-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correct abstraction for try/catch #27
Comments
The V8 documentation claims that the napi_value
napi_call_function_with_exception(napi_env e,
napi_value scope,
napi_value func,
int argc,
napi_value* argv,
napi_value* exception); Then, applications can simply re-throw the exception if our implementation sets it. OTOH, if we can heap-allocate, IINM in the V8 implementation we have to remember to This way, we have the Unfortunately this means that, if somebody leaks the |
@fhinkel - can you comment on this ? |
During our last meeting, I learned that there are other V8 structures that are also documented as having to be stack-allocated yet work fine when heap-allocated. So, I went ahead and created an implementation of @mhdawson's API with a heap-allocated |
The reason v8::TryCatch ought to be stack-allocated is that nested v8::TryCatch scopes build a chain that reflect this nesting. Heap-allocating would be possible, but must make sure that the allocation/deallocation order is kept. Otherwise things might break in weird ways. Letting it escape via proposed API seems an easy source for bugs. |
@hashseed do you think the API could abstract it in such a way that it can't be used incorrectly? |
Well you could, maybe in debug mode, track the nesting inside napi_trycatch_* and make sure we can only call napi_trycatch_delete on the last v8::TryCatch in the chain. But if the user would use v8::TryCatch intermixed with napi_trycatch_*, we could still deallocate out of order. |
What about implementing the ChakraCore abstraction instead? We could surround all calls into JS ( Otherwise, if nobody calls napi_trycatch_exception(), napi_trycatch_delete() would throw the exception present in the persistent, if any. Is there a big performance penalty when surrounding a call into JS with a v8::TryCatch? |
I think surrounding all calls into V8 with a v8::TryCatch is a very good idea. TryCatch scopes are not particularly expensive to allocate. If no exception is thrown, it should have almost no performance impact. If the exception is thrown and you need to rethrow, then you add some churn there. |
api-prototype-6.2.0...gabrielschulhof:try-catch-6.2.0-global-persistent-exception shows the global persistent exception approach. |
Re nodejsgh-27 Re nodejsgh-43 (cherry picked from commit 8d8c17fc3458b70abfd2efcaee97538b49ca3008)
Error handling design has covered this issue - but we need to track the performance impact of this. Closing this issue for now - either reopen or file new issue if problem arises. |
Comment from Ben in : nodejs/node-eps#20 (comment)
I think most JS engines have an 'is exception pending?' function; V8 is the outlier with its TryCatch construct. API strawman:
// Wrapper around a v8::TryCatch. Dummy with other engines.
typedef struct napi_trycatch { struct napi_trycatch *v; } napi_trycatch;
NODE_EXTERN void napi_trycatch_new(napi_env e, napi_trycatch *trycatch);
// Returns exception object or undefined.
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);
The text was updated successfully, but these errors were encountered: