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::Ignore)
303 else
304 BASELINEJIT_GENERATE_RUNTIME_CALL(SetLookupSloppy, CallResultDestination::Ignore)
305 LOAD_ACC();
306}
307
308void BaselineJIT::generate_LoadSuperProperty(int property)
309{
310 STORE_IP();
311 as->prepareCallWithArgCount(2);
312 as->passJSSlotAsArg(property, 1);
313 as->passEngineAsArg(0);
314 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadSuperProperty, CallResultDestination::InAccumulator);
315}
316
317void BaselineJIT::generate_StoreSuperProperty(int property)
318{
319 STORE_IP();
320 STORE_ACC();
321 as->prepareCallWithArgCount(3);
322 as->passAccumulatorAsArg(2);
323 as->passJSSlotAsArg(property, 1);
324 as->passEngineAsArg(0);
325 BASELINEJIT_GENERATE_RUNTIME_CALL(StoreSuperProperty, CallResultDestination::Ignore);
326 LOAD_ACC();
327}
328
329void BaselineJIT::generate_Yield()
330{
331 // #####
332 Q_UNREACHABLE();
333}
334
335void BaselineJIT::generate_YieldStar()
336{
337 // #####
338 Q_UNREACHABLE();
339}
340
341void BaselineJIT::generate_Resume(int)
342{
343 // #####
344 Q_UNREACHABLE();
345}
346
347void BaselineJIT::generate_CallValue(int name, int argc, int argv)
348{
349 STORE_IP();
350 as->prepareCallWithArgCount(4);
351 as->passInt32AsArg(argc, 3);
352 as->passJSSlotAsArg(argv, 2);
353 as->passJSSlotAsArg(name, 1);
354 as->passEngineAsArg(0);
355 BASELINEJIT_GENERATE_RUNTIME_CALL(CallValue, CallResultDestination::InAccumulator);
356}
357
358void BaselineJIT::generate_CallWithReceiver(int name, int thisObject, int argc, int argv)
359{
360 STORE_IP();
361 as->prepareCallWithArgCount(5);
362 as->passInt32AsArg(argc, 4);
363 as->passJSSlotAsArg(argv, 3);
364 as->passJSSlotAsArg(thisObject, 2);
365 as->passJSSlotAsArg(name, 1);
366 as->passEngineAsArg(0);
367 BASELINEJIT_GENERATE_RUNTIME_CALL(CallWithReceiver, CallResultDestination::InAccumulator);
368}
369
370void BaselineJIT::generate_CallProperty(int name, int base, int argc, int argv)
371{
372 STORE_IP();
373 as->prepareCallWithArgCount(5);
374 as->passInt32AsArg(argc, 4);
375 as->passJSSlotAsArg(argv, 3);
376 as->passInt32AsArg(name, 2);
377 as->passJSSlotAsArg(base, 1);
378 as->passEngineAsArg(0);
379 BASELINEJIT_GENERATE_RUNTIME_CALL(CallProperty, CallResultDestination::InAccumulator);
380}
381
382void BaselineJIT::generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv)
383{
384 STORE_IP();
385 as->prepareCallWithArgCount(5);
386 as->passInt32AsArg(argc, 4);
387 as->passJSSlotAsArg(argv, 3);
388 as->passInt32AsArg(lookupIndex, 2);
389 as->passJSSlotAsArg(base, 1);
390 as->passEngineAsArg(0);
391 BASELINEJIT_GENERATE_RUNTIME_CALL(CallPropertyLookup, CallResultDestination::InAccumulator);
392}
393
394void BaselineJIT::generate_CallName(int name, int argc, int argv)
395{
396 STORE_IP();
397 as->prepareCallWithArgCount(4);
398 as->passInt32AsArg(argc, 3);
399 as->passJSSlotAsArg(argv, 2);
400 as->passInt32AsArg(name, 1);
401 as->passEngineAsArg(0);
402 BASELINEJIT_GENERATE_RUNTIME_CALL(CallName, CallResultDestination::InAccumulator);
403}
404
405void BaselineJIT::generate_CallPossiblyDirectEval(int argc, int argv)
406{
407 STORE_IP();
408 as->prepareCallWithArgCount(3);
409 as->passInt32AsArg(argc, 2);
410 as->passJSSlotAsArg(argv, 1);
411 as->passEngineAsArg(0);
412 BASELINEJIT_GENERATE_RUNTIME_CALL(CallPossiblyDirectEval, CallResultDestination::InAccumulator);
413}
414
415void BaselineJIT::generate_CallGlobalLookup(int index, int argc, int argv)
416{
417 STORE_IP();
418 as->prepareCallWithArgCount(4);
419 as->passInt32AsArg(argc, 3);
420 as->passJSSlotAsArg(argv, 2);
421 as->passInt32AsArg(index, 1);
422 as->passEngineAsArg(0);
423 BASELINEJIT_GENERATE_RUNTIME_CALL(CallGlobalLookup, CallResultDestination::InAccumulator);
424}
425
426void BaselineJIT::generate_CallQmlContextPropertyLookup(int index, int argc, int argv)
427{
428 STORE_IP();
429 as->prepareCallWithArgCount(4);
430 as->passInt32AsArg(argc, 3);
431 as->passJSSlotAsArg(argv, 2);
432 as->passInt32AsArg(index, 1);
433 as->passEngineAsArg(0);
434 BASELINEJIT_GENERATE_RUNTIME_CALL(CallQmlContextPropertyLookup, CallResultDestination::InAccumulator);
435}
436
437void BaselineJIT::generate_CallWithSpread(int func, int thisObject, int argc, int argv)
438{
439 STORE_IP();
440 as->prepareCallWithArgCount(5);
441 as->passInt32AsArg(argc, 4);
442 as->passJSSlotAsArg(argv, 3);
443 as->passJSSlotAsArg(thisObject, 2);
444 as->passJSSlotAsArg(func, 1);
445 as->passEngineAsArg(0);
446 BASELINEJIT_GENERATE_RUNTIME_CALL(CallWithSpread, CallResultDestination::InAccumulator);
447}
448
449void BaselineJIT::generate_TailCall(int func, int thisObject, int argc, int argv)
450{
451 STORE_IP();
452 as->jsTailCall(func, thisObject, argc, argv);
453}
454
455void BaselineJIT::generate_Construct(int func, int argc, int argv)
456{
457 STORE_IP();
458 STORE_ACC();
459 as->prepareCallWithArgCount(5);
460 as->passInt32AsArg(argc, 4);
461 as->passJSSlotAsArg(argv, 3);
462 as->passAccumulatorAsArg(2);
463 as->passJSSlotAsArg(func, 1);
464 as->passEngineAsArg(0);
465 BASELINEJIT_GENERATE_RUNTIME_CALL(Construct, CallResultDestination::InAccumulator);
466}
467
468void BaselineJIT::generate_ConstructWithSpread(int func, int argc, int argv)
469{
470 STORE_IP();
471 STORE_ACC();
472 as->prepareCallWithArgCount(5);
473 as->passInt32AsArg(argc, 4);
474 as->passJSSlotAsArg(argv, 3);
475 as->passAccumulatorAsArg(2);
476 as->passJSSlotAsArg(func, 1);
477 as->passEngineAsArg(0);
478 BASELINEJIT_GENERATE_RUNTIME_CALL(ConstructWithSpread, CallResultDestination::InAccumulator);
479}
480
481void BaselineJIT::generate_SetUnwindHandler(int offset)
482{
483 if (offset)
484 labels.insert(as->setUnwindHandler(absoluteOffset(offset)));
485 else
486 as->clearUnwindHandler();
487}
488
489void BaselineJIT::generate_UnwindDispatch()
490{
491 as->unwindDispatch();
492}
493
494void BaselineJIT::generate_UnwindToLabel(int level, int offset)
495{
496 labels.insert(as->unwindToLabel(level, absoluteOffset(offset)));
497}
498
499void BaselineJIT::generate_DeadTemporalZoneCheck(int name)
500{
501 as->deadTemporalZoneCheck(nextInstructionOffset(), name);
502}
503
504void BaselineJIT::generate_ThrowException()
505{
506 STORE_IP();
507 STORE_ACC();
508 as->prepareCallWithArgCount(2);
509 as->passAccumulatorAsArg(1);
510 as->passEngineAsArg(0);
511 BASELINEJIT_GENERATE_RUNTIME_CALL(ThrowException, CallResultDestination::Ignore);
512 as->gotoCatchException();
513
514 // LOAD_ACC(); <- not needed here since it would be unreachable.
515}
516
517void BaselineJIT::generate_GetException() { as->getException(); }
518void BaselineJIT::generate_SetException() { as->setException(); }
519
520void BaselineJIT::generate_CreateCallContext()
521{
522 STORE_ACC();
523 as->prepareCallWithArgCount(1);
524 as->passCppFrameAsArg(0);
525 BASELINEJIT_GENERATE_RUNTIME_CALL(PushCallContext, CallResultDestination::Ignore);
526 LOAD_ACC();
527}
528
529void BaselineJIT::generate_PushCatchContext(int index, int name) { as->pushCatchContext(index, name); }
530
531void BaselineJIT::generate_PushWithContext()
532{
533 STORE_IP();
534 as->saveAccumulatorInFrame();
535 as->prepareCallWithArgCount(2);
536 as->passJSSlotAsArg(CallData::Accumulator, 1);
537 as->passEngineAsArg(0);
538 BASELINEJIT_GENERATE_RUNTIME_CALL(PushWithContext, CallResultDestination::InAccumulator);
539}
540
541void BaselineJIT::generate_PushBlockContext(int index)
542{
543 as->saveAccumulatorInFrame();
544 as->prepareCallWithArgCount(2);
545 as->passInt32AsArg(index, 1);
546 as->passEngineAsArg(0);
547 BASELINEJIT_GENERATE_RUNTIME_CALL(PushBlockContext, CallResultDestination::Ignore);
548 as->loadAccumulatorFromFrame();
549}
550
551void BaselineJIT::generate_CloneBlockContext()
552{
553 as->saveAccumulatorInFrame();
554 as->prepareCallWithArgCount(1);
555 as->passEngineAsArg(0);
556 BASELINEJIT_GENERATE_RUNTIME_CALL(CloneBlockContext, CallResultDestination::Ignore);
557 as->loadAccumulatorFromFrame();
558}
559
560void BaselineJIT::generate_PushScriptContext(int index)
561{
562 as->saveAccumulatorInFrame();
563 as->prepareCallWithArgCount(2);
564 as->passInt32AsArg(index, 1);
565 as->passEngineAsArg(0);
566 BASELINEJIT_GENERATE_RUNTIME_CALL(PushScriptContext, CallResultDestination::Ignore);
567 as->loadAccumulatorFromFrame();
568}
569
570void BaselineJIT::generate_PopScriptContext()
571{
572 as->saveAccumulatorInFrame();
573 as->prepareCallWithArgCount(1);
574 as->passEngineAsArg(0);
575 BASELINEJIT_GENERATE_RUNTIME_CALL(PopScriptContext, CallResultDestination::Ignore);
576 as->loadAccumulatorFromFrame();
577}
578
579void BaselineJIT::generate_PopContext() { as->popContext(); }
580
581void BaselineJIT::generate_GetIterator(int iterator)
582{
583 as->saveAccumulatorInFrame();
584 as->prepareCallWithArgCount(3);
585 as->passInt32AsArg(iterator, 2);
586 as->passAccumulatorAsArg(1);
587 as->passEngineAsArg(0);
588 BASELINEJIT_GENERATE_RUNTIME_CALL(GetIterator, CallResultDestination::InAccumulator);
589}
590
591void BaselineJIT::generate_IteratorNext(int value, int offset)
592{
593 as->saveAccumulatorInFrame();
594 as->prepareCallWithArgCount(3);
595 as->passJSSlotAsArg(value, 2);
596 as->passAccumulatorAsArg(1);
597 as->passEngineAsArg(0);
598 BASELINEJIT_GENERATE_RUNTIME_CALL(IteratorNext, CallResultDestination::InAccumulator);
599 labels.insert(as->jumpTrue(absoluteOffset(offset)));
600}
601
602void BaselineJIT::generate_IteratorNextForYieldStar(int iterator, int object, int offset)
603{
604 as->saveAccumulatorInFrame();
605 as->prepareCallWithArgCount(4);
606 as->passJSSlotAsArg(object, 3);
607 as->passJSSlotAsArg(iterator, 2);
608 as->passAccumulatorAsArg(1);
609 as->passEngineAsArg(0);
610 BASELINEJIT_GENERATE_RUNTIME_CALL(IteratorNextForYieldStar, CallResultDestination::InAccumulator);
611 labels.insert(as->jumpTrue(absoluteOffset(offset)));
612}
613
614void BaselineJIT::generate_IteratorClose()
615{
616 as->saveAccumulatorInFrame();
617 as->prepareCallWithArgCount(2);
618 as->passAccumulatorAsArg(1);
619 as->passEngineAsArg(0);
620 BASELINEJIT_GENERATE_RUNTIME_CALL(IteratorClose, CallResultDestination::InAccumulator);
621}
622
623void BaselineJIT::generate_DestructureRestElement()
624{
625 as->saveAccumulatorInFrame();
626 as->prepareCallWithArgCount(2);
627 as->passAccumulatorAsArg(1);
628 as->passEngineAsArg(0);
629 BASELINEJIT_GENERATE_RUNTIME_CALL(DestructureRestElement, CallResultDestination::InAccumulator);
630}
631
632void BaselineJIT::generate_DeleteProperty(int base, int index)
633{
634 STORE_IP();
635 as->prepareCallWithArgCount(4);
636 as->passJSSlotAsArg(index, 3);
637 as->passJSSlotAsArg(base, 2);
638 as->passFunctionAsArg(1);
639 as->passEngineAsArg(0);
640 BASELINEJIT_GENERATE_RUNTIME_CALL(DeleteProperty, CallResultDestination::InAccumulator);
641}
642
643void BaselineJIT::generate_DeleteName(int name)
644{
645 STORE_IP();
646 as->prepareCallWithArgCount(3);
647 as->passInt32AsArg(name, 2);
648 as->passFunctionAsArg(1);
649 as->passEngineAsArg(0);
650 BASELINEJIT_GENERATE_RUNTIME_CALL(DeleteName, CallResultDestination::InAccumulator);
651}
652
653void BaselineJIT::generate_TypeofName(int name)
654{
655 as->prepareCallWithArgCount(2);
656 as->passInt32AsArg(name, 1);
657 as->passEngineAsArg(0);
658 BASELINEJIT_GENERATE_RUNTIME_CALL(TypeofName, CallResultDestination::InAccumulator);
659}
660
661void BaselineJIT::generate_TypeofValue()
662{
663 STORE_ACC();
664 as->prepareCallWithArgCount(2);
665 as->passAccumulatorAsArg(1);
666 as->passEngineAsArg(0);
667 BASELINEJIT_GENERATE_RUNTIME_CALL(TypeofValue, CallResultDestination::InAccumulator);
668}
669
670void BaselineJIT::generate_DeclareVar(int varName, int isDeletable)
671{
672 STORE_ACC();
673 as->prepareCallWithArgCount(3);
674 as->passInt32AsArg(varName, 2);
675 as->passInt32AsArg(isDeletable, 1);
676 as->passEngineAsArg(0);
677 BASELINEJIT_GENERATE_RUNTIME_CALL(DeclareVar, CallResultDestination::Ignore);
678 LOAD_ACC();
679}
680
681void BaselineJIT::generate_DefineArray(int argc, int args)
682{
683 as->prepareCallWithArgCount(3);
684 as->passInt32AsArg(argc, 2);
685 as->passJSSlotAsArg(args, 1);
686 as->passEngineAsArg(0);
687 BASELINEJIT_GENERATE_RUNTIME_CALL(ArrayLiteral, CallResultDestination::InAccumulator);
688}
689
690void BaselineJIT::generate_DefineObjectLiteral(int internalClassId, int argc, int args)
691{
692 as->prepareCallWithArgCount(4);
693 as->passInt32AsArg(argc, 3);
694 as->passJSSlotAsArg(args, 2);
695 as->passInt32AsArg(internalClassId, 1);
696 as->passEngineAsArg(0);
697 BASELINEJIT_GENERATE_RUNTIME_CALL(ObjectLiteral, CallResultDestination::InAccumulator);
698}
699
700void BaselineJIT::generate_CreateClass(int classIndex, int heritage, int computedNames)
701{
702 as->prepareCallWithArgCount(4);
703 as->passJSSlotAsArg(computedNames, 3);
704 as->passJSSlotAsArg(heritage, 2);
705 as->passInt32AsArg(classIndex, 1);
706 as->passEngineAsArg(0);
707 BASELINEJIT_GENERATE_RUNTIME_CALL(CreateClass, CallResultDestination::InAccumulator);
708}
709
710void BaselineJIT::generate_CreateMappedArgumentsObject()
711{
712 as->prepareCallWithArgCount(1);
713 as->passEngineAsArg(0);
714 BASELINEJIT_GENERATE_RUNTIME_CALL(CreateMappedArgumentsObject,
715 CallResultDestination::InAccumulator);
716}
717
718void BaselineJIT::generate_CreateUnmappedArgumentsObject()
719{
720 as->prepareCallWithArgCount(1);
721 as->passEngineAsArg(0);
722 BASELINEJIT_GENERATE_RUNTIME_CALL(CreateUnmappedArgumentsObject,
723 CallResultDestination::InAccumulator);
724}
725
726void BaselineJIT::generate_CreateRestParameter(int argIndex)
727{
728 as->prepareCallWithArgCount(2);
729 as->passInt32AsArg(argIndex, 1);
730 as->passEngineAsArg(0);
731 BASELINEJIT_GENERATE_RUNTIME_CALL(CreateRestParameter, CallResultDestination::InAccumulator);
732}
733
734void BaselineJIT::generate_ConvertThisToObject()
735{
736 STORE_ACC();
737 as->prepareCallWithArgCount(2);
738 as->passJSSlotAsArg(CallData::This, 1);
739 as->passEngineAsArg(0);
740 BASELINEJIT_GENERATE_RUNTIME_CALL(ConvertThisToObject, CallResultDestination::InAccumulator);
741 as->storeReg(CallData::This);
742 LOAD_ACC();
743}
744
745void BaselineJIT::generate_LoadSuperConstructor()
746{
747 as->prepareCallWithArgCount(2);
748 as->passJSSlotAsArg(CallData::Function, 1);
749 as->passEngineAsArg(0);
750 BASELINEJIT_GENERATE_RUNTIME_CALL(LoadSuperConstructor, CallResultDestination::InAccumulator);
751}
752
753void BaselineJIT::generate_ToObject()
754{
755 STORE_ACC();
756 as->prepareCallWithArgCount(2);
757 as->passAccumulatorAsArg(1);
758 as->passEngineAsArg(0);
759 BASELINEJIT_GENERATE_RUNTIME_CALL(ToObject, CallResultDestination::InAccumulator);
760
761}
762
763void BaselineJIT::generate_Jump(int offset)
764{
765 labels.insert(as->jump(absoluteOffset(offset)));
766}
767
768void BaselineJIT::generate_JumpTrue(int offset)
769{
770 labels.insert(as->jumpTrue(absoluteOffset(offset)));
771}
772
773void BaselineJIT::generate_JumpFalse(int offset)
774{
775 labels.insert(as->jumpFalse(absoluteOffset(offset)));
776}
777
778void BaselineJIT::generate_JumpNoException(int offset)
779{
780 labels.insert(as->jumpNoException(absoluteOffset(offset)));
781}
782
783void BaselineJIT::generate_JumpNotUndefined(int offset)
784{
785 labels.insert(as->jumpNotUndefined(absoluteOffset(offset)));
786}
787
788void BaselineJIT::generate_CheckException()
789{
790 as->checkException();
791}
792
793void BaselineJIT::generate_CmpEqNull() { as->cmpeqNull(); }
794void BaselineJIT::generate_CmpNeNull() { as->cmpneNull(); }
795void BaselineJIT::generate_CmpEqInt(int lhs) { as->cmpeqInt(lhs); }
796void BaselineJIT::generate_CmpNeInt(int lhs) { as->cmpneInt(lhs); }
797void BaselineJIT::generate_CmpEq(int lhs) { as->cmpeq(lhs); }
798void BaselineJIT::generate_CmpNe(int lhs) { as->cmpne(lhs); }
799void BaselineJIT::generate_CmpGt(int lhs) { as->cmpgt(lhs); }
800void BaselineJIT::generate_CmpGe(int lhs) { as->cmpge(lhs); }
801void BaselineJIT::generate_CmpLt(int lhs) { as->cmplt(lhs); }
802void BaselineJIT::generate_CmpLe(int lhs) { as->cmple(lhs); }
803void BaselineJIT::generate_CmpStrictEqual(int lhs) { as->cmpStrictEqual(lhs); }
804void BaselineJIT::generate_CmpStrictNotEqual(int lhs) { as->cmpStrictNotEqual(lhs); }
805
806void BaselineJIT::generate_CmpIn(int lhs)
807{
808 STORE_IP();
809 STORE_ACC();
810 as->prepareCallWithArgCount(3);
811 as->passAccumulatorAsArg(2);
812 as->passJSSlotAsArg(lhs, 1);
813 as->passEngineAsArg(0);
814 BASELINEJIT_GENERATE_RUNTIME_CALL(In, CallResultDestination::InAccumulator);
815}
816
817void BaselineJIT::generate_CmpInstanceOf(int lhs)
818{
819 STORE_ACC();
820 as->prepareCallWithArgCount(3);
821 as->passAccumulatorAsArg(2);
822 as->passJSSlotAsArg(lhs, 1);
823 as->passEngineAsArg(0);
824 BASELINEJIT_GENERATE_RUNTIME_CALL(Instanceof, CallResultDestination::InAccumulator);
825}
826
827void BaselineJIT::generate_As(int lhs)
828{
829 STORE_ACC();
830 as->prepareCallWithArgCount(3);
831 as->passAccumulatorAsArg(2);
832 as->passJSSlotAsArg(lhs, 1);
833 as->passEngineAsArg(0);
834 BASELINEJIT_GENERATE_RUNTIME_CALL(As, CallResultDestination::InAccumulator);
835}
836
837void BaselineJIT::generate_UNot() { as->unot(); }
838void BaselineJIT::generate_UPlus() { as->toNumber(); }
839void BaselineJIT::generate_UMinus() { as->uminus(); }
840void BaselineJIT::generate_UCompl() { as->ucompl(); }
841void BaselineJIT::generate_Increment() { as->inc(); }
842void BaselineJIT::generate_Decrement() { as->dec(); }
843void BaselineJIT::generate_Add(int lhs) { as->add(lhs); }
844
845void BaselineJIT::generate_BitAnd(int lhs) { as->bitAnd(lhs); }
846void BaselineJIT::generate_BitOr(int lhs) { as->bitOr(lhs); }
847void BaselineJIT::generate_BitXor(int lhs) { as->bitXor(lhs); }
848void BaselineJIT::generate_UShr(int lhs) { as->ushr(lhs); }
849void BaselineJIT::generate_Shr(int lhs) { as->shr(lhs); }
850void BaselineJIT::generate_Shl(int lhs) { as->shl(lhs); }
851
852void BaselineJIT::generate_BitAndConst(int rhs) { as->bitAndConst(rhs); }
853void BaselineJIT::generate_BitOrConst(int rhs) { as->bitOrConst(rhs); }
854void BaselineJIT::generate_BitXorConst(int rhs) { as->bitXorConst(rhs); }
855void BaselineJIT::generate_UShrConst(int rhs) { as->ushrConst(rhs); }
856void BaselineJIT::generate_ShrConst(int rhs) { as->shrConst(rhs); }
857void BaselineJIT::generate_ShlConst(int rhs) { as->shlConst(rhs); }
858
859void BaselineJIT::generate_Exp(int lhs) {
860 STORE_IP();
861 STORE_ACC();
862 as->prepareCallWithArgCount(2);
863 as->passAccumulatorAsArg(1);
864 as->passJSSlotAsArg(lhs, 0);
865 BASELINEJIT_GENERATE_RUNTIME_CALL(Exp, CallResultDestination::InAccumulator);
866}
867void BaselineJIT::generate_Mul(int lhs) { as->mul(lhs); }
868void BaselineJIT::generate_Div(int lhs) { as->div(lhs); }
869void BaselineJIT::generate_Mod(int lhs) { as->mod(lhs); }
870void BaselineJIT::generate_Sub(int lhs) { as->sub(lhs); }
871
872//void BaselineJIT::generate_BinopContext(int alu, int lhs)
873//{
874// auto engine = function->internalClass->engine;
875// void *op = engine->runtime.runtimeMethods[alu];
876// STORE_ACC();
877// as->passAccumulatorAsArg(2);
878// as->passRegAsArg(lhs, 1);
879// as->passEngineAsArg(0);
880// as->callRuntime("binopContext", op, CallResultDestination::InAccumulator);
881// as->checkException();
882//}
883
884void BaselineJIT::generate_InitializeBlockDeadTemporalZone(int firstReg, int count)
885{
886 as->loadValue(Value::emptyValue().rawValue());
887 for (int i = firstReg, end = firstReg + count; i < end; ++i)
888 as->storeReg(i);
889}
890
891void BaselineJIT::generate_ThrowOnNullOrUndefined()
892{
893 STORE_ACC();
894 as->prepareCallWithArgCount(2);
895 as->passAccumulatorAsArg(1);
896 as->passEngineAsArg(0);
897 BASELINEJIT_GENERATE_RUNTIME_CALL(ThrowOnNullOrUndefined, CallResultDestination::Ignore);
898 LOAD_ACC();
899}
900
901void BaselineJIT::generate_GetTemplateObject(int index)
902{
903 as->prepareCallWithArgCount(2);
904 as->passInt32AsArg(index, 1);
905 as->passFunctionAsArg(0);
906 BASELINEJIT_GENERATE_RUNTIME_CALL(GetTemplateObject, CallResultDestination::InAccumulator);
907}
908
909ByteCodeHandler::Verdict BaselineJIT::startInstruction(Instr::Type /*instr*/)
910{
911 if (labels.contains(currentInstructionOffset()))
912 as->addLabel(currentInstructionOffset());
913 return ProcessInstruction;
914}
915
916void BaselineJIT::endInstruction(Instr::Type instr)
917{
918 Q_UNUSED(instr);
919}
920
921#endif // QT_CONFIG(qml_jit)