15 Context::Context(std::shared_ptr<Isolate> isolate_helper,
17 isolate_helper(isolate_helper),
18 isolate(isolate_helper->get_isolate()),
19 context(
v8::Global<
v8::
Context>(*isolate_helper, context))
37 return this->isolate_helper;
41 return this->isolate_helper->json(json);
57 time_t modification_time = 0;
63 return compile(contents, filename);
73 v8::TryCatch try_catch(
isolate);
76 v8::String::NewFromUtf8(this->
isolate, javascript_source.c_str());
80 v8::ScriptOrigin script_origin(v8::String::NewFromUtf8(
isolate, this->
get_url(filename).c_str()),
84 v8::Integer::New(
isolate, ++Context::script_id_counter)
88 v8::MaybeLocal<v8::Script> compiled_script = v8::Script::Compile(context.Get(
isolate), source, &script_origin);
89 if (compiled_script.IsEmpty()) {
92 return std::shared_ptr<Script>(
new Script(shared_from_this(),
93 compiled_script.ToLocalChecked(), javascript_source));
98 v8::Global<v8::Value>
Context::run(
const v8::Global<v8::Script> & script)
103 v8::TryCatch try_catch(
isolate);
106 auto maybe_result = local_script->Run(context.Get(
isolate));
107 if (try_catch.HasCaught()) {
114 if(maybe_result.IsEmpty()) {
119 if(e->IsExternal()) {
120 auto anybase = (
AnyBase *)v8::External::Cast(*e)->Value();
122 assert(anyptr_exception_ptr);
125 std::rethrow_exception(anyptr_exception_ptr->get());
132 return v8::Global<v8::Value>(
isolate, result);
138 return (*
this)([
this, source]{
139 auto compiled_code =
compile(source);
140 return compiled_code->run();
148 return (*
this)([
this, value]{
149 return run(*v8::String::Utf8Value(value));
161 return this->context;
165 std::future<std::pair<ScriptPtr, v8::Global<v8::Value>>>
170 return (*
this)([
this, source, launch_policy]{
171 return this->
compile(source)->run_async(launch_policy);
178 (*this)([
this, source]{
179 this->
compile(source)->run_detached();
186 return (*
this)([
this, source]{
187 return this->
compile(source)->run_thread();
197 return boost::uuids::to_string(this->uuid);
201 return fmt::format(
"v8toolkit://{}/{}", this->
get_uuid_string(), name);
211 require_result, paths,
false,
true, [
this](
RequireResult const & require_result) {},
214 return require_result;
220 this->
require(filename, {directory_name});
227 isolate->SetData(0, (
void *)&this->uuid);
229 this->global_object_template.Reset(isolate, v8::ObjectTemplate::New(this->
get_isolate()));
235 auto unbound_script = this->script.Get(isolate)->GetUnboundScript();
236 assert(!unbound_script.IsEmpty());
237 return unbound_script;
241 Isolate::operator v8::Isolate*()
249 return this->global_object_template.Get(this->isolate);
255 (*this)([
this, callback](){
273 (*this)([
this, paths]{
288 v8::TryCatch tc(this->isolate);
290 auto ot = this->get_object_template();
291 auto context = v8::Context::New(this->isolate, NULL, ot);
294 if (tc.HasCaught() || context.IsEmpty()) {
300 auto context_helper =
new Context(shared_from_this(), context);
302 return std::shared_ptr<Context>(context_helper);
307 v8::TryCatch tc(this->isolate);
309 auto ot = this->get_object_template();
310 auto context = v8::Context::New(this->isolate, NULL, ot);
313 if (tc.HasCaught() || context.IsEmpty()) {
319 auto debug_context =
new DebugContext(shared_from_this(), context, port);
321 return std::shared_ptr<DebugContext>(debug_context);
328 return global_object_template.Get(isolate);
334 assert(!debug_context.IsEmpty());
341 #ifdef V8TOOLKIT_JAVASCRIPT_DEBUG 342 printf(
"Deleting isolate helper %p for isolate %p\n",
this, this->isolate);
349 this->global_object_template.Reset();
350 this->isolate->Dispose();
357 add_function(
"assert", [](
const v8::FunctionCallbackInfo<v8::Value>& info) {
358 auto isolate = info.GetIsolate();
359 auto context = isolate->GetCurrentContext();
361 v8::TryCatch tc(isolate);
362 auto script_maybe = v8::Script::Compile(context, info[0]->ToString());
368 auto script = script_maybe.ToLocalChecked();
369 auto result_maybe = script->Run(context);
375 auto result = result_maybe.ToLocalChecked();
377 bool default_value =
false;
378 bool assert_result = result->BooleanValue(context).FromMaybe(default_value);
379 if (!assert_result) {
386 add_function(
"assert_contents", [
this](
const v8::FunctionCallbackInfo<v8::Value>& args){
387 auto isolate = args.GetIsolate();
397 assert(!Platform::initialized);
398 expose_gc_value =
true;
403 Platform::memory_size_in_mb = new_memory_size_in_mb;
410 assert(!initialized);
413 if (expose_gc_value) {
419 v8::V8::InitializeICU();
423 if (snapshot_directory !=
"") {
424 v8::V8::InitializeExternalStartupData(snapshot_directory.c_str());
427 Platform::platform = std::unique_ptr<v8::Platform>(v8::platform::CreateDefaultPlatform());
428 v8::V8::InitializePlatform(platform.get());
429 v8::V8::Initialize();
439 v8::V8::ShutdownPlatform();
447 v8::Isolate::CreateParams create_params;
448 if (Platform::memory_size_in_mb > 0) {
449 create_params.constraints.set_max_old_space_size(Platform::memory_size_in_mb);
454 auto isolate_helper =
new Isolate(v8::Isolate::New(create_params));
456 return std::shared_ptr<Isolate>(isolate_helper);
463 context_helper(context_helper),
464 isolate(context_helper->get_isolate()),
465 script(v8::Global<v8::Script>(isolate, script)),
466 script_source_code(source_code)
477 return std::thread([
this](
auto script_helper)->
void{
481 }, shared_from_this());
490 return this->script_source_code;
495 return std::string(
"v8toolkit://") + this->context_helper->get_uuid_string() +
"/" + *v8::String::Utf8Value(this->script.Get(this->isolate)->GetUnboundScript()->GetScriptName());
500 auto unbound_script = this->get_unbound_script();
501 auto id = unbound_script->GetId();
509 bool Platform::initialized =
false;
510 std::unique_ptr<v8::Platform> Platform::platform;
513 bool Platform::expose_gc_value =
false;
514 int Platform::memory_size_in_mb = -1;
v8::Global< v8::Value > run_from_file(const std::string &filename)
v8::Global< v8::Value > run(const v8::Global< v8::Script > &script)
void run_detached(const v8::Global< v8::Script > &script)
v8::Local< v8::Value > require(std::string const &filename, std::vector< std::string > const &paths)
boost::uuids::uuid const & get_uuid() const
v8::Isolate *const isolate
shortcut to the v8::isolate object instead of always going through the Isolate
v8::Global< v8::Context > const & get_global_context() const
void require_directory(std::string const &directory_name)
std::shared_ptr< Script > compile(const std::string &source, const std::string &filename="Unspecified")
std::shared_ptr< Isolate > get_isolate_helper() const
std::thread run_thread(const v8::Global< v8::Script > &script)
v8::Local< v8::Value > json(const std::string &json)
void add_function(std::string name, Function function)
v8::Local< v8::Context > get_context() const
v8::Isolate * get_isolate() const
std::shared_ptr< Script > compile_from_file(const std::string &filename)
std::future< std::pair< ScriptPtr, v8::Global< v8::Value > > > run_async(const std::string &source, std::launch launch_policy=std::launch::async|std::launch::deferred)
std::string get_url(std::string const &name) const
std::string get_uuid_string() const