Skip to content

Commit b33af60

Browse files
hashseedCommit Bot
authored and
Commit Bot
committed
[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 <[email protected]> Commit-Queue: Yang Guo <[email protected]> Cr-Commit-Position: refs/heads/master@{#62830}
1 parent 9c76633 commit b33af60

File tree

3 files changed

+78
-59
lines changed

3 files changed

+78
-59
lines changed

include/v8.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,8 @@ class V8_EXPORT ScriptCompiler {
16991699
Local<String> arguments[], size_t context_extension_count,
17001700
Local<Object> context_extensions[],
17011701
CompileOptions options = kNoCompileOptions,
1702-
NoCacheReason no_cache_reason = kNoCacheNoReason);
1702+
NoCacheReason no_cache_reason = kNoCacheNoReason,
1703+
Local<ScriptOrModule>* script_or_module_out = nullptr);
17031704

17041705
/**
17051706
* Creates and returns code cache for the specified unbound_script.

src/api/api.cc

Lines changed: 69 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,70 +2496,83 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
24962496
Local<Context> v8_context, Source* source, size_t arguments_count,
24972497
Local<String> arguments[], size_t context_extension_count,
24982498
Local<Object> context_extensions[], CompileOptions options,
2499-
NoCacheReason no_cache_reason) {
2500-
PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext,
2501-
Function);
2502-
TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2499+
NoCacheReason no_cache_reason,
2500+
Local<ScriptOrModule>* script_or_module_out) {
2501+
Local<Function> result;
25032502

2504-
DCHECK(options == CompileOptions::kConsumeCodeCache ||
2505-
options == CompileOptions::kEagerCompile ||
2506-
options == CompileOptions::kNoCompileOptions);
2503+
{
2504+
PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext,
2505+
Function);
2506+
TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
25072507

2508-
i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2508+
DCHECK(options == CompileOptions::kConsumeCodeCache ||
2509+
options == CompileOptions::kEagerCompile ||
2510+
options == CompileOptions::kNoCompileOptions);
25092511

2510-
DCHECK(context->IsNativeContext());
2511-
i::Handle<i::SharedFunctionInfo> outer_info(
2512-
context->empty_function().shared(), isolate);
2513-
2514-
i::Handle<i::JSFunction> fun;
2515-
i::Handle<i::FixedArray> arguments_list =
2516-
isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
2517-
for (int i = 0; i < static_cast<int>(arguments_count); i++) {
2518-
i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
2519-
if (!IsIdentifier(isolate, argument)) return Local<Function>();
2520-
arguments_list->set(i, *argument);
2521-
}
2522-
2523-
for (size_t i = 0; i < context_extension_count; ++i) {
2524-
i::Handle<i::JSReceiver> extension =
2525-
Utils::OpenHandle(*context_extensions[i]);
2526-
if (!extension->IsJSObject()) return Local<Function>();
2527-
context = isolate->factory()->NewWithContext(
2528-
context,
2529-
i::ScopeInfo::CreateForWithScope(
2530-
isolate,
2531-
context->IsNativeContext()
2532-
? i::Handle<i::ScopeInfo>::null()
2533-
: i::Handle<i::ScopeInfo>(context->scope_info(), isolate)),
2534-
extension);
2535-
}
2512+
i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
25362513

2537-
i::Compiler::ScriptDetails script_details = GetScriptDetails(
2538-
isolate, source->resource_name, source->resource_line_offset,
2539-
source->resource_column_offset, source->source_map_url,
2540-
source->host_defined_options);
2514+
DCHECK(context->IsNativeContext());
25412515

2542-
i::ScriptData* script_data = nullptr;
2543-
if (options == kConsumeCodeCache) {
2544-
DCHECK(source->cached_data);
2545-
// ScriptData takes care of pointer-aligning the data.
2546-
script_data = new i::ScriptData(source->cached_data->data,
2547-
source->cached_data->length);
2516+
i::Handle<i::FixedArray> arguments_list =
2517+
isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
2518+
for (int i = 0; i < static_cast<int>(arguments_count); i++) {
2519+
i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
2520+
if (!IsIdentifier(isolate, argument)) return Local<Function>();
2521+
arguments_list->set(i, *argument);
2522+
}
2523+
2524+
for (size_t i = 0; i < context_extension_count; ++i) {
2525+
i::Handle<i::JSReceiver> extension =
2526+
Utils::OpenHandle(*context_extensions[i]);
2527+
if (!extension->IsJSObject()) return Local<Function>();
2528+
context = isolate->factory()->NewWithContext(
2529+
context,
2530+
i::ScopeInfo::CreateForWithScope(
2531+
isolate,
2532+
context->IsNativeContext()
2533+
? i::Handle<i::ScopeInfo>::null()
2534+
: i::Handle<i::ScopeInfo>(context->scope_info(), isolate)),
2535+
extension);
2536+
}
2537+
2538+
i::Compiler::ScriptDetails script_details = GetScriptDetails(
2539+
isolate, source->resource_name, source->resource_line_offset,
2540+
source->resource_column_offset, source->source_map_url,
2541+
source->host_defined_options);
2542+
2543+
i::ScriptData* script_data = nullptr;
2544+
if (options == kConsumeCodeCache) {
2545+
DCHECK(source->cached_data);
2546+
// ScriptData takes care of pointer-aligning the data.
2547+
script_data = new i::ScriptData(source->cached_data->data,
2548+
source->cached_data->length);
2549+
}
2550+
2551+
i::Handle<i::JSFunction> scoped_result;
2552+
has_pending_exception =
2553+
!i::Compiler::GetWrappedFunction(
2554+
Utils::OpenHandle(*source->source_string), arguments_list, context,
2555+
script_details, source->resource_options, script_data, options,
2556+
no_cache_reason)
2557+
.ToHandle(&scoped_result);
2558+
if (options == kConsumeCodeCache) {
2559+
source->cached_data->rejected = script_data->rejected();
2560+
}
2561+
delete script_data;
2562+
RETURN_ON_FAILED_EXECUTION(Function);
2563+
result = handle_scope.Escape(Utils::CallableToLocal(scoped_result));
25482564
}
25492565

2550-
i::Handle<i::JSFunction> result;
2551-
has_pending_exception =
2552-
!i::Compiler::GetWrappedFunction(
2553-
Utils::OpenHandle(*source->source_string), arguments_list, context,
2554-
script_details, source->resource_options, script_data, options,
2555-
no_cache_reason)
2556-
.ToHandle(&result);
2557-
if (options == kConsumeCodeCache) {
2558-
source->cached_data->rejected = script_data->rejected();
2566+
if (script_or_module_out != nullptr) {
2567+
i::Handle<i::JSFunction> function =
2568+
i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*result));
2569+
i::Isolate* isolate = function->GetIsolate();
2570+
i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate);
2571+
i::Handle<i::Script> script(i::Script::cast(shared->script()), isolate);
2572+
*script_or_module_out = v8::Utils::ScriptOrModuleToLocal(script);
25592573
}
2560-
delete script_data;
2561-
RETURN_ON_FAILED_EXECUTION(Function);
2562-
RETURN_ESCAPED(Utils::CallableToLocal(result));
2574+
2575+
return result;
25632576
}
25642577

25652578
void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); }

test/cctest/test-compiler.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,11 +650,16 @@ TEST(CompileFunctionInContextScriptOrigin) {
650650
v8::Integer::New(CcTest::isolate(), 22),
651651
v8::Integer::New(CcTest::isolate(), 41));
652652
v8::ScriptCompiler::Source script_source(v8_str("throw new Error()"), origin);
653+
Local<ScriptOrModule> script;
653654
v8::Local<v8::Function> fun =
654-
v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source,
655-
0, nullptr, 0, nullptr)
655+
v8::ScriptCompiler::CompileFunctionInContext(
656+
env.local(), &script_source, 0, nullptr, 0, nullptr,
657+
v8::ScriptCompiler::CompileOptions::kNoCompileOptions,
658+
v8::ScriptCompiler::NoCacheReason::kNoCacheNoReason, &script)
656659
.ToLocalChecked();
657660
CHECK(!fun.IsEmpty());
661+
CHECK(!script.IsEmpty());
662+
CHECK(script->GetResourceName()->StrictEquals(v8_str("test")));
658663
v8::TryCatch try_catch(CcTest::isolate());
659664
CcTest::isolate()->SetCaptureStackTraceForUncaughtExceptions(true);
660665
CHECK(fun->Call(env.local(), env->Global(), 0, nullptr).IsEmpty());

0 commit comments

Comments
 (0)