Chromium Code Reviews| Index: src/code-stub-assembler.cc |
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
| index 80c4c77bf6f034f21cd12a2b7d90788aa2fec7d4..64a1ed6b2b9dc4c995909b952ba4d3728e3d7c19 100644 |
| --- a/src/code-stub-assembler.cc |
| +++ b/src/code-stub-assembler.cc |
| @@ -2429,6 +2429,251 @@ Node* CodeStubAssembler::StringFromCharCode(Node* code) { |
| return var_result.value(); |
| } |
| +Node* CodeStubAssembler::StringFromCodePointAt(Node* string, Node* length, |
|
Benedikt Meurer
2016/09/22 03:48:23
I'd prefer to have a helper method StringFromCodeP
caitp
2016/09/22 13:26:21
The main reason I've put this in CodeStubAssembler
Benedikt Meurer
2016/09/23 03:46:24
I'd be fine with __ if it improves readability (an
caitp
2016/09/23 10:14:28
Acknowledged, but maybe that will be a cleanup fol
|
| + Node* index) { |
| + Label return_result(this); |
| + Variable var_result(this, MachineRepresentation::kTagged); |
| + var_result.Bind(UndefinedConstant()); |
| + |
| + Node* string_instance_type = LoadInstanceType(string); |
| + |
| + Label if_stringissequential(this), if_stringisexternal(this); |
| + Branch(Word32Equal(Word32And(string_instance_type, |
| + Int32Constant(kStringRepresentationMask)), |
| + Int32Constant(kSeqStringTag)), |
| + &if_stringissequential, &if_stringisexternal); |
| + |
| + Bind(&if_stringissequential); |
| + { |
| + Label if_stringisonebyte(this), if_stringistwobyte(this); |
| + Branch(Word32Equal(Word32And(string_instance_type, |
| + Int32Constant(kStringEncodingMask)), |
| + Int32Constant(kOneByteStringTag)), |
| + &if_stringisonebyte, &if_stringistwobyte); |
| + |
| + Bind(&if_stringisonebyte); |
| + { |
| + Node* ch = |
| + Load(MachineType::Uint8(), string, |
| + IntPtrAdd(index, IntPtrConstant(SeqOneByteString::kHeaderSize - |
| + kHeapObjectTag))); |
| + Node* result = AllocateSeqOneByteString(1); |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord8, result, |
| + IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), ch); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + |
| + Bind(&if_stringistwobyte); |
| + { |
| + Node* lead = Load(MachineType::Uint16(), string, |
| + IntPtrAdd(WordShl(index, IntPtrConstant(1)), |
| + IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| + kHeapObjectTag))); |
| + Node* next_pos = Int32Add(index, Int32Constant(1)); |
| + |
| + Label if_issinglecodeunit(this), if_isdoublecodeunit(this); |
| + GotoIf(Int32GreaterThanOrEqual(next_pos, length), &if_issinglecodeunit); |
| + GotoIf(Int32LessThan(lead, Int32Constant(0xD800)), &if_issinglecodeunit); |
| + BranchIf(Int32LessThan(lead, Int32Constant(0xDC00)), &if_isdoublecodeunit, |
| + &if_issinglecodeunit); |
| + |
| + Bind(&if_isdoublecodeunit); |
| + { |
| + Node* trail = |
| + Load(MachineType::Uint16(), string, |
| + IntPtrAdd(WordShl(next_pos, IntPtrConstant(1)), |
| + IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| + kHeapObjectTag))); |
| + GotoIf(Int32LessThan(trail, Int32Constant(0xDC00)), |
| + &if_issinglecodeunit); |
| + GotoIf(Int32GreaterThan(trail, Int32Constant(0xDFFF)), |
| + &if_issinglecodeunit); |
| + |
| + Node* result = AllocateSeqTwoByteString(2); |
| +#if defined(V8_TARGET_LITTLE_ENDIAN) |
| + Node* ch = Word32Or(WordShl(trail, Int32Constant(16)), lead); |
| +#else |
| + Node* ch = Word32Or(WordShl(lead, Int32Constant(16)), trail); |
| +#endif |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord32, result, |
| + IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), ch); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + |
| + Bind(&if_issinglecodeunit); |
| + { |
| + Node* result = AllocateSeqTwoByteString(1); |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord16, result, |
| + IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), |
| + lead); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + } |
| + } |
| + |
| + Bind(&if_stringisexternal); |
| + { |
| + Assert(Word32Equal(Word32And(string_instance_type, |
| + Int32Constant(kStringRepresentationMask)), |
| + Int32Constant(kExternalStringTag))); |
| + Label if_stringisshort(this), if_stringisnotshort(this); |
| + |
| + Branch(Word32Equal(Word32And(string_instance_type, |
| + Int32Constant(kShortExternalStringMask)), |
| + Int32Constant(0)), |
| + &if_stringisshort, &if_stringisnotshort); |
| + |
| + Bind(&if_stringisshort); |
| + { |
| + // Load the actual resource data from the {string}. |
| + Node* string_resource_data = LoadObjectField( |
| + string, ExternalString::kResourceDataOffset, MachineType::Pointer()); |
| + |
| + Label if_stringistwobyte(this), if_stringisonebyte(this); |
| + Branch(Word32Equal(Word32And(string_instance_type, |
| + Int32Constant(kStringEncodingMask)), |
| + Int32Constant(kTwoByteStringTag)), |
| + &if_stringistwobyte, &if_stringisonebyte); |
| + |
| + Bind(&if_stringisonebyte); |
| + { |
| + Node* ch = Load(MachineType::Uint8(), string_resource_data, index); |
| + Node* result = AllocateSeqOneByteString(1); |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord8, result, |
| + IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), ch); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + |
| + Bind(&if_stringistwobyte); |
| + { |
| + Label if_issinglecodeunit(this), if_isdoublecodeunit(this); |
| + Node* lead = Load(MachineType::Uint16(), string_resource_data, |
| + WordShl(index, IntPtrConstant(1))); |
| + Node* next_pos = Int32Add(index, Int32Constant(1)); |
| + |
| + GotoIf(Int32GreaterThanOrEqual(next_pos, length), &if_issinglecodeunit); |
| + GotoIf(Int32LessThan(lead, Int32Constant(0xD800)), |
| + &if_issinglecodeunit); |
| + Branch(Int32LessThan(lead, Int32Constant(0xDC00)), &if_isdoublecodeunit, |
| + &if_issinglecodeunit); |
| + |
| + Bind(&if_isdoublecodeunit); |
| + { |
| + Node* trail = |
| + Load(MachineType::Uint16(), string, |
| + IntPtrAdd(WordShl(next_pos, IntPtrConstant(1)), |
| + IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| + kHeapObjectTag))); |
| + GotoIf(Int32LessThan(trail, Int32Constant(0xDC00)), |
| + &if_issinglecodeunit); |
| + GotoIf(Int32GreaterThan(trail, Int32Constant(0xDFFF)), |
| + &if_issinglecodeunit); |
| + |
| + Node* result = AllocateSeqTwoByteString(2); |
| +#if defined(V8_TARGET_LITTLE_ENDIAN) |
| + Node* ch = Word32Or(WordShl(trail, Int32Constant(16)), lead); |
| +#else |
| + Node* ch = Word32Or(WordShl(lead, Int32Constant(16)), trail); |
| +#endif |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord32, result, |
| + IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), |
| + ch); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + |
| + Bind(&if_issinglecodeunit); |
| + { |
| + Node* result = AllocateSeqTwoByteString(1); |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord16, result, |
| + IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), |
| + lead); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + } |
| + } |
| + |
| + Bind(&if_stringisnotshort); |
| + { |
| + Label if_issinglecodeunit(this), if_isdoublecodeunit(this); |
| + Node* lead = |
| + SmiToWord32(CallRuntime(Runtime::kExternalStringGetChar, |
| + NoContextConstant(), string, SmiTag(index))); |
| + Node* next_pos = Int32Add(index, Int32Constant(1)); |
| + |
| + GotoIf(Int32GreaterThanOrEqual(next_pos, length), &if_issinglecodeunit); |
| + GotoIf(Int32LessThan(lead, Int32Constant(0xD800)), &if_issinglecodeunit); |
| + Branch(Int32GreaterThan(lead, Int32Constant(0xDBFF)), |
| + &if_issinglecodeunit, &if_isdoublecodeunit); |
| + |
| + Bind(&if_isdoublecodeunit); |
| + { |
| + Node* trail = SmiToWord32(CallRuntime(Runtime::kExternalStringGetChar, |
| + NoContextConstant(), string, |
| + SmiTag(next_pos))); |
| + GotoIf(Int32LessThan(trail, Int32Constant(0xDC00)), |
| + &if_issinglecodeunit); |
| + GotoIf(Int32GreaterThan(trail, Int32Constant(0xDFFF)), |
| + &if_issinglecodeunit); |
| + Node* result = AllocateSeqTwoByteString(2); |
| +#if defined(V8_TARGET_LITTLE_ENDIAN) |
| + Node* ch = Word32Or(WordShl(trail, Int32Constant(16)), lead); |
| +#else |
| + Node* ch = Word32Or(WordShl(lead, Int32Constant(16)), trail); |
| +#endif |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord32, result, |
| + IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), ch); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + |
| + Bind(&if_issinglecodeunit); |
| + { |
| + Label if_isonebyte(this), if_istwobyte(this); |
| + Branch(Int32LessThan(lead, Int32Constant(0x100)), &if_isonebyte, |
| + &if_istwobyte); |
| + |
| + Bind(&if_isonebyte); |
| + { |
| + Node* result = AllocateSeqOneByteString(1); |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord8, result, |
| + IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), |
| + lead); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + |
| + Bind(&if_istwobyte); |
| + { |
| + Node* result = AllocateSeqTwoByteString(1); |
| + StoreNoWriteBarrier( |
| + MachineRepresentation::kWord8, result, |
| + IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), |
| + lead); |
| + var_result.Bind(result); |
| + Goto(&return_result); |
| + } |
| + } |
| + } |
| + } |
| + |
| + Bind(&return_result); |
| + return var_result.value(); |
| +} |
| + |
| Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) { |
| Label runtime(this, Label::kDeferred); |
| Label end(this); |