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: 2017-10-20 Functions: 41 41 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         589 :       : CodeStubAssembler(state) {}
      19             : 
      20             :  protected:
      21             :   void Generate_DatePrototype_GetField(Node* context, Node* receiver,
      22             :                                        int field_index);
      23             : };
      24             : 
      25         589 : void DateBuiltinsAssembler::Generate_DatePrototype_GetField(Node* context,
      26             :                                                             Node* receiver,
      27             :                                                             int field_index) {
      28         589 :   Label receiver_not_date(this, Label::kDeferred);
      29             : 
      30        1178 :   GotoIf(TaggedIsSmi(receiver), &receiver_not_date);
      31        1178 :   Node* receiver_instance_type = LoadInstanceType(receiver);
      32             :   GotoIfNot(InstanceTypeEqual(receiver_instance_type, JS_DATE_TYPE),
      33        1178 :             &receiver_not_date);
      34             : 
      35             :   // Load the specified date field, falling back to the runtime as necessary.
      36         589 :   if (field_index == JSDate::kDateValue) {
      37          62 :     Return(LoadObjectField(receiver, JSDate::kValueOffset));
      38             :   } else {
      39         527 :     if (field_index < JSDate::kFirstUncachedField) {
      40             :       Label stamp_mismatch(this, Label::kDeferred);
      41             :       Node* date_cache_stamp = Load(
      42             :           MachineType::AnyTagged(),
      43         434 :           ExternalConstant(ExternalReference::date_cache_stamp(isolate())));
      44             : 
      45             :       Node* cache_stamp = LoadObjectField(receiver, JSDate::kCacheStampOffset);
      46         434 :       GotoIf(WordNotEqual(date_cache_stamp, cache_stamp), &stamp_mismatch);
      47             :       Return(LoadObjectField(
      48         434 :           receiver, JSDate::kValueOffset + field_index * kPointerSize));
      49             : 
      50         217 :       BIND(&stamp_mismatch);
      51             :     }
      52             : 
      53        1054 :     Node* field_index_smi = SmiConstant(field_index);
      54             :     Node* function =
      55        1054 :         ExternalConstant(ExternalReference::get_date_field_function(isolate()));
      56             :     Node* result = CallCFunction2(
      57             :         MachineType::AnyTagged(), MachineType::AnyTagged(),
      58         527 :         MachineType::AnyTagged(), function, receiver, field_index_smi);
      59         527 :     Return(result);
      60             :   }
      61             : 
      62             :   // Raise a TypeError if the receiver is not a date.
      63         589 :   BIND(&receiver_not_date);
      64             :   {
      65             :     CallRuntime(Runtime::kThrowNotDateError, context);
      66         589 :     Unreachable();
      67         589 :   }
      68         589 : }
      69             : 
      70         124 : TF_BUILTIN(DatePrototypeGetDate, DateBuiltinsAssembler) {
      71             :   Node* context = Parameter(Descriptor::kContext);
      72             :   Node* receiver = Parameter(Descriptor::kReceiver);
      73          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDay);
      74          31 : }
      75             : 
      76         124 : TF_BUILTIN(DatePrototypeGetDay, DateBuiltinsAssembler) {
      77             :   Node* context = Parameter(Descriptor::kContext);
      78             :   Node* receiver = Parameter(Descriptor::kReceiver);
      79          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kWeekday);
      80          31 : }
      81             : 
      82         124 : TF_BUILTIN(DatePrototypeGetFullYear, DateBuiltinsAssembler) {
      83             :   Node* context = Parameter(Descriptor::kContext);
      84             :   Node* receiver = Parameter(Descriptor::kReceiver);
      85          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kYear);
      86          31 : }
      87             : 
      88         124 : TF_BUILTIN(DatePrototypeGetHours, DateBuiltinsAssembler) {
      89             :   Node* context = Parameter(Descriptor::kContext);
      90             :   Node* receiver = Parameter(Descriptor::kReceiver);
      91          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kHour);
      92          31 : }
      93             : 
      94         124 : TF_BUILTIN(DatePrototypeGetMilliseconds, DateBuiltinsAssembler) {
      95             :   Node* context = Parameter(Descriptor::kContext);
      96             :   Node* receiver = Parameter(Descriptor::kReceiver);
      97          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMillisecond);
      98          31 : }
      99             : 
     100         124 : TF_BUILTIN(DatePrototypeGetMinutes, DateBuiltinsAssembler) {
     101             :   Node* context = Parameter(Descriptor::kContext);
     102             :   Node* receiver = Parameter(Descriptor::kReceiver);
     103          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMinute);
     104          31 : }
     105             : 
     106         124 : TF_BUILTIN(DatePrototypeGetMonth, DateBuiltinsAssembler) {
     107             :   Node* context = Parameter(Descriptor::kContext);
     108             :   Node* receiver = Parameter(Descriptor::kReceiver);
     109          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMonth);
     110          31 : }
     111             : 
     112         124 : TF_BUILTIN(DatePrototypeGetSeconds, DateBuiltinsAssembler) {
     113             :   Node* context = Parameter(Descriptor::kContext);
     114             :   Node* receiver = Parameter(Descriptor::kReceiver);
     115          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kSecond);
     116          31 : }
     117             : 
     118         124 : TF_BUILTIN(DatePrototypeGetTime, DateBuiltinsAssembler) {
     119             :   Node* context = Parameter(Descriptor::kContext);
     120             :   Node* receiver = Parameter(Descriptor::kReceiver);
     121          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDateValue);
     122          31 : }
     123             : 
     124         124 : TF_BUILTIN(DatePrototypeGetTimezoneOffset, DateBuiltinsAssembler) {
     125             :   Node* context = Parameter(Descriptor::kContext);
     126             :   Node* receiver = Parameter(Descriptor::kReceiver);
     127          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kTimezoneOffset);
     128          31 : }
     129             : 
     130         124 : TF_BUILTIN(DatePrototypeGetUTCDate, DateBuiltinsAssembler) {
     131             :   Node* context = Parameter(Descriptor::kContext);
     132             :   Node* receiver = Parameter(Descriptor::kReceiver);
     133          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDayUTC);
     134          31 : }
     135             : 
     136         124 : TF_BUILTIN(DatePrototypeGetUTCDay, DateBuiltinsAssembler) {
     137             :   Node* context = Parameter(Descriptor::kContext);
     138             :   Node* receiver = Parameter(Descriptor::kReceiver);
     139          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kWeekdayUTC);
     140          31 : }
     141             : 
     142         124 : TF_BUILTIN(DatePrototypeGetUTCFullYear, DateBuiltinsAssembler) {
     143             :   Node* context = Parameter(Descriptor::kContext);
     144             :   Node* receiver = Parameter(Descriptor::kReceiver);
     145          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kYearUTC);
     146          31 : }
     147             : 
     148         124 : TF_BUILTIN(DatePrototypeGetUTCHours, DateBuiltinsAssembler) {
     149             :   Node* context = Parameter(Descriptor::kContext);
     150             :   Node* receiver = Parameter(Descriptor::kReceiver);
     151          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kHourUTC);
     152          31 : }
     153             : 
     154         124 : TF_BUILTIN(DatePrototypeGetUTCMilliseconds, DateBuiltinsAssembler) {
     155             :   Node* context = Parameter(Descriptor::kContext);
     156             :   Node* receiver = Parameter(Descriptor::kReceiver);
     157          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMillisecondUTC);
     158          31 : }
     159             : 
     160         124 : TF_BUILTIN(DatePrototypeGetUTCMinutes, DateBuiltinsAssembler) {
     161             :   Node* context = Parameter(Descriptor::kContext);
     162             :   Node* receiver = Parameter(Descriptor::kReceiver);
     163          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMinuteUTC);
     164          31 : }
     165             : 
     166         124 : TF_BUILTIN(DatePrototypeGetUTCMonth, DateBuiltinsAssembler) {
     167             :   Node* context = Parameter(Descriptor::kContext);
     168             :   Node* receiver = Parameter(Descriptor::kReceiver);
     169          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kMonthUTC);
     170          31 : }
     171             : 
     172         124 : TF_BUILTIN(DatePrototypeGetUTCSeconds, DateBuiltinsAssembler) {
     173             :   Node* context = Parameter(Descriptor::kContext);
     174             :   Node* receiver = Parameter(Descriptor::kReceiver);
     175          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kSecondUTC);
     176          31 : }
     177             : 
     178         124 : TF_BUILTIN(DatePrototypeValueOf, DateBuiltinsAssembler) {
     179             :   Node* context = Parameter(Descriptor::kContext);
     180             :   Node* receiver = Parameter(Descriptor::kReceiver);
     181          31 :   Generate_DatePrototype_GetField(context, receiver, JSDate::kDateValue);
     182          31 : }
     183             : 
     184          93 : TF_BUILTIN(DatePrototypeToPrimitive, CodeStubAssembler) {
     185             :   Node* context = Parameter(Descriptor::kContext);
     186             :   Node* receiver = Parameter(Descriptor::kReceiver);
     187             :   Node* hint = Parameter(Descriptor::kHint);
     188             : 
     189             :   // Check if the {receiver} is actually a JSReceiver.
     190             :   Label receiver_is_invalid(this, Label::kDeferred);
     191          62 :   GotoIf(TaggedIsSmi(receiver), &receiver_is_invalid);
     192          62 :   GotoIfNot(IsJSReceiver(receiver), &receiver_is_invalid);
     193             : 
     194             :   // Dispatch to the appropriate OrdinaryToPrimitive builtin.
     195          31 :   Label hint_is_number(this), hint_is_string(this),
     196          31 :       hint_is_invalid(this, Label::kDeferred);
     197             : 
     198             :   // Fast cases for internalized strings.
     199          62 :   Node* number_string = LoadRoot(Heap::knumber_stringRootIndex);
     200          62 :   GotoIf(WordEqual(hint, number_string), &hint_is_number);
     201          62 :   Node* default_string = LoadRoot(Heap::kdefault_stringRootIndex);
     202          62 :   GotoIf(WordEqual(hint, default_string), &hint_is_string);
     203          62 :   Node* string_string = LoadRoot(Heap::kstring_stringRootIndex);
     204          62 :   GotoIf(WordEqual(hint, string_string), &hint_is_string);
     205             : 
     206             :   // Slow-case with actual string comparisons.
     207          62 :   GotoIf(TaggedIsSmi(hint), &hint_is_invalid);
     208          62 :   GotoIfNot(IsString(hint), &hint_is_invalid);
     209             :   GotoIf(WordEqual(
     210             :              CallBuiltin(Builtins::kStringEqual, context, hint, number_string),
     211          93 :              TrueConstant()),
     212          31 :          &hint_is_number);
     213             :   GotoIf(WordEqual(
     214             :              CallBuiltin(Builtins::kStringEqual, context, hint, default_string),
     215          93 :              TrueConstant()),
     216          31 :          &hint_is_string);
     217             :   GotoIf(WordEqual(
     218             :              CallBuiltin(Builtins::kStringEqual, context, hint, string_string),
     219          93 :              TrueConstant()),
     220          31 :          &hint_is_string);
     221          31 :   Goto(&hint_is_invalid);
     222             : 
     223             :   // Use the OrdinaryToPrimitive builtin to convert to a Number.
     224          31 :   BIND(&hint_is_number);
     225             :   {
     226             :     Callable callable = CodeFactory::OrdinaryToPrimitive(
     227          31 :         isolate(), OrdinaryToPrimitiveHint::kNumber);
     228          31 :     Node* result = CallStub(callable, context, receiver);
     229          31 :     Return(result);
     230             :   }
     231             : 
     232             :   // Use the OrdinaryToPrimitive builtin to convert to a String.
     233          31 :   BIND(&hint_is_string);
     234             :   {
     235             :     Callable callable = CodeFactory::OrdinaryToPrimitive(
     236          31 :         isolate(), OrdinaryToPrimitiveHint::kString);
     237          31 :     Node* result = CallStub(callable, context, receiver);
     238          31 :     Return(result);
     239             :   }
     240             : 
     241             :   // Raise a TypeError if the {hint} is invalid.
     242          31 :   BIND(&hint_is_invalid);
     243             :   {
     244             :     CallRuntime(Runtime::kThrowInvalidHint, context, hint);
     245          31 :     Unreachable();
     246             :   }
     247             : 
     248             :   // Raise a TypeError if the {receiver} is not a JSReceiver instance.
     249          31 :   BIND(&receiver_is_invalid);
     250             :   {
     251             :     CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
     252          31 :                 StringConstant("Date.prototype [ @@toPrimitive ]"), receiver);
     253          31 :     Unreachable();
     254          31 :   }
     255          31 : }
     256             : 
     257             : }  // namespace internal
     258             : }  // namespace v8

Generated by: LCOV version 1.10