Commit f537d778 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[async] First prototype of zero-cost async stack traces.

This introduces a new flag --async-stack-traces, which enables zero-cost
async stack traces. This enriches the non-standard Error.stack property
with async stack frames computed from walking up the promise chains and
collecting all the await suspension points along the way. In Error.stack
these async frames are marked with "async" to make it possible to
distinguish them from regular frames, for example:

```
Error: Some error message
    at bar (<anonymous>)
    at async foo (<anonymous>)
```

It's zero-cost because no additional information is collected during the
execution of the program, but only the information already present in the
promise chains is used to reconstruct an approximation of the async stack
in case of an exception. But this approximation is limited to suspension
points at await's in async functions. This depends on a recent ECMAScript
specification change, flagged behind --harmony-await-optimization and
implied the --async-stack-traces flag. Without this change there's no
way to get from the outer promise of an async function to the rest of
the promise chain, since the link is broken by the indirection introduced
by await.

For async functions the special outer promise, named .promise in the
Parser desugaring, is now forcible allocated to stack slot 0 during
scope resolution, to make it accessible to the stack frame construction
logic. Note that this first prototype doesn't yet work fully support
async generators and might have other limitations.

Bug: v8:7522
Ref: nodejs/node#11865
Change-Id: I0cc8e3cdfe45dab56d3d506be2d25907409b01a9
Design-Document: http://bit.ly/v8-zero-cost-async-stack-traces
Reviewed-on: https://chromium-review.googlesource.com/c/1256762
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56363}
parent 25aa6c51
......@@ -308,6 +308,7 @@ void DeclarationScope::SetDefaults() {
has_arguments_parameter_ = false;
scope_uses_super_property_ = false;
has_rest_ = false;
has_promise_ = false;
sloppy_block_function_map_ = nullptr;
receiver_ = nullptr;
new_target_ = nullptr;
......@@ -785,6 +786,7 @@ Variable* DeclarationScope::DeclarePromiseVar(const AstRawString* name) {
DCHECK_NULL(promise_var());
Variable* result = EnsureRareData()->promise = NewTemporary(name);
result->set_is_used();
has_promise_ = true;
return result;
}
......@@ -1491,6 +1493,7 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
sloppy_block_function_map_ = nullptr;
rare_data_ = nullptr;
has_rest_ = false;
has_promise_ = false;
DCHECK_NE(zone_, ast_value_factory->zone());
zone_->ReleaseMemory();
......@@ -2172,6 +2175,15 @@ void DeclarationScope::AllocateReceiver() {
AllocateParameter(receiver(), -1);
}
void DeclarationScope::AllocatePromise() {
if (!has_promise_) return;
DCHECK_NOT_NULL(promise_var());
DCHECK_EQ(this, promise_var()->scope());
AllocateStackSlot(promise_var());
DCHECK_EQ(VariableLocation::LOCAL, promise_var()->location());
DCHECK_EQ(kPromiseVarIndex, promise_var()->index());
}
void Scope::AllocateNonParameterLocal(Variable* var) {
DCHECK(var->scope() == this);
if (var->IsUnallocated() && MustAllocate(var)) {
......@@ -2240,6 +2252,11 @@ void Scope::AllocateVariablesRecursively() {
return;
}
// Make sure to allocate the .promise first, so that it get's
// the required stack slot 0 in case it's needed. See
// http://bit.ly/v8-zero-cost-async-stack-traces for details.
if (is_function_scope()) AsDeclarationScope()->AllocatePromise();
// Allocate variables for inner scopes.
for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
scope->AllocateVariablesRecursively();
......
......@@ -771,6 +771,9 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
return GetRareVariable(RareVariable::kGeneratorObject);
}
// The variable holding the promise returned from async functions.
// Only valid for function scopes in async functions (i.e. not
// for async generators).
Variable* promise_var() const {
DCHECK(is_function_scope());
DCHECK(IsAsyncFunction(function_kind_));
......@@ -778,6 +781,11 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
return GetRareVariable(RareVariable::kPromise);
}
// For async functions, the .promise variable is always allocated
// to a fixed stack slot, such that the stack trace construction
// logic can access it.
static constexpr int kPromiseVarIndex = 0;
// Parameters. The left-most parameter has index 0.
// Only valid for function and module scopes.
Variable* parameter(int index) const {
......@@ -905,6 +913,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
void AllocateLocals();
void AllocateParameterLocals();
void AllocateReceiver();
void AllocatePromise();
void ResetAfterPreparsing(AstValueFactory* ast_value_factory, bool aborted);
......@@ -961,6 +970,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
bool force_eager_compilation_ : 1;
// This function scope has a rest parameter.
bool has_rest_ : 1;
// This function scope has a .promise variable.
bool has_promise_ : 1;
// This scope has a parameter called "arguments".
bool has_arguments_parameter_ : 1;
// This scope uses "super" property ('super.foo').
......
......@@ -4362,6 +4362,7 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
Builtins::kCallSitePrototypeGetScriptNameOrSourceURL},
{"getThis", Builtins::kCallSitePrototypeGetThis},
{"getTypeName", Builtins::kCallSitePrototypeGetTypeName},
{"isAsync", Builtins::kCallSitePrototypeIsAsync},
{"isConstructor", Builtins::kCallSitePrototypeIsConstructor},
{"isEval", Builtins::kCallSitePrototypeIsEval},
{"isNative", Builtins::kCallSitePrototypeIsNative},
......
......@@ -137,6 +137,14 @@ BUILTIN(CallSitePrototypeGetTypeName) {
return *it.Frame()->GetTypeName();
}
BUILTIN(CallSitePrototypeIsAsync) {
HandleScope scope(isolate);
CHECK_CALLSITE(recv, "isAsync");
FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
GetFrameIndex(isolate, recv));
return isolate->heap()->ToBoolean(it.Frame()->IsAsync());
}
BUILTIN(CallSitePrototypeIsConstructor) {
HandleScope scope(isolate);
CHECK_CALLSITE(recv, "isConstructor");
......
......@@ -468,6 +468,7 @@ namespace internal {
CPP(CallSitePrototypeGetScriptNameOrSourceURL) \
CPP(CallSitePrototypeGetThis) \
CPP(CallSitePrototypeGetTypeName) \
CPP(CallSitePrototypeIsAsync) \
CPP(CallSitePrototypeIsConstructor) \
CPP(CallSitePrototypeIsEval) \
CPP(CallSitePrototypeIsNative) \
......
......@@ -265,6 +265,8 @@ bool Builtins::IsLazy(int index) {
case kArrayReduceRightPreLoopEagerDeoptContinuation:
case kArraySomeLoopEagerDeoptContinuation:
case kArraySomeLoopLazyDeoptContinuation:
case kAsyncFunctionAwaitResolveClosure: // https://crbug.com/v8/7522
case kAsyncFunctionAwaitRejectClosure: // https://crbug.com/v8/7522
case kAsyncGeneratorAwaitCaught: // https://crbug.com/v8/6786.
case kAsyncGeneratorAwaitUncaught: // https://crbug.com/v8/6786.
// CEntry variants must be immovable, whereas lazy deserialization allocates
......
......@@ -1042,6 +1042,9 @@ DEFINE_BOOL(trace_sim_messages, false,
"Trace simulator debug messages. Implied by --trace-sim.")
// isolate.cc
DEFINE_BOOL(async_stack_traces, false,
"include async stack traces in Error.stack")
DEFINE_IMPLICATION(async_stack_traces, harmony_await_optimization)
DEFINE_BOOL(stack_trace_on_illegal, false,
"print stack trace when an illegal exception is thrown")
DEFINE_BOOL(abort_on_uncaught_exception, false,
......
......@@ -15,6 +15,7 @@
#include "src/assembler-inl.h"
#include "src/ast/ast-value-factory.h"
#include "src/ast/context-slot-cache.h"
#include "src/ast/scopes.h"
#include "src/base/adapters.h"
#include "src/base/hashmap.h"
#include "src/base/platform/platform.h"
......@@ -28,6 +29,7 @@
#include "src/compilation-statistics.h"
#include "src/compiler-dispatcher/compiler-dispatcher.h"
#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
#include "src/debug/debug-frames.h"
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
#include "src/elements.h"
......@@ -42,6 +44,7 @@
#include "src/objects/frame-array-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/module-inl.h"
#include "src/objects/promise-inl.h"
#include "src/objects/stack-frame-info-inl.h"
......@@ -408,82 +411,87 @@ class FrameArrayBuilder {
elements_ = isolate->factory()->NewFrameArray(Min(limit, 10));
}
void AppendStandardFrame(StandardFrame* frame) {
std::vector<FrameSummary> frames;
frame->Summarize(&frames);
// A standard frame may include many summarized frames (due to inlining).
for (size_t i = frames.size(); i != 0 && !full(); i--) {
const auto& summ = frames[i - 1];
if (summ.IsJavaScript()) {
//====================================================================
// Handle a JavaScript frame.
//====================================================================
const auto& summary = summ.AsJavaScript();
// Filter out internal frames that we do not want to show.
if (!IsVisibleInStackTrace(summary.function())) continue;
Handle<AbstractCode> abstract_code = summary.abstract_code();
const int offset = summary.code_offset();
bool is_constructor = summary.is_constructor();
// Help CallSite::IsConstructor correctly detect hand-written
// construct stubs.
if (abstract_code->IsCode() &&
Code::cast(*abstract_code)->is_construct_stub()) {
is_constructor = true;
}
void AppendAsyncFrame(Handle<JSGeneratorObject> generator_object) {
if (full()) return;
Handle<JSFunction> function(generator_object->function(), isolate_);
if (!IsVisibleInStackTrace(function)) return;
int flags = FrameArray::kIsAsync;
if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict;
int flags = 0;
Handle<JSFunction> function = summary.function();
if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict;
if (is_constructor) flags |= FrameArray::kIsConstructor;
elements_ = FrameArray::AppendJSFrame(
elements_, TheHoleToUndefined(isolate_, summary.receiver()),
function, abstract_code, offset, flags);
} else if (summ.IsWasmCompiled()) {
//====================================================================
// Handle a WASM compiled frame.
//====================================================================
const auto& summary = summ.AsWasmCompiled();
if (summary.code()->kind() != wasm::WasmCode::kFunction) {
continue;
}
Handle<WasmInstanceObject> instance = summary.wasm_instance();
int flags = 0;
if (instance->module_object()->is_asm_js()) {
flags |= FrameArray::kIsAsmJsWasmFrame;
if (WasmCompiledFrame::cast(frame)->at_to_number_conversion()) {
flags |= FrameArray::kAsmJsAtNumberConversion;
}
} else {
flags |= FrameArray::kIsWasmFrame;
}
Handle<Object> receiver(generator_object->receiver(), isolate_);
Handle<AbstractCode> code(
AbstractCode::cast(function->shared()->GetBytecodeArray()), isolate_);
int offset = Smi::ToInt(generator_object->input_or_debug_pos());
// The stored bytecode offset is relative to a different base than what
// is used in the source position table, hence the subtraction.
offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
elements_ = FrameArray::AppendJSFrame(elements_, receiver, function, code,
offset, flags);
}
bool AppendJavaScriptFrame(
FrameSummary::JavaScriptFrameSummary const& summary) {
// Filter out internal frames that we do not want to show.
if (!IsVisibleInStackTrace(summary.function())) return false;
elements_ = FrameArray::AppendWasmFrame(
elements_, instance, summary.function_index(), summary.code(),
summary.code_offset(), flags);
} else if (summ.IsWasmInterpreted()) {
//====================================================================
// Handle a WASM interpreted frame.
//====================================================================
const auto& summary = summ.AsWasmInterpreted();
Handle<WasmInstanceObject> instance = summary.wasm_instance();
int flags = FrameArray::kIsWasmInterpretedFrame;
DCHECK(!instance->module_object()->is_asm_js());
elements_ = FrameArray::AppendWasmFrame(elements_, instance,
summary.function_index(), {},
summary.byte_offset(), flags);
Handle<AbstractCode> abstract_code = summary.abstract_code();
const int offset = summary.code_offset();
bool is_constructor = summary.is_constructor();
// Help CallSite::IsConstructor correctly detect hand-written
// construct stubs.
if (abstract_code->IsCode() &&
Code::cast(*abstract_code)->is_construct_stub()) {
is_constructor = true;
}
int flags = 0;
Handle<JSFunction> function = summary.function();
if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict;
if (is_constructor) flags |= FrameArray::kIsConstructor;
elements_ = FrameArray::AppendJSFrame(
elements_, TheHoleToUndefined(isolate_, summary.receiver()), function,
abstract_code, offset, flags);
return true;
}
bool AppendWasmCompiledFrame(
FrameSummary::WasmCompiledFrameSummary const& summary) {
if (summary.code()->kind() != wasm::WasmCode::kFunction) return false;
Handle<WasmInstanceObject> instance = summary.wasm_instance();
int flags = 0;
if (instance->module_object()->is_asm_js()) {
flags |= FrameArray::kIsAsmJsWasmFrame;
if (summary.at_to_number_conversion()) {
flags |= FrameArray::kAsmJsAtNumberConversion;
}
} else {
flags |= FrameArray::kIsWasmFrame;
}
elements_ = FrameArray::AppendWasmFrame(
elements_, instance, summary.function_index(), summary.code(),
summary.code_offset(), flags);
return true;
}
bool AppendWasmInterpretedFrame(
FrameSummary::WasmInterpretedFrameSummary const& summary) {
Handle<WasmInstanceObject> instance = summary.wasm_instance();
int flags = FrameArray::kIsWasmInterpretedFrame;
DCHECK(!instance->module_object()->is_asm_js());
elements_ = FrameArray::AppendWasmFrame(elements_, instance,
summary.function_index(), {},
summary.byte_offset(), flags);
return true;
}
void AppendBuiltinExitFrame(BuiltinExitFrame* exit_frame) {
bool AppendBuiltinExitFrame(BuiltinExitFrame* exit_frame) {
Handle<JSFunction> function = handle(exit_frame->function(), isolate_);
// Filter out internal frames that we do not want to show.
if (!IsVisibleInStackTrace(function)) return;
if (!IsVisibleInStackTrace(function)) return false;
Handle<Object> receiver(exit_frame->receiver(), isolate_);
Handle<Code> code(exit_frame->LookupCode(), isolate_);
......@@ -497,6 +505,8 @@ class FrameArrayBuilder {
elements_ = FrameArray::AppendJSFrame(elements_, receiver, function,
Handle<AbstractCode>::cast(code),
offset, flags);
return true;
}
bool full() { return elements_->FrameCount() >= limit_; }
......@@ -599,6 +609,70 @@ bool GetStackTraceLimit(Isolate* isolate, int* result) {
}
bool NoExtension(const v8::FunctionCallbackInfo<v8::Value>&) { return false; }
bool IsBuiltinFunction(Isolate* isolate, HeapObject* object,
Builtins::Name builtin_index) {
if (!object->IsJSFunction()) return false;
JSFunction* const function = JSFunction::cast(object);
return function->code() == isolate->builtins()->builtin(builtin_index);
}
void CaptureAsyncStackTrace(Isolate* isolate, Handle<JSPromise> promise,
FrameArrayBuilder* builder) {
CHECK_EQ(Promise::kPending, promise->status());
while (!builder->full()) {
// Check that we have exactly one PromiseReaction on the {promise}.
if (!promise->reactions()->IsPromiseReaction()) return;
Handle<PromiseReaction> reaction(
PromiseReaction::cast(promise->reactions()), isolate);
if (!reaction->next()->IsSmi()) return;
// Check if the {reaction} has the Await Fulfill and
// Await Rejected functions as its handlers.
if (IsBuiltinFunction(isolate, reaction->fulfill_handler(),
Builtins::kAsyncFunctionAwaitResolveClosure) &&
IsBuiltinFunction(isolate, reaction->reject_handler(),
Builtins::kAsyncFunctionAwaitRejectClosure)) {
// Now peak into the handlers' AwaitContext to get to
// the JSGeneratorObject for the async function.
Handle<Context> context(
JSFunction::cast(reaction->fulfill_handler())->context(), isolate);
Handle<JSGeneratorObject> generator_object(
JSGeneratorObject::cast(context->extension()), isolate);
CHECK(generator_object->is_suspended());
// Append async frame corresponding to the {generator_object}.
builder->AppendAsyncFrame(generator_object);
// Try to continue from here.
Handle<JSFunction> function(generator_object->function(), isolate);
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
Handle<Object> dot_promise(
generator_object->parameters_and_registers()->get(
DeclarationScope::kPromiseVarIndex +
shared->scope_info()->ParameterCount()),
isolate);
if (!dot_promise->IsJSPromise()) return;
promise = Handle<JSPromise>::cast(dot_promise);
} else {
// We have some generic promise chain here, so try to
// continue with the chained promise on the reaction
// (only works for native promise chains).
Handle<HeapObject> promise_or_capability(
reaction->promise_or_capability(), isolate);
if (promise_or_capability->IsJSPromise()) {
promise = Handle<JSPromise>::cast(promise_or_capability);
} else {
Handle<PromiseCapability> capability =
Handle<PromiseCapability>::cast(promise_or_capability);
if (!capability->promise()->IsJSPromise()) return;
promise = handle(JSPromise::cast(capability->promise()), isolate);
}
}
}
}
} // namespace
Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
......@@ -611,28 +685,65 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
FrameArrayBuilder builder(this, mode, limit, caller);
for (StackFrameIterator iter(this); !iter.done() && !builder.full();
iter.Advance()) {
StackFrame* frame = iter.frame();
// Build the regular stack trace, and remember the last relevant
// frame ID and inlined index (for the async stack trace handling
// below, which starts from this last frame).
int last_frame_index = 0;
StackFrame::Id last_frame_id = StackFrame::NO_ID;
for (StackFrameIterator it(this); !it.done() && !builder.full();
it.Advance()) {
StackFrame* const frame = it.frame();
switch (frame->type()) {
case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION:
case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
case StackFrame::OPTIMIZED:
case StackFrame::INTERPRETED:
case StackFrame::BUILTIN:
builder.AppendStandardFrame(JavaScriptFrame::cast(frame));
case StackFrame::WASM_COMPILED:
case StackFrame::WASM_INTERPRETER_ENTRY: {
// A standard frame may include many summarized frames (due to
// inlining).
std::vector<FrameSummary> frames;
StandardFrame::cast(frame)->Summarize(&frames);
for (size_t i = frames.size(); i-- != 0 && !builder.full();) {
const auto& summary = frames[i];
if (summary.IsJavaScript()) {
//====================================================================
// Handle a JavaScript frame.
//====================================================================
if (builder.AppendJavaScriptFrame(summary.AsJavaScript())) {
last_frame_id = frame->id();
last_frame_index = static_cast<int>(i);
}
} else if (summary.IsWasmCompiled()) {
//====================================================================
// Handle a WASM compiled frame.
//====================================================================
if (builder.AppendWasmCompiledFrame(summary.AsWasmCompiled())) {
last_frame_id = StackFrame::NO_ID;
last_frame_index = 0;
}
} else if (summary.IsWasmInterpreted()) {
//====================================================================
// Handle a WASM interpreted frame.
//====================================================================
if (builder.AppendWasmInterpretedFrame(
summary.AsWasmInterpreted())) {
last_frame_id = StackFrame::NO_ID;
last_frame_index = 0;
}
}
}
break;
}
case StackFrame::BUILTIN_EXIT:
// BuiltinExitFrames are not standard frames, so they do not have
// Summarize(). However, they may have one JS frame worth showing.
builder.AppendBuiltinExitFrame(BuiltinExitFrame::cast(frame));
break;
case StackFrame::WASM_COMPILED:
builder.AppendStandardFrame(WasmCompiledFrame::cast(frame));
break;
case StackFrame::WASM_INTERPRETER_ENTRY:
builder.AppendStandardFrame(WasmInterpreterEntryFrame::cast(frame));
if (builder.AppendBuiltinExitFrame(BuiltinExitFrame::cast(frame))) {
last_frame_id = StackFrame::NO_ID;
last_frame_index = 0;
}
break;
default:
......@@ -640,6 +751,34 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
}
}
// If --async-stack-traces is enabled, and we ended on a regular JavaScript
// frame above, we can enrich the stack trace with async frames (if this
// last frame corresponds to an async function).
if (FLAG_async_stack_traces && last_frame_id != StackFrame::NO_ID) {
StackFrameIterator it(this);
while (it.frame()->id() != last_frame_id) it.Advance();
FrameInspector inspector(StandardFrame::cast(it.frame()), last_frame_index,
this);
FunctionKind const kind = inspector.GetFunction()->shared()->kind();
if (IsAsyncGeneratorFunction(kind)) {
// TODO(bmeurer): Handle async generators here.
} else if (IsAsyncFunction(kind)) {
Handle<Object> const dot_promise =
inspector.GetExpression(DeclarationScope::kPromiseVarIndex);
if (dot_promise->IsJSPromise()) {
// We can start collecting an async stack trace from .promise here.
CaptureAsyncStackTrace(this, Handle<JSPromise>::cast(dot_promise),
&builder);
} else {
// If .promise was not yet initialized (i.e. we see a really
// early exception in the setup of the function), it holds
// the value undefined. Sanity check here to make sure that
// we're not peaking into the completely wrong stack slot.
CHECK(dot_promise->IsUndefined(this));
}
}
}
// TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
return factory()->NewJSArrayWithElements(builder.GetElements());
}
......
......@@ -305,6 +305,7 @@ void JSStackFrame::FromFrameArray(Isolate* isolate, Handle<FrameArray> array,
const int flags = array->Flags(frame_ix)->value();
is_constructor_ = (flags & FrameArray::kIsConstructor) != 0;
is_strict_ = (flags & FrameArray::kIsStrict) != 0;
is_async_ = (flags & FrameArray::kIsAsync) != 0;
}
JSStackFrame::JSStackFrame(Isolate* isolate, Handle<Object> receiver,
......@@ -315,6 +316,7 @@ JSStackFrame::JSStackFrame(Isolate* isolate, Handle<Object> receiver,
function_(function),
code_(code),
offset_(offset),
is_async_(false),
is_constructor_(false),
is_strict_(false) {}
......@@ -604,9 +606,13 @@ MaybeHandle<String> JSStackFrame::ToString() {
Handle<Object> function_name = GetFunctionName();
const bool is_toplevel = IsToplevel();
const bool is_async = IsAsync();
const bool is_constructor = IsConstructor();
const bool is_method_call = !(is_toplevel || is_constructor);
if (is_async) {
builder.AppendCString("async ");
}
if (is_method_call) {
AppendMethodCall(isolate_, this, &builder);
} else if (is_constructor) {
......
......@@ -71,6 +71,7 @@ class StackFrameBase {
virtual bool IsNative() = 0;
virtual bool IsToplevel() = 0;
virtual bool IsEval();
virtual bool IsAsync() const = 0;
virtual bool IsConstructor() = 0;
virtual bool IsStrict() const = 0;
......@@ -108,6 +109,7 @@ class JSStackFrame : public StackFrameBase {
bool IsNative() override;
bool IsToplevel() override;
bool IsAsync() const override { return is_async_; }
bool IsConstructor() override { return is_constructor_; }
bool IsStrict() const override { return is_strict_; }
......@@ -125,8 +127,9 @@ class JSStackFrame : public StackFrameBase {
Handle<AbstractCode> code_;
int offset_;
bool is_constructor_;
bool is_strict_;
bool is_async_ : 1;
bool is_constructor_ : 1;
bool is_strict_ : 1;
friend class FrameArrayIterator;
};
......@@ -150,6 +153,7 @@ class WasmStackFrame : public StackFrameBase {
bool IsNative() override { return false; }
bool IsToplevel() override { return false; }
bool IsAsync() const override { return false; }
bool IsConstructor() override { return false; }
bool IsStrict() const override { return false; }
bool IsInterpreted() const { return code_ == nullptr; }
......
......@@ -50,7 +50,8 @@ class FrameArray : public FixedArray {
kIsAsmJsWasmFrame = 1 << 2,
kIsStrict = 1 << 3,
kIsConstructor = 1 << 4,
kAsmJsAtNumberConversion = 1 << 5
kAsmJsAtNumberConversion = 1 << 5,
kIsAsync = 1 << 6
};
static Handle<FrameArray> AppendJSFrame(Handle<FrameArray> in,
......
......@@ -18,18 +18,18 @@ frame size: 23
parameter count: 1
bytecode array length: 514
bytecodes: [
B(SwitchOnGeneratorState), R(2), U8(0), U8(3),
B(SwitchOnGeneratorState), R(3), U8(0), U8(3),
B(Mov), R(closure), R(12),
B(Mov), R(this), R(13),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(12), U8(2),
B(Star), R(2),
B(Star), R(3),
/* 16 E> */ B(StackCheck),
B(CallJSRuntime), U8(%async_function_promise_create), R(0), U8(0),
B(Star), R(11),
B(Star), R(0),
B(Mov), R(context), R(14),
B(Mov), R(context), R(15),
B(LdaZero),
B(Star), R(7),
B(Star), R(8),
B(Mov), R(context), R(18),
B(Mov), R(context), R(19),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
......@@ -46,40 +46,40 @@ bytecodes: [
B(CallProperty0), R(21), R(20), U8(7),
B(Star), R(21),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(21), U8(1),
B(Star), R(4),
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(9),
B(Star), R(5),
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(11),
/* 43 E> */ B(LdaNamedProperty), R(5), U8(6), U8(9),
B(Star), R(6),
/* 40 S> */ B(CallProperty0), R(6), R(5), U8(11),
B(Star), R(21),
B(Mov), R(2), R(20),
B(Mov), R(11), R(22),
B(Mov), R(3), R(20),
B(Mov), R(0), R(22),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(20), U8(3),
/* 40 E> */ B(SuspendGenerator), R(2), R(0), U8(20), U8(0),
B(ResumeGenerator), R(2), R(0), U8(20),
/* 40 E> */ B(SuspendGenerator), R(3), R(0), U8(20), U8(0),
B(ResumeGenerator), R(3), R(0), U8(20),
B(Star), R(20),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(21),
B(LdaZero),
B(TestReferenceEqual), R(21),
B(JumpIfTrue), U8(5),
B(Ldar), R(20),
B(ReThrow),
B(Mov), R(20), R(6),
B(Mov), R(20), R(7),
/* 40 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(20), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(7), U8(13),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(7), U8(13),
B(JumpIfToBooleanTrue), U8(25),
B(LdaNamedProperty), R(6), U8(8), U8(15),
B(Star), R(8),
B(LdaNamedProperty), R(7), U8(8), U8(15),
B(Star), R(9),
B(LdaSmi), I8(2),
B(Star), R(7),
B(Mov), R(8), R(3),
B(Star), R(8),
B(Mov), R(9), R(4),
/* 23 E> */ B(StackCheck),
B(Mov), R(3), R(0),
B(Mov), R(4), R(1),
B(LdaZero),
B(Star), R(7),
B(Star), R(8),
B(JumpLoop), U8(82), I8(0),
B(Jump), U8(37),
B(Star), R(20),
......@@ -90,10 +90,10 @@ bytecodes: [
B(Ldar), R(19),
B(PushContext), R(20),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(7), U8(17),
B(TestEqualStrict), R(8), U8(17),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(7),
B(Star), R(8),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(21),
B(CallRuntime), U16(Runtime::kReThrow), R(21), U8(1),
......@@ -109,17 +109,17 @@ bytecodes: [
B(SetPendingMessage),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrict), R(7), U8(18),
B(TestEqualStrict), R(8), U8(18),
B(JumpIfTrue), U8(167),
B(LdaNamedProperty), R(4), U8(10), U8(19),
B(Star), R(9),
B(LdaNamedProperty), R(5), U8(10), U8(19),
B(Star), R(10),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(156),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(7), U8(21),
B(TestEqualStrict), R(8), U8(21),
B(JumpIfFalse), U8(86),
B(Ldar), R(9),
B(Ldar), R(10),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
......@@ -130,17 +130,17 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kNewTypeError), R(19), U8(2),
B(Throw),
B(Mov), R(context), R(19),
B(Mov), R(9), R(20),
B(Mov), R(4), R(21),
B(Mov), R(10), R(20),
B(Mov), R(5), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(20), U8(2),
B(Star), R(21),
B(Mov), R(2), R(20),
B(Mov), R(11), R(22),
B(Mov), R(3), R(20),
B(Mov), R(0), R(22),
B(CallJSRuntime), U8(%async_function_await_caught), R(20), U8(3),
B(SuspendGenerator), R(2), R(0), U8(20), U8(1),
B(ResumeGenerator), R(2), R(0), U8(20),
B(SuspendGenerator), R(3), R(0), U8(20), U8(1),
B(ResumeGenerator), R(3), R(0), U8(20),
B(Star), R(20),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(21),
B(LdaZero),
B(TestReferenceEqual), R(21),
......@@ -153,28 +153,28 @@ bytecodes: [
B(SetPendingMessage),
B(Ldar), R(19),
B(Jump), U8(65),
B(Mov), R(9), R(19),
B(Mov), R(4), R(20),
B(Mov), R(10), R(19),
B(Mov), R(5), R(20),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(2),
B(Star), R(20),
B(Mov), R(2), R(19),
B(Mov), R(11), R(21),
B(Mov), R(3), R(19),
B(Mov), R(0), R(21),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(19), U8(3),
B(SuspendGenerator), R(2), R(0), U8(19), U8(2),
B(ResumeGenerator), R(2), R(0), U8(19),
B(SuspendGenerator), R(3), R(0), U8(19), U8(2),
B(ResumeGenerator), R(3), R(0), U8(19),
B(Star), R(19),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(20),
B(LdaZero),
B(TestReferenceEqual), R(20),
B(JumpIfTrue), U8(5),
B(Ldar), R(19),
B(ReThrow),
B(Mov), R(19), R(10),
B(Mov), R(19), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(19), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(Ldar), R(18),
B(SetPendingMessage),
B(LdaZero),
......@@ -184,11 +184,11 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star), R(17),
B(Mov), R(11), R(16),
B(Mov), R(0), R(16),
B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(16), U8(2),
B(LdaZero),
B(Star), R(12),
B(Mov), R(11), R(13),
B(Mov), R(0), R(13),
B(Jump), U8(55),
B(Jump), U8(39),
B(Star), R(16),
......@@ -202,12 +202,12 @@ bytecodes: [
B(Star), R(18),
B(LdaFalse),
B(Star), R(19),
B(Mov), R(11), R(17),
B(Mov), R(0), R(17),
B(InvokeIntrinsic), U8(Runtime::k_RejectPromise), R(17), U8(3),
B(PopContext), R(16),
B(LdaZero),
B(Star), R(12),
B(Mov), R(11), R(13),
B(Mov), R(0), R(13),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(13),
......@@ -221,7 +221,7 @@ bytecodes: [
B(Star), R(14),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(11), R(15),
B(Mov), R(0), R(15),
B(CallJSRuntime), U8(%async_function_promise_release), R(15), U8(2),
B(Ldar), R(14),
B(SetPendingMessage),
......@@ -271,18 +271,18 @@ frame size: 23
parameter count: 1
bytecode array length: 543
bytecodes: [
B(SwitchOnGeneratorState), R(2), U8(0), U8(3),
B(SwitchOnGeneratorState), R(3), U8(0), U8(3),
B(Mov), R(closure), R(12),
B(Mov), R(this), R(13),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(12), U8(2),
B(Star), R(2),
B(Star), R(3),
/* 16 E> */ B(StackCheck),
B(CallJSRuntime), U8(%async_function_promise_create), R(0), U8(0),
B(Star), R(11),
B(Star), R(0),
B(Mov), R(context), R(14),
B(Mov), R(context), R(15),
B(LdaZero),
B(Star), R(7),
B(Star), R(8),
B(Mov), R(context), R(18),
B(Mov), R(context), R(19),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
......@@ -299,41 +299,41 @@ bytecodes: [
B(CallProperty0), R(21), R(20), U8(7),
B(Star), R(21),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(21), U8(1),
B(Star), R(4),
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(9),
B(Star), R(5),
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(11),
/* 43 E> */ B(LdaNamedProperty), R(5), U8(6), U8(9),
B(Star), R(6),
/* 40 S> */ B(CallProperty0), R(6), R(5), U8(11),
B(Star), R(21),
B(Mov), R(2), R(20),
B(Mov), R(11), R(22),
B(Mov), R(3), R(20),
B(Mov), R(0), R(22),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(20), U8(3),
/* 40 E> */ B(SuspendGenerator), R(2), R(0), U8(20), U8(0),
B(ResumeGenerator), R(2), R(0), U8(20),
/* 40 E> */ B(SuspendGenerator), R(3), R(0), U8(20), U8(0),
B(ResumeGenerator), R(3), R(0), U8(20),
B(Star), R(20),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(21),
B(LdaZero),
B(TestReferenceEqual), R(21),
B(JumpIfTrue), U8(5),
B(Ldar), R(20),
B(ReThrow),
B(Mov), R(20), R(6),
B(Mov), R(20), R(7),
/* 40 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(20), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(7), U8(13),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(7), U8(13),
B(JumpIfToBooleanTrue), U8(27),
B(LdaNamedProperty), R(6), U8(8), U8(15),
B(Star), R(8),
B(LdaNamedProperty), R(7), U8(8), U8(15),
B(Star), R(9),
B(LdaSmi), I8(2),
B(Star), R(7),
B(Mov), R(8), R(3),
B(Star), R(8),
B(Mov), R(9), R(4),
/* 23 E> */ B(StackCheck),
B(Mov), R(3), R(0),
B(Mov), R(4), R(1),
/* 56 S> */ B(LdaZero),
B(Star), R(16),
B(Mov), R(8), R(17),
B(Mov), R(9), R(17),
B(Jump), U8(53),
B(Jump), U8(37),
B(Star), R(20),
......@@ -344,10 +344,10 @@ bytecodes: [
B(Ldar), R(19),
B(PushContext), R(20),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(7), U8(17),
B(TestEqualStrict), R(8), U8(17),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(7),
B(Star), R(8),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(21),
B(CallRuntime), U16(Runtime::kReThrow), R(21), U8(1),
......@@ -363,17 +363,17 @@ bytecodes: [
B(SetPendingMessage),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrict), R(7), U8(18),
B(TestEqualStrict), R(8), U8(18),
B(JumpIfTrue), U8(167),
B(LdaNamedProperty), R(4), U8(10), U8(19),
B(Star), R(9),
B(LdaNamedProperty), R(5), U8(10), U8(19),
B(Star), R(10),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(156),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(7), U8(21),
B(TestEqualStrict), R(8), U8(21),
B(JumpIfFalse), U8(86),
B(Ldar), R(9),
B(Ldar), R(10),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
......@@ -384,17 +384,17 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kNewTypeError), R(19), U8(2),
B(Throw),
B(Mov), R(context), R(19),
B(Mov), R(9), R(20),
B(Mov), R(4), R(21),
B(Mov), R(10), R(20),
B(Mov), R(5), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(20), U8(2),
B(Star), R(21),
B(Mov), R(2), R(20),
B(Mov), R(11), R(22),
B(Mov), R(3), R(20),
B(Mov), R(0), R(22),
B(CallJSRuntime), U8(%async_function_await_caught), R(20), U8(3),
B(SuspendGenerator), R(2), R(0), U8(20), U8(1),
B(ResumeGenerator), R(2), R(0), U8(20),
B(SuspendGenerator), R(3), R(0), U8(20), U8(1),
B(ResumeGenerator), R(3), R(0), U8(20),
B(Star), R(20),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(21),
B(LdaZero),
B(TestReferenceEqual), R(21),
......@@ -407,28 +407,28 @@ bytecodes: [
B(SetPendingMessage),
B(Ldar), R(19),
B(Jump), U8(65),
B(Mov), R(9), R(19),
B(Mov), R(4), R(20),
B(Mov), R(10), R(19),
B(Mov), R(5), R(20),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(2),
B(Star), R(20),
B(Mov), R(2), R(19),
B(Mov), R(11), R(21),
B(Mov), R(3), R(19),
B(Mov), R(0), R(21),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(19), U8(3),
B(SuspendGenerator), R(2), R(0), U8(19), U8(2),
B(ResumeGenerator), R(2), R(0), U8(19),
B(SuspendGenerator), R(3), R(0), U8(19), U8(2),
B(ResumeGenerator), R(3), R(0), U8(19),
B(Star), R(19),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(20),
B(LdaZero),
B(TestReferenceEqual), R(20),
B(JumpIfTrue), U8(5),
B(Ldar), R(19),
B(ReThrow),
B(Mov), R(19), R(10),
B(Mov), R(19), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(19), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(Ldar), R(18),
B(SetPendingMessage),
B(Ldar), R(16),
......@@ -442,11 +442,11 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star), R(17),
B(Mov), R(11), R(16),
B(Mov), R(0), R(16),
B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(16), U8(2),
B(LdaSmi), I8(1),
B(Star), R(12),
B(Mov), R(11), R(13),
B(Mov), R(0), R(13),
B(Jump), U8(56),
B(Jump), U8(40),
B(Star), R(16),
......@@ -460,12 +460,12 @@ bytecodes: [
B(Star), R(18),
B(LdaFalse),
B(Star), R(19),
B(Mov), R(11), R(17),
B(Mov), R(0), R(17),
B(InvokeIntrinsic), U8(Runtime::k_RejectPromise), R(17), U8(3),
B(PopContext), R(16),
B(LdaSmi), I8(1),
B(Star), R(12),
B(Mov), R(11), R(13),
B(Mov), R(0), R(13),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(13),
......@@ -479,17 +479,17 @@ bytecodes: [
B(Star), R(14),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(11), R(15),
B(Mov), R(0), R(15),
B(CallJSRuntime), U8(%async_function_promise_release), R(15), U8(2),
B(Ldar), R(14),
B(SetPendingMessage),
B(Ldar), R(12),
B(SwitchOnSmiNoFeedback), U8(15), U8(3), I8(0),
B(Jump), U8(21),
B(Mov), R(11), R(15),
B(Mov), R(0), R(15),
B(Mov), R(13), R(16),
B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(15), U8(2),
B(Ldar), R(11),
B(Ldar), R(0),
/* 68 S> */ B(Return),
B(Ldar), R(13),
/* 68 S> */ B(Return),
......@@ -540,18 +540,18 @@ frame size: 23
parameter count: 1
bytecode array length: 532
bytecodes: [
B(SwitchOnGeneratorState), R(2), U8(0), U8(3),
B(SwitchOnGeneratorState), R(3), U8(0), U8(3),
B(Mov), R(closure), R(12),
B(Mov), R(this), R(13),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(12), U8(2),
B(Star), R(2),
B(Star), R(3),
/* 16 E> */ B(StackCheck),
B(CallJSRuntime), U8(%async_function_promise_create), R(0), U8(0),
B(Star), R(11),
B(Star), R(0),
B(Mov), R(context), R(14),
B(Mov), R(context), R(15),
B(LdaZero),
B(Star), R(7),
B(Star), R(8),
B(Mov), R(context), R(18),
B(Mov), R(context), R(19),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
......@@ -568,48 +568,48 @@ bytecodes: [
B(CallProperty0), R(21), R(20), U8(7),
B(Star), R(21),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(21), U8(1),
B(Star), R(4),
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(9),
B(Star), R(5),
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(11),
/* 43 E> */ B(LdaNamedProperty), R(5), U8(6), U8(9),
B(Star), R(6),
/* 40 S> */ B(CallProperty0), R(6), R(5), U8(11),
B(Star), R(21),
B(Mov), R(2), R(20),
B(Mov), R(11), R(22),
B(Mov), R(3), R(20),
B(Mov), R(0), R(22),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(20), U8(3),
/* 40 E> */ B(SuspendGenerator), R(2), R(0), U8(20), U8(0),
B(ResumeGenerator), R(2), R(0), U8(20),
/* 40 E> */ B(SuspendGenerator), R(3), R(0), U8(20), U8(0),
B(ResumeGenerator), R(3), R(0), U8(20),
B(Star), R(20),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(21),
B(LdaZero),
B(TestReferenceEqual), R(21),
B(JumpIfTrue), U8(5),
B(Ldar), R(20),
B(ReThrow),
B(Mov), R(20), R(6),
B(Mov), R(20), R(7),
/* 40 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(20), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(7), U8(13),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(7), U8(13),
B(JumpIfToBooleanTrue), U8(43),
B(LdaNamedProperty), R(6), U8(8), U8(15),
B(Star), R(8),
B(LdaNamedProperty), R(7), U8(8), U8(15),
B(Star), R(9),
B(LdaSmi), I8(2),
B(Star), R(7),
B(Mov), R(8), R(3),
B(Star), R(8),
B(Mov), R(9), R(4),
/* 23 E> */ B(StackCheck),
B(Mov), R(3), R(0),
B(Mov), R(4), R(1),
/* 63 S> */ B(LdaSmi), I8(10),
/* 69 E> */ B(TestEqual), R(0), U8(17),
/* 69 E> */ B(TestEqual), R(1), U8(17),
B(JumpIfFalse), U8(4),
/* 76 S> */ B(Jump), U8(14),
/* 90 S> */ B(LdaSmi), I8(20),
/* 96 E> */ B(TestEqual), R(0), U8(18),
/* 96 E> */ B(TestEqual), R(1), U8(18),
B(JumpIfFalse), U8(4),
/* 103 S> */ B(Jump), U8(8),
B(LdaZero),
B(Star), R(7),
B(Star), R(8),
B(JumpLoop), U8(100), I8(0),
B(Jump), U8(37),
B(Star), R(20),
......@@ -620,10 +620,10 @@ bytecodes: [
B(Ldar), R(19),
B(PushContext), R(20),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(7), U8(19),
B(TestEqualStrict), R(8), U8(19),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(7),
B(Star), R(8),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(21),
B(CallRuntime), U16(Runtime::kReThrow), R(21), U8(1),
......@@ -639,17 +639,17 @@ bytecodes: [
B(SetPendingMessage),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrict), R(7), U8(20),
B(TestEqualStrict), R(8), U8(20),
B(JumpIfTrue), U8(167),
B(LdaNamedProperty), R(4), U8(10), U8(21),
B(Star), R(9),
B(LdaNamedProperty), R(5), U8(10), U8(21),
B(Star), R(10),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(156),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(7), U8(23),
B(TestEqualStrict), R(8), U8(23),
B(JumpIfFalse), U8(86),
B(Ldar), R(9),
B(Ldar), R(10),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
......@@ -660,17 +660,17 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kNewTypeError), R(19), U8(2),
B(Throw),
B(Mov), R(context), R(19),
B(Mov), R(9), R(20),
B(Mov), R(4), R(21),
B(Mov), R(10), R(20),
B(Mov), R(5), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(20), U8(2),
B(Star), R(21),
B(Mov), R(2), R(20),
B(Mov), R(11), R(22),
B(Mov), R(3), R(20),
B(Mov), R(0), R(22),
B(CallJSRuntime), U8(%async_function_await_caught), R(20), U8(3),
B(SuspendGenerator), R(2), R(0), U8(20), U8(1),
B(ResumeGenerator), R(2), R(0), U8(20),
B(SuspendGenerator), R(3), R(0), U8(20), U8(1),
B(ResumeGenerator), R(3), R(0), U8(20),
B(Star), R(20),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(21),
B(LdaZero),
B(TestReferenceEqual), R(21),
......@@ -683,28 +683,28 @@ bytecodes: [
B(SetPendingMessage),
B(Ldar), R(19),
B(Jump), U8(65),
B(Mov), R(9), R(19),
B(Mov), R(4), R(20),
B(Mov), R(10), R(19),
B(Mov), R(5), R(20),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(2),
B(Star), R(20),
B(Mov), R(2), R(19),
B(Mov), R(11), R(21),
B(Mov), R(3), R(19),
B(Mov), R(0), R(21),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(19), U8(3),
B(SuspendGenerator), R(2), R(0), U8(19), U8(2),
B(ResumeGenerator), R(2), R(0), U8(19),
B(SuspendGenerator), R(3), R(0), U8(19), U8(2),
B(ResumeGenerator), R(3), R(0), U8(19),
B(Star), R(19),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(20),
B(LdaZero),
B(TestReferenceEqual), R(20),
B(JumpIfTrue), U8(5),
B(Ldar), R(19),
B(ReThrow),
B(Mov), R(19), R(10),
B(Mov), R(19), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(19), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(Ldar), R(18),
B(SetPendingMessage),
B(LdaZero),
......@@ -714,11 +714,11 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star), R(17),
B(Mov), R(11), R(16),
B(Mov), R(0), R(16),
B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(16), U8(2),
B(LdaZero),
B(Star), R(12),
B(Mov), R(11), R(13),
B(Mov), R(0), R(13),
B(Jump), U8(55),
B(Jump), U8(39),
B(Star), R(16),
......@@ -732,12 +732,12 @@ bytecodes: [
B(Star), R(18),
B(LdaFalse),
B(Star), R(19),
B(Mov), R(11), R(17),
B(Mov), R(0), R(17),
B(InvokeIntrinsic), U8(Runtime::k_RejectPromise), R(17), U8(3),
B(PopContext), R(16),
B(LdaZero),
B(Star), R(12),
B(Mov), R(11), R(13),
B(Mov), R(0), R(13),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(13),
......@@ -751,7 +751,7 @@ bytecodes: [
B(Star), R(14),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(11), R(15),
B(Mov), R(0), R(15),
B(CallJSRuntime), U8(%async_function_promise_release), R(15), U8(2),
B(Ldar), R(14),
B(SetPendingMessage),
......@@ -804,13 +804,13 @@ bytecode array length: 403
bytecodes: [
/* 16 E> */ B(StackCheck),
B(CallJSRuntime), U8(%async_function_promise_create), R(0), U8(0),
B(Star), R(9),
B(Star), R(0),
B(Mov), R(context), R(12),
B(Mov), R(context), R(13),
/* 31 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), R(14),
B(Mov), R(14), R(1),
B(Mov), R(14), R(2),
B(LdaZero),
B(Star), R(5),
B(Star), R(6),
B(Mov), R(context), R(16),
B(Mov), R(context), R(17),
/* 68 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
......@@ -820,25 +820,25 @@ bytecodes: [
B(CallProperty0), R(19), R(18), U8(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(2),
/* 68 E> */ B(LdaNamedProperty), R(2), U8(3), U8(6),
B(Star), R(3),
/* 59 S> */ B(CallProperty0), R(3), R(2), U8(8),
/* 68 E> */ B(LdaNamedProperty), R(3), U8(3), U8(6),
B(Star), R(4),
/* 59 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(4), U8(1),
/* 59 S> */ B(CallProperty0), R(4), R(3), U8(8),
B(Star), R(5),
/* 59 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(5), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
B(LdaNamedProperty), R(4), U8(4), U8(10),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(4), U8(10),
B(JumpIfToBooleanTrue), U8(30),
/* 58 E> */ B(LdaNamedProperty), R(4), U8(5), U8(12),
B(Star), R(6),
/* 58 E> */ B(LdaNamedProperty), R(5), U8(5), U8(12),
B(Star), R(7),
B(LdaSmi), I8(2),
B(Star), R(5),
B(Ldar), R(6),
B(StaNamedProperty), R(1), U8(6), U8(14),
B(Star), R(6),
B(Ldar), R(7),
B(StaNamedProperty), R(2), U8(6), U8(14),
/* 53 E> */ B(StackCheck),
/* 87 S> */ B(LdaNamedProperty), R(1), U8(6), U8(16),
/* 87 S> */ B(LdaNamedProperty), R(2), U8(6), U8(16),
B(Star), R(15),
B(LdaZero),
B(Star), R(14),
......@@ -852,10 +852,10 @@ bytecodes: [
B(Ldar), R(17),
B(PushContext), R(18),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(5), U8(18),
B(TestEqualStrict), R(6), U8(18),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(5),
B(Star), R(6),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(19),
B(CallRuntime), U16(Runtime::kReThrow), R(19), U8(1),
......@@ -871,17 +871,17 @@ bytecodes: [
B(SetPendingMessage),
B(Star), R(16),
B(LdaZero),
B(TestEqualStrict), R(5), U8(19),
B(TestEqualStrict), R(6), U8(19),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(2), U8(8), U8(20),
B(Star), R(7),
B(LdaNamedProperty), R(3), U8(8), U8(20),
B(Star), R(8),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(5), U8(22),
B(TestEqualStrict), R(6), U8(22),
B(JumpIfFalse), U8(47),
B(Ldar), R(7),
B(Ldar), R(8),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
......@@ -892,22 +892,22 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kNewTypeError), R(17), U8(2),
B(Throw),
B(Mov), R(context), R(17),
B(Mov), R(7), R(18),
B(Mov), R(2), R(19),
B(Mov), R(8), R(18),
B(Mov), R(3), R(19),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(18), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(17),
B(Jump), U8(27),
B(Mov), R(7), R(17),
B(Mov), R(2), R(18),
B(Mov), R(8), R(17),
B(Mov), R(3), R(18),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(17), U8(2),
B(Star), R(8),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(8), U8(1),
B(Star), R(9),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(9), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(Ldar), R(16),
B(SetPendingMessage),
B(Ldar), R(14),
......@@ -921,11 +921,11 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star), R(15),
B(Mov), R(9), R(14),
B(Mov), R(0), R(14),
B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(14), U8(2),
B(LdaSmi), I8(1),
B(Star), R(10),
B(Mov), R(9), R(11),
B(Mov), R(0), R(11),
B(Jump), U8(56),
B(Jump), U8(40),
B(Star), R(14),
......@@ -939,12 +939,12 @@ bytecodes: [
B(Star), R(16),
B(LdaFalse),
B(Star), R(17),
B(Mov), R(9), R(15),
B(Mov), R(0), R(15),
B(InvokeIntrinsic), U8(Runtime::k_RejectPromise), R(15), U8(3),
B(PopContext), R(14),
B(LdaSmi), I8(1),
B(Star), R(10),
B(Mov), R(9), R(11),
B(Mov), R(0), R(11),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(11),
......@@ -958,17 +958,17 @@ bytecodes: [
B(Star), R(12),
B(LdaFalse),
B(Star), R(14),
B(Mov), R(9), R(13),
B(Mov), R(0), R(13),
B(CallJSRuntime), U8(%async_function_promise_release), R(13), U8(2),
B(Ldar), R(12),
B(SetPendingMessage),
B(Ldar), R(10),
B(SwitchOnSmiNoFeedback), U8(13), U8(3), I8(0),
B(Jump), U8(21),
B(Mov), R(9), R(13),
B(Mov), R(0), R(13),
B(Mov), R(11), R(14),
B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(13), U8(2),
B(Ldar), R(9),
B(Ldar), R(0),
/* 96 S> */ B(Return),
B(Ldar), R(11),
/* 96 S> */ B(Return),
......
......@@ -930,11 +930,11 @@ bytecode array length: 363
bytecodes: [
/* 16 E> */ B(StackCheck),
B(CallJSRuntime), U8(%async_function_promise_create), R(0), U8(0),
B(Star), R(12),
B(Star), R(0),
B(Mov), R(context), R(15),
B(Mov), R(context), R(16),
B(LdaZero),
B(Star), R(8),
B(Star), R(9),
B(Mov), R(context), R(19),
B(Mov), R(context), R(20),
/* 40 S> */ B(LdaNamedProperty), R(arg0), U8(0), U8(0),
......@@ -943,27 +943,27 @@ bytecodes: [
B(Mov), R(arg0), R(21),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
/* 40 E> */ B(LdaNamedProperty), R(5), U8(1), U8(4),
B(Star), R(6),
/* 35 S> */ B(CallProperty0), R(6), R(5), U8(6),
/* 40 E> */ B(LdaNamedProperty), R(6), U8(1), U8(4),
B(Star), R(7),
/* 35 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
/* 35 S> */ B(CallProperty0), R(7), R(6), U8(6),
B(Star), R(8),
/* 35 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(8), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(2), U8(8),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(LdaNamedProperty), R(8), U8(2), U8(8),
B(JumpIfToBooleanTrue), U8(28),
B(LdaNamedProperty), R(7), U8(3), U8(10),
B(Star), R(9),
B(LdaNamedProperty), R(8), U8(3), U8(10),
B(Star), R(10),
B(LdaSmi), I8(2),
B(Star), R(8),
B(Mov), R(9), R(4),
B(Star), R(9),
B(Mov), R(10), R(5),
/* 26 E> */ B(StackCheck),
B(Mov), R(4), R(1),
/* 55 S> */ B(Mov), R(1), R(0),
B(Mov), R(5), R(2),
/* 55 S> */ B(Mov), R(2), R(1),
B(LdaZero),
B(Star), R(8),
B(Star), R(9),
B(JumpLoop), U8(47), I8(0),
B(Jump), U8(37),
B(Star), R(21),
......@@ -974,10 +974,10 @@ bytecodes: [
B(Ldar), R(20),
B(PushContext), R(21),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(8), U8(12),
B(TestEqualStrict), R(9), U8(12),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(8),
B(Star), R(9),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(22),
B(CallRuntime), U16(Runtime::kReThrow), R(22), U8(1),
......@@ -993,17 +993,17 @@ bytecodes: [
B(SetPendingMessage),
B(Star), R(19),
B(LdaZero),
B(TestEqualStrict), R(8), U8(13),
B(TestEqualStrict), R(9), U8(13),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(5), U8(5), U8(14),
B(Star), R(10),
B(LdaNamedProperty), R(6), U8(5), U8(14),
B(Star), R(11),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(8), U8(16),
B(TestEqualStrict), R(9), U8(16),
B(JumpIfFalse), U8(47),
B(Ldar), R(10),
B(Ldar), R(11),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
......@@ -1014,22 +1014,22 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kNewTypeError), R(20), U8(2),
B(Throw),
B(Mov), R(context), R(20),
B(Mov), R(10), R(21),
B(Mov), R(5), R(22),
B(Mov), R(11), R(21),
B(Mov), R(6), R(22),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(21), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(20),
B(Jump), U8(27),
B(Mov), R(10), R(20),
B(Mov), R(5), R(21),
B(Mov), R(11), R(20),
B(Mov), R(6), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(20), U8(2),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(12), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(Ldar), R(19),
B(SetPendingMessage),
B(LdaZero),
......@@ -1039,11 +1039,11 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star), R(18),
B(Mov), R(12), R(17),
B(Mov), R(0), R(17),
B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(17), U8(2),
B(LdaZero),
B(Star), R(13),
B(Mov), R(12), R(14),
B(Mov), R(0), R(14),
B(Jump), U8(55),
B(Jump), U8(39),
B(Star), R(17),
......@@ -1057,12 +1057,12 @@ bytecodes: [
B(Star), R(19),
B(LdaFalse),
B(Star), R(20),
B(Mov), R(12), R(18),
B(Mov), R(0), R(18),
B(InvokeIntrinsic), U8(Runtime::k_RejectPromise), R(18), U8(3),
B(PopContext), R(17),
B(LdaZero),
B(Star), R(13),
B(Mov), R(12), R(14),
B(Mov), R(0), R(14),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(14),
......@@ -1076,7 +1076,7 @@ bytecodes: [
B(Star), R(15),
B(LdaFalse),
B(Star), R(17),
B(Mov), R(12), R(16),
B(Mov), R(0), R(16),
B(CallJSRuntime), U8(%async_function_promise_release), R(16), U8(2),
B(Ldar), R(15),
B(SetPendingMessage),
......@@ -1121,18 +1121,18 @@ frame size: 23
parameter count: 2
bytecode array length: 414
bytecodes: [
B(SwitchOnGeneratorState), R(2), U8(0), U8(1),
B(SwitchOnGeneratorState), R(3), U8(0), U8(1),
B(Mov), R(closure), R(12),
B(Mov), R(this), R(13),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(12), U8(2),
B(Star), R(2),
B(Star), R(3),
/* 16 E> */ B(StackCheck),
B(CallJSRuntime), U8(%async_function_promise_create), R(0), U8(0),
B(Star), R(11),
B(Star), R(0),
B(Mov), R(context), R(14),
B(Mov), R(context), R(15),
B(LdaZero),
B(Star), R(7),
B(Star), R(8),
B(Mov), R(context), R(18),
B(Mov), R(context), R(19),
/* 40 S> */ B(LdaNamedProperty), R(arg0), U8(1), U8(0),
......@@ -1141,32 +1141,32 @@ bytecodes: [
B(Mov), R(arg0), R(20),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
/* 40 E> */ B(LdaNamedProperty), R(4), U8(2), U8(4),
B(Star), R(5),
/* 35 S> */ B(CallProperty0), R(5), R(4), U8(6),
/* 40 E> */ B(LdaNamedProperty), R(5), U8(2), U8(4),
B(Star), R(6),
/* 35 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
/* 35 S> */ B(CallProperty0), R(6), R(5), U8(6),
B(Star), R(7),
/* 35 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(3), U8(8),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(3), U8(8),
B(JumpIfToBooleanTrue), U8(63),
B(LdaNamedProperty), R(6), U8(4), U8(10),
B(Star), R(8),
B(LdaNamedProperty), R(7), U8(4), U8(10),
B(Star), R(9),
B(LdaSmi), I8(2),
B(Star), R(7),
B(Mov), R(8), R(3),
B(Star), R(8),
B(Mov), R(9), R(4),
/* 26 E> */ B(StackCheck),
B(Mov), R(3), R(0),
/* 45 S> */ B(Mov), R(2), R(20),
B(Mov), R(0), R(21),
B(Mov), R(11), R(22),
B(Mov), R(4), R(1),
/* 45 S> */ B(Mov), R(3), R(20),
B(Mov), R(1), R(21),
B(Mov), R(0), R(22),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(20), U8(3),
/* 45 E> */ B(SuspendGenerator), R(2), R(0), U8(20), U8(0),
B(ResumeGenerator), R(2), R(0), U8(20),
/* 45 E> */ B(SuspendGenerator), R(3), R(0), U8(20), U8(0),
B(ResumeGenerator), R(3), R(0), U8(20),
B(Star), R(20),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
B(Star), R(21),
B(LdaZero),
B(TestReferenceEqual), R(21),
......@@ -1174,7 +1174,7 @@ bytecodes: [
B(Ldar), R(20),
B(ReThrow),
B(LdaZero),
B(Star), R(7),
B(Star), R(8),
B(JumpLoop), U8(82), I8(0),
B(Jump), U8(37),
B(Star), R(20),
......@@ -1185,10 +1185,10 @@ bytecodes: [
B(Ldar), R(19),
B(PushContext), R(20),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(7), U8(12),
B(TestEqualStrict), R(8), U8(12),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(7),
B(Star), R(8),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(21),
B(CallRuntime), U16(Runtime::kReThrow), R(21), U8(1),
......@@ -1204,17 +1204,17 @@ bytecodes: [
B(SetPendingMessage),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrict), R(7), U8(13),
B(TestEqualStrict), R(8), U8(13),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(4), U8(6), U8(14),
B(Star), R(9),
B(LdaNamedProperty), R(5), U8(6), U8(14),
B(Star), R(10),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(7), U8(16),
B(TestEqualStrict), R(8), U8(16),
B(JumpIfFalse), U8(47),
B(Ldar), R(9),
B(Ldar), R(10),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
......@@ -1225,22 +1225,22 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kNewTypeError), R(19), U8(2),
B(Throw),
B(Mov), R(context), R(19),
B(Mov), R(9), R(20),
B(Mov), R(4), R(21),
B(Mov), R(10), R(20),
B(Mov), R(5), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(20), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(19),
B(Jump), U8(27),
B(Mov), R(9), R(19),
B(Mov), R(4), R(20),
B(Mov), R(10), R(19),
B(Mov), R(5), R(20),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(2),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(Ldar), R(18),
B(SetPendingMessage),
B(LdaZero),
......@@ -1250,11 +1250,11 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star), R(17),
B(Mov), R(11), R(16),
B(Mov), R(0), R(16),
B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(16), U8(2),
B(LdaZero),
B(Star), R(12),
B(Mov), R(11), R(13),
B(Mov), R(0), R(13),
B(Jump), U8(55),
B(Jump), U8(39),
B(Star), R(16),
......@@ -1268,12 +1268,12 @@ bytecodes: [
B(Star), R(18),
B(LdaFalse),
B(Star), R(19),
B(Mov), R(11), R(17),
B(Mov), R(0), R(17),
B(InvokeIntrinsic), U8(Runtime::k_RejectPromise), R(17), U8(3),
B(PopContext), R(16),
B(LdaZero),
B(Star), R(12),
B(Mov), R(11), R(13),
B(Mov), R(0), R(13),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(13),
......@@ -1287,7 +1287,7 @@ bytecodes: [
B(Star), R(14),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(11), R(15),
B(Mov), R(0), R(15),
B(CallJSRuntime), U8(%async_function_promise_release), R(15), U8(2),
B(Ldar), R(14),
B(SetPendingMessage),
......
......@@ -385,27 +385,27 @@ bytecode array length: 140
bytecodes: [
/* 16 E> */ B(StackCheck),
B(CallJSRuntime), U8(%async_function_promise_create), R(0), U8(0),
B(Star), R(3),
B(Star), R(0),
B(Mov), R(context), R(6),
B(Mov), R(context), R(7),
/* 36 S> */ B(LdaZero),
B(Star), R(1),
B(Star), R(2),
/* 41 S> */ B(LdaSmi), I8(10),
/* 41 E> */ B(TestLessThan), R(1), U8(0),
/* 41 E> */ B(TestLessThan), R(2), U8(0),
B(JumpIfFalse), U8(15),
/* 23 E> */ B(StackCheck),
/* 62 S> */ B(Mov), R(1), R(0),
/* 49 S> */ B(Ldar), R(0),
/* 62 S> */ B(Mov), R(2), R(1),
/* 49 S> */ B(Ldar), R(1),
B(Inc), U8(1),
B(Star), R(1),
B(Star), R(2),
B(JumpLoop), U8(17), I8(0),
B(LdaUndefined),
B(Star), R(9),
B(Mov), R(3), R(8),
B(Mov), R(0), R(8),
/* 49 E> */ B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(8), U8(2),
B(LdaZero),
B(Star), R(4),
B(Mov), R(3), R(5),
B(Mov), R(0), R(5),
B(Jump), U8(55),
B(Jump), U8(39),
B(Star), R(8),
......@@ -419,12 +419,12 @@ bytecodes: [
B(Star), R(10),
B(LdaFalse),
B(Star), R(11),
B(Mov), R(3), R(9),
B(Mov), R(0), R(9),
B(InvokeIntrinsic), U8(Runtime::k_RejectPromise), R(9), U8(3),
B(PopContext), R(8),
B(LdaZero),
B(Star), R(4),
B(Mov), R(3), R(5),
B(Mov), R(0), R(5),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(5),
......@@ -438,7 +438,7 @@ bytecodes: [
B(Star), R(6),
B(LdaFalse),
B(Star), R(8),
B(Mov), R(3), R(7),
B(Mov), R(0), R(7),
B(CallJSRuntime), U8(%async_function_promise_release), R(7), U8(2),
B(Ldar), R(6),
B(SetPendingMessage),
......@@ -473,47 +473,47 @@ frame size: 11
parameter count: 1
bytecode array length: 191
bytecodes: [
B(SwitchOnGeneratorState), R(1), U8(0), U8(1),
B(SwitchOnGeneratorState), R(2), U8(0), U8(1),
B(Mov), R(closure), R(3),
B(Mov), R(this), R(4),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(3), U8(2),
B(Star), R(1),
B(Star), R(2),
/* 16 E> */ B(StackCheck),
B(CallJSRuntime), U8(%async_function_promise_create), R(0), U8(0),
B(Star), R(2),
B(Star), R(0),
B(Mov), R(context), R(5),
B(Mov), R(context), R(6),
/* 36 S> */ B(LdaZero),
B(Star), R(0),
B(Star), R(1),
/* 41 S> */ B(LdaSmi), I8(10),
/* 41 E> */ B(TestLessThan), R(0), U8(0),
/* 41 E> */ B(TestLessThan), R(1), U8(0),
B(JumpIfFalse), U8(50),
/* 23 E> */ B(StackCheck),
/* 52 S> */ B(Mov), R(1), R(7),
B(Mov), R(0), R(8),
B(Mov), R(2), R(9),
/* 52 S> */ B(Mov), R(2), R(7),
B(Mov), R(1), R(8),
B(Mov), R(0), R(9),
B(CallJSRuntime), U8(%async_function_await_uncaught), R(7), U8(3),
/* 52 E> */ B(SuspendGenerator), R(1), R(0), U8(7), U8(0),
B(ResumeGenerator), R(1), R(0), U8(7),
/* 52 E> */ B(SuspendGenerator), R(2), R(0), U8(7), U8(0),
B(ResumeGenerator), R(2), R(0), U8(7),
B(Star), R(7),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(1), U8(1),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(Star), R(8),
B(LdaZero),
B(TestReferenceEqual), R(8),
B(JumpIfTrue), U8(5),
B(Ldar), R(7),
B(ReThrow),
/* 49 S> */ B(Ldar), R(0),
/* 49 S> */ B(Ldar), R(1),
B(Inc), U8(1),
B(Star), R(0),
B(Star), R(1),
B(JumpLoop), U8(52), I8(0),
B(LdaUndefined),
B(Star), R(8),
B(Mov), R(2), R(7),
B(Mov), R(0), R(7),
/* 49 E> */ B(InvokeIntrinsic), U8(Runtime::k_ResolvePromise), R(7), U8(2),
B(LdaZero),
B(Star), R(3),
B(Mov), R(2), R(4),
B(Mov), R(0), R(4),
B(Jump), U8(55),
B(Jump), U8(39),
B(Star), R(7),
......@@ -527,12 +527,12 @@ bytecodes: [
B(Star), R(9),
B(LdaFalse),
B(Star), R(10),
B(Mov), R(2), R(8),
B(Mov), R(0), R(8),
B(InvokeIntrinsic), U8(Runtime::k_RejectPromise), R(8), U8(3),
B(PopContext), R(7),
B(LdaZero),
B(Star), R(3),
B(Mov), R(2), R(4),
B(Mov), R(0), R(4),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(4),
......@@ -546,7 +546,7 @@ bytecodes: [
B(Star), R(5),
B(LdaTrue),
B(Star), R(7),
B(Mov), R(2), R(6),
B(Mov), R(0), R(6),
B(CallJSRuntime), U8(%async_function_promise_release), R(6), U8(2),
B(Ldar), R(5),
B(SetPendingMessage),
......
// Copyright 2018 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: --async-stack-traces
// Check that Error.prepareStackTrace doesn't expose strict
// mode closures, even in the presence of async frames.
Error.prepareStackTrace = (e, frames) => {
assertEquals(two, frames[0].getFunction());
assertEquals(two.name, frames[0].getFunctionName());
assertEquals(undefined, frames[1].getFunction());
assertEquals(one.name, frames[1].getFunctionName());
return frames;
};
async function one(x) {
"use strict";
return await two(x);
}
async function two(x) {
try {
x = await x;
throw new Error();
} catch (e) {
return e.stack;
}
}
one(1).catch(e => setTimeout(_ => {throw e}, 0));
// Copyright 2018 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: --async-stack-traces
// Check that Error.prepareStackTrace doesn't expose strict
// mode closures, even in the presence of async frames.
Error.prepareStackTrace = (e, frames) => {
assertEquals(undefined, frames[0].getFunction());
assertEquals(two.name, frames[0].getFunctionName());
assertEquals(undefined, frames[1].getFunction());
assertEquals(one.name, frames[1].getFunctionName());
return frames;
};
async function one(x) {
return await two(x);
}
async function two(x) {
"use strict";
try {
x = await x;
throw new Error();
} catch (e) {
return e.stack;
}
}
one(1).catch(e => setTimeout(_ => {throw e}, 0));
// Copyright 2018 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: --async-stack-traces
// Check that Error.prepareStackTrace properly marks async frames.
Error.prepareStackTrace = (e, frames) => {
assertEquals(two, frames[0].getFunction());
assertEquals(two.name, frames[0].getFunctionName());
assertFalse(frames[0].isAsync());
assertEquals(two, frames[1].getFunction());
assertEquals(one.name, frames[1].getFunctionName());
assertTrue(frames[1].isAsync());
return frames;
};
async function one(x) {
return await two(x);
}
async function two(x) {
try {
x = await x;
throw new Error();
} catch (e) {
return e.stack;
}
}
one(1).catch(e => setTimeout(_ => {throw e}, 0));
// Copyright 2018 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: --allow-natives-syntax --async-stack-traces
// Basic test with an explicit throw.
(function() {
async function one(x) {
await two(x);
}
async function two(x) {
await x;
throw new Error();
}
async function test(f) {
try {
await f(1);
assertUnreachable();
} catch (e) {
assertInstanceof(e, Error);
assertMatches(/Error.+at two.+at async one.+at async test/ms, e.stack);
}
}
assertPromiseResult((async () => {
await test(one);
await test(one);
%OptimizeFunctionOnNextCall(two);
await test(one);
%OptimizeFunctionOnNextCall(one);
await test(one);
})());
})();
// Basic test with an implicit throw (via ToNumber on Symbol).
(function() {
async function one(x) {
return await two(x);
}
async function two(x) {
await x;
return +x; // This will raise a TypeError.
}
async function test(f) {
try {
await f(Symbol());
assertUnreachable();
} catch (e) {
assertInstanceof(e, TypeError);
assertMatches(/TypeError.+at two.+at async one.+at async test/ms, e.stack);
}
}
assertPromiseResult((async() => {
await test(one);
await test(one);
%OptimizeFunctionOnNextCall(two);
await test(one);
%OptimizeFunctionOnNextCall(one);
await test(one);
})());
})();
// Basic test with throw in inlined function.
(function() {
function throwError() {
throw new Error();
}
async function one(x) {
return await two(x);
}
async function two(x) {
await x;
return throwError();
}
async function test(f) {
try {
await f(1);
assertUnreachable();
} catch (e) {
assertInstanceof(e, Error);
assertMatches(/Error.+at two.+at async one.+at async test/ms, e.stack);
}
}
assertPromiseResult((async() => {
await test(one);
await test(one);
%OptimizeFunctionOnNextCall(two);
await test(one);
%OptimizeFunctionOnNextCall(one);
await test(one);
})());
})();
// Basic test with async function inlined into sync function.
(function() {
function callOne(x) {
return one(x);
}
function callTwo(x) {
return two(x);
}
async function one(x) {
return await callTwo(x);
}
async function two(x) {
await x;
throw new Error();
}
async function test(f) {
try {
await f(1);
assertUnreachable();
} catch (e) {
assertInstanceof(e, Error);
assertMatches(/Error.+at two.+at async one.+at async test/ms, e.stack);
}
}
assertPromiseResult((async() => {
await test(callOne);
await test(callOne);
%OptimizeFunctionOnNextCall(callTwo);
await test(callOne);
%OptimizeFunctionOnNextCall(callOne);
await test(callOne);
})());
})();
// Basic test with async functions and promises chained via
// Promise.prototype.then(), which should still work following
// the generic chain upwards.
(function() {
async function one(x) {
return await two(x).then(x => x);
}
async function two(x) {
await x.then(x => x);
throw new Error();
}
async function test(f) {
try {
await f(Promise.resolve(1));
assertUnreachable();
} catch (e) {
assertInstanceof(e, Error);
assertMatches(/Error.+at two.+at async one.+at async test/ms, e.stack);
}
}
assertPromiseResult((async() => {
await test(one);
await test(one);
%OptimizeFunctionOnNextCall(two);
await test(one);
%OptimizeFunctionOnNextCall(one);
await test(one);
})());
})();
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