Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4baselinejit.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:jit
4
7#include <private/qv4lookup_p.h>
8#include <private/qv4generatorobject_p.h>
9
10#if QT_CONFIG(qml_jit)
11
12QT_USE_NAMESPACE
13using namespace QV4;
14using namespace QV4::JIT;
15using namespace QV4::Moth;
16
17BaselineJIT::BaselineJIT(Function *function)
18 : function(function)
19 , as(new BaselineAssembler(&(function->compilationUnit->constants->asValue<Value>())))
20{}
21
22BaselineJIT::~BaselineJIT()
23{}
24
25void BaselineJIT::generate()
26{
27// qDebug()<<"jitting" << function->name()->toQString();
28 const char *code = function->codeData;
29 uint len = function->compiledFunction->codeSize;
30
31 for (unsigned i = 0, ei = function->compiledFunction->nLabelInfos; i != ei; ++i)
32 labels.insert(int(function->compiledFunction->labelInfoTable()[i]));
33
34 as->generatePrologue();
35 // Make sure the ACC register is initialized and not clobbered by the caller.
36 as->loadAccumulatorFromFrame();
37 decode(code, len);
38 as->generateEpilogue();
39
40 as->link(function);
41// qDebug()<<"done";
42}
43
44#define STORE_IP() as->storeInstructionPointer(nextInstructionOffset())
45#define STORE_ACC() as->saveAccumulatorInFrame()
46#define LOAD_ACC() as->loadAccumulatorFromFrame()
47#define BASELINEJIT_GENERATE_RUNTIME_CALL(function, destination) {
48 as->GENERATE_RUNTIME_CALL(function, destination);
49 if (Runtime::function::throws)
50 as->checkException();
51 else {} } // this else prevents else statements after the macro from attaching to the if above
52
53void BaselineJIT::generate_Ret()
54{
55 as->ret();
56}
57
58void BaselineJIT::generate_Debug() { Q_UNREACHABLE(); }
59
60void BaselineJIT::generate_LoadConst(int index)
61{
62 as->loadConst(index);
63}
64
65void BaselineJIT::generate_LoadZero()
66{
67 as->loadValue(Encode(int(0)));
68}
69
70void BaselineJIT::generate_LoadTrue()
71{
72 as->loadValue(Encode(true));
73}
74
75void BaselineJIT::generate_LoadFalse()
76{
77 as->loadValue(Encode(false));
78}
79
80void BaselineJIT::generate_LoadNull()
81{
82 as->loadValue(Encode::null());
83}
84
85void BaselineJIT::generate_LoadUndefined()
86{
87 as->loadValue(Encode::undefined());
88}
89
90void BaselineJIT::generate_LoadInt(int value)
91{
92 //###
93 as->loadValue(Encode(value));
94}
95
96void BaselineJIT::generate_MoveConst(int constIndex, int destTemp)
97{
98 as->copyConst(constIndex, destTemp);
99}
100
101void BaselineJIT::generate_LoadReg(int reg)
102{
103 as->loadReg(reg);
104}
105
106void BaselineJIT::generate_StoreReg(int reg)
107{
108 as->storeReg(reg);
109}
110
111void BaselineJIT::generate_MoveReg(int srcReg, int destReg)
112{
113 // Don't clobber the accumulator.
114 as->moveReg(srcReg, destReg);
115}
116
117void BaselineJIT::generate_LoadImport(int index)
118{
119 as->loadImport(index);
120}
121
122void BaselineJIT::generate_LoadLocal(int index)
123{
124 as->loadLocal(index);
125}
126
127void BaselineJIT::generate_StoreLocal(int index)
128{
129 as->checkException();
130 as->storeLocal(index);
131}
132
133void BaselineJIT::generate_LoadScopedLocal(int scope, int index)
134{
135 as->loadLocal(index, scope);
136}
137
138void BaselineJIT::generate_StoreScopedLocal(int scope, int index)
139{
140 as->checkException();
141 as->storeLocal(index, scope);
142}
143
144void BaselineJIT::generate_LoadRuntimeString(int stringId)
145{
146 as->loadString(stringId);
147}
148
149void BaselineJIT::generate_MoveRegExp(int regExpId, int destReg)
150{
151 as->prepareCallWithArgCount(2);
152 as->passInt32AsArg(regExpId, 1);
153 as->passEngineAsArg(0);
154 BASELINEJIT_GENERATE_RUNTIME_CALL(RegexpLiteral, CallResultDestination::InAccumulator);
155 as->storeReg(destReg);
156}
157
158void BaselineJIT::generate_LoadClosure(int value)
159{
160 as->prepareCallWithArgCount(2);
161 as->passInt32AsArg(value, 1);
162 as->passEngineAsArg(0);
163 BASELINEJIT_GENERATE_RUNTIME_CALL(Closure, CallResultDestination::InAccumulator);
164}
165
166void BaselineJIT::generate_LoadName(int name)
167{
168 STORE_IP();
169 as->prepareCallWithArgCount(2);
170 as->passInt32AsArg(name, 1);
171 as->passEngineAsArg(0);
172 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadName, CallResultDestination::InAccumulator);
173}
174
175void BaselineJIT::generate_LoadGlobalLookup(int index)
176{
177 STORE_IP();
178 as->prepareCallWithArgCount(3);
179 as->passInt32AsArg(index, 2);
180 as->passFunctionAsArg(1);
181 as->passEngineAsArg(0);
182 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadGlobalLookup, CallResultDestination::InAccumulator);
183}
184
185void BaselineJIT::generate_LoadQmlContextPropertyLookup(int index)
186{
187 STORE_IP();
188 as->prepareCallWithArgCount(2);
189 as->passInt32AsArg(index, 1);
190 as->passEngineAsArg(0);
191 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadQmlContextPropertyLookup, CallResultDestination::InAccumulator);
192}
193
194void BaselineJIT::generate_StoreNameSloppy(int name)
195{
196 STORE_IP();
197 STORE_ACC();
198 as->prepareCallWithArgCount(3);
199 as->passAccumulatorAsArg(2);
200 as->passInt32AsArg(name, 1);
201 as->passEngineAsArg(0);
202 BASELINEJIT_GENERATE_RUNTIME_CALL(StoreNameSloppy, CallResultDestination::Ignore);
203 LOAD_ACC();
204}
205
206void BaselineJIT::generate_StoreNameStrict(int name)
207{
208 STORE_IP();
209 STORE_ACC();
210 as->prepareCallWithArgCount(3);
211 as->passAccumulatorAsArg(2);
212 as->passInt32AsArg(name, 1);
213 as->passEngineAsArg(0);
214 BASELINEJIT_GENERATE_RUNTIME_CALL(StoreNameStrict, CallResultDestination::Ignore);
215 LOAD_ACC();
216}
217
218void BaselineJIT::generate_LoadElement(int base)
219{
220 STORE_IP();
221 STORE_ACC();
222 as->prepareCallWithArgCount(3);
223 as->passAccumulatorAsArg(2);
224 as->passJSSlotAsArg(base, 1);
225 as->passEngineAsArg(0);
226 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadElement, CallResultDestination::InAccumulator);
227}
228
229void BaselineJIT::generate_StoreElement(int base, int index)
230{
231 STORE_IP();
232 STORE_ACC();
233 as->prepareCallWithArgCount(4);
234 as->passAccumulatorAsArg(3);
235 as->passJSSlotAsArg(index, 2);
236 as->passJSSlotAsArg(base, 1);
237 as->passEngineAsArg(0);
238 BASELINEJIT_GENERATE_RUNTIME_CALL(StoreElement, CallResultDestination::Ignore);
239 LOAD_ACC();
240}
241
242void BaselineJIT::generate_LoadProperty(int name)
243{
244 STORE_IP();
245 STORE_ACC();
246 as->prepareCallWithArgCount(3);
247 as->passInt32AsArg(name, 2);
248 as->passAccumulatorAsArg(1);
249 as->passEngineAsArg(0);
250 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadProperty, CallResultDestination::InAccumulator);
251}
252
253void BaselineJIT::generate_LoadOptionalProperty(int name, int offset)
254{
255 labels.insert(as->jumpEqNull(absoluteOffset(offset)));
256
257 generate_LoadProperty(name);
258}
259
260void BaselineJIT::generate_GetLookup(int index)
261{
262 STORE_IP();
263 STORE_ACC();
264 as->prepareCallWithArgCount(4);
265 as->passInt32AsArg(index, 3);
266 as->passAccumulatorAsArg(2);
267 as->passFunctionAsArg(1);
268 as->passEngineAsArg(0);
269 BASELINEJIT_GENERATE_RUNTIME_CALL(GetLookup, CallResultDestination::InAccumulator);
270}
271
272void BaselineJIT::generate_GetOptionalLookup(int index, int offset)
273{
274 labels.insert(as->jumpEqNull(absoluteOffset(offset)));
275
276 generate_GetLookup(index);
277}
278
279void BaselineJIT::generate_StoreProperty(int name, int base)
280{
281 STORE_IP();
282 STORE_ACC();
283 as->prepareCallWithArgCount(4);
284 as->passAccumulatorAsArg(3);
285 as->passInt32AsArg(name, 2);
286 as->passJSSlotAsArg(base, 1);
287 as->passEngineAsArg(0);
288 BASELINEJIT_GENERATE_RUNTIME_CALL(StoreProperty, CallResultDestination::Ignore);
289 LOAD_ACC();
290}
291
292void BaselineJIT::generate_SetLookup(int index, int base)
293{
294 STORE_IP();
295 STORE_ACC();
296 as->prepareCallWithArgCount(4);
297 as->passAccumulatorAsArg(3);
298 as->passInt32AsArg(index, 2);
299 as->passJSSlotAsArg(base, 1);
300 as->passFunctionAsArg(0);
301 if (function->isStrict())
302 BASELINEJIT_GENERATE_RUNTIME_CALL(SetLookupStrict, CallResultDestination::InAccumulator)
303 else
304 BASELINEJIT_GENERATE_RUNTIME_CALL(SetLookupSloppy, CallResultDestination::InAccumulator)
305}
306
307void BaselineJIT::generate_LoadSuperProperty(int property)
308{
309 STORE_IP();
310 as->prepareCallWithArgCount(2);
311 as->passJSSlotAsArg(property, 1);
312 as->passEngineAsArg(0);
313 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadSuperProperty, CallResultDestination::InAccumulator);
314}
315
316void BaselineJIT::generate_StoreSuperProperty(int property)
317{
318 STORE_IP();
319 STORE_ACC();
320 as->prepareCallWithArgCount(3);
321 as->passAccumulatorAsArg(2);
322 as->passJSSlotAsArg(property, 1);
323 as->passEngineAsArg(0);
324 BASELINEJIT_GENERATE_RUNTIME_CALL(StoreSuperProperty, CallResultDestination::Ignore);
325 LOAD_ACC();
326}
327
328void BaselineJIT::generate_Yield()
329{
330 // #####
331 Q_UNREACHABLE();
332}
333
334void BaselineJIT::generate_YieldStar()
335{
336 // #####
337 Q_UNREACHABLE();
338}
339
340void BaselineJIT::generate_Resume(int)
341{
342 // #####
343 Q_UNREACHABLE();
344}
345
346void BaselineJIT::generate_CallValue(int name, int argc, int argv)
347{
348 STORE_IP();
349 as->prepareCallWithArgCount(4);
350 as->passInt32AsArg(argc, 3);
351 as->passJSSlotAsArg(argv, 2);
352 as->passJSSlotAsArg(name, 1);
353 as->passEngineAsArg(0);
354 BASELINEJIT_GENERATE_RUNTIME_CALL(CallValue, CallResultDestination::InAccumulator);
355}
356
357void BaselineJIT::generate_CallWithReceiver(int name, int thisObject, int argc, int argv)
358{
359 STORE_IP();
360 as->prepareCallWithArgCount(5);
361 as->passInt32AsArg(argc, 4);
362 as->passJSSlotAsArg(argv, 3);
363 as->passJSSlotAsArg(thisObject, 2);
364 as->passJSSlotAsArg(name, 1);
365 as->passEngineAsArg(0);
366 BASELINEJIT_GENERATE_RUNTIME_CALL(CallWithReceiver, CallResultDestination::InAccumulator);
367}
368
369void BaselineJIT::generate_CallProperty(int name, int base, int argc, int argv)
370{
371 STORE_IP();
372 as->prepareCallWithArgCount(5);
373 as->passInt32AsArg(argc, 4);
374 as->passJSSlotAsArg(argv, 3);
375 as->passInt32AsArg(name, 2);
376 as->passJSSlotAsArg(base, 1);
377 as->passEngineAsArg(0);
378 BASELINEJIT_GENERATE_RUNTIME_CALL(CallProperty, CallResultDestination::InAccumulator);
379}
380
381void BaselineJIT::generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv)
382{
383 STORE_IP();
384 as->prepareCallWithArgCount(5);
385 as->passInt32AsArg(argc, 4);
386 as->passJSSlotAsArg(argv, 3);
387 as->passInt32AsArg(lookupIndex, 2);
388 as->passJSSlotAsArg(base, 1);
389 as->passEngineAsArg(0);
390 BASELINEJIT_GENERATE_RUNTIME_CALL(CallPropertyLookup, CallResultDestination::InAccumulator);
391}
392
393void BaselineJIT::generate_CallName(int name, int argc, int argv)
394{
395 STORE_IP();
396 as->prepareCallWithArgCount(4);
397 as->passInt32AsArg(argc, 3);
398 as->passJSSlotAsArg(argv, 2);
399 as->passInt32AsArg(name, 1);
400 as->passEngineAsArg(0);
401 BASELINEJIT_GENERATE_RUNTIME_CALL(CallName, CallResultDestination::InAccumulator);
402}
403
404void BaselineJIT::generate_CallPossiblyDirectEval(int argc, int argv)
405{
406 STORE_IP();
407 as->prepareCallWithArgCount(3);
408 as->passInt32AsArg(argc, 2);
409 as->passJSSlotAsArg(argv, 1);
410 as->passEngineAsArg(0);
411 BASELINEJIT_GENERATE_RUNTIME_CALL(CallPossiblyDirectEval, CallResultDestination::InAccumulator);
412}
413
414void BaselineJIT::generate_CallGlobalLookup(int index, int argc, int argv)
415{
416 STORE_IP();
417 as->prepareCallWithArgCount(4);
418 as->passInt32AsArg(argc, 3);
419 as->passJSSlotAsArg(argv, 2);
420 as->passInt32AsArg(index, 1);
421 as->passEngineAsArg(0);
422 BASELINEJIT_GENERATE_RUNTIME_CALL(CallGlobalLookup, CallResultDestination::InAccumulator);
423}
424
425void BaselineJIT::generate_CallQmlContextPropertyLookup(int index, int argc, int argv)
426{
427 STORE_IP();
428 as->prepareCallWithArgCount(4);
429 as->passInt32AsArg(argc, 3);
430 as->passJSSlotAsArg(argv, 2);
431 as->passInt32AsArg(index, 1);
432 as->passEngineAsArg(0);
433 BASELINEJIT_GENERATE_RUNTIME_CALL(CallQmlContextPropertyLookup, CallResultDestination::InAccumulator);
434}
435
436void BaselineJIT::generate_CallWithSpread(int func, int thisObject, int argc, int argv)
437{
438 STORE_IP();
439 as->prepareCallWithArgCount(5);
440 as->passInt32AsArg(argc, 4);
441 as->passJSSlotAsArg(argv, 3);
442 as->passJSSlotAsArg(thisObject, 2);
443 as->passJSSlotAsArg(func, 1);
444 as->passEngineAsArg(0);
445 BASELINEJIT_GENERATE_RUNTIME_CALL(CallWithSpread, CallResultDestination::InAccumulator);
446}
447
448void BaselineJIT::generate_TailCall(int func, int thisObject, int argc, int argv)
449{
450 STORE_IP();
451 as->jsTailCall(func, thisObject, argc, argv);
452}
453
454void BaselineJIT::generate_Construct(int func, int argc, int argv)
455{
456 STORE_IP();
457 STORE_ACC();
458 as->prepareCallWithArgCount(5);
459 as->passInt32AsArg(argc, 4);
460 as->passJSSlotAsArg(argv, 3);
461 as->passAccumulatorAsArg(2);
462 as->passJSSlotAsArg(func, 1);
463 as->passEngineAsArg(0);
464 BASELINEJIT_GENERATE_RUNTIME_CALL(Construct, CallResultDestination::InAccumulator);
465}
466
467void BaselineJIT::generate_ConstructWithSpread(int func, int argc, int argv)
468{
469 STORE_IP();
470 STORE_ACC();
471 as->prepareCallWithArgCount(5);
472 as->passInt32AsArg(argc, 4);
473 as->passJSSlotAsArg(argv, 3);
474 as->passAccumulatorAsArg(2);
475 as->passJSSlotAsArg(func, 1);
476 as->passEngineAsArg(0);
477 BASELINEJIT_GENERATE_RUNTIME_CALL(ConstructWithSpread, CallResultDestination::InAccumulator);
478}
479
480void BaselineJIT::generate_SetUnwindHandler(int offset)
481{
482 if (offset)
483 labels.insert(as->setUnwindHandler(absoluteOffset(offset)));
484 else
485 as->clearUnwindHandler();
486}
487
488void BaselineJIT::generate_UnwindDispatch()
489{
490 as->unwindDispatch();
491}
492
493void BaselineJIT::generate_UnwindToLabel(int level, int offset)
494{
495 labels.insert(as->unwindToLabel(level, absoluteOffset(offset)));
496}
497
498void BaselineJIT::generate_DeadTemporalZoneCheck(int name)
499{
500 as->deadTemporalZoneCheck(nextInstructionOffset(), name);
501}
502
503void BaselineJIT::generate_ThrowException()
504{
505 STORE_IP();
506 STORE_ACC();
507 as->prepareCallWithArgCount(2);
508 as->passAccumulatorAsArg(1);
509 as->passEngineAsArg(0);
510 BASELINEJIT_GENERATE_RUNTIME_CALL(ThrowException, CallResultDestination::Ignore);
511 as->gotoCatchException();
512
513 // LOAD_ACC(); <- not needed here since it would be unreachable.
514}
515
516void BaselineJIT::generate_GetException() { as->getException(); }
517void BaselineJIT::generate_SetException() { as->setException(); }
518
519void BaselineJIT::generate_CreateCallContext()
520{
521 STORE_ACC();
522 as->prepareCallWithArgCount(1);
523 as->passCppFrameAsArg(0);
524 BASELINEJIT_GENERATE_RUNTIME_CALL(PushCallContext, CallResultDestination::Ignore);
525 LOAD_ACC();
526}
527
528void BaselineJIT::generate_PushCatchContext(int index, int name) { as->pushCatchContext(index, name); }
529
530void BaselineJIT::generate_PushWithContext()
531{
532 STORE_IP();
533 as->saveAccumulatorInFrame();
534 as->prepareCallWithArgCount(2);
535 as->passJSSlotAsArg(CallData::Accumulator, 1);
536 as->passEngineAsArg(0);
537 BASELINEJIT_GENERATE_RUNTIME_CALL(PushWithContext, CallResultDestination::InAccumulator);
538}
539
540void BaselineJIT::generate_PushBlockContext(int index)
541{
542 as->saveAccumulatorInFrame();
543 as->prepareCallWithArgCount(2);
544 as->passInt32AsArg(index, 1);
545 as->passEngineAsArg(0);
546 BASELINEJIT_GENERATE_RUNTIME_CALL(PushBlockContext, CallResultDestination::Ignore);
547 as->loadAccumulatorFromFrame();
548}
549
550void BaselineJIT::generate_CloneBlockContext()
551{
552 as->saveAccumulatorInFrame();
553 as->prepareCallWithArgCount(1);
554 as->passEngineAsArg(0);
555 BASELINEJIT_GENERATE_RUNTIME_CALL(CloneBlockContext, CallResultDestination::Ignore);
556 as->loadAccumulatorFromFrame();
557}
558
559void BaselineJIT::generate_PushScriptContext(int index)
560{
561 as->saveAccumulatorInFrame();
562 as->prepareCallWithArgCount(2);
563 as->passInt32AsArg(index, 1);
564 as->passEngineAsArg(0);
565 BASELINEJIT_GENERATE_RUNTIME_CALL(PushScriptContext, CallResultDestination::Ignore);
566 as->loadAccumulatorFromFrame();
567}
568
569void BaselineJIT::generate_PopScriptContext()
570{
571 as->saveAccumulatorInFrame();
572 as->prepareCallWithArgCount(1);
573 as->passEngineAsArg(0);
574 BASELINEJIT_GENERATE_RUNTIME_CALL(PopScriptContext, CallResultDestination::Ignore);
575 as->loadAccumulatorFromFrame();
576}
577
578void BaselineJIT::generate_PopContext() { as->popContext(); }
579
580void BaselineJIT::generate_GetIterator(int iterator)
581{
582 as->saveAccumulatorInFrame();
583 as->prepareCallWithArgCount(3);
584 as->passInt32AsArg(iterator, 2);
585 as->passAccumulatorAsArg(1);
586 as->passEngineAsArg(0);
587 BASELINEJIT_GENERATE_RUNTIME_CALL(GetIterator, CallResultDestination::InAccumulator);
588}
589
590void BaselineJIT::generate_IteratorNext(int value, int offset)
591{
592 as->saveAccumulatorInFrame();
593 as->prepareCallWithArgCount(3);
594 as->passJSSlotAsArg(value, 2);
595 as->passAccumulatorAsArg(1);
596 as->passEngineAsArg(0);
597 BASELINEJIT_GENERATE_RUNTIME_CALL(IteratorNext, CallResultDestination::InAccumulator);
598 labels.insert(as->jumpTrue(absoluteOffset(offset)));
599}
600
601void BaselineJIT::generate_IteratorNextForYieldStar(int iterator, int object, int offset)
602{
603 as->saveAccumulatorInFrame();
604 as->prepareCallWithArgCount(4);
605 as->passJSSlotAsArg(object, 3);
606 as->passJSSlotAsArg(iterator, 2);
607 as->passAccumulatorAsArg(1);
608 as->passEngineAsArg(0);
609 BASELINEJIT_GENERATE_RUNTIME_CALL(IteratorNextForYieldStar, CallResultDestination::InAccumulator);
610 labels.insert(as->jumpTrue(absoluteOffset(offset)));
611}
612
613void BaselineJIT::generate_IteratorClose()
614{
615 as->saveAccumulatorInFrame();
616 as->prepareCallWithArgCount(2);
617 as->passAccumulatorAsArg(1);
618 as->passEngineAsArg(0);
619 BASELINEJIT_GENERATE_RUNTIME_CALL(IteratorClose, CallResultDestination::InAccumulator);
620}
621
622void BaselineJIT::generate_DestructureRestElement()
623{
624 as->saveAccumulatorInFrame();
625 as->prepareCallWithArgCount(2);
626 as->passAccumulatorAsArg(1);
627 as->passEngineAsArg(0);
628 BASELINEJIT_GENERATE_RUNTIME_CALL(DestructureRestElement, CallResultDestination::InAccumulator);
629}
630
631void BaselineJIT::generate_DeleteProperty(int base, int index)
632{
633 STORE_IP();
634 as->prepareCallWithArgCount(4);
635 as->passJSSlotAsArg(index, 3);
636 as->passJSSlotAsArg(base, 2);
637 as->passFunctionAsArg(1);
638 as->passEngineAsArg(0);
639 BASELINEJIT_GENERATE_RUNTIME_CALL(DeleteProperty, CallResultDestination::InAccumulator);
640}
641
642void BaselineJIT::generate_DeleteName(int name)
643{
644 STORE_IP();
645 as->prepareCallWithArgCount(3);
646 as->passInt32AsArg(name, 2);
647 as->passFunctionAsArg(1);
648 as->passEngineAsArg(0);
649 BASELINEJIT_GENERATE_RUNTIME_CALL(DeleteName, CallResultDestination::InAccumulator);
650}
651
652void BaselineJIT::generate_TypeofName(int name)
653{
654 as->prepareCallWithArgCount(2);
655 as->passInt32AsArg(name, 1);
656 as->passEngineAsArg(0);
657 BASELINEJIT_GENERATE_RUNTIME_CALL(TypeofName, CallResultDestination::InAccumulator);
658}
659
660void BaselineJIT::generate_TypeofValue()
661{
662 STORE_ACC();
663 as->prepareCallWithArgCount(2);
664 as->passAccumulatorAsArg(1);
665 as->passEngineAsArg(0);
666 BASELINEJIT_GENERATE_RUNTIME_CALL(TypeofValue, CallResultDestination::InAccumulator);
667}
668
669void BaselineJIT::generate_DeclareVar(int varName, int isDeletable)
670{
671 STORE_ACC();
672 as->prepareCallWithArgCount(3);
673 as->passInt32AsArg(varName, 2);
674 as->passInt32AsArg(isDeletable, 1);
675 as->passEngineAsArg(0);
676 BASELINEJIT_GENERATE_RUNTIME_CALL(DeclareVar, CallResultDestination::Ignore);
677 LOAD_ACC();
678}
679
680void BaselineJIT::generate_DefineArray(int argc, int args)
681{
682 as->prepareCallWithArgCount(3);
683 as->passInt32AsArg(argc, 2);
684 as->passJSSlotAsArg(args, 1);
685 as->passEngineAsArg(0);
686 BASELINEJIT_GENERATE_RUNTIME_CALL(ArrayLiteral, CallResultDestination::InAccumulator);
687}
688
689void BaselineJIT::generate_DefineObjectLiteral(int internalClassId, int argc, int args)
690{
691 as->prepareCallWithArgCount(4);
692 as->passInt32AsArg(argc, 3);
693 as->passJSSlotAsArg(args, 2);
694 as->passInt32AsArg(internalClassId, 1);
695 as->passEngineAsArg(0);
696 BASELINEJIT_GENERATE_RUNTIME_CALL(ObjectLiteral, CallResultDestination::InAccumulator);
697}
698
699void BaselineJIT::generate_CreateClass(int classIndex, int heritage, int computedNames)
700{
701 as->prepareCallWithArgCount(4);
702 as->passJSSlotAsArg(computedNames, 3);
703 as->passJSSlotAsArg(heritage, 2);
704 as->passInt32AsArg(classIndex, 1);
705 as->passEngineAsArg(0);
706 BASELINEJIT_GENERATE_RUNTIME_CALL(CreateClass, CallResultDestination::InAccumulator);
707}
708
709void BaselineJIT::generate_CreateMappedArgumentsObject()
710{
711 as->prepareCallWithArgCount(1);
712 as->passEngineAsArg(0);
713 BASELINEJIT_GENERATE_RUNTIME_CALL(CreateMappedArgumentsObject,
714 CallResultDestination::InAccumulator);
715}
716
717void BaselineJIT::generate_CreateUnmappedArgumentsObject()
718{
719 as->prepareCallWithArgCount(1);
720 as->passEngineAsArg(0);
721 BASELINEJIT_GENERATE_RUNTIME_CALL(CreateUnmappedArgumentsObject,
722 CallResultDestination::InAccumulator);
723}
724
725void BaselineJIT::generate_CreateRestParameter(int argIndex)
726{
727 as->prepareCallWithArgCount(2);
728 as->passInt32AsArg(argIndex, 1);
729 as->passEngineAsArg(0);
730 BASELINEJIT_GENERATE_RUNTIME_CALL(CreateRestParameter, CallResultDestination::InAccumulator);
731}
732
733void BaselineJIT::generate_ConvertThisToObject()
734{
735 STORE_ACC();
736 as->prepareCallWithArgCount(2);
737 as->passJSSlotAsArg(CallData::This, 1);
738 as->passEngineAsArg(0);
739 BASELINEJIT_GENERATE_RUNTIME_CALL(ConvertThisToObject, CallResultDestination::InAccumulator);
740 as->storeReg(CallData::This);
741 LOAD_ACC();
742}
743
744void BaselineJIT::generate_LoadSuperConstructor()
745{
746 as->prepareCallWithArgCount(2);
747 as->passJSSlotAsArg(CallData::Function, 1);
748 as->passEngineAsArg(0);
749 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadSuperConstructor, CallResultDestination::InAccumulator);
750}
751
752void BaselineJIT::generate_ToObject()
753{
754 STORE_ACC();
755 as->prepareCallWithArgCount(2);
756 as->passAccumulatorAsArg(1);
757 as->passEngineAsArg(0);
758 BASELINEJIT_GENERATE_RUNTIME_CALL(ToObject, CallResultDestination::InAccumulator);
759
760}
761
762void BaselineJIT::generate_Jump(int offset)
763{
764 labels.insert(as->jump(absoluteOffset(offset)));
765}
766
767void BaselineJIT::generate_JumpTrue(int offset)
768{
769 labels.insert(as->jumpTrue(absoluteOffset(offset)));
770}
771
772void BaselineJIT::generate_JumpFalse(int offset)
773{
774 labels.insert(as->jumpFalse(absoluteOffset(offset)));
775}
776
777void BaselineJIT::generate_JumpNoException(int offset)
778{
779 labels.insert(as->jumpNoException(absoluteOffset(offset)));
780}
781
782void BaselineJIT::generate_JumpNotUndefined(int offset)
783{
784 labels.insert(as->jumpNotUndefined(absoluteOffset(offset)));
785}
786
787void BaselineJIT::generate_CheckException()
788{
789 as->checkException();
790}
791
792void BaselineJIT::generate_CmpEqNull() { as->cmpeqNull(); }
793void BaselineJIT::generate_CmpNeNull() { as->cmpneNull(); }
794void BaselineJIT::generate_CmpEqInt(int lhs) { as->cmpeqInt(lhs); }
795void BaselineJIT::generate_CmpNeInt(int lhs) { as->cmpneInt(lhs); }
796void BaselineJIT::generate_CmpEq(int lhs) { as->cmpeq(lhs); }
797void BaselineJIT::generate_CmpNe(int lhs) { as->cmpne(lhs); }
798void BaselineJIT::generate_CmpGt(int lhs) { as->cmpgt(lhs); }
799void BaselineJIT::generate_CmpGe(int lhs) { as->cmpge(lhs); }
800void BaselineJIT::generate_CmpLt(int lhs) { as->cmplt(lhs); }
801void BaselineJIT::generate_CmpLe(int lhs) { as->cmple(lhs); }
802void BaselineJIT::generate_CmpStrictEqual(int lhs) { as->cmpStrictEqual(lhs); }
803void BaselineJIT::generate_CmpStrictNotEqual(int lhs) { as->cmpStrictNotEqual(lhs); }
804
805void BaselineJIT::generate_CmpIn(int lhs)
806{
807 STORE_IP();
808 STORE_ACC();
809 as->prepareCallWithArgCount(3);
810 as->passAccumulatorAsArg(2);
811 as->passJSSlotAsArg(lhs, 1);
812 as->passEngineAsArg(0);
813 BASELINEJIT_GENERATE_RUNTIME_CALL(In, CallResultDestination::InAccumulator);
814}
815
816void BaselineJIT::generate_CmpInstanceOf(int lhs)
817{
818 STORE_ACC();
819 as->prepareCallWithArgCount(3);
820 as->passAccumulatorAsArg(2);
821 as->passJSSlotAsArg(lhs, 1);
822 as->passEngineAsArg(0);
823 BASELINEJIT_GENERATE_RUNTIME_CALL(Instanceof, CallResultDestination::InAccumulator);
824}
825
826void BaselineJIT::generate_As(int lhs)
827{
828 STORE_ACC();
829 as->prepareCallWithArgCount(3);
830 as->passAccumulatorAsArg(2);
831 as->passJSSlotAsArg(lhs, 1);
832 as->passEngineAsArg(0);
833 BASELINEJIT_GENERATE_RUNTIME_CALL(As, CallResultDestination::InAccumulator);
834}
835
836void BaselineJIT::generate_UNot() { as->unot(); }
837void BaselineJIT::generate_UPlus() { as->toNumber(); }
838void BaselineJIT::generate_UMinus() { as->uminus(); }
839void BaselineJIT::generate_UCompl() { as->ucompl(); }
840void BaselineJIT::generate_Increment() { as->inc(); }
841void BaselineJIT::generate_Decrement() { as->dec(); }
842void BaselineJIT::generate_Add(int lhs) { as->add(lhs); }
843
844void BaselineJIT::generate_BitAnd(int lhs) { as->bitAnd(lhs); }
845void BaselineJIT::generate_BitOr(int lhs) { as->bitOr(lhs); }
846void BaselineJIT::generate_BitXor(int lhs) { as->bitXor(lhs); }
847void BaselineJIT::generate_UShr(int lhs) { as->ushr(lhs); }
848void BaselineJIT::generate_Shr(int lhs) { as->shr(lhs); }
849void BaselineJIT::generate_Shl(int lhs) { as->shl(lhs); }
850
851void BaselineJIT::generate_BitAndConst(int rhs) { as->bitAndConst(rhs); }
852void BaselineJIT::generate_BitOrConst(int rhs) { as->bitOrConst(rhs); }
853void BaselineJIT::generate_BitXorConst(int rhs) { as->bitXorConst(rhs); }
854void BaselineJIT::generate_UShrConst(int rhs) { as->ushrConst(rhs); }
855void BaselineJIT::generate_ShrConst(int rhs) { as->shrConst(rhs); }
856void BaselineJIT::generate_ShlConst(int rhs) { as->shlConst(rhs); }
857
858void BaselineJIT::generate_Exp(int lhs) {
859 STORE_IP();
860 STORE_ACC();
861 as->prepareCallWithArgCount(2);
862 as->passAccumulatorAsArg(1);
863 as->passJSSlotAsArg(lhs, 0);
864 BASELINEJIT_GENERATE_RUNTIME_CALL(Exp, CallResultDestination::InAccumulator);
865}
866void BaselineJIT::generate_Mul(int lhs) { as->mul(lhs); }
867void BaselineJIT::generate_Div(int lhs) { as->div(lhs); }
868void BaselineJIT::generate_Mod(int lhs) { as->mod(lhs); }
869void BaselineJIT::generate_Sub(int lhs) { as->sub(lhs); }
870
871//void BaselineJIT::generate_BinopContext(int alu, int lhs)
872//{
873// auto engine = function->internalClass->engine;
874// void *op = engine->runtime.runtimeMethods[alu];
875// STORE_ACC();
876// as->passAccumulatorAsArg(2);
877// as->passRegAsArg(lhs, 1);
878// as->passEngineAsArg(0);
879// as->callRuntime("binopContext", op, CallResultDestination::InAccumulator);
880// as->checkException();
881//}
882
883void BaselineJIT::generate_InitializeBlockDeadTemporalZone(int firstReg, int count)
884{
885 as->loadValue(Value::emptyValue().rawValue());
886 for (int i = firstReg, end = firstReg + count; i < end; ++i)
887 as->storeReg(i);
888}
889
890void BaselineJIT::generate_ThrowOnNullOrUndefined()
891{
892 STORE_ACC();
893 as->prepareCallWithArgCount(2);
894 as->passAccumulatorAsArg(1);
895 as->passEngineAsArg(0);
896 BASELINEJIT_GENERATE_RUNTIME_CALL(ThrowOnNullOrUndefined, CallResultDestination::Ignore);
897 LOAD_ACC();
898}
899
900void BaselineJIT::generate_GetTemplateObject(int index)
901{
902 as->prepareCallWithArgCount(2);
903 as->passInt32AsArg(index, 1);
904 as->passFunctionAsArg(0);
905 BASELINEJIT_GENERATE_RUNTIME_CALL(GetTemplateObject, CallResultDestination::InAccumulator);
906}
907
908ByteCodeHandler::Verdict BaselineJIT::startInstruction(Instr::Type /*instr*/)
909{
910 if (labels.contains(currentInstructionOffset()))
911 as->addLabel(currentInstructionOffset());
912 return ProcessInstruction;
913}
914
915void BaselineJIT::endInstruction(Instr::Type instr)
916{
917 Q_UNUSED(instr);
918}
919
920#endif // QT_CONFIG(qml_jit)