diff --git a/src/node_jsvmapi.cc b/src/node_jsvmapi.cc index 1ed38cbd95..01fff0bff9 100644 --- a/src/node_jsvmapi.cc +++ b/src/node_jsvmapi.cc @@ -836,15 +836,41 @@ napi_value napi_make_callback(napi_env e, napi_value recv, return v8impl::JsValueFromV8LocalValue(result); } -bool napi_try_catch(napi_env e, napi_try_callback cbtry, - napi_catch_callback cbcatch, void* data) { - v8::TryCatch try_catch; - cbtry(e, data); - if (try_catch.HasCaught()) { - cbcatch; - return true; - } - return false; +struct napi_trycatch_impl { + v8::TryCatch impl; + bool exceptionRetrieved; +}; + +void napi_trycatch_new(napi_env e, napi_trycatch *trycatch) { + struct napi_trycatch_impl *local = new struct napi_trycatch_impl; + + if (!local) { + return; + } + + local->exceptionRetrieved = false; + + *trycatch = (napi_trycatch)local; +} + +napi_value napi_trycatch_exception(napi_env e, napi_trycatch trycatch) { + struct napi_trycatch_impl *local = (struct napi_trycatch_impl *)trycatch; + + if (local->impl.HasCaught()) { + local->exceptionRetrieved = true; + return v8impl::JsValueFromV8LocalValue(local->impl.Exception()); + } else { + return napi_get_undefined_(e); + } +} + +void napi_trycatch_delete(napi_env e, napi_trycatch trycatch) { + struct napi_trycatch_impl *local = (struct napi_trycatch_impl *)trycatch; + + if (!(local->exceptionRetrieved)) { + local->impl.ReThrow(); + } + delete local; } napi_value napi_buffer_new(napi_env e, char* data, uint32_t size) { diff --git a/src/node_jsvmapi.h b/src/node_jsvmapi.h index f1e3955c8e..99304e6537 100644 --- a/src/node_jsvmapi.h +++ b/src/node_jsvmapi.h @@ -279,16 +279,10 @@ NODE_EXTERN void napi_throw(napi_env e, napi_value error); NODE_EXTERN void napi_throw_error(napi_env e, const char* msg); NODE_EXTERN void napi_throw_type_error(napi_env e, const char* msg); -// TODO(ianhall): APIs for handling try catch semantics need serious -// design analysis, this is just a quick hack -// One thing to note is that v8::TryCatch relies on the current -// stack pointer position, so it cannot be used -// with a wrapper class hack like we're doing for handle scopes. -typedef void (*napi_try_callback)(napi_env e, void* data); -typedef void (*napi_catch_callback)(napi_env e, void* data); -NODE_EXTERN bool napi_try_catch(napi_env e, napi_try_callback t, - napi_catch_callback c, void* data); - +// Methods to support catching exceptions +NODE_EXTERN void napi_trycatch_new(napi_env e, napi_trycatch *trycatch); +NODE_EXTERN napi_value napi_trycatch_exception(napi_env e, napi_trycatch trycatch); +NODE_EXTERN void napi_trycatch_delete(napi_env e, napi_trycatch trycatch); // Methods to provide node::Buffer functionality with napi types NODE_EXTERN napi_value napi_buffer_new(napi_env e, diff --git a/src/node_jsvmapi_types.h b/src/node_jsvmapi_types.h index d92a6bfcd3..02b743611c 100644 --- a/src/node_jsvmapi_types.h +++ b/src/node_jsvmapi_types.h @@ -10,6 +10,7 @@ typedef struct napi_weakref__ *napi_weakref; typedef struct napi_handle_scope__ *napi_handle_scope; typedef struct napi_escapable_handle_scope__ *napi_escapable_handle_scope; typedef struct napi_propertyname__ *napi_propertyname; +typedef struct napi_trycatch__ *napi_trycatch; typedef struct napi_func_cb_info__ *napi_func_cb_info; typedef void (*napi_callback)(napi_env, napi_func_cb_info); typedef void napi_destruct(void* v);