File: doc_adv_jit.h

package info (click to toggle)
angelscript 2.35.1%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 5,388 kB
  • sloc: cpp: 71,969; asm: 1,558; makefile: 665; xml: 214; javascript: 42; python: 22; ansic: 22; sh: 7
file content (601 lines) | stat: -rw-r--r-- 14,792 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
/**

\page doc_adv_jit How to build a JIT compiler

AngelScript doesn't provide a built-in JIT compiler, instead it permits an external JIT compiler to be implemented 
through a public interface.

To use JIT compilation, the scripts must be compiled with a few extra instructions that provide hints to the JIT compiler
and also entry points so that the VM will know when to pass control to the JIT compiled function. By default this is 
turned off, and must thus be turned on by setting the engine property \ref asEP_INCLUDE_JIT_INSTRUCTIONS.

If the application sets the \ref asIJITCompiler "JIT compiler" with \ref asIScriptEngine::SetJITCompiler "SetJITCompiler" 
AngelScript will automatically invoke it to provide the \ref asJITFunction "JIT functions" with each compilation or 
\ref doc_adv_precompile "loading of pre-compiled bytecode".




\section doc_adv_jit_3 The structure of the JIT function

The \ref asJITFunction "JIT compiled function" must follow certain rules in order to behave well with the virtual machine. The intention
is that the VM will pass the control to the JIT function, and when the execution is to be suspended the JIT function
returns the control to the VM, updating the internal state of the VM so that the VM can resume the execution when
requested. Each time the JIT function returns control to the VM it must make sure that the \ref asSVMRegisters "VM registers" and stack values
have been updated according to the code that was executed.

The byte code will have a special instruction, \ref asBC_JitEntry "JitEntry", which defines the positions where the VM
can pass the control to the JIT function. These are usually placed for every script statement, and after each instruction
that calls another function. This implies that the JIT compiled function needs to be able to start the execution at 
different points based on the argument in the JitEntry instruction. The value of the argument is defined by the JIT compiler
and how it is interpreted is also up to the JIT compiler, with the exception of 0 that means that the control should not be 
passed to the JIT function.

Some byte code instructions are not meant to be converted into native code. These are usually the ones that have a more 
global effect on the VM, e.g. the instructions that setup a call to a new script function, or that return from a previous 
instruction. When these functions are encountered, the JIT function should return the control to the VM, and then the VM
will execute the instruction. 

Other byte code instructions may be partially implemented by the JIT function, for example those that can throw an exception
based on specific conditions. One such example is the instructions for divisions, if the divider is 0 the VM will set
an exception and abort the execution. For these instructions the JIT compiler should preferrably implement the condition
that doesn't throw an exception, and if an exception is to be thrown the JIT function will instead break out to the VM.

The following shows a possible structure of a JIT compiled function:

<pre>
  void jitCompiledFunc(asSVMRegisters *regs, asPWORD jitArg)
  {
    Read desired VM registers into CPU registers.
    Jump to the current position of the function based on the 'jitArg' argument.
  1:
    Execute code in block 1.
    Jump to exit if an illegal operation is done, e.g. divide by zero. 
    Jump to exit if block ends with an instruction that should not be executed by JIT function. 
  2:
    ...
  3:
    ...
  exit:
    Update the VM registers before returning control to VM.
    If necessary the function can invoke the methods of the context informed 
    in the regs, e.g. to suspend the execution, or to set a script exception.
  }
</pre>



\section doc_adv_jit_2 Traversing the byte code


\code
int CJITCompiler::CompileFunction(asIScriptFunction *func, asJITFunction *output)
{
  bool success = StartNewCompilation();

  // Get the script byte code
  asUINT   length;
  asDWORD *byteCode = func->GetByteCode(&length);
  asDWORD *end = byteCode + length;
  
  while( byteCode < end )
  {
    // Determine the instruction
    asEBCInstr op = asEBCInstr(*(asBYTE*)byteCode);
    switch( op )
    {
    // Translate each byte code instruction into native code.
    // The codes that cannot be translated should return the control
    // to the VM, so that it can continue the processing. When 
    // the VM encounters the next JitEntry instruction it will
    // transfer the control back to the JIT function.
    ...
    
    case asBC_JitEntry:
      // Update the argument for the JitEntry instruction with  
      // the argument that should be sent to the jit function.
      // Remember that 0 means that the VM should not pass
      // control to the JIT function.
      asBC_PTRARG(byteCode) = DetermineJitEntryArg();
      break;
    }
    
    // Move to next instruction
    byteCode += asBCTypeSize[asBCInfo[op].type];
  }
  
  if( success )
  {
    *output = GetCompiledFunction();
    return 0;
  }
  
  return -1;
}
\endcode

The following macros should be used to read the arguments from the bytecode instruction. 
The layout of the arguments is determined from the \ref asBCInfo array.

 - \ref asBC_DWORDARG
 - \ref asBC_INTARG
 - \ref asBC_QWORDARG
 - \ref asBC_FLOATARG
 - \ref asBC_PTRARG
 - \ref asBC_WORDARG0
 - \ref asBC_WORDARG1
 - \ref asBC_SWORDARG0
 - \ref asBC_SWORDARG1
 - \ref asBC_SWORDARG2

What each \ref asEBCInstr "byte code" instruction does is described in \ref doc_adv_jit_1, but the exact 
implementation of each byte code instruction is best determined from the implementation
in the VM, i.e. the asCScriptContext::ExecuteNext method.







\page doc_adv_jit_1 Byte code instructions

This page gives a brief description of each of the byte code instructions that the virtual machine has.


 - \ref doc_adv_jit_1_1
 - \ref doc_adv_jit_1_2
 - \ref doc_adv_jit_1_3
 - \ref doc_adv_jit_1_4
 - \ref doc_adv_jit_1_5
 - \ref doc_adv_jit_1_6
 - \ref doc_adv_jit_1_7
 - \ref doc_adv_jit_1_8
 - \ref doc_adv_jit_1_9
 - \ref doc_adv_jit_1_10




\section doc_adv_jit_1_1 Object management

Perform a bitwise copy of a memory buffer to another

 - \ref asBC_COPY

Push the address and length of a string on the stack

 - \ref asBC_STR
 
Allocate the memory for an object and setup the VM to execute the constructor
 
 - \ref asBC_ALLOC
 
Release the memory of an object or list buffer
 
 - \ref asBC_FREE
 
Move the address in an object variable to the object register. The address in the variable is then cleared.
 
 - \ref asBC_LOADOBJ
 
Move the address from the object register to an object variable. The address in the object register is then cleared.
 
 - \ref asBC_STOREOBJ

Copy the object handle from one address to another. The reference count of the object is updated to reflect the copy.

 - \ref asBC_REFCPY
 
Copy the object handle on stack to a handle in a variable. The reference count of the object is updated to reflect the copy.

 - \ref asBC_RefCpyV
 
Push the pointer of an object type on the stack
 
 - \ref asBC_OBJTYPE
 
Push the type id on the stack
 
 - \ref asBC_TYPEID
 
Pop an address to a script object from the stack. If the desired cast can be made store the address in the object register.
 
 - \ref asBC_Cast

Push the function pointer on the stack

 - \ref asBC_FuncPtr

Load the address to a property of the object into the value register. Substitutes the sequence PshV4/8, ADDSi, PopRPtr.

 - \ref asBC_LoadThisR
 - \ref asBC_LoadRObjR

Load the address to a property of a value object into the value register. Substitutes the sequence PSF, ADDSi, PopRPtr.

 - \ref asBC_LoadVObjR

 



\section doc_adv_jit_1_2 Math instructions

Negate the value in the variable. The original value is overwritten.

 - \ref asBC_NEGi
 - \ref asBC_NEGf
 - \ref asBC_NEGd
 - \ref asBC_NEGi64

Perform the operation with the value of two variables and store the result in a third variable.

 - \ref asBC_ADDi
 - \ref asBC_SUBi
 - \ref asBC_MULi
 - \ref asBC_DIVi
 - \ref asBC_MODi
 - \ref asBC_POWi
 - \ref asBC_POWu

 - \ref asBC_ADDf
 - \ref asBC_SUBf
 - \ref asBC_MULf
 - \ref asBC_DIVf
 - \ref asBC_MODf
 - \ref asBC_POWf

 - \ref asBC_ADDd
 - \ref asBC_SUBd
 - \ref asBC_MULd
 - \ref asBC_DIVd
 - \ref asBC_MODd
 - \ref asBC_POWd
 - \ref asBC_POWdi

 - \ref asBC_ADDi64
 - \ref asBC_SUBi64
 - \ref asBC_MULi64
 - \ref asBC_DIVi64
 - \ref asBC_MODi64
 - \ref asBC_POWi64
 - \ref asBC_POWu64

Perform the operation with a constant value and the value of the variable. The original value is overwritten.

 - \ref asBC_ADDIi
 - \ref asBC_SUBIi
 - \ref asBC_MULIi

 - \ref asBC_ADDIf
 - \ref asBC_SUBIf
 - \ref asBC_MULIf




\section doc_adv_jit_1_3 Bitwise instructions

Perform a boolean not operation on the value in the variable. The original value is overwritten.

 - \ref asBC_NOT

Perform a bitwise complement on the value in the variable. The original value is overwritten.

 - \ref asBC_BNOT
 - \ref asBC_BNOT64

Perform the operation with the value of two variables and store the result in a third variable.

 - \ref asBC_BAND
 - \ref asBC_BOR
 - \ref asBC_BXOR
 
 - \ref asBC_BAND64
 - \ref asBC_BOR64
 - \ref asBC_BXOR64
 
 - \ref asBC_BSLL
 - \ref asBC_BSRL
 - \ref asBC_BSRA

 - \ref asBC_BSLL64
 - \ref asBC_BSRL64
 - \ref asBC_BSRA64




\section doc_adv_jit_1_4 Comparisons

Compare the value of two variables and store the result in the value register.

 - \ref asBC_CMPi
 - \ref asBC_CMPu
 - \ref asBC_CMPf
 - \ref asBC_CMPd
 - \ref asBC_CMPi64
 - \ref asBC_CMPu64
 - \ref asBC_CmpPtr

Compare the value of a variable with a constant and store the result in the value register.

 - \ref asBC_CMPIi
 - \ref asBC_CMPIu
 - \ref asBC_CMPIf

Test the value in the value register. Update the value register according to the result.

 - \ref asBC_TZ
 - \ref asBC_TNZ
 - \ref asBC_TS
 - \ref asBC_TNS
 - \ref asBC_TP
 - \ref asBC_TNP




\section doc_adv_jit_1_5 Type conversions

Convert the value in the variable. The original value is overwritten.

 - \ref asBC_iTOb
 - \ref asBC_iTOw
 - \ref asBC_sbTOi
 - \ref asBC_swTOi
 - \ref asBC_ubTOi
 - \ref asBC_uwTOi

 - \ref asBC_iTOf
 - \ref asBC_fTOi
 - \ref asBC_uTOf
 - \ref asBC_fTOu

 - \ref asBC_dTOi64
 - \ref asBC_dTOu64
 - \ref asBC_i64TOd
 - \ref asBC_u64TOd

Convert the value of a variable and store the result in another variable.

 - \ref asBC_dTOi
 - \ref asBC_dTOu
 - \ref asBC_dTOf
 - \ref asBC_iTOd
 - \ref asBC_uTOd
 - \ref asBC_fTOd

 - \ref asBC_i64TOi
 - \ref asBC_i64TOf
 - \ref asBC_u64TOf
 - \ref asBC_uTOi64
 - \ref asBC_iTOi64
 - \ref asBC_fTOi64
 - \ref asBC_fTOu64
 
 
 
 
\section doc_adv_jit_1_6 Increment and decrement

Increment or decrement the value pointed to by the address in the value register.

 - \ref asBC_INCi8
 - \ref asBC_DECi8
 - \ref asBC_INCi16
 - \ref asBC_DECi16
 - \ref asBC_INCi
 - \ref asBC_DECi
 - \ref asBC_INCi64
 - \ref asBC_DECi64
 - \ref asBC_INCf
 - \ref asBC_DECf
 - \ref asBC_INCd
 - \ref asBC_DECd

Increment or decrement the value in the variable.

 - \ref asBC_IncVi
 - \ref asBC_DecVi




\section doc_adv_jit_1_7 Flow control

Setup the VM to begin execution of the other script function

 - \ref asBC_CALL
 - \ref asBC_CALLINTF
 - \ref asBC_CALLBND
 - \ref asBC_CallPtr
 
Setup the VM to return to the calling function 
 
 - \ref asBC_RET

Make an unconditional jump to a relative position
 
 - \ref asBC_JMP
 
Make a jump to a relative position depending on the value in the value register

 - \ref asBC_JZ
 - \ref asBC_JNZ
 - \ref asBC_JS
 - \ref asBC_JNS
 - \ref asBC_JP
 - \ref asBC_JNP
 - \ref asBC_JMPP
 - \ref asBC_JLowZ
 - \ref asBC_JLowNZ

Call an application registered function

 - \ref asBC_CALLSYS
 - \ref asBC_Thiscall1

Save the state and suspend execution, then return control to the application

 - \ref asBC_SUSPEND

Give control of execution to the JIT compiled function
 
 - \ref asBC_JitEntry
 
 
 

\section doc_adv_jit_1_8 Stack and data management

Push a constant value on the stack.
 
 - \ref asBC_PshC4
 - \ref asBC_PshC8
 - \ref asBC_PshNull

Push the stack frame pointer on the stack.
 
 - \ref asBC_PSF

Swap the top values on the stack.

 - \ref asBC_SwapPtr

Dereference top pointer on stack. Raises exception if pointer is null.

 - \ref asBC_RDSPtr

Add an offset to the top address on the stack. Raises exception if address is null.

 - \ref asBC_ADDSi

Push the value of a variable on the stack.

 - \ref asBC_PshV4
 - \ref asBC_PshV8
 - \ref asBC_PshVPtr

Initialize the value of a variable with a constant.
 
 - \ref asBC_SetV1
 - \ref asBC_SetV2
 - \ref asBC_SetV4
 - \ref asBC_SetV8
 - \ref asBC_ClrVPtr

Copy the value of one variable to another.
 
 - \ref asBC_CpyVtoV4
 - \ref asBC_CpyVtoV8

Validate that an expected pointer is not null.

 - \ref asBC_CHKREF
 - \ref asBC_ChkRefS
 - \ref asBC_ChkNullV
 - \ref asBC_ChkNullS

Push the variable index with the size of a pointer on the stack.

 - \ref asBC_VAR

Replace a variable index on the stack with an address.
 
 - \ref asBC_GETREF
 - \ref asBC_GETOBJ
 - \ref asBC_GETOBJREF

Pop and discard an address from the stack.

 - \ref asBC_PopPtr
 
Pop or push an address to or from the value register.

 - \ref asBC_PopRPtr
 - \ref asBC_PshRPtr
 
Copy a value between value register and a variable.
 
 - \ref asBC_CpyVtoR4
 - \ref asBC_CpyVtoR8
 - \ref asBC_CpyRtoV4
 - \ref asBC_CpyRtoV8

Copy a value from a variable to the address held in the value register

 - \ref asBC_WRTV1
 - \ref asBC_WRTV2
 - \ref asBC_WRTV4
 - \ref asBC_WRTV8

Copy a value from the address held in the value register to a variable
 
 - \ref asBC_RDR1
 - \ref asBC_RDR2
 - \ref asBC_RDR4
 - \ref asBC_RDR8

Load the address of the variable into the value register

 - \ref asBC_LDV
 
Clear the upper bytes of the value register
 
 - \ref asBC_ClrHi




\section doc_adv_jit_1_9 Global variables

Push the value of a global variable on the stack

 - \ref asBC_PshG4
 - \ref asBC_PshGPtr

Load the address of a global variable into the value register

 - \ref asBC_LDG
 
Load the address of a global variable into the value register and copy the value of the global variable to local variable
 
 - \ref asBC_LdGRdR4

Copy a value between local variable and global variable.

 - \ref asBC_CpyVtoG4
 - \ref asBC_CpyGtoV4
 
Push the address of the global variable on the stack.

 - \ref asBC_PGA

Initialize the variable of a global variable with a constant.

 - \ref asBC_SetG4


 
\section doc_adv_jit_1_10 Initialization list management
 
Allocates the memory for the initialization list buffer
 
- \ref asBC_AllocMem

Sets the number of elements that will be repeated afterwards

- \ref asBC_SetListSize

Sets the type of the next element

- \ref asBC_SetListType

Pushes the address of the list element on the stack

- \ref asBC_PshListElmnt
 
 
*/