Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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: nodejs/node-v8#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: v8/v8@b33af60

Backport-PR-URL: #28779
PR-URL: #28671
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
  • Loading branch information
devsnek authored and targos committed Aug 9, 2019
commit b2ba22677fa6d83f2b3252ae711a53c7b44006a9
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -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.13',
'v8_embedder_string': '-node.14',

##### V8 defaults for Node.js #####

Expand Down
7 changes: 7 additions & 0 deletions deps/v8/include/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -1670,6 +1670,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
Expand Down
133 changes: 78 additions & 55 deletions deps/v8/src/api/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2442,69 +2442,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(); }
Expand Down
9 changes: 7 additions & 2 deletions deps/v8/test/cctest/test-compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down