| Index: src/builtins/builtins-string.cc
 | 
| diff --git a/src/builtins/builtins-string.cc b/src/builtins/builtins-string.cc
 | 
| index 09ff31673fd65e77601e3aacc2e408cc71d01a8f..83738415fc4bb88f7b0058cb7a4a1305678cc941 100644
 | 
| --- a/src/builtins/builtins-string.cc
 | 
| +++ b/src/builtins/builtins-string.cc
 | 
| @@ -516,443 +516,58 @@
 | 
|    assembler->Return(result);
 | 
|  }
 | 
|  
 | 
| -void Builtins::Generate_StringPrototypeIterator(CodeStubAssembler* assembler) {
 | 
| -  typedef CodeStubAssembler::Label Label;
 | 
| -  typedef compiler::Node Node;
 | 
| -  typedef CodeStubAssembler::Variable Variable;
 | 
| -
 | 
| -  Variable var_string(assembler, MachineRepresentation::kTagged);
 | 
| -  Variable var_index(assembler, MachineRepresentation::kTagged);
 | 
| -
 | 
| -  Variable* loop_inputs[] = {&var_string, &var_index};
 | 
| -  Label loop(assembler, 2, loop_inputs);
 | 
| -  Label allocate_iterator(assembler);
 | 
| -
 | 
| -  Node* receiver = assembler->Parameter(0);
 | 
| -  Node* context = assembler->Parameter(3);
 | 
| -
 | 
| -  Node* string = assembler->ToThisString(context, receiver,
 | 
| -                                         "String.prototype[Symbol.iterator]");
 | 
| -  var_string.Bind(string);
 | 
| -  var_index.Bind(assembler->SmiConstant(Smi::FromInt(0)));
 | 
| -
 | 
| -  assembler->Goto(&loop);
 | 
| -  assembler->Bind(&loop);
 | 
| -  {
 | 
| -    // Load the instance type of the {string}.
 | 
| -    Node* string_instance_type = assembler->LoadInstanceType(string);
 | 
| -
 | 
| -    // Check if the {string} is a SeqString.
 | 
| -    Label if_stringisnotsequential(assembler);
 | 
| -    assembler->Branch(assembler->Word32Equal(
 | 
| -                          assembler->Word32And(string_instance_type,
 | 
| -                                               assembler->Int32Constant(
 | 
| -                                                   kStringRepresentationMask)),
 | 
| -                          assembler->Int32Constant(kSeqStringTag)),
 | 
| -                      &allocate_iterator, &if_stringisnotsequential);
 | 
| -
 | 
| -    assembler->Bind(&if_stringisnotsequential);
 | 
| -    {
 | 
| -      // Check if the {string} is a ConsString.
 | 
| -      Label if_stringiscons(assembler), if_stringisnotcons(assembler);
 | 
| -      assembler->Branch(
 | 
| -          assembler->Word32Equal(
 | 
| -              assembler->Word32And(
 | 
| -                  string_instance_type,
 | 
| -                  assembler->Int32Constant(kStringRepresentationMask)),
 | 
| -              assembler->Int32Constant(kConsStringTag)),
 | 
| -          &if_stringiscons, &if_stringisnotcons);
 | 
| -
 | 
| -      assembler->Bind(&if_stringiscons);
 | 
| -      {
 | 
| -        // Flatten cons-string and finish.
 | 
| -        var_string.Bind(assembler->CallRuntime(
 | 
| -            Runtime::kFlattenString, assembler->NoContextConstant(), string));
 | 
| -        assembler->Goto(&allocate_iterator);
 | 
| +BUILTIN(StringPrototypeIterator) {
 | 
| +  HandleScope scope(isolate);
 | 
| +  TO_THIS_STRING(object, "String.prototype[Symbol.iterator]");
 | 
| +
 | 
| +  Handle<String> string;
 | 
| +  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string,
 | 
| +                                     Object::ToString(isolate, object));
 | 
| +
 | 
| +  return *isolate->factory()->NewJSStringIterator(string);
 | 
| +}
 | 
| +
 | 
| +BUILTIN(StringIteratorPrototypeNext) {
 | 
| +  HandleScope scope(isolate);
 | 
| +
 | 
| +  if (!args.receiver()->IsJSStringIterator()) {
 | 
| +    Handle<String> reason = isolate->factory()->NewStringFromAsciiChecked(
 | 
| +        "String Iterator.prototype.next");
 | 
| +    THROW_NEW_ERROR_RETURN_FAILURE(
 | 
| +        isolate,
 | 
| +        NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, reason));
 | 
| +  }
 | 
| +  Handle<JSStringIterator> iterator =
 | 
| +      Handle<JSStringIterator>::cast(args.receiver());
 | 
| +  Handle<String> string(iterator->string());
 | 
| +
 | 
| +  int position = iterator->index();
 | 
| +  int length = string->length();
 | 
| +
 | 
| +  if (position < length) {
 | 
| +    uint16_t lead = string->Get(position);
 | 
| +    if (lead >= 0xD800 && lead <= 0xDBFF && position + 1 < length) {
 | 
| +      uint16_t trail = string->Get(position + 1);
 | 
| +      if (V8_LIKELY(trail >= 0xDC00 && trail <= 0xDFFF)) {
 | 
| +        // Return surrogate pair code units
 | 
| +        iterator->set_index(position + 2);
 | 
| +        Handle<String> value =
 | 
| +            isolate->factory()->NewSurrogatePairString(lead, trail);
 | 
| +        return *isolate->factory()->NewJSIteratorResult(value, false);
 | 
|        }
 | 
| -
 | 
| -      assembler->Bind(&if_stringisnotcons);
 | 
| -      {
 | 
| -        // Check if the {string} is an ExternalString.
 | 
| -        Label if_stringisnotexternal(assembler);
 | 
| -        assembler->Branch(
 | 
| -            assembler->Word32Equal(
 | 
| -                assembler->Word32And(
 | 
| -                    string_instance_type,
 | 
| -                    assembler->Int32Constant(kStringRepresentationMask)),
 | 
| -                assembler->Int32Constant(kExternalStringTag)),
 | 
| -            &allocate_iterator, &if_stringisnotexternal);
 | 
| -
 | 
| -        assembler->Bind(&if_stringisnotexternal);
 | 
| -        {
 | 
| -          // The {string} is a SlicedString, continue with its parent.
 | 
| -          Node* index = var_index.value();
 | 
| -          Node* string_offset =
 | 
| -              assembler->LoadObjectField(string, SlicedString::kOffsetOffset);
 | 
| -          Node* string_parent =
 | 
| -              assembler->LoadObjectField(string, SlicedString::kParentOffset);
 | 
| -          var_index.Bind(assembler->SmiAdd(index, string_offset));
 | 
| -          var_string.Bind(string_parent);
 | 
| -          assembler->Goto(&loop);
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  assembler->Bind(&allocate_iterator);
 | 
| -  {
 | 
| -    Node* native_context = assembler->LoadNativeContext(context);
 | 
| -    Node* map = assembler->LoadFixedArrayElement(
 | 
| -        native_context,
 | 
| -        assembler->IntPtrConstant(Context::STRING_ITERATOR_MAP_INDEX), 0,
 | 
| -        CodeStubAssembler::INTPTR_PARAMETERS);
 | 
| -    Node* iterator = assembler->Allocate(JSStringIterator::kSize);
 | 
| -    assembler->StoreMapNoWriteBarrier(iterator, map);
 | 
| -    assembler->StoreObjectFieldRoot(iterator, JSValue::kPropertiesOffset,
 | 
| -                                    Heap::kEmptyFixedArrayRootIndex);
 | 
| -    assembler->StoreObjectFieldRoot(iterator, JSObject::kElementsOffset,
 | 
| -                                    Heap::kEmptyFixedArrayRootIndex);
 | 
| -    assembler->StoreObjectFieldNoWriteBarrier(
 | 
| -        iterator, JSStringIterator::kStringOffset, var_string.value());
 | 
| -
 | 
| -    assembler->StoreObjectFieldNoWriteBarrier(
 | 
| -        iterator, JSStringIterator::kNextIndexOffset, var_index.value());
 | 
| -    assembler->Return(iterator);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -namespace {
 | 
| -
 | 
| -// Return the |word32| codepoint at {index}. Supports SeqStrings and
 | 
| -// ExternalStrings.
 | 
| -compiler::Node* LoadSurrogatePairInternal(CodeStubAssembler* assembler,
 | 
| -                                          compiler::Node* string,
 | 
| -                                          compiler::Node* length,
 | 
| -                                          compiler::Node* index,
 | 
| -                                          UnicodeEncoding encoding) {
 | 
| -  typedef CodeStubAssembler::Label Label;
 | 
| -  typedef compiler::Node Node;
 | 
| -  typedef CodeStubAssembler::Variable Variable;
 | 
| -  Label handle_surrogate_pair(assembler), return_result(assembler);
 | 
| -  Variable var_result(assembler, MachineRepresentation::kWord32);
 | 
| -  Variable var_trail(assembler, MachineRepresentation::kWord16);
 | 
| -  var_result.Bind(assembler->Int32Constant(0));
 | 
| -  var_trail.Bind(assembler->Int32Constant(0));
 | 
| -
 | 
| -  Node* string_instance_type = assembler->LoadInstanceType(string);
 | 
| -
 | 
| -  Label if_stringissequential(assembler), if_stringisexternal(assembler);
 | 
| -  assembler->Branch(assembler->Word32Equal(
 | 
| -                        assembler->Word32And(string_instance_type,
 | 
| -                                             assembler->Int32Constant(
 | 
| -                                                 kStringRepresentationMask)),
 | 
| -                        assembler->Int32Constant(kSeqStringTag)),
 | 
| -                    &if_stringissequential, &if_stringisexternal);
 | 
| -
 | 
| -  assembler->Bind(&if_stringissequential);
 | 
| -  {
 | 
| -    Label if_stringisonebyte(assembler), if_stringistwobyte(assembler);
 | 
| -    assembler->Branch(
 | 
| -        assembler->Word32Equal(
 | 
| -            assembler->Word32And(string_instance_type,
 | 
| -                                 assembler->Int32Constant(kStringEncodingMask)),
 | 
| -            assembler->Int32Constant(kOneByteStringTag)),
 | 
| -        &if_stringisonebyte, &if_stringistwobyte);
 | 
| -
 | 
| -    assembler->Bind(&if_stringisonebyte);
 | 
| -    {
 | 
| -      var_result.Bind(assembler->Load(
 | 
| -          MachineType::Uint8(), string,
 | 
| -          assembler->IntPtrAdd(
 | 
| -              index, assembler->IntPtrConstant(SeqOneByteString::kHeaderSize -
 | 
| -                                               kHeapObjectTag))));
 | 
| -      assembler->Goto(&return_result);
 | 
| -    }
 | 
| -
 | 
| -    assembler->Bind(&if_stringistwobyte);
 | 
| -    {
 | 
| -      Node* lead = assembler->Load(
 | 
| -          MachineType::Uint16(), string,
 | 
| -          assembler->IntPtrAdd(
 | 
| -              assembler->WordShl(index, assembler->IntPtrConstant(1)),
 | 
| -              assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
 | 
| -                                        kHeapObjectTag)));
 | 
| -      var_result.Bind(lead);
 | 
| -      Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1));
 | 
| -
 | 
| -      Label if_isdoublecodeunit(assembler);
 | 
| -      assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length),
 | 
| -                        &return_result);
 | 
| -      assembler->GotoIf(
 | 
| -          assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)),
 | 
| -          &return_result);
 | 
| -      assembler->Branch(
 | 
| -          assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)),
 | 
| -          &if_isdoublecodeunit, &return_result);
 | 
| -
 | 
| -      assembler->Bind(&if_isdoublecodeunit);
 | 
| -      {
 | 
| -        Node* trail = assembler->Load(
 | 
| -            MachineType::Uint16(), string,
 | 
| -            assembler->IntPtrAdd(
 | 
| -                assembler->WordShl(next_pos, assembler->IntPtrConstant(1)),
 | 
| -                assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
 | 
| -                                          kHeapObjectTag)));
 | 
| -        assembler->GotoIf(
 | 
| -            assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)),
 | 
| -            &return_result);
 | 
| -        assembler->GotoIf(assembler->Uint32GreaterThanOrEqual(
 | 
| -                              trail, assembler->Int32Constant(0xE000)),
 | 
| -                          &return_result);
 | 
| -
 | 
| -        var_trail.Bind(trail);
 | 
| -        assembler->Goto(&handle_surrogate_pair);
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  assembler->Bind(&if_stringisexternal);
 | 
| -  {
 | 
| -    assembler->Assert(assembler->Word32Equal(
 | 
| -        assembler->Word32And(
 | 
| -            string_instance_type,
 | 
| -            assembler->Int32Constant(kStringRepresentationMask)),
 | 
| -        assembler->Int32Constant(kExternalStringTag)));
 | 
| -    Label if_stringisshort(assembler), if_stringisnotshort(assembler);
 | 
| -
 | 
| -    assembler->Branch(assembler->Word32Equal(
 | 
| -                          assembler->Word32And(string_instance_type,
 | 
| -                                               assembler->Int32Constant(
 | 
| -                                                   kShortExternalStringMask)),
 | 
| -                          assembler->Int32Constant(0)),
 | 
| -                      &if_stringisshort, &if_stringisnotshort);
 | 
| -
 | 
| -    assembler->Bind(&if_stringisshort);
 | 
| -    {
 | 
| -      // Load the actual resource data from the {string}.
 | 
| -      Node* string_resource_data = assembler->LoadObjectField(
 | 
| -          string, ExternalString::kResourceDataOffset, MachineType::Pointer());
 | 
| -
 | 
| -      Label if_stringistwobyte(assembler), if_stringisonebyte(assembler);
 | 
| -      assembler->Branch(assembler->Word32Equal(
 | 
| -                            assembler->Word32And(
 | 
| -                                string_instance_type,
 | 
| -                                assembler->Int32Constant(kStringEncodingMask)),
 | 
| -                            assembler->Int32Constant(kTwoByteStringTag)),
 | 
| -                        &if_stringistwobyte, &if_stringisonebyte);
 | 
| -
 | 
| -      assembler->Bind(&if_stringisonebyte);
 | 
| -      {
 | 
| -        var_result.Bind(
 | 
| -            assembler->Load(MachineType::Uint8(), string_resource_data, index));
 | 
| -        assembler->Goto(&return_result);
 | 
| -      }
 | 
| -
 | 
| -      assembler->Bind(&if_stringistwobyte);
 | 
| -      {
 | 
| -        Label if_isdoublecodeunit(assembler);
 | 
| -        Node* lead = assembler->Load(
 | 
| -            MachineType::Uint16(), string_resource_data,
 | 
| -            assembler->WordShl(index, assembler->IntPtrConstant(1)));
 | 
| -        var_result.Bind(lead);
 | 
| -        Node* next_pos =
 | 
| -            assembler->Int32Add(index, assembler->Int32Constant(1));
 | 
| -
 | 
| -        assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length),
 | 
| -                          &return_result);
 | 
| -        assembler->GotoIf(
 | 
| -            assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)),
 | 
| -            &return_result);
 | 
| -        assembler->Branch(
 | 
| -            assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)),
 | 
| -            &if_isdoublecodeunit, &return_result);
 | 
| -
 | 
| -        assembler->Bind(&if_isdoublecodeunit);
 | 
| -        {
 | 
| -          Node* trail = assembler->Load(
 | 
| -              MachineType::Uint16(), string,
 | 
| -              assembler->IntPtrAdd(
 | 
| -                  assembler->WordShl(next_pos, assembler->IntPtrConstant(1)),
 | 
| -                  assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
 | 
| -                                            kHeapObjectTag)));
 | 
| -          assembler->GotoIf(assembler->Uint32LessThan(
 | 
| -                                trail, assembler->Int32Constant(0xDC00)),
 | 
| -                            &return_result);
 | 
| -          assembler->GotoIf(assembler->Uint32GreaterThanOrEqual(
 | 
| -                                trail, assembler->Int32Constant(0xE000)),
 | 
| -                            &return_result);
 | 
| -
 | 
| -          var_trail.Bind(trail);
 | 
| -          assembler->Goto(&handle_surrogate_pair);
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    assembler->Bind(&if_stringisnotshort);
 | 
| -    {
 | 
| -      Label if_isdoublecodeunit(assembler);
 | 
| -      Node* lead = assembler->SmiToWord32(assembler->CallRuntime(
 | 
| -          Runtime::kExternalStringGetChar, assembler->NoContextConstant(),
 | 
| -          string, assembler->SmiTag(index)));
 | 
| -      var_result.Bind(lead);
 | 
| -      Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1));
 | 
| -
 | 
| -      assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length),
 | 
| -                        &return_result);
 | 
| -      assembler->GotoIf(
 | 
| -          assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)),
 | 
| -          &return_result);
 | 
| -      assembler->Branch(assembler->Uint32GreaterThanOrEqual(
 | 
| -                            lead, assembler->Int32Constant(0xDC00)),
 | 
| -                        &return_result, &if_isdoublecodeunit);
 | 
| -
 | 
| -      assembler->Bind(&if_isdoublecodeunit);
 | 
| -      {
 | 
| -        Node* trail = assembler->SmiToWord32(assembler->CallRuntime(
 | 
| -            Runtime::kExternalStringGetChar, assembler->NoContextConstant(),
 | 
| -            string, assembler->SmiTag(next_pos)));
 | 
| -        assembler->GotoIf(
 | 
| -            assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)),
 | 
| -            &return_result);
 | 
| -        assembler->GotoIf(assembler->Uint32GreaterThanOrEqual(
 | 
| -                              trail, assembler->Int32Constant(0xE000)),
 | 
| -                          &return_result);
 | 
| -        var_trail.Bind(trail);
 | 
| -        assembler->Goto(&handle_surrogate_pair);
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  assembler->Bind(&handle_surrogate_pair);
 | 
| -  {
 | 
| -    Node* lead = var_result.value();
 | 
| -    Node* trail = var_trail.value();
 | 
| -#ifdef ENABLE_SLOW_DCHECKS
 | 
| -    // Check that this path is only taken if a surrogate pair is found
 | 
| -    assembler->Assert(assembler->Uint32GreaterThanOrEqual(
 | 
| -        lead, assembler->Int32Constant(0xD800)));
 | 
| -    assembler->Assert(
 | 
| -        assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)));
 | 
| -    assembler->Assert(assembler->Uint32GreaterThanOrEqual(
 | 
| -        trail, assembler->Int32Constant(0xDC00)));
 | 
| -    assembler->Assert(
 | 
| -        assembler->Uint32LessThan(trail, assembler->Int32Constant(0xE000)));
 | 
| -#endif
 | 
| -
 | 
| -    switch (encoding) {
 | 
| -      case UnicodeEncoding::UTF16:
 | 
| -        var_result.Bind(assembler->WordOr(
 | 
| -            assembler->WordShl(trail, assembler->Int32Constant(16)), lead));
 | 
| -        break;
 | 
| -
 | 
| -      case UnicodeEncoding::UTF32: {
 | 
| -        // Convert UTF16 surrogate pair into |word32| code point, encoded as
 | 
| -        // UTF32.
 | 
| -        Node* surrogate_offset =
 | 
| -            assembler->Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00);
 | 
| -
 | 
| -        // (lead << 10) + trail + SURROGATE_OFFSET
 | 
| -        var_result.Bind(assembler->Int32Add(
 | 
| -            assembler->WordShl(lead, assembler->Int32Constant(10)),
 | 
| -            assembler->Int32Add(trail, surrogate_offset)));
 | 
| -        break;
 | 
| -      }
 | 
| -    }
 | 
| -    assembler->Goto(&return_result);
 | 
| -  }
 | 
| -
 | 
| -  assembler->Bind(&return_result);
 | 
| -  return var_result.value();
 | 
| -}
 | 
| -
 | 
| -compiler::Node* LoadSurrogatePairAt(CodeStubAssembler* assembler,
 | 
| -                                    compiler::Node* string,
 | 
| -                                    compiler::Node* length,
 | 
| -                                    compiler::Node* index) {
 | 
| -  return LoadSurrogatePairInternal(assembler, string, length, index,
 | 
| -                                   UnicodeEncoding::UTF16);
 | 
| -}
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
| -void Builtins::Generate_StringIteratorPrototypeNext(
 | 
| -    CodeStubAssembler* assembler) {
 | 
| -  typedef CodeStubAssembler::Label Label;
 | 
| -  typedef compiler::Node Node;
 | 
| -  typedef CodeStubAssembler::Variable Variable;
 | 
| -
 | 
| -  Variable var_value(assembler, MachineRepresentation::kTagged);
 | 
| -  Variable var_done(assembler, MachineRepresentation::kTagged);
 | 
| -
 | 
| -  var_value.Bind(assembler->UndefinedConstant());
 | 
| -  var_done.Bind(assembler->BooleanConstant(true));
 | 
| -
 | 
| -  Label throw_bad_receiver(assembler), next_codepoint(assembler),
 | 
| -      return_result(assembler);
 | 
| -
 | 
| -  Node* iterator = assembler->Parameter(0);
 | 
| -  Node* context = assembler->Parameter(3);
 | 
| -
 | 
| -  assembler->GotoIf(assembler->WordIsSmi(iterator), &throw_bad_receiver);
 | 
| -  assembler->GotoUnless(
 | 
| -      assembler->WordEqual(assembler->LoadInstanceType(iterator),
 | 
| -                           assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)),
 | 
| -      &throw_bad_receiver);
 | 
| -
 | 
| -  Node* string =
 | 
| -      assembler->LoadObjectField(iterator, JSStringIterator::kStringOffset);
 | 
| -  Node* position =
 | 
| -      assembler->LoadObjectField(iterator, JSStringIterator::kNextIndexOffset);
 | 
| -  Node* length = assembler->LoadObjectField(string, String::kLengthOffset);
 | 
| -
 | 
| -  assembler->Branch(assembler->SmiLessThan(position, length), &next_codepoint,
 | 
| -                    &return_result);
 | 
| -
 | 
| -  assembler->Bind(&next_codepoint);
 | 
| -  {
 | 
| -    Node* ch =
 | 
| -        LoadSurrogatePairAt(assembler, string, assembler->SmiUntag(length),
 | 
| -                            assembler->SmiUntag(position));
 | 
| -    Node* value = assembler->StringFromCodePoint(ch, UnicodeEncoding::UTF16);
 | 
| -    var_value.Bind(value);
 | 
| -    Node* length = assembler->LoadObjectField(value, String::kLengthOffset);
 | 
| -    assembler->StoreObjectFieldNoWriteBarrier(
 | 
| -        iterator, JSStringIterator::kNextIndexOffset,
 | 
| -        assembler->SmiAdd(position, length));
 | 
| -    var_done.Bind(assembler->BooleanConstant(false));
 | 
| -    assembler->Goto(&return_result);
 | 
| -  }
 | 
| -
 | 
| -  assembler->Bind(&return_result);
 | 
| -  {
 | 
| -    Node* native_context = assembler->LoadNativeContext(context);
 | 
| -    Node* map = assembler->LoadFixedArrayElement(
 | 
| -        native_context,
 | 
| -        assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0,
 | 
| -        CodeStubAssembler::INTPTR_PARAMETERS);
 | 
| -    Node* result = assembler->Allocate(JSIteratorResult::kSize);
 | 
| -    assembler->StoreMapNoWriteBarrier(result, map);
 | 
| -    assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
 | 
| -                                    Heap::kEmptyFixedArrayRootIndex);
 | 
| -    assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
 | 
| -                                    Heap::kEmptyFixedArrayRootIndex);
 | 
| -    assembler->StoreObjectFieldNoWriteBarrier(
 | 
| -        result, JSIteratorResult::kValueOffset, var_value.value());
 | 
| -    assembler->StoreObjectFieldNoWriteBarrier(
 | 
| -        result, JSIteratorResult::kDoneOffset, var_done.value());
 | 
| -    assembler->Return(result);
 | 
| -  }
 | 
| -
 | 
| -  assembler->Bind(&throw_bad_receiver);
 | 
| -  {
 | 
| -    // The {receiver} is not a valid JSGeneratorObject.
 | 
| -    Node* result = assembler->CallRuntime(
 | 
| -        Runtime::kThrowIncompatibleMethodReceiver, context,
 | 
| -        assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked(
 | 
| -            "String Iterator.prototype.next", TENURED)),
 | 
| -        iterator);
 | 
| -    assembler->Return(result);  // Never reached.
 | 
| -  }
 | 
| +    }
 | 
| +
 | 
| +    // Return single code unit
 | 
| +    iterator->set_index(position + 1);
 | 
| +    Handle<String> value =
 | 
| +        isolate->factory()->LookupSingleCharacterStringFromCode(lead);
 | 
| +    return *isolate->factory()->NewJSIteratorResult(value, false);
 | 
| +  }
 | 
| +
 | 
| +  iterator->set_string(isolate->heap()->empty_string());
 | 
| +
 | 
| +  return *isolate->factory()->NewJSIteratorResult(
 | 
| +      isolate->factory()->undefined_value(), true);
 | 
|  }
 | 
|  
 | 
|  }  // namespace internal
 | 
| 
 |