v8js_exceptions.cc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2015 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | http://www.opensource.org/licenses/mit-license.php MIT License |
  8. +----------------------------------------------------------------------+
  9. | Author: Jani Taskinen <[email protected]> |
  10. | Author: Patrick Reilly <[email protected]> |
  11. | Author: Stefan Siegl <[email protected]> |
  12. +----------------------------------------------------------------------+
  13. */
  14. #ifdef HAVE_CONFIG_H
  15. #include "config.h"
  16. #endif
  17. extern "C" {
  18. #include "php.h"
  19. #include "ext/date/php_date.h"
  20. #include "ext/standard/php_string.h"
  21. #include "zend_interfaces.h"
  22. #include "zend_closures.h"
  23. #include "ext/spl/spl_exceptions.h"
  24. #include "zend_exceptions.h"
  25. }
  26. #include "php_v8js_macros.h"
  27. /* {{{ Class Entries */
  28. zend_class_entry *php_ce_v8js_exception;
  29. zend_class_entry *php_ce_v8js_script_exception;
  30. zend_class_entry *php_ce_v8js_time_limit_exception;
  31. zend_class_entry *php_ce_v8js_memory_limit_exception;
  32. /* }}} */
  33. /* {{{ Class: V8JsScriptException */
  34. void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
  35. {
  36. v8::String::Utf8Value exception(try_catch->Exception());
  37. const char *exception_string = ToCString(exception);
  38. v8::Handle<v8::Message> tc_message = try_catch->Message();
  39. const char *filename_string, *sourceline_string;
  40. char *message_string;
  41. int linenum, start_col, end_col, message_len;
  42. object_init_ex(return_value, php_ce_v8js_script_exception);
  43. #define PHPV8_EXPROP(type, name, value) \
  44. zend_update_property##type(php_ce_v8js_script_exception, return_value, #name, sizeof(#name) - 1, value TSRMLS_CC);
  45. if (tc_message.IsEmpty()) {
  46. message_len = spprintf(&message_string, 0, "%s", exception_string);
  47. }
  48. else
  49. {
  50. v8::String::Utf8Value filename(tc_message->GetScriptResourceName());
  51. filename_string = ToCString(filename);
  52. PHPV8_EXPROP(_string, JsFileName, filename_string);
  53. v8::String::Utf8Value sourceline(tc_message->GetSourceLine());
  54. sourceline_string = ToCString(sourceline);
  55. PHPV8_EXPROP(_string, JsSourceLine, sourceline_string);
  56. linenum = tc_message->GetLineNumber();
  57. PHPV8_EXPROP(_long, JsLineNumber, linenum);
  58. start_col = tc_message->GetStartColumn();
  59. PHPV8_EXPROP(_long, JsStartColumn, start_col);
  60. end_col = tc_message->GetEndColumn();
  61. PHPV8_EXPROP(_long, JsEndColumn, end_col);
  62. message_len = spprintf(&message_string, 0, "%s:%d: %s", filename_string, linenum, exception_string);
  63. v8::String::Utf8Value stacktrace(try_catch->StackTrace());
  64. if (stacktrace.length() > 0) {
  65. const char* stacktrace_string = ToCString(stacktrace);
  66. PHPV8_EXPROP(_string, JsTrace, stacktrace_string);
  67. }
  68. if(try_catch->Exception()->IsObject()) {
  69. v8::Local<v8::Value> php_ref = try_catch->Exception()->ToObject()->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY));
  70. if(!php_ref.IsEmpty()) {
  71. assert(php_ref->IsExternal());
  72. zval *php_exception = reinterpret_cast<zval *>(v8::External::Cast(*php_ref)->Value());
  73. zend_class_entry *exception_ce = zend_exception_get_default(TSRMLS_C);
  74. if (Z_TYPE_P(php_exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(php_exception), exception_ce TSRMLS_CC)) {
  75. Z_ADDREF_P(php_exception);
  76. zend_exception_set_previous(return_value, php_exception TSRMLS_CC);
  77. }
  78. }
  79. }
  80. }
  81. PHPV8_EXPROP(_string, message, message_string);
  82. efree(message_string);
  83. }
  84. /* }}} */
  85. void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
  86. {
  87. v8::String::Utf8Value exception(try_catch->Exception());
  88. const char *exception_string = ToCString(exception);
  89. zval *zexception = NULL;
  90. if (try_catch->Message().IsEmpty()) {
  91. zend_throw_exception(php_ce_v8js_script_exception, (char *) exception_string, 0 TSRMLS_CC);
  92. } else {
  93. MAKE_STD_ZVAL(zexception);
  94. v8js_create_script_exception(zexception, isolate, try_catch TSRMLS_CC);
  95. zend_throw_exception_object(zexception TSRMLS_CC);
  96. }
  97. }
  98. /* }}} */
  99. #define V8JS_EXCEPTION_METHOD(property) \
  100. static PHP_METHOD(V8JsScriptException, get##property) \
  101. { \
  102. zval *value; \
  103. \
  104. if (zend_parse_parameters_none() == FAILURE) { \
  105. return; \
  106. } \
  107. value = zend_read_property(php_ce_v8js_script_exception, getThis(), #property, sizeof(#property) - 1, 0 TSRMLS_CC); \
  108. *return_value = *value; \
  109. zval_copy_ctor(return_value); \
  110. INIT_PZVAL(return_value); \
  111. }
  112. /* {{{ proto string V8JsEScriptxception::getJsFileName()
  113. */
  114. V8JS_EXCEPTION_METHOD(JsFileName);
  115. /* }}} */
  116. /* {{{ proto string V8JsScriptException::getJsLineNumber()
  117. */
  118. V8JS_EXCEPTION_METHOD(JsLineNumber);
  119. /* }}} */
  120. /* {{{ proto string V8JsScriptException::getJsStartColumn()
  121. */
  122. V8JS_EXCEPTION_METHOD(JsStartColumn);
  123. /* }}} */
  124. /* {{{ proto string V8JsScriptException::getJsEndColumn()
  125. */
  126. V8JS_EXCEPTION_METHOD(JsEndColumn);
  127. /* }}} */
  128. /* {{{ proto string V8JsScriptException::getJsSourceLine()
  129. */
  130. V8JS_EXCEPTION_METHOD(JsSourceLine);
  131. /* }}} */
  132. /* {{{ proto string V8JsScriptException::getJsTrace()
  133. */
  134. V8JS_EXCEPTION_METHOD(JsTrace);
  135. /* }}} */
  136. ZEND_BEGIN_ARG_INFO(arginfo_v8jsscriptexception_no_args, 0)
  137. ZEND_END_ARG_INFO()
  138. static const zend_function_entry v8js_script_exception_methods[] = { /* {{{ */
  139. PHP_ME(V8JsScriptException, getJsFileName, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
  140. PHP_ME(V8JsScriptException, getJsLineNumber, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
  141. PHP_ME(V8JsScriptException, getJsStartColumn, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
  142. PHP_ME(V8JsScriptException, getJsEndColumn, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
  143. PHP_ME(V8JsScriptException, getJsSourceLine, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
  144. PHP_ME(V8JsScriptException, getJsTrace, arginfo_v8jsscriptexception_no_args, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
  145. {NULL, NULL, NULL}
  146. };
  147. /* }}} */
  148. /* }}} V8JsScriptException */
  149. /* {{{ Class: V8JsException */
  150. static const zend_function_entry v8js_exception_methods[] = { /* {{{ */
  151. {NULL, NULL, NULL}
  152. };
  153. /* }}} */
  154. /* }}} V8JsException */
  155. /* {{{ Class: V8JsTimeLimitException */
  156. static const zend_function_entry v8js_time_limit_exception_methods[] = { /* {{{ */
  157. {NULL, NULL, NULL}
  158. };
  159. /* }}} */
  160. /* }}} V8JsTimeLimitException */
  161. /* {{{ Class: V8JsMemoryLimitException */
  162. static const zend_function_entry v8js_memory_limit_exception_methods[] = { /* {{{ */
  163. {NULL, NULL, NULL}
  164. };
  165. /* }}} */
  166. /* }}} V8JsMemoryLimitException */
  167. PHP_MINIT_FUNCTION(v8js_exceptions) /* {{{ */
  168. {
  169. zend_class_entry ce;
  170. /* V8JsException Class */
  171. INIT_CLASS_ENTRY(ce, "V8JsException", v8js_exception_methods);
  172. php_ce_v8js_exception = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException, NULL TSRMLS_CC);
  173. /* V8JsScriptException Class */
  174. INIT_CLASS_ENTRY(ce, "V8JsScriptException", v8js_script_exception_methods);
  175. php_ce_v8js_script_exception = zend_register_internal_class_ex(&ce, php_ce_v8js_exception, NULL TSRMLS_CC);
  176. php_ce_v8js_script_exception->ce_flags |= ZEND_ACC_FINAL;
  177. /* Add custom JS specific properties */
  178. zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsFileName"), ZEND_ACC_PROTECTED TSRMLS_CC);
  179. zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsLineNumber"), ZEND_ACC_PROTECTED TSRMLS_CC);
  180. zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsStartColumn"), ZEND_ACC_PROTECTED TSRMLS_CC);
  181. zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsEndColumn"), ZEND_ACC_PROTECTED TSRMLS_CC);
  182. zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsSourceLine"), ZEND_ACC_PROTECTED TSRMLS_CC);
  183. zend_declare_property_null(php_ce_v8js_script_exception, ZEND_STRL("JsTrace"), ZEND_ACC_PROTECTED TSRMLS_CC);
  184. /* V8JsTimeLimitException Class */
  185. INIT_CLASS_ENTRY(ce, "V8JsTimeLimitException", v8js_time_limit_exception_methods);
  186. php_ce_v8js_time_limit_exception = zend_register_internal_class_ex(&ce, php_ce_v8js_exception, NULL TSRMLS_CC);
  187. php_ce_v8js_time_limit_exception->ce_flags |= ZEND_ACC_FINAL;
  188. /* V8JsMemoryLimitException Class */
  189. INIT_CLASS_ENTRY(ce, "V8JsMemoryLimitException", v8js_memory_limit_exception_methods);
  190. php_ce_v8js_memory_limit_exception = zend_register_internal_class_ex(&ce, php_ce_v8js_exception, NULL TSRMLS_CC);
  191. php_ce_v8js_memory_limit_exception->ce_flags |= ZEND_ACC_FINAL;
  192. return SUCCESS;
  193. } /* }}} */
  194. /*
  195. * Local variables:
  196. * tab-width: 4
  197. * c-basic-offset: 4
  198. * End:
  199. * vim600: noet sw=4 ts=4 fdm=marker
  200. * vim<600: noet sw=4 ts=4
  201. */