Index: src/builtins/builtins-array.cc |
diff --git a/src/builtins/builtins-array.cc b/src/builtins/builtins-array.cc |
index 8a5232d6e2c6a399f53a1517fffdfbe31a50a2c0..0a3ffa575e9ba9c1bf9d776835de84ddca0431d3 100644 |
--- a/src/builtins/builtins-array.cc |
+++ b/src/builtins/builtins-array.cc |
@@ -2301,6 +2301,8 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( |
assembler->Bind(&if_isgeneric); |
{ |
+ Label if_wasfastarray(assembler); |
+ |
Node* length = nullptr; |
{ |
Variable var_length(assembler, MachineRepresentation::kTagged); |
@@ -2314,7 +2316,35 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( |
{ |
var_length.Bind( |
assembler->LoadObjectField(array, JSArray::kLengthOffset)); |
- assembler->Goto(&done); |
+ |
+ // Invalidate protector cell if needed |
+ assembler->Branch( |
+ assembler->WordNotEqual(orig_map, assembler->UndefinedConstant()), |
+ &if_wasfastarray, &done); |
+ |
+ assembler->Bind(&if_wasfastarray); |
+ { |
+ Label if_invalid(assembler, Label::kDeferred); |
+ // A fast array iterator transitioned to a slow iterator during |
+ // iteration. Invalidate fast_array_iteration_prtoector cell to |
+ // prevent potential deopt loops. |
+ assembler->StoreObjectFieldNoWriteBarrier( |
+ iterator, JSArrayIterator::kIteratedObjectMapOffset, |
+ assembler->UndefinedConstant()); |
+ assembler->GotoIf( |
+ assembler->Uint32LessThanOrEqual( |
+ instance_type, assembler->Int32Constant( |
+ JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), |
+ &done); |
+ |
+ Node* invalid = assembler->SmiConstant( |
+ Smi::FromInt(Isolate::kArrayProtectorInvalid)); |
+ Node* cell = assembler->LoadRoot( |
+ Heap::kFastArrayIterationProtectorRootIndex); |
+ assembler->StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, |
+ invalid); |
+ assembler->Goto(&done); |
+ } |
} |
assembler->Bind(&if_isnotarray); |
@@ -2377,6 +2407,8 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( |
assembler->Bind(&if_isdetached); |
{ |
+ // TODO(caitp): If IsDetached(buffer) is true, throw a TypeError, per |
+ // https://github.com/tc39/ecma262/issues/713 |
var_length.Bind(assembler->SmiConstant(Smi::kZero)); |
assembler->Goto(&done); |
} |