Search code examples
c++v8

How to run a JavaScript file - V8


I have embedded v8 into my c++ application. Referring https://chromium.googlesource.com/v8/v8/+/master/samples/hello-world.cc I am able to run a javascript. Tested and works fine.

I access the links from my c++ application, download html data, download javascript. Some embedded scripts in the html call functions in external script files. How do I ensure that the external scripts are available for the embedded ones?

The downloaded JavaScript files (one or more) may be of large size. In such a context, how do I execute the JavaScript api present in HTML using v8? Code to run a JavaScript in v8 is below,

  // Create a string containing the JavaScript source code.
  v8::Local<v8::String> source =
      v8::String::NewFromUtf8(isolate, "'Hello' + ', World!'",
                              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();

Assuming downloaded javascript is 200KB, how can I feed such a large buffer to v8::Script::Compile api. And when I have more than one file present, how can feed I them to v8 ?


Solution

  • How do I ensure that the external scripts are available for the embedded ones?

    You load the external scripts first.

    How do I execute the JavaScript API present in HTML using v8?

    Do you mean the DOM? window, document and the like? The DOM is not part of ECMAScript, so V8 knows nothing about it; it is provided by the embedder (i.e. usually Chrome). In your own embedding you need to provide all those objects yourself, using V8's API. Needless to say, this is a huge amount of work. If what you're after is a way to render websites, then I recommend that you use some existing component/library for that, for example the Chromium Embedded Framework, or your favorite GUI toolkit's WebView (or whatever it is called).

    Assuming downloaded JavaScript is 200KB, how can I feed such a large buffer to v8::Script::Compile API?

    Just like you feed a small script to V8: put it into a v8::Local<v8::String>, then call v8::Script::Compile and v8::Script::Run.

    And when I have more than one file present, how can feed I them to v8 ?

    Call v8::Script::Compile and v8::Script::Run repeatedly, possibly using a loop. For an example, see V8's shell sample, specifically the function RunMain.

    As I receive partial JavaScript in HTTP packets (chunks), can I pass the partial JavaScript to V8?

    Yes, V8 has a script streaming interface. See the API documentation for v8::ScriptCompiler::ExternalSourceStream. For examples on how to use it, you can study the tests. Streaming may or may not be worth it for scripts as small as 200KB; it is definitely not required.