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