Commit 4a285a25 authored by jameslahm's avatar jameslahm Committed by V8 LUCI CQ

[iterator] Extend GetIterator to Check iterator type

This CL extends GetIterator to check whether the result of
calling @@iterator is JSReceiver and throw SymbolIteratorInvalid
if it's not JSReceiver.

GetIterator bytecode involves 3 steps now:
- method = GetMethod(obj, @@iterator)
- iterator = Call(method, obj)
- if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid [Added]

New Builtin: CallIteratorWithFeedbackLazyDeoptContinuation, which
is used when lazy deopt is triggered by call @@iterator.

Related spec: https://tc39.es/ecma262/#sec-getiterator.
Related doc: https://docs.google.com/document/d/1s67HC2f-4zxA_s1Bmm7dfwMFv_KDUfMiWIKkNSeQNKw/edit#heading=h.kdzv8mq4g4ks.

Bug: v8:9489
Change-Id: I17952c0f3e24e1e600ee1348809fb188c2c70f8e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3563447Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: 王澳 <wangao.james@bytedance.com>
Cr-Commit-Position: refs/heads/main@{#80112}
parent 0603f8a9
...@@ -389,6 +389,7 @@ extern enum MessageTemplate { ...@@ -389,6 +389,7 @@ extern enum MessageTemplate {
kInvalidCountValue, kInvalidCountValue,
kConstructorNotFunction, kConstructorNotFunction,
kSymbolToString, kSymbolToString,
kSymbolIteratorInvalid,
kPropertyNotFunction, kPropertyNotFunction,
kBigIntTooBig, kBigIntTooBig,
kNotTypedArray, kNotTypedArray,
......
...@@ -590,6 +590,7 @@ namespace internal { ...@@ -590,6 +590,7 @@ namespace internal {
\ \
/* Iterator Protocol */ \ /* Iterator Protocol */ \
TFC(GetIteratorWithFeedbackLazyDeoptContinuation, GetIteratorStackParameter) \ TFC(GetIteratorWithFeedbackLazyDeoptContinuation, GetIteratorStackParameter) \
TFC(CallIteratorWithFeedbackLazyDeoptContinuation, SingleParameterOnStack) \
\ \
/* Global object */ \ /* Global object */ \
CPP(GlobalDecodeURI) \ CPP(GlobalDecodeURI) \
......
...@@ -472,6 +472,16 @@ TF_BUILTIN(GetIteratorWithFeedbackLazyDeoptContinuation, ...@@ -472,6 +472,16 @@ TF_BUILTIN(GetIteratorWithFeedbackLazyDeoptContinuation,
Return(result); Return(result);
} }
TF_BUILTIN(CallIteratorWithFeedbackLazyDeoptContinuation,
IteratorBuiltinsAssembler) {
TNode<Context> context = Parameter<Context>(Descriptor::kContext);
TNode<Object> iterator = Parameter<Object>(Descriptor::kArgument);
ThrowIfNotJSReceiver(context, iterator,
MessageTemplate::kSymbolIteratorInvalid, "");
Return(iterator);
}
// This builtin creates a FixedArray based on an Iterable and doesn't have a // This builtin creates a FixedArray based on an Iterable and doesn't have a
// fast path for anything. // fast path for anything.
TF_BUILTIN(IterableToFixedArrayWithSymbolLookupSlow, TF_BUILTIN(IterableToFixedArrayWithSymbolLookupSlow,
......
...@@ -111,7 +111,9 @@ transitioning builtin CallIteratorWithFeedback( ...@@ -111,7 +111,9 @@ transitioning builtin CallIteratorWithFeedback(
context, feedback, callSlotUnTagged); context, feedback, callSlotUnTagged);
const iteratorCallable: Callable = Cast<Callable>(iteratorMethod) const iteratorCallable: Callable = Cast<Callable>(iteratorMethod)
otherwise ThrowIteratorError(receiver); otherwise ThrowIteratorError(receiver);
return Call(context, iteratorCallable, receiver); const iterator = Call(context, iteratorCallable, receiver);
ThrowIfNotJSReceiver(iterator, MessageTemplate::kSymbolIteratorInvalid, '');
return iterator;
} }
// https://tc39.es/ecma262/#sec-iteratorclose // https://tc39.es/ecma262/#sec-iteratorclose
......
...@@ -1454,6 +1454,44 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) { ...@@ -1454,6 +1454,44 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) {
Effect effect = n.effect(); Effect effect = n.effect();
Control control = n.control(); Control control = n.control();
Node* iterator_exception_node = nullptr;
Node* if_exception_merge = nullptr;
Node* if_exception_effect_phi = nullptr;
Node* if_exception_phi = nullptr;
bool has_exception_node =
NodeProperties::IsExceptionalCall(node, &iterator_exception_node);
int exception_node_index = 0;
if (has_exception_node) {
DCHECK_NOT_NULL(iterator_exception_node);
// If there exists an IfException node for the iterator node, we need
// to merge all the desugared nodes exception. The iterator node will be
// desugared to LoadNamed, Call, CallRuntime, we can pre-allocate the
// nodes with 4 inputs here and we use dead_node as a placeholder for the
// input, which will be replaced.
// We use dead_node as a placeholder for the original exception node before
// it's uses are rewired.
Node* dead_node = jsgraph()->Dead();
if_exception_merge = graph()->NewNode(common()->Merge(4), dead_node,
dead_node, dead_node, dead_node);
if_exception_effect_phi =
graph()->NewNode(common()->EffectPhi(4), dead_node, dead_node,
dead_node, dead_node, if_exception_merge);
if_exception_phi = graph()->NewNode(
common()->Phi(MachineRepresentation::kTagged, 4), dead_node, dead_node,
dead_node, dead_node, if_exception_merge);
// Rewire the original exception node uses.
ReplaceWithValue(iterator_exception_node, if_exception_phi,
if_exception_effect_phi, if_exception_merge);
if_exception_merge->ReplaceInput(exception_node_index,
iterator_exception_node);
if_exception_effect_phi->ReplaceInput(exception_node_index,
iterator_exception_node);
if_exception_phi->ReplaceInput(exception_node_index,
iterator_exception_node);
exception_node_index++;
}
// Load iterator property operator // Load iterator property operator
NameRef iterator_symbol = MakeRef(broker(), factory()->iterator_symbol()); NameRef iterator_symbol = MakeRef(broker(), factory()->iterator_symbol());
const Operator* load_op = const Operator* load_op =
...@@ -1474,32 +1512,15 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) { ...@@ -1474,32 +1512,15 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) {
effect = load_property; effect = load_property;
control = load_property; control = load_property;
// Handle exception path for the load named property // Merge the exception path for LoadNamed.
Node* iterator_exception_node = nullptr; if (has_exception_node) {
if (NodeProperties::IsExceptionalCall(node, &iterator_exception_node)) { Node* if_exception =
// If there exists an exception node for the given iterator_node, create a
// pair of IfException/IfSuccess nodes on the current control path. The uses
// of new exception node are merged with the original exception node. The
// IfSuccess node is returned as a control path for further reduction.
Node* exception_node =
graph()->NewNode(common()->IfException(), effect, control); graph()->NewNode(common()->IfException(), effect, control);
Node* if_success = graph()->NewNode(common()->IfSuccess(), control); if_exception_merge->ReplaceInput(exception_node_index, if_exception);
if_exception_phi->ReplaceInput(exception_node_index, if_exception);
// Use dead_node as a placeholder for the original exception node until if_exception_effect_phi->ReplaceInput(exception_node_index, if_exception);
// its uses are rewired to the nodes merging the exceptions exception_node_index++;
Node* dead_node = jsgraph()->Dead(); control = graph()->NewNode(common()->IfSuccess(), control);
Node* merge_node =
graph()->NewNode(common()->Merge(2), dead_node, exception_node);
Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), dead_node,
exception_node, merge_node);
Node* phi =
graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
dead_node, exception_node, merge_node);
ReplaceWithValue(iterator_exception_node, phi, effect_phi, merge_node);
phi->ReplaceInput(0, iterator_exception_node);
effect_phi->ReplaceInput(0, iterator_exception_node);
merge_node->ReplaceInput(0, iterator_exception_node);
control = if_success;
} }
// Eager deopt of call iterator property // Eager deopt of call iterator property
...@@ -1521,11 +1542,73 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) { ...@@ -1521,11 +1542,73 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) {
JSCallNode::ArityForArgc(0), CallFrequency(), p.callFeedback(), JSCallNode::ArityForArgc(0), CallFrequency(), p.callFeedback(),
ConvertReceiverMode::kNotNullOrUndefined, mode, ConvertReceiverMode::kNotNullOrUndefined, mode,
CallFeedbackRelation::kTarget); CallFeedbackRelation::kTarget);
Node* call_property = // Lazy deopt to check the call result is JSReceiver.
Node* call_lazy_deopt_frame_state = CreateStubBuiltinContinuationFrameState(
jsgraph(), Builtin::kCallIteratorWithFeedbackLazyDeoptContinuation,
context, nullptr, 0, frame_state, ContinuationFrameStateMode::LAZY);
Node* call_property = effect = control =
graph()->NewNode(call_op, load_property, receiver, n.feedback_vector(), graph()->NewNode(call_op, load_property, receiver, n.feedback_vector(),
context, frame_state, effect, control); context, call_lazy_deopt_frame_state, effect, control);
return Replace(call_property); // Merge the exception path for Call.
if (has_exception_node) {
Node* if_exception =
graph()->NewNode(common()->IfException(), effect, control);
if_exception_merge->ReplaceInput(exception_node_index, if_exception);
if_exception_phi->ReplaceInput(exception_node_index, if_exception);
if_exception_effect_phi->ReplaceInput(exception_node_index, if_exception);
exception_node_index++;
control = graph()->NewNode(common()->IfSuccess(), control);
}
// If the result is not JSReceiver, throw invalid iterator exception.
Node* is_receiver =
graph()->NewNode(simplified()->ObjectIsReceiver(), call_property);
Node* branch_node = graph()->NewNode(common()->Branch(BranchHint::kTrue),
is_receiver, control);
{
Node* if_not_receiver = graph()->NewNode(common()->IfFalse(), branch_node);
Node* effect_not_receiver = effect;
Node* control_not_receiver = if_not_receiver;
Node* call_runtime = effect_not_receiver = control_not_receiver =
graph()->NewNode(
javascript()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid, 0),
context, frame_state, effect_not_receiver, control_not_receiver);
// Merge the exception path for CallRuntime.
if (has_exception_node) {
Node* if_exception = graph()->NewNode(
common()->IfException(), effect_not_receiver, control_not_receiver);
if_exception_merge->ReplaceInput(exception_node_index, if_exception);
if_exception_phi->ReplaceInput(exception_node_index, if_exception);
if_exception_effect_phi->ReplaceInput(exception_node_index, if_exception);
exception_node_index++;
control_not_receiver =
graph()->NewNode(common()->IfSuccess(), control_not_receiver);
}
Node* throw_node =
graph()->NewNode(common()->Throw(), call_runtime, control_not_receiver);
NodeProperties::MergeControlToEnd(graph(), common(), throw_node);
}
Node* if_receiver = graph()->NewNode(common()->IfTrue(), branch_node);
ReplaceWithValue(node, call_property, effect, if_receiver);
if (has_exception_node) {
DCHECK_EQ(exception_node_index, if_exception_merge->InputCount());
DCHECK_EQ(exception_node_index, if_exception_effect_phi->InputCount() - 1);
DCHECK_EQ(exception_node_index, if_exception_phi->InputCount() - 1);
#ifdef DEBUG
for (Node* input : if_exception_merge->inputs()) {
DCHECK(!input->IsDead());
}
for (Node* input : if_exception_effect_phi->inputs()) {
DCHECK(!input->IsDead());
}
for (Node* input : if_exception_phi->inputs()) {
DCHECK(!input->IsDead());
}
#endif
}
return Replace(if_receiver);
} }
Reduction JSNativeContextSpecialization::ReduceJSSetNamedProperty(Node* node) { Reduction JSNativeContextSpecialization::ReduceJSSetNamedProperty(Node* node) {
......
...@@ -6342,16 +6342,11 @@ void BytecodeGenerator::BuildGetIterator(IteratorType hint) { ...@@ -6342,16 +6342,11 @@ void BytecodeGenerator::BuildGetIterator(IteratorType hint) {
feedback_index(feedback_spec()->AddCallICSlot()); feedback_index(feedback_spec()->AddCallICSlot());
// Let method be GetMethod(obj, @@iterator) and // Let method be GetMethod(obj, @@iterator) and
// iterator be Call(method, obj). // iterator be Call(method, obj). If iterator is
// not JSReceiver, then throw TypeError.
builder()->StoreAccumulatorInRegister(obj).GetIterator( builder()->StoreAccumulatorInRegister(obj).GetIterator(
obj, load_feedback_index, call_feedback_index); obj, load_feedback_index, call_feedback_index);
} }
// If Type(iterator) is not Object, throw a TypeError exception.
BytecodeLabel no_type_error;
builder()->JumpIfJSReceiver(&no_type_error);
builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid);
builder()->Bind(&no_type_error);
} }
} }
......
...@@ -2931,10 +2931,8 @@ IGNITION_HANDLER(ForInStep, InterpreterAssembler) { ...@@ -2931,10 +2931,8 @@ IGNITION_HANDLER(ForInStep, InterpreterAssembler) {
// GetIterator <object> // GetIterator <object>
// //
// Retrieves the object[Symbol.iterator] method, calls it and stores // Retrieves the object[Symbol.iterator] method, calls it and stores
// the result in the accumulator // the result in the accumulator. If the result is not JSReceiver,
// TODO(swapnilgaikwad): Extend the functionality of the bytecode to // throw SymbolIteratorInvalid runtime exception.
// check if the result is a JSReceiver else throw SymbolIteratorInvalid
// runtime exception
IGNITION_HANDLER(GetIterator, InterpreterAssembler) { IGNITION_HANDLER(GetIterator, InterpreterAssembler) {
TNode<Object> receiver = LoadRegisterAtOperandIndex(0); TNode<Object> receiver = LoadRegisterAtOperandIndex(0);
TNode<Context> context = GetContext(); TNode<Context> context = GetContext();
......
...@@ -138,7 +138,7 @@ snippet: " ...@@ -138,7 +138,7 @@ snippet: "
" "
frame size: 6 frame size: 6
parameter count: 1 parameter count: 1
bytecode array length: 68 bytecode array length: 61
bytecodes: [ bytecodes: [
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star0), B(Star0),
...@@ -147,8 +147,6 @@ bytecodes: [ ...@@ -147,8 +147,6 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
/* 67 S> */ B(Star1), /* 67 S> */ B(Star1),
/* 67 E> */ B(GetIterator), R(0), U8(2), U8(4), /* 67 E> */ B(GetIterator), R(0), U8(2), U8(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star4), B(Star4),
B(GetNamedProperty), R(4), U8(2), U8(6), B(GetNamedProperty), R(4), U8(2), U8(6),
B(Star3), B(Star3),
......
...@@ -210,7 +210,7 @@ snippet: " ...@@ -210,7 +210,7 @@ snippet: "
" "
frame size: 18 frame size: 18
parameter count: 1 parameter count: 1
bytecode array length: 311 bytecode array length: 304
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(4), B(Mov), R(closure), R(4),
...@@ -230,12 +230,10 @@ bytecodes: [ ...@@ -230,12 +230,10 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star4), B(Star4),
B(Mov), R(8), R(5), B(Mov), R(8), R(5),
B(Jump), U8(222), B(Jump), U8(215),
/* 36 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37), /* 36 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37),
B(Star10), B(Star10),
B(GetIterator), R(10), U8(1), U8(3), B(GetIterator), R(10), U8(1), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star9), B(Star9),
B(GetNamedProperty), R(9), U8(5), U8(5), B(GetNamedProperty), R(9), U8(5), U8(5),
B(Star8), B(Star8),
...@@ -360,7 +358,7 @@ bytecodes: [ ...@@ -360,7 +358,7 @@ bytecodes: [
] ]
constant pool: [ constant pool: [
Smi [28], Smi [28],
Smi [130], Smi [123],
Smi [15], Smi [15],
Smi [7], Smi [7],
ARRAY_BOILERPLATE_DESCRIPTION_TYPE, ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
...@@ -378,10 +376,10 @@ constant pool: [ ...@@ -378,10 +376,10 @@ constant pool: [
Smi [22], Smi [22],
] ]
handlers: [ handlers: [
[18, 269, 269], [18, 262, 262],
[21, 240, 240], [21, 233, 233],
[79, 160, 166], [72, 153, 159],
[179, 200, 202], [172, 193, 195],
] ]
--- ---
......
...@@ -65,7 +65,7 @@ snippet: " ...@@ -65,7 +65,7 @@ snippet: "
" "
frame size: 7 frame size: 7
parameter count: 1 parameter count: 1
bytecode array length: 89 bytecode array length: 82
bytecodes: [ bytecodes: [
/* 34 S> */ B(LdaGlobal), U8(0), U8(0), /* 34 S> */ B(LdaGlobal), U8(0), U8(0),
B(Star1), B(Star1),
...@@ -78,8 +78,6 @@ bytecodes: [ ...@@ -78,8 +78,6 @@ bytecodes: [
/* 49 S> */ B(CreateArrayLiteral), U8(3), U8(5), U8(37), /* 49 S> */ B(CreateArrayLiteral), U8(3), U8(5), U8(37),
B(Star6), B(Star6),
/* 49 E> */ B(GetIterator), R(6), U8(6), U8(8), /* 49 E> */ B(GetIterator), R(6), U8(6), U8(8),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star5), B(Star5),
B(GetNamedProperty), R(5), U8(4), U8(10), B(GetNamedProperty), R(5), U8(4), U8(10),
B(Star4), B(Star4),
......
...@@ -12,18 +12,16 @@ snippet: " ...@@ -12,18 +12,16 @@ snippet: "
" "
frame size: 13 frame size: 13
parameter count: 1 parameter count: 1
bytecode array length: 129 bytecode array length: 122
bytecodes: [ bytecodes: [
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star1), B(Star1),
/* 60 S> */ B(GetIterator), R(1), U8(1), U8(3), /* 60 S> */ B(GetIterator), R(1), U8(1), U8(3),
B(Mov), R(1), R(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star4), B(Star4),
B(GetNamedProperty), R(4), U8(1), U8(5), B(GetNamedProperty), R(4), U8(1), U8(5),
B(Star3), B(Star3),
B(LdaFalse), B(LdaFalse),
B(Mov), R(1), R(2),
B(Star5), B(Star5),
B(Mov), R(context), R(8), B(Mov), R(context), R(8),
/* 57 S> */ B(Ldar), R(5), /* 57 S> */ B(Ldar), R(5),
...@@ -89,8 +87,8 @@ constant pool: [ ...@@ -89,8 +87,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[30, 67, 73], [23, 60, 66],
[86, 105, 107], [79, 98, 100],
] ]
--- ---
...@@ -100,18 +98,16 @@ snippet: " ...@@ -100,18 +98,16 @@ snippet: "
" "
frame size: 14 frame size: 14
parameter count: 1 parameter count: 1
bytecode array length: 204 bytecode array length: 197
bytecodes: [ bytecodes: [
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star2), B(Star2),
/* 69 S> */ B(GetIterator), R(2), U8(1), U8(3), /* 69 S> */ B(GetIterator), R(2), U8(1), U8(3),
B(Mov), R(2), R(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star5), B(Star5),
B(GetNamedProperty), R(5), U8(1), U8(5), B(GetNamedProperty), R(5), U8(1), U8(5),
B(Star4), B(Star4),
B(LdaFalse), B(LdaFalse),
B(Mov), R(2), R(3),
B(Star6), B(Star6),
B(Mov), R(context), R(9), B(Mov), R(context), R(9),
B(Ldar), R(6), B(Ldar), R(6),
...@@ -210,8 +206,8 @@ constant pool: [ ...@@ -210,8 +206,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[30, 142, 148], [23, 135, 141],
[161, 180, 182], [154, 173, 175],
] ]
--- ---
...@@ -221,20 +217,18 @@ snippet: " ...@@ -221,20 +217,18 @@ snippet: "
" "
frame size: 15 frame size: 15
parameter count: 1 parameter count: 1
bytecode array length: 175 bytecode array length: 168
bytecodes: [ bytecodes: [
/* 40 S> */ B(CreateEmptyObjectLiteral), /* 40 S> */ B(CreateEmptyObjectLiteral),
B(Star0), B(Star0),
/* 51 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 51 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star2), B(Star2),
/* 68 S> */ B(GetIterator), R(2), U8(1), U8(3), /* 68 S> */ B(GetIterator), R(2), U8(1), U8(3),
B(Mov), R(2), R(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star5), B(Star5),
B(GetNamedProperty), R(5), U8(1), U8(5), B(GetNamedProperty), R(5), U8(1), U8(5),
B(Star4), B(Star4),
B(LdaFalse), B(LdaFalse),
B(Mov), R(2), R(3),
B(Star6), B(Star6),
B(Mov), R(context), R(9), B(Mov), R(context), R(9),
/* 59 S> */ B(Ldar), R(6), /* 59 S> */ B(Ldar), R(6),
...@@ -320,8 +314,8 @@ constant pool: [ ...@@ -320,8 +314,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[32, 113, 119], [25, 106, 112],
[132, 151, 153], [125, 144, 146],
] ]
--- ---
......
...@@ -485,7 +485,7 @@ snippet: " ...@@ -485,7 +485,7 @@ snippet: "
" "
frame size: 14 frame size: 14
parameter count: 1 parameter count: 1
bytecode array length: 198 bytecode array length: 191
bytecodes: [ bytecodes: [
B(Mov), R(closure), R(2), B(Mov), R(closure), R(2),
B(Mov), R(this), R(3), B(Mov), R(this), R(3),
...@@ -497,8 +497,6 @@ bytecodes: [ ...@@ -497,8 +497,6 @@ bytecodes: [
/* 68 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), /* 68 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star5), B(Star5),
B(GetIterator), R(5), U8(2), U8(4), B(GetIterator), R(5), U8(2), U8(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star4), B(Star4),
B(GetNamedProperty), R(4), U8(2), U8(6), B(GetNamedProperty), R(4), U8(2), U8(6),
B(Star3), B(Star3),
...@@ -594,8 +592,8 @@ constant pool: [ ...@@ -594,8 +592,8 @@ constant pool: [
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
] ]
handlers: [ handlers: [
[14, 176, 176], [14, 169, 169],
[46, 92, 98], [39, 85, 91],
[111, 130, 132], [104, 123, 125],
] ]
...@@ -11,13 +11,11 @@ snippet: " ...@@ -11,13 +11,11 @@ snippet: "
" "
frame size: 12 frame size: 12
parameter count: 1 parameter count: 1
bytecode array length: 128 bytecode array length: 121
bytecodes: [ bytecodes: [
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star4), B(Star4),
B(GetIterator), R(4), U8(1), U8(3), B(GetIterator), R(4), U8(1), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star3), B(Star3),
B(GetNamedProperty), R(3), U8(1), U8(5), B(GetNamedProperty), R(3), U8(1), U8(5),
B(Star2), B(Star2),
...@@ -85,8 +83,8 @@ constant pool: [ ...@@ -85,8 +83,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[27, 66, 72], [20, 59, 65],
[85, 104, 106], [78, 97, 99],
] ]
--- ---
...@@ -96,13 +94,11 @@ snippet: " ...@@ -96,13 +94,11 @@ snippet: "
" "
frame size: 13 frame size: 13
parameter count: 1 parameter count: 1
bytecode array length: 134 bytecode array length: 127
bytecodes: [ bytecodes: [
/* 42 S> */ B(LdaConstant), U8(0), /* 42 S> */ B(LdaConstant), U8(0),
B(Star0), B(Star0),
/* 68 S> */ B(GetIterator), R(0), U8(0), U8(2), /* 68 S> */ B(GetIterator), R(0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star4), B(Star4),
B(GetNamedProperty), R(4), U8(1), U8(4), B(GetNamedProperty), R(4), U8(1), U8(4),
B(Star3), B(Star3),
...@@ -176,8 +172,8 @@ constant pool: [ ...@@ -176,8 +172,8 @@ constant pool: [
Smi [9], Smi [9],
] ]
handlers: [ handlers: [
[25, 66, 72], [18, 59, 65],
[85, 104, 106], [78, 97, 99],
] ]
--- ---
...@@ -189,13 +185,11 @@ snippet: " ...@@ -189,13 +185,11 @@ snippet: "
" "
frame size: 12 frame size: 12
parameter count: 1 parameter count: 1
bytecode array length: 144 bytecode array length: 137
bytecodes: [ bytecodes: [
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star4), B(Star4),
B(GetIterator), R(4), U8(1), U8(3), B(GetIterator), R(4), U8(1), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star3), B(Star3),
B(GetNamedProperty), R(3), U8(1), U8(5), B(GetNamedProperty), R(3), U8(1), U8(5),
B(Star2), B(Star2),
...@@ -270,8 +264,8 @@ constant pool: [ ...@@ -270,8 +264,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[27, 82, 88], [20, 75, 81],
[101, 120, 122], [94, 113, 115],
] ]
--- ---
...@@ -281,15 +275,13 @@ snippet: " ...@@ -281,15 +275,13 @@ snippet: "
" "
frame size: 12 frame size: 12
parameter count: 1 parameter count: 1
bytecode array length: 146 bytecode array length: 139
bytecodes: [ bytecodes: [
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), /* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star0), B(Star0),
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), /* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star3), B(Star3),
B(GetIterator), R(3), U8(2), U8(4), B(GetIterator), R(3), U8(2), U8(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star2), B(Star2),
B(GetNamedProperty), R(2), U8(2), U8(6), B(GetNamedProperty), R(2), U8(2), U8(6),
B(Star1), B(Star1),
...@@ -367,7 +359,7 @@ constant pool: [ ...@@ -367,7 +359,7 @@ constant pool: [
Smi [9], Smi [9],
] ]
handlers: [ handlers: [
[32, 78, 84], [25, 71, 77],
[97, 116, 118], [90, 109, 111],
] ]
...@@ -15,11 +15,9 @@ snippet: " ...@@ -15,11 +15,9 @@ snippet: "
" "
frame size: 14 frame size: 14
parameter count: 2 parameter count: 2
bytecode array length: 126 bytecode array length: 119
bytecodes: [ bytecodes: [
/* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2), /* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star5), B(Star5),
B(GetNamedProperty), R(5), U8(0), U8(4), B(GetNamedProperty), R(5), U8(0), U8(4),
B(Star4), B(Star4),
...@@ -87,8 +85,8 @@ constant pool: [ ...@@ -87,8 +85,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[22, 64, 70], [15, 57, 63],
[83, 102, 104], [76, 95, 97],
] ]
--- ---
...@@ -100,7 +98,7 @@ snippet: " ...@@ -100,7 +98,7 @@ snippet: "
" "
frame size: 20 frame size: 20
parameter count: 2 parameter count: 2
bytecode array length: 206 bytecode array length: 199
bytecodes: [ bytecodes: [
/* 10 E> */ B(CreateFunctionContext), U8(0), U8(5), /* 10 E> */ B(CreateFunctionContext), U8(0), U8(5),
B(PushContext), R(2), B(PushContext), R(2),
...@@ -119,8 +117,6 @@ bytecodes: [ ...@@ -119,8 +117,6 @@ bytecodes: [
/* 34 S> */ B(LdaContextSlot), R(3), U8(4), U8(0), /* 34 S> */ B(LdaContextSlot), R(3), U8(4), U8(0),
B(Star6), B(Star6),
B(GetIterator), R(6), U8(0), U8(2), B(GetIterator), R(6), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star5), B(Star5),
B(GetNamedProperty), R(5), U8(2), U8(4), B(GetNamedProperty), R(5), U8(2), U8(4),
B(Star4), B(Star4),
...@@ -215,8 +211,8 @@ constant pool: [ ...@@ -215,8 +211,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[54, 142, 148], [47, 135, 141],
[161, 180, 182], [154, 173, 175],
] ]
--- ---
...@@ -228,11 +224,9 @@ snippet: " ...@@ -228,11 +224,9 @@ snippet: "
" "
frame size: 13 frame size: 13
parameter count: 2 parameter count: 2
bytecode array length: 142 bytecode array length: 135
bytecodes: [ bytecodes: [
/* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2), /* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star3), B(Star3),
B(GetNamedProperty), R(3), U8(0), U8(4), B(GetNamedProperty), R(3), U8(0), U8(4),
B(Star2), B(Star2),
...@@ -310,8 +304,8 @@ constant pool: [ ...@@ -310,8 +304,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[22, 80, 86], [15, 73, 79],
[99, 118, 120], [92, 111, 113],
] ]
--- ---
...@@ -323,11 +317,9 @@ snippet: " ...@@ -323,11 +317,9 @@ snippet: "
" "
frame size: 16 frame size: 16
parameter count: 2 parameter count: 2
bytecode array length: 134 bytecode array length: 127
bytecodes: [ bytecodes: [
/* 41 S> */ B(GetIterator), R(arg0), U8(0), U8(2), /* 41 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star7), B(Star7),
B(GetNamedProperty), R(7), U8(0), U8(4), B(GetNamedProperty), R(7), U8(0), U8(4),
B(Star6), B(Star6),
...@@ -401,8 +393,8 @@ constant pool: [ ...@@ -401,8 +393,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[22, 72, 78], [15, 65, 71],
[91, 110, 112], [84, 103, 105],
] ]
--- ---
...@@ -414,7 +406,7 @@ snippet: " ...@@ -414,7 +406,7 @@ snippet: "
" "
frame size: 15 frame size: 15
parameter count: 2 parameter count: 2
bytecode array length: 165 bytecode array length: 158
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(1), B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
B(Mov), R(closure), R(5), B(Mov), R(closure), R(5),
...@@ -431,8 +423,6 @@ bytecodes: [ ...@@ -431,8 +423,6 @@ bytecodes: [
B(Ldar), R(5), B(Ldar), R(5),
B(Return), B(Return),
/* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2), /* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star6), B(Star6),
B(GetNamedProperty), R(6), U8(3), U8(4), B(GetNamedProperty), R(6), U8(3), U8(4),
B(Star5), B(Star5),
...@@ -503,8 +493,8 @@ constant pool: [ ...@@ -503,8 +493,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
] ]
handlers: [ handlers: [
[61, 103, 109], [54, 96, 102],
[122, 141, 143], [115, 134, 136],
] ]
--- ---
...@@ -516,7 +506,7 @@ snippet: " ...@@ -516,7 +506,7 @@ snippet: "
" "
frame size: 14 frame size: 14
parameter count: 2 parameter count: 2
bytecode array length: 206 bytecode array length: 199
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(4), B(Mov), R(closure), R(4),
...@@ -533,8 +523,6 @@ bytecodes: [ ...@@ -533,8 +523,6 @@ bytecodes: [
B(Ldar), R(4), B(Ldar), R(4),
B(Return), B(Return),
/* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2), /* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star5), B(Star5),
B(GetNamedProperty), R(5), U8(4), U8(4), B(GetNamedProperty), R(5), U8(4), U8(4),
B(Star4), B(Star4),
...@@ -613,7 +601,7 @@ bytecodes: [ ...@@ -613,7 +601,7 @@ bytecodes: [
] ]
constant pool: [ constant pool: [
Smi [20], Smi [20],
Smi [108], Smi [101],
Smi [10], Smi [10],
Smi [7], Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
...@@ -626,8 +614,8 @@ constant pool: [ ...@@ -626,8 +614,8 @@ constant pool: [
Smi [9], Smi [9],
] ]
handlers: [ handlers: [
[61, 138, 144], [54, 131, 137],
[157, 176, 178], [150, 169, 171],
] ]
--- ---
...@@ -639,7 +627,7 @@ snippet: " ...@@ -639,7 +627,7 @@ snippet: "
" "
frame size: 16 frame size: 16
parameter count: 2 parameter count: 2
bytecode array length: 170 bytecode array length: 163
bytecodes: [ bytecodes: [
B(Mov), R(closure), R(5), B(Mov), R(closure), R(5),
B(Mov), R(this), R(6), B(Mov), R(this), R(6),
...@@ -647,8 +635,6 @@ bytecodes: [ ...@@ -647,8 +635,6 @@ bytecodes: [
B(Star0), B(Star0),
B(Mov), R(context), R(5), B(Mov), R(context), R(5),
/* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2), /* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star7), B(Star7),
B(GetNamedProperty), R(7), U8(0), U8(4), B(GetNamedProperty), R(7), U8(0), U8(4),
B(Star6), B(Star6),
...@@ -732,9 +718,9 @@ constant pool: [ ...@@ -732,9 +718,9 @@ constant pool: [
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
] ]
handlers: [ handlers: [
[14, 148, 148], [14, 141, 141],
[36, 78, 84], [29, 71, 77],
[97, 116, 118], [90, 109, 111],
] ]
--- ---
...@@ -746,7 +732,7 @@ snippet: " ...@@ -746,7 +732,7 @@ snippet: "
" "
frame size: 15 frame size: 15
parameter count: 2 parameter count: 2
bytecode array length: 204 bytecode array length: 197
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(1), B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
B(Mov), R(closure), R(4), B(Mov), R(closure), R(4),
...@@ -755,8 +741,6 @@ bytecodes: [ ...@@ -755,8 +741,6 @@ bytecodes: [
B(Star0), B(Star0),
B(Mov), R(context), R(4), B(Mov), R(context), R(4),
/* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2), /* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star6), B(Star6),
B(GetNamedProperty), R(6), U8(1), U8(4), B(GetNamedProperty), R(6), U8(1), U8(4),
B(Star5), B(Star5),
...@@ -845,7 +829,7 @@ bytecodes: [ ...@@ -845,7 +829,7 @@ bytecodes: [
B(Return), B(Return),
] ]
constant pool: [ constant pool: [
Smi [88], Smi [81],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
...@@ -853,8 +837,8 @@ constant pool: [ ...@@ -853,8 +837,8 @@ constant pool: [
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
] ]
handlers: [ handlers: [
[18, 182, 182], [18, 175, 175],
[40, 112, 118], [33, 105, 111],
[131, 150, 152], [124, 143, 145],
] ]
...@@ -98,7 +98,7 @@ snippet: " ...@@ -98,7 +98,7 @@ snippet: "
" "
frame size: 14 frame size: 14
parameter count: 1 parameter count: 1
bytecode array length: 211 bytecode array length: 204
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(4), B(Mov), R(closure), R(4),
...@@ -117,8 +117,6 @@ bytecodes: [ ...@@ -117,8 +117,6 @@ bytecodes: [
/* 30 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37), /* 30 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37),
B(Star6), B(Star6),
B(GetIterator), R(6), U8(1), U8(3), B(GetIterator), R(6), U8(1), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star5), B(Star5),
B(GetNamedProperty), R(5), U8(5), U8(5), B(GetNamedProperty), R(5), U8(5), U8(5),
B(Star4), B(Star4),
...@@ -197,7 +195,7 @@ bytecodes: [ ...@@ -197,7 +195,7 @@ bytecodes: [
] ]
constant pool: [ constant pool: [
Smi [20], Smi [20],
Smi [113], Smi [106],
Smi [10], Smi [10],
Smi [7], Smi [7],
ARRAY_BOILERPLATE_DESCRIPTION_TYPE, ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
...@@ -211,8 +209,8 @@ constant pool: [ ...@@ -211,8 +209,8 @@ constant pool: [
Smi [9], Smi [9],
] ]
handlers: [ handlers: [
[66, 143, 149], [59, 136, 142],
[162, 181, 183], [155, 174, 176],
] ]
--- ---
...@@ -223,7 +221,7 @@ snippet: " ...@@ -223,7 +221,7 @@ snippet: "
" "
frame size: 7 frame size: 7
parameter count: 1 parameter count: 1
bytecode array length: 189 bytecode array length: 182
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
...@@ -244,8 +242,6 @@ bytecodes: [ ...@@ -244,8 +242,6 @@ bytecodes: [
/* 50 E> */ B(CallUndefinedReceiver0), R(5), U8(2), /* 50 E> */ B(CallUndefinedReceiver0), R(5), U8(2),
B(Star6), B(Star6),
B(GetIterator), R(6), U8(4), U8(6), B(GetIterator), R(6), U8(4), U8(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star3), B(Star3),
B(GetNamedProperty), R(3), U8(5), U8(8), B(GetNamedProperty), R(3), U8(5), U8(8),
B(Star5), B(Star5),
...@@ -302,7 +298,7 @@ bytecodes: [ ...@@ -302,7 +298,7 @@ bytecodes: [
] ]
constant pool: [ constant pool: [
Smi [20], Smi [20],
Smi [159], Smi [152],
Smi [10], Smi [10],
Smi [7], Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"],
......
...@@ -90,7 +90,7 @@ snippet: " ...@@ -90,7 +90,7 @@ snippet: "
" "
frame size: 7 frame size: 7
parameter count: 1 parameter count: 1
bytecode array length: 111 bytecode array length: 104
bytecodes: [ bytecodes: [
B(CreateBlockContext), U8(0), B(CreateBlockContext), U8(0),
B(PushContext), R(1), B(PushContext), R(1),
...@@ -112,12 +112,10 @@ bytecodes: [ ...@@ -112,12 +112,10 @@ bytecodes: [
/* 101 S> */ B(CreateArrayLiteral), U8(4), U8(1), U8(37), /* 101 S> */ B(CreateArrayLiteral), U8(4), U8(1), U8(37),
B(Star6), B(Star6),
/* 101 E> */ B(GetIterator), R(6), U8(2), U8(4), /* 101 E> */ B(GetIterator), R(6), U8(2), U8(4),
B(Mov), R(4), R(1),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star5), B(Star5),
B(GetNamedProperty), R(5), U8(5), U8(6), B(GetNamedProperty), R(5), U8(5), U8(6),
B(Star4), B(Star4),
B(Mov), R(0), R(1),
B(CallProperty0), R(4), R(5), U8(15), B(CallProperty0), R(4), R(5), U8(15),
B(Star6), B(Star6),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
......
...@@ -93,7 +93,7 @@ snippet: " ...@@ -93,7 +93,7 @@ snippet: "
" "
frame size: 11 frame size: 11
parameter count: 1 parameter count: 1
bytecode array length: 104 bytecode array length: 97
bytecodes: [ bytecodes: [
/* 128 E> */ B(CreateRestParameter), /* 128 E> */ B(CreateRestParameter),
B(Star3), B(Star3),
...@@ -106,12 +106,10 @@ bytecodes: [ ...@@ -106,12 +106,10 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
/* 152 S> */ B(Star6), /* 152 S> */ B(Star6),
/* 152 E> */ B(GetIterator), R(3), U8(1), U8(3), /* 152 E> */ B(GetIterator), R(3), U8(1), U8(3),
B(Mov), R(1), R(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star9), B(Star9),
B(GetNamedProperty), R(9), U8(1), U8(5), B(GetNamedProperty), R(9), U8(1), U8(5),
B(Star8), B(Star8),
B(Mov), R(1), R(4),
B(CallProperty0), R(8), R(9), U8(14), B(CallProperty0), R(8), R(9), U8(14),
B(Star10), B(Star10),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
......
// Copyright 2022 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.
// The GetIterator bytecode is used to implement a part of the iterator
// protocol (https://tc39.es/ecma262/#sec-getiterator). Here, the
// bytecode performs multiple operations including some that have side-effects
// and may deoptimize eagerly or lazily.
// This test ensures the call @@iterator lazy deoptimization is handled correctly.
// Flags: --allow-natives-syntax --no-always-opt
let getIteratorCount = 0;
let iteratorCount = 0;
let iteratorAfterEagerDeoptCount = 0;
let triggerLazyDeopt = false;
function foo(obj) {
// The following for-of loop uses the iterator protocol to iterate
// over the 'obj'.
// The GetIterator bytecode involves 3 steps:
// 1. method = GetMethod(obj, @@iterator)
// 2. iterator = Call(method, obj).
// 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid.
for (var x of obj) {
}
}
// The lazy deoptimization is triggerred by setting the
// 'triggerLazyDeopt' to true. And the lazy deopt should
// goto continuation to check the call result is JSReceiver.
var iterator =
function () {
if (triggerLazyDeopt) {
iteratorAfterEagerDeoptCount++;
%DeoptimizeFunction(foo);
// SymbolIteratorInvalid should be throwed.
return 1;
}
iteratorCount++;
return {
next: function () {
return { done: true };
}
}
}
let y = {
get [Symbol.iterator]() {
getIteratorCount++;
return iterator;
}
};
%PrepareFunctionForOptimization(foo);
foo(y);
foo(y);
%OptimizeFunctionOnNextCall(foo);
triggerLazyDeopt = true;
assertThrows(() => {
foo(y)
}, TypeError, "Result of the Symbol.iterator method is not an object")
assertUnoptimized(foo);
assertEquals(getIteratorCount, 3);
assertEquals(iteratorCount, 2);
assertEquals(iteratorAfterEagerDeoptCount, 1);
...@@ -17,9 +17,10 @@ var iteratorAfterEagerDeoptCount = 0; ...@@ -17,9 +17,10 @@ var iteratorAfterEagerDeoptCount = 0;
function foo(obj) { function foo(obj) {
// The following for-of loop uses the iterator protocol to iterate // The following for-of loop uses the iterator protocol to iterate
// over the 'obj'. // over the 'obj'.
// The GetIterator bytecode invovlves 2 steps: // The GetIterator bytecode involves 3 steps:
// 1. method = GetMethod(obj, @@iterator) // 1. method = GetMethod(obj, @@iterator)
// 2. iterator = Call(method, obj). // 2. iterator = Call(method, obj).
// 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid.
for(var x of obj){} for(var x of obj){}
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// protocol (https://tc39.es/ecma262/#sec-getiterator). Here, the // protocol (https://tc39.es/ecma262/#sec-getiterator). Here, the
// bytecode performs multiple operations including some that have side-effects // bytecode performs multiple operations including some that have side-effects
// and may deoptimize eagerly or lazily. // and may deoptimize eagerly or lazily.
// This test ensures the lazy deoptimization is handled correctly. // This test ensures the get @@iterator lazy deoptimization is handled correctly.
// Flags: --allow-natives-syntax --no-always-opt // Flags: --allow-natives-syntax --no-always-opt
...@@ -18,9 +18,10 @@ var getIteratorCount = 0; ...@@ -18,9 +18,10 @@ var getIteratorCount = 0;
function foo(obj) { function foo(obj) {
// The following for-of loop uses the iterator protocol to iterate // The following for-of loop uses the iterator protocol to iterate
// over the 'obj'. // over the 'obj'.
// The GetIterator bytecode invovlves 2 steps: // The GetIterator bytecode involves 3 steps:
// 1. method = GetMethod(obj, @@iterator) // 1. method = GetMethod(obj, @@iterator)
// 2. iterator = Call(method, obj). // 2. iterator = Call(method, obj).
// 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid.
for(var x of obj){} for(var x of obj){}
} }
......
// Copyright 2022 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.
// The GetIterator bytecode is used to implement a part of the iterator
// protocol (https://tc39.es/ecma262/#sec-getiterator).
// Here, calling @@iterator property returns invalid JS receiver.
// This test ensures that the optimized version of the GetIterator bytecode
// correctly handle the SymbolIteratorInvalid exception without deoptimizing.
// Flags: --allow-natives-syntax --opt
var iteratorCount = 0;
var exceptionCount = 0;
function foo(obj) {
// The following for-of loop uses the iterator protocol to iterate
// over the 'obj'.
// The GetIterator bytecode involves 3 steps:
// 1. method = GetMethod(obj, @@iterator)
// 2. iterator = Call(method, obj)
// 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid.
try{
for(let a of obj){
assertUnreachable();
}
} catch(e){
exceptionCount++;
}
}
// This iterator retuns '1' which is not a valid JSReceiver
var iterator = function() {
iteratorCount++;
return 1;
}
let y = {
get [Symbol.iterator]() {
return iterator;
}
};
%PrepareFunctionForOptimization(foo);
foo(y);
foo(y);
%OptimizeFunctionOnNextCall(foo);
foo(y);
assertOptimized(foo);
assertEquals(iteratorCount, 3);
assertEquals(exceptionCount, 3);
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