1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ecmascript/compiler/builtins/builtins_stubs.h"
17
18 #include "ecmascript/base/number_helper.h"
19 #include "ecmascript/compiler/builtins/builtins_array_stub_builder.h"
20 #include "ecmascript/compiler/builtins/builtins_call_signature.h"
21 #include "ecmascript/compiler/builtins/builtins_dataview_stub_builder.h"
22 #include "ecmascript/compiler/builtins/builtins_function_stub_builder.h"
23 #include "ecmascript/compiler/builtins/builtins_string_stub_builder.h"
24 #include "ecmascript/compiler/builtins/builtins_number_stub_builder.h"
25 #include "ecmascript/compiler/builtins/builtins_proxy_stub_builder.h"
26 #include "ecmascript/compiler/builtins/builtins_reflect_stub_builder.h"
27 #include "ecmascript/compiler/builtins/builtins_typedarray_stub_builder.h"
28 #include "ecmascript/compiler/builtins/containers_vector_stub_builder.h"
29 #include "ecmascript/compiler/builtins/containers_stub_builder.h"
30 #include "ecmascript/compiler/builtins/builtins_collection_stub_builder.h"
31 #include "ecmascript/compiler/builtins/builtins_object_stub_builder.h"
32 #include "ecmascript/compiler/codegen/llvm/llvm_ir_builder.h"
33 #include "ecmascript/compiler/interpreter_stub-inl.h"
34 #include "ecmascript/compiler/new_object_stub_builder.h"
35 #include "ecmascript/compiler/stub_builder-inl.h"
36 #include "ecmascript/compiler/stub_builder.h"
37 #include "ecmascript/compiler/hash_stub_builder.h"
38 #include "ecmascript/compiler/variable_type.h"
39 #include "ecmascript/js_dataview.h"
40 #include "ecmascript/js_date.h"
41 #include "ecmascript/js_primitive_ref.h"
42 #include "ecmascript/linked_hash_table.h"
43 #include "ecmascript/js_set.h"
44 #include "ecmascript/js_map.h"
45
46 namespace panda::ecmascript::kungfu {
47 #if ECMASCRIPT_ENABLE_BUILTIN_LOG
48 #define DECLARE_BUILTINS(name) \
49 void name##StubBuilder::GenerateCircuit() \
50 { \
51 GateRef glue = PtrArgument(static_cast<size_t>(BuiltinsArgs::GLUE)); \
52 GateRef nativeCode = PtrArgument(static_cast<size_t>(BuiltinsArgs::NATIVECODE)); \
53 GateRef func = TaggedArgument(static_cast<size_t>(BuiltinsArgs::FUNC)); \
54 GateRef newTarget = TaggedArgument(static_cast<size_t>(BuiltinsArgs::NEWTARGET)); \
55 GateRef thisValue = TaggedArgument(static_cast<size_t>(BuiltinsArgs::THISVALUE)); \
56 GateRef numArgs = PtrArgument(static_cast<size_t>(BuiltinsArgs::NUMARGS)); \
57 DebugPrint(glue, { Int32(GET_MESSAGE_STRING_ID(name)) }); \
58 GenerateCircuitImpl(glue, nativeCode, func, newTarget, thisValue, numArgs); \
59 } \
60 void name##StubBuilder::GenerateCircuitImpl(GateRef glue, GateRef nativeCode, GateRef func, \
61 GateRef newTarget, GateRef thisValue, GateRef numArgs)
62 #else
63 #ifndef NDEBUG
64 #define DECLARE_BUILTINS(name) \
65 void name##StubBuilder::GenerateCircuit() \
66 { \
67 GateRef glue = PtrArgument(static_cast<size_t>(BuiltinsArgs::GLUE)); \
68 GateRef nativeCode = PtrArgument(static_cast<size_t>(BuiltinsArgs::NATIVECODE)); \
69 GateRef func = TaggedArgument(static_cast<size_t>(BuiltinsArgs::FUNC)); \
70 GateRef newTarget = TaggedArgument(static_cast<size_t>(BuiltinsArgs::NEWTARGET)); \
71 GateRef thisValue = TaggedArgument(static_cast<size_t>(BuiltinsArgs::THISVALUE)); \
72 GateRef numArgs = PtrArgument(static_cast<size_t>(BuiltinsArgs::NUMARGS)); \
73 CallRuntime(glue, RTSTUB_ID(ForceGC), {}); \
74 GenerateCircuitImpl(glue, nativeCode, func, newTarget, thisValue, numArgs); \
75 } \
76 void name##StubBuilder::GenerateCircuitImpl(GateRef glue, GateRef nativeCode, GateRef func, \
77 GateRef newTarget, GateRef thisValue, GateRef numArgs)
78 #else
79 #define DECLARE_BUILTINS(name) \
80 void name##StubBuilder::GenerateCircuit() \
81 { \
82 GateRef glue = PtrArgument(static_cast<size_t>(BuiltinsArgs::GLUE)); \
83 GateRef nativeCode = PtrArgument(static_cast<size_t>(BuiltinsArgs::NATIVECODE)); \
84 GateRef func = TaggedArgument(static_cast<size_t>(BuiltinsArgs::FUNC)); \
85 GateRef newTarget = TaggedArgument(static_cast<size_t>(BuiltinsArgs::NEWTARGET)); \
86 GateRef thisValue = TaggedArgument(static_cast<size_t>(BuiltinsArgs::THISVALUE)); \
87 GateRef numArgs = PtrArgument(static_cast<size_t>(BuiltinsArgs::NUMARGS)); \
88 GenerateCircuitImpl(glue, nativeCode, func, newTarget, thisValue, numArgs); \
89 } \
90 void name##StubBuilder::GenerateCircuitImpl(GateRef glue, GateRef nativeCode, GateRef func, \
91 GateRef newTarget, GateRef thisValue, GateRef numArgs)
92 #endif
93 #endif
94
GetCallArg0(GateRef numArg)95 GateRef BuiltinsStubBuilder::GetCallArg0(GateRef numArg)
96 {
97 auto env = GetEnvironment();
98 Label subentry(env);
99 env->SubCfgEntry(&subentry);
100 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
101 Label isValid(env);
102 Label exit(env);
103 BRANCH(Int32GreaterThan(TruncPtrToInt32(numArg), Int32(0)), &isValid, &exit);
104 Bind(&isValid);
105 {
106 result = TaggedArgument(static_cast<size_t>(BuiltinsArgs::ARG0_OR_ARGV));
107 Jump(&exit);
108 }
109 Bind(&exit);
110 auto res = *result;
111 env->SubCfgExit();
112 return res;
113 }
114
GetCallArg1(GateRef numArg)115 GateRef BuiltinsStubBuilder::GetCallArg1(GateRef numArg)
116 {
117 auto env = GetEnvironment();
118 Label subentry(env);
119 env->SubCfgEntry(&subentry);
120 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
121 Label isValid(env);
122 Label exit(env);
123 BRANCH(Int32GreaterThan(TruncPtrToInt32(numArg), Int32(1)), &isValid, &exit);
124 Bind(&isValid);
125 {
126 result = TaggedArgument(static_cast<size_t>(BuiltinsArgs::ARG1));
127 Jump(&exit);
128 }
129 Bind(&exit);
130 auto res = *result;
131 env->SubCfgExit();
132 return res;
133 }
134
GetCallArg2(GateRef numArg)135 GateRef BuiltinsStubBuilder::GetCallArg2(GateRef numArg)
136 {
137 auto env = GetEnvironment();
138 Label subentry(env);
139 env->SubCfgEntry(&subentry);
140 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
141 Label isValid(env);
142 Label exit(env);
143 // 2: 2 args
144 BRANCH(Int32GreaterThan(TruncPtrToInt32(numArg), Int32(2)), &isValid, &exit);
145 Bind(&isValid);
146 {
147 result = TaggedArgument(static_cast<size_t>(BuiltinsArgs::ARG2));
148 Jump(&exit);
149 }
150 Bind(&exit);
151 auto res = *result;
152 env->SubCfgExit();
153 return res;
154 }
155
GetArgFromArgv(GateRef index,GateRef numArgs,bool needCheck)156 GateRef BuiltinsStubBuilder::GetArgFromArgv(GateRef index, GateRef numArgs, bool needCheck)
157 {
158 if (!needCheck) {
159 GateRef argv = GetArgv();
160 return Load(VariableType::JS_ANY(), argv, PtrMul(index, IntPtr(JSTaggedValue::TaggedTypeSize())));
161 }
162 auto env = GetEnvironment();
163 Label entry(env);
164 env->SubCfgEntry(&entry);
165 DEFVARIABLE(arg, VariableType::JS_ANY(), Undefined());
166 Label validIndex(env);
167 Label exit(env);
168 BRANCH(IntPtrGreaterThan(numArgs, index), &validIndex, &exit);
169 Bind(&validIndex);
170 {
171 GateRef argv = GetArgv();
172 arg = Load(VariableType::JS_ANY(), argv, PtrMul(index, IntPtr(JSTaggedValue::TaggedTypeSize())));
173 Jump(&exit);
174 }
175 Bind(&exit);
176 GateRef ret = *arg;
177 env->SubCfgExit();
178 return ret;
179 }
180
CallSlowPath(GateRef nativeCode,GateRef glue,GateRef thisValue,GateRef numArgs,GateRef func,GateRef newTarget)181 GateRef BuiltinsStubBuilder::CallSlowPath(GateRef nativeCode, GateRef glue, GateRef thisValue,
182 GateRef numArgs, GateRef func, GateRef newTarget)
183 {
184 auto env = GetEnvironment();
185 Label entry(env);
186 env->SubCfgEntry(&entry);
187 Label exit(env);
188 Label callThis0(env);
189 Label notcallThis0(env);
190 Label notcallThis1(env);
191 Label callThis1(env);
192 Label callThis2(env);
193 Label callThis3(env);
194 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
195 GateRef runtimeCallInfoArgs = PtrAdd(numArgs, IntPtr(NUM_MANDATORY_JSFUNC_ARGS));
196 BRANCH(Int64Equal(numArgs, IntPtr(0)), &callThis0, ¬callThis0);
197 Bind(&callThis0);
198 {
199 auto args = { nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue };
200 result = CallBuiltinRuntime(glue, args, false);
201 Jump(&exit);
202 }
203 Bind(¬callThis0);
204 {
205 BRANCH(Int64Equal(numArgs, IntPtr(1)), &callThis1, ¬callThis1);
206 Bind(&callThis1);
207 {
208 GateRef arg0 = GetCallArg0(numArgs);
209 auto args = { nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue, arg0 };
210 result = CallBuiltinRuntime(glue, args, false);
211 Jump(&exit);
212 }
213 Bind(¬callThis1);
214 {
215 BRANCH(Int64Equal(numArgs, IntPtr(2)), &callThis2, &callThis3); // 2: args2
216 Bind(&callThis2);
217 {
218 GateRef arg0 = GetCallArg0(numArgs);
219 GateRef arg1 = GetCallArg1(numArgs);
220 auto args = { nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue, arg0, arg1 };
221 result = CallBuiltinRuntime(glue, args, false);
222 Jump(&exit);
223 }
224 Bind(&callThis3);
225 {
226 GateRef arg0 = GetCallArg0(numArgs);
227 GateRef arg1 = GetCallArg1(numArgs);
228 GateRef arg2 = GetCallArg2(numArgs);
229 auto args = { nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue, arg0, arg1, arg2 };
230 result = CallBuiltinRuntime(glue, args, false);
231 Jump(&exit);
232 }
233 }
234 }
235
236 Bind(&exit);
237 auto ret = *result;
238 env->SubCfgExit();
239 return ret;
240 }
241
242 #define DECLARE_BUILTINS_STUB_BUILDER(method, type, initValue) \
243 DECLARE_BUILTINS(type##method) \
244 { \
245 auto env = GetEnvironment(); \
246 DEFVARIABLE(res, VariableType::JS_ANY(), initValue); \
247 Label exit(env); \
248 Label slowPath(env); \
249 Builtins##type##StubBuilder builder(this); \
250 builder.method(glue, thisValue, numArgs, &res, &exit, &slowPath); \
251 Bind(&slowPath); \
252 { \
253 res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget); \
254 Jump(&exit); \
255 } \
256 Bind(&exit); \
257 Return(*res); \
258 }
259
260 #define DECLARE_BUILTINS_STUB_BUILDER1(method, type, initValue) \
261 DECLARE_BUILTINS(type##method) \
262 { \
263 auto env = GetEnvironment(); \
264 DEFVARIABLE(res, VariableType::JS_ANY(), initValue); \
265 Label thisCollectionObj(env); \
266 Label slowPath(env); \
267 Label exit(env); \
268 Builtins##type##StubBuilder builder(this, glue, thisValue, numArgs); \
269 builder.method(&res, &exit, &slowPath); \
270 Bind(&slowPath); \
271 { \
272 res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget); \
273 Jump(&exit); \
274 } \
275 Bind(&exit); \
276 Return(*res); \
277 }
278
279 // map and set stub function
280 #define DECLARE_BUILTINS_COLLECTION_STUB_BUILDER(method, type, retDefaultValue) \
281 DECLARE_BUILTINS(type##method) \
282 { \
283 auto env = GetEnvironment(); \
284 DEFVARIABLE(res, VariableType::JS_ANY(), retDefaultValue); \
285 Label slowPath(env); \
286 Label exit(env); \
287 BuiltinsCollectionStubBuilder<JS##type> builder(this, glue, thisValue, numArgs); \
288 builder.method(&res, &exit, &slowPath); \
289 Bind(&slowPath); \
290 { \
291 res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget); \
292 Jump(&exit); \
293 } \
294 Bind(&exit); \
295 Return(*res); \
296 }
297
298 // map and set stub function
299 #define DECLARE_BUILTINS_DATAVIEW_STUB_BUILDER(method, type, numType, function, retDefaultValue) \
300 DECLARE_BUILTINS(type##method) \
301 { \
302 auto env = GetEnvironment(); \
303 DEFVARIABLE(res, VariableType::JS_ANY(), retDefaultValue); \
304 Label slowPath(env); \
305 Label exit(env); \
306 BuiltinsDataViewStubBuilder builder(this); \
307 builder.function<DataViewType::numType>(glue, thisValue, numArgs, &res, &exit, &slowPath); \
308 Bind(&slowPath); \
309 { \
310 auto name = BuiltinsStubCSigns::GetName(BUILTINS_STUB_ID(type##method)); \
311 res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget); \
312 Jump(&exit); \
313 } \
314 Bind(&exit); \
315 Return(*res); \
316 }
317
BUILTINS_METHOD_STUB_LIST(DECLARE_BUILTINS_STUB_BUILDER,DECLARE_BUILTINS_STUB_BUILDER1,DECLARE_BUILTINS_COLLECTION_STUB_BUILDER,DECLARE_BUILTINS_DATAVIEW_STUB_BUILDER)318 BUILTINS_METHOD_STUB_LIST(DECLARE_BUILTINS_STUB_BUILDER, DECLARE_BUILTINS_STUB_BUILDER1,
319 DECLARE_BUILTINS_COLLECTION_STUB_BUILDER, DECLARE_BUILTINS_DATAVIEW_STUB_BUILDER)
320 #undef DECLARE_BUILTINS_STUB_BUILDER
321 #undef DECLARE_BUILTINS_STUB_BUILDER1
322 #undef DECLARE_BUILTINS_COLLECTION_STUB_BUILDER
323 #undef DECLARE_BUILTINS_DATAVIEW_STUB_BUILDER
324
325 DECLARE_BUILTINS(ArkToolsHashCode)
326 {
327 (void) nativeCode;
328 (void) func;
329 (void) newTarget;
330 (void) thisValue;
331 auto env = GetEnvironment();
332 GateRef key = GetCallArg0(numArgs);
333
334 Label irHash(env);
335 Label rtHash(env);
336 BRANCH(IntPtrEqual(numArgs, IntPtr(1)), &irHash, &rtHash);
337 Bind(&irHash);
338 {
339 HashStubBuilder hashBuilder(this, glue);
340 GateRef hash = hashBuilder.GetHash(key);
341 Return(env->GetBuilder()->Int32ToTaggedPtr(hash));
342 }
343 Bind(&rtHash);
344 Return(CallRuntime(glue, RTSTUB_ID(GetLinkedHash), { key }));
345 }
346
347 // aot and builtins public stub function
348 #define DECLARE_AOT_AND_BUILTINS_STUB_BUILDER(stubName, method, type, initValue) \
349 DECLARE_BUILTINS(stubName) \
350 { \
351 auto env = GetEnvironment(); \
352 DEFVARIABLE(res, VariableType::JS_ANY(), initValue); \
353 Label exit(env); \
354 Label slowPath(env); \
355 Builtins##type##StubBuilder builder(this); \
356 builder.method(glue, thisValue, numArgs, &res, &exit, &slowPath); \
357 Bind(&slowPath); \
358 { \
359 res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget); \
360 Jump(&exit); \
361 } \
362 Bind(&exit); \
363 Return(*res); \
364 }
365
366 #define AOT_AND_BUILTINS_STUB_LIST_WITH_METHOD(V) \
367 V(StringLocaleCompare, LocaleCompare, String, Undefined()) \
368 V(StringIteratorProtoNext, StringIteratorNext, String, Undefined()) \
369 V(ArraySort, Sort, Array, Undefined())
370
371 AOT_AND_BUILTINS_STUB_LIST_WITH_METHOD(DECLARE_AOT_AND_BUILTINS_STUB_BUILDER)
372 #undef AOT_AND_BUILTINS_STUB_LIST
373 #undef DECLARE_AOT_AND_BUILTINS_STUB_BUILDER
374
375 // containers stub function
376 #define DECLARE_BUILTINS_WITH_CONTAINERS_STUB_BUILDER(funcName, type, method, methodType, resultVariableType) \
377 DECLARE_BUILTINS(type##funcName) \
378 { \
379 auto env = GetEnvironment(); \
380 DEFVARIABLE(res, VariableType::resultVariableType(), Undefined()); \
381 Label exit(env); \
382 Label slowPath(env); \
383 ContainersStubBuilder containersBuilder(this); \
384 containersBuilder.method(glue, thisValue, numArgs, &res, &exit, &slowPath, ContainersType::methodType); \
385 Bind(&slowPath); \
386 { \
387 res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget); \
388 Jump(&exit); \
389 } \
390 Bind(&exit); \
391 Return(*res); \
392 }
393
BUILTINS_WITH_CONTAINERS_STUB_BUILDER(DECLARE_BUILTINS_WITH_CONTAINERS_STUB_BUILDER)394 BUILTINS_WITH_CONTAINERS_STUB_BUILDER(DECLARE_BUILTINS_WITH_CONTAINERS_STUB_BUILDER)
395 #undef DECLARE_BUILTINS_WITH_CONTAINERS_STUB_BUILDER
396
397 DECLARE_BUILTINS(BooleanConstructor)
398 {
399 auto env = GetEnvironment();
400 DEFVARIABLE(res, VariableType::JS_ANY(), Undefined());
401
402 Label newTargetIsHeapObject(env);
403 Label newTargetIsJSFunction(env);
404 Label slowPath(env);
405 Label slowPath1(env);
406 Label exit(env);
407
408 BRANCH(TaggedIsHeapObject(newTarget), &newTargetIsHeapObject, &slowPath);
409 Bind(&newTargetIsHeapObject);
410 BRANCH(IsJSFunction(newTarget), &newTargetIsJSFunction, &slowPath);
411 Bind(&newTargetIsJSFunction);
412 {
413 Label intialHClassIsHClass(env);
414 GateRef intialHClass = Load(VariableType::JS_ANY(), newTarget,
415 IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
416 BRANCH(IsJSHClass(intialHClass), &intialHClassIsHClass, &slowPath1);
417 Bind(&intialHClassIsHClass);
418 {
419 NewObjectStubBuilder newBuilder(this);
420 newBuilder.SetParameters(glue, 0);
421 Label afterNew(env);
422 newBuilder.NewJSObject(&res, &afterNew, intialHClass);
423 Bind(&afterNew);
424 {
425 GateRef valueOffset = IntPtr(JSPrimitiveRef::VALUE_OFFSET);
426 GateRef value = GetArgFromArgv(IntPtr(0), numArgs, true);
427 Store(VariableType::INT64(), glue, *res, valueOffset, FastToBoolean(value));
428 Jump(&exit);
429 }
430 }
431 Bind(&slowPath1);
432 {
433 GateRef argv = GetArgv();
434 auto args = { glue, nativeCode, func, thisValue, numArgs, argv, newTarget };
435 res = CallBuiltinRuntimeWithNewTarget(glue, args);
436 Jump(&exit);
437 }
438 }
439 Bind(&slowPath);
440 {
441 GateRef argv = GetArgv();
442 auto args = { glue, nativeCode, func, thisValue, numArgs, argv };
443 res = CallBuiltinRuntime(glue, args, true);
444 Jump(&exit);
445 }
446 Bind(&exit);
447 Return(*res);
448 }
449
DECLARE_BUILTINS(DateConstructor)450 DECLARE_BUILTINS(DateConstructor)
451 {
452 auto env = GetEnvironment();
453 DEFVARIABLE(res, VariableType::JS_ANY(), Undefined());
454
455 Label newTargetIsHeapObject(env);
456 Label newTargetIsJSFunction(env);
457 Label slowPath(env);
458 Label slowPath1(env);
459 Label exit(env);
460
461 BRANCH(TaggedIsHeapObject(newTarget), &newTargetIsHeapObject, &slowPath);
462 Bind(&newTargetIsHeapObject);
463 BRANCH(IsJSFunction(newTarget), &newTargetIsJSFunction, &slowPath);
464 Bind(&newTargetIsJSFunction);
465 {
466 Label intialHClassIsHClass(env);
467 GateRef intialHClass = Load(VariableType::JS_ANY(), newTarget,
468 IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
469 BRANCH(IsJSHClass(intialHClass), &intialHClassIsHClass, &slowPath1);
470 Bind(&intialHClassIsHClass);
471 {
472 Label oneArg(env);
473 Label notOneArg(env);
474 Label newJSDate(env);
475 DEFVARIABLE(timeValue, VariableType::FLOAT64(), Double(0));
476 BRANCH(Int64Equal(numArgs, IntPtr(1)), &oneArg, ¬OneArg);
477 Bind(&oneArg);
478 {
479 Label valueIsNumber(env);
480 GateRef value = GetArgFromArgv(IntPtr(0));
481 BRANCH(TaggedIsNumber(value), &valueIsNumber, &slowPath);
482 Bind(&valueIsNumber);
483 {
484 timeValue = CallNGCRuntime(glue, RTSTUB_ID(TimeClip), {GetDoubleOfTNumber(value)});
485 Jump(&newJSDate);
486 }
487 }
488 Bind(¬OneArg);
489 {
490 Label threeArgs(env);
491 BRANCH(Int64Equal(numArgs, IntPtr(3)), &threeArgs, &slowPath); // 3: year month day
492 Bind(&threeArgs);
493 {
494 Label numberYearMonthDay(env);
495 GateRef year = GetArgFromArgv(IntPtr(0));
496 GateRef month = GetArgFromArgv(IntPtr(1));
497 GateRef day = GetArgFromArgv(IntPtr(2));
498 BRANCH(IsNumberYearMonthDay(year, month, day), &numberYearMonthDay, &slowPath);
499 Bind(&numberYearMonthDay);
500 {
501 GateRef y = GetDoubleOfTNumber(year);
502 GateRef m = GetDoubleOfTNumber(month);
503 GateRef d = GetDoubleOfTNumber(day);
504 timeValue = CallNGCRuntime(glue, RTSTUB_ID(SetDateValues), {y, m, d});
505 Jump(&newJSDate);
506 }
507 }
508 }
509 Bind(&newJSDate);
510 {
511 NewObjectStubBuilder newBuilder(this);
512 newBuilder.SetParameters(glue, 0);
513 Label afterNew(env);
514 newBuilder.NewJSObject(&res, &afterNew, intialHClass);
515 Bind(&afterNew);
516 {
517 GateRef timeValueOffset = IntPtr(JSDate::TIME_VALUE_OFFSET);
518 Store(VariableType::JS_NOT_POINTER(), glue, *res, timeValueOffset,
519 DoubleToTaggedDoublePtr(*timeValue));
520 Jump(&exit);
521 }
522 }
523 }
524 Bind(&slowPath1);
525 {
526 GateRef argv = GetArgv();
527 res = CallBuiltinRuntimeWithNewTarget(glue,
528 { glue, nativeCode, func, thisValue, numArgs, argv, newTarget });
529 Jump(&exit);
530 }
531 }
532 Bind(&slowPath);
533 {
534 GateRef argv = GetArgv();
535 res = CallBuiltinRuntime(glue, { glue, nativeCode, func, thisValue, numArgs, argv }, true);
536 Jump(&exit);
537 }
538 Bind(&exit);
539 Return(*res);
540 }
541
DECLARE_BUILTINS(NumberConstructor)542 DECLARE_BUILTINS(NumberConstructor)
543 {
544 BuiltinsNumberStubBuilder builder(this, glue, thisValue, numArgs);
545 builder.GenNumberConstructor(nativeCode, func, newTarget);
546 }
547
DECLARE_BUILTINS(ProxyConstructor)548 DECLARE_BUILTINS(ProxyConstructor)
549 {
550 BuiltinsProxyStubBuilder builder(this, glue, thisValue, numArgs);
551 builder.GenProxyConstructor(nativeCode, func, newTarget);
552 }
553
DECLARE_BUILTINS(ArrayConstructor)554 DECLARE_BUILTINS(ArrayConstructor)
555 {
556 BuiltinsArrayStubBuilder builder(this);
557 builder.GenArrayConstructor(glue, nativeCode, func, newTarget, thisValue, numArgs);
558 }
559
DECLARE_BUILTINS(MapConstructor)560 DECLARE_BUILTINS(MapConstructor)
561 {
562 LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> hashTableBuilder(this, glue);
563 GateRef arg0 = GetArgFromArgv(IntPtr(0), numArgs, true);
564 hashTableBuilder.GenMapSetConstructor(nativeCode, func, newTarget, thisValue, numArgs, arg0, GetArgv());
565 }
566
DECLARE_BUILTINS(SetConstructor)567 DECLARE_BUILTINS(SetConstructor)
568 {
569 LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> hashTableBuilder(this, glue);
570 GateRef arg0 = GetArgFromArgv(IntPtr(0), numArgs, true);
571 hashTableBuilder.GenMapSetConstructor(nativeCode, func, newTarget, thisValue, numArgs, arg0, GetArgv());
572 }
573 } // namespace panda::ecmascript::kungfu
574