Add CodeStubAssembler::FlattenString
R=danno@chromium.org BUG= Review-Url: https://chromiumcodereview.appspot.com/2435953002 Cr-Commit-Position: refs/heads/master@{#40456}
This commit is contained in:
parent
5006df44c3
commit
9780e970ff
@ -3609,6 +3609,44 @@ Node* CodeStubAssembler::ToString(Node* context, Node* input) {
|
||||
return result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::FlattenString(Node* string) {
|
||||
Variable var_result(this, MachineRepresentation::kTagged);
|
||||
var_result.Bind(string);
|
||||
|
||||
Node* instance_type = LoadInstanceType(string);
|
||||
|
||||
// Check if the {string} is not a ConsString (i.e. already flat).
|
||||
Label is_cons(this, Label::kDeferred), is_flat_in_cons(this), end(this);
|
||||
{
|
||||
GotoUnless(Word32Equal(Word32And(instance_type,
|
||||
Int32Constant(kStringRepresentationMask)),
|
||||
Int32Constant(kConsStringTag)),
|
||||
&end);
|
||||
|
||||
// Check whether the right hand side is the empty string (i.e. if
|
||||
// this is really a flat string in a cons string).
|
||||
Node* rhs = LoadObjectField(string, ConsString::kSecondOffset);
|
||||
Branch(WordEqual(rhs, EmptyStringConstant()), &is_flat_in_cons, &is_cons);
|
||||
}
|
||||
|
||||
// Bail out to the runtime.
|
||||
Bind(&is_cons);
|
||||
{
|
||||
var_result.Bind(
|
||||
CallRuntime(Runtime::kFlattenString, NoContextConstant(), string));
|
||||
Goto(&end);
|
||||
}
|
||||
|
||||
Bind(&is_flat_in_cons);
|
||||
{
|
||||
var_result.Bind(LoadObjectField(string, ConsString::kFirstOffset));
|
||||
Goto(&end);
|
||||
}
|
||||
|
||||
Bind(&end);
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::JSReceiverToPrimitive(Node* context, Node* input) {
|
||||
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
Label if_isreceiver(this, Label::kDeferred), if_isnotreceiver(this);
|
||||
|
@ -644,6 +644,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
compiler::Node* JSReceiverToPrimitive(compiler::Node* context,
|
||||
compiler::Node* input);
|
||||
|
||||
// Convert a String to a flat String.
|
||||
compiler::Node* FlattenString(compiler::Node* string);
|
||||
|
||||
enum ToIntegerTruncationMode {
|
||||
kNoTruncation,
|
||||
kTruncateMinusZero,
|
||||
|
@ -175,6 +175,46 @@ TEST(ToString) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FlattenString) {
|
||||
Isolate* isolate(CcTest::InitIsolateOnce());
|
||||
const int kNumParams = 1;
|
||||
CodeStubAssemblerTester m(isolate, kNumParams);
|
||||
m.Return(m.FlattenString(m.Parameter(0)));
|
||||
|
||||
Handle<Code> code = m.GenerateCode();
|
||||
FunctionTester ft(code, kNumParams);
|
||||
|
||||
Handle<FixedArray> test_cases(isolate->factory()->NewFixedArray(4));
|
||||
Handle<String> expected(
|
||||
isolate->factory()->InternalizeUtf8String("hello, world!"));
|
||||
test_cases->set(0, *expected);
|
||||
|
||||
Handle<String> string(
|
||||
isolate->factory()->InternalizeUtf8String("filler hello, world! filler"));
|
||||
Handle<String> sub_string(
|
||||
isolate->factory()->NewProperSubString(string, 7, 20));
|
||||
test_cases->set(1, *sub_string);
|
||||
|
||||
Handle<String> hello(isolate->factory()->InternalizeUtf8String("hello,"));
|
||||
Handle<String> world(isolate->factory()->InternalizeUtf8String(" world!"));
|
||||
Handle<String> cons_str(
|
||||
isolate->factory()->NewConsString(hello, world).ToHandleChecked());
|
||||
test_cases->set(2, *cons_str);
|
||||
|
||||
Handle<String> empty(isolate->factory()->InternalizeUtf8String(""));
|
||||
Handle<String> fake_cons_str(
|
||||
isolate->factory()->NewConsString(expected, empty).ToHandleChecked());
|
||||
test_cases->set(3, *fake_cons_str);
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Handle<String> test = handle(String::cast(test_cases->get(i)));
|
||||
Handle<Object> result = ft.Call(test).ToHandleChecked();
|
||||
CHECK(result->IsString());
|
||||
CHECK(Handle<String>::cast(result)->IsFlat());
|
||||
CHECK(String::Equals(Handle<String>::cast(result), expected));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TryToName) {
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
|
Loading…
Reference in New Issue
Block a user