Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: src/code-stub-assembler.cc

Issue 2398423002: [regexp] Port RegExp.prototype[@@replace] (Closed)
Patch Set: Smi::kZero Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/contexts.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 6adec9aff6fd100da4efb4b4baa942b281566f2f..a72e267f391581a840defb56e0dfe7e5b25a3dc7 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -1350,6 +1350,40 @@ Node* CodeStubAssembler::AllocateSlicedTwoByteString(Node* length, Node* parent,
return result;
}
+Node* CodeStubAssembler::AllocateOneByteConsString(Node* length, Node* first,
+ Node* second) {
+ Node* result = Allocate(ConsString::kSize);
+ Node* map = LoadRoot(Heap::kConsOneByteStringMapRootIndex);
+ StoreMapNoWriteBarrier(result, map);
+ StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length,
+ MachineRepresentation::kTagged);
+ StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset,
+ Int32Constant(String::kEmptyHashField),
+ MachineRepresentation::kWord32);
+ StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first,
+ MachineRepresentation::kTagged);
+ StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second,
+ MachineRepresentation::kTagged);
+ return result;
+}
+
+Node* CodeStubAssembler::AllocateTwoByteConsString(Node* length, Node* first,
+ Node* second) {
+ Node* result = Allocate(ConsString::kSize);
+ Node* map = LoadRoot(Heap::kConsStringMapRootIndex);
+ StoreMapNoWriteBarrier(result, map);
+ StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length,
+ MachineRepresentation::kTagged);
+ StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset,
+ Int32Constant(String::kEmptyHashField),
+ MachineRepresentation::kWord32);
+ StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first,
+ MachineRepresentation::kTagged);
+ StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second,
+ MachineRepresentation::kTagged);
+ return result;
+}
+
Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length,
Node* index, Node* input) {
Node* const max_length =
@@ -1687,6 +1721,7 @@ void CodeStubAssembler::CopyFixedArrayElements(
void CodeStubAssembler::CopyStringCharacters(compiler::Node* from_string,
compiler::Node* to_string,
compiler::Node* from_index,
+ compiler::Node* to_index,
compiler::Node* character_count,
String::Encoding encoding) {
Label out(this);
@@ -1704,20 +1739,22 @@ void CodeStubAssembler::CopyStringCharacters(compiler::Node* from_string,
{
Node* byte_count = SmiUntag(character_count);
Node* from_byte_index = SmiUntag(from_index);
+ Node* to_byte_index = SmiUntag(to_index);
if (encoding == String::ONE_BYTE_ENCODING) {
const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag;
from_offset = IntPtrAdd(IntPtrConstant(offset), from_byte_index);
limit_offset = IntPtrAdd(from_offset, byte_count);
- to_offset = IntPtrConstant(offset);
+ to_offset = IntPtrAdd(IntPtrConstant(offset), to_byte_index);
} else {
STATIC_ASSERT(2 == sizeof(uc16));
byte_count = WordShl(byte_count, 1);
from_byte_index = WordShl(from_byte_index, 1);
+ to_byte_index = WordShl(to_byte_index, 1);
const int offset = SeqTwoByteString::kHeaderSize - kHeapObjectTag;
from_offset = IntPtrAdd(IntPtrConstant(offset), from_byte_index);
limit_offset = IntPtrAdd(from_offset, byte_count);
- to_offset = IntPtrConstant(offset);
+ to_offset = IntPtrAdd(IntPtrConstant(offset), to_byte_index);
}
}
@@ -2515,6 +2552,8 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
Label end(a), two_byte_sequential(a);
Variable var_result(a, MachineRepresentation::kTagged);
+ Node* const smi_zero = a->SmiConstant(Smi::kZero);
+
STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
a->GotoIf(a->Word32Equal(a->Word32And(from_instance_type,
a->Int32Constant(kStringEncodingMask)),
@@ -2525,7 +2564,7 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
{
Node* result =
a->AllocateSeqOneByteString(context, a->SmiToWord(character_count));
- a->CopyStringCharacters(from, result, from_index, character_count,
+ a->CopyStringCharacters(from, result, from_index, smi_zero, character_count,
String::ONE_BYTE_ENCODING);
var_result.Bind(result);
@@ -2537,7 +2576,7 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
{
Node* result =
a->AllocateSeqTwoByteString(context, a->SmiToWord(character_count));
- a->CopyStringCharacters(from, result, from_index, character_count,
+ a->CopyStringCharacters(from, result, from_index, smi_zero, character_count,
String::TWO_BYTE_ENCODING);
var_result.Bind(result);
@@ -2772,6 +2811,146 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
return var_result.value();
}
+Node* CodeStubAssembler::StringConcat(Node* context, Node* first,
+ Node* second) {
+ Variable var_result(this, MachineRepresentation::kTagged);
+
+ Label out(this), runtime(this, Label::kDeferred);
+
+ // TODO(jgruber): Handle indirect, external, and two-byte strings.
+
+ Node* const one_byte_seq_mask = Int32Constant(
+ kIsIndirectStringMask | kExternalStringTag | kStringEncodingMask);
+ Node* const expected_masked = Int32Constant(kOneByteStringTag);
+
+ Node* const first_instance_type = LoadInstanceType(first);
+ GotoUnless(Word32Equal(Word32And(first_instance_type, one_byte_seq_mask),
+ expected_masked),
+ &runtime);
+
+ Node* const second_instance_type = LoadInstanceType(second);
+ GotoUnless(Word32Equal(Word32And(second_instance_type, one_byte_seq_mask),
+ expected_masked),
+ &runtime);
+
+ Node* const smi_zero = SmiConstant(Smi::kZero);
+ Node* const first_length = LoadStringLength(first);
+ Node* const second_length = LoadStringLength(second);
+ Node* const length = SmiAdd(first_length, second_length);
+
+ Label if_makeseqstring(this), if_makeconsstring(this);
+ Node* const min_cons_length =
+ SmiConstant(Smi::FromInt(ConsString::kMinLength));
+ Branch(SmiLessThan(length, min_cons_length), &if_makeseqstring,
+ &if_makeconsstring);
+
+ Bind(&if_makeseqstring);
+ {
+ Node* result = AllocateSeqOneByteString(context, SmiToWord(length));
+
+ CopyStringCharacters(first, result, smi_zero, smi_zero, first_length,
+ String::ONE_BYTE_ENCODING);
+ CopyStringCharacters(second, result, smi_zero, first_length, second_length,
+ String::ONE_BYTE_ENCODING);
+
+ var_result.Bind(result);
+ Goto(&out);
+ }
+
+ Bind(&if_makeconsstring);
+ {
+ Node* result = AllocateOneByteConsString(length, first, second);
+ var_result.Bind(result);
+ Goto(&out);
+ }
+
+ Bind(&runtime);
+ {
+ Node* const result =
+ CallRuntime(Runtime::kStringAdd, context, first, second);
+ var_result.Bind(result);
+ Goto(&out);
+ }
+
+ Bind(&out);
+ return var_result.value();
+}
+
+Node* CodeStubAssembler::StringIndexOfChar(Node* context, Node* string,
+ Node* needle_char, Node* from) {
+ Variable var_result(this, MachineRepresentation::kTagged);
+
+ Label out(this), runtime(this, Label::kDeferred);
+
+ // Let runtime handle non-one-byte {needle_char}.
+
+ Node* const one_byte_char_mask = IntPtrConstant(0xFF);
+ GotoUnless(WordEqual(WordAnd(needle_char, one_byte_char_mask), needle_char),
+ &runtime);
+
+ // TODO(jgruber): Handle external and two-byte strings.
+
+ Node* const one_byte_seq_mask = Int32Constant(
+ kIsIndirectStringMask | kExternalStringTag | kStringEncodingMask);
+ Node* const expected_masked = Int32Constant(kOneByteStringTag);
+
+ Node* const string_instance_type = LoadInstanceType(string);
+ GotoUnless(Word32Equal(Word32And(string_instance_type, one_byte_seq_mask),
+ expected_masked),
+ &runtime);
+
+ // If we reach this, {string} is a non-indirect, non-external one-byte string.
+
+ Node* const length = LoadStringLength(string);
+ Node* const search_range_length = SmiUntag(SmiSub(length, from));
+
+ const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag;
+ Node* const begin = IntPtrConstant(offset);
+ Node* const cursor = IntPtrAdd(begin, SmiUntag(from));
+ Node* const end = IntPtrAdd(cursor, search_range_length);
+
+ Variable var_cursor(this, MachineType::PointerRepresentation());
+ Variable* vars[] = {&var_cursor};
+ Label loop(this, 1, vars), loop_tail(this);
+
+ var_cursor.Bind(cursor);
+ var_result.Bind(SmiConstant(Smi::FromInt(-1)));
+
+ Goto(&loop);
+ Bind(&loop);
+ {
+ Node* const cursor = var_cursor.value();
+
+ Node* value = Load(MachineType::Uint8(), string, cursor);
+ GotoUnless(WordEqual(value, needle_char), &loop_tail);
+
+ // Found a match.
+ Node* index = SmiTag(IntPtrSub(cursor, begin));
+ var_result.Bind(index);
+ Goto(&out);
+
+ Bind(&loop_tail);
+ {
+ Node* const new_cursor = IntPtrAdd(cursor, IntPtrConstant(1));
+ var_cursor.Bind(new_cursor);
+ Branch(IntPtrLessThan(new_cursor, end), &loop, &out);
+ }
+ }
+
+ Bind(&runtime);
+ {
+ Node* const pattern = StringFromCharCode(needle_char);
+ Node* const result =
+ CallRuntime(Runtime::kStringIndexOf, context, string, pattern, from);
+ var_result.Bind(result);
+ var_cursor.Bind(IntPtrConstant(0));
+ Goto(&out);
+ }
+
+ Bind(&out);
+ return var_result.value();
+}
+
Node* CodeStubAssembler::StringFromCodePoint(compiler::Node* codepoint,
UnicodeEncoding encoding) {
Variable var_result(this, MachineRepresentation::kTagged);
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698