Dear All
I am quite new to v8. I am a c developer, with limited c++ knowledge. Sorry if I ask very basic questions.
I have a C application, that interacts with web servers. Gets javascript. Need to execute javascript.
Imagine a situation, where I get total 2 javascript files from server.
js1.js
function js_add_elements(var1, var2)
{
var var3 = parseInt(var1) + parseInt(var2);
var result = 'Addition of ' + var1 + ' and ' + var2 + ' results ' + var3;
return result;
}
js2.js
I have my c code as below.
Header file
typedef struct
{
std::unique_ptr<v8::Platform> platform;
v8::Isolate::CreateParams create_params;
v8::Isolate *isolate;
v8::Isolate::Scope *isolate_scope;
}MJSEInstance;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Create MJSE instance
*/
void *mjse_create_instance(char **argv);
/**
* @brief Destroy MJSE instance
* @param instance -> MJSE instance
*/
void mjse_destroy_instance(void *instance);
/**
* @brief Executes a script
* @param minstance - MJSE instance
* @param jscript - the javascript
* @param scriptlen - Length of script
*/
void mjse_execute_script(void *instance, char *jscript);
#ifdef __cplusplus
}
#endif
CPP File
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/libplatform/libplatform.h"
#include "include/v8.h"
#include "mjse.h"
#include "mjse_int.h"
#include <new>
extern "C" {
using namespace v8;
void *mjse_create_instance(char **argv)
{
MJSEInstance *instance = (MJSEInstance *)calloc(1, sizeof(MJSEInstance));
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
instance->platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(instance->platform.get());
v8::V8::Initialize();
instance->create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
instance->isolate = v8::Isolate::New(instance->create_params);
instance->isolate_scope = new v8::Isolate::Scope(instance->isolate);
return instance;
}
void mjse_destroy_instance(void *minstance)
{
MJSEInstance *instance = (MJSEInstance *)minstance;
if(instance == NULL)
return;
if(instance->isolate_scope)
{
delete instance->isolate_scope;
}
if(instance->isolate)
{
instance->isolate->Dispose();
}
v8::V8::Dispose();
v8::V8::ShutdownPlatform();
if(instance->create_params.array_buffer_allocator)
{
delete instance->create_params.array_buffer_allocator;
}
instance->~MJSEInstance();
free(instance);
}
void mjse_execute_script(void *minstance, char *jscript)
{
MJSEInstance *instance = (MJSEInstance *)minstance;
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(instance->isolate);
// Create a new context.
v8::Local<v8::Context> context = v8::Context::New(instance->isolate);
// Enter the context for compiling and running the hello world script.
v8::Context::Scope context_scope(context);
{
// Create a string containing the JavaScript source code.
v8::Local<v8::String> source =
v8::String::NewFromUtf8(instance->isolate, jscript,
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();
// Convert the result to an UTF8 string and print it.
v8::String::Utf8Value utf8(instance->isolate, result);
printf("%s\n", *utf8);
}
}
}
Main File
int main(int argc, char **argv)
{
char *script;
void *instance;
instance = mjse_create_instance(argv);
script = "function js_add_elements(var1, var2) \
{ \
var var3 = parseInt(var1) + parseInt(var2); \
var result = 'Addition of ' + var1 + ' and ' + var2 + ' results ' + var3; \
return result; \
};";
mjse_execute_script(instance, script);
script = "js_add_elements(2, 3);";
mjse_execute_script(instance, script);
mjse_destroy_instance(instance);
return 0;
}
Now whats happening, while executing javascript first time it executes fine. But while trying to execute second time (letter in red), it gets exception.
I understand, it is creating new v8 Local context each time, and does not have js1.js details, hence getting exception. I also found in web we can have v8 Global context and refer the context while executing for second time.
However I have not been able to find, how to declare v8 global context and store / move v8 local context there and refer it during second time execution. Please let me know with a sample/example code.
Thanks
Austin