Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

v8 do not support v8::Value::ToNumber anymore?

I'm currently looking for C++ add-ons with node-gyp.

node-gyp configure works fine, but node-gyp build gives an error with error C2661: 'v8::Value::ToNumber': no overloaded function take 0 parameter.

There are some warnings about deprecated, and they give a link to declaration at v8.h file (in node-gyp). However, there are only V8_DEPRECATED and V8_WARN_UNUSED_RESULT about ToNumber. So it seems like error resulted due to absence of definition about v8::Value::ToNumber in v8.h.

Error occurs at the last line of code below:

void someFunction(const FunctionCallbackInfo<Value>& args) {
    Isolate *iso = args.GetIsolate();
    if (args.Length() < 1) {
        iso->ThrowException(Exception::TypeError(String::NewFromUtf8(iso, "Must provide Input")));
    }

    Local<Object> coords = args[0]->ToObject()->Clone();  // note that the keys are available with coords->GetOwnPropertyNames();
    Local<Array> keys = coords->GetOwnPropertyNames();

    if (keys->Length() != 2) {
        iso->ThrowException(Exception::TypeError(String::NewFromUtf8(iso, "Need exactly 2 values")));
    }

    char props[2];
    double values[2];

    for (int i=0; i < 2; i++) {
        String::Utf8Value key(keys->Get(i)->ToString());
        props[i] = (*key)[0];
        values[i] = coords->Get(keys->Get(i))->ToNumber()->Value();
    }
    ...

I tried to read nodejs documents, but there seems no evidence about removing ToNumber. Also looked for relevant questions, but nothing matches mine :(

Maybe it is related to my node version, but I need some answers for my problem before test with node versions..

I'm using node: 10.16.3 npm: 6.9.0 node-gyp: 5.0.3

Thank you for your readings. Any helps are appreciated!

like image 737
lee Avatar asked Oct 01 '19 05:10

lee


1 Answers

V8 developer here. You can find no evidence of removing ToNumber because it hasn't been removed ;-)

It's just that the no-parameter version of the function, which had been deprecated for a while, has finally been dropped. The replacement is the version that takes a Local<Context> as a parameter, see here: https://github.com/nodejs/node/blob/v10.16.3/deps/v8/include/v8.h#L2425

The technical background is that ToNumber can end up executing JavaScript (if it's called on an object with a valueOf method, for example), and executing JavaScript is context-specific. The context to use for ToNumber used to be implicit, which was hard to reason about and sometimes led to subtle bugs on the embedder side; so V8's "new" (for the past couple of years) API philosophy is to make context parameters explicit. The more complex your embedding application is, the more you'll (hopefully) appreciate the more obvious structure of the code.

ToString is in the same boat, btw. In this case the no-parameter version still exists, but it's deprecated; the replacement is ToString(Local<Context> context).

like image 172
jmrk Avatar answered Nov 12 '22 11:11

jmrk