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

Unified Diff: src/builtins.cc

Issue 1868963002: [builtins] Migrate String.prototype.charCodeAt and String.prototype.charAt to TurboFan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix typo Created 4 years, 8 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
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index 5456cd5b4f3b277811ac5de80078def8b745d47a..be780bf92802a8f4828eac591f4af1d2d020f74b 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -4187,6 +4187,199 @@ BUILTIN(ObjectProtoToString) {
return *result;
}
+// -----------------------------------------------------------------------------
+// ES6 section 21.1 String Objects
+
+// ES6 section 21.1.3.1 String.prototype.charAt ( pos )
+void Builtins::Generate_StringPrototypeCharAt(
+ compiler::CodeStubAssembler* assembler) {
+ typedef compiler::CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef compiler::CodeStubAssembler::Variable Variable;
+
+ Node* receiver = assembler->Parameter(0);
+ Node* position = assembler->Parameter(1);
+ Node* context = assembler->Parameter(4);
+
+ // Check that {receiver} is coercible to Object and convert it to a String.
+ receiver =
+ assembler->ToThisString(context, receiver, "String.prototype.charAt");
+
+ // Convert the {position} to a Smi and check that it's in bounds of the
+ // {receiver}.
+ // TODO(bmeurer): Find an abstraction for this!
+ {
+ // Check if the {position} is already a Smi.
+ Variable var_position(assembler, MachineRepresentation::kTagged);
+ var_position.Bind(position);
+ Label if_positionissmi(assembler),
+ if_positionisnotsmi(assembler, Label::kDeferred);
+ assembler->Branch(assembler->WordIsSmi(position), &if_positionissmi,
+ &if_positionisnotsmi);
+ assembler->Bind(&if_positionisnotsmi);
+ {
+ // Convert the {position} to an Integer via the ToIntegerStub.
+ Callable callable = CodeFactory::ToInteger(assembler->isolate());
+ Node* index = assembler->CallStub(callable, context, position);
+
+ // Check if the resulting {index} is now a Smi.
+ Label if_indexissmi(assembler, Label::kDeferred),
+ if_indexisnotsmi(assembler, Label::kDeferred);
+ assembler->Branch(assembler->WordIsSmi(index), &if_indexissmi,
+ &if_indexisnotsmi);
+
+ assembler->Bind(&if_indexissmi);
+ {
+ var_position.Bind(index);
+ assembler->Goto(&if_positionissmi);
+ }
+
+ assembler->Bind(&if_indexisnotsmi);
+ {
+ // The ToIntegerStub canonicalizes everything in Smi range to Smi
+ // representation, so any HeapNumber returned is not in Smi range.
+ // The only exception here is -0.0, which we treat as 0.
+ Node* index_value = assembler->LoadHeapNumberValue(index);
+ Label if_indexiszero(assembler, Label::kDeferred),
+ if_indexisnotzero(assembler, Label::kDeferred);
+ assembler->Branch(assembler->Float64Equal(
+ index_value, assembler->Float64Constant(0.0)),
+ &if_indexiszero, &if_indexisnotzero);
+
+ assembler->Bind(&if_indexiszero);
+ {
+ var_position.Bind(assembler->SmiConstant(Smi::FromInt(0)));
+ assembler->Goto(&if_positionissmi);
+ }
+
+ assembler->Bind(&if_indexisnotzero);
+ {
+ // The {index} is some other integral Number, that is definitely
+ // neither -0.0 nor in Smi range.
+ assembler->Return(assembler->EmptyStringConstant());
+ }
+ }
+ }
+ assembler->Bind(&if_positionissmi);
+ position = var_position.value();
+
+ // Determine the actual length of the {receiver} String.
+ Node* receiver_length =
+ assembler->LoadObjectField(receiver, String::kLengthOffset);
+
+ // Return "" if the Smi {position} is outside the bounds of the {receiver}.
+ Label if_positioninbounds(assembler),
+ if_positionnotinbounds(assembler, Label::kDeferred);
+ assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length),
+ &if_positionnotinbounds, &if_positioninbounds);
+ assembler->Bind(&if_positionnotinbounds);
+ assembler->Return(assembler->EmptyStringConstant());
+ assembler->Bind(&if_positioninbounds);
+ }
+
+ // Load the character code at the {position} from the {receiver}.
+ Node* code = assembler->StringCharCodeAt(receiver, position);
+
+ // And return the single character string with only that {code}.
+ Node* result = assembler->StringFromCharCode(code);
+ assembler->Return(result);
+}
+
+// ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos )
+void Builtins::Generate_StringPrototypeCharCodeAt(
+ compiler::CodeStubAssembler* assembler) {
+ typedef compiler::CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef compiler::CodeStubAssembler::Variable Variable;
+
+ Node* receiver = assembler->Parameter(0);
+ Node* position = assembler->Parameter(1);
+ Node* context = assembler->Parameter(4);
+
+ // Check that {receiver} is coercible to Object and convert it to a String.
+ receiver =
+ assembler->ToThisString(context, receiver, "String.prototype.charCodeAt");
+
+ // Convert the {position} to a Smi and check that it's in bounds of the
+ // {receiver}.
+ // TODO(bmeurer): Find an abstraction for this!
+ {
+ // Check if the {position} is already a Smi.
+ Variable var_position(assembler, MachineRepresentation::kTagged);
+ var_position.Bind(position);
+ Label if_positionissmi(assembler),
+ if_positionisnotsmi(assembler, Label::kDeferred);
+ assembler->Branch(assembler->WordIsSmi(position), &if_positionissmi,
+ &if_positionisnotsmi);
+ assembler->Bind(&if_positionisnotsmi);
+ {
+ // Convert the {position} to an Integer via the ToIntegerStub.
+ Callable callable = CodeFactory::ToInteger(assembler->isolate());
+ Node* index = assembler->CallStub(callable, context, position);
+
+ // Check if the resulting {index} is now a Smi.
+ Label if_indexissmi(assembler, Label::kDeferred),
+ if_indexisnotsmi(assembler, Label::kDeferred);
+ assembler->Branch(assembler->WordIsSmi(index), &if_indexissmi,
+ &if_indexisnotsmi);
+
+ assembler->Bind(&if_indexissmi);
+ {
+ var_position.Bind(index);
+ assembler->Goto(&if_positionissmi);
+ }
+
+ assembler->Bind(&if_indexisnotsmi);
+ {
+ // The ToIntegerStub canonicalizes everything in Smi range to Smi
+ // representation, so any HeapNumber returned is not in Smi range.
+ // The only exception here is -0.0, which we treat as 0.
+ Node* index_value = assembler->LoadHeapNumberValue(index);
+ Label if_indexiszero(assembler, Label::kDeferred),
+ if_indexisnotzero(assembler, Label::kDeferred);
+ assembler->Branch(assembler->Float64Equal(
+ index_value, assembler->Float64Constant(0.0)),
+ &if_indexiszero, &if_indexisnotzero);
+
+ assembler->Bind(&if_indexiszero);
+ {
+ var_position.Bind(assembler->SmiConstant(Smi::FromInt(0)));
+ assembler->Goto(&if_positionissmi);
+ }
+
+ assembler->Bind(&if_indexisnotzero);
+ {
+ // The {index} is some other integral Number, that is definitely
+ // neither -0.0 nor in Smi range.
+ assembler->Return(assembler->NaNConstant());
+ }
+ }
+ }
+ assembler->Bind(&if_positionissmi);
+ position = var_position.value();
+
+ // Determine the actual length of the {receiver} String.
+ Node* receiver_length =
+ assembler->LoadObjectField(receiver, String::kLengthOffset);
+
+ // Return NaN if the Smi {position} is outside the bounds of the {receiver}.
+ Label if_positioninbounds(assembler),
+ if_positionnotinbounds(assembler, Label::kDeferred);
+ assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length),
+ &if_positionnotinbounds, &if_positioninbounds);
+ assembler->Bind(&if_positionnotinbounds);
+ assembler->Return(assembler->NaNConstant());
+ assembler->Bind(&if_positioninbounds);
+ }
+
+ // Load the character at the {position} from the {receiver}.
+ Node* value = assembler->StringCharCodeAt(receiver, position);
+ Node* result = assembler->SmiFromWord32(value);
+ assembler->Return(result);
+}
+
+// -----------------------------------------------------------------------------
+// ES6 section 21.1 ArrayBuffer Objects
// ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case.
BUILTIN(ArrayBufferConstructor) {

Powered by Google App Engine
This is Rietveld 408576698