Commit 4671cb56 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

Revert "Extend GetIterator bytecode to perform JSReceiver check on object[Symbol.iterator]()"

This reverts commit 91e3243d.

Reason for revert: This deopts to the wrong point.

Original change's description:
> Extend GetIterator bytecode to perform JSReceiver check on object[Symbol.iterator]()
> 
> Current GetIterator bytecode loads and calls @@iterator property on a
> given object. This change extends the bytecode functionality to check
> whether the value returned after calling @@iterator property is a valid
> JSReceiver. The bytecode throws SymbolIteratorInvalid exception if the
> returned value is not a valid JSReceiver. This change absorbs the
> functionality of additional two bytecodes - JumpIfJSReceiver and
> CallRuntime, that are part of the iterator protocol in the GetIterator
> bytecode.
> 
> Bug: v8:9489
> Change-Id: I9e84cfe85eeb9a1b8a97ca0595375ac26ba1bbfd
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1792905
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Commit-Queue: Swapnil Gaikwad <swapnilgaikwad@google.com>
> Cr-Commit-Position: refs/heads/master@{#63704}

TBR=rmcilroy@chromium.org,leszeks@chromium.org,tebbi@chromium.org,swapnilgaikwad@google.com

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: v8:9489
Change-Id: I9324b5b01ead29912ad793a1e7b4d009643d7901
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1960288Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65541}
parent 16cfeda9
......@@ -460,8 +460,6 @@ extern transitioning runtime ThrowTypeErrorIfStrict(implicit context: Context)(
Smi, Object, Object): void;
extern transitioning runtime ThrowCalledNonCallable(implicit context: Context)(
JSAny): never;
extern transitioning runtime ThrowSymbolIteratorInvalid(
implicit context: Context)(): never;
extern transitioning macro ThrowIfNotJSReceiver(implicit context: Context)(
JSAny, constexpr MessageTemplate, constexpr string): void;
......
......@@ -70,14 +70,6 @@ namespace iterator {
CollectCallFeedback(iteratorMethod, context, feedback, callSlotUnTagged);
const iteratorCallable: Callable = Cast<Callable>(iteratorMethod)
otherwise ThrowCalledNonCallable(iteratorMethod);
const iterator: JSAny = Call(context, iteratorCallable, receiver);
typeswitch (iterator) {
case (JSReceiver): {
return iterator;
}
case (JSPrimitive): {
ThrowSymbolIteratorInvalid();
}
}
return Call(context, iteratorCallable, receiver);
}
}
......@@ -1364,35 +1364,6 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
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);
if (has_exception_node) {
// If there exists an IfException node for the current {node}, we need
// exception handling for all the desugared nodes. Create a combination
// of Merge+Phi+EffectPhi nodes that consumes the exception paths from
// from all the desugared nodes including the original exception node.
// Usages of the original exception node are then rewired to the newly
// created combination of Merge+Phi+EffectPhi. Here, use dead_node as a
// placeholder for the original exception node until its uses are rewired.
Node* dead_node = jsgraph()->Dead();
if_exception_merge = graph()->NewNode(common()->Merge(1), dead_node);
if_exception_effect_phi =
graph()->NewNode(common()->EffectPhi(1), dead_node, if_exception_merge);
if_exception_phi =
graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 1),
dead_node, if_exception_merge);
ReplaceWithValue(iterator_exception_node, if_exception_phi,
if_exception_effect_phi, if_exception_merge);
if_exception_merge->ReplaceInput(0, iterator_exception_node);
if_exception_effect_phi->ReplaceInput(0, iterator_exception_node);
if_exception_phi->ReplaceInput(0, iterator_exception_node);
}
// Load iterator property operator
Handle<Name> iterator_symbol = factory()->iterator_symbol();
const Operator* load_op =
......@@ -1412,10 +1383,31 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) {
control = load_property;
// Handle exception path for the load named property
if (has_exception_node) {
control =
AppendExceptionHandling(effect, control, if_exception_merge,
if_exception_phi, if_exception_effect_phi);
Node* iterator_exception_node = nullptr;
if (NodeProperties::IsExceptionalCall(node, &iterator_exception_node)) {
// 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);
Node* if_success = graph()->NewNode(common()->IfSuccess(), control);
// Use dead_node as a placeholder for the original exception node until
// its uses are rewired to the nodes merging the exceptions
Node* dead_node = jsgraph()->Dead();
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
......@@ -1439,46 +1431,8 @@ Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) {
CallFeedbackRelation::kRelated);
Node* call_property = graph()->NewNode(call_op, load_property, receiver,
context, frame_state, effect, control);
effect = call_property;
control = call_property;
if (has_exception_node) {
control =
AppendExceptionHandling(effect, control, if_exception_merge,
if_exception_phi, if_exception_effect_phi);
}
// Check if the call property returns a valid JSReceiver else throw an invalid
// iterator runtime exception
Node* is_receiver =
graph()->NewNode(simplified()->ObjectIsReceiver(), call_property);
Node* branch_node = graph()->NewNode(
common()->Branch(BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck),
is_receiver, control);
{
// Create a version of effect and control for the false path of the branch
Node* effect = call_property;
Node* control = call_property;
Node* if_not_receiver = graph()->NewNode(common()->IfFalse(), branch_node);
control = if_not_receiver;
const Operator* call_runtime_op =
javascript()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid, 0);
Node* call_runtime = graph()->NewNode(call_runtime_op, context, frame_state,
effect, control);
control = call_runtime;
effect = call_runtime;
if (has_exception_node) {
control =
AppendExceptionHandling(effect, control, if_exception_merge,
if_exception_phi, if_exception_effect_phi);
}
Node* throw_node =
graph()->NewNode(common()->Throw(), call_runtime, control);
NodeProperties::MergeControlToEnd(graph(), common(), throw_node);
}
Node* if_receiver = graph()->NewNode(common()->IfTrue(), branch_node);
ReplaceWithValue(node, call_property, effect, if_receiver);
return Replace(if_receiver);
return Replace(call_property);
}
Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) {
......@@ -3239,22 +3193,6 @@ Node* JSNativeContextSpecialization::BuildCheckEqualsName(NameRef const& name,
control);
}
Node* JSNativeContextSpecialization::AppendExceptionHandling(
Node* effect, Node* control, Node* merge, Node* phi, Node* effect_phi) {
DCHECK_EQ(effect, control);
int input_count = merge->InputCount() + 1;
Node* if_exception =
graph()->NewNode(common()->IfException(), effect, control);
merge->InsertInput(graph()->zone(), 0, if_exception);
NodeProperties::ChangeOp(merge, common()->Merge(input_count));
phi->InsertInput(graph()->zone(), 0, if_exception);
NodeProperties::ChangeOp(
phi, common()->Phi(MachineRepresentation::kTagged, input_count));
effect_phi->InsertInput(graph()->zone(), 0, if_exception);
NodeProperties::ChangeOp(effect_phi, common()->EffectPhi(input_count));
return graph()->NewNode(common()->IfSuccess(), control);
}
bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
ZoneVector<Handle<Map>> const& receiver_maps) {
// Check if all {receiver_maps} have one of the initial Array.prototype
......
......@@ -198,12 +198,6 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
Node* BuildCheckEqualsName(NameRef const& name, Node* value, Node* effect,
Node* control);
// Attach a pair of success and exception paths on a given control path.
// The exception is joined to the Merge+Phi+EffectPhi nodes while the success
// path is returned.
Node* AppendExceptionHandling(Node* effect, Node* control, Node* merge,
Node* phi, Node* effect_phi);
// Checks if we can turn the hole into undefined when loading an element
// from an object with one of the {receiver_maps}; sets up appropriate
// code dependencies and might use the array protector cell.
......
......@@ -5517,11 +5517,16 @@ void BytecodeGenerator::BuildGetIterator(IteratorType hint) {
feedback_index(feedback_spec()->AddCallICSlot());
// Let method be GetMethod(obj, @@iterator) and
// iterator be Call(method, obj). If Type(iterator) is not Object,
// throw a SymbolIteratorInvalid exception.
// iterator be Call(method, obj).
builder()->StoreAccumulatorInRegister(obj).GetIterator(
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);
}
}
......
......@@ -3215,8 +3215,10 @@ IGNITION_HANDLER(ForInStep, InterpreterAssembler) {
// GetIterator <object>
//
// Retrieves the object[Symbol.iterator] method, calls it and stores
// the result in the accumulator. If the result is not a JSReceiver, throws
// SymbolIteratorInvalid runtime exception.
// the result in the accumulator
// TODO(swapnilgaikwad): Extend the functionality of the bytecode to
// check if the result is a JSReceiver else throw SymbolIteratorInvalid
// runtime exception
IGNITION_HANDLER(GetIterator, InterpreterAssembler) {
TNode<Object> receiver = LoadRegisterAtOperandIndex(0);
TNode<Context> context = GetContext();
......
......@@ -143,7 +143,7 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 68
bytecode array length: 75
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
......@@ -153,6 +153,8 @@ bytecodes: [
B(LdaConstant), U8(2),
/* 67 S> */ B(Star), R(1),
B(GetIterator), R(0), U8(2), U8(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
B(LdaNamedProperty), R(4), U8(3), U8(6),
B(Star), R(3),
......
......@@ -214,7 +214,7 @@ snippet: "
"
frame size: 19
parameter count: 1
bytecode array length: 357
bytecode array length: 364
bytecodes: [
/* 17 E> */ B(StackCheck),
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
......@@ -239,6 +239,8 @@ bytecodes: [
/* 36 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37),
B(Star), R(10),
B(GetIterator), R(10), U8(1), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(9),
B(LdaNamedProperty), R(9), U8(5), U8(5),
B(Star), R(8),
......@@ -372,7 +374,7 @@ bytecodes: [
]
constant pool: [
Smi [29],
Smi [135],
Smi [142],
Smi [16],
Smi [7],
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
......@@ -386,16 +388,16 @@ constant pool: [
Smi [6],
Smi [9],
SCOPE_INFO_TYPE,
Smi [262],
Smi [269],
Smi [6],
Smi [9],
Smi [23],
]
handlers: [
[20, 303, 311],
[23, 267, 269],
[80, 167, 175],
[199, 232, 234],
[20, 310, 318],
[23, 274, 276],
[87, 174, 182],
[206, 239, 241],
]
---
......
......@@ -67,7 +67,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 94
bytecode array length: 101
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaGlobal), U8(0), U8(0),
......@@ -81,9 +81,11 @@ bytecodes: [
/* 49 S> */ B(CreateArrayLiteral), U8(4), U8(5), U8(37),
B(Star), R(7),
B(GetIterator), R(7), U8(6), U8(8),
B(Mov), R(0), R(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(6),
B(LdaNamedProperty), R(6), U8(5), U8(10),
B(Mov), R(0), R(2),
B(Star), R(5),
B(CallProperty0), R(5), R(6), U8(19),
B(Star), R(7),
......
......@@ -12,17 +12,19 @@ snippet: "
"
frame size: 14
parameter count: 1
bytecode array length: 160
bytecode array length: 167
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(1),
/* 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(Star), R(4),
B(LdaNamedProperty), R(4), U8(1), U8(5),
B(Star), R(3),
B(LdaFalse),
B(Mov), R(1), R(2),
B(Star), R(5),
B(Mov), R(context), R(8),
/* 57 S> */ B(Ldar), R(5),
......@@ -97,8 +99,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[28, 70, 78],
[102, 135, 137],
[35, 77, 85],
[109, 142, 144],
]
---
......@@ -108,17 +110,19 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 246
bytecode array length: 253
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(2),
/* 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(Star), R(5),
B(LdaNamedProperty), R(5), U8(1), U8(5),
B(Star), R(4),
B(LdaFalse),
B(Mov), R(2), R(3),
B(Star), R(6),
B(Mov), R(context), R(9),
B(Ldar), R(6),
......@@ -227,8 +231,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[28, 156, 164],
[188, 221, 223],
[35, 163, 171],
[195, 228, 230],
]
---
......@@ -238,7 +242,7 @@ snippet: "
"
frame size: 16
parameter count: 1
bytecode array length: 211
bytecode array length: 218
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 40 S> */ B(CreateEmptyObjectLiteral),
......@@ -246,11 +250,13 @@ bytecodes: [
/* 51 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(2),
/* 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(Star), R(5),
B(LdaNamedProperty), R(5), U8(1), U8(5),
B(Star), R(4),
B(LdaFalse),
B(Mov), R(2), R(3),
B(Star), R(6),
B(Mov), R(context), R(9),
/* 59 S> */ B(Ldar), R(6),
......@@ -345,8 +351,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[31, 121, 129],
[153, 186, 188],
[38, 128, 136],
[160, 193, 195],
]
---
......
......@@ -532,7 +532,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 246
bytecode array length: 253
bytecodes: [
/* 16 E> */ B(StackCheck),
B(Mov), R(closure), R(2),
......@@ -545,6 +545,8 @@ bytecodes: [
/* 68 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(5),
B(GetIterator), R(5), U8(2), U8(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
B(LdaNamedProperty), R(4), U8(2), U8(6),
B(Star), R(3),
......@@ -656,8 +658,8 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[16, 218, 218],
[46, 99, 107],
[131, 164, 166],
[16, 225, 225],
[53, 106, 114],
[138, 171, 173],
]
......@@ -11,12 +11,14 @@ snippet: "
"
frame size: 13
parameter count: 1
bytecode array length: 158
bytecode array length: 165
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(4),
B(GetIterator), R(4), U8(1), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(3),
B(LdaNamedProperty), R(3), U8(1), U8(5),
B(Star), R(2),
......@@ -94,8 +96,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[25, 68, 76],
[100, 133, 135],
[32, 75, 83],
[107, 140, 142],
]
---
......@@ -105,12 +107,14 @@ snippet: "
"
frame size: 14
parameter count: 1
bytecode array length: 166
bytecode array length: 173
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 68 S> */ B(GetIterator), R(0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
B(LdaNamedProperty), R(4), U8(1), U8(4),
B(Star), R(3),
......@@ -194,8 +198,8 @@ constant pool: [
Smi [9],
]
handlers: [
[23, 70, 78],
[102, 135, 137],
[30, 77, 85],
[109, 142, 144],
]
---
......@@ -207,12 +211,14 @@ snippet: "
"
frame size: 13
parameter count: 1
bytecode array length: 174
bytecode array length: 181
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(4),
B(GetIterator), R(4), U8(1), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(3),
B(LdaNamedProperty), R(3), U8(1), U8(5),
B(Star), R(2),
......@@ -297,8 +303,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[25, 84, 92],
[116, 149, 151],
[32, 91, 99],
[123, 156, 158],
]
---
......@@ -308,7 +314,7 @@ snippet: "
"
frame size: 13
parameter count: 1
bytecode array length: 180
bytecode array length: 187
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
......@@ -316,6 +322,8 @@ bytecodes: [
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(3),
B(GetIterator), R(3), U8(2), U8(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(2),
B(LdaNamedProperty), R(2), U8(2), U8(6),
B(Star), R(1),
......@@ -403,7 +411,7 @@ constant pool: [
Smi [9],
]
handlers: [
[31, 84, 92],
[116, 149, 151],
[38, 91, 99],
[123, 156, 158],
]
......@@ -15,10 +15,12 @@ snippet: "
"
frame size: 15
parameter count: 2
bytecode array length: 155
bytecode array length: 162
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
B(LdaNamedProperty), R(5), U8(0), U8(4),
B(Star), R(4),
......@@ -96,8 +98,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[19, 65, 73],
[97, 130, 132],
[26, 72, 80],
[104, 137, 139],
]
---
......@@ -109,7 +111,7 @@ snippet: "
"
frame size: 20
parameter count: 2
bytecode array length: 239
bytecode array length: 246
bytecodes: [
/* 10 E> */ B(StackCheck),
B(CreateFunctionContext), U8(0), U8(5),
......@@ -129,6 +131,8 @@ bytecodes: [
/* 34 S> */ B(LdaContextSlot), R(3), U8(3), U8(0),
B(Star), R(6),
B(GetIterator), R(6), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
B(LdaNamedProperty), R(5), U8(2), U8(4),
B(Star), R(4),
......@@ -233,8 +237,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[52, 147, 155],
[179, 212, 214],
[59, 154, 162],
[186, 219, 221],
]
---
......@@ -246,10 +250,12 @@ snippet: "
"
frame size: 14
parameter count: 2
bytecode array length: 172
bytecode array length: 179
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(3),
B(LdaNamedProperty), R(3), U8(0), U8(4),
B(Star), R(2),
......@@ -337,8 +343,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[19, 82, 90],
[114, 147, 149],
[26, 89, 97],
[121, 154, 156],
]
---
......@@ -350,10 +356,12 @@ snippet: "
"
frame size: 17
parameter count: 2
bytecode array length: 166
bytecode array length: 173
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 41 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(7),
B(LdaNamedProperty), R(7), U8(0), U8(4),
B(Star), R(6),
......@@ -437,8 +445,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[19, 76, 84],
[108, 141, 143],
[26, 83, 91],
[115, 148, 150],
]
---
......@@ -450,7 +458,7 @@ snippet: "
"
frame size: 16
parameter count: 2
bytecode array length: 196
bytecode array length: 203
bytecodes: [
/* 11 E> */ B(StackCheck),
B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
......@@ -468,6 +476,8 @@ bytecodes: [
B(Ldar), R(5),
/* 55 S> */ B(Return),
/* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(6),
B(LdaNamedProperty), R(6), U8(3), U8(4),
B(Star), R(5),
......@@ -548,8 +558,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[60, 106, 114],
[138, 171, 173],
[67, 113, 121],
[145, 178, 180],
]
---
......@@ -561,7 +571,7 @@ snippet: "
"
frame size: 15
parameter count: 2
bytecode array length: 240
bytecode array length: 247
bytecodes: [
/* 11 E> */ B(StackCheck),
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
......@@ -579,6 +589,8 @@ bytecodes: [
B(Ldar), R(4),
/* 49 S> */ B(Return),
/* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
B(LdaNamedProperty), R(5), U8(4), U8(4),
B(Star), R(4),
......@@ -666,7 +678,7 @@ bytecodes: [
]
constant pool: [
Smi [21],
Smi [112],
Smi [119],
Smi [10],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
......@@ -680,8 +692,8 @@ constant pool: [
Smi [9],
]
handlers: [
[60, 144, 152],
[176, 209, 211],
[67, 151, 159],
[183, 216, 218],
]
---
......@@ -693,7 +705,7 @@ snippet: "
"
frame size: 17
parameter count: 2
bytecode array length: 210
bytecode array length: 217
bytecodes: [
/* 16 E> */ B(StackCheck),
B(Mov), R(closure), R(5),
......@@ -702,6 +714,8 @@ bytecodes: [
B(Star), R(0),
B(Mov), R(context), R(5),
/* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(7),
B(LdaNamedProperty), R(7), U8(0), U8(4),
B(Star), R(6),
......@@ -799,9 +813,9 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[16, 182, 182],
[34, 80, 88],
[112, 145, 147],
[16, 189, 189],
[41, 87, 95],
[119, 152, 154],
]
---
......@@ -813,7 +827,7 @@ snippet: "
"
frame size: 16
parameter count: 2
bytecode array length: 246
bytecode array length: 253
bytecodes: [
/* 16 E> */ B(StackCheck),
B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
......@@ -823,6 +837,8 @@ bytecodes: [
B(Star), R(0),
B(Mov), R(context), R(4),
/* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(6),
B(LdaNamedProperty), R(6), U8(1), U8(4),
B(Star), R(5),
......@@ -924,7 +940,7 @@ bytecodes: [
/* 54 S> */ B(Return),
]
constant pool: [
Smi [90],
Smi [97],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
......@@ -933,8 +949,8 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[20, 218, 218],
[38, 116, 124],
[148, 181, 183],
[20, 225, 225],
[45, 123, 131],
[155, 188, 190],
]
......@@ -100,7 +100,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 246
bytecode array length: 253
bytecodes: [
/* 11 E> */ B(StackCheck),
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
......@@ -120,6 +120,8 @@ bytecodes: [
/* 30 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37),
B(Star), R(6),
B(GetIterator), R(6), U8(1), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
B(LdaNamedProperty), R(5), U8(5), U8(5),
B(Star), R(4),
......@@ -207,7 +209,7 @@ bytecodes: [
]
constant pool: [
Smi [21],
Smi [118],
Smi [125],
Smi [10],
Smi [7],
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
......@@ -222,8 +224,8 @@ constant pool: [
Smi [9],
]
handlers: [
[66, 150, 158],
[182, 215, 217],
[73, 157, 165],
[189, 222, 224],
]
---
......@@ -234,7 +236,7 @@ snippet: "
"
frame size: 7
parameter count: 1
bytecode array length: 198
bytecode array length: 205
bytecodes: [
/* 38 E> */ B(StackCheck),
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
......@@ -256,6 +258,8 @@ bytecodes: [
/* 50 E> */ B(CallUndefinedReceiver0), R(5), U8(2),
B(Star), R(6),
B(GetIterator), R(6), U8(4), U8(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(3),
B(LdaNamedProperty), R(3), U8(5), U8(8),
B(Star), R(5),
......@@ -312,7 +316,7 @@ bytecodes: [
]
constant pool: [
Smi [21],
Smi [165],
Smi [172],
Smi [10],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"],
......
......@@ -92,7 +92,7 @@ snippet: "
"
frame size: 7
parameter count: 1
bytecode array length: 115
bytecode array length: 122
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
......@@ -115,10 +115,12 @@ bytecodes: [
/* 101 S> */ B(CreateArrayLiteral), U8(5), U8(1), U8(37),
B(Star), R(6),
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(Star), R(5),
B(LdaNamedProperty), R(5), U8(6), U8(6),
B(Star), R(4),
B(Mov), R(0), R(1),
B(CallProperty0), R(4), R(5), U8(15),
B(Star), R(6),
B(JumpIfJSReceiver), U8(7),
......
......@@ -93,7 +93,7 @@ snippet: "
"
frame size: 11
parameter count: 1
bytecode array length: 112
bytecode array length: 119
bytecodes: [
/* 128 E> */ B(StackCheck),
B(CreateRestParameter),
......@@ -112,10 +112,12 @@ bytecodes: [
B(Inc), U8(3),
/* 152 S> */ B(Star), R(6),
B(GetIterator), R(3), U8(4), U8(6),
B(Mov), R(1), R(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(9),
B(LdaNamedProperty), R(9), U8(0), U8(8),
B(Star), R(8),
B(Mov), R(1), R(4),
B(CallProperty0), R(8), R(9), U8(14),
B(Star), R(10),
B(JumpIfJSReceiver), U8(7),
......
......@@ -17,10 +17,9 @@ var iteratorAfterEagerDeoptCount = 0;
function foo(obj) {
// The following for-of loop uses the iterator protocol to iterate
// over the 'obj'.
// The GetIterator bytecode invovlves 3 steps:
// The GetIterator bytecode invovlves 2 steps:
// 1. method = GetMethod(obj, @@iterator)
// 2. iterator = Call(method, obj)
// 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid.
// 2. iterator = Call(method, obj).
for(var x of obj){}
}
......
// Copyright 2019 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, call to the @@iterator property returns invalid JS receiver.
// This test ensures that the optimized version of the GetIterator bytecode
// incorporates exception handling mechanism 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 invovlves 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 '3' which is not a valid JSReceiver
var iterator = function() {
iteratorCount++;
return 3;
}
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);
......@@ -18,10 +18,9 @@ var getIteratorCount = 0;
function foo(obj) {
// The following for-of loop uses the iterator protocol to iterate
// over the 'obj'.
// The GetIterator bytecode invovlves 3 steps:
// The GetIterator bytecode invovlves 2 steps:
// 1. method = GetMethod(obj, @@iterator)
// 2. iterator = Call(method, obj)
// 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid.
// 2. iterator = Call(method, obj).
for(var x of obj){}
}
......
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