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
-~----------~----~----~----~------~----~------~--~---

Reply via email to