diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-07-20 13:39:10 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-08-01 12:56:38 +0200 |
commit | 84d3243ce92143b0fa4d6b868c27b715f4681d0b (patch) | |
tree | 4840cb9ce58d8f4d8b908602b58a7579e43a690a /deps | |
parent | 3b7c95220b7f3bb637d3b2d98dad3d590574e26a (diff) | |
download | android-node-v8-84d3243ce92143b0fa4d6b868c27b715f4681d0b.tar.gz android-node-v8-84d3243ce92143b0fa4d6b868c27b715f4681d0b.tar.bz2 android-node-v8-84d3243ce92143b0fa4d6b868c27b715f4681d0b.zip |
deps: V8: cherry-pick b33af60
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 <yangguo@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
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 <cjihrig@gmail.com>
Reviewed-By: Refael Ackermann (רפאל פלחי) <refack@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r-- | deps/v8/include/v8.h | 3 | ||||
-rw-r--r-- | deps/v8/src/api/api.cc | 125 | ||||
-rw-r--r-- | deps/v8/test/cctest/test-compiler.cc | 9 |
3 files changed, 78 insertions, 59 deletions
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 09da82fd61..6a6dbb5193 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -1668,7 +1668,8 @@ class V8_EXPORT ScriptCompiler { Local<String> arguments[], size_t context_extension_count, Local<Object> context_extensions[], CompileOptions options = kNoCompileOptions, - NoCacheReason no_cache_reason = kNoCacheNoReason); + NoCacheReason no_cache_reason = kNoCacheNoReason, + Local<ScriptOrModule>* 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 399aca7eb6..90ff932215 100644 --- a/deps/v8/src/api/api.cc +++ b/deps/v8/src/api/api.cc @@ -2441,70 +2441,83 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext( Local<Context> v8_context, Source* source, size_t arguments_count, Local<String> arguments[], size_t context_extension_count, Local<Object> 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<ScriptOrModule>* script_or_module_out) { + Local<Function> 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<i::Context> context = Utils::OpenHandle(*v8_context); + DCHECK(options == CompileOptions::kConsumeCodeCache || + options == CompileOptions::kEagerCompile || + options == CompileOptions::kNoCompileOptions); - DCHECK(context->IsNativeContext()); - i::Handle<i::SharedFunctionInfo> outer_info( - context->empty_function().shared(), isolate); - - i::Handle<i::JSFunction> fun; - i::Handle<i::FixedArray> arguments_list = - isolate->factory()->NewFixedArray(static_cast<int>(arguments_count)); - for (int i = 0; i < static_cast<int>(arguments_count); i++) { - i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]); - if (!IsIdentifier(isolate, argument)) return Local<Function>(); - arguments_list->set(i, *argument); - } - - for (size_t i = 0; i < context_extension_count; ++i) { - i::Handle<i::JSReceiver> extension = - Utils::OpenHandle(*context_extensions[i]); - if (!extension->IsJSObject()) return Local<Function>(); - context = isolate->factory()->NewWithContext( - context, - i::ScopeInfo::CreateForWithScope( - isolate, - context->IsNativeContext() - ? i::Handle<i::ScopeInfo>::null() - : i::Handle<i::ScopeInfo>(context->scope_info(), isolate)), - extension); - } + i::Handle<i::Context> 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<i::FixedArray> arguments_list = + isolate->factory()->NewFixedArray(static_cast<int>(arguments_count)); + for (int i = 0; i < static_cast<int>(arguments_count); i++) { + i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]); + if (!IsIdentifier(isolate, argument)) return Local<Function>(); + arguments_list->set(i, *argument); + } + + for (size_t i = 0; i < context_extension_count; ++i) { + i::Handle<i::JSReceiver> extension = + Utils::OpenHandle(*context_extensions[i]); + if (!extension->IsJSObject()) return Local<Function>(); + context = isolate->factory()->NewWithContext( + context, + i::ScopeInfo::CreateForWithScope( + isolate, + context->IsNativeContext() + ? i::Handle<i::ScopeInfo>::null() + : i::Handle<i::ScopeInfo>(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<i::JSFunction> 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<i::JSFunction> 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<i::JSFunction> function = + i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*result)); + i::Isolate* isolate = function->GetIsolate(); + i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate); + i::Handle<i::Script> 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 28867a89ef..660ee98a9a 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<ScriptOrModule> script; v8::Local<v8::Function> 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()); |