From what I can tell, as long as you don't propagate a native
exception through JavaScript, things will be fine.
By "calling JS", I meant if you, for instance, attempt to execute a
JavaScript function from C++. Say you call a v8 function like this:
int main (...)
{
...
try {
function->Call(...)
}
catch(...)
{
}
...
}
The (simplified) stack might look like this when the exception was
thrown:
SomeCPPFunctionWhichThrowsError <-- Error thrown. C++ looks for catch.
MyNativeCPPFunction <-- Is there one here?
myNativeCPPWrapperFunction <-- is there one here?
myJSFunction <-- What the heck is this? I don't understand it. Uh
oh... no catch found?
main <-- there is a catch here, but C++ can't see it, because it is
hiding behind JS.
If the JS function calls a native C++ function which throws an error,
things will not work. So, you must catch it inside the native C++
function being called by the JavaScript. You should be able to define
the try/catch in the proxy function safely -- so long as you do indeed
catch all exceptions.
At least, that is the hypothesis I formed as a result of the little
experiment I did this morning.
Alex
On Mar 14, 2009, at 11:14 AM, Stephan Beal wrote:
>
> On Sat, Mar 14, 2009 at 3:43 PM, Alex Iskander <[email protected]>
> wrote:
>> I just tested code almost just like that, and it worked fine.
>> Logically,
>> there should be no problem with it, as long as you catch the error.
>> Where
>> things will not work is when your "catch" is in a function calling
>> the
>> JavaScript.
>
> When you say "calling JS", do you mean using Script::Run(), or do you
> mean "using the v8 API to exec operations on JS objects"? i'm not
> using Script::Run() (or similar) except at the top-most level of the
> app (the shell).
>
>> Because the JavaScript frames don't keep track of themselves the
>> same way, C++ won't be able to trace back up them to deliver the
>> exception
>> to the right place.
>
> My initial experiment in this direction was a proxy function like
> this:
>
> Handle<Value> Toss( char const * fmt, ... );
>
> which produces a printf-style exception message and returns
> ThrowException(the error message). However, i found that using that
> function lead to stack corruption (for reasons i can't explain - use
> the same code in SpiderMonkey-based stuff). So... my assumption was
> that i don't know the whole story about the JS stack (but it doesn't
> seem to follow the same rules as the C++ stack?), and thus i'm leary
> of using C++ exceptions. However, without exceptions i can't do
> certain forms of automatic type conversion (e.g. JS-to-(T &), which
> needs to throw if the conversion cannot happen, to avoid a segfault).
>
>> I tested that as well. To reiterate, throwing and
>> catching an exception inside a function called from JavaScript is
>> fine.
>> Throwing an exception meant to be caught outside of the function
>> called from
>> JavaScript won't work, because C++ won't be able to find the catch.
>
> Where does that leave me with proxy functions? e.g. a user binds
> MyType::foo() to a JS function. That binding necessarily creates a
> proxy function which 1) convers argv.This() to a native object and
> then forwards to MyType::foo(). Must i then catch in foo() or can i do
> it in the (template-generated) proxy function/wrapper? i.e. do i
> *need* to catch it at the most local point possible or can i let it
> propagate up the stack a bit to be caught by a more generic handler?
>
> For example:
>
> template < typename A0, typename A1, typename NativeFunc >
> Handle<Value> FwdToFunc2( NativeFunc func, Arguments const & argv )
> {
> if( argv.Length() != 2 ) return
> ThrowException(String::New("Requires exactly 2 arguments!");
> // ^^^ if i use my Toss() function instead of ThrowException() i
> get stack corruption here!!!
> try{
> return CastToJS( func( CastFromJS<A0>(argv[0]),
> CastFromJS<A1>(argv[1]) ) );
> }
> catch(exception const & ex) {
> return ThrowException(String::New(ex.what());
> }
> // is everything okay here as long as i don't propagate a native
> exception?
> return ...;
> }
>
> What i'm worried about most there is the actual call to func(), as
> that can of course perform arbitrary v8 operations and i don't know
> what happens to v8's internals if a function call from five levels
> deep into func()'s call chain throws and i don't catch it until the
> above block.
>
> i know it "should" work, but after getting stack corruption in some
> cases when dealing with exceptions in v8 i'm a tad bit nervous about
> it.
>
> --
> ----- stephan beal
> http://wanderinghorse.net/home/stephan/
>
> >
Alex Iskander, TPSi
--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---