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

Generated by: LCOV version 1.10