[d8] Fix stack overflow when importing modules

Bug: chromium:740694
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: Ib23bca1942c25d8a9f32e12be3f7b50fc3ab55c8
Reviewed-on: https://chromium-review.googlesource.com/568222
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46611}
This commit is contained in:
Sathya Gunasekaran 2017-07-12 15:15:39 -07:00 committed by Commit Bot
parent 293d84c737
commit ea632716d7
6 changed files with 46 additions and 17 deletions

View File

@ -6135,7 +6135,7 @@ typedef void (*DeprecatedCallCompletedCallback)();
* namespace object. In case of an exception, the embedder must reject
* this promise with the exception.
*/
typedef Local<Promise> (*HostImportModuleDynamicallyCallback)(
typedef MaybeLocal<Promise> (*HostImportModuleDynamicallyCallback)(
Local<Context> context, Local<String> referrer, Local<String> specifier);
/**

View File

@ -792,16 +792,21 @@ struct DynamicImportData {
} // namespace
Local<Promise> Shell::HostImportModuleDynamically(Local<Context> context,
Local<String> referrer,
Local<String> specifier) {
MaybeLocal<Promise> Shell::HostImportModuleDynamically(
Local<Context> context, Local<String> referrer, Local<String> specifier) {
Isolate* isolate = context->GetIsolate();
Local<Promise::Resolver> resolver =
Promise::Resolver::New(context).ToLocalChecked();
DynamicImportData* data =
new DynamicImportData(isolate, referrer, specifier, resolver);
isolate->EnqueueMicrotask(Shell::DoHostImportModuleDynamically, data);
return resolver->GetPromise();
MaybeLocal<Promise::Resolver> maybe_resolver =
Promise::Resolver::New(context);
Local<Promise::Resolver> resolver;
if (maybe_resolver.ToLocal(&resolver)) {
DynamicImportData* data =
new DynamicImportData(isolate, referrer, specifier, resolver);
isolate->EnqueueMicrotask(Shell::DoHostImportModuleDynamically, data);
return resolver->GetPromise();
}
return MaybeLocal<Promise>();
}
void Shell::DoHostImportModuleDynamically(void* import_data) {

View File

@ -444,9 +444,8 @@ class Shell : public i::AllStatic {
static void SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args);
static void MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
static void RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
static Local<Promise> HostImportModuleDynamically(Local<Context> context,
Local<String> referrer,
Local<String> specifier);
static MaybeLocal<Promise> HostImportModuleDynamically(
Local<Context> context, Local<String> referrer, Local<String> specifier);
// Data is of type DynamicImportData*. We use void* here to be able
// to conform with MicrotaskCallback interface and enqueue this

View File

@ -3370,9 +3370,12 @@ MaybeHandle<JSPromise> Isolate::RunHostImportModuleDynamicallyCallback(
}
DCHECK(!has_pending_exception());
v8::Local<v8::Promise> promise = host_import_module_dynamically_callback_(
api_context, v8::Utils::ToLocal(source_url),
v8::Utils::ToLocal(specifier_str));
v8::MaybeLocal<v8::Promise> maybe_promise =
host_import_module_dynamically_callback_(
api_context, v8::Utils::ToLocal(source_url),
v8::Utils::ToLocal(specifier_str));
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(this, MaybeHandle<JSPromise>());
v8::Local<v8::Promise> promise = maybe_promise.ToLocalChecked();
return v8::Utils::OpenHandle(*promise);
}

View File

@ -26888,7 +26888,7 @@ TEST(CorrectEnteredContext) {
object->ToString(currentContext.local()).ToLocalChecked();
}
Local<v8::Promise> HostImportModuleDynamicallyCallbackResolve(
v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallbackResolve(
Local<Context> context, Local<String> referrer, Local<String> specifier) {
CHECK(!referrer.IsEmpty());
String::Utf8Value referrer_utf8(referrer);

View File

@ -0,0 +1,22 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony --allow-natives-syntax --stack-size=100
function __f_0() {
try {
return __f_0();
} catch(e) {
return import('no-such-file');
}
}
var done = false;
var error;
var promise = __f_0();
promise.then(assertUnreachable,
err => { done = true; error = err });
%RunMicrotasks();
assertTrue(error.startsWith('Error reading'));
assertTrue(done);