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

Unified Diff: src/builtins/builtins.cc

Issue 2134803002: [builtins] Object.prototype.toString() as TurboFan stub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 5 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/builtins/builtins.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins.cc
diff --git a/src/builtins/builtins.cc b/src/builtins/builtins.cc
index 71aacb6affe519e18f70dfaa743491fbb912c1ce..fa8ea3e4eac3e6ba6932f40d2979b65bcba909f9 100644
--- a/src/builtins/builtins.cc
+++ b/src/builtins/builtins.cc
@@ -6,7 +6,6 @@
#include "src/api-arguments.h"
#include "src/api-natives.h"
-#include "src/api.h"
#include "src/base/ieee754.h"
#include "src/base/once.h"
#include "src/bootstrapper.h"
@@ -389,6 +388,254 @@ void Builtins::Generate_ObjectHasOwnProperty(CodeStubAssembler* assembler) {
context, object, key));
}
+namespace { // anonymous namespace for ObjectProtoToString()
+
+void IsString(CodeStubAssembler* assembler, compiler::Node* object,
+ CodeStubAssembler::Label* if_string,
+ CodeStubAssembler::Label* if_notstring) {
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Label Label;
+
+ Label if_notsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(object), if_notstring, &if_notsmi);
+
+ assembler->Bind(&if_notsmi);
+ {
+ Node* instance_type = assembler->LoadInstanceType(object);
+
+ assembler->Branch(
+ assembler->Int32LessThan(
+ instance_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
+ if_string, if_notstring);
+ }
+}
+
+void ReturnToStringFormat(CodeStubAssembler* assembler, compiler::Node* context,
+ compiler::Node* string) {
+ typedef compiler::Node Node;
+
+ Node* lhs = assembler->HeapConstant(
+ assembler->factory()->NewStringFromStaticChars("[object "));
+ Node* rhs = assembler->HeapConstant(
+ assembler->factory()->NewStringFromStaticChars("]"));
+
+ Callable callable = CodeFactory::StringAdd(
+ assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
+
+ assembler->Return(assembler->CallStub(
+ callable, context, assembler->CallStub(callable, context, lhs, string),
+ rhs));
+}
+
+void ReturnIfPrimitive(CodeStubAssembler* assembler,
+ compiler::Node* instance_type,
+ CodeStubAssembler::Label* return_string,
+ CodeStubAssembler::Label* return_boolean,
+ CodeStubAssembler::Label* return_number) {
+ assembler->GotoIf(
+ assembler->Int32LessThan(instance_type,
+ assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
+ return_string);
+
+ assembler->GotoIf(assembler->Word32Equal(
+ instance_type, assembler->Int32Constant(ODDBALL_TYPE)),
+ return_boolean);
+
+ assembler->GotoIf(
+ assembler->Word32Equal(instance_type,
+ assembler->Int32Constant(HEAP_NUMBER_TYPE)),
+ return_number);
+}
+
+} // namespace
+
+// ES6 section 19.1.3.6 Object.prototype.toString
+void Builtins::Generate_ObjectProtoToString(CodeStubAssembler* assembler) {
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Label Label;
+ typedef CodeStubAssembler::Variable Variable;
+
+ Label return_undefined(assembler, Label::kDeferred),
+ return_null(assembler, Label::kDeferred),
+ return_arguments(assembler, Label::kDeferred), return_array(assembler),
+ return_api(assembler, Label::kDeferred), return_object(assembler),
+ return_regexp(assembler), return_function(assembler),
+ return_error(assembler), return_date(assembler), return_string(assembler),
+ return_boolean(assembler), return_jsvalue(assembler),
+ return_jsproxy(assembler, Label::kDeferred), return_number(assembler);
+
+ Label if_isproxy(assembler, Label::kDeferred);
+
+ Label checkstringtag(assembler);
+ Label if_tostringtag(assembler), if_notostringtag(assembler);
+
+ Node* receiver = assembler->Parameter(0);
+ Node* context = assembler->Parameter(3);
+
+ assembler->GotoIf(
+ assembler->Word32Equal(receiver, assembler->UndefinedConstant()),
+ &return_undefined);
+
+ assembler->GotoIf(assembler->Word32Equal(receiver, assembler->NullConstant()),
+ &return_null);
+
+ assembler->GotoIf(assembler->WordIsSmi(receiver), &return_number);
+
+ Node* receiver_instance_type = assembler->LoadInstanceType(receiver);
+ ReturnIfPrimitive(assembler, receiver_instance_type, &return_string,
+ &return_boolean, &return_number);
+
+ // for proxies, check IsArray before getting @@toStringTag
+ Variable var_proxy_is_array(assembler, MachineRepresentation::kTagged);
+ var_proxy_is_array.Bind(assembler->BooleanConstant(false));
+
+ assembler->Branch(
+ assembler->Word32Equal(receiver_instance_type,
+ assembler->Int32Constant(JS_PROXY_TYPE)),
+ &if_isproxy, &checkstringtag);
+
+ assembler->Bind(&if_isproxy);
+ {
+ // This can throw
+ var_proxy_is_array.Bind(
+ assembler->CallRuntime(Runtime::kArrayIsArray, context, receiver));
+ assembler->Goto(&checkstringtag);
+ }
+
+ assembler->Bind(&checkstringtag);
+ {
+ Node* to_string_tag_symbol = assembler->HeapConstant(
+ assembler->isolate()->factory()->to_string_tag_symbol());
+
+ GetPropertyStub stub(assembler->isolate());
+ Callable get_property =
+ Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
+ Node* to_string_tag_value = assembler->CallStub(
+ get_property, context, receiver, to_string_tag_symbol);
+
+ IsString(assembler, to_string_tag_value, &if_tostringtag,
+ &if_notostringtag);
+
+ assembler->Bind(&if_tostringtag);
+ ReturnToStringFormat(assembler, context, to_string_tag_value);
+ }
+ assembler->Bind(&if_notostringtag);
+ {
+ size_t const kNumCases = 11;
+ Label* case_labels[kNumCases];
+ int32_t case_values[kNumCases];
+ case_labels[0] = &return_api;
+ case_values[0] = JS_API_OBJECT_TYPE;
+ case_labels[1] = &return_api;
+ case_values[1] = JS_SPECIAL_API_OBJECT_TYPE;
+ case_labels[2] = &return_arguments;
+ case_values[2] = JS_ARGUMENTS_TYPE;
+ case_labels[3] = &return_array;
+ case_values[3] = JS_ARRAY_TYPE;
+ case_labels[4] = &return_function;
+ case_values[4] = JS_BOUND_FUNCTION_TYPE;
+ case_labels[5] = &return_function;
+ case_values[5] = JS_FUNCTION_TYPE;
+ case_labels[6] = &return_error;
+ case_values[6] = JS_ERROR_TYPE;
+ case_labels[7] = &return_date;
+ case_values[7] = JS_DATE_TYPE;
+ case_labels[8] = &return_regexp;
+ case_values[8] = JS_REGEXP_TYPE;
+ case_labels[9] = &return_jsvalue;
+ case_values[9] = JS_VALUE_TYPE;
+ case_labels[10] = &return_jsproxy;
+ case_values[10] = JS_PROXY_TYPE;
+
+ assembler->Switch(receiver_instance_type, &return_object, case_values,
+ case_labels, arraysize(case_values));
+
+ assembler->Bind(&return_undefined);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->undefined_to_string()));
+
+ assembler->Bind(&return_null);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->null_to_string()));
+
+ assembler->Bind(&return_number);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->number_to_string()));
+
+ assembler->Bind(&return_string);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->string_to_string()));
+
+ assembler->Bind(&return_boolean);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->boolean_to_string()));
+
+ assembler->Bind(&return_arguments);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->arguments_to_string()));
+
+ assembler->Bind(&return_array);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->array_to_string()));
+
+ assembler->Bind(&return_function);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->function_to_string()));
+
+ assembler->Bind(&return_error);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->error_to_string()));
+
+ assembler->Bind(&return_date);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->date_to_string()));
+
+ assembler->Bind(&return_regexp);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->regexp_to_string()));
+
+ assembler->Bind(&return_api);
+ {
+ Node* class_name =
+ assembler->CallRuntime(Runtime::kClassOf, context, receiver);
+ ReturnToStringFormat(assembler, context, class_name);
+ }
+
+ assembler->Bind(&return_jsvalue);
+ {
+ Node* value = assembler->LoadJSValueValue(receiver);
+ assembler->GotoIf(assembler->WordIsSmi(value), &return_number);
+
+ ReturnIfPrimitive(assembler, assembler->LoadInstanceType(value),
+ &return_string, &return_boolean, &return_number);
+ assembler->Goto(&return_object);
+ }
+
+ assembler->Bind(&return_jsproxy);
+ {
+ assembler->GotoIf(assembler->WordEqual(var_proxy_is_array.value(),
+ assembler->BooleanConstant(true)),
+ &return_array);
+
+ Node* map = assembler->LoadMap(receiver);
+
+ // Return object if the proxy {receiver} is not callable.
+ assembler->Branch(
+ assembler->Word32Equal(
+ assembler->Word32And(
+ assembler->LoadMapBitField(map),
+ assembler->Int32Constant(1 << Map::kIsCallable)),
+ assembler->Int32Constant(0)),
+ &return_object, &return_function);
+ }
+
+ // Default
+ assembler->Bind(&return_object);
+ assembler->Return(assembler->HeapConstant(
+ assembler->isolate()->factory()->object_to_string()));
+ }
+}
+
namespace {
Object* DoArrayPush(Isolate* isolate, BuiltinArguments args) {
@@ -4893,14 +5140,6 @@ BUILTIN(ObjectPrototypePropertyIsEnumerable) {
return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
}
-// ES6 section 19.1.3.6 Object.prototype.toString
-BUILTIN(ObjectProtoToString) {
- HandleScope scope(isolate);
- Handle<Object> object = args.at<Object>(0);
- RETURN_RESULT_OR_FAILURE(isolate,
- Object::ObjectProtoToString(isolate, object));
-}
-
// -----------------------------------------------------------------------------
// ES6 section 19.4 Symbol Objects
« no previous file with comments | « src/builtins/builtins.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698