LCOV - code coverage report
Current view: top level - src/builtins - builtins-date-gen.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 113 113 100.0 %
Date: 2019-01-20 Functions: 43 43 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             : 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        1064 :   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        1064 :   GotoIfNot(InstanceTypeEqual(receiver_instance_type, JS_DATE_TYPE),
      33        2128 :             &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             :       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             :       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 = CallCFunction2(
      57             :         MachineType::AnyTagged(), MachineType::AnyTagged(),
      58         952 :         MachineType::AnyTagged(), function, receiver, field_index_smi);
      59         952 :     Return(result);
      60             :   }
      61             : 
      62             :   // Raise a TypeError if the receiver is not a date.
      63        1064 :   BIND(&receiver_not_date);
      64        1064 :   { ThrowTypeError(context, MessageTemplate::kNotDateObject); }
      65        1064 : }
      66             : 
      67         224 : TF_BUILTIN(DatePrototypeGetDate, DateBuiltinsAssembler) {
      68             :   Node* context = Parameter(Descriptor::kContext);
      69             :   Node* receiver = Parameter(Descriptor::kReceiver);
      70          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDay);
      71          56 : }
      72             : 
      73         224 : TF_BUILTIN(DatePrototypeGetDay, DateBuiltinsAssembler) {
      74             :   Node* context = Parameter(Descriptor::kContext);
      75             :   Node* receiver = Parameter(Descriptor::kReceiver);
      76          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kWeekday);
      77          56 : }
      78             : 
      79         224 : TF_BUILTIN(DatePrototypeGetFullYear, DateBuiltinsAssembler) {
      80             :   Node* context = Parameter(Descriptor::kContext);
      81             :   Node* receiver = Parameter(Descriptor::kReceiver);
      82          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kYear);
      83          56 : }
      84             : 
      85         224 : TF_BUILTIN(DatePrototypeGetHours, DateBuiltinsAssembler) {
      86             :   Node* context = Parameter(Descriptor::kContext);
      87             :   Node* receiver = Parameter(Descriptor::kReceiver);
      88          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kHour);
      89          56 : }
      90             : 
      91         224 : TF_BUILTIN(DatePrototypeGetMilliseconds, DateBuiltinsAssembler) {
      92             :   Node* context = Parameter(Descriptor::kContext);
      93             :   Node* receiver = Parameter(Descriptor::kReceiver);
      94          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMillisecond);
      95          56 : }
      96             : 
      97         224 : TF_BUILTIN(DatePrototypeGetMinutes, DateBuiltinsAssembler) {
      98             :   Node* context = Parameter(Descriptor::kContext);
      99             :   Node* receiver = Parameter(Descriptor::kReceiver);
     100          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMinute);
     101          56 : }
     102             : 
     103         224 : TF_BUILTIN(DatePrototypeGetMonth, DateBuiltinsAssembler) {
     104             :   Node* context = Parameter(Descriptor::kContext);
     105             :   Node* receiver = Parameter(Descriptor::kReceiver);
     106          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMonth);
     107          56 : }
     108             : 
     109         224 : TF_BUILTIN(DatePrototypeGetSeconds, DateBuiltinsAssembler) {
     110             :   Node* context = Parameter(Descriptor::kContext);
     111             :   Node* receiver = Parameter(Descriptor::kReceiver);
     112          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kSecond);
     113          56 : }
     114             : 
     115         224 : TF_BUILTIN(DatePrototypeGetTime, DateBuiltinsAssembler) {
     116             :   Node* context = Parameter(Descriptor::kContext);
     117             :   Node* receiver = Parameter(Descriptor::kReceiver);
     118          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDateValue);
     119          56 : }
     120             : 
     121         224 : TF_BUILTIN(DatePrototypeGetTimezoneOffset, DateBuiltinsAssembler) {
     122             :   Node* context = Parameter(Descriptor::kContext);
     123             :   Node* receiver = Parameter(Descriptor::kReceiver);
     124          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kTimezoneOffset);
     125          56 : }
     126             : 
     127         224 : TF_BUILTIN(DatePrototypeGetUTCDate, DateBuiltinsAssembler) {
     128             :   Node* context = Parameter(Descriptor::kContext);
     129             :   Node* receiver = Parameter(Descriptor::kReceiver);
     130          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDayUTC);
     131          56 : }
     132             : 
     133         224 : TF_BUILTIN(DatePrototypeGetUTCDay, DateBuiltinsAssembler) {
     134             :   Node* context = Parameter(Descriptor::kContext);
     135             :   Node* receiver = Parameter(Descriptor::kReceiver);
     136          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kWeekdayUTC);
     137          56 : }
     138             : 
     139         224 : TF_BUILTIN(DatePrototypeGetUTCFullYear, DateBuiltinsAssembler) {
     140             :   Node* context = Parameter(Descriptor::kContext);
     141             :   Node* receiver = Parameter(Descriptor::kReceiver);
     142          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kYearUTC);
     143          56 : }
     144             : 
     145         224 : TF_BUILTIN(DatePrototypeGetUTCHours, DateBuiltinsAssembler) {
     146             :   Node* context = Parameter(Descriptor::kContext);
     147             :   Node* receiver = Parameter(Descriptor::kReceiver);
     148          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kHourUTC);
     149          56 : }
     150             : 
     151         224 : TF_BUILTIN(DatePrototypeGetUTCMilliseconds, DateBuiltinsAssembler) {
     152             :   Node* context = Parameter(Descriptor::kContext);
     153             :   Node* receiver = Parameter(Descriptor::kReceiver);
     154          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMillisecondUTC);
     155          56 : }
     156             : 
     157         224 : TF_BUILTIN(DatePrototypeGetUTCMinutes, DateBuiltinsAssembler) {
     158             :   Node* context = Parameter(Descriptor::kContext);
     159             :   Node* receiver = Parameter(Descriptor::kReceiver);
     160          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMinuteUTC);
     161          56 : }
     162             : 
     163         224 : TF_BUILTIN(DatePrototypeGetUTCMonth, DateBuiltinsAssembler) {
     164             :   Node* context = Parameter(Descriptor::kContext);
     165             :   Node* receiver = Parameter(Descriptor::kReceiver);
     166          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMonthUTC);
     167          56 : }
     168             : 
     169         224 : TF_BUILTIN(DatePrototypeGetUTCSeconds, DateBuiltinsAssembler) {
     170             :   Node* context = Parameter(Descriptor::kContext);
     171             :   Node* receiver = Parameter(Descriptor::kReceiver);
     172          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kSecondUTC);
     173          56 : }
     174             : 
     175         224 : TF_BUILTIN(DatePrototypeValueOf, DateBuiltinsAssembler) {
     176             :   Node* context = Parameter(Descriptor::kContext);
     177             :   Node* receiver = Parameter(Descriptor::kReceiver);
     178          56 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDateValue);
     179          56 : }
     180             : 
     181         168 : TF_BUILTIN(DatePrototypeToPrimitive, CodeStubAssembler) {
     182             :   Node* context = Parameter(Descriptor::kContext);
     183             :   Node* receiver = Parameter(Descriptor::kReceiver);
     184             :   Node* hint = Parameter(Descriptor::kHint);
     185             : 
     186             :   // Check if the {receiver} is actually a JSReceiver.
     187             :   Label receiver_is_invalid(this, Label::kDeferred);
     188         112 :   GotoIf(TaggedIsSmi(receiver), &receiver_is_invalid);
     189         112 :   GotoIfNot(IsJSReceiver(receiver), &receiver_is_invalid);
     190             : 
     191             :   // Dispatch to the appropriate OrdinaryToPrimitive builtin.
     192          56 :   Label hint_is_number(this), hint_is_string(this),
     193          56 :       hint_is_invalid(this, Label::kDeferred);
     194             : 
     195             :   // Fast cases for internalized strings.
     196         112 :   Node* number_string = LoadRoot(RootIndex::knumber_string);
     197         112 :   GotoIf(WordEqual(hint, number_string), &hint_is_number);
     198         112 :   Node* default_string = LoadRoot(RootIndex::kdefault_string);
     199         112 :   GotoIf(WordEqual(hint, default_string), &hint_is_string);
     200         112 :   Node* string_string = LoadRoot(RootIndex::kstring_string);
     201         112 :   GotoIf(WordEqual(hint, string_string), &hint_is_string);
     202             : 
     203             :   // Slow-case with actual string comparisons.
     204         112 :   GotoIf(TaggedIsSmi(hint), &hint_is_invalid);
     205         112 :   GotoIfNot(IsString(hint), &hint_is_invalid);
     206             :   GotoIf(WordEqual(
     207             :              CallBuiltin(Builtins::kStringEqual, context, hint, number_string),
     208         168 :              TrueConstant()),
     209          56 :          &hint_is_number);
     210             :   GotoIf(WordEqual(
     211             :              CallBuiltin(Builtins::kStringEqual, context, hint, default_string),
     212         168 :              TrueConstant()),
     213          56 :          &hint_is_string);
     214             :   GotoIf(WordEqual(
     215             :              CallBuiltin(Builtins::kStringEqual, context, hint, string_string),
     216         168 :              TrueConstant()),
     217          56 :          &hint_is_string);
     218          56 :   Goto(&hint_is_invalid);
     219             : 
     220             :   // Use the OrdinaryToPrimitive builtin to convert to a Number.
     221          56 :   BIND(&hint_is_number);
     222             :   {
     223             :     Callable callable = CodeFactory::OrdinaryToPrimitive(
     224          56 :         isolate(), OrdinaryToPrimitiveHint::kNumber);
     225         112 :     Node* result = CallStub(callable, context, receiver);
     226          56 :     Return(result);
     227             :   }
     228             : 
     229             :   // Use the OrdinaryToPrimitive builtin to convert to a String.
     230          56 :   BIND(&hint_is_string);
     231             :   {
     232             :     Callable callable = CodeFactory::OrdinaryToPrimitive(
     233          56 :         isolate(), OrdinaryToPrimitiveHint::kString);
     234         112 :     Node* result = CallStub(callable, context, receiver);
     235          56 :     Return(result);
     236             :   }
     237             : 
     238             :   // Raise a TypeError if the {hint} is invalid.
     239          56 :   BIND(&hint_is_invalid);
     240          56 :   { ThrowTypeError(context, MessageTemplate::kInvalidHint, hint); }
     241             : 
     242             :   // Raise a TypeError if the {receiver} is not a JSReceiver instance.
     243          56 :   BIND(&receiver_is_invalid);
     244             :   {
     245             :     ThrowTypeError(context, MessageTemplate::kIncompatibleMethodReceiver,
     246             :                    StringConstant("Date.prototype [ @@toPrimitive ]"),
     247         112 :                    receiver);
     248          56 :   }
     249          56 : }
     250             : 
     251             : }  // namespace internal
     252       94089 : }  // namespace v8

Generated by: LCOV version 1.10