1

To run a simple Javascript program using v8 I go about it as follows:

// Create a string containing the JavaScript source code.
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "'Hello' + ', from Javascript!'", v8::NewStringType::kNormal).ToLocalChecked();

// Compile the source code.
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();

// Run the script to get the result.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();

How can I go about calling a Javascript function in a /path/to/my_js_functions.js file?

function myJsFunction(stringParam) {
  return stringParam   // The function returns a stringParam from the parameter
}  

Thank you all in advance.

1 Answer 1

2

First you have to get your hands on the function object. Assuming it's in the global scope (== on the global object), you can access it like this:

v8::Local<v8::String> name = v8::String::NewFromUtf8(
    isolate, "myJsFunction", v8::NewStringType::kInternalized).ToLocalChecked();
v8::Local<v8::Value> obj =
    context->Global()->Get(context.local(), name).ToLocalChecked();
if (!obj->IsFunction()) {
  /* someone overwrote it, handle error */
}
v8::Local<v8::Function> my_function = v8::Local<v8::Function>::Cast(obj);

Note that every time you get a MaybeLocal, the result could be empty, which happens when an exception was thrown. If you can't guarantee that that won't happen, then you shouldn't just use .ToLocalChecked() (which will crash when the MaybeLocal is empty), but instead properly check for and handle the error case.

Once you have a function, you can prepare arguments for it and call it:

v8::Local<v8::Value> receiver = ...;
int argc = ...;
v8::Local<v8::Value> args[argc] = ...;
v8::MaybeLocal<v8::Value> result = my_function->Call(context.local(), receiver, argc, args);

Again, the result is a MaybeLocal, because functions can throw exceptions (explicitly, or indirectly by calling/doing something that throws). It's up to you to catch any error cases, and otherwise Cast the result to the appropriate type and do something with it.

(Working with JavaScript through a C++ API is not exactly pleasant. That's largely due to the many conceptual differences between the two languages.)

For many more examples, have a look at V8's test-api.cc.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much @jmrk for the answer. I have looked at test-api.cc. I am, however, not sure as to how to go about loading the js file. Could you please suggest how to go about it? I've been at this for a few days now. There doesn't seem to be much documentation about it. If you could please help with an illustration of how the code would flow. Again, thank you.
Open the file any way you want (using standard C++ facilities), read its content as a string, create a v8::String from it and pass it to v8::Script::Compile and Run like in the snippet you posted. If you want to study an example: here's how the d8 shell implements its load command: cs.chromium.org/chromium/src/v8/src/d8/…
Thank you @jmrk. I can't express my gratitude enough. It works! Thank you for your help again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.