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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins.h" 5 #include "src/builtins/builtins.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/api.h"
10 #include "src/base/ieee754.h" 9 #include "src/base/ieee754.h"
11 #include "src/base/once.h" 10 #include "src/base/once.h"
12 #include "src/bootstrapper.h" 11 #include "src/bootstrapper.h"
13 #include "src/code-factory.h" 12 #include "src/code-factory.h"
14 #include "src/code-stub-assembler.h" 13 #include "src/code-stub-assembler.h"
15 #include "src/dateparser-inl.h" 14 #include "src/dateparser-inl.h"
16 #include "src/elements.h" 15 #include "src/elements.h"
17 #include "src/frames-inl.h" 16 #include "src/frames-inl.h"
18 #include "src/gdb-jit.h" 17 #include "src/gdb-jit.h"
19 #include "src/globals.h" 18 #include "src/globals.h"
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 assembler->Return(assembler->BooleanConstant(true)); 381 assembler->Return(assembler->BooleanConstant(true));
383 382
384 assembler->Bind(&return_false); 383 assembler->Bind(&return_false);
385 assembler->Return(assembler->BooleanConstant(false)); 384 assembler->Return(assembler->BooleanConstant(false));
386 385
387 assembler->Bind(&call_runtime); 386 assembler->Bind(&call_runtime);
388 assembler->Return(assembler->CallRuntime(Runtime::kObjectHasOwnProperty, 387 assembler->Return(assembler->CallRuntime(Runtime::kObjectHasOwnProperty,
389 context, object, key)); 388 context, object, key));
390 } 389 }
391 390
391 namespace { // anonymous namespace for ObjectProtoToString()
392
393 void IsString(CodeStubAssembler* assembler, compiler::Node* object,
394 CodeStubAssembler::Label* if_string,
395 CodeStubAssembler::Label* if_notstring) {
396 typedef compiler::Node Node;
397 typedef CodeStubAssembler::Label Label;
398
399 Label if_notsmi(assembler);
400 assembler->Branch(assembler->WordIsSmi(object), if_notstring, &if_notsmi);
401
402 assembler->Bind(&if_notsmi);
403 {
404 Node* instance_type = assembler->LoadInstanceType(object);
405
406 assembler->Branch(
407 assembler->Int32LessThan(
408 instance_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
409 if_string, if_notstring);
410 }
411 }
412
413 void ReturnToStringFormat(CodeStubAssembler* assembler, compiler::Node* context,
414 compiler::Node* string) {
415 typedef compiler::Node Node;
416
417 Node* lhs = assembler->HeapConstant(
418 assembler->factory()->NewStringFromStaticChars("[object "));
419 Node* rhs = assembler->HeapConstant(
420 assembler->factory()->NewStringFromStaticChars("]"));
421
422 Callable callable = CodeFactory::StringAdd(
423 assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
424
425 assembler->Return(assembler->CallStub(
426 callable, context, assembler->CallStub(callable, context, lhs, string),
427 rhs));
428 }
429
430 void ReturnIfPrimitive(CodeStubAssembler* assembler,
431 compiler::Node* instance_type,
432 CodeStubAssembler::Label* return_string,
433 CodeStubAssembler::Label* return_boolean,
434 CodeStubAssembler::Label* return_number) {
435 assembler->GotoIf(
436 assembler->Int32LessThan(instance_type,
437 assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
438 return_string);
439
440 assembler->GotoIf(assembler->Word32Equal(
441 instance_type, assembler->Int32Constant(ODDBALL_TYPE)),
442 return_boolean);
443
444 assembler->GotoIf(
445 assembler->Word32Equal(instance_type,
446 assembler->Int32Constant(HEAP_NUMBER_TYPE)),
447 return_number);
448 }
449
450 } // namespace
451
452 // ES6 section 19.1.3.6 Object.prototype.toString
453 void Builtins::Generate_ObjectProtoToString(CodeStubAssembler* assembler) {
454 typedef compiler::Node Node;
455 typedef CodeStubAssembler::Label Label;
456 typedef CodeStubAssembler::Variable Variable;
457
458 Label return_undefined(assembler, Label::kDeferred),
459 return_null(assembler, Label::kDeferred),
460 return_arguments(assembler, Label::kDeferred), return_array(assembler),
461 return_api(assembler, Label::kDeferred), return_object(assembler),
462 return_regexp(assembler), return_function(assembler),
463 return_error(assembler), return_date(assembler), return_string(assembler),
464 return_boolean(assembler), return_jsvalue(assembler),
465 return_jsproxy(assembler, Label::kDeferred), return_number(assembler);
466
467 Label if_isproxy(assembler, Label::kDeferred);
468
469 Label checkstringtag(assembler);
470 Label if_tostringtag(assembler), if_notostringtag(assembler);
471
472 Node* receiver = assembler->Parameter(0);
473 Node* context = assembler->Parameter(3);
474
475 assembler->GotoIf(
476 assembler->Word32Equal(receiver, assembler->UndefinedConstant()),
477 &return_undefined);
478
479 assembler->GotoIf(assembler->Word32Equal(receiver, assembler->NullConstant()),
480 &return_null);
481
482 assembler->GotoIf(assembler->WordIsSmi(receiver), &return_number);
483
484 Node* receiver_instance_type = assembler->LoadInstanceType(receiver);
485 ReturnIfPrimitive(assembler, receiver_instance_type, &return_string,
486 &return_boolean, &return_number);
487
488 // for proxies, check IsArray before getting @@toStringTag
489 Variable var_proxy_is_array(assembler, MachineRepresentation::kTagged);
490 var_proxy_is_array.Bind(assembler->BooleanConstant(false));
491
492 assembler->Branch(
493 assembler->Word32Equal(receiver_instance_type,
494 assembler->Int32Constant(JS_PROXY_TYPE)),
495 &if_isproxy, &checkstringtag);
496
497 assembler->Bind(&if_isproxy);
498 {
499 // This can throw
500 var_proxy_is_array.Bind(
501 assembler->CallRuntime(Runtime::kArrayIsArray, context, receiver));
502 assembler->Goto(&checkstringtag);
503 }
504
505 assembler->Bind(&checkstringtag);
506 {
507 Node* to_string_tag_symbol = assembler->HeapConstant(
508 assembler->isolate()->factory()->to_string_tag_symbol());
509
510 GetPropertyStub stub(assembler->isolate());
511 Callable get_property =
512 Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
513 Node* to_string_tag_value = assembler->CallStub(
514 get_property, context, receiver, to_string_tag_symbol);
515
516 IsString(assembler, to_string_tag_value, &if_tostringtag,
517 &if_notostringtag);
518
519 assembler->Bind(&if_tostringtag);
520 ReturnToStringFormat(assembler, context, to_string_tag_value);
521 }
522 assembler->Bind(&if_notostringtag);
523 {
524 size_t const kNumCases = 11;
525 Label* case_labels[kNumCases];
526 int32_t case_values[kNumCases];
527 case_labels[0] = &return_api;
528 case_values[0] = JS_API_OBJECT_TYPE;
529 case_labels[1] = &return_api;
530 case_values[1] = JS_SPECIAL_API_OBJECT_TYPE;
531 case_labels[2] = &return_arguments;
532 case_values[2] = JS_ARGUMENTS_TYPE;
533 case_labels[3] = &return_array;
534 case_values[3] = JS_ARRAY_TYPE;
535 case_labels[4] = &return_function;
536 case_values[4] = JS_BOUND_FUNCTION_TYPE;
537 case_labels[5] = &return_function;
538 case_values[5] = JS_FUNCTION_TYPE;
539 case_labels[6] = &return_error;
540 case_values[6] = JS_ERROR_TYPE;
541 case_labels[7] = &return_date;
542 case_values[7] = JS_DATE_TYPE;
543 case_labels[8] = &return_regexp;
544 case_values[8] = JS_REGEXP_TYPE;
545 case_labels[9] = &return_jsvalue;
546 case_values[9] = JS_VALUE_TYPE;
547 case_labels[10] = &return_jsproxy;
548 case_values[10] = JS_PROXY_TYPE;
549
550 assembler->Switch(receiver_instance_type, &return_object, case_values,
551 case_labels, arraysize(case_values));
552
553 assembler->Bind(&return_undefined);
554 assembler->Return(assembler->HeapConstant(
555 assembler->isolate()->factory()->undefined_to_string()));
556
557 assembler->Bind(&return_null);
558 assembler->Return(assembler->HeapConstant(
559 assembler->isolate()->factory()->null_to_string()));
560
561 assembler->Bind(&return_number);
562 assembler->Return(assembler->HeapConstant(
563 assembler->isolate()->factory()->number_to_string()));
564
565 assembler->Bind(&return_string);
566 assembler->Return(assembler->HeapConstant(
567 assembler->isolate()->factory()->string_to_string()));
568
569 assembler->Bind(&return_boolean);
570 assembler->Return(assembler->HeapConstant(
571 assembler->isolate()->factory()->boolean_to_string()));
572
573 assembler->Bind(&return_arguments);
574 assembler->Return(assembler->HeapConstant(
575 assembler->isolate()->factory()->arguments_to_string()));
576
577 assembler->Bind(&return_array);
578 assembler->Return(assembler->HeapConstant(
579 assembler->isolate()->factory()->array_to_string()));
580
581 assembler->Bind(&return_function);
582 assembler->Return(assembler->HeapConstant(
583 assembler->isolate()->factory()->function_to_string()));
584
585 assembler->Bind(&return_error);
586 assembler->Return(assembler->HeapConstant(
587 assembler->isolate()->factory()->error_to_string()));
588
589 assembler->Bind(&return_date);
590 assembler->Return(assembler->HeapConstant(
591 assembler->isolate()->factory()->date_to_string()));
592
593 assembler->Bind(&return_regexp);
594 assembler->Return(assembler->HeapConstant(
595 assembler->isolate()->factory()->regexp_to_string()));
596
597 assembler->Bind(&return_api);
598 {
599 Node* class_name =
600 assembler->CallRuntime(Runtime::kClassOf, context, receiver);
601 ReturnToStringFormat(assembler, context, class_name);
602 }
603
604 assembler->Bind(&return_jsvalue);
605 {
606 Node* value = assembler->LoadJSValueValue(receiver);
607 assembler->GotoIf(assembler->WordIsSmi(value), &return_number);
608
609 ReturnIfPrimitive(assembler, assembler->LoadInstanceType(value),
610 &return_string, &return_boolean, &return_number);
611 assembler->Goto(&return_object);
612 }
613
614 assembler->Bind(&return_jsproxy);
615 {
616 assembler->GotoIf(assembler->WordEqual(var_proxy_is_array.value(),
617 assembler->BooleanConstant(true)),
618 &return_array);
619
620 Node* map = assembler->LoadMap(receiver);
621
622 // Return object if the proxy {receiver} is not callable.
623 assembler->Branch(
624 assembler->Word32Equal(
625 assembler->Word32And(
626 assembler->LoadMapBitField(map),
627 assembler->Int32Constant(1 << Map::kIsCallable)),
628 assembler->Int32Constant(0)),
629 &return_object, &return_function);
630 }
631
632 // Default
633 assembler->Bind(&return_object);
634 assembler->Return(assembler->HeapConstant(
635 assembler->isolate()->factory()->object_to_string()));
636 }
637 }
638
392 namespace { 639 namespace {
393 640
394 Object* DoArrayPush(Isolate* isolate, BuiltinArguments args) { 641 Object* DoArrayPush(Isolate* isolate, BuiltinArguments args) {
395 HandleScope scope(isolate); 642 HandleScope scope(isolate);
396 Handle<Object> receiver = args.receiver(); 643 Handle<Object> receiver = args.receiver();
397 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) { 644 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) {
398 return CallJsIntrinsic(isolate, isolate->array_push(), args); 645 return CallJsIntrinsic(isolate, isolate->array_push(), args);
399 } 646 }
400 // Fast Elements Path 647 // Fast Elements Path
401 int to_add = args.length() - 1; 648 int to_add = args.length() - 1;
(...skipping 4484 matching lines...) Expand 10 before | Expand all | Expand 10 after
4886 isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1))); 5133 isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1)));
4887 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 5134 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4888 isolate, object, JSReceiver::ToObject(isolate, args.receiver())); 5135 isolate, object, JSReceiver::ToObject(isolate, args.receiver()));
4889 Maybe<PropertyAttributes> maybe = 5136 Maybe<PropertyAttributes> maybe =
4890 JSReceiver::GetOwnPropertyAttributes(object, name); 5137 JSReceiver::GetOwnPropertyAttributes(object, name);
4891 if (!maybe.IsJust()) return isolate->heap()->exception(); 5138 if (!maybe.IsJust()) return isolate->heap()->exception();
4892 if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value(); 5139 if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value();
4893 return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0); 5140 return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
4894 } 5141 }
4895 5142
4896 // ES6 section 19.1.3.6 Object.prototype.toString
4897 BUILTIN(ObjectProtoToString) {
4898 HandleScope scope(isolate);
4899 Handle<Object> object = args.at<Object>(0);
4900 RETURN_RESULT_OR_FAILURE(isolate,
4901 Object::ObjectProtoToString(isolate, object));
4902 }
4903
4904 // ----------------------------------------------------------------------------- 5143 // -----------------------------------------------------------------------------
4905 // ES6 section 19.4 Symbol Objects 5144 // ES6 section 19.4 Symbol Objects
4906 5145
4907 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Call]] case. 5146 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Call]] case.
4908 BUILTIN(SymbolConstructor) { 5147 BUILTIN(SymbolConstructor) {
4909 HandleScope scope(isolate); 5148 HandleScope scope(isolate);
4910 Handle<Symbol> result = isolate->factory()->NewSymbol(); 5149 Handle<Symbol> result = isolate->factory()->NewSymbol();
4911 Handle<Object> description = args.atOrUndefined(isolate, 1); 5150 Handle<Object> description = args.atOrUndefined(isolate, 1);
4912 if (!description->IsUndefined(isolate)) { 5151 if (!description->IsUndefined(isolate)) {
4913 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, description, 5152 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, description,
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after
6923 #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \ 7162 #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \
6924 Handle<Code> Builtins::Name() { \ 7163 Handle<Code> Builtins::Name() { \
6925 Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \ 7164 Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \
6926 return Handle<Code>(code_address); \ 7165 return Handle<Code>(code_address); \
6927 } 7166 }
6928 BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR) 7167 BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR)
6929 #undef DEFINE_BUILTIN_ACCESSOR 7168 #undef DEFINE_BUILTIN_ACCESSOR
6930 7169
6931 } // namespace internal 7170 } // namespace internal
6932 } // namespace v8 7171 } // namespace v8
OLDNEW
« 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