From 84d3243ce92143b0fa4d6b868c27b715f4681d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Sat, 20 Jul 2019 13:39:10 +0200 Subject: [PATCH] deps: V8: cherry-pick b33af60 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit message: [api] Get ScriptOrModule from CompileFunctionInContext Adds a new out param which allows accessing the ScriptOrModule of a function, which allows an embedder such as Node.js to use the function's i::Script lifetime. Refs: https://github.com/nodejs/node-v8/issues/111 Change-Id: I34346d94d76e8f9b8377c97d948673f4b95eb9d5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1699698 Reviewed-by: Yang Guo Commit-Queue: Yang Guo Cr-Commit-Position: refs/heads/master@{#62830} Refs: https://github.com/v8/v8/commit/b33af60dd9e7e5b2557b9fbf3fdb80209f6db844 PR-URL: https://github.com/nodejs/node/pull/28016 Reviewed-By: Colin Ihrig Reviewed-By: Refael Ackermann (רפאל פלחי) Reviewed-By: Rich Trott Reviewed-By: Michael Dawson Reviewed-By: Jiawen Geng --- common.gypi | 2 +- deps/v8/include/v8.h | 3 +- deps/v8/src/api/api.cc | 125 +++++++++++++++------------ deps/v8/test/cctest/test-compiler.cc | 9 +- 4 files changed, 79 insertions(+), 60 deletions(-) diff --git a/common.gypi b/common.gypi index 10b4ecfc52e2fb..78a57d929198be 100644 --- a/common.gypi +++ b/common.gypi @@ -39,7 +39,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.13', + 'v8_embedder_string': '-node.14', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 09da82fd61ed40..6a6dbb519327cd 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -1668,7 +1668,8 @@ class V8_EXPORT ScriptCompiler { Local arguments[], size_t context_extension_count, Local context_extensions[], CompileOptions options = kNoCompileOptions, - NoCacheReason no_cache_reason = kNoCacheNoReason); + NoCacheReason no_cache_reason = kNoCacheNoReason, + Local* script_or_module_out = nullptr); /** * Creates and returns code cache for the specified unbound_script. diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc index 399aca7eb61dff..90ff932215ffaf 100644 --- a/deps/v8/src/api/api.cc +++ b/deps/v8/src/api/api.cc @@ -2441,70 +2441,83 @@ MaybeLocal ScriptCompiler::CompileFunctionInContext( Local v8_context, Source* source, size_t arguments_count, Local arguments[], size_t context_extension_count, Local context_extensions[], CompileOptions options, - NoCacheReason no_cache_reason) { - PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext, - Function); - TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler"); + NoCacheReason no_cache_reason, + Local* script_or_module_out) { + Local result; - DCHECK(options == CompileOptions::kConsumeCodeCache || - options == CompileOptions::kEagerCompile || - options == CompileOptions::kNoCompileOptions); + { + PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext, + Function); + TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler"); - i::Handle context = Utils::OpenHandle(*v8_context); + DCHECK(options == CompileOptions::kConsumeCodeCache || + options == CompileOptions::kEagerCompile || + options == CompileOptions::kNoCompileOptions); - DCHECK(context->IsNativeContext()); - i::Handle outer_info( - context->empty_function().shared(), isolate); - - i::Handle fun; - i::Handle arguments_list = - isolate->factory()->NewFixedArray(static_cast(arguments_count)); - for (int i = 0; i < static_cast(arguments_count); i++) { - i::Handle argument = Utils::OpenHandle(*arguments[i]); - if (!IsIdentifier(isolate, argument)) return Local(); - arguments_list->set(i, *argument); - } - - for (size_t i = 0; i < context_extension_count; ++i) { - i::Handle extension = - Utils::OpenHandle(*context_extensions[i]); - if (!extension->IsJSObject()) return Local(); - context = isolate->factory()->NewWithContext( - context, - i::ScopeInfo::CreateForWithScope( - isolate, - context->IsNativeContext() - ? i::Handle::null() - : i::Handle(context->scope_info(), isolate)), - extension); - } + i::Handle context = Utils::OpenHandle(*v8_context); - i::Compiler::ScriptDetails script_details = GetScriptDetails( - isolate, source->resource_name, source->resource_line_offset, - source->resource_column_offset, source->source_map_url, - source->host_defined_options); + DCHECK(context->IsNativeContext()); - i::ScriptData* script_data = nullptr; - if (options == kConsumeCodeCache) { - DCHECK(source->cached_data); - // ScriptData takes care of pointer-aligning the data. - script_data = new i::ScriptData(source->cached_data->data, - source->cached_data->length); + i::Handle arguments_list = + isolate->factory()->NewFixedArray(static_cast(arguments_count)); + for (int i = 0; i < static_cast(arguments_count); i++) { + i::Handle argument = Utils::OpenHandle(*arguments[i]); + if (!IsIdentifier(isolate, argument)) return Local(); + arguments_list->set(i, *argument); + } + + for (size_t i = 0; i < context_extension_count; ++i) { + i::Handle extension = + Utils::OpenHandle(*context_extensions[i]); + if (!extension->IsJSObject()) return Local(); + context = isolate->factory()->NewWithContext( + context, + i::ScopeInfo::CreateForWithScope( + isolate, + context->IsNativeContext() + ? i::Handle::null() + : i::Handle(context->scope_info(), isolate)), + extension); + } + + i::Compiler::ScriptDetails script_details = GetScriptDetails( + isolate, source->resource_name, source->resource_line_offset, + source->resource_column_offset, source->source_map_url, + source->host_defined_options); + + i::ScriptData* script_data = nullptr; + if (options == kConsumeCodeCache) { + DCHECK(source->cached_data); + // ScriptData takes care of pointer-aligning the data. + script_data = new i::ScriptData(source->cached_data->data, + source->cached_data->length); + } + + i::Handle scoped_result; + has_pending_exception = + !i::Compiler::GetWrappedFunction( + Utils::OpenHandle(*source->source_string), arguments_list, context, + script_details, source->resource_options, script_data, options, + no_cache_reason) + .ToHandle(&scoped_result); + if (options == kConsumeCodeCache) { + source->cached_data->rejected = script_data->rejected(); + } + delete script_data; + RETURN_ON_FAILED_EXECUTION(Function); + result = handle_scope.Escape(Utils::CallableToLocal(scoped_result)); } - i::Handle result; - has_pending_exception = - !i::Compiler::GetWrappedFunction( - Utils::OpenHandle(*source->source_string), arguments_list, context, - script_details, source->resource_options, script_data, options, - no_cache_reason) - .ToHandle(&result); - if (options == kConsumeCodeCache) { - source->cached_data->rejected = script_data->rejected(); + if (script_or_module_out != nullptr) { + i::Handle function = + i::Handle::cast(Utils::OpenHandle(*result)); + i::Isolate* isolate = function->GetIsolate(); + i::Handle shared(function->shared(), isolate); + i::Handle script(i::Script::cast(shared->script()), isolate); + *script_or_module_out = v8::Utils::ScriptOrModuleToLocal(script); } - delete script_data; - RETURN_ON_FAILED_EXECUTION(Function); - RETURN_ESCAPED(Utils::CallableToLocal(result)); + + return result; } void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); } diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc index 28867a89efa809..660ee98a9a110c 100644 --- a/deps/v8/test/cctest/test-compiler.cc +++ b/deps/v8/test/cctest/test-compiler.cc @@ -650,11 +650,16 @@ TEST(CompileFunctionInContextScriptOrigin) { v8::Integer::New(CcTest::isolate(), 22), v8::Integer::New(CcTest::isolate(), 41)); v8::ScriptCompiler::Source script_source(v8_str("throw new Error()"), origin); + Local script; v8::Local fun = - v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, - 0, nullptr, 0, nullptr) + v8::ScriptCompiler::CompileFunctionInContext( + env.local(), &script_source, 0, nullptr, 0, nullptr, + v8::ScriptCompiler::CompileOptions::kNoCompileOptions, + v8::ScriptCompiler::NoCacheReason::kNoCacheNoReason, &script) .ToLocalChecked(); CHECK(!fun.IsEmpty()); + CHECK(!script.IsEmpty()); + CHECK(script->GetResourceName()->StrictEquals(v8_str("test"))); v8::TryCatch try_catch(CcTest::isolate()); CcTest::isolate()->SetCaptureStackTraceForUncaughtExceptions(true); CHECK(fun->Call(env.local(), env->Global(), 0, nullptr).IsEmpty());