LCOV - code coverage report
Current view: top level - src/builtins - builtins-date-gen.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 120 120 100.0 %
Date: 2019-04-19 Functions: 42 42 100.0 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/builtins/builtins-utils-gen.h"
       6             : #include "src/builtins/builtins.h"
       7             : #include "src/code-stub-assembler.h"
       8             : 
       9             : namespace v8 {
      10             : namespace internal {
      11             : 
      12             : // -----------------------------------------------------------------------------
      13             : // ES6 section 20.3 Date Objects
      14             : 
      15        1064 : class DateBuiltinsAssembler : public CodeStubAssembler {
      16             :  public:
      17             :   explicit DateBuiltinsAssembler(compiler::CodeAssemblerState* state)
      18        1064 :       : CodeStubAssembler(state) {}
      19             : 
      20             :  protected:
      21             :   void Generate_DatePrototype_GetField(Node* context, Node* receiver,
      22             :                                        int field_index);
      23             : };
      24             : 
      25        1064 : void DateBuiltinsAssembler::Generate_DatePrototype_GetField(Node* context,
      26             :                                                             Node* receiver,
      27             :                                                             int field_index) {
      28        2128 :   Label receiver_not_date(this, Label::kDeferred);
      29             : 
      30        2128 :   GotoIf(TaggedIsSmi(receiver), &receiver_not_date);
      31        2128 :   Node* receiver_instance_type = LoadInstanceType(receiver);
      32        2128 :   GotoIfNot(InstanceTypeEqual(receiver_instance_type, JS_DATE_TYPE),
      33        1064 :             &receiver_not_date);
      34             : 
      35             :   // Load the specified date field, falling back to the runtime as necessary.
      36        1064 :   if (field_index == JSDate::kDateValue) {
      37         112 :     Return(LoadObjectField(receiver, JSDate::kValueOffset));
      38             :   } else {
      39         952 :     if (field_index < JSDate::kFirstUncachedField) {
      40         392 :       Label stamp_mismatch(this, Label::kDeferred);
      41             :       Node* date_cache_stamp = Load(
      42             :           MachineType::AnyTagged(),
      43         784 :           ExternalConstant(ExternalReference::date_cache_stamp(isolate())));
      44             : 
      45             :       Node* cache_stamp = LoadObjectField(receiver, JSDate::kCacheStampOffset);
      46         784 :       GotoIf(WordNotEqual(date_cache_stamp, cache_stamp), &stamp_mismatch);
      47         392 :       Return(LoadObjectField(receiver,
      48         784 :                              JSDate::kValueOffset + field_index * kTaggedSize));
      49             : 
      50         392 :       BIND(&stamp_mismatch);
      51             :     }
      52             : 
      53        1904 :     Node* field_index_smi = SmiConstant(field_index);
      54             :     Node* function =
      55        1904 :         ExternalConstant(ExternalReference::get_date_field_function());
      56             :     Node* result = CallCFunction(
      57             :         function, MachineType::AnyTagged(),
      58             :         std::make_pair(MachineType::AnyTagged(), receiver),
      59         952 :         std::make_pair(MachineType::AnyTagged(), field_index_smi));
      60         952 :     Return(result);
      61             :   }
      62             : 
      63             :   // Raise a TypeError if the receiver is not a date.
      64        1064 :   BIND(&receiver_not_date);
      65        1064 :   { ThrowTypeError(context, MessageTemplate::kNotDateObject); }
      66        1064 : }
      67             : 
      68         224 : TF_BUILTIN(DatePrototypeGetDate, DateBuiltinsAssembler) {
      69             :   Node* context = Parameter(Descriptor::kContext);
      70             :   Node* receiver = Parameter(Descriptor::kReceiver);
      71          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDay);
      72          56 : }
      73             : 
      74         224 : TF_BUILTIN(DatePrototypeGetDay, DateBuiltinsAssembler) {
      75             :   Node* context = Parameter(Descriptor::kContext);
      76             :   Node* receiver = Parameter(Descriptor::kReceiver);
      77          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kWeekday);
      78          56 : }
      79             : 
      80         224 : TF_BUILTIN(DatePrototypeGetFullYear, DateBuiltinsAssembler) {
      81             :   Node* context = Parameter(Descriptor::kContext);
      82             :   Node* receiver = Parameter(Descriptor::kReceiver);
      83          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kYear);
      84          56 : }
      85             : 
      86         224 : TF_BUILTIN(DatePrototypeGetHours, DateBuiltinsAssembler) {
      87             :   Node* context = Parameter(Descriptor::kContext);
      88             :   Node* receiver = Parameter(Descriptor::kReceiver);
      89          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kHour);
      90          56 : }
      91             : 
      92         224 : TF_BUILTIN(DatePrototypeGetMilliseconds, DateBuiltinsAssembler) {
      93             :   Node* context = Parameter(Descriptor::kContext);
      94             :   Node* receiver = Parameter(Descriptor::kReceiver);
      95          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMillisecond);
      96          56 : }
      97             : 
      98         224 : TF_BUILTIN(DatePrototypeGetMinutes, DateBuiltinsAssembler) {
      99             :   Node* context = Parameter(Descriptor::kContext);
     100             :   Node* receiver = Parameter(Descriptor::kReceiver);
     101          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMinute);
     102          56 : }
     103             : 
     104         224 : TF_BUILTIN(DatePrototypeGetMonth, DateBuiltinsAssembler) {
     105             :   Node* context = Parameter(Descriptor::kContext);
     106             :   Node* receiver = Parameter(Descriptor::kReceiver);
     107          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMonth);
     108          56 : }
     109             : 
     110         224 : TF_BUILTIN(DatePrototypeGetSeconds, DateBuiltinsAssembler) {
     111             :   Node* context = Parameter(Descriptor::kContext);
     112             :   Node* receiver = Parameter(Descriptor::kReceiver);
     113          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kSecond);
     114          56 : }
     115             : 
     116         224 : TF_BUILTIN(DatePrototypeGetTime, DateBuiltinsAssembler) {
     117             :   Node* context = Parameter(Descriptor::kContext);
     118             :   Node* receiver = Parameter(Descriptor::kReceiver);
     119          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDateValue);
     120          56 : }
     121             : 
     122         224 : TF_BUILTIN(DatePrototypeGetTimezoneOffset, DateBuiltinsAssembler) {
     123             :   Node* context = Parameter(Descriptor::kContext);
     124             :   Node* receiver = Parameter(Descriptor::kReceiver);
     125          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kTimezoneOffset);
     126          56 : }
     127             : 
     128         224 : TF_BUILTIN(DatePrototypeGetUTCDate, DateBuiltinsAssembler) {
     129             :   Node* context = Parameter(Descriptor::kContext);
     130             :   Node* receiver = Parameter(Descriptor::kReceiver);
     131          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDayUTC);
     132          56 : }
     133             : 
     134         224 : TF_BUILTIN(DatePrototypeGetUTCDay, DateBuiltinsAssembler) {
     135             :   Node* context = Parameter(Descriptor::kContext);
     136             :   Node* receiver = Parameter(Descriptor::kReceiver);
     137          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kWeekdayUTC);
     138          56 : }
     139             : 
     140         224 : TF_BUILTIN(DatePrototypeGetUTCFullYear, DateBuiltinsAssembler) {
     141             :   Node* context = Parameter(Descriptor::kContext);
     142             :   Node* receiver = Parameter(Descriptor::kReceiver);
     143          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kYearUTC);
     144          56 : }
     145             : 
     146         224 : TF_BUILTIN(DatePrototypeGetUTCHours, DateBuiltinsAssembler) {
     147             :   Node* context = Parameter(Descriptor::kContext);
     148             :   Node* receiver = Parameter(Descriptor::kReceiver);
     149          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kHourUTC);
     150          56 : }
     151             : 
     152         224 : TF_BUILTIN(DatePrototypeGetUTCMilliseconds, DateBuiltinsAssembler) {
     153             :   Node* context = Parameter(Descriptor::kContext);
     154             :   Node* receiver = Parameter(Descriptor::kReceiver);
     155          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMillisecondUTC);
     156          56 : }
     157             : 
     158         224 : TF_BUILTIN(DatePrototypeGetUTCMinutes, DateBuiltinsAssembler) {
     159             :   Node* context = Parameter(Descriptor::kContext);
     160             :   Node* receiver = Parameter(Descriptor::kReceiver);
     161          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMinuteUTC);
     162          56 : }
     163             : 
     164         224 : TF_BUILTIN(DatePrototypeGetUTCMonth, DateBuiltinsAssembler) {
     165             :   Node* context = Parameter(Descriptor::kContext);
     166             :   Node* receiver = Parameter(Descriptor::kReceiver);
     167          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMonthUTC);
     168          56 : }
     169             : 
     170         224 : TF_BUILTIN(DatePrototypeGetUTCSeconds, DateBuiltinsAssembler) {
     171             :   Node* context = Parameter(Descriptor::kContext);
     172             :   Node* receiver = Parameter(Descriptor::kReceiver);
     173          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kSecondUTC);
     174          56 : }
     175             : 
     176         224 : TF_BUILTIN(DatePrototypeValueOf, DateBuiltinsAssembler) {
     177             :   Node* context = Parameter(Descriptor::kContext);
     178             :   Node* receiver = Parameter(Descriptor::kReceiver);
     179          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDateValue);
     180          56 : }
     181             : 
     182         168 : TF_BUILTIN(DatePrototypeToPrimitive, CodeStubAssembler) {
     183             :   Node* context = Parameter(Descriptor::kContext);
     184             :   Node* receiver = Parameter(Descriptor::kReceiver);
     185             :   Node* hint = Parameter(Descriptor::kHint);
     186             : 
     187             :   // Check if the {receiver} is actually a JSReceiver.
     188          56 :   Label receiver_is_invalid(this, Label::kDeferred);
     189         112 :   GotoIf(TaggedIsSmi(receiver), &receiver_is_invalid);
     190         112 :   GotoIfNot(IsJSReceiver(receiver), &receiver_is_invalid);
     191             : 
     192             :   // Dispatch to the appropriate OrdinaryToPrimitive builtin.
     193          56 :   Label hint_is_number(this), hint_is_string(this),
     194          56 :       hint_is_invalid(this, Label::kDeferred);
     195             : 
     196             :   // Fast cases for internalized strings.
     197         112 :   Node* number_string = LoadRoot(RootIndex::knumber_string);
     198         112 :   GotoIf(WordEqual(hint, number_string), &hint_is_number);
     199         112 :   Node* default_string = LoadRoot(RootIndex::kdefault_string);
     200         112 :   GotoIf(WordEqual(hint, default_string), &hint_is_string);
     201         112 :   Node* string_string = LoadRoot(RootIndex::kstring_string);
     202         112 :   GotoIf(WordEqual(hint, string_string), &hint_is_string);
     203             : 
     204             :   // Slow-case with actual string comparisons.
     205         112 :   GotoIf(TaggedIsSmi(hint), &hint_is_invalid);
     206         112 :   GotoIfNot(IsString(hint), &hint_is_invalid);
     207          56 :   GotoIf(WordEqual(
     208             :              CallBuiltin(Builtins::kStringEqual, context, hint, number_string),
     209         168 :              TrueConstant()),
     210          56 :          &hint_is_number);
     211          56 :   GotoIf(WordEqual(
     212             :              CallBuiltin(Builtins::kStringEqual, context, hint, default_string),
     213         168 :              TrueConstant()),
     214          56 :          &hint_is_string);
     215          56 :   GotoIf(WordEqual(
     216             :              CallBuiltin(Builtins::kStringEqual, context, hint, string_string),
     217         168 :              TrueConstant()),
     218          56 :          &hint_is_string);
     219          56 :   Goto(&hint_is_invalid);
     220             : 
     221             :   // Use the OrdinaryToPrimitive builtin to convert to a Number.
     222          56 :   BIND(&hint_is_number);
     223             :   {
     224             :     Callable callable = CodeFactory::OrdinaryToPrimitive(
     225          56 :         isolate(), OrdinaryToPrimitiveHint::kNumber);
     226         112 :     Node* result = CallStub(callable, context, receiver);
     227          56 :     Return(result);
     228             :   }
     229             : 
     230             :   // Use the OrdinaryToPrimitive builtin to convert to a String.
     231          56 :   BIND(&hint_is_string);
     232             :   {
     233             :     Callable callable = CodeFactory::OrdinaryToPrimitive(
     234          56 :         isolate(), OrdinaryToPrimitiveHint::kString);
     235         112 :     Node* result = CallStub(callable, context, receiver);
     236          56 :     Return(result);
     237             :   }
     238             : 
     239             :   // Raise a TypeError if the {hint} is invalid.
     240          56 :   BIND(&hint_is_invalid);
     241          56 :   { ThrowTypeError(context, MessageTemplate::kInvalidHint, hint); }
     242             : 
     243             :   // Raise a TypeError if the {receiver} is not a JSReceiver instance.
     244          56 :   BIND(&receiver_is_invalid);
     245             :   {
     246             :     ThrowTypeError(context, MessageTemplate::kIncompatibleMethodReceiver,
     247         112 :                    StringConstant("Date.prototype [ @@toPrimitive ]"),
     248          56 :                    receiver);
     249             :   }
     250          56 : }
     251             : 
     252             : }  // namespace internal
     253       59480 : }  // namespace v8

Generated by: LCOV version 1.10