Skip to content

Instantly share code, notes, and snippets.

@terryjsmith
Last active September 23, 2020 20:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save terryjsmith/391495e84d3a7979aa851e436965aab6 to your computer and use it in GitHub Desktop.
Save terryjsmith/391495e84d3a7979aa851e436965aab6 to your computer and use it in GitHub Desktop.
Script::Script() {
}
Script::~Script() {
}
void Script::Initialize(char* src) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(isolate);
// Create an instance of the global context so we can plug variables in
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
v8::Local<v8::Context> localContext = v8::Context::New(isolate, NULL, global);
m_context.Reset(isolate, localContext);
localContext->Enter();
// Catch any errors the script might throw
v8::TryCatch try_catch(isolate);
// Copy source
v8::Local<v8::String> scriptSrc = v8::String::NewFromUtf8(isolate, src, v8::NewStringType::kNormal).ToLocalChecked();
v8::Local<v8::Script> script;
if (v8::Script::Compile(localContext, scriptSrc).ToLocal(&script) == false) {
v8::String::Utf8Value error(try_catch.Exception());
ErrorSystem::HandleError(new FileError(ERROR_WARN, (char*)"Unable to compile script file", (char*)*error));
return;
}
v8::Local<v8::Value> result;
if (script->Run(localContext).ToLocal(&result) == false) {
v8::String::Utf8Value error(try_catch.Exception());
ErrorSystem::HandleError(new FileError(ERROR_WARN, (char*)"Unable to execute script file", (char*)*error));
return;
}
// Pull out the functions we care about
v8::Local<v8::Object> globalSpace = isolate->GetCurrentContext()->Global();
// Get the update function
v8::Local<v8::Value> value = globalSpace->Get(v8::String::NewFromUtf8(isolate, "Update"));
m_updateFunction.Reset(isolate, value.As<v8::Function>());
// Make sure the update function is a function
v8::String::Utf8Value type(value->TypeOf(isolate));
assert(value->IsFunction());
// Save script
m_script.Reset(isolate, script);
localContext->Exit();
}
void Script::Execute() {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(isolate);
// Create an instance of the global context so we can plug variables in
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
// Reset our current local context
v8::Local<v8::Context> context = m_context.Get(isolate);
context->Enter();
// Catch any errors the script might throw
v8::TryCatch try_catch(isolate);
// Script local
v8::Local<v8::Script> script = m_script.Get(isolate);
v8::Local<v8::Value> result;
/**
* Note: we do not need to Run the script again, just call our functions; this retains the values
* of local variables inside the script
*/
// Run specific functions
v8::Local<v8::Function> updateFunc = m_updateFunction.Get(isolate);
result = updateFunc->Call(updateFunc->CreationContext()->Global(), 0, 0);
context->Exit();
}
class Script {
public:
Script();
~Script();
void Initialize(char* src);
void Execute();
protected:
v8::Persistent<v8::Script> m_script;
v8::Persistent<v8::Context> m_context;
// Functions we look for to call
v8::Persistent<v8::Function> m_updateFunction;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment