summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGus Caplan <me@gus.host>2019-07-19 09:22:56 -0500
committerMichaƫl Zasso <targos@protonmail.com>2019-07-23 08:13:20 +0200
commit674d33cb8c288b0e91d6e9e742e9739b2383e847 (patch)
treef78d58c9097e377e8cd6ead53a7ec3a4e79ef07c
parent85862946706349b8e3af889c104a5184f0ccdaea (diff)
downloadandroid-node-v8-674d33cb8c288b0e91d6e9e742e9739b2383e847.tar.gz
android-node-v8-674d33cb8c288b0e91d6e9e742e9739b2383e847.tar.bz2
android-node-v8-674d33cb8c288b0e91d6e9e742e9739b2383e847.zip
deps: V8: backport 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 Backport-PR-URL: https://github.com/nodejs/node/pull/28779 PR-URL: https://github.com/nodejs/node/pull/28671 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Guy Bedford <guybedford@gmail.com>
-rw-r--r--common.gypi2
-rw-r--r--deps/v8/include/v8.h7
-rw-r--r--deps/v8/src/api.cc133
-rw-r--r--deps/v8/test/cctest/test-compiler.cc9
4 files changed, 93 insertions, 58 deletions
diff --git a/common.gypi b/common.gypi
index 36e9745009..1eadd779a3 100644
--- a/common.gypi
+++ b/common.gypi
@@ -38,7 +38,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.15',
+ 'v8_embedder_string': '-node.16',
##### V8 defaults for Node.js #####
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h
index 3682c888cc..79c17ad57f 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -1703,6 +1703,13 @@ class V8_EXPORT ScriptCompiler {
CompileOptions options = kNoCompileOptions,
NoCacheReason no_cache_reason = kNoCacheNoReason);
+ static V8_WARN_UNUSED_RESULT MaybeLocal<Function> CompileFunctionInContext(
+ Local<Context> 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,
+ Local<ScriptOrModule>* script_or_module_out);
+
/**
* Creates and returns code cache for the specified unbound_script.
* This will return nullptr if the script cannot be serialized. The
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index f4f3fa309e..4127d6735a 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -2500,69 +2500,92 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
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");
+ return ScriptCompiler::CompileFunctionInContext(
+ v8_context, source, arguments_count, arguments, context_extension_count,
+ context_extensions, options, no_cache_reason, nullptr);
+}
- DCHECK(options == CompileOptions::kConsumeCodeCache ||
- options == CompileOptions::kEagerCompile ||
- options == CompileOptions::kNoCompileOptions);
+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,
+ Local<ScriptOrModule>* script_or_module_out) {
+ Local<Function> result;
- i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
+ {
+ PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext,
+ Function);
+ TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
- 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);
- }
+ DCHECK(options == CompileOptions::kConsumeCodeCache ||
+ options == CompileOptions::kEagerCompile ||
+ options == CompileOptions::kNoCompileOptions);
- 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::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
- 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);
+ DCHECK(context->IsNativeContext());
+
+ 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 17f7a7d851..cb559d8fe2 100644
--- a/deps/v8/test/cctest/test-compiler.cc
+++ b/deps/v8/test/cctest/test-compiler.cc
@@ -647,11 +647,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());