Commit 3c52ac79 authored by caitp's avatar caitp Committed by Commit bot

Reland "[builtins] migrate C++ String Iterator builtins to baseline TurboFan"

Migrate newly added C++ String Iterator builtins to TFJ builtins, per
step 4. of the String Iterator Baseline Implementation section of the design doc

BUG=v8:5388
R=bmeurer@chromium.org, mstarzinger@chromium.org, jkummerow@chromium.org

Committed: https://crrev.com/f9a2c8b1112c4e915df8bc5f7ea1fccdf7a33ff8
Cr-Commit-Position: refs/heads/master@{#39765}

patch from issue 2358263002 at patchset 260001 (http://crrev.com/2358263002#ps260001)

Review-Url: https://codereview.chromium.org/2381053002
Cr-Commit-Position: refs/heads/master@{#39879}
parent 537c8558
......@@ -1438,9 +1438,17 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
factory->NewStringFromAsciiChecked("String Iterator"),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
InstallFunction(string_iterator_prototype, "next", JS_OBJECT_TYPE,
JSObject::kHeaderSize, MaybeHandle<JSObject>(),
Builtins::kStringIteratorPrototypeNext);
Handle<JSFunction> next =
InstallFunction(string_iterator_prototype, "next", JS_OBJECT_TYPE,
JSObject::kHeaderSize, MaybeHandle<JSObject>(),
Builtins::kStringIteratorPrototypeNext);
// Set the expected parameters for %StringIteratorPrototype%.next to 0 (not
// including the receiver), as required by the builtin.
next->shared()->set_internal_formal_parameter_count(0);
// Set the length for the function to satisfy ECMA-262.
next->shared()->set_length(0);
Handle<JSFunction> string_iterator_function = CreateFunction(
isolate, factory->NewStringFromAsciiChecked("StringIterator"),
......
This diff is collapsed.
......@@ -564,10 +564,10 @@ namespace internal {
/* ES6 section 21.1.3.28 String.prototype.valueOf () */ \
TFJ(StringPrototypeValueOf, 1) \
/* ES6 #sec-string.prototype-@@iterator */ \
CPP(StringPrototypeIterator) \
TFJ(StringPrototypeIterator, 1) \
\
/* StringIterator */ \
CPP(StringIteratorPrototypeNext) \
TFJ(StringIteratorPrototypeNext, 1) \
\
/* Symbol */ \
CPP(SymbolConstructor) \
......
......@@ -2734,6 +2734,58 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
return var_result.value();
}
Node* CodeStubAssembler::StringFromCodePoint(compiler::Node* codepoint,
UnicodeEncoding encoding) {
Variable var_result(this, MachineRepresentation::kTagged);
var_result.Bind(EmptyStringConstant());
Label if_isword16(this), if_isword32(this), return_result(this);
Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16,
&if_isword32);
Bind(&if_isword16);
{
var_result.Bind(StringFromCharCode(codepoint));
Goto(&return_result);
}
Bind(&if_isword32);
{
switch (encoding) {
case UnicodeEncoding::UTF16:
break;
case UnicodeEncoding::UTF32: {
// Convert UTF32 to UTF16 code units, and store as a 32 bit word.
Node* lead_offset = Int32Constant(0xD800 - (0x10000 >> 10));
// lead = (codepoint >> 10) + LEAD_OFFSET
Node* lead =
Int32Add(WordShr(codepoint, Int32Constant(10)), lead_offset);
// trail = (codepoint & 0x3FF) + 0xDC00;
Node* trail = Int32Add(Word32And(codepoint, Int32Constant(0x3FF)),
Int32Constant(0xDC00));
// codpoint = (trail << 16) | lead;
codepoint = Word32Or(WordShl(trail, Int32Constant(16)), lead);
break;
}
}
Node* value = AllocateSeqTwoByteString(2);
StoreNoWriteBarrier(
MachineRepresentation::kWord32, value,
IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag),
codepoint);
var_result.Bind(value);
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);
......
......@@ -19,6 +19,12 @@ class StubCache;
enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
enum class UnicodeEncoding {
// Different unicode encodings in a |word32|:
UTF16, // hi 16bits -> trailing surrogate or 0, low 16bits -> lead surrogate
UTF32, // full UTF32 code unit / Unicode codepoint
};
// Provides JavaScript-specific "macro-assembler" functionality on top of the
// CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler,
// it's possible to add JavaScript-specific useful CodeAssembler "macros"
......@@ -472,6 +478,9 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* SubString(compiler::Node* context, compiler::Node* string,
compiler::Node* from, compiler::Node* to);
compiler::Node* StringFromCodePoint(compiler::Node* codepoint,
UnicodeEncoding encoding);
// Type conversion helpers.
// Convert a String to a Number.
compiler::Node* StringToNumber(compiler::Node* context,
......
......@@ -785,7 +785,8 @@ void JSWeakMap::JSWeakMapVerify() {
void JSStringIterator::JSStringIteratorVerify() {
CHECK(IsJSStringIterator());
JSObjectVerify();
CHECK(string()->IsString());
CHECK(string()->IsSeqString() || string()->IsExternalString());
CHECK_GE(index(), 0);
CHECK_LE(index(), String::kMaxLength);
}
......
......@@ -92,3 +92,11 @@ function TestNonOwnSlots() {
assertThrows(function() { object.next(); }, TypeError);
}
TestNonOwnSlots();
function TestSlicedStringRegression() {
var long_string = "abcdefhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var sliced_string = long_string.substring(1);
var iterator = sliced_string[Symbol.iterator]();
}
TestSlicedStringRegression();
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