Skip to content

Instantly share code, notes, and snippets.

@xaxxon
Last active January 7, 2016 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xaxxon/bffe70dc93abca22ead3 to your computer and use it in GitHub Desktop.
Save xaxxon/bffe70dc93abca22ead3 to your computer and use it in GitHub Desktop.
JavascriptEngine::JavascriptEngine()
{
printf("platform %p\n", platform.get());
assert(initialized);
// Create a new Isolate and make it the current one.
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = (v8::ArrayBuffer::Allocator *) &JavascriptEngine::allocator;
this->isolate = v8::Isolate::New(create_params);
// now create a handle scope with the isolate so it handles can be created
{
v8::Isolate::Scope is(this->get_isolate());
v8::HandleScope handle_scope(this->get_isolate());
v8::Local<v8::ObjectTemplate> ot = v8::ObjectTemplate::New(this->get_isolate());
this->global_object_template = CopyablePersistent<v8::ObjectTemplate>(this->get_isolate(), ot);
ot->Set(this->get_isolate(), "coffeescript_source", v8::String::NewFromUtf8(this->get_isolate(), "a:4")); <<<===== THIS LINE - if I move it below context creation, the variable is not seen when used later
auto local_context = v8::Context::New(this->isolate, NULL, ot);
this->context = CopyablePersistent<v8::Context>(this->get_isolate(), local_context);
context_created = true;
}
}
elsewhere...
// this is my own wrapper.. it calls the run function at the very bottom which calls compile and then the other run method
javascript_engine->run("coffeescript_source");
JavascriptEngine::CopyablePersistent<v8::Script> JavascriptEngine::compile(const char * javascript_source)
{
v8::HandleScope hs(this->get_isolate());
v8::Context::Scope context_scope(this->get_local(context));
// This catches any errors thrown during script compilation
v8::TryCatch try_catch(this->get_isolate());
assert(context_created);
v8::Local<v8::String> source =
v8::String::NewFromUtf8(this->isolate, javascript_source,
v8::NewStringType::kNormal).ToLocalChecked();
// Compile the source code.
v8::MaybeLocal<v8::Script> compiled_script = v8::Script::Compile(this->get_local(this->context), source).ToLocalChecked();
if (compiled_script.IsEmpty()) {
v8::String::Utf8Value error(try_catch.Exception());
printf("%s\n", *error);
throw *error;
}
auto persistent_script = v8::Persistent<v8::Script, v8::CopyablePersistentTraits<v8::Script>>(this->get_isolate(), compiled_script.ToLocalChecked());
return persistent_script;
}
void JavascriptEngine::run(v8::Persistent<v8::Script, v8::CopyablePersistentTraits<v8::Script>> script)
{
v8::Isolate::Scope is(this->get_isolate());
v8::HandleScope hs(this->get_isolate());
v8::Context::Scope context_scope(this->get_local(context));
// auto local_script = this->get_local(script);
auto local_script = v8::Local<v8::Script>::New(this->get_isolate(), script);
v8::Local<v8::Value> result = local_script->Run(this->get_local(this->context)).ToLocalChecked();
// Convert the result to an UTF8 string and print it.
v8::String::Utf8Value utf8(result);
printf("%s\n", *utf8);
}
void JavascriptEngine::run(const char * code)
{
run(compile(code));
}
prints either:
a:4
or if the ->Set line is moved after context creation:
<unknown>:0: Uncaught ReferenceError: coffeescript_source is not defined
class JavascriptEngine {
public:
template <class T>
using CopyablePersistent = v8::Persistent<T, v8::CopyablePersistentTraits<T>>;
private:
static std::unique_ptr<v8::Platform> platform;
v8::Isolate * isolate;
v8::Persistent<v8::Context> context;
CopyablePersistent<v8::ObjectTemplate> global_object_template;
static ArrayBufferAllocator allocator;
public:
static void init(int argc, char ** argv);
static void cleanup();
JavascriptEngine();
virtual ~JavascriptEngine();
v8::Isolate * get_isolate() {return this->isolate;}
CopyablePersistent<v8::Script> compile(const char *);
CopyablePersistent<v8::Script> compile_from_file(const char *);
void run(CopyablePersistent<v8::Script> script);
void run(const char *);
template <class T>
v8::Local<T> get_local(v8::Global<T> && global) {
v8::EscapableHandleScope escapable_handle_scope(this->get_isolate());
auto local = v8::Local<T>::New(this->get_isolate(), global);
return escapable_handle_scope.Escape(local);
}
template <class T>
v8::Local<T> get_local(CopyablePersistent<T> persistent) {
v8::EscapableHandleScope escapable_handle_scope(this->get_isolate());
auto local = v8::Local<T>::New(this->get_isolate(), persistent);
return escapable_handle_scope.Escape(local);
}
template<class T>
auto wrap_class() {
return V8ClassWrapper<T>::get_instance(this->isolate);
}
v8::Persistent<v8::Context> get_context(){return this->context;}
auto get_global_object_template(){return this->global_object_template;}
/// adds the "require" function to the javascript context to emulate node.js require
void add_require();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment