Commit a1241353 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[modules] Anticipate stack overflow when traversing module graph.

Bug: chromium:836124
Change-Id: I82d29408476c9c5b2c62a6368f32575e33932ef3
Reviewed-on: https://chromium-review.googlesource.com/1025890Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52774}
parent 44a000fd
...@@ -461,8 +461,10 @@ bool Module::PrepareInstantiate(Handle<Module> module, ...@@ -461,8 +461,10 @@ bool Module::PrepareInstantiate(Handle<Module> module,
if (module->status() >= kPreInstantiating) return true; if (module->status() >= kPreInstantiating) return true;
module->SetStatus(kPreInstantiating); module->SetStatus(kPreInstantiating);
// Obtain requested modules.
Isolate* isolate = module->GetIsolate(); Isolate* isolate = module->GetIsolate();
STACK_CHECK(isolate, false);
// Obtain requested modules.
Handle<ModuleInfo> module_info(module->info(), isolate); Handle<ModuleInfo> module_info(module->info(), isolate);
Handle<FixedArray> module_requests(module_info->module_requests(), isolate); Handle<FixedArray> module_requests(module_info->module_requests(), isolate);
Handle<FixedArray> requested_modules(module->requested_modules(), isolate); Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
...@@ -515,21 +517,26 @@ bool Module::PrepareInstantiate(Handle<Module> module, ...@@ -515,21 +517,26 @@ bool Module::PrepareInstantiate(Handle<Module> module,
return true; return true;
} }
void Module::RunInitializationCode(Handle<Module> module) { bool Module::RunInitializationCode(Handle<Module> module) {
DCHECK_EQ(module->status(), kInstantiating); DCHECK_EQ(module->status(), kInstantiating);
Isolate* isolate = module->GetIsolate(); Isolate* isolate = module->GetIsolate();
Handle<JSFunction> function(JSFunction::cast(module->code()), isolate); Handle<JSFunction> function(JSFunction::cast(module->code()), isolate);
DCHECK_EQ(MODULE_SCOPE, function->shared()->scope_info()->scope_type()); DCHECK_EQ(MODULE_SCOPE, function->shared()->scope_info()->scope_type());
Handle<Object> receiver = isolate->factory()->undefined_value(); Handle<Object> receiver = isolate->factory()->undefined_value();
Handle<Object> argv[] = {module}; Handle<Object> argv[] = {module};
Handle<Object> generator = MaybeHandle<Object> maybe_generator =
Execution::Call(isolate, function, receiver, arraysize(argv), argv) Execution::Call(isolate, function, receiver, arraysize(argv), argv);
.ToHandleChecked(); Handle<Object> generator;
if (!maybe_generator.ToHandle(&generator)) {
DCHECK(isolate->has_pending_exception());
return false;
}
DCHECK_EQ(*function, Handle<JSGeneratorObject>::cast(generator)->function()); DCHECK_EQ(*function, Handle<JSGeneratorObject>::cast(generator)->function());
module->set_code(*generator); module->set_code(*generator);
return true;
} }
void Module::MaybeTransitionComponent(Handle<Module> module, bool Module::MaybeTransitionComponent(Handle<Module> module,
ZoneForwardList<Handle<Module>>* stack, ZoneForwardList<Handle<Module>>* stack,
Status new_status) { Status new_status) {
DCHECK(new_status == kInstantiated || new_status == kEvaluated); DCHECK(new_status == kInstantiated || new_status == kEvaluated);
...@@ -546,10 +553,13 @@ void Module::MaybeTransitionComponent(Handle<Module> module, ...@@ -546,10 +553,13 @@ void Module::MaybeTransitionComponent(Handle<Module> module,
stack->pop_front(); stack->pop_front();
DCHECK_EQ(ancestor->status(), DCHECK_EQ(ancestor->status(),
new_status == kInstantiated ? kInstantiating : kEvaluating); new_status == kInstantiated ? kInstantiating : kEvaluating);
if (new_status == kInstantiated) RunInitializationCode(ancestor); if (new_status == kInstantiated) {
if (!RunInitializationCode(ancestor)) return false;
}
ancestor->SetStatus(new_status); ancestor->SetStatus(new_status);
} while (*ancestor != *module); } while (*ancestor != *module);
} }
return true;
} }
bool Module::FinishInstantiate(Handle<Module> module, bool Module::FinishInstantiate(Handle<Module> module,
...@@ -559,9 +569,11 @@ bool Module::FinishInstantiate(Handle<Module> module, ...@@ -559,9 +569,11 @@ bool Module::FinishInstantiate(Handle<Module> module,
if (module->status() >= kInstantiating) return true; if (module->status() >= kInstantiating) return true;
DCHECK_EQ(module->status(), kPreInstantiating); DCHECK_EQ(module->status(), kPreInstantiating);
Isolate* isolate = module->GetIsolate();
STACK_CHECK(isolate, false);
// Instantiate SharedFunctionInfo and mark module as instantiating for // Instantiate SharedFunctionInfo and mark module as instantiating for
// the recursion. // the recursion.
Isolate* isolate = module->GetIsolate();
Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(module->code()), Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(module->code()),
isolate); isolate);
Handle<JSFunction> function = Handle<JSFunction> function =
...@@ -635,8 +647,7 @@ bool Module::FinishInstantiate(Handle<Module> module, ...@@ -635,8 +647,7 @@ bool Module::FinishInstantiate(Handle<Module> module,
} }
} }
MaybeTransitionComponent(module, stack, kInstantiated); return MaybeTransitionComponent(module, stack, kInstantiated);
return true;
} }
MaybeHandle<Object> Module::Evaluate(Handle<Module> module) { MaybeHandle<Object> Module::Evaluate(Handle<Module> module) {
...@@ -688,6 +699,7 @@ MaybeHandle<Object> Module::Evaluate(Handle<Module> module, ...@@ -688,6 +699,7 @@ MaybeHandle<Object> Module::Evaluate(Handle<Module> module,
return isolate->factory()->undefined_value(); return isolate->factory()->undefined_value();
} }
DCHECK_EQ(module->status(), kInstantiated); DCHECK_EQ(module->status(), kInstantiated);
STACK_CHECK(isolate, MaybeHandle<Object>());
Handle<JSGeneratorObject> generator(JSGeneratorObject::cast(module->code()), Handle<JSGeneratorObject> generator(JSGeneratorObject::cast(module->code()),
isolate); isolate);
...@@ -734,7 +746,7 @@ MaybeHandle<Object> Module::Evaluate(Handle<Module> module, ...@@ -734,7 +746,7 @@ MaybeHandle<Object> Module::Evaluate(Handle<Module> module,
->done() ->done()
->BooleanValue()); ->BooleanValue());
MaybeTransitionComponent(module, stack, kEvaluated); CHECK(MaybeTransitionComponent(module, stack, kEvaluated));
return handle( return handle(
static_cast<JSIteratorResult*>(JSObject::cast(*result))->value(), static_cast<JSIteratorResult*>(JSObject::cast(*result))->value(),
isolate); isolate);
......
...@@ -172,15 +172,16 @@ class Module : public Struct { ...@@ -172,15 +172,16 @@ class Module : public Struct {
static V8_WARN_UNUSED_RESULT bool FinishInstantiate( static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
Handle<Module> module, ZoneForwardList<Handle<Module>>* stack, Handle<Module> module, ZoneForwardList<Handle<Module>>* stack,
unsigned* dfs_index, Zone* zone); unsigned* dfs_index, Zone* zone);
static void RunInitializationCode(Handle<Module> module); static V8_WARN_UNUSED_RESULT bool RunInitializationCode(
Handle<Module> module);
static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate( static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
Handle<Module> module, ZoneForwardList<Handle<Module>>* stack, Handle<Module> module, ZoneForwardList<Handle<Module>>* stack,
unsigned* dfs_index); unsigned* dfs_index);
static void MaybeTransitionComponent(Handle<Module> module, static V8_WARN_UNUSED_RESULT bool MaybeTransitionComponent(
ZoneForwardList<Handle<Module>>* stack, Handle<Module> module, ZoneForwardList<Handle<Module>>* stack,
Status new_status); Status new_status);
// Set module's status back to kUninstantiated and reset other internal state. // Set module's status back to kUninstantiated and reset other internal state.
// This is used when instantiation fails. // This is used when instantiation fails.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment