On Thu, May 12, 2016 at 11:16 PM, Ryan Ingram <[email protected]> wrote:
> My codebase is currently running on V8 3.30 in case it matters.
>
> I'm writing a marshalling system to link JS function calls to native C++
> code.  As part of this system, I need to convert function arguments into
> native C++ types.  For the sake of example, lets say I'm implementing a
> simple binding to C's "atan2" function.
>
>     double atan2(double y, double x);
>
> So, an example v8::FunctionCallback for this case
>
>     void V8CallAtan2( const v8::FunctionCallbackInfo<v8::Value>& info )
>     {
>         v8::Isolate* isolate = info.GetIsolate();
>
>         // Not sure if this is required, since we must be in an isolate
> scope already to be getting called from script
>         v8::Isolate::Scope isolateScope(isolate);
>
>         // Don't hold onto Local handles allocated by this function
>         v8::Handle::Scope handleScope(isolate);
>
>         // Some simple checks that we're not being stupid
>         if(info.IsConstructCall())
>         {
>             isolate->ThrowException( v8::String::NewFromUtf8( isolate,
> "Called 'atan2' as a constructor" ) );
>             return;
>         }
>
>         if(info.Length() != 2)
>         {
>             isolate->ThrowException( v8::String::NewFromUtf8( isolate,
> "Called 'atan2' with incorrect number of arguments." ) );
>             return;
>         }
>
>         // Extract arguments from the call
>         v8::Local<v8::Value> yVal = info[0];
>         v8::Local<v8::Value> xVal = info[1];
>
>         // Marshal into native C++ types
>         double y = yVal->NumberValue();        // HERE1
>         double x = xVal->NumberValue();        // HERE2
>
>         // Call native function
>         double result = atan2(y,x);
>
>         // Marshal return value back into a JS type
>         v8::Local<v8::Value> resultVal = v8::Number::New(isolate, result);
>
>         // and return it to the caller
>         info.GetReturnValue().Set( resultVal );
>     }
>
> From reading the source code to NumberValue() it looks like this call could
> potentially throw a JS exception, which makes sense--the arguments could be
> of some type that isn't convertible to double.  So, if the line at HERE1
> throws a JS exception, if my understanding of ThrowException is correct, I'm
> not allowed to do any further JS operations (including calling NumberValue()
> at HERE2), and instead need to immediately return control to v8 by returning
> from my callback -- as I do in the sanity checks before reading the
> arguments.
>
> But I haven't been able to find a way to ask the Isoalte if there is a
> pending exception, at least not in the public API.  How do I detect this
> case?
>
> I noticed that newer versions of v8 have Value::NumberValue() return
> Maybe<double> instead, and I'm considering pushing a v8 upgrade for that
> reason.  But first I want to know if there's a fix without impacting the
> other users on my team.
>
> Thanks!
>
>   -- ryan

Here is how you do it:

  v8::TryCatch try_catch(isolate);  // |isolate| may not be necessary with 3.30.
  DoOperationThatCanThrow();
  if (try_catch.HasCaught()) {
    // Do something with the exception, e.g. try_catch.ReThrow().
  }

By the way, in your example, the v8::Isolate::Scope and
v8::HandleScope are not necessary; function callbacks and property
callbacks have them implicitly.

-- 
-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to