aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-23 23:36:30 +1000
committerDavid Walter Seikel2012-01-23 23:36:30 +1000
commit6523585c66c04cea54df50013df8886b589847d8 (patch)
tree0b22aee7064166d88595eda260ca2d17c0773da5 /libraries
parentUpdate the EFL to what I'm actually using, coz I'm using some stuff not yet r... (diff)
downloadSledjHamr-6523585c66c04cea54df50013df8886b589847d8.zip
SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.gz
SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.bz2
SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.xz
Add luaproc and LuaJIT libraries.
Two versions of LuaJIT, the stable release, and the dev version. Try the dev version first, until ih fails badly.
Diffstat (limited to 'libraries')
-rw-r--r--libraries/LuaJIT-1.1.7/COPYRIGHT40
-rw-r--r--libraries/LuaJIT-1.1.7/Makefile130
-rw-r--r--libraries/LuaJIT-1.1.7/README46
-rw-r--r--libraries/LuaJIT-1.1.7/doc/amazon.gifbin0 -> 797 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/doc/contents.html499
-rw-r--r--libraries/LuaJIT-1.1.7/doc/cover.pngbin0 -> 3305 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/doc/logo.gifbin0 -> 4232 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/doc/lua.1163
-rw-r--r--libraries/LuaJIT-1.1.7/doc/lua.css41
-rw-r--r--libraries/LuaJIT-1.1.7/doc/lua.html172
-rw-r--r--libraries/LuaJIT-1.1.7/doc/luac.1136
-rw-r--r--libraries/LuaJIT-1.1.7/doc/luac.html145
-rw-r--r--libraries/LuaJIT-1.1.7/doc/manual.css13
-rw-r--r--libraries/LuaJIT-1.1.7/doc/manual.html8801
-rw-r--r--libraries/LuaJIT-1.1.7/doc/readme.html40
-rw-r--r--libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h68
-rw-r--r--libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h455
-rw-r--r--libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua1581
-rw-r--r--libraries/LuaJIT-1.1.7/dynasm/dynasm.lua1070
-rw-r--r--libraries/LuaJIT-1.1.7/etc/README20
-rw-r--r--libraries/LuaJIT-1.1.7/etc/lua.hpp9
-rw-r--r--libraries/LuaJIT-1.1.7/etc/luajit.icobin0 -> 1078 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/etc/luajit.pc28
-rwxr-xr-xlibraries/LuaJIT-1.1.7/etc/luavs.bat22
-rw-r--r--libraries/LuaJIT-1.1.7/etc/strict.lua41
-rw-r--r--libraries/LuaJIT-1.1.7/jit/dis_x86.lua622
-rw-r--r--libraries/LuaJIT-1.1.7/jit/dump.lua265
-rw-r--r--libraries/LuaJIT-1.1.7/jit/dumphints.lua239
-rw-r--r--libraries/LuaJIT-1.1.7/jit/opt.lua508
-rw-r--r--libraries/LuaJIT-1.1.7/jit/opt_inline.lua397
-rw-r--r--libraries/LuaJIT-1.1.7/jit/trace.lua111
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css166
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/bluequad.css292
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/coco.html132
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/coco_api.html182
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/coco_changes.html146
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/coco_portability.html235
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/contact.html105
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/dynasm.html116
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/dynasm_examples.html188
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/dynasm_features.html139
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/img/backbar.pngbin0 -> 118 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/img/bluebar.pngbin0 -> 134 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/img/contact.pngbin0 -> 1340 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/img/magentabar.pngbin0 -> 152 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/img/spacer.pngbin0 -> 95 bytes
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/index.html103
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit.html109
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit_api.html372
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit_changes.html301
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit_debug.html273
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit_features.html226
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit_install.html340
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit_intro.html389
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit_performance.html394
-rw-r--r--libraries/LuaJIT-1.1.7/jitdoc/luajit_run.html159
-rw-r--r--libraries/LuaJIT-1.1.7/src/Makefile252
-rw-r--r--libraries/LuaJIT-1.1.7/src/lapi.c1082
-rw-r--r--libraries/LuaJIT-1.1.7/src/lapi.h16
-rw-r--r--libraries/LuaJIT-1.1.7/src/lauxlib.c652
-rw-r--r--libraries/LuaJIT-1.1.7/src/lauxlib.h174
-rw-r--r--libraries/LuaJIT-1.1.7/src/lbaselib.c679
-rw-r--r--libraries/LuaJIT-1.1.7/src/lcoco.c693
-rw-r--r--libraries/LuaJIT-1.1.7/src/lcoco.h72
-rw-r--r--libraries/LuaJIT-1.1.7/src/lcode.c831
-rw-r--r--libraries/LuaJIT-1.1.7/src/lcode.h76
-rw-r--r--libraries/LuaJIT-1.1.7/src/ldblib.c398
-rw-r--r--libraries/LuaJIT-1.1.7/src/ldebug.c640
-rw-r--r--libraries/LuaJIT-1.1.7/src/ldebug.h33
-rw-r--r--libraries/LuaJIT-1.1.7/src/ldo.c519
-rw-r--r--libraries/LuaJIT-1.1.7/src/ldo.h59
-rw-r--r--libraries/LuaJIT-1.1.7/src/ldump.c164
-rw-r--r--libraries/LuaJIT-1.1.7/src/lfunc.c182
-rw-r--r--libraries/LuaJIT-1.1.7/src/lfunc.h34
-rw-r--r--libraries/LuaJIT-1.1.7/src/lgc.c711
-rw-r--r--libraries/LuaJIT-1.1.7/src/lgc.h110
-rw-r--r--libraries/LuaJIT-1.1.7/src/linit.c39
-rw-r--r--libraries/LuaJIT-1.1.7/src/liolib.c556
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit.h167
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_backend.c342
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_core.c385
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_dasm.c38
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_dasm.h19
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_hints.h137
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_mem.c405
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_x86.dasc2457
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_x86.dash297
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_x86.h2301
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_x86_inline.dash625
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljitlib.c637
-rw-r--r--libraries/LuaJIT-1.1.7/src/llex.c463
-rw-r--r--libraries/LuaJIT-1.1.7/src/llex.h81
-rw-r--r--libraries/LuaJIT-1.1.7/src/llimits.h128
-rw-r--r--libraries/LuaJIT-1.1.7/src/lmathlib.c263
-rw-r--r--libraries/LuaJIT-1.1.7/src/lmem.c86
-rw-r--r--libraries/LuaJIT-1.1.7/src/lmem.h49
-rw-r--r--libraries/LuaJIT-1.1.7/src/loadlib.c669
-rw-r--r--libraries/LuaJIT-1.1.7/src/lobject.c214
-rw-r--r--libraries/LuaJIT-1.1.7/src/lobject.h386
-rw-r--r--libraries/LuaJIT-1.1.7/src/lopcodes.c102
-rw-r--r--libraries/LuaJIT-1.1.7/src/lopcodes.h268
-rw-r--r--libraries/LuaJIT-1.1.7/src/loslib.c244
-rw-r--r--libraries/LuaJIT-1.1.7/src/lparser.c1339
-rw-r--r--libraries/LuaJIT-1.1.7/src/lparser.h82
-rw-r--r--libraries/LuaJIT-1.1.7/src/lstate.c218
-rw-r--r--libraries/LuaJIT-1.1.7/src/lstate.h179
-rw-r--r--libraries/LuaJIT-1.1.7/src/lstring.c111
-rw-r--r--libraries/LuaJIT-1.1.7/src/lstring.h31
-rw-r--r--libraries/LuaJIT-1.1.7/src/lstrlib.c871
-rw-r--r--libraries/LuaJIT-1.1.7/src/ltable.c588
-rw-r--r--libraries/LuaJIT-1.1.7/src/ltable.h41
-rw-r--r--libraries/LuaJIT-1.1.7/src/ltablib.c287
-rw-r--r--libraries/LuaJIT-1.1.7/src/ltm.c75
-rw-r--r--libraries/LuaJIT-1.1.7/src/ltm.h54
-rw-r--r--libraries/LuaJIT-1.1.7/src/lua.c463
-rw-r--r--libraries/LuaJIT-1.1.7/src/lua.h385
-rw-r--r--libraries/LuaJIT-1.1.7/src/luac.c200
-rw-r--r--libraries/LuaJIT-1.1.7/src/luaconf.h786
-rw-r--r--libraries/LuaJIT-1.1.7/src/luajit.h68
-rw-r--r--libraries/LuaJIT-1.1.7/src/lualib.h56
-rw-r--r--libraries/LuaJIT-1.1.7/src/lundump.c227
-rw-r--r--libraries/LuaJIT-1.1.7/src/lundump.h36
-rw-r--r--libraries/LuaJIT-1.1.7/src/lvm.c766
-rw-r--r--libraries/LuaJIT-1.1.7/src/lvm.h40
-rw-r--r--libraries/LuaJIT-1.1.7/src/lzio.c82
-rw-r--r--libraries/LuaJIT-1.1.7/src/lzio.h67
-rw-r--r--libraries/LuaJIT-1.1.7/src/print.c227
-rw-r--r--libraries/luajit-2.0/.gitignore11
-rw-r--r--libraries/luajit-2.0/COPYRIGHT56
-rw-r--r--libraries/luajit-2.0/Makefile142
-rw-r--r--libraries/luajit-2.0/README16
-rw-r--r--libraries/luajit-2.0/doc/bluequad-print.css166
-rw-r--r--libraries/luajit-2.0/doc/bluequad.css306
-rw-r--r--libraries/luajit-2.0/doc/changes.html640
-rw-r--r--libraries/luajit-2.0/doc/contact.html98
-rw-r--r--libraries/luajit-2.0/doc/ext_c_api.html183
-rw-r--r--libraries/luajit-2.0/doc/ext_ffi.html332
-rw-r--r--libraries/luajit-2.0/doc/ext_ffi_api.html553
-rw-r--r--libraries/luajit-2.0/doc/ext_ffi_semantics.html1146
-rw-r--r--libraries/luajit-2.0/doc/ext_ffi_tutorial.html598
-rw-r--r--libraries/luajit-2.0/doc/ext_jit.html195
-rw-r--r--libraries/luajit-2.0/doc/extensions.html336
-rw-r--r--libraries/luajit-2.0/doc/faq.html180
-rw-r--r--libraries/luajit-2.0/doc/img/contact.pngbin0 -> 1340 bytes
-rw-r--r--libraries/luajit-2.0/doc/install.html543
-rw-r--r--libraries/luajit-2.0/doc/luajit.html142
-rw-r--r--libraries/luajit-2.0/doc/running.html313
-rw-r--r--libraries/luajit-2.0/doc/status.html240
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_arm.h448
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_arm.lua949
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_mips.h415
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_mips.lua948
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_ppc.h411
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_ppc.lua1230
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_proto.h83
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_x64.lua12
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_x86.h470
-rw-r--r--libraries/luajit-2.0/dynasm/dasm_x86.lua1931
-rw-r--r--libraries/luajit-2.0/dynasm/dynasm.lua1076
-rw-r--r--libraries/luajit-2.0/etc/luajit.185
-rw-r--r--libraries/luajit-2.0/etc/luajit.pc24
-rw-r--r--libraries/luajit-2.0/etc/strict.lua41
-rw-r--r--libraries/luajit-2.0/lib/.gitignore1
-rw-r--r--libraries/luajit-2.0/lib/bc.lua192
-rw-r--r--libraries/luajit-2.0/lib/bcsave.lua496
-rw-r--r--libraries/luajit-2.0/lib/dis_arm.lua543
-rw-r--r--libraries/luajit-2.0/lib/dis_ppc.lua591
-rw-r--r--libraries/luajit-2.0/lib/dis_x64.lua20
-rw-r--r--libraries/luajit-2.0/lib/dis_x86.lua836
-rw-r--r--libraries/luajit-2.0/lib/dump.lua685
-rw-r--r--libraries/luajit-2.0/lib/v.lua167
-rw-r--r--libraries/luajit-2.0/src/.gitignore8
-rw-r--r--libraries/luajit-2.0/src/Makefile633
-rw-r--r--libraries/luajit-2.0/src/Makefile.dep207
-rw-r--r--libraries/luajit-2.0/src/buildvm.c513
-rw-r--r--libraries/luajit-2.0/src/buildvm.h104
-rw-r--r--libraries/luajit-2.0/src/buildvm_arm.dasc4115
-rw-r--r--libraries/luajit-2.0/src/buildvm_arm.h7487
-rw-r--r--libraries/luajit-2.0/src/buildvm_asm.c277
-rw-r--r--libraries/luajit-2.0/src/buildvm_fold.c229
-rw-r--r--libraries/luajit-2.0/src/buildvm_lib.c377
-rw-r--r--libraries/luajit-2.0/src/buildvm_peobj.c352
-rw-r--r--libraries/luajit-2.0/src/buildvm_ppc.dasc4873
-rw-r--r--libraries/luajit-2.0/src/buildvm_ppc.h9804
-rw-r--r--libraries/luajit-2.0/src/buildvm_ppcspe.dasc3704
-rw-r--r--libraries/luajit-2.0/src/buildvm_ppcspe.h6093
-rw-r--r--libraries/luajit-2.0/src/buildvm_x64.h3406
-rw-r--r--libraries/luajit-2.0/src/buildvm_x64win.h3401
-rw-r--r--libraries/luajit-2.0/src/buildvm_x86.dasc6458
-rw-r--r--libraries/luajit-2.0/src/buildvm_x86.h3561
-rw-r--r--libraries/luajit-2.0/src/lauxlib.h159
-rw-r--r--libraries/luajit-2.0/src/lib_aux.c375
-rw-r--r--libraries/luajit-2.0/src/lib_base.c650
-rw-r--r--libraries/luajit-2.0/src/lib_bit.c74
-rw-r--r--libraries/luajit-2.0/src/lib_debug.c366
-rw-r--r--libraries/luajit-2.0/src/lib_ffi.c811
-rw-r--r--libraries/luajit-2.0/src/lib_init.c53
-rw-r--r--libraries/luajit-2.0/src/lib_io.c533
-rw-r--r--libraries/luajit-2.0/src/lib_jit.c659
-rw-r--r--libraries/luajit-2.0/src/lib_math.c218
-rw-r--r--libraries/luajit-2.0/src/lib_os.c256
-rw-r--r--libraries/luajit-2.0/src/lib_package.c585
-rw-r--r--libraries/luajit-2.0/src/lib_string.c855
-rw-r--r--libraries/luajit-2.0/src/lib_table.c282
-rw-r--r--libraries/luajit-2.0/src/lj.supp16
-rw-r--r--libraries/luajit-2.0/src/lj_alloc.c1381
-rw-r--r--libraries/luajit-2.0/src/lj_alloc.h17
-rw-r--r--libraries/luajit-2.0/src/lj_api.c1220
-rw-r--r--libraries/luajit-2.0/src/lj_arch.h324
-rw-r--r--libraries/luajit-2.0/src/lj_asm.c1741
-rw-r--r--libraries/luajit-2.0/src/lj_asm.h17
-rw-r--r--libraries/luajit-2.0/src/lj_asm_arm.h1785
-rw-r--r--libraries/luajit-2.0/src/lj_asm_ppc.h2143
-rw-r--r--libraries/luajit-2.0/src/lj_asm_x86.h2751
-rw-r--r--libraries/luajit-2.0/src/lj_bc.c14
-rw-r--r--libraries/luajit-2.0/src/lj_bc.h261
-rw-r--r--libraries/luajit-2.0/src/lj_bcdump.h66
-rw-r--r--libraries/luajit-2.0/src/lj_bcread.c466
-rw-r--r--libraries/luajit-2.0/src/lj_bcwrite.c389
-rw-r--r--libraries/luajit-2.0/src/lj_carith.c314
-rw-r--r--libraries/luajit-2.0/src/lj_carith.h27
-rw-r--r--libraries/luajit-2.0/src/lj_ccall.c675
-rw-r--r--libraries/luajit-2.0/src/lj_ccall.h143
-rw-r--r--libraries/luajit-2.0/src/lj_ccallback.c544
-rw-r--r--libraries/luajit-2.0/src/lj_ccallback.h25
-rw-r--r--libraries/luajit-2.0/src/lj_cconv.c742
-rw-r--r--libraries/luajit-2.0/src/lj_cconv.h70
-rw-r--r--libraries/luajit-2.0/src/lj_cdata.c284
-rw-r--r--libraries/luajit-2.0/src/lj_cdata.h75
-rw-r--r--libraries/luajit-2.0/src/lj_char.c43
-rw-r--r--libraries/luajit-2.0/src/lj_char.h42
-rw-r--r--libraries/luajit-2.0/src/lj_clib.c389
-rw-r--r--libraries/luajit-2.0/src/lj_clib.h29
-rw-r--r--libraries/luajit-2.0/src/lj_cparse.c1839
-rw-r--r--libraries/luajit-2.0/src/lj_cparse.h64
-rw-r--r--libraries/luajit-2.0/src/lj_crecord.c1316
-rw-r--r--libraries/luajit-2.0/src/lj_crecord.h40
-rw-r--r--libraries/luajit-2.0/src/lj_ctype.c607
-rw-r--r--libraries/luajit-2.0/src/lj_ctype.h459
-rw-r--r--libraries/luajit-2.0/src/lj_debug.c502
-rw-r--r--libraries/luajit-2.0/src/lj_debug.h41
-rw-r--r--libraries/luajit-2.0/src/lj_def.h307
-rw-r--r--libraries/luajit-2.0/src/lj_dispatch.c464
-rw-r--r--libraries/luajit-2.0/src/lj_dispatch.h93
-rw-r--r--libraries/luajit-2.0/src/lj_emit_arm.h300
-rw-r--r--libraries/luajit-2.0/src/lj_emit_ppc.h232
-rw-r--r--libraries/luajit-2.0/src/lj_emit_x86.h457
-rw-r--r--libraries/luajit-2.0/src/lj_err.c736
-rw-r--r--libraries/luajit-2.0/src/lj_err.h41
-rw-r--r--libraries/luajit-2.0/src/lj_errmsg.h173
-rw-r--r--libraries/luajit-2.0/src/lj_ff.h18
-rw-r--r--libraries/luajit-2.0/src/lj_ffrecord.c855
-rw-r--r--libraries/luajit-2.0/src/lj_ffrecord.h24
-rw-r--r--libraries/luajit-2.0/src/lj_frame.h160
-rw-r--r--libraries/luajit-2.0/src/lj_func.c184
-rw-r--r--libraries/luajit-2.0/src/lj_func.h24
-rw-r--r--libraries/luajit-2.0/src/lj_gc.c838
-rw-r--r--libraries/luajit-2.0/src/lj_gc.h133
-rw-r--r--libraries/luajit-2.0/src/lj_gdbjit.c783
-rw-r--r--libraries/luajit-2.0/src/lj_gdbjit.h22
-rw-r--r--libraries/luajit-2.0/src/lj_ir.c492
-rw-r--r--libraries/luajit-2.0/src/lj_ir.h540
-rw-r--r--libraries/luajit-2.0/src/lj_ircall.h271
-rw-r--r--libraries/luajit-2.0/src/lj_iropt.h159
-rw-r--r--libraries/luajit-2.0/src/lj_jit.h394
-rw-r--r--libraries/luajit-2.0/src/lj_lex.c505
-rw-r--r--libraries/luajit-2.0/src/lj_lex.h82
-rw-r--r--libraries/luajit-2.0/src/lj_lib.c260
-rw-r--r--libraries/luajit-2.0/src/lj_lib.h112
-rw-r--r--libraries/luajit-2.0/src/lj_mcode.c364
-rw-r--r--libraries/luajit-2.0/src/lj_mcode.h30
-rw-r--r--libraries/luajit-2.0/src/lj_meta.c463
-rw-r--r--libraries/luajit-2.0/src/lj_meta.h37
-rw-r--r--libraries/luajit-2.0/src/lj_obj.c35
-rw-r--r--libraries/luajit-2.0/src/lj_obj.h844
-rw-r--r--libraries/luajit-2.0/src/lj_opt_dce.c77
-rw-r--r--libraries/luajit-2.0/src/lj_opt_fold.c2218
-rw-r--r--libraries/luajit-2.0/src/lj_opt_loop.c429
-rw-r--r--libraries/luajit-2.0/src/lj_opt_mem.c861
-rw-r--r--libraries/luajit-2.0/src/lj_opt_narrow.c648
-rw-r--r--libraries/luajit-2.0/src/lj_opt_split.c723
-rw-r--r--libraries/luajit-2.0/src/lj_parse.c2511
-rw-r--r--libraries/luajit-2.0/src/lj_parse.h18
-rw-r--r--libraries/luajit-2.0/src/lj_record.c2228
-rw-r--r--libraries/luajit-2.0/src/lj_record.h43
-rw-r--r--libraries/luajit-2.0/src/lj_snap.c446
-rw-r--r--libraries/luajit-2.0/src/lj_snap.h34
-rw-r--r--libraries/luajit-2.0/src/lj_state.c280
-rw-r--r--libraries/luajit-2.0/src/lj_state.h35
-rw-r--r--libraries/luajit-2.0/src/lj_str.c415
-rw-r--r--libraries/luajit-2.0/src/lj_str.h53
-rw-r--r--libraries/luajit-2.0/src/lj_tab.c622
-rw-r--r--libraries/luajit-2.0/src/lj_tab.h67
-rw-r--r--libraries/luajit-2.0/src/lj_target.h158
-rw-r--r--libraries/luajit-2.0/src/lj_target_arm.h210
-rw-r--r--libraries/luajit-2.0/src/lj_target_ppc.h279
-rw-r--r--libraries/luajit-2.0/src/lj_target_x86.h337
-rw-r--r--libraries/luajit-2.0/src/lj_trace.c812
-rw-r--r--libraries/luajit-2.0/src/lj_trace.h53
-rw-r--r--libraries/luajit-2.0/src/lj_traceerr.h61
-rw-r--r--libraries/luajit-2.0/src/lj_udata.c34
-rw-r--r--libraries/luajit-2.0/src/lj_udata.h14
-rw-r--r--libraries/luajit-2.0/src/lj_vm.h102
-rw-r--r--libraries/luajit-2.0/src/lj_vmevent.c56
-rw-r--r--libraries/luajit-2.0/src/lj_vmevent.h59
-rw-r--r--libraries/luajit-2.0/src/lj_vmmath.c119
-rw-r--r--libraries/luajit-2.0/src/ljamalg.c90
-rw-r--r--libraries/luajit-2.0/src/lua.h388
-rw-r--r--libraries/luajit-2.0/src/lua.hpp9
-rw-r--r--libraries/luajit-2.0/src/luaconf.h131
-rw-r--r--libraries/luajit-2.0/src/luajit.c553
-rw-r--r--libraries/luajit-2.0/src/luajit.h70
-rw-r--r--libraries/luajit-2.0/src/lualib.h43
-rw-r--r--libraries/luajit-2.0/src/msvcbuild.bat101
-rw-r--r--libraries/luaproc/COPYRIGHT32
-rw-r--r--libraries/luaproc/Lua_multithreading_ry08-05.pdfbin0 -> 135164 bytes
-rw-r--r--libraries/luaproc/Makefile64
-rw-r--r--libraries/luaproc/README97
-rw-r--r--libraries/luaproc/channel.c151
-rw-r--r--libraries/luaproc/channel.h67
-rw-r--r--libraries/luaproc/list.c241
-rw-r--r--libraries/luaproc/list.h76
-rw-r--r--libraries/luaproc/luaproc.c837
-rw-r--r--libraries/luaproc/luaproc.h92
-rw-r--r--libraries/luaproc/luaproc.lua34
-rw-r--r--libraries/luaproc/sched.c314
-rw-r--r--libraries/luaproc/sched.h78
-rw-r--r--libraries/luaproc/test.lua39
328 files changed, 174173 insertions, 0 deletions
diff --git a/libraries/LuaJIT-1.1.7/COPYRIGHT b/libraries/LuaJIT-1.1.7/COPYRIGHT
new file mode 100644
index 0000000..0ab5523
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/COPYRIGHT
@@ -0,0 +1,40 @@
1Lua License
2-----------
3
4Lua is licensed under the terms of the MIT license reproduced below.
5This means that Lua is free software and can be used for both academic
6and commercial purposes at absolutely no cost.
7
8For details and rationale, see http://www.lua.org/license.html .
9
10***
11LuaJIT is a derivative work, heavily based on Lua. The JIT extensions
12are licensed under the same conditions (except by a different author).
13The LuaJIT license can be found in: src/luajit.h
14***
15
16===============================================================================
17
18Copyright (C) 1994-2008 Lua.org, PUC-Rio.
19
20Permission is hereby granted, free of charge, to any person obtaining a copy
21of this software and associated documentation files (the "Software"), to deal
22in the Software without restriction, including without limitation the rights
23to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24copies of the Software, and to permit persons to whom the Software is
25furnished to do so, subject to the following conditions:
26
27The above copyright notice and this permission notice shall be included in
28all copies or substantial portions of the Software.
29
30THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36THE SOFTWARE.
37
38===============================================================================
39
40(end of COPYRIGHT)
diff --git a/libraries/LuaJIT-1.1.7/Makefile b/libraries/LuaJIT-1.1.7/Makefile
new file mode 100644
index 0000000..727ccc4
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/Makefile
@@ -0,0 +1,130 @@
1# makefile for installing Lua
2# see INSTALL for installation instructions
3# see src/Makefile and src/luaconf.h for further customization
4
5# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
6
7# Your platform. See PLATS for possible values.
8PLAT= none
9
10# Where to install. The installation starts in the src and doc directories,
11# so take care if INSTALL_TOP is not an absolute path.
12INSTALL_TOP= /usr/local
13INSTALL_BIN= $(INSTALL_TOP)/bin
14INSTALL_INC= $(INSTALL_TOP)/include
15INSTALL_LIB= $(INSTALL_TOP)/lib
16INSTALL_MAN= $(INSTALL_TOP)/man/man1
17#
18# You probably want to make INSTALL_LMOD and INSTALL_CMOD consistent with
19# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/luajit.pc).
20INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V
21INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V
22
23# How to install. If your install program does not support "-p", then you
24# may have to run ranlib on the installed liblua.a (do "make ranlib").
25INSTALL= install -p
26INSTALL_EXEC= $(INSTALL) -m 0755
27INSTALL_DATA= $(INSTALL) -m 0644
28#
29# If you don't have install you can use cp instead.
30# INSTALL= cp -p
31# INSTALL_EXEC= $(INSTALL)
32# INSTALL_DATA= $(INSTALL)
33
34# Utilities.
35MKDIR= mkdir -p
36RANLIB= ranlib
37
38# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
39
40# Convenience platforms targets.
41PLATS= linux bsd macosx solaris mingw cygwin posix generic linux_rl bsd_rl macosx_rl
42
43# What to install.
44TO_BIN= luajit
45###TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp
46###TO_LIB= liblua.a
47###TO_MAN= lua.1 luac.1
48
49# Lua version and release.
50V= 5.1
51R= 5.1.4
52# LuaJIT version.
53JV= 1.1.7
54
55all: $(PLAT)
56
57$(PLATS) clean:
58 cd src && $(MAKE) $@
59
60test: dummy
61 src/luajit -O -e 'io.write("Hello world, from ", jit.version, "!\n")'
62
63install: dummy
64 cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) $(INSTALL_LMOD)/jit
65 cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
66 ###cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
67 ###cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
68 ###cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
69 cd jit && $(INSTALL_DATA) *.lua $(INSTALL_LMOD)/jit
70
71ranlib:
72 cd src && cd $(INSTALL_LIB) && $(RANLIB) $(TO_LIB)
73
74none:
75 @echo "Please do"
76 @echo " make PLATFORM"
77 @echo "where PLATFORM is one of these:"
78 @echo " $(PLATS)"
79 @echo "See jitdoc/luajit_install.html for complete instructions."
80
81# make may get confused with test/ and INSTALL in a case-insensitive OS
82dummy:
83
84# echo config parameters
85echo:
86 @echo ""
87 @echo "These are the parameters currently set in src/Makefile to build LuaJIT $(JV):"
88 @echo ""
89 @cd src && $(MAKE) -s echo
90 @echo ""
91 @echo "These are the parameters currently set in Makefile to install LuaJIT $(JV):"
92 @echo ""
93 @echo "PLAT = $(PLAT)"
94 @echo "INSTALL_TOP = $(INSTALL_TOP)"
95 @echo "INSTALL_BIN = $(INSTALL_BIN)"
96 @echo "INSTALL_INC = $(INSTALL_INC)"
97 @echo "INSTALL_LIB = $(INSTALL_LIB)"
98 @echo "INSTALL_MAN = $(INSTALL_MAN)"
99 @echo "INSTALL_LMOD = $(INSTALL_LMOD)"
100 @echo "INSTALL_CMOD = $(INSTALL_CMOD)"
101 @echo "INSTALL_EXEC = $(INSTALL_EXEC)"
102 @echo "INSTALL_DATA = $(INSTALL_DATA)"
103 @echo ""
104 @echo "See also src/luaconf.h ."
105 @echo ""
106
107# echo private config parameters
108pecho:
109 @echo "V = $(V)"
110 @echo "R = $(R)"
111 @echo "JV = $(JV)"
112 @echo "TO_BIN = $(TO_BIN)"
113 @echo "TO_INC = $(TO_INC)"
114 @echo "TO_LIB = $(TO_LIB)"
115 @echo "TO_MAN = $(TO_MAN)"
116
117# echo config parameters as Lua code
118# uncomment the last sed expression if you want nil instead of empty strings
119lecho:
120 @echo "-- installation parameters for Lua $(R), LuaJIT $(JV)"
121 @echo "VERSION = '$(V)'"
122 @echo "RELEASE = '$(R)'"
123 @echo "LUAJIT_VERSION = '$(JV)'"
124 @$(MAKE) echo | grep = | sed -e 's/= /= "/' -e 's/$$/"/' #-e 's/""/nil/'
125 @echo "-- EOF"
126
127# list targets that do not create files (but not all makes understand .PHONY)
128.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho
129
130# (end of Makefile)
diff --git a/libraries/LuaJIT-1.1.7/README b/libraries/LuaJIT-1.1.7/README
new file mode 100644
index 0000000..3af04b8
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/README
@@ -0,0 +1,46 @@
1README for LuaJIT 1.1.7
2-----------------------
3
4************************************************************
5* This is only a bugfix release for the LuaJIT 1.1 branch. *
6* LuaJIT 2.0 is available with much improved performance! *
7************************************************************
8
9LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
10
11 Lua is a powerful, light-weight programming language designed
12 for extending applications. Lua is also frequently used as a
13 general-purpose, stand-alone language. More information about
14 Lua can be found in the docs (see below) or at: http://www.lua.org/
15
16LuaJIT 1.x is based on the Lua 5.1.x virtual machine and bytecode
17interpreter from lua.org. It compiles bytecode to native x86 (i386+)
18machine code to speed up the execution of Lua programs.
19
20Homepage: http://luajit.org/
21
22LuaJIT is Copyright (C) 2005-2011 Mike Pall. LuaJIT is free
23software, released under the MIT/X license.
24
25-----------------------
26
27Full documentation for LuaJIT is available in HTML format.
28Please point your favourite browser to:
29
30 jitdoc/luajit.html
31
32Detailed installation instructions are here:
33
34 jitdoc/luajit_install.html
35
36The original documentation for Lua has been included for convenience:
37
38 doc/readme.html
39
40-----------------------
41
42LuaJIT 1.1.7 is a heavily modified version of Lua 5.1.4.
43The unmodified Lua distribution is available at:
44
45 http://www.lua.org/ftp/lua-5.1.4.tar.gz
46
diff --git a/libraries/LuaJIT-1.1.7/doc/amazon.gif b/libraries/LuaJIT-1.1.7/doc/amazon.gif
new file mode 100644
index 0000000..f2586d5
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/amazon.gif
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/doc/contents.html b/libraries/LuaJIT-1.1.7/doc/contents.html
new file mode 100644
index 0000000..8e58e18
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/contents.html
@@ -0,0 +1,499 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<HTML>
3<HEAD>
4<TITLE>Lua 5.1 Reference Manual - contents</TITLE>
5<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
6<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
7<STYLE TYPE="text/css">
8ul {
9 list-style-type: none ;
10 list-style-position: outside ;
11}
12</STYLE>
13</HEAD>
14
15<BODY>
16
17<HR>
18<H1>
19<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="" BORDER=0></A>
20Lua 5.1 Reference Manual
21</H1>
22
23This is an online version of
24<BLOCKQUOTE>
25<A HREF="http://www.amazon.com/exec/obidos/ASIN/8590379833/lua-indexmanual-20">
26<IMG SRC="cover.png" ALT="" TITLE="buy from Amazon" BORDER=1 ALIGN="left" HSPACE=12>
27</A>
28<B>Lua 5.1 Reference Manual</B>
29<BR>by R. Ierusalimschy, L. H. de Figueiredo, W. Celes
30<BR>Lua.org, August 2006
31<BR>ISBN 85-903798-3-3
32<BR><A HREF="http://www.amazon.com/exec/obidos/ASIN/8590379833/lua-indexmanual-20">
33<IMG SRC="amazon.gif" ALT="[Buy from Amazon]" BORDER=0></A>
34<BR CLEAR="all">
35</BLOCKQUOTE>
36<P>
37
38Buy a copy of this book and
39<A HREF="http://www.lua.org/donations.html">help to support</A>
40the Lua project.
41<P>
42
43The reference manual is the official definition of the Lua language.
44For a complete introduction to Lua programming, see the book
45<A HREF="http://www.lua.org/docs.html#books">Programming in Lua</A>.
46<P>
47
48<A HREF="manual.html">start</A>
49&middot;
50<A HREF="#contents">contents</A>
51&middot;
52<A HREF="#index">index</A>
53&middot;
54<A HREF="http://www.lua.org/manual/5.1/pt/">português</A>
55&middot;
56<A HREF="http://www.lua.org/manual/5.1/es/">español</A>
57<HR>
58<SMALL>
59Copyright &copy; 2006-2008 Lua.org, PUC-Rio.
60Freely available under the terms of the
61<a href="http://www.lua.org/license.html#5">Lua license</a>.
62</SMALL>
63<P>
64
65<H2><A NAME="contents">Contents</A></H2>
66<UL style="padding: 0">
67<LI><A HREF="manual.html">1 - Introduction</A>
68<P>
69<LI><A HREF="manual.html#2">2 - The Language</A>
70<UL>
71<LI><A HREF="manual.html#2.1">2.1 - Lexical Conventions</A>
72<LI><A HREF="manual.html#2.2">2.2 - Values and Types</A>
73<UL>
74<LI><A HREF="manual.html#2.2.1">2.2.1 - Coercion</A>
75</UL>
76<LI><A HREF="manual.html#2.3">2.3 - Variables</A>
77<LI><A HREF="manual.html#2.4">2.4 - Statements</A>
78<UL>
79<LI><A HREF="manual.html#2.4.1">2.4.1 - Chunks</A>
80<LI><A HREF="manual.html#2.4.2">2.4.2 - Blocks</A>
81<LI><A HREF="manual.html#2.4.3">2.4.3 - Assignment</A>
82<LI><A HREF="manual.html#2.4.4">2.4.4 - Control Structures</A>
83<LI><A HREF="manual.html#2.4.5">2.4.5 - For Statement</A>
84<LI><A HREF="manual.html#2.4.6">2.4.6 - Function Calls as Statements</A>
85<LI><A HREF="manual.html#2.4.7">2.4.7 - Local Declarations</A>
86</UL>
87<LI><A HREF="manual.html#2.5">2.5 - Expressions</A>
88<UL>
89<LI><A HREF="manual.html#2.5.1">2.5.1 - Arithmetic Operators</A>
90<LI><A HREF="manual.html#2.5.2">2.5.2 - Relational Operators</A>
91<LI><A HREF="manual.html#2.5.3">2.5.3 - Logical Operators</A>
92<LI><A HREF="manual.html#2.5.4">2.5.4 - Concatenation</A>
93<LI><A HREF="manual.html#2.5.5">2.5.5 - The Length Operator</A>
94<LI><A HREF="manual.html#2.5.6">2.5.6 - Precedence</A>
95<LI><A HREF="manual.html#2.5.7">2.5.7 - Table Constructors</A>
96<LI><A HREF="manual.html#2.5.8">2.5.8 - Function Calls</A>
97<LI><A HREF="manual.html#2.5.9">2.5.9 - Function Definitions</A>
98</UL>
99<LI><A HREF="manual.html#2.6">2.6 - Visibility Rules</A>
100<LI><A HREF="manual.html#2.7">2.7 - Error Handling</A>
101<LI><A HREF="manual.html#2.8">2.8 - Metatables</A>
102<LI><A HREF="manual.html#2.9">2.9 - Environments</A>
103<LI><A HREF="manual.html#2.10">2.10 - Garbage Collection</A>
104<UL>
105<LI><A HREF="manual.html#2.10.1">2.10.1 - Garbage-Collection Metamethods</A>
106<LI><A HREF="manual.html#2.10.2">2.10.2 - Weak Tables</A>
107</UL>
108<LI><A HREF="manual.html#2.11">2.11 - Coroutines</A>
109</UL>
110<P>
111<LI><A HREF="manual.html#3">3 - The Application Program Interface</A>
112<UL>
113<LI><A HREF="manual.html#3.1">3.1 - The Stack</A>
114<LI><A HREF="manual.html#3.2">3.2 - Stack Size</A>
115<LI><A HREF="manual.html#3.3">3.3 - Pseudo-Indices</A>
116<LI><A HREF="manual.html#3.4">3.4 - C Closures</A>
117<LI><A HREF="manual.html#3.5">3.5 - Registry</A>
118<LI><A HREF="manual.html#3.6">3.6 - Error Handling in C</A>
119<LI><A HREF="manual.html#3.7">3.7 - Functions and Types</A>
120<LI><A HREF="manual.html#3.8">3.8 - The Debug Interface</A>
121</UL>
122<P>
123<LI><A HREF="manual.html#4">4 - The Auxiliary Library</A>
124<UL>
125<LI><A HREF="manual.html#4.1">4.1 - Functions and Types</A>
126</UL>
127<P>
128<LI><A HREF="manual.html#5">5 - Standard Libraries</A>
129<UL>
130<LI><A HREF="manual.html#5.1">5.1 - Basic Functions</A>
131<LI><A HREF="manual.html#5.2">5.2 - Coroutine Manipulation</A>
132<LI><A HREF="manual.html#5.3">5.3 - Modules</A>
133<LI><A HREF="manual.html#5.4">5.4 - String Manipulation</A>
134<UL>
135<LI><A HREF="manual.html#5.4.1">5.4.1 - Patterns</A>
136</UL>
137<LI><A HREF="manual.html#5.5">5.5 - Table Manipulation</A>
138<LI><A HREF="manual.html#5.6">5.6 - Mathematical Functions</A>
139<LI><A HREF="manual.html#5.7">5.7 - Input and Output Facilities</A>
140<LI><A HREF="manual.html#5.8">5.8 - Operating System Facilities</A>
141<LI><A HREF="manual.html#5.9">5.9 - The Debug Library</A>
142</UL>
143<P>
144<LI><A HREF="manual.html#6">6 - Lua Stand-alone</A>
145<P>
146<LI><A HREF="manual.html#7">7 - Incompatibilities with the Previous Version</A>
147<UL>
148<LI><A HREF="manual.html#7.1">7.1 - Changes in the Language</A>
149<LI><A HREF="manual.html#7.2">7.2 - Changes in the Libraries</A>
150<LI><A HREF="manual.html#7.3">7.3 - Changes in the API</A>
151</UL>
152<P>
153<LI><A HREF="manual.html#8">8 - The Complete Syntax of Lua</A>
154</UL>
155
156<H2><A NAME="index">Index</A></H2>
157<TABLE WIDTH="100%">
158<TR VALIGN="top">
159<TD>
160<H3><A NAME="functions">Lua functions</A></H3>
161<A HREF="manual.html#pdf-_G">_G</A><BR>
162<A HREF="manual.html#pdf-_VERSION">_VERSION</A><BR>
163<A HREF="manual.html#pdf-assert">assert</A><BR>
164<A HREF="manual.html#pdf-collectgarbage">collectgarbage</A><BR>
165<A HREF="manual.html#pdf-dofile">dofile</A><BR>
166<A HREF="manual.html#pdf-error">error</A><BR>
167<A HREF="manual.html#pdf-getfenv">getfenv</A><BR>
168<A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR>
169<A HREF="manual.html#pdf-ipairs">ipairs</A><BR>
170<A HREF="manual.html#pdf-load">load</A><BR>
171<A HREF="manual.html#pdf-loadfile">loadfile</A><BR>
172<A HREF="manual.html#pdf-loadstring">loadstring</A><BR>
173<A HREF="manual.html#pdf-module">module</A><BR>
174<A HREF="manual.html#pdf-next">next</A><BR>
175<A HREF="manual.html#pdf-pairs">pairs</A><BR>
176<A HREF="manual.html#pdf-pcall">pcall</A><BR>
177<A HREF="manual.html#pdf-print">print</A><BR>
178<A HREF="manual.html#pdf-rawequal">rawequal</A><BR>
179<A HREF="manual.html#pdf-rawget">rawget</A><BR>
180<A HREF="manual.html#pdf-rawset">rawset</A><BR>
181<A HREF="manual.html#pdf-require">require</A><BR>
182<A HREF="manual.html#pdf-select">select</A><BR>
183<A HREF="manual.html#pdf-setfenv">setfenv</A><BR>
184<A HREF="manual.html#pdf-setmetatable">setmetatable</A><BR>
185<A HREF="manual.html#pdf-tonumber">tonumber</A><BR>
186<A HREF="manual.html#pdf-tostring">tostring</A><BR>
187<A HREF="manual.html#pdf-type">type</A><BR>
188<A HREF="manual.html#pdf-unpack">unpack</A><BR>
189<A HREF="manual.html#pdf-xpcall">xpcall</A><BR>
190<P>
191
192<A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR>
193<A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR>
194<A HREF="manual.html#pdf-coroutine.running">coroutine.running</A><BR>
195<A HREF="manual.html#pdf-coroutine.status">coroutine.status</A><BR>
196<A HREF="manual.html#pdf-coroutine.wrap">coroutine.wrap</A><BR>
197<A HREF="manual.html#pdf-coroutine.yield">coroutine.yield</A><BR>
198<P>
199
200<A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR>
201<A HREF="manual.html#pdf-debug.getfenv">debug.getfenv</A><BR>
202<A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR>
203<A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR>
204<A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR>
205<A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR>
206<A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR>
207<A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR>
208<A HREF="manual.html#pdf-debug.setfenv">debug.setfenv</A><BR>
209<A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR>
210<A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR>
211<A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR>
212<A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR>
213<A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR>
214
215</TD>
216<TD>
217<H3>&nbsp;</H3>
218<A HREF="manual.html#pdf-file:close">file:close</A><BR>
219<A HREF="manual.html#pdf-file:flush">file:flush</A><BR>
220<A HREF="manual.html#pdf-file:lines">file:lines</A><BR>
221<A HREF="manual.html#pdf-file:read">file:read</A><BR>
222<A HREF="manual.html#pdf-file:seek">file:seek</A><BR>
223<A HREF="manual.html#pdf-file:setvbuf">file:setvbuf</A><BR>
224<A HREF="manual.html#pdf-file:write">file:write</A><BR>
225<P>
226
227<A HREF="manual.html#pdf-io.close">io.close</A><BR>
228<A HREF="manual.html#pdf-io.flush">io.flush</A><BR>
229<A HREF="manual.html#pdf-io.input">io.input</A><BR>
230<A HREF="manual.html#pdf-io.lines">io.lines</A><BR>
231<A HREF="manual.html#pdf-io.open">io.open</A><BR>
232<A HREF="manual.html#pdf-io.output">io.output</A><BR>
233<A HREF="manual.html#pdf-io.popen">io.popen</A><BR>
234<A HREF="manual.html#pdf-io.read">io.read</A><BR>
235<A HREF="manual.html#pdf-io.stderr">io.stderr</A><BR>
236<A HREF="manual.html#pdf-io.stdin">io.stdin</A><BR>
237<A HREF="manual.html#pdf-io.stdout">io.stdout</A><BR>
238<A HREF="manual.html#pdf-io.tmpfile">io.tmpfile</A><BR>
239<A HREF="manual.html#pdf-io.type">io.type</A><BR>
240<A HREF="manual.html#pdf-io.write">io.write</A><BR>
241<P>
242
243<A HREF="manual.html#pdf-math.abs">math.abs</A><BR>
244<A HREF="manual.html#pdf-math.acos">math.acos</A><BR>
245<A HREF="manual.html#pdf-math.asin">math.asin</A><BR>
246<A HREF="manual.html#pdf-math.atan">math.atan</A><BR>
247<A HREF="manual.html#pdf-math.atan2">math.atan2</A><BR>
248<A HREF="manual.html#pdf-math.ceil">math.ceil</A><BR>
249<A HREF="manual.html#pdf-math.cos">math.cos</A><BR>
250<A HREF="manual.html#pdf-math.cosh">math.cosh</A><BR>
251<A HREF="manual.html#pdf-math.deg">math.deg</A><BR>
252<A HREF="manual.html#pdf-math.exp">math.exp</A><BR>
253<A HREF="manual.html#pdf-math.floor">math.floor</A><BR>
254<A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR>
255<A HREF="manual.html#pdf-math.frexp">math.frexp</A><BR>
256<A HREF="manual.html#pdf-math.huge">math.huge</A><BR>
257<A HREF="manual.html#pdf-math.ldexp">math.ldexp</A><BR>
258<A HREF="manual.html#pdf-math.log">math.log</A><BR>
259<A HREF="manual.html#pdf-math.log10">math.log10</A><BR>
260<A HREF="manual.html#pdf-math.max">math.max</A><BR>
261<A HREF="manual.html#pdf-math.min">math.min</A><BR>
262<A HREF="manual.html#pdf-math.modf">math.modf</A><BR>
263<A HREF="manual.html#pdf-math.pi">math.pi</A><BR>
264<A HREF="manual.html#pdf-math.pow">math.pow</A><BR>
265<A HREF="manual.html#pdf-math.rad">math.rad</A><BR>
266<A HREF="manual.html#pdf-math.random">math.random</A><BR>
267<A HREF="manual.html#pdf-math.randomseed">math.randomseed</A><BR>
268<A HREF="manual.html#pdf-math.sin">math.sin</A><BR>
269<A HREF="manual.html#pdf-math.sinh">math.sinh</A><BR>
270<A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR>
271<A HREF="manual.html#pdf-math.tan">math.tan</A><BR>
272<A HREF="manual.html#pdf-math.tanh">math.tanh</A><BR>
273<P>
274
275<A HREF="manual.html#pdf-os.clock">os.clock</A><BR>
276<A HREF="manual.html#pdf-os.date">os.date</A><BR>
277<A HREF="manual.html#pdf-os.difftime">os.difftime</A><BR>
278<A HREF="manual.html#pdf-os.execute">os.execute</A><BR>
279<A HREF="manual.html#pdf-os.exit">os.exit</A><BR>
280<A HREF="manual.html#pdf-os.getenv">os.getenv</A><BR>
281<A HREF="manual.html#pdf-os.remove">os.remove</A><BR>
282<A HREF="manual.html#pdf-os.rename">os.rename</A><BR>
283<A HREF="manual.html#pdf-os.setlocale">os.setlocale</A><BR>
284<A HREF="manual.html#pdf-os.time">os.time</A><BR>
285<A HREF="manual.html#pdf-os.tmpname">os.tmpname</A><BR>
286<P>
287
288<A HREF="manual.html#pdf-package.cpath">package.cpath</A><BR>
289<A HREF="manual.html#pdf-package.loaded">package.loaded</A><BR>
290<A HREF="manual.html#pdf-package.loaders">package.loaders</A><BR>
291<A HREF="manual.html#pdf-package.loadlib">package.loadlib</A><BR>
292<A HREF="manual.html#pdf-package.path">package.path</A><BR>
293<A HREF="manual.html#pdf-package.preload">package.preload</A><BR>
294<A HREF="manual.html#pdf-package.seeall">package.seeall</A><BR>
295<P>
296
297<A HREF="manual.html#pdf-string.byte">string.byte</A><BR>
298<A HREF="manual.html#pdf-string.char">string.char</A><BR>
299<A HREF="manual.html#pdf-string.dump">string.dump</A><BR>
300<A HREF="manual.html#pdf-string.find">string.find</A><BR>
301<A HREF="manual.html#pdf-string.format">string.format</A><BR>
302<A HREF="manual.html#pdf-string.gmatch">string.gmatch</A><BR>
303<A HREF="manual.html#pdf-string.gsub">string.gsub</A><BR>
304<A HREF="manual.html#pdf-string.len">string.len</A><BR>
305<A HREF="manual.html#pdf-string.lower">string.lower</A><BR>
306<A HREF="manual.html#pdf-string.match">string.match</A><BR>
307<A HREF="manual.html#pdf-string.rep">string.rep</A><BR>
308<A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR>
309<A HREF="manual.html#pdf-string.sub">string.sub</A><BR>
310<A HREF="manual.html#pdf-string.upper">string.upper</A><BR>
311<P>
312
313<A HREF="manual.html#pdf-table.concat">table.concat</A><BR>
314<A HREF="manual.html#pdf-table.insert">table.insert</A><BR>
315<A HREF="manual.html#pdf-table.maxn">table.maxn</A><BR>
316<A HREF="manual.html#pdf-table.remove">table.remove</A><BR>
317<A HREF="manual.html#pdf-table.sort">table.sort</A><BR>
318
319</TD>
320<TD>
321<H3>C API</H3>
322<A HREF="manual.html#lua_Alloc">lua_Alloc</A><BR>
323<A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR>
324<A HREF="manual.html#lua_Debug">lua_Debug</A><BR>
325<A HREF="manual.html#lua_Hook">lua_Hook</A><BR>
326<A HREF="manual.html#lua_Integer">lua_Integer</A><BR>
327<A HREF="manual.html#lua_Number">lua_Number</A><BR>
328<A HREF="manual.html#lua_Reader">lua_Reader</A><BR>
329<A HREF="manual.html#lua_State">lua_State</A><BR>
330<A HREF="manual.html#lua_Writer">lua_Writer</A><BR>
331<P>
332
333<A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR>
334<A HREF="manual.html#lua_call">lua_call</A><BR>
335<A HREF="manual.html#lua_checkstack">lua_checkstack</A><BR>
336<A HREF="manual.html#lua_close">lua_close</A><BR>
337<A HREF="manual.html#lua_concat">lua_concat</A><BR>
338<A HREF="manual.html#lua_cpcall">lua_cpcall</A><BR>
339<A HREF="manual.html#lua_createtable">lua_createtable</A><BR>
340<A HREF="manual.html#lua_dump">lua_dump</A><BR>
341<A HREF="manual.html#lua_equal">lua_equal</A><BR>
342<A HREF="manual.html#lua_error">lua_error</A><BR>
343<A HREF="manual.html#lua_gc">lua_gc</A><BR>
344<A HREF="manual.html#lua_getallocf">lua_getallocf</A><BR>
345<A HREF="manual.html#lua_getfenv">lua_getfenv</A><BR>
346<A HREF="manual.html#lua_getfield">lua_getfield</A><BR>
347<A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR>
348<A HREF="manual.html#lua_gethook">lua_gethook</A><BR>
349<A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR>
350<A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR>
351<A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR>
352<A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR>
353<A HREF="manual.html#lua_getmetatable">lua_getmetatable</A><BR>
354<A HREF="manual.html#lua_getstack">lua_getstack</A><BR>
355<A HREF="manual.html#lua_gettable">lua_gettable</A><BR>
356<A HREF="manual.html#lua_gettop">lua_gettop</A><BR>
357<A HREF="manual.html#lua_getupvalue">lua_getupvalue</A><BR>
358<A HREF="manual.html#lua_insert">lua_insert</A><BR>
359<A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR>
360<A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR>
361<A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR>
362<A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR>
363<A HREF="manual.html#lua_isnil">lua_isnil</A><BR>
364<A HREF="manual.html#lua_isnone">lua_isnone</A><BR>
365<A HREF="manual.html#lua_isnoneornil">lua_isnoneornil</A><BR>
366<A HREF="manual.html#lua_isnumber">lua_isnumber</A><BR>
367<A HREF="manual.html#lua_isstring">lua_isstring</A><BR>
368<A HREF="manual.html#lua_istable">lua_istable</A><BR>
369<A HREF="manual.html#lua_isthread">lua_isthread</A><BR>
370<A HREF="manual.html#lua_isuserdata">lua_isuserdata</A><BR>
371<A HREF="manual.html#lua_lessthan">lua_lessthan</A><BR>
372<A HREF="manual.html#lua_load">lua_load</A><BR>
373<A HREF="manual.html#lua_newstate">lua_newstate</A><BR>
374<A HREF="manual.html#lua_newtable">lua_newtable</A><BR>
375<A HREF="manual.html#lua_newthread">lua_newthread</A><BR>
376<A HREF="manual.html#lua_newuserdata">lua_newuserdata</A><BR>
377<A HREF="manual.html#lua_next">lua_next</A><BR>
378<A HREF="manual.html#lua_objlen">lua_objlen</A><BR>
379<A HREF="manual.html#lua_pcall">lua_pcall</A><BR>
380<A HREF="manual.html#lua_pop">lua_pop</A><BR>
381<A HREF="manual.html#lua_pushboolean">lua_pushboolean</A><BR>
382<A HREF="manual.html#lua_pushcclosure">lua_pushcclosure</A><BR>
383<A HREF="manual.html#lua_pushcfunction">lua_pushcfunction</A><BR>
384<A HREF="manual.html#lua_pushfstring">lua_pushfstring</A><BR>
385<A HREF="manual.html#lua_pushinteger">lua_pushinteger</A><BR>
386<A HREF="manual.html#lua_pushlightuserdata">lua_pushlightuserdata</A><BR>
387<A HREF="manual.html#lua_pushliteral">lua_pushliteral</A><BR>
388<A HREF="manual.html#lua_pushlstring">lua_pushlstring</A><BR>
389<A HREF="manual.html#lua_pushnil">lua_pushnil</A><BR>
390<A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR>
391<A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR>
392<A HREF="manual.html#lua_pushthread">lua_pushthread</A><BR>
393<A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR>
394<A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR>
395<A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR>
396<A HREF="manual.html#lua_rawget">lua_rawget</A><BR>
397<A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR>
398<A HREF="manual.html#lua_rawset">lua_rawset</A><BR>
399<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR>
400<A HREF="manual.html#lua_register">lua_register</A><BR>
401<A HREF="manual.html#lua_remove">lua_remove</A><BR>
402<A HREF="manual.html#lua_replace">lua_replace</A><BR>
403<A HREF="manual.html#lua_resume">lua_resume</A><BR>
404<A HREF="manual.html#lua_setallocf">lua_setallocf</A><BR>
405<A HREF="manual.html#lua_setfenv">lua_setfenv</A><BR>
406<A HREF="manual.html#lua_setfield">lua_setfield</A><BR>
407<A HREF="manual.html#lua_setglobal">lua_setglobal</A><BR>
408<A HREF="manual.html#lua_sethook">lua_sethook</A><BR>
409<A HREF="manual.html#lua_setlocal">lua_setlocal</A><BR>
410<A HREF="manual.html#lua_setmetatable">lua_setmetatable</A><BR>
411<A HREF="manual.html#lua_settable">lua_settable</A><BR>
412<A HREF="manual.html#lua_settop">lua_settop</A><BR>
413<A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR>
414<A HREF="manual.html#lua_status">lua_status</A><BR>
415<A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR>
416<A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR>
417<A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR>
418<A HREF="manual.html#lua_tolstring">lua_tolstring</A><BR>
419<A HREF="manual.html#lua_tonumber">lua_tonumber</A><BR>
420<A HREF="manual.html#lua_topointer">lua_topointer</A><BR>
421<A HREF="manual.html#lua_tostring">lua_tostring</A><BR>
422<A HREF="manual.html#lua_tothread">lua_tothread</A><BR>
423<A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR>
424<A HREF="manual.html#lua_type">lua_type</A><BR>
425<A HREF="manual.html#lua_typename">lua_typename</A><BR>
426<A HREF="manual.html#lua_upvalueindex">lua_upvalueindex</A><BR>
427<A HREF="manual.html#lua_xmove">lua_xmove</A><BR>
428<A HREF="manual.html#lua_yield">lua_yield</A><BR>
429
430</TD>
431<TD>
432<H3>auxiliary library</H3>
433<A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR>
434<A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR>
435<P>
436
437<A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR>
438<A HREF="manual.html#luaL_addlstring">luaL_addlstring</A><BR>
439<A HREF="manual.html#luaL_addsize">luaL_addsize</A><BR>
440<A HREF="manual.html#luaL_addstring">luaL_addstring</A><BR>
441<A HREF="manual.html#luaL_addvalue">luaL_addvalue</A><BR>
442<A HREF="manual.html#luaL_argcheck">luaL_argcheck</A><BR>
443<A HREF="manual.html#luaL_argerror">luaL_argerror</A><BR>
444<A HREF="manual.html#luaL_buffinit">luaL_buffinit</A><BR>
445<A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR>
446<A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR>
447<A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR>
448<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR>
449<A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR>
450<A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR>
451<A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR>
452<A HREF="manual.html#luaL_checkoption">luaL_checkoption</A><BR>
453<A HREF="manual.html#luaL_checkstack">luaL_checkstack</A><BR>
454<A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR>
455<A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR>
456<A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR>
457<A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR>
458<A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR>
459<A HREF="manual.html#luaL_error">luaL_error</A><BR>
460<A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR>
461<A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR>
462<A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR>
463<A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR>
464<A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR>
465<A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR>
466<A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR>
467<A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR>
468<A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR>
469<A HREF="manual.html#luaL_optint">luaL_optint</A><BR>
470<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
471<A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR>
472<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
473<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
474<A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR>
475<A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR>
476<A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR>
477<A HREF="manual.html#luaL_ref">luaL_ref</A><BR>
478<A HREF="manual.html#luaL_register">luaL_register</A><BR>
479<A HREF="manual.html#luaL_typename">luaL_typename</A><BR>
480<A HREF="manual.html#luaL_typerror">luaL_typerror</A><BR>
481<A HREF="manual.html#luaL_unref">luaL_unref</A><BR>
482<A HREF="manual.html#luaL_where">luaL_where</A><BR>
483
484</TD>
485</TR>
486</TABLE>
487<P>
488
489<HR>
490<SMALL>
491Last update:
492Sat Jan 19 13:24:29 BRST 2008
493</SMALL>
494<!--
495Last change: revised for Lua 5.1.3
496-->
497
498</BODY>
499</HTML>
diff --git a/libraries/LuaJIT-1.1.7/doc/cover.png b/libraries/LuaJIT-1.1.7/doc/cover.png
new file mode 100644
index 0000000..2dbb198
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/cover.png
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/doc/logo.gif b/libraries/LuaJIT-1.1.7/doc/logo.gif
new file mode 100644
index 0000000..2f5e4ac
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/logo.gif
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.1 b/libraries/LuaJIT-1.1.7/doc/lua.1
new file mode 100644
index 0000000..24809cc
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/lua.1
@@ -0,0 +1,163 @@
1.\" $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $
2.TH LUA 1 "$Date: 2006/01/06 16:03:34 $"
3.SH NAME
4lua \- Lua interpreter
5.SH SYNOPSIS
6.B lua
7[
8.I options
9]
10[
11.I script
12[
13.I args
14]
15]
16.SH DESCRIPTION
17.B lua
18is the stand-alone Lua interpreter.
19It loads and executes Lua programs,
20either in textual source form or
21in precompiled binary form.
22(Precompiled binaries are output by
23.BR luac ,
24the Lua compiler.)
25.B lua
26can be used as a batch interpreter and also interactively.
27.LP
28The given
29.I options
30(see below)
31are executed and then
32the Lua program in file
33.I script
34is loaded and executed.
35The given
36.I args
37are available to
38.I script
39as strings in a global table named
40.BR arg .
41If these arguments contain spaces or other characters special to the shell,
42then they should be quoted
43(but note that the quotes will be removed by the shell).
44The arguments in
45.B arg
46start at 0,
47which contains the string
48.RI ' script '.
49The index of the last argument is stored in
50.BR arg.n .
51The arguments given in the command line before
52.IR script ,
53including the name of the interpreter,
54are available in negative indices in
55.BR arg .
56.LP
57At the very start,
58before even handling the command line,
59.B lua
60executes the contents of the environment variable
61.BR LUA_INIT ,
62if it is defined.
63If the value of
64.B LUA_INIT
65is of the form
66.RI '@ filename ',
67then
68.I filename
69is executed.
70Otherwise, the string is assumed to be a Lua statement and is executed.
71.LP
72Options start with
73.B '\-'
74and are described below.
75You can use
76.B "'\--'"
77to signal the end of options.
78.LP
79If no arguments are given,
80then
81.B "\-v \-i"
82is assumed when the standard input is a terminal;
83otherwise,
84.B "\-"
85is assumed.
86.LP
87In interactive mode,
88.B lua
89prompts the user,
90reads lines from the standard input,
91and executes them as they are read.
92If a line does not contain a complete statement,
93then a secondary prompt is displayed and
94lines are read until a complete statement is formed or
95a syntax error is found.
96So, one way to interrupt the reading of an incomplete statement is
97to force a syntax error:
98adding a
99.B ';'
100in the middle of a statement is a sure way of forcing a syntax error
101(except inside multiline strings and comments; these must be closed explicitly).
102If a line starts with
103.BR '=' ,
104then
105.B lua
106displays the values of all the expressions in the remainder of the
107line. The expressions must be separated by commas.
108The primary prompt is the value of the global variable
109.BR _PROMPT ,
110if this value is a string;
111otherwise, the default prompt is used.
112Similarly, the secondary prompt is the value of the global variable
113.BR _PROMPT2 .
114So,
115to change the prompts,
116set the corresponding variable to a string of your choice.
117You can do that after calling the interpreter
118or on the command line
119(but in this case you have to be careful with quotes
120if the prompt string contains a space; otherwise you may confuse the shell.)
121The default prompts are "> " and ">> ".
122.SH OPTIONS
123.TP
124.B \-
125load and execute the standard input as a file,
126that is,
127not interactively,
128even when the standard input is a terminal.
129.TP
130.BI \-e " stat"
131execute statement
132.IR stat .
133You need to quote
134.I stat
135if it contains spaces, quotes,
136or other characters special to the shell.
137.TP
138.B \-i
139enter interactive mode after
140.I script
141is executed.
142.TP
143.BI \-l " name"
144call
145.BI require(' name ')
146before executing
147.IR script .
148Typically used to load libraries.
149.TP
150.B \-v
151show version information.
152.SH "SEE ALSO"
153.BR luac (1)
154.br
155http://www.lua.org/
156.SH DIAGNOSTICS
157Error messages should be self explanatory.
158.SH AUTHORS
159R. Ierusalimschy,
160L. H. de Figueiredo,
161and
162W. Celes
163.\" EOF
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.css b/libraries/LuaJIT-1.1.7/doc/lua.css
new file mode 100644
index 0000000..039cf11
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/lua.css
@@ -0,0 +1,41 @@
1body {
2 color: #000000 ;
3 background-color: #FFFFFF ;
4 font-family: sans-serif ;
5 text-align: justify ;
6 margin-right: 20px ;
7 margin-left: 20px ;
8}
9
10h1, h2, h3, h4 {
11 font-weight: normal ;
12 font-style: italic ;
13}
14
15a:link {
16 color: #000080 ;
17 background-color: inherit ;
18 text-decoration: none ;
19}
20
21a:visited {
22 background-color: inherit ;
23 text-decoration: none ;
24}
25
26a:link:hover, a:visited:hover {
27 color: #000080 ;
28 background-color: #E0E0FF ;
29}
30
31a:link:active, a:visited:active {
32 color: #FF0000 ;
33}
34
35hr {
36 border: 0 ;
37 height: 1px ;
38 color: #a0a0a0 ;
39 background-color: #a0a0a0 ;
40}
41
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.html b/libraries/LuaJIT-1.1.7/doc/lua.html
new file mode 100644
index 0000000..1d435ab
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/lua.html
@@ -0,0 +1,172 @@
1<!-- $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $ -->
2<HTML>
3<HEAD>
4<TITLE>LUA man page</TITLE>
5<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
6</HEAD>
7
8<BODY BGCOLOR="#FFFFFF">
9
10<H2>NAME</H2>
11lua - Lua interpreter
12<H2>SYNOPSIS</H2>
13<B>lua</B>
14[
15<I>options</I>
16]
17[
18<I>script</I>
19[
20<I>args</I>
21]
22]
23<H2>DESCRIPTION</H2>
24<B>lua</B>
25is the stand-alone Lua interpreter.
26It loads and executes Lua programs,
27either in textual source form or
28in precompiled binary form.
29(Precompiled binaries are output by
30<B>luac</B>,
31the Lua compiler.)
32<B>lua</B>
33can be used as a batch interpreter and also interactively.
34<P>
35The given
36<I>options</I>
37(see below)
38are executed and then
39the Lua program in file
40<I>script</I>
41is loaded and executed.
42The given
43<I>args</I>
44are available to
45<I>script</I>
46as strings in a global table named
47<B>arg</B>.
48If these arguments contain spaces or other characters special to the shell,
49then they should be quoted
50(but note that the quotes will be removed by the shell).
51The arguments in
52<B>arg</B>
53start at 0,
54which contains the string
55'<I>script</I>'.
56The index of the last argument is stored in
57<B>arg.n</B>.
58The arguments given in the command line before
59<I>script</I>,
60including the name of the interpreter,
61are available in negative indices in
62<B>arg</B>.
63<P>
64At the very start,
65before even handling the command line,
66<B>lua</B>
67executes the contents of the environment variable
68<B>LUA_INIT</B>,
69if it is defined.
70If the value of
71<B>LUA_INIT</B>
72is of the form
73'@<I>filename</I>',
74then
75<I>filename</I>
76is executed.
77Otherwise, the string is assumed to be a Lua statement and is executed.
78<P>
79Options start with
80<B>'-'</B>
81and are described below.
82You can use
83<B>'--'</B>
84to signal the end of options.
85<P>
86If no arguments are given,
87then
88<B>"-v -i"</B>
89is assumed when the standard input is a terminal;
90otherwise,
91<B>"-"</B>
92is assumed.
93<P>
94In interactive mode,
95<B>lua</B>
96prompts the user,
97reads lines from the standard input,
98and executes them as they are read.
99If a line does not contain a complete statement,
100then a secondary prompt is displayed and
101lines are read until a complete statement is formed or
102a syntax error is found.
103So, one way to interrupt the reading of an incomplete statement is
104to force a syntax error:
105adding a
106<B>';'</B>
107in the middle of a statement is a sure way of forcing a syntax error
108(except inside multiline strings and comments; these must be closed explicitly).
109If a line starts with
110<B>'='</B>,
111then
112<B>lua</B>
113displays the values of all the expressions in the remainder of the
114line. The expressions must be separated by commas.
115The primary prompt is the value of the global variable
116<B>_PROMPT</B>,
117if this value is a string;
118otherwise, the default prompt is used.
119Similarly, the secondary prompt is the value of the global variable
120<B>_PROMPT2</B>.
121So,
122to change the prompts,
123set the corresponding variable to a string of your choice.
124You can do that after calling the interpreter
125or on the command line
126(but in this case you have to be careful with quotes
127if the prompt string contains a space; otherwise you may confuse the shell.)
128The default prompts are "&gt; " and "&gt;&gt; ".
129<H2>OPTIONS</H2>
130<P>
131<B>-</B>
132load and execute the standard input as a file,
133that is,
134not interactively,
135even when the standard input is a terminal.
136<P>
137<B>-e </B><I>stat</I>
138execute statement
139<I>stat</I>.
140You need to quote
141<I>stat </I>
142if it contains spaces, quotes,
143or other characters special to the shell.
144<P>
145<B>-i</B>
146enter interactive mode after
147<I>script</I>
148is executed.
149<P>
150<B>-l </B><I>name</I>
151call
152<B>require</B>('<I>name</I>')
153before executing
154<I>script</I>.
155Typically used to load libraries.
156<P>
157<B>-v</B>
158show version information.
159<H2>SEE ALSO</H2>
160<B>luac</B>(1)
161<BR>
162<A HREF="http://www.lua.org/">http://www.lua.org/</A>
163<H2>DIAGNOSTICS</H2>
164Error messages should be self explanatory.
165<H2>AUTHORS</H2>
166R. Ierusalimschy,
167L. H. de Figueiredo,
168and
169W. Celes
170<!-- EOF -->
171</BODY>
172</HTML>
diff --git a/libraries/LuaJIT-1.1.7/doc/luac.1 b/libraries/LuaJIT-1.1.7/doc/luac.1
new file mode 100644
index 0000000..d814678
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/luac.1
@@ -0,0 +1,136 @@
1.\" $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $
2.TH LUAC 1 "$Date: 2006/01/06 16:03:34 $"
3.SH NAME
4luac \- Lua compiler
5.SH SYNOPSIS
6.B luac
7[
8.I options
9] [
10.I filenames
11]
12.SH DESCRIPTION
13.B luac
14is the Lua compiler.
15It translates programs written in the Lua programming language
16into binary files that can be later loaded and executed.
17.LP
18The main advantages of precompiling chunks are:
19faster loading,
20protecting source code from accidental user changes,
21and
22off-line syntax checking.
23.LP
24Pre-compiling does not imply faster execution
25because in Lua chunks are always compiled into bytecodes before being executed.
26.B luac
27simply allows those bytecodes to be saved in a file for later execution.
28.LP
29Pre-compiled chunks are not necessarily smaller than the corresponding source.
30The main goal in pre-compiling is faster loading.
31.LP
32The binary files created by
33.B luac
34are portable only among architectures with the same word size and byte order.
35.LP
36.B luac
37produces a single output file containing the bytecodes
38for all source files given.
39By default,
40the output file is named
41.BR luac.out ,
42but you can change this with the
43.B \-o
44option.
45.LP
46In the command line,
47you can mix
48text files containing Lua source and
49binary files containing precompiled chunks.
50This is useful to combine several precompiled chunks,
51even from different (but compatible) platforms,
52into a single precompiled chunk.
53.LP
54You can use
55.B "'\-'"
56to indicate the standard input as a source file
57and
58.B "'\--'"
59to signal the end of options
60(that is,
61all remaining arguments will be treated as files even if they start with
62.BR "'\-'" ).
63.LP
64The internal format of the binary files produced by
65.B luac
66is likely to change when a new version of Lua is released.
67So,
68save the source files of all Lua programs that you precompile.
69.LP
70.SH OPTIONS
71Options must be separate.
72.TP
73.B \-l
74produce a listing of the compiled bytecode for Lua's virtual machine.
75Listing bytecodes is useful to learn about Lua's virtual machine.
76If no files are given, then
77.B luac
78loads
79.B luac.out
80and lists its contents.
81.TP
82.BI \-o " file"
83output to
84.IR file ,
85instead of the default
86.BR luac.out .
87(You can use
88.B "'\-'"
89for standard output,
90but not on platforms that open standard output in text mode.)
91The output file may be a source file because
92all files are loaded before the output file is written.
93Be careful not to overwrite precious files.
94.TP
95.B \-p
96load files but do not generate any output file.
97Used mainly for syntax checking and for testing precompiled chunks:
98corrupted files will probably generate errors when loaded.
99Lua always performs a thorough integrity test on precompiled chunks.
100Bytecode that passes this test is completely safe,
101in the sense that it will not break the interpreter.
102However,
103there is no guarantee that such code does anything sensible.
104(None can be given, because the halting problem is unsolvable.)
105If no files are given, then
106.B luac
107loads
108.B luac.out
109and tests its contents.
110No messages are displayed if the file passes the integrity test.
111.TP
112.B \-s
113strip debug information before writing the output file.
114This saves some space in very large chunks,
115but if errors occur when running a stripped chunk,
116then the error messages may not contain the full information they usually do.
117For instance,
118line numbers and names of local variables are lost.
119.TP
120.B \-v
121show version information.
122.SH FILES
123.TP 15
124.B luac.out
125default output file
126.SH "SEE ALSO"
127.BR lua (1)
128.br
129http://www.lua.org/
130.SH DIAGNOSTICS
131Error messages should be self explanatory.
132.SH AUTHORS
133L. H. de Figueiredo,
134R. Ierusalimschy and
135W. Celes
136.\" EOF
diff --git a/libraries/LuaJIT-1.1.7/doc/luac.html b/libraries/LuaJIT-1.1.7/doc/luac.html
new file mode 100644
index 0000000..179ffe8
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/luac.html
@@ -0,0 +1,145 @@
1<!-- $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $ -->
2<HTML>
3<HEAD>
4<TITLE>LUAC man page</TITLE>
5<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
6</HEAD>
7
8<BODY BGCOLOR="#FFFFFF">
9
10<H2>NAME</H2>
11luac - Lua compiler
12<H2>SYNOPSIS</H2>
13<B>luac</B>
14[
15<I>options</I>
16] [
17<I>filenames</I>
18]
19<H2>DESCRIPTION</H2>
20<B>luac</B>
21is the Lua compiler.
22It translates programs written in the Lua programming language
23into binary files that can be later loaded and executed.
24<P>
25The main advantages of precompiling chunks are:
26faster loading,
27protecting source code from accidental user changes,
28and
29off-line syntax checking.
30<P>
31Precompiling does not imply faster execution
32because in Lua chunks are always compiled into bytecodes before being executed.
33<B>luac</B>
34simply allows those bytecodes to be saved in a file for later execution.
35<P>
36Precompiled chunks are not necessarily smaller than the corresponding source.
37The main goal in precompiling is faster loading.
38<P>
39The binary files created by
40<B>luac</B>
41are portable only among architectures with the same word size and byte order.
42<P>
43<B>luac</B>
44produces a single output file containing the bytecodes
45for all source files given.
46By default,
47the output file is named
48<B>luac.out</B>,
49but you can change this with the
50<B>-o</B>
51option.
52<P>
53In the command line,
54you can mix
55text files containing Lua source and
56binary files containing precompiled chunks.
57This is useful because several precompiled chunks,
58even from different (but compatible) platforms,
59can be combined into a single precompiled chunk.
60<P>
61You can use
62<B>'-'</B>
63to indicate the standard input as a source file
64and
65<B>'--'</B>
66to signal the end of options
67(that is,
68all remaining arguments will be treated as files even if they start with
69<B>'-'</B>).
70<P>
71The internal format of the binary files produced by
72<B>luac</B>
73is likely to change when a new version of Lua is released.
74So,
75save the source files of all Lua programs that you precompile.
76<P>
77<H2>OPTIONS</H2>
78Options must be separate.
79<P>
80<B>-l</B>
81produce a listing of the compiled bytecode for Lua's virtual machine.
82Listing bytecodes is useful to learn about Lua's virtual machine.
83If no files are given, then
84<B>luac</B>
85loads
86<B>luac.out</B>
87and lists its contents.
88<P>
89<B>-o </B><I>file</I>
90output to
91<I>file</I>,
92instead of the default
93<B>luac.out</B>.
94(You can use
95<B>'-'</B>
96for standard output,
97but not on platforms that open standard output in text mode.)
98The output file may be a source file because
99all files are loaded before the output file is written.
100Be careful not to overwrite precious files.
101<P>
102<B>-p</B>
103load files but do not generate any output file.
104Used mainly for syntax checking and for testing precompiled chunks:
105corrupted files will probably generate errors when loaded.
106Lua always performs a thorough integrity test on precompiled chunks.
107Bytecode that passes this test is completely safe,
108in the sense that it will not break the interpreter.
109However,
110there is no guarantee that such code does anything sensible.
111(None can be given, because the halting problem is unsolvable.)
112If no files are given, then
113<B>luac</B>
114loads
115<B>luac.out</B>
116and tests its contents.
117No messages are displayed if the file passes the integrity test.
118<P>
119<B>-s</B>
120strip debug information before writing the output file.
121This saves some space in very large chunks,
122but if errors occur when running a stripped chunk,
123then the error messages may not contain the full information they usually do.
124For instance,
125line numbers and names of local variables are lost.
126<P>
127<B>-v</B>
128show version information.
129<H2>FILES</H2>
130<P>
131<B>luac.out</B>
132default output file
133<H2>SEE ALSO</H2>
134<B>lua</B>(1)
135<BR>
136<A HREF="http://www.lua.org/">http://www.lua.org/</A>
137<H2>DIAGNOSTICS</H2>
138Error messages should be self explanatory.
139<H2>AUTHORS</H2>
140L. H. de Figueiredo,
141R. Ierusalimschy and
142W. Celes
143<!-- EOF -->
144</BODY>
145</HTML>
diff --git a/libraries/LuaJIT-1.1.7/doc/manual.css b/libraries/LuaJIT-1.1.7/doc/manual.css
new file mode 100644
index 0000000..eed5afd
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/manual.css
@@ -0,0 +1,13 @@
1h3 code {
2 font-family: inherit ;
3}
4
5pre {
6 font-size: 105% ;
7}
8
9span.apii {
10 float: right ;
11 font-family: inherit ;
12}
13
diff --git a/libraries/LuaJIT-1.1.7/doc/manual.html b/libraries/LuaJIT-1.1.7/doc/manual.html
new file mode 100644
index 0000000..f46f17c
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/manual.html
@@ -0,0 +1,8801 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<html>
3
4<head>
5<title>Lua 5.1 Reference Manual</title>
6<link rel="stylesheet" type="text/css" href="lua.css">
7<link rel="stylesheet" type="text/css" href="manual.css">
8<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
9</head>
10
11<body>
12
13<hr>
14<h1>
15<a href="http://www.lua.org/"><img src="logo.gif" alt="" border="0"></a>
16Lua 5.1 Reference Manual
17</h1>
18
19by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
20<p>
21<small>
22Copyright &copy; 2006-2008 Lua.org, PUC-Rio.
23Freely available under the terms of the
24<a href="http://www.lua.org/license.html#5">Lua license</a>.
25</small>
26<hr>
27<p>
28
29<a href="contents.html#contents">contents</A>
30&middot;
31<a href="contents.html#index">index</A>
32
33<!-- ====================================================================== -->
34<p>
35
36<!-- $Id: manual.of,v 1.48 2008/08/18 15:24:20 roberto Exp $ -->
37
38
39
40
41<h1>1 - <a name="1">Introduction</a></h1>
42
43<p>
44Lua is an extension programming language designed to support
45general procedural programming with data description
46facilities.
47It also offers good support for object-oriented programming,
48functional programming, and data-driven programming.
49Lua is intended to be used as a powerful, light-weight
50scripting language for any program that needs one.
51Lua is implemented as a library, written in <em>clean</em> C
52(that is, in the common subset of ANSI&nbsp;C and C++).
53
54
55<p>
56Being an extension language, Lua has no notion of a "main" program:
57it only works <em>embedded</em> in a host client,
58called the <em>embedding program</em> or simply the <em>host</em>.
59This host program can invoke functions to execute a piece of Lua code,
60can write and read Lua variables,
61and can register C&nbsp;functions to be called by Lua code.
62Through the use of C&nbsp;functions, Lua can be augmented to cope with
63a wide range of different domains,
64thus creating customized programming languages sharing a syntactical framework.
65The Lua distribution includes a sample host program called <code>lua</code>,
66which uses the Lua library to offer a complete, stand-alone Lua interpreter.
67
68
69<p>
70Lua is free software,
71and is provided as usual with no guarantees,
72as stated in its license.
73The implementation described in this manual is available
74at Lua's official web site, <code>www.lua.org</code>.
75
76
77<p>
78Like any other reference manual,
79this document is dry in places.
80For a discussion of the decisions behind the design of Lua,
81see the technical papers available at Lua's web site.
82For a detailed introduction to programming in Lua,
83see Roberto's book, <em>Programming in Lua (Second Edition)</em>.
84
85
86
87<h1>2 - <a name="2">The Language</a></h1>
88
89<p>
90This section describes the lexis, the syntax, and the semantics of Lua.
91In other words,
92this section describes
93which tokens are valid,
94how they can be combined,
95and what their combinations mean.
96
97
98<p>
99The language constructs will be explained using the usual extended BNF notation,
100in which
101{<em>a</em>}&nbsp;means&nbsp;0 or more <em>a</em>'s, and
102[<em>a</em>]&nbsp;means an optional <em>a</em>.
103Non-terminals are shown like non-terminal,
104keywords are shown like <b>kword</b>,
105and other terminal symbols are shown like `<b>=</b>&acute;.
106The complete syntax of Lua can be found in <a href="#8">&sect;8</a>
107at the end of this manual.
108
109
110
111<h2>2.1 - <a name="2.1">Lexical Conventions</a></h2>
112
113<p>
114<em>Names</em>
115(also called <em>identifiers</em>)
116in Lua can be any string of letters,
117digits, and underscores,
118not beginning with a digit.
119This coincides with the definition of names in most languages.
120(The definition of letter depends on the current locale:
121any character considered alphabetic by the current locale
122can be used in an identifier.)
123Identifiers are used to name variables and table fields.
124
125
126<p>
127The following <em>keywords</em> are reserved
128and cannot be used as names:
129
130
131<pre>
132 and break do else elseif
133 end false for function if
134 in local nil not or
135 repeat return then true until while
136</pre>
137
138<p>
139Lua is a case-sensitive language:
140<code>and</code> is a reserved word, but <code>And</code> and <code>AND</code>
141are two different, valid names.
142As a convention, names starting with an underscore followed by
143uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>)
144are reserved for internal global variables used by Lua.
145
146
147<p>
148The following strings denote other tokens:
149
150<pre>
151 + - * / % ^ #
152 == ~= &lt;= &gt;= &lt; &gt; =
153 ( ) { } [ ]
154 ; : , . .. ...
155</pre>
156
157<p>
158<em>Literal strings</em>
159can be delimited by matching single or double quotes,
160and can contain the following C-like escape sequences:
161'<code>\a</code>' (bell),
162'<code>\b</code>' (backspace),
163'<code>\f</code>' (form feed),
164'<code>\n</code>' (newline),
165'<code>\r</code>' (carriage return),
166'<code>\t</code>' (horizontal tab),
167'<code>\v</code>' (vertical tab),
168'<code>\\</code>' (backslash),
169'<code>\"</code>' (quotation mark [double quote]),
170and '<code>\'</code>' (apostrophe [single quote]).
171Moreover, a backslash followed by a real newline
172results in a newline in the string.
173A character in a string can also be specified by its numerical value
174using the escape sequence <code>\<em>ddd</em></code>,
175where <em>ddd</em> is a sequence of up to three decimal digits.
176(Note that if a numerical escape is to be followed by a digit,
177it must be expressed using exactly three digits.)
178Strings in Lua can contain any 8-bit value, including embedded zeros,
179which can be specified as '<code>\0</code>'.
180
181
182<p>
183Literal strings can also be defined using a long format
184enclosed by <em>long brackets</em>.
185We define an <em>opening long bracket of level <em>n</em></em> as an opening
186square bracket followed by <em>n</em> equal signs followed by another
187opening square bracket.
188So, an opening long bracket of level&nbsp;0 is written as <code>[[</code>,
189an opening long bracket of level&nbsp;1 is written as <code>[=[</code>,
190and so on.
191A <em>closing long bracket</em> is defined similarly;
192for instance, a closing long bracket of level&nbsp;4 is written as <code>]====]</code>.
193A long string starts with an opening long bracket of any level and
194ends at the first closing long bracket of the same level.
195Literals in this bracketed form can run for several lines,
196do not interpret any escape sequences,
197and ignore long brackets of any other level.
198They can contain anything except a closing bracket of the proper level.
199
200
201<p>
202For convenience,
203when the opening long bracket is immediately followed by a newline,
204the newline is not included in the string.
205As an example, in a system using ASCII
206(in which '<code>a</code>' is coded as&nbsp;97,
207newline is coded as&nbsp;10, and '<code>1</code>' is coded as&nbsp;49),
208the five literal strings below denote the same string:
209
210<pre>
211 a = 'alo\n123"'
212 a = "alo\n123\""
213 a = '\97lo\10\04923"'
214 a = [[alo
215 123"]]
216 a = [==[
217 alo
218 123"]==]
219</pre>
220
221<p>
222A <em>numerical constant</em> can be written with an optional decimal part
223and an optional decimal exponent.
224Lua also accepts integer hexadecimal constants,
225by prefixing them with <code>0x</code>.
226Examples of valid numerical constants are
227
228<pre>
229 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56
230</pre>
231
232<p>
233A <em>comment</em> starts with a double hyphen (<code>--</code>)
234anywhere outside a string.
235If the text immediately after <code>--</code> is not an opening long bracket,
236the comment is a <em>short comment</em>,
237which runs until the end of the line.
238Otherwise, it is a <em>long comment</em>,
239which runs until the corresponding closing long bracket.
240Long comments are frequently used to disable code temporarily.
241
242
243
244
245
246<h2>2.2 - <a name="2.2">Values and Types</a></h2>
247
248<p>
249Lua is a <em>dynamically typed language</em>.
250This means that
251variables do not have types; only values do.
252There are no type definitions in the language.
253All values carry their own type.
254
255
256<p>
257All values in Lua are <em>first-class values</em>.
258This means that all values can be stored in variables,
259passed as arguments to other functions, and returned as results.
260
261
262<p>
263There are eight basic types in Lua:
264<em>nil</em>, <em>boolean</em>, <em>number</em>,
265<em>string</em>, <em>function</em>, <em>userdata</em>,
266<em>thread</em>, and <em>table</em>.
267<em>Nil</em> is the type of the value <b>nil</b>,
268whose main property is to be different from any other value;
269it usually represents the absence of a useful value.
270<em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>.
271Both <b>nil</b> and <b>false</b> make a condition false;
272any other value makes it true.
273<em>Number</em> represents real (double-precision floating-point) numbers.
274(It is easy to build Lua interpreters that use other
275internal representations for numbers,
276such as single-precision float or long integers;
277see file <code>luaconf.h</code>.)
278<em>String</em> represents arrays of characters.
279
280Lua is 8-bit clean:
281strings can contain any 8-bit character,
282including embedded zeros ('<code>\0</code>') (see <a href="#2.1">&sect;2.1</a>).
283
284
285<p>
286Lua can call (and manipulate) functions written in Lua and
287functions written in C
288(see <a href="#2.5.8">&sect;2.5.8</a>).
289
290
291<p>
292The type <em>userdata</em> is provided to allow arbitrary C&nbsp;data to
293be stored in Lua variables.
294This type corresponds to a block of raw memory
295and has no pre-defined operations in Lua,
296except assignment and identity test.
297However, by using <em>metatables</em>,
298the programmer can define operations for userdata values
299(see <a href="#2.8">&sect;2.8</a>).
300Userdata values cannot be created or modified in Lua,
301only through the C&nbsp;API.
302This guarantees the integrity of data owned by the host program.
303
304
305<p>
306The type <em>thread</em> represents independent threads of execution
307and it is used to implement coroutines (see <a href="#2.11">&sect;2.11</a>).
308Do not confuse Lua threads with operating-system threads.
309Lua supports coroutines on all systems,
310even those that do not support threads.
311
312
313<p>
314The type <em>table</em> implements associative arrays,
315that is, arrays that can be indexed not only with numbers,
316but with any value (except <b>nil</b>).
317Tables can be <em>heterogeneous</em>;
318that is, they can contain values of all types (except <b>nil</b>).
319Tables are the sole data structuring mechanism in Lua;
320they can be used to represent ordinary arrays,
321symbol tables, sets, records, graphs, trees, etc.
322To represent records, Lua uses the field name as an index.
323The language supports this representation by
324providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>.
325There are several convenient ways to create tables in Lua
326(see <a href="#2.5.7">&sect;2.5.7</a>).
327
328
329<p>
330Like indices,
331the value of a table field can be of any type (except <b>nil</b>).
332In particular,
333because functions are first-class values,
334table fields can contain functions.
335Thus tables can also carry <em>methods</em> (see <a href="#2.5.9">&sect;2.5.9</a>).
336
337
338<p>
339Tables, functions, threads, and (full) userdata values are <em>objects</em>:
340variables do not actually <em>contain</em> these values,
341only <em>references</em> to them.
342Assignment, parameter passing, and function returns
343always manipulate references to such values;
344these operations do not imply any kind of copy.
345
346
347<p>
348The library function <a href="#pdf-type"><code>type</code></a> returns a string describing the type
349of a given value.
350
351
352
353<h3>2.2.1 - <a name="2.2.1">Coercion</a></h3>
354
355<p>
356Lua provides automatic conversion between
357string and number values at run time.
358Any arithmetic operation applied to a string tries to convert
359this string to a number, following the usual conversion rules.
360Conversely, whenever a number is used where a string is expected,
361the number is converted to a string, in a reasonable format.
362For complete control over how numbers are converted to strings,
363use the <code>format</code> function from the string library
364(see <a href="#pdf-string.format"><code>string.format</code></a>).
365
366
367
368
369
370
371
372<h2>2.3 - <a name="2.3">Variables</a></h2>
373
374<p>
375Variables are places that store values.
376
377There are three kinds of variables in Lua:
378global variables, local variables, and table fields.
379
380
381<p>
382A single name can denote a global variable or a local variable
383(or a function's formal parameter,
384which is a particular kind of local variable):
385
386<pre>
387 var ::= Name
388</pre><p>
389Name denotes identifiers, as defined in <a href="#2.1">&sect;2.1</a>.
390
391
392<p>
393Any variable is assumed to be global unless explicitly declared
394as a local (see <a href="#2.4.7">&sect;2.4.7</a>).
395Local variables are <em>lexically scoped</em>:
396local variables can be freely accessed by functions
397defined inside their scope (see <a href="#2.6">&sect;2.6</a>).
398
399
400<p>
401Before the first assignment to a variable, its value is <b>nil</b>.
402
403
404<p>
405Square brackets are used to index a table:
406
407<pre>
408 var ::= prefixexp `<b>[</b>&acute; exp `<b>]</b>&acute;
409</pre><p>
410The meaning of accesses to global variables
411and table fields can be changed via metatables.
412An access to an indexed variable <code>t[i]</code> is equivalent to
413a call <code>gettable_event(t,i)</code>.
414(See <a href="#2.8">&sect;2.8</a> for a complete description of the
415<code>gettable_event</code> function.
416This function is not defined or callable in Lua.
417We use it here only for explanatory purposes.)
418
419
420<p>
421The syntax <code>var.Name</code> is just syntactic sugar for
422<code>var["Name"]</code>:
423
424<pre>
425 var ::= prefixexp `<b>.</b>&acute; Name
426</pre>
427
428<p>
429All global variables live as fields in ordinary Lua tables,
430called <em>environment tables</em> or simply
431<em>environments</em> (see <a href="#2.9">&sect;2.9</a>).
432Each function has its own reference to an environment,
433so that all global variables in this function
434will refer to this environment table.
435When a function is created,
436it inherits the environment from the function that created it.
437To get the environment table of a Lua function,
438you call <a href="#pdf-getfenv"><code>getfenv</code></a>.
439To replace it,
440you call <a href="#pdf-setfenv"><code>setfenv</code></a>.
441(You can only manipulate the environment of C&nbsp;functions
442through the debug library; (see <a href="#5.9">&sect;5.9</a>).)
443
444
445<p>
446An access to a global variable <code>x</code>
447is equivalent to <code>_env.x</code>,
448which in turn is equivalent to
449
450<pre>
451 gettable_event(_env, "x")
452</pre><p>
453where <code>_env</code> is the environment of the running function.
454(See <a href="#2.8">&sect;2.8</a> for a complete description of the
455<code>gettable_event</code> function.
456This function is not defined or callable in Lua.
457Similarly, the <code>_env</code> variable is not defined in Lua.
458We use them here only for explanatory purposes.)
459
460
461
462
463
464<h2>2.4 - <a name="2.4">Statements</a></h2>
465
466<p>
467Lua supports an almost conventional set of statements,
468similar to those in Pascal or C.
469This set includes
470assignments, control structures, function calls,
471and variable declarations.
472
473
474
475<h3>2.4.1 - <a name="2.4.1">Chunks</a></h3>
476
477<p>
478The unit of execution of Lua is called a <em>chunk</em>.
479A chunk is simply a sequence of statements,
480which are executed sequentially.
481Each statement can be optionally followed by a semicolon:
482
483<pre>
484 chunk ::= {stat [`<b>;</b>&acute;]}
485</pre><p>
486There are no empty statements and thus '<code>;;</code>' is not legal.
487
488
489<p>
490Lua handles a chunk as the body of an anonymous function
491with a variable number of arguments
492(see <a href="#2.5.9">&sect;2.5.9</a>).
493As such, chunks can define local variables,
494receive arguments, and return values.
495
496
497<p>
498A chunk can be stored in a file or in a string inside the host program.
499To execute a chunk,
500Lua first pre-compiles the chunk into instructions for a virtual machine,
501and then it executes the compiled code
502with an interpreter for the virtual machine.
503
504
505<p>
506Chunks can also be pre-compiled into binary form;
507see program <code>luac</code> for details.
508Programs in source and compiled forms are interchangeable;
509Lua automatically detects the file type and acts accordingly.
510
511
512
513
514
515
516<h3>2.4.2 - <a name="2.4.2">Blocks</a></h3><p>
517A block is a list of statements;
518syntactically, a block is the same as a chunk:
519
520<pre>
521 block ::= chunk
522</pre>
523
524<p>
525A block can be explicitly delimited to produce a single statement:
526
527<pre>
528 stat ::= <b>do</b> block <b>end</b>
529</pre><p>
530Explicit blocks are useful
531to control the scope of variable declarations.
532Explicit blocks are also sometimes used to
533add a <b>return</b> or <b>break</b> statement in the middle
534of another block (see <a href="#2.4.4">&sect;2.4.4</a>).
535
536
537
538
539
540<h3>2.4.3 - <a name="2.4.3">Assignment</a></h3>
541
542<p>
543Lua allows multiple assignments.
544Therefore, the syntax for assignment
545defines a list of variables on the left side
546and a list of expressions on the right side.
547The elements in both lists are separated by commas:
548
549<pre>
550 stat ::= varlist `<b>=</b>&acute; explist
551 varlist ::= var {`<b>,</b>&acute; var}
552 explist ::= exp {`<b>,</b>&acute; exp}
553</pre><p>
554Expressions are discussed in <a href="#2.5">&sect;2.5</a>.
555
556
557<p>
558Before the assignment,
559the list of values is <em>adjusted</em> to the length of
560the list of variables.
561If there are more values than needed,
562the excess values are thrown away.
563If there are fewer values than needed,
564the list is extended with as many <b>nil</b>'s as needed.
565If the list of expressions ends with a function call,
566then all values returned by that call enter the list of values,
567before the adjustment
568(except when the call is enclosed in parentheses; see <a href="#2.5">&sect;2.5</a>).
569
570
571<p>
572The assignment statement first evaluates all its expressions
573and only then are the assignments performed.
574Thus the code
575
576<pre>
577 i = 3
578 i, a[i] = i+1, 20
579</pre><p>
580sets <code>a[3]</code> to 20, without affecting <code>a[4]</code>
581because the <code>i</code> in <code>a[i]</code> is evaluated (to 3)
582before it is assigned&nbsp;4.
583Similarly, the line
584
585<pre>
586 x, y = y, x
587</pre><p>
588exchanges the values of <code>x</code> and <code>y</code>,
589and
590
591<pre>
592 x, y, z = y, z, x
593</pre><p>
594cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>.
595
596
597<p>
598The meaning of assignments to global variables
599and table fields can be changed via metatables.
600An assignment to an indexed variable <code>t[i] = val</code> is equivalent to
601<code>settable_event(t,i,val)</code>.
602(See <a href="#2.8">&sect;2.8</a> for a complete description of the
603<code>settable_event</code> function.
604This function is not defined or callable in Lua.
605We use it here only for explanatory purposes.)
606
607
608<p>
609An assignment to a global variable <code>x = val</code>
610is equivalent to the assignment
611<code>_env.x = val</code>,
612which in turn is equivalent to
613
614<pre>
615 settable_event(_env, "x", val)
616</pre><p>
617where <code>_env</code> is the environment of the running function.
618(The <code>_env</code> variable is not defined in Lua.
619We use it here only for explanatory purposes.)
620
621
622
623
624
625<h3>2.4.4 - <a name="2.4.4">Control Structures</a></h3><p>
626The control structures
627<b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and
628familiar syntax:
629
630
631
632
633<pre>
634 stat ::= <b>while</b> exp <b>do</b> block <b>end</b>
635 stat ::= <b>repeat</b> block <b>until</b> exp
636 stat ::= <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b>
637</pre><p>
638Lua also has a <b>for</b> statement, in two flavors (see <a href="#2.4.5">&sect;2.4.5</a>).
639
640
641<p>
642The condition expression of a
643control structure can return any value.
644Both <b>false</b> and <b>nil</b> are considered false.
645All values different from <b>nil</b> and <b>false</b> are considered true
646(in particular, the number 0 and the empty string are also true).
647
648
649<p>
650In the <b>repeat</b>&ndash;<b>until</b> loop,
651the inner block does not end at the <b>until</b> keyword,
652but only after the condition.
653So, the condition can refer to local variables
654declared inside the loop block.
655
656
657<p>
658The <b>return</b> statement is used to return values
659from a function or a chunk (which is just a function).
660
661Functions and chunks can return more than one value,
662and so the syntax for the <b>return</b> statement is
663
664<pre>
665 stat ::= <b>return</b> [explist]
666</pre>
667
668<p>
669The <b>break</b> statement is used to terminate the execution of a
670<b>while</b>, <b>repeat</b>, or <b>for</b> loop,
671skipping to the next statement after the loop:
672
673
674<pre>
675 stat ::= <b>break</b>
676</pre><p>
677A <b>break</b> ends the innermost enclosing loop.
678
679
680<p>
681The <b>return</b> and <b>break</b>
682statements can only be written as the <em>last</em> statement of a block.
683If it is really necessary to <b>return</b> or <b>break</b> in the
684middle of a block,
685then an explicit inner block can be used,
686as in the idioms
687<code>do return end</code> and <code>do break end</code>,
688because now <b>return</b> and <b>break</b> are the last statements in
689their (inner) blocks.
690
691
692
693
694
695<h3>2.4.5 - <a name="2.4.5">For Statement</a></h3>
696
697<p>
698
699The <b>for</b> statement has two forms:
700one numeric and one generic.
701
702
703<p>
704The numeric <b>for</b> loop repeats a block of code while a
705control variable runs through an arithmetic progression.
706It has the following syntax:
707
708<pre>
709 stat ::= <b>for</b> Name `<b>=</b>&acute; exp `<b>,</b>&acute; exp [`<b>,</b>&acute; exp] <b>do</b> block <b>end</b>
710</pre><p>
711The <em>block</em> is repeated for <em>name</em> starting at the value of
712the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the
713third <em>exp</em>.
714More precisely, a <b>for</b> statement like
715
716<pre>
717 for v = <em>e1</em>, <em>e2</em>, <em>e3</em> do <em>block</em> end
718</pre><p>
719is equivalent to the code:
720
721<pre>
722 do
723 local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>)
724 if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end
725 while (<em>step</em> &gt; 0 and <em>var</em> &lt;= <em>limit</em>) or (<em>step</em> &lt;= 0 and <em>var</em> &gt;= <em>limit</em>) do
726 local v = <em>var</em>
727 <em>block</em>
728 <em>var</em> = <em>var</em> + <em>step</em>
729 end
730 end
731</pre><p>
732Note the following:
733
734<ul>
735
736<li>
737All three control expressions are evaluated only once,
738before the loop starts.
739They must all result in numbers.
740</li>
741
742<li>
743<code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables.
744The names shown here are for explanatory purposes only.
745</li>
746
747<li>
748If the third expression (the step) is absent,
749then a step of&nbsp;1 is used.
750</li>
751
752<li>
753You can use <b>break</b> to exit a <b>for</b> loop.
754</li>
755
756<li>
757The loop variable <code>v</code> is local to the loop;
758you cannot use its value after the <b>for</b> ends or is broken.
759If you need this value,
760assign it to another variable before breaking or exiting the loop.
761</li>
762
763</ul>
764
765<p>
766The generic <b>for</b> statement works over functions,
767called <em>iterators</em>.
768On each iteration, the iterator function is called to produce a new value,
769stopping when this new value is <b>nil</b>.
770The generic <b>for</b> loop has the following syntax:
771
772<pre>
773 stat ::= <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b>
774 namelist ::= Name {`<b>,</b>&acute; Name}
775</pre><p>
776A <b>for</b> statement like
777
778<pre>
779 for <em>var_1</em>, &middot;&middot;&middot;, <em>var_n</em> in <em>explist</em> do <em>block</em> end
780</pre><p>
781is equivalent to the code:
782
783<pre>
784 do
785 local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em>
786 while true do
787 local <em>var_1</em>, &middot;&middot;&middot;, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>)
788 <em>var</em> = <em>var_1</em>
789 if <em>var</em> == nil then break end
790 <em>block</em>
791 end
792 end
793</pre><p>
794Note the following:
795
796<ul>
797
798<li>
799<code><em>explist</em></code> is evaluated only once.
800Its results are an <em>iterator</em> function,
801a <em>state</em>,
802and an initial value for the first <em>iterator variable</em>.
803</li>
804
805<li>
806<code><em>f</em></code>, <code><em>s</em></code>, and <code><em>var</em></code> are invisible variables.
807The names are here for explanatory purposes only.
808</li>
809
810<li>
811You can use <b>break</b> to exit a <b>for</b> loop.
812</li>
813
814<li>
815The loop variables <code><em>var_i</em></code> are local to the loop;
816you cannot use their values after the <b>for</b> ends.
817If you need these values,
818then assign them to other variables before breaking or exiting the loop.
819</li>
820
821</ul>
822
823
824
825
826<h3>2.4.6 - <a name="2.4.6">Function Calls as Statements</a></h3><p>
827To allow possible side-effects,
828function calls can be executed as statements:
829
830<pre>
831 stat ::= functioncall
832</pre><p>
833In this case, all returned values are thrown away.
834Function calls are explained in <a href="#2.5.8">&sect;2.5.8</a>.
835
836
837
838
839
840<h3>2.4.7 - <a name="2.4.7">Local Declarations</a></h3><p>
841Local variables can be declared anywhere inside a block.
842The declaration can include an initial assignment:
843
844<pre>
845 stat ::= <b>local</b> namelist [`<b>=</b>&acute; explist]
846</pre><p>
847If present, an initial assignment has the same semantics
848of a multiple assignment (see <a href="#2.4.3">&sect;2.4.3</a>).
849Otherwise, all variables are initialized with <b>nil</b>.
850
851
852<p>
853A chunk is also a block (see <a href="#2.4.1">&sect;2.4.1</a>),
854and so local variables can be declared in a chunk outside any explicit block.
855The scope of such local variables extends until the end of the chunk.
856
857
858<p>
859The visibility rules for local variables are explained in <a href="#2.6">&sect;2.6</a>.
860
861
862
863
864
865
866
867<h2>2.5 - <a name="2.5">Expressions</a></h2>
868
869<p>
870The basic expressions in Lua are the following:
871
872<pre>
873 exp ::= prefixexp
874 exp ::= <b>nil</b> | <b>false</b> | <b>true</b>
875 exp ::= Number
876 exp ::= String
877 exp ::= function
878 exp ::= tableconstructor
879 exp ::= `<b>...</b>&acute;
880 exp ::= exp binop exp
881 exp ::= unop exp
882 prefixexp ::= var | functioncall | `<b>(</b>&acute; exp `<b>)</b>&acute;
883</pre>
884
885<p>
886Numbers and literal strings are explained in <a href="#2.1">&sect;2.1</a>;
887variables are explained in <a href="#2.3">&sect;2.3</a>;
888function definitions are explained in <a href="#2.5.9">&sect;2.5.9</a>;
889function calls are explained in <a href="#2.5.8">&sect;2.5.8</a>;
890table constructors are explained in <a href="#2.5.7">&sect;2.5.7</a>.
891Vararg expressions,
892denoted by three dots ('<code>...</code>'), can only be used when
893directly inside a vararg function;
894they are explained in <a href="#2.5.9">&sect;2.5.9</a>.
895
896
897<p>
898Binary operators comprise arithmetic operators (see <a href="#2.5.1">&sect;2.5.1</a>),
899relational operators (see <a href="#2.5.2">&sect;2.5.2</a>), logical operators (see <a href="#2.5.3">&sect;2.5.3</a>),
900and the concatenation operator (see <a href="#2.5.4">&sect;2.5.4</a>).
901Unary operators comprise the unary minus (see <a href="#2.5.1">&sect;2.5.1</a>),
902the unary <b>not</b> (see <a href="#2.5.3">&sect;2.5.3</a>),
903and the unary <em>length operator</em> (see <a href="#2.5.5">&sect;2.5.5</a>).
904
905
906<p>
907Both function calls and vararg expressions can result in multiple values.
908If an expression is used as a statement
909(only possible for function calls (see <a href="#2.4.6">&sect;2.4.6</a>)),
910then its return list is adjusted to zero elements,
911thus discarding all returned values.
912If an expression is used as the last (or the only) element
913of a list of expressions,
914then no adjustment is made
915(unless the call is enclosed in parentheses).
916In all other contexts,
917Lua adjusts the result list to one element,
918discarding all values except the first one.
919
920
921<p>
922Here are some examples:
923
924<pre>
925 f() -- adjusted to 0 results
926 g(f(), x) -- f() is adjusted to 1 result
927 g(x, f()) -- g gets x plus all results from f()
928 a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil)
929 a,b = ... -- a gets the first vararg parameter, b gets
930 -- the second (both a and b can get nil if there
931 -- is no corresponding vararg parameter)
932
933 a,b,c = x, f() -- f() is adjusted to 2 results
934 a,b,c = f() -- f() is adjusted to 3 results
935 return f() -- returns all results from f()
936 return ... -- returns all received vararg parameters
937 return x,y,f() -- returns x, y, and all results from f()
938 {f()} -- creates a list with all results from f()
939 {...} -- creates a list with all vararg parameters
940 {f(), nil} -- f() is adjusted to 1 result
941</pre>
942
943<p>
944Any expression enclosed in parentheses always results in only one value.
945Thus,
946<code>(f(x,y,z))</code> is always a single value,
947even if <code>f</code> returns several values.
948(The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code>
949or <b>nil</b> if <code>f</code> does not return any values.)
950
951
952
953<h3>2.5.1 - <a name="2.5.1">Arithmetic Operators</a></h3><p>
954Lua supports the usual arithmetic operators:
955the binary <code>+</code> (addition),
956<code>-</code> (subtraction), <code>*</code> (multiplication),
957<code>/</code> (division), <code>%</code> (modulo), and <code>^</code> (exponentiation);
958and unary <code>-</code> (negation).
959If the operands are numbers, or strings that can be converted to
960numbers (see <a href="#2.2.1">&sect;2.2.1</a>),
961then all operations have the usual meaning.
962Exponentiation works for any exponent.
963For instance, <code>x^(-0.5)</code> computes the inverse of the square root of <code>x</code>.
964Modulo is defined as
965
966<pre>
967 a % b == a - math.floor(a/b)*b
968</pre><p>
969That is, it is the remainder of a division that rounds
970the quotient towards minus infinity.
971
972
973
974
975
976<h3>2.5.2 - <a name="2.5.2">Relational Operators</a></h3><p>
977The relational operators in Lua are
978
979<pre>
980 == ~= &lt; &gt; &lt;= &gt;=
981</pre><p>
982These operators always result in <b>false</b> or <b>true</b>.
983
984
985<p>
986Equality (<code>==</code>) first compares the type of its operands.
987If the types are different, then the result is <b>false</b>.
988Otherwise, the values of the operands are compared.
989Numbers and strings are compared in the usual way.
990Objects (tables, userdata, threads, and functions)
991are compared by <em>reference</em>:
992two objects are considered equal only if they are the <em>same</em> object.
993Every time you create a new object
994(a table, userdata, thread, or function),
995this new object is different from any previously existing object.
996
997
998<p>
999You can change the way that Lua compares tables and userdata
1000by using the "eq" metamethod (see <a href="#2.8">&sect;2.8</a>).
1001
1002
1003<p>
1004The conversion rules of <a href="#2.2.1">&sect;2.2.1</a>
1005<em>do not</em> apply to equality comparisons.
1006Thus, <code>"0"==0</code> evaluates to <b>false</b>,
1007and <code>t[0]</code> and <code>t["0"]</code> denote different
1008entries in a table.
1009
1010
1011<p>
1012The operator <code>~=</code> is exactly the negation of equality (<code>==</code>).
1013
1014
1015<p>
1016The order operators work as follows.
1017If both arguments are numbers, then they are compared as such.
1018Otherwise, if both arguments are strings,
1019then their values are compared according to the current locale.
1020Otherwise, Lua tries to call the "lt" or the "le"
1021metamethod (see <a href="#2.8">&sect;2.8</a>).
1022A comparison <code>a &gt; b</code> is translated to <code>b &lt; a</code>
1023and <code>a &gt;= b</code> is translated to <code>b &lt;= a</code>.
1024
1025
1026
1027
1028
1029<h3>2.5.3 - <a name="2.5.3">Logical Operators</a></h3><p>
1030The logical operators in Lua are
1031<b>and</b>, <b>or</b>, and <b>not</b>.
1032Like the control structures (see <a href="#2.4.4">&sect;2.4.4</a>),
1033all logical operators consider both <b>false</b> and <b>nil</b> as false
1034and anything else as true.
1035
1036
1037<p>
1038The negation operator <b>not</b> always returns <b>false</b> or <b>true</b>.
1039The conjunction operator <b>and</b> returns its first argument
1040if this value is <b>false</b> or <b>nil</b>;
1041otherwise, <b>and</b> returns its second argument.
1042The disjunction operator <b>or</b> returns its first argument
1043if this value is different from <b>nil</b> and <b>false</b>;
1044otherwise, <b>or</b> returns its second argument.
1045Both <b>and</b> and <b>or</b> use short-cut evaluation;
1046that is,
1047the second operand is evaluated only if necessary.
1048Here are some examples:
1049
1050<pre>
1051 10 or 20 --&gt; 10
1052 10 or error() --&gt; 10
1053 nil or "a" --&gt; "a"
1054 nil and 10 --&gt; nil
1055 false and error() --&gt; false
1056 false and nil --&gt; false
1057 false or nil --&gt; nil
1058 10 and 20 --&gt; 20
1059</pre><p>
1060(In this manual,
1061<code>--&gt;</code> indicates the result of the preceding expression.)
1062
1063
1064
1065
1066
1067<h3>2.5.4 - <a name="2.5.4">Concatenation</a></h3><p>
1068The string concatenation operator in Lua is
1069denoted by two dots ('<code>..</code>').
1070If both operands are strings or numbers, then they are converted to
1071strings according to the rules mentioned in <a href="#2.2.1">&sect;2.2.1</a>.
1072Otherwise, the "concat" metamethod is called (see <a href="#2.8">&sect;2.8</a>).
1073
1074
1075
1076
1077
1078<h3>2.5.5 - <a name="2.5.5">The Length Operator</a></h3>
1079
1080<p>
1081The length operator is denoted by the unary operator <code>#</code>.
1082The length of a string is its number of bytes
1083(that is, the usual meaning of string length when each
1084character is one byte).
1085
1086
1087<p>
1088The length of a table <code>t</code> is defined to be any
1089integer index <code>n</code>
1090such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>;
1091moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> can be zero.
1092For a regular array, with non-nil values from 1 to a given <code>n</code>,
1093its length is exactly that <code>n</code>,
1094the index of its last value.
1095If the array has "holes"
1096(that is, <b>nil</b> values between other non-nil values),
1097then <code>#t</code> can be any of the indices that
1098directly precedes a <b>nil</b> value
1099(that is, it may consider any such <b>nil</b> value as the end of
1100the array).
1101
1102
1103
1104
1105
1106<h3>2.5.6 - <a name="2.5.6">Precedence</a></h3><p>
1107Operator precedence in Lua follows the table below,
1108from lower to higher priority:
1109
1110<pre>
1111 or
1112 and
1113 &lt; &gt; &lt;= &gt;= ~= ==
1114 ..
1115 + -
1116 * / %
1117 not # - (unary)
1118 ^
1119</pre><p>
1120As usual,
1121you can use parentheses to change the precedences of an expression.
1122The concatenation ('<code>..</code>') and exponentiation ('<code>^</code>')
1123operators are right associative.
1124All other binary operators are left associative.
1125
1126
1127
1128
1129
1130<h3>2.5.7 - <a name="2.5.7">Table Constructors</a></h3><p>
1131Table constructors are expressions that create tables.
1132Every time a constructor is evaluated, a new table is created.
1133A constructor can be used to create an empty table
1134or to create a table and initialize some of its fields.
1135The general syntax for constructors is
1136
1137<pre>
1138 tableconstructor ::= `<b>{</b>&acute; [fieldlist] `<b>}</b>&acute;
1139 fieldlist ::= field {fieldsep field} [fieldsep]
1140 field ::= `<b>[</b>&acute; exp `<b>]</b>&acute; `<b>=</b>&acute; exp | Name `<b>=</b>&acute; exp | exp
1141 fieldsep ::= `<b>,</b>&acute; | `<b>;</b>&acute;
1142</pre>
1143
1144<p>
1145Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry
1146with key <code>exp1</code> and value <code>exp2</code>.
1147A field of the form <code>name = exp</code> is equivalent to
1148<code>["name"] = exp</code>.
1149Finally, fields of the form <code>exp</code> are equivalent to
1150<code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers,
1151starting with 1.
1152Fields in the other formats do not affect this counting.
1153For example,
1154
1155<pre>
1156 a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
1157</pre><p>
1158is equivalent to
1159
1160<pre>
1161 do
1162 local t = {}
1163 t[f(1)] = g
1164 t[1] = "x" -- 1st exp
1165 t[2] = "y" -- 2nd exp
1166 t.x = 1 -- t["x"] = 1
1167 t[3] = f(x) -- 3rd exp
1168 t[30] = 23
1169 t[4] = 45 -- 4th exp
1170 a = t
1171 end
1172</pre>
1173
1174<p>
1175If the last field in the list has the form <code>exp</code>
1176and the expression is a function call or a vararg expression,
1177then all values returned by this expression enter the list consecutively
1178(see <a href="#2.5.8">&sect;2.5.8</a>).
1179To avoid this,
1180enclose the function call or the vararg expression
1181in parentheses (see <a href="#2.5">&sect;2.5</a>).
1182
1183
1184<p>
1185The field list can have an optional trailing separator,
1186as a convenience for machine-generated code.
1187
1188
1189
1190
1191
1192<h3>2.5.8 - <a name="2.5.8">Function Calls</a></h3><p>
1193A function call in Lua has the following syntax:
1194
1195<pre>
1196 functioncall ::= prefixexp args
1197</pre><p>
1198In a function call,
1199first prefixexp and args are evaluated.
1200If the value of prefixexp has type <em>function</em>,
1201then this function is called
1202with the given arguments.
1203Otherwise, the prefixexp "call" metamethod is called,
1204having as first parameter the value of prefixexp,
1205followed by the original call arguments
1206(see <a href="#2.8">&sect;2.8</a>).
1207
1208
1209<p>
1210The form
1211
1212<pre>
1213 functioncall ::= prefixexp `<b>:</b>&acute; Name args
1214</pre><p>
1215can be used to call "methods".
1216A call <code>v:name(<em>args</em>)</code>
1217is syntactic sugar for <code>v.name(v,<em>args</em>)</code>,
1218except that <code>v</code> is evaluated only once.
1219
1220
1221<p>
1222Arguments have the following syntax:
1223
1224<pre>
1225 args ::= `<b>(</b>&acute; [explist] `<b>)</b>&acute;
1226 args ::= tableconstructor
1227 args ::= String
1228</pre><p>
1229All argument expressions are evaluated before the call.
1230A call of the form <code>f{<em>fields</em>}</code> is
1231syntactic sugar for <code>f({<em>fields</em>})</code>;
1232that is, the argument list is a single new table.
1233A call of the form <code>f'<em>string</em>'</code>
1234(or <code>f"<em>string</em>"</code> or <code>f[[<em>string</em>]]</code>)
1235is syntactic sugar for <code>f('<em>string</em>')</code>;
1236that is, the argument list is a single literal string.
1237
1238
1239<p>
1240As an exception to the free-format syntax of Lua,
1241you cannot put a line break before the '<code>(</code>' in a function call.
1242This restriction avoids some ambiguities in the language.
1243If you write
1244
1245<pre>
1246 a = f
1247 (g).x(a)
1248</pre><p>
1249Lua would see that as a single statement, <code>a = f(g).x(a)</code>.
1250So, if you want two statements, you must add a semi-colon between them.
1251If you actually want to call <code>f</code>,
1252you must remove the line break before <code>(g)</code>.
1253
1254
1255<p>
1256A call of the form <code>return</code> <em>functioncall</em> is called
1257a <em>tail call</em>.
1258Lua implements <em>proper tail calls</em>
1259(or <em>proper tail recursion</em>):
1260in a tail call,
1261the called function reuses the stack entry of the calling function.
1262Therefore, there is no limit on the number of nested tail calls that
1263a program can execute.
1264However, a tail call erases any debug information about the
1265calling function.
1266Note that a tail call only happens with a particular syntax,
1267where the <b>return</b> has one single function call as argument;
1268this syntax makes the calling function return exactly
1269the returns of the called function.
1270So, none of the following examples are tail calls:
1271
1272<pre>
1273 return (f(x)) -- results adjusted to 1
1274 return 2 * f(x)
1275 return x, f(x) -- additional results
1276 f(x); return -- results discarded
1277 return x or f(x) -- results adjusted to 1
1278</pre>
1279
1280
1281
1282
1283<h3>2.5.9 - <a name="2.5.9">Function Definitions</a></h3>
1284
1285<p>
1286The syntax for function definition is
1287
1288<pre>
1289 function ::= <b>function</b> funcbody
1290 funcbody ::= `<b>(</b>&acute; [parlist] `<b>)</b>&acute; block <b>end</b>
1291</pre>
1292
1293<p>
1294The following syntactic sugar simplifies function definitions:
1295
1296<pre>
1297 stat ::= <b>function</b> funcname funcbody
1298 stat ::= <b>local</b> <b>function</b> Name funcbody
1299 funcname ::= Name {`<b>.</b>&acute; Name} [`<b>:</b>&acute; Name]
1300</pre><p>
1301The statement
1302
1303<pre>
1304 function f () <em>body</em> end
1305</pre><p>
1306translates to
1307
1308<pre>
1309 f = function () <em>body</em> end
1310</pre><p>
1311The statement
1312
1313<pre>
1314 function t.a.b.c.f () <em>body</em> end
1315</pre><p>
1316translates to
1317
1318<pre>
1319 t.a.b.c.f = function () <em>body</em> end
1320</pre><p>
1321The statement
1322
1323<pre>
1324 local function f () <em>body</em> end
1325</pre><p>
1326translates to
1327
1328<pre>
1329 local f; f = function () <em>body</em> end
1330</pre><p>
1331<em>not</em> to
1332
1333<pre>
1334 local f = function () <em>body</em> end
1335</pre><p>
1336(This only makes a difference when the body of the function
1337contains references to <code>f</code>.)
1338
1339
1340<p>
1341A function definition is an executable expression,
1342whose value has type <em>function</em>.
1343When Lua pre-compiles a chunk,
1344all its function bodies are pre-compiled too.
1345Then, whenever Lua executes the function definition,
1346the function is <em>instantiated</em> (or <em>closed</em>).
1347This function instance (or <em>closure</em>)
1348is the final value of the expression.
1349Different instances of the same function
1350can refer to different external local variables
1351and can have different environment tables.
1352
1353
1354<p>
1355Parameters act as local variables that are
1356initialized with the argument values:
1357
1358<pre>
1359 parlist ::= namelist [`<b>,</b>&acute; `<b>...</b>&acute;] | `<b>...</b>&acute;
1360</pre><p>
1361When a function is called,
1362the list of arguments is adjusted to
1363the length of the list of parameters,
1364unless the function is a variadic or <em>vararg function</em>,
1365which is
1366indicated by three dots ('<code>...</code>') at the end of its parameter list.
1367A vararg function does not adjust its argument list;
1368instead, it collects all extra arguments and supplies them
1369to the function through a <em>vararg expression</em>,
1370which is also written as three dots.
1371The value of this expression is a list of all actual extra arguments,
1372similar to a function with multiple results.
1373If a vararg expression is used inside another expression
1374or in the middle of a list of expressions,
1375then its return list is adjusted to one element.
1376If the expression is used as the last element of a list of expressions,
1377then no adjustment is made
1378(unless that last expression is enclosed in parentheses).
1379
1380
1381<p>
1382As an example, consider the following definitions:
1383
1384<pre>
1385 function f(a, b) end
1386 function g(a, b, ...) end
1387 function r() return 1,2,3 end
1388</pre><p>
1389Then, we have the following mapping from arguments to parameters and
1390to the vararg expression:
1391
1392<pre>
1393 CALL PARAMETERS
1394
1395 f(3) a=3, b=nil
1396 f(3, 4) a=3, b=4
1397 f(3, 4, 5) a=3, b=4
1398 f(r(), 10) a=1, b=10
1399 f(r()) a=1, b=2
1400
1401 g(3) a=3, b=nil, ... --&gt; (nothing)
1402 g(3, 4) a=3, b=4, ... --&gt; (nothing)
1403 g(3, 4, 5, 8) a=3, b=4, ... --&gt; 5 8
1404 g(5, r()) a=5, b=1, ... --&gt; 2 3
1405</pre>
1406
1407<p>
1408Results are returned using the <b>return</b> statement (see <a href="#2.4.4">&sect;2.4.4</a>).
1409If control reaches the end of a function
1410without encountering a <b>return</b> statement,
1411then the function returns with no results.
1412
1413
1414<p>
1415The <em>colon</em> syntax
1416is used for defining <em>methods</em>,
1417that is, functions that have an implicit extra parameter <code>self</code>.
1418Thus, the statement
1419
1420<pre>
1421 function t.a.b.c:f (<em>params</em>) <em>body</em> end
1422</pre><p>
1423is syntactic sugar for
1424
1425<pre>
1426 t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end
1427</pre>
1428
1429
1430
1431
1432
1433
1434<h2>2.6 - <a name="2.6">Visibility Rules</a></h2>
1435
1436<p>
1437
1438Lua is a lexically scoped language.
1439The scope of variables begins at the first statement <em>after</em>
1440their declaration and lasts until the end of the innermost block that
1441includes the declaration.
1442Consider the following example:
1443
1444<pre>
1445 x = 10 -- global variable
1446 do -- new block
1447 local x = x -- new 'x', with value 10
1448 print(x) --&gt; 10
1449 x = x+1
1450 do -- another block
1451 local x = x+1 -- another 'x'
1452 print(x) --&gt; 12
1453 end
1454 print(x) --&gt; 11
1455 end
1456 print(x) --&gt; 10 (the global one)
1457</pre>
1458
1459<p>
1460Notice that, in a declaration like <code>local x = x</code>,
1461the new <code>x</code> being declared is not in scope yet,
1462and so the second <code>x</code> refers to the outside variable.
1463
1464
1465<p>
1466Because of the lexical scoping rules,
1467local variables can be freely accessed by functions
1468defined inside their scope.
1469A local variable used by an inner function is called
1470an <em>upvalue</em>, or <em>external local variable</em>,
1471inside the inner function.
1472
1473
1474<p>
1475Notice that each execution of a <b>local</b> statement
1476defines new local variables.
1477Consider the following example:
1478
1479<pre>
1480 a = {}
1481 local x = 20
1482 for i=1,10 do
1483 local y = 0
1484 a[i] = function () y=y+1; return x+y end
1485 end
1486</pre><p>
1487The loop creates ten closures
1488(that is, ten instances of the anonymous function).
1489Each of these closures uses a different <code>y</code> variable,
1490while all of them share the same <code>x</code>.
1491
1492
1493
1494
1495
1496<h2>2.7 - <a name="2.7">Error Handling</a></h2>
1497
1498<p>
1499Because Lua is an embedded extension language,
1500all Lua actions start from C&nbsp;code in the host program
1501calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>).
1502Whenever an error occurs during Lua compilation or execution,
1503control returns to C,
1504which can take appropriate measures
1505(such as printing an error message).
1506
1507
1508<p>
1509Lua code can explicitly generate an error by calling the
1510<a href="#pdf-error"><code>error</code></a> function.
1511If you need to catch errors in Lua,
1512you can use the <a href="#pdf-pcall"><code>pcall</code></a> function.
1513
1514
1515
1516
1517
1518<h2>2.8 - <a name="2.8">Metatables</a></h2>
1519
1520<p>
1521Every value in Lua can have a <em>metatable</em>.
1522This <em>metatable</em> is an ordinary Lua table
1523that defines the behavior of the original value
1524under certain special operations.
1525You can change several aspects of the behavior
1526of operations over a value by setting specific fields in its metatable.
1527For instance, when a non-numeric value is the operand of an addition,
1528Lua checks for a function in the field <code>"__add"</code> in its metatable.
1529If it finds one,
1530Lua calls this function to perform the addition.
1531
1532
1533<p>
1534We call the keys in a metatable <em>events</em>
1535and the values <em>metamethods</em>.
1536In the previous example, the event is <code>"add"</code>
1537and the metamethod is the function that performs the addition.
1538
1539
1540<p>
1541You can query the metatable of any value
1542through the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function.
1543
1544
1545<p>
1546You can replace the metatable of tables
1547through the <a href="#pdf-setmetatable"><code>setmetatable</code></a>
1548function.
1549You cannot change the metatable of other types from Lua
1550(except by using the debug library);
1551you must use the C&nbsp;API for that.
1552
1553
1554<p>
1555Tables and full userdata have individual metatables
1556(although multiple tables and userdata can share their metatables).
1557Values of all other types share one single metatable per type;
1558that is, there is one single metatable for all numbers,
1559one for all strings, etc.
1560
1561
1562<p>
1563A metatable controls how an object behaves in arithmetic operations,
1564order comparisons, concatenation, length operation, and indexing.
1565A metatable also can define a function to be called when a userdata
1566is garbage collected.
1567For each of these operations Lua associates a specific key
1568called an <em>event</em>.
1569When Lua performs one of these operations over a value,
1570it checks whether this value has a metatable with the corresponding event.
1571If so, the value associated with that key (the metamethod)
1572controls how Lua will perform the operation.
1573
1574
1575<p>
1576Metatables control the operations listed next.
1577Each operation is identified by its corresponding name.
1578The key for each operation is a string with its name prefixed by
1579two underscores, '<code>__</code>';
1580for instance, the key for operation "add" is the
1581string <code>"__add"</code>.
1582The semantics of these operations is better explained by a Lua function
1583describing how the interpreter executes the operation.
1584
1585
1586<p>
1587The code shown here in Lua is only illustrative;
1588the real behavior is hard coded in the interpreter
1589and it is much more efficient than this simulation.
1590All functions used in these descriptions
1591(<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.)
1592are described in <a href="#5.1">&sect;5.1</a>.
1593In particular, to retrieve the metamethod of a given object,
1594we use the expression
1595
1596<pre>
1597 metatable(obj)[event]
1598</pre><p>
1599This should be read as
1600
1601<pre>
1602 rawget(getmetatable(obj) or {}, event)
1603</pre><p>
1604
1605That is, the access to a metamethod does not invoke other metamethods,
1606and the access to objects with no metatables does not fail
1607(it simply results in <b>nil</b>).
1608
1609
1610
1611<ul>
1612
1613<li><b>"add":</b>
1614the <code>+</code> operation.
1615
1616
1617
1618<p>
1619The function <code>getbinhandler</code> below defines how Lua chooses a handler
1620for a binary operation.
1621First, Lua tries the first operand.
1622If its type does not define a handler for the operation,
1623then Lua tries the second operand.
1624
1625<pre>
1626 function getbinhandler (op1, op2, event)
1627 return metatable(op1)[event] or metatable(op2)[event]
1628 end
1629</pre><p>
1630By using this function,
1631the behavior of the <code>op1 + op2</code> is
1632
1633<pre>
1634 function add_event (op1, op2)
1635 local o1, o2 = tonumber(op1), tonumber(op2)
1636 if o1 and o2 then -- both operands are numeric?
1637 return o1 + o2 -- '+' here is the primitive 'add'
1638 else -- at least one of the operands is not numeric
1639 local h = getbinhandler(op1, op2, "__add")
1640 if h then
1641 -- call the handler with both operands
1642 return (h(op1, op2))
1643 else -- no handler available: default behavior
1644 error(&middot;&middot;&middot;)
1645 end
1646 end
1647 end
1648</pre><p>
1649</li>
1650
1651<li><b>"sub":</b>
1652the <code>-</code> operation.
1653
1654Behavior similar to the "add" operation.
1655</li>
1656
1657<li><b>"mul":</b>
1658the <code>*</code> operation.
1659
1660Behavior similar to the "add" operation.
1661</li>
1662
1663<li><b>"div":</b>
1664the <code>/</code> operation.
1665
1666Behavior similar to the "add" operation.
1667</li>
1668
1669<li><b>"mod":</b>
1670the <code>%</code> operation.
1671
1672Behavior similar to the "add" operation,
1673with the operation
1674<code>o1 - floor(o1/o2)*o2</code> as the primitive operation.
1675</li>
1676
1677<li><b>"pow":</b>
1678the <code>^</code> (exponentiation) operation.
1679
1680Behavior similar to the "add" operation,
1681with the function <code>pow</code> (from the C&nbsp;math library)
1682as the primitive operation.
1683</li>
1684
1685<li><b>"unm":</b>
1686the unary <code>-</code> operation.
1687
1688
1689<pre>
1690 function unm_event (op)
1691 local o = tonumber(op)
1692 if o then -- operand is numeric?
1693 return -o -- '-' here is the primitive 'unm'
1694 else -- the operand is not numeric.
1695 -- Try to get a handler from the operand
1696 local h = metatable(op).__unm
1697 if h then
1698 -- call the handler with the operand
1699 return (h(op))
1700 else -- no handler available: default behavior
1701 error(&middot;&middot;&middot;)
1702 end
1703 end
1704 end
1705</pre><p>
1706</li>
1707
1708<li><b>"concat":</b>
1709the <code>..</code> (concatenation) operation.
1710
1711
1712<pre>
1713 function concat_event (op1, op2)
1714 if (type(op1) == "string" or type(op1) == "number") and
1715 (type(op2) == "string" or type(op2) == "number") then
1716 return op1 .. op2 -- primitive string concatenation
1717 else
1718 local h = getbinhandler(op1, op2, "__concat")
1719 if h then
1720 return (h(op1, op2))
1721 else
1722 error(&middot;&middot;&middot;)
1723 end
1724 end
1725 end
1726</pre><p>
1727</li>
1728
1729<li><b>"len":</b>
1730the <code>#</code> operation.
1731
1732
1733<pre>
1734 function len_event (op)
1735 if type(op) == "string" then
1736 return strlen(op) -- primitive string length
1737 elseif type(op) == "table" then
1738 return #op -- primitive table length
1739 else
1740 local h = metatable(op).__len
1741 if h then
1742 -- call the handler with the operand
1743 return (h(op))
1744 else -- no handler available: default behavior
1745 error(&middot;&middot;&middot;)
1746 end
1747 end
1748 end
1749</pre><p>
1750See <a href="#2.5.5">&sect;2.5.5</a> for a description of the length of a table.
1751</li>
1752
1753<li><b>"eq":</b>
1754the <code>==</code> operation.
1755
1756The function <code>getcomphandler</code> defines how Lua chooses a metamethod
1757for comparison operators.
1758A metamethod only is selected when both objects
1759being compared have the same type
1760and the same metamethod for the selected operation.
1761
1762<pre>
1763 function getcomphandler (op1, op2, event)
1764 if type(op1) ~= type(op2) then return nil end
1765 local mm1 = metatable(op1)[event]
1766 local mm2 = metatable(op2)[event]
1767 if mm1 == mm2 then return mm1 else return nil end
1768 end
1769</pre><p>
1770The "eq" event is defined as follows:
1771
1772<pre>
1773 function eq_event (op1, op2)
1774 if type(op1) ~= type(op2) then -- different types?
1775 return false -- different objects
1776 end
1777 if op1 == op2 then -- primitive equal?
1778 return true -- objects are equal
1779 end
1780 -- try metamethod
1781 local h = getcomphandler(op1, op2, "__eq")
1782 if h then
1783 return (h(op1, op2))
1784 else
1785 return false
1786 end
1787 end
1788</pre><p>
1789<code>a ~= b</code> is equivalent to <code>not (a == b)</code>.
1790</li>
1791
1792<li><b>"lt":</b>
1793the <code>&lt;</code> operation.
1794
1795
1796<pre>
1797 function lt_event (op1, op2)
1798 if type(op1) == "number" and type(op2) == "number" then
1799 return op1 &lt; op2 -- numeric comparison
1800 elseif type(op1) == "string" and type(op2) == "string" then
1801 return op1 &lt; op2 -- lexicographic comparison
1802 else
1803 local h = getcomphandler(op1, op2, "__lt")
1804 if h then
1805 return (h(op1, op2))
1806 else
1807 error(&middot;&middot;&middot;)
1808 end
1809 end
1810 end
1811</pre><p>
1812<code>a &gt; b</code> is equivalent to <code>b &lt; a</code>.
1813</li>
1814
1815<li><b>"le":</b>
1816the <code>&lt;=</code> operation.
1817
1818
1819<pre>
1820 function le_event (op1, op2)
1821 if type(op1) == "number" and type(op2) == "number" then
1822 return op1 &lt;= op2 -- numeric comparison
1823 elseif type(op1) == "string" and type(op2) == "string" then
1824 return op1 &lt;= op2 -- lexicographic comparison
1825 else
1826 local h = getcomphandler(op1, op2, "__le")
1827 if h then
1828 return (h(op1, op2))
1829 else
1830 h = getcomphandler(op1, op2, "__lt")
1831 if h then
1832 return not h(op2, op1)
1833 else
1834 error(&middot;&middot;&middot;)
1835 end
1836 end
1837 end
1838 end
1839</pre><p>
1840<code>a &gt;= b</code> is equivalent to <code>b &lt;= a</code>.
1841Note that, in the absence of a "le" metamethod,
1842Lua tries the "lt", assuming that <code>a &lt;= b</code> is
1843equivalent to <code>not (b &lt; a)</code>.
1844</li>
1845
1846<li><b>"index":</b>
1847The indexing access <code>table[key]</code>.
1848
1849
1850<pre>
1851 function gettable_event (table, key)
1852 local h
1853 if type(table) == "table" then
1854 local v = rawget(table, key)
1855 if v ~= nil then return v end
1856 h = metatable(table).__index
1857 if h == nil then return nil end
1858 else
1859 h = metatable(table).__index
1860 if h == nil then
1861 error(&middot;&middot;&middot;)
1862 end
1863 end
1864 if type(h) == "function" then
1865 return (h(table, key)) -- call the handler
1866 else return h[key] -- or repeat operation on it
1867 end
1868 end
1869</pre><p>
1870</li>
1871
1872<li><b>"newindex":</b>
1873The indexing assignment <code>table[key] = value</code>.
1874
1875
1876<pre>
1877 function settable_event (table, key, value)
1878 local h
1879 if type(table) == "table" then
1880 local v = rawget(table, key)
1881 if v ~= nil then rawset(table, key, value); return end
1882 h = metatable(table).__newindex
1883 if h == nil then rawset(table, key, value); return end
1884 else
1885 h = metatable(table).__newindex
1886 if h == nil then
1887 error(&middot;&middot;&middot;)
1888 end
1889 end
1890 if type(h) == "function" then
1891 h(table, key,value) -- call the handler
1892 else h[key] = value -- or repeat operation on it
1893 end
1894 end
1895</pre><p>
1896</li>
1897
1898<li><b>"call":</b>
1899called when Lua calls a value.
1900
1901
1902<pre>
1903 function function_event (func, ...)
1904 if type(func) == "function" then
1905 return func(...) -- primitive call
1906 else
1907 local h = metatable(func).__call
1908 if h then
1909 return h(func, ...)
1910 else
1911 error(&middot;&middot;&middot;)
1912 end
1913 end
1914 end
1915</pre><p>
1916</li>
1917
1918</ul>
1919
1920
1921
1922
1923<h2>2.9 - <a name="2.9">Environments</a></h2>
1924
1925<p>
1926Besides metatables,
1927objects of types thread, function, and userdata
1928have another table associated with them,
1929called their <em>environment</em>.
1930Like metatables, environments are regular tables and
1931multiple objects can share the same environment.
1932
1933
1934<p>
1935Threads are created sharing the environment of the creating thread.
1936Userdata and C&nbsp;functions are created sharing the environment
1937of the creating C&nbsp;function.
1938Non-nested Lua functions
1939(created by <a href="#pdf-loadfile"><code>loadfile</code></a>, <a href="#pdf-loadstring"><code>loadstring</code></a> or <a href="#pdf-load"><code>load</code></a>)
1940are created sharing the environment of the creating thread.
1941Nested Lua functions are created sharing the environment of
1942the creating Lua function.
1943
1944
1945<p>
1946Environments associated with userdata have no meaning for Lua.
1947It is only a convenience feature for programmers to associate a table to
1948a userdata.
1949
1950
1951<p>
1952Environments associated with threads are called
1953<em>global environments</em>.
1954They are used as the default environment for threads and
1955non-nested Lua functions created by the thread
1956and can be directly accessed by C&nbsp;code (see <a href="#3.3">&sect;3.3</a>).
1957
1958
1959<p>
1960The environment associated with a C&nbsp;function can be directly
1961accessed by C&nbsp;code (see <a href="#3.3">&sect;3.3</a>).
1962It is used as the default environment for other C&nbsp;functions
1963and userdata created by the function.
1964
1965
1966<p>
1967Environments associated with Lua functions are used to resolve
1968all accesses to global variables within the function (see <a href="#2.3">&sect;2.3</a>).
1969They are used as the default environment for nested Lua functions
1970created by the function.
1971
1972
1973<p>
1974You can change the environment of a Lua function or the
1975running thread by calling <a href="#pdf-setfenv"><code>setfenv</code></a>.
1976You can get the environment of a Lua function or the running thread
1977by calling <a href="#pdf-getfenv"><code>getfenv</code></a>.
1978To manipulate the environment of other objects
1979(userdata, C&nbsp;functions, other threads) you must
1980use the C&nbsp;API.
1981
1982
1983
1984
1985
1986<h2>2.10 - <a name="2.10">Garbage Collection</a></h2>
1987
1988<p>
1989Lua performs automatic memory management.
1990This means that
1991you have to worry neither about allocating memory for new objects
1992nor about freeing it when the objects are no longer needed.
1993Lua manages memory automatically by running
1994a <em>garbage collector</em> from time to time
1995to collect all <em>dead objects</em>
1996(that is, objects that are no longer accessible from Lua).
1997All memory used by Lua is subject to automatic management:
1998tables, userdata, functions, threads, strings, etc.
1999
2000
2001<p>
2002Lua implements an incremental mark-and-sweep collector.
2003It uses two numbers to control its garbage-collection cycles:
2004the <em>garbage-collector pause</em> and
2005the <em>garbage-collector step multiplier</em>.
2006Both use percentage points as units
2007(so that a value of 100 means an internal value of 1).
2008
2009
2010<p>
2011The garbage-collector pause
2012controls how long the collector waits before starting a new cycle.
2013Larger values make the collector less aggressive.
2014Values smaller than 100 mean the collector will not wait to
2015start a new cycle.
2016A value of 200 means that the collector waits for the total memory in use
2017to double before starting a new cycle.
2018
2019
2020<p>
2021The step multiplier
2022controls the relative speed of the collector relative to
2023memory allocation.
2024Larger values make the collector more aggressive but also increase
2025the size of each incremental step.
2026Values smaller than 100 make the collector too slow and
2027can result in the collector never finishing a cycle.
2028The default, 200, means that the collector runs at "twice"
2029the speed of memory allocation.
2030
2031
2032<p>
2033You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C
2034or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua.
2035With these functions you can also control
2036the collector directly (e.g., stop and restart it).
2037
2038
2039
2040<h3>2.10.1 - <a name="2.10.1">Garbage-Collection Metamethods</a></h3>
2041
2042<p>
2043Using the C&nbsp;API,
2044you can set garbage-collector metamethods for userdata (see <a href="#2.8">&sect;2.8</a>).
2045These metamethods are also called <em>finalizers</em>.
2046Finalizers allow you to coordinate Lua's garbage collection
2047with external resource management
2048(such as closing files, network or database connections,
2049or freeing your own memory).
2050
2051
2052<p>
2053Garbage userdata with a field <code>__gc</code> in their metatables are not
2054collected immediately by the garbage collector.
2055Instead, Lua puts them in a list.
2056After the collection,
2057Lua does the equivalent of the following function
2058for each userdata in that list:
2059
2060<pre>
2061 function gc_event (udata)
2062 local h = metatable(udata).__gc
2063 if h then
2064 h(udata)
2065 end
2066 end
2067</pre>
2068
2069<p>
2070At the end of each garbage-collection cycle,
2071the finalizers for userdata are called in <em>reverse</em>
2072order of their creation,
2073among those collected in that cycle.
2074That is, the first finalizer to be called is the one associated
2075with the userdata created last in the program.
2076The userdata itself is freed only in the next garbage-collection cycle.
2077
2078
2079
2080
2081
2082<h3>2.10.2 - <a name="2.10.2">Weak Tables</a></h3>
2083
2084<p>
2085A <em>weak table</em> is a table whose elements are
2086<em>weak references</em>.
2087A weak reference is ignored by the garbage collector.
2088In other words,
2089if the only references to an object are weak references,
2090then the garbage collector will collect this object.
2091
2092
2093<p>
2094A weak table can have weak keys, weak values, or both.
2095A table with weak keys allows the collection of its keys,
2096but prevents the collection of its values.
2097A table with both weak keys and weak values allows the collection of
2098both keys and values.
2099In any case, if either the key or the value is collected,
2100the whole pair is removed from the table.
2101The weakness of a table is controlled by the
2102<code>__mode</code> field of its metatable.
2103If the <code>__mode</code> field is a string containing the character&nbsp;'<code>k</code>',
2104the keys in the table are weak.
2105If <code>__mode</code> contains '<code>v</code>',
2106the values in the table are weak.
2107
2108
2109<p>
2110After you use a table as a metatable,
2111you should not change the value of its <code>__mode</code> field.
2112Otherwise, the weak behavior of the tables controlled by this
2113metatable is undefined.
2114
2115
2116
2117
2118
2119
2120
2121<h2>2.11 - <a name="2.11">Coroutines</a></h2>
2122
2123<p>
2124Lua supports coroutines,
2125also called <em>collaborative multithreading</em>.
2126A coroutine in Lua represents an independent thread of execution.
2127Unlike threads in multithread systems, however,
2128a coroutine only suspends its execution by explicitly calling
2129a yield function.
2130
2131
2132<p>
2133You create a coroutine with a call to <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>.
2134Its sole argument is a function
2135that is the main function of the coroutine.
2136The <code>create</code> function only creates a new coroutine and
2137returns a handle to it (an object of type <em>thread</em>);
2138it does not start the coroutine execution.
2139
2140
2141<p>
2142When you first call <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
2143passing as its first argument
2144a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
2145the coroutine starts its execution,
2146at the first line of its main function.
2147Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on
2148to the coroutine main function.
2149After the coroutine starts running,
2150it runs until it terminates or <em>yields</em>.
2151
2152
2153<p>
2154A coroutine can terminate its execution in two ways:
2155normally, when its main function returns
2156(explicitly or implicitly, after the last instruction);
2157and abnormally, if there is an unprotected error.
2158In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>,
2159plus any values returned by the coroutine main function.
2160In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b>
2161plus an error message.
2162
2163
2164<p>
2165A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
2166When a coroutine yields,
2167the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately,
2168even if the yield happens inside nested function calls
2169(that is, not in the main function,
2170but in a function directly or indirectly called by the main function).
2171In the case of a yield, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <b>true</b>,
2172plus any values passed to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
2173The next time you resume the same coroutine,
2174it continues its execution from the point where it yielded,
2175with the call to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a> returning any extra
2176arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
2177
2178
2179<p>
2180Like <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
2181the <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> function also creates a coroutine,
2182but instead of returning the coroutine itself,
2183it returns a function that, when called, resumes the coroutine.
2184Any arguments passed to this function
2185go as extra arguments to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
2186<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> returns all the values returned by <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
2187except the first one (the boolean error code).
2188Unlike <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
2189<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> does not catch errors;
2190any error is propagated to the caller.
2191
2192
2193<p>
2194As an example,
2195consider the following code:
2196
2197<pre>
2198 function foo (a)
2199 print("foo", a)
2200 return coroutine.yield(2*a)
2201 end
2202
2203 co = coroutine.create(function (a,b)
2204 print("co-body", a, b)
2205 local r = foo(a+1)
2206 print("co-body", r)
2207 local r, s = coroutine.yield(a+b, a-b)
2208 print("co-body", r, s)
2209 return b, "end"
2210 end)
2211
2212 print("main", coroutine.resume(co, 1, 10))
2213 print("main", coroutine.resume(co, "r"))
2214 print("main", coroutine.resume(co, "x", "y"))
2215 print("main", coroutine.resume(co, "x", "y"))
2216</pre><p>
2217When you run it, it produces the following output:
2218
2219<pre>
2220 co-body 1 10
2221 foo 2
2222
2223 main true 4
2224 co-body r
2225 main true 11 -9
2226 co-body x y
2227 main true 10 end
2228 main false cannot resume dead coroutine
2229</pre>
2230
2231
2232
2233
2234<h1>3 - <a name="3">The Application Program Interface</a></h1>
2235
2236<p>
2237
2238This section describes the C&nbsp;API for Lua, that is,
2239the set of C&nbsp;functions available to the host program to communicate
2240with Lua.
2241All API functions and related types and constants
2242are declared in the header file <a name="pdf-lua.h"><code>lua.h</code></a>.
2243
2244
2245<p>
2246Even when we use the term "function",
2247any facility in the API may be provided as a macro instead.
2248All such macros use each of their arguments exactly once
2249(except for the first argument, which is always a Lua state),
2250and so do not generate any hidden side-effects.
2251
2252
2253<p>
2254As in most C&nbsp;libraries,
2255the Lua API functions do not check their arguments for validity or consistency.
2256However, you can change this behavior by compiling Lua
2257with a proper definition for the macro <a name="pdf-luai_apicheck"><code>luai_apicheck</code></a>,
2258in file <code>luaconf.h</code>.
2259
2260
2261
2262<h2>3.1 - <a name="3.1">The Stack</a></h2>
2263
2264<p>
2265Lua uses a <em>virtual stack</em> to pass values to and from C.
2266Each element in this stack represents a Lua value
2267(<b>nil</b>, number, string, etc.).
2268
2269
2270<p>
2271Whenever Lua calls C, the called function gets a new stack,
2272which is independent of previous stacks and of stacks of
2273C&nbsp;functions that are still active.
2274This stack initially contains any arguments to the C&nbsp;function
2275and it is where the C&nbsp;function pushes its results
2276to be returned to the caller (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
2277
2278
2279<p>
2280For convenience,
2281most query operations in the API do not follow a strict stack discipline.
2282Instead, they can refer to any element in the stack
2283by using an <em>index</em>:
2284A positive index represents an <em>absolute</em> stack position
2285(starting at&nbsp;1);
2286a negative index represents an <em>offset</em> relative to the top of the stack.
2287More specifically, if the stack has <em>n</em> elements,
2288then index&nbsp;1 represents the first element
2289(that is, the element that was pushed onto the stack first)
2290and
2291index&nbsp;<em>n</em> represents the last element;
2292index&nbsp;-1 also represents the last element
2293(that is, the element at the&nbsp;top)
2294and index <em>-n</em> represents the first element.
2295We say that an index is <em>valid</em>
2296if it lies between&nbsp;1 and the stack top
2297(that is, if <code>1 &le; abs(index) &le; top</code>).
2298
2299
2300
2301
2302
2303
2304<h2>3.2 - <a name="3.2">Stack Size</a></h2>
2305
2306<p>
2307When you interact with Lua API,
2308you are responsible for ensuring consistency.
2309In particular,
2310<em>you are responsible for controlling stack overflow</em>.
2311You can use the function <a href="#lua_checkstack"><code>lua_checkstack</code></a>
2312to grow the stack size.
2313
2314
2315<p>
2316Whenever Lua calls C,
2317it ensures that at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> stack positions are available.
2318<code>LUA_MINSTACK</code> is defined as 20,
2319so that usually you do not have to worry about stack space
2320unless your code has loops pushing elements onto the stack.
2321
2322
2323<p>
2324Most query functions accept as indices any value inside the
2325available stack space, that is, indices up to the maximum stack size
2326you have set through <a href="#lua_checkstack"><code>lua_checkstack</code></a>.
2327Such indices are called <em>acceptable indices</em>.
2328More formally, we define an <em>acceptable index</em>
2329as follows:
2330
2331<pre>
2332 (index &lt; 0 &amp;&amp; abs(index) &lt;= top) ||
2333 (index &gt; 0 &amp;&amp; index &lt;= stackspace)
2334</pre><p>
2335Note that 0 is never an acceptable index.
2336
2337
2338
2339
2340
2341<h2>3.3 - <a name="3.3">Pseudo-Indices</a></h2>
2342
2343<p>
2344Unless otherwise noted,
2345any function that accepts valid indices can also be called with
2346<em>pseudo-indices</em>,
2347which represent some Lua values that are accessible to C&nbsp;code
2348but which are not in the stack.
2349Pseudo-indices are used to access the thread environment,
2350the function environment,
2351the registry,
2352and the upvalues of a C&nbsp;function (see <a href="#3.4">&sect;3.4</a>).
2353
2354
2355<p>
2356The thread environment (where global variables live) is
2357always at pseudo-index <a name="pdf-LUA_GLOBALSINDEX"><code>LUA_GLOBALSINDEX</code></a>.
2358The environment of the running C&nbsp;function is always
2359at pseudo-index <a name="pdf-LUA_ENVIRONINDEX"><code>LUA_ENVIRONINDEX</code></a>.
2360
2361
2362<p>
2363To access and change the value of global variables,
2364you can use regular table operations over an environment table.
2365For instance, to access the value of a global variable, do
2366
2367<pre>
2368 lua_getfield(L, LUA_GLOBALSINDEX, varname);
2369</pre>
2370
2371
2372
2373
2374<h2>3.4 - <a name="3.4">C Closures</a></h2>
2375
2376<p>
2377When a C&nbsp;function is created,
2378it is possible to associate some values with it,
2379thus creating a <em>C&nbsp;closure</em>;
2380these values are called <em>upvalues</em> and are
2381accessible to the function whenever it is called
2382(see <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>).
2383
2384
2385<p>
2386Whenever a C&nbsp;function is called,
2387its upvalues are located at specific pseudo-indices.
2388These pseudo-indices are produced by the macro
2389<a name="lua_upvalueindex"><code>lua_upvalueindex</code></a>.
2390The first value associated with a function is at position
2391<code>lua_upvalueindex(1)</code>, and so on.
2392Any access to <code>lua_upvalueindex(<em>n</em>)</code>,
2393where <em>n</em> is greater than the number of upvalues of the
2394current function (but not greater than 256),
2395produces an acceptable (but invalid) index.
2396
2397
2398
2399
2400
2401<h2>3.5 - <a name="3.5">Registry</a></h2>
2402
2403<p>
2404Lua provides a <em>registry</em>,
2405a pre-defined table that can be used by any C&nbsp;code to
2406store whatever Lua value it needs to store.
2407This table is always located at pseudo-index
2408<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>.
2409Any C&nbsp;library can store data into this table,
2410but it should take care to choose keys different from those used
2411by other libraries, to avoid collisions.
2412Typically, you should use as key a string containing your library name
2413or a light userdata with the address of a C&nbsp;object in your code.
2414
2415
2416<p>
2417The integer keys in the registry are used by the reference mechanism,
2418implemented by the auxiliary library,
2419and therefore should not be used for other purposes.
2420
2421
2422
2423
2424
2425<h2>3.6 - <a name="3.6">Error Handling in C</a></h2>
2426
2427<p>
2428Internally, Lua uses the C <code>longjmp</code> facility to handle errors.
2429(You can also choose to use exceptions if you use C++;
2430see file <code>luaconf.h</code>.)
2431When Lua faces any error
2432(such as memory allocation errors, type errors, syntax errors,
2433and runtime errors)
2434it <em>raises</em> an error;
2435that is, it does a long jump.
2436A <em>protected environment</em> uses <code>setjmp</code>
2437to set a recover point;
2438any error jumps to the most recent active recover point.
2439
2440
2441<p>
2442Most functions in the API can throw an error,
2443for instance due to a memory allocation error.
2444The documentation for each function indicates whether
2445it can throw errors.
2446
2447
2448<p>
2449Inside a C&nbsp;function you can throw an error by calling <a href="#lua_error"><code>lua_error</code></a>.
2450
2451
2452
2453
2454
2455<h2>3.7 - <a name="3.7">Functions and Types</a></h2>
2456
2457<p>
2458Here we list all functions and types from the C&nbsp;API in
2459alphabetical order.
2460Each function has an indicator like this:
2461<span class="apii">[-o, +p, <em>x</em>]</span>
2462
2463
2464<p>
2465The first field, <code>o</code>,
2466is how many elements the function pops from the stack.
2467The second field, <code>p</code>,
2468is how many elements the function pushes onto the stack.
2469(Any function always pushes its results after popping its arguments.)
2470A field in the form <code>x|y</code> means the function can push (or pop)
2471<code>x</code> or <code>y</code> elements,
2472depending on the situation;
2473an interrogation mark '<code>?</code>' means that
2474we cannot know how many elements the function pops/pushes
2475by looking only at its arguments
2476(e.g., they may depend on what is on the stack).
2477The third field, <code>x</code>,
2478tells whether the function may throw errors:
2479'<code>-</code>' means the function never throws any error;
2480'<code>m</code>' means the function may throw an error
2481only due to not enough memory;
2482'<code>e</code>' means the function may throw other kinds of errors;
2483'<code>v</code>' means the function may throw an error on purpose.
2484
2485
2486
2487<hr><h3><a name="lua_Alloc"><code>lua_Alloc</code></a></h3>
2488<pre>typedef void * (*lua_Alloc) (void *ud,
2489 void *ptr,
2490 size_t osize,
2491 size_t nsize);</pre>
2492
2493<p>
2494The type of the memory-allocation function used by Lua states.
2495The allocator function must provide a
2496functionality similar to <code>realloc</code>,
2497but not exactly the same.
2498Its arguments are
2499<code>ud</code>, an opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>;
2500<code>ptr</code>, a pointer to the block being allocated/reallocated/freed;
2501<code>osize</code>, the original size of the block;
2502<code>nsize</code>, the new size of the block.
2503<code>ptr</code> is <code>NULL</code> if and only if <code>osize</code> is zero.
2504When <code>nsize</code> is zero, the allocator must return <code>NULL</code>;
2505if <code>osize</code> is not zero,
2506it should free the block pointed to by <code>ptr</code>.
2507When <code>nsize</code> is not zero, the allocator returns <code>NULL</code>
2508if and only if it cannot fill the request.
2509When <code>nsize</code> is not zero and <code>osize</code> is zero,
2510the allocator should behave like <code>malloc</code>.
2511When <code>nsize</code> and <code>osize</code> are not zero,
2512the allocator behaves like <code>realloc</code>.
2513Lua assumes that the allocator never fails when
2514<code>osize &gt;= nsize</code>.
2515
2516
2517<p>
2518Here is a simple implementation for the allocator function.
2519It is used in the auxiliary library by <a href="#luaL_newstate"><code>luaL_newstate</code></a>.
2520
2521<pre>
2522 static void *l_alloc (void *ud, void *ptr, size_t osize,
2523 size_t nsize) {
2524 (void)ud; (void)osize; /* not used */
2525 if (nsize == 0) {
2526 free(ptr);
2527 return NULL;
2528 }
2529 else
2530 return realloc(ptr, nsize);
2531 }
2532</pre><p>
2533This code assumes
2534that <code>free(NULL)</code> has no effect and that
2535<code>realloc(NULL, size)</code> is equivalent to <code>malloc(size)</code>.
2536ANSI&nbsp;C ensures both behaviors.
2537
2538
2539
2540
2541
2542<hr><h3><a name="lua_atpanic"><code>lua_atpanic</code></a></h3><p>
2543<span class="apii">[-0, +0, <em>-</em>]</span>
2544<pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre>
2545
2546<p>
2547Sets a new panic function and returns the old one.
2548
2549
2550<p>
2551If an error happens outside any protected environment,
2552Lua calls a <em>panic function</em>
2553and then calls <code>exit(EXIT_FAILURE)</code>,
2554thus exiting the host application.
2555Your panic function can avoid this exit by
2556never returning (e.g., doing a long jump).
2557
2558
2559<p>
2560The panic function can access the error message at the top of the stack.
2561
2562
2563
2564
2565
2566<hr><h3><a name="lua_call"><code>lua_call</code></a></h3><p>
2567<span class="apii">[-(nargs + 1), +nresults, <em>e</em>]</span>
2568<pre>void lua_call (lua_State *L, int nargs, int nresults);</pre>
2569
2570<p>
2571Calls a function.
2572
2573
2574<p>
2575To call a function you must use the following protocol:
2576first, the function to be called is pushed onto the stack;
2577then, the arguments to the function are pushed
2578in direct order;
2579that is, the first argument is pushed first.
2580Finally you call <a href="#lua_call"><code>lua_call</code></a>;
2581<code>nargs</code> is the number of arguments that you pushed onto the stack.
2582All arguments and the function value are popped from the stack
2583when the function is called.
2584The function results are pushed onto the stack when the function returns.
2585The number of results is adjusted to <code>nresults</code>,
2586unless <code>nresults</code> is <a name="pdf-LUA_MULTRET"><code>LUA_MULTRET</code></a>.
2587In this case, <em>all</em> results from the function are pushed.
2588Lua takes care that the returned values fit into the stack space.
2589The function results are pushed onto the stack in direct order
2590(the first result is pushed first),
2591so that after the call the last result is on the top of the stack.
2592
2593
2594<p>
2595Any error inside the called function is propagated upwards
2596(with a <code>longjmp</code>).
2597
2598
2599<p>
2600The following example shows how the host program can do the
2601equivalent to this Lua code:
2602
2603<pre>
2604 a = f("how", t.x, 14)
2605</pre><p>
2606Here it is in&nbsp;C:
2607
2608<pre>
2609 lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */
2610 lua_pushstring(L, "how"); /* 1st argument */
2611 lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* table to be indexed */
2612 lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */
2613 lua_remove(L, -2); /* remove 't' from the stack */
2614 lua_pushinteger(L, 14); /* 3rd argument */
2615 lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */
2616 lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* set global 'a' */
2617</pre><p>
2618Note that the code above is "balanced":
2619at its end, the stack is back to its original configuration.
2620This is considered good programming practice.
2621
2622
2623
2624
2625
2626<hr><h3><a name="lua_CFunction"><code>lua_CFunction</code></a></h3>
2627<pre>typedef int (*lua_CFunction) (lua_State *L);</pre>
2628
2629<p>
2630Type for C&nbsp;functions.
2631
2632
2633<p>
2634In order to communicate properly with Lua,
2635a C&nbsp;function must use the following protocol,
2636which defines the way parameters and results are passed:
2637a C&nbsp;function receives its arguments from Lua in its stack
2638in direct order (the first argument is pushed first).
2639So, when the function starts,
2640<code>lua_gettop(L)</code> returns the number of arguments received by the function.
2641The first argument (if any) is at index 1
2642and its last argument is at index <code>lua_gettop(L)</code>.
2643To return values to Lua, a C&nbsp;function just pushes them onto the stack,
2644in direct order (the first result is pushed first),
2645and returns the number of results.
2646Any other value in the stack below the results will be properly
2647discarded by Lua.
2648Like a Lua function, a C&nbsp;function called by Lua can also return
2649many results.
2650
2651
2652<p>
2653As an example, the following function receives a variable number
2654of numerical arguments and returns their average and sum:
2655
2656<pre>
2657 static int foo (lua_State *L) {
2658 int n = lua_gettop(L); /* number of arguments */
2659 lua_Number sum = 0;
2660 int i;
2661 for (i = 1; i &lt;= n; i++) {
2662 if (!lua_isnumber(L, i)) {
2663 lua_pushstring(L, "incorrect argument");
2664 lua_error(L);
2665 }
2666 sum += lua_tonumber(L, i);
2667 }
2668 lua_pushnumber(L, sum/n); /* first result */
2669 lua_pushnumber(L, sum); /* second result */
2670 return 2; /* number of results */
2671 }
2672</pre>
2673
2674
2675
2676
2677<hr><h3><a name="lua_checkstack"><code>lua_checkstack</code></a></h3><p>
2678<span class="apii">[-0, +0, <em>m</em>]</span>
2679<pre>int lua_checkstack (lua_State *L, int extra);</pre>
2680
2681<p>
2682Ensures that there are at least <code>extra</code> free stack slots in the stack.
2683It returns false if it cannot grow the stack to that size.
2684This function never shrinks the stack;
2685if the stack is already larger than the new size,
2686it is left unchanged.
2687
2688
2689
2690
2691
2692<hr><h3><a name="lua_close"><code>lua_close</code></a></h3><p>
2693<span class="apii">[-0, +0, <em>-</em>]</span>
2694<pre>void lua_close (lua_State *L);</pre>
2695
2696<p>
2697Destroys all objects in the given Lua state
2698(calling the corresponding garbage-collection metamethods, if any)
2699and frees all dynamic memory used by this state.
2700On several platforms, you may not need to call this function,
2701because all resources are naturally released when the host program ends.
2702On the other hand, long-running programs,
2703such as a daemon or a web server,
2704might need to release states as soon as they are not needed,
2705to avoid growing too large.
2706
2707
2708
2709
2710
2711<hr><h3><a name="lua_concat"><code>lua_concat</code></a></h3><p>
2712<span class="apii">[-n, +1, <em>e</em>]</span>
2713<pre>void lua_concat (lua_State *L, int n);</pre>
2714
2715<p>
2716Concatenates the <code>n</code> values at the top of the stack,
2717pops them, and leaves the result at the top.
2718If <code>n</code>&nbsp;is&nbsp;1, the result is the single value on the stack
2719(that is, the function does nothing);
2720if <code>n</code> is 0, the result is the empty string.
2721Concatenation is performed following the usual semantics of Lua
2722(see <a href="#2.5.4">&sect;2.5.4</a>).
2723
2724
2725
2726
2727
2728<hr><h3><a name="lua_cpcall"><code>lua_cpcall</code></a></h3><p>
2729<span class="apii">[-0, +(0|1), <em>-</em>]</span>
2730<pre>int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);</pre>
2731
2732<p>
2733Calls the C&nbsp;function <code>func</code> in protected mode.
2734<code>func</code> starts with only one element in its stack,
2735a light userdata containing <code>ud</code>.
2736In case of errors,
2737<a href="#lua_cpcall"><code>lua_cpcall</code></a> returns the same error codes as <a href="#lua_pcall"><code>lua_pcall</code></a>,
2738plus the error object on the top of the stack;
2739otherwise, it returns zero, and does not change the stack.
2740All values returned by <code>func</code> are discarded.
2741
2742
2743
2744
2745
2746<hr><h3><a name="lua_createtable"><code>lua_createtable</code></a></h3><p>
2747<span class="apii">[-0, +1, <em>m</em>]</span>
2748<pre>void lua_createtable (lua_State *L, int narr, int nrec);</pre>
2749
2750<p>
2751Creates a new empty table and pushes it onto the stack.
2752The new table has space pre-allocated
2753for <code>narr</code> array elements and <code>nrec</code> non-array elements.
2754This pre-allocation is useful when you know exactly how many elements
2755the table will have.
2756Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</code></a>.
2757
2758
2759
2760
2761
2762<hr><h3><a name="lua_dump"><code>lua_dump</code></a></h3><p>
2763<span class="apii">[-0, +0, <em>m</em>]</span>
2764<pre>int lua_dump (lua_State *L, lua_Writer writer, void *data);</pre>
2765
2766<p>
2767Dumps a function as a binary chunk.
2768Receives a Lua function on the top of the stack
2769and produces a binary chunk that,
2770if loaded again,
2771results in a function equivalent to the one dumped.
2772As it produces parts of the chunk,
2773<a href="#lua_dump"><code>lua_dump</code></a> calls function <code>writer</code> (see <a href="#lua_Writer"><code>lua_Writer</code></a>)
2774with the given <code>data</code>
2775to write them.
2776
2777
2778<p>
2779The value returned is the error code returned by the last
2780call to the writer;
27810&nbsp;means no errors.
2782
2783
2784<p>
2785This function does not pop the Lua function from the stack.
2786
2787
2788
2789
2790
2791<hr><h3><a name="lua_equal"><code>lua_equal</code></a></h3><p>
2792<span class="apii">[-0, +0, <em>e</em>]</span>
2793<pre>int lua_equal (lua_State *L, int index1, int index2);</pre>
2794
2795<p>
2796Returns 1 if the two values in acceptable indices <code>index1</code> and
2797<code>index2</code> are equal,
2798following the semantics of the Lua <code>==</code> operator
2799(that is, may call metamethods).
2800Otherwise returns&nbsp;0.
2801Also returns&nbsp;0 if any of the indices is non valid.
2802
2803
2804
2805
2806
2807<hr><h3><a name="lua_error"><code>lua_error</code></a></h3><p>
2808<span class="apii">[-1, +0, <em>v</em>]</span>
2809<pre>int lua_error (lua_State *L);</pre>
2810
2811<p>
2812Generates a Lua error.
2813The error message (which can actually be a Lua value of any type)
2814must be on the stack top.
2815This function does a long jump,
2816and therefore never returns.
2817(see <a href="#luaL_error"><code>luaL_error</code></a>).
2818
2819
2820
2821
2822
2823<hr><h3><a name="lua_gc"><code>lua_gc</code></a></h3><p>
2824<span class="apii">[-0, +0, <em>e</em>]</span>
2825<pre>int lua_gc (lua_State *L, int what, int data);</pre>
2826
2827<p>
2828Controls the garbage collector.
2829
2830
2831<p>
2832This function performs several tasks,
2833according to the value of the parameter <code>what</code>:
2834
2835<ul>
2836
2837<li><b><code>LUA_GCSTOP</code>:</b>
2838stops the garbage collector.
2839</li>
2840
2841<li><b><code>LUA_GCRESTART</code>:</b>
2842restarts the garbage collector.
2843</li>
2844
2845<li><b><code>LUA_GCCOLLECT</code>:</b>
2846performs a full garbage-collection cycle.
2847</li>
2848
2849<li><b><code>LUA_GCCOUNT</code>:</b>
2850returns the current amount of memory (in Kbytes) in use by Lua.
2851</li>
2852
2853<li><b><code>LUA_GCCOUNTB</code>:</b>
2854returns the remainder of dividing the current amount of bytes of
2855memory in use by Lua by 1024.
2856</li>
2857
2858<li><b><code>LUA_GCSTEP</code>:</b>
2859performs an incremental step of garbage collection.
2860The step "size" is controlled by <code>data</code>
2861(larger values mean more steps) in a non-specified way.
2862If you want to control the step size
2863you must experimentally tune the value of <code>data</code>.
2864The function returns 1 if the step finished a
2865garbage-collection cycle.
2866</li>
2867
2868<li><b><code>LUA_GCSETPAUSE</code>:</b>
2869sets <code>data</code> as the new value
2870for the <em>pause</em> of the collector (see <a href="#2.10">&sect;2.10</a>).
2871The function returns the previous value of the pause.
2872</li>
2873
2874<li><b><code>LUA_GCSETSTEPMUL</code>:</b>
2875sets <code>data</code> as the new value for the <em>step multiplier</em> of
2876the collector (see <a href="#2.10">&sect;2.10</a>).
2877The function returns the previous value of the step multiplier.
2878</li>
2879
2880</ul>
2881
2882
2883
2884
2885<hr><h3><a name="lua_getallocf"><code>lua_getallocf</code></a></h3><p>
2886<span class="apii">[-0, +0, <em>-</em>]</span>
2887<pre>lua_Alloc lua_getallocf (lua_State *L, void **ud);</pre>
2888
2889<p>
2890Returns the memory-allocation function of a given state.
2891If <code>ud</code> is not <code>NULL</code>, Lua stores in <code>*ud</code> the
2892opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>.
2893
2894
2895
2896
2897
2898<hr><h3><a name="lua_getfenv"><code>lua_getfenv</code></a></h3><p>
2899<span class="apii">[-0, +1, <em>-</em>]</span>
2900<pre>void lua_getfenv (lua_State *L, int index);</pre>
2901
2902<p>
2903Pushes onto the stack the environment table of
2904the value at the given index.
2905
2906
2907
2908
2909
2910<hr><h3><a name="lua_getfield"><code>lua_getfield</code></a></h3><p>
2911<span class="apii">[-0, +1, <em>e</em>]</span>
2912<pre>void lua_getfield (lua_State *L, int index, const char *k);</pre>
2913
2914<p>
2915Pushes onto the stack the value <code>t[k]</code>,
2916where <code>t</code> is the value at the given valid index.
2917As in Lua, this function may trigger a metamethod
2918for the "index" event (see <a href="#2.8">&sect;2.8</a>).
2919
2920
2921
2922
2923
2924<hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p>
2925<span class="apii">[-0, +1, <em>e</em>]</span>
2926<pre>void lua_getglobal (lua_State *L, const char *name);</pre>
2927
2928<p>
2929Pushes onto the stack the value of the global <code>name</code>.
2930It is defined as a macro:
2931
2932<pre>
2933 #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
2934</pre>
2935
2936
2937
2938
2939<hr><h3><a name="lua_getmetatable"><code>lua_getmetatable</code></a></h3><p>
2940<span class="apii">[-0, +(0|1), <em>-</em>]</span>
2941<pre>int lua_getmetatable (lua_State *L, int index);</pre>
2942
2943<p>
2944Pushes onto the stack the metatable of the value at the given
2945acceptable index.
2946If the index is not valid,
2947or if the value does not have a metatable,
2948the function returns&nbsp;0 and pushes nothing on the stack.
2949
2950
2951
2952
2953
2954<hr><h3><a name="lua_gettable"><code>lua_gettable</code></a></h3><p>
2955<span class="apii">[-1, +1, <em>e</em>]</span>
2956<pre>void lua_gettable (lua_State *L, int index);</pre>
2957
2958<p>
2959Pushes onto the stack the value <code>t[k]</code>,
2960where <code>t</code> is the value at the given valid index
2961and <code>k</code> is the value at the top of the stack.
2962
2963
2964<p>
2965This function pops the key from the stack
2966(putting the resulting value in its place).
2967As in Lua, this function may trigger a metamethod
2968for the "index" event (see <a href="#2.8">&sect;2.8</a>).
2969
2970
2971
2972
2973
2974<hr><h3><a name="lua_gettop"><code>lua_gettop</code></a></h3><p>
2975<span class="apii">[-0, +0, <em>-</em>]</span>
2976<pre>int lua_gettop (lua_State *L);</pre>
2977
2978<p>
2979Returns the index of the top element in the stack.
2980Because indices start at&nbsp;1,
2981this result is equal to the number of elements in the stack
2982(and so 0&nbsp;means an empty stack).
2983
2984
2985
2986
2987
2988<hr><h3><a name="lua_insert"><code>lua_insert</code></a></h3><p>
2989<span class="apii">[-1, +1, <em>-</em>]</span>
2990<pre>void lua_insert (lua_State *L, int index);</pre>
2991
2992<p>
2993Moves the top element into the given valid index,
2994shifting up the elements above this index to open space.
2995Cannot be called with a pseudo-index,
2996because a pseudo-index is not an actual stack position.
2997
2998
2999
3000
3001
3002<hr><h3><a name="lua_Integer"><code>lua_Integer</code></a></h3>
3003<pre>typedef ptrdiff_t lua_Integer;</pre>
3004
3005<p>
3006The type used by the Lua API to represent integral values.
3007
3008
3009<p>
3010By default it is a <code>ptrdiff_t</code>,
3011which is usually the largest signed integral type the machine handles
3012"comfortably".
3013
3014
3015
3016
3017
3018<hr><h3><a name="lua_isboolean"><code>lua_isboolean</code></a></h3><p>
3019<span class="apii">[-0, +0, <em>-</em>]</span>
3020<pre>int lua_isboolean (lua_State *L, int index);</pre>
3021
3022<p>
3023Returns 1 if the value at the given acceptable index has type boolean,
3024and 0&nbsp;otherwise.
3025
3026
3027
3028
3029
3030<hr><h3><a name="lua_iscfunction"><code>lua_iscfunction</code></a></h3><p>
3031<span class="apii">[-0, +0, <em>-</em>]</span>
3032<pre>int lua_iscfunction (lua_State *L, int index);</pre>
3033
3034<p>
3035Returns 1 if the value at the given acceptable index is a C&nbsp;function,
3036and 0&nbsp;otherwise.
3037
3038
3039
3040
3041
3042<hr><h3><a name="lua_isfunction"><code>lua_isfunction</code></a></h3><p>
3043<span class="apii">[-0, +0, <em>-</em>]</span>
3044<pre>int lua_isfunction (lua_State *L, int index);</pre>
3045
3046<p>
3047Returns 1 if the value at the given acceptable index is a function
3048(either C or Lua), and 0&nbsp;otherwise.
3049
3050
3051
3052
3053
3054<hr><h3><a name="lua_islightuserdata"><code>lua_islightuserdata</code></a></h3><p>
3055<span class="apii">[-0, +0, <em>-</em>]</span>
3056<pre>int lua_islightuserdata (lua_State *L, int index);</pre>
3057
3058<p>
3059Returns 1 if the value at the given acceptable index is a light userdata,
3060and 0&nbsp;otherwise.
3061
3062
3063
3064
3065
3066<hr><h3><a name="lua_isnil"><code>lua_isnil</code></a></h3><p>
3067<span class="apii">[-0, +0, <em>-</em>]</span>
3068<pre>int lua_isnil (lua_State *L, int index);</pre>
3069
3070<p>
3071Returns 1 if the value at the given acceptable index is <b>nil</b>,
3072and 0&nbsp;otherwise.
3073
3074
3075
3076
3077
3078<hr><h3><a name="lua_isnone"><code>lua_isnone</code></a></h3><p>
3079<span class="apii">[-0, +0, <em>-</em>]</span>
3080<pre>int lua_isnone (lua_State *L, int index);</pre>
3081
3082<p>
3083Returns 1 if the given acceptable index is not valid
3084(that is, it refers to an element outside the current stack),
3085and 0&nbsp;otherwise.
3086
3087
3088
3089
3090
3091<hr><h3><a name="lua_isnoneornil"><code>lua_isnoneornil</code></a></h3><p>
3092<span class="apii">[-0, +0, <em>-</em>]</span>
3093<pre>int lua_isnoneornil (lua_State *L, int index);</pre>
3094
3095<p>
3096Returns 1 if the given acceptable index is not valid
3097(that is, it refers to an element outside the current stack)
3098or if the value at this index is <b>nil</b>,
3099and 0&nbsp;otherwise.
3100
3101
3102
3103
3104
3105<hr><h3><a name="lua_isnumber"><code>lua_isnumber</code></a></h3><p>
3106<span class="apii">[-0, +0, <em>-</em>]</span>
3107<pre>int lua_isnumber (lua_State *L, int index);</pre>
3108
3109<p>
3110Returns 1 if the value at the given acceptable index is a number
3111or a string convertible to a number,
3112and 0&nbsp;otherwise.
3113
3114
3115
3116
3117
3118<hr><h3><a name="lua_isstring"><code>lua_isstring</code></a></h3><p>
3119<span class="apii">[-0, +0, <em>-</em>]</span>
3120<pre>int lua_isstring (lua_State *L, int index);</pre>
3121
3122<p>
3123Returns 1 if the value at the given acceptable index is a string
3124or a number (which is always convertible to a string),
3125and 0&nbsp;otherwise.
3126
3127
3128
3129
3130
3131<hr><h3><a name="lua_istable"><code>lua_istable</code></a></h3><p>
3132<span class="apii">[-0, +0, <em>-</em>]</span>
3133<pre>int lua_istable (lua_State *L, int index);</pre>
3134
3135<p>
3136Returns 1 if the value at the given acceptable index is a table,
3137and 0&nbsp;otherwise.
3138
3139
3140
3141
3142
3143<hr><h3><a name="lua_isthread"><code>lua_isthread</code></a></h3><p>
3144<span class="apii">[-0, +0, <em>-</em>]</span>
3145<pre>int lua_isthread (lua_State *L, int index);</pre>
3146
3147<p>
3148Returns 1 if the value at the given acceptable index is a thread,
3149and 0&nbsp;otherwise.
3150
3151
3152
3153
3154
3155<hr><h3><a name="lua_isuserdata"><code>lua_isuserdata</code></a></h3><p>
3156<span class="apii">[-0, +0, <em>-</em>]</span>
3157<pre>int lua_isuserdata (lua_State *L, int index);</pre>
3158
3159<p>
3160Returns 1 if the value at the given acceptable index is a userdata
3161(either full or light), and 0&nbsp;otherwise.
3162
3163
3164
3165
3166
3167<hr><h3><a name="lua_lessthan"><code>lua_lessthan</code></a></h3><p>
3168<span class="apii">[-0, +0, <em>e</em>]</span>
3169<pre>int lua_lessthan (lua_State *L, int index1, int index2);</pre>
3170
3171<p>
3172Returns 1 if the value at acceptable index <code>index1</code> is smaller
3173than the value at acceptable index <code>index2</code>,
3174following the semantics of the Lua <code>&lt;</code> operator
3175(that is, may call metamethods).
3176Otherwise returns&nbsp;0.
3177Also returns&nbsp;0 if any of the indices is non valid.
3178
3179
3180
3181
3182
3183<hr><h3><a name="lua_load"><code>lua_load</code></a></h3><p>
3184<span class="apii">[-0, +1, <em>-</em>]</span>
3185<pre>int lua_load (lua_State *L,
3186 lua_Reader reader,
3187 void *data,
3188 const char *chunkname);</pre>
3189
3190<p>
3191Loads a Lua chunk.
3192If there are no errors,
3193<a href="#lua_load"><code>lua_load</code></a> pushes the compiled chunk as a Lua
3194function on top of the stack.
3195Otherwise, it pushes an error message.
3196The return values of <a href="#lua_load"><code>lua_load</code></a> are:
3197
3198<ul>
3199
3200<li><b>0:</b> no errors;</li>
3201
3202<li><b><a name="pdf-LUA_ERRSYNTAX"><code>LUA_ERRSYNTAX</code></a>:</b>
3203syntax error during pre-compilation;</li>
3204
3205<li><b><a href="#pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b>
3206memory allocation error.</li>
3207
3208</ul>
3209
3210<p>
3211This function only loads a chunk;
3212it does not run it.
3213
3214
3215<p>
3216<a href="#lua_load"><code>lua_load</code></a> automatically detects whether the chunk is text or binary,
3217and loads it accordingly (see program <code>luac</code>).
3218
3219
3220<p>
3221The <a href="#lua_load"><code>lua_load</code></a> function uses a user-supplied <code>reader</code> function
3222to read the chunk (see <a href="#lua_Reader"><code>lua_Reader</code></a>).
3223The <code>data</code> argument is an opaque value passed to the reader function.
3224
3225
3226<p>
3227The <code>chunkname</code> argument gives a name to the chunk,
3228which is used for error messages and in debug information (see <a href="#3.8">&sect;3.8</a>).
3229
3230
3231
3232
3233
3234<hr><h3><a name="lua_newstate"><code>lua_newstate</code></a></h3><p>
3235<span class="apii">[-0, +0, <em>-</em>]</span>
3236<pre>lua_State *lua_newstate (lua_Alloc f, void *ud);</pre>
3237
3238<p>
3239Creates a new, independent state.
3240Returns <code>NULL</code> if cannot create the state
3241(due to lack of memory).
3242The argument <code>f</code> is the allocator function;
3243Lua does all memory allocation for this state through this function.
3244The second argument, <code>ud</code>, is an opaque pointer that Lua
3245simply passes to the allocator in every call.
3246
3247
3248
3249
3250
3251<hr><h3><a name="lua_newtable"><code>lua_newtable</code></a></h3><p>
3252<span class="apii">[-0, +1, <em>m</em>]</span>
3253<pre>void lua_newtable (lua_State *L);</pre>
3254
3255<p>
3256Creates a new empty table and pushes it onto the stack.
3257It is equivalent to <code>lua_createtable(L, 0, 0)</code>.
3258
3259
3260
3261
3262
3263<hr><h3><a name="lua_newthread"><code>lua_newthread</code></a></h3><p>
3264<span class="apii">[-0, +1, <em>m</em>]</span>
3265<pre>lua_State *lua_newthread (lua_State *L);</pre>
3266
3267<p>
3268Creates a new thread, pushes it on the stack,
3269and returns a pointer to a <a href="#lua_State"><code>lua_State</code></a> that represents this new thread.
3270The new state returned by this function shares with the original state
3271all global objects (such as tables),
3272but has an independent execution stack.
3273
3274
3275<p>
3276There is no explicit function to close or to destroy a thread.
3277Threads are subject to garbage collection,
3278like any Lua object.
3279
3280
3281
3282
3283
3284<hr><h3><a name="lua_newuserdata"><code>lua_newuserdata</code></a></h3><p>
3285<span class="apii">[-0, +1, <em>m</em>]</span>
3286<pre>void *lua_newuserdata (lua_State *L, size_t size);</pre>
3287
3288<p>
3289This function allocates a new block of memory with the given size,
3290pushes onto the stack a new full userdata with the block address,
3291and returns this address.
3292
3293
3294<p>
3295Userdata represent C&nbsp;values in Lua.
3296A <em>full userdata</em> represents a block of memory.
3297It is an object (like a table):
3298you must create it, it can have its own metatable,
3299and you can detect when it is being collected.
3300A full userdata is only equal to itself (under raw equality).
3301
3302
3303<p>
3304When Lua collects a full userdata with a <code>gc</code> metamethod,
3305Lua calls the metamethod and marks the userdata as finalized.
3306When this userdata is collected again then
3307Lua frees its corresponding memory.
3308
3309
3310
3311
3312
3313<hr><h3><a name="lua_next"><code>lua_next</code></a></h3><p>
3314<span class="apii">[-1, +(2|0), <em>e</em>]</span>
3315<pre>int lua_next (lua_State *L, int index);</pre>
3316
3317<p>
3318Pops a key from the stack,
3319and pushes a key-value pair from the table at the given index
3320(the "next" pair after the given key).
3321If there are no more elements in the table,
3322then <a href="#lua_next"><code>lua_next</code></a> returns 0 (and pushes nothing).
3323
3324
3325<p>
3326A typical traversal looks like this:
3327
3328<pre>
3329 /* table is in the stack at index 't' */
3330 lua_pushnil(L); /* first key */
3331 while (lua_next(L, t) != 0) {
3332 /* uses 'key' (at index -2) and 'value' (at index -1) */
3333 printf("%s - %s\n",
3334 lua_typename(L, lua_type(L, -2)),
3335 lua_typename(L, lua_type(L, -1)));
3336 /* removes 'value'; keeps 'key' for next iteration */
3337 lua_pop(L, 1);
3338 }
3339</pre>
3340
3341<p>
3342While traversing a table,
3343do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key,
3344unless you know that the key is actually a string.
3345Recall that <a href="#lua_tolstring"><code>lua_tolstring</code></a> <em>changes</em>
3346the value at the given index;
3347this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>.
3348
3349
3350
3351
3352
3353<hr><h3><a name="lua_Number"><code>lua_Number</code></a></h3>
3354<pre>typedef double lua_Number;</pre>
3355
3356<p>
3357The type of numbers in Lua.
3358By default, it is double, but that can be changed in <code>luaconf.h</code>.
3359
3360
3361<p>
3362Through the configuration file you can change
3363Lua to operate with another type for numbers (e.g., float or long).
3364
3365
3366
3367
3368
3369<hr><h3><a name="lua_objlen"><code>lua_objlen</code></a></h3><p>
3370<span class="apii">[-0, +0, <em>-</em>]</span>
3371<pre>size_t lua_objlen (lua_State *L, int index);</pre>
3372
3373<p>
3374Returns the "length" of the value at the given acceptable index:
3375for strings, this is the string length;
3376for tables, this is the result of the length operator ('<code>#</code>');
3377for userdata, this is the size of the block of memory allocated
3378for the userdata;
3379for other values, it is&nbsp;0.
3380
3381
3382
3383
3384
3385<hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p>
3386<span class="apii">[-(nargs + 1), +(nresults|1), <em>-</em>]</span>
3387<pre>int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);</pre>
3388
3389<p>
3390Calls a function in protected mode.
3391
3392
3393<p>
3394Both <code>nargs</code> and <code>nresults</code> have the same meaning as
3395in <a href="#lua_call"><code>lua_call</code></a>.
3396If there are no errors during the call,
3397<a href="#lua_pcall"><code>lua_pcall</code></a> behaves exactly like <a href="#lua_call"><code>lua_call</code></a>.
3398However, if there is any error,
3399<a href="#lua_pcall"><code>lua_pcall</code></a> catches it,
3400pushes a single value on the stack (the error message),
3401and returns an error code.
3402Like <a href="#lua_call"><code>lua_call</code></a>,
3403<a href="#lua_pcall"><code>lua_pcall</code></a> always removes the function
3404and its arguments from the stack.
3405
3406
3407<p>
3408If <code>errfunc</code> is 0,
3409then the error message returned on the stack
3410is exactly the original error message.
3411Otherwise, <code>errfunc</code> is the stack index of an
3412<em>error handler function</em>.
3413(In the current implementation, this index cannot be a pseudo-index.)
3414In case of runtime errors,
3415this function will be called with the error message
3416and its return value will be the message returned on the stack by <a href="#lua_pcall"><code>lua_pcall</code></a>.
3417
3418
3419<p>
3420Typically, the error handler function is used to add more debug
3421information to the error message, such as a stack traceback.
3422Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>,
3423since by then the stack has unwound.
3424
3425
3426<p>
3427The <a href="#lua_pcall"><code>lua_pcall</code></a> function returns 0 in case of success
3428or one of the following error codes
3429(defined in <code>lua.h</code>):
3430
3431<ul>
3432
3433<li><b><a name="pdf-LUA_ERRRUN"><code>LUA_ERRRUN</code></a>:</b>
3434a runtime error.
3435</li>
3436
3437<li><b><a name="pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b>
3438memory allocation error.
3439For such errors, Lua does not call the error handler function.
3440</li>
3441
3442<li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a>:</b>
3443error while running the error handler function.
3444</li>
3445
3446</ul>
3447
3448
3449
3450
3451<hr><h3><a name="lua_pop"><code>lua_pop</code></a></h3><p>
3452<span class="apii">[-n, +0, <em>-</em>]</span>
3453<pre>void lua_pop (lua_State *L, int n);</pre>
3454
3455<p>
3456Pops <code>n</code> elements from the stack.
3457
3458
3459
3460
3461
3462<hr><h3><a name="lua_pushboolean"><code>lua_pushboolean</code></a></h3><p>
3463<span class="apii">[-0, +1, <em>-</em>]</span>
3464<pre>void lua_pushboolean (lua_State *L, int b);</pre>
3465
3466<p>
3467Pushes a boolean value with value <code>b</code> onto the stack.
3468
3469
3470
3471
3472
3473<hr><h3><a name="lua_pushcclosure"><code>lua_pushcclosure</code></a></h3><p>
3474<span class="apii">[-n, +1, <em>m</em>]</span>
3475<pre>void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);</pre>
3476
3477<p>
3478Pushes a new C&nbsp;closure onto the stack.
3479
3480
3481<p>
3482When a C&nbsp;function is created,
3483it is possible to associate some values with it,
3484thus creating a C&nbsp;closure (see <a href="#3.4">&sect;3.4</a>);
3485these values are then accessible to the function whenever it is called.
3486To associate values with a C&nbsp;function,
3487first these values should be pushed onto the stack
3488(when there are multiple values, the first value is pushed first).
3489Then <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>
3490is called to create and push the C&nbsp;function onto the stack,
3491with the argument <code>n</code> telling how many values should be
3492associated with the function.
3493<a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> also pops these values from the stack.
3494
3495
3496<p>
3497The maximum value for <code>n</code> is 255.
3498
3499
3500
3501
3502
3503<hr><h3><a name="lua_pushcfunction"><code>lua_pushcfunction</code></a></h3><p>
3504<span class="apii">[-0, +1, <em>m</em>]</span>
3505<pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre>
3506
3507<p>
3508Pushes a C&nbsp;function onto the stack.
3509This function receives a pointer to a C function
3510and pushes onto the stack a Lua value of type <code>function</code> that,
3511when called, invokes the corresponding C&nbsp;function.
3512
3513
3514<p>
3515Any function to be registered in Lua must
3516follow the correct protocol to receive its parameters
3517and return its results (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
3518
3519
3520<p>
3521<code>lua_pushcfunction</code> is defined as a macro:
3522
3523<pre>
3524 #define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
3525</pre>
3526
3527
3528
3529
3530<hr><h3><a name="lua_pushfstring"><code>lua_pushfstring</code></a></h3><p>
3531<span class="apii">[-0, +1, <em>m</em>]</span>
3532<pre>const char *lua_pushfstring (lua_State *L, const char *fmt, ...);</pre>
3533
3534<p>
3535Pushes onto the stack a formatted string
3536and returns a pointer to this string.
3537It is similar to the C&nbsp;function <code>sprintf</code>,
3538but has some important differences:
3539
3540<ul>
3541
3542<li>
3543You do not have to allocate space for the result:
3544the result is a Lua string and Lua takes care of memory allocation
3545(and deallocation, through garbage collection).
3546</li>
3547
3548<li>
3549The conversion specifiers are quite restricted.
3550There are no flags, widths, or precisions.
3551The conversion specifiers can only be
3552'<code>%%</code>' (inserts a '<code>%</code>' in the string),
3553'<code>%s</code>' (inserts a zero-terminated string, with no size restrictions),
3554'<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>),
3555'<code>%p</code>' (inserts a pointer as a hexadecimal numeral),
3556'<code>%d</code>' (inserts an <code>int</code>), and
3557'<code>%c</code>' (inserts an <code>int</code> as a character).
3558</li>
3559
3560</ul>
3561
3562
3563
3564
3565<hr><h3><a name="lua_pushinteger"><code>lua_pushinteger</code></a></h3><p>
3566<span class="apii">[-0, +1, <em>-</em>]</span>
3567<pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre>
3568
3569<p>
3570Pushes a number with value <code>n</code> onto the stack.
3571
3572
3573
3574
3575
3576<hr><h3><a name="lua_pushlightuserdata"><code>lua_pushlightuserdata</code></a></h3><p>
3577<span class="apii">[-0, +1, <em>-</em>]</span>
3578<pre>void lua_pushlightuserdata (lua_State *L, void *p);</pre>
3579
3580<p>
3581Pushes a light userdata onto the stack.
3582
3583
3584<p>
3585Userdata represent C&nbsp;values in Lua.
3586A <em>light userdata</em> represents a pointer.
3587It is a value (like a number):
3588you do not create it, it has no individual metatable,
3589and it is not collected (as it was never created).
3590A light userdata is equal to "any"
3591light userdata with the same C&nbsp;address.
3592
3593
3594
3595
3596
3597<hr><h3><a name="lua_pushliteral"><code>lua_pushliteral</code></a></h3><p>
3598<span class="apii">[-0, +1, <em>m</em>]</span>
3599<pre>void lua_pushliteral (lua_State *L, const char *s);</pre>
3600
3601<p>
3602This macro is equivalent to <a href="#lua_pushlstring"><code>lua_pushlstring</code></a>,
3603but can be used only when <code>s</code> is a literal string.
3604In these cases, it automatically provides the string length.
3605
3606
3607
3608
3609
3610<hr><h3><a name="lua_pushlstring"><code>lua_pushlstring</code></a></h3><p>
3611<span class="apii">[-0, +1, <em>m</em>]</span>
3612<pre>void lua_pushlstring (lua_State *L, const char *s, size_t len);</pre>
3613
3614<p>
3615Pushes the string pointed to by <code>s</code> with size <code>len</code>
3616onto the stack.
3617Lua makes (or reuses) an internal copy of the given string,
3618so the memory at <code>s</code> can be freed or reused immediately after
3619the function returns.
3620The string can contain embedded zeros.
3621
3622
3623
3624
3625
3626<hr><h3><a name="lua_pushnil"><code>lua_pushnil</code></a></h3><p>
3627<span class="apii">[-0, +1, <em>-</em>]</span>
3628<pre>void lua_pushnil (lua_State *L);</pre>
3629
3630<p>
3631Pushes a nil value onto the stack.
3632
3633
3634
3635
3636
3637<hr><h3><a name="lua_pushnumber"><code>lua_pushnumber</code></a></h3><p>
3638<span class="apii">[-0, +1, <em>-</em>]</span>
3639<pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre>
3640
3641<p>
3642Pushes a number with value <code>n</code> onto the stack.
3643
3644
3645
3646
3647
3648<hr><h3><a name="lua_pushstring"><code>lua_pushstring</code></a></h3><p>
3649<span class="apii">[-0, +1, <em>m</em>]</span>
3650<pre>void lua_pushstring (lua_State *L, const char *s);</pre>
3651
3652<p>
3653Pushes the zero-terminated string pointed to by <code>s</code>
3654onto the stack.
3655Lua makes (or reuses) an internal copy of the given string,
3656so the memory at <code>s</code> can be freed or reused immediately after
3657the function returns.
3658The string cannot contain embedded zeros;
3659it is assumed to end at the first zero.
3660
3661
3662
3663
3664
3665<hr><h3><a name="lua_pushthread"><code>lua_pushthread</code></a></h3><p>
3666<span class="apii">[-0, +1, <em>-</em>]</span>
3667<pre>int lua_pushthread (lua_State *L);</pre>
3668
3669<p>
3670Pushes the thread represented by <code>L</code> onto the stack.
3671Returns 1 if this thread is the main thread of its state.
3672
3673
3674
3675
3676
3677<hr><h3><a name="lua_pushvalue"><code>lua_pushvalue</code></a></h3><p>
3678<span class="apii">[-0, +1, <em>-</em>]</span>
3679<pre>void lua_pushvalue (lua_State *L, int index);</pre>
3680
3681<p>
3682Pushes a copy of the element at the given valid index
3683onto the stack.
3684
3685
3686
3687
3688
3689<hr><h3><a name="lua_pushvfstring"><code>lua_pushvfstring</code></a></h3><p>
3690<span class="apii">[-0, +1, <em>m</em>]</span>
3691<pre>const char *lua_pushvfstring (lua_State *L,
3692 const char *fmt,
3693 va_list argp);</pre>
3694
3695<p>
3696Equivalent to <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>, except that it receives a <code>va_list</code>
3697instead of a variable number of arguments.
3698
3699
3700
3701
3702
3703<hr><h3><a name="lua_rawequal"><code>lua_rawequal</code></a></h3><p>
3704<span class="apii">[-0, +0, <em>-</em>]</span>
3705<pre>int lua_rawequal (lua_State *L, int index1, int index2);</pre>
3706
3707<p>
3708Returns 1 if the two values in acceptable indices <code>index1</code> and
3709<code>index2</code> are primitively equal
3710(that is, without calling metamethods).
3711Otherwise returns&nbsp;0.
3712Also returns&nbsp;0 if any of the indices are non valid.
3713
3714
3715
3716
3717
3718<hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p>
3719<span class="apii">[-1, +1, <em>-</em>]</span>
3720<pre>void lua_rawget (lua_State *L, int index);</pre>
3721
3722<p>
3723Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw access
3724(i.e., without metamethods).
3725
3726
3727
3728
3729
3730<hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p>
3731<span class="apii">[-0, +1, <em>-</em>]</span>
3732<pre>void lua_rawgeti (lua_State *L, int index, int n);</pre>
3733
3734<p>
3735Pushes onto the stack the value <code>t[n]</code>,
3736where <code>t</code> is the value at the given valid index.
3737The access is raw;
3738that is, it does not invoke metamethods.
3739
3740
3741
3742
3743
3744<hr><h3><a name="lua_rawset"><code>lua_rawset</code></a></h3><p>
3745<span class="apii">[-2, +0, <em>m</em>]</span>
3746<pre>void lua_rawset (lua_State *L, int index);</pre>
3747
3748<p>
3749Similar to <a href="#lua_settable"><code>lua_settable</code></a>, but does a raw assignment
3750(i.e., without metamethods).
3751
3752
3753
3754
3755
3756<hr><h3><a name="lua_rawseti"><code>lua_rawseti</code></a></h3><p>
3757<span class="apii">[-1, +0, <em>m</em>]</span>
3758<pre>void lua_rawseti (lua_State *L, int index, int n);</pre>
3759
3760<p>
3761Does the equivalent of <code>t[n] = v</code>,
3762where <code>t</code> is the value at the given valid index
3763and <code>v</code> is the value at the top of the stack.
3764
3765
3766<p>
3767This function pops the value from the stack.
3768The assignment is raw;
3769that is, it does not invoke metamethods.
3770
3771
3772
3773
3774
3775<hr><h3><a name="lua_Reader"><code>lua_Reader</code></a></h3>
3776<pre>typedef const char * (*lua_Reader) (lua_State *L,
3777 void *data,
3778 size_t *size);</pre>
3779
3780<p>
3781The reader function used by <a href="#lua_load"><code>lua_load</code></a>.
3782Every time it needs another piece of the chunk,
3783<a href="#lua_load"><code>lua_load</code></a> calls the reader,
3784passing along its <code>data</code> parameter.
3785The reader must return a pointer to a block of memory
3786with a new piece of the chunk
3787and set <code>size</code> to the block size.
3788The block must exist until the reader function is called again.
3789To signal the end of the chunk,
3790the reader must return <code>NULL</code> or set <code>size</code> to zero.
3791The reader function may return pieces of any size greater than zero.
3792
3793
3794
3795
3796
3797<hr><h3><a name="lua_register"><code>lua_register</code></a></h3><p>
3798<span class="apii">[-0, +0, <em>e</em>]</span>
3799<pre>void lua_register (lua_State *L,
3800 const char *name,
3801 lua_CFunction f);</pre>
3802
3803<p>
3804Sets the C function <code>f</code> as the new value of global <code>name</code>.
3805It is defined as a macro:
3806
3807<pre>
3808 #define lua_register(L,n,f) \
3809 (lua_pushcfunction(L, f), lua_setglobal(L, n))
3810</pre>
3811
3812
3813
3814
3815<hr><h3><a name="lua_remove"><code>lua_remove</code></a></h3><p>
3816<span class="apii">[-1, +0, <em>-</em>]</span>
3817<pre>void lua_remove (lua_State *L, int index);</pre>
3818
3819<p>
3820Removes the element at the given valid index,
3821shifting down the elements above this index to fill the gap.
3822Cannot be called with a pseudo-index,
3823because a pseudo-index is not an actual stack position.
3824
3825
3826
3827
3828
3829<hr><h3><a name="lua_replace"><code>lua_replace</code></a></h3><p>
3830<span class="apii">[-1, +0, <em>-</em>]</span>
3831<pre>void lua_replace (lua_State *L, int index);</pre>
3832
3833<p>
3834Moves the top element into the given position (and pops it),
3835without shifting any element
3836(therefore replacing the value at the given position).
3837
3838
3839
3840
3841
3842<hr><h3><a name="lua_resume"><code>lua_resume</code></a></h3><p>
3843<span class="apii">[-?, +?, <em>-</em>]</span>
3844<pre>int lua_resume (lua_State *L, int narg);</pre>
3845
3846<p>
3847Starts and resumes a coroutine in a given thread.
3848
3849
3850<p>
3851To start a coroutine, you first create a new thread
3852(see <a href="#lua_newthread"><code>lua_newthread</code></a>);
3853then you push onto its stack the main function plus any arguments;
3854then you call <a href="#lua_resume"><code>lua_resume</code></a>,
3855with <code>narg</code> being the number of arguments.
3856This call returns when the coroutine suspends or finishes its execution.
3857When it returns, the stack contains all values passed to <a href="#lua_yield"><code>lua_yield</code></a>,
3858or all values returned by the body function.
3859<a href="#lua_resume"><code>lua_resume</code></a> returns
3860<a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the coroutine yields,
38610 if the coroutine finishes its execution
3862without errors,
3863or an error code in case of errors (see <a href="#lua_pcall"><code>lua_pcall</code></a>).
3864In case of errors,
3865the stack is not unwound,
3866so you can use the debug API over it.
3867The error message is on the top of the stack.
3868To restart a coroutine, you put on its stack only the values to
3869be passed as results from <code>yield</code>,
3870and then call <a href="#lua_resume"><code>lua_resume</code></a>.
3871
3872
3873
3874
3875
3876<hr><h3><a name="lua_setallocf"><code>lua_setallocf</code></a></h3><p>
3877<span class="apii">[-0, +0, <em>-</em>]</span>
3878<pre>void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);</pre>
3879
3880<p>
3881Changes the allocator function of a given state to <code>f</code>
3882with user data <code>ud</code>.
3883
3884
3885
3886
3887
3888<hr><h3><a name="lua_setfenv"><code>lua_setfenv</code></a></h3><p>
3889<span class="apii">[-1, +0, <em>-</em>]</span>
3890<pre>int lua_setfenv (lua_State *L, int index);</pre>
3891
3892<p>
3893Pops a table from the stack and sets it as
3894the new environment for the value at the given index.
3895If the value at the given index is
3896neither a function nor a thread nor a userdata,
3897<a href="#lua_setfenv"><code>lua_setfenv</code></a> returns 0.
3898Otherwise it returns 1.
3899
3900
3901
3902
3903
3904<hr><h3><a name="lua_setfield"><code>lua_setfield</code></a></h3><p>
3905<span class="apii">[-1, +0, <em>e</em>]</span>
3906<pre>void lua_setfield (lua_State *L, int index, const char *k);</pre>
3907
3908<p>
3909Does the equivalent to <code>t[k] = v</code>,
3910where <code>t</code> is the value at the given valid index
3911and <code>v</code> is the value at the top of the stack.
3912
3913
3914<p>
3915This function pops the value from the stack.
3916As in Lua, this function may trigger a metamethod
3917for the "newindex" event (see <a href="#2.8">&sect;2.8</a>).
3918
3919
3920
3921
3922
3923<hr><h3><a name="lua_setglobal"><code>lua_setglobal</code></a></h3><p>
3924<span class="apii">[-1, +0, <em>e</em>]</span>
3925<pre>void lua_setglobal (lua_State *L, const char *name);</pre>
3926
3927<p>
3928Pops a value from the stack and
3929sets it as the new value of global <code>name</code>.
3930It is defined as a macro:
3931
3932<pre>
3933 #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
3934</pre>
3935
3936
3937
3938
3939<hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p>
3940<span class="apii">[-1, +0, <em>-</em>]</span>
3941<pre>int lua_setmetatable (lua_State *L, int index);</pre>
3942
3943<p>
3944Pops a table from the stack and
3945sets it as the new metatable for the value at the given
3946acceptable index.
3947
3948
3949
3950
3951
3952<hr><h3><a name="lua_settable"><code>lua_settable</code></a></h3><p>
3953<span class="apii">[-2, +0, <em>e</em>]</span>
3954<pre>void lua_settable (lua_State *L, int index);</pre>
3955
3956<p>
3957Does the equivalent to <code>t[k] = v</code>,
3958where <code>t</code> is the value at the given valid index,
3959<code>v</code> is the value at the top of the stack,
3960and <code>k</code> is the value just below the top.
3961
3962
3963<p>
3964This function pops both the key and the value from the stack.
3965As in Lua, this function may trigger a metamethod
3966for the "newindex" event (see <a href="#2.8">&sect;2.8</a>).
3967
3968
3969
3970
3971
3972<hr><h3><a name="lua_settop"><code>lua_settop</code></a></h3><p>
3973<span class="apii">[-?, +?, <em>-</em>]</span>
3974<pre>void lua_settop (lua_State *L, int index);</pre>
3975
3976<p>
3977Accepts any acceptable index, or&nbsp;0,
3978and sets the stack top to this index.
3979If the new top is larger than the old one,
3980then the new elements are filled with <b>nil</b>.
3981If <code>index</code> is&nbsp;0, then all stack elements are removed.
3982
3983
3984
3985
3986
3987<hr><h3><a name="lua_State"><code>lua_State</code></a></h3>
3988<pre>typedef struct lua_State lua_State;</pre>
3989
3990<p>
3991Opaque structure that keeps the whole state of a Lua interpreter.
3992The Lua library is fully reentrant:
3993it has no global variables.
3994All information about a state is kept in this structure.
3995
3996
3997<p>
3998A pointer to this state must be passed as the first argument to
3999every function in the library, except to <a href="#lua_newstate"><code>lua_newstate</code></a>,
4000which creates a Lua state from scratch.
4001
4002
4003
4004
4005
4006<hr><h3><a name="lua_status"><code>lua_status</code></a></h3><p>
4007<span class="apii">[-0, +0, <em>-</em>]</span>
4008<pre>int lua_status (lua_State *L);</pre>
4009
4010<p>
4011Returns the status of the thread <code>L</code>.
4012
4013
4014<p>
4015The status can be 0 for a normal thread,
4016an error code if the thread finished its execution with an error,
4017or <a name="pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the thread is suspended.
4018
4019
4020
4021
4022
4023<hr><h3><a name="lua_toboolean"><code>lua_toboolean</code></a></h3><p>
4024<span class="apii">[-0, +0, <em>-</em>]</span>
4025<pre>int lua_toboolean (lua_State *L, int index);</pre>
4026
4027<p>
4028Converts the Lua value at the given acceptable index to a C&nbsp;boolean
4029value (0&nbsp;or&nbsp;1).
4030Like all tests in Lua,
4031<a href="#lua_toboolean"><code>lua_toboolean</code></a> returns 1 for any Lua value
4032different from <b>false</b> and <b>nil</b>;
4033otherwise it returns 0.
4034It also returns 0 when called with a non-valid index.
4035(If you want to accept only actual boolean values,
4036use <a href="#lua_isboolean"><code>lua_isboolean</code></a> to test the value's type.)
4037
4038
4039
4040
4041
4042<hr><h3><a name="lua_tocfunction"><code>lua_tocfunction</code></a></h3><p>
4043<span class="apii">[-0, +0, <em>-</em>]</span>
4044<pre>lua_CFunction lua_tocfunction (lua_State *L, int index);</pre>
4045
4046<p>
4047Converts a value at the given acceptable index to a C&nbsp;function.
4048That value must be a C&nbsp;function;
4049otherwise, returns <code>NULL</code>.
4050
4051
4052
4053
4054
4055<hr><h3><a name="lua_tointeger"><code>lua_tointeger</code></a></h3><p>
4056<span class="apii">[-0, +0, <em>-</em>]</span>
4057<pre>lua_Integer lua_tointeger (lua_State *L, int index);</pre>
4058
4059<p>
4060Converts the Lua value at the given acceptable index
4061to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>.
4062The Lua value must be a number or a string convertible to a number
4063(see <a href="#2.2.1">&sect;2.2.1</a>);
4064otherwise, <a href="#lua_tointeger"><code>lua_tointeger</code></a> returns&nbsp;0.
4065
4066
4067<p>
4068If the number is not an integer,
4069it is truncated in some non-specified way.
4070
4071
4072
4073
4074
4075<hr><h3><a name="lua_tolstring"><code>lua_tolstring</code></a></h3><p>
4076<span class="apii">[-0, +0, <em>m</em>]</span>
4077<pre>const char *lua_tolstring (lua_State *L, int index, size_t *len);</pre>
4078
4079<p>
4080Converts the Lua value at the given acceptable index to a C&nbsp;string.
4081If <code>len</code> is not <code>NULL</code>,
4082it also sets <code>*len</code> with the string length.
4083The Lua value must be a string or a number;
4084otherwise, the function returns <code>NULL</code>.
4085If the value is a number,
4086then <a href="#lua_tolstring"><code>lua_tolstring</code></a> also
4087<em>changes the actual value in the stack to a string</em>.
4088(This change confuses <a href="#lua_next"><code>lua_next</code></a>
4089when <a href="#lua_tolstring"><code>lua_tolstring</code></a> is applied to keys during a table traversal.)
4090
4091
4092<p>
4093<a href="#lua_tolstring"><code>lua_tolstring</code></a> returns a fully aligned pointer
4094to a string inside the Lua state.
4095This string always has a zero ('<code>\0</code>')
4096after its last character (as in&nbsp;C),
4097but can contain other zeros in its body.
4098Because Lua has garbage collection,
4099there is no guarantee that the pointer returned by <a href="#lua_tolstring"><code>lua_tolstring</code></a>
4100will be valid after the corresponding value is removed from the stack.
4101
4102
4103
4104
4105
4106<hr><h3><a name="lua_tonumber"><code>lua_tonumber</code></a></h3><p>
4107<span class="apii">[-0, +0, <em>-</em>]</span>
4108<pre>lua_Number lua_tonumber (lua_State *L, int index);</pre>
4109
4110<p>
4111Converts the Lua value at the given acceptable index
4112to the C&nbsp;type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>).
4113The Lua value must be a number or a string convertible to a number
4114(see <a href="#2.2.1">&sect;2.2.1</a>);
4115otherwise, <a href="#lua_tonumber"><code>lua_tonumber</code></a> returns&nbsp;0.
4116
4117
4118
4119
4120
4121<hr><h3><a name="lua_topointer"><code>lua_topointer</code></a></h3><p>
4122<span class="apii">[-0, +0, <em>-</em>]</span>
4123<pre>const void *lua_topointer (lua_State *L, int index);</pre>
4124
4125<p>
4126Converts the value at the given acceptable index to a generic
4127C&nbsp;pointer (<code>void*</code>).
4128The value can be a userdata, a table, a thread, or a function;
4129otherwise, <a href="#lua_topointer"><code>lua_topointer</code></a> returns <code>NULL</code>.
4130Different objects will give different pointers.
4131There is no way to convert the pointer back to its original value.
4132
4133
4134<p>
4135Typically this function is used only for debug information.
4136
4137
4138
4139
4140
4141<hr><h3><a name="lua_tostring"><code>lua_tostring</code></a></h3><p>
4142<span class="apii">[-0, +0, <em>m</em>]</span>
4143<pre>const char *lua_tostring (lua_State *L, int index);</pre>
4144
4145<p>
4146Equivalent to <a href="#lua_tolstring"><code>lua_tolstring</code></a> with <code>len</code> equal to <code>NULL</code>.
4147
4148
4149
4150
4151
4152<hr><h3><a name="lua_tothread"><code>lua_tothread</code></a></h3><p>
4153<span class="apii">[-0, +0, <em>-</em>]</span>
4154<pre>lua_State *lua_tothread (lua_State *L, int index);</pre>
4155
4156<p>
4157Converts the value at the given acceptable index to a Lua thread
4158(represented as <code>lua_State*</code>).
4159This value must be a thread;
4160otherwise, the function returns <code>NULL</code>.
4161
4162
4163
4164
4165
4166<hr><h3><a name="lua_touserdata"><code>lua_touserdata</code></a></h3><p>
4167<span class="apii">[-0, +0, <em>-</em>]</span>
4168<pre>void *lua_touserdata (lua_State *L, int index);</pre>
4169
4170<p>
4171If the value at the given acceptable index is a full userdata,
4172returns its block address.
4173If the value is a light userdata,
4174returns its pointer.
4175Otherwise, returns <code>NULL</code>.
4176
4177
4178
4179
4180
4181<hr><h3><a name="lua_type"><code>lua_type</code></a></h3><p>
4182<span class="apii">[-0, +0, <em>-</em>]</span>
4183<pre>int lua_type (lua_State *L, int index);</pre>
4184
4185<p>
4186Returns the type of the value in the given acceptable index,
4187or <code>LUA_TNONE</code> for a non-valid index
4188(that is, an index to an "empty" stack position).
4189The types returned by <a href="#lua_type"><code>lua_type</code></a> are coded by the following constants
4190defined in <code>lua.h</code>:
4191<code>LUA_TNIL</code>,
4192<code>LUA_TNUMBER</code>,
4193<code>LUA_TBOOLEAN</code>,
4194<code>LUA_TSTRING</code>,
4195<code>LUA_TTABLE</code>,
4196<code>LUA_TFUNCTION</code>,
4197<code>LUA_TUSERDATA</code>,
4198<code>LUA_TTHREAD</code>,
4199and
4200<code>LUA_TLIGHTUSERDATA</code>.
4201
4202
4203
4204
4205
4206<hr><h3><a name="lua_typename"><code>lua_typename</code></a></h3><p>
4207<span class="apii">[-0, +0, <em>-</em>]</span>
4208<pre>const char *lua_typename (lua_State *L, int tp);</pre>
4209
4210<p>
4211Returns the name of the type encoded by the value <code>tp</code>,
4212which must be one the values returned by <a href="#lua_type"><code>lua_type</code></a>.
4213
4214
4215
4216
4217
4218<hr><h3><a name="lua_Writer"><code>lua_Writer</code></a></h3>
4219<pre>typedef int (*lua_Writer) (lua_State *L,
4220 const void* p,
4221 size_t sz,
4222 void* ud);</pre>
4223
4224<p>
4225The type of the writer function used by <a href="#lua_dump"><code>lua_dump</code></a>.
4226Every time it produces another piece of chunk,
4227<a href="#lua_dump"><code>lua_dump</code></a> calls the writer,
4228passing along the buffer to be written (<code>p</code>),
4229its size (<code>sz</code>),
4230and the <code>data</code> parameter supplied to <a href="#lua_dump"><code>lua_dump</code></a>.
4231
4232
4233<p>
4234The writer returns an error code:
42350&nbsp;means no errors;
4236any other value means an error and stops <a href="#lua_dump"><code>lua_dump</code></a> from
4237calling the writer again.
4238
4239
4240
4241
4242
4243<hr><h3><a name="lua_xmove"><code>lua_xmove</code></a></h3><p>
4244<span class="apii">[-?, +?, <em>-</em>]</span>
4245<pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre>
4246
4247<p>
4248Exchange values between different threads of the <em>same</em> global state.
4249
4250
4251<p>
4252This function pops <code>n</code> values from the stack <code>from</code>,
4253and pushes them onto the stack <code>to</code>.
4254
4255
4256
4257
4258
4259<hr><h3><a name="lua_yield"><code>lua_yield</code></a></h3><p>
4260<span class="apii">[-?, +?, <em>-</em>]</span>
4261<pre>int lua_yield (lua_State *L, int nresults);</pre>
4262
4263<p>
4264Yields a coroutine.
4265
4266
4267<p>
4268This function should only be called as the
4269return expression of a C&nbsp;function, as follows:
4270
4271<pre>
4272 return lua_yield (L, nresults);
4273</pre><p>
4274When a C&nbsp;function calls <a href="#lua_yield"><code>lua_yield</code></a> in that way,
4275the running coroutine suspends its execution,
4276and the call to <a href="#lua_resume"><code>lua_resume</code></a> that started this coroutine returns.
4277The parameter <code>nresults</code> is the number of values from the stack
4278that are passed as results to <a href="#lua_resume"><code>lua_resume</code></a>.
4279
4280
4281
4282
4283
4284
4285
4286<h2>3.8 - <a name="3.8">The Debug Interface</a></h2>
4287
4288<p>
4289Lua has no built-in debugging facilities.
4290Instead, it offers a special interface
4291by means of functions and <em>hooks</em>.
4292This interface allows the construction of different
4293kinds of debuggers, profilers, and other tools
4294that need "inside information" from the interpreter.
4295
4296
4297
4298<hr><h3><a name="lua_Debug"><code>lua_Debug</code></a></h3>
4299<pre>typedef struct lua_Debug {
4300 int event;
4301 const char *name; /* (n) */
4302 const char *namewhat; /* (n) */
4303 const char *what; /* (S) */
4304 const char *source; /* (S) */
4305 int currentline; /* (l) */
4306 int nups; /* (u) number of upvalues */
4307 int linedefined; /* (S) */
4308 int lastlinedefined; /* (S) */
4309 char short_src[LUA_IDSIZE]; /* (S) */
4310 /* private part */
4311 <em>other fields</em>
4312} lua_Debug;</pre>
4313
4314<p>
4315A structure used to carry different pieces of
4316information about an active function.
4317<a href="#lua_getstack"><code>lua_getstack</code></a> fills only the private part
4318of this structure, for later use.
4319To fill the other fields of <a href="#lua_Debug"><code>lua_Debug</code></a> with useful information,
4320call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
4321
4322
4323<p>
4324The fields of <a href="#lua_Debug"><code>lua_Debug</code></a> have the following meaning:
4325
4326<ul>
4327
4328<li><b><code>source</code>:</b>
4329If the function was defined in a string,
4330then <code>source</code> is that string.
4331If the function was defined in a file,
4332then <code>source</code> starts with a '<code>@</code>' followed by the file name.
4333</li>
4334
4335<li><b><code>short_src</code>:</b>
4336a "printable" version of <code>source</code>, to be used in error messages.
4337</li>
4338
4339<li><b><code>linedefined</code>:</b>
4340the line number where the definition of the function starts.
4341</li>
4342
4343<li><b><code>lastlinedefined</code>:</b>
4344the line number where the definition of the function ends.
4345</li>
4346
4347<li><b><code>what</code>:</b>
4348the string <code>"Lua"</code> if the function is a Lua function,
4349<code>"C"</code> if it is a C&nbsp;function,
4350<code>"main"</code> if it is the main part of a chunk,
4351and <code>"tail"</code> if it was a function that did a tail call.
4352In the latter case,
4353Lua has no other information about the function.
4354</li>
4355
4356<li><b><code>currentline</code>:</b>
4357the current line where the given function is executing.
4358When no line information is available,
4359<code>currentline</code> is set to -1.
4360</li>
4361
4362<li><b><code>name</code>:</b>
4363a reasonable name for the given function.
4364Because functions in Lua are first-class values,
4365they do not have a fixed name:
4366some functions can be the value of multiple global variables,
4367while others can be stored only in a table field.
4368The <code>lua_getinfo</code> function checks how the function was
4369called to find a suitable name.
4370If it cannot find a name,
4371then <code>name</code> is set to <code>NULL</code>.
4372</li>
4373
4374<li><b><code>namewhat</code>:</b>
4375explains the <code>name</code> field.
4376The value of <code>namewhat</code> can be
4377<code>"global"</code>, <code>"local"</code>, <code>"method"</code>,
4378<code>"field"</code>, <code>"upvalue"</code>, or <code>""</code> (the empty string),
4379according to how the function was called.
4380(Lua uses the empty string when no other option seems to apply.)
4381</li>
4382
4383<li><b><code>nups</code>:</b>
4384the number of upvalues of the function.
4385</li>
4386
4387</ul>
4388
4389
4390
4391
4392<hr><h3><a name="lua_gethook"><code>lua_gethook</code></a></h3><p>
4393<span class="apii">[-0, +0, <em>-</em>]</span>
4394<pre>lua_Hook lua_gethook (lua_State *L);</pre>
4395
4396<p>
4397Returns the current hook function.
4398
4399
4400
4401
4402
4403<hr><h3><a name="lua_gethookcount"><code>lua_gethookcount</code></a></h3><p>
4404<span class="apii">[-0, +0, <em>-</em>]</span>
4405<pre>int lua_gethookcount (lua_State *L);</pre>
4406
4407<p>
4408Returns the current hook count.
4409
4410
4411
4412
4413
4414<hr><h3><a name="lua_gethookmask"><code>lua_gethookmask</code></a></h3><p>
4415<span class="apii">[-0, +0, <em>-</em>]</span>
4416<pre>int lua_gethookmask (lua_State *L);</pre>
4417
4418<p>
4419Returns the current hook mask.
4420
4421
4422
4423
4424
4425<hr><h3><a name="lua_getinfo"><code>lua_getinfo</code></a></h3><p>
4426<span class="apii">[-(0|1), +(0|1|2), <em>m</em>]</span>
4427<pre>int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);</pre>
4428
4429<p>
4430Returns information about a specific function or function invocation.
4431
4432
4433<p>
4434To get information about a function invocation,
4435the parameter <code>ar</code> must be a valid activation record that was
4436filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or
4437given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>).
4438
4439
4440<p>
4441To get information about a function you push it onto the stack
4442and start the <code>what</code> string with the character '<code>&gt;</code>'.
4443(In that case,
4444<code>lua_getinfo</code> pops the function in the top of the stack.)
4445For instance, to know in which line a function <code>f</code> was defined,
4446you can write the following code:
4447
4448<pre>
4449 lua_Debug ar;
4450 lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global 'f' */
4451 lua_getinfo(L, "&gt;S", &amp;ar);
4452 printf("%d\n", ar.linedefined);
4453</pre>
4454
4455<p>
4456Each character in the string <code>what</code>
4457selects some fields of the structure <code>ar</code> to be filled or
4458a value to be pushed on the stack:
4459
4460<ul>
4461
4462<li><b>'<code>n</code>':</b> fills in the field <code>name</code> and <code>namewhat</code>;
4463</li>
4464
4465<li><b>'<code>S</code>':</b>
4466fills in the fields <code>source</code>, <code>short_src</code>,
4467<code>linedefined</code>, <code>lastlinedefined</code>, and <code>what</code>;
4468</li>
4469
4470<li><b>'<code>l</code>':</b> fills in the field <code>currentline</code>;
4471</li>
4472
4473<li><b>'<code>u</code>':</b> fills in the field <code>nups</code>;
4474</li>
4475
4476<li><b>'<code>f</code>':</b>
4477pushes onto the stack the function that is
4478running at the given level;
4479</li>
4480
4481<li><b>'<code>L</code>':</b>
4482pushes onto the stack a table whose indices are the
4483numbers of the lines that are valid on the function.
4484(A <em>valid line</em> is a line with some associated code,
4485that is, a line where you can put a break point.
4486Non-valid lines include empty lines and comments.)
4487</li>
4488
4489</ul>
4490
4491<p>
4492This function returns 0 on error
4493(for instance, an invalid option in <code>what</code>).
4494
4495
4496
4497
4498
4499<hr><h3><a name="lua_getlocal"><code>lua_getlocal</code></a></h3><p>
4500<span class="apii">[-0, +(0|1), <em>-</em>]</span>
4501<pre>const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);</pre>
4502
4503<p>
4504Gets information about a local variable of a given activation record.
4505The parameter <code>ar</code> must be a valid activation record that was
4506filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or
4507given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>).
4508The index <code>n</code> selects which local variable to inspect
4509(1 is the first parameter or active local variable, and so on,
4510until the last active local variable).
4511<a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack
4512and returns its name.
4513
4514
4515<p>
4516Variable names starting with '<code>(</code>' (open parentheses)
4517represent internal variables
4518(loop control variables, temporaries, and C&nbsp;function locals).
4519
4520
4521<p>
4522Returns <code>NULL</code> (and pushes nothing)
4523when the index is greater than
4524the number of active local variables.
4525
4526
4527
4528
4529
4530<hr><h3><a name="lua_getstack"><code>lua_getstack</code></a></h3><p>
4531<span class="apii">[-0, +0, <em>-</em>]</span>
4532<pre>int lua_getstack (lua_State *L, int level, lua_Debug *ar);</pre>
4533
4534<p>
4535Get information about the interpreter runtime stack.
4536
4537
4538<p>
4539This function fills parts of a <a href="#lua_Debug"><code>lua_Debug</code></a> structure with
4540an identification of the <em>activation record</em>
4541of the function executing at a given level.
4542Level&nbsp;0 is the current running function,
4543whereas level <em>n+1</em> is the function that has called level <em>n</em>.
4544When there are no errors, <a href="#lua_getstack"><code>lua_getstack</code></a> returns 1;
4545when called with a level greater than the stack depth,
4546it returns 0.
4547
4548
4549
4550
4551
4552<hr><h3><a name="lua_getupvalue"><code>lua_getupvalue</code></a></h3><p>
4553<span class="apii">[-0, +(0|1), <em>-</em>]</span>
4554<pre>const char *lua_getupvalue (lua_State *L, int funcindex, int n);</pre>
4555
4556<p>
4557Gets information about a closure's upvalue.
4558(For Lua functions,
4559upvalues are the external local variables that the function uses,
4560and that are consequently included in its closure.)
4561<a href="#lua_getupvalue"><code>lua_getupvalue</code></a> gets the index <code>n</code> of an upvalue,
4562pushes the upvalue's value onto the stack,
4563and returns its name.
4564<code>funcindex</code> points to the closure in the stack.
4565(Upvalues have no particular order,
4566as they are active through the whole function.
4567So, they are numbered in an arbitrary order.)
4568
4569
4570<p>
4571Returns <code>NULL</code> (and pushes nothing)
4572when the index is greater than the number of upvalues.
4573For C&nbsp;functions, this function uses the empty string <code>""</code>
4574as a name for all upvalues.
4575
4576
4577
4578
4579
4580<hr><h3><a name="lua_Hook"><code>lua_Hook</code></a></h3>
4581<pre>typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);</pre>
4582
4583<p>
4584Type for debugging hook functions.
4585
4586
4587<p>
4588Whenever a hook is called, its <code>ar</code> argument has its field
4589<code>event</code> set to the specific event that triggered the hook.
4590Lua identifies these events with the following constants:
4591<a name="pdf-LUA_HOOKCALL"><code>LUA_HOOKCALL</code></a>, <a name="pdf-LUA_HOOKRET"><code>LUA_HOOKRET</code></a>,
4592<a name="pdf-LUA_HOOKTAILRET"><code>LUA_HOOKTAILRET</code></a>, <a name="pdf-LUA_HOOKLINE"><code>LUA_HOOKLINE</code></a>,
4593and <a name="pdf-LUA_HOOKCOUNT"><code>LUA_HOOKCOUNT</code></a>.
4594Moreover, for line events, the field <code>currentline</code> is also set.
4595To get the value of any other field in <code>ar</code>,
4596the hook must call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
4597For return events, <code>event</code> can be <code>LUA_HOOKRET</code>,
4598the normal value, or <code>LUA_HOOKTAILRET</code>.
4599In the latter case, Lua is simulating a return from
4600a function that did a tail call;
4601in this case, it is useless to call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
4602
4603
4604<p>
4605While Lua is running a hook, it disables other calls to hooks.
4606Therefore, if a hook calls back Lua to execute a function or a chunk,
4607this execution occurs without any calls to hooks.
4608
4609
4610
4611
4612
4613<hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p>
4614<span class="apii">[-0, +0, <em>-</em>]</span>
4615<pre>int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre>
4616
4617<p>
4618Sets the debugging hook function.
4619
4620
4621<p>
4622Argument <code>f</code> is the hook function.
4623<code>mask</code> specifies on which events the hook will be called:
4624it is formed by a bitwise or of the constants
4625<a name="pdf-LUA_MASKCALL"><code>LUA_MASKCALL</code></a>,
4626<a name="pdf-LUA_MASKRET"><code>LUA_MASKRET</code></a>,
4627<a name="pdf-LUA_MASKLINE"><code>LUA_MASKLINE</code></a>,
4628and <a name="pdf-LUA_MASKCOUNT"><code>LUA_MASKCOUNT</code></a>.
4629The <code>count</code> argument is only meaningful when the mask
4630includes <code>LUA_MASKCOUNT</code>.
4631For each event, the hook is called as explained below:
4632
4633<ul>
4634
4635<li><b>The call hook:</b> is called when the interpreter calls a function.
4636The hook is called just after Lua enters the new function,
4637before the function gets its arguments.
4638</li>
4639
4640<li><b>The return hook:</b> is called when the interpreter returns from a function.
4641The hook is called just before Lua leaves the function.
4642You have no access to the values to be returned by the function.
4643</li>
4644
4645<li><b>The line hook:</b> is called when the interpreter is about to
4646start the execution of a new line of code,
4647or when it jumps back in the code (even to the same line).
4648(This event only happens while Lua is executing a Lua function.)
4649</li>
4650
4651<li><b>The count hook:</b> is called after the interpreter executes every
4652<code>count</code> instructions.
4653(This event only happens while Lua is executing a Lua function.)
4654</li>
4655
4656</ul>
4657
4658<p>
4659A hook is disabled by setting <code>mask</code> to zero.
4660
4661
4662
4663
4664
4665<hr><h3><a name="lua_setlocal"><code>lua_setlocal</code></a></h3><p>
4666<span class="apii">[-(0|1), +0, <em>-</em>]</span>
4667<pre>const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);</pre>
4668
4669<p>
4670Sets the value of a local variable of a given activation record.
4671Parameters <code>ar</code> and <code>n</code> are as in <a href="#lua_getlocal"><code>lua_getlocal</code></a>
4672(see <a href="#lua_getlocal"><code>lua_getlocal</code></a>).
4673<a href="#lua_setlocal"><code>lua_setlocal</code></a> assigns the value at the top of the stack
4674to the variable and returns its name.
4675It also pops the value from the stack.
4676
4677
4678<p>
4679Returns <code>NULL</code> (and pops nothing)
4680when the index is greater than
4681the number of active local variables.
4682
4683
4684
4685
4686
4687<hr><h3><a name="lua_setupvalue"><code>lua_setupvalue</code></a></h3><p>
4688<span class="apii">[-(0|1), +0, <em>-</em>]</span>
4689<pre>const char *lua_setupvalue (lua_State *L, int funcindex, int n);</pre>
4690
4691<p>
4692Sets the value of a closure's upvalue.
4693It assigns the value at the top of the stack
4694to the upvalue and returns its name.
4695It also pops the value from the stack.
4696Parameters <code>funcindex</code> and <code>n</code> are as in the <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>
4697(see <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>).
4698
4699
4700<p>
4701Returns <code>NULL</code> (and pops nothing)
4702when the index is greater than the number of upvalues.
4703
4704
4705
4706
4707
4708
4709
4710<h1>4 - <a name="4">The Auxiliary Library</a></h1>
4711
4712<p>
4713
4714The <em>auxiliary library</em> provides several convenient functions
4715to interface C with Lua.
4716While the basic API provides the primitive functions for all
4717interactions between C and Lua,
4718the auxiliary library provides higher-level functions for some
4719common tasks.
4720
4721
4722<p>
4723All functions from the auxiliary library
4724are defined in header file <code>lauxlib.h</code> and
4725have a prefix <code>luaL_</code>.
4726
4727
4728<p>
4729All functions in the auxiliary library are built on
4730top of the basic API,
4731and so they provide nothing that cannot be done with this API.
4732
4733
4734<p>
4735Several functions in the auxiliary library are used to
4736check C&nbsp;function arguments.
4737Their names are always <code>luaL_check*</code> or <code>luaL_opt*</code>.
4738All of these functions throw an error if the check is not satisfied.
4739Because the error message is formatted for arguments
4740(e.g., "<code>bad argument #1</code>"),
4741you should not use these functions for other stack values.
4742
4743
4744
4745<h2>4.1 - <a name="4.1">Functions and Types</a></h2>
4746
4747<p>
4748Here we list all functions and types from the auxiliary library
4749in alphabetical order.
4750
4751
4752
4753<hr><h3><a name="luaL_addchar"><code>luaL_addchar</code></a></h3><p>
4754<span class="apii">[-0, +0, <em>m</em>]</span>
4755<pre>void luaL_addchar (luaL_Buffer *B, char c);</pre>
4756
4757<p>
4758Adds the character <code>c</code> to the buffer <code>B</code>
4759(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
4760
4761
4762
4763
4764
4765<hr><h3><a name="luaL_addlstring"><code>luaL_addlstring</code></a></h3><p>
4766<span class="apii">[-0, +0, <em>m</em>]</span>
4767<pre>void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);</pre>
4768
4769<p>
4770Adds the string pointed to by <code>s</code> with length <code>l</code> to
4771the buffer <code>B</code>
4772(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
4773The string may contain embedded zeros.
4774
4775
4776
4777
4778
4779<hr><h3><a name="luaL_addsize"><code>luaL_addsize</code></a></h3><p>
4780<span class="apii">[-0, +0, <em>m</em>]</span>
4781<pre>void luaL_addsize (luaL_Buffer *B, size_t n);</pre>
4782
4783<p>
4784Adds to the buffer <code>B</code> (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>)
4785a string of length <code>n</code> previously copied to the
4786buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>).
4787
4788
4789
4790
4791
4792<hr><h3><a name="luaL_addstring"><code>luaL_addstring</code></a></h3><p>
4793<span class="apii">[-0, +0, <em>m</em>]</span>
4794<pre>void luaL_addstring (luaL_Buffer *B, const char *s);</pre>
4795
4796<p>
4797Adds the zero-terminated string pointed to by <code>s</code>
4798to the buffer <code>B</code>
4799(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
4800The string may not contain embedded zeros.
4801
4802
4803
4804
4805
4806<hr><h3><a name="luaL_addvalue"><code>luaL_addvalue</code></a></h3><p>
4807<span class="apii">[-1, +0, <em>m</em>]</span>
4808<pre>void luaL_addvalue (luaL_Buffer *B);</pre>
4809
4810<p>
4811Adds the value at the top of the stack
4812to the buffer <code>B</code>
4813(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
4814Pops the value.
4815
4816
4817<p>
4818This is the only function on string buffers that can (and must)
4819be called with an extra element on the stack,
4820which is the value to be added to the buffer.
4821
4822
4823
4824
4825
4826<hr><h3><a name="luaL_argcheck"><code>luaL_argcheck</code></a></h3><p>
4827<span class="apii">[-0, +0, <em>v</em>]</span>
4828<pre>void luaL_argcheck (lua_State *L,
4829 int cond,
4830 int narg,
4831 const char *extramsg);</pre>
4832
4833<p>
4834Checks whether <code>cond</code> is true.
4835If not, raises an error with the following message,
4836where <code>func</code> is retrieved from the call stack:
4837
4838<pre>
4839 bad argument #&lt;narg&gt; to &lt;func&gt; (&lt;extramsg&gt;)
4840</pre>
4841
4842
4843
4844
4845<hr><h3><a name="luaL_argerror"><code>luaL_argerror</code></a></h3><p>
4846<span class="apii">[-0, +0, <em>v</em>]</span>
4847<pre>int luaL_argerror (lua_State *L, int narg, const char *extramsg);</pre>
4848
4849<p>
4850Raises an error with the following message,
4851where <code>func</code> is retrieved from the call stack:
4852
4853<pre>
4854 bad argument #&lt;narg&gt; to &lt;func&gt; (&lt;extramsg&gt;)
4855</pre>
4856
4857<p>
4858This function never returns,
4859but it is an idiom to use it in C&nbsp;functions
4860as <code>return luaL_argerror(<em>args</em>)</code>.
4861
4862
4863
4864
4865
4866<hr><h3><a name="luaL_Buffer"><code>luaL_Buffer</code></a></h3>
4867<pre>typedef struct luaL_Buffer luaL_Buffer;</pre>
4868
4869<p>
4870Type for a <em>string buffer</em>.
4871
4872
4873<p>
4874A string buffer allows C&nbsp;code to build Lua strings piecemeal.
4875Its pattern of use is as follows:
4876
4877<ul>
4878
4879<li>First you declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
4880
4881<li>Then you initialize it with a call <code>luaL_buffinit(L, &amp;b)</code>.</li>
4882
4883<li>
4884Then you add string pieces to the buffer calling any of
4885the <code>luaL_add*</code> functions.
4886</li>
4887
4888<li>
4889You finish by calling <code>luaL_pushresult(&amp;b)</code>.
4890This call leaves the final string on the top of the stack.
4891</li>
4892
4893</ul>
4894
4895<p>
4896During its normal operation,
4897a string buffer uses a variable number of stack slots.
4898So, while using a buffer, you cannot assume that you know where
4899the top of the stack is.
4900You can use the stack between successive calls to buffer operations
4901as long as that use is balanced;
4902that is,
4903when you call a buffer operation,
4904the stack is at the same level
4905it was immediately after the previous buffer operation.
4906(The only exception to this rule is <a href="#luaL_addvalue"><code>luaL_addvalue</code></a>.)
4907After calling <a href="#luaL_pushresult"><code>luaL_pushresult</code></a> the stack is back to its
4908level when the buffer was initialized,
4909plus the final string on its top.
4910
4911
4912
4913
4914
4915<hr><h3><a name="luaL_buffinit"><code>luaL_buffinit</code></a></h3><p>
4916<span class="apii">[-0, +0, <em>-</em>]</span>
4917<pre>void luaL_buffinit (lua_State *L, luaL_Buffer *B);</pre>
4918
4919<p>
4920Initializes a buffer <code>B</code>.
4921This function does not allocate any space;
4922the buffer must be declared as a variable
4923(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
4924
4925
4926
4927
4928
4929<hr><h3><a name="luaL_callmeta"><code>luaL_callmeta</code></a></h3><p>
4930<span class="apii">[-0, +(0|1), <em>e</em>]</span>
4931<pre>int luaL_callmeta (lua_State *L, int obj, const char *e);</pre>
4932
4933<p>
4934Calls a metamethod.
4935
4936
4937<p>
4938If the object at index <code>obj</code> has a metatable and this
4939metatable has a field <code>e</code>,
4940this function calls this field and passes the object as its only argument.
4941In this case this function returns 1 and pushes onto the
4942stack the value returned by the call.
4943If there is no metatable or no metamethod,
4944this function returns 0 (without pushing any value on the stack).
4945
4946
4947
4948
4949
4950<hr><h3><a name="luaL_checkany"><code>luaL_checkany</code></a></h3><p>
4951<span class="apii">[-0, +0, <em>v</em>]</span>
4952<pre>void luaL_checkany (lua_State *L, int narg);</pre>
4953
4954<p>
4955Checks whether the function has an argument
4956of any type (including <b>nil</b>) at position <code>narg</code>.
4957
4958
4959
4960
4961
4962<hr><h3><a name="luaL_checkint"><code>luaL_checkint</code></a></h3><p>
4963<span class="apii">[-0, +0, <em>v</em>]</span>
4964<pre>int luaL_checkint (lua_State *L, int narg);</pre>
4965
4966<p>
4967Checks whether the function argument <code>narg</code> is a number
4968and returns this number cast to an <code>int</code>.
4969
4970
4971
4972
4973
4974<hr><h3><a name="luaL_checkinteger"><code>luaL_checkinteger</code></a></h3><p>
4975<span class="apii">[-0, +0, <em>v</em>]</span>
4976<pre>lua_Integer luaL_checkinteger (lua_State *L, int narg);</pre>
4977
4978<p>
4979Checks whether the function argument <code>narg</code> is a number
4980and returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>.
4981
4982
4983
4984
4985
4986<hr><h3><a name="luaL_checklong"><code>luaL_checklong</code></a></h3><p>
4987<span class="apii">[-0, +0, <em>v</em>]</span>
4988<pre>long luaL_checklong (lua_State *L, int narg);</pre>
4989
4990<p>
4991Checks whether the function argument <code>narg</code> is a number
4992and returns this number cast to a <code>long</code>.
4993
4994
4995
4996
4997
4998<hr><h3><a name="luaL_checklstring"><code>luaL_checklstring</code></a></h3><p>
4999<span class="apii">[-0, +0, <em>v</em>]</span>
5000<pre>const char *luaL_checklstring (lua_State *L, int narg, size_t *l);</pre>
5001
5002<p>
5003Checks whether the function argument <code>narg</code> is a string
5004and returns this string;
5005if <code>l</code> is not <code>NULL</code> fills <code>*l</code>
5006with the string's length.
5007
5008
5009<p>
5010This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
5011so all conversions and caveats of that function apply here.
5012
5013
5014
5015
5016
5017<hr><h3><a name="luaL_checknumber"><code>luaL_checknumber</code></a></h3><p>
5018<span class="apii">[-0, +0, <em>v</em>]</span>
5019<pre>lua_Number luaL_checknumber (lua_State *L, int narg);</pre>
5020
5021<p>
5022Checks whether the function argument <code>narg</code> is a number
5023and returns this number.
5024
5025
5026
5027
5028
5029<hr><h3><a name="luaL_checkoption"><code>luaL_checkoption</code></a></h3><p>
5030<span class="apii">[-0, +0, <em>v</em>]</span>
5031<pre>int luaL_checkoption (lua_State *L,
5032 int narg,
5033 const char *def,
5034 const char *const lst[]);</pre>
5035
5036<p>
5037Checks whether the function argument <code>narg</code> is a string and
5038searches for this string in the array <code>lst</code>
5039(which must be NULL-terminated).
5040Returns the index in the array where the string was found.
5041Raises an error if the argument is not a string or
5042if the string cannot be found.
5043
5044
5045<p>
5046If <code>def</code> is not <code>NULL</code>,
5047the function uses <code>def</code> as a default value when
5048there is no argument <code>narg</code> or if this argument is <b>nil</b>.
5049
5050
5051<p>
5052This is a useful function for mapping strings to C&nbsp;enums.
5053(The usual convention in Lua libraries is
5054to use strings instead of numbers to select options.)
5055
5056
5057
5058
5059
5060<hr><h3><a name="luaL_checkstack"><code>luaL_checkstack</code></a></h3><p>
5061<span class="apii">[-0, +0, <em>v</em>]</span>
5062<pre>void luaL_checkstack (lua_State *L, int sz, const char *msg);</pre>
5063
5064<p>
5065Grows the stack size to <code>top + sz</code> elements,
5066raising an error if the stack cannot grow to that size.
5067<code>msg</code> is an additional text to go into the error message.
5068
5069
5070
5071
5072
5073<hr><h3><a name="luaL_checkstring"><code>luaL_checkstring</code></a></h3><p>
5074<span class="apii">[-0, +0, <em>v</em>]</span>
5075<pre>const char *luaL_checkstring (lua_State *L, int narg);</pre>
5076
5077<p>
5078Checks whether the function argument <code>narg</code> is a string
5079and returns this string.
5080
5081
5082<p>
5083This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
5084so all conversions and caveats of that function apply here.
5085
5086
5087
5088
5089
5090<hr><h3><a name="luaL_checktype"><code>luaL_checktype</code></a></h3><p>
5091<span class="apii">[-0, +0, <em>v</em>]</span>
5092<pre>void luaL_checktype (lua_State *L, int narg, int t);</pre>
5093
5094<p>
5095Checks whether the function argument <code>narg</code> has type <code>t</code>.
5096See <a href="#lua_type"><code>lua_type</code></a> for the encoding of types for <code>t</code>.
5097
5098
5099
5100
5101
5102<hr><h3><a name="luaL_checkudata"><code>luaL_checkudata</code></a></h3><p>
5103<span class="apii">[-0, +0, <em>v</em>]</span>
5104<pre>void *luaL_checkudata (lua_State *L, int narg, const char *tname);</pre>
5105
5106<p>
5107Checks whether the function argument <code>narg</code> is a userdata
5108of the type <code>tname</code> (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
5109
5110
5111
5112
5113
5114<hr><h3><a name="luaL_dofile"><code>luaL_dofile</code></a></h3><p>
5115<span class="apii">[-0, +?, <em>m</em>]</span>
5116<pre>int luaL_dofile (lua_State *L, const char *filename);</pre>
5117
5118<p>
5119Loads and runs the given file.
5120It is defined as the following macro:
5121
5122<pre>
5123 (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
5124</pre><p>
5125It returns 0 if there are no errors
5126or 1 in case of errors.
5127
5128
5129
5130
5131
5132<hr><h3><a name="luaL_dostring"><code>luaL_dostring</code></a></h3><p>
5133<span class="apii">[-0, +?, <em>m</em>]</span>
5134<pre>int luaL_dostring (lua_State *L, const char *str);</pre>
5135
5136<p>
5137Loads and runs the given string.
5138It is defined as the following macro:
5139
5140<pre>
5141 (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
5142</pre><p>
5143It returns 0 if there are no errors
5144or 1 in case of errors.
5145
5146
5147
5148
5149
5150<hr><h3><a name="luaL_error"><code>luaL_error</code></a></h3><p>
5151<span class="apii">[-0, +0, <em>v</em>]</span>
5152<pre>int luaL_error (lua_State *L, const char *fmt, ...);</pre>
5153
5154<p>
5155Raises an error.
5156The error message format is given by <code>fmt</code>
5157plus any extra arguments,
5158following the same rules of <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>.
5159It also adds at the beginning of the message the file name and
5160the line number where the error occurred,
5161if this information is available.
5162
5163
5164<p>
5165This function never returns,
5166but it is an idiom to use it in C&nbsp;functions
5167as <code>return luaL_error(<em>args</em>)</code>.
5168
5169
5170
5171
5172
5173<hr><h3><a name="luaL_getmetafield"><code>luaL_getmetafield</code></a></h3><p>
5174<span class="apii">[-0, +(0|1), <em>m</em>]</span>
5175<pre>int luaL_getmetafield (lua_State *L, int obj, const char *e);</pre>
5176
5177<p>
5178Pushes onto the stack the field <code>e</code> from the metatable
5179of the object at index <code>obj</code>.
5180If the object does not have a metatable,
5181or if the metatable does not have this field,
5182returns 0 and pushes nothing.
5183
5184
5185
5186
5187
5188<hr><h3><a name="luaL_getmetatable"><code>luaL_getmetatable</code></a></h3><p>
5189<span class="apii">[-0, +1, <em>-</em>]</span>
5190<pre>void luaL_getmetatable (lua_State *L, const char *tname);</pre>
5191
5192<p>
5193Pushes onto the stack the metatable associated with name <code>tname</code>
5194in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
5195
5196
5197
5198
5199
5200<hr><h3><a name="luaL_gsub"><code>luaL_gsub</code></a></h3><p>
5201<span class="apii">[-0, +1, <em>m</em>]</span>
5202<pre>const char *luaL_gsub (lua_State *L,
5203 const char *s,
5204 const char *p,
5205 const char *r);</pre>
5206
5207<p>
5208Creates a copy of string <code>s</code> by replacing
5209any occurrence of the string <code>p</code>
5210with the string <code>r</code>.
5211Pushes the resulting string on the stack and returns it.
5212
5213
5214
5215
5216
5217<hr><h3><a name="luaL_loadbuffer"><code>luaL_loadbuffer</code></a></h3><p>
5218<span class="apii">[-0, +1, <em>m</em>]</span>
5219<pre>int luaL_loadbuffer (lua_State *L,
5220 const char *buff,
5221 size_t sz,
5222 const char *name);</pre>
5223
5224<p>
5225Loads a buffer as a Lua chunk.
5226This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the
5227buffer pointed to by <code>buff</code> with size <code>sz</code>.
5228
5229
5230<p>
5231This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>.
5232<code>name</code> is the chunk name,
5233used for debug information and error messages.
5234
5235
5236
5237
5238
5239<hr><h3><a name="luaL_loadfile"><code>luaL_loadfile</code></a></h3><p>
5240<span class="apii">[-0, +1, <em>m</em>]</span>
5241<pre>int luaL_loadfile (lua_State *L, const char *filename);</pre>
5242
5243<p>
5244Loads a file as a Lua chunk.
5245This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the file
5246named <code>filename</code>.
5247If <code>filename</code> is <code>NULL</code>,
5248then it loads from the standard input.
5249The first line in the file is ignored if it starts with a <code>#</code>.
5250
5251
5252<p>
5253This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>,
5254but it has an extra error code <a name="pdf-LUA_ERRFILE"><code>LUA_ERRFILE</code></a>
5255if it cannot open/read the file.
5256
5257
5258<p>
5259As <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk;
5260it does not run it.
5261
5262
5263
5264
5265
5266<hr><h3><a name="luaL_loadstring"><code>luaL_loadstring</code></a></h3><p>
5267<span class="apii">[-0, +1, <em>m</em>]</span>
5268<pre>int luaL_loadstring (lua_State *L, const char *s);</pre>
5269
5270<p>
5271Loads a string as a Lua chunk.
5272This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in
5273the zero-terminated string <code>s</code>.
5274
5275
5276<p>
5277This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>.
5278
5279
5280<p>
5281Also as <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk;
5282it does not run it.
5283
5284
5285
5286
5287
5288<hr><h3><a name="luaL_newmetatable"><code>luaL_newmetatable</code></a></h3><p>
5289<span class="apii">[-0, +1, <em>m</em>]</span>
5290<pre>int luaL_newmetatable (lua_State *L, const char *tname);</pre>
5291
5292<p>
5293If the registry already has the key <code>tname</code>,
5294returns 0.
5295Otherwise,
5296creates a new table to be used as a metatable for userdata,
5297adds it to the registry with key <code>tname</code>,
5298and returns 1.
5299
5300
5301<p>
5302In both cases pushes onto the stack the final value associated
5303with <code>tname</code> in the registry.
5304
5305
5306
5307
5308
5309<hr><h3><a name="luaL_newstate"><code>luaL_newstate</code></a></h3><p>
5310<span class="apii">[-0, +0, <em>-</em>]</span>
5311<pre>lua_State *luaL_newstate (void);</pre>
5312
5313<p>
5314Creates a new Lua state.
5315It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an
5316allocator based on the standard&nbsp;C <code>realloc</code> function
5317and then sets a panic function (see <a href="#lua_atpanic"><code>lua_atpanic</code></a>) that prints
5318an error message to the standard error output in case of fatal
5319errors.
5320
5321
5322<p>
5323Returns the new state,
5324or <code>NULL</code> if there is a memory allocation error.
5325
5326
5327
5328
5329
5330<hr><h3><a name="luaL_openlibs"><code>luaL_openlibs</code></a></h3><p>
5331<span class="apii">[-0, +0, <em>m</em>]</span>
5332<pre>void luaL_openlibs (lua_State *L);</pre>
5333
5334<p>
5335Opens all standard Lua libraries into the given state.
5336
5337
5338
5339
5340
5341<hr><h3><a name="luaL_optint"><code>luaL_optint</code></a></h3><p>
5342<span class="apii">[-0, +0, <em>v</em>]</span>
5343<pre>int luaL_optint (lua_State *L, int narg, int d);</pre>
5344
5345<p>
5346If the function argument <code>narg</code> is a number,
5347returns this number cast to an <code>int</code>.
5348If this argument is absent or is <b>nil</b>,
5349returns <code>d</code>.
5350Otherwise, raises an error.
5351
5352
5353
5354
5355
5356<hr><h3><a name="luaL_optinteger"><code>luaL_optinteger</code></a></h3><p>
5357<span class="apii">[-0, +0, <em>v</em>]</span>
5358<pre>lua_Integer luaL_optinteger (lua_State *L,
5359 int narg,
5360 lua_Integer d);</pre>
5361
5362<p>
5363If the function argument <code>narg</code> is a number,
5364returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>.
5365If this argument is absent or is <b>nil</b>,
5366returns <code>d</code>.
5367Otherwise, raises an error.
5368
5369
5370
5371
5372
5373<hr><h3><a name="luaL_optlong"><code>luaL_optlong</code></a></h3><p>
5374<span class="apii">[-0, +0, <em>v</em>]</span>
5375<pre>long luaL_optlong (lua_State *L, int narg, long d);</pre>
5376
5377<p>
5378If the function argument <code>narg</code> is a number,
5379returns this number cast to a <code>long</code>.
5380If this argument is absent or is <b>nil</b>,
5381returns <code>d</code>.
5382Otherwise, raises an error.
5383
5384
5385
5386
5387
5388<hr><h3><a name="luaL_optlstring"><code>luaL_optlstring</code></a></h3><p>
5389<span class="apii">[-0, +0, <em>v</em>]</span>
5390<pre>const char *luaL_optlstring (lua_State *L,
5391 int narg,
5392 const char *d,
5393 size_t *l);</pre>
5394
5395<p>
5396If the function argument <code>narg</code> is a string,
5397returns this string.
5398If this argument is absent or is <b>nil</b>,
5399returns <code>d</code>.
5400Otherwise, raises an error.
5401
5402
5403<p>
5404If <code>l</code> is not <code>NULL</code>,
5405fills the position <code>*l</code> with the results's length.
5406
5407
5408
5409
5410
5411<hr><h3><a name="luaL_optnumber"><code>luaL_optnumber</code></a></h3><p>
5412<span class="apii">[-0, +0, <em>v</em>]</span>
5413<pre>lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);</pre>
5414
5415<p>
5416If the function argument <code>narg</code> is a number,
5417returns this number.
5418If this argument is absent or is <b>nil</b>,
5419returns <code>d</code>.
5420Otherwise, raises an error.
5421
5422
5423
5424
5425
5426<hr><h3><a name="luaL_optstring"><code>luaL_optstring</code></a></h3><p>
5427<span class="apii">[-0, +0, <em>v</em>]</span>
5428<pre>const char *luaL_optstring (lua_State *L,
5429 int narg,
5430 const char *d);</pre>
5431
5432<p>
5433If the function argument <code>narg</code> is a string,
5434returns this string.
5435If this argument is absent or is <b>nil</b>,
5436returns <code>d</code>.
5437Otherwise, raises an error.
5438
5439
5440
5441
5442
5443<hr><h3><a name="luaL_prepbuffer"><code>luaL_prepbuffer</code></a></h3><p>
5444<span class="apii">[-0, +0, <em>-</em>]</span>
5445<pre>char *luaL_prepbuffer (luaL_Buffer *B);</pre>
5446
5447<p>
5448Returns an address to a space of size <a name="pdf-LUAL_BUFFERSIZE"><code>LUAL_BUFFERSIZE</code></a>
5449where you can copy a string to be added to buffer <code>B</code>
5450(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
5451After copying the string into this space you must call
5452<a href="#luaL_addsize"><code>luaL_addsize</code></a> with the size of the string to actually add
5453it to the buffer.
5454
5455
5456
5457
5458
5459<hr><h3><a name="luaL_pushresult"><code>luaL_pushresult</code></a></h3><p>
5460<span class="apii">[-?, +1, <em>m</em>]</span>
5461<pre>void luaL_pushresult (luaL_Buffer *B);</pre>
5462
5463<p>
5464Finishes the use of buffer <code>B</code> leaving the final string on
5465the top of the stack.
5466
5467
5468
5469
5470
5471<hr><h3><a name="luaL_ref"><code>luaL_ref</code></a></h3><p>
5472<span class="apii">[-1, +0, <em>m</em>]</span>
5473<pre>int luaL_ref (lua_State *L, int t);</pre>
5474
5475<p>
5476Creates and returns a <em>reference</em>,
5477in the table at index <code>t</code>,
5478for the object at the top of the stack (and pops the object).
5479
5480
5481<p>
5482A reference is a unique integer key.
5483As long as you do not manually add integer keys into table <code>t</code>,
5484<a href="#luaL_ref"><code>luaL_ref</code></a> ensures the uniqueness of the key it returns.
5485You can retrieve an object referred by reference <code>r</code>
5486by calling <code>lua_rawgeti(L, t, r)</code>.
5487Function <a href="#luaL_unref"><code>luaL_unref</code></a> frees a reference and its associated object.
5488
5489
5490<p>
5491If the object at the top of the stack is <b>nil</b>,
5492<a href="#luaL_ref"><code>luaL_ref</code></a> returns the constant <a name="pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>.
5493The constant <a name="pdf-LUA_NOREF"><code>LUA_NOREF</code></a> is guaranteed to be different
5494from any reference returned by <a href="#luaL_ref"><code>luaL_ref</code></a>.
5495
5496
5497
5498
5499
5500<hr><h3><a name="luaL_Reg"><code>luaL_Reg</code></a></h3>
5501<pre>typedef struct luaL_Reg {
5502 const char *name;
5503 lua_CFunction func;
5504} luaL_Reg;</pre>
5505
5506<p>
5507Type for arrays of functions to be registered by
5508<a href="#luaL_register"><code>luaL_register</code></a>.
5509<code>name</code> is the function name and <code>func</code> is a pointer to
5510the function.
5511Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with an sentinel entry
5512in which both <code>name</code> and <code>func</code> are <code>NULL</code>.
5513
5514
5515
5516
5517
5518<hr><h3><a name="luaL_register"><code>luaL_register</code></a></h3><p>
5519<span class="apii">[-(0|1), +1, <em>m</em>]</span>
5520<pre>void luaL_register (lua_State *L,
5521 const char *libname,
5522 const luaL_Reg *l);</pre>
5523
5524<p>
5525Opens a library.
5526
5527
5528<p>
5529When called with <code>libname</code> equal to <code>NULL</code>,
5530it simply registers all functions in the list <code>l</code>
5531(see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack.
5532
5533
5534<p>
5535When called with a non-null <code>libname</code>,
5536<code>luaL_register</code> creates a new table <code>t</code>,
5537sets it as the value of the global variable <code>libname</code>,
5538sets it as the value of <code>package.loaded[libname]</code>,
5539and registers on it all functions in the list <code>l</code>.
5540If there is a table in <code>package.loaded[libname]</code> or in
5541variable <code>libname</code>,
5542reuses this table instead of creating a new one.
5543
5544
5545<p>
5546In any case the function leaves the table
5547on the top of the stack.
5548
5549
5550
5551
5552
5553<hr><h3><a name="luaL_typename"><code>luaL_typename</code></a></h3><p>
5554<span class="apii">[-0, +0, <em>-</em>]</span>
5555<pre>const char *luaL_typename (lua_State *L, int index);</pre>
5556
5557<p>
5558Returns the name of the type of the value at the given index.
5559
5560
5561
5562
5563
5564<hr><h3><a name="luaL_typerror"><code>luaL_typerror</code></a></h3><p>
5565<span class="apii">[-0, +0, <em>v</em>]</span>
5566<pre>int luaL_typerror (lua_State *L, int narg, const char *tname);</pre>
5567
5568<p>
5569Generates an error with a message like the following:
5570
5571<pre>
5572 <em>location</em>: bad argument <em>narg</em> to '<em>func</em>' (<em>tname</em> expected, got <em>rt</em>)
5573</pre><p>
5574where <code><em>location</em></code> is produced by <a href="#luaL_where"><code>luaL_where</code></a>,
5575<code><em>func</em></code> is the name of the current function,
5576and <code><em>rt</em></code> is the type name of the actual argument.
5577
5578
5579
5580
5581
5582<hr><h3><a name="luaL_unref"><code>luaL_unref</code></a></h3><p>
5583<span class="apii">[-0, +0, <em>-</em>]</span>
5584<pre>void luaL_unref (lua_State *L, int t, int ref);</pre>
5585
5586<p>
5587Releases reference <code>ref</code> from the table at index <code>t</code>
5588(see <a href="#luaL_ref"><code>luaL_ref</code></a>).
5589The entry is removed from the table,
5590so that the referred object can be collected.
5591The reference <code>ref</code> is also freed to be used again.
5592
5593
5594<p>
5595If <code>ref</code> is <a href="#pdf-LUA_NOREF"><code>LUA_NOREF</code></a> or <a href="#pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>,
5596<a href="#luaL_unref"><code>luaL_unref</code></a> does nothing.
5597
5598
5599
5600
5601
5602<hr><h3><a name="luaL_where"><code>luaL_where</code></a></h3><p>
5603<span class="apii">[-0, +1, <em>m</em>]</span>
5604<pre>void luaL_where (lua_State *L, int lvl);</pre>
5605
5606<p>
5607Pushes onto the stack a string identifying the current position
5608of the control at level <code>lvl</code> in the call stack.
5609Typically this string has the following format:
5610
5611<pre>
5612 <em>chunkname</em>:<em>currentline</em>:
5613</pre><p>
5614Level&nbsp;0 is the running function,
5615level&nbsp;1 is the function that called the running function,
5616etc.
5617
5618
5619<p>
5620This function is used to build a prefix for error messages.
5621
5622
5623
5624
5625
5626
5627
5628<h1>5 - <a name="5">Standard Libraries</a></h1>
5629
5630<p>
5631The standard Lua libraries provide useful functions
5632that are implemented directly through the C&nbsp;API.
5633Some of these functions provide essential services to the language
5634(e.g., <a href="#pdf-type"><code>type</code></a> and <a href="#pdf-getmetatable"><code>getmetatable</code></a>);
5635others provide access to "outside" services (e.g., I/O);
5636and others could be implemented in Lua itself,
5637but are quite useful or have critical performance requirements that
5638deserve an implementation in C (e.g., <a href="#pdf-table.sort"><code>table.sort</code></a>).
5639
5640
5641<p>
5642All libraries are implemented through the official C&nbsp;API
5643and are provided as separate C&nbsp;modules.
5644Currently, Lua has the following standard libraries:
5645
5646<ul>
5647
5648<li>basic library,</li> which includes the coroutine sub-library;
5649
5650<li>package library;</li>
5651
5652<li>string manipulation;</li>
5653
5654<li>table manipulation;</li>
5655
5656<li>mathematical functions (sin, log, etc.);</li>
5657
5658<li>input and output;</li>
5659
5660<li>operating system facilities;</li>
5661
5662<li>debug facilities.</li>
5663
5664</ul><p>
5665Except for the basic and package libraries,
5666each library provides all its functions as fields of a global table
5667or as methods of its objects.
5668
5669
5670<p>
5671To have access to these libraries,
5672the C&nbsp;host program should call the <a href="#luaL_openlibs"><code>luaL_openlibs</code></a> function,
5673which opens all standard libraries.
5674Alternatively,
5675it can open them individually by calling
5676<a name="pdf-luaopen_base"><code>luaopen_base</code></a> (for the basic library),
5677<a name="pdf-luaopen_package"><code>luaopen_package</code></a> (for the package library),
5678<a name="pdf-luaopen_string"><code>luaopen_string</code></a> (for the string library),
5679<a name="pdf-luaopen_table"><code>luaopen_table</code></a> (for the table library),
5680<a name="pdf-luaopen_math"><code>luaopen_math</code></a> (for the mathematical library),
5681<a name="pdf-luaopen_io"><code>luaopen_io</code></a> (for the I/O library),
5682<a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the Operating System library),
5683and <a name="pdf-luaopen_debug"><code>luaopen_debug</code></a> (for the debug library).
5684These functions are declared in <a name="pdf-lualib.h"><code>lualib.h</code></a>
5685and should not be called directly:
5686you must call them like any other Lua C&nbsp;function,
5687e.g., by using <a href="#lua_call"><code>lua_call</code></a>.
5688
5689
5690
5691<h2>5.1 - <a name="5.1">Basic Functions</a></h2>
5692
5693<p>
5694The basic library provides some core functions to Lua.
5695If you do not include this library in your application,
5696you should check carefully whether you need to provide
5697implementations for some of its facilities.
5698
5699
5700<p>
5701<hr><h3><a name="pdf-assert"><code>assert (v [, message])</code></a></h3>
5702Issues an error when
5703the value of its argument <code>v</code> is false (i.e., <b>nil</b> or <b>false</b>);
5704otherwise, returns all its arguments.
5705<code>message</code> is an error message;
5706when absent, it defaults to "assertion failed!"
5707
5708
5709
5710
5711<p>
5712<hr><h3><a name="pdf-collectgarbage"><code>collectgarbage (opt [, arg])</code></a></h3>
5713
5714
5715<p>
5716This function is a generic interface to the garbage collector.
5717It performs different functions according to its first argument, <code>opt</code>:
5718
5719<ul>
5720
5721<li><b>"stop":</b>
5722stops the garbage collector.
5723</li>
5724
5725<li><b>"restart":</b>
5726restarts the garbage collector.
5727</li>
5728
5729<li><b>"collect":</b>
5730performs a full garbage-collection cycle.
5731</li>
5732
5733<li><b>"count":</b>
5734returns the total memory in use by Lua (in Kbytes).
5735</li>
5736
5737<li><b>"step":</b>
5738performs a garbage-collection step.
5739The step "size" is controlled by <code>arg</code>
5740(larger values mean more steps) in a non-specified way.
5741If you want to control the step size
5742you must experimentally tune the value of <code>arg</code>.
5743Returns <b>true</b> if the step finished a collection cycle.
5744</li>
5745
5746<li><b>"setpause":</b>
5747sets <code>arg</code> as the new value for the <em>pause</em> of
5748the collector (see <a href="#2.10">&sect;2.10</a>).
5749Returns the previous value for <em>pause</em>.
5750</li>
5751
5752<li><b>"setstepmul":</b>
5753sets <code>arg</code> as the new value for the <em>step multiplier</em> of
5754the collector (see <a href="#2.10">&sect;2.10</a>).
5755Returns the previous value for <em>step</em>.
5756</li>
5757
5758</ul>
5759
5760
5761
5762<p>
5763<hr><h3><a name="pdf-dofile"><code>dofile (filename)</code></a></h3>
5764Opens the named file and executes its contents as a Lua chunk.
5765When called without arguments,
5766<code>dofile</code> executes the contents of the standard input (<code>stdin</code>).
5767Returns all values returned by the chunk.
5768In case of errors, <code>dofile</code> propagates the error
5769to its caller (that is, <code>dofile</code> does not run in protected mode).
5770
5771
5772
5773
5774<p>
5775<hr><h3><a name="pdf-error"><code>error (message [, level])</code></a></h3>
5776Terminates the last protected function called
5777and returns <code>message</code> as the error message.
5778Function <code>error</code> never returns.
5779
5780
5781<p>
5782Usually, <code>error</code> adds some information about the error position
5783at the beginning of the message.
5784The <code>level</code> argument specifies how to get the error position.
5785With level&nbsp;1 (the default), the error position is where the
5786<code>error</code> function was called.
5787Level&nbsp;2 points the error to where the function
5788that called <code>error</code> was called; and so on.
5789Passing a level&nbsp;0 avoids the addition of error position information
5790to the message.
5791
5792
5793
5794
5795<p>
5796<hr><h3><a name="pdf-_G"><code>_G</code></a></h3>
5797A global variable (not a function) that
5798holds the global environment (that is, <code>_G._G = _G</code>).
5799Lua itself does not use this variable;
5800changing its value does not affect any environment,
5801nor vice-versa.
5802(Use <a href="#pdf-setfenv"><code>setfenv</code></a> to change environments.)
5803
5804
5805
5806
5807<p>
5808<hr><h3><a name="pdf-getfenv"><code>getfenv ([f])</code></a></h3>
5809Returns the current environment in use by the function.
5810<code>f</code> can be a Lua function or a number
5811that specifies the function at that stack level:
5812Level&nbsp;1 is the function calling <code>getfenv</code>.
5813If the given function is not a Lua function,
5814or if <code>f</code> is 0,
5815<code>getfenv</code> returns the global environment.
5816The default for <code>f</code> is 1.
5817
5818
5819
5820
5821<p>
5822<hr><h3><a name="pdf-getmetatable"><code>getmetatable (object)</code></a></h3>
5823
5824
5825<p>
5826If <code>object</code> does not have a metatable, returns <b>nil</b>.
5827Otherwise,
5828if the object's metatable has a <code>"__metatable"</code> field,
5829returns the associated value.
5830Otherwise, returns the metatable of the given object.
5831
5832
5833
5834
5835<p>
5836<hr><h3><a name="pdf-ipairs"><code>ipairs (t)</code></a></h3>
5837
5838
5839<p>
5840Returns three values: an iterator function, the table <code>t</code>, and 0,
5841so that the construction
5842
5843<pre>
5844 for i,v in ipairs(t) do <em>body</em> end
5845</pre><p>
5846will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), &middot;&middot;&middot;,
5847up to the first integer key absent from the table.
5848
5849
5850
5851
5852<p>
5853<hr><h3><a name="pdf-load"><code>load (func [, chunkname])</code></a></h3>
5854
5855
5856<p>
5857Loads a chunk using function <code>func</code> to get its pieces.
5858Each call to <code>func</code> must return a string that concatenates
5859with previous results.
5860A return of an empty string, <b>nil</b>, or no value signals the end of the chunk.
5861
5862
5863<p>
5864If there are no errors,
5865returns the compiled chunk as a function;
5866otherwise, returns <b>nil</b> plus the error message.
5867The environment of the returned function is the global environment.
5868
5869
5870<p>
5871<code>chunkname</code> is used as the chunk name for error messages
5872and debug information.
5873When absent,
5874it defaults to "<code>=(load)</code>".
5875
5876
5877
5878
5879<p>
5880<hr><h3><a name="pdf-loadfile"><code>loadfile ([filename])</code></a></h3>
5881
5882
5883<p>
5884Similar to <a href="#pdf-load"><code>load</code></a>,
5885but gets the chunk from file <code>filename</code>
5886or from the standard input,
5887if no file name is given.
5888
5889
5890
5891
5892<p>
5893<hr><h3><a name="pdf-loadstring"><code>loadstring (string [, chunkname])</code></a></h3>
5894
5895
5896<p>
5897Similar to <a href="#pdf-load"><code>load</code></a>,
5898but gets the chunk from the given string.
5899
5900
5901<p>
5902To load and run a given string, use the idiom
5903
5904<pre>
5905 assert(loadstring(s))()
5906</pre>
5907
5908<p>
5909When absent,
5910<code>chunkname</code> defaults to the given string.
5911
5912
5913
5914
5915<p>
5916<hr><h3><a name="pdf-next"><code>next (table [, index])</code></a></h3>
5917
5918
5919<p>
5920Allows a program to traverse all fields of a table.
5921Its first argument is a table and its second argument
5922is an index in this table.
5923<code>next</code> returns the next index of the table
5924and its associated value.
5925When called with <b>nil</b> as its second argument,
5926<code>next</code> returns an initial index
5927and its associated value.
5928When called with the last index,
5929or with <b>nil</b> in an empty table,
5930<code>next</code> returns <b>nil</b>.
5931If the second argument is absent, then it is interpreted as <b>nil</b>.
5932In particular,
5933you can use <code>next(t)</code> to check whether a table is empty.
5934
5935
5936<p>
5937The order in which the indices are enumerated is not specified,
5938<em>even for numeric indices</em>.
5939(To traverse a table in numeric order,
5940use a numerical <b>for</b> or the <a href="#pdf-ipairs"><code>ipairs</code></a> function.)
5941
5942
5943<p>
5944The behavior of <code>next</code> is <em>undefined</em> if,
5945during the traversal,
5946you assign any value to a non-existent field in the table.
5947You may however modify existing fields.
5948In particular, you may clear existing fields.
5949
5950
5951
5952
5953<p>
5954<hr><h3><a name="pdf-pairs"><code>pairs (t)</code></a></h3>
5955
5956
5957<p>
5958Returns three values: the <a href="#pdf-next"><code>next</code></a> function, the table <code>t</code>, and <b>nil</b>,
5959so that the construction
5960
5961<pre>
5962 for k,v in pairs(t) do <em>body</em> end
5963</pre><p>
5964will iterate over all key&ndash;value pairs of table <code>t</code>.
5965
5966
5967<p>
5968See function <a href="#pdf-next"><code>next</code></a> for the caveats of modifying
5969the table during its traversal.
5970
5971
5972
5973
5974<p>
5975<hr><h3><a name="pdf-pcall"><code>pcall (f, arg1, &middot;&middot;&middot;)</code></a></h3>
5976
5977
5978<p>
5979Calls function <code>f</code> with
5980the given arguments in <em>protected mode</em>.
5981This means that any error inside&nbsp;<code>f</code> is not propagated;
5982instead, <code>pcall</code> catches the error
5983and returns a status code.
5984Its first result is the status code (a boolean),
5985which is true if the call succeeds without errors.
5986In such case, <code>pcall</code> also returns all results from the call,
5987after this first result.
5988In case of any error, <code>pcall</code> returns <b>false</b> plus the error message.
5989
5990
5991
5992
5993<p>
5994<hr><h3><a name="pdf-print"><code>print (&middot;&middot;&middot;)</code></a></h3>
5995Receives any number of arguments,
5996and prints their values to <code>stdout</code>,
5997using the <a href="#pdf-tostring"><code>tostring</code></a> function to convert them to strings.
5998<code>print</code> is not intended for formatted output,
5999but only as a quick way to show a value,
6000typically for debugging.
6001For formatted output, use <a href="#pdf-string.format"><code>string.format</code></a>.
6002
6003
6004
6005
6006<p>
6007<hr><h3><a name="pdf-rawequal"><code>rawequal (v1, v2)</code></a></h3>
6008Checks whether <code>v1</code> is equal to <code>v2</code>,
6009without invoking any metamethod.
6010Returns a boolean.
6011
6012
6013
6014
6015<p>
6016<hr><h3><a name="pdf-rawget"><code>rawget (table, index)</code></a></h3>
6017Gets the real value of <code>table[index]</code>,
6018without invoking any metamethod.
6019<code>table</code> must be a table;
6020<code>index</code> may be any value.
6021
6022
6023
6024
6025<p>
6026<hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3>
6027Sets the real value of <code>table[index]</code> to <code>value</code>,
6028without invoking any metamethod.
6029<code>table</code> must be a table,
6030<code>index</code> any value different from <b>nil</b>,
6031and <code>value</code> any Lua value.
6032
6033
6034<p>
6035This function returns <code>table</code>.
6036
6037
6038
6039
6040<p>
6041<hr><h3><a name="pdf-select"><code>select (index, &middot;&middot;&middot;)</code></a></h3>
6042
6043
6044<p>
6045If <code>index</code> is a number,
6046returns all arguments after argument number <code>index</code>.
6047Otherwise, <code>index</code> must be the string <code>"#"</code>,
6048and <code>select</code> returns the total number of extra arguments it received.
6049
6050
6051
6052
6053<p>
6054<hr><h3><a name="pdf-setfenv"><code>setfenv (f, table)</code></a></h3>
6055
6056
6057<p>
6058Sets the environment to be used by the given function.
6059<code>f</code> can be a Lua function or a number
6060that specifies the function at that stack level:
6061Level&nbsp;1 is the function calling <code>setfenv</code>.
6062<code>setfenv</code> returns the given function.
6063
6064
6065<p>
6066As a special case, when <code>f</code> is 0 <code>setfenv</code> changes
6067the environment of the running thread.
6068In this case, <code>setfenv</code> returns no values.
6069
6070
6071
6072
6073<p>
6074<hr><h3><a name="pdf-setmetatable"><code>setmetatable (table, metatable)</code></a></h3>
6075
6076
6077<p>
6078Sets the metatable for the given table.
6079(You cannot change the metatable of other types from Lua, only from&nbsp;C.)
6080If <code>metatable</code> is <b>nil</b>,
6081removes the metatable of the given table.
6082If the original metatable has a <code>"__metatable"</code> field,
6083raises an error.
6084
6085
6086<p>
6087This function returns <code>table</code>.
6088
6089
6090
6091
6092<p>
6093<hr><h3><a name="pdf-tonumber"><code>tonumber (e [, base])</code></a></h3>
6094Tries to convert its argument to a number.
6095If the argument is already a number or a string convertible
6096to a number, then <code>tonumber</code> returns this number;
6097otherwise, it returns <b>nil</b>.
6098
6099
6100<p>
6101An optional argument specifies the base to interpret the numeral.
6102The base may be any integer between 2 and 36, inclusive.
6103In bases above&nbsp;10, the letter '<code>A</code>' (in either upper or lower case)
6104represents&nbsp;10, '<code>B</code>' represents&nbsp;11, and so forth,
6105with '<code>Z</code>' representing 35.
6106In base 10 (the default), the number can have a decimal part,
6107as well as an optional exponent part (see <a href="#2.1">&sect;2.1</a>).
6108In other bases, only unsigned integers are accepted.
6109
6110
6111
6112
6113<p>
6114<hr><h3><a name="pdf-tostring"><code>tostring (e)</code></a></h3>
6115Receives an argument of any type and
6116converts it to a string in a reasonable format.
6117For complete control of how numbers are converted,
6118use <a href="#pdf-string.format"><code>string.format</code></a>.
6119
6120
6121<p>
6122If the metatable of <code>e</code> has a <code>"__tostring"</code> field,
6123then <code>tostring</code> calls the corresponding value
6124with <code>e</code> as argument,
6125and uses the result of the call as its result.
6126
6127
6128
6129
6130<p>
6131<hr><h3><a name="pdf-type"><code>type (v)</code></a></h3>
6132Returns the type of its only argument, coded as a string.
6133The possible results of this function are
6134"<code>nil</code>" (a string, not the value <b>nil</b>),
6135"<code>number</code>",
6136"<code>string</code>",
6137"<code>boolean</code>",
6138"<code>table</code>",
6139"<code>function</code>",
6140"<code>thread</code>",
6141and "<code>userdata</code>".
6142
6143
6144
6145
6146<p>
6147<hr><h3><a name="pdf-unpack"><code>unpack (list [, i [, j]])</code></a></h3>
6148Returns the elements from the given table.
6149This function is equivalent to
6150
6151<pre>
6152 return list[i], list[i+1], &middot;&middot;&middot;, list[j]
6153</pre><p>
6154except that the above code can be written only for a fixed number
6155of elements.
6156By default, <code>i</code> is&nbsp;1 and <code>j</code> is the length of the list,
6157as defined by the length operator (see <a href="#2.5.5">&sect;2.5.5</a>).
6158
6159
6160
6161
6162<p>
6163<hr><h3><a name="pdf-_VERSION"><code>_VERSION</code></a></h3>
6164A global variable (not a function) that
6165holds a string containing the current interpreter version.
6166The current contents of this variable is "<code>Lua 5.1</code>".
6167
6168
6169
6170
6171<p>
6172<hr><h3><a name="pdf-xpcall"><code>xpcall (f, err)</code></a></h3>
6173
6174
6175<p>
6176This function is similar to <a href="#pdf-pcall"><code>pcall</code></a>,
6177except that you can set a new error handler.
6178
6179
6180<p>
6181<code>xpcall</code> calls function <code>f</code> in protected mode,
6182using <code>err</code> as the error handler.
6183Any error inside <code>f</code> is not propagated;
6184instead, <code>xpcall</code> catches the error,
6185calls the <code>err</code> function with the original error object,
6186and returns a status code.
6187Its first result is the status code (a boolean),
6188which is true if the call succeeds without errors.
6189In this case, <code>xpcall</code> also returns all results from the call,
6190after this first result.
6191In case of any error,
6192<code>xpcall</code> returns <b>false</b> plus the result from <code>err</code>.
6193
6194
6195
6196
6197
6198
6199
6200<h2>5.2 - <a name="5.2">Coroutine Manipulation</a></h2>
6201
6202<p>
6203The operations related to coroutines comprise a sub-library of
6204the basic library and come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>.
6205See <a href="#2.11">&sect;2.11</a> for a general description of coroutines.
6206
6207
6208<p>
6209<hr><h3><a name="pdf-coroutine.create"><code>coroutine.create (f)</code></a></h3>
6210
6211
6212<p>
6213Creates a new coroutine, with body <code>f</code>.
6214<code>f</code> must be a Lua function.
6215Returns this new coroutine,
6216an object with type <code>"thread"</code>.
6217
6218
6219
6220
6221<p>
6222<hr><h3><a name="pdf-coroutine.resume"><code>coroutine.resume (co [, val1, &middot;&middot;&middot;])</code></a></h3>
6223
6224
6225<p>
6226Starts or continues the execution of coroutine <code>co</code>.
6227The first time you resume a coroutine,
6228it starts running its body.
6229The values <code>val1</code>, &middot;&middot;&middot; are passed
6230as the arguments to the body function.
6231If the coroutine has yielded,
6232<code>resume</code> restarts it;
6233the values <code>val1</code>, &middot;&middot;&middot; are passed
6234as the results from the yield.
6235
6236
6237<p>
6238If the coroutine runs without any errors,
6239<code>resume</code> returns <b>true</b> plus any values passed to <code>yield</code>
6240(if the coroutine yields) or any values returned by the body function
6241(if the coroutine terminates).
6242If there is any error,
6243<code>resume</code> returns <b>false</b> plus the error message.
6244
6245
6246
6247
6248<p>
6249<hr><h3><a name="pdf-coroutine.running"><code>coroutine.running ()</code></a></h3>
6250
6251
6252<p>
6253Returns the running coroutine,
6254or <b>nil</b> when called by the main thread.
6255
6256
6257
6258
6259<p>
6260<hr><h3><a name="pdf-coroutine.status"><code>coroutine.status (co)</code></a></h3>
6261
6262
6263<p>
6264Returns the status of coroutine <code>co</code>, as a string:
6265<code>"running"</code>,
6266if the coroutine is running (that is, it called <code>status</code>);
6267<code>"suspended"</code>, if the coroutine is suspended in a call to <code>yield</code>,
6268or if it has not started running yet;
6269<code>"normal"</code> if the coroutine is active but not running
6270(that is, it has resumed another coroutine);
6271and <code>"dead"</code> if the coroutine has finished its body function,
6272or if it has stopped with an error.
6273
6274
6275
6276
6277<p>
6278<hr><h3><a name="pdf-coroutine.wrap"><code>coroutine.wrap (f)</code></a></h3>
6279
6280
6281<p>
6282Creates a new coroutine, with body <code>f</code>.
6283<code>f</code> must be a Lua function.
6284Returns a function that resumes the coroutine each time it is called.
6285Any arguments passed to the function behave as the
6286extra arguments to <code>resume</code>.
6287Returns the same values returned by <code>resume</code>,
6288except the first boolean.
6289In case of error, propagates the error.
6290
6291
6292
6293
6294<p>
6295<hr><h3><a name="pdf-coroutine.yield"><code>coroutine.yield (&middot;&middot;&middot;)</code></a></h3>
6296
6297
6298<p>
6299Suspends the execution of the calling coroutine.
6300The coroutine cannot be running a C&nbsp;function,
6301a metamethod, or an iterator.
6302Any arguments to <code>yield</code> are passed as extra results to <code>resume</code>.
6303
6304
6305
6306
6307
6308
6309
6310<h2>5.3 - <a name="5.3">Modules</a></h2>
6311
6312<p>
6313The package library provides basic
6314facilities for loading and building modules in Lua.
6315It exports two of its functions directly in the global environment:
6316<a href="#pdf-require"><code>require</code></a> and <a href="#pdf-module"><code>module</code></a>.
6317Everything else is exported in a table <a name="pdf-package"><code>package</code></a>.
6318
6319
6320<p>
6321<hr><h3><a name="pdf-module"><code>module (name [, &middot;&middot;&middot;])</code></a></h3>
6322
6323
6324<p>
6325Creates a module.
6326If there is a table in <code>package.loaded[name]</code>,
6327this table is the module.
6328Otherwise, if there is a global table <code>t</code> with the given name,
6329this table is the module.
6330Otherwise creates a new table <code>t</code> and
6331sets it as the value of the global <code>name</code> and
6332the value of <code>package.loaded[name]</code>.
6333This function also initializes <code>t._NAME</code> with the given name,
6334<code>t._M</code> with the module (<code>t</code> itself),
6335and <code>t._PACKAGE</code> with the package name
6336(the full module name minus last component; see below).
6337Finally, <code>module</code> sets <code>t</code> as the new environment
6338of the current function and the new value of <code>package.loaded[name]</code>,
6339so that <a href="#pdf-require"><code>require</code></a> returns <code>t</code>.
6340
6341
6342<p>
6343If <code>name</code> is a compound name
6344(that is, one with components separated by dots),
6345<code>module</code> creates (or reuses, if they already exist)
6346tables for each component.
6347For instance, if <code>name</code> is <code>a.b.c</code>,
6348then <code>module</code> stores the module table in field <code>c</code> of
6349field <code>b</code> of global <code>a</code>.
6350
6351
6352<p>
6353This function can receive optional <em>options</em> after
6354the module name,
6355where each option is a function to be applied over the module.
6356
6357
6358
6359
6360<p>
6361<hr><h3><a name="pdf-require"><code>require (modname)</code></a></h3>
6362
6363
6364<p>
6365Loads the given module.
6366The function starts by looking into the <a href="#pdf-package.loaded"><code>package.loaded</code></a> table
6367to determine whether <code>modname</code> is already loaded.
6368If it is, then <code>require</code> returns the value stored
6369at <code>package.loaded[modname]</code>.
6370Otherwise, it tries to find a <em>loader</em> for the module.
6371
6372
6373<p>
6374To find a loader,
6375<code>require</code> is guided by the <a href="#pdf-package.loaders"><code>package.loaders</code></a> array.
6376By changing this array,
6377we can change how <code>require</code> looks for a module.
6378The following explanation is based on the default configuration
6379for <a href="#pdf-package.loaders"><code>package.loaders</code></a>.
6380
6381
6382<p>
6383First <code>require</code> queries <code>package.preload[modname]</code>.
6384If it has a value,
6385this value (which should be a function) is the loader.
6386Otherwise <code>require</code> searches for a Lua loader using the
6387path stored in <a href="#pdf-package.path"><code>package.path</code></a>.
6388If that also fails, it searches for a C&nbsp;loader using the
6389path stored in <a href="#pdf-package.cpath"><code>package.cpath</code></a>.
6390If that also fails,
6391it tries an <em>all-in-one</em> loader (see <a href="#pdf-package.loaders"><code>package.loaders</code></a>).
6392
6393
6394<p>
6395Once a loader is found,
6396<code>require</code> calls the loader with a single argument, <code>modname</code>.
6397If the loader returns any value,
6398<code>require</code> assigns the returned value to <code>package.loaded[modname]</code>.
6399If the loader returns no value and
6400has not assigned any value to <code>package.loaded[modname]</code>,
6401then <code>require</code> assigns <b>true</b> to this entry.
6402In any case, <code>require</code> returns the
6403final value of <code>package.loaded[modname]</code>.
6404
6405
6406<p>
6407If there is any error loading or running the module,
6408or if it cannot find any loader for the module,
6409then <code>require</code> signals an error.
6410
6411
6412
6413
6414<p>
6415<hr><h3><a name="pdf-package.cpath"><code>package.cpath</code></a></h3>
6416
6417
6418<p>
6419The path used by <a href="#pdf-require"><code>require</code></a> to search for a C&nbsp;loader.
6420
6421
6422<p>
6423Lua initializes the C&nbsp;path <a href="#pdf-package.cpath"><code>package.cpath</code></a> in the same way
6424it initializes the Lua path <a href="#pdf-package.path"><code>package.path</code></a>,
6425using the environment variable <a name="pdf-LUA_CPATH"><code>LUA_CPATH</code></a>
6426or a default path defined in <code>luaconf.h</code>.
6427
6428
6429
6430
6431<p>
6432
6433<hr><h3><a name="pdf-package.loaded"><code>package.loaded</code></a></h3>
6434
6435
6436<p>
6437A table used by <a href="#pdf-require"><code>require</code></a> to control which
6438modules are already loaded.
6439When you require a module <code>modname</code> and
6440<code>package.loaded[modname]</code> is not false,
6441<a href="#pdf-require"><code>require</code></a> simply returns the value stored there.
6442
6443
6444
6445
6446<p>
6447<hr><h3><a name="pdf-package.loaders"><code>package.loaders</code></a></h3>
6448
6449
6450<p>
6451A table used by <a href="#pdf-require"><code>require</code></a> to control how to load modules.
6452
6453
6454<p>
6455Each entry in this table is a <em>searcher function</em>.
6456When looking for a module,
6457<a href="#pdf-require"><code>require</code></a> calls each of these searchers in ascending order,
6458with the module name (the argument given to <a href="#pdf-require"><code>require</code></a>) as its
6459sole parameter.
6460The function can return another function (the module <em>loader</em>)
6461or a string explaining why it did not find that module
6462(or <b>nil</b> if it has nothing to say).
6463Lua initializes this table with four functions.
6464
6465
6466<p>
6467The first searcher simply looks for a loader in the
6468<a href="#pdf-package.preload"><code>package.preload</code></a> table.
6469
6470
6471<p>
6472The second searcher looks for a loader as a Lua library,
6473using the path stored at <a href="#pdf-package.path"><code>package.path</code></a>.
6474A path is a sequence of <em>templates</em> separated by semicolons.
6475For each template,
6476the searcher will change each interrogation
6477mark in the template by <code>filename</code>,
6478which is the module name with each dot replaced by a
6479"directory separator" (such as "<code>/</code>" in Unix);
6480then it will try to open the resulting file name.
6481So, for instance, if the Lua path is the string
6482
6483<pre>
6484 "./?.lua;./?.lc;/usr/local/?/init.lua"
6485</pre><p>
6486the search for a Lua file for module <code>foo</code>
6487will try to open the files
6488<code>./foo.lua</code>, <code>./foo.lc</code>, and
6489<code>/usr/local/foo/init.lua</code>, in that order.
6490
6491
6492<p>
6493The third searcher looks for a loader as a C&nbsp;library,
6494using the path given by the variable <a href="#pdf-package.cpath"><code>package.cpath</code></a>.
6495For instance,
6496if the C&nbsp;path is the string
6497
6498<pre>
6499 "./?.so;./?.dll;/usr/local/?/init.so"
6500</pre><p>
6501the searcher for module <code>foo</code>
6502will try to open the files <code>./foo.so</code>, <code>./foo.dll</code>,
6503and <code>/usr/local/foo/init.so</code>, in that order.
6504Once it finds a C&nbsp;library,
6505this searcher first uses a dynamic link facility to link the
6506application with the library.
6507Then it tries to find a C&nbsp;function inside the library to
6508be used as the loader.
6509The name of this C&nbsp;function is the string "<code>luaopen_</code>"
6510concatenated with a copy of the module name where each dot
6511is replaced by an underscore.
6512Moreover, if the module name has a hyphen,
6513its prefix up to (and including) the first hyphen is removed.
6514For instance, if the module name is <code>a.v1-b.c</code>,
6515the function name will be <code>luaopen_b_c</code>.
6516
6517
6518<p>
6519The fourth searcher tries an <em>all-in-one loader</em>.
6520It searches the C&nbsp;path for a library for
6521the root name of the given module.
6522For instance, when requiring <code>a.b.c</code>,
6523it will search for a C&nbsp;library for <code>a</code>.
6524If found, it looks into it for an open function for
6525the submodule;
6526in our example, that would be <code>luaopen_a_b_c</code>.
6527With this facility, a package can pack several C&nbsp;submodules
6528into one single library,
6529with each submodule keeping its original open function.
6530
6531
6532
6533
6534<p>
6535<hr><h3><a name="pdf-package.loadlib"><code>package.loadlib (libname, funcname)</code></a></h3>
6536
6537
6538<p>
6539Dynamically links the host program with the C&nbsp;library <code>libname</code>.
6540Inside this library, looks for a function <code>funcname</code>
6541and returns this function as a C&nbsp;function.
6542(So, <code>funcname</code> must follow the protocol (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>)).
6543
6544
6545<p>
6546This is a low-level function.
6547It completely bypasses the package and module system.
6548Unlike <a href="#pdf-require"><code>require</code></a>,
6549it does not perform any path searching and
6550does not automatically adds extensions.
6551<code>libname</code> must be the complete file name of the C&nbsp;library,
6552including if necessary a path and extension.
6553<code>funcname</code> must be the exact name exported by the C&nbsp;library
6554(which may depend on the C&nbsp;compiler and linker used).
6555
6556
6557<p>
6558This function is not supported by ANSI C.
6559As such, it is only available on some platforms
6560(Windows, Linux, Mac OS X, Solaris, BSD,
6561plus other Unix systems that support the <code>dlfcn</code> standard).
6562
6563
6564
6565
6566<p>
6567<hr><h3><a name="pdf-package.path"><code>package.path</code></a></h3>
6568
6569
6570<p>
6571The path used by <a href="#pdf-require"><code>require</code></a> to search for a Lua loader.
6572
6573
6574<p>
6575At start-up, Lua initializes this variable with
6576the value of the environment variable <a name="pdf-LUA_PATH"><code>LUA_PATH</code></a> or
6577with a default path defined in <code>luaconf.h</code>,
6578if the environment variable is not defined.
6579Any "<code>;;</code>" in the value of the environment variable
6580is replaced by the default path.
6581
6582
6583
6584
6585<p>
6586<hr><h3><a name="pdf-package.preload"><code>package.preload</code></a></h3>
6587
6588
6589<p>
6590A table to store loaders for specific modules
6591(see <a href="#pdf-require"><code>require</code></a>).
6592
6593
6594
6595
6596<p>
6597<hr><h3><a name="pdf-package.seeall"><code>package.seeall (module)</code></a></h3>
6598
6599
6600<p>
6601Sets a metatable for <code>module</code> with
6602its <code>__index</code> field referring to the global environment,
6603so that this module inherits values
6604from the global environment.
6605To be used as an option to function <a href="#pdf-module"><code>module</code></a>.
6606
6607
6608
6609
6610
6611
6612
6613<h2>5.4 - <a name="5.4">String Manipulation</a></h2>
6614
6615<p>
6616This library provides generic functions for string manipulation,
6617such as finding and extracting substrings, and pattern matching.
6618When indexing a string in Lua, the first character is at position&nbsp;1
6619(not at&nbsp;0, as in C).
6620Indices are allowed to be negative and are interpreted as indexing backwards,
6621from the end of the string.
6622Thus, the last character is at position -1, and so on.
6623
6624
6625<p>
6626The string library provides all its functions inside the table
6627<a name="pdf-string"><code>string</code></a>.
6628It also sets a metatable for strings
6629where the <code>__index</code> field points to the <code>string</code> table.
6630Therefore, you can use the string functions in object-oriented style.
6631For instance, <code>string.byte(s, i)</code>
6632can be written as <code>s:byte(i)</code>.
6633
6634
6635<p>
6636The string library assumes one-byte character encodings.
6637
6638
6639<p>
6640<hr><h3><a name="pdf-string.byte"><code>string.byte (s [, i [, j]])</code></a></h3>
6641Returns the internal numerical codes of the characters <code>s[i]</code>,
6642<code>s[i+1]</code>, &middot;&middot;&middot;, <code>s[j]</code>.
6643The default value for <code>i</code> is&nbsp;1;
6644the default value for <code>j</code> is&nbsp;<code>i</code>.
6645
6646
6647<p>
6648Note that numerical codes are not necessarily portable across platforms.
6649
6650
6651
6652
6653<p>
6654<hr><h3><a name="pdf-string.char"><code>string.char (&middot;&middot;&middot;)</code></a></h3>
6655Receives zero or more integers.
6656Returns a string with length equal to the number of arguments,
6657in which each character has the internal numerical code equal
6658to its corresponding argument.
6659
6660
6661<p>
6662Note that numerical codes are not necessarily portable across platforms.
6663
6664
6665
6666
6667<p>
6668<hr><h3><a name="pdf-string.dump"><code>string.dump (function)</code></a></h3>
6669
6670
6671<p>
6672Returns a string containing a binary representation of the given function,
6673so that a later <a href="#pdf-loadstring"><code>loadstring</code></a> on this string returns
6674a copy of the function.
6675<code>function</code> must be a Lua function without upvalues.
6676
6677
6678
6679
6680<p>
6681<hr><h3><a name="pdf-string.find"><code>string.find (s, pattern [, init [, plain]])</code></a></h3>
6682Looks for the first match of
6683<code>pattern</code> in the string <code>s</code>.
6684If it finds a match, then <code>find</code> returns the indices of&nbsp;<code>s</code>
6685where this occurrence starts and ends;
6686otherwise, it returns <b>nil</b>.
6687A third, optional numerical argument <code>init</code> specifies
6688where to start the search;
6689its default value is&nbsp;1 and can be negative.
6690A value of <b>true</b> as a fourth, optional argument <code>plain</code>
6691turns off the pattern matching facilities,
6692so the function does a plain "find substring" operation,
6693with no characters in <code>pattern</code> being considered "magic".
6694Note that if <code>plain</code> is given, then <code>init</code> must be given as well.
6695
6696
6697<p>
6698If the pattern has captures,
6699then in a successful match
6700the captured values are also returned,
6701after the two indices.
6702
6703
6704
6705
6706<p>
6707<hr><h3><a name="pdf-string.format"><code>string.format (formatstring, &middot;&middot;&middot;)</code></a></h3>
6708Returns a formatted version of its variable number of arguments
6709following the description given in its first argument (which must be a string).
6710The format string follows the same rules as the <code>printf</code> family of
6711standard C&nbsp;functions.
6712The only differences are that the options/modifiers
6713<code>*</code>, <code>l</code>, <code>L</code>, <code>n</code>, <code>p</code>,
6714and <code>h</code> are not supported
6715and that there is an extra option, <code>q</code>.
6716The <code>q</code> option formats a string in a form suitable to be safely read
6717back by the Lua interpreter:
6718the string is written between double quotes,
6719and all double quotes, newlines, embedded zeros,
6720and backslashes in the string
6721are correctly escaped when written.
6722For instance, the call
6723
6724<pre>
6725 string.format('%q', 'a string with "quotes" and \n new line')
6726</pre><p>
6727will produce the string:
6728
6729<pre>
6730 "a string with \"quotes\" and \
6731 new line"
6732</pre>
6733
6734<p>
6735The options <code>c</code>, <code>d</code>, <code>E</code>, <code>e</code>, <code>f</code>,
6736<code>g</code>, <code>G</code>, <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> all
6737expect a number as argument,
6738whereas <code>q</code> and <code>s</code> expect a string.
6739
6740
6741<p>
6742This function does not accept string values
6743containing embedded zeros,
6744except as arguments to the <code>q</code> option.
6745
6746
6747
6748
6749<p>
6750<hr><h3><a name="pdf-string.gmatch"><code>string.gmatch (s, pattern)</code></a></h3>
6751Returns an iterator function that,
6752each time it is called,
6753returns the next captures from <code>pattern</code> over string <code>s</code>.
6754If <code>pattern</code> specifies no captures,
6755then the whole match is produced in each call.
6756
6757
6758<p>
6759As an example, the following loop
6760
6761<pre>
6762 s = "hello world from Lua"
6763 for w in string.gmatch(s, "%a+") do
6764 print(w)
6765 end
6766</pre><p>
6767will iterate over all the words from string <code>s</code>,
6768printing one per line.
6769The next example collects all pairs <code>key=value</code> from the
6770given string into a table:
6771
6772<pre>
6773 t = {}
6774 s = "from=world, to=Lua"
6775 for k, v in string.gmatch(s, "(%w+)=(%w+)") do
6776 t[k] = v
6777 end
6778</pre>
6779
6780<p>
6781For this function, a '<code>^</code>' at the start of a pattern does not
6782work as an anchor, as this would prevent the iteration.
6783
6784
6785
6786
6787<p>
6788<hr><h3><a name="pdf-string.gsub"><code>string.gsub (s, pattern, repl [, n])</code></a></h3>
6789Returns a copy of <code>s</code>
6790in which all (or the first <code>n</code>, if given)
6791occurrences of the <code>pattern</code> have been
6792replaced by a replacement string specified by <code>repl</code>,
6793which can be a string, a table, or a function.
6794<code>gsub</code> also returns, as its second value,
6795the total number of matches that occurred.
6796
6797
6798<p>
6799If <code>repl</code> is a string, then its value is used for replacement.
6800The character&nbsp;<code>%</code> works as an escape character:
6801any sequence in <code>repl</code> of the form <code>%<em>n</em></code>,
6802with <em>n</em> between 1 and 9,
6803stands for the value of the <em>n</em>-th captured substring (see below).
6804The sequence <code>%0</code> stands for the whole match.
6805The sequence <code>%%</code> stands for a single&nbsp;<code>%</code>.
6806
6807
6808<p>
6809If <code>repl</code> is a table, then the table is queried for every match,
6810using the first capture as the key;
6811if the pattern specifies no captures,
6812then the whole match is used as the key.
6813
6814
6815<p>
6816If <code>repl</code> is a function, then this function is called every time a
6817match occurs, with all captured substrings passed as arguments,
6818in order;
6819if the pattern specifies no captures,
6820then the whole match is passed as a sole argument.
6821
6822
6823<p>
6824If the value returned by the table query or by the function call
6825is a string or a number,
6826then it is used as the replacement string;
6827otherwise, if it is <b>false</b> or <b>nil</b>,
6828then there is no replacement
6829(that is, the original match is kept in the string).
6830
6831
6832<p>
6833Here are some examples:
6834
6835<pre>
6836 x = string.gsub("hello world", "(%w+)", "%1 %1")
6837 --&gt; x="hello hello world world"
6838
6839 x = string.gsub("hello world", "%w+", "%0 %0", 1)
6840 --&gt; x="hello hello world"
6841
6842 x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
6843 --&gt; x="world hello Lua from"
6844
6845 x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
6846 --&gt; x="home = /home/roberto, user = roberto"
6847
6848 x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
6849 return loadstring(s)()
6850 end)
6851 --&gt; x="4+5 = 9"
6852
6853 local t = {name="lua", version="5.1"}
6854 x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
6855 --&gt; x="lua-5.1.tar.gz"
6856</pre>
6857
6858
6859
6860<p>
6861<hr><h3><a name="pdf-string.len"><code>string.len (s)</code></a></h3>
6862Receives a string and returns its length.
6863The empty string <code>""</code> has length 0.
6864Embedded zeros are counted,
6865so <code>"a\000bc\000"</code> has length 5.
6866
6867
6868
6869
6870<p>
6871<hr><h3><a name="pdf-string.lower"><code>string.lower (s)</code></a></h3>
6872Receives a string and returns a copy of this string with all
6873uppercase letters changed to lowercase.
6874All other characters are left unchanged.
6875The definition of what an uppercase letter is depends on the current locale.
6876
6877
6878
6879
6880<p>
6881<hr><h3><a name="pdf-string.match"><code>string.match (s, pattern [, init])</code></a></h3>
6882Looks for the first <em>match</em> of
6883<code>pattern</code> in the string <code>s</code>.
6884If it finds one, then <code>match</code> returns
6885the captures from the pattern;
6886otherwise it returns <b>nil</b>.
6887If <code>pattern</code> specifies no captures,
6888then the whole match is returned.
6889A third, optional numerical argument <code>init</code> specifies
6890where to start the search;
6891its default value is&nbsp;1 and can be negative.
6892
6893
6894
6895
6896<p>
6897<hr><h3><a name="pdf-string.rep"><code>string.rep (s, n)</code></a></h3>
6898Returns a string that is the concatenation of <code>n</code> copies of
6899the string <code>s</code>.
6900
6901
6902
6903
6904<p>
6905<hr><h3><a name="pdf-string.reverse"><code>string.reverse (s)</code></a></h3>
6906Returns a string that is the string <code>s</code> reversed.
6907
6908
6909
6910
6911<p>
6912<hr><h3><a name="pdf-string.sub"><code>string.sub (s, i [, j])</code></a></h3>
6913Returns the substring of <code>s</code> that
6914starts at <code>i</code> and continues until <code>j</code>;
6915<code>i</code> and <code>j</code> can be negative.
6916If <code>j</code> is absent, then it is assumed to be equal to -1
6917(which is the same as the string length).
6918In particular,
6919the call <code>string.sub(s,1,j)</code> returns a prefix of <code>s</code>
6920with length <code>j</code>,
6921and <code>string.sub(s, -i)</code> returns a suffix of <code>s</code>
6922with length <code>i</code>.
6923
6924
6925
6926
6927<p>
6928<hr><h3><a name="pdf-string.upper"><code>string.upper (s)</code></a></h3>
6929Receives a string and returns a copy of this string with all
6930lowercase letters changed to uppercase.
6931All other characters are left unchanged.
6932The definition of what a lowercase letter is depends on the current locale.
6933
6934
6935
6936<h3>5.4.1 - <a name="5.4.1">Patterns</a></h3>
6937
6938
6939<h4>Character Class:</h4><p>
6940A <em>character class</em> is used to represent a set of characters.
6941The following combinations are allowed in describing a character class:
6942
6943<ul>
6944
6945<li><b><em>x</em>:</b>
6946(where <em>x</em> is not one of the <em>magic characters</em>
6947<code>^$()%.[]*+-?</code>)
6948represents the character <em>x</em> itself.
6949</li>
6950
6951<li><b><code>.</code>:</b> (a dot) represents all characters.</li>
6952
6953<li><b><code>%a</code>:</b> represents all letters.</li>
6954
6955<li><b><code>%c</code>:</b> represents all control characters.</li>
6956
6957<li><b><code>%d</code>:</b> represents all digits.</li>
6958
6959<li><b><code>%l</code>:</b> represents all lowercase letters.</li>
6960
6961<li><b><code>%p</code>:</b> represents all punctuation characters.</li>
6962
6963<li><b><code>%s</code>:</b> represents all space characters.</li>
6964
6965<li><b><code>%u</code>:</b> represents all uppercase letters.</li>
6966
6967<li><b><code>%w</code>:</b> represents all alphanumeric characters.</li>
6968
6969<li><b><code>%x</code>:</b> represents all hexadecimal digits.</li>
6970
6971<li><b><code>%z</code>:</b> represents the character with representation 0.</li>
6972
6973<li><b><code>%<em>x</em></code>:</b> (where <em>x</em> is any non-alphanumeric character)
6974represents the character <em>x</em>.
6975This is the standard way to escape the magic characters.
6976Any punctuation character (even the non magic)
6977can be preceded by a '<code>%</code>'
6978when used to represent itself in a pattern.
6979</li>
6980
6981<li><b><code>[<em>set</em>]</code>:</b>
6982represents the class which is the union of all
6983characters in <em>set</em>.
6984A range of characters can be specified by
6985separating the end characters of the range with a '<code>-</code>'.
6986All classes <code>%</code><em>x</em> described above can also be used as
6987components in <em>set</em>.
6988All other characters in <em>set</em> represent themselves.
6989For example, <code>[%w_]</code> (or <code>[_%w]</code>)
6990represents all alphanumeric characters plus the underscore,
6991<code>[0-7]</code> represents the octal digits,
6992and <code>[0-7%l%-]</code> represents the octal digits plus
6993the lowercase letters plus the '<code>-</code>' character.
6994
6995
6996<p>
6997The interaction between ranges and classes is not defined.
6998Therefore, patterns like <code>[%a-z]</code> or <code>[a-%%]</code>
6999have no meaning.
7000</li>
7001
7002<li><b><code>[^<em>set</em>]</code>:</b>
7003represents the complement of <em>set</em>,
7004where <em>set</em> is interpreted as above.
7005</li>
7006
7007</ul><p>
7008For all classes represented by single letters (<code>%a</code>, <code>%c</code>, etc.),
7009the corresponding uppercase letter represents the complement of the class.
7010For instance, <code>%S</code> represents all non-space characters.
7011
7012
7013<p>
7014The definitions of letter, space, and other character groups
7015depend on the current locale.
7016In particular, the class <code>[a-z]</code> may not be equivalent to <code>%l</code>.
7017
7018
7019
7020
7021
7022<h4>Pattern Item:</h4><p>
7023A <em>pattern item</em> can be
7024
7025<ul>
7026
7027<li>
7028a single character class,
7029which matches any single character in the class;
7030</li>
7031
7032<li>
7033a single character class followed by '<code>*</code>',
7034which matches 0 or more repetitions of characters in the class.
7035These repetition items will always match the longest possible sequence;
7036</li>
7037
7038<li>
7039a single character class followed by '<code>+</code>',
7040which matches 1 or more repetitions of characters in the class.
7041These repetition items will always match the longest possible sequence;
7042</li>
7043
7044<li>
7045a single character class followed by '<code>-</code>',
7046which also matches 0 or more repetitions of characters in the class.
7047Unlike '<code>*</code>',
7048these repetition items will always match the <em>shortest</em> possible sequence;
7049</li>
7050
7051<li>
7052a single character class followed by '<code>?</code>',
7053which matches 0 or 1 occurrence of a character in the class;
7054</li>
7055
7056<li>
7057<code>%<em>n</em></code>, for <em>n</em> between 1 and 9;
7058such item matches a substring equal to the <em>n</em>-th captured string
7059(see below);
7060</li>
7061
7062<li>
7063<code>%b<em>xy</em></code>, where <em>x</em> and <em>y</em> are two distinct characters;
7064such item matches strings that start with&nbsp;<em>x</em>, end with&nbsp;<em>y</em>,
7065and where the <em>x</em> and <em>y</em> are <em>balanced</em>.
7066This means that, if one reads the string from left to right,
7067counting <em>+1</em> for an <em>x</em> and <em>-1</em> for a <em>y</em>,
7068the ending <em>y</em> is the first <em>y</em> where the count reaches 0.
7069For instance, the item <code>%b()</code> matches expressions with
7070balanced parentheses.
7071</li>
7072
7073</ul>
7074
7075
7076
7077
7078<h4>Pattern:</h4><p>
7079A <em>pattern</em> is a sequence of pattern items.
7080A '<code>^</code>' at the beginning of a pattern anchors the match at the
7081beginning of the subject string.
7082A '<code>$</code>' at the end of a pattern anchors the match at the
7083end of the subject string.
7084At other positions,
7085'<code>^</code>' and '<code>$</code>' have no special meaning and represent themselves.
7086
7087
7088
7089
7090
7091<h4>Captures:</h4><p>
7092A pattern can contain sub-patterns enclosed in parentheses;
7093they describe <em>captures</em>.
7094When a match succeeds, the substrings of the subject string
7095that match captures are stored (<em>captured</em>) for future use.
7096Captures are numbered according to their left parentheses.
7097For instance, in the pattern <code>"(a*(.)%w(%s*))"</code>,
7098the part of the string matching <code>"a*(.)%w(%s*)"</code> is
7099stored as the first capture (and therefore has number&nbsp;1);
7100the character matching "<code>.</code>" is captured with number&nbsp;2,
7101and the part matching "<code>%s*</code>" has number&nbsp;3.
7102
7103
7104<p>
7105As a special case, the empty capture <code>()</code> captures
7106the current string position (a number).
7107For instance, if we apply the pattern <code>"()aa()"</code> on the
7108string <code>"flaaap"</code>, there will be two captures: 3&nbsp;and&nbsp;5.
7109
7110
7111<p>
7112A pattern cannot contain embedded zeros. Use <code>%z</code> instead.
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124<h2>5.5 - <a name="5.5">Table Manipulation</a></h2><p>
7125This library provides generic functions for table manipulation.
7126It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>.
7127
7128
7129<p>
7130Most functions in the table library assume that the table
7131represents an array or a list.
7132For these functions, when we talk about the "length" of a table
7133we mean the result of the length operator.
7134
7135
7136<p>
7137<hr><h3><a name="pdf-table.concat"><code>table.concat (table [, sep [, i [, j]]])</code></a></h3>
7138Given an array where all elements are strings or numbers,
7139returns <code>table[i]..sep..table[i+1] &middot;&middot;&middot; sep..table[j]</code>.
7140The default value for <code>sep</code> is the empty string,
7141the default for <code>i</code> is 1,
7142and the default for <code>j</code> is the length of the table.
7143If <code>i</code> is greater than <code>j</code>, returns the empty string.
7144
7145
7146
7147
7148<p>
7149<hr><h3><a name="pdf-table.insert"><code>table.insert (table, [pos,] value)</code></a></h3>
7150
7151
7152<p>
7153Inserts element <code>value</code> at position <code>pos</code> in <code>table</code>,
7154shifting up other elements to open space, if necessary.
7155The default value for <code>pos</code> is <code>n+1</code>,
7156where <code>n</code> is the length of the table (see <a href="#2.5.5">&sect;2.5.5</a>),
7157so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end
7158of table <code>t</code>.
7159
7160
7161
7162
7163<p>
7164<hr><h3><a name="pdf-table.maxn"><code>table.maxn (table)</code></a></h3>
7165
7166
7167<p>
7168Returns the largest positive numerical index of the given table,
7169or zero if the table has no positive numerical indices.
7170(To do its job this function does a linear traversal of
7171the whole table.)
7172
7173
7174
7175
7176<p>
7177<hr><h3><a name="pdf-table.remove"><code>table.remove (table [, pos])</code></a></h3>
7178
7179
7180<p>
7181Removes from <code>table</code> the element at position <code>pos</code>,
7182shifting down other elements to close the space, if necessary.
7183Returns the value of the removed element.
7184The default value for <code>pos</code> is <code>n</code>,
7185where <code>n</code> is the length of the table,
7186so that a call <code>table.remove(t)</code> removes the last element
7187of table <code>t</code>.
7188
7189
7190
7191
7192<p>
7193<hr><h3><a name="pdf-table.sort"><code>table.sort (table [, comp])</code></a></h3>
7194Sorts table elements in a given order, <em>in-place</em>,
7195from <code>table[1]</code> to <code>table[n]</code>,
7196where <code>n</code> is the length of the table.
7197If <code>comp</code> is given,
7198then it must be a function that receives two table elements,
7199and returns true
7200when the first is less than the second
7201(so that <code>not comp(a[i+1],a[i])</code> will be true after the sort).
7202If <code>comp</code> is not given,
7203then the standard Lua operator <code>&lt;</code> is used instead.
7204
7205
7206<p>
7207The sort algorithm is not stable;
7208that is, elements considered equal by the given order
7209may have their relative positions changed by the sort.
7210
7211
7212
7213
7214
7215
7216
7217<h2>5.6 - <a name="5.6">Mathematical Functions</a></h2>
7218
7219<p>
7220This library is an interface to the standard C&nbsp;math library.
7221It provides all its functions inside the table <a name="pdf-math"><code>math</code></a>.
7222
7223
7224<p>
7225<hr><h3><a name="pdf-math.abs"><code>math.abs (x)</code></a></h3>
7226
7227
7228<p>
7229Returns the absolute value of <code>x</code>.
7230
7231
7232
7233
7234<p>
7235<hr><h3><a name="pdf-math.acos"><code>math.acos (x)</code></a></h3>
7236
7237
7238<p>
7239Returns the arc cosine of <code>x</code> (in radians).
7240
7241
7242
7243
7244<p>
7245<hr><h3><a name="pdf-math.asin"><code>math.asin (x)</code></a></h3>
7246
7247
7248<p>
7249Returns the arc sine of <code>x</code> (in radians).
7250
7251
7252
7253
7254<p>
7255<hr><h3><a name="pdf-math.atan"><code>math.atan (x)</code></a></h3>
7256
7257
7258<p>
7259Returns the arc tangent of <code>x</code> (in radians).
7260
7261
7262
7263
7264<p>
7265<hr><h3><a name="pdf-math.atan2"><code>math.atan2 (y, x)</code></a></h3>
7266
7267
7268<p>
7269Returns the arc tangent of <code>y/x</code> (in radians),
7270but uses the signs of both parameters to find the
7271quadrant of the result.
7272(It also handles correctly the case of <code>x</code> being zero.)
7273
7274
7275
7276
7277<p>
7278<hr><h3><a name="pdf-math.ceil"><code>math.ceil (x)</code></a></h3>
7279
7280
7281<p>
7282Returns the smallest integer larger than or equal to <code>x</code>.
7283
7284
7285
7286
7287<p>
7288<hr><h3><a name="pdf-math.cos"><code>math.cos (x)</code></a></h3>
7289
7290
7291<p>
7292Returns the cosine of <code>x</code> (assumed to be in radians).
7293
7294
7295
7296
7297<p>
7298<hr><h3><a name="pdf-math.cosh"><code>math.cosh (x)</code></a></h3>
7299
7300
7301<p>
7302Returns the hyperbolic cosine of <code>x</code>.
7303
7304
7305
7306
7307<p>
7308<hr><h3><a name="pdf-math.deg"><code>math.deg (x)</code></a></h3>
7309
7310
7311<p>
7312Returns the angle <code>x</code> (given in radians) in degrees.
7313
7314
7315
7316
7317<p>
7318<hr><h3><a name="pdf-math.exp"><code>math.exp (x)</code></a></h3>
7319
7320
7321<p>
7322Returns the value <em>e<sup>x</sup></em>.
7323
7324
7325
7326
7327<p>
7328<hr><h3><a name="pdf-math.floor"><code>math.floor (x)</code></a></h3>
7329
7330
7331<p>
7332Returns the largest integer smaller than or equal to <code>x</code>.
7333
7334
7335
7336
7337<p>
7338<hr><h3><a name="pdf-math.fmod"><code>math.fmod (x, y)</code></a></h3>
7339
7340
7341<p>
7342Returns the remainder of the division of <code>x</code> by <code>y</code>
7343that rounds the quotient towards zero.
7344
7345
7346
7347
7348<p>
7349<hr><h3><a name="pdf-math.frexp"><code>math.frexp (x)</code></a></h3>
7350
7351
7352<p>
7353Returns <code>m</code> and <code>e</code> such that <em>x = m2<sup>e</sup></em>,
7354<code>e</code> is an integer and the absolute value of <code>m</code> is
7355in the range <em>[0.5, 1)</em>
7356(or zero when <code>x</code> is zero).
7357
7358
7359
7360
7361<p>
7362<hr><h3><a name="pdf-math.huge"><code>math.huge</code></a></h3>
7363
7364
7365<p>
7366The value <code>HUGE_VAL</code>,
7367a value larger than or equal to any other numerical value.
7368
7369
7370
7371
7372<p>
7373<hr><h3><a name="pdf-math.ldexp"><code>math.ldexp (m, e)</code></a></h3>
7374
7375
7376<p>
7377Returns <em>m2<sup>e</sup></em> (<code>e</code> should be an integer).
7378
7379
7380
7381
7382<p>
7383<hr><h3><a name="pdf-math.log"><code>math.log (x)</code></a></h3>
7384
7385
7386<p>
7387Returns the natural logarithm of <code>x</code>.
7388
7389
7390
7391
7392<p>
7393<hr><h3><a name="pdf-math.log10"><code>math.log10 (x)</code></a></h3>
7394
7395
7396<p>
7397Returns the base-10 logarithm of <code>x</code>.
7398
7399
7400
7401
7402<p>
7403<hr><h3><a name="pdf-math.max"><code>math.max (x, &middot;&middot;&middot;)</code></a></h3>
7404
7405
7406<p>
7407Returns the maximum value among its arguments.
7408
7409
7410
7411
7412<p>
7413<hr><h3><a name="pdf-math.min"><code>math.min (x, &middot;&middot;&middot;)</code></a></h3>
7414
7415
7416<p>
7417Returns the minimum value among its arguments.
7418
7419
7420
7421
7422<p>
7423<hr><h3><a name="pdf-math.modf"><code>math.modf (x)</code></a></h3>
7424
7425
7426<p>
7427Returns two numbers,
7428the integral part of <code>x</code> and the fractional part of <code>x</code>.
7429
7430
7431
7432
7433<p>
7434<hr><h3><a name="pdf-math.pi"><code>math.pi</code></a></h3>
7435
7436
7437<p>
7438The value of <em>pi</em>.
7439
7440
7441
7442
7443<p>
7444<hr><h3><a name="pdf-math.pow"><code>math.pow (x, y)</code></a></h3>
7445
7446
7447<p>
7448Returns <em>x<sup>y</sup></em>.
7449(You can also use the expression <code>x^y</code> to compute this value.)
7450
7451
7452
7453
7454<p>
7455<hr><h3><a name="pdf-math.rad"><code>math.rad (x)</code></a></h3>
7456
7457
7458<p>
7459Returns the angle <code>x</code> (given in degrees) in radians.
7460
7461
7462
7463
7464<p>
7465<hr><h3><a name="pdf-math.random"><code>math.random ([m [, n]])</code></a></h3>
7466
7467
7468<p>
7469This function is an interface to the simple
7470pseudo-random generator function <code>rand</code> provided by ANSI&nbsp;C.
7471(No guarantees can be given for its statistical properties.)
7472
7473
7474<p>
7475When called without arguments,
7476returns a uniform pseudo-random real number
7477in the range <em>[0,1)</em>.
7478When called with an integer number <code>m</code>,
7479<code>math.random</code> returns
7480a uniform pseudo-random integer in the range <em>[1, m]</em>.
7481When called with two integer numbers <code>m</code> and <code>n</code>,
7482<code>math.random</code> returns a uniform pseudo-random
7483integer in the range <em>[m, n]</em>.
7484
7485
7486
7487
7488<p>
7489<hr><h3><a name="pdf-math.randomseed"><code>math.randomseed (x)</code></a></h3>
7490
7491
7492<p>
7493Sets <code>x</code> as the "seed"
7494for the pseudo-random generator:
7495equal seeds produce equal sequences of numbers.
7496
7497
7498
7499
7500<p>
7501<hr><h3><a name="pdf-math.sin"><code>math.sin (x)</code></a></h3>
7502
7503
7504<p>
7505Returns the sine of <code>x</code> (assumed to be in radians).
7506
7507
7508
7509
7510<p>
7511<hr><h3><a name="pdf-math.sinh"><code>math.sinh (x)</code></a></h3>
7512
7513
7514<p>
7515Returns the hyperbolic sine of <code>x</code>.
7516
7517
7518
7519
7520<p>
7521<hr><h3><a name="pdf-math.sqrt"><code>math.sqrt (x)</code></a></h3>
7522
7523
7524<p>
7525Returns the square root of <code>x</code>.
7526(You can also use the expression <code>x^0.5</code> to compute this value.)
7527
7528
7529
7530
7531<p>
7532<hr><h3><a name="pdf-math.tan"><code>math.tan (x)</code></a></h3>
7533
7534
7535<p>
7536Returns the tangent of <code>x</code> (assumed to be in radians).
7537
7538
7539
7540
7541<p>
7542<hr><h3><a name="pdf-math.tanh"><code>math.tanh (x)</code></a></h3>
7543
7544
7545<p>
7546Returns the hyperbolic tangent of <code>x</code>.
7547
7548
7549
7550
7551
7552
7553
7554<h2>5.7 - <a name="5.7">Input and Output Facilities</a></h2>
7555
7556<p>
7557The I/O library provides two different styles for file manipulation.
7558The first one uses implicit file descriptors;
7559that is, there are operations to set a default input file and a
7560default output file,
7561and all input/output operations are over these default files.
7562The second style uses explicit file descriptors.
7563
7564
7565<p>
7566When using implicit file descriptors,
7567all operations are supplied by table <a name="pdf-io"><code>io</code></a>.
7568When using explicit file descriptors,
7569the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file descriptor
7570and then all operations are supplied as methods of the file descriptor.
7571
7572
7573<p>
7574The table <code>io</code> also provides
7575three predefined file descriptors with their usual meanings from C:
7576<a name="pdf-io.stdin"><code>io.stdin</code></a>, <a name="pdf-io.stdout"><code>io.stdout</code></a>, and <a name="pdf-io.stderr"><code>io.stderr</code></a>.
7577The I/O library never closes these files.
7578
7579
7580<p>
7581Unless otherwise stated,
7582all I/O functions return <b>nil</b> on failure
7583(plus an error message as a second result and
7584a system-dependent error code as a third result)
7585and some value different from <b>nil</b> on success.
7586
7587
7588<p>
7589<hr><h3><a name="pdf-io.close"><code>io.close ([file])</code></a></h3>
7590
7591
7592<p>
7593Equivalent to <code>file:close()</code>.
7594Without a <code>file</code>, closes the default output file.
7595
7596
7597
7598
7599<p>
7600<hr><h3><a name="pdf-io.flush"><code>io.flush ()</code></a></h3>
7601
7602
7603<p>
7604Equivalent to <code>file:flush</code> over the default output file.
7605
7606
7607
7608
7609<p>
7610<hr><h3><a name="pdf-io.input"><code>io.input ([file])</code></a></h3>
7611
7612
7613<p>
7614When called with a file name, it opens the named file (in text mode),
7615and sets its handle as the default input file.
7616When called with a file handle,
7617it simply sets this file handle as the default input file.
7618When called without parameters,
7619it returns the current default input file.
7620
7621
7622<p>
7623In case of errors this function raises the error,
7624instead of returning an error code.
7625
7626
7627
7628
7629<p>
7630<hr><h3><a name="pdf-io.lines"><code>io.lines ([filename])</code></a></h3>
7631
7632
7633<p>
7634Opens the given file name in read mode
7635and returns an iterator function that,
7636each time it is called,
7637returns a new line from the file.
7638Therefore, the construction
7639
7640<pre>
7641 for line in io.lines(filename) do <em>body</em> end
7642</pre><p>
7643will iterate over all lines of the file.
7644When the iterator function detects the end of file,
7645it returns <b>nil</b> (to finish the loop) and automatically closes the file.
7646
7647
7648<p>
7649The call <code>io.lines()</code> (with no file name) is equivalent
7650to <code>io.input():lines()</code>;
7651that is, it iterates over the lines of the default input file.
7652In this case it does not close the file when the loop ends.
7653
7654
7655
7656
7657<p>
7658<hr><h3><a name="pdf-io.open"><code>io.open (filename [, mode])</code></a></h3>
7659
7660
7661<p>
7662This function opens a file,
7663in the mode specified in the string <code>mode</code>.
7664It returns a new file handle,
7665or, in case of errors, <b>nil</b> plus an error message.
7666
7667
7668<p>
7669The <code>mode</code> string can be any of the following:
7670
7671<ul>
7672<li><b>"r":</b> read mode (the default);</li>
7673<li><b>"w":</b> write mode;</li>
7674<li><b>"a":</b> append mode;</li>
7675<li><b>"r+":</b> update mode, all previous data is preserved;</li>
7676<li><b>"w+":</b> update mode, all previous data is erased;</li>
7677<li><b>"a+":</b> append update mode, previous data is preserved,
7678 writing is only allowed at the end of file.</li>
7679</ul><p>
7680The <code>mode</code> string can also have a '<code>b</code>' at the end,
7681which is needed in some systems to open the file in binary mode.
7682This string is exactly what is used in the
7683standard&nbsp;C function <code>fopen</code>.
7684
7685
7686
7687
7688<p>
7689<hr><h3><a name="pdf-io.output"><code>io.output ([file])</code></a></h3>
7690
7691
7692<p>
7693Similar to <a href="#pdf-io.input"><code>io.input</code></a>, but operates over the default output file.
7694
7695
7696
7697
7698<p>
7699<hr><h3><a name="pdf-io.popen"><code>io.popen (prog [, mode])</code></a></h3>
7700
7701
7702<p>
7703Starts program <code>prog</code> in a separated process and returns
7704a file handle that you can use to read data from this program
7705(if <code>mode</code> is <code>"r"</code>, the default)
7706or to write data to this program
7707(if <code>mode</code> is <code>"w"</code>).
7708
7709
7710<p>
7711This function is system dependent and is not available
7712on all platforms.
7713
7714
7715
7716
7717<p>
7718<hr><h3><a name="pdf-io.read"><code>io.read (&middot;&middot;&middot;)</code></a></h3>
7719
7720
7721<p>
7722Equivalent to <code>io.input():read</code>.
7723
7724
7725
7726
7727<p>
7728<hr><h3><a name="pdf-io.tmpfile"><code>io.tmpfile ()</code></a></h3>
7729
7730
7731<p>
7732Returns a handle for a temporary file.
7733This file is opened in update mode
7734and it is automatically removed when the program ends.
7735
7736
7737
7738
7739<p>
7740<hr><h3><a name="pdf-io.type"><code>io.type (obj)</code></a></h3>
7741
7742
7743<p>
7744Checks whether <code>obj</code> is a valid file handle.
7745Returns the string <code>"file"</code> if <code>obj</code> is an open file handle,
7746<code>"closed file"</code> if <code>obj</code> is a closed file handle,
7747or <b>nil</b> if <code>obj</code> is not a file handle.
7748
7749
7750
7751
7752<p>
7753<hr><h3><a name="pdf-io.write"><code>io.write (&middot;&middot;&middot;)</code></a></h3>
7754
7755
7756<p>
7757Equivalent to <code>io.output():write</code>.
7758
7759
7760
7761
7762<p>
7763<hr><h3><a name="pdf-file:close"><code>file:close ()</code></a></h3>
7764
7765
7766<p>
7767Closes <code>file</code>.
7768Note that files are automatically closed when
7769their handles are garbage collected,
7770but that takes an unpredictable amount of time to happen.
7771
7772
7773
7774
7775<p>
7776<hr><h3><a name="pdf-file:flush"><code>file:flush ()</code></a></h3>
7777
7778
7779<p>
7780Saves any written data to <code>file</code>.
7781
7782
7783
7784
7785<p>
7786<hr><h3><a name="pdf-file:lines"><code>file:lines ()</code></a></h3>
7787
7788
7789<p>
7790Returns an iterator function that,
7791each time it is called,
7792returns a new line from the file.
7793Therefore, the construction
7794
7795<pre>
7796 for line in file:lines() do <em>body</em> end
7797</pre><p>
7798will iterate over all lines of the file.
7799(Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file
7800when the loop ends.)
7801
7802
7803
7804
7805<p>
7806<hr><h3><a name="pdf-file:read"><code>file:read (&middot;&middot;&middot;)</code></a></h3>
7807
7808
7809<p>
7810Reads the file <code>file</code>,
7811according to the given formats, which specify what to read.
7812For each format,
7813the function returns a string (or a number) with the characters read,
7814or <b>nil</b> if it cannot read data with the specified format.
7815When called without formats,
7816it uses a default format that reads the entire next line
7817(see below).
7818
7819
7820<p>
7821The available formats are
7822
7823<ul>
7824
7825<li><b>"*n":</b>
7826reads a number;
7827this is the only format that returns a number instead of a string.
7828</li>
7829
7830<li><b>"*a":</b>
7831reads the whole file, starting at the current position.
7832On end of file, it returns the empty string.
7833</li>
7834
7835<li><b>"*l":</b>
7836reads the next line (skipping the end of line),
7837returning <b>nil</b> on end of file.
7838This is the default format.
7839</li>
7840
7841<li><b><em>number</em>:</b>
7842reads a string with up to this number of characters,
7843returning <b>nil</b> on end of file.
7844If number is zero,
7845it reads nothing and returns an empty string,
7846or <b>nil</b> on end of file.
7847</li>
7848
7849</ul>
7850
7851
7852
7853<p>
7854<hr><h3><a name="pdf-file:seek"><code>file:seek ([whence] [, offset])</code></a></h3>
7855
7856
7857<p>
7858Sets and gets the file position,
7859measured from the beginning of the file,
7860to the position given by <code>offset</code> plus a base
7861specified by the string <code>whence</code>, as follows:
7862
7863<ul>
7864<li><b>"set":</b> base is position 0 (beginning of the file);</li>
7865<li><b>"cur":</b> base is current position;</li>
7866<li><b>"end":</b> base is end of file;</li>
7867</ul><p>
7868In case of success, function <code>seek</code> returns the final file position,
7869measured in bytes from the beginning of the file.
7870If this function fails, it returns <b>nil</b>,
7871plus a string describing the error.
7872
7873
7874<p>
7875The default value for <code>whence</code> is <code>"cur"</code>,
7876and for <code>offset</code> is 0.
7877Therefore, the call <code>file:seek()</code> returns the current
7878file position, without changing it;
7879the call <code>file:seek("set")</code> sets the position to the
7880beginning of the file (and returns 0);
7881and the call <code>file:seek("end")</code> sets the position to the
7882end of the file, and returns its size.
7883
7884
7885
7886
7887<p>
7888<hr><h3><a name="pdf-file:setvbuf"><code>file:setvbuf (mode [, size])</code></a></h3>
7889
7890
7891<p>
7892Sets the buffering mode for an output file.
7893There are three available modes:
7894
7895<ul>
7896
7897<li><b>"no":</b>
7898no buffering; the result of any output operation appears immediately.
7899</li>
7900
7901<li><b>"full":</b>
7902full buffering; output operation is performed only
7903when the buffer is full (or when you explicitly <code>flush</code> the file
7904(see <a href="#pdf-io.flush"><code>io.flush</code></a>)).
7905</li>
7906
7907<li><b>"line":</b>
7908line buffering; output is buffered until a newline is output
7909or there is any input from some special files
7910(such as a terminal device).
7911</li>
7912
7913</ul><p>
7914For the last two cases, <code>size</code>
7915specifies the size of the buffer, in bytes.
7916The default is an appropriate size.
7917
7918
7919
7920
7921<p>
7922<hr><h3><a name="pdf-file:write"><code>file:write (&middot;&middot;&middot;)</code></a></h3>
7923
7924
7925<p>
7926Writes the value of each of its arguments to
7927the <code>file</code>.
7928The arguments must be strings or numbers.
7929To write other values,
7930use <a href="#pdf-tostring"><code>tostring</code></a> or <a href="#pdf-string.format"><code>string.format</code></a> before <code>write</code>.
7931
7932
7933
7934
7935
7936
7937
7938<h2>5.8 - <a name="5.8">Operating System Facilities</a></h2>
7939
7940<p>
7941This library is implemented through table <a name="pdf-os"><code>os</code></a>.
7942
7943
7944<p>
7945<hr><h3><a name="pdf-os.clock"><code>os.clock ()</code></a></h3>
7946
7947
7948<p>
7949Returns an approximation of the amount in seconds of CPU time
7950used by the program.
7951
7952
7953
7954
7955<p>
7956<hr><h3><a name="pdf-os.date"><code>os.date ([format [, time]])</code></a></h3>
7957
7958
7959<p>
7960Returns a string or a table containing date and time,
7961formatted according to the given string <code>format</code>.
7962
7963
7964<p>
7965If the <code>time</code> argument is present,
7966this is the time to be formatted
7967(see the <a href="#pdf-os.time"><code>os.time</code></a> function for a description of this value).
7968Otherwise, <code>date</code> formats the current time.
7969
7970
7971<p>
7972If <code>format</code> starts with '<code>!</code>',
7973then the date is formatted in Coordinated Universal Time.
7974After this optional character,
7975if <code>format</code> is the string "<code>*t</code>",
7976then <code>date</code> returns a table with the following fields:
7977<code>year</code> (four digits), <code>month</code> (1--12), <code>day</code> (1--31),
7978<code>hour</code> (0--23), <code>min</code> (0--59), <code>sec</code> (0--61),
7979<code>wday</code> (weekday, Sunday is&nbsp;1),
7980<code>yday</code> (day of the year),
7981and <code>isdst</code> (daylight saving flag, a boolean).
7982
7983
7984<p>
7985If <code>format</code> is not "<code>*t</code>",
7986then <code>date</code> returns the date as a string,
7987formatted according to the same rules as the C&nbsp;function <code>strftime</code>.
7988
7989
7990<p>
7991When called without arguments,
7992<code>date</code> returns a reasonable date and time representation that depends on
7993the host system and on the current locale
7994(that is, <code>os.date()</code> is equivalent to <code>os.date("%c")</code>).
7995
7996
7997
7998
7999<p>
8000<hr><h3><a name="pdf-os.difftime"><code>os.difftime (t2, t1)</code></a></h3>
8001
8002
8003<p>
8004Returns the number of seconds from time <code>t1</code> to time <code>t2</code>.
8005In POSIX, Windows, and some other systems,
8006this value is exactly <code>t2</code><em>-</em><code>t1</code>.
8007
8008
8009
8010
8011<p>
8012<hr><h3><a name="pdf-os.execute"><code>os.execute ([command])</code></a></h3>
8013
8014
8015<p>
8016This function is equivalent to the C&nbsp;function <code>system</code>.
8017It passes <code>command</code> to be executed by an operating system shell.
8018It returns a status code, which is system-dependent.
8019If <code>command</code> is absent, then it returns nonzero if a shell is available
8020and zero otherwise.
8021
8022
8023
8024
8025<p>
8026<hr><h3><a name="pdf-os.exit"><code>os.exit ([code])</code></a></h3>
8027
8028
8029<p>
8030Calls the C&nbsp;function <code>exit</code>,
8031with an optional <code>code</code>,
8032to terminate the host program.
8033The default value for <code>code</code> is the success code.
8034
8035
8036
8037
8038<p>
8039<hr><h3><a name="pdf-os.getenv"><code>os.getenv (varname)</code></a></h3>
8040
8041
8042<p>
8043Returns the value of the process environment variable <code>varname</code>,
8044or <b>nil</b> if the variable is not defined.
8045
8046
8047
8048
8049<p>
8050<hr><h3><a name="pdf-os.remove"><code>os.remove (filename)</code></a></h3>
8051
8052
8053<p>
8054Deletes the file or directory with the given name.
8055Directories must be empty to be removed.
8056If this function fails, it returns <b>nil</b>,
8057plus a string describing the error.
8058
8059
8060
8061
8062<p>
8063<hr><h3><a name="pdf-os.rename"><code>os.rename (oldname, newname)</code></a></h3>
8064
8065
8066<p>
8067Renames file or directory named <code>oldname</code> to <code>newname</code>.
8068If this function fails, it returns <b>nil</b>,
8069plus a string describing the error.
8070
8071
8072
8073
8074<p>
8075<hr><h3><a name="pdf-os.setlocale"><code>os.setlocale (locale [, category])</code></a></h3>
8076
8077
8078<p>
8079Sets the current locale of the program.
8080<code>locale</code> is a string specifying a locale;
8081<code>category</code> is an optional string describing which category to change:
8082<code>"all"</code>, <code>"collate"</code>, <code>"ctype"</code>,
8083<code>"monetary"</code>, <code>"numeric"</code>, or <code>"time"</code>;
8084the default category is <code>"all"</code>.
8085The function returns the name of the new locale,
8086or <b>nil</b> if the request cannot be honored.
8087
8088
8089<p>
8090If <code>locale</code> is the empty string,
8091the current locale is set to an implementation-defined native locale.
8092If <code>locale</code> is the string "<code>C</code>",
8093the current locale is set to the standard C locale.
8094
8095
8096<p>
8097When called with <b>nil</b> as the first argument,
8098this function only returns the name of the current locale
8099for the given category.
8100
8101
8102
8103
8104<p>
8105<hr><h3><a name="pdf-os.time"><code>os.time ([table])</code></a></h3>
8106
8107
8108<p>
8109Returns the current time when called without arguments,
8110or a time representing the date and time specified by the given table.
8111This table must have fields <code>year</code>, <code>month</code>, and <code>day</code>,
8112and may have fields <code>hour</code>, <code>min</code>, <code>sec</code>, and <code>isdst</code>
8113(for a description of these fields, see the <a href="#pdf-os.date"><code>os.date</code></a> function).
8114
8115
8116<p>
8117The returned value is a number, whose meaning depends on your system.
8118In POSIX, Windows, and some other systems, this number counts the number
8119of seconds since some given start time (the "epoch").
8120In other systems, the meaning is not specified,
8121and the number returned by <code>time</code> can be used only as an argument to
8122<code>date</code> and <code>difftime</code>.
8123
8124
8125
8126
8127<p>
8128<hr><h3><a name="pdf-os.tmpname"><code>os.tmpname ()</code></a></h3>
8129
8130
8131<p>
8132Returns a string with a file name that can
8133be used for a temporary file.
8134The file must be explicitly opened before its use
8135and explicitly removed when no longer needed.
8136
8137
8138<p>
8139On some systems (POSIX),
8140this function also creates a file with that name,
8141to avoid security risks.
8142(Someone else might create the file with wrong permissions
8143in the time between getting the name and creating the file.)
8144You still have to open the file to use it
8145and to remove it (even if you do not use it).
8146
8147
8148<p>
8149When possible,
8150you may prefer to use <a href="#pdf-io.tmpfile"><code>io.tmpfile</code></a>,
8151which automatically removes the file when the program ends.
8152
8153
8154
8155
8156
8157
8158
8159<h2>5.9 - <a name="5.9">The Debug Library</a></h2>
8160
8161<p>
8162This library provides
8163the functionality of the debug interface to Lua programs.
8164You should exert care when using this library.
8165The functions provided here should be used exclusively for debugging
8166and similar tasks, such as profiling.
8167Please resist the temptation to use them as a
8168usual programming tool:
8169they can be very slow.
8170Moreover, several of these functions
8171violate some assumptions about Lua code
8172(e.g., that variables local to a function
8173cannot be accessed from outside or
8174that userdata metatables cannot be changed by Lua code)
8175and therefore can compromise otherwise secure code.
8176
8177
8178<p>
8179All functions in this library are provided
8180inside the <a name="pdf-debug"><code>debug</code></a> table.
8181All functions that operate over a thread
8182have an optional first argument which is the
8183thread to operate over.
8184The default is always the current thread.
8185
8186
8187<p>
8188<hr><h3><a name="pdf-debug.debug"><code>debug.debug ()</code></a></h3>
8189
8190
8191<p>
8192Enters an interactive mode with the user,
8193running each string that the user enters.
8194Using simple commands and other debug facilities,
8195the user can inspect global and local variables,
8196change their values, evaluate expressions, and so on.
8197A line containing only the word <code>cont</code> finishes this function,
8198so that the caller continues its execution.
8199
8200
8201<p>
8202Note that commands for <code>debug.debug</code> are not lexically nested
8203within any function, and so have no direct access to local variables.
8204
8205
8206
8207
8208<p>
8209<hr><h3><a name="pdf-debug.getfenv"><code>debug.getfenv (o)</code></a></h3>
8210Returns the environment of object <code>o</code>.
8211
8212
8213
8214
8215<p>
8216<hr><h3><a name="pdf-debug.gethook"><code>debug.gethook ([thread])</code></a></h3>
8217
8218
8219<p>
8220Returns the current hook settings of the thread, as three values:
8221the current hook function, the current hook mask,
8222and the current hook count
8223(as set by the <a href="#pdf-debug.sethook"><code>debug.sethook</code></a> function).
8224
8225
8226
8227
8228<p>
8229<hr><h3><a name="pdf-debug.getinfo"><code>debug.getinfo ([thread,] function [, what])</code></a></h3>
8230
8231
8232<p>
8233Returns a table with information about a function.
8234You can give the function directly,
8235or you can give a number as the value of <code>function</code>,
8236which means the function running at level <code>function</code> of the call stack
8237of the given thread:
8238level&nbsp;0 is the current function (<code>getinfo</code> itself);
8239level&nbsp;1 is the function that called <code>getinfo</code>;
8240and so on.
8241If <code>function</code> is a number larger than the number of active functions,
8242then <code>getinfo</code> returns <b>nil</b>.
8243
8244
8245<p>
8246The returned table can contain all the fields returned by <a href="#lua_getinfo"><code>lua_getinfo</code></a>,
8247with the string <code>what</code> describing which fields to fill in.
8248The default for <code>what</code> is to get all information available,
8249except the table of valid lines.
8250If present,
8251the option '<code>f</code>'
8252adds a field named <code>func</code> with the function itself.
8253If present,
8254the option '<code>L</code>'
8255adds a field named <code>activelines</code> with the table of
8256valid lines.
8257
8258
8259<p>
8260For instance, the expression <code>debug.getinfo(1,"n").name</code> returns
8261a table with a name for the current function,
8262if a reasonable name can be found,
8263and the expression <code>debug.getinfo(print)</code>
8264returns a table with all available information
8265about the <a href="#pdf-print"><code>print</code></a> function.
8266
8267
8268
8269
8270<p>
8271<hr><h3><a name="pdf-debug.getlocal"><code>debug.getlocal ([thread,] level, local)</code></a></h3>
8272
8273
8274<p>
8275This function returns the name and the value of the local variable
8276with index <code>local</code> of the function at level <code>level</code> of the stack.
8277(The first parameter or local variable has index&nbsp;1, and so on,
8278until the last active local variable.)
8279The function returns <b>nil</b> if there is no local
8280variable with the given index,
8281and raises an error when called with a <code>level</code> out of range.
8282(You can call <a href="#pdf-debug.getinfo"><code>debug.getinfo</code></a> to check whether the level is valid.)
8283
8284
8285<p>
8286Variable names starting with '<code>(</code>' (open parentheses)
8287represent internal variables
8288(loop control variables, temporaries, and C&nbsp;function locals).
8289
8290
8291
8292
8293<p>
8294<hr><h3><a name="pdf-debug.getmetatable"><code>debug.getmetatable (object)</code></a></h3>
8295
8296
8297<p>
8298Returns the metatable of the given <code>object</code>
8299or <b>nil</b> if it does not have a metatable.
8300
8301
8302
8303
8304<p>
8305<hr><h3><a name="pdf-debug.getregistry"><code>debug.getregistry ()</code></a></h3>
8306
8307
8308<p>
8309Returns the registry table (see <a href="#3.5">&sect;3.5</a>).
8310
8311
8312
8313
8314<p>
8315<hr><h3><a name="pdf-debug.getupvalue"><code>debug.getupvalue (func, up)</code></a></h3>
8316
8317
8318<p>
8319This function returns the name and the value of the upvalue
8320with index <code>up</code> of the function <code>func</code>.
8321The function returns <b>nil</b> if there is no upvalue with the given index.
8322
8323
8324
8325
8326<p>
8327<hr><h3><a name="pdf-debug.setfenv"><code>debug.setfenv (object, table)</code></a></h3>
8328
8329
8330<p>
8331Sets the environment of the given <code>object</code> to the given <code>table</code>.
8332Returns <code>object</code>.
8333
8334
8335
8336
8337<p>
8338<hr><h3><a name="pdf-debug.sethook"><code>debug.sethook ([thread,] hook, mask [, count])</code></a></h3>
8339
8340
8341<p>
8342Sets the given function as a hook.
8343The string <code>mask</code> and the number <code>count</code> describe
8344when the hook will be called.
8345The string mask may have the following characters,
8346with the given meaning:
8347
8348<ul>
8349<li><b><code>"c"</code>:</b> the hook is called every time Lua calls a function;</li>
8350<li><b><code>"r"</code>:</b> the hook is called every time Lua returns from a function;</li>
8351<li><b><code>"l"</code>:</b> the hook is called every time Lua enters a new line of code.</li>
8352</ul><p>
8353With a <code>count</code> different from zero,
8354the hook is called after every <code>count</code> instructions.
8355
8356
8357<p>
8358When called without arguments,
8359<a href="#pdf-debug.sethook"><code>debug.sethook</code></a> turns off the hook.
8360
8361
8362<p>
8363When the hook is called, its first parameter is a string
8364describing the event that has triggered its call:
8365<code>"call"</code>, <code>"return"</code> (or <code>"tail return"</code>,
8366when simulating a return from a tail call),
8367<code>"line"</code>, and <code>"count"</code>.
8368For line events,
8369the hook also gets the new line number as its second parameter.
8370Inside a hook,
8371you can call <code>getinfo</code> with level&nbsp;2 to get more information about
8372the running function
8373(level&nbsp;0 is the <code>getinfo</code> function,
8374and level&nbsp;1 is the hook function),
8375unless the event is <code>"tail return"</code>.
8376In this case, Lua is only simulating the return,
8377and a call to <code>getinfo</code> will return invalid data.
8378
8379
8380
8381
8382<p>
8383<hr><h3><a name="pdf-debug.setlocal"><code>debug.setlocal ([thread,] level, local, value)</code></a></h3>
8384
8385
8386<p>
8387This function assigns the value <code>value</code> to the local variable
8388with index <code>local</code> of the function at level <code>level</code> of the stack.
8389The function returns <b>nil</b> if there is no local
8390variable with the given index,
8391and raises an error when called with a <code>level</code> out of range.
8392(You can call <code>getinfo</code> to check whether the level is valid.)
8393Otherwise, it returns the name of the local variable.
8394
8395
8396
8397
8398<p>
8399<hr><h3><a name="pdf-debug.setmetatable"><code>debug.setmetatable (object, table)</code></a></h3>
8400
8401
8402<p>
8403Sets the metatable for the given <code>object</code> to the given <code>table</code>
8404(which can be <b>nil</b>).
8405
8406
8407
8408
8409<p>
8410<hr><h3><a name="pdf-debug.setupvalue"><code>debug.setupvalue (func, up, value)</code></a></h3>
8411
8412
8413<p>
8414This function assigns the value <code>value</code> to the upvalue
8415with index <code>up</code> of the function <code>func</code>.
8416The function returns <b>nil</b> if there is no upvalue
8417with the given index.
8418Otherwise, it returns the name of the upvalue.
8419
8420
8421
8422
8423<p>
8424<hr><h3><a name="pdf-debug.traceback"><code>debug.traceback ([thread,] [message] [, level])</code></a></h3>
8425
8426
8427<p>
8428Returns a string with a traceback of the call stack.
8429An optional <code>message</code> string is appended
8430at the beginning of the traceback.
8431An optional <code>level</code> number tells at which level
8432to start the traceback
8433(default is 1, the function calling <code>traceback</code>).
8434
8435
8436
8437
8438
8439
8440
8441<h1>6 - <a name="6">Lua Stand-alone</a></h1>
8442
8443<p>
8444Although Lua has been designed as an extension language,
8445to be embedded in a host C&nbsp;program,
8446it is also frequently used as a stand-alone language.
8447An interpreter for Lua as a stand-alone language,
8448called simply <code>lua</code>,
8449is provided with the standard distribution.
8450The stand-alone interpreter includes
8451all standard libraries, including the debug library.
8452Its usage is:
8453
8454<pre>
8455 lua [options] [script [args]]
8456</pre><p>
8457The options are:
8458
8459<ul>
8460<li><b><code>-e <em>stat</em></code>:</b> executes string <em>stat</em>;</li>
8461<li><b><code>-l <em>mod</em></code>:</b> "requires" <em>mod</em>;</li>
8462<li><b><code>-i</code>:</b> enters interactive mode after running <em>script</em>;</li>
8463<li><b><code>-v</code>:</b> prints version information;</li>
8464<li><b><code>--</code>:</b> stops handling options;</li>
8465<li><b><code>-</code>:</b> executes <code>stdin</code> as a file and stops handling options.</li>
8466</ul><p>
8467After handling its options, <code>lua</code> runs the given <em>script</em>,
8468passing to it the given <em>args</em> as string arguments.
8469When called without arguments,
8470<code>lua</code> behaves as <code>lua -v -i</code>
8471when the standard input (<code>stdin</code>) is a terminal,
8472and as <code>lua -</code> otherwise.
8473
8474
8475<p>
8476Before running any argument,
8477the interpreter checks for an environment variable <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a>.
8478If its format is <code>@<em>filename</em></code>,
8479then <code>lua</code> executes the file.
8480Otherwise, <code>lua</code> executes the string itself.
8481
8482
8483<p>
8484All options are handled in order, except <code>-i</code>.
8485For instance, an invocation like
8486
8487<pre>
8488 $ lua -e'a=1' -e 'print(a)' script.lua
8489</pre><p>
8490will first set <code>a</code> to 1, then print the value of <code>a</code> (which is '<code>1</code>'),
8491and finally run the file <code>script.lua</code> with no arguments.
8492(Here <code>$</code> is the shell prompt. Your prompt may be different.)
8493
8494
8495<p>
8496Before starting to run the script,
8497<code>lua</code> collects all arguments in the command line
8498in a global table called <code>arg</code>.
8499The script name is stored at index 0,
8500the first argument after the script name goes to index 1,
8501and so on.
8502Any arguments before the script name
8503(that is, the interpreter name plus the options)
8504go to negative indices.
8505For instance, in the call
8506
8507<pre>
8508 $ lua -la b.lua t1 t2
8509</pre><p>
8510the interpreter first runs the file <code>a.lua</code>,
8511then creates a table
8512
8513<pre>
8514 arg = { [-2] = "lua", [-1] = "-la",
8515 [0] = "b.lua",
8516 [1] = "t1", [2] = "t2" }
8517</pre><p>
8518and finally runs the file <code>b.lua</code>.
8519The script is called with <code>arg[1]</code>, <code>arg[2]</code>, &middot;&middot;&middot;
8520as arguments;
8521it can also access these arguments with the vararg expression '<code>...</code>'.
8522
8523
8524<p>
8525In interactive mode,
8526if you write an incomplete statement,
8527the interpreter waits for its completion
8528by issuing a different prompt.
8529
8530
8531<p>
8532If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string,
8533then its value is used as the prompt.
8534Similarly, if the global variable <a name="pdf-_PROMPT2"><code>_PROMPT2</code></a> contains a string,
8535its value is used as the secondary prompt
8536(issued during incomplete statements).
8537Therefore, both prompts can be changed directly on the command line
8538or in any Lua programs by assigning to <code>_PROMPT</code>.
8539See the next example:
8540
8541<pre>
8542 $ lua -e"_PROMPT='myprompt&gt; '" -i
8543</pre><p>
8544(The outer pair of quotes is for the shell,
8545the inner pair is for Lua.)
8546Note the use of <code>-i</code> to enter interactive mode;
8547otherwise,
8548the program would just end silently
8549right after the assignment to <code>_PROMPT</code>.
8550
8551
8552<p>
8553To allow the use of Lua as a
8554script interpreter in Unix systems,
8555the stand-alone interpreter skips
8556the first line of a chunk if it starts with <code>#</code>.
8557Therefore, Lua scripts can be made into executable programs
8558by using <code>chmod +x</code> and the&nbsp;<code>#!</code> form,
8559as in
8560
8561<pre>
8562 #!/usr/local/bin/lua
8563</pre><p>
8564(Of course,
8565the location of the Lua interpreter may be different in your machine.
8566If <code>lua</code> is in your <code>PATH</code>,
8567then
8568
8569<pre>
8570 #!/usr/bin/env lua
8571</pre><p>
8572is a more portable solution.)
8573
8574
8575
8576<h1>7 - <a name="7">Incompatibilities with the Previous Version</a></h1>
8577
8578<p>
8579Here we list the incompatibilities that you may find when moving a program
8580from Lua&nbsp;5.0 to Lua&nbsp;5.1.
8581You can avoid most of the incompatibilities compiling Lua with
8582appropriate options (see file <code>luaconf.h</code>).
8583However,
8584all these compatibility options will be removed in the next version of Lua.
8585
8586
8587
8588<h2>7.1 - <a name="7.1">Changes in the Language</a></h2>
8589<ul>
8590
8591<li>
8592The vararg system changed from the pseudo-argument <code>arg</code> with a
8593table with the extra arguments to the vararg expression.
8594(See compile-time option <code>LUA_COMPAT_VARARG</code> in <code>luaconf.h</code>.)
8595</li>
8596
8597<li>
8598There was a subtle change in the scope of the implicit
8599variables of the <b>for</b> statement and for the <b>repeat</b> statement.
8600</li>
8601
8602<li>
8603The long string/long comment syntax (<code>[[<em>string</em>]]</code>)
8604does not allow nesting.
8605You can use the new syntax (<code>[=[<em>string</em>]=]</code>) in these cases.
8606(See compile-time option <code>LUA_COMPAT_LSTR</code> in <code>luaconf.h</code>.)
8607</li>
8608
8609</ul>
8610
8611
8612
8613
8614<h2>7.2 - <a name="7.2">Changes in the Libraries</a></h2>
8615<ul>
8616
8617<li>
8618Function <code>string.gfind</code> was renamed <a href="#pdf-string.gmatch"><code>string.gmatch</code></a>.
8619(See compile-time option <code>LUA_COMPAT_GFIND</code> in <code>luaconf.h</code>.)
8620</li>
8621
8622<li>
8623When <a href="#pdf-string.gsub"><code>string.gsub</code></a> is called with a function as its
8624third argument,
8625whenever this function returns <b>nil</b> or <b>false</b> the
8626replacement string is the whole match,
8627instead of the empty string.
8628</li>
8629
8630<li>
8631Function <code>table.setn</code> was deprecated.
8632Function <code>table.getn</code> corresponds
8633to the new length operator (<code>#</code>);
8634use the operator instead of the function.
8635(See compile-time option <code>LUA_COMPAT_GETN</code> in <code>luaconf.h</code>.)
8636</li>
8637
8638<li>
8639Function <code>loadlib</code> was renamed <a href="#pdf-package.loadlib"><code>package.loadlib</code></a>.
8640(See compile-time option <code>LUA_COMPAT_LOADLIB</code> in <code>luaconf.h</code>.)
8641</li>
8642
8643<li>
8644Function <code>math.mod</code> was renamed <a href="#pdf-math.fmod"><code>math.fmod</code></a>.
8645(See compile-time option <code>LUA_COMPAT_MOD</code> in <code>luaconf.h</code>.)
8646</li>
8647
8648<li>
8649Functions <code>table.foreach</code> and <code>table.foreachi</code> are deprecated.
8650You can use a for loop with <code>pairs</code> or <code>ipairs</code> instead.
8651</li>
8652
8653<li>
8654There were substantial changes in function <a href="#pdf-require"><code>require</code></a> due to
8655the new module system.
8656However, the new behavior is mostly compatible with the old,
8657but <code>require</code> gets the path from <a href="#pdf-package.path"><code>package.path</code></a> instead
8658of from <code>LUA_PATH</code>.
8659</li>
8660
8661<li>
8662Function <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> has different arguments.
8663Function <code>gcinfo</code> is deprecated;
8664use <code>collectgarbage("count")</code> instead.
8665</li>
8666
8667</ul>
8668
8669
8670
8671
8672<h2>7.3 - <a name="7.3">Changes in the API</a></h2>
8673<ul>
8674
8675<li>
8676The <code>luaopen_*</code> functions (to open libraries)
8677cannot be called directly,
8678like a regular C function.
8679They must be called through Lua,
8680like a Lua function.
8681</li>
8682
8683<li>
8684Function <code>lua_open</code> was replaced by <a href="#lua_newstate"><code>lua_newstate</code></a> to
8685allow the user to set a memory-allocation function.
8686You can use <a href="#luaL_newstate"><code>luaL_newstate</code></a> from the standard library to
8687create a state with a standard allocation function
8688(based on <code>realloc</code>).
8689</li>
8690
8691<li>
8692Functions <code>luaL_getn</code> and <code>luaL_setn</code>
8693(from the auxiliary library) are deprecated.
8694Use <a href="#lua_objlen"><code>lua_objlen</code></a> instead of <code>luaL_getn</code>
8695and nothing instead of <code>luaL_setn</code>.
8696</li>
8697
8698<li>
8699Function <code>luaL_openlib</code> was replaced by <a href="#luaL_register"><code>luaL_register</code></a>.
8700</li>
8701
8702<li>
8703Function <code>luaL_checkudata</code> now throws an error when the given value
8704is not a userdata of the expected type.
8705(In Lua&nbsp;5.0 it returned <code>NULL</code>.)
8706</li>
8707
8708</ul>
8709
8710
8711
8712
8713<h1>8 - <a name="8">The Complete Syntax of Lua</a></h1>
8714
8715<p>
8716Here is the complete syntax of Lua in extended BNF.
8717(It does not describe operator precedences.)
8718
8719
8720
8721
8722<pre>
8723
8724 chunk ::= {stat [`<b>;</b>&acute;]} [laststat [`<b>;</b>&acute;]]
8725
8726 block ::= chunk
8727
8728 stat ::= varlist `<b>=</b>&acute; explist |
8729 functioncall |
8730 <b>do</b> block <b>end</b> |
8731 <b>while</b> exp <b>do</b> block <b>end</b> |
8732 <b>repeat</b> block <b>until</b> exp |
8733 <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> |
8734 <b>for</b> Name `<b>=</b>&acute; exp `<b>,</b>&acute; exp [`<b>,</b>&acute; exp] <b>do</b> block <b>end</b> |
8735 <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> |
8736 <b>function</b> funcname funcbody |
8737 <b>local</b> <b>function</b> Name funcbody |
8738 <b>local</b> namelist [`<b>=</b>&acute; explist]
8739
8740 laststat ::= <b>return</b> [explist] | <b>break</b>
8741
8742 funcname ::= Name {`<b>.</b>&acute; Name} [`<b>:</b>&acute; Name]
8743
8744 varlist ::= var {`<b>,</b>&acute; var}
8745
8746 var ::= Name | prefixexp `<b>[</b>&acute; exp `<b>]</b>&acute; | prefixexp `<b>.</b>&acute; Name
8747
8748 namelist ::= Name {`<b>,</b>&acute; Name}
8749
8750 explist ::= {exp `<b>,</b>&acute;} exp
8751
8752 exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | `<b>...</b>&acute; | function |
8753 prefixexp | tableconstructor | exp binop exp | unop exp
8754
8755 prefixexp ::= var | functioncall | `<b>(</b>&acute; exp `<b>)</b>&acute;
8756
8757 functioncall ::= prefixexp args | prefixexp `<b>:</b>&acute; Name args
8758
8759 args ::= `<b>(</b>&acute; [explist] `<b>)</b>&acute; | tableconstructor | String
8760
8761 function ::= <b>function</b> funcbody
8762
8763 funcbody ::= `<b>(</b>&acute; [parlist] `<b>)</b>&acute; block <b>end</b>
8764
8765 parlist ::= namelist [`<b>,</b>&acute; `<b>...</b>&acute;] | `<b>...</b>&acute;
8766
8767 tableconstructor ::= `<b>{</b>&acute; [fieldlist] `<b>}</b>&acute;
8768
8769 fieldlist ::= field {fieldsep field} [fieldsep]
8770
8771 field ::= `<b>[</b>&acute; exp `<b>]</b>&acute; `<b>=</b>&acute; exp | Name `<b>=</b>&acute; exp | exp
8772
8773 fieldsep ::= `<b>,</b>&acute; | `<b>;</b>&acute;
8774
8775 binop ::= `<b>+</b>&acute; | `<b>-</b>&acute; | `<b>*</b>&acute; | `<b>/</b>&acute; | `<b>^</b>&acute; | `<b>%</b>&acute; | `<b>..</b>&acute; |
8776 `<b>&lt;</b>&acute; | `<b>&lt;=</b>&acute; | `<b>&gt;</b>&acute; | `<b>&gt;=</b>&acute; | `<b>==</b>&acute; | `<b>~=</b>&acute; |
8777 <b>and</b> | <b>or</b>
8778
8779 unop ::= `<b>-</b>&acute; | <b>not</b> | `<b>#</b>&acute;
8780
8781</pre>
8782
8783<p>
8784
8785
8786
8787
8788
8789
8790
8791<HR>
8792<SMALL>
8793Last update:
8794Mon Aug 18 13:25:46 BRT 2008
8795</SMALL>
8796<!--
8797Last change: revised for Lua 5.1.4
8798-->
8799
8800</body></html>
8801
diff --git a/libraries/LuaJIT-1.1.7/doc/readme.html b/libraries/LuaJIT-1.1.7/doc/readme.html
new file mode 100644
index 0000000..38be6db
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/readme.html
@@ -0,0 +1,40 @@
1<HTML>
2<HEAD>
3<TITLE>Lua documentation</TITLE>
4<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
5</HEAD>
6
7<BODY>
8
9<HR>
10<H1>
11<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A>
12Documentation
13</H1>
14
15This is the documentation included in the source distribution of Lua 5.1.4.
16
17<UL>
18<LI><A HREF="contents.html">Reference manual</A>
19<LI><A HREF="lua.html">lua man page</A>
20<LI><A HREF="luac.html">luac man page</A>
21<LI><A HREF="../README">lua/README</A>
22<LI><A HREF="../etc/README">lua/etc/README</A>
23<LI><A HREF="../test/README">lua/test/README</A>
24</UL>
25
26Lua's
27<A HREF="http://www.lua.org/">official web site</A>
28contains updated documentation,
29especially the
30<A HREF="http://www.lua.org/manual/5.1/">reference manual</A>.
31<P>
32
33<HR>
34<SMALL>
35Last update:
36Tue Aug 12 14:46:07 BRT 2008
37</SMALL>
38
39</BODY>
40</HTML>
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h b/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h
new file mode 100644
index 0000000..c194cba
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h
@@ -0,0 +1,68 @@
1/*
2** DynASM encoding engine prototypes.
3** Copyright (C) 2005-2008 Mike Pall. All rights reserved.
4** Released under the MIT/X license. See dynasm.lua for full copyright notice.
5*/
6
7#ifndef _DASM_PROTO_H
8#define _DASM_PROTO_H
9
10#include <stddef.h>
11#include <stdarg.h>
12
13#define DASM_VERSION 10104 /* 1.1.4 */
14
15#ifndef Dst_DECL
16#define Dst_DECL dasm_State *Dst
17#endif
18
19#ifndef Dst_GET
20#define Dst_GET (Dst)
21#endif
22
23#ifndef DASM_FDEF
24#define DASM_FDEF extern
25#endif
26
27
28/* Internal DynASM encoder state. */
29typedef struct dasm_State dasm_State;
30
31/* Action list type. */
32typedef const unsigned char *dasm_ActList;
33
34
35/* Initialize and free DynASM state. */
36DASM_FDEF void dasm_init(Dst_DECL, int maxsection);
37DASM_FDEF void dasm_free(Dst_DECL);
38
39/* Setup global array. Must be called before dasm_setup(). */
40DASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl);
41
42/* Grow PC label array. Can be called after dasm_setup(), too. */
43DASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc);
44
45/* Setup encoder. */
46DASM_FDEF void dasm_setup(Dst_DECL, dasm_ActList actionlist);
47
48/* Feed encoder with actions. Calls are generated by pre-processor. */
49DASM_FDEF void dasm_put(Dst_DECL, int start, ...);
50
51/* Link sections and return the resulting size. */
52DASM_FDEF int dasm_link(Dst_DECL, size_t *szp);
53
54/* Encode sections into buffer. */
55DASM_FDEF int dasm_encode(Dst_DECL, void *buffer);
56
57/* Get PC label offset. */
58DASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc);
59
60#ifdef DASM_CHECKS
61/* Optional sanity checker to call between isolated encoding steps. */
62DASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch);
63#else
64#define dasm_checkstep(a, b) 0
65#endif
66
67
68#endif /* _DASM_PROTO_H */
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h
new file mode 100644
index 0000000..2d4fb26
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h
@@ -0,0 +1,455 @@
1/*
2** DynASM x86 encoding engine.
3** Copyright (C) 2005-2008 Mike Pall. All rights reserved.
4** Released under the MIT/X license. See dynasm.lua for full copyright notice.
5*/
6
7#include <stddef.h>
8#include <stdarg.h>
9#include <string.h>
10#include <stdlib.h>
11
12#define DASM_ARCH "x86"
13
14/* Action definitions. DASM_STOP must be 255. */
15enum {
16 DASM_DISP = 235,
17 DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
18 DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC, DASM_IMM_LG,
19 DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN, DASM_ESC, DASM_MARK,
20 DASM_SECTION, DASM_STOP
21};
22
23/* Maximum number of section buffer positions for a single dasm_put() call. */
24#define DASM_MAXSECPOS 25
25
26/* DynASM encoder status codes. Action list offset or number are or'ed in. */
27#define DASM_S_OK 0x00000000
28#define DASM_S_NOMEM 0x01000000
29#define DASM_S_PHASE 0x02000000
30#define DASM_S_MATCH_SEC 0x03000000
31#define DASM_S_RANGE_I 0x11000000
32#define DASM_S_RANGE_SEC 0x12000000
33#define DASM_S_RANGE_LG 0x13000000
34#define DASM_S_RANGE_PC 0x14000000
35#define DASM_S_UNDEF_L 0x21000000
36#define DASM_S_UNDEF_PC 0x22000000
37
38/* Macros to convert positions (8 bit section + 24 bit index). */
39#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
40#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
41#define DASM_SEC2POS(sec) ((sec)<<24)
42#define DASM_POS2SEC(pos) ((pos)>>24)
43#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
44
45/* Per-section structure. */
46typedef struct dasm_Section {
47 int *rbuf; /* Biased buffer pointer (negative section bias). */
48 int *buf; /* True buffer pointer. */
49 size_t bsize; /* Buffer size in bytes. */
50 int pos; /* Biased buffer position. */
51 int epos; /* End of biased buffer position - max single put. */
52 int ofs; /* Byte offset into section. */
53} dasm_Section;
54
55/* Core structure holding the DynASM encoding state. */
56struct dasm_State {
57 size_t psize; /* Allocated size of this structure. */
58 dasm_ActList actionlist; /* Current actionlist pointer. */
59 int *lglabels; /* Local/global chain/pos ptrs. */
60 size_t lgsize;
61 int *pclabels; /* PC label chains/pos ptrs. */
62 size_t pcsize;
63 void **globals; /* Array of globals (bias -10). */
64 dasm_Section *section; /* Pointer to active section. */
65 size_t codesize; /* Total size of all code sections. */
66 int maxsection; /* 0 <= sectionidx < maxsection. */
67 int status; /* Status code. */
68 dasm_Section sections[1]; /* All sections. Alloc-extended. */
69};
70
71/* The size of the core structure depends on the max. number of sections. */
72#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
73
74
75/* Initialize DynASM state. */
76void dasm_init(Dst_DECL, int maxsection)
77{
78 dasm_State *D;
79 size_t psz = 0;
80 int i;
81 Dst_REF = NULL;
82 DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
83 D = Dst_REF;
84 D->psize = psz;
85 D->lglabels = NULL;
86 D->lgsize = 0;
87 D->pclabels = NULL;
88 D->pcsize = 0;
89 D->globals = NULL;
90 D->maxsection = maxsection;
91 for (i = 0; i < maxsection; i++) {
92 D->sections[i].buf = NULL; /* Need this for pass3. */
93 D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
94 D->sections[i].bsize = 0;
95 D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
96 }
97}
98
99/* Free DynASM state. */
100void dasm_free(Dst_DECL)
101{
102 dasm_State *D = Dst_REF;
103 int i;
104 for (i = 0; i < D->maxsection; i++)
105 if (D->sections[i].buf)
106 DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
107 if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
108 if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
109 DASM_M_FREE(Dst, D, D->psize);
110}
111
112/* Setup global label array. Must be called before dasm_setup(). */
113void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
114{
115 dasm_State *D = Dst_REF;
116 D->globals = gl - 10; /* Negative bias to compensate for locals. */
117 DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
118}
119
120/* Grow PC label array. Can be called after dasm_setup(), too. */
121void dasm_growpc(Dst_DECL, unsigned int maxpc)
122{
123 dasm_State *D = Dst_REF;
124 size_t osz = D->pcsize;
125 DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
126 memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
127}
128
129/* Setup encoder. */
130void dasm_setup(Dst_DECL, dasm_ActList actionlist)
131{
132 dasm_State *D = Dst_REF;
133 int i;
134 D->actionlist = actionlist;
135 D->status = DASM_S_OK;
136 D->section = &D->sections[0];
137 memset((void *)D->lglabels, 0, D->lgsize);
138 if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
139 for (i = 0; i < D->maxsection; i++) {
140 D->sections[i].pos = DASM_SEC2POS(i);
141 D->sections[i].ofs = 0;
142 }
143}
144
145
146#ifdef DASM_CHECKS
147#define CK(x, st) \
148 do { if (!(x)) { \
149 D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
150#define CKPL(kind, st) \
151 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
152 D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
153#else
154#define CK(x, st) ((void)0)
155#define CKPL(kind, st) ((void)0)
156#endif
157
158/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
159void dasm_put(Dst_DECL, int start, ...)
160{
161 va_list ap;
162 dasm_State *D = Dst_REF;
163 dasm_ActList p = D->actionlist + start;
164 dasm_Section *sec = D->section;
165 int pos = sec->pos, ofs = sec->ofs, mrm = 4;
166 int *b;
167
168 if (pos >= sec->epos) {
169 DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
170 sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
171 sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
172 sec->epos = sec->bsize/sizeof(int) - DASM_MAXSECPOS + DASM_POS2BIAS(pos);
173 }
174
175 b = sec->rbuf;
176 b[pos++] = start;
177
178 va_start(ap, start);
179 while (1) {
180 int action = *p++;
181 if (action < DASM_DISP) {
182 ofs++;
183 } else if (action <= DASM_REL_A) {
184 int n = va_arg(ap, int);
185 b[pos++] = n;
186 switch (action) {
187 case DASM_DISP:
188 if (n == 0) { if ((mrm&7) == 4) mrm = p[-2]; if ((mrm&7) != 5) break; }
189 case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob;
190 case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
191 case DASM_IMM_D: ofs += 4; break;
192 case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
193 case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
194 case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob;
195 case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
196 case DASM_SPACE: p++; ofs += n; break;
197 case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */
198 }
199 mrm = 4;
200 } else {
201 int *pl, n;
202 switch (action) {
203 case DASM_REL_LG:
204 case DASM_IMM_LG:
205 n = *p++; pl = D->lglabels + n;
206 if (n <= 246) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
207 pl -= 246; n = *pl;
208 if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
209 goto linkrel;
210 case DASM_REL_PC:
211 case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
212 putrel:
213 n = *pl;
214 if (n < 0) { /* Label exists. Get label pos and store it. */
215 b[pos] = -n;
216 } else {
217 linkrel:
218 b[pos] = n; /* Else link to rel chain, anchored at label. */
219 *pl = pos;
220 }
221 pos++;
222 ofs += 4; /* Maximum offset needed. */
223 if (action == DASM_REL_LG || action == DASM_REL_PC)
224 b[pos++] = ofs; /* Store pass1 offset estimate. */
225 break;
226 case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
227 case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
228 putlabel:
229 n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
230 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; }
231 *pl = -pos; /* Label exists now. */
232 b[pos++] = ofs; /* Store pass1 offset estimate. */
233 break;
234 case DASM_ALIGN:
235 ofs += *p++; /* Maximum alignment needed (arg is 2**n-1). */
236 b[pos++] = ofs; /* Store pass1 offset estimate. */
237 break;
238 case DASM_ESC: p++; ofs++; break;
239 case DASM_MARK: mrm = p[-2]; break;
240 case DASM_SECTION:
241 n = *p; CK(n < D->maxsection, RANGE_SEC); D->section = &D->sections[n];
242 case DASM_STOP: goto stop;
243 }
244 }
245 }
246stop:
247 va_end(ap);
248 sec->pos = pos;
249 sec->ofs = ofs;
250}
251#undef CK
252
253/* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */
254int dasm_link(Dst_DECL, size_t *szp)
255{
256 dasm_State *D = Dst_REF;
257 int secnum;
258 int ofs = 0;
259
260#ifdef DASM_CHECKS
261 *szp = 0;
262 if (D->status != DASM_S_OK) return D->status;
263 {
264 int pc;
265 for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
266 if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
267 }
268#endif
269
270 { /* Handle globals not defined in this translation unit. */
271 int idx;
272 for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
273 int n = D->lglabels[idx];
274 /* Undefined label: Collapse rel chain and replace with marker (< 0). */
275 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
276 }
277 }
278
279 /* Combine all code sections. No support for data sections (yet). */
280 for (secnum = 0; secnum < D->maxsection; secnum++) {
281 dasm_Section *sec = D->sections + secnum;
282 int *b = sec->rbuf;
283 int pos = DASM_SEC2POS(secnum);
284 int lastpos = sec->pos;
285
286 while (pos != lastpos) {
287 dasm_ActList p = D->actionlist + b[pos++];
288 while (1) {
289 int op, action = *p++;
290 switch (action) {
291 case DASM_REL_LG: p++; op = p[-3]; goto rel_pc;
292 case DASM_REL_PC: op = p[-2]; rel_pc: {
293 int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
294 if (shrink) { /* Shrinkable branch opcode? */
295 int lofs, lpos = b[pos];
296 if (lpos < 0) goto noshrink; /* Ext global? */
297 lofs = *DASM_POS2PTR(D, lpos);
298 if (lpos > pos) { /* Fwd label: add cumulative section offsets. */
299 int i;
300 for (i = secnum; i < DASM_POS2SEC(lpos); i++)
301 lofs += D->sections[i].ofs;
302 } else {
303 lofs -= ofs; /* Bkwd label: unfix offset. */
304 }
305 lofs -= b[pos+1]; /* Short branch ok? */
306 if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink; /* Yes. */
307 else { noshrink: shrink = 0; } /* No, cannot shrink op. */
308 }
309 b[pos+1] = shrink;
310 pos += 2;
311 break;
312 }
313 case DASM_SPACE: case DASM_IMM_LG: p++;
314 case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
315 case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
316 case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
317 case DASM_LABEL_LG: p++;
318 case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
319 case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
320 case DASM_ESC: p++;
321 case DASM_MARK: break;
322 case DASM_SECTION: case DASM_STOP: goto stop;
323 }
324 }
325 stop: (void)0;
326 }
327 ofs += sec->ofs; /* Next section starts right after current section. */
328 }
329
330 D->codesize = ofs; /* Total size of all code sections */
331 *szp = ofs;
332 return DASM_S_OK;
333}
334
335#define dasmb(x) *cp++ = (unsigned char)(x)
336#ifndef DASM_ALIGNED_WRITES
337#define dasmw(x) \
338 do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
339#define dasmd(x) \
340 do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
341#else
342#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
343#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
344#endif
345
346/* Pass 3: Encode sections. */
347int dasm_encode(Dst_DECL, void *buffer)
348{
349 dasm_State *D = Dst_REF;
350 unsigned char *base = (unsigned char *)buffer;
351 unsigned char *cp = base;
352 int secnum;
353
354 /* Encode all code sections. No support for data sections (yet). */
355 for (secnum = 0; secnum < D->maxsection; secnum++) {
356 dasm_Section *sec = D->sections + secnum;
357 int *b = sec->buf;
358 int *endb = sec->rbuf + sec->pos;
359
360 while (b != endb) {
361 dasm_ActList p = D->actionlist + *b++;
362 unsigned char *mark = NULL;
363 while (1) {
364 int action = *p++;
365 int n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0;
366 switch (action) {
367 case DASM_DISP: if (!mark) mark = cp; {
368 unsigned char *mm = mark;
369 if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL;
370 if (n == 0) { int mrm = mm[-1]&7; if (mrm == 4) mrm = mm[0]&7;
371 if (mrm != 5) { mm[-1] -= 0x80; break; } }
372 if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;
373 }
374 case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;
375 case DASM_IMM_DB: if (((n+128)&-256) == 0) {
376 db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;
377 } else mark = NULL;
378 case DASM_IMM_D: wd: dasmd(n); break;
379 case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
380 case DASM_IMM_W: dasmw(n); break;
381 case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
382 b++; n = (int)D->globals[-n];
383 case DASM_REL_A: rel_a: n -= (int)(cp+4); goto wd; /* !x64 */
384 case DASM_REL_PC: rel_pc: {
385 int shrink = *b++;
386 int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }
387 n = *pb - ((cp-base) + 4-shrink);
388 if (shrink == 0) goto wd;
389 if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb;
390 goto wb;
391 }
392 case DASM_IMM_LG: p++; if (n < 0) { n = (int)D->globals[-n]; goto wd; }
393 case DASM_IMM_PC: {
394 int *pb = DASM_POS2PTR(D, n);
395 n = *pb < 0 ? pb[1] : (*pb + (ptrdiff_t)base);
396 goto wd;
397 }
398 case DASM_LABEL_LG: {
399 int idx = *p++;
400 if (idx >= 10)
401 D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
402 break;
403 }
404 case DASM_LABEL_PC: case DASM_SETLABEL: break;
405 case DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; }
406 case DASM_ALIGN:
407 n = *p++;
408 while (((cp-base) & n)) *cp++ = 0x90; /* nop */
409 break;
410 case DASM_MARK: mark = cp; break;
411 case DASM_ESC: action = *p++;
412 default: *cp++ = action; break;
413 case DASM_SECTION: case DASM_STOP: goto stop;
414 }
415 }
416 stop: (void)0;
417 }
418 }
419
420 if (base + D->codesize != cp) /* Check for phase errors. */
421 return DASM_S_PHASE;
422 return DASM_S_OK;
423}
424
425/* Get PC label offset. */
426int dasm_getpclabel(Dst_DECL, unsigned int pc)
427{
428 dasm_State *D = Dst_REF;
429 if (pc*sizeof(int) < D->pcsize) {
430 int pos = D->pclabels[pc];
431 if (pos < 0) return *DASM_POS2PTR(D, -pos);
432 if (pos > 0) return -1; /* Undefined. */
433 }
434 return -2; /* Unused or out of range. */
435}
436
437#ifdef DASM_CHECKS
438/* Optional sanity checker to call between isolated encoding steps. */
439int dasm_checkstep(Dst_DECL, int secmatch)
440{
441 dasm_State *D = Dst_REF;
442 if (D->status == DASM_S_OK) {
443 int i;
444 for (i = 1; i <= 9; i++) {
445 if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; }
446 D->lglabels[i] = 0;
447 }
448 }
449 if (D->status == DASM_S_OK && secmatch >= 0 &&
450 D->section != &D->sections[secmatch])
451 D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
452 return D->status;
453}
454#endif
455
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua
new file mode 100644
index 0000000..026c3b0
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua
@@ -0,0 +1,1581 @@
1------------------------------------------------------------------------------
2-- DynASM x86 module.
3--
4-- Copyright (C) 2005-2008 Mike Pall. All rights reserved.
5-- See dynasm.lua for full copyright notice.
6------------------------------------------------------------------------------
7
8-- Module information:
9local _info = {
10 arch = "x86",
11 description = "DynASM x86 (i386) module",
12 version = "1.1.4",
13 vernum = 10104,
14 release = "2008-01-29",
15 author = "Mike Pall",
16 license = "MIT",
17}
18
19-- Exported glue functions for the arch-specific module.
20local _M = { _info = _info }
21
22-- Cache library functions.
23local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
24local assert, unpack = assert, unpack
25local _s = string
26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
27local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
28local concat, sort = table.concat, table.sort
29local char, unpack = string.char, unpack
30
31-- Inherited tables and callbacks.
32local g_opt, g_arch
33local wline, werror, wfatal, wwarn
34
35-- Action name list.
36-- CHECK: Keep this in sync with the C code!
37local action_names = {
38 -- int arg, 1 buffer pos:
39 "DISP", "IMM_S", "IMM_B", "IMM_W", "IMM_D", "IMM_WB", "IMM_DB",
40 -- action arg (1 byte), int arg, 1 buffer pos (num):
41 "SPACE",
42 -- ptrdiff_t arg, 1 buffer pos (address): !x64
43 "SETLABEL", "REL_A",
44 -- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
45 "REL_LG", "REL_PC",
46 -- action arg (1 byte) or int arg, 1 buffer pos (link):
47 "IMM_LG", "IMM_PC",
48 -- action arg (1 byte) or int arg, 1 buffer pos (offset):
49 "LABEL_LG", "LABEL_PC",
50 -- action arg (1 byte), 1 buffer pos (offset):
51 "ALIGN",
52 -- action arg (1 byte), no buffer pos.
53 "ESC",
54 -- no action arg, no buffer pos.
55 "MARK",
56 -- action arg (1 byte), no buffer pos, terminal action:
57 "SECTION",
58 -- no args, no buffer pos, terminal action:
59 "STOP"
60}
61
62-- Maximum number of section buffer positions for dasm_put().
63-- CHECK: Keep this in sync with the C code!
64local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
65
66-- Action name -> action number (dynamically generated below).
67local map_action = {}
68-- First action number. Everything below does not need to be escaped.
69local actfirst = 256-#action_names
70
71-- Action list buffer and string (only used to remove dupes).
72local actlist = {}
73local actstr = ""
74
75-- Argument list for next dasm_put(). Start with offset 0 into action list.
76local actargs = { 0 }
77
78-- Current number of section buffer positions for dasm_put().
79local secpos = 1
80
81------------------------------------------------------------------------------
82
83-- Compute action numbers for action names.
84for n,name in ipairs(action_names) do
85 local num = actfirst + n - 1
86 map_action[name] = num
87end
88
89-- Dump action names and numbers.
90local function dumpactions(out)
91 out:write("DynASM encoding engine action codes:\n")
92 for n,name in ipairs(action_names) do
93 local num = map_action[name]
94 out:write(format(" %-10s %02X %d\n", name, num, num))
95 end
96 out:write("\n")
97end
98
99-- Write action list buffer as a huge static C array.
100local function writeactions(out, name)
101 local nn = #actlist
102 local last = actlist[nn] or 255
103 actlist[nn] = nil -- Remove last byte.
104 if nn == 0 then nn = 1 end
105 out:write("static const unsigned char ", name, "[", nn, "] = {\n")
106 local s = " "
107 for n,b in ipairs(actlist) do
108 s = s..b..","
109 if #s >= 75 then
110 assert(out:write(s, "\n"))
111 s = " "
112 end
113 end
114 out:write(s, last, "\n};\n\n") -- Add last byte back.
115end
116
117------------------------------------------------------------------------------
118
119-- Add byte to action list.
120local function wputxb(n)
121 assert(n >= 0 and n <= 255 and n % 1 == 0, "byte out of range")
122 actlist[#actlist+1] = n
123end
124
125-- Add action to list with optional arg. Advance buffer pos, too.
126local function waction(action, a, num)
127 wputxb(assert(map_action[action], "bad action name `"..action.."'"))
128 if a then actargs[#actargs+1] = a end
129 if a or num then secpos = secpos + (num or 1) end
130end
131
132-- Add call to embedded DynASM C code.
133local function wcall(func, args)
134 wline(format("dasm_%s(Dst, %s);", func, concat(args, ", ")), true)
135end
136
137-- Delete duplicate action list chunks. A tad slow, but so what.
138local function dedupechunk(offset)
139 local al, as = actlist, actstr
140 local chunk = char(unpack(al, offset+1, #al))
141 local orig = find(as, chunk, 1, true)
142 if orig then
143 actargs[1] = orig-1 -- Replace with original offset.
144 for i=offset+1,#al do al[i] = nil end -- Kill dupe.
145 else
146 actstr = as..chunk
147 end
148end
149
150-- Flush action list (intervening C code or buffer pos overflow).
151local function wflush(term)
152 local offset = actargs[1]
153 if #actlist == offset then return end -- Nothing to flush.
154 if not term then waction("STOP") end -- Terminate action list.
155 dedupechunk(offset)
156 wcall("put", actargs) -- Add call to dasm_put().
157 actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
158 secpos = 1 -- The actionlist offset occupies a buffer position, too.
159end
160
161-- Put escaped byte.
162local function wputb(n)
163 if n >= actfirst then waction("ESC") end -- Need to escape byte.
164 wputxb(n)
165end
166
167------------------------------------------------------------------------------
168
169-- Global label name -> global label number. With auto assignment on 1st use.
170local next_global = 10
171local map_global = setmetatable({}, { __index = function(t, name)
172 if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
173 local n = next_global
174 if n > 246 then werror("too many global labels") end
175 next_global = n + 1
176 t[name] = n
177 return n
178end})
179
180-- Dump global labels.
181local function dumpglobals(out, lvl)
182 local t = {}
183 for name, n in pairs(map_global) do t[n] = name end
184 out:write("Global labels:\n")
185 for i=10,next_global-1 do
186 out:write(format(" %s\n", t[i]))
187 end
188 out:write("\n")
189end
190
191-- Write global label enum.
192local function writeglobals(out, prefix)
193 local t = {}
194 for name, n in pairs(map_global) do t[n] = name end
195 out:write("enum {\n")
196 for i=10,next_global-1 do
197 out:write(" ", prefix, t[i], ",\n")
198 end
199 out:write(" ", prefix, "_MAX\n};\n")
200end
201
202------------------------------------------------------------------------------
203
204-- Arch-specific maps.
205local map_archdef = {} -- Ext. register name -> int. name.
206local map_reg_rev = {} -- Int. register name -> ext. name.
207local map_reg_num = {} -- Int. register name -> register number.
208local map_reg_opsize = {} -- Int. register name -> operand size.
209local map_reg_valid_base = {} -- Int. register name -> valid base register?
210local map_reg_valid_index = {} -- Int. register name -> valid index register?
211local reg_list = {} -- Canonical list of int. register names.
212
213local map_type = {} -- Type name -> { ctype, reg }
214local ctypenum = 0 -- Type number (for _PTx macros).
215
216local addrsize = "d" -- Size for address operands. !x64
217
218-- Helper function to fill register maps.
219local function mkrmap(sz, names)
220 for n,name in ipairs(names) do
221 local iname = format("@%s%x", sz, n-1)
222 reg_list[#reg_list+1] = iname
223 map_archdef[name] = iname
224 map_reg_rev[iname] = name
225 map_reg_num[iname] = n-1
226 map_reg_opsize[iname] = sz
227 if sz == addrsize then
228 map_reg_valid_base[iname] = true
229 map_reg_valid_index[iname] = true
230 end
231 end
232 reg_list[#reg_list+1] = ""
233end
234
235-- Integer registers (dword, word and byte sized).
236mkrmap("d", {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"})
237map_reg_valid_index[map_archdef.esp] = nil
238mkrmap("w", {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"})
239mkrmap("b", {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"})
240
241-- FP registers (internally tword sized, but use "f" as operand size).
242mkrmap("f", {"st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7"})
243
244-- SSE registers (oword sized, but qword and dword accessible).
245mkrmap("o", {"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"})
246
247-- Operand size prefixes to codes.
248local map_opsize = {
249 byte = "b", word = "w", dword = "d", qword = "q", oword = "o", tword = "t",
250 aword = addrsize,
251}
252
253-- Operand size code to number.
254local map_opsizenum = {
255 b = 1, w = 2, d = 4, q = 8, o = 16, t = 10,
256}
257
258-- Operand size code to name.
259local map_opsizename = {
260 b = "byte", w = "word", d = "dword", q = "qword", o = "oword", t = "tword",
261 f = "fpword",
262}
263
264-- Valid index register scale factors.
265local map_xsc = {
266 ["1"] = 0, ["2"] = 1, ["4"] = 2, ["8"] = 3,
267}
268
269-- Condition codes.
270local map_cc = {
271 o = 0, no = 1, b = 2, nb = 3, e = 4, ne = 5, be = 6, nbe = 7,
272 s = 8, ns = 9, p = 10, np = 11, l = 12, nl = 13, le = 14, nle = 15,
273 c = 2, nae = 2, nc = 3, ae = 3, z = 4, nz = 5, na = 6, a = 7,
274 nge = 12, ge = 13, ng = 14, g = 15,
275}
276
277
278-- Reverse defines for registers.
279function _M.revdef(s)
280 return gsub(s, "@%w+", map_reg_rev)
281end
282
283-- Dump register names and numbers
284local function dumpregs(out)
285 out:write("Register names, sizes and internal numbers:\n")
286 for _,reg in ipairs(reg_list) do
287 if reg == "" then
288 out:write("\n")
289 else
290 local name = map_reg_rev[reg]
291 local num = map_reg_num[reg]
292 local opsize = map_opsizename[map_reg_opsize[reg]]
293 out:write(format(" %-5s %-8s %d\n", name, opsize, num))
294 end
295 end
296end
297
298------------------------------------------------------------------------------
299
300-- Put action for label arg (IMM_LG, IMM_PC, REL_LG, REL_PC).
301local function wputlabel(aprefix, imm, num)
302 if type(imm) == "number" then
303 waction(aprefix.."LG", nil, num);
304 wputxb(imm)
305 else
306 waction(aprefix.."PC", imm, num)
307 end
308end
309
310-- Put signed byte or arg.
311local function wputsbarg(n)
312 if type(n) == "number" then
313 if n < -128 or n > 127 then
314 werror("signed immediate byte out of range")
315 end
316 if n < 0 then n = n + 256 end
317 wputb(n)
318 else waction("IMM_S", n) end
319end
320
321-- Put unsigned byte or arg.
322local function wputbarg(n)
323 if type(n) == "number" then
324 if n < 0 or n > 255 then
325 werror("unsigned immediate byte out of range")
326 end
327 wputb(n)
328 else waction("IMM_B", n) end
329end
330
331-- Put unsigned word or arg.
332local function wputwarg(n)
333 if type(n) == "number" then
334 if n < 0 or n > 65535 then
335 werror("unsigned immediate word out of range")
336 end
337 local r = n%256; n = (n-r)/256; wputb(r); wputb(n);
338 else waction("IMM_W", n) end
339end
340
341-- Put signed or unsigned dword or arg.
342local function wputdarg(n)
343 local tn = type(n)
344 if tn == "number" then
345 if n < 0 then n = n + 4294967296 end
346 local r = n%256; n = (n-r)/256; wputb(r);
347 r = n%256; n = (n-r)/256; wputb(r);
348 r = n%256; n = (n-r)/256; wputb(r); wputb(n);
349 elseif tn == "table" then
350 wputlabel("IMM_", n[1], 1)
351 else
352 waction("IMM_D", n)
353 end
354end
355
356-- Put operand-size dependent number or arg (defaults to dword).
357local function wputszarg(sz, n)
358 if not sz or sz == "d" then wputdarg(n)
359 elseif sz == "w" then wputwarg(n)
360 elseif sz == "b" then wputbarg(n)
361 elseif sz == "s" then wputsbarg(n)
362 else werror("bad operand size") end
363end
364
365-- Put multi-byte opcode with operand-size dependent modifications.
366local function wputop(sz, op)
367 local r
368 if sz == "w" then wputb(102) end
369 if op >= 16777216 then r = op % 16777216 wputb((op-r) / 16777216) op = r end
370 if op >= 65536 then r = op % 65536 wputb((op-r) / 65536) op = r end
371 if op >= 256 then r = op % 256 wputb((op-r) / 256) op = r end
372 if sz == "b" then op = op - 1 end
373 wputb(op)
374end
375
376-- Put ModRM or SIB formatted byte.
377local function wputmodrm(m, s, rm)
378 assert(m < 4 and s < 8 and rm < 8, "bad modrm operands")
379 wputb(64*m + 8*s + rm)
380end
381
382-- Put ModRM/SIB plus optional displacement.
383local function wputmrmsib(t, s, imark)
384 -- Register mode.
385 if sub(t.mode, 1, 1) == "r" then
386 wputmodrm(3, s, t.reg)
387 return
388 end
389
390 local disp = t.disp
391 local tdisp = type(disp)
392 -- No base register?
393 if not t.reg then
394 if t.xreg then
395 -- Indexed mode with index register only.
396 wputmodrm(0, s, 4) -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
397 wputmodrm(t.xsc, t.xreg, 5)
398 else
399 -- Pure displacement.
400 wputmodrm(0, s, 5) -- [disp] -> (0, s, ebp)
401 end
402 wputdarg(disp)
403 return
404 end
405
406 local m
407 if tdisp == "number" then -- Check displacement size at assembly time.
408 if disp == 0 and t.reg ~= 5 then m = 0 -- [ebp] -> [ebp+0] (in SIB, too)
409 elseif disp >= -128 and disp <= 127 then m = 1
410 else m = 2 end
411 elseif tdisp == "table" then
412 m = 2
413 end
414
415 -- Index register present or esp as base register: need SIB encoding.
416 if t.xreg or t.reg == 4 then
417 wputmodrm(m or 2, s, 4) -- ModRM.
418 if (m == nil or imark) and tdisp ~= "table" then waction("MARK") end
419 wputmodrm(t.xsc or 0, t.xreg or 4, t.reg) -- SIB.
420 else
421 wputmodrm(m or 2, s, t.reg) -- ModRM.
422 if imark and (m == 1 or m == 2) then waction("MARK") end
423 end
424
425 -- Put displacement.
426 if m == 1 then wputsbarg(disp)
427 elseif m == 2 then wputdarg(disp)
428 elseif not m then waction("DISP", disp) end
429end
430
431------------------------------------------------------------------------------
432
433-- Return human-readable operand mode string.
434local function opmodestr(op, args)
435 local m = {}
436 for i=1,#args do
437 local a = args[i]
438 m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or "?")
439 end
440 return op.." "..concat(m, ",")
441end
442
443-- Convert number to valid integer or nil.
444local function toint(expr)
445 local n = tonumber(expr)
446 if n then
447 if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
448 werror("bad integer number `"..expr.."'")
449 end
450 return n
451 end
452end
453
454-- Parse immediate expression.
455local function immexpr(expr)
456 -- &expr (pointer)
457 if sub(expr, 1, 1) == "&" then
458 return "iPJ", format("(ptrdiff_t)(%s)", sub(expr,2))
459 end
460
461 local prefix = sub(expr, 1, 2)
462 -- =>expr (pc label reference)
463 if prefix == "=>" then
464 return "iJ", sub(expr, 3)
465 end
466 -- ->name (global label reference)
467 if prefix == "->" then
468 return "iJ", map_global[sub(expr, 3)]
469 end
470
471 -- [<>][1-9] (local label reference)
472 local dir, lnum = match(expr, "^([<>])([1-9])$")
473 if dir then -- Fwd: 247-255, Bkwd: 1-9.
474 return "iJ", lnum + (dir == ">" and 246 or 0)
475 end
476
477 -- expr (interpreted as immediate)
478 return "iI", expr
479end
480
481-- Parse displacement expression: +-num, +-expr, +-opsize*num
482local function dispexpr(expr)
483 local disp = expr == "" and 0 or toint(expr)
484 if disp then return disp end
485 local c, dispt = match(expr, "^([+-])%s*(.+)$")
486 if c == "+" then
487 expr = dispt
488 elseif not c then
489 werror("bad displacement expression `"..expr.."'")
490 end
491 local opsize, tailops = match(dispt, "^(%w+)%s*%*%s*(.+)$")
492 local ops, imm = map_opsize[opsize], toint(tailops)
493 if ops and imm then
494 if c == "-" then imm = -imm end
495 return imm*map_opsizenum[ops]
496 end
497 local mode, iexpr = immexpr(dispt)
498 if mode == "iJ" then
499 if c == "-" then werror("cannot invert label reference") end
500 return { iexpr }
501 end
502 return expr -- Need to return original signed expression.
503end
504
505-- Parse register or type expression.
506local function rtexpr(expr)
507 if not expr then return end
508 local tname, ovreg = match(expr, "^([%w_]+):(@[%w_]+)$")
509 local tp = map_type[tname or expr]
510 if tp then
511 local reg = ovreg or tp.reg
512 local rnum = map_reg_num[reg]
513 if not rnum then
514 werror("type `"..(tname or expr).."' needs a register override")
515 end
516 if not map_reg_valid_base[reg] then
517 werror("bad base register override `"..(map_reg_rev[reg] or reg).."'")
518 end
519 return reg, rnum, tp
520 end
521 return expr, map_reg_num[expr]
522end
523
524-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
525local function parseoperand(param)
526 local t = {}
527
528 local expr = param
529 local opsize, tailops = match(param, "^(%w+)%s*(.+)$")
530 if opsize then
531 t.opsize = map_opsize[opsize]
532 if t.opsize then expr = tailops end
533 end
534
535 local br = match(expr, "^%[%s*(.-)%s*%]$")
536 repeat
537 if br then
538 t.mode = "xm"
539
540 -- [disp]
541 t.disp = toint(br)
542 if t.disp then
543 t.mode = "xmO"
544 break
545 end
546
547 -- [reg...]
548 local tp
549 local reg, tailr = match(br, "^([@%w_:]+)%s*(.*)$")
550 reg, t.reg, tp = rtexpr(reg)
551 if not t.reg then
552 -- [expr]
553 t.mode = "xmO"
554 t.disp = dispexpr("+"..br)
555 break
556 end
557
558 -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr]
559 local xsc, tailsc = match(tailr, "^%*%s*([1248])%s*(.*)$")
560 if xsc then
561 if not map_reg_valid_index[reg] then
562 werror("bad index register `"..map_reg_rev[reg].."'")
563 end
564 t.xsc = map_xsc[xsc]
565 t.xreg = t.reg
566 t.reg = nil
567 t.disp = dispexpr(tailsc)
568 break
569 end
570 if not map_reg_valid_base[reg] then
571 werror("bad base register `"..map_reg_rev[reg].."'")
572 end
573
574 -- [reg] or [reg+-disp]
575 t.disp = toint(tailr) or (tailr == "" and 0)
576 if t.disp then break end
577
578 -- [reg+xreg...]
579 local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$")
580 xreg, t.xreg, tp = rtexpr(xreg)
581 if not t.xreg then
582 -- [reg+-expr]
583 t.disp = dispexpr(tailr)
584 break
585 end
586 if not map_reg_valid_index[xreg] then
587 werror("bad index register `"..map_reg_rev[xreg].."'")
588 end
589
590 -- [reg+xreg*xsc...]
591 local xsc, tailsc = match(tailx, "^%*%s*([1248])%s*(.*)$")
592 if xsc then
593 t.xsc = map_xsc[xsc]
594 tailx = tailsc
595 end
596
597 -- [...] or [...+-disp] or [...+-expr]
598 t.disp = dispexpr(tailx)
599 else
600 -- imm or opsize*imm
601 local imm = toint(expr)
602 if not imm and sub(expr, 1, 1) == "*" and t.opsize then
603 imm = toint(sub(expr, 2))
604 if imm then
605 imm = imm * map_opsizenum[t.opsize]
606 t.opsize = nil
607 end
608 end
609 if imm then
610 if t.opsize then werror("bad operand size override") end
611 local m = "i"
612 if imm == 1 then m = m.."1" end
613 if imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end
614 if imm >= -128 and imm <= 127 then m = m.."S" end
615 t.imm = imm
616 t.mode = m
617 break
618 end
619
620 local tp
621 local reg, tailr = match(expr, "^([@%w_:]+)%s*(.*)$")
622 reg, t.reg, tp = rtexpr(reg)
623 if t.reg then
624 -- reg
625 if tailr == "" then
626 if t.opsize then werror("bad operand size override") end
627 t.opsize = map_reg_opsize[reg]
628 if t.opsize == "f" then
629 t.mode = t.reg == 0 and "fF" or "f"
630 else
631 if reg == "@w4" then wwarn("bad idea, try again with `esp'") end
632 t.mode = t.reg == 0 and "rmR" or (reg == "@b1" and "rmC" or "rm")
633 end
634 break
635 end
636
637 -- type[idx], type[idx].field, type->field -> [reg+offset_expr]
638 if not tp then werror("bad operand `"..param.."'") end
639 t.mode = "xm"
640 t.disp = format(tp.ctypefmt, tailr)
641 else
642 t.mode, t.imm = immexpr(expr)
643 if sub(t.mode, -1) == "J" then
644 if t.opsize and t.opsize ~= addrsize then
645 werror("bad operand size override")
646 end
647 t.opsize = addrsize
648 end
649 end
650 end
651 until true
652 return t
653end
654
655------------------------------------------------------------------------------
656-- x86 Template String Description
657-- ===============================
658--
659-- Each template string is a list of [match:]pattern pairs,
660-- separated by "|". The first match wins. No match means a
661-- bad or unsupported combination of operand modes or sizes.
662--
663-- The match part and the ":" is omitted if the operation has
664-- no operands. Otherwise the first N characters are matched
665-- against the mode strings of each of the N operands.
666--
667-- The mode string for each operand type is (see parseoperand()):
668-- Integer register: "rm", +"R" for eax, ax, al, +"C" for cl
669-- FP register: "f", +"F" for st0
670-- Index operand: "xm", +"O" for [disp] (pure offset)
671-- Immediate: "i", +"S" for signed 8 bit, +"1" for 1,
672-- +"I" for arg, +"P" for pointer
673-- Any: +"J" for valid jump targets
674--
675-- So a match character "m" (mixed) matches both an integer register
676-- and an index operand (to be encoded with the ModRM/SIB scheme).
677-- But "r" matches only a register and "x" only an index operand
678-- (e.g. for FP memory access operations).
679--
680-- The operand size match string starts right after the mode match
681-- characters and ends before the ":". "dwb" is assumed, if empty.
682-- The effective data size of the operation is matched against this list.
683--
684-- If only the regular "b", "w", "d", "q", "t" operand sizes are
685-- present, then all operands must be the same size. Unspecified sizes
686-- are ignored, but at least one operand must have a size or the pattern
687-- won't match (use the "byte", "word", "dword", "qword", "tword"
688-- operand size overrides. E.g.: mov dword [eax], 1).
689--
690-- If the list has a "1" or "2" prefix, the operand size is taken
691-- from the respective operand and any other operand sizes are ignored.
692-- If the list contains only ".", all operand sizes are ignored.
693-- If the list has a "/" prefix, the concatenated (mixed) operand sizes
694-- are compared to the match.
695--
696-- E.g. "rrdw" matches for either two dword registers or two word
697-- registers. "Fx2dq" matches an st0 operand plus an index operand
698-- pointing to a dword (float) or qword (double).
699--
700-- Every character after the ":" is part of the pattern string:
701-- Hex chars are accumulated to form the opcode (left to right).
702-- "n" disables the standard opcode mods
703-- (otherwise: -1 for "b", o16 prefix for "w")
704-- "r"/"R" adds the reg. number from the 1st/2nd operand to the opcode.
705-- "m"/"M" generates ModRM/SIB from the 1st/2nd operand.
706-- The spare 3 bits are either filled with the last hex digit or
707-- the result from a previous "r"/"R". The opcode is restored.
708--
709-- All of the following characters force a flush of the opcode:
710-- "o"/"O" stores a pure 32 bit disp (offset) from the 1st/2nd operand.
711-- "S" stores a signed 8 bit immediate from the last operand.
712-- "U" stores an unsigned 8 bit immediate from the last operand.
713-- "W" stores an unsigned 16 bit immediate from the last operand.
714-- "i" stores an operand sized immediate from the last operand.
715-- "I" dito, but generates an action code to optionally modify
716-- the opcode (+2) for a signed 8 bit immediate.
717-- "J" generates one of the REL action codes from the last operand.
718--
719------------------------------------------------------------------------------
720
721-- Template strings for x86 instructions. Ordered by first opcode byte.
722-- Unimplemented opcodes (deliberate omissions) are marked with *.
723local map_op = {
724 -- 00-05: add...
725 -- 06: *push es
726 -- 07: *pop es
727 -- 08-0D: or...
728 -- 0E: *push cs
729 -- 0F: two byte opcode prefix
730 -- 10-15: adc...
731 -- 16: *push ss
732 -- 17: *pop ss
733 -- 18-1D: sbb...
734 -- 1E: *push ds
735 -- 1F: *pop ds
736 -- 20-25: and...
737 es_0 = "26",
738 -- 27: *daa
739 -- 28-2D: sub...
740 cs_0 = "2E",
741 -- 2F: *das
742 -- 30-35: xor...
743 ss_0 = "36",
744 -- 37: *aaa
745 -- 38-3D: cmp...
746 ds_0 = "3E",
747 -- 3F: *aas
748 inc_1 = "rdw:40r|m:FF0m",
749 dec_1 = "rdw:48r|m:FF1m",
750 push_1 = "rdw:50r|mdw:FF6m|S.:6AS|ib:n6Ai|i.:68i",
751 pop_1 = "rdw:58r|mdw:8F0m",
752 -- 60: *pusha, *pushad, *pushaw
753 -- 61: *popa, *popad, *popaw
754 -- 62: *bound rdw,x
755 -- 63: *arpl mw,rw
756 fs_0 = "64",
757 gs_0 = "65",
758 o16_0 = "66",
759 a16_0 = "67",
760 -- 68: push idw
761 -- 69: imul rdw,mdw,idw
762 -- 6A: push ib
763 -- 6B: imul rdw,mdw,S
764 -- 6C: *insb
765 -- 6D: *insd, *insw
766 -- 6E: *outsb
767 -- 6F: *outsd, *outsw
768 -- 70-7F: jcc lb
769 -- 80: add... mb,i
770 -- 81: add... mdw,i
771 -- 82: *undefined
772 -- 83: add... mdw,S
773 test_2 = "mr:85Rm|rm:85rM|Ri:A9i|mi:F70mi",
774 -- 86: xchg rb,mb
775 -- 87: xchg rdw,mdw
776 -- 88: mov mb,r
777 -- 89: mov mdw,r
778 -- 8A: mov r,mb
779 -- 8B: mov r,mdw
780 -- 8C: *mov mdw,seg
781 lea_2 = "rxd:8DrM",
782 -- 8E: *mov seg,mdw
783 -- 8F: pop mdw
784 nop_0 = "90",
785 xchg_2 = "Rrdw:90R|rRdw:90r|rm:87rM|mr:87Rm",
786 cbw_0 = "6698",
787 cwde_0 = "98",
788 cwd_0 = "6699",
789 cdq_0 = "99",
790 -- 9A: *call iw:idw
791 wait_0 = "9B",
792 fwait_0 = "9B",
793 pushf_0 = "9C",
794 pushfw_0 = "669C",
795 pushfd_0 = "9C",
796 popf_0 = "9D",
797 popfw_0 = "669D",
798 popfd_0 = "9D",
799 sahf_0 = "9E",
800 lahf_0 = "9F",
801 mov_2 = "OR:A3o|RO:A1O|mr:89Rm|rm:8BrM|rib:nB0ri|ridw:B8ri|mi:C70mi",
802 movsb_0 = "A4",
803 movsw_0 = "66A5",
804 movsd_0 = "A5",
805 cmpsb_0 = "A6",
806 cmpsw_0 = "66A7",
807 cmpsd_0 = "A7",
808 -- A8: test Rb,i
809 -- A9: test Rdw,i
810 stosb_0 = "AA",
811 stosw_0 = "66AB",
812 stosd_0 = "AB",
813 lodsb_0 = "AC",
814 lodsw_0 = "66AD",
815 lodsd_0 = "AD",
816 scasb_0 = "AE",
817 scasw_0 = "66AF",
818 scasd_0 = "AF",
819 -- B0-B7: mov rb,i
820 -- B8-BF: mov rdw,i
821 -- C0: rol... mb,i
822 -- C1: rol... mdw,i
823 ret_1 = "i.:nC2W",
824 ret_0 = "C3",
825 -- C4: *les rdw,mq
826 -- C5: *lds rdw,mq
827 -- C6: mov mb,i
828 -- C7: mov mdw,i
829 -- C8: *enter iw,ib
830 leave_0 = "C9",
831 -- CA: *retf iw
832 -- CB: *retf
833 int3_0 = "CC",
834 int_1 = "i.:nCDU",
835 into_0 = "CE",
836 -- CF: *iret
837 -- D0: rol... mb,1
838 -- D1: rol... mdw,1
839 -- D2: rol... mb,cl
840 -- D3: rol... mb,cl
841 -- D4: *aam ib
842 -- D5: *aad ib
843 -- D6: *salc
844 -- D7: *xlat
845 -- D8-DF: floating point ops
846 -- E0: *loopne
847 -- E1: *loope
848 -- E2: *loop
849 -- E3: *jcxz, *jecxz
850 -- E4: *in Rb,ib
851 -- E5: *in Rdw,ib
852 -- E6: *out ib,Rb
853 -- E7: *out ib,Rdw
854 call_1 = "md:FF2m|J.:E8J",
855 jmp_1 = "md:FF4m|J.:E9J", -- short: EB
856 -- EA: *jmp iw:idw
857 -- EB: jmp ib
858 -- EC: *in Rb,dx
859 -- ED: *in Rdw,dx
860 -- EE: *out dx,Rb
861 -- EF: *out dx,Rdw
862 -- F0: *lock
863 int1_0 = "F1",
864 repne_0 = "F2",
865 repnz_0 = "F2",
866 rep_0 = "F3",
867 repe_0 = "F3",
868 repz_0 = "F3",
869 -- F4: *hlt
870 cmc_0 = "F5",
871 -- F6: test... mb,i; div... mb
872 -- F7: test... mdw,i; div... mdw
873 clc_0 = "F8",
874 stc_0 = "F9",
875 -- FA: *cli
876 cld_0 = "FC",
877 std_0 = "FD",
878 -- FE: inc... mb
879 -- FF: inc... mdw
880
881 -- misc ops
882 not_1 = "m:F72m",
883 neg_1 = "m:F73m",
884 mul_1 = "m:F74m",
885 imul_1 = "m:F75m",
886 div_1 = "m:F76m",
887 idiv_1 = "m:F77m",
888
889 imul_2 = "rmdw:0FAFrM|rIdw:69rmI|rSdw:6BrmS|ridw:69rmi",
890 imul_3 = "rmIdw:69rMI|rmSdw:6BrMS|rmidw:69rMi",
891
892 movzx_2 = "rm/db:0FB6rM|rm/wb:0FB6rM|rm/dw:0FB7rM",
893 movsx_2 = "rm/db:0FBErM|rm/wb:0FBErM|rm/dw:0FBFrM",
894
895 bswap_1 = "rd:0FC8r",
896 bsf_2 = "rmdw:0FBCrM",
897 bsr_2 = "rmdw:0FBDrM",
898 bt_2 = "mrdw:0FA3Rm|midw:0FBA4mU",
899 btc_2 = "mrdw:0FBBRm|midw:0FBA7mU",
900 btr_2 = "mrdw:0FB3Rm|midw:0FBA6mU",
901 bts_2 = "mrdw:0FABRm|midw:0FBA5mU",
902
903 rdtsc_0 = "0F31", -- P1+
904 cpuid_0 = "0FA2", -- P1+
905
906 -- floating point ops
907 fst_1 = "ff:DDD0r|xd:D92m|xq:DD2m",
908 fstp_1 = "ff:DDD8r|xd:D93m|xq:DD3m|xt:DB7m",
909 fld_1 = "ff:D9C0r|xd:D90m|xq:DD0m|xt:DB5m",
910
911 fpop_0 = "DDD8", -- Alias for fstp st0.
912
913 fist_1 = "xw:nDF2m|xd:DB2m",
914 fistp_1 = "xw:nDF3m|xd:DB3m|xq:DF7m",
915 fisttp_1 = "xw:nDF1m|xd:DB1m|xq:DD1m", -- SSE3
916 fild_1 = "xw:nDF0m|xd:DB0m|xq:DF5m",
917
918 fxch_0 = "D9C9",
919 fxch_1 = "ff:D9C8r",
920 fxch_2 = "fFf:D9C8r|Fff:D9C8R",
921
922 fucom_1 = "ff:DDE0r",
923 fucom_2 = "Fff:DDE0R",
924 fucomp_1 = "ff:DDE8r",
925 fucomp_2 = "Fff:DDE8R",
926 fucomi_1 = "ff:DBE8r", -- P6+
927 fucomi_2 = "Fff:DBE8R", -- P6+
928 fucomip_1 = "ff:DFE8r", -- P6+
929 fucomip_2 = "Fff:DFE8R", -- P6+
930 fcomi_1 = "ff:DBF0r", -- P6+
931 fcomi_2 = "Fff:DBF0R", -- P6+
932 fcomip_1 = "ff:DFF0r", -- P6+
933 fcomip_2 = "Fff:DFF0R", -- P6+
934 fucompp_0 = "DAE9",
935 fcompp_0 = "DED9",
936
937 fldcw_1 = "xw:nD95m",
938 fstcw_1 = "xw:n9BD97m",
939 fnstcw_1 = "xw:nD97m",
940 fstsw_1 = "Rw:n9BDFE0|xw:n9BDD7m",
941 fnstsw_1 = "Rw:nDFE0|xw:nDD7m",
942 fclex_0 = "9BDBE2",
943 fnclex_0 = "DBE2",
944
945 fnop_0 = "D9D0",
946 -- D9D1-D9DF: unassigned
947
948 fchs_0 = "D9E0",
949 fabs_0 = "D9E1",
950 -- D9E2: unassigned
951 -- D9E3: unassigned
952 ftst_0 = "D9E4",
953 fxam_0 = "D9E5",
954 -- D9E6: unassigned
955 -- D9E7: unassigned
956 fld1_0 = "D9E8",
957 fldl2t_0 = "D9E9",
958 fldl2e_0 = "D9EA",
959 fldpi_0 = "D9EB",
960 fldlg2_0 = "D9EC",
961 fldln2_0 = "D9ED",
962 fldz_0 = "D9EE",
963 -- D9EF: unassigned
964
965 f2xm1_0 = "D9F0",
966 fyl2x_0 = "D9F1",
967 fptan_0 = "D9F2",
968 fpatan_0 = "D9F3",
969 fxtract_0 = "D9F4",
970 fprem1_0 = "D9F5",
971 fdecstp_0 = "D9F6",
972 fincstp_0 = "D9F7",
973 fprem_0 = "D9F8",
974 fyl2xp1_0 = "D9F9",
975 fsqrt_0 = "D9FA",
976 fsincos_0 = "D9FB",
977 frndint_0 = "D9FC",
978 fscale_0 = "D9FD",
979 fsin_0 = "D9FE",
980 fcos_0 = "D9FF",
981
982 -- SSE, SSE2, SSE3, SSSE3 ops
983 addsubpd_2 = "rmo:660FD0rM",
984 addsubps_2 = "rmo:F20FD0rM",
985 andnpd_2 = "rmo:660F55rM",
986 andnps_2 = "rmo:0F55rM",
987 andpd_2 = "rmo:660F54rM",
988 andps_2 = "rmo:0F54rM",
989 clflush_1 = "x.:0FAE7m",
990 cmppd_3 = "rmio:660FC2rMU",
991 cmpps_3 = "rmio:0FC2rMU",
992 cmpsd_3 = "rmio:F20FC2rMU",
993 cmpss_3 = "rmio:F30FC2rMU",
994 comisd_2 = "rmo:660F2FrM",
995 comiss_2 = "rmo:0F2FrM",
996 cvtdq2pd_2 = "rro:F30FE6rM|rx/oq:",
997 cvtdq2ps_2 = "rmo:0F5BrM",
998 cvtpd2dq_2 = "rmo:F20FE6rM",
999 cvtpd2ps_2 = "rmo:660F5ArM",
1000 cvtpi2pd_2 = "rx/oq:660F2ArM",
1001 cvtpi2ps_2 = "rx/oq:0F2ArM",
1002 cvtps2dq_2 = "rmo:660F5BrM",
1003 cvtps2pd_2 = "rro:0F5ArM|rx/oq:",
1004 cvtsd2si_2 = "rr/do:F20F2DrM|rx/dq:",
1005 cvtsd2ss_2 = "rro:F20F5ArM|rx/oq:",
1006 cvtsi2sd_2 = "rm/od:F20F2ArM",
1007 cvtsi2ss_2 = "rm/od:F30F2ArM",
1008 cvtss2sd_2 = "rro:F30F5ArM|rx/od:",
1009 cvtss2si_2 = "rr/do:F20F2CrM|rx/dd:",
1010 cvttpd2dq_2 = "rmo:660FE6rM",
1011 cvttps2dq_2 = "rmo:F30F5BrM",
1012 cvttsd2si_2 = "rr/do:F20F2CrM|rx/dq:",
1013 cvttss2si_2 = "rr/do:F30F2CrM|rx/dd:",
1014 haddpd_2 = "rmo:660F7CrM",
1015 haddps_2 = "rmo:F20F7CrM",
1016 hsubpd_2 = "rmo:660F7DrM",
1017 hsubps_2 = "rmo:F20F7DrM",
1018 lddqu_2 = "rxo:F20FF0rM",
1019 ldmxcsr_1 = "xd:0FAE2m",
1020 lfence_0 = "0FAEE8",
1021 maskmovdqu_2 = "rro:660FF7rM",
1022 mfence_0 = "0FAEF0",
1023 movapd_2 = "rmo:660F28rM|mro:660F29Rm",
1024 movaps_2 = "rmo:0F28rM|mro:0F29Rm",
1025 movd_2 = "rm/od:660F6ErM|mr/do:660F7ERm",
1026 movddup_2 = "rmo:F20F12rM",
1027 movdqa_2 = "rmo:660F6FrM|mro:660F7FRm",
1028 movdqu_2 = "rmo:F30F6FrM|mro:F30F7FRm",
1029 movhlps_2 = "rro:0F12rM",
1030 movhpd_2 = "rx/oq:660F16rM|xr/qo:660F17Rm",
1031 movhps_2 = "rx/oq:0F16rM|xr/qo:0F17Rm",
1032 movlhps_2 = "rro:0F16rM",
1033 movlpd_2 = "rx/oq:660F12rM|xr/qo:660F13Rm",
1034 movlps_2 = "rx/oq:0F12rM|xr/qo:0F13Rm",
1035 movmskpd_2 = "rr/do:660F50rM",
1036 movmskps_2 = "rr/do:0F50rM",
1037 movntdq_2 = "xro:660FE7Rm",
1038 movnti_2 = "xrd:0FC3Rm",
1039 movntpd_2 = "xro:660F2BRm",
1040 movntps_2 = "xro:0F2BRm",
1041 movq_2 = "rro:F30F7ErM|rx/oq:|xr/qo:660FD6Rm",
1042 movsd_2 = "rro:F20F10rM|rx/oq:|xr/qo:F20F11Rm",
1043 movshdup_2 = "rmo:F30F16rM",
1044 movsldup_2 = "rmo:F30F12rM",
1045 movss_2 = "rro:F30F10rM|rx/od:|xr/do:F30F11Rm",
1046 movupd_2 = "rmo:660F10rM|mro:660F11Rm",
1047 movups_2 = "rmo:0F10rM|mro:0F11Rm",
1048 orpd_2 = "rmo:660F56rM",
1049 orps_2 = "rmo:0F56rM",
1050 pabsb_2 = "rmo:660F381CrM",
1051 pabsd_2 = "rmo:660F381ErM",
1052 pabsw_2 = "rmo:660F381DrM",
1053 packssdw_2 = "rmo:660F6BrM",
1054 packsswb_2 = "rmo:660F63rM",
1055 packuswb_2 = "rmo:660F67rM",
1056 paddb_2 = "rmo:660FFCrM",
1057 paddd_2 = "rmo:660FFErM",
1058 paddq_2 = "rmo:660FD4rM",
1059 paddsb_2 = "rmo:660FECrM",
1060 paddsw_2 = "rmo:660FEDrM",
1061 paddusb_2 = "rmo:660FDCrM",
1062 paddusw_2 = "rmo:660FDDrM",
1063 paddw_2 = "rmo:660FFDrM",
1064 palignr_3 = "rmio:660F3A0FrMU",
1065 pand_2 = "rmo:660FDBrM",
1066 pandn_2 = "rmo:660FDFrM",
1067 pause_0 = "F390",
1068 pavgb_2 = "rmo:660FE0rM",
1069 pavgw_2 = "rmo:660FE3rM",
1070 pcmpeqb_2 = "rmo:660F74rM",
1071 pcmpeqd_2 = "rmo:660F76rM",
1072 pcmpeqw_2 = "rmo:660F75rM",
1073 pcmpgtb_2 = "rmo:660F64rM",
1074 pcmpgtd_2 = "rmo:660F66rM",
1075 pcmpgtw_2 = "rmo:660F65rM",
1076 pextrw_3 = "rri/do:660FC5rMU",
1077 phaddd_2 = "rmo:660F3802rM",
1078 phaddsw_2 = "rmo:660F3803rM",
1079 phaddw_2 = "rmo:660F3801rM",
1080 phsubd_2 = "rmo:660F3806rM",
1081 phsubsw_2 = "rmo:660F3807rM",
1082 phsubw_2 = "rmo:660F3805rM",
1083 pinsrw_3 = "rri/od:660FC4rMU|rmi/ow:",
1084 pmaddubsw_2 = "rmo:660F3804rM",
1085 pmaddwd_2 = "rmo:660FF5rM",
1086 pmaxsw_2 = "rmo:660FEErM",
1087 pmaxub_2 = "rmo:660FDErM",
1088 pminsw_2 = "rmo:660FEArM",
1089 pminub_2 = "rmo:660FDArM",
1090 pmovmskb_2 = "rr/do:660FD7rM",
1091 pmulhrsw_2 = "rmo:660F380BrM",
1092 pmulhuw_2 = "rmo:660FE4rM",
1093 pmulhw_2 = "rmo:660FE5rM",
1094 pmullw_2 = "rmo:660FD5rM",
1095 pmuludq_2 = "rmo:660FF4rM",
1096 por_2 = "rmo:660FEBrM",
1097 prefetchnta_1 = "xb:n0F180m",
1098 prefetcht0_1 = "xb:n0F181m",
1099 prefetcht1_1 = "xb:n0F182m",
1100 prefetcht2_1 = "xb:n0F183m",
1101 psadbw_2 = "rmo:660FF6rM",
1102 pshufb_2 = "rmo:660F3800rM",
1103 pshufd_3 = "rmio:660F70rMU",
1104 pshufhw_3 = "rmio:F30F70rMU",
1105 pshuflw_3 = "rmio:F20F70rMU",
1106 psignb_2 = "rmo:660F3808rM",
1107 psignd_2 = "rmo:660F380ArM",
1108 psignw_2 = "rmo:660F3809rM",
1109 pslld_2 = "rmo:660FF2rM|rio:660F726mU",
1110 pslldq_2 = "rio:660F737mU",
1111 psllq_2 = "rmo:660FF3rM|rio:660F736mU",
1112 psllw_2 = "rmo:660FF1rM|rio:660F716mU",
1113 psrad_2 = "rmo:660FE2rM|rio:660F724mU",
1114 psraw_2 = "rmo:660FE1rM|rio:660F714mU",
1115 psrld_2 = "rmo:660FD2rM|rio:660F722mU",
1116 psrldq_2 = "rio:660F733mU",
1117 psrlq_2 = "rmo:660FD3rM|rio:660F732mU",
1118 psrlw_2 = "rmo:660FD1rM|rio:660F712mU",
1119 psubb_2 = "rmo:660FF8rM",
1120 psubd_2 = "rmo:660FFArM",
1121 psubq_2 = "rmo:660FFBrM",
1122 psubsb_2 = "rmo:660FE8rM",
1123 psubsw_2 = "rmo:660FE9rM",
1124 psubusb_2 = "rmo:660FD8rM",
1125 psubusw_2 = "rmo:660FD9rM",
1126 psubw_2 = "rmo:660FF9rM",
1127 punpckhbw_2 = "rmo:660F68rM",
1128 punpckhdq_2 = "rmo:660F6ArM",
1129 punpckhqdq_2 = "rmo:660F6DrM",
1130 punpckhwd_2 = "rmo:660F69rM",
1131 punpcklbw_2 = "rmo:660F60rM",
1132 punpckldq_2 = "rmo:660F62rM",
1133 punpcklqdq_2 = "rmo:660F6CrM",
1134 punpcklwd_2 = "rmo:660F61rM",
1135 pxor_2 = "rmo:660FEFrM",
1136 rcpps_2 = "rmo:0F53rM",
1137 rcpss_2 = "rmo:F30F53rM",
1138 rsqrtps_2 = "rmo:0F52rM",
1139 rsqrtss_2 = "rmo:F30F52rM",
1140 sfence_0 = "0FAEF8",
1141 shufpd_3 = "rmio:660FC6rMU",
1142 shufps_3 = "rmio:0FC6rMU",
1143 stmxcsr_1 = "xd:0FAE3m",
1144 ucomisd_2 = "rmo:660F2ErM",
1145 ucomiss_2 = "rmo:0F2ErM",
1146 unpckhpd_2 = "rmo:660F15rM",
1147 unpckhps_2 = "rmo:0F15rM",
1148 unpcklpd_2 = "rmo:660F14rM",
1149 unpcklps_2 = "rmo:0F14rM",
1150 xorpd_2 = "rmo:660F57rM",
1151 xorps_2 = "rmo:0F57rM",
1152}
1153
1154------------------------------------------------------------------------------
1155
1156-- Arithmetic ops.
1157for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3,
1158 ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do
1159 local n8 = n * 8
1160 map_op[name.."_2"] = format(
1161 "mr:%02XRm|rm:%02XrM|mI1dw:81%XmI|mS1dw:83%XmS|Ri1dwb:%02Xi|mi1dwb:81%Xmi",
1162 1+n8, 3+n8, n, n, 5+n8, n)
1163end
1164
1165-- Shift ops.
1166for name,n in pairs{ rol = 0, ror = 1, rcl = 2, rcr = 3,
1167 shl = 4, shr = 5, sar = 7, sal = 4 } do
1168 map_op[name.."_2"] = format("m1:D1%Xm|mC1dwb:D3%Xm|mi:C1%XmU", n, n, n)
1169end
1170
1171-- Conditional ops.
1172for cc,n in pairs(map_cc) do
1173 map_op["j"..cc.."_1"] = format("J.:0F8%XJ", n) -- short: 7%X
1174 map_op["set"..cc.."_1"] = format("mb:n0F9%X2m", n)
1175 map_op["cmov"..cc.."_2"] = format("rmdw:0F4%XrM", n) -- P6+
1176end
1177
1178-- FP arithmetic ops.
1179for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,
1180 sub = 4, subr = 5, div = 6, divr = 7 } do
1181 local nc = 192 + n * 8
1182 local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))
1183 local fn = "f"..name
1184 map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:DC%Xm", nc, n, n)
1185 if n == 2 or n == 3 then
1186 map_op[fn.."_2"] = format("Fff:D8%02XR|Fx2d:D8%XM|Fx2q:DC%XM", nc, n, n)
1187 else
1188 map_op[fn.."_2"] = format("Fff:D8%02XR|fFf:DC%02Xr|Fx2d:D8%XM|Fx2q:DC%XM", nc, nr, n, n)
1189 map_op[fn.."p_1"] = format("ff:DE%02Xr", nr)
1190 map_op[fn.."p_2"] = format("fFf:DE%02Xr", nr)
1191 end
1192 map_op["fi"..name.."_1"] = format("xd:DA%Xm|xw:nDE%Xm", n, n)
1193end
1194
1195-- FP conditional moves.
1196for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
1197 local n4 = n % 4
1198 local nc = 56000 + n4 * 8 + (n-n4) * 64
1199 map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+
1200 map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
1201end
1202
1203-- SSE FP arithmetic ops.
1204for name,n in pairs{ sqrt = 1, add = 8, mul = 9,
1205 sub = 12, min = 13, div = 14, max = 15 } do
1206 map_op[name.."ps_2"] = format("rmo:0F5%XrM", n)
1207 map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n)
1208 map_op[name.."pd_2"] = format("rmo:660F5%XrM", n)
1209 map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n)
1210end
1211
1212------------------------------------------------------------------------------
1213
1214-- Process pattern string.
1215local function dopattern(pat, args, sz, op)
1216 local digit, addin
1217 local opcode = 0
1218 local szov = sz
1219
1220 -- Limit number of section buffer positions used by a single dasm_put().
1221 -- A single opcode needs a maximum of 2 positions. !x64
1222 if secpos+2 > maxsecpos then wflush() end
1223
1224 -- Process each character.
1225 for c in gmatch(pat, ".") do
1226 if match(c, "%x") then -- Hex digit.
1227 digit = byte(c) - 48
1228 if digit > 48 then digit = digit - 39
1229 elseif digit > 16 then digit = digit - 7 end
1230 opcode = opcode*16 + digit
1231 addin = nil
1232 elseif c == "n" then -- Disable operand size mods for opcode.
1233 szov = nil
1234 elseif c == "r" then -- Merge 1st operand regno. into opcode.
1235 addin = args[1].reg; opcode = opcode + addin
1236 elseif c == "R" then -- Merge 2nd operand regno. into opcode.
1237 addin = args[2].reg; opcode = opcode + addin
1238 elseif c == "m" or c == "M" then -- Encode ModRM/SIB.
1239 if addin then
1240 opcode = opcode - addin -- Undo regno opcode merge.
1241 else
1242 addin = opcode % 16 -- Undo last digit.
1243 opcode = (opcode - addin) / 16
1244 end
1245 wputop(szov, opcode); opcode = nil
1246 local imark = (sub(pat, -1) == "I") -- Force a mark (ugly).
1247 -- Put ModRM/SIB with regno/last digit as spare.
1248 wputmrmsib(args[c == "m" and 1 or 2], addin, imark)
1249 else
1250 if opcode then wputop(szov, opcode); opcode = nil end -- Flush opcode.
1251 if c == "o" or c == "O" then -- Offset (pure 32 bit displacement).
1252 wputdarg(args[c == "o" and 1 or 2].disp)
1253 else
1254 -- Anything else is an immediate operand.
1255 local a = args[#args]
1256 local mode, imm = a.mode, a.imm
1257 if mode == "iJ" and not match("iIJ", c) then
1258 werror("bad operand size for label")
1259 end
1260 if c == "S" then
1261 wputsbarg(imm)
1262 elseif c == "U" then
1263 wputbarg(imm)
1264 elseif c == "W" then
1265 wputwarg(imm)
1266 elseif c == "i" or c == "I" then
1267 if mode == "iJ" then
1268 wputlabel("IMM_", imm, 1)
1269 elseif mode == "iI" and c == "I" then
1270 waction(sz == "w" and "IMM_WB" or "IMM_DB", imm)
1271 else
1272 wputszarg(sz, imm)
1273 end
1274 elseif c == "J" then
1275 if mode == "iPJ" then
1276 waction("REL_A", imm) -- !x64 (secpos)
1277 else
1278 wputlabel("REL_", imm, 2)
1279 end
1280 else
1281 werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")
1282 end
1283 end
1284 end
1285 end
1286 if opcode then wputop(szov, opcode) end
1287end
1288
1289------------------------------------------------------------------------------
1290
1291-- Mapping of operand modes to short names. Suppress output with '#'.
1292local map_modename = {
1293 r = "reg", R = "eax", C = "cl", x = "mem", m = "mrm", i = "imm",
1294 f = "stx", F = "st0", J = "lbl", ["1"] = "1",
1295 I = "#", S = "#", O = "#",
1296}
1297
1298-- Return a table/string showing all possible operand modes.
1299local function templatehelp(template, nparams)
1300 if nparams == 0 then return "" end
1301 local t = {}
1302 for tm in gmatch(template, "[^%|]+") do
1303 local s = map_modename[sub(tm, 1, 1)]
1304 s = s..gsub(sub(tm, 2, nparams), ".", function(c)
1305 return ", "..map_modename[c]
1306 end)
1307 if not match(s, "#") then t[#t+1] = s end
1308 end
1309 return t
1310end
1311
1312-- Match operand modes against mode match part of template.
1313local function matchtm(tm, args)
1314 for i=1,#args do
1315 if not match(args[i].mode, sub(tm, i, i)) then return end
1316 end
1317 return true
1318end
1319
1320-- Handle opcodes defined with template strings.
1321map_op[".template__"] = function(params, template, nparams)
1322 if not params then return templatehelp(template, nparams) end
1323 local args = {}
1324
1325 -- Zero-operand opcodes have no match part.
1326 if #params == 0 then
1327 dopattern(template, args, "d", params.op)
1328 return
1329 end
1330
1331 -- Determine common operand size (coerce undefined size) or flag as mixed.
1332 local sz, szmix
1333 for i,p in ipairs(params) do
1334 args[i] = parseoperand(p)
1335 local nsz = args[i].opsize
1336 if nsz then
1337 if sz and sz ~= nsz then szmix = true else sz = nsz end
1338 end
1339 end
1340
1341 -- Try all match:pattern pairs (separated by '|').
1342 local gotmatch, lastpat
1343 for tm in gmatch(template, "[^%|]+") do
1344 -- Split off size match (starts after mode match) and pattern string.
1345 local szm, pat = match(tm, "^(.-):(.*)$", #args+1)
1346 if pat == "" then pat = lastpat else lastpat = pat end
1347 if matchtm(tm, args) then
1348 local prefix = sub(szm, 1, 1)
1349 if prefix == "/" then -- Match both operand sizes.
1350 if args[1].opsize == sub(szm, 2, 2) and
1351 args[2].opsize == sub(szm, 3, 3) then
1352 dopattern(pat, args, sz, params.op) -- Process pattern string.
1353 return
1354 end
1355 else -- Match common operand size.
1356 local szp = sz
1357 if szm == "" then szm = "dwb" end -- Default size match.
1358 if prefix == "1" then szp = args[1].opsize; szmix = nil
1359 elseif prefix == "2" then szp = args[2].opsize; szmix = nil end
1360 if not szmix and (prefix == "." or match(szm, szp or "#")) then
1361 dopattern(pat, args, szp, params.op) -- Process pattern string.
1362 return
1363 end
1364 end
1365 gotmatch = true
1366 end
1367 end
1368
1369 local msg = "bad operand mode"
1370 if gotmatch then
1371 if szmix then
1372 msg = "mixed operand size"
1373 else
1374 msg = sz and "bad operand size" or "missing operand size"
1375 end
1376 end
1377
1378 werror(msg.." in `"..opmodestr(params.op, args).."'")
1379end
1380
1381------------------------------------------------------------------------------
1382
1383-- Pseudo-opcodes for data storage.
1384local function op_data(params)
1385 if not params then return "imm..." end
1386 local sz = sub(params.op, 2, 2)
1387 if sz == "a" then sz = addrsize end
1388 for _,p in ipairs(params) do
1389 local a = parseoperand(p)
1390 if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
1391 werror("bad mode or size in `"..p.."'")
1392 end
1393 if a.mode == "iJ" then
1394 wputlabel("IMM_", a.imm, 1)
1395 else
1396 wputszarg(sz, a.imm)
1397 end
1398 end
1399end
1400
1401map_op[".byte_*"] = op_data
1402map_op[".sbyte_*"] = op_data
1403map_op[".word_*"] = op_data
1404map_op[".dword_*"] = op_data
1405map_op[".aword_*"] = op_data
1406
1407------------------------------------------------------------------------------
1408
1409-- Pseudo-opcode to mark the position where the action list is to be emitted.
1410map_op[".actionlist_1"] = function(params)
1411 if not params then return "cvar" end
1412 local name = params[1] -- No syntax check. You get to keep the pieces.
1413 wline(function(out) writeactions(out, name) end)
1414end
1415
1416-- Pseudo-opcode to mark the position where the global enum is to be emitted.
1417map_op[".globals_1"] = function(params)
1418 if not params then return "prefix" end
1419 local prefix = params[1] -- No syntax check. You get to keep the pieces.
1420 wline(function(out) writeglobals(out, prefix) end)
1421end
1422
1423------------------------------------------------------------------------------
1424
1425-- Label pseudo-opcode (converted from trailing colon form).
1426map_op[".label_2"] = function(params)
1427 if not params then return "[1-9] | ->global | =>pcexpr [, addr]" end
1428 local a = parseoperand(params[1])
1429 local mode, imm = a.mode, a.imm
1430 if type(imm) == "number" and (mode == "iJ" or (imm >= 1 and imm <= 9)) then
1431 -- Local label (1: ... 9:) or global label (->global:).
1432 waction("LABEL_LG", nil, 1)
1433 wputxb(imm)
1434 elseif mode == "iJ" then
1435 -- PC label (=>pcexpr:).
1436 waction("LABEL_PC", imm)
1437 else
1438 werror("bad label definition")
1439 end
1440 -- SETLABEL must immediately follow LABEL_LG/LABEL_PC.
1441 local addr = params[2]
1442 if addr then
1443 local a = parseoperand(params[2])
1444 if a.mode == "iPJ" then
1445 waction("SETLABEL", a.imm) -- !x64 (secpos)
1446 else
1447 werror("bad label assignment")
1448 end
1449 end
1450end
1451map_op[".label_1"] = map_op[".label_2"]
1452
1453------------------------------------------------------------------------------
1454
1455-- Alignment pseudo-opcode.
1456map_op[".align_1"] = function(params)
1457 if not params then return "numpow2" end
1458 local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]]
1459 if align then
1460 local x = align
1461 -- Must be a power of 2 in the range (2 ... 256).
1462 for i=1,8 do
1463 x = x / 2
1464 if x == 1 then
1465 waction("ALIGN", nil, 1)
1466 wputxb(align-1) -- Action byte is 2**n-1.
1467 return
1468 end
1469 end
1470 end
1471 werror("bad alignment")
1472end
1473
1474-- Spacing pseudo-opcode.
1475map_op[".space_2"] = function(params)
1476 if not params then return "num [, filler]" end
1477 waction("SPACE", params[1])
1478 local fill = params[2]
1479 if fill then
1480 fill = tonumber(fill)
1481 if not fill or fill < 0 or fill > 255 then werror("bad filler") end
1482 end
1483 wputxb(fill or 0)
1484end
1485map_op[".space_1"] = map_op[".space_2"]
1486
1487------------------------------------------------------------------------------
1488
1489-- Pseudo-opcode for (primitive) type definitions (map to C types).
1490map_op[".type_3"] = function(params, nparams)
1491 if not params then
1492 return nparams == 2 and "name, ctype" or "name, ctype, reg"
1493 end
1494 local name, ctype, reg = params[1], params[2], params[3]
1495 if not match(name, "^[%a_][%w_]*$") then
1496 werror("bad type name `"..name.."'")
1497 end
1498 local tp = map_type[name]
1499 if tp then
1500 werror("duplicate type `"..name.."'")
1501 end
1502 if reg and not map_reg_valid_base[reg] then
1503 werror("bad base register `"..(map_reg_rev[reg] or reg).."'")
1504 end
1505 -- Add #type to defines. A bit unclean to put it in map_archdef.
1506 map_archdef["#"..name] = "sizeof("..ctype..")"
1507 -- Add new type and emit shortcut define.
1508 local num = ctypenum + 1
1509 map_type[name] = {
1510 ctype = ctype,
1511 ctypefmt = format("Dt%X(%%s)", num),
1512 reg = reg,
1513 }
1514 wline(format("#define Dt%X(_V) (int)&(((%s *)0)_V)", num, ctype))
1515 ctypenum = num
1516end
1517map_op[".type_2"] = map_op[".type_3"]
1518
1519-- Dump type definitions.
1520local function dumptypes(out, lvl)
1521 local t = {}
1522 for name in pairs(map_type) do t[#t+1] = name end
1523 sort(t)
1524 out:write("Type definitions:\n")
1525 for _,name in ipairs(t) do
1526 local tp = map_type[name]
1527 local reg = tp.reg and map_reg_rev[tp.reg] or ""
1528 out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
1529 end
1530 out:write("\n")
1531end
1532
1533------------------------------------------------------------------------------
1534
1535-- Set the current section.
1536function _M.section(num)
1537 waction("SECTION")
1538 wputxb(num)
1539 wflush(true) -- SECTION is a terminal action.
1540end
1541
1542------------------------------------------------------------------------------
1543
1544-- Dump architecture description.
1545function _M.dumparch(out)
1546 out:write(format("DynASM %s version %s, released %s\n\n",
1547 _info.arch, _info.version, _info.release))
1548 dumpregs(out)
1549 dumpactions(out)
1550end
1551
1552-- Dump all user defined elements.
1553function _M.dumpdef(out, lvl)
1554 dumptypes(out, lvl)
1555 dumpglobals(out, lvl)
1556end
1557
1558------------------------------------------------------------------------------
1559
1560-- Pass callbacks from/to the DynASM core.
1561function _M.passcb(wl, we, wf, ww)
1562 wline, werror, wfatal, wwarn = wl, we, wf, ww
1563 return wflush
1564end
1565
1566-- Setup the arch-specific module.
1567function _M.setup(arch, opt)
1568 g_arch, g_opt = arch, opt
1569end
1570
1571-- Merge the core maps and the arch-specific maps.
1572function _M.mergemaps(map_coreop, map_def)
1573 setmetatable(map_op, { __index = map_coreop })
1574 setmetatable(map_def, { __index = map_archdef })
1575 return map_op, map_def
1576end
1577
1578return _M
1579
1580------------------------------------------------------------------------------
1581
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua b/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua
new file mode 100644
index 0000000..264a4bb
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua
@@ -0,0 +1,1070 @@
1------------------------------------------------------------------------------
2-- DynASM. A dynamic assembler for code generation engines.
3-- Originally designed and implemented for LuaJIT.
4--
5-- Copyright (C) 2005-2008 Mike Pall. All rights reserved.
6-- See below for full copyright notice.
7------------------------------------------------------------------------------
8
9-- Application information.
10local _info = {
11 name = "DynASM",
12 description = "A dynamic assembler for code generation engines",
13 version = "1.1.4",
14 vernum = 10104,
15 release = "2008-01-29",
16 author = "Mike Pall",
17 url = "http://luajit.org/dynasm.html",
18 license = "MIT",
19 copyright = [[
20Copyright (C) 2005-2008 Mike Pall. All rights reserved.
21
22Permission is hereby granted, free of charge, to any person obtaining
23a copy of this software and associated documentation files (the
24"Software"), to deal in the Software without restriction, including
25without limitation the rights to use, copy, modify, merge, publish,
26distribute, sublicense, and/or sell copies of the Software, and to
27permit persons to whom the Software is furnished to do so, subject to
28the following conditions:
29
30The above copyright notice and this permission notice shall be
31included in all copies or substantial portions of the Software.
32
33THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
35MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
36IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
37CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
38TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
39SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40
41[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
42]],
43}
44
45-- Cache library functions.
46local type, pairs, ipairs = type, pairs, ipairs
47local pcall, error, assert = pcall, error, assert
48local _s = string
49local sub, match, gmatch, gsub = _s.sub, _s.match, _s.gmatch, _s.gsub
50local format, rep, upper = _s.format, _s.rep, _s.upper
51local _t = table
52local insert, remove, concat, sort = _t.insert, _t.remove, _t.concat, _t.sort
53local exit = os.exit
54local io = io
55local stdin, stdout, stderr = io.stdin, io.stdout, io.stderr
56
57------------------------------------------------------------------------------
58
59-- Program options.
60local g_opt = {}
61
62-- Global state for current file.
63local g_fname, g_curline, g_indent, g_lineno, g_synclineno, g_arch
64local g_errcount = 0
65
66-- Write buffer for output file.
67local g_wbuffer, g_capbuffer
68
69------------------------------------------------------------------------------
70
71-- Write an output line (or callback function) to the buffer.
72local function wline(line, needindent)
73 local buf = g_capbuffer or g_wbuffer
74 buf[#buf+1] = needindent and g_indent..line or line
75 g_synclineno = g_synclineno + 1
76end
77
78-- Write assembler line as a comment, if requestd.
79local function wcomment(aline)
80 if g_opt.comment then
81 wline(g_opt.comment..aline..g_opt.endcomment, true)
82 end
83end
84
85-- Resync CPP line numbers.
86local function wsync()
87 if g_synclineno ~= g_lineno and g_opt.cpp then
88 wline("# "..g_lineno..' "'..g_fname..'"')
89 g_synclineno = g_lineno
90 end
91end
92
93-- Dummy action flush function. Replaced with arch-specific function later.
94local function wflush(term)
95end
96
97-- Dump all buffered output lines.
98local function wdumplines(out, buf)
99 for _,line in ipairs(buf) do
100 if type(line) == "string" then
101 assert(out:write(line, "\n"))
102 else
103 -- Special callback to dynamically insert lines after end of processing.
104 line(out)
105 end
106 end
107end
108
109------------------------------------------------------------------------------
110
111-- Emit an error. Processing continues with next statement.
112local function werror(msg)
113 error(format("%s:%s: error: %s:\n%s", g_fname, g_lineno, msg, g_curline), 0)
114end
115
116-- Emit a fatal error. Processing stops.
117local function wfatal(msg)
118 g_errcount = "fatal"
119 werror(msg)
120end
121
122-- Print a warning. Processing continues.
123local function wwarn(msg)
124 stderr:write(format("%s:%s: warning: %s:\n%s\n",
125 g_fname, g_lineno, msg, g_curline))
126end
127
128-- Print caught error message. But suppress excessive errors.
129local function wprinterr(...)
130 if type(g_errcount) == "number" then
131 -- Regular error.
132 g_errcount = g_errcount + 1
133 if g_errcount < 21 then -- Seems to be a reasonable limit.
134 stderr:write(...)
135 elseif g_errcount == 21 then
136 stderr:write(g_fname,
137 ":*: warning: too many errors (suppressed further messages).\n")
138 end
139 else
140 -- Fatal error.
141 stderr:write(...)
142 return true -- Stop processing.
143 end
144end
145
146------------------------------------------------------------------------------
147
148-- Map holding all option handlers.
149local opt_map = {}
150local opt_current
151
152-- Print error and exit with error status.
153local function opterror(...)
154 stderr:write("dynasm.lua: ERROR: ", ...)
155 stderr:write("\n")
156 exit(1)
157end
158
159-- Get option parameter.
160local function optparam(args)
161 local argn = args.argn
162 local p = args[argn]
163 if not p then
164 opterror("missing parameter for option `", opt_current, "'.")
165 end
166 args.argn = argn + 1
167 return p
168end
169
170------------------------------------------------------------------------------
171
172-- Core pseudo-opcodes.
173local map_coreop = {}
174-- Dummy opcode map. Replaced by arch-specific map.
175local map_op = {}
176
177-- Forward declarations.
178local dostmt
179local readfile
180
181------------------------------------------------------------------------------
182
183-- Map for defines (initially empty, chains to arch-specific map).
184local map_def = {}
185
186-- Pseudo-opcode to define a substitution.
187map_coreop[".define_2"] = function(params, nparams)
188 if not params then return nparams == 1 and "name" or "name, subst" end
189 local name, def = params[1], params[2] or "1"
190 if not match(name, "^[%a_][%w_]*$") then werror("bad or duplicate define") end
191 map_def[name] = def
192end
193map_coreop[".define_1"] = map_coreop[".define_2"]
194
195-- Define a substitution on the command line.
196function opt_map.D(args)
197 local namesubst = optparam(args)
198 local name, subst = match(namesubst, "^([%a_][%w_]*)=(.*)$")
199 if name then
200 map_def[name] = subst
201 elseif match(namesubst, "^[%a_][%w_]*$") then
202 map_def[namesubst] = "1"
203 else
204 opterror("bad define")
205 end
206end
207
208-- Undefine a substitution on the command line.
209function opt_map.U(args)
210 local name = optparam(args)
211 if match(name, "^[%a_][%w_]*$") then
212 map_def[name] = nil
213 else
214 opterror("bad define")
215 end
216end
217
218-- Helper for definesubst.
219local gotsubst
220
221local function definesubst_one(word)
222 local subst = map_def[word]
223 if subst then gotsubst = word; return subst else return word end
224end
225
226-- Iteratively substitute defines.
227local function definesubst(stmt)
228 -- Limit number of iterations.
229 for i=1,100 do
230 gotsubst = false
231 stmt = gsub(stmt, "#?[%w_]+", definesubst_one)
232 if not gotsubst then break end
233 end
234 if gotsubst then wfatal("recursive define involving `"..gotsubst.."'") end
235 return stmt
236end
237
238-- Dump all defines.
239local function dumpdefines(out, lvl)
240 local t = {}
241 for name in pairs(map_def) do
242 t[#t+1] = name
243 end
244 sort(t)
245 out:write("Defines:\n")
246 for _,name in ipairs(t) do
247 local subst = map_def[name]
248 if g_arch then subst = g_arch.revdef(subst) end
249 out:write(format(" %-20s %s\n", name, subst))
250 end
251 out:write("\n")
252end
253
254------------------------------------------------------------------------------
255
256-- Support variables for conditional assembly.
257local condlevel = 0
258local condstack = {}
259
260-- Evaluate condition with a Lua expression. Substitutions already performed.
261local function cond_eval(cond)
262 local func, err = loadstring("return "..cond)
263 if func then
264 setfenv(func, {}) -- No globals. All unknown identifiers evaluate to nil.
265 local ok, res = pcall(func)
266 if ok then
267 if res == 0 then return false end -- Oh well.
268 return not not res
269 end
270 err = res
271 end
272 wfatal("bad condition: "..err)
273end
274
275-- Skip statements until next conditional pseudo-opcode at the same level.
276local function stmtskip()
277 local dostmt_save = dostmt
278 local lvl = 0
279 dostmt = function(stmt)
280 local op = match(stmt, "^%s*(%S+)")
281 if op == ".if" then
282 lvl = lvl + 1
283 elseif lvl ~= 0 then
284 if op == ".endif" then lvl = lvl - 1 end
285 elseif op == ".elif" or op == ".else" or op == ".endif" then
286 dostmt = dostmt_save
287 dostmt(stmt)
288 end
289 end
290end
291
292-- Pseudo-opcodes for conditional assembly.
293map_coreop[".if_1"] = function(params)
294 if not params then return "condition" end
295 local lvl = condlevel + 1
296 local res = cond_eval(params[1])
297 condlevel = lvl
298 condstack[lvl] = res
299 if not res then stmtskip() end
300end
301
302map_coreop[".elif_1"] = function(params)
303 if not params then return "condition" end
304 if condlevel == 0 then wfatal(".elif without .if") end
305 local lvl = condlevel
306 local res = condstack[lvl]
307 if res then
308 if res == "else" then wfatal(".elif after .else") end
309 else
310 res = cond_eval(params[1])
311 if res then
312 condstack[lvl] = res
313 return
314 end
315 end
316 stmtskip()
317end
318
319map_coreop[".else_0"] = function(params)
320 if condlevel == 0 then wfatal(".else without .if") end
321 local lvl = condlevel
322 local res = condstack[lvl]
323 condstack[lvl] = "else"
324 if res then
325 if res == "else" then wfatal(".else after .else") end
326 stmtskip()
327 end
328end
329
330map_coreop[".endif_0"] = function(params)
331 local lvl = condlevel
332 if lvl == 0 then wfatal(".endif without .if") end
333 condlevel = lvl - 1
334end
335
336-- Check for unfinished conditionals.
337local function checkconds()
338 if g_errcount ~= "fatal" and condlevel ~= 0 then
339 wprinterr(g_fname, ":*: error: unbalanced conditional\n")
340 end
341end
342
343------------------------------------------------------------------------------
344
345-- Search for a file in the given path and open it for reading.
346local function pathopen(path, name)
347 local dirsep = match(package.path, "\\") and "\\" or "/"
348 for _,p in ipairs(path) do
349 local fullname = p == "" and name or p..dirsep..name
350 local fin = io.open(fullname, "r")
351 if fin then
352 g_fname = fullname
353 return fin
354 end
355 end
356end
357
358-- Include a file.
359map_coreop[".include_1"] = function(params)
360 if not params then return "filename" end
361 local name = params[1]
362 -- Save state. Ugly, I know. but upvalues are fast.
363 local gf, gl, gcl, gi = g_fname, g_lineno, g_curline, g_indent
364 -- Read the included file.
365 local fatal = readfile(pathopen(g_opt.include, name) or
366 wfatal("include file `"..name.."' not found"))
367 -- Restore state.
368 g_synclineno = -1
369 g_fname, g_lineno, g_curline, g_indent = gf, gl, gcl, gi
370 if fatal then wfatal("in include file") end
371end
372
373-- Make .include initially available, too.
374map_op[".include_1"] = map_coreop[".include_1"]
375
376------------------------------------------------------------------------------
377
378-- Support variables for macros.
379local mac_capture, mac_lineno, mac_name
380local mac_active = {}
381local mac_list = {}
382
383-- Pseudo-opcode to define a macro.
384map_coreop[".macro_*"] = function(mparams)
385 if not mparams then return "name [, params...]" end
386 -- Split off and validate macro name.
387 local name = remove(mparams, 1)
388 if not name then werror("missing macro name") end
389 if not (match(name, "^[%a_][%w_%.]*$") or match(name, "^%.[%w_%.]+$")) then
390 wfatal("bad macro name `"..name.."'")
391 end
392 -- Validate macro parameter names.
393 local mdup = {}
394 for _,mp in ipairs(mparams) do
395 if not match(mp, "^[%a_][%w_]*$") then
396 wfatal("bad macro parameter name `"..mp.."'")
397 end
398 if mdup[mp] then wfatal("duplicate macro parameter name `"..mp.."'") end
399 mdup[mp] = true
400 end
401 -- Check for duplicate or recursive macro definitions.
402 local opname = name.."_"..#mparams
403 if map_op[opname] or map_op[name.."_*"] then
404 wfatal("duplicate macro `"..name.."' ("..#mparams.." parameters)")
405 end
406 if mac_capture then wfatal("recursive macro definition") end
407
408 -- Enable statement capture.
409 local lines = {}
410 mac_lineno = g_lineno
411 mac_name = name
412 mac_capture = function(stmt) -- Statement capture function.
413 -- Stop macro definition with .endmacro pseudo-opcode.
414 if not match(stmt, "^%s*.endmacro%s*$") then
415 lines[#lines+1] = stmt
416 return
417 end
418 mac_capture = nil
419 mac_lineno = nil
420 mac_name = nil
421 mac_list[#mac_list+1] = opname
422 -- Add macro-op definition.
423 map_op[opname] = function(params)
424 if not params then return mparams, lines end
425 -- Protect against recursive macro invocation.
426 if mac_active[opname] then wfatal("recursive macro invocation") end
427 mac_active[opname] = true
428 -- Setup substitution map.
429 local subst = {}
430 for i,mp in ipairs(mparams) do subst[mp] = params[i] end
431 local mcom
432 if g_opt.maccomment and g_opt.comment then
433 mcom = " MACRO "..name.." ("..#mparams..")"
434 wcomment("{"..mcom)
435 end
436 -- Loop through all captured statements
437 for _,stmt in ipairs(lines) do
438 -- Substitute macro parameters.
439 local st = gsub(stmt, "[%w_]+", subst)
440 st = definesubst(st)
441 st = gsub(st, "%s*%.%.%s*", "") -- Token paste a..b.
442 if mcom and sub(st, 1, 1) ~= "|" then wcomment(st) end
443 -- Emit statement. Use a protected call for better diagnostics.
444 local ok, err = pcall(dostmt, st)
445 if not ok then
446 -- Add the captured statement to the error.
447 wprinterr(err, "\n", g_indent, "| ", stmt,
448 "\t[MACRO ", name, " (", #mparams, ")]\n")
449 end
450 end
451 if mcom then wcomment("}"..mcom) end
452 mac_active[opname] = nil
453 end
454 end
455end
456
457-- An .endmacro pseudo-opcode outside of a macro definition is an error.
458map_coreop[".endmacro_0"] = function(params)
459 wfatal(".endmacro without .macro")
460end
461
462-- Dump all macros and their contents (with -PP only).
463local function dumpmacros(out, lvl)
464 sort(mac_list)
465 out:write("Macros:\n")
466 for _,opname in ipairs(mac_list) do
467 local name = sub(opname, 1, -3)
468 local params, lines = map_op[opname]()
469 out:write(format(" %-20s %s\n", name, concat(params, ", ")))
470 if lvl > 1 then
471 for _,line in ipairs(lines) do
472 out:write(" |", line, "\n")
473 end
474 out:write("\n")
475 end
476 end
477 out:write("\n")
478end
479
480-- Check for unfinished macro definitions.
481local function checkmacros()
482 if mac_capture then
483 wprinterr(g_fname, ":", mac_lineno,
484 ": error: unfinished .macro `", mac_name ,"'\n")
485 end
486end
487
488------------------------------------------------------------------------------
489
490-- Support variables for captures.
491local cap_lineno, cap_name
492local cap_buffers = {}
493local cap_used = {}
494
495-- Start a capture.
496map_coreop[".capture_1"] = function(params)
497 if not params then return "name" end
498 wflush()
499 local name = params[1]
500 if not match(name, "^[%a_][%w_]*$") then
501 wfatal("bad capture name `"..name.."'")
502 end
503 if cap_name then
504 wfatal("already capturing to `"..cap_name.."' since line "..cap_lineno)
505 end
506 cap_name = name
507 cap_lineno = g_lineno
508 -- Create or continue a capture buffer and start the output line capture.
509 local buf = cap_buffers[name]
510 if not buf then buf = {}; cap_buffers[name] = buf end
511 g_capbuffer = buf
512 g_synclineno = 0
513end
514
515-- Stop a capture.
516map_coreop[".endcapture_0"] = function(params)
517 wflush()
518 if not cap_name then wfatal(".endcapture without a valid .capture") end
519 cap_name = nil
520 cap_lineno = nil
521 g_capbuffer = nil
522 g_synclineno = 0
523end
524
525-- Dump a capture buffer.
526map_coreop[".dumpcapture_1"] = function(params)
527 if not params then return "name" end
528 wflush()
529 local name = params[1]
530 if not match(name, "^[%a_][%w_]*$") then
531 wfatal("bad capture name `"..name.."'")
532 end
533 cap_used[name] = true
534 wline(function(out)
535 local buf = cap_buffers[name]
536 if buf then wdumplines(out, buf) end
537 end)
538 g_synclineno = 0
539end
540
541-- Dump all captures and their buffers (with -PP only).
542local function dumpcaptures(out, lvl)
543 out:write("Captures:\n")
544 for name,buf in pairs(cap_buffers) do
545 out:write(format(" %-20s %4s)\n", name, "("..#buf))
546 if lvl > 1 then
547 local bar = rep("=", 76)
548 out:write(" ", bar, "\n")
549 for _,line in ipairs(buf) do
550 out:write(" ", line, "\n")
551 end
552 out:write(" ", bar, "\n\n")
553 end
554 end
555 out:write("\n")
556end
557
558-- Check for unfinished or unused captures.
559local function checkcaptures()
560 if cap_name then
561 wprinterr(g_fname, ":", cap_lineno,
562 ": error: unfinished .capture `", cap_name,"'\n")
563 return
564 end
565 for name in pairs(cap_buffers) do
566 if not cap_used[name] then
567 wprinterr(g_fname, ":*: error: missing .dumpcapture ", name ,"\n")
568 end
569 end
570end
571
572------------------------------------------------------------------------------
573
574-- Sections names.
575local map_sections = {}
576
577-- Pseudo-opcode to define code sections.
578-- TODO: Data sections, BSS sections. Needs extra C code and API.
579map_coreop[".section_*"] = function(params)
580 if not params then return "name..." end
581 if #map_sections > 0 then werror("duplicate section definition") end
582 wflush()
583 for sn,name in ipairs(params) do
584 local opname = "."..name.."_0"
585 if not match(name, "^[%a][%w_]*$") or
586 map_op[opname] or map_op["."..name.."_*"] then
587 werror("bad section name `"..name.."'")
588 end
589 map_sections[#map_sections+1] = name
590 wline(format("#define DASM_SECTION_%s\t%d", upper(name), sn-1))
591 map_op[opname] = function(params) g_arch.section(sn-1) end
592 end
593 wline(format("#define DASM_MAXSECTION\t\t%d", #map_sections))
594end
595
596-- Dump all sections.
597local function dumpsections(out, lvl)
598 out:write("Sections:\n")
599 for _,name in ipairs(map_sections) do
600 out:write(format(" %s\n", name))
601 end
602 out:write("\n")
603end
604
605------------------------------------------------------------------------------
606
607-- Load architecture-specific module.
608local function loadarch(arch)
609 if not match(arch, "^[%w_]+$") then return "bad arch name" end
610 local ok, m_arch = pcall(require, "dasm_"..arch)
611 if not ok then return "cannot load module: "..m_arch end
612 g_arch = m_arch
613 wflush = m_arch.passcb(wline, werror, wfatal, wwarn)
614 m_arch.setup(arch, g_opt)
615 map_op, map_def = m_arch.mergemaps(map_coreop, map_def)
616end
617
618-- Dump architecture description.
619function opt_map.dumparch(args)
620 local name = optparam(args)
621 if not g_arch then
622 local err = loadarch(name)
623 if err then opterror(err) end
624 end
625
626 local t = {}
627 for name in pairs(map_coreop) do t[#t+1] = name end
628 for name in pairs(map_op) do t[#t+1] = name end
629 sort(t)
630
631 local out = stdout
632 local _arch = g_arch._info
633 out:write(format("%s version %s, released %s, %s\n",
634 _info.name, _info.version, _info.release, _info.url))
635 g_arch.dumparch(out)
636
637 local pseudo = true
638 out:write("Pseudo-Opcodes:\n")
639 for _,sname in ipairs(t) do
640 local name, nparam = match(sname, "^(.+)_([0-9%*])$")
641 if name then
642 if pseudo and sub(name, 1, 1) ~= "." then
643 out:write("\nOpcodes:\n")
644 pseudo = false
645 end
646 local f = map_op[sname]
647 local s
648 if nparam ~= "*" then nparam = nparam + 0 end
649 if nparam == 0 then
650 s = ""
651 elseif type(f) == "string" then
652 s = map_op[".template__"](nil, f, nparam)
653 else
654 s = f(nil, nparam)
655 end
656 if type(s) == "table" then
657 for _,s2 in ipairs(s) do
658 out:write(format(" %-12s %s\n", name, s2))
659 end
660 else
661 out:write(format(" %-12s %s\n", name, s))
662 end
663 end
664 end
665 out:write("\n")
666 exit(0)
667end
668
669-- Pseudo-opcode to set the architecture.
670-- Only initially available (map_op is replaced when called).
671map_op[".arch_1"] = function(params)
672 if not params then return "name" end
673 local err = loadarch(params[1])
674 if err then wfatal(err) end
675end
676
677-- Dummy .arch pseudo-opcode to improve the error report.
678map_coreop[".arch_1"] = function(params)
679 if not params then return "name" end
680 wfatal("duplicate .arch statement")
681end
682
683------------------------------------------------------------------------------
684
685-- Dummy pseudo-opcode. Don't confuse '.nop' with 'nop'.
686map_coreop[".nop_*"] = function(params)
687 if not params then return "[ignored...]" end
688end
689
690-- Pseudo-opcodes to raise errors.
691map_coreop[".error_1"] = function(params)
692 if not params then return "message" end
693 werror(params[1])
694end
695
696map_coreop[".fatal_1"] = function(params)
697 if not params then return "message" end
698 wfatal(params[1])
699end
700
701-- Dump all user defined elements.
702local function dumpdef(out)
703 local lvl = g_opt.dumpdef
704 if lvl == 0 then return end
705 dumpsections(out, lvl)
706 dumpdefines(out, lvl)
707 if g_arch then g_arch.dumpdef(out, lvl) end
708 dumpmacros(out, lvl)
709 dumpcaptures(out, lvl)
710end
711
712------------------------------------------------------------------------------
713
714-- Helper for splitstmt.
715local splitlvl
716
717local function splitstmt_one(c)
718 if c == "(" then
719 splitlvl = ")"..splitlvl
720 elseif c == "[" then
721 splitlvl = "]"..splitlvl
722 elseif c == ")" or c == "]" then
723 if sub(splitlvl, 1, 1) ~= c then werror("unbalanced () or []") end
724 splitlvl = sub(splitlvl, 2)
725 elseif splitlvl == "" then
726 return " \0 "
727 end
728 return c
729end
730
731-- Split statement into (pseudo-)opcode and params.
732local function splitstmt(stmt)
733 -- Convert label with trailing-colon into .label statement.
734 local label = match(stmt, "^%s*(.+):%s*$")
735 if label then return ".label", {label} end
736
737 -- Split at commas and equal signs, but obey parentheses and brackets.
738 splitlvl = ""
739 stmt = gsub(stmt, "[,%(%)%[%]]", splitstmt_one)
740 if splitlvl ~= "" then werror("unbalanced () or []") end
741
742 -- Split off opcode.
743 local op, other = match(stmt, "^%s*([^%s%z]+)%s*(.*)$")
744 if not op then werror("bad statement syntax") end
745
746 -- Split parameters.
747 local params = {}
748 for p in gmatch(other, "%s*(%Z+)%z?") do
749 params[#params+1] = gsub(p, "%s+$", "")
750 end
751 if #params > 16 then werror("too many parameters") end
752
753 params.op = op
754 return op, params
755end
756
757-- Process a single statement.
758dostmt = function(stmt)
759 -- Ignore empty statements.
760 if match(stmt, "^%s*$") then return end
761
762 -- Capture macro defs before substitution.
763 if mac_capture then return mac_capture(stmt) end
764 stmt = definesubst(stmt)
765
766 -- Emit C code without parsing the line.
767 if sub(stmt, 1, 1) == "|" then
768 local tail = sub(stmt, 2)
769 wflush()
770 if sub(tail, 1, 2) == "//" then wcomment(tail) else wline(tail, true) end
771 return
772 end
773
774 -- Split into (pseudo-)opcode and params.
775 local op, params = splitstmt(stmt)
776
777 -- Get opcode handler (matching # of parameters or generic handler).
778 local f = map_op[op.."_"..#params] or map_op[op.."_*"]
779 if not f then
780 if not g_arch then wfatal("first statement must be .arch") end
781 -- Improve error report.
782 for i=0,16 do
783 if map_op[op.."_"..i] then
784 werror("wrong number of parameters for `"..op.."'")
785 end
786 end
787 werror("unknown statement `"..op.."'")
788 end
789
790 -- Call opcode handler or special handler for template strings.
791 if type(f) == "string" then
792 map_op[".template__"](params, f)
793 else
794 f(params)
795 end
796end
797
798-- Process a single line.
799local function doline(line)
800 if g_opt.flushline then wflush() end
801
802 -- Assembler line?
803 local indent, aline = match(line, "^(%s*)%|(.*)$")
804 if not aline then
805 -- No, plain C code line, need to flush first.
806 wflush()
807 wsync()
808 wline(line, false)
809 return
810 end
811
812 g_indent = indent -- Remember current line indentation.
813
814 -- Emit C code (even from macros). Avoids echo and line parsing.
815 if sub(aline, 1, 1) == "|" then
816 if not mac_capture then
817 wsync()
818 elseif g_opt.comment then
819 wsync()
820 wcomment(aline)
821 end
822 dostmt(aline)
823 return
824 end
825
826 -- Echo assembler line as a comment.
827 if g_opt.comment then
828 wsync()
829 wcomment(aline)
830 end
831
832 -- Strip assembler comments.
833 aline = gsub(aline, "//.*$", "")
834
835 -- Split line into statements at semicolons.
836 if match(aline, ";") then
837 for stmt in gmatch(aline, "[^;]+") do dostmt(stmt) end
838 else
839 dostmt(aline)
840 end
841end
842
843------------------------------------------------------------------------------
844
845-- Write DynASM header.
846local function dasmhead(out)
847 out:write(format([[
848/*
849** This file has been pre-processed with DynASM.
850** %s
851** DynASM version %s, DynASM %s version %s
852** DO NOT EDIT! The original file is in "%s".
853*/
854
855#if DASM_VERSION != %d
856#error "Version mismatch between DynASM and included encoding engine"
857#endif
858
859]], _info.url,
860 _info.version, g_arch._info.arch, g_arch._info.version,
861 g_fname, _info.vernum))
862end
863
864-- Read input file.
865readfile = function(fin)
866 g_indent = ""
867 g_lineno = 0
868 g_synclineno = -1
869
870 -- Process all lines.
871 for line in fin:lines() do
872 g_lineno = g_lineno + 1
873 g_curline = line
874 local ok, err = pcall(doline, line)
875 if not ok and wprinterr(err, "\n") then return true end
876 end
877 wflush()
878
879 -- Close input file.
880 assert(fin == stdin or fin:close())
881end
882
883-- Write output file.
884local function writefile(outfile)
885 local fout
886
887 -- Open output file.
888 if outfile == nil or outfile == "-" then
889 fout = stdout
890 else
891 fout = assert(io.open(outfile, "w"))
892 end
893
894 -- Write all buffered lines
895 wdumplines(fout, g_wbuffer)
896
897 -- Close output file.
898 assert(fout == stdout or fout:close())
899
900 -- Optionally dump definitions.
901 dumpdef(fout == stdout and stderr or stdout)
902end
903
904-- Translate an input file to an output file.
905local function translate(infile, outfile)
906 g_wbuffer = {}
907 g_indent = ""
908 g_lineno = 0
909 g_synclineno = -1
910
911 -- Put header.
912 wline(dasmhead)
913
914 -- Read input file.
915 local fin
916 if infile == "-" then
917 g_fname = "(stdin)"
918 fin = stdin
919 else
920 g_fname = infile
921 fin = assert(io.open(infile, "r"))
922 end
923 readfile(fin)
924
925 -- Check for errors.
926 if not g_arch then
927 wprinterr(g_fname, ":*: error: missing .arch directive\n")
928 end
929 checkconds()
930 checkmacros()
931 checkcaptures()
932
933 if g_errcount ~= 0 then
934 stderr:write(g_fname, ":*: info: ", g_errcount, " error",
935 (type(g_errcount) == "number" and g_errcount > 1) and "s" or "",
936 " in input file -- no output file generated.\n")
937 dumpdef(stderr)
938 exit(1)
939 end
940
941 -- Write output file.
942 writefile(outfile)
943end
944
945------------------------------------------------------------------------------
946
947-- Print help text.
948function opt_map.help()
949 stdout:write("DynASM -- ", _info.description, ".\n")
950 stdout:write("DynASM ", _info.version, " ", _info.release, " ", _info.url, "\n")
951 stdout:write[[
952
953Usage: dynasm [OPTION]... INFILE.dasc|-
954
955 -h, --help Display this help text.
956 -V, --version Display version and copyright information.
957
958 -o, --outfile FILE Output file name (default is stdout).
959 -I, --include DIR Add directory to the include search path.
960
961 -c, --ccomment Use /* */ comments for assembler lines.
962 -C, --cppcomment Use // comments for assembler lines (default).
963 -N, --nocomment Suppress assembler lines in output.
964 -M, --maccomment Show macro expansions as comments (default off).
965
966 -L, --nolineno Suppress CPP line number information in output.
967 -F, --flushline Flush action list for every line.
968
969 -D NAME[=SUBST] Define a substitution.
970 -U NAME Undefine a substitution.
971
972 -P, --dumpdef Dump defines, macros, etc. Repeat for more output.
973 -A, --dumparch ARCH Load architecture ARCH and dump description.
974]]
975 exit(0)
976end
977
978-- Print version information.
979function opt_map.version()
980 stdout:write(format("%s version %s, released %s\n%s\n\n%s",
981 _info.name, _info.version, _info.release, _info.url, _info.copyright))
982 exit(0)
983end
984
985-- Misc. options.
986function opt_map.outfile(args) g_opt.outfile = optparam(args) end
987function opt_map.include(args) insert(g_opt.include, 1, optparam(args)) end
988function opt_map.ccomment() g_opt.comment = "/*|"; g_opt.endcomment = " */" end
989function opt_map.cppcomment() g_opt.comment = "//|"; g_opt.endcomment = "" end
990function opt_map.nocomment() g_opt.comment = false end
991function opt_map.maccomment() g_opt.maccomment = true end
992function opt_map.nolineno() g_opt.cpp = false end
993function opt_map.flushline() g_opt.flushline = true end
994function opt_map.dumpdef() g_opt.dumpdef = g_opt.dumpdef + 1 end
995
996------------------------------------------------------------------------------
997
998-- Short aliases for long options.
999local opt_alias = {
1000 h = "help", ["?"] = "help", V = "version",
1001 o = "outfile", I = "include",
1002 c = "ccomment", C = "cppcomment", N = "nocomment", M = "maccomment",
1003 L = "nolineno", F = "flushline",
1004 P = "dumpdef", A = "dumparch",
1005}
1006
1007-- Parse single option.
1008local function parseopt(opt, args)
1009 opt_current = #opt == 1 and "-"..opt or "--"..opt
1010 local f = opt_map[opt] or opt_map[opt_alias[opt]]
1011 if not f then
1012 opterror("unrecognized option `", opt_current, "'. Try `--help'.\n")
1013 end
1014 f(args)
1015end
1016
1017-- Parse arguments.
1018local function parseargs(args)
1019 -- Default options.
1020 g_opt.comment = "//|"
1021 g_opt.endcomment = ""
1022 g_opt.cpp = true
1023 g_opt.dumpdef = 0
1024 g_opt.include = { "" }
1025
1026 -- Process all option arguments.
1027 args.argn = 1
1028 repeat
1029 local a = args[args.argn]
1030 if not a then break end
1031 local lopt, opt = match(a, "^%-(%-?)(.+)")
1032 if not opt then break end
1033 args.argn = args.argn + 1
1034 if lopt == "" then
1035 -- Loop through short options.
1036 for o in gmatch(opt, ".") do parseopt(o, args) end
1037 else
1038 -- Long option.
1039 parseopt(opt, args)
1040 end
1041 until false
1042
1043 -- Check for proper number of arguments.
1044 local nargs = #args - args.argn + 1
1045 if nargs ~= 1 then
1046 if nargs == 0 then
1047 if g_opt.dumpdef > 0 then return dumpdef(stdout) end
1048 end
1049 opt_map.help()
1050 end
1051
1052 -- Translate a single input file to a single output file
1053 -- TODO: Handle multiple files?
1054 translate(args[args.argn], g_opt.outfile)
1055end
1056
1057------------------------------------------------------------------------------
1058
1059-- Add the directory dynasm.lua resides in to the Lua module search path.
1060local arg = arg
1061if arg and arg[0] then
1062 local prefix = match(arg[0], "^(.*/)")
1063 if prefix then package.path = prefix.."?.lua;"..package.path end
1064end
1065
1066-- Start DynASM.
1067parseargs{...}
1068
1069------------------------------------------------------------------------------
1070
diff --git a/libraries/LuaJIT-1.1.7/etc/README b/libraries/LuaJIT-1.1.7/etc/README
new file mode 100644
index 0000000..98117d0
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/README
@@ -0,0 +1,20 @@
1This directory contains some useful files and code.
2Unlike the code in ../src, everything here is in the public domain.
3
4lua.hpp
5 Lua header files for C++ using 'extern "C"'.
6
7luajit.ico
8 A LuaJIT icon for Windows (and web sites: save as favicon.ico).
9 Lua icon drawn by hand by Markus Gritsch. Modified for LuaJIT.
10
11luajit.pc
12 pkg-config data for LuaJIT
13
14luavs.bat
15 Script to build LuaJIT under "Visual Studio .NET Command Prompt".
16 Run it from the toplevel as etc\luavs.bat.
17
18strict.lua
19 Traps uses of undeclared global variables.
20
diff --git a/libraries/LuaJIT-1.1.7/etc/lua.hpp b/libraries/LuaJIT-1.1.7/etc/lua.hpp
new file mode 100644
index 0000000..ec417f5
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/lua.hpp
@@ -0,0 +1,9 @@
1// lua.hpp
2// Lua header files for C++
3// <<extern "C">> not supplied automatically because Lua also compiles as C++
4
5extern "C" {
6#include "lua.h"
7#include "lualib.h"
8#include "lauxlib.h"
9}
diff --git a/libraries/LuaJIT-1.1.7/etc/luajit.ico b/libraries/LuaJIT-1.1.7/etc/luajit.ico
new file mode 100644
index 0000000..bdd7a90
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/luajit.ico
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/etc/luajit.pc b/libraries/LuaJIT-1.1.7/etc/luajit.pc
new file mode 100644
index 0000000..1444076
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/luajit.pc
@@ -0,0 +1,28 @@
1# luajit.pc -- pkg-config data for LuaJIT
2
3# vars from install Makefile
4
5# grep '^J*V=' ../Makefile
6V= 5.1
7JV= 1.1.7
8
9# grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/'
10prefix= /usr/local
11INSTALL_BIN= ${prefix}/bin
12INSTALL_INC= ${prefix}/include
13INSTALL_LIB= ${prefix}/lib
14INSTALL_MAN= ${prefix}/man/man1
15INSTALL_LMOD= ${prefix}/share/lua/${V}
16INSTALL_CMOD= ${prefix}/lib/lua/${V}
17
18exec_prefix=${prefix}
19libdir=${exec_prefix}/lib
20includedir=${prefix}/include
21
22Name: LuaJIT
23Description: An Extensible Extension Language (JIT compiled for speed)
24Version: ${JV}
25Requires:
26Libs: -L${libdir} -llua -lm
27Cflags: -I${includedir}
28
diff --git a/libraries/LuaJIT-1.1.7/etc/luavs.bat b/libraries/LuaJIT-1.1.7/etc/luavs.bat
new file mode 100755
index 0000000..4f311e2
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/luavs.bat
@@ -0,0 +1,22 @@
1@rem Script to build LuaJIT under "Visual Studio .NET Command Prompt".
2@rem Do not run from this directory; run it from the toplevel: etc\luavs.bat .
3@rem It creates lua51.dll, lua51.lib and luajit.exe in src.
4@rem (contributed by David Manura and Mike Pall)
5
6@setlocal
7@set MYCOMPILE=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE /I . /I ..\dynasm
8@set MYLINK=link /nologo
9@set MYMT=mt /nologo
10
11cd src
12%MYCOMPILE% /DLUA_BUILD_AS_DLL l*.c
13del lua.obj luac.obj
14%MYLINK% /DLL /out:lua51.dll l*.obj
15if exist lua51.dll.manifest^
16 %MYMT% -manifest lua51.dll.manifest -outputresource:lua51.dll;2
17%MYCOMPILE% /DLUA_BUILD_AS_DLL lua.c
18%MYLINK% /out:luajit.exe lua.obj lua51.lib
19if exist luajit.exe.manifest^
20 %MYMT% -manifest luajit.exe.manifest -outputresource:luajit.exe
21del *.obj *.manifest
22cd ..
diff --git a/libraries/LuaJIT-1.1.7/etc/strict.lua b/libraries/LuaJIT-1.1.7/etc/strict.lua
new file mode 100644
index 0000000..604619d
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/strict.lua
@@ -0,0 +1,41 @@
1--
2-- strict.lua
3-- checks uses of undeclared global variables
4-- All global variables must be 'declared' through a regular assignment
5-- (even assigning nil will do) in a main chunk before being used
6-- anywhere or assigned to inside a function.
7--
8
9local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget
10
11local mt = getmetatable(_G)
12if mt == nil then
13 mt = {}
14 setmetatable(_G, mt)
15end
16
17mt.__declared = {}
18
19local function what ()
20 local d = getinfo(3, "S")
21 return d and d.what or "C"
22end
23
24mt.__newindex = function (t, n, v)
25 if not mt.__declared[n] then
26 local w = what()
27 if w ~= "main" and w ~= "C" then
28 error("assign to undeclared variable '"..n.."'", 2)
29 end
30 mt.__declared[n] = true
31 end
32 rawset(t, n, v)
33end
34
35mt.__index = function (t, n)
36 if not mt.__declared[n] and what() ~= "C" then
37 error("variable '"..n.."' is not declared", 2)
38 end
39 return rawget(t, n)
40end
41
diff --git a/libraries/LuaJIT-1.1.7/jit/dis_x86.lua b/libraries/LuaJIT-1.1.7/jit/dis_x86.lua
new file mode 100644
index 0000000..b9ca150
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/dis_x86.lua
@@ -0,0 +1,622 @@
1----------------------------------------------------------------------------
2-- LuaJIT x86 disassembler module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- This is a helper module used by the LuaJIT machine code dumper module.
8--
9-- Sending small code snippets to an external disassembler and mixing the
10-- output with our own stuff was too fragile. So I had to bite the bullet
11-- and write yet another x86 disassembler. Oh well ...
12--
13-- The output format is very similar to what ndisasm generates. But it has
14-- been developed independently by looking at the opcode tables from the
15-- Intel and AMD manuals. The supported instruction set is quite extensive
16-- and reflects what a current generation P4 or K8 implements in 32 bit
17-- mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3 and even privileged
18-- instructions.
19--
20-- Notes:
21-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
22-- * No attempt at optimization has been made -- it's fast enough for my needs.
23-- * The public API may change when more architectures are added.
24--
25-- TODO:
26-- * More testing with arbitrary x86 code (not just LuaJIT generated code).
27-- * The output for a few MMX/SSE opcodes could be improved.
28-- * Adding x64 support would be straightforward.
29-- * Better input API (iterator) and output API (structured access to instr).
30------------------------------------------------------------------------------
31
32local type = type
33local sub, byte, format = string.sub, string.byte, string.format
34local match, gmatch, gsub = string.match, string.gmatch, string.gsub
35
36-- Map for 1st opcode byte. Ugly? Well ... read on.
37local map_opc1 = {
38--0x
39[0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es",
40"orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*",
41--1x
42"adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss",
43"sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds",
44--2x
45"andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa",
46"subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das",
47--3x
48"xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa",
49"cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas",
50--4x
51"incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR",
52"decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR",
53--5x
54"pushVR","pushVR","pushVR","pushVR","pushVR","pushVR","pushVR","pushVR",
55"popVR","popVR","popVR","popVR","popVR","popVR","popVR","popVR",
56--6x
57"pusha/pushaw","popa/popaw","boundVrm","arplWmr",
58"fs:seg","gs:seg","o16:","a16",
59"pushVi","imulVrmi","pushBs","imulVrms",
60"insb","insd/insw","outsb","outsd/outsw",
61--7x
62"joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj",
63"jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj",
64--8x
65"arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms",
66"testBmr","testVmr","xchgBrm","xchgVrm",
67"movBmr","movVmr","movBrm","movVrm",
68"movVmg","leaVrm","movWgm","popVm",
69--9x
70"nop|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR",
71"xchgVaR","xchgVaR","xchgVaR","xchgVaR",
72"cwde/cbw","cdq/cwd","call farViw","wait",
73"pushf/pushfw","popf/popfw","sahf","lahf",
74--Ax
75"movBao","movVao","movBoa","movVoa",
76"movsb","movsd/movsb","cmpsb","cmpsd/cmpsw",
77"testBai","testVai","stosb","stosd/stosw",
78"lodsb","lodsd/lodsw","scasb","scasd/scasw",
79--Bx
80"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
81"movVRi","movVRi","movVRi","movVRi","movVRi","movVRi","movVRi","movVRi",
82--Cx
83"shift!Bmu","shift!Vmu","retBw","ret","lesVrm","ldsVrm","movBmi","movVmi",
84"enterBwu","leave","retfBw","retf","int3","intBu","into","iret/iretw",
85--Dx
86"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
87"fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7",
88--Ex
89"loopneBj","loopeBj","loopBj","jecxz/jcxzBj","inBau","inVau","outBua","outVua",
90"callDj","jmpDj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda",
91--Fx
92"lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm",
93"clc","stc","cli","sti","cld","std","inc!Bm","inc!Vm",
94}
95assert(#map_opc1 == 255)
96
97-- Map for 2nd opcode byte (0f xx). True CISC hell. Hey, I told you.
98-- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne
99local map_opc2 = {
100--0x
101[0]="sldt!Dmp","sgdt!Dmp","larVrm","lslVrm",nil,"syscall","clts","sysret",
102"invd","wbinvd",nil,"ud1",nil,"prefetch!Bm","femms","3dnowMrmu",
103--1x
104"movupsXrm|movssXrm|movupdXrm|movsdXrm",
105"movupsXmr|movssXmr|movupdXmr|movsdXmr",
106"movhlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", -- TODO: movlpsXrMm (mem case).
107"movlpsXmr||movlpdXmr",
108"unpcklpsXrm||unpcklpdXrm",
109"unpckhpsXrm||unpckhpdXrm",
110"movlhpsXrm|movshdupXrm|movhpdXrm", -- TODO: movhpsXrMm (mem case).
111"movhpsXmr||movhpdXmr",
112"prefetcht!Bm","hintnopBm","hintnopBm","hintnopBm",
113"hintnopBm","hintnopBm","hintnopBm","hintnopBm",
114--2x
115"movDmx","movDmy","movDxm","movDym","movDmz",nil,"movDzm",nil,
116"movapsXrm||movapdXrm",
117"movapsXmr||movapdXmr",
118"cvtpi2psXrMm|cvtsi2ssXrDm|cvtpi2pdXrMm|cvtsi2sdXrDm",
119"movntpsXmr||movntpdXmr",
120"cvttps2piMrXm|cvttss2siDrXm|cvttpd2piMrXm|cvttsd2siDrXm",
121"cvtps2piMrXm|cvtss2siDrXm|cvtpd2piMrXm|cvtsd2siDrXm",
122"ucomissXrm||ucomisdXrm",
123"comissXrm||comisdXrm",
124--3x
125"wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,nil,
126"ssse3*38",nil,"ssse3*3a",nil,nil,nil,nil,nil,
127--4x
128"cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm",
129"cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm",
130"cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm",
131"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
132--5x
133"movmskpsDrXm||movmskpdDrXm","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
134"rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm",
135"andpsXrm||andpdXrm","andnpsXrm||andnpdXrm",
136"orpsXrm||orpdXrm","xorpsXrm||xorpdXrm",
137"addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm",
138"cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm",
139"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
140"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm",
141"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm",
142--6x
143"punpcklbwMrm||punpcklbqXrm","punpcklwdPrm","punpckldqPrm","packsswbPrm",
144"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm",
145"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm",
146"||punpcklqdqXrm","||punpckhqdqXrm",
147"movdPrDm","movqMrm|movdquXrm|movdqaXrm",
148--7x
149"pshufwPrmu","pshiftw!Pmu","pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
150"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|",
151nil,nil,nil,nil,
152"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm",
153"movdDmMr|movqXrm|movdDmXr","movqMmr|movdquXmr|movdqaXmr",
154--8x
155"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
156"jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj",
157--9x
158"setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm",
159"setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm",
160--Ax
161"push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil,
162"push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm",
163--Bx
164"cmpxchgBmr","cmpxchgVmr","lssVrm","btrVmr",
165"lfsVrm","lgsVrm","movzxVrBm","movzxDrWm",
166nil,"ud2","bt!Vmu","btcVmr",
167"bsfVrm","bsrVrm","movsxVrBm","movsxDrWm",
168--Cx
169"xaddBmr","xaddVmr",
170"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","movntiDmr|",
171"pinsrwPrWmu","pextrwDrPmu",
172"shufpsXrmu||shufpdXrmu","cmpxchg!Dmp",
173"bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR",
174--Dx
175"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm",
176"paddqPrm","pmullwPrm",
177"|movq2dqXrMm|movqXmr|movdq2qMrXm","pmovmskbDrPm",
178"psubusbPrm","psubuswPrm","pminubPrm","pandPrm",
179"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm",
180--Ex
181"pavgbPrm","psrawPrm","psradPrm","pavgwPrm",
182"pmulhuwPrm","pmulhwPrm",
183"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","movntqMmr||movntdqXmr",
184"psubsbPrm","psubswPrm","pminswPrm","porPrm",
185"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm",
186--Fx
187"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm",
188"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm",
189"psubbPrm","psubwPrm","psubdPrm","psubqPrm",
190"paddbPrm","paddwPrm","padddPrm","ud",
191}
192assert(map_opc2[255] == "ud")
193
194-- Map for SSSE3 opcodes.
195local map_ssse3 = {
196["38"] = { -- [66] 0f 38 xx
197--0x
198[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm",
199"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm",
200"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm",
201nil,nil,nil,nil,
202--1x
203nil,nil,nil,nil,nil,nil,nil,nil,
204nil,nil,nil,nil,"pabsbPrm","pabswPrm","pabsdPrm",nil,
205},
206["3a"] = { -- [66] 0f 3a xx
207[0x0f] = "palignrPrmu",
208},
209}
210
211-- Map for FP opcodes. And you thought stack machines are simple?
212local map_opcfp = {
213-- D8-DF 00-BF: opcodes with a memory operand.
214-- D8
215[0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm",
216"fldFm",nil,"fstFm","fstpFm","fldenvDmp","fldcwWm","fnstenvDmp","fnstcwWm",
217-- DA
218"fiaddDm","fimulDm","ficomDm","ficompDm",
219"fisubDm","fisubrDm","fidivDm","fidivrDm",
220-- DB
221"fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp",
222-- DC
223"faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm",
224-- DD
225"fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm",
226-- DE
227"fiaddWm","fimulWm","ficomWm","ficompWm",
228"fisubWm","fisubrWm","fidivWm","fidivrWm",
229-- DF
230"fildWm","fisttpWm","fistWm","fistpWm",
231"fbld twordFmp","fildQm","fbstp twordFmp","fistpQm",
232-- xx C0-FF: opcodes with a pseudo-register operand.
233-- D8
234"faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf",
235-- D9
236"fldFf","fxchFf",{"fnop"},nil,
237{"fchs","fabs",nil,nil,"ftst","fxam"},
238{"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"},
239{"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"},
240{"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"},
241-- DA
242"fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil,
243-- DB
244"fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf",
245{nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil,
246-- DC
247"fadd toFf","fmul toFf",nil,nil,
248"fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf",
249-- DD
250"ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil,
251-- DE
252"faddpFf","fmulpFf",nil,{nil,"fcompp"},
253"fsubrpFf","fsubpFf","fdivrpFf","fdivpFf",
254-- DF
255nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil,
256}
257assert(map_opcfp[126] == "fcomipFf")
258
259-- Map for opcode groups. The subkey is sp from the ModRM byte.
260local map_opcgroup = {
261 arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" },
262 shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" },
263 testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" },
264 testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" },
265 inc = { "inc", "dec", "callDmp", "call farDmp",
266 "jmpDmp", "jmp farDmp", "push" },
267 sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" },
268 sgdt = { "sgdt", "sidt", "lgdt", "lidt", "smsw", nil, "lmsw", "invlpg" },
269 bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" },
270 cmpxchg = { nil, "cmpxchg8b" },
271 pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" },
272 pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" },
273 pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" },
274 pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" },
275 fxsave = { "fxsave", "fxrstor", "ldmxcsr", "stmxcsr",
276 nil, "lfenceDp", "mfenceDp", "sfenceDp" }, -- TODO: clflush.
277 prefetch = { "prefetch", "prefetchw" },
278 prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" },
279}
280
281------------------------------------------------------------------------------
282
283-- Maps for register names.
284local map_aregs = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" }
285local map_regs = {
286 B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" },
287 W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" },
288 D = map_aregs,
289 M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" },
290 X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" },
291}
292local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
293
294-- Maps for size names.
295local map_sz2n = {
296 B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16,
297}
298local map_sz2prefix = {
299 B = "byte", W = "word", D = "dword",
300 Q = "qword", -- No associated reg in 32 bit mode.
301 F = "dword", G = "qword", -- No need for sizes/register names for these two.
302 M = "qword", X = "xword",
303}
304
305------------------------------------------------------------------------------
306
307-- Output a nicely formatted line with an opcode and operands.
308local function putop(ctx, text, operands)
309 local code, pos, hex = ctx.code, ctx.pos, ""
310 for i=ctx.start,pos-1 do
311 hex = hex..format("%02X", byte(code, i, i))
312 end
313 if #hex > 16 then hex = sub(hex, 1, 16).."." end
314 if operands then text = text.." "..operands end
315 if ctx.o16 then text = "o16 "..text; ctx.o16 = false end
316 if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
317 if ctx.seg then
318 local text2, n = gsub(text, "%[", "["..ctx.seg..":")
319 if n == 0 then text = ctx.seg.." "..text else text = text2 end
320 ctx.seg = false
321 end
322 if ctx.lock then text = "lock "..text; ctx.lock = false end
323 local imm = ctx.imm
324 if imm then
325 local sym = ctx.symtab[imm]
326 if sym then text = text.."\t->"..sym end
327 end
328 ctx.out(format("%08x %-18s%s\n", ctx.addr+ctx.start, hex, text))
329 ctx.mrm = false
330 ctx.start = pos
331 ctx.imm = nil
332end
333
334-- Fallback for incomplete opcodes at the end.
335local function incomplete(ctx)
336 ctx.pos = ctx.stop+1
337 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
338 return putop(ctx, "(incomplete)")
339end
340
341-- Fallback for unknown opcodes.
342local function unknown(ctx)
343 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
344 return putop(ctx, "(unknown)")
345end
346
347-- Return an immediate of the specified size.
348local function getimm(ctx, pos, n)
349 if pos+n-1 > ctx.stop then return incomplete(ctx) end
350 local code = ctx.code
351 if n == 1 then
352 local b1 = byte(code, pos, pos)
353 return b1
354 elseif n == 2 then
355 local b1, b2 = byte(code, pos, pos+1)
356 return b1+b2*256
357 else
358 local b1, b2, b3, b4 = byte(code, pos, pos+3)
359 local imm = b1+b2*256+b3*65536+b4*16777216
360 ctx.imm = imm
361 return imm
362 end
363end
364
365-- Process pattern string and generate the operands.
366local function putpat(ctx, name, pat)
367 local operands, regs, sz, mode, sp, rm, sc, rx, disp, sdisp
368 local code, pos, stop = ctx.code, ctx.pos, ctx.stop
369
370 -- Chars used: 1DFGMPQRVWXacdfgijmoprsuwxyz
371 for p in gmatch(pat, ".") do
372 local x = nil
373 if p == "V" then
374 sz = ctx.o16 and "W" or "D"; ctx.o16 = false
375 regs = map_regs[sz]
376 elseif match(p, "[BWDQFGMX]") then
377 sz = p
378 regs = map_regs[sz]
379 elseif p == "P" then
380 sz = ctx.o16 and "X" or "M"; ctx.o16 = false
381 regs = map_regs[sz]
382 elseif p == "s" then
383 local imm = getimm(ctx, pos, 1); if not imm then return end
384 x = imm <= 127 and format("byte +0x%02x", imm)
385 or format("byte -0x%02x", 256-imm)
386 pos = pos+1
387 elseif p == "u" then
388 local imm = getimm(ctx, pos, 1); if not imm then return end
389 x = format("0x%02x", imm)
390 pos = pos+1
391 elseif p == "w" then
392 local imm = getimm(ctx, pos, 2); if not imm then return end
393 x = format("0x%x", imm)
394 pos = pos+2
395 elseif p == "o" then -- [offset]
396 local imm = getimm(ctx, pos, 4); if not imm then return end
397 x = format("[0x%08x]", imm)
398 pos = pos+4
399 elseif p == "i" then
400 local n = map_sz2n[sz]
401 local imm = getimm(ctx, pos, n); if not imm then return end
402 x = format(imm > 65535 and "0x%08x" or "0x%x", imm)
403 pos = pos+n
404 elseif p == "j" then
405 local n = map_sz2n[sz]
406 local imm = getimm(ctx, pos, n); if not imm then return end
407 if sz == "B" and imm > 127 then imm = imm-256
408 elseif imm > 2147483647 then imm = imm-4294967296 end
409 pos = pos+n
410 imm = imm + pos + ctx.addr
411 ctx.imm = imm
412 x = sz == "W" and format("word 0x%04x", imm%65536)
413 or format("0x%08x", imm)
414 elseif p == "R" then x = regs[byte(code, pos-1, pos-1)%8+1]
415 elseif p == "a" then x = regs[1]
416 elseif p == "c" then x = "cl"
417 elseif p == "d" then x = "dx"
418 elseif p == "1" then x = "1"
419 else
420 if not mode then
421 mode = ctx.mrm
422 if not mode then
423 if pos > stop then return incomplete(ctx) end
424 mode = byte(code, pos, pos)
425 pos = pos+1
426 end
427 rm = mode%8; mode = (mode-rm)/8
428 sp = mode%8; mode = (mode-sp)/8
429 sdisp = ""
430 if mode < 3 then
431 if rm == 4 then
432 if pos > stop then return incomplete(ctx) end
433 sc = byte(code, pos, pos)
434 pos = pos+1
435 rm = sc%8; sc = (sc-rm)/8
436 rx = sc%8; sc = (sc-rx)/8
437 if rx == 4 then rx = nil end
438 end
439 if mode > 0 or rm == 5 then
440 local dsz = mode
441 if dsz ~= 1 then dsz = 4 end
442 disp = getimm(ctx, pos, dsz); if not disp then return end
443 sdisp = (dsz == 4 or disp <= 127) and
444 format(disp > 65535 and "+0x%08x" or "+0x%x", disp) or
445 format("-0x%x", 256-disp)
446 pos = pos+dsz
447 end
448 end
449 end
450 if p == "m" then
451 if mode == 3 then x = regs[rm+1]
452 else
453 local srm, srx = map_aregs[rm+1], ""
454 if rx then
455 srm = srm.."+"
456 srx = map_aregs[rx+1]
457 if sc > 0 then srx = srx.."*"..(2^sc) end
458 end
459 if mode == 0 and rm == 5 then
460 srm = ""
461 sdisp = format("%s0x%08x", rx and "+" or "", disp)
462 end
463 x = format("[%s%s%s]", srm, srx, sdisp)
464 end
465 if mode < 3 and
466 (not match(pat, "[aRrgp]") or
467 name == "movzx" or name == "movsx") then -- Yuck.
468 x = map_sz2prefix[sz].." "..x
469 end
470 elseif p == "r" then x = regs[sp+1]
471 elseif p == "g" then x = map_segregs[sp+1]
472 elseif p == "p" then -- Suppress prefix.
473 elseif p == "f" then x = "st"..rm
474 elseif p == "x" then x = "CR"..sp
475 elseif p == "y" then x = "DR"..sp
476 elseif p == "z" then x = "TR"..sp
477 else
478 error("bad pattern `"..pat.."'")
479 end
480 end
481 if x then operands = operands and operands..","..x or x end
482 end
483 ctx.pos = pos
484 return putop(ctx, name, operands)
485end
486
487-- Forward declaration.
488local map_act
489
490-- Get a pattern from an opcode map and dispatch to handler.
491local function opcdispatch(ctx, opcmap)
492 local pos = ctx.pos
493 local opat = opcmap[byte(ctx.code, pos, pos)]
494 if not opat then return unknown(ctx) end
495 if match(opat, "%|") then -- MMX/SSE variants depending on prefix.
496 local p
497 if ctx.rep then p = ctx.rep=="rep" and "%|([^%|]*)" or "%|.-%|.-%|([^%|]*)"
498 elseif ctx.o16 then p = "%|.-%|([^%|]*)"
499 else p = "^[^%|]*" end
500 opat = match(opat, p)
501 if not opat or opat == "" then return unknown(ctx) end
502 ctx.rep = false; ctx.o16 = false
503 end
504 local name, pat, act = match(opat, "^([a-z0-9 ]*)((.?).*)")
505 ctx.pos = pos + 1
506 return map_act[act](ctx, name, pat)
507end
508
509-- Map for action codes. The key is the first char after the name.
510map_act = {
511 -- Simple opcodes without operands.
512 [""] = function(ctx, name, pat)
513 return putop(ctx, name)
514 end,
515
516 -- Operand size chars fall right through.
517 B = putpat, W = putpat, D = putpat, V = putpat,
518 F = putpat, G = putpat,
519 M = putpat, X = putpat, P = putpat,
520
521 -- Collect prefixes.
522 [":"] = function(ctx, name, pat)
523 ctx[pat == ":" and name or sub(pat, 2)] = name
524 end,
525
526 -- Select alternate opcode name when prefixed with o16.
527 ["/"] = function(ctx, name, pat)
528 local wname, rpat = match(pat, "^/([a-z0-9 ]+)(.*)")
529 if ctx.o16 then name = wname; ctx.o16 = false end
530 return putpat(ctx, name, rpat)
531 end,
532
533 -- Chain to special handler specified by name.
534 ["*"] = function(ctx, name, pat)
535 return map_act[name](ctx, name, sub(pat, 2))
536 end,
537
538 -- Use named subtable for opcode group.
539 ["!"] = function(ctx, name, pat)
540
541 local pos = ctx.pos
542 if pos > ctx.stop then return incomplete(ctx) end
543 local mrm = byte(ctx.code, pos, pos)
544 ctx.pos = pos+1
545 ctx.mrm = mrm
546
547 local opat = map_opcgroup[name][((mrm-(mrm%8))/8)%8+1]
548 if not opat then return unknown(ctx) end
549 local name, pat2 = match(opat, "^([a-z0-9 ]*)(.*)")
550 return putpat(ctx, name, pat2 ~= "" and pat2 or sub(pat, 2))
551 end,
552
553 -- Two-byte opcode dispatch.
554 opc2 = function(ctx, name, pat)
555 return opcdispatch(ctx, map_opc2)
556 end,
557
558 -- SSSE3 dispatch.
559 ssse3 = function(ctx, name, pat)
560 return opcdispatch(ctx, map_ssse3[pat])
561 end,
562
563 -- Floating point opcode dispatch.
564 fp = function(ctx, name, pat)
565
566 local pos = ctx.pos
567 if pos > ctx.stop then return incomplete(ctx) end
568 local mrm = byte(ctx.code, pos, pos)
569 ctx.pos = pos+1
570 ctx.mrm = mrm
571
572 local rm = mrm%8
573 local idx = pat*8 + ((mrm-rm)/8)%8
574 if mrm >= 192 then idx = idx + 64 end
575 local opat = map_opcfp[idx]
576 if type(opat) == "table" then opat = opat[rm+1] end
577 if not opat then return unknown(ctx) end
578 local name, pat2 = match(opat, "^([a-z0-9 ]*)(.*)")
579 return putpat(ctx, name, pat2)
580 end,
581}
582
583------------------------------------------------------------------------------
584
585-- Disassemble a block of code.
586local function disass_block(ctx, ofs, len)
587 if not ofs then ofs = 0 end
588 local stop = len and ofs+len or #ctx.code
589 ofs = ofs + 1
590 ctx.start = ofs
591 ctx.pos = ofs
592 ctx.stop = stop
593 ctx.imm = nil
594 ctx.mrm = false
595 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
596 while ctx.pos <= stop do opcdispatch(ctx, map_opc1) end
597 if ctx.pos ~= ctx.start then incomplete(ctx) end
598end
599
600-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
601local function create_(code, addr, out)
602 local ctx = {}
603 ctx.code = code
604 ctx.addr = (addr or 0) - 1
605 ctx.out = out or io.write
606 ctx.symtab = {}
607 ctx.disass = disass_block
608 return ctx
609end
610
611-- Simple API: disassemble code (a string) at address and output via out.
612local function disass_(code, addr, out)
613 create_(code, addr, out):disass()
614end
615
616
617-- Public module functions.
618module(...)
619
620create = create_
621disass = disass_
622
diff --git a/libraries/LuaJIT-1.1.7/jit/dump.lua b/libraries/LuaJIT-1.1.7/jit/dump.lua
new file mode 100644
index 0000000..2287c23
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/dump.lua
@@ -0,0 +1,265 @@
1----------------------------------------------------------------------------
2-- LuaJIT machine code dumper module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- Activate this module to dump the machine code for all functions
8-- immediately after they have been compiled. The disassembler
9-- output is mixed with the bytecode listing.
10--
11-- Try: luajit -j dump -e 'print "foo"'
12-- luajit -j dump=foo.dump foo.lua
13-- luajit -j off -j dump -e 'jit.compile(assert(loadfile"foo.lua")))'
14--
15-- Default output is to stderr. To redirect output to a file,
16-- pass a filename as an argument or set the environment variable
17-- "LUAJIT_DUMPFILE".
18-- Note: The file is overwritten each time you run luajit.
19--
20-- TODO: Find a way to be more selective on what to dump.
21------------------------------------------------------------------------------
22
23-- Priority for compiler pipeline. Must run after backend (negative)
24-- and should be even because we only catch successful compiles.
25local PRIORITY = -98
26
27-- Cache some library functions and objects.
28local jit = require("jit")
29assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
30local jutil = require("jit.util")
31local type, format, gsub = type, string.format, string.gsub
32local bytecode, const = jutil.bytecode, jutil.const
33local getinfo = debug.getinfo
34local stdout, stderr = io.stdout, io.stderr
35
36-- Load the right disassembler.
37local dis = require("jit.dis_"..jit.arch)
38local discreate, disass_ = dis.create, dis.disass
39
40-- Turn compilation off for the whole module. LuaJIT would do that anyway.
41jit.off(true, true)
42
43-- Separator line.
44local sepline = "-------------------------------"
45
46-- Map JSUB indices to names.
47-- CHECK: must match the order in ljit_x86.h. Regenerate with:
48-- grep '^ *JSUB_[^_].*,' ljit_x86.h | sed -e 's/^ *JSUB_/ "/' -e 's/,.*/",/'
49local jsubnames = {
50 "STACKPTR",
51 "GATE_LJ",
52 "GATE_JL",
53 "GATE_JC",
54 "GROW_STACK",
55 "GROW_CI",
56 "GATE_JC_PATCH",
57 "GATE_JC_DEBUG",
58 "DEOPTIMIZE_CALLER",
59 "DEOPTIMIZE",
60 "DEOPTIMIZE_OPEN",
61 "HOOKINS",
62 "GCSTEP",
63 "STRING_SUB3",
64 "STRING_SUB2",
65 "HOOKCALL",
66 "HOOKRET",
67 "METACALL",
68 "METATAILCALL",
69 "BARRIERF",
70 "GETGLOBAL",
71 "GETTABLE_KSTR",
72 "GETTABLE_STR",
73 "BARRIERBACK",
74 "SETGLOBAL",
75 "SETTABLE_KSTR",
76 "SETTABLE_STR",
77 "GETTABLE_KNUM",
78 "GETTABLE_NUM",
79 "SETTABLE_KNUM",
80 "SETTABLE_NUM",
81 "LOG2_TWORD",
82 "CONCAT_STR2",
83}
84
85-- Generate map from JSUB addresses to JSUB names.
86local jsubmap = {}
87do
88 local jsubmcode = jutil.jsubmcode
89 for pc=0,100000 do
90 local addr = jsubmcode(pc)
91 if not addr then break end
92 jsubmap[addr] = jsubnames[pc+1] or "JSUB#"..pc
93 end
94end
95
96-- Pretty-print a constant.
97local function conststr(func, idx)
98 local k = const(func, idx)
99 if k == nil then return "nil"
100 elseif k == true then return "true"
101 elseif k == false then return "false"
102 elseif type(k) == "string" then
103 if #k > 10 then return format('"%.10s"~', k)
104 else return '"'..k..'"' end
105 else return k.."" end
106end
107
108-- Pretty-print a bytecode instruction (one or two lines).
109local function bytecodeout(out, func, pc)
110 local op, a, b, c = bytecode(func, pc)
111 if not op then
112 return true
113 elseif op == "JMP" then
114 out:write(format("\n--%04d-- JMP => %04d", pc, pc+1+b))
115 elseif op == "FORLOOP" or op == "FORPREP" then
116 out:write(format("\n--%04d-- %-9s %3d => %04d", pc, op, a, pc+1+b))
117 else
118 out:write(format("\n--%04d-- %-9s %3d %4s %4s",
119 pc, op, a, b or "", c or ""))
120 if b and b < 0 then out:write(" ; ", conststr(func, b)) end
121 if c and c < 0 then out:write(" ; ", conststr(func, c)) end
122 end
123end
124
125-- Dump machine code and mix it with the bytecode listing.
126local function dumpfunc(func, out, deopt)
127 if not out then out = stderr end
128 local info = getinfo(func, "S")
129
130 -- Don't bother checking for the right blocks to dump.
131 -- Dump the main block (if not deopt) and always all deopt blocks.
132 for block=deopt and 2 or 1,1000000 do
133 local addr, code, mfmiter = jutil.mcode(func, block)
134 if not addr then
135 if code then return code end -- Not compiled: return status.
136 break -- No more blocks to dump.
137 end
138
139 -- Print header.
140 out:write(sepline, " ", info.source, ":", info.linedefined)
141 if block ~= 1 then out:write(" DEOPT block ", block) end
142
143 -- Create disassembler context.
144 local ctx = discreate(code, addr, function(s) out:write(s) end)
145 ctx.symtab = jsubmap
146
147 -- Dump an mcode block.
148 local pc, ofs = 1, 0
149 local len, isdeopt = mfmiter()
150 if isdeopt then pc = len; len = 0
151 elseif block ~= 1 then break end -- Stop before next main block.
152 for t, m in mfmiter do
153 if t == "COMBINE" then
154 bytecodeout(out, func, pc)
155 else
156 if len ~= 0 then
157 out:write("\n")
158 if len > 0 then
159 ctx:disass(ofs, len)
160 ofs = ofs + len
161 else
162 out:write(format("%08x ** deoptimized\n", addr+ofs))
163 ofs = ofs - len
164 end
165 len = 0
166 end
167 if type(t) == "number" then
168 if m then
169 if isdeopt then
170 pc = t - 1
171 else
172 bytecodeout(out, func, pc)
173 len = -t
174 end
175 else
176 len = t
177 if bytecodeout(out, func, pc) then break end
178 end
179 end
180 end
181 pc = pc + 1
182 end
183 if len and len ~= 0 then
184 out:write(sepline, " tail code\n")
185 ctx:disass(ofs, len)
186 end
187 end
188
189 -- Print footer.
190 out:write(sepline, "\n")
191 out:flush()
192end
193
194-- Dump the internal JIT subroutines.
195local function dumpjsub_(out)
196 if not out then out = stderr end
197 local addr, code = jutil.jsubmcode()
198
199 -- Create disassembler context.
200 local ctx = discreate(code, addr, function(s) out:write(s) end)
201 ctx.symtab = jsubmap
202
203 -- Collect addresses and sort them.
204 local t = {}
205 for addr in pairs(jsubmap) do t[#t+1] = addr end
206 t[#t+1] = addr + #code
207 table.sort(t)
208
209 -- Go through the addresses in ascending order.
210 local ofs = addr
211 for i=2,#t do
212 local next = t[i]
213 out:write("\n->", jsubmap[ofs], ":\n") -- Output label for JSUB.
214 ctx:disass(ofs-addr, next-ofs) -- Disassemble corresponding code block.
215 ofs = next
216 end
217 out:flush()
218end
219
220
221-- Active flag and output file handle.
222local active, out
223
224-- Dump handler for compiler pipeline.
225local function h_dump(st)
226 local ok, err = pcall(dumpfunc, st.func, out, st.deopt)
227 if not ok then
228 stderr:write("\nERROR: jit.dump disabled: ", err, "\n")
229 jit.attach(h_dump) -- Better turn ourselves off after a failure.
230 if out and out ~= stdout then out:close() end
231 out = nil
232 active = nil
233 end
234end
235
236-- Detach dump handler from compiler pipeline.
237local function dumpoff()
238 if active then
239 active = false
240 jit.attach(h_dump)
241 if out and out ~= stdout then out:close() end
242 out = nil
243 end
244end
245
246-- Open the output file and attach dump handler to compiler pipeline.
247local function dumpon(filename)
248 if active then dumpoff() end
249 local outfile = filename or os.getenv("LUAJIT_DUMPFILE")
250 out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
251 jit.attach(h_dump, PRIORITY)
252 active = true
253end
254
255
256-- Public module functions.
257module(...)
258
259disass = disass_
260dump = dumpfunc
261dumpjsub = dumpjsub_
262on = dumpon
263off = dumpoff
264start = dumpon -- For -j command line option.
265
diff --git a/libraries/LuaJIT-1.1.7/jit/dumphints.lua b/libraries/LuaJIT-1.1.7/jit/dumphints.lua
new file mode 100644
index 0000000..4a64676
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/dumphints.lua
@@ -0,0 +1,239 @@
1----------------------------------------------------------------------------
2-- LuaJIT hints dumper module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- Activate this module to dump the bytecode and the hints from
8-- the optimizer for all functions to be compiled.
9--
10-- Try: luajit -O -j dumphints -e 'return 1'
11--
12-- Default output is to stderr. To redirect output to a file,
13-- pass a filename as an argument or set the environment variable
14-- "LUAJIT_DUMPHINTSFILE".
15-- Note: The file is overwritten each time you run luajit.
16--
17-- TODO: Find a way to be more selective on what to dump.
18------------------------------------------------------------------------------
19
20-- Priority for compiler pipeline. Should run before backend (positive)
21-- and should be even because we only catch successful compiles.
22local PRIORITY = 10
23
24-- Cache some library functions and objects.
25local jit = require("jit")
26assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
27local jutil = require("jit.util")
28local type, pairs, format = type, pairs, string.format
29local bytecode, const = jutil.bytecode, jutil.const
30local hints, fhints = jutil.hints, jutil.fhints
31local stdout, stderr = io.stdout, io.stderr
32
33-- Turn compilation off for the whole module. LuaJIT would do that anyway.
34jit.off(true, true)
35
36-- Separator line.
37local sepline = "-------------------------------"
38
39
40-- Pretty-print a constant.
41local function conststr(func, idx)
42 local k = const(func, idx)
43 if k == nil then return "nil"
44 elseif k == true then return "true"
45 elseif k == false then return "false"
46 elseif type(k) == "string" then
47 if #k > 10 then return format('"%.10s"~', k)
48 else return '"'..k..'"' end
49 else return k.."" end
50end
51
52-- Pretty-print a bytecode instruction.
53local function bytecodeline(func, pc, flag)
54 local op, a, b, c = bytecode(func, pc)
55 if not op then return end
56 if op == "JMP" then
57 return format("\n%04d %s JMP => %04d", pc, flag, pc+1+b)
58 end
59 if op == "FORLOOP" or op == "FORPREP" then
60 return format("\n%04d %s %-9s %3d => %04d", pc, flag, op, a, pc+1+b)
61 end
62 local s = format("\n%04d %s %-9s %3d %4s %4s",
63 pc, flag, op, a, b or "", c or "")
64 if b and b < 0 then s = s.." ; "..conststr(func, b) end
65 if c and c < 0 then s = s.." ; "..conststr(func, c) end
66 return s
67end
68
69-- Precompute inverse hints table.
70local invhints = {}
71for k,v in pairs(hints) do invhints[v] = k end
72
73-- The inverse resolver for inline functions is loaded on demand.
74local getname
75
76-- Helper functions to pretty-print hints.
77local function typehint(h, v, st, pc)
78 if st[pc+hints.INLINE] then return "" end
79 local tp = type(v)
80 if tp == "function" then
81 tp = debug.getinfo(v, "S").what
82 elseif tp == "number" and v % 1 == 0 then
83 tp = "integer"
84 elseif v == false then
85 tp = "mixed"
86 end
87 return " #"..h.."("..tp..")"
88end
89
90local hintprint = {
91 COMBINE = function(h, v, st, pc)
92 if v == false then return "" end -- Dead instructions are already marked.
93 end,
94 TYPE = typehint,
95 TYPEKEY = typehint,
96 INLINE = function(h, v, st, pc)
97 if not getname then getname = require("jit.opt_inline").getname end
98 return " #INLINE("..getname(st[pc+hints.TYPE], v)..")"
99 end,
100}
101
102-- Generate range string from table: pc[-pc] [,...]
103local function rangestring(t)
104 local s = ""
105 for i,range in ipairs(t) do
106 if i ~= 1 then s = s.."," end
107 local pc = range % 65536
108 range = (range - pc) / 65536
109 s = s..pc
110 if range ~= 0 then s = s..(-(pc+range)) end
111 end
112 return s
113end
114
115-- Dump instructions and hints for a (to be compiled) function.
116local function dumphints(st, out)
117 if not out then out = stderr end
118 local func = st.func
119 local COMBINE = hints.COMBINE
120
121 -- Need to recompute branch targets (not part of hints).
122 local target = {}
123 for pc=1,1e6 do
124 local op, a, b, c = bytecode(func, pc)
125 if not op then break end
126 if op == "JMP" or op == "FORLOOP" then
127 local t = pc+1+b
128 if st[pc+COMBINE] ~= false then target[t] = true end
129 elseif op == "LOADBOOL" and c ~= 0 then
130 target[pc+2] = true
131 end
132 end
133
134 -- Map hints to bytecode instructions.
135 local hintstr = {}
136 for k,v in pairs(st) do
137 -- CHECK: must match hint shift in ljit_hints.h:JIT_H2NUM().
138 if type(k) == "number" and k >= 65536 then
139 local pc = k % 65536
140 if pc > 0 then
141 k = k - pc
142 local h = invhints[k] or (k/65536)
143 local hp = hintprint[h]
144 local s = hp and hp(h, v, st, pc) or (" #"..h)
145 local hs = hintstr[pc]
146 hintstr[pc] = hs and (hs..s) or s
147 end
148 end
149 end
150
151 -- Write header.
152 local info = debug.getinfo(func, "S")
153 out:write(sepline, " ", info.source, ":", info.linedefined)
154
155 -- Write function hints.
156 for k,v in pairs(fhints) do
157 if st[v] then out:write("\n#", k) end
158 end
159
160 -- Write instruction hints and bytecode.
161 local function dumprange(firstpc, lastpc)
162 for pc=firstpc,lastpc do
163 local prefix = " "
164 if st[pc+COMBINE] == false then prefix = "**"
165 elseif target[pc] then prefix = "=>" end
166 local line = bytecodeline(func, pc, prefix)
167 if not line then break end
168 local h = hintstr[pc]
169 if h then
170 out:write(format("%-40s %s", line, h))
171 else
172 out:write(line)
173 end
174 end
175 end
176
177 -- Handle deoptimization range table.
178 local t = st.deopt
179 if t then
180 out:write(" DEOPT=", rangestring(t))
181 for i,range in ipairs(t) do
182 if i ~= 1 then out:write("\n----") end
183 local pc = range % 65536
184 range = (range - pc) / 65536
185 dumprange(pc, pc+range)
186 end
187 else
188 dumprange(1, 1000000)
189 end
190
191 -- Write footer.
192 out:write("\n", sepline, "\n")
193 out:flush()
194end
195
196
197-- Active flag and output file handle.
198local active, out
199
200-- Dump hints handler for compiler pipeline.
201local function h_dumphints(st)
202 local ok, err = pcall(dumphints, st, out)
203 if not ok then
204 stderr:write("\nERROR: jit.dumphints disabled: ", err, "\n")
205 jit.attach(h_dumphints) -- Better turn ourselves off after a failure.
206 if out and out ~= stdout then out:close() end
207 out = nil
208 active = nil
209 end
210end
211
212-- Detach dump handler from compiler pipeline.
213local function dumphintsoff()
214 if active then
215 active = false
216 jit.attach(h_dumphints)
217 if out and out ~= stdout then out:close() end
218 out = nil
219 end
220end
221
222-- Open the output file and attach dump handler to compiler pipeline.
223local function dumphintson(filename)
224 if active then dumphintsoff() end
225 local outfile = filename or os.getenv("LUAJIT_DUMPHINTSFILE")
226 out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
227 jit.attach(h_dumphints, PRIORITY)
228 active = true
229end
230
231
232-- Public module functions.
233module(...)
234
235dump = dumphints
236on = dumphintson
237off = dumphintsoff
238start = dumphintson -- For -j command line option.
239
diff --git a/libraries/LuaJIT-1.1.7/jit/opt.lua b/libraries/LuaJIT-1.1.7/jit/opt.lua
new file mode 100644
index 0000000..5fe0f34
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/opt.lua
@@ -0,0 +1,508 @@
1----------------------------------------------------------------------------
2-- LuaJIT optimizer.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- This module contains a simple optimizer that generates some hints for
8-- the compiler backend.
9--
10-- Compare: luajit -j dump -e 'return 1'
11-- with: luajit -O -j dumphints -j dump -e 'return 1'
12--
13-- This module uses a very simplistic (but fast) abstract interpretation
14-- algorithm. It mostly ignores control flow and/or basic block boundaries.
15-- Thus the results of the analysis are really only predictions (e.g. about
16-- monomorphic use of operators). The backend _must_ check all contracts
17-- (e.g. verify the object type) and use a (polymorphic) fallback or
18-- deoptimization in case a contract is broken.
19--
20-- Although simplistic, the generated hints are pretty accurate. Note that
21-- some hints are really definitive and don't need to be checked (like
22-- COMBINE or FOR_STEP_K).
23--
24-- TODO: Try MFP with an extended lattice. But it's unclear whether the
25-- added complexity really pays off with the current backend.
26------------------------------------------------------------------------------
27
28-- Priority for compiler pipeline. Right in the middle before the backend.
29local PRIORITY = 50
30
31-- Default optimizer level, i.e. what you get with -O.
32-- Caveat: this may change in the future when more optimizations are added.
33local OPTLEVEL = 2
34
35-- Heuristic limits for what the compiler should reasonably handle.
36-- Functions outside these limits are unlikely to be run more than once.
37-- Maybe a bit on the generous side. Check ljit.h for backend limits, too.
38-- TODO: make it depend on the bytecode distribution, too.
39local LIMITS = {
40 bytecodes = 4000,
41 stackslots = 150,
42 params = 20,
43 consts = 200,
44 subs = 30,
45}
46
47-- Cache some library functions and objects.
48local jit = require("jit")
49assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
50local jutil = require("jit.util")
51local type, rawget, next, pcall = type, rawget, next, pcall
52local bytecode, const = jutil.bytecode, jutil.const
53local hints, fhints = jutil.hints, jutil.fhints
54local getmetatable = getmetatable
55
56-- Turn compilation off for the whole module. LuaJIT would do that anyway.
57jit.off(true, true)
58
59-- Default optimizer level after loading. But -O runs setlevel(), too.
60local optlevel = -1
61
62
63-- Use iterative path marking to mark live instructions and branch targets.
64local function marklive(func)
65 local live, work, workn, pc = {}, {}, 0, 1
66 repeat
67 repeat
68 local op, a, b, c, test = bytecode(func, pc)
69 live[pc] = true
70 pc = pc + 1
71 if op == "JMP" then
72 pc = pc + b
73 live[-pc] = true
74 elseif op == "FORLOOP" then
75 local mpc = -pc
76 live[mpc - b] = true
77 live[mpc] = true
78 elseif op == "RETURN" then
79 break
80 elseif test then
81 local fpc = pc + 1
82 -- No need for fallthrough target mark live[-fpc] in our analysis.
83 if not live[fpc] then -- Add fallthrough path to work list.
84 workn = workn + 1
85 work[workn] = fpc
86 end
87 elseif op == "CLOSURE" then
88 pc = pc + jutil.closurenup(func, b) -- Do not mark pseudo-ins live.
89 elseif op == "LOADBOOL" and c ~= 0 then
90 pc = pc + 1
91 live[-pc] = true
92 elseif op == "SETLIST" and c == 0 then
93 pc = pc + 1 -- Do not mark pseudo-ins live.
94 end
95 until live[pc]
96 if workn == 0 then return live end -- Return if work list is empty.
97 pc = work[workn] -- Else fetch next path to mark from work list.
98 workn = workn - 1
99 until false
100end
101
102
103-- Empty objects.
104local function empty() end
105
106-- Dummy function to set call hints. Replaced when jit.opt_inline is loaded.
107local function callhint(st, slot, pc, base, narg, nres)
108 st[pc+hints.TYPE] = slot[base]
109 for i=base,base+nres-1 do slot[i] = nil end
110end
111
112-- Set TYPE hint, but only for numbers, strings or tables.
113local function typehint(st, pc, o)
114 local tp = type(o)
115 if tp == "number" or tp == "string" or tp == "table" then
116 st[pc+hints.TYPE] = o
117 end
118end
119
120-- Set TYPE and TYPEKEY hints for table operations.
121local function tablehint(st, slot, pc, t, kslot)
122 local tp = type(t)
123 if tp == "table" or tp == "userdata" then st[pc+hints.TYPE] = t end
124 if kslot >= 0 then -- Don't need this hint for constants.
125 local key = slot[kslot]
126 local tp = type(key)
127 if tp == "number" or tp == "string" then st[pc+hints.TYPEKEY] = key end
128 end
129end
130
131-- Try to lookup a value. Guess the value or at least the value type.
132local function trylookup(st, t, k)
133 if k == nil then return nil end
134 if type(t) == "table" then
135 local v = rawget(t, k)
136 if v ~= nil then return v end
137 end
138 local mt = getmetatable(t)
139 if type(mt) == "table" then
140 -- One __index level is enough for our purposes.
141 local it = rawget(mt, "__index")
142 if type(it) == "table" then
143 local v = rawget(it, k)
144 if v ~= nil then return v end
145 end
146 end
147 local v = st.tableval[t] -- Resort to a generic guess.
148 if v == nil and type(t) == "table" then v = next(t) end -- Getting desperate.
149 return v
150end
151
152-- Check whether the previous instruction sets a const.
153local function prevconst(st, slot, pc, reg)
154 if st.live[-pc] == nil then -- Current instruction must not be a target.
155 local op, ka, kb = bytecode(st.func, pc-1)
156 if ka == reg and (op == "LOADK" or op == "LOADBOOL" or
157 (op == "LOADNIL" and kb == reg)) then
158 return true, slot[reg]
159 end
160 end
161end
162
163-- Common handler for arithmetic and comparison opcodes.
164local function arithop(st, slot, pc, a, b, c, op)
165 local sb, sc = slot[b], slot[c]
166 if sb == nil then sb = sc elseif sc == nil then sc = sb end
167 local tb, tc = type(sb), type(sc)
168 if tb == tc then
169 if tb == "number" then -- Improve the guess for numbers.
170 if op == "DIV" or sb % 1 ~= 0 or sc % 1 ~= 0 then
171 sb = 0.5 -- Probably a non-integral number.
172 else
173 sb = 1 -- Optimistic guess.
174 end
175 end
176 if sb ~= nil then st[pc+hints.TYPE] = sb end
177 else
178 st[pc+hints.TYPE] = false -- Marker for mixed types.
179 end
180 if op ~= "LT" and op ~= "LE" then
181 slot[a] = sb -- Assume coercion to 1st type if different.
182 end
183end
184
185-- Common handler for TEST and TESTSET.
186local function testop(st, slot, pc, a, b, c)
187 -- Optimize the 'expr and k1 or k2' idiom.
188 local ok, k = prevconst(st, slot, pc, b)
189 if k and a == b then
190 st[pc+hints.COMBINE] = false -- Kill the TEST/TESTSET.
191 if c == 0 then st.live[pc+1] = nil end -- Kill the JMP.
192 end
193 slot[a] = slot[b]
194end
195
196-- Dispatch table for opcode handlers.
197local handler = {
198 MOVE = function(st, slot, pc, a, b, c)
199 slot[a] = slot[b]
200 end,
201
202 LOADK = function(st, slot, pc, a, b, c)
203 slot[a] = const(st.func, b)
204 end,
205
206 LOADBOOL = function(st, slot, pc, a, b, c)
207 slot[a] = (b == 1)
208 end,
209
210 LOADNIL = function(st, slot, pc, a, b, c)
211 for i=a,b do slot[i] = nil end
212 end,
213
214 GETUPVAL = function(st, slot, pc, a, b, c)
215 slot[a] = jutil.upvalue(st.func, b)
216 end,
217
218 GETGLOBAL = function(st, slot, pc, a, b, c)
219 slot[a] = trylookup(st, st.stats.env, const(st.func, b))
220 end,
221
222 GETTABLE = function(st, slot, pc, a, b, c)
223 local t = slot[b]
224 tablehint(st, slot, pc, t, c)
225 slot[a] = trylookup(st, t, slot[c])
226 end,
227
228 SETGLOBAL = empty,
229
230 SETUPVAL = empty, -- TODO: shortcut -- but this is rare?
231
232 SETTABLE = function(st, slot, pc, a, b, c)
233 local t = slot[a]
234 tablehint(st, slot, pc, t, b)
235 if type(t) == "table" or type(t) == "userdata" then -- Must validate setkey.
236 local val = slot[c]
237 if val ~= nil then st.tableval[t] = val end
238 end
239 end,
240
241 NEWTABLE = function(st, slot, pc, a, b, c)
242 slot[a] = {} -- Need unique tables for indexing st.tableval.
243 end,
244
245 SELF = function(st, slot, pc, a, b, c)
246 local t = slot[b]
247 tablehint(st, slot, pc, t, c)
248 slot[a+1] = t
249 slot[a] = trylookup(st, t, slot[c])
250 end,
251
252 ADD = arithop, SUB = arithop, MUL = arithop, DIV = arithop,
253 MOD = arithop, POW = arithop, LT = arithop, LE = arithop,
254
255 UNM = function(st, slot, pc, a, b, c)
256 return arithop(st, slot, pc, a, b, b, "UNM")
257 end,
258
259 NOT = function(st, slot, pc, a, b, c)
260 slot[a] = true
261 end,
262
263 LEN = function(st, slot, pc, a, b, c)
264 typehint(st, pc, slot[b])
265 slot[a] = 1
266 end,
267
268 CONCAT = function(st, slot, pc, a, b, c)
269 local mixed
270 local sb = slot[b]
271 for i=b+1,c do
272 local si = slot[i]
273 if sb == nil then
274 sb = si
275 elseif si ~= nil and type(sb) ~= type(si) then
276 mixed = true
277 break
278 end
279 end
280 if sb == nil then
281 sb = ""
282 else
283 st[pc+hints.TYPE] = not mixed and sb or false
284 if type(sb) == "number" then sb = "" end
285 end
286 slot[a] = sb -- Assume coercion to 1st type (if different) or string.
287 end,
288
289 JMP = function(st, slot, pc, a, b, c)
290 if b >= 0 then -- Kill JMPs across dead code.
291 local tpc = pc + b
292 while not st.live[tpc] do tpc = tpc - 1 end
293 if tpc == pc then st[pc+hints.COMBINE] = false end
294 end
295 end,
296
297 EQ = function(st, slot, pc, a, b, c)
298 if b >= 0 and c >= 0 then typehint(st, pc, slot[b] or slot[c]) end
299 end,
300
301 TEST = function(st, slot, pc, a, b, c)
302 return testop(st, slot, pc, a, a, c)
303 end,
304
305 TESTSET = testop,
306
307 CALL = function(st, slot, pc, a, b, c)
308 callhint(st, slot, pc, a, b-1, c-1)
309 end,
310
311 TAILCALL = function(st, slot, pc, a, b, c)
312 callhint(st, slot, pc, a, b-1, -1)
313 end,
314
315 RETURN = function(st, slot, pc, a, b, c)
316 if b == 2 and prevconst(st, slot, pc, a) then
317 st[pc-1+hints.COMBINE] = true -- Set COMBINE hint for prev. instruction.
318 end
319 end,
320
321 FORLOOP = empty,
322
323 FORPREP = function(st, slot, pc, a, b, c)
324 local ok, step = prevconst(st, slot, pc, a+2)
325 if type(step) == "number" then
326 st[pc+hints.FOR_STEP_K] = step
327 end
328 local nstart, nstep = slot[a], slot[a+2]
329 local tnstart, tnstep = type(nstart), type(nstep)
330 local ntype = ((tnstart == "number" and nstart % 1 ~= 0) or
331 (tnstep == "number" and nstep % 1 ~= 0)) and 0.5 or 1
332 slot[a+3] = ntype
333 if tnstart == "number" and tnstep == "number" and
334 type(slot[a+1]) == "number" then
335 st[pc+hints.TYPE] = ntype
336 end
337 end,
338
339 -- TFORLOOP is at the end of the loop. Setting slots would be pointless.
340 -- Inlining is handled by the corresponding iterator constructor (CALL).
341 TFORLOOP = function(st, slot, pc, a, b, c)
342 st[pc+hints.TYPE] = slot[a]
343 end,
344
345 SETLIST = function(st, slot, pc, a, b, c)
346 -- TODO: if only (numeric) const: shortcut (+ nobarrier).
347 local t = slot[a]
348 -- Very imprecise. But better than nothing.
349 if type(t) == "table" then st.tableval[t] = slot[a+1] end
350 end,
351
352 CLOSE = empty,
353
354 CLOSURE = function(st, slot, pc, a, b, c)
355 slot[a] = empty
356 if st.noclose then
357 local nup = jutil.closurenup(st.func, b)
358 for i=pc+1,pc+nup do
359 local op = bytecode(st.func, i)
360 if op == "MOVE" then
361 st.noclose = false
362 return
363 end
364 end
365 end
366 end,
367
368 VARARG = function(st, slot, pc, a, b, c)
369 local params = st.stats.params
370 for i=1,b do slot[a+i-1] = st[params+i] end
371 end,
372}
373
374-- Generate some hints for the compiler backend.
375local function optimize(st)
376 -- Deoptimization is simple: just don't generate any hints. :-)
377 if st.deopt then return end
378
379 local func = st.func
380 local stats = jutil.stats(func)
381 if not stats then return jutil.status.COMPILER_ERROR end -- Eh?
382
383 -- Check limits.
384 if stats.bytecodes > LIMITS.bytecodes or
385 stats.stackslots > LIMITS.stackslots or
386 stats.params > LIMITS.params or
387 stats.consts > LIMITS.consts or
388 stats.subs > LIMITS.subs then
389 return jutil.status.TOOLARGE
390 end
391
392 -- Mark live instructions (live[pc]) and branch targets (live[-pc]).
393 local live = marklive(func)
394
395 -- Handlers need access to some temporary state fields.
396 st.noclose = true
397 st.stats = stats
398 st.live = live
399 st.tableval = { [stats.env] = empty } -- Guess: unknown globals are functions.
400
401 -- Initialize slots with argument hints and constants.
402 local slot = {}
403 for i=1,stats.params do slot[i-1] = st[i] end
404 for i=-1,-256,-1 do -- No need to copy non-RK-able consts.
405 local k, ok = const(func, i)
406 if not ok then break end
407 slot[i] = k
408 end
409
410 -- Step through all live instructions, update slots and add hints.
411 for pc=1,stats.bytecodes do
412 if live[pc] then
413 local op, a, b, c, test = bytecode(func, pc)
414 handler[op](st, slot, pc, a, b, c, op)
415 else
416 st[pc+hints.COMBINE] = false -- Dead instruction hint.
417 end
418 end
419
420 -- Update function hints.
421 if st.noclose then st[fhints.NOCLOSE] = true end
422
423 -- Clear temporary state fields.
424 st.noclose = nil
425 st.stats = nil
426 st.live = nil
427 st.tableval = nil
428end
429
430
431-- Active flags.
432local active, active_opt_inline
433
434-- Handler for compiler pipeline.
435local function h_opt(st)
436 if optlevel <= 0 then return end
437 local ok, err = pcall(optimize, st)
438 if not ok then
439 io.stderr:write("\nERROR: jit.opt disabled: ", err, "\n")
440 jit.attach(h_opt) -- Better turn ourselves off after a failure.
441 active = nil
442 else
443 if err then return err end
444 end
445end
446
447-- Load add-on module.
448local function loadaddon(opt)
449 local name, val = string.match(opt, "^(.-)=(.*)$") -- Strip value.
450 if not name then name = opt end
451 name = "jit.opt_"..name
452 local ok, mod = pcall(require, name)
453 if not ok then
454 -- Return error if not installed, but propagate other errors.
455 if string.sub(mod, 1, 7) ~= "module " then error(mod, 0) end
456 return "optimizer add-on module "..name.." not found"
457 end
458 mod.start(val)
459end
460
461-- Attach optimizer and set optimizer level or load add-on module.
462local function setlevel_(opt)
463 -- Easier to always attach the optimizer (even for -O0).
464 if not active then
465 jit.attach(h_opt, PRIORITY)
466 active = true
467 end
468
469 -- Parse -O<level> or -O<name[=value]>.
470 if opt == nil or opt == "" then
471 optlevel = OPTLEVEL
472 else
473 local level = tonumber(opt) -- Numeric level?
474 if level then
475 if level < 0 or level % 1 ~= 0 then
476 error("bad optimizer level", 0)
477 end
478 optlevel = level
479 else
480 if optlevel == -1 then optlevel = OPTLEVEL end
481 local err = loadaddon(opt)
482 if err then error(err, 0) end
483 end
484 end
485
486 -- Load add-on module for inlining functions for -O2 and above.
487 if not active_opt_inline and optlevel >= 2 then
488 loadaddon("inline") -- Be silent if not installed.
489 active_opt_inline = true -- Try this only once.
490 end
491end
492
493
494-- Public module functions.
495module(...)
496
497-- Callback to allow attaching a call hinter. Used by jit.opt_inline.
498function attach_callhint(f)
499 callhint = f
500end
501
502function getlevel()
503 return optlevel
504end
505
506setlevel = setlevel_
507start = setlevel_ -- For -O command line option.
508
diff --git a/libraries/LuaJIT-1.1.7/jit/opt_inline.lua b/libraries/LuaJIT-1.1.7/jit/opt_inline.lua
new file mode 100644
index 0000000..cc19bf4
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/opt_inline.lua
@@ -0,0 +1,397 @@
1----------------------------------------------------------------------------
2-- LuaJIT optimizer add-on module for function inlining.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- This is a simple framework for C function signature maps.
8-- It helps with type propagation and C function inlining.
9--
10-- This module is automatically loaded with -O2 and above.
11-- By default most standard library functions are added.
12--
13-- TODO: generalize it, e.g. for back propagation (i.e. arg types).
14-- TODO: extend it for Lua functions (but need to analyze them before use).
15------------------------------------------------------------------------------
16
17-- Cache some library functions and objects.
18local jit = require("jit")
19assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
20local jutil = require("jit.util")
21local type, rawget, next = type, rawget, next
22local hints, fhints = jutil.hints, jutil.fhints
23local sub, match, gsub = string.sub, string.match, string.gsub
24
25-- Turn compilation off for the whole module. LuaJIT would do that anyway.
26jit.off(true, true)
27
28-- Prototypical objects used for type hints.
29local TABLE = {}
30local CFUNC = collectgarbage -- Pretty sure this is never inlined.
31
32
33-- Map from C closures to signatures. Cannot use a weak table.
34-- Closures must be kept alive because inlining checks against their addrs.
35local map_sign = {}
36
37-- For jit.dumphints: get printable name for TYPE hint: "#INLINE(foo.bar)".
38local function getname_(f, idx)
39 local sign = map_sign[f]
40 if sign then
41 local libname, name = sign.libname, sign.name
42 if libname then
43 return libname.."."..name
44 else
45 return name
46 end
47 elseif idx == 0 then
48 return "recursive"
49 else
50 return "?"
51 end
52end
53
54-- Name, base table and running index for convenience functions.
55-- CHECK: the library index and the order below must match with ljit_hints.h
56local flibname, flib, fidx
57
58local function fadd(name, results, args, handler)
59 local f = rawget(flib, name)
60 if f then
61 map_sign[f] = {
62 libname = flibname, name = name, idx = fidx,
63 results = results, args = args, handler = handler,
64 }
65 end
66 if fidx then fidx = fidx + 1 end
67end
68
69local function faddf(name, f, results, args, handler)
70 map_sign[f] = {
71 libname = flibname, name = name, idx = fidx,
72 results = results, args = args, handler = handler,
73 }
74 if fidx then fidx = fidx + 1 end
75end
76
77
78-- Signature handler: copy first argument to first result.
79local function copyfirst(st, slot, pc, base, narg, nres)
80 slot[base] = slot[base+1]
81end
82
83-- Helper for iterators: check if the function is an iterator constructor.
84--
85-- 'for ivars in func(args) do body end'
86--
87-- ...load func+args...
88-- CALL func <-- pc
89-- JMP fwd ---+
90-- back: | <--+
91-- ...body... | |
92-- fwd: <--+ |
93-- TFORLOOP ivars | <-- tforpc
94-- JMP back ---+
95--
96local function itercheck(st, slot, pc, base, idx)
97 if idx then
98 local bytecode, func = jutil.bytecode, st.func
99 local op, _, fwd = bytecode(func, pc+1)
100 if op == "JMP" then
101 local tforpc = pc+2+fwd
102 local op, tfbase, _, tfnres = bytecode(func, tforpc)
103 if op == "TFORLOOP" and tfbase == base and tfnres <= 2 then
104 local op, _, back = bytecode(func, tforpc+1)
105 if op == "JMP" and fwd+back == -2 then
106 -- Must set inlining hint for TFORLOOP instruction here.
107 st[tforpc+hints.INLINE] = idx -- Serves as iterator index, too.
108 return -- Inline it.
109 end
110 end
111 end
112 end
113 slot[base] = CFUNC -- Better make it different from pairs.
114 return true -- Better not inline it, if not used in a for statement.
115end
116
117-- Helper for pairs/next: guess result types for standard table iterator.
118local function guessnext(st, slot, base, dest)
119 local t, k, v = slot[base+1]
120 if type(t) == "table" then
121 k, v = next(t)
122 if v == nil then v = st.tableval[t] end
123 end
124 slot[dest] = k or "" -- Strings are a good guess for the key type.
125 slot[dest+1] = v -- But better not guess any fixed value type.
126end
127
128
129-- Signatures for base library functions.
130-- Note: Only add functions where result type hints or inlining makes sense.
131flibname, flib, fidx = nil, _G, 65536*1
132fadd("pairs", "..0", "T",
133 function(st, slot, pc, base, narg, nres, idx)
134 -- Table in slot[base+1] is kept (2nd result = 1st arg).
135 -- Fill result slots for the iterator here (TFORLOOP is at the end).
136 guessnext(st, slot, base, base+3)
137 return itercheck(st, slot, pc, base, idx)
138 end)
139
140fadd("ipairs", "..I", "T",
141 function(st, slot, pc, base, narg, nres, idx)
142 -- Table in slot[base+1] is kept (2nd result = 1st arg).
143 -- Fill result slots for the iterator here (TFORLOOP is at the end).
144 local t = slot[base+1]
145 slot[base+3] = 1 -- Integer key.
146 local v
147 if type(t) == "table" then
148 v = rawget(t, 1)
149 if v == nil then v = st.tableval[t] end
150 end
151 slot[base+4] = v
152 return itercheck(st, slot, pc, base, idx)
153 end)
154
155fidx = nil -- Pure result type signatures follow:
156fadd("next", "..", "T.?",
157 function(st, slot, pc, base, narg, nres)
158 guessnext(st, slot, base, base)
159 end)
160fadd("type", "S", ".")
161fadd("getmetatable", "T", ".")
162fadd("setmetatable", ".", "TT?", copyfirst)
163fadd("rawequal", "B", "..")
164fadd("rawget", ".", "T.",
165 function(st, slot, pc, base, narg, nres)
166 local t = slot[base+1]
167 slot[base] = type(t) == "table" and rawget(t, slot[base+2]) or ""
168 end)
169fadd("rawset", ".", "T..", copyfirst)
170fadd("assert", "*", "..*",
171 function(st, slot, pc, base, narg, nres)
172 for i=1,nres do slot[base+i-1] = i <= narg and slot[base+i] or nil end
173 end)
174fadd("tonumber", "I", ".I?")
175fadd("tostring", "S", ".")
176fadd("require", "T", "S")
177
178-- Signatures for coroutine library functions.
179flibname, flib, fidx = "coroutine", coroutine, 65536*2
180if flib then
181 fadd("yield", "*", ".*")
182 fadd("resume", "*", "R.*",
183 function(st, slot, pc, base, narg, nres)
184 slot[base] = true
185 for i=1,nres-1 do slot[base+i] = nil end -- No guess.
186 end)
187
188 fidx = nil -- Pure result type signatures follow:
189 fadd("wrap", "C", "F")
190end
191
192-- Signatures for string library functions.
193flibname, flib, fidx = "string", string, 65536*3
194if flib then
195 fadd("len", "I", "S")
196 fadd("sub", "S", "SII?")
197 fadd("char", "S", "I*")
198
199 fidx = nil -- Pure result type signatures follow:
200 fadd("byte", "I", "S",
201 function(st, slot, pc, base, narg, nres)
202 for i=0,nres-1 do slot[base+i] = 1 end -- Set all result hints.
203 end)
204 fadd("rep", "S", "SI")
205 fadd("reverse", "S", "S")
206 fadd("upper", "S", "S")
207 fadd("lower", "S", "S")
208
209 fadd("format", "S", "S.*")
210 fadd("find", "*", "SSI?.?",
211 function(st, slot, pc, base, narg, nres)
212 slot[base] = 1
213 slot[base+1] = 1
214 for i=2,nres-1 do slot[base+i] = "" end -- Hints for matches.
215 end)
216 fadd("match", "*", "SSI?",
217 function(st, slot, pc, base, narg, nres)
218 for i=0,nres-1 do slot[base+i] = "" end -- Hints for matches.
219 end)
220 fadd("gsub", "SI", "SSGI?")
221 fadd("gmatch", "C00", "SS",
222 function(st, slot, pc, base, narg, nres)
223 -- Fill result slots for gmatch_iter here (TFORLOOP is at the end).
224 for i=base+3,st.stats.stackslots-1 do slot[i] = "" end
225 end)
226 -- The gmatch iterator itself is never inlined. No point in adding it.
227end
228
229-- Signatures for table library functions.
230flibname, flib, fidx = "table", table, 65536*4
231if flib then
232 fadd("insert", "", "TI?.")
233 fadd("remove", ".", "T",
234 function(st, slot, pc, base, narg, nres)
235 if nres >= 1 then
236 local t = slot[base+1]
237 slot[base] = type(t) == "table" and rawget(t, 1) or ""
238 end
239 end)
240 fadd("getn", "I", "T")
241
242 fidx = nil -- Pure result type signatures follow:
243 fadd("concat", "S", "TS?I?I?")
244end
245
246-- Signatures for math library functions.
247flibname, flib, fidx = "math", math, 65536*5
248if flib then
249 -- 1 arg, 1 result.
250 fadd("log", "N", "N")
251 fadd("log10", "N", "N")
252 fadd("exp", "N", "N")
253 fadd("sinh", "N", "N")
254 fadd("cosh", "N", "N")
255 fadd("tanh", "N", "N")
256 fadd("asin", "N", "N")
257 fadd("acos", "N", "N")
258 fadd("atan", "N", "N")
259 fadd("sin", "N", "N")
260 fadd("cos", "N", "N")
261 fadd("tan", "N", "N")
262 fadd("ceil", "I", "N")
263 fadd("floor", "I", "N")
264 fadd("abs", ".", "N", copyfirst)
265 fadd("sqrt", "N", "N")
266 -- 2 args, 1 result.
267 -- math.fmod is aliased to math.mod for compatibility.
268 fadd("fmod", ".", "NN",
269 function(st, slot, pc, base, narg, nres)
270 slot[base] = slot[base+2] or 1 -- Copy integer or number hint.
271 end)
272 fadd("atan2", "N", "NN")
273
274 fidx = nil -- Pure result type signatures follow:
275 -- 1-n args, 1 result.
276 fadd("min", ".", "NN*", copyfirst) -- Really depends on all args.
277 fadd("max", ".", "NN*", copyfirst) -- Really depends on all args.
278 -- 1 arg, 1 result.
279 fadd("deg", "N", "N")
280 fadd("rad", "N", "N")
281 -- 1 arg, 2 results.
282 fadd("modf", "IN", "N")
283 fadd("frexp", "NI", "N")
284 -- 2 args, 1 result.
285 fadd("pow", "N", "NN")
286 fadd("ldexp", ".", "NI", copyfirst)
287 -- 1 arg, 0 results.
288 fadd("randomseed", "", "I")
289 -- 0-2 args, 1 result.
290 fadd("random", "N", "I?I?",
291 function(st, slot, pc, base, narg, nres)
292 if narg > 0 then slot[base] = 1 end
293 end)
294end
295
296-- Signatures for I/O library functions.
297-- Not inlined anytime soon. Used for result types only.
298flibname, flib, fidx = "io", io, nil
299if flib then
300 fadd("lines", "C00S", "S?")
301 fadd("read", "S", "") -- Simplified (a lot).
302 -- Adding io methods doesn't work, because we don't deal with userdata (yet).
303end
304
305
306-- Type names to argument type shorthands.
307-- TODO: make the matches more exact? Need to differentiate nil/unknown.
308local map_argtype = {
309 ["nil"] = "0", boolean = "b", number = "n", string = "s",
310 table = "t", ["function"] = "f", userdata = "u", thread = "r",
311}
312
313-- Complex argument match patterns to regexp fragments.
314local map_argmatch = {
315 B = "[b0]", S = "[s0]", T = "[t0]", F = "[f0]", U = "[u0]", R = "[r0]",
316 N = "[n0]", I = "[n0]", -- Number/int args are the same for now.
317 G = "[stf0]", -- For string.gsub.
318}
319
320-- Result type shorthands to sample types.
321local map_restype = {
322 -- ["0"] = nil,
323 B = true, S = "", T = {},
324 N = 0.5, I = 1,
325 L = function() end, C = collectgarbage, -- Pretty sure this is never inlined.
326}
327
328-- Create argument match regexp and cache it.
329local function getargmatch(sign)
330 local argmatch = "^"..gsub(sign.args, ".", map_argmatch).."0*$"
331 sign.argmatch = argmatch
332 return argmatch
333end
334
335-- Set INLINE hints and result types for known C functions.
336local function inlinehint(sign, st, slot, pc, base, narg, nres)
337 local idx = sign.idx
338 if idx then
339 if narg ~= -1 then
340 local argpat = ""
341 for i=1,narg do argpat = argpat..map_argtype[type(slot[base+i])] end
342 if not match(argpat, sign.argmatch or getargmatch(sign)) then
343 idx = nil
344 end
345 end
346 end
347
348 local results = sign.results
349 if results ~= "*" and nres ~= -1 then
350 if nres > #results then idx = nil end
351 for i=1,#results do
352 local c = sub(results, i, i)
353 if c ~= "." then slot[base+i-1] = map_restype[c] end
354 end
355 end
356
357 local handler = sign.handler
358 if handler and handler(st, slot, pc, base, narg, nres, idx) then idx = nil end
359
360 if idx then st[pc+hints.INLINE] = idx end
361end
362
363-- Set call hints and result types during forward propagation.
364local function fwdcallhint(st, slot, pc, base, narg, nres)
365 local f = slot[base]
366 st[pc+hints.TYPE] = f
367 if type(f) == "function" then
368 local sign = map_sign[f]
369 if sign then
370 inlinehint(sign, st, slot, pc, base, narg, nres)
371 return
372 end
373 if f == st.func and not st.stats.isvararg and
374 (narg == -1 or narg == st.stats.params) then
375 st[pc+hints.INLINE] = 0 -- Recursive call.
376 end
377 end
378 -- Clear result types for unknown functions.
379 for i=base,base+nres-1 do slot[i] = nil end
380end
381
382
383-- Attach call hinter to optimizer.
384local function start_()
385 local jopt = require "jit.opt"
386 jopt.attach_callhint(fwdcallhint)
387 -- Note that just loading the optimizer does not start it, yet.
388end
389
390
391-- Public module functions.
392module(...)
393
394-- TODO: Public API to add signatures. Alas, the API is still in flux.
395getname = getname_
396start = start_
397
diff --git a/libraries/LuaJIT-1.1.7/jit/trace.lua b/libraries/LuaJIT-1.1.7/jit/trace.lua
new file mode 100644
index 0000000..42367c6
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/trace.lua
@@ -0,0 +1,111 @@
1----------------------------------------------------------------------------
2-- LuaJIT compiler tracing module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See luajit.h for full copyright notice.
6----------------------------------------------------------------------------
7-- Activate this module to trace the progress of the JIT compiler.
8--
9-- Try: luajit -j trace -e 'print "foo"'
10-- luajit -j trace=foo.trace foo.lua
11--
12-- Default output is to stderr. To redirect output to a file,
13-- pass a filename as an argument or set the environment variable
14-- "LUAJIT_TRACEFILE".
15-- Note: the file is overwritten each time you run luajit.
16------------------------------------------------------------------------------
17
18-- Priority for compiler pipeline. Must run after backend (negative)
19-- and should be odd to catch compiler errors, too.
20local PRIORITY = -99
21
22-- Cache some library functions and objects.
23local jit = require("jit")
24assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
25local jutil = require("jit.util")
26local type, tostring, sub, format = type, tostring, string.sub, string.format
27local getinfo, justats = debug.getinfo, jutil.stats
28local stdout, stderr = io.stdout, io.stderr
29
30-- Turn compilation off for the whole module. LuaJIT would do that anyway.
31jit.off(true, true)
32
33-- Active flag and output file handle.
34local active, out
35
36-- Generate range string from table: pc[-pc] [,...]
37local function rangestring(t)
38 local s = ""
39 for i,range in ipairs(t) do
40 if i ~= 1 then s = s.."," end
41 local pc = range % 65536
42 range = (range - pc) / 65536
43 s = s..pc
44 if range ~= 0 then s = s..(-(pc+range)) end
45 end
46 return s
47end
48
49-- Trace handler for compiler pipeline.
50local function h_trace(st, status)
51 local o = out or stderr
52 local func = st.func
53 if type(func) ~= "function" then return end
54 local info = getinfo(func, "S")
55 local src, line = info.source, info.linedefined or 0
56 if src then
57 if sub(src, 1, 1) == "@" or sub(src, 1, 2) == "=(" then
58 src = sub(src, 2)
59 else
60 src = "**"..string.gsub(sub(src, 1, 40), "%c", " ").."**"
61 end
62 else
63 src = "?"
64 end
65 local aux = st.deopt and " DEOPT="..rangestring(st.deopt) or ""
66 if status == nil then
67 local stats = justats(func)
68 if not stats then return end
69 o:write(format("[LuaJIT: OK %4d %6d %s:%d%s]\n",
70 stats.bytecodes, stats.mcodesize or -1, src, line, aux))
71 return
72 else
73 local stname = jit.util.status[status] or status
74 local pc, err = st.dasm_pc, st.dasm_err
75 if type(pc) == "number" and type(err) == "number" then
76 local op = jutil.bytecode(func, pc) or "END"
77 o:write(format("[LuaJIT: %s %s@%d %08x %s:%d%s]\n",
78 stname, op, pc, err, src, line, aux))
79 else
80 o:write(format("[LuaJIT: %s %s:%d%s]\n", stname, src, line, aux))
81 end
82 end
83end
84
85-- Detach trace handler from compiler pipeline.
86local function traceoff()
87 if active then
88 active = false
89 jit.attach(h_trace)
90 if out and out ~= stdout then out:close() end
91 out = nil
92 end
93end
94
95-- Open the output file and attach trace handler to compiler pipeline.
96local function traceon(filename)
97 if active then traceoff() end
98 local outfile = filename or os.getenv("LUAJIT_TRACEFILE")
99 out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
100 jit.attach(h_trace, PRIORITY)
101 active = true
102end
103
104
105-- Public module functions.
106module(...)
107
108on = traceon
109off = traceoff
110start = traceon -- For -j command line option.
111
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css b/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css
new file mode 100644
index 0000000..69c07d6
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css
@@ -0,0 +1,166 @@
1/* Copyright (C) 2004-2011 Mike Pall.
2 *
3 * You are welcome to use the general ideas of this design for your own sites.
4 * But please do not steal the stylesheet, the layout or the color scheme.
5 */
6body {
7 font-family: serif;
8 font-size: 11pt;
9 margin: 0 3em;
10 padding: 0;
11 border: none;
12}
13a:link, a:visited, a:hover, a:active {
14 text-decoration: none;
15 background: transparent;
16 color: #0000ff;
17}
18h1, h2, h3 {
19 font-family: sans-serif;
20 font-weight: bold;
21 text-align: left;
22 margin: 0.5em 0;
23 padding: 0;
24}
25h1 {
26 font-size: 200%;
27}
28h2 {
29 font-size: 150%;
30}
31h3 {
32 font-size: 125%;
33}
34p {
35 margin: 0 0 0.5em 0;
36 padding: 0;
37}
38ul, ol {
39 margin: 0.5em 0;
40 padding: 0 0 0 2em;
41}
42ul {
43 list-style: outside square;
44}
45ol {
46 list-style: outside decimal;
47}
48li {
49 margin: 0;
50 padding: 0;
51}
52dl {
53 margin: 1em 0;
54 padding: 1em;
55 border: 1px solid black;
56}
57dt {
58 font-weight: bold;
59 margin: 0;
60 padding: 0;
61}
62dt sup {
63 float: right;
64 margin-left: 1em;
65}
66dd {
67 margin: 0.5em 0 0 2em;
68 padding: 0;
69}
70table {
71 table-layout: fixed;
72 width: 100%;
73 margin: 1em 0;
74 padding: 0;
75 border: 1px solid black;
76 border-spacing: 0;
77 border-collapse: collapse;
78}
79tr {
80 margin: 0;
81 padding: 0;
82 border: none;
83}
84td {
85 text-align: left;
86 margin: 0;
87 padding: 0.2em 0.5em;
88 border-top: 1px solid black;
89 border-bottom: 1px solid black;
90}
91tr.separate td {
92 border-top: double;
93}
94tt, pre, code, kbd, samp {
95 font-family: monospace;
96 font-size: 75%;
97}
98kbd {
99 font-weight: bolder;
100}
101blockquote, pre {
102 margin: 1em 2em;
103 padding: 0;
104}
105img {
106 border: none;
107 vertical-align: baseline;
108 margin: 0;
109 padding: 0;
110}
111img.left {
112 float: left;
113 margin: 0.5em 1em 0.5em 0;
114}
115img.right {
116 float: right;
117 margin: 0.5em 0 0.5em 1em;
118}
119.flush {
120 clear: both;
121 visibility: hidden;
122}
123.hide, .noprint, #nav {
124 display: none !important;
125}
126.pagebreak {
127 page-break-before: always;
128}
129#site {
130 text-align: right;
131 font-family: sans-serif;
132 font-weight: bold;
133 margin: 0 1em;
134 border-bottom: 1pt solid black;
135}
136#site a {
137 font-size: 1.2em;
138}
139#site a:link, #site a:visited {
140 text-decoration: none;
141 font-weight: bold;
142 background: transparent;
143 color: #ffffff;
144}
145#logo {
146 color: #ff8000;
147}
148#head {
149 clear: both;
150 margin: 0 1em;
151}
152#main {
153 line-height: 1.3;
154 text-align: justify;
155 margin: 1em;
156}
157#foot {
158 clear: both;
159 font-size: 80%;
160 text-align: center;
161 margin: 0 1.25em;
162 padding: 0.5em 0 0 0;
163 border-top: 1pt solid black;
164 page-break-before: avoid;
165 page-break-after: avoid;
166}
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css b/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css
new file mode 100644
index 0000000..8d72de9
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css
@@ -0,0 +1,292 @@
1/* Copyright (C) 2004-2011 Mike Pall.
2 *
3 * You are welcome to use the general ideas of this design for your own sites.
4 * But please do not steal the stylesheet, the layout or the color scheme.
5 */
6/* colorscheme:
7 *
8 * site | head #4162bf/white | #6078bf/#e6ecff
9 * ------+------ ----------------+-------------------
10 * nav | main #bfcfff | #e6ecff/black
11 *
12 * nav: hiback loback #c5d5ff #b9c9f9
13 * hiborder loborder #e6ecff #97a7d7
14 * link hover #2142bf #ff0000
15 *
16 * link: link visited hover #2142bf #8122bf #ff0000
17 *
18 * main: boxback boxborder #f0f4ff #bfcfff
19 */
20body {
21 font-family: Verdana, Arial, Helvetica, sans-serif;
22 font-size: 10pt;
23 margin: 0;
24 padding: 0;
25 border: none;
26 background: #e0e0e0;
27 color: #000000;
28}
29a:link {
30 text-decoration: none;
31 background: transparent;
32 color: #2142bf;
33}
34a:visited {
35 text-decoration: none;
36 background: transparent;
37 color: #8122bf;
38}
39a:hover, a:active {
40 text-decoration: underline;
41 background: transparent;
42 color: #ff0000;
43}
44h1, h2, h3 {
45 font-weight: bold;
46 text-align: left;
47 margin: 0.5em 0;
48 padding: 0;
49 background: transparent;
50}
51h1 {
52 font-size: 200%;
53 line-height: 3em; /* really 6em relative to body, match #site span */
54 margin: 0;
55}
56h2 {
57 font-size: 150%;
58 color: #606060;
59}
60h3 {
61 font-size: 125%;
62 color: #404040;
63}
64p {
65 max-width: 600px;
66 margin: 0 0 0.5em 0;
67 padding: 0;
68}
69ul, ol {
70 max-width: 600px;
71 margin: 0.5em 0;
72 padding: 0 0 0 2em;
73}
74ul {
75 list-style: outside square;
76}
77ol {
78 list-style: outside decimal;
79}
80li {
81 margin: 0;
82 padding: 0;
83}
84dl {
85 max-width: 600px;
86 margin: 1em 0;
87 padding: 1em;
88 border: 1px solid #bfcfff;
89 background: #f0f4ff;
90}
91dt {
92 font-weight: bold;
93 margin: 0;
94 padding: 0;
95}
96dt sup {
97 float: right;
98 margin-left: 1em;
99 color: #808080;
100}
101dt a:visited {
102 text-decoration: none;
103 color: #2142bf;
104}
105dt a:hover, dt a:active {
106 text-decoration: none;
107 color: #ff0000;
108}
109dd {
110 margin: 0.5em 0 0 2em;
111 padding: 0;
112}
113div.tablewrap { /* for IE *sigh* */
114 max-width: 600px;
115}
116table {
117 table-layout: fixed;
118 border-spacing: 0;
119 border-collapse: collapse;
120 max-width: 600px;
121 width: 100%;
122 margin: 1em 0;
123 padding: 0;
124 border: 1px solid #bfcfff;
125}
126tr {
127 margin: 0;
128 padding: 0;
129 border: none;
130}
131tr.odd {
132 background: #f0f4ff;
133}
134tr.separate td {
135 border-top: 1px solid #bfcfff;
136}
137td {
138 text-align: left;
139 margin: 0;
140 padding: 0.2em 0.5em;
141 border: none;
142}
143tt, code, kbd, samp {
144 font-family: Courier New, Courier, monospace;
145 font-size: 110%;
146}
147kbd {
148 font-weight: bolder;
149}
150blockquote, pre {
151 max-width: 600px;
152 margin: 1em 2em;
153 padding: 0;
154}
155pre {
156 line-height: 1.1;
157}
158img {
159 border: none;
160 vertical-align: baseline;
161 margin: 0;
162 padding: 0;
163}
164img.left {
165 float: left;
166 margin: 0.5em 1em 0.5em 0;
167}
168img.right {
169 float: right;
170 margin: 0.5em 0 0.5em 1em;
171}
172.indent {
173 padding-left: 1em;
174}
175.flush {
176 clear: both;
177 visibility: hidden;
178}
179.hide, .noscreen {
180 display: none !important;
181}
182.ext {
183 color: #ff8000;
184}
185#site {
186 clear: both;
187 float: left;
188 width: 13em;
189 text-align: center;
190 font-weight: bold;
191 margin: 0;
192 padding: 0;
193 background: transparent;
194 color: #ffffff;
195}
196#site a {
197 font-size: 200%;
198}
199#site a:link, #site a:visited {
200 text-decoration: none;
201 font-weight: bold;
202 background: transparent;
203 color: #ffffff;
204}
205#site span {
206 line-height: 3em; /* really 6em relative to body, match h1 */
207}
208#logo {
209 color: #ffb380;
210}
211#head {
212 margin: 0;
213 padding: 0 0 0 2em;
214 border-left: solid 13em #4162bf;
215 border-right: solid 3em #6078bf;
216 background: #6078bf;
217 color: #e6ecff;
218}
219#nav {
220 clear: both;
221 float: left;
222 overflow: hidden;
223 text-align: left;
224 line-height: 1.5;
225 width: 13em;
226 padding-top: 1em;
227 background: transparent;
228}
229#nav ul {
230 list-style: none outside;
231 margin: 0;
232 padding: 0;
233}
234#nav li {
235 margin: 0;
236 padding: 0;
237}
238#nav a {
239 display: block;
240 text-decoration: none;
241 font-weight: bold;
242 margin: 0;
243 padding: 2px 1em;
244 border-top: 1px solid transparent;
245 border-bottom: 1px solid transparent;
246 background: transparent;
247 color: #2142bf;
248}
249#nav a:hover, #nav a:active {
250 text-decoration: none;
251 border-top: 1px solid #97a7d7;
252 border-bottom: 1px solid #e6ecff;
253 background: #b9c9f9;
254 color: #ff0000;
255}
256#nav a.current, #nav a.current:hover, #nav a.current:active {
257 border-top: 1px solid #e6ecff;
258 border-bottom: 1px solid #97a7d7;
259 background: #c5d5ff;
260 color: #2142bf;
261}
262#nav ul ul a {
263 padding: 0 1em 0 2em;
264}
265#main {
266 line-height: 1.5;
267 text-align: left;
268 margin: 0;
269 padding: 1em 2em;
270 border-left: solid 13em #bfcfff;
271 border-right: solid 3em #e6ecff;
272 background: #e6ecff;
273}
274#foot {
275 clear: both;
276 font-size: 80%;
277 text-align: center;
278 margin: 0;
279 padding: 0.5em;
280 background: #6078bf;
281 color: #ffffff;
282}
283#foot a:link, #foot a:visited {
284 text-decoration: underline;
285 background: transparent;
286 color: #ffffff;
287}
288#foot a:hover, #foot a:active {
289 text-decoration: underline;
290 background: transparent;
291 color: #bfcfff;
292}
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco.html b/libraries/LuaJIT-1.1.7/jitdoc/coco.html
new file mode 100644
index 0000000..0ef43f1
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/coco.html
@@ -0,0 +1,132 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Coco</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Coco</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a class="current" href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63Coco is a small extension to get <strong>True C&nbsp;Coroutine</strong>
64semantics for Lua 5.1.
65</p>
66<p>
67Coco is both available as a stand-alone release and integrated
68into <a href="luajit.html">LuaJIT</a> 1.x.
69</p>
70<p>
71The stand-alone release is a patchset against the
72<a href="http://www.lua.org/ftp/"><span class="ext">&raquo;</span>&nbsp;standard Lua 5.1.4</a>
73distribution. There are no dependencies on LuaJIT. However LuaJIT 1.x
74depends on Coco to allow yielding for JIT compiled functions.
75</p>
76<p>
77Coco is Copyright &copy; 2004-2011 Mike Pall.
78Coco is free software, released under the
79<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT/X license</a>
80(same license as the Lua core).
81</p>
82<h2>Features</h2>
83<p>
84True C&nbsp;coroutine semantics mean you can yield from a coroutine
85across a C&nbsp;call boundary and resume back to it.
86</p>
87<p>
88Coco allows you to use a dedicated C&nbsp;stack for each coroutine.
89Resuming a coroutine and yielding from a coroutine automatically switches
90C&nbsp;stacks, too.
91</p>
92<p>
93In particular you can now:
94</p>
95<ul>
96<li>Yield across all metamethods (not advised for <tt>__gc</tt>).</li>
97<li>Yield across iterator functions (<tt>for x in func do</tt>).</li>
98<li>Yield across callbacks (<tt>table.foreach()</tt>, <tt>dofile()</tt>, ...).</li>
99<li>Yield across protected callbacks (<tt>pcall()</tt>, <tt>xpcall()</tt>, ...).</li>
100<li>Yield from C&nbsp;functions and resume back to them.</li>
101</ul>
102<p>
103Best of all, you don't need to change your Lua or C&nbsp;sources
104and still get the benefits. It's fully integrated into the
105Lua core, but tries to minimize the required changes.
106</p>
107
108<h2>More ...</h2>
109<p>
110Please visit the <a href="http://luajit.org/download.html"><span class="ext">&raquo;</span>&nbsp;Download</a> page
111to fetch the current version of the stand-alone package.
112</p>
113<p>
114Coco needs some machine-specific features &mdash; please have a look
115at the <a href="coco_portability.html">Portability Requirements</a>.
116</p>
117<p>
118Coco also provides some upwards-compatible
119<a href="coco_api.html">API Extensions</a> for Lua.
120</p>
121<br class="flush">
122</div>
123<div id="foot">
124<hr class="hide">
125Copyright &copy; 2005-2011 Mike Pall
126<span class="noprint">
127&middot;
128<a href="contact.html">Contact</a>
129</span>
130</div>
131</body>
132</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco_api.html b/libraries/LuaJIT-1.1.7/jitdoc/coco_api.html
new file mode 100644
index 0000000..990ac5b
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/coco_api.html
@@ -0,0 +1,182 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Coco API Extensions</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Coco API Extensions</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a class="current" href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63Coco changes the semantics of several standard API functions and
64provides a few API extensions for Lua.
65</p>
66<p>
67By default all your coroutines get an associated C&nbsp;stack.
68If you want to be more selective, see below.
69</p>
70
71<h2>Lua API extensions</h2>
72<p>
73All <tt>coroutine.*</tt> functions should be fully upwards compatible.
74</p>
75
76<h3><tt>coroutine.coco</tt></h3>
77<p>
78This field is <tt>true</tt> when Coco is present (nil otherwise).
79</p>
80
81<h3><tt>coro = coroutine.create(f [, cstacksize])<br>
82func = coroutine.wrap(f [, cstacksize])</tt></h3>
83<p>
84The optional argument <tt>cstacksize</tt> specifies the size of the
85C&nbsp;stack to allocate for the coroutine:
86</p>
87<ul>
88<li>A default stack size is used if <tt>cstacksize</tt> is not given
89or is nil or zero.</li>
90<li>No C&nbsp;stack is allocated if <tt>cstacksize</tt> is -1.</li>
91<li>Any other value is rounded up to the minimum size
92(i.e. use 1 to get the minimum size).</li>
93</ul>
94<p>
95Important notice for LuaJIT: JIT compiled functions cannot
96yield if a coroutine does not have a dedicated C&nbsp;stack.
97</p>
98
99<h3><tt>olddefault = coroutine.cstacksize([newdefault])</tt></h3>
100<p>
101Returns the current default C&nbsp;stack size (may be 0 if the
102underlying context switch method has its own default).
103Sets a new default C&nbsp;stack size if <tt>newdefault</tt> is present.
104Use 0 to reset it to the default C&nbsp;stack size. Any other
105value is rounded up to the minimum size.
106</p>
107
108<h2>C&nbsp;API extensions</h2>
109<p>
110All C&nbsp;API functions are either unchanged or upwards compatible.
111</p>
112
113<h3><tt>int lua_yield(lua_State *L, int nresults)</tt></h3>
114<p>
115The semantics for <tt>lua_yield()</tt> have changed slightly.
116Existing programs should work fine as long as they follow
117the usage conventions from the Lua manual:
118</p>
119<pre>
120return lua_yield(L, nresults);
121</pre>
122<p>
123Previously <tt>lua_yield()</tt> returned a 'magic' value (<tt>-1</tt>) that
124indicated a yield. Your C&nbsp;function had to pass this value
125on to the Lua core and was <em>not</em> called again.
126</p>
127<p>
128Now, if the current coroutine has an associated C&nbsp;stack,
129<tt>lua_yield()</tt> returns the number of arguments passed back from
130the resume. This just happens to be the right convention for
131returning them as a result from a C&nbsp;function. I.e. if you
132used the above convention, you'll never notice the change.
133</p>
134<p>
135But the results <em>are</em> on the Lua stack when <tt>lua_yield()</tt>
136returns. So the C&nbsp;function can just continue and process them
137or retry an I/O operation etc. And your whole C&nbsp;stack frame
138(local variables etc.) is still there, too. You can yield from
139anywhere in your C&nbsp;program, even several call levels deeper.
140</p>
141<p>
142Of course all of this only works with Lua+Coco and not with standard Lua.
143</p>
144
145<h3><tt>lua_State *lua_newcthread(lua_State *L, int cstacksize)</tt></h3>
146<p>
147This is an (optional) new function that allows you to create
148a coroutine with an associated C&nbsp;stack directly from the C&nbsp;API.
149Other than that it works the same as <tt>lua_newthread(L)</tt>.
150</p>
151<p>
152You have to declare this function as <tt>extern</tt>
153yourself, since it's not part of the official Lua API.
154This means that a C&nbsp;module that uses this call cannot
155be loaded with standard Lua. This may be intentional.
156</p>
157<p>
158If you want your C&nbsp;module to work with both standard Lua
159and Lua+Coco you can check whether Coco is available with:
160</p>
161<pre>
162 lua_getfield(L, LUA_GLOBALSINDEX, "coroutine");
163 lua_getfield(L, -1, "coco");
164 coco_available = lua_toboolean(L, -1);
165 lua_pop(L, 2);
166</pre>
167<p>
168You can create coroutines with a C&nbsp;stack by calling
169the Lua function <tt>coroutine.create()</tt> from C, too.
170</p>
171<br class="flush">
172</div>
173<div id="foot">
174<hr class="hide">
175Copyright &copy; 2005-2011 Mike Pall
176<span class="noprint">
177&middot;
178<a href="contact.html">Contact</a>
179</span>
180</div>
181</body>
182</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco_changes.html b/libraries/LuaJIT-1.1.7/jitdoc/coco_changes.html
new file mode 100644
index 0000000..ea2dc16
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/coco_changes.html
@@ -0,0 +1,146 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Coco Change History</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Coco Change History</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a class="current" href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63This is a list of changes between the released versions of Coco.
64The current stand-alone release is <strong>Coco&nbsp;1.1.6</strong>.
65</p>
66<p>
67Please check the
68<a href="http://coco.luajit.org/changes.html"><span class="ext">&raquo;</span>&nbsp;Online Change History</a>
69to see whether newer versions are available.
70</p>
71
72<h2 id="Coco-1.1.6">Coco 1.1.6 &mdash; 2009-09-08</h2>
73<ul>
74<li>Fix compilation of the GCC inline assembler code on x64.
75Now works when compiled as C++ code (reported by Jonathan Sauer)
76or with -fPIC (reported by Jim Pryor).</li>
77<li>Added GCC inline assembler for faster context switching on Sparc.
78Thanks to Takayuki Usui.</li>
79</ul>
80
81<h2 id="Coco-1.1.5">Coco 1.1.5 &mdash; 2008-10-25</h2>
82<ul>
83<li>Upgraded to patch cleanly into Lua 5.1.4.</li>
84<li>Added GCC inline assembler for faster context switching on x64.
85Thanks to Robert G. Jakabosky.</li>
86</ul>
87
88<h2 id="Coco-1.1.4">Coco 1.1.4 &mdash; 2008-02-05</h2>
89<ul>
90<li>Upgraded to patch cleanly into Lua 5.1.3.</li>
91<li>Fixed setjmp method for ARM with recent glibc versions.
92Thanks to the LuaTeX developers.</li>
93<li>Fixed setjmp method for x86 on Mac OS X (rarely used,
94default is GCC inline assembler). Thanks to Jason Toffaletti.</li>
95</ul>
96
97<h2 id="Coco-1.1.3">Coco 1.1.3 &mdash; 2007-05-24</h2>
98<ul>
99<li>Upgraded to patch cleanly into Lua 5.1.2.</li>
100<li>Merged patch from Zachary P. Landau for a Linux/ARM setjmp method (uClibc and glibc).</li>
101</ul>
102
103<h2 id="Coco-1.1.1">Coco 1.1.1 &mdash; 2006-06-20</h2>
104<ul>
105<li>Upgraded to patch cleanly into Lua 5.1.1.</li>
106<li>C stacks are deallocated early: when a coroutine ends, and not when
107the coroutine object is collected. This mainly benefits Windows Fibers.</li>
108<li>Windows threads get the required Fiber context when resuming
109a coroutine and not just on creation.</li>
110</ul>
111
112<h2 id="Coco-1.1.0">Coco 1.1.0 &mdash; 2006-02-18</h2>
113<ul>
114<li>Upgraded to patch cleanly into Lua 5.1 (final).</li>
115<li>Added GCC inline assembler for context switching on x86 and MIPS32
116[up to 3x faster].</li>
117<li>New targets for setjmp method:
118Mac OS X/x86, Solaris/x86 and x64 and Linux/MIPS32.</li>
119<li>Workaround for WinXP problem with GetCurrentFiber().</li>
120<li>The minimum C stack size has been increased to 32K+4K.</li>
121<li>Removed <tt>lcocolib.c</tt> and integrated the (much smaller) changes
122into <tt>lbaselib.c</tt>.<br>
123Note for embedders: this means you no longer need to call
124<tt>luaopen_coco()</tt>.</li>
125<li>Optional Valgrind support requires version 3.x.
126Renamed define to USE_VALGRIND.</li>
127<li>C stacks are now registered with Valgrind.</li>
128</ul>
129
130<h2 id="Coco-51w6">Coco pre-release 51w6 &mdash; 2005-08-09</h2>
131<p>
132This is the first pre-release of Coco. It targets Lua 5.1-work6 only
133and is no longer available for download.
134</p>
135<br class="flush">
136</div>
137<div id="foot">
138<hr class="hide">
139Copyright &copy; 2005-2011 Mike Pall
140<span class="noprint">
141&middot;
142<a href="contact.html">Contact</a>
143</span>
144</div>
145</body>
146</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco_portability.html b/libraries/LuaJIT-1.1.7/jitdoc/coco_portability.html
new file mode 100644
index 0000000..e120ae9
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/coco_portability.html
@@ -0,0 +1,235 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Portability Requirements for Coco</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.support {
13 line-height: 1.2;
14 width: 25em;
15}
16tr.supporthead td {
17 font-weight: bold;
18}
19td.supportcpu {
20 width: 6em;
21}
22td.supportsys {
23 width: 8em;
24}
25</style>
26</head>
27<body>
28<div id="site">
29<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
30</div>
31<div id="head">
32<h1>Portability Requirements for Coco</h1>
33</div>
34<div id="nav">
35<ul><li>
36<a href="index.html">Index</a>
37</li><li>
38<a href="luajit.html">LuaJIT</a>
39<ul><li>
40<a href="luajit_features.html">Features</a>
41</li><li>
42<a href="luajit_install.html">Installation</a>
43</li><li>
44<a href="luajit_run.html">Running</a>
45</li><li>
46<a href="luajit_api.html">API Extensions</a>
47</li><li>
48<a href="luajit_intro.html">Introduction</a>
49</li><li>
50<a href="luajit_performance.html">Performance</a>
51</li><li>
52<a href="luajit_debug.html">Debugging</a>
53</li><li>
54<a href="luajit_changes.html">Changes</a>
55</li></ul>
56</li><li>
57<a href="coco.html">Coco</a>
58<ul><li>
59<a class="current" href="coco_portability.html">Portability</a>
60</li><li>
61<a href="coco_api.html">API Extensions</a>
62</li><li>
63<a href="coco_changes.html">Changes</a>
64</li></ul>
65</li><li>
66<a href="dynasm.html">DynASM</a>
67<ul><li>
68<a href="dynasm_features.html">Features</a>
69</li><li>
70<a href="dynasm_examples.html">Examples</a>
71</li></ul>
72</li><li>
73<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
74</li></ul>
75</div>
76<div id="main">
77<p>
78Coco needs some machine-specific features which are
79inherently non-portable. Although the coverage is pretty good,
80this means that Coco will probably never be a standard part
81of the Lua core (which is pure ANSI&nbsp;C).
82</p>
83
84<h2>Context Switching Methods</h2>
85<p>
86Coco relies on four different machine-specific methods
87for allocating a C&nbsp;stack and switching context.
88The appropriate method is automatically selected at compile time.
89</p>
90
91<h3>GCC Inline Assembler</h3>
92<p>
93This method is only available when GCC 3.x/4.x is used
94to compile the source.
95This is the fastest method for context switching, but only available
96for a few CPUs (see below).
97</p>
98
99<h3>Modified setjmp Buffer</h3>
100<p>
101This method changes a few fields in the setjmp buffer to
102redirect the next longjmp to a new function with a new stack
103frame. It needs a bit of guesswork and lots of #ifdef's to
104handle the supported CPU/OS combinations, but this is quite
105manageable.
106</p>
107<p>
108This is the fallback method if inline assembler is not available.
109It's pretty fast because it doesn't have to save or restore signals
110(which is slow and generally undesirable for Lua coroutines).
111</p>
112
113<h3>POSIX ucontext</h3>
114<p>
115The POSIX calls getcontext, makecontext and switchcontext
116are used to set up and switch between different C&nbsp;stacks.
117Although highly portable and even available for some
118esoteric platforms, it's slower than the setjmp method
119because it saves and restores signals, too (using at least one
120syscall for each context switch).
121</p>
122<p>
123You can force the use of ucontext (instead of setjmp) by enabling
124<tt>-DCOCO_USE_UCONTEXT</tt> in <tt>src/Makefile</tt>.
125</p>
126
127<h3>Windows Fibers</h3>
128<p>
129This is the standard method to set up and switch between
130different C&nbsp;stacks on Windows. It's available on Windows&nbsp;98
131and later.
132</p>
133<p>
134None of the other methods work for Windows because OS specific code
135is required to switch exception handling contexts.
136</p>
137
138<h2 class="pagebreak">Supported Platforms</h2>
139<p>
140Coco has support for the following platforms:
141</p>
142<table class="support">
143<tr class="supporthead">
144<td class="supportcpu">CPU</td>
145<td class="supportsys">System</td>
146<td>Method</td>
147</tr>
148<tr class="odd separate">
149<td class="supportcpu">x86</td><td class="supportsys">(any OS)</td><td>gccasm</td></tr>
150<tr class="even">
151<td class="supportcpu">x86</td><td class="supportsys">Linux</td><td>setjmp</td></tr>
152<tr class="odd">
153<td class="supportcpu">x86</td><td class="supportsys">FreeBSD</td><td>setjmp</td></tr>
154<tr class="even">
155<td class="supportcpu">x86</td><td class="supportsys">NetBSD</td><td>setjmp</td></tr>
156<tr class="odd">
157<td class="supportcpu">x86</td><td class="supportsys">OpenBSD</td><td>setjmp</td></tr>
158<tr class="even">
159<td class="supportcpu">x86</td><td class="supportsys">Solaris</td><td>setjmp</td></tr>
160<tr class="odd">
161<td class="supportcpu">x86</td><td class="supportsys">Mac OS X</td><td>setjmp</td></tr>
162<tr class="even separate">
163<td class="supportcpu">x64</td><td class="supportsys">(any OS)</td><td>gccasm</td></tr>
164<tr class="odd">
165<td class="supportcpu">x64</td><td class="supportsys">Solaris</td><td>setjmp</td></tr>
166<tr class="even separate">
167<td class="supportcpu">MIPS32</td><td class="supportsys">(any OS)</td><td>gccasm</td></tr>
168<tr class="odd">
169<td class="supportcpu">MIPS32</td><td class="supportsys">Linux</td><td>setjmp</td></tr>
170<tr class="even separate">
171<td class="supportcpu">ARM</td><td class="supportsys">Linux</td><td>setjmp</td></tr>
172<tr class="odd separate">
173<td class="supportcpu">PPC32</td><td class="supportsys">Mac OS X</td><td>setjmp</td></tr>
174<tr class="even separate">
175<td class="supportcpu">(any CPU)</td><td class="supportsys">POSIX</td><td>ucontext</td></tr>
176<tr class="odd separate">
177<td class="supportcpu">(any CPU)</td><td class="supportsys">Windows</td><td>fibers</td></tr>
178</table>
179<pre>
180</pre>
181<p>
182It should work pretty much anywhere where a <em>correct</em>
183POSIX ucontext implementation is available. It has been tested
184on every systems I could get hold of (e.g. Sparc, PPC32/PPC64,
185IA64, Alpha, HPPA with various operating systems).
186</p>
187
188<h2>Caveats</h2>
189<ul>
190<li>
191Some older operating systems may have defective ucontext
192implementations because this feature is not widely used. E.g. some
193implementations don't mix well with other C&nbsp;library functions
194like <tt>malloc()</tt> or with native threads.
195This is really not the fault of Coco &mdash; please upgrade your OS.
196</li>
197<li>
198Note for Windows: Please read the explanation for the default
199<a href="http://msdn.microsoft.com/library/en-us/dllproc/base/thread_stack_size.asp"><span class="ext">&raquo;</span>&nbsp;Thread Stack Size</a>
200in case you want to create large numbers of Fiber-based coroutines.
201</li>
202<li>
203Note for MinGW/Cygwin: Older releases of GCC (before 4.0) generate
204wrong unwind information when <tt>-fomit-frame-pointer</tt> is used
205with stdcalls. This may lead to crashes when exceptions are thrown.
206The workaround is to always use two flags:<br>
207<tt>-fomit-frame-pointer -maccumulate-outgoing-args</tt>.
208</li>
209<li>
210Note for MIPS CPUs without FPU: It's recommended to compile
211<em>all</em> sources with <tt>-msoft-float</tt>, even if you don't use
212any floating point ops anywhere. Otherwise context switching must
213save and restore FPU registers (which needs to go through
214the slow kernel emulation).
215</li>
216<li>
217To run Coco with <a href="http://valgrind.org/"><span class="ext">&raquo;</span>&nbsp;Valgrind</a>
218(a memory debugger) you <em>must</em> add <tt>-DUSE_VALGRIND</tt>
219to <tt>MYCFLAGS</tt> and recompile. You will get random errors
220if you don't! Valgrind 3.x or later is required. Earlier versions
221do not work well with newly allocated C stacks.
222</li>
223</ul>
224<br class="flush">
225</div>
226<div id="foot">
227<hr class="hide">
228Copyright &copy; 2005-2011 Mike Pall
229<span class="noprint">
230&middot;
231<a href="contact.html">Contact</a>
232</span>
233</div>
234</body>
235</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/contact.html b/libraries/LuaJIT-1.1.7/jitdoc/contact.html
new file mode 100644
index 0000000..5da1ecf
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/contact.html
@@ -0,0 +1,105 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Contact</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Contact</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63Please send general questions regarding LuaJIT or Coco to the
64<a href="http://www.lua.org/lua-l.html"><span class="ext">&raquo;</span>&nbsp;Lua mailing list</a>.
65You can also send any questions you have directly to me:
66</p>
67
68<script type="text/javascript">
69<!--
70var xS="@-: .0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZa<b>cdefghijklmnopqrstuvwxyz"
71function xD(s)
72{var len=s.length;var r="";for(var i=0;i<len;i++)
73{var c=s.charAt(i);var n=xS.indexOf(c);if(n!=-1)
74c=xS.charAt(66-n);r+=c;}
75document.write("<"+"p>"+r+"<"+"/p>\n");}
76//-->
77</script>
78<script type="text/javascript">
79<!--
80xD("ewYKA7vu-EIwslx7 K9A.t41C")
81//--></script>
82<noscript>
83<p><img src="img/contact.png" alt="Contact info in image" width="170" height="13">
84</p>
85</noscript>
86
87<h2>Copyright</h2>
88<p>
89All documentation is
90Copyright &copy; 2005-2011 Mike Pall.
91</p>
92
93
94<br class="flush">
95</div>
96<div id="foot">
97<hr class="hide">
98Copyright &copy; 2005-2011 Mike Pall
99<span class="noprint">
100&middot;
101<a href="contact.html">Contact</a>
102</span>
103</div>
104</body>
105</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/dynasm.html b/libraries/LuaJIT-1.1.7/jitdoc/dynasm.html
new file mode 100644
index 0000000..de8f859
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/dynasm.html
@@ -0,0 +1,116 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>DynASM</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>DynASM</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a class="current" href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63DynASM is a <strong>Dynamic Assembler</strong> for code generation
64engines.
65</p>
66<p>
67DynASM has been developed primarily as a tool for
68<a href="luajit.html">LuaJIT</a>, but might be useful for other
69projects, too.
70</p>
71<p>
72If you are writing a just-in-time compiler or need to generate
73code on the fly (e.g. for high-performance graphics or other
74CPU-intensive computations), DynASM might be just what you
75are looking for.
76</p>
77<p>
78Please have a look at the list of <a href="dynasm_features.html">Features</a>
79to find out whether DynASM could be useful for your project.
80</p>
81<p>
82DynASM is Copyright &copy; 2005-2011 Mike Pall.
83DynASM is free software, released under the
84<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT/X license</a>.
85</p>
86
87<h2>More ...</h2>
88<p>
89Sorry, right now there is no proper documentation available other
90than some <a href="dynasm_examples.html">Examples</a> and of course
91the source code. The source <em>is</em> well documented, though (IMHO).
92</p>
93<p>
94I may add more docs in case someone actually finds DynASM to be
95useful outside of LuaJIT. If you do, I'd like to
96<a href="contact.html">hear</a> from you, please. Thank you!
97</p>
98<p>
99If you want to check it out please visit the
100<a href="http://luajit.org/download.html"><span class="ext">&raquo;</span>&nbsp;Download</a> page and fetch the most recent
101version of LuaJIT. All you need is in the dynasm directory.
102For some complex examples take a peek at the
103<tt>*.dasc</tt> and <tt>*.dash</tt> files in LuaJIT, too.
104</p>
105<br class="flush">
106</div>
107<div id="foot">
108<hr class="hide">
109Copyright &copy; 2005-2011 Mike Pall
110<span class="noprint">
111&middot;
112<a href="contact.html">Contact</a>
113</span>
114</div>
115</body>
116</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/dynasm_examples.html b/libraries/LuaJIT-1.1.7/jitdoc/dynasm_examples.html
new file mode 100644
index 0000000..5d2331e
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/dynasm_examples.html
@@ -0,0 +1,188 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>DynASM Examples</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>DynASM Examples</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a class="current" href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<h2>A Simple Example</h2>
63<p>
64To get you started, here is a simple code snippet to be pre-processed.
65The lines starting with '|' (the pipe symbol) are for DynASM:
66</p>
67<pre>
68 if (ptr != NULL) {
69 | mov eax, foo+17
70 | mov edx, [eax+esi*2+0x20]
71 | add ebx, [ecx+bar(ptr, 9)]
72 }
73</pre>
74<p>
75After pre-processing you get:
76</p>
77<pre>
78 if (ptr != NULL) {
79 dasm_put(Dst, 123, foo+17, bar(ptr, 9));
80 }
81</pre>
82<p style="font-size: 80%;">
83Note: yes, you usually get the assembler code as comments and proper
84CPP directives to match them up with the source. I've omitted
85them here for clarity. Oh and BTW: the pipe symbols probably
86line up much more nicely in your editor than in a browser.
87</p>
88<p>
89Here 123 is an offset into the action list buffer that
90holds the partially specified machine code. Without going
91into too much detail, the embedded C&nbsp;library implements a
92tiny bytecode engine that takes the action list as input and
93outputs machine code. It basically copies machine code snippets
94from the action list and merges them with the arguments
95passed in by <tt>dasm_put()</tt>.
96</p>
97<p>
98The arguments can be any kind of C&nbsp;expressions. In practical
99use most of them evaluate to constants (e.g. structure offsets).
100Your C&nbsp;compiler should generate very compact code out of it.
101</p>
102<p>
103The embedded C&nbsp;library knows only what's absolutely needed to
104generate proper machine code for the target CPU (e.g. variable
105displacement sizes, variable branch offset sizes and so on).
106It doesn't have a clue about other atrocities like x86 opcode
107encodings &mdash; and it doesn't need to. This dramatically
108reduces the minimum required code size to around 2K [sic!].
109</p>
110<p>
111The action list buffer itself has a pretty compact encoding, too.
112E.g. the whole action list buffer for an early version of LuaJIT
113needs only around 3K.
114</p>
115
116<h2>Advanced Features</h2>
117<p>
118Here's a real-life example taken from LuaJIT that shows some
119advanced features like type maps, macros and how to access
120C&nbsp;structures:
121</p>
122<pre>
123|.type L, lua_State, esi // L.
124|.type BASE, TValue, ebx // L->base.
125|.type TOP, TValue, edi // L->top.
126|.type CI, CallInfo, ecx // L->ci.
127|.type LCL, LClosure, eax // L->ci->func->value.
128|.type UPVAL, UpVal
129
130|.macro copyslot, D, S, R1, R2, R3
131| mov R1, S.value; mov R2, S.value.na[1]; mov R3, S.tt
132| mov D.value, R1; mov D.value.na[1], R2; mov D.tt, R3
133|.endmacro
134
135|.macro copyslot, D, S; copyslot D, S, ecx, edx, eax; .endmacro
136
137|.macro getLCL, reg
138||if (!J->pt->is_vararg) {
139| mov LCL:reg, BASE[-1].value
140||} else {
141| mov CI, L->ci
142| mov TOP, CI->func
143| mov LCL:reg, TOP->value
144||}
145|.endmacro
146
147|.macro getLCL; getLCL eax; .endmacro
148
149[...]
150
151static void jit_op_getupval(jit_State *J, int dest, int uvidx)
152{
153 | getLCL
154 | mov UPVAL:ecx, LCL->upvals[uvidx]
155 | mov TOP, UPVAL:ecx->v
156 | copyslot BASE[dest], TOP[0]
157}
158</pre>
159<p>
160And here is the pre-processed output (stripped a bit for clarity):
161</p>
162<pre>
163#define Dt1(_V) (int)&amp;(((lua_State *)0)_V)
164[...]
165static void jit_op_getupval(jit_State *J, int dest, int uvidx)
166{
167 if (!J->pt->is_vararg) {
168 dasm_put(Dst, 1164, Dt2([-1].value));
169 } else {
170 dasm_put(Dst, 1168, Dt1(->ci), Dt4(->func), Dt3(->value));
171 }
172 dasm_put(Dst, 1178, Dt5(->upvals[uvidx]), DtF(->v), Dt3([0].value),
173 Dt3([0].value.na[1]), Dt3([0].tt), Dt2([dest].value),
174 Dt2([dest].value.na[1]), Dt2([dest].tt));
175}
176</pre>
177<br class="flush">
178</div>
179<div id="foot">
180<hr class="hide">
181Copyright &copy; 2005-2011 Mike Pall
182<span class="noprint">
183&middot;
184<a href="contact.html">Contact</a>
185</span>
186</div>
187</body>
188</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/dynasm_features.html b/libraries/LuaJIT-1.1.7/jitdoc/dynasm_features.html
new file mode 100644
index 0000000..1b8ce69
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/dynasm_features.html
@@ -0,0 +1,139 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>DynASM Features</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>DynASM Features</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a class="current" href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<h2>DynASM Toolchain Features</h2>
63<ul>
64<li>DynASM is a pre-processing assembler.</li>
65<li>DynASM converts mixed C/Assembler source to plain C&nbsp;code.</li>
66<li>The primary knowledge about instruction names, operand modes,
67registers, opcodes and how to encode them is <em>only</em>
68needed in the pre-processor.</li>
69<li>The generated C&nbsp;code is extremely small and fast.</li>
70<li>A tiny embeddable C&nbsp;library helps with the process of dynamically
71assembling, relocating and linking machine code.</li>
72<li>There are no outside dependencies on other tools (such as
73stand-alone assemblers or linkers).</li>
74<li>Internal consistency checks catch runtime errors
75(e.g. undefined labels).</li>
76<li>The toolchain is split into a portable subset and
77CPU-specific modules.</li>
78<li>DynASM itself (the pre-processor) is written in Lua.</li>
79<li>There is no machine-dependency for the pre-processor itself.
80It should work everywhere you can get Lua 5.1 up and running
81(i.e. Linux, *BSD, Solaris, Windows, ... you name it).</li>
82</ul>
83
84<h2>DynASM Assembler Features</h2>
85<ul>
86<li>C&nbsp;code and assembler code can be freely mixed.
87<em>Readable</em>, too.</li>
88<li>All the usual syntax for instructions and operand modes
89you come to expect from a standard assembler.</li>
90<li>Access to C&nbsp;variables and CPP defines in assembler statements.</li>
91<li>Access to C&nbsp;structures and unions via type mapping.</li>
92<li>Convenient shortcuts for accessing C&nbsp;structures.</li>
93<li>Local and global labels.</li>
94<li>Numbered labels (e.g. for mapping bytecode instruction numbers).</li>
95<li>Multiple code sections (e.g. for tailcode).</li>
96<li>Defines/substitutions (inline and from command line).</li>
97<li>Conditionals (translation time) with proper nesting.</li>
98<li>Macros with parameters.</li>
99<li>Macros can mix assembler statements and C&nbsp;code.</li>
100<li>Captures (output diversion for code reordering).</li>
101<li>Simple and extensible template system for instruction definitions.</li>
102</ul>
103
104<h2>Restrictions</h2>
105<p>
106Currently only a subset of x86 (i386+) instructions is supported.
107Unsupported instructions are either not usable in user-mode or
108are slow on modern CPUs (i.e. not suited for a code generator).
109SSE, SSE2, SSE3 and SSSE3 are fully supported. MMX is not supported.
110</p>
111<p>
112The whole toolchain has been designed to support multiple CPU
113architectures. As LuaJIT gets support for more architectures,
114DynASM will be extended with new CPU-specific modules.
115</p>
116<p>
117The assembler itself will be extended with more features on an
118as-needed basis. E.g. I'm thinking about vararg macros.
119</p>
120<p>
121Note that runtime conditionals are not really needed, since you can
122just use plain C&nbsp;code for that (and LuaJIT does this <em>a lot</em>).
123It's not going to be more (time-) efficient if conditionals are done
124by the embedded C&nbsp;library (maybe a bit more space-efficient).
125</p>
126
127
128<br class="flush">
129</div>
130<div id="foot">
131<hr class="hide">
132Copyright &copy; 2005-2011 Mike Pall
133<span class="noprint">
134&middot;
135<a href="contact.html">Contact</a>
136</span>
137</div>
138</body>
139</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/backbar.png b/libraries/LuaJIT-1.1.7/jitdoc/img/backbar.png
new file mode 100644
index 0000000..3c90029
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/img/backbar.png
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/bluebar.png b/libraries/LuaJIT-1.1.7/jitdoc/img/bluebar.png
new file mode 100644
index 0000000..70dcf07
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/img/bluebar.png
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/contact.png b/libraries/LuaJIT-1.1.7/jitdoc/img/contact.png
new file mode 100644
index 0000000..9c73dc5
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/img/contact.png
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/magentabar.png b/libraries/LuaJIT-1.1.7/jitdoc/img/magentabar.png
new file mode 100644
index 0000000..11ebd2b
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/img/magentabar.png
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/spacer.png b/libraries/LuaJIT-1.1.7/jitdoc/img/spacer.png
new file mode 100644
index 0000000..75a203c
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/img/spacer.png
Binary files differ
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/index.html b/libraries/LuaJIT-1.1.7/jitdoc/index.html
new file mode 100644
index 0000000..22236b4
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/index.html
@@ -0,0 +1,103 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>The LuaJIT Project</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>The LuaJIT Project</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a class="current" href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63This is the offline documentation for:
64</p>
65<ul>
66<li>
67<a href="luajit.html">LuaJIT</a> &mdash;
68a <strong>Just-In-Time Compiler</strong> for Lua.
69</li>
70<li>
71<a href="coco.html">Coco</a> &mdash;
72a Lua extension for <strong>True C&nbsp;Coroutines</strong>.
73</li>
74<li>
75<a href="dynasm.html">DynASM</a> &mdash;
76a <strong>Dynamic Assembler</strong> for code generation engines.
77</li>
78</ul>
79
80
81
82<h2>More ...</h2>
83<p>
84Please click on one of the links in the navigation bar to your left
85to learn more.
86</p>
87<p>
88Click on the Logo in the upper left corner to visit
89the LuaJIT project page on the web. All other links to online
90resources are marked with a '<span class="ext">&raquo;</span>'.
91</p>
92<br class="flush">
93</div>
94<div id="foot">
95<hr class="hide">
96Copyright &copy; 2005-2011 Mike Pall
97<span class="noprint">
98&middot;
99<a href="contact.html">Contact</a>
100</span>
101</div>
102</body>
103</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit.html
new file mode 100644
index 0000000..f9a7245
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit.html
@@ -0,0 +1,109 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>LuaJIT</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>LuaJIT</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a class="current" href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63LuaJIT is a <strong>Just-In-Time Compiler</strong> for the Lua
64programming language.
65</p>
66<p class="indent">
67Lua is a powerful, light-weight programming language designed
68for extending applications. Lua is also frequently used as a
69general-purpose, stand-alone language. More information about
70Lua can be found at: <a href="http://www.lua.org/"><span class="ext">&raquo;</span>&nbsp;http://www.lua.org/</a>
71</p>
72<p>
73LuaJIT 1.x is based on the Lua 5.1.x virtual machine and bytecode interpreter
74from lua.org. It compiles bytecode to native x86 (i386+) machine code
75to speed up the execution of Lua programs.
76</p>
77<p>
78LuaJIT depends on <a href="coco.html">Coco</a> to allow yielding
79from coroutines for JIT compiled functions. Coco is part of the
80LuaJIT distribution.
81</p>
82<p>
83LuaJIT is Copyright &copy; 2005-2011 Mike Pall.
84LuaJIT is free software, released under the
85<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT/X license</a>
86(same license as the Lua core).
87</p>
88<h2>More ...</h2>
89<p>
90Click on the LuaJIT sub-topics in the navigation bar to learn more
91about LuaJIT.
92</p>
93<p style="background: #ffd0d0; text-align: center;">
94LuaJIT 2.0 is available with much improved performance!<br>
95Please visit the <a href="http://luajit.org/download.html"><span class="ext">&raquo;</span>&nbsp;Download</a> page to fetch
96the current version of LuaJIT.
97</p>
98<br class="flush">
99</div>
100<div id="foot">
101<hr class="hide">
102Copyright &copy; 2005-2011 Mike Pall
103<span class="noprint">
104&middot;
105<a href="contact.html">Contact</a>
106</span>
107</div>
108</body>
109</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_api.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_api.html
new file mode 100644
index 0000000..58ac809
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_api.html
@@ -0,0 +1,372 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>LuaJIT API Extensions</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12td.stname { width: 10em; }
13tr.sthead td { font-weight: bold; }
14</style>
15</head>
16<body>
17<div id="site">
18<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
19</div>
20<div id="head">
21<h1>LuaJIT API Extensions</h1>
22</div>
23<div id="nav">
24<ul><li>
25<a href="index.html">Index</a>
26</li><li>
27<a href="luajit.html">LuaJIT</a>
28<ul><li>
29<a href="luajit_features.html">Features</a>
30</li><li>
31<a href="luajit_install.html">Installation</a>
32</li><li>
33<a href="luajit_run.html">Running</a>
34</li><li>
35<a class="current" href="luajit_api.html">API Extensions</a>
36</li><li>
37<a href="luajit_intro.html">Introduction</a>
38</li><li>
39<a href="luajit_performance.html">Performance</a>
40</li><li>
41<a href="luajit_debug.html">Debugging</a>
42</li><li>
43<a href="luajit_changes.html">Changes</a>
44</li></ul>
45</li><li>
46<a href="coco.html">Coco</a>
47<ul><li>
48<a href="coco_portability.html">Portability</a>
49</li><li>
50<a href="coco_api.html">API Extensions</a>
51</li><li>
52<a href="coco_changes.html">Changes</a>
53</li></ul>
54</li><li>
55<a href="dynasm.html">DynASM</a>
56<ul><li>
57<a href="dynasm_features.html">Features</a>
58</li><li>
59<a href="dynasm_examples.html">Examples</a>
60</li></ul>
61</li><li>
62<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
63</li></ul>
64</div>
65<div id="main">
66<p>
67LuaJIT provides several new API functions organized into two
68libraries.
69</p>
70<p>
71LuaJIT includes Coco &mdash; so have a look at the
72<a href="coco_api.html">Coco API Extensions</a>, too.
73</p>
74
75<h2>Standard Library Functions</h2>
76<p>
77All standard library functions have the same behaviour as
78in the Lua distribution LuaJIT is based on.
79</p>
80<p>
81The Lua loader used by the standard <tt>require()</tt> library
82function has been modified to turn off compilation of the main
83chunk of a module. The main chunk is only run once when the module
84is loaded for the first time. There is no point in compiling it.
85</p>
86<p>
87You might want to adapt this behaviour if you use your own utility
88functions (and not <tt>require()</tt>) to load modules.
89</p>
90<p>
91Note that the subfunctions defined in a loaded module <em>are</em>
92of course compiled. See below if you want to override this.
93</p>
94
95<h2>The jit.* Library</h2>
96<p>
97This library holds several functions to control the behaviour
98of the JIT engine.
99</p>
100
101<h3 id="jit_onoff"><tt>jit.on()<br>
102jit.off()</tt></h3>
103<p>
104Turns the JIT engine on (default) or off.
105</p>
106<p>
107These functions are typically used with the command line options
108<tt>-j on</tt> or <tt>-j off</tt>.
109</p>
110
111<h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br>
112jit.off(func|true [,true|false])</tt></h3>
113<p>
114Enable (with <tt>jit.on</tt>, default) or disable (with <tt>jit.off</tt>)
115JIT compilation for a Lua function. The current function (the Lua function
116calling this library function) can be specified with <tt>true</tt>.
117</p>
118<p>
119If the second argument is <tt>true</tt>, JIT compilation is also
120enabled/disabled recursively for all subfunctions of a function.
121With <tt>false</tt> only the subfunctions are affected.
122</p>
123<p>
124Both library functions only set a flag which is checked when
125the function is executed for the first/next time. They do not
126trigger immediate compilation.
127</p>
128<p>
129Typical usage is <tt>jit.off(true, true)</tt> in the main chunk
130of a module to turn off JIT compilation for the whole module.
131Note that <tt>require()</tt> already turns off compilation for
132the main chunk itself.
133</p>
134
135<h3 id="jit_compile"><tt>status = jit.compile(func [,args...])</tt></h3>
136<p>
137Compiles a Lua function and returns the compilation status.
138Successful compilation is indicated with a <tt>nil</tt> status.
139Failure is indicated with a numeric status (see <tt>jit.util.status</tt>).
140</p>
141<p>
142The optimizer pass of the compiler tries to derive hints from the
143passed arguments. Not passing any arguments or passing untypical
144arguments (esp. the wrong types) reduces the efficiency of the
145optimizer. The compiled function will still run, but probably not
146with maximum speed.
147</p>
148<p>
149This library function is typically used for Ahead-Of-Time (AOT)
150compilation of time-critical functions or for testing/debugging.
151</p>
152
153<h3 id="jit_compilesub"><tt>status = jit.compilesub(func|true [,true])</tt></h3>
154<p>
155Recursively compile all subfunctions of a Lua function.
156The current function (the Lua function calling this library function)
157can be specified with <tt>true</tt>. Note that the function
158<em>itself</em> is not compiled (use <tt>jit.compile()</tt>).
159</p>
160<p>
161If the second argument is <tt>true</tt>, compilation will stop
162when the first error is encountered. Otherwise compilation will
163continue with the next subfunction.
164</p>
165<p>
166The returned status is <tt>nil</tt>, if all subfunctions have been
167compiled successfully. A numeric status (see <tt>jit.util.status</tt>)
168indicates that at least one compilation failed and gives the status
169of the last failure (this is only helpful when stop on error
170is <tt>true</tt>).
171</p>
172
173<h3 id="jit_debug"><tt>jit.debug([level])</tt></h3>
174<p>
175Set the debug level for JIT compilation. If no <tt>level</tt> is given,
176the maximum debug level is set.
177</p>
178<ul>
179<li>Level 0 disables debugging: no checks for hooks are compiled
180into the code. This is the default when LuaJIT is started and
181provides the maximum performance.</li>
182<li>Level 1 enables function call debugging: call hooks and
183return hooks are checked in the function prologue and epilogue.
184This slows down function calls somewhat (by up to 10%).</li>
185<li>Level 2 enables full debugging: all hooks are checked.
186This slows down execution quite a bit, even when the hooks
187are not active.</li>
188</ul>
189<p>
190Note that some compiler optimizations are turned off when
191debugging is enabled.
192</p>
193<p>
194This function is typically used with the command line options
195<tt>-j debug</tt> or <tt>-j debug=level</tt>.
196</p>
197
198<h3 id="jit_attach"><tt>jit.attach(handler [, priority])</tt></h3>
199<p>
200Attach a handler to the compiler pipeline with the given priority.
201The handler is detached if no priority is given.
202</p>
203<p>
204The inner workings of the compiler pipeline and the API for handlers
205are still in flux. Please see the source code for more details.
206</p>
207
208<h3 id="jit_version"><tt>jit.version</tt></h3>
209<p>
210Contains the LuaJIT version string.
211</p>
212
213<h3 id="jit_version_num"><tt>jit.version_num</tt></h3>
214<p>
215Contains the version number of the LuaJIT core. Version xx.yy.zz
216is represented by the decimal number xxyyzz.
217</p>
218
219<h3 id="jit_arch"><tt>jit.arch</tt></h3>
220<p>
221Contains the target architecture name (CPU and optional ABI).
222</p>
223
224
225<h2 id="jit_util">The jit.util.* Library</h2>
226<p>
227This library holds many utility functions used by the provided
228extension modules for LuaJIT (e.g. the optimizer). The API may
229change in future versions.
230</p>
231
232<h3 id="jit_util_stats"><tt>stats = jit.util.stats(func)</tt></h3>
233<p>
234Retrieves information about a function. Returns <tt>nil</tt>
235for C functions. Returns a table with the following fields for
236Lua functions:
237</p>
238<ul>
239<li><tt>status</tt>: numeric compilation status (see <tt>jit.util.status</tt>).</li>
240<li><tt>stackslots</tt>: number of stack slots.</li>
241<li><tt>params</tt>: number of fixed parameters (arguments).</li>
242<li><tt>consts</tt>: number of constants.</li>
243<li><tt>upvalues</tt>: number of upvalues.</li>
244<li><tt>subs</tt>: number of subfunctions (sub prototypes).</li>
245<li><tt>bytecodes</tt>: number of bytecode instructions.</li>
246<li><tt>isvararg</tt>: fixarg (false) or vararg (true) function.</li>
247<li><tt>env</tt>: function environment table.</li>
248<li><tt>mcodesize</tt>: size of the compiled machine code.</li>
249<li><tt>mcodeaddr</tt>: start address of the compiled machine code.</li>
250</ul>
251<p>
252<tt>mcodesize</tt> and <tt>mcodeaddr</tt> are not set if the
253function has not been compiled (yet).
254</p>
255
256<h3 id="jit_util_bytecode"><tt>op, a, b, c, test = jit.util.bytecode(func, pc)</tt></h3>
257<p>
258Returns the fields of the bytecode instruction at the given <tt>pc</tt>
259for a Lua function. The first instruction is at <tt>pc</tt> = 1.
260Nothing is returned if <tt>pc</tt> is out of range.
261</p>
262<p>
263The opcode name is returned as an uppercase string in <tt>op</tt>.
264The opcode arguments are returned as <tt>a</tt>, <tt>b</tt> and
265optionally <tt>c</tt>. Arguments that indicate an index into the
266array of constants are translated to negative numbers (the first
267constant is referred to with -1). Branch targets are signed numbers
268relative to the next instruction.
269</p>
270<p>
271<tt>test</tt> is true if the instruction is a test (i.e. followed
272by a JMP).
273</p>
274
275<h3 id="jit_util_const"><tt>const, ok = jit.util.const(func, idx)</tt></h3>
276<p>
277Returns a constant from the array of constants for a Lua function.
278<tt>ok</tt> is true if <tt>idx</tt> is in range. Otherwise nothing
279is returned.
280</p>
281<p>
282Constants are numbered starting with 1. A negative <tt>idx</tt>
283is mapped to a positive index.
284</p>
285
286<h3 id="jit_util_upvalue"><tt>upvalue, ok = jit.util.upvalue(func, idx)</tt></h3>
287<p>
288Returns an upvalue from the array of upvalues for a Lua function.
289<tt>ok</tt> is true if <tt>idx</tt> is in range. Otherwise nothing
290is returned. Upvalues are numbered starting with 0.
291</p>
292
293<h3 id="jit_util_closurenup"><tt>nup = jit.util.closurenup(func, idx)</tt></h3>
294<p>
295Returns the number of upvalues for the subfunction prototype with
296the given index <tt>idx</tt> for a Lua function. Nothing is returned
297if <tt>idx</tt> is out of range. Subfunctions are numbered starting
298with 0.
299</p>
300
301<h3 id="jit_util_mcode"><tt>addr, mcode, mfmiter = jit.util.mcode(func, block])</tt></h3>
302<p>
303Returns the numeric start address, the compiled machine code
304(converted to a string) and an iterator for the machine code fragment map
305for the specified machine code block associated with a Lua function.
306</p>
307<p>
308Returns <tt>nil</tt> and a numeric status code (see <tt>jit.util.status</tt>)
309if the function has not been compiled yet or compilation has failed
310or compilation is disabled. Returns nothing if the selected
311machine code block does not exist.
312</p>
313<p>
314The machine code fragment map is used for debugging and error handling.
315The format may change between versions and is an internal implementation
316detail of LuaJIT.
317</p>
318
319<h3 id="jit_util_jsubmcode"><tt>addr [, mcode] = jit.util.jsubmcode([idx])</tt></h3>
320<p>
321If <tt>idx</tt> is omitted or nil:
322Returns the numeric start address and the compiled machine code
323(converted to a string) for internal subroutines used by the
324compiled machine code.
325</p>
326<p>
327If <tt>idx</tt> is given:
328Returns the numeric start address of the machine code for a specific
329internal subroutine (0&nbsp;based). Nothing is returned if <tt>idx</tt> is
330out of range.
331</p>
332
333<h3 id="jit_util_status"><tt>jit.util.status</tt></h3>
334<p>
335This is a table that bidirectionally maps status numbers and
336status names (strings):
337</p>
338<div class="tablewrap">
339<table>
340<tr class="sthead"><td class="stname">Status Name</td><td>Description</td></tr>
341<tr class="odd"><td class="stname">OK</td><td>Ok, code has been compiled.</td></tr>
342<tr class="even"><td class="stname">NONE</td><td>Nothing analyzed or compiled, yet (default).</td></tr>
343<tr class="odd"><td class="stname">OFF</td><td>Compilation disabled for this function.</td></tr>
344<tr class="even"><td class="stname">ENGINE_OFF</td><td>JIT engine is turned off.</td></tr>
345<tr class="odd"><td class="stname">DELAYED</td><td>Compilation delayed (recursive invocation).</td></tr>
346<tr class="even"><td class="stname">TOOLARGE</td><td>Bytecode or machine code is too large.</td></tr>
347<tr class="odd"><td class="stname">COMPILER_ERROR</td><td>Error from compiler frontend.</td></tr>
348<tr class="even"><td class="stname">DASM_ERROR</td><td>Error from DynASM engine.</td></tr>
349</table>
350</div>
351
352<h3 id="jit_util_hints"><tt>jit.util.hints<br>
353jit.util.fhints</tt></h3>
354<p>
355These two tables map compiler hint names to internal hint numbers.
356</p>
357<p>
358The hint system is an internal implementation detail of LuaJIT.
359Please see the source code for more info.
360</p>
361<br class="flush">
362</div>
363<div id="foot">
364<hr class="hide">
365Copyright &copy; 2005-2011 Mike Pall
366<span class="noprint">
367&middot;
368<a href="contact.html">Contact</a>
369</span>
370</div>
371</body>
372</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_changes.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_changes.html
new file mode 100644
index 0000000..bf42b93
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_changes.html
@@ -0,0 +1,301 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>LuaJIT Change History</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>LuaJIT Change History</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a class="current" href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63This is a list of changes between the released versions of LuaJIT.
64The current version is <strong>LuaJIT&nbsp;1.1.7</strong>.
65</p>
66<p>
67Please check the
68<a href="http://luajit.org/changes.html"><span class="ext">&raquo;</span>&nbsp;Online Change History</a>
69to see whether newer versions are available.
70</p>
71
72<h2 id="LuaJIT-1.1.7">LuaJIT 1.1.7 &mdash; 2011-05-05</h2>
73<ul>
74<li>Added fixes for the
75<a href="http://www.lua.org/bugs.html#5.1.4"><span class="ext">&raquo;</span>&nbsp;currently known bugs in Lua 5.1.4</a>.</li>
76</ul>
77
78<h2 id="LuaJIT-1.1.6">LuaJIT 1.1.6 &mdash; 2010-03-28</h2>
79<ul>
80<li>Added fixes for the
81<a href="http://www.lua.org/bugs.html#5.1.4"><span class="ext">&raquo;</span>&nbsp;currently known bugs in Lua 5.1.4</a>.</li>
82<li>Removed wrong GC check in <tt>jit_createstate()</tt>.
83Thanks to Tim Mensch.</li>
84<li>Fixed bad assertions while compiling <tt>table.insert()</tt> and
85<tt>table.remove()</tt>.</li>
86</ul>
87
88<h2 id="LuaJIT-1.1.5">LuaJIT 1.1.5 &mdash; 2008-10-25</h2>
89<ul>
90<li>Merged with Lua 5.1.4. Fixes all
91<a href="http://www.lua.org/bugs.html#5.1.3"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.3</a>.</li>
92</ul>
93
94<h2 id="LuaJIT-1.1.4">LuaJIT 1.1.4 &mdash; 2008-02-05</h2>
95<ul>
96<li>Merged with Lua 5.1.3. Fixes all
97<a href="http://www.lua.org/bugs.html#5.1.2"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.2</a>.</li>
98<li>Fixed possible (but unlikely) stack corruption while compiling
99<tt>k^x</tt> expressions.</li>
100<li>Fixed DynASM template for cmpss instruction.</li>
101</ul>
102
103<h2 id="LuaJIT-1.1.3">LuaJIT 1.1.3 &mdash; 2007-05-24</h2>
104<ul>
105<li>Merged with Lua 5.1.2. Fixes all
106<a href="http://www.lua.org/bugs.html#5.1.1"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.1</a>.</li>
107<li>Merged pending Lua 5.1.x fixes: "return -nil" bug, spurious count hook call.</li>
108<li>Remove a (sometimes) wrong assertion in <tt>luaJIT_findpc()</tt>.</li>
109<li>DynASM now allows labels for displacements and <tt>.aword</tt>.</li>
110<li>Fix some compiler warnings for DynASM glue (internal API change).</li>
111<li>Correct naming for SSSE3 (temporarily known as SSE4) in DynASM and x86 disassembler.</li>
112<li>The loadable debug modules now handle redirection to stdout
113(e.g. <tt>-j&nbsp;trace=-</tt>).</li>
114</ul>
115
116<h2 id="LuaJIT-1.1.2">LuaJIT 1.1.2 &mdash; 2006-06-24</h2>
117<ul>
118<li>Fix MSVC inline assembly: use only local variables with
119<tt>lua_number2int()</tt>.</li>
120<li>Fix "attempt to call a thread value" bug on Mac OS X:
121make values of consts used as lightuserdata keys unique
122to avoid joining by the compiler/linker.</li>
123</ul>
124
125<h2 id="LuaJIT-1.1.1">LuaJIT 1.1.1 &mdash; 2006-06-20</h2>
126<ul>
127<li>Merged with Lua 5.1.1. Fixes all
128<a href="http://www.lua.org/bugs.html#5.1"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1</a>.</li>
129<li>Enforce (dynamic) linker error for EXE/DLL version mismatches.</li>
130<li>Minor changes to DynASM: faster preprocessing, smaller encoding
131for some immediates.</li>
132</ul>
133<p>
134This release is in sync with Coco 1.1.1 (see the
135<a href="coco_changes.html">Coco Change History</a>).
136</p>
137
138<h2 id="LuaJIT-1.1.0">LuaJIT 1.1.0 &mdash; 2006-03-13</h2>
139<ul>
140<li>Merged with Lua 5.1 (final).</li>
141
142<li>New JIT call frame setup:
143<ul>
144<li>The C stack is kept 16 byte aligned (faster).
145Mandatory for Mac OS X on Intel, too.</li>
146<li>Faster calling conventions for internal C helper functions.</li>
147<li>Better instruction scheduling for function prologue, OP_CALL and
148OP_RETURN.</li>
149</ul></li>
150
151<li>Miscellaneous optimizations:
152<ul>
153<li>Faster loads of FP constants. Remove narrow-to-wide store-to-load
154forwarding stalls.</li>
155<li>Use (scalar) SSE2 ops (if the CPU supports it) to speed up slot moves
156and FP to integer conversions.</li>
157<li>Optimized the two-argument form of <tt>OP_CONCAT</tt> (<tt>a..b</tt>).</li>
158<li>Inlined <tt>OP_MOD</tt> (<tt>a%b</tt>).
159With better accuracy than the C variant, too.</li>
160<li>Inlined <tt>OP_POW</tt> (<tt>a^b</tt>). Unroll <tt>x^k</tt> or
161use <tt>k^x = 2^(log2(k)*x)</tt> or call <tt>pow()</tt>.</li>
162</ul></li>
163
164<li>Changes in the optimizer:
165<ul>
166<li>Improved hinting for table keys derived from table values
167(<tt>t1[t2[x]]</tt>).</li>
168<li>Lookup hinting now works with arbitrary object types and
169supports index chains, too.</li>
170<li>Generate type hints for arithmetic and comparison operators,
171OP_LEN, OP_CONCAT and OP_FORPREP.</li>
172<li>Remove several hint definitions in favour of a generic COMBINE hint.</li>
173<li>Complete rewrite of <tt>jit.opt_inline</tt> module
174(ex <tt>jit.opt_lib</tt>).</li>
175</ul></li>
176
177<li>Use adaptive deoptimization:
178<ul>
179<li>If runtime verification of a contract fails, the affected
180instruction is recompiled and patched on-the-fly.
181Regular programs will trigger deoptimization only occasionally.</li>
182<li>This avoids generating code for uncommon fallback cases
183most of the time. Generated code is up to 30% smaller compared to
184LuaJIT&nbsp;1.0.3.</li>
185<li>Deoptimization is used for many opcodes and contracts:
186<ul>
187<li>OP_CALL, OP_TAILCALL: type mismatch for callable.</li>
188<li>Inlined calls: closure mismatch, parameter number and type mismatches.</li>
189<li>OP_GETTABLE, OP_SETTABLE: table or key type and range mismatches.</li>
190<li>All arithmetic and comparison operators, OP_LEN, OP_CONCAT,
191OP_FORPREP: operand type and range mismatches.</li>
192</ul></li>
193<li>Complete redesign of the debug and traceback info
194(bytecode &harr; mcode) to support deoptimization.
195Much more flexible and needs only 50% of the space.</li>
196<li>The modules <tt>jit.trace</tt>, <tt>jit.dumphints</tt> and
197<tt>jit.dump</tt> handle deoptimization.</li>
198</ul></li>
199
200<li>Inlined many popular library functions
201(for commonly used arguments only):
202<ul>
203<li>Most <tt>math.*</tt> functions (the 18 most used ones)
204[2x-10x faster].</li>
205<li><tt>string.len</tt>, <tt>string.sub</tt> and <tt>string.char</tt>
206[2x-10x faster].</li>
207<li><tt>table.insert</tt>, <tt>table.remove</tt> and <tt>table.getn</tt>
208[3x-5x faster].</li>
209<li><tt>coroutine.yield</tt> and <tt>coroutine.resume</tt>
210[3x-5x faster].</li>
211<li><tt>pairs</tt>, <tt>ipairs</tt> and the corresponding iterators
212[8x-15x faster].</li>
213</ul></li>
214
215<li>Changes in the core and loadable modules and the stand-alone executable:
216<ul>
217<li>Added <tt>jit.version</tt>, <tt>jit.version_num</tt>
218and <tt>jit.arch</tt>.</li>
219<li>Reorganized some internal API functions (<tt>jit.util.*mcode*</tt>).</li>
220<li>The <tt>-j dump</tt> output now shows JSUB names, too.</li>
221<li>New x86 disassembler module written in pure Lua. No dependency
222on ndisasm anymore. Flexible API, very compact (500 lines)
223and complete (x87, MMX, SSE, SSE2, SSE3, SSSE3, privileged instructions).</li>
224<li><tt>luajit -v</tt> prints the LuaJIT version and copyright
225on a separate line.</li>
226</ul></li>
227
228<li>Added SSE, SSE2, SSE3 and SSSE3 support to DynASM.</li>
229<li>Miscellaneous doc changes. Added a section about
230<a href="luajit_install.html#embedding">embedding LuaJIT</a>.</li>
231</ul>
232<p>
233This release is in sync with Coco 1.1.0 (see the
234<a href="coco_changes.html">Coco Change History</a>).
235</p>
236
237<h2 id="LuaJIT-1.0.3">LuaJIT 1.0.3 &mdash; 2005-09-08</h2>
238<ul>
239<li>Even more docs.</li>
240<li>Unified closure checks in <tt>jit.*</tt>.</li>
241<li>Fixed some range checks in <tt>jit.util.*</tt>.</li>
242<li>Fixed __newindex call originating from <tt>jit_settable_str()</tt>.</li>
243<li>Merged with Lua 5.1 alpha (including early bugfixes).</li>
244</ul>
245<p>
246This is the first public release of LuaJIT.
247</p>
248
249<h2 id="LuaJIT-1.0.2">LuaJIT 1.0.2 &mdash; 2005-09-02</h2>
250<ul>
251<li>Add support for flushing the Valgrind translation cache <br>
252(<tt>MYCFLAGS= -DUSE_VALGRIND</tt>).</li>
253<li>Add support for freeing executable mcode memory to the <tt>mmap()</tt>-based
254variant for POSIX systems.</li>
255<li>Reorganized the C&nbsp;function signature handling in
256<tt>jit.opt_lib</tt>.</li>
257<li>Changed to index-based hints for inlining C&nbsp;functions.
258Still no support in the backend for inlining.</li>
259<li>Hardcode <tt>HEAP_CREATE_ENABLE_EXECUTE</tt> value if undefined.</li>
260<li>Misc. changes to the <tt>jit.*</tt> modules.</li>
261<li>Misc. changes to the Makefiles.</li>
262<li>Lots of new docs.</li>
263<li>Complete doc reorg.</li>
264</ul>
265<p>
266Not released because Lua 5.1 alpha came out today.
267</p>
268
269<h2 id="LuaJIT-1.0.1">LuaJIT 1.0.1 &mdash; 2005-08-31</h2>
270<ul>
271<li>Missing GC step in <tt>OP_CONCAT</tt>.</li>
272<li>Fix result handling for C &ndash;> JIT calls.</li>
273<li>Detect CPU feature bits.</li>
274<li>Encode conditional moves (<tt>fucomip</tt>) only when supported.</li>
275<li>Add fallback instructions for FP compares.</li>
276<li>Add support for <tt>LUA_COMPAT_VARARG</tt>. Still disabled by default.</li>
277<li>MSVC needs a specific place for the <tt>CALLBACK</tt> attribute
278(David Burgess).</li>
279<li>Misc. doc updates.</li>
280</ul>
281<p>
282Interim non-public release.
283Special thanks to Adam D. Moss for reporting most of the bugs.
284</p>
285
286<h2 id="LuaJIT-1.0.0">LuaJIT 1.0.0 &mdash; 2005-08-29</h2>
287<p>
288This is the initial non-public release of LuaJIT.
289</p>
290<br class="flush">
291</div>
292<div id="foot">
293<hr class="hide">
294Copyright &copy; 2005-2011 Mike Pall
295<span class="noprint">
296&middot;
297<a href="contact.html">Contact</a>
298</span>
299</div>
300</body>
301</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_debug.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_debug.html
new file mode 100644
index 0000000..95d5565
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_debug.html
@@ -0,0 +1,273 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Debugging LuaJIT</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Debugging LuaJIT</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a class="current" href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63LuaJIT is a rather complex application. There will undoubtedly
64be bugs lurking in there. You have been warned. :-)
65</p>
66<p>
67If you came here looking for information on how to debug
68<em>your application</em> (and not LuaJIT itself) then please
69check out <a href="luajit_api.html#jit_debug"><tt>jit.debug()</tt></a>
70and the <a href="luajit_run.html#j_debug"><tt>-j debug</tt></a>
71command line option.
72</p>
73<p>
74But if you suspect a problem with LuaJIT itself, then try
75any of the following suggestions (in order).
76</p>
77
78<h2>Is LuaJIT the Problem?</h2>
79<p>
80Try to run your application in several different ways:
81</p>
82<ul>
83<li><tt>luajit app.lua</tt></li>
84<li><tt>luajit -O1 app.lua</tt></li>
85<li><tt>luajit -O app.lua</tt></li>
86<li><tt>luajit -j off app.lua</tt></li>
87<li><tt>lua app.lua</tt> (i.e. with standard Lua)</li>
88</ul>
89<p>
90If the behaviour is the <em>same</em> as with standard Lua then ...
91well ... that's what LuaJIT is about: doing the same things,
92just faster. Even bugs fly faster. :-)
93</p>
94<p>
95So this is most likely a bug in your application then. It may be easier
96to debug this with plain Lua &mdash; the remainder of this page
97is probably not helpful for you.
98</p>
99<p>
100But if the behaviour is <em>different</em>, there is some likelihood
101that you caught a bug in LuaJIT. Oh dear ...
102</p>
103<p>
104Ok, so don't just give up. Please read on and help the community
105by finding the bug. Thank you!
106</p>
107
108<h2>Get the Latest Version</h2>
109<p>
110Number one on your list of things to check is the
111<a href="http://luajit.org/luajit_changes.html"><span class="ext">&raquo;</span>&nbsp;Online Change History</a>.
112</p>
113<p>
114Please check if a newer version is available. Maybe the bug
115you have encountered has been fixed already. Always download the
116latest version and try it with your application before continuing.
117</p>
118
119<h2>Reproduce the Bug</h2>
120<p>
121First try to make the bug reproducible. Try to isolate the module
122and the function the bug occurs in:
123</p>
124<p>
125Either selectively turn off compilation for some modules with<br>
126<tt>&nbsp;&nbsp;jit.off(true, true)</tt><br>
127until the bug disappears ...
128</p>
129<p>
130And/or turn the whole JIT engine off and selectively compile
131functions with<br>
132<tt>&nbsp;&nbsp;jit.compile(func)</tt><br>
133until it reappears.
134</p>
135<p>
136If you have isolated the point where it happens, it's most helpful
137to reduce the affected Lua code to a short code snippet that
138still shows the problem. You may need to <tt>print()</tt> some
139variables until you can pinpoint the exact spot where it happens.
140</p>
141<p>
142If you've got a <em>reproducible</em> and <em>short</em> test
143you can either send it directly to me or the mailing list
144(see the <a href="contact.html">Contact Information</a>)
145or you can try to debug this a bit further.
146</p>
147<p>
148Well &mdash; if you are brave enough. :-)
149</p>
150
151<h2>Look at the Generated Code</h2>
152<p>
153You may want to have a look at the output of <tt>-j dumphints</tt>
154first. Try to change things around until you can see which hint
155or which instruction is the cause of the bug. If you suspect
156an optimizer bug then have a look at the backend (<tt>*.das[ch]</tt>)
157and check how the hint is encoded.
158</p>
159<p>
160Otherwise have a look at <tt>-j dump</tt> and see whether
161you can spot the problem around the affected instruction.
162It's helpful to have a good knowledge of assembler, though
163(sorry).
164</p>
165
166<h2>Locate a Crash</h2>
167<p>
168If you get a crash, you should compile LuaJIT with debugging
169turned on:
170</p>
171<p>
172Add <tt>-g</tt> to <tt>CFLAGS</tt> and <tt>MYLDFLAGS</tt>
173or whatever is needed to turn on debugging. For Windows you
174need both an executable and a DLL built with debugging.
175</p>
176<p>
177Then start LuaJIT with your debugger. Run it with
178<tt>-j dump=test.dump</tt>.
179</p>
180<p>
181Have a look at the backtrace and compare it with the generated
182dump file to find out exactly where it crashes. I'm sorry, but
183symbols or instructions for JIT compiled functions are not
184displayed in your debugger (this is really hard to solve).
185</p>
186
187<h2>Turn on Assertions</h2>
188<p>
189Another way to debug LuaJIT is to turn on assertions.
190They can be turned on only for the JIT engine by adding
191<tt>-DLUAJIT_ASSERT</tt> to <tt>JITCFLAGS</tt> in <tt>src/Makefile</tt>.
192Then recompile with <tt>make&nbsp;clean</tt> and <tt>make</tt>.
193</p>
194<p>
195Add these two lines to <tt>src/luaconf.h</tt> to turn on all assertions in the Lua core:<br>
196<tt>&nbsp;&nbsp;#include &lt;assert.h&gt;</tt><br>
197<tt>&nbsp;&nbsp;#define lua_assert(x) assert(x)</tt><br>
198This turns on the JIT engine assertions, too.
199Recompile and see whether any assertions trigger.
200Don't forget to turn off the (slow) assertions when you're done!
201</p>
202
203<h2>Use Valgrind</h2>
204<p>
205A tremendously useful (and free) tool for runtime code analysis
206is <a href="http://valgrind.org/"><span class="ext">&raquo;</span>&nbsp;Valgrind</a>. Regularly
207run your applications with <tt>valgrind --memcheck</tt> and
208your life will be better.
209</p>
210<p>
211To run LuaJIT under Valgrind you <em>must</em> add
212<tt>-DUSE_VALGRIND</tt> to <tt>MYCFLAGS</tt>
213and recompile LuaJIT. You will get random errors if you don't!
214Valgrind 3.x or later is required. Earlier versions
215do not work well with newly allocated C stacks.
216</p>
217<p>
218An executable built with this option runs fine without Valgrind
219and without a performance loss. But it needs the Valgrind header
220files for compilation (which is why it's not enabled by default).
221</p>
222<p>
223It's helpful to compile LuaJIT with debugging turned on, too
224(see above).
225</p>
226<p>
227If Valgrind spots many invalid memory accesses that involve
228memory allocation/free functions you've probably found a bug
229related to garbage collection. Some object reference must have
230gone astray.
231</p>
232<p>
233Try to find out which object is disappearing. You can force
234eager garbage collection with repeated calls to
235<tt>collectgarbage()</tt> or by setting a very low threshold
236with <tt>collectgarbage("setpause", 1)</tt>.
237</p>
238
239<h2>Don't Despair</h2>
240<p>
241If all of this doesn't help to find the bug, please send
242a summary of your findings to the mailing list. Describe as much
243of the circumstances you think are relevant.
244</p>
245<p>
246Please <em>don't</em> send your whole application to me
247(without asking first) and especially not to the mailing list.
248Code snippets should preferrably be less than 50 lines and
249up to the point.
250</p>
251<p>
252All bug reports are helpful, even if no immediate solution
253is available. Often enough someone else finds the same bug
254in a different setting and together with your bug report
255this may help to track it down.
256</p>
257<p>
258Finally I have to say a <strong>BIG THANK YOU</strong>
259to everyone who has helped to make LuaJIT better by finding
260and fixing bugs!
261</p>
262<br class="flush">
263</div>
264<div id="foot">
265<hr class="hide">
266Copyright &copy; 2005-2011 Mike Pall
267<span class="noprint">
268&middot;
269<a href="contact.html">Contact</a>
270</span>
271</div>
272</body>
273</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_features.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_features.html
new file mode 100644
index 0000000..b4e896f
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_features.html
@@ -0,0 +1,226 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>LuaJIT Features</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>LuaJIT Features</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a class="current" href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63LuaJIT tries to keep the spirit of Lua &mdash; it's <em>light-weight</em>,
64<em>efficient</em> and <em>extensible</em>.
65</p>
66
67<h2>Features</h2>
68<p>
69All functions are by default compiled Just-In-Time (JIT) to
70machine code:
71</p>
72<ul>
73<li>Functions that are unused are not compiled at all.</li>
74<li>Compilation can be enabled/disabled selectively for individual
75functions and subfunctions or even whole modules.</li>
76<li>Interpreted and compiled functions can be freely mixed.</li>
77</ul>
78<p>
79Ahead-Of-Time (AOT) compilation (at runtime) is supported, too:
80</p>
81<ul>
82<li>A number of API functions and command line options allows
83full user control over the compilation process.</li>
84</ul>
85<p>
86The JIT compiler is extensible:
87</p>
88<ul>
89<li>The optimizer is an extra module that attaches to the compiler
90pipeline.</li>
91<li>Various modules provide trace and debug information about
92the compilation process.</li>
93<li>All of these features can be activated with command line options.</li>
94</ul>
95
96<h2>Performance</h2>
97<p>
98The compiled machine code is <em>very efficient</em>:
99</p>
100<ul>
101<li>Have a look at some
102<a href="luajit_performance.html">Performance Measurements</a>.</li>
103<li>Aggressive optimizations (specialization, inlining) are enabled
104wherever possible. Inlined contracts catch wrong optimizer predictions
105at runtime (undetected polymorphism).</li>
106<li>Adaptive deoptimization is used to recompile individual bytecode
107instructions with broken contracts. This avoids generating code for the
108generic fallback cases most of the time (faster compilation, reduced
109I-cache contention).</li>
110<li>Special CPU features (such as conditional moves or SSE2)
111are automatically used when detected.</li>
112</ul>
113<p>
114The JIT compiler is <em>very fast</em>:
115</p>
116<ul>
117<li>Compilation times vary a great deal (depending on the nature of
118the function to be compiled) but are generally in the
119<em>microsecond</em> range.</li>
120<li>Even compiling large functions (hundreds of lines) with the
121maximum optimization level takes only a few milliseconds in the
122worst case.</li>
123</ul>
124<p>
125LuaJIT is <em>very small</em>:
126</p>
127<ul>
128<li>The whole JIT compiler engine adds only around <strong>32K</strong>
129of code to the Lua core (if compiled with <tt>-Os</tt>).</li>
130<li>The optimizer is split into several optional modules that
131can be loaded at runtime if requested.</li>
132<li>LuaJIT adds around 6.000 lines of C and assembler code and
1332.000 lines of Lua code to the Lua 5.1 core (17.000 lines of C).</li>
134<li>Required build tools (<a href="dynasm.html">DynASM</a>)
135take another 2.500 lines of Lua code.</li>
136</ul>
137
138<h2>Compatibility</h2>
139<p>
140LuaJIT is designed to be <em>fully compatible</em> with Lua 5.1.
141It accepts the same source code and/or precompiled bytecode.
142It supports all standard language semantics. In particular:
143</p>
144<ul>
145<li>All standard types, operators and metamethods are supported.</li>
146<li>Implicit type coercions (number/string) work as expected.</li>
147<li>Full IEEE-754 semantics for floating point arithmetics
148(NaN, +-Inf, +-0, ...).</li>
149<li>Full support for lexical closures.
150Proper tail calls do not consume a call frame.</li>
151<li>Exceptions are precise. Backtraces work fine.</li>
152<li>Coroutines are supported with the help of <a href="coco.html">Coco</a>.</li>
153<li>No changes to the Lua 5.1 incremental garbage collector.</li>
154<li>No changes to the standard Lua/C API.</li>
155<li>Dynamically loaded C modules are link compatible with Lua 5.1
156(same ABI).</li>
157<li>LuaJIT can be <a href="luajit_install.html#embedding">embedded</a>
158into an application just like Lua.</li>
159</ul>
160<p>
161Some minor differences are related to debugging:
162</p>
163<ul>
164<li>Debug hooks are only called if debug code generation is enabled.</li>
165<li>There is no support for tailcall counting in JIT compiled code.
166HOOKTAILRET is not called, too. Note: this won't affect you unless
167you are writing a Lua debugger. <sup>*</sup></li>
168</ul>
169<p style="font-size: 80%;">
170<sup>*</sup> There is not much I can do to improve this situation without undue
171complications. A suggestion to modify the behaviour of standard Lua
172has been made on the mailing list (it would be beneficial there, too).
173</p>
174
175<h2>Restrictions</h2>
176<ul>
177<li>Only x86 (i386+) CPUs are supported right now (but see below).</li>
178<li>Only the default type for <tt>lua_Number</tt> is supported
179(<tt>double</tt>).</li>
180<li>The interrupt signal (Ctrl-C) is ignored unless you enable
181debug hooks (with <tt>-j debug</tt>). But this will seriously
182slow down your application. I'm looking for better ways to handle
183this. In the meantime you have to press Ctrl-C twice to interrupt
184a currently running JIT compiled function (just like C functions).</li>
185<li>GDB, Valgrind and other debugging tools can't report symbols
186or stack frames for JIT compiled code. This is rather difficult to solve.
187Have a look at <a href="luajit_debug.html">Debugging LuaJIT</a>, too.</li>
188</ul>
189
190<h2>Caveats</h2>
191<ul>
192<li>LuaJIT allocates executable memory for the generated machine code
193if your OS has support for it: either <tt>HeapCreate()</tt> for Windows or
194<tt>mmap()</tt> on POSIX systems.<br>
195The fallback is the standard Lua allocator (i.e. malloc()).
196But this usually means the allocated memory is not marked executable.
197Running compiled code will trap on CPUs/OS with the NX (No eXecute)
198extension <em>if you can only use the fallback</em>.</li>
199<li><a href="dynasm.html">DynASM</a> is needed to regenerate the
200<tt>ljit_x86.h</tt> file. But only in case you want to <em>modify</em>
201the <tt>*.dasc</tt>/<tt>*.dash</tt> files. A pre-processed <tt>*.h</tt>
202file is supplied with LuaJIT.<br>
203DynASM is written in Lua and needs a plain copy of Lua 5.1
204(installed as <tt>lua</tt>). Or you can run it with LuaJIT built from
205the <tt>*.h</tt> file supplied with the distribution (modify
206<tt>DASM=</tt> in <tt>src/Makefile</tt>). It's a good idea to install
207a known good copy of LuaJIT under a different name for this.</li>
208<li>LuaJIT ships with <tt>LUA_COMPAT_VARARG</tt> turned off.
209I.e. the implicit <tt>arg</tt> parameter is not created anymore.
210Please have a look at the comments in <tt>luaconf.h</tt> for
211this configuration option. You can turn it on, if you really need it.
212Or better yet, convert your code to the new Lua 5.1 vararg syntax.</li>
213</ul>
214
215<br class="flush">
216</div>
217<div id="foot">
218<hr class="hide">
219Copyright &copy; 2005-2011 Mike Pall
220<span class="noprint">
221&middot;
222<a href="contact.html">Contact</a>
223</span>
224</div>
225</body>
226</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_install.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_install.html
new file mode 100644
index 0000000..bc5a3cd
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_install.html
@@ -0,0 +1,340 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Installing LuaJIT</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.build {
13 line-height: 1.2;
14}
15td.buildsys {
16 width: 11em;
17}
18td.buildcmd {
19 width: 10em;
20 font-family: Courier New, Courier, monospace;
21}
22tr.buildhead td {
23 /* font-family: inherit; ... not supported in IE *sigh* */
24 font-family: Verdana, Arial, Helvetica, sans-serif;
25 font-weight: bold;
26}
27</style>
28</head>
29<body>
30<div id="site">
31<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
32</div>
33<div id="head">
34<h1>Installing LuaJIT</h1>
35</div>
36<div id="nav">
37<ul><li>
38<a href="index.html">Index</a>
39</li><li>
40<a href="luajit.html">LuaJIT</a>
41<ul><li>
42<a href="luajit_features.html">Features</a>
43</li><li>
44<a class="current" href="luajit_install.html">Installation</a>
45</li><li>
46<a href="luajit_run.html">Running</a>
47</li><li>
48<a href="luajit_api.html">API Extensions</a>
49</li><li>
50<a href="luajit_intro.html">Introduction</a>
51</li><li>
52<a href="luajit_performance.html">Performance</a>
53</li><li>
54<a href="luajit_debug.html">Debugging</a>
55</li><li>
56<a href="luajit_changes.html">Changes</a>
57</li></ul>
58</li><li>
59<a href="coco.html">Coco</a>
60<ul><li>
61<a href="coco_portability.html">Portability</a>
62</li><li>
63<a href="coco_api.html">API Extensions</a>
64</li><li>
65<a href="coco_changes.html">Changes</a>
66</li></ul>
67</li><li>
68<a href="dynasm.html">DynASM</a>
69<ul><li>
70<a href="dynasm_features.html">Features</a>
71</li><li>
72<a href="dynasm_examples.html">Examples</a>
73</li></ul>
74</li><li>
75<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
76</li></ul>
77</div>
78<div id="main">
79<p>
80LuaJIT is not much more difficult to install than Lua itself.
81Just unpack the distribution file, change into the newly created
82directory and follow the instructions below.
83</p>
84<p class="indent">
85For the impatient: <b><tt>make&nbsp;linux&nbsp;&amp;&amp;&nbsp;sudo&nbsp;make&nbsp;install</tt></b><br>
86Replace <tt>linux</tt> with e.g. <tt>bsd</tt> or <tt>macosx</tt> depending on your OS.
87</p>
88<p>
89In case you've missed this in <a href="luajit_features.html">Features</a>:
90LuaJIT only works on x86 (i386+) systems right now. Support for
91other architectures may be added in future versions.
92</p>
93
94<h2>Configuring LuaJIT</h2>
95<p>
96LuaJIT is (deliberately) <em>not</em> autoconfigured &mdash; the
97defaults should work fine on most systems. But please check the
98system-specific instructions below.
99</p>
100<p>
101The following three files hold all configuration information:
102</p>
103<ul>
104<li><tt>Makefile</tt> holds settings for installing LuaJIT.</li>
105<li><tt>src/Makefile</tt> holds settings for compiling LuaJIT.</li>
106<li><tt>src/luaconf.h</tt> sets a multitude of configuration
107variables.</li>
108</ul>
109<p>
110If this is your first build then it's better not to give into
111the temptation to tweak every little setting. The standard
112configuration provides sensible defaults (IMHO).
113</p>
114<p>
115One particular setting you might want to change is the installation
116path. Note that you need to modify both the top-level <tt>Makefile</tt>
117and <tt>src/luaconf.h</tt> (right at the start) to take
118effect.
119</p>
120<p>
121If you have trouble getting Coco to work, you can disable it by
122uncommenting the <tt>COCOFLAGS= -DCOCO_DISABLE</tt> line in
123<tt>src/Makefile</tt>. But note that this effectively disables
124yielding from coroutines for JIT compiled functions.
125</p>
126<p>
127A few more settings need to be changed if you want to
128<a href="luajit_debug.html">Debug LuaJIT</a> <em>itself</em>.
129Application debugging can be turned on/off at runtime.
130</p>
131
132<h3>Upgrading From Previous Versions</h3>
133<p>
134It's important to keep the LuaJIT core and the add-on modules in sync.
135Be sure to delete any old versions of LuaJIT modules from the
136Lua module search path (check the current directory, too!).
137</p>
138<p>
139Lua files compiled to bytecode may be incompatible if the underlying
140Lua core has changed (like from Lua&nbsp;5.1 alpha to Lua&nbsp;5.1
141final between LuaJIT&nbsp;1.0.3 and LuaJIT&nbsp;1.1.0). The same
142applies to any
143<a href="http://lua-users.org/wiki/BuildingModules"><span class="ext">&raquo;</span>&nbsp;loadable C modules</a>
144(shared libraries, DLLs) which need to be recompiled with the new
145Lua header files.
146</p>
147<p>
148Compiled bytecode and loadable C modules are fully compatible and
149can be freely exchanged between LuaJIT and the <em>same</em>
150version of Lua it is based on. Please verify that <tt>LUA_RELEASE</tt>
151in <tt>src/lua.h</tt> is the same in both distributions.
152</p>
153
154<h2>Building LuaJIT</h2>
155
156<h3>Makefile Targets</h3>
157<p>
158The Makefiles have a number of targets for various operating systems:
159</p>
160
161<div class="tablewrap">
162<table class="build">
163<tr class="buildhead"><td class="buildsys">System</td><td class="buildcmd">Build Command</td><td>Notes</td></tr>
164<tr class="odd"><td class="buildsys">Linux i386</td><td class="buildcmd">make linux</td><td></td></tr>
165<tr class="even"><td class="buildsys">BSD i386</td><td class="buildcmd">make bsd</td><td>FreeBSD, NetBSD or OpenBSD</td></tr>
166<tr class="odd"><td class="buildsys">Mac OS X on Intel</td><td class="buildcmd">make macosx</td><td>Check <tt>src/Makefile</tt> for OS X &lt; 10.4</td></tr>
167<tr class="even"><td class="buildsys">Solaris x86</td><td class="buildcmd">make solaris</td><td>GCC only, SunCC miscompiles LuaJIT</td></tr>
168<tr class="odd"><td class="buildsys">MinGW (Win32)</td><td class="buildcmd">make mingw</td><td>cross-MinGW: must be 1st in PATH</td></tr>
169<tr class="even"><td class="buildsys">Cygwin</td><td class="buildcmd">make cygwin</td><td></td></tr>
170<tr class="odd"><td class="buildsys">POSIX on x86</td><td class="buildcmd">make posix</td><td>Check <a href="coco_portability.html">Portability Req. for Coco</a>, too</td></tr>
171<tr class="even"><td class="buildsys">Generic x86</td><td class="buildcmd">make generic</td><td>Check <a href="coco_portability.html">Portability Req. for Coco</a>, too</td></tr>
172</table>
173</div>
174
175<p>
176You may want to enable interactive line editing for the stand-alone
177executable. There are extra targets for Linux, BSD and Mac OS X:
178<tt>make&nbsp;linux_rl</tt>, <tt>make&nbsp;bsd_rl</tt>
179and <tt>make&nbsp;macosx_rl</tt>.
180</p>
181
182<h3>MSVC (Win32)</h3>
183<p>
184First check out <tt>etc\luavs.bat</tt> if it suits your needs. Then try
185running it from the MSVC command prompt (start it from the toplevel directory).
186</p>
187<p>
188Another option is to set up your own MSVC project:
189</p>
190<p>
191Change to the <tt>src</tt> directory
192and create a new DLL project for <tt>lua51.dll</tt>.
193Add all C files to it except for <tt>lua.c</tt>, <tt>luac.c</tt>
194and <tt>print.c</tt>. Add the <tt>..\dynasm</tt> directory
195to the include path and build the DLL.
196</p>
197<p>
198Next create a new EXE project for <tt>luajit.exe</tt>.
199Add <tt>lua.c</tt> to it and link with the import library
200<tt>lua51.lib</tt> created for <tt>lua51.dll</tt>. Build
201the executable.
202</p>
203
204<h2>Installation</h2>
205
206<h3>POSIX systems</h3>
207<p>
208Run <tt>make&nbsp;install</tt> from the top-level directory.
209You probably need to be the root user before doing so, i.e. use
210<tt>sudo&nbsp;make&nbsp;install</tt> or <tt>su&nbsp;-&nbsp;root</tt>
211before the <tt>make&nbsp;install</tt>.
212</p>
213<p>
214By default this installs only:<br>
215<tt>&nbsp;&nbsp;/usr/local/bin/<strong>luajit</strong></tt> &mdash; The stand-alone executable.<br>
216<tt>&nbsp;&nbsp;/usr/local/lib/lua/5.1</tt> &mdash; C module directory.<br>
217<tt>&nbsp;&nbsp;/usr/local/share/lua/5.1</tt> &mdash; Lua module directory.<br>
218<tt>&nbsp;&nbsp;/usr/local/share/lua/5.1/<strong>jit/*.lua</strong></tt> &mdash;
219<tt>jit.*</tt> modules.<br>
220</p>
221<p>
222The Lua docs and includes are not installed to avoid overwriting
223an existing Lua installation. In any case these are identical
224to the version of Lua that LuaJIT is based on. If you want
225to install them, edit the top-level makefile (look for <tt>###</tt>).
226</p>
227<p>
228The stand-alone Lua bytecode compiler <tt>luac</tt> is neither
229built nor installed, for the same reason. If you really need it,
230you may be better off with <tt>luac</tt> built from the original Lua
231distribution (use the <em>same</em> version your copy of LuaJIT
232is based on). This avoids dragging in most of LuaJIT which is not
233needed for the pure bytecode compiler. You can also use the bare-bones
234Lua to bytecode translator <tt>luac.lua</tt> (look in the <tt>test</tt>
235directory of the original Lua distribution).
236</p>
237
238<h3>Windows</h3>
239<p>
240Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt>
241to a newly created directory (any location is ok). Add <tt>lua</tt>
242and <tt>lua\jit</tt> directories below it and copy all Lua files
243from the <tt>jit</tt> directory of the distribution to the latter directory.
244</p>
245<p>
246There are no hardcoded
247absolute path names &mdash; all modules are loaded relative to the
248directory where <tt>luajit.exe</tt> is installed
249(see <tt>src/luaconf.h</tt>).
250</p>
251
252<h2 id="embedding">Embedding LuaJIT</h2>
253<p>
254It's strongly recommended that you build the stand-alone executable
255with your toolchain and verify that it works <em>before</em> starting
256to embed LuaJIT into an application. The stand-alone executable is
257also useful later on, when you want to experiment with code snippets
258or try out some Lua files.
259</p>
260<p>
261Please consult the Lua docs for general information about how to
262embed Lua into your application. The following list only shows
263the additional steps needed for embedding LuaJIT:
264</p>
265<ul>
266<li>You need to add the LuaJIT library functions by running
267<tt>luaopen_jit()</tt> after all the other standard library functions.
268The modified <tt>src/linit.c</tt> used by the stand-alone executable
269already does this for you.</li>
270<li><em>Caveat:</em> LuaJIT is based on Lua 5.1 which
271means the <tt>luaopen_*()</tt> functions <em>must not</em>
272be called directly. See <tt>src/linit.c</tt> for the proper way to
273run them. You'll get an error initializing the <tt>io</tt> library
274if you don't follow these instructions.</li>
275<li>To use the optimizer (strongly recommended) you need to:
276<ul>
277<li>Install the optimizer modules <tt>jit.opt</tt> and
278<tt>jit.opt_inline</tt> relative to the Lua module path
279(you've probably modified it &mdash; see <tt>src/luaconf.h</tt>):<br>
280<tt>jit/opt.lua</tt><br>
281<tt>jit/opt_inline.lua</tt></li>
282<li>If you want to ship a single executable then you may want to
283embed the optimizer modules into your application (but don't loose
284time with this during the early development phase). This involves:
285<ul>
286<li>Compile the two modules to bytecode
287(using <tt>luac&nbsp;-s</tt> from a plain Lua installation).</li>
288<li>Convert them to C include files (search for "Lua&nbsp;bin2c").</li>
289<li>On Windows you can also put the compiled bytecode into a resource
290(search for "Lua&nbsp;bin2res").</li>
291<li>Load the bytecode with <tt>luaL_loadbuffer</tt> (but don't run it).</li>
292<li>Put the resulting functions into <tt>package.preload["jit.opt"]</tt>
293and <tt>package.preload["jit.opt_inline"]</tt>.</li>
294</ul></li>
295<li>Activate the LuaJIT optimizer from Lua code to be run at startup:
296<tt>&nbsp;&nbsp;require("jit.opt").start()</tt><br>
297Or use equivalent C code. See <tt>dojitopt()</tt> in <tt>src/lua.c</tt>.</li>
298</ul></li>
299<li>All other LuaJIT specific modules (<tt>jit.*</tt>) are for debugging only.
300They do not need to be shipped with an application. But they may be quite
301useful, anyway (especially <tt>jit.trace</tt>).</li>
302<li>DynASM is only needed while <em>building</em> LuaJIT. It's not
303needed while running LuaJIT and there is no point in shipping or
304installing it together with an application.</li>
305<li>In case you want to strip some of the standard libraries from
306your application: The optimizer modules need several functions from
307the base library and the string library (and of course the LuaJIT
308core libraries). The io library is only used to print a fatal error
309message (you may want to replace it). The optional modules
310for debugging depend on a few more library functions &mdash;
311please check the source.</li>
312</ul>
313<p>
314Although the very liberal LuaJIT
315<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;license</a>
316does not require any acknowledgment whatsoever, it would be appreciated
317if you give some credit in the docs (or the "About" box) of your application.
318A simple line like:<br>
319<tt>&nbsp;&nbsp;This product includes LuaJIT, http://luajit.org/</tt><br>
320would be nice. Please do not include any E-Mail addresses. Thank you!
321</p>
322<p>
323I'm always interested where LuaJIT can be put to good use in applications.
324Please <a href="contact.html">tell me</a>
325or better yet write a few lines about your project to the
326<a href="http://www.lua.org/lua-l.html"><span class="ext">&raquo;</span>&nbsp;Lua mailing list</a>.
327Thank you!
328</p>
329<br class="flush">
330</div>
331<div id="foot">
332<hr class="hide">
333Copyright &copy; 2005-2011 Mike Pall
334<span class="noprint">
335&middot;
336<a href="contact.html">Contact</a>
337</span>
338</div>
339</body>
340</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_intro.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_intro.html
new file mode 100644
index 0000000..9e1fb23
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_intro.html
@@ -0,0 +1,389 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Introducing LuaJIT</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Introducing LuaJIT</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a class="current" href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63This is a little essay that tries to answer the question:
64<em>'So, how does LuaJIT really work?'</em>.
65</p>
66<p>
67I tried to avoid going into all the gory details, but at the
68same time provide a deep enough explanation, to let you find
69your way around LuaJIT's inner workings.
70</p>
71<p>
72The learning curve is maybe a little bit steep for newbies and
73compiler gurus will certainly fall asleep after two paragraphs.
74It's difficult to strike a balance here.
75</p>
76
77<h2>Acronym Soup</h2>
78<p>
79As the name says LuaJIT is a <em>Just-In-Time</em> (JIT) compiler.
80This means that functions are compiled on demand, i.e. when they
81are run first. This ensures both a quick application startup
82and helps to avoid useless work, too. E.g. unused functions
83are not compiled at all.
84</p>
85<p>
86The other alternative is known as <em>Ahead-Of-Time</em> (AOT)
87compilation. Here everything is compiled before running any function.
88This is the classic way for many languages, such as C or C++.
89</p>
90<p>
91In fact plain Lua allows you to pre-compile Lua source code into
92Lua bytecode and store it in a binary file that can be run
93later on. This is used only in specific settings (e.g. memory limited
94embedded systems), because the Lua bytecode compiler is really fast.
95The ability to run source files right away is part of what makes
96a dynamic language (aka scripting language) so powerful.
97</p>
98<p>
99JIT compilation has a few other advantages for dynamic languages
100that AOT compilation can only provide with a massive amount
101of code analysis. More can be found in the literature.
102One particular advantage is explained later.
103</p>
104
105<h2>Quick, JIT &mdash; Run!</h2>
106<p>
107JIT compilation happens mostly invisible. You'll probably never
108notice that a compilation is going on. Part of the secret is
109that everything happens in little pieces intermixed with running
110the application itself inbetween. The other part of the secret
111is that JIT compilation can be made pretty fast.
112</p>
113<p>
114Most applications quickly converge to a stable state where
115everything that really needs to be compiled is compiled
116right away. Only occasional isolated compiles happen later on.
117</p>
118<p>
119Even though the name doesn't suggest it, LuaJIT <em>can</em> operate
120in AOT mode, too. But this is completely under user control
121(see <a href="luajit_api.html#jit_compile"><tt>jit.compile()</tt></a>)
122and doesn't happen automatically.
123</p>
124<p>
125Unless you have good reason to suspect that AOT compilation
126might help for a specific application, I wouldn't bother though.
127Compilation speed is usually a non-argument, because LuaJIT
128is extremely fast. Compilation times are typically in the
129<em>microsecond range</em> for individual Lua functions.
130</p>
131
132<h2>Starting Up</h2>
133<p>
134The next few paragraphs may not be exactly breaking news to you,
135if you are familiar with JIT compilers. Still, please read on,
136because some terms are introduced that are used later on.
137</p>
138<p>
139When you start LuaJIT everything proceeds like in standard Lua:
140the Lua core is initialized, the standard libraries are loaded and
141the command line is analyzed. Then usually the first Lua source
142code file is loaded and is translated to Lua bytecode. And finally
143the function for the initial main chunk is run ...
144</p>
145
146<h2>Kicking the Compiler</h2>
147<p>
148This is where LuaJIT kicks in:
149</p>
150<p>
151All Lua functions carry an additional <em>status code</em> for LuaJIT.
152Initially this is set to 'NONE', i.e. the function has not been
153looked at (yet). If a function is run with this setting,
154the LuaJIT <em>compiler pipeline</em> is started up.
155</p>
156<p>
157If you haven't loaded any special LuaJIT modules and optimization
158is not turned on, the compiler pipeline only consists of the
159<em>compiler backend</em>.
160</p>
161<p>
162The compiler backend is the low-level encoding engine that translates
163bytecode instructions to machine code instructions. Without any
164further hints from other modules, the backend more or less does a
1651:1 translation. I.e. a single variant of a bytecode instruction
166corresponds to a single piece of machine code.
167</p>
168<p>
169If all goes well, these little code pieces are put together,
170a function prologue is slapped on and voila: your Lua function
171has been translated to machine code. Of course things are not
172that simple when you look closer, but hey &mdash; this is
173the theory.
174</p>
175<p>
176Anyway, the status code for the function is set to 'OK' and the
177machine code is run. If this function runs another Lua function
178which has not been compiled, that one is compiled, too. And so on.
179</p>
180
181<h2>Call Gates</h2>
182<p>
183Ok, so what happens when a function is called repeatedly? After all
184this is the most common case.
185</p>
186<p>
187Simple: The status code is checked again. This time it's set to 'OK',
188so the machine code can be run directly. Well &mdash; that's not the
189whole truth: for calls that originate in a JIT compiled function
190a better mechanism, tentatively named <em>call gates</em> is used.
191</p>
192<p>
193Every function has a call gate field (a function pointer). By default
194it's set to a function that does the above checks and runs the
195compiler. But as soon as a function is compiled, the call gate
196is modified to point to the just compiled machine code.
197</p>
198<p>
199Calling a function is then as easy as calling the code that the
200call gate points to. But due to special (faster) calling conventions
201this function pointer cannot be used directly from C. So calls from
202a non-compiled function or from a C&nbsp;function use an extra entry
203call gate which in turn calls the real call gate. But this is
204really a non-issue since most calls in typical applications
205are intra-JIT calls.
206</p>
207
208<h2>The Compiler Pipeline</h2>
209<p>
210The compiler pipeline has already been mentioned. This sounds
211more complicated than it is. Basically this is a coroutine that
212runs a <em>frontend</em> function which in turn calls all functions
213from the <em>pipeline table</em>.
214</p>
215<p>
216The pipeline table is sorted by <em>priorities</em>. The standard
217backend has priority 0. Positive priorities are run before the
218backend and negative priorities are run after the backend. Modules
219can dynamically attach or detach themselves to the pipeline with
220the library function <tt>jit.attach()</tt>.
221</p>
222<p>
223So a typical optimizer pass better have a positive priority,
224because it needs to be run before the backend is run. E.g. the
225LuaJIT optimizer module registers itself with priority 50.
226</p>
227<p>
228On the other hand a typical helper module for debugging &mdash;
229a machine code disassembler &mdash; needs to be run after the
230backend and is attached with a negative priority.
231</p>
232<p>
233One special case occurs when compilation fails. This can be due to
234an internal error (ouch) or on purpose. E.g. the optimizer module
235checks some characteristics of the function to be compiled and
236may decide that it's just not worth it. In this case a status
237other than OK is passed back to the pipeline frontend.
238</p>
239<p>
240The easiest thing would be to abort pipeline processing and just
241give up. But this would remove the ability to trace the progress
242of the compiler (which better include failed compilations, too).
243So there is a special rule that odd priorities are still run,
244but even priorities are not. That's why e.g. <tt>-j trace</tt>
245registers itself with priority -99.
246</p>
247
248<h2>The Optimizer</h2>
249<p>
250Maybe it hasn't become clear from the above description,
251but a module can attach any Lua or C&nbsp;function to the compiler
252pipeline. In fact all of the loadable modules are Lua modules.
253Only the backend itself is written in C.
254</p>
255<p>
256So, yes &mdash; the LuaJIT optimizer is written in pure Lua!
257</p>
258<p>
259And no, don't worry, it's quite fast. One reason for this is
260that a very simple <em>abstract interpretation</em> algorithm
261is used. It mostly ignores control flow and/or basic block
262boundaries.
263</p>
264<p>
265Thus the results of the analysis are really only <em>hints</em>.
266The backend <em>must</em> check the preconditions (the contracts)
267for these hints (e.g. the object type). Still, the generated
268hints are pretty accurate and quite useful to speed up the
269compiled code (see below).
270</p>
271<p>
272Explaining how abstract interpretation works is not within the
273scope for this short essay. You may want to have a look at the
274optimizer source code and/or read some articles or books on
275this topic. The canonical reference is
276<a href="http://www2.imm.dtu.dk/~riis/PPA/ppa.html"><span class="ext">&raquo;</span>&nbsp;Principles of Program Analysis</a>.
277Ok, so this one is a bit more on the theoretical side (a gross
278understatement). Try a search engine with the keywords "abstract
279interpretation", too.
280</p>
281<p>
282Suffice to say the optimizer generates hints and passes these
283on to the backend. The backend then decides to encode different
284forms for the same bytecode instruction, to combine several
285instructions or to inline code for C&nbsp;functions. If the hints
286from the optimizer are good, the resulting code will perform
287better because shorter code paths are used for the typical cases.
288</p>
289
290<h2>The JIT Advantage</h2>
291<p>
292One important feature of the optimizer is that it takes 'live'
293function arguments into account. Since the JIT compiler is
294called just before the function is run, the arguments for this
295first invocation are already present. This can be used to great
296advantage in a <em>dynamically typed language</em>, such as Lua.
297</p>
298<p>
299Here's a trivial example:
300</p>
301<pre>
302function foo(t, k)
303 return t[k]
304end
305</pre>
306<p>
307Without knowing the most likely arguments for the function
308there's not much to optimize.
309</p>
310<p>
311Ok, so 't' is most likely a table. But it could be userdata, too.
312In fact it could be any type since the introduction of generic
313metatables for types.
314</p>
315<p>
316And more importantly 'k' can be a number, a string
317or any other type. Oh and let's not forget about metamethods ...
318</p>
319<p>
320If you know a bit about Lua internals, it should be clear by now
321that the code for this function could potentially branch to half
322of the Lua core. And it's of course impossible to inline all
323these cases.
324</p>
325<p>
326On the other hand if it's <em>known</em> (or there's a good hint)
327that 't' is a table and that 'k' is a positive integer, then there
328is a high likeliness that the key 'k' is in the array part
329of the table. This lookup can be done with just a few machine code
330instructions.
331</p>
332<p>
333Of course the preconditions for this fast path have to be checked
334(unless there are definitive hints). But if the hints are right,
335the code runs a lot faster (about a factor of 3 in this case
336for the pure table lookup).
337</p>
338
339<h2>Optimizing the Optimizer</h2>
340<p>
341A question that surely popped up in your mind while reading
342the above section: does the optimizer optimize itself? I.e.
343is the optimizer module compiled?
344</p>
345<p>
346The current answer is no. Mainly because the compiler pipeline
347is single-threaded only. It's locked during compilation and
348any parallel attempt to JIT compile a function results in
349a 'DELAYED' status code. In fact all modules that attach to
350the compiler pipeline disable compilation for the entire
351module (because LuaJIT would do that anyway). The main chunk
352of modules loaded with <tt>require()</tt> is never compiled,
353so there is no chicken-and-egg problem here.
354</p>
355<p>
356Of course you could do an AOT compilation in the main chunk of
357the optimizer module. But then only with the plain backend.
358Recompiling it later on with the optimizer attached doesn't work,
359because a function cannot be compiled twice (I plan to lift
360this restriction).
361</p>
362<p>
363The other question is whether it pays off to compile the optimizer
364at all? Honestly, I haven't tried, because the current optimizer
365is really simple. It runs very quickly, even under the bytecode
366interpreter.
367</p>
368
369<h2>That's All Folks</h2>
370<p>
371Ok, that's all for now. I'll extend this text later on with
372new topics that come up in questions. Keep on asking these
373on the mailing list if you are interested.
374</p>
375<p>
376Thank you for your attention!
377</p>
378<br class="flush">
379</div>
380<div id="foot">
381<hr class="hide">
382Copyright &copy; 2005-2011 Mike Pall
383<span class="noprint">
384&middot;
385<a href="contact.html">Contact</a>
386</span>
387</div>
388</body>
389</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_performance.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_performance.html
new file mode 100644
index 0000000..7f2307c
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_performance.html
@@ -0,0 +1,394 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>LuaJIT Performance</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.bench {
13 line-height: 1.2;
14}
15tr.benchhead td {
16 font-weight: bold;
17}
18td img, li img {
19 vertical-align: middle;
20}
21td.barhead, td.bar {
22 font-size: 8pt;
23 font-family: Courier New, Courier, monospace;
24 width: 360px;
25 padding: 0;
26}
27td.bar {
28 background: url('img/backbar.png');
29}
30td.speedup {
31 text-align: center;
32}
33</style>
34</head>
35<body>
36<div id="site">
37<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
38</div>
39<div id="head">
40<h1>LuaJIT Performance</h1>
41</div>
42<div id="nav">
43<ul><li>
44<a href="index.html">Index</a>
45</li><li>
46<a href="luajit.html">LuaJIT</a>
47<ul><li>
48<a href="luajit_features.html">Features</a>
49</li><li>
50<a href="luajit_install.html">Installation</a>
51</li><li>
52<a href="luajit_run.html">Running</a>
53</li><li>
54<a href="luajit_api.html">API Extensions</a>
55</li><li>
56<a href="luajit_intro.html">Introduction</a>
57</li><li>
58<a class="current" href="luajit_performance.html">Performance</a>
59</li><li>
60<a href="luajit_debug.html">Debugging</a>
61</li><li>
62<a href="luajit_changes.html">Changes</a>
63</li></ul>
64</li><li>
65<a href="coco.html">Coco</a>
66<ul><li>
67<a href="coco_portability.html">Portability</a>
68</li><li>
69<a href="coco_api.html">API Extensions</a>
70</li><li>
71<a href="coco_changes.html">Changes</a>
72</li></ul>
73</li><li>
74<a href="dynasm.html">DynASM</a>
75<ul><li>
76<a href="dynasm_features.html">Features</a>
77</li><li>
78<a href="dynasm_examples.html">Examples</a>
79</li></ul>
80</li><li>
81<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
82</li></ul>
83</div>
84<div id="main">
85<p>
86Here are some performance measurements, based on a few benchmarks.
87</p>
88<p style="background: #ffd0d0; text-align: center;">
89LuaJIT 2.0 is available with much improved performance!<br>
90Please check the new
91<a href="http://luajit.org/performance.html"><span class="ext">&raquo;</span> interactive performance comparison</a>.
92</p>
93
94<h2 id="interpretation">Interpreting the Results</h2>
95<p>
96As is always the case with benchmarks, care must be taken to
97interpret the results:
98</p>
99<p>
100First, the standard Lua interpreter is already <em>very</em> fast.
101It's commonly the fastest of it's class (interpreters) in the
102<a href="http://shootout.alioth.debian.org/"><span class="ext">&raquo;</span>&nbsp;Great Computer Language Shootout</a>.
103Only true machine code compilers get a better overall score.
104</p>
105<p>
106Any performance improvements due to LuaJIT can only be incremental.
107You can't expect a speedup of 50x if the fastest compiled language
108is only 5x faster than interpreted Lua in a particular benchmark.
109LuaJIT can't do miracles.
110</p>
111<p>
112Also please note that most of the benchmarks below are <em>not</em>
113trivial micro-benchmarks, which are often cited with marvelous numbers.
114Micro-benchmarks do not realistically model the performance gains you
115can expect in your own programs.
116</p>
117<p>
118It's easy to make up a few one-liners like:<br>
119<tt>&nbsp;&nbsp;local function f(...) end; for i=1,1e7 do f() end</tt><br>
120This is more than 30x faster with LuaJIT. But you won't find
121this in a real-world program.
122</p>
123
124<h2 id="methods">Measurement Methods</h2>
125<p>
126All measurements have been taken on a Pentium&nbsp;III 1.139&nbsp;GHz
127running Linux&nbsp;2.6. Both Lua and LuaJIT have been compiled with
128GCC&nbsp;3.3.6 with <tt>-O3 -fomit-frame-pointer</tt>.
129You'll definitely get different results on different machines or
130with different C&nbsp;compiler options. <sup>*</sup>
131</p>
132<p>
133The base for the comparison are the user CPU times as reported by
134<tt>/usr/bin/time</tt>. The runtime of each benchmark is parametrized
135and has been adjusted to minimize the variation between several runs.
136The ratio between the times for LuaJIT and Lua gives the speedup.
137Only this number is shown because it's less dependent on a specific system.
138</p>
139<p>
140E.g. a speedup of 6.74 means the same benchmark runs almost 7 times
141faster with <tt>luajit&nbsp;-O</tt> than with standard Lua (or with
142<tt>-j off</tt>). Your mileage may vary.
143</p>
144<p style="font-size: 80%;">
145<sup>*</sup> Yes, LuaJIT relies on quite a bit of the Lua core infrastructure
146like table and string handling. All of this is written in C and
147should be compiled with full optimization turned on, or performance
148will suffer.
149</p>
150
151<h2 id="lua_luajit" class="pagebreak">Comparing Lua to LuaJIT</h2>
152<p>
153Here is a comparison using the current benchmark collection of the
154<a href="http://shootout.alioth.debian.org/"><span class="ext">&raquo;</span>&nbsp;Great Computer Language Shootout</a> (as of 3/2006):
155</p>
156
157<div class="tablewrap">
158<table class="bench">
159<tr class="benchhead">
160<td>Benchmark</td>
161<td class="speedup">Speedup</td>
162<td class="barhead">
163<img src="img/spacer.png" width="360" height="12" alt="-----1x----2x----3x----4x----5x----6x----7x----8x">
164</td>
165</tr>
166<tr class="odd">
167<td>mandelbrot</td>
168<td class="speedup">6.74</td>
169<td class="bar"><img src="img/bluebar.png" width="303" height="12" alt="========================================"></td>
170</tr>
171<tr class="even">
172<td>recursive</td>
173<td class="speedup">6.64</td>
174<td class="bar"><img src="img/bluebar.png" width="299" height="12" alt="========================================"></td>
175</tr>
176<tr class="odd">
177<td>fannkuch</td>
178<td class="speedup">5.37</td>
179<td class="bar"><img src="img/bluebar.png" width="242" height="12" alt="================================"></td>
180</tr>
181<tr class="even">
182<td>chameneos</td>
183<td class="speedup">5.08</td>
184<td class="bar"><img src="img/bluebar.png" width="229" height="12" alt="=============================="></td>
185</tr>
186<tr class="odd">
187<td>nsievebits</td>
188<td class="speedup">5.05</td>
189<td class="bar"><img src="img/bluebar.png" width="227" height="12" alt="=============================="></td>
190</tr>
191<tr class="even">
192<td>pidigits</td>
193<td class="speedup">4.94</td>
194<td class="bar"><img src="img/bluebar.png" width="222" height="12" alt="=============================="></td>
195</tr>
196<tr class="odd">
197<td>nbody</td>
198<td class="speedup">4.63</td>
199<td class="bar"><img src="img/bluebar.png" width="208" height="12" alt="============================"></td>
200</tr>
201<tr class="even">
202<td>spectralnorm</td>
203<td class="speedup">4.59</td>
204<td class="bar"><img src="img/bluebar.png" width="207" height="12" alt="============================"></td>
205</tr>
206<tr class="odd">
207<td>cheapconcr</td>
208<td class="speedup">4.46</td>
209<td class="bar"><img src="img/bluebar.png" width="201" height="12" alt="==========================="></td>
210</tr>
211<tr class="even">
212<td>partialsums</td>
213<td class="speedup">3.73</td>
214<td class="bar"><img src="img/bluebar.png" width="168" height="12" alt="======================"></td>
215</tr>
216<tr class="odd">
217<td>fasta</td>
218<td class="speedup">2.68</td>
219<td class="bar"><img src="img/bluebar.png" width="121" height="12" alt="================"></td>
220</tr>
221<tr class="even">
222<td>cheapconcw</td>
223<td class="speedup">2.52</td>
224<td class="bar"><img src="img/bluebar.png" width="113" height="12" alt="==============="></td>
225</tr>
226<tr class="odd">
227<td>nsieve</td>
228<td class="speedup">1.95</td>
229<td class="bar"><img src="img/bluebar.png" width="88" height="12" alt="============"></td>
230</tr>
231<tr class="even">
232<td>revcomp</td>
233<td class="speedup">1.92</td>
234<td class="bar"><img src="img/bluebar.png" width="86" height="12" alt="============"></td>
235</tr>
236<tr class="odd">
237<td>knucleotide</td>
238<td class="speedup">1.59</td>
239<td class="bar"><img src="img/bluebar.png" width="72" height="12" alt="=========="></td>
240</tr>
241<tr class="even">
242<td>binarytrees</td>
243<td class="speedup">1.52</td>
244<td class="bar"><img src="img/bluebar.png" width="68" height="12" alt="========="></td>
245</tr>
246<tr class="odd">
247<td>sumfile</td>
248<td class="speedup">1.27</td>
249<td class="bar"><img src="img/bluebar.png" width="57" height="12" alt="========"></td>
250</tr>
251<tr class="even">
252<td>regexdna</td>
253<td class="speedup">1.01</td>
254<td class="bar"><img src="img/bluebar.png" width="45" height="12" alt="======"></td>
255</tr>
256</table>
257</div>
258<p>
259Note that many of these benchmarks have changed over time (both spec
260and code). Benchmark results shown in previous versions of LuaJIT
261are not directly comparable. The next section compares different
262versions with the current set of benchmarks.
263</p>
264
265<h2 id="luajit_versions" class="pagebreak">Comparing LuaJIT Versions</h2>
266<p>
267This shows the improvements between the following versions:
268</p>
269<ul>
270<li>LuaJIT&nbsp;1.0.x <img src="img/bluebar.png" width="30" height="12" alt="(===)"></li>
271<li>LuaJIT&nbsp;1.1.x <img src="img/bluebar.png" width="30" height="12" alt="(===##)"><img src="img/magentabar.png" width="20" height="12" alt=""></li>
272</ul>
273
274<div class="tablewrap">
275<table class="bench">
276<tr class="benchhead">
277<td>Benchmark</td>
278<td class="speedup">Speedup</td>
279<td class="barhead">
280<img src="img/spacer.png" width="360" height="12" alt="-----1x----2x----3x----4x----5x----6x----7x----8x">
281</td>
282</tr>
283<tr class="odd">
284<td>fannkuch</td>
285<td class="speedup">3.96&nbsp;&rarr;&nbsp;5.37</td>
286<td class="bar"><img src="img/bluebar.png" width="178" height="12" alt="========================"><img src="img/magentabar.png" width="64" height="12" alt="########"></td>
287</tr>
288<tr class="even">
289<td>chameneos</td>
290<td class="speedup">2.25&nbsp;&rarr;&nbsp;5.08</td>
291<td class="bar"><img src="img/bluebar.png" width="101" height="12" alt="=============="><img src="img/magentabar.png" width="128" height="12" alt="################"></td>
292</tr>
293<tr class="odd">
294<td>nsievebits</td>
295<td class="speedup">2.90&nbsp;&rarr;&nbsp;5.05</td>
296<td class="bar"><img src="img/bluebar.png" width="131" height="12" alt="================="><img src="img/magentabar.png" width="96" height="12" alt="#############"></td>
297</tr>
298<tr class="even">
299<td>pidigits</td>
300<td class="speedup">3.58&nbsp;&rarr;&nbsp;4.94</td>
301<td class="bar"><img src="img/bluebar.png" width="161" height="12" alt="====================="><img src="img/magentabar.png" width="61" height="12" alt="#########"></td>
302</tr>
303<tr class="odd">
304<td>nbody</td>
305<td class="speedup">4.16&nbsp;&rarr;&nbsp;4.63</td>
306<td class="bar"><img src="img/bluebar.png" width="187" height="12" alt="========================="><img src="img/magentabar.png" width="21" height="12" alt="###"></td>
307</tr>
308<tr class="even">
309<td>cheapconcr</td>
310<td class="speedup">1.46&nbsp;&rarr;&nbsp;4.46</td>
311<td class="bar"><img src="img/bluebar.png" width="66" height="12" alt="========="><img src="img/magentabar.png" width="135" height="12" alt="##################"></td>
312</tr>
313<tr class="odd">
314<td>partialsums</td>
315<td class="speedup">1.71&nbsp;&rarr;&nbsp;3.73</td>
316<td class="bar"><img src="img/bluebar.png" width="77" height="12" alt="=========="><img src="img/magentabar.png" width="91" height="12" alt="############"></td>
317</tr>
318<tr class="even">
319<td>fasta</td>
320<td class="speedup">2.37&nbsp;&rarr;&nbsp;2.68</td>
321<td class="bar"><img src="img/bluebar.png" width="107" height="12" alt="=============="><img src="img/magentabar.png" width="14" height="12" alt="##"></td>
322</tr>
323<tr class="odd">
324<td>cheapconcw</td>
325<td class="speedup">1.27&nbsp;&rarr;&nbsp;2.52</td>
326<td class="bar"><img src="img/bluebar.png" width="57" height="12" alt="========"><img src="img/magentabar.png" width="56" height="12" alt="#######"></td>
327</tr>
328<tr class="even">
329<td>revcomp</td>
330<td class="speedup">1.45&nbsp;&rarr;&nbsp;1.92</td>
331<td class="bar"><img src="img/bluebar.png" width="65" height="12" alt="========="><img src="img/magentabar.png" width="21" height="12" alt="###"></td>
332</tr>
333<tr class="odd">
334<td>knucleotide</td>
335<td class="speedup">1.32&nbsp;&rarr;&nbsp;1.59</td>
336<td class="bar"><img src="img/bluebar.png" width="59" height="12" alt="========"><img src="img/magentabar.png" width="13" height="12" alt="##"></td>
337</tr>
338</table>
339</div>
340<p>
341All other benchmarks show only minor performance differences.
342</p>
343
344<h2 id="summary">Summary</h2>
345<p>
346These results should give you an idea about what speedup
347you can expect depending on the nature of your Lua code:
348</p>
349<ul>
350<li>
351LuaJIT is really good at (floating-point) math and loops
352(mandelbrot, pidigits, spectralnorm, partialsums).
353</li>
354<li>
355Function calls (recursive), vararg calls, table lookups (nbody),
356table iteration and coroutine switching (chameneos, cheapconc)
357are a lot faster than with plain Lua.
358</li>
359<li>
360It's still pretty good for indexed table access (fannkuch, nsieve)
361and string processing (fasta, revcomp, knucleotide).
362But there is room for improvement in a future version.
363</li>
364<li>
365If your application spends most of the time in C&nbsp;code
366you won't see much of a difference (regexdna, sumfile).
367Ok, so write more code in pure Lua. :-)
368</li>
369<li>
370The real speedup may be shadowed by other dominant factors in a benchmark:
371<ul>
372<li>Common parts of the Lua core: e.g. memory allocation
373and GC (binarytrees).</li>
374<li>Language characteristics: e.g. lack of bit operations (nsievebits).</li>
375<li>System characteristics: e.g. CPU cache size and memory speed (nsieve).</li>
376</ul>
377</li>
378</ul>
379<p>
380The best idea is of course to benchmark your <em>own</em> applications.
381Please report any interesting results you may find. Thank you!
382</p>
383<br class="flush">
384</div>
385<div id="foot">
386<hr class="hide">
387Copyright &copy; 2005-2011 Mike Pall
388<span class="noprint">
389&middot;
390<a href="contact.html">Contact</a>
391</span>
392</div>
393</body>
394</html>
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_run.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_run.html
new file mode 100644
index 0000000..bc9105b
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_run.html
@@ -0,0 +1,159 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Running LuaJIT</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Running LuaJIT</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="index.html">Index</a>
22</li><li>
23<a href="luajit.html">LuaJIT</a>
24<ul><li>
25<a href="luajit_features.html">Features</a>
26</li><li>
27<a href="luajit_install.html">Installation</a>
28</li><li>
29<a class="current" href="luajit_run.html">Running</a>
30</li><li>
31<a href="luajit_api.html">API Extensions</a>
32</li><li>
33<a href="luajit_intro.html">Introduction</a>
34</li><li>
35<a href="luajit_performance.html">Performance</a>
36</li><li>
37<a href="luajit_debug.html">Debugging</a>
38</li><li>
39<a href="luajit_changes.html">Changes</a>
40</li></ul>
41</li><li>
42<a href="coco.html">Coco</a>
43<ul><li>
44<a href="coco_portability.html">Portability</a>
45</li><li>
46<a href="coco_api.html">API Extensions</a>
47</li><li>
48<a href="coco_changes.html">Changes</a>
49</li></ul>
50</li><li>
51<a href="dynasm.html">DynASM</a>
52<ul><li>
53<a href="dynasm_features.html">Features</a>
54</li><li>
55<a href="dynasm_examples.html">Examples</a>
56</li></ul>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63LuaJIT has only a single stand-alone executable, called <tt>luajit</tt>.
64It can be used to run simple Lua statements or whole Lua applications
65from the command line. It has an interactive mode, too.
66</p>
67<p>
68<em>Note: The optimizer is not activated by default because it resides
69in an external module
70(see <a href="luajit_install.html">Installing LuaJIT</a>).
71It's recommended to always use the optimizer, i.e.:</em> <tt>luajit -O</tt>
72</p>
73
74<h2 id="options">Command Line Options</h2>
75<p>
76The <tt>luajit</tt> stand-alone executable is just a slightly modified
77version of the regular <tt>lua</tt> stand-alone executable.
78It supports the same basic options, too. Please have a look at the
79<a href="../doc/lua.html">Manual Page</a>
80for the regular <tt>lua</tt> stand-alone executable.
81</p>
82<p>
83Two additional options control LuaJIT behaviour:
84</p>
85
86<h3 id="opt_j"><tt>-j cmd[=value]</tt></h3>
87<p>
88This option performs a LuaJIT control command. LuaJIT has a small
89but extensible set of control commands. It's easy to add your own.
90</p>
91<p>
92The command is first searched for in the <tt>jit.*</tt> library.
93If no matching function is found, a module named <tt>jit.&lt;cmd&gt;</tt>
94is loaded. The module table must provide a <tt>start()</tt> function.
95</p>
96<p>
97For the <tt>-j cmd</tt> form the function is called without an argument.
98Otherwise the <tt>value</tt> is passed as the first argument (a string).
99</p>
100<p>
101Here are the built-in LuaJIT control commands:
102</p>
103<ul>
104<li id="j_on"><tt>-j on</tt> &mdash; Turns the JIT engine on (default).</li>
105<li id="j_off"><tt>-j off</tt> &mdash; Turns the JIT engine off.</li>
106<li id="j_debug"><tt>-j debug[=level]</tt> &mdash; Set debug level. See
107<a href="luajit_api.html#jit_debug">jit.debug()</a>.</li>
108</ul>
109<p>
110The following control commands are loaded from add-on modules:
111</p>
112<ul>
113<li id="j_trace"><tt>-j trace[=file]</tt> &mdash; Trace the progress of the JIT compiler.</li>
114<li id="j_dumphints"><tt>-j dumphints[=file]</tt> &mdash; Dump bytecode + hints before compilation.</li>
115<li id="j_dump"><tt>-j dump[=file]</tt> &mdash; Dump machine code after compilation.</li>
116</ul>
117
118<!--
119<h3 id="opt_O"><tt>-O[level|ext]</tt></h3>
120-->
121<h3 id="opt_O"><tt>-O[level]</tt></h3>
122<p>
123This option loads and runs the optimizer module <tt>jit.opt</tt>.
124The optimizer generates hints for the compiler backend to improve
125the performance of the compiled code. The optimizer slows down
126compilation slightly, but the end result should make up for it
127in almost every case.
128</p>
129<p>
130The <tt>-O</tt> form sets the default optimizer level, which is
131currently <tt>2</tt> (this may change in future versions
132of LuaJIT).
133</p>
134<p>
135The <tt>-Olevel</tt> form explicitly sets the optimizer level:
136</p>
137<ul>
138<li><tt>-O0</tt> &mdash; disable the optimizer but leave it attached.</li>
139<li><tt>-O1</tt> &mdash; perform standard optimizations (like hints for table lookups).</li>
140<li><tt>-O2</tt> &mdash; like <tt>-O1</tt> but also loads <tt>jit.opt_inline</tt> to enable result hints and inlining for standard library functions.</li>
141</ul>
142<!--
143<p>
144The <tt>-Oext</tt> form loads optimizer extension modules
145from <tt>jit.opt_&lt;ext&gt;</tt>.
146</p>
147-->
148<br class="flush">
149</div>
150<div id="foot">
151<hr class="hide">
152Copyright &copy; 2005-2011 Mike Pall
153<span class="noprint">
154&middot;
155<a href="contact.html">Contact</a>
156</span>
157</div>
158</body>
159</html>
diff --git a/libraries/LuaJIT-1.1.7/src/Makefile b/libraries/LuaJIT-1.1.7/src/Makefile
new file mode 100644
index 0000000..b678fe1
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/Makefile
@@ -0,0 +1,252 @@
1# makefile for building Lua
2# see ../INSTALL for installation instructions
3# see ../Makefile and luaconf.h for further customization
4
5# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
6
7# Your platform. See PLATS for possible values.
8PLAT= none
9
10CC= gcc -m32
11CFLAGS= -O2 -fomit-frame-pointer -Wall $(MYCFLAGS) $(COCOCFLAGS) $(JITCFLAGS)
12AR= ar rcu
13RANLIB= ranlib
14RM= rm -f
15LIBS= -lm $(MYLIBS)
16
17MYCFLAGS=
18MYLDFLAGS=
19MYLIBS=
20
21# ++ Coco =========
22# Default: autodetect gccasm/setjmp/ucontext/fibers context switch method.
23COCOCFLAGS=
24# Force use of setjmp (instead of gccasm).
25#COCOCFLAGS= -DCOCO_USE_SETJMP
26# Force use of ucontext (instead of gccasm or setjmp).
27#COCOCFLAGS= -DCOCO_USE_UCONTEXT
28# Uncomment this if you want to compile LuaJIT without Coco.
29# This effectively disables yielding from JIT compiled functions.
30#COCOCFLAGS= -DCOCO_DISABLE
31# -- Coco =========
32
33# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
34
35PLATS= linux bsd macosx solaris mingw cygwin posix generic linux_rl bsd_rl macosx_rl
36
37# ++ Coco =========
38COCO_O= lcoco.o
39# -- Coco =========
40
41# ++ LuaJIT =========
42DASMDIR= ../dynasm
43DASMFLAGS=
44DASMDISTFLAGS= -LN
45
46# This assumes you already have a copy of (plain) Lua 5.1 installed
47# You can use luajit, too (built with the pre-processed headers from the dist)
48DASM= lua $(DASMDIR)/dynasm.lua
49
50JITCFLAGS= -I$(DASMDIR)
51JIT_O= ljit_core.o ljit_mem.o ljit_dasm.o ljit_backend.o
52JITLIB_O= ljitlib.o
53
54ALL_DH = ljit_x86.h
55# -- LuaJIT =========
56
57LUA_A= liblua.a
58CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
59 lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
60 lundump.o lvm.o lzio.o $(COCO_O) $(JIT_O)
61LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
62 lstrlib.o loadlib.o $(JITLIB_O) linit.o
63
64# Standalone has been renamed to avoid conflicts during installation
65LUA_T= luajit
66LUA_O= lua.o
67
68LUAC_T= luac
69LUAC_O= luac.o print.o
70
71ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
72# Do not build luac by default
73#ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
74ALL_T= $(LUA_A) $(LUA_T)
75ALL_A= $(LUA_A)
76
77default: $(PLAT)
78
79all: $(ALL_T)
80
81o: $(ALL_O)
82
83a: $(ALL_A)
84
85$(LUA_A): $(CORE_O) $(LIB_O)
86 $(AR) $@ $?
87 $(RANLIB) $@
88
89$(LUA_T): $(LUA_O) $(LUA_A)
90 $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
91
92$(LUAC_T): $(LUAC_O) $(LUA_A)
93 $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
94
95# ++ LuaJIT =========
96ljit_x86.h: ljit_x86.dasc ljit_x86_inline.dash ljit_x86.dash
97 $(DASM) $(DASMFLAGS) -o $@ ljit_x86.dasc
98
99distclean: clean
100 $(DASM) $(DASMDISTFLAGS) -o ljit_x86.h ljit_x86.dasc
101
102cleaner: clean
103 $(RM) $(ALL_DH)
104# -- LuaJIT =========
105
106clean:
107 $(RM) $(ALL_T) $(ALL_O)
108
109depend:
110 @$(CC) $(CFLAGS) -MM l*.c print.c
111
112echo:
113 @echo "PLAT = $(PLAT)"
114 @echo "CC = $(CC)"
115 @echo "CFLAGS = $(CFLAGS)"
116 @echo "AR = $(AR)"
117 @echo "RANLIB = $(RANLIB)"
118 @echo "RM = $(RM)"
119 @echo "MYCFLAGS = $(MYCFLAGS)"
120 @echo "MYLDFLAGS = $(MYLDFLAGS)"
121 @echo "MYLIBS = $(MYLIBS)"
122
123# convenience targets for popular platforms
124
125none:
126 @echo "Please choose a platform:"
127 @echo " $(PLATS)"
128
129bsd:
130 $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E"
131
132bsd_rl:
133 $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -DLUA_USE_READLINE" MYLIBS="-Wl,-E -lreadline"
134
135generic:
136 $(MAKE) all MYCFLAGS=
137
138linux:
139 $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl"
140
141linux_rl:
142 $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE" MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses"
143
144# Mac OS X on Intel Macs only!
145macosx:
146 $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX
147# use this on Mac OS X 10.3
148# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX
149
150macosx_rl:
151 $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE" MYLIBS="-lreadline"
152
153mingw:
154 $(MAKE) "LUA_A=lua51.dll" "LUA_T=luajit.exe" \
155 "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
156 "MYCFLAGS=-DLUA_BUILD_AS_DLL -maccumulate-outgoing-args" \
157 "MYLIBS=" "MYLDFLAGS=-s" luajit.exe
158
159cygwin:
160 $(MAKE) "CC=gcc -mno-cygwin" mingw
161
162posix:
163 $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX
164
165# Solaris x86 only!
166solaris:
167 $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl"
168
169# list targets that do not create files (but not all makes understand .PHONY)
170.PHONY: all $(PLATS) default o a clean depend echo none cleaner distclean
171
172# DO NOT DELETE
173
174lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \
175 lstate.h ltm.h lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lstring.h \
176 ltable.h lundump.h lvm.h
177lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h
178lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h lcoco.h
179lcoco.o: lcoco.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \
180 lzio.h lmem.h lcoco.h ldo.h lvm.h lgc.h
181lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
182 lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h lcoco.h \
183 ldo.h lgc.h ltable.h
184ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
185ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \
186 llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
187 lcoco.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h ljit.h
188ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
189 lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \
190 lstring.h ltable.h lundump.h lvm.h ljit.h
191ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \
192 lzio.h lmem.h lcoco.h lundump.h
193lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \
194 lstate.h ltm.h lzio.h lcoco.h ljit.h
195lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
196 lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lstring.h ltable.h
197linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
198liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
199ljit_backend.o: ljit_backend.c lua.h luaconf.h lobject.h llimits.h \
200 lstate.h ltm.h lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lstring.h \
201 ltable.h lvm.h lopcodes.h ldebug.h ljit.h ljit_hints.h ljit_dasm.h \
202 ../dynasm/dasm_proto.h ljit_x86.h
203ljit_core.o: ljit_core.c lua.h luaconf.h lobject.h llimits.h lstate.h \
204 ltm.h lzio.h lmem.h lcoco.h ldo.h lstring.h lgc.h ltable.h ldebug.h \
205 lopcodes.h ljit.h ljit_hints.h luajit.h
206ljit_dasm.o: ljit_dasm.c lua.h luaconf.h ljit.h lobject.h llimits.h \
207 ljit_dasm.h ../dynasm/dasm_proto.h lmem.h ../dynasm/dasm_x86.h
208ljit_mem.o: ljit_mem.c lua.h luaconf.h lmem.h llimits.h ldo.h lobject.h \
209 lstate.h ltm.h lzio.h lcoco.h ljit.h ljit_dasm.h ../dynasm/dasm_proto.h
210ljitlib.o: ljitlib.c lua.h luaconf.h lauxlib.h luajit.h lualib.h \
211 lobject.h llimits.h lstate.h ltm.h lzio.h lmem.h lcoco.h lstring.h \
212 lgc.h ltable.h lfunc.h lopcodes.h ljit.h ljit_hints.h
213llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \
214 lzio.h lmem.h lcoco.h llex.h lparser.h lstring.h lgc.h ltable.h
215lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
216lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
217 ltm.h lzio.h lmem.h lcoco.h ldo.h
218loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h luajit.h
219lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \
220 ltm.h lzio.h lmem.h lcoco.h lstring.h lgc.h lvm.h
221lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h
222loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h
223lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
224 lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h lcoco.h \
225 ldo.h lfunc.h lstring.h lgc.h ltable.h
226lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
227 ltm.h lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h llex.h lstring.h \
228 ltable.h ljit.h
229lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \
230 ltm.h lzio.h lcoco.h lstring.h lgc.h
231lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
232ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
233 ltm.h lzio.h lmem.h lcoco.h ldo.h lgc.h ltable.h
234ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
235ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
236 lmem.h lcoco.h lstring.h lgc.h ltable.h
237lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h luajit.h
238luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \
239 lstate.h ltm.h lzio.h lmem.h lcoco.h lfunc.h lopcodes.h lstring.h lgc.h \
240 lundump.h
241lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
242 llimits.h ltm.h lzio.h lmem.h lcoco.h ldo.h lfunc.h lstring.h lgc.h \
243 lundump.h
244lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
245 lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h \
246 lvm.h
247lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
248 lzio.h lcoco.h
249print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \
250 ltm.h lzio.h lmem.h lcoco.h lopcodes.h lundump.h
251
252# (end of Makefile)
diff --git a/libraries/LuaJIT-1.1.7/src/lapi.c b/libraries/LuaJIT-1.1.7/src/lapi.c
new file mode 100644
index 0000000..e8347a2
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lapi.c
@@ -0,0 +1,1082 @@
1/*
2** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
3** Lua API
4** See Copyright Notice in lua.h
5*/
6
7
8#include <assert.h>
9#include <math.h>
10#include <stdarg.h>
11#include <string.h>
12
13#define lapi_c
14#define LUA_CORE
15
16#include "lua.h"
17
18#include "lapi.h"
19#include "ldebug.h"
20#include "ldo.h"
21#include "lfunc.h"
22#include "lgc.h"
23#include "lmem.h"
24#include "lobject.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29#include "lundump.h"
30#include "lvm.h"
31
32
33
34const char lua_ident[] =
35 "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
36 "$Authors: " LUA_AUTHORS " $\n"
37 "$URL: www.lua.org $\n";
38
39
40
41#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
42
43#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
44
45#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
46
47
48
49static TValue *index2adr (lua_State *L, int idx) {
50 if (idx > 0) {
51 TValue *o = L->base + (idx - 1);
52 api_check(L, idx <= L->ci->top - L->base);
53 if (o >= L->top) return cast(TValue *, luaO_nilobject);
54 else return o;
55 }
56 else if (idx > LUA_REGISTRYINDEX) {
57 api_check(L, idx != 0 && -idx <= L->top - L->base);
58 return L->top + idx;
59 }
60 else switch (idx) { /* pseudo-indices */
61 case LUA_REGISTRYINDEX: return registry(L);
62 case LUA_ENVIRONINDEX: {
63 Closure *func = curr_func(L);
64 sethvalue(L, &L->env, func->c.env);
65 return &L->env;
66 }
67 case LUA_GLOBALSINDEX: return gt(L);
68 default: {
69 Closure *func = curr_func(L);
70 idx = LUA_GLOBALSINDEX - idx;
71 return (idx <= func->c.nupvalues)
72 ? &func->c.upvalue[idx-1]
73 : cast(TValue *, luaO_nilobject);
74 }
75 }
76}
77
78
79static Table *getcurrenv (lua_State *L) {
80 if (L->ci == L->base_ci) /* no enclosing function? */
81 return hvalue(gt(L)); /* use global table as environment */
82 else {
83 Closure *func = curr_func(L);
84 return func->c.env;
85 }
86}
87
88
89void luaA_pushobject (lua_State *L, const TValue *o) {
90 setobj2s(L, L->top, o);
91 api_incr_top(L);
92}
93
94
95LUA_API int lua_checkstack (lua_State *L, int size) {
96 int res = 1;
97 lua_lock(L);
98 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
99 res = 0; /* stack overflow */
100 else if (size > 0) {
101 luaD_checkstack(L, size);
102 if (L->ci->top < L->top + size)
103 L->ci->top = L->top + size;
104 }
105 lua_unlock(L);
106 return res;
107}
108
109
110LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
111 StkId f, t;
112 if (from == to) return;
113 lua_lock(to);
114 api_checknelems(from, n);
115 api_check(from, G(from) == G(to));
116 api_check(from, to->ci->top - to->top >= n);
117 f = from->top;
118 t = to->top = to->top + n;
119 while (--n >= 0) setobj2s(to, --t, --f);
120 from->top = f;
121 lua_unlock(to);
122}
123
124
125LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
126 lua_CFunction old;
127 lua_lock(L);
128 old = G(L)->panic;
129 G(L)->panic = panicf;
130 lua_unlock(L);
131 return old;
132}
133
134
135LUA_API lua_State *lua_newthread (lua_State *L) {
136 lua_State *L1;
137 lua_lock(L);
138 luaC_checkGC(L);
139 L1 = luaE_newthread(L);
140 setthvalue(L, L->top, L1);
141 api_incr_top(L);
142 lua_unlock(L);
143 luai_userstatethread(L, L1);
144 return L1;
145}
146
147
148
149/*
150** basic stack manipulation
151*/
152
153
154LUA_API int lua_gettop (lua_State *L) {
155 return cast_int(L->top - L->base);
156}
157
158
159LUA_API void lua_settop (lua_State *L, int idx) {
160 lua_lock(L);
161 if (idx >= 0) {
162 api_check(L, idx <= L->stack_last - L->base);
163 while (L->top < L->base + idx)
164 setnilvalue(L->top++);
165 L->top = L->base + idx;
166 }
167 else {
168 api_check(L, -(idx+1) <= (L->top - L->base));
169 L->top += idx+1; /* `subtract' index (index is negative) */
170 }
171 lua_unlock(L);
172}
173
174
175LUA_API void lua_remove (lua_State *L, int idx) {
176 StkId p;
177 lua_lock(L);
178 p = index2adr(L, idx);
179 api_checkvalidindex(L, p);
180 while (++p < L->top) setobjs2s(L, p-1, p);
181 L->top--;
182 lua_unlock(L);
183}
184
185
186LUA_API void lua_insert (lua_State *L, int idx) {
187 StkId p;
188 StkId q;
189 lua_lock(L);
190 p = index2adr(L, idx);
191 api_checkvalidindex(L, p);
192 for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
193 setobjs2s(L, p, L->top);
194 lua_unlock(L);
195}
196
197
198LUA_API void lua_replace (lua_State *L, int idx) {
199 StkId o;
200 lua_lock(L);
201 /* explicit test for incompatible code */
202 if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
203 luaG_runerror(L, "no calling environment");
204 api_checknelems(L, 1);
205 o = index2adr(L, idx);
206 api_checkvalidindex(L, o);
207 if (idx == LUA_ENVIRONINDEX) {
208 Closure *func = curr_func(L);
209 api_check(L, ttistable(L->top - 1));
210 func->c.env = hvalue(L->top - 1);
211 luaC_barrier(L, func, L->top - 1);
212 }
213 else {
214 setobj(L, o, L->top - 1);
215 if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
216 luaC_barrier(L, curr_func(L), L->top - 1);
217 }
218 L->top--;
219 lua_unlock(L);
220}
221
222
223LUA_API void lua_pushvalue (lua_State *L, int idx) {
224 lua_lock(L);
225 setobj2s(L, L->top, index2adr(L, idx));
226 api_incr_top(L);
227 lua_unlock(L);
228}
229
230
231
232/*
233** access functions (stack -> C)
234*/
235
236
237LUA_API int lua_type (lua_State *L, int idx) {
238 StkId o = index2adr(L, idx);
239 return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
240}
241
242
243LUA_API const char *lua_typename (lua_State *L, int t) {
244 UNUSED(L);
245 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
246}
247
248
249LUA_API int lua_iscfunction (lua_State *L, int idx) {
250 StkId o = index2adr(L, idx);
251 return iscfunction(o);
252}
253
254
255LUA_API int lua_isnumber (lua_State *L, int idx) {
256 TValue n;
257 const TValue *o = index2adr(L, idx);
258 return tonumber(o, &n);
259}
260
261
262LUA_API int lua_isstring (lua_State *L, int idx) {
263 int t = lua_type(L, idx);
264 return (t == LUA_TSTRING || t == LUA_TNUMBER);
265}
266
267
268LUA_API int lua_isuserdata (lua_State *L, int idx) {
269 const TValue *o = index2adr(L, idx);
270 return (ttisuserdata(o) || ttislightuserdata(o));
271}
272
273
274LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
275 StkId o1 = index2adr(L, index1);
276 StkId o2 = index2adr(L, index2);
277 return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
278 : luaO_rawequalObj(o1, o2);
279}
280
281
282LUA_API int lua_equal (lua_State *L, int index1, int index2) {
283 StkId o1, o2;
284 int i;
285 lua_lock(L); /* may call tag method */
286 o1 = index2adr(L, index1);
287 o2 = index2adr(L, index2);
288 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
289 lua_unlock(L);
290 return i;
291}
292
293
294LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
295 StkId o1, o2;
296 int i;
297 lua_lock(L); /* may call tag method */
298 o1 = index2adr(L, index1);
299 o2 = index2adr(L, index2);
300 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
301 : luaV_lessthan(L, o1, o2);
302 lua_unlock(L);
303 return i;
304}
305
306
307
308LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
309 TValue n;
310 const TValue *o = index2adr(L, idx);
311 if (tonumber(o, &n))
312 return nvalue(o);
313 else
314 return 0;
315}
316
317
318LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
319 TValue n;
320 const TValue *o = index2adr(L, idx);
321 if (tonumber(o, &n)) {
322 lua_Integer res;
323 lua_Number num = nvalue(o);
324 lua_number2integer(res, num);
325 return res;
326 }
327 else
328 return 0;
329}
330
331
332LUA_API int lua_toboolean (lua_State *L, int idx) {
333 const TValue *o = index2adr(L, idx);
334 return !l_isfalse(o);
335}
336
337
338LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
339 StkId o = index2adr(L, idx);
340 if (!ttisstring(o)) {
341 lua_lock(L); /* `luaV_tostring' may create a new string */
342 if (!luaV_tostring(L, o)) { /* conversion failed? */
343 if (len != NULL) *len = 0;
344 lua_unlock(L);
345 return NULL;
346 }
347 luaC_checkGC(L);
348 o = index2adr(L, idx); /* previous call may reallocate the stack */
349 lua_unlock(L);
350 }
351 if (len != NULL) *len = tsvalue(o)->len;
352 return svalue(o);
353}
354
355
356LUA_API size_t lua_objlen (lua_State *L, int idx) {
357 StkId o = index2adr(L, idx);
358 switch (ttype(o)) {
359 case LUA_TSTRING: return tsvalue(o)->len;
360 case LUA_TUSERDATA: return uvalue(o)->len;
361 case LUA_TTABLE: return luaH_getn(hvalue(o));
362 case LUA_TNUMBER: {
363 size_t l;
364 lua_lock(L); /* `luaV_tostring' may create a new string */
365 l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
366 lua_unlock(L);
367 return l;
368 }
369 default: return 0;
370 }
371}
372
373
374LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
375 StkId o = index2adr(L, idx);
376 return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
377}
378
379
380LUA_API void *lua_touserdata (lua_State *L, int idx) {
381 StkId o = index2adr(L, idx);
382 switch (ttype(o)) {
383 case LUA_TUSERDATA: return (rawuvalue(o) + 1);
384 case LUA_TLIGHTUSERDATA: return pvalue(o);
385 default: return NULL;
386 }
387}
388
389
390LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
391 StkId o = index2adr(L, idx);
392 return (!ttisthread(o)) ? NULL : thvalue(o);
393}
394
395
396LUA_API const void *lua_topointer (lua_State *L, int idx) {
397 StkId o = index2adr(L, idx);
398 switch (ttype(o)) {
399 case LUA_TTABLE: return hvalue(o);
400 case LUA_TFUNCTION: return clvalue(o);
401 case LUA_TTHREAD: return thvalue(o);
402 case LUA_TUSERDATA:
403 case LUA_TLIGHTUSERDATA:
404 return lua_touserdata(L, idx);
405 default: return NULL;
406 }
407}
408
409
410
411/*
412** push functions (C -> stack)
413*/
414
415
416LUA_API void lua_pushnil (lua_State *L) {
417 lua_lock(L);
418 setnilvalue(L->top);
419 api_incr_top(L);
420 lua_unlock(L);
421}
422
423
424LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
425 lua_lock(L);
426 setnvalue(L->top, n);
427 api_incr_top(L);
428 lua_unlock(L);
429}
430
431
432LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
433 lua_lock(L);
434 setnvalue(L->top, cast_num(n));
435 api_incr_top(L);
436 lua_unlock(L);
437}
438
439
440LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
441 lua_lock(L);
442 luaC_checkGC(L);
443 setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
444 api_incr_top(L);
445 lua_unlock(L);
446}
447
448
449LUA_API void lua_pushstring (lua_State *L, const char *s) {
450 if (s == NULL)
451 lua_pushnil(L);
452 else
453 lua_pushlstring(L, s, strlen(s));
454}
455
456
457LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
458 va_list argp) {
459 const char *ret;
460 lua_lock(L);
461 luaC_checkGC(L);
462 ret = luaO_pushvfstring(L, fmt, argp);
463 lua_unlock(L);
464 return ret;
465}
466
467
468LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
469 const char *ret;
470 va_list argp;
471 lua_lock(L);
472 luaC_checkGC(L);
473 va_start(argp, fmt);
474 ret = luaO_pushvfstring(L, fmt, argp);
475 va_end(argp);
476 lua_unlock(L);
477 return ret;
478}
479
480
481LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
482 Closure *cl;
483 lua_lock(L);
484 luaC_checkGC(L);
485 api_checknelems(L, n);
486 cl = luaF_newCclosure(L, n, getcurrenv(L));
487 cl->c.f = fn;
488 L->top -= n;
489 while (n--)
490 setobj2n(L, &cl->c.upvalue[n], L->top+n);
491 setclvalue(L, L->top, cl);
492 lua_assert(iswhite(obj2gco(cl)));
493 api_incr_top(L);
494 lua_unlock(L);
495}
496
497
498LUA_API void lua_pushboolean (lua_State *L, int b) {
499 lua_lock(L);
500 setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
501 api_incr_top(L);
502 lua_unlock(L);
503}
504
505
506LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
507 lua_lock(L);
508 setpvalue(L->top, p);
509 api_incr_top(L);
510 lua_unlock(L);
511}
512
513
514LUA_API int lua_pushthread (lua_State *L) {
515 lua_lock(L);
516 setthvalue(L, L->top, L);
517 api_incr_top(L);
518 lua_unlock(L);
519 return (G(L)->mainthread == L);
520}
521
522
523
524/*
525** get functions (Lua -> stack)
526*/
527
528
529LUA_API void lua_gettable (lua_State *L, int idx) {
530 StkId t;
531 lua_lock(L);
532 t = index2adr(L, idx);
533 api_checkvalidindex(L, t);
534 luaV_gettable(L, t, L->top - 1, L->top - 1);
535 lua_unlock(L);
536}
537
538
539LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
540 StkId t;
541 TValue key;
542 lua_lock(L);
543 t = index2adr(L, idx);
544 api_checkvalidindex(L, t);
545 setsvalue(L, &key, luaS_new(L, k));
546 luaV_gettable(L, t, &key, L->top);
547 api_incr_top(L);
548 lua_unlock(L);
549}
550
551
552LUA_API void lua_rawget (lua_State *L, int idx) {
553 StkId t;
554 lua_lock(L);
555 t = index2adr(L, idx);
556 api_check(L, ttistable(t));
557 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
558 lua_unlock(L);
559}
560
561
562LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
563 StkId o;
564 lua_lock(L);
565 o = index2adr(L, idx);
566 api_check(L, ttistable(o));
567 setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
568 api_incr_top(L);
569 lua_unlock(L);
570}
571
572
573LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
574 lua_lock(L);
575 luaC_checkGC(L);
576 sethvalue(L, L->top, luaH_new(L, narray, nrec));
577 api_incr_top(L);
578 lua_unlock(L);
579}
580
581
582LUA_API int lua_getmetatable (lua_State *L, int objindex) {
583 const TValue *obj;
584 Table *mt = NULL;
585 int res;
586 lua_lock(L);
587 obj = index2adr(L, objindex);
588 switch (ttype(obj)) {
589 case LUA_TTABLE:
590 mt = hvalue(obj)->metatable;
591 break;
592 case LUA_TUSERDATA:
593 mt = uvalue(obj)->metatable;
594 break;
595 default:
596 mt = G(L)->mt[ttype(obj)];
597 break;
598 }
599 if (mt == NULL)
600 res = 0;
601 else {
602 sethvalue(L, L->top, mt);
603 api_incr_top(L);
604 res = 1;
605 }
606 lua_unlock(L);
607 return res;
608}
609
610
611LUA_API void lua_getfenv (lua_State *L, int idx) {
612 StkId o;
613 lua_lock(L);
614 o = index2adr(L, idx);
615 api_checkvalidindex(L, o);
616 switch (ttype(o)) {
617 case LUA_TFUNCTION:
618 sethvalue(L, L->top, clvalue(o)->c.env);
619 break;
620 case LUA_TUSERDATA:
621 sethvalue(L, L->top, uvalue(o)->env);
622 break;
623 case LUA_TTHREAD:
624 setobj2s(L, L->top, gt(thvalue(o)));
625 break;
626 default:
627 setnilvalue(L->top);
628 break;
629 }
630 api_incr_top(L);
631 lua_unlock(L);
632}
633
634
635/*
636** set functions (stack -> Lua)
637*/
638
639
640LUA_API void lua_settable (lua_State *L, int idx) {
641 StkId t;
642 lua_lock(L);
643 api_checknelems(L, 2);
644 t = index2adr(L, idx);
645 api_checkvalidindex(L, t);
646 luaV_settable(L, t, L->top - 2, L->top - 1);
647 L->top -= 2; /* pop index and value */
648 lua_unlock(L);
649}
650
651
652LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
653 StkId t;
654 TValue key;
655 lua_lock(L);
656 api_checknelems(L, 1);
657 t = index2adr(L, idx);
658 api_checkvalidindex(L, t);
659 setsvalue(L, &key, luaS_new(L, k));
660 luaV_settable(L, t, &key, L->top - 1);
661 L->top--; /* pop value */
662 lua_unlock(L);
663}
664
665
666LUA_API void lua_rawset (lua_State *L, int idx) {
667 StkId t;
668 lua_lock(L);
669 api_checknelems(L, 2);
670 t = index2adr(L, idx);
671 api_check(L, ttistable(t));
672 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
673 luaC_barriert(L, hvalue(t), L->top-1);
674 L->top -= 2;
675 lua_unlock(L);
676}
677
678
679LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
680 StkId o;
681 lua_lock(L);
682 api_checknelems(L, 1);
683 o = index2adr(L, idx);
684 api_check(L, ttistable(o));
685 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
686 luaC_barriert(L, hvalue(o), L->top-1);
687 L->top--;
688 lua_unlock(L);
689}
690
691
692LUA_API int lua_setmetatable (lua_State *L, int objindex) {
693 TValue *obj;
694 Table *mt;
695 lua_lock(L);
696 api_checknelems(L, 1);
697 obj = index2adr(L, objindex);
698 api_checkvalidindex(L, obj);
699 if (ttisnil(L->top - 1))
700 mt = NULL;
701 else {
702 api_check(L, ttistable(L->top - 1));
703 mt = hvalue(L->top - 1);
704 }
705 switch (ttype(obj)) {
706 case LUA_TTABLE: {
707 hvalue(obj)->metatable = mt;
708 if (mt)
709 luaC_objbarriert(L, hvalue(obj), mt);
710 break;
711 }
712 case LUA_TUSERDATA: {
713 uvalue(obj)->metatable = mt;
714 if (mt)
715 luaC_objbarrier(L, rawuvalue(obj), mt);
716 break;
717 }
718 default: {
719 G(L)->mt[ttype(obj)] = mt;
720 break;
721 }
722 }
723 L->top--;
724 lua_unlock(L);
725 return 1;
726}
727
728
729LUA_API int lua_setfenv (lua_State *L, int idx) {
730 StkId o;
731 int res = 1;
732 lua_lock(L);
733 api_checknelems(L, 1);
734 o = index2adr(L, idx);
735 api_checkvalidindex(L, o);
736 api_check(L, ttistable(L->top - 1));
737 switch (ttype(o)) {
738 case LUA_TFUNCTION:
739 clvalue(o)->c.env = hvalue(L->top - 1);
740 break;
741 case LUA_TUSERDATA:
742 uvalue(o)->env = hvalue(L->top - 1);
743 break;
744 case LUA_TTHREAD:
745 sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
746 break;
747 default:
748 res = 0;
749 break;
750 }
751 if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
752 L->top--;
753 lua_unlock(L);
754 return res;
755}
756
757
758/*
759** `load' and `call' functions (run Lua code)
760*/
761
762
763#define adjustresults(L,nres) \
764 { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
765
766
767#define checkresults(L,na,nr) \
768 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
769
770
771LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
772 StkId func;
773 lua_lock(L);
774 api_checknelems(L, nargs+1);
775 checkresults(L, nargs, nresults);
776 func = L->top - (nargs+1);
777 luaD_call(L, func, nresults);
778 adjustresults(L, nresults);
779 lua_unlock(L);
780}
781
782
783
784/*
785** Execute a protected call.
786*/
787struct CallS { /* data to `f_call' */
788 StkId func;
789 int nresults;
790};
791
792
793static void f_call (lua_State *L, void *ud) {
794 struct CallS *c = cast(struct CallS *, ud);
795 luaD_call(L, c->func, c->nresults);
796}
797
798
799
800LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
801 struct CallS c;
802 int status;
803 ptrdiff_t func;
804 lua_lock(L);
805 api_checknelems(L, nargs+1);
806 checkresults(L, nargs, nresults);
807 if (errfunc == 0)
808 func = 0;
809 else {
810 StkId o = index2adr(L, errfunc);
811 api_checkvalidindex(L, o);
812 func = savestack(L, o);
813 }
814 c.func = L->top - (nargs+1); /* function to be called */
815 c.nresults = nresults;
816 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
817 adjustresults(L, nresults);
818 lua_unlock(L);
819 return status;
820}
821
822
823/*
824** Execute a protected C call.
825*/
826struct CCallS { /* data to `f_Ccall' */
827 lua_CFunction func;
828 void *ud;
829};
830
831
832static void f_Ccall (lua_State *L, void *ud) {
833 struct CCallS *c = cast(struct CCallS *, ud);
834 Closure *cl;
835 cl = luaF_newCclosure(L, 0, getcurrenv(L));
836 cl->c.f = c->func;
837 setclvalue(L, L->top, cl); /* push function */
838 api_incr_top(L);
839 setpvalue(L->top, c->ud); /* push only argument */
840 api_incr_top(L);
841 luaD_call(L, L->top - 2, 0);
842}
843
844
845LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
846 struct CCallS c;
847 int status;
848 lua_lock(L);
849 c.func = func;
850 c.ud = ud;
851 status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
852 lua_unlock(L);
853 return status;
854}
855
856
857LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
858 const char *chunkname) {
859 ZIO z;
860 int status;
861 lua_lock(L);
862 if (!chunkname) chunkname = "?";
863 luaZ_init(L, &z, reader, data);
864 status = luaD_protectedparser(L, &z, chunkname);
865 lua_unlock(L);
866 return status;
867}
868
869
870LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
871 int status;
872 TValue *o;
873 lua_lock(L);
874 api_checknelems(L, 1);
875 o = L->top - 1;
876 if (isLfunction(o))
877 status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
878 else
879 status = 1;
880 lua_unlock(L);
881 return status;
882}
883
884
885LUA_API int lua_status (lua_State *L) {
886 return L->status;
887}
888
889
890/*
891** Garbage-collection function
892*/
893
894LUA_API int lua_gc (lua_State *L, int what, int data) {
895 int res = 0;
896 global_State *g;
897 lua_lock(L);
898 g = G(L);
899 switch (what) {
900 case LUA_GCSTOP: {
901 g->GCthreshold = MAX_LUMEM;
902 break;
903 }
904 case LUA_GCRESTART: {
905 g->GCthreshold = g->totalbytes;
906 break;
907 }
908 case LUA_GCCOLLECT: {
909 luaC_fullgc(L);
910 break;
911 }
912 case LUA_GCCOUNT: {
913 /* GC values are expressed in Kbytes: #bytes/2^10 */
914 res = cast_int(g->totalbytes >> 10);
915 break;
916 }
917 case LUA_GCCOUNTB: {
918 res = cast_int(g->totalbytes & 0x3ff);
919 break;
920 }
921 case LUA_GCSTEP: {
922 lu_mem a = (cast(lu_mem, data) << 10);
923 if (a <= g->totalbytes)
924 g->GCthreshold = g->totalbytes - a;
925 else
926 g->GCthreshold = 0;
927 while (g->GCthreshold <= g->totalbytes) {
928 luaC_step(L);
929 if (g->gcstate == GCSpause) { /* end of cycle? */
930 res = 1; /* signal it */
931 break;
932 }
933 }
934 break;
935 }
936 case LUA_GCSETPAUSE: {
937 res = g->gcpause;
938 g->gcpause = data;
939 break;
940 }
941 case LUA_GCSETSTEPMUL: {
942 res = g->gcstepmul;
943 g->gcstepmul = data;
944 break;
945 }
946 default: res = -1; /* invalid option */
947 }
948 lua_unlock(L);
949 return res;
950}
951
952
953
954/*
955** miscellaneous functions
956*/
957
958
959LUA_API int lua_error (lua_State *L) {
960 lua_lock(L);
961 api_checknelems(L, 1);
962 luaG_errormsg(L);
963 lua_unlock(L);
964 return 0; /* to avoid warnings */
965}
966
967
968LUA_API int lua_next (lua_State *L, int idx) {
969 StkId t;
970 int more;
971 lua_lock(L);
972 t = index2adr(L, idx);
973 api_check(L, ttistable(t));
974 more = luaH_next(L, hvalue(t), L->top - 1);
975 if (more) {
976 api_incr_top(L);
977 }
978 else /* no more elements */
979 L->top -= 1; /* remove key */
980 lua_unlock(L);
981 return more;
982}
983
984
985LUA_API void lua_concat (lua_State *L, int n) {
986 lua_lock(L);
987 api_checknelems(L, n);
988 if (n >= 2) {
989 luaC_checkGC(L);
990 luaV_concat(L, n, cast_int(L->top - L->base) - 1);
991 L->top -= (n-1);
992 }
993 else if (n == 0) { /* push empty string */
994 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
995 api_incr_top(L);
996 }
997 /* else n == 1; nothing to do */
998 lua_unlock(L);
999}
1000
1001
1002LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1003 lua_Alloc f;
1004 lua_lock(L);
1005 if (ud) *ud = G(L)->ud;
1006 f = G(L)->frealloc;
1007 lua_unlock(L);
1008 return f;
1009}
1010
1011
1012LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1013 lua_lock(L);
1014 G(L)->ud = ud;
1015 G(L)->frealloc = f;
1016 lua_unlock(L);
1017}
1018
1019
1020LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1021 Udata *u;
1022 lua_lock(L);
1023 luaC_checkGC(L);
1024 u = luaS_newudata(L, size, getcurrenv(L));
1025 setuvalue(L, L->top, u);
1026 api_incr_top(L);
1027 lua_unlock(L);
1028 return u + 1;
1029}
1030
1031
1032
1033
1034static const char *aux_upvalue (StkId fi, int n, TValue **val) {
1035 Closure *f;
1036 if (!ttisfunction(fi)) return NULL;
1037 f = clvalue(fi);
1038 if (f->c.isC) {
1039 if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
1040 *val = &f->c.upvalue[n-1];
1041 return "";
1042 }
1043 else {
1044 Proto *p = f->l.p;
1045 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1046 *val = f->l.upvals[n-1]->v;
1047 return getstr(p->upvalues[n-1]);
1048 }
1049}
1050
1051
1052LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1053 const char *name;
1054 TValue *val;
1055 lua_lock(L);
1056 name = aux_upvalue(index2adr(L, funcindex), n, &val);
1057 if (name) {
1058 setobj2s(L, L->top, val);
1059 api_incr_top(L);
1060 }
1061 lua_unlock(L);
1062 return name;
1063}
1064
1065
1066LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1067 const char *name;
1068 TValue *val;
1069 StkId fi;
1070 lua_lock(L);
1071 fi = index2adr(L, funcindex);
1072 api_checknelems(L, 1);
1073 name = aux_upvalue(fi, n, &val);
1074 if (name) {
1075 L->top--;
1076 setobj(L, val, L->top);
1077 luaC_barrier(L, clvalue(fi), L->top);
1078 }
1079 lua_unlock(L);
1080 return name;
1081}
1082
diff --git a/libraries/LuaJIT-1.1.7/src/lapi.h b/libraries/LuaJIT-1.1.7/src/lapi.h
new file mode 100644
index 0000000..2c3fab2
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lapi.h
@@ -0,0 +1,16 @@
1/*
2** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $
3** Auxiliary functions from Lua API
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lapi_h
8#define lapi_h
9
10
11#include "lobject.h"
12
13
14LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
15
16#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lauxlib.c b/libraries/LuaJIT-1.1.7/src/lauxlib.c
new file mode 100644
index 0000000..10f14e2
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lauxlib.c
@@ -0,0 +1,652 @@
1/*
2** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <errno.h>
10#include <stdarg.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15
16/* This file uses only the official API of Lua.
17** Any function declared here could be written as an application function.
18*/
19
20#define lauxlib_c
21#define LUA_LIB
22
23#include "lua.h"
24
25#include "lauxlib.h"
26
27
28#define FREELIST_REF 0 /* free list of references */
29
30
31/* convert a stack index to positive */
32#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
33 lua_gettop(L) + (i) + 1)
34
35
36/*
37** {======================================================
38** Error-report functions
39** =======================================================
40*/
41
42
43LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
44 lua_Debug ar;
45 if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
46 return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
47 lua_getinfo(L, "n", &ar);
48 if (strcmp(ar.namewhat, "method") == 0) {
49 narg--; /* do not count `self' */
50 if (narg == 0) /* error is in the self argument itself? */
51 return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
52 ar.name, extramsg);
53 }
54 if (ar.name == NULL)
55 ar.name = "?";
56 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
57 narg, ar.name, extramsg);
58}
59
60
61LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
62 const char *msg = lua_pushfstring(L, "%s expected, got %s",
63 tname, luaL_typename(L, narg));
64 return luaL_argerror(L, narg, msg);
65}
66
67
68static void tag_error (lua_State *L, int narg, int tag) {
69 luaL_typerror(L, narg, lua_typename(L, tag));
70}
71
72
73LUALIB_API void luaL_where (lua_State *L, int level) {
74 lua_Debug ar;
75 if (lua_getstack(L, level, &ar)) { /* check function at level */
76 lua_getinfo(L, "Sl", &ar); /* get info about it */
77 if (ar.currentline > 0) { /* is there info? */
78 lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
79 return;
80 }
81 }
82 lua_pushliteral(L, ""); /* else, no information available... */
83}
84
85
86LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
87 va_list argp;
88 va_start(argp, fmt);
89 luaL_where(L, 1);
90 lua_pushvfstring(L, fmt, argp);
91 va_end(argp);
92 lua_concat(L, 2);
93 return lua_error(L);
94}
95
96/* }====================================================== */
97
98
99LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
100 const char *const lst[]) {
101 const char *name = (def) ? luaL_optstring(L, narg, def) :
102 luaL_checkstring(L, narg);
103 int i;
104 for (i=0; lst[i]; i++)
105 if (strcmp(lst[i], name) == 0)
106 return i;
107 return luaL_argerror(L, narg,
108 lua_pushfstring(L, "invalid option " LUA_QS, name));
109}
110
111
112LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
113 lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
114 if (!lua_isnil(L, -1)) /* name already in use? */
115 return 0; /* leave previous value on top, but return 0 */
116 lua_pop(L, 1);
117 lua_newtable(L); /* create metatable */
118 lua_pushvalue(L, -1);
119 lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
120 return 1;
121}
122
123
124LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
125 void *p = lua_touserdata(L, ud);
126 if (p != NULL) { /* value is a userdata? */
127 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
128 lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
129 if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
130 lua_pop(L, 2); /* remove both metatables */
131 return p;
132 }
133 }
134 }
135 luaL_typerror(L, ud, tname); /* else error */
136 return NULL; /* to avoid warnings */
137}
138
139
140LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
141 if (!lua_checkstack(L, space))
142 luaL_error(L, "stack overflow (%s)", mes);
143}
144
145
146LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
147 if (lua_type(L, narg) != t)
148 tag_error(L, narg, t);
149}
150
151
152LUALIB_API void luaL_checkany (lua_State *L, int narg) {
153 if (lua_type(L, narg) == LUA_TNONE)
154 luaL_argerror(L, narg, "value expected");
155}
156
157
158LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
159 const char *s = lua_tolstring(L, narg, len);
160 if (!s) tag_error(L, narg, LUA_TSTRING);
161 return s;
162}
163
164
165LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
166 const char *def, size_t *len) {
167 if (lua_isnoneornil(L, narg)) {
168 if (len)
169 *len = (def ? strlen(def) : 0);
170 return def;
171 }
172 else return luaL_checklstring(L, narg, len);
173}
174
175
176LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
177 lua_Number d = lua_tonumber(L, narg);
178 if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
179 tag_error(L, narg, LUA_TNUMBER);
180 return d;
181}
182
183
184LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
185 return luaL_opt(L, luaL_checknumber, narg, def);
186}
187
188
189LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
190 lua_Integer d = lua_tointeger(L, narg);
191 if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
192 tag_error(L, narg, LUA_TNUMBER);
193 return d;
194}
195
196
197LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
198 lua_Integer def) {
199 return luaL_opt(L, luaL_checkinteger, narg, def);
200}
201
202
203LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
204 if (!lua_getmetatable(L, obj)) /* no metatable? */
205 return 0;
206 lua_pushstring(L, event);
207 lua_rawget(L, -2);
208 if (lua_isnil(L, -1)) {
209 lua_pop(L, 2); /* remove metatable and metafield */
210 return 0;
211 }
212 else {
213 lua_remove(L, -2); /* remove only metatable */
214 return 1;
215 }
216}
217
218
219LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
220 obj = abs_index(L, obj);
221 if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
222 return 0;
223 lua_pushvalue(L, obj);
224 lua_call(L, 1, 1);
225 return 1;
226}
227
228
229LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
230 const luaL_Reg *l) {
231 luaI_openlib(L, libname, l, 0);
232}
233
234
235static int libsize (const luaL_Reg *l) {
236 int size = 0;
237 for (; l->name; l++) size++;
238 return size;
239}
240
241
242LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
243 const luaL_Reg *l, int nup) {
244 if (libname) {
245 int size = libsize(l);
246 /* check whether lib already exists */
247 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
248 lua_getfield(L, -1, libname); /* get _LOADED[libname] */
249 if (!lua_istable(L, -1)) { /* not found? */
250 lua_pop(L, 1); /* remove previous result */
251 /* try global variable (and create one if it does not exist) */
252 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
253 luaL_error(L, "name conflict for module " LUA_QS, libname);
254 lua_pushvalue(L, -1);
255 lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
256 }
257 lua_remove(L, -2); /* remove _LOADED table */
258 lua_insert(L, -(nup+1)); /* move library table to below upvalues */
259 }
260 for (; l->name; l++) {
261 int i;
262 for (i=0; i<nup; i++) /* copy upvalues to the top */
263 lua_pushvalue(L, -nup);
264 lua_pushcclosure(L, l->func, nup);
265 lua_setfield(L, -(nup+2), l->name);
266 }
267 lua_pop(L, nup); /* remove upvalues */
268}
269
270
271
272/*
273** {======================================================
274** getn-setn: size for arrays
275** =======================================================
276*/
277
278#if defined(LUA_COMPAT_GETN)
279
280static int checkint (lua_State *L, int topop) {
281 int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
282 lua_pop(L, topop);
283 return n;
284}
285
286
287static void getsizes (lua_State *L) {
288 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
289 if (lua_isnil(L, -1)) { /* no `size' table? */
290 lua_pop(L, 1); /* remove nil */
291 lua_newtable(L); /* create it */
292 lua_pushvalue(L, -1); /* `size' will be its own metatable */
293 lua_setmetatable(L, -2);
294 lua_pushliteral(L, "kv");
295 lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
296 lua_pushvalue(L, -1);
297 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
298 }
299}
300
301
302LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
303 t = abs_index(L, t);
304 lua_pushliteral(L, "n");
305 lua_rawget(L, t);
306 if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
307 lua_pushliteral(L, "n"); /* use it */
308 lua_pushinteger(L, n);
309 lua_rawset(L, t);
310 }
311 else { /* use `sizes' */
312 getsizes(L);
313 lua_pushvalue(L, t);
314 lua_pushinteger(L, n);
315 lua_rawset(L, -3); /* sizes[t] = n */
316 lua_pop(L, 1); /* remove `sizes' */
317 }
318}
319
320
321LUALIB_API int luaL_getn (lua_State *L, int t) {
322 int n;
323 t = abs_index(L, t);
324 lua_pushliteral(L, "n"); /* try t.n */
325 lua_rawget(L, t);
326 if ((n = checkint(L, 1)) >= 0) return n;
327 getsizes(L); /* else try sizes[t] */
328 lua_pushvalue(L, t);
329 lua_rawget(L, -2);
330 if ((n = checkint(L, 2)) >= 0) return n;
331 return (int)lua_objlen(L, t);
332}
333
334#endif
335
336/* }====================================================== */
337
338
339
340LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
341 const char *r) {
342 const char *wild;
343 size_t l = strlen(p);
344 luaL_Buffer b;
345 luaL_buffinit(L, &b);
346 while ((wild = strstr(s, p)) != NULL) {
347 luaL_addlstring(&b, s, wild - s); /* push prefix */
348 luaL_addstring(&b, r); /* push replacement in place of pattern */
349 s = wild + l; /* continue after `p' */
350 }
351 luaL_addstring(&b, s); /* push last suffix */
352 luaL_pushresult(&b);
353 return lua_tostring(L, -1);
354}
355
356
357LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
358 const char *fname, int szhint) {
359 const char *e;
360 lua_pushvalue(L, idx);
361 do {
362 e = strchr(fname, '.');
363 if (e == NULL) e = fname + strlen(fname);
364 lua_pushlstring(L, fname, e - fname);
365 lua_rawget(L, -2);
366 if (lua_isnil(L, -1)) { /* no such field? */
367 lua_pop(L, 1); /* remove this nil */
368 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
369 lua_pushlstring(L, fname, e - fname);
370 lua_pushvalue(L, -2);
371 lua_settable(L, -4); /* set new table into field */
372 }
373 else if (!lua_istable(L, -1)) { /* field has a non-table value? */
374 lua_pop(L, 2); /* remove table and value */
375 return fname; /* return problematic part of the name */
376 }
377 lua_remove(L, -2); /* remove previous table */
378 fname = e + 1;
379 } while (*e == '.');
380 return NULL;
381}
382
383
384
385/*
386** {======================================================
387** Generic Buffer manipulation
388** =======================================================
389*/
390
391
392#define bufflen(B) ((B)->p - (B)->buffer)
393#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
394
395#define LIMIT (LUA_MINSTACK/2)
396
397
398static int emptybuffer (luaL_Buffer *B) {
399 size_t l = bufflen(B);
400 if (l == 0) return 0; /* put nothing on stack */
401 else {
402 lua_pushlstring(B->L, B->buffer, l);
403 B->p = B->buffer;
404 B->lvl++;
405 return 1;
406 }
407}
408
409
410static void adjuststack (luaL_Buffer *B) {
411 if (B->lvl > 1) {
412 lua_State *L = B->L;
413 int toget = 1; /* number of levels to concat */
414 size_t toplen = lua_strlen(L, -1);
415 do {
416 size_t l = lua_strlen(L, -(toget+1));
417 if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
418 toplen += l;
419 toget++;
420 }
421 else break;
422 } while (toget < B->lvl);
423 lua_concat(L, toget);
424 B->lvl = B->lvl - toget + 1;
425 }
426}
427
428
429LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
430 if (emptybuffer(B))
431 adjuststack(B);
432 return B->buffer;
433}
434
435
436LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
437 while (l--)
438 luaL_addchar(B, *s++);
439}
440
441
442LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
443 luaL_addlstring(B, s, strlen(s));
444}
445
446
447LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
448 emptybuffer(B);
449 lua_concat(B->L, B->lvl);
450 B->lvl = 1;
451}
452
453
454LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
455 lua_State *L = B->L;
456 size_t vl;
457 const char *s = lua_tolstring(L, -1, &vl);
458 if (vl <= bufffree(B)) { /* fit into buffer? */
459 memcpy(B->p, s, vl); /* put it there */
460 B->p += vl;
461 lua_pop(L, 1); /* remove from stack */
462 }
463 else {
464 if (emptybuffer(B))
465 lua_insert(L, -2); /* put buffer before new value */
466 B->lvl++; /* add new value into B stack */
467 adjuststack(B);
468 }
469}
470
471
472LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
473 B->L = L;
474 B->p = B->buffer;
475 B->lvl = 0;
476}
477
478/* }====================================================== */
479
480
481LUALIB_API int luaL_ref (lua_State *L, int t) {
482 int ref;
483 t = abs_index(L, t);
484 if (lua_isnil(L, -1)) {
485 lua_pop(L, 1); /* remove from stack */
486 return LUA_REFNIL; /* `nil' has a unique fixed reference */
487 }
488 lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
489 ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
490 lua_pop(L, 1); /* remove it from stack */
491 if (ref != 0) { /* any free element? */
492 lua_rawgeti(L, t, ref); /* remove it from list */
493 lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
494 }
495 else { /* no free elements */
496 ref = (int)lua_objlen(L, t);
497 ref++; /* create new reference */
498 }
499 lua_rawseti(L, t, ref);
500 return ref;
501}
502
503
504LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
505 if (ref >= 0) {
506 t = abs_index(L, t);
507 lua_rawgeti(L, t, FREELIST_REF);
508 lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
509 lua_pushinteger(L, ref);
510 lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
511 }
512}
513
514
515
516/*
517** {======================================================
518** Load functions
519** =======================================================
520*/
521
522typedef struct LoadF {
523 int extraline;
524 FILE *f;
525 char buff[LUAL_BUFFERSIZE];
526} LoadF;
527
528
529static const char *getF (lua_State *L, void *ud, size_t *size) {
530 LoadF *lf = (LoadF *)ud;
531 (void)L;
532 if (lf->extraline) {
533 lf->extraline = 0;
534 *size = 1;
535 return "\n";
536 }
537 if (feof(lf->f)) return NULL;
538 *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
539 return (*size > 0) ? lf->buff : NULL;
540}
541
542
543static int errfile (lua_State *L, const char *what, int fnameindex) {
544 const char *serr = strerror(errno);
545 const char *filename = lua_tostring(L, fnameindex) + 1;
546 lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
547 lua_remove(L, fnameindex);
548 return LUA_ERRFILE;
549}
550
551
552LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
553 LoadF lf;
554 int status, readstatus;
555 int c;
556 int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
557 lf.extraline = 0;
558 if (filename == NULL) {
559 lua_pushliteral(L, "=stdin");
560 lf.f = stdin;
561 }
562 else {
563 lua_pushfstring(L, "@%s", filename);
564 lf.f = fopen(filename, "r");
565 if (lf.f == NULL) return errfile(L, "open", fnameindex);
566 }
567 c = getc(lf.f);
568 if (c == '#') { /* Unix exec. file? */
569 lf.extraline = 1;
570 while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
571 if (c == '\n') c = getc(lf.f);
572 }
573 if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
574 lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
575 if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
576 /* skip eventual `#!...' */
577 while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
578 lf.extraline = 0;
579 }
580 ungetc(c, lf.f);
581 status = lua_load(L, getF, &lf, lua_tostring(L, -1));
582 readstatus = ferror(lf.f);
583 if (filename) fclose(lf.f); /* close file (even in case of errors) */
584 if (readstatus) {
585 lua_settop(L, fnameindex); /* ignore results from `lua_load' */
586 return errfile(L, "read", fnameindex);
587 }
588 lua_remove(L, fnameindex);
589 return status;
590}
591
592
593typedef struct LoadS {
594 const char *s;
595 size_t size;
596} LoadS;
597
598
599static const char *getS (lua_State *L, void *ud, size_t *size) {
600 LoadS *ls = (LoadS *)ud;
601 (void)L;
602 if (ls->size == 0) return NULL;
603 *size = ls->size;
604 ls->size = 0;
605 return ls->s;
606}
607
608
609LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
610 const char *name) {
611 LoadS ls;
612 ls.s = buff;
613 ls.size = size;
614 return lua_load(L, getS, &ls, name);
615}
616
617
618LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
619 return luaL_loadbuffer(L, s, strlen(s), s);
620}
621
622
623
624/* }====================================================== */
625
626
627static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
628 (void)ud;
629 (void)osize;
630 if (nsize == 0) {
631 free(ptr);
632 return NULL;
633 }
634 else
635 return realloc(ptr, nsize);
636}
637
638
639static int panic (lua_State *L) {
640 (void)L; /* to avoid warnings */
641 fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
642 lua_tostring(L, -1));
643 return 0;
644}
645
646
647LUALIB_API lua_State *luaL_newstate (void) {
648 lua_State *L = lua_newstate(l_alloc, NULL);
649 if (L) lua_atpanic(L, &panic);
650 return L;
651}
652
diff --git a/libraries/LuaJIT-1.1.7/src/lauxlib.h b/libraries/LuaJIT-1.1.7/src/lauxlib.h
new file mode 100644
index 0000000..3425823
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lauxlib.h
@@ -0,0 +1,174 @@
1/*
2** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lauxlib_h
9#define lauxlib_h
10
11
12#include <stddef.h>
13#include <stdio.h>
14
15#include "lua.h"
16
17
18#if defined(LUA_COMPAT_GETN)
19LUALIB_API int (luaL_getn) (lua_State *L, int t);
20LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
21#else
22#define luaL_getn(L,i) ((int)lua_objlen(L, i))
23#define luaL_setn(L,i,j) ((void)0) /* no op! */
24#endif
25
26#if defined(LUA_COMPAT_OPENLIB)
27#define luaI_openlib luaL_openlib
28#endif
29
30
31/* extra error code for `luaL_load' */
32#define LUA_ERRFILE (LUA_ERRERR+1)
33
34
35typedef struct luaL_Reg {
36 const char *name;
37 lua_CFunction func;
38} luaL_Reg;
39
40
41
42LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
43 const luaL_Reg *l, int nup);
44LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
45 const luaL_Reg *l);
46LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
47LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
48LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
49LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
50LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
51 size_t *l);
52LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
53 const char *def, size_t *l);
54LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
55LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
56
57LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
58LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
59 lua_Integer def);
60
61LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
62LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
63LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
64
65LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
66LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
67
68LUALIB_API void (luaL_where) (lua_State *L, int lvl);
69LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
70
71LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
72 const char *const lst[]);
73
74LUALIB_API int (luaL_ref) (lua_State *L, int t);
75LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
76
77LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
78LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
79 const char *name);
80LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
81
82LUALIB_API lua_State *(luaL_newstate) (void);
83
84
85LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
86 const char *r);
87
88LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
89 const char *fname, int szhint);
90
91
92
93
94/*
95** ===============================================================
96** some useful macros
97** ===============================================================
98*/
99
100#define luaL_argcheck(L, cond,numarg,extramsg) \
101 ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
102#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
103#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
104#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
105#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
106#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
107#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
108
109#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
110
111#define luaL_dofile(L, fn) \
112 (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
113
114#define luaL_dostring(L, s) \
115 (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
116
117#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
118
119#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
120
121/*
122** {======================================================
123** Generic Buffer manipulation
124** =======================================================
125*/
126
127
128
129typedef struct luaL_Buffer {
130 char *p; /* current position in buffer */
131 int lvl; /* number of strings in the stack (level) */
132 lua_State *L;
133 char buffer[LUAL_BUFFERSIZE];
134} luaL_Buffer;
135
136#define luaL_addchar(B,c) \
137 ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
138 (*(B)->p++ = (char)(c)))
139
140/* compatibility only */
141#define luaL_putchar(B,c) luaL_addchar(B,c)
142
143#define luaL_addsize(B,n) ((B)->p += (n))
144
145LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
146LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
147LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
148LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
149LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
150LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
151
152
153/* }====================================================== */
154
155
156/* compatibility with ref system */
157
158/* pre-defined references */
159#define LUA_NOREF (-2)
160#define LUA_REFNIL (-1)
161
162#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
163 (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
164
165#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
166
167#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
168
169
170#define luaL_reg luaL_Reg
171
172#endif
173
174
diff --git a/libraries/LuaJIT-1.1.7/src/lbaselib.c b/libraries/LuaJIT-1.1.7/src/lbaselib.c
new file mode 100644
index 0000000..2366a02
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lbaselib.c
@@ -0,0 +1,679 @@
1/*
2** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
3** Basic library
4** See Copyright Notice in lua.h
5*/
6
7
8
9#include <ctype.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define lbaselib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21#ifndef COCO_DISABLE
22#include "lcoco.h"
23#endif
24
25
26
27
28/*
29** If your system does not support `stdout', you can just remove this function.
30** If you need, you can define your own `print' function, following this
31** model but changing `fputs' to put the strings at a proper place
32** (a console window or a log file, for instance).
33*/
34static int luaB_print (lua_State *L) {
35 int n = lua_gettop(L); /* number of arguments */
36 int i;
37 lua_getglobal(L, "tostring");
38 for (i=1; i<=n; i++) {
39 const char *s;
40 lua_pushvalue(L, -1); /* function to be called */
41 lua_pushvalue(L, i); /* value to print */
42 lua_call(L, 1, 1);
43 s = lua_tostring(L, -1); /* get result */
44 if (s == NULL)
45 return luaL_error(L, LUA_QL("tostring") " must return a string to "
46 LUA_QL("print"));
47 if (i>1) fputs("\t", stdout);
48 fputs(s, stdout);
49 lua_pop(L, 1); /* pop result */
50 }
51 fputs("\n", stdout);
52 return 0;
53}
54
55
56static int luaB_tonumber (lua_State *L) {
57 int base = luaL_optint(L, 2, 10);
58 if (base == 10) { /* standard conversion */
59 luaL_checkany(L, 1);
60 if (lua_isnumber(L, 1)) {
61 lua_pushnumber(L, lua_tonumber(L, 1));
62 return 1;
63 }
64 }
65 else {
66 const char *s1 = luaL_checkstring(L, 1);
67 char *s2;
68 unsigned long n;
69 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
70 n = strtoul(s1, &s2, base);
71 if (s1 != s2) { /* at least one valid digit? */
72 while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
73 if (*s2 == '\0') { /* no invalid trailing characters? */
74 lua_pushnumber(L, (lua_Number)n);
75 return 1;
76 }
77 }
78 }
79 lua_pushnil(L); /* else not a number */
80 return 1;
81}
82
83
84static int luaB_error (lua_State *L) {
85 int level = luaL_optint(L, 2, 1);
86 lua_settop(L, 1);
87 if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
88 luaL_where(L, level);
89 lua_pushvalue(L, 1);
90 lua_concat(L, 2);
91 }
92 return lua_error(L);
93}
94
95
96static int luaB_getmetatable (lua_State *L) {
97 luaL_checkany(L, 1);
98 if (!lua_getmetatable(L, 1)) {
99 lua_pushnil(L);
100 return 1; /* no metatable */
101 }
102 luaL_getmetafield(L, 1, "__metatable");
103 return 1; /* returns either __metatable field (if present) or metatable */
104}
105
106
107static int luaB_setmetatable (lua_State *L) {
108 int t = lua_type(L, 2);
109 luaL_checktype(L, 1, LUA_TTABLE);
110 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
111 "nil or table expected");
112 if (luaL_getmetafield(L, 1, "__metatable"))
113 luaL_error(L, "cannot change a protected metatable");
114 lua_settop(L, 2);
115 lua_setmetatable(L, 1);
116 return 1;
117}
118
119
120static void getfunc (lua_State *L, int opt) {
121 if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
122 else {
123 lua_Debug ar;
124 int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
125 luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
126 if (lua_getstack(L, level, &ar) == 0)
127 luaL_argerror(L, 1, "invalid level");
128 lua_getinfo(L, "f", &ar);
129 if (lua_isnil(L, -1))
130 luaL_error(L, "no function environment for tail call at level %d",
131 level);
132 }
133}
134
135
136static int luaB_getfenv (lua_State *L) {
137 getfunc(L, 1);
138 if (lua_iscfunction(L, -1)) /* is a C function? */
139 lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
140 else
141 lua_getfenv(L, -1);
142 return 1;
143}
144
145
146static int luaB_setfenv (lua_State *L) {
147 luaL_checktype(L, 2, LUA_TTABLE);
148 getfunc(L, 0);
149 lua_pushvalue(L, 2);
150 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
151 /* change environment of current thread */
152 lua_pushthread(L);
153 lua_insert(L, -2);
154 lua_setfenv(L, -2);
155 return 0;
156 }
157 else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
158 luaL_error(L,
159 LUA_QL("setfenv") " cannot change environment of given object");
160 return 1;
161}
162
163
164static int luaB_rawequal (lua_State *L) {
165 luaL_checkany(L, 1);
166 luaL_checkany(L, 2);
167 lua_pushboolean(L, lua_rawequal(L, 1, 2));
168 return 1;
169}
170
171
172static int luaB_rawget (lua_State *L) {
173 luaL_checktype(L, 1, LUA_TTABLE);
174 luaL_checkany(L, 2);
175 lua_settop(L, 2);
176 lua_rawget(L, 1);
177 return 1;
178}
179
180static int luaB_rawset (lua_State *L) {
181 luaL_checktype(L, 1, LUA_TTABLE);
182 luaL_checkany(L, 2);
183 luaL_checkany(L, 3);
184 lua_settop(L, 3);
185 lua_rawset(L, 1);
186 return 1;
187}
188
189
190static int luaB_gcinfo (lua_State *L) {
191 lua_pushinteger(L, lua_getgccount(L));
192 return 1;
193}
194
195
196static int luaB_collectgarbage (lua_State *L) {
197 static const char *const opts[] = {"stop", "restart", "collect",
198 "count", "step", "setpause", "setstepmul", NULL};
199 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
200 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
201 int o = luaL_checkoption(L, 1, "collect", opts);
202 int ex = luaL_optint(L, 2, 0);
203 int res = lua_gc(L, optsnum[o], ex);
204 switch (optsnum[o]) {
205 case LUA_GCCOUNT: {
206 int b = lua_gc(L, LUA_GCCOUNTB, 0);
207 lua_pushnumber(L, res + ((lua_Number)b/1024));
208 return 1;
209 }
210 case LUA_GCSTEP: {
211 lua_pushboolean(L, res);
212 return 1;
213 }
214 default: {
215 lua_pushnumber(L, res);
216 return 1;
217 }
218 }
219}
220
221
222static int luaB_type (lua_State *L) {
223 luaL_checkany(L, 1);
224 lua_pushstring(L, luaL_typename(L, 1));
225 return 1;
226}
227
228
229static int luaB_next (lua_State *L) {
230 luaL_checktype(L, 1, LUA_TTABLE);
231 lua_settop(L, 2); /* create a 2nd argument if there isn't one */
232 if (lua_next(L, 1))
233 return 2;
234 else {
235 lua_pushnil(L);
236 return 1;
237 }
238}
239
240
241static int luaB_pairs (lua_State *L) {
242 luaL_checktype(L, 1, LUA_TTABLE);
243 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
244 lua_pushvalue(L, 1); /* state, */
245 lua_pushnil(L); /* and initial value */
246 return 3;
247}
248
249
250static int ipairsaux (lua_State *L) {
251 int i = luaL_checkint(L, 2);
252 luaL_checktype(L, 1, LUA_TTABLE);
253 i++; /* next value */
254 lua_pushinteger(L, i);
255 lua_rawgeti(L, 1, i);
256 return (lua_isnil(L, -1)) ? 0 : 2;
257}
258
259
260static int luaB_ipairs (lua_State *L) {
261 luaL_checktype(L, 1, LUA_TTABLE);
262 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
263 lua_pushvalue(L, 1); /* state, */
264 lua_pushinteger(L, 0); /* and initial value */
265 return 3;
266}
267
268
269static int load_aux (lua_State *L, int status) {
270 if (status == 0) /* OK? */
271 return 1;
272 else {
273 lua_pushnil(L);
274 lua_insert(L, -2); /* put before error message */
275 return 2; /* return nil plus error message */
276 }
277}
278
279
280static int luaB_loadstring (lua_State *L) {
281 size_t l;
282 const char *s = luaL_checklstring(L, 1, &l);
283 const char *chunkname = luaL_optstring(L, 2, s);
284 return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
285}
286
287
288static int luaB_loadfile (lua_State *L) {
289 const char *fname = luaL_optstring(L, 1, NULL);
290 return load_aux(L, luaL_loadfile(L, fname));
291}
292
293
294/*
295** Reader for generic `load' function: `lua_load' uses the
296** stack for internal stuff, so the reader cannot change the
297** stack top. Instead, it keeps its resulting string in a
298** reserved slot inside the stack.
299*/
300static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
301 (void)ud; /* to avoid warnings */
302 luaL_checkstack(L, 2, "too many nested functions");
303 lua_pushvalue(L, 1); /* get function */
304 lua_call(L, 0, 1); /* call it */
305 if (lua_isnil(L, -1)) {
306 *size = 0;
307 return NULL;
308 }
309 else if (lua_isstring(L, -1)) {
310 lua_replace(L, 3); /* save string in a reserved stack slot */
311 return lua_tolstring(L, 3, size);
312 }
313 else luaL_error(L, "reader function must return a string");
314 return NULL; /* to avoid warnings */
315}
316
317
318static int luaB_load (lua_State *L) {
319 int status;
320 const char *cname = luaL_optstring(L, 2, "=(load)");
321 luaL_checktype(L, 1, LUA_TFUNCTION);
322 lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
323 status = lua_load(L, generic_reader, NULL, cname);
324 return load_aux(L, status);
325}
326
327
328static int luaB_dofile (lua_State *L) {
329 const char *fname = luaL_optstring(L, 1, NULL);
330 int n = lua_gettop(L);
331 if (luaL_loadfile(L, fname) != 0) lua_error(L);
332 lua_call(L, 0, LUA_MULTRET);
333 return lua_gettop(L) - n;
334}
335
336
337static int luaB_assert (lua_State *L) {
338 luaL_checkany(L, 1);
339 if (!lua_toboolean(L, 1))
340 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
341 return lua_gettop(L);
342}
343
344
345static int luaB_unpack (lua_State *L) {
346 int i, e, n;
347 luaL_checktype(L, 1, LUA_TTABLE);
348 i = luaL_optint(L, 2, 1);
349 e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
350 if (i > e) return 0; /* empty range */
351 n = e - i + 1; /* number of elements */
352 if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
353 return luaL_error(L, "too many results to unpack");
354 lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
355 while (i++ < e) /* push arg[i + 1...e] */
356 lua_rawgeti(L, 1, i);
357 return n;
358}
359
360
361static int luaB_select (lua_State *L) {
362 int n = lua_gettop(L);
363 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
364 lua_pushinteger(L, n-1);
365 return 1;
366 }
367 else {
368 int i = luaL_checkint(L, 1);
369 if (i < 0) i = n + i;
370 else if (i > n) i = n;
371 luaL_argcheck(L, 1 <= i, 1, "index out of range");
372 return n - i;
373 }
374}
375
376
377static int luaB_pcall (lua_State *L) {
378 int status;
379 luaL_checkany(L, 1);
380 status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
381 lua_pushboolean(L, (status == 0));
382 lua_insert(L, 1);
383 return lua_gettop(L); /* return status + all results */
384}
385
386
387static int luaB_xpcall (lua_State *L) {
388 int status;
389 luaL_checkany(L, 2);
390 lua_settop(L, 2);
391 lua_insert(L, 1); /* put error function under function to be called */
392 status = lua_pcall(L, 0, LUA_MULTRET, 1);
393 lua_pushboolean(L, (status == 0));
394 lua_replace(L, 1);
395 return lua_gettop(L); /* return status + all results */
396}
397
398
399static int luaB_tostring (lua_State *L) {
400 luaL_checkany(L, 1);
401 if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
402 return 1; /* use its value */
403 switch (lua_type(L, 1)) {
404 case LUA_TNUMBER:
405 lua_pushstring(L, lua_tostring(L, 1));
406 break;
407 case LUA_TSTRING:
408 lua_pushvalue(L, 1);
409 break;
410 case LUA_TBOOLEAN:
411 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
412 break;
413 case LUA_TNIL:
414 lua_pushliteral(L, "nil");
415 break;
416 default:
417 lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
418 break;
419 }
420 return 1;
421}
422
423
424static int luaB_newproxy (lua_State *L) {
425 lua_settop(L, 1);
426 lua_newuserdata(L, 0); /* create proxy */
427 if (lua_toboolean(L, 1) == 0)
428 return 1; /* no metatable */
429 else if (lua_isboolean(L, 1)) {
430 lua_newtable(L); /* create a new metatable `m' ... */
431 lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
432 lua_pushboolean(L, 1);
433 lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
434 }
435 else {
436 int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
437 if (lua_getmetatable(L, 1)) {
438 lua_rawget(L, lua_upvalueindex(1));
439 validproxy = lua_toboolean(L, -1);
440 lua_pop(L, 1); /* remove value */
441 }
442 luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
443 lua_getmetatable(L, 1); /* metatable is valid; get it */
444 }
445 lua_setmetatable(L, 2);
446 return 1;
447}
448
449
450static const luaL_Reg base_funcs[] = {
451 {"assert", luaB_assert},
452 {"collectgarbage", luaB_collectgarbage},
453 {"dofile", luaB_dofile},
454 {"error", luaB_error},
455 {"gcinfo", luaB_gcinfo},
456 {"getfenv", luaB_getfenv},
457 {"getmetatable", luaB_getmetatable},
458 {"loadfile", luaB_loadfile},
459 {"load", luaB_load},
460 {"loadstring", luaB_loadstring},
461 {"next", luaB_next},
462 {"pcall", luaB_pcall},
463 {"print", luaB_print},
464 {"rawequal", luaB_rawequal},
465 {"rawget", luaB_rawget},
466 {"rawset", luaB_rawset},
467 {"select", luaB_select},
468 {"setfenv", luaB_setfenv},
469 {"setmetatable", luaB_setmetatable},
470 {"tonumber", luaB_tonumber},
471 {"tostring", luaB_tostring},
472 {"type", luaB_type},
473 {"unpack", luaB_unpack},
474 {"xpcall", luaB_xpcall},
475 {NULL, NULL}
476};
477
478
479/*
480** {======================================================
481** Coroutine library
482** =======================================================
483*/
484
485#define CO_RUN 0 /* running */
486#define CO_SUS 1 /* suspended */
487#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
488#define CO_DEAD 3
489
490static const char *const statnames[] =
491 {"running", "suspended", "normal", "dead"};
492
493static int costatus (lua_State *L, lua_State *co) {
494 if (L == co) return CO_RUN;
495 switch (lua_status(co)) {
496 case LUA_YIELD:
497 return CO_SUS;
498 case 0: {
499 lua_Debug ar;
500 if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
501 return CO_NOR; /* it is running */
502 else if (lua_gettop(co) == 0)
503 return CO_DEAD;
504 else
505 return CO_SUS; /* initial state */
506 }
507 default: /* some error occured */
508 return CO_DEAD;
509 }
510}
511
512
513static int luaB_costatus (lua_State *L) {
514 lua_State *co = lua_tothread(L, 1);
515 luaL_argcheck(L, co, 1, "coroutine expected");
516 lua_pushstring(L, statnames[costatus(L, co)]);
517 return 1;
518}
519
520
521static int auxresume (lua_State *L, lua_State *co, int narg) {
522 int status = costatus(L, co);
523 if (!lua_checkstack(co, narg))
524 luaL_error(L, "too many arguments to resume");
525 if (status != CO_SUS) {
526 lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
527 return -1; /* error flag */
528 }
529 lua_xmove(L, co, narg);
530 status = lua_resume(co, narg);
531 if (status == 0 || status == LUA_YIELD) {
532 int nres = lua_gettop(co);
533 if (!lua_checkstack(L, nres + 1))
534 luaL_error(L, "too many results to resume");
535 lua_xmove(co, L, nres); /* move yielded values */
536 return nres;
537 }
538 else {
539 lua_xmove(co, L, 1); /* move error message */
540 return -1; /* error flag */
541 }
542}
543
544
545static int luaB_coresume (lua_State *L) {
546 lua_State *co = lua_tothread(L, 1);
547 int r;
548 luaL_argcheck(L, co, 1, "coroutine expected");
549 r = auxresume(L, co, lua_gettop(L) - 1);
550 if (r < 0) {
551 lua_pushboolean(L, 0);
552 lua_insert(L, -2);
553 return 2; /* return false + error message */
554 }
555 else {
556 lua_pushboolean(L, 1);
557 lua_insert(L, -(r + 1));
558 return r + 1; /* return true + `resume' returns */
559 }
560}
561
562
563static int luaB_auxwrap (lua_State *L) {
564 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
565 int r = auxresume(L, co, lua_gettop(L));
566 if (r < 0) {
567 if (lua_isstring(L, -1)) { /* error object is a string? */
568 luaL_where(L, 1); /* add extra info */
569 lua_insert(L, -2);
570 lua_concat(L, 2);
571 }
572 lua_error(L); /* propagate error */
573 }
574 return r;
575}
576
577
578#ifndef COCO_DISABLE
579static int luaB_cstacksize (lua_State *L)
580{
581 lua_pushinteger(L, luaCOCO_cstacksize(luaL_optint(L, 1, -1)));
582 return 1;
583}
584#endif
585
586
587static int luaB_cocreate (lua_State *L) {
588#ifdef COCO_DISABLE
589 lua_State *NL = lua_newthread(L);
590 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
591 "Lua function expected");
592#else
593 int cstacksize = luaL_optint(L, 2, 0);
594 lua_State *NL = lua_newcthread(L, cstacksize);
595 luaL_argcheck(L, lua_isfunction(L, 1) &&
596 (cstacksize >= 0 ? 1 : !lua_iscfunction(L, 1)),
597 1, "Lua function expected");
598#endif
599 lua_pushvalue(L, 1); /* move function to top */
600 lua_xmove(L, NL, 1); /* move function from L to NL */
601 return 1;
602}
603
604
605static int luaB_cowrap (lua_State *L) {
606 luaB_cocreate(L);
607 lua_pushcclosure(L, luaB_auxwrap, 1);
608 return 1;
609}
610
611
612static int luaB_yield (lua_State *L) {
613 return lua_yield(L, lua_gettop(L));
614}
615
616
617static int luaB_corunning (lua_State *L) {
618 if (lua_pushthread(L))
619 lua_pushnil(L); /* main thread is not a coroutine */
620 return 1;
621}
622
623
624static const luaL_Reg co_funcs[] = {
625 {"create", luaB_cocreate},
626 {"resume", luaB_coresume},
627 {"running", luaB_corunning},
628 {"status", luaB_costatus},
629 {"wrap", luaB_cowrap},
630 {"yield", luaB_yield},
631#ifndef COCO_DISABLE
632 {"cstacksize", luaB_cstacksize},
633#endif
634 {NULL, NULL}
635};
636
637/* }====================================================== */
638
639
640static void auxopen (lua_State *L, const char *name,
641 lua_CFunction f, lua_CFunction u) {
642 lua_pushcfunction(L, u);
643 lua_pushcclosure(L, f, 1);
644 lua_setfield(L, -2, name);
645}
646
647
648static void base_open (lua_State *L) {
649 /* set global _G */
650 lua_pushvalue(L, LUA_GLOBALSINDEX);
651 lua_setglobal(L, "_G");
652 /* open lib into global table */
653 luaL_register(L, "_G", base_funcs);
654 lua_pushliteral(L, LUA_VERSION);
655 lua_setglobal(L, "_VERSION"); /* set global _VERSION */
656 /* `ipairs' and `pairs' need auxliliary functions as upvalues */
657 auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
658 auxopen(L, "pairs", luaB_pairs, luaB_next);
659 /* `newproxy' needs a weaktable as upvalue */
660 lua_createtable(L, 0, 1); /* new table `w' */
661 lua_pushvalue(L, -1); /* `w' will be its own metatable */
662 lua_setmetatable(L, -2);
663 lua_pushliteral(L, "kv");
664 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
665 lua_pushcclosure(L, luaB_newproxy, 1);
666 lua_setglobal(L, "newproxy"); /* set global `newproxy' */
667}
668
669
670LUALIB_API int luaopen_base (lua_State *L) {
671 base_open(L);
672 luaL_register(L, LUA_COLIBNAME, co_funcs);
673#ifndef COCO_DISABLE
674 lua_pushboolean(L, 1);
675 lua_setfield(L, -2, "coco");
676#endif
677 return 2;
678}
679
diff --git a/libraries/LuaJIT-1.1.7/src/lcoco.c b/libraries/LuaJIT-1.1.7/src/lcoco.c
new file mode 100644
index 0000000..c3acc68
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lcoco.c
@@ -0,0 +1,693 @@
1/*
2** Copyright (C) 2004-2011 Mike Pall. All rights reserved.
3**
4** Permission is hereby granted, free of charge, to any person obtaining
5** a copy of this software and associated documentation files (the
6** "Software"), to deal in the Software without restriction, including
7** without limitation the rights to use, copy, modify, merge, publish,
8** distribute, sublicense, and/or sell copies of the Software, and to
9** permit persons to whom the Software is furnished to do so, subject to
10** the following conditions:
11**
12** The above copyright notice and this permission notice shall be
13** included in all copies or substantial portions of the Software.
14**
15** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22**
23** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
24*/
25
26/* Coco -- True C coroutines for Lua. http://luajit.org/coco.html */
27#ifndef COCO_DISABLE
28
29#define lcoco_c
30#define LUA_CORE
31
32#include "lua.h"
33
34#include "lobject.h"
35#include "lstate.h"
36#include "ldo.h"
37#include "lvm.h"
38#include "lgc.h"
39
40
41/*
42** Define this if you want to run Coco with valgrind. You will get random
43** errors about accessing memory from newly allocated C stacks if you don't.
44** You need at least valgrind 3.0 for this to work.
45**
46** This macro evaluates to a no-op if not run with valgrind. I.e. you can
47** use the same binary for regular runs, too (without a performance loss).
48*/
49#ifdef USE_VALGRIND
50#include <valgrind/valgrind.h>
51#define STACK_REG(coco, p, sz) (coco)->vgid = VALGRIND_STACK_REGISTER(p, p+sz);
52#define STACK_DEREG(coco) VALGRIND_STACK_DEREGISTER((coco)->vgid);
53#define STACK_VGID unsigned int vgid;
54#else
55#define STACK_REG(coco, p, sz)
56#define STACK_DEREG(id)
57#define STACK_VGID
58#endif
59
60/* ------------------------------------------------------------------------ */
61
62/* Use Windows Fibers. */
63#if defined(COCO_USE_FIBERS)
64
65#define _WIN32_WINNT 0x0400
66#include <windows.h>
67
68#define COCO_MAIN_DECL CALLBACK
69
70typedef LPFIBER_START_ROUTINE coco_MainFunc;
71
72#define COCO_NEW(OL, NL, cstacksize, mainfunc) \
73 if ((L2COCO(NL)->fib = CreateFiber(cstacksize, mainfunc, NL)) == NULL) \
74 luaD_throw(OL, LUA_ERRMEM);
75
76#define COCO_FREE(L) \
77 DeleteFiber(L2COCO(L)->fib); \
78 L2COCO(L)->fib = NULL;
79
80/* See: http://blogs.msdn.com/oldnewthing/archive/2004/12/31/344799.aspx */
81#define COCO_JUMPIN(coco) \
82 { void *cur = GetCurrentFiber(); \
83 coco->back = (cur == NULL || cur == (void *)0x1e00) ? \
84 ConvertThreadToFiber(NULL) : cur; } \
85 SwitchToFiber(coco->fib);
86
87#define COCO_JUMPOUT(coco) \
88 SwitchToFiber(coco->back);
89
90/* CreateFiber() defaults to STACKSIZE from the Windows module .def file. */
91#define COCO_DEFAULT_CSTACKSIZE 0
92
93/* ------------------------------------------------------------------------ */
94
95#else /* !COCO_USE_FIBERS */
96
97#ifndef COCO_USE_UCONTEXT
98
99/* Try inline asm first. */
100#if __GNUC__ >= 3 && !defined(COCO_USE_SETJMP)
101
102#if defined(__i386) || defined(__i386__)
103
104#ifdef __PIC__
105typedef void *coco_ctx[4]; /* eip, esp, ebp, ebx */
106static inline void coco_switch(coco_ctx from, coco_ctx to)
107{
108 __asm__ __volatile__ (
109 "call 1f\n" "1:\tpopl %%eax\n\t" "addl $(2f-1b),%%eax\n\t"
110 "movl %%eax, (%0)\n\t" "movl %%esp, 4(%0)\n\t"
111 "movl %%ebp, 8(%0)\n\t" "movl %%ebx, 12(%0)\n\t"
112 "movl 12(%1), %%ebx\n\t" "movl 8(%1), %%ebp\n\t"
113 "movl 4(%1), %%esp\n\t" "jmp *(%1)\n" "2:\n"
114 : "+S" (from), "+D" (to) : : "eax", "ecx", "edx", "memory", "cc");
115}
116#else
117typedef void *coco_ctx[3]; /* eip, esp, ebp */
118static inline void coco_switch(coco_ctx from, coco_ctx to)
119{
120 __asm__ __volatile__ (
121 "movl $1f, (%0)\n\t" "movl %%esp, 4(%0)\n\t" "movl %%ebp, 8(%0)\n\t"
122 "movl 8(%1), %%ebp\n\t" "movl 4(%1), %%esp\n\t" "jmp *(%1)\n" "1:\n"
123 : "+S" (from), "+D" (to) : : "eax", "ebx", "ecx", "edx", "memory", "cc");
124}
125#endif
126
127#define COCO_CTX coco_ctx
128#define COCO_SWITCH(from, to) coco_switch(from, to);
129#define COCO_MAKECTX(coco, buf, func, stack, a0) \
130 buf[0] = (void *)(func); \
131 buf[1] = (void *)(stack); \
132 buf[2] = (void *)0; \
133 stack[0] = 0xdeadc0c0; /* Dummy return address. */ \
134 coco->arg0 = (size_t)(a0);
135#define COCO_STATE_HEAD size_t arg0;
136
137#elif defined(__x86_64__)
138
139static void coco_wrap_main(void)
140{
141 __asm__ __volatile__ ("\tmovq %r13, %rdi\n\tjmpq *%r12\n");
142}
143
144typedef void *coco_ctx[8]; /* rip, rsp, rbp, rbx, r12, r13, r14, r15 */
145static inline void coco_switch(coco_ctx from, coco_ctx to)
146{
147 __asm__ __volatile__ (
148 "leaq 1f(%%rip), %%rax\n\t"
149 "movq %%rax, (%0)\n\t" "movq %%rsp, 8(%0)\n\t" "movq %%rbp, 16(%0)\n\t"
150 "movq %%rbx, 24(%0)\n\t" "movq %%r12, 32(%0)\n\t" "movq %%r13, 40(%0)\n\t"
151 "movq %%r14, 48(%0)\n\t" "movq %%r15, 56(%0)\n\t"
152 "movq 56(%1), %%r15\n\t" "movq 48(%1), %%r14\n\t" "movq 40(%1), %%r13\n\t"
153 "movq 32(%1), %%r12\n\t" "movq 24(%1), %%rbx\n\t" "movq 16(%1), %%rbp\n\t"
154 "movq 8(%1), %%rsp\n\t" "jmpq *(%1)\n" "1:\n"
155 : "+S" (from), "+D" (to) :
156 : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "memory", "cc");
157}
158
159#define COCO_CTX coco_ctx
160#define COCO_SWITCH(from, to) coco_switch(from, to);
161#define COCO_MAKECTX(coco, buf, func, stack, a0) \
162 buf[0] = (void *)(coco_wrap_main); \
163 buf[1] = (void *)(stack); \
164 buf[2] = (void *)0; \
165 buf[3] = (void *)0; \
166 buf[4] = (void *)(func); \
167 buf[5] = (void *)(a0); \
168 buf[6] = (void *)0; \
169 buf[7] = (void *)0; \
170 stack[0] = 0xdeadc0c0deadc0c0; /* Dummy return address. */ \
171
172#elif __mips && _MIPS_SIM == _MIPS_SIM_ABI32 && !defined(__mips_eabi)
173
174/* No way to avoid the function prologue with inline assembler. So use this: */
175static const unsigned int coco_switch[] = {
176#ifdef __mips_soft_float
177#define COCO_STACKSAVE -10
178 0x27bdffd8, /* addiu sp, sp, -(10*4) */
179#else
180#define COCO_STACKSAVE -22
181 0x27bdffa8, /* addiu sp, sp, -(10*4+6*8) */
182 /* sdc1 {$f20-$f30}, offset(sp) */
183 0xf7be0050, 0xf7bc0048, 0xf7ba0040, 0xf7b80038, 0xf7b60030, 0xf7b40028,
184#endif
185 /* sw {gp,s0-s8}, offset(sp) */
186 0xafbe0024, 0xafb70020, 0xafb6001c, 0xafb50018, 0xafb40014, 0xafb30010,
187 0xafb2000c, 0xafb10008, 0xafb00004, 0xafbc0000,
188 /* sw sp, 4(a0); sw ra, 0(a0); lw ra, 0(a1); lw sp, 4(a1); move t9, ra */
189 0xac9d0004, 0xac9f0000, 0x8cbf0000, 0x8cbd0004, 0x03e0c821,
190 /* lw caller-saved-reg, offset(sp) */
191 0x8fbe0024, 0x8fb70020, 0x8fb6001c, 0x8fb50018, 0x8fb40014, 0x8fb30010,
192 0x8fb2000c, 0x8fb10008, 0x8fb00004, 0x8fbc0000,
193#ifdef __mips_soft_float
194 0x03e00008, 0x27bd0028 /* jr ra; addiu sp, sp, 10*4 */
195#else
196 /* ldc1 {$f20-$f30}, offset(sp) */
197 0xd7be0050, 0xd7bc0048, 0xd7ba0040, 0xd7b80038, 0xd7b60030, 0xd7b40028,
198 0x03e00008, 0x27bd0058 /* jr ra; addiu sp, sp, 10*4+6*8 */
199#endif
200};
201
202typedef void *coco_ctx[2]; /* ra, sp */
203#define COCO_CTX coco_ctx
204#define COCO_SWITCH(from, to) \
205 ((void (*)(coco_ctx, coco_ctx))coco_switch)(from, to);
206#define COCO_MAKECTX(coco, buf, func, stack, a0) \
207 buf[0] = (void *)(func); \
208 buf[1] = (void *)&stack[COCO_STACKSAVE]; \
209 stack[4] = (size_t)(a0); /* Assumes o32 ABI. */
210#define COCO_STACKADJUST 8
211#define COCO_MAIN_PARAM int _a, int _b, int _c, int _d, lua_State *L
212
213#elif defined(__sparc__)
214
215typedef void *coco_ctx[4];
216#define COCO_CTX coco_ctx
217#define COCO_SWITCH(from, to) coco_switch(from, to);
218#define COCO_STACKADJUST 24
219
220#if defined(__LP64__)
221#define COCO_STACKBIAS (2047UL)
222#define COCO_PTR2SP(stack) (((unsigned long)stack)-COCO_STACKBIAS)
223static inline void coco_switch(coco_ctx from, coco_ctx to)
224{
225 void *__stack[16] __attribute__((aligned (16)));
226 unsigned long __tmp_sp = COCO_PTR2SP(__stack);
227 __asm__ __volatile__
228 (/* Flush register window(s) to stack and save the previous stack
229 pointer to capture the current registers, %l0-%l7 and %i0-%i7. */
230 "ta 3\n\t"
231 "stx %%sp,[%0+8]\n\t"
232 /* Move to a temporary stack. If the register window is flushed
233 for some reason (e.g. context switch), not the next stack
234 but the temporary stack should be used so as not to break
235 neither the previous nor next stack */
236 "mov %2,%%sp\n\t"
237 "sethi %%hh(1f),%%g1\n\t" /* i.e. setx 1f,%%g1 */
238 "or %%g1,%%hm(1f),%%g1\n\t"
239 "sethi %%lm(1f),%%g2\n\t"
240 "or %%g2,%%lo(1f),%%g2\n\t"
241 "sllx %%g1,32,%%g1\n\t"
242 "or %%g1,%%g2,%%g1\n\t"
243 "stx %%g1,[%0]\n\t"
244 /* Restore registers from stack. DO NOT load the next stack
245 pointer directly to %sp. The register window can be possibly
246 flushed and restored asynchronous (e.g. context switch). */
247 "mov %1,%%o1\n\t"
248 "ldx [%%o1+8],%%o2\n\t"
249 "ldx [%%o2+%3],%%l0\n\t"
250 "ldx [%%o2+%3+8],%%l1\n\t"
251 "ldx [%%o2+%3+0x10],%%l2\n\t"
252 "ldx [%%o2+%3+0x18],%%l3\n\t"
253 "ldx [%%o2+%3+0x20],%%l4\n\t"
254 "ldx [%%o2+%3+0x28],%%l5\n\t"
255 "ldx [%%o2+%3+0x30],%%l6\n\t"
256 "ldx [%%o2+%3+0x38],%%l7\n\t"
257 "ldx [%%o2+%3+0x40],%%i0\n\t"
258 "ldx [%%o2+%3+0x48],%%i1\n\t"
259 "ldx [%%o2+%3+0x50],%%i2\n\t"
260 "ldx [%%o2+%3+0x58],%%i3\n\t"
261 "ldx [%%o2+%3+0x60],%%i4\n\t"
262 "ldx [%%o2+%3+0x68],%%i5\n\t"
263 "ldx [%%o2+%3+0x70],%%i6\n\t"
264 "ldx [%%o2+%3+0x78],%%i7\n\t"
265 /* Move to the next stack with the consistent registers atomically */
266 "mov %%o2,%%sp\n\t"
267 "ldx [%%o1],%%o2\n\t"
268 /* Since %o0-%o7 are marked as clobbered, values are safely overwritten
269 across the inline assembly. %o0-%o7 will have meaningless values
270 after leaving the inline assembly. The only exception is %o0, which
271 serves as an argument to coco_main */
272 "ldx [%%o1+16],%%o0\n\t"
273 "jmpl %%o2,%%g0\n\t"
274 "nop\n\t"
275 "1:\n"
276 /* An assumption is made here; no input operand is assigned to %g1
277 nor %g2. It's the case for the currently avilable gcc's */
278 : : "r"(from),"r"(to),"r"(__tmp_sp),"i"(COCO_STACKBIAS)
279 : "g1","g2","o0","o1","o2","o3","o4","o5","o7","memory","cc");
280}
281
282#define COCO_MAKECTX(coco, buf, func, stack, a0) \
283 buf[0] = (void *)(func); \
284 buf[1] = (void *)COCO_PTR2SP(&(stack)[0]); \
285 buf[2] = (void *)(a0); \
286 stack[0] = 0; \
287 stack[1] = 0; \
288 stack[2] = 0; \
289 stack[3] = 0; \
290 stack[4] = 0; \
291 stack[5] = 0; \
292 stack[6] = 0; \
293 stack[7] = 0; \
294 stack[8] = 0; \
295 stack[9] = 0; \
296 stack[10] = 0; \
297 stack[11] = 0; \
298 stack[12] = 0; \
299 stack[13] = 0; \
300 stack[14] = COCO_PTR2SP(&(stack)[COCO_STACKADJUST]); \
301 stack[15] = 0xdeadc0c0deadc0c0; /* Dummy return address. */ \
302
303#else
304static inline void coco_switch(coco_ctx from, coco_ctx to)
305{
306 void *__tmp_stack[16] __attribute__((aligned (16)));
307 __asm__ __volatile__
308 ("ta 3\n\t"
309 "st %%sp,[%0+4]\n\t"
310 "mov %2,%%sp\n\t"
311 "set 1f,%%g1\n\t"
312 "st %%g1,[%0]\n\t"
313 "mov %1,%%o1\n\t"
314 "ld [%%o1+4],%%o2\n\t"
315 "ldd [%%o2],%%l0\n\t"
316 "ldd [%%o2+8],%%l2\n\t"
317 "ldd [%%o2+0x10],%%l4\n\t"
318 "ldd [%%o2+0x18],%%l6\n\t"
319 "ldd [%%o2+0x20],%%i0\n\t"
320 "ldd [%%o2+0x28],%%i2\n\t"
321 "ldd [%%o2+0x30],%%i4\n\t"
322 "ldd [%%o2+0x38],%%i6\n\t"
323 "mov %%o2,%%sp\n\t"
324 "ld [%%o1],%%o2\n\t"
325 "ld [%%o1+8],%%o0\n\t"
326 "jmpl %%o2,%%g0\n\t"
327 "nop\n\t"
328 "1:\n"
329 : : "r"(from),"r"(to),"r"(__tmp_stack)
330 : "g1","o0","o1","o2","o3","o4","o5","o7","memory","cc");
331}
332
333#define COCO_MAKECTX(coco, buf, func, stack, a0) \
334 buf[0] = (void *)(func); \
335 buf[1] = (void *)(stack); \
336 buf[2] = (void *)(a0); \
337 stack[0] = 0; \
338 stack[1] = 0; \
339 stack[2] = 0; \
340 stack[3] = 0; \
341 stack[4] = 0; \
342 stack[5] = 0; \
343 stack[6] = 0; \
344 stack[7] = 0; \
345 stack[8] = 0; \
346 stack[9] = 0; \
347 stack[10] = 0; \
348 stack[11] = 0; \
349 stack[12] = 0; \
350 stack[13] = 0; \
351 stack[14] = (size_t)&stack[COCO_STACKADJUST]; \
352 stack[15] = 0xdeadc0c0; /* Dummy return address. */ \
353
354#endif /* !define(__LP64__) */
355
356#endif /* arch check */
357
358#endif /* !(__GNUC__ >= 3 && !defined(COCO_USE_SETJMP)) */
359
360/* Try _setjmp/_longjmp with a patched jump buffer. */
361#ifndef COCO_MAKECTX
362#include <setjmp.h>
363
364/* Check for supported CPU+OS combinations. */
365#if defined(__i386) || defined(__i386__)
366
367#define COCO_STATE_HEAD size_t arg0;
368#define COCO_SETJMP_X86(coco, stack, a0) \
369 stack[COCO_STACKADJUST-1] = 0xdeadc0c0; /* Dummy return address. */ \
370 coco->arg0 = (size_t)(a0);
371
372#if __GLIBC__ == 2 && defined(JB_SP) /* x86-linux-glibc2 */
373#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
374 buf->__jmpbuf[JB_PC] = (int)(func); \
375 buf->__jmpbuf[JB_SP] = (int)(stack); \
376 buf->__jmpbuf[JB_BP] = 0; \
377 COCO_SETJMP_X86(coco, stack, a0)
378#elif defined(__linux__) && defined(_I386_JMP_BUF_H) /* x86-linux-libc5 */
379#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
380 buf->__pc = (func); \
381 buf->__sp = (stack); \
382 buf->__bp = NULL; \
383 COCO_SETJMP_X86(coco, stack, a0)
384#elif defined(__FreeBSD__) /* x86-FreeBSD */
385#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
386 buf->_jb[0] = (long)(func); \
387 buf->_jb[2] = (long)(stack); \
388 buf->_jb[3] = 0; /* ebp */ \
389 COCO_SETJMP_X86(coco, stack, a0)
390#define COCO_STACKADJUST 2
391#elif defined(__NetBSD__) || defined(__OpenBSD__) /* x86-NetBSD, x86-OpenBSD */
392#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
393 buf[0] = (long)(func); \
394 buf[2] = (long)(stack); \
395 buf[3] = 0; /* ebp */ \
396 COCO_SETJMP_X86(coco, stack, a0)
397#define COCO_STACKADJUST 2
398#elif defined(__solaris__) && _JBLEN == 10 /* x86-solaris */
399#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
400 buf[5] = (int)(func); \
401 buf[4] = (int)(stack); \
402 buf[3] = 0; \
403 COCO_SETJMP_X86(coco, stack, a0)
404#elif defined(__MACH__) && defined(_BSD_I386_SETJMP_H) /* x86-macosx */
405#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
406 buf[12] = (int)(func); \
407 buf[9] = (int)(stack); \
408 buf[8] = 0; /* ebp */ \
409 COCO_SETJMP_X86(coco, stack, a0)
410#endif
411
412#elif defined(__x86_64__) || defined(__x86_64)
413
414#define COCO_STATE_HEAD size_t arg0;
415
416#define COCO_MAIN_PARAM \
417 int _a, int _b, int _c, int _d, int _e, int _f, lua_State *L
418
419#if defined(__solaris__) && _JBLEN == 8 /* x64-solaris */
420#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
421 buf[7] = (long)(func); \
422 buf[6] = (long)(stack); \
423 buf[5] = 0; \
424 stack[0] = 0xdeadc0c0; /* Dummy return address. */ \
425 coco->arg0 = (size_t)(a0);
426#endif
427
428#elif defined(PPC) || defined(__ppc__) || defined(__PPC__) || \
429 defined(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC)
430
431#define COCO_STACKADJUST 16
432#define COCO_MAIN_PARAM \
433 int _a, int _b, int _c, int _d, int _e, int _f, int _g, int _h, lua_State *L
434
435#if defined(__MACH__) && defined(_BSD_PPC_SETJMP_H_) /* ppc32-macosx */
436#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
437 buf[21] = (int)(func); \
438 buf[0] = (int)(stack); \
439 stack[6+8] = (size_t)(a0);
440#endif
441
442#elif (defined(MIPS) || defined(MIPSEL) || defined(__mips)) && \
443 _MIPS_SIM == _MIPS_SIM_ABI32 && !defined(__mips_eabi)
444
445/* Stack layout for o32 ABI. */
446#define COCO_STACKADJUST 8
447#define COCO_MAIN_PARAM int _a, int _b, int _c, int _d, lua_State *L
448
449#if __GLIBC__ == 2 || defined(__UCLIBC__) /* mips32-linux-glibc2 */
450#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
451 buf->__jmpbuf->__pc = (func); /* = t9 in _longjmp. Reqd. for -mabicalls. */ \
452 buf->__jmpbuf->__sp = (stack); \
453 buf->__jmpbuf->__fp = (void *)0; \
454 stack[4] = (size_t)(a0);
455#endif
456
457#elif defined(__arm__) || defined(__ARM__)
458
459#if __GLIBC__ == 2 || defined(__UCLIBC__) /* arm-linux-glibc2 */
460#ifndef __JMP_BUF_SP
461#define __JMP_BUF_SP ((sizeof(__jmp_buf)/sizeof(int))-2)
462#endif
463#define COCO_PATCHCTX(coco, buf, func, stack, a0) \
464 buf->__jmpbuf[__JMP_BUF_SP+1] = (int)(func); /* pc */ \
465 buf->__jmpbuf[__JMP_BUF_SP] = (int)(stack); /* sp */ \
466 buf->__jmpbuf[__JMP_BUF_SP-1] = 0; /* fp */ \
467 stack[0] = (size_t)(a0);
468#define COCO_STACKADJUST 2
469#define COCO_MAIN_PARAM int _a, int _b, int _c, int _d, lua_State *L
470#endif
471
472#endif /* arch check */
473
474#ifdef COCO_PATCHCTX
475#define COCO_CTX jmp_buf
476#define COCO_MAKECTX(coco, buf, func, stack, a0) \
477 _setjmp(buf); COCO_PATCHCTX(coco, buf, func, stack, a0)
478#define COCO_SWITCH(from, to) if (!_setjmp(from)) _longjmp(to, 1);
479#endif
480
481#endif /* !defined(COCO_MAKECTX) */
482
483#endif /* !defined(COCO_USE_UCONTEXT) */
484
485/* ------------------------------------------------------------------------ */
486
487/* Use inline asm or _setjmp/_longjmp if available. */
488#ifdef COCO_MAKECTX
489
490#ifndef COCO_STACKADJUST
491#define COCO_STACKADJUST 1
492#endif
493
494#define COCO_FILL(coco, NL, mainfunc) \
495{ /* Include the return address to get proper stack alignment. */ \
496 size_t *stackptr = &((size_t *)coco)[-COCO_STACKADJUST]; \
497 COCO_MAKECTX(coco, coco->ctx, mainfunc, stackptr, NL) \
498}
499
500/* ------------------------------------------------------------------------ */
501
502/* Else fallback to ucontext. Slower, because it saves/restores signals. */
503#else /* !defined(COCO_MAKECTX) */
504
505#include <ucontext.h>
506
507#define COCO_CTX ucontext_t
508
509/* Ugly workaround for makecontext() deficiencies on 64 bit CPUs. */
510/* Note that WIN64 (which is LLP64) never comes here. See above. */
511#if defined(__LP64__) || defined(_LP64) || INT_MAX != LONG_MAX
512/* 64 bit CPU: split the pointer into two 32 bit ints. */
513#define COCO_MAIN_PARAM unsigned int lo, unsigned int hi
514#define COCO_MAIN_GETL \
515 lua_State *L = (lua_State *)((((unsigned long)hi)<<32)+(unsigned long)lo);
516#define COCO_MAKECTX(coco, NL, mainfunc) \
517 makecontext(&coco->ctx, mainfunc, 2, \
518 (int)(ptrdiff_t)NL, (int)((ptrdiff_t)NL>>32));
519#else
520/* 32 bit CPU: a pointer fits into an int. */
521#define COCO_MAKECTX(coco, NL, mainfunc) \
522 makecontext(&coco->ctx, mainfunc, 1, (int)NL);
523#endif
524
525#define COCO_FILL(coco, NL, mainfunc) \
526 getcontext(&coco->ctx); \
527 coco->ctx.uc_link = NULL; /* We never exit from coco_main. */ \
528 coco->ctx.uc_stack.ss_sp = coco->allocptr; \
529 coco->ctx.uc_stack.ss_size = (char *)coco - (char *)(coco->allocptr); \
530 COCO_MAKECTX(coco, NL, mainfunc)
531
532#define COCO_SWITCH(from, to) swapcontext(&(from), &(to));
533
534#endif /* !defined(COCO_MAKECTX) */
535
536
537/* Common code for inline asm/setjmp/ucontext to allocate/free the stack. */
538
539struct coco_State {
540#ifdef COCO_STATE_HEAD
541 COCO_STATE_HEAD
542#endif
543 COCO_CTX ctx; /* Own context. */
544 COCO_CTX back; /* Context to switch back to. */
545 void *allocptr; /* Pointer to allocated memory. */
546 int allocsize; /* Size of allocated memory. */
547 int nargs; /* Number of arguments to pass. */
548 STACK_VGID /* Optional valgrind stack id. See above. */
549};
550
551typedef void (*coco_MainFunc)(void);
552
553/* Put the Coco state at the end and align it downwards. */
554#define ALIGNED_END(p, s, t) \
555 ((t *)(((char *)0) + ((((char *)(p)-(char *)0)+(s)-sizeof(t)) & -16)))
556
557/* TODO: use mmap. */
558#define COCO_NEW(OL, NL, cstacksize, mainfunc) \
559{ \
560 void *ptr = luaM_malloc(OL, cstacksize); \
561 coco_State *coco = ALIGNED_END(ptr, cstacksize, coco_State); \
562 STACK_REG(coco, ptr, cstacksize) \
563 coco->allocptr = ptr; \
564 coco->allocsize = cstacksize; \
565 COCO_FILL(coco, NL, mainfunc) \
566 L2COCO(NL) = coco; \
567}
568
569#define COCO_FREE(L) \
570 STACK_DEREG(L2COCO(L)) \
571 luaM_freemem(L, L2COCO(L)->allocptr, L2COCO(L)->allocsize); \
572 L2COCO(L) = NULL;
573
574#define COCO_JUMPIN(coco) COCO_SWITCH(coco->back, coco->ctx)
575#define COCO_JUMPOUT(coco) COCO_SWITCH(coco->ctx, coco->back)
576
577#endif /* !COCO_USE_FIBERS */
578
579/* ------------------------------------------------------------------------ */
580
581#ifndef COCO_MIN_CSTACKSIZE
582#define COCO_MIN_CSTACKSIZE (32768+4096)
583#endif
584
585/* Don't use multiples of 64K to avoid D-cache aliasing conflicts. */
586#ifndef COCO_DEFAULT_CSTACKSIZE
587#define COCO_DEFAULT_CSTACKSIZE (65536-4096)
588#endif
589
590static int defaultcstacksize = COCO_DEFAULT_CSTACKSIZE;
591
592/* Start the Lua or C function. */
593static void coco_start(lua_State *L, void *ud)
594{
595 if (luaD_precall(L, (StkId)ud, LUA_MULTRET) == PCRLUA)
596 luaV_execute(L, L->ci - L->base_ci);
597}
598
599#ifndef COCO_MAIN_PARAM
600#define COCO_MAIN_PARAM lua_State *L
601#endif
602
603#ifndef COCO_MAIN_DECL
604#define COCO_MAIN_DECL
605#endif
606
607/* Toplevel function for the new coroutine stack. Never exits. */
608static void COCO_MAIN_DECL coco_main(COCO_MAIN_PARAM)
609{
610#ifdef COCO_MAIN_GETL
611 COCO_MAIN_GETL
612#endif
613 coco_State *coco = L2COCO(L);
614 for (;;) {
615 L->status = luaD_rawrunprotected(L, coco_start, L->top - (coco->nargs+1));
616 if (L->status != 0) luaD_seterrorobj(L, L->status, L->top);
617 COCO_JUMPOUT(coco)
618 }
619}
620
621/* Add a C stack to a coroutine. */
622lua_State *lua_newcthread(lua_State *OL, int cstacksize)
623{
624 lua_State *NL = lua_newthread(OL);
625
626 if (cstacksize < 0)
627 return NL;
628 if (cstacksize == 0)
629 cstacksize = defaultcstacksize;
630 else if (cstacksize < COCO_MIN_CSTACKSIZE)
631 cstacksize = COCO_MIN_CSTACKSIZE;
632 cstacksize &= -16;
633
634 COCO_NEW(OL, NL, cstacksize, ((coco_MainFunc)(coco_main)))
635
636 return NL;
637}
638
639/* Free the C stack of a coroutine. Called from lstate.c. */
640void luaCOCO_free(lua_State *L)
641{
642 COCO_FREE(L)
643}
644
645/* Resume a coroutine with a C stack. Called from ldo.c. */
646int luaCOCO_resume(lua_State *L, int nargs)
647{
648 coco_State *coco = L2COCO(L);
649 coco->nargs = nargs;
650 COCO_JUMPIN(coco)
651#ifndef COCO_DISABLE_EARLY_FREE
652 if (L->status != LUA_YIELD) {
653 COCO_FREE(L)
654 }
655#endif
656 return L->status;
657}
658
659/* Yield from a coroutine with a C stack. Called from ldo.c. */
660int luaCOCO_yield(lua_State *L)
661{
662 coco_State *coco = L2COCO(L);
663 L->status = LUA_YIELD;
664 COCO_JUMPOUT(coco)
665 L->status = 0;
666 {
667 StkId base = L->top - coco->nargs;
668 StkId rbase = L->base;
669 if (rbase < base) { /* Need to move args down? */
670 while (base < L->top)
671 setobjs2s(L, rbase++, base++);
672 L->top = rbase;
673 }
674 }
675 L->base = L->ci->base; /* Restore invariant. */
676 return coco->nargs;
677}
678
679/* Get/set the default C stack size. */
680int luaCOCO_cstacksize(int cstacksize)
681{
682 int oldsz = defaultcstacksize;
683 if (cstacksize >= 0) {
684 if (cstacksize == 0)
685 cstacksize = COCO_DEFAULT_CSTACKSIZE;
686 else if (cstacksize < COCO_MIN_CSTACKSIZE)
687 cstacksize = COCO_MIN_CSTACKSIZE;
688 defaultcstacksize = cstacksize;
689 }
690 return oldsz;
691}
692
693#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lcoco.h b/libraries/LuaJIT-1.1.7/src/lcoco.h
new file mode 100644
index 0000000..9fb6207
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lcoco.h
@@ -0,0 +1,72 @@
1/*
2** Lua/Coco glue.
3** Copyright (C) 2004-2011 Mike Pall. See copyright notice in lcoco.c
4*/
5
6#ifndef lcoco_h
7#define lcoco_h
8
9#define LUACOCO_VERSION "Coco 1.1.6"
10#define LUACOCO_VERSION_NUM 10106
11
12/* Exported C API to add a C stack to a coroutine. */
13LUA_API lua_State *lua_newcthread(lua_State *L, int cstacksize);
14
15/* Internal support routines. */
16LUAI_FUNC void luaCOCO_free(lua_State *L);
17LUAI_FUNC int luaCOCO_resume(lua_State *L, int nargs);
18LUAI_FUNC int luaCOCO_yield(lua_State *L);
19LUAI_FUNC int luaCOCO_cstacksize(int cstacksize);
20
21/* Forward declaration. */
22typedef struct coco_State coco_State;
23
24/* These are redefined below. */
25#undef LUAI_EXTRASPACE
26#undef luai_userstateopen
27/* luai_userstateclose unused */
28#undef luai_userstatethread
29#undef luai_userstatefree
30#undef luai_userstateresume
31#undef luai_userstateyield
32
33/* Use Windows Fibers (Win98+). */
34#if defined(_WIN32)
35
36/* Fibers allocate their own stack. The whole Coco state is in front of L. */
37struct coco_State {
38 void *fib; /* Own fiber (if any). */
39 void *back; /* Fiber to switch back to. */
40 int nargs; /* Number of arguments to pass. */
41 int dummy_align;
42};
43
44#define L2COCO(L) (&((coco_State *)(L))[-1])
45#define LHASCOCO(L) (L2COCO(L)->fib)
46#define LUAI_EXTRASPACE sizeof(coco_State)
47#define luai_userstateopen(L) L2COCO(L)->fib = NULL
48#define luai_userstatethread(L,L1) L2COCO(L1)->fib = NULL
49#define COCO_USE_FIBERS
50
51#else /* !defined(_WIN32) */
52
53/* The Coco state depends on the context switch method used. See lcoco.c. */
54/* It's stored at the end of the stack. Only need a pointer in front of L. */
55#define L2COCO(L) (((coco_State **)(L))[-1])
56#define LHASCOCO(L) (L2COCO(L))
57/* This wastes some space on 32 bit systems, but gets better alignment. */
58#define LUAI_EXTRASPACE sizeof(LUAI_USER_ALIGNMENT_T)
59#define luai_userstateopen(L) L2COCO(L) = NULL
60#define luai_userstatethread(L,L1) L2COCO(L1) = NULL
61
62#endif /* !defined(_WIN32) */
63
64#define luai_userstatefree(L) if (LHASCOCO(L)) luaCOCO_free(L)
65#define luai_userstateresume(L, nargs) \
66 if (LHASCOCO(L)) return luaCOCO_resume(L, nargs)
67#define luai_userstateyield(L, nresults) \
68 do { if (LHASCOCO(L)) { \
69 L->base = L->top - (nresults); /* Protect stack slots below. */ \
70 return luaCOCO_yield(L); } } while (0)
71
72#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lcode.c b/libraries/LuaJIT-1.1.7/src/lcode.c
new file mode 100644
index 0000000..c13066e
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lcode.c
@@ -0,0 +1,831 @@
1/*
2** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
3** Code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdlib.h>
9
10#define lcode_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lcode.h"
16#include "ldebug.h"
17#include "ldo.h"
18#include "lgc.h"
19#include "llex.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lparser.h"
24#include "ltable.h"
25
26
27#define hasjumps(e) ((e)->t != (e)->f)
28
29
30static int isnumeral(expdesc *e) {
31 return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
32}
33
34
35void luaK_nil (FuncState *fs, int from, int n) {
36 Instruction *previous;
37 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
38 if (fs->pc == 0) { /* function start? */
39 if (from >= fs->nactvar)
40 return; /* positions are already clean */
41 }
42 else {
43 previous = &fs->f->code[fs->pc-1];
44 if (GET_OPCODE(*previous) == OP_LOADNIL) {
45 int pfrom = GETARG_A(*previous);
46 int pto = GETARG_B(*previous);
47 if (pfrom <= from && from <= pto+1) { /* can connect both? */
48 if (from+n-1 > pto)
49 SETARG_B(*previous, from+n-1);
50 return;
51 }
52 }
53 }
54 }
55 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
56}
57
58
59int luaK_jump (FuncState *fs) {
60 int jpc = fs->jpc; /* save list of jumps to here */
61 int j;
62 fs->jpc = NO_JUMP;
63 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
64 luaK_concat(fs, &j, jpc); /* keep them on hold */
65 return j;
66}
67
68
69void luaK_ret (FuncState *fs, int first, int nret) {
70 luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
71}
72
73
74static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
75 luaK_codeABC(fs, op, A, B, C);
76 return luaK_jump(fs);
77}
78
79
80static void fixjump (FuncState *fs, int pc, int dest) {
81 Instruction *jmp = &fs->f->code[pc];
82 int offset = dest-(pc+1);
83 lua_assert(dest != NO_JUMP);
84 if (abs(offset) > MAXARG_sBx)
85 luaX_syntaxerror(fs->ls, "control structure too long");
86 SETARG_sBx(*jmp, offset);
87}
88
89
90/*
91** returns current `pc' and marks it as a jump target (to avoid wrong
92** optimizations with consecutive instructions not in the same basic block).
93*/
94int luaK_getlabel (FuncState *fs) {
95 fs->lasttarget = fs->pc;
96 return fs->pc;
97}
98
99
100static int getjump (FuncState *fs, int pc) {
101 int offset = GETARG_sBx(fs->f->code[pc]);
102 if (offset == NO_JUMP) /* point to itself represents end of list */
103 return NO_JUMP; /* end of list */
104 else
105 return (pc+1)+offset; /* turn offset into absolute position */
106}
107
108
109static Instruction *getjumpcontrol (FuncState *fs, int pc) {
110 Instruction *pi = &fs->f->code[pc];
111 if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
112 return pi-1;
113 else
114 return pi;
115}
116
117
118/*
119** check whether list has any jump that do not produce a value
120** (or produce an inverted value)
121*/
122static int need_value (FuncState *fs, int list) {
123 for (; list != NO_JUMP; list = getjump(fs, list)) {
124 Instruction i = *getjumpcontrol(fs, list);
125 if (GET_OPCODE(i) != OP_TESTSET) return 1;
126 }
127 return 0; /* not found */
128}
129
130
131static int patchtestreg (FuncState *fs, int node, int reg) {
132 Instruction *i = getjumpcontrol(fs, node);
133 if (GET_OPCODE(*i) != OP_TESTSET)
134 return 0; /* cannot patch other instructions */
135 if (reg != NO_REG && reg != GETARG_B(*i))
136 SETARG_A(*i, reg);
137 else /* no register to put value or register already has the value */
138 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
139
140 return 1;
141}
142
143
144static void removevalues (FuncState *fs, int list) {
145 for (; list != NO_JUMP; list = getjump(fs, list))
146 patchtestreg(fs, list, NO_REG);
147}
148
149
150static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
151 int dtarget) {
152 while (list != NO_JUMP) {
153 int next = getjump(fs, list);
154 if (patchtestreg(fs, list, reg))
155 fixjump(fs, list, vtarget);
156 else
157 fixjump(fs, list, dtarget); /* jump to default target */
158 list = next;
159 }
160}
161
162
163static void dischargejpc (FuncState *fs) {
164 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
165 fs->jpc = NO_JUMP;
166}
167
168
169void luaK_patchlist (FuncState *fs, int list, int target) {
170 if (target == fs->pc)
171 luaK_patchtohere(fs, list);
172 else {
173 lua_assert(target < fs->pc);
174 patchlistaux(fs, list, target, NO_REG, target);
175 }
176}
177
178
179void luaK_patchtohere (FuncState *fs, int list) {
180 luaK_getlabel(fs);
181 luaK_concat(fs, &fs->jpc, list);
182}
183
184
185void luaK_concat (FuncState *fs, int *l1, int l2) {
186 if (l2 == NO_JUMP) return;
187 else if (*l1 == NO_JUMP)
188 *l1 = l2;
189 else {
190 int list = *l1;
191 int next;
192 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
193 list = next;
194 fixjump(fs, list, l2);
195 }
196}
197
198
199void luaK_checkstack (FuncState *fs, int n) {
200 int newstack = fs->freereg + n;
201 if (newstack > fs->f->maxstacksize) {
202 if (newstack >= MAXSTACK)
203 luaX_syntaxerror(fs->ls, "function or expression too complex");
204 fs->f->maxstacksize = cast_byte(newstack);
205 }
206}
207
208
209void luaK_reserveregs (FuncState *fs, int n) {
210 luaK_checkstack(fs, n);
211 fs->freereg += n;
212}
213
214
215static void freereg (FuncState *fs, int reg) {
216 if (!ISK(reg) && reg >= fs->nactvar) {
217 fs->freereg--;
218 lua_assert(reg == fs->freereg);
219 }
220}
221
222
223static void freeexp (FuncState *fs, expdesc *e) {
224 if (e->k == VNONRELOC)
225 freereg(fs, e->u.s.info);
226}
227
228
229static int addk (FuncState *fs, TValue *k, TValue *v) {
230 lua_State *L = fs->L;
231 TValue *idx = luaH_set(L, fs->h, k);
232 Proto *f = fs->f;
233 int oldsize = f->sizek;
234 if (ttisnumber(idx)) {
235 lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
236 return cast_int(nvalue(idx));
237 }
238 else { /* constant not found; create a new entry */
239 setnvalue(idx, cast_num(fs->nk));
240 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
241 MAXARG_Bx, "constant table overflow");
242 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
243 setobj(L, &f->k[fs->nk], v);
244 luaC_barrier(L, f, v);
245 return fs->nk++;
246 }
247}
248
249
250int luaK_stringK (FuncState *fs, TString *s) {
251 TValue o;
252 setsvalue(fs->L, &o, s);
253 return addk(fs, &o, &o);
254}
255
256
257int luaK_numberK (FuncState *fs, lua_Number r) {
258 TValue o;
259 setnvalue(&o, r);
260 return addk(fs, &o, &o);
261}
262
263
264static int boolK (FuncState *fs, int b) {
265 TValue o;
266 setbvalue(&o, b);
267 return addk(fs, &o, &o);
268}
269
270
271static int nilK (FuncState *fs) {
272 TValue k, v;
273 setnilvalue(&v);
274 /* cannot use nil as key; instead use table itself to represent nil */
275 sethvalue(fs->L, &k, fs->h);
276 return addk(fs, &k, &v);
277}
278
279
280void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
281 if (e->k == VCALL) { /* expression is an open function call? */
282 SETARG_C(getcode(fs, e), nresults+1);
283 }
284 else if (e->k == VVARARG) {
285 SETARG_B(getcode(fs, e), nresults+1);
286 SETARG_A(getcode(fs, e), fs->freereg);
287 luaK_reserveregs(fs, 1);
288 }
289}
290
291
292void luaK_setoneret (FuncState *fs, expdesc *e) {
293 if (e->k == VCALL) { /* expression is an open function call? */
294 e->k = VNONRELOC;
295 e->u.s.info = GETARG_A(getcode(fs, e));
296 }
297 else if (e->k == VVARARG) {
298 SETARG_B(getcode(fs, e), 2);
299 e->k = VRELOCABLE; /* can relocate its simple result */
300 }
301}
302
303
304void luaK_dischargevars (FuncState *fs, expdesc *e) {
305 switch (e->k) {
306 case VLOCAL: {
307 e->k = VNONRELOC;
308 break;
309 }
310 case VUPVAL: {
311 e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
312 e->k = VRELOCABLE;
313 break;
314 }
315 case VGLOBAL: {
316 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
317 e->k = VRELOCABLE;
318 break;
319 }
320 case VINDEXED: {
321 freereg(fs, e->u.s.aux);
322 freereg(fs, e->u.s.info);
323 e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
324 e->k = VRELOCABLE;
325 break;
326 }
327 case VVARARG:
328 case VCALL: {
329 luaK_setoneret(fs, e);
330 break;
331 }
332 default: break; /* there is one value available (somewhere) */
333 }
334}
335
336
337static int code_label (FuncState *fs, int A, int b, int jump) {
338 luaK_getlabel(fs); /* those instructions may be jump targets */
339 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
340}
341
342
343static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
344 luaK_dischargevars(fs, e);
345 switch (e->k) {
346 case VNIL: {
347 luaK_nil(fs, reg, 1);
348 break;
349 }
350 case VFALSE: case VTRUE: {
351 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
352 break;
353 }
354 case VK: {
355 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
356 break;
357 }
358 case VKNUM: {
359 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
360 break;
361 }
362 case VRELOCABLE: {
363 Instruction *pc = &getcode(fs, e);
364 SETARG_A(*pc, reg);
365 break;
366 }
367 case VNONRELOC: {
368 if (reg != e->u.s.info)
369 luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
370 break;
371 }
372 default: {
373 lua_assert(e->k == VVOID || e->k == VJMP);
374 return; /* nothing to do... */
375 }
376 }
377 e->u.s.info = reg;
378 e->k = VNONRELOC;
379}
380
381
382static void discharge2anyreg (FuncState *fs, expdesc *e) {
383 if (e->k != VNONRELOC) {
384 luaK_reserveregs(fs, 1);
385 discharge2reg(fs, e, fs->freereg-1);
386 }
387}
388
389
390static void exp2reg (FuncState *fs, expdesc *e, int reg) {
391 discharge2reg(fs, e, reg);
392 if (e->k == VJMP)
393 luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
394 if (hasjumps(e)) {
395 int final; /* position after whole expression */
396 int p_f = NO_JUMP; /* position of an eventual LOAD false */
397 int p_t = NO_JUMP; /* position of an eventual LOAD true */
398 if (need_value(fs, e->t) || need_value(fs, e->f)) {
399 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
400 p_f = code_label(fs, reg, 0, 1);
401 p_t = code_label(fs, reg, 1, 0);
402 luaK_patchtohere(fs, fj);
403 }
404 final = luaK_getlabel(fs);
405 patchlistaux(fs, e->f, final, reg, p_f);
406 patchlistaux(fs, e->t, final, reg, p_t);
407 }
408 e->f = e->t = NO_JUMP;
409 e->u.s.info = reg;
410 e->k = VNONRELOC;
411}
412
413
414void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
415 luaK_dischargevars(fs, e);
416 freeexp(fs, e);
417 luaK_reserveregs(fs, 1);
418 exp2reg(fs, e, fs->freereg - 1);
419}
420
421
422int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
423 luaK_dischargevars(fs, e);
424 if (e->k == VNONRELOC) {
425 if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
426 if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
427 exp2reg(fs, e, e->u.s.info); /* put value on it */
428 return e->u.s.info;
429 }
430 }
431 luaK_exp2nextreg(fs, e); /* default */
432 return e->u.s.info;
433}
434
435
436void luaK_exp2val (FuncState *fs, expdesc *e) {
437 if (hasjumps(e))
438 luaK_exp2anyreg(fs, e);
439 else
440 luaK_dischargevars(fs, e);
441}
442
443
444int luaK_exp2RK (FuncState *fs, expdesc *e) {
445 luaK_exp2val(fs, e);
446 switch (e->k) {
447 case VKNUM:
448 case VTRUE:
449 case VFALSE:
450 case VNIL: {
451 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
452 e->u.s.info = (e->k == VNIL) ? nilK(fs) :
453 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
454 boolK(fs, (e->k == VTRUE));
455 e->k = VK;
456 return RKASK(e->u.s.info);
457 }
458 else break;
459 }
460 case VK: {
461 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
462 return RKASK(e->u.s.info);
463 else break;
464 }
465 default: break;
466 }
467 /* not a constant in the right range: put it in a register */
468 return luaK_exp2anyreg(fs, e);
469}
470
471
472void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
473 switch (var->k) {
474 case VLOCAL: {
475 freeexp(fs, ex);
476 exp2reg(fs, ex, var->u.s.info);
477 return;
478 }
479 case VUPVAL: {
480 int e = luaK_exp2anyreg(fs, ex);
481 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
482 break;
483 }
484 case VGLOBAL: {
485 int e = luaK_exp2anyreg(fs, ex);
486 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
487 break;
488 }
489 case VINDEXED: {
490 int e = luaK_exp2RK(fs, ex);
491 luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
492 break;
493 }
494 default: {
495 lua_assert(0); /* invalid var kind to store */
496 break;
497 }
498 }
499 freeexp(fs, ex);
500}
501
502
503void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
504 int func;
505 luaK_exp2anyreg(fs, e);
506 freeexp(fs, e);
507 func = fs->freereg;
508 luaK_reserveregs(fs, 2);
509 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
510 freeexp(fs, key);
511 e->u.s.info = func;
512 e->k = VNONRELOC;
513}
514
515
516static void invertjump (FuncState *fs, expdesc *e) {
517 Instruction *pc = getjumpcontrol(fs, e->u.s.info);
518 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
519 GET_OPCODE(*pc) != OP_TEST);
520 SETARG_A(*pc, !(GETARG_A(*pc)));
521}
522
523
524static int jumponcond (FuncState *fs, expdesc *e, int cond) {
525 if (e->k == VRELOCABLE) {
526 Instruction ie = getcode(fs, e);
527 if (GET_OPCODE(ie) == OP_NOT) {
528 fs->pc--; /* remove previous OP_NOT */
529 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
530 }
531 /* else go through */
532 }
533 discharge2anyreg(fs, e);
534 freeexp(fs, e);
535 return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
536}
537
538
539void luaK_goiftrue (FuncState *fs, expdesc *e) {
540 int pc; /* pc of last jump */
541 luaK_dischargevars(fs, e);
542 switch (e->k) {
543 case VK: case VKNUM: case VTRUE: {
544 pc = NO_JUMP; /* always true; do nothing */
545 break;
546 }
547 case VJMP: {
548 invertjump(fs, e);
549 pc = e->u.s.info;
550 break;
551 }
552 default: {
553 pc = jumponcond(fs, e, 0);
554 break;
555 }
556 }
557 luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
558 luaK_patchtohere(fs, e->t);
559 e->t = NO_JUMP;
560}
561
562
563static void luaK_goiffalse (FuncState *fs, expdesc *e) {
564 int pc; /* pc of last jump */
565 luaK_dischargevars(fs, e);
566 switch (e->k) {
567 case VNIL: case VFALSE: {
568 pc = NO_JUMP; /* always false; do nothing */
569 break;
570 }
571 case VJMP: {
572 pc = e->u.s.info;
573 break;
574 }
575 default: {
576 pc = jumponcond(fs, e, 1);
577 break;
578 }
579 }
580 luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
581 luaK_patchtohere(fs, e->f);
582 e->f = NO_JUMP;
583}
584
585
586static void codenot (FuncState *fs, expdesc *e) {
587 luaK_dischargevars(fs, e);
588 switch (e->k) {
589 case VNIL: case VFALSE: {
590 e->k = VTRUE;
591 break;
592 }
593 case VK: case VKNUM: case VTRUE: {
594 e->k = VFALSE;
595 break;
596 }
597 case VJMP: {
598 invertjump(fs, e);
599 break;
600 }
601 case VRELOCABLE:
602 case VNONRELOC: {
603 discharge2anyreg(fs, e);
604 freeexp(fs, e);
605 e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
606 e->k = VRELOCABLE;
607 break;
608 }
609 default: {
610 lua_assert(0); /* cannot happen */
611 break;
612 }
613 }
614 /* interchange true and false lists */
615 { int temp = e->f; e->f = e->t; e->t = temp; }
616 removevalues(fs, e->f);
617 removevalues(fs, e->t);
618}
619
620
621void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
622 t->u.s.aux = luaK_exp2RK(fs, k);
623 t->k = VINDEXED;
624}
625
626
627static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
628 lua_Number v1, v2, r;
629 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
630 v1 = e1->u.nval;
631 v2 = e2->u.nval;
632 switch (op) {
633 case OP_ADD: r = luai_numadd(v1, v2); break;
634 case OP_SUB: r = luai_numsub(v1, v2); break;
635 case OP_MUL: r = luai_nummul(v1, v2); break;
636 case OP_DIV:
637 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
638 r = luai_numdiv(v1, v2); break;
639 case OP_MOD:
640 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
641 r = luai_nummod(v1, v2); break;
642 case OP_POW: r = luai_numpow(v1, v2); break;
643 case OP_UNM: r = luai_numunm(v1); break;
644 case OP_LEN: return 0; /* no constant folding for 'len' */
645 default: lua_assert(0); r = 0; break;
646 }
647 if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
648 e1->u.nval = r;
649 return 1;
650}
651
652
653static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
654 if (constfolding(op, e1, e2))
655 return;
656 else {
657 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
658 int o1 = luaK_exp2RK(fs, e1);
659 if (o1 > o2) {
660 freeexp(fs, e1);
661 freeexp(fs, e2);
662 }
663 else {
664 freeexp(fs, e2);
665 freeexp(fs, e1);
666 }
667 e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
668 e1->k = VRELOCABLE;
669 }
670}
671
672
673static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
674 expdesc *e2) {
675 int o1 = luaK_exp2RK(fs, e1);
676 int o2 = luaK_exp2RK(fs, e2);
677 freeexp(fs, e2);
678 freeexp(fs, e1);
679 if (cond == 0 && op != OP_EQ) {
680 int temp; /* exchange args to replace by `<' or `<=' */
681 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
682 cond = 1;
683 }
684 e1->u.s.info = condjump(fs, op, cond, o1, o2);
685 e1->k = VJMP;
686}
687
688
689void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
690 expdesc e2;
691 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
692 switch (op) {
693 case OPR_MINUS: {
694 if (!isnumeral(e))
695 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
696 codearith(fs, OP_UNM, e, &e2);
697 break;
698 }
699 case OPR_NOT: codenot(fs, e); break;
700 case OPR_LEN: {
701 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
702 codearith(fs, OP_LEN, e, &e2);
703 break;
704 }
705 default: lua_assert(0);
706 }
707}
708
709
710void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
711 switch (op) {
712 case OPR_AND: {
713 luaK_goiftrue(fs, v);
714 break;
715 }
716 case OPR_OR: {
717 luaK_goiffalse(fs, v);
718 break;
719 }
720 case OPR_CONCAT: {
721 luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
722 break;
723 }
724 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
725 case OPR_MOD: case OPR_POW: {
726 if (!isnumeral(v)) luaK_exp2RK(fs, v);
727 break;
728 }
729 default: {
730 luaK_exp2RK(fs, v);
731 break;
732 }
733 }
734}
735
736
737void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
738 switch (op) {
739 case OPR_AND: {
740 lua_assert(e1->t == NO_JUMP); /* list must be closed */
741 luaK_dischargevars(fs, e2);
742 luaK_concat(fs, &e2->f, e1->f);
743 *e1 = *e2;
744 break;
745 }
746 case OPR_OR: {
747 lua_assert(e1->f == NO_JUMP); /* list must be closed */
748 luaK_dischargevars(fs, e2);
749 luaK_concat(fs, &e2->t, e1->t);
750 *e1 = *e2;
751 break;
752 }
753 case OPR_CONCAT: {
754 luaK_exp2val(fs, e2);
755 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
756 lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
757 freeexp(fs, e1);
758 SETARG_B(getcode(fs, e2), e1->u.s.info);
759 e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
760 }
761 else {
762 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
763 codearith(fs, OP_CONCAT, e1, e2);
764 }
765 break;
766 }
767 case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
768 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
769 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
770 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
771 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
772 case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
773 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
774 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
775 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
776 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
777 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
778 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
779 default: lua_assert(0);
780 }
781}
782
783
784void luaK_fixline (FuncState *fs, int line) {
785 fs->f->lineinfo[fs->pc - 1] = line;
786}
787
788
789static int luaK_code (FuncState *fs, Instruction i, int line) {
790 Proto *f = fs->f;
791 dischargejpc(fs); /* `pc' will change */
792 /* put new instruction in code array */
793 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
794 MAX_INT, "code size overflow");
795 f->code[fs->pc] = i;
796 /* save corresponding line information */
797 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
798 MAX_INT, "code size overflow");
799 f->lineinfo[fs->pc] = line;
800 return fs->pc++;
801}
802
803
804int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
805 lua_assert(getOpMode(o) == iABC);
806 lua_assert(getBMode(o) != OpArgN || b == 0);
807 lua_assert(getCMode(o) != OpArgN || c == 0);
808 return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
809}
810
811
812int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
813 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
814 lua_assert(getCMode(o) == OpArgN);
815 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
816}
817
818
819void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
820 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
821 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
822 lua_assert(tostore != 0);
823 if (c <= MAXARG_C)
824 luaK_codeABC(fs, OP_SETLIST, base, b, c);
825 else {
826 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
827 luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
828 }
829 fs->freereg = base + 1; /* free registers with list values */
830}
831
diff --git a/libraries/LuaJIT-1.1.7/src/lcode.h b/libraries/LuaJIT-1.1.7/src/lcode.h
new file mode 100644
index 0000000..b941c60
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lcode.h
@@ -0,0 +1,76 @@
1/*
2** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $
3** Code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lcode_h
8#define lcode_h
9
10#include "llex.h"
11#include "lobject.h"
12#include "lopcodes.h"
13#include "lparser.h"
14
15
16/*
17** Marks the end of a patch list. It is an invalid value both as an absolute
18** address, and as a list link (would link an element to itself).
19*/
20#define NO_JUMP (-1)
21
22
23/*
24** grep "ORDER OPR" if you change these enums
25*/
26typedef enum BinOpr {
27 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
28 OPR_CONCAT,
29 OPR_NE, OPR_EQ,
30 OPR_LT, OPR_LE, OPR_GT, OPR_GE,
31 OPR_AND, OPR_OR,
32 OPR_NOBINOPR
33} BinOpr;
34
35
36typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
37
38
39#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
40
41#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
42
43#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
44
45LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
46LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
47LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
48LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
49LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
50LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
51LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
52LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
53LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
54LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
55LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
56LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
57LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
58LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
59LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
60LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
61LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
62LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
63LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
64LUAI_FUNC int luaK_jump (FuncState *fs);
65LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
66LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
67LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
68LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
69LUAI_FUNC int luaK_getlabel (FuncState *fs);
70LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
71LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
72LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
73LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
74
75
76#endif
diff --git a/libraries/LuaJIT-1.1.7/src/ldblib.c b/libraries/LuaJIT-1.1.7/src/ldblib.c
new file mode 100644
index 0000000..21116ac
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ldblib.c
@@ -0,0 +1,398 @@
1/*
2** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $
3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define ldblib_c
13#define LUA_LIB
14
15#include "lua.h"
16
17#include "lauxlib.h"
18#include "lualib.h"
19
20
21
22static int db_getregistry (lua_State *L) {
23 lua_pushvalue(L, LUA_REGISTRYINDEX);
24 return 1;
25}
26
27
28static int db_getmetatable (lua_State *L) {
29 luaL_checkany(L, 1);
30 if (!lua_getmetatable(L, 1)) {
31 lua_pushnil(L); /* no metatable */
32 }
33 return 1;
34}
35
36
37static int db_setmetatable (lua_State *L) {
38 int t = lua_type(L, 2);
39 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
40 "nil or table expected");
41 lua_settop(L, 2);
42 lua_pushboolean(L, lua_setmetatable(L, 1));
43 return 1;
44}
45
46
47static int db_getfenv (lua_State *L) {
48 luaL_checkany(L, 1);
49 lua_getfenv(L, 1);
50 return 1;
51}
52
53
54static int db_setfenv (lua_State *L) {
55 luaL_checktype(L, 2, LUA_TTABLE);
56 lua_settop(L, 2);
57 if (lua_setfenv(L, 1) == 0)
58 luaL_error(L, LUA_QL("setfenv")
59 " cannot change environment of given object");
60 return 1;
61}
62
63
64static void settabss (lua_State *L, const char *i, const char *v) {
65 lua_pushstring(L, v);
66 lua_setfield(L, -2, i);
67}
68
69
70static void settabsi (lua_State *L, const char *i, int v) {
71 lua_pushinteger(L, v);
72 lua_setfield(L, -2, i);
73}
74
75
76static lua_State *getthread (lua_State *L, int *arg) {
77 if (lua_isthread(L, 1)) {
78 *arg = 1;
79 return lua_tothread(L, 1);
80 }
81 else {
82 *arg = 0;
83 return L;
84 }
85}
86
87
88static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
89 if (L == L1) {
90 lua_pushvalue(L, -2);
91 lua_remove(L, -3);
92 }
93 else
94 lua_xmove(L1, L, 1);
95 lua_setfield(L, -2, fname);
96}
97
98
99static int db_getinfo (lua_State *L) {
100 lua_Debug ar;
101 int arg;
102 lua_State *L1 = getthread(L, &arg);
103 const char *options = luaL_optstring(L, arg+2, "flnSu");
104 if (lua_isnumber(L, arg+1)) {
105 if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
106 lua_pushnil(L); /* level out of range */
107 return 1;
108 }
109 }
110 else if (lua_isfunction(L, arg+1)) {
111 lua_pushfstring(L, ">%s", options);
112 options = lua_tostring(L, -1);
113 lua_pushvalue(L, arg+1);
114 lua_xmove(L, L1, 1);
115 }
116 else
117 return luaL_argerror(L, arg+1, "function or level expected");
118 if (!lua_getinfo(L1, options, &ar))
119 return luaL_argerror(L, arg+2, "invalid option");
120 lua_createtable(L, 0, 2);
121 if (strchr(options, 'S')) {
122 settabss(L, "source", ar.source);
123 settabss(L, "short_src", ar.short_src);
124 settabsi(L, "linedefined", ar.linedefined);
125 settabsi(L, "lastlinedefined", ar.lastlinedefined);
126 settabss(L, "what", ar.what);
127 }
128 if (strchr(options, 'l'))
129 settabsi(L, "currentline", ar.currentline);
130 if (strchr(options, 'u'))
131 settabsi(L, "nups", ar.nups);
132 if (strchr(options, 'n')) {
133 settabss(L, "name", ar.name);
134 settabss(L, "namewhat", ar.namewhat);
135 }
136 if (strchr(options, 'L'))
137 treatstackoption(L, L1, "activelines");
138 if (strchr(options, 'f'))
139 treatstackoption(L, L1, "func");
140 return 1; /* return table */
141}
142
143
144static int db_getlocal (lua_State *L) {
145 int arg;
146 lua_State *L1 = getthread(L, &arg);
147 lua_Debug ar;
148 const char *name;
149 if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
150 return luaL_argerror(L, arg+1, "level out of range");
151 name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
152 if (name) {
153 lua_xmove(L1, L, 1);
154 lua_pushstring(L, name);
155 lua_pushvalue(L, -2);
156 return 2;
157 }
158 else {
159 lua_pushnil(L);
160 return 1;
161 }
162}
163
164
165static int db_setlocal (lua_State *L) {
166 int arg;
167 lua_State *L1 = getthread(L, &arg);
168 lua_Debug ar;
169 if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
170 return luaL_argerror(L, arg+1, "level out of range");
171 luaL_checkany(L, arg+3);
172 lua_settop(L, arg+3);
173 lua_xmove(L, L1, 1);
174 lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
175 return 1;
176}
177
178
179static int auxupvalue (lua_State *L, int get) {
180 const char *name;
181 int n = luaL_checkint(L, 2);
182 luaL_checktype(L, 1, LUA_TFUNCTION);
183 if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
184 name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
185 if (name == NULL) return 0;
186 lua_pushstring(L, name);
187 lua_insert(L, -(get+1));
188 return get + 1;
189}
190
191
192static int db_getupvalue (lua_State *L) {
193 return auxupvalue(L, 1);
194}
195
196
197static int db_setupvalue (lua_State *L) {
198 luaL_checkany(L, 3);
199 return auxupvalue(L, 0);
200}
201
202
203
204static const char KEY_HOOK = 'h';
205
206
207static void hookf (lua_State *L, lua_Debug *ar) {
208 static const char *const hooknames[] =
209 {"call", "return", "line", "count", "tail return"};
210 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
211 lua_rawget(L, LUA_REGISTRYINDEX);
212 lua_pushlightuserdata(L, L);
213 lua_rawget(L, -2);
214 if (lua_isfunction(L, -1)) {
215 lua_pushstring(L, hooknames[(int)ar->event]);
216 if (ar->currentline >= 0)
217 lua_pushinteger(L, ar->currentline);
218 else lua_pushnil(L);
219 lua_assert(lua_getinfo(L, "lS", ar));
220 lua_call(L, 2, 0);
221 }
222}
223
224
225static int makemask (const char *smask, int count) {
226 int mask = 0;
227 if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
228 if (strchr(smask, 'r')) mask |= LUA_MASKRET;
229 if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
230 if (count > 0) mask |= LUA_MASKCOUNT;
231 return mask;
232}
233
234
235static char *unmakemask (int mask, char *smask) {
236 int i = 0;
237 if (mask & LUA_MASKCALL) smask[i++] = 'c';
238 if (mask & LUA_MASKRET) smask[i++] = 'r';
239 if (mask & LUA_MASKLINE) smask[i++] = 'l';
240 smask[i] = '\0';
241 return smask;
242}
243
244
245static void gethooktable (lua_State *L) {
246 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
247 lua_rawget(L, LUA_REGISTRYINDEX);
248 if (!lua_istable(L, -1)) {
249 lua_pop(L, 1);
250 lua_createtable(L, 0, 1);
251 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
252 lua_pushvalue(L, -2);
253 lua_rawset(L, LUA_REGISTRYINDEX);
254 }
255}
256
257
258static int db_sethook (lua_State *L) {
259 int arg, mask, count;
260 lua_Hook func;
261 lua_State *L1 = getthread(L, &arg);
262 if (lua_isnoneornil(L, arg+1)) {
263 lua_settop(L, arg+1);
264 func = NULL; mask = 0; count = 0; /* turn off hooks */
265 }
266 else {
267 const char *smask = luaL_checkstring(L, arg+2);
268 luaL_checktype(L, arg+1, LUA_TFUNCTION);
269 count = luaL_optint(L, arg+3, 0);
270 func = hookf; mask = makemask(smask, count);
271 }
272 gethooktable(L);
273 lua_pushlightuserdata(L, L1);
274 lua_pushvalue(L, arg+1);
275 lua_rawset(L, -3); /* set new hook */
276 lua_pop(L, 1); /* remove hook table */
277 lua_sethook(L1, func, mask, count); /* set hooks */
278 return 0;
279}
280
281
282static int db_gethook (lua_State *L) {
283 int arg;
284 lua_State *L1 = getthread(L, &arg);
285 char buff[5];
286 int mask = lua_gethookmask(L1);
287 lua_Hook hook = lua_gethook(L1);
288 if (hook != NULL && hook != hookf) /* external hook? */
289 lua_pushliteral(L, "external hook");
290 else {
291 gethooktable(L);
292 lua_pushlightuserdata(L, L1);
293 lua_rawget(L, -2); /* get hook */
294 lua_remove(L, -2); /* remove hook table */
295 }
296 lua_pushstring(L, unmakemask(mask, buff));
297 lua_pushinteger(L, lua_gethookcount(L1));
298 return 3;
299}
300
301
302static int db_debug (lua_State *L) {
303 for (;;) {
304 char buffer[250];
305 fputs("lua_debug> ", stderr);
306 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
307 strcmp(buffer, "cont\n") == 0)
308 return 0;
309 if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
310 lua_pcall(L, 0, 0, 0)) {
311 fputs(lua_tostring(L, -1), stderr);
312 fputs("\n", stderr);
313 }
314 lua_settop(L, 0); /* remove eventual returns */
315 }
316}
317
318
319#define LEVELS1 12 /* size of the first part of the stack */
320#define LEVELS2 10 /* size of the second part of the stack */
321
322static int db_errorfb (lua_State *L) {
323 int level;
324 int firstpart = 1; /* still before eventual `...' */
325 int arg;
326 lua_State *L1 = getthread(L, &arg);
327 lua_Debug ar;
328 if (lua_isnumber(L, arg+2)) {
329 level = (int)lua_tointeger(L, arg+2);
330 lua_pop(L, 1);
331 }
332 else
333 level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
334 if (lua_gettop(L) == arg)
335 lua_pushliteral(L, "");
336 else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
337 else lua_pushliteral(L, "\n");
338 lua_pushliteral(L, "stack traceback:");
339 while (lua_getstack(L1, level++, &ar)) {
340 if (level > LEVELS1 && firstpart) {
341 /* no more than `LEVELS2' more levels? */
342 if (!lua_getstack(L1, level+LEVELS2, &ar))
343 level--; /* keep going */
344 else {
345 lua_pushliteral(L, "\n\t..."); /* too many levels */
346 while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
347 level++;
348 }
349 firstpart = 0;
350 continue;
351 }
352 lua_pushliteral(L, "\n\t");
353 lua_getinfo(L1, "Snl", &ar);
354 lua_pushfstring(L, "%s:", ar.short_src);
355 if (ar.currentline > 0)
356 lua_pushfstring(L, "%d:", ar.currentline);
357 if (*ar.namewhat != '\0') /* is there a name? */
358 lua_pushfstring(L, " in function " LUA_QS, ar.name);
359 else {
360 if (*ar.what == 'm') /* main? */
361 lua_pushfstring(L, " in main chunk");
362 else if (*ar.what == 'C' || *ar.what == 't')
363 lua_pushliteral(L, " ?"); /* C function or tail call */
364 else
365 lua_pushfstring(L, " in function <%s:%d>",
366 ar.short_src, ar.linedefined);
367 }
368 lua_concat(L, lua_gettop(L) - arg);
369 }
370 lua_concat(L, lua_gettop(L) - arg);
371 return 1;
372}
373
374
375static const luaL_Reg dblib[] = {
376 {"debug", db_debug},
377 {"getfenv", db_getfenv},
378 {"gethook", db_gethook},
379 {"getinfo", db_getinfo},
380 {"getlocal", db_getlocal},
381 {"getregistry", db_getregistry},
382 {"getmetatable", db_getmetatable},
383 {"getupvalue", db_getupvalue},
384 {"setfenv", db_setfenv},
385 {"sethook", db_sethook},
386 {"setlocal", db_setlocal},
387 {"setmetatable", db_setmetatable},
388 {"setupvalue", db_setupvalue},
389 {"traceback", db_errorfb},
390 {NULL, NULL}
391};
392
393
394LUALIB_API int luaopen_debug (lua_State *L) {
395 luaL_register(L, LUA_DBLIBNAME, dblib);
396 return 1;
397}
398
diff --git a/libraries/LuaJIT-1.1.7/src/ldebug.c b/libraries/LuaJIT-1.1.7/src/ldebug.c
new file mode 100644
index 0000000..89891fd
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ldebug.c
@@ -0,0 +1,640 @@
1/*
2** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $
3** Debug Interface
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdarg.h>
9#include <stddef.h>
10#include <string.h>
11
12
13#define ldebug_c
14#define LUA_CORE
15
16#include "lua.h"
17
18#include "lapi.h"
19#include "lcode.h"
20#include "ldebug.h"
21#include "ldo.h"
22#include "lfunc.h"
23#include "lobject.h"
24#include "lopcodes.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29#include "lvm.h"
30#include "ljit.h"
31
32
33
34static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
35
36
37static int currentpc (lua_State *L, CallInfo *ci) {
38 if (isLua(ci)) /* must be a Lua function to get current PC */
39 return luaJIT_findpc(ci_func(ci)->l.p,
40 ci==L->ci ? L->savedpc : ci->savedpc);
41 else
42 return -1;
43}
44
45
46static int currentline (lua_State *L, CallInfo *ci) {
47 int pc = currentpc(L, ci);
48 if (pc < 0)
49 return -1; /* only active lua functions have current-line information */
50 else
51 return getline(ci_func(ci)->l.p, pc);
52}
53
54
55/*
56** this function can be called asynchronous (e.g. during a signal)
57*/
58LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
59 if (func == NULL || mask == 0) { /* turn off hooks? */
60 mask = 0;
61 func = NULL;
62 }
63 L->hook = func;
64 L->basehookcount = count;
65 resethookcount(L);
66 L->hookmask = cast_byte(mask);
67 return 1;
68}
69
70
71LUA_API lua_Hook lua_gethook (lua_State *L) {
72 return L->hook;
73}
74
75
76LUA_API int lua_gethookmask (lua_State *L) {
77 return L->hookmask;
78}
79
80
81LUA_API int lua_gethookcount (lua_State *L) {
82 return L->basehookcount;
83}
84
85
86LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
87 int status;
88 CallInfo *ci;
89 lua_lock(L);
90 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
91 level--;
92 if (f_isLua(ci)) /* Lua function? */
93 level -= ci->tailcalls; /* skip lost tail calls */
94 }
95 if (level == 0 && ci > L->base_ci) { /* level found? */
96 status = 1;
97 ar->i_ci = cast_int(ci - L->base_ci);
98 }
99 else if (level < 0) { /* level is of a lost tail call? */
100 status = 1;
101 ar->i_ci = 0;
102 }
103 else status = 0; /* no such level */
104 lua_unlock(L);
105 return status;
106}
107
108
109static Proto *getluaproto (CallInfo *ci) {
110 return (isLua(ci) ? ci_func(ci)->l.p : NULL);
111}
112
113
114static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
115 const char *name;
116 Proto *fp = getluaproto(ci);
117 if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
118 return name; /* is a local variable in a Lua function */
119 else {
120 StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
121 if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
122 return "(*temporary)";
123 else
124 return NULL;
125 }
126}
127
128
129LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
130 CallInfo *ci = L->base_ci + ar->i_ci;
131 const char *name = findlocal(L, ci, n);
132 lua_lock(L);
133 if (name)
134 luaA_pushobject(L, ci->base + (n - 1));
135 lua_unlock(L);
136 return name;
137}
138
139
140LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
141 CallInfo *ci = L->base_ci + ar->i_ci;
142 const char *name = findlocal(L, ci, n);
143 lua_lock(L);
144 if (name)
145 setobjs2s(L, ci->base + (n - 1), L->top - 1);
146 L->top--; /* pop value */
147 lua_unlock(L);
148 return name;
149}
150
151
152static void funcinfo (lua_Debug *ar, Closure *cl) {
153 if (cl->c.isC) {
154 ar->source = "=[C]";
155 ar->linedefined = -1;
156 ar->lastlinedefined = -1;
157 ar->what = "C";
158 }
159 else {
160 ar->source = getstr(cl->l.p->source);
161 ar->linedefined = cl->l.p->linedefined;
162 ar->lastlinedefined = cl->l.p->lastlinedefined;
163 ar->what = (ar->linedefined == 0) ? "main" : "Lua";
164 }
165 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
166}
167
168
169static void info_tailcall (lua_Debug *ar) {
170 ar->name = ar->namewhat = "";
171 ar->what = "tail";
172 ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
173 ar->source = "=(tail call)";
174 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
175 ar->nups = 0;
176}
177
178
179static void collectvalidlines (lua_State *L, Closure *f) {
180 if (f == NULL || f->c.isC) {
181 setnilvalue(L->top);
182 }
183 else {
184 Table *t = luaH_new(L, 0, 0);
185 int *lineinfo = f->l.p->lineinfo;
186 int i;
187 for (i=0; i<f->l.p->sizelineinfo; i++)
188 setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
189 sethvalue(L, L->top, t);
190 }
191 incr_top(L);
192}
193
194
195static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
196 Closure *f, CallInfo *ci) {
197 int status = 1;
198 if (f == NULL) {
199 info_tailcall(ar);
200 return status;
201 }
202 for (; *what; what++) {
203 switch (*what) {
204 case 'S': {
205 funcinfo(ar, f);
206 break;
207 }
208 case 'l': {
209 ar->currentline = (ci) ? currentline(L, ci) : -1;
210 break;
211 }
212 case 'u': {
213 ar->nups = f->c.nupvalues;
214 break;
215 }
216 case 'n': {
217 ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
218 if (ar->namewhat == NULL) {
219 ar->namewhat = ""; /* not found */
220 ar->name = NULL;
221 }
222 break;
223 }
224 case 'L':
225 case 'f': /* handled by lua_getinfo */
226 break;
227 default: status = 0; /* invalid option */
228 }
229 }
230 return status;
231}
232
233
234LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
235 int status;
236 Closure *f = NULL;
237 CallInfo *ci = NULL;
238 lua_lock(L);
239 if (*what == '>') {
240 StkId func = L->top - 1;
241 luai_apicheck(L, ttisfunction(func));
242 what++; /* skip the '>' */
243 f = clvalue(func);
244 L->top--; /* pop function */
245 }
246 else if (ar->i_ci != 0) { /* no tail call? */
247 ci = L->base_ci + ar->i_ci;
248 lua_assert(ttisfunction(ci->func));
249 f = clvalue(ci->func);
250 }
251 status = auxgetinfo(L, what, ar, f, ci);
252 if (strchr(what, 'f')) {
253 if (f == NULL) setnilvalue(L->top);
254 else setclvalue(L, L->top, f);
255 incr_top(L);
256 }
257 if (strchr(what, 'L'))
258 collectvalidlines(L, f);
259 lua_unlock(L);
260 return status;
261}
262
263
264/*
265** {======================================================
266** Symbolic Execution and code checker
267** =======================================================
268*/
269
270#define check(x) if (!(x)) return 0;
271
272#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
273
274#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
275
276
277
278static int precheck (const Proto *pt) {
279 check(pt->maxstacksize <= MAXSTACK);
280 check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
281 check(!(pt->is_vararg & VARARG_NEEDSARG) ||
282 (pt->is_vararg & VARARG_HASARG));
283 check(pt->sizeupvalues <= pt->nups);
284 check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
285 check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
286 return 1;
287}
288
289
290#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
291
292int luaG_checkopenop (Instruction i) {
293 switch (GET_OPCODE(i)) {
294 case OP_CALL:
295 case OP_TAILCALL:
296 case OP_RETURN:
297 case OP_SETLIST: {
298 check(GETARG_B(i) == 0);
299 return 1;
300 }
301 default: return 0; /* invalid instruction after an open call */
302 }
303}
304
305
306static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
307 switch (mode) {
308 case OpArgN: check(r == 0); break;
309 case OpArgU: break;
310 case OpArgR: checkreg(pt, r); break;
311 case OpArgK:
312 check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
313 break;
314 }
315 return 1;
316}
317
318
319static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
320 int pc;
321 int last; /* stores position of last instruction that changed `reg' */
322 last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
323 check(precheck(pt));
324 for (pc = 0; pc < lastpc; pc++) {
325 Instruction i = pt->code[pc];
326 OpCode op = GET_OPCODE(i);
327 int a = GETARG_A(i);
328 int b = 0;
329 int c = 0;
330 check(op < NUM_OPCODES);
331 checkreg(pt, a);
332 switch (getOpMode(op)) {
333 case iABC: {
334 b = GETARG_B(i);
335 c = GETARG_C(i);
336 check(checkArgMode(pt, b, getBMode(op)));
337 check(checkArgMode(pt, c, getCMode(op)));
338 break;
339 }
340 case iABx: {
341 b = GETARG_Bx(i);
342 if (getBMode(op) == OpArgK) check(b < pt->sizek);
343 break;
344 }
345 case iAsBx: {
346 b = GETARG_sBx(i);
347 if (getBMode(op) == OpArgR) {
348 int dest = pc+1+b;
349 check(0 <= dest && dest < pt->sizecode);
350 if (dest > 0) {
351 int j;
352 /* check that it does not jump to a setlist count; this
353 is tricky, because the count from a previous setlist may
354 have the same value of an invalid setlist; so, we must
355 go all the way back to the first of them (if any) */
356 for (j = 0; j < dest; j++) {
357 Instruction d = pt->code[dest-1-j];
358 if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break;
359 }
360 /* if 'j' is even, previous value is not a setlist (even if
361 it looks like one) */
362 check((j&1) == 0);
363 }
364 }
365 break;
366 }
367 }
368 if (testAMode(op)) {
369 if (a == reg) last = pc; /* change register `a' */
370 }
371 if (testTMode(op)) {
372 check(pc+2 < pt->sizecode); /* check skip */
373 check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
374 }
375 switch (op) {
376 case OP_LOADBOOL: {
377 if (c == 1) { /* does it jump? */
378 check(pc+2 < pt->sizecode); /* check its jump */
379 check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
380 GETARG_C(pt->code[pc+1]) != 0);
381 }
382 break;
383 }
384 case OP_LOADNIL: {
385 if (a <= reg && reg <= b)
386 last = pc; /* set registers from `a' to `b' */
387 break;
388 }
389 case OP_GETUPVAL:
390 case OP_SETUPVAL: {
391 check(b < pt->nups);
392 break;
393 }
394 case OP_GETGLOBAL:
395 case OP_SETGLOBAL: {
396 check(ttisstring(&pt->k[b]));
397 break;
398 }
399 case OP_SELF: {
400 checkreg(pt, a+1);
401 if (reg == a+1) last = pc;
402 break;
403 }
404 case OP_CONCAT: {
405 check(b < c); /* at least two operands */
406 break;
407 }
408 case OP_TFORLOOP: {
409 check(c >= 1); /* at least one result (control variable) */
410 checkreg(pt, a+2+c); /* space for results */
411 if (reg >= a+2) last = pc; /* affect all regs above its base */
412 break;
413 }
414 case OP_FORLOOP:
415 case OP_FORPREP:
416 checkreg(pt, a+3);
417 /* go through */
418 case OP_JMP: {
419 int dest = pc+1+b;
420 /* not full check and jump is forward and do not skip `lastpc'? */
421 if (reg != NO_REG && pc < dest && dest <= lastpc)
422 pc += b; /* do the jump */
423 break;
424 }
425 case OP_CALL:
426 case OP_TAILCALL: {
427 if (b != 0) {
428 checkreg(pt, a+b-1);
429 }
430 c--; /* c = num. returns */
431 if (c == LUA_MULTRET) {
432 check(checkopenop(pt, pc));
433 }
434 else if (c != 0)
435 checkreg(pt, a+c-1);
436 if (reg >= a) last = pc; /* affect all registers above base */
437 break;
438 }
439 case OP_RETURN: {
440 b--; /* b = num. returns */
441 if (b > 0) checkreg(pt, a+b-1);
442 break;
443 }
444 case OP_SETLIST: {
445 if (b > 0) checkreg(pt, a + b);
446 if (c == 0) {
447 pc++;
448 check(pc < pt->sizecode - 1);
449 }
450 break;
451 }
452 case OP_CLOSURE: {
453 int nup, j;
454 check(b < pt->sizep);
455 nup = pt->p[b]->nups;
456 check(pc + nup < pt->sizecode);
457 for (j = 1; j <= nup; j++) {
458 OpCode op1 = GET_OPCODE(pt->code[pc + j]);
459 check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
460 }
461 if (reg != NO_REG) /* tracing? */
462 pc += nup; /* do not 'execute' these pseudo-instructions */
463 break;
464 }
465 case OP_VARARG: {
466 check((pt->is_vararg & VARARG_ISVARARG) &&
467 !(pt->is_vararg & VARARG_NEEDSARG));
468 b--;
469 if (b == LUA_MULTRET) check(checkopenop(pt, pc));
470 checkreg(pt, a+b-1);
471 break;
472 }
473 default: break;
474 }
475 }
476 return pt->code[last];
477}
478
479#undef check
480#undef checkjump
481#undef checkreg
482
483/* }====================================================== */
484
485
486int luaG_checkcode (const Proto *pt) {
487 return (symbexec(pt, pt->sizecode, NO_REG) != 0);
488}
489
490
491static const char *kname (Proto *p, int c) {
492 if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
493 return svalue(&p->k[INDEXK(c)]);
494 else
495 return "?";
496}
497
498
499static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
500 const char **name) {
501 if (isLua(ci)) { /* a Lua function? */
502 Proto *p = ci_func(ci)->l.p;
503 int pc = currentpc(L, ci);
504 Instruction i;
505 *name = luaF_getlocalname(p, stackpos+1, pc);
506 if (*name) /* is a local? */
507 return "local";
508 i = symbexec(p, pc, stackpos); /* try symbolic execution */
509 lua_assert(pc != -1);
510 switch (GET_OPCODE(i)) {
511 case OP_GETGLOBAL: {
512 int g = GETARG_Bx(i); /* global index */
513 lua_assert(ttisstring(&p->k[g]));
514 *name = svalue(&p->k[g]);
515 return "global";
516 }
517 case OP_MOVE: {
518 int a = GETARG_A(i);
519 int b = GETARG_B(i); /* move from `b' to `a' */
520 if (b < a)
521 return getobjname(L, ci, b, name); /* get name for `b' */
522 break;
523 }
524 case OP_GETTABLE: {
525 int k = GETARG_C(i); /* key index */
526 *name = kname(p, k);
527 return "field";
528 }
529 case OP_GETUPVAL: {
530 int u = GETARG_B(i); /* upvalue index */
531 *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
532 return "upvalue";
533 }
534 case OP_SELF: {
535 int k = GETARG_C(i); /* key index */
536 *name = kname(p, k);
537 return "method";
538 }
539 default: break;
540 }
541 }
542 return NULL; /* no useful name found */
543}
544
545
546static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
547 Instruction i;
548 if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
549 return NULL; /* calling function is not Lua (or is unknown) */
550 ci--; /* calling function */
551 i = ci_func(ci)->l.p->code[currentpc(L, ci)];
552 if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
553 GET_OPCODE(i) == OP_TFORLOOP)
554 return getobjname(L, ci, GETARG_A(i), name);
555 else
556 return NULL; /* no useful name can be found */
557}
558
559
560/* only ANSI way to check whether a pointer points to an array */
561static int isinstack (CallInfo *ci, const TValue *o) {
562 StkId p;
563 for (p = ci->base; p < ci->top; p++)
564 if (o == p) return 1;
565 return 0;
566}
567
568
569void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
570 const char *name = NULL;
571 const char *t = luaT_typenames[ttype(o)];
572 const char *kind = (isinstack(L->ci, o)) ?
573 getobjname(L, L->ci, cast_int(o - L->base), &name) :
574 NULL;
575 if (kind)
576 luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
577 op, kind, name, t);
578 else
579 luaG_runerror(L, "attempt to %s a %s value", op, t);
580}
581
582
583void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
584 if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
585 lua_assert(!ttisstring(p1) && !ttisnumber(p1));
586 luaG_typeerror(L, p1, "concatenate");
587}
588
589
590void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
591 TValue temp;
592 if (luaV_tonumber(p1, &temp) == NULL)
593 p2 = p1; /* first operand is wrong */
594 luaG_typeerror(L, p2, "perform arithmetic on");
595}
596
597
598int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
599 const char *t1 = luaT_typenames[ttype(p1)];
600 const char *t2 = luaT_typenames[ttype(p2)];
601 if (t1[2] == t2[2])
602 luaG_runerror(L, "attempt to compare two %s values", t1);
603 else
604 luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
605 return 0;
606}
607
608
609static void addinfo (lua_State *L, const char *msg) {
610 CallInfo *ci = L->ci;
611 if (isLua(ci)) { /* is Lua code? */
612 char buff[LUA_IDSIZE]; /* add file:line information */
613 int line = currentline(L, ci);
614 luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
615 luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
616 }
617}
618
619
620void luaG_errormsg (lua_State *L) {
621 if (L->errfunc != 0) { /* is there an error handling function? */
622 StkId errfunc = restorestack(L, L->errfunc);
623 if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
624 setobjs2s(L, L->top, L->top - 1); /* move argument */
625 setobjs2s(L, L->top - 1, errfunc); /* push function */
626 incr_top(L);
627 luaD_call(L, L->top - 2, 1); /* call it */
628 }
629 luaD_throw(L, LUA_ERRRUN);
630}
631
632
633void luaG_runerror (lua_State *L, const char *fmt, ...) {
634 va_list argp;
635 va_start(argp, fmt);
636 addinfo(L, luaO_pushvfstring(L, fmt, argp));
637 va_end(argp);
638 luaG_errormsg(L);
639}
640
diff --git a/libraries/LuaJIT-1.1.7/src/ldebug.h b/libraries/LuaJIT-1.1.7/src/ldebug.h
new file mode 100644
index 0000000..ba28a97
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ldebug.h
@@ -0,0 +1,33 @@
1/*
2** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $
3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ldebug_h
8#define ldebug_h
9
10
11#include "lstate.h"
12
13
14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15
16#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
17
18#define resethookcount(L) (L->hookcount = L->basehookcount)
19
20
21LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
22 const char *opname);
23LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
24LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
25 const TValue *p2);
26LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
27 const TValue *p2);
28LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
29LUAI_FUNC void luaG_errormsg (lua_State *L);
30LUAI_FUNC int luaG_checkcode (const Proto *pt);
31LUAI_FUNC int luaG_checkopenop (Instruction i);
32
33#endif
diff --git a/libraries/LuaJIT-1.1.7/src/ldo.c b/libraries/LuaJIT-1.1.7/src/ldo.c
new file mode 100644
index 0000000..1d9393d
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ldo.c
@@ -0,0 +1,519 @@
1/*
2** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $
3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#include <setjmp.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define ldo_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lfunc.h"
20#include "lgc.h"
21#include "lmem.h"
22#include "lobject.h"
23#include "lopcodes.h"
24#include "lparser.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29#include "lundump.h"
30#include "lvm.h"
31#include "lzio.h"
32#include "ljit.h"
33
34
35
36
37/*
38** {======================================================
39** Error-recovery functions
40** =======================================================
41*/
42
43
44/* chain list of long jump buffers */
45struct lua_longjmp {
46 struct lua_longjmp *previous;
47 luai_jmpbuf b;
48 volatile int status; /* error code */
49};
50
51
52void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
53 switch (errcode) {
54 case LUA_ERRMEM: {
55 setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
56 break;
57 }
58 case LUA_ERRERR: {
59 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
60 break;
61 }
62 case LUA_ERRSYNTAX:
63 case LUA_ERRRUN: {
64 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
65 break;
66 }
67 }
68 L->top = oldtop + 1;
69}
70
71
72static void restore_stack_limit (lua_State *L) {
73 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
74 if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
75 int inuse = cast_int(L->ci - L->base_ci);
76 if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
77 luaD_reallocCI(L, LUAI_MAXCALLS);
78 }
79}
80
81
82static void resetstack (lua_State *L, int status) {
83 L->ci = L->base_ci;
84 L->base = L->ci->base;
85 luaF_close(L, L->base); /* close eventual pending closures */
86 luaD_seterrorobj(L, status, L->base);
87 L->nCcalls = 0;
88 L->allowhook = 1;
89 restore_stack_limit(L);
90 L->errfunc = 0;
91 L->errorJmp = NULL;
92}
93
94
95void luaD_throw (lua_State *L, int errcode) {
96 if (L->errorJmp) {
97 L->errorJmp->status = errcode;
98 LUAI_THROW(L, L->errorJmp);
99 }
100 else {
101 L->status = cast_byte(errcode);
102 if (G(L)->panic) {
103 resetstack(L, errcode);
104 lua_unlock(L);
105 G(L)->panic(L);
106 }
107 exit(EXIT_FAILURE);
108 }
109}
110
111
112int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
113 struct lua_longjmp lj;
114 lj.status = 0;
115 lj.previous = L->errorJmp; /* chain new error handler */
116 L->errorJmp = &lj;
117 LUAI_TRY(L, &lj,
118 (*f)(L, ud);
119 );
120 L->errorJmp = lj.previous; /* restore old error handler */
121 return lj.status;
122}
123
124/* }====================================================== */
125
126
127static void correctstack (lua_State *L, TValue *oldstack) {
128 CallInfo *ci;
129 GCObject *up;
130 L->top = (L->top - oldstack) + L->stack;
131 for (up = L->openupval; up != NULL; up = up->gch.next)
132 gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
133 for (ci = L->base_ci; ci <= L->ci; ci++) {
134 ci->top = (ci->top - oldstack) + L->stack;
135 ci->base = (ci->base - oldstack) + L->stack;
136 ci->func = (ci->func - oldstack) + L->stack;
137 }
138 L->base = (L->base - oldstack) + L->stack;
139}
140
141
142void luaD_reallocstack (lua_State *L, int newsize) {
143 TValue *oldstack = L->stack;
144 int realsize = newsize + 1 + EXTRA_STACK;
145 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
146 luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
147 L->stacksize = realsize;
148 L->stack_last = L->stack+newsize;
149 correctstack(L, oldstack);
150}
151
152
153void luaD_reallocCI (lua_State *L, int newsize) {
154 CallInfo *oldci = L->base_ci;
155 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
156 L->size_ci = newsize;
157 L->ci = (L->ci - oldci) + L->base_ci;
158 L->end_ci = L->base_ci + L->size_ci - 1;
159}
160
161
162void luaD_growstack (lua_State *L, int n) {
163 if (n <= L->stacksize) /* double size is enough? */
164 luaD_reallocstack(L, 2*L->stacksize);
165 else
166 luaD_reallocstack(L, L->stacksize + n);
167}
168
169
170CallInfo *luaD_growCI (lua_State *L) {
171 if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */
172 luaD_throw(L, LUA_ERRERR);
173 else {
174 luaD_reallocCI(L, 2*L->size_ci);
175 if (L->size_ci > LUAI_MAXCALLS)
176 luaG_runerror(L, "stack overflow");
177 }
178 return ++L->ci;
179}
180
181
182void luaD_callhook (lua_State *L, int event, int line) {
183 lua_Hook hook = L->hook;
184 if (hook && L->allowhook) {
185 ptrdiff_t top = savestack(L, L->top);
186 ptrdiff_t ci_top = savestack(L, L->ci->top);
187 lua_Debug ar;
188 ar.event = event;
189 ar.currentline = line;
190 if (event == LUA_HOOKTAILRET)
191 ar.i_ci = 0; /* tail call; no debug information about it */
192 else
193 ar.i_ci = cast_int(L->ci - L->base_ci);
194 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
195 L->ci->top = L->top + LUA_MINSTACK;
196 lua_assert(L->ci->top <= L->stack_last);
197 L->allowhook = 0; /* cannot call hooks inside a hook */
198 lua_unlock(L);
199 (*hook)(L, &ar);
200 lua_lock(L);
201 lua_assert(!L->allowhook);
202 L->allowhook = 1;
203 L->ci->top = restorestack(L, ci_top);
204 L->top = restorestack(L, top);
205 }
206}
207
208
209static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
210 int i;
211 int nfixargs = p->numparams;
212 Table *htab = NULL;
213 StkId base, fixed;
214 for (; actual < nfixargs; ++actual)
215 setnilvalue(L->top++);
216#if defined(LUA_COMPAT_VARARG)
217 if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
218 int nvar = actual - nfixargs; /* number of extra arguments */
219 lua_assert(p->is_vararg & VARARG_HASARG);
220 luaC_checkGC(L);
221 htab = luaH_new(L, nvar, 1); /* create `arg' table */
222 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
223 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
224 /* store counter in field `n' */
225 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
226 }
227#endif
228 /* move fixed parameters to final position */
229 fixed = L->top - actual; /* first fixed argument */
230 base = L->top; /* final position of first argument */
231 for (i=0; i<nfixargs; i++) {
232 setobjs2s(L, L->top++, fixed+i);
233 setnilvalue(fixed+i);
234 }
235 /* add `arg' parameter */
236 if (htab) {
237 sethvalue(L, L->top++, htab);
238 lua_assert(iswhite(obj2gco(htab)));
239 }
240 return base;
241}
242
243
244StkId luaD_tryfuncTM (lua_State *L, StkId func) {
245 const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
246 StkId p;
247 ptrdiff_t funcr = savestack(L, func);
248 if (!ttisfunction(tm))
249 luaG_typeerror(L, func, "call");
250 /* Open a hole inside the stack at `func' */
251 for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
252 incr_top(L);
253 func = restorestack(L, funcr); /* previous call may change stack */
254 setobj2s(L, func, tm); /* tag method is the new function to be called */
255 return func;
256}
257
258
259
260#define inc_ci(L) \
261 ((L->ci == L->end_ci) ? luaD_growCI(L) : \
262 (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
263
264
265int luaD_precall (lua_State *L, StkId func, int nresults) {
266 LClosure *cl;
267 ptrdiff_t funcr;
268 if (!ttisfunction(func)) /* `func' is not a function? */
269 func = luaD_tryfuncTM(L, func); /* check the `function' tag method */
270 funcr = savestack(L, func);
271 cl = &clvalue(func)->l;
272 L->ci->savedpc = L->savedpc;
273 if (!cl->isC) { /* Lua function? prepare its call */
274 CallInfo *ci;
275 StkId st, base;
276 Proto *p = cl->p;
277 if (p->jit_status <= JIT_S_NONE) { /* JIT compiler enabled? */
278 if (p->jit_status == JIT_S_OK)
279 return G(L)->jit_gateLJ(L, func, nresults); /* Run compiled code. */
280 else
281 return luaJIT_run(L, func, nresults); /* Compile and run code. */
282 }
283 luaD_checkstack(L, p->maxstacksize);
284 func = restorestack(L, funcr);
285 if (!p->is_vararg) { /* no varargs? */
286 base = func + 1;
287 if (L->top > base + p->numparams)
288 L->top = base + p->numparams;
289 }
290 else { /* vararg function */
291 int nargs = cast_int(L->top - func) - 1;
292 base = adjust_varargs(L, p, nargs);
293 func = restorestack(L, funcr); /* previous call may change the stack */
294 }
295 ci = inc_ci(L); /* now `enter' new function */
296 ci->func = func;
297 L->base = ci->base = base;
298 ci->top = L->base + p->maxstacksize;
299 lua_assert(ci->top <= L->stack_last);
300 L->savedpc = p->code; /* starting point */
301 ci->tailcalls = 0;
302 ci->nresults = nresults;
303 for (st = L->top; st < ci->top; st++)
304 setnilvalue(st);
305 L->top = ci->top;
306 if (L->hookmask & LUA_MASKCALL) {
307 L->savedpc++; /* hooks assume 'pc' is already incremented */
308 luaD_callhook(L, LUA_HOOKCALL, -1);
309 L->savedpc--; /* correct 'pc' */
310 }
311 return PCRLUA;
312 }
313 else { /* if is a C function, call it */
314 CallInfo *ci;
315 int n;
316 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
317 ci = inc_ci(L); /* now `enter' new function */
318 ci->func = restorestack(L, funcr);
319 L->base = ci->base = ci->func + 1;
320 ci->top = L->top + LUA_MINSTACK;
321 lua_assert(ci->top <= L->stack_last);
322 ci->nresults = nresults;
323 if (L->hookmask & LUA_MASKCALL)
324 luaD_callhook(L, LUA_HOOKCALL, -1);
325 lua_unlock(L);
326 n = (*curr_func(L)->c.f)(L); /* do the actual call */
327 lua_lock(L);
328 if (n < 0) /* yielding? */
329 return PCRYIELD;
330 else {
331 luaD_poscall(L, L->top - n);
332 return PCRC;
333 }
334 }
335}
336
337
338static StkId callrethooks (lua_State *L, StkId firstResult) {
339 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
340 luaD_callhook(L, LUA_HOOKRET, -1);
341 if (f_isLua(L->ci)) { /* Lua function? */
342 while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
343 luaD_callhook(L, LUA_HOOKTAILRET, -1);
344 }
345 return restorestack(L, fr);
346}
347
348
349int luaD_poscall (lua_State *L, StkId firstResult) {
350 StkId res;
351 int wanted, i;
352 CallInfo *ci;
353 if (L->hookmask & LUA_MASKRET)
354 firstResult = callrethooks(L, firstResult);
355 ci = L->ci--;
356 res = ci->func; /* res == final position of 1st result */
357 wanted = ci->nresults;
358 L->base = (ci - 1)->base; /* restore base */
359 L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
360 /* move results to correct place */
361 for (i = wanted; i != 0 && firstResult < L->top; i--)
362 setobjs2s(L, res++, firstResult++);
363 while (i-- > 0)
364 setnilvalue(res++);
365 L->top = res;
366 return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
367}
368
369
370/*
371** Call a function (C or Lua). The function to be called is at *func.
372** The arguments are on the stack, right after the function.
373** When returns, all the results are on the stack, starting at the original
374** function position.
375*/
376void luaD_call (lua_State *L, StkId func, int nResults) {
377 if (++L->nCcalls >= LUAI_MAXCCALLS) {
378 if (L->nCcalls == LUAI_MAXCCALLS)
379 luaG_runerror(L, "C stack overflow");
380 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
381 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
382 }
383 if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
384 luaV_execute(L, 1); /* call it */
385 L->nCcalls--;
386 luaC_checkGC(L);
387}
388
389
390static void resume (lua_State *L, void *ud) {
391 StkId firstArg = cast(StkId, ud);
392 CallInfo *ci = L->ci;
393 if (L->status == 0) { /* start coroutine? */
394 lua_assert(ci == L->base_ci && firstArg > L->base);
395 if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
396 return;
397 }
398 else { /* resuming from previous yield */
399 lua_assert(L->status == LUA_YIELD);
400 L->status = 0;
401 if (!f_isLua(ci)) { /* `common' yield? */
402 /* finish interrupted execution of `OP_CALL' */
403 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
404 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
405 if (luaD_poscall(L, firstArg)) /* complete it... */
406 L->top = L->ci->top; /* and correct top if not multiple results */
407 }
408 else /* yielded inside a hook: just continue its execution */
409 L->base = L->ci->base;
410 }
411 luaV_execute(L, cast_int(L->ci - L->base_ci));
412}
413
414
415static int resume_error (lua_State *L, const char *msg) {
416 L->top = L->ci->base;
417 setsvalue2s(L, L->top, luaS_new(L, msg));
418 incr_top(L);
419 lua_unlock(L);
420 return LUA_ERRRUN;
421}
422
423
424LUA_API int lua_resume (lua_State *L, int nargs) {
425 int status;
426 lua_lock(L);
427 if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
428 return resume_error(L, "cannot resume non-suspended coroutine");
429 luai_userstateresume(L, nargs);
430 lua_assert(L->errfunc == 0 && L->nCcalls == 0);
431 status = luaD_rawrunprotected(L, resume, L->top - nargs);
432 if (status != 0) { /* error? */
433 L->status = cast_byte(status); /* mark thread as `dead' */
434 luaD_seterrorobj(L, status, L->top);
435 L->ci->top = L->top;
436 }
437 else
438 status = L->status;
439 lua_unlock(L);
440 return status;
441}
442
443
444LUA_API int lua_yield (lua_State *L, int nresults) {
445 luai_userstateyield(L, nresults);
446 lua_lock(L);
447 if (L->nCcalls > 0)
448 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
449 L->base = L->top - nresults; /* protect stack slots below */
450 L->status = LUA_YIELD;
451 lua_unlock(L);
452 return -1;
453}
454
455
456int luaD_pcall (lua_State *L, Pfunc func, void *u,
457 ptrdiff_t old_top, ptrdiff_t ef) {
458 int status;
459 unsigned short oldnCcalls = L->nCcalls;
460 ptrdiff_t old_ci = saveci(L, L->ci);
461 lu_byte old_allowhooks = L->allowhook;
462 ptrdiff_t old_errfunc = L->errfunc;
463 L->errfunc = ef;
464 status = luaD_rawrunprotected(L, func, u);
465 if (status != 0) { /* an error occurred? */
466 StkId oldtop = restorestack(L, old_top);
467 luaF_close(L, oldtop); /* close eventual pending closures */
468 luaD_seterrorobj(L, status, oldtop);
469 L->nCcalls = oldnCcalls;
470 L->ci = restoreci(L, old_ci);
471 L->base = L->ci->base;
472 L->savedpc = L->ci->savedpc;
473 L->allowhook = old_allowhooks;
474 restore_stack_limit(L);
475 }
476 L->errfunc = old_errfunc;
477 return status;
478}
479
480
481
482/*
483** Execute a protected parser.
484*/
485struct SParser { /* data to `f_parser' */
486 ZIO *z;
487 Mbuffer buff; /* buffer to be used by the scanner */
488 const char *name;
489};
490
491static void f_parser (lua_State *L, void *ud) {
492 int i;
493 Proto *tf;
494 Closure *cl;
495 struct SParser *p = cast(struct SParser *, ud);
496 int c = luaZ_lookahead(p->z);
497 luaC_checkGC(L);
498 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
499 &p->buff, p->name);
500 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
501 cl->l.p = tf;
502 for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
503 cl->l.upvals[i] = luaF_newupval(L);
504 setclvalue(L, L->top, cl);
505 incr_top(L);
506}
507
508
509int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
510 struct SParser p;
511 int status;
512 p.z = z; p.name = name;
513 luaZ_initbuffer(L, &p.buff);
514 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
515 luaZ_freebuffer(L, &p.buff);
516 return status;
517}
518
519
diff --git a/libraries/LuaJIT-1.1.7/src/ldo.h b/libraries/LuaJIT-1.1.7/src/ldo.h
new file mode 100644
index 0000000..63760f9
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ldo.h
@@ -0,0 +1,59 @@
1/*
2** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $
3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ldo_h
8#define ldo_h
9
10
11#include "lobject.h"
12#include "lstate.h"
13#include "lzio.h"
14
15
16#define luaD_checkstack(L,n) \
17 if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
18 luaD_growstack(L, n); \
19 else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
20
21
22#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
23
24#define savestack(L,p) ((char *)(p) - (char *)L->stack)
25#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
26
27#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
28#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
29
30
31/* results from luaD_precall */
32#define PCRLUA 0 /* initiated a call to a Lua function */
33#define PCRC 1 /* did a call to a C function */
34#define PCRYIELD 2 /* C function yielded */
35
36
37/* type of protected functions, to be ran by `runprotected' */
38typedef void (*Pfunc) (lua_State *L, void *ud);
39
40LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
41LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
42LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func);
43LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
44LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
45LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
46 ptrdiff_t oldtop, ptrdiff_t ef);
47LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
48LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
49LUAI_FUNC CallInfo *luaD_growCI (lua_State *L);
50LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
51LUAI_FUNC void luaD_growstack (lua_State *L, int n);
52
53LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
54LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
55
56LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
57
58#endif
59
diff --git a/libraries/LuaJIT-1.1.7/src/ldump.c b/libraries/LuaJIT-1.1.7/src/ldump.c
new file mode 100644
index 0000000..c9d3d48
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ldump.c
@@ -0,0 +1,164 @@
1/*
2** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
3** save precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#include <stddef.h>
8
9#define ldump_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "lobject.h"
15#include "lstate.h"
16#include "lundump.h"
17
18typedef struct {
19 lua_State* L;
20 lua_Writer writer;
21 void* data;
22 int strip;
23 int status;
24} DumpState;
25
26#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
27#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
28
29static void DumpBlock(const void* b, size_t size, DumpState* D)
30{
31 if (D->status==0)
32 {
33 lua_unlock(D->L);
34 D->status=(*D->writer)(D->L,b,size,D->data);
35 lua_lock(D->L);
36 }
37}
38
39static void DumpChar(int y, DumpState* D)
40{
41 char x=(char)y;
42 DumpVar(x,D);
43}
44
45static void DumpInt(int x, DumpState* D)
46{
47 DumpVar(x,D);
48}
49
50static void DumpNumber(lua_Number x, DumpState* D)
51{
52 DumpVar(x,D);
53}
54
55static void DumpVector(const void* b, int n, size_t size, DumpState* D)
56{
57 DumpInt(n,D);
58 DumpMem(b,n,size,D);
59}
60
61static void DumpString(const TString* s, DumpState* D)
62{
63 if (s==NULL || getstr(s)==NULL)
64 {
65 size_t size=0;
66 DumpVar(size,D);
67 }
68 else
69 {
70 size_t size=s->tsv.len+1; /* include trailing '\0' */
71 DumpVar(size,D);
72 DumpBlock(getstr(s),size,D);
73 }
74}
75
76#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
77
78static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
79
80static void DumpConstants(const Proto* f, DumpState* D)
81{
82 int i,n=f->sizek;
83 DumpInt(n,D);
84 for (i=0; i<n; i++)
85 {
86 const TValue* o=&f->k[i];
87 DumpChar(ttype(o),D);
88 switch (ttype(o))
89 {
90 case LUA_TNIL:
91 break;
92 case LUA_TBOOLEAN:
93 DumpChar(bvalue(o),D);
94 break;
95 case LUA_TNUMBER:
96 DumpNumber(nvalue(o),D);
97 break;
98 case LUA_TSTRING:
99 DumpString(rawtsvalue(o),D);
100 break;
101 default:
102 lua_assert(0); /* cannot happen */
103 break;
104 }
105 }
106 n=f->sizep;
107 DumpInt(n,D);
108 for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
109}
110
111static void DumpDebug(const Proto* f, DumpState* D)
112{
113 int i,n;
114 n= (D->strip) ? 0 : f->sizelineinfo;
115 DumpVector(f->lineinfo,n,sizeof(int),D);
116 n= (D->strip) ? 0 : f->sizelocvars;
117 DumpInt(n,D);
118 for (i=0; i<n; i++)
119 {
120 DumpString(f->locvars[i].varname,D);
121 DumpInt(f->locvars[i].startpc,D);
122 DumpInt(f->locvars[i].endpc,D);
123 }
124 n= (D->strip) ? 0 : f->sizeupvalues;
125 DumpInt(n,D);
126 for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
127}
128
129static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
130{
131 DumpString((f->source==p || D->strip) ? NULL : f->source,D);
132 DumpInt(f->linedefined,D);
133 DumpInt(f->lastlinedefined,D);
134 DumpChar(f->nups,D);
135 DumpChar(f->numparams,D);
136 DumpChar(f->is_vararg,D);
137 DumpChar(f->maxstacksize,D);
138 DumpCode(f,D);
139 DumpConstants(f,D);
140 DumpDebug(f,D);
141}
142
143static void DumpHeader(DumpState* D)
144{
145 char h[LUAC_HEADERSIZE];
146 luaU_header(h);
147 DumpBlock(h,LUAC_HEADERSIZE,D);
148}
149
150/*
151** dump Lua function as precompiled chunk
152*/
153int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
154{
155 DumpState D;
156 D.L=L;
157 D.writer=w;
158 D.data=data;
159 D.strip=strip;
160 D.status=0;
161 DumpHeader(&D);
162 DumpFunction(f,NULL,&D);
163 return D.status;
164}
diff --git a/libraries/LuaJIT-1.1.7/src/lfunc.c b/libraries/LuaJIT-1.1.7/src/lfunc.c
new file mode 100644
index 0000000..334e305
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lfunc.c
@@ -0,0 +1,182 @@
1/*
2** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lfunc_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lfunc.h"
16#include "lgc.h"
17#include "lmem.h"
18#include "lobject.h"
19#include "lstate.h"
20#include "ljit.h"
21
22
23
24Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
25 Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
26 luaC_link(L, obj2gco(c), LUA_TFUNCTION);
27 c->c.isC = 1;
28 c->c.env = e;
29 c->c.nupvalues = cast_byte(nelems);
30 c->c.jit_gate = G(L)->jit_gateJC;
31 return c;
32}
33
34
35Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
36 Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
37 luaC_link(L, obj2gco(c), LUA_TFUNCTION);
38 c->l.isC = 0;
39 c->l.env = e;
40 c->l.jit_gate = G(L)->jit_gateJL;
41 c->l.nupvalues = cast_byte(nelems);
42 while (nelems--) c->l.upvals[nelems] = NULL;
43 return c;
44}
45
46
47UpVal *luaF_newupval (lua_State *L) {
48 UpVal *uv = luaM_new(L, UpVal);
49 luaC_link(L, obj2gco(uv), LUA_TUPVAL);
50 uv->v = &uv->u.value;
51 setnilvalue(uv->v);
52 return uv;
53}
54
55
56UpVal *luaF_findupval (lua_State *L, StkId level) {
57 global_State *g = G(L);
58 GCObject **pp = &L->openupval;
59 UpVal *p;
60 UpVal *uv;
61 while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) {
62 lua_assert(p->v != &p->u.value);
63 if (p->v == level) { /* found a corresponding upvalue? */
64 if (isdead(g, obj2gco(p))) /* is it dead? */
65 changewhite(obj2gco(p)); /* ressurect it */
66 return p;
67 }
68 pp = &p->next;
69 }
70 uv = luaM_new(L, UpVal); /* not found: create a new one */
71 uv->tt = LUA_TUPVAL;
72 uv->marked = luaC_white(g);
73 uv->v = level; /* current value lives in the stack */
74 uv->next = *pp; /* chain it in the proper position */
75 *pp = obj2gco(uv);
76 uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
77 uv->u.l.next = g->uvhead.u.l.next;
78 uv->u.l.next->u.l.prev = uv;
79 g->uvhead.u.l.next = uv;
80 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
81 return uv;
82}
83
84
85static void unlinkupval (UpVal *uv) {
86 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
87 uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
88 uv->u.l.prev->u.l.next = uv->u.l.next;
89}
90
91
92void luaF_freeupval (lua_State *L, UpVal *uv) {
93 if (uv->v != &uv->u.value) /* is it open? */
94 unlinkupval(uv); /* remove from open list */
95 luaM_free(L, uv); /* free upvalue */
96}
97
98
99void luaF_close (lua_State *L, StkId level) {
100 UpVal *uv;
101 global_State *g = G(L);
102 while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) {
103 GCObject *o = obj2gco(uv);
104 lua_assert(!isblack(o) && uv->v != &uv->u.value);
105 L->openupval = uv->next; /* remove from `open' list */
106 if (isdead(g, o))
107 luaF_freeupval(L, uv); /* free upvalue */
108 else {
109 unlinkupval(uv);
110 setobj(L, &uv->u.value, uv->v);
111 uv->v = &uv->u.value; /* now current value lives here */
112 luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
113 }
114 }
115}
116
117
118Proto *luaF_newproto (lua_State *L) {
119 Proto *f = luaM_new(L, Proto);
120 luaC_link(L, obj2gco(f), LUA_TPROTO);
121 f->k = NULL;
122 f->sizek = 0;
123 f->p = NULL;
124 f->sizep = 0;
125 f->code = NULL;
126 f->sizecode = 0;
127 f->sizelineinfo = 0;
128 f->sizeupvalues = 0;
129 f->nups = 0;
130 f->upvalues = NULL;
131 f->numparams = 0;
132 f->is_vararg = 0;
133 f->maxstacksize = 0;
134 f->lineinfo = NULL;
135 f->sizelocvars = 0;
136 f->locvars = NULL;
137 f->linedefined = 0;
138 f->lastlinedefined = 0;
139 f->source = NULL;
140 /* LuaJIT extensions */
141 f->jit_mcode = NULL;
142 f->jit_szmcode = 0;
143 f->jit_status = JIT_S_NONE;
144 return f;
145}
146
147
148void luaF_freeproto (lua_State *L, Proto *f) {
149 luaJIT_freeproto(L, f);
150 luaM_freearray(L, f->code, f->sizecode, Instruction);
151 luaM_freearray(L, f->p, f->sizep, Proto *);
152 luaM_freearray(L, f->k, f->sizek, TValue);
153 luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
154 luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
155 luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
156 luaM_free(L, f);
157}
158
159
160void luaF_freeclosure (lua_State *L, Closure *c) {
161 int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
162 sizeLclosure(c->l.nupvalues);
163 luaM_freemem(L, c, size);
164}
165
166
167/*
168** Look for n-th local variable at line `line' in function `func'.
169** Returns NULL if not found.
170*/
171const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
172 int i;
173 for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
174 if (pc < f->locvars[i].endpc) { /* is variable active? */
175 local_number--;
176 if (local_number == 0)
177 return getstr(f->locvars[i].varname);
178 }
179 }
180 return NULL; /* not found */
181}
182
diff --git a/libraries/LuaJIT-1.1.7/src/lfunc.h b/libraries/LuaJIT-1.1.7/src/lfunc.h
new file mode 100644
index 0000000..a68cf51
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lfunc.h
@@ -0,0 +1,34 @@
1/*
2** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lfunc_h
8#define lfunc_h
9
10
11#include "lobject.h"
12
13
14#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
15 cast(int, sizeof(TValue)*((n)-1)))
16
17#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
18 cast(int, sizeof(TValue *)*((n)-1)))
19
20
21LUAI_FUNC Proto *luaF_newproto (lua_State *L);
22LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
23LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
24LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
25LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
26LUAI_FUNC void luaF_close (lua_State *L, StkId level);
27LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
28LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
29LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
30LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
31 int pc);
32
33
34#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lgc.c b/libraries/LuaJIT-1.1.7/src/lgc.c
new file mode 100644
index 0000000..d9e0b78
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lgc.c
@@ -0,0 +1,711 @@
1/*
2** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $
3** Garbage Collector
4** See Copyright Notice in lua.h
5*/
6
7#include <string.h>
8
9#define lgc_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "ldebug.h"
15#include "ldo.h"
16#include "lfunc.h"
17#include "lgc.h"
18#include "lmem.h"
19#include "lobject.h"
20#include "lstate.h"
21#include "lstring.h"
22#include "ltable.h"
23#include "ltm.h"
24
25
26#define GCSTEPSIZE 1024u
27#define GCSWEEPMAX 40
28#define GCSWEEPCOST 10
29#define GCFINALIZECOST 100
30
31
32#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
33
34#define makewhite(g,x) \
35 ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g)))
36
37#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
38#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
39
40#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
41
42
43#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
44#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
45
46
47#define KEYWEAK bitmask(KEYWEAKBIT)
48#define VALUEWEAK bitmask(VALUEWEAKBIT)
49
50
51
52#define markvalue(g,o) { checkconsistency(o); \
53 if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
54
55#define markobject(g,t) { if (iswhite(obj2gco(t))) \
56 reallymarkobject(g, obj2gco(t)); }
57
58
59#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
60
61
62static void removeentry (Node *n) {
63 lua_assert(ttisnil(gval(n)));
64 if (iscollectable(gkey(n)))
65 setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
66}
67
68
69static void reallymarkobject (global_State *g, GCObject *o) {
70 lua_assert(iswhite(o) && !isdead(g, o));
71 white2gray(o);
72 switch (o->gch.tt) {
73 case LUA_TSTRING: {
74 return;
75 }
76 case LUA_TUSERDATA: {
77 Table *mt = gco2u(o)->metatable;
78 gray2black(o); /* udata are never gray */
79 if (mt) markobject(g, mt);
80 markobject(g, gco2u(o)->env);
81 return;
82 }
83 case LUA_TUPVAL: {
84 UpVal *uv = gco2uv(o);
85 markvalue(g, uv->v);
86 if (uv->v == &uv->u.value) /* closed? */
87 gray2black(o); /* open upvalues are never black */
88 return;
89 }
90 case LUA_TFUNCTION: {
91 gco2cl(o)->c.gclist = g->gray;
92 g->gray = o;
93 break;
94 }
95 case LUA_TTABLE: {
96 gco2h(o)->gclist = g->gray;
97 g->gray = o;
98 break;
99 }
100 case LUA_TTHREAD: {
101 gco2th(o)->gclist = g->gray;
102 g->gray = o;
103 break;
104 }
105 case LUA_TPROTO: {
106 gco2p(o)->gclist = g->gray;
107 g->gray = o;
108 break;
109 }
110 default: lua_assert(0);
111 }
112}
113
114
115static void marktmu (global_State *g) {
116 GCObject *u = g->tmudata;
117 if (u) {
118 do {
119 u = u->gch.next;
120 makewhite(g, u); /* may be marked, if left from previous GC */
121 reallymarkobject(g, u);
122 } while (u != g->tmudata);
123 }
124}
125
126
127/* move `dead' udata that need finalization to list `tmudata' */
128size_t luaC_separateudata (lua_State *L, int all) {
129 global_State *g = G(L);
130 size_t deadmem = 0;
131 GCObject **p = &g->mainthread->next;
132 GCObject *curr;
133 while ((curr = *p) != NULL) {
134 if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
135 p = &curr->gch.next; /* don't bother with them */
136 else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
137 markfinalized(gco2u(curr)); /* don't need finalization */
138 p = &curr->gch.next;
139 }
140 else { /* must call its gc method */
141 deadmem += sizeudata(gco2u(curr));
142 markfinalized(gco2u(curr));
143 *p = curr->gch.next;
144 /* link `curr' at the end of `tmudata' list */
145 if (g->tmudata == NULL) /* list is empty? */
146 g->tmudata = curr->gch.next = curr; /* creates a circular list */
147 else {
148 curr->gch.next = g->tmudata->gch.next;
149 g->tmudata->gch.next = curr;
150 g->tmudata = curr;
151 }
152 }
153 }
154 return deadmem;
155}
156
157
158static int traversetable (global_State *g, Table *h) {
159 int i;
160 int weakkey = 0;
161 int weakvalue = 0;
162 const TValue *mode;
163 if (h->metatable)
164 markobject(g, h->metatable);
165 mode = gfasttm(g, h->metatable, TM_MODE);
166 if (mode && ttisstring(mode)) { /* is there a weak mode? */
167 weakkey = (strchr(svalue(mode), 'k') != NULL);
168 weakvalue = (strchr(svalue(mode), 'v') != NULL);
169 if (weakkey || weakvalue) { /* is really weak? */
170 h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
171 h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
172 (weakvalue << VALUEWEAKBIT));
173 h->gclist = g->weak; /* must be cleared after GC, ... */
174 g->weak = obj2gco(h); /* ... so put in the appropriate list */
175 }
176 }
177 if (weakkey && weakvalue) return 1;
178 if (!weakvalue) {
179 i = h->sizearray;
180 while (i--)
181 markvalue(g, &h->array[i]);
182 }
183 i = sizenode(h);
184 while (i--) {
185 Node *n = gnode(h, i);
186 lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
187 if (ttisnil(gval(n)))
188 removeentry(n); /* remove empty entries */
189 else {
190 lua_assert(!ttisnil(gkey(n)));
191 if (!weakkey) markvalue(g, gkey(n));
192 if (!weakvalue) markvalue(g, gval(n));
193 }
194 }
195 return weakkey || weakvalue;
196}
197
198
199/*
200** All marks are conditional because a GC may happen while the
201** prototype is still being created
202*/
203static void traverseproto (global_State *g, Proto *f) {
204 int i;
205 if (f->source) stringmark(f->source);
206 for (i=0; i<f->sizek; i++) /* mark literals */
207 markvalue(g, &f->k[i]);
208 for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
209 if (f->upvalues[i])
210 stringmark(f->upvalues[i]);
211 }
212 for (i=0; i<f->sizep; i++) { /* mark nested protos */
213 if (f->p[i])
214 markobject(g, f->p[i]);
215 }
216 for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
217 if (f->locvars[i].varname)
218 stringmark(f->locvars[i].varname);
219 }
220}
221
222
223
224static void traverseclosure (global_State *g, Closure *cl) {
225 markobject(g, cl->c.env);
226 if (cl->c.isC) {
227 int i;
228 for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
229 markvalue(g, &cl->c.upvalue[i]);
230 }
231 else {
232 int i;
233 lua_assert(cl->l.nupvalues == cl->l.p->nups);
234 markobject(g, cl->l.p);
235 for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
236 markobject(g, cl->l.upvals[i]);
237 }
238}
239
240
241static void checkstacksizes (lua_State *L, StkId max) {
242 int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */
243 int s_used = cast_int(max - L->stack); /* part of stack in use */
244 if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */
245 return; /* do not touch the stacks */
246 if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
247 luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
248 condhardstacktests(luaD_reallocCI(L, ci_used + 1));
249 if (4*s_used < L->stacksize &&
250 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
251 luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
252 condhardstacktests(luaD_reallocstack(L, s_used));
253}
254
255
256static void traversestack (global_State *g, lua_State *l) {
257 StkId o, lim;
258 CallInfo *ci;
259 markvalue(g, gt(l));
260 lim = l->top;
261 for (ci = l->base_ci; ci <= l->ci; ci++) {
262 lua_assert(ci->top <= l->stack_last);
263 if (lim < ci->top) lim = ci->top;
264 }
265 for (o = l->stack; o < l->top; o++)
266 markvalue(g, o);
267 for (; o <= lim; o++)
268 setnilvalue(o);
269 checkstacksizes(l, lim);
270}
271
272
273/*
274** traverse one gray object, turning it to black.
275** Returns `quantity' traversed.
276*/
277static l_mem propagatemark (global_State *g) {
278 GCObject *o = g->gray;
279 lua_assert(isgray(o));
280 gray2black(o);
281 switch (o->gch.tt) {
282 case LUA_TTABLE: {
283 Table *h = gco2h(o);
284 g->gray = h->gclist;
285 if (traversetable(g, h)) /* table is weak? */
286 black2gray(o); /* keep it gray */
287 return sizeof(Table) + sizeof(TValue) * h->sizearray +
288 sizeof(Node) * sizenode(h);
289 }
290 case LUA_TFUNCTION: {
291 Closure *cl = gco2cl(o);
292 g->gray = cl->c.gclist;
293 traverseclosure(g, cl);
294 return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
295 sizeLclosure(cl->l.nupvalues);
296 }
297 case LUA_TTHREAD: {
298 lua_State *th = gco2th(o);
299 g->gray = th->gclist;
300 th->gclist = g->grayagain;
301 g->grayagain = o;
302 black2gray(o);
303 traversestack(g, th);
304 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
305 sizeof(CallInfo) * th->size_ci;
306 }
307 case LUA_TPROTO: {
308 Proto *p = gco2p(o);
309 g->gray = p->gclist;
310 traverseproto(g, p);
311 return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
312 sizeof(Proto *) * p->sizep +
313 sizeof(TValue) * p->sizek +
314 sizeof(int) * p->sizelineinfo +
315 sizeof(LocVar) * p->sizelocvars +
316 sizeof(TString *) * p->sizeupvalues;
317 }
318 default: lua_assert(0); return 0;
319 }
320}
321
322
323static size_t propagateall (global_State *g) {
324 size_t m = 0;
325 while (g->gray) m += propagatemark(g);
326 return m;
327}
328
329
330/*
331** The next function tells whether a key or value can be cleared from
332** a weak table. Non-collectable objects are never removed from weak
333** tables. Strings behave as `values', so are never removed too. for
334** other objects: if really collected, cannot keep them; for userdata
335** being finalized, keep them in keys, but not in values
336*/
337static int iscleared (const TValue *o, int iskey) {
338 if (!iscollectable(o)) return 0;
339 if (ttisstring(o)) {
340 stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
341 return 0;
342 }
343 return iswhite(gcvalue(o)) ||
344 (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
345}
346
347
348/*
349** clear collected entries from weaktables
350*/
351static void cleartable (GCObject *l) {
352 while (l) {
353 Table *h = gco2h(l);
354 int i = h->sizearray;
355 lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
356 testbit(h->marked, KEYWEAKBIT));
357 if (testbit(h->marked, VALUEWEAKBIT)) {
358 while (i--) {
359 TValue *o = &h->array[i];
360 if (iscleared(o, 0)) /* value was collected? */
361 setnilvalue(o); /* remove value */
362 }
363 }
364 i = sizenode(h);
365 while (i--) {
366 Node *n = gnode(h, i);
367 if (!ttisnil(gval(n)) && /* non-empty entry? */
368 (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
369 setnilvalue(gval(n)); /* remove value ... */
370 removeentry(n); /* remove entry from table */
371 }
372 }
373 l = h->gclist;
374 }
375}
376
377
378static void freeobj (lua_State *L, GCObject *o) {
379 switch (o->gch.tt) {
380 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
381 case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
382 case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
383 case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
384 case LUA_TTHREAD: {
385 lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
386 luaE_freethread(L, gco2th(o));
387 break;
388 }
389 case LUA_TSTRING: {
390 G(L)->strt.nuse--;
391 luaM_freemem(L, o, sizestring(gco2ts(o)));
392 break;
393 }
394 case LUA_TUSERDATA: {
395 luaM_freemem(L, o, sizeudata(gco2u(o)));
396 break;
397 }
398 default: lua_assert(0);
399 }
400}
401
402
403
404#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
405
406
407static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
408 GCObject *curr;
409 global_State *g = G(L);
410 int deadmask = otherwhite(g);
411 while ((curr = *p) != NULL && count-- > 0) {
412 if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
413 sweepwholelist(L, &gco2th(curr)->openupval);
414 if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
415 lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
416 makewhite(g, curr); /* make it white (for next cycle) */
417 p = &curr->gch.next;
418 }
419 else { /* must erase `curr' */
420 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
421 *p = curr->gch.next;
422 if (curr == g->rootgc) /* is the first element of the list? */
423 g->rootgc = curr->gch.next; /* adjust first */
424 freeobj(L, curr);
425 }
426 }
427 return p;
428}
429
430
431static void checkSizes (lua_State *L) {
432 global_State *g = G(L);
433 /* check size of string hash */
434 if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
435 g->strt.size > MINSTRTABSIZE*2)
436 luaS_resize(L, g->strt.size/2); /* table is too big */
437 /* check size of buffer */
438 if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
439 size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
440 luaZ_resizebuffer(L, &g->buff, newsize);
441 }
442}
443
444
445static void GCTM (lua_State *L) {
446 global_State *g = G(L);
447 GCObject *o = g->tmudata->gch.next; /* get first element */
448 Udata *udata = rawgco2u(o);
449 const TValue *tm;
450 /* remove udata from `tmudata' */
451 if (o == g->tmudata) /* last element? */
452 g->tmudata = NULL;
453 else
454 g->tmudata->gch.next = udata->uv.next;
455 udata->uv.next = g->mainthread->next; /* return it to `root' list */
456 g->mainthread->next = o;
457 makewhite(g, o);
458 tm = fasttm(L, udata->uv.metatable, TM_GC);
459 if (tm != NULL) {
460 lu_byte oldah = L->allowhook;
461 lu_mem oldt = g->GCthreshold;
462 L->allowhook = 0; /* stop debug hooks during GC tag method */
463 g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
464 setobj2s(L, L->top, tm);
465 setuvalue(L, L->top+1, udata);
466 L->top += 2;
467 luaD_call(L, L->top - 2, 0);
468 L->allowhook = oldah; /* restore hooks */
469 g->GCthreshold = oldt; /* restore threshold */
470 }
471}
472
473
474/*
475** Call all GC tag methods
476*/
477void luaC_callGCTM (lua_State *L) {
478 while (G(L)->tmudata)
479 GCTM(L);
480}
481
482
483void luaC_freeall (lua_State *L) {
484 global_State *g = G(L);
485 int i;
486 g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
487 sweepwholelist(L, &g->rootgc);
488 for (i = 0; i < g->strt.size; i++) /* free all string lists */
489 sweepwholelist(L, &g->strt.hash[i]);
490}
491
492
493static void markmt (global_State *g) {
494 int i;
495 for (i=0; i<NUM_TAGS; i++)
496 if (g->mt[i]) markobject(g, g->mt[i]);
497}
498
499
500/* mark root set */
501static void markroot (lua_State *L) {
502 global_State *g = G(L);
503 g->gray = NULL;
504 g->grayagain = NULL;
505 g->weak = NULL;
506 markobject(g, g->mainthread);
507 /* make global table be traversed before main stack */
508 markvalue(g, gt(g->mainthread));
509 markvalue(g, registry(L));
510 markmt(g);
511 g->gcstate = GCSpropagate;
512}
513
514
515static void remarkupvals (global_State *g) {
516 UpVal *uv;
517 for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
518 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
519 if (isgray(obj2gco(uv)))
520 markvalue(g, uv->v);
521 }
522}
523
524
525static void atomic (lua_State *L) {
526 global_State *g = G(L);
527 size_t udsize; /* total size of userdata to be finalized */
528 /* remark occasional upvalues of (maybe) dead threads */
529 remarkupvals(g);
530 /* traverse objects cautch by write barrier and by 'remarkupvals' */
531 propagateall(g);
532 /* remark weak tables */
533 g->gray = g->weak;
534 g->weak = NULL;
535 lua_assert(!iswhite(obj2gco(g->mainthread)));
536 markobject(g, L); /* mark running thread */
537 markmt(g); /* mark basic metatables (again) */
538 propagateall(g);
539 /* remark gray again */
540 g->gray = g->grayagain;
541 g->grayagain = NULL;
542 propagateall(g);
543 udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
544 marktmu(g); /* mark `preserved' userdata */
545 udsize += propagateall(g); /* remark, to propagate `preserveness' */
546 cleartable(g->weak); /* remove collected objects from weak tables */
547 /* flip current white */
548 g->currentwhite = cast_byte(otherwhite(g));
549 g->sweepstrgc = 0;
550 g->sweepgc = &g->rootgc;
551 g->gcstate = GCSsweepstring;
552 g->estimate = g->totalbytes - udsize; /* first estimate */
553}
554
555
556static l_mem singlestep (lua_State *L) {
557 global_State *g = G(L);
558 /*lua_checkmemory(L);*/
559 switch (g->gcstate) {
560 case GCSpause: {
561 markroot(L); /* start a new collection */
562 return 0;
563 }
564 case GCSpropagate: {
565 if (g->gray)
566 return propagatemark(g);
567 else { /* no more `gray' objects */
568 atomic(L); /* finish mark phase */
569 return 0;
570 }
571 }
572 case GCSsweepstring: {
573 lu_mem old = g->totalbytes;
574 sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
575 if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
576 g->gcstate = GCSsweep; /* end sweep-string phase */
577 lua_assert(old >= g->totalbytes);
578 g->estimate -= old - g->totalbytes;
579 return GCSWEEPCOST;
580 }
581 case GCSsweep: {
582 lu_mem old = g->totalbytes;
583 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
584 if (*g->sweepgc == NULL) { /* nothing more to sweep? */
585 checkSizes(L);
586 g->gcstate = GCSfinalize; /* end sweep phase */
587 }
588 lua_assert(old >= g->totalbytes);
589 g->estimate -= old - g->totalbytes;
590 return GCSWEEPMAX*GCSWEEPCOST;
591 }
592 case GCSfinalize: {
593 if (g->tmudata) {
594 GCTM(L);
595 if (g->estimate > GCFINALIZECOST)
596 g->estimate -= GCFINALIZECOST;
597 return GCFINALIZECOST;
598 }
599 else {
600 g->gcstate = GCSpause; /* end collection */
601 g->gcdept = 0;
602 return 0;
603 }
604 }
605 default: lua_assert(0); return 0;
606 }
607}
608
609
610void luaC_step (lua_State *L) {
611 global_State *g = G(L);
612 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
613 if (lim == 0)
614 lim = (MAX_LUMEM-1)/2; /* no limit */
615 g->gcdept += g->totalbytes - g->GCthreshold;
616 do {
617 lim -= singlestep(L);
618 if (g->gcstate == GCSpause)
619 break;
620 } while (lim > 0);
621 if (g->gcstate != GCSpause) {
622 if (g->gcdept < GCSTEPSIZE)
623 g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
624 else {
625 g->gcdept -= GCSTEPSIZE;
626 g->GCthreshold = g->totalbytes;
627 }
628 }
629 else {
630 lua_assert(g->totalbytes >= g->estimate);
631 setthreshold(g);
632 }
633}
634
635
636void luaC_fullgc (lua_State *L) {
637 global_State *g = G(L);
638 if (g->gcstate <= GCSpropagate) {
639 /* reset sweep marks to sweep all elements (returning them to white) */
640 g->sweepstrgc = 0;
641 g->sweepgc = &g->rootgc;
642 /* reset other collector lists */
643 g->gray = NULL;
644 g->grayagain = NULL;
645 g->weak = NULL;
646 g->gcstate = GCSsweepstring;
647 }
648 lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
649 /* finish any pending sweep phase */
650 while (g->gcstate != GCSfinalize) {
651 lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
652 singlestep(L);
653 }
654 markroot(L);
655 while (g->gcstate != GCSpause) {
656 singlestep(L);
657 }
658 setthreshold(g);
659}
660
661
662void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
663 global_State *g = G(L);
664 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
665 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
666 lua_assert(ttype(&o->gch) != LUA_TTABLE);
667 /* must keep invariant? */
668 if (g->gcstate == GCSpropagate)
669 reallymarkobject(g, v); /* restore invariant */
670 else /* don't mind */
671 makewhite(g, o); /* mark as white just to avoid other barriers */
672}
673
674
675void luaC_barrierback (lua_State *L, Table *t) {
676 global_State *g = G(L);
677 GCObject *o = obj2gco(t);
678 lua_assert(isblack(o) && !isdead(g, o));
679 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
680 black2gray(o); /* make table gray (again) */
681 t->gclist = g->grayagain;
682 g->grayagain = o;
683}
684
685
686void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
687 global_State *g = G(L);
688 o->gch.next = g->rootgc;
689 g->rootgc = o;
690 o->gch.marked = luaC_white(g);
691 o->gch.tt = tt;
692}
693
694
695void luaC_linkupval (lua_State *L, UpVal *uv) {
696 global_State *g = G(L);
697 GCObject *o = obj2gco(uv);
698 o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
699 g->rootgc = o;
700 if (isgray(o)) {
701 if (g->gcstate == GCSpropagate) {
702 gray2black(o); /* closed upvalues need barrier */
703 luaC_barrier(L, uv, uv->v);
704 }
705 else { /* sweep phase: sweep it (turning it into white) */
706 makewhite(g, o);
707 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
708 }
709 }
710}
711
diff --git a/libraries/LuaJIT-1.1.7/src/lgc.h b/libraries/LuaJIT-1.1.7/src/lgc.h
new file mode 100644
index 0000000..5a8dc60
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lgc.h
@@ -0,0 +1,110 @@
1/*
2** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $
3** Garbage Collector
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lgc_h
8#define lgc_h
9
10
11#include "lobject.h"
12
13
14/*
15** Possible states of the Garbage Collector
16*/
17#define GCSpause 0
18#define GCSpropagate 1
19#define GCSsweepstring 2
20#define GCSsweep 3
21#define GCSfinalize 4
22
23
24/*
25** some userful bit tricks
26*/
27#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
28#define setbits(x,m) ((x) |= (m))
29#define testbits(x,m) ((x) & (m))
30#define bitmask(b) (1<<(b))
31#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
32#define l_setbit(x,b) setbits(x, bitmask(b))
33#define resetbit(x,b) resetbits(x, bitmask(b))
34#define testbit(x,b) testbits(x, bitmask(b))
35#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
36#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
37#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))
38
39
40
41/*
42** Layout for bit use in `marked' field:
43** bit 0 - object is white (type 0)
44** bit 1 - object is white (type 1)
45** bit 2 - object is black
46** bit 3 - for userdata: has been finalized
47** bit 3 - for tables: has weak keys
48** bit 4 - for tables: has weak values
49** bit 5 - object is fixed (should not be collected)
50** bit 6 - object is "super" fixed (only the main thread)
51*/
52
53
54#define WHITE0BIT 0
55#define WHITE1BIT 1
56#define BLACKBIT 2
57#define FINALIZEDBIT 3
58#define KEYWEAKBIT 3
59#define VALUEWEAKBIT 4
60#define FIXEDBIT 5
61#define SFIXEDBIT 6
62#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
63
64
65#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
66#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
67#define isgray(x) (!isblack(x) && !iswhite(x))
68
69#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
70#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
71
72#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
73#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
74
75#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
76
77#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
78
79
80#define luaC_checkGC(L) { \
81 condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
82 if (G(L)->totalbytes >= G(L)->GCthreshold) \
83 luaC_step(L); }
84
85
86#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
87 luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
88
89#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
90 luaC_barrierback(L,t); }
91
92#define luaC_objbarrier(L,p,o) \
93 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
94 luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
95
96#define luaC_objbarriert(L,t,o) \
97 { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }
98
99LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
100LUAI_FUNC void luaC_callGCTM (lua_State *L);
101LUAI_FUNC void luaC_freeall (lua_State *L);
102LUAI_FUNC void luaC_step (lua_State *L);
103LUAI_FUNC void luaC_fullgc (lua_State *L);
104LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
105LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
106LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
107LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
108
109
110#endif
diff --git a/libraries/LuaJIT-1.1.7/src/linit.c b/libraries/LuaJIT-1.1.7/src/linit.c
new file mode 100644
index 0000000..db24ccd
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/linit.c
@@ -0,0 +1,39 @@
1/*
2** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
3** Initialization of libraries for lua.c
4** See Copyright Notice in lua.h
5*/
6
7
8#define linit_c
9#define LUA_LIB
10
11#include "lua.h"
12
13#include "lualib.h"
14#include "lauxlib.h"
15
16
17static const luaL_Reg lualibs[] = {
18 {"", luaopen_base},
19 {LUA_LOADLIBNAME, luaopen_package},
20 {LUA_TABLIBNAME, luaopen_table},
21 {LUA_IOLIBNAME, luaopen_io},
22 {LUA_OSLIBNAME, luaopen_os},
23 {LUA_STRLIBNAME, luaopen_string},
24 {LUA_MATHLIBNAME, luaopen_math},
25 {LUA_DBLIBNAME, luaopen_debug},
26 {LUA_JITLIBNAME, luaopen_jit},
27 {NULL, NULL}
28};
29
30
31LUALIB_API void luaL_openlibs (lua_State *L) {
32 const luaL_Reg *lib = lualibs;
33 for (; lib->func; lib++) {
34 lua_pushcfunction(L, lib->func);
35 lua_pushstring(L, lib->name);
36 lua_call(L, 1, 0);
37 }
38}
39
diff --git a/libraries/LuaJIT-1.1.7/src/liolib.c b/libraries/LuaJIT-1.1.7/src/liolib.c
new file mode 100644
index 0000000..8de2547
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/liolib.c
@@ -0,0 +1,556 @@
1/*
2** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $
3** Standard I/O (and system) library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <errno.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define liolib_c
14#define LUA_LIB
15
16#include "lua.h"
17
18#include "lauxlib.h"
19#include "lualib.h"
20
21
22
23#define IO_INPUT 1
24#define IO_OUTPUT 2
25
26
27static const char *const fnames[] = {"input", "output"};
28
29
30static int pushresult (lua_State *L, int i, const char *filename) {
31 int en = errno; /* calls to Lua API may change this value */
32 if (i) {
33 lua_pushboolean(L, 1);
34 return 1;
35 }
36 else {
37 lua_pushnil(L);
38 if (filename)
39 lua_pushfstring(L, "%s: %s", filename, strerror(en));
40 else
41 lua_pushfstring(L, "%s", strerror(en));
42 lua_pushinteger(L, en);
43 return 3;
44 }
45}
46
47
48static void fileerror (lua_State *L, int arg, const char *filename) {
49 lua_pushfstring(L, "%s: %s", filename, strerror(errno));
50 luaL_argerror(L, arg, lua_tostring(L, -1));
51}
52
53
54#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
55
56
57static int io_type (lua_State *L) {
58 void *ud;
59 luaL_checkany(L, 1);
60 ud = lua_touserdata(L, 1);
61 lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
62 if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
63 lua_pushnil(L); /* not a file */
64 else if (*((FILE **)ud) == NULL)
65 lua_pushliteral(L, "closed file");
66 else
67 lua_pushliteral(L, "file");
68 return 1;
69}
70
71
72static FILE *tofile (lua_State *L) {
73 FILE **f = tofilep(L);
74 if (*f == NULL)
75 luaL_error(L, "attempt to use a closed file");
76 return *f;
77}
78
79
80
81/*
82** When creating file handles, always creates a `closed' file handle
83** before opening the actual file; so, if there is a memory error, the
84** file is not left opened.
85*/
86static FILE **newfile (lua_State *L) {
87 FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
88 *pf = NULL; /* file handle is currently `closed' */
89 luaL_getmetatable(L, LUA_FILEHANDLE);
90 lua_setmetatable(L, -2);
91 return pf;
92}
93
94
95/*
96** function to (not) close the standard files stdin, stdout, and stderr
97*/
98static int io_noclose (lua_State *L) {
99 lua_pushnil(L);
100 lua_pushliteral(L, "cannot close standard file");
101 return 2;
102}
103
104
105/*
106** function to close 'popen' files
107*/
108static int io_pclose (lua_State *L) {
109 FILE **p = tofilep(L);
110 int ok = lua_pclose(L, *p);
111 *p = NULL;
112 return pushresult(L, ok, NULL);
113}
114
115
116/*
117** function to close regular files
118*/
119static int io_fclose (lua_State *L) {
120 FILE **p = tofilep(L);
121 int ok = (fclose(*p) == 0);
122 *p = NULL;
123 return pushresult(L, ok, NULL);
124}
125
126
127static int aux_close (lua_State *L) {
128 lua_getfenv(L, 1);
129 lua_getfield(L, -1, "__close");
130 return (lua_tocfunction(L, -1))(L);
131}
132
133
134static int io_close (lua_State *L) {
135 if (lua_isnone(L, 1))
136 lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
137 tofile(L); /* make sure argument is a file */
138 return aux_close(L);
139}
140
141
142static int io_gc (lua_State *L) {
143 FILE *f = *tofilep(L);
144 /* ignore closed files */
145 if (f != NULL)
146 aux_close(L);
147 return 0;
148}
149
150
151static int io_tostring (lua_State *L) {
152 FILE *f = *tofilep(L);
153 if (f == NULL)
154 lua_pushliteral(L, "file (closed)");
155 else
156 lua_pushfstring(L, "file (%p)", f);
157 return 1;
158}
159
160
161static int io_open (lua_State *L) {
162 const char *filename = luaL_checkstring(L, 1);
163 const char *mode = luaL_optstring(L, 2, "r");
164 FILE **pf = newfile(L);
165 *pf = fopen(filename, mode);
166 return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
167}
168
169
170/*
171** this function has a separated environment, which defines the
172** correct __close for 'popen' files
173*/
174static int io_popen (lua_State *L) {
175 const char *filename = luaL_checkstring(L, 1);
176 const char *mode = luaL_optstring(L, 2, "r");
177 FILE **pf = newfile(L);
178 *pf = lua_popen(L, filename, mode);
179 return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
180}
181
182
183static int io_tmpfile (lua_State *L) {
184 FILE **pf = newfile(L);
185 *pf = tmpfile();
186 return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
187}
188
189
190static FILE *getiofile (lua_State *L, int findex) {
191 FILE *f;
192 lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
193 f = *(FILE **)lua_touserdata(L, -1);
194 if (f == NULL)
195 luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
196 return f;
197}
198
199
200static int g_iofile (lua_State *L, int f, const char *mode) {
201 if (!lua_isnoneornil(L, 1)) {
202 const char *filename = lua_tostring(L, 1);
203 if (filename) {
204 FILE **pf = newfile(L);
205 *pf = fopen(filename, mode);
206 if (*pf == NULL)
207 fileerror(L, 1, filename);
208 }
209 else {
210 tofile(L); /* check that it's a valid file handle */
211 lua_pushvalue(L, 1);
212 }
213 lua_rawseti(L, LUA_ENVIRONINDEX, f);
214 }
215 /* return current value */
216 lua_rawgeti(L, LUA_ENVIRONINDEX, f);
217 return 1;
218}
219
220
221static int io_input (lua_State *L) {
222 return g_iofile(L, IO_INPUT, "r");
223}
224
225
226static int io_output (lua_State *L) {
227 return g_iofile(L, IO_OUTPUT, "w");
228}
229
230
231static int io_readline (lua_State *L);
232
233
234static void aux_lines (lua_State *L, int idx, int toclose) {
235 lua_pushvalue(L, idx);
236 lua_pushboolean(L, toclose); /* close/not close file when finished */
237 lua_pushcclosure(L, io_readline, 2);
238}
239
240
241static int f_lines (lua_State *L) {
242 tofile(L); /* check that it's a valid file handle */
243 aux_lines(L, 1, 0);
244 return 1;
245}
246
247
248static int io_lines (lua_State *L) {
249 if (lua_isnoneornil(L, 1)) { /* no arguments? */
250 /* will iterate over default input */
251 lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
252 return f_lines(L);
253 }
254 else {
255 const char *filename = luaL_checkstring(L, 1);
256 FILE **pf = newfile(L);
257 *pf = fopen(filename, "r");
258 if (*pf == NULL)
259 fileerror(L, 1, filename);
260 aux_lines(L, lua_gettop(L), 1);
261 return 1;
262 }
263}
264
265
266/*
267** {======================================================
268** READ
269** =======================================================
270*/
271
272
273static int read_number (lua_State *L, FILE *f) {
274 lua_Number d;
275 if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
276 lua_pushnumber(L, d);
277 return 1;
278 }
279 else {
280 lua_pushnil(L); /* "result" to be removed */
281 return 0; /* read fails */
282 }
283}
284
285
286static int test_eof (lua_State *L, FILE *f) {
287 int c = getc(f);
288 ungetc(c, f);
289 lua_pushlstring(L, NULL, 0);
290 return (c != EOF);
291}
292
293
294static int read_line (lua_State *L, FILE *f) {
295 luaL_Buffer b;
296 luaL_buffinit(L, &b);
297 for (;;) {
298 size_t l;
299 char *p = luaL_prepbuffer(&b);
300 if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
301 luaL_pushresult(&b); /* close buffer */
302 return (lua_objlen(L, -1) > 0); /* check whether read something */
303 }
304 l = strlen(p);
305 if (l == 0 || p[l-1] != '\n')
306 luaL_addsize(&b, l);
307 else {
308 luaL_addsize(&b, l - 1); /* do not include `eol' */
309 luaL_pushresult(&b); /* close buffer */
310 return 1; /* read at least an `eol' */
311 }
312 }
313}
314
315
316static int read_chars (lua_State *L, FILE *f, size_t n) {
317 size_t rlen; /* how much to read */
318 size_t nr; /* number of chars actually read */
319 luaL_Buffer b;
320 luaL_buffinit(L, &b);
321 rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
322 do {
323 char *p = luaL_prepbuffer(&b);
324 if (rlen > n) rlen = n; /* cannot read more than asked */
325 nr = fread(p, sizeof(char), rlen, f);
326 luaL_addsize(&b, nr);
327 n -= nr; /* still have to read `n' chars */
328 } while (n > 0 && nr == rlen); /* until end of count or eof */
329 luaL_pushresult(&b); /* close buffer */
330 return (n == 0 || lua_objlen(L, -1) > 0);
331}
332
333
334static int g_read (lua_State *L, FILE *f, int first) {
335 int nargs = lua_gettop(L) - 1;
336 int success;
337 int n;
338 clearerr(f);
339 if (nargs == 0) { /* no arguments? */
340 success = read_line(L, f);
341 n = first+1; /* to return 1 result */
342 }
343 else { /* ensure stack space for all results and for auxlib's buffer */
344 luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
345 success = 1;
346 for (n = first; nargs-- && success; n++) {
347 if (lua_type(L, n) == LUA_TNUMBER) {
348 size_t l = (size_t)lua_tointeger(L, n);
349 success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
350 }
351 else {
352 const char *p = lua_tostring(L, n);
353 luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
354 switch (p[1]) {
355 case 'n': /* number */
356 success = read_number(L, f);
357 break;
358 case 'l': /* line */
359 success = read_line(L, f);
360 break;
361 case 'a': /* file */
362 read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
363 success = 1; /* always success */
364 break;
365 default:
366 return luaL_argerror(L, n, "invalid format");
367 }
368 }
369 }
370 }
371 if (ferror(f))
372 return pushresult(L, 0, NULL);
373 if (!success) {
374 lua_pop(L, 1); /* remove last result */
375 lua_pushnil(L); /* push nil instead */
376 }
377 return n - first;
378}
379
380
381static int io_read (lua_State *L) {
382 return g_read(L, getiofile(L, IO_INPUT), 1);
383}
384
385
386static int f_read (lua_State *L) {
387 return g_read(L, tofile(L), 2);
388}
389
390
391static int io_readline (lua_State *L) {
392 FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
393 int sucess;
394 if (f == NULL) /* file is already closed? */
395 luaL_error(L, "file is already closed");
396 sucess = read_line(L, f);
397 if (ferror(f))
398 return luaL_error(L, "%s", strerror(errno));
399 if (sucess) return 1;
400 else { /* EOF */
401 if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
402 lua_settop(L, 0);
403 lua_pushvalue(L, lua_upvalueindex(1));
404 aux_close(L); /* close it */
405 }
406 return 0;
407 }
408}
409
410/* }====================================================== */
411
412
413static int g_write (lua_State *L, FILE *f, int arg) {
414 int nargs = lua_gettop(L) - 1;
415 int status = 1;
416 for (; nargs--; arg++) {
417 if (lua_type(L, arg) == LUA_TNUMBER) {
418 /* optimization: could be done exactly as for strings */
419 status = status &&
420 fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
421 }
422 else {
423 size_t l;
424 const char *s = luaL_checklstring(L, arg, &l);
425 status = status && (fwrite(s, sizeof(char), l, f) == l);
426 }
427 }
428 return pushresult(L, status, NULL);
429}
430
431
432static int io_write (lua_State *L) {
433 return g_write(L, getiofile(L, IO_OUTPUT), 1);
434}
435
436
437static int f_write (lua_State *L) {
438 return g_write(L, tofile(L), 2);
439}
440
441
442static int f_seek (lua_State *L) {
443 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
444 static const char *const modenames[] = {"set", "cur", "end", NULL};
445 FILE *f = tofile(L);
446 int op = luaL_checkoption(L, 2, "cur", modenames);
447 long offset = luaL_optlong(L, 3, 0);
448 op = fseek(f, offset, mode[op]);
449 if (op)
450 return pushresult(L, 0, NULL); /* error */
451 else {
452 lua_pushinteger(L, ftell(f));
453 return 1;
454 }
455}
456
457
458static int f_setvbuf (lua_State *L) {
459 static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
460 static const char *const modenames[] = {"no", "full", "line", NULL};
461 FILE *f = tofile(L);
462 int op = luaL_checkoption(L, 2, NULL, modenames);
463 lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
464 int res = setvbuf(f, NULL, mode[op], sz);
465 return pushresult(L, res == 0, NULL);
466}
467
468
469
470static int io_flush (lua_State *L) {
471 return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
472}
473
474
475static int f_flush (lua_State *L) {
476 return pushresult(L, fflush(tofile(L)) == 0, NULL);
477}
478
479
480static const luaL_Reg iolib[] = {
481 {"close", io_close},
482 {"flush", io_flush},
483 {"input", io_input},
484 {"lines", io_lines},
485 {"open", io_open},
486 {"output", io_output},
487 {"popen", io_popen},
488 {"read", io_read},
489 {"tmpfile", io_tmpfile},
490 {"type", io_type},
491 {"write", io_write},
492 {NULL, NULL}
493};
494
495
496static const luaL_Reg flib[] = {
497 {"close", io_close},
498 {"flush", f_flush},
499 {"lines", f_lines},
500 {"read", f_read},
501 {"seek", f_seek},
502 {"setvbuf", f_setvbuf},
503 {"write", f_write},
504 {"__gc", io_gc},
505 {"__tostring", io_tostring},
506 {NULL, NULL}
507};
508
509
510static void createmeta (lua_State *L) {
511 luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
512 lua_pushvalue(L, -1); /* push metatable */
513 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
514 luaL_register(L, NULL, flib); /* file methods */
515}
516
517
518static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
519 *newfile(L) = f;
520 if (k > 0) {
521 lua_pushvalue(L, -1);
522 lua_rawseti(L, LUA_ENVIRONINDEX, k);
523 }
524 lua_pushvalue(L, -2); /* copy environment */
525 lua_setfenv(L, -2); /* set it */
526 lua_setfield(L, -3, fname);
527}
528
529
530static void newfenv (lua_State *L, lua_CFunction cls) {
531 lua_createtable(L, 0, 1);
532 lua_pushcfunction(L, cls);
533 lua_setfield(L, -2, "__close");
534}
535
536
537LUALIB_API int luaopen_io (lua_State *L) {
538 createmeta(L);
539 /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
540 newfenv(L, io_fclose);
541 lua_replace(L, LUA_ENVIRONINDEX);
542 /* open library */
543 luaL_register(L, LUA_IOLIBNAME, iolib);
544 /* create (and set) default files */
545 newfenv(L, io_noclose); /* close function for default files */
546 createstdfile(L, stdin, IO_INPUT, "stdin");
547 createstdfile(L, stdout, IO_OUTPUT, "stdout");
548 createstdfile(L, stderr, 0, "stderr");
549 lua_pop(L, 1); /* pop environment for default files */
550 lua_getfield(L, -1, "popen");
551 newfenv(L, io_pclose); /* create environment for 'popen' */
552 lua_setfenv(L, -2); /* set fenv for 'popen' */
553 lua_pop(L, 1); /* pop 'popen' */
554 return 1;
555}
556
diff --git a/libraries/LuaJIT-1.1.7/src/ljit.h b/libraries/LuaJIT-1.1.7/src/ljit.h
new file mode 100644
index 0000000..347de3b
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit.h
@@ -0,0 +1,167 @@
1/*
2** Interface to JIT engine.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef ljit_h
7#define ljit_h
8
9#include "lobject.h"
10
11
12/* Define this to enable assertions when debugging LuaJIT. */
13#ifdef LUAJIT_ASSERT
14#include <assert.h>
15#define jit_assert(x) assert(x)
16#define DASM_CHECKS
17#else
18/* A better idea is to define lua_assert() in luaconf.h. */
19#define jit_assert(x) lua_assert(x)
20#endif
21
22/* Define this to set the C stack size for the compiler thread. */
23/* The compiler runs on the callers C stack otherwise. */
24#undef LUAJIT_COMPILER_CSTACK
25
26/* Hardcoded limits for the backend to avoid useless work. */
27/* Note: mind you, these are very generous limits. Check jit.opt, too. */
28#define LUAJIT_LIM_BYTECODE 3000 /* Max. # of bytecodes. */
29#define LUAJIT_LIM_MCODE 128000 /* Max. mcode size of a function. */
30
31/* Global JIT engine flags. */
32#define JIT_F_ON 0x0001 /* JIT engine is on. */
33#define JIT_F_COMPILING 0x0002 /* Currently compiling. */
34#define JIT_F_INIT_FAILED 0x0004 /* Initialization failed. */
35
36#define JIT_F_CPU_CMOV 0x0010 /* CPU has conditional move support. */
37#define JIT_F_CPU_SSE2 0x0020 /* CPU has SSE2 support. */
38
39#define JIT_F_DEBUG_CALL 0x0100 /* Compile with call hooks. */
40#define JIT_F_DEBUG_INS 0x0200 /* Compile with instruction hooks. */
41#define JIT_F_DEBUG 0x0f00 /* Union of all debug flags. */
42
43/* Temporary backend flags. */
44#define JIT_TF_USED_DEOPT 0x0001 /* Used .deopt segment. */
45
46/* JIT engine status codes for prototypes (grep "ORDER JIT_S"). */
47enum {
48 JIT_S_OK, /* OK, code has been compiled. */
49 JIT_S_NONE, /* Nothing compiled yet (default). */
50
51 JIT_S_OFF, /* Compilation for this prototype disabled. */
52 JIT_S_ENGINE_OFF, /* JIT engine is turned off. */
53 JIT_S_DELAYED, /* Compilation delayed (recursive invocation). */
54
55 JIT_S_TOOLARGE, /* Bytecode or machine code is too large. */
56 JIT_S_COMPILER_ERROR, /* Error from compiler frontend. */
57 JIT_S_DASM_ERROR, /* Error from DynASM engine. */
58
59 JIT_S_MAX
60};
61
62/* Machine code trailer and mcode fragment map. */
63typedef struct jit_MCTrailer {
64 char *mcode; /* Pointer to next machine code block. */
65 size_t sz; /* Size of next machine code block. */
66} jit_MCTrailer;
67
68typedef unsigned short jit_Mfm;
69
70/* Deliberately return a void * because the trailer is not fully aligned. */
71#define JIT_MCTRAILER(mcode, sz) \
72 ((void *)(((char *)(mcode))+(sz)-sizeof(jit_MCTrailer)))
73#define JIT_MCMFM(mcode, sz) \
74 ((jit_Mfm *)(((char *)(mcode))+(sz)-sizeof(jit_MCTrailer)-sizeof(jit_Mfm)))
75
76#define JIT_MFM_MAX 0x7ff0 /* Max. mcode fragment length. */
77#define JIT_MFM_MASK 0x7fff /* Tag mask. */
78#define JIT_MFM_MARK 0x8000 /* Deoptimized (main mfm), seek (deopt mfm). */
79#define JIT_MFM_COMBINE 0xfffd /* Combined with prev. instruction(s). */
80#define JIT_MFM_DEAD 0xfffe /* Dead instruction. */
81#define JIT_MFM_STOP 0xffff /* End of map. */
82
83#define jit_mfm_ismain(mfm) (!(*(mfm) & JIT_MFM_MARK))
84#define jit_mfm_isdeoptpc(mfm, pc) ((mfm)[-(pc)] & JIT_MFM_MARK)
85
86/* Deoptimization hints at end of mfm. */
87#define JIT_MFM_DEOPT_PAIRS 0xfffc /* CALL+TFORLOOP inlined (i)pairs. */
88
89/* Preallocation for the hash part of the compiler state table. */
90#define COMSTATE_PREALLOC 128
91
92/* Forward declaration for DynASM state. */
93struct dasm_State;
94
95/* Frontend wrapper. */
96typedef int (*jit_FrontWrap)(lua_State *L, Table *st);
97
98/* Global JIT state. */
99typedef struct jit_State {
100 /* Permanent backend environment: */
101 struct dasm_State *D; /* DynASM state. Keep this as the first field. */
102 void *mcodeheap; /* Private heap to allocate executable memory from. */
103 void **jsub; /* Addresses of JIT subroutines. */
104 void *jsubmcode; /* Base address of JSUB mcode. */
105 size_t szjsubmcode; /* Size of JSUB mcode. */
106 int numjsub; /* Number of JSUBs. */
107
108 /* Temporary backend environment (valid only while running): */
109 lua_State *L; /* Compiler thread. */
110 Table *comstate; /* Compiler state table. */
111 Proto *pt; /* Currently compiled prototype. */
112 const Instruction *nextins; /* Pointer to next instruction. */
113 jit_Mfm *mfm; /* Position in temporary mcode fragment map. */
114 int nextpc; /* Next PC. */
115 int combine; /* Number of following instructions to combine. */
116 unsigned int tflags; /* Temporary flags. */
117 int dasmstatus; /* DynASM status code. */
118
119 /* JIT engine fields: */
120 jit_FrontWrap frontwrap; /* Compiler frontend wrapper. */
121 unsigned int flags; /* Global JIT engine flags. */
122} jit_State;
123
124
125/* --- ljit_core.c */
126
127/* Initialize and free JIT engine state. */
128LUAI_FUNC void luaJIT_initstate(lua_State *L);
129LUAI_FUNC void luaJIT_freestate(lua_State *L);
130
131/* Compile and run a function. */
132LUAI_FUNC int luaJIT_run(lua_State *L, StkId func, int nresults);
133/* Deoptimize the current instruction. Return new mcode addr to continue. */
134LUAI_FUNC void *luaJIT_deoptimize(lua_State *L);
135
136/* Find relative PC (0 based) for a bytecode pointer or a JIT mcode address. */
137LUAI_FUNC int luaJIT_findpc(Proto *pt, const Instruction *savedpc);
138/* Find mcode address for PC (1 based). */
139LUAI_FUNC void *luaJIT_findmcode(Proto *pt, int pc);
140
141
142/* --- ljit_backend.c */
143
144/* Arch string. */
145LUAI_DATA const char luaJIT_arch[];
146/* Initialize and free compiler backend. */
147LUAI_FUNC int luaJIT_initbackend(lua_State *L);
148LUAI_FUNC void luaJIT_freebackend(lua_State *L);
149/* Compiler backend. */
150LUAI_FUNC int luaJIT_backend(lua_State *L);
151/* Notify backend that the debug mode may have changed. */
152LUAI_FUNC void luaJIT_debugnotify(jit_State *J);
153
154
155/* ---- ljit_mem.c */
156
157/* Free the mcode heap. */
158LUAI_FUNC void luaJIT_freemcodeheap(jit_State *J);
159/* Free mcode. */
160LUAI_FUNC void luaJIT_freemcode(jit_State *J, void *mcode, size_t sz);
161/* Free JIT structures in function prototype. */
162LUAI_FUNC void luaJIT_freeproto(lua_State *L, Proto *pt);
163/* Link generated code. */
164LUAI_FUNC int luaJIT_link(jit_State *J, void **mcodep, size_t *szp);
165
166
167#endif
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_backend.c b/libraries/LuaJIT-1.1.7/src/ljit_backend.c
new file mode 100644
index 0000000..698342f
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_backend.c
@@ -0,0 +1,342 @@
1/*
2** LuaJIT wrapper for architecture-specific compiler backend.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include <math.h>
7#include <string.h>
8
9#define ljit_backend_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "lobject.h"
15#include "lstate.h"
16#include "ldo.h"
17#include "lfunc.h"
18#include "lgc.h"
19#include "lstring.h"
20#include "ltable.h"
21#include "ltm.h"
22#include "lvm.h"
23#include "lopcodes.h"
24#include "ldebug.h"
25#include "lzio.h"
26
27#include "ljit.h"
28#include "ljit_hints.h"
29#include "ljit_dasm.h"
30
31/* ------------------------------------------------------------------------ */
32
33/* Get target of combined JMP op. */
34static int jit_jmp_target(jit_State *J)
35{
36 J->combine++;
37 jit_assert(GET_OPCODE(*J->nextins)==OP_JMP);
38 return J->nextpc + 1 + GETARG_sBx(*J->nextins);
39}
40
41/* ------------------------------------------------------------------------ */
42
43/* Include pre-processed architecture-specific backend. */
44#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
45#ifndef LUA_NUMBER_DOUBLE
46#error "No support for other number types on x86 (yet)"
47#endif
48#include "ljit_x86.h"
49#else
50#error "No support for this architecture (yet)"
51#endif
52
53/* ------------------------------------------------------------------------ */
54
55/* Compile instruction range. */
56static void jit_compile_irange(jit_State *J, int firstpc, int lastpc)
57{
58 J->combine = 0;
59 J->nextpc = firstpc;
60 J->nextins = J->pt->code + (firstpc-1);
61 while (J->nextpc <= lastpc) {
62 Instruction ins = *J->nextins++;
63 OpCode op = GET_OPCODE(ins);
64 int ra = GETARG_A(ins);
65 int rb = GETARG_B(ins);
66 int rc = GETARG_C(ins);
67 int rbx = GETARG_Bx(ins);
68 const TValue *combinehint;
69
70 jit_ins_start(J);
71 J->nextpc++;
72
73 combinehint = hint_get(J, COMBINE);
74 if (ttisboolean(combinehint)) {
75 if (bvalue(combinehint)) { /* COMBINE = true: combine with next ins. */
76 if (!(J->flags & JIT_F_DEBUG)) /* But not when debugging. */
77 J->combine = 1;
78 } else { /* COMBINE = false: dead instruction. */
79 *J->mfm++ = JIT_MFM_DEAD;
80 continue;
81 }
82 } /* Other COMBINE hint value types are not defined (yet). */
83
84 if (J->flags & JIT_F_DEBUG_INS)
85 jit_ins_debug(J, luaG_checkopenop(ins));
86
87 switch (op) {
88 case OP_MOVE: jit_op_move(J, ra, rb); break;
89 case OP_LOADK: jit_op_loadk(J, ra, rbx); break;
90 case OP_LOADBOOL: jit_op_loadbool(J, ra, rb, rc); break;
91 case OP_LOADNIL: jit_op_loadnil(J, ra, rb); break;
92
93 case OP_GETUPVAL: jit_op_getupval(J, ra, rb); break;
94 case OP_SETUPVAL: jit_op_setupval(J, ra, rb); break;
95
96 case OP_GETGLOBAL: jit_op_getglobal(J, ra, rbx); break;
97 case OP_SETGLOBAL: jit_op_setglobal(J, ra, rbx); break;
98
99 case OP_NEWTABLE: jit_op_newtable(J, ra, rb, rc); break;
100 case OP_GETTABLE: jit_op_gettable(J, ra, rb, rc); break;
101 case OP_SETTABLE: jit_op_settable(J, ra, rb, rc); break;
102 case OP_SELF: jit_op_self(J, ra, rb, rc); break;
103 case OP_SETLIST: jit_op_setlist(J, ra, rb, rc); break;
104
105 case OP_ADD: jit_op_arith(J, ra, rb, rc, TM_ADD); break;
106 case OP_SUB: jit_op_arith(J, ra, rb, rc, TM_SUB); break;
107 case OP_MUL: jit_op_arith(J, ra, rb, rc, TM_MUL); break;
108 case OP_DIV: jit_op_arith(J, ra, rb, rc, TM_DIV); break;
109 case OP_MOD: jit_op_arith(J, ra, rb, rc, TM_MOD); break;
110 case OP_POW: jit_op_arith(J, ra, rb, rc, TM_POW); break;
111 case OP_UNM: jit_op_arith(J, ra, rb, rb, TM_UNM); break; /* rc unused. */
112
113 case OP_LEN: jit_op_len(J, ra, rb); break;
114 case OP_NOT: jit_op_not(J, ra, rb); break;
115
116 case OP_CONCAT: jit_op_concat(J, ra, rb, rc); break;
117
118 case OP_EQ: jit_op_eq(J, ra, rb, rc); break;
119 case OP_LT: jit_op_arith(J, ra, rb, rc, TM_LT); break;
120 case OP_LE: jit_op_arith(J, ra, rb, rc, TM_LE); break;
121
122 case OP_TEST: jit_op_test(J, rc, ra, ra); break;
123 case OP_TESTSET: jit_op_test(J, rc, ra, rb); break;
124
125 case OP_JMP: jit_op_jmp(J, J->nextpc + rbx-MAXARG_sBx); break;
126
127 case OP_CALL: jit_op_call(J, ra, rb-1, rc-1); break;
128 case OP_TAILCALL: jit_op_tailcall(J, ra, rb-1); break;
129 case OP_RETURN: jit_op_return(J, ra, rb-1); break;
130
131 case OP_FORLOOP: jit_op_forloop(J, ra, J->nextpc + rbx-MAXARG_sBx); break;
132 case OP_FORPREP: jit_op_forprep(J, ra, J->nextpc + rbx-MAXARG_sBx); break;
133
134 case OP_TFORLOOP: jit_op_tforloop(J, ra, rc); break;
135
136 case OP_CLOSE: jit_op_close(J, ra); break;
137 case OP_CLOSURE: jit_op_closure(J, ra, rbx); break;
138
139 case OP_VARARG: jit_op_vararg(J, ra, rb-1); break;
140
141 default: jit_assert(0); break;
142 }
143
144 /* Convention: all opcodes start and end with the .code section. */
145 if (dasm_checkstep(Dst, DASM_SECTION_CODE)) { J->nextpc--; return; }
146
147 *J->mfm++ = 0; /* Placeholder mfm entry. Replaced later. */
148 if (J->combine > 0) { /* Combine next J->combine ins with prev ins. */
149 J->nextpc += J->combine;
150 J->nextins += J->combine;
151 do { *J->mfm++ = JIT_MFM_COMBINE; } while (--J->combine);
152 }
153 }
154}
155
156/* Merge temporary mfm (forward) with PC labels to inverse mfm in mcode. */
157static void jit_mfm_merge(jit_State *J, jit_Mfm *from, jit_Mfm *to, int maxpc)
158{
159 int pc = 1, ofs = 0;
160 for (;;) {
161 int m = *from++;
162 if (m & JIT_MFM_MARK) {
163 switch (m) {
164 default: pc = m ^ JIT_MFM_MARK; break;
165 case JIT_MFM_COMBINE: case JIT_MFM_DEAD: break;
166 case JIT_MFM_STOP: return;
167 }
168 } else {
169 int idx, nofs;
170 for (idx = 0; from[idx] == JIT_MFM_COMBINE; idx++) ;
171 idx += pc;
172 if (idx == J->nextpc) idx = maxpc + 1;
173 nofs = dasm_getpclabel(Dst, idx);
174 m = nofs - ofs;
175 ofs = nofs;
176 jit_assert(nofs >= 0 && m >= 0 && m < JIT_MFM_MAX);
177 }
178 pc++;
179 *to-- = m;
180 }
181}
182
183/* Compile function prototype. */
184static int jit_compile_proto(jit_State *J, Table *deopt)
185{
186 jit_Mfm *tempmfm;
187 void *mcode;
188 size_t sz;
189 int firstpc = 0, maxpc = J->pt->sizecode;
190 int deoptidx = 1;
191 int status;
192 /* (Ab)use the global string concatenation buffer for the temporary mfm. */
193 /* Caveat: the GC must not be run while the backend is active. */
194 tempmfm = (jit_Mfm *)luaZ_openspace(J->L, &G(J->L)->buff,
195 (1+maxpc+1+1+1)*sizeof(jit_Mfm));
196nextdeopt:
197 J->mfm = tempmfm;
198 J->tflags = 0;
199 /* Setup DynASM. */
200 dasm_growpc(Dst, 1+maxpc+2); /* See jit_ins_last(). */
201 dasm_setup(Dst, jit_actionlist);
202 if (deopt) { /* Partial deoptimization. */
203 /* TODO: check deopt chain length? problem: pairs TFOR_CTL migration. */
204 int pc, lastpc;
205 lua_Number n;
206 const TValue *obj = luaH_getnum(deopt, deoptidx++);
207 if (ttisnil(obj) && deoptidx != 2) return JIT_S_OK;
208 if (!ttisnumber(obj)) return JIT_S_COMPILER_ERROR;
209 n = nvalue(obj);
210 lua_number2int(pc, n);
211 firstpc = JIT_IH_IDX(pc);
212 lastpc = firstpc + JIT_IH_LIB(pc);
213 if (firstpc < 1 || firstpc > maxpc || lastpc > maxpc ||
214 J->pt->jit_szmcode == 0)
215 return JIT_S_COMPILER_ERROR;
216 *J->mfm++ = JIT_MFM_MARK+firstpc; /* Seek to firstpc. */
217 jit_compile_irange(J, firstpc, lastpc);
218 jit_assert(J->nextpc == lastpc+1); /* Problem with combined ins? */
219 if (J->nextpc <= maxpc) jit_ins_chainto(J, J->nextpc);
220 *J->mfm++ = JIT_MFM_MARK+maxpc+1; /* Seek to .deopt/.tail. */
221 for (pc = 1; pc <= maxpc; pc++)
222 if (dasm_getpclabel(Dst, pc) == -1) { /* Undefind label referenced? */
223 jit_ins_setpc(J, pc, luaJIT_findmcode(J->pt, pc)); /* => Old mcode. */
224 }
225 } else { /* Full compile. */
226 *J->mfm++ = 0; /* Placeholder mfm entry for prologue. */
227 jit_prologue(J);
228 jit_compile_irange(J, 1, maxpc);
229 }
230 *J->mfm++ = 0; /* Placeholder mfm entry for .deopt/.tail. */
231 *J->mfm = JIT_MFM_STOP;
232 jit_ins_last(J, maxpc, (char *)J->mfm - (char *)tempmfm);
233
234 status = luaJIT_link(J, &mcode, &sz);
235 if (status != JIT_S_OK)
236 return status;
237
238 jit_mfm_merge(J, tempmfm, JIT_MCMFM(mcode, sz), maxpc);
239
240 if (deopt) {
241 jit_MCTrailer tr;
242 /* Patch first instruction to jump to the deoptimized code. */
243 jit_patch_jmp(J, luaJIT_findmcode(J->pt, firstpc), mcode);
244 /* Mark instruction as deoptimized in main mfm. */
245 JIT_MCMFM(J->pt->jit_mcode, J->pt->jit_szmcode)[-firstpc] |= JIT_MFM_MARK;
246 /* Chain deopt mcode block between main mfm and existing mfms. */
247 memcpy(JIT_MCTRAILER(mcode, sz),
248 JIT_MCTRAILER(J->pt->jit_mcode, J->pt->jit_szmcode),
249 sizeof(jit_MCTrailer));
250 tr.mcode = (char *)mcode;
251 tr.sz = sz;
252 memcpy(JIT_MCTRAILER(J->pt->jit_mcode, J->pt->jit_szmcode), (void *)&tr,
253 sizeof(jit_MCTrailer));
254 goto nextdeopt;
255 }
256
257 if (J->pt->jit_szmcode != 0) { /* Full recompile? */
258 jit_MCTrailer tr;
259 /* Patch old mcode entry so other closures get the new callgate. */
260 jit_patch_jmp(J, J->pt->jit_mcode, J->jsub[JSUB_GATE_JL]);
261 /* Chain old main mfm after new main mfm. */
262 tr.mcode = (char *)J->pt->jit_mcode;
263 tr.sz = J->pt->jit_szmcode;
264 memcpy(JIT_MCTRAILER(mcode, sz), (void *)&tr, sizeof(jit_MCTrailer));
265 }
266 /* Set new main mcode block. */
267 J->pt->jit_mcode = mcode;
268 J->pt->jit_szmcode = sz;
269 return JIT_S_OK;
270}
271
272/* ------------------------------------------------------------------------ */
273
274/* Compiler backend. */
275int luaJIT_backend(lua_State *L)
276{
277 jit_State *J = G(L)->jit_state;
278 const TValue *cl;
279 int status = JIT_S_COMPILER_ERROR;
280 lua_lock(L);
281 /* Remember compiler state table. */
282 jit_assert(L->top > L->base && ttistable(L->top-1));
283 J->comstate = hvalue(L->top-1);
284 /* Fetch prototoype. Better check this in case some handler screwed up. */
285 cl = luaH_getstr(J->comstate, luaS_newliteral(L, "func"));
286 if (isLfunction(cl)) {
287 J->pt = clvalue(cl)->l.p;
288 if (J->pt->sizecode > LUAJIT_LIM_BYTECODE) { /* Hard backend limit. */
289 status = JIT_S_TOOLARGE;
290 } else {
291 const TValue *obj = luaH_getstr(J->comstate,
292 luaS_newliteral(J->L, "deopt"));
293 status = jit_compile_proto(J, ttistable(obj) ? hvalue(obj) : (Table *)0);
294 }
295 }
296 lua_unlock(L);
297 J->comstate = NULL; /* Just in case. */
298 J->pt = NULL;
299 if (status == JIT_S_OK) {
300 return 0;
301 } else {
302 if (status == JIT_S_DASM_ERROR) {
303 lua_pushinteger(L, J->nextpc);
304 lua_setfield(L, 1, "dasm_pc");
305 lua_pushinteger(L, J->dasmstatus);
306 lua_setfield(L, 1, "dasm_err");
307 }
308 lua_pushinteger(L, status);
309 return 1;
310 }
311}
312
313/* Initialize compiler backend. */
314int luaJIT_initbackend(lua_State *L)
315{
316 jit_State *J = G(L)->jit_state;
317 J->L = L;
318 J->pt = NULL; /* Not in use. */
319 J->D = NULL;
320 J->mcodeheap = NULL;
321 J->jsubmcode = NULL;
322 J->szjsubmcode = 0;
323 J->numjsub = JSUB__MAX;
324 J->jsub = luaM_newvector(J->L, JSUB__MAX, void *);
325 memset((void *)J->jsub, 0, JSUB__MAX*sizeof(void *)); /* Just in case. */
326 dasm_init(Dst, DASM_MAXSECTION);
327 dasm_setupglobal(Dst, J->jsub, JSUB__MAX);
328 return jit_compile_jsub(J);
329}
330
331/* Free compiler backend. */
332void luaJIT_freebackend(lua_State *L)
333{
334 jit_State *J = G(L)->jit_state;
335 J->L = L;
336 if (J->jsub) luaM_freearray(L, J->jsub, JSUB__MAX, void *);
337 luaJIT_freemcodeheap(J); /* Frees JSUB mcode, too. */
338 dasm_free(Dst);
339}
340
341/* ------------------------------------------------------------------------ */
342
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_core.c b/libraries/LuaJIT-1.1.7/src/ljit_core.c
new file mode 100644
index 0000000..f7385f2
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_core.c
@@ -0,0 +1,385 @@
1/*
2** Interface to JIT engine.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define ljit_core_c
7#define LUA_CORE
8
9#include <string.h>
10
11#include "lua.h"
12
13#include "lobject.h"
14#include "lstate.h"
15#include "ldo.h"
16#include "lstring.h"
17#include "ltable.h"
18#include "ldebug.h"
19#include "lopcodes.h"
20
21#include "ljit.h"
22#include "ljit_hints.h"
23#include "luajit.h"
24
25const char luajit_ident[] =
26 "$LuaJIT: " LUAJIT_VERSION " " LUAJIT_COPYRIGHT " " LUAJIT_URL " $\n";
27
28/* ------------------------------------------------------------------------ */
29
30/* Initialize JIT engine state. */
31void luaJIT_initstate(lua_State *L)
32{
33 jit_State *J = luaM_new(L, jit_State);
34 G(L)->jit_state = J;
35 /* Clear JIT engine fields. */
36 J->frontwrap = NULL; /* Filled in by ljitlib before enabling the engine. */
37 J->flags = 0; /* Disable the JIT engine by default. */
38 /* Try to initialize the backend. */
39 if (luaJIT_initbackend(L) != JIT_S_OK)
40 J->flags = JIT_F_INIT_FAILED;
41 J->L = NULL; /* No compiler thread allocated, yet. */
42}
43
44/* Free JIT engine state. */
45void luaJIT_freestate(lua_State *L)
46{
47 jit_State *J = G(L)->jit_state;
48 if (J == NULL) return;
49 luaJIT_freebackend(L);
50 luaM_free(L, J);
51 G(L)->jit_state = NULL;
52}
53
54/* ------------------------------------------------------------------------ */
55
56/* Find relative PC (0 based) for a bytecode pointer or a JIT mcode address. */
57int luaJIT_findpc(Proto *pt, const Instruction *savedpc)
58{
59 ptrdiff_t pcdiff = savedpc - pt->code;
60 if (pcdiff >= 0 && pcdiff <= pt->sizecode) { /* Bytecode pointer? */
61 return (int)pcdiff-1;
62 } else { /* Else translate JIT mcode address to PC. */
63 char *addr = (char *)savedpc;
64 jit_MCTrailer tr;
65 tr.mcode = (char *)pt->jit_mcode;
66 tr.sz = pt->jit_szmcode;
67 /* Follow trailer chain until addr is part of an mcode block. */
68 while (!((size_t)(addr - tr.mcode) < tr.sz)) {
69 memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz),
70 sizeof(jit_MCTrailer));
71 if (tr.mcode == NULL) return -1; /* Not in chain. */
72 }
73 {
74 jit_Mfm *mfm = JIT_MCMFM(tr.mcode, tr.sz);
75 int ofs = (int)(addr - tr.mcode);
76 int isdeopt = !jit_mfm_ismain(mfm);
77 int pc = 0; /* Prologue fragment is at start of main mfm. */
78 while (pc <= pt->sizecode) {
79 int m = *mfm--;
80 switch (m) {
81 default:
82 if (m & JIT_MFM_MARK) {
83 m ^= JIT_MFM_MARK;
84 if (isdeopt) { pc = m; continue; } /* Seek. */
85 }
86 ofs -= m;
87 if (ofs <= 0) return pc-1; /* Found! */
88 case JIT_MFM_COMBINE:
89 case JIT_MFM_DEAD:
90 pc++;
91 break;
92 case JIT_MFM_STOP:
93 jit_assert(0); /* Premature STOP found. */
94 return -1;
95 }
96 }
97 jit_assert(0); /* Address is in .tail. */
98 return -1;
99 }
100 }
101}
102
103/* Lookup mcode address for PC (1 based) in mfm. */
104static void *jit_mfmlookup(jit_Mfm *mfm, char *addr, int mpc)
105{
106 int isdeopt = !jit_mfm_ismain(mfm);
107 int pc = 0; /* Prologue fragment is at start of main mfm. */
108 while (pc != mpc) {
109 int m = *mfm--;
110 switch (m) {
111 default:
112 if (m & JIT_MFM_MARK) {
113 m ^= JIT_MFM_MARK;
114 if (isdeopt) { pc = m; continue; } /* Seek. */
115 }
116 addr += m;
117 case JIT_MFM_COMBINE:
118 case JIT_MFM_DEAD:
119 pc++;
120 break;
121 case JIT_MFM_STOP:
122 return NULL;
123 }
124 }
125 return (void *)addr;
126}
127
128/* Find mcode address for PC (1 based). */
129void *luaJIT_findmcode(Proto *pt, int pc)
130{
131 void *addr = NULL;
132 jit_Mfm *mfm;
133 jit_MCTrailer tr;
134 tr.mcode = (char *)pt->jit_mcode;
135 tr.sz = pt->jit_szmcode;
136 mfm = JIT_MCMFM(tr.mcode, tr.sz);
137 jit_assert(pc >= 1 && pc <= pt->sizecode);
138 while (mfm[-pc] == JIT_MFM_COMBINE) pc--;
139 while (mfm[-pc] == JIT_MFM_DEAD) pc++;
140 jit_assert(pc >= 1 && mfm[-pc] < (JIT_MFM_MARK|JIT_MFM_MAX)); /* Valid? */
141 if (jit_mfm_isdeoptpc(mfm, pc)) { /* Deoptimized instruction. */
142 do { /* Search through deopt mfm chain. */
143 memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz),
144 sizeof(jit_MCTrailer));
145 if (tr.mcode == NULL) break; /* Deopt ins missing in chain. */
146 mfm = JIT_MCMFM(tr.mcode, tr.sz);
147 if (jit_mfm_ismain(mfm)) break; /* Old main mfm stops search, too. */
148 addr = jit_mfmlookup(mfm, tr.mcode, pc);
149 } while (addr == NULL);
150 } else { /* Not deoptimized. Lookup in main mfm. */
151 addr = jit_mfmlookup(mfm, tr.mcode, pc);
152 }
153 jit_assert(addr != NULL); /* Corrupt mfm chain. */
154 return addr;
155}
156
157/* ------------------------------------------------------------------------ */
158
159/* Compile a prototype. */
160/* Note: func pointer may be invalidated because of stack reallocation. */
161static int jit_compile(lua_State *L, StkId func, Table *st, int force)
162{
163 jit_State *J = G(L)->jit_state;
164 Closure *cl = clvalue(func);
165 Proto *pt = cl->l.p;
166 int status;
167
168 /* Check if JIT engine is enabled and prevent recursive invocation. */
169 if ((J->flags & JIT_F_INIT_FAILED) ||
170 (!force && !(J->flags & JIT_F_ON)) ||
171 !J->frontwrap) {
172 status = JIT_S_ENGINE_OFF;
173 } else if (J->flags & JIT_F_COMPILING) {
174 status = JIT_S_DELAYED;
175 } else if (pt->jit_szmcode != 0 && force < 2) { /* Prevent recompile. */
176 /* TODO: Allow recompiles? Use case? Extra flag for jit.compile()? */
177 status = JIT_S_OK;
178 } else {
179 setclvalue(L, luaH_setstr(L, st, luaS_newliteral(L, "func")), cl);
180 /* Call frontend wrapper. */
181 J->flags |= JIT_F_COMPILING;
182 lua_unlock(L);
183 status = J->frontwrap(L, st);
184 lua_lock(L);
185 J->flags &= ~JIT_F_COMPILING;
186 }
187
188 /* Better sanity check what the frontend returns. */
189 if ((status == JIT_S_OK && pt->jit_szmcode == 0) || status == JIT_S_NONE)
190 status = JIT_S_COMPILER_ERROR;
191
192 /* Update closure callgate and prototype status. */
193 cl->l.jit_gate = (status == JIT_S_OK) ? (lua_CFunction)pt->jit_mcode :
194 G(L)->jit_gateJL;
195 pt->jit_status = status;
196 return status;
197}
198
199/* Create the state table and copy the arguments. */
200static Table *jit_createstate(lua_State *L, StkId arg, int nargs)
201{
202 Table *st = luaH_new(L, nargs, COMSTATE_PREALLOC);
203 int i;
204 for (i = 0; i < nargs; i++)
205 setobj2t(L, luaH_setnum(L, st, i+1), arg+i);
206 return st;
207}
208
209/* ------------------------------------------------------------------------ */
210
211/* Compile and run a function. To be used by luaD_precall() only. */
212int luaJIT_run(lua_State *L, StkId func, int nresults)
213{
214 ptrdiff_t funcr = savestack(L, func);
215 Table *st = jit_createstate(L, func+1, L->top-(func+1));
216 int status = jit_compile(L, func, st, 0); /* Compile function. */
217 func = restorestack(L, funcr);
218
219 /* Run the compiled function on success. Fallback to bytecode on failure. */
220 if (status == JIT_S_OK)
221 return G(L)->jit_gateLJ(L, func, nresults);
222 else
223 return luaD_precall(L, func, nresults);
224 /* Note: We are called from luaD_precall and we call it again. */
225 /* So jit_compile makes sure pt->jit_status != JIT_S_NONE. */
226}
227
228/* ------------------------------------------------------------------------ */
229
230/* No more than two ranges for a single deoptimization right now. */
231#define DEOPTRANGE_ALLOC 2
232
233/* Find PC range of combined instructions and return a range hint. */
234static int combinedrange(jit_Mfm *mfm, int pc)
235{
236 int lastpc = pc;
237 while (mfm[-pc] == JIT_MFM_COMBINE) pc--; /* 1st comb. ins. */
238 while (mfm[-(lastpc+1)] == JIT_MFM_COMBINE) lastpc++; /* Last comb. ins. */
239 return JIT_IH_MKIDX(lastpc-pc, pc); /* (#ins-1, pc) in hint format. */
240}
241
242/* Process deoptimization hints for the given PC range. */
243static int deopthints(Proto *pt, jit_Mfm *dh, TValue *dhint, int pcrange)
244{
245 int m;
246 setnvalue(dhint++, (lua_Number)pcrange);
247 while ((m = *dh--) != JIT_MFM_STOP) {
248 if ((unsigned int)(m - JIT_IH_IDX(pcrange)) <=
249 (unsigned int)JIT_IH_LIB(pcrange)) {
250 switch (*dh--) {
251 case JIT_MFM_DEOPT_PAIRS: /* CALL [i]pairs(): deopt TFORLOOP+JMP. */
252 if (GET_OPCODE(pt->code[m+1-1]) == OP_JMP) {
253 int tfpc = m+2 + GETARG_sBx(pt->code[m+1-1]);
254 if ((unsigned)tfpc < (unsigned)pt->sizecode &&
255 GET_OPCODE(pt->code[tfpc-1]) == OP_TFORLOOP) {
256 setnvalue(dhint++, (lua_Number)JIT_IH_MKIDX(1, tfpc));
257 break;
258 }
259 }
260 return 1; /* Bad hint. */
261 default:
262 return 1; /* Cannot tolerate unknown deoptimization hints. */
263 }
264 }
265 }
266 return 0; /* Ok. */
267}
268
269/* Deoptimize the current instruction. Return new mcode addr to continue. */
270void *luaJIT_deoptimize(lua_State *L)
271{
272 StkId func = L->ci->func;
273 Proto *pt = clvalue(func)->l.p;
274 int pc = luaJIT_findpc(pt, L->savedpc)+1; /* Get prev. PC (1 based). */
275 jit_Mfm *mfm = JIT_MCMFM(pt->jit_mcode, pt->jit_szmcode);
276 int pcrange = combinedrange(mfm, pc);
277 if (!jit_mfm_isdeoptpc(mfm, JIT_IH_IDX(pcrange))) { /* Not deopt. yet? */
278 Table *st = jit_createstate(L, NULL, 0); /* Don't know original args. */
279 Table *deopt = luaH_new(L, DEOPTRANGE_ALLOC, 0);
280 sethvalue(L, luaH_setstr(L, st, luaS_newliteral(L, "deopt")), deopt);
281 if (deopthints(pt, mfm-(pt->sizecode+2), deopt->array, pcrange) ||
282 jit_compile(L, func, st, 2) != JIT_S_OK)
283 luaG_runerror(L, "deoptimization failed");
284 }
285 return luaJIT_findmcode(pt, pc);
286}
287
288/* ------------------------------------------------------------------------ */
289
290/* API function: Compile a Lua function. Pass arguments as hints. */
291LUA_API int luaJIT_compile(lua_State *L, int nargs)
292{
293 StkId func;
294 Table *st;
295 int status;
296 lua_lock(L);
297 api_check(L, (nargs+1) <= (L->top - L->base));
298 func = L->top - (nargs+1);
299 st = jit_createstate(L, func+1, nargs);
300 status = isLfunction(func) ? jit_compile(L, func, st, 1) : -1;
301 lua_unlock(L);
302 return status;
303}
304
305/* Recursively set the mode for all subroutines. */
306static void rec_setmode(Proto *pt, int on)
307{
308 int i;
309 for (i = 0; i < pt->sizep; i++) {
310 Proto *pti = pt->p[i];
311 pti->jit_status = on ? (pti->jit_szmcode?JIT_S_OK:JIT_S_NONE) : JIT_S_OFF;
312 rec_setmode(pti, on); /* Recurse into proto. */
313 }
314}
315
316/* API function: Set the JIT mode for the whole engine or a function+subs. */
317LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode)
318{
319 jit_State *J = G(L)->jit_state;
320 int mm = mode & LUAJIT_MODE_MASK;
321 if (J->flags & JIT_F_INIT_FAILED) return -1; /* Init failed. */
322 switch (mm) {
323 case LUAJIT_MODE_ENGINE: /* Set mode for JIT engine. */
324 if (mode & LUAJIT_MODE_ON)
325 J->flags |= JIT_F_ON;
326 else
327 J->flags &= ~JIT_F_ON;
328 break;
329 case LUAJIT_MODE_DEBUG: { /* Set debug mode. */
330 int dbg;
331 switch (idx) {
332 case 0: dbg = 0; break;
333 case 1: dbg = JIT_F_DEBUG_CALL; break;
334 case 2: default: dbg = JIT_F_DEBUG_CALL | JIT_F_DEBUG_INS; break;
335 }
336 J->flags = (J->flags & ~JIT_F_DEBUG) | dbg;
337 luaJIT_debugnotify(J);
338 break;
339 }
340 case LUAJIT_MODE_FUNC: /* Set mode for function. */
341 case LUAJIT_MODE_ALLFUNC: /* Set mode for function + subfuncs. */
342 case LUAJIT_MODE_ALLSUBFUNC: { /* Set mode for subfunctions. */
343 StkId func;
344 lua_lock(L);
345 func = idx == 0 ? (L->ci-1)->func :
346 (idx > 0 ? L->base + (idx-1) : L->top + idx);
347 if (isLfunction(func)) {
348 Closure *cl = clvalue(func);
349 Proto *pt = cl->l.p;
350 if (mm != LUAJIT_MODE_ALLSUBFUNC) {
351 if (mode & LUAJIT_MODE_ON) {
352 if (pt->jit_szmcode) { /* Already compiled? */
353 cl->l.jit_gate = (lua_CFunction)pt->jit_mcode; /* Reenable. */
354 pt->jit_status = JIT_S_OK;
355 } else {
356 pt->jit_status = JIT_S_NONE; /* (Re-)enable proto compilation */
357 }
358 } else {
359 cl->l.jit_gate = G(L)->jit_gateJL; /* Default callgate. */
360 pt->jit_status = JIT_S_OFF; /* Disable proto compilation. */
361 /* Note: compiled code must be retained for suspended threads. */
362 }
363 }
364 if (mm != LUAJIT_MODE_FUNC)
365 rec_setmode(pt, mode & LUAJIT_MODE_ON);
366 lua_unlock(L);
367 } else {
368 lua_unlock(L);
369 return 0; /* Failed. */
370 }
371 break;
372 }
373 default:
374 return 0; /* Failed. */
375 }
376 return 1; /* OK. */
377}
378
379/* Enforce (dynamic) linker error for version mismatches. See lua.c. */
380LUA_API void LUAJIT_VERSION_SYM(void)
381{
382}
383
384/* ------------------------------------------------------------------------ */
385
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_dasm.c b/libraries/LuaJIT-1.1.7/src/ljit_dasm.c
new file mode 100644
index 0000000..c2d44ee
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_dasm.c
@@ -0,0 +1,38 @@
1/*
2** Wrapper for architecture-specific DynASM encoder.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define ljit_dasm_c
7#define LUA_CORE
8
9
10#include "lua.h"
11
12#include "ljit.h"
13#include "ljit_dasm.h"
14#include "lmem.h"
15
16
17/* Glue macros for DynASM memory allocation. */
18#define DASM_M_GROW(J, t, p, sz, need) \
19 do { \
20 size_t _sz = (sz), _need = (need); \
21 if (_sz < _need) { \
22 if (_sz < 16) _sz = 16; \
23 while (_sz < _need) _sz += _sz; \
24 (p) = (t *)luaM_realloc_(J->L, (p), (sz), _sz); \
25 (sz) = _sz; \
26 } \
27 } while(0)
28
29#define DASM_M_FREE(J, p, sz) luaM_freemem(J->L, p, sz)
30
31/* Embed architecture-specific DynASM encoder. */
32#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
33#include "dasm_x86.h"
34#else
35#error "No support for this architecture (yet)"
36#endif
37
38
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_dasm.h b/libraries/LuaJIT-1.1.7/src/ljit_dasm.h
new file mode 100644
index 0000000..0a9dd5d
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_dasm.h
@@ -0,0 +1,19 @@
1/*
2** Interface to DynASM engine.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef ljit_dasm_h
7#define ljit_dasm_h
8
9#include "ljit.h"
10
11/* DynASM glue definitions. */
12#define Dst J
13#define Dst_DECL jit_State *J
14#define Dst_REF (J->D)
15#define DASM_FDEF LUAI_FUNC
16
17#include "dasm_proto.h"
18
19#endif
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_hints.h b/libraries/LuaJIT-1.1.7/src/ljit_hints.h
new file mode 100644
index 0000000..23743bc
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_hints.h
@@ -0,0 +1,137 @@
1/*
2** Hints for the JIT compiler backend.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifdef STRING_HINTS
7#define HH(x, name) #name
8#define HH_START(x) static const char *const hints_##x [] = {
9#define HH_END(x) NULL }
10#else
11#define HH(x, name) JIT_##x##_##name
12#define HH_START(x) enum { JIT_##x##_NONE,
13#define HH_END(x) JIT_##x##_MAX }
14
15/* Macros to access hints. */
16#define JIT_H2NUM(x) ((x) << 16)
17
18#define fhint_get(J, hh) \
19 (luaH_getnum(J->comstate, JIT_H2NUM(JIT_FH_##hh)))
20#define fhint_isset(J, hh) (!ttisnil(fhint_get(J, hh)))
21
22#define hint_getpc(J, hh, pc) \
23 (luaH_getnum(J->comstate, (pc)+JIT_H2NUM(JIT_H_##hh)))
24#define hint_get(J, hh) hint_getpc(J, hh, J->nextpc-1)
25#define hint_issetpc(J, hh, pc) (!ttisnil(hint_getpc(J, hh, pc)))
26#define hint_isset(J, hh) hint_issetpc(J, hh, J->nextpc-1)
27
28#endif
29
30/* Hints for functions. */
31HH_START(FH)
32 HH(FH, NOCLOSE), /* No luaF_close() needed. */
33HH_END(FH);
34
35/* Hints for individual bytecode instruction. */
36HH_START(H)
37 HH(H, COMBINE), /* Combine/dead instruction: true/false. */
38 HH(H, FOR_STEP_K), /* FORPREP/FORLOOP step is const: step. */
39 HH(H, TYPE), /* Type hint: typed object. */
40 HH(H, TYPEKEY), /* Type hint for keys: typed object. */
41 HH(H, INLINE), /* Inline function call: internal index. */
42HH_END(H);
43
44#undef HH
45#undef HH_START
46#undef HH_END
47
48
49/* Avoid multiple inclusion for the following. */
50#ifndef ljit_hints_h
51#define ljit_hints_h
52
53/* Index numbers for inlining C functions. */
54/* CHECK: the index numbers must match with jit.opt_lib. */
55
56#define JIT_IH_LIB(x) ((x) >> 16)
57#define JIT_IH_IDX(x) ((x) & 0xffff)
58#define JIT_IH_MKIDX(l, f) (((l) << 16) | (f))
59
60/* Library index numbers. */
61enum {
62 JIT_IHLIB_INTERNAL,
63 JIT_IHLIB_BASE,
64 JIT_IHLIB_COROUTINE,
65 JIT_IHLIB_STRING,
66 JIT_IHLIB_TABLE,
67 JIT_IHLIB_MATH,
68 JIT_IHLIB__LAST
69};
70
71/* Internal functions. */
72enum {
73 JIT_IH_INTERNAL_RECURSIVE, /* Recursive call. */
74 JIT_IH_INTERNAL__LAST
75};
76
77/* Base library functions. */
78enum {
79 JIT_IH_BASE_PAIRS,
80 JIT_IH_BASE_IPAIRS,
81 JIT_IH_BASE__LAST
82};
83
84/* Coroutine library functions. */
85enum {
86 JIT_IH_COROUTINE_YIELD,
87 JIT_IH_COROUTINE_RESUME,
88 JIT_IH_COROUTINE__LAST
89};
90
91/* String library functions. */
92enum {
93 JIT_IH_STRING_LEN,
94 JIT_IH_STRING_SUB,
95 JIT_IH_STRING_CHAR,
96 JIT_IH_STRING__LAST
97};
98
99/* Table library functions. */
100enum {
101 JIT_IH_TABLE_INSERT,
102 JIT_IH_TABLE_REMOVE,
103 JIT_IH_TABLE_GETN,
104 JIT_IH_TABLE__LAST
105};
106
107/* Math library functions. */
108/* CHECK: order must match with function table for jit_inline_math(). */
109enum {
110 /* 1 arg, 1 result. */
111 /* Partially inlined. Call C function from libm: */
112 JIT_IH_MATH_LOG,
113 JIT_IH_MATH_LOG10,
114 JIT_IH_MATH_EXP,
115 JIT_IH_MATH_SINH,
116 JIT_IH_MATH_COSH,
117 JIT_IH_MATH_TANH,
118 JIT_IH_MATH_ASIN,
119 JIT_IH_MATH_ACOS,
120 JIT_IH_MATH_ATAN,
121 /* Fully inlined: */
122 JIT_IH_MATH_SIN,
123 JIT_IH_MATH_COS,
124 JIT_IH_MATH_TAN,
125 JIT_IH_MATH_CEIL,
126 JIT_IH_MATH_FLOOR,
127 JIT_IH_MATH_ABS,
128 JIT_IH_MATH_SQRT,
129 /* 2 args, 1 result. */
130 JIT_IH_MATH_FMOD,
131 JIT_IH_MATH_ATAN2,
132 JIT_IH_MATH__LAST
133};
134
135#define JIT_IH_MATH__21 JIT_IH_MATH_FMOD
136
137#endif
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_mem.c b/libraries/LuaJIT-1.1.7/src/ljit_mem.c
new file mode 100644
index 0000000..73ade7f
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_mem.c
@@ -0,0 +1,405 @@
1/*
2** Memory management for machine code.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define ljit_mem_c
7#define LUA_CORE
8
9#include <string.h>
10
11#include "lua.h"
12
13#include "lmem.h"
14#include "ldo.h"
15#include "ljit.h"
16#include "ljit_dasm.h"
17
18
19/*
20** Define this if you want to run LuaJIT with valgrind. You will get random
21** errors if you don't. And these errors are usually not caught by valgrind!
22**
23** This macro evaluates to a no-op if not run with valgrind. I.e. you can
24** use the same binary for regular runs, too (without a performance loss).
25*/
26#ifdef USE_VALGRIND
27#include <valgrind/valgrind.h>
28#define MCH_INVALIDATE(ptr, addr) VALGRIND_DISCARD_TRANSLATIONS(ptr, addr)
29#else
30#define MCH_INVALIDATE(ptr, addr) ((void)0)
31#endif
32
33
34/* ------------------------------------------------------------------------ */
35
36#if defined(_WIN32) && !defined(LUAJIT_MCH_USE_MALLOC)
37
38/* Use a private heap with executable memory for Windows. */
39#include <windows.h>
40
41/* No need for serialization. There's already a lock per Lua universe. */
42#ifdef HEAP_CREATE_ENABLE_EXECUTE
43#define MCH_HCFLAGS (HEAP_NO_SERIALIZE|HEAP_CREATE_ENABLE_EXECUTE)
44#else
45#define MCH_HCFLAGS (HEAP_NO_SERIALIZE|0x00040000)
46#endif
47
48/* Free the whole mcode heap. */
49void luaJIT_freemcodeheap(jit_State *J)
50{
51 if (J->mcodeheap) HeapDestroy((HANDLE)J->mcodeheap);
52}
53
54/* Allocate a code block from the mcode heap. */
55static void *mcode_alloc(jit_State *J, size_t sz)
56{
57 void *ptr;
58 if (J->mcodeheap == NULL) {
59 J->mcodeheap = (void *)HeapCreate(MCH_HCFLAGS, 0, 0);
60 if (J->mcodeheap == NULL) luaD_throw(J->L, LUA_ERRMEM);
61 }
62 ptr = HeapAlloc(J->mcodeheap, 0, (sz));
63 if (ptr == NULL) luaD_throw(J->L, LUA_ERRMEM);
64 return ptr;
65}
66
67#define mcode_free(L, J, p, sz) HeapFree(J->mcodeheap, 0, (p))
68
69/* ------------------------------------------------------------------------ */
70
71#elif defined(LUA_USE_POSIX) && !defined(LUAJIT_MCH_USE_MALLOC)
72
73/*
74** Allocate EXECUTABLE memory with mmap() on POSIX systems.
75**
76** There is no standard way to reuse malloc(). So this is a very small,
77** but also very naive memory allocator. This should be ok, because:
78**
79** 1. Most apps only allocate mcode while running and free all on exit.
80**
81** 2. Some apps regularly load/unload a bunch of modules ("stages").
82** Allocs/frees come in groups, so coalescing should work fine.
83**
84** If your app differs, then please elaborate and/or supply code.
85** And no -- including a full blown malloc is NOT an option.
86**
87** Caveat: the mmap()'ed heaps are not freed until exit.
88** This shouldn't be too difficult to add, but I didn't bother.
89*/
90
91#include <sys/types.h>
92#include <sys/mman.h>
93
94/* TODO: move this to luaconf.h */
95#define LUAJIT_MCH_CHUNKSIZE (1<<17) /* 128K */
96
97#if defined(MAP_ANONYMOUS)
98#define MCH_MMFLAGS (MAP_PRIVATE|MAP_ANONYMOUS)
99#elif defined(MAP_ANON)
100#define MCH_MMFLAGS (MAP_PRIVATE|MAP_ANON)
101#else
102/* I'm too lazy to add /dev/zero support for ancient systems. */
103#error "Your OS has no (easy) support for anonymous mmap(). Please upgrade."
104#endif
105
106/* Chunk header. Used for the free chunk list / heap headers. */
107typedef struct MCodeHead {
108 struct MCodeHead *next; /* Next free chunk / 1st head: first free. */
109 struct MCodeHead *prev; /* Prev free chunk / 1st head: next head. */
110 size_t size; /* Size of free chunk / Size of heap. */
111 size_t dummy; /* May or may not overlap with trailer. */
112} MCodeHead;
113
114/* Allocation granularity. Assumes sizeof(void *) >= sizeof(size_t). */
115#define MCH_GRANULARITY (4*sizeof(void *))
116#define MCH_ROUNDSIZE(x) (((x) + MCH_GRANULARITY-1) & -MCH_GRANULARITY)
117#define MCH_ROUNDHEAP(x) (((x) + 4095) & -4096)
118#define MCH_HEADERSIZE MCH_ROUNDSIZE(sizeof(MCodeHead))
119
120/* Trailer flags. */
121#define MCH_USED 1 /* Next chunk is in use. */
122#define MCH_LAST 2 /* Next chunk is the last one. */
123#define MCH_FIRST 4 /* Next chunk is the first one. */
124/* Note: the last chunk of each heap doesn't have a trailer. */
125
126/* Trailer macros. */
127#define MCH_PREVTRAILER(mh) ((size_t *)(mh) - 1)
128#define MCH_TRAILER(mh, sz) ((size_t *)((char *)(mh) + (sz)) - 1)
129#define MCH_TRFLAGS(tr) ((tr) & (MCH_USED|MCH_LAST))
130#define MCH_TRSIZE(tr) ((tr) & ~(MCH_USED|MCH_LAST))
131
132/* Debugging memory allocators is ... oh well. */
133#ifdef MCH_DEBUG
134#include <stdio.h>
135#define MCH_DBGF stderr
136#define MCH_DBG(x) fprintf x
137#else
138#define MCH_DBG(x) ((void)0)
139#endif
140
141/* Free the whole list of mcode heaps. */
142void luaJIT_freemcodeheap(jit_State *J)
143{
144 MCodeHead *mh = (MCodeHead *)J->mcodeheap;
145 while (mh) {
146 MCodeHead *prev = mh->prev; /* Heaps are in the prev chain. */
147#ifdef MCH_DEBUG
148 munmap((void *)mh, mh->size+4096);
149#else
150 munmap((void *)mh, mh->size);
151#endif
152 mh = prev;
153 }
154 J->mcodeheap = NULL;
155}
156
157/* Allocate a new heap of at least the given size. */
158static void mcode_newheap(jit_State *J, size_t sz)
159{
160 MCodeHead *mh, *mhn, *fh;
161 void *ptr;
162
163 /* Ensure minimum size or round up. */
164 if (sz + MCH_HEADERSIZE <= LUAJIT_MCH_CHUNKSIZE)
165 sz = LUAJIT_MCH_CHUNKSIZE;
166 else
167 sz = MCH_ROUNDHEAP(sz + MCH_HEADERSIZE);
168
169#ifdef MCH_DEBUG
170 /* Allocate a new heap plus a guard page. */
171 ptr = mmap(NULL, sz+4096, PROT_READ|PROT_WRITE|PROT_EXEC, MCH_MMFLAGS, -1, 0);
172 if (ptr == MAP_FAILED) luaD_throw(J->L, LUA_ERRMEM);
173 mprotect((char *)ptr+sz, 4096, PROT_NONE);
174#else
175 /* Allocate a new heap. */
176 ptr = mmap(NULL, sz, PROT_READ|PROT_WRITE|PROT_EXEC, MCH_MMFLAGS, -1, 0);
177 if (ptr == MAP_FAILED) luaD_throw(J->L, LUA_ERRMEM);
178#endif
179
180 /* Initialize free chunk. */
181 fh = (MCodeHead *)((char *)ptr + MCH_HEADERSIZE);
182 fh->size = sz - MCH_HEADERSIZE;
183 *MCH_PREVTRAILER(fh) = MCH_LAST | MCH_FIRST; /* Zero size, no coalesce. */
184
185 /* Initialize new heap and make it the first heap. */
186 mh = (MCodeHead *)J->mcodeheap;
187 J->mcodeheap = ptr;
188 mhn = (MCodeHead *)ptr;
189 mhn->prev = mh; /* Heaps are in the prev. chain. */
190 mhn->size = sz;
191 mhn->next = fh; /* Start of free list is always in the first heap. */
192 fh->prev = mhn;
193 if (mh) {
194 fh->next = mh->next; /* Old start of free list. */
195 mh->next = NULL; /* Just in case. */
196 } else {
197 fh->next = NULL; /* No other free chunks yet. */
198 }
199 MCH_DBG((MCH_DBGF, "HEAP %p %5x\n", mhn, sz));
200}
201
202/* Allocate a code block. */
203static void *mcode_alloc(jit_State *J, size_t sz)
204{
205 sz = MCH_ROUNDSIZE(sz + sizeof(size_t));
206 for ( ; ; ) {
207 MCodeHead *mh = (MCodeHead *)J->mcodeheap;
208 if (mh) { /* Got at least one heap so search free list. */
209#ifdef MCH_DEBUG
210 int slen = 0;
211 for (mh = mh->next; mh ; mh = mh->next, slen++)
212#else
213 for (mh = mh->next; mh ; mh = mh->next)
214#endif
215 if (mh->size >= sz) { /* Very naive first fit. */
216 size_t *trailer = MCH_TRAILER(mh, sz);
217 size_t *ptrailer = MCH_PREVTRAILER(mh);
218 if (mh->size == sz) { /* Exact match: just unchain chunk. */
219 mh->prev->next = mh->next;
220 if (mh->next)
221 mh->next->prev = mh->prev;
222 *ptrailer |= MCH_USED;
223 MCH_DBG((MCH_DBGF, "NEW %p %5x FIT #%d%s\n",
224 mh, sz, slen, (*ptrailer & MCH_LAST) ? " LAST" : ""));
225 } else { /* Chunk is larger: rechain remainder chunk. */
226 MCodeHead *fh = (MCodeHead *)((char *)mh + sz);
227 size_t tr;
228 fh->size = mh->size - sz;
229 (fh->prev = mh->prev)->next = fh;
230 if ((fh->next = mh->next) != NULL)
231 fh->next->prev = fh;
232 tr = *ptrailer;
233 if (tr & MCH_LAST) {
234 *ptrailer = (tr & ~MCH_LAST) | MCH_USED;
235 *trailer = sz | MCH_LAST;
236 MCH_DBG((MCH_DBGF, "NEW %p %5x REST %p %5x #%d LAST\n",
237 mh, sz, fh, fh->size, slen));
238 } else {
239 size_t *ftrailer = MCH_TRAILER(fh, fh->size);
240 *ftrailer = MCH_TRFLAGS(*ftrailer) | fh->size;
241 *ptrailer = tr | MCH_USED;
242 *trailer = sz;
243 MCH_DBG((MCH_DBGF, "NEW %p %5x REST %p %5x #%d\n",
244 mh, sz, fh, fh->size, slen));
245 }
246 }
247 return (void *)mh;
248 }
249 }
250 /* No luck. Allocate a new heap. Next loop iteration will succeed. */
251 mcode_newheap(J, sz);
252 }
253}
254
255/* Free a code block. */
256static void mcode_free_(jit_State *J, void *ptr, size_t sz)
257{
258 MCodeHead *mh = (MCodeHead *)ptr;
259 size_t *trailer = MCH_TRAILER(mh, sz);
260 size_t *ptrailer = MCH_PREVTRAILER(mh);
261 size_t tr = *ptrailer;
262
263#ifdef MCH_DEBUG
264 if (!(tr & MCH_USED)) MCH_DBG((MCH_DBGF, "**unused %p %5x\n", ptr, sz));
265#endif
266
267 if (!(tr & MCH_FIRST)) {
268 MCodeHead *ph = (MCodeHead *)((char *)mh - MCH_TRSIZE(tr));
269 size_t *pptrailer = MCH_PREVTRAILER(ph);
270 if (!(*pptrailer & MCH_USED)) { /* Prev free? */
271 if (!(tr & MCH_LAST) && !(*trailer & MCH_USED)) { /* Next free? */
272 /* Coalesce with previous and next chunk. */
273 MCodeHead *nh = (MCodeHead *)((char *)mh + sz);
274 MCH_DBG((MCH_DBGF, "free %p %5x PN %p %5x %p %5x%s\n",
275 mh, sz, ph, ph->size, nh, nh->size,
276 (*trailer & MCH_LAST) ? " last" : ""));
277 if ((nh->prev->next = nh->next) != NULL)
278 nh->next->prev = nh->prev;
279 ph->size += sz + nh->size;
280 if (*trailer & MCH_LAST) {
281 *pptrailer |= MCH_LAST;
282 } else {
283 trailer = MCH_TRAILER(nh, nh->size);
284 *trailer = MCH_TRFLAGS(*trailer) | ph->size;
285 }
286 return;
287 }
288 MCH_DBG((MCH_DBGF, "free %p %5x P- %p %5x%s\n",
289 mh, sz, ph, ph->size,
290 (tr & MCH_LAST) ? " last" : ""));
291 ph->size += sz;
292 if (tr & MCH_LAST)
293 *pptrailer |= MCH_LAST;
294 else
295 *trailer = MCH_TRFLAGS(*trailer) | ph->size;
296 return;
297 }
298 }
299
300 if (!(tr & MCH_LAST) && !(*trailer & MCH_USED)) { /* Next free? */
301 /* Coalesce with next chunk. */
302 MCodeHead *nh = (MCodeHead *)((char *)mh + sz);
303 MCH_DBG((MCH_DBGF, "free %p %5x -N %p %5x%s\n",
304 mh, sz, nh, nh->size, (*trailer & MCH_LAST) ? " last" : ""));
305 (mh->prev = nh->prev)->next = mh;
306 if ((mh->next = nh->next))
307 mh->next->prev = mh;
308 mh->size = nh->size + sz;
309 if (*trailer & MCH_LAST) {
310 *ptrailer = (tr & ~MCH_USED) | MCH_LAST;
311 } else {
312 trailer = MCH_TRAILER(mh, mh->size);
313 *trailer = MCH_TRFLAGS(*trailer) | mh->size;
314 *ptrailer = tr & ~MCH_USED;
315 }
316 } else {
317 /* No coalesce possible, just add to free list. */
318 MCodeHead *fh = (MCodeHead *)J->mcodeheap;
319 MCH_DBG((MCH_DBGF, "free %p %5x --%s\n",
320 mh, sz, (tr & MCH_LAST) ? " last" : ""));
321 if ((mh->next = fh->next))
322 mh->next->prev = mh;
323 fh->next = mh;
324 mh->prev = fh;
325 mh->size = sz;
326 *ptrailer = tr & ~MCH_USED;
327 }
328}
329
330#define mcode_free(L, J, p, sz) \
331 mcode_free_(J, (p), MCH_ROUNDSIZE((sz) + sizeof(size_t)))
332
333/* ------------------------------------------------------------------------ */
334
335#else
336
337/*
338** Fallback to Lua's alloc, i.e. probably malloc().
339**
340** Note: the returned memory is usually not marked executable!
341** Running the code will crash if the CPU/OS checks for this.
342** E.g. on x86 CPUs that support the NX (No eXecute) bit.
343*/
344
345/* There's no heap to free, but the JSUB mcode is. */
346void luaJIT_freemcodeheap(jit_State *J)
347{
348 if (J->jsubmcode) luaM_freemem(J->L, J->jsubmcode, J->szjsubmcode);
349}
350
351#define mcode_alloc(J, sz) luaM_realloc_(J->L, NULL, 0, (sz))
352#define mcode_free(L, J, p, sz) luaM_freemem(L, p, sz)
353
354#endif
355
356/* ------------------------------------------------------------------------ */
357
358/* Free mcode. */
359void luaJIT_freemcode(jit_State *J, void *mcode, size_t sz)
360{
361 mcode_free(J->L, J, mcode, sz);
362}
363
364/* Free JIT structures in function prototype. */
365void luaJIT_freeproto(lua_State *L, Proto *pt)
366{
367 char *mcode = (char *)pt->jit_mcode;
368 size_t sz = pt->jit_szmcode;
369 pt->jit_mcode = NULL;
370 pt->jit_szmcode = 0;
371 while (sz != 0) { /* Free whole chain of mcode blocks for this proto. */
372 jit_MCTrailer next;
373 memcpy((void *)&next, JIT_MCTRAILER(mcode, sz), sizeof(jit_MCTrailer));
374 MCH_INVALIDATE(mcode, sz);
375 mcode_free(L, G(L)->jit_state, mcode, sz);
376 mcode = next.mcode;
377 sz = next.sz;
378 }
379}
380
381/* Link generated code. Return mcode address, size and status. */
382int luaJIT_link(jit_State *J, void **mcodep, size_t *szp)
383{
384 size_t sz;
385 void *mcode;
386
387 /* Pass 2: link sections. */
388 if ((J->dasmstatus = dasm_link(Dst, &sz))) return JIT_S_DASM_ERROR;
389
390 /* Check for hardcoded limit on mcode size. */
391 if (sz > LUAJIT_LIM_MCODE) return JIT_S_TOOLARGE;
392
393 /* TODO: mark mcode readonly when we're done. */
394 mcode = mcode_alloc(J, sz);
395
396 /* Pass 3: encode sections. */
397 if ((J->dasmstatus = dasm_encode(Dst, mcode)) != 0) {
398 mcode_free(J->L, J, mcode, sz);
399 return JIT_S_DASM_ERROR;
400 }
401 *mcodep = mcode;
402 *szp = sz;
403 return JIT_S_OK;
404}
405
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86.dasc b/libraries/LuaJIT-1.1.7/src/ljit_x86.dasc
new file mode 100644
index 0000000..f7be91e
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_x86.dasc
@@ -0,0 +1,2457 @@
1/*
2** Bytecode to machine code translation for x86 CPUs.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6|// Include common definitions and macros.
7|.include ljit_x86.dash
8|
9|// Place actionlist and globals here at the top of the file.
10|.actionlist jit_actionlist
11|.globals JSUB_
12
13/* ------------------------------------------------------------------------ */
14
15/* Arch string. */
16const char luaJIT_arch[] = "x86";
17
18/* Forward declarations for C functions called from jsubs. */
19static void jit_hookins(lua_State *L, const Instruction *newpc);
20static void jit_gettable_fb(lua_State *L, Table *t, StkId dest);
21static void jit_settable_fb(lua_State *L, Table *t, StkId val);
22
23/* ------------------------------------------------------------------------ */
24
25/* Detect CPU features and set JIT flags. */
26static int jit_cpudetect(jit_State *J)
27{
28 void *mcode;
29 size_t sz;
30 int status;
31 /* Some of the jsubs need the flags. So compile this separately. */
32 unsigned int feature;
33 dasm_setup(Dst, jit_actionlist);
34 | // Check for CPUID support first.
35 | pushfd
36 | pop edx
37 | mov ecx, edx
38 | xor edx, 0x00200000 // Toggle ID bit in flags.
39 | push edx
40 | popfd
41 | pushfd
42 | pop edx
43 | xor eax, eax // Zero means no features supported.
44 | cmp ecx, edx
45 | jz >1 // No ID toggle means no CPUID support.
46 |
47 | inc eax // CPUID function 1.
48 | push ebx // Callee-save ebx modified by CPUID.
49 | cpuid
50 | pop ebx
51 | mov eax, edx // Return feature support bits.
52 |1:
53 | ret
54 (void)dasm_checkstep(Dst, DASM_SECTION_CODE);
55 status = luaJIT_link(J, &mcode, &sz);
56 if (status != JIT_S_OK)
57 return status;
58 /* Check feature bits. See the Intel/AMD manuals for the bit definitions. */
59 feature = ((unsigned int (*)(void))mcode)();
60 if (feature & (1<<15)) J->flags |= JIT_F_CPU_CMOV;
61 if (feature & (1<<26)) J->flags |= JIT_F_CPU_SSE2;
62 luaJIT_freemcode(J, mcode, sz); /* We don't need this code anymore. */
63 return JIT_S_OK;
64}
65
66/* Check some assumptions. Should compile to nop. */
67static int jit_consistency_check(jit_State *J)
68{
69 do {
70 /* Force a compiler error for inconsistent structure sizes. */
71 /* Check LUA_TVALUE_ALIGN in luaconf.h, too. */
72 ||int check_TVALUE_SIZE_in_ljit_x86_dash[1+TVALUE_SIZE-sizeof(TValue)];
73 ||int check_TVALUE_SIZE_in_ljit_x86_dash_[1+sizeof(TValue)-TVALUE_SIZE];
74 ((void)check_TVALUE_SIZE_in_ljit_x86_dash[0]);
75 ((void)check_TVALUE_SIZE_in_ljit_x86_dash_[0]);
76 if (LUA_TNIL != 0 || LUA_TBOOLEAN != 1 || PCRLUA != 0) break;
77 if ((int)&(((Node *)0)->i_val) != (int)&(((StkId)0)->value)) break;
78 return JIT_S_OK;
79 } while (0);
80 J->dasmstatus = 999999999; /* Recognizable error. */
81 return JIT_S_COMPILER_ERROR;
82}
83
84/* Compile JIT subroutines (once). */
85static int jit_compile_jsub(jit_State *J)
86{
87 int status = jit_consistency_check(J);
88 if (status != JIT_S_OK) return status;
89 status = jit_cpudetect(J);
90 if (status != JIT_S_OK) return status;
91 dasm_setup(Dst, jit_actionlist);
92 |// Macros to reorder and combine JIT subroutine definitions.
93 |.macro .jsub, name
94 |.capture JSUB // Add the entry point.
95 ||//-----------------------------------------------------------------------
96 ||//->name:
97 | .align 16
98 |->name:
99 |.endmacro
100 |.macro .endjsub; .endcapture; .endmacro
101 |.macro .dumpjsub; .dumpcapture JSUB; .endmacro
102 |
103 |.code
104 |//-----------------------------------------------------------------------
105 | .align 16
106 | // Must be the first JSUB defined or used.
107 |->STACKPTR: // Get stack pointer (for jit.util.*).
108 | lea eax, [esp+aword*1] // But adjust for the return address.
109 | ret
110 |
111 |//-----------------------------------------------------------------------
112 | .align 16
113 |->GATE_LJ: // Lua -> JIT gate. (L, func, nresults)
114 | push ebp
115 | mov ebp, esp
116 | sub esp, LJFRAME_OFFSET
117 | mov SAVER1, BASE
118 | mov BASE, CARG2 // func
119 | mov CARG2, L // Arg used as savereg. Avoids aword*8 stack frame.
120 | mov L, CARG1 // L
121 | mov SAVER2, TOP
122 | mov TOP, L->top
123 | mov LCL, BASE->value
124 | mov CI, L->ci
125 | // Prevent stackless yields. No limit check -- this is not a real C call.
126 | inc word L->nCcalls // short
127 |
128 | call aword LCL->jit_gate // Call the compiled code.
129 |
130 | mov CI, L->ci
131 | mov L->top, TOP // Only correct for LUA_MULTRET.
132 | mov edx, CI->savedpc
133 | mov eax, CARG3 // nresults
134 | mov L->savedpc, edx // L->savedpc = CI->savedpc
135 | mov edx, CI->base
136 | test eax, eax
137 | mov L->base, edx // L->base = CI->base
138 | js >2 // Skip for nresults == LUA_MULTRET.
139 |
140 | TValuemul eax
141 | add BASE, eax
142 | xor ecx, ecx
143 | mov L->top, BASE // L->top = &func[nresults]
144 |1: // No initial check. May use EXTRA_STACK (once).
145 | mov TOP->tt, ecx // Clear unset stack slots.
146 | add TOP, #TOP
147 | cmp TOP, BASE
148 | jb <1
149 |
150 |2:
151 | dec word L->nCcalls // short
152 | mov eax, PCRC
153 | mov TOP, SAVER2
154 | mov BASE, SAVER1
155 | mov L, CARG2
156 | mov esp, ebp
157 | pop ebp
158 | ret
159 |
160 |//-----------------------------------------------------------------------
161 | .align 16
162 |->GATE_JL: // JIT -> Lua callgate.
163 | mov PROTO:edx, LCL->p
164 | cmp dword PROTO:edx->jit_status, JIT_S_OK
165 | jne >1 // Already compiled?
166 |
167 | // Yes, copy callgate to closure (so GATE_JL is not called again).
168 | mov edx, PROTO:edx->jit_mcode
169 | mov LCL->jit_gate, edx
170 | jmp edx // Chain to compiled code.
171 |
172 |1: // Let luaD_precall do the hard work: compile & run or fallback.
173 | sub esp, FRAME_OFFSET
174 | mov eax, CI->savedpc
175 | mov L->ci, CI // May not be in sync for tailcalls.
176 | mov L->top, TOP
177 | mov ARG3, -1 // LUA_MULTRET
178 | mov L->savedpc, eax // luaD_precall expects it there.
179 | mov ARG2, BASE
180 | sub BASE, L->stack // Preserve old BASE (= func).
181 | mov ARG1, L
182 | call &luaD_precall // luaD_precall(L, func, nresults)
183 | test eax,eax // Assumes: PCRLUA == 0
184 | jnz >2 // PCRC? PCRYIELD cannot happen.
185 |
186 | // Returned PCRLUA: need to call the bytecode interpreter.
187 | call &luaV_execute, L, 1
188 | // Indirect yield (L->status == LUA_YIELD) cannot happen.
189 |
190 |2: // Returned PCRC: compile & run done. Frame is already unwound.
191 | add esp, FRAME_OFFSET
192 | add BASE, L->stack // Restore stack-relative pointers BASE and TOP.
193 | mov TOP, L->top
194 | ret
195 |
196 |//-----------------------------------------------------------------------
197 | .align 16
198 |->GATE_JC: // JIT -> C callgate.
199 | lea eax, TOP[LUA_MINSTACK]
200 | sub esp, FRAME_OFFSET
201 | cmp eax, L->stack_last
202 | jae ->GROW_STACK // Stack overflow?
203 | cmp CI, L->end_ci
204 | lea CI, CI[1]
205 | je ->GROW_CI // CI overflow?
206 | mov L->ci, CI
207 | mov CI->func, BASE
208 | mov CI->top, eax
209 | mov CCLOSURE:edx, BASE->value
210 | add BASE, #BASE
211 | mov L->top, TOP
212 | mov L->base, BASE
213 | mov CI->base, BASE
214 | // ci->nresults is not set because we don't use luaD_poscall().
215 |
216 |->GATE_JC_PATCH: // Patch mark for jmp to GATE_JC_DEBUG.
217 |
218 | call aword CCLOSURE:edx->f, L // Call the C function.
219 |
220 |2: // Label used below!
221 | add esp, FRAME_OFFSET
222 | mov CI, L->ci
223 | TValuemul eax // eax = nresults*sizeof(TValue)
224 | mov TOP, CI->func
225 | jz >4 // Skip loop if nresults == 0.
226 | // Yield (-1) cannot happen.
227 | mov BASE, L->top
228 | mov edx, BASE
229 | sub BASE, eax // BASE = &L->top[-nresults]
230 |3: // Relocate [L->top-nresults, L->top) -> [ci->func, ci->func+nresults)
231 | mov eax, [BASE]
232 | add BASE, aword*1
233 | mov [TOP], eax
234 | add TOP, aword*1
235 | cmp BASE, edx
236 | jb <3
237 |
238 |4:
239 | mov BASE, CI->func
240 | sub CI, #CI
241 | mov L->ci, CI
242 | ret
243 |
244 |//-----------------------------------------------------------------------
245 | nop; nop; nop; nop; nop; nop // Save area. See DEBUGPATCH_SIZE.
246 | .align 16
247 |->GATE_JC_DEBUG: // JIT -> C callgate for debugging.
248 | test byte L->hookmask, LUA_MASKCALL // Need to call hook?
249 | jnz >7
250 |6:
251 | call aword CCLOSURE:edx->f, L // Call the C function.
252 |
253 | test byte L->hookmask, LUA_MASKRET // Need to call hook?
254 | jz <2
255 |
256 | // Return hook. TODO: LUA_HOOKTAILRET is not called since tailcalls == 0.
257 | mov BASE, eax // BASE (ebx) is callee-save.
258 | call &luaD_callhook, L, LUA_HOOKRET, -1
259 | mov eax, BASE
260 | jmp <2
261 |
262 |7: // Call hook.
263 | mov BASE, CCLOSURE:edx // BASE (ebx) is callee-save.
264 | call &luaD_callhook, L, LUA_HOOKCALL, -1
265 | mov CCLOSURE:edx, BASE
266 | jmp <6
267 |
268 |//-----------------------------------------------------------------------
269 | .align 16
270 |->GROW_STACK: // Grow stack. Jump from/to prologue.
271 | sub eax, TOP
272 | TValuediv eax // eax = (eax-TOP)/sizeof(TValue).
273 | mov L->top, TOP
274 | sub BASE, L->stack
275 | mov ARG3, CI
276 | call &luaD_growstack, L, eax
277 | mov CI, ARG3 // CI may not be in sync with L->ci.
278 | add BASE, L->stack // Restore stack-relative pointers.
279 | mov TOP, L->top
280 | mov LCL, BASE->value
281 | add esp, FRAME_OFFSET // Undo esp adjust of prologue/GATE_JC.
282 | jmp aword LCL->jit_gate // Retry prologue.
283 |
284 |//-----------------------------------------------------------------------
285 | .align 16
286 |->GROW_CI: // Grow CI. Jump from/to prologue.
287 | mov L->top, TOP // May throw LUA_ERRMEM, so save TOP.
288 | call &luaD_growCI, L
289 | lea CI, CINFO:eax[-1] // Undo ci++ (L->ci reset in prologue).
290 | mov LCL, BASE->value
291 | mov L->ci, CI
292 | add esp, FRAME_OFFSET // Undo esp adjust of prologue/GATE_JC.
293 | jmp aword LCL->jit_gate // Retry prologue.
294 |
295 |//-----------------------------------------------------------------------
296 |.dumpjsub // Dump all captured .jsub's.
297 |
298 |// Uncritical jsubs follow. No need to align them.
299 |//-----------------------------------------------------------------------
300 |->DEOPTIMIZE_CALLER: // Deoptimize calling instruction.
301 | pop edx
302 | jmp ->DEOPTIMIZE
303 |
304 |->DEOPTIMIZE_OPEN: // Deoptimize open instruction.
305 | mov L->top, TOP // Save TOP.
306 |
307 |->DEOPTIMIZE: // Deoptimize instruction.
308 | mov L->savedpc, edx // &J->nextins expected in edx.
309 | call &luaJIT_deoptimize, L
310 | mov BASE, L->base
311 | mov TOP, L->top // Restore TOP for open ins.
312 | jmp eax // Continue with new mcode addr.
313 |
314 | .align 16
315 |//-----------------------------------------------------------------------
316
317 (void)dasm_checkstep(Dst, DASM_SECTION_CODE);
318 status = luaJIT_link(J, &J->jsubmcode, &J->szjsubmcode);
319 if (status != JIT_S_OK)
320 return status;
321
322 /* Copy the callgates from the globals to the global state. */
323 G(J->L)->jit_gateLJ = (luaJIT_GateLJ)J->jsub[JSUB_GATE_LJ];
324 G(J->L)->jit_gateJL = (lua_CFunction)J->jsub[JSUB_GATE_JL];
325 G(J->L)->jit_gateJC = (lua_CFunction)J->jsub[JSUB_GATE_JC];
326 return JIT_S_OK;
327}
328
329/* Match with number of nops above. Avoid confusing the instruction decoder. */
330#define DEBUGPATCH_SIZE 6
331
332/* Notify backend that the debug mode may have changed. */
333void luaJIT_debugnotify(jit_State *J)
334{
335 unsigned char *patch = (unsigned char *)J->jsub[JSUB_GATE_JC_PATCH];
336 unsigned char *target = (unsigned char *)J->jsub[JSUB_GATE_JC_DEBUG];
337 /* Yep, this is self-modifying code -- don't tell anyone. */
338 if (patch[0] == 0xe9) { /* Debug patch is active. */
339 if (!(J->flags & JIT_F_DEBUG_CALL)) /* Deactivate it. */
340 memcpy(patch, target-DEBUGPATCH_SIZE, DEBUGPATCH_SIZE);
341 } else { /* Debug patch is inactive. */
342 if (J->flags & JIT_F_DEBUG_CALL) { /* Activate it. */
343 int rel = target-(patch+5);
344 memcpy(target-DEBUGPATCH_SIZE, patch, DEBUGPATCH_SIZE);
345 patch[0] = 0xe9; /* jmp */
346 memcpy(patch+1, &rel, 4); /* Relative address. */
347 memset(patch+5, 0x90, DEBUGPATCH_SIZE-5); /* nop */
348 }
349 }
350}
351
352/* Patch a jmp into existing mcode. */
353static void jit_patch_jmp(jit_State *J, void *mcode, void *to)
354{
355 unsigned char *patch = (unsigned char *)mcode;
356 int rel = ((unsigned char *)to)-(patch+5);
357 patch[0] = 0xe9; /* jmp */
358 memcpy((void *)(patch+1), &rel, 4); /* Relative addr. */
359}
360
361/* ------------------------------------------------------------------------ */
362
363/* Call line/count hook. */
364static void jit_hookins(lua_State *L, const Instruction *newpc)
365{
366 Proto *pt = ci_func(L->ci)->l.p;
367 int pc = luaJIT_findpc(pt, newpc); /* Sloooow with mcode addrs. */
368 const Instruction *savedpc = L->savedpc;
369 L->savedpc = pt->code + pc + 1;
370 if (L->hookmask > LUA_MASKLINE && L->hookcount == 0) {
371 resethookcount(L);
372 luaD_callhook(L, LUA_HOOKCOUNT, -1);
373 }
374 if (L->hookmask & LUA_MASKLINE) {
375 int newline = getline(pt, pc);
376 if (pc != 0) {
377 int oldpc = luaJIT_findpc(pt, savedpc);
378 if (!(pc <= oldpc || newline != getline(pt, oldpc))) return;
379 }
380 luaD_callhook(L, LUA_HOOKLINE, newline);
381 }
382}
383
384/* Insert hook check for each instruction in full debug mode. */
385static void jit_ins_debug(jit_State *J, int openop)
386{
387 if (openop) {
388 | mov L->top, TOP
389 }
390 |// TODO: Passing bytecode addrs would speed this up (but use more space).
391 | call ->HOOKINS
392
393 |.jsub HOOKINS
394 | test byte L->hookmask, LUA_MASKLINE|LUA_MASKCOUNT
395 | jz >2
396 | dec dword L->hookcount
397 | jz >1
398 | test byte L->hookmask, LUA_MASKLINE
399 | jz >2
400 |1:
401 | mov eax, [esp] // Current machine code address.
402 | sub esp, FRAME_OFFSET
403 | call &jit_hookins, L, eax
404 | add esp, FRAME_OFFSET
405 | mov BASE, L->base // Restore stack-relative pointers.
406 | mov TOP, L->top
407 |2:
408 | ret
409 |.endjsub
410}
411
412/* Called before every instruction. */
413static void jit_ins_start(jit_State *J)
414{
415 |// Always emit PC labels, even for dead code (but not for combined JMP).
416 |=>J->nextpc:
417}
418
419/* Chain to another instruction. */
420static void jit_ins_chainto(jit_State *J, int pc)
421{
422 | jmp =>pc
423}
424
425/* Set PC label. */
426static void jit_ins_setpc(jit_State *J, int pc, void *target)
427{
428 |.label =>pc, &target
429}
430
431/* Called after the last instruction has been encoded. */
432static void jit_ins_last(jit_State *J, int lastpc, int sizemfm)
433{
434 if (J->tflags & JIT_TF_USED_DEOPT) { /* Deopt section has been used? */
435 |.deopt
436 | jmp ->DEOPTIMIZE // Yes, need to add final jmp.
437 |.code
438 }
439 |=>lastpc+1: // Extra label at the end of .code.
440 |.tail
441 |=>lastpc+2: // And at the end of .deopt/.tail.
442 | .align word // Keep next section word aligned.
443 | .word 0xffff // Terminate mfm with JIT_MFM_STOP.
444 |.mfmap
445 | // <-- Deoptimization hints are inserted here.
446 | .space sizemfm // To be filled in with inverse mfm.
447 | .aword 0, 0 // Next mcode block pointer and size.
448 | // The previous two awords are only word, but not aword aligned.
449 | // Copying them is easier than aligning them and adjusting mfm handling.
450 |.code
451}
452
453/* Add a deoptimize target for the current instruction. */
454static void jit_deopt_target(jit_State *J, int nargs)
455{
456 |.define L_DEOPTLABEL, 9 // Local deopt label.
457 |.define L_DEOPTIMIZE, <9 // Local deopt target. Use after call.
458 |.define L_DEOPTIMIZEF, >9 // Local deopt target. Use before call.
459 if (nargs != -1) {
460 |// Alas, x86 doesn't have conditional calls. So branch to the .deopt
461 |// section to load J->nextins and jump to JSUB_DEOPTIMIZE.
462 |// Only a single jump is added at the end (if needed) and any
463 |// intervening code sequences are shadowed (lea trick).
464 |.deopt // Occupies 6 bytes in .deopt section.
465 | .byte 0x8d // Shadow mov with lea edi, [edx+ofs].
466 |L_DEOPTLABEL:
467 | mov edx, &J->nextins // Current instruction + 1.
468 |.code
469 J->tflags |= JIT_TF_USED_DEOPT;
470 } else {
471 |.tail // Occupies 10 bytes in .tail section.
472 |L_DEOPTLABEL:
473 | mov edx, &J->nextins
474 | jmp ->DEOPTIMIZE_OPEN // Open ins need to save TOP, too.
475 | // And TOP (edi) would be overwritten by the lea trick.
476 | // So checking for open ops later on wouldn't suffice. Sigh.
477 |.code
478 }
479}
480
481/* luaC_checkGC() inlined. Destroys caller-saves + TOP (edi). Uses label 7:. */
482/* Use this only at the _end_ of an instruction. */
483static void jit_checkGC(jit_State *J)
484{
485 | mov GL:ecx, L->l_G
486 | mov eax, GL:ecx->totalbytes // size_t
487 | mov TOP, >7
488 | cmp eax, GL:ecx->GCthreshold // size_t
489 | jae ->GCSTEP
490 |7:
491
492 |.jsub GCSTEP
493 | call &luaC_step, L
494 | mov BASE, L->base
495 | jmp TOP
496 |.endjsub
497}
498
499/* ------------------------------------------------------------------------ */
500
501|// JIT->JIT calling conventions:
502|//
503|// Register/Type | Call Setup | Prologue | Epilogue | Call Finish
504|// ===========================================================================
505|// eax | LCL | = BASE->value| | * | *
506|// ecx | CI | = L->ci | L->ci = ++CI | * | *
507|// edx | * | * | * | * | *
508|// ---------------------------------------------------------------------------
509|// esi | L | | | |
510|// ebx | BASE | += f | ++ | -- | -= f
511|// edi | TOP | += f+1+nargs | = BASE+maxst | = f+nresults | = BASE+maxst
512|// ---------------------------------------------------------------------------
513|// L->base | | = BASE | | = BASE
514|// L->top | | = TOP | | = TOP
515|// L->ci | | ++, -> = ... | -- |
516|// L->ci->savedpc| = &code[pc] | [ L-> = ] | |
517|// ---------------------------------------------------------------------------
518|// args + vars | | setnil | |
519|// results | | | move | setnil
520|// ---------------------------------------------------------------------------
521
522
523|// Include support for function inlining.
524|.include ljit_x86_inline.dash
525
526
527#ifdef LUA_COMPAT_VARARG
528static void jit_vararg_table(lua_State *L)
529{
530 Table *tab;
531 StkId base, func;
532 int i, num, numparams;
533 luaC_checkGC(L);
534 base = L->base;
535 func = L->ci->func;
536 numparams = clvalue(func)->l.p->numparams;
537 num = base - func - numparams - 1;
538 tab = luaH_new(L, num, 1);
539 for (i = 0; i < num; i++)
540 setobj2n(L, luaH_setnum(L, tab, i+1), base - num + i);
541 setnvalue(luaH_setstr(L, tab, luaS_newliteral(L, "n")), (lua_Number)num);
542 sethvalue(L, base + numparams, tab);
543}
544#endif
545
546/* Encode JIT function prologue. */
547static void jit_prologue(jit_State *J)
548{
549 Proto *pt = J->pt;
550 int numparams = pt->numparams;
551 int stacksize = pt->maxstacksize;
552
553 |// Note: the order of the following instructions has been carefully tuned.
554 | lea eax, TOP[stacksize]
555 | sub esp, FRAME_OFFSET
556 | cmp eax, L->stack_last
557 | jae ->GROW_STACK // Stack overflow?
558 | // This is a slight overallocation (BASE[1+stacksize] would be enough).
559 | // We duplicate luaD_precall() behaviour so we can use luaD_growstack().
560 | cmp CI, L->end_ci
561 | lea CI, CI[1]
562 | je ->GROW_CI // CI overflow?
563 | xor eax, eax // Assumes: LUA_TNIL == 0
564 | mov CI->func, BASE
565 | add BASE, #BASE
566 | mov L->ci, CI
567
568 if (numparams > 0) {
569 | lea edx, BASE[numparams]
570 | cmp TOP, edx // L->top >< L->base+numparams ?
571 }
572
573 if (!pt->is_vararg) { /* Fixarg function. */
574 /* Must cap L->top at L->base+numparams because 1st LOADNIL is omitted. */
575 if (numparams == 0) {
576 | mov TOP, BASE
577 } else if (J->flags & JIT_F_CPU_CMOV) {
578 | cmova TOP, edx
579 } else {
580 | jna >1
581 | mov TOP, edx
582 |1:
583 }
584 | lea edx, BASE[stacksize] // New ci->top.
585 | mov CI->tailcalls, eax // 0
586 | mov CI->top, edx
587 | mov L->top, edx
588 | mov L->base, BASE
589 | mov CI->base, BASE
590 } else { /* Vararg function. */
591 int i;
592 if (numparams > 0) {
593 |// If some fixargs are missing we need to clear them and
594 |// bump TOP to get a consistent frame layout for OP_VARARG.
595 | jb >5
596 |4:
597 |.tail
598 |5: // This is uncommon. So move it to .tail and use a loop.
599 | mov TOP->tt, eax
600 | add TOP, #TOP
601 | cmp TOP, edx
602 | jb <5
603 | jmp <4
604 |.code
605 }
606 | mov L->base, TOP // New base is after last arg.
607 | mov CI->base, TOP
608 | mov CI->tailcalls, eax // 0
609 for (i = 0; i < numparams; i++) { /* Move/clear fixargs. */
610 |// Inline this. Vararg funcs usually have very few fixargs.
611 | copyslot TOP[i], BASE[i], ecx, edx
612 | mov BASE[i].tt, eax // Clear old fixarg slot (help the GC).
613 }
614 if (numparams > 0) {
615 | mov CI, L->ci // Reload CI = ecx (used by move).
616 }
617 | mov BASE, TOP
618 | lea edx, BASE[stacksize] // New ci->top.
619 | lea TOP, BASE[numparams] // Start of vars to clear.
620 | mov CI->top, edx
621 | mov L->top, edx
622 stacksize -= numparams; /* Fixargs are already cleared. */
623 }
624
625 /* Clear undefined args and all vars. Still assumes eax = LUA_TNIL = 0. */
626 /* Note: cannot clear only args because L->top has grown. */
627 if (stacksize <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */
628 int i;
629 for (i = 0; i < stacksize; i++) {
630 | mov TOP[i].tt, eax
631 }
632 } else { /* Standard loop. */
633 |2: // Unrolled for 2 stack slots. No initial check. May use EXTRA_STACK.
634 | mov TOP[0].tt, eax
635 | mov TOP[1].tt, eax
636 | add TOP, 2*#TOP
637 | cmp TOP, edx
638 | jb <2
639 |// Note: TOP is undefined now. TOP is only valid across calls/open ins.
640 }
641
642#ifdef LUA_COMPAT_VARARG
643 if (pt->is_vararg & VARARG_NEEDSARG) {
644 | call &jit_vararg_table, L
645 }
646#endif
647
648 /* Call hook check. */
649 if (J->flags & JIT_F_DEBUG_CALL) {
650 | test byte L->hookmask, LUA_MASKCALL
651 | jz >9
652 | call ->HOOKCALL
653 |9:
654
655 |.jsub HOOKCALL
656 | mov CI, L->ci
657 | mov TOP, CI->func
658 | mov LCL, TOP->value
659 | mov PROTO:edi, LCL->p // clvalue(L->ci->func)->l.p
660 | mov eax, PROTO:edi->code
661 | add eax, 4 // Hooks expect incremented PC.
662 | mov L->savedpc, eax
663 | sub esp, FRAME_OFFSET
664 | call &luaD_callhook, L, LUA_HOOKCALL, -1
665 | add esp, FRAME_OFFSET
666 | mov eax, PROTO:edi->code // PROTO:edi is callee-save.
667 | mov L->savedpc, eax // jit_hookins needs previous PC.
668 | mov BASE, L->base
669 | ret
670 |.endjsub
671 }
672}
673
674/* Check if we can combine 'return const'. */
675static int jit_return_k(jit_State *J)
676{
677 if (!J->combine) return 0; /* COMBINE hint set? */
678 /* May need to close open upvalues. */
679 if (!fhint_isset(J, NOCLOSE)) {
680 | call &luaF_close, L, BASE
681 }
682 if (!J->pt->is_vararg) { /* Fixarg function. */
683 | sub aword L->ci, #CI
684 | mov TOP, BASE
685 | sub BASE, #BASE
686 | add esp, FRAME_OFFSET
687 } else { /* Vararg function. */
688 | mov CI, L->ci
689 | mov BASE, CI->func
690 | sub CI, #CI
691 | mov L->ci, CI
692 | lea TOP, BASE[1]
693 | add esp, FRAME_OFFSET
694 }
695 jit_assert(J->combine == 1); /* Required to skip next RETURN instruction. */
696 return 1;
697}
698
699static void jit_op_return(jit_State *J, int rbase, int nresults)
700{
701 /* Return hook check. */
702 if (J->flags & JIT_F_DEBUG_CALL) {
703 if (nresults < 0 && !(J->flags & JIT_F_DEBUG_INS)) {
704 | mov L->top, TOP
705 }
706 |// TODO: LUA_HOOKTAILRET (+ ci->tailcalls counting) or changed debug API.
707 | test byte L->hookmask, LUA_MASKRET
708 | jz >7
709 | call ->HOOKRET
710 |7:
711 if (J->flags & JIT_F_DEBUG_INS) {
712 | mov eax, FRAME_RETADDR
713 | mov L->savedpc, eax
714 }
715
716 |.jsub HOOKRET
717 | mov eax, [esp] // Current machine code address.
718 | mov L->savedpc, eax
719 | sub esp, FRAME_OFFSET
720 | call &luaD_callhook, L, LUA_HOOKRET, -1
721 | add esp, FRAME_OFFSET
722 | mov BASE, L->base // Restore stack-relative pointers.
723 | mov TOP, L->top
724 | ret
725 |.endjsub
726 }
727
728 /* May need to close open upvalues. */
729 if (!fhint_isset(J, NOCLOSE)) {
730 | call &luaF_close, L, BASE
731 }
732
733 /* Previous op was open: 'return f()' or 'return ...' */
734 if (nresults < 0) {
735 |// Relocate [BASE+rbase, TOP) -> [ci->func, *).
736 | mov CI, L->ci
737 | addidx BASE, rbase
738 | mov edx, CI->func
739 | cmp BASE, TOP
740 | jnb >2
741 |1:
742 | mov eax, [BASE]
743 | add BASE, aword*1
744 | mov [edx], eax
745 | add edx, aword*1
746 | cmp BASE, TOP
747 | jb <1
748 |2:
749 | add esp, FRAME_OFFSET
750 | mov BASE, CI->func
751 | sub CI, #CI
752 | mov TOP, edx // Relocated TOP.
753 | mov L->ci, CI
754 | ret
755 return;
756 }
757
758 if (!J->pt->is_vararg) { /* Fixarg function, nresults >= 0. */
759 int i;
760 | sub aword L->ci, #CI
761 |// Relocate [BASE+rbase,BASE+rbase+nresults) -> [BASE-1, *).
762 |// TODO: loop for large nresults?
763 | sub BASE, #BASE
764 for (i = 0; i < nresults; i++) {
765 | copyslot BASE[i], BASE[rbase+i+1]
766 }
767 | add esp, FRAME_OFFSET
768 | lea TOP, BASE[nresults]
769 | ret
770 } else { /* Vararg function, nresults >= 0. */
771 int i;
772 |// Relocate [BASE+rbase,BASE+rbase+nresults) -> [ci->func, *).
773 | mov CI, L->ci
774 | mov TOP, CI->func
775 | sub CI, #CI
776 | mov L->ci, CI // CI = ecx is used by copyslot.
777 for (i = 0; i < nresults; i++) {
778 | copyslot TOP[i], BASE[rbase+i]
779 }
780 | add esp, FRAME_OFFSET
781 | mov BASE, TOP
782 | addidx TOP, nresults
783 | ret
784 }
785}
786
787static void jit_op_call(jit_State *J, int func, int nargs, int nresults)
788{
789 int cltype = jit_inline_call(J, func, nargs, nresults);
790 if (cltype < 0) return; /* Inlined? */
791
792 |// Note: the order of the following instructions has been carefully tuned.
793 | addidx BASE, func
794 | mov CI, L->ci
795 | isfunction 0 // BASE[0] is L->base[func].
796 if (nargs >= 0) { /* Previous op was not open and did not set TOP. */
797 | lea TOP, BASE[1+nargs]
798 }
799 | mov LCL, BASE->value
800 | mov edx, &J->nextins
801 | mov CI->savedpc, edx
802 if (cltype == LUA_TFUNCTION) {
803 if (nargs == -1) {
804 | jne ->DEOPTIMIZE_OPEN // TYPE hint was wrong (open op)?
805 } else {
806 | jne ->DEOPTIMIZE // TYPE hint was wrong?
807 }
808 } else {
809 | je >1 // Skip __call handling for functions.
810 | call ->METACALL
811 |1:
812
813 |.jsub METACALL // CALL to __call metamethod.
814 | sub esp, FRAME_OFFSET
815 | mov L->savedpc, edx // May throw errors. Save PC and TOP.
816 | mov L->top, TOP
817 | call &luaD_tryfuncTM, L, BASE // Resolve __call metamethod.
818 | add esp, FRAME_OFFSET
819 | mov BASE, eax // Restore stack-relative pointers.
820 | mov TOP, L->top
821 | mov LCL, BASE->value
822 | mov CI, L->ci
823 | ret
824 |.endjsub
825 }
826 | call aword LCL->jit_gate // Call JIT func or GATE_JL/GATE_JC.
827 | subidx BASE, func
828 | mov L->base, BASE
829
830 /* Clear undefined results TOP <= o < func+nresults. */
831 if (nresults > 0) {
832 | xor eax, eax
833 if (nresults <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */
834 int i;
835 for (i = 0; i < nresults; i++) {
836 | mov TOP[i].tt, eax
837 }
838 } else { /* Standard loop. TODO: move to .tail? */
839 | lea edx, BASE[func+nresults]
840 |1: // Unrolled for 2 stack slots. No initial check. May use EXTRA_STACK.
841 | mov TOP[0].tt, eax // LUA_TNIL
842 | mov TOP[1].tt, eax // LUA_TNIL
843 | add TOP, 2*#TOP
844 | cmp TOP, edx
845 | jb <1
846 }
847 }
848
849 if (nresults >= 0) { /* Not an open ins. Restore L->top. */
850 | lea TOP, BASE[J->pt->maxstacksize] // Faster than getting L->ci->top.
851 | mov L->top, TOP
852 } /* Otherwise keep TOP for next instruction. */
853}
854
855static void jit_op_tailcall(jit_State *J, int func, int nargs)
856{
857 int cltype;
858
859 if (!fhint_isset(J, NOCLOSE)) { /* May need to close open upvalues. */
860 | call &luaF_close, L, BASE
861 }
862
863 cltype = jit_inline_call(J, func, nargs, -2);
864 if (cltype < 0) goto finish; /* Inlined? */
865
866 if (cltype == LUA_TFUNCTION) {
867 jit_deopt_target(J, nargs);
868 | isfunction func
869 | jne L_DEOPTIMIZE // TYPE hint was wrong?
870 } else {
871 | isfunction func; jne >5 // Handle generic callables first.
872 |.tail
873 |5: // Fallback for generic callables.
874 | addidx BASE, func
875 if (nargs >= 0) {
876 | lea TOP, BASE[1+nargs]
877 }
878 | mov edx, &J->nextins
879 | jmp ->METATAILCALL
880 |.code
881
882 |.jsub METATAILCALL // TAILCALL to __call metamethod.
883 | mov L->savedpc, edx
884 | mov L->top, TOP
885 | call &luaD_tryfuncTM, L, BASE // Resolve __call metamethod.
886 |
887 |// Relocate [eax, L->top) -> [L->ci->func, *).
888 | mov CI, L->ci
889 | mov edx, L->top
890 | mov TOP, CI->func
891 |1:
892 | mov BASE, [eax]
893 | add eax, aword*1
894 | mov [TOP], BASE
895 | add TOP, aword*1
896 | cmp eax, edx
897 | jb <1
898 |
899 | mov BASE, CI->func
900 | mov LCL, BASE->value
901 | sub CI, #CI
902 | add esp, FRAME_OFFSET
903 | jmp aword LCL->jit_gate // Chain to callgate.
904 |.endjsub
905 }
906
907 if (nargs >= 0) { /* Previous op was not open and did not set TOP. */
908 int i;
909 /* Relocate [BASE+func, BASE+func+nargs] -> [ci->func, ci->func+nargs]. */
910 /* TODO: loop for large nargs? */
911 if (!J->pt->is_vararg) { /* Fixarg function. */
912 | mov LCL, BASE[func].value
913 for (i = 0; i < nargs; i++) {
914 | copyslot BASE[i], BASE[func+1+i], ecx, edx
915 }
916 | lea TOP, BASE[nargs]
917 | sub BASE, #BASE
918 | mov CI, L->ci
919 | mov BASE->value, LCL // Sufficient to copy func->value.
920 } else { /* Vararg function. */
921 | mov CI, L->ci
922 | lea TOP, BASE[func]
923 | mov BASE, CI->func
924 | mov LCL, TOP->value
925 | mov BASE->value, LCL // Sufficient to copy func->value.
926 for (i = 0; i < nargs; i++) {
927 | copyslot BASE[i+1], TOP[i+1], eax, edx
928 }
929 | lea TOP, BASE[1+nargs]
930 | mov LCL, BASE->value // Need to reload LCL = eax.
931 }
932 } else { /* Previous op was open and set TOP. */
933 |// Relocate [BASE+func, TOP) -> [ci->func, *).
934 | mov CI, L->ci
935 | addidx BASE, func
936 | mov edx, CI->func
937 |1:
938 | mov eax, [BASE]
939 | add BASE, aword*1
940 | mov [edx], eax
941 | add edx, aword*1
942 | cmp BASE, TOP
943 | jb <1
944 | mov BASE, CI->func
945 | mov TOP, edx // Relocated TOP.
946 | mov LCL, BASE->value
947 }
948 | sub CI, #CI
949 | add esp, FRAME_OFFSET
950 | jmp aword LCL->jit_gate // Chain to JIT function.
951
952finish:
953 J->combine++; /* Combine with following return instruction. */
954}
955
956/* ------------------------------------------------------------------------ */
957
958static void jit_op_move(jit_State *J, int dest, int src)
959{
960 | copyslot BASE[dest], BASE[src]
961}
962
963static void jit_op_loadk(jit_State *J, int dest, int kidx)
964{
965 const TValue *kk = &J->pt->k[kidx];
966 int rk = jit_return_k(J);
967 if (rk) dest = 0;
968 | copyconst BASE[dest], kk
969 if (rk) {
970 | ret
971 }
972}
973
974static void jit_op_loadnil(jit_State *J, int first, int last)
975{
976 int idx, num = last - first + 1;
977 int rk = jit_return_k(J);
978 | xor eax, eax // Assumes: LUA_TNIL == 0
979 if (rk) {
980 | settt BASE[0], eax
981 | ret
982 } else if (num <= 8) {
983 for (idx = first; idx <= last; idx++) {
984 | settt BASE[idx], eax // 3/6 bytes
985 }
986 } else {
987 | lea ecx, BASE[first].tt // 15-21 bytes
988 | lea edx, BASE[last].tt
989 |1:
990 | mov [ecx], eax
991 | cmp ecx, edx
992 | lea ecx, [ecx+#BASE] // Preserves CC.
993 | jbe <1
994 }
995}
996
997static void jit_op_loadbool(jit_State *J, int dest, int b, int dojump)
998{
999 int rk = jit_return_k(J);
1000 if (rk) dest = 0;
1001 | setbvalue BASE[dest], b
1002 if (rk) {
1003 | ret
1004 } else if (dojump) {
1005 const TValue *h = hint_getpc(J, COMBINE, J->nextpc);
1006 if (!(ttisboolean(h) && bvalue(h) == 0)) { /* Avoid jmp around dead ins. */
1007 | jmp =>J->nextpc+1
1008 }
1009 }
1010}
1011
1012/* ------------------------------------------------------------------------ */
1013
1014static void jit_op_getupval(jit_State *J, int dest, int uvidx)
1015{
1016 | getLCL
1017 | mov UPVAL:ecx, LCL->upvals[uvidx]
1018 | mov TOP, UPVAL:ecx->v
1019 | copyslot BASE[dest], TOP[0]
1020}
1021
1022static void jit_op_setupval(jit_State *J, int src, int uvidx)
1023{
1024 | getLCL
1025 | mov UPVAL:ecx, LCL->upvals[uvidx]
1026 | mov TOP, UPVAL:ecx->v
1027 | // This is really copyslot TOP[0], BASE[src] with compare mixed in.
1028 | mov eax, BASE[src].tt
1029 | mov GCOBJECT:edx, BASE[src].value
1030 | mov TOP->tt, eax
1031 | cmp eax, LUA_TSTRING // iscollectable(val)?
1032 | mov eax, BASE[src].value.na[1]
1033 | mov TOP->value, GCOBJECT:edx
1034 | mov TOP->value.na[1], eax
1035 | jae >5
1036 |4:
1037 |.tail
1038 |5:
1039 | test byte GCOBJECT:edx->gch.marked, WHITEBITS // && iswhite(val)
1040 | jz <4
1041 | test byte UPVAL:ecx->marked, bitmask(BLACKBIT) // && isblack(uv)
1042 | jz <4
1043 | call ->BARRIERF // Yes, need barrier.
1044 | jmp <4
1045 |.code
1046
1047 |.jsub BARRIERF // luaC_barrierf() with regparms.
1048 | mov ARG4, GCOBJECT:edx
1049 | mov ARG3, UPVAL:ecx
1050 | mov ARG2, L
1051 | jmp &luaC_barrierf // Chain to C code.
1052 |.endjsub
1053}
1054
1055/* ------------------------------------------------------------------------ */
1056
1057/* Optimized table lookup routines. Enter via jsub, fallback to C. */
1058
1059/* Fallback for GETTABLE_*. Temporary key is in L->env. */
1060static void jit_gettable_fb(lua_State *L, Table *t, StkId dest)
1061{
1062 Table *mt = t->metatable;
1063 const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_INDEX]);
1064 if (ttisnil(tm)) { /* No __index method? */
1065 mt->flags |= 1<<TM_INDEX; /* Cache this fact. */
1066 setnilvalue(dest);
1067 } else if (ttisfunction(tm)) { /* __index function? */
1068 ptrdiff_t destr = savestack(L, dest);
1069 setobj2s(L, L->top, tm);
1070 sethvalue(L, L->top+1, t);
1071 setobj2s(L, L->top+2, &L->env);
1072 luaD_checkstack(L, 3);
1073 L->top += 3;
1074 luaD_call(L, L->top - 3, 1);
1075 dest = restorestack(L, destr);
1076 L->top--;
1077 setobjs2s(L, dest, L->top);
1078 } else { /* Let luaV_gettable() continue with the __index object. */
1079 luaV_gettable(L, tm, &L->env, dest);
1080 }
1081
1082 |//-----------------------------------------------------------------------
1083 |.jsub GETGLOBAL // Lookup global variable.
1084 |// Call with: TSTRING:edx (key), BASE (dest)
1085 | mov CI, L->ci
1086 | mov TOP, CI->func
1087 | mov LCL, TOP->value
1088 | mov TABLE:edi, LCL->env
1089 | jmp >9
1090 |.endjsub
1091 |
1092 |//-----------------------------------------------------------------------
1093 |.jsub GETTABLE_KSTR // Lookup constant string in table.
1094 |// Call with: TOP (tab), TSTRING:edx (key), BASE (dest)
1095 | cmp dword TOP->tt, LUA_TTABLE
1096 | mov TABLE:edi, TOP->value
1097 | jne ->DEOPTIMIZE_CALLER // Not a table? Deoptimize.
1098 |
1099 |// Common entry: TABLE:edi (tab), TSTRING:edx (key), BASE (dest)
1100 |// Restores BASE, destroys eax, ecx, edx, edi (TOP).
1101 |9:
1102 | movzx ecx, byte TABLE:edi->lsizenode // hashstr(t, key).
1103 | mov eax, 1
1104 | shl eax, cl
1105 | dec eax
1106 | and eax, TSTRING:edx->tsv.hash
1107 | Nodemul NODE:eax
1108 | add NODE:eax, TABLE:edi->node
1109 |
1110 |1: // Start of inner loop. Check node key.
1111 | cmp dword NODE:eax->i_key.nk.tt, LUA_TSTRING
1112 | jne >2
1113 | cmp aword NODE:eax->i_key.nk.value, TSTRING:edx
1114 | jne >2
1115 | // Note: swapping the two checks is faster, but valgrind complains.
1116 |// Assumes: (int)&(((Node *)0)->i_val) == (int)&(((StkId)0)->value)
1117 |
1118 |// Ok, key found. Copy node value to destination (stack) slot.
1119 | mov ecx, NODE:eax->i_val.tt
1120 | test ecx, ecx; je >3 // Node has nil value?
1121 ||if (J->flags & JIT_F_CPU_SSE2) {
1122 | movq xmm0, qword NODE:eax->i_val.value
1123 | movq qword BASE->value, xmm0
1124 ||} else {
1125 | mov edx, NODE:eax->i_val.value
1126 | mov edi, NODE:eax->i_val.value.na[1]
1127 | mov BASE->value, edx
1128 | mov BASE->value.na[1], edi
1129 ||}
1130 | mov BASE->tt, ecx
1131 | mov BASE, L->base
1132 | ret
1133 |2:
1134 | mov NODE:eax, NODE:eax->i_key.nk.next // Get next key in chain.
1135 | test NODE:eax, NODE:eax
1136 | jnz <1 // Loop if non-NULL.
1137 |
1138 | xor ecx, ecx
1139 |3:
1140 | mov TABLE:eax, TABLE:edi->metatable
1141 | test TABLE:eax, TABLE:eax
1142 | jz >4 // No metatable?
1143 | test byte TABLE:eax->flags, 1<<TM_INDEX
1144 | jz >5 // Or 'no __index' flag set?
1145 |4:
1146 | settt BASE[0], ecx // Yes, set to nil.
1147 | mov BASE, L->base
1148 | ret
1149 |
1150 |5: // Otherwise chain to C code which eventually calls luaV_gettable.
1151 | setsvalue L->env, TSTRING:edx // Use L->env as temp key.
1152 | mov ecx, [esp]
1153 | sub esp, FRAME_OFFSET
1154 | mov L->savedpc, ecx
1155 | call &jit_gettable_fb, L, TABLE:edi, BASE
1156 | add esp, FRAME_OFFSET
1157 | mov BASE, L->base
1158 | ret
1159 |.endjsub
1160 |
1161 |//-----------------------------------------------------------------------
1162 |.jsub GETTABLE_STR // Lookup string in table.
1163 |// Call with: TOP (tab), TVALUE:ecx (key), BASE (dest)
1164 | mov eax, TOP->tt; shl eax, 4; or eax, TVALUE:ecx->tt
1165 | cmp eax, LUA_TTABLE_STR
1166 | mov TABLE:edi, TOP->value
1167 | mov TSTRING:edx, TVALUE:ecx->value
1168 | je <9 // Types ok? Continue above.
1169 | jmp ->DEOPTIMIZE_CALLER // Otherwise deoptimize.
1170 |.endjsub
1171}
1172
1173/* Fallback for SETTABLE_*STR. Temporary (string) key is in L->env. */
1174static void jit_settable_fb(lua_State *L, Table *t, StkId val)
1175{
1176 Table *mt = t->metatable;
1177 const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_NEWINDEX]);
1178 if (ttisnil(tm)) { /* No __newindex method? */
1179 mt->flags |= 1<<TM_NEWINDEX; /* Cache this fact. */
1180 t->flags = 0; /* But need to clear the cache for the table itself. */
1181 setobj2t(L, luaH_setstr(L, t, rawtsvalue(&L->env)), val);
1182 luaC_barriert(L, t, val);
1183 } else if (ttisfunction(tm)) { /* __newindex function? */
1184 setobj2s(L, L->top, tm);
1185 sethvalue(L, L->top+1, t);
1186 setobj2s(L, L->top+2, &L->env);
1187 setobj2s(L, L->top+3, val);
1188 luaD_checkstack(L, 4);
1189 L->top += 4;
1190 luaD_call(L, L->top - 4, 0);
1191 } else { /* Let luaV_settable() continue with the __newindex object. */
1192 luaV_settable(L, tm, &L->env, val);
1193 }
1194
1195 |//-----------------------------------------------------------------------
1196 |.jsub BARRIERBACK // luaC_barrierback() with regparms.
1197 |// Call with: TABLE:edi (table). Destroys ecx, edx.
1198 | mov GL:ecx, L->l_G
1199 | and byte TABLE:edi->marked, (~bitmask(BLACKBIT))&0xff
1200 | mov edx, GL:ecx->grayagain
1201 | mov GL:ecx->grayagain, TABLE:edi
1202 | mov TABLE:edi->gclist, edx
1203 | ret
1204 |.endjsub
1205 |
1206 |//-----------------------------------------------------------------------
1207 |.jsub SETGLOBAL // Set global variable.
1208 |// Call with: TSTRING:edx (key), BASE (val)
1209 | mov CI, L->ci
1210 | mov TOP, CI->func
1211 | mov LCL, TOP->value
1212 | mov TABLE:edi, LCL->env
1213 | jmp >9
1214 |.endjsub
1215 |
1216 |//-----------------------------------------------------------------------
1217 |.jsub SETTABLE_KSTR // Set constant string entry in table.
1218 |// Call with: TOP (tab), TSTRING:edx (key), BASE (val)
1219 | cmp dword TOP->tt, LUA_TTABLE
1220 | mov TABLE:edi, TOP->value
1221 | jne ->DEOPTIMIZE_CALLER // Not a table? Deoptimize.
1222 |
1223 |// Common entry: TABLE:edi (tab), TSTRING:edx (key), BASE (val)
1224 |// Restores BASE, destroys eax, ecx, edx, edi (TOP).
1225 |9:
1226 | movzx ecx, byte TABLE:edi->lsizenode // hashstr(t, key).
1227 | mov eax, 1
1228 | shl eax, cl
1229 | dec eax
1230 | and eax, TSTRING:edx->tsv.hash
1231 | Nodemul NODE:eax
1232 | add NODE:eax, TABLE:edi->node
1233 |
1234 |1: // Start of inner loop. Check node key.
1235 | cmp dword NODE:eax->i_key.nk.tt, LUA_TSTRING
1236 | jne >4
1237 | cmp aword NODE:eax->i_key.nk.value, TSTRING:edx
1238 | jne >4
1239 | // Note: swapping the two checks is faster, but valgrind complains.
1240 |
1241 |// Ok, key found. Copy new value to node value.
1242 | cmp dword NODE:eax->i_val.tt, LUA_TNIL // Previous value is nil?
1243 | je >6
1244 | // Assumes: (int)&(((Node *)0)->i_val) == (int)&(((StkId)0)->value)
1245 |2:
1246 | mov byte TABLE:edi->flags, 0 // Clear metamethod cache.
1247 |3: // Target for SETTABLE_NUM below.
1248 | test byte TABLE:edi->marked, bitmask(BLACKBIT) // isblack(table)
1249 | jnz >8 // Unlikely, but set barrier back.
1250 |7: // Caveat: recycled label.
1251 | copyslot TVALUE:eax[0], BASE[0], ecx, edx, TOP
1252 | mov BASE, L->base
1253 | ret
1254 |
1255 |8: // Avoid valiswhite() check -- black2gray(table) is ok.
1256 | call ->BARRIERBACK
1257 | jmp <7
1258 |
1259 |4:
1260 | mov NODE:eax, NODE:eax->i_key.nk.next // Get next key in chain.
1261 | test NODE:eax, NODE:eax
1262 | jnz <1 // Loop if non-NULL.
1263 |
1264 |// Key not found. Add a new one, but check metatable first.
1265 | mov TABLE:ecx, TABLE:edi->metatable
1266 | test TABLE:ecx, TABLE:ecx
1267 | jz >5 // No metatable?
1268 | test byte TABLE:ecx->flags, 1<<TM_NEWINDEX
1269 | jz >7 // Or 'no __newindex' flag set?
1270 |
1271 |5: // Add new key.
1272 | // No need for setting L->savedpc since only LUA_ERRMEM may be thrown.
1273 | lea TVALUE:eax, L->env
1274 | setsvalue TVALUE:eax[0], TSTRING:edx
1275 | sub esp, FRAME_OFFSET
1276 | call &luaH_newkey, L, TABLE:edi, TVALUE:eax
1277 | add esp, FRAME_OFFSET
1278 | jmp <2 // Copy to the returned value. See Node/TValue assumption above.
1279 |
1280 |6: // Key found, but previous value is nil.
1281 | mov TABLE:ecx, TABLE:edi->metatable
1282 | test TABLE:ecx, TABLE:ecx
1283 | jz <2 // No metatable?
1284 | test byte TABLE:ecx->flags, 1<<TM_NEWINDEX
1285 | jnz <2 // Or 'no __newindex' flag set?
1286 |
1287 |7: // Otherwise chain to C code which eventually calls luaV_settable.
1288 | setsvalue L->env, TSTRING:edx // Use L->env as temp key.
1289 | mov ecx, [esp]
1290 | sub esp, FRAME_OFFSET
1291 | mov L->savedpc, ecx
1292 | call &jit_settable_fb, L, TABLE:edi, BASE
1293 | add esp, FRAME_OFFSET
1294 | mov BASE, L->base
1295 | ret
1296 |.endjsub
1297 |
1298 |//-----------------------------------------------------------------------
1299 |.jsub SETTABLE_STR // Set string entry in table.
1300 |// Call with: TOP (tab), TVALUE:ecx (key), BASE (val)
1301 | mov eax, TOP->tt; shl eax, 4; or eax, TVALUE:ecx->tt
1302 | cmp eax, LUA_TTABLE_STR
1303 | mov TABLE:edi, TOP->value
1304 | mov TSTRING:edx, TVALUE:ecx->value
1305 | je <9 // Types ok? Continue above.
1306 | jmp ->DEOPTIMIZE_CALLER // Otherwise deoptimize.
1307 |.endjsub
1308}
1309
1310/* ------------------------------------------------------------------------ */
1311
1312static void jit_op_newtable(jit_State *J, int dest, int lnarray, int lnhash)
1313{
1314 | call &luaH_new, L, luaO_fb2int(lnarray), luaO_fb2int(lnhash)
1315 | sethvalue BASE[dest], eax
1316 jit_checkGC(J);
1317}
1318
1319static void jit_op_getglobal(jit_State *J, int dest, int kidx)
1320{
1321 const TValue *kk = &J->pt->k[kidx];
1322 jit_assert(ttisstring(kk));
1323 | mov TSTRING:edx, &&kk->value.gc->ts
1324 | addidx BASE, dest
1325 | call ->GETGLOBAL
1326}
1327
1328static void jit_op_setglobal(jit_State *J, int rval, int kidx)
1329{
1330 const TValue *kk = &J->pt->k[kidx];
1331 jit_assert(ttisstring(kk));
1332 | mov TSTRING:edx, &&kk->value.gc->ts
1333 | addidx BASE, rval
1334 | call ->SETGLOBAL
1335}
1336
1337enum { TKEY_KSTR = -2, TKEY_STR = -1, TKEY_ANY = 0 };
1338
1339/* Optimize key lookup depending on consts or hints type. */
1340static int jit_keylookup(jit_State *J, int tab, int rkey)
1341{
1342 const TValue *tabt = hint_get(J, TYPE);
1343 const TValue *key;
1344 if (!ttistable(tabt)) return TKEY_ANY; /* Not a table? Use fallback. */
1345 key = ISK(rkey) ? &J->pt->k[INDEXK(rkey)] : hint_get(J, TYPEKEY);
1346 if (ttisstring(key)) { /* String key? */
1347 if (ISK(rkey)) {
1348 | lea TOP, BASE[tab]
1349 | mov TSTRING:edx, &&key->value.gc->ts
1350 return TKEY_KSTR; /* Const string key. */
1351 } else {
1352 | lea TOP, BASE[tab]
1353 | lea TVALUE:ecx, BASE[rkey]
1354 return TKEY_STR; /* Var string key. */
1355 }
1356 } else if (ttisnumber(key)) { /* Number key? */
1357 lua_Number n = nvalue(key);
1358 int k;
1359 lua_number2int(k, n);
1360 if (!(k >= 1 && k < (1 << 26) && (lua_Number)k == n))
1361 return TKEY_ANY; /* Not a proper array key? Use fallback. */
1362 if (ISK(rkey)) {
1363 | istable tab
1364 | mov TABLE:edi, BASE[tab].value
1365 | jne >9 // TYPE hint was wrong?
1366 | mov ecx, k // Needed for hash fallback.
1367 | mov TVALUE:eax, TABLE:edi->array
1368 | cmp ecx, TABLE:edi->sizearray; ja >5 // Not in array part?
1369 return k; /* Const array key (>= 1). */
1370 } else {
1371 | mov eax, BASE[tab].tt; shl eax, 4; or eax, BASE[rkey].tt
1372 | cmp eax, LUA_TTABLE_NUM; jne >9 // TYPE/TYPEKEY hint was wrong?
1373 if (J->flags & JIT_F_CPU_SSE2) {
1374 | movsd xmm0, qword BASE[rkey]
1375 | cvttsd2si eax, xmm0
1376 | cvtsi2sd xmm1, eax
1377 | dec eax
1378 | ucomisd xmm1, xmm0
1379 | mov TABLE:edi, BASE[tab].value
1380 | jne >9; jp >9 // Not an integer? Deoptimize.
1381 } else {
1382 |// Annoying x87 stuff: check whether a number is an integer.
1383 |// The latency of fist/fild is the real problem here.
1384 | fld qword BASE[rkey].value
1385 | fist dword TMP1
1386 | fild dword TMP1
1387 | fcomparepp // eax may be modified.
1388 | jne >9; jp >9 // Not an integer? Deoptimize.
1389 | mov eax, TMP1
1390 | mov TABLE:edi, BASE[tab].value
1391 | dec eax
1392 }
1393 | cmp eax, TABLE:edi->sizearray; jae >5 // Not in array part?
1394 | TValuemul eax
1395 | add eax, TABLE:edi->array
1396 return 1; /* Variable array key. */
1397 }
1398 }
1399 return TKEY_ANY; /* Use fallback. */
1400}
1401
1402static void jit_op_gettable(jit_State *J, int dest, int tab, int rkey)
1403{
1404 int k = jit_keylookup(J, tab, rkey);
1405 switch (k) {
1406 case TKEY_KSTR: /* Const string key. */
1407 | addidx BASE, dest
1408 | call ->GETTABLE_KSTR
1409 break;
1410 case TKEY_STR: /* Variable string key. */
1411 | addidx BASE, dest
1412 | call ->GETTABLE_STR
1413 break;
1414 case TKEY_ANY: /* Generic gettable fallback. */
1415 if (ISK(rkey)) {
1416 | mov ecx, &&J->pt->k[INDEXK(rkey)]
1417 } else {
1418 | lea ecx, BASE[rkey]
1419 }
1420 | lea edx, BASE[tab]
1421 | addidx BASE, dest
1422 | mov L->savedpc, &J->nextins
1423 | call &luaV_gettable, L, edx, ecx, BASE
1424 | mov BASE, L->base
1425 break;
1426 default: /* Array key. */
1427 |// This is really copyslot BASE[dest], TVALUE:eax[k-1] mixed with compare.
1428 |1:
1429 | mov edx, TVALUE:eax[k-1].tt
1430 | test edx, edx; je >6 // Array has nil value?
1431 if (J->flags & JIT_F_CPU_SSE2) {
1432 | movq xmm0, qword TVALUE:eax[k-1].value
1433 | movq qword BASE[dest].value, xmm0
1434 } else {
1435 | mov ecx, TVALUE:eax[k-1].value
1436 | mov eax, TVALUE:eax[k-1].value.na[1]
1437 | mov BASE[dest].value, ecx
1438 | mov BASE[dest].value.na[1], eax
1439 }
1440 |2:
1441 | mov BASE[dest].tt, edx
1442 |.tail
1443 |5: // Fallback to hash part. TABLE:edi is callee-saved.
1444 if (ISK(rkey)) {
1445 | call ->GETTABLE_KNUM
1446 } else {
1447 | call ->GETTABLE_NUM
1448 }
1449 | jmp <1 // Slot is at TVALUE:eax[k-1].
1450 |
1451 |6: // Shortcut for tables without an __index metamethod.
1452 | mov TABLE:ecx, TABLE:edi->metatable
1453 | test TABLE:ecx, TABLE:ecx
1454 | jz <2 // No metatable?
1455 | test byte TABLE:ecx->flags, 1<<TM_INDEX
1456 | jnz <2 // Or 'no __index' flag set?
1457 |
1458 |9: // Otherwise deoptimize.
1459 | mov edx, &J->nextins
1460 | jmp ->DEOPTIMIZE
1461 |.code
1462 break;
1463 }
1464
1465 |.jsub GETTABLE_KNUM // Gettable fallback for const numeric keys.
1466 | mov TMP2, ecx // Save k.
1467 | sub esp, FRAME_OFFSET
1468 | call &luaH_getnum, TABLE:edi, ecx
1469 | add esp, FRAME_OFFSET
1470 | mov ecx, TMP2 // Restore k.
1471 | TValuemul ecx
1472 | sub TVALUE:eax, ecx // Compensate for TVALUE:eax[k-1].
1473 | add TVALUE:eax, #TVALUE
1474 | ret
1475 |.endjsub
1476 |
1477 |.jsub GETTABLE_NUM // Gettable fallback for variable numeric keys.
1478 | inc eax
1479 | mov ARG2, TABLE:edi // Really ARG1 and ARG2.
1480 | mov ARG3, eax
1481 | jmp &luaH_getnum // Chain to C code.
1482 |.endjsub
1483}
1484
1485static void jit_op_settable(jit_State *J, int tab, int rkey, int rval)
1486{
1487 const TValue *val = ISK(rval) ? &J->pt->k[INDEXK(rval)] : NULL;
1488 int k = jit_keylookup(J, tab, rkey);
1489 switch (k) {
1490 case TKEY_KSTR: /* Const string key. */
1491 case TKEY_STR: /* Variable string key. */
1492 if (ISK(rval)) {
1493 | mov BASE, &val
1494 } else {
1495 | addidx BASE, rval
1496 }
1497 if (k == TKEY_KSTR) {
1498 | call ->SETTABLE_KSTR
1499 } else {
1500 | call ->SETTABLE_STR
1501 }
1502 break;
1503 case TKEY_ANY: /* Generic settable fallback. */
1504 if (ISK(rkey)) {
1505 | mov ecx, &&J->pt->k[INDEXK(rkey)]
1506 } else {
1507 | lea ecx, BASE[rkey]
1508 }
1509 if (ISK(rval)) {
1510 | mov edx, &val
1511 } else {
1512 | lea edx, BASE[rval]
1513 }
1514 | addidx BASE, tab
1515 | mov L->savedpc, &J->nextins
1516 | call &luaV_settable, L, BASE, ecx, edx
1517 | mov BASE, L->base
1518 break;
1519 default: /* Array key. */
1520 |1:
1521 | tvisnil TVALUE:eax[k-1]; je >6 // Previous value is nil?
1522 |2:
1523 |.tail
1524 |5: // Fallback to hash part. TABLE:edi is callee-saved.
1525 if (ISK(rkey)) {
1526 | call ->SETTABLE_KNUM
1527 } else {
1528 | call ->SETTABLE_NUM
1529 }
1530 | jmp <1 // Slot is at TVALUE:eax[k-1].
1531 |
1532 |6: // Shortcut for tables without a __newindex metamethod.
1533 | mov TABLE:ecx, TABLE:edi->metatable
1534 | test TABLE:ecx, TABLE:ecx
1535 | jz <2 // No metatable?
1536 | test byte TABLE:ecx->flags, 1<<TM_NEWINDEX
1537 | jnz <2 // Or 'no __newindex' flag set?
1538 |
1539 |9: // Otherwise deoptimize.
1540 | mov edx, &J->nextins
1541 | jmp ->DEOPTIMIZE
1542 |.code
1543 if (!ISK(rval) || iscollectable(val)) {
1544 | test byte TABLE:edi->marked, bitmask(BLACKBIT) // isblack(table)
1545 | jnz >7 // Unlikely, but set barrier back.
1546 |3:
1547 |.tail
1548 |7: // Avoid valiswhite() check -- black2gray(table) is ok.
1549 | call ->BARRIERBACK
1550 | jmp <3
1551 |.code
1552 }
1553 if (ISK(rval)) {
1554 | copyconst TVALUE:eax[k-1], val
1555 } else {
1556 | copyslot TVALUE:eax[k-1], BASE[rval], ecx, edx, TOP
1557 }
1558 break;
1559 }
1560
1561 |.jsub SETTABLE_KNUM // Settable fallback for const numeric keys.
1562 | mov TMP2, ecx // Save k.
1563 | sub esp, FRAME_OFFSET
1564 | call &luaH_setnum, L, TABLE:edi, ecx
1565 | add esp, FRAME_OFFSET
1566 | mov ecx, TMP2 // Restore k.
1567 | TValuemul ecx
1568 | sub TVALUE:eax, ecx // Compensate for TVALUE:eax[k-1].
1569 | add TVALUE:eax, #TVALUE
1570 | ret
1571 |.endjsub
1572 |
1573 |.jsub SETTABLE_NUM // Settable fallback for variable numeric keys.
1574 | inc eax
1575 | mov ARG2, L // Really ARG1, ARG2 and ARG3.
1576 | mov ARG3, TABLE:edi
1577 | mov ARG4, eax
1578 | jmp &luaH_setnum // Chain to C code.
1579 |.endjsub
1580}
1581
1582static void jit_op_self(jit_State *J, int dest, int tab, int rkey)
1583{
1584 | copyslot BASE[dest+1], BASE[tab]
1585 jit_op_gettable(J, dest, tab, rkey);
1586}
1587
1588/* ------------------------------------------------------------------------ */
1589
1590static void jit_op_setlist(jit_State *J, int ra, int num, int batch)
1591{
1592 if (batch == 0) { batch = (int)(*J->nextins); J->combine++; }
1593 batch = (batch-1)*LFIELDS_PER_FLUSH;
1594 if (num == 0) { /* Previous op was open and set TOP: {f()} or {...}. */
1595 | mov L->env.value, TOP // Need to save TOP (edi).
1596 | lea eax, BASE[ra+1]
1597 | sub eax, TOP
1598 | neg eax
1599 | TValuediv eax // num = (TOP-ra-1)/sizeof(TValue).
1600 | mov TABLE:edi, BASE[ra].value
1601 | jz >4 // Nothing to set?
1602 if (batch > 0) {
1603 | add eax, batch
1604 }
1605 | cmp dword TABLE:edi->sizearray, eax
1606 | jae >1 // Skip resize if not needed.
1607 | // A resize is likely, so inline it.
1608 | call &luaH_resizearray, L, TABLE:edi, eax
1609 |1:
1610 | test byte TABLE:edi->marked, bitmask(BLACKBIT) // isblack(table)
1611 | mov edx, TABLE:edi->array
1612 | jnz >6 // Unlikely, but set barrier back.
1613 | mov TOP, L->env.value
1614 |
1615 |.tail
1616 |6: // Avoid lots of valiswhite() checks -- black2gray(table) is ok.
1617 | call ->BARRIERBACK
1618 | jmp <1 // Need to reload edx.
1619 |.code
1620 } else { /* Set fixed number of args. */
1621 | mov TABLE:edi, BASE[ra].value // edi is callee-save.
1622 | cmp dword TABLE:edi->sizearray, batch+num
1623 | jb >5 // Need to resize array?
1624 |1:
1625 | test byte TABLE:edi->marked, bitmask(BLACKBIT) // isblack(table)
1626 | mov edx, TABLE:edi->array
1627 | jnz >6 // Unlikely, but set barrier back.
1628 | lea TOP, BASE[ra+1+num] // Careful: TOP is edi.
1629 |
1630 |.tail
1631 |5: // A resize is unlikely (impossible?). NEWTABLE should've done it.
1632 | call &luaH_resizearray, L, TABLE:edi, batch+num
1633 | jmp <1
1634 |6: // Avoid lots of valiswhite() checks -- black2gray(table) is ok.
1635 | call ->BARRIERBACK
1636 | jmp <1 // Need to reload edx.
1637 |.code
1638 }
1639 if (batch > 0) {
1640 | add edx, batch*#TVALUE // edx = &t->array[(batch+1)-1]
1641 }
1642 | lea ecx, BASE[ra+1]
1643 |3: // Copy stack slots to array.
1644 | mov eax, [ecx]
1645 | add ecx, aword*1
1646 | mov [edx], eax
1647 | add edx, aword*1
1648 | cmp ecx, TOP
1649 | jb <3
1650 |
1651 |4:
1652 if (num == 0) { /* Previous op was open. Restore L->top. */
1653 | lea TOP, BASE[J->pt->maxstacksize] // Faster than getting L->ci->top.
1654 | mov L->top, TOP
1655 }
1656}
1657
1658/* ------------------------------------------------------------------------ */
1659
1660static void jit_op_arith(jit_State *J, int dest, int rkb, int rkc, int ev)
1661{
1662 const TValue *kkb = ISK(rkb) ? &J->pt->k[INDEXK(rkb)] : NULL;
1663 const TValue *kkc = ISK(rkc) ? &J->pt->k[INDEXK(rkc)] : NULL;
1664 const Value *kval;
1665 int idx, rev;
1666 int target = (ev == TM_LT || ev == TM_LE) ? jit_jmp_target(J) : 0;
1667 int hastail = 0;
1668
1669 /* The bytecode compiler already folds constants except for: k/0, k%0, */
1670 /* NaN results, k1<k2, k1<=k2. No point in optimizing these cases. */
1671 if (ISK(rkb&rkc)) goto fallback;
1672
1673 /* Avoid optimization when non-numeric constants are present. */
1674 if (kkb ? !ttisnumber(kkb) : (kkc && !ttisnumber(kkc))) goto fallback;
1675
1676 /* The TYPE hint selects numeric inlining and/or fallback encoding. */
1677 switch (ttype(hint_get(J, TYPE))) {
1678 case LUA_TNIL: hastail = 1; break; /* No hint: numeric + fallback. */
1679 case LUA_TNUMBER: break; /* Numbers: numeric + deoptimization. */
1680 default: goto fallback; /* Mixed/other types: fallback only. */
1681 }
1682
1683 /* The checks above ensure: at most one of the operands is a constant. */
1684 /* Reverse operation and swap operands so the 2nd operand is a variable. */
1685 if (kkc) { kval = &kkc->value; idx = rkb; rev = 1; }
1686 else { kval = kkb ? &kkb->value : NULL; idx = rkc; rev = 0; }
1687
1688 /* Special handling for some operators. */
1689 switch (ev) {
1690 case TM_MOD:
1691 /* Check for modulo with positive numbers, so we can use fprem. */
1692 if (kval) {
1693 if (kval->na[1] < 0) { hastail = 0; goto fallback; } /* x%-k, -k%x */
1694 | isnumber idx
1695 | mov eax, BASE[idx].value.na[1]
1696 | jne L_DEOPTIMIZEF
1697 | test eax, eax; js L_DEOPTIMIZEF
1698 |// This will trigger deoptimization in some benchmarks (pidigits).
1699 |// But it's still a win.
1700 if (kkb) {
1701 | fld qword BASE[rkc].value
1702 | fld qword [kval]
1703 } else {
1704 | fld qword [kval]
1705 | fld qword BASE[rkb].value
1706 }
1707 } else {
1708 | isnumber2 rkb, rkc
1709 | mov eax, BASE[rkb].value.na[1]
1710 | jne L_DEOPTIMIZEF
1711 | or eax, BASE[rkc].value.na[1]; js L_DEOPTIMIZEF
1712 | fld qword BASE[rkc].value
1713 | fld qword BASE[rkb].value
1714 }
1715 |1: ; fprem; fnstsw ax; sahf; jp <1
1716 | fstp st1
1717 goto fpstore;
1718 case TM_POW:
1719 if (hastail || !kval) break; /* Avoid this if not optimizing. */
1720 if (rev) { /* x^k for k > 0, k integer. */
1721 lua_Number n = kval->n;
1722 int k;
1723 lua_number2int(k, n);
1724 /* All positive integers would work. But need to limit code explosion. */
1725 if (k > 0 && k <= 65536 && (lua_Number)k == n) {
1726 | isnumber idx; jne L_DEOPTIMIZEF
1727 | fld qword BASE[idx]
1728 for (; (k & 1) == 0; k >>= 1) { /* Handle leading zeroes (2^k). */
1729 | fmul st0
1730 }
1731 if ((k >>= 1) != 0) { /* Handle trailing bits. */
1732 | fld st0
1733 | fmul st0
1734 for (; k != 1; k >>= 1) {
1735 if (k & 1) {
1736 | fmul st1, st0
1737 }
1738 | fmul st0
1739 }
1740 | fmulp st1
1741 }
1742 goto fpstore;
1743 }
1744 } else if (kval->n > (lua_Number)0) { /* k^x for k > 0. */
1745 int log2kval[3]; /* Enough storage for a tword (80 bits). */
1746 log2kval[2] = 0; /* Avoid leaking garbage. */
1747 /* Double precision log2(k) doesn't cut it (3^x != 3 for x = 1). */
1748 ((void (*)(int *, double))J->jsub[JSUB_LOG2_TWORD])(log2kval, kval->n);
1749 | mov ARG1, log2kval[0] // Abuse stack for tword const.
1750 | mov ARG2, log2kval[1]
1751 | mov ARG3, log2kval[2] // TODO: store2load fwd stall.
1752 | isnumber idx; jne L_DEOPTIMIZEF
1753 | fld tword [esp]
1754 | fmul qword BASE[idx].value // log2(k)*x
1755 | fld st0; frndint; fsub st1, st0; fxch // Split into fract/int part.
1756 | f2xm1; fld1; faddp st1; fscale // (2^fract-1 +1) << int.
1757 | fstp st1
1758
1759 |.jsub LOG2_TWORD // Calculate log2(k) with max. precision.
1760 |// Called with (int *ptr, double k).
1761 | fld1; fld FPARG2 // Offset ok due to retaddr.
1762 | fyl2x
1763 | mov eax, ARG2 // Really ARG1.
1764 | fstp tword [eax]
1765 | ret
1766 |.endjsub
1767 goto fpstore;
1768 }
1769 break;
1770 }
1771
1772 /* Check number type and load 1st operand. */
1773 if (kval) {
1774 | isnumber idx; jne L_DEOPTIMIZEF
1775 | loadnvaluek kval
1776 } else {
1777 if (rkb == rkc) {
1778 | isnumber rkb
1779 } else {
1780 | isnumber2 rkb, rkc
1781 }
1782 | jne L_DEOPTIMIZEF
1783 | fld qword BASE[rkb].value
1784 }
1785
1786 /* Encode arithmetic operation with 2nd operand. */
1787 switch ((ev<<1)+rev) {
1788 case TM_ADD<<1: case (TM_ADD<<1)+1:
1789 if (rkb == rkc) {
1790 | fadd st0
1791 } else {
1792 | fadd qword BASE[idx].value
1793 }
1794 break;
1795 case TM_SUB<<1:
1796 | fsub qword BASE[idx].value
1797 break;
1798 case (TM_SUB<<1)+1:
1799 | fsubr qword BASE[idx].value
1800 break;
1801 case TM_MUL<<1: case (TM_MUL<<1)+1:
1802 if (rkb == rkc) {
1803 | fmul st0
1804 } else {
1805 | fmul qword BASE[idx].value
1806 }
1807 break;
1808 case TM_DIV<<1:
1809 | fdiv qword BASE[idx].value
1810 break;
1811 case (TM_DIV<<1)+1:
1812 | fdivr qword BASE[idx].value
1813 break;
1814 case TM_POW<<1:
1815 | sub esp, S2LFRAME_OFFSET
1816 | fstp FPARG1
1817 | fld qword BASE[idx].value
1818 | fstp FPARG2
1819 | call &pow
1820 | add esp, S2LFRAME_OFFSET
1821 break;
1822 case (TM_POW<<1)+1:
1823 | sub esp, S2LFRAME_OFFSET
1824 | fstp FPARG2
1825 | fld qword BASE[idx].value
1826 | fstp FPARG1
1827 | call &pow
1828 | add esp, S2LFRAME_OFFSET
1829 break;
1830 case TM_UNM<<1: case (TM_UNM<<1)+1:
1831 | fchs // No 2nd operand.
1832 break;
1833 default: /* TM_LT or TM_LE. */
1834 | fld qword BASE[idx].value
1835 | fcomparepp
1836 | jp =>dest?(J->nextpc+1):target // Unordered means false.
1837 jit_assert(dest == 0 || dest == 1); /* Really cond. */
1838 switch (((rev^dest)<<1)+(dest^(ev == TM_LT))) {
1839 case 0:
1840 | jb =>target
1841 break;
1842 case 1:
1843 | jbe =>target
1844 break;
1845 case 2:
1846 | ja =>target
1847 break;
1848 case 3:
1849 | jae =>target
1850 break;
1851 }
1852 goto skipstore;
1853 }
1854fpstore:
1855 /* Store result and set result type (if necessary). */
1856 | fstp qword BASE[dest].value
1857 if (dest != rkb && dest != rkc) {
1858 | settt BASE[dest], LUA_TNUMBER
1859 }
1860
1861skipstore:
1862 if (!hastail) {
1863 jit_deopt_target(J, 0);
1864 return;
1865 }
1866
1867 |4:
1868 |.tail
1869 |L_DEOPTLABEL: // Recycle as fallback label.
1870
1871fallback:
1872 /* Generic fallback for arithmetic ops. */
1873 if (kkb) {
1874 | mov ecx, &kkb
1875 } else {
1876 | lea ecx, BASE[rkb]
1877 }
1878 if (kkc) {
1879 | mov edx, &kkc
1880 } else {
1881 | lea edx, BASE[rkc]
1882 }
1883 if (target) { /* TM_LT or TM_LE. */
1884 | mov L->savedpc, &(J->nextins+1)
1885 | call &ev==TM_LT?luaV_lessthan:luaV_lessequal, L, ecx, edx
1886 | test eax, eax
1887 | mov BASE, L->base
1888 if (dest) { /* cond */
1889 | jnz =>target
1890 } else {
1891 | jz =>target
1892 }
1893 } else {
1894 | addidx BASE, dest
1895 | mov L->savedpc, &J->nextins
1896 | call &luaV_arith, L, BASE, ecx, edx, ev
1897 | mov BASE, L->base
1898 }
1899
1900 if (hastail) {
1901 | jmp <4
1902 |.code
1903 }
1904}
1905
1906/* ------------------------------------------------------------------------ */
1907
1908static void jit_fallback_len(lua_State *L, StkId ra, const TValue *rb)
1909{
1910 switch (ttype(rb)) {
1911 case LUA_TTABLE:
1912 setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
1913 break;
1914 case LUA_TSTRING:
1915 setnvalue(ra, cast_num(tsvalue(rb)->len));
1916 break;
1917 default: {
1918 const TValue *tm = luaT_gettmbyobj(L, rb, TM_LEN);
1919 if (ttisfunction(tm)) {
1920 ptrdiff_t rasave = savestack(L, ra);
1921 setobj2s(L, L->top, tm);
1922 setobj2s(L, L->top+1, rb);
1923 luaD_checkstack(L, 2);
1924 L->top += 2;
1925 luaD_call(L, L->top - 2, 1);
1926 ra = restorestack(L, rasave);
1927 L->top--;
1928 setobjs2s(L, ra, L->top);
1929 } else {
1930 luaG_typeerror(L, rb, "get length of");
1931 }
1932 break;
1933 }
1934 }
1935}
1936
1937static void jit_op_len(jit_State *J, int dest, int rb)
1938{
1939 switch (ttype(hint_get(J, TYPE))) {
1940 case LUA_TTABLE:
1941 jit_deopt_target(J, 0);
1942 | istable rb
1943 | mov TABLE:ecx, BASE[rb].value
1944 | jne L_DEOPTIMIZE // TYPE hint was wrong?
1945 | call &luaH_getn, TABLE:ecx
1946 | mov TMP1, eax
1947 | fild dword TMP1
1948 | fstp qword BASE[dest].value
1949 | settt BASE[dest], LUA_TNUMBER
1950 break;
1951 case LUA_TSTRING:
1952 jit_deopt_target(J, 0);
1953 | isstring rb
1954 | mov TSTRING:ecx, BASE[rb].value
1955 | jne L_DEOPTIMIZE // TYPE hint was wrong?
1956 | fild aword TSTRING:ecx->tsv.len // size_t
1957 | fstp qword BASE[dest].value
1958 | settt BASE[dest], LUA_TNUMBER
1959 break;
1960 default:
1961 | lea TVALUE:ecx, BASE[rb]
1962 | addidx BASE, dest
1963 | mov L->savedpc, &J->nextins
1964 | call &jit_fallback_len, L, BASE, TVALUE:ecx
1965 | mov BASE, L->base
1966 break;
1967 }
1968}
1969
1970static void jit_op_not(jit_State *J, int dest, int rb)
1971{
1972 /* l_isfalse() without a branch -- truly devious. */
1973 /* ((value & tt) | (tt>>1)) is only zero for nil/false. */
1974 /* Assumes: LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */
1975 | mov eax, BASE[rb].tt
1976 | mov ecx, BASE[rb].value
1977 | mov edx, 1
1978 | and ecx, eax
1979 | shr eax, 1
1980 | or ecx, eax
1981 | xor eax, eax
1982 | cmp ecx, edx
1983 | adc eax, eax
1984 | mov BASE[dest].tt, edx
1985 | mov BASE[dest].value, eax
1986}
1987
1988/* ------------------------------------------------------------------------ */
1989
1990static void jit_op_concat(jit_State *J, int dest, int first, int last)
1991{
1992 int num = last-first+1;
1993 if (num == 2 && ttisstring(hint_get(J, TYPE))) { /* Optimize common case. */
1994 | addidx BASE, first
1995 | call ->CONCAT_STR2
1996 | setsvalue BASE[dest], eax
1997 } else { /* Generic fallback. */
1998 | mov L->savedpc, &J->nextins
1999 | call &luaV_concat, L, num, last
2000 | mov BASE, L->base
2001 if (dest != first) {
2002 | copyslot BASE[dest], BASE[first]
2003 }
2004 }
2005 jit_checkGC(J); /* Always do this, even for the optimized variant. */
2006
2007 |.jsub CONCAT_STR2 // Concatenate two strings.
2008 |// Call with: BASE (first). Destroys all regs. L and BASE restored.
2009 | mov ARG2, L // Save L (esi).
2010 | mov eax, BASE[0].tt; shl eax, 4; or eax, BASE[1].tt
2011 | sub eax, LUA_TSTR_STR // eax = 0 on success.
2012 | jne ->DEOPTIMIZE_CALLER // Wrong types? Deoptimize.
2013 |
2014 |1:
2015 | mov GL:edi, L->l_G
2016 | mov TSTRING:esi, BASE[0].value // Caveat: L (esi) is gone now!
2017 | mov TSTRING:edx, BASE[1].value
2018 | mov ecx, TSTRING:esi->tsv.len // size_t
2019 | test ecx, ecx
2020 | jz >2 // 1st string is empty?
2021 | or eax, TSTRING:edx->tsv.len // eax is known to be zero.
2022 | jz >4 // 2nd string is empty?
2023 | add eax, ecx
2024 | jc >9 // Length overflow?
2025 | cmp eax, GL:edi->buff.buffsize // size_t
2026 | ja >5 // Temp buffer overflow?
2027 | mov edi, GL:edi->buff.buffer
2028 | add esi, #TSTRING
2029 | rep; movsb // Copy first string.
2030 | mov ecx, TSTRING:edx->tsv.len
2031 | lea esi, TSTRING:edx[1]
2032 | rep; movsb // Copy second string.
2033 |
2034 | sub edi, eax // start = end - total.
2035 | mov L, ARG2 // Restore L (esi). Reuse as 1st arg.
2036 | mov ARG3, edi
2037 | mov ARG4, eax
2038 | mov BASE, L->base // Restore BASE.
2039 | jmp &luaS_newlstr
2040 |
2041 |2: // 1st string is empty.
2042 | mov eax, TSTRING:edx // Return 2nd string.
2043 |3:
2044 | mov L, ARG2 // Restore L (esi) and BASE.
2045 | mov BASE, L->base
2046 | ret
2047 |
2048 |4: // 2nd string is empty.
2049 | mov eax, TSTRING:esi // Return 1st string.
2050 | jmp <3
2051 |
2052 |5: // Resize temp buffer.
2053 | // No need for setting L->savedpc since only LUA_ERRMEM may be thrown.
2054 | mov L, ARG2 // Restore L.
2055 | lea ecx, GL:edi->buff
2056 | sub esp, FRAME_OFFSET
2057 | call &luaZ_openspace, L, ecx, eax
2058 | add esp, FRAME_OFFSET
2059 | xor eax, eax // BASE (first) and L saved. eax = 0.
2060 | jmp <1 // Just restart.
2061 |
2062 |9: // Length overflow errors are rare (> 2 GB string required).
2063 | mov L, ARG2 // Need L for deoptimization.
2064 | jmp ->DEOPTIMIZE_CALLER
2065 |.endjsub
2066}
2067
2068/* ------------------------------------------------------------------------ */
2069
2070static void jit_op_eq(jit_State *J, int cond, int rkb, int rkc)
2071{
2072 int target = jit_jmp_target(J);
2073 int condtarget = cond ? (J->nextpc+1) : target;
2074 jit_assert(cond == 0 || cond == 1);
2075
2076 /* Comparison of two constants. Evaluate at compile time. */
2077 if (ISK(rkb&rkc)) {
2078 if ((rkb == rkc) == cond) { /* Constants are already unique. */
2079 | jmp =>target
2080 }
2081 return;
2082 }
2083
2084 if (ISK(rkb|rkc)) { /* Compare a variable and a constant. */
2085 const TValue *kk;
2086 if (ISK(rkb)) { int t = rkc; rkc = rkb; rkb = t; } /* rkc holds const. */
2087 kk = &J->pt->k[INDEXK(rkc)];
2088 switch (ttype(kk)) {
2089 case LUA_TNIL:
2090 | isnil rkb
2091 break;
2092 case LUA_TBOOLEAN:
2093 if (bvalue(kk)) {
2094 | mov eax, BASE[rkb].tt
2095 | mov ecx, BASE[rkb].value
2096 | dec eax
2097 | dec ecx
2098 | or eax, ecx
2099 } else {
2100 | mov eax, BASE[rkb].tt
2101 | dec eax
2102 | or eax, BASE[rkb].value
2103 }
2104 break;
2105 case LUA_TNUMBER:
2106 |// Note: bitwise comparison is not faster (and needs to handle -0 == 0).
2107 | isnumber rkb
2108 | jne =>condtarget
2109 | fld qword BASE[rkb].value
2110 | fld qword [&kk->value]
2111 | fcomparepp
2112 | jp =>condtarget // Unordered means not equal.
2113 break;
2114 case LUA_TSTRING:
2115 | isstring rkb
2116 | jne =>condtarget
2117 | cmp aword BASE[rkb].value, &rawtsvalue(kk)
2118 break;
2119 default: jit_assert(0); break;
2120 }
2121 } else { /* Compare two variables. */
2122 | mov eax, BASE[rkb].tt
2123 | cmp eax, BASE[rkc].tt
2124 | jne =>condtarget
2125 switch (ttype(hint_get(J, TYPE))) {
2126 case LUA_TNUMBER:
2127 jit_deopt_target(J, 0);
2128 |// Note: bitwise comparison is not an option (-0 == 0, NaN ~= NaN).
2129 | cmp eax, LUA_TNUMBER; jne L_DEOPTIMIZE
2130 | fld qword BASE[rkb].value
2131 | fld qword BASE[rkc].value
2132 | fcomparepp
2133 | jp =>condtarget // Unordered means not equal.
2134 break;
2135 case LUA_TSTRING:
2136 jit_deopt_target(J, 0);
2137 | cmp eax, LUA_TSTRING; jne L_DEOPTIMIZE
2138 | mov ecx, BASE[rkb].value
2139 | cmp ecx, BASE[rkc].value
2140 break;
2141 default:
2142 |// Generic equality comparison fallback.
2143 | lea edx, BASE[rkc]
2144 | lea ecx, BASE[rkb]
2145 | mov L->savedpc, &J->nextins
2146 | call &luaV_equalval, L, ecx, edx
2147 | dec eax
2148 | mov BASE, L->base
2149 break;
2150 }
2151 }
2152 if (cond) {
2153 | je =>target
2154 } else {
2155 | jne =>target
2156 }
2157}
2158
2159/* ------------------------------------------------------------------------ */
2160
2161static void jit_op_test(jit_State *J, int cond, int dest, int src)
2162{
2163 int target = jit_jmp_target(J);
2164
2165 /* l_isfalse() without a branch. But this time preserve tt/value. */
2166 /* (((value & tt) * 2 + tt) >> 1) is only zero for nil/false. */
2167 /* Assumes: 3*tt < 2^32, LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */
2168 | mov eax, BASE[src].tt
2169 | mov ecx, BASE[src].value
2170 | mov edx, eax
2171 | and edx, ecx
2172 | lea edx, [eax+edx*2]
2173 | shr edx, 1
2174
2175 /* Check if we can omit the stack copy. */
2176 if (dest == src) { /* Yes, invert branch condition. */
2177 if (cond) {
2178 | jnz =>target
2179 } else {
2180 | jz =>target
2181 }
2182 } else { /* No, jump around copy code. */
2183 if (cond) {
2184 | jz >1
2185 } else {
2186 | jnz >1
2187 }
2188 | mov edx, BASE[src].value.na[1]
2189 | mov BASE[dest].tt, eax
2190 | mov BASE[dest].value, ecx
2191 | mov BASE[dest].value.na[1], edx
2192 | jmp =>target
2193 |1:
2194 }
2195}
2196
2197static void jit_op_jmp(jit_State *J, int target)
2198{
2199 | jmp =>target
2200}
2201
2202/* ------------------------------------------------------------------------ */
2203
2204enum { FOR_IDX, FOR_LIM, FOR_STP, FOR_EXT };
2205
2206static const char *const jit_for_coerce_error[] = {
2207 LUA_QL("for") " initial value must be a number",
2208 LUA_QL("for") " limit must be a number",
2209 LUA_QL("for") " step must be a number",
2210};
2211
2212/* Try to coerce for slots with strings to numbers in place or complain. */
2213static void jit_for_coerce(lua_State *L, TValue *o)
2214{
2215 int i;
2216 for (i = FOR_IDX; i <= FOR_STP; i++, o++) {
2217 lua_Number num;
2218 if (ttisnumber(o)) continue;
2219 if (ttisstring(o) && luaO_str2d(svalue(o), &num)) {
2220 setnvalue(o, num);
2221 } else {
2222 luaG_runerror(L, jit_for_coerce_error[i]);
2223 }
2224 }
2225}
2226
2227static void jit_op_forprep(jit_State *J, int ra, int target)
2228{
2229 const TValue *step = hint_get(J, FOR_STEP_K);
2230 if (ttisnumber(step)) {
2231 | isnumber2 ra+FOR_IDX, ra+FOR_LIM; jne L_DEOPTIMIZEF
2232 |4:
2233 | fld qword BASE[ra+FOR_LIM].value // [lim]
2234 | fld qword BASE[ra+FOR_IDX].value // [idx lim]
2235 | fst qword BASE[ra+FOR_EXT].value // extidx = idx
2236 | fcomparepp // idx >< lim ?
2237 | settt BASE[ra+FOR_EXT], LUA_TNUMBER
2238 if (nvalue(step) < (lua_Number)0) {
2239 | jb =>target+1 // step < 0 && idx < lim: skip loop.
2240 } else {
2241 | ja =>target+1 // step >= 0 && idx > lim: skip loop.
2242 }
2243 } else {
2244 |4:
2245 | isnumber3 ra+FOR_IDX, ra+FOR_LIM, ra+FOR_STP
2246 | mov eax, BASE[ra+FOR_STP].value.na[1] // Sign bit is in hi dword.
2247 | jne L_DEOPTIMIZEF
2248 | fld qword BASE[ra+FOR_LIM].value // [lim] (FP stack notation)
2249 | fld qword BASE[ra+FOR_IDX].value // [idx lim]
2250 | test eax, eax // step >< 0 ?
2251 | fst qword BASE[ra+FOR_EXT].value // extidx = idx
2252 | js >1
2253 | fxch // if (step > 0) [lim idx]
2254 |1:
2255 | fcomparepp // step > 0 ? lim < idx : idx < lim
2256 | settt BASE[ra+FOR_EXT], LUA_TNUMBER
2257 | jb =>target+1 // Skip loop.
2258 }
2259 if (ttisnumber(hint_get(J, TYPE))) {
2260 jit_deopt_target(J, 0);
2261 } else {
2262 |.tail
2263 |L_DEOPTLABEL: // Recycle as fallback label.
2264 | // Fallback for strings as loop vars. No need to make this fast.
2265 | lea eax, BASE[ra]
2266 | mov L->savedpc, &J->nextins
2267 | call &jit_for_coerce, L, eax // Coerce strings or throw error.
2268 | jmp <4 // Easier than reloading eax.
2269 |.code
2270 }
2271}
2272
2273static void jit_op_forloop(jit_State *J, int ra, int target)
2274{
2275 const TValue *step = hint_getpc(J, FOR_STEP_K, target-1);
2276 if (ttisnumber(step)) {
2277 | fld qword BASE[ra+FOR_LIM].value // [lim] (FP stack notation)
2278 | fld qword BASE[ra+FOR_IDX].value // [idx lim]
2279 | fadd qword BASE[ra+FOR_STP].value // [nidx lim]
2280 | fst qword BASE[ra+FOR_EXT].value // extidx = nidx
2281 | fst qword BASE[ra+FOR_IDX].value // idx = nidx
2282 | settt BASE[ra+FOR_EXT], LUA_TNUMBER
2283 | fcomparepp // nidx >< lim ?
2284 if (nvalue(step) < (lua_Number)0) {
2285 | jae =>target // step < 0 && nidx >= lim: loop again.
2286 } else {
2287 | jbe =>target // step >= 0 && nidx <= lim: loop again.
2288 }
2289 } else {
2290 | mov eax, BASE[ra+FOR_STP].value.na[1] // Sign bit is in hi dword.
2291 | fld qword BASE[ra+FOR_LIM].value // [lim] (FP stack notation)
2292 | fld qword BASE[ra+FOR_IDX].value // [idx lim]
2293 | fld qword BASE[ra+FOR_STP].value // [stp idx lim]
2294 | faddp st1 // [nidx lim]
2295 | fst qword BASE[ra+FOR_IDX].value // idx = nidx
2296 | fst qword BASE[ra+FOR_EXT].value // extidx = nidx
2297 | settt BASE[ra+FOR_EXT], LUA_TNUMBER
2298 | test eax, eax // step >< 0 ?
2299 | js >1
2300 | fxch // if (step > 0) [lim nidx]
2301 |1:
2302 | fcomparepp // step > 0 ? lim >= nidx : nidx >= lim
2303 | jae =>target // Loop again.
2304 }
2305}
2306
2307/* ------------------------------------------------------------------------ */
2308
2309static void jit_op_tforloop(jit_State *J, int ra, int nresults)
2310{
2311 int target = jit_jmp_target(J);
2312 int i;
2313 if (jit_inline_tforloop(J, ra, nresults, target)) return; /* Inlined? */
2314 for (i = 2; i >= 0; i--) {
2315 | copyslot BASE[ra+i+3], BASE[ra+i] // Copy ctlvar/state/callable.
2316 }
2317 jit_op_call(J, ra+3, 2, nresults);
2318 | isnil ra+3; je >1
2319 | copyslot BASE[ra+2], BASE[ra+3] // Save control variable.
2320 | jmp =>target
2321 |1:
2322}
2323
2324/* ------------------------------------------------------------------------ */
2325
2326static void jit_op_close(jit_State *J, int ra)
2327{
2328 if (ra) {
2329 | lea eax, BASE[ra]
2330 | mov ARG2, eax
2331 } else {
2332 | mov ARG2, BASE
2333 }
2334 | call &luaF_close, L // , StkId level (ARG2)
2335}
2336
2337static void jit_op_closure(jit_State *J, int dest, int ptidx)
2338{
2339 Proto *npt = J->pt->p[ptidx];
2340 int nup = npt->nups;
2341 | getLCL edi // LCL:edi is callee-saved.
2342 | mov edx, LCL:edi->env
2343 | call &luaF_newLclosure, L, nup, edx
2344 | mov LCL->p, &npt // Store new proto in returned closure.
2345 | mov aword BASE[dest].value, LCL // setclvalue()
2346 | settt BASE[dest], LUA_TFUNCTION
2347 /* Process pseudo-instructions for upvalues. */
2348 if (nup > 0) {
2349 const Instruction *uvcode = J->nextins;
2350 int i, uvuv;
2351 /* Check which of the two types we need. */
2352 for (i = 0, uvuv = 0; i < nup; i++)
2353 if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) uvuv++;
2354 /* Copy upvalues from parent first. */
2355 if (uvuv) {
2356 /* LCL:eax->upvals (new closure) <-- LCL:edi->upvals (own closure). */
2357 for (i = 0; i < nup; i++)
2358 if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) {
2359 | mov UPVAL:edx, LCL:edi->upvals[GETARG_B(uvcode[i])]
2360 | mov LCL->upvals[i], UPVAL:edx
2361 }
2362 }
2363 /* Next find or create upvalues for our own stack slots. */
2364 if (nup > uvuv) {
2365 | mov LCL:edi, LCL // Move new closure to callee-save register. */
2366 /* LCL:edi->upvals (new closure) <-- upvalue for stack slot. */
2367 for (i = 0; i < nup; i++)
2368 if (GET_OPCODE(uvcode[i]) == OP_MOVE) {
2369 int rb = GETARG_B(uvcode[i]);
2370 if (rb) {
2371 | lea eax, BASE[rb]
2372 | mov ARG2, eax
2373 } else {
2374 | mov ARG2, BASE
2375 }
2376 | call &luaF_findupval, L // , StkId level (ARG2)
2377 | mov LCL:edi->upvals[i], UPVAL:eax
2378 }
2379 }
2380 J->combine += nup; /* Skip pseudo-instructions. */
2381 }
2382 jit_checkGC(J);
2383}
2384
2385/* ------------------------------------------------------------------------ */
2386
2387static void jit_op_vararg(jit_State *J, int dest, int num)
2388{
2389 if (num < 0) { /* Copy all varargs. */
2390 |// Copy [ci->func+1+pt->numparams, BASE) -> [BASE+dest, *).
2391 |1:
2392 | mov CI, L->ci
2393 | mov edx, CI->func
2394 | add edx, (1+J->pt->numparams)*#TVALUE // Start of varargs.
2395 |
2396 | // luaD_checkstack(L, nvararg) with nvararg = L->base - vastart.
2397 | // This is a slight overallocation (BASE[dest+nvararg] would be enough).
2398 | // We duplicate OP_VARARG behaviour so we can use luaD_growstack().
2399 | lea eax, [BASE+BASE+J->pt->maxstacksize*#TVALUE] // L->base + L->top
2400 | sub eax, edx // L->top + (L->base - vastart)
2401 | cmp eax, L->stack_last
2402 | jae >5 // Need to grow stack?
2403 |
2404 | lea TOP, BASE[dest]
2405 | cmp edx, BASE
2406 | jnb >3
2407 |2: // Copy loop.
2408 | mov eax, [edx]
2409 | add edx, aword*1
2410 | mov [TOP], eax
2411 | add TOP, aword*1
2412 | cmp edx, BASE
2413 | jb <2
2414 |3:
2415 |// This is an open ins. Must keep TOP for next instruction.
2416 |
2417 |.tail
2418 |5: // Grow stack for varargs.
2419 | sub eax, L->top
2420 | TValuediv eax
2421 | call &luaD_growstack, L, eax
2422 | mov BASE, L->base
2423 | jmp <1 // Just restart op to avoid saving/restoring regs.
2424 |.code
2425 } else if (num > 0) { /* Copy limited number of varargs. */
2426 |// Copy [ci->func+1+pt->numparams, BASE) -> [BASE+dest, BASE+dest+num).
2427 | mov CI, L->ci
2428 | mov edx, CI->func
2429 | add edx, (1+J->pt->numparams)*#TVALUE
2430 | lea TOP, BASE[dest]
2431 | lea ecx, BASE[dest+num]
2432 | cmp edx, BASE // No varargs present: only fill.
2433 | jnb >2
2434 |
2435 |1: // Copy loop.
2436 | mov eax, [edx]
2437 | add edx, aword*1
2438 | mov [TOP], eax
2439 | add TOP, aword*1
2440 | cmp TOP, ecx // Stop if all dest slots got a vararg.
2441 | jnb >4
2442 | cmp edx, BASE // Continue if more varargs present.
2443 | jb <1
2444 |
2445 |2: // Fill remaining slots with nils.
2446 | xor eax, eax // Assumes: LUA_TNIL == 0
2447 |3: // Fill loop.
2448 | settt TOP[0], eax
2449 | add TOP, #TVALUE
2450 | cmp TOP, ecx
2451 | jb <3
2452 |4:
2453 }
2454}
2455
2456/* ------------------------------------------------------------------------ */
2457
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86.dash b/libraries/LuaJIT-1.1.7/src/ljit_x86.dash
new file mode 100644
index 0000000..432e1c8
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_x86.dash
@@ -0,0 +1,297 @@
1|//
2|// Common DynASM definitions and macros for x86 CPUs.
3|// Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4|//
5|
6|// Standard DynASM declarations.
7|.arch x86
8|.section code, deopt, tail, mfmap
9|
10|// Type definitions with (almost) global validity.
11|.type L, lua_State, esi // L.
12|.type BASE, TValue, ebx // L->base.
13|.type TOP, TValue, edi // L->top (calls/open ops).
14|.type CI, CallInfo, ecx // L->ci (calls, locally).
15|.type LCL, LClosure, eax // func->value (calls).
16|
17|// Type definitions with local validity.
18|.type GL, global_State
19|.type TVALUE, TValue
20|.type VALUE, Value
21|.type CINFO, CallInfo
22|.type GCOBJECT, GCObject
23|.type TSTRING, TString
24|.type TABLE, Table
25|.type CCLOSURE, CClosure
26|.type PROTO, Proto
27|.type UPVAL, UpVal
28|.type NODE, Node
29|
30|// Definitions copied to DynASM domain to avoid unnecessary constant args.
31|// CHECK: must match with the definitions in lua.h!
32|.define LUA_TNIL, 0
33|.define LUA_TBOOLEAN, 1
34|.define LUA_TLIGHTUSERDATA, 2
35|.define LUA_TNUMBER, 3
36|.define LUA_TSTRING, 4
37|.define LUA_TTABLE, 5
38|.define LUA_TFUNCTION, 6
39|.define LUA_TUSERDATA, 7
40|.define LUA_TTHREAD, 8
41|
42|.define LUA_TNUM_NUM, 0x33
43|.define LUA_TNUM_NUM_NUM, 0x333
44|.define LUA_TSTR_STR, 0x44
45|.define LUA_TSTR_NUM, 0x43
46|.define LUA_TSTR_NUM_NUM, 0x433
47|.define LUA_TTABLE_NUM, 0x53
48|.define LUA_TTABLE_STR, 0x54
49|
50|// Macros to test, set and copy stack slots.
51|.macro istt, idx, tp; cmp dword BASE[idx].tt, tp; .endmacro
52|.macro isnil, idx; istt idx, LUA_TNIL; .endmacro
53|.macro isnumber, idx; istt idx, LUA_TNUMBER; .endmacro
54|.macro isstring, idx; istt idx, LUA_TSTRING; .endmacro
55|.macro istable, idx; istt idx, LUA_TTABLE; .endmacro
56|.macro isfunction, idx; istt idx, LUA_TFUNCTION; .endmacro
57|
58|.macro isnumber2, idx1, idx2, reg
59| mov reg, BASE[idx1].tt; shl reg, 4; or reg, BASE[idx2].tt
60| cmp reg, LUA_TNUM_NUM
61|.endmacro
62|.macro isnumber2, idx1, idx2; isnumber2, idx1, idx2, eax; .endmacro
63|
64|.macro isnumber3, idx1, idx2, idx3, reg
65| mov reg, BASE[idx1].tt; shl reg, 4; or reg, BASE[idx2].tt
66| shl reg, 4; or reg, BASE[idx3].tt; cmp reg, LUA_TNUM_NUM_NUM
67|.endmacro
68|.macro isnumber3, idx1, idx2, idx3; isnumber3, idx1, idx2, idx3, eax; .endmacro
69|
70|.macro tvisnil, tv; cmp dword tv.tt, LUA_TNIL; .endmacro
71|
72|.macro settt, tv, tp; mov dword tv.tt, tp; .endmacro
73|.macro setnilvalue, tv; settt tv, LUA_TNIL; .endmacro
74|
75|.macro setbvalue, tv, val // May use edx.
76||if (val) { /* true */
77| mov edx, LUA_TBOOLEAN
78| mov dword tv.value, edx // Assumes: LUA_TBOOLEAN == 1
79| settt tv, edx
80||} else { /* false */
81| mov dword tv.value, 0
82| settt tv, LUA_TBOOLEAN
83||}
84|.endmacro
85|
86|.macro loadnvaluek, vptr
87||if ((vptr)->n == (lua_Number)0) {
88| fldz
89||} else if ((vptr)->n == (lua_Number)1) {
90| fld1
91||} else {
92| fld qword [vptr]
93||}
94|.endmacro
95|
96|.macro setnvaluek, tv, vptr // Pass a Value *! With permanent addr.
97| // SSE2 does not pay off here (I tried).
98| loadnvaluek vptr
99| fstp qword tv.value
100| settt tv, LUA_TNUMBER
101|.endmacro
102|
103|.macro setnvalue, tv, vptr // Pass a Value *! Temporary ok.
104| mov dword tv.value, (vptr)->na[0]
105| mov dword tv.value.na[1], (vptr)->na[1]
106| settt tv, LUA_TNUMBER
107|.endmacro
108|
109|.macro setsvalue, tv, vptr
110| mov aword tv.value, vptr
111| settt tv, LUA_TSTRING
112|.endmacro
113|
114|.macro sethvalue, tv, vptr
115| mov aword tv.value, vptr
116| settt tv, LUA_TTABLE
117|.endmacro
118|
119|.macro copyslotSSE, D, S, R1 // May use xmm0.
120| mov R1, S.tt; movq xmm0, qword S.value
121| mov D.tt, R1; movq qword D.value, xmm0
122|.endmacro
123|
124|.macro copyslot, D, S, R1, R2, R3
125||if (J->flags & JIT_F_CPU_SSE2) {
126| copyslotSSE D, S, R1
127||} else {
128| mov R1, S.value; mov R2, S.value.na[1]; mov R3, S.tt
129| mov D.value, R1; mov D.value.na[1], R2; mov D.tt, R3
130||}
131|.endmacro
132|
133|.macro copyslot, D, S, R1, R2
134||if (J->flags & JIT_F_CPU_SSE2) {
135| copyslotSSE D, S, R1
136||} else {
137| mov R1, S.value; mov R2, S.value.na[1]; mov D.value, R1
138| mov R1, S.tt; mov D.value.na[1], R2; mov D.tt, R1
139||}
140|.endmacro
141|
142|.macro copyslot, D, S
143| copyslot D, S, ecx, edx, eax
144|.endmacro
145|
146|.macro copyconst, tv, tvk // May use edx.
147||switch (ttype(tvk)) {
148||case LUA_TNIL:
149| setnilvalue tv
150|| break;
151||case LUA_TBOOLEAN:
152| setbvalue tv, bvalue(tvk) // May use edx.
153|| break;
154||case LUA_TNUMBER: {
155| setnvaluek tv, &(tvk)->value
156|| break;
157||}
158||case LUA_TSTRING:
159| setsvalue tv, &gcvalue(tvk)
160|| break;
161||default: lua_assert(0); break;
162||}
163|.endmacro
164|
165|// Macros to get Lua structures.
166|.macro getLCL, reg // May use CI and TOP (edi).
167||if (!J->pt->is_vararg) {
168| mov LCL:reg, BASE[-1].value
169||} else {
170| mov CI, L->ci
171| mov TOP, CI->func
172| mov LCL:reg, TOP->value
173||}
174|.endmacro
175|.macro getLCL; getLCL eax; .endmacro
176|
177|// Macros to handle variants.
178|.macro addidx, type, idx
179||if (idx) {
180| add type, idx*#type
181||}
182|.endmacro
183|
184|.macro subidx, type, idx
185||if (idx) {
186| sub type, idx*#type
187||}
188|.endmacro
189|
190|// Annoying x87 stuff: support for two compare variants.
191|.macro fcomparepp // Compare and pop st0 >< st1.
192||if (J->flags & JIT_F_CPU_CMOV) {
193| fucomip st1
194| fpop
195||} else {
196| fucompp
197| fnstsw ax // eax modified!
198| sahf
199| // Sometimes test ah, imm8 would be faster.
200| // But all following compares need to be changed then.
201| // Don't bother since this is only compatibility stuff for old CPUs.
202||}
203|.endmacro
204|
205|// If you change LUA_TVALUE_ALIGN, be sure to change the Makefile, too:
206|// DASMFLAGS= -D TVALUE_SIZE=...
207|// Then rerun make. Or change the default below:
208|.if not TVALUE_SIZE; .define TVALUE_SIZE, 16; .endif
209|
210|.if TVALUE_SIZE == 16
211| .macro TValuemul, reg; sal reg, 4; .endmacro // *16
212| .macro TValuediv, reg; sar reg, 4; .endmacro // /16
213| .macro Nodemul, reg; sal reg, 5; .endmacro // *32
214|.elif TVALUE_SIZE == 12
215| .macro TValuemul, reg; sal reg, 2; lea reg, [reg+reg*2]; .endmacro // *12
216| .macro TValuediv, reg; sal reg, 2; imul reg, 0xaaaaaaab; .endmacro // /12
217| .macro Nodemul, reg; imul reg, 28; .endmacro // *28
218|.else
219| .fatal Unsupported TValue size `TVALUE_SIZE'.
220|.endif
221|
222|//
223|// x86 C calling conventions and stack frame layout during a JIT call:
224|//
225|// ebp+aword*4 CARG2 nresults
226|// ebp+aword*3 CARG2 func (also used as SAVER3 for L)
227|// ebp+aword*2 CARG1 L
228|// ------------------------------- call to GATE_LJ
229|// ebp+aword*1 retaddr
230|// ebp+aword*0 frameptr ebp
231|// ebp-aword*1 SAVER1 TOP edi
232|// ebp-aword*2 SAVER2 BASE ebx
233|// -------------------------------
234|// GATE_LJ retaddr
235|// esp+aword*2 ARG3
236|// esp+aword*1 ARG2
237|// esp+aword*0 ARG1 <-- esp for first JIT frame
238|// -------------------------------
239|// 1st JIT frame retaddr
240|// esp+aword*2 ARG3
241|// esp+aword*1 ARG2
242|// esp+aword*0 ARG1 <-- esp for second JIT frame
243|// -------------------------------
244|// 2nd JIT frame retaddr
245|//
246|// We could omit the fixed frame pointer (ebp) and have one more register
247|// available. But there is no pressing need (could use it for CI).
248|// And it's easier for debugging (gdb is still confused -- why?).
249|//
250|// The stack is aligned to 4 awords (16 bytes). Calls to C functions
251|// with up to 3 arguments do not need any stack pointer adjustment.
252|//
253|
254|.define CARG3, [ebp+aword*4]
255|.define CARG2, [ebp+aword*3]
256|.define CARG1, [ebp+aword*2]
257|.define SAVER1, [ebp-aword*1]
258|.define SAVER2, [ebp-aword*2]
259|.define ARG7, aword [esp+aword*6] // Requires large frame.
260|.define ARG6, aword [esp+aword*5] // Requires large frame.
261|.define ARG5, aword [esp+aword*4] // Requires large frame.
262|.define ARG4, aword [esp+aword*3] // Requires large frame.
263|.define ARG3, aword [esp+aword*2]
264|.define ARG2, aword [esp+aword*1]
265|.define ARG1, aword [esp]
266|.define FRAME_RETADDR, aword [esp+aword*3]
267|.define TMP3, [esp+aword*2]
268|.define TMP2, [esp+aword*1]
269|.define TMP1, [esp]
270|.define FPARG2, qword [esp+qword*1] // Requires large frame.
271|.define FPARG1, qword [esp]
272|.define LJFRAME_OFFSET, aword*2 // 16 byte aligned with retaddr + ebp.
273|.define FRAME_OFFSET, aword*3 // 16 byte aligned with retaddr.
274|.define LFRAME_OFFSET, aword*7 // 16 byte aligned with retaddr.
275|.define S2LFRAME_OFFSET, aword*4 // Delta to large frame.
276|
277|.macro call, target, a1
278| mov ARG1, a1; call target; .endmacro
279|.macro call, target, a1, a2
280| mov ARG1, a1; mov ARG2, a2; call target; .endmacro
281|.macro call, target, a1, a2, a3
282| mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; call target; .endmacro
283|.macro call, target, a1, a2, a3, a4
284| push a4; push a3; push a2; push a1
285| call target; add esp, S2LFRAME_OFFSET; .endmacro
286|.macro call, target, a1, a2, a3, a4, a5
287| mov ARG1, a5; push a4; push a3; push a2; push a1
288| call target; add esp, S2LFRAME_OFFSET; .endmacro
289|
290|// The following macros require a large frame.
291|.macro call_LFRAME, target, a1, a2, a3, a4
292| mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; mov ARG4, a4
293| call target; .endmacro
294|.macro call_LFRAME, target, a1, a2, a3, a4, a5
295| mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; mov ARG4, a4; mov ARG5, a5
296| call target; .endmacro
297|
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86.h b/libraries/LuaJIT-1.1.7/src/ljit_x86.h
new file mode 100644
index 0000000..fc860bc
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_x86.h
@@ -0,0 +1,2301 @@
1/*
2** This file has been pre-processed with DynASM.
3** http://luajit.org/dynasm.html
4** DynASM version 1.1.4, DynASM x86 version 1.1.4
5** DO NOT EDIT! The original file is in "ljit_x86.dasc".
6*/
7
8#if DASM_VERSION != 10104
9#error "Version mismatch between DynASM and included encoding engine"
10#endif
11
12/*
13** Bytecode to machine code translation for x86 CPUs.
14** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
15*/
16
17#define DASM_SECTION_CODE 0
18#define DASM_SECTION_DEOPT 1
19#define DASM_SECTION_TAIL 2
20#define DASM_SECTION_MFMAP 3
21#define DASM_MAXSECTION 4
22#define Dt1(_V) (int)&(((lua_State *)0)_V)
23#define Dt2(_V) (int)&(((TValue *)0)_V)
24#define Dt3(_V) (int)&(((TValue *)0)_V)
25#define Dt4(_V) (int)&(((CallInfo *)0)_V)
26#define Dt5(_V) (int)&(((LClosure *)0)_V)
27#define Dt6(_V) (int)&(((global_State *)0)_V)
28#define Dt7(_V) (int)&(((TValue *)0)_V)
29#define Dt8(_V) (int)&(((Value *)0)_V)
30#define Dt9(_V) (int)&(((CallInfo *)0)_V)
31#define DtA(_V) (int)&(((GCObject *)0)_V)
32#define DtB(_V) (int)&(((TString *)0)_V)
33#define DtC(_V) (int)&(((Table *)0)_V)
34#define DtD(_V) (int)&(((CClosure *)0)_V)
35#define DtE(_V) (int)&(((Proto *)0)_V)
36#define DtF(_V) (int)&(((UpVal *)0)_V)
37#define Dt10(_V) (int)&(((Node *)0)_V)
38static const unsigned char jit_actionlist[5059] = {
39 156,90,137,209,129,252,242,0,0,32,0,82,157,156,90,49,192,57,209,15,132,245,
40 247,64,83,15,162,91,137,208,249,1,195,255,254,0,251,15,249,10,141,68,36,4,
41 195,251,15,249,11,85,137,229,131,252,236,8,137,93,252,252,139,93,12,137,117,
42 12,139,117,8,137,125,252,248,139,190,235,139,131,235,139,142,235,102,252,
43 255,134,235,252,255,144,235,139,142,235,137,190,235,139,145,235,139,69,16,
44 137,150,235,139,145,235,133,192,137,150,235,15,136,245,248,193,224,4,1,195,
45 49,201,137,158,235,249,1,137,143,235,129,199,241,57,223,15,130,245,1,249,
46 2,255,102,252,255,142,235,184,239,139,125,252,248,139,93,252,252,139,117,
47 12,137,252,236,93,195,251,15,249,12,139,144,235,129,186,235,241,15,133,245,
48 247,139,146,235,137,144,235,252,255,226,249,1,131,252,236,12,139,129,235,
49 137,142,235,137,190,235,199,68,36,8,252,255,252,255,252,255,252,255,137,134,
50 235,137,92,36,4,43,158,235,137,52,36,232,244,133,192,15,133,245,248,137,52,
51 36,199,68,36,4,1,0,0,0,232,244,249,2,131,196,12,3,158,235,255,139,190,235,
52 195,251,15,249,13,141,135,235,131,252,236,12,59,134,235,15,131,245,14,59,
53 142,235,141,137,235,15,132,245,15,137,142,235,137,153,235,137,129,235,139,
54 147,235,129,195,241,137,190,235,137,158,235,137,153,235,249,16,137,52,36,
55 252,255,146,235,249,2,131,196,12,139,142,235,255,193,224,4,139,185,235,15,
56 132,245,250,139,158,235,137,218,41,195,249,3,139,3,131,195,4,137,7,131,199,
57 4,57,211,15,130,245,3,249,4,139,153,235,129,233,241,137,142,235,195,144,144,
58 144,144,144,144,251,15,249,17,252,246,134,235,237,15,133,245,253,249,6,137,
59 52,36,252,255,146,235,252,246,134,235,237,15,132,245,2,255,137,195,137,52,
60 36,199,68,36,4,239,199,68,36,8,252,255,252,255,252,255,252,255,232,244,137,
61 216,233,245,2,249,7,137,211,137,52,36,199,68,36,4,239,199,68,36,8,252,255,
62 252,255,252,255,252,255,232,244,137,218,233,245,6,251,15,249,14,41,252,248,
63 193,252,248,4,137,190,235,43,158,235,137,76,36,8,137,52,36,137,68,36,4,232,
64 244,139,76,36,8,3,158,235,139,190,235,139,131,235,131,196,12,252,255,160,
65 235,251,15,249,15,137,190,235,137,52,36,232,244,141,136,235,255,139,131,235,
66 137,142,235,131,196,12,252,255,160,235,255,249,18,90,233,245,19,249,20,137,
67 190,235,249,19,137,150,235,137,52,36,232,244,139,158,235,139,190,235,252,
68 255,224,251,15,255,137,190,235,255,232,245,21,255,251,15,249,21,252,246,134,
69 235,237,15,132,245,248,252,255,142,235,15,132,245,247,252,246,134,235,237,
70 15,132,245,248,249,1,139,4,36,131,252,236,12,137,52,36,137,68,36,4,232,244,
71 131,196,12,139,158,235,139,190,235,249,2,195,255,250,255,233,246,255,250,
72 243,255,254,1,233,245,19,254,0,250,254,2,250,251,1,252,255,252,255,254,3,
73 242,0,0,0,0,0,0,0,0,0,254,0,141,249,9,186,239,254,0,249,9,186,239,233,245,
74 20,254,0,139,142,235,139,129,235,191,247,253,59,129,235,15,131,245,22,249,
75 7,255,251,15,249,22,137,52,36,232,244,139,158,235,252,255,231,255,131,187,
76 235,5,15,133,245,9,49,192,137,131,235,137,131,235,254,3,238,238,254,0,131,
77 190,235,0,15,132,245,9,199,134,235,239,129,195,241,255,141,187,235,255,137,
78 158,235,137,190,235,137,52,36,232,244,139,158,235,139,190,235,255,199,135,
79 235,0,0,0,0,255,139,139,235,252,243,15,126,131,235,137,139,235,102,15,214,
80 131,235,255,139,139,235,139,147,235,139,131,235,137,139,235,137,147,235,137,
81 131,235,255,57,223,15,130,245,9,255,131,187,235,8,15,133,245,9,139,131,235,
82 131,184,235,0,15,132,245,9,199,134,235,239,137,190,235,137,52,36,137,92,36,
83 4,199,68,36,8,239,232,244,139,158,235,255,137,199,255,131,187,235,4,15,133,
84 245,9,139,139,235,219,129,235,199,131,235,3,0,0,0,221,155,235,255,141,187,
85 235,232,245,23,137,131,235,199,131,235,4,0,0,0,255,141,187,235,232,245,24,
86 137,131,235,199,131,235,4,0,0,0,255,131,187,235,3,15,133,245,9,141,134,235,
87 221,131,235,219,24,129,56,252,255,0,0,0,15,135,245,9,137,52,36,137,68,36,
88 4,199,68,36,8,1,0,0,0,232,244,137,131,235,199,131,235,4,0,0,0,255,251,15,
89 249,23,139,135,235,193,224,4,11,135,235,193,224,4,11,135,235,45,51,4,0,0,
90 15,133,245,18,221,135,235,221,135,235,219,92,36,8,219,92,36,4,139,143,235,
91 139,185,235,139,84,36,8,57,215,15,130,245,250,249,1,11,68,36,4,15,142,245,
92 252,249,2,41,194,15,140,245,253,141,140,253,1,235,66,249,3,137,116,36,4,137,
93 76,36,8,137,84,36,12,139,190,235,139,135,235,255,59,135,235,15,131,245,254,
94 233,244,249,4,15,140,245,251,141,84,58,1,233,245,1,249,5,137,252,250,233,
95 245,1,249,6,15,132,245,251,1,252,248,64,15,143,245,2,249,5,184,1,0,0,0,233,
96 245,2,249,7,49,210,233,245,3,255,251,15,249,24,139,135,235,193,224,4,11,135,
97 235,131,232,67,15,133,245,18,221,135,235,219,92,36,4,139,143,235,139,185,
98 235,137,252,250,233,245,1,249,8,131,252,236,12,137,52,36,232,244,131,196,
99 12,139,158,235,233,244,255,131,187,235,5,15,133,245,9,255,141,131,235,137,
100 52,36,137,68,36,4,232,244,255,141,131,235,141,139,235,137,52,36,137,68,36,
101 4,137,76,36,8,232,244,255,139,131,235,137,4,36,232,244,137,4,36,219,4,36,
102 221,155,235,199,131,235,3,0,0,0,255,131,187,235,3,15,133,245,9,221,131,235,
103 255,139,131,235,193,224,4,11,131,235,131,252,248,51,15,133,245,9,255,217,
104 252,254,255,217,252,255,255,217,252,242,221,216,255,217,60,36,217,45,239,
105 217,252,252,217,44,36,255,217,225,255,217,252,250,255,221,131,235,221,131,
106 235,249,1,217,252,248,223,224,158,15,138,245,1,221,217,255,221,131,235,221,
107 131,235,217,252,243,255,221,28,36,232,244,255,131,187,235,6,15,133,245,9,
108 129,187,235,239,15,133,245,9,255,141,131,235,57,199,15,133,245,9,255,141,
109 187,235,137,190,235,255,131,196,12,129,252,235,241,129,174,235,241,195,255,
110 141,187,235,137,52,36,137,124,36,4,232,244,133,192,15,133,246,255,139,131,
111 235,64,139,147,235,137,131,235,137,20,36,137,68,36,4,232,244,139,136,235,
112 133,201,15,132,245,255,219,131,235,199,131,235,3,0,0,0,221,155,235,139,144,
113 235,139,128,235,137,139,235,137,147,235,137,131,235,233,246,249,9,255,141,
114 135,235,131,252,236,12,59,134,235,15,131,245,14,59,142,235,141,137,235,15,
115 132,245,15,49,192,137,153,235,129,195,241,137,142,235,255,141,147,235,57,
116 215,255,137,223,255,15,71,252,250,255,15,134,245,247,137,215,249,1,255,141,
117 147,235,137,129,235,137,145,235,137,150,235,137,158,235,137,153,235,255,15,
118 130,245,251,249,4,254,2,249,5,137,135,235,129,199,241,57,215,15,130,245,5,
119 233,245,4,254,0,137,190,235,137,185,235,137,129,235,255,139,139,235,252,243,
120 15,126,131,235,137,143,235,102,15,214,135,235,255,139,139,235,139,147,235,
121 137,143,235,139,139,235,137,151,235,137,143,235,255,137,252,251,141,147,235,
122 141,187,235,137,145,235,137,150,235,255,137,135,235,255,249,2,137,135,235,
123 137,135,235,129,199,241,57,215,15,130,245,2,255,137,52,36,232,244,255,252,
124 246,134,235,237,15,132,245,255,232,245,25,249,9,255,251,15,249,25,139,142,
125 235,139,185,235,139,135,235,139,184,235,139,135,235,131,192,4,137,134,235,
126 131,252,236,12,137,52,36,199,68,36,4,239,199,68,36,8,252,255,252,255,252,
127 255,252,255,232,244,131,196,12,139,135,235,137,134,235,139,158,235,195,255,
128 137,52,36,137,92,36,4,232,244,255,129,174,235,241,137,223,129,252,235,241,
129 131,196,12,255,139,142,235,139,153,235,129,233,241,137,142,235,141,187,235,
130 131,196,12,255,252,246,134,235,237,15,132,245,253,232,245,26,249,7,255,139,
131 68,36,12,137,134,235,255,251,15,249,26,139,4,36,137,134,235,131,252,236,12,
132 137,52,36,199,68,36,4,239,199,68,36,8,252,255,252,255,252,255,252,255,232,
133 244,131,196,12,139,158,235,139,190,235,195,255,139,145,235,57,252,251,15,
134 131,245,248,249,1,139,3,131,195,4,137,2,131,194,4,57,252,251,15,130,245,1,
135 249,2,131,196,12,139,153,235,129,233,241,137,215,137,142,235,195,255,129,
136 174,235,241,129,252,235,241,255,131,196,12,141,187,235,195,255,139,142,235,
137 139,185,235,129,233,241,137,142,235,255,139,139,235,139,147,235,139,131,235,
138 137,143,235,137,151,235,137,135,235,255,131,196,12,137,252,251,255,129,199,
139 241,255,139,142,235,131,187,235,6,255,139,131,235,186,239,137,145,235,255,
140 15,133,245,20,255,15,133,245,19,255,15,132,245,247,232,245,27,249,1,255,251,
141 15,249,27,131,252,236,12,137,150,235,137,190,235,137,52,36,137,92,36,4,232,
142 244,131,196,12,137,195,139,190,235,139,131,235,139,142,235,195,255,252,255,
143 144,235,255,137,158,235,255,49,192,255,141,147,235,249,1,137,135,235,137,
144 135,235,129,199,241,57,215,15,130,245,1,255,131,187,235,6,15,133,245,9,255,
145 131,187,235,6,15,133,245,251,254,2,249,5,255,186,239,233,245,28,254,0,251,
146 15,249,28,137,150,235,137,190,235,137,52,36,137,92,36,4,232,244,139,142,235,
147 139,150,235,139,185,235,249,1,139,24,131,192,4,137,31,131,199,4,57,208,15,
148 130,245,1,139,153,235,139,131,235,129,233,241,131,196,12,252,255,160,235,
149 255,139,131,235,255,139,139,235,139,147,235,137,139,235,139,139,235,137,147,
150 235,137,139,235,255,141,187,235,129,252,235,241,139,142,235,137,131,235,255,
151 139,142,235,141,187,235,139,153,235,139,135,235,137,131,235,255,139,135,235,
152 252,243,15,126,135,235,137,131,235,102,15,214,131,235,255,139,135,235,139,
153 151,235,137,131,235,139,135,235,137,147,235,137,131,235,255,141,187,235,139,
154 131,235,255,139,145,235,249,1,139,3,131,195,4,137,2,131,194,4,57,252,251,
155 15,130,245,1,139,153,235,137,215,139,131,235,255,199,131,235,0,0,0,0,255,
156 186,1,0,0,0,137,147,235,137,147,235,255,199,131,235,0,0,0,0,199,131,235,1,
157 0,0,0,255,217,252,238,255,217,232,255,221,5,239,255,199,131,235,239,199,131,
158 235,4,0,0,0,255,137,131,235,195,255,141,139,235,141,147,235,249,1,137,1,57,
159 209,141,137,235,15,134,245,1,255,139,142,235,139,185,235,139,135,235,255,
160 139,136,235,139,185,235,255,139,143,235,252,243,15,126,135,235,137,139,235,
161 102,15,214,131,235,255,139,143,235,139,151,235,139,135,235,137,139,235,137,
162 147,235,137,131,235,255,139,136,235,139,185,235,139,131,235,139,147,235,137,
163 135,235,131,252,248,4,139,131,235,137,151,235,137,135,235,15,131,245,251,
164 249,4,254,2,249,5,252,246,130,235,237,15,132,245,4,252,246,129,235,237,15,
165 132,245,4,232,245,29,233,245,4,254,0,251,15,249,29,137,84,36,12,137,76,36,
166 8,137,116,36,4,233,244,255,251,15,249,30,139,142,235,139,185,235,139,135,
167 235,139,184,235,233,245,255,255,251,15,249,31,131,191,235,5,139,191,235,15,
168 133,245,18,249,9,15,182,143,235,184,1,0,0,0,211,224,72,35,130,235,193,224,
169 5,3,135,235,249,1,131,184,235,4,15,133,245,248,57,144,235,15,133,245,248,
170 139,136,235,133,201,15,132,245,249,255,252,243,15,126,128,235,102,15,214,
171 131,235,255,139,144,235,139,184,235,137,147,235,137,187,235,255,137,139,235,
172 139,158,235,195,249,2,139,128,235,133,192,15,133,245,1,49,201,249,3,139,135,
173 235,133,192,15,132,245,250,252,246,128,235,237,15,132,245,251,249,4,137,139,
174 235,139,158,235,195,249,5,137,150,235,199,134,235,4,0,0,0,139,12,36,131,252,
175 236,12,137,142,235,137,52,36,137,124,36,4,137,92,36,8,232,244,131,196,12,
176 139,158,235,255,251,15,249,32,139,135,235,193,224,4,11,129,235,131,252,248,
177 84,139,191,235,139,145,235,15,132,245,9,233,245,18,255,251,15,249,33,139,
178 142,235,128,167,235,237,139,145,235,137,185,235,137,151,235,195,255,251,15,
179 249,34,139,142,235,139,185,235,139,135,235,139,184,235,233,245,255,255,251,
180 15,249,35,131,191,235,5,139,191,235,15,133,245,18,249,9,15,182,143,235,184,
181 1,0,0,0,211,224,72,35,130,235,193,224,5,3,135,235,249,1,131,184,235,4,15,
182 133,245,250,57,144,235,15,133,245,250,131,184,235,0,15,132,245,252,249,2,
183 198,135,235,0,249,3,255,252,246,135,235,237,15,133,245,254,249,7,255,139,
184 139,235,252,243,15,126,131,235,137,136,235,102,15,214,128,235,255,139,139,
185 235,139,147,235,139,187,235,137,136,235,137,144,235,137,184,235,255,139,158,
186 235,195,249,8,232,245,33,233,245,7,249,4,139,128,235,133,192,15,133,245,1,
187 139,143,235,133,201,15,132,245,251,252,246,129,235,237,15,132,245,253,249,
188 5,141,134,235,137,144,235,199,128,235,4,0,0,0,131,252,236,12,137,52,36,137,
189 124,36,4,137,68,36,8,232,244,131,196,12,233,245,2,249,6,255,139,143,235,133,
190 201,15,132,245,2,252,246,129,235,237,15,133,245,2,249,7,137,150,235,199,134,
191 235,4,0,0,0,139,12,36,131,252,236,12,137,142,235,137,52,36,137,124,36,4,137,
192 92,36,8,232,244,131,196,12,139,158,235,195,255,251,15,249,36,139,135,235,
193 193,224,4,11,129,235,131,252,248,84,139,191,235,139,145,235,15,132,245,9,
194 233,245,18,255,137,52,36,199,68,36,4,239,199,68,36,8,239,232,244,137,131,
195 235,199,131,235,5,0,0,0,255,186,239,255,232,245,30,255,232,245,34,255,141,
196 187,235,186,239,255,141,187,235,141,139,235,255,131,187,235,5,139,187,235,
197 15,133,245,255,185,239,139,135,235,59,143,235,15,135,245,251,255,139,131,
198 235,193,224,4,11,131,235,131,252,248,83,15,133,245,255,255,252,242,15,16,
199 131,235,252,242,15,44,192,252,242,15,42,200,72,102,15,46,200,139,187,235,
200 15,133,245,255,15,138,245,255,255,221,131,235,219,20,36,219,4,36,255,223,
201 233,221,216,255,218,233,223,224,158,255,15,133,245,255,15,138,245,255,139,
202 4,36,139,187,235,72,255,59,135,235,15,131,245,251,193,224,4,3,135,235,255,
203 232,245,31,255,232,245,32,255,185,239,255,141,147,235,255,199,134,235,239,
204 83,81,82,86,232,244,131,196,16,139,158,235,255,249,1,139,144,235,133,210,
205 15,132,245,252,255,139,136,235,139,128,235,137,139,235,137,131,235,255,249,
206 2,137,147,235,254,2,232,245,37,255,232,245,38,255,233,245,1,249,6,139,143,
207 235,133,201,15,132,245,2,252,246,129,235,237,15,133,245,2,249,9,186,239,233,
208 245,19,254,0,251,15,249,37,137,76,36,4,131,252,236,12,137,60,36,137,76,36,
209 4,232,244,131,196,12,139,76,36,4,193,225,4,41,200,129,192,241,195,255,251,
210 15,249,38,64,137,124,36,4,137,68,36,8,233,244,255,187,239,255,232,245,35,
211 255,232,245,36,255,199,134,235,239,82,81,83,86,232,244,131,196,16,139,158,
212 235,255,249,1,131,184,235,0,15,132,245,252,249,2,254,2,232,245,39,255,232,
213 245,40,255,252,246,135,235,237,15,133,245,253,249,3,254,2,249,7,232,245,33,
214 233,245,3,254,0,199,128,235,0,0,0,0,255,186,1,0,0,0,137,144,235,137,144,235,
215 255,199,128,235,0,0,0,0,199,128,235,1,0,0,0,255,221,152,235,199,128,235,3,
216 0,0,0,255,199,128,235,239,199,128,235,4,0,0,0,255,251,15,249,39,137,76,36,
217 4,131,252,236,12,137,52,36,137,124,36,4,137,76,36,8,232,244,131,196,12,139,
218 76,36,4,193,225,4,41,200,129,192,241,195,255,251,15,249,40,64,137,116,36,
219 4,137,124,36,8,137,68,36,12,233,244,255,137,190,235,141,131,235,41,252,248,
220 252,247,216,193,252,248,4,139,187,235,15,132,245,250,255,129,192,241,255,
221 57,135,235,15,131,245,247,137,52,36,137,124,36,4,137,68,36,8,232,244,249,
222 1,252,246,135,235,237,139,151,235,15,133,245,252,139,190,235,254,2,249,6,
223 232,245,33,233,245,1,254,0,139,187,235,129,191,235,241,15,130,245,251,249,
224 1,252,246,135,235,237,139,151,235,15,133,245,252,141,187,235,254,2,249,5,
225 137,52,36,137,124,36,4,199,68,36,8,239,232,244,233,245,1,249,6,232,245,33,
226 233,245,1,254,0,129,194,241,255,141,139,235,249,3,139,1,131,193,4,137,2,131,
227 194,4,57,252,249,15,130,245,3,249,4,255,131,187,235,3,139,131,235,15,133,
228 245,255,133,192,15,136,245,255,255,221,131,235,221,5,239,255,221,5,239,221,
229 131,235,255,139,131,235,193,224,4,11,131,235,131,252,248,51,139,131,235,15,
230 133,245,255,11,131,235,15,136,245,255,221,131,235,221,131,235,255,131,187,
231 235,3,15,133,245,255,221,131,235,255,216,200,255,217,192,216,200,255,220,
232 201,255,222,201,255,199,4,36,239,199,68,36,4,239,199,68,36,8,239,131,187,
233 235,3,15,133,245,255,219,44,36,220,139,235,217,192,217,252,252,220,233,217,
234 201,217,252,240,217,232,222,193,217,252,253,221,217,255,251,15,249,41,217,
235 232,221,68,36,8,217,252,241,139,68,36,4,219,56,195,255,131,187,235,3,15,133,
236 245,255,255,131,187,235,3,255,139,131,235,193,224,4,11,131,235,131,252,248,
237 51,255,216,192,255,220,131,235,255,220,163,235,255,220,171,235,255,220,139,
238 235,255,220,179,235,255,220,187,235,255,131,252,236,16,221,28,36,221,131,
239 235,221,92,36,8,232,244,131,196,16,255,131,252,236,16,221,92,36,8,221,131,
240 235,221,28,36,232,244,131,196,16,255,217,224,255,15,138,246,255,15,130,246,
241 255,15,134,246,255,15,135,246,255,15,131,246,255,199,134,235,239,137,52,36,
242 137,76,36,4,137,84,36,8,232,244,133,192,139,158,235,255,15,132,246,255,199,
243 134,235,239,199,4,36,239,82,81,83,86,232,244,131,196,16,139,158,235,255,131,
244 187,235,5,139,139,235,15,133,245,9,137,12,36,232,244,137,4,36,219,4,36,221,
245 155,235,199,131,235,3,0,0,0,255,131,187,235,4,139,139,235,15,133,245,9,219,
246 129,235,221,155,235,199,131,235,3,0,0,0,255,199,134,235,239,137,52,36,137,
247 92,36,4,137,76,36,8,232,244,139,158,235,255,139,131,235,139,139,235,186,1,
248 0,0,0,33,193,209,232,9,193,49,192,57,209,17,192,137,147,235,137,131,235,255,
249 232,245,42,137,131,235,199,131,235,4,0,0,0,255,199,134,235,239,137,52,36,
250 199,68,36,4,239,199,68,36,8,239,232,244,139,158,235,255,251,15,249,42,137,
251 116,36,4,139,131,235,193,224,4,11,131,235,131,232,68,15,133,245,18,249,1,
252 139,190,235,139,179,235,139,147,235,139,142,235,133,201,15,132,245,248,11,
253 130,235,15,132,245,250,1,200,15,130,245,255,59,135,235,15,135,245,251,139,
254 191,235,129,198,241,255,252,243,164,139,138,235,141,178,235,252,243,164,41,
255 199,139,116,36,4,137,124,36,8,137,68,36,12,139,158,235,233,244,249,2,137,
256 208,249,3,139,116,36,4,139,158,235,195,249,4,137,252,240,233,245,3,249,5,
257 139,116,36,4,141,143,235,131,252,236,12,137,52,36,137,76,36,4,137,68,36,8,
258 232,244,131,196,12,49,192,233,245,1,249,9,139,116,36,4,233,245,18,255,131,
259 187,235,0,255,139,131,235,139,139,235,72,73,9,200,255,139,131,235,72,11,131,
260 235,255,131,187,235,3,15,133,246,221,131,235,221,5,239,255,131,187,235,4,
261 15,133,246,129,187,235,239,255,139,131,235,59,131,235,15,133,246,255,131,
262 252,248,3,15,133,245,9,221,131,235,221,131,235,255,131,252,248,4,15,133,245,
263 9,139,139,235,59,139,235,255,141,147,235,141,139,235,199,134,235,239,137,
264 52,36,137,76,36,4,137,84,36,8,232,244,72,139,158,235,255,139,131,235,139,
265 139,235,137,194,33,202,141,20,80,209,234,255,15,132,245,247,255,15,133,245,
266 247,255,139,147,235,137,131,235,137,139,235,137,147,235,233,246,249,1,255,
267 139,131,235,193,224,4,11,131,235,131,252,248,51,15,133,245,255,249,4,221,
268 131,235,221,131,235,221,147,235,255,249,4,139,131,235,193,224,4,11,131,235,
269 193,224,4,11,131,235,61,51,3,0,0,139,131,235,15,133,245,255,221,131,235,221,
270 131,235,133,192,221,147,235,15,136,245,247,217,201,249,1,255,199,131,235,
271 3,0,0,0,15,130,246,255,249,9,141,131,235,199,134,235,239,137,52,36,137,68,
272 36,4,232,244,233,245,4,254,0,221,131,235,221,131,235,220,131,235,221,147,
273 235,221,147,235,199,131,235,3,0,0,0,255,139,131,235,221,131,235,221,131,235,
274 221,131,235,222,193,221,147,235,221,147,235,199,131,235,3,0,0,0,133,192,15,
275 136,245,247,217,201,249,1,255,131,187,235,0,15,132,245,247,255,141,131,235,
276 137,68,36,4,255,137,92,36,4,255,139,187,235,255,139,142,235,139,185,235,139,
277 191,235,255,139,151,235,137,52,36,199,68,36,4,239,137,84,36,8,232,244,199,
278 128,235,239,137,131,235,199,131,235,6,0,0,0,255,139,151,235,137,144,235,255,
279 137,52,36,232,244,137,135,235,255,249,1,139,142,235,139,145,235,129,194,241,
280 141,132,253,27,235,41,208,59,134,235,15,131,245,251,141,187,235,57,218,15,
281 131,245,249,249,2,139,2,131,194,4,137,7,131,199,4,57,218,15,130,245,2,249,
282 3,254,2,249,5,43,134,235,193,252,248,4,137,52,36,137,68,36,4,232,244,139,
283 158,235,233,245,1,254,0,139,142,235,139,145,235,129,194,241,141,187,235,141,
284 139,235,57,218,15,131,245,248,249,1,139,2,131,194,4,137,7,131,199,4,57,207,
285 15,131,245,250,57,218,15,130,245,1,249,2,49,192,249,3,137,135,235,129,199,
286 241,57,207,15,130,245,3,249,4,255
287};
288
289enum {
290 JSUB_STACKPTR,
291 JSUB_GATE_LJ,
292 JSUB_GATE_JL,
293 JSUB_GATE_JC,
294 JSUB_GROW_STACK,
295 JSUB_GROW_CI,
296 JSUB_GATE_JC_PATCH,
297 JSUB_GATE_JC_DEBUG,
298 JSUB_DEOPTIMIZE_CALLER,
299 JSUB_DEOPTIMIZE,
300 JSUB_DEOPTIMIZE_OPEN,
301 JSUB_HOOKINS,
302 JSUB_GCSTEP,
303 JSUB_STRING_SUB3,
304 JSUB_STRING_SUB2,
305 JSUB_HOOKCALL,
306 JSUB_HOOKRET,
307 JSUB_METACALL,
308 JSUB_METATAILCALL,
309 JSUB_BARRIERF,
310 JSUB_GETGLOBAL,
311 JSUB_GETTABLE_KSTR,
312 JSUB_GETTABLE_STR,
313 JSUB_BARRIERBACK,
314 JSUB_SETGLOBAL,
315 JSUB_SETTABLE_KSTR,
316 JSUB_SETTABLE_STR,
317 JSUB_GETTABLE_KNUM,
318 JSUB_GETTABLE_NUM,
319 JSUB_SETTABLE_KNUM,
320 JSUB_SETTABLE_NUM,
321 JSUB_LOG2_TWORD,
322 JSUB_CONCAT_STR2,
323 JSUB__MAX
324};
325
326/* ------------------------------------------------------------------------ */
327
328/* Arch string. */
329const char luaJIT_arch[] = "x86";
330
331/* Forward declarations for C functions called from jsubs. */
332static void jit_hookins(lua_State *L, const Instruction *newpc);
333static void jit_gettable_fb(lua_State *L, Table *t, StkId dest);
334static void jit_settable_fb(lua_State *L, Table *t, StkId val);
335
336/* ------------------------------------------------------------------------ */
337
338/* Detect CPU features and set JIT flags. */
339static int jit_cpudetect(jit_State *J)
340{
341 void *mcode;
342 size_t sz;
343 int status;
344 /* Some of the jsubs need the flags. So compile this separately. */
345 unsigned int feature;
346 dasm_setup(Dst, jit_actionlist);
347 dasm_put(Dst, 0);
348 (void)dasm_checkstep(Dst, DASM_SECTION_CODE);
349 status = luaJIT_link(J, &mcode, &sz);
350 if (status != JIT_S_OK)
351 return status;
352 /* Check feature bits. See the Intel/AMD manuals for the bit definitions. */
353 feature = ((unsigned int (*)(void))mcode)();
354 if (feature & (1<<15)) J->flags |= JIT_F_CPU_CMOV;
355 if (feature & (1<<26)) J->flags |= JIT_F_CPU_SSE2;
356 luaJIT_freemcode(J, mcode, sz); /* We don't need this code anymore. */
357 return JIT_S_OK;
358}
359
360/* Check some assumptions. Should compile to nop. */
361static int jit_consistency_check(jit_State *J)
362{
363 do {
364 /* Force a compiler error for inconsistent structure sizes. */
365 /* Check LUA_TVALUE_ALIGN in luaconf.h, too. */
366 int check_TVALUE_SIZE_in_ljit_x86_dash[1+16-sizeof(TValue)];
367 int check_TVALUE_SIZE_in_ljit_x86_dash_[1+sizeof(TValue)-16];
368 ((void)check_TVALUE_SIZE_in_ljit_x86_dash[0]);
369 ((void)check_TVALUE_SIZE_in_ljit_x86_dash_[0]);
370 if (LUA_TNIL != 0 || LUA_TBOOLEAN != 1 || PCRLUA != 0) break;
371 if ((int)&(((Node *)0)->i_val) != (int)&(((StkId)0)->value)) break;
372 return JIT_S_OK;
373 } while (0);
374 J->dasmstatus = 999999999; /* Recognizable error. */
375 return JIT_S_COMPILER_ERROR;
376}
377
378/* Compile JIT subroutines (once). */
379static int jit_compile_jsub(jit_State *J)
380{
381 int status = jit_consistency_check(J);
382 if (status != JIT_S_OK) return status;
383 status = jit_cpudetect(J);
384 if (status != JIT_S_OK) return status;
385 dasm_setup(Dst, jit_actionlist);
386 dasm_put(Dst, 34);
387 dasm_put(Dst, 36, Dt1(->top), Dt2(->value), Dt1(->ci), Dt1(->nCcalls), Dt5(->jit_gate), Dt1(->ci), Dt1(->top), Dt4(->savedpc), Dt1(->savedpc), Dt4(->base), Dt1(->base), Dt1(->top), Dt3(->tt), sizeof(TValue));
388 dasm_put(Dst, 145, Dt1(->nCcalls), PCRC, Dt5(->p), DtE(->jit_status), JIT_S_OK, DtE(->jit_mcode), Dt5(->jit_gate), Dt4(->savedpc), Dt1(->ci), Dt1(->top), Dt1(->savedpc), Dt1(->stack), (ptrdiff_t)(luaD_precall), (ptrdiff_t)(luaV_execute), Dt1(->stack));
389 dasm_put(Dst, 262, Dt1(->top), Dt3([LUA_MINSTACK]), Dt1(->stack_last), Dt1(->end_ci), Dt4([1]), Dt1(->ci), Dt4(->func), Dt4(->top), Dt2(->value), sizeof(TValue), Dt1(->top), Dt1(->base), Dt4(->base), DtD(->f), Dt1(->ci));
390 dasm_put(Dst, 336, Dt4(->func), Dt1(->top), Dt4(->func), sizeof(CallInfo), Dt1(->ci), Dt1(->hookmask), LUA_MASKCALL, DtD(->f), Dt1(->hookmask), LUA_MASKRET);
391 dasm_put(Dst, 421, LUA_HOOKRET, (ptrdiff_t)(luaD_callhook), LUA_HOOKCALL, (ptrdiff_t)(luaD_callhook), Dt1(->top), Dt1(->stack), (ptrdiff_t)(luaD_growstack), Dt1(->stack), Dt1(->top), Dt2(->value), Dt5(->jit_gate), Dt1(->top), (ptrdiff_t)(luaD_growCI), Dt9([-1]));
392 dasm_put(Dst, 547, Dt2(->value), Dt1(->ci), Dt5(->jit_gate));
393 dasm_put(Dst, 602, Dt1(->hookmask), LUA_MASKLINE|LUA_MASKCOUNT, Dt1(->hookcount), Dt1(->hookmask), LUA_MASKLINE, (ptrdiff_t)(jit_hookins), Dt1(->base), Dt1(->top));
394 dasm_put(Dst, 737, (ptrdiff_t)(luaC_step), Dt1(->base));
395 dasm_put(Dst, 1026, Dt3([0].tt), Dt3([1].tt), Dt3([2].tt), Dt3([1].value), Dt3([2].value), Dt3([0].value), DtB(->tsv.len), sizeof(TString)-1, Dt1(->l_G), Dt6(->totalbytes));
396 dasm_put(Dst, 1129, Dt6(->GCthreshold), (ptrdiff_t)(luaS_newlstr));
397 dasm_put(Dst, 1191, Dt3([0].tt), Dt3([1].tt), Dt3([1].value), Dt3([0].value), DtB(->tsv.len), (ptrdiff_t)(luaC_step), Dt1(->base), (ptrdiff_t)(luaS_newlstr));
398 dasm_put(Dst, 1755, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->p), DtE(->code), Dt1(->savedpc), LUA_HOOKCALL, (ptrdiff_t)(luaD_callhook), DtE(->code), Dt1(->savedpc), Dt1(->base));
399 dasm_put(Dst, 1886, Dt1(->savedpc), LUA_HOOKRET, (ptrdiff_t)(luaD_callhook), Dt1(->base), Dt1(->top));
400 dasm_put(Dst, 2077, Dt1(->savedpc), Dt1(->top), (ptrdiff_t)(luaD_tryfuncTM), Dt1(->top), Dt2(->value), Dt1(->ci));
401 dasm_put(Dst, 2178, Dt1(->savedpc), Dt1(->top), (ptrdiff_t)(luaD_tryfuncTM), Dt1(->ci), Dt1(->top), Dt4(->func), Dt4(->func), Dt2(->value), sizeof(CallInfo), Dt5(->jit_gate));
402 dasm_put(Dst, 2570, (ptrdiff_t)(luaC_barrierf));
403 dasm_put(Dst, 2589, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->env));
404 dasm_put(Dst, 2609, Dt3(->tt), Dt3(->value), DtC(->lsizenode), DtB(->tsv.hash), DtC(->node), Dt10(->i_key.nk.tt), Dt10(->i_key.nk.value), Dt10(->i_val.tt));
405 if (J->flags & JIT_F_CPU_SSE2) {
406 dasm_put(Dst, 2674, Dt10(->i_val.value), Dt2(->value));
407 } else {
408 dasm_put(Dst, 2686, Dt10(->i_val.value), Dt10(->i_val.value.na[1]), Dt2(->value), Dt2(->value.na[1]));
409 }
410 dasm_put(Dst, 2699, Dt2(->tt), Dt1(->base), Dt10(->i_key.nk.next), DtC(->metatable), DtC(->flags), 1<<TM_INDEX, Dt2([0].tt), Dt1(->base), Dt1(->env.value), Dt1(->env.tt), Dt1(->savedpc), (ptrdiff_t)(jit_gettable_fb), Dt1(->base));
411 dasm_put(Dst, 32);
412 dasm_put(Dst, 2790, Dt3(->tt), Dt7(->tt), Dt3(->value), Dt7(->value));
413 dasm_put(Dst, 2821, Dt1(->l_G), DtC(->marked), (~bitmask(BLACKBIT))&0xff, Dt6(->grayagain), Dt6(->grayagain), DtC(->gclist));
414 dasm_put(Dst, 2843, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->env));
415 dasm_put(Dst, 2863, Dt3(->tt), Dt3(->value), DtC(->lsizenode), DtB(->tsv.hash), DtC(->node), Dt10(->i_key.nk.tt), Dt10(->i_key.nk.value), Dt10(->i_val.tt), DtC(->flags));
416 dasm_put(Dst, 2935, DtC(->marked), bitmask(BLACKBIT));
417 if (J->flags & JIT_F_CPU_SSE2) {
418 dasm_put(Dst, 2947, Dt2([0].tt), Dt2([0].value), Dt7([0].tt), Dt7([0].value));
419 } else {
420 dasm_put(Dst, 2965, Dt2([0].value), Dt2([0].value.na[1]), Dt2([0].tt), Dt7([0].value), Dt7([0].value.na[1]), Dt7([0].tt));
421 }
422 dasm_put(Dst, 2984, Dt1(->base), Dt10(->i_key.nk.next), DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, Dt1(->env), Dt7([0].value), Dt7([0].tt), (ptrdiff_t)(luaH_newkey));
423 dasm_put(Dst, 3066, DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, Dt1(->env.value), Dt1(->env.tt), Dt1(->savedpc), (ptrdiff_t)(jit_settable_fb), Dt1(->base));
424 dasm_put(Dst, 3127, Dt3(->tt), Dt7(->tt), Dt3(->value), Dt7(->value));
425 dasm_put(Dst, 3438, (ptrdiff_t)(luaH_getnum), sizeof(TValue));
426 dasm_put(Dst, 3476, (ptrdiff_t)(luaH_getnum));
427 dasm_put(Dst, 3623, (ptrdiff_t)(luaH_setnum), sizeof(TValue));
428 dasm_put(Dst, 3665, (ptrdiff_t)(luaH_setnum));
429 dasm_put(Dst, 3992);
430 dasm_put(Dst, 4325, Dt2([0].tt), Dt2([1].tt), Dt1(->l_G), Dt2([0].value), Dt2([1].value), DtB(->tsv.len), DtB(->tsv.len), Dt6(->buff.buffsize), Dt6(->buff.buffer), sizeof(TString));
431 dasm_put(Dst, 4396, DtB(->tsv.len), DtB([1]), Dt1(->base), (ptrdiff_t)(luaS_newlstr), Dt1(->base), Dt6(->buff), (ptrdiff_t)(luaZ_openspace));
432 dasm_put(Dst, 561, Dt1(->top), Dt1(->savedpc), (ptrdiff_t)(luaJIT_deoptimize), Dt1(->base), Dt1(->top));
433
434 (void)dasm_checkstep(Dst, DASM_SECTION_CODE);
435 status = luaJIT_link(J, &J->jsubmcode, &J->szjsubmcode);
436 if (status != JIT_S_OK)
437 return status;
438
439 /* Copy the callgates from the globals to the global state. */
440 G(J->L)->jit_gateLJ = (luaJIT_GateLJ)J->jsub[JSUB_GATE_LJ];
441 G(J->L)->jit_gateJL = (lua_CFunction)J->jsub[JSUB_GATE_JL];
442 G(J->L)->jit_gateJC = (lua_CFunction)J->jsub[JSUB_GATE_JC];
443 return JIT_S_OK;
444}
445
446/* Match with number of nops above. Avoid confusing the instruction decoder. */
447#define DEBUGPATCH_SIZE 6
448
449/* Notify backend that the debug mode may have changed. */
450void luaJIT_debugnotify(jit_State *J)
451{
452 unsigned char *patch = (unsigned char *)J->jsub[JSUB_GATE_JC_PATCH];
453 unsigned char *target = (unsigned char *)J->jsub[JSUB_GATE_JC_DEBUG];
454 /* Yep, this is self-modifying code -- don't tell anyone. */
455 if (patch[0] == 0xe9) { /* Debug patch is active. */
456 if (!(J->flags & JIT_F_DEBUG_CALL)) /* Deactivate it. */
457 memcpy(patch, target-DEBUGPATCH_SIZE, DEBUGPATCH_SIZE);
458 } else { /* Debug patch is inactive. */
459 if (J->flags & JIT_F_DEBUG_CALL) { /* Activate it. */
460 int rel = target-(patch+5);
461 memcpy(target-DEBUGPATCH_SIZE, patch, DEBUGPATCH_SIZE);
462 patch[0] = 0xe9; /* jmp */
463 memcpy(patch+1, &rel, 4); /* Relative address. */
464 memset(patch+5, 0x90, DEBUGPATCH_SIZE-5); /* nop */
465 }
466 }
467}
468
469/* Patch a jmp into existing mcode. */
470static void jit_patch_jmp(jit_State *J, void *mcode, void *to)
471{
472 unsigned char *patch = (unsigned char *)mcode;
473 int rel = ((unsigned char *)to)-(patch+5);
474 patch[0] = 0xe9; /* jmp */
475 memcpy((void *)(patch+1), &rel, 4); /* Relative addr. */
476}
477
478/* ------------------------------------------------------------------------ */
479
480/* Call line/count hook. */
481static void jit_hookins(lua_State *L, const Instruction *newpc)
482{
483 Proto *pt = ci_func(L->ci)->l.p;
484 int pc = luaJIT_findpc(pt, newpc); /* Sloooow with mcode addrs. */
485 const Instruction *savedpc = L->savedpc;
486 L->savedpc = pt->code + pc + 1;
487 if (L->hookmask > LUA_MASKLINE && L->hookcount == 0) {
488 resethookcount(L);
489 luaD_callhook(L, LUA_HOOKCOUNT, -1);
490 }
491 if (L->hookmask & LUA_MASKLINE) {
492 int newline = getline(pt, pc);
493 if (pc != 0) {
494 int oldpc = luaJIT_findpc(pt, savedpc);
495 if (!(pc <= oldpc || newline != getline(pt, oldpc))) return;
496 }
497 luaD_callhook(L, LUA_HOOKLINE, newline);
498 }
499}
500
501/* Insert hook check for each instruction in full debug mode. */
502static void jit_ins_debug(jit_State *J, int openop)
503{
504 if (openop) {
505 dasm_put(Dst, 594, Dt1(->top));
506 }
507 dasm_put(Dst, 598);
508
509}
510
511/* Called before every instruction. */
512static void jit_ins_start(jit_State *J)
513{
514 dasm_put(Dst, 663, J->nextpc);
515}
516
517/* Chain to another instruction. */
518static void jit_ins_chainto(jit_State *J, int pc)
519{
520 dasm_put(Dst, 665, pc);
521}
522
523/* Set PC label. */
524static void jit_ins_setpc(jit_State *J, int pc, void *target)
525{
526 dasm_put(Dst, 668, pc, (ptrdiff_t)(target));
527}
528
529/* Called after the last instruction has been encoded. */
530static void jit_ins_last(jit_State *J, int lastpc, int sizemfm)
531{
532 if (J->tflags & JIT_TF_USED_DEOPT) { /* Deopt section has been used? */
533 dasm_put(Dst, 671);
534 dasm_put(Dst, 673);
535 }
536 dasm_put(Dst, 678, lastpc+1);
537 dasm_put(Dst, 681, lastpc+2);
538 dasm_put(Dst, 690, sizemfm);
539}
540
541/* Add a deoptimize target for the current instruction. */
542static void jit_deopt_target(jit_State *J, int nargs)
543{
544 if (nargs != -1) {
545 dasm_put(Dst, 671);
546 dasm_put(Dst, 702, (ptrdiff_t)(J->nextins));
547 J->tflags |= JIT_TF_USED_DEOPT;
548 } else {
549 dasm_put(Dst, 679);
550 dasm_put(Dst, 709, (ptrdiff_t)(J->nextins));
551 }
552}
553
554/* luaC_checkGC() inlined. Destroys caller-saves + TOP (edi). Uses label 7:. */
555/* Use this only at the _end_ of an instruction. */
556static void jit_checkGC(jit_State *J)
557{
558 dasm_put(Dst, 718, Dt1(->l_G), Dt6(->totalbytes), Dt6(->GCthreshold));
559
560}
561
562/* ------------------------------------------------------------------------ */
563
564
565
566/*
567** Function inlining support for x86 CPUs.
568** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
569*/
570
571/* ------------------------------------------------------------------------ */
572
573/* Private structure holding function inlining info. */
574typedef struct jit_InlineInfo {
575 int func; /* Function slot. 1st arg slot = func+1. */
576 int res; /* 1st result slot. Overlaps func/ci->func. */
577 int nargs; /* Number of args. */
578 int nresults; /* Number of results. */
579 int xnargs; /* Expected number of args. */
580 int xnresults; /* Returned number of results. */
581 int hidx; /* Library/function index numbers. */
582} jit_InlineInfo;
583
584/* ------------------------------------------------------------------------ */
585
586enum { TFOR_FUNC, TFOR_TAB, TFOR_CTL, TFOR_KEY, TFOR_VAL };
587
588static void jit_inline_base(jit_State *J, jit_InlineInfo *ii)
589{
590 int func = ii->func;
591 switch (JIT_IH_IDX(ii->hidx)) {
592 case JIT_IH_BASE_PAIRS:
593 case JIT_IH_BASE_IPAIRS:
594 dasm_put(Dst, 753, Dt2([func+TFOR_TAB].tt), Dt2([func+TFOR_CTL].tt), Dt2([func+TFOR_CTL].value));
595 dasm_put(Dst, 771, JIT_MFM_DEOPT_PAIRS, J->nextpc-1);
596 break;
597 default:
598 jit_assert(0);
599 break;
600 }
601}
602
603/* ------------------------------------------------------------------------ */
604
605#ifndef COCO_DISABLE
606
607/* Helper function for inlined coroutine.resume(). */
608static StkId jit_coroutine_resume(lua_State *L, StkId base, int nresults)
609{
610 lua_State *co = thvalue(base-1);
611 /* Check for proper usage. Merge of lua_resume() and auxresume() checks. */
612 if (co->status != LUA_YIELD) {
613 if (co->status > LUA_YIELD) {
614errdead:
615 setsvalue(L, base-1, luaS_newliteral(L, "cannot resume dead coroutine"));
616 goto err;
617 } else if (co->ci != co->base_ci) {
618 setsvalue(L, base-1,
619 luaS_newliteral(L, "cannot resume non-suspended coroutine"));
620 goto err;
621 } else if (co->base == co->top) {
622 goto errdead;
623 }
624 }
625 {
626 ptrdiff_t ndelta = (char *)L->top - (char *)base;
627 int nargs = ndelta/sizeof(TValue); /* Compute nargs. */
628 int status;
629 if ((char *)co->stack_last-(char *)co->top <= ndelta) {
630 co->ci->top = (StkId)(((char *)co->top) + ndelta); /* Ok before grow. */
631 luaD_growstack(co, nargs); /* Grow thread stack. */
632 }
633 /* Copy args. */
634 co->top = (StkId)(((char *)co->top) + ndelta);
635 { StkId t = co->top, f = L->top; while (f > base) setobj2s(co, --t, --f); }
636 L->top = base;
637 status = luaCOCO_resume(co, nargs); /* Resume Coco thread. */
638 if (status == 0 || status == LUA_YIELD) { /* Ok. */
639 StkId f;
640 if (nresults == 0) return NULL;
641 if (nresults == -1) {
642 luaD_checkstack(L, co->top - co->base); /* Grow own stack. */
643 }
644 base = L->top - 2;
645 setbvalue(base++, 1); /* true */
646 /* Copy results. Fill unused result slots with nil. */
647 f = co->base;
648 while (--nresults != 0 && f < co->top) setobj2s(L, base++, f++);
649 while (nresults-- > 0) setnilvalue(base++);
650 co->top = co->base;
651 return base;
652 } else { /* Error. */
653 base = L->top;
654 setobj2s(L, base-1, co->top-1); /* Copy error object. */
655err:
656 setbvalue(base-2, 0); /* false */
657 nresults -= 2;
658 while (--nresults >= 0) setnilvalue(base+nresults); /* Fill results. */
659 return base;
660 }
661 }
662}
663
664static void jit_inline_coroutine(jit_State *J, jit_InlineInfo *ii)
665{
666 int arg = ii->func+1;
667 int res = ii->res;
668 int i;
669 switch (JIT_IH_IDX(ii->hidx)) {
670 case JIT_IH_COROUTINE_YIELD:
671 dasm_put(Dst, 775, ((int)&LHASCOCO((lua_State *)0)), Dt1(->savedpc), (ptrdiff_t)(J->nextins), arg*sizeof(TValue));
672 if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */
673 dasm_put(Dst, 791, Dt2([ii->nargs]));
674 }
675 dasm_put(Dst, 795, Dt1(->base), Dt1(->top), (ptrdiff_t)(luaCOCO_yield), Dt1(->base), Dt1(->top));
676 jit_assert(ii->nresults >= 0 && ii->nresults <= EXTRA_STACK);
677 for (i = 0; i < ii->nresults; i++) {
678 dasm_put(Dst, 813, Dt3([i].tt));
679 if (J->flags & JIT_F_CPU_SSE2) {
680 dasm_put(Dst, 821, Dt2([arg+i].tt), Dt2([arg+i].value), Dt2([res+i].tt), Dt2([res+i].value));
681 } else {
682 dasm_put(Dst, 839, Dt2([arg+i].value), Dt2([arg+i].value.na[1]), Dt2([arg+i].tt), Dt2([res+i].value), Dt2([res+i].value.na[1]), Dt2([res+i].tt));
683 }
684 }
685 ii->nargs = -1; /* Force restore of L->top. */
686 break;
687 case JIT_IH_COROUTINE_RESUME:
688 jit_assert(ii->nargs != 0 && ii->res == ii->func);
689 dasm_put(Dst, 787, (arg+1)*sizeof(TValue));
690 if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */
691 dasm_put(Dst, 791, Dt2([ii->nargs-1]));
692 } else {
693 dasm_put(Dst, 858);
694 }
695 dasm_put(Dst, 865, Dt2([-1].tt), Dt2([-1].value), ((int)&LHASCOCO((lua_State *)0)), Dt1(->savedpc), (ptrdiff_t)(J->nextins), Dt1(->top), ii->nresults, (ptrdiff_t)(jit_coroutine_resume), Dt1(->base));
696 if (ii->nresults == -1) {
697 dasm_put(Dst, 909);
698 }
699 ii->nargs = -1; /* Force restore of L->top. */
700 break;
701 default:
702 jit_assert(0);
703 break;
704 }
705}
706
707#endif /* COCO_DISABLE */
708
709/* ------------------------------------------------------------------------ */
710
711static void jit_inline_string(jit_State *J, jit_InlineInfo *ii)
712{
713 int arg = ii->func+1;
714 int res = ii->res;
715 switch (JIT_IH_IDX(ii->hidx)) {
716 case JIT_IH_STRING_LEN:
717 dasm_put(Dst, 912, Dt2([arg].tt), Dt2([arg].value), DtB(->tsv.len), Dt2([res].tt), Dt2([res].value));
718 break;
719 case JIT_IH_STRING_SUB:
720 /* TODO: inline numeric constants with help from the optimizer. */
721 /* But this would save only another 15-20% in a trivial loop. */
722 jit_assert(ii->nargs >= 2); /* Open op caveat is ok, too. */
723 if (ii->nargs > 2) {
724 dasm_put(Dst, 937, Dt2([arg]), Dt2([res].value), Dt2([res].tt));
725 } else {
726 dasm_put(Dst, 954, Dt2([arg]), Dt2([res].value), Dt2([res].tt));
727 }
728 break;
729 case JIT_IH_STRING_CHAR:
730 dasm_put(Dst, 971, Dt2([arg].tt), Dt1(->env), Dt2([arg].value), (ptrdiff_t)(luaS_newlstr), Dt2([res].value), Dt2([res].tt));
731 break;
732 default:
733 jit_assert(0);
734 break;
735 }
736
737}
738
739/* ------------------------------------------------------------------------ */
740
741/* Helper functions for inlined calls to table.*. */
742static void jit_table_insert(lua_State *L, TValue *arg)
743{
744 setobj2t(L, luaH_setnum(L, hvalue(arg), luaH_getn(hvalue(arg))+1), arg+1);
745 luaC_barriert(L, hvalue(arg), arg+1);
746}
747
748static TValue *jit_table_remove(lua_State *L, TValue *arg, TValue *res)
749{
750 int n = luaH_getn(hvalue(arg));
751 if (n == 0) {
752 setnilvalue(res); /* For the nresults == 1 case. Harmless otherwise. */
753 return res; /* For the nresults == -1 case. */
754 } else {
755 TValue *val = luaH_setnum(L, hvalue(arg), n);
756 setobj2s(L, res, val);
757 setnilvalue(val);
758 return res+1; /* For the nresults == -1 case. */
759 }
760}
761
762static void jit_inline_table(jit_State *J, jit_InlineInfo *ii)
763{
764 int arg = ii->func+1;
765 int res = ii->res;
766 dasm_put(Dst, 1250, Dt2([arg].tt));
767 switch (JIT_IH_IDX(ii->hidx)) {
768 case JIT_IH_TABLE_INSERT:
769 dasm_put(Dst, 1259, Dt2([arg]), (ptrdiff_t)(jit_table_insert));
770 break;
771 case JIT_IH_TABLE_REMOVE:
772 dasm_put(Dst, 1272, Dt2([arg]), Dt2([res]), (ptrdiff_t)(jit_table_remove));
773 if (ii->nresults == -1) {
774 ii->xnresults = -1;
775 dasm_put(Dst, 909);
776 }
777 break;
778 case JIT_IH_TABLE_GETN:
779 dasm_put(Dst, 1292, Dt2([arg].value), (ptrdiff_t)(luaH_getn), Dt2([res].value), Dt2([res].tt));
780 break;
781 default:
782 jit_assert(0);
783 break;
784 }
785}
786
787/* ------------------------------------------------------------------------ */
788
789/* This typedef must match the libm function signature. */
790/* Serves as a check against wrong lua_Number or wrong calling conventions. */
791typedef lua_Number (*mathfunc_11)(lua_Number);
792
793/* Partially inlined math functions. */
794/* CHECK: must match with jit_hints.h and jit.opt_lib. */
795static const mathfunc_11 jit_mathfuncs_11[JIT_IH_MATH_SIN] = {
796 log, log10, exp, sinh, cosh, tanh, asin, acos, atan
797};
798
799/* FPU control words for ceil and floor (exceptions masked, full precision). */
800static const unsigned short jit_fpucw[2] = { 0x0b7f, 0x077f };
801
802static void jit_inline_math(jit_State *J, jit_InlineInfo *ii)
803{
804 int arg = ii->func+1;
805 int res = ii->res;
806 int idx = JIT_IH_IDX(ii->hidx);
807
808 if (idx < JIT_IH_MATH__21) {
809 dasm_put(Dst, 1317, Dt2([arg].tt), Dt2([arg].value));
810 } else {
811 jit_assert(idx < JIT_IH_MATH__LAST);
812 dasm_put(Dst, 1329, Dt2([arg].tt), Dt2([arg+1].tt));
813 }
814 switch (idx) {
815 /* We ignore sin/cos/tan range overflows (2^63 rad) just like -ffast-math. */
816 case JIT_IH_MATH_SIN:
817 dasm_put(Dst, 1347);
818 break;
819 case JIT_IH_MATH_COS:
820 dasm_put(Dst, 1351);
821 break;
822 case JIT_IH_MATH_TAN:
823 dasm_put(Dst, 1355);
824 break;
825 case JIT_IH_MATH_CEIL:
826 case JIT_IH_MATH_FLOOR:
827 dasm_put(Dst, 1361, (ptrdiff_t)&jit_fpucw[idx-JIT_IH_MATH_CEIL]);
828 break;
829 case JIT_IH_MATH_ABS:
830 dasm_put(Dst, 1374);
831 break;
832 case JIT_IH_MATH_SQRT:
833 dasm_put(Dst, 1377);
834 break;
835 case JIT_IH_MATH_FMOD:
836 dasm_put(Dst, 1381, Dt2([arg+1].value), Dt2([arg].value));
837 break;
838 case JIT_IH_MATH_ATAN2:
839 dasm_put(Dst, 1402, Dt2([arg].value), Dt2([arg+1].value));
840 break;
841 default:
842 dasm_put(Dst, 1412, (ptrdiff_t)(jit_mathfuncs_11[idx]));
843 break;
844 }
845 dasm_put(Dst, 926, Dt2([res].tt), Dt2([res].value));
846}
847
848/* ------------------------------------------------------------------------ */
849
850/* Try to inline a CALL or TAILCALL instruction. */
851static int jit_inline_call(jit_State *J, int func, int nargs, int nresults)
852{
853 const TValue *callable = hint_get(J, TYPE); /* TYPE hint = callable. */
854 int cltype = ttype(callable);
855 const TValue *oidx;
856 jit_InlineInfo ii;
857 int idx;
858
859 if (cltype != LUA_TFUNCTION) goto fail;
860 if (J->flags & JIT_F_DEBUG) goto fail; /* DWIM. */
861
862 oidx = hint_get(J, INLINE); /* INLINE hint = library/function index. */
863 if (!ttisnumber(oidx)) goto fail;
864
865 ii.hidx = (int)nvalue(oidx);
866 idx = JIT_IH_IDX(ii.hidx);
867
868 if (nresults == -2) { /* Tailcall. */
869 /* Tailcalls from vararg functions don't work with BASE[-1]. */
870 if (J->pt->is_vararg) goto fail; /* So forget about this rare case. */
871 ii.res = -1; /* Careful: 2nd result overlaps 1st stack slot. */
872 ii.nresults = -1;
873 } else {
874 ii.res = func;
875 ii.nresults = nresults;
876 }
877 ii.func = func;
878 ii.nargs = nargs;
879 ii.xnargs = ii.xnresults = 1; /* Default: 1 arg, 1 result. */
880
881 /* Check for the currently supported cases. */
882 switch (JIT_IH_LIB(ii.hidx)) {
883 case JIT_IHLIB_BASE:
884 switch (idx) {
885 case JIT_IH_BASE_PAIRS:
886 case JIT_IH_BASE_IPAIRS:
887 if (nresults == -2) goto fail; /* Not useful for tailcalls. */
888 ii.xnresults = 3;
889 goto check;
890 }
891 break;
892#ifndef COCO_DISABLE
893 case JIT_IHLIB_COROUTINE:
894 switch (idx) {
895 case JIT_IH_COROUTINE_YIELD:
896 /* Only support common cases: no tailcalls, low number of results. */
897 if (nresults < 0 || nresults > EXTRA_STACK) goto fail;
898 ii.xnargs = ii.xnresults = -1;
899 goto ok; /* Anything else is ok. */
900 case JIT_IH_COROUTINE_RESUME:
901 /* Only support common cases: no tailcalls, not with 0 args (error). */
902 if (nresults == -2 || nargs == 0) goto fail;
903 ii.xnargs = ii.xnresults = -1;
904 goto ok; /* Anything else is ok. */
905 }
906 break;
907#endif
908 case JIT_IHLIB_STRING:
909 switch (idx) {
910 case JIT_IH_STRING_LEN:
911 goto check;
912 case JIT_IH_STRING_SUB:
913 if (nargs < 2) goto fail; /* No support for open calls, too. */
914 goto ok; /* 2 or more args are ok. */
915 case JIT_IH_STRING_CHAR:
916 goto check; /* Only single arg supported. */
917 }
918 break;
919 case JIT_IHLIB_TABLE:
920 switch (idx) {
921 case JIT_IH_TABLE_INSERT:
922 ii.xnargs = 2;
923 goto check; /* Only push (append) supported. */
924 case JIT_IH_TABLE_REMOVE:
925 goto check; /* Only pop supported. */
926 case JIT_IH_TABLE_GETN:
927 goto check;
928 }
929 break;
930 case JIT_IHLIB_MATH:
931 if (idx >= JIT_IH_MATH__LAST) goto fail;
932 if (idx >= JIT_IH_MATH__21) ii.xnargs = 2;
933 goto check;
934 }
935fail:
936 return cltype; /* Call could not be inlined. Return type of callable. */
937
938check:
939 if (nargs != ii.xnargs && nargs != -1) goto fail;
940 /* The optimizer already checks the number of results (avoid setnil). */
941
942ok: /* Whew, all checks done. Go for it! */
943
944 /* Start with the common leadin for inlined calls. */
945 jit_deopt_target(J, nargs);
946 dasm_put(Dst, 1418, Dt2([func].tt), Dt2([func].value), (ptrdiff_t)(clvalue(callable)));
947 if (nargs == -1 && ii.xnargs >= 0) {
948 dasm_put(Dst, 1435, Dt2([func+1+ii.xnargs]));
949 }
950
951 /* Now inline the function itself. */
952 switch (JIT_IH_LIB(ii.hidx)) {
953 case JIT_IHLIB_BASE: jit_inline_base(J, &ii); break;
954#ifndef COCO_DISABLE
955 case JIT_IHLIB_COROUTINE: jit_inline_coroutine(J, &ii); break;
956#endif
957 case JIT_IHLIB_STRING: jit_inline_string(J, &ii); break;
958 case JIT_IHLIB_TABLE: jit_inline_table(J, &ii); break;
959 case JIT_IHLIB_MATH: jit_inline_math(J, &ii); break;
960 default: jit_assert(0); break;
961 }
962
963 /* And add the common leadout for inlined calls. */
964 if (ii.nresults == -1) {
965 if (ii.xnresults >= 0) {
966 dasm_put(Dst, 791, Dt2([ii.res+ii.xnresults]));
967 }
968 } else if (ii.nargs == -1) { /* Restore L->top only if needed. */
969 dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top));
970 }
971
972 if (nresults == -2) { /* Results are in place. Add return for tailcalls. */
973 dasm_put(Dst, 1452, sizeof(TValue), Dt1(->ci), sizeof(CallInfo));
974 }
975
976 return -1; /* Success, call has been inlined. */
977}
978
979/* ------------------------------------------------------------------------ */
980
981/* Helper function for inlined iterator code. Paraphrased from luaH_next. */
982/* TODO: GCC has trouble optimizing this. */
983static int jit_table_next(lua_State *L, TValue *ra)
984{
985 Table *t = hvalue(&ra[TFOR_TAB]);
986 int i = ra[TFOR_CTL].value.b; /* Hidden control variable. */
987 for (; i < t->sizearray; i++) { /* First the array part. */
988 if (!ttisnil(&t->array[i])) {
989 setnvalue(&ra[TFOR_KEY], cast_num(i+1));
990 setobj2s(L, &ra[TFOR_VAL], &t->array[i]);
991 ra[TFOR_CTL].value.b = i+1;
992 return 1;
993 }
994 }
995 for (i -= t->sizearray; i < sizenode(t); i++) { /* Then the hash part. */
996 if (!ttisnil(gval(gnode(t, i)))) {
997 setobj2s(L, &ra[TFOR_KEY], key2tval(gnode(t, i)));
998 setobj2s(L, &ra[TFOR_VAL], gval(gnode(t, i)));
999 ra[TFOR_CTL].value.b = i+1+t->sizearray;
1000 return 1;
1001 }
1002 }
1003 return 0; /* End of iteration. */
1004}
1005
1006/* Try to inline a TFORLOOP instruction. */
1007static int jit_inline_tforloop(jit_State *J, int ra, int nresults, int target)
1008{
1009 const TValue *oidx = hint_get(J, INLINE); /* INLINE hint = lib/func idx. */
1010 int idx;
1011
1012 if (!ttisnumber(oidx)) return 0; /* No hint: don't inline anything. */
1013 idx = (int)nvalue(oidx);
1014 if (J->flags & JIT_F_DEBUG) return 0; /* DWIM. */
1015
1016 switch (idx) {
1017 case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_PAIRS):
1018 dasm_put(Dst, 1465, Dt2([ra]), (ptrdiff_t)(jit_table_next), target);
1019 return 1; /* Success, iterator has been inlined. */
1020 case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_IPAIRS):
1021 dasm_put(Dst, 1483, Dt2([ra+TFOR_CTL].value), Dt2([ra+TFOR_TAB].value), Dt2([ra+TFOR_CTL].value), (ptrdiff_t)(luaH_getnum), Dt7(->tt), Dt2([ra+TFOR_CTL].value), Dt2([ra+TFOR_KEY].tt), Dt2([ra+TFOR_KEY].value), Dt7(->value), Dt7(->value.na[1]), Dt2([ra+TFOR_VAL].tt), Dt2([ra+TFOR_VAL].value), Dt2([ra+TFOR_VAL].value.na[1]), target);
1022 return 1; /* Success, iterator has been inlined. */
1023 }
1024
1025 return 0; /* No support for inlining any other iterators. */
1026}
1027
1028/* ------------------------------------------------------------------------ */
1029
1030
1031
1032#ifdef LUA_COMPAT_VARARG
1033static void jit_vararg_table(lua_State *L)
1034{
1035 Table *tab;
1036 StkId base, func;
1037 int i, num, numparams;
1038 luaC_checkGC(L);
1039 base = L->base;
1040 func = L->ci->func;
1041 numparams = clvalue(func)->l.p->numparams;
1042 num = base - func - numparams - 1;
1043 tab = luaH_new(L, num, 1);
1044 for (i = 0; i < num; i++)
1045 setobj2n(L, luaH_setnum(L, tab, i+1), base - num + i);
1046 setnvalue(luaH_setstr(L, tab, luaS_newliteral(L, "n")), (lua_Number)num);
1047 sethvalue(L, base + numparams, tab);
1048}
1049#endif
1050
1051/* Encode JIT function prologue. */
1052static void jit_prologue(jit_State *J)
1053{
1054 Proto *pt = J->pt;
1055 int numparams = pt->numparams;
1056 int stacksize = pt->maxstacksize;
1057
1058 dasm_put(Dst, 1544, Dt3([stacksize]), Dt1(->stack_last), Dt1(->end_ci), Dt4([1]), Dt4(->func), sizeof(TValue), Dt1(->ci));
1059
1060 if (numparams > 0) {
1061 dasm_put(Dst, 1580, Dt2([numparams]));
1062 }
1063
1064 if (!pt->is_vararg) { /* Fixarg function. */
1065 /* Must cap L->top at L->base+numparams because 1st LOADNIL is omitted. */
1066 if (numparams == 0) {
1067 dasm_put(Dst, 1586);
1068 } else if (J->flags & JIT_F_CPU_CMOV) {
1069 dasm_put(Dst, 1589);
1070 } else {
1071 dasm_put(Dst, 1594);
1072 }
1073 dasm_put(Dst, 1603, Dt2([stacksize]), Dt4(->tailcalls), Dt4(->top), Dt1(->top), Dt1(->base), Dt4(->base));
1074 } else { /* Vararg function. */
1075 int i;
1076 if (numparams > 0) {
1077 dasm_put(Dst, 1622);
1078 dasm_put(Dst, 1630, Dt3(->tt), sizeof(TValue));
1079 }
1080 dasm_put(Dst, 1649, Dt1(->base), Dt4(->base), Dt4(->tailcalls));
1081 for (i = 0; i < numparams; i++) { /* Move/clear fixargs. */
1082 if (J->flags & JIT_F_CPU_SSE2) {
1083 dasm_put(Dst, 1659, Dt2([i].tt), Dt2([i].value), Dt3([i].tt), Dt3([i].value));
1084 } else {
1085 dasm_put(Dst, 1677, Dt2([i].value), Dt2([i].value.na[1]), Dt3([i].value), Dt2([i].tt), Dt3([i].value.na[1]), Dt3([i].tt));
1086 }
1087 dasm_put(Dst, 854, Dt2([i].tt));
1088 }
1089 if (numparams > 0) {
1090 dasm_put(Dst, 332, Dt1(->ci));
1091 }
1092 dasm_put(Dst, 1696, Dt2([stacksize]), Dt2([numparams]), Dt4(->top), Dt1(->top));
1093 stacksize -= numparams; /* Fixargs are already cleared. */
1094 }
1095
1096 /* Clear undefined args and all vars. Still assumes eax = LUA_TNIL = 0. */
1097 /* Note: cannot clear only args because L->top has grown. */
1098 if (stacksize <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */
1099 int i;
1100 for (i = 0; i < stacksize; i++) {
1101 dasm_put(Dst, 1712, Dt3([i].tt));
1102 }
1103 } else { /* Standard loop. */
1104 dasm_put(Dst, 1716, Dt3([0].tt), Dt3([1].tt), 2*sizeof(TValue));
1105 }
1106
1107#ifdef LUA_COMPAT_VARARG
1108 if (pt->is_vararg & VARARG_NEEDSARG) {
1109 dasm_put(Dst, 1734, (ptrdiff_t)(jit_vararg_table));
1110 }
1111#endif
1112
1113 /* Call hook check. */
1114 if (J->flags & JIT_F_DEBUG_CALL) {
1115 dasm_put(Dst, 1740, Dt1(->hookmask), LUA_MASKCALL);
1116
1117 }
1118}
1119
1120/* Check if we can combine 'return const'. */
1121static int jit_return_k(jit_State *J)
1122{
1123 if (!J->combine) return 0; /* COMBINE hint set? */
1124 /* May need to close open upvalues. */
1125 if (!fhint_isset(J, NOCLOSE)) {
1126 dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close));
1127 }
1128 if (!J->pt->is_vararg) { /* Fixarg function. */
1129 dasm_put(Dst, 1830, Dt1(->ci), sizeof(CallInfo), sizeof(TValue));
1130 } else { /* Vararg function. */
1131 dasm_put(Dst, 1844, Dt1(->ci), Dt4(->func), sizeof(CallInfo), Dt1(->ci), Dt2([1]));
1132 }
1133 jit_assert(J->combine == 1); /* Required to skip next RETURN instruction. */
1134 return 1;
1135}
1136
1137static void jit_op_return(jit_State *J, int rbase, int nresults)
1138{
1139 /* Return hook check. */
1140 if (J->flags & JIT_F_DEBUG_CALL) {
1141 if (nresults < 0 && !(J->flags & JIT_F_DEBUG_INS)) {
1142 dasm_put(Dst, 594, Dt1(->top));
1143 }
1144 dasm_put(Dst, 1863, Dt1(->hookmask), LUA_MASKRET);
1145 if (J->flags & JIT_F_DEBUG_INS) {
1146 dasm_put(Dst, 1878, Dt1(->savedpc));
1147 }
1148
1149 }
1150
1151 /* May need to close open upvalues. */
1152 if (!fhint_isset(J, NOCLOSE)) {
1153 dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close));
1154 }
1155
1156 /* Previous op was open: 'return f()' or 'return ...' */
1157 if (nresults < 0) {
1158 dasm_put(Dst, 332, Dt1(->ci));
1159 if (rbase) {
1160 dasm_put(Dst, 787, rbase*sizeof(TValue));
1161 }
1162 dasm_put(Dst, 1933, Dt4(->func), Dt4(->func), sizeof(CallInfo), Dt1(->ci));
1163 return;
1164 }
1165
1166 if (!J->pt->is_vararg) { /* Fixarg function, nresults >= 0. */
1167 int i;
1168 dasm_put(Dst, 1980, Dt1(->ci), sizeof(CallInfo), sizeof(TValue));
1169 for (i = 0; i < nresults; i++) {
1170 if (J->flags & JIT_F_CPU_SSE2) {
1171 dasm_put(Dst, 821, Dt2([rbase+i+1].tt), Dt2([rbase+i+1].value), Dt2([i].tt), Dt2([i].value));
1172 } else {
1173 dasm_put(Dst, 839, Dt2([rbase+i+1].value), Dt2([rbase+i+1].value.na[1]), Dt2([rbase+i+1].tt), Dt2([i].value), Dt2([i].value.na[1]), Dt2([i].tt));
1174 }
1175 }
1176 dasm_put(Dst, 1989, Dt2([nresults]));
1177 } else { /* Vararg function, nresults >= 0. */
1178 int i;
1179 dasm_put(Dst, 1997, Dt1(->ci), Dt4(->func), sizeof(CallInfo), Dt1(->ci));
1180 for (i = 0; i < nresults; i++) {
1181 if (J->flags & JIT_F_CPU_SSE2) {
1182 dasm_put(Dst, 1659, Dt2([rbase+i].tt), Dt2([rbase+i].value), Dt3([i].tt), Dt3([i].value));
1183 } else {
1184 dasm_put(Dst, 2010, Dt2([rbase+i].value), Dt2([rbase+i].value.na[1]), Dt2([rbase+i].tt), Dt3([i].value), Dt3([i].value.na[1]), Dt3([i].tt));
1185 }
1186 }
1187 dasm_put(Dst, 2029);
1188 if (nresults) {
1189 dasm_put(Dst, 2036, nresults*sizeof(TValue));
1190 }
1191 dasm_put(Dst, 32);
1192 }
1193}
1194
1195static void jit_op_call(jit_State *J, int func, int nargs, int nresults)
1196{
1197 int cltype = jit_inline_call(J, func, nargs, nresults);
1198 if (cltype < 0) return; /* Inlined? */
1199
1200 if (func) {
1201 dasm_put(Dst, 787, func*sizeof(TValue));
1202 }
1203 dasm_put(Dst, 2040, Dt1(->ci), Dt2([0].tt));
1204 if (nargs >= 0) { /* Previous op was not open and did not set TOP. */
1205 dasm_put(Dst, 791, Dt2([1+nargs]));
1206 }
1207 dasm_put(Dst, 2048, Dt2(->value), (ptrdiff_t)(J->nextins), Dt4(->savedpc));
1208 if (cltype == LUA_TFUNCTION) {
1209 if (nargs == -1) {
1210 dasm_put(Dst, 2057);
1211 } else {
1212 dasm_put(Dst, 2062);
1213 }
1214 } else {
1215 dasm_put(Dst, 2067);
1216
1217 }
1218 dasm_put(Dst, 2116, Dt5(->jit_gate));
1219 if (func) {
1220 dasm_put(Dst, 1984, func*sizeof(TValue));
1221 }
1222 dasm_put(Dst, 2121, Dt1(->base));
1223
1224 /* Clear undefined results TOP <= o < func+nresults. */
1225 if (nresults > 0) {
1226 dasm_put(Dst, 2125);
1227 if (nresults <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */
1228 int i;
1229 for (i = 0; i < nresults; i++) {
1230 dasm_put(Dst, 1712, Dt3([i].tt));
1231 }
1232 } else { /* Standard loop. TODO: move to .tail? */
1233 dasm_put(Dst, 2128, Dt2([func+nresults]), Dt3([0].tt), Dt3([1].tt), 2*sizeof(TValue));
1234 }
1235 }
1236
1237 if (nresults >= 0) { /* Not an open ins. Restore L->top. */
1238 dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top));
1239 } /* Otherwise keep TOP for next instruction. */
1240}
1241
1242static void jit_op_tailcall(jit_State *J, int func, int nargs)
1243{
1244 int cltype;
1245
1246 if (!fhint_isset(J, NOCLOSE)) { /* May need to close open upvalues. */
1247 dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close));
1248 }
1249
1250 cltype = jit_inline_call(J, func, nargs, -2);
1251 if (cltype < 0) goto finish; /* Inlined? */
1252
1253 if (cltype == LUA_TFUNCTION) {
1254 jit_deopt_target(J, nargs);
1255 dasm_put(Dst, 2149, Dt2([func].tt));
1256 } else {
1257 dasm_put(Dst, 2158, Dt2([func].tt));
1258 dasm_put(Dst, 2168);
1259 if (func) {
1260 dasm_put(Dst, 787, func*sizeof(TValue));
1261 }
1262 if (nargs >= 0) {
1263 dasm_put(Dst, 791, Dt2([1+nargs]));
1264 }
1265 dasm_put(Dst, 2171, (ptrdiff_t)(J->nextins));
1266
1267 }
1268
1269 if (nargs >= 0) { /* Previous op was not open and did not set TOP. */
1270 int i;
1271 /* Relocate [BASE+func, BASE+func+nargs] -> [ci->func, ci->func+nargs]. */
1272 /* TODO: loop for large nargs? */
1273 if (!J->pt->is_vararg) { /* Fixarg function. */
1274 dasm_put(Dst, 2241, Dt2([func].value));
1275 for (i = 0; i < nargs; i++) {
1276 if (J->flags & JIT_F_CPU_SSE2) {
1277 dasm_put(Dst, 821, Dt2([func+1+i].tt), Dt2([func+1+i].value), Dt2([i].tt), Dt2([i].value));
1278 } else {
1279 dasm_put(Dst, 2245, Dt2([func+1+i].value), Dt2([func+1+i].value.na[1]), Dt2([i].value), Dt2([func+1+i].tt), Dt2([i].value.na[1]), Dt2([i].tt));
1280 }
1281 }
1282 dasm_put(Dst, 2264, Dt2([nargs]), sizeof(TValue), Dt1(->ci), Dt2(->value));
1283 } else { /* Vararg function. */
1284 dasm_put(Dst, 2278, Dt1(->ci), Dt2([func]), Dt4(->func), Dt3(->value), Dt2(->value));
1285 for (i = 0; i < nargs; i++) {
1286 if (J->flags & JIT_F_CPU_SSE2) {
1287 dasm_put(Dst, 2294, Dt3([i+1].tt), Dt3([i+1].value), Dt2([i+1].tt), Dt2([i+1].value));
1288 } else {
1289 dasm_put(Dst, 2312, Dt3([i+1].value), Dt3([i+1].value.na[1]), Dt2([i+1].value), Dt3([i+1].tt), Dt2([i+1].value.na[1]), Dt2([i+1].tt));
1290 }
1291 }
1292 dasm_put(Dst, 2331, Dt2([1+nargs]), Dt2(->value));
1293 }
1294 } else { /* Previous op was open and set TOP. */
1295 dasm_put(Dst, 332, Dt1(->ci));
1296 if (func) {
1297 dasm_put(Dst, 787, func*sizeof(TValue));
1298 }
1299 dasm_put(Dst, 2338, Dt4(->func), Dt4(->func), Dt2(->value));
1300 }
1301 dasm_put(Dst, 2230, sizeof(CallInfo), Dt5(->jit_gate));
1302
1303finish:
1304 J->combine++; /* Combine with following return instruction. */
1305}
1306
1307/* ------------------------------------------------------------------------ */
1308
1309static void jit_op_move(jit_State *J, int dest, int src)
1310{
1311 if (J->flags & JIT_F_CPU_SSE2) {
1312 dasm_put(Dst, 821, Dt2([src].tt), Dt2([src].value), Dt2([dest].tt), Dt2([dest].value));
1313 } else {
1314 dasm_put(Dst, 839, Dt2([src].value), Dt2([src].value.na[1]), Dt2([src].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt));
1315 }
1316}
1317
1318static void jit_op_loadk(jit_State *J, int dest, int kidx)
1319{
1320 const TValue *kk = &J->pt->k[kidx];
1321 int rk = jit_return_k(J);
1322 if (rk) dest = 0;
1323 switch (ttype(kk)) {
1324 case 0:
1325 dasm_put(Dst, 2369, Dt2([dest].tt));
1326 break;
1327 case 1:
1328 if (bvalue(kk)) { /* true */
1329 dasm_put(Dst, 2377, Dt2([dest].value), Dt2([dest].tt));
1330 } else { /* false */
1331 dasm_put(Dst, 2389, Dt2([dest].value), Dt2([dest].tt));
1332 }
1333 break;
1334 case 3: {
1335 if ((&(kk)->value)->n == (lua_Number)0) {
1336 dasm_put(Dst, 2404);
1337 } else if ((&(kk)->value)->n == (lua_Number)1) {
1338 dasm_put(Dst, 2408);
1339 } else {
1340 dasm_put(Dst, 2411, &(kk)->value);
1341 }
1342 dasm_put(Dst, 1306, Dt2([dest].value), Dt2([dest].tt));
1343 break;
1344 }
1345 case 4:
1346 dasm_put(Dst, 2415, Dt2([dest].value), (ptrdiff_t)(gcvalue(kk)), Dt2([dest].tt));
1347 break;
1348 default: lua_assert(0); break;
1349 }
1350 if (rk) {
1351 dasm_put(Dst, 32);
1352 }
1353}
1354
1355static void jit_op_loadnil(jit_State *J, int first, int last)
1356{
1357 int idx, num = last - first + 1;
1358 int rk = jit_return_k(J);
1359 dasm_put(Dst, 2125);
1360 if (rk) {
1361 dasm_put(Dst, 2427, Dt2([0].tt));
1362 } else if (num <= 8) {
1363 for (idx = first; idx <= last; idx++) {
1364 dasm_put(Dst, 854, Dt2([idx].tt));
1365 }
1366 } else {
1367 dasm_put(Dst, 2432, Dt2([first].tt), Dt2([last].tt), sizeof(TValue));
1368 }
1369}
1370
1371static void jit_op_loadbool(jit_State *J, int dest, int b, int dojump)
1372{
1373 int rk = jit_return_k(J);
1374 if (rk) dest = 0;
1375 if (b) { /* true */
1376 dasm_put(Dst, 2377, Dt2([dest].value), Dt2([dest].tt));
1377 } else { /* false */
1378 dasm_put(Dst, 2389, Dt2([dest].value), Dt2([dest].tt));
1379 }
1380 if (rk) {
1381 dasm_put(Dst, 32);
1382 } else if (dojump) {
1383 const TValue *h = hint_getpc(J, COMBINE, J->nextpc);
1384 if (!(ttisboolean(h) && bvalue(h) == 0)) { /* Avoid jmp around dead ins. */
1385 dasm_put(Dst, 665, J->nextpc+1);
1386 }
1387 }
1388}
1389
1390/* ------------------------------------------------------------------------ */
1391
1392static void jit_op_getupval(jit_State *J, int dest, int uvidx)
1393{
1394 if (!J->pt->is_vararg) {
1395 dasm_put(Dst, 2241, Dt2([-1].value));
1396 } else {
1397 dasm_put(Dst, 2452, Dt1(->ci), Dt4(->func), Dt3(->value));
1398 }
1399 dasm_put(Dst, 2462, Dt5(->upvals[uvidx]), DtF(->v));
1400 if (J->flags & JIT_F_CPU_SSE2) {
1401 dasm_put(Dst, 2469, Dt3([0].tt), Dt3([0].value), Dt2([dest].tt), Dt2([dest].value));
1402 } else {
1403 dasm_put(Dst, 2487, Dt3([0].value), Dt3([0].value.na[1]), Dt3([0].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt));
1404 }
1405}
1406
1407static void jit_op_setupval(jit_State *J, int src, int uvidx)
1408{
1409 if (!J->pt->is_vararg) {
1410 dasm_put(Dst, 2241, Dt2([-1].value));
1411 } else {
1412 dasm_put(Dst, 2452, Dt1(->ci), Dt4(->func), Dt3(->value));
1413 }
1414 dasm_put(Dst, 2506, Dt5(->upvals[uvidx]), DtF(->v), Dt2([src].tt), Dt2([src].value), Dt3(->tt), Dt2([src].value.na[1]), Dt3(->value), Dt3(->value.na[1]));
1415 dasm_put(Dst, 2542, DtA(->gch.marked), WHITEBITS, DtF(->marked), bitmask(BLACKBIT));
1416
1417}
1418
1419/* ------------------------------------------------------------------------ */
1420
1421/* Optimized table lookup routines. Enter via jsub, fallback to C. */
1422
1423/* Fallback for GETTABLE_*. Temporary key is in L->env. */
1424static void jit_gettable_fb(lua_State *L, Table *t, StkId dest)
1425{
1426 Table *mt = t->metatable;
1427 const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_INDEX]);
1428 if (ttisnil(tm)) { /* No __index method? */
1429 mt->flags |= 1<<TM_INDEX; /* Cache this fact. */
1430 setnilvalue(dest);
1431 } else if (ttisfunction(tm)) { /* __index function? */
1432 ptrdiff_t destr = savestack(L, dest);
1433 setobj2s(L, L->top, tm);
1434 sethvalue(L, L->top+1, t);
1435 setobj2s(L, L->top+2, &L->env);
1436 luaD_checkstack(L, 3);
1437 L->top += 3;
1438 luaD_call(L, L->top - 3, 1);
1439 dest = restorestack(L, destr);
1440 L->top--;
1441 setobjs2s(L, dest, L->top);
1442 } else { /* Let luaV_gettable() continue with the __index object. */
1443 luaV_gettable(L, tm, &L->env, dest);
1444 }
1445
1446}
1447
1448/* Fallback for SETTABLE_*STR. Temporary (string) key is in L->env. */
1449static void jit_settable_fb(lua_State *L, Table *t, StkId val)
1450{
1451 Table *mt = t->metatable;
1452 const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_NEWINDEX]);
1453 if (ttisnil(tm)) { /* No __newindex method? */
1454 mt->flags |= 1<<TM_NEWINDEX; /* Cache this fact. */
1455 t->flags = 0; /* But need to clear the cache for the table itself. */
1456 setobj2t(L, luaH_setstr(L, t, rawtsvalue(&L->env)), val);
1457 luaC_barriert(L, t, val);
1458 } else if (ttisfunction(tm)) { /* __newindex function? */
1459 setobj2s(L, L->top, tm);
1460 sethvalue(L, L->top+1, t);
1461 setobj2s(L, L->top+2, &L->env);
1462 setobj2s(L, L->top+3, val);
1463 luaD_checkstack(L, 4);
1464 L->top += 4;
1465 luaD_call(L, L->top - 4, 0);
1466 } else { /* Let luaV_settable() continue with the __newindex object. */
1467 luaV_settable(L, tm, &L->env, val);
1468 }
1469
1470}
1471
1472/* ------------------------------------------------------------------------ */
1473
1474static void jit_op_newtable(jit_State *J, int dest, int lnarray, int lnhash)
1475{
1476 dasm_put(Dst, 3158, luaO_fb2int(lnarray), luaO_fb2int(lnhash), (ptrdiff_t)(luaH_new), Dt2([dest].value), Dt2([dest].tt));
1477 jit_checkGC(J);
1478}
1479
1480static void jit_op_getglobal(jit_State *J, int dest, int kidx)
1481{
1482 const TValue *kk = &J->pt->k[kidx];
1483 jit_assert(ttisstring(kk));
1484 dasm_put(Dst, 3184, (ptrdiff_t)(&kk->value.gc->ts));
1485 if (dest) {
1486 dasm_put(Dst, 787, dest*sizeof(TValue));
1487 }
1488 dasm_put(Dst, 3187);
1489}
1490
1491static void jit_op_setglobal(jit_State *J, int rval, int kidx)
1492{
1493 const TValue *kk = &J->pt->k[kidx];
1494 jit_assert(ttisstring(kk));
1495 dasm_put(Dst, 3184, (ptrdiff_t)(&kk->value.gc->ts));
1496 if (rval) {
1497 dasm_put(Dst, 787, rval*sizeof(TValue));
1498 }
1499 dasm_put(Dst, 3191);
1500}
1501
1502enum { TKEY_KSTR = -2, TKEY_STR = -1, TKEY_ANY = 0 };
1503
1504/* Optimize key lookup depending on consts or hints type. */
1505static int jit_keylookup(jit_State *J, int tab, int rkey)
1506{
1507 const TValue *tabt = hint_get(J, TYPE);
1508 const TValue *key;
1509 if (!ttistable(tabt)) return TKEY_ANY; /* Not a table? Use fallback. */
1510 key = ISK(rkey) ? &J->pt->k[INDEXK(rkey)] : hint_get(J, TYPEKEY);
1511 if (ttisstring(key)) { /* String key? */
1512 if (ISK(rkey)) {
1513 dasm_put(Dst, 3195, Dt2([tab]), (ptrdiff_t)(&key->value.gc->ts));
1514 return TKEY_KSTR; /* Const string key. */
1515 } else {
1516 dasm_put(Dst, 3201, Dt2([tab]), Dt2([rkey]));
1517 return TKEY_STR; /* Var string key. */
1518 }
1519 } else if (ttisnumber(key)) { /* Number key? */
1520 lua_Number n = nvalue(key);
1521 int k;
1522 lua_number2int(k, n);
1523 if (!(k >= 1 && k < (1 << 26) && (lua_Number)k == n))
1524 return TKEY_ANY; /* Not a proper array key? Use fallback. */
1525 if (ISK(rkey)) {
1526 dasm_put(Dst, 3208, Dt2([tab].tt), Dt2([tab].value), k, DtC(->array), DtC(->sizearray));
1527 return k; /* Const array key (>= 1). */
1528 } else {
1529 dasm_put(Dst, 3232, Dt2([tab].tt), Dt2([rkey].tt));
1530 if (J->flags & JIT_F_CPU_SSE2) {
1531 dasm_put(Dst, 3250, Dt2([rkey]), Dt2([tab].value));
1532 } else {
1533 dasm_put(Dst, 3283, Dt2([rkey].value));
1534 if (J->flags & JIT_F_CPU_CMOV) {
1535 dasm_put(Dst, 3293);
1536 } else {
1537 dasm_put(Dst, 3298);
1538 }
1539 dasm_put(Dst, 3304, Dt2([tab].value));
1540 }
1541 dasm_put(Dst, 3320, DtC(->sizearray), DtC(->array));
1542 return 1; /* Variable array key. */
1543 }
1544 }
1545 return TKEY_ANY; /* Use fallback. */
1546}
1547
1548static void jit_op_gettable(jit_State *J, int dest, int tab, int rkey)
1549{
1550 int k = jit_keylookup(J, tab, rkey);
1551 switch (k) {
1552 case TKEY_KSTR: /* Const string key. */
1553 if (dest) {
1554 dasm_put(Dst, 787, dest*sizeof(TValue));
1555 }
1556 dasm_put(Dst, 3334);
1557 break;
1558 case TKEY_STR: /* Variable string key. */
1559 if (dest) {
1560 dasm_put(Dst, 787, dest*sizeof(TValue));
1561 }
1562 dasm_put(Dst, 3338);
1563 break;
1564 case TKEY_ANY: /* Generic gettable fallback. */
1565 if (ISK(rkey)) {
1566 dasm_put(Dst, 3342, (ptrdiff_t)(&J->pt->k[INDEXK(rkey)]));
1567 } else {
1568 dasm_put(Dst, 3204, Dt2([rkey]));
1569 }
1570 dasm_put(Dst, 3345, Dt2([tab]));
1571 if (dest) {
1572 dasm_put(Dst, 787, dest*sizeof(TValue));
1573 }
1574 dasm_put(Dst, 3349, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_gettable), Dt1(->base));
1575 break;
1576 default: /* Array key. */
1577 dasm_put(Dst, 3366, Dt7([k-1].tt));
1578 if (J->flags & JIT_F_CPU_SSE2) {
1579 dasm_put(Dst, 2674, Dt7([k-1].value), Dt2([dest].value));
1580 } else {
1581 dasm_put(Dst, 3378, Dt7([k-1].value), Dt7([k-1].value.na[1]), Dt2([dest].value), Dt2([dest].value.na[1]));
1582 }
1583 dasm_put(Dst, 3391, Dt2([dest].tt));
1584 dasm_put(Dst, 2168);
1585 if (ISK(rkey)) {
1586 dasm_put(Dst, 3398);
1587 } else {
1588 dasm_put(Dst, 3402);
1589 }
1590 dasm_put(Dst, 3406, DtC(->metatable), DtC(->flags), 1<<TM_INDEX, (ptrdiff_t)(J->nextins));
1591 break;
1592 }
1593
1594}
1595
1596static void jit_op_settable(jit_State *J, int tab, int rkey, int rval)
1597{
1598 const TValue *val = ISK(rval) ? &J->pt->k[INDEXK(rval)] : NULL;
1599 int k = jit_keylookup(J, tab, rkey);
1600 switch (k) {
1601 case TKEY_KSTR: /* Const string key. */
1602 case TKEY_STR: /* Variable string key. */
1603 if (ISK(rval)) {
1604 dasm_put(Dst, 3492, (ptrdiff_t)(val));
1605 } else {
1606 if (rval) {
1607 dasm_put(Dst, 787, rval*sizeof(TValue));
1608 }
1609 }
1610 if (k == TKEY_KSTR) {
1611 dasm_put(Dst, 3495);
1612 } else {
1613 dasm_put(Dst, 3499);
1614 }
1615 break;
1616 case TKEY_ANY: /* Generic settable fallback. */
1617 if (ISK(rkey)) {
1618 dasm_put(Dst, 3342, (ptrdiff_t)(&J->pt->k[INDEXK(rkey)]));
1619 } else {
1620 dasm_put(Dst, 3204, Dt2([rkey]));
1621 }
1622 if (ISK(rval)) {
1623 dasm_put(Dst, 3184, (ptrdiff_t)(val));
1624 } else {
1625 dasm_put(Dst, 3345, Dt2([rval]));
1626 }
1627 if (tab) {
1628 dasm_put(Dst, 787, tab*sizeof(TValue));
1629 }
1630 dasm_put(Dst, 3503, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_settable), Dt1(->base));
1631 break;
1632 default: /* Array key. */
1633 dasm_put(Dst, 3520, Dt7([k-1].tt));
1634 dasm_put(Dst, 2168);
1635 if (ISK(rkey)) {
1636 dasm_put(Dst, 3534);
1637 } else {
1638 dasm_put(Dst, 3538);
1639 }
1640 dasm_put(Dst, 3406, DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, (ptrdiff_t)(J->nextins));
1641 if (!ISK(rval) || iscollectable(val)) {
1642 dasm_put(Dst, 3542, DtC(->marked), bitmask(BLACKBIT));
1643 dasm_put(Dst, 3555);
1644 }
1645 if (ISK(rval)) {
1646 switch (ttype(val)) {
1647 case 0:
1648 dasm_put(Dst, 3565, Dt7([k-1].tt));
1649 break;
1650 case 1:
1651 if (bvalue(val)) { /* true */
1652 dasm_put(Dst, 3573, Dt7([k-1].value), Dt7([k-1].tt));
1653 } else { /* false */
1654 dasm_put(Dst, 3585, Dt7([k-1].value), Dt7([k-1].tt));
1655 }
1656 break;
1657 case 3: {
1658 if ((&(val)->value)->n == (lua_Number)0) {
1659 dasm_put(Dst, 2404);
1660 } else if ((&(val)->value)->n == (lua_Number)1) {
1661 dasm_put(Dst, 2408);
1662 } else {
1663 dasm_put(Dst, 2411, &(val)->value);
1664 }
1665 dasm_put(Dst, 3600, Dt7([k-1].value), Dt7([k-1].tt));
1666 break;
1667 }
1668 case 4:
1669 dasm_put(Dst, 3611, Dt7([k-1].value), (ptrdiff_t)(gcvalue(val)), Dt7([k-1].tt));
1670 break;
1671 default: lua_assert(0); break;
1672 }
1673 } else {
1674 if (J->flags & JIT_F_CPU_SSE2) {
1675 dasm_put(Dst, 2947, Dt2([rval].tt), Dt2([rval].value), Dt7([k-1].tt), Dt7([k-1].value));
1676 } else {
1677 dasm_put(Dst, 2965, Dt2([rval].value), Dt2([rval].value.na[1]), Dt2([rval].tt), Dt7([k-1].value), Dt7([k-1].value.na[1]), Dt7([k-1].tt));
1678 }
1679 }
1680 break;
1681 }
1682
1683}
1684
1685static void jit_op_self(jit_State *J, int dest, int tab, int rkey)
1686{
1687 if (J->flags & JIT_F_CPU_SSE2) {
1688 dasm_put(Dst, 821, Dt2([tab].tt), Dt2([tab].value), Dt2([dest+1].tt), Dt2([dest+1].value));
1689 } else {
1690 dasm_put(Dst, 839, Dt2([tab].value), Dt2([tab].value.na[1]), Dt2([tab].tt), Dt2([dest+1].value), Dt2([dest+1].value.na[1]), Dt2([dest+1].tt));
1691 }
1692 jit_op_gettable(J, dest, tab, rkey);
1693}
1694
1695/* ------------------------------------------------------------------------ */
1696
1697static void jit_op_setlist(jit_State *J, int ra, int num, int batch)
1698{
1699 if (batch == 0) { batch = (int)(*J->nextins); J->combine++; }
1700 batch = (batch-1)*LFIELDS_PER_FLUSH;
1701 if (num == 0) { /* Previous op was open and set TOP: {f()} or {...}. */
1702 dasm_put(Dst, 3685, Dt1(->env.value), Dt2([ra+1]), Dt2([ra].value));
1703 if (batch > 0) {
1704 dasm_put(Dst, 3709, batch);
1705 }
1706 dasm_put(Dst, 3713, DtC(->sizearray), (ptrdiff_t)(luaH_resizearray), DtC(->marked), bitmask(BLACKBIT), DtC(->array), Dt1(->env.value));
1707 dasm_put(Dst, 3752);
1708 } else { /* Set fixed number of args. */
1709 dasm_put(Dst, 3762, Dt2([ra].value), DtC(->sizearray), batch+num, DtC(->marked), bitmask(BLACKBIT), DtC(->array), Dt2([ra+1+num]));
1710 dasm_put(Dst, 3792, batch+num, (ptrdiff_t)(luaH_resizearray));
1711 }
1712 if (batch > 0) {
1713 dasm_put(Dst, 3821, batch*sizeof(TValue));
1714 }
1715 dasm_put(Dst, 3825, Dt2([ra+1]));
1716 if (num == 0) { /* Previous op was open. Restore L->top. */
1717 dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top));
1718 }
1719}
1720
1721/* ------------------------------------------------------------------------ */
1722
1723static void jit_op_arith(jit_State *J, int dest, int rkb, int rkc, int ev)
1724{
1725 const TValue *kkb = ISK(rkb) ? &J->pt->k[INDEXK(rkb)] : NULL;
1726 const TValue *kkc = ISK(rkc) ? &J->pt->k[INDEXK(rkc)] : NULL;
1727 const Value *kval;
1728 int idx, rev;
1729 int target = (ev == TM_LT || ev == TM_LE) ? jit_jmp_target(J) : 0;
1730 int hastail = 0;
1731
1732 /* The bytecode compiler already folds constants except for: k/0, k%0, */
1733 /* NaN results, k1<k2, k1<=k2. No point in optimizing these cases. */
1734 if (ISK(rkb&rkc)) goto fallback;
1735
1736 /* Avoid optimization when non-numeric constants are present. */
1737 if (kkb ? !ttisnumber(kkb) : (kkc && !ttisnumber(kkc))) goto fallback;
1738
1739 /* The TYPE hint selects numeric inlining and/or fallback encoding. */
1740 switch (ttype(hint_get(J, TYPE))) {
1741 case LUA_TNIL: hastail = 1; break; /* No hint: numeric + fallback. */
1742 case LUA_TNUMBER: break; /* Numbers: numeric + deoptimization. */
1743 default: goto fallback; /* Mixed/other types: fallback only. */
1744 }
1745
1746 /* The checks above ensure: at most one of the operands is a constant. */
1747 /* Reverse operation and swap operands so the 2nd operand is a variable. */
1748 if (kkc) { kval = &kkc->value; idx = rkb; rev = 1; }
1749 else { kval = kkb ? &kkb->value : NULL; idx = rkc; rev = 0; }
1750
1751 /* Special handling for some operators. */
1752 switch (ev) {
1753 case TM_MOD:
1754 /* Check for modulo with positive numbers, so we can use fprem. */
1755 if (kval) {
1756 if (kval->na[1] < 0) { hastail = 0; goto fallback; } /* x%-k, -k%x */
1757 dasm_put(Dst, 3850, Dt2([idx].tt), Dt2([idx].value.na[1]));
1758 if (kkb) {
1759 dasm_put(Dst, 3868, Dt2([rkc].value), kval);
1760 } else {
1761 dasm_put(Dst, 3875, kval, Dt2([rkb].value));
1762 }
1763 } else {
1764 dasm_put(Dst, 3882, Dt2([rkb].tt), Dt2([rkc].tt), Dt2([rkb].value.na[1]), Dt2([rkc].value.na[1]), Dt2([rkc].value), Dt2([rkb].value));
1765 }
1766 dasm_put(Dst, 1387);
1767 goto fpstore;
1768 case TM_POW:
1769 if (hastail || !kval) break; /* Avoid this if not optimizing. */
1770 if (rev) { /* x^k for k > 0, k integer. */
1771 lua_Number n = kval->n;
1772 int k;
1773 lua_number2int(k, n);
1774 /* All positive integers would work. But need to limit code explosion. */
1775 if (k > 0 && k <= 65536 && (lua_Number)k == n) {
1776 dasm_put(Dst, 3916, Dt2([idx].tt), Dt2([idx]));
1777 for (; (k & 1) == 0; k >>= 1) { /* Handle leading zeroes (2^k). */
1778 dasm_put(Dst, 3928);
1779 }
1780 if ((k >>= 1) != 0) { /* Handle trailing bits. */
1781 dasm_put(Dst, 3931);
1782 for (; k != 1; k >>= 1) {
1783 if (k & 1) {
1784 dasm_put(Dst, 3936);
1785 }
1786 dasm_put(Dst, 3928);
1787 }
1788 dasm_put(Dst, 3939);
1789 }
1790 goto fpstore;
1791 }
1792 } else if (kval->n > (lua_Number)0) { /* k^x for k > 0. */
1793 int log2kval[3]; /* Enough storage for a tword (80 bits). */
1794 log2kval[2] = 0; /* Avoid leaking garbage. */
1795 /* Double precision log2(k) doesn't cut it (3^x != 3 for x = 1). */
1796 ((void (*)(int *, double))J->jsub[JSUB_LOG2_TWORD])(log2kval, kval->n);
1797 dasm_put(Dst, 3942, log2kval[0], log2kval[1], log2kval[2], Dt2([idx].tt), Dt2([idx].value));
1798
1799 goto fpstore;
1800 }
1801 break;
1802 }
1803
1804 /* Check number type and load 1st operand. */
1805 if (kval) {
1806 dasm_put(Dst, 4013, Dt2([idx].tt));
1807 if ((kval)->n == (lua_Number)0) {
1808 dasm_put(Dst, 2404);
1809 } else if ((kval)->n == (lua_Number)1) {
1810 dasm_put(Dst, 2408);
1811 } else {
1812 dasm_put(Dst, 2411, kval);
1813 }
1814 } else {
1815 if (rkb == rkc) {
1816 dasm_put(Dst, 4022, Dt2([rkb].tt));
1817 } else {
1818 dasm_put(Dst, 4027, Dt2([rkb].tt), Dt2([rkc].tt));
1819 }
1820 dasm_put(Dst, 3920, Dt2([rkb].value));
1821 }
1822
1823 /* Encode arithmetic operation with 2nd operand. */
1824 switch ((ev<<1)+rev) {
1825 case TM_ADD<<1: case (TM_ADD<<1)+1:
1826 if (rkb == rkc) {
1827 dasm_put(Dst, 4041);
1828 } else {
1829 dasm_put(Dst, 4044, Dt2([idx].value));
1830 }
1831 break;
1832 case TM_SUB<<1:
1833 dasm_put(Dst, 4048, Dt2([idx].value));
1834 break;
1835 case (TM_SUB<<1)+1:
1836 dasm_put(Dst, 4052, Dt2([idx].value));
1837 break;
1838 case TM_MUL<<1: case (TM_MUL<<1)+1:
1839 if (rkb == rkc) {
1840 dasm_put(Dst, 3928);
1841 } else {
1842 dasm_put(Dst, 4056, Dt2([idx].value));
1843 }
1844 break;
1845 case TM_DIV<<1:
1846 dasm_put(Dst, 4060, Dt2([idx].value));
1847 break;
1848 case (TM_DIV<<1)+1:
1849 dasm_put(Dst, 4064, Dt2([idx].value));
1850 break;
1851 case TM_POW<<1:
1852 dasm_put(Dst, 4068, Dt2([idx].value), (ptrdiff_t)(pow));
1853 break;
1854 case (TM_POW<<1)+1:
1855 dasm_put(Dst, 4088, Dt2([idx].value), (ptrdiff_t)(pow));
1856 break;
1857 case TM_UNM<<1: case (TM_UNM<<1)+1:
1858 dasm_put(Dst, 4108);
1859 break;
1860 default: /* TM_LT or TM_LE. */
1861 dasm_put(Dst, 1325, Dt2([idx].value));
1862 if (J->flags & JIT_F_CPU_CMOV) {
1863 dasm_put(Dst, 3293);
1864 } else {
1865 dasm_put(Dst, 3298);
1866 }
1867 dasm_put(Dst, 4111, dest?(J->nextpc+1):target);
1868 jit_assert(dest == 0 || dest == 1); /* Really cond. */
1869 switch (((rev^dest)<<1)+(dest^(ev == TM_LT))) {
1870 case 0:
1871 dasm_put(Dst, 4115, target);
1872 break;
1873 case 1:
1874 dasm_put(Dst, 4119, target);
1875 break;
1876 case 2:
1877 dasm_put(Dst, 4123, target);
1878 break;
1879 case 3:
1880 dasm_put(Dst, 4127, target);
1881 break;
1882 }
1883 goto skipstore;
1884 }
1885fpstore:
1886 /* Store result and set result type (if necessary). */
1887 dasm_put(Dst, 933, Dt2([dest].value));
1888 if (dest != rkb && dest != rkc) {
1889 dasm_put(Dst, 1309, Dt2([dest].tt));
1890 }
1891
1892skipstore:
1893 if (!hastail) {
1894 jit_deopt_target(J, 0);
1895 return;
1896 }
1897
1898 dasm_put(Dst, 1626);
1899 dasm_put(Dst, 1541);
1900
1901fallback:
1902 /* Generic fallback for arithmetic ops. */
1903 if (kkb) {
1904 dasm_put(Dst, 3342, (ptrdiff_t)(kkb));
1905 } else {
1906 dasm_put(Dst, 3204, Dt2([rkb]));
1907 }
1908 if (kkc) {
1909 dasm_put(Dst, 3184, (ptrdiff_t)(kkc));
1910 } else {
1911 dasm_put(Dst, 3345, Dt2([rkc]));
1912 }
1913 if (target) { /* TM_LT or TM_LE. */
1914 dasm_put(Dst, 4131, Dt1(->savedpc), (ptrdiff_t)((J->nextins+1)), (ptrdiff_t)(ev==TM_LT?luaV_lessthan:luaV_lessequal), Dt1(->base));
1915 if (dest) { /* cond */
1916 dasm_put(Dst, 1479, target);
1917 } else {
1918 dasm_put(Dst, 4154, target);
1919 }
1920 } else {
1921 if (dest) {
1922 dasm_put(Dst, 787, dest*sizeof(TValue));
1923 }
1924 dasm_put(Dst, 4158, Dt1(->savedpc), (ptrdiff_t)(J->nextins), ev, (ptrdiff_t)(luaV_arith), Dt1(->base));
1925 }
1926
1927 if (hastail) {
1928 dasm_put(Dst, 1644);
1929 }
1930}
1931
1932/* ------------------------------------------------------------------------ */
1933
1934static void jit_fallback_len(lua_State *L, StkId ra, const TValue *rb)
1935{
1936 switch (ttype(rb)) {
1937 case LUA_TTABLE:
1938 setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
1939 break;
1940 case LUA_TSTRING:
1941 setnvalue(ra, cast_num(tsvalue(rb)->len));
1942 break;
1943 default: {
1944 const TValue *tm = luaT_gettmbyobj(L, rb, TM_LEN);
1945 if (ttisfunction(tm)) {
1946 ptrdiff_t rasave = savestack(L, ra);
1947 setobj2s(L, L->top, tm);
1948 setobj2s(L, L->top+1, rb);
1949 luaD_checkstack(L, 2);
1950 L->top += 2;
1951 luaD_call(L, L->top - 2, 1);
1952 ra = restorestack(L, rasave);
1953 L->top--;
1954 setobjs2s(L, ra, L->top);
1955 } else {
1956 luaG_typeerror(L, rb, "get length of");
1957 }
1958 break;
1959 }
1960 }
1961}
1962
1963static void jit_op_len(jit_State *J, int dest, int rb)
1964{
1965 switch (ttype(hint_get(J, TYPE))) {
1966 case LUA_TTABLE:
1967 jit_deopt_target(J, 0);
1968 dasm_put(Dst, 4179, Dt2([rb].tt), Dt2([rb].value), (ptrdiff_t)(luaH_getn), Dt2([dest].value), Dt2([dest].tt));
1969 break;
1970 case LUA_TSTRING:
1971 jit_deopt_target(J, 0);
1972 dasm_put(Dst, 4212, Dt2([rb].tt), Dt2([rb].value), DtB(->tsv.len), Dt2([dest].value), Dt2([dest].tt));
1973 break;
1974 default:
1975 dasm_put(Dst, 3204, Dt2([rb]));
1976 if (dest) {
1977 dasm_put(Dst, 787, dest*sizeof(TValue));
1978 }
1979 dasm_put(Dst, 4237, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(jit_fallback_len), Dt1(->base));
1980 break;
1981 }
1982}
1983
1984static void jit_op_not(jit_State *J, int dest, int rb)
1985{
1986 /* l_isfalse() without a branch -- truly devious. */
1987 /* ((value & tt) | (tt>>1)) is only zero for nil/false. */
1988 /* Assumes: LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */
1989 dasm_put(Dst, 4258, Dt2([rb].tt), Dt2([rb].value), Dt2([dest].tt), Dt2([dest].value));
1990}
1991
1992/* ------------------------------------------------------------------------ */
1993
1994static void jit_op_concat(jit_State *J, int dest, int first, int last)
1995{
1996 int num = last-first+1;
1997 if (num == 2 && ttisstring(hint_get(J, TYPE))) { /* Optimize common case. */
1998 if (first) {
1999 dasm_put(Dst, 787, first*sizeof(TValue));
2000 }
2001 dasm_put(Dst, 4288, Dt2([dest].value), Dt2([dest].tt));
2002 } else { /* Generic fallback. */
2003 dasm_put(Dst, 4302, Dt1(->savedpc), (ptrdiff_t)(J->nextins), num, last, (ptrdiff_t)(luaV_concat), Dt1(->base));
2004 if (dest != first) {
2005 if (J->flags & JIT_F_CPU_SSE2) {
2006 dasm_put(Dst, 821, Dt2([first].tt), Dt2([first].value), Dt2([dest].tt), Dt2([dest].value));
2007 } else {
2008 dasm_put(Dst, 839, Dt2([first].value), Dt2([first].value.na[1]), Dt2([first].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt));
2009 }
2010 }
2011 }
2012 jit_checkGC(J); /* Always do this, even for the optimized variant. */
2013
2014}
2015
2016/* ------------------------------------------------------------------------ */
2017
2018static void jit_op_eq(jit_State *J, int cond, int rkb, int rkc)
2019{
2020 int target = jit_jmp_target(J);
2021 int condtarget = cond ? (J->nextpc+1) : target;
2022 jit_assert(cond == 0 || cond == 1);
2023
2024 /* Comparison of two constants. Evaluate at compile time. */
2025 if (ISK(rkb&rkc)) {
2026 if ((rkb == rkc) == cond) { /* Constants are already unique. */
2027 dasm_put(Dst, 665, target);
2028 }
2029 return;
2030 }
2031
2032 if (ISK(rkb|rkc)) { /* Compare a variable and a constant. */
2033 const TValue *kk;
2034 if (ISK(rkb)) { int t = rkc; rkc = rkb; rkb = t; } /* rkc holds const. */
2035 kk = &J->pt->k[INDEXK(rkc)];
2036 switch (ttype(kk)) {
2037 case LUA_TNIL:
2038 dasm_put(Dst, 4493, Dt2([rkb].tt));
2039 break;
2040 case LUA_TBOOLEAN:
2041 if (bvalue(kk)) {
2042 dasm_put(Dst, 4498, Dt2([rkb].tt), Dt2([rkb].value));
2043 } else {
2044 dasm_put(Dst, 4509, Dt2([rkb].tt), Dt2([rkb].value));
2045 }
2046 break;
2047 case LUA_TNUMBER:
2048 dasm_put(Dst, 4517, Dt2([rkb].tt), condtarget, Dt2([rkb].value), &kk->value);
2049 if (J->flags & JIT_F_CPU_CMOV) {
2050 dasm_put(Dst, 3293);
2051 } else {
2052 dasm_put(Dst, 3298);
2053 }
2054 dasm_put(Dst, 4111, condtarget);
2055 break;
2056 case LUA_TSTRING:
2057 dasm_put(Dst, 4531, Dt2([rkb].tt), condtarget, Dt2([rkb].value), (ptrdiff_t)(rawtsvalue(kk)));
2058 break;
2059 default: jit_assert(0); break;
2060 }
2061 } else { /* Compare two variables. */
2062 dasm_put(Dst, 4543, Dt2([rkb].tt), Dt2([rkc].tt), condtarget);
2063 switch (ttype(hint_get(J, TYPE))) {
2064 case LUA_TNUMBER:
2065 jit_deopt_target(J, 0);
2066 dasm_put(Dst, 4553, Dt2([rkb].value), Dt2([rkc].value));
2067 if (J->flags & JIT_F_CPU_CMOV) {
2068 dasm_put(Dst, 3293);
2069 } else {
2070 dasm_put(Dst, 3298);
2071 }
2072 dasm_put(Dst, 4111, condtarget);
2073 break;
2074 case LUA_TSTRING:
2075 jit_deopt_target(J, 0);
2076 dasm_put(Dst, 4568, Dt2([rkb].value), Dt2([rkc].value));
2077 break;
2078 default:
2079 dasm_put(Dst, 4583, Dt2([rkc]), Dt2([rkb]), Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_equalval), Dt1(->base));
2080 break;
2081 }
2082 }
2083 if (cond) {
2084 dasm_put(Dst, 4154, target);
2085 } else {
2086 dasm_put(Dst, 1479, target);
2087 }
2088}
2089
2090/* ------------------------------------------------------------------------ */
2091
2092static void jit_op_test(jit_State *J, int cond, int dest, int src)
2093{
2094 int target = jit_jmp_target(J);
2095
2096 /* l_isfalse() without a branch. But this time preserve tt/value. */
2097 /* (((value & tt) * 2 + tt) >> 1) is only zero for nil/false. */
2098 /* Assumes: 3*tt < 2^32, LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */
2099 dasm_put(Dst, 4611, Dt2([src].tt), Dt2([src].value));
2100
2101 /* Check if we can omit the stack copy. */
2102 if (dest == src) { /* Yes, invert branch condition. */
2103 if (cond) {
2104 dasm_put(Dst, 1479, target);
2105 } else {
2106 dasm_put(Dst, 4154, target);
2107 }
2108 } else { /* No, jump around copy code. */
2109 if (cond) {
2110 dasm_put(Dst, 4627);
2111 } else {
2112 dasm_put(Dst, 4632);
2113 }
2114 dasm_put(Dst, 4637, Dt2([src].value.na[1]), Dt2([dest].tt), Dt2([dest].value), Dt2([dest].value.na[1]), target);
2115 }
2116}
2117
2118static void jit_op_jmp(jit_State *J, int target)
2119{
2120 dasm_put(Dst, 665, target);
2121}
2122
2123/* ------------------------------------------------------------------------ */
2124
2125enum { FOR_IDX, FOR_LIM, FOR_STP, FOR_EXT };
2126
2127static const char *const jit_for_coerce_error[] = {
2128 LUA_QL("for") " initial value must be a number",
2129 LUA_QL("for") " limit must be a number",
2130 LUA_QL("for") " step must be a number",
2131};
2132
2133/* Try to coerce for slots with strings to numbers in place or complain. */
2134static void jit_for_coerce(lua_State *L, TValue *o)
2135{
2136 int i;
2137 for (i = FOR_IDX; i <= FOR_STP; i++, o++) {
2138 lua_Number num;
2139 if (ttisnumber(o)) continue;
2140 if (ttisstring(o) && luaO_str2d(svalue(o), &num)) {
2141 setnvalue(o, num);
2142 } else {
2143 luaG_runerror(L, jit_for_coerce_error[i]);
2144 }
2145 }
2146}
2147
2148static void jit_op_forprep(jit_State *J, int ra, int target)
2149{
2150 const TValue *step = hint_get(J, FOR_STEP_K);
2151 if (ttisnumber(step)) {
2152 dasm_put(Dst, 4654, Dt2([ra+FOR_IDX].tt), Dt2([ra+FOR_LIM].tt), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value));
2153 if (J->flags & JIT_F_CPU_CMOV) {
2154 dasm_put(Dst, 3293);
2155 } else {
2156 dasm_put(Dst, 3298);
2157 }
2158 dasm_put(Dst, 1309, Dt2([ra+FOR_EXT].tt));
2159 if (nvalue(step) < (lua_Number)0) {
2160 dasm_put(Dst, 4115, target+1);
2161 } else {
2162 dasm_put(Dst, 4123, target+1);
2163 }
2164 } else {
2165 dasm_put(Dst, 4683, Dt2([ra+FOR_IDX].tt), Dt2([ra+FOR_LIM].tt), Dt2([ra+FOR_STP].tt), Dt2([ra+FOR_STP].value.na[1]), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value));
2166 if (J->flags & JIT_F_CPU_CMOV) {
2167 dasm_put(Dst, 3293);
2168 } else {
2169 dasm_put(Dst, 3298);
2170 }
2171 dasm_put(Dst, 4732, Dt2([ra+FOR_EXT].tt), target+1);
2172 }
2173 if (ttisnumber(hint_get(J, TYPE))) {
2174 jit_deopt_target(J, 0);
2175 } else {
2176 dasm_put(Dst, 679);
2177 dasm_put(Dst, 4743, Dt2([ra]), Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(jit_for_coerce));
2178 }
2179}
2180
2181static void jit_op_forloop(jit_State *J, int ra, int target)
2182{
2183 const TValue *step = hint_getpc(J, FOR_STEP_K, target-1);
2184 if (ttisnumber(step)) {
2185 dasm_put(Dst, 4766, Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_STP].value), Dt2([ra+FOR_EXT].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].tt));
2186 if (J->flags & JIT_F_CPU_CMOV) {
2187 dasm_put(Dst, 3293);
2188 } else {
2189 dasm_put(Dst, 3298);
2190 }
2191 if (nvalue(step) < (lua_Number)0) {
2192 dasm_put(Dst, 4127, target);
2193 } else {
2194 dasm_put(Dst, 4119, target);
2195 }
2196 } else {
2197 dasm_put(Dst, 4789, Dt2([ra+FOR_STP].value.na[1]), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_STP].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value), Dt2([ra+FOR_EXT].tt));
2198 if (J->flags & JIT_F_CPU_CMOV) {
2199 dasm_put(Dst, 3293);
2200 } else {
2201 dasm_put(Dst, 3298);
2202 }
2203 dasm_put(Dst, 4127, target);
2204 }
2205}
2206
2207/* ------------------------------------------------------------------------ */
2208
2209static void jit_op_tforloop(jit_State *J, int ra, int nresults)
2210{
2211 int target = jit_jmp_target(J);
2212 int i;
2213 if (jit_inline_tforloop(J, ra, nresults, target)) return; /* Inlined? */
2214 for (i = 2; i >= 0; i--) {
2215 if (J->flags & JIT_F_CPU_SSE2) {
2216 dasm_put(Dst, 821, Dt2([ra+i].tt), Dt2([ra+i].value), Dt2([ra+i+3].tt), Dt2([ra+i+3].value));
2217 } else {
2218 dasm_put(Dst, 839, Dt2([ra+i].value), Dt2([ra+i].value.na[1]), Dt2([ra+i].tt), Dt2([ra+i+3].value), Dt2([ra+i+3].value.na[1]), Dt2([ra+i+3].tt));
2219 }
2220 }
2221 jit_op_call(J, ra+3, 2, nresults);
2222 dasm_put(Dst, 4827, Dt2([ra+3].tt));
2223 if (J->flags & JIT_F_CPU_SSE2) {
2224 dasm_put(Dst, 821, Dt2([ra+3].tt), Dt2([ra+3].value), Dt2([ra+2].tt), Dt2([ra+2].value));
2225 } else {
2226 dasm_put(Dst, 839, Dt2([ra+3].value), Dt2([ra+3].value.na[1]), Dt2([ra+3].tt), Dt2([ra+2].value), Dt2([ra+2].value.na[1]), Dt2([ra+2].tt));
2227 }
2228 dasm_put(Dst, 4649, target);
2229}
2230
2231/* ------------------------------------------------------------------------ */
2232
2233static void jit_op_close(jit_State *J, int ra)
2234{
2235 if (ra) {
2236 dasm_put(Dst, 4836, Dt2([ra]));
2237 } else {
2238 dasm_put(Dst, 4844);
2239 }
2240 dasm_put(Dst, 1734, (ptrdiff_t)(luaF_close));
2241}
2242
2243static void jit_op_closure(jit_State *J, int dest, int ptidx)
2244{
2245 Proto *npt = J->pt->p[ptidx];
2246 int nup = npt->nups;
2247 if (!J->pt->is_vararg) {
2248 dasm_put(Dst, 4849, Dt2([-1].value));
2249 } else {
2250 dasm_put(Dst, 4853, Dt1(->ci), Dt4(->func), Dt3(->value));
2251 }
2252 dasm_put(Dst, 4863, Dt5(->env), nup, (ptrdiff_t)(luaF_newLclosure), Dt5(->p), (ptrdiff_t)(npt), Dt2([dest].value), Dt2([dest].tt));
2253 /* Process pseudo-instructions for upvalues. */
2254 if (nup > 0) {
2255 const Instruction *uvcode = J->nextins;
2256 int i, uvuv;
2257 /* Check which of the two types we need. */
2258 for (i = 0, uvuv = 0; i < nup; i++)
2259 if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) uvuv++;
2260 /* Copy upvalues from parent first. */
2261 if (uvuv) {
2262 /* LCL:eax->upvals (new closure) <-- LCL:edi->upvals (own closure). */
2263 for (i = 0; i < nup; i++)
2264 if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) {
2265 dasm_put(Dst, 4895, Dt5(->upvals[GETARG_B(uvcode[i])]), Dt5(->upvals[i]));
2266 }
2267 }
2268 /* Next find or create upvalues for our own stack slots. */
2269 if (nup > uvuv) {
2270 dasm_put(Dst, 909);
2271 /* LCL:edi->upvals (new closure) <-- upvalue for stack slot. */
2272 for (i = 0; i < nup; i++)
2273 if (GET_OPCODE(uvcode[i]) == OP_MOVE) {
2274 int rb = GETARG_B(uvcode[i]);
2275 if (rb) {
2276 dasm_put(Dst, 4836, Dt2([rb]));
2277 } else {
2278 dasm_put(Dst, 4844);
2279 }
2280 dasm_put(Dst, 4902, (ptrdiff_t)(luaF_findupval), Dt5(->upvals[i]));
2281 }
2282 }
2283 J->combine += nup; /* Skip pseudo-instructions. */
2284 }
2285 jit_checkGC(J);
2286}
2287
2288/* ------------------------------------------------------------------------ */
2289
2290static void jit_op_vararg(jit_State *J, int dest, int num)
2291{
2292 if (num < 0) { /* Copy all varargs. */
2293 dasm_put(Dst, 4911, Dt1(->ci), Dt4(->func), (1+J->pt->numparams)*sizeof(TValue), J->pt->maxstacksize*sizeof(TValue), Dt1(->stack_last), Dt2([dest]));
2294 dasm_put(Dst, 4967, Dt1(->top), (ptrdiff_t)(luaD_growstack), Dt1(->base));
2295 } else if (num > 0) { /* Copy limited number of varargs. */
2296 dasm_put(Dst, 4993, Dt1(->ci), Dt4(->func), (1+J->pt->numparams)*sizeof(TValue), Dt2([dest]), Dt2([dest+num]), Dt3([0].tt), sizeof(TValue));
2297 }
2298}
2299
2300/* ------------------------------------------------------------------------ */
2301
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86_inline.dash b/libraries/LuaJIT-1.1.7/src/ljit_x86_inline.dash
new file mode 100644
index 0000000..203642f
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljit_x86_inline.dash
@@ -0,0 +1,625 @@
1/*
2** Function inlining support for x86 CPUs.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* ------------------------------------------------------------------------ */
7
8/* Private structure holding function inlining info. */
9typedef struct jit_InlineInfo {
10 int func; /* Function slot. 1st arg slot = func+1. */
11 int res; /* 1st result slot. Overlaps func/ci->func. */
12 int nargs; /* Number of args. */
13 int nresults; /* Number of results. */
14 int xnargs; /* Expected number of args. */
15 int xnresults; /* Returned number of results. */
16 int hidx; /* Library/function index numbers. */
17} jit_InlineInfo;
18
19/* ------------------------------------------------------------------------ */
20
21enum { TFOR_FUNC, TFOR_TAB, TFOR_CTL, TFOR_KEY, TFOR_VAL };
22
23static void jit_inline_base(jit_State *J, jit_InlineInfo *ii)
24{
25 int func = ii->func;
26 switch (JIT_IH_IDX(ii->hidx)) {
27 case JIT_IH_BASE_PAIRS:
28 case JIT_IH_BASE_IPAIRS:
29 |// Easy for regular calls: res == func. Not inlined for tailcalls.
30 |// Guaranteed to be inlined only if used in conjunction with TFORLOOP.
31 |// So we omit setting the iterator function and fake the control var.
32 | istable func+TFOR_TAB; jne L_DEOPTIMIZE // Caveat: deopt TFORLOOP, too!
33 | xor eax, eax // Assumes: LUA_TNIL == 0.
34 | mov BASE[func+TFOR_CTL].tt, eax // Fake nil type.
35 | mov BASE[func+TFOR_CTL].value, eax // Hidden control var = 0.
36 |// mov BASE[func+TFOR_FUNC].tt, eax // Kill function (not needed).
37 |.mfmap
38 | .word JIT_MFM_DEOPT_PAIRS, J->nextpc-1 // Deoptimize TFORLOOP, too.
39 |.code
40 break;
41 default:
42 jit_assert(0);
43 break;
44 }
45}
46
47/* ------------------------------------------------------------------------ */
48
49#ifndef COCO_DISABLE
50
51/* Helper function for inlined coroutine.resume(). */
52static StkId jit_coroutine_resume(lua_State *L, StkId base, int nresults)
53{
54 lua_State *co = thvalue(base-1);
55 /* Check for proper usage. Merge of lua_resume() and auxresume() checks. */
56 if (co->status != LUA_YIELD) {
57 if (co->status > LUA_YIELD) {
58errdead:
59 setsvalue(L, base-1, luaS_newliteral(L, "cannot resume dead coroutine"));
60 goto err;
61 } else if (co->ci != co->base_ci) {
62 setsvalue(L, base-1,
63 luaS_newliteral(L, "cannot resume non-suspended coroutine"));
64 goto err;
65 } else if (co->base == co->top) {
66 goto errdead;
67 }
68 }
69 {
70 ptrdiff_t ndelta = (char *)L->top - (char *)base;
71 int nargs = ndelta/sizeof(TValue); /* Compute nargs. */
72 int status;
73 if ((char *)co->stack_last-(char *)co->top <= ndelta) {
74 co->ci->top = (StkId)(((char *)co->top) + ndelta); /* Ok before grow. */
75 luaD_growstack(co, nargs); /* Grow thread stack. */
76 }
77 /* Copy args. */
78 co->top = (StkId)(((char *)co->top) + ndelta);
79 { StkId t = co->top, f = L->top; while (f > base) setobj2s(co, --t, --f); }
80 L->top = base;
81 status = luaCOCO_resume(co, nargs); /* Resume Coco thread. */
82 if (status == 0 || status == LUA_YIELD) { /* Ok. */
83 StkId f;
84 if (nresults == 0) return NULL;
85 if (nresults == -1) {
86 luaD_checkstack(L, co->top - co->base); /* Grow own stack. */
87 }
88 base = L->top - 2;
89 setbvalue(base++, 1); /* true */
90 /* Copy results. Fill unused result slots with nil. */
91 f = co->base;
92 while (--nresults != 0 && f < co->top) setobj2s(L, base++, f++);
93 while (nresults-- > 0) setnilvalue(base++);
94 co->top = co->base;
95 return base;
96 } else { /* Error. */
97 base = L->top;
98 setobj2s(L, base-1, co->top-1); /* Copy error object. */
99err:
100 setbvalue(base-2, 0); /* false */
101 nresults -= 2;
102 while (--nresults >= 0) setnilvalue(base+nresults); /* Fill results. */
103 return base;
104 }
105 }
106}
107
108static void jit_inline_coroutine(jit_State *J, jit_InlineInfo *ii)
109{
110 int arg = ii->func+1;
111 int res = ii->res;
112 int i;
113 switch (JIT_IH_IDX(ii->hidx)) {
114 case JIT_IH_COROUTINE_YIELD:
115 | cmp aword [L+((int)&LHASCOCO((lua_State *)0))], 0 // Got a C stack?
116 | je L_DEOPTIMIZE
117 | mov L->savedpc, &J->nextins // Debugger-friendly.
118 | add BASE, arg*#TVALUE
119 if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */
120 | lea TOP, BASE[ii->nargs]
121 }
122 | mov L->base, BASE
123 | mov L->top, TOP
124 | call &luaCOCO_yield, L
125 | mov BASE, L->base
126 | mov TOP, L->top
127 jit_assert(ii->nresults >= 0 && ii->nresults <= EXTRA_STACK);
128 for (i = 0; i < ii->nresults; i++) {
129 | setnilvalue TOP[i] // Clear undefined result.
130 | copyslot BASE[res+i], BASE[arg+i] // Move result down.
131 }
132 ii->nargs = -1; /* Force restore of L->top. */
133 break;
134 case JIT_IH_COROUTINE_RESUME:
135 jit_assert(ii->nargs != 0 && ii->res == ii->func);
136 | add BASE, (arg+1)*#TVALUE
137 if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */
138 | lea TOP, BASE[ii->nargs-1]
139 } else {
140 | cmp TOP, BASE; jb L_DEOPTIMIZE // No thread arg? Deoptimize.
141 }
142 | istt -1, LUA_TTHREAD; jne L_DEOPTIMIZE // Wrong type? Deoptimize.
143 | mov L:eax, BASE[-1].value
144 | cmp aword [L:eax+((int)&LHASCOCO((lua_State *)0))], 0
145 | je L_DEOPTIMIZE // No C stack? Deoptimize.
146 | mov L->savedpc, &J->nextins // Debugger-friendly.
147 | mov L->top, TOP
148 | call &jit_coroutine_resume, L, BASE, ii->nresults
149 | mov BASE, L->base
150 if (ii->nresults == -1) {
151 | mov TOP, eax
152 }
153 ii->nargs = -1; /* Force restore of L->top. */
154 break;
155 default:
156 jit_assert(0);
157 break;
158 }
159}
160
161#endif /* COCO_DISABLE */
162
163/* ------------------------------------------------------------------------ */
164
165static void jit_inline_string(jit_State *J, jit_InlineInfo *ii)
166{
167 int arg = ii->func+1;
168 int res = ii->res;
169 switch (JIT_IH_IDX(ii->hidx)) {
170 case JIT_IH_STRING_LEN:
171 | isstring arg; jne L_DEOPTIMIZE
172 | mov TSTRING:ecx, BASE[arg].value
173 | fild aword TSTRING:ecx->tsv.len // size_t
174 | settt BASE[res], LUA_TNUMBER
175 | fstp qword BASE[res].value
176 break;
177 case JIT_IH_STRING_SUB:
178 /* TODO: inline numeric constants with help from the optimizer. */
179 /* But this would save only another 15-20% in a trivial loop. */
180 jit_assert(ii->nargs >= 2); /* Open op caveat is ok, too. */
181 if (ii->nargs > 2) {
182 | lea TOP, BASE[arg]
183 | call ->STRING_SUB3
184 | setsvalue BASE[res], eax
185 } else {
186 | lea TOP, BASE[arg]
187 | call ->STRING_SUB2
188 | setsvalue BASE[res], eax
189 }
190 break;
191 case JIT_IH_STRING_CHAR:
192 | isnumber arg; jne L_DEOPTIMIZE
193 | lea eax, L->env // Abuse L->env to hold temp string.
194 | fld qword BASE[arg].value
195 | fistp dword [eax] // LSB is at start (little-endian).
196 | cmp dword [eax], 255; ja L_DEOPTIMIZE
197 | call &luaS_newlstr, L, eax, 1
198 | setsvalue BASE[res], eax
199 break;
200 default:
201 jit_assert(0);
202 break;
203 }
204
205 |//-----------------------------------------------------------------------
206 |.jsub STRING_SUB3 // string.sub(str, start, end)
207 | mov eax, TOP[0].tt; shl eax, 4; or eax, TOP[1].tt; shl eax, 4
208 | or eax, TOP[2].tt; sub eax, LUA_TSTR_NUM_NUM
209 | jne ->DEOPTIMIZE_CALLER // Wrong types? Deoptimize.
210 | // eax must be zero here!
211 | fld qword TOP[1].value
212 | fld qword TOP[2].value
213 | fistp aword TMP3 // size_t
214 | fistp aword TMP2 // size_t
215 | mov TSTRING:ecx, TOP[0].value
216 | mov TOP, aword TSTRING:ecx->tsv.len // size_t
217 | mov edx, TMP3
218 | cmp TOP, edx
219 | jb >4
220 |1:
221 | or eax, TMP2 // eax is known to be zero.
222 | jle >6 // start <= 0?
223 |2:
224 | sub edx, eax // newlen = end-start
225 | jl >7 // start > end?
226 | lea ecx, [TSTRING:ecx+eax+#TSTRING-1] // svalue()-1+start
227 | inc edx
228 |3:
229 | mov ARG2, L // First arg for tailcall is ARG2.
230 | mov ARG3, ecx // Pointer to start.
231 | mov ARG4, edx // Length.
232 | mov GL:edi, L->l_G
233 | mov eax, GL:edi->totalbytes // size_t
234 | cmp eax, GL:edi->GCthreshold // size_t
235 | jae >8 // G->totalbytes >= G->GCthreshold?
236 | jmp &luaS_newlstr // Tailcall to C function.
237 |
238 |4: // Negative end or overflow.
239 | jl >5
240 | lea edx, [edx+TOP+1] // end = end+(len+1)
241 | jmp <1
242 |5: // Overflow
243 | mov edx, TOP // end = len
244 | jmp <1
245 |
246 |6: // Negative start or underflow.
247 | je >5
248 | add eax, TOP // start = start+(len+1)
249 | inc eax
250 | jg <2 // start > 0?
251 |5: // Underflow.
252 | mov eax, 1 // start = 1
253 | jmp <2
254 |
255 |7: // Range underflow.
256 | xor edx, edx // Zero length.
257 | jmp <3 // Any pointer in ecx is ok.
258 |.endjsub
259 |
260 |//-----------------------------------------------------------------------
261 |.jsub STRING_SUB2 // string.sub(str, start)
262 | mov eax, TOP[0].tt; shl eax, 4; or eax, TOP[1].tt; sub eax, LUA_TSTR_NUM
263 | jne ->DEOPTIMIZE_CALLER // Wrong types? Deoptimize.
264 | // eax must be zero here!
265 | fld qword TOP[1].value
266 | fistp aword TMP2 // size_t
267 | mov TSTRING:ecx, TOP[0].value
268 | mov TOP, aword TSTRING:ecx->tsv.len // size_t
269 | mov edx, TOP
270 | jmp <1 // See STRING_SUB3.
271 |
272 |8: // GC threshold reached.
273 | sub esp, FRAME_OFFSET
274 | call &luaC_step, L
275 | add esp, FRAME_OFFSET
276 | mov BASE, L->base
277 | jmp &luaS_newlstr // Tailcall to C function.
278 |.endjsub
279}
280
281/* ------------------------------------------------------------------------ */
282
283/* Helper functions for inlined calls to table.*. */
284static void jit_table_insert(lua_State *L, TValue *arg)
285{
286 setobj2t(L, luaH_setnum(L, hvalue(arg), luaH_getn(hvalue(arg))+1), arg+1);
287 luaC_barriert(L, hvalue(arg), arg+1);
288}
289
290static TValue *jit_table_remove(lua_State *L, TValue *arg, TValue *res)
291{
292 int n = luaH_getn(hvalue(arg));
293 if (n == 0) {
294 setnilvalue(res); /* For the nresults == 1 case. Harmless otherwise. */
295 return res; /* For the nresults == -1 case. */
296 } else {
297 TValue *val = luaH_setnum(L, hvalue(arg), n);
298 setobj2s(L, res, val);
299 setnilvalue(val);
300 return res+1; /* For the nresults == -1 case. */
301 }
302}
303
304static void jit_inline_table(jit_State *J, jit_InlineInfo *ii)
305{
306 int arg = ii->func+1;
307 int res = ii->res;
308 | istable arg; jne L_DEOPTIMIZE
309 switch (JIT_IH_IDX(ii->hidx)) {
310 case JIT_IH_TABLE_INSERT:
311 | lea TVALUE:eax, BASE[arg]
312 | call &jit_table_insert, L, TVALUE:eax
313 break;
314 case JIT_IH_TABLE_REMOVE:
315 | lea TVALUE:eax, BASE[arg]
316 | lea TVALUE:ecx, BASE[res]
317 | call &jit_table_remove, L, TVALUE:eax, TVALUE:ecx
318 if (ii->nresults == -1) {
319 ii->xnresults = -1;
320 | mov TOP, TVALUE:eax
321 }
322 break;
323 case JIT_IH_TABLE_GETN:
324 | mov TABLE:eax, BASE[arg].value
325 | call &luaH_getn, TABLE:eax
326 | mov TMP1, eax
327 | fild dword TMP1
328 | fstp qword BASE[res].value
329 | settt BASE[res], LUA_TNUMBER
330 break;
331 default:
332 jit_assert(0);
333 break;
334 }
335}
336
337/* ------------------------------------------------------------------------ */
338
339/* This typedef must match the libm function signature. */
340/* Serves as a check against wrong lua_Number or wrong calling conventions. */
341typedef lua_Number (*mathfunc_11)(lua_Number);
342
343/* Partially inlined math functions. */
344/* CHECK: must match with jit_hints.h and jit.opt_lib. */
345static const mathfunc_11 jit_mathfuncs_11[JIT_IH_MATH_SIN] = {
346 log, log10, exp, sinh, cosh, tanh, asin, acos, atan
347};
348
349/* FPU control words for ceil and floor (exceptions masked, full precision). */
350static const unsigned short jit_fpucw[2] = { 0x0b7f, 0x077f };
351
352static void jit_inline_math(jit_State *J, jit_InlineInfo *ii)
353{
354 int arg = ii->func+1;
355 int res = ii->res;
356 int idx = JIT_IH_IDX(ii->hidx);
357
358 if (idx < JIT_IH_MATH__21) {
359 | isnumber arg; jne L_DEOPTIMIZE
360 | fld qword BASE[arg].value
361 } else {
362 jit_assert(idx < JIT_IH_MATH__LAST);
363 | isnumber2 arg, arg+1; jne L_DEOPTIMIZE
364 }
365 switch (idx) {
366 /* We ignore sin/cos/tan range overflows (2^63 rad) just like -ffast-math. */
367 case JIT_IH_MATH_SIN:
368 | fsin
369 break;
370 case JIT_IH_MATH_COS:
371 | fcos
372 break;
373 case JIT_IH_MATH_TAN:
374 | fptan; fpop
375 break;
376 case JIT_IH_MATH_CEIL:
377 case JIT_IH_MATH_FLOOR:
378 | fnstcw word TMP1
379 | fldcw word [(ptrdiff_t)&jit_fpucw[idx-JIT_IH_MATH_CEIL]]
380 | frndint
381 | fldcw word TMP1
382 break;
383 case JIT_IH_MATH_ABS:
384 | fabs
385 break;
386 case JIT_IH_MATH_SQRT:
387 | fsqrt
388 break;
389 case JIT_IH_MATH_FMOD:
390 | fld qword BASE[arg+1].value
391 | fld qword BASE[arg].value
392 |1: ; fprem; fnstsw ax; sahf; jp <1
393 | fstp st1
394 break;
395 case JIT_IH_MATH_ATAN2:
396 |// Inlining is easier than calling atan2().
397 | fld qword BASE[arg].value
398 | fld qword BASE[arg+1].value
399 | fpatan
400 break;
401 default:
402 |// Partially inlined. Just call the libm function (__cdecl!).
403 | fstp FPARG1
404 | call &jit_mathfuncs_11[idx]
405 break;
406 }
407 | settt BASE[res], LUA_TNUMBER
408 | fstp qword BASE[res].value
409}
410
411/* ------------------------------------------------------------------------ */
412
413/* Try to inline a CALL or TAILCALL instruction. */
414static int jit_inline_call(jit_State *J, int func, int nargs, int nresults)
415{
416 const TValue *callable = hint_get(J, TYPE); /* TYPE hint = callable. */
417 int cltype = ttype(callable);
418 const TValue *oidx;
419 jit_InlineInfo ii;
420 int idx;
421
422 if (cltype != LUA_TFUNCTION) goto fail;
423 if (J->flags & JIT_F_DEBUG) goto fail; /* DWIM. */
424
425 oidx = hint_get(J, INLINE); /* INLINE hint = library/function index. */
426 if (!ttisnumber(oidx)) goto fail;
427
428 ii.hidx = (int)nvalue(oidx);
429 idx = JIT_IH_IDX(ii.hidx);
430
431 if (nresults == -2) { /* Tailcall. */
432 /* Tailcalls from vararg functions don't work with BASE[-1]. */
433 if (J->pt->is_vararg) goto fail; /* So forget about this rare case. */
434 ii.res = -1; /* Careful: 2nd result overlaps 1st stack slot. */
435 ii.nresults = -1;
436 } else {
437 ii.res = func;
438 ii.nresults = nresults;
439 }
440 ii.func = func;
441 ii.nargs = nargs;
442 ii.xnargs = ii.xnresults = 1; /* Default: 1 arg, 1 result. */
443
444 /* Check for the currently supported cases. */
445 switch (JIT_IH_LIB(ii.hidx)) {
446 case JIT_IHLIB_BASE:
447 switch (idx) {
448 case JIT_IH_BASE_PAIRS:
449 case JIT_IH_BASE_IPAIRS:
450 if (nresults == -2) goto fail; /* Not useful for tailcalls. */
451 ii.xnresults = 3;
452 goto check;
453 }
454 break;
455#ifndef COCO_DISABLE
456 case JIT_IHLIB_COROUTINE:
457 switch (idx) {
458 case JIT_IH_COROUTINE_YIELD:
459 /* Only support common cases: no tailcalls, low number of results. */
460 if (nresults < 0 || nresults > EXTRA_STACK) goto fail;
461 ii.xnargs = ii.xnresults = -1;
462 goto ok; /* Anything else is ok. */
463 case JIT_IH_COROUTINE_RESUME:
464 /* Only support common cases: no tailcalls, not with 0 args (error). */
465 if (nresults == -2 || nargs == 0) goto fail;
466 ii.xnargs = ii.xnresults = -1;
467 goto ok; /* Anything else is ok. */
468 }
469 break;
470#endif
471 case JIT_IHLIB_STRING:
472 switch (idx) {
473 case JIT_IH_STRING_LEN:
474 goto check;
475 case JIT_IH_STRING_SUB:
476 if (nargs < 2) goto fail; /* No support for open calls, too. */
477 goto ok; /* 2 or more args are ok. */
478 case JIT_IH_STRING_CHAR:
479 goto check; /* Only single arg supported. */
480 }
481 break;
482 case JIT_IHLIB_TABLE:
483 switch (idx) {
484 case JIT_IH_TABLE_INSERT:
485 ii.xnargs = 2;
486 goto check; /* Only push (append) supported. */
487 case JIT_IH_TABLE_REMOVE:
488 goto check; /* Only pop supported. */
489 case JIT_IH_TABLE_GETN:
490 goto check;
491 }
492 break;
493 case JIT_IHLIB_MATH:
494 if (idx >= JIT_IH_MATH__LAST) goto fail;
495 if (idx >= JIT_IH_MATH__21) ii.xnargs = 2;
496 goto check;
497 }
498fail:
499 return cltype; /* Call could not be inlined. Return type of callable. */
500
501check:
502 if (nargs != ii.xnargs && nargs != -1) goto fail;
503 /* The optimizer already checks the number of results (avoid setnil). */
504
505ok: /* Whew, all checks done. Go for it! */
506
507 /* Start with the common leadin for inlined calls. */
508 jit_deopt_target(J, nargs);
509 |// Caveat: Must save TOP for open ops if jsub uses DEOPTIMIZE_CALLER.
510 | isfunction func
511 | jne L_DEOPTIMIZE // Not a function? Deoptimize.
512 | cmp aword BASE[func].value, &clvalue(callable)
513 | jne L_DEOPTIMIZE // Wrong closure? Deoptimize.
514 if (nargs == -1 && ii.xnargs >= 0) {
515 | lea eax, BASE[func+1+ii.xnargs]
516 | cmp TOP, eax
517 | jne L_DEOPTIMIZE // Wrong #args? Deoptimize.
518 }
519
520 /* Now inline the function itself. */
521 switch (JIT_IH_LIB(ii.hidx)) {
522 case JIT_IHLIB_BASE: jit_inline_base(J, &ii); break;
523#ifndef COCO_DISABLE
524 case JIT_IHLIB_COROUTINE: jit_inline_coroutine(J, &ii); break;
525#endif
526 case JIT_IHLIB_STRING: jit_inline_string(J, &ii); break;
527 case JIT_IHLIB_TABLE: jit_inline_table(J, &ii); break;
528 case JIT_IHLIB_MATH: jit_inline_math(J, &ii); break;
529 default: jit_assert(0); break;
530 }
531
532 /* And add the common leadout for inlined calls. */
533 if (ii.nresults == -1) {
534 if (ii.xnresults >= 0) {
535 | lea TOP, BASE[ii.res+ii.xnresults]
536 }
537 } else if (ii.nargs == -1) { /* Restore L->top only if needed. */
538 | lea TOP, BASE[J->pt->maxstacksize]
539 | mov L->top, TOP
540 }
541
542 if (nresults == -2) { /* Results are in place. Add return for tailcalls. */
543 | add esp, FRAME_OFFSET
544 | sub BASE, #BASE
545 | sub aword L->ci, #CI
546 | ret
547 }
548
549 return -1; /* Success, call has been inlined. */
550}
551
552/* ------------------------------------------------------------------------ */
553
554/* Helper function for inlined iterator code. Paraphrased from luaH_next. */
555/* TODO: GCC has trouble optimizing this. */
556static int jit_table_next(lua_State *L, TValue *ra)
557{
558 Table *t = hvalue(&ra[TFOR_TAB]);
559 int i = ra[TFOR_CTL].value.b; /* Hidden control variable. */
560 for (; i < t->sizearray; i++) { /* First the array part. */
561 if (!ttisnil(&t->array[i])) {
562 setnvalue(&ra[TFOR_KEY], cast_num(i+1));
563 setobj2s(L, &ra[TFOR_VAL], &t->array[i]);
564 ra[TFOR_CTL].value.b = i+1;
565 return 1;
566 }
567 }
568 for (i -= t->sizearray; i < sizenode(t); i++) { /* Then the hash part. */
569 if (!ttisnil(gval(gnode(t, i)))) {
570 setobj2s(L, &ra[TFOR_KEY], key2tval(gnode(t, i)));
571 setobj2s(L, &ra[TFOR_VAL], gval(gnode(t, i)));
572 ra[TFOR_CTL].value.b = i+1+t->sizearray;
573 return 1;
574 }
575 }
576 return 0; /* End of iteration. */
577}
578
579/* Try to inline a TFORLOOP instruction. */
580static int jit_inline_tforloop(jit_State *J, int ra, int nresults, int target)
581{
582 const TValue *oidx = hint_get(J, INLINE); /* INLINE hint = lib/func idx. */
583 int idx;
584
585 if (!ttisnumber(oidx)) return 0; /* No hint: don't inline anything. */
586 idx = (int)nvalue(oidx);
587 if (J->flags & JIT_F_DEBUG) return 0; /* DWIM. */
588
589 switch (idx) {
590 case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_PAIRS):
591 |// The type checks can be omitted -- see the iterator constructor.
592 | lea TOP, BASE[ra]
593 | call &jit_table_next, L, TOP
594 | test eax, eax
595 | jnz =>target
596 return 1; /* Success, iterator has been inlined. */
597 case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_IPAIRS):
598 |// The type checks can be omitted -- see the iterator constructor.
599 | mov eax, BASE[ra+TFOR_CTL].value // Hidden control variable.
600 | inc eax
601 | mov TABLE:edx, BASE[ra+TFOR_TAB].value // Table object.
602 | mov BASE[ra+TFOR_CTL].value, eax
603 | call &luaH_getnum, TABLE:edx, eax
604 | // This is really copyslot BASE[ra+TFOR_VAL], TVALUE:eax[0] plus compare.
605 | mov ecx, TVALUE:eax->tt
606 | test ecx, ecx // Assumes: LUA_TNIL == 0.
607 | jz >9 // nil value stops iteration.
608 | fild dword BASE[ra+TFOR_CTL].value // Set numeric key.
609 | settt BASE[ra+TFOR_KEY], LUA_TNUMBER
610 | fstp qword BASE[ra+TFOR_KEY].value
611 | mov edx, TVALUE:eax->value
612 | mov eax, TVALUE:eax->value.na[1] // Overwrites eax.
613 | mov BASE[ra+TFOR_VAL].tt, ecx // Copy value from table slot.
614 | mov BASE[ra+TFOR_VAL].value, edx
615 | mov BASE[ra+TFOR_VAL].value.na[1], eax
616 | jmp =>target
617 |9:
618 return 1; /* Success, iterator has been inlined. */
619 }
620
621 return 0; /* No support for inlining any other iterators. */
622}
623
624/* ------------------------------------------------------------------------ */
625
diff --git a/libraries/LuaJIT-1.1.7/src/ljitlib.c b/libraries/LuaJIT-1.1.7/src/ljitlib.c
new file mode 100644
index 0000000..4efc04d
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljitlib.c
@@ -0,0 +1,637 @@
1/*
2** Lua library for the JIT engine.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include <stdio.h>
7#include <string.h>
8
9#define ljitlib_c
10#define LUA_LIB
11
12#include "lua.h"
13#include "lauxlib.h"
14#include "luajit.h"
15#include "lualib.h"
16
17/* This file is not a pure C API user. Some internals are required. */
18#include "lobject.h"
19#include "lstate.h"
20#include "lstring.h"
21#include "ltable.h"
22#include "lfunc.h"
23#include "lgc.h"
24#include "lopcodes.h"
25
26#include "ljit.h"
27#include "ljit_hints.h"
28
29#define STRING_HINTS
30#include "ljit_hints.h"
31
32/* ------------------------------------------------------------------------ */
33
34/* Static pointer addresses used as registry keys. */
35/* The values do not matter, but must be different to prevent joining. */
36static const int regkey_frontend = 0x6c6a6c01;
37static const int regkey_comthread = 0x6c6a6c02;
38
39/* Check that the first argument is a Lua function and return its closure. */
40static Closure *check_LCL(lua_State *L)
41{
42 StkId o = L->base;
43 switch (lua_type(L, 1)) {
44 case LUA_TBOOLEAN:
45 o = (L->ci-1)->func;
46 case LUA_TFUNCTION:
47 if (isLfunction(o))
48 return clvalue(o);
49 break;
50 }
51 luaL_argerror(L, 1, "Lua function expected");
52 return NULL;
53}
54
55/* Create a new closure from a prototype. */
56/* Note: upvalues are assumed to be after first two slots. */
57static void push_LCL(lua_State *L, Proto *pt, Table *env)
58{
59 Closure *cl;
60 int i, nup = pt->nups;
61 /* Adjust the number of stack slots to the number of upvalues. */
62 luaL_checkstack(L, nup, "too many upvalues");
63 lua_settop(L, 2+nup);
64 /* Create a closure from the subroutine prototype. */
65 cl = luaF_newLclosure(L, nup, env);
66 cl->l.p = pt;
67 /* Allocate new upvalues and close them. */
68 for (i = 0; i < nup; i++)
69 cl->l.upvals[i] = luaF_findupval(L, L->base + (2+i));
70 luaF_close(L, L->base + 2);
71 lua_settop(L, 2); /* Remove upvalues. */
72 setclvalue(L, L->top++, cl); /* Return closure on top of stack. */
73 luaC_checkGC(L);
74}
75
76/* ------------------------------------------------------------------------ */
77
78/* Set JIT mode for the engine or a closure and/or its subroutines. */
79static int setmode(lua_State *L, int mode)
80{
81 int idx = 0;
82 switch (lua_type(L, 1)) {
83 case LUA_TNONE: /* jit.on/off() */
84 case LUA_TNIL: /* jit.on/off(nil) */
85 luaJIT_setmode(L, 0, mode | LUAJIT_MODE_ENGINE);
86 break;
87 case LUA_TFUNCTION: /* jit.on/off(func, nil|true|false) */
88 idx = 1;
89 case LUA_TBOOLEAN: /* jit.on/off(true, nil|true|false) (parent frame) */
90 if (lua_isboolean(L, 2))
91 mode |= lua_toboolean(L, 2)?LUAJIT_MODE_ALLFUNC:LUAJIT_MODE_ALLSUBFUNC;
92 else
93 mode |= LUAJIT_MODE_FUNC;
94 if (luaJIT_setmode(L, idx, mode) == 1) /* Ok? */
95 break;
96 default:
97 luaL_argerror(L, 1, "Lua function expected");
98 break;
99 }
100 return 0;
101}
102
103/* Set JIT mode to on: (re-)enable compilation. */
104static int j_on(lua_State *L)
105{
106 return setmode(L, LUAJIT_MODE_ON);
107}
108
109/* Set JIT mode to off: disable compilation. */
110static int j_off(lua_State *L)
111{
112 return setmode(L, LUAJIT_MODE_OFF);
113}
114
115/* Set JIT debug level. Defaults to maximum level for use with -j. */
116static int j_debug(lua_State *L)
117{
118 luaJIT_setmode(L, luaL_optinteger(L, 1, 100), LUAJIT_MODE_DEBUG);
119 return 0;
120}
121
122/* ------------------------------------------------------------------------ */
123
124/* Report the compilation status. */
125static int compstatus(lua_State *L, int status)
126{
127 if (status == -1)
128 return luaL_argerror(L, 1, "Lua function expected");
129 else if (status == JIT_S_OK)
130 return 0;
131 else {
132 lua_pushinteger(L, status);
133 return 1;
134 }
135}
136
137/* Compile a function. Pass typical args to help the optimizer. */
138static int j_compile(lua_State *L)
139{
140 int nargs = lua_gettop(L) - 1;
141 return compstatus(L, nargs >= 0 ? luaJIT_compile(L, nargs) : -1);
142}
143
144/* Recursively compile all subroutine prototypes. */
145static int rec_compile(lua_State *L, Proto *pt, Table *env, int stoponerror)
146{
147 int rstatus = JIT_S_OK;
148 int i;
149 for (i = 0; i < pt->sizep; i++) {
150 Proto *pti = pt->p[i];
151 int status;
152 push_LCL(L, pti, env); /* Assumes stack is at 2 (no upvalues). */
153 status = luaJIT_compile(L, 0);
154 lua_settop(L, 2); /* Clear stack */
155 if (status != JIT_S_OK) {
156 rstatus = status;
157 if (stoponerror) break;
158 }
159 status = rec_compile(L, pti, env, stoponerror);
160 if (status != JIT_S_OK) {
161 rstatus = status;
162 if (stoponerror) break;
163 }
164 }
165 return rstatus;
166}
167
168/* Compile all subroutines of a function. */
169/* Note: the function itself is _not_ compiled (use jit.compile()). */
170static int j_compilesub(lua_State *L)
171{
172 Closure *cl = check_LCL(L);
173 int stoponerror = lua_toboolean(L, 2); /* Stop on first error? */
174 lua_settop(L, 2);
175 return compstatus(L, rec_compile(L, cl->l.p, cl->l.env, stoponerror));
176}
177
178/* jit.* functions. */
179static const luaL_Reg jitlib[] = {
180 { "on", j_on },
181 { "off", j_off },
182 { "debug", j_debug },
183 { "compile", j_compile },
184 { "compilesub", j_compilesub },
185 /* j_attach is added below. */
186 { NULL, NULL }
187};
188
189/* ------------------------------------------------------------------------ */
190
191/* Get the compiler pipeline table from an upvalue (j_attach, j_frontend). */
192#define COMPIPE lua_upvalueindex(1)
193
194/* Attach/detach handler to/from compiler pipeline. */
195static int j_attach(lua_State *L)
196{
197 int pipesz;
198 luaL_checktype(L, 1, LUA_TFUNCTION);
199 pipesz = lua_objlen(L, COMPIPE);
200 if (lua_isnoneornil(L, 2)) { /* Detach if no priority given. */
201 int i;
202 for (i = 1; i <= pipesz; i += 2) {
203 lua_rawgeti(L, COMPIPE, i);
204 if (lua_rawequal(L, 1, -1)) { /* Found: delete from pipeline. */
205 for (; i+2 <= pipesz; i++) { /* Shift down. */
206 lua_rawgeti(L, COMPIPE, i+2);
207 lua_rawseti(L, COMPIPE, i);
208 }
209 /* Clear last two elements. */
210 lua_pushnil(L); lua_rawseti(L, COMPIPE, i);
211 lua_pushnil(L); lua_rawseti(L, COMPIPE, i+1);
212 return 0;
213 }
214 lua_pop(L, 1);
215 }
216 return 0; /* Not found: ignore detach request. */
217 } else { /* Attach if priority given. */
218 int prio = luaL_checkint(L, 2);
219 int pos, i;
220 for (pos = 2; pos <= pipesz; pos += 2) {
221 lua_rawgeti(L, COMPIPE, pos);
222 if (prio > (int)lua_tointeger(L, -1)) break; /* Insertion point found. */
223 lua_pop(L, 1);
224 }
225 for (i = pipesz+2; i > pos; i--) { /* Shift up. */
226 lua_rawgeti(L, COMPIPE, i-2);
227 lua_rawseti(L, COMPIPE, i);
228 }
229 /* Set handler and priority. */
230 lua_pushvalue(L, 1); lua_rawseti(L, COMPIPE, i-1);
231 lua_pushvalue(L, 2); lua_rawseti(L, COMPIPE, i);
232 return 0;
233 }
234}
235
236/* Compiler frontend. Runs in the compiler thread. */
237/* First and only arg is the compiler state table. */
238static int j_frontend(lua_State *L)
239{
240 int status = JIT_S_OK;
241 int pos;
242 /* Loop through all handlers in the compiler pipeline. */
243 for (pos = 1; ; pos += 2) {
244 if (status != JIT_S_OK) { /* Pending failure? */
245 int prio;
246 lua_rawgeti(L, COMPIPE, pos+1); /* Must check for odd/even priority. */
247 if (lua_isnil(L, -1)) break; /* End of pipeline. */
248 prio = (int)lua_tointeger(L, -1);
249 lua_pop(L, 1);
250 if ((prio & 1) == 0) continue; /* Skip handlers with even priority. */
251 }
252 /* Call handler with compiler state table and optional failure status. */
253 lua_rawgeti(L, COMPIPE, pos);
254 if (lua_isnil(L, -1)) break; /* End of pipeline. */
255 lua_pushvalue(L, 1);
256 if (status != JIT_S_OK)
257 lua_pushinteger(L, status);
258 lua_call(L, status ? 2 : 1, 1);
259 if (!lua_isnil(L, -1)) /* Remember failure status. */
260 status = (int)lua_tointeger(L, -1);
261 lua_pop(L, 1);
262 }
263 lua_pushinteger(L, status);
264 return 1;
265}
266
267/* Compiler frontend wrapper. */
268static int frontwrap(lua_State *L, Table *st)
269{
270 jit_State *J = G(L)->jit_state;
271 lua_State *JL;
272 int status;
273
274 /* Allocate compiler thread on demand. */
275 if (J->L == NULL) {
276 if (!lua_checkstack(L, 3)) return JIT_S_COMPILER_ERROR;
277 sethvalue(L, L->top++, st); /* Prevent GC of state table. */
278 lua_pushlightuserdata(L, (void *)&regkey_comthread);
279 /* Cannot use C stack, since it's deallocated early in Coco. */
280 /* But we don't need one -- the compiler thread never yields, anyway. */
281 J->L = lua_newthread(L);
282 lua_rawset(L, LUA_REGISTRYINDEX);
283 L->top--; /* Remove state table from this stack. */
284 }
285 JL = J->L;
286
287 /* Initialize compiler thread stack with frontend and state table. */
288 lua_settop(JL, 0);
289 lua_pushlightuserdata(JL, (void *)&regkey_frontend);
290 lua_rawget(JL, LUA_REGISTRYINDEX);
291 sethvalue(JL, JL->top, st);
292 JL->top++;
293
294 /* Start the frontend by resuming the compiler thread. */
295 if (lua_resume(JL, 1) != 0) { /* Failed? */
296 /* Note: LUA_YIELD is treated like any other error. */
297 J->L = NULL; /* Get a new thread next time. */
298 fprintf(stderr, "[LuaJIT frontend failed: %s]\n",
299 lua_isstring(JL, -1) ? lua_tostring(JL, -1) : "(unknown error)");
300 return JIT_S_COMPILER_ERROR;
301 }
302
303 /* Get status from terminated thread. */
304 status = (int)lua_tointeger(JL, -1);
305 lua_settop(JL, 0); /* Help the GC. */
306 return status;
307}
308
309/* Create the compiler pipeline and register it. */
310static void makepipeline(lua_State *L)
311{
312 lua_createtable(L, 20, 0); /* 10 handlers+priorities should be enough. */
313 lua_pushcfunction(L, luaJIT_backend);
314 lua_rawseti(L, -2, 1);
315 lua_pushinteger(L, 0); /* Fill in the backend at prio 0. */
316 lua_rawseti(L, -2, 2);
317
318 /* Store the compiler frontend in the registry. */
319 lua_pushlightuserdata(L, (void *)&regkey_frontend);
320 lua_pushvalue(L, -2); /* Pipeline table as upvalue. */
321 lua_pushcclosure(L, j_frontend, 1);
322 lua_rawset(L, LUA_REGISTRYINDEX);
323
324 /* Register the frontend wrapper. */
325 G(L)->jit_state->frontwrap = frontwrap;
326
327 /* Add jit.attach with the pipeline table as upvalue. */
328 lua_pushcclosure(L, j_attach, 1);
329 lua_setfield(L, -2, "attach"); /* "jit" table must be below. */
330}
331
332/* ------------------------------------------------------------------------ */
333
334/* Calculate total mcode size without mfm and only for active mcode blocks. */
335static size_t mcodesize(Proto *pt)
336{
337 jit_MCTrailer tr;
338 size_t sz = 0;
339 tr.mcode = (char *)pt->jit_mcode;
340 tr.sz = pt->jit_szmcode;
341 do {
342 jit_Mfm *mfm = JIT_MCMFM(tr.mcode, tr.sz);
343 if (sz != 0 && jit_mfm_ismain(mfm)) break; /* Stop at old main mfm. */
344 while (*mfm != JIT_MFM_STOP) mfm--; /* Search for end of mcode. */
345 sz += (char *)mfm-(char *)tr.mcode; /* Add size of mcode without mfm. */
346 memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz), sizeof(jit_MCTrailer));
347 } while (tr.mcode != NULL);
348 return sz;
349}
350
351#define setintfield(name, i) \
352 do { lua_pushinteger(L, i); lua_setfield(L, -2, name); } while (0)
353
354/* local stats = jit.util.stats(func) */
355static int ju_stats(lua_State *L)
356{
357 if (!(L->top > L->base))
358 luaL_argerror(L, 1, "Lua function expected");
359 if (isLfunction(L->base)) {
360 Proto *pt = clvalue(L->base)->l.p;
361 lua_createtable(L, 0, 11);
362 setintfield("status", pt->jit_status);
363 setintfield("stackslots", pt->maxstacksize);
364 setintfield("params", pt->numparams);
365 setintfield("bytecodes", pt->sizecode);
366 setintfield("consts", pt->sizek);
367 setintfield("upvalues", pt->nups);
368 setintfield("subs", pt->sizep);
369 lua_pushboolean(L, pt->is_vararg);
370 lua_setfield(L, -2, "isvararg");
371 lua_getfenv(L, 1);
372 lua_setfield(L, -2, "env");
373 if (pt->jit_szmcode != 0) {
374 setintfield("mcodesize", (int)mcodesize(pt));
375 lua_pushnumber(L, (lua_Number)(size_t)pt->jit_mcode);
376 lua_setfield(L, -2, "mcodeaddr");
377 }
378 return 1;
379 } else {
380 return 0; /* Don't throw an error like the other util functions. */
381 }
382}
383
384/* local op, a, b, c, test = jit.util.bytecode(func, pc) */
385static int ju_bytecode(lua_State *L)
386{
387 Proto *pt = check_LCL(L)->l.p;
388 int pc = luaL_checkint(L, 2);
389 if (pc >= 1 && pc <= pt->sizecode) {
390 Instruction ins = pt->code[pc-1];
391 OpCode op = GET_OPCODE(ins);
392 if (pc > 1 && (((int)OP_SETLIST) << POS_OP) ==
393 (pt->code[pc-2] & (MASK1(SIZE_OP,POS_OP) | MASK1(SIZE_C,POS_C)))) {
394 lua_pushstring(L, luaP_opnames[OP_SETLIST]);
395 lua_pushnumber(L, (lua_Number)ins); /* Fake extended op. */
396 return 1;
397 }
398 if (op >= NUM_OPCODES) return 0; /* Just in case. */
399 lua_pushstring(L, luaP_opnames[op]);
400 lua_pushinteger(L, GETARG_A(ins));
401 switch (getOpMode(op)) {
402 case iABC: {
403 int b = GETARG_B(ins), c = GETARG_C(ins);
404 switch (getBMode(op)) {
405 case OpArgN: lua_pushnil(L); break;
406 case OpArgK: if (ISK(b)) b = -1-INDEXK(b);
407 case OpArgR: case OpArgU: lua_pushinteger(L, b); break;
408 }
409 switch (getCMode(op)) {
410 case OpArgN: lua_pushnil(L); break;
411 case OpArgK: if (ISK(c)) c = -1-INDEXK(c);
412 case OpArgR: case OpArgU: lua_pushinteger(L, c); break;
413 }
414 lua_pushboolean(L, testTMode(op));
415 return 5;
416 }
417 case iABx: {
418 int bx = GETARG_Bx(ins);
419 lua_pushinteger(L, getBMode(op) == OpArgK ? -1-bx : bx);
420 return 3;
421 }
422 case iAsBx:
423 lua_pushinteger(L, GETARG_sBx(ins));
424 return 3;
425 }
426 }
427 return 0;
428}
429
430/* local const, ok = jit.util.const(func, idx) */
431static int ju_const(lua_State *L)
432{
433 Proto *pt = check_LCL(L)->l.p;
434 int idx = luaL_checkint(L, 2);
435 if (idx < 0) idx = -idx; /* Handle both positive and negative indices. */
436 if (idx >= 1 && idx <= pt->sizek) {
437 setobj2s(L, L->top-1, &pt->k[idx-1]);
438 lua_pushboolean(L, 1);
439 return 2;
440 }
441 lua_pushnil(L);
442 lua_pushboolean(L, 0);
443 return 2;
444}
445
446/* local upvalue, ok = jit.util.upvalue(func, idx) */
447static int ju_upvalue(lua_State *L)
448{
449 Closure *cl = check_LCL(L);
450 Proto *pt = cl->l.p;
451 int idx = luaL_checkint(L, 2);
452 if (idx >= 0 && idx < pt->nups) {
453 setobj2s(L, L->top-1, cl->l.upvals[idx]->v);
454 lua_pushboolean(L, 1);
455 return 2;
456 }
457 lua_pushnil(L);
458 lua_pushboolean(L, 0);
459 return 2;
460}
461
462/* local nup = jit.util.closurenup(func, idx) */
463static int ju_closurenup(lua_State *L)
464{
465 Closure *cl = check_LCL(L);
466 Proto *pt = cl->l.p;
467 int idx = luaL_checkint(L, 2);
468 if (idx >= 0 && idx < pt->sizep) {
469 lua_pushinteger(L, pt->p[idx]->nups);
470 return 1;
471 }
472 return 0;
473}
474
475/* for tag, mark in mfmiter do ... end. */
476static int ju_mfmiter(lua_State *L)
477{
478 jit_Mfm *mfm = (jit_Mfm *)lua_touserdata(L, lua_upvalueindex(1));
479 int m = *mfm--;
480 switch (m) {
481 case JIT_MFM_STOP: return 0;
482 case JIT_MFM_COMBINE: lua_pushliteral(L, "COMBINE"); lua_pushnil(L); break;
483 case JIT_MFM_DEAD: lua_pushliteral(L, "DEAD"); lua_pushnil(L); break;
484 default:
485 lua_pushinteger(L, m & JIT_MFM_MASK);
486 lua_pushboolean(L, m & JIT_MFM_MARK);
487 break;
488 }
489 lua_pushlightuserdata(L, (void *)mfm);
490 lua_replace(L, lua_upvalueindex(1));
491 return 2;
492}
493
494/* local addr, mcode, mfmiter = jit.util.mcode(func, block) */
495static int ju_mcode(lua_State *L)
496{
497 Proto *pt = check_LCL(L)->l.p;
498 if (pt->jit_szmcode == 0) { /* Not compiled (yet): return nil, status. */
499 lua_pushnil(L);
500 lua_pushinteger(L, pt->jit_status);
501 return 2;
502 } else {
503 jit_Mfm *mfm;
504 jit_MCTrailer tr;
505 int block = luaL_checkint(L, 2);
506 tr.mcode = (char *)pt->jit_mcode;
507 tr.sz = pt->jit_szmcode;
508 while (--block > 0) {
509 void *trp = JIT_MCTRAILER(tr.mcode, tr.sz);
510 memcpy((void *)&tr, trp, sizeof(jit_MCTrailer));
511 if (tr.sz == 0) return 0;
512 }
513 mfm = JIT_MCMFM(tr.mcode, tr.sz);
514 while (*mfm != JIT_MFM_STOP) mfm--; /* Search for end of mcode. */
515 lua_pushnumber(L, (lua_Number)(size_t)tr.mcode);
516 lua_pushlstring(L, (const char *)tr.mcode, (char *)mfm-(char *)tr.mcode);
517 lua_pushlightuserdata(L, (void *)JIT_MCMFM(tr.mcode, tr.sz));
518 lua_pushvalue(L, 1); /* Must hold onto function to avoid GC. */
519 lua_pushcclosure(L, ju_mfmiter, 2);
520 return 3;
521 }
522}
523
524/* local addr [, mcode] = jit.util.jsubmcode([idx]) */
525static int ju_jsubmcode(lua_State *L)
526{
527 jit_State *J = G(L)->jit_state;
528 if (lua_isnoneornil(L, 1)) {
529 lua_pushnumber(L, (lua_Number)(size_t)J->jsubmcode);
530 lua_pushlstring(L, (const char *)J->jsubmcode, J->szjsubmcode);
531 return 2;
532 } else {
533 int idx = luaL_checkint(L, 1);
534 if (idx >= 0 && idx < J->numjsub) {
535 lua_pushnumber(L, (lua_Number)(size_t)J->jsub[idx]);
536 return 1;
537 }
538 return 0;
539 }
540}
541
542/* FOR INTERNAL DEBUGGING USE ONLY: local addr = jit.util.stackptr() */
543static int ju_stackptr(lua_State *L)
544{
545 jit_State *J = G(L)->jit_state;
546 size_t addr = cast(size_t (*)(void), J->jsub[0])(); /* JSUB_STACKPTR == 0! */
547 lua_pushnumber(L, (lua_Number)addr);
548 return 1;
549}
550
551/* jit.util.* functions. */
552static const luaL_Reg jitutillib[] = {
553 {"stats", ju_stats },
554 {"bytecode", ju_bytecode },
555 {"const", ju_const },
556 {"upvalue", ju_upvalue },
557 {"closurenup", ju_closurenup },
558 {"mcode", ju_mcode },
559 {"jsubmcode", ju_jsubmcode },
560 {"stackptr", ju_stackptr },
561 { NULL, NULL }
562};
563
564/* Make hint name to hint number map. */
565static void makehints(lua_State *L, const char *const *t, int tmax,
566 const char *name)
567{
568 int i;
569 lua_createtable(L, 0, tmax);
570 for (i = 1; i < tmax; i++) {
571 lua_pushinteger(L, JIT_H2NUM(i));
572 lua_setfield(L, -2, t[i-1]);
573 }
574 lua_setfield(L, -2, name);
575}
576
577/* CHECK: must match with ljit.h (grep "ORDER JIT_S"). */
578static const char *const status_list[] = {
579 "OK",
580 "NONE",
581 "OFF",
582 "ENGINE_OFF",
583 "DELAYED",
584 "TOOLARGE",
585 "COMPILER_ERROR",
586 "DASM_ERROR"
587};
588
589/* Make bidirectional status name to status number map. */
590static void makestatus(lua_State *L, const char *name)
591{
592 int i;
593 lua_createtable(L, JIT_S_MAX-1, JIT_S_MAX+1); /* Codes are not 1-based. */
594 for (i = 0; i < JIT_S_MAX; i++) {
595 lua_pushstring(L, status_list[i]);
596 lua_pushinteger(L, i);
597 lua_pushvalue(L, -2);
598 lua_rawseti(L, -4, i);
599 lua_rawset(L, -3);
600 }
601 lua_setfield(L, -2, name);
602}
603
604/* ------------------------------------------------------------------------ */
605
606/*
607** Open JIT library
608*/
609LUALIB_API int luaopen_jit(lua_State *L)
610{
611 /* Add the core JIT library. */
612 luaL_register(L, LUA_JITLIBNAME, jitlib);
613 lua_pushliteral(L, LUAJIT_VERSION);
614 lua_setfield(L, -2, "version");
615 setintfield("version_num", LUAJIT_VERSION_NUM);
616 lua_pushstring(L, luaJIT_arch);
617 lua_setfield(L, -2, "arch");
618 makepipeline(L);
619
620 /* Add the utility JIT library. */
621 luaL_register(L, LUA_JITLIBNAME ".util", jitutillib);
622 makestatus(L, "status");
623 makehints(L, hints_H, JIT_H_MAX, "hints");
624 makehints(L, hints_FH, JIT_FH_MAX, "fhints");
625 lua_pop(L, 1);
626
627 /* Everything ok, so turn the JIT engine on. Vroooom! */
628 if (luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_ON) <= 0) {
629 /* Ouch. Someone screwed up DynASM or the JSUBs. Probably me. */
630 /* But if you get 999999999, look at jit_consistency_check(). */
631 return luaL_error(L, "JIT engine init failed (%d)",
632 G(L)->jit_state->dasmstatus);
633 }
634
635 return 1;
636}
637
diff --git a/libraries/LuaJIT-1.1.7/src/llex.c b/libraries/LuaJIT-1.1.7/src/llex.c
new file mode 100644
index 0000000..92d6575
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/llex.c
@@ -0,0 +1,463 @@
1/*
2** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $
3** Lexical Analyzer
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <locale.h>
10#include <string.h>
11
12#define llex_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "ldo.h"
18#include "llex.h"
19#include "lobject.h"
20#include "lparser.h"
21#include "lstate.h"
22#include "lstring.h"
23#include "ltable.h"
24#include "lzio.h"
25
26
27
28#define next(ls) (ls->current = zgetc(ls->z))
29
30
31
32
33#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
34
35
36/* ORDER RESERVED */
37const char *const luaX_tokens [] = {
38 "and", "break", "do", "else", "elseif",
39 "end", "false", "for", "function", "if",
40 "in", "local", "nil", "not", "or", "repeat",
41 "return", "then", "true", "until", "while",
42 "..", "...", "==", ">=", "<=", "~=",
43 "<number>", "<name>", "<string>", "<eof>",
44 NULL
45};
46
47
48#define save_and_next(ls) (save(ls, ls->current), next(ls))
49
50
51static void save (LexState *ls, int c) {
52 Mbuffer *b = ls->buff;
53 if (b->n + 1 > b->buffsize) {
54 size_t newsize;
55 if (b->buffsize >= MAX_SIZET/2)
56 luaX_lexerror(ls, "lexical element too long", 0);
57 newsize = b->buffsize * 2;
58 luaZ_resizebuffer(ls->L, b, newsize);
59 }
60 b->buffer[b->n++] = cast(char, c);
61}
62
63
64void luaX_init (lua_State *L) {
65 int i;
66 for (i=0; i<NUM_RESERVED; i++) {
67 TString *ts = luaS_new(L, luaX_tokens[i]);
68 luaS_fix(ts); /* reserved words are never collected */
69 lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
70 ts->tsv.reserved = cast_byte(i+1); /* reserved word */
71 }
72}
73
74
75#define MAXSRC 80
76
77
78const char *luaX_token2str (LexState *ls, int token) {
79 if (token < FIRST_RESERVED) {
80 lua_assert(token == cast(unsigned char, token));
81 return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
82 luaO_pushfstring(ls->L, "%c", token);
83 }
84 else
85 return luaX_tokens[token-FIRST_RESERVED];
86}
87
88
89static const char *txtToken (LexState *ls, int token) {
90 switch (token) {
91 case TK_NAME:
92 case TK_STRING:
93 case TK_NUMBER:
94 save(ls, '\0');
95 return luaZ_buffer(ls->buff);
96 default:
97 return luaX_token2str(ls, token);
98 }
99}
100
101
102void luaX_lexerror (LexState *ls, const char *msg, int token) {
103 char buff[MAXSRC];
104 luaO_chunkid(buff, getstr(ls->source), MAXSRC);
105 msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
106 if (token)
107 luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token));
108 luaD_throw(ls->L, LUA_ERRSYNTAX);
109}
110
111
112void luaX_syntaxerror (LexState *ls, const char *msg) {
113 luaX_lexerror(ls, msg, ls->t.token);
114}
115
116
117TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
118 lua_State *L = ls->L;
119 TString *ts = luaS_newlstr(L, str, l);
120 TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
121 if (ttisnil(o)) {
122 setbvalue(o, 1); /* make sure `str' will not be collected */
123 luaC_checkGC(L);
124 }
125 return ts;
126}
127
128
129static void inclinenumber (LexState *ls) {
130 int old = ls->current;
131 lua_assert(currIsNewline(ls));
132 next(ls); /* skip `\n' or `\r' */
133 if (currIsNewline(ls) && ls->current != old)
134 next(ls); /* skip `\n\r' or `\r\n' */
135 if (++ls->linenumber >= MAX_INT)
136 luaX_syntaxerror(ls, "chunk has too many lines");
137}
138
139
140void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
141 ls->decpoint = '.';
142 ls->L = L;
143 ls->lookahead.token = TK_EOS; /* no look-ahead token */
144 ls->z = z;
145 ls->fs = NULL;
146 ls->linenumber = 1;
147 ls->lastline = 1;
148 ls->source = source;
149 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
150 next(ls); /* read first char */
151}
152
153
154
155/*
156** =======================================================
157** LEXICAL ANALYZER
158** =======================================================
159*/
160
161
162
163static int check_next (LexState *ls, const char *set) {
164 if (!strchr(set, ls->current))
165 return 0;
166 save_and_next(ls);
167 return 1;
168}
169
170
171static void buffreplace (LexState *ls, char from, char to) {
172 size_t n = luaZ_bufflen(ls->buff);
173 char *p = luaZ_buffer(ls->buff);
174 while (n--)
175 if (p[n] == from) p[n] = to;
176}
177
178
179static void trydecpoint (LexState *ls, SemInfo *seminfo) {
180 /* format error: try to update decimal point separator */
181 struct lconv *cv = localeconv();
182 char old = ls->decpoint;
183 ls->decpoint = (cv ? cv->decimal_point[0] : '.');
184 buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
185 if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
186 /* format error with correct decimal point: no more options */
187 buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
188 luaX_lexerror(ls, "malformed number", TK_NUMBER);
189 }
190}
191
192
193/* LUA_NUMBER */
194static void read_numeral (LexState *ls, SemInfo *seminfo) {
195 lua_assert(isdigit(ls->current));
196 do {
197 save_and_next(ls);
198 } while (isdigit(ls->current) || ls->current == '.');
199 if (check_next(ls, "Ee")) /* `E'? */
200 check_next(ls, "+-"); /* optional exponent sign */
201 while (isalnum(ls->current) || ls->current == '_')
202 save_and_next(ls);
203 save(ls, '\0');
204 buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
205 if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
206 trydecpoint(ls, seminfo); /* try to update decimal point separator */
207}
208
209
210static int skip_sep (LexState *ls) {
211 int count = 0;
212 int s = ls->current;
213 lua_assert(s == '[' || s == ']');
214 save_and_next(ls);
215 while (ls->current == '=') {
216 save_and_next(ls);
217 count++;
218 }
219 return (ls->current == s) ? count : (-count) - 1;
220}
221
222
223static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
224 int cont = 0;
225 (void)(cont); /* avoid warnings when `cont' is not used */
226 save_and_next(ls); /* skip 2nd `[' */
227 if (currIsNewline(ls)) /* string starts with a newline? */
228 inclinenumber(ls); /* skip it */
229 for (;;) {
230 switch (ls->current) {
231 case EOZ:
232 luaX_lexerror(ls, (seminfo) ? "unfinished long string" :
233 "unfinished long comment", TK_EOS);
234 break; /* to avoid warnings */
235#if defined(LUA_COMPAT_LSTR)
236 case '[': {
237 if (skip_sep(ls) == sep) {
238 save_and_next(ls); /* skip 2nd `[' */
239 cont++;
240#if LUA_COMPAT_LSTR == 1
241 if (sep == 0)
242 luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
243#endif
244 }
245 break;
246 }
247#endif
248 case ']': {
249 if (skip_sep(ls) == sep) {
250 save_and_next(ls); /* skip 2nd `]' */
251#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
252 cont--;
253 if (sep == 0 && cont >= 0) break;
254#endif
255 goto endloop;
256 }
257 break;
258 }
259 case '\n':
260 case '\r': {
261 save(ls, '\n');
262 inclinenumber(ls);
263 if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
264 break;
265 }
266 default: {
267 if (seminfo) save_and_next(ls);
268 else next(ls);
269 }
270 }
271 } endloop:
272 if (seminfo)
273 seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
274 luaZ_bufflen(ls->buff) - 2*(2 + sep));
275}
276
277
278static void read_string (LexState *ls, int del, SemInfo *seminfo) {
279 save_and_next(ls);
280 while (ls->current != del) {
281 switch (ls->current) {
282 case EOZ:
283 luaX_lexerror(ls, "unfinished string", TK_EOS);
284 continue; /* to avoid warnings */
285 case '\n':
286 case '\r':
287 luaX_lexerror(ls, "unfinished string", TK_STRING);
288 continue; /* to avoid warnings */
289 case '\\': {
290 int c;
291 next(ls); /* do not save the `\' */
292 switch (ls->current) {
293 case 'a': c = '\a'; break;
294 case 'b': c = '\b'; break;
295 case 'f': c = '\f'; break;
296 case 'n': c = '\n'; break;
297 case 'r': c = '\r'; break;
298 case 't': c = '\t'; break;
299 case 'v': c = '\v'; break;
300 case '\n': /* go through */
301 case '\r': save(ls, '\n'); inclinenumber(ls); continue;
302 case EOZ: continue; /* will raise an error next loop */
303 default: {
304 if (!isdigit(ls->current))
305 save_and_next(ls); /* handles \\, \", \', and \? */
306 else { /* \xxx */
307 int i = 0;
308 c = 0;
309 do {
310 c = 10*c + (ls->current-'0');
311 next(ls);
312 } while (++i<3 && isdigit(ls->current));
313 if (c > UCHAR_MAX)
314 luaX_lexerror(ls, "escape sequence too large", TK_STRING);
315 save(ls, c);
316 }
317 continue;
318 }
319 }
320 save(ls, c);
321 next(ls);
322 continue;
323 }
324 default:
325 save_and_next(ls);
326 }
327 }
328 save_and_next(ls); /* skip delimiter */
329 seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
330 luaZ_bufflen(ls->buff) - 2);
331}
332
333
334static int llex (LexState *ls, SemInfo *seminfo) {
335 luaZ_resetbuffer(ls->buff);
336 for (;;) {
337 switch (ls->current) {
338 case '\n':
339 case '\r': {
340 inclinenumber(ls);
341 continue;
342 }
343 case '-': {
344 next(ls);
345 if (ls->current != '-') return '-';
346 /* else is a comment */
347 next(ls);
348 if (ls->current == '[') {
349 int sep = skip_sep(ls);
350 luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
351 if (sep >= 0) {
352 read_long_string(ls, NULL, sep); /* long comment */
353 luaZ_resetbuffer(ls->buff);
354 continue;
355 }
356 }
357 /* else short comment */
358 while (!currIsNewline(ls) && ls->current != EOZ)
359 next(ls);
360 continue;
361 }
362 case '[': {
363 int sep = skip_sep(ls);
364 if (sep >= 0) {
365 read_long_string(ls, seminfo, sep);
366 return TK_STRING;
367 }
368 else if (sep == -1) return '[';
369 else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
370 }
371 case '=': {
372 next(ls);
373 if (ls->current != '=') return '=';
374 else { next(ls); return TK_EQ; }
375 }
376 case '<': {
377 next(ls);
378 if (ls->current != '=') return '<';
379 else { next(ls); return TK_LE; }
380 }
381 case '>': {
382 next(ls);
383 if (ls->current != '=') return '>';
384 else { next(ls); return TK_GE; }
385 }
386 case '~': {
387 next(ls);
388 if (ls->current != '=') return '~';
389 else { next(ls); return TK_NE; }
390 }
391 case '"':
392 case '\'': {
393 read_string(ls, ls->current, seminfo);
394 return TK_STRING;
395 }
396 case '.': {
397 save_and_next(ls);
398 if (check_next(ls, ".")) {
399 if (check_next(ls, "."))
400 return TK_DOTS; /* ... */
401 else return TK_CONCAT; /* .. */
402 }
403 else if (!isdigit(ls->current)) return '.';
404 else {
405 read_numeral(ls, seminfo);
406 return TK_NUMBER;
407 }
408 }
409 case EOZ: {
410 return TK_EOS;
411 }
412 default: {
413 if (isspace(ls->current)) {
414 lua_assert(!currIsNewline(ls));
415 next(ls);
416 continue;
417 }
418 else if (isdigit(ls->current)) {
419 read_numeral(ls, seminfo);
420 return TK_NUMBER;
421 }
422 else if (isalpha(ls->current) || ls->current == '_') {
423 /* identifier or reserved word */
424 TString *ts;
425 do {
426 save_and_next(ls);
427 } while (isalnum(ls->current) || ls->current == '_');
428 ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
429 luaZ_bufflen(ls->buff));
430 if (ts->tsv.reserved > 0) /* reserved word? */
431 return ts->tsv.reserved - 1 + FIRST_RESERVED;
432 else {
433 seminfo->ts = ts;
434 return TK_NAME;
435 }
436 }
437 else {
438 int c = ls->current;
439 next(ls);
440 return c; /* single-char tokens (+ - / ...) */
441 }
442 }
443 }
444 }
445}
446
447
448void luaX_next (LexState *ls) {
449 ls->lastline = ls->linenumber;
450 if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
451 ls->t = ls->lookahead; /* use this one */
452 ls->lookahead.token = TK_EOS; /* and discharge it */
453 }
454 else
455 ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
456}
457
458
459void luaX_lookahead (LexState *ls) {
460 lua_assert(ls->lookahead.token == TK_EOS);
461 ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
462}
463
diff --git a/libraries/LuaJIT-1.1.7/src/llex.h b/libraries/LuaJIT-1.1.7/src/llex.h
new file mode 100644
index 0000000..a9201ce
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/llex.h
@@ -0,0 +1,81 @@
1/*
2** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $
3** Lexical Analyzer
4** See Copyright Notice in lua.h
5*/
6
7#ifndef llex_h
8#define llex_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13
14#define FIRST_RESERVED 257
15
16/* maximum length of a reserved word */
17#define TOKEN_LEN (sizeof("function")/sizeof(char))
18
19
20/*
21* WARNING: if you change the order of this enumeration,
22* grep "ORDER RESERVED"
23*/
24enum RESERVED {
25 /* terminal symbols denoted by reserved words */
26 TK_AND = FIRST_RESERVED, TK_BREAK,
27 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
28 TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
29 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
30 /* other terminal symbols */
31 TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
32 TK_NAME, TK_STRING, TK_EOS
33};
34
35/* number of reserved words */
36#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
37
38
39/* array with token `names' */
40LUAI_DATA const char *const luaX_tokens [];
41
42
43typedef union {
44 lua_Number r;
45 TString *ts;
46} SemInfo; /* semantics information */
47
48
49typedef struct Token {
50 int token;
51 SemInfo seminfo;
52} Token;
53
54
55typedef struct LexState {
56 int current; /* current character (charint) */
57 int linenumber; /* input line counter */
58 int lastline; /* line of last token `consumed' */
59 Token t; /* current token */
60 Token lookahead; /* look ahead token */
61 struct FuncState *fs; /* `FuncState' is private to the parser */
62 struct lua_State *L;
63 ZIO *z; /* input stream */
64 Mbuffer *buff; /* buffer for tokens */
65 TString *source; /* current source name */
66 char decpoint; /* locale decimal point */
67} LexState;
68
69
70LUAI_FUNC void luaX_init (lua_State *L);
71LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
72 TString *source);
73LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
74LUAI_FUNC void luaX_next (LexState *ls);
75LUAI_FUNC void luaX_lookahead (LexState *ls);
76LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
77LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
78LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
79
80
81#endif
diff --git a/libraries/LuaJIT-1.1.7/src/llimits.h b/libraries/LuaJIT-1.1.7/src/llimits.h
new file mode 100644
index 0000000..ca8dcb7
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/llimits.h
@@ -0,0 +1,128 @@
1/*
2** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $
3** Limits, basic types, and some other `installation-dependent' definitions
4** See Copyright Notice in lua.h
5*/
6
7#ifndef llimits_h
8#define llimits_h
9
10
11#include <limits.h>
12#include <stddef.h>
13
14
15#include "lua.h"
16
17
18typedef LUAI_UINT32 lu_int32;
19
20typedef LUAI_UMEM lu_mem;
21
22typedef LUAI_MEM l_mem;
23
24
25
26/* chars used as small naturals (so that `char' is reserved for characters) */
27typedef unsigned char lu_byte;
28
29
30#define MAX_SIZET ((size_t)(~(size_t)0)-2)
31
32#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
33
34
35#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
36
37/*
38** conversion of pointer to integer
39** this is for hashing only; there is no problem if the integer
40** cannot hold the whole pointer value
41*/
42#define IntPoint(p) ((unsigned int)(lu_mem)(p))
43
44
45
46/* type to ensure maximum alignment */
47typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
48
49
50/* result of a `usual argument conversion' over lua_Number */
51typedef LUAI_UACNUMBER l_uacNumber;
52
53
54/* internal assertions for in-house debugging */
55#ifdef lua_assert
56
57#define check_exp(c,e) (lua_assert(c), (e))
58#define api_check(l,e) lua_assert(e)
59
60#else
61
62#define lua_assert(c) ((void)0)
63#define check_exp(c,e) (e)
64#define api_check luai_apicheck
65
66#endif
67
68
69#ifndef UNUSED
70#define UNUSED(x) ((void)(x)) /* to avoid warnings */
71#endif
72
73
74#ifndef cast
75#define cast(t, exp) ((t)(exp))
76#endif
77
78#define cast_byte(i) cast(lu_byte, (i))
79#define cast_num(i) cast(lua_Number, (i))
80#define cast_int(i) cast(int, (i))
81
82
83
84/*
85** type for virtual-machine instructions
86** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
87*/
88typedef lu_int32 Instruction;
89
90
91
92/* maximum stack for a Lua function */
93#define MAXSTACK 250
94
95
96
97/* minimum size for the string table (must be power of 2) */
98#ifndef MINSTRTABSIZE
99#define MINSTRTABSIZE 32
100#endif
101
102
103/* minimum size for string buffer */
104#ifndef LUA_MINBUFFER
105#define LUA_MINBUFFER 32
106#endif
107
108
109#ifndef lua_lock
110#define lua_lock(L) ((void) 0)
111#define lua_unlock(L) ((void) 0)
112#endif
113
114#ifndef luai_threadyield
115#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
116#endif
117
118
119/*
120** macro to control inclusion of some hard tests on stack reallocation
121*/
122#ifndef HARDSTACKTESTS
123#define condhardstacktests(x) ((void)0)
124#else
125#define condhardstacktests(x) x
126#endif
127
128#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lmathlib.c b/libraries/LuaJIT-1.1.7/src/lmathlib.c
new file mode 100644
index 0000000..441fbf7
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lmathlib.c
@@ -0,0 +1,263 @@
1/*
2** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $
3** Standard mathematical library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdlib.h>
9#include <math.h>
10
11#define lmathlib_c
12#define LUA_LIB
13
14#include "lua.h"
15
16#include "lauxlib.h"
17#include "lualib.h"
18
19
20#undef PI
21#define PI (3.14159265358979323846)
22#define RADIANS_PER_DEGREE (PI/180.0)
23
24
25
26static int math_abs (lua_State *L) {
27 lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
28 return 1;
29}
30
31static int math_sin (lua_State *L) {
32 lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
33 return 1;
34}
35
36static int math_sinh (lua_State *L) {
37 lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
38 return 1;
39}
40
41static int math_cos (lua_State *L) {
42 lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
43 return 1;
44}
45
46static int math_cosh (lua_State *L) {
47 lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
48 return 1;
49}
50
51static int math_tan (lua_State *L) {
52 lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
53 return 1;
54}
55
56static int math_tanh (lua_State *L) {
57 lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
58 return 1;
59}
60
61static int math_asin (lua_State *L) {
62 lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
63 return 1;
64}
65
66static int math_acos (lua_State *L) {
67 lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
68 return 1;
69}
70
71static int math_atan (lua_State *L) {
72 lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
73 return 1;
74}
75
76static int math_atan2 (lua_State *L) {
77 lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
78 return 1;
79}
80
81static int math_ceil (lua_State *L) {
82 lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
83 return 1;
84}
85
86static int math_floor (lua_State *L) {
87 lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
88 return 1;
89}
90
91static int math_fmod (lua_State *L) {
92 lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
93 return 1;
94}
95
96static int math_modf (lua_State *L) {
97 double ip;
98 double fp = modf(luaL_checknumber(L, 1), &ip);
99 lua_pushnumber(L, ip);
100 lua_pushnumber(L, fp);
101 return 2;
102}
103
104static int math_sqrt (lua_State *L) {
105 lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
106 return 1;
107}
108
109static int math_pow (lua_State *L) {
110 lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
111 return 1;
112}
113
114static int math_log (lua_State *L) {
115 lua_pushnumber(L, log(luaL_checknumber(L, 1)));
116 return 1;
117}
118
119static int math_log10 (lua_State *L) {
120 lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
121 return 1;
122}
123
124static int math_exp (lua_State *L) {
125 lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
126 return 1;
127}
128
129static int math_deg (lua_State *L) {
130 lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
131 return 1;
132}
133
134static int math_rad (lua_State *L) {
135 lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
136 return 1;
137}
138
139static int math_frexp (lua_State *L) {
140 int e;
141 lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
142 lua_pushinteger(L, e);
143 return 2;
144}
145
146static int math_ldexp (lua_State *L) {
147 lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
148 return 1;
149}
150
151
152
153static int math_min (lua_State *L) {
154 int n = lua_gettop(L); /* number of arguments */
155 lua_Number dmin = luaL_checknumber(L, 1);
156 int i;
157 for (i=2; i<=n; i++) {
158 lua_Number d = luaL_checknumber(L, i);
159 if (d < dmin)
160 dmin = d;
161 }
162 lua_pushnumber(L, dmin);
163 return 1;
164}
165
166
167static int math_max (lua_State *L) {
168 int n = lua_gettop(L); /* number of arguments */
169 lua_Number dmax = luaL_checknumber(L, 1);
170 int i;
171 for (i=2; i<=n; i++) {
172 lua_Number d = luaL_checknumber(L, i);
173 if (d > dmax)
174 dmax = d;
175 }
176 lua_pushnumber(L, dmax);
177 return 1;
178}
179
180
181static int math_random (lua_State *L) {
182 /* the `%' avoids the (rare) case of r==1, and is needed also because on
183 some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
184 lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
185 switch (lua_gettop(L)) { /* check number of arguments */
186 case 0: { /* no arguments */
187 lua_pushnumber(L, r); /* Number between 0 and 1 */
188 break;
189 }
190 case 1: { /* only upper limit */
191 int u = luaL_checkint(L, 1);
192 luaL_argcheck(L, 1<=u, 1, "interval is empty");
193 lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
194 break;
195 }
196 case 2: { /* lower and upper limits */
197 int l = luaL_checkint(L, 1);
198 int u = luaL_checkint(L, 2);
199 luaL_argcheck(L, l<=u, 2, "interval is empty");
200 lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
201 break;
202 }
203 default: return luaL_error(L, "wrong number of arguments");
204 }
205 return 1;
206}
207
208
209static int math_randomseed (lua_State *L) {
210 srand(luaL_checkint(L, 1));
211 return 0;
212}
213
214
215static const luaL_Reg mathlib[] = {
216 {"abs", math_abs},
217 {"acos", math_acos},
218 {"asin", math_asin},
219 {"atan2", math_atan2},
220 {"atan", math_atan},
221 {"ceil", math_ceil},
222 {"cosh", math_cosh},
223 {"cos", math_cos},
224 {"deg", math_deg},
225 {"exp", math_exp},
226 {"floor", math_floor},
227 {"fmod", math_fmod},
228 {"frexp", math_frexp},
229 {"ldexp", math_ldexp},
230 {"log10", math_log10},
231 {"log", math_log},
232 {"max", math_max},
233 {"min", math_min},
234 {"modf", math_modf},
235 {"pow", math_pow},
236 {"rad", math_rad},
237 {"random", math_random},
238 {"randomseed", math_randomseed},
239 {"sinh", math_sinh},
240 {"sin", math_sin},
241 {"sqrt", math_sqrt},
242 {"tanh", math_tanh},
243 {"tan", math_tan},
244 {NULL, NULL}
245};
246
247
248/*
249** Open math library
250*/
251LUALIB_API int luaopen_math (lua_State *L) {
252 luaL_register(L, LUA_MATHLIBNAME, mathlib);
253 lua_pushnumber(L, PI);
254 lua_setfield(L, -2, "pi");
255 lua_pushnumber(L, HUGE_VAL);
256 lua_setfield(L, -2, "huge");
257#if defined(LUA_COMPAT_MOD)
258 lua_getfield(L, -1, "fmod");
259 lua_setfield(L, -2, "mod");
260#endif
261 return 1;
262}
263
diff --git a/libraries/LuaJIT-1.1.7/src/lmem.c b/libraries/LuaJIT-1.1.7/src/lmem.c
new file mode 100644
index 0000000..ae7d8c9
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lmem.c
@@ -0,0 +1,86 @@
1/*
2** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $
3** Interface to Memory Manager
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lmem_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "ldebug.h"
16#include "ldo.h"
17#include "lmem.h"
18#include "lobject.h"
19#include "lstate.h"
20
21
22
23/*
24** About the realloc function:
25** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
26** (`osize' is the old size, `nsize' is the new size)
27**
28** Lua ensures that (ptr == NULL) iff (osize == 0).
29**
30** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
31**
32** * frealloc(ud, p, x, 0) frees the block `p'
33** (in this specific case, frealloc must return NULL).
34** particularly, frealloc(ud, NULL, 0, 0) does nothing
35** (which is equivalent to free(NULL) in ANSI C)
36**
37** frealloc returns NULL if it cannot create or reallocate the area
38** (any reallocation to an equal or smaller size cannot fail!)
39*/
40
41
42
43#define MINSIZEARRAY 4
44
45
46void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
47 int limit, const char *errormsg) {
48 void *newblock;
49 int newsize;
50 if (*size >= limit/2) { /* cannot double it? */
51 if (*size >= limit) /* cannot grow even a little? */
52 luaG_runerror(L, errormsg);
53 newsize = limit; /* still have at least one free place */
54 }
55 else {
56 newsize = (*size)*2;
57 if (newsize < MINSIZEARRAY)
58 newsize = MINSIZEARRAY; /* minimum size */
59 }
60 newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
61 *size = newsize; /* update only when everything else is OK */
62 return newblock;
63}
64
65
66void *luaM_toobig (lua_State *L) {
67 luaG_runerror(L, "memory allocation error: block too big");
68 return NULL; /* to avoid warnings */
69}
70
71
72
73/*
74** generic allocation routine.
75*/
76void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
77 global_State *g = G(L);
78 lua_assert((osize == 0) == (block == NULL));
79 block = (*g->frealloc)(g->ud, block, osize, nsize);
80 if (block == NULL && nsize > 0)
81 luaD_throw(L, LUA_ERRMEM);
82 lua_assert((nsize == 0) == (block == NULL));
83 g->totalbytes = (g->totalbytes - osize) + nsize;
84 return block;
85}
86
diff --git a/libraries/LuaJIT-1.1.7/src/lmem.h b/libraries/LuaJIT-1.1.7/src/lmem.h
new file mode 100644
index 0000000..7c2dcb3
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lmem.h
@@ -0,0 +1,49 @@
1/*
2** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
3** Interface to Memory Manager
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lmem_h
8#define lmem_h
9
10
11#include <stddef.h>
12
13#include "llimits.h"
14#include "lua.h"
15
16#define MEMERRMSG "not enough memory"
17
18
19#define luaM_reallocv(L,b,on,n,e) \
20 ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
21 luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
22 luaM_toobig(L))
23
24#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
25#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
26#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t))
27
28#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t))
29#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
30#define luaM_newvector(L,n,t) \
31 cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
32
33#define luaM_growvector(L,v,nelems,size,t,limit,e) \
34 if ((nelems)+1 > (size)) \
35 ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
36
37#define luaM_reallocvector(L, v,oldn,n,t) \
38 ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
39
40
41LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
42 size_t size);
43LUAI_FUNC void *luaM_toobig (lua_State *L);
44LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
45 size_t size_elem, int limit,
46 const char *errormsg);
47
48#endif
49
diff --git a/libraries/LuaJIT-1.1.7/src/loadlib.c b/libraries/LuaJIT-1.1.7/src/loadlib.c
new file mode 100644
index 0000000..a2da9fc
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/loadlib.c
@@ -0,0 +1,669 @@
1/*
2** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $
3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h
5**
6** This module contains an implementation of loadlib for Unix systems
7** that have dlfcn, an implementation for Darwin (Mac OS X), an
8** implementation for Windows, and a stub for other systems.
9*/
10
11
12#include <stdlib.h>
13#include <string.h>
14
15
16#define loadlib_c
17#define LUA_LIB
18
19#include "lua.h"
20
21#include "lauxlib.h"
22#include "lualib.h"
23#include "luajit.h"
24
25
26/* prefix for open functions in C libraries */
27#define LUA_POF "luaopen_"
28
29/* separator for open functions in C libraries */
30#define LUA_OFSEP "_"
31
32
33#define LIBPREFIX "LOADLIB: "
34
35#define POF LUA_POF
36#define LIB_FAIL "open"
37
38
39/* error codes for ll_loadfunc */
40#define ERRLIB 1
41#define ERRFUNC 2
42
43#define setprogdir(L) ((void)0)
44
45
46static void ll_unloadlib (void *lib);
47static void *ll_load (lua_State *L, const char *path);
48static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
49
50
51
52#if defined(LUA_DL_DLOPEN)
53/*
54** {========================================================================
55** This is an implementation of loadlib based on the dlfcn interface.
56** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
57** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
58** as an emulation layer on top of native functions.
59** =========================================================================
60*/
61
62#include <dlfcn.h>
63
64static void ll_unloadlib (void *lib) {
65 dlclose(lib);
66}
67
68
69static void *ll_load (lua_State *L, const char *path) {
70 void *lib = dlopen(path, RTLD_NOW);
71 if (lib == NULL) lua_pushstring(L, dlerror());
72 return lib;
73}
74
75
76static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
77 lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
78 if (f == NULL) lua_pushstring(L, dlerror());
79 return f;
80}
81
82/* }====================================================== */
83
84
85
86#elif defined(LUA_DL_DLL)
87/*
88** {======================================================================
89** This is an implementation of loadlib for Windows using native functions.
90** =======================================================================
91*/
92
93#include <windows.h>
94
95
96#undef setprogdir
97
98static void setprogdir (lua_State *L) {
99 char buff[MAX_PATH + 1];
100 char *lb;
101 DWORD nsize = sizeof(buff)/sizeof(char);
102 DWORD n = GetModuleFileNameA(NULL, buff, nsize);
103 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
104 luaL_error(L, "unable to get ModuleFileName");
105 else {
106 *lb = '\0';
107 luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
108 lua_remove(L, -2); /* remove original string */
109 }
110}
111
112
113static void pusherror (lua_State *L) {
114 int error = GetLastError();
115 char buffer[128];
116 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
117 NULL, error, 0, buffer, sizeof(buffer), NULL))
118 lua_pushstring(L, buffer);
119 else
120 lua_pushfstring(L, "system error %d\n", error);
121}
122
123static void ll_unloadlib (void *lib) {
124 FreeLibrary((HINSTANCE)lib);
125}
126
127
128static void *ll_load (lua_State *L, const char *path) {
129 HINSTANCE lib = LoadLibraryA(path);
130 if (lib == NULL) pusherror(L);
131 return lib;
132}
133
134
135static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
136 lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
137 if (f == NULL) pusherror(L);
138 return f;
139}
140
141/* }====================================================== */
142
143
144
145#elif defined(LUA_DL_DYLD)
146/*
147** {======================================================================
148** Native Mac OS X / Darwin Implementation
149** =======================================================================
150*/
151
152#include <mach-o/dyld.h>
153
154
155/* Mac appends a `_' before C function names */
156#undef POF
157#define POF "_" LUA_POF
158
159
160static void pusherror (lua_State *L) {
161 const char *err_str;
162 const char *err_file;
163 NSLinkEditErrors err;
164 int err_num;
165 NSLinkEditError(&err, &err_num, &err_file, &err_str);
166 lua_pushstring(L, err_str);
167}
168
169
170static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
171 switch (ret) {
172 case NSObjectFileImageInappropriateFile:
173 return "file is not a bundle";
174 case NSObjectFileImageArch:
175 return "library is for wrong CPU type";
176 case NSObjectFileImageFormat:
177 return "bad format";
178 case NSObjectFileImageAccess:
179 return "cannot access file";
180 case NSObjectFileImageFailure:
181 default:
182 return "unable to load library";
183 }
184}
185
186
187static void ll_unloadlib (void *lib) {
188 NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
189}
190
191
192static void *ll_load (lua_State *L, const char *path) {
193 NSObjectFileImage img;
194 NSObjectFileImageReturnCode ret;
195 /* this would be a rare case, but prevents crashing if it happens */
196 if(!_dyld_present()) {
197 lua_pushliteral(L, "dyld not present");
198 return NULL;
199 }
200 ret = NSCreateObjectFileImageFromFile(path, &img);
201 if (ret == NSObjectFileImageSuccess) {
202 NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
203 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
204 NSDestroyObjectFileImage(img);
205 if (mod == NULL) pusherror(L);
206 return mod;
207 }
208 lua_pushstring(L, errorfromcode(ret));
209 return NULL;
210}
211
212
213static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
214 NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
215 if (nss == NULL) {
216 lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
217 return NULL;
218 }
219 return (lua_CFunction)NSAddressOfSymbol(nss);
220}
221
222/* }====================================================== */
223
224
225
226#else
227/*
228** {======================================================
229** Fallback for other systems
230** =======================================================
231*/
232
233#undef LIB_FAIL
234#define LIB_FAIL "absent"
235
236
237#define DLMSG "dynamic libraries not enabled; check your Lua installation"
238
239
240static void ll_unloadlib (void *lib) {
241 (void)lib; /* to avoid warnings */
242}
243
244
245static void *ll_load (lua_State *L, const char *path) {
246 (void)path; /* to avoid warnings */
247 lua_pushliteral(L, DLMSG);
248 return NULL;
249}
250
251
252static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
253 (void)lib; (void)sym; /* to avoid warnings */
254 lua_pushliteral(L, DLMSG);
255 return NULL;
256}
257
258/* }====================================================== */
259#endif
260
261
262
263static void **ll_register (lua_State *L, const char *path) {
264 void **plib;
265 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
266 lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
267 if (!lua_isnil(L, -1)) /* is there an entry? */
268 plib = (void **)lua_touserdata(L, -1);
269 else { /* no entry yet; create one */
270 lua_pop(L, 1);
271 plib = (void **)lua_newuserdata(L, sizeof(const void *));
272 *plib = NULL;
273 luaL_getmetatable(L, "_LOADLIB");
274 lua_setmetatable(L, -2);
275 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
276 lua_pushvalue(L, -2);
277 lua_settable(L, LUA_REGISTRYINDEX);
278 }
279 return plib;
280}
281
282
283/*
284** __gc tag method: calls library's `ll_unloadlib' function with the lib
285** handle
286*/
287static int gctm (lua_State *L) {
288 void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
289 if (*lib) ll_unloadlib(*lib);
290 *lib = NULL; /* mark library as closed */
291 return 0;
292}
293
294
295static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
296 void **reg = ll_register(L, path);
297 if (*reg == NULL) *reg = ll_load(L, path);
298 if (*reg == NULL)
299 return ERRLIB; /* unable to load library */
300 else {
301 lua_CFunction f = ll_sym(L, *reg, sym);
302 if (f == NULL)
303 return ERRFUNC; /* unable to find function */
304 lua_pushcfunction(L, f);
305 return 0; /* return function */
306 }
307}
308
309
310static int ll_loadlib (lua_State *L) {
311 const char *path = luaL_checkstring(L, 1);
312 const char *init = luaL_checkstring(L, 2);
313 int stat = ll_loadfunc(L, path, init);
314 if (stat == 0) /* no errors? */
315 return 1; /* return the loaded function */
316 else { /* error; error message is on stack top */
317 lua_pushnil(L);
318 lua_insert(L, -2);
319 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
320 return 3; /* return nil, error message, and where */
321 }
322}
323
324
325
326/*
327** {======================================================
328** 'require' function
329** =======================================================
330*/
331
332
333static int readable (const char *filename) {
334 FILE *f = fopen(filename, "r"); /* try to open file */
335 if (f == NULL) return 0; /* open failed */
336 fclose(f);
337 return 1;
338}
339
340
341static const char *pushnexttemplate (lua_State *L, const char *path) {
342 const char *l;
343 while (*path == *LUA_PATHSEP) path++; /* skip separators */
344 if (*path == '\0') return NULL; /* no more templates */
345 l = strchr(path, *LUA_PATHSEP); /* find next separator */
346 if (l == NULL) l = path + strlen(path);
347 lua_pushlstring(L, path, l - path); /* template */
348 return l;
349}
350
351
352static const char *findfile (lua_State *L, const char *name,
353 const char *pname) {
354 const char *path;
355 name = luaL_gsub(L, name, ".", LUA_DIRSEP);
356 lua_getfield(L, LUA_ENVIRONINDEX, pname);
357 path = lua_tostring(L, -1);
358 if (path == NULL)
359 luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
360 lua_pushliteral(L, ""); /* error accumulator */
361 while ((path = pushnexttemplate(L, path)) != NULL) {
362 const char *filename;
363 filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
364 lua_remove(L, -2); /* remove path template */
365 if (readable(filename)) /* does file exist and is readable? */
366 return filename; /* return that file name */
367 lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
368 lua_remove(L, -2); /* remove file name */
369 lua_concat(L, 2); /* add entry to possible error message */
370 }
371 return NULL; /* not found */
372}
373
374
375static void loaderror (lua_State *L, const char *filename) {
376 luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
377 lua_tostring(L, 1), filename, lua_tostring(L, -1));
378}
379
380
381static int loader_Lua (lua_State *L) {
382 const char *filename;
383 const char *name = luaL_checkstring(L, 1);
384 filename = findfile(L, name, "path");
385 if (filename == NULL) return 1; /* library not found in this path */
386 if (luaL_loadfile(L, filename) != 0)
387 loaderror(L, filename);
388 /* not useful to JIT compile main chunk of a module */
389 luaJIT_setmode(L, -1, LUAJIT_MODE_FUNC|LUAJIT_MODE_OFF);
390 return 1; /* library loaded successfully */
391}
392
393
394static const char *mkfuncname (lua_State *L, const char *modname) {
395 const char *funcname;
396 const char *mark = strchr(modname, *LUA_IGMARK);
397 if (mark) modname = mark + 1;
398 funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
399 funcname = lua_pushfstring(L, POF"%s", funcname);
400 lua_remove(L, -2); /* remove 'gsub' result */
401 return funcname;
402}
403
404
405static int loader_C (lua_State *L) {
406 const char *funcname;
407 const char *name = luaL_checkstring(L, 1);
408 const char *filename = findfile(L, name, "cpath");
409 if (filename == NULL) return 1; /* library not found in this path */
410 funcname = mkfuncname(L, name);
411 if (ll_loadfunc(L, filename, funcname) != 0)
412 loaderror(L, filename);
413 return 1; /* library loaded successfully */
414}
415
416
417static int loader_Croot (lua_State *L) {
418 const char *funcname;
419 const char *filename;
420 const char *name = luaL_checkstring(L, 1);
421 const char *p = strchr(name, '.');
422 int stat;
423 if (p == NULL) return 0; /* is root */
424 lua_pushlstring(L, name, p - name);
425 filename = findfile(L, lua_tostring(L, -1), "cpath");
426 if (filename == NULL) return 1; /* root not found */
427 funcname = mkfuncname(L, name);
428 if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
429 if (stat != ERRFUNC) loaderror(L, filename); /* real error */
430 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
431 name, filename);
432 return 1; /* function not found */
433 }
434 return 1;
435}
436
437
438static int loader_preload (lua_State *L) {
439 const char *name = luaL_checkstring(L, 1);
440 lua_getfield(L, LUA_ENVIRONINDEX, "preload");
441 if (!lua_istable(L, -1))
442 luaL_error(L, LUA_QL("package.preload") " must be a table");
443 lua_getfield(L, -1, name);
444 if (lua_isnil(L, -1)) /* not found? */
445 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
446 return 1;
447}
448
449
450static const int sentinel_ = 0;
451#define sentinel ((void *)&sentinel_)
452
453
454static int ll_require (lua_State *L) {
455 const char *name = luaL_checkstring(L, 1);
456 int i;
457 lua_settop(L, 1); /* _LOADED table will be at index 2 */
458 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
459 lua_getfield(L, 2, name);
460 if (lua_toboolean(L, -1)) { /* is it there? */
461 if (lua_touserdata(L, -1) == sentinel) /* check loops */
462 luaL_error(L, "loop or previous error loading module " LUA_QS, name);
463 return 1; /* package is already loaded */
464 }
465 /* else must load it; iterate over available loaders */
466 lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
467 if (!lua_istable(L, -1))
468 luaL_error(L, LUA_QL("package.loaders") " must be a table");
469 lua_pushliteral(L, ""); /* error message accumulator */
470 for (i=1; ; i++) {
471 lua_rawgeti(L, -2, i); /* get a loader */
472 if (lua_isnil(L, -1))
473 luaL_error(L, "module " LUA_QS " not found:%s",
474 name, lua_tostring(L, -2));
475 lua_pushstring(L, name);
476 lua_call(L, 1, 1); /* call it */
477 if (lua_isfunction(L, -1)) /* did it find module? */
478 break; /* module loaded successfully */
479 else if (lua_isstring(L, -1)) /* loader returned error message? */
480 lua_concat(L, 2); /* accumulate it */
481 else
482 lua_pop(L, 1);
483 }
484 lua_pushlightuserdata(L, sentinel);
485 lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
486 lua_pushstring(L, name); /* pass name as argument to module */
487 lua_call(L, 1, 1); /* run loaded module */
488 if (!lua_isnil(L, -1)) /* non-nil return? */
489 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
490 lua_getfield(L, 2, name);
491 if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
492 lua_pushboolean(L, 1); /* use true as result */
493 lua_pushvalue(L, -1); /* extra copy to be returned */
494 lua_setfield(L, 2, name); /* _LOADED[name] = true */
495 }
496 return 1;
497}
498
499/* }====================================================== */
500
501
502
503/*
504** {======================================================
505** 'module' function
506** =======================================================
507*/
508
509
510static void setfenv (lua_State *L) {
511 lua_Debug ar;
512 if (lua_getstack(L, 1, &ar) == 0 ||
513 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
514 lua_iscfunction(L, -1))
515 luaL_error(L, LUA_QL("module") " not called from a Lua function");
516 lua_pushvalue(L, -2);
517 lua_setfenv(L, -2);
518 lua_pop(L, 1);
519}
520
521
522static void dooptions (lua_State *L, int n) {
523 int i;
524 for (i = 2; i <= n; i++) {
525 lua_pushvalue(L, i); /* get option (a function) */
526 lua_pushvalue(L, -2); /* module */
527 lua_call(L, 1, 0);
528 }
529}
530
531
532static void modinit (lua_State *L, const char *modname) {
533 const char *dot;
534 lua_pushvalue(L, -1);
535 lua_setfield(L, -2, "_M"); /* module._M = module */
536 lua_pushstring(L, modname);
537 lua_setfield(L, -2, "_NAME");
538 dot = strrchr(modname, '.'); /* look for last dot in module name */
539 if (dot == NULL) dot = modname;
540 else dot++;
541 /* set _PACKAGE as package name (full module name minus last part) */
542 lua_pushlstring(L, modname, dot - modname);
543 lua_setfield(L, -2, "_PACKAGE");
544}
545
546
547static int ll_module (lua_State *L) {
548 const char *modname = luaL_checkstring(L, 1);
549 int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
550 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
551 lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
552 if (!lua_istable(L, -1)) { /* not found? */
553 lua_pop(L, 1); /* remove previous result */
554 /* try global variable (and create one if it does not exist) */
555 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
556 return luaL_error(L, "name conflict for module " LUA_QS, modname);
557 lua_pushvalue(L, -1);
558 lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
559 }
560 /* check whether table already has a _NAME field */
561 lua_getfield(L, -1, "_NAME");
562 if (!lua_isnil(L, -1)) /* is table an initialized module? */
563 lua_pop(L, 1);
564 else { /* no; initialize it */
565 lua_pop(L, 1);
566 modinit(L, modname);
567 }
568 lua_pushvalue(L, -1);
569 setfenv(L);
570 dooptions(L, loaded - 1);
571 return 0;
572}
573
574
575static int ll_seeall (lua_State *L) {
576 luaL_checktype(L, 1, LUA_TTABLE);
577 if (!lua_getmetatable(L, 1)) {
578 lua_createtable(L, 0, 1); /* create new metatable */
579 lua_pushvalue(L, -1);
580 lua_setmetatable(L, 1);
581 }
582 lua_pushvalue(L, LUA_GLOBALSINDEX);
583 lua_setfield(L, -2, "__index"); /* mt.__index = _G */
584 return 0;
585}
586
587
588/* }====================================================== */
589
590
591
592/* auxiliary mark (for internal use) */
593#define AUXMARK "\1"
594
595static void setpath (lua_State *L, const char *fieldname, const char *envname,
596 const char *def) {
597 const char *path = getenv(envname);
598 if (path == NULL) /* no environment variable? */
599 lua_pushstring(L, def); /* use default */
600 else {
601 /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
602 path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
603 LUA_PATHSEP AUXMARK LUA_PATHSEP);
604 luaL_gsub(L, path, AUXMARK, def);
605 lua_remove(L, -2);
606 }
607 setprogdir(L);
608 lua_setfield(L, -2, fieldname);
609}
610
611
612static const luaL_Reg pk_funcs[] = {
613 {"loadlib", ll_loadlib},
614 {"seeall", ll_seeall},
615 {NULL, NULL}
616};
617
618
619static const luaL_Reg ll_funcs[] = {
620 {"module", ll_module},
621 {"require", ll_require},
622 {NULL, NULL}
623};
624
625
626static const lua_CFunction loaders[] =
627 {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
628
629
630LUALIB_API int luaopen_package (lua_State *L) {
631 int i;
632 /* create new type _LOADLIB */
633 luaL_newmetatable(L, "_LOADLIB");
634 lua_pushcfunction(L, gctm);
635 lua_setfield(L, -2, "__gc");
636 /* create `package' table */
637 luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
638#if defined(LUA_COMPAT_LOADLIB)
639 lua_getfield(L, -1, "loadlib");
640 lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
641#endif
642 lua_pushvalue(L, -1);
643 lua_replace(L, LUA_ENVIRONINDEX);
644 /* create `loaders' table */
645 lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
646 /* fill it with pre-defined loaders */
647 for (i=0; loaders[i] != NULL; i++) {
648 lua_pushcfunction(L, loaders[i]);
649 lua_rawseti(L, -2, i+1);
650 }
651 lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
652 setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
653 setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
654 /* store config information */
655 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
656 LUA_EXECDIR "\n" LUA_IGMARK);
657 lua_setfield(L, -2, "config");
658 /* set field `loaded' */
659 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
660 lua_setfield(L, -2, "loaded");
661 /* set field `preload' */
662 lua_newtable(L);
663 lua_setfield(L, -2, "preload");
664 lua_pushvalue(L, LUA_GLOBALSINDEX);
665 luaL_register(L, NULL, ll_funcs); /* open lib into global table */
666 lua_pop(L, 1);
667 return 1; /* return 'package' table */
668}
669
diff --git a/libraries/LuaJIT-1.1.7/src/lobject.c b/libraries/LuaJIT-1.1.7/src/lobject.c
new file mode 100644
index 0000000..4ff5073
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lobject.c
@@ -0,0 +1,214 @@
1/*
2** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h
5*/
6
7#include <ctype.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define lobject_c
14#define LUA_CORE
15
16#include "lua.h"
17
18#include "ldo.h"
19#include "lmem.h"
20#include "lobject.h"
21#include "lstate.h"
22#include "lstring.h"
23#include "lvm.h"
24
25
26
27const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
28
29
30/*
31** converts an integer to a "floating point byte", represented as
32** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
33** eeeee != 0 and (xxx) otherwise.
34*/
35int luaO_int2fb (unsigned int x) {
36 int e = 0; /* expoent */
37 while (x >= 16) {
38 x = (x+1) >> 1;
39 e++;
40 }
41 if (x < 8) return x;
42 else return ((e+1) << 3) | (cast_int(x) - 8);
43}
44
45
46/* converts back */
47int luaO_fb2int (int x) {
48 int e = (x >> 3) & 31;
49 if (e == 0) return x;
50 else return ((x & 7)+8) << (e - 1);
51}
52
53
54int luaO_log2 (unsigned int x) {
55 static const lu_byte log_2[256] = {
56 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
57 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
58 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
59 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
60 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
61 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
62 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
63 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
64 };
65 int l = -1;
66 while (x >= 256) { l += 8; x >>= 8; }
67 return l + log_2[x];
68
69}
70
71
72int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
73 if (ttype(t1) != ttype(t2)) return 0;
74 else switch (ttype(t1)) {
75 case LUA_TNIL:
76 return 1;
77 case LUA_TNUMBER:
78 return luai_numeq(nvalue(t1), nvalue(t2));
79 case LUA_TBOOLEAN:
80 return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
81 case LUA_TLIGHTUSERDATA:
82 return pvalue(t1) == pvalue(t2);
83 default:
84 lua_assert(iscollectable(t1));
85 return gcvalue(t1) == gcvalue(t2);
86 }
87}
88
89
90int luaO_str2d (const char *s, lua_Number *result) {
91 char *endptr;
92 *result = lua_str2number(s, &endptr);
93 if (endptr == s) return 0; /* conversion failed */
94 if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
95 *result = cast_num(strtoul(s, &endptr, 16));
96 if (*endptr == '\0') return 1; /* most common case */
97 while (isspace(cast(unsigned char, *endptr))) endptr++;
98 if (*endptr != '\0') return 0; /* invalid trailing characters? */
99 return 1;
100}
101
102
103
104static void pushstr (lua_State *L, const char *str) {
105 setsvalue2s(L, L->top, luaS_new(L, str));
106 incr_top(L);
107}
108
109
110/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
111const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
112 int n = 1;
113 pushstr(L, "");
114 for (;;) {
115 const char *e = strchr(fmt, '%');
116 if (e == NULL) break;
117 setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
118 incr_top(L);
119 switch (*(e+1)) {
120 case 's': {
121 const char *s = va_arg(argp, char *);
122 if (s == NULL) s = "(null)";
123 pushstr(L, s);
124 break;
125 }
126 case 'c': {
127 char buff[2];
128 buff[0] = cast(char, va_arg(argp, int));
129 buff[1] = '\0';
130 pushstr(L, buff);
131 break;
132 }
133 case 'd': {
134 setnvalue(L->top, cast_num(va_arg(argp, int)));
135 incr_top(L);
136 break;
137 }
138 case 'f': {
139 setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
140 incr_top(L);
141 break;
142 }
143 case 'p': {
144 char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
145 sprintf(buff, "%p", va_arg(argp, void *));
146 pushstr(L, buff);
147 break;
148 }
149 case '%': {
150 pushstr(L, "%");
151 break;
152 }
153 default: {
154 char buff[3];
155 buff[0] = '%';
156 buff[1] = *(e+1);
157 buff[2] = '\0';
158 pushstr(L, buff);
159 break;
160 }
161 }
162 n += 2;
163 fmt = e+2;
164 }
165 pushstr(L, fmt);
166 luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
167 L->top -= n;
168 return svalue(L->top - 1);
169}
170
171
172const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
173 const char *msg;
174 va_list argp;
175 va_start(argp, fmt);
176 msg = luaO_pushvfstring(L, fmt, argp);
177 va_end(argp);
178 return msg;
179}
180
181
182void luaO_chunkid (char *out, const char *source, size_t bufflen) {
183 if (*source == '=') {
184 strncpy(out, source+1, bufflen); /* remove first char */
185 out[bufflen-1] = '\0'; /* ensures null termination */
186 }
187 else { /* out = "source", or "...source" */
188 if (*source == '@') {
189 size_t l;
190 source++; /* skip the `@' */
191 bufflen -= sizeof(" '...' ");
192 l = strlen(source);
193 strcpy(out, "");
194 if (l > bufflen) {
195 source += (l-bufflen); /* get last part of file name */
196 strcat(out, "...");
197 }
198 strcat(out, source);
199 }
200 else { /* out = [string "string"] */
201 size_t len = strcspn(source, "\n\r"); /* stop at first newline */
202 bufflen -= sizeof(" [string \"...\"] ");
203 if (len > bufflen) len = bufflen;
204 strcpy(out, "[string \"");
205 if (source[len] != '\0') { /* must truncate? */
206 strncat(out, source, len);
207 strcat(out, "...");
208 }
209 else
210 strcat(out, source);
211 strcat(out, "\"]");
212 }
213 }
214}
diff --git a/libraries/LuaJIT-1.1.7/src/lobject.h b/libraries/LuaJIT-1.1.7/src/lobject.h
new file mode 100644
index 0000000..df9c528
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lobject.h
@@ -0,0 +1,386 @@
1/*
2** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $
3** Type definitions for Lua objects
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lobject_h
9#define lobject_h
10
11
12#include <stdarg.h>
13
14
15#include "llimits.h"
16#include "lua.h"
17
18
19/* tags for values visible from Lua */
20#define LAST_TAG LUA_TTHREAD
21
22#define NUM_TAGS (LAST_TAG+1)
23
24
25/*
26** Extra tags for non-values
27*/
28#define LUA_TPROTO (LAST_TAG+1)
29#define LUA_TUPVAL (LAST_TAG+2)
30#define LUA_TDEADKEY (LAST_TAG+3)
31
32
33/*
34** Union of all collectable objects
35*/
36typedef union GCObject GCObject;
37
38
39/*
40** Common Header for all collectable objects (in macro form, to be
41** included in other objects)
42*/
43#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
44
45
46/*
47** Common header in struct form
48*/
49typedef struct GCheader {
50 CommonHeader;
51} GCheader;
52
53
54
55
56/*
57** Union of all Lua values
58*/
59typedef union {
60 GCObject *gc;
61 void *p;
62 lua_Number n;
63 ptrdiff_t na[sizeof(lua_Number)/sizeof(ptrdiff_t)]; /* LuaJIT kludge */
64 int b;
65} Value;
66
67
68/*
69** Tagged Values
70*/
71
72#define TValuefields Value value; int tt
73
74typedef struct lua_TValue {
75 TValuefields;
76} LUA_TVALUE_ALIGN TValue;
77
78
79/* Macros to test type */
80#define ttisnil(o) (ttype(o) == LUA_TNIL)
81#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
82#define ttisstring(o) (ttype(o) == LUA_TSTRING)
83#define ttistable(o) (ttype(o) == LUA_TTABLE)
84#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
85#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
86#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
87#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
88#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
89
90/* Macros to access values */
91#define ttype(o) ((o)->tt)
92#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
93#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
94#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
95#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
96#define tsvalue(o) (&rawtsvalue(o)->tsv)
97#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
98#define uvalue(o) (&rawuvalue(o)->uv)
99#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
100#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
101#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
102#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
103
104#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
105
106/*
107** for internal debug only
108*/
109#define checkconsistency(obj) \
110 lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
111
112#define checkliveness(g,obj) \
113 lua_assert(!iscollectable(obj) || \
114 ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
115
116
117/* Macros to set values */
118#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
119
120#define setnvalue(obj,x) \
121 { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
122
123#define setpvalue(obj,x) \
124 { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
125
126#define setbvalue(obj,x) \
127 { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
128
129#define setsvalue(L,obj,x) \
130 { TValue *i_o=(obj); \
131 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
132 checkliveness(G(L),i_o); }
133
134#define setuvalue(L,obj,x) \
135 { TValue *i_o=(obj); \
136 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
137 checkliveness(G(L),i_o); }
138
139#define setthvalue(L,obj,x) \
140 { TValue *i_o=(obj); \
141 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
142 checkliveness(G(L),i_o); }
143
144#define setclvalue(L,obj,x) \
145 { TValue *i_o=(obj); \
146 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
147 checkliveness(G(L),i_o); }
148
149#define sethvalue(L,obj,x) \
150 { TValue *i_o=(obj); \
151 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
152 checkliveness(G(L),i_o); }
153
154#define setptvalue(L,obj,x) \
155 { TValue *i_o=(obj); \
156 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
157 checkliveness(G(L),i_o); }
158
159
160
161
162#define setobj(L,obj1,obj2) \
163 { const TValue *o2=(obj2); TValue *o1=(obj1); \
164 o1->value = o2->value; o1->tt=o2->tt; \
165 checkliveness(G(L),o1); }
166
167
168/*
169** different types of sets, according to destination
170*/
171
172/* from stack to (same) stack */
173#define setobjs2s setobj
174/* to stack (not from same stack) */
175#define setobj2s setobj
176#define setsvalue2s setsvalue
177#define sethvalue2s sethvalue
178#define setptvalue2s setptvalue
179/* from table to same table */
180#define setobjt2t setobj
181/* to table */
182#define setobj2t setobj
183/* to new object */
184#define setobj2n setobj
185#define setsvalue2n setsvalue
186
187#define setttype(obj, tt) (ttype(obj) = (tt))
188
189
190#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
191
192
193
194typedef TValue *StkId; /* index to stack elements */
195
196
197/*
198** String headers for string table
199*/
200typedef union TString {
201 L_Umaxalign dummy; /* ensures maximum alignment for strings */
202 struct {
203 CommonHeader;
204 lu_byte reserved;
205 unsigned int hash;
206 size_t len;
207 } tsv;
208} TString;
209
210
211#define getstr(ts) cast(const char *, (ts) + 1)
212#define svalue(o) getstr(rawtsvalue(o))
213
214
215
216typedef union Udata {
217 L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
218 struct {
219 CommonHeader;
220 struct Table *metatable;
221 struct Table *env;
222 size_t len;
223 } uv;
224} Udata;
225
226
227
228
229/*
230** Function Prototypes
231*/
232typedef struct Proto {
233 CommonHeader;
234 TValue *k; /* constants used by the function */
235 Instruction *code;
236 struct Proto **p; /* functions defined inside the function */
237 int *lineinfo; /* map from opcodes to source lines */
238 struct LocVar *locvars; /* information about local variables */
239 TString **upvalues; /* upvalue names */
240 TString *source;
241 int sizeupvalues;
242 int sizek; /* size of `k' */
243 int sizecode;
244 int sizelineinfo;
245 int sizep; /* size of `p' */
246 int sizelocvars;
247 int linedefined;
248 int lastlinedefined;
249 GCObject *gclist;
250 lu_byte nups; /* number of upvalues */
251 lu_byte numparams;
252 lu_byte is_vararg;
253 lu_byte maxstacksize;
254 /* LuaJIT extensions */
255 void *jit_mcode; /* compiled machine code base address */
256 size_t jit_szmcode; /* size of compiled mcode */
257 int jit_status; /* JIT engine status code */
258} Proto;
259
260
261/* masks for new-style vararg */
262#define VARARG_HASARG 1
263#define VARARG_ISVARARG 2
264#define VARARG_NEEDSARG 4
265
266
267typedef struct LocVar {
268 TString *varname;
269 int startpc; /* first point where variable is active */
270 int endpc; /* first point where variable is dead */
271} LocVar;
272
273
274
275/*
276** Upvalues
277*/
278
279typedef struct UpVal {
280 CommonHeader;
281 TValue *v; /* points to stack or to its own value */
282 union {
283 TValue value; /* the value (when closed) */
284 struct { /* double linked list (when open) */
285 struct UpVal *prev;
286 struct UpVal *next;
287 } l;
288 } u;
289} UpVal;
290
291
292/*
293** Closures
294*/
295
296#define ClosureHeader \
297 CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
298 struct Table *env; lua_CFunction jit_gate
299
300typedef struct CClosure {
301 ClosureHeader;
302 lua_CFunction f;
303 TValue upvalue[1];
304} CClosure;
305
306
307typedef struct LClosure {
308 ClosureHeader;
309 struct Proto *p;
310 UpVal *upvals[1];
311} LClosure;
312
313
314typedef union Closure {
315 CClosure c;
316 LClosure l;
317} Closure;
318
319
320#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
321#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
322
323
324/*
325** Tables
326*/
327
328typedef union TKey {
329 struct {
330 TValuefields;
331 struct Node *next; /* for chaining */
332 } nk;
333 TValue tvk;
334} TKey;
335
336
337typedef struct Node {
338 TValue i_val;
339 TKey i_key;
340} Node;
341
342
343typedef struct Table {
344 CommonHeader;
345 lu_byte flags; /* 1<<p means tagmethod(p) is not present */
346 lu_byte lsizenode; /* log2 of size of `node' array */
347 struct Table *metatable;
348 TValue *array; /* array part */
349 Node *node;
350 Node *lastfree; /* any free position is before this position */
351 GCObject *gclist;
352 int sizearray; /* size of `array' array */
353} Table;
354
355
356
357/*
358** `module' operation for hashing (size is always a power of 2)
359*/
360#define lmod(s,size) \
361 (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
362
363
364#define twoto(x) (1<<(x))
365#define sizenode(t) (twoto((t)->lsizenode))
366
367
368#define luaO_nilobject (&luaO_nilobject_)
369
370LUAI_DATA const TValue luaO_nilobject_;
371
372#define ceillog2(x) (luaO_log2((x)-1) + 1)
373
374LUAI_FUNC int luaO_log2 (unsigned int x);
375LUAI_FUNC int luaO_int2fb (unsigned int x);
376LUAI_FUNC int luaO_fb2int (int x);
377LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
378LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
379LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
380 va_list argp);
381LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
382LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
383
384
385#endif
386
diff --git a/libraries/LuaJIT-1.1.7/src/lopcodes.c b/libraries/LuaJIT-1.1.7/src/lopcodes.c
new file mode 100644
index 0000000..4cc7452
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lopcodes.c
@@ -0,0 +1,102 @@
1/*
2** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
3** See Copyright Notice in lua.h
4*/
5
6
7#define lopcodes_c
8#define LUA_CORE
9
10
11#include "lopcodes.h"
12
13
14/* ORDER OP */
15
16const char *const luaP_opnames[NUM_OPCODES+1] = {
17 "MOVE",
18 "LOADK",
19 "LOADBOOL",
20 "LOADNIL",
21 "GETUPVAL",
22 "GETGLOBAL",
23 "GETTABLE",
24 "SETGLOBAL",
25 "SETUPVAL",
26 "SETTABLE",
27 "NEWTABLE",
28 "SELF",
29 "ADD",
30 "SUB",
31 "MUL",
32 "DIV",
33 "MOD",
34 "POW",
35 "UNM",
36 "NOT",
37 "LEN",
38 "CONCAT",
39 "JMP",
40 "EQ",
41 "LT",
42 "LE",
43 "TEST",
44 "TESTSET",
45 "CALL",
46 "TAILCALL",
47 "RETURN",
48 "FORLOOP",
49 "FORPREP",
50 "TFORLOOP",
51 "SETLIST",
52 "CLOSE",
53 "CLOSURE",
54 "VARARG",
55 NULL
56};
57
58
59#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
60
61const lu_byte luaP_opmodes[NUM_OPCODES] = {
62/* T A B C mode opcode */
63 opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
64 ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
65 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
66 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
67 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
68 ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
69 ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
70 ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
71 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
72 ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
73 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
74 ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
75 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
76 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
77 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
78 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
79 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
80 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
81 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
82 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
83 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
84 ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
85 ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
86 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
87 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
88 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
89 ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
90 ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
91 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
92 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
93 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
94 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
95 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
96 ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
97 ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
98 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
99 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
100 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
101};
102
diff --git a/libraries/LuaJIT-1.1.7/src/lopcodes.h b/libraries/LuaJIT-1.1.7/src/lopcodes.h
new file mode 100644
index 0000000..41224d6
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lopcodes.h
@@ -0,0 +1,268 @@
1/*
2** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lopcodes_h
8#define lopcodes_h
9
10#include "llimits.h"
11
12
13/*===========================================================================
14 We assume that instructions are unsigned numbers.
15 All instructions have an opcode in the first 6 bits.
16 Instructions can have the following fields:
17 `A' : 8 bits
18 `B' : 9 bits
19 `C' : 9 bits
20 `Bx' : 18 bits (`B' and `C' together)
21 `sBx' : signed Bx
22
23 A signed argument is represented in excess K; that is, the number
24 value is the unsigned value minus K. K is exactly the maximum value
25 for that argument (so that -max is represented by 0, and +max is
26 represented by 2*max), which is half the maximum for the corresponding
27 unsigned argument.
28===========================================================================*/
29
30
31enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
32
33
34/*
35** size and position of opcode arguments.
36*/
37#define SIZE_C 9
38#define SIZE_B 9
39#define SIZE_Bx (SIZE_C + SIZE_B)
40#define SIZE_A 8
41
42#define SIZE_OP 6
43
44#define POS_OP 0
45#define POS_A (POS_OP + SIZE_OP)
46#define POS_C (POS_A + SIZE_A)
47#define POS_B (POS_C + SIZE_C)
48#define POS_Bx POS_C
49
50
51/*
52** limits for opcode arguments.
53** we use (signed) int to manipulate most arguments,
54** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
55*/
56#if SIZE_Bx < LUAI_BITSINT-1
57#define MAXARG_Bx ((1<<SIZE_Bx)-1)
58#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
59#else
60#define MAXARG_Bx MAX_INT
61#define MAXARG_sBx MAX_INT
62#endif
63
64
65#define MAXARG_A ((1<<SIZE_A)-1)
66#define MAXARG_B ((1<<SIZE_B)-1)
67#define MAXARG_C ((1<<SIZE_C)-1)
68
69
70/* creates a mask with `n' 1 bits at position `p' */
71#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
72
73/* creates a mask with `n' 0 bits at position `p' */
74#define MASK0(n,p) (~MASK1(n,p))
75
76/*
77** the following macros help to manipulate instructions
78*/
79
80#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
81#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
82 ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
83
84#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
85#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
86 ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
87
88#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
89#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
90 ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
91
92#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
93#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
94 ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
95
96#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
97#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
98 ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
99
100#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
101#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
102
103
104#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
105 | (cast(Instruction, a)<<POS_A) \
106 | (cast(Instruction, b)<<POS_B) \
107 | (cast(Instruction, c)<<POS_C))
108
109#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
110 | (cast(Instruction, a)<<POS_A) \
111 | (cast(Instruction, bc)<<POS_Bx))
112
113
114/*
115** Macros to operate RK indices
116*/
117
118/* this bit 1 means constant (0 means register) */
119#define BITRK (1 << (SIZE_B - 1))
120
121/* test whether value is a constant */
122#define ISK(x) ((x) & BITRK)
123
124/* gets the index of the constant */
125#define INDEXK(r) ((int)(r) & ~BITRK)
126
127#define MAXINDEXRK (BITRK - 1)
128
129/* code a constant index as a RK value */
130#define RKASK(x) ((x) | BITRK)
131
132
133/*
134** invalid register that fits in 8 bits
135*/
136#define NO_REG MAXARG_A
137
138
139/*
140** R(x) - register
141** Kst(x) - constant (in constant table)
142** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
143*/
144
145
146/*
147** grep "ORDER OP" if you change these enums
148*/
149
150typedef enum {
151/*----------------------------------------------------------------------
152name args description
153------------------------------------------------------------------------*/
154OP_MOVE,/* A B R(A) := R(B) */
155OP_LOADK,/* A Bx R(A) := Kst(Bx) */
156OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
157OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
158OP_GETUPVAL,/* A B R(A) := UpValue[B] */
159
160OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
161OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
162
163OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
164OP_SETUPVAL,/* A B UpValue[B] := R(A) */
165OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
166
167OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
168
169OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
170
171OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
172OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
173OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
174OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
175OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
176OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
177OP_UNM,/* A B R(A) := -R(B) */
178OP_NOT,/* A B R(A) := not R(B) */
179OP_LEN,/* A B R(A) := length of R(B) */
180
181OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
182
183OP_JMP,/* sBx pc+=sBx */
184
185OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
186OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
187OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
188
189OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
190OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
191
192OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
193OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
194OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
195
196OP_FORLOOP,/* A sBx R(A)+=R(A+2);
197 if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
198OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
199
200OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
201 if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
202OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
203
204OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
205OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
206
207OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
208} OpCode;
209
210
211#define NUM_OPCODES (cast(int, OP_VARARG) + 1)
212
213
214
215/*===========================================================================
216 Notes:
217 (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
218 and can be 0: OP_CALL then sets `top' to last_result+1, so
219 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
220
221 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
222 set top (like in OP_CALL with C == 0).
223
224 (*) In OP_RETURN, if (B == 0) then return up to `top'
225
226 (*) In OP_SETLIST, if (B == 0) then B = `top';
227 if (C == 0) then next `instruction' is real C
228
229 (*) For comparisons, A specifies what condition the test should accept
230 (true or false).
231
232 (*) All `skips' (pc++) assume that next instruction is a jump
233===========================================================================*/
234
235
236/*
237** masks for instruction properties. The format is:
238** bits 0-1: op mode
239** bits 2-3: C arg mode
240** bits 4-5: B arg mode
241** bit 6: instruction set register A
242** bit 7: operator is a test
243*/
244
245enum OpArgMask {
246 OpArgN, /* argument is not used */
247 OpArgU, /* argument is used */
248 OpArgR, /* argument is a register or a jump offset */
249 OpArgK /* argument is a constant or register/constant */
250};
251
252LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
253
254#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
255#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
256#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
257#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
258#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
259
260
261LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
262
263
264/* number of list items to accumulate before a SETLIST instruction */
265#define LFIELDS_PER_FLUSH 50
266
267
268#endif
diff --git a/libraries/LuaJIT-1.1.7/src/loslib.c b/libraries/LuaJIT-1.1.7/src/loslib.c
new file mode 100644
index 0000000..01a02a2
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/loslib.c
@@ -0,0 +1,244 @@
1/*
2** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $
3** Standard Operating System library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <errno.h>
9#include <locale.h>
10#include <stdlib.h>
11#include <string.h>
12#include <time.h>
13
14#define loslib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23static int os_pushresult (lua_State *L, int i, const char *filename) {
24 int en = errno; /* calls to Lua API may change this value */
25 if (i) {
26 lua_pushboolean(L, 1);
27 return 1;
28 }
29 else {
30 lua_pushnil(L);
31 lua_pushfstring(L, "%s: %s", filename, strerror(en));
32 lua_pushinteger(L, en);
33 return 3;
34 }
35}
36
37
38static int os_execute (lua_State *L) {
39 lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
40 return 1;
41}
42
43
44static int os_remove (lua_State *L) {
45 const char *filename = luaL_checkstring(L, 1);
46 return os_pushresult(L, remove(filename) == 0, filename);
47}
48
49
50static int os_rename (lua_State *L) {
51 const char *fromname = luaL_checkstring(L, 1);
52 const char *toname = luaL_checkstring(L, 2);
53 return os_pushresult(L, rename(fromname, toname) == 0, fromname);
54}
55
56
57static int os_tmpname (lua_State *L) {
58 char buff[LUA_TMPNAMBUFSIZE];
59 int err;
60 lua_tmpnam(buff, err);
61 if (err)
62 return luaL_error(L, "unable to generate a unique filename");
63 lua_pushstring(L, buff);
64 return 1;
65}
66
67
68static int os_getenv (lua_State *L) {
69 lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
70 return 1;
71}
72
73
74static int os_clock (lua_State *L) {
75 lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
76 return 1;
77}
78
79
80/*
81** {======================================================
82** Time/Date operations
83** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
84** wday=%w+1, yday=%j, isdst=? }
85** =======================================================
86*/
87
88static void setfield (lua_State *L, const char *key, int value) {
89 lua_pushinteger(L, value);
90 lua_setfield(L, -2, key);
91}
92
93static void setboolfield (lua_State *L, const char *key, int value) {
94 if (value < 0) /* undefined? */
95 return; /* does not set field */
96 lua_pushboolean(L, value);
97 lua_setfield(L, -2, key);
98}
99
100static int getboolfield (lua_State *L, const char *key) {
101 int res;
102 lua_getfield(L, -1, key);
103 res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
104 lua_pop(L, 1);
105 return res;
106}
107
108
109static int getfield (lua_State *L, const char *key, int d) {
110 int res;
111 lua_getfield(L, -1, key);
112 if (lua_isnumber(L, -1))
113 res = (int)lua_tointeger(L, -1);
114 else {
115 if (d < 0)
116 return luaL_error(L, "field " LUA_QS " missing in date table", key);
117 res = d;
118 }
119 lua_pop(L, 1);
120 return res;
121}
122
123
124static int os_date (lua_State *L) {
125 const char *s = luaL_optstring(L, 1, "%c");
126 time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
127 struct tm *stm;
128 if (*s == '!') { /* UTC? */
129 stm = gmtime(&t);
130 s++; /* skip `!' */
131 }
132 else
133 stm = localtime(&t);
134 if (stm == NULL) /* invalid date? */
135 lua_pushnil(L);
136 else if (strcmp(s, "*t") == 0) {
137 lua_createtable(L, 0, 9); /* 9 = number of fields */
138 setfield(L, "sec", stm->tm_sec);
139 setfield(L, "min", stm->tm_min);
140 setfield(L, "hour", stm->tm_hour);
141 setfield(L, "day", stm->tm_mday);
142 setfield(L, "month", stm->tm_mon+1);
143 setfield(L, "year", stm->tm_year+1900);
144 setfield(L, "wday", stm->tm_wday+1);
145 setfield(L, "yday", stm->tm_yday+1);
146 setboolfield(L, "isdst", stm->tm_isdst);
147 }
148 else {
149 char cc[3];
150 luaL_Buffer b;
151 cc[0] = '%'; cc[2] = '\0';
152 luaL_buffinit(L, &b);
153 for (; *s; s++) {
154 if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
155 luaL_addchar(&b, *s);
156 else {
157 size_t reslen;
158 char buff[200]; /* should be big enough for any conversion result */
159 cc[1] = *(++s);
160 reslen = strftime(buff, sizeof(buff), cc, stm);
161 luaL_addlstring(&b, buff, reslen);
162 }
163 }
164 luaL_pushresult(&b);
165 }
166 return 1;
167}
168
169
170static int os_time (lua_State *L) {
171 time_t t;
172 if (lua_isnoneornil(L, 1)) /* called without args? */
173 t = time(NULL); /* get current time */
174 else {
175 struct tm ts;
176 luaL_checktype(L, 1, LUA_TTABLE);
177 lua_settop(L, 1); /* make sure table is at the top */
178 ts.tm_sec = getfield(L, "sec", 0);
179 ts.tm_min = getfield(L, "min", 0);
180 ts.tm_hour = getfield(L, "hour", 12);
181 ts.tm_mday = getfield(L, "day", -1);
182 ts.tm_mon = getfield(L, "month", -1) - 1;
183 ts.tm_year = getfield(L, "year", -1) - 1900;
184 ts.tm_isdst = getboolfield(L, "isdst");
185 t = mktime(&ts);
186 }
187 if (t == (time_t)(-1))
188 lua_pushnil(L);
189 else
190 lua_pushnumber(L, (lua_Number)t);
191 return 1;
192}
193
194
195static int os_difftime (lua_State *L) {
196 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
197 (time_t)(luaL_optnumber(L, 2, 0))));
198 return 1;
199}
200
201/* }====================================================== */
202
203
204static int os_setlocale (lua_State *L) {
205 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
206 LC_NUMERIC, LC_TIME};
207 static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
208 "numeric", "time", NULL};
209 const char *l = luaL_optstring(L, 1, NULL);
210 int op = luaL_checkoption(L, 2, "all", catnames);
211 lua_pushstring(L, setlocale(cat[op], l));
212 return 1;
213}
214
215
216static int os_exit (lua_State *L) {
217 exit(luaL_optint(L, 1, EXIT_SUCCESS));
218 return 0; /* to avoid warnings */
219}
220
221static const luaL_Reg syslib[] = {
222 {"clock", os_clock},
223 {"date", os_date},
224 {"difftime", os_difftime},
225 {"execute", os_execute},
226 {"exit", os_exit},
227 {"getenv", os_getenv},
228 {"remove", os_remove},
229 {"rename", os_rename},
230 {"setlocale", os_setlocale},
231 {"time", os_time},
232 {"tmpname", os_tmpname},
233 {NULL, NULL}
234};
235
236/* }====================================================== */
237
238
239
240LUALIB_API int luaopen_os (lua_State *L) {
241 luaL_register(L, LUA_OSLIBNAME, syslib);
242 return 1;
243}
244
diff --git a/libraries/LuaJIT-1.1.7/src/lparser.c b/libraries/LuaJIT-1.1.7/src/lparser.c
new file mode 100644
index 0000000..1e2a9a8
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lparser.c
@@ -0,0 +1,1339 @@
1/*
2** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
3** Lua Parser
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lparser_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lcode.h"
16#include "ldebug.h"
17#include "ldo.h"
18#include "lfunc.h"
19#include "llex.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lparser.h"
24#include "lstate.h"
25#include "lstring.h"
26#include "ltable.h"
27
28
29
30#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
31
32#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
33
34#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
35
36
37/*
38** nodes for block list (list of active blocks)
39*/
40typedef struct BlockCnt {
41 struct BlockCnt *previous; /* chain */
42 int breaklist; /* list of jumps out of this loop */
43 lu_byte nactvar; /* # active locals outside the breakable structure */
44 lu_byte upval; /* true if some variable in the block is an upvalue */
45 lu_byte isbreakable; /* true if `block' is a loop */
46} BlockCnt;
47
48
49
50/*
51** prototypes for recursive non-terminal functions
52*/
53static void chunk (LexState *ls);
54static void expr (LexState *ls, expdesc *v);
55
56
57static void anchor_token (LexState *ls) {
58 if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
59 TString *ts = ls->t.seminfo.ts;
60 luaX_newstring(ls, getstr(ts), ts->tsv.len);
61 }
62}
63
64
65static void error_expected (LexState *ls, int token) {
66 luaX_syntaxerror(ls,
67 luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
68}
69
70
71static void errorlimit (FuncState *fs, int limit, const char *what) {
72 const char *msg = (fs->f->linedefined == 0) ?
73 luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
74 luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
75 fs->f->linedefined, limit, what);
76 luaX_lexerror(fs->ls, msg, 0);
77}
78
79
80static int testnext (LexState *ls, int c) {
81 if (ls->t.token == c) {
82 luaX_next(ls);
83 return 1;
84 }
85 else return 0;
86}
87
88
89static void check (LexState *ls, int c) {
90 if (ls->t.token != c)
91 error_expected(ls, c);
92}
93
94static void checknext (LexState *ls, int c) {
95 check(ls, c);
96 luaX_next(ls);
97}
98
99
100#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
101
102
103
104static void check_match (LexState *ls, int what, int who, int where) {
105 if (!testnext(ls, what)) {
106 if (where == ls->linenumber)
107 error_expected(ls, what);
108 else {
109 luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
110 LUA_QS " expected (to close " LUA_QS " at line %d)",
111 luaX_token2str(ls, what), luaX_token2str(ls, who), where));
112 }
113 }
114}
115
116
117static TString *str_checkname (LexState *ls) {
118 TString *ts;
119 check(ls, TK_NAME);
120 ts = ls->t.seminfo.ts;
121 luaX_next(ls);
122 return ts;
123}
124
125
126static void init_exp (expdesc *e, expkind k, int i) {
127 e->f = e->t = NO_JUMP;
128 e->k = k;
129 e->u.s.info = i;
130}
131
132
133static void codestring (LexState *ls, expdesc *e, TString *s) {
134 init_exp(e, VK, luaK_stringK(ls->fs, s));
135}
136
137
138static void checkname(LexState *ls, expdesc *e) {
139 codestring(ls, e, str_checkname(ls));
140}
141
142
143static int registerlocalvar (LexState *ls, TString *varname) {
144 FuncState *fs = ls->fs;
145 Proto *f = fs->f;
146 int oldsize = f->sizelocvars;
147 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
148 LocVar, SHRT_MAX, "too many local variables");
149 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
150 f->locvars[fs->nlocvars].varname = varname;
151 luaC_objbarrier(ls->L, f, varname);
152 return fs->nlocvars++;
153}
154
155
156#define new_localvarliteral(ls,v,n) \
157 new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
158
159
160static void new_localvar (LexState *ls, TString *name, int n) {
161 FuncState *fs = ls->fs;
162 luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
163 fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
164}
165
166
167static void adjustlocalvars (LexState *ls, int nvars) {
168 FuncState *fs = ls->fs;
169 fs->nactvar = cast_byte(fs->nactvar + nvars);
170 for (; nvars; nvars--) {
171 getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
172 }
173}
174
175
176static void removevars (LexState *ls, int tolevel) {
177 FuncState *fs = ls->fs;
178 while (fs->nactvar > tolevel)
179 getlocvar(fs, --fs->nactvar).endpc = fs->pc;
180}
181
182
183static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
184 int i;
185 Proto *f = fs->f;
186 int oldsize = f->sizeupvalues;
187 for (i=0; i<f->nups; i++) {
188 if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
189 lua_assert(f->upvalues[i] == name);
190 return i;
191 }
192 }
193 /* new one */
194 luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
195 luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
196 TString *, MAX_INT, "");
197 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
198 f->upvalues[f->nups] = name;
199 luaC_objbarrier(fs->L, f, name);
200 lua_assert(v->k == VLOCAL || v->k == VUPVAL);
201 fs->upvalues[f->nups].k = cast_byte(v->k);
202 fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
203 return f->nups++;
204}
205
206
207static int searchvar (FuncState *fs, TString *n) {
208 int i;
209 for (i=fs->nactvar-1; i >= 0; i--) {
210 if (n == getlocvar(fs, i).varname)
211 return i;
212 }
213 return -1; /* not found */
214}
215
216
217static void markupval (FuncState *fs, int level) {
218 BlockCnt *bl = fs->bl;
219 while (bl && bl->nactvar > level) bl = bl->previous;
220 if (bl) bl->upval = 1;
221}
222
223
224static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
225 if (fs == NULL) { /* no more levels? */
226 init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
227 return VGLOBAL;
228 }
229 else {
230 int v = searchvar(fs, n); /* look up at current level */
231 if (v >= 0) {
232 init_exp(var, VLOCAL, v);
233 if (!base)
234 markupval(fs, v); /* local will be used as an upval */
235 return VLOCAL;
236 }
237 else { /* not found at current level; try upper one */
238 if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
239 return VGLOBAL;
240 var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
241 var->k = VUPVAL; /* upvalue in this level */
242 return VUPVAL;
243 }
244 }
245}
246
247
248static void singlevar (LexState *ls, expdesc *var) {
249 TString *varname = str_checkname(ls);
250 FuncState *fs = ls->fs;
251 if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
252 var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
253}
254
255
256static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
257 FuncState *fs = ls->fs;
258 int extra = nvars - nexps;
259 if (hasmultret(e->k)) {
260 extra++; /* includes call itself */
261 if (extra < 0) extra = 0;
262 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
263 if (extra > 1) luaK_reserveregs(fs, extra-1);
264 }
265 else {
266 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
267 if (extra > 0) {
268 int reg = fs->freereg;
269 luaK_reserveregs(fs, extra);
270 luaK_nil(fs, reg, extra);
271 }
272 }
273}
274
275
276static void enterlevel (LexState *ls) {
277 if (++ls->L->nCcalls > LUAI_MAXCCALLS)
278 luaX_lexerror(ls, "chunk has too many syntax levels", 0);
279}
280
281
282#define leavelevel(ls) ((ls)->L->nCcalls--)
283
284
285static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
286 bl->breaklist = NO_JUMP;
287 bl->isbreakable = isbreakable;
288 bl->nactvar = fs->nactvar;
289 bl->upval = 0;
290 bl->previous = fs->bl;
291 fs->bl = bl;
292 lua_assert(fs->freereg == fs->nactvar);
293}
294
295
296static void leaveblock (FuncState *fs) {
297 BlockCnt *bl = fs->bl;
298 fs->bl = bl->previous;
299 removevars(fs->ls, bl->nactvar);
300 if (bl->upval)
301 luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
302 /* a block either controls scope or breaks (never both) */
303 lua_assert(!bl->isbreakable || !bl->upval);
304 lua_assert(bl->nactvar == fs->nactvar);
305 fs->freereg = fs->nactvar; /* free registers */
306 luaK_patchtohere(fs, bl->breaklist);
307}
308
309
310static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
311 FuncState *fs = ls->fs;
312 Proto *f = fs->f;
313 int oldsize = f->sizep;
314 int i;
315 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
316 MAXARG_Bx, "constant table overflow");
317 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
318 f->p[fs->np++] = func->f;
319 luaC_objbarrier(ls->L, f, func->f);
320 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
321 for (i=0; i<func->f->nups; i++) {
322 OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
323 luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
324 }
325}
326
327
328static void open_func (LexState *ls, FuncState *fs) {
329 lua_State *L = ls->L;
330 Proto *f = luaF_newproto(L);
331 fs->f = f;
332 fs->prev = ls->fs; /* linked list of funcstates */
333 fs->ls = ls;
334 fs->L = L;
335 ls->fs = fs;
336 fs->pc = 0;
337 fs->lasttarget = -1;
338 fs->jpc = NO_JUMP;
339 fs->freereg = 0;
340 fs->nk = 0;
341 fs->np = 0;
342 fs->nlocvars = 0;
343 fs->nactvar = 0;
344 fs->bl = NULL;
345 f->source = ls->source;
346 f->maxstacksize = 2; /* registers 0/1 are always valid */
347 fs->h = luaH_new(L, 0, 0);
348 /* anchor table of constants and prototype (to avoid being collected) */
349 sethvalue2s(L, L->top, fs->h);
350 incr_top(L);
351 setptvalue2s(L, L->top, f);
352 incr_top(L);
353}
354
355
356static void close_func (LexState *ls) {
357 lua_State *L = ls->L;
358 FuncState *fs = ls->fs;
359 Proto *f = fs->f;
360 removevars(ls, 0);
361 luaK_ret(fs, 0, 0); /* final return */
362 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
363 f->sizecode = fs->pc;
364 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
365 f->sizelineinfo = fs->pc;
366 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
367 f->sizek = fs->nk;
368 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
369 f->sizep = fs->np;
370 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
371 f->sizelocvars = fs->nlocvars;
372 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
373 f->sizeupvalues = f->nups;
374 lua_assert(luaG_checkcode(f));
375 lua_assert(fs->bl == NULL);
376 ls->fs = fs->prev;
377 L->top -= 2; /* remove table and prototype from the stack */
378 /* last token read was anchored in defunct function; must reanchor it */
379 if (fs) anchor_token(ls);
380}
381
382
383Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
384 struct LexState lexstate;
385 struct FuncState funcstate;
386 lexstate.buff = buff;
387 luaX_setinput(L, &lexstate, z, luaS_new(L, name));
388 open_func(&lexstate, &funcstate);
389 funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
390 luaX_next(&lexstate); /* read first token */
391 chunk(&lexstate);
392 check(&lexstate, TK_EOS);
393 close_func(&lexstate);
394 lua_assert(funcstate.prev == NULL);
395 lua_assert(funcstate.f->nups == 0);
396 lua_assert(lexstate.fs == NULL);
397 return funcstate.f;
398}
399
400
401
402/*============================================================*/
403/* GRAMMAR RULES */
404/*============================================================*/
405
406
407static void field (LexState *ls, expdesc *v) {
408 /* field -> ['.' | ':'] NAME */
409 FuncState *fs = ls->fs;
410 expdesc key;
411 luaK_exp2anyreg(fs, v);
412 luaX_next(ls); /* skip the dot or colon */
413 checkname(ls, &key);
414 luaK_indexed(fs, v, &key);
415}
416
417
418static void yindex (LexState *ls, expdesc *v) {
419 /* index -> '[' expr ']' */
420 luaX_next(ls); /* skip the '[' */
421 expr(ls, v);
422 luaK_exp2val(ls->fs, v);
423 checknext(ls, ']');
424}
425
426
427/*
428** {======================================================================
429** Rules for Constructors
430** =======================================================================
431*/
432
433
434struct ConsControl {
435 expdesc v; /* last list item read */
436 expdesc *t; /* table descriptor */
437 int nh; /* total number of `record' elements */
438 int na; /* total number of array elements */
439 int tostore; /* number of array elements pending to be stored */
440};
441
442
443static void recfield (LexState *ls, struct ConsControl *cc) {
444 /* recfield -> (NAME | `['exp1`]') = exp1 */
445 FuncState *fs = ls->fs;
446 int reg = ls->fs->freereg;
447 expdesc key, val;
448 int rkkey;
449 if (ls->t.token == TK_NAME) {
450 luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
451 checkname(ls, &key);
452 }
453 else /* ls->t.token == '[' */
454 yindex(ls, &key);
455 cc->nh++;
456 checknext(ls, '=');
457 rkkey = luaK_exp2RK(fs, &key);
458 expr(ls, &val);
459 luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
460 fs->freereg = reg; /* free registers */
461}
462
463
464static void closelistfield (FuncState *fs, struct ConsControl *cc) {
465 if (cc->v.k == VVOID) return; /* there is no list item */
466 luaK_exp2nextreg(fs, &cc->v);
467 cc->v.k = VVOID;
468 if (cc->tostore == LFIELDS_PER_FLUSH) {
469 luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
470 cc->tostore = 0; /* no more items pending */
471 }
472}
473
474
475static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
476 if (cc->tostore == 0) return;
477 if (hasmultret(cc->v.k)) {
478 luaK_setmultret(fs, &cc->v);
479 luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
480 cc->na--; /* do not count last expression (unknown number of elements) */
481 }
482 else {
483 if (cc->v.k != VVOID)
484 luaK_exp2nextreg(fs, &cc->v);
485 luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
486 }
487}
488
489
490static void listfield (LexState *ls, struct ConsControl *cc) {
491 expr(ls, &cc->v);
492 luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
493 cc->na++;
494 cc->tostore++;
495}
496
497
498static void constructor (LexState *ls, expdesc *t) {
499 /* constructor -> ?? */
500 FuncState *fs = ls->fs;
501 int line = ls->linenumber;
502 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
503 struct ConsControl cc;
504 cc.na = cc.nh = cc.tostore = 0;
505 cc.t = t;
506 init_exp(t, VRELOCABLE, pc);
507 init_exp(&cc.v, VVOID, 0); /* no value (yet) */
508 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
509 checknext(ls, '{');
510 do {
511 lua_assert(cc.v.k == VVOID || cc.tostore > 0);
512 if (ls->t.token == '}') break;
513 closelistfield(fs, &cc);
514 switch(ls->t.token) {
515 case TK_NAME: { /* may be listfields or recfields */
516 luaX_lookahead(ls);
517 if (ls->lookahead.token != '=') /* expression? */
518 listfield(ls, &cc);
519 else
520 recfield(ls, &cc);
521 break;
522 }
523 case '[': { /* constructor_item -> recfield */
524 recfield(ls, &cc);
525 break;
526 }
527 default: { /* constructor_part -> listfield */
528 listfield(ls, &cc);
529 break;
530 }
531 }
532 } while (testnext(ls, ',') || testnext(ls, ';'));
533 check_match(ls, '}', '{', line);
534 lastlistfield(fs, &cc);
535 SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
536 SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
537}
538
539/* }====================================================================== */
540
541
542
543static void parlist (LexState *ls) {
544 /* parlist -> [ param { `,' param } ] */
545 FuncState *fs = ls->fs;
546 Proto *f = fs->f;
547 int nparams = 0;
548 f->is_vararg = 0;
549 if (ls->t.token != ')') { /* is `parlist' not empty? */
550 do {
551 switch (ls->t.token) {
552 case TK_NAME: { /* param -> NAME */
553 new_localvar(ls, str_checkname(ls), nparams++);
554 break;
555 }
556 case TK_DOTS: { /* param -> `...' */
557 luaX_next(ls);
558#if defined(LUA_COMPAT_VARARG)
559 /* use `arg' as default name */
560 new_localvarliteral(ls, "arg", nparams++);
561 f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
562#endif
563 f->is_vararg |= VARARG_ISVARARG;
564 break;
565 }
566 default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
567 }
568 } while (!f->is_vararg && testnext(ls, ','));
569 }
570 adjustlocalvars(ls, nparams);
571 f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
572 luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
573}
574
575
576static void body (LexState *ls, expdesc *e, int needself, int line) {
577 /* body -> `(' parlist `)' chunk END */
578 FuncState new_fs;
579 open_func(ls, &new_fs);
580 new_fs.f->linedefined = line;
581 checknext(ls, '(');
582 if (needself) {
583 new_localvarliteral(ls, "self", 0);
584 adjustlocalvars(ls, 1);
585 }
586 parlist(ls);
587 checknext(ls, ')');
588 chunk(ls);
589 new_fs.f->lastlinedefined = ls->linenumber;
590 check_match(ls, TK_END, TK_FUNCTION, line);
591 close_func(ls);
592 pushclosure(ls, &new_fs, e);
593}
594
595
596static int explist1 (LexState *ls, expdesc *v) {
597 /* explist1 -> expr { `,' expr } */
598 int n = 1; /* at least one expression */
599 expr(ls, v);
600 while (testnext(ls, ',')) {
601 luaK_exp2nextreg(ls->fs, v);
602 expr(ls, v);
603 n++;
604 }
605 return n;
606}
607
608
609static void funcargs (LexState *ls, expdesc *f) {
610 FuncState *fs = ls->fs;
611 expdesc args;
612 int base, nparams;
613 int line = ls->linenumber;
614 switch (ls->t.token) {
615 case '(': { /* funcargs -> `(' [ explist1 ] `)' */
616 if (line != ls->lastline)
617 luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
618 luaX_next(ls);
619 if (ls->t.token == ')') /* arg list is empty? */
620 args.k = VVOID;
621 else {
622 explist1(ls, &args);
623 luaK_setmultret(fs, &args);
624 }
625 check_match(ls, ')', '(', line);
626 break;
627 }
628 case '{': { /* funcargs -> constructor */
629 constructor(ls, &args);
630 break;
631 }
632 case TK_STRING: { /* funcargs -> STRING */
633 codestring(ls, &args, ls->t.seminfo.ts);
634 luaX_next(ls); /* must use `seminfo' before `next' */
635 break;
636 }
637 default: {
638 luaX_syntaxerror(ls, "function arguments expected");
639 return;
640 }
641 }
642 lua_assert(f->k == VNONRELOC);
643 base = f->u.s.info; /* base register for call */
644 if (hasmultret(args.k))
645 nparams = LUA_MULTRET; /* open call */
646 else {
647 if (args.k != VVOID)
648 luaK_exp2nextreg(fs, &args); /* close last argument */
649 nparams = fs->freereg - (base+1);
650 }
651 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
652 luaK_fixline(fs, line);
653 fs->freereg = base+1; /* call remove function and arguments and leaves
654 (unless changed) one result */
655}
656
657
658
659
660/*
661** {======================================================================
662** Expression parsing
663** =======================================================================
664*/
665
666
667static void prefixexp (LexState *ls, expdesc *v) {
668 /* prefixexp -> NAME | '(' expr ')' */
669 switch (ls->t.token) {
670 case '(': {
671 int line = ls->linenumber;
672 luaX_next(ls);
673 expr(ls, v);
674 check_match(ls, ')', '(', line);
675 luaK_dischargevars(ls->fs, v);
676 return;
677 }
678 case TK_NAME: {
679 singlevar(ls, v);
680 return;
681 }
682 default: {
683 luaX_syntaxerror(ls, "unexpected symbol");
684 return;
685 }
686 }
687}
688
689
690static void primaryexp (LexState *ls, expdesc *v) {
691 /* primaryexp ->
692 prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
693 FuncState *fs = ls->fs;
694 prefixexp(ls, v);
695 for (;;) {
696 switch (ls->t.token) {
697 case '.': { /* field */
698 field(ls, v);
699 break;
700 }
701 case '[': { /* `[' exp1 `]' */
702 expdesc key;
703 luaK_exp2anyreg(fs, v);
704 yindex(ls, &key);
705 luaK_indexed(fs, v, &key);
706 break;
707 }
708 case ':': { /* `:' NAME funcargs */
709 expdesc key;
710 luaX_next(ls);
711 checkname(ls, &key);
712 luaK_self(fs, v, &key);
713 funcargs(ls, v);
714 break;
715 }
716 case '(': case TK_STRING: case '{': { /* funcargs */
717 luaK_exp2nextreg(fs, v);
718 funcargs(ls, v);
719 break;
720 }
721 default: return;
722 }
723 }
724}
725
726
727static void simpleexp (LexState *ls, expdesc *v) {
728 /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
729 constructor | FUNCTION body | primaryexp */
730 switch (ls->t.token) {
731 case TK_NUMBER: {
732 init_exp(v, VKNUM, 0);
733 v->u.nval = ls->t.seminfo.r;
734 break;
735 }
736 case TK_STRING: {
737 codestring(ls, v, ls->t.seminfo.ts);
738 break;
739 }
740 case TK_NIL: {
741 init_exp(v, VNIL, 0);
742 break;
743 }
744 case TK_TRUE: {
745 init_exp(v, VTRUE, 0);
746 break;
747 }
748 case TK_FALSE: {
749 init_exp(v, VFALSE, 0);
750 break;
751 }
752 case TK_DOTS: { /* vararg */
753 FuncState *fs = ls->fs;
754 check_condition(ls, fs->f->is_vararg,
755 "cannot use " LUA_QL("...") " outside a vararg function");
756 fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
757 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
758 break;
759 }
760 case '{': { /* constructor */
761 constructor(ls, v);
762 return;
763 }
764 case TK_FUNCTION: {
765 luaX_next(ls);
766 body(ls, v, 0, ls->linenumber);
767 return;
768 }
769 default: {
770 primaryexp(ls, v);
771 return;
772 }
773 }
774 luaX_next(ls);
775}
776
777
778static UnOpr getunopr (int op) {
779 switch (op) {
780 case TK_NOT: return OPR_NOT;
781 case '-': return OPR_MINUS;
782 case '#': return OPR_LEN;
783 default: return OPR_NOUNOPR;
784 }
785}
786
787
788static BinOpr getbinopr (int op) {
789 switch (op) {
790 case '+': return OPR_ADD;
791 case '-': return OPR_SUB;
792 case '*': return OPR_MUL;
793 case '/': return OPR_DIV;
794 case '%': return OPR_MOD;
795 case '^': return OPR_POW;
796 case TK_CONCAT: return OPR_CONCAT;
797 case TK_NE: return OPR_NE;
798 case TK_EQ: return OPR_EQ;
799 case '<': return OPR_LT;
800 case TK_LE: return OPR_LE;
801 case '>': return OPR_GT;
802 case TK_GE: return OPR_GE;
803 case TK_AND: return OPR_AND;
804 case TK_OR: return OPR_OR;
805 default: return OPR_NOBINOPR;
806 }
807}
808
809
810static const struct {
811 lu_byte left; /* left priority for each binary operator */
812 lu_byte right; /* right priority */
813} priority[] = { /* ORDER OPR */
814 {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
815 {10, 9}, {5, 4}, /* power and concat (right associative) */
816 {3, 3}, {3, 3}, /* equality and inequality */
817 {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
818 {2, 2}, {1, 1} /* logical (and/or) */
819};
820
821#define UNARY_PRIORITY 8 /* priority for unary operators */
822
823
824/*
825** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
826** where `binop' is any binary operator with a priority higher than `limit'
827*/
828static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
829 BinOpr op;
830 UnOpr uop;
831 enterlevel(ls);
832 uop = getunopr(ls->t.token);
833 if (uop != OPR_NOUNOPR) {
834 luaX_next(ls);
835 subexpr(ls, v, UNARY_PRIORITY);
836 luaK_prefix(ls->fs, uop, v);
837 }
838 else simpleexp(ls, v);
839 /* expand while operators have priorities higher than `limit' */
840 op = getbinopr(ls->t.token);
841 while (op != OPR_NOBINOPR && priority[op].left > limit) {
842 expdesc v2;
843 BinOpr nextop;
844 luaX_next(ls);
845 luaK_infix(ls->fs, op, v);
846 /* read sub-expression with higher priority */
847 nextop = subexpr(ls, &v2, priority[op].right);
848 luaK_posfix(ls->fs, op, v, &v2);
849 op = nextop;
850 }
851 leavelevel(ls);
852 return op; /* return first untreated operator */
853}
854
855
856static void expr (LexState *ls, expdesc *v) {
857 subexpr(ls, v, 0);
858}
859
860/* }==================================================================== */
861
862
863
864/*
865** {======================================================================
866** Rules for Statements
867** =======================================================================
868*/
869
870
871static int block_follow (int token) {
872 switch (token) {
873 case TK_ELSE: case TK_ELSEIF: case TK_END:
874 case TK_UNTIL: case TK_EOS:
875 return 1;
876 default: return 0;
877 }
878}
879
880
881static void block (LexState *ls) {
882 /* block -> chunk */
883 FuncState *fs = ls->fs;
884 BlockCnt bl;
885 enterblock(fs, &bl, 0);
886 chunk(ls);
887 lua_assert(bl.breaklist == NO_JUMP);
888 leaveblock(fs);
889}
890
891
892/*
893** structure to chain all variables in the left-hand side of an
894** assignment
895*/
896struct LHS_assign {
897 struct LHS_assign *prev;
898 expdesc v; /* variable (global, local, upvalue, or indexed) */
899};
900
901
902/*
903** check whether, in an assignment to a local variable, the local variable
904** is needed in a previous assignment (to a table). If so, save original
905** local value in a safe place and use this safe copy in the previous
906** assignment.
907*/
908static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
909 FuncState *fs = ls->fs;
910 int extra = fs->freereg; /* eventual position to save local variable */
911 int conflict = 0;
912 for (; lh; lh = lh->prev) {
913 if (lh->v.k == VINDEXED) {
914 if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
915 conflict = 1;
916 lh->v.u.s.info = extra; /* previous assignment will use safe copy */
917 }
918 if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
919 conflict = 1;
920 lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
921 }
922 }
923 }
924 if (conflict) {
925 luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
926 luaK_reserveregs(fs, 1);
927 }
928}
929
930
931static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
932 expdesc e;
933 check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
934 "syntax error");
935 if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
936 struct LHS_assign nv;
937 nv.prev = lh;
938 primaryexp(ls, &nv.v);
939 if (nv.v.k == VLOCAL)
940 check_conflict(ls, lh, &nv.v);
941 luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
942 "variables in assignment");
943 assignment(ls, &nv, nvars+1);
944 }
945 else { /* assignment -> `=' explist1 */
946 int nexps;
947 checknext(ls, '=');
948 nexps = explist1(ls, &e);
949 if (nexps != nvars) {
950 adjust_assign(ls, nvars, nexps, &e);
951 if (nexps > nvars)
952 ls->fs->freereg -= nexps - nvars; /* remove extra values */
953 }
954 else {
955 luaK_setoneret(ls->fs, &e); /* close last expression */
956 luaK_storevar(ls->fs, &lh->v, &e);
957 return; /* avoid default */
958 }
959 }
960 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
961 luaK_storevar(ls->fs, &lh->v, &e);
962}
963
964
965static int cond (LexState *ls) {
966 /* cond -> exp */
967 expdesc v;
968 expr(ls, &v); /* read condition */
969 if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
970 luaK_goiftrue(ls->fs, &v);
971 return v.f;
972}
973
974
975static void breakstat (LexState *ls) {
976 FuncState *fs = ls->fs;
977 BlockCnt *bl = fs->bl;
978 int upval = 0;
979 while (bl && !bl->isbreakable) {
980 upval |= bl->upval;
981 bl = bl->previous;
982 }
983 if (!bl)
984 luaX_syntaxerror(ls, "no loop to break");
985 if (upval)
986 luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
987 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
988}
989
990
991static void whilestat (LexState *ls, int line) {
992 /* whilestat -> WHILE cond DO block END */
993 FuncState *fs = ls->fs;
994 int whileinit;
995 int condexit;
996 BlockCnt bl;
997 luaX_next(ls); /* skip WHILE */
998 whileinit = luaK_getlabel(fs);
999 condexit = cond(ls);
1000 enterblock(fs, &bl, 1);
1001 checknext(ls, TK_DO);
1002 block(ls);
1003 luaK_patchlist(fs, luaK_jump(fs), whileinit);
1004 check_match(ls, TK_END, TK_WHILE, line);
1005 leaveblock(fs);
1006 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
1007}
1008
1009
1010static void repeatstat (LexState *ls, int line) {
1011 /* repeatstat -> REPEAT block UNTIL cond */
1012 int condexit;
1013 FuncState *fs = ls->fs;
1014 int repeat_init = luaK_getlabel(fs);
1015 BlockCnt bl1, bl2;
1016 enterblock(fs, &bl1, 1); /* loop block */
1017 enterblock(fs, &bl2, 0); /* scope block */
1018 luaX_next(ls); /* skip REPEAT */
1019 chunk(ls);
1020 check_match(ls, TK_UNTIL, TK_REPEAT, line);
1021 condexit = cond(ls); /* read condition (inside scope block) */
1022 if (!bl2.upval) { /* no upvalues? */
1023 leaveblock(fs); /* finish scope */
1024 luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
1025 }
1026 else { /* complete semantics when there are upvalues */
1027 breakstat(ls); /* if condition then break */
1028 luaK_patchtohere(ls->fs, condexit); /* else... */
1029 leaveblock(fs); /* finish scope... */
1030 luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
1031 }
1032 leaveblock(fs); /* finish loop */
1033}
1034
1035
1036static int exp1 (LexState *ls) {
1037 expdesc e;
1038 int k;
1039 expr(ls, &e);
1040 k = e.k;
1041 luaK_exp2nextreg(ls->fs, &e);
1042 return k;
1043}
1044
1045
1046static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1047 /* forbody -> DO block */
1048 BlockCnt bl;
1049 FuncState *fs = ls->fs;
1050 int prep, endfor;
1051 adjustlocalvars(ls, 3); /* control variables */
1052 checknext(ls, TK_DO);
1053 prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
1054 enterblock(fs, &bl, 0); /* scope for declared variables */
1055 adjustlocalvars(ls, nvars);
1056 luaK_reserveregs(fs, nvars);
1057 block(ls);
1058 leaveblock(fs); /* end of scope for declared variables */
1059 luaK_patchtohere(fs, prep);
1060 endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
1061 luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
1062 luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
1063 luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
1064}
1065
1066
1067static void fornum (LexState *ls, TString *varname, int line) {
1068 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1069 FuncState *fs = ls->fs;
1070 int base = fs->freereg;
1071 new_localvarliteral(ls, "(for index)", 0);
1072 new_localvarliteral(ls, "(for limit)", 1);
1073 new_localvarliteral(ls, "(for step)", 2);
1074 new_localvar(ls, varname, 3);
1075 checknext(ls, '=');
1076 exp1(ls); /* initial value */
1077 checknext(ls, ',');
1078 exp1(ls); /* limit */
1079 if (testnext(ls, ','))
1080 exp1(ls); /* optional step */
1081 else { /* default step = 1 */
1082 luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
1083 luaK_reserveregs(fs, 1);
1084 }
1085 forbody(ls, base, line, 1, 1);
1086}
1087
1088
1089static void forlist (LexState *ls, TString *indexname) {
1090 /* forlist -> NAME {,NAME} IN explist1 forbody */
1091 FuncState *fs = ls->fs;
1092 expdesc e;
1093 int nvars = 0;
1094 int line;
1095 int base = fs->freereg;
1096 /* create control variables */
1097 new_localvarliteral(ls, "(for generator)", nvars++);
1098 new_localvarliteral(ls, "(for state)", nvars++);
1099 new_localvarliteral(ls, "(for control)", nvars++);
1100 /* create declared variables */
1101 new_localvar(ls, indexname, nvars++);
1102 while (testnext(ls, ','))
1103 new_localvar(ls, str_checkname(ls), nvars++);
1104 checknext(ls, TK_IN);
1105 line = ls->linenumber;
1106 adjust_assign(ls, 3, explist1(ls, &e), &e);
1107 luaK_checkstack(fs, 3); /* extra space to call generator */
1108 forbody(ls, base, line, nvars - 3, 0);
1109}
1110
1111
1112static void forstat (LexState *ls, int line) {
1113 /* forstat -> FOR (fornum | forlist) END */
1114 FuncState *fs = ls->fs;
1115 TString *varname;
1116 BlockCnt bl;
1117 enterblock(fs, &bl, 1); /* scope for loop and control variables */
1118 luaX_next(ls); /* skip `for' */
1119 varname = str_checkname(ls); /* first variable name */
1120 switch (ls->t.token) {
1121 case '=': fornum(ls, varname, line); break;
1122 case ',': case TK_IN: forlist(ls, varname); break;
1123 default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
1124 }
1125 check_match(ls, TK_END, TK_FOR, line);
1126 leaveblock(fs); /* loop scope (`break' jumps to this point) */
1127}
1128
1129
1130static int test_then_block (LexState *ls) {
1131 /* test_then_block -> [IF | ELSEIF] cond THEN block */
1132 int condexit;
1133 luaX_next(ls); /* skip IF or ELSEIF */
1134 condexit = cond(ls);
1135 checknext(ls, TK_THEN);
1136 block(ls); /* `then' part */
1137 return condexit;
1138}
1139
1140
1141static void ifstat (LexState *ls, int line) {
1142 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1143 FuncState *fs = ls->fs;
1144 int flist;
1145 int escapelist = NO_JUMP;
1146 flist = test_then_block(ls); /* IF cond THEN block */
1147 while (ls->t.token == TK_ELSEIF) {
1148 luaK_concat(fs, &escapelist, luaK_jump(fs));
1149 luaK_patchtohere(fs, flist);
1150 flist = test_then_block(ls); /* ELSEIF cond THEN block */
1151 }
1152 if (ls->t.token == TK_ELSE) {
1153 luaK_concat(fs, &escapelist, luaK_jump(fs));
1154 luaK_patchtohere(fs, flist);
1155 luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
1156 block(ls); /* `else' part */
1157 }
1158 else
1159 luaK_concat(fs, &escapelist, flist);
1160 luaK_patchtohere(fs, escapelist);
1161 check_match(ls, TK_END, TK_IF, line);
1162}
1163
1164
1165static void localfunc (LexState *ls) {
1166 expdesc v, b;
1167 FuncState *fs = ls->fs;
1168 new_localvar(ls, str_checkname(ls), 0);
1169 init_exp(&v, VLOCAL, fs->freereg);
1170 luaK_reserveregs(fs, 1);
1171 adjustlocalvars(ls, 1);
1172 body(ls, &b, 0, ls->linenumber);
1173 luaK_storevar(fs, &v, &b);
1174 /* debug information will only see the variable after this point! */
1175 getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
1176}
1177
1178
1179static void localstat (LexState *ls) {
1180 /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
1181 int nvars = 0;
1182 int nexps;
1183 expdesc e;
1184 do {
1185 new_localvar(ls, str_checkname(ls), nvars++);
1186 } while (testnext(ls, ','));
1187 if (testnext(ls, '='))
1188 nexps = explist1(ls, &e);
1189 else {
1190 e.k = VVOID;
1191 nexps = 0;
1192 }
1193 adjust_assign(ls, nvars, nexps, &e);
1194 adjustlocalvars(ls, nvars);
1195}
1196
1197
1198static int funcname (LexState *ls, expdesc *v) {
1199 /* funcname -> NAME {field} [`:' NAME] */
1200 int needself = 0;
1201 singlevar(ls, v);
1202 while (ls->t.token == '.')
1203 field(ls, v);
1204 if (ls->t.token == ':') {
1205 needself = 1;
1206 field(ls, v);
1207 }
1208 return needself;
1209}
1210
1211
1212static void funcstat (LexState *ls, int line) {
1213 /* funcstat -> FUNCTION funcname body */
1214 int needself;
1215 expdesc v, b;
1216 luaX_next(ls); /* skip FUNCTION */
1217 needself = funcname(ls, &v);
1218 body(ls, &b, needself, line);
1219 luaK_storevar(ls->fs, &v, &b);
1220 luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
1221}
1222
1223
1224static void exprstat (LexState *ls) {
1225 /* stat -> func | assignment */
1226 FuncState *fs = ls->fs;
1227 struct LHS_assign v;
1228 primaryexp(ls, &v.v);
1229 if (v.v.k == VCALL) /* stat -> func */
1230 SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
1231 else { /* stat -> assignment */
1232 v.prev = NULL;
1233 assignment(ls, &v, 1);
1234 }
1235}
1236
1237
1238static void retstat (LexState *ls) {
1239 /* stat -> RETURN explist */
1240 FuncState *fs = ls->fs;
1241 expdesc e;
1242 int first, nret; /* registers with returned values */
1243 luaX_next(ls); /* skip RETURN */
1244 if (block_follow(ls->t.token) || ls->t.token == ';')
1245 first = nret = 0; /* return no values */
1246 else {
1247 nret = explist1(ls, &e); /* optional return values */
1248 if (hasmultret(e.k)) {
1249 luaK_setmultret(fs, &e);
1250 if (e.k == VCALL && nret == 1) { /* tail call? */
1251 SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
1252 lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
1253 }
1254 first = fs->nactvar;
1255 nret = LUA_MULTRET; /* return all values */
1256 }
1257 else {
1258 if (nret == 1) /* only one single value? */
1259 first = luaK_exp2anyreg(fs, &e);
1260 else {
1261 luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
1262 first = fs->nactvar; /* return all `active' values */
1263 lua_assert(nret == fs->freereg - first);
1264 }
1265 }
1266 }
1267 luaK_ret(fs, first, nret);
1268}
1269
1270
1271static int statement (LexState *ls) {
1272 int line = ls->linenumber; /* may be needed for error messages */
1273 switch (ls->t.token) {
1274 case TK_IF: { /* stat -> ifstat */
1275 ifstat(ls, line);
1276 return 0;
1277 }
1278 case TK_WHILE: { /* stat -> whilestat */
1279 whilestat(ls, line);
1280 return 0;
1281 }
1282 case TK_DO: { /* stat -> DO block END */
1283 luaX_next(ls); /* skip DO */
1284 block(ls);
1285 check_match(ls, TK_END, TK_DO, line);
1286 return 0;
1287 }
1288 case TK_FOR: { /* stat -> forstat */
1289 forstat(ls, line);
1290 return 0;
1291 }
1292 case TK_REPEAT: { /* stat -> repeatstat */
1293 repeatstat(ls, line);
1294 return 0;
1295 }
1296 case TK_FUNCTION: {
1297 funcstat(ls, line); /* stat -> funcstat */
1298 return 0;
1299 }
1300 case TK_LOCAL: { /* stat -> localstat */
1301 luaX_next(ls); /* skip LOCAL */
1302 if (testnext(ls, TK_FUNCTION)) /* local function? */
1303 localfunc(ls);
1304 else
1305 localstat(ls);
1306 return 0;
1307 }
1308 case TK_RETURN: { /* stat -> retstat */
1309 retstat(ls);
1310 return 1; /* must be last statement */
1311 }
1312 case TK_BREAK: { /* stat -> breakstat */
1313 luaX_next(ls); /* skip BREAK */
1314 breakstat(ls);
1315 return 1; /* must be last statement */
1316 }
1317 default: {
1318 exprstat(ls);
1319 return 0; /* to avoid warnings */
1320 }
1321 }
1322}
1323
1324
1325static void chunk (LexState *ls) {
1326 /* chunk -> { stat [`;'] } */
1327 int islast = 0;
1328 enterlevel(ls);
1329 while (!islast && !block_follow(ls->t.token)) {
1330 islast = statement(ls);
1331 testnext(ls, ';');
1332 lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
1333 ls->fs->freereg >= ls->fs->nactvar);
1334 ls->fs->freereg = ls->fs->nactvar; /* free registers */
1335 }
1336 leavelevel(ls);
1337}
1338
1339/* }====================================================================== */
diff --git a/libraries/LuaJIT-1.1.7/src/lparser.h b/libraries/LuaJIT-1.1.7/src/lparser.h
new file mode 100644
index 0000000..18836af
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lparser.h
@@ -0,0 +1,82 @@
1/*
2** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $
3** Lua Parser
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lparser_h
8#define lparser_h
9
10#include "llimits.h"
11#include "lobject.h"
12#include "lzio.h"
13
14
15/*
16** Expression descriptor
17*/
18
19typedef enum {
20 VVOID, /* no value */
21 VNIL,
22 VTRUE,
23 VFALSE,
24 VK, /* info = index of constant in `k' */
25 VKNUM, /* nval = numerical value */
26 VLOCAL, /* info = local register */
27 VUPVAL, /* info = index of upvalue in `upvalues' */
28 VGLOBAL, /* info = index of table; aux = index of global name in `k' */
29 VINDEXED, /* info = table register; aux = index register (or `k') */
30 VJMP, /* info = instruction pc */
31 VRELOCABLE, /* info = instruction pc */
32 VNONRELOC, /* info = result register */
33 VCALL, /* info = instruction pc */
34 VVARARG /* info = instruction pc */
35} expkind;
36
37typedef struct expdesc {
38 expkind k;
39 union {
40 struct { int info, aux; } s;
41 lua_Number nval;
42 } u;
43 int t; /* patch list of `exit when true' */
44 int f; /* patch list of `exit when false' */
45} expdesc;
46
47
48typedef struct upvaldesc {
49 lu_byte k;
50 lu_byte info;
51} upvaldesc;
52
53
54struct BlockCnt; /* defined in lparser.c */
55
56
57/* state needed to generate code for a given function */
58typedef struct FuncState {
59 Proto *f; /* current function header */
60 Table *h; /* table to find (and reuse) elements in `k' */
61 struct FuncState *prev; /* enclosing function */
62 struct LexState *ls; /* lexical state */
63 struct lua_State *L; /* copy of the Lua state */
64 struct BlockCnt *bl; /* chain of current blocks */
65 int pc; /* next position to code (equivalent to `ncode') */
66 int lasttarget; /* `pc' of last `jump target' */
67 int jpc; /* list of pending jumps to `pc' */
68 int freereg; /* first free register */
69 int nk; /* number of elements in `k' */
70 int np; /* number of elements in `p' */
71 short nlocvars; /* number of elements in `locvars' */
72 lu_byte nactvar; /* number of active local variables */
73 upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
74 unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
75} FuncState;
76
77
78LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
79 const char *name);
80
81
82#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lstate.c b/libraries/LuaJIT-1.1.7/src/lstate.c
new file mode 100644
index 0000000..2bf835b
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lstate.c
@@ -0,0 +1,218 @@
1/*
2** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lstate_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "ldebug.h"
16#include "ldo.h"
17#include "lfunc.h"
18#include "lgc.h"
19#include "llex.h"
20#include "lmem.h"
21#include "lstate.h"
22#include "lstring.h"
23#include "ltable.h"
24#include "ltm.h"
25#include "ljit.h"
26
27
28#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
29#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
30#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
31
32
33/*
34** Main thread combines a thread state and the global state
35*/
36typedef struct LG {
37 lua_State l;
38 global_State g;
39} LG;
40
41
42
43static void stack_init (lua_State *L1, lua_State *L) {
44 /* initialize CallInfo array */
45 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
46 L1->ci = L1->base_ci;
47 L1->size_ci = BASIC_CI_SIZE;
48 L1->end_ci = L1->base_ci + L1->size_ci - 1;
49 /* initialize stack array */
50 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
51 L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
52 L1->top = L1->stack;
53 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
54 /* initialize first ci */
55 L1->ci->func = L1->top;
56 setnilvalue(L1->top++); /* `function' entry for this `ci' */
57 L1->base = L1->ci->base = L1->top;
58 L1->ci->top = L1->top + LUA_MINSTACK;
59}
60
61
62static void freestack (lua_State *L, lua_State *L1) {
63 luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
64 luaM_freearray(L, L1->stack, L1->stacksize, TValue);
65}
66
67
68/*
69** open parts that may cause memory-allocation errors
70*/
71static void f_luaopen (lua_State *L, void *ud) {
72 global_State *g = G(L);
73 UNUSED(ud);
74 stack_init(L, L); /* init stack */
75 sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
76 sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
77 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
78 luaT_init(L);
79 luaX_init(L);
80 luaS_fix(luaS_newliteral(L, MEMERRMSG));
81 g->GCthreshold = 4*g->totalbytes;
82 luaJIT_initstate(L);
83}
84
85
86static void preinit_state (lua_State *L, global_State *g) {
87 G(L) = g;
88 L->stack = NULL;
89 L->stacksize = 0;
90 L->errorJmp = NULL;
91 L->hook = NULL;
92 L->hookmask = 0;
93 L->basehookcount = 0;
94 L->allowhook = 1;
95 resethookcount(L);
96 L->openupval = NULL;
97 L->size_ci = 0;
98 L->nCcalls = 0;
99 L->status = 0;
100 L->base_ci = L->ci = NULL;
101 L->savedpc = NULL;
102 L->errfunc = 0;
103 setnilvalue(gt(L));
104}
105
106
107static void close_state (lua_State *L) {
108 global_State *g = G(L);
109 luaF_close(L, L->stack); /* close all upvalues for this thread */
110 luaC_freeall(L); /* collect all objects */
111 luaJIT_freestate(L);
112 lua_assert(g->rootgc == obj2gco(L));
113 lua_assert(g->strt.nuse == 0);
114 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
115 luaZ_freebuffer(L, &g->buff);
116 freestack(L, L);
117 lua_assert(g->totalbytes == sizeof(LG));
118 (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
119}
120
121
122lua_State *luaE_newthread (lua_State *L) {
123 lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
124 luaC_link(L, obj2gco(L1), LUA_TTHREAD);
125 preinit_state(L1, G(L));
126 stack_init(L1, L); /* init stack */
127 setobj2n(L, gt(L1), gt(L)); /* share table of globals */
128 L1->hookmask = L->hookmask;
129 L1->basehookcount = L->basehookcount;
130 L1->hook = L->hook;
131 resethookcount(L1);
132 lua_assert(iswhite(obj2gco(L1)));
133 return L1;
134}
135
136
137void luaE_freethread (lua_State *L, lua_State *L1) {
138 luaF_close(L1, L1->stack); /* close all upvalues for this thread */
139 lua_assert(L1->openupval == NULL);
140 luai_userstatefree(L1);
141 freestack(L, L1);
142 luaM_freemem(L, fromstate(L1), state_size(lua_State));
143}
144
145
146LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
147 int i;
148 lua_State *L;
149 global_State *g;
150 void *l = (*f)(ud, NULL, 0, state_size(LG));
151 if (l == NULL) return NULL;
152 L = tostate(l);
153 g = &((LG *)L)->g;
154 L->next = NULL;
155 L->tt = LUA_TTHREAD;
156 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
157 L->marked = luaC_white(g);
158 set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
159 preinit_state(L, g);
160 g->frealloc = f;
161 g->ud = ud;
162 g->mainthread = L;
163 g->uvhead.u.l.prev = &g->uvhead;
164 g->uvhead.u.l.next = &g->uvhead;
165 g->GCthreshold = 0; /* mark it as unfinished state */
166 g->strt.size = 0;
167 g->strt.nuse = 0;
168 g->strt.hash = NULL;
169 setnilvalue(registry(L));
170 luaZ_initbuffer(L, &g->buff);
171 g->panic = NULL;
172 g->gcstate = GCSpause;
173 g->rootgc = obj2gco(L);
174 g->sweepstrgc = 0;
175 g->sweepgc = &g->rootgc;
176 g->gray = NULL;
177 g->grayagain = NULL;
178 g->weak = NULL;
179 g->tmudata = NULL;
180 g->totalbytes = sizeof(LG);
181 g->gcpause = LUAI_GCPAUSE;
182 g->gcstepmul = LUAI_GCMUL;
183 g->gcdept = 0;
184 g->jit_state = NULL;
185 for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
186 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
187 /* memory allocation error: free partial state */
188 close_state(L);
189 L = NULL;
190 }
191 else
192 luai_userstateopen(L);
193 return L;
194}
195
196
197static void callallgcTM (lua_State *L, void *ud) {
198 UNUSED(ud);
199 luaC_callGCTM(L); /* call GC metamethods for all udata */
200}
201
202
203LUA_API void lua_close (lua_State *L) {
204 L = G(L)->mainthread; /* only the main thread can be closed */
205 lua_lock(L);
206 luaF_close(L, L->stack); /* close all upvalues for this thread */
207 luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
208 L->errfunc = 0; /* no error function during GC metamethods */
209 do { /* repeat until no more errors */
210 L->ci = L->base_ci;
211 L->base = L->top = L->ci->base;
212 L->nCcalls = 0;
213 } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
214 lua_assert(G(L)->tmudata == NULL);
215 luai_userstateclose(L);
216 close_state(L);
217}
218
diff --git a/libraries/LuaJIT-1.1.7/src/lstate.h b/libraries/LuaJIT-1.1.7/src/lstate.h
new file mode 100644
index 0000000..ddaa554
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lstate.h
@@ -0,0 +1,179 @@
1/*
2** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lstate_h
8#define lstate_h
9
10#include "lua.h"
11
12#include "lobject.h"
13#include "ltm.h"
14#include "lzio.h"
15#ifndef COCO_DISABLE
16#include "lcoco.h"
17#endif
18
19
20
21struct lua_longjmp; /* defined in ldo.c */
22struct jit_State; /* defined in ljit.c */
23typedef int (*luaJIT_GateLJ)(lua_State *L, StkId func, int nresults);
24
25
26/* table of globals */
27#define gt(L) (&L->l_gt)
28
29/* registry */
30#define registry(L) (&G(L)->l_registry)
31
32
33/* extra stack space to handle TM calls and some other extras */
34/* LuaJIT uses more than the default (5) to speed up calls (setnil loop) */
35#define EXTRA_STACK 8
36
37
38#define BASIC_CI_SIZE 8
39
40#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
41
42
43
44typedef struct stringtable {
45 GCObject **hash;
46 lu_int32 nuse; /* number of elements */
47 int size;
48} stringtable;
49
50
51/*
52** informations about a call
53*/
54typedef struct CallInfo {
55 StkId base; /* base for this function */
56 StkId func; /* function index in the stack */
57 StkId top; /* top for this function */
58 const Instruction *savedpc;
59 int nresults; /* expected number of results from this function */
60 int tailcalls; /* number of tail calls lost under this entry */
61} CallInfo;
62
63
64
65#define curr_func(L) (clvalue(L->ci->func))
66#define ci_func(ci) (clvalue((ci)->func))
67#define f_isLua(ci) (!ci_func(ci)->c.isC)
68#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
69
70
71/*
72** `global state', shared by all threads of this state
73*/
74typedef struct global_State {
75 stringtable strt; /* hash table for strings */
76 lua_Alloc frealloc; /* function to reallocate memory */
77 void *ud; /* auxiliary data to `frealloc' */
78 lu_byte currentwhite;
79 lu_byte gcstate; /* state of garbage collector */
80 int sweepstrgc; /* position of sweep in `strt' */
81 GCObject *rootgc; /* list of all collectable objects */
82 GCObject **sweepgc; /* position of sweep in `rootgc' */
83 GCObject *gray; /* list of gray objects */
84 GCObject *grayagain; /* list of objects to be traversed atomically */
85 GCObject *weak; /* list of weak tables (to be cleared) */
86 GCObject *tmudata; /* last element of list of userdata to be GC */
87 Mbuffer buff; /* temporary buffer for string concatentation */
88 lu_mem GCthreshold;
89 lu_mem totalbytes; /* number of bytes currently allocated */
90 lu_mem estimate; /* an estimate of number of bytes actually in use */
91 lu_mem gcdept; /* how much GC is `behind schedule' */
92 int gcpause; /* size of pause between successive GCs */
93 int gcstepmul; /* GC `granularity' */
94 lua_CFunction panic; /* to be called in unprotected errors */
95 TValue l_registry;
96 struct lua_State *mainthread;
97 UpVal uvhead; /* head of double-linked list of all open upvalues */
98 struct Table *mt[NUM_TAGS]; /* metatables for basic types */
99 TString *tmname[TM_N]; /* array with tag-method names */
100 /* LuaJIT extensions */
101 struct jit_State *jit_state; /* JIT state */
102 luaJIT_GateLJ jit_gateLJ; /* Lua -> JIT gate */
103 lua_CFunction jit_gateJL; /* JIT -> Lua callgate */
104 lua_CFunction jit_gateJC; /* JIT -> C callgate */
105} global_State;
106
107
108/*
109** `per thread' state
110*/
111struct lua_State {
112 CommonHeader;
113 lu_byte status;
114 StkId top; /* first free slot in the stack */
115 StkId base; /* base of current function */
116 global_State *l_G;
117 CallInfo *ci; /* call info for current function */
118 const Instruction *savedpc; /* `savedpc' of current function */
119 StkId stack_last; /* last free slot in the stack */
120 StkId stack; /* stack base */
121 CallInfo *end_ci; /* points after end of ci array*/
122 CallInfo *base_ci; /* array of CallInfo's */
123 int stacksize;
124 int size_ci; /* size of array `base_ci' */
125 unsigned short nCcalls; /* number of nested C calls */
126 lu_byte hookmask;
127 lu_byte allowhook;
128 int basehookcount;
129 int hookcount;
130 lua_Hook hook;
131 TValue l_gt; /* table of globals */
132 TValue env; /* temporary place for environments */
133 GCObject *openupval; /* list of open upvalues in this stack */
134 GCObject *gclist;
135 struct lua_longjmp *errorJmp; /* current error recover point */
136 ptrdiff_t errfunc; /* current error handling function (stack index) */
137};
138
139
140#define G(L) (L->l_G)
141
142
143/*
144** Union of all collectable objects
145*/
146union GCObject {
147 GCheader gch;
148 union TString ts;
149 union Udata u;
150 union Closure cl;
151 struct Table h;
152 struct Proto p;
153 struct UpVal uv;
154 struct lua_State th; /* thread */
155};
156
157
158/* macros to convert a GCObject into a specific value */
159#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
160#define gco2ts(o) (&rawgco2ts(o)->tsv)
161#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
162#define gco2u(o) (&rawgco2u(o)->uv)
163#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
164#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
165#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
166#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
167#define ngcotouv(o) \
168 check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
169#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
170
171/* macro to convert any Lua object into a GCObject */
172#define obj2gco(v) (cast(GCObject *, (v)))
173
174
175LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
176LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
177
178#endif
179
diff --git a/libraries/LuaJIT-1.1.7/src/lstring.c b/libraries/LuaJIT-1.1.7/src/lstring.c
new file mode 100644
index 0000000..4911315
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lstring.c
@@ -0,0 +1,111 @@
1/*
2** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lstring_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lmem.h"
16#include "lobject.h"
17#include "lstate.h"
18#include "lstring.h"
19
20
21
22void luaS_resize (lua_State *L, int newsize) {
23 GCObject **newhash;
24 stringtable *tb;
25 int i;
26 if (G(L)->gcstate == GCSsweepstring)
27 return; /* cannot resize during GC traverse */
28 newhash = luaM_newvector(L, newsize, GCObject *);
29 tb = &G(L)->strt;
30 for (i=0; i<newsize; i++) newhash[i] = NULL;
31 /* rehash */
32 for (i=0; i<tb->size; i++) {
33 GCObject *p = tb->hash[i];
34 while (p) { /* for each node in the list */
35 GCObject *next = p->gch.next; /* save next */
36 unsigned int h = gco2ts(p)->hash;
37 int h1 = lmod(h, newsize); /* new position */
38 lua_assert(cast_int(h%newsize) == lmod(h, newsize));
39 p->gch.next = newhash[h1]; /* chain it */
40 newhash[h1] = p;
41 p = next;
42 }
43 }
44 luaM_freearray(L, tb->hash, tb->size, TString *);
45 tb->size = newsize;
46 tb->hash = newhash;
47}
48
49
50static TString *newlstr (lua_State *L, const char *str, size_t l,
51 unsigned int h) {
52 TString *ts;
53 stringtable *tb;
54 if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
55 luaM_toobig(L);
56 ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
57 ts->tsv.len = l;
58 ts->tsv.hash = h;
59 ts->tsv.marked = luaC_white(G(L));
60 ts->tsv.tt = LUA_TSTRING;
61 ts->tsv.reserved = 0;
62 memcpy(ts+1, str, l*sizeof(char));
63 ((char *)(ts+1))[l] = '\0'; /* ending 0 */
64 tb = &G(L)->strt;
65 h = lmod(h, tb->size);
66 ts->tsv.next = tb->hash[h]; /* chain new entry */
67 tb->hash[h] = obj2gco(ts);
68 tb->nuse++;
69 if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
70 luaS_resize(L, tb->size*2); /* too crowded */
71 return ts;
72}
73
74
75TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
76 GCObject *o;
77 unsigned int h = cast(unsigned int, l); /* seed */
78 size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
79 size_t l1;
80 for (l1=l; l1>=step; l1-=step) /* compute hash */
81 h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
82 for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
83 o != NULL;
84 o = o->gch.next) {
85 TString *ts = rawgco2ts(o);
86 if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
87 /* string may be dead */
88 if (isdead(G(L), o)) changewhite(o);
89 return ts;
90 }
91 }
92 return newlstr(L, str, l, h); /* not found */
93}
94
95
96Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
97 Udata *u;
98 if (s > MAX_SIZET - sizeof(Udata))
99 luaM_toobig(L);
100 u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
101 u->uv.marked = luaC_white(G(L)); /* is not finalized */
102 u->uv.tt = LUA_TUSERDATA;
103 u->uv.len = s;
104 u->uv.metatable = NULL;
105 u->uv.env = e;
106 /* chain it on udata list (after main thread) */
107 u->uv.next = G(L)->mainthread->next;
108 G(L)->mainthread->next = obj2gco(u);
109 return u;
110}
111
diff --git a/libraries/LuaJIT-1.1.7/src/lstring.h b/libraries/LuaJIT-1.1.7/src/lstring.h
new file mode 100644
index 0000000..73a2ff8
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lstring.h
@@ -0,0 +1,31 @@
1/*
2** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $
3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lstring_h
8#define lstring_h
9
10
11#include "lgc.h"
12#include "lobject.h"
13#include "lstate.h"
14
15
16#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
17
18#define sizeudata(u) (sizeof(union Udata)+(u)->len)
19
20#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
21#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
22 (sizeof(s)/sizeof(char))-1))
23
24#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
25
26LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
27LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
28LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
29
30
31#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lstrlib.c b/libraries/LuaJIT-1.1.7/src/lstrlib.c
new file mode 100644
index 0000000..fe452ce
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lstrlib.c
@@ -0,0 +1,871 @@
1/*
2** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $
3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <stddef.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define lstrlib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23/* macro to `unsign' a character */
24#define uchar(c) ((unsigned char)(c))
25
26
27
28static int str_len (lua_State *L) {
29 size_t l;
30 luaL_checklstring(L, 1, &l);
31 lua_pushinteger(L, l);
32 return 1;
33}
34
35
36static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
37 /* relative string position: negative means back from end */
38 if (pos < 0) pos += (ptrdiff_t)len + 1;
39 return (pos >= 0) ? pos : 0;
40}
41
42
43static int str_sub (lua_State *L) {
44 size_t l;
45 const char *s = luaL_checklstring(L, 1, &l);
46 ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
47 ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
48 if (start < 1) start = 1;
49 if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
50 if (start <= end)
51 lua_pushlstring(L, s+start-1, end-start+1);
52 else lua_pushliteral(L, "");
53 return 1;
54}
55
56
57static int str_reverse (lua_State *L) {
58 size_t l;
59 luaL_Buffer b;
60 const char *s = luaL_checklstring(L, 1, &l);
61 luaL_buffinit(L, &b);
62 while (l--) luaL_addchar(&b, s[l]);
63 luaL_pushresult(&b);
64 return 1;
65}
66
67
68static int str_lower (lua_State *L) {
69 size_t l;
70 size_t i;
71 luaL_Buffer b;
72 const char *s = luaL_checklstring(L, 1, &l);
73 luaL_buffinit(L, &b);
74 for (i=0; i<l; i++)
75 luaL_addchar(&b, tolower(uchar(s[i])));
76 luaL_pushresult(&b);
77 return 1;
78}
79
80
81static int str_upper (lua_State *L) {
82 size_t l;
83 size_t i;
84 luaL_Buffer b;
85 const char *s = luaL_checklstring(L, 1, &l);
86 luaL_buffinit(L, &b);
87 for (i=0; i<l; i++)
88 luaL_addchar(&b, toupper(uchar(s[i])));
89 luaL_pushresult(&b);
90 return 1;
91}
92
93static int str_rep (lua_State *L) {
94 size_t l;
95 luaL_Buffer b;
96 const char *s = luaL_checklstring(L, 1, &l);
97 int n = luaL_checkint(L, 2);
98 luaL_buffinit(L, &b);
99 while (n-- > 0)
100 luaL_addlstring(&b, s, l);
101 luaL_pushresult(&b);
102 return 1;
103}
104
105
106static int str_byte (lua_State *L) {
107 size_t l;
108 const char *s = luaL_checklstring(L, 1, &l);
109 ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
110 ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
111 int n, i;
112 if (posi <= 0) posi = 1;
113 if ((size_t)pose > l) pose = l;
114 if (posi > pose) return 0; /* empty interval; return no values */
115 n = (int)(pose - posi + 1);
116 if (posi + n <= pose) /* overflow? */
117 luaL_error(L, "string slice too long");
118 luaL_checkstack(L, n, "string slice too long");
119 for (i=0; i<n; i++)
120 lua_pushinteger(L, uchar(s[posi+i-1]));
121 return n;
122}
123
124
125static int str_char (lua_State *L) {
126 int n = lua_gettop(L); /* number of arguments */
127 int i;
128 luaL_Buffer b;
129 luaL_buffinit(L, &b);
130 for (i=1; i<=n; i++) {
131 int c = luaL_checkint(L, i);
132 luaL_argcheck(L, uchar(c) == c, i, "invalid value");
133 luaL_addchar(&b, uchar(c));
134 }
135 luaL_pushresult(&b);
136 return 1;
137}
138
139
140static int writer (lua_State *L, const void* b, size_t size, void* B) {
141 (void)L;
142 luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
143 return 0;
144}
145
146
147static int str_dump (lua_State *L) {
148 luaL_Buffer b;
149 luaL_checktype(L, 1, LUA_TFUNCTION);
150 lua_settop(L, 1);
151 luaL_buffinit(L,&b);
152 if (lua_dump(L, writer, &b) != 0)
153 luaL_error(L, "unable to dump given function");
154 luaL_pushresult(&b);
155 return 1;
156}
157
158
159
160/*
161** {======================================================
162** PATTERN MATCHING
163** =======================================================
164*/
165
166
167#define CAP_UNFINISHED (-1)
168#define CAP_POSITION (-2)
169
170typedef struct MatchState {
171 const char *src_init; /* init of source string */
172 const char *src_end; /* end (`\0') of source string */
173 lua_State *L;
174 int level; /* total number of captures (finished or unfinished) */
175 struct {
176 const char *init;
177 ptrdiff_t len;
178 } capture[LUA_MAXCAPTURES];
179} MatchState;
180
181
182#define L_ESC '%'
183#define SPECIALS "^$*+?.([%-"
184
185
186static int check_capture (MatchState *ms, int l) {
187 l -= '1';
188 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
189 return luaL_error(ms->L, "invalid capture index");
190 return l;
191}
192
193
194static int capture_to_close (MatchState *ms) {
195 int level = ms->level;
196 for (level--; level>=0; level--)
197 if (ms->capture[level].len == CAP_UNFINISHED) return level;
198 return luaL_error(ms->L, "invalid pattern capture");
199}
200
201
202static const char *classend (MatchState *ms, const char *p) {
203 switch (*p++) {
204 case L_ESC: {
205 if (*p == '\0')
206 luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
207 return p+1;
208 }
209 case '[': {
210 if (*p == '^') p++;
211 do { /* look for a `]' */
212 if (*p == '\0')
213 luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
214 if (*(p++) == L_ESC && *p != '\0')
215 p++; /* skip escapes (e.g. `%]') */
216 } while (*p != ']');
217 return p+1;
218 }
219 default: {
220 return p;
221 }
222 }
223}
224
225
226static int match_class (int c, int cl) {
227 int res;
228 switch (tolower(cl)) {
229 case 'a' : res = isalpha(c); break;
230 case 'c' : res = iscntrl(c); break;
231 case 'd' : res = isdigit(c); break;
232 case 'l' : res = islower(c); break;
233 case 'p' : res = ispunct(c); break;
234 case 's' : res = isspace(c); break;
235 case 'u' : res = isupper(c); break;
236 case 'w' : res = isalnum(c); break;
237 case 'x' : res = isxdigit(c); break;
238 case 'z' : res = (c == 0); break;
239 default: return (cl == c);
240 }
241 return (islower(cl) ? res : !res);
242}
243
244
245static int matchbracketclass (int c, const char *p, const char *ec) {
246 int sig = 1;
247 if (*(p+1) == '^') {
248 sig = 0;
249 p++; /* skip the `^' */
250 }
251 while (++p < ec) {
252 if (*p == L_ESC) {
253 p++;
254 if (match_class(c, uchar(*p)))
255 return sig;
256 }
257 else if ((*(p+1) == '-') && (p+2 < ec)) {
258 p+=2;
259 if (uchar(*(p-2)) <= c && c <= uchar(*p))
260 return sig;
261 }
262 else if (uchar(*p) == c) return sig;
263 }
264 return !sig;
265}
266
267
268static int singlematch (int c, const char *p, const char *ep) {
269 switch (*p) {
270 case '.': return 1; /* matches any char */
271 case L_ESC: return match_class(c, uchar(*(p+1)));
272 case '[': return matchbracketclass(c, p, ep-1);
273 default: return (uchar(*p) == c);
274 }
275}
276
277
278static const char *match (MatchState *ms, const char *s, const char *p);
279
280
281static const char *matchbalance (MatchState *ms, const char *s,
282 const char *p) {
283 if (*p == 0 || *(p+1) == 0)
284 luaL_error(ms->L, "unbalanced pattern");
285 if (*s != *p) return NULL;
286 else {
287 int b = *p;
288 int e = *(p+1);
289 int cont = 1;
290 while (++s < ms->src_end) {
291 if (*s == e) {
292 if (--cont == 0) return s+1;
293 }
294 else if (*s == b) cont++;
295 }
296 }
297 return NULL; /* string ends out of balance */
298}
299
300
301static const char *max_expand (MatchState *ms, const char *s,
302 const char *p, const char *ep) {
303 ptrdiff_t i = 0; /* counts maximum expand for item */
304 while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
305 i++;
306 /* keeps trying to match with the maximum repetitions */
307 while (i>=0) {
308 const char *res = match(ms, (s+i), ep+1);
309 if (res) return res;
310 i--; /* else didn't match; reduce 1 repetition to try again */
311 }
312 return NULL;
313}
314
315
316static const char *min_expand (MatchState *ms, const char *s,
317 const char *p, const char *ep) {
318 for (;;) {
319 const char *res = match(ms, s, ep+1);
320 if (res != NULL)
321 return res;
322 else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
323 s++; /* try with one more repetition */
324 else return NULL;
325 }
326}
327
328
329static const char *start_capture (MatchState *ms, const char *s,
330 const char *p, int what) {
331 const char *res;
332 int level = ms->level;
333 if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
334 ms->capture[level].init = s;
335 ms->capture[level].len = what;
336 ms->level = level+1;
337 if ((res=match(ms, s, p)) == NULL) /* match failed? */
338 ms->level--; /* undo capture */
339 return res;
340}
341
342
343static const char *end_capture (MatchState *ms, const char *s,
344 const char *p) {
345 int l = capture_to_close(ms);
346 const char *res;
347 ms->capture[l].len = s - ms->capture[l].init; /* close capture */
348 if ((res = match(ms, s, p)) == NULL) /* match failed? */
349 ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
350 return res;
351}
352
353
354static const char *match_capture (MatchState *ms, const char *s, int l) {
355 size_t len;
356 l = check_capture(ms, l);
357 len = ms->capture[l].len;
358 if ((size_t)(ms->src_end-s) >= len &&
359 memcmp(ms->capture[l].init, s, len) == 0)
360 return s+len;
361 else return NULL;
362}
363
364
365static const char *match (MatchState *ms, const char *s, const char *p) {
366 init: /* using goto's to optimize tail recursion */
367 switch (*p) {
368 case '(': { /* start capture */
369 if (*(p+1) == ')') /* position capture? */
370 return start_capture(ms, s, p+2, CAP_POSITION);
371 else
372 return start_capture(ms, s, p+1, CAP_UNFINISHED);
373 }
374 case ')': { /* end capture */
375 return end_capture(ms, s, p+1);
376 }
377 case L_ESC: {
378 switch (*(p+1)) {
379 case 'b': { /* balanced string? */
380 s = matchbalance(ms, s, p+2);
381 if (s == NULL) return NULL;
382 p+=4; goto init; /* else return match(ms, s, p+4); */
383 }
384 case 'f': { /* frontier? */
385 const char *ep; char previous;
386 p += 2;
387 if (*p != '[')
388 luaL_error(ms->L, "missing " LUA_QL("[") " after "
389 LUA_QL("%%f") " in pattern");
390 ep = classend(ms, p); /* points to what is next */
391 previous = (s == ms->src_init) ? '\0' : *(s-1);
392 if (matchbracketclass(uchar(previous), p, ep-1) ||
393 !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
394 p=ep; goto init; /* else return match(ms, s, ep); */
395 }
396 default: {
397 if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
398 s = match_capture(ms, s, uchar(*(p+1)));
399 if (s == NULL) return NULL;
400 p+=2; goto init; /* else return match(ms, s, p+2) */
401 }
402 goto dflt; /* case default */
403 }
404 }
405 }
406 case '\0': { /* end of pattern */
407 return s; /* match succeeded */
408 }
409 case '$': {
410 if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
411 return (s == ms->src_end) ? s : NULL; /* check end of string */
412 else goto dflt;
413 }
414 default: dflt: { /* it is a pattern item */
415 const char *ep = classend(ms, p); /* points to what is next */
416 int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
417 switch (*ep) {
418 case '?': { /* optional */
419 const char *res;
420 if (m && ((res=match(ms, s+1, ep+1)) != NULL))
421 return res;
422 p=ep+1; goto init; /* else return match(ms, s, ep+1); */
423 }
424 case '*': { /* 0 or more repetitions */
425 return max_expand(ms, s, p, ep);
426 }
427 case '+': { /* 1 or more repetitions */
428 return (m ? max_expand(ms, s+1, p, ep) : NULL);
429 }
430 case '-': { /* 0 or more repetitions (minimum) */
431 return min_expand(ms, s, p, ep);
432 }
433 default: {
434 if (!m) return NULL;
435 s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
436 }
437 }
438 }
439 }
440}
441
442
443
444static const char *lmemfind (const char *s1, size_t l1,
445 const char *s2, size_t l2) {
446 if (l2 == 0) return s1; /* empty strings are everywhere */
447 else if (l2 > l1) return NULL; /* avoids a negative `l1' */
448 else {
449 const char *init; /* to search for a `*s2' inside `s1' */
450 l2--; /* 1st char will be checked by `memchr' */
451 l1 = l1-l2; /* `s2' cannot be found after that */
452 while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
453 init++; /* 1st char is already checked */
454 if (memcmp(init, s2+1, l2) == 0)
455 return init-1;
456 else { /* correct `l1' and `s1' to try again */
457 l1 -= init-s1;
458 s1 = init;
459 }
460 }
461 return NULL; /* not found */
462 }
463}
464
465
466static void push_onecapture (MatchState *ms, int i, const char *s,
467 const char *e) {
468 if (i >= ms->level) {
469 if (i == 0) /* ms->level == 0, too */
470 lua_pushlstring(ms->L, s, e - s); /* add whole match */
471 else
472 luaL_error(ms->L, "invalid capture index");
473 }
474 else {
475 ptrdiff_t l = ms->capture[i].len;
476 if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
477 if (l == CAP_POSITION)
478 lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
479 else
480 lua_pushlstring(ms->L, ms->capture[i].init, l);
481 }
482}
483
484
485static int push_captures (MatchState *ms, const char *s, const char *e) {
486 int i;
487 int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
488 luaL_checkstack(ms->L, nlevels, "too many captures");
489 for (i = 0; i < nlevels; i++)
490 push_onecapture(ms, i, s, e);
491 return nlevels; /* number of strings pushed */
492}
493
494
495static int str_find_aux (lua_State *L, int find) {
496 size_t l1, l2;
497 const char *s = luaL_checklstring(L, 1, &l1);
498 const char *p = luaL_checklstring(L, 2, &l2);
499 ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
500 if (init < 0) init = 0;
501 else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
502 if (find && (lua_toboolean(L, 4) || /* explicit request? */
503 strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
504 /* do a plain search */
505 const char *s2 = lmemfind(s+init, l1-init, p, l2);
506 if (s2) {
507 lua_pushinteger(L, s2-s+1);
508 lua_pushinteger(L, s2-s+l2);
509 return 2;
510 }
511 }
512 else {
513 MatchState ms;
514 int anchor = (*p == '^') ? (p++, 1) : 0;
515 const char *s1=s+init;
516 ms.L = L;
517 ms.src_init = s;
518 ms.src_end = s+l1;
519 do {
520 const char *res;
521 ms.level = 0;
522 if ((res=match(&ms, s1, p)) != NULL) {
523 if (find) {
524 lua_pushinteger(L, s1-s+1); /* start */
525 lua_pushinteger(L, res-s); /* end */
526 return push_captures(&ms, NULL, 0) + 2;
527 }
528 else
529 return push_captures(&ms, s1, res);
530 }
531 } while (s1++ < ms.src_end && !anchor);
532 }
533 lua_pushnil(L); /* not found */
534 return 1;
535}
536
537
538static int str_find (lua_State *L) {
539 return str_find_aux(L, 1);
540}
541
542
543static int str_match (lua_State *L) {
544 return str_find_aux(L, 0);
545}
546
547
548static int gmatch_aux (lua_State *L) {
549 MatchState ms;
550 size_t ls;
551 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
552 const char *p = lua_tostring(L, lua_upvalueindex(2));
553 const char *src;
554 ms.L = L;
555 ms.src_init = s;
556 ms.src_end = s+ls;
557 for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
558 src <= ms.src_end;
559 src++) {
560 const char *e;
561 ms.level = 0;
562 if ((e = match(&ms, src, p)) != NULL) {
563 lua_Integer newstart = e-s;
564 if (e == src) newstart++; /* empty match? go at least one position */
565 lua_pushinteger(L, newstart);
566 lua_replace(L, lua_upvalueindex(3));
567 return push_captures(&ms, src, e);
568 }
569 }
570 return 0; /* not found */
571}
572
573
574static int gmatch (lua_State *L) {
575 luaL_checkstring(L, 1);
576 luaL_checkstring(L, 2);
577 lua_settop(L, 2);
578 lua_pushinteger(L, 0);
579 lua_pushcclosure(L, gmatch_aux, 3);
580 return 1;
581}
582
583
584static int gfind_nodef (lua_State *L) {
585 return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
586 LUA_QL("string.gmatch"));
587}
588
589
590static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
591 const char *e) {
592 size_t l, i;
593 const char *news = lua_tolstring(ms->L, 3, &l);
594 for (i = 0; i < l; i++) {
595 if (news[i] != L_ESC)
596 luaL_addchar(b, news[i]);
597 else {
598 i++; /* skip ESC */
599 if (!isdigit(uchar(news[i])))
600 luaL_addchar(b, news[i]);
601 else if (news[i] == '0')
602 luaL_addlstring(b, s, e - s);
603 else {
604 push_onecapture(ms, news[i] - '1', s, e);
605 luaL_addvalue(b); /* add capture to accumulated result */
606 }
607 }
608 }
609}
610
611
612static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
613 const char *e) {
614 lua_State *L = ms->L;
615 switch (lua_type(L, 3)) {
616 case LUA_TNUMBER:
617 case LUA_TSTRING: {
618 add_s(ms, b, s, e);
619 return;
620 }
621 case LUA_TFUNCTION: {
622 int n;
623 lua_pushvalue(L, 3);
624 n = push_captures(ms, s, e);
625 lua_call(L, n, 1);
626 break;
627 }
628 case LUA_TTABLE: {
629 push_onecapture(ms, 0, s, e);
630 lua_gettable(L, 3);
631 break;
632 }
633 }
634 if (!lua_toboolean(L, -1)) { /* nil or false? */
635 lua_pop(L, 1);
636 lua_pushlstring(L, s, e - s); /* keep original text */
637 }
638 else if (!lua_isstring(L, -1))
639 luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
640 luaL_addvalue(b); /* add result to accumulator */
641}
642
643
644static int str_gsub (lua_State *L) {
645 size_t srcl;
646 const char *src = luaL_checklstring(L, 1, &srcl);
647 const char *p = luaL_checkstring(L, 2);
648 int tr = lua_type(L, 3);
649 int max_s = luaL_optint(L, 4, srcl+1);
650 int anchor = (*p == '^') ? (p++, 1) : 0;
651 int n = 0;
652 MatchState ms;
653 luaL_Buffer b;
654 luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
655 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
656 "string/function/table expected");
657 luaL_buffinit(L, &b);
658 ms.L = L;
659 ms.src_init = src;
660 ms.src_end = src+srcl;
661 while (n < max_s) {
662 const char *e;
663 ms.level = 0;
664 e = match(&ms, src, p);
665 if (e) {
666 n++;
667 add_value(&ms, &b, src, e);
668 }
669 if (e && e>src) /* non empty match? */
670 src = e; /* skip it */
671 else if (src < ms.src_end)
672 luaL_addchar(&b, *src++);
673 else break;
674 if (anchor) break;
675 }
676 luaL_addlstring(&b, src, ms.src_end-src);
677 luaL_pushresult(&b);
678 lua_pushinteger(L, n); /* number of substitutions */
679 return 2;
680}
681
682/* }====================================================== */
683
684
685/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
686#define MAX_ITEM 512
687/* valid flags in a format specification */
688#define FLAGS "-+ #0"
689/*
690** maximum size of each format specification (such as '%-099.99d')
691** (+10 accounts for %99.99x plus margin of error)
692*/
693#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
694
695
696static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
697 size_t l;
698 const char *s = luaL_checklstring(L, arg, &l);
699 luaL_addchar(b, '"');
700 while (l--) {
701 switch (*s) {
702 case '"': case '\\': case '\n': {
703 luaL_addchar(b, '\\');
704 luaL_addchar(b, *s);
705 break;
706 }
707 case '\r': {
708 luaL_addlstring(b, "\\r", 2);
709 break;
710 }
711 case '\0': {
712 luaL_addlstring(b, "\\000", 4);
713 break;
714 }
715 default: {
716 luaL_addchar(b, *s);
717 break;
718 }
719 }
720 s++;
721 }
722 luaL_addchar(b, '"');
723}
724
725static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
726 const char *p = strfrmt;
727 while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
728 if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
729 luaL_error(L, "invalid format (repeated flags)");
730 if (isdigit(uchar(*p))) p++; /* skip width */
731 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
732 if (*p == '.') {
733 p++;
734 if (isdigit(uchar(*p))) p++; /* skip precision */
735 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
736 }
737 if (isdigit(uchar(*p)))
738 luaL_error(L, "invalid format (width or precision too long)");
739 *(form++) = '%';
740 strncpy(form, strfrmt, p - strfrmt + 1);
741 form += p - strfrmt + 1;
742 *form = '\0';
743 return p;
744}
745
746
747static void addintlen (char *form) {
748 size_t l = strlen(form);
749 char spec = form[l - 1];
750 strcpy(form + l - 1, LUA_INTFRMLEN);
751 form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
752 form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
753}
754
755
756static int str_format (lua_State *L) {
757 int top = lua_gettop(L);
758 int arg = 1;
759 size_t sfl;
760 const char *strfrmt = luaL_checklstring(L, arg, &sfl);
761 const char *strfrmt_end = strfrmt+sfl;
762 luaL_Buffer b;
763 luaL_buffinit(L, &b);
764 while (strfrmt < strfrmt_end) {
765 if (*strfrmt != L_ESC)
766 luaL_addchar(&b, *strfrmt++);
767 else if (*++strfrmt == L_ESC)
768 luaL_addchar(&b, *strfrmt++); /* %% */
769 else { /* format item */
770 char form[MAX_FORMAT]; /* to store the format (`%...') */
771 char buff[MAX_ITEM]; /* to store the formatted item */
772 if (++arg > top)
773 luaL_argerror(L, arg, "no value");
774 strfrmt = scanformat(L, strfrmt, form);
775 switch (*strfrmt++) {
776 case 'c': {
777 sprintf(buff, form, (int)luaL_checknumber(L, arg));
778 break;
779 }
780 case 'd': case 'i': {
781 addintlen(form);
782 sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
783 break;
784 }
785 case 'o': case 'u': case 'x': case 'X': {
786 addintlen(form);
787 sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
788 break;
789 }
790 case 'e': case 'E': case 'f':
791 case 'g': case 'G': {
792 sprintf(buff, form, (double)luaL_checknumber(L, arg));
793 break;
794 }
795 case 'q': {
796 addquoted(L, &b, arg);
797 continue; /* skip the 'addsize' at the end */
798 }
799 case 's': {
800 size_t l;
801 const char *s = luaL_checklstring(L, arg, &l);
802 if (!strchr(form, '.') && l >= 100) {
803 /* no precision and string is too long to be formatted;
804 keep original string */
805 lua_pushvalue(L, arg);
806 luaL_addvalue(&b);
807 continue; /* skip the `addsize' at the end */
808 }
809 else {
810 sprintf(buff, form, s);
811 break;
812 }
813 }
814 default: { /* also treat cases `pnLlh' */
815 return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
816 LUA_QL("format"), *(strfrmt - 1));
817 }
818 }
819 luaL_addlstring(&b, buff, strlen(buff));
820 }
821 }
822 luaL_pushresult(&b);
823 return 1;
824}
825
826
827static const luaL_Reg strlib[] = {
828 {"byte", str_byte},
829 {"char", str_char},
830 {"dump", str_dump},
831 {"find", str_find},
832 {"format", str_format},
833 {"gfind", gfind_nodef},
834 {"gmatch", gmatch},
835 {"gsub", str_gsub},
836 {"len", str_len},
837 {"lower", str_lower},
838 {"match", str_match},
839 {"rep", str_rep},
840 {"reverse", str_reverse},
841 {"sub", str_sub},
842 {"upper", str_upper},
843 {NULL, NULL}
844};
845
846
847static void createmetatable (lua_State *L) {
848 lua_createtable(L, 0, 1); /* create metatable for strings */
849 lua_pushliteral(L, ""); /* dummy string */
850 lua_pushvalue(L, -2);
851 lua_setmetatable(L, -2); /* set string metatable */
852 lua_pop(L, 1); /* pop dummy string */
853 lua_pushvalue(L, -2); /* string library... */
854 lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
855 lua_pop(L, 1); /* pop metatable */
856}
857
858
859/*
860** Open string library
861*/
862LUALIB_API int luaopen_string (lua_State *L) {
863 luaL_register(L, LUA_STRLIBNAME, strlib);
864#if defined(LUA_COMPAT_GFIND)
865 lua_getfield(L, -1, "gmatch");
866 lua_setfield(L, -2, "gfind");
867#endif
868 createmetatable(L);
869 return 1;
870}
871
diff --git a/libraries/LuaJIT-1.1.7/src/ltable.c b/libraries/LuaJIT-1.1.7/src/ltable.c
new file mode 100644
index 0000000..6b226ad
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ltable.c
@@ -0,0 +1,588 @@
1/*
2** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $
3** Lua tables (hash)
4** See Copyright Notice in lua.h
5*/
6
7
8/*
9** Implementation of tables (aka arrays, objects, or hash tables).
10** Tables keep its elements in two parts: an array part and a hash part.
11** Non-negative integer keys are all candidates to be kept in the array
12** part. The actual size of the array is the largest `n' such that at
13** least half the slots between 0 and n are in use.
14** Hash uses a mix of chained scatter table with Brent's variation.
15** A main invariant of these tables is that, if an element is not
16** in its main position (i.e. the `original' position that its hash gives
17** to it), then the colliding element is in its own main position.
18** Hence even when the load factor reaches 100%, performance remains good.
19*/
20
21#include <math.h>
22#include <string.h>
23
24#define ltable_c
25#define LUA_CORE
26
27#include "lua.h"
28
29#include "ldebug.h"
30#include "ldo.h"
31#include "lgc.h"
32#include "lmem.h"
33#include "lobject.h"
34#include "lstate.h"
35#include "ltable.h"
36
37
38/*
39** max size of array part is 2^MAXBITS
40*/
41#if LUAI_BITSINT > 26
42#define MAXBITS 26
43#else
44#define MAXBITS (LUAI_BITSINT-2)
45#endif
46
47#define MAXASIZE (1 << MAXBITS)
48
49
50#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
51
52#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
53#define hashboolean(t,p) hashpow2(t, p)
54
55
56/*
57** for some types, it is better to avoid modulus by power of 2, as
58** they tend to have many 2 factors.
59*/
60#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
61
62
63#define hashpointer(t,p) hashmod(t, IntPoint(p))
64
65
66/*
67** number of ints inside a lua_Number
68*/
69#define numints cast_int(sizeof(lua_Number)/sizeof(int))
70
71
72
73#define dummynode (&dummynode_)
74
75static const Node dummynode_ = {
76 {{NULL}, LUA_TNIL}, /* value */
77 {{{NULL}, LUA_TNIL, NULL}} /* key */
78};
79
80
81/*
82** hash for lua_Numbers
83*/
84static Node *hashnum (const Table *t, lua_Number n) {
85 unsigned int a[numints];
86 int i;
87 if (luai_numeq(n, 0)) /* avoid problems with -0 */
88 return gnode(t, 0);
89 memcpy(a, &n, sizeof(a));
90 for (i = 1; i < numints; i++) a[0] += a[i];
91 return hashmod(t, a[0]);
92}
93
94
95
96/*
97** returns the `main' position of an element in a table (that is, the index
98** of its hash value)
99*/
100static Node *mainposition (const Table *t, const TValue *key) {
101 switch (ttype(key)) {
102 case LUA_TNUMBER:
103 return hashnum(t, nvalue(key));
104 case LUA_TSTRING:
105 return hashstr(t, rawtsvalue(key));
106 case LUA_TBOOLEAN:
107 return hashboolean(t, bvalue(key));
108 case LUA_TLIGHTUSERDATA:
109 return hashpointer(t, pvalue(key));
110 default:
111 return hashpointer(t, gcvalue(key));
112 }
113}
114
115
116/*
117** returns the index for `key' if `key' is an appropriate key to live in
118** the array part of the table, -1 otherwise.
119*/
120static int arrayindex (const TValue *key) {
121 if (ttisnumber(key)) {
122 lua_Number n = nvalue(key);
123 int k;
124 lua_number2int(k, n);
125 if (luai_numeq(cast_num(k), n))
126 return k;
127 }
128 return -1; /* `key' did not match some condition */
129}
130
131
132/*
133** returns the index of a `key' for table traversals. First goes all
134** elements in the array part, then elements in the hash part. The
135** beginning of a traversal is signalled by -1.
136*/
137static int findindex (lua_State *L, Table *t, StkId key) {
138 int i;
139 if (ttisnil(key)) return -1; /* first iteration */
140 i = arrayindex(key);
141 if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
142 return i-1; /* yes; that's the index (corrected to C) */
143 else {
144 Node *n = mainposition(t, key);
145 do { /* check whether `key' is somewhere in the chain */
146 /* key may be dead already, but it is ok to use it in `next' */
147 if (luaO_rawequalObj(key2tval(n), key) ||
148 (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
149 gcvalue(gkey(n)) == gcvalue(key))) {
150 i = cast_int(n - gnode(t, 0)); /* key index in hash table */
151 /* hash elements are numbered after array ones */
152 return i + t->sizearray;
153 }
154 else n = gnext(n);
155 } while (n);
156 luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
157 return 0; /* to avoid warnings */
158 }
159}
160
161
162int luaH_next (lua_State *L, Table *t, StkId key) {
163 int i = findindex(L, t, key); /* find original element */
164 for (i++; i < t->sizearray; i++) { /* try first array part */
165 if (!ttisnil(&t->array[i])) { /* a non-nil value? */
166 setnvalue(key, cast_num(i+1));
167 setobj2s(L, key+1, &t->array[i]);
168 return 1;
169 }
170 }
171 for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
172 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
173 setobj2s(L, key, key2tval(gnode(t, i)));
174 setobj2s(L, key+1, gval(gnode(t, i)));
175 return 1;
176 }
177 }
178 return 0; /* no more elements */
179}
180
181
182/*
183** {=============================================================
184** Rehash
185** ==============================================================
186*/
187
188
189static int computesizes (int nums[], int *narray) {
190 int i;
191 int twotoi; /* 2^i */
192 int a = 0; /* number of elements smaller than 2^i */
193 int na = 0; /* number of elements to go to array part */
194 int n = 0; /* optimal size for array part */
195 for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
196 if (nums[i] > 0) {
197 a += nums[i];
198 if (a > twotoi/2) { /* more than half elements present? */
199 n = twotoi; /* optimal size (till now) */
200 na = a; /* all elements smaller than n will go to array part */
201 }
202 }
203 if (a == *narray) break; /* all elements already counted */
204 }
205 *narray = n;
206 lua_assert(*narray/2 <= na && na <= *narray);
207 return na;
208}
209
210
211static int countint (const TValue *key, int *nums) {
212 int k = arrayindex(key);
213 if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
214 nums[ceillog2(k)]++; /* count as such */
215 return 1;
216 }
217 else
218 return 0;
219}
220
221
222static int numusearray (const Table *t, int *nums) {
223 int lg;
224 int ttlg; /* 2^lg */
225 int ause = 0; /* summation of `nums' */
226 int i = 1; /* count to traverse all array keys */
227 for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
228 int lc = 0; /* counter */
229 int lim = ttlg;
230 if (lim > t->sizearray) {
231 lim = t->sizearray; /* adjust upper limit */
232 if (i > lim)
233 break; /* no more elements to count */
234 }
235 /* count elements in range (2^(lg-1), 2^lg] */
236 for (; i <= lim; i++) {
237 if (!ttisnil(&t->array[i-1]))
238 lc++;
239 }
240 nums[lg] += lc;
241 ause += lc;
242 }
243 return ause;
244}
245
246
247static int numusehash (const Table *t, int *nums, int *pnasize) {
248 int totaluse = 0; /* total number of elements */
249 int ause = 0; /* summation of `nums' */
250 int i = sizenode(t);
251 while (i--) {
252 Node *n = &t->node[i];
253 if (!ttisnil(gval(n))) {
254 ause += countint(key2tval(n), nums);
255 totaluse++;
256 }
257 }
258 *pnasize += ause;
259 return totaluse;
260}
261
262
263static void setarrayvector (lua_State *L, Table *t, int size) {
264 int i;
265 luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
266 for (i=t->sizearray; i<size; i++)
267 setnilvalue(&t->array[i]);
268 t->sizearray = size;
269}
270
271
272static void setnodevector (lua_State *L, Table *t, int size) {
273 int lsize;
274 if (size == 0) { /* no elements to hash part? */
275 t->node = cast(Node *, dummynode); /* use common `dummynode' */
276 lsize = 0;
277 }
278 else {
279 int i;
280 lsize = ceillog2(size);
281 if (lsize > MAXBITS)
282 luaG_runerror(L, "table overflow");
283 size = twoto(lsize);
284 t->node = luaM_newvector(L, size, Node);
285 for (i=0; i<size; i++) {
286 Node *n = gnode(t, i);
287 gnext(n) = NULL;
288 setnilvalue(gkey(n));
289 setnilvalue(gval(n));
290 }
291 }
292 t->lsizenode = cast_byte(lsize);
293 t->lastfree = gnode(t, size); /* all positions are free */
294}
295
296
297static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
298 int i;
299 int oldasize = t->sizearray;
300 int oldhsize = t->lsizenode;
301 Node *nold = t->node; /* save old hash ... */
302 if (nasize > oldasize) /* array part must grow? */
303 setarrayvector(L, t, nasize);
304 /* create new hash part with appropriate size */
305 setnodevector(L, t, nhsize);
306 if (nasize < oldasize) { /* array part must shrink? */
307 t->sizearray = nasize;
308 /* re-insert elements from vanishing slice */
309 for (i=nasize; i<oldasize; i++) {
310 if (!ttisnil(&t->array[i]))
311 setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
312 }
313 /* shrink array */
314 luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
315 }
316 /* re-insert elements from hash part */
317 for (i = twoto(oldhsize) - 1; i >= 0; i--) {
318 Node *old = nold+i;
319 if (!ttisnil(gval(old)))
320 setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
321 }
322 if (nold != dummynode)
323 luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
324}
325
326
327void luaH_resizearray (lua_State *L, Table *t, int nasize) {
328 int nsize = (t->node == dummynode) ? 0 : sizenode(t);
329 resize(L, t, nasize, nsize);
330}
331
332
333static void rehash (lua_State *L, Table *t, const TValue *ek) {
334 int nasize, na;
335 int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
336 int i;
337 int totaluse;
338 for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
339 nasize = numusearray(t, nums); /* count keys in array part */
340 totaluse = nasize; /* all those keys are integer keys */
341 totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
342 /* count extra key */
343 nasize += countint(ek, nums);
344 totaluse++;
345 /* compute new size for array part */
346 na = computesizes(nums, &nasize);
347 /* resize the table to new computed sizes */
348 resize(L, t, nasize, totaluse - na);
349}
350
351
352
353/*
354** }=============================================================
355*/
356
357
358Table *luaH_new (lua_State *L, int narray, int nhash) {
359 Table *t = luaM_new(L, Table);
360 luaC_link(L, obj2gco(t), LUA_TTABLE);
361 t->metatable = NULL;
362 t->flags = cast_byte(~0);
363 /* temporary values (kept only if some malloc fails) */
364 t->array = NULL;
365 t->sizearray = 0;
366 t->lsizenode = 0;
367 t->node = cast(Node *, dummynode);
368 setarrayvector(L, t, narray);
369 setnodevector(L, t, nhash);
370 return t;
371}
372
373
374void luaH_free (lua_State *L, Table *t) {
375 if (t->node != dummynode)
376 luaM_freearray(L, t->node, sizenode(t), Node);
377 luaM_freearray(L, t->array, t->sizearray, TValue);
378 luaM_free(L, t);
379}
380
381
382static Node *getfreepos (Table *t) {
383 while (t->lastfree-- > t->node) {
384 if (ttisnil(gkey(t->lastfree)))
385 return t->lastfree;
386 }
387 return NULL; /* could not find a free place */
388}
389
390
391
392/*
393** inserts a new key into a hash table; first, check whether key's main
394** position is free. If not, check whether colliding node is in its main
395** position or not: if it is not, move colliding node to an empty place and
396** put new key in its main position; otherwise (colliding node is in its main
397** position), new key goes to an empty position.
398*/
399TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
400 Node *mp = mainposition(t, key);
401 if (!ttisnil(gval(mp)) || mp == dummynode) {
402 Node *othern;
403 Node *n = getfreepos(t); /* get a free place */
404 if (n == NULL) { /* cannot find a free place? */
405 rehash(L, t, key); /* grow table */
406 return luaH_set(L, t, key); /* re-insert key into grown table */
407 }
408 lua_assert(n != dummynode);
409 othern = mainposition(t, key2tval(mp));
410 if (othern != mp) { /* is colliding node out of its main position? */
411 /* yes; move colliding node into free position */
412 while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
413 gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
414 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
415 gnext(mp) = NULL; /* now `mp' is free */
416 setnilvalue(gval(mp));
417 }
418 else { /* colliding node is in its own main position */
419 /* new node will go into free position */
420 gnext(n) = gnext(mp); /* chain new position */
421 gnext(mp) = n;
422 mp = n;
423 }
424 }
425 gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
426 luaC_barriert(L, t, key);
427 lua_assert(ttisnil(gval(mp)));
428 return gval(mp);
429}
430
431
432/*
433** search function for integers
434*/
435const TValue *luaH_getnum (Table *t, int key) {
436 /* (1 <= key && key <= t->sizearray) */
437 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
438 return &t->array[key-1];
439 else {
440 lua_Number nk = cast_num(key);
441 Node *n = hashnum(t, nk);
442 do { /* check whether `key' is somewhere in the chain */
443 if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
444 return gval(n); /* that's it */
445 else n = gnext(n);
446 } while (n);
447 return luaO_nilobject;
448 }
449}
450
451
452/*
453** search function for strings
454*/
455const TValue *luaH_getstr (Table *t, TString *key) {
456 Node *n = hashstr(t, key);
457 do { /* check whether `key' is somewhere in the chain */
458 if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
459 return gval(n); /* that's it */
460 else n = gnext(n);
461 } while (n);
462 return luaO_nilobject;
463}
464
465
466/*
467** main search function
468*/
469const TValue *luaH_get (Table *t, const TValue *key) {
470 switch (ttype(key)) {
471 case LUA_TNIL: return luaO_nilobject;
472 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
473 case LUA_TNUMBER: {
474 int k;
475 lua_Number n = nvalue(key);
476 lua_number2int(k, n);
477 if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
478 return luaH_getnum(t, k); /* use specialized version */
479 /* else go through */
480 }
481 default: {
482 Node *n = mainposition(t, key);
483 do { /* check whether `key' is somewhere in the chain */
484 if (luaO_rawequalObj(key2tval(n), key))
485 return gval(n); /* that's it */
486 else n = gnext(n);
487 } while (n);
488 return luaO_nilobject;
489 }
490 }
491}
492
493
494TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
495 const TValue *p = luaH_get(t, key);
496 t->flags = 0;
497 if (p != luaO_nilobject)
498 return cast(TValue *, p);
499 else {
500 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
501 else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
502 luaG_runerror(L, "table index is NaN");
503 return luaH_newkey(L, t, key);
504 }
505}
506
507
508TValue *luaH_setnum (lua_State *L, Table *t, int key) {
509 const TValue *p = luaH_getnum(t, key);
510 if (p != luaO_nilobject)
511 return cast(TValue *, p);
512 else {
513 TValue k;
514 setnvalue(&k, cast_num(key));
515 return luaH_newkey(L, t, &k);
516 }
517}
518
519
520TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
521 const TValue *p = luaH_getstr(t, key);
522 if (p != luaO_nilobject)
523 return cast(TValue *, p);
524 else {
525 TValue k;
526 setsvalue(L, &k, key);
527 return luaH_newkey(L, t, &k);
528 }
529}
530
531
532static int unbound_search (Table *t, unsigned int j) {
533 unsigned int i = j; /* i is zero or a present index */
534 j++;
535 /* find `i' and `j' such that i is present and j is not */
536 while (!ttisnil(luaH_getnum(t, j))) {
537 i = j;
538 j *= 2;
539 if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
540 /* table was built with bad purposes: resort to linear search */
541 i = 1;
542 while (!ttisnil(luaH_getnum(t, i))) i++;
543 return i - 1;
544 }
545 }
546 /* now do a binary search between them */
547 while (j - i > 1) {
548 unsigned int m = (i+j)/2;
549 if (ttisnil(luaH_getnum(t, m))) j = m;
550 else i = m;
551 }
552 return i;
553}
554
555
556/*
557** Try to find a boundary in table `t'. A `boundary' is an integer index
558** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
559*/
560int luaH_getn (Table *t) {
561 unsigned int j = t->sizearray;
562 if (j > 0 && ttisnil(&t->array[j - 1])) {
563 /* there is a boundary in the array part: (binary) search for it */
564 unsigned int i = 0;
565 while (j - i > 1) {
566 unsigned int m = (i+j)/2;
567 if (ttisnil(&t->array[m - 1])) j = m;
568 else i = m;
569 }
570 return i;
571 }
572 /* else must find a boundary in hash part */
573 else if (t->node == dummynode) /* hash part is empty? */
574 return j; /* that is easy... */
575 else return unbound_search(t, j);
576}
577
578
579
580#if defined(LUA_DEBUG)
581
582Node *luaH_mainposition (const Table *t, const TValue *key) {
583 return mainposition(t, key);
584}
585
586int luaH_isdummy (Node *n) { return n == dummynode; }
587
588#endif
diff --git a/libraries/LuaJIT-1.1.7/src/ltable.h b/libraries/LuaJIT-1.1.7/src/ltable.h
new file mode 100644
index 0000000..a61c981
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ltable.h
@@ -0,0 +1,41 @@
1/*
2** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $
3** Lua tables (hash)
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltable_h
8#define ltable_h
9
10#include "lobject.h"
11
12
13#define gnode(t,i) (&(t)->node[i])
14#define gkey(n) (&(n)->i_key.nk)
15#define gval(n) (&(n)->i_val)
16#define gnext(n) ((n)->i_key.nk.next)
17
18#define key2tval(n) (&(n)->i_key.tvk)
19
20
21LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
22LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
23LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
24LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
25LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
26LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
27LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
28LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
29LUAI_FUNC void luaH_free (lua_State *L, Table *t);
30LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
31LUAI_FUNC int luaH_getn (Table *t);
32LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
33
34
35#if defined(LUA_DEBUG)
36LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
37LUAI_FUNC int luaH_isdummy (Node *n);
38#endif
39
40
41#endif
diff --git a/libraries/LuaJIT-1.1.7/src/ltablib.c b/libraries/LuaJIT-1.1.7/src/ltablib.c
new file mode 100644
index 0000000..b6d9cb4
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ltablib.c
@@ -0,0 +1,287 @@
1/*
2** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
3** Library for Table Manipulation
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define ltablib_c
11#define LUA_LIB
12
13#include "lua.h"
14
15#include "lauxlib.h"
16#include "lualib.h"
17
18
19#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
20
21
22static int foreachi (lua_State *L) {
23 int i;
24 int n = aux_getn(L, 1);
25 luaL_checktype(L, 2, LUA_TFUNCTION);
26 for (i=1; i <= n; i++) {
27 lua_pushvalue(L, 2); /* function */
28 lua_pushinteger(L, i); /* 1st argument */
29 lua_rawgeti(L, 1, i); /* 2nd argument */
30 lua_call(L, 2, 1);
31 if (!lua_isnil(L, -1))
32 return 1;
33 lua_pop(L, 1); /* remove nil result */
34 }
35 return 0;
36}
37
38
39static int foreach (lua_State *L) {
40 luaL_checktype(L, 1, LUA_TTABLE);
41 luaL_checktype(L, 2, LUA_TFUNCTION);
42 lua_pushnil(L); /* first key */
43 while (lua_next(L, 1)) {
44 lua_pushvalue(L, 2); /* function */
45 lua_pushvalue(L, -3); /* key */
46 lua_pushvalue(L, -3); /* value */
47 lua_call(L, 2, 1);
48 if (!lua_isnil(L, -1))
49 return 1;
50 lua_pop(L, 2); /* remove value and result */
51 }
52 return 0;
53}
54
55
56static int maxn (lua_State *L) {
57 lua_Number max = 0;
58 luaL_checktype(L, 1, LUA_TTABLE);
59 lua_pushnil(L); /* first key */
60 while (lua_next(L, 1)) {
61 lua_pop(L, 1); /* remove value */
62 if (lua_type(L, -1) == LUA_TNUMBER) {
63 lua_Number v = lua_tonumber(L, -1);
64 if (v > max) max = v;
65 }
66 }
67 lua_pushnumber(L, max);
68 return 1;
69}
70
71
72static int getn (lua_State *L) {
73 lua_pushinteger(L, aux_getn(L, 1));
74 return 1;
75}
76
77
78static int setn (lua_State *L) {
79 luaL_checktype(L, 1, LUA_TTABLE);
80#ifndef luaL_setn
81 luaL_setn(L, 1, luaL_checkint(L, 2));
82#else
83 luaL_error(L, LUA_QL("setn") " is obsolete");
84#endif
85 lua_pushvalue(L, 1);
86 return 1;
87}
88
89
90static int tinsert (lua_State *L) {
91 int e = aux_getn(L, 1) + 1; /* first empty element */
92 int pos; /* where to insert new element */
93 switch (lua_gettop(L)) {
94 case 2: { /* called with only 2 arguments */
95 pos = e; /* insert new element at the end */
96 break;
97 }
98 case 3: {
99 int i;
100 pos = luaL_checkint(L, 2); /* 2nd argument is the position */
101 if (pos > e) e = pos; /* `grow' array if necessary */
102 for (i = e; i > pos; i--) { /* move up elements */
103 lua_rawgeti(L, 1, i-1);
104 lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
105 }
106 break;
107 }
108 default: {
109 return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
110 }
111 }
112 luaL_setn(L, 1, e); /* new size */
113 lua_rawseti(L, 1, pos); /* t[pos] = v */
114 return 0;
115}
116
117
118static int tremove (lua_State *L) {
119 int e = aux_getn(L, 1);
120 int pos = luaL_optint(L, 2, e);
121 if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
122 return 0; /* nothing to remove */
123 luaL_setn(L, 1, e - 1); /* t.n = n-1 */
124 lua_rawgeti(L, 1, pos); /* result = t[pos] */
125 for ( ;pos<e; pos++) {
126 lua_rawgeti(L, 1, pos+1);
127 lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
128 }
129 lua_pushnil(L);
130 lua_rawseti(L, 1, e); /* t[e] = nil */
131 return 1;
132}
133
134
135static void addfield (lua_State *L, luaL_Buffer *b, int i) {
136 lua_rawgeti(L, 1, i);
137 if (!lua_isstring(L, -1))
138 luaL_error(L, "invalid value (%s) at index %d in table for "
139 LUA_QL("concat"), luaL_typename(L, -1), i);
140 luaL_addvalue(b);
141}
142
143
144static int tconcat (lua_State *L) {
145 luaL_Buffer b;
146 size_t lsep;
147 int i, last;
148 const char *sep = luaL_optlstring(L, 2, "", &lsep);
149 luaL_checktype(L, 1, LUA_TTABLE);
150 i = luaL_optint(L, 3, 1);
151 last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1));
152 luaL_buffinit(L, &b);
153 for (; i < last; i++) {
154 addfield(L, &b, i);
155 luaL_addlstring(&b, sep, lsep);
156 }
157 if (i == last) /* add last value (if interval was not empty) */
158 addfield(L, &b, i);
159 luaL_pushresult(&b);
160 return 1;
161}
162
163
164
165/*
166** {======================================================
167** Quicksort
168** (based on `Algorithms in MODULA-3', Robert Sedgewick;
169** Addison-Wesley, 1993.)
170*/
171
172
173static void set2 (lua_State *L, int i, int j) {
174 lua_rawseti(L, 1, i);
175 lua_rawseti(L, 1, j);
176}
177
178static int sort_comp (lua_State *L, int a, int b) {
179 if (!lua_isnil(L, 2)) { /* function? */
180 int res;
181 lua_pushvalue(L, 2);
182 lua_pushvalue(L, a-1); /* -1 to compensate function */
183 lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
184 lua_call(L, 2, 1);
185 res = lua_toboolean(L, -1);
186 lua_pop(L, 1);
187 return res;
188 }
189 else /* a < b? */
190 return lua_lessthan(L, a, b);
191}
192
193static void auxsort (lua_State *L, int l, int u) {
194 while (l < u) { /* for tail recursion */
195 int i, j;
196 /* sort elements a[l], a[(l+u)/2] and a[u] */
197 lua_rawgeti(L, 1, l);
198 lua_rawgeti(L, 1, u);
199 if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
200 set2(L, l, u); /* swap a[l] - a[u] */
201 else
202 lua_pop(L, 2);
203 if (u-l == 1) break; /* only 2 elements */
204 i = (l+u)/2;
205 lua_rawgeti(L, 1, i);
206 lua_rawgeti(L, 1, l);
207 if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
208 set2(L, i, l);
209 else {
210 lua_pop(L, 1); /* remove a[l] */
211 lua_rawgeti(L, 1, u);
212 if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
213 set2(L, i, u);
214 else
215 lua_pop(L, 2);
216 }
217 if (u-l == 2) break; /* only 3 elements */
218 lua_rawgeti(L, 1, i); /* Pivot */
219 lua_pushvalue(L, -1);
220 lua_rawgeti(L, 1, u-1);
221 set2(L, i, u-1);
222 /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
223 i = l; j = u-1;
224 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
225 /* repeat ++i until a[i] >= P */
226 while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
227 if (i>u) luaL_error(L, "invalid order function for sorting");
228 lua_pop(L, 1); /* remove a[i] */
229 }
230 /* repeat --j until a[j] <= P */
231 while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
232 if (j<l) luaL_error(L, "invalid order function for sorting");
233 lua_pop(L, 1); /* remove a[j] */
234 }
235 if (j<i) {
236 lua_pop(L, 3); /* pop pivot, a[i], a[j] */
237 break;
238 }
239 set2(L, i, j);
240 }
241 lua_rawgeti(L, 1, u-1);
242 lua_rawgeti(L, 1, i);
243 set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
244 /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
245 /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
246 if (i-l < u-i) {
247 j=l; i=i-1; l=i+2;
248 }
249 else {
250 j=i+1; i=u; u=j-2;
251 }
252 auxsort(L, j, i); /* call recursively the smaller one */
253 } /* repeat the routine for the larger one */
254}
255
256static int sort (lua_State *L) {
257 int n = aux_getn(L, 1);
258 luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
259 if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
260 luaL_checktype(L, 2, LUA_TFUNCTION);
261 lua_settop(L, 2); /* make sure there is two arguments */
262 auxsort(L, 1, n);
263 return 0;
264}
265
266/* }====================================================== */
267
268
269static const luaL_Reg tab_funcs[] = {
270 {"concat", tconcat},
271 {"foreach", foreach},
272 {"foreachi", foreachi},
273 {"getn", getn},
274 {"maxn", maxn},
275 {"insert", tinsert},
276 {"remove", tremove},
277 {"setn", setn},
278 {"sort", sort},
279 {NULL, NULL}
280};
281
282
283LUALIB_API int luaopen_table (lua_State *L) {
284 luaL_register(L, LUA_TABLIBNAME, tab_funcs);
285 return 1;
286}
287
diff --git a/libraries/LuaJIT-1.1.7/src/ltm.c b/libraries/LuaJIT-1.1.7/src/ltm.c
new file mode 100644
index 0000000..c27f0f6
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ltm.c
@@ -0,0 +1,75 @@
1/*
2** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
3** Tag methods
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define ltm_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lobject.h"
16#include "lstate.h"
17#include "lstring.h"
18#include "ltable.h"
19#include "ltm.h"
20
21
22
23const char *const luaT_typenames[] = {
24 "nil", "boolean", "userdata", "number",
25 "string", "table", "function", "userdata", "thread",
26 "proto", "upval"
27};
28
29
30void luaT_init (lua_State *L) {
31 static const char *const luaT_eventname[] = { /* ORDER TM */
32 "__index", "__newindex",
33 "__gc", "__mode", "__eq",
34 "__add", "__sub", "__mul", "__div", "__mod",
35 "__pow", "__unm", "__len", "__lt", "__le",
36 "__concat", "__call"
37 };
38 int i;
39 for (i=0; i<TM_N; i++) {
40 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
41 luaS_fix(G(L)->tmname[i]); /* never collect these names */
42 }
43}
44
45
46/*
47** function to be used with macro "fasttm": optimized for absence of
48** tag methods
49*/
50const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
51 const TValue *tm = luaH_getstr(events, ename);
52 lua_assert(event <= TM_EQ);
53 if (ttisnil(tm)) { /* no tag method? */
54 events->flags |= cast_byte(1u<<event); /* cache this fact */
55 return NULL;
56 }
57 else return tm;
58}
59
60
61const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
62 Table *mt;
63 switch (ttype(o)) {
64 case LUA_TTABLE:
65 mt = hvalue(o)->metatable;
66 break;
67 case LUA_TUSERDATA:
68 mt = uvalue(o)->metatable;
69 break;
70 default:
71 mt = G(L)->mt[ttype(o)];
72 }
73 return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
74}
75
diff --git a/libraries/LuaJIT-1.1.7/src/ltm.h b/libraries/LuaJIT-1.1.7/src/ltm.h
new file mode 100644
index 0000000..64343b7
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ltm.h
@@ -0,0 +1,54 @@
1/*
2** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $
3** Tag methods
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltm_h
8#define ltm_h
9
10
11#include "lobject.h"
12
13
14/*
15* WARNING: if you change the order of this enumeration,
16* grep "ORDER TM"
17*/
18typedef enum {
19 TM_INDEX,
20 TM_NEWINDEX,
21 TM_GC,
22 TM_MODE,
23 TM_EQ, /* last tag method with `fast' access */
24 TM_ADD,
25 TM_SUB,
26 TM_MUL,
27 TM_DIV,
28 TM_MOD,
29 TM_POW,
30 TM_UNM,
31 TM_LEN,
32 TM_LT,
33 TM_LE,
34 TM_CONCAT,
35 TM_CALL,
36 TM_N /* number of elements in the enum */
37} TMS;
38
39
40
41#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
42 ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
43
44#define fasttm(l,et,e) gfasttm(G(l), et, e)
45
46LUAI_DATA const char *const luaT_typenames[];
47
48
49LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
50LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
51 TMS event);
52LUAI_FUNC void luaT_init (lua_State *L);
53
54#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lua.c b/libraries/LuaJIT-1.1.7/src/lua.c
new file mode 100644
index 0000000..a4b413f
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lua.c
@@ -0,0 +1,463 @@
1/*
2** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $
3** Lua stand-alone interpreter
4** See Copyright Notice in lua.h
5*/
6
7
8#include <signal.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define lua_c
14
15#include "lua.h"
16
17#include "lauxlib.h"
18#include "lualib.h"
19#include "luajit.h"
20
21
22
23static lua_State *globalL = NULL;
24
25static const char *progname = LUA_PROGNAME;
26
27
28
29static void lstop (lua_State *L, lua_Debug *ar) {
30 (void)ar; /* unused arg. */
31 lua_sethook(L, NULL, 0, 0);
32 luaL_error(L, "interrupted!");
33}
34
35
36static void laction (int i) {
37 signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
38 terminate process (default action) */
39 lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
40}
41
42
43static void print_usage (void) {
44 fprintf(stderr,
45 "usage: %s [options] [script [args]].\n"
46 "Available options are:\n"
47 " -e stat execute string " LUA_QL("stat") "\n"
48 " -l name require library " LUA_QL("name") "\n"
49 " -j cmd perform LuaJIT control command\n"
50 " -O[lvl] set LuaJIT optimization level\n"
51 " -i enter interactive mode after executing " LUA_QL("script") "\n"
52 " -v show version information\n"
53 " -- stop handling options\n"
54 " - execute stdin and stop handling options\n"
55 ,
56 progname);
57 fflush(stderr);
58}
59
60
61static void l_message (const char *pname, const char *msg) {
62 if (pname) fprintf(stderr, "%s: ", pname);
63 fprintf(stderr, "%s\n", msg);
64 fflush(stderr);
65}
66
67
68static int report (lua_State *L, int status) {
69 if (status && !lua_isnil(L, -1)) {
70 const char *msg = lua_tostring(L, -1);
71 if (msg == NULL) msg = "(error object is not a string)";
72 l_message(progname, msg);
73 lua_pop(L, 1);
74 }
75 return status;
76}
77
78
79static int traceback (lua_State *L) {
80 if (!lua_isstring(L, 1)) /* 'message' not a string? */
81 return 1; /* keep it intact */
82 lua_getfield(L, LUA_GLOBALSINDEX, "debug");
83 if (!lua_istable(L, -1)) {
84 lua_pop(L, 1);
85 return 1;
86 }
87 lua_getfield(L, -1, "traceback");
88 if (!lua_isfunction(L, -1)) {
89 lua_pop(L, 2);
90 return 1;
91 }
92 lua_pushvalue(L, 1); /* pass error message */
93 lua_pushinteger(L, 2); /* skip this function and traceback */
94 lua_call(L, 2, 1); /* call debug.traceback */
95 return 1;
96}
97
98
99static int docall (lua_State *L, int narg, int clear) {
100 int status;
101 int base = lua_gettop(L) - narg; /* function index */
102 lua_pushcfunction(L, traceback); /* push traceback function */
103 lua_insert(L, base); /* put it under chunk and args */
104 signal(SIGINT, laction);
105 status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
106 signal(SIGINT, SIG_DFL);
107 lua_remove(L, base); /* remove traceback function */
108 /* force a complete garbage collection in case of errors */
109 if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
110 return status;
111}
112
113
114static void print_version (void) {
115 l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT);
116 l_message(NULL, LUAJIT_VERSION " " LUAJIT_COPYRIGHT ", " LUAJIT_URL);
117}
118
119
120static int getargs (lua_State *L, char **argv, int n) {
121 int narg;
122 int i;
123 int argc = 0;
124 while (argv[argc]) argc++; /* count total number of arguments */
125 narg = argc - (n + 1); /* number of arguments to the script */
126 luaL_checkstack(L, narg + 3, "too many arguments to script");
127 for (i=n+1; i < argc; i++)
128 lua_pushstring(L, argv[i]);
129 lua_createtable(L, narg, n + 1);
130 for (i=0; i < argc; i++) {
131 lua_pushstring(L, argv[i]);
132 lua_rawseti(L, -2, i - n);
133 }
134 return narg;
135}
136
137
138static int dofile (lua_State *L, const char *name) {
139 int status = luaL_loadfile(L, name) || docall(L, 0, 1);
140 return report(L, status);
141}
142
143
144static int dostring (lua_State *L, const char *s, const char *name) {
145 int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
146 return report(L, status);
147}
148
149
150static int dolibrary (lua_State *L, const char *name) {
151 lua_getglobal(L, "require");
152 lua_pushstring(L, name);
153 return report(L, docall(L, 1, 1));
154}
155
156
157static const char *get_prompt (lua_State *L, int firstline) {
158 const char *p;
159 lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
160 p = lua_tostring(L, -1);
161 if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
162 lua_pop(L, 1); /* remove global */
163 return p;
164}
165
166
167static int incomplete (lua_State *L, int status) {
168 if (status == LUA_ERRSYNTAX) {
169 size_t lmsg;
170 const char *msg = lua_tolstring(L, -1, &lmsg);
171 const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
172 if (strstr(msg, LUA_QL("<eof>")) == tp) {
173 lua_pop(L, 1);
174 return 1;
175 }
176 }
177 return 0; /* else... */
178}
179
180
181static int pushline (lua_State *L, int firstline) {
182 char buffer[LUA_MAXINPUT];
183 char *b = buffer;
184 size_t l;
185 const char *prmt = get_prompt(L, firstline);
186 if (lua_readline(L, b, prmt) == 0)
187 return 0; /* no input */
188 l = strlen(b);
189 if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
190 b[l-1] = '\0'; /* remove it */
191 if (firstline && b[0] == '=') /* first line starts with `=' ? */
192 lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
193 else
194 lua_pushstring(L, b);
195 lua_freeline(L, b);
196 return 1;
197}
198
199
200static int loadline (lua_State *L) {
201 int status;
202 lua_settop(L, 0);
203 if (!pushline(L, 1))
204 return -1; /* no input */
205 for (;;) { /* repeat until gets a complete line */
206 status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
207 if (!incomplete(L, status)) break; /* cannot try to add lines? */
208 if (!pushline(L, 0)) /* no more input? */
209 return -1;
210 lua_pushliteral(L, "\n"); /* add a new line... */
211 lua_insert(L, -2); /* ...between the two lines */
212 lua_concat(L, 3); /* join them */
213 }
214 lua_saveline(L, 1);
215 lua_remove(L, 1); /* remove line */
216 return status;
217}
218
219
220static void dotty (lua_State *L) {
221 int status;
222 const char *oldprogname = progname;
223 progname = NULL;
224 while ((status = loadline(L)) != -1) {
225 if (status == 0) status = docall(L, 0, 0);
226 report(L, status);
227 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
228 lua_getglobal(L, "print");
229 lua_insert(L, 1);
230 if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
231 l_message(progname, lua_pushfstring(L,
232 "error calling " LUA_QL("print") " (%s)",
233 lua_tostring(L, -1)));
234 }
235 }
236 lua_settop(L, 0); /* clear stack */
237 fputs("\n", stdout);
238 fflush(stdout);
239 progname = oldprogname;
240}
241
242
243static int handle_script (lua_State *L, char **argv, int n) {
244 int status;
245 const char *fname;
246 int narg = getargs(L, argv, n); /* collect arguments */
247 lua_setglobal(L, "arg");
248 fname = argv[n];
249 if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
250 fname = NULL; /* stdin */
251 status = luaL_loadfile(L, fname);
252 lua_insert(L, -(narg+1));
253 if (status == 0)
254 status = docall(L, narg, 0);
255 else
256 lua_pop(L, narg);
257 return report(L, status);
258}
259
260/* ---- start of LuaJIT extensions */
261
262static int loadjitmodule (lua_State *L, const char *notfound) {
263 lua_getglobal(L, "require");
264 lua_pushliteral(L, "jit.");
265 lua_pushvalue(L, -3);
266 lua_concat(L, 2);
267 if (lua_pcall(L, 1, 1, 0)) {
268 const char *msg = lua_tostring(L, -1);
269 if (msg && !strncmp(msg, "module ", 7)) {
270 l_message(progname, notfound);
271 return 1;
272 }
273 else
274 return report(L, 1);
275 }
276 lua_getfield(L, -1, "start");
277 lua_remove(L, -2); /* drop module table */
278 return 0;
279}
280
281/* JIT engine control command: try jit library first or load add-on module */
282static int dojitcmd (lua_State *L, const char *cmd) {
283 const char *val = strchr(cmd, '=');
284 lua_pushlstring(L, cmd, val ? val - cmd : strlen(cmd));
285 lua_getglobal(L, "jit"); /* get jit.* table */
286 lua_pushvalue(L, -2);
287 lua_gettable(L, -2); /* lookup library function */
288 if (!lua_isfunction(L, -1)) {
289 lua_pop(L, 2); /* drop non-function and jit.* table, keep module name */
290 if (loadjitmodule(L, "unknown luaJIT command"))
291 return 1;
292 }
293 else {
294 lua_remove(L, -2); /* drop jit.* table */
295 }
296 lua_remove(L, -2); /* drop module name */
297 if (val) lua_pushstring(L, val+1);
298 return report(L, lua_pcall(L, val ? 1 : 0, 0, 0));
299}
300
301/* start optimizer */
302static int dojitopt (lua_State *L, const char *opt) {
303 lua_pushliteral(L, "opt");
304 if (loadjitmodule(L, "LuaJIT optimizer module not installed"))
305 return 1;
306 lua_remove(L, -2); /* drop module name */
307 if (*opt) lua_pushstring(L, opt);
308 return report(L, lua_pcall(L, *opt ? 1 : 0, 0, 0));
309}
310
311/* ---- end of LuaJIT extensions */
312
313/* check that argument has no extra characters at the end */
314#define notail(x) {if ((x)[2] != '\0') return -1;}
315
316
317static int collectargs (char **argv, int *pi, int *pv, int *pe) {
318 int i;
319 for (i = 1; argv[i] != NULL; i++) {
320 if (argv[i][0] != '-') /* not an option? */
321 return i;
322 switch (argv[i][1]) { /* option */
323 case '-':
324 notail(argv[i]);
325 return (argv[i+1] != NULL ? i+1 : 0);
326 case '\0':
327 return i;
328 case 'i':
329 notail(argv[i]);
330 *pi = 1; /* go through */
331 case 'v':
332 notail(argv[i]);
333 *pv = 1;
334 break;
335 case 'e':
336 *pe = 1; /* go through */
337 case 'j': /* LuaJIT extension */
338 case 'l':
339 if (argv[i][2] == '\0') {
340 i++;
341 if (argv[i] == NULL) return -1;
342 }
343 break;
344 case 'O': break; /* LuaJIT extension */
345 default: return -1; /* invalid option */
346 }
347 }
348 return 0;
349}
350
351
352static int runargs (lua_State *L, char **argv, int n) {
353 int i;
354 for (i = 1; i < n; i++) {
355 if (argv[i] == NULL) continue;
356 lua_assert(argv[i][0] == '-');
357 switch (argv[i][1]) { /* option */
358 case 'e': {
359 const char *chunk = argv[i] + 2;
360 if (*chunk == '\0') chunk = argv[++i];
361 lua_assert(chunk != NULL);
362 if (dostring(L, chunk, "=(command line)") != 0)
363 return 1;
364 break;
365 }
366 case 'l': {
367 const char *filename = argv[i] + 2;
368 if (*filename == '\0') filename = argv[++i];
369 lua_assert(filename != NULL);
370 if (dolibrary(L, filename))
371 return 1; /* stop if file fails */
372 break;
373 }
374 case 'j': { /* LuaJIT extension */
375 const char *cmd = argv[i] + 2;
376 if (*cmd == '\0') cmd = argv[++i];
377 lua_assert(cmd != NULL);
378 if (dojitcmd(L, cmd))
379 return 1;
380 break;
381 }
382 case 'O': /* LuaJIT extension */
383 if (dojitopt(L, argv[i] + 2))
384 return 1;
385 break;
386 default: break;
387 }
388 }
389 return 0;
390}
391
392
393static int handle_luainit (lua_State *L) {
394 const char *init = getenv(LUA_INIT);
395 if (init == NULL) return 0; /* status OK */
396 else if (init[0] == '@')
397 return dofile(L, init+1);
398 else
399 return dostring(L, init, "=" LUA_INIT);
400}
401
402
403struct Smain {
404 int argc;
405 char **argv;
406 int status;
407};
408
409
410static int pmain (lua_State *L) {
411 struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
412 char **argv = s->argv;
413 int script;
414 int has_i = 0, has_v = 0, has_e = 0;
415 globalL = L;
416 if (argv[0] && argv[0][0]) progname = argv[0];
417 LUAJIT_VERSION_SYM(); /* linker-enforced version check */
418 lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
419 luaL_openlibs(L); /* open libraries */
420 lua_gc(L, LUA_GCRESTART, 0);
421 s->status = handle_luainit(L);
422 if (s->status != 0) return 0;
423 script = collectargs(argv, &has_i, &has_v, &has_e);
424 if (script < 0) { /* invalid args? */
425 print_usage();
426 s->status = 1;
427 return 0;
428 }
429 if (has_v) print_version();
430 s->status = runargs(L, argv, (script > 0) ? script : s->argc);
431 if (s->status != 0) return 0;
432 if (script)
433 s->status = handle_script(L, argv, script);
434 if (s->status != 0) return 0;
435 if (has_i)
436 dotty(L);
437 else if (script == 0 && !has_e && !has_v) {
438 if (lua_stdin_is_tty()) {
439 print_version();
440 dotty(L);
441 }
442 else dofile(L, NULL); /* executes stdin as a file */
443 }
444 return 0;
445}
446
447
448int main (int argc, char **argv) {
449 int status;
450 struct Smain s;
451 lua_State *L = lua_open(); /* create state */
452 if (L == NULL) {
453 l_message(argv[0], "cannot create state: not enough memory");
454 return EXIT_FAILURE;
455 }
456 s.argc = argc;
457 s.argv = argv;
458 status = lua_cpcall(L, &pmain, &s);
459 report(L, status);
460 lua_close(L);
461 return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
462}
463
diff --git a/libraries/LuaJIT-1.1.7/src/lua.h b/libraries/LuaJIT-1.1.7/src/lua.h
new file mode 100644
index 0000000..7d6ee45
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lua.h
@@ -0,0 +1,385 @@
1/*
2** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
3** Lua - An Extensible Extension Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file
6*/
7
8
9#ifndef lua_h
10#define lua_h
11
12#include <stdarg.h>
13#include <stddef.h>
14
15
16#include "luaconf.h"
17
18
19#define LUA_VERSION "Lua 5.1"
20#define LUA_RELEASE "Lua 5.1.4"
21#define LUA_VERSION_NUM 501
22#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
23#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
24
25
26/* mark for precompiled code (`<esc>Lua') */
27#define LUA_SIGNATURE "\033Lua"
28
29/* option for multiple returns in `lua_pcall' and `lua_call' */
30#define LUA_MULTRET (-1)
31
32
33/*
34** pseudo-indices
35*/
36#define LUA_REGISTRYINDEX (-10000)
37#define LUA_ENVIRONINDEX (-10001)
38#define LUA_GLOBALSINDEX (-10002)
39#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
40
41
42/* thread status; 0 is OK */
43#define LUA_YIELD 1
44#define LUA_ERRRUN 2
45#define LUA_ERRSYNTAX 3
46#define LUA_ERRMEM 4
47#define LUA_ERRERR 5
48
49
50typedef struct lua_State lua_State;
51
52typedef int (*lua_CFunction) (lua_State *L);
53
54
55/*
56** functions that read/write blocks when loading/dumping Lua chunks
57*/
58typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
59
60typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
61
62
63/*
64** prototype for memory-allocation functions
65*/
66typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
67
68
69/*
70** basic types
71*/
72#define LUA_TNONE (-1)
73
74#define LUA_TNIL 0
75#define LUA_TBOOLEAN 1
76#define LUA_TLIGHTUSERDATA 2
77#define LUA_TNUMBER 3
78#define LUA_TSTRING 4
79#define LUA_TTABLE 5
80#define LUA_TFUNCTION 6
81#define LUA_TUSERDATA 7
82#define LUA_TTHREAD 8
83
84
85
86/* minimum Lua stack available to a C function */
87#define LUA_MINSTACK 20
88
89
90/*
91** generic extra include file
92*/
93#if defined(LUA_USER_H)
94#include LUA_USER_H
95#endif
96
97
98/* type of numbers in Lua */
99typedef LUA_NUMBER lua_Number;
100
101
102/* type for integer functions */
103typedef LUA_INTEGER lua_Integer;
104
105
106
107/*
108** state manipulation
109*/
110LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
111LUA_API void (lua_close) (lua_State *L);
112LUA_API lua_State *(lua_newthread) (lua_State *L);
113
114LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
115
116
117/*
118** basic stack manipulation
119*/
120LUA_API int (lua_gettop) (lua_State *L);
121LUA_API void (lua_settop) (lua_State *L, int idx);
122LUA_API void (lua_pushvalue) (lua_State *L, int idx);
123LUA_API void (lua_remove) (lua_State *L, int idx);
124LUA_API void (lua_insert) (lua_State *L, int idx);
125LUA_API void (lua_replace) (lua_State *L, int idx);
126LUA_API int (lua_checkstack) (lua_State *L, int sz);
127
128LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
129
130
131/*
132** access functions (stack -> C)
133*/
134
135LUA_API int (lua_isnumber) (lua_State *L, int idx);
136LUA_API int (lua_isstring) (lua_State *L, int idx);
137LUA_API int (lua_iscfunction) (lua_State *L, int idx);
138LUA_API int (lua_isuserdata) (lua_State *L, int idx);
139LUA_API int (lua_type) (lua_State *L, int idx);
140LUA_API const char *(lua_typename) (lua_State *L, int tp);
141
142LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
143LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
144LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
145
146LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
147LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
148LUA_API int (lua_toboolean) (lua_State *L, int idx);
149LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
150LUA_API size_t (lua_objlen) (lua_State *L, int idx);
151LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
152LUA_API void *(lua_touserdata) (lua_State *L, int idx);
153LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
154LUA_API const void *(lua_topointer) (lua_State *L, int idx);
155
156
157/*
158** push functions (C -> stack)
159*/
160LUA_API void (lua_pushnil) (lua_State *L);
161LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
162LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
163LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
164LUA_API void (lua_pushstring) (lua_State *L, const char *s);
165LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
166 va_list argp);
167LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
168LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
169LUA_API void (lua_pushboolean) (lua_State *L, int b);
170LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
171LUA_API int (lua_pushthread) (lua_State *L);
172
173
174/*
175** get functions (Lua -> stack)
176*/
177LUA_API void (lua_gettable) (lua_State *L, int idx);
178LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
179LUA_API void (lua_rawget) (lua_State *L, int idx);
180LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
181LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
182LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
183LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
184LUA_API void (lua_getfenv) (lua_State *L, int idx);
185
186
187/*
188** set functions (stack -> Lua)
189*/
190LUA_API void (lua_settable) (lua_State *L, int idx);
191LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
192LUA_API void (lua_rawset) (lua_State *L, int idx);
193LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
194LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
195LUA_API int (lua_setfenv) (lua_State *L, int idx);
196
197
198/*
199** `load' and `call' functions (load and run Lua code)
200*/
201LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
202LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
203LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
204LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
205 const char *chunkname);
206
207LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
208
209
210/*
211** coroutine functions
212*/
213LUA_API int (lua_yield) (lua_State *L, int nresults);
214LUA_API int (lua_resume) (lua_State *L, int narg);
215LUA_API int (lua_status) (lua_State *L);
216
217/*
218** garbage-collection function and options
219*/
220
221#define LUA_GCSTOP 0
222#define LUA_GCRESTART 1
223#define LUA_GCCOLLECT 2
224#define LUA_GCCOUNT 3
225#define LUA_GCCOUNTB 4
226#define LUA_GCSTEP 5
227#define LUA_GCSETPAUSE 6
228#define LUA_GCSETSTEPMUL 7
229
230LUA_API int (lua_gc) (lua_State *L, int what, int data);
231
232
233/*
234** miscellaneous functions
235*/
236
237LUA_API int (lua_error) (lua_State *L);
238
239LUA_API int (lua_next) (lua_State *L, int idx);
240
241LUA_API void (lua_concat) (lua_State *L, int n);
242
243LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
244LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
245
246
247
248/*
249** ===============================================================
250** some useful macros
251** ===============================================================
252*/
253
254#define lua_pop(L,n) lua_settop(L, -(n)-1)
255
256#define lua_newtable(L) lua_createtable(L, 0, 0)
257
258#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
259
260#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
261
262#define lua_strlen(L,i) lua_objlen(L, (i))
263
264#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
265#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
266#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
267#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
268#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
269#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
270#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
271#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
272
273#define lua_pushliteral(L, s) \
274 lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
275
276#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
277#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
278
279#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
280
281
282
283/*
284** compatibility macros and functions
285*/
286
287#define lua_open() luaL_newstate()
288
289#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
290
291#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
292
293#define lua_Chunkreader lua_Reader
294#define lua_Chunkwriter lua_Writer
295
296
297
298/*
299** {======================================================================
300** Debug API
301** =======================================================================
302*/
303
304
305/*
306** Event codes
307*/
308#define LUA_HOOKCALL 0
309#define LUA_HOOKRET 1
310#define LUA_HOOKLINE 2
311#define LUA_HOOKCOUNT 3
312#define LUA_HOOKTAILRET 4
313
314
315/*
316** Event masks
317*/
318#define LUA_MASKCALL (1 << LUA_HOOKCALL)
319#define LUA_MASKRET (1 << LUA_HOOKRET)
320#define LUA_MASKLINE (1 << LUA_HOOKLINE)
321#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
322
323typedef struct lua_Debug lua_Debug; /* activation record */
324
325
326/* Functions to be called by the debuger in specific events */
327typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
328
329
330LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
331LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
332LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
333LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
334LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
335LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
336
337LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
338LUA_API lua_Hook lua_gethook (lua_State *L);
339LUA_API int lua_gethookmask (lua_State *L);
340LUA_API int lua_gethookcount (lua_State *L);
341
342
343struct lua_Debug {
344 int event;
345 const char *name; /* (n) */
346 const char *namewhat; /* (n) `global', `local', `field', `method' */
347 const char *what; /* (S) `Lua', `C', `main', `tail' */
348 const char *source; /* (S) */
349 int currentline; /* (l) */
350 int nups; /* (u) number of upvalues */
351 int linedefined; /* (S) */
352 int lastlinedefined; /* (S) */
353 char short_src[LUA_IDSIZE]; /* (S) */
354 /* private part */
355 int i_ci; /* active function */
356};
357
358/* }====================================================================== */
359
360
361/******************************************************************************
362* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
363*
364* Permission is hereby granted, free of charge, to any person obtaining
365* a copy of this software and associated documentation files (the
366* "Software"), to deal in the Software without restriction, including
367* without limitation the rights to use, copy, modify, merge, publish,
368* distribute, sublicense, and/or sell copies of the Software, and to
369* permit persons to whom the Software is furnished to do so, subject to
370* the following conditions:
371*
372* The above copyright notice and this permission notice shall be
373* included in all copies or substantial portions of the Software.
374*
375* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
376* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
377* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
378* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
379* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
380* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
381* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
382******************************************************************************/
383
384
385#endif
diff --git a/libraries/LuaJIT-1.1.7/src/luac.c b/libraries/LuaJIT-1.1.7/src/luac.c
new file mode 100644
index 0000000..d070173
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/luac.c
@@ -0,0 +1,200 @@
1/*
2** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $
3** Lua compiler (saves bytecodes to files; also list bytecodes)
4** See Copyright Notice in lua.h
5*/
6
7#include <errno.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define luac_c
13#define LUA_CORE
14
15#include "lua.h"
16#include "lauxlib.h"
17
18#include "ldo.h"
19#include "lfunc.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lstring.h"
24#include "lundump.h"
25
26#define PROGNAME "luac" /* default program name */
27#define OUTPUT PROGNAME ".out" /* default output file */
28
29static int listing=0; /* list bytecodes? */
30static int dumping=1; /* dump bytecodes? */
31static int stripping=0; /* strip debug information? */
32static char Output[]={ OUTPUT }; /* default output file name */
33static const char* output=Output; /* actual output file name */
34static const char* progname=PROGNAME; /* actual program name */
35
36static void fatal(const char* message)
37{
38 fprintf(stderr,"%s: %s\n",progname,message);
39 exit(EXIT_FAILURE);
40}
41
42static void cannot(const char* what)
43{
44 fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
45 exit(EXIT_FAILURE);
46}
47
48static void usage(const char* message)
49{
50 if (*message=='-')
51 fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
52 else
53 fprintf(stderr,"%s: %s\n",progname,message);
54 fprintf(stderr,
55 "usage: %s [options] [filenames].\n"
56 "Available options are:\n"
57 " - process stdin\n"
58 " -l list\n"
59 " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
60 " -p parse only\n"
61 " -s strip debug information\n"
62 " -v show version information\n"
63 " -- stop handling options\n",
64 progname,Output);
65 exit(EXIT_FAILURE);
66}
67
68#define IS(s) (strcmp(argv[i],s)==0)
69
70static int doargs(int argc, char* argv[])
71{
72 int i;
73 int version=0;
74 if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
75 for (i=1; i<argc; i++)
76 {
77 if (*argv[i]!='-') /* end of options; keep it */
78 break;
79 else if (IS("--")) /* end of options; skip it */
80 {
81 ++i;
82 if (version) ++version;
83 break;
84 }
85 else if (IS("-")) /* end of options; use stdin */
86 break;
87 else if (IS("-l")) /* list */
88 ++listing;
89 else if (IS("-o")) /* output file */
90 {
91 output=argv[++i];
92 if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument");
93 if (IS("-")) output=NULL;
94 }
95 else if (IS("-p")) /* parse only */
96 dumping=0;
97 else if (IS("-s")) /* strip debug information */
98 stripping=1;
99 else if (IS("-v")) /* show version */
100 ++version;
101 else /* unknown option */
102 usage(argv[i]);
103 }
104 if (i==argc && (listing || !dumping))
105 {
106 dumping=0;
107 argv[--i]=Output;
108 }
109 if (version)
110 {
111 printf("%s %s\n",LUA_RELEASE,LUA_COPYRIGHT);
112 if (version==argc-1) exit(EXIT_SUCCESS);
113 }
114 return i;
115}
116
117#define toproto(L,i) (clvalue(L->top+(i))->l.p)
118
119static const Proto* combine(lua_State* L, int n)
120{
121 if (n==1)
122 return toproto(L,-1);
123 else
124 {
125 int i,pc;
126 Proto* f=luaF_newproto(L);
127 setptvalue2s(L,L->top,f); incr_top(L);
128 f->source=luaS_newliteral(L,"=(" PROGNAME ")");
129 f->maxstacksize=1;
130 pc=2*n+1;
131 f->code=luaM_newvector(L,pc,Instruction);
132 f->sizecode=pc;
133 f->p=luaM_newvector(L,n,Proto*);
134 f->sizep=n;
135 pc=0;
136 for (i=0; i<n; i++)
137 {
138 f->p[i]=toproto(L,i-n-1);
139 f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i);
140 f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);
141 }
142 f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0);
143 return f;
144 }
145}
146
147static int writer(lua_State* L, const void* p, size_t size, void* u)
148{
149 UNUSED(L);
150 return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
151}
152
153struct Smain {
154 int argc;
155 char** argv;
156};
157
158static int pmain(lua_State* L)
159{
160 struct Smain* s = (struct Smain*)lua_touserdata(L, 1);
161 int argc=s->argc;
162 char** argv=s->argv;
163 const Proto* f;
164 int i;
165 if (!lua_checkstack(L,argc)) fatal("too many input files");
166 for (i=0; i<argc; i++)
167 {
168 const char* filename=IS("-") ? NULL : argv[i];
169 if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
170 }
171 f=combine(L,argc);
172 if (listing) luaU_print(f,listing>1);
173 if (dumping)
174 {
175 FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
176 if (D==NULL) cannot("open");
177 lua_lock(L);
178 luaU_dump(L,f,writer,D,stripping);
179 lua_unlock(L);
180 if (ferror(D)) cannot("write");
181 if (fclose(D)) cannot("close");
182 }
183 return 0;
184}
185
186int main(int argc, char* argv[])
187{
188 lua_State* L;
189 struct Smain s;
190 int i=doargs(argc,argv);
191 argc-=i; argv+=i;
192 if (argc<=0) usage("no input files given");
193 L=lua_open();
194 if (L==NULL) fatal("not enough memory for state");
195 s.argc=argc;
196 s.argv=argv;
197 if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1));
198 lua_close(L);
199 return EXIT_SUCCESS;
200}
diff --git a/libraries/LuaJIT-1.1.7/src/luaconf.h b/libraries/LuaJIT-1.1.7/src/luaconf.h
new file mode 100644
index 0000000..35a6bd1
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/luaconf.h
@@ -0,0 +1,786 @@
1/*
2** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $
3** Configuration file for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lconfig_h
9#define lconfig_h
10
11#include <limits.h>
12#include <stddef.h>
13
14
15/*
16** ==================================================================
17** Search for "@@" to find all configurable definitions.
18** ===================================================================
19*/
20
21
22/*
23@@ LUA_ANSI controls the use of non-ansi features.
24** CHANGE it (define it) if you want Lua to avoid the use of any
25** non-ansi feature or library.
26*/
27#if defined(__STRICT_ANSI__)
28#define LUA_ANSI
29#endif
30
31
32#if !defined(LUA_ANSI) && defined(_WIN32)
33#define LUA_WIN
34#endif
35
36#if defined(LUA_USE_LINUX)
37#define LUA_USE_POSIX
38#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
39/* #define LUA_USE_READLINE */ /* needs some extra libraries */
40#endif
41
42#if defined(LUA_USE_MACOSX)
43#define LUA_USE_POSIX
44#define LUA_DL_DYLD /* does not need extra library */
45#endif
46
47
48
49/*
50@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
51@* Interfaces Extension (XSI).
52** CHANGE it (define it) if your system is XSI compatible.
53*/
54#if defined(LUA_USE_POSIX)
55#define LUA_USE_MKSTEMP
56#define LUA_USE_ISATTY
57#define LUA_USE_POPEN
58#define LUA_USE_ULONGJMP
59#endif
60
61
62/*
63@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
64@* Lua check to set its paths.
65@@ LUA_INIT is the name of the environment variable that Lua
66@* checks for initialization code.
67** CHANGE them if you want different names.
68*/
69#define LUA_PATH "LUA_PATH"
70#define LUA_CPATH "LUA_CPATH"
71#define LUA_INIT "LUA_INIT"
72
73
74/*
75@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
76@* Lua libraries.
77@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
78@* C libraries.
79** CHANGE them if your machine has a non-conventional directory
80** hierarchy or if you want to install your libraries in
81** non-conventional directories.
82*/
83#if defined(_WIN32)
84/*
85** In Windows, any exclamation mark ('!') in the path is replaced by the
86** path of the directory of the executable file of the current process.
87*/
88#define LUA_LDIR "!\\lua\\"
89#define LUA_CDIR "!\\"
90#define LUA_PATH_DEFAULT \
91 ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
92 LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
93#define LUA_CPATH_DEFAULT \
94 ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
95
96#else
97#define LUA_ROOT "/usr/local/"
98#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
99#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
100#define LUA_PATH_DEFAULT \
101 "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
102 LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
103#define LUA_CPATH_DEFAULT \
104 "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
105#endif
106
107
108/*
109@@ LUA_DIRSEP is the directory separator (for submodules).
110** CHANGE it if your machine does not use "/" as the directory separator
111** and is not Windows. (On Windows Lua automatically uses "\".)
112*/
113#if defined(_WIN32)
114#define LUA_DIRSEP "\\"
115#else
116#define LUA_DIRSEP "/"
117#endif
118
119
120/*
121@@ LUA_PATHSEP is the character that separates templates in a path.
122@@ LUA_PATH_MARK is the string that marks the substitution points in a
123@* template.
124@@ LUA_EXECDIR in a Windows path is replaced by the executable's
125@* directory.
126@@ LUA_IGMARK is a mark to ignore all before it when bulding the
127@* luaopen_ function name.
128** CHANGE them if for some reason your system cannot use those
129** characters. (E.g., if one of those characters is a common character
130** in file/directory names.) Probably you do not need to change them.
131*/
132#define LUA_PATHSEP ";"
133#define LUA_PATH_MARK "?"
134#define LUA_EXECDIR "!"
135#define LUA_IGMARK "-"
136
137
138/*
139@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
140** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
141** machines, ptrdiff_t gives a good choice between int or long.)
142*/
143#define LUA_INTEGER ptrdiff_t
144
145
146/*
147@@ LUA_API is a mark for all core API functions.
148@@ LUALIB_API is a mark for all standard library functions.
149** CHANGE them if you need to define those functions in some special way.
150** For instance, if you want to create one Windows DLL with the core and
151** the libraries, you may want to use the following definition (define
152** LUA_BUILD_AS_DLL to get it).
153*/
154#if defined(LUA_BUILD_AS_DLL)
155
156#if defined(LUA_CORE) || defined(LUA_LIB)
157#define LUA_API __declspec(dllexport)
158#else
159#define LUA_API __declspec(dllimport)
160#endif
161
162#else
163
164#define LUA_API extern
165
166#endif
167
168/* more often than not the libs go together with the core */
169#define LUALIB_API LUA_API
170
171
172/*
173@@ LUAI_FUNC is a mark for all extern functions that are not to be
174@* exported to outside modules.
175@@ LUAI_DATA is a mark for all extern (const) variables that are not to
176@* be exported to outside modules.
177** CHANGE them if you need to mark them in some special way. Elf/gcc
178** (versions 3.2 and later) mark them as "hidden" to optimize access
179** when Lua is compiled as a shared library.
180*/
181#if defined(luaall_c)
182#define LUAI_FUNC static
183#define LUAI_DATA /* empty */
184
185#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
186 defined(__ELF__)
187#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
188#define LUAI_DATA LUAI_FUNC
189
190#else
191#define LUAI_FUNC extern
192#define LUAI_DATA extern
193#endif
194
195
196
197/*
198@@ LUA_QL describes how error messages quote program elements.
199** CHANGE it if you want a different appearance.
200*/
201#define LUA_QL(x) "'" x "'"
202#define LUA_QS LUA_QL("%s")
203
204
205/*
206@@ LUA_IDSIZE gives the maximum size for the description of the source
207@* of a function in debug information.
208** CHANGE it if you want a different size.
209*/
210#define LUA_IDSIZE 60
211
212
213/*
214** {==================================================================
215** Stand-alone configuration
216** ===================================================================
217*/
218
219#if defined(lua_c) || defined(luaall_c)
220
221/*
222@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
223@* is, whether we're running lua interactively).
224** CHANGE it if you have a better definition for non-POSIX/non-Windows
225** systems.
226*/
227#if defined(LUA_USE_ISATTY)
228#include <unistd.h>
229#define lua_stdin_is_tty() isatty(0)
230#elif defined(LUA_WIN)
231#include <io.h>
232#include <stdio.h>
233#define lua_stdin_is_tty() _isatty(_fileno(stdin))
234#else
235#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
236#endif
237
238
239/*
240@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
241@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
242** CHANGE them if you want different prompts. (You can also change the
243** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
244*/
245#define LUA_PROMPT "> "
246#define LUA_PROMPT2 ">> "
247
248
249/*
250@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
251** CHANGE it if your stand-alone interpreter has a different name and
252** your system is not able to detect that name automatically.
253*/
254#define LUA_PROGNAME "luajit"
255
256
257/*
258@@ LUA_MAXINPUT is the maximum length for an input line in the
259@* stand-alone interpreter.
260** CHANGE it if you need longer lines.
261*/
262#define LUA_MAXINPUT 512
263
264
265/*
266@@ lua_readline defines how to show a prompt and then read a line from
267@* the standard input.
268@@ lua_saveline defines how to "save" a read line in a "history".
269@@ lua_freeline defines how to free a line read by lua_readline.
270** CHANGE them if you want to improve this functionality (e.g., by using
271** GNU readline and history facilities).
272*/
273#if defined(LUA_USE_READLINE)
274#include <stdio.h>
275#include <readline/readline.h>
276#include <readline/history.h>
277#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
278#define lua_saveline(L,idx) \
279 if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
280 add_history(lua_tostring(L, idx)); /* add it to history */
281#define lua_freeline(L,b) ((void)L, free(b))
282#else
283#define lua_readline(L,b,p) \
284 ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
285 fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
286#define lua_saveline(L,idx) { (void)L; (void)idx; }
287#define lua_freeline(L,b) { (void)L; (void)b; }
288#endif
289
290#endif
291
292/* }================================================================== */
293
294
295/*
296@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
297@* as a percentage.
298** CHANGE it if you want the GC to run faster or slower (higher values
299** mean larger pauses which mean slower collection.) You can also change
300** this value dynamically.
301*/
302#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
303
304
305/*
306@@ LUAI_GCMUL defines the default speed of garbage collection relative to
307@* memory allocation as a percentage.
308** CHANGE it if you want to change the granularity of the garbage
309** collection. (Higher values mean coarser collections. 0 represents
310** infinity, where each step performs a full collection.) You can also
311** change this value dynamically.
312*/
313#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
314
315
316
317/*
318@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
319** CHANGE it (define it) if you want exact compatibility with the
320** behavior of setn/getn in Lua 5.0.
321**
322** Note: this is not supported by LuaJIT. Leave it undefined.
323*/
324#undef LUA_COMPAT_GETN
325
326/*
327@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
328** CHANGE it to undefined as soon as you do not need a global 'loadlib'
329** function (the function is still available as 'package.loadlib').
330*/
331#undef LUA_COMPAT_LOADLIB
332
333/*
334@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
335** CHANGE it to undefined as soon as your programs use only '...' to
336** access vararg parameters (instead of the old 'arg' table).
337**
338** Note: this has a slightly negative performance impact with LuaJIT
339** for all vararg functions. Leave it off if possible and upgrade your
340** code (replace unpack(arg) with ... and/or add local arg = {...}).
341*/
342#undef LUA_COMPAT_VARARG
343
344/*
345@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
346** CHANGE it to undefined as soon as your programs use 'math.fmod' or
347** the new '%' operator instead of 'math.mod'.
348*/
349#define LUA_COMPAT_MOD
350
351/*
352@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
353@* facility.
354** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
355** off the advisory error when nesting [[...]].
356*/
357#define LUA_COMPAT_LSTR 1
358
359/*
360@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
361** CHANGE it to undefined as soon as you rename 'string.gfind' to
362** 'string.gmatch'.
363*/
364#define LUA_COMPAT_GFIND
365
366/*
367@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
368@* behavior.
369** CHANGE it to undefined as soon as you replace to 'luaL_register'
370** your uses of 'luaL_openlib'
371*/
372#define LUA_COMPAT_OPENLIB
373
374
375
376/*
377@@ luai_apicheck is the assert macro used by the Lua-C API.
378** CHANGE luai_apicheck if you want Lua to perform some checks in the
379** parameters it gets from API calls. This may slow down the interpreter
380** a bit, but may be quite useful when debugging C code that interfaces
381** with Lua. A useful redefinition is to use assert.h.
382*/
383#if defined(LUA_USE_APICHECK)
384#include <assert.h>
385#define luai_apicheck(L,o) { (void)L; assert(o); }
386#else
387#define luai_apicheck(L,o) { (void)L; }
388#endif
389
390
391/*
392@@ LUAI_BITSINT defines the number of bits in an int.
393** CHANGE here if Lua cannot automatically detect the number of bits of
394** your machine. Probably you do not need to change this.
395*/
396/* avoid overflows in comparison */
397#if INT_MAX-20 < 32760
398#define LUAI_BITSINT 16
399#elif INT_MAX > 2147483640L
400/* int has at least 32 bits */
401#define LUAI_BITSINT 32
402#else
403#error "you must define LUA_BITSINT with number of bits in an integer"
404#endif
405
406
407/*
408@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
409@@ LUAI_INT32 is an signed integer with at least 32 bits.
410@@ LUAI_UMEM is an unsigned integer big enough to count the total
411@* memory used by Lua.
412@@ LUAI_MEM is a signed integer big enough to count the total memory
413@* used by Lua.
414** CHANGE here if for some weird reason the default definitions are not
415** good enough for your machine. (The definitions in the 'else'
416** part always works, but may waste space on machines with 64-bit
417** longs.) Probably you do not need to change this.
418*/
419#if LUAI_BITSINT >= 32
420#define LUAI_UINT32 unsigned int
421#define LUAI_INT32 int
422#define LUAI_MAXINT32 INT_MAX
423#define LUAI_UMEM size_t
424#define LUAI_MEM ptrdiff_t
425#else
426/* 16-bit ints */
427#define LUAI_UINT32 unsigned long
428#define LUAI_INT32 long
429#define LUAI_MAXINT32 LONG_MAX
430#define LUAI_UMEM unsigned long
431#define LUAI_MEM long
432#endif
433
434
435/*
436@@ LUAI_MAXCALLS limits the number of nested calls.
437** CHANGE it if you need really deep recursive calls. This limit is
438** arbitrary; its only purpose is to stop infinite recursion before
439** exhausting memory.
440*/
441#define LUAI_MAXCALLS 20000
442
443
444/*
445@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
446@* can use.
447** CHANGE it if you need lots of (Lua) stack space for your C
448** functions. This limit is arbitrary; its only purpose is to stop C
449** functions to consume unlimited stack space. (must be smaller than
450** -LUA_REGISTRYINDEX)
451*/
452#define LUAI_MAXCSTACK 8000
453
454
455/*
456** {==================================================================
457** CHANGE (to smaller values) the following definitions if your system
458** has a small C stack. (Or you may want to change them to larger
459** values if your system has a large C stack and these limits are
460** too rigid for you.) Some of these constants control the size of
461** stack-allocated arrays used by the compiler or the interpreter, while
462** others limit the maximum number of recursive calls that the compiler
463** or the interpreter can perform. Values too large may cause a C stack
464** overflow for some forms of deep constructs.
465** ===================================================================
466*/
467
468
469/*
470@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
471@* syntactical nested non-terminals in a program.
472*/
473#define LUAI_MAXCCALLS 200
474
475
476/*
477@@ LUAI_MAXVARS is the maximum number of local variables per function
478@* (must be smaller than 250).
479*/
480#define LUAI_MAXVARS 200
481
482
483/*
484@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
485@* (must be smaller than 250).
486*/
487#define LUAI_MAXUPVALUES 60
488
489
490/*
491@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
492*/
493#define LUAL_BUFFERSIZE BUFSIZ
494
495/* }================================================================== */
496
497
498
499
500/*
501** {==================================================================
502@@ LUA_NUMBER is the type of numbers in Lua.
503** CHANGE the following definitions only if you want to build Lua
504** with a number type different from double. You may also need to
505** change lua_number2int & lua_number2integer.
506** ===================================================================
507*/
508
509#define LUA_NUMBER_DOUBLE
510#define LUA_NUMBER double
511
512/*
513@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
514@* over a number.
515*/
516#define LUAI_UACNUMBER double
517
518
519/*
520@@ LUA_NUMBER_SCAN is the format for reading numbers.
521@@ LUA_NUMBER_FMT is the format for writing numbers.
522@@ lua_number2str converts a number to a string.
523@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
524@@ lua_str2number converts a string to a number.
525*/
526#define LUA_NUMBER_SCAN "%lf"
527#define LUA_NUMBER_FMT "%.14g"
528#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
529#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
530#define lua_str2number(s,p) strtod((s), (p))
531
532
533/*
534@@ The luai_num* macros define the primitive operations over numbers.
535*/
536#if defined(LUA_CORE)
537#include <math.h>
538#define luai_numadd(a,b) ((a)+(b))
539#define luai_numsub(a,b) ((a)-(b))
540#define luai_nummul(a,b) ((a)*(b))
541#define luai_numdiv(a,b) ((a)/(b))
542#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
543#define luai_numpow(a,b) (pow(a,b))
544#define luai_numunm(a) (-(a))
545#define luai_numeq(a,b) ((a)==(b))
546#define luai_numlt(a,b) ((a)<(b))
547#define luai_numle(a,b) ((a)<=(b))
548#define luai_numisnan(a) (!luai_numeq((a), (a)))
549#endif
550
551
552/*
553@@ lua_number2int is a macro to convert lua_Number to int.
554@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
555** CHANGE them if you know a faster way to convert a lua_Number to
556** int (with any rounding method and without throwing errors) in your
557** system. In Pentium machines, a naive typecast from double to int
558** in C is extremely slow, so any alternative is worth trying.
559*/
560
561/* On a Pentium, resort to a trick */
562#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
563 (defined(__i386) || defined (_M_IX86) || defined(__i386__))
564
565/* On a Microsoft compiler, use assembler */
566#if defined(_MSC_VER)
567
568#define lua_number2int(i,d) __asm fld d __asm fistp i
569#define lua_number2integer(i,n) lua_number2int(i, n)
570
571/* the next trick should work on any Pentium, but sometimes clashes
572 with a DirectX idiosyncrasy */
573#else
574
575union luai_Cast { double l_d; long l_l; };
576#define lua_number2int(i,d) \
577 { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
578#define lua_number2integer(i,n) lua_number2int(i, n)
579
580#endif
581
582
583/* this option always works, but may be slow */
584#else
585#define lua_number2int(i,d) ((i)=(int)(d))
586#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
587
588#endif
589
590
591/*
592@@ LUA_TVALUE_ALIGN specifies extra alignment constraints for the
593@@ tagged value structure to get better lua_Number alignment.
594** CHANGE it to an empty define if you want to save some space
595** at the cost of execution time. Note that this is only needed
596** for the x86 ABI on most POSIX systems, but not on Windows and
597** not for most other CPUs. If you change it then you need to follow
598** the instructions in ljit_x86.dash, too (look for TVALUE_SIZE).
599*/
600
601#if defined(LUA_NUMBER_DOUBLE) && defined(__GNUC__) && \
602 (defined(__i386) || defined(__i386__)) && !defined(_WIN32)
603#define LUA_TVALUE_ALIGN __attribute__ ((aligned(8)))
604#else
605#define LUA_TVALUE_ALIGN
606#endif
607
608/* }================================================================== */
609
610
611/*
612@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
613** CHANGE it if your system requires alignments larger than double. (For
614** instance, if your system supports long doubles and they must be
615** aligned in 16-byte boundaries, then you should add long double in the
616** union.) Probably you do not need to change this.
617*/
618#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
619
620
621/*
622@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
623** CHANGE them if you prefer to use longjmp/setjmp even with C++
624** or if want/don't to use _longjmp/_setjmp instead of regular
625** longjmp/setjmp. By default, Lua handles errors with exceptions when
626** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
627** and with longjmp/setjmp otherwise.
628*/
629#if defined(__cplusplus)
630/* C++ exceptions */
631#define LUAI_THROW(L,c) throw(c)
632#define LUAI_TRY(L,c,a) try { a } catch(...) \
633 { if ((c)->status == 0) (c)->status = -1; }
634#define luai_jmpbuf int /* dummy variable */
635
636#elif defined(LUA_USE_ULONGJMP)
637/* in Unix, try _longjmp/_setjmp (more efficient) */
638#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
639#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
640#define luai_jmpbuf jmp_buf
641
642#else
643/* default handling with long jumps */
644#define LUAI_THROW(L,c) longjmp((c)->b, 1)
645#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
646#define luai_jmpbuf jmp_buf
647
648#endif
649
650
651/*
652@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
653@* can do during pattern-matching.
654** CHANGE it if you need more captures. This limit is arbitrary.
655*/
656#define LUA_MAXCAPTURES 32
657
658
659/*
660@@ lua_tmpnam is the function that the OS library uses to create a
661@* temporary name.
662@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
663** CHANGE them if you have an alternative to tmpnam (which is considered
664** insecure) or if you want the original tmpnam anyway. By default, Lua
665** uses tmpnam except when POSIX is available, where it uses mkstemp.
666*/
667#if defined(loslib_c) || defined(luaall_c)
668
669#if defined(LUA_USE_MKSTEMP)
670#include <unistd.h>
671#define LUA_TMPNAMBUFSIZE 32
672#define lua_tmpnam(b,e) { \
673 strcpy(b, "/tmp/lua_XXXXXX"); \
674 e = mkstemp(b); \
675 if (e != -1) close(e); \
676 e = (e == -1); }
677
678#else
679#define LUA_TMPNAMBUFSIZE L_tmpnam
680#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
681#endif
682
683#endif
684
685
686/*
687@@ lua_popen spawns a new process connected to the current one through
688@* the file streams.
689** CHANGE it if you have a way to implement it in your system.
690*/
691#if defined(LUA_USE_POPEN)
692
693#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
694#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
695
696#elif defined(LUA_WIN)
697
698#define lua_popen(L,c,m) ((void)L, _popen(c,m))
699#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
700
701#else
702
703#define lua_popen(L,c,m) ((void)((void)c, m), \
704 luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
705#define lua_pclose(L,file) ((void)((void)L, file), 0)
706
707#endif
708
709/*
710@@ LUA_DL_* define which dynamic-library system Lua should use.
711** CHANGE here if Lua has problems choosing the appropriate
712** dynamic-library system for your platform (either Windows' DLL, Mac's
713** dyld, or Unix's dlopen). If your system is some kind of Unix, there
714** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
715** it. To use dlopen you also need to adapt the src/Makefile (probably
716** adding -ldl to the linker options), so Lua does not select it
717** automatically. (When you change the makefile to add -ldl, you must
718** also add -DLUA_USE_DLOPEN.)
719** If you do not want any kind of dynamic library, undefine all these
720** options.
721** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
722*/
723#if defined(LUA_USE_DLOPEN)
724#define LUA_DL_DLOPEN
725#endif
726
727#if defined(LUA_WIN)
728#define LUA_DL_DLL
729#endif
730
731
732/*
733@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
734@* (the data goes just *before* the lua_State pointer).
735** CHANGE (define) this if you really need that. This value must be
736** a multiple of the maximum alignment required for your machine.
737*/
738#define LUAI_EXTRASPACE 0
739
740
741/*
742@@ luai_userstate* allow user-specific actions on threads.
743** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
744** extra when a thread is created/deleted/resumed/yielded.
745*/
746#define luai_userstateopen(L) ((void)L)
747#define luai_userstateclose(L) ((void)L)
748#define luai_userstatethread(L,L1) ((void)L)
749#define luai_userstatefree(L) ((void)L)
750#define luai_userstateresume(L,n) ((void)L)
751#define luai_userstateyield(L,n) ((void)L)
752
753
754/*
755@@ LUA_INTFRMLEN is the length modifier for integer conversions
756@* in 'string.format'.
757@@ LUA_INTFRM_T is the integer type correspoding to the previous length
758@* modifier.
759** CHANGE them if your system supports long long or does not support long.
760*/
761
762#if defined(LUA_USELONGLONG)
763
764#define LUA_INTFRMLEN "ll"
765#define LUA_INTFRM_T long long
766
767#else
768
769#define LUA_INTFRMLEN "l"
770#define LUA_INTFRM_T long
771
772#endif
773
774
775
776/* =================================================================== */
777
778/*
779** Local configuration. You can use this space to add your redefinitions
780** without modifying the main part of the file.
781*/
782
783
784
785#endif
786
diff --git a/libraries/LuaJIT-1.1.7/src/luajit.h b/libraries/LuaJIT-1.1.7/src/luajit.h
new file mode 100644
index 0000000..fa32e17
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/luajit.h
@@ -0,0 +1,68 @@
1/*
2** Copyright (C) 2005-2011 Mike Pall. All rights reserved.
3**
4** Permission is hereby granted, free of charge, to any person obtaining
5** a copy of this software and associated documentation files (the
6** "Software"), to deal in the Software without restriction, including
7** without limitation the rights to use, copy, modify, merge, publish,
8** distribute, sublicense, and/or sell copies of the Software, and to
9** permit persons to whom the Software is furnished to do so, subject to
10** the following conditions:
11**
12** The above copyright notice and this permission notice shall be
13** included in all copies or substantial portions of the Software.
14**
15** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22**
23** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
24*/
25
26/* LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ */
27
28/* LuaJIT public C API. */
29#ifndef luajit_h
30#define luajit_h
31
32#include "lua.h"
33
34
35#define LUAJIT_VERSION "LuaJIT 1.1.7"
36#define LUAJIT_VERSION_NUM 10107 /* Version 1.1.7 = 01.01.07. */
37#define LUAJIT_VERSION_SYM luaJIT_version_1_1_7
38#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2011 Mike Pall"
39#define LUAJIT_URL "http://luajit.org/"
40
41/* Modes for luaJIT_setmode. */
42#define LUAJIT_MODE_MASK 0x00ff
43
44enum {
45 LUAJIT_MODE_ENGINE, /* Set mode for whole JIT engine. */
46 LUAJIT_MODE_DEBUG, /* Set debug mode (idx = level). */
47
48 LUAJIT_MODE_FUNC, /* Change mode for a function. */
49 LUAJIT_MODE_ALLFUNC, /* Recurse into subroutine protos. */
50 LUAJIT_MODE_ALLSUBFUNC, /* Change only the subroutines. */
51 LUAJIT_MODE_MAX
52};
53
54/* Flags or'ed in to the mode. */
55#define LUAJIT_MODE_OFF 0x0000 /* Disable JIT compilation. */
56#define LUAJIT_MODE_ON 0x0100 /* (Re-)enable JIT compilation. */
57
58
59/* Compile a Lua function. Pass arguments as hints. */
60LUA_API int luaJIT_compile(lua_State *L, int nargs);
61
62/* Set the JIT mode for the whole engine or a function (idx = 0: self). */
63LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
64
65/* Enforce (dynamic) linker error for version mismatches. Call from main. */
66LUA_API void LUAJIT_VERSION_SYM(void);
67
68#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lualib.h b/libraries/LuaJIT-1.1.7/src/lualib.h
new file mode 100644
index 0000000..c4567e9
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lualib.h
@@ -0,0 +1,56 @@
1/*
2** $Id: lualib.h,v 1.36 2005/12/27 17:12:00 roberto Exp $
3** Lua standard libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lualib_h
9#define lualib_h
10
11#include "lua.h"
12
13
14/* Key to file-handle type */
15#define LUA_FILEHANDLE "FILE*"
16
17
18#define LUA_COLIBNAME "coroutine"
19LUALIB_API int (luaopen_base) (lua_State *L);
20
21#define LUA_TABLIBNAME "table"
22LUALIB_API int (luaopen_table) (lua_State *L);
23
24#define LUA_IOLIBNAME "io"
25LUALIB_API int (luaopen_io) (lua_State *L);
26
27#define LUA_OSLIBNAME "os"
28LUALIB_API int (luaopen_os) (lua_State *L);
29
30#define LUA_STRLIBNAME "string"
31LUALIB_API int (luaopen_string) (lua_State *L);
32
33#define LUA_MATHLIBNAME "math"
34LUALIB_API int (luaopen_math) (lua_State *L);
35
36#define LUA_DBLIBNAME "debug"
37LUALIB_API int (luaopen_debug) (lua_State *L);
38
39#define LUA_LOADLIBNAME "package"
40LUALIB_API int (luaopen_package) (lua_State *L);
41
42#define LUA_JITLIBNAME "jit"
43LUALIB_API int (luaopen_jit) (lua_State *L);
44
45
46/* open all previous libraries */
47LUALIB_API void (luaL_openlibs) (lua_State *L);
48
49
50
51#ifndef lua_assert
52#define lua_assert(x) ((void)0)
53#endif
54
55
56#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lundump.c b/libraries/LuaJIT-1.1.7/src/lundump.c
new file mode 100644
index 0000000..8010a45
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lundump.c
@@ -0,0 +1,227 @@
1/*
2** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
3** load precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#include <string.h>
8
9#define lundump_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "ldebug.h"
15#include "ldo.h"
16#include "lfunc.h"
17#include "lmem.h"
18#include "lobject.h"
19#include "lstring.h"
20#include "lundump.h"
21#include "lzio.h"
22
23typedef struct {
24 lua_State* L;
25 ZIO* Z;
26 Mbuffer* b;
27 const char* name;
28} LoadState;
29
30#ifdef LUAC_TRUST_BINARIES
31#define IF(c,s)
32#define error(S,s)
33#else
34#define IF(c,s) if (c) error(S,s)
35
36static void error(LoadState* S, const char* why)
37{
38 luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
39 luaD_throw(S->L,LUA_ERRSYNTAX);
40}
41#endif
42
43#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
44#define LoadByte(S) (lu_byte)LoadChar(S)
45#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
46#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
47
48static void LoadBlock(LoadState* S, void* b, size_t size)
49{
50 size_t r=luaZ_read(S->Z,b,size);
51 IF (r!=0, "unexpected end");
52}
53
54static int LoadChar(LoadState* S)
55{
56 char x;
57 LoadVar(S,x);
58 return x;
59}
60
61static int LoadInt(LoadState* S)
62{
63 int x;
64 LoadVar(S,x);
65 IF (x<0, "bad integer");
66 return x;
67}
68
69static lua_Number LoadNumber(LoadState* S)
70{
71 lua_Number x;
72 LoadVar(S,x);
73 return x;
74}
75
76static TString* LoadString(LoadState* S)
77{
78 size_t size;
79 LoadVar(S,size);
80 if (size==0)
81 return NULL;
82 else
83 {
84 char* s=luaZ_openspace(S->L,S->b,size);
85 LoadBlock(S,s,size);
86 return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
87 }
88}
89
90static void LoadCode(LoadState* S, Proto* f)
91{
92 int n=LoadInt(S);
93 f->code=luaM_newvector(S->L,n,Instruction);
94 f->sizecode=n;
95 LoadVector(S,f->code,n,sizeof(Instruction));
96}
97
98static Proto* LoadFunction(LoadState* S, TString* p);
99
100static void LoadConstants(LoadState* S, Proto* f)
101{
102 int i,n;
103 n=LoadInt(S);
104 f->k=luaM_newvector(S->L,n,TValue);
105 f->sizek=n;
106 for (i=0; i<n; i++) setnilvalue(&f->k[i]);
107 for (i=0; i<n; i++)
108 {
109 TValue* o=&f->k[i];
110 int t=LoadChar(S);
111 switch (t)
112 {
113 case LUA_TNIL:
114 setnilvalue(o);
115 break;
116 case LUA_TBOOLEAN:
117 setbvalue(o,LoadChar(S)!=0);
118 break;
119 case LUA_TNUMBER:
120 setnvalue(o,LoadNumber(S));
121 break;
122 case LUA_TSTRING:
123 setsvalue2n(S->L,o,LoadString(S));
124 break;
125 default:
126 error(S,"bad constant");
127 break;
128 }
129 }
130 n=LoadInt(S);
131 f->p=luaM_newvector(S->L,n,Proto*);
132 f->sizep=n;
133 for (i=0; i<n; i++) f->p[i]=NULL;
134 for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
135}
136
137static void LoadDebug(LoadState* S, Proto* f)
138{
139 int i,n;
140 n=LoadInt(S);
141 f->lineinfo=luaM_newvector(S->L,n,int);
142 f->sizelineinfo=n;
143 LoadVector(S,f->lineinfo,n,sizeof(int));
144 n=LoadInt(S);
145 f->locvars=luaM_newvector(S->L,n,LocVar);
146 f->sizelocvars=n;
147 for (i=0; i<n; i++) f->locvars[i].varname=NULL;
148 for (i=0; i<n; i++)
149 {
150 f->locvars[i].varname=LoadString(S);
151 f->locvars[i].startpc=LoadInt(S);
152 f->locvars[i].endpc=LoadInt(S);
153 }
154 n=LoadInt(S);
155 f->upvalues=luaM_newvector(S->L,n,TString*);
156 f->sizeupvalues=n;
157 for (i=0; i<n; i++) f->upvalues[i]=NULL;
158 for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
159}
160
161static Proto* LoadFunction(LoadState* S, TString* p)
162{
163 Proto* f;
164 if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
165 f=luaF_newproto(S->L);
166 setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
167 f->source=LoadString(S); if (f->source==NULL) f->source=p;
168 f->linedefined=LoadInt(S);
169 f->lastlinedefined=LoadInt(S);
170 f->nups=LoadByte(S);
171 f->numparams=LoadByte(S);
172 f->is_vararg=LoadByte(S);
173 f->maxstacksize=LoadByte(S);
174 LoadCode(S,f);
175 LoadConstants(S,f);
176 LoadDebug(S,f);
177 IF (!luaG_checkcode(f), "bad code");
178 S->L->top--;
179 S->L->nCcalls--;
180 return f;
181}
182
183static void LoadHeader(LoadState* S)
184{
185 char h[LUAC_HEADERSIZE];
186 char s[LUAC_HEADERSIZE];
187 luaU_header(h);
188 LoadBlock(S,s,LUAC_HEADERSIZE);
189 IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
190}
191
192/*
193** load precompiled chunk
194*/
195Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
196{
197 LoadState S;
198 if (*name=='@' || *name=='=')
199 S.name=name+1;
200 else if (*name==LUA_SIGNATURE[0])
201 S.name="binary string";
202 else
203 S.name=name;
204 S.L=L;
205 S.Z=Z;
206 S.b=buff;
207 LoadHeader(&S);
208 return LoadFunction(&S,luaS_newliteral(L,"=?"));
209}
210
211/*
212* make header
213*/
214void luaU_header (char* h)
215{
216 int x=1;
217 memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
218 h+=sizeof(LUA_SIGNATURE)-1;
219 *h++=(char)LUAC_VERSION;
220 *h++=(char)LUAC_FORMAT;
221 *h++=(char)*(char*)&x; /* endianness */
222 *h++=(char)sizeof(int);
223 *h++=(char)sizeof(size_t);
224 *h++=(char)sizeof(Instruction);
225 *h++=(char)sizeof(lua_Number);
226 *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
227}
diff --git a/libraries/LuaJIT-1.1.7/src/lundump.h b/libraries/LuaJIT-1.1.7/src/lundump.h
new file mode 100644
index 0000000..c80189d
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lundump.h
@@ -0,0 +1,36 @@
1/*
2** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
3** load precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lundump_h
8#define lundump_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13/* load one chunk; from lundump.c */
14LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
15
16/* make header; from lundump.c */
17LUAI_FUNC void luaU_header (char* h);
18
19/* dump one chunk; from ldump.c */
20LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
21
22#ifdef luac_c
23/* print one chunk; from print.c */
24LUAI_FUNC void luaU_print (const Proto* f, int full);
25#endif
26
27/* for header of binary files -- this is Lua 5.1 */
28#define LUAC_VERSION 0x51
29
30/* for header of binary files -- this is the official format */
31#define LUAC_FORMAT 0
32
33/* size of header of binary files */
34#define LUAC_HEADERSIZE 12
35
36#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lvm.c b/libraries/LuaJIT-1.1.7/src/lvm.c
new file mode 100644
index 0000000..d24f43c
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lvm.c
@@ -0,0 +1,766 @@
1/*
2** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $
3** Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define lvm_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lfunc.h"
20#include "lgc.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lstate.h"
24#include "lstring.h"
25#include "ltable.h"
26#include "ltm.h"
27#include "lvm.h"
28
29
30
31/* limit for table tag-method chains (to avoid loops) */
32#define MAXTAGLOOP 100
33
34
35const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
36 lua_Number num;
37 if (ttisnumber(obj)) return obj;
38 if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
39 setnvalue(n, num);
40 return n;
41 }
42 else
43 return NULL;
44}
45
46
47int luaV_tostring (lua_State *L, StkId obj) {
48 if (!ttisnumber(obj))
49 return 0;
50 else {
51 char s[LUAI_MAXNUMBER2STR];
52 lua_Number n = nvalue(obj);
53 lua_number2str(s, n);
54 setsvalue2s(L, obj, luaS_new(L, s));
55 return 1;
56 }
57}
58
59
60static void traceexec (lua_State *L, const Instruction *pc) {
61 lu_byte mask = L->hookmask;
62 const Instruction *oldpc = L->savedpc;
63 L->savedpc = pc;
64 if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
65 resethookcount(L);
66 luaD_callhook(L, LUA_HOOKCOUNT, -1);
67 }
68 if (mask & LUA_MASKLINE) {
69 Proto *p = ci_func(L->ci)->l.p;
70 int npc = pcRel(pc, p);
71 int newline = getline(p, npc);
72 /* call linehook when enter a new function, when jump back (loop),
73 or when enter a new line */
74 if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
75 luaD_callhook(L, LUA_HOOKLINE, newline);
76 }
77}
78
79
80static void callTMres (lua_State *L, StkId res, const TValue *f,
81 const TValue *p1, const TValue *p2) {
82 ptrdiff_t result = savestack(L, res);
83 setobj2s(L, L->top, f); /* push function */
84 setobj2s(L, L->top+1, p1); /* 1st argument */
85 setobj2s(L, L->top+2, p2); /* 2nd argument */
86 luaD_checkstack(L, 3);
87 L->top += 3;
88 luaD_call(L, L->top - 3, 1);
89 res = restorestack(L, result);
90 L->top--;
91 setobjs2s(L, res, L->top);
92}
93
94
95
96static void callTM (lua_State *L, const TValue *f, const TValue *p1,
97 const TValue *p2, const TValue *p3) {
98 setobj2s(L, L->top, f); /* push function */
99 setobj2s(L, L->top+1, p1); /* 1st argument */
100 setobj2s(L, L->top+2, p2); /* 2nd argument */
101 setobj2s(L, L->top+3, p3); /* 3th argument */
102 luaD_checkstack(L, 4);
103 L->top += 4;
104 luaD_call(L, L->top - 4, 0);
105}
106
107
108void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
109 int loop;
110 for (loop = 0; loop < MAXTAGLOOP; loop++) {
111 const TValue *tm;
112 if (ttistable(t)) { /* `t' is a table? */
113 Table *h = hvalue(t);
114 const TValue *res = luaH_get(h, key); /* do a primitive get */
115 if (!ttisnil(res) || /* result is no nil? */
116 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
117 setobj2s(L, val, res);
118 return;
119 }
120 /* else will try the tag method */
121 }
122 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
123 luaG_typeerror(L, t, "index");
124 if (ttisfunction(tm)) {
125 callTMres(L, val, tm, t, key);
126 return;
127 }
128 t = tm; /* else repeat with `tm' */
129 }
130 luaG_runerror(L, "loop in gettable");
131}
132
133
134void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
135 int loop;
136 TValue temp;
137 for (loop = 0; loop < MAXTAGLOOP; loop++) {
138 const TValue *tm;
139 if (ttistable(t)) { /* `t' is a table? */
140 Table *h = hvalue(t);
141 TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
142 if (!ttisnil(oldval) || /* result is no nil? */
143 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
144 setobj2t(L, oldval, val);
145 luaC_barriert(L, h, val);
146 return;
147 }
148 /* else will try the tag method */
149 }
150 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
151 luaG_typeerror(L, t, "index");
152 if (ttisfunction(tm)) {
153 callTM(L, tm, t, key, val);
154 return;
155 }
156 /* else repeat with `tm' */
157 setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */
158 t = &temp;
159 }
160 luaG_runerror(L, "loop in settable");
161}
162
163
164static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
165 StkId res, TMS event) {
166 const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
167 if (ttisnil(tm))
168 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
169 if (ttisnil(tm)) return 0;
170 callTMres(L, res, tm, p1, p2);
171 return 1;
172}
173
174
175static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
176 TMS event) {
177 const TValue *tm1 = fasttm(L, mt1, event);
178 const TValue *tm2;
179 if (tm1 == NULL) return NULL; /* no metamethod */
180 if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
181 tm2 = fasttm(L, mt2, event);
182 if (tm2 == NULL) return NULL; /* no metamethod */
183 if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
184 return tm1;
185 return NULL;
186}
187
188
189static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
190 TMS event) {
191 const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
192 const TValue *tm2;
193 if (ttisnil(tm1)) return -1; /* no metamethod? */
194 tm2 = luaT_gettmbyobj(L, p2, event);
195 if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
196 return -1;
197 callTMres(L, L->top, tm1, p1, p2);
198 return !l_isfalse(L->top);
199}
200
201
202static int l_strcmp (const TString *ls, const TString *rs) {
203 const char *l = getstr(ls);
204 size_t ll = ls->tsv.len;
205 const char *r = getstr(rs);
206 size_t lr = rs->tsv.len;
207 for (;;) {
208 int temp = strcoll(l, r);
209 if (temp != 0) return temp;
210 else { /* strings are equal up to a `\0' */
211 size_t len = strlen(l); /* index of first `\0' in both strings */
212 if (len == lr) /* r is finished? */
213 return (len == ll) ? 0 : 1;
214 else if (len == ll) /* l is finished? */
215 return -1; /* l is smaller than r (because r is not finished) */
216 /* both strings longer than `len'; go on comparing (after the `\0') */
217 len++;
218 l += len; ll -= len; r += len; lr -= len;
219 }
220 }
221}
222
223
224int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
225 int res;
226 if (ttype(l) != ttype(r))
227 return luaG_ordererror(L, l, r);
228 else if (ttisnumber(l))
229 return luai_numlt(nvalue(l), nvalue(r));
230 else if (ttisstring(l))
231 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
232 else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
233 return res;
234 return luaG_ordererror(L, l, r);
235}
236
237
238int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
239 int res;
240 if (ttype(l) != ttype(r))
241 return luaG_ordererror(L, l, r);
242 else if (ttisnumber(l))
243 return luai_numle(nvalue(l), nvalue(r));
244 else if (ttisstring(l))
245 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
246 else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
247 return res;
248 else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
249 return !res;
250 return luaG_ordererror(L, l, r);
251}
252
253
254int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
255 const TValue *tm;
256 lua_assert(ttype(t1) == ttype(t2));
257 switch (ttype(t1)) {
258 case LUA_TNIL: return 1;
259 case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
260 case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
261 case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
262 case LUA_TUSERDATA: {
263 if (uvalue(t1) == uvalue(t2)) return 1;
264 tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
265 TM_EQ);
266 break; /* will try TM */
267 }
268 case LUA_TTABLE: {
269 if (hvalue(t1) == hvalue(t2)) return 1;
270 tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
271 break; /* will try TM */
272 }
273 default: return gcvalue(t1) == gcvalue(t2);
274 }
275 if (tm == NULL) return 0; /* no TM? */
276 callTMres(L, L->top, tm, t1, t2); /* call TM */
277 return !l_isfalse(L->top);
278}
279
280
281void luaV_concat (lua_State *L, int total, int last) {
282 do {
283 StkId top = L->base + last + 1;
284 int n = 2; /* number of elements handled in this pass (at least 2) */
285 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
286 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
287 luaG_concaterror(L, top-2, top-1);
288 } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
289 (void)tostring(L, top - 2); /* result is first op (as string) */
290 else {
291 /* at least two string values; get as many as possible */
292 size_t tl = tsvalue(top-1)->len;
293 char *buffer;
294 int i;
295 /* collect total length */
296 for (n = 1; n < total && tostring(L, top-n-1); n++) {
297 size_t l = tsvalue(top-n-1)->len;
298 if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
299 tl += l;
300 }
301 buffer = luaZ_openspace(L, &G(L)->buff, tl);
302 tl = 0;
303 for (i=n; i>0; i--) { /* concat all strings */
304 size_t l = tsvalue(top-i)->len;
305 memcpy(buffer+tl, svalue(top-i), l);
306 tl += l;
307 }
308 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
309 }
310 total -= n-1; /* got `n' strings to create 1 new */
311 last -= n-1;
312 } while (total > 1); /* repeat until only 1 result left */
313}
314
315
316void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
317 const TValue *rc, TMS op) {
318 TValue tempb, tempc;
319 const TValue *b, *c;
320 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
321 (c = luaV_tonumber(rc, &tempc)) != NULL) {
322 lua_Number nb = nvalue(b), nc = nvalue(c);
323 switch (op) {
324 case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
325 case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
326 case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
327 case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
328 case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
329 case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
330 case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
331 default: lua_assert(0); break;
332 }
333 }
334 else if (!call_binTM(L, rb, rc, ra, op))
335 luaG_aritherror(L, rb, rc);
336}
337
338
339
340/*
341** some macros for common tasks in `luaV_execute'
342*/
343
344#define runtime_check(L, c) { if (!(c)) break; }
345
346#define RA(i) (base+GETARG_A(i))
347/* to be used after possible stack reallocation */
348#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
349#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
350#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
351 ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
352#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
353 ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
354#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
355
356
357#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
358
359
360#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
361
362
363#define arith_op(op,tm) { \
364 TValue *rb = RKB(i); \
365 TValue *rc = RKC(i); \
366 if (ttisnumber(rb) && ttisnumber(rc)) { \
367 lua_Number nb = nvalue(rb), nc = nvalue(rc); \
368 setnvalue(ra, op(nb, nc)); \
369 } \
370 else \
371 Protect(luaV_arith(L, ra, rb, rc, tm)); \
372 }
373
374
375
376void luaV_execute (lua_State *L, int nexeccalls) {
377 LClosure *cl;
378 StkId base;
379 TValue *k;
380 const Instruction *pc;
381 reentry: /* entry point */
382 lua_assert(isLua(L->ci));
383 pc = L->savedpc;
384 cl = &clvalue(L->ci->func)->l;
385 base = L->base;
386 k = cl->p->k;
387 /* main loop of interpreter */
388 for (;;) {
389 const Instruction i = *pc++;
390 StkId ra;
391 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
392 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
393 traceexec(L, pc);
394 if (L->status == LUA_YIELD) { /* did hook yield? */
395 L->savedpc = pc - 1;
396 return;
397 }
398 base = L->base;
399 }
400 /* warning!! several calls may realloc the stack and invalidate `ra' */
401 ra = RA(i);
402 lua_assert(base == L->base && L->base == L->ci->base);
403 lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
404 lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
405 switch (GET_OPCODE(i)) {
406 case OP_MOVE: {
407 setobjs2s(L, ra, RB(i));
408 continue;
409 }
410 case OP_LOADK: {
411 setobj2s(L, ra, KBx(i));
412 continue;
413 }
414 case OP_LOADBOOL: {
415 setbvalue(ra, GETARG_B(i));
416 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
417 continue;
418 }
419 case OP_LOADNIL: {
420 TValue *rb = RB(i);
421 do {
422 setnilvalue(rb--);
423 } while (rb >= ra);
424 continue;
425 }
426 case OP_GETUPVAL: {
427 int b = GETARG_B(i);
428 setobj2s(L, ra, cl->upvals[b]->v);
429 continue;
430 }
431 case OP_GETGLOBAL: {
432 TValue g;
433 TValue *rb = KBx(i);
434 sethvalue(L, &g, cl->env);
435 lua_assert(ttisstring(rb));
436 Protect(luaV_gettable(L, &g, rb, ra));
437 continue;
438 }
439 case OP_GETTABLE: {
440 Protect(luaV_gettable(L, RB(i), RKC(i), ra));
441 continue;
442 }
443 case OP_SETGLOBAL: {
444 TValue g;
445 sethvalue(L, &g, cl->env);
446 lua_assert(ttisstring(KBx(i)));
447 Protect(luaV_settable(L, &g, KBx(i), ra));
448 continue;
449 }
450 case OP_SETUPVAL: {
451 UpVal *uv = cl->upvals[GETARG_B(i)];
452 setobj(L, uv->v, ra);
453 luaC_barrier(L, uv, ra);
454 continue;
455 }
456 case OP_SETTABLE: {
457 Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
458 continue;
459 }
460 case OP_NEWTABLE: {
461 int b = GETARG_B(i);
462 int c = GETARG_C(i);
463 sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
464 Protect(luaC_checkGC(L));
465 continue;
466 }
467 case OP_SELF: {
468 StkId rb = RB(i);
469 setobjs2s(L, ra+1, rb);
470 Protect(luaV_gettable(L, rb, RKC(i), ra));
471 continue;
472 }
473 case OP_ADD: {
474 arith_op(luai_numadd, TM_ADD);
475 continue;
476 }
477 case OP_SUB: {
478 arith_op(luai_numsub, TM_SUB);
479 continue;
480 }
481 case OP_MUL: {
482 arith_op(luai_nummul, TM_MUL);
483 continue;
484 }
485 case OP_DIV: {
486 arith_op(luai_numdiv, TM_DIV);
487 continue;
488 }
489 case OP_MOD: {
490 arith_op(luai_nummod, TM_MOD);
491 continue;
492 }
493 case OP_POW: {
494 arith_op(luai_numpow, TM_POW);
495 continue;
496 }
497 case OP_UNM: {
498 TValue *rb = RB(i);
499 if (ttisnumber(rb)) {
500 lua_Number nb = nvalue(rb);
501 setnvalue(ra, luai_numunm(nb));
502 }
503 else {
504 Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
505 }
506 continue;
507 }
508 case OP_NOT: {
509 int res = l_isfalse(RB(i)); /* next assignment may change this value */
510 setbvalue(ra, res);
511 continue;
512 }
513 case OP_LEN: {
514 const TValue *rb = RB(i);
515 switch (ttype(rb)) {
516 case LUA_TTABLE: {
517 setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
518 break;
519 }
520 case LUA_TSTRING: {
521 setnvalue(ra, cast_num(tsvalue(rb)->len));
522 break;
523 }
524 default: { /* try metamethod */
525 Protect(
526 if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
527 luaG_typeerror(L, rb, "get length of");
528 )
529 }
530 }
531 continue;
532 }
533 case OP_CONCAT: {
534 int b = GETARG_B(i);
535 int c = GETARG_C(i);
536 Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
537 setobjs2s(L, RA(i), base+b);
538 continue;
539 }
540 case OP_JMP: {
541 dojump(L, pc, GETARG_sBx(i));
542 continue;
543 }
544 case OP_EQ: {
545 TValue *rb = RKB(i);
546 TValue *rc = RKC(i);
547 Protect(
548 if (equalobj(L, rb, rc) == GETARG_A(i))
549 dojump(L, pc, GETARG_sBx(*pc));
550 )
551 pc++;
552 continue;
553 }
554 case OP_LT: {
555 Protect(
556 if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
557 dojump(L, pc, GETARG_sBx(*pc));
558 )
559 pc++;
560 continue;
561 }
562 case OP_LE: {
563 Protect(
564 if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
565 dojump(L, pc, GETARG_sBx(*pc));
566 )
567 pc++;
568 continue;
569 }
570 case OP_TEST: {
571 if (l_isfalse(ra) != GETARG_C(i))
572 dojump(L, pc, GETARG_sBx(*pc));
573 pc++;
574 continue;
575 }
576 case OP_TESTSET: {
577 TValue *rb = RB(i);
578 if (l_isfalse(rb) != GETARG_C(i)) {
579 setobjs2s(L, ra, rb);
580 dojump(L, pc, GETARG_sBx(*pc));
581 }
582 pc++;
583 continue;
584 }
585 case OP_CALL: {
586 int b = GETARG_B(i);
587 int nresults = GETARG_C(i) - 1;
588 if (b != 0) L->top = ra+b; /* else previous instruction set top */
589 L->savedpc = pc;
590 switch (luaD_precall(L, ra, nresults)) {
591 case PCRLUA: {
592 nexeccalls++;
593 goto reentry; /* restart luaV_execute over new Lua function */
594 }
595 case PCRC: {
596 /* it was a C function (`precall' called it); adjust results */
597 if (nresults >= 0) L->top = L->ci->top;
598 base = L->base;
599 continue;
600 }
601 default: {
602 return; /* yield */
603 }
604 }
605 }
606 case OP_TAILCALL: {
607 int b = GETARG_B(i);
608 if (b != 0) L->top = ra+b; /* else previous instruction set top */
609 L->savedpc = pc;
610 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
611 switch (luaD_precall(L, ra, LUA_MULTRET)) {
612 case PCRLUA: {
613 /* tail call: put new frame in place of previous one */
614 CallInfo *ci = L->ci - 1; /* previous frame */
615 int aux;
616 StkId func = ci->func;
617 StkId pfunc = (ci+1)->func; /* previous function index */
618 if (L->openupval) luaF_close(L, ci->base);
619 L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
620 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
621 setobjs2s(L, func+aux, pfunc+aux);
622 ci->top = L->top = func+aux; /* correct top */
623 lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
624 ci->savedpc = L->savedpc;
625 ci->tailcalls++; /* one more call lost */
626 L->ci--; /* remove new frame */
627 goto reentry;
628 }
629 case PCRC: { /* it was a C function (`precall' called it) */
630 base = L->base;
631 continue;
632 }
633 default: {
634 return; /* yield */
635 }
636 }
637 }
638 case OP_RETURN: {
639 int b = GETARG_B(i);
640 if (b != 0) L->top = ra+b-1;
641 if (L->openupval) luaF_close(L, base);
642 L->savedpc = pc;
643 b = luaD_poscall(L, ra);
644 if (--nexeccalls == 0) /* was previous function running `here'? */
645 return; /* no: return */
646 else { /* yes: continue its execution */
647 if (b) L->top = L->ci->top;
648 lua_assert(isLua(L->ci));
649 lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
650 goto reentry;
651 }
652 }
653 case OP_FORLOOP: {
654 lua_Number step = nvalue(ra+2);
655 lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
656 lua_Number limit = nvalue(ra+1);
657 if (luai_numlt(0, step) ? luai_numle(idx, limit)
658 : luai_numle(limit, idx)) {
659 dojump(L, pc, GETARG_sBx(i)); /* jump back */
660 setnvalue(ra, idx); /* update internal index... */
661 setnvalue(ra+3, idx); /* ...and external index */
662 }
663 continue;
664 }
665 case OP_FORPREP: {
666 const TValue *init = ra;
667 const TValue *plimit = ra+1;
668 const TValue *pstep = ra+2;
669 L->savedpc = pc; /* next steps may throw errors */
670 if (!tonumber(init, ra))
671 luaG_runerror(L, LUA_QL("for") " initial value must be a number");
672 else if (!tonumber(plimit, ra+1))
673 luaG_runerror(L, LUA_QL("for") " limit must be a number");
674 else if (!tonumber(pstep, ra+2))
675 luaG_runerror(L, LUA_QL("for") " step must be a number");
676 setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
677 dojump(L, pc, GETARG_sBx(i));
678 continue;
679 }
680 case OP_TFORLOOP: {
681 StkId cb = ra + 3; /* call base */
682 setobjs2s(L, cb+2, ra+2);
683 setobjs2s(L, cb+1, ra+1);
684 setobjs2s(L, cb, ra);
685 L->top = cb+3; /* func. + 2 args (state and index) */
686 Protect(luaD_call(L, cb, GETARG_C(i)));
687 L->top = L->ci->top;
688 cb = RA(i) + 3; /* previous call may change the stack */
689 if (!ttisnil(cb)) { /* continue loop? */
690 setobjs2s(L, cb-1, cb); /* save control variable */
691 dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
692 }
693 pc++;
694 continue;
695 }
696 case OP_SETLIST: {
697 int n = GETARG_B(i);
698 int c = GETARG_C(i);
699 int last;
700 Table *h;
701 if (n == 0) {
702 n = cast_int(L->top - ra) - 1;
703 L->top = L->ci->top;
704 }
705 if (c == 0) c = cast_int(*pc++);
706 runtime_check(L, ttistable(ra));
707 h = hvalue(ra);
708 last = ((c-1)*LFIELDS_PER_FLUSH) + n;
709 if (last > h->sizearray) /* needs more space? */
710 luaH_resizearray(L, h, last); /* pre-alloc it at once */
711 for (; n > 0; n--) {
712 TValue *val = ra+n;
713 setobj2t(L, luaH_setnum(L, h, last--), val);
714 luaC_barriert(L, h, val);
715 }
716 continue;
717 }
718 case OP_CLOSE: {
719 luaF_close(L, ra);
720 continue;
721 }
722 case OP_CLOSURE: {
723 Proto *p;
724 Closure *ncl;
725 int nup, j;
726 p = cl->p->p[GETARG_Bx(i)];
727 nup = p->nups;
728 ncl = luaF_newLclosure(L, nup, cl->env);
729 ncl->l.p = p;
730 for (j=0; j<nup; j++, pc++) {
731 if (GET_OPCODE(*pc) == OP_GETUPVAL)
732 ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
733 else {
734 lua_assert(GET_OPCODE(*pc) == OP_MOVE);
735 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
736 }
737 }
738 setclvalue(L, ra, ncl);
739 Protect(luaC_checkGC(L));
740 continue;
741 }
742 case OP_VARARG: {
743 int b = GETARG_B(i) - 1;
744 int j;
745 CallInfo *ci = L->ci;
746 int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
747 if (b == LUA_MULTRET) {
748 Protect(luaD_checkstack(L, n));
749 ra = RA(i); /* previous call may change the stack */
750 b = n;
751 L->top = ra + n;
752 }
753 for (j = 0; j < b; j++) {
754 if (j < n) {
755 setobjs2s(L, ra + j, ci->base - n + j);
756 }
757 else {
758 setnilvalue(ra + j);
759 }
760 }
761 continue;
762 }
763 }
764 }
765}
766
diff --git a/libraries/LuaJIT-1.1.7/src/lvm.h b/libraries/LuaJIT-1.1.7/src/lvm.h
new file mode 100644
index 0000000..506a294
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lvm.h
@@ -0,0 +1,40 @@
1/*
2** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $
3** Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lvm_h
8#define lvm_h
9
10
11#include "ldo.h"
12#include "lobject.h"
13#include "ltm.h"
14
15
16#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
17
18#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
19 (((o) = luaV_tonumber(o,n)) != NULL))
20
21#define equalobj(L,o1,o2) \
22 (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
23
24
25LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
26LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
27LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
28LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
29LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
30LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
31 StkId val);
32LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
33 StkId val);
34LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
35 const TValue *rc, TMS op);
36
37LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
38LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
39
40#endif
diff --git a/libraries/LuaJIT-1.1.7/src/lzio.c b/libraries/LuaJIT-1.1.7/src/lzio.c
new file mode 100644
index 0000000..293edd5
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lzio.c
@@ -0,0 +1,82 @@
1/*
2** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
3** a generic input stream interface
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lzio_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "llimits.h"
16#include "lmem.h"
17#include "lstate.h"
18#include "lzio.h"
19
20
21int luaZ_fill (ZIO *z) {
22 size_t size;
23 lua_State *L = z->L;
24 const char *buff;
25 lua_unlock(L);
26 buff = z->reader(L, z->data, &size);
27 lua_lock(L);
28 if (buff == NULL || size == 0) return EOZ;
29 z->n = size - 1;
30 z->p = buff;
31 return char2int(*(z->p++));
32}
33
34
35int luaZ_lookahead (ZIO *z) {
36 if (z->n == 0) {
37 if (luaZ_fill(z) == EOZ)
38 return EOZ;
39 else {
40 z->n++; /* luaZ_fill removed first byte; put back it */
41 z->p--;
42 }
43 }
44 return char2int(*z->p);
45}
46
47
48void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
49 z->L = L;
50 z->reader = reader;
51 z->data = data;
52 z->n = 0;
53 z->p = NULL;
54}
55
56
57/* --------------------------------------------------------------- read --- */
58size_t luaZ_read (ZIO *z, void *b, size_t n) {
59 while (n) {
60 size_t m;
61 if (luaZ_lookahead(z) == EOZ)
62 return n; /* return number of missing bytes */
63 m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
64 memcpy(b, z->p, m);
65 z->n -= m;
66 z->p += m;
67 b = (char *)b + m;
68 n -= m;
69 }
70 return 0;
71}
72
73/* ------------------------------------------------------------------------ */
74char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
75 if (n > buff->buffsize) {
76 if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
77 luaZ_resizebuffer(L, buff, n);
78 }
79 return buff->buffer;
80}
81
82
diff --git a/libraries/LuaJIT-1.1.7/src/lzio.h b/libraries/LuaJIT-1.1.7/src/lzio.h
new file mode 100644
index 0000000..51d695d
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/lzio.h
@@ -0,0 +1,67 @@
1/*
2** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $
3** Buffered streams
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lzio_h
9#define lzio_h
10
11#include "lua.h"
12
13#include "lmem.h"
14
15
16#define EOZ (-1) /* end of stream */
17
18typedef struct Zio ZIO;
19
20#define char2int(c) cast(int, cast(unsigned char, (c)))
21
22#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
23
24typedef struct Mbuffer {
25 char *buffer;
26 size_t n;
27 size_t buffsize;
28} Mbuffer;
29
30#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
31
32#define luaZ_buffer(buff) ((buff)->buffer)
33#define luaZ_sizebuffer(buff) ((buff)->buffsize)
34#define luaZ_bufflen(buff) ((buff)->n)
35
36#define luaZ_resetbuffer(buff) ((buff)->n = 0)
37
38
39#define luaZ_resizebuffer(L, buff, size) \
40 (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
41 (buff)->buffsize = size)
42
43#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
44
45
46LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
47LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
48 void *data);
49LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
50LUAI_FUNC int luaZ_lookahead (ZIO *z);
51
52
53
54/* --------- Private Part ------------------ */
55
56struct Zio {
57 size_t n; /* bytes still unread */
58 const char *p; /* current position in buffer */
59 lua_Reader reader;
60 void* data; /* additional data */
61 lua_State *L; /* Lua state (for reader) */
62};
63
64
65LUAI_FUNC int luaZ_fill (ZIO *z);
66
67#endif
diff --git a/libraries/LuaJIT-1.1.7/src/print.c b/libraries/LuaJIT-1.1.7/src/print.c
new file mode 100644
index 0000000..e240cfc
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/print.c
@@ -0,0 +1,227 @@
1/*
2** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $
3** print bytecodes
4** See Copyright Notice in lua.h
5*/
6
7#include <ctype.h>
8#include <stdio.h>
9
10#define luac_c
11#define LUA_CORE
12
13#include "ldebug.h"
14#include "lobject.h"
15#include "lopcodes.h"
16#include "lundump.h"
17
18#define PrintFunction luaU_print
19
20#define Sizeof(x) ((int)sizeof(x))
21#define VOID(p) ((const void*)(p))
22
23static void PrintString(const TString* ts)
24{
25 const char* s=getstr(ts);
26 size_t i,n=ts->tsv.len;
27 putchar('"');
28 for (i=0; i<n; i++)
29 {
30 int c=s[i];
31 switch (c)
32 {
33 case '"': printf("\\\""); break;
34 case '\\': printf("\\\\"); break;
35 case '\a': printf("\\a"); break;
36 case '\b': printf("\\b"); break;
37 case '\f': printf("\\f"); break;
38 case '\n': printf("\\n"); break;
39 case '\r': printf("\\r"); break;
40 case '\t': printf("\\t"); break;
41 case '\v': printf("\\v"); break;
42 default: if (isprint((unsigned char)c))
43 putchar(c);
44 else
45 printf("\\%03u",(unsigned char)c);
46 }
47 }
48 putchar('"');
49}
50
51static void PrintConstant(const Proto* f, int i)
52{
53 const TValue* o=&f->k[i];
54 switch (ttype(o))
55 {
56 case LUA_TNIL:
57 printf("nil");
58 break;
59 case LUA_TBOOLEAN:
60 printf(bvalue(o) ? "true" : "false");
61 break;
62 case LUA_TNUMBER:
63 printf(LUA_NUMBER_FMT,nvalue(o));
64 break;
65 case LUA_TSTRING:
66 PrintString(rawtsvalue(o));
67 break;
68 default: /* cannot happen */
69 printf("? type=%d",ttype(o));
70 break;
71 }
72}
73
74static void PrintCode(const Proto* f)
75{
76 const Instruction* code=f->code;
77 int pc,n=f->sizecode;
78 for (pc=0; pc<n; pc++)
79 {
80 Instruction i=code[pc];
81 OpCode o=GET_OPCODE(i);
82 int a=GETARG_A(i);
83 int b=GETARG_B(i);
84 int c=GETARG_C(i);
85 int bx=GETARG_Bx(i);
86 int sbx=GETARG_sBx(i);
87 int line=getline(f,pc);
88 printf("\t%d\t",pc+1);
89 if (line>0) printf("[%d]\t",line); else printf("[-]\t");
90 printf("%-9s\t",luaP_opnames[o]);
91 switch (getOpMode(o))
92 {
93 case iABC:
94 printf("%d",a);
95 if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
96 if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
97 break;
98 case iABx:
99 if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
100 break;
101 case iAsBx:
102 if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
103 break;
104 }
105 switch (o)
106 {
107 case OP_LOADK:
108 printf("\t; "); PrintConstant(f,bx);
109 break;
110 case OP_GETUPVAL:
111 case OP_SETUPVAL:
112 printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
113 break;
114 case OP_GETGLOBAL:
115 case OP_SETGLOBAL:
116 printf("\t; %s",svalue(&f->k[bx]));
117 break;
118 case OP_GETTABLE:
119 case OP_SELF:
120 if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
121 break;
122 case OP_SETTABLE:
123 case OP_ADD:
124 case OP_SUB:
125 case OP_MUL:
126 case OP_DIV:
127 case OP_POW:
128 case OP_EQ:
129 case OP_LT:
130 case OP_LE:
131 if (ISK(b) || ISK(c))
132 {
133 printf("\t; ");
134 if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
135 printf(" ");
136 if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
137 }
138 break;
139 case OP_JMP:
140 case OP_FORLOOP:
141 case OP_FORPREP:
142 printf("\t; to %d",sbx+pc+2);
143 break;
144 case OP_CLOSURE:
145 printf("\t; %p",VOID(f->p[bx]));
146 break;
147 case OP_SETLIST:
148 if (c==0) printf("\t; %d",(int)code[++pc]);
149 else printf("\t; %d",c);
150 break;
151 default:
152 break;
153 }
154 printf("\n");
155 }
156}
157
158#define SS(x) (x==1)?"":"s"
159#define S(x) x,SS(x)
160
161static void PrintHeader(const Proto* f)
162{
163 const char* s=getstr(f->source);
164 if (*s=='@' || *s=='=')
165 s++;
166 else if (*s==LUA_SIGNATURE[0])
167 s="(bstring)";
168 else
169 s="(string)";
170 printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
171 (f->linedefined==0)?"main":"function",s,
172 f->linedefined,f->lastlinedefined,
173 S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
174 printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
175 f->numparams,f->is_vararg?"+":"",SS(f->numparams),
176 S(f->maxstacksize),S(f->nups));
177 printf("%d local%s, %d constant%s, %d function%s\n",
178 S(f->sizelocvars),S(f->sizek),S(f->sizep));
179}
180
181static void PrintConstants(const Proto* f)
182{
183 int i,n=f->sizek;
184 printf("constants (%d) for %p:\n",n,VOID(f));
185 for (i=0; i<n; i++)
186 {
187 printf("\t%d\t",i+1);
188 PrintConstant(f,i);
189 printf("\n");
190 }
191}
192
193static void PrintLocals(const Proto* f)
194{
195 int i,n=f->sizelocvars;
196 printf("locals (%d) for %p:\n",n,VOID(f));
197 for (i=0; i<n; i++)
198 {
199 printf("\t%d\t%s\t%d\t%d\n",
200 i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
201 }
202}
203
204static void PrintUpvalues(const Proto* f)
205{
206 int i,n=f->sizeupvalues;
207 printf("upvalues (%d) for %p:\n",n,VOID(f));
208 if (f->upvalues==NULL) return;
209 for (i=0; i<n; i++)
210 {
211 printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
212 }
213}
214
215void PrintFunction(const Proto* f, int full)
216{
217 int i,n=f->sizep;
218 PrintHeader(f);
219 PrintCode(f);
220 if (full)
221 {
222 PrintConstants(f);
223 PrintLocals(f);
224 PrintUpvalues(f);
225 }
226 for (i=0; i<n; i++) PrintFunction(f->p[i],full);
227}
diff --git a/libraries/luajit-2.0/.gitignore b/libraries/luajit-2.0/.gitignore
new file mode 100644
index 0000000..1a07bf7
--- /dev/null
+++ b/libraries/luajit-2.0/.gitignore
@@ -0,0 +1,11 @@
1*.[oa]
2*.so
3*.obj
4*.lib
5*.exp
6*.dll
7*.exe
8*.manifest
9*.dmp
10*.swp
11.tags
diff --git a/libraries/luajit-2.0/COPYRIGHT b/libraries/luajit-2.0/COPYRIGHT
new file mode 100644
index 0000000..6f2a45b
--- /dev/null
+++ b/libraries/luajit-2.0/COPYRIGHT
@@ -0,0 +1,56 @@
1===============================================================================
2LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
3
4Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22THE SOFTWARE.
23
24[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
25
26===============================================================================
27[ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ]
28
29Copyright (C) 1994-2011 Lua.org, PUC-Rio.
30
31Permission is hereby granted, free of charge, to any person obtaining a copy
32of this software and associated documentation files (the "Software"), to deal
33in the Software without restriction, including without limitation the rights
34to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35copies of the Software, and to permit persons to whom the Software is
36furnished to do so, subject to the following conditions:
37
38The above copyright notice and this permission notice shall be included in
39all copies or substantial portions of the Software.
40
41THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47THE SOFTWARE.
48
49===============================================================================
50[ LuaJIT includes code from dlmalloc, which has this license statement: ]
51
52This is a version (aka dlmalloc) of malloc/free/realloc written by
53Doug Lea and released to the public domain, as explained at
54http://creativecommons.org/licenses/publicdomain
55
56===============================================================================
diff --git a/libraries/luajit-2.0/Makefile b/libraries/luajit-2.0/Makefile
new file mode 100644
index 0000000..61b0cf2
--- /dev/null
+++ b/libraries/luajit-2.0/Makefile
@@ -0,0 +1,142 @@
1##############################################################################
2# LuaJIT top level Makefile for installation. Requires GNU Make.
3#
4# Please read doc/install.html before changing any variables!
5#
6# Suitable for POSIX platforms (Linux, *BSD, OSX etc.).
7# Note: src/Makefile has many more configurable options.
8#
9# ##### This Makefile is NOT useful for Windows! #####
10# For MSVC, please follow the instructions given in src/msvcbuild.bat.
11# For MinGW and Cygwin, cd to src and run make with the Makefile there.
12#
13# Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
14##############################################################################
15
16MAJVER= 2
17MINVER= 0
18RELVER= 0
19PREREL= -beta9
20VERSION= $(MAJVER).$(MINVER).$(RELVER)$(PREREL)
21ABIVER= 5.1
22NODOTABIVER= 51
23
24##############################################################################
25#
26# Change the installation path as needed. This automatically adjusts
27# the paths in src/luaconf.h, too. Note: PREFIX must be an absolute path!
28#
29export PREFIX= /usr/local
30##############################################################################
31
32DPREFIX= $(DESTDIR)$(PREFIX)
33INSTALL_BIN= $(DPREFIX)/bin
34INSTALL_LIB= $(DPREFIX)/lib
35INSTALL_SHARE= $(DPREFIX)/share
36INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER)
37
38INSTALL_JITLIB= $(INSTALL_SHARE)/luajit-$(VERSION)/jit
39INSTALL_LMOD= $(INSTALL_SHARE)/lua/$(ABIVER)
40INSTALL_CMOD= $(INSTALL_LIB)/lua/$(ABIVER)
41INSTALL_MAN= $(INSTALL_SHARE)/man/man1
42INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig
43
44INSTALL_TNAME= luajit-$(VERSION)
45INSTALL_TSYMNAME= luajit
46INSTALL_ANAME= libluajit-$(ABIVER).a
47INSTALL_SONAME= libluajit-$(ABIVER).so.$(MAJVER).$(MINVER).$(RELVER)
48INSTALL_SOSHORT= libluajit-$(ABIVER).so
49INSTALL_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib
50INSTALL_DYLIBSHORT1= libluajit-$(NODOTABIVER).dylib
51INSTALL_DYLIBSHORT2= libluajit-$(NODOTABIVER).$(MAJVER).dylib
52INSTALL_PCNAME= luajit.pc
53
54INSTALL_STATIC= $(INSTALL_LIB)/$(INSTALL_ANAME)
55INSTALL_DYN= $(INSTALL_LIB)/$(INSTALL_SONAME)
56INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
57INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
58INSTALL_T= $(INSTALL_BIN)/$(INSTALL_TNAME)
59INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME)
60INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME)
61
62INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \
63 $(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD)
64
65RM= rm -f
66MKDIR= mkdir -p
67SYMLINK= ln -sf
68INSTALL_X= install -m 0755
69INSTALL_F= install -m 0644
70LDCONFIG= ldconfig -n
71SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|"
72
73FILE_T= luajit
74FILE_A= libluajit.a
75FILE_SO= libluajit.so
76FILE_MAN= luajit.1
77FILE_PC= luajit.pc
78FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h
79FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua dis_arm.lua \
80 dis_ppc.lua bcsave.lua vmdef.lua
81
82ifeq (,$(findstring Windows,$(OS)))
83 ifeq (Darwin,$(shell uname -s))
84 INSTALL_SONAME= $(INSTALL_DYLIBNAME)
85 INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT1)
86 INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT2)
87 LDCONFIG= :
88 endif
89endif
90
91##############################################################################
92
93INSTALL_DEP= src/luajit
94
95default all $(INSTALL_DEP):
96 @echo "==== Building LuaJIT $(VERSION) ===="
97 $(MAKE) -C src
98 @echo "==== Successfully built LuaJIT $(VERSION) ===="
99
100install: $(INSTALL_DEP)
101 @echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ===="
102 $(MKDIR) $(INSTALL_DIRS)
103 cd src && $(INSTALL_X) $(FILE_T) $(INSTALL_T)
104 cd src && test -f $(FILE_A) && $(INSTALL_F) $(FILE_A) $(INSTALL_STATIC) || :
105 $(RM) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2)
106 cd src && test -f $(FILE_SO) && \
107 $(INSTALL_X) $(FILE_SO) $(INSTALL_DYN) && \
108 $(LDCONFIG) $(INSTALL_LIB) && \
109 $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \
110 $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || :
111 cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN)
112 cd etc && $(SED_PC) $(FILE_PC) > $(FILE_PC).tmp && \
113 $(INSTALL_F) $(FILE_PC).tmp $(INSTALL_PC) && \
114 $(RM) $(FILE_PC).tmp
115 cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC)
116 cd lib && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB)
117 @echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ===="
118 @echo ""
119 @echo "Note: the beta releases deliberately do NOT install a symlink for luajit"
120 @echo "You can do this now by running this command (with sudo):"
121 @echo ""
122 @echo " $(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM)"
123 @echo ""
124
125##############################################################################
126
127amalg:
128 @echo "Building LuaJIT $(VERSION)"
129 $(MAKE) -C src amalg
130
131clean:
132 $(MAKE) -C src clean
133
134cleaner:
135 $(MAKE) -C src cleaner
136
137distclean:
138 $(MAKE) -C src distclean
139
140.PHONY: all install amalg clean cleaner distclean
141
142##############################################################################
diff --git a/libraries/luajit-2.0/README b/libraries/luajit-2.0/README
new file mode 100644
index 0000000..271e312
--- /dev/null
+++ b/libraries/luajit-2.0/README
@@ -0,0 +1,16 @@
1README for LuaJIT 2.0.0-beta9
2-----------------------------
3
4LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
5
6Project Homepage: http://luajit.org/
7
8LuaJIT is Copyright (C) 2005-2011 Mike Pall.
9LuaJIT is free software, released under the MIT license.
10See full Copyright Notice in the COPYRIGHT file or in luajit.h.
11
12Documentation for LuaJIT is available in HTML format.
13Please point your favorite browser to:
14
15 doc/luajit.html
16
diff --git a/libraries/luajit-2.0/doc/bluequad-print.css b/libraries/luajit-2.0/doc/bluequad-print.css
new file mode 100644
index 0000000..69c07d6
--- /dev/null
+++ b/libraries/luajit-2.0/doc/bluequad-print.css
@@ -0,0 +1,166 @@
1/* Copyright (C) 2004-2011 Mike Pall.
2 *
3 * You are welcome to use the general ideas of this design for your own sites.
4 * But please do not steal the stylesheet, the layout or the color scheme.
5 */
6body {
7 font-family: serif;
8 font-size: 11pt;
9 margin: 0 3em;
10 padding: 0;
11 border: none;
12}
13a:link, a:visited, a:hover, a:active {
14 text-decoration: none;
15 background: transparent;
16 color: #0000ff;
17}
18h1, h2, h3 {
19 font-family: sans-serif;
20 font-weight: bold;
21 text-align: left;
22 margin: 0.5em 0;
23 padding: 0;
24}
25h1 {
26 font-size: 200%;
27}
28h2 {
29 font-size: 150%;
30}
31h3 {
32 font-size: 125%;
33}
34p {
35 margin: 0 0 0.5em 0;
36 padding: 0;
37}
38ul, ol {
39 margin: 0.5em 0;
40 padding: 0 0 0 2em;
41}
42ul {
43 list-style: outside square;
44}
45ol {
46 list-style: outside decimal;
47}
48li {
49 margin: 0;
50 padding: 0;
51}
52dl {
53 margin: 1em 0;
54 padding: 1em;
55 border: 1px solid black;
56}
57dt {
58 font-weight: bold;
59 margin: 0;
60 padding: 0;
61}
62dt sup {
63 float: right;
64 margin-left: 1em;
65}
66dd {
67 margin: 0.5em 0 0 2em;
68 padding: 0;
69}
70table {
71 table-layout: fixed;
72 width: 100%;
73 margin: 1em 0;
74 padding: 0;
75 border: 1px solid black;
76 border-spacing: 0;
77 border-collapse: collapse;
78}
79tr {
80 margin: 0;
81 padding: 0;
82 border: none;
83}
84td {
85 text-align: left;
86 margin: 0;
87 padding: 0.2em 0.5em;
88 border-top: 1px solid black;
89 border-bottom: 1px solid black;
90}
91tr.separate td {
92 border-top: double;
93}
94tt, pre, code, kbd, samp {
95 font-family: monospace;
96 font-size: 75%;
97}
98kbd {
99 font-weight: bolder;
100}
101blockquote, pre {
102 margin: 1em 2em;
103 padding: 0;
104}
105img {
106 border: none;
107 vertical-align: baseline;
108 margin: 0;
109 padding: 0;
110}
111img.left {
112 float: left;
113 margin: 0.5em 1em 0.5em 0;
114}
115img.right {
116 float: right;
117 margin: 0.5em 0 0.5em 1em;
118}
119.flush {
120 clear: both;
121 visibility: hidden;
122}
123.hide, .noprint, #nav {
124 display: none !important;
125}
126.pagebreak {
127 page-break-before: always;
128}
129#site {
130 text-align: right;
131 font-family: sans-serif;
132 font-weight: bold;
133 margin: 0 1em;
134 border-bottom: 1pt solid black;
135}
136#site a {
137 font-size: 1.2em;
138}
139#site a:link, #site a:visited {
140 text-decoration: none;
141 font-weight: bold;
142 background: transparent;
143 color: #ffffff;
144}
145#logo {
146 color: #ff8000;
147}
148#head {
149 clear: both;
150 margin: 0 1em;
151}
152#main {
153 line-height: 1.3;
154 text-align: justify;
155 margin: 1em;
156}
157#foot {
158 clear: both;
159 font-size: 80%;
160 text-align: center;
161 margin: 0 1.25em;
162 padding: 0.5em 0 0 0;
163 border-top: 1pt solid black;
164 page-break-before: avoid;
165 page-break-after: avoid;
166}
diff --git a/libraries/luajit-2.0/doc/bluequad.css b/libraries/luajit-2.0/doc/bluequad.css
new file mode 100644
index 0000000..49849fb
--- /dev/null
+++ b/libraries/luajit-2.0/doc/bluequad.css
@@ -0,0 +1,306 @@
1/* Copyright (C) 2004-2011 Mike Pall.
2 *
3 * You are welcome to use the general ideas of this design for your own sites.
4 * But please do not steal the stylesheet, the layout or the color scheme.
5 */
6/* colorscheme:
7 *
8 * site | head #4162bf/white | #6078bf/#e6ecff
9 * ------+------ ----------------+-------------------
10 * nav | main #bfcfff | #e6ecff/black
11 *
12 * nav: hiback loback #c5d5ff #b9c9f9
13 * hiborder loborder #e6ecff #97a7d7
14 * link hover #2142bf #ff0000
15 *
16 * link: link visited hover #2142bf #8122bf #ff0000
17 *
18 * main: boxback boxborder #f0f4ff #bfcfff
19 */
20body {
21 font-family: Verdana, Arial, Helvetica, sans-serif;
22 font-size: 10pt;
23 margin: 0;
24 padding: 0;
25 border: none;
26 background: #e0e0e0;
27 color: #000000;
28}
29a:link {
30 text-decoration: none;
31 background: transparent;
32 color: #2142bf;
33}
34a:visited {
35 text-decoration: none;
36 background: transparent;
37 color: #8122bf;
38}
39a:hover, a:active {
40 text-decoration: underline;
41 background: transparent;
42 color: #ff0000;
43}
44h1, h2, h3 {
45 font-weight: bold;
46 text-align: left;
47 margin: 0.5em 0;
48 padding: 0;
49 background: transparent;
50}
51h1 {
52 font-size: 200%;
53 line-height: 3em; /* really 6em relative to body, match #site span */
54 margin: 0;
55}
56h2 {
57 font-size: 150%;
58 color: #606060;
59}
60h3 {
61 font-size: 125%;
62 color: #404040;
63}
64p {
65 max-width: 600px;
66 margin: 0 0 0.5em 0;
67 padding: 0;
68}
69b {
70 color: #404040;
71}
72ul, ol {
73 max-width: 600px;
74 margin: 0.5em 0;
75 padding: 0 0 0 2em;
76}
77ul {
78 list-style: outside square;
79}
80ol {
81 list-style: outside decimal;
82}
83li {
84 margin: 0;
85 padding: 0;
86}
87dl {
88 max-width: 600px;
89 margin: 1em 0;
90 padding: 1em;
91 border: 1px solid #bfcfff;
92 background: #f0f4ff;
93}
94dt {
95 font-weight: bold;
96 margin: 0;
97 padding: 0;
98}
99dt sup {
100 float: right;
101 margin-left: 1em;
102 color: #808080;
103}
104dt a:visited {
105 text-decoration: none;
106 color: #2142bf;
107}
108dt a:hover, dt a:active {
109 text-decoration: none;
110 color: #ff0000;
111}
112dd {
113 margin: 0.5em 0 0 2em;
114 padding: 0;
115}
116div.tablewrap { /* for IE *sigh* */
117 max-width: 600px;
118}
119table {
120 table-layout: fixed;
121 border-spacing: 0;
122 border-collapse: collapse;
123 max-width: 600px;
124 width: 100%;
125 margin: 1em 0;
126 padding: 0;
127 border: 1px solid #bfcfff;
128}
129tr {
130 margin: 0;
131 padding: 0;
132 border: none;
133}
134tr.odd {
135 background: #f0f4ff;
136}
137tr.separate td {
138 border-top: 1px solid #bfcfff;
139}
140td {
141 text-align: left;
142 margin: 0;
143 padding: 0.2em 0.5em;
144 border: none;
145}
146tt, code, kbd, samp {
147 font-family: Courier New, Courier, monospace;
148 line-height: 1.2;
149 font-size: 110%;
150}
151kbd {
152 font-weight: bolder;
153}
154blockquote, pre {
155 max-width: 600px;
156 margin: 1em 2em;
157 padding: 0;
158}
159pre {
160 line-height: 1.1;
161}
162pre.code {
163 line-height: 1.4;
164 margin: 0.5em 0 1em 0.5em;
165 padding: 0.5em 1em;
166 border: 1px solid #bfcfff;
167 background: #f0f4ff;
168}
169img {
170 border: none;
171 vertical-align: baseline;
172 margin: 0;
173 padding: 0;
174}
175img.left {
176 float: left;
177 margin: 0.5em 1em 0.5em 0;
178}
179img.right {
180 float: right;
181 margin: 0.5em 0 0.5em 1em;
182}
183.indent {
184 padding-left: 1em;
185}
186.flush {
187 clear: both;
188 visibility: hidden;
189}
190.hide, .noscreen {
191 display: none !important;
192}
193.ext {
194 color: #ff8000;
195}
196#site {
197 clear: both;
198 float: left;
199 width: 13em;
200 text-align: center;
201 font-weight: bold;
202 margin: 0;
203 padding: 0;
204 background: transparent;
205 color: #ffffff;
206}
207#site a {
208 font-size: 200%;
209}
210#site a:link, #site a:visited {
211 text-decoration: none;
212 font-weight: bold;
213 background: transparent;
214 color: #ffffff;
215}
216#site span {
217 line-height: 3em; /* really 6em relative to body, match h1 */
218}
219#logo {
220 color: #ffb380;
221}
222#head {
223 margin: 0;
224 padding: 0 0 0 2em;
225 border-left: solid 13em #4162bf;
226 border-right: solid 3em #6078bf;
227 background: #6078bf;
228 color: #e6ecff;
229}
230#nav {
231 clear: both;
232 float: left;
233 overflow: hidden;
234 text-align: left;
235 line-height: 1.5;
236 width: 13em;
237 padding-top: 1em;
238 background: transparent;
239}
240#nav ul {
241 list-style: none outside;
242 margin: 0;
243 padding: 0;
244}
245#nav li {
246 margin: 0;
247 padding: 0;
248}
249#nav a {
250 display: block;
251 text-decoration: none;
252 font-weight: bold;
253 margin: 0;
254 padding: 2px 1em;
255 border-top: 1px solid transparent;
256 border-bottom: 1px solid transparent;
257 background: transparent;
258 color: #2142bf;
259}
260#nav a:hover, #nav a:active {
261 text-decoration: none;
262 border-top: 1px solid #97a7d7;
263 border-bottom: 1px solid #e6ecff;
264 background: #b9c9f9;
265 color: #ff0000;
266}
267#nav a.current, #nav a.current:hover, #nav a.current:active {
268 border-top: 1px solid #e6ecff;
269 border-bottom: 1px solid #97a7d7;
270 background: #c5d5ff;
271 color: #2142bf;
272}
273#nav ul ul a {
274 padding: 0 1em 0 1.7em;
275}
276#nav ul ul ul a {
277 padding: 0 0.5em 0 2.4em;
278}
279#main {
280 line-height: 1.5;
281 text-align: left;
282 margin: 0;
283 padding: 1em 2em;
284 border-left: solid 13em #bfcfff;
285 border-right: solid 3em #e6ecff;
286 background: #e6ecff;
287}
288#foot {
289 clear: both;
290 font-size: 80%;
291 text-align: center;
292 margin: 0;
293 padding: 0.5em;
294 background: #6078bf;
295 color: #ffffff;
296}
297#foot a:link, #foot a:visited {
298 text-decoration: underline;
299 background: transparent;
300 color: #ffffff;
301}
302#foot a:hover, #foot a:active {
303 text-decoration: underline;
304 background: transparent;
305 color: #bfcfff;
306}
diff --git a/libraries/luajit-2.0/doc/changes.html b/libraries/luajit-2.0/doc/changes.html
new file mode 100644
index 0000000..51027a9
--- /dev/null
+++ b/libraries/luajit-2.0/doc/changes.html
@@ -0,0 +1,640 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>LuaJIT Change History</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
13</style>
14</head>
15<body>
16<div id="site">
17<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
18</div>
19<div id="head">
20<h1>LuaJIT Change History</h1>
21</div>
22<div id="nav">
23<ul><li>
24<a href="luajit.html">LuaJIT</a>
25<ul><li>
26<a href="install.html">Installation</a>
27</li><li>
28<a href="running.html">Running</a>
29</li></ul>
30</li><li>
31<a href="extensions.html">Extensions</a>
32<ul><li>
33<a href="ext_ffi.html">FFI Library</a>
34<ul><li>
35<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
36</li><li>
37<a href="ext_ffi_api.html">ffi.* API</a>
38</li><li>
39<a href="ext_ffi_semantics.html">FFI Semantics</a>
40</li></ul>
41</li><li>
42<a href="ext_jit.html">jit.* Library</a>
43</li><li>
44<a href="ext_c_api.html">Lua/C API</a>
45</li></ul>
46</li><li>
47<a href="status.html">Status</a>
48<ul><li>
49<a class="current" href="changes.html">Changes</a>
50</li></ul>
51</li><li>
52<a href="faq.html">FAQ</a>
53</li><li>
54<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
55</li><li>
56<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
57</li></ul>
58</div>
59<div id="main">
60<p>
61This is a list of changes between the released versions of LuaJIT.<br>
62The current <span style="color: #c00000;">development version</span> is <strong>LuaJIT&nbsp;2.0.0-beta9</strong>.<br>
63The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT&nbsp;1.1.7</strong>.
64</p>
65<p>
66Please check the
67<a href="http://luajit.org/changes.html"><span class="ext">&raquo;</span>&nbsp;Online Change History</a>
68to see whether newer versions are available.
69</p>
70
71<div class="major" style="background: #ffd0d0;">
72<h2 id="LuaJIT-2.0.0-beta9">LuaJIT 2.0.0-beta9 &mdash; 2011-12-14</h2>
73<ul>
74<li>New features:
75<ul>
76<li>PPC port of LuaJIT is complete. Default is the dual-number port
77(usually faster). Single-number port selectable via <tt>src/Makefile</tt>
78at build time.</li>
79<li>Add FFI callback support.</li>
80<li>Extend <tt>-b</tt> to generate <tt>.c</tt>, <tt>.h</tt> or <tt>.obj/.o</tt>
81files with embedded bytecode.</li>
82<li>Allow loading embedded bytecode with <tt>require()</tt>.</li>
83<li>From Lua 5.2: Change to <tt>'\z'</tt> escape. Reject undefined escape
84sequences.</li>
85</ul></li>
86<li>Correctness and completeness:
87<ul>
88<li>Fix OSX 10.7 build. Fix <tt>install_name</tt> and versioning on OSX.</li>
89<li>Fix iOS build.</li>
90<li>Install <tt>dis_arm.lua</tt>, too.</li>
91<li>Mark installed shared library as executable.</li>
92<li>Add debug option to <tt>msvcbuild.bat</tt> and improve error handling.</li>
93<li>Fix data-flow analysis for iterators.</li>
94<li>Fix forced unwinding triggered by external unwinder.</li>
95<li>Record missing <tt>for</tt> loop slot loads (return to lower frame).</li>
96<li>Always use ANSI variants of Windows system functions.</li>
97<li>Fix GC barrier for multi-result table constructor (<tt>TSETM</tt>).</li>
98<li>Fix/add various FOLD rules.</li>
99<li>Add potential PHI for number conversions due to type instability.</li>
100<li>Do not eliminate PHIs only referenced from other PHIs.</li>
101<li>Correctly anchor implicit number to string conversions in Lua/C API.</li>
102<li>Fix various stack limit checks.</li>
103<li>x64: Use thread-safe exceptions for external unwinding (GCC platforms).</li>
104<li>x64: Fix result type of cdata index conversions.</li>
105<li>x64: Fix <tt>math.random()</tt> and <tt>bit.bswap()</tt> code generation.</li>
106<li>x64: Fix <tt>lightuserdata</tt> comparisons.</li>
107<li>x64: Always extend stack-passed arguments to pointer size.</li>
108<li>ARM: Many fixes to code generation backend.</li>
109<li>PPC/e500: Fix dispatch for binop metamethods.</li>
110<li>PPC/e500: Save/restore condition registers when entering/leaving the VM.</li>
111<li>PPC/e500: Fix write barrier in stores of strings to upvalues.</li>
112</ul></li>
113<li>FFI library:
114<ul>
115<li>Fix C comment parsing.</li>
116<li>Fix snapshot optimization for cdata comparisons.</li>
117<li>Fix recording of const/enum lookups in namespaces.</li>
118<li>Fix call argument and return handling for <tt>I8/U8/I16/U16</tt> types.</li>
119<li>Fix unfused loads of float fields.</li>
120<li>Fix <tt>ffi.string()</tt> recording.</li>
121<li>Save <tt>GetLastError()</tt> around <tt>ffi.load()</tt> and symbol
122resolving, too.</li>
123<li>Improve ld script detection in <tt>ffi.load()</tt>.</li>
124<li>Record loads/stores to external variables in namespaces.</li>
125<li>Compile calls to stdcall, fastcall and vararg functions.</li>
126<li>Treat function ctypes like pointers in comparisons.</li>
127<li>Resolve <tt>__call</tt> metamethod for pointers, too.</li>
128<li>Record C function calls with bool return values.</li>
129<li>Record <tt>ffi.errno()</tt>.</li>
130<li>x86: Fix number to <tt>uint32_t</tt> conversion rounding.</li>
131<li>x86: Fix 64 bit arithmetic in assembler backend.</li>
132<li>x64: Fix struct-by-value calling conventions.</li>
133<li>ARM: Ensure invocation of SPLIT pass for float conversions.</li>
134</ul></li>
135<li>Structural and performance enhancements:
136<ul>
137<li>Display trace types with <tt>-jv</tt> and <tt>-jdump</tt>.</li>
138<li>Record isolated calls. But prefer recording loops over calls.</li>
139<li>Specialize to prototype for non-monomorphic functions. Solves the
140trace-explosion problem for closure-heavy programming styles.</li>
141<li>Always generate a portable <tt>vmdef.lua</tt>. Easier for distros.</li>
142</ul></li>
143</ul>
144
145<h2 id="LuaJIT-2.0.0-beta8">LuaJIT 2.0.0-beta8 &mdash; 2011-06-23</h2>
146<ul>
147<li>New features:
148<ul>
149<li>Soft-float ARM port of LuaJIT is complete.</li>
150<li>Add support for bytecode loading/saving and <tt>-b</tt> command line
151option.</li>
152<li>From Lua 5.2: <tt>__len</tt> metamethod for tables
153(disabled by default).</li>
154</ul></li>
155<li>Correctness and completeness:
156<ul>
157<li>ARM: Misc. fixes for interpreter.</li>
158<li>x86/x64: Fix <tt>bit.*</tt> argument checking in interpreter.</li>
159<li>Catch early out-of-memory in memory allocator initialization.</li>
160<li>Fix data-flow analysis for paths leading to an upvalue close.</li>
161<li>Fix check for missing arguments in <tt>string.format()</tt>.</li>
162<li>Fix Solaris/x86 build (note: not a supported target).</li>
163<li>Fix recording of loops with instable directions in side traces.</li>
164<li>x86/x64: Fix fusion of comparisons with <tt>u8</tt>/<tt>u16</tt>
165<tt>XLOAD</tt>.</li>
166<li>x86/x64: Fix register allocation for variable shifts.</li>
167</ul></li>
168<li>FFI library:
169<ul>
170<li>Add <tt>ffi.errno()</tt>. Save <tt>errno</tt>/<tt>GetLastError()</tt>
171around allocations etc.</li>
172<li>Fix <tt>__gc</tt> for VLA/VLS cdata objects.</li>
173<li>Fix recording of casts from 32 bit cdata pointers to integers.</li>
174<li><tt>tonumber(cdata)</tt> returns <tt>nil</tt> for non-numbers.</li>
175<li>Show address pointed to for <tt>tostring(pointer)</tt>.</li>
176<li>Print <tt>NULL</tt> pointers as <tt>"cdata&lt;... *&gt;: NULL"</tt>.</li>
177<li>Support <tt>__tostring</tt> metamethod for pointers to structs, too.</li>
178</ul></li>
179<li>Structural and performance enhancements:
180<ul>
181<li>More tuning for loop unrolling heuristics.</li>
182<li>Flatten and compress in-memory debug info (saves ~70%).</li>
183</ul></li>
184</ul>
185
186<h2 id="LuaJIT-2.0.0-beta7">LuaJIT 2.0.0-beta7 &mdash; 2011-05-05</h2>
187<ul>
188<li>New features:
189<ul>
190<li>ARM port of the LuaJIT interpreter is complete.</li>
191<li>FFI library: Add <tt>ffi.gc()</tt>, <tt>ffi.metatype()</tt>,
192<tt>ffi.istype()</tt>.</li>
193<li>FFI library: Resolve ld script redirection in <tt>ffi.load()</tt>.</li>
194<li>From Lua 5.2: <tt>package.searchpath()</tt>, <tt>fp:read("*L")</tt>,
195<tt>load(string)</tt>.</li>
196<li>From Lua 5.2, disabled by default: empty statement,
197<tt>table.unpack()</tt>, modified <tt>coroutine.running()</tt>.</li>
198</ul></li>
199<li>Correctness and completeness:
200<ul>
201<li>FFI library: numerous fixes.</li>
202<li>Fix type mismatches in store-to-load forwarding.</li>
203<li>Fix error handling within metamethods.</li>
204<li>Fix <tt>table.maxn()</tt>.</li>
205<li>Improve accuracy of <tt>x^-k</tt> on x64.</li>
206<li>Fix code generation for Intel Atom in x64 mode.</li>
207<li>Fix narrowing of POW.</li>
208<li>Fix recording of retried fast functions.</li>
209<li>Fix code generation for <tt>bit.bnot()</tt> and multiplies.</li>
210<li>Fix error location within cpcall frames.</li>
211<li>Add workaround for old libgcc unwind bug.</li>
212<li>Fix <tt>lua_yield()</tt> and <tt>getmetatable(lightuserdata)</tt> on x64.</li>
213<li>Misc. fixes for PPC/e500 interpreter.</li>
214<li>Fix stack slot updates for down-recursion.</li>
215</ul></li>
216<li>Structural and performance enhancements:
217<ul>
218<li>Add dual-number mode (int/double) for the VM. Enabled for ARM.</li>
219<li>Improve narrowing of arithmetic operators and <tt>for</tt> loops.</li>
220<li>Tune loop unrolling heuristics and increase trace recorder limits.</li>
221<li>Eliminate dead slots in snapshots using bytecode data-flow analysis.</li>
222<li>Avoid phantom stores to proxy tables.</li>
223<li>Optimize lookups in empty proxy tables.</li>
224<li>Improve bytecode optimization of <tt>and</tt>/<tt>or</tt> operators.</li>
225</ul></li>
226</ul>
227
228<h2 id="LuaJIT-2.0.0-beta6">LuaJIT 2.0.0-beta6 &mdash; 2011-02-11</h2>
229<ul>
230<li>New features:
231<ul>
232<li>PowerPC/e500v2 port of the LuaJIT interpreter is complete.</li>
233<li>Various minor features from Lua 5.2: Hex escapes in literals,
234<tt>'\*'</tt> escape, reversible <tt>string.format("%q",s)</tt>,
235<tt>"%g"</tt> pattern, <tt>table.sort</tt> checks callbacks,
236<tt>os.exit(status|true|false[,close])</tt>.</li>
237<li>Lua 5.2 <tt>__pairs</tt> and <tt>__ipairs</tt> metamethods
238(disabled by default).</li>
239<li>Initial release of the FFI library.</li>
240</ul></li>
241<li>Correctness and completeness:
242<ul>
243<li>Fix <tt>string.format()</tt> for non-finite numbers.</li>
244<li>Fix memory leak when compiled to use the built-in allocator.</li>
245<li>x86/x64: Fix unnecessary resize in <tt>TSETM</tt> bytecode.</li>
246<li>Fix various GC issues with traces and <tt>jit.flush()</tt>.</li>
247<li>x64: Fix fusion of indexes for array references.</li>
248<li>x86/x64: Fix stack overflow handling for coroutine results.</li>
249<li>Enable low-2GB memory allocation on FreeBSD/x64.</li>
250<li>Fix <tt>collectgarbage("count")</tt> result if more than 2GB is in use.</li>
251<li>Fix parsing of hex floats.</li>
252<li>x86/x64: Fix loop branch inversion with trailing
253<tt>HREF+NE/EQ</tt>.</li>
254<li>Add <tt>jit.os</tt> string.</li>
255<li><tt>coroutine.create()</tt> permits running C functions, too.</li>
256<li>Fix OSX build to work with newer ld64 versions.</li>
257<li>Fix bytecode optimization of <tt>and</tt>/<tt>or</tt> operators.</li>
258</ul></li>
259<li>Structural and performance enhancements:
260<ul>
261<li>Emit specialized bytecode for <tt>pairs()</tt>/<tt>next()</tt>.</li>
262<li>Improve bytecode coalescing of <tt>nil</tt> constants.</li>
263<li>Compile calls to vararg functions.</li>
264<li>Compile <tt>select()</tt>.</li>
265<li>Improve alias analysis, esp. for loads from allocations.</li>
266<li>Tuning of various compiler heuristics.</li>
267<li>Refactor and extend IR conversion instructions.</li>
268<li>x86/x64: Various backend enhancements related to the FFI.</li>
269<li>Add SPLIT pass to split 64 bit IR instructions for 32 bit CPUs.</li>
270</ul></li>
271</ul>
272
273<h2 id="LuaJIT-2.0.0-beta5">LuaJIT 2.0.0-beta5 &mdash; 2010-08-24</h2>
274<ul>
275<li>Correctness and completeness:
276<ul>
277<li>Fix trace exit dispatch to function headers.</li>
278<li>Fix Windows and OSX builds with LUAJIT_DISABLE_JIT.</li>
279<li>Reorganize and fix placement of generated machine code on x64.</li>
280<li>Fix TNEW in x64 interpreter.</li>
281<li>Do not eliminate PHIs for values only referenced from side exits.</li>
282<li>OS-independent canonicalization of strings for non-finite numbers.</li>
283<li>Fix <tt>string.char()</tt> range check on x64.</li>
284<li>Fix <tt>tostring()</tt> resolving within <tt>print()</tt>.</li>
285<li>Fix error handling for <tt>next()</tt>.</li>
286<li>Fix passing of constant arguments to external calls on x64.</li>
287<li>Fix interpreter argument check for two-argument SSE math functions.</li>
288<li>Fix C frame chain corruption caused by <tt>lua_cpcall()</tt>.</li>
289<li>Fix return from <tt>pcall()</tt> within active hook.</li>
290</ul></li>
291<li>Structural and performance enhancements:
292<ul>
293<li>Replace on-trace GC frame syncing with interpreter exit.</li>
294<li>Improve hash lookup specialization by not removing dead keys during GC.</li>
295<li>Turn traces into true GC objects.</li>
296<li>Avoid starting a GC cycle immediately after library init.</li>
297<li>Add weak guards to improve dead-code elimination.</li>
298<li>Speed up string interning.</li>
299</ul></li>
300</ul>
301
302<h2 id="LuaJIT-2.0.0-beta4">LuaJIT 2.0.0-beta4 &mdash; 2010-03-28</h2>
303<ul>
304<li>Correctness and completeness:
305<ul>
306<li>Fix precondition for on-trace creation of table keys.</li>
307<li>Fix <tt>{f()}</tt> on x64 when table is resized.</li>
308<li>Fix folding of ordered comparisons with same references.</li>
309<li>Fix snapshot restores for multi-result bytecodes.</li>
310<li>Fix potential hang when recording bytecode with nested closures.</li>
311<li>Fix recording of <tt>getmetatable()</tt>, <tt>tonumber()</tt> and bad argument types.</li>
312<li>Fix SLOAD fusion across returns to lower frames.</li>
313</ul></li>
314<li>Structural and performance enhancements:
315<ul>
316<li>Add array bounds check elimination. <tt>-Oabc</tt> is enabled by default.</li>
317<li>More tuning for x64, e.g. smaller table objects.</li>
318</ul></li>
319</ul>
320
321<h2 id="LuaJIT-2.0.0-beta3">LuaJIT 2.0.0-beta3 &mdash; 2010-03-07</h2>
322<ul>
323<li>LuaJIT x64 port:
324<ul>
325<li>Port integrated memory allocator to Linux/x64, Windows/x64 and OSX/x64.</li>
326<li>Port interpreter and JIT compiler to x64.</li>
327<li>Port DynASM to x64.</li>
328<li>Many 32/64 bit cleanups in the VM.</li>
329<li>Allow building the interpreter with either x87 or SSE2 arithmetics.</li>
330<li>Add external unwinding and C++ exception interop (default on x64).</li>
331</ul></li>
332<li>Correctness and completeness:
333<ul>
334<li>Fix constructor bytecode generation for certain conditional values.</li>
335<li>Fix some cases of ordered string comparisons.</li>
336<li>Fix <tt>lua_tocfunction()</tt>.</li>
337<li>Fix cutoff register in JMP bytecode for some conditional expressions.</li>
338<li>Fix PHI marking algorithm for references from variant slots.</li>
339<li>Fix <tt>package.cpath</tt> for non-default PREFIX.</li>
340<li>Fix DWARF2 frame unwind information for interpreter on OSX.</li>
341<li>Drive the GC forward on string allocations in the parser.</li>
342<li>Implement call/return hooks (zero-cost if disabled).</li>
343<li>Implement yield from C hooks.</li>
344<li>Disable JIT compiler on older non-SSE2 CPUs instead of aborting.</li>
345</ul></li>
346<li>Structural and performance enhancements:
347<ul>
348<li>Compile recursive code (tail-, up- and down-recursion).</li>
349<li>Improve heuristics for bytecode penalties and blacklisting.</li>
350<li>Split CALL/FUNC recording and clean up fast function call semantics.</li>
351<li>Major redesign of internal function call handling.</li>
352<li>Improve FOR loop const specialization and integerness checks.</li>
353<li>Switch to pre-initialized stacks. Avoid frame-clearing.</li>
354<li>Colocation of prototypes and related data: bytecode, constants, debug info.</li>
355<li>Cleanup parser and streamline bytecode generation.</li>
356<li>Add support for weak IR references to register allocator.</li>
357<li>Switch to compressed, extensible snapshots.</li>
358<li>Compile returns to frames below the start frame.</li>
359<li>Improve alias analysis of upvalues using a disambiguation hash value.</li>
360<li>Compile floor/ceil/trunc to SSE2 helper calls or SSE4.1 instructions.</li>
361<li>Add generic C call handling to IR and backend.</li>
362<li>Improve KNUM fuse vs. load heuristics.</li>
363<li>Compile various <tt>io.*()</tt> functions.</li>
364<li>Compile <tt>math.sinh()</tt>, <tt>math.cosh()</tt>, <tt>math.tanh()</tt>
365and <tt>math.random()</tt>.</li>
366</ul></li>
367</ul>
368
369<h2 id="LuaJIT-2.0.0-beta2">LuaJIT 2.0.0-beta2 &mdash; 2009-11-09</h2>
370<ul>
371<li>Reorganize build system. Build static+shared library on POSIX.</li>
372<li>Allow C++ exception conversion on all platforms
373using a wrapper function.</li>
374<li>Automatically catch C++ exceptions and rethrow Lua error
375(DWARF2 only).</li>
376<li>Check for the correct x87 FPU precision at strategic points.</li>
377<li>Always use wrappers for libm functions.</li>
378<li>Resurrect metamethod name strings before copying them.</li>
379<li>Mark current trace, even if compiler is idle.</li>
380<li>Ensure FILE metatable is created only once.</li>
381<li>Fix type comparisons when different integer types are involved.</li>
382<li>Fix <tt>getmetatable()</tt> recording.</li>
383<li>Fix TDUP with dead keys in template table.</li>
384<li><tt>jit.flush(tr)</tt> returns status.
385Prevent manual flush of a trace that's still linked.</li>
386<li>Improve register allocation heuristics for invariant references.</li>
387<li>Compile the push/pop variants of <tt>table.insert()</tt> and
388<tt>table.remove()</tt>.</li>
389<li>Compatibility with MSVC <tt>link&nbsp/debug</tt>.</li>
390<li>Fix <tt>lua_iscfunction()</tt>.</li>
391<li>Fix <tt>math.random()</tt> when compiled with <tt>-fpic</tt> (OSX).</li>
392<li>Fix <tt>table.maxn()</tt>.</li>
393<li>Bump <tt>MACOSX_DEPLOYMENT_TARGET</tt> to <tt>10.4</tt></li>
394<li><tt>luaL_check*()</tt> and <tt>luaL_opt*()</tt> now support
395negative arguments, too.<br>
396This matches the behavior of Lua 5.1, but not the specification.</li>
397</ul>
398
399<h2 id="LuaJIT-2.0.0-beta1">LuaJIT 2.0.0-beta1 &mdash; 2009-10-31</h2>
400<ul>
401<li>This is the first public release of LuaJIT 2.0.</li>
402<li>The whole VM has been rewritten from the ground up, so there's
403no point in listing differences over earlier versions.</li>
404</ul>
405</div>
406
407<div class="major" style="background: #d0d0ff;">
408<h2 id="LuaJIT-1.1.7">LuaJIT 1.1.7 &mdash; 2011-05-05</h2>
409<ul>
410<li>Added fixes for the
411<a href="http://www.lua.org/bugs.html#5.1.4"><span class="ext">&raquo;</span>&nbsp;currently known bugs in Lua 5.1.4</a>.</li>
412</ul>
413
414<h2 id="LuaJIT-1.1.6">LuaJIT 1.1.6 &mdash; 2010-03-28</h2>
415<ul>
416<li>Added fixes for the
417<a href="http://www.lua.org/bugs.html#5.1.4"><span class="ext">&raquo;</span>&nbsp;currently known bugs in Lua 5.1.4</a>.</li>
418<li>Removed wrong GC check in <tt>jit_createstate()</tt>.
419Thanks to Tim Mensch.</li>
420<li>Fixed bad assertions while compiling <tt>table.insert()</tt> and
421<tt>table.remove()</tt>.</li>
422</ul>
423
424<h2 id="LuaJIT-1.1.5">LuaJIT 1.1.5 &mdash; 2008-10-25</h2>
425<ul>
426<li>Merged with Lua 5.1.4. Fixes all
427<a href="http://www.lua.org/bugs.html#5.1.3"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.3</a>.</li>
428</ul>
429
430<h2 id="LuaJIT-1.1.4">LuaJIT 1.1.4 &mdash; 2008-02-05</h2>
431<ul>
432<li>Merged with Lua 5.1.3. Fixes all
433<a href="http://www.lua.org/bugs.html#5.1.2"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.2</a>.</li>
434<li>Fixed possible (but unlikely) stack corruption while compiling
435<tt>k^x</tt> expressions.</li>
436<li>Fixed DynASM template for cmpss instruction.</li>
437</ul>
438
439<h2 id="LuaJIT-1.1.3">LuaJIT 1.1.3 &mdash; 2007-05-24</h2>
440<ul>
441<li>Merged with Lua 5.1.2. Fixes all
442<a href="http://www.lua.org/bugs.html#5.1.1"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1.1</a>.</li>
443<li>Merged pending Lua 5.1.x fixes: "return -nil" bug, spurious count hook call.</li>
444<li>Remove a (sometimes) wrong assertion in <tt>luaJIT_findpc()</tt>.</li>
445<li>DynASM now allows labels for displacements and <tt>.aword</tt>.</li>
446<li>Fix some compiler warnings for DynASM glue (internal API change).</li>
447<li>Correct naming for SSSE3 (temporarily known as SSE4) in DynASM and x86 disassembler.</li>
448<li>The loadable debug modules now handle redirection to stdout
449(e.g. <tt>-j&nbsp;trace=-</tt>).</li>
450</ul>
451
452<h2 id="LuaJIT-1.1.2">LuaJIT 1.1.2 &mdash; 2006-06-24</h2>
453<ul>
454<li>Fix MSVC inline assembly: use only local variables with
455<tt>lua_number2int()</tt>.</li>
456<li>Fix "attempt to call a thread value" bug on Mac OS X:
457make values of consts used as lightuserdata keys unique
458to avoid joining by the compiler/linker.</li>
459</ul>
460
461<h2 id="LuaJIT-1.1.1">LuaJIT 1.1.1 &mdash; 2006-06-20</h2>
462<ul>
463<li>Merged with Lua 5.1.1. Fixes all
464<a href="http://www.lua.org/bugs.html#5.1"><span class="ext">&raquo;</span>&nbsp;known bugs in Lua 5.1</a>.</li>
465<li>Enforce (dynamic) linker error for EXE/DLL version mismatches.</li>
466<li>Minor changes to DynASM: faster pre-processing, smaller encoding
467for some immediates.</li>
468</ul>
469<p>
470This release is in sync with Coco 1.1.1 (see the
471<a href="http://coco.luajit.org/changes.html"><span class="ext">&raquo;</span>&nbsp;Coco Change History</a>).
472</p>
473
474<h2 id="LuaJIT-1.1.0">LuaJIT 1.1.0 &mdash; 2006-03-13</h2>
475<ul>
476<li>Merged with Lua 5.1 (final).</li>
477
478<li>New JIT call frame setup:
479<ul>
480<li>The C stack is kept 16 byte aligned (faster).
481Mandatory for Mac OS X on Intel, too.</li>
482<li>Faster calling conventions for internal C helper functions.</li>
483<li>Better instruction scheduling for function prologue, OP_CALL and
484OP_RETURN.</li>
485</ul></li>
486
487<li>Miscellaneous optimizations:
488<ul>
489<li>Faster loads of FP constants. Remove narrow-to-wide store-to-load
490forwarding stalls.</li>
491<li>Use (scalar) SSE2 ops (if the CPU supports it) to speed up slot moves
492and FP to integer conversions.</li>
493<li>Optimized the two-argument form of <tt>OP_CONCAT</tt> (<tt>a..b</tt>).</li>
494<li>Inlined <tt>OP_MOD</tt> (<tt>a%b</tt>).
495With better accuracy than the C variant, too.</li>
496<li>Inlined <tt>OP_POW</tt> (<tt>a^b</tt>). Unroll <tt>x^k</tt> or
497use <tt>k^x = 2^(log2(k)*x)</tt> or call <tt>pow()</tt>.</li>
498</ul></li>
499
500<li>Changes in the optimizer:
501<ul>
502<li>Improved hinting for table keys derived from table values
503(<tt>t1[t2[x]]</tt>).</li>
504<li>Lookup hinting now works with arbitrary object types and
505supports index chains, too.</li>
506<li>Generate type hints for arithmetic and comparison operators,
507OP_LEN, OP_CONCAT and OP_FORPREP.</li>
508<li>Remove several hint definitions in favour of a generic COMBINE hint.</li>
509<li>Complete rewrite of <tt>jit.opt_inline</tt> module
510(ex <tt>jit.opt_lib</tt>).</li>
511</ul></li>
512
513<li>Use adaptive deoptimization:
514<ul>
515<li>If runtime verification of a contract fails, the affected
516instruction is recompiled and patched on-the-fly.
517Regular programs will trigger deoptimization only occasionally.</li>
518<li>This avoids generating code for uncommon fallback cases
519most of the time. Generated code is up to 30% smaller compared to
520LuaJIT&nbsp;1.0.3.</li>
521<li>Deoptimization is used for many opcodes and contracts:
522<ul>
523<li>OP_CALL, OP_TAILCALL: type mismatch for callable.</li>
524<li>Inlined calls: closure mismatch, parameter number and type mismatches.</li>
525<li>OP_GETTABLE, OP_SETTABLE: table or key type and range mismatches.</li>
526<li>All arithmetic and comparison operators, OP_LEN, OP_CONCAT,
527OP_FORPREP: operand type and range mismatches.</li>
528</ul></li>
529<li>Complete redesign of the debug and traceback info
530(bytecode &harr; mcode) to support deoptimization.
531Much more flexible and needs only 50% of the space.</li>
532<li>The modules <tt>jit.trace</tt>, <tt>jit.dumphints</tt> and
533<tt>jit.dump</tt> handle deoptimization.</li>
534</ul></li>
535
536<li>Inlined many popular library functions
537(for commonly used arguments only):
538<ul>
539<li>Most <tt>math.*</tt> functions (the 18 most used ones)
540[2x-10x faster].</li>
541<li><tt>string.len</tt>, <tt>string.sub</tt> and <tt>string.char</tt>
542[2x-10x faster].</li>
543<li><tt>table.insert</tt>, <tt>table.remove</tt> and <tt>table.getn</tt>
544[3x-5x faster].</li>
545<li><tt>coroutine.yield</tt> and <tt>coroutine.resume</tt>
546[3x-5x faster].</li>
547<li><tt>pairs</tt>, <tt>ipairs</tt> and the corresponding iterators
548[8x-15x faster].</li>
549</ul></li>
550
551<li>Changes in the core and loadable modules and the stand-alone executable:
552<ul>
553<li>Added <tt>jit.version</tt>, <tt>jit.version_num</tt>
554and <tt>jit.arch</tt>.</li>
555<li>Reorganized some internal API functions (<tt>jit.util.*mcode*</tt>).</li>
556<li>The <tt>-j dump</tt> output now shows JSUB names, too.</li>
557<li>New x86 disassembler module written in pure Lua. No dependency
558on ndisasm anymore. Flexible API, very compact (500 lines)
559and complete (x87, MMX, SSE, SSE2, SSE3, SSSE3, privileged instructions).</li>
560<li><tt>luajit -v</tt> prints the LuaJIT version and copyright
561on a separate line.</li>
562</ul></li>
563
564<li>Added SSE, SSE2, SSE3 and SSSE3 support to DynASM.</li>
565<li>Miscellaneous doc changes. Added a section about
566<a href="install.html#embedding">embedding LuaJIT</a>.</li>
567</ul>
568<p>
569This release is in sync with Coco 1.1.0 (see the
570<a href="http://coco.luajit.org/changes.html"><span class="ext">&raquo;</span>&nbsp;Coco Change History</a>).
571</p>
572</div>
573
574<div class="major" style="background: #ffffd0;">
575<h2 id="LuaJIT-1.0.3">LuaJIT 1.0.3 &mdash; 2005-09-08</h2>
576<ul>
577<li>Even more docs.</li>
578<li>Unified closure checks in <tt>jit.*</tt>.</li>
579<li>Fixed some range checks in <tt>jit.util.*</tt>.</li>
580<li>Fixed __newindex call originating from <tt>jit_settable_str()</tt>.</li>
581<li>Merged with Lua 5.1 alpha (including early bug fixes).</li>
582</ul>
583<p>
584This is the first public release of LuaJIT.
585</p>
586
587<h2 id="LuaJIT-1.0.2">LuaJIT 1.0.2 &mdash; 2005-09-02</h2>
588<ul>
589<li>Add support for flushing the Valgrind translation cache <br>
590(<tt>MYCFLAGS= -DUSE_VALGRIND</tt>).</li>
591<li>Add support for freeing executable mcode memory to the <tt>mmap()</tt>-based
592variant for POSIX systems.</li>
593<li>Reorganized the C&nbsp;function signature handling in
594<tt>jit.opt_lib</tt>.</li>
595<li>Changed to index-based hints for inlining C&nbsp;functions.
596Still no support in the backend for inlining.</li>
597<li>Hardcode <tt>HEAP_CREATE_ENABLE_EXECUTE</tt> value if undefined.</li>
598<li>Misc. changes to the <tt>jit.*</tt> modules.</li>
599<li>Misc. changes to the Makefiles.</li>
600<li>Lots of new docs.</li>
601<li>Complete doc reorg.</li>
602</ul>
603<p>
604Not released because Lua 5.1 alpha came out today.
605</p>
606
607<h2 id="LuaJIT-1.0.1">LuaJIT 1.0.1 &mdash; 2005-08-31</h2>
608<ul>
609<li>Missing GC step in <tt>OP_CONCAT</tt>.</li>
610<li>Fix result handling for C &ndash;> JIT calls.</li>
611<li>Detect CPU feature bits.</li>
612<li>Encode conditional moves (<tt>fucomip</tt>) only when supported.</li>
613<li>Add fallback instructions for FP compares.</li>
614<li>Add support for <tt>LUA_COMPAT_VARARG</tt>. Still disabled by default.</li>
615<li>MSVC needs a specific place for the <tt>CALLBACK</tt> attribute
616(David Burgess).</li>
617<li>Misc. doc updates.</li>
618</ul>
619<p>
620Interim non-public release.
621Special thanks to Adam D. Moss for reporting most of the bugs.
622</p>
623
624<h2 id="LuaJIT-1.0.0">LuaJIT 1.0.0 &mdash; 2005-08-29</h2>
625<p>
626This is the initial non-public release of LuaJIT.
627</p>
628</div>
629<br class="flush">
630</div>
631<div id="foot">
632<hr class="hide">
633Copyright &copy; 2005-2011 Mike Pall
634<span class="noprint">
635&middot;
636<a href="contact.html">Contact</a>
637</span>
638</div>
639</body>
640</html>
diff --git a/libraries/luajit-2.0/doc/contact.html b/libraries/luajit-2.0/doc/contact.html
new file mode 100644
index 0000000..a85c488
--- /dev/null
+++ b/libraries/luajit-2.0/doc/contact.html
@@ -0,0 +1,98 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Contact</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Contact</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="luajit.html">LuaJIT</a>
22<ul><li>
23<a href="install.html">Installation</a>
24</li><li>
25<a href="running.html">Running</a>
26</li></ul>
27</li><li>
28<a href="extensions.html">Extensions</a>
29<ul><li>
30<a href="ext_ffi.html">FFI Library</a>
31<ul><li>
32<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
33</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li>
36<a href="ext_ffi_semantics.html">FFI Semantics</a>
37</li></ul>
38</li><li>
39<a href="ext_jit.html">jit.* Library</a>
40</li><li>
41<a href="ext_c_api.html">Lua/C API</a>
42</li></ul>
43</li><li>
44<a href="status.html">Status</a>
45<ul><li>
46<a href="changes.html">Changes</a>
47</li></ul>
48</li><li>
49<a href="faq.html">FAQ</a>
50</li><li>
51<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
52</li><li>
53<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
54</li></ul>
55</div>
56<div id="main">
57<p>
58Please send general questions to the
59<a href="http://www.lua.org/lua-l.html"><span class="ext">&raquo;</span>&nbsp;Lua mailing list</a>.
60You can also send any questions you have directly to me:
61</p>
62
63<script type="text/javascript">
64<!--
65var xS="@-:\" .0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ<abc>defghijklmnopqrstuvwxyz";function xD(s)
66{var len=s.length;var r="";for(var i=0;i<len;i++)
67{var c=s.charAt(i);var n=xS.indexOf(c);if(n!=-1)c=xS.charAt(69-n);r+=c;}
68document.write("<"+"p>"+r+"<"+"/p>\n");}
69//-->
70</script>
71<script type="text/javascript">
72<!--
73xD("fyZKB8xv\"FJytmz8.KAB0u52D")
74//--></script>
75<noscript>
76<p><img src="img/contact.png" alt="Contact info in image" width="170" height="13">
77</p>
78</noscript>
79
80<h2>Copyright</h2>
81<p>
82All documentation is
83Copyright &copy; 2005-2011 Mike Pall.
84</p>
85
86
87<br class="flush">
88</div>
89<div id="foot">
90<hr class="hide">
91Copyright &copy; 2005-2011 Mike Pall
92<span class="noprint">
93&middot;
94<a href="contact.html">Contact</a>
95</span>
96</div>
97</body>
98</html>
diff --git a/libraries/luajit-2.0/doc/ext_c_api.html b/libraries/luajit-2.0/doc/ext_c_api.html
new file mode 100644
index 0000000..35e2234
--- /dev/null
+++ b/libraries/luajit-2.0/doc/ext_c_api.html
@@ -0,0 +1,183 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Lua/C API Extensions</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1>Lua/C API Extensions</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="luajit.html">LuaJIT</a>
22<ul><li>
23<a href="install.html">Installation</a>
24</li><li>
25<a href="running.html">Running</a>
26</li></ul>
27</li><li>
28<a href="extensions.html">Extensions</a>
29<ul><li>
30<a href="ext_ffi.html">FFI Library</a>
31<ul><li>
32<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
33</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li>
36<a href="ext_ffi_semantics.html">FFI Semantics</a>
37</li></ul>
38</li><li>
39<a href="ext_jit.html">jit.* Library</a>
40</li><li>
41<a class="current" href="ext_c_api.html">Lua/C API</a>
42</li></ul>
43</li><li>
44<a href="status.html">Status</a>
45<ul><li>
46<a href="changes.html">Changes</a>
47</li></ul>
48</li><li>
49<a href="faq.html">FAQ</a>
50</li><li>
51<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
52</li><li>
53<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
54</li></ul>
55</div>
56<div id="main">
57<p>
58LuaJIT adds some extensions to the standard Lua/C API. The LuaJIT include
59directory must be in the compiler search path (<tt>-I<i>path</i></tt>)
60to be able to include the required header for C code:
61</p>
62<pre class="code">
63#include "luajit.h"
64</pre>
65<p>
66Or for C++ code:
67</p>
68<pre class="code">
69#include "lua.hpp"
70</pre>
71
72<h2 id="luaJIT_setmode"><tt>luaJIT_setmode(L, idx, mode)</tt>
73&mdash; Control VM</h2>
74<p>
75This is a C API extension to allow control of the VM from C code. The
76full prototype of <tt>LuaJIT_setmode</tt> is:
77</p>
78<pre class="code">
79LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
80</pre>
81<p>
82The returned status is either success (<tt>1</tt>) or failure (<tt>0</tt>).
83The second argument is either <tt>0</tt> or a stack index (similar to the
84other Lua/C API functions).
85</p>
86<p>
87The third argument specifies the mode, which is 'or'ed with a flag.
88The flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature on,
89<tt>LUAJIT_MODE_ON</tt> to turn a feature off, or
90<tt>LUAJIT_MODE_FLUSH</tt> to flush cached code.
91</p>
92<p>
93The following modes are defined:
94</p>
95
96<h3 id="mode_engine"><tt>luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)</tt></h3>
97<p>
98Turn the whole JIT compiler on or off or flush the whole cache of compiled code.
99</p>
100
101<h3 id="mode_func"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)</tt><br>
102<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)</tt><br>
103<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)</tt></h3>
104<p>
105This sets the mode for the function at the stack index <tt>idx</tt> or
106the parent of the calling function (<tt>idx = 0</tt>). It either
107enables JIT compilation for a function, disables it and flushes any
108already compiled code or only flushes already compiled code. This
109applies recursively to all sub-functions of the function with
110<tt>LUAJIT_MODE_ALLFUNC</tt> or only to the sub-functions with
111<tt>LUAJIT_MODE_ALLSUBFUNC</tt>.
112</p>
113
114<h3 id="mode_trace"><tt>luaJIT_setmode(L, trace,<br>
115&nbsp;&nbsp;LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)</tt></h3>
116<p>
117Flushes the specified root trace and all of its side traces from the cache.
118The code for the trace will be retained as long as there are any other
119traces which link to it.
120</p>
121
122<h3 id="mode_wrapcfunc"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)</tt></h3>
123<p>
124This mode defines a wrapper function for calls to C functions. If
125called with <tt>LUAJIT_MODE_ON</tt>, the stack index at <tt>idx</tt>
126must be a <tt>lightuserdata</tt> object holding a pointer to the wrapper
127function. From now on all C functions are called through the wrapper
128function. If called with <tt>LUAJIT_MODE_OFF</tt> this mode is turned
129off and all C functions are directly called.
130</p>
131<p>
132The wrapper function can be used for debugging purposes or to catch
133and convert foreign exceptions. But please read the section on
134<a href="extensions.html#exceptions">C++&nbsp;exception interoperability</a>
135first. Recommended usage can be seen in this C++ code excerpt:
136</p>
137<pre class="code">
138#include &lt;exception&gt;
139#include "lua.hpp"
140
141// Catch C++ exceptions and convert them to Lua error messages.
142// Customize as needed for your own exception classes.
143static int wrap_exceptions(lua_State *L, lua_CFunction f)
144{
145 try {
146 return f(L); // Call wrapped function and return result.
147 } catch (const char *s) { // Catch and convert exceptions.
148 lua_pushstring(L, s);
149 } catch (std::exception& e) {
150 lua_pushstring(L, e.what());
151 } catch (...) {
152 lua_pushliteral(L, "caught (...)");
153 }
154 return lua_error(L); // Rethrow as a Lua error.
155}
156
157static int myinit(lua_State *L)
158{
159 ...
160 // Define wrapper function and enable it.
161 lua_pushlightuserdata(L, (void *)wrap_exceptions);
162 luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
163 lua_pop(L, 1);
164 ...
165}
166</pre>
167<p>
168Note that you can only define <b>a single global wrapper function</b>,
169so be careful when using this mechanism from multiple C++ modules.
170Also note that this mechanism is not without overhead.
171</p>
172<br class="flush">
173</div>
174<div id="foot">
175<hr class="hide">
176Copyright &copy; 2005-2011 Mike Pall
177<span class="noprint">
178&middot;
179<a href="contact.html">Contact</a>
180</span>
181</div>
182</body>
183</html>
diff --git a/libraries/luajit-2.0/doc/ext_ffi.html b/libraries/luajit-2.0/doc/ext_ffi.html
new file mode 100644
index 0000000..9b59a3f
--- /dev/null
+++ b/libraries/luajit-2.0/doc/ext_ffi.html
@@ -0,0 +1,332 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>FFI Library</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12span.codemark { position:absolute; left: 16em; color: #4040c0; }
13span.mark { color: #4040c0; font-family: Courier New, Courier, monospace;
14 line-height: 1.1; }
15pre.mark { padding-left: 2em; }
16</style>
17</head>
18<body>
19<div id="site">
20<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
21</div>
22<div id="head">
23<h1>FFI Library</h1>
24</div>
25<div id="nav">
26<ul><li>
27<a href="luajit.html">LuaJIT</a>
28<ul><li>
29<a href="install.html">Installation</a>
30</li><li>
31<a href="running.html">Running</a>
32</li></ul>
33</li><li>
34<a href="extensions.html">Extensions</a>
35<ul><li>
36<a class="current" href="ext_ffi.html">FFI Library</a>
37<ul><li>
38<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
39</li><li>
40<a href="ext_ffi_api.html">ffi.* API</a>
41</li><li>
42<a href="ext_ffi_semantics.html">FFI Semantics</a>
43</li></ul>
44</li><li>
45<a href="ext_jit.html">jit.* Library</a>
46</li><li>
47<a href="ext_c_api.html">Lua/C API</a>
48</li></ul>
49</li><li>
50<a href="status.html">Status</a>
51<ul><li>
52<a href="changes.html">Changes</a>
53</li></ul>
54</li><li>
55<a href="faq.html">FAQ</a>
56</li><li>
57<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
58</li><li>
59<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
60</li></ul>
61</div>
62<div id="main">
63<p>
64
65The FFI library allows <b>calling external C&nbsp;functions</b> and
66<b>using C&nbsp;data structures</b> from pure Lua code.
67
68</p>
69<p>
70
71The FFI library largely obviates the need to write tedious manual
72Lua/C bindings in C. No need to learn a separate binding language
73&mdash; <b>it parses plain C&nbsp;declarations!</b> These can be
74cut-n-pasted from C&nbsp;header files or reference manuals. It's up to
75the task of binding large libraries without the need for dealing with
76fragile binding generators.
77
78</p>
79<p>
80The FFI library is tightly integrated into LuaJIT (it's not available
81as a separate module). The code generated by the JIT-compiler for
82accesses to C&nbsp;data structures from Lua code is on par with the
83code a C&nbsp;compiler would generate. Calls to C&nbsp;functions can
84be inlined in JIT-compiled code, unlike calls to functions bound via
85the classic Lua/C API.
86</p>
87<p>
88This page gives a short introduction to the usage of the FFI library.
89<em>Please use the FFI sub-topics in the navigation bar to learn more.</em>
90</p>
91
92<h2 id="call">Motivating Example: Calling External C Functions</h2>
93<p>
94It's really easy to call an external C&nbsp;library function:
95</p>
96<pre class="code mark">
97<span class="codemark">&#9312;
98&#9313;
99
100
101&#9314;</span>local ffi = require("ffi")
102ffi.cdef[[
103<span style="color:#00a000;">int printf(const char *fmt, ...);</span>
104]]
105ffi.C.printf("Hello %s!", "world")
106</pre>
107<p>
108So, let's pick that apart:
109</p>
110<p>
111<span class="mark">&#9312;</span> Load the FFI library.
112</p>
113<p>
114<span class="mark">&#9313;</span> Add a C&nbsp;declaration
115for the function. The part inside the double-brackets (in green) is
116just standard C&nbsp;syntax.
117</p>
118<p>
119<span class="mark">&#9314;</span> Call the named
120C&nbsp;function &mdash; Yes, it's that simple!
121</p>
122<p style="font-size: 8pt;">
123Actually, what goes on behind the scenes is far from simple: <span
124style="color:#4040c0;">&#9314;</span> makes use of the standard
125C&nbsp;library namespace <tt>ffi.C</tt>. Indexing this namespace with
126a symbol name (<tt>"printf"</tt>) automatically binds it to the the
127standard C&nbsp;library. The result is a special kind of object which,
128when called, runs the <tt>printf</tt> function. The arguments passed
129to this function are automatically converted from Lua objects to the
130corresponding C&nbsp;types.
131</p>
132<p>
133Ok, so maybe the use of <tt>printf()</tt> wasn't such a spectacular
134example. You could have done that with <tt>io.write()</tt> and
135<tt>string.format()</tt>, too. But you get the idea ...
136</p>
137<p>
138So here's something to pop up a message box on Windows:
139</p>
140<pre class="code">
141local ffi = require("ffi")
142ffi.cdef[[
143<span style="color:#00a000;">int MessageBoxA(void *w, const char *txt, const char *cap, int type);</span>
144]]
145ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0)
146</pre>
147<p>
148Bing! Again, that was far too easy, no?
149</p>
150<p style="font-size: 8pt;">
151Compare this with the effort required to bind that function using the
152classic Lua/C API: create an extra C&nbsp;file, add a C&nbsp;function
153that retrieves and checks the argument types passed from Lua and calls
154the actual C&nbsp;function, add a list of module functions and their
155names, add a <tt>luaopen_*</tt> function and register all module
156functions, compile and link it into a shared library (DLL), move it to
157the proper path, add Lua code that loads the module aaaand ... finally
158call the binding function. Phew!
159</p>
160
161<h2 id="cdata">Motivating Example: Using C Data Structures</h2>
162<p>
163The FFI library allows you to create and access C&nbsp;data
164structures. Of course the main use for this is for interfacing with
165C&nbsp;functions. But they can be used stand-alone, too.
166</p>
167<p>
168Lua is built upon high-level data types. They are flexible, extensible
169and dynamic. That's why we all love Lua so much. Alas, this can be
170inefficient for certain tasks, where you'd really want a low-level
171data type. E.g. a large array of a fixed structure needs to be
172implemented with a big table holding lots of tiny tables. This imposes
173both a substantial memory overhead as well as a performance overhead.
174</p>
175<p>
176Here's a sketch of a library that operates on color images plus a
177simple benchmark. First, the plain Lua version:
178</p>
179<pre class="code">
180local floor = math.floor
181
182local function image_ramp_green(n)
183 local img = {}
184 local f = 255/(n-1)
185 for i=1,n do
186 img[i] = { red = 0, green = floor((i-1)*f), blue = 0, alpha = 255 }
187 end
188 return img
189end
190
191local function image_to_grey(img, n)
192 for i=1,n do
193 local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)
194 img[i].red = y; img[i].green = y; img[i].blue = y
195 end
196end
197
198local N = 400*400
199local img = image_ramp_green(N)
200for i=1,1000 do
201 image_to_grey(img, N)
202end
203</pre>
204<p>
205This creates a table with 160.000 pixels, each of which is a table
206holding four number values in the range of 0-255. First an image with
207a green ramp is created (1D for simplicity), then the image is
208converted to greyscale 1000 times. Yes, that's silly, but I was in
209need of a simple example ...
210</p>
211<p>
212And here's the FFI version. The modified parts have been marked in
213bold:
214</p>
215<pre class="code mark">
216<span class="codemark">&#9312;
217
218
219
220
221
222&#9313;
223
224&#9314;
225&#9315;
226
227
228
229
230
231
232&#9314;
233&#9316;</span><b>local ffi = require("ffi")
234ffi.cdef[[
235</b><span style="color:#00a000;">typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;</span><b>
236]]</b>
237
238local function image_ramp_green(n)
239 <b>local img = ffi.new("rgba_pixel[?]", n)</b>
240 local f = 255/(n-1)
241 for i=<b>0,n-1</b> do
242 <b>img[i].green = i*f</b>
243 <b>img[i].alpha = 255</b>
244 end
245 return img
246end
247
248local function image_to_grey(img, n)
249 for i=<b>0,n-1</b> do
250 local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b>
251 img[i].red = y; img[i].green = y; img[i].blue = y
252 end
253end
254
255local N = 400*400
256local img = image_ramp_green(N)
257for i=1,1000 do
258 image_to_grey(img, N)
259end
260</pre>
261<p>
262Ok, so that wasn't too difficult:
263</p>
264<p>
265<span class="mark">&#9312;</span> First, load the FFI
266library and declare the low-level data type. Here we choose a
267<tt>struct</tt> which holds four byte fields, one for each component
268of a 4x8&nbsp;bit RGBA pixel.
269</p>
270<p>
271<span class="mark">&#9313;</span> Creating the data
272structure with <tt>ffi.new()</tt> is straightforward &mdash; the
273<tt>'?'</tt> is a placeholder for the number of elements of a
274variable-length array.
275</p>
276<p>
277<span class="mark">&#9314;</span> C&nbsp;arrays are
278zero-based, so the indexes have to run from <tt>0</tt> to
279<tt>n-1</tt>. One might want to allocate one more element instead to
280simplify converting legacy code.
281</p>
282<p>
283<span class="mark">&#9315;</span> Since <tt>ffi.new()</tt>
284zero-fills the array by default, we only need to set the green and the
285alpha fields.
286</p>
287<p>
288<span class="mark">&#9316;</span> The calls to
289<tt>math.floor()</tt> can be omitted here, because floating-point
290numbers are already truncated towards zero when converting them to an
291integer. This happens implicitly when the number is stored in the
292fields of each pixel.
293</p>
294<p>
295Now let's have a look at the impact of the changes: first, memory
296consumption for the image is down from 22&nbsp;Megabytes to
297640&nbsp;Kilobytes (400*400*4 bytes). That's a factor of 35x less! So,
298yes, tables do have a noticeable overhead. BTW: The original program
299would consume 40&nbsp;Megabytes in plain Lua (on x64).
300</p>
301<p>
302Next, performance: the pure Lua version runs in 9.57 seconds (52.9
303seconds with the Lua interpreter) and the FFI version runs in 0.48
304seconds on my machine (YMMV). That's a factor of 20x faster (110x
305faster than the Lua interpreter).
306</p>
307<p style="font-size: 8pt;">
308The avid reader may notice that converting the pure Lua version over
309to use array indexes for the colors (<tt>[1]</tt> instead of
310<tt>.red</tt>, <tt>[2]</tt> instead of <tt>.green</tt> etc.) ought to
311be more compact and faster. This is certainly true (by a factor of
312~1.7x). Switching to a struct-of-arrays would help, too.
313</p>
314<p style="font-size: 8pt;">
315However the resulting code would be less idiomatic and rather
316error-prone. And it still doesn't get even close to the performance of
317the FFI version of the code. Also, high-level data structures cannot
318be easily passed to other C&nbsp;functions, especially I/O functions,
319without undue conversion penalties.
320</p>
321<br class="flush">
322</div>
323<div id="foot">
324<hr class="hide">
325Copyright &copy; 2005-2011 Mike Pall
326<span class="noprint">
327&middot;
328<a href="contact.html">Contact</a>
329</span>
330</div>
331</body>
332</html>
diff --git a/libraries/luajit-2.0/doc/ext_ffi_api.html b/libraries/luajit-2.0/doc/ext_ffi_api.html
new file mode 100644
index 0000000..222c580
--- /dev/null
+++ b/libraries/luajit-2.0/doc/ext_ffi_api.html
@@ -0,0 +1,553 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>ffi.* API Functions</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.abitable { width: 30em; line-height: 1.2; }
13tr.abihead td { font-weight: bold; }
14td.abiparam { font-weight: bold; width: 6em; }
15</style>
16</head>
17<body>
18<div id="site">
19<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
20</div>
21<div id="head">
22<h1><tt>ffi.*</tt> API Functions</h1>
23</div>
24<div id="nav">
25<ul><li>
26<a href="luajit.html">LuaJIT</a>
27<ul><li>
28<a href="install.html">Installation</a>
29</li><li>
30<a href="running.html">Running</a>
31</li></ul>
32</li><li>
33<a href="extensions.html">Extensions</a>
34<ul><li>
35<a href="ext_ffi.html">FFI Library</a>
36<ul><li>
37<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
38</li><li>
39<a class="current" href="ext_ffi_api.html">ffi.* API</a>
40</li><li>
41<a href="ext_ffi_semantics.html">FFI Semantics</a>
42</li></ul>
43</li><li>
44<a href="ext_jit.html">jit.* Library</a>
45</li><li>
46<a href="ext_c_api.html">Lua/C API</a>
47</li></ul>
48</li><li>
49<a href="status.html">Status</a>
50<ul><li>
51<a href="changes.html">Changes</a>
52</li></ul>
53</li><li>
54<a href="faq.html">FAQ</a>
55</li><li>
56<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
57</li><li>
58<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59</li></ul>
60</div>
61<div id="main">
62<p>
63This page describes the API functions provided by the FFI library in
64detail. It's recommended to read through the
65<a href="ext_ffi.html">introduction</a> and the
66<a href="ext_ffi_tutorial.html">FFI tutorial</a> first.
67</p>
68
69<h2 id="glossary">Glossary</h2>
70<ul>
71<li><b>cdecl</b> &mdash; An abstract C&nbsp;type declaration (a Lua
72string).</li>
73<li><b>ctype</b> &mdash; A C&nbsp;type object. This is a special kind of
74<b>cdata</b> returned by <tt>ffi.typeof()</tt>. It serves as a
75<b>cdata</b> <a href="#ffi_new">constructor</a> when called.</li>
76<li><b>cdata</b> &mdash; A C&nbsp;data object. It holds a value of the
77corresponding <b>ctype</b>.</li>
78<li><b>ct</b> &mdash; A C&nbsp;type specification which can be used for
79most of the API functions. Either a <b>cdecl</b>, a <b>ctype</b> or a
80<b>cdata</b> serving as a template type.</li>
81<li><b>cb</b> &mdash; A callback object. This is a C&nbsp;data object
82holding a special function pointer. Calling this function from
83C&nbsp;code runs an associated Lua function.</li>
84<li><b>VLA</b> &mdash; A variable-length array is declared with a
85<tt>?</tt> instead of the number of elements, e.g. <tt>"int[?]"</tt>.
86The number of elements (<tt>nelem</tt>) must be given when it's
87<a href="#ffi_new">created</a>.</li>
88<li><b>VLS</b> &mdash; A variable-length struct is a <tt>struct</tt> C
89type where the last element is a <b>VLA</b>. The same rules for
90declaration and creation apply.</li>
91</ul>
92
93<h2 id="decl">Declaring and Accessing External Symbols</h2>
94<p>
95External symbols must be declared first and can then be accessed by
96indexing a <a href="ext_ffi_semantics.html#clib">C&nbsp;library
97namespace</a>, which automatically binds the symbol to a specific
98library.
99</p>
100
101<h3 id="ffi_cdef"><tt>ffi.cdef(def)</tt></h3>
102<p>
103Adds multiple C&nbsp;declarations for types or external symbols (named
104variables or functions). <tt>def</tt> must be a Lua string. It's
105recommended to use the syntactic sugar for string arguments as
106follows:
107</p>
108<pre class="code">
109ffi.cdef[[
110<span style="color:#00a000;">typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
111int dofoo(foo_t *f, int n); /* Declare an external C function. */</span>
112]]
113</pre>
114<p>
115The contents of the string (the part in green above) must be a
116sequence of
117<a href="ext_ffi_semantics.html#clang">C&nbsp;declarations</a>,
118separated by semicolons. The trailing semicolon for a single
119declaration may be omitted.
120</p>
121<p>
122Please note that external symbols are only <em>declared</em>, but they
123are <em>not bound</em> to any specific address, yet. Binding is
124achieved with C&nbsp;library namespaces (see below).
125</p>
126<p style="color: #c00000;">
127C&nbsp;declarations are not passed through a C&nbsp;pre-processor,
128yet. No pre-processor tokens are allowed, except for
129<tt>#pragma&nbsp;pack</tt>. Replace <tt>#define</tt> in existing
130C&nbsp;header files with <tt>enum</tt>, <tt>static&nbsp;const</tt>
131or <tt>typedef</tt> and/or pass the files through an external
132C&nbsp;pre-processor (once). Be careful not to include unneeded or
133redundant declarations from unrelated header files.
134</p>
135
136<h3 id="ffi_C"><tt>ffi.C</tt></h3>
137<p>
138This is the default C&nbsp;library namespace &mdash; note the
139uppercase <tt>'C'</tt>. It binds to the default set of symbols or
140libraries on the target system. These are more or less the same as a
141C&nbsp;compiler would offer by default, without specifying extra link
142libraries.
143</p>
144<p>
145On POSIX systems, this binds to symbols in the default or global
146namespace. This includes all exported symbols from the executable and
147any libraries loaded into the global namespace. This includes at least
148<tt>libc</tt>, <tt>libm</tt>, <tt>libdl</tt> (on Linux),
149<tt>libgcc</tt> (if compiled with GCC), as well as any exported
150symbols from the Lua/C&nbsp;API provided by LuaJIT itself.
151</p>
152<p>
153On Windows systems, this binds to symbols exported from the
154<tt>*.exe</tt>, the <tt>lua51.dll</tt> (i.e. the Lua/C&nbsp;API
155provided by LuaJIT itself), the C&nbsp;runtime library LuaJIT was linked
156with (<tt>msvcrt*.dll</tt>), <tt>kernel32.dll</tt>,
157<tt>user32.dll</tt> and <tt>gdi32.dll</tt>.
158</p>
159
160<h3 id="ffi_load"><tt>clib = ffi.load(name [,global])</tt></h3>
161<p>
162This loads the dynamic library given by <tt>name</tt> and returns
163a new C&nbsp;library namespace which binds to its symbols. On POSIX
164systems, if <tt>global</tt> is <tt>true</tt>, the library symbols are
165loaded into the global namespace, too.
166</p>
167<p>
168If <tt>name</tt> is a path, the library is loaded from this path.
169Otherwise <tt>name</tt> is canonicalized in a system-dependent way and
170searched in the default search path for dynamic libraries:
171</p>
172<p>
173On POSIX systems, if the name contains no dot, the extension
174<tt>.so</tt> is appended. Also, the <tt>lib</tt> prefix is prepended
175if necessary. So <tt>ffi.load("z")</tt> looks for <tt>"libz.so"</tt>
176in the default shared library search path.
177</p>
178<p>
179On Windows systems, if the name contains no dot, the extension
180<tt>.dll</tt> is appended. So <tt>ffi.load("ws2_32")</tt> looks for
181<tt>"ws2_32.dll"</tt> in the default DLL search path.
182</p>
183
184<h2 id="create">Creating cdata Objects</h2>
185<p>
186The following API functions create cdata objects (<tt>type()</tt>
187returns <tt>"cdata"</tt>). All created cdata objects are
188<a href="ext_ffi_semantics.html#gc">garbage collected</a>.
189</p>
190
191<h3 id="ffi_new"><tt>cdata = ffi.new(ct [,nelem] [,init...])<br>
192cdata = <em>ctype</em>([nelem,] [init...])</tt></h3>
193<p>
194Creates a cdata object for the given <tt>ct</tt>. VLA/VLS types
195require the <tt>nelem</tt> argument. The second syntax uses a ctype as
196a constructor and is otherwise fully equivalent.
197</p>
198<p>
199The cdata object is initialized according to the
200<a href="ext_ffi_semantics.html#init">rules for initializers</a>,
201using the optional <tt>init</tt> arguments. Excess initializers cause
202an error.
203</p>
204<p>
205Performance notice: if you want to create many objects of one kind,
206parse the cdecl only once and get its ctype with
207<tt>ffi.typeof()</tt>. Then use the ctype as a constructor repeatedly.
208</p>
209<p style="font-size: 8pt;">
210Please note that an anonymous <tt>struct</tt> declaration implicitly
211creates a new and distinguished ctype every time you use it for
212<tt>ffi.new()</tt>. This is probably <b>not</b> what you want,
213especially if you create more than one cdata object. Different anonymous
214<tt>structs</tt> are not considered assignment-compatible by the
215C&nbsp;standard, even though they may have the same fields! Also, they
216are considered different types by the JIT-compiler, which may cause an
217excessive number of traces. It's strongly suggested to either declare
218a named <tt>struct</tt> or <tt>typedef</tt> with <tt>ffi.cdef()</tt>
219or to create a single ctype object for an anonymous <tt>struct</tt>
220with <tt>ffi.typeof()</tt>.
221</p>
222
223<h3 id="ffi_typeof"><tt>ctype = ffi.typeof(ct)</tt></h3>
224<p>
225Creates a ctype object for the given <tt>ct</tt>.
226</p>
227<p>
228This function is especially useful to parse a cdecl only once and then
229use the resulting ctype object as a <a href="#ffi_new">constructor</a>.
230</p>
231
232<h3 id="ffi_cast"><tt>cdata = ffi.cast(ct, init)</tt></h3>
233<p>
234Creates a scalar cdata object for the given <tt>ct</tt>. The cdata
235object is initialized with <tt>init</tt> using the "cast" variant of
236the <a href="ext_ffi_semantics.html#convert">C&nbsp;type conversion
237rules</a>.
238</p>
239<p>
240This functions is mainly useful to override the pointer compatibility
241checks or to convert pointers to addresses or vice versa.
242</p>
243
244<h3 id="ffi_metatype"><tt>ctype = ffi.metatype(ct, metatable)</tt></h3>
245<p>
246Creates a ctype object for the given <tt>ct</tt> and associates it with
247a metatable. Only <tt>struct</tt>/<tt>union</tt> types, complex numbers
248and vectors are allowed. Other types may be wrapped in a
249<tt>struct</tt>, if needed.
250</p>
251<p>
252The association with a metatable is permanent and cannot be changed
253afterwards. Neither the contents of the <tt>metatable</tt> nor the
254contents of an <tt>__index</tt> table (if any) may be modified
255afterwards. The associated metatable automatically applies to all uses
256of this type, no matter how the objects are created or where they
257originate from. Note that pre-defined operations on types have
258precedence (e.g. declared field names cannot be overriden).
259</p>
260<p>
261All standard Lua metamethods are implemented. These are called directly,
262without shortcuts and on any mix of types. For binary operations, the
263left operand is checked first for a valid ctype metamethod. The
264<tt>__gc</tt> metamethod only applies to <tt>struct</tt>/<tt>union</tt>
265types and performs an implicit <a href="#ffi_gc"><tt>ffi.gc()</tt></a>
266call during creation of an instance.
267</p>
268
269<h3 id="ffi_gc"><tt>cdata = ffi.gc(cdata, finalizer)</tt></h3>
270<p>
271Associates a finalizer with a pointer or aggregate cdata object. The
272cdata object is returned unchanged.
273</p>
274<p>
275This function allows safe integration of unmanaged resources into the
276automatic memory management of the LuaJIT garbage collector. Typical
277usage:
278</p>
279<pre class="code">
280local p = ffi.gc(ffi.C.malloc(n), ffi.C.free)
281...
282p = nil -- Last reference to p is gone.
283-- GC will eventually run finalizer: ffi.C.free(p)
284</pre>
285<p>
286A cdata finalizer works like the <tt>__gc</tt> metamethod for userdata
287objects: when the last reference to a cdata object is gone, the
288associated finalizer is called with the cdata object as an argument. The
289finalizer can be a Lua function or a cdata function or cdata function
290pointer. An existing finalizer can be removed by setting a <tt>nil</tt>
291finalizer, e.g. right before explicitly deleting a resource:
292</p>
293<pre class="code">
294ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.
295</pre>
296
297<h2 id="info">C&nbsp;Type Information</h2>
298<p>
299The following API functions return information about C&nbsp;types.
300They are most useful for inspecting cdata objects.
301</p>
302
303<h3 id="ffi_sizeof"><tt>size = ffi.sizeof(ct [,nelem])</tt></h3>
304<p>
305Returns the size of <tt>ct</tt> in bytes. Returns <tt>nil</tt> if
306the size is not known (e.g. for <tt>"void"</tt> or function types).
307Requires <tt>nelem</tt> for VLA/VLS types, except for cdata objects.
308</p>
309
310<h3 id="ffi_alignof"><tt>align = ffi.alignof(ct)</tt></h3>
311<p>
312Returns the minimum required alignment for <tt>ct</tt> in bytes.
313</p>
314
315<h3 id="ffi_offsetof"><tt>ofs [,bpos,bsize] = ffi.offsetof(ct, field)</tt></h3>
316<p>
317Returns the offset (in bytes) of <tt>field</tt> relative to the start
318of <tt>ct</tt>, which must be a <tt>struct</tt>. Additionally returns
319the position and the field size (in bits) for bit fields.
320</p>
321
322<h3 id="ffi_istype"><tt>status = ffi.istype(ct, obj)</tt></h3>
323<p>
324Returns <tt>true</tt> if <tt>obj</tt> has the C&nbsp;type given by
325<tt>ct</tt>. Returns <tt>false</tt> otherwise.
326</p>
327<p>
328C&nbsp;type qualifiers (<tt>const</tt> etc.) are ignored. Pointers are
329checked with the standard pointer compatibility rules, but without any
330special treatment for <tt>void&nbsp;*</tt>. If <tt>ct</tt> specifies a
331<tt>struct</tt>/<tt>union</tt>, then a pointer to this type is accepted,
332too. Otherwise the types must match exactly.
333</p>
334<p>
335Note: this function accepts all kinds of Lua objects for the
336<tt>obj</tt> argument, but always returns <tt>false</tt> for non-cdata
337objects.
338</p>
339
340<h2 id="util">Utility Functions</h2>
341
342<h3 id="ffi_errno"><tt>err = ffi.errno([newerr])</tt></h3>
343<p>
344Returns the error number set by the last C&nbsp;function call which
345indicated an error condition. If the optional <tt>newerr</tt> argument
346is present, the error number is set to the new value and the previous
347value is returned.
348</p>
349<p>
350This function offers a portable and OS-independent way to get and set the
351error number. Note that only <em>some</em> C&nbsp;functions set the error
352number. And it's only significant if the function actually indicated an
353error condition (e.g. with a return value of <tt>-1</tt> or
354<tt>NULL</tt>). Otherwise, it may or may not contain any previously set
355value.
356</p>
357<p>
358You're advised to call this function only when needed and as close as
359possible after the return of the related C&nbsp;function. The
360<tt>errno</tt> value is preserved across hooks, memory allocations,
361invocations of the JIT compiler and other internal VM activity. The same
362applies to the value returned by <tt>GetLastError()</tt> on Windows, but
363you need to declare and call it yourself.
364</p>
365
366<h3 id="ffi_string"><tt>str = ffi.string(ptr [,len])</tt></h3>
367<p>
368Creates an interned Lua string from the data pointed to by
369<tt>ptr</tt>.
370</p>
371<p>
372If the optional argument <tt>len</tt> is missing, <tt>ptr</tt> is
373converted to a <tt>"char&nbsp;*"</tt> and the data is assumed to be
374zero-terminated. The length of the string is computed with
375<tt>strlen()</tt>.
376</p>
377<p>
378Otherwise <tt>ptr</tt> is converted to a <tt>"void&nbsp;*"</tt> and
379<tt>len</tt> gives the length of the data. The data may contain
380embedded zeros and need not be byte-oriented (though this may cause
381endianess issues).
382</p>
383<p>
384This function is mainly useful to convert (temporary)
385<tt>"const&nbsp;char&nbsp;*"</tt> pointers returned by
386C&nbsp;functions to Lua strings and store them or pass them to other
387functions expecting a Lua string. The Lua string is an (interned) copy
388of the data and bears no relation to the original data area anymore.
389Lua strings are 8&nbsp;bit clean and may be used to hold arbitrary,
390non-character data.
391</p>
392<p>
393Performance notice: it's faster to pass the length of the string, if
394it's known. E.g. when the length is returned by a C&nbsp;call like
395<tt>sprintf()</tt>.
396</p>
397
398<h3 id="ffi_copy"><tt>ffi.copy(dst, src, len)<br>
399ffi.copy(dst, str)</tt></h3>
400<p>
401Copies the data pointed to by <tt>src</tt> to <tt>dst</tt>.
402<tt>dst</tt> is converted to a <tt>"void&nbsp;*"</tt> and <tt>src</tt>
403is converted to a <tt>"const void&nbsp;*"</tt>.
404</p>
405<p>
406In the first syntax, <tt>len</tt> gives the number of bytes to copy.
407Caveat: if <tt>src</tt> is a Lua string, then <tt>len</tt> must not
408exceed <tt>#src+1</tt>.
409</p>
410<p>
411In the second syntax, the source of the copy must be a Lua string. All
412bytes of the string <em>plus a zero-terminator</em> are copied to
413<tt>dst</tt> (i.e. <tt>#src+1</tt> bytes).
414</p>
415<p>
416Performance notice: <tt>ffi.copy()</tt> may be used as a faster
417(inlinable) replacement for the C&nbsp;library functions
418<tt>memcpy()</tt>, <tt>strcpy()</tt> and <tt>strncpy()</tt>.
419</p>
420
421<h3 id="ffi_fill"><tt>ffi.fill(dst, len [,c])</tt></h3>
422<p>
423Fills the data pointed to by <tt>dst</tt> with <tt>len</tt> constant
424bytes, given by <tt>c</tt>. If <tt>c</tt> is omitted, the data is
425zero-filled.
426</p>
427<p>
428Performance notice: <tt>ffi.fill()</tt> may be used as a faster
429(inlinable) replacement for the C&nbsp;library function
430<tt>memset(dst,&nbsp;c,&nbsp;len)</tt>. Please note the different
431order of arguments!
432</p>
433
434<h2 id="target">Target-specific Information</h2>
435
436<h3 id="ffi_abi"><tt>status = ffi.abi(param)</tt></h3>
437<p>
438Returns <tt>true</tt> if <tt>param</tt> (a Lua string) applies for the
439target ABI (Application Binary Interface). Returns <tt>false</tt>
440otherwise. The following parameters are currently defined:
441</p>
442<table class="abitable">
443<tr class="abihead">
444<td class="abiparam">Parameter</td>
445<td class="abidesc">Description</td>
446</tr>
447<tr class="odd separate">
448<td class="abiparam">32bit</td><td class="abidesc">32 bit architecture</td></tr>
449<tr class="even">
450<td class="abiparam">64bit</td><td class="abidesc">64 bit architecture</td></tr>
451<tr class="odd separate">
452<td class="abiparam">le</td><td class="abidesc">Little-endian architecture</td></tr>
453<tr class="even">
454<td class="abiparam">be</td><td class="abidesc">Big-endian architecture</td></tr>
455<tr class="odd separate">
456<td class="abiparam">fpu</td><td class="abidesc">Target has a hardware FPU</td></tr>
457<tr class="even">
458<td class="abiparam">softfp</td><td class="abidesc">softfp calling conventions</td></tr>
459<tr class="odd">
460<td class="abiparam">hardfp</td><td class="abidesc">hardfp calling conventions</td></tr>
461<tr class="even separate">
462<td class="abiparam">eabi</td><td class="abidesc">EABI variant of the standard ABI</td></tr>
463<tr class="odd">
464<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
465</table>
466
467<h3 id="ffi_os"><tt>ffi.os</tt></h3>
468<p>
469Contains the target OS name. Same contents as
470<a href="ext_jit.html#jit_os"><tt>jit.os</tt></a>.
471</p>
472
473<h3 id="ffi_arch"><tt>ffi.arch</tt></h3>
474<p>
475Contains the target architecture name. Same contents as
476<a href="ext_jit.html#jit_arch"><tt>jit.arch</tt></a>.
477</p>
478
479<h2 id="callback">Methods for Callbacks</h2>
480<p>
481The C&nbsp;types for <a href="ext_ffi_semantics.html#callback">callbacks</a>
482have some extra methods:
483</p>
484
485<h3 id="callback_free"><tt>cb:free()</tt></h3>
486<p>
487Free the resources associated with a callback. The associated Lua
488function is unanchored and may be garbage collected. The callback
489function pointer is no longer valid and must not be called anymore
490(it may be reused by a subsequently created callback).
491</p>
492
493<h3 id="callback_set"><tt>cb:set(func)</tt></h3>
494<p>
495Associate a new Lua function with a callback. The C&nbsp;type of the
496callback and the callback function pointer are unchanged.
497</p>
498<p>
499This method is useful to dynamically switch the receiver of callbacks
500without creating a new callback each time and registering it again (e.g.
501with a GUI library).
502</p>
503
504<h2 id="extended">Extended Standard Library Functions</h2>
505<p>
506The following standard library functions have been extended to work
507with cdata objects:
508</p>
509
510<h3 id="tonumber"><tt>n = tonumber(cdata)</tt></h3>
511<p>
512Converts a number cdata object to a <tt>double</tt> and returns it as
513a Lua number. This is particularly useful for boxed 64&nbsp;bit
514integer values. Caveat: this conversion may incur a precision loss.
515</p>
516
517<h3 id="tostring"><tt>s = tostring(cdata)</tt></h3>
518<p>
519Returns a string representation of the value of 64&nbsp;bit integers
520(<tt><b>"</b>nnn<b>LL"</b></tt> or <tt><b>"</b>nnn<b>ULL"</b></tt>) or
521complex numbers (<tt><b>"</b>re&plusmn;im<b>i"</b></tt>). Otherwise
522returns a string representation of the C&nbsp;type of a ctype object
523(<tt><b>"ctype&lt;</b>type<b>&gt;"</b></tt>) or a cdata object
524(<tt><b>"cdata&lt;</b>type<b>&gt;:&nbsp;</b>address"</tt>).
525</p>
526
527<h2 id="literals">Extensions to the Lua Parser</h2>
528<p>
529The parser for Lua source code treats numeric literals with the
530suffixes <tt>LL</tt> or <tt>ULL</tt> as signed or unsigned 64&nbsp;bit
531integers. Case doesn't matter, but uppercase is recommended for
532readability. It handles both decimal (<tt>42LL</tt>) and hexadecimal
533(<tt>0x2aLL</tt>) literals.
534</p>
535<p>
536The imaginary part of complex numbers can be specified by suffixing
537number literals with <tt>i</tt> or <tt>I</tt>, e.g. <tt>12.5i</tt>.
538Caveat: you'll need to use <tt>1i</tt> to get an imaginary part with
539the value one, since <tt>i</tt> itself still refers to a variable
540named <tt>i</tt>.
541</p>
542<br class="flush">
543</div>
544<div id="foot">
545<hr class="hide">
546Copyright &copy; 2005-2011 Mike Pall
547<span class="noprint">
548&middot;
549<a href="contact.html">Contact</a>
550</span>
551</div>
552</body>
553</html>
diff --git a/libraries/luajit-2.0/doc/ext_ffi_semantics.html b/libraries/luajit-2.0/doc/ext_ffi_semantics.html
new file mode 100644
index 0000000..661b0b4
--- /dev/null
+++ b/libraries/luajit-2.0/doc/ext_ffi_semantics.html
@@ -0,0 +1,1146 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>FFI Semantics</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.convtable { line-height: 1.2; }
13tr.convhead td { font-weight: bold; }
14td.convin { width: 11em; }
15td.convop { font-style: italic; width: 16em; }
16</style>
17</head>
18<body>
19<div id="site">
20<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
21</div>
22<div id="head">
23<h1>FFI Semantics</h1>
24</div>
25<div id="nav">
26<ul><li>
27<a href="luajit.html">LuaJIT</a>
28<ul><li>
29<a href="install.html">Installation</a>
30</li><li>
31<a href="running.html">Running</a>
32</li></ul>
33</li><li>
34<a href="extensions.html">Extensions</a>
35<ul><li>
36<a href="ext_ffi.html">FFI Library</a>
37<ul><li>
38<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
39</li><li>
40<a href="ext_ffi_api.html">ffi.* API</a>
41</li><li>
42<a class="current" href="ext_ffi_semantics.html">FFI Semantics</a>
43</li></ul>
44</li><li>
45<a href="ext_jit.html">jit.* Library</a>
46</li><li>
47<a href="ext_c_api.html">Lua/C API</a>
48</li></ul>
49</li><li>
50<a href="status.html">Status</a>
51<ul><li>
52<a href="changes.html">Changes</a>
53</li></ul>
54</li><li>
55<a href="faq.html">FAQ</a>
56</li><li>
57<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
58</li><li>
59<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
60</li></ul>
61</div>
62<div id="main">
63<p>
64This page describes the detailed semantics underlying the FFI library
65and its interaction with both Lua and C&nbsp;code.
66</p>
67<p>
68Given that the FFI library is designed to interface with C&nbsp;code
69and that declarations can be written in plain C&nbsp;syntax, <b>it
70closely follows the C&nbsp;language semantics</b>, wherever possible.
71Some minor concessions are needed for smoother interoperation with Lua
72language semantics.
73</p>
74<p>
75Please don't be overwhelmed by the contents of this page &mdash; this
76is a reference and you may need to consult it, if in doubt. It doesn't
77hurt to skim this page, but most of the semantics "just work" as you'd
78expect them to work. It should be straightforward to write
79applications using the LuaJIT FFI for developers with a C or C++
80background.
81</p>
82<p class="indent" style="color: #c00000;">
83Please note: this doesn't comprise the final specification for the FFI
84semantics, yet. Some semantics may need to be changed, based on your
85feedback. Please <a href="contact.html">report</a> any problems you may
86encounter or any improvements you'd like to see &mdash; thank you!
87</p>
88
89<h2 id="clang">C Language Support</h2>
90<p>
91The FFI library has a built-in C&nbsp;parser with a minimal memory
92footprint. It's used by the <a href="ext_ffi_api.html">ffi.* library
93functions</a> to declare C&nbsp;types or external symbols.
94</p>
95<p>
96It's only purpose is to parse C&nbsp;declarations, as found e.g. in
97C&nbsp;header files. Although it does evaluate constant expressions,
98it's <em>not</em> a C&nbsp;compiler. The body of <tt>inline</tt>
99C&nbsp;function definitions is simply ignored.
100</p>
101<p>
102Also, this is <em>not</em> a validating C&nbsp;parser. It expects and
103accepts correctly formed C&nbsp;declarations, but it may choose to
104ignore bad declarations or show rather generic error messages. If in
105doubt, please check the input against your favorite C&nbsp;compiler.
106</p>
107<p>
108The C&nbsp;parser complies to the <b>C99 language standard</b> plus
109the following extensions:
110</p>
111<ul>
112
113<li>The <tt>'\e'</tt> escape in character and string literals.</li>
114
115<li>The C99/C++ boolean type, declared with the keywords <tt>bool</tt>
116or <tt>_Bool</tt>.</li>
117
118<li>Complex numbers, declared with the keywords <tt>complex</tt> or
119<tt>_Complex</tt>.</li>
120
121<li>Two complex number types: <tt>complex</tt> (aka
122<tt>complex&nbsp;double</tt>) and <tt>complex&nbsp;float</tt>.</li>
123
124<li>Vector types, declared with the GCC <tt>mode</tt> or
125<tt>vector_size</tt> attribute.</li>
126
127<li>Unnamed ('transparent') <tt>struct</tt>/<tt>union</tt> fields
128inside a <tt>struct</tt>/<tt>union</tt>.</li>
129
130<li>Incomplete <tt>enum</tt> declarations, handled like incomplete
131<tt>struct</tt> declarations.</li>
132
133<li>Unnamed <tt>enum</tt> fields inside a
134<tt>struct</tt>/<tt>union</tt>. This is similar to a scoped C++
135<tt>enum</tt>, except that declared constants are visible in the
136global namespace, too.</li>
137
138<li>Scoped <tt>static&nbsp;const</tt> declarations inside a
139<tt>struct</tt>/<tt>union</tt> (from C++).</li>
140
141<li>Zero-length arrays (<tt>[0]</tt>), empty
142<tt>struct</tt>/<tt>union</tt>, variable-length arrays (VLA,
143<tt>[?]</tt>) and variable-length structs (VLS, with a trailing
144VLA).</li>
145
146<li>C++ reference types (<tt>int&nbsp;&amp;x</tt>).</li>
147
148<li>Alternate GCC keywords with '<tt>__</tt>', e.g.
149<tt>__const__</tt>.</li>
150
151<li>GCC <tt>__attribute__</tt> with the following attributes:
152<tt>aligned</tt>, <tt>packed</tt>, <tt>mode</tt>,
153<tt>vector_size</tt>, <tt>cdecl</tt>, <tt>fastcall</tt>,
154<tt>stdcall</tt>.</li>
155
156<li>The GCC <tt>__extension__</tt> keyword and the GCC
157<tt>__alignof__</tt> operator.</li>
158
159<li>GCC <tt>__asm__("symname")</tt> symbol name redirection for
160function declarations.</li>
161
162<li>MSVC keywords for fixed-length types: <tt>__int8</tt>,
163<tt>__int16</tt>, <tt>__int32</tt> and <tt>__int64</tt>.</li>
164
165<li>MSVC <tt>__cdecl</tt>, <tt>__fastcall</tt>, <tt>__stdcall</tt>,
166<tt>__ptr32</tt>, <tt>__ptr64</tt>, <tt>__declspec(align(n))</tt>
167and <tt>#pragma&nbsp;pack</tt>.</li>
168
169<li>All other GCC/MSVC-specific attributes are ignored.</li>
170
171</ul>
172<p>
173The following C&nbsp;types are pre-defined by the C&nbsp;parser (like
174a <tt>typedef</tt>, except re-declarations will be ignored):
175</p>
176<ul>
177
178<li>Vararg handling: <tt>va_list</tt>, <tt>__builtin_va_list</tt>,
179<tt>__gnuc_va_list</tt>.</li>
180
181<li>From <tt>&lt;stddef.h&gt;</tt>: <tt>ptrdiff_t</tt>,
182<tt>size_t</tt>, <tt>wchar_t</tt>.</li>
183
184<li>From <tt>&lt;stdint.h&gt;</tt>: <tt>int8_t</tt>, <tt>int16_t</tt>,
185<tt>int32_t</tt>, <tt>int64_t</tt>, <tt>uint8_t</tt>,
186<tt>uint16_t</tt>, <tt>uint32_t</tt>, <tt>uint64_t</tt>,
187<tt>intptr_t</tt>, <tt>uintptr_t</tt>.</li>
188
189</ul>
190<p>
191You're encouraged to use these types in preference to the
192compiler-specific extensions or the target-dependent standard types.
193E.g. <tt>char</tt> differs in signedness and <tt>long</tt> differs in
194size, depending on the target architecture and platform ABI.
195</p>
196<p>
197The following C&nbsp;features are <b>not</b> supported:
198</p>
199<ul>
200
201<li>A declaration must always have a type specifier; it doesn't
202default to an <tt>int</tt> type.</li>
203
204<li>Old-style empty function declarations (K&amp;R) are not allowed.
205All C&nbsp;functions must have a proper prototype declaration. A
206function declared without parameters (<tt>int&nbsp;foo();</tt>) is
207treated as a function taking zero arguments, like in C++.</li>
208
209<li>The <tt>long double</tt> C&nbsp;type is parsed correctly, but
210there's no support for the related conversions, accesses or arithmetic
211operations.</li>
212
213<li>Wide character strings and character literals are not
214supported.</li>
215
216<li><a href="#status">See below</a> for features that are currently
217not implemented.</li>
218
219</ul>
220
221<h2 id="convert">C Type Conversion Rules</h2>
222
223<h3 id="convert_tolua">Conversions from C&nbsp;types to Lua objects</h3>
224<p>
225These conversion rules apply for <em>read accesses</em> to
226C&nbsp;types: indexing pointers, arrays or
227<tt>struct</tt>/<tt>union</tt> types; reading external variables or
228constant values; retrieving return values from C&nbsp;calls:
229</p>
230<table class="convtable">
231<tr class="convhead">
232<td class="convin">Input</td>
233<td class="convop">Conversion</td>
234<td class="convout">Output</td>
235</tr>
236<tr class="odd separate">
237<td class="convin"><tt>int8_t</tt>, <tt>int16_t</tt></td><td class="convop">&rarr;<sup>sign-ext</sup> <tt>int32_t</tt> &rarr; <tt>double</tt></td><td class="convout">number</td></tr>
238<tr class="even">
239<td class="convin"><tt>uint8_t</tt>, <tt>uint16_t</tt></td><td class="convop">&rarr;<sup>zero-ext</sup> <tt>int32_t</tt> &rarr; <tt>double</tt></td><td class="convout">number</td></tr>
240<tr class="odd">
241<td class="convin"><tt>int32_t</tt>, <tt>uint32_t</tt></td><td class="convop">&rarr; <tt>double</tt></td><td class="convout">number</td></tr>
242<tr class="even">
243<td class="convin"><tt>int64_t</tt>, <tt>uint64_t</tt></td><td class="convop">boxed value</td><td class="convout">64 bit int cdata</td></tr>
244<tr class="odd separate">
245<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr; <tt>double</tt></td><td class="convout">number</td></tr>
246<tr class="even separate">
247<td class="convin"><tt>bool</tt></td><td class="convop">0 &rarr; <tt>false</tt>, otherwise <tt>true</tt></td><td class="convout">boolean</td></tr>
248<tr class="odd separate">
249<td class="convin">Complex number</td><td class="convop">boxed value</td><td class="convout">complex cdata</td></tr>
250<tr class="even">
251<td class="convin">Vector</td><td class="convop">boxed value</td><td class="convout">vector cdata</td></tr>
252<tr class="odd">
253<td class="convin">Pointer</td><td class="convop">boxed value</td><td class="convout">pointer cdata</td></tr>
254<tr class="even separate">
255<td class="convin">Array</td><td class="convop">boxed reference</td><td class="convout">reference cdata</td></tr>
256<tr class="odd">
257<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">boxed reference</td><td class="convout">reference cdata</td></tr>
258</table>
259<p>
260Bitfields or <tt>enum</tt> types are treated like their underlying
261type.
262</p>
263<p>
264Reference types are dereferenced <em>before</em> a conversion can take
265place &mdash; the conversion is applied to the C&nbsp;type pointed to
266by the reference.
267</p>
268
269<h3 id="convert_fromlua">Conversions from Lua objects to C&nbsp;types</h3>
270<p>
271These conversion rules apply for <em>write accesses</em> to
272C&nbsp;types: indexing pointers, arrays or
273<tt>struct</tt>/<tt>union</tt> types; initializing cdata objects;
274casts to C&nbsp;types; writing to external variables; passing
275arguments to C&nbsp;calls:
276</p>
277<table class="convtable">
278<tr class="convhead">
279<td class="convin">Input</td>
280<td class="convop">Conversion</td>
281<td class="convout">Output</td>
282</tr>
283<tr class="odd separate">
284<td class="convin">number</td><td class="convop">&rarr;</td><td class="convout"><tt>double</tt></td></tr>
285<tr class="even">
286<td class="convin">boolean</td><td class="convop"><tt>false</tt> &rarr; 0, <tt>true</tt> &rarr; 1</td><td class="convout"><tt>bool</tt></td></tr>
287<tr class="odd separate">
288<td class="convin">nil</td><td class="convop"><tt>NULL</tt> &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
289<tr class="even">
290<td class="convin">userdata</td><td class="convop">userdata payload &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
291<tr class="odd">
292<td class="convin">lightuserdata</td><td class="convop">lightuserdata address &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
293<tr class="even separate">
294<td class="convin">string</td><td class="convop">match against <tt>enum</tt> constant</td><td class="convout"><tt>enum</tt></td></tr>
295<tr class="odd">
296<td class="convin">string</td><td class="convop">copy string data + zero-byte</td><td class="convout"><tt>int8_t[]</tt>, <tt>uint8_t[]</tt></td></tr>
297<tr class="even">
298<td class="convin">string</td><td class="convop">string data &rarr;</td><td class="convout"><tt>const char[]</tt></td></tr>
299<tr class="odd separate">
300<td class="convin">function</td><td class="convop"><a href="#callback">create callback</a> &rarr;</td><td class="convout">C function type</td></tr>
301<tr class="even separate">
302<td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout">Array</td></tr>
303<tr class="odd">
304<td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr>
305<tr class="even separate">
306<td class="convin">cdata</td><td class="convop">cdata payload &rarr;</td><td class="convout">C type</td></tr>
307</table>
308<p>
309If the result type of this conversion doesn't match the
310C&nbsp;type of the destination, the
311<a href="#convert_between">conversion rules between C&nbsp;types</a>
312are applied.
313</p>
314<p>
315Reference types are immutable after initialization ("no re-seating of
316references"). For initialization purposes or when passing values to
317reference parameters, they are treated like pointers. Note that unlike
318in C++, there's no way to implement automatic reference generation of
319variables under the Lua language semantics. If you want to call a
320function with a reference parameter, you need to explicitly pass a
321one-element array.
322</p>
323
324<h3 id="convert_between">Conversions between C&nbsp;types</h3>
325<p>
326These conversion rules are more or less the same as the standard
327C&nbsp;conversion rules. Some rules only apply to casts, or require
328pointer or type compatibility:
329</p>
330<table class="convtable">
331<tr class="convhead">
332<td class="convin">Input</td>
333<td class="convop">Conversion</td>
334<td class="convout">Output</td>
335</tr>
336<tr class="odd separate">
337<td class="convin">Signed integer</td><td class="convop">&rarr;<sup>narrow or sign-extend</sup></td><td class="convout">Integer</td></tr>
338<tr class="even">
339<td class="convin">Unsigned integer</td><td class="convop">&rarr;<sup>narrow or zero-extend</sup></td><td class="convout">Integer</td></tr>
340<tr class="odd">
341<td class="convin">Integer</td><td class="convop">&rarr;<sup>round</sup></td><td class="convout"><tt>double</tt>, <tt>float</tt></td></tr>
342<tr class="even">
343<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>trunc</sup> <tt>int32_t</tt> &rarr;<sup>narrow</sup></td><td class="convout"><tt>(u)int8_t</tt>, <tt>(u)int16_t</tt></td></tr>
344<tr class="odd">
345<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>trunc</sup></td><td class="convout"><tt>(u)int32_t</tt>, <tt>(u)int64_t</tt></td></tr>
346<tr class="even">
347<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">&rarr;<sup>round</sup></td><td class="convout"><tt>float</tt>, <tt>double</tt></td></tr>
348<tr class="odd separate">
349<td class="convin">Number</td><td class="convop">n == 0 &rarr; 0, otherwise 1</td><td class="convout"><tt>bool</tt></td></tr>
350<tr class="even">
351<td class="convin"><tt>bool</tt></td><td class="convop"><tt>false</tt> &rarr; 0, <tt>true</tt> &rarr; 1</td><td class="convout">Number</td></tr>
352<tr class="odd separate">
353<td class="convin">Complex number</td><td class="convop">convert real part</td><td class="convout">Number</td></tr>
354<tr class="even">
355<td class="convin">Number</td><td class="convop">convert real part, imag = 0</td><td class="convout">Complex number</td></tr>
356<tr class="odd">
357<td class="convin">Complex number</td><td class="convop">convert real and imag part</td><td class="convout">Complex number</td></tr>
358<tr class="even separate">
359<td class="convin">Number</td><td class="convop">convert scalar and replicate</td><td class="convout">Vector</td></tr>
360<tr class="odd">
361<td class="convin">Vector</td><td class="convop">copy (same size)</td><td class="convout">Vector</td></tr>
362<tr class="even separate">
363<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr>
364<tr class="odd">
365<td class="convin">Array</td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr>
366<tr class="even">
367<td class="convin">Function</td><td class="convop">take function address</td><td class="convout">Function pointer</td></tr>
368<tr class="odd separate">
369<td class="convin">Number</td><td class="convop">convert via <tt>uintptr_t</tt> (cast)</td><td class="convout">Pointer</td></tr>
370<tr class="even">
371<td class="convin">Pointer</td><td class="convop">convert address (compat/cast)</td><td class="convout">Pointer</td></tr>
372<tr class="odd">
373<td class="convin">Pointer</td><td class="convop">convert address (cast)</td><td class="convout">Integer</td></tr>
374<tr class="even">
375<td class="convin">Array</td><td class="convop">convert base address (cast)</td><td class="convout">Integer</td></tr>
376<tr class="odd separate">
377<td class="convin">Array</td><td class="convop">copy (compat)</td><td class="convout">Array</td></tr>
378<tr class="even">
379<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">copy (identical type)</td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr>
380</table>
381<p>
382Bitfields or <tt>enum</tt> types are treated like their underlying
383type.
384</p>
385<p>
386Conversions not listed above will raise an error. E.g. it's not
387possible to convert a pointer to a complex number or vice versa.
388</p>
389
390<h3 id="convert_vararg">Conversions for vararg C&nbsp;function arguments</h3>
391<p>
392The following default conversion rules apply when passing Lua objects
393to the variable argument part of vararg C&nbsp;functions:
394</p>
395<table class="convtable">
396<tr class="convhead">
397<td class="convin">Input</td>
398<td class="convop">Conversion</td>
399<td class="convout">Output</td>
400</tr>
401<tr class="odd separate">
402<td class="convin">number</td><td class="convop">&rarr;</td><td class="convout"><tt>double</tt></td></tr>
403<tr class="even">
404<td class="convin">boolean</td><td class="convop"><tt>false</tt> &rarr; 0, <tt>true</tt> &rarr; 1</td><td class="convout"><tt>bool</tt></td></tr>
405<tr class="odd separate">
406<td class="convin">nil</td><td class="convop"><tt>NULL</tt> &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
407<tr class="even">
408<td class="convin">userdata</td><td class="convop">userdata payload &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
409<tr class="odd">
410<td class="convin">lightuserdata</td><td class="convop">lightuserdata address &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
411<tr class="even separate">
412<td class="convin">string</td><td class="convop">string data &rarr;</td><td class="convout"><tt>const char *</tt></td></tr>
413<tr class="odd separate">
414<td class="convin"><tt>float</tt> cdata</td><td class="convop">&rarr;</td><td class="convout"><tt>double</tt></td></tr>
415<tr class="even">
416<td class="convin">Array cdata</td><td class="convop">take base address</td><td class="convout">Element pointer</td></tr>
417<tr class="odd">
418<td class="convin"><tt>struct</tt>/<tt>union</tt> cdata</td><td class="convop">take base address</td><td class="convout"><tt>struct</tt>/<tt>union</tt> pointer</td></tr>
419<tr class="even">
420<td class="convin">Function cdata</td><td class="convop">take function address</td><td class="convout">Function pointer</td></tr>
421<tr class="odd">
422<td class="convin">Any other cdata</td><td class="convop">no conversion</td><td class="convout">C type</td></tr>
423</table>
424<p>
425To pass a Lua object, other than a cdata object, as a specific type,
426you need to override the conversion rules: create a temporary cdata
427object with a constructor or a cast and initialize it with the value
428to pass:
429</p>
430<p>
431Assuming <tt>x</tt> is a Lua number, here's how to pass it as an
432integer to a vararg function:
433</p>
434<pre class="code">
435ffi.cdef[[
436int printf(const char *fmt, ...);
437]]
438ffi.C.printf("integer value: %d\n", ffi.new("int", x))
439</pre>
440<p>
441If you don't do this, the default Lua number &rarr; <tt>double</tt>
442conversion rule applies. A vararg C&nbsp;function expecting an integer
443will see a garbled or uninitialized value.
444</p>
445
446<h2 id="init">Initializers</h2>
447<p>
448Creating a cdata object with
449<a href="ext_ffi_api.html#ffi_new"><tt>ffi.new()</tt></a> or the
450equivalent constructor syntax always initializes its contents, too.
451Different rules apply, depending on the number of optional
452initializers and the C&nbsp;types involved:
453</p>
454<ul>
455<li>If no initializers are given, the object is filled with zero bytes.</li>
456
457<li>Scalar types (numbers and pointers) accept a single initializer.
458The Lua object is <a href="#convert_fromlua">converted to the scalar
459C&nbsp;type</a>.</li>
460
461<li>Valarrays (complex numbers and vectors) are treated like scalars
462when a single initializer is given. Otherwise they are treated like
463regular arrays.</li>
464
465<li>Aggregate types (arrays and structs) accept either a single
466<a href="#init_table">table initializer</a> or a flat list of
467initializers.</li>
468
469<li>The elements of an array are initialized, starting at index zero.
470If a single initializer is given for an array, it's repeated for all
471remaining elements. This doesn't happen if two or more initializers
472are given: all remaining uninitialized elements are filled with zero
473bytes.</li>
474
475<li>Byte arrays may also be initialized with a Lua string. This copies
476the whole string plus a terminating zero-byte. The copy stops early only
477if the array has a known, fixed size.</li>
478
479<li>The fields of a <tt>struct</tt> are initialized in the order of
480their declaration. Uninitialized fields are filled with zero
481bytes.</li>
482
483<li>Only the first field of a <tt>union</tt> can be initialized with a
484flat initializer.</li>
485
486<li>Elements or fields which are aggregates themselves are initialized
487with a <em>single</em> initializer, but this may be a table
488initializer or a compatible aggregate.</li>
489
490<li>Excess initializers cause an error.</li>
491
492</ul>
493
494<h2 id="init_table">Table Initializers</h2>
495<p>
496The following rules apply if a Lua table is used to initialize an
497Array or a <tt>struct</tt>/<tt>union</tt>:
498</p>
499<ul>
500
501<li>If the table index <tt>[0]</tt> is non-<tt>nil</tt>, then the
502table is assumed to be zero-based. Otherwise it's assumed to be
503one-based.</li>
504
505<li>Array elements, starting at index zero, are initialized one-by-one
506with the consecutive table elements, starting at either index
507<tt>[0]</tt> or <tt>[1]</tt>. This process stops at the first
508<tt>nil</tt> table element.</li>
509
510<li>If exactly one array element was initialized, it's repeated for
511all the remaining elements. Otherwise all remaining uninitialized
512elements are filled with zero bytes.</li>
513
514<li>The above logic only applies to arrays with a known fixed size.
515A VLA is only initialized with the element(s) given in the table.
516Depending on the use case, you may need to explicitly add a
517<tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li>
518
519<li>If the table has a non-empty hash part, a
520<tt>struct</tt>/<tt>union</tt> is initialized by looking up each field
521name (as a string key) in the table. Each non-<tt>nil</tt> value is
522used to initialize the corresponding field.</li>
523
524<li>Otherwise a <tt>struct</tt>/<tt>union</tt> is initialized in the
525order of the declaration of its fields. Each field is initialized with
526the consecutive table elements, starting at either index <tt>[0]</tt>
527or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table
528element.</li>
529
530<li>Uninitialized fields of a <tt>struct</tt> are filled with zero
531bytes, except for the trailing VLA of a VLS.</li>
532
533<li>Initialization of a <tt>union</tt> stops after one field has been
534initialized. If no field has been initialized, the <tt>union</tt> is
535filled with zero bytes.</li>
536
537<li>Elements or fields which are aggregates themselves are initialized
538with a <em>single</em> initializer, but this may be a nested table
539initializer (or a compatible aggregate).</li>
540
541<li>Excess initializers for an array cause an error. Excess
542initializers for a <tt>struct</tt>/<tt>union</tt> are ignored.
543Unrelated table entries are ignored, too.</li>
544
545</ul>
546<p>
547Example:
548</p>
549<pre class="code">
550local ffi = require("ffi")
551
552ffi.cdef[[
553struct foo { int a, b; };
554union bar { int i; double d; };
555struct nested { int x; struct foo y; };
556]]
557
558ffi.new("int[3]", {}) --> 0, 0, 0
559ffi.new("int[3]", {1}) --> 1, 1, 1
560ffi.new("int[3]", {1,2}) --> 1, 2, 0
561ffi.new("int[3]", {1,2,3}) --> 1, 2, 3
562ffi.new("int[3]", {[0]=1}) --> 1, 1, 1
563ffi.new("int[3]", {[0]=1,2}) --> 1, 2, 0
564ffi.new("int[3]", {[0]=1,2,3}) --> 1, 2, 3
565ffi.new("int[3]", {[0]=1,2,3,4}) --> error: too many initializers
566
567ffi.new("struct foo", {}) --> a = 0, b = 0
568ffi.new("struct foo", {1}) --> a = 1, b = 0
569ffi.new("struct foo", {1,2}) --> a = 1, b = 2
570ffi.new("struct foo", {[0]=1,2}) --> a = 1, b = 2
571ffi.new("struct foo", {b=2}) --> a = 0, b = 2
572ffi.new("struct foo", {a=1,b=2,c=3}) --> a = 1, b = 2 'c' is ignored
573
574ffi.new("union bar", {}) --> i = 0, d = 0.0
575ffi.new("union bar", {1}) --> i = 1, d = ?
576ffi.new("union bar", {[0]=1,2}) --> i = 1, d = ? '2' is ignored
577ffi.new("union bar", {d=2}) --> i = ?, d = 2.0
578
579ffi.new("struct nested", {1,{2,3}}) --> x = 1, y.a = 2, y.b = 3
580ffi.new("struct nested", {x=1,y={2,3}}) --> x = 1, y.a = 2, y.b = 3
581</pre>
582
583<h2 id="cdata_ops">Operations on cdata Objects</h2>
584<p>
585All of the standard Lua operators can be applied to cdata objects or a
586mix of a cdata object and another Lua object. The following list shows
587the valid combinations. All other combinations currently raise an
588error.
589</p>
590<p>
591Reference types are dereferenced <em>before</em> performing each of
592the operations below &mdash; the operation is applied to the
593C&nbsp;type pointed to by the reference.
594</p>
595<p>
596The pre-defined operations are always tried first before deferring to a
597metamethod for a ctype (if defined).
598</p>
599
600<h3 id="cdata_array">Indexing a cdata object</h3>
601<ul>
602
603<li><b>Indexing a pointer/array</b>: a cdata pointer/array can be
604indexed by a cdata number or a Lua number. The element address is
605computed as the base address plus the number value multiplied by the
606element size in bytes. A read access loads the element value and
607<a href="#convert_tolua">converts it to a Lua object</a>. A write
608access <a href="#convert_fromlua">converts a Lua object to the element
609type</a> and stores the converted value to the element. An error is
610raised if the element size is undefined or a write access to a
611constant element is attempted.</li>
612
613<li><b>Dereferencing a <tt>struct</tt>/<tt>union</tt> field</b>: a
614cdata <tt>struct</tt>/<tt>union</tt> or a pointer to a
615<tt>struct</tt>/<tt>union</tt> can be dereferenced by a string key,
616giving the field name. The field address is computed as the base
617address plus the relative offset of the field. A read access loads the
618field value and <a href="#convert_tolua">converts it to a Lua
619object</a>. A write access <a href="#convert_fromlua">converts a Lua
620object to the field type</a> and stores the converted value to the
621field. An error is raised if a write access to a constant
622<tt>struct</tt>/<tt>union</tt> or a constant field is attempted.</li>
623
624<li><b>Indexing a complex number</b>: a complex number can be indexed
625either by a cdata number or a Lua number with the values 0 or 1, or by
626the strings <tt>"re"</tt> or <tt>"im"</tt>. A read access loads the
627real part (<tt>[0]</tt>, <tt>.re</tt>) or the imaginary part
628(<tt>[1]</tt>, <tt>.im</tt>) part of a complex number and
629<a href="#convert_tolua">converts it to a Lua number</a>. The
630sub-parts of a complex number are immutable &mdash; assigning to an
631index of a complex number raises an error. Accessing out-of-bound
632indexes returns unspecified results, but is guaranteed not to trigger
633memory access violations.</li>
634
635<li><b>Indexing a vector</b>: a vector is treated like an array for
636indexing purposes, except the vector elements are immutable &mdash;
637assigning to an index of a vector raises an error.</li>
638
639</ul>
640<p>
641Note: since there's (deliberately) no address-of operator, a cdata
642object holding a value type is effectively immutable after
643initialization. The JIT compiler benefits from this fact when applying
644certain optimizations.
645</p>
646<p>
647As a consequence of this, the <em>elements</em> of complex numbers and
648vectors are immutable. But the elements of an aggregate holding these
649types <em>may</em> be modified of course. I.e. you cannot assign to
650<tt>foo.c.im</tt>, but you can assign a (newly created) complex number
651to <tt>foo.c</tt>.
652</p>
653
654<h3 id="cdata_call">Calling a cdata object</h3>
655<ul>
656
657<li><b>Constructor</b>: a ctype object can be called and used as a
658<a href="ext_ffi_api.html#ffi_new">constructor</a>.</li>
659
660<li><b>C&nbsp;function call</b>: a cdata function or cdata function
661pointer can be called. The passed arguments are
662<a href="#convert_fromlua">converted to the C&nbsp;types</a> of the
663parameters given by the function declaration. Arguments passed to the
664variable argument part of vararg C&nbsp;function use
665<a href="#convert_vararg">special conversion rules</a>. This
666C&nbsp;function is called and the return value (if any) is
667<a href="#convert_tolua">converted to a Lua object</a>.<br>
668On Windows/x86 systems, <tt>__stdcall</tt> functions are automatically
669detected and a function declared as <tt>__cdecl</tt> (the default) is
670silently fixed up after the first call.</li>
671
672</ul>
673
674<h3 id="cdata_arith">Arithmetic on cdata objects</h3>
675<ul>
676
677<li><b>Pointer arithmetic</b>: a cdata pointer/array and a cdata
678number or a Lua number can be added or subtracted. The number must be
679on the right hand side for a subtraction. The result is a pointer of
680the same type with an address plus or minus the number value
681multiplied by the element size in bytes. An error is raised if the
682element size is undefined.</li>
683
684<li><b>Pointer difference</b>: two compatible cdata pointers/arrays
685can be subtracted. The result is the difference between their
686addresses, divided by the element size in bytes. An error is raised if
687the element size is undefined or zero.</li>
688
689<li><b>64&nbsp;bit integer arithmetic</b>: the standard arithmetic
690operators (<tt>+&nbsp;-&nbsp;*&nbsp;/&nbsp;%&nbsp;^</tt> and unary
691minus) can be applied to two cdata numbers, or a cdata number and a
692Lua number. If one of them is an <tt>uint64_t</tt>, the other side is
693converted to an <tt>uint64_t</tt> and an unsigned arithmetic operation
694is performed. Otherwise both sides are converted to an
695<tt>int64_t</tt> and a signed arithmetic operation is performed. The
696result is a boxed 64&nbsp;bit cdata object.<br>
697
698These rules ensure that 64&nbsp;bit integers are "sticky". Any
699expression involving at least one 64&nbsp;bit integer operand results
700in another one. The undefined cases for the division, modulo and power
701operators return <tt>2LL&nbsp;^&nbsp;63</tt> or
702<tt>2ULL&nbsp;^&nbsp;63</tt>.<br>
703
704You'll have to explicitly convert a 64&nbsp;bit integer to a Lua
705number (e.g. for regular floating-point calculations) with
706<tt>tonumber()</tt>. But note this may incur a precision loss.</li>
707
708</ul>
709
710<h3 id="cdata_comp">Comparisons of cdata objects</h3>
711<ul>
712
713<li><b>Pointer comparison</b>: two compatible cdata pointers/arrays
714can be compared. The result is the same as an unsigned comparison of
715their addresses. <tt>nil</tt> is treated like a <tt>NULL</tt> pointer,
716which is compatible with any other pointer type.</li>
717
718<li><b>64&nbsp;bit integer comparison</b>: two cdata numbers, or a
719cdata number and a Lua number can be compared with each other. If one
720of them is an <tt>uint64_t</tt>, the other side is converted to an
721<tt>uint64_t</tt> and an unsigned comparison is performed. Otherwise
722both sides are converted to an <tt>int64_t</tt> and a signed
723comparison is performed.</li>
724
725</ul>
726
727<h3 id="cdata_key">cdata objects as table keys</h3>
728<p>
729Lua tables may be indexed by cdata objects, but this doesn't provide
730any useful semantics &mdash; <b>cdata objects are unsuitable as table
731keys!</b>
732</p>
733<p>
734A cdata object is treated like any other garbage-collected object and
735is hashed and compared by its address for table indexing. Since
736there's no interning for cdata value types, the same value may be
737boxed in different cdata objects with different addresses. Thus
738<tt>t[1LL+1LL]</tt> and <tt>t[2LL]</tt> usually <b>do not</b> point to
739the same hash slot and they certainly <b>do not</b> point to the same
740hash slot as <tt>t[2]</tt>.
741</p>
742<p>
743It would seriously drive up implementation complexity and slow down
744the common case, if one were to add extra handling for by-value
745hashing and comparisons to Lua tables. Given the ubiquity of their use
746inside the VM, this is not acceptable.
747</p>
748<p>
749There are three viable alternatives, if you really need to use cdata
750objects as keys:
751</p>
752<ul>
753
754<li>If you can get by with the precision of Lua numbers
755(52&nbsp;bits), then use <tt>tonumber()</tt> on a cdata number or
756combine multiple fields of a cdata aggregate to a Lua number. Then use
757the resulting Lua number as a key when indexing tables.<br>
758One obvious benefit: <tt>t[tonumber(2LL)]</tt> <b>does</b> point to
759the same slot as <tt>t[2]</tt>.</li>
760
761<li>Otherwise use either <tt>tostring()</tt> on 64&nbsp;bit integers
762or complex numbers or combine multiple fields of a cdata aggregate to
763a Lua string (e.g. with
764<a href="ext_ffi_api.html#ffi_string"><tt>ffi.string()</tt></a>). Then
765use the resulting Lua string as a key when indexing tables.</li>
766
767<li>Create your own specialized hash table implementation using the
768C&nbsp;types provided by the FFI library, just like you would in
769C&nbsp;code. Ultimately this may give much better performance than the
770other alternatives or what a generic by-value hash table could
771possibly provide.</li>
772
773</ul>
774
775<h2 id="gc">Garbage Collection of cdata Objects</h2>
776<p>
777All explicitly (<tt>ffi.new()</tt>, <tt>ffi.cast()</tt> etc.) or
778implicitly (accessors) created cdata objects are garbage collected.
779You need to ensure to retain valid references to cdata objects
780somewhere on a Lua stack, an upvalue or in a Lua table while they are
781still in use. Once the last reference to a cdata object is gone, the
782garbage collector will automatically free the memory used by it (at
783the end of the next GC cycle).
784</p>
785<p>
786Please note that pointers themselves are cdata objects, however they
787are <b>not</b> followed by the garbage collector. So e.g. if you
788assign a cdata array to a pointer, you must keep the cdata object
789holding the array alive as long as the pointer is still in use:
790</p>
791<pre class="code">
792ffi.cdef[[
793typedef struct { int *a; } foo_t;
794]]
795
796local s = ffi.new("foo_t", ffi.new("int[10]")) -- <span style="color:#c00000;">WRONG!</span>
797
798local a = ffi.new("int[10]") -- <span style="color:#00a000;">OK</span>
799local s = ffi.new("foo_t", a)
800-- Now do something with 's', but keep 'a' alive until you're done.
801</pre>
802<p>
803Similar rules apply for Lua strings which are implicitly converted to
804<tt>"const&nbsp;char&nbsp;*"</tt>: the string object itself must be
805referenced somewhere or it'll be garbage collected eventually. The
806pointer will then point to stale data, which may have already been
807overwritten. Note that <em>string literals</em> are automatically kept
808alive as long as the function containing it (actually its prototype)
809is not garbage collected.
810</p>
811<p>
812Objects which are passed as an argument to an external C&nbsp;function
813are kept alive until the call returns. So it's generally safe to
814create temporary cdata objects in argument lists. This is a common
815idiom for <a href="#convert_vararg">passing specific C&nbsp;types to
816vararg functions</a>.
817</p>
818<p>
819Memory areas returned by C functions (e.g. from <tt>malloc()</tt>)
820must be manually managed, of course (or use
821<a href="ext_ffi_api.html#ffi_gc"><tt>ffi.gc()</tt></a>). Pointers to
822cdata objects are indistinguishable from pointers returned by C
823functions (which is one of the reasons why the GC cannot follow them).
824</p>
825
826<h2 id="callback">Callbacks</h2>
827<p>
828The LuaJIT FFI automatically generates special callback functions
829whenever a Lua function is converted to a C&nbsp;function pointer. This
830associates the generated callback function pointer with the C&nbsp;type
831of the function pointer and the Lua function object (closure).
832</p>
833<p>
834This can happen implicitly due to the usual conversions, e.g. when
835passing a Lua function to a function pointer argument. Or you can use
836<tt>ffi.cast()</tt> to explicitly cast a Lua function to a
837C&nbsp;function pointer.
838</p>
839<p>
840Currently only certain C&nbsp;function types can be used as callback
841functions. Neither C&nbsp;vararg functions nor functions with
842pass-by-value aggregate argument or result types are supported. There
843are no restrictions for the kind of Lua functions that can be called
844from the callback &mdash; no checks for the proper number of arguments
845are made. The return value of the Lua function will be converted to the
846result type and an error will be thrown for invalid conversions.
847</p>
848<p>
849It's allowed to throw errors across a callback invocation, but it's not
850advisable in general. Do this only if you know the C&nbsp;function, that
851called the callback, copes with the forced stack unwinding and doesn't
852leak resources.
853</p>
854
855<h3 id="callback_resources">Callback resource handling</h3>
856<p>
857Callbacks take up resources &mdash; you can only have a limited number
858of them at the same time (500&nbsp;-&nbsp;1000, depending on the
859architecture). The associated Lua functions are anchored to prevent
860garbage collection, too.
861</p>
862<p>
863<b>Callbacks due to implicit conversions are permanent!</b> There is no
864way to guess their lifetime, since the C&nbsp;side might store the
865function pointer for later use (typical for GUI toolkits). The associated
866resources cannot be reclaimed until termination:
867</p>
868<pre class="code">
869ffi.cdef[[
870typedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l);
871int EnumWindows(WNDENUMPROC func, intptr_t l);
872]]
873
874-- Implicit conversion to a callback via function pointer argument.
875local count = 0
876ffi.C.EnumWindows(function(hwnd, l)
877 count = count + 1
878 return true
879end, 0)
880-- The callback is permanent and its resources cannot be reclaimed!
881-- Ok, so this may not be a problem, if you do this only once.
882</pre>
883<p>
884Note: this example shows that you <em>must</em> properly declare
885<tt>__stdcall</tt> callbacks on Windows/x86 systems. The calling
886convention cannot be automatically detected, unlike for
887<tt>__stdcall</tt> calls <em>to</em> Windows functions.
888</p>
889<p>
890For some use cases it's necessary to free up the resources or to
891dynamically redirect callbacks. Use an explicit cast to a
892C&nbsp;function pointer and keep the resulting cdata object. Then use
893the <a href="ext_ffi_api.html#callback_free"><tt>cb:free()</tt></a>
894or <a href="ext_ffi_api.html#callback_set"><tt>cb:set()</tt></a> methods
895on the cdata object:
896</p>
897<pre class="code">
898-- Explicitly convert to a callback via cast.
899local count = 0
900local cb = ffi.cast("WNDENUMPROC", function(hwnd, l)
901 count = count + 1
902 return true
903end)
904
905-- Pass it to a C function.
906ffi.C.EnumWindows(cb, 0)
907-- EnumWindows doesn't need the callback after it returns, so free it.
908
909cb:free()
910-- The callback function pointer is no longer valid and its resources
911-- will be reclaimed. The created Lua closure will be garbage collected.
912</pre>
913
914<h3 id="callback_performance">Callback performance</h3>
915<p>
916<b>Callbacks are slow!</b> First, the C&nbsp;to Lua transition itself
917has an unavoidable cost, similar to a <tt>lua_call()</tt> or
918<tt>lua_pcall()</tt>. Argument and result marshalling add to that cost.
919And finally, neither the C&nbsp;compiler nor LuaJIT can inline or
920optimize across the language barrier and hoist repeated computations out
921of a callback function.
922</p>
923<p>
924Do not use callbacks for performance-sensitive work: e.g. consider a
925numerical integration routine which takes a user-defined function to
926integrate over. It's a bad idea to call a user-defined Lua function from
927C&nbsp;code millions of times. The callback overhead will be absolutely
928detrimental for performance.
929</p>
930<p>
931It's considerably faster to write the numerical integration routine
932itself in Lua &mdash; the JIT compiler will be able to inline the
933user-defined function and optimize it together with its calling context,
934with very competitive performance.
935</p>
936<p>
937As a general guideline: <b>use callbacks only when you must</b>, because
938of existing C&nbsp;APIs. E.g. callback performance is irrelevant for a
939GUI application, which waits for user input most of the time, anyway.
940</p>
941<p>
942For new designs <b>avoid push-style APIs</b> (C&nbsp;function repeatedly
943calling a callback for each result). Instead <b>use pull-style APIs</b>
944(call a C&nbsp;function repeatedly to get a new result). Calls from Lua
945to C via the FFI are much faster than the other way round. Most well-designed
946libraries already use pull-style APIs (read/write, get/put).
947</p>
948
949<h2 id="clib">C Library Namespaces</h2>
950<p>
951A C&nbsp;library namespace is a special kind of object which allows
952access to the symbols contained in shared libraries or the default
953symbol namespace. The default
954<a href="ext_ffi_api.html#ffi_C"><tt>ffi.C</tt></a> namespace is
955automatically created when the FFI library is loaded. C&nbsp;library
956namespaces for specific shared libraries may be created with the
957<a href="ext_ffi_api.html#ffi_load"><tt>ffi.load()</tt></a> API
958function.
959</p>
960<p>
961Indexing a C&nbsp;library namespace object with a symbol name (a Lua
962string) automatically binds it to the library. First the symbol type
963is resolved &mdash; it must have been declared with
964<a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a>. Then the
965symbol address is resolved by searching for the symbol name in the
966associated shared libraries or the default symbol namespace. Finally,
967the resulting binding between the symbol name, the symbol type and its
968address is cached. Missing symbol declarations or nonexistent symbol
969names cause an error.
970</p>
971<p>
972This is what happens on a <b>read access</b> for the different kinds of
973symbols:
974</p>
975<ul>
976
977<li>External functions: a cdata object with the type of the function
978and its address is returned.</li>
979
980<li>External variables: the symbol address is dereferenced and the
981loaded value is <a href="#convert_tolua">converted to a Lua object</a>
982and returned.</li>
983
984<li>Constant values (<tt>static&nbsp;const</tt> or <tt>enum</tt>
985constants): the constant is <a href="#convert_tolua">converted to a
986Lua object</a> and returned.</li>
987
988</ul>
989<p>
990This is what happens on a <b>write access</b>:
991</p>
992<ul>
993
994<li>External variables: the value to be written is
995<a href="#convert_fromlua">converted to the C&nbsp;type</a> of the
996variable and then stored at the symbol address.</li>
997
998<li>Writing to constant variables or to any other symbol type causes
999an error, like any other attempted write to a constant location.</li>
1000
1001</ul>
1002<p>
1003C&nbsp;library namespaces themselves are garbage collected objects. If
1004the last reference to the namespace object is gone, the garbage
1005collector will eventually release the shared library reference and
1006remove all memory associated with the namespace. Since this may
1007trigger the removal of the shared library from the memory of the
1008running process, it's generally <em>not safe</em> to use function
1009cdata objects obtained from a library if the namespace object may be
1010unreferenced.
1011</p>
1012<p>
1013Performance notice: the JIT compiler specializes to the identity of
1014namespace objects and to the strings used to index it. This
1015effectively turns function cdata objects into constants. It's not
1016useful and actually counter-productive to explicitly cache these
1017function objects, e.g. <tt>local strlen = ffi.C.strlen</tt>. OTOH it
1018<em>is</em> useful to cache the namespace itself, e.g. <tt>local C =
1019ffi.C</tt>.
1020</p>
1021
1022<h2 id="policy">No Hand-holding!</h2>
1023<p>
1024The FFI library has been designed as <b>a low-level library</b>. The
1025goal is to interface with C&nbsp;code and C&nbsp;data types with a
1026minimum of overhead. This means <b>you can do anything you can do
1027from&nbsp;C</b>: access all memory, overwrite anything in memory, call
1028machine code at any memory address and so on.
1029</p>
1030<p>
1031The FFI library provides <b>no memory safety</b>, unlike regular Lua
1032code. It will happily allow you to dereference a <tt>NULL</tt>
1033pointer, to access arrays out of bounds or to misdeclare
1034C&nbsp;functions. If you make a mistake, your application might crash,
1035just like equivalent C&nbsp;code would.
1036</p>
1037<p>
1038This behavior is inevitable, since the goal is to provide full
1039interoperability with C&nbsp;code. Adding extra safety measures, like
1040bounds checks, would be futile. There's no way to detect
1041misdeclarations of C&nbsp;functions, since shared libraries only
1042provide symbol names, but no type information. Likewise there's no way
1043to infer the valid range of indexes for a returned pointer.
1044</p>
1045<p>
1046Again: the FFI library is a low-level library. This implies it needs
1047to be used with care, but it's flexibility and performance often
1048outweigh this concern. If you're a C or C++ developer, it'll be easy
1049to apply your existing knowledge. OTOH writing code for the FFI
1050library is not for the faint of heart and probably shouldn't be the
1051first exercise for someone with little experience in Lua, C or C++.
1052</p>
1053<p>
1054As a corollary of the above, the FFI library is <b>not safe for use by
1055untrusted Lua code</b>. If you're sandboxing untrusted Lua code, you
1056definitely don't want to give this code access to the FFI library or
1057to <em>any</em> cdata object (except 64&nbsp;bit integers or complex
1058numbers). Any properly engineered Lua sandbox needs to provide safety
1059wrappers for many of the standard Lua library functions &mdash;
1060similar wrappers need to be written for high-level operations on FFI
1061data types, too.
1062</p>
1063
1064<h2 id="status">Current Status</h2>
1065<p>
1066The initial release of the FFI library has some limitations and is
1067missing some features. Most of these will be fixed in future releases.
1068</p>
1069<p>
1070<a href="#clang">C language support</a> is
1071currently incomplete:
1072</p>
1073<ul>
1074<li>C&nbsp;declarations are not passed through a C&nbsp;pre-processor,
1075yet.</li>
1076<li>The C&nbsp;parser is able to evaluate most constant expressions
1077commonly found in C&nbsp;header files. However it doesn't handle the
1078full range of C&nbsp;expression semantics and may fail for some
1079obscure constructs.</li>
1080<li><tt>static const</tt> declarations only work for integer types
1081up to 32&nbsp;bits. Neither declaring string constants nor
1082floating-point constants is supported.</li>
1083<li>Packed <tt>struct</tt> bitfields that cross container boundaries
1084are not implemented.</li>
1085<li>Native vector types may be defined with the GCC <tt>mode</tt> or
1086<tt>vector_size</tt> attribute. But no operations other than loading,
1087storing and initializing them are supported, yet.</li>
1088<li>The <tt>volatile</tt> type qualifier is currently ignored by
1089compiled code.</li>
1090<li><a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a> silently
1091ignores all re-declarations.</li>
1092</ul>
1093<p>
1094The JIT compiler already handles a large subset of all FFI operations.
1095It automatically falls back to the interpreter for unimplemented
1096operations (you can check for this with the
1097<a href="running.html#opt_j"><tt>-jv</tt></a> command line option).
1098The following operations are currently not compiled and may exhibit
1099suboptimal performance, especially when used in inner loops:
1100</p>
1101<ul>
1102<li>Array/<tt>struct</tt> copies and bulk initializations.</li>
1103<li>Bitfield accesses and initializations.</li>
1104<li>Vector operations.</li>
1105<li>Table initializers.</li>
1106<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>
1107<li>Allocations of variable-length arrays or structs.</li>
1108<li>Allocations of C&nbsp;types with a size &gt; 64&nbsp;bytes or an
1109alignment &gt; 8&nbsp;bytes.</li>
1110<li>Conversions from lightuserdata to <tt>void&nbsp;*</tt>.</li>
1111<li>Pointer differences for element sizes that are not a power of
1112two.</li>
1113<li>Calls to C&nbsp;functions with aggregates passed or returned by
1114value.</li>
1115<li>Calls to ctype metamethods which are not plain functions.</li>
1116<li>ctype <tt>__newindex</tt> tables and non-string lookups in ctype
1117<tt>__index</tt> tables.</li>
1118<li><tt>tostring()</tt> for cdata types.</li>
1119<li>Calls to the following <a href="ext_ffi_api.html">ffi.* API</a>
1120functions: <tt>cdef</tt>, <tt>load</tt>, <tt>typeof</tt>,
1121<tt>metatype</tt>, <tt>gc</tt>, <tt>sizeof</tt>, <tt>alignof</tt>,
1122<tt>offsetof</tt>.</li>
1123</ul>
1124<p>
1125Other missing features:
1126</p>
1127<ul>
1128<li>Bit operations for 64&nbsp;bit types.</li>
1129<li>Arithmetic for <tt>complex</tt> numbers.</li>
1130<li>Passing structs by value to vararg C&nbsp;functions.</li>
1131<li><a href="extensions.html#exceptions">C++ exception interoperability</a>
1132does not extend to C&nbsp;functions called via the FFI, if the call is
1133compiled.</li>
1134</ul>
1135<br class="flush">
1136</div>
1137<div id="foot">
1138<hr class="hide">
1139Copyright &copy; 2005-2011 Mike Pall
1140<span class="noprint">
1141&middot;
1142<a href="contact.html">Contact</a>
1143</span>
1144</div>
1145</body>
1146</html>
diff --git a/libraries/luajit-2.0/doc/ext_ffi_tutorial.html b/libraries/luajit-2.0/doc/ext_ffi_tutorial.html
new file mode 100644
index 0000000..fb46a84
--- /dev/null
+++ b/libraries/luajit-2.0/doc/ext_ffi_tutorial.html
@@ -0,0 +1,598 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>FFI Tutorial</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12span.codemark { position:absolute; left: 16em; color: #4040c0; }
13span.mark { color: #4040c0; font-family: Courier New, Courier, monospace;
14 line-height: 1.1; }
15pre.mark { padding-left: 2em; }
16table.idiomtable { line-height: 1.2; }
17table.idiomtable tt { font-size: 100%; }
18table.idiomtable td { vertical-align: top; }
19tr.idiomhead td { font-weight: bold; }
20td.idiomc { width: 12em; }
21td.idiomlua { width: 14em; }
22td.idiomlua b { font-weight: normal; color: #2142bf; }
23</style>
24</head>
25<body>
26<div id="site">
27<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
28</div>
29<div id="head">
30<h1>FFI Tutorial</h1>
31</div>
32<div id="nav">
33<ul><li>
34<a href="luajit.html">LuaJIT</a>
35<ul><li>
36<a href="install.html">Installation</a>
37</li><li>
38<a href="running.html">Running</a>
39</li></ul>
40</li><li>
41<a href="extensions.html">Extensions</a>
42<ul><li>
43<a href="ext_ffi.html">FFI Library</a>
44<ul><li>
45<a class="current" href="ext_ffi_tutorial.html">FFI Tutorial</a>
46</li><li>
47<a href="ext_ffi_api.html">ffi.* API</a>
48</li><li>
49<a href="ext_ffi_semantics.html">FFI Semantics</a>
50</li></ul>
51</li><li>
52<a href="ext_jit.html">jit.* Library</a>
53</li><li>
54<a href="ext_c_api.html">Lua/C API</a>
55</li></ul>
56</li><li>
57<a href="status.html">Status</a>
58<ul><li>
59<a href="changes.html">Changes</a>
60</li></ul>
61</li><li>
62<a href="faq.html">FAQ</a>
63</li><li>
64<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
65</li><li>
66<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
67</li></ul>
68</div>
69<div id="main">
70<p>
71This page is intended to give you an overview of the features of the FFI
72library by presenting a few use cases and guidelines.
73</p>
74<p>
75This page makes no attempt to explain all of the FFI library, though.
76You'll want to have a look at the <a href="ext_ffi_api.html">ffi.* API
77function reference</a> and the <a href="ext_ffi_semantics.html">FFI
78semantics</a> to learn more.
79</p>
80
81<h2 id="load">Loading the FFI Library</h2>
82<p>
83The FFI library is built into LuaJIT by default, but it's not loaded
84and initialized by default. The suggested way to use the FFI library
85is to add the following to the start of every Lua file that needs one
86of its functions:
87</p>
88<pre class="code">
89local ffi = require("ffi")
90</pre>
91<p>
92Please note this doesn't define an <tt>ffi</tt> variable in the table
93of globals &mdash; you really need to use the local variable. The
94<tt>require</tt> function ensures the library is only loaded once.
95</p>
96
97<h2 id="sleep">Accessing Standard System Functions</h2>
98<p>
99The following code explains how to access standard system functions.
100We slowly print two lines of dots by sleeping for 10&nbsp;milliseconds
101after each dot:
102</p>
103<pre class="code mark">
104<span class="codemark">&nbsp;
105&#9312;
106
107
108
109
110
111&#9313;
112&#9314;
113&#9315;
114
115
116
117&#9316;
118
119
120
121
122
123&#9317;</span>local ffi = require("ffi")
124ffi.cdef[[
125<span style="color:#00a000;">void Sleep(int ms);
126int poll(struct pollfd *fds, unsigned long nfds, int timeout);</span>
127]]
128
129local sleep
130if ffi.os == "Windows" then
131 function sleep(s)
132 ffi.C.Sleep(s*1000)
133 end
134else
135 function sleep(s)
136 ffi.C.poll(nil, 0, s*1000)
137 end
138end
139
140for i=1,160 do
141 io.write("."); io.flush()
142 sleep(0.01)
143end
144io.write("\n")
145</pre>
146<p>
147Here's the step-by-step explanation:
148</p>
149<p>
150<span class="mark">&#9312;</span> This defines the
151C&nbsp;library functions we're going to use. The part inside the
152double-brackets (in green) is just standard C&nbsp;syntax. You can
153usually get this info from the C&nbsp;header files or the
154documentation provided by each C&nbsp;library or C&nbsp;compiler.
155</p>
156<p>
157<span class="mark">&#9313;</span> The difficulty we're
158facing here, is that there are different standards to choose from.
159Windows has a simple <tt>Sleep()</tt> function. On other systems there
160are a variety of functions available to achieve sub-second sleeps, but
161with no clear consensus. Thankfully <tt>poll()</tt> can be used for
162this task, too, and it's present on most non-Windows systems. The
163check for <tt>ffi.os</tt> makes sure we use the Windows-specific
164function only on Windows systems.
165</p>
166<p>
167<span class="mark">&#9314;</span> Here we're wrapping the
168call to the C&nbsp;function in a Lua function. This isn't strictly
169necessary, but it's helpful to deal with system-specific issues only
170in one part of the code. The way we're wrapping it ensures the check
171for the OS is only done during initialization and not for every call.
172</p>
173<p>
174<span class="mark">&#9315;</span> A more subtle point is
175that we defined our <tt>sleep()</tt> function (for the sake of this
176example) as taking the number of seconds, but accepting fractional
177seconds. Multiplying this by 1000 gets us milliseconds, but that still
178leaves it a Lua number, which is a floating-point value. Alas, the
179<tt>Sleep()</tt> function only accepts an integer value. Luckily for
180us, the FFI library automatically performs the conversion when calling
181the function (truncating the FP value towards zero, like in C).
182</p>
183<p style="font-size: 8pt;">
184Some readers will notice that <tt>Sleep()</tt> is part of
185<tt>KERNEL32.DLL</tt> and is also a <tt>stdcall</tt> function. So how
186can this possibly work? The FFI library provides the <tt>ffi.C</tt>
187default C&nbsp;library namespace, which allows calling functions from
188the default set of libraries, like a C&nbsp;compiler would. Also, the
189FFI library automatically detects <tt>stdcall</tt> functions, so you
190don't need to declare them as such.
191</p>
192<p>
193<span class="mark">&#9316;</span> The <tt>poll()</tt>
194function takes a couple more arguments we're not going to use. You can
195simply use <tt>nil</tt> to pass a <tt>NULL</tt> pointer and <tt>0</tt>
196for the <tt>nfds</tt> parameter. Please note that the
197number&nbsp;<tt>0</tt> <em>does not convert to a pointer value</em>,
198unlike in C++. You really have to pass pointers to pointer arguments
199and numbers to number arguments.
200</p>
201<p style="font-size: 8pt;">
202The page on <a href="ext_ffi_semantics.html">FFI semantics</a> has all
203of the gory details about
204<a href="ext_ffi_semantics.html#convert">conversions between Lua
205objects and C&nbsp;types</a>. For the most part you don't have to deal
206with this, as it's performed automatically and it's carefully designed
207to bridge the semantic differences between Lua and C.
208</p>
209<p>
210<span class="mark">&#9317;</span> Now that we have defined
211our own <tt>sleep()</tt> function, we can just call it from plain Lua
212code. That wasn't so bad, huh? Turning these boring animated dots into
213a fascinating best-selling game is left as an exercise for the reader.
214:-)
215</p>
216
217<h2 id="zlib">Accessing the zlib Compression Library</h2>
218<p>
219The following code shows how to access the <a
220href="http://zlib.net/">zlib</a> compression library from Lua code.
221We'll define two convenience wrapper functions that take a string and
222compress or uncompress it to another string:
223</p>
224<pre class="code mark">
225<span class="codemark">&nbsp;
226&#9312;
227
228
229
230
231
232
233&#9313;
234
235
236&#9314;
237
238&#9315;
239
240
241&#9316;
242
243
244&#9317;
245
246
247
248
249
250
251
252&#9318;</span>local ffi = require("ffi")
253ffi.cdef[[
254<span style="color:#00a000;">unsigned long compressBound(unsigned long sourceLen);
255int compress2(uint8_t *dest, unsigned long *destLen,
256 const uint8_t *source, unsigned long sourceLen, int level);
257int uncompress(uint8_t *dest, unsigned long *destLen,
258 const uint8_t *source, unsigned long sourceLen);</span>
259]]
260local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")
261
262local function compress(txt)
263 local n = zlib.compressBound(#txt)
264 local buf = ffi.new("uint8_t[?]", n)
265 local buflen = ffi.new("unsigned long[1]", n)
266 local res = zlib.compress2(buf, buflen, txt, #txt, 9)
267 assert(res == 0)
268 return ffi.string(buf, buflen[0])
269end
270
271local function uncompress(comp, n)
272 local buf = ffi.new("uint8_t[?]", n)
273 local buflen = ffi.new("unsigned long[1]", n)
274 local res = zlib.uncompress(buf, buflen, comp, #comp)
275 assert(res == 0)
276 return ffi.string(buf, buflen[0])
277end
278
279-- Simple test code.
280local txt = string.rep("abcd", 1000)
281print("Uncompressed size: ", #txt)
282local c = compress(txt)
283print("Compressed size: ", #c)
284local txt2 = uncompress(c, #txt)
285assert(txt2 == txt)
286</pre>
287<p>
288Here's the step-by-step explanation:
289</p>
290<p>
291<span class="mark">&#9312;</span> This defines some of the
292C&nbsp;functions provided by zlib. For the sake of this example, some
293type indirections have been reduced and it uses the pre-defined
294fixed-size integer types, while still adhering to the zlib API/ABI.
295</p>
296<p>
297<span class="mark">&#9313;</span> This loads the zlib shared
298library. On POSIX systems it's named <tt>libz.so</tt> and usually
299comes pre-installed. Since <tt>ffi.load()</tt> automatically adds any
300missing standard prefixes/suffixes, we can simply load the
301<tt>"z"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and
302you'll have to download it first from the
303<a href="http://zlib.net/"><span class="ext">&raquo;</span>&nbsp;zlib site</a>. The check for
304<tt>ffi.os</tt> makes sure we pass the right name to
305<tt>ffi.load()</tt>.
306</p>
307<p>
308<span class="mark">&#9314;</span> First, the maximum size of
309the compression buffer is obtained by calling the
310<tt>zlib.compressBound</tt> function with the length of the
311uncompressed string. The next line allocates a byte buffer of this
312size. The <tt>[?]</tt> in the type specification indicates a
313variable-length array (VLA). The actual number of elements of this
314array is given as the 2nd argument to <tt>ffi.new()</tt>.
315</p>
316<p>
317<span class="mark">&#9315;</span> This may look strange at
318first, but have a look at the declaration of the <tt>compress2</tt>
319function from zlib: the destination length is defined as a pointer!
320This is because you pass in the maximum buffer size and get back the
321actual length that was used.
322</p>
323<p>
324In C you'd pass in the address of a local variable
325(<tt>&amp;buflen</tt>). But since there's no address-of operator in
326Lua, we'll just pass in a one-element array. Conveniently it can be
327initialized with the maximum buffer size in one step. Calling the
328actual <tt>zlib.compress2</tt> function is then straightforward.
329</p>
330<p>
331<span class="mark">&#9316;</span> We want to return the
332compressed data as a Lua string, so we'll use <tt>ffi.string()</tt>.
333It needs a pointer to the start of the data and the actual length. The
334length has been returned in the <tt>buflen</tt> array, so we'll just
335get it from there.
336</p>
337<p style="font-size: 8pt;">
338Note that since the function returns now, the <tt>buf</tt> and
339<tt>buflen</tt> variables will eventually be garbage collected. This
340is fine, because <tt>ffi.string()</tt> has copied the contents to a
341newly created (interned) Lua string. If you plan to call this function
342lots of times, consider reusing the buffers and/or handing back the
343results in buffers instead of strings. This will reduce the overhead
344for garbage collection and string interning.
345</p>
346<p>
347<span class="mark">&#9317;</span> The <tt>uncompress</tt>
348functions does the exact opposite of the <tt>compress</tt> function.
349The compressed data doesn't include the size of the original string,
350so this needs to be passed in. Otherwise no surprises here.
351</p>
352<p>
353<span class="mark">&#9318;</span> The code, that makes use
354of the functions we just defined, is just plain Lua code. It doesn't
355need to know anything about the LuaJIT FFI &mdash; the convenience
356wrapper functions completely hide it.
357</p>
358<p>
359One major advantage of the LuaJIT FFI is that you are now able to
360write those wrappers <em>in Lua</em>. And at a fraction of the time it
361would cost you to create an extra C&nbsp;module using the Lua/C API.
362Many of the simpler C&nbsp;functions can probably be used directly
363from your Lua code, without any wrappers.
364</p>
365<p style="font-size: 8pt;">
366Side note: the zlib API uses the <tt>long</tt> type for passing
367lengths and sizes around. But all those zlib functions actually only
368deal with 32&nbsp;bit values. This is an unfortunate choice for a
369public API, but may be explained by zlib's history &mdash; we'll just
370have to deal with it.
371</p>
372<p style="font-size: 8pt;">
373First, you should know that a <tt>long</tt> is a 64&nbsp;bit type e.g.
374on POSIX/x64 systems, but a 32&nbsp;bit type on Windows/x64 and on
37532&nbsp;bit systems. Thus a <tt>long</tt> result can be either a plain
376Lua number or a boxed 64&nbsp;bit integer cdata object, depending on
377the target system.
378</p>
379<p style="font-size: 8pt;">
380Ok, so the <tt>ffi.*</tt> functions generally accept cdata objects
381wherever you'd want to use a number. That's why we get a away with
382passing <tt>n</tt> to <tt>ffi.string()</tt> above. But other Lua
383library functions or modules don't know how to deal with this. So for
384maximum portability one needs to use <tt>tonumber()</tt> on returned
385<tt>long</tt> results before passing them on. Otherwise the
386application might work on some systems, but would fail in a POSIX/x64
387environment.
388</p>
389
390<h2 id="metatype">Defining Metamethods for a C&nbsp;Type</h2>
391<p>
392The following code explains how to define metamethods for a C type.
393We define a simple point type and add some operations to it:
394</p>
395<pre class="code mark">
396<span class="codemark">&nbsp;
397&#9312;
398
399
400
401&#9313;
402
403&#9314;
404
405&#9315;
406
407
408
409&#9316;
410
411&#9317;</span>local ffi = require("ffi")
412ffi.cdef[[
413<span style="color:#00a000;">typedef struct { double x, y; } point_t;</span>
414]]
415
416local point
417local mt = {
418 __add = function(a, b) return point(a.x+b.x, a.y+b.y) end,
419 __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
420 __index = {
421 area = function(a) return a.x*a.x + a.y*a.y end,
422 },
423}
424point = ffi.metatype("point_t", mt)
425
426local a = point(3, 4)
427print(a.x, a.y) --> 3 4
428print(#a) --> 5
429print(a:area()) --> 25
430local b = a + point(0.5, 8)
431print(#b) --> 12.5
432</pre>
433<p>
434Here's the step-by-step explanation:
435</p>
436<p>
437<span class="mark">&#9312;</span> This defines the C&nbsp;type for a
438two-dimensional point object.
439</p>
440<p>
441<span class="mark">&#9313;</span> We have to declare the variable
442holding the point constructor first, because it's used inside of a
443metamethod.
444</p>
445<p>
446<span class="mark">&#9314;</span> Let's define an <tt>__add</tt>
447metamethod which adds the coordinates of two points and creates a new
448point object. For simplicity, this function assumes that both arguments
449are points. But it could be any mix of objects, if at least one operand
450is of the required type (e.g. adding a point plus a number or vice
451versa). Our <tt>__len</tt> metamethod returns the distance of a point to
452the origin.
453</p>
454<p>
455<span class="mark">&#9315;</span> If we run out of operators, we can
456define named methods, too. Here the <tt>__index</tt> table defines an
457<tt>area</tt> function. For custom indexing needs, one might want to
458define <tt>__index</tt> and <tt>__newindex</tt> <em>functions</em> instead.
459</p>
460<p>
461<span class="mark">&#9316;</span> This associates the metamethods with
462our C&nbsp;type. This only needs to be done once. For convenience, a
463constructor is returned by
464<a href="ext_ffi_api.html#ffi_metatype"><tt>ffi.metatype()</tt></a>.
465We're not required to use it, though. The original C&nbsp;type can still
466be used e.g. to create an array of points. The metamethods automatically
467apply to any and all uses of this type.
468</p>
469<p>
470Please note that the association with a metatable is permanent and
471<b>the metatable must not be modified afterwards!</b> Ditto for the
472<tt>__index</tt> table.
473</p>
474<p>
475<span class="mark">&#9317;</span> Here are some simple usage examples
476for the point type and their expected results. The pre-defined
477operations (such as <tt>a.x</tt>) can be freely mixed with the newly
478defined metamethods. Note that <tt>area</tt> is a method and must be
479called with the Lua syntax for methods: <tt>a:area()</tt>, not
480<tt>a.area()</tt>.
481</p>
482<p>
483The C&nbsp;type metamethod mechanism is most useful when used in
484conjunction with C&nbsp;libraries that are written in an object-oriented
485style. Creators return a pointer to a new instance and methods take an
486instance pointer as the first argument. Sometimes you can just point
487<tt>__index</tt> to the library namespace and <tt>__gc</tt> to the
488destructor and you're done. But often enough you'll want to add
489convenience wrappers, e.g. to return actual Lua strings or when
490returning multiple values.
491</p>
492<p>
493Some C libraries only declare instance pointers as an opaque
494<tt>void&nbsp;*</tt> type. In this case you can use a fake type for all
495declarations, e.g. a pointer to a named (incomplete) struct will do:
496<tt>typedef struct foo_type *foo_handle</tt>. The C&nbsp;side doesn't
497know what you declare with the LuaJIT FFI, but as long as the underlying
498types are compatible, everything still works.
499</p>
500
501<h2 id="idioms">Translating C&nbsp;Idioms</h2>
502<p>
503Here's a list of common C&nbsp;idioms and their translation to the
504LuaJIT FFI:
505</p>
506<table class="idiomtable">
507<tr class="idiomhead">
508<td class="idiomdesc">Idiom</td>
509<td class="idiomc">C&nbsp;code</td>
510<td class="idiomlua">Lua code</td>
511</tr>
512<tr class="odd separate">
513<td class="idiomdesc">Pointer dereference<br><tt>int *p;</tt></td><td class="idiomc"><tt>x = *p;<br>*p = y;</tt></td><td class="idiomlua"><tt>x = <b>p[0]</b><br><b>p[0]</b> = y</tt></td></tr>
514<tr class="even">
515<td class="idiomdesc">Pointer indexing<br><tt>int i, *p;</tt></td><td class="idiomc"><tt>x = p[i];<br>p[i+1] = y;</tt></td><td class="idiomlua"><tt>x = p[i]<br>p[i+1] = y</tt></td></tr>
516<tr class="odd">
517<td class="idiomdesc">Array indexing<br><tt>int i, a[];</tt></td><td class="idiomc"><tt>x = a[i];<br>a[i+1] = y;</tt></td><td class="idiomlua"><tt>x = a[i]<br>a[i+1] = y</tt></td></tr>
518<tr class="even separate">
519<td class="idiomdesc"><tt>struct</tt>/<tt>union</tt> dereference<br><tt>struct foo s;</tt></td><td class="idiomc"><tt>x = s.field;<br>s.field = y;</tt></td><td class="idiomlua"><tt>x = s.field<br>s.field = y</tt></td></tr>
520<tr class="odd">
521<td class="idiomdesc"><tt>struct</tt>/<tt>union</tt> pointer deref.<br><tt>struct foo *sp;</tt></td><td class="idiomc"><tt>x = sp->field;<br>sp->field = y;</tt></td><td class="idiomlua"><tt>x = <b>s.field</b><br><b>s.field</b> = y</tt></td></tr>
522<tr class="even separate">
523<td class="idiomdesc">Pointer arithmetic<br><tt>int i, *p;</tt></td><td class="idiomc"><tt>x = p + i;<br>y = p - i;</tt></td><td class="idiomlua"><tt>x = p + i<br>y = p - i</tt></td></tr>
524<tr class="odd">
525<td class="idiomdesc">Pointer difference<br><tt>int *p1, *p2;</tt></td><td class="idiomc"><tt>x = p1 - p2;</tt></td><td class="idiomlua"><tt>x = p1 - p2</tt></td></tr>
526<tr class="even">
527<td class="idiomdesc">Array element pointer<br><tt>int i, a[];</tt></td><td class="idiomc"><tt>x = &amp;a[i];</tt></td><td class="idiomlua"><tt>x = <b>a+i</b></tt></td></tr>
528<tr class="odd">
529<td class="idiomdesc">Cast pointer to address<br><tt>int *p;</tt></td><td class="idiomc"><tt>x = (intptr_t)p;</tt></td><td class="idiomlua"><tt>x = <b>tonumber(<br>&nbsp;ffi.cast("intptr_t",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p))</b></tt></td></tr>
530<tr class="even separate">
531<td class="idiomdesc">Functions with outargs<br><tt>void foo(int *inoutlen);</tt></td><td class="idiomc"><tt>int len = x;<br>foo(&amp;len);<br>y = len;</tt></td><td class="idiomlua"><tt><b>local len =<br>&nbsp;&nbsp;ffi.new("int[1]", x)<br>foo(len)<br>y = len[0]</b></tt></td></tr>
532<tr class="odd">
533<td class="idiomdesc"><a href="ext_ffi_semantics.html#convert_vararg">Vararg conversions</a><br><tt>int printf(char *fmt, ...);</tt></td><td class="idiomc"><tt>printf("%g", 1.0);<br>printf("%d", 1);<br>&nbsp;</tt></td><td class="idiomlua"><tt>printf("%g", 1);<br>printf("%d",<br>&nbsp;&nbsp;<b>ffi.new("int", 1)</b>)</tt></td></tr>
534</table>
535
536<h2 id="cache">To Cache or Not to Cache</h2>
537<p>
538It's a common Lua idiom to cache library functions in local variables
539or upvalues, e.g.:
540</p>
541<pre class="code">
542local byte, char = string.byte, string.char
543local function foo(x)
544 return char(byte(x)+1)
545end
546</pre>
547<p>
548This replaces several hash-table lookups with a (faster) direct use of
549a local or an upvalue. This is less important with LuaJIT, since the
550JIT compiler optimizes hash-table lookups a lot and is even able to
551hoist most of them out of the inner loops. It can't eliminate
552<em>all</em> of them, though, and it saves some typing for often-used
553functions. So there's still a place for this, even with LuaJIT.
554</p>
555<p>
556The situation is a bit different with C&nbsp;function calls via the
557FFI library. The JIT compiler has special logic to eliminate <em>all
558of the lookup overhead</em> for functions resolved from a
559<a href="ext_ffi_semantics.html#clib">C&nbsp;library namespace</a>!
560Thus it's not helpful and actually counter-productive to cache
561individual C&nbsp;functions like this:
562</p>
563<pre class="code">
564local <b>funca</b>, <b>funcb</b> = ffi.C.funcb, ffi.C.funcb -- <span style="color:#c00000;">Not helpful!</span>
565local function foo(x, n)
566 for i=1,n do <b>funcb</b>(<b>funca</b>(x, i), 1) end
567end
568</pre>
569<p>
570This turns them into indirect calls and generates bigger and slower
571machine code. Instead you'll want to cache the namespace itself and
572rely on the JIT compiler to eliminate the lookups:
573</p>
574<pre class="code">
575local <b>C</b> = ffi.C -- <span style="color:#00a000;">Instead use this!</span>
576local function foo(x, n)
577 for i=1,n do <b>C.funcb</b>(<b>C.funca</b>(x, i), 1) end
578end
579</pre>
580<p>
581This generates both shorter and faster code. So <b>don't cache
582C&nbsp;functions</b>, but <b>do</b> cache namespaces! Most often the
583namespace is already in a local variable at an outer scope, e.g. from
584<tt>local&nbsp;lib&nbsp;=&nbsp;ffi.load(...)</tt>. Note that copying
585it to a local variable in the function scope is unnecessary.
586</p>
587<br class="flush">
588</div>
589<div id="foot">
590<hr class="hide">
591Copyright &copy; 2005-2011 Mike Pall
592<span class="noprint">
593&middot;
594<a href="contact.html">Contact</a>
595</span>
596</div>
597</body>
598</html>
diff --git a/libraries/luajit-2.0/doc/ext_jit.html b/libraries/luajit-2.0/doc/ext_jit.html
new file mode 100644
index 0000000..e8f5518
--- /dev/null
+++ b/libraries/luajit-2.0/doc/ext_jit.html
@@ -0,0 +1,195 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>jit.* Library</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11</head>
12<body>
13<div id="site">
14<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
15</div>
16<div id="head">
17<h1><tt>jit.*</tt> Library</h1>
18</div>
19<div id="nav">
20<ul><li>
21<a href="luajit.html">LuaJIT</a>
22<ul><li>
23<a href="install.html">Installation</a>
24</li><li>
25<a href="running.html">Running</a>
26</li></ul>
27</li><li>
28<a href="extensions.html">Extensions</a>
29<ul><li>
30<a href="ext_ffi.html">FFI Library</a>
31<ul><li>
32<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
33</li><li>
34<a href="ext_ffi_api.html">ffi.* API</a>
35</li><li>
36<a href="ext_ffi_semantics.html">FFI Semantics</a>
37</li></ul>
38</li><li>
39<a class="current" href="ext_jit.html">jit.* Library</a>
40</li><li>
41<a href="ext_c_api.html">Lua/C API</a>
42</li></ul>
43</li><li>
44<a href="status.html">Status</a>
45<ul><li>
46<a href="changes.html">Changes</a>
47</li></ul>
48</li><li>
49<a href="faq.html">FAQ</a>
50</li><li>
51<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
52</li><li>
53<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
54</li></ul>
55</div>
56<div id="main">
57<p>
58The functions in this built-in module control the behavior of the JIT
59compiler engine. Note that JIT-compilation is fully automatic &mdash;
60you probably won't need to use any of the following functions unless
61you have special needs.
62</p>
63
64<h3 id="jit_onoff"><tt>jit.on()<br>
65jit.off()</tt></h3>
66<p>
67Turns the whole JIT compiler on (default) or off.
68</p>
69<p>
70These functions are typically used with the command line options
71<tt>-j on</tt> or <tt>-j off</tt>.
72</p>
73
74<h3 id="jit_flush"><tt>jit.flush()</tt></h3>
75<p>
76Flushes the whole cache of compiled code.
77</p>
78
79<h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br>
80jit.off(func|true [,true|false])<br>
81jit.flush(func|true [,true|false])</tt></h3>
82<p>
83<tt>jit.on</tt> enables JIT compilation for a Lua function (this is
84the default).
85</p>
86<p>
87<tt>jit.off</tt> disables JIT compilation for a Lua function and
88flushes any already compiled code from the code cache.
89</p>
90<p>
91<tt>jit.flush</tt> flushes the code, but doesn't affect the
92enable/disable status.
93</p>
94<p>
95The current function, i.e. the Lua function calling this library
96function, can also be specified by passing <tt>true</tt> as the first
97argument.
98</p>
99<p>
100If the second argument is <tt>true</tt>, JIT compilation is also
101enabled, disabled or flushed recursively for all sub-functions of a
102function. With <tt>false</tt> only the sub-functions are affected.
103</p>
104<p>
105The <tt>jit.on</tt> and <tt>jit.off</tt> functions only set a flag
106which is checked when the function is about to be compiled. They do
107not trigger immediate compilation.
108</p>
109<p>
110Typical usage is <tt>jit.off(true, true)</tt> in the main chunk
111of a module to turn off JIT compilation for the whole module for
112debugging purposes.
113</p>
114
115<h3 id="jit_flush_tr"><tt>jit.flush(tr)</tt></h3>
116<p>
117Flushes the root trace, specified by its number, and all of its side
118traces from the cache. The code for the trace will be retained as long
119as there are any other traces which link to it.
120</p>
121
122<h3 id="jit_status"><tt>status, ... = jit.status()</tt></h3>
123<p>
124Returns the current status of the JIT compiler. The first result is
125either <tt>true</tt> or <tt>false</tt> if the JIT compiler is turned
126on or off. The remaining results are strings for CPU-specific features
127and enabled optimizations.
128</p>
129
130<h3 id="jit_version"><tt>jit.version</tt></h3>
131<p>
132Contains the LuaJIT version string.
133</p>
134
135<h3 id="jit_version_num"><tt>jit.version_num</tt></h3>
136<p>
137Contains the version number of the LuaJIT core. Version xx.yy.zz
138is represented by the decimal number xxyyzz.
139</p>
140
141<h3 id="jit_os"><tt>jit.os</tt></h3>
142<p>
143Contains the target OS name:
144"Windows", "Linux", "OSX", "BSD", "POSIX" or "Other".
145</p>
146
147<h3 id="jit_arch"><tt>jit.arch</tt></h3>
148<p>
149Contains the target architecture name:
150"x86", "x64" or "ppcspe".
151</p>
152
153<h2 id="jit_opt"><tt>jit.opt.*</tt> &mdash; JIT compiler optimization control</h2>
154<p>
155This sub-module provides the backend for the <tt>-O</tt> command line
156option.
157</p>
158<p>
159You can also use it programmatically, e.g.:
160</p>
161<pre class="code">
162jit.opt.start(2) -- same as -O2
163jit.opt.start("-dce")
164jit.opt.start("hotloop=10", "hotexit=2")
165</pre>
166<p>
167Unlike in LuaJIT 1.x, the module is built-in and
168<b>optimization is turned on by default!</b>
169It's no longer necessary to run <tt>require("jit.opt").start()</tt>,
170which was one of the ways to enable optimization.
171</p>
172
173<h2 id="jit_util"><tt>jit.util.*</tt> &mdash; JIT compiler introspection</h2>
174<p>
175This sub-module holds functions to introspect the bytecode, generated
176traces, the IR and the generated machine code. The functionality
177provided by this module is still in flux and therefore undocumented.
178</p>
179<p>
180The debug modules <tt>-jbc</tt>, <tt>-jv</tt> and <tt>-jdump</tt> make
181extensive use of these functions. Please check out their source code,
182if you want to know more.
183</p>
184<br class="flush">
185</div>
186<div id="foot">
187<hr class="hide">
188Copyright &copy; 2005-2011 Mike Pall
189<span class="noprint">
190&middot;
191<a href="contact.html">Contact</a>
192</span>
193</div>
194</body>
195</html>
diff --git a/libraries/luajit-2.0/doc/extensions.html b/libraries/luajit-2.0/doc/extensions.html
new file mode 100644
index 0000000..b0e1164
--- /dev/null
+++ b/libraries/luajit-2.0/doc/extensions.html
@@ -0,0 +1,336 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Extensions</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.exc {
13 line-height: 1.2;
14}
15tr.exchead td {
16 font-weight: bold;
17}
18td.excplatform {
19 width: 48%;
20}
21td.exccompiler {
22 width: 29%;
23}
24td.excinterop {
25 width: 23%;
26}
27</style>
28</head>
29<body>
30<div id="site">
31<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
32</div>
33<div id="head">
34<h1>Extensions</h1>
35</div>
36<div id="nav">
37<ul><li>
38<a href="luajit.html">LuaJIT</a>
39<ul><li>
40<a href="install.html">Installation</a>
41</li><li>
42<a href="running.html">Running</a>
43</li></ul>
44</li><li>
45<a class="current" href="extensions.html">Extensions</a>
46<ul><li>
47<a href="ext_ffi.html">FFI Library</a>
48<ul><li>
49<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
50</li><li>
51<a href="ext_ffi_api.html">ffi.* API</a>
52</li><li>
53<a href="ext_ffi_semantics.html">FFI Semantics</a>
54</li></ul>
55</li><li>
56<a href="ext_jit.html">jit.* Library</a>
57</li><li>
58<a href="ext_c_api.html">Lua/C API</a>
59</li></ul>
60</li><li>
61<a href="status.html">Status</a>
62<ul><li>
63<a href="changes.html">Changes</a>
64</li></ul>
65</li><li>
66<a href="faq.html">FAQ</a>
67</li><li>
68<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
69</li><li>
70<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
71</li></ul>
72</div>
73<div id="main">
74<p>
75LuaJIT is fully upwards-compatible with Lua 5.1. It supports all
76<a href="http://www.lua.org/manual/5.1/manual.html#5"><span class="ext">&raquo;</span>&nbsp;standard Lua
77library functions</a> and the full set of
78<a href="http://www.lua.org/manual/5.1/manual.html#3"><span class="ext">&raquo;</span>&nbsp;Lua/C API
79functions</a>.
80</p>
81<p>
82LuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic
83loader level. This means you can compile a C&nbsp;module against the
84standard Lua headers and load the same shared library from either Lua
85or LuaJIT.
86</p>
87<p>
88LuaJIT extends the standard Lua VM with new functionality and adds
89several extension modules. Please note that this page is only about
90<em>functional</em> enhancements and not about performance enhancements,
91such as the optimized VM, the faster interpreter or the JIT compiler.
92</p>
93
94<h2 id="modules">Extensions Modules</h2>
95<p>
96LuaJIT comes with several built-in extension modules:
97</p>
98
99<h3 id="bit"><tt>bit.*</tt> &mdash; Bitwise operations</h3>
100<p>
101LuaJIT supports all bitwise operations as defined by
102<a href="http://bitop.luajit.org"><span class="ext">&raquo;</span>&nbsp;Lua BitOp</a>:
103</p>
104<pre class="code">
105bit.tobit bit.tohex bit.bnot bit.band bit.bor bit.bxor
106bit.lshift bit.rshift bit.arshift bit.rol bit.ror bit.bswap
107</pre>
108<p>
109This module is a LuaJIT built-in &mdash; you don't need to download or
110install Lua BitOp. The Lua BitOp site has full documentation for all
111<a href="http://bitop.luajit.org/api.html"><span class="ext">&raquo;</span>&nbsp;Lua BitOp API functions</a>.
112</p>
113<p>
114Please make sure to <tt>require</tt> the module before using any of
115its functions:
116</p>
117<pre class="code">
118local bit = require("bit")
119</pre>
120<p>
121An already installed Lua BitOp module is ignored by LuaJIT.
122This way you can use bit operations from both Lua and LuaJIT on a
123shared installation.
124</p>
125
126<h3 id="ffi"><tt>ffi.*</tt> &mdash; FFI library</h3>
127<p>
128The <a href="ext_ffi.html">FFI library</a> allows calling external
129C&nbsp;functions and the use of C&nbsp;data structures from pure Lua
130code.
131</p>
132
133<h3 id="jit"><tt>jit.*</tt> &mdash; JIT compiler control</h3>
134<p>
135The functions in this module
136<a href="ext_jit.html">control the behavior of the JIT compiler engine</a>.
137</p>
138
139<h3 id="c_api">C API extensions</h3>
140<p>
141LuaJIT adds some
142<a href="ext_c_api.html">extra functions to the Lua/C API</a>.
143</p>
144
145<h2 id="library">Enhanced Standard Library Functions</h2>
146
147<h3 id="xpcall"><tt>xpcall(f, err [,args...])</tt> passes arguments</h3>
148<p>
149Unlike the standard implementation in Lua 5.1, <tt>xpcall()</tt>
150passes any arguments after the error function to the function
151which is called in a protected context.
152</p>
153
154<h3 id="load"><tt>loadfile()</tt> etc. handle UTF-8 source code</h3>
155<p>
156Non-ASCII characters are handled transparently by the Lua source code parser.
157This allows the use of UTF-8 characters in identifiers and strings.
158A UTF-8 BOM is skipped at the start of the source code.
159</p>
160
161<h3 id="tostring"><tt>tostring()</tt> etc. canonicalize NaN and &plusmn;Inf</h3>
162<p>
163All number-to-string conversions consistently convert non-finite numbers
164to the same strings on all platforms. NaN results in <tt>"nan"</tt>,
165positive infinity results in <tt>"inf"</tt> and negative infinity results
166in <tt>"-inf"</tt>.
167</p>
168
169<h3 id="string_dump"><tt>string.dump(f [,strip])</tt> generates portable bytecode</h3>
170<p>
171An extra argument has been added to <tt>string.dump()</tt>. If set to
172<tt>true</tt>, 'stripped' bytecode without debug information is
173generated. This speeds up later bytecode loading and reduces memory
174usage. See also the
175<a href="running.html#opt_b"><tt>-b</tt> command line option</a>.
176</p>
177<p>
178The generated bytecode is portable and can be loaded on any architecture
179that LuaJIT supports, independent of word size or endianess. However the
180bytecode compatibility versions must match. Bytecode stays compatible
181for dot releases (x.y.0 &rarr; x.y.1), but may change with major or
182minor releases (2.0 &rarr; 2.1) or between any beta release. Foreign
183bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
184</p>
185
186<h3 id="math_random">Enhanced PRNG for <tt>math.random()</tt></h3>
187<p>
188LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
189<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of
190the PRNG results is much superior compared to the standard Lua
191implementation which uses the platform-specific ANSI rand().
192</p>
193<p>
194The PRNG generates the same sequences from the same seeds on all
195platforms and makes use of all bits in the seed argument.
196<tt>math.random()</tt> without arguments generates 52 pseudo-random bits
197for every call. The result is uniformly distributed between 0 and 1.
198It's correctly scaled up and rounded for <tt>math.random(n&nbsp;[,m])</tt> to
199preserve uniformity.
200</p>
201
202<h3 id="io"><tt>io.*</tt> functions handle 64&nbsp;bit file offsets</h3>
203<p>
204The file I/O functions in the standard <tt>io.*</tt> library handle
20564&nbsp;bit file offsets. In particular this means it's possible
206to open files larger than 2&nbsp;Gigabytes and to reposition or obtain
207the current file position for offsets beyond 2&nbsp;GB
208(<tt>fp:seek()</tt> method).
209</p>
210
211<h3 id="debug_meta"><tt>debug.*</tt> functions identify metamethods</h3>
212<p>
213<tt>debug.getinfo()</tt> and <tt>lua_getinfo()</tt> also return information
214about invoked metamethods. The <tt>namewhat</tt> field is set to
215<tt>"metamethod"</tt> and the <tt>name</tt> field has the name of
216the corresponding metamethod (e.g. <tt>"__index"</tt>).
217</p>
218
219<h2 id="resumable">Fully Resumable VM</h2>
220<p>
221The LuaJIT 2.x VM is fully resumable. This means you can yield from a
222coroutine even across contexts, where this would not possible with
223the standard Lua&nbsp;5.1 VM: e.g. you can yield across <tt>pcall()</tt>
224and <tt>xpcall()</tt>, across iterators and across metamethods.
225</p>
226<p>
227Note however that LuaJIT 2.x doesn't use
228<a href="http://coco.luajit.org/"><span class="ext">&raquo;</span>&nbsp;Coco</a> anymore. This means the
229overhead for creating coroutines is much smaller and no extra
230C&nbsp;stacks need to be allocated. OTOH you can no longer yield
231across arbitrary C&nbsp;functions. Keep this in mind when
232upgrading from LuaJIT 1.x.
233</p>
234
235<h2 id="exceptions">C++ Exception Interoperability</h2>
236<p>
237LuaJIT has built-in support for interoperating with C++&nbsp;exceptions.
238The available range of features depends on the target platform and
239the toolchain used to compile LuaJIT:
240</p>
241<table class="exc">
242<tr class="exchead">
243<td class="excplatform">Platform</td>
244<td class="exccompiler">Compiler</td>
245<td class="excinterop">Interoperability</td>
246</tr>
247<tr class="odd separate">
248<td class="excplatform">POSIX/x64, DWARF2 unwinding</td>
249<td class="exccompiler">GCC 4.3+</td>
250<td class="excinterop"><b style="color: #00a000;">Full</b></td>
251</tr>
252<tr class="even">
253<td class="excplatform">Other platforms, DWARF2 unwinding</td>
254<td class="exccompiler">GCC</td>
255<td class="excinterop"><b style="color: #c06000;">Limited</b></td>
256</tr>
257<tr class="odd">
258<td class="excplatform">Windows/x64</td>
259<td class="exccompiler">MSVC or WinSDK</td>
260<td class="excinterop"><b style="color: #00a000;">Full</b></td>
261</tr>
262<tr class="even">
263<td class="excplatform">Windows/x86</td>
264<td class="exccompiler">Any</td>
265<td class="excinterop"><b style="color: #a00000;">No</b></td>
266</tr>
267<tr class="odd">
268<td class="excplatform">Other platforms</td>
269<td class="exccompiler">Other compilers</td>
270<td class="excinterop"><b style="color: #a00000;">No</b></td>
271</tr>
272</table>
273<p>
274<b style="color: #00a000;">Full interoperability</b> means:
275</p>
276<ul>
277<li>C++&nbsp;exceptions can be caught on the Lua side with <tt>pcall()</tt>,
278<tt>lua_pcall()</tt> etc.</li>
279<li>C++&nbsp;exceptions will be converted to the generic Lua error
280<tt>"C++&nbsp;exception"</tt>, unless you use the
281<a href="ext_c_api.html#mode_wrapcfunc">C&nbsp;call wrapper</a> feature.</li>
282<li>It's safe to throw C++&nbsp;exceptions across non-protected Lua frames
283on the C&nbsp;stack. The contents of the C++&nbsp;exception object
284pass through unmodified.</li>
285<li>Lua errors can be caught on the C++ side with <tt>catch(...)</tt>.
286The corresponding Lua error message can be retrieved from the Lua stack.</li>
287<li>Throwing Lua errors across C++ frames is safe. C++ destructors
288will be called.</li>
289</ul>
290<p>
291<b style="color: #c06000;">Limited interoperability</b> means:
292</p>
293<ul>
294<li>C++&nbsp;exceptions can be caught on the Lua side with <tt>pcall()</tt>,
295<tt>lua_pcall()</tt> etc.</li>
296<li>C++&nbsp;exceptions will be converted to the generic Lua error
297<tt>"C++&nbsp;exception"</tt>, unless you use the
298<a href="ext_c_api.html#mode_wrapcfunc">C&nbsp;call wrapper</a> feature.</li>
299<li>C++&nbsp;exceptions will be caught by non-protected Lua frames and
300are rethrown as a generic Lua error. The C++&nbsp;exception object will
301be destroyed.</li>
302<li>Lua errors <b>cannot</b> be caught on the C++ side.</li>
303<li>Throwing Lua errors across C++ frames will <b>not</b> call
304C++ destructors.</li>
305</ul>
306
307<p>
308<b style="color: #a00000;">No interoperability</b> means:
309</p>
310<ul>
311<li>It's <b>not</b> safe to throw C++&nbsp;exceptions across Lua frames.</li>
312<li>C++&nbsp;exceptions <b>cannot</b> be caught on the Lua side.</li>
313<li>Lua errors <b>cannot</b> be caught on the C++ side.</li>
314<li>Throwing Lua errors across C++ frames will <b>not</b> call
315C++ destructors.</li>
316<li>Additionally, on Windows/x86 with SEH-based C++&nbsp;exceptions:
317it's <b>not</b> safe to throw a Lua error across any frames containing
318a C++ function with any try/catch construct or using variables with
319(implicit) destructors. This also applies to any functions which may be
320inlined in such a function. It doesn't matter whether <tt>lua_error()</tt>
321is called inside or outside of a try/catch or whether any object actually
322needs to be destroyed: the SEH chain is corrupted and this will eventually
323lead to the termination of the process.</li>
324</ul>
325<br class="flush">
326</div>
327<div id="foot">
328<hr class="hide">
329Copyright &copy; 2005-2011 Mike Pall
330<span class="noprint">
331&middot;
332<a href="contact.html">Contact</a>
333</span>
334</div>
335</body>
336</html>
diff --git a/libraries/luajit-2.0/doc/faq.html b/libraries/luajit-2.0/doc/faq.html
new file mode 100644
index 0000000..b28a72c
--- /dev/null
+++ b/libraries/luajit-2.0/doc/faq.html
@@ -0,0 +1,180 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Frequently Asked Questions (FAQ)</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12dd { margin-left: 1.5em; }
13</style>
14</head>
15<body>
16<div id="site">
17<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
18</div>
19<div id="head">
20<h1>Frequently Asked Questions (FAQ)</h1>
21</div>
22<div id="nav">
23<ul><li>
24<a href="luajit.html">LuaJIT</a>
25<ul><li>
26<a href="install.html">Installation</a>
27</li><li>
28<a href="running.html">Running</a>
29</li></ul>
30</li><li>
31<a href="extensions.html">Extensions</a>
32<ul><li>
33<a href="ext_ffi.html">FFI Library</a>
34<ul><li>
35<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
36</li><li>
37<a href="ext_ffi_api.html">ffi.* API</a>
38</li><li>
39<a href="ext_ffi_semantics.html">FFI Semantics</a>
40</li></ul>
41</li><li>
42<a href="ext_jit.html">jit.* Library</a>
43</li><li>
44<a href="ext_c_api.html">Lua/C API</a>
45</li></ul>
46</li><li>
47<a href="status.html">Status</a>
48<ul><li>
49<a href="changes.html">Changes</a>
50</li></ul>
51</li><li>
52<a class="current" href="faq.html">FAQ</a>
53</li><li>
54<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
55</li><li>
56<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
57</li></ul>
58</div>
59<div id="main">
60<dl>
61<dt>Q: Where can I learn more about Lua and LuaJIT?</dt>
62<dd>
63<ul style="padding: 0;">
64<li>The <a href="http://lua.org"><span class="ext">&raquo;</span>&nbsp;main Lua.org site</a> has complete
65<a href="http://www.lua.org/docs.html"><span class="ext">&raquo;</span>&nbsp;documentation</a> of the language
66and links to books and papers about Lua.</li>
67<li>The community-managed <a href="http://lua-users.org/wiki/"><span class="ext">&raquo;</span>&nbsp;Lua Wiki</a>
68has information about diverse topics.</li>
69<li>The primary source of information for the latest developments surrounding
70Lua is the <a href="http://www.lua.org/lua-l.html"><span class="ext">&raquo;</span>&nbsp;Lua mailing list</a>.
71You can check out the <a href="http://lua-users.org/lists/lua-l/"><span class="ext">&raquo;</span>&nbsp;mailing
72list archive</a> or
73<a href="http://bazar2.conectiva.com.br/mailman/listinfo/lua"><span class="ext">&raquo;</span>&nbsp;subscribe</a>
74to the list (you need to be subscribed before posting).<br>
75This is also the place where announcements and discussions about LuaJIT
76take place.</li>
77</ul>
78</dl>
79
80<dl>
81<dt>Q: Where can I learn more about the compiler technology used by LuaJIT?</dt>
82<dd>
83I'm planning to write more documentation about the internals of LuaJIT.
84In the meantime, please use the following Google Scholar searches
85to find relevant papers:<br>
86Search for: <a href="http://scholar.google.com/scholar?q=Trace+Compiler"><span class="ext">&raquo;</span>&nbsp;Trace Compiler</a><br>
87Search for: <a href="http://scholar.google.com/scholar?q=JIT+Compiler"><span class="ext">&raquo;</span>&nbsp;JIT Compiler</a><br>
88Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">&raquo;</span>&nbsp;Dynamic Language Optimizations</a><br>
89Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">&raquo;</span>&nbsp;SSA Form</a><br>
90Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">&raquo;</span>&nbsp;Linear Scan Register Allocation</a><br>
91Here is a list of the <a href="http://article.gmane.org/gmane.comp.lang.lua.general/58908"><span class="ext">&raquo;</span>&nbsp;innovative features in LuaJIT</a>.<br>
92And, you know, reading the source is of course the only way to enlightenment. :-)
93</dd>
94</dl>
95
96<dl>
97<dt>Q: Why do I get this error: "attempt to index global 'arg' (a nil value)"?<br>
98Q: My vararg functions fail after switching to LuaJIT!</dt>
99<dd>LuaJIT is compatible to the Lua 5.1 language standard. It doesn't
100support the implicit <tt>arg</tt> parameter for old-style vararg
101functions from Lua 5.0.<br>Please convert your code to the
102<a href="http://www.lua.org/manual/5.1/manual.html#2.5.9"><span class="ext">&raquo;</span>&nbsp;Lua 5.1
103vararg syntax</a>.</dd>
104</dl>
105
106<dl>
107<dt>Q: Why do I get this error: "bad FPU precision"?<br>
108<dt>Q: I get weird behavior after initializing Direct3D.<br>
109<dt>Q: Some FPU operations crash after I load a Delphi DLL.<br>
110</dt>
111<dd>
112
113DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision
114mode by default. This violates the Windows ABI and interferes with the
115operation of many programs &mdash; LuaJIT is affected, too. Please make
116sure you always use the <tt>D3DCREATE_FPU_PRESERVE</tt> flag when
117initializing Direct3D.<br>
118
119Direct3D version 10 or higher do not show this behavior anymore.
120Consider testing your application with older versions, too.<br>
121
122Similarly, the Borland/Delphi runtime modifies the FPU control word and
123enables FP exceptions. Of course this violates the Windows ABI, too.
124Please check the Delphi docs for the Set8087CW method.
125
126</dl>
127
128<dl>
129<dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt>
130<dd>The interrupt signal handler sets a Lua debug hook. But this is
131currently ignored by compiled code (this will eventually be fixed). If
132your program is running in a tight loop and never falls back to the
133interpreter, the debug hook never runs and can't throw the
134"interrupted!" error.<br> In the meantime you have to press Ctrl-C
135twice to get stop your program. That's similar to when it's stuck
136running inside a C function under the Lua interpreter.</dd>
137</dl>
138
139<dl>
140<dt>Q: Why doesn't my favorite power-patch for Lua apply against LuaJIT?</dt>
141<dd>Because it's a completely redesigned VM and has very little code
142in common with Lua anymore. Also, if the patch introduces changes to
143the Lua semantics, these would need to be reflected everywhere in the
144VM, from the interpreter up to all stages of the compiler.<br> Please
145use only standard Lua language constructs. For many common needs you
146can use source transformations or use wrapper or proxy functions.
147The compiler will happily optimize away such indirections.</dd>
148</dl>
149
150<dl>
151<dt>Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?</dt>
152<dd>Because it's a compiler &mdash; it needs to generate native
153machine code. This means the code generator must be ported to each
154architecture. And the fast interpreter is written in assembler and
155must be ported, too. This is quite an undertaking.<br>
156The <a href="install.html">install documentation</a> shows the supported
157architectures. Other architectures will follow based on sufficient user
158demand and/or sponsoring.</dd>
159</dl>
160
161<dl>
162<dt>Q: When will feature X be added? When will the next version be released?</dt>
163<dd>When it's ready.<br>
164C'mon, it's open source &mdash; I'm doing it on my own time and you're
165getting it for free. You can either contribute a patch or sponsor
166the development of certain features, if they are important to you.
167</dd>
168</dl>
169<br class="flush">
170</div>
171<div id="foot">
172<hr class="hide">
173Copyright &copy; 2005-2011 Mike Pall
174<span class="noprint">
175&middot;
176<a href="contact.html">Contact</a>
177</span>
178</div>
179</body>
180</html>
diff --git a/libraries/luajit-2.0/doc/img/contact.png b/libraries/luajit-2.0/doc/img/contact.png
new file mode 100644
index 0000000..9c73dc5
--- /dev/null
+++ b/libraries/luajit-2.0/doc/img/contact.png
Binary files differ
diff --git a/libraries/luajit-2.0/doc/install.html b/libraries/luajit-2.0/doc/install.html
new file mode 100644
index 0000000..07c55fa
--- /dev/null
+++ b/libraries/luajit-2.0/doc/install.html
@@ -0,0 +1,543 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Installation</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.compat {
13 line-height: 1.2;
14 width: 600px;
15}
16table.compat td {
17 border: 1px solid #bfcfff;
18 font-size: 90%;
19 height: 2.5em;
20}
21table.compat tr.compathead td {
22 font-weight: bold;
23 border-bottom: 2px solid #bfcfff;
24}
25tr.compathead td.compatos {
26 vertical-align: top;
27}
28table.compat td.compatcpu {
29 width: 16%;
30 border-right: 2px solid #bfcfff;
31}
32td.compatos {
33 width: 21%;
34 vertical-align: middle;
35}
36td.compatno {
37 background-color: #d0d0d0;
38}
39</style>
40</head>
41<body>
42<div id="site">
43<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
44</div>
45<div id="head">
46<h1>Installation</h1>
47</div>
48<div id="nav">
49<ul><li>
50<a href="luajit.html">LuaJIT</a>
51<ul><li>
52<a class="current" href="install.html">Installation</a>
53</li><li>
54<a href="running.html">Running</a>
55</li></ul>
56</li><li>
57<a href="extensions.html">Extensions</a>
58<ul><li>
59<a href="ext_ffi.html">FFI Library</a>
60<ul><li>
61<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
62</li><li>
63<a href="ext_ffi_api.html">ffi.* API</a>
64</li><li>
65<a href="ext_ffi_semantics.html">FFI Semantics</a>
66</li></ul>
67</li><li>
68<a href="ext_jit.html">jit.* Library</a>
69</li><li>
70<a href="ext_c_api.html">Lua/C API</a>
71</li></ul>
72</li><li>
73<a href="status.html">Status</a>
74<ul><li>
75<a href="changes.html">Changes</a>
76</li></ul>
77</li><li>
78<a href="faq.html">FAQ</a>
79</li><li>
80<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
81</li><li>
82<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
83</li></ul>
84</div>
85<div id="main">
86<p>
87LuaJIT is only distributed as a source package. This page explains
88how to build and install LuaJIT with different operating systems
89and C&nbsp;compilers.
90</p>
91<p>
92For the impatient (on POSIX systems):
93</p>
94<pre class="code">
95make &amp;&amp; sudo make install
96</pre>
97<p>
98LuaJIT currently builds out-of-the box on most systems.
99Here's the compatibility matrix for the supported combinations of
100operating systems, CPUs and compilers:
101</p>
102<table class="compat">
103<tr class="compathead">
104<td class="compatcpu">CPU / OS</td>
105<td class="compatos"><a href="#posix">Linux</a> or<br><a href="#android">Android</a></td>
106<td class="compatos"><a href="#posix">*BSD, Other</a></td>
107<td class="compatos"><a href="#posix">OSX 10.3+</a> or<br><a href="#ios">iOS 3.0+</a></td>
108<td class="compatos"><a href="#windows">Windows<br>XP/Vista/7</a></td>
109</tr>
110<tr class="odd separate">
111<td class="compatcpu">x86 (32 bit)</td>
112<td class="compatos">GCC 4.x<br>GCC 3.4</td>
113<td class="compatos">GCC 4.x<br>GCC 3.4</td>
114<td class="compatos">GCC 4.x<br>GCC 3.4</td>
115<td class="compatos">MSVC, MSVC/EE<br>WinSDK<br>MinGW, Cygwin</td>
116</tr>
117<tr class="even">
118<td class="compatcpu">x64 (64 bit)</td>
119<td class="compatos">GCC 4.x</td>
120<td class="compatos compatno">&nbsp;</td>
121<td class="compatos">GCC 4.x</td>
122<td class="compatos">MSVC + SDK v7.0<br>WinSDK v7.0</td>
123</tr>
124<tr class="odd">
125<td class="compatcpu"><a href="#android">ARMv5+<br>ARM9E+</a></td>
126<td class="compatos">GCC 4.2+</td>
127<td class="compatos">GCC 4.2+</td>
128<td class="compatos">GCC 4.2+</td>
129<td class="compatos compatno">&nbsp;</td>
130</tr>
131<tr class="even">
132<td class="compatcpu"><a href="#ppc">PPC</a></td>
133<td class="compatos">GCC 4.3+</td>
134<td class="compatos">GCC 4.3+</td>
135<td class="compatos compatno">&nbsp;</td>
136<td class="compatos compatno">&nbsp;</td>
137</tr>
138<tr class="odd">
139<td class="compatcpu"><a href="#ppc">PPC/e500v2</a></td>
140<td class="compatos">GCC 4.3+</td>
141<td class="compatos">GCC 4.3+</td>
142<td class="compatos compatno">&nbsp;</td>
143<td class="compatos compatno">&nbsp;</td>
144</tr>
145</table>
146
147<h2>Configuring LuaJIT</h2>
148<p>
149The standard configuration should work fine for most installations.
150Usually there is no need to tweak the settings. The following files
151hold all user-configurable settings:
152</p>
153<ul>
154<li><tt>src/luaconf.h</tt> sets some configuration variables.</li>
155<li><tt>Makefile</tt> has settings for <b>installing</b> LuaJIT (POSIX
156only).</li>
157<li><tt>src/Makefile</tt> has settings for <b>compiling</b> LuaJIT
158under POSIX, MinGW or Cygwin.</li>
159<li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with
160MSVC or WinSDK.</li>
161</ul>
162<p>
163Please read the instructions given in these files, before changing
164any settings.
165</p>
166
167<h2 id="posix">POSIX Systems (Linux, OSX, *BSD etc.)</h2>
168<h3>Prerequisites</h3>
169<p>
170Depending on your distribution, you may need to install a package for
171GCC, the development headers and/or a complete SDK. E.g. on a current
172Debian/Ubuntu, install <tt>libc6-dev</tt> with the package manager.
173</p>
174<p>
175Download the current source package of LuaJIT (pick the .tar.gz),
176if you haven't already done so. Move it to a directory of your choice,
177open a terminal window and change to this directory. Now unpack the archive
178and change to the newly created directory:
179</p>
180<pre class="code">
181tar zxf LuaJIT-2.0.0-beta9.tar.gz
182cd LuaJIT-2.0.0-beta9</pre>
183<h3>Building LuaJIT</h3>
184<p>
185The supplied Makefiles try to auto-detect the settings needed for your
186operating system and your compiler. They need to be run with GNU Make,
187which is probably the default on your system, anyway. Simply run:
188</p>
189<pre class="code">
190make
191</pre>
192<p>
193This always builds a native x86, x64 or PPC binary, depending on the host OS
194you're running this command on. Check the section on
195<a href="#cross">cross-compilation</a> for more options.
196</p>
197<p>
198By default, modules are only searched under the prefix <tt>/usr/local</tt>.
199You can add an extra prefix to the search paths by appending the
200<tt>PREFIX</tt> option, e.g.:
201</p>
202<pre class="code">
203make PREFIX=/home/myself/lj2
204</pre>
205<p>
206Note for OSX: <tt>MACOSX_DEPLOYMENT_TARGET</tt> is set to <tt>10.4</tt>
207in <tt>src/Makefile</tt>. Change it, if you want to build on an older version.
208</p>
209<h3>Installing LuaJIT</h3>
210<p>
211The top-level Makefile installs LuaJIT by default under
212<tt>/usr/local</tt>, i.e. the executable ends up in
213<tt>/usr/local/bin</tt> and so on. You need root privileges
214to write to this path. So, assuming sudo is installed on your system,
215run the following command and enter your sudo password:
216</p>
217<pre class="code">
218sudo make install
219</pre>
220<p>
221Otherwise specify the directory prefix as an absolute path, e.g.:
222</p>
223<pre class="code">
224make install PREFIX=/home/myself/lj2
225</pre>
226<p>
227Obviously the prefixes given during build and installation need to be the same.
228</p>
229<p style="color: #c00000;">
230Note: to avoid overwriting a previous version, the beta test releases
231only install the LuaJIT executable under the versioned name (i.e.
232<tt>luajit-2.0.0-beta9</tt>). You probably want to create a symlink
233for convenience, with a command like this:
234</p>
235<pre class="code" style="color: #c00000;">
236sudo ln -sf luajit-2.0.0-beta9&nbsp;/usr/local/bin/luajit
237</pre>
238
239<h2 id="windows">Windows Systems</h2>
240<h3>Prerequisites</h3>
241<p>
242Either install one of the open source SDKs
243(<a href="http://mingw.org/"><span class="ext">&raquo;</span>&nbsp;MinGW</a> or
244<a href="http://www.cygwin.com/"><span class="ext">&raquo;</span>&nbsp;Cygwin</a>), which come with a modified
245GCC plus the required development headers.
246</p>
247<p>
248Or install Microsoft's Visual C++ (MSVC). The freely downloadable
249<a href="http://www.microsoft.com/Express/VC/"><span class="ext">&raquo;</span>&nbsp;Express Edition</a>
250works just fine, but only contains an x86 compiler.
251</p>
252<p>
253The freely downloadable
254<a href="http://msdn.microsoft.com/en-us/windowsserver/bb980924.aspx"><span class="ext">&raquo;</span>&nbsp;Windows SDK</a>
255only comes with command line tools, but this is all you need to build LuaJIT.
256It contains x86 and x64 compilers.
257</p>
258<p>
259Next, download the source package and unpack it using an archive manager
260(e.g. the Windows Explorer) to a directory of your choice.
261</p>
262<h3>Building with MSVC</h3>
263<p>
264Open a "Visual Studio .NET Command Prompt", <tt>cd</tt> to the
265directory where you've unpacked the sources and run these commands:
266</p>
267<pre class="code">
268cd src
269msvcbuild
270</pre>
271<p>
272Then follow the installation instructions below.
273</p>
274<h3>Building with the Windows SDK</h3>
275<p>
276Open a "Windows SDK Command Shell" and select the x86 compiler:
277</p>
278<pre class="code">
279setenv /release /x86
280</pre>
281<p>
282Or select the x64 compiler:
283</p>
284<pre class="code">
285setenv /release /x64
286</pre>
287<p>
288Then <tt>cd</tt> to the directory where you've unpacked the sources
289and run these commands:
290</p>
291<pre class="code">
292cd src
293msvcbuild
294</pre>
295<p>
296Then follow the installation instructions below.
297</p>
298<h3>Building with MinGW or Cygwin</h3>
299<p>
300Open a command prompt window and make sure the MinGW or Cygwin programs
301are in your path. Then <tt>cd</tt> to the directory where
302you've unpacked the sources and run this command for MinGW:
303</p>
304<pre class="code">
305mingw32-make
306</pre>
307<p>
308Or this command for Cygwin:
309</p>
310<pre class="code">
311make
312</pre>
313<p>
314Then follow the installation instructions below.
315</p>
316<h3>Installing LuaJIT</h3>
317<p>
318Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> (built in the <tt>src</tt>
319directory) to a newly created directory (any location is ok).
320Add <tt>lua</tt> and <tt>lua\jit</tt> directories below it and copy
321all Lua files from the <tt>lib</tt> directory of the distribution
322to the latter directory.
323</p>
324<p>
325There are no hardcoded
326absolute path names &mdash; all modules are loaded relative to the
327directory where <tt>luajit.exe</tt> is installed
328(see <tt>src/luaconf.h</tt>).
329</p>
330
331<h2 id="cross">Cross-compiling LuaJIT</h2>
332<p>
333The build system has limited support for cross-compilation. For details
334check the comments in <tt>src/Makefile</tt>. Here are some popular examples:
335</p>
336<p>
337You can cross-compile to a <b>32 bit binary on a multilib x64 OS</b> by
338installing the multilib development packages (e.g. <tt>libc6-dev-i386</tt>
339on Debian/Ubuntu) and running:
340</p>
341<pre class="code">
342make CC="gcc -m32"
343</pre>
344<p>
345You can cross-compile for a <b>Windows target on Debian/Ubuntu</b> by
346installing the <tt>mingw32</tt> package and running:
347</p>
348<pre class="code">
349make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
350</pre>
351<p>
352You can cross-compile for an <b>ARM target</b> on an x86 or x64 host
353system using a standard GNU cross-compile toolchain (Binutils, GCC,
354EGLIBC). The <tt>CROSS</tt> prefix may vary depending on the
355<tt>--target</tt> of the toolchain:
356</p>
357<pre class="code">
358make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi-
359</pre>
360<p>
361You can cross-compile for <b id="android">Android (ARM)</b> using the <a href="http://developer.android.com/sdk/ndk/index.html"><span class="ext">&raquo;</span>&nbsp;Android NDK</a>.
362The environment variables need to match the install locations and the
363desired target platform. E.g. Android&nbsp;2.2 corresponds to ABI level&nbsp;8:
364</p>
365<pre class="code">
366NDK=/opt/android/ndk
367NDKABI=8
368NDKVER=$NDK/toolchains/arm-linux-androideabi-4.4.3
369NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi-
370NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
371make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
372</pre>
373<p>
374You can cross-compile for <b id="ios">iOS 3.0+</b> (iPhone/iPad) using the <a href="http://developer.apple.com/devcenter/ios/index.action"><span class="ext">&raquo;</span>&nbsp;iOS SDK</a>.
375The environment variables need to match the iOS SDK version:
376</p>
377<p style="font-size: 8pt;">
378Note: <b>the JIT compiler is disabled for iOS</b>, because regular iOS Apps
379are not allowed to generate code at runtime. You'll only get the performance
380of the LuaJIT interpreter on iOS. This is still faster than plain Lua, but
381much slower than the JIT compiler. Please complain to Apple, not me.
382Or use Android. :-p
383</p>
384<pre class="code">
385ISDK=/Developer/Platforms/iPhoneOS.platform/Developer
386ISDKVER=iPhoneOS4.3.sdk
387ISDKP=$ISDK/usr/bin/
388ISDKF="-arch armv6 -isysroot $ISDK/SDKs/$ISDKVER"
389make HOST_CC="gcc -m32 -arch i386" CROSS=$ISDKP TARGET_FLAGS="$ISDKF" \
390 TARGET_SYS=iOS
391</pre>
392<p>
393You can cross-compile for a <b id="ppc">PPC target</b> or a
394<b>PPC/e500v2 target</b> on x86 or x64 host systems using a standard
395GNU cross-compile toolchain (Binutils, GCC, EGLIBC).
396The <tt>CROSS</tt> prefix may vary depending on the <tt>--target</tt>
397of the toolchain:
398</p>
399<pre class="code">
400# PPC
401make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
402</pre>
403<pre class="code">
404# PPC/e500v2
405make HOST_CC="gcc -m32" CROSS=powerpc-e500v2-linux-gnuspe-
406</pre>
407<p>
408Whenever the <b>host OS and the target OS differ</b>, you need to specify
409<tt>TARGET_SYS</tt> or you'll get assembler or linker errors. E.g. if
410you're compiling on a Windows or OSX host for embedded Linux or Android,
411you need to add <tt>TARGET_SYS=Linux</tt> to the examples above. For a
412minimal target OS, you may need to disable the built-in allocator in
413<tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.
414</p>
415
416<h2 id="embed">Embedding LuaJIT</h2>
417<p>
418LuaJIT is API-compatible with Lua 5.1. If you've already embedded Lua
419into your application, you probably don't need to do anything to switch
420to LuaJIT, except link with a different library:
421</p>
422<ul>
423<li>It's strongly suggested to build LuaJIT separately using the supplied
424build system. Please do <em>not</em> attempt to integrate the individual
425source files into your build tree. You'll most likely get the internal build
426dependencies wrong or mess up the compiler flags. Treat LuaJIT like any
427other external library and link your application with either the dynamic
428or static library, depending on your needs.</li>
429<li>If you want to load C modules compiled for plain Lua
430with <tt>require()</tt>, you need to make sure the public symbols
431(e.g. <tt>lua_pushnumber</tt>) are exported, too:
432<ul><li>On POSIX systems you can either link to the shared library
433or link the static library into your application. In the latter case
434you'll need to export all public symbols from your main executable
435(e.g. <tt>-Wl,-E</tt> on Linux) and add the external dependencies
436(e.g. <tt>-lm -ldl</tt> on Linux).</li>
437<li>Since Windows symbols are bound to a specific DLL name, you need to
438link to the <tt>lua51.dll</tt> created by the LuaJIT build (do not rename
439the DLL). You may link LuaJIT statically on Windows only if you don't
440intend to load Lua/C modules at runtime.
441</li></ul>
442</li>
443<li>
444If you're building a 64 bit application on OSX which links directly or
445indirectly against LuaJIT, you need to link your main executable
446with these flags:
447<pre class="code">
448-pagezero_size 10000 -image_base 100000000
449</pre>
450Also, it's recommended to <tt>rebase</tt> all (self-compiled) shared libraries
451which are loaded at runtime on OSX/x64 (e.g. C extension modules for Lua).
452See: <tt>man rebase</tt>
453</li>
454</ul>
455<p>Additional hints for initializing LuaJIT using the C API functions:</p>
456<ul>
457<li>Here's a
458<a href="http://lua-users.org/wiki/SimpleLuaApiExample"><span class="ext">&raquo;</span>&nbsp;simple example</a>
459for embedding Lua or LuaJIT into your application.</li>
460<li>Make sure you use <tt>luaL_newstate</tt>. Avoid using
461<tt>lua_newstate</tt>, since this uses the (slower) default memory
462allocator from your system (no support for this on x64).</li>
463<li>Make sure you use <tt>luaL_openlibs</tt> and not the old Lua 5.0 style
464of calling <tt>luaopen_base</tt> etc. directly.</li>
465<li>To change or extend the list of standard libraries to load, copy
466<tt>src/lib_init.c</tt> to your project and modify it accordingly.
467Make sure the <tt>jit</tt> library is loaded or the JIT compiler
468will not be activated.</li>
469<li>The <tt>bit.*</tt> module for bitwise operations
470is already built-in. There's no need to statically link
471<a href="http://bitop.luajit.org/"><span class="ext">&raquo;</span>&nbsp;Lua BitOp</a> to your application.</li>
472</ul>
473
474<h2 id="distro">Hints for Distribution Maintainers</h2>
475<p>
476The LuaJIT build system has extra provisions for the needs of most
477POSIX-based distributions. If you're a package maintainer for
478a distribution, <em>please</em> make use of these features and
479avoid patching, subverting, autotoolizing or messing up the build system
480in unspeakable ways.
481</p>
482<p>
483There should be absolutely no need to patch <tt>luaconf.h</tt> or any
484of the Makefiles. And please do not hand-pick files for your packages &mdash;
485simply use whatever <tt>make install</tt> creates. There's a reason
486for all of the files <em>and</em> directories it creates.
487</p>
488<p>
489The build system uses GNU make and auto-detects most settings based on
490the host you're building it on. This should work fine for native builds,
491even when sandboxed. You may need to pass some of the following flags to
492<em>both</em> the <tt>make</tt> and the <tt>make install</tt> command lines
493for a regular distribution build:
494</p>
495<ul>
496<li><tt>PREFIX</tt> overrides the installation path and should usually
497be set to <tt>/usr</tt>. Setting this also changes the module paths and
498the <tt>-rpath</tt> of the shared library.</li>
499<li><tt>DESTDIR</tt> is an absolute path which allows you to install
500to a shadow tree instead of the root tree of the build system.</li>
501<li>Have a look at the top-level <tt>Makefile</tt> and <tt>src/Makefile</tt>
502for additional variables to tweak. The following variables <em>may</em> be
503overridden, but it's <em>not</em> recommended, except for special needs
504like cross-builds:
505<tt>BUILDMODE, CC, HOST_CC, STATIC_CC, DYNAMIC_CC, CFLAGS, HOST_CFLAGS,
506TARGET_CFLAGS, LDFLAGS, HOST_LDFLAGS, TARGET_LDFLAGS, TARGET_SHLDFLAGS,
507TARGET_FLAGS, LIBS, HOST_LIBS, TARGET_LIBS, CROSS, HOST_SYS, TARGET_SYS
508</tt></li>
509</ul>
510<p>
511The build system has a special target for an amalgamated build, i.e.
512<tt>make amalg</tt>. This compiles the LuaJIT core as one huge C file
513and allows GCC to generate faster and shorter code. Alas, this requires
514lots of memory during the build. This may be a problem for some users,
515that's why it's not enabled by default. But it shouldn't be a problem for
516most build farms. It's recommended that binary distributions use this
517target for their LuaJIT builds.
518</p>
519<p>
520The tl;dr version of the above:
521</p>
522<pre class="code">
523make amalg PREFIX=/usr && \
524make install PREFIX=/usr DESTDIR=/tmp/buildroot
525</pre>
526<p>
527Finally, if you encounter any difficulties, please
528<a href="contact.html">contact me</a> first, instead of releasing a broken
529package onto unsuspecting users. Because they'll usually gonna complain
530to me (the upstream) and not you (the package maintainer), anyway.
531</p>
532<br class="flush">
533</div>
534<div id="foot">
535<hr class="hide">
536Copyright &copy; 2005-2011 Mike Pall
537<span class="noprint">
538&middot;
539<a href="contact.html">Contact</a>
540</span>
541</div>
542</body>
543</html>
diff --git a/libraries/luajit-2.0/doc/luajit.html b/libraries/luajit-2.0/doc/luajit.html
new file mode 100644
index 0000000..9725f5c
--- /dev/null
+++ b/libraries/luajit-2.0/doc/luajit.html
@@ -0,0 +1,142 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>LuaJIT</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<meta name="description" content="LuaJIT is a Just-In-Time (JIT) compiler for the Lua language.">
12</head>
13<body>
14<div id="site">
15<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
16</div>
17<div id="head">
18<h1>LuaJIT</h1>
19</div>
20<div id="nav">
21<ul><li>
22<a class="current" href="luajit.html">LuaJIT</a>
23<ul><li>
24<a href="install.html">Installation</a>
25</li><li>
26<a href="running.html">Running</a>
27</li></ul>
28</li><li>
29<a href="extensions.html">Extensions</a>
30<ul><li>
31<a href="ext_ffi.html">FFI Library</a>
32<ul><li>
33<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
34</li><li>
35<a href="ext_ffi_api.html">ffi.* API</a>
36</li><li>
37<a href="ext_ffi_semantics.html">FFI Semantics</a>
38</li></ul>
39</li><li>
40<a href="ext_jit.html">jit.* Library</a>
41</li><li>
42<a href="ext_c_api.html">Lua/C API</a>
43</li></ul>
44</li><li>
45<a href="status.html">Status</a>
46<ul><li>
47<a href="changes.html">Changes</a>
48</li></ul>
49</li><li>
50<a href="faq.html">FAQ</a>
51</li><li>
52<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
53</li><li>
54<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
55</li></ul>
56</div>
57<div id="main">
58<p>
59LuaJIT is a <b>Just-In-Time Compiler</b> for the Lua<sup>*</sup>
60programming language.
61</p>
62<p>
63LuaJIT is Copyright &copy; 2005-2011 Mike Pall.
64LuaJIT is open source software, released under the
65<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT license</a>.
66</p>
67<p class="indent" style="color: #606060;">
68* Lua is a powerful, dynamic and light-weight programming language
69designed for extending applications. Lua is also frequently used as a
70general-purpose, stand-alone language. More information about
71Lua can be found at: <a href="http://www.lua.org/"><span class="ext">&raquo;</span>&nbsp;http://www.lua.org/</a>
72</p>
73<h2>Compatibility</h2>
74<p>
75LuaJIT implements the full set of language features defined by Lua 5.1.
76The virtual machine (VM) is <b>API- and ABI-compatible</b> to the
77standard Lua interpreter and can be deployed as a drop-in replacement.
78</p>
79<p>
80LuaJIT offers more performance, at the expense of portability. It
81currently runs on all popular operating systems based on
82<b>x86</b> or <b>x64</b> CPUs (Linux, Windows, OSX etc.) or embedded
83systems based on <b>ARM</b> (Android, iOS) or <b>PPC</b> CPUs.
84Other platforms will be supported in the future, based on user demand
85and sponsoring.
86</p>
87
88<h2>Overview</h2>
89<p>
90LuaJIT has been successfully used as a <b>scripting middleware</b> in
91games, 3D modellers, numerical simulations, trading platforms and many
92other specialty applications. It combines high flexibility with high
93performance and an unmatched <b>low memory footprint</b>: less than
94<b>125K</b> for the VM plus less than <b>85K</b> for the JIT compiler (on x86).
95</p>
96<p>
97LuaJIT has been in continuous development since 2005. It's widely
98considered to be <b>one of the fastest dynamic language
99implementations</b>. It has outperformed other dynamic languages on many
100cross-language benchmarks since its first release &mdash; often by a
101substantial margin. In 2009 other dynamic language VMs started to catch up
102with the performance of LuaJIT 1.x. Well, I couldn't let that slide. ;-)
103</p>
104<p>
1052009 also marks the first release of the long-awaited <b>LuaJIT 2.0</b>.
106The whole VM has been rewritten from the ground up and relentlessly
107optimized for performance. It combines a high-speed interpreter,
108written in assembler, with a state-of-the-art JIT compiler.
109</p>
110<p>
111An innovative <b>trace compiler</b> is integrated with advanced,
112SSA-based optimizations and a highly tuned code generation backend. This
113allows a substantial reduction of the overhead associated with dynamic
114language features.
115</p>
116<p>
117It's destined to break into the <a href="http://luajit.org/performance.html"><span class="ext">&raquo;</span>&nbsp;performance</a>
118range traditionally reserved for offline, static language compilers.
119</p>
120
121<h2>More ...</h2>
122<p>
123Click on the LuaJIT sub-topics in the navigation bar to learn more
124about LuaJIT.
125</p>
126<p><p>
127Click on the Logo in the upper left corner to visit
128the LuaJIT project page on the web. All other links to online
129resources are marked with a '<span class="ext">&raquo;</span>'.
130</p>
131<br class="flush">
132</div>
133<div id="foot">
134<hr class="hide">
135Copyright &copy; 2005-2011 Mike Pall
136<span class="noprint">
137&middot;
138<a href="contact.html">Contact</a>
139</span>
140</div>
141</body>
142</html>
diff --git a/libraries/luajit-2.0/doc/running.html b/libraries/luajit-2.0/doc/running.html
new file mode 100644
index 0000000..e2afdee
--- /dev/null
+++ b/libraries/luajit-2.0/doc/running.html
@@ -0,0 +1,313 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Running LuaJIT</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12table.opt {
13 line-height: 1.2;
14}
15tr.opthead td {
16 font-weight: bold;
17}
18td.flag_name {
19 width: 4em;
20}
21td.flag_level {
22 width: 2em;
23 text-align: center;
24}
25td.param_name {
26 width: 6em;
27}
28td.param_default {
29 width: 4em;
30 text-align: right;
31}
32</style>
33</head>
34<body>
35<div id="site">
36<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
37</div>
38<div id="head">
39<h1>Running LuaJIT</h1>
40</div>
41<div id="nav">
42<ul><li>
43<a href="luajit.html">LuaJIT</a>
44<ul><li>
45<a href="install.html">Installation</a>
46</li><li>
47<a class="current" href="running.html">Running</a>
48</li></ul>
49</li><li>
50<a href="extensions.html">Extensions</a>
51<ul><li>
52<a href="ext_ffi.html">FFI Library</a>
53<ul><li>
54<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
55</li><li>
56<a href="ext_ffi_api.html">ffi.* API</a>
57</li><li>
58<a href="ext_ffi_semantics.html">FFI Semantics</a>
59</li></ul>
60</li><li>
61<a href="ext_jit.html">jit.* Library</a>
62</li><li>
63<a href="ext_c_api.html">Lua/C API</a>
64</li></ul>
65</li><li>
66<a href="status.html">Status</a>
67<ul><li>
68<a href="changes.html">Changes</a>
69</li></ul>
70</li><li>
71<a href="faq.html">FAQ</a>
72</li><li>
73<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
74</li><li>
75<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
76</li></ul>
77</div>
78<div id="main">
79<p>
80LuaJIT has only a single stand-alone executable, called <tt>luajit</tt> on
81POSIX systems or <tt>luajit.exe</tt> on Windows. It can be used to run simple
82Lua statements or whole Lua applications from the command line. It has an
83interactive mode, too.
84</p>
85<p class="indent" style="color: #c00000;">
86Note: the beta test releases only install under the versioned name on
87POSIX systems (to avoid overwriting a previous version). You either need
88to type <tt>luajit-2.0.0-beta9</tt> to start it or create a symlink
89with a command like this:
90</p>
91<pre class="code" style="color: #c00000;">
92sudo ln -sf luajit-2.0.0-beta9&nbsp;/usr/local/bin/luajit
93</pre>
94<p>
95Unlike previous versions <b>optimization is turned on by default</b> in
96LuaJIT 2.0!<br>It's no longer necessary to use <tt>luajit&nbsp;-O</tt>.
97</p>
98
99<h2 id="options">Command Line Options</h2>
100<p>
101The <tt>luajit</tt> stand-alone executable is just a slightly modified
102version of the regular <tt>lua</tt> stand-alone executable.
103It supports the same basic options, too. <tt>luajit&nbsp;-h</tt>
104prints a short list of the available options. Please have a look at the
105<a href="http://www.lua.org/manual/5.1/manual.html#6"><span class="ext">&raquo;</span>&nbsp;Lua manual</a>
106for details.
107</p>
108<p>
109LuaJIT has some additional options:
110</p>
111
112<h3 id="opt_b"><tt>-b[options] input output</tt></h3>
113<p>
114This option saves or lists bytecode. The following additional options
115are accepted:
116</p>
117<ul>
118<li><tt>-l</tt> &mdash; Only list bytecode.</li>
119<li><tt>-s</tt> &mdash; Strip debug info (this is the default).</li>
120<li><tt>-g</tt> &mdash; Keep debug info.</li>
121<li><tt>-n name</tt> &mdash; Set module name (default: auto-detect from input name)</li>
122<li><tt>-t type</tt> &mdash; Set output file type (default: auto-detect from output name).</li>
123<li><tt>-a arch</tt> &mdash; Override architecture for object files (default: native).</li>
124<li><tt>-o os</tt> &mdash; Override OS for object files (default: native).</li>
125<li><tt>-e chunk</tt> &mdash; Use chunk string as input.</li>
126<li><tt>-</tt> (a single minus sign) &mdash; Use stdin as input and/or stdout as output.</li>
127</ul>
128<p>
129The output file type is auto-detected from the extension of the output
130file name:
131</p>
132<ul>
133<li><tt>c</tt> &mdash; C source file, exported bytecode data.</li>
134<li><tt>h</tt> &mdash; C header file, static bytecode data.</li>
135<li><tt>obj</tt> or <tt>o</tt> &mdash; Object file, exported bytecode data
136(OS- and architecture-specific).</li>
137<li><tt>raw</tt> or any other extension &mdash; Raw bytecode file (portable).
138</ul>
139<p>
140Notes:
141</p>
142<ul>
143<li>See also <a href="extensions.html#string_dump">string.dump()</a>
144for information on bytecode portability and compatibility.</li>
145<li>A file in raw bytecode format is auto-detected and can be loaded like
146any Lua source file. E.g. directly from the command line or with
147<tt>loadfile()</tt>, <tt>dofile()</tt> etc.</li>
148<li>To statically embed the bytecode of a module in your application,
149generate an object file and just link it with your application.</li>
150<li>On most ELF-based systems (e.g. Linux) you need to explicitly export the
151global symbols when linking your application, e.g. with: <tt>-Wl,-E</tt></li>
152<li><tt>require()</tt> tries to load embedded bytecode data from exported
153symbols (in <tt>*.exe</tt> or <tt>lua51.dll</tt> on Windows) and from
154shared libraries in <tt>package.cpath</tt>.</li>
155</ul>
156<p>
157Typical usage examples:
158</p>
159<pre class="code">
160luajit -b test.lua test.out # Save bytecode to test.out
161luajit -bg test.lua test.out # Keep debug info
162luajit -be "print('hello world')" test.out # Save cmdline script
163
164luajit -bl test.lua # List to stdout
165luajit -bl test.lua test.txt # List to test.txt
166luajit -ble "print('hello world')" # List cmdline script
167
168luajit -b test.lua test.obj # Generate object file
169# Link test.obj with your application and load it with require("test")
170</pre>
171
172<h3 id="opt_j"><tt>-j cmd[=arg[,arg...]]</tt></h3>
173<p>
174This option performs a LuaJIT control command or activates one of the
175loadable extension modules. The command is first looked up in the
176<tt>jit.*</tt> library. If no matching function is found, a module
177named <tt>jit.&lt;cmd&gt;</tt> is loaded and the <tt>start()</tt>
178function of the module is called with the specified arguments (if
179any). The space between <tt>-j</tt> and <tt>cmd</tt> is optional.
180</p>
181<p>
182Here are the available LuaJIT control commands:
183</p>
184<ul>
185<li id="j_on"><tt>-jon</tt> &mdash; Turns the JIT compiler on (default).</li>
186<li id="j_off"><tt>-joff</tt> &mdash; Turns the JIT compiler off (only use the interpreter).</li>
187<li id="j_flush"><tt>-jflush</tt> &mdash; Flushes the whole cache of compiled code.</li>
188<li id="j_v"><tt>-jv</tt> &mdash; Shows verbose information about the progress of the JIT compiler.</li>
189<li id="j_dump"><tt>-jdump</tt> &mdash; Dumps the code and structures used in various compiler stages.</li>
190</ul>
191<p>
192The <tt>-jv</tt> and <tt>-jdump</tt> commands are extension modules
193written in Lua. They are mainly used for debugging the JIT compiler
194itself. For a description of their options and output format, please
195read the comment block at the start of their source.
196They can be found in the <tt>lib</tt> directory of the source
197distribution or installed under the <tt>jit</tt> directory. By default
198this is <tt>/usr/local/share/luajit-2.0.0-beta9/jit</tt> on POSIX
199systems.
200</p>
201
202<h3 id="opt_O"><tt>-O[level]</tt><br>
203<tt>-O[+]flag</tt>&nbsp;&nbsp;&nbsp;<tt>-O-flag</tt><br>
204<tt>-Oparam=value</tt></h3>
205<p>
206This options allows fine-tuned control of the optimizations used by
207the JIT compiler. This is mainly intended for debugging LuaJIT itself.
208Please note that the JIT compiler is extremely fast (we are talking
209about the microsecond to millisecond range). Disabling optimizations
210doesn't have any visible impact on its overhead, but usually generates
211code that runs slower.
212</p>
213<p>
214The first form sets an optimization level &mdash; this enables a
215specific mix of optimization flags. <tt>-O0</tt> turns off all
216optimizations and higher numbers enable more optimizations. Omitting
217the level (i.e. just <tt>-O</tt>) sets the default optimization level,
218which is <tt>-O3</tt> in the current version.
219</p>
220<p>
221The second form adds or removes individual optimization flags.
222The third form sets a parameter for the VM or the JIT compiler
223to a specific value.
224</p>
225<p>
226You can either use this option multiple times (like <tt>-Ocse
227-O-dce -Ohotloop=10</tt>) or separate several settings with a comma
228(like <tt>-O+cse,-dce,hotloop=10</tt>). The settings are applied from
229left to right and later settings override earlier ones. You can freely
230mix the three forms, but note that setting an optimization level
231overrides all earlier flags.
232</p>
233<p>
234Here are the available flags and at what optimization levels they
235are enabled:
236</p>
237<table class="opt">
238<tr class="opthead">
239<td class="flag_name">Flag</td>
240<td class="flag_level">-O1</td>
241<td class="flag_level">-O2</td>
242<td class="flag_level">-O3</td>
243<td class="flag_desc">&nbsp;</td>
244</tr>
245<tr class="odd separate">
246<td class="flag_name">fold</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Constant Folding, Simplifications and Reassociation</td></tr>
247<tr class="even">
248<td class="flag_name">cse</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Common-Subexpression Elimination</td></tr>
249<tr class="odd">
250<td class="flag_name">dce</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Dead-Code Elimination</td></tr>
251<tr class="even">
252<td class="flag_name">narrow</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Narrowing of numbers to integers</td></tr>
253<tr class="odd">
254<td class="flag_name">loop</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_level">&bull;</td><td class="flag_desc">Loop Optimizations (code hoisting)</td></tr>
255<tr class="even">
256<td class="flag_name">fwd</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Load Forwarding (L2L) and Store Forwarding (S2L)</td></tr>
257<tr class="odd">
258<td class="flag_name">dse</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Dead-Store Elimination</td></tr>
259<tr class="even">
260<td class="flag_name">abc</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Array Bounds Check Elimination</td></tr>
261<tr class="odd">
262<td class="flag_name">fuse</td><td class="flag_level">&nbsp;</td><td class="flag_level">&nbsp;</td><td class="flag_level">&bull;</td><td class="flag_desc">Fusion of operands into instructions</td></tr>
263</table>
264<p>
265Here are the parameters and their default settings:
266</p>
267<table class="opt">
268<tr class="opthead">
269<td class="param_name">Parameter</td>
270<td class="param_default">Default</td>
271<td class="param_desc">&nbsp;</td>
272</tr>
273<tr class="odd separate">
274<td class="param_name">maxtrace</td><td class="param_default">1000</td><td class="param_desc">Max. number of traces in the cache</td></tr>
275<tr class="even">
276<td class="param_name">maxrecord</td><td class="param_default">4000</td><td class="param_desc">Max. number of recorded IR instructions</td></tr>
277<tr class="odd">
278<td class="param_name">maxirconst</td><td class="param_default">500</td><td class="param_desc">Max. number of IR constants of a trace</td></tr>
279<tr class="even">
280<td class="param_name">maxside</td><td class="param_default">100</td><td class="param_desc">Max. number of side traces of a root trace</td></tr>
281<tr class="odd">
282<td class="param_name">maxsnap</td><td class="param_default">500</td><td class="param_desc">Max. number of snapshots for a trace</td></tr>
283<tr class="even separate">
284<td class="param_name">hotloop</td><td class="param_default">56</td><td class="param_desc">Number of iterations to detect a hot loop or hot call</td></tr>
285<tr class="odd">
286<td class="param_name">hotexit</td><td class="param_default">10</td><td class="param_desc">Number of taken exits to start a side trace</td></tr>
287<tr class="even">
288<td class="param_name">tryside</td><td class="param_default">4</td><td class="param_desc">Number of attempts to compile a side trace</td></tr>
289<tr class="odd separate">
290<td class="param_name">instunroll</td><td class="param_default">4</td><td class="param_desc">Max. unroll factor for instable loops</td></tr>
291<tr class="even">
292<td class="param_name">loopunroll</td><td class="param_default">15</td><td class="param_desc">Max. unroll factor for loop ops in side traces</td></tr>
293<tr class="odd">
294<td class="param_name">callunroll</td><td class="param_default">3</td><td class="param_desc">Max. unroll factor for pseudo-recursive calls</td></tr>
295<tr class="even">
296<td class="param_name">recunroll</td><td class="param_default">2</td><td class="param_desc">Min. unroll factor for true recursion</td></tr>
297<tr class="odd separate">
298<td class="param_name">sizemcode</td><td class="param_default">32</td><td class="param_desc">Size of each machine code area in KBytes (Windows: 64K)</td></tr>
299<tr class="even">
300<td class="param_name">maxmcode</td><td class="param_default">512</td><td class="param_desc">Max. total size of all machine code areas in KBytes</td></tr>
301</table>
302<br class="flush">
303</div>
304<div id="foot">
305<hr class="hide">
306Copyright &copy; 2005-2011 Mike Pall
307<span class="noprint">
308&middot;
309<a href="contact.html">Contact</a>
310</span>
311</div>
312</body>
313</html>
diff --git a/libraries/luajit-2.0/doc/status.html b/libraries/luajit-2.0/doc/status.html
new file mode 100644
index 0000000..d9cffe0
--- /dev/null
+++ b/libraries/luajit-2.0/doc/status.html
@@ -0,0 +1,240 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<title>Status &amp; Roadmap</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="Author" content="Mike Pall">
7<meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall">
8<meta name="Language" content="en">
9<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11<style type="text/css">
12ul li { padding-bottom: 0.3em; }
13</style>
14</head>
15<body>
16<div id="site">
17<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
18</div>
19<div id="head">
20<h1>Status &amp; Roadmap</h1>
21</div>
22<div id="nav">
23<ul><li>
24<a href="luajit.html">LuaJIT</a>
25<ul><li>
26<a href="install.html">Installation</a>
27</li><li>
28<a href="running.html">Running</a>
29</li></ul>
30</li><li>
31<a href="extensions.html">Extensions</a>
32<ul><li>
33<a href="ext_ffi.html">FFI Library</a>
34<ul><li>
35<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
36</li><li>
37<a href="ext_ffi_api.html">ffi.* API</a>
38</li><li>
39<a href="ext_ffi_semantics.html">FFI Semantics</a>
40</li></ul>
41</li><li>
42<a href="ext_jit.html">jit.* Library</a>
43</li><li>
44<a href="ext_c_api.html">Lua/C API</a>
45</li></ul>
46</li><li>
47<a class="current" href="status.html">Status</a>
48<ul><li>
49<a href="changes.html">Changes</a>
50</li></ul>
51</li><li>
52<a href="faq.html">FAQ</a>
53</li><li>
54<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
55</li><li>
56<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
57</li></ul>
58</div>
59<div id="main">
60<p>
61The <span style="color: #0000c0;">LuaJIT 1.x</span> series represents
62the current <span style="color: #0000c0;">stable branch</span>.
63Only a single bug has been discovered in the last two years. So, if
64you need a rock-solid VM, you are encouraged to fetch the latest
65release of LuaJIT 1.x from the <a href="http://luajit.org/download.html"><span class="ext">&raquo;</span>&nbsp;Download</a>
66page.
67</p>
68<p>
69<span style="color: #c00000;">LuaJIT 2.0</span> is the currently active
70<span style="color: #c00000;">development branch</span>.
71It has <b>Beta Test</b> status and is still undergoing
72substantial changes.
73It has <a href="http://luajit.org/performance.html"><span class="ext">&raquo;</span>&nbsp;much better performance</a> than LuaJIT 1.x.
74It's maturing quickly, so you should definitely
75start to evaluate it for new projects right now.
76</p>
77
78<h2>Current Status</h2>
79<p>
80This is a list of the things you should know about the LuaJIT 2.0 beta test:
81</p>
82<ul>
83<li>
84Obviously there will be some <b>bugs</b> in a VM which has been
85rewritten from the ground up. Please report your findings together with
86the circumstances needed to reproduce the bug. If possible, reduce the
87problem down to a simple test case.<br>
88There is no formal bug tracker at the moment. The best place for
89discussion is the
90<a href="http://www.lua.org/lua-l.html"><span class="ext">&raquo;</span>&nbsp;Lua mailing list</a>. Of course
91you may also send your bug reports <a href="contact.html">directly to me</a>,
92especially when they contain lengthy debug output or if you require
93confidentiality.
94</li>
95<li>
96The x86 JIT compiler only generates code for CPUs with support for
97<b>SSE2</b> instructions. I.e. you need at least a P4, Core 2/i3/i5/i7,
98Atom or K8/K10 to get the full benefit.<br>
99If you run LuaJIT on older CPUs without SSE2 support, the JIT compiler
100is disabled and the VM falls back to the LuaJIT interpreter. This is faster
101than the Lua interpreter, but not nearly as fast as the JIT compiler of course.
102Run the command line executable without arguments to show the current status
103(<tt>JIT: ON</tt> or <tt>JIT: OFF</tt>).
104</li>
105<li>
106The VM is complete in the sense that it <b>should</b> run all Lua code
107just fine. It's considered a serious bug if the VM crashes or produces
108unexpected results &mdash; please report this. There are only very few
109known incompatibilities with standard Lua:
110<ul>
111<li>
112The Lua <b>debug API</b> is missing a couple of features (return
113hooks for non-Lua functions) and shows slightly different behavior
114(no per-coroutine hooks, no tail call counting).
115</li>
116<li>
117Some of the <b>configuration options</b> of Lua&nbsp;5.1 are not supported:
118<ul>
119<li>The <b>number type</b> cannot be changed (it's always a <tt>double</tt>).</li>
120<li>The stand-alone executable cannot be linked with <b>readline</b>
121to enable line editing. It's planned to add support for loading it
122on-demand.</li>
123</ul>
124</li>
125<li>
126Most other issues you're likely to find (e.g. with the existing test
127suites) are differences in the <b>implementation-defined</b> behavior.
128These either have a good reason (like early tail call resolving which
129may cause differences in error reporting), are arbitrary design choices
130or are due to quirks in the VM. The latter cases may get fixed if a
131demonstrable need is shown.
132</li>
133</ul>
134</li>
135<li>
136The <b>JIT compiler</b> falls back to the
137interpreter in some cases. All of this works transparently, so unless
138you use <tt>-jv</tt>, you'll probably never notice (the interpreter is
139<a href="http://luajit.org/performance.html"><span class="ext">&raquo;</span>&nbsp;quite fast</a>, too). Here are the known issues:
140<ul>
141<li>
142Most known issues cause a <b>NYI</b> (not yet implemented) trace abort
143message. E.g. for calls to some internal library
144functions. Reporting these is only mildly useful, except if you have good
145example code that shows the problem. Obviously, reports accompanied with
146a patch to fix the issue are more than welcome. But please check back
147with me, before writing major improvements, to avoid duplication of
148effort.
149</li>
150<li>
151Some checks are missing in the JIT-compiled code for obscure situations
152with <b>open upvalues aliasing</b> one of the SSA slots later on (or
153vice versa). Bonus points, if you can find a real world test case for
154this.
155</li>
156<li>
157Currently some <b>out-of-memory</b> errors from <b>on-trace code</b> are not
158handled correctly. The error may fall through an on-trace
159<tt>pcall</tt> (x86) or it may be passed on to the function set with
160<tt>lua_atpanic</tt> (x64).
161</li>
162</ul>
163</li>
164</ul>
165
166<h2>Roadmap</h2>
167<p>
168Please refer to the
169<a href="http://lua-users.org/lists/lua-l/2011-01/msg01238.html"><span class="ext">&raquo;</span>&nbsp;LuaJIT
170Roadmap 2011</a> for the latest release plan. Here's the general
171project plan for LuaJIT 2.0:
172</p>
173<ul>
174<li>
175The main goal right now is to stabilize LuaJIT 2.0 and get it out of
176beta test. <b>Correctness</b> has priority over completeness. This
177implies the first stable release will certainly NOT compile every
178library function call and will fall back to the interpreter from time
179to time. This is perfectly ok, since it still executes all Lua code,
180just not at the highest possible speed.
181</li>
182<li>
183The next step is to get it to compile more library functions and handle
184more cases where the compiler currently bails out. This doesn't mean it
185will compile every corner case. It's much more important that it
186performs well in a majority of use cases. Every compiler has to make
187these trade-offs &mdash; <b>completeness</b> just cannot be the
188overriding goal for a low-footprint, low-overhead JIT compiler.
189</li>
190<li>
191More <b>optimizations</b> will be added in parallel to the last step on
192an as-needed basis. Sinking of stores
193to aggregates and sinking of allocations are high on the list.
194More complex optimizations with less pay-off, such as value-range-propagation
195(VRP) will have to wait.
196</li>
197<li>
198LuaJIT 2.0 has been designed with <b>portability</b> in mind.
199Nonetheless, it compiles to native code and needs to be adapted to each
200architecture. The two major work items are porting the the fast interpreter,
201which is written in assembler, and porting the compiler backend.
202Most other portability issues like endianess or 32 vs. 64&nbsp;bit CPUs
203have already been taken care of.<br>
204Several ports are already available, thanks to the
205<a href="http://luajit.org/sponsors.html"><span class="ext">&raquo;</span>&nbsp;LuaJIT sponsorship program</a>.
206More ports will follow in the future &mdash; companies which are
207interested in sponsoring a port to a particular architecture, please
208use the given contact address.
209</li>
210<li>
211<b>Documentation</b> about the <b>internals</b> of LuaJIT is still sorely
212missing. Although the source code is included and is IMHO well
213commented, many basic design decisions are in need of an explanation.
214The rather un-traditional compiler architecture and the many highly
215optimized data structures are a barrier for outside participation in
216the development. Alas, as I've repeatedly stated, I'm better at
217writing code than papers and I'm not in need of any academic merits.
218Someday I will find the time for it. :-)
219</li>
220<li>
221Producing good code for unbiased branches is a key problem for trace
222compilers. This is the main cause for "trace explosion".
223<b>Hyperblock scheduling</b> promises to solve this nicely at the
224price of a major redesign of the compiler. This would also pave the
225way for emitting predicated instructions, which is a prerequisite
226for efficient <b>vectorization</b>.
227</li>
228</ul>
229<br class="flush">
230</div>
231<div id="foot">
232<hr class="hide">
233Copyright &copy; 2005-2011 Mike Pall
234<span class="noprint">
235&middot;
236<a href="contact.html">Contact</a>
237</span>
238</div>
239</body>
240</html>
diff --git a/libraries/luajit-2.0/dynasm/dasm_arm.h b/libraries/luajit-2.0/dynasm/dasm_arm.h
new file mode 100644
index 0000000..43d2963
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_arm.h
@@ -0,0 +1,448 @@
1/*
2** DynASM ARM encoding engine.
3** Copyright (C) 2005-2011 Mike Pall. All rights reserved.
4** Released under the MIT license. See dynasm.lua for full copyright notice.
5*/
6
7#include <stddef.h>
8#include <stdarg.h>
9#include <string.h>
10#include <stdlib.h>
11
12#define DASM_ARCH "arm"
13
14#ifndef DASM_EXTERN
15#define DASM_EXTERN(a,b,c,d) 0
16#endif
17
18/* Action definitions. */
19enum {
20 DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
21 /* The following actions need a buffer position. */
22 DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
23 /* The following actions also have an argument. */
24 DASM_REL_PC, DASM_LABEL_PC,
25 DASM_IMM, DASM_IMM12, DASM_IMM16, DASM_IMML8, DASM_IMML12,
26 DASM__MAX
27};
28
29/* Maximum number of section buffer positions for a single dasm_put() call. */
30#define DASM_MAXSECPOS 25
31
32/* DynASM encoder status codes. Action list offset or number are or'ed in. */
33#define DASM_S_OK 0x00000000
34#define DASM_S_NOMEM 0x01000000
35#define DASM_S_PHASE 0x02000000
36#define DASM_S_MATCH_SEC 0x03000000
37#define DASM_S_RANGE_I 0x11000000
38#define DASM_S_RANGE_SEC 0x12000000
39#define DASM_S_RANGE_LG 0x13000000
40#define DASM_S_RANGE_PC 0x14000000
41#define DASM_S_RANGE_REL 0x15000000
42#define DASM_S_UNDEF_LG 0x21000000
43#define DASM_S_UNDEF_PC 0x22000000
44
45/* Macros to convert positions (8 bit section + 24 bit index). */
46#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
47#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
48#define DASM_SEC2POS(sec) ((sec)<<24)
49#define DASM_POS2SEC(pos) ((pos)>>24)
50#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
51
52/* Action list type. */
53typedef const unsigned int *dasm_ActList;
54
55/* Per-section structure. */
56typedef struct dasm_Section {
57 int *rbuf; /* Biased buffer pointer (negative section bias). */
58 int *buf; /* True buffer pointer. */
59 size_t bsize; /* Buffer size in bytes. */
60 int pos; /* Biased buffer position. */
61 int epos; /* End of biased buffer position - max single put. */
62 int ofs; /* Byte offset into section. */
63} dasm_Section;
64
65/* Core structure holding the DynASM encoding state. */
66struct dasm_State {
67 size_t psize; /* Allocated size of this structure. */
68 dasm_ActList actionlist; /* Current actionlist pointer. */
69 int *lglabels; /* Local/global chain/pos ptrs. */
70 size_t lgsize;
71 int *pclabels; /* PC label chains/pos ptrs. */
72 size_t pcsize;
73 void **globals; /* Array of globals (bias -10). */
74 dasm_Section *section; /* Pointer to active section. */
75 size_t codesize; /* Total size of all code sections. */
76 int maxsection; /* 0 <= sectionidx < maxsection. */
77 int status; /* Status code. */
78 dasm_Section sections[1]; /* All sections. Alloc-extended. */
79};
80
81/* The size of the core structure depends on the max. number of sections. */
82#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
83
84
85/* Initialize DynASM state. */
86void dasm_init(Dst_DECL, int maxsection)
87{
88 dasm_State *D;
89 size_t psz = 0;
90 int i;
91 Dst_REF = NULL;
92 DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
93 D = Dst_REF;
94 D->psize = psz;
95 D->lglabels = NULL;
96 D->lgsize = 0;
97 D->pclabels = NULL;
98 D->pcsize = 0;
99 D->globals = NULL;
100 D->maxsection = maxsection;
101 for (i = 0; i < maxsection; i++) {
102 D->sections[i].buf = NULL; /* Need this for pass3. */
103 D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
104 D->sections[i].bsize = 0;
105 D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
106 }
107}
108
109/* Free DynASM state. */
110void dasm_free(Dst_DECL)
111{
112 dasm_State *D = Dst_REF;
113 int i;
114 for (i = 0; i < D->maxsection; i++)
115 if (D->sections[i].buf)
116 DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
117 if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
118 if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
119 DASM_M_FREE(Dst, D, D->psize);
120}
121
122/* Setup global label array. Must be called before dasm_setup(). */
123void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
124{
125 dasm_State *D = Dst_REF;
126 D->globals = gl - 10; /* Negative bias to compensate for locals. */
127 DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
128}
129
130/* Grow PC label array. Can be called after dasm_setup(), too. */
131void dasm_growpc(Dst_DECL, unsigned int maxpc)
132{
133 dasm_State *D = Dst_REF;
134 size_t osz = D->pcsize;
135 DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
136 memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
137}
138
139/* Setup encoder. */
140void dasm_setup(Dst_DECL, const void *actionlist)
141{
142 dasm_State *D = Dst_REF;
143 int i;
144 D->actionlist = (dasm_ActList)actionlist;
145 D->status = DASM_S_OK;
146 D->section = &D->sections[0];
147 memset((void *)D->lglabels, 0, D->lgsize);
148 if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
149 for (i = 0; i < D->maxsection; i++) {
150 D->sections[i].pos = DASM_SEC2POS(i);
151 D->sections[i].ofs = 0;
152 }
153}
154
155
156#ifdef DASM_CHECKS
157#define CK(x, st) \
158 do { if (!(x)) { \
159 D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
160#define CKPL(kind, st) \
161 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
162 D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
163#else
164#define CK(x, st) ((void)0)
165#define CKPL(kind, st) ((void)0)
166#endif
167
168static int dasm_imm12(unsigned int n)
169{
170 int i;
171 for (i = 0; i < 16; i++, n = (n << 2) | (n >> 30))
172 if (n <= 255) return (int)(n + (i << 8));
173 return -1;
174}
175
176/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
177void dasm_put(Dst_DECL, int start, ...)
178{
179 va_list ap;
180 dasm_State *D = Dst_REF;
181 dasm_ActList p = D->actionlist + start;
182 dasm_Section *sec = D->section;
183 int pos = sec->pos, ofs = sec->ofs;
184 int *b;
185
186 if (pos >= sec->epos) {
187 DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
188 sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
189 sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
190 sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
191 }
192
193 b = sec->rbuf;
194 b[pos++] = start;
195
196 va_start(ap, start);
197 while (1) {
198 unsigned int ins = *p++;
199 unsigned int action = (ins >> 16);
200 if (action >= DASM__MAX) {
201 ofs += 4;
202 } else {
203 int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
204 switch (action) {
205 case DASM_STOP: goto stop;
206 case DASM_SECTION:
207 n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
208 D->section = &D->sections[n]; goto stop;
209 case DASM_ESC: p++; ofs += 4; break;
210 case DASM_REL_EXT: break;
211 case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
212 case DASM_REL_LG:
213 n = (ins & 2047) - 10; pl = D->lglabels + n;
214 if (n >= 0) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
215 pl += 10; n = *pl;
216 if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
217 goto linkrel;
218 case DASM_REL_PC:
219 pl = D->pclabels + n; CKPL(pc, PC);
220 putrel:
221 n = *pl;
222 if (n < 0) { /* Label exists. Get label pos and store it. */
223 b[pos] = -n;
224 } else {
225 linkrel:
226 b[pos] = n; /* Else link to rel chain, anchored at label. */
227 *pl = pos;
228 }
229 pos++;
230 break;
231 case DASM_LABEL_LG:
232 pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
233 case DASM_LABEL_PC:
234 pl = D->pclabels + n; CKPL(pc, PC);
235 putlabel:
236 n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
237 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
238 }
239 *pl = -pos; /* Label exists now. */
240 b[pos++] = ofs; /* Store pass1 offset estimate. */
241 break;
242 case DASM_IMM:
243 case DASM_IMM16:
244#ifdef DASM_CHECKS
245 CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
246 if ((ins & 0x8000))
247 CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
248 else
249 CK((n>>((ins>>5)&31)) == 0, RANGE_I);
250#endif
251 b[pos++] = n;
252 break;
253 case DASM_IMML8:
254 case DASM_IMML12:
255 CK(n >= 0 ? ((n>>((ins>>5)&31)) == 0) :
256 (((-n)>>((ins>>5)&31)) == 0), RANGE_I);
257 b[pos++] = n;
258 break;
259 case DASM_IMM12:
260 CK(dasm_imm12((unsigned int)n) != -1, RANGE_I);
261 b[pos++] = n;
262 break;
263 }
264 }
265 }
266stop:
267 va_end(ap);
268 sec->pos = pos;
269 sec->ofs = ofs;
270}
271#undef CK
272
273/* Pass 2: Link sections, shrink aligns, fix label offsets. */
274int dasm_link(Dst_DECL, size_t *szp)
275{
276 dasm_State *D = Dst_REF;
277 int secnum;
278 int ofs = 0;
279
280#ifdef DASM_CHECKS
281 *szp = 0;
282 if (D->status != DASM_S_OK) return D->status;
283 {
284 int pc;
285 for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
286 if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
287 }
288#endif
289
290 { /* Handle globals not defined in this translation unit. */
291 int idx;
292 for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
293 int n = D->lglabels[idx];
294 /* Undefined label: Collapse rel chain and replace with marker (< 0). */
295 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
296 }
297 }
298
299 /* Combine all code sections. No support for data sections (yet). */
300 for (secnum = 0; secnum < D->maxsection; secnum++) {
301 dasm_Section *sec = D->sections + secnum;
302 int *b = sec->rbuf;
303 int pos = DASM_SEC2POS(secnum);
304 int lastpos = sec->pos;
305
306 while (pos != lastpos) {
307 dasm_ActList p = D->actionlist + b[pos++];
308 while (1) {
309 unsigned int ins = *p++;
310 unsigned int action = (ins >> 16);
311 switch (action) {
312 case DASM_STOP: case DASM_SECTION: goto stop;
313 case DASM_ESC: p++; break;
314 case DASM_REL_EXT: break;
315 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
316 case DASM_REL_LG: case DASM_REL_PC: pos++; break;
317 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
318 case DASM_IMM: case DASM_IMM12: case DASM_IMM16:
319 case DASM_IMML8: case DASM_IMML12: pos++; break;
320 }
321 }
322 stop: (void)0;
323 }
324 ofs += sec->ofs; /* Next section starts right after current section. */
325 }
326
327 D->codesize = ofs; /* Total size of all code sections */
328 *szp = ofs;
329 return DASM_S_OK;
330}
331
332#ifdef DASM_CHECKS
333#define CK(x, st) \
334 do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
335#else
336#define CK(x, st) ((void)0)
337#endif
338
339/* Pass 3: Encode sections. */
340int dasm_encode(Dst_DECL, void *buffer)
341{
342 dasm_State *D = Dst_REF;
343 char *base = (char *)buffer;
344 unsigned int *cp = (unsigned int *)buffer;
345 int secnum;
346
347 /* Encode all code sections. No support for data sections (yet). */
348 for (secnum = 0; secnum < D->maxsection; secnum++) {
349 dasm_Section *sec = D->sections + secnum;
350 int *b = sec->buf;
351 int *endb = sec->rbuf + sec->pos;
352
353 while (b != endb) {
354 dasm_ActList p = D->actionlist + *b++;
355 while (1) {
356 unsigned int ins = *p++;
357 unsigned int action = (ins >> 16);
358 int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
359 switch (action) {
360 case DASM_STOP: case DASM_SECTION: goto stop;
361 case DASM_ESC: *cp++ = *p++; break;
362 case DASM_REL_EXT:
363 n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));
364 goto patchrel;
365 case DASM_ALIGN:
366 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
367 break;
368 case DASM_REL_LG:
369 CK(n >= 0, UNDEF_LG);
370 case DASM_REL_PC:
371 CK(n >= 0, UNDEF_PC);
372 n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) - 4;
373 patchrel:
374 if ((ins & 0x800) == 0) {
375 CK((n & 3) == 0 && ((n+0x02000000) >> 26) == 0, RANGE_REL);
376 cp[-1] |= ((n >> 2) & 0x00ffffff);
377 } else if ((ins & 0x1000)) {
378 CK((n & 3) == 0 && -256 <= n && n <= 256, RANGE_REL);
379 goto patchimml8;
380 } else {
381 CK((n & 3) == 0 && -4096 <= n && n <= 4096, RANGE_REL);
382 goto patchimml12;
383 }
384 break;
385 case DASM_LABEL_LG:
386 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
387 break;
388 case DASM_LABEL_PC: break;
389 case DASM_IMM:
390 cp[-1] |= ((n>>((ins>>10)&31)) & ((1<<((ins>>5)&31))-1)) << (ins&31);
391 break;
392 case DASM_IMM12:
393 cp[-1] |= dasm_imm12((unsigned int)n);
394 break;
395 case DASM_IMM16:
396 cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff);
397 break;
398 case DASM_IMML8: patchimml8:
399 cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :
400 ((-n & 0x0f) | ((-n & 0xf0) << 4));
401 break;
402 case DASM_IMML12: patchimml12:
403 cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);
404 break;
405 default: *cp++ = ins; break;
406 }
407 }
408 stop: (void)0;
409 }
410 }
411
412 if (base + D->codesize != (char *)cp) /* Check for phase errors. */
413 return DASM_S_PHASE;
414 return DASM_S_OK;
415}
416#undef CK
417
418/* Get PC label offset. */
419int dasm_getpclabel(Dst_DECL, unsigned int pc)
420{
421 dasm_State *D = Dst_REF;
422 if (pc*sizeof(int) < D->pcsize) {
423 int pos = D->pclabels[pc];
424 if (pos < 0) return *DASM_POS2PTR(D, -pos);
425 if (pos > 0) return -1; /* Undefined. */
426 }
427 return -2; /* Unused or out of range. */
428}
429
430#ifdef DASM_CHECKS
431/* Optional sanity checker to call between isolated encoding steps. */
432int dasm_checkstep(Dst_DECL, int secmatch)
433{
434 dasm_State *D = Dst_REF;
435 if (D->status == DASM_S_OK) {
436 int i;
437 for (i = 1; i <= 9; i++) {
438 if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
439 D->lglabels[i] = 0;
440 }
441 }
442 if (D->status == DASM_S_OK && secmatch >= 0 &&
443 D->section != &D->sections[secmatch])
444 D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
445 return D->status;
446}
447#endif
448
diff --git a/libraries/luajit-2.0/dynasm/dasm_arm.lua b/libraries/luajit-2.0/dynasm/dasm_arm.lua
new file mode 100644
index 0000000..b8a595b
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_arm.lua
@@ -0,0 +1,949 @@
1------------------------------------------------------------------------------
2-- DynASM ARM module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- See dynasm.lua for full copyright notice.
6------------------------------------------------------------------------------
7
8-- Module information:
9local _info = {
10 arch = "arm",
11 description = "DynASM ARM module",
12 version = "1.3.0",
13 vernum = 10300,
14 release = "2011-05-05",
15 author = "Mike Pall",
16 license = "MIT",
17}
18
19-- Exported glue functions for the arch-specific module.
20local _M = { _info = _info }
21
22-- Cache library functions.
23local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
24local assert, setmetatable, rawget = assert, setmetatable, rawget
25local _s = string
26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
27local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub
28local concat, sort, insert = table.concat, table.sort, table.insert
29
30-- Inherited tables and callbacks.
31local g_opt, g_arch
32local wline, werror, wfatal, wwarn
33
34-- Action name list.
35-- CHECK: Keep this in sync with the C code!
36local action_names = {
37 "STOP", "SECTION", "ESC", "REL_EXT",
38 "ALIGN", "REL_LG", "LABEL_LG",
39 "REL_PC", "LABEL_PC", "IMM", "IMM12", "IMM16", "IMML8", "IMML12",
40}
41
42-- Maximum number of section buffer positions for dasm_put().
43-- CHECK: Keep this in sync with the C code!
44local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
45
46-- Action name -> action number.
47local map_action = {}
48for n,name in ipairs(action_names) do
49 map_action[name] = n-1
50end
51
52-- Action list buffer.
53local actlist = {}
54
55-- Argument list for next dasm_put(). Start with offset 0 into action list.
56local actargs = { 0 }
57
58-- Current number of section buffer positions for dasm_put().
59local secpos = 1
60
61------------------------------------------------------------------------------
62
63-- Return 8 digit hex number.
64local function tohex(x)
65 return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
66end
67
68-- Dump action names and numbers.
69local function dumpactions(out)
70 out:write("DynASM encoding engine action codes:\n")
71 for n,name in ipairs(action_names) do
72 local num = map_action[name]
73 out:write(format(" %-10s %02X %d\n", name, num, num))
74 end
75 out:write("\n")
76end
77
78-- Write action list buffer as a huge static C array.
79local function writeactions(out, name)
80 local nn = #actlist
81 if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
82 out:write("static const unsigned int ", name, "[", nn, "] = {\n")
83 for i = 1,nn-1 do
84 assert(out:write("0x", tohex(actlist[i]), ",\n"))
85 end
86 assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
87end
88
89------------------------------------------------------------------------------
90
91-- Add word to action list.
92local function wputxw(n)
93 assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
94 actlist[#actlist+1] = n
95end
96
97-- Add action to list with optional arg. Advance buffer pos, too.
98local function waction(action, val, a, num)
99 local w = assert(map_action[action], "bad action name `"..action.."'")
100 wputxw(w * 0x10000 + (val or 0))
101 if a then actargs[#actargs+1] = a end
102 if a or num then secpos = secpos + (num or 1) end
103end
104
105-- Flush action list (intervening C code or buffer pos overflow).
106local function wflush(term)
107 if #actlist == actargs[1] then return end -- Nothing to flush.
108 if not term then waction("STOP") end -- Terminate action list.
109 wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
110 actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
111 secpos = 1 -- The actionlist offset occupies a buffer position, too.
112end
113
114-- Put escaped word.
115local function wputw(n)
116 if n <= 0x000fffff then waction("ESC") end
117 wputxw(n)
118end
119
120-- Reserve position for word.
121local function wpos()
122 local pos = #actlist+1
123 actlist[pos] = ""
124 return pos
125end
126
127-- Store word to reserved position.
128local function wputpos(pos, n)
129 assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
130 if n <= 0x000fffff then
131 insert(actlist, pos+1, n)
132 n = map_action.ESC * 0x10000
133 end
134 actlist[pos] = n
135end
136
137------------------------------------------------------------------------------
138
139-- Global label name -> global label number. With auto assignment on 1st use.
140local next_global = 20
141local map_global = setmetatable({}, { __index = function(t, name)
142 if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
143 local n = next_global
144 if n > 2047 then werror("too many global labels") end
145 next_global = n + 1
146 t[name] = n
147 return n
148end})
149
150-- Dump global labels.
151local function dumpglobals(out, lvl)
152 local t = {}
153 for name, n in pairs(map_global) do t[n] = name end
154 out:write("Global labels:\n")
155 for i=20,next_global-1 do
156 out:write(format(" %s\n", t[i]))
157 end
158 out:write("\n")
159end
160
161-- Write global label enum.
162local function writeglobals(out, prefix)
163 local t = {}
164 for name, n in pairs(map_global) do t[n] = name end
165 out:write("enum {\n")
166 for i=20,next_global-1 do
167 out:write(" ", prefix, t[i], ",\n")
168 end
169 out:write(" ", prefix, "_MAX\n};\n")
170end
171
172-- Write global label names.
173local function writeglobalnames(out, name)
174 local t = {}
175 for name, n in pairs(map_global) do t[n] = name end
176 out:write("static const char *const ", name, "[] = {\n")
177 for i=20,next_global-1 do
178 out:write(" \"", t[i], "\",\n")
179 end
180 out:write(" (const char *)0\n};\n")
181end
182
183------------------------------------------------------------------------------
184
185-- Extern label name -> extern label number. With auto assignment on 1st use.
186local next_extern = 0
187local map_extern_ = {}
188local map_extern = setmetatable({}, { __index = function(t, name)
189 -- No restrictions on the name for now.
190 local n = next_extern
191 if n > 2047 then werror("too many extern labels") end
192 next_extern = n + 1
193 t[name] = n
194 map_extern_[n] = name
195 return n
196end})
197
198-- Dump extern labels.
199local function dumpexterns(out, lvl)
200 out:write("Extern labels:\n")
201 for i=0,next_extern-1 do
202 out:write(format(" %s\n", map_extern_[i]))
203 end
204 out:write("\n")
205end
206
207-- Write extern label names.
208local function writeexternnames(out, name)
209 out:write("static const char *const ", name, "[] = {\n")
210 for i=0,next_extern-1 do
211 out:write(" \"", map_extern_[i], "\",\n")
212 end
213 out:write(" (const char *)0\n};\n")
214end
215
216------------------------------------------------------------------------------
217
218-- Arch-specific maps.
219
220-- Ext. register name -> int. name.
221local map_archdef = { sp = "r13", lr = "r14", pc = "r15", }
222
223-- Int. register name -> ext. name.
224local map_reg_rev = { r13 = "sp", r14 = "lr", r15 = "pc", }
225
226local map_type = {} -- Type name -> { ctype, reg }
227local ctypenum = 0 -- Type number (for Dt... macros).
228
229-- Reverse defines for registers.
230function _M.revdef(s)
231 return map_reg_rev[s] or s
232end
233
234local map_shift = { lsl = 0, lsr = 1, asr = 2, ror = 3, }
235
236local map_cond = {
237 eq = 0, ne = 1, cs = 2, cc = 3, mi = 4, pl = 5, vs = 6, vc = 7,
238 hi = 8, ls = 9, ge = 10, lt = 11, gt = 12, le = 13, al = 14,
239 hs = 2, lo = 3,
240}
241
242------------------------------------------------------------------------------
243
244-- Template strings for ARM instructions.
245local map_op = {
246 -- Basic data processing instructions.
247 and_3 = "e0000000DNPs",
248 eor_3 = "e0200000DNPs",
249 sub_3 = "e0400000DNPs",
250 rsb_3 = "e0600000DNPs",
251 add_3 = "e0800000DNPs",
252 adc_3 = "e0a00000DNPs",
253 sbc_3 = "e0c00000DNPs",
254 rsc_3 = "e0e00000DNPs",
255 tst_2 = "e1100000NP",
256 teq_2 = "e1300000NP",
257 cmp_2 = "e1500000NP",
258 cmn_2 = "e1700000NP",
259 orr_3 = "e1800000DNPs",
260 mov_2 = "e1a00000DPs",
261 bic_3 = "e1c00000DNPs",
262 mvn_2 = "e1e00000DPs",
263
264 and_4 = "e0000000DNMps",
265 eor_4 = "e0200000DNMps",
266 sub_4 = "e0400000DNMps",
267 rsb_4 = "e0600000DNMps",
268 add_4 = "e0800000DNMps",
269 adc_4 = "e0a00000DNMps",
270 sbc_4 = "e0c00000DNMps",
271 rsc_4 = "e0e00000DNMps",
272 tst_3 = "e1100000NMp",
273 teq_3 = "e1300000NMp",
274 cmp_3 = "e1500000NMp",
275 cmn_3 = "e1700000NMp",
276 orr_4 = "e1800000DNMps",
277 mov_3 = "e1a00000DMps",
278 bic_4 = "e1c00000DNMps",
279 mvn_3 = "e1e00000DMps",
280
281 lsl_3 = "e1a00000DMws",
282 lsr_3 = "e1a00020DMws",
283 asr_3 = "e1a00040DMws",
284 ror_3 = "e1a00060DMws",
285 rrx_2 = "e1a00060DMs",
286
287 -- Multiply and multiply-accumulate.
288 mul_3 = "e0000090NMSs",
289 mla_4 = "e0200090NMSDs",
290 umaal_4 = "e0400090DNMSs", -- v6
291 mls_4 = "e0600090DNMSs", -- v6T2
292 umull_4 = "e0800090DNMSs",
293 umlal_4 = "e0a00090DNMSs",
294 smull_4 = "e0c00090DNMSs",
295 smlal_4 = "e0e00090DNMSs",
296
297 -- Halfword multiply and multiply-accumulate.
298 smlabb_4 = "e1000080NMSD", -- v5TE
299 smlatb_4 = "e10000a0NMSD", -- v5TE
300 smlabt_4 = "e10000c0NMSD", -- v5TE
301 smlatt_4 = "e10000e0NMSD", -- v5TE
302 smlawb_4 = "e1200080NMSD", -- v5TE
303 smulwb_3 = "e12000a0NMS", -- v5TE
304 smlawt_4 = "e12000c0NMSD", -- v5TE
305 smulwt_3 = "e12000e0NMS", -- v5TE
306 smlalbb_4 = "e1400080NMSD", -- v5TE
307 smlaltb_4 = "e14000a0NMSD", -- v5TE
308 smlalbt_4 = "e14000c0NMSD", -- v5TE
309 smlaltt_4 = "e14000e0NMSD", -- v5TE
310 smulbb_3 = "e1600080NMS", -- v5TE
311 smultb_3 = "e16000a0NMS", -- v5TE
312 smulbt_3 = "e16000c0NMS", -- v5TE
313 smultt_3 = "e16000e0NMS", -- v5TE
314
315 -- Miscellaneous data processing instructions.
316 clz_2 = "e16f0f10DM", -- v5T
317 rev_2 = "e6bf0f30DM", -- v6
318 rev16_2 = "e6bf0fb0DM", -- v6
319 revsh_2 = "e6ff0fb0DM", -- v6
320 sel_3 = "e6800fb0DNM", -- v6
321 usad8_3 = "e780f010NMS", -- v6
322 usada8_4 = "e7800010NMSD", -- v6
323 rbit_2 = "e6ff0f30DM", -- v6T2
324 movw_2 = "e3000000DW", -- v6T2
325 movt_2 = "e3400000DW", -- v6T2
326 -- Note: the X encodes width-1, not width.
327 sbfx_4 = "e7a00050DMvX", -- v6T2
328 ubfx_4 = "e7e00050DMvX", -- v6T2
329 -- Note: the X encodes the msb field, not the width.
330 bfc_3 = "e7c0001fDvX", -- v6T2
331 bfi_4 = "e7c00010DMvX", -- v6T2
332
333 -- Packing and unpacking instructions.
334 pkhbt_3 = "e6800010DNM", pkhbt_4 = "e6800010DNMv", -- v6
335 pkhtb_3 = "e6800050DNM", pkhtb_4 = "e6800050DNMv", -- v6
336 sxtab_3 = "e6a00070DNM", sxtab_4 = "e6a00070DNMv", -- v6
337 sxtab16_3 = "e6800070DNM", sxtab16_4 = "e6800070DNMv", -- v6
338 sxtah_3 = "e6b00070DNM", sxtah_4 = "e6b00070DNMv", -- v6
339 sxtb_2 = "e6af0070DM", sxtb_3 = "e6af0070DMv", -- v6
340 sxtb16_2 = "e68f0070DM", sxtb16_3 = "e68f0070DMv", -- v6
341 sxth_2 = "e6bf0070DM", sxth_3 = "e6bf0070DMv", -- v6
342 uxtab_3 = "e6e00070DNM", uxtab_4 = "e6e00070DNMv", -- v6
343 uxtab16_3 = "e6c00070DNM", uxtab16_4 = "e6c00070DNMv", -- v6
344 uxtah_3 = "e6f00070DNM", uxtah_4 = "e6f00070DNMv", -- v6
345 uxtb_2 = "e6ef0070DM", uxtb_3 = "e6ef0070DMv", -- v6
346 uxtb16_2 = "e6cf0070DM", uxtb16_3 = "e6cf0070DMv", -- v6
347 uxth_2 = "e6ff0070DM", uxth_3 = "e6ff0070DMv", -- v6
348
349 -- Saturating instructions.
350 qadd_3 = "e1000050DMN", -- v5TE
351 qsub_3 = "e1200050DMN", -- v5TE
352 qdadd_3 = "e1400050DMN", -- v5TE
353 qdsub_3 = "e1600050DMN", -- v5TE
354 -- Note: the X for ssat* encodes sat_imm-1, not sat_imm.
355 ssat_3 = "e6a00010DXM", ssat_4 = "e6a00010DXMp", -- v6
356 usat_3 = "e6e00010DXM", usat_4 = "e6e00010DXMp", -- v6
357 ssat16_3 = "e6a00f30DXM", -- v6
358 usat16_3 = "e6e00f30DXM", -- v6
359
360 -- Parallel addition and subtraction.
361 sadd16_3 = "e6100f10DNM", -- v6
362 sasx_3 = "e6100f30DNM", -- v6
363 ssax_3 = "e6100f50DNM", -- v6
364 ssub16_3 = "e6100f70DNM", -- v6
365 sadd8_3 = "e6100f90DNM", -- v6
366 ssub8_3 = "e6100ff0DNM", -- v6
367 qadd16_3 = "e6200f10DNM", -- v6
368 qasx_3 = "e6200f30DNM", -- v6
369 qsax_3 = "e6200f50DNM", -- v6
370 qsub16_3 = "e6200f70DNM", -- v6
371 qadd8_3 = "e6200f90DNM", -- v6
372 qsub8_3 = "e6200ff0DNM", -- v6
373 shadd16_3 = "e6300f10DNM", -- v6
374 shasx_3 = "e6300f30DNM", -- v6
375 shsax_3 = "e6300f50DNM", -- v6
376 shsub16_3 = "e6300f70DNM", -- v6
377 shadd8_3 = "e6300f90DNM", -- v6
378 shsub8_3 = "e6300ff0DNM", -- v6
379 uadd16_3 = "e6500f10DNM", -- v6
380 uasx_3 = "e6500f30DNM", -- v6
381 usax_3 = "e6500f50DNM", -- v6
382 usub16_3 = "e6500f70DNM", -- v6
383 uadd8_3 = "e6500f90DNM", -- v6
384 usub8_3 = "e6500ff0DNM", -- v6
385 uqadd16_3 = "e6600f10DNM", -- v6
386 uqasx_3 = "e6600f30DNM", -- v6
387 uqsax_3 = "e6600f50DNM", -- v6
388 uqsub16_3 = "e6600f70DNM", -- v6
389 uqadd8_3 = "e6600f90DNM", -- v6
390 uqsub8_3 = "e6600ff0DNM", -- v6
391 uhadd16_3 = "e6700f10DNM", -- v6
392 uhasx_3 = "e6700f30DNM", -- v6
393 uhsax_3 = "e6700f50DNM", -- v6
394 uhsub16_3 = "e6700f70DNM", -- v6
395 uhadd8_3 = "e6700f90DNM", -- v6
396 uhsub8_3 = "e6700ff0DNM", -- v6
397
398 -- Load/store instructions.
399 str_2 = "e4000000DL", str_3 = "e4000000DL", str_4 = "e4000000DL",
400 strb_2 = "e4400000DL", strb_3 = "e4400000DL", strb_4 = "e4400000DL",
401 ldr_2 = "e4100000DL", ldr_3 = "e4100000DL", ldr_4 = "e4100000DL",
402 ldrb_2 = "e4500000DL", ldrb_3 = "e4500000DL", ldrb_4 = "e4500000DL",
403 strh_2 = "e00000b0DL", strh_3 = "e00000b0DL",
404 ldrh_2 = "e01000b0DL", ldrh_3 = "e01000b0DL",
405 ldrd_2 = "e00000d0DL", ldrd_3 = "e00000d0DL", -- v5TE
406 ldrsb_2 = "e01000d0DL", ldrsb_3 = "e01000d0DL",
407 strd_2 = "e00000f0DL", strd_3 = "e00000f0DL", -- v5TE
408 ldrsh_2 = "e01000f0DL", ldrsh_3 = "e01000f0DL",
409
410 ldm_2 = "e8900000nR", ldmia_2 = "e8900000nR", ldmfd_2 = "e8900000nR",
411 ldmda_2 = "e8100000nR", ldmfa_2 = "e8100000nR",
412 ldmdb_2 = "e9100000nR", ldmea_2 = "e9100000nR",
413 ldmib_2 = "e9900000nR", ldmed_2 = "e9900000nR",
414 stm_2 = "e8800000nR", stmia_2 = "e8800000nR", stmfd_2 = "e8800000nR",
415 stmda_2 = "e8000000nR", stmfa_2 = "e8000000nR",
416 stmdb_2 = "e9000000nR", stmea_2 = "e9000000nR",
417 stmib_2 = "e9800000nR", stmed_2 = "e9800000nR",
418 pop_1 = "e8bd0000R", push_1 = "e92d0000R",
419
420 -- Branch instructions.
421 b_1 = "ea000000B",
422 bl_1 = "eb000000B",
423 blx_1 = "e12fff30C",
424 bx_1 = "e12fff10M",
425
426 -- Miscellaneous instructions.
427 nop_0 = "e1a00000",
428 mrs_1 = "e10f0000D",
429 bkpt_1 = "e1200070K", -- v5T
430 svc_1 = "ef000000T", swi_1 = "ef000000T",
431 ud_0 = "e7f001f0",
432
433 -- NYI: Advanced SIMD and VFP instructions.
434
435 -- NYI instructions, since I have no need for them right now:
436 -- swp, swpb, strex, ldrex, strexd, ldrexd, strexb, ldrexb, strexh, ldrexh
437 -- msr, nopv6, yield, wfe, wfi, sev, dbg, bxj, smc, srs, rfe
438 -- cps, setend, pli, pld, pldw, clrex, dsb, dmb, isb
439 -- stc, ldc, mcr, mcr2, mrc, mrc2, mcrr, mcrr2, mrrc, mrrc2, cdp, cdp2
440}
441
442-- Add mnemonics for "s" variants.
443do
444 local t = {}
445 for k,v in pairs(map_op) do
446 if sub(v, -1) == "s" then
447 local v2 = sub(v, 1, 2)..char(byte(v, 3)+1)..sub(v, 4, -2)
448 t[sub(k, 1, -3).."s"..sub(k, -2)] = v2
449 end
450 end
451 for k,v in pairs(t) do
452 map_op[k] = v
453 end
454end
455
456------------------------------------------------------------------------------
457
458local function parse_gpr(expr)
459 local tname, ovreg = match(expr, "^([%w_]+):(r1?[0-9])$")
460 local tp = map_type[tname or expr]
461 if tp then
462 local reg = ovreg or tp.reg
463 if not reg then
464 werror("type `"..(tname or expr).."' needs a register override")
465 end
466 expr = reg
467 end
468 local r = match(expr, "^r(1?[0-9])$")
469 if r then
470 r = tonumber(r)
471 if r <= 15 then return r, tp end
472 end
473 werror("bad register name `"..expr.."'")
474end
475
476local function parse_gpr_pm(expr)
477 local pm, expr2 = match(expr, "^([+-]?)(.*)$")
478 return parse_gpr(expr2), (pm == "-")
479end
480
481local function parse_reglist(reglist)
482 reglist = match(reglist, "^{%s*([^}]*)}$")
483 if not reglist then werror("register list expected") end
484 local rr = 0
485 for p in gmatch(reglist..",", "%s*([^,]*),") do
486 local rbit = 2^parse_gpr(gsub(p, "%s+$", ""))
487 if ((rr - (rr % rbit)) / rbit) % 2 ~= 0 then
488 werror("duplicate register `"..p.."'")
489 end
490 rr = rr + rbit
491 end
492 return rr
493end
494
495local function parse_imm(imm, bits, shift, scale, signed)
496 imm = match(imm, "^#(.*)$")
497 if not imm then werror("expected immediate operand") end
498 local n = tonumber(imm)
499 if n then
500 if n % 2^scale == 0 then
501 n = n / 2^scale
502 if signed then
503 if n >= 0 then
504 if n < 2^(bits-1) then return n*2^shift end
505 else
506 if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end
507 end
508 else
509 if n >= 0 and n <= 2^bits-1 then return n*2^shift end
510 end
511 end
512 werror("out of range immediate `"..imm.."'")
513 else
514 waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
515 return 0
516 end
517end
518
519local function parse_imm12(imm)
520 local n = tonumber(imm)
521 if n then
522 local m = n
523 for i=0,-15,-1 do
524 if m >= 0 and m <= 255 and n % 1 == 0 then return m + (i%16) * 256 end
525 local t = m % 4
526 m = (m - t) / 4 + t * 2^30
527 end
528 werror("out of range immediate `"..imm.."'")
529 else
530 waction("IMM12", 0, imm)
531 return 0
532 end
533end
534
535local function parse_imm16(imm)
536 imm = match(imm, "^#(.*)$")
537 if not imm then werror("expected immediate operand") end
538 local n = tonumber(imm)
539 if n then
540 if n >= 0 and n <= 65535 and n % 1 == 0 then
541 local t = n % 4096
542 return (n - t) * 16 + t
543 end
544 werror("out of range immediate `"..imm.."'")
545 else
546 waction("IMM16", 32*16, imm)
547 return 0
548 end
549end
550
551local function parse_imm_load(imm, ext)
552 local n = tonumber(imm)
553 if n then
554 if ext then
555 if n >= -255 and n <= 255 then
556 local up = 0x00800000
557 if n < 0 then n = -n; up = 0 end
558 return (n-(n%16))*16+(n%16) + up
559 end
560 else
561 if n >= -4095 and n <= 4095 then
562 if n >= 0 then return n+0x00800000 end
563 return -n
564 end
565 end
566 werror("out of range immediate `"..imm.."'")
567 else
568 waction(ext and "IMML8" or "IMML12", 32768 + 32*(ext and 8 or 12), imm)
569 return 0
570 end
571end
572
573local function parse_shift(shift, gprok)
574 if shift == "rrx" then
575 return 3 * 32
576 else
577 local s, s2 = match(shift, "^(%S+)%s*(.*)$")
578 s = map_shift[s]
579 if not s then werror("expected shift operand") end
580 if sub(s2, 1, 1) == "#" then
581 return parse_imm(s2, 5, 7, 0, false) + s * 32
582 else
583 if not gprok then werror("expected immediate shift operand") end
584 return parse_gpr(s2) * 256 + s * 32 + 16
585 end
586 end
587end
588
589local function parse_label(label, def)
590 local prefix = sub(label, 1, 2)
591 -- =>label (pc label reference)
592 if prefix == "=>" then
593 return "PC", 0, sub(label, 3)
594 end
595 -- ->name (global label reference)
596 if prefix == "->" then
597 return "LG", map_global[sub(label, 3)]
598 end
599 if def then
600 -- [1-9] (local label definition)
601 if match(label, "^[1-9]$") then
602 return "LG", 10+tonumber(label)
603 end
604 else
605 -- [<>][1-9] (local label reference)
606 local dir, lnum = match(label, "^([<>])([1-9])$")
607 if dir then -- Fwd: 1-9, Bkwd: 11-19.
608 return "LG", lnum + (dir == ">" and 0 or 10)
609 end
610 -- extern label (extern label reference)
611 local extname = match(label, "^extern%s+(%S+)$")
612 if extname then
613 return "EXT", map_extern[extname]
614 end
615 end
616 werror("bad label `"..label.."'")
617end
618
619local function parse_load(params, nparams, n, op)
620 local oplo = op % 256
621 local ext, ldrd = (oplo ~= 0), (oplo == 208)
622 local d
623 if (ldrd or oplo == 240) then
624 d = ((op - (op % 4096)) / 4096) % 16
625 if d % 2 ~= 0 then werror("odd destination register") end
626 end
627 local pn = params[n]
628 local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
629 local p2 = params[n+1]
630 if not p1 then
631 if not p2 then
632 if match(pn, "^[<>=%-]") or match(pn, "^extern%s+") then
633 local mode, n, s = parse_label(pn, false)
634 waction("REL_"..mode, n + (ext and 0x1800 or 0x0800), s, 1)
635 return op + 15 * 65536 + 0x01000000 + (ext and 0x00400000 or 0)
636 end
637 local reg, tailr = match(pn, "^([%w_:]+)%s*(.*)$")
638 if reg and tailr ~= "" then
639 local d, tp = parse_gpr(reg)
640 if tp then
641 waction(ext and "IMML8" or "IMML12", 32768 + 32*(ext and 8 or 12),
642 format(tp.ctypefmt, tailr))
643 return op + d * 65536 + 0x01000000 + (ext and 0x00400000 or 0)
644 end
645 end
646 end
647 werror("expected address operand")
648 end
649 if wb == "!" then op = op + 0x00200000 end
650 if p2 then
651 if wb == "!" then werror("bad use of '!'") end
652 local p3 = params[n+2]
653 op = op + parse_gpr(p1) * 65536
654 local imm = match(p2, "^#(.*)$")
655 if imm then
656 local m = parse_imm_load(imm, ext)
657 if p3 then werror("too many parameters") end
658 op = op + m + (ext and 0x00400000 or 0)
659 else
660 local m, neg = parse_gpr_pm(p2)
661 if ldrd and (m == d or m-1 == d) then werror("register conflict") end
662 op = op + m + (neg and 0 or 0x00800000) + (ext and 0 or 0x02000000)
663 if p3 then op = op + parse_shift(p3) end
664 end
665 else
666 local p1a, p2 = match(p1, "^([^,%s]*)%s*(.*)$")
667 op = op + parse_gpr(p1a) * 65536 + 0x01000000
668 if p2 ~= "" then
669 local imm = match(p2, "^,%s*#(.*)$")
670 if imm then
671 local m = parse_imm_load(imm, ext)
672 op = op + m + (ext and 0x00400000 or 0)
673 else
674 local p2a, p3 = match(p2, "^,%s*([^,%s]*)%s*,?%s*(.*)$")
675 local m, neg = parse_gpr_pm(p2a)
676 if ldrd and (m == d or m-1 == d) then werror("register conflict") end
677 op = op + m + (neg and 0 or 0x00800000) + (ext and 0 or 0x02000000)
678 if p3 ~= "" then
679 if ext then werror("too many parameters") end
680 op = op + parse_shift(p3)
681 end
682 end
683 else
684 if wb == "!" then werror("bad use of '!'") end
685 op = op + (ext and 0x00c00000 or 0x00800000)
686 end
687 end
688 return op
689end
690
691------------------------------------------------------------------------------
692
693-- Handle opcodes defined with template strings.
694map_op[".template__"] = function(params, template, nparams)
695 if not params then return sub(template, 9) end
696 local op = tonumber(sub(template, 1, 8), 16)
697 local n = 1
698
699 -- Limit number of section buffer positions used by a single dasm_put().
700 -- A single opcode needs a maximum of 3 positions.
701 if secpos+3 > maxsecpos then wflush() end
702 local pos = wpos()
703
704 -- Process each character.
705 for p in gmatch(sub(template, 9), ".") do
706 if p == "D" then
707 op = op + parse_gpr(params[n]) * 4096; n = n + 1
708 elseif p == "N" then
709 op = op + parse_gpr(params[n]) * 65536; n = n + 1
710 elseif p == "S" then
711 op = op + parse_gpr(params[n]) * 256; n = n + 1
712 elseif p == "M" then
713 op = op + parse_gpr(params[n]); n = n + 1
714 elseif p == "P" then
715 local imm = match(params[n], "^#(.*)$")
716 if imm then
717 op = op + parse_imm12(imm) + 0x02000000
718 else
719 op = op + parse_gpr(params[n])
720 end
721 n = n + 1
722 elseif p == "p" then
723 op = op + parse_shift(params[n], true); n = n + 1
724 elseif p == "L" then
725 op = parse_load(params, nparams, n, op)
726 elseif p == "B" then
727 local mode, n, s = parse_label(params[n], false)
728 waction("REL_"..mode, n, s, 1)
729 elseif p == "C" then -- blx gpr vs. blx label.
730 local p = params[n]
731 if match(p, "^([%w_]+):(r1?[0-9])$") or match(p, "^r(1?[0-9])$") then
732 op = op + parse_gpr(p)
733 else
734 if op < 0xe0000000 then werror("unconditional instruction") end
735 local mode, n, s = parse_label(p, false)
736 waction("REL_"..mode, n, s, 1)
737 op = 0xfa000000
738 end
739 elseif p == "n" then
740 local r, wb = match(params[n], "^([^!]*)(!?)$")
741 op = op + parse_gpr(r) * 65536 + (wb == "!" and 0x00200000 or 0)
742 n = n + 1
743 elseif p == "R" then
744 op = op + parse_reglist(params[n]); n = n + 1
745 elseif p == "W" then
746 op = op + parse_imm16(params[n]); n = n + 1
747 elseif p == "v" then
748 op = op + parse_imm(params[n], 5, 7, 0, false); n = n + 1
749 elseif p == "w" then
750 local imm = match(params[n], "^#(.*)$")
751 if imm then
752 op = op + parse_imm(params[n], 5, 7, 0, false); n = n + 1
753 else
754 op = op + parse_gpr(params[n]) * 256 + 16
755 end
756 elseif p == "X" then
757 op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1
758 elseif p == "K" then
759 local imm = tonumber(match(params[n], "^#(.*)$")); n = n + 1
760 if not imm or imm % 1 ~= 0 or imm < 0 or imm > 0xffff then
761 werror("bad immediate operand")
762 end
763 local t = imm % 16
764 op = op + (imm - t) * 16 + t
765 elseif p == "T" then
766 op = op + parse_imm(params[n], 24, 0, 0, false); n = n + 1
767 elseif p == "s" then
768 -- Ignored.
769 else
770 assert(false)
771 end
772 end
773 wputpos(pos, op)
774end
775
776------------------------------------------------------------------------------
777
778-- Pseudo-opcode to mark the position where the action list is to be emitted.
779map_op[".actionlist_1"] = function(params)
780 if not params then return "cvar" end
781 local name = params[1] -- No syntax check. You get to keep the pieces.
782 wline(function(out) writeactions(out, name) end)
783end
784
785-- Pseudo-opcode to mark the position where the global enum is to be emitted.
786map_op[".globals_1"] = function(params)
787 if not params then return "prefix" end
788 local prefix = params[1] -- No syntax check. You get to keep the pieces.
789 wline(function(out) writeglobals(out, prefix) end)
790end
791
792-- Pseudo-opcode to mark the position where the global names are to be emitted.
793map_op[".globalnames_1"] = function(params)
794 if not params then return "cvar" end
795 local name = params[1] -- No syntax check. You get to keep the pieces.
796 wline(function(out) writeglobalnames(out, name) end)
797end
798
799-- Pseudo-opcode to mark the position where the extern names are to be emitted.
800map_op[".externnames_1"] = function(params)
801 if not params then return "cvar" end
802 local name = params[1] -- No syntax check. You get to keep the pieces.
803 wline(function(out) writeexternnames(out, name) end)
804end
805
806------------------------------------------------------------------------------
807
808-- Label pseudo-opcode (converted from trailing colon form).
809map_op[".label_1"] = function(params)
810 if not params then return "[1-9] | ->global | =>pcexpr" end
811 if secpos+1 > maxsecpos then wflush() end
812 local mode, n, s = parse_label(params[1], true)
813 if mode == "EXT" then werror("bad label definition") end
814 waction("LABEL_"..mode, n, s, 1)
815end
816
817------------------------------------------------------------------------------
818
819-- Pseudo-opcodes for data storage.
820map_op[".long_*"] = function(params)
821 if not params then return "imm..." end
822 for _,p in ipairs(params) do
823 local n = tonumber(p)
824 if not n then werror("bad immediate `"..p.."'") end
825 if n < 0 then n = n + 2^32 end
826 wputw(n)
827 if secpos+2 > maxsecpos then wflush() end
828 end
829end
830
831-- Alignment pseudo-opcode.
832map_op[".align_1"] = function(params)
833 if not params then return "numpow2" end
834 if secpos+1 > maxsecpos then wflush() end
835 local align = tonumber(params[1])
836 if align then
837 local x = align
838 -- Must be a power of 2 in the range (2 ... 256).
839 for i=1,8 do
840 x = x / 2
841 if x == 1 then
842 waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
843 return
844 end
845 end
846 end
847 werror("bad alignment")
848end
849
850------------------------------------------------------------------------------
851
852-- Pseudo-opcode for (primitive) type definitions (map to C types).
853map_op[".type_3"] = function(params, nparams)
854 if not params then
855 return nparams == 2 and "name, ctype" or "name, ctype, reg"
856 end
857 local name, ctype, reg = params[1], params[2], params[3]
858 if not match(name, "^[%a_][%w_]*$") then
859 werror("bad type name `"..name.."'")
860 end
861 local tp = map_type[name]
862 if tp then
863 werror("duplicate type `"..name.."'")
864 end
865 -- Add #type to defines. A bit unclean to put it in map_archdef.
866 map_archdef["#"..name] = "sizeof("..ctype..")"
867 -- Add new type and emit shortcut define.
868 local num = ctypenum + 1
869 map_type[name] = {
870 ctype = ctype,
871 ctypefmt = format("Dt%X(%%s)", num),
872 reg = reg,
873 }
874 wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
875 ctypenum = num
876end
877map_op[".type_2"] = map_op[".type_3"]
878
879-- Dump type definitions.
880local function dumptypes(out, lvl)
881 local t = {}
882 for name in pairs(map_type) do t[#t+1] = name end
883 sort(t)
884 out:write("Type definitions:\n")
885 for _,name in ipairs(t) do
886 local tp = map_type[name]
887 local reg = tp.reg or ""
888 out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
889 end
890 out:write("\n")
891end
892
893------------------------------------------------------------------------------
894
895-- Set the current section.
896function _M.section(num)
897 waction("SECTION", num)
898 wflush(true) -- SECTION is a terminal action.
899end
900
901------------------------------------------------------------------------------
902
903-- Dump architecture description.
904function _M.dumparch(out)
905 out:write(format("DynASM %s version %s, released %s\n\n",
906 _info.arch, _info.version, _info.release))
907 dumpactions(out)
908end
909
910-- Dump all user defined elements.
911function _M.dumpdef(out, lvl)
912 dumptypes(out, lvl)
913 dumpglobals(out, lvl)
914 dumpexterns(out, lvl)
915end
916
917------------------------------------------------------------------------------
918
919-- Pass callbacks from/to the DynASM core.
920function _M.passcb(wl, we, wf, ww)
921 wline, werror, wfatal, wwarn = wl, we, wf, ww
922 return wflush
923end
924
925-- Setup the arch-specific module.
926function _M.setup(arch, opt)
927 g_arch, g_opt = arch, opt
928end
929
930-- Merge the core maps and the arch-specific maps.
931function _M.mergemaps(map_coreop, map_def)
932 setmetatable(map_op, { __index = function(t, k)
933 local v = map_coreop[k]
934 if v then return v end
935 local cc = sub(k, -4, -3)
936 local cv = map_cond[cc]
937 if cv then
938 local v = rawget(t, sub(k, 1, -5)..sub(k, -2))
939 if type(v) == "string" then return format("%x%s", cv, sub(v, 2)) end
940 end
941 end })
942 setmetatable(map_def, { __index = map_archdef })
943 return map_op, map_def
944end
945
946return _M
947
948------------------------------------------------------------------------------
949
diff --git a/libraries/luajit-2.0/dynasm/dasm_mips.h b/libraries/luajit-2.0/dynasm/dasm_mips.h
new file mode 100644
index 0000000..832f9f2
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_mips.h
@@ -0,0 +1,415 @@
1/*
2** DynASM MIPS encoding engine.
3** Copyright (C) 2005-2011 Mike Pall. All rights reserved.
4** Released under the MIT license. See dynasm.lua for full copyright notice.
5*/
6
7#include <stddef.h>
8#include <stdarg.h>
9#include <string.h>
10#include <stdlib.h>
11
12#define DASM_ARCH "mips"
13
14#ifndef DASM_EXTERN
15#define DASM_EXTERN(a,b,c,d) 0
16#endif
17
18/* Action definitions. */
19enum {
20 DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
21 /* The following actions need a buffer position. */
22 DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
23 /* The following actions also have an argument. */
24 DASM_REL_PC, DASM_LABEL_PC, DASM_IMM,
25 DASM__MAX
26};
27
28/* Maximum number of section buffer positions for a single dasm_put() call. */
29#define DASM_MAXSECPOS 25
30
31/* DynASM encoder status codes. Action list offset or number are or'ed in. */
32#define DASM_S_OK 0x00000000
33#define DASM_S_NOMEM 0x01000000
34#define DASM_S_PHASE 0x02000000
35#define DASM_S_MATCH_SEC 0x03000000
36#define DASM_S_RANGE_I 0x11000000
37#define DASM_S_RANGE_SEC 0x12000000
38#define DASM_S_RANGE_LG 0x13000000
39#define DASM_S_RANGE_PC 0x14000000
40#define DASM_S_RANGE_REL 0x15000000
41#define DASM_S_UNDEF_LG 0x21000000
42#define DASM_S_UNDEF_PC 0x22000000
43
44/* Macros to convert positions (8 bit section + 24 bit index). */
45#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
46#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
47#define DASM_SEC2POS(sec) ((sec)<<24)
48#define DASM_POS2SEC(pos) ((pos)>>24)
49#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
50
51/* Action list type. */
52typedef const unsigned int *dasm_ActList;
53
54/* Per-section structure. */
55typedef struct dasm_Section {
56 int *rbuf; /* Biased buffer pointer (negative section bias). */
57 int *buf; /* True buffer pointer. */
58 size_t bsize; /* Buffer size in bytes. */
59 int pos; /* Biased buffer position. */
60 int epos; /* End of biased buffer position - max single put. */
61 int ofs; /* Byte offset into section. */
62} dasm_Section;
63
64/* Core structure holding the DynASM encoding state. */
65struct dasm_State {
66 size_t psize; /* Allocated size of this structure. */
67 dasm_ActList actionlist; /* Current actionlist pointer. */
68 int *lglabels; /* Local/global chain/pos ptrs. */
69 size_t lgsize;
70 int *pclabels; /* PC label chains/pos ptrs. */
71 size_t pcsize;
72 void **globals; /* Array of globals (bias -10). */
73 dasm_Section *section; /* Pointer to active section. */
74 size_t codesize; /* Total size of all code sections. */
75 int maxsection; /* 0 <= sectionidx < maxsection. */
76 int status; /* Status code. */
77 dasm_Section sections[1]; /* All sections. Alloc-extended. */
78};
79
80/* The size of the core structure depends on the max. number of sections. */
81#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
82
83
84/* Initialize DynASM state. */
85void dasm_init(Dst_DECL, int maxsection)
86{
87 dasm_State *D;
88 size_t psz = 0;
89 int i;
90 Dst_REF = NULL;
91 DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
92 D = Dst_REF;
93 D->psize = psz;
94 D->lglabels = NULL;
95 D->lgsize = 0;
96 D->pclabels = NULL;
97 D->pcsize = 0;
98 D->globals = NULL;
99 D->maxsection = maxsection;
100 for (i = 0; i < maxsection; i++) {
101 D->sections[i].buf = NULL; /* Need this for pass3. */
102 D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
103 D->sections[i].bsize = 0;
104 D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
105 }
106}
107
108/* Free DynASM state. */
109void dasm_free(Dst_DECL)
110{
111 dasm_State *D = Dst_REF;
112 int i;
113 for (i = 0; i < D->maxsection; i++)
114 if (D->sections[i].buf)
115 DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
116 if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
117 if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
118 DASM_M_FREE(Dst, D, D->psize);
119}
120
121/* Setup global label array. Must be called before dasm_setup(). */
122void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
123{
124 dasm_State *D = Dst_REF;
125 D->globals = gl - 10; /* Negative bias to compensate for locals. */
126 DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
127}
128
129/* Grow PC label array. Can be called after dasm_setup(), too. */
130void dasm_growpc(Dst_DECL, unsigned int maxpc)
131{
132 dasm_State *D = Dst_REF;
133 size_t osz = D->pcsize;
134 DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
135 memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
136}
137
138/* Setup encoder. */
139void dasm_setup(Dst_DECL, const void *actionlist)
140{
141 dasm_State *D = Dst_REF;
142 int i;
143 D->actionlist = (dasm_ActList)actionlist;
144 D->status = DASM_S_OK;
145 D->section = &D->sections[0];
146 memset((void *)D->lglabels, 0, D->lgsize);
147 if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
148 for (i = 0; i < D->maxsection; i++) {
149 D->sections[i].pos = DASM_SEC2POS(i);
150 D->sections[i].ofs = 0;
151 }
152}
153
154
155#ifdef DASM_CHECKS
156#define CK(x, st) \
157 do { if (!(x)) { \
158 D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
159#define CKPL(kind, st) \
160 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
161 D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
162#else
163#define CK(x, st) ((void)0)
164#define CKPL(kind, st) ((void)0)
165#endif
166
167/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
168void dasm_put(Dst_DECL, int start, ...)
169{
170 va_list ap;
171 dasm_State *D = Dst_REF;
172 dasm_ActList p = D->actionlist + start;
173 dasm_Section *sec = D->section;
174 int pos = sec->pos, ofs = sec->ofs;
175 int *b;
176
177 if (pos >= sec->epos) {
178 DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
179 sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
180 sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
181 sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
182 }
183
184 b = sec->rbuf;
185 b[pos++] = start;
186
187 va_start(ap, start);
188 while (1) {
189 unsigned int ins = *p++;
190 unsigned int action = (ins >> 16) - 0xff00;
191 if (action >= DASM__MAX) {
192 ofs += 4;
193 } else {
194 int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
195 switch (action) {
196 case DASM_STOP: goto stop;
197 case DASM_SECTION:
198 n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
199 D->section = &D->sections[n]; goto stop;
200 case DASM_ESC: p++; ofs += 4; break;
201 case DASM_REL_EXT: break;
202 case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
203 case DASM_REL_LG:
204 n = (ins & 2047) - 10; pl = D->lglabels + n;
205 if (n >= 0) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
206 pl += 10; n = *pl;
207 if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
208 goto linkrel;
209 case DASM_REL_PC:
210 pl = D->pclabels + n; CKPL(pc, PC);
211 putrel:
212 n = *pl;
213 if (n < 0) { /* Label exists. Get label pos and store it. */
214 b[pos] = -n;
215 } else {
216 linkrel:
217 b[pos] = n; /* Else link to rel chain, anchored at label. */
218 *pl = pos;
219 }
220 pos++;
221 break;
222 case DASM_LABEL_LG:
223 pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
224 case DASM_LABEL_PC:
225 pl = D->pclabels + n; CKPL(pc, PC);
226 putlabel:
227 n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
228 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
229 }
230 *pl = -pos; /* Label exists now. */
231 b[pos++] = ofs; /* Store pass1 offset estimate. */
232 break;
233 case DASM_IMM:
234#ifdef DASM_CHECKS
235 CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
236#endif
237 n >>= ((ins>>10)&31);
238#ifdef DASM_CHECKS
239 if (ins & 0x8000)
240 CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
241 else
242 CK((n>>((ins>>5)&31)) == 0, RANGE_I);
243#endif
244 b[pos++] = n;
245 break;
246 }
247 }
248 }
249stop:
250 va_end(ap);
251 sec->pos = pos;
252 sec->ofs = ofs;
253}
254#undef CK
255
256/* Pass 2: Link sections, shrink aligns, fix label offsets. */
257int dasm_link(Dst_DECL, size_t *szp)
258{
259 dasm_State *D = Dst_REF;
260 int secnum;
261 int ofs = 0;
262
263#ifdef DASM_CHECKS
264 *szp = 0;
265 if (D->status != DASM_S_OK) return D->status;
266 {
267 int pc;
268 for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
269 if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
270 }
271#endif
272
273 { /* Handle globals not defined in this translation unit. */
274 int idx;
275 for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
276 int n = D->lglabels[idx];
277 /* Undefined label: Collapse rel chain and replace with marker (< 0). */
278 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
279 }
280 }
281
282 /* Combine all code sections. No support for data sections (yet). */
283 for (secnum = 0; secnum < D->maxsection; secnum++) {
284 dasm_Section *sec = D->sections + secnum;
285 int *b = sec->rbuf;
286 int pos = DASM_SEC2POS(secnum);
287 int lastpos = sec->pos;
288
289 while (pos != lastpos) {
290 dasm_ActList p = D->actionlist + b[pos++];
291 while (1) {
292 unsigned int ins = *p++;
293 unsigned int action = (ins >> 16) - 0xff00;
294 switch (action) {
295 case DASM_STOP: case DASM_SECTION: goto stop;
296 case DASM_ESC: p++; break;
297 case DASM_REL_EXT: break;
298 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
299 case DASM_REL_LG: case DASM_REL_PC: pos++; break;
300 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
301 case DASM_IMM: pos++; break;
302 }
303 }
304 stop: (void)0;
305 }
306 ofs += sec->ofs; /* Next section starts right after current section. */
307 }
308
309 D->codesize = ofs; /* Total size of all code sections */
310 *szp = ofs;
311 return DASM_S_OK;
312}
313
314#ifdef DASM_CHECKS
315#define CK(x, st) \
316 do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
317#else
318#define CK(x, st) ((void)0)
319#endif
320
321/* Pass 3: Encode sections. */
322int dasm_encode(Dst_DECL, void *buffer)
323{
324 dasm_State *D = Dst_REF;
325 char *base = (char *)buffer;
326 unsigned int *cp = (unsigned int *)buffer;
327 int secnum;
328
329 /* Encode all code sections. No support for data sections (yet). */
330 for (secnum = 0; secnum < D->maxsection; secnum++) {
331 dasm_Section *sec = D->sections + secnum;
332 int *b = sec->buf;
333 int *endb = sec->rbuf + sec->pos;
334
335 while (b != endb) {
336 dasm_ActList p = D->actionlist + *b++;
337 while (1) {
338 unsigned int ins = *p++;
339 unsigned int action = (ins >> 16) - 0xff00;
340 int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
341 switch (action) {
342 case DASM_STOP: case DASM_SECTION: goto stop;
343 case DASM_ESC: *cp++ = *p++; break;
344 case DASM_REL_EXT:
345 n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1);
346 goto patchrel;
347 case DASM_ALIGN:
348 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
349 break;
350 case DASM_REL_LG:
351 CK(n >= 0, UNDEF_LG);
352 case DASM_REL_PC:
353 CK(n >= 0, UNDEF_PC);
354 n = *DASM_POS2PTR(D, n);
355 if (ins & 2048)
356 n = n - (int)((char *)cp - base);
357 else
358 n = (n + (int)base) & 0x0fffffff;
359 patchrel:
360 CK((n & 3) == 0 &&
361 ((n + ((ins & 2048) ? 0x00020000 : 0)) >>
362 ((ins & 2048) ? 18 : 28)) == 0, RANGE_REL);
363 cp[-1] |= ((n>>2) & ((ins & 2048) ? 0x0000ffff: 0x03ffffff));
364 break;
365 case DASM_LABEL_LG:
366 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
367 break;
368 case DASM_LABEL_PC: break;
369 case DASM_IMM:
370 cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
371 break;
372 default: *cp++ = ins; break;
373 }
374 }
375 stop: (void)0;
376 }
377 }
378
379 if (base + D->codesize != (char *)cp) /* Check for phase errors. */
380 return DASM_S_PHASE;
381 return DASM_S_OK;
382}
383#undef CK
384
385/* Get PC label offset. */
386int dasm_getpclabel(Dst_DECL, unsigned int pc)
387{
388 dasm_State *D = Dst_REF;
389 if (pc*sizeof(int) < D->pcsize) {
390 int pos = D->pclabels[pc];
391 if (pos < 0) return *DASM_POS2PTR(D, -pos);
392 if (pos > 0) return -1; /* Undefined. */
393 }
394 return -2; /* Unused or out of range. */
395}
396
397#ifdef DASM_CHECKS
398/* Optional sanity checker to call between isolated encoding steps. */
399int dasm_checkstep(Dst_DECL, int secmatch)
400{
401 dasm_State *D = Dst_REF;
402 if (D->status == DASM_S_OK) {
403 int i;
404 for (i = 1; i <= 9; i++) {
405 if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
406 D->lglabels[i] = 0;
407 }
408 }
409 if (D->status == DASM_S_OK && secmatch >= 0 &&
410 D->section != &D->sections[secmatch])
411 D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
412 return D->status;
413}
414#endif
415
diff --git a/libraries/luajit-2.0/dynasm/dasm_mips.lua b/libraries/luajit-2.0/dynasm/dasm_mips.lua
new file mode 100644
index 0000000..5cbae8b
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_mips.lua
@@ -0,0 +1,948 @@
1------------------------------------------------------------------------------
2-- DynASM MIPS module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- See dynasm.lua for full copyright notice.
6------------------------------------------------------------------------------
7
8-- Module information:
9local _info = {
10 arch = "mips",
11 description = "DynASM MIPS module",
12 version = "1.3.0",
13 vernum = 10300,
14 release = "2011-12-16",
15 author = "Mike Pall",
16 license = "MIT",
17}
18
19-- Exported glue functions for the arch-specific module.
20local _M = { _info = _info }
21
22-- Cache library functions.
23local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
24local assert, setmetatable = assert, setmetatable
25local _s = string
26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
27local match, gmatch = _s.match, _s.gmatch
28local concat, sort = table.concat, table.sort
29
30-- Inherited tables and callbacks.
31local g_opt, g_arch
32local wline, werror, wfatal, wwarn
33
34-- Action name list.
35-- CHECK: Keep this in sync with the C code!
36local action_names = {
37 "STOP", "SECTION", "ESC", "REL_EXT",
38 "ALIGN", "REL_LG", "LABEL_LG",
39 "REL_PC", "LABEL_PC", "IMM",
40}
41
42-- Maximum number of section buffer positions for dasm_put().
43-- CHECK: Keep this in sync with the C code!
44local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
45
46-- Action name -> action number.
47local map_action = {}
48for n,name in ipairs(action_names) do
49 map_action[name] = n-1
50end
51
52-- Action list buffer.
53local actlist = {}
54
55-- Argument list for next dasm_put(). Start with offset 0 into action list.
56local actargs = { 0 }
57
58-- Current number of section buffer positions for dasm_put().
59local secpos = 1
60
61------------------------------------------------------------------------------
62
63-- Return 8 digit hex number.
64local function tohex(x)
65 return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
66end
67
68-- Dump action names and numbers.
69local function dumpactions(out)
70 out:write("DynASM encoding engine action codes:\n")
71 for n,name in ipairs(action_names) do
72 local num = map_action[name]
73 out:write(format(" %-10s %02X %d\n", name, num, num))
74 end
75 out:write("\n")
76end
77
78-- Write action list buffer as a huge static C array.
79local function writeactions(out, name)
80 local nn = #actlist
81 if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
82 out:write("static const unsigned int ", name, "[", nn, "] = {\n")
83 for i = 1,nn-1 do
84 assert(out:write("0x", tohex(actlist[i]), ",\n"))
85 end
86 assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
87end
88
89------------------------------------------------------------------------------
90
91-- Add word to action list.
92local function wputxw(n)
93 assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
94 actlist[#actlist+1] = n
95end
96
97-- Add action to list with optional arg. Advance buffer pos, too.
98local function waction(action, val, a, num)
99 local w = assert(map_action[action], "bad action name `"..action.."'")
100 wputxw(0xff000000 + w * 0x10000 + (val or 0))
101 if a then actargs[#actargs+1] = a end
102 if a or num then secpos = secpos + (num or 1) end
103end
104
105-- Flush action list (intervening C code or buffer pos overflow).
106local function wflush(term)
107 if #actlist == actargs[1] then return end -- Nothing to flush.
108 if not term then waction("STOP") end -- Terminate action list.
109 wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
110 actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
111 secpos = 1 -- The actionlist offset occupies a buffer position, too.
112end
113
114-- Put escaped word.
115local function wputw(n)
116 if n >= 0xff000000 then waction("ESC") end
117 wputxw(n)
118end
119
120-- Reserve position for word.
121local function wpos()
122 local pos = #actlist+1
123 actlist[pos] = ""
124 return pos
125end
126
127-- Store word to reserved position.
128local function wputpos(pos, n)
129 assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
130 actlist[pos] = n
131end
132
133------------------------------------------------------------------------------
134
135-- Global label name -> global label number. With auto assignment on 1st use.
136local next_global = 20
137local map_global = setmetatable({}, { __index = function(t, name)
138 if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
139 local n = next_global
140 if n > 2047 then werror("too many global labels") end
141 next_global = n + 1
142 t[name] = n
143 return n
144end})
145
146-- Dump global labels.
147local function dumpglobals(out, lvl)
148 local t = {}
149 for name, n in pairs(map_global) do t[n] = name end
150 out:write("Global labels:\n")
151 for i=20,next_global-1 do
152 out:write(format(" %s\n", t[i]))
153 end
154 out:write("\n")
155end
156
157-- Write global label enum.
158local function writeglobals(out, prefix)
159 local t = {}
160 for name, n in pairs(map_global) do t[n] = name end
161 out:write("enum {\n")
162 for i=20,next_global-1 do
163 out:write(" ", prefix, t[i], ",\n")
164 end
165 out:write(" ", prefix, "_MAX\n};\n")
166end
167
168-- Write global label names.
169local function writeglobalnames(out, name)
170 local t = {}
171 for name, n in pairs(map_global) do t[n] = name end
172 out:write("static const char *const ", name, "[] = {\n")
173 for i=20,next_global-1 do
174 out:write(" \"", t[i], "\",\n")
175 end
176 out:write(" (const char *)0\n};\n")
177end
178
179------------------------------------------------------------------------------
180
181-- Extern label name -> extern label number. With auto assignment on 1st use.
182local next_extern = 0
183local map_extern_ = {}
184local map_extern = setmetatable({}, { __index = function(t, name)
185 -- No restrictions on the name for now.
186 local n = next_extern
187 if n > 2047 then werror("too many extern labels") end
188 next_extern = n + 1
189 t[name] = n
190 map_extern_[n] = name
191 return n
192end})
193
194-- Dump extern labels.
195local function dumpexterns(out, lvl)
196 out:write("Extern labels:\n")
197 for i=0,next_extern-1 do
198 out:write(format(" %s\n", map_extern_[i]))
199 end
200 out:write("\n")
201end
202
203-- Write extern label names.
204local function writeexternnames(out, name)
205 out:write("static const char *const ", name, "[] = {\n")
206 for i=0,next_extern-1 do
207 out:write(" \"", map_extern_[i], "\",\n")
208 end
209 out:write(" (const char *)0\n};\n")
210end
211
212------------------------------------------------------------------------------
213
214-- Arch-specific maps.
215local map_archdef = { sp="r29", ra="r31" } -- Ext. register name -> int. name.
216
217local map_type = {} -- Type name -> { ctype, reg }
218local ctypenum = 0 -- Type number (for Dt... macros).
219
220-- Reverse defines for registers.
221function _M.revdef(s)
222 if s == "r29" then return "sp"
223 elseif s == "r31" then return "ra" end
224 return s
225end
226
227------------------------------------------------------------------------------
228
229-- Template strings for MIPS instructions.
230local map_op = {
231 -- First-level opcodes.
232 j_1 = "08000000J",
233 jal_1 = "0c000000J",
234 b_1 = "10000000B",
235 beqz_2 = "10000000SB",
236 beq_3 = "10000000STB",
237 bnez_2 = "14000000SB",
238 bne_3 = "14000000STB",
239 blez_2 = "18000000SB",
240 bgtz_2 = "1c000000SB",
241 addi_3 = "20000000TSI",
242 li_2 = "24000000TI",
243 addiu_3 = "24000000TSI",
244 slti_3 = "28000000TSI",
245 sltiu_3 = "2c000000TSI",
246 andi_3 = "30000000TSU",
247 lu_2 = "34000000TU",
248 ori_3 = "34000000TSU",
249 xori_3 = "38000000TSU",
250 lui_2 = "3c000000TU",
251 beqzl_2 = "50000000SB",
252 beql_3 = "50000000STB",
253 bnezl_2 = "54000000SB",
254 bnel_3 = "54000000STB",
255 blezl_2 = "58000000SB",
256 bgtzl_2 = "5c000000SB",
257 lb_2 = "80000000TO",
258 lh_2 = "84000000TO",
259 lwl_2 = "88000000TO",
260 lw_2 = "8c000000TO",
261 lbu_2 = "90000000TO",
262 lhu_2 = "94000000TO",
263 lwr_2 = "98000000TO",
264 sb_2 = "a0000000TO",
265 sh_2 = "a4000000TO",
266 swl_2 = "a8000000TO",
267 sw_2 = "ac000000TO",
268 swr_2 = "b8000000TO",
269 cache_2 = "bc000000NO",
270 ll_2 = "c0000000TO",
271 lwc1_2 = "c4000000HO",
272 pref_2 = "cc000000NO",
273 ldc1_2 = "d4000000HO",
274 sc_2 = "e0000000TO",
275 swc1_2 = "e4000000HO",
276 sdc1_2 = "f4000000HO",
277
278 -- Opcode SPECIAL.
279 nop_0 = "00000000",
280 sll_3 = "00000000DTA",
281 movf_3 = "00000001DSC",
282 movt_3 = "00010001DSC",
283 srl_3 = "00000002DTA",
284 rotr_3 = "00200002DTA",
285 sra_3 = "00000003DTA",
286 sllv_3 = "00000004DTS",
287 srlv_3 = "00000006DTS",
288 rotrv_3 = "00000046DTS",
289 srav_3 = "00000007DTS",
290 jr_1 = "00000008S",
291 jalr_1 = "0000f809S",
292 jalr_2 = "00000009DS",
293 movz_3 = "0000000aDST",
294 movn_3 = "0000000bDST",
295 syscall_0 = "0000000c",
296 syscall_1 = "0000000cY",
297 break_0 = "0000000d",
298 break_1 = "0000000dY",
299 sync_0 = "0000000f",
300 mfhi_1 = "00000010D",
301 mthi_1 = "00000011S",
302 mflo_1 = "00000012D",
303 mtlo_1 = "00000013S",
304 mult_2 = "00000018ST",
305 multu_2 = "00000019ST",
306 div_2 = "0000001aST",
307 divu_2 = "0000001bST",
308 add_3 = "00000020DST",
309 move_2 = "00000021DS",
310 addu_3 = "00000021DST",
311 sub_3 = "00000022DST",
312 subu_3 = "00000023DST",
313 and_3 = "00000024DST",
314 or_3 = "00000025DST",
315 xor_3 = "00000026DST",
316 nor_3 = "00000027DST",
317 slt_3 = "0000002aDST",
318 sltu_3 = "0000002bDST",
319 tge_2 = "00000030ST",
320 tge_3 = "00000030STZ",
321 tgeu_2 = "00000031ST",
322 tgeu_3 = "00000031STZ",
323 tlt_2 = "00000032ST",
324 tlt_3 = "00000032STZ",
325 tltu_2 = "00000033ST",
326 tltu_3 = "00000033STZ",
327 teq_2 = "00000034ST",
328 teq_3 = "00000034STZ",
329 tne_2 = "00000036ST",
330 tne_3 = "00000036STZ",
331
332 -- Opcode REGIMM.
333 bltz_2 = "04000000SB",
334 bgez_2 = "04010000SB",
335 bltzl_2 = "04020000SB",
336 bgezl_2 = "04030000SB",
337 tgei_2 = "04080000SI",
338 tgeiu_2 = "04090000SI",
339 tlti_2 = "040a0000SI",
340 tltiu_2 = "040b0000SI",
341 teqi_2 = "040c0000SI",
342 tnei_2 = "040e0000SI",
343 bltzal_2 = "04100000SB",
344 bgezal_2 = "04110000SB",
345 bltzall_2 = "04120000SB",
346 bgezall_2 = "04130000SB",
347 synci_1 = "041f0000O",
348
349 -- Opcode SPECIAL2.
350 madd_2 = "70000000ST",
351 maddu_2 = "70000001ST",
352 mul_3 = "70000002DST",
353 msub_2 = "70000004ST",
354 msubu_2 = "70000005ST",
355 clz_2 = "70000020DS=",
356 clo_2 = "70000021DS=",
357 sdbbp_0 = "7000003f",
358 sdbbp_1 = "7000003fY",
359
360 -- Opcode SPECIAL3.
361 ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1
362 ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1
363 wsbh_2 = "7c0000a0DT",
364 seb_2 = "7c000420DT",
365 seh_2 = "7c000620DT",
366 rdhwr_2 = "7c00003bTD",
367
368 -- Opcode COP0.
369 mfc0_2 = "40000000TD",
370 mfc0_3 = "40000000TDW",
371 mtc0_2 = "40800000TD",
372 mtc0_3 = "40800000TDW",
373 rdpgpr_2 = "41400000DT",
374 di_0 = "41606000",
375 di_1 = "41606000T",
376 ei_0 = "41606020",
377 ei_1 = "41606020T",
378 wrpgpr_2 = "41c00000DT",
379 tlbr_0 = "42000001",
380 tlbwi_0 = "42000002",
381 tlbwr_0 = "42000006",
382 tlbp_0 = "42000008",
383 eret_0 = "42000018",
384 deret_0 = "4200001f",
385 wait_0 = "42000020",
386
387 -- Opcode COP1.
388 mfc1_2 = "44000000TG",
389 cfc1_2 = "44400000TG",
390 mfhc1_2 = "44600000TG",
391 mtc1_2 = "44800000TG",
392 ctc1_2 = "44c00000TG",
393 mthc1_2 = "44e00000TG",
394
395 bc1f_1 = "45000000B",
396 bc1f_2 = "45000000CB",
397 bc1t_1 = "45010000B",
398 bc1t_2 = "45010000CB",
399 bc1fl_1 = "45020000B",
400 bc1fl_2 = "45020000CB",
401 bc1tl_1 = "45030000B",
402 bc1tl_2 = "45030000CB",
403
404 ["add.s_3"] = "46000000FGH",
405 ["sub.s_3"] = "46000001FGH",
406 ["mul.s_3"] = "46000002FGH",
407 ["div.s_3"] = "46000003FGH",
408 ["sqrt.s_2"] = "46000004FG",
409 ["abs.s_2"] = "46000005FG",
410 ["mov.s_2"] = "46000006FG",
411 ["neg.s_2"] = "46000007FG",
412 ["round.l.s_2"] = "46000008FG",
413 ["trunc.l.s_2"] = "46000009FG",
414 ["ceil.l.s_2"] = "4600000aFG",
415 ["floor.l.s_2"] = "4600000bFG",
416 ["round.w.s_2"] = "4600000cFG",
417 ["trunc.w.s_2"] = "4600000dFG",
418 ["ceil.w.s_2"] = "4600000eFG",
419 ["floor.w.s_2"] = "4600000fFG",
420 ["movf.s_2"] = "46000011FG",
421 ["movf.s_3"] = "46000011FGC",
422 ["movt.s_2"] = "46010011FG",
423 ["movt.s_3"] = "46010011FGC",
424 ["movz.s_3"] = "46000012FGT",
425 ["movn.s_3"] = "46000013FGT",
426 ["recip.s_2"] = "46000015FG",
427 ["rsqrt.s_2"] = "46000016FG",
428 ["cvt.d.s_2"] = "46000021FG",
429 ["cvt.w.s_2"] = "46000024FG",
430 ["cvt.l.s_2"] = "46000025FG",
431 ["cvt.ps.s_3"] = "46000026FGH",
432 ["c.f.s_2"] = "46000030GH",
433 ["c.f.s_3"] = "46000030VGH",
434 ["c.un.s_2"] = "46000031GH",
435 ["c.un.s_3"] = "46000031VGH",
436 ["c.eq.s_2"] = "46000032GH",
437 ["c.eq.s_3"] = "46000032VGH",
438 ["c.ueq.s_2"] = "46000033GH",
439 ["c.ueq.s_3"] = "46000033VGH",
440 ["c.olt.s_2"] = "46000034GH",
441 ["c.olt.s_3"] = "46000034VGH",
442 ["c.ult.s_2"] = "46000035GH",
443 ["c.ult.s_3"] = "46000035VGH",
444 ["c.ole.s_2"] = "46000036GH",
445 ["c.ole.s_3"] = "46000036VGH",
446 ["c.ule.s_2"] = "46000037GH",
447 ["c.ule.s_3"] = "46000037VGH",
448 ["c.sf.s_2"] = "46000038GH",
449 ["c.sf.s_3"] = "46000038VGH",
450 ["c.ngle.s_2"] = "46000039GH",
451 ["c.ngle.s_3"] = "46000039VGH",
452 ["c.seq.s_2"] = "4600003aGH",
453 ["c.seq.s_3"] = "4600003aVGH",
454 ["c.ngl.s_2"] = "4600003bGH",
455 ["c.ngl.s_3"] = "4600003bVGH",
456 ["c.lt.s_2"] = "4600003cGH",
457 ["c.lt.s_3"] = "4600003cVGH",
458 ["c.nge.s_2"] = "4600003dGH",
459 ["c.nge.s_3"] = "4600003dVGH",
460 ["c.le.s_2"] = "4600003eGH",
461 ["c.le.s_3"] = "4600003eVGH",
462 ["c.ngt.s_2"] = "4600003fGH",
463 ["c.ngt.s_3"] = "4600003fVGH",
464
465 ["add.d_3"] = "46200000FGH",
466 ["sub.d_3"] = "46200001FGH",
467 ["mul.d_3"] = "46200002FGH",
468 ["div.d_3"] = "46200003FGH",
469 ["sqrt.d_2"] = "46200004FG",
470 ["abs.d_2"] = "46200005FG",
471 ["mov.d_2"] = "46200006FG",
472 ["neg.d_2"] = "46200007FG",
473 ["round.l.d_2"] = "46200008FG",
474 ["trunc.l.d_2"] = "46200009FG",
475 ["ceil.l.d_2"] = "4620000aFG",
476 ["floor.l.d_2"] = "4620000bFG",
477 ["round.w.d_2"] = "4620000cFG",
478 ["trunc.w.d_2"] = "4620000dFG",
479 ["ceil.w.d_2"] = "4620000eFG",
480 ["floor.w.d_2"] = "4620000fFG",
481 ["movf.d_2"] = "46200011FG",
482 ["movf.d_3"] = "46200011FGC",
483 ["movt.d_2"] = "46210011FG",
484 ["movt.d_3"] = "46210011FGC",
485 ["movz.d_3"] = "46200012FGT",
486 ["movn.d_3"] = "46200013FGT",
487 ["recip.d_2"] = "46200015FG",
488 ["rsqrt.d_2"] = "46200016FG",
489 ["cvt.s.d_2"] = "46200020FG",
490 ["cvt.w.d_2"] = "46200024FG",
491 ["cvt.l.d_2"] = "46200025FG",
492 ["c.f.d_2"] = "46200030GH",
493 ["c.f.d_3"] = "46200030VGH",
494 ["c.un.d_2"] = "46200031GH",
495 ["c.un.d_3"] = "46200031VGH",
496 ["c.eq.d_2"] = "46200032GH",
497 ["c.eq.d_3"] = "46200032VGH",
498 ["c.ueq.d_2"] = "46200033GH",
499 ["c.ueq.d_3"] = "46200033VGH",
500 ["c.olt.d_2"] = "46200034GH",
501 ["c.olt.d_3"] = "46200034VGH",
502 ["c.ult.d_2"] = "46200035GH",
503 ["c.ult.d_3"] = "46200035VGH",
504 ["c.ole.d_2"] = "46200036GH",
505 ["c.ole.d_3"] = "46200036VGH",
506 ["c.ule.d_2"] = "46200037GH",
507 ["c.ule.d_3"] = "46200037VGH",
508 ["c.sf.d_2"] = "46200038GH",
509 ["c.sf.d_3"] = "46200038VGH",
510 ["c.ngle.d_2"] = "46200039GH",
511 ["c.ngle.d_3"] = "46200039VGH",
512 ["c.seq.d_2"] = "4620003aGH",
513 ["c.seq.d_3"] = "4620003aVGH",
514 ["c.ngl.d_2"] = "4620003bGH",
515 ["c.ngl.d_3"] = "4620003bVGH",
516 ["c.lt.d_2"] = "4620003cGH",
517 ["c.lt.d_3"] = "4620003cVGH",
518 ["c.nge.d_2"] = "4620003dGH",
519 ["c.nge.d_3"] = "4620003dVGH",
520 ["c.le.d_2"] = "4620003eGH",
521 ["c.le.d_3"] = "4620003eVGH",
522 ["c.ngt.d_2"] = "4620003fGH",
523 ["c.ngt.d_3"] = "4620003fVGH",
524
525 ["add.ps_3"] = "46c00000FGH",
526 ["sub.ps_3"] = "46c00001FGH",
527 ["mul.ps_3"] = "46c00002FGH",
528 ["abs.ps_2"] = "46c00005FG",
529 ["mov.ps_2"] = "46c00006FG",
530 ["neg.ps_2"] = "46c00007FG",
531 ["movf.ps_2"] = "46c00011FG",
532 ["movf.ps_3"] = "46c00011FGC",
533 ["movt.ps_2"] = "46c10011FG",
534 ["movt.ps_3"] = "46c10011FGC",
535 ["movz.ps_3"] = "46c00012FGT",
536 ["movn.ps_3"] = "46c00013FGT",
537 ["cvt.s.pu_2"] = "46c00020FG",
538 ["cvt.s.pl_2"] = "46c00028FG",
539 ["pll.ps_3"] = "46c0002cFGH",
540 ["plu.ps_3"] = "46c0002dFGH",
541 ["pul.ps_3"] = "46c0002eFGH",
542 ["puu.ps_3"] = "46c0002fFGH",
543 ["c.f.ps_2"] = "46c00030GH",
544 ["c.f.ps_3"] = "46c00030VGH",
545 ["c.un.ps_2"] = "46c00031GH",
546 ["c.un.ps_3"] = "46c00031VGH",
547 ["c.eq.ps_2"] = "46c00032GH",
548 ["c.eq.ps_3"] = "46c00032VGH",
549 ["c.ueq.ps_2"] = "46c00033GH",
550 ["c.ueq.ps_3"] = "46c00033VGH",
551 ["c.olt.ps_2"] = "46c00034GH",
552 ["c.olt.ps_3"] = "46c00034VGH",
553 ["c.ult.ps_2"] = "46c00035GH",
554 ["c.ult.ps_3"] = "46c00035VGH",
555 ["c.ole.ps_2"] = "46c00036GH",
556 ["c.ole.ps_3"] = "46c00036VGH",
557 ["c.ule.ps_2"] = "46c00037GH",
558 ["c.ule.ps_3"] = "46c00037VGH",
559 ["c.sf.ps_2"] = "46c00038GH",
560 ["c.sf.ps_3"] = "46c00038VGH",
561 ["c.ngle.ps_2"] = "46c00039GH",
562 ["c.ngle.ps_3"] = "46c00039VGH",
563 ["c.seq.ps_2"] = "46c0003aGH",
564 ["c.seq.ps_3"] = "46c0003aVGH",
565 ["c.ngl.ps_2"] = "46c0003bGH",
566 ["c.ngl.ps_3"] = "46c0003bVGH",
567 ["c.lt.ps_2"] = "46c0003cGH",
568 ["c.lt.ps_3"] = "46c0003cVGH",
569 ["c.nge.ps_2"] = "46c0003dGH",
570 ["c.nge.ps_3"] = "46c0003dVGH",
571 ["c.le.ps_2"] = "46c0003eGH",
572 ["c.le.ps_3"] = "46c0003eVGH",
573 ["c.ngt.ps_2"] = "46c0003fGH",
574 ["c.ngt.ps_3"] = "46c0003fVGH",
575
576 ["cvt.s.w_2"] = "46800020FG",
577 ["cvt.d.w_2"] = "46800021FG",
578
579 ["cvt.s.l_2"] = "46a00020FG",
580 ["cvt.d.l_2"] = "46a00021FG",
581
582 -- Opcode COP1X.
583 lwxc1_2 = "4c000000FX",
584 ldxc1_2 = "4c000001FX",
585 luxc1_2 = "4c000005FX",
586 swxc1_2 = "4c000008FX",
587 sdxc1_2 = "4c000009FX",
588 suxc1_2 = "4c00000dFX",
589 prefx_2 = "4c00000fMX",
590 ["alnv.ps_4"] = "4c00001eFGHS",
591 ["madd.s_4"] = "4c000020FRGH",
592 ["madd.d_4"] = "4c000021FRGH",
593 ["madd.ps_4"] = "4c000026FRGH",
594 ["msub.s_4"] = "4c000028FRGH",
595 ["msub.d_4"] = "4c000029FRGH",
596 ["msub.ps_4"] = "4c00002eFRGH",
597 ["nmadd.s_4"] = "4c000030FRGH",
598 ["nmadd.d_4"] = "4c000031FRGH",
599 ["nmadd.ps_4"] = "4c000036FRGH",
600 ["nmsub.s_4"] = "4c000038FRGH",
601 ["nmsub.d_4"] = "4c000039FRGH",
602 ["nmsub.ps_4"] = "4c00003eFRGH",
603}
604
605------------------------------------------------------------------------------
606
607local function parse_gpr(expr)
608 local tname, ovreg = match(expr, "^([%w_]+):(r[1-3]?[0-9])$")
609 local tp = map_type[tname or expr]
610 if tp then
611 local reg = ovreg or tp.reg
612 if not reg then
613 werror("type `"..(tname or expr).."' needs a register override")
614 end
615 expr = reg
616 end
617 local r = match(expr, "^r([1-3]?[0-9])$")
618 if r then
619 r = tonumber(r)
620 if r <= 31 then return r, tp end
621 end
622 werror("bad register name `"..expr.."'")
623end
624
625local function parse_fpr(expr)
626 local r = match(expr, "^f([1-3]?[0-9])$")
627 if r then
628 r = tonumber(r)
629 if r <= 31 then return r end
630 end
631 werror("bad register name `"..expr.."'")
632end
633
634local function parse_imm(imm, bits, shift, scale, signed)
635 local n = tonumber(imm)
636 if n then
637 if n % 2^scale == 0 then
638 n = n / 2^scale
639 if signed then
640 if n >= 0 then
641 if n < 2^(bits-1) then return n*2^shift end
642 else
643 if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end
644 end
645 else
646 if n >= 0 and n <= 2^bits-1 then return n*2^shift end
647 end
648 end
649 werror("out of range immediate `"..imm.."'")
650 elseif match(imm, "^[rf]([1-3]?[0-9])$") or
651 match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then
652 werror("expected immediate operand, got register")
653 else
654 waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
655 return 0
656 end
657end
658
659local function parse_disp(disp)
660 local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
661 if imm then
662 local r = parse_gpr(reg)
663 return r*2^21 + parse_imm(imm, 16, 0, 0, true)
664 end
665 local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
666 if reg and tailr ~= "" then
667 local r, tp = parse_gpr(reg)
668 if tp then
669 waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
670 return r*2^21
671 end
672 end
673 werror("bad displacement `"..disp.."'")
674end
675
676local function parse_index(idx)
677 local rt, rs = match(idx, "^(.*)%(([%w_:]+)%)$")
678 if rt then
679 rt = parse_gpr(rt)
680 rs = parse_gpr(rs)
681 return rt*2^16 + rs*2^21
682 end
683 werror("bad index `"..idx.."'")
684end
685
686local function parse_label(label, def)
687 local prefix = sub(label, 1, 2)
688 -- =>label (pc label reference)
689 if prefix == "=>" then
690 return "PC", 0, sub(label, 3)
691 end
692 -- ->name (global label reference)
693 if prefix == "->" then
694 return "LG", map_global[sub(label, 3)]
695 end
696 if def then
697 -- [1-9] (local label definition)
698 if match(label, "^[1-9]$") then
699 return "LG", 10+tonumber(label)
700 end
701 else
702 -- [<>][1-9] (local label reference)
703 local dir, lnum = match(label, "^([<>])([1-9])$")
704 if dir then -- Fwd: 1-9, Bkwd: 11-19.
705 return "LG", lnum + (dir == ">" and 0 or 10)
706 end
707 -- extern label (extern label reference)
708 local extname = match(label, "^extern%s+(%S+)$")
709 if extname then
710 return "EXT", map_extern[extname]
711 end
712 end
713 werror("bad label `"..label.."'")
714end
715
716------------------------------------------------------------------------------
717
718-- Handle opcodes defined with template strings.
719map_op[".template__"] = function(params, template, nparams)
720 if not params then return sub(template, 9) end
721 local op = tonumber(sub(template, 1, 8), 16)
722 local n = 1
723
724 -- Limit number of section buffer positions used by a single dasm_put().
725 -- A single opcode needs a maximum of 2 positions (ins/ext).
726 if secpos+2 > maxsecpos then wflush() end
727 local pos = wpos()
728
729 -- Process each character.
730 for p in gmatch(sub(template, 9), ".") do
731 if p == "D" then
732 op = op + parse_gpr(params[n]) * 2^11; n = n + 1
733 elseif p == "T" then
734 op = op + parse_gpr(params[n]) * 2^16; n = n + 1
735 elseif p == "S" then
736 op = op + parse_gpr(params[n]) * 2^21; n = n + 1
737 elseif p == "F" then
738 op = op + parse_fpr(params[n]) * 2^6; n = n + 1
739 elseif p == "G" then
740 op = op + parse_fpr(params[n]) * 2^11; n = n + 1
741 elseif p == "H" then
742 op = op + parse_fpr(params[n]) * 2^16; n = n + 1
743 elseif p == "R" then
744 op = op + parse_fpr(params[n]) * 2^21; n = n + 1
745 elseif p == "I" then
746 op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1
747 elseif p == "U" then
748 op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1
749 elseif p == "O" then
750 op = op + parse_disp(params[n]); n = n + 1
751 elseif p == "X" then
752 op = op + parse_index(params[n]); n = n + 1
753 elseif p == "B" or p == "J" then
754 local mode, n, s = parse_label(params[n], false)
755 if p == "B" then n = n + 2048 end
756 waction("REL_"..mode, n, s, 1)
757 n = n + 1
758 elseif p == "A" then
759 op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1
760 elseif p == "M" then
761 op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1
762 elseif p == "N" then
763 op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1
764 elseif p == "C" then
765 op = op + parse_imm(params[n], 3, 18, 0, false); n = n + 1
766 elseif p == "V" then
767 op = op + parse_imm(params[n], 3, 8, 0, false); n = n + 1
768 elseif p == "W" then
769 op = op + parse_imm(params[n], 3, 0, 0, false); n = n + 1
770 elseif p == "Y" then
771 op = op + parse_imm(params[n], 20, 6, 0, false); n = n + 1
772 elseif p == "Z" then
773 op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1
774 elseif p == "=" then
775 local d = ((op - op % 2^11) / 2^11) % 32
776 op = op + d * 2^16 -- Copy D to T for clz, clo.
777 else
778 assert(false)
779 end
780 end
781 wputpos(pos, op)
782end
783
784------------------------------------------------------------------------------
785
786-- Pseudo-opcode to mark the position where the action list is to be emitted.
787map_op[".actionlist_1"] = function(params)
788 if not params then return "cvar" end
789 local name = params[1] -- No syntax check. You get to keep the pieces.
790 wline(function(out) writeactions(out, name) end)
791end
792
793-- Pseudo-opcode to mark the position where the global enum is to be emitted.
794map_op[".globals_1"] = function(params)
795 if not params then return "prefix" end
796 local prefix = params[1] -- No syntax check. You get to keep the pieces.
797 wline(function(out) writeglobals(out, prefix) end)
798end
799
800-- Pseudo-opcode to mark the position where the global names are to be emitted.
801map_op[".globalnames_1"] = function(params)
802 if not params then return "cvar" end
803 local name = params[1] -- No syntax check. You get to keep the pieces.
804 wline(function(out) writeglobalnames(out, name) end)
805end
806
807-- Pseudo-opcode to mark the position where the extern names are to be emitted.
808map_op[".externnames_1"] = function(params)
809 if not params then return "cvar" end
810 local name = params[1] -- No syntax check. You get to keep the pieces.
811 wline(function(out) writeexternnames(out, name) end)
812end
813
814------------------------------------------------------------------------------
815
816-- Label pseudo-opcode (converted from trailing colon form).
817map_op[".label_1"] = function(params)
818 if not params then return "[1-9] | ->global | =>pcexpr" end
819 if secpos+1 > maxsecpos then wflush() end
820 local mode, n, s = parse_label(params[1], true)
821 if mode == "EXT" then werror("bad label definition") end
822 waction("LABEL_"..mode, n, s, 1)
823end
824
825------------------------------------------------------------------------------
826
827-- Pseudo-opcodes for data storage.
828map_op[".long_*"] = function(params)
829 if not params then return "imm..." end
830 for _,p in ipairs(params) do
831 local n = tonumber(p)
832 if not n then werror("bad immediate `"..p.."'") end
833 if n < 0 then n = n + 2^32 end
834 wputw(n)
835 if secpos+2 > maxsecpos then wflush() end
836 end
837end
838
839-- Alignment pseudo-opcode.
840map_op[".align_1"] = function(params)
841 if not params then return "numpow2" end
842 if secpos+1 > maxsecpos then wflush() end
843 local align = tonumber(params[1])
844 if align then
845 local x = align
846 -- Must be a power of 2 in the range (2 ... 256).
847 for i=1,8 do
848 x = x / 2
849 if x == 1 then
850 waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
851 return
852 end
853 end
854 end
855 werror("bad alignment")
856end
857
858------------------------------------------------------------------------------
859
860-- Pseudo-opcode for (primitive) type definitions (map to C types).
861map_op[".type_3"] = function(params, nparams)
862 if not params then
863 return nparams == 2 and "name, ctype" or "name, ctype, reg"
864 end
865 local name, ctype, reg = params[1], params[2], params[3]
866 if not match(name, "^[%a_][%w_]*$") then
867 werror("bad type name `"..name.."'")
868 end
869 local tp = map_type[name]
870 if tp then
871 werror("duplicate type `"..name.."'")
872 end
873 -- Add #type to defines. A bit unclean to put it in map_archdef.
874 map_archdef["#"..name] = "sizeof("..ctype..")"
875 -- Add new type and emit shortcut define.
876 local num = ctypenum + 1
877 map_type[name] = {
878 ctype = ctype,
879 ctypefmt = format("Dt%X(%%s)", num),
880 reg = reg,
881 }
882 wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
883 ctypenum = num
884end
885map_op[".type_2"] = map_op[".type_3"]
886
887-- Dump type definitions.
888local function dumptypes(out, lvl)
889 local t = {}
890 for name in pairs(map_type) do t[#t+1] = name end
891 sort(t)
892 out:write("Type definitions:\n")
893 for _,name in ipairs(t) do
894 local tp = map_type[name]
895 local reg = tp.reg or ""
896 out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
897 end
898 out:write("\n")
899end
900
901------------------------------------------------------------------------------
902
903-- Set the current section.
904function _M.section(num)
905 waction("SECTION", num)
906 wflush(true) -- SECTION is a terminal action.
907end
908
909------------------------------------------------------------------------------
910
911-- Dump architecture description.
912function _M.dumparch(out)
913 out:write(format("DynASM %s version %s, released %s\n\n",
914 _info.arch, _info.version, _info.release))
915 dumpactions(out)
916end
917
918-- Dump all user defined elements.
919function _M.dumpdef(out, lvl)
920 dumptypes(out, lvl)
921 dumpglobals(out, lvl)
922 dumpexterns(out, lvl)
923end
924
925------------------------------------------------------------------------------
926
927-- Pass callbacks from/to the DynASM core.
928function _M.passcb(wl, we, wf, ww)
929 wline, werror, wfatal, wwarn = wl, we, wf, ww
930 return wflush
931end
932
933-- Setup the arch-specific module.
934function _M.setup(arch, opt)
935 g_arch, g_opt = arch, opt
936end
937
938-- Merge the core maps and the arch-specific maps.
939function _M.mergemaps(map_coreop, map_def)
940 setmetatable(map_op, { __index = map_coreop })
941 setmetatable(map_def, { __index = map_archdef })
942 return map_op, map_def
943end
944
945return _M
946
947------------------------------------------------------------------------------
948
diff --git a/libraries/luajit-2.0/dynasm/dasm_ppc.h b/libraries/luajit-2.0/dynasm/dasm_ppc.h
new file mode 100644
index 0000000..645e060
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_ppc.h
@@ -0,0 +1,411 @@
1/*
2** DynASM PPC encoding engine.
3** Copyright (C) 2005-2011 Mike Pall. All rights reserved.
4** Released under the MIT license. See dynasm.lua for full copyright notice.
5*/
6
7#include <stddef.h>
8#include <stdarg.h>
9#include <string.h>
10#include <stdlib.h>
11
12#define DASM_ARCH "ppc"
13
14#ifndef DASM_EXTERN
15#define DASM_EXTERN(a,b,c,d) 0
16#endif
17
18/* Action definitions. */
19enum {
20 DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
21 /* The following actions need a buffer position. */
22 DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
23 /* The following actions also have an argument. */
24 DASM_REL_PC, DASM_LABEL_PC, DASM_IMM,
25 DASM__MAX
26};
27
28/* Maximum number of section buffer positions for a single dasm_put() call. */
29#define DASM_MAXSECPOS 25
30
31/* DynASM encoder status codes. Action list offset or number are or'ed in. */
32#define DASM_S_OK 0x00000000
33#define DASM_S_NOMEM 0x01000000
34#define DASM_S_PHASE 0x02000000
35#define DASM_S_MATCH_SEC 0x03000000
36#define DASM_S_RANGE_I 0x11000000
37#define DASM_S_RANGE_SEC 0x12000000
38#define DASM_S_RANGE_LG 0x13000000
39#define DASM_S_RANGE_PC 0x14000000
40#define DASM_S_RANGE_REL 0x15000000
41#define DASM_S_UNDEF_LG 0x21000000
42#define DASM_S_UNDEF_PC 0x22000000
43
44/* Macros to convert positions (8 bit section + 24 bit index). */
45#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
46#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
47#define DASM_SEC2POS(sec) ((sec)<<24)
48#define DASM_POS2SEC(pos) ((pos)>>24)
49#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
50
51/* Action list type. */
52typedef const unsigned int *dasm_ActList;
53
54/* Per-section structure. */
55typedef struct dasm_Section {
56 int *rbuf; /* Biased buffer pointer (negative section bias). */
57 int *buf; /* True buffer pointer. */
58 size_t bsize; /* Buffer size in bytes. */
59 int pos; /* Biased buffer position. */
60 int epos; /* End of biased buffer position - max single put. */
61 int ofs; /* Byte offset into section. */
62} dasm_Section;
63
64/* Core structure holding the DynASM encoding state. */
65struct dasm_State {
66 size_t psize; /* Allocated size of this structure. */
67 dasm_ActList actionlist; /* Current actionlist pointer. */
68 int *lglabels; /* Local/global chain/pos ptrs. */
69 size_t lgsize;
70 int *pclabels; /* PC label chains/pos ptrs. */
71 size_t pcsize;
72 void **globals; /* Array of globals (bias -10). */
73 dasm_Section *section; /* Pointer to active section. */
74 size_t codesize; /* Total size of all code sections. */
75 int maxsection; /* 0 <= sectionidx < maxsection. */
76 int status; /* Status code. */
77 dasm_Section sections[1]; /* All sections. Alloc-extended. */
78};
79
80/* The size of the core structure depends on the max. number of sections. */
81#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
82
83
84/* Initialize DynASM state. */
85void dasm_init(Dst_DECL, int maxsection)
86{
87 dasm_State *D;
88 size_t psz = 0;
89 int i;
90 Dst_REF = NULL;
91 DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
92 D = Dst_REF;
93 D->psize = psz;
94 D->lglabels = NULL;
95 D->lgsize = 0;
96 D->pclabels = NULL;
97 D->pcsize = 0;
98 D->globals = NULL;
99 D->maxsection = maxsection;
100 for (i = 0; i < maxsection; i++) {
101 D->sections[i].buf = NULL; /* Need this for pass3. */
102 D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
103 D->sections[i].bsize = 0;
104 D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
105 }
106}
107
108/* Free DynASM state. */
109void dasm_free(Dst_DECL)
110{
111 dasm_State *D = Dst_REF;
112 int i;
113 for (i = 0; i < D->maxsection; i++)
114 if (D->sections[i].buf)
115 DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
116 if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
117 if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
118 DASM_M_FREE(Dst, D, D->psize);
119}
120
121/* Setup global label array. Must be called before dasm_setup(). */
122void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
123{
124 dasm_State *D = Dst_REF;
125 D->globals = gl - 10; /* Negative bias to compensate for locals. */
126 DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
127}
128
129/* Grow PC label array. Can be called after dasm_setup(), too. */
130void dasm_growpc(Dst_DECL, unsigned int maxpc)
131{
132 dasm_State *D = Dst_REF;
133 size_t osz = D->pcsize;
134 DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
135 memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
136}
137
138/* Setup encoder. */
139void dasm_setup(Dst_DECL, const void *actionlist)
140{
141 dasm_State *D = Dst_REF;
142 int i;
143 D->actionlist = (dasm_ActList)actionlist;
144 D->status = DASM_S_OK;
145 D->section = &D->sections[0];
146 memset((void *)D->lglabels, 0, D->lgsize);
147 if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
148 for (i = 0; i < D->maxsection; i++) {
149 D->sections[i].pos = DASM_SEC2POS(i);
150 D->sections[i].ofs = 0;
151 }
152}
153
154
155#ifdef DASM_CHECKS
156#define CK(x, st) \
157 do { if (!(x)) { \
158 D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
159#define CKPL(kind, st) \
160 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
161 D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
162#else
163#define CK(x, st) ((void)0)
164#define CKPL(kind, st) ((void)0)
165#endif
166
167/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
168void dasm_put(Dst_DECL, int start, ...)
169{
170 va_list ap;
171 dasm_State *D = Dst_REF;
172 dasm_ActList p = D->actionlist + start;
173 dasm_Section *sec = D->section;
174 int pos = sec->pos, ofs = sec->ofs;
175 int *b;
176
177 if (pos >= sec->epos) {
178 DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
179 sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
180 sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
181 sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
182 }
183
184 b = sec->rbuf;
185 b[pos++] = start;
186
187 va_start(ap, start);
188 while (1) {
189 unsigned int ins = *p++;
190 unsigned int action = (ins >> 16);
191 if (action >= DASM__MAX) {
192 ofs += 4;
193 } else {
194 int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
195 switch (action) {
196 case DASM_STOP: goto stop;
197 case DASM_SECTION:
198 n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
199 D->section = &D->sections[n]; goto stop;
200 case DASM_ESC: p++; ofs += 4; break;
201 case DASM_REL_EXT: break;
202 case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
203 case DASM_REL_LG:
204 n = (ins & 2047) - 10; pl = D->lglabels + n;
205 if (n >= 0) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
206 pl += 10; n = *pl;
207 if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
208 goto linkrel;
209 case DASM_REL_PC:
210 pl = D->pclabels + n; CKPL(pc, PC);
211 putrel:
212 n = *pl;
213 if (n < 0) { /* Label exists. Get label pos and store it. */
214 b[pos] = -n;
215 } else {
216 linkrel:
217 b[pos] = n; /* Else link to rel chain, anchored at label. */
218 *pl = pos;
219 }
220 pos++;
221 break;
222 case DASM_LABEL_LG:
223 pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
224 case DASM_LABEL_PC:
225 pl = D->pclabels + n; CKPL(pc, PC);
226 putlabel:
227 n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
228 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
229 }
230 *pl = -pos; /* Label exists now. */
231 b[pos++] = ofs; /* Store pass1 offset estimate. */
232 break;
233 case DASM_IMM:
234#ifdef DASM_CHECKS
235 CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
236#endif
237 n >>= ((ins>>10)&31);
238#ifdef DASM_CHECKS
239 if (ins & 0x8000)
240 CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
241 else
242 CK((n>>((ins>>5)&31)) == 0, RANGE_I);
243#endif
244 b[pos++] = n;
245 break;
246 }
247 }
248 }
249stop:
250 va_end(ap);
251 sec->pos = pos;
252 sec->ofs = ofs;
253}
254#undef CK
255
256/* Pass 2: Link sections, shrink aligns, fix label offsets. */
257int dasm_link(Dst_DECL, size_t *szp)
258{
259 dasm_State *D = Dst_REF;
260 int secnum;
261 int ofs = 0;
262
263#ifdef DASM_CHECKS
264 *szp = 0;
265 if (D->status != DASM_S_OK) return D->status;
266 {
267 int pc;
268 for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
269 if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
270 }
271#endif
272
273 { /* Handle globals not defined in this translation unit. */
274 int idx;
275 for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
276 int n = D->lglabels[idx];
277 /* Undefined label: Collapse rel chain and replace with marker (< 0). */
278 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
279 }
280 }
281
282 /* Combine all code sections. No support for data sections (yet). */
283 for (secnum = 0; secnum < D->maxsection; secnum++) {
284 dasm_Section *sec = D->sections + secnum;
285 int *b = sec->rbuf;
286 int pos = DASM_SEC2POS(secnum);
287 int lastpos = sec->pos;
288
289 while (pos != lastpos) {
290 dasm_ActList p = D->actionlist + b[pos++];
291 while (1) {
292 unsigned int ins = *p++;
293 unsigned int action = (ins >> 16);
294 switch (action) {
295 case DASM_STOP: case DASM_SECTION: goto stop;
296 case DASM_ESC: p++; break;
297 case DASM_REL_EXT: break;
298 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
299 case DASM_REL_LG: case DASM_REL_PC: pos++; break;
300 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
301 case DASM_IMM: pos++; break;
302 }
303 }
304 stop: (void)0;
305 }
306 ofs += sec->ofs; /* Next section starts right after current section. */
307 }
308
309 D->codesize = ofs; /* Total size of all code sections */
310 *szp = ofs;
311 return DASM_S_OK;
312}
313
314#ifdef DASM_CHECKS
315#define CK(x, st) \
316 do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
317#else
318#define CK(x, st) ((void)0)
319#endif
320
321/* Pass 3: Encode sections. */
322int dasm_encode(Dst_DECL, void *buffer)
323{
324 dasm_State *D = Dst_REF;
325 char *base = (char *)buffer;
326 unsigned int *cp = (unsigned int *)buffer;
327 int secnum;
328
329 /* Encode all code sections. No support for data sections (yet). */
330 for (secnum = 0; secnum < D->maxsection; secnum++) {
331 dasm_Section *sec = D->sections + secnum;
332 int *b = sec->buf;
333 int *endb = sec->rbuf + sec->pos;
334
335 while (b != endb) {
336 dasm_ActList p = D->actionlist + *b++;
337 while (1) {
338 unsigned int ins = *p++;
339 unsigned int action = (ins >> 16);
340 int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
341 switch (action) {
342 case DASM_STOP: case DASM_SECTION: goto stop;
343 case DASM_ESC: *cp++ = *p++; break;
344 case DASM_REL_EXT:
345 n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1) - 4;
346 goto patchrel;
347 case DASM_ALIGN:
348 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
349 break;
350 case DASM_REL_LG:
351 CK(n >= 0, UNDEF_LG);
352 case DASM_REL_PC:
353 CK(n >= 0, UNDEF_PC);
354 n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base);
355 patchrel:
356 CK((n & 3) == 0 &&
357 (((n+4) + ((ins & 2048) ? 0x00008000 : 0x02000000)) >>
358 ((ins & 2048) ? 16 : 26)) == 0, RANGE_REL);
359 cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc));
360 break;
361 case DASM_LABEL_LG:
362 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
363 break;
364 case DASM_LABEL_PC: break;
365 case DASM_IMM:
366 cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
367 break;
368 default: *cp++ = ins; break;
369 }
370 }
371 stop: (void)0;
372 }
373 }
374
375 if (base + D->codesize != (char *)cp) /* Check for phase errors. */
376 return DASM_S_PHASE;
377 return DASM_S_OK;
378}
379#undef CK
380
381/* Get PC label offset. */
382int dasm_getpclabel(Dst_DECL, unsigned int pc)
383{
384 dasm_State *D = Dst_REF;
385 if (pc*sizeof(int) < D->pcsize) {
386 int pos = D->pclabels[pc];
387 if (pos < 0) return *DASM_POS2PTR(D, -pos);
388 if (pos > 0) return -1; /* Undefined. */
389 }
390 return -2; /* Unused or out of range. */
391}
392
393#ifdef DASM_CHECKS
394/* Optional sanity checker to call between isolated encoding steps. */
395int dasm_checkstep(Dst_DECL, int secmatch)
396{
397 dasm_State *D = Dst_REF;
398 if (D->status == DASM_S_OK) {
399 int i;
400 for (i = 1; i <= 9; i++) {
401 if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
402 D->lglabels[i] = 0;
403 }
404 }
405 if (D->status == DASM_S_OK && secmatch >= 0 &&
406 D->section != &D->sections[secmatch])
407 D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
408 return D->status;
409}
410#endif
411
diff --git a/libraries/luajit-2.0/dynasm/dasm_ppc.lua b/libraries/luajit-2.0/dynasm/dasm_ppc.lua
new file mode 100644
index 0000000..b2bee2c
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_ppc.lua
@@ -0,0 +1,1230 @@
1------------------------------------------------------------------------------
2-- DynASM PPC module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- See dynasm.lua for full copyright notice.
6------------------------------------------------------------------------------
7
8-- Module information:
9local _info = {
10 arch = "ppc",
11 description = "DynASM PPC module",
12 version = "1.3.0",
13 vernum = 10300,
14 release = "2011-05-05",
15 author = "Mike Pall",
16 license = "MIT",
17}
18
19-- Exported glue functions for the arch-specific module.
20local _M = { _info = _info }
21
22-- Cache library functions.
23local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
24local assert, setmetatable = assert, setmetatable
25local _s = string
26local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
27local match, gmatch = _s.match, _s.gmatch
28local concat, sort = table.concat, table.sort
29
30-- Inherited tables and callbacks.
31local g_opt, g_arch
32local wline, werror, wfatal, wwarn
33
34-- Action name list.
35-- CHECK: Keep this in sync with the C code!
36local action_names = {
37 "STOP", "SECTION", "ESC", "REL_EXT",
38 "ALIGN", "REL_LG", "LABEL_LG",
39 "REL_PC", "LABEL_PC", "IMM",
40}
41
42-- Maximum number of section buffer positions for dasm_put().
43-- CHECK: Keep this in sync with the C code!
44local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
45
46-- Action name -> action number.
47local map_action = {}
48for n,name in ipairs(action_names) do
49 map_action[name] = n-1
50end
51
52-- Action list buffer.
53local actlist = {}
54
55-- Argument list for next dasm_put(). Start with offset 0 into action list.
56local actargs = { 0 }
57
58-- Current number of section buffer positions for dasm_put().
59local secpos = 1
60
61------------------------------------------------------------------------------
62
63-- Return 8 digit hex number.
64local function tohex(x)
65 return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
66end
67
68-- Dump action names and numbers.
69local function dumpactions(out)
70 out:write("DynASM encoding engine action codes:\n")
71 for n,name in ipairs(action_names) do
72 local num = map_action[name]
73 out:write(format(" %-10s %02X %d\n", name, num, num))
74 end
75 out:write("\n")
76end
77
78-- Write action list buffer as a huge static C array.
79local function writeactions(out, name)
80 local nn = #actlist
81 if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
82 out:write("static const unsigned int ", name, "[", nn, "] = {\n")
83 for i = 1,nn-1 do
84 assert(out:write("0x", tohex(actlist[i]), ",\n"))
85 end
86 assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
87end
88
89------------------------------------------------------------------------------
90
91-- Add word to action list.
92local function wputxw(n)
93 assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
94 actlist[#actlist+1] = n
95end
96
97-- Add action to list with optional arg. Advance buffer pos, too.
98local function waction(action, val, a, num)
99 local w = assert(map_action[action], "bad action name `"..action.."'")
100 wputxw(w * 0x10000 + (val or 0))
101 if a then actargs[#actargs+1] = a end
102 if a or num then secpos = secpos + (num or 1) end
103end
104
105-- Flush action list (intervening C code or buffer pos overflow).
106local function wflush(term)
107 if #actlist == actargs[1] then return end -- Nothing to flush.
108 if not term then waction("STOP") end -- Terminate action list.
109 wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
110 actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
111 secpos = 1 -- The actionlist offset occupies a buffer position, too.
112end
113
114-- Put escaped word.
115local function wputw(n)
116 if n <= 0xffffff then waction("ESC") end
117 wputxw(n)
118end
119
120-- Reserve position for word.
121local function wpos()
122 local pos = #actlist+1
123 actlist[pos] = ""
124 return pos
125end
126
127-- Store word to reserved position.
128local function wputpos(pos, n)
129 assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
130 actlist[pos] = n
131end
132
133------------------------------------------------------------------------------
134
135-- Global label name -> global label number. With auto assignment on 1st use.
136local next_global = 20
137local map_global = setmetatable({}, { __index = function(t, name)
138 if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
139 local n = next_global
140 if n > 2047 then werror("too many global labels") end
141 next_global = n + 1
142 t[name] = n
143 return n
144end})
145
146-- Dump global labels.
147local function dumpglobals(out, lvl)
148 local t = {}
149 for name, n in pairs(map_global) do t[n] = name end
150 out:write("Global labels:\n")
151 for i=20,next_global-1 do
152 out:write(format(" %s\n", t[i]))
153 end
154 out:write("\n")
155end
156
157-- Write global label enum.
158local function writeglobals(out, prefix)
159 local t = {}
160 for name, n in pairs(map_global) do t[n] = name end
161 out:write("enum {\n")
162 for i=20,next_global-1 do
163 out:write(" ", prefix, t[i], ",\n")
164 end
165 out:write(" ", prefix, "_MAX\n};\n")
166end
167
168-- Write global label names.
169local function writeglobalnames(out, name)
170 local t = {}
171 for name, n in pairs(map_global) do t[n] = name end
172 out:write("static const char *const ", name, "[] = {\n")
173 for i=20,next_global-1 do
174 out:write(" \"", t[i], "\",\n")
175 end
176 out:write(" (const char *)0\n};\n")
177end
178
179------------------------------------------------------------------------------
180
181-- Extern label name -> extern label number. With auto assignment on 1st use.
182local next_extern = 0
183local map_extern_ = {}
184local map_extern = setmetatable({}, { __index = function(t, name)
185 -- No restrictions on the name for now.
186 local n = next_extern
187 if n > 2047 then werror("too many extern labels") end
188 next_extern = n + 1
189 t[name] = n
190 map_extern_[n] = name
191 return n
192end})
193
194-- Dump extern labels.
195local function dumpexterns(out, lvl)
196 out:write("Extern labels:\n")
197 for i=0,next_extern-1 do
198 out:write(format(" %s\n", map_extern_[i]))
199 end
200 out:write("\n")
201end
202
203-- Write extern label names.
204local function writeexternnames(out, name)
205 out:write("static const char *const ", name, "[] = {\n")
206 for i=0,next_extern-1 do
207 out:write(" \"", map_extern_[i], "\",\n")
208 end
209 out:write(" (const char *)0\n};\n")
210end
211
212------------------------------------------------------------------------------
213
214-- Arch-specific maps.
215local map_archdef = { sp = "r1" } -- Ext. register name -> int. name.
216
217local map_type = {} -- Type name -> { ctype, reg }
218local ctypenum = 0 -- Type number (for Dt... macros).
219
220-- Reverse defines for registers.
221function _M.revdef(s)
222 if s == "r1" then return "sp" end
223 return s
224end
225
226local map_cond = {
227 lt = 0, gt = 1, eq = 2, so = 3,
228 ge = 4, le = 5, ne = 6, ns = 7,
229}
230
231------------------------------------------------------------------------------
232
233-- Template strings for PPC instructions.
234local map_op = {
235 tdi_3 = "08000000ARI",
236 twi_3 = "0c000000ARI",
237 mulli_3 = "1c000000RRI",
238 subfic_3 = "20000000RRI",
239 cmplwi_3 = "28000000XRU",
240 cmplwi_2 = "28000000-RU",
241 cmpldi_3 = "28200000XRU",
242 cmpldi_2 = "28200000-RU",
243 cmpwi_3 = "2c000000XRI",
244 cmpwi_2 = "2c000000-RI",
245 cmpdi_3 = "2c200000XRI",
246 cmpdi_2 = "2c200000-RI",
247 addic_3 = "30000000RRI",
248 ["addic._3"] = "34000000RRI",
249 addi_3 = "38000000RR0I",
250 li_2 = "38000000RI",
251 la_2 = "38000000RD",
252 addis_3 = "3c000000RR0I",
253 lis_2 = "3c000000RI",
254 lus_2 = "3c000000RU",
255 bc_3 = "40000000AAK",
256 bcl_3 = "40000001AAK",
257 bdnz_1 = "42000000K",
258 bdz_1 = "42400000K",
259 sc_0 = "44000000",
260 b_1 = "48000000J",
261 bl_1 = "48000001J",
262 rlwimi_5 = "50000000RR~AAA.",
263 rlwinm_5 = "54000000RR~AAA.",
264 rlwnm_5 = "5c000000RR~RAA.",
265 ori_3 = "60000000RR~U",
266 nop_0 = "60000000",
267 oris_3 = "64000000RR~U",
268 xori_3 = "68000000RR~U",
269 xoris_3 = "6c000000RR~U",
270 ["andi._3"] = "70000000RR~U",
271 ["andis._3"] = "74000000RR~U",
272 lwz_2 = "80000000RD",
273 lwzu_2 = "84000000RD",
274 lbz_2 = "88000000RD",
275 lbzu_2 = "8c000000RD",
276 stw_2 = "90000000RD",
277 stwu_2 = "94000000RD",
278 stb_2 = "98000000RD",
279 stbu_2 = "9c000000RD",
280 lhz_2 = "a0000000RD",
281 lhzu_2 = "a4000000RD",
282 lha_2 = "a8000000RD",
283 lhau_2 = "ac000000RD",
284 sth_2 = "b0000000RD",
285 sthu_2 = "b4000000RD",
286 lmw_2 = "b8000000RD",
287 stmw_2 = "bc000000RD",
288 lfs_2 = "c0000000FD",
289 lfsu_2 = "c4000000FD",
290 lfd_2 = "c8000000FD",
291 lfdu_2 = "cc000000FD",
292 stfs_2 = "d0000000FD",
293 stfsu_2 = "d4000000FD",
294 stfd_2 = "d8000000FD",
295 stfdu_2 = "dc000000FD",
296 ld_2 = "e8000000RD", -- NYI: displacement must be divisible by 4.
297 ldu_2 = "e8000001RD",
298 lwa_2 = "e8000002RD",
299 std_2 = "f8000000RD",
300 stdu_2 = "f8000001RD",
301
302 -- Primary opcode 19:
303 mcrf_2 = "4c000000XX",
304 isync_0 = "4c00012c",
305 crnor_3 = "4c000042CCC",
306 crnot_2 = "4c000042CC=",
307 crandc_3 = "4c000102CCC",
308 crxor_3 = "4c000182CCC",
309 crclr_1 = "4c000182C==",
310 crnand_3 = "4c0001c2CCC",
311 crand_3 = "4c000202CCC",
312 creqv_3 = "4c000242CCC",
313 crset_1 = "4c000242C==",
314 crorc_3 = "4c000342CCC",
315 cror_3 = "4c000382CCC",
316 crmove_2 = "4c000382CC=",
317 bclr_2 = "4c000020AA",
318 bclrl_2 = "4c000021AA",
319 bcctr_2 = "4c000420AA",
320 bcctrl_2 = "4c000421AA",
321 blr_0 = "4e800020",
322 blrl_0 = "4e800021",
323 bctr_0 = "4e800420",
324 bctrl_0 = "4e800421",
325
326 -- Primary opcode 31:
327 cmpw_3 = "7c000000XRR",
328 cmpw_2 = "7c000000-RR",
329 cmpd_3 = "7c200000XRR",
330 cmpd_2 = "7c200000-RR",
331 tw_3 = "7c000008ARR",
332 subfc_3 = "7c000010RRR.",
333 subc_3 = "7c000010RRR~.",
334 mulhdu_3 = "7c000012RRR.",
335 addc_3 = "7c000014RRR.",
336 mulhwu_3 = "7c000016RRR.",
337 isel_4 = "7c00001eRRRC",
338 isellt_3 = "7c00001eRRR",
339 iselgt_3 = "7c00005eRRR",
340 iseleq_3 = "7c00009eRRR",
341 mfcr_1 = "7c000026R",
342 mtcrf_2 = "7c000120GR",
343 -- NYI: mtocrf, mfocrf
344 lwarx_3 = "7c000028RR0R",
345 ldx_3 = "7c00002aRR0R",
346 lwzx_3 = "7c00002eRR0R",
347 slw_3 = "7c000030RR~R.",
348 cntlzw_2 = "7c000034RR~",
349 sld_3 = "7c000036RR~R.",
350 and_3 = "7c000038RR~R.",
351 cmplw_3 = "7c000040XRR",
352 cmplw_2 = "7c000040-RR",
353 cmpld_3 = "7c200040XRR",
354 cmpld_2 = "7c200040-RR",
355 subf_3 = "7c000050RRR.",
356 sub_3 = "7c000050RRR~.",
357 ldux_3 = "7c00006aRR0R",
358 dcbst_2 = "7c00006c-RR",
359 lwzux_3 = "7c00006eRR0R",
360 cntlzd_2 = "7c000074RR~",
361 andc_3 = "7c000078RR~R.",
362 td_3 = "7c000088ARR",
363 mulhd_3 = "7c000092RRR.",
364 mulhw_3 = "7c000096RRR.",
365 ldarx_3 = "7c0000a8RR0R",
366 dcbf_2 = "7c0000ac-RR",
367 lbzx_3 = "7c0000aeRR0R",
368 neg_2 = "7c0000d0RR.",
369 lbzux_3 = "7c0000eeRR0R",
370 popcntb_2 = "7c0000f4RR~",
371 not_2 = "7c0000f8RR~%.",
372 nor_3 = "7c0000f8RR~R.",
373 subfe_3 = "7c000110RRR.",
374 sube_3 = "7c000110RRR~.",
375 adde_3 = "7c000114RRR.",
376 stdx_3 = "7c00012aRR0R",
377 stwcx_3 = "7c00012cRR0R.",
378 stwx_3 = "7c00012eRR0R",
379 prtyw_2 = "7c000134RR~",
380 stdux_3 = "7c00016aRR0R",
381 stwux_3 = "7c00016eRR0R",
382 prtyd_2 = "7c000174RR~",
383 subfze_2 = "7c000190RR.",
384 addze_2 = "7c000194RR.",
385 stdcx_3 = "7c0001acRR0R.",
386 stbx_3 = "7c0001aeRR0R",
387 subfme_2 = "7c0001d0RR.",
388 mulld_3 = "7c0001d2RRR.",
389 addme_2 = "7c0001d4RR.",
390 mullw_3 = "7c0001d6RRR.",
391 dcbtst_2 = "7c0001ec-RR",
392 stbux_3 = "7c0001eeRR0R",
393 add_3 = "7c000214RRR.",
394 dcbt_2 = "7c00022c-RR",
395 lhzx_3 = "7c00022eRR0R",
396 eqv_3 = "7c000238RR~R.",
397 eciwx_3 = "7c00026cRR0R",
398 lhzux_3 = "7c00026eRR0R",
399 xor_3 = "7c000278RR~R.",
400 mfspefscr_1 = "7c0082a6R",
401 mfxer_1 = "7c0102a6R",
402 mflr_1 = "7c0802a6R",
403 mfctr_1 = "7c0902a6R",
404 lwax_3 = "7c0002aaRR0R",
405 lhax_3 = "7c0002aeRR0R",
406 mftb_1 = "7c0c42e6R",
407 mftbu_1 = "7c0d42e6R",
408 lwaux_3 = "7c0002eaRR0R",
409 lhaux_3 = "7c0002eeRR0R",
410 sthx_3 = "7c00032eRR0R",
411 orc_3 = "7c000338RR~R.",
412 ecowx_3 = "7c00036cRR0R",
413 sthux_3 = "7c00036eRR0R",
414 or_3 = "7c000378RR~R.",
415 mr_2 = "7c000378RR~%.",
416 divdu_3 = "7c000392RRR.",
417 divwu_3 = "7c000396RRR.",
418 mtspefscr_1 = "7c0083a6R",
419 mtxer_1 = "7c0103a6R",
420 mtlr_1 = "7c0803a6R",
421 mtctr_1 = "7c0903a6R",
422 dcbi_2 = "7c0003ac-RR",
423 nand_3 = "7c0003b8RR~R.",
424 divd_3 = "7c0003d2RRR.",
425 divw_3 = "7c0003d6RRR.",
426 cmpb_3 = "7c0003f8RR~R.",
427 mcrxr_1 = "7c000400X",
428 subfco_3 = "7c000410RRR.",
429 subco_3 = "7c000410RRR~.",
430 addco_3 = "7c000414RRR.",
431 ldbrx_3 = "7c000428RR0R",
432 lswx_3 = "7c00042aRR0R",
433 lwbrx_3 = "7c00042cRR0R",
434 lfsx_3 = "7c00042eFR0R",
435 srw_3 = "7c000430RR~R.",
436 srd_3 = "7c000436RR~R.",
437 subfo_3 = "7c000450RRR.",
438 subo_3 = "7c000450RRR~.",
439 lfsux_3 = "7c00046eFR0R",
440 lswi_3 = "7c0004aaRR0A",
441 sync_0 = "7c0004ac",
442 lwsync_0 = "7c2004ac",
443 ptesync_0 = "7c4004ac",
444 lfdx_3 = "7c0004aeFR0R",
445 nego_2 = "7c0004d0RR.",
446 lfdux_3 = "7c0004eeFR0R",
447 subfeo_3 = "7c000510RRR.",
448 subeo_3 = "7c000510RRR~.",
449 addeo_3 = "7c000514RRR.",
450 stdbrx_3 = "7c000528RR0R",
451 stswx_3 = "7c00052aRR0R",
452 stwbrx_3 = "7c00052cRR0R",
453 stfsx_3 = "7c00052eFR0R",
454 stfsux_3 = "7c00056eFR0R",
455 subfzeo_2 = "7c000590RR.",
456 addzeo_2 = "7c000594RR.",
457 stswi_3 = "7c0005aaRR0A",
458 stfdx_3 = "7c0005aeFR0R",
459 subfmeo_2 = "7c0005d0RR.",
460 mulldo_3 = "7c0005d2RRR.",
461 addmeo_2 = "7c0005d4RR.",
462 mullwo_3 = "7c0005d6RRR.",
463 dcba_2 = "7c0005ec-RR",
464 stfdux_3 = "7c0005eeFR0R",
465 addo_3 = "7c000614RRR.",
466 lhbrx_3 = "7c00062cRR0R",
467 sraw_3 = "7c000630RR~R.",
468 srad_3 = "7c000634RR~R.",
469 srawi_3 = "7c000670RR~A.",
470 eieio_0 = "7c0006ac",
471 lfiwax_3 = "7c0006aeFR0R",
472 sthbrx_3 = "7c00072cRR0R",
473 extsh_2 = "7c000734RR~.",
474 extsb_2 = "7c000774RR~.",
475 divduo_3 = "7c000792RRR.",
476 divwou_3 = "7c000796RRR.",
477 icbi_2 = "7c0007ac-RR",
478 stfiwx_3 = "7c0007aeFR0R",
479 extsw_2 = "7c0007b4RR~.",
480 divdo_3 = "7c0007d2RRR.",
481 divwo_3 = "7c0007d6RRR.",
482 dcbz_2 = "7c0007ec-RR",
483
484 -- Primary opcode 59:
485 fdivs_3 = "ec000024FFF.",
486 fsubs_3 = "ec000028FFF.",
487 fadds_3 = "ec00002aFFF.",
488 fsqrts_2 = "ec00002cF-F.",
489 fres_2 = "ec000030F-F.",
490 fmuls_3 = "ec000032FF-F.",
491 frsqrtes_2 = "ec000034F-F.",
492 fmsubs_4 = "ec000038FFFF~.",
493 fmadds_4 = "ec00003aFFFF~.",
494 fnmsubs_4 = "ec00003cFFFF~.",
495 fnmadds_4 = "ec00003eFFFF~.",
496
497 -- Primary opcode 63:
498 fdiv_3 = "fc000024FFF.",
499 fsub_3 = "fc000028FFF.",
500 fadd_3 = "fc00002aFFF.",
501 fsqrt_2 = "fc00002cF-F.",
502 fsel_4 = "fc00002eFFFF~.",
503 fre_2 = "fc000030F-F.",
504 fmul_3 = "fc000032FF-F.",
505 frsqrte_2 = "fc000034F-F.",
506 fmsub_4 = "fc000038FFFF~.",
507 fmadd_4 = "fc00003aFFFF~.",
508 fnmsub_4 = "fc00003cFFFF~.",
509 fnmadd_4 = "fc00003eFFFF~.",
510 fcmpu_3 = "fc000000XFF",
511 fcpsgn_3 = "fc000010FFF.",
512 fcmpo_3 = "fc000040XFF",
513 mtfsb1_1 = "fc00004cA",
514 fneg_2 = "fc000050F-F.",
515 mcrfs_2 = "fc000080XX",
516 mtfsb0_1 = "fc00008cA",
517 fmr_2 = "fc000090F-F.",
518 frsp_2 = "fc000018F-F.",
519 fctiw_2 = "fc00001cF-F.",
520 fctiwz_2 = "fc00001eF-F.",
521 mtfsfi_2 = "fc00010cAA", -- NYI: upshift.
522 fnabs_2 = "fc000110F-F.",
523 fabs_2 = "fc000210F-F.",
524 frin_2 = "fc000310F-F.",
525 friz_2 = "fc000350F-F.",
526 frip_2 = "fc000390F-F.",
527 frim_2 = "fc0003d0F-F.",
528 mffs_1 = "fc00048eF.",
529 -- NYI: mtfsf, mtfsb0, mtfsb1.
530 fctid_2 = "fc00065cF-F.",
531 fctidz_2 = "fc00065eF-F.",
532 fcfid_2 = "fc00069cF-F.",
533
534 -- Primary opcode 4, SPE APU extension:
535 evaddw_3 = "10000200RRR",
536 evaddiw_3 = "10000202RAR~",
537 evsubw_3 = "10000204RRR~",
538 evsubiw_3 = "10000206RAR~",
539 evabs_2 = "10000208RR",
540 evneg_2 = "10000209RR",
541 evextsb_2 = "1000020aRR",
542 evextsh_2 = "1000020bRR",
543 evrndw_2 = "1000020cRR",
544 evcntlzw_2 = "1000020dRR",
545 evcntlsw_2 = "1000020eRR",
546 brinc_3 = "1000020fRRR",
547 evand_3 = "10000211RRR",
548 evandc_3 = "10000212RRR",
549 evxor_3 = "10000216RRR",
550 evor_3 = "10000217RRR",
551 evmr_2 = "10000217RR=",
552 evnor_3 = "10000218RRR",
553 evnot_2 = "10000218RR=",
554 eveqv_3 = "10000219RRR",
555 evorc_3 = "1000021bRRR",
556 evnand_3 = "1000021eRRR",
557 evsrwu_3 = "10000220RRR",
558 evsrws_3 = "10000221RRR",
559 evsrwiu_3 = "10000222RRA",
560 evsrwis_3 = "10000223RRA",
561 evslw_3 = "10000224RRR",
562 evslwi_3 = "10000226RRA",
563 evrlw_3 = "10000228RRR",
564 evsplati_2 = "10000229RS",
565 evrlwi_3 = "1000022aRRA",
566 evsplatfi_2 = "1000022bRS",
567 evmergehi_3 = "1000022cRRR",
568 evmergelo_3 = "1000022dRRR",
569 evcmpgtu_3 = "10000230XRR",
570 evcmpgtu_2 = "10000230-RR",
571 evcmpgts_3 = "10000231XRR",
572 evcmpgts_2 = "10000231-RR",
573 evcmpltu_3 = "10000232XRR",
574 evcmpltu_2 = "10000232-RR",
575 evcmplts_3 = "10000233XRR",
576 evcmplts_2 = "10000233-RR",
577 evcmpeq_3 = "10000234XRR",
578 evcmpeq_2 = "10000234-RR",
579 evsel_4 = "10000278RRRW",
580 evsel_3 = "10000278RRR",
581 evfsadd_3 = "10000280RRR",
582 evfssub_3 = "10000281RRR",
583 evfsabs_2 = "10000284RR",
584 evfsnabs_2 = "10000285RR",
585 evfsneg_2 = "10000286RR",
586 evfsmul_3 = "10000288RRR",
587 evfsdiv_3 = "10000289RRR",
588 evfscmpgt_3 = "1000028cXRR",
589 evfscmpgt_2 = "1000028c-RR",
590 evfscmplt_3 = "1000028dXRR",
591 evfscmplt_2 = "1000028d-RR",
592 evfscmpeq_3 = "1000028eXRR",
593 evfscmpeq_2 = "1000028e-RR",
594 evfscfui_2 = "10000290R-R",
595 evfscfsi_2 = "10000291R-R",
596 evfscfuf_2 = "10000292R-R",
597 evfscfsf_2 = "10000293R-R",
598 evfsctui_2 = "10000294R-R",
599 evfsctsi_2 = "10000295R-R",
600 evfsctuf_2 = "10000296R-R",
601 evfsctsf_2 = "10000297R-R",
602 evfsctuiz_2 = "10000298R-R",
603 evfsctsiz_2 = "1000029aR-R",
604 evfststgt_3 = "1000029cXRR",
605 evfststgt_2 = "1000029c-RR",
606 evfststlt_3 = "1000029dXRR",
607 evfststlt_2 = "1000029d-RR",
608 evfststeq_3 = "1000029eXRR",
609 evfststeq_2 = "1000029e-RR",
610 efsadd_3 = "100002c0RRR",
611 efssub_3 = "100002c1RRR",
612 efsabs_2 = "100002c4RR",
613 efsnabs_2 = "100002c5RR",
614 efsneg_2 = "100002c6RR",
615 efsmul_3 = "100002c8RRR",
616 efsdiv_3 = "100002c9RRR",
617 efscmpgt_3 = "100002ccXRR",
618 efscmpgt_2 = "100002cc-RR",
619 efscmplt_3 = "100002cdXRR",
620 efscmplt_2 = "100002cd-RR",
621 efscmpeq_3 = "100002ceXRR",
622 efscmpeq_2 = "100002ce-RR",
623 efscfd_2 = "100002cfR-R",
624 efscfui_2 = "100002d0R-R",
625 efscfsi_2 = "100002d1R-R",
626 efscfuf_2 = "100002d2R-R",
627 efscfsf_2 = "100002d3R-R",
628 efsctui_2 = "100002d4R-R",
629 efsctsi_2 = "100002d5R-R",
630 efsctuf_2 = "100002d6R-R",
631 efsctsf_2 = "100002d7R-R",
632 efsctuiz_2 = "100002d8R-R",
633 efsctsiz_2 = "100002daR-R",
634 efststgt_3 = "100002dcXRR",
635 efststgt_2 = "100002dc-RR",
636 efststlt_3 = "100002ddXRR",
637 efststlt_2 = "100002dd-RR",
638 efststeq_3 = "100002deXRR",
639 efststeq_2 = "100002de-RR",
640 efdadd_3 = "100002e0RRR",
641 efdsub_3 = "100002e1RRR",
642 efdcfuid_2 = "100002e2R-R",
643 efdcfsid_2 = "100002e3R-R",
644 efdabs_2 = "100002e4RR",
645 efdnabs_2 = "100002e5RR",
646 efdneg_2 = "100002e6RR",
647 efdmul_3 = "100002e8RRR",
648 efddiv_3 = "100002e9RRR",
649 efdctuidz_2 = "100002eaR-R",
650 efdctsidz_2 = "100002ebR-R",
651 efdcmpgt_3 = "100002ecXRR",
652 efdcmpgt_2 = "100002ec-RR",
653 efdcmplt_3 = "100002edXRR",
654 efdcmplt_2 = "100002ed-RR",
655 efdcmpeq_3 = "100002eeXRR",
656 efdcmpeq_2 = "100002ee-RR",
657 efdcfs_2 = "100002efR-R",
658 efdcfui_2 = "100002f0R-R",
659 efdcfsi_2 = "100002f1R-R",
660 efdcfuf_2 = "100002f2R-R",
661 efdcfsf_2 = "100002f3R-R",
662 efdctui_2 = "100002f4R-R",
663 efdctsi_2 = "100002f5R-R",
664 efdctuf_2 = "100002f6R-R",
665 efdctsf_2 = "100002f7R-R",
666 efdctuiz_2 = "100002f8R-R",
667 efdctsiz_2 = "100002faR-R",
668 efdtstgt_3 = "100002fcXRR",
669 efdtstgt_2 = "100002fc-RR",
670 efdtstlt_3 = "100002fdXRR",
671 efdtstlt_2 = "100002fd-RR",
672 efdtsteq_3 = "100002feXRR",
673 efdtsteq_2 = "100002fe-RR",
674 evlddx_3 = "10000300RR0R",
675 evldd_2 = "10000301R8",
676 evldwx_3 = "10000302RR0R",
677 evldw_2 = "10000303R8",
678 evldhx_3 = "10000304RR0R",
679 evldh_2 = "10000305R8",
680 evlwhex_3 = "10000310RR0R",
681 evlwhe_2 = "10000311R4",
682 evlwhoux_3 = "10000314RR0R",
683 evlwhou_2 = "10000315R4",
684 evlwhosx_3 = "10000316RR0R",
685 evlwhos_2 = "10000317R4",
686 evstddx_3 = "10000320RR0R",
687 evstdd_2 = "10000321R8",
688 evstdwx_3 = "10000322RR0R",
689 evstdw_2 = "10000323R8",
690 evstdhx_3 = "10000324RR0R",
691 evstdh_2 = "10000325R8",
692 evstwhex_3 = "10000330RR0R",
693 evstwhe_2 = "10000331R4",
694 evstwhox_3 = "10000334RR0R",
695 evstwho_2 = "10000335R4",
696 evstwwex_3 = "10000338RR0R",
697 evstwwe_2 = "10000339R4",
698 evstwwox_3 = "1000033cRR0R",
699 evstwwo_2 = "1000033dR4",
700 evmhessf_3 = "10000403RRR",
701 evmhossf_3 = "10000407RRR",
702 evmheumi_3 = "10000408RRR",
703 evmhesmi_3 = "10000409RRR",
704 evmhesmf_3 = "1000040bRRR",
705 evmhoumi_3 = "1000040cRRR",
706 evmhosmi_3 = "1000040dRRR",
707 evmhosmf_3 = "1000040fRRR",
708 evmhessfa_3 = "10000423RRR",
709 evmhossfa_3 = "10000427RRR",
710 evmheumia_3 = "10000428RRR",
711 evmhesmia_3 = "10000429RRR",
712 evmhesmfa_3 = "1000042bRRR",
713 evmhoumia_3 = "1000042cRRR",
714 evmhosmia_3 = "1000042dRRR",
715 evmhosmfa_3 = "1000042fRRR",
716 evmwhssf_3 = "10000447RRR",
717 evmwlumi_3 = "10000448RRR",
718 evmwhumi_3 = "1000044cRRR",
719 evmwhsmi_3 = "1000044dRRR",
720 evmwhsmf_3 = "1000044fRRR",
721 evmwssf_3 = "10000453RRR",
722 evmwumi_3 = "10000458RRR",
723 evmwsmi_3 = "10000459RRR",
724 evmwsmf_3 = "1000045bRRR",
725 evmwhssfa_3 = "10000467RRR",
726 evmwlumia_3 = "10000468RRR",
727 evmwhumia_3 = "1000046cRRR",
728 evmwhsmia_3 = "1000046dRRR",
729 evmwhsmfa_3 = "1000046fRRR",
730 evmwssfa_3 = "10000473RRR",
731 evmwumia_3 = "10000478RRR",
732 evmwsmia_3 = "10000479RRR",
733 evmwsmfa_3 = "1000047bRRR",
734 evmra_2 = "100004c4RR",
735 evdivws_3 = "100004c6RRR",
736 evdivwu_3 = "100004c7RRR",
737 evmwssfaa_3 = "10000553RRR",
738 evmwumiaa_3 = "10000558RRR",
739 evmwsmiaa_3 = "10000559RRR",
740 evmwsmfaa_3 = "1000055bRRR",
741 evmwssfan_3 = "100005d3RRR",
742 evmwumian_3 = "100005d8RRR",
743 evmwsmian_3 = "100005d9RRR",
744 evmwsmfan_3 = "100005dbRRR",
745 evmergehilo_3 = "1000022eRRR",
746 evmergelohi_3 = "1000022fRRR",
747 evlhhesplatx_3 = "10000308RR0R",
748 evlhhesplat_2 = "10000309R2",
749 evlhhousplatx_3 = "1000030cRR0R",
750 evlhhousplat_2 = "1000030dR2",
751 evlhhossplatx_3 = "1000030eRR0R",
752 evlhhossplat_2 = "1000030fR2",
753 evlwwsplatx_3 = "10000318RR0R",
754 evlwwsplat_2 = "10000319R4",
755 evlwhsplatx_3 = "1000031cRR0R",
756 evlwhsplat_2 = "1000031dR4",
757 evaddusiaaw_2 = "100004c0RR",
758 evaddssiaaw_2 = "100004c1RR",
759 evsubfusiaaw_2 = "100004c2RR",
760 evsubfssiaaw_2 = "100004c3RR",
761 evaddumiaaw_2 = "100004c8RR",
762 evaddsmiaaw_2 = "100004c9RR",
763 evsubfumiaaw_2 = "100004caRR",
764 evsubfsmiaaw_2 = "100004cbRR",
765 evmheusiaaw_3 = "10000500RRR",
766 evmhessiaaw_3 = "10000501RRR",
767 evmhessfaaw_3 = "10000503RRR",
768 evmhousiaaw_3 = "10000504RRR",
769 evmhossiaaw_3 = "10000505RRR",
770 evmhossfaaw_3 = "10000507RRR",
771 evmheumiaaw_3 = "10000508RRR",
772 evmhesmiaaw_3 = "10000509RRR",
773 evmhesmfaaw_3 = "1000050bRRR",
774 evmhoumiaaw_3 = "1000050cRRR",
775 evmhosmiaaw_3 = "1000050dRRR",
776 evmhosmfaaw_3 = "1000050fRRR",
777 evmhegumiaa_3 = "10000528RRR",
778 evmhegsmiaa_3 = "10000529RRR",
779 evmhegsmfaa_3 = "1000052bRRR",
780 evmhogumiaa_3 = "1000052cRRR",
781 evmhogsmiaa_3 = "1000052dRRR",
782 evmhogsmfaa_3 = "1000052fRRR",
783 evmwlusiaaw_3 = "10000540RRR",
784 evmwlssiaaw_3 = "10000541RRR",
785 evmwlumiaaw_3 = "10000548RRR",
786 evmwlsmiaaw_3 = "10000549RRR",
787 evmheusianw_3 = "10000580RRR",
788 evmhessianw_3 = "10000581RRR",
789 evmhessfanw_3 = "10000583RRR",
790 evmhousianw_3 = "10000584RRR",
791 evmhossianw_3 = "10000585RRR",
792 evmhossfanw_3 = "10000587RRR",
793 evmheumianw_3 = "10000588RRR",
794 evmhesmianw_3 = "10000589RRR",
795 evmhesmfanw_3 = "1000058bRRR",
796 evmhoumianw_3 = "1000058cRRR",
797 evmhosmianw_3 = "1000058dRRR",
798 evmhosmfanw_3 = "1000058fRRR",
799 evmhegumian_3 = "100005a8RRR",
800 evmhegsmian_3 = "100005a9RRR",
801 evmhegsmfan_3 = "100005abRRR",
802 evmhogumian_3 = "100005acRRR",
803 evmhogsmian_3 = "100005adRRR",
804 evmhogsmfan_3 = "100005afRRR",
805 evmwlusianw_3 = "100005c0RRR",
806 evmwlssianw_3 = "100005c1RRR",
807 evmwlumianw_3 = "100005c8RRR",
808 evmwlsmianw_3 = "100005c9RRR",
809
810 -- NYI: some 64 bit PowerPC and Book E instructions:
811 -- rldicl, rldicr, rldic, rldimi, rldcl, rldcr, sradi, 64 bit ext. add/sub,
812 -- extended addressing branches, cache management, loads and stores
813}
814
815-- Add mnemonics for "." variants.
816do
817 local t = {}
818 for k,v in pairs(map_op) do
819 if sub(v, -1) == "." then
820 local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2)
821 t[sub(k, 1, -3).."."..sub(k, -2)] = v2
822 end
823 end
824 for k,v in pairs(t) do
825 map_op[k] = v
826 end
827end
828
829-- Add more branch mnemonics.
830for cond,c in pairs(map_cond) do
831 local b1 = "b"..cond
832 local c1 = (c%4)*0x00010000 + (c < 4 and 0x01000000 or 0)
833 -- bX[l]
834 map_op[b1.."_1"] = tohex(0x40800000 + c1).."K"
835 map_op[b1.."y_1"] = tohex(0x40a00000 + c1).."K"
836 map_op[b1.."l_1"] = tohex(0x40800001 + c1).."K"
837 map_op[b1.."_2"] = tohex(0x40800000 + c1).."-XK"
838 map_op[b1.."y_2"] = tohex(0x40a00000 + c1).."-XK"
839 map_op[b1.."l_2"] = tohex(0x40800001 + c1).."-XK"
840 -- bXlr[l]
841 map_op[b1.."lr_0"] = tohex(0x4c800020 + c1)
842 map_op[b1.."lrl_0"] = tohex(0x4c800021 + c1)
843 map_op[b1.."ctr_0"] = tohex(0x4c800420 + c1)
844 map_op[b1.."ctrl_0"] = tohex(0x4c800421 + c1)
845 -- bXctr[l]
846 map_op[b1.."lr_1"] = tohex(0x4c800020 + c1).."-X"
847 map_op[b1.."lrl_1"] = tohex(0x4c800021 + c1).."-X"
848 map_op[b1.."ctr_1"] = tohex(0x4c800420 + c1).."-X"
849 map_op[b1.."ctrl_1"] = tohex(0x4c800421 + c1).."-X"
850end
851
852------------------------------------------------------------------------------
853
854local function parse_gpr(expr)
855 local tname, ovreg = match(expr, "^([%w_]+):(r[1-3]?[0-9])$")
856 local tp = map_type[tname or expr]
857 if tp then
858 local reg = ovreg or tp.reg
859 if not reg then
860 werror("type `"..(tname or expr).."' needs a register override")
861 end
862 expr = reg
863 end
864 local r = match(expr, "^r([1-3]?[0-9])$")
865 if r then
866 r = tonumber(r)
867 if r <= 31 then return r, tp end
868 end
869 werror("bad register name `"..expr.."'")
870end
871
872local function parse_fpr(expr)
873 local r = match(expr, "^f([1-3]?[0-9])$")
874 if r then
875 r = tonumber(r)
876 if r <= 31 then return r end
877 end
878 werror("bad register name `"..expr.."'")
879end
880
881local function parse_cr(expr)
882 local r = match(expr, "^cr([0-7])$")
883 if r then return tonumber(r) end
884 werror("bad condition register name `"..expr.."'")
885end
886
887local function parse_cond(expr)
888 local r, cond = match(expr, "^4%*cr([0-7])%+(%w%w)$")
889 if r then
890 r = tonumber(r)
891 local c = map_cond[cond]
892 if c and c < 4 then return r*4+c end
893 end
894 werror("bad condition bit name `"..expr.."'")
895end
896
897local function parse_imm(imm, bits, shift, scale, signed)
898 local n = tonumber(imm)
899 if n then
900 if n % 2^scale == 0 then
901 n = n / 2^scale
902 if signed then
903 if n >= 0 then
904 if n < 2^(bits-1) then return n*2^shift end
905 else
906 if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end
907 end
908 else
909 if n >= 0 and n <= 2^bits-1 then return n*2^shift end
910 end
911 end
912 werror("out of range immediate `"..imm.."'")
913 elseif match(imm, "^r([1-3]?[0-9])$") or
914 match(imm, "^([%w_]+):(r[1-3]?[0-9])$") then
915 werror("expected immediate operand, got register")
916 else
917 waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
918 return 0
919 end
920end
921
922local function parse_disp(disp)
923 local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
924 if imm then
925 local r = parse_gpr(reg)
926 if r == 0 then werror("cannot use r0 in displacement") end
927 return r*65536 + parse_imm(imm, 16, 0, 0, true)
928 end
929 local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
930 if reg and tailr ~= "" then
931 local r, tp = parse_gpr(reg)
932 if r == 0 then werror("cannot use r0 in displacement") end
933 if tp then
934 waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
935 return r*65536
936 end
937 end
938 werror("bad displacement `"..disp.."'")
939end
940
941local function parse_u5disp(disp, scale)
942 local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
943 if imm then
944 local r = parse_gpr(reg)
945 if r == 0 then werror("cannot use r0 in displacement") end
946 return r*65536 + parse_imm(imm, 5, 11, scale, false)
947 end
948 local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
949 if reg and tailr ~= "" then
950 local r, tp = parse_gpr(reg)
951 if r == 0 then werror("cannot use r0 in displacement") end
952 if tp then
953 waction("IMM", scale*1024+5*32+11, format(tp.ctypefmt, tailr))
954 return r*65536
955 end
956 end
957 werror("bad displacement `"..disp.."'")
958end
959
960local function parse_label(label, def)
961 local prefix = sub(label, 1, 2)
962 -- =>label (pc label reference)
963 if prefix == "=>" then
964 return "PC", 0, sub(label, 3)
965 end
966 -- ->name (global label reference)
967 if prefix == "->" then
968 return "LG", map_global[sub(label, 3)]
969 end
970 if def then
971 -- [1-9] (local label definition)
972 if match(label, "^[1-9]$") then
973 return "LG", 10+tonumber(label)
974 end
975 else
976 -- [<>][1-9] (local label reference)
977 local dir, lnum = match(label, "^([<>])([1-9])$")
978 if dir then -- Fwd: 1-9, Bkwd: 11-19.
979 return "LG", lnum + (dir == ">" and 0 or 10)
980 end
981 -- extern label (extern label reference)
982 local extname = match(label, "^extern%s+(%S+)$")
983 if extname then
984 return "EXT", map_extern[extname]
985 end
986 end
987 werror("bad label `"..label.."'")
988end
989
990------------------------------------------------------------------------------
991
992-- Handle opcodes defined with template strings.
993map_op[".template__"] = function(params, template, nparams)
994 if not params then return sub(template, 9) end
995 local op = tonumber(sub(template, 1, 8), 16)
996 local n, rs = 1, 26
997
998 -- Limit number of section buffer positions used by a single dasm_put().
999 -- A single opcode needs a maximum of 3 positions (rlwinm).
1000 if secpos+3 > maxsecpos then wflush() end
1001 local pos = wpos()
1002
1003 -- Process each character.
1004 for p in gmatch(sub(template, 9), ".") do
1005 if p == "R" then
1006 rs = rs - 5; op = op + parse_gpr(params[n]) * 2^rs; n = n + 1
1007 elseif p == "F" then
1008 rs = rs - 5; op = op + parse_fpr(params[n]) * 2^rs; n = n + 1
1009 elseif p == "A" then
1010 rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1
1011 elseif p == "S" then
1012 rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, true); n = n + 1
1013 elseif p == "I" then
1014 op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1
1015 elseif p == "U" then
1016 op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1
1017 elseif p == "D" then
1018 op = op + parse_disp(params[n]); n = n + 1
1019 elseif p == "2" then
1020 op = op + parse_u5disp(params[n], 1); n = n + 1
1021 elseif p == "4" then
1022 op = op + parse_u5disp(params[n], 2); n = n + 1
1023 elseif p == "8" then
1024 op = op + parse_u5disp(params[n], 3); n = n + 1
1025 elseif p == "C" then
1026 rs = rs - 5; op = op + parse_cond(params[n]) * 2^rs; n = n + 1
1027 elseif p == "X" then
1028 rs = rs - 5; op = op + parse_cr(params[n]) * 2^(rs+2); n = n + 1
1029 elseif p == "W" then
1030 op = op + parse_cr(params[n]); n = n + 1
1031 elseif p == "G" then
1032 op = op + parse_imm(params[n], 8, 12, 0, false); n = n + 1
1033 elseif p == "J" or p == "K" then
1034 local mode, n, s = parse_label(params[n], false)
1035 if p == "K" then n = n + 2048 end
1036 waction("REL_"..mode, n, s, 1)
1037 n = n + 1
1038 elseif p == "0" then
1039 local mm = 2^rs
1040 local t = op % mm
1041 if ((op - t) / mm) % 32 == 0 then werror("cannot use r0") end
1042 elseif p == "=" or p == "%" then
1043 local mm = 2^(rs + (p == "%" and 5 or 0))
1044 local t = ((op - op % mm) / mm) % 32
1045 rs = rs - 5
1046 op = op + t * 2^rs
1047 elseif p == "~" then
1048 local mm = 2^rs
1049 local t1l = op % mm
1050 local t1h = (op - t1l) / mm
1051 local t2l = t1h % 32
1052 local t2h = (t1h - t2l) / 32
1053 local t3l = t2h % 32
1054 op = ((t2h - t3l + t2l)*32 + t3l)*mm + t1l
1055 elseif p == "-" then
1056 rs = rs - 5
1057 elseif p == "." then
1058 -- Ignored.
1059 else
1060 assert(false)
1061 end
1062 end
1063 wputpos(pos, op)
1064end
1065
1066------------------------------------------------------------------------------
1067
1068-- Pseudo-opcode to mark the position where the action list is to be emitted.
1069map_op[".actionlist_1"] = function(params)
1070 if not params then return "cvar" end
1071 local name = params[1] -- No syntax check. You get to keep the pieces.
1072 wline(function(out) writeactions(out, name) end)
1073end
1074
1075-- Pseudo-opcode to mark the position where the global enum is to be emitted.
1076map_op[".globals_1"] = function(params)
1077 if not params then return "prefix" end
1078 local prefix = params[1] -- No syntax check. You get to keep the pieces.
1079 wline(function(out) writeglobals(out, prefix) end)
1080end
1081
1082-- Pseudo-opcode to mark the position where the global names are to be emitted.
1083map_op[".globalnames_1"] = function(params)
1084 if not params then return "cvar" end
1085 local name = params[1] -- No syntax check. You get to keep the pieces.
1086 wline(function(out) writeglobalnames(out, name) end)
1087end
1088
1089-- Pseudo-opcode to mark the position where the extern names are to be emitted.
1090map_op[".externnames_1"] = function(params)
1091 if not params then return "cvar" end
1092 local name = params[1] -- No syntax check. You get to keep the pieces.
1093 wline(function(out) writeexternnames(out, name) end)
1094end
1095
1096------------------------------------------------------------------------------
1097
1098-- Label pseudo-opcode (converted from trailing colon form).
1099map_op[".label_1"] = function(params)
1100 if not params then return "[1-9] | ->global | =>pcexpr" end
1101 if secpos+1 > maxsecpos then wflush() end
1102 local mode, n, s = parse_label(params[1], true)
1103 if mode == "EXT" then werror("bad label definition") end
1104 waction("LABEL_"..mode, n, s, 1)
1105end
1106
1107------------------------------------------------------------------------------
1108
1109-- Pseudo-opcodes for data storage.
1110map_op[".long_*"] = function(params)
1111 if not params then return "imm..." end
1112 for _,p in ipairs(params) do
1113 local n = tonumber(p)
1114 if not n then werror("bad immediate `"..p.."'") end
1115 if n < 0 then n = n + 2^32 end
1116 wputw(n)
1117 if secpos+2 > maxsecpos then wflush() end
1118 end
1119end
1120
1121-- Alignment pseudo-opcode.
1122map_op[".align_1"] = function(params)
1123 if not params then return "numpow2" end
1124 if secpos+1 > maxsecpos then wflush() end
1125 local align = tonumber(params[1])
1126 if align then
1127 local x = align
1128 -- Must be a power of 2 in the range (2 ... 256).
1129 for i=1,8 do
1130 x = x / 2
1131 if x == 1 then
1132 waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
1133 return
1134 end
1135 end
1136 end
1137 werror("bad alignment")
1138end
1139
1140------------------------------------------------------------------------------
1141
1142-- Pseudo-opcode for (primitive) type definitions (map to C types).
1143map_op[".type_3"] = function(params, nparams)
1144 if not params then
1145 return nparams == 2 and "name, ctype" or "name, ctype, reg"
1146 end
1147 local name, ctype, reg = params[1], params[2], params[3]
1148 if not match(name, "^[%a_][%w_]*$") then
1149 werror("bad type name `"..name.."'")
1150 end
1151 local tp = map_type[name]
1152 if tp then
1153 werror("duplicate type `"..name.."'")
1154 end
1155 -- Add #type to defines. A bit unclean to put it in map_archdef.
1156 map_archdef["#"..name] = "sizeof("..ctype..")"
1157 -- Add new type and emit shortcut define.
1158 local num = ctypenum + 1
1159 map_type[name] = {
1160 ctype = ctype,
1161 ctypefmt = format("Dt%X(%%s)", num),
1162 reg = reg,
1163 }
1164 wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
1165 ctypenum = num
1166end
1167map_op[".type_2"] = map_op[".type_3"]
1168
1169-- Dump type definitions.
1170local function dumptypes(out, lvl)
1171 local t = {}
1172 for name in pairs(map_type) do t[#t+1] = name end
1173 sort(t)
1174 out:write("Type definitions:\n")
1175 for _,name in ipairs(t) do
1176 local tp = map_type[name]
1177 local reg = tp.reg or ""
1178 out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
1179 end
1180 out:write("\n")
1181end
1182
1183------------------------------------------------------------------------------
1184
1185-- Set the current section.
1186function _M.section(num)
1187 waction("SECTION", num)
1188 wflush(true) -- SECTION is a terminal action.
1189end
1190
1191------------------------------------------------------------------------------
1192
1193-- Dump architecture description.
1194function _M.dumparch(out)
1195 out:write(format("DynASM %s version %s, released %s\n\n",
1196 _info.arch, _info.version, _info.release))
1197 dumpactions(out)
1198end
1199
1200-- Dump all user defined elements.
1201function _M.dumpdef(out, lvl)
1202 dumptypes(out, lvl)
1203 dumpglobals(out, lvl)
1204 dumpexterns(out, lvl)
1205end
1206
1207------------------------------------------------------------------------------
1208
1209-- Pass callbacks from/to the DynASM core.
1210function _M.passcb(wl, we, wf, ww)
1211 wline, werror, wfatal, wwarn = wl, we, wf, ww
1212 return wflush
1213end
1214
1215-- Setup the arch-specific module.
1216function _M.setup(arch, opt)
1217 g_arch, g_opt = arch, opt
1218end
1219
1220-- Merge the core maps and the arch-specific maps.
1221function _M.mergemaps(map_coreop, map_def)
1222 setmetatable(map_op, { __index = map_coreop })
1223 setmetatable(map_def, { __index = map_archdef })
1224 return map_op, map_def
1225end
1226
1227return _M
1228
1229------------------------------------------------------------------------------
1230
diff --git a/libraries/luajit-2.0/dynasm/dasm_proto.h b/libraries/luajit-2.0/dynasm/dasm_proto.h
new file mode 100644
index 0000000..3cc3af2
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_proto.h
@@ -0,0 +1,83 @@
1/*
2** DynASM encoding engine prototypes.
3** Copyright (C) 2005-2011 Mike Pall. All rights reserved.
4** Released under the MIT license. See dynasm.lua for full copyright notice.
5*/
6
7#ifndef _DASM_PROTO_H
8#define _DASM_PROTO_H
9
10#include <stddef.h>
11#include <stdarg.h>
12
13#define DASM_IDENT "DynASM 1.3.0"
14#define DASM_VERSION 10300 /* 1.3.0 */
15
16#ifndef Dst_DECL
17#define Dst_DECL dasm_State **Dst
18#endif
19
20#ifndef Dst_REF
21#define Dst_REF (*Dst)
22#endif
23
24#ifndef DASM_FDEF
25#define DASM_FDEF extern
26#endif
27
28#ifndef DASM_M_GROW
29#define DASM_M_GROW(ctx, t, p, sz, need) \
30 do { \
31 size_t _sz = (sz), _need = (need); \
32 if (_sz < _need) { \
33 if (_sz < 16) _sz = 16; \
34 while (_sz < _need) _sz += _sz; \
35 (p) = (t *)realloc((p), _sz); \
36 if ((p) == NULL) exit(1); \
37 (sz) = _sz; \
38 } \
39 } while(0)
40#endif
41
42#ifndef DASM_M_FREE
43#define DASM_M_FREE(ctx, p, sz) free(p)
44#endif
45
46/* Internal DynASM encoder state. */
47typedef struct dasm_State dasm_State;
48
49
50/* Initialize and free DynASM state. */
51DASM_FDEF void dasm_init(Dst_DECL, int maxsection);
52DASM_FDEF void dasm_free(Dst_DECL);
53
54/* Setup global array. Must be called before dasm_setup(). */
55DASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl);
56
57/* Grow PC label array. Can be called after dasm_setup(), too. */
58DASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc);
59
60/* Setup encoder. */
61DASM_FDEF void dasm_setup(Dst_DECL, const void *actionlist);
62
63/* Feed encoder with actions. Calls are generated by pre-processor. */
64DASM_FDEF void dasm_put(Dst_DECL, int start, ...);
65
66/* Link sections and return the resulting size. */
67DASM_FDEF int dasm_link(Dst_DECL, size_t *szp);
68
69/* Encode sections into buffer. */
70DASM_FDEF int dasm_encode(Dst_DECL, void *buffer);
71
72/* Get PC label offset. */
73DASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc);
74
75#ifdef DASM_CHECKS
76/* Optional sanity checker to call between isolated encoding steps. */
77DASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch);
78#else
79#define dasm_checkstep(a, b) 0
80#endif
81
82
83#endif /* _DASM_PROTO_H */
diff --git a/libraries/luajit-2.0/dynasm/dasm_x64.lua b/libraries/luajit-2.0/dynasm/dasm_x64.lua
new file mode 100644
index 0000000..73e01e9
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_x64.lua
@@ -0,0 +1,12 @@
1------------------------------------------------------------------------------
2-- DynASM x64 module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- See dynasm.lua for full copyright notice.
6------------------------------------------------------------------------------
7-- This module just sets 64 bit mode for the combined x86/x64 module.
8-- All the interesting stuff is there.
9------------------------------------------------------------------------------
10
11x64 = true -- Using a global is an ugly, but effective solution.
12return require("dasm_x86")
diff --git a/libraries/luajit-2.0/dynasm/dasm_x86.h b/libraries/luajit-2.0/dynasm/dasm_x86.h
new file mode 100644
index 0000000..8f2dd1c
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_x86.h
@@ -0,0 +1,470 @@
1/*
2** DynASM x86 encoding engine.
3** Copyright (C) 2005-2011 Mike Pall. All rights reserved.
4** Released under the MIT license. See dynasm.lua for full copyright notice.
5*/
6
7#include <stddef.h>
8#include <stdarg.h>
9#include <string.h>
10#include <stdlib.h>
11
12#define DASM_ARCH "x86"
13
14#ifndef DASM_EXTERN
15#define DASM_EXTERN(a,b,c,d) 0
16#endif
17
18/* Action definitions. DASM_STOP must be 255. */
19enum {
20 DASM_DISP = 233,
21 DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
22 DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
23 DASM_IMM_LG, DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN,
24 DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
25};
26
27/* Maximum number of section buffer positions for a single dasm_put() call. */
28#define DASM_MAXSECPOS 25
29
30/* DynASM encoder status codes. Action list offset or number are or'ed in. */
31#define DASM_S_OK 0x00000000
32#define DASM_S_NOMEM 0x01000000
33#define DASM_S_PHASE 0x02000000
34#define DASM_S_MATCH_SEC 0x03000000
35#define DASM_S_RANGE_I 0x11000000
36#define DASM_S_RANGE_SEC 0x12000000
37#define DASM_S_RANGE_LG 0x13000000
38#define DASM_S_RANGE_PC 0x14000000
39#define DASM_S_RANGE_VREG 0x15000000
40#define DASM_S_UNDEF_L 0x21000000
41#define DASM_S_UNDEF_PC 0x22000000
42
43/* Macros to convert positions (8 bit section + 24 bit index). */
44#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
45#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
46#define DASM_SEC2POS(sec) ((sec)<<24)
47#define DASM_POS2SEC(pos) ((pos)>>24)
48#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
49
50/* Action list type. */
51typedef const unsigned char *dasm_ActList;
52
53/* Per-section structure. */
54typedef struct dasm_Section {
55 int *rbuf; /* Biased buffer pointer (negative section bias). */
56 int *buf; /* True buffer pointer. */
57 size_t bsize; /* Buffer size in bytes. */
58 int pos; /* Biased buffer position. */
59 int epos; /* End of biased buffer position - max single put. */
60 int ofs; /* Byte offset into section. */
61} dasm_Section;
62
63/* Core structure holding the DynASM encoding state. */
64struct dasm_State {
65 size_t psize; /* Allocated size of this structure. */
66 dasm_ActList actionlist; /* Current actionlist pointer. */
67 int *lglabels; /* Local/global chain/pos ptrs. */
68 size_t lgsize;
69 int *pclabels; /* PC label chains/pos ptrs. */
70 size_t pcsize;
71 void **globals; /* Array of globals (bias -10). */
72 dasm_Section *section; /* Pointer to active section. */
73 size_t codesize; /* Total size of all code sections. */
74 int maxsection; /* 0 <= sectionidx < maxsection. */
75 int status; /* Status code. */
76 dasm_Section sections[1]; /* All sections. Alloc-extended. */
77};
78
79/* The size of the core structure depends on the max. number of sections. */
80#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
81
82
83/* Initialize DynASM state. */
84void dasm_init(Dst_DECL, int maxsection)
85{
86 dasm_State *D;
87 size_t psz = 0;
88 int i;
89 Dst_REF = NULL;
90 DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
91 D = Dst_REF;
92 D->psize = psz;
93 D->lglabels = NULL;
94 D->lgsize = 0;
95 D->pclabels = NULL;
96 D->pcsize = 0;
97 D->globals = NULL;
98 D->maxsection = maxsection;
99 for (i = 0; i < maxsection; i++) {
100 D->sections[i].buf = NULL; /* Need this for pass3. */
101 D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
102 D->sections[i].bsize = 0;
103 D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
104 }
105}
106
107/* Free DynASM state. */
108void dasm_free(Dst_DECL)
109{
110 dasm_State *D = Dst_REF;
111 int i;
112 for (i = 0; i < D->maxsection; i++)
113 if (D->sections[i].buf)
114 DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
115 if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
116 if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
117 DASM_M_FREE(Dst, D, D->psize);
118}
119
120/* Setup global label array. Must be called before dasm_setup(). */
121void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
122{
123 dasm_State *D = Dst_REF;
124 D->globals = gl - 10; /* Negative bias to compensate for locals. */
125 DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
126}
127
128/* Grow PC label array. Can be called after dasm_setup(), too. */
129void dasm_growpc(Dst_DECL, unsigned int maxpc)
130{
131 dasm_State *D = Dst_REF;
132 size_t osz = D->pcsize;
133 DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
134 memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
135}
136
137/* Setup encoder. */
138void dasm_setup(Dst_DECL, const void *actionlist)
139{
140 dasm_State *D = Dst_REF;
141 int i;
142 D->actionlist = (dasm_ActList)actionlist;
143 D->status = DASM_S_OK;
144 D->section = &D->sections[0];
145 memset((void *)D->lglabels, 0, D->lgsize);
146 if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
147 for (i = 0; i < D->maxsection; i++) {
148 D->sections[i].pos = DASM_SEC2POS(i);
149 D->sections[i].ofs = 0;
150 }
151}
152
153
154#ifdef DASM_CHECKS
155#define CK(x, st) \
156 do { if (!(x)) { \
157 D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
158#define CKPL(kind, st) \
159 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
160 D->status=DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
161#else
162#define CK(x, st) ((void)0)
163#define CKPL(kind, st) ((void)0)
164#endif
165
166/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
167void dasm_put(Dst_DECL, int start, ...)
168{
169 va_list ap;
170 dasm_State *D = Dst_REF;
171 dasm_ActList p = D->actionlist + start;
172 dasm_Section *sec = D->section;
173 int pos = sec->pos, ofs = sec->ofs, mrm = 4;
174 int *b;
175
176 if (pos >= sec->epos) {
177 DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
178 sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
179 sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
180 sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
181 }
182
183 b = sec->rbuf;
184 b[pos++] = start;
185
186 va_start(ap, start);
187 while (1) {
188 int action = *p++;
189 if (action < DASM_DISP) {
190 ofs++;
191 } else if (action <= DASM_REL_A) {
192 int n = va_arg(ap, int);
193 b[pos++] = n;
194 switch (action) {
195 case DASM_DISP:
196 if (n == 0) { if ((mrm&7) == 4) mrm = p[-2]; if ((mrm&7) != 5) break; }
197 case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob;
198 case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
199 case DASM_IMM_D: ofs += 4; break;
200 case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
201 case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
202 case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob;
203 case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
204 case DASM_SPACE: p++; ofs += n; break;
205 case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */
206 case DASM_VREG: CK((n&-8) == 0 && (n != 4 || (*p&1) == 0), RANGE_VREG);
207 if (*p++ == 1 && *p == DASM_DISP) mrm = n; continue;
208 }
209 mrm = 4;
210 } else {
211 int *pl, n;
212 switch (action) {
213 case DASM_REL_LG:
214 case DASM_IMM_LG:
215 n = *p++; pl = D->lglabels + n;
216 if (n <= 246) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
217 pl -= 246; n = *pl;
218 if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
219 goto linkrel;
220 case DASM_REL_PC:
221 case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
222 putrel:
223 n = *pl;
224 if (n < 0) { /* Label exists. Get label pos and store it. */
225 b[pos] = -n;
226 } else {
227 linkrel:
228 b[pos] = n; /* Else link to rel chain, anchored at label. */
229 *pl = pos;
230 }
231 pos++;
232 ofs += 4; /* Maximum offset needed. */
233 if (action == DASM_REL_LG || action == DASM_REL_PC)
234 b[pos++] = ofs; /* Store pass1 offset estimate. */
235 break;
236 case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
237 case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
238 putlabel:
239 n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
240 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; }
241 *pl = -pos; /* Label exists now. */
242 b[pos++] = ofs; /* Store pass1 offset estimate. */
243 break;
244 case DASM_ALIGN:
245 ofs += *p++; /* Maximum alignment needed (arg is 2**n-1). */
246 b[pos++] = ofs; /* Store pass1 offset estimate. */
247 break;
248 case DASM_EXTERN: p += 2; ofs += 4; break;
249 case DASM_ESC: p++; ofs++; break;
250 case DASM_MARK: mrm = p[-2]; break;
251 case DASM_SECTION:
252 n = *p; CK(n < D->maxsection, RANGE_SEC); D->section = &D->sections[n];
253 case DASM_STOP: goto stop;
254 }
255 }
256 }
257stop:
258 va_end(ap);
259 sec->pos = pos;
260 sec->ofs = ofs;
261}
262#undef CK
263
264/* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */
265int dasm_link(Dst_DECL, size_t *szp)
266{
267 dasm_State *D = Dst_REF;
268 int secnum;
269 int ofs = 0;
270
271#ifdef DASM_CHECKS
272 *szp = 0;
273 if (D->status != DASM_S_OK) return D->status;
274 {
275 int pc;
276 for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
277 if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
278 }
279#endif
280
281 { /* Handle globals not defined in this translation unit. */
282 int idx;
283 for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
284 int n = D->lglabels[idx];
285 /* Undefined label: Collapse rel chain and replace with marker (< 0). */
286 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
287 }
288 }
289
290 /* Combine all code sections. No support for data sections (yet). */
291 for (secnum = 0; secnum < D->maxsection; secnum++) {
292 dasm_Section *sec = D->sections + secnum;
293 int *b = sec->rbuf;
294 int pos = DASM_SEC2POS(secnum);
295 int lastpos = sec->pos;
296
297 while (pos != lastpos) {
298 dasm_ActList p = D->actionlist + b[pos++];
299 while (1) {
300 int op, action = *p++;
301 switch (action) {
302 case DASM_REL_LG: p++; op = p[-3]; goto rel_pc;
303 case DASM_REL_PC: op = p[-2]; rel_pc: {
304 int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
305 if (shrink) { /* Shrinkable branch opcode? */
306 int lofs, lpos = b[pos];
307 if (lpos < 0) goto noshrink; /* Ext global? */
308 lofs = *DASM_POS2PTR(D, lpos);
309 if (lpos > pos) { /* Fwd label: add cumulative section offsets. */
310 int i;
311 for (i = secnum; i < DASM_POS2SEC(lpos); i++)
312 lofs += D->sections[i].ofs;
313 } else {
314 lofs -= ofs; /* Bkwd label: unfix offset. */
315 }
316 lofs -= b[pos+1]; /* Short branch ok? */
317 if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink; /* Yes. */
318 else { noshrink: shrink = 0; } /* No, cannot shrink op. */
319 }
320 b[pos+1] = shrink;
321 pos += 2;
322 break;
323 }
324 case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
325 case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
326 case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
327 case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
328 case DASM_LABEL_LG: p++;
329 case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
330 case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
331 case DASM_EXTERN: p += 2; break;
332 case DASM_ESC: p++; break;
333 case DASM_MARK: break;
334 case DASM_SECTION: case DASM_STOP: goto stop;
335 }
336 }
337 stop: (void)0;
338 }
339 ofs += sec->ofs; /* Next section starts right after current section. */
340 }
341
342 D->codesize = ofs; /* Total size of all code sections */
343 *szp = ofs;
344 return DASM_S_OK;
345}
346
347#define dasmb(x) *cp++ = (unsigned char)(x)
348#ifndef DASM_ALIGNED_WRITES
349#define dasmw(x) \
350 do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
351#define dasmd(x) \
352 do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
353#else
354#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
355#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
356#endif
357
358/* Pass 3: Encode sections. */
359int dasm_encode(Dst_DECL, void *buffer)
360{
361 dasm_State *D = Dst_REF;
362 unsigned char *base = (unsigned char *)buffer;
363 unsigned char *cp = base;
364 int secnum;
365
366 /* Encode all code sections. No support for data sections (yet). */
367 for (secnum = 0; secnum < D->maxsection; secnum++) {
368 dasm_Section *sec = D->sections + secnum;
369 int *b = sec->buf;
370 int *endb = sec->rbuf + sec->pos;
371
372 while (b != endb) {
373 dasm_ActList p = D->actionlist + *b++;
374 unsigned char *mark = NULL;
375 while (1) {
376 int action = *p++;
377 int n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0;
378 switch (action) {
379 case DASM_DISP: if (!mark) mark = cp; {
380 unsigned char *mm = mark;
381 if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL;
382 if (n == 0) { int mrm = mm[-1]&7; if (mrm == 4) mrm = mm[0]&7;
383 if (mrm != 5) { mm[-1] -= 0x80; break; } }
384 if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;
385 }
386 case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;
387 case DASM_IMM_DB: if (((n+128)&-256) == 0) {
388 db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;
389 } else mark = NULL;
390 case DASM_IMM_D: wd: dasmd(n); break;
391 case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
392 case DASM_IMM_W: dasmw(n); break;
393 case DASM_VREG: { int t = *p++; if (t >= 2) n<<=3; cp[-1] |= n; break; }
394 case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
395 b++; n = (int)(ptrdiff_t)D->globals[-n];
396 case DASM_REL_A: rel_a: n -= (int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
397 case DASM_REL_PC: rel_pc: {
398 int shrink = *b++;
399 int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }
400 n = *pb - ((int)(cp-base) + 4-shrink);
401 if (shrink == 0) goto wd;
402 if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb;
403 goto wb;
404 }
405 case DASM_IMM_LG:
406 p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }
407 case DASM_IMM_PC: {
408 int *pb = DASM_POS2PTR(D, n);
409 n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
410 goto wd;
411 }
412 case DASM_LABEL_LG: {
413 int idx = *p++;
414 if (idx >= 10)
415 D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
416 break;
417 }
418 case DASM_LABEL_PC: case DASM_SETLABEL: break;
419 case DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; }
420 case DASM_ALIGN:
421 n = *p++;
422 while (((cp-base) & n)) *cp++ = 0x90; /* nop */
423 break;
424 case DASM_EXTERN: n = DASM_EXTERN(Dst, cp, p[1], *p); p += 2; goto wd;
425 case DASM_MARK: mark = cp; break;
426 case DASM_ESC: action = *p++;
427 default: *cp++ = action; break;
428 case DASM_SECTION: case DASM_STOP: goto stop;
429 }
430 }
431 stop: (void)0;
432 }
433 }
434
435 if (base + D->codesize != cp) /* Check for phase errors. */
436 return DASM_S_PHASE;
437 return DASM_S_OK;
438}
439
440/* Get PC label offset. */
441int dasm_getpclabel(Dst_DECL, unsigned int pc)
442{
443 dasm_State *D = Dst_REF;
444 if (pc*sizeof(int) < D->pcsize) {
445 int pos = D->pclabels[pc];
446 if (pos < 0) return *DASM_POS2PTR(D, -pos);
447 if (pos > 0) return -1; /* Undefined. */
448 }
449 return -2; /* Unused or out of range. */
450}
451
452#ifdef DASM_CHECKS
453/* Optional sanity checker to call between isolated encoding steps. */
454int dasm_checkstep(Dst_DECL, int secmatch)
455{
456 dasm_State *D = Dst_REF;
457 if (D->status == DASM_S_OK) {
458 int i;
459 for (i = 1; i <= 9; i++) {
460 if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; }
461 D->lglabels[i] = 0;
462 }
463 }
464 if (D->status == DASM_S_OK && secmatch >= 0 &&
465 D->section != &D->sections[secmatch])
466 D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
467 return D->status;
468}
469#endif
470
diff --git a/libraries/luajit-2.0/dynasm/dasm_x86.lua b/libraries/luajit-2.0/dynasm/dasm_x86.lua
new file mode 100644
index 0000000..5571f93
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dasm_x86.lua
@@ -0,0 +1,1931 @@
1------------------------------------------------------------------------------
2-- DynASM x86/x64 module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- See dynasm.lua for full copyright notice.
6------------------------------------------------------------------------------
7
8local x64 = x64
9
10-- Module information:
11local _info = {
12 arch = x64 and "x64" or "x86",
13 description = "DynASM x86/x64 module",
14 version = "1.3.0",
15 vernum = 10300,
16 release = "2011-05-05",
17 author = "Mike Pall",
18 license = "MIT",
19}
20
21-- Exported glue functions for the arch-specific module.
22local _M = { _info = _info }
23
24-- Cache library functions.
25local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
26local assert, unpack, setmetatable = assert, unpack, setmetatable
27local _s = string
28local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
29local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
30local concat, sort = table.concat, table.sort
31
32-- Inherited tables and callbacks.
33local g_opt, g_arch
34local wline, werror, wfatal, wwarn
35
36-- Action name list.
37-- CHECK: Keep this in sync with the C code!
38local action_names = {
39 -- int arg, 1 buffer pos:
40 "DISP", "IMM_S", "IMM_B", "IMM_W", "IMM_D", "IMM_WB", "IMM_DB",
41 -- action arg (1 byte), int arg, 1 buffer pos (reg/num):
42 "VREG", "SPACE", -- !x64: VREG support NYI.
43 -- ptrdiff_t arg, 1 buffer pos (address): !x64
44 "SETLABEL", "REL_A",
45 -- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
46 "REL_LG", "REL_PC",
47 -- action arg (1 byte) or int arg, 1 buffer pos (link):
48 "IMM_LG", "IMM_PC",
49 -- action arg (1 byte) or int arg, 1 buffer pos (offset):
50 "LABEL_LG", "LABEL_PC",
51 -- action arg (1 byte), 1 buffer pos (offset):
52 "ALIGN",
53 -- action args (2 bytes), no buffer pos.
54 "EXTERN",
55 -- action arg (1 byte), no buffer pos.
56 "ESC",
57 -- no action arg, no buffer pos.
58 "MARK",
59 -- action arg (1 byte), no buffer pos, terminal action:
60 "SECTION",
61 -- no args, no buffer pos, terminal action:
62 "STOP"
63}
64
65-- Maximum number of section buffer positions for dasm_put().
66-- CHECK: Keep this in sync with the C code!
67local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
68
69-- Action name -> action number (dynamically generated below).
70local map_action = {}
71-- First action number. Everything below does not need to be escaped.
72local actfirst = 256-#action_names
73
74-- Action list buffer and string (only used to remove dupes).
75local actlist = {}
76local actstr = ""
77
78-- Argument list for next dasm_put(). Start with offset 0 into action list.
79local actargs = { 0 }
80
81-- Current number of section buffer positions for dasm_put().
82local secpos = 1
83
84------------------------------------------------------------------------------
85
86-- Compute action numbers for action names.
87for n,name in ipairs(action_names) do
88 local num = actfirst + n - 1
89 map_action[name] = num
90end
91
92-- Dump action names and numbers.
93local function dumpactions(out)
94 out:write("DynASM encoding engine action codes:\n")
95 for n,name in ipairs(action_names) do
96 local num = map_action[name]
97 out:write(format(" %-10s %02X %d\n", name, num, num))
98 end
99 out:write("\n")
100end
101
102-- Write action list buffer as a huge static C array.
103local function writeactions(out, name)
104 local nn = #actlist
105 local last = actlist[nn] or 255
106 actlist[nn] = nil -- Remove last byte.
107 if nn == 0 then nn = 1 end
108 out:write("static const unsigned char ", name, "[", nn, "] = {\n")
109 local s = " "
110 for n,b in ipairs(actlist) do
111 s = s..b..","
112 if #s >= 75 then
113 assert(out:write(s, "\n"))
114 s = " "
115 end
116 end
117 out:write(s, last, "\n};\n\n") -- Add last byte back.
118end
119
120------------------------------------------------------------------------------
121
122-- Add byte to action list.
123local function wputxb(n)
124 assert(n >= 0 and n <= 255 and n % 1 == 0, "byte out of range")
125 actlist[#actlist+1] = n
126end
127
128-- Add action to list with optional arg. Advance buffer pos, too.
129local function waction(action, a, num)
130 wputxb(assert(map_action[action], "bad action name `"..action.."'"))
131 if a then actargs[#actargs+1] = a end
132 if a or num then secpos = secpos + (num or 1) end
133end
134
135-- Add call to embedded DynASM C code.
136local function wcall(func, args)
137 wline(format("dasm_%s(Dst, %s);", func, concat(args, ", ")), true)
138end
139
140-- Delete duplicate action list chunks. A tad slow, but so what.
141local function dedupechunk(offset)
142 local al, as = actlist, actstr
143 local chunk = char(unpack(al, offset+1, #al))
144 local orig = find(as, chunk, 1, true)
145 if orig then
146 actargs[1] = orig-1 -- Replace with original offset.
147 for i=offset+1,#al do al[i] = nil end -- Kill dupe.
148 else
149 actstr = as..chunk
150 end
151end
152
153-- Flush action list (intervening C code or buffer pos overflow).
154local function wflush(term)
155 local offset = actargs[1]
156 if #actlist == offset then return end -- Nothing to flush.
157 if not term then waction("STOP") end -- Terminate action list.
158 dedupechunk(offset)
159 wcall("put", actargs) -- Add call to dasm_put().
160 actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
161 secpos = 1 -- The actionlist offset occupies a buffer position, too.
162end
163
164-- Put escaped byte.
165local function wputb(n)
166 if n >= actfirst then waction("ESC") end -- Need to escape byte.
167 wputxb(n)
168end
169
170------------------------------------------------------------------------------
171
172-- Global label name -> global label number. With auto assignment on 1st use.
173local next_global = 10
174local map_global = setmetatable({}, { __index = function(t, name)
175 if not match(name, "^[%a_][%w_@]*$") then werror("bad global label") end
176 local n = next_global
177 if n > 246 then werror("too many global labels") end
178 next_global = n + 1
179 t[name] = n
180 return n
181end})
182
183-- Dump global labels.
184local function dumpglobals(out, lvl)
185 local t = {}
186 for name, n in pairs(map_global) do t[n] = name end
187 out:write("Global labels:\n")
188 for i=10,next_global-1 do
189 out:write(format(" %s\n", t[i]))
190 end
191 out:write("\n")
192end
193
194-- Write global label enum.
195local function writeglobals(out, prefix)
196 local t = {}
197 for name, n in pairs(map_global) do t[n] = name end
198 out:write("enum {\n")
199 for i=10,next_global-1 do
200 out:write(" ", prefix, gsub(t[i], "@.*", ""), ",\n")
201 end
202 out:write(" ", prefix, "_MAX\n};\n")
203end
204
205-- Write global label names.
206local function writeglobalnames(out, name)
207 local t = {}
208 for name, n in pairs(map_global) do t[n] = name end
209 out:write("static const char *const ", name, "[] = {\n")
210 for i=10,next_global-1 do
211 out:write(" \"", t[i], "\",\n")
212 end
213 out:write(" (const char *)0\n};\n")
214end
215
216------------------------------------------------------------------------------
217
218-- Extern label name -> extern label number. With auto assignment on 1st use.
219local next_extern = -1
220local map_extern = setmetatable({}, { __index = function(t, name)
221 -- No restrictions on the name for now.
222 local n = next_extern
223 if n < -256 then werror("too many extern labels") end
224 next_extern = n - 1
225 t[name] = n
226 return n
227end})
228
229-- Dump extern labels.
230local function dumpexterns(out, lvl)
231 local t = {}
232 for name, n in pairs(map_extern) do t[-n] = name end
233 out:write("Extern labels:\n")
234 for i=1,-next_extern-1 do
235 out:write(format(" %s\n", t[i]))
236 end
237 out:write("\n")
238end
239
240-- Write extern label names.
241local function writeexternnames(out, name)
242 local t = {}
243 for name, n in pairs(map_extern) do t[-n] = name end
244 out:write("static const char *const ", name, "[] = {\n")
245 for i=1,-next_extern-1 do
246 out:write(" \"", t[i], "\",\n")
247 end
248 out:write(" (const char *)0\n};\n")
249end
250
251------------------------------------------------------------------------------
252
253-- Arch-specific maps.
254local map_archdef = {} -- Ext. register name -> int. name.
255local map_reg_rev = {} -- Int. register name -> ext. name.
256local map_reg_num = {} -- Int. register name -> register number.
257local map_reg_opsize = {} -- Int. register name -> operand size.
258local map_reg_valid_base = {} -- Int. register name -> valid base register?
259local map_reg_valid_index = {} -- Int. register name -> valid index register?
260local map_reg_needrex = {} -- Int. register name -> need rex vs. no rex.
261local reg_list = {} -- Canonical list of int. register names.
262
263local map_type = {} -- Type name -> { ctype, reg }
264local ctypenum = 0 -- Type number (for _PTx macros).
265
266local addrsize = x64 and "q" or "d" -- Size for address operands.
267
268-- Helper functions to fill register maps.
269local function mkrmap(sz, cl, names)
270 local cname = format("@%s", sz)
271 reg_list[#reg_list+1] = cname
272 map_archdef[cl] = cname
273 map_reg_rev[cname] = cl
274 map_reg_num[cname] = -1
275 map_reg_opsize[cname] = sz
276 if sz == addrsize or sz == "d" then
277 map_reg_valid_base[cname] = true
278 map_reg_valid_index[cname] = true
279 end
280 if names then
281 for n,name in ipairs(names) do
282 local iname = format("@%s%x", sz, n-1)
283 reg_list[#reg_list+1] = iname
284 map_archdef[name] = iname
285 map_reg_rev[iname] = name
286 map_reg_num[iname] = n-1
287 map_reg_opsize[iname] = sz
288 if sz == "b" and n > 4 then map_reg_needrex[iname] = false end
289 if sz == addrsize or sz == "d" then
290 map_reg_valid_base[iname] = true
291 map_reg_valid_index[iname] = true
292 end
293 end
294 end
295 for i=0,(x64 and sz ~= "f") and 15 or 7 do
296 local needrex = sz == "b" and i > 3
297 local iname = format("@%s%x%s", sz, i, needrex and "R" or "")
298 if needrex then map_reg_needrex[iname] = true end
299 local name
300 if sz == "o" then name = format("xmm%d", i)
301 elseif sz == "f" then name = format("st%d", i)
302 else name = format("r%d%s", i, sz == addrsize and "" or sz) end
303 map_archdef[name] = iname
304 if not map_reg_rev[iname] then
305 reg_list[#reg_list+1] = iname
306 map_reg_rev[iname] = name
307 map_reg_num[iname] = i
308 map_reg_opsize[iname] = sz
309 if sz == addrsize or sz == "d" then
310 map_reg_valid_base[iname] = true
311 map_reg_valid_index[iname] = true
312 end
313 end
314 end
315 reg_list[#reg_list+1] = ""
316end
317
318-- Integer registers (qword, dword, word and byte sized).
319if x64 then
320 mkrmap("q", "Rq", {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"})
321end
322mkrmap("d", "Rd", {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"})
323mkrmap("w", "Rw", {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"})
324mkrmap("b", "Rb", {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"})
325map_reg_valid_index[map_archdef.esp] = false
326if x64 then map_reg_valid_index[map_archdef.rsp] = false end
327map_archdef["Ra"] = "@"..addrsize
328
329-- FP registers (internally tword sized, but use "f" as operand size).
330mkrmap("f", "Rf")
331
332-- SSE registers (oword sized, but qword and dword accessible).
333mkrmap("o", "xmm")
334
335-- Operand size prefixes to codes.
336local map_opsize = {
337 byte = "b", word = "w", dword = "d", qword = "q", oword = "o", tword = "t",
338 aword = addrsize,
339}
340
341-- Operand size code to number.
342local map_opsizenum = {
343 b = 1, w = 2, d = 4, q = 8, o = 16, t = 10,
344}
345
346-- Operand size code to name.
347local map_opsizename = {
348 b = "byte", w = "word", d = "dword", q = "qword", o = "oword", t = "tword",
349 f = "fpword",
350}
351
352-- Valid index register scale factors.
353local map_xsc = {
354 ["1"] = 0, ["2"] = 1, ["4"] = 2, ["8"] = 3,
355}
356
357-- Condition codes.
358local map_cc = {
359 o = 0, no = 1, b = 2, nb = 3, e = 4, ne = 5, be = 6, nbe = 7,
360 s = 8, ns = 9, p = 10, np = 11, l = 12, nl = 13, le = 14, nle = 15,
361 c = 2, nae = 2, nc = 3, ae = 3, z = 4, nz = 5, na = 6, a = 7,
362 pe = 10, po = 11, nge = 12, ge = 13, ng = 14, g = 15,
363}
364
365
366-- Reverse defines for registers.
367function _M.revdef(s)
368 return gsub(s, "@%w+", map_reg_rev)
369end
370
371-- Dump register names and numbers
372local function dumpregs(out)
373 out:write("Register names, sizes and internal numbers:\n")
374 for _,reg in ipairs(reg_list) do
375 if reg == "" then
376 out:write("\n")
377 else
378 local name = map_reg_rev[reg]
379 local num = map_reg_num[reg]
380 local opsize = map_opsizename[map_reg_opsize[reg]]
381 out:write(format(" %-5s %-8s %s\n", name, opsize,
382 num < 0 and "(variable)" or num))
383 end
384 end
385end
386
387------------------------------------------------------------------------------
388
389-- Put action for label arg (IMM_LG, IMM_PC, REL_LG, REL_PC).
390local function wputlabel(aprefix, imm, num)
391 if type(imm) == "number" then
392 if imm < 0 then
393 waction("EXTERN")
394 wputxb(aprefix == "IMM_" and 0 or 1)
395 imm = -imm-1
396 else
397 waction(aprefix.."LG", nil, num);
398 end
399 wputxb(imm)
400 else
401 waction(aprefix.."PC", imm, num)
402 end
403end
404
405-- Put signed byte or arg.
406local function wputsbarg(n)
407 if type(n) == "number" then
408 if n < -128 or n > 127 then
409 werror("signed immediate byte out of range")
410 end
411 if n < 0 then n = n + 256 end
412 wputb(n)
413 else waction("IMM_S", n) end
414end
415
416-- Put unsigned byte or arg.
417local function wputbarg(n)
418 if type(n) == "number" then
419 if n < 0 or n > 255 then
420 werror("unsigned immediate byte out of range")
421 end
422 wputb(n)
423 else waction("IMM_B", n) end
424end
425
426-- Put unsigned word or arg.
427local function wputwarg(n)
428 if type(n) == "number" then
429 if n < 0 or n > 65535 then
430 werror("unsigned immediate word out of range")
431 end
432 local r = n%256; n = (n-r)/256; wputb(r); wputb(n);
433 else waction("IMM_W", n) end
434end
435
436-- Put signed or unsigned dword or arg.
437local function wputdarg(n)
438 local tn = type(n)
439 if tn == "number" then
440 if n < 0 then n = n + 4294967296 end
441 local r = n%256; n = (n-r)/256; wputb(r);
442 r = n%256; n = (n-r)/256; wputb(r);
443 r = n%256; n = (n-r)/256; wputb(r); wputb(n);
444 elseif tn == "table" then
445 wputlabel("IMM_", n[1], 1)
446 else
447 waction("IMM_D", n)
448 end
449end
450
451-- Put operand-size dependent number or arg (defaults to dword).
452local function wputszarg(sz, n)
453 if not sz or sz == "d" or sz == "q" then wputdarg(n)
454 elseif sz == "w" then wputwarg(n)
455 elseif sz == "b" then wputbarg(n)
456 elseif sz == "s" then wputsbarg(n)
457 else werror("bad operand size") end
458end
459
460-- Put multi-byte opcode with operand-size dependent modifications.
461local function wputop(sz, op, rex)
462 local r
463 if rex ~= 0 and not x64 then werror("bad operand size") end
464 if sz == "w" then wputb(102) end
465 -- Needs >32 bit numbers, but only for crc32 eax, word [ebx]
466 if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end
467 if op >= 16777216 then r = op % 16777216 wputb((op-r) / 16777216) op = r end
468 if op >= 65536 then
469 if rex ~= 0 then
470 local opc3 = op - op % 256
471 if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then
472 wputb(64 + rex % 16); rex = 0
473 end
474 end
475 r = op % 65536 wputb((op-r) / 65536) op = r
476 end
477 if op >= 256 then
478 r = op % 256
479 local b = (op-r) / 256
480 if b == 15 and rex ~= 0 then wputb(64 + rex % 16); rex = 0 end
481 wputb(b)
482 op = r
483 end
484 if rex ~= 0 then wputb(64 + rex % 16) end
485 if sz == "b" then op = op - 1 end
486 wputb(op)
487end
488
489-- Put ModRM or SIB formatted byte.
490local function wputmodrm(m, s, rm, vs, vrm)
491 assert(m < 4 and s < 16 and rm < 16, "bad modrm operands")
492 wputb(64*m + 8*(s%8) + (rm%8))
493end
494
495-- Put ModRM/SIB plus optional displacement.
496local function wputmrmsib(t, imark, s, vsreg)
497 local vreg, vxreg
498 local reg, xreg = t.reg, t.xreg
499 if reg and reg < 0 then reg = 0; vreg = t.vreg end
500 if xreg and xreg < 0 then xreg = 0; vxreg = t.vxreg end
501 if s < 0 then s = 0 end
502
503 -- Register mode.
504 if sub(t.mode, 1, 1) == "r" then
505 wputmodrm(3, s, reg)
506 if vsreg then waction("VREG", vsreg); wputxb(2) end
507 if vreg then waction("VREG", vreg); wputxb(0) end
508 return
509 end
510
511 local disp = t.disp
512 local tdisp = type(disp)
513 -- No base register?
514 if not reg then
515 local riprel = false
516 if xreg then
517 -- Indexed mode with index register only.
518 -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
519 wputmodrm(0, s, 4)
520 if imark == "I" then waction("MARK") end
521 if vsreg then waction("VREG", vsreg); wputxb(2) end
522 wputmodrm(t.xsc, xreg, 5)
523 if vxreg then waction("VREG", vxreg); wputxb(3) end
524 else
525 -- Pure 32 bit displacement.
526 if x64 and tdisp ~= "table" then
527 wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)
528 if imark == "I" then waction("MARK") end
529 wputmodrm(0, 4, 5)
530 else
531 riprel = x64
532 wputmodrm(0, s, 5) -- [disp|rip-label] -> (0, s, ebp)
533 if imark == "I" then waction("MARK") end
534 end
535 if vsreg then waction("VREG", vsreg); wputxb(2) end
536 end
537 if riprel then -- Emit rip-relative displacement.
538 if match("UWSiI", imark) then
539 werror("NYI: rip-relative displacement followed by immediate")
540 end
541 -- The previous byte in the action buffer cannot be 0xe9 or 0x80-0x8f.
542 wputlabel("REL_", disp[1], 2)
543 else
544 wputdarg(disp)
545 end
546 return
547 end
548
549 local m
550 if tdisp == "number" then -- Check displacement size at assembly time.
551 if disp == 0 and (reg%8) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too)
552 if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0]
553 elseif disp >= -128 and disp <= 127 then m = 1
554 else m = 2 end
555 elseif tdisp == "table" then
556 m = 2
557 end
558
559 -- Index register present or esp as base register: need SIB encoding.
560 if xreg or (reg%8) == 4 then
561 wputmodrm(m or 2, s, 4) -- ModRM.
562 if m == nil or imark == "I" then waction("MARK") end
563 if vsreg then waction("VREG", vsreg); wputxb(2) end
564 wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.
565 if vxreg then waction("VREG", vxreg); wputxb(3) end
566 if vreg then waction("VREG", vreg); wputxb(1) end
567 else
568 wputmodrm(m or 2, s, reg) -- ModRM.
569 if (imark == "I" and (m == 1 or m == 2)) or
570 (m == nil and (vsreg or vreg)) then waction("MARK") end
571 if vsreg then waction("VREG", vsreg); wputxb(2) end
572 if vreg then waction("VREG", vreg); wputxb(1) end
573 end
574
575 -- Put displacement.
576 if m == 1 then wputsbarg(disp)
577 elseif m == 2 then wputdarg(disp)
578 elseif m == nil then waction("DISP", disp) end
579end
580
581------------------------------------------------------------------------------
582
583-- Return human-readable operand mode string.
584local function opmodestr(op, args)
585 local m = {}
586 for i=1,#args do
587 local a = args[i]
588 m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or "?")
589 end
590 return op.." "..concat(m, ",")
591end
592
593-- Convert number to valid integer or nil.
594local function toint(expr)
595 local n = tonumber(expr)
596 if n then
597 if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
598 werror("bad integer number `"..expr.."'")
599 end
600 return n
601 end
602end
603
604-- Parse immediate expression.
605local function immexpr(expr)
606 -- &expr (pointer)
607 if sub(expr, 1, 1) == "&" then
608 return "iPJ", format("(ptrdiff_t)(%s)", sub(expr,2))
609 end
610
611 local prefix = sub(expr, 1, 2)
612 -- =>expr (pc label reference)
613 if prefix == "=>" then
614 return "iJ", sub(expr, 3)
615 end
616 -- ->name (global label reference)
617 if prefix == "->" then
618 return "iJ", map_global[sub(expr, 3)]
619 end
620
621 -- [<>][1-9] (local label reference)
622 local dir, lnum = match(expr, "^([<>])([1-9])$")
623 if dir then -- Fwd: 247-255, Bkwd: 1-9.
624 return "iJ", lnum + (dir == ">" and 246 or 0)
625 end
626
627 local extname = match(expr, "^extern%s+(%S+)$")
628 if extname then
629 return "iJ", map_extern[extname]
630 end
631
632 -- expr (interpreted as immediate)
633 return "iI", expr
634end
635
636-- Parse displacement expression: +-num, +-expr, +-opsize*num
637local function dispexpr(expr)
638 local disp = expr == "" and 0 or toint(expr)
639 if disp then return disp end
640 local c, dispt = match(expr, "^([+-])%s*(.+)$")
641 if c == "+" then
642 expr = dispt
643 elseif not c then
644 werror("bad displacement expression `"..expr.."'")
645 end
646 local opsize, tailops = match(dispt, "^(%w+)%s*%*%s*(.+)$")
647 local ops, imm = map_opsize[opsize], toint(tailops)
648 if ops and imm then
649 if c == "-" then imm = -imm end
650 return imm*map_opsizenum[ops]
651 end
652 local mode, iexpr = immexpr(dispt)
653 if mode == "iJ" then
654 if c == "-" then werror("cannot invert label reference") end
655 return { iexpr }
656 end
657 return expr -- Need to return original signed expression.
658end
659
660-- Parse register or type expression.
661local function rtexpr(expr)
662 if not expr then return end
663 local tname, ovreg = match(expr, "^([%w_]+):(@[%w_]+)$")
664 local tp = map_type[tname or expr]
665 if tp then
666 local reg = ovreg or tp.reg
667 local rnum = map_reg_num[reg]
668 if not rnum then
669 werror("type `"..(tname or expr).."' needs a register override")
670 end
671 if not map_reg_valid_base[reg] then
672 werror("bad base register override `"..(map_reg_rev[reg] or reg).."'")
673 end
674 return reg, rnum, tp
675 end
676 return expr, map_reg_num[expr]
677end
678
679-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
680local function parseoperand(param)
681 local t = {}
682
683 local expr = param
684 local opsize, tailops = match(param, "^(%w+)%s*(.+)$")
685 if opsize then
686 t.opsize = map_opsize[opsize]
687 if t.opsize then expr = tailops end
688 end
689
690 local br = match(expr, "^%[%s*(.-)%s*%]$")
691 repeat
692 if br then
693 t.mode = "xm"
694
695 -- [disp]
696 t.disp = toint(br)
697 if t.disp then
698 t.mode = x64 and "xm" or "xmO"
699 break
700 end
701
702 -- [reg...]
703 local tp
704 local reg, tailr = match(br, "^([@%w_:]+)%s*(.*)$")
705 reg, t.reg, tp = rtexpr(reg)
706 if not t.reg then
707 -- [expr]
708 t.mode = x64 and "xm" or "xmO"
709 t.disp = dispexpr("+"..br)
710 break
711 end
712
713 if t.reg == -1 then
714 t.vreg, tailr = match(tailr, "^(%b())(.*)$")
715 if not t.vreg then werror("bad variable register expression") end
716 end
717
718 -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr]
719 local xsc, tailsc = match(tailr, "^%*%s*([1248])%s*(.*)$")
720 if xsc then
721 if not map_reg_valid_index[reg] then
722 werror("bad index register `"..map_reg_rev[reg].."'")
723 end
724 t.xsc = map_xsc[xsc]
725 t.xreg = t.reg
726 t.vxreg = t.vreg
727 t.reg = nil
728 t.vreg = nil
729 t.disp = dispexpr(tailsc)
730 break
731 end
732 if not map_reg_valid_base[reg] then
733 werror("bad base register `"..map_reg_rev[reg].."'")
734 end
735
736 -- [reg] or [reg+-disp]
737 t.disp = toint(tailr) or (tailr == "" and 0)
738 if t.disp then break end
739
740 -- [reg+xreg...]
741 local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$")
742 xreg, t.xreg, tp = rtexpr(xreg)
743 if not t.xreg then
744 -- [reg+-expr]
745 t.disp = dispexpr(tailr)
746 break
747 end
748 if not map_reg_valid_index[xreg] then
749 werror("bad index register `"..map_reg_rev[xreg].."'")
750 end
751
752 if t.xreg == -1 then
753 t.vxreg, tailx = match(tailx, "^(%b())(.*)$")
754 if not t.vxreg then werror("bad variable register expression") end
755 end
756
757 -- [reg+xreg*xsc...]
758 local xsc, tailsc = match(tailx, "^%*%s*([1248])%s*(.*)$")
759 if xsc then
760 t.xsc = map_xsc[xsc]
761 tailx = tailsc
762 end
763
764 -- [...] or [...+-disp] or [...+-expr]
765 t.disp = dispexpr(tailx)
766 else
767 -- imm or opsize*imm
768 local imm = toint(expr)
769 if not imm and sub(expr, 1, 1) == "*" and t.opsize then
770 imm = toint(sub(expr, 2))
771 if imm then
772 imm = imm * map_opsizenum[t.opsize]
773 t.opsize = nil
774 end
775 end
776 if imm then
777 if t.opsize then werror("bad operand size override") end
778 local m = "i"
779 if imm == 1 then m = m.."1" end
780 if imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end
781 if imm >= -128 and imm <= 127 then m = m.."S" end
782 t.imm = imm
783 t.mode = m
784 break
785 end
786
787 local tp
788 local reg, tailr = match(expr, "^([@%w_:]+)%s*(.*)$")
789 reg, t.reg, tp = rtexpr(reg)
790 if t.reg then
791 if t.reg == -1 then
792 t.vreg, tailr = match(tailr, "^(%b())(.*)$")
793 if not t.vreg then werror("bad variable register expression") end
794 end
795 -- reg
796 if tailr == "" then
797 if t.opsize then werror("bad operand size override") end
798 t.opsize = map_reg_opsize[reg]
799 if t.opsize == "f" then
800 t.mode = t.reg == 0 and "fF" or "f"
801 else
802 if reg == "@w4" or (x64 and reg == "@d4") then
803 wwarn("bad idea, try again with `"..(x64 and "rsp'" or "esp'"))
804 end
805 t.mode = t.reg == 0 and "rmR" or (reg == "@b1" and "rmC" or "rm")
806 end
807 t.needrex = map_reg_needrex[reg]
808 break
809 end
810
811 -- type[idx], type[idx].field, type->field -> [reg+offset_expr]
812 if not tp then werror("bad operand `"..param.."'") end
813 t.mode = "xm"
814 t.disp = format(tp.ctypefmt, tailr)
815 else
816 t.mode, t.imm = immexpr(expr)
817 if sub(t.mode, -1) == "J" then
818 if t.opsize and t.opsize ~= addrsize then
819 werror("bad operand size override")
820 end
821 t.opsize = addrsize
822 end
823 end
824 end
825 until true
826 return t
827end
828
829------------------------------------------------------------------------------
830-- x86 Template String Description
831-- ===============================
832--
833-- Each template string is a list of [match:]pattern pairs,
834-- separated by "|". The first match wins. No match means a
835-- bad or unsupported combination of operand modes or sizes.
836--
837-- The match part and the ":" is omitted if the operation has
838-- no operands. Otherwise the first N characters are matched
839-- against the mode strings of each of the N operands.
840--
841-- The mode string for each operand type is (see parseoperand()):
842-- Integer register: "rm", +"R" for eax, ax, al, +"C" for cl
843-- FP register: "f", +"F" for st0
844-- Index operand: "xm", +"O" for [disp] (pure offset)
845-- Immediate: "i", +"S" for signed 8 bit, +"1" for 1,
846-- +"I" for arg, +"P" for pointer
847-- Any: +"J" for valid jump targets
848--
849-- So a match character "m" (mixed) matches both an integer register
850-- and an index operand (to be encoded with the ModRM/SIB scheme).
851-- But "r" matches only a register and "x" only an index operand
852-- (e.g. for FP memory access operations).
853--
854-- The operand size match string starts right after the mode match
855-- characters and ends before the ":". "dwb" or "qdwb" is assumed, if empty.
856-- The effective data size of the operation is matched against this list.
857--
858-- If only the regular "b", "w", "d", "q", "t" operand sizes are
859-- present, then all operands must be the same size. Unspecified sizes
860-- are ignored, but at least one operand must have a size or the pattern
861-- won't match (use the "byte", "word", "dword", "qword", "tword"
862-- operand size overrides. E.g.: mov dword [eax], 1).
863--
864-- If the list has a "1" or "2" prefix, the operand size is taken
865-- from the respective operand and any other operand sizes are ignored.
866-- If the list contains only ".", all operand sizes are ignored.
867-- If the list has a "/" prefix, the concatenated (mixed) operand sizes
868-- are compared to the match.
869--
870-- E.g. "rrdw" matches for either two dword registers or two word
871-- registers. "Fx2dq" matches an st0 operand plus an index operand
872-- pointing to a dword (float) or qword (double).
873--
874-- Every character after the ":" is part of the pattern string:
875-- Hex chars are accumulated to form the opcode (left to right).
876-- "n" disables the standard opcode mods
877-- (otherwise: -1 for "b", o16 prefix for "w", rex.w for "q")
878-- "X" Force REX.W.
879-- "r"/"R" adds the reg. number from the 1st/2nd operand to the opcode.
880-- "m"/"M" generates ModRM/SIB from the 1st/2nd operand.
881-- The spare 3 bits are either filled with the last hex digit or
882-- the result from a previous "r"/"R". The opcode is restored.
883--
884-- All of the following characters force a flush of the opcode:
885-- "o"/"O" stores a pure 32 bit disp (offset) from the 1st/2nd operand.
886-- "S" stores a signed 8 bit immediate from the last operand.
887-- "U" stores an unsigned 8 bit immediate from the last operand.
888-- "W" stores an unsigned 16 bit immediate from the last operand.
889-- "i" stores an operand sized immediate from the last operand.
890-- "I" dito, but generates an action code to optionally modify
891-- the opcode (+2) for a signed 8 bit immediate.
892-- "J" generates one of the REL action codes from the last operand.
893--
894------------------------------------------------------------------------------
895
896-- Template strings for x86 instructions. Ordered by first opcode byte.
897-- Unimplemented opcodes (deliberate omissions) are marked with *.
898local map_op = {
899 -- 00-05: add...
900 -- 06: *push es
901 -- 07: *pop es
902 -- 08-0D: or...
903 -- 0E: *push cs
904 -- 0F: two byte opcode prefix
905 -- 10-15: adc...
906 -- 16: *push ss
907 -- 17: *pop ss
908 -- 18-1D: sbb...
909 -- 1E: *push ds
910 -- 1F: *pop ds
911 -- 20-25: and...
912 es_0 = "26",
913 -- 27: *daa
914 -- 28-2D: sub...
915 cs_0 = "2E",
916 -- 2F: *das
917 -- 30-35: xor...
918 ss_0 = "36",
919 -- 37: *aaa
920 -- 38-3D: cmp...
921 ds_0 = "3E",
922 -- 3F: *aas
923 inc_1 = x64 and "m:FF0m" or "rdw:40r|m:FF0m",
924 dec_1 = x64 and "m:FF1m" or "rdw:48r|m:FF1m",
925 push_1 = (x64 and "rq:n50r|rw:50r|mq:nFF6m|mw:FF6m" or
926 "rdw:50r|mdw:FF6m").."|S.:6AS|ib:n6Ai|i.:68i",
927 pop_1 = x64 and "rq:n58r|rw:58r|mq:n8F0m|mw:8F0m" or "rdw:58r|mdw:8F0m",
928 -- 60: *pusha, *pushad, *pushaw
929 -- 61: *popa, *popad, *popaw
930 -- 62: *bound rdw,x
931 -- 63: x86: *arpl mw,rw
932 movsxd_2 = x64 and "rm/qd:63rM",
933 fs_0 = "64",
934 gs_0 = "65",
935 o16_0 = "66",
936 a16_0 = not x64 and "67" or nil,
937 a32_0 = x64 and "67",
938 -- 68: push idw
939 -- 69: imul rdw,mdw,idw
940 -- 6A: push ib
941 -- 6B: imul rdw,mdw,S
942 -- 6C: *insb
943 -- 6D: *insd, *insw
944 -- 6E: *outsb
945 -- 6F: *outsd, *outsw
946 -- 70-7F: jcc lb
947 -- 80: add... mb,i
948 -- 81: add... mdw,i
949 -- 82: *undefined
950 -- 83: add... mdw,S
951 test_2 = "mr:85Rm|rm:85rM|Ri:A9ri|mi:F70mi",
952 -- 86: xchg rb,mb
953 -- 87: xchg rdw,mdw
954 -- 88: mov mb,r
955 -- 89: mov mdw,r
956 -- 8A: mov r,mb
957 -- 8B: mov r,mdw
958 -- 8C: *mov mdw,seg
959 lea_2 = "rx1dq:8DrM",
960 -- 8E: *mov seg,mdw
961 -- 8F: pop mdw
962 nop_0 = "90",
963 xchg_2 = "Rrqdw:90R|rRqdw:90r|rm:87rM|mr:87Rm",
964 cbw_0 = "6698",
965 cwde_0 = "98",
966 cdqe_0 = "4898",
967 cwd_0 = "6699",
968 cdq_0 = "99",
969 cqo_0 = "4899",
970 -- 9A: *call iw:idw
971 wait_0 = "9B",
972 fwait_0 = "9B",
973 pushf_0 = "9C",
974 pushfd_0 = not x64 and "9C",
975 pushfq_0 = x64 and "9C",
976 popf_0 = "9D",
977 popfd_0 = not x64 and "9D",
978 popfq_0 = x64 and "9D",
979 sahf_0 = "9E",
980 lahf_0 = "9F",
981 mov_2 = "OR:A3o|RO:A1O|mr:89Rm|rm:8BrM|rib:nB0ri|ridw:B8ri|mi:C70mi",
982 movsb_0 = "A4",
983 movsw_0 = "66A5",
984 movsd_0 = "A5",
985 cmpsb_0 = "A6",
986 cmpsw_0 = "66A7",
987 cmpsd_0 = "A7",
988 -- A8: test Rb,i
989 -- A9: test Rdw,i
990 stosb_0 = "AA",
991 stosw_0 = "66AB",
992 stosd_0 = "AB",
993 lodsb_0 = "AC",
994 lodsw_0 = "66AD",
995 lodsd_0 = "AD",
996 scasb_0 = "AE",
997 scasw_0 = "66AF",
998 scasd_0 = "AF",
999 -- B0-B7: mov rb,i
1000 -- B8-BF: mov rdw,i
1001 -- C0: rol... mb,i
1002 -- C1: rol... mdw,i
1003 ret_1 = "i.:nC2W",
1004 ret_0 = "C3",
1005 -- C4: *les rdw,mq
1006 -- C5: *lds rdw,mq
1007 -- C6: mov mb,i
1008 -- C7: mov mdw,i
1009 -- C8: *enter iw,ib
1010 leave_0 = "C9",
1011 -- CA: *retf iw
1012 -- CB: *retf
1013 int3_0 = "CC",
1014 int_1 = "i.:nCDU",
1015 into_0 = "CE",
1016 -- CF: *iret
1017 -- D0: rol... mb,1
1018 -- D1: rol... mdw,1
1019 -- D2: rol... mb,cl
1020 -- D3: rol... mb,cl
1021 -- D4: *aam ib
1022 -- D5: *aad ib
1023 -- D6: *salc
1024 -- D7: *xlat
1025 -- D8-DF: floating point ops
1026 -- E0: *loopne
1027 -- E1: *loope
1028 -- E2: *loop
1029 -- E3: *jcxz, *jecxz
1030 -- E4: *in Rb,ib
1031 -- E5: *in Rdw,ib
1032 -- E6: *out ib,Rb
1033 -- E7: *out ib,Rdw
1034 call_1 = x64 and "mq:nFF2m|J.:E8nJ" or "md:FF2m|J.:E8J",
1035 jmp_1 = x64 and "mq:nFF4m|J.:E9nJ" or "md:FF4m|J.:E9J", -- short: EB
1036 -- EA: *jmp iw:idw
1037 -- EB: jmp ib
1038 -- EC: *in Rb,dx
1039 -- ED: *in Rdw,dx
1040 -- EE: *out dx,Rb
1041 -- EF: *out dx,Rdw
1042 -- F0: *lock
1043 int1_0 = "F1",
1044 repne_0 = "F2",
1045 repnz_0 = "F2",
1046 rep_0 = "F3",
1047 repe_0 = "F3",
1048 repz_0 = "F3",
1049 -- F4: *hlt
1050 cmc_0 = "F5",
1051 -- F6: test... mb,i; div... mb
1052 -- F7: test... mdw,i; div... mdw
1053 clc_0 = "F8",
1054 stc_0 = "F9",
1055 -- FA: *cli
1056 cld_0 = "FC",
1057 std_0 = "FD",
1058 -- FE: inc... mb
1059 -- FF: inc... mdw
1060
1061 -- misc ops
1062 not_1 = "m:F72m",
1063 neg_1 = "m:F73m",
1064 mul_1 = "m:F74m",
1065 imul_1 = "m:F75m",
1066 div_1 = "m:F76m",
1067 idiv_1 = "m:F77m",
1068
1069 imul_2 = "rmqdw:0FAFrM|rIqdw:69rmI|rSqdw:6BrmS|riqdw:69rmi",
1070 imul_3 = "rmIqdw:69rMI|rmSqdw:6BrMS|rmiqdw:69rMi",
1071
1072 movzx_2 = "rm/db:0FB6rM|rm/qb:|rm/wb:0FB6rM|rm/dw:0FB7rM|rm/qw:",
1073 movsx_2 = "rm/db:0FBErM|rm/qb:|rm/wb:0FBErM|rm/dw:0FBFrM|rm/qw:",
1074
1075 bswap_1 = "rqd:0FC8r",
1076 bsf_2 = "rmqdw:0FBCrM",
1077 bsr_2 = "rmqdw:0FBDrM",
1078 bt_2 = "mrqdw:0FA3Rm|miqdw:0FBA4mU",
1079 btc_2 = "mrqdw:0FBBRm|miqdw:0FBA7mU",
1080 btr_2 = "mrqdw:0FB3Rm|miqdw:0FBA6mU",
1081 bts_2 = "mrqdw:0FABRm|miqdw:0FBA5mU",
1082
1083 rdtsc_0 = "0F31", -- P1+
1084 cpuid_0 = "0FA2", -- P1+
1085
1086 -- floating point ops
1087 fst_1 = "ff:DDD0r|xd:D92m|xq:nDD2m",
1088 fstp_1 = "ff:DDD8r|xd:D93m|xq:nDD3m|xt:DB7m",
1089 fld_1 = "ff:D9C0r|xd:D90m|xq:nDD0m|xt:DB5m",
1090
1091 fpop_0 = "DDD8", -- Alias for fstp st0.
1092
1093 fist_1 = "xw:nDF2m|xd:DB2m",
1094 fistp_1 = "xw:nDF3m|xd:DB3m|xq:nDF7m",
1095 fild_1 = "xw:nDF0m|xd:DB0m|xq:nDF5m",
1096
1097 fxch_0 = "D9C9",
1098 fxch_1 = "ff:D9C8r",
1099 fxch_2 = "fFf:D9C8r|Fff:D9C8R",
1100
1101 fucom_1 = "ff:DDE0r",
1102 fucom_2 = "Fff:DDE0R",
1103 fucomp_1 = "ff:DDE8r",
1104 fucomp_2 = "Fff:DDE8R",
1105 fucomi_1 = "ff:DBE8r", -- P6+
1106 fucomi_2 = "Fff:DBE8R", -- P6+
1107 fucomip_1 = "ff:DFE8r", -- P6+
1108 fucomip_2 = "Fff:DFE8R", -- P6+
1109 fcomi_1 = "ff:DBF0r", -- P6+
1110 fcomi_2 = "Fff:DBF0R", -- P6+
1111 fcomip_1 = "ff:DFF0r", -- P6+
1112 fcomip_2 = "Fff:DFF0R", -- P6+
1113 fucompp_0 = "DAE9",
1114 fcompp_0 = "DED9",
1115
1116 fldcw_1 = "xw:nD95m",
1117 fstcw_1 = "xw:n9BD97m",
1118 fnstcw_1 = "xw:nD97m",
1119 fstsw_1 = "Rw:n9BDFE0|xw:n9BDD7m",
1120 fnstsw_1 = "Rw:nDFE0|xw:nDD7m",
1121 fclex_0 = "9BDBE2",
1122 fnclex_0 = "DBE2",
1123
1124 fnop_0 = "D9D0",
1125 -- D9D1-D9DF: unassigned
1126
1127 fchs_0 = "D9E0",
1128 fabs_0 = "D9E1",
1129 -- D9E2: unassigned
1130 -- D9E3: unassigned
1131 ftst_0 = "D9E4",
1132 fxam_0 = "D9E5",
1133 -- D9E6: unassigned
1134 -- D9E7: unassigned
1135 fld1_0 = "D9E8",
1136 fldl2t_0 = "D9E9",
1137 fldl2e_0 = "D9EA",
1138 fldpi_0 = "D9EB",
1139 fldlg2_0 = "D9EC",
1140 fldln2_0 = "D9ED",
1141 fldz_0 = "D9EE",
1142 -- D9EF: unassigned
1143
1144 f2xm1_0 = "D9F0",
1145 fyl2x_0 = "D9F1",
1146 fptan_0 = "D9F2",
1147 fpatan_0 = "D9F3",
1148 fxtract_0 = "D9F4",
1149 fprem1_0 = "D9F5",
1150 fdecstp_0 = "D9F6",
1151 fincstp_0 = "D9F7",
1152 fprem_0 = "D9F8",
1153 fyl2xp1_0 = "D9F9",
1154 fsqrt_0 = "D9FA",
1155 fsincos_0 = "D9FB",
1156 frndint_0 = "D9FC",
1157 fscale_0 = "D9FD",
1158 fsin_0 = "D9FE",
1159 fcos_0 = "D9FF",
1160
1161 -- SSE, SSE2
1162 andnpd_2 = "rmo:660F55rM",
1163 andnps_2 = "rmo:0F55rM",
1164 andpd_2 = "rmo:660F54rM",
1165 andps_2 = "rmo:0F54rM",
1166 clflush_1 = "x.:0FAE7m",
1167 cmppd_3 = "rmio:660FC2rMU",
1168 cmpps_3 = "rmio:0FC2rMU",
1169 cmpsd_3 = "rrio:F20FC2rMU|rxi/oq:",
1170 cmpss_3 = "rrio:F30FC2rMU|rxi/od:",
1171 comisd_2 = "rro:660F2FrM|rx/oq:",
1172 comiss_2 = "rro:0F2FrM|rx/od:",
1173 cvtdq2pd_2 = "rro:F30FE6rM|rx/oq:",
1174 cvtdq2ps_2 = "rmo:0F5BrM",
1175 cvtpd2dq_2 = "rmo:F20FE6rM",
1176 cvtpd2ps_2 = "rmo:660F5ArM",
1177 cvtpi2pd_2 = "rx/oq:660F2ArM",
1178 cvtpi2ps_2 = "rx/oq:0F2ArM",
1179 cvtps2dq_2 = "rmo:660F5BrM",
1180 cvtps2pd_2 = "rro:0F5ArM|rx/oq:",
1181 cvtsd2si_2 = "rr/do:F20F2DrM|rr/qo:|rx/dq:|rxq:",
1182 cvtsd2ss_2 = "rro:F20F5ArM|rx/oq:",
1183 cvtsi2sd_2 = "rm/od:F20F2ArM|rm/oq:F20F2ArXM",
1184 cvtsi2ss_2 = "rm/od:F30F2ArM|rm/oq:F30F2ArXM",
1185 cvtss2sd_2 = "rro:F30F5ArM|rx/od:",
1186 cvtss2si_2 = "rr/do:F20F2CrM|rr/qo:|rxd:|rx/qd:",
1187 cvttpd2dq_2 = "rmo:660FE6rM",
1188 cvttps2dq_2 = "rmo:F30F5BrM",
1189 cvttsd2si_2 = "rr/do:F20F2CrM|rr/qo:|rx/dq:|rxq:",
1190 cvttss2si_2 = "rr/do:F30F2CrM|rr/qo:|rxd:|rx/qd:",
1191 ldmxcsr_1 = "xd:0FAE2m",
1192 lfence_0 = "0FAEE8",
1193 maskmovdqu_2 = "rro:660FF7rM",
1194 mfence_0 = "0FAEF0",
1195 movapd_2 = "rmo:660F28rM|mro:660F29Rm",
1196 movaps_2 = "rmo:0F28rM|mro:0F29Rm",
1197 movd_2 = "rm/od:660F6ErM|rm/oq:660F6ErXM|mr/do:660F7ERm|mr/qo:",
1198 movdqa_2 = "rmo:660F6FrM|mro:660F7FRm",
1199 movdqu_2 = "rmo:F30F6FrM|mro:F30F7FRm",
1200 movhlps_2 = "rro:0F12rM",
1201 movhpd_2 = "rx/oq:660F16rM|xr/qo:n660F17Rm",
1202 movhps_2 = "rx/oq:0F16rM|xr/qo:n0F17Rm",
1203 movlhps_2 = "rro:0F16rM",
1204 movlpd_2 = "rx/oq:660F12rM|xr/qo:n660F13Rm",
1205 movlps_2 = "rx/oq:0F12rM|xr/qo:n0F13Rm",
1206 movmskpd_2 = "rr/do:660F50rM",
1207 movmskps_2 = "rr/do:0F50rM",
1208 movntdq_2 = "xro:660FE7Rm",
1209 movnti_2 = "xrqd:0FC3Rm",
1210 movntpd_2 = "xro:660F2BRm",
1211 movntps_2 = "xro:0F2BRm",
1212 movq_2 = "rro:F30F7ErM|rx/oq:|xr/qo:n660FD6Rm",
1213 movsd_2 = "rro:F20F10rM|rx/oq:|xr/qo:nF20F11Rm",
1214 movss_2 = "rro:F30F10rM|rx/od:|xr/do:F30F11Rm",
1215 movupd_2 = "rmo:660F10rM|mro:660F11Rm",
1216 movups_2 = "rmo:0F10rM|mro:0F11Rm",
1217 orpd_2 = "rmo:660F56rM",
1218 orps_2 = "rmo:0F56rM",
1219 packssdw_2 = "rmo:660F6BrM",
1220 packsswb_2 = "rmo:660F63rM",
1221 packuswb_2 = "rmo:660F67rM",
1222 paddb_2 = "rmo:660FFCrM",
1223 paddd_2 = "rmo:660FFErM",
1224 paddq_2 = "rmo:660FD4rM",
1225 paddsb_2 = "rmo:660FECrM",
1226 paddsw_2 = "rmo:660FEDrM",
1227 paddusb_2 = "rmo:660FDCrM",
1228 paddusw_2 = "rmo:660FDDrM",
1229 paddw_2 = "rmo:660FFDrM",
1230 pand_2 = "rmo:660FDBrM",
1231 pandn_2 = "rmo:660FDFrM",
1232 pause_0 = "F390",
1233 pavgb_2 = "rmo:660FE0rM",
1234 pavgw_2 = "rmo:660FE3rM",
1235 pcmpeqb_2 = "rmo:660F74rM",
1236 pcmpeqd_2 = "rmo:660F76rM",
1237 pcmpeqw_2 = "rmo:660F75rM",
1238 pcmpgtb_2 = "rmo:660F64rM",
1239 pcmpgtd_2 = "rmo:660F66rM",
1240 pcmpgtw_2 = "rmo:660F65rM",
1241 pextrw_3 = "rri/do:660FC5rMU|xri/wo:660F3A15nrMU", -- Mem op: SSE4.1 only.
1242 pinsrw_3 = "rri/od:660FC4rMU|rxi/ow:",
1243 pmaddwd_2 = "rmo:660FF5rM",
1244 pmaxsw_2 = "rmo:660FEErM",
1245 pmaxub_2 = "rmo:660FDErM",
1246 pminsw_2 = "rmo:660FEArM",
1247 pminub_2 = "rmo:660FDArM",
1248 pmovmskb_2 = "rr/do:660FD7rM",
1249 pmulhuw_2 = "rmo:660FE4rM",
1250 pmulhw_2 = "rmo:660FE5rM",
1251 pmullw_2 = "rmo:660FD5rM",
1252 pmuludq_2 = "rmo:660FF4rM",
1253 por_2 = "rmo:660FEBrM",
1254 prefetchnta_1 = "xb:n0F180m",
1255 prefetcht0_1 = "xb:n0F181m",
1256 prefetcht1_1 = "xb:n0F182m",
1257 prefetcht2_1 = "xb:n0F183m",
1258 psadbw_2 = "rmo:660FF6rM",
1259 pshufd_3 = "rmio:660F70rMU",
1260 pshufhw_3 = "rmio:F30F70rMU",
1261 pshuflw_3 = "rmio:F20F70rMU",
1262 pslld_2 = "rmo:660FF2rM|rio:660F726mU",
1263 pslldq_2 = "rio:660F737mU",
1264 psllq_2 = "rmo:660FF3rM|rio:660F736mU",
1265 psllw_2 = "rmo:660FF1rM|rio:660F716mU",
1266 psrad_2 = "rmo:660FE2rM|rio:660F724mU",
1267 psraw_2 = "rmo:660FE1rM|rio:660F714mU",
1268 psrld_2 = "rmo:660FD2rM|rio:660F722mU",
1269 psrldq_2 = "rio:660F733mU",
1270 psrlq_2 = "rmo:660FD3rM|rio:660F732mU",
1271 psrlw_2 = "rmo:660FD1rM|rio:660F712mU",
1272 psubb_2 = "rmo:660FF8rM",
1273 psubd_2 = "rmo:660FFArM",
1274 psubq_2 = "rmo:660FFBrM",
1275 psubsb_2 = "rmo:660FE8rM",
1276 psubsw_2 = "rmo:660FE9rM",
1277 psubusb_2 = "rmo:660FD8rM",
1278 psubusw_2 = "rmo:660FD9rM",
1279 psubw_2 = "rmo:660FF9rM",
1280 punpckhbw_2 = "rmo:660F68rM",
1281 punpckhdq_2 = "rmo:660F6ArM",
1282 punpckhqdq_2 = "rmo:660F6DrM",
1283 punpckhwd_2 = "rmo:660F69rM",
1284 punpcklbw_2 = "rmo:660F60rM",
1285 punpckldq_2 = "rmo:660F62rM",
1286 punpcklqdq_2 = "rmo:660F6CrM",
1287 punpcklwd_2 = "rmo:660F61rM",
1288 pxor_2 = "rmo:660FEFrM",
1289 rcpps_2 = "rmo:0F53rM",
1290 rcpss_2 = "rro:F30F53rM|rx/od:",
1291 rsqrtps_2 = "rmo:0F52rM",
1292 rsqrtss_2 = "rmo:F30F52rM",
1293 sfence_0 = "0FAEF8",
1294 shufpd_3 = "rmio:660FC6rMU",
1295 shufps_3 = "rmio:0FC6rMU",
1296 stmxcsr_1 = "xd:0FAE3m",
1297 ucomisd_2 = "rro:660F2ErM|rx/oq:",
1298 ucomiss_2 = "rro:0F2ErM|rx/od:",
1299 unpckhpd_2 = "rmo:660F15rM",
1300 unpckhps_2 = "rmo:0F15rM",
1301 unpcklpd_2 = "rmo:660F14rM",
1302 unpcklps_2 = "rmo:0F14rM",
1303 xorpd_2 = "rmo:660F57rM",
1304 xorps_2 = "rmo:0F57rM",
1305
1306 -- SSE3 ops
1307 fisttp_1 = "xw:nDF1m|xd:DB1m|xq:nDD1m",
1308 addsubpd_2 = "rmo:660FD0rM",
1309 addsubps_2 = "rmo:F20FD0rM",
1310 haddpd_2 = "rmo:660F7CrM",
1311 haddps_2 = "rmo:F20F7CrM",
1312 hsubpd_2 = "rmo:660F7DrM",
1313 hsubps_2 = "rmo:F20F7DrM",
1314 lddqu_2 = "rxo:F20FF0rM",
1315 movddup_2 = "rmo:F20F12rM",
1316 movshdup_2 = "rmo:F30F16rM",
1317 movsldup_2 = "rmo:F30F12rM",
1318
1319 -- SSSE3 ops
1320 pabsb_2 = "rmo:660F381CrM",
1321 pabsd_2 = "rmo:660F381ErM",
1322 pabsw_2 = "rmo:660F381DrM",
1323 palignr_3 = "rmio:660F3A0FrMU",
1324 phaddd_2 = "rmo:660F3802rM",
1325 phaddsw_2 = "rmo:660F3803rM",
1326 phaddw_2 = "rmo:660F3801rM",
1327 phsubd_2 = "rmo:660F3806rM",
1328 phsubsw_2 = "rmo:660F3807rM",
1329 phsubw_2 = "rmo:660F3805rM",
1330 pmaddubsw_2 = "rmo:660F3804rM",
1331 pmulhrsw_2 = "rmo:660F380BrM",
1332 pshufb_2 = "rmo:660F3800rM",
1333 psignb_2 = "rmo:660F3808rM",
1334 psignd_2 = "rmo:660F380ArM",
1335 psignw_2 = "rmo:660F3809rM",
1336
1337 -- SSE4.1 ops
1338 blendpd_3 = "rmio:660F3A0DrMU",
1339 blendps_3 = "rmio:660F3A0CrMU",
1340 blendvpd_3 = "rmRo:660F3815rM",
1341 blendvps_3 = "rmRo:660F3814rM",
1342 dppd_3 = "rmio:660F3A41rMU",
1343 dpps_3 = "rmio:660F3A40rMU",
1344 extractps_3 = "mri/do:660F3A17RmU|rri/qo:660F3A17RXmU",
1345 insertps_3 = "rrio:660F3A41rMU|rxi/od:",
1346 movntdqa_2 = "rmo:660F382ArM",
1347 mpsadbw_3 = "rmio:660F3A42rMU",
1348 packusdw_2 = "rmo:660F382BrM",
1349 pblendvb_3 = "rmRo:660F3810rM",
1350 pblendw_3 = "rmio:660F3A0ErMU",
1351 pcmpeqq_2 = "rmo:660F3829rM",
1352 pextrb_3 = "rri/do:660F3A14nRmU|rri/qo:|xri/bo:",
1353 pextrd_3 = "mri/do:660F3A16RmU",
1354 pextrq_3 = "mri/qo:660F3A16RmU",
1355 -- pextrw is SSE2, mem operand is SSE4.1 only
1356 phminposuw_2 = "rmo:660F3841rM",
1357 pinsrb_3 = "rri/od:660F3A20nrMU|rxi/ob:",
1358 pinsrd_3 = "rmi/od:660F3A22rMU",
1359 pinsrq_3 = "rmi/oq:660F3A22rXMU",
1360 pmaxsb_2 = "rmo:660F383CrM",
1361 pmaxsd_2 = "rmo:660F383DrM",
1362 pmaxud_2 = "rmo:660F383FrM",
1363 pmaxuw_2 = "rmo:660F383ErM",
1364 pminsb_2 = "rmo:660F3838rM",
1365 pminsd_2 = "rmo:660F3839rM",
1366 pminud_2 = "rmo:660F383BrM",
1367 pminuw_2 = "rmo:660F383ArM",
1368 pmovsxbd_2 = "rro:660F3821rM|rx/od:",
1369 pmovsxbq_2 = "rro:660F3822rM|rx/ow:",
1370 pmovsxbw_2 = "rro:660F3820rM|rx/oq:",
1371 pmovsxdq_2 = "rro:660F3825rM|rx/oq:",
1372 pmovsxwd_2 = "rro:660F3823rM|rx/oq:",
1373 pmovsxwq_2 = "rro:660F3824rM|rx/od:",
1374 pmovzxbd_2 = "rro:660F3831rM|rx/od:",
1375 pmovzxbq_2 = "rro:660F3832rM|rx/ow:",
1376 pmovzxbw_2 = "rro:660F3830rM|rx/oq:",
1377 pmovzxdq_2 = "rro:660F3835rM|rx/oq:",
1378 pmovzxwd_2 = "rro:660F3833rM|rx/oq:",
1379 pmovzxwq_2 = "rro:660F3834rM|rx/od:",
1380 pmuldq_2 = "rmo:660F3828rM",
1381 pmulld_2 = "rmo:660F3840rM",
1382 ptest_2 = "rmo:660F3817rM",
1383 roundpd_3 = "rmio:660F3A09rMU",
1384 roundps_3 = "rmio:660F3A08rMU",
1385 roundsd_3 = "rrio:660F3A0BrMU|rxi/oq:",
1386 roundss_3 = "rrio:660F3A0ArMU|rxi/od:",
1387
1388 -- SSE4.2 ops
1389 crc32_2 = "rmqd:F20F38F1rM|rm/dw:66F20F38F1rM|rm/db:F20F38F0rM|rm/qb:",
1390 pcmpestri_3 = "rmio:660F3A61rMU",
1391 pcmpestrm_3 = "rmio:660F3A60rMU",
1392 pcmpgtq_2 = "rmo:660F3837rM",
1393 pcmpistri_3 = "rmio:660F3A63rMU",
1394 pcmpistrm_3 = "rmio:660F3A62rMU",
1395 popcnt_2 = "rmqdw:F30FB8rM",
1396
1397 -- SSE4a
1398 extrq_2 = "rro:660F79rM",
1399 extrq_3 = "riio:660F780mUU",
1400 insertq_2 = "rro:F20F79rM",
1401 insertq_4 = "rriio:F20F78rMUU",
1402 lzcnt_2 = "rmqdw:F30FBDrM",
1403 movntsd_2 = "xr/qo:nF20F2BRm",
1404 movntss_2 = "xr/do:F30F2BRm",
1405 -- popcnt is also in SSE4.2
1406}
1407
1408------------------------------------------------------------------------------
1409
1410-- Arithmetic ops.
1411for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3,
1412 ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do
1413 local n8 = n * 8
1414 map_op[name.."_2"] = format(
1415 "mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi",
1416 1+n8, 3+n8, n, n, 5+n8, n)
1417end
1418
1419-- Shift ops.
1420for name,n in pairs{ rol = 0, ror = 1, rcl = 2, rcr = 3,
1421 shl = 4, shr = 5, sar = 7, sal = 4 } do
1422 map_op[name.."_2"] = format("m1:D1%Xm|mC1qdwb:D3%Xm|mi:C1%XmU", n, n, n)
1423end
1424
1425-- Conditional ops.
1426for cc,n in pairs(map_cc) do
1427 map_op["j"..cc.."_1"] = format("J.:n0F8%XJ", n) -- short: 7%X
1428 map_op["set"..cc.."_1"] = format("mb:n0F9%X2m", n)
1429 map_op["cmov"..cc.."_2"] = format("rmqdw:0F4%XrM", n) -- P6+
1430end
1431
1432-- FP arithmetic ops.
1433for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,
1434 sub = 4, subr = 5, div = 6, divr = 7 } do
1435 local nc = 192 + n * 8
1436 local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))
1437 local fn = "f"..name
1438 map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n)
1439 if n == 2 or n == 3 then
1440 map_op[fn.."_2"] = format("Fff:D8%02XR|Fx2d:D8%XM|Fx2q:nDC%XM", nc, n, n)
1441 else
1442 map_op[fn.."_2"] = format("Fff:D8%02XR|fFf:DC%02Xr|Fx2d:D8%XM|Fx2q:nDC%XM", nc, nr, n, n)
1443 map_op[fn.."p_1"] = format("ff:DE%02Xr", nr)
1444 map_op[fn.."p_2"] = format("fFf:DE%02Xr", nr)
1445 end
1446 map_op["fi"..name.."_1"] = format("xd:DA%Xm|xw:nDE%Xm", n, n)
1447end
1448
1449-- FP conditional moves.
1450for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
1451 local n4 = n % 4
1452 local nc = 56000 + n4 * 8 + (n-n4) * 64
1453 map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+
1454 map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
1455end
1456
1457-- SSE FP arithmetic ops.
1458for name,n in pairs{ sqrt = 1, add = 8, mul = 9,
1459 sub = 12, min = 13, div = 14, max = 15 } do
1460 map_op[name.."ps_2"] = format("rmo:0F5%XrM", n)
1461 map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n)
1462 map_op[name.."pd_2"] = format("rmo:660F5%XrM", n)
1463 map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n)
1464end
1465
1466------------------------------------------------------------------------------
1467
1468-- Process pattern string.
1469local function dopattern(pat, args, sz, op, needrex)
1470 local digit, addin
1471 local opcode = 0
1472 local szov = sz
1473 local narg = 1
1474 local rex = 0
1475
1476 -- Limit number of section buffer positions used by a single dasm_put().
1477 -- A single opcode needs a maximum of 5 positions.
1478 if secpos+5 > maxsecpos then wflush() end
1479
1480 -- Process each character.
1481 for c in gmatch(pat.."|", ".") do
1482 if match(c, "%x") then -- Hex digit.
1483 digit = byte(c) - 48
1484 if digit > 48 then digit = digit - 39
1485 elseif digit > 16 then digit = digit - 7 end
1486 opcode = opcode*16 + digit
1487 addin = nil
1488 elseif c == "n" then -- Disable operand size mods for opcode.
1489 szov = nil
1490 elseif c == "X" then -- Force REX.W.
1491 rex = 8
1492 elseif c == "r" then -- Merge 1st operand regno. into opcode.
1493 addin = args[1]; opcode = opcode + (addin.reg % 8)
1494 if narg < 2 then narg = 2 end
1495 elseif c == "R" then -- Merge 2nd operand regno. into opcode.
1496 addin = args[2]; opcode = opcode + (addin.reg % 8)
1497 narg = 3
1498 elseif c == "m" or c == "M" then -- Encode ModRM/SIB.
1499 local s
1500 if addin then
1501 s = addin.reg
1502 opcode = opcode - (s%8) -- Undo regno opcode merge.
1503 else
1504 s = opcode % 16 -- Undo last digit.
1505 opcode = (opcode - s) / 16
1506 end
1507 local nn = c == "m" and 1 or 2
1508 local t = args[nn]
1509 if narg <= nn then narg = nn + 1 end
1510 if szov == "q" and rex == 0 then rex = rex + 8 end
1511 if t.reg and t.reg > 7 then rex = rex + 1 end
1512 if t.xreg and t.xreg > 7 then rex = rex + 2 end
1513 if s > 7 then rex = rex + 4 end
1514 if needrex then rex = rex + 16 end
1515 wputop(szov, opcode, rex); opcode = nil
1516 local imark = sub(pat, -1) -- Force a mark (ugly).
1517 -- Put ModRM/SIB with regno/last digit as spare.
1518 wputmrmsib(t, imark, s, addin and addin.vreg)
1519 addin = nil
1520 else
1521 if opcode then -- Flush opcode.
1522 if szov == "q" and rex == 0 then rex = rex + 8 end
1523 if needrex then rex = rex + 16 end
1524 if addin and addin.reg == -1 then
1525 wputop(szov, opcode - 7, rex)
1526 waction("VREG", addin.vreg); wputxb(0)
1527 else
1528 if addin and addin.reg > 7 then rex = rex + 1 end
1529 wputop(szov, opcode, rex)
1530 end
1531 opcode = nil
1532 end
1533 if c == "|" then break end
1534 if c == "o" then -- Offset (pure 32 bit displacement).
1535 wputdarg(args[1].disp); if narg < 2 then narg = 2 end
1536 elseif c == "O" then
1537 wputdarg(args[2].disp); narg = 3
1538 else
1539 -- Anything else is an immediate operand.
1540 local a = args[narg]
1541 narg = narg + 1
1542 local mode, imm = a.mode, a.imm
1543 if mode == "iJ" and not match("iIJ", c) then
1544 werror("bad operand size for label")
1545 end
1546 if c == "S" then
1547 wputsbarg(imm)
1548 elseif c == "U" then
1549 wputbarg(imm)
1550 elseif c == "W" then
1551 wputwarg(imm)
1552 elseif c == "i" or c == "I" then
1553 if mode == "iJ" then
1554 wputlabel("IMM_", imm, 1)
1555 elseif mode == "iI" and c == "I" then
1556 waction(sz == "w" and "IMM_WB" or "IMM_DB", imm)
1557 else
1558 wputszarg(sz, imm)
1559 end
1560 elseif c == "J" then
1561 if mode == "iPJ" then
1562 waction("REL_A", imm) -- !x64 (secpos)
1563 else
1564 wputlabel("REL_", imm, 2)
1565 end
1566 else
1567 werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")
1568 end
1569 end
1570 end
1571 end
1572end
1573
1574------------------------------------------------------------------------------
1575
1576-- Mapping of operand modes to short names. Suppress output with '#'.
1577local map_modename = {
1578 r = "reg", R = "eax", C = "cl", x = "mem", m = "mrm", i = "imm",
1579 f = "stx", F = "st0", J = "lbl", ["1"] = "1",
1580 I = "#", S = "#", O = "#",
1581}
1582
1583-- Return a table/string showing all possible operand modes.
1584local function templatehelp(template, nparams)
1585 if nparams == 0 then return "" end
1586 local t = {}
1587 for tm in gmatch(template, "[^%|]+") do
1588 local s = map_modename[sub(tm, 1, 1)]
1589 s = s..gsub(sub(tm, 2, nparams), ".", function(c)
1590 return ", "..map_modename[c]
1591 end)
1592 if not match(s, "#") then t[#t+1] = s end
1593 end
1594 return t
1595end
1596
1597-- Match operand modes against mode match part of template.
1598local function matchtm(tm, args)
1599 for i=1,#args do
1600 if not match(args[i].mode, sub(tm, i, i)) then return end
1601 end
1602 return true
1603end
1604
1605-- Handle opcodes defined with template strings.
1606map_op[".template__"] = function(params, template, nparams)
1607 if not params then return templatehelp(template, nparams) end
1608 local args = {}
1609
1610 -- Zero-operand opcodes have no match part.
1611 if #params == 0 then
1612 dopattern(template, args, "d", params.op, nil)
1613 return
1614 end
1615
1616 -- Determine common operand size (coerce undefined size) or flag as mixed.
1617 local sz, szmix, needrex
1618 for i,p in ipairs(params) do
1619 args[i] = parseoperand(p)
1620 local nsz = args[i].opsize
1621 if nsz then
1622 if sz and sz ~= nsz then szmix = true else sz = nsz end
1623 end
1624 local nrex = args[i].needrex
1625 if nrex ~= nil then
1626 if needrex == nil then
1627 needrex = nrex
1628 elseif needrex ~= nrex then
1629 werror("bad mix of byte-addressable registers")
1630 end
1631 end
1632 end
1633
1634 -- Try all match:pattern pairs (separated by '|').
1635 local gotmatch, lastpat
1636 for tm in gmatch(template, "[^%|]+") do
1637 -- Split off size match (starts after mode match) and pattern string.
1638 local szm, pat = match(tm, "^(.-):(.*)$", #args+1)
1639 if pat == "" then pat = lastpat else lastpat = pat end
1640 if matchtm(tm, args) then
1641 local prefix = sub(szm, 1, 1)
1642 if prefix == "/" then -- Match both operand sizes.
1643 if args[1].opsize == sub(szm, 2, 2) and
1644 args[2].opsize == sub(szm, 3, 3) then
1645 dopattern(pat, args, sz, params.op, needrex) -- Process pattern.
1646 return
1647 end
1648 else -- Match common operand size.
1649 local szp = sz
1650 if szm == "" then szm = x64 and "qdwb" or "dwb" end -- Default sizes.
1651 if prefix == "1" then szp = args[1].opsize; szmix = nil
1652 elseif prefix == "2" then szp = args[2].opsize; szmix = nil end
1653 if not szmix and (prefix == "." or match(szm, szp or "#")) then
1654 dopattern(pat, args, szp, params.op, needrex) -- Process pattern.
1655 return
1656 end
1657 end
1658 gotmatch = true
1659 end
1660 end
1661
1662 local msg = "bad operand mode"
1663 if gotmatch then
1664 if szmix then
1665 msg = "mixed operand size"
1666 else
1667 msg = sz and "bad operand size" or "missing operand size"
1668 end
1669 end
1670
1671 werror(msg.." in `"..opmodestr(params.op, args).."'")
1672end
1673
1674------------------------------------------------------------------------------
1675
1676-- x64-specific opcode for 64 bit immediates and displacements.
1677if x64 then
1678 function map_op.mov64_2(params)
1679 if not params then return { "reg, imm", "reg, [disp]", "[disp], reg" } end
1680 if secpos+2 > maxsecpos then wflush() end
1681 local opcode, op64, sz, rex
1682 local op64 = match(params[1], "^%[%s*(.-)%s*%]$")
1683 if op64 then
1684 local a = parseoperand(params[2])
1685 if a.mode ~= "rmR" then werror("bad operand mode") end
1686 sz = a.opsize
1687 rex = sz == "q" and 8 or 0
1688 opcode = 0xa3
1689 else
1690 op64 = match(params[2], "^%[%s*(.-)%s*%]$")
1691 local a = parseoperand(params[1])
1692 if op64 then
1693 if a.mode ~= "rmR" then werror("bad operand mode") end
1694 sz = a.opsize
1695 rex = sz == "q" and 8 or 0
1696 opcode = 0xa1
1697 else
1698 if sub(a.mode, 1, 1) ~= "r" or a.opsize ~= "q" then
1699 werror("bad operand mode")
1700 end
1701 op64 = params[2]
1702 opcode = 0xb8 + (a.reg%8) -- !x64: no VREG support.
1703 rex = a.reg > 7 and 9 or 8
1704 end
1705 end
1706 wputop(sz, opcode, rex)
1707 waction("IMM_D", format("(unsigned int)(%s)", op64))
1708 waction("IMM_D", format("(unsigned int)((%s)>>32)", op64))
1709 end
1710end
1711
1712------------------------------------------------------------------------------
1713
1714-- Pseudo-opcodes for data storage.
1715local function op_data(params)
1716 if not params then return "imm..." end
1717 local sz = sub(params.op, 2, 2)
1718 if sz == "a" then sz = addrsize end
1719 for _,p in ipairs(params) do
1720 local a = parseoperand(p)
1721 if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
1722 werror("bad mode or size in `"..p.."'")
1723 end
1724 if a.mode == "iJ" then
1725 wputlabel("IMM_", a.imm, 1)
1726 else
1727 wputszarg(sz, a.imm)
1728 end
1729 if secpos+2 > maxsecpos then wflush() end
1730 end
1731end
1732
1733map_op[".byte_*"] = op_data
1734map_op[".sbyte_*"] = op_data
1735map_op[".word_*"] = op_data
1736map_op[".dword_*"] = op_data
1737map_op[".aword_*"] = op_data
1738
1739------------------------------------------------------------------------------
1740
1741-- Pseudo-opcode to mark the position where the action list is to be emitted.
1742map_op[".actionlist_1"] = function(params)
1743 if not params then return "cvar" end
1744 local name = params[1] -- No syntax check. You get to keep the pieces.
1745 wline(function(out) writeactions(out, name) end)
1746end
1747
1748-- Pseudo-opcode to mark the position where the global enum is to be emitted.
1749map_op[".globals_1"] = function(params)
1750 if not params then return "prefix" end
1751 local prefix = params[1] -- No syntax check. You get to keep the pieces.
1752 wline(function(out) writeglobals(out, prefix) end)
1753end
1754
1755-- Pseudo-opcode to mark the position where the global names are to be emitted.
1756map_op[".globalnames_1"] = function(params)
1757 if not params then return "cvar" end
1758 local name = params[1] -- No syntax check. You get to keep the pieces.
1759 wline(function(out) writeglobalnames(out, name) end)
1760end
1761
1762-- Pseudo-opcode to mark the position where the extern names are to be emitted.
1763map_op[".externnames_1"] = function(params)
1764 if not params then return "cvar" end
1765 local name = params[1] -- No syntax check. You get to keep the pieces.
1766 wline(function(out) writeexternnames(out, name) end)
1767end
1768
1769------------------------------------------------------------------------------
1770
1771-- Label pseudo-opcode (converted from trailing colon form).
1772map_op[".label_2"] = function(params)
1773 if not params then return "[1-9] | ->global | =>pcexpr [, addr]" end
1774 if secpos+2 > maxsecpos then wflush() end
1775 local a = parseoperand(params[1])
1776 local mode, imm = a.mode, a.imm
1777 if type(imm) == "number" and (mode == "iJ" or (imm >= 1 and imm <= 9)) then
1778 -- Local label (1: ... 9:) or global label (->global:).
1779 waction("LABEL_LG", nil, 1)
1780 wputxb(imm)
1781 elseif mode == "iJ" then
1782 -- PC label (=>pcexpr:).
1783 waction("LABEL_PC", imm)
1784 else
1785 werror("bad label definition")
1786 end
1787 -- SETLABEL must immediately follow LABEL_LG/LABEL_PC.
1788 local addr = params[2]
1789 if addr then
1790 local a = parseoperand(addr)
1791 if a.mode == "iPJ" then
1792 waction("SETLABEL", a.imm)
1793 else
1794 werror("bad label assignment")
1795 end
1796 end
1797end
1798map_op[".label_1"] = map_op[".label_2"]
1799
1800------------------------------------------------------------------------------
1801
1802-- Alignment pseudo-opcode.
1803map_op[".align_1"] = function(params)
1804 if not params then return "numpow2" end
1805 if secpos+1 > maxsecpos then wflush() end
1806 local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]]
1807 if align then
1808 local x = align
1809 -- Must be a power of 2 in the range (2 ... 256).
1810 for i=1,8 do
1811 x = x / 2
1812 if x == 1 then
1813 waction("ALIGN", nil, 1)
1814 wputxb(align-1) -- Action byte is 2**n-1.
1815 return
1816 end
1817 end
1818 end
1819 werror("bad alignment")
1820end
1821
1822-- Spacing pseudo-opcode.
1823map_op[".space_2"] = function(params)
1824 if not params then return "num [, filler]" end
1825 if secpos+1 > maxsecpos then wflush() end
1826 waction("SPACE", params[1])
1827 local fill = params[2]
1828 if fill then
1829 fill = tonumber(fill)
1830 if not fill or fill < 0 or fill > 255 then werror("bad filler") end
1831 end
1832 wputxb(fill or 0)
1833end
1834map_op[".space_1"] = map_op[".space_2"]
1835
1836------------------------------------------------------------------------------
1837
1838-- Pseudo-opcode for (primitive) type definitions (map to C types).
1839map_op[".type_3"] = function(params, nparams)
1840 if not params then
1841 return nparams == 2 and "name, ctype" or "name, ctype, reg"
1842 end
1843 local name, ctype, reg = params[1], params[2], params[3]
1844 if not match(name, "^[%a_][%w_]*$") then
1845 werror("bad type name `"..name.."'")
1846 end
1847 local tp = map_type[name]
1848 if tp then
1849 werror("duplicate type `"..name.."'")
1850 end
1851 if reg and not map_reg_valid_base[reg] then
1852 werror("bad base register `"..(map_reg_rev[reg] or reg).."'")
1853 end
1854 -- Add #type to defines. A bit unclean to put it in map_archdef.
1855 map_archdef["#"..name] = "sizeof("..ctype..")"
1856 -- Add new type and emit shortcut define.
1857 local num = ctypenum + 1
1858 map_type[name] = {
1859 ctype = ctype,
1860 ctypefmt = format("Dt%X(%%s)", num),
1861 reg = reg,
1862 }
1863 wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
1864 ctypenum = num
1865end
1866map_op[".type_2"] = map_op[".type_3"]
1867
1868-- Dump type definitions.
1869local function dumptypes(out, lvl)
1870 local t = {}
1871 for name in pairs(map_type) do t[#t+1] = name end
1872 sort(t)
1873 out:write("Type definitions:\n")
1874 for _,name in ipairs(t) do
1875 local tp = map_type[name]
1876 local reg = tp.reg and map_reg_rev[tp.reg] or ""
1877 out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
1878 end
1879 out:write("\n")
1880end
1881
1882------------------------------------------------------------------------------
1883
1884-- Set the current section.
1885function _M.section(num)
1886 waction("SECTION")
1887 wputxb(num)
1888 wflush(true) -- SECTION is a terminal action.
1889end
1890
1891------------------------------------------------------------------------------
1892
1893-- Dump architecture description.
1894function _M.dumparch(out)
1895 out:write(format("DynASM %s version %s, released %s\n\n",
1896 _info.arch, _info.version, _info.release))
1897 dumpregs(out)
1898 dumpactions(out)
1899end
1900
1901-- Dump all user defined elements.
1902function _M.dumpdef(out, lvl)
1903 dumptypes(out, lvl)
1904 dumpglobals(out, lvl)
1905 dumpexterns(out, lvl)
1906end
1907
1908------------------------------------------------------------------------------
1909
1910-- Pass callbacks from/to the DynASM core.
1911function _M.passcb(wl, we, wf, ww)
1912 wline, werror, wfatal, wwarn = wl, we, wf, ww
1913 return wflush
1914end
1915
1916-- Setup the arch-specific module.
1917function _M.setup(arch, opt)
1918 g_arch, g_opt = arch, opt
1919end
1920
1921-- Merge the core maps and the arch-specific maps.
1922function _M.mergemaps(map_coreop, map_def)
1923 setmetatable(map_op, { __index = map_coreop })
1924 setmetatable(map_def, { __index = map_archdef })
1925 return map_op, map_def
1926end
1927
1928return _M
1929
1930------------------------------------------------------------------------------
1931
diff --git a/libraries/luajit-2.0/dynasm/dynasm.lua b/libraries/luajit-2.0/dynasm/dynasm.lua
new file mode 100644
index 0000000..8ff9851
--- /dev/null
+++ b/libraries/luajit-2.0/dynasm/dynasm.lua
@@ -0,0 +1,1076 @@
1------------------------------------------------------------------------------
2-- DynASM. A dynamic assembler for code generation engines.
3-- Originally designed and implemented for LuaJIT.
4--
5-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
6-- See below for full copyright notice.
7------------------------------------------------------------------------------
8
9-- Application information.
10local _info = {
11 name = "DynASM",
12 description = "A dynamic assembler for code generation engines",
13 version = "1.3.0",
14 vernum = 10300,
15 release = "2011-05-05",
16 author = "Mike Pall",
17 url = "http://luajit.org/dynasm.html",
18 license = "MIT",
19 copyright = [[
20Copyright (C) 2005-2011 Mike Pall. All rights reserved.
21
22Permission is hereby granted, free of charge, to any person obtaining
23a copy of this software and associated documentation files (the
24"Software"), to deal in the Software without restriction, including
25without limitation the rights to use, copy, modify, merge, publish,
26distribute, sublicense, and/or sell copies of the Software, and to
27permit persons to whom the Software is furnished to do so, subject to
28the following conditions:
29
30The above copyright notice and this permission notice shall be
31included in all copies or substantial portions of the Software.
32
33THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
35MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
36IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
37CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
38TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
39SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40
41[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
42]],
43}
44
45-- Cache library functions.
46local type, pairs, ipairs = type, pairs, ipairs
47local pcall, error, assert = pcall, error, assert
48local _s = string
49local sub, match, gmatch, gsub = _s.sub, _s.match, _s.gmatch, _s.gsub
50local format, rep, upper = _s.format, _s.rep, _s.upper
51local _t = table
52local insert, remove, concat, sort = _t.insert, _t.remove, _t.concat, _t.sort
53local exit = os.exit
54local io = io
55local stdin, stdout, stderr = io.stdin, io.stdout, io.stderr
56
57------------------------------------------------------------------------------
58
59-- Program options.
60local g_opt = {}
61
62-- Global state for current file.
63local g_fname, g_curline, g_indent, g_lineno, g_synclineno, g_arch
64local g_errcount = 0
65
66-- Write buffer for output file.
67local g_wbuffer, g_capbuffer
68
69------------------------------------------------------------------------------
70
71-- Write an output line (or callback function) to the buffer.
72local function wline(line, needindent)
73 local buf = g_capbuffer or g_wbuffer
74 buf[#buf+1] = needindent and g_indent..line or line
75 g_synclineno = g_synclineno + 1
76end
77
78-- Write assembler line as a comment, if requestd.
79local function wcomment(aline)
80 if g_opt.comment then
81 wline(g_opt.comment..aline..g_opt.endcomment, true)
82 end
83end
84
85-- Resync CPP line numbers.
86local function wsync()
87 if g_synclineno ~= g_lineno and g_opt.cpp then
88 wline("# "..g_lineno..' "'..g_fname..'"')
89 g_synclineno = g_lineno
90 end
91end
92
93-- Dummy action flush function. Replaced with arch-specific function later.
94local function wflush(term)
95end
96
97-- Dump all buffered output lines.
98local function wdumplines(out, buf)
99 for _,line in ipairs(buf) do
100 if type(line) == "string" then
101 assert(out:write(line, "\n"))
102 else
103 -- Special callback to dynamically insert lines after end of processing.
104 line(out)
105 end
106 end
107end
108
109------------------------------------------------------------------------------
110
111-- Emit an error. Processing continues with next statement.
112local function werror(msg)
113 error(format("%s:%s: error: %s:\n%s", g_fname, g_lineno, msg, g_curline), 0)
114end
115
116-- Emit a fatal error. Processing stops.
117local function wfatal(msg)
118 g_errcount = "fatal"
119 werror(msg)
120end
121
122-- Print a warning. Processing continues.
123local function wwarn(msg)
124 stderr:write(format("%s:%s: warning: %s:\n%s\n",
125 g_fname, g_lineno, msg, g_curline))
126end
127
128-- Print caught error message. But suppress excessive errors.
129local function wprinterr(...)
130 if type(g_errcount) == "number" then
131 -- Regular error.
132 g_errcount = g_errcount + 1
133 if g_errcount < 21 then -- Seems to be a reasonable limit.
134 stderr:write(...)
135 elseif g_errcount == 21 then
136 stderr:write(g_fname,
137 ":*: warning: too many errors (suppressed further messages).\n")
138 end
139 else
140 -- Fatal error.
141 stderr:write(...)
142 return true -- Stop processing.
143 end
144end
145
146------------------------------------------------------------------------------
147
148-- Map holding all option handlers.
149local opt_map = {}
150local opt_current
151
152-- Print error and exit with error status.
153local function opterror(...)
154 stderr:write("dynasm.lua: ERROR: ", ...)
155 stderr:write("\n")
156 exit(1)
157end
158
159-- Get option parameter.
160local function optparam(args)
161 local argn = args.argn
162 local p = args[argn]
163 if not p then
164 opterror("missing parameter for option `", opt_current, "'.")
165 end
166 args.argn = argn + 1
167 return p
168end
169
170------------------------------------------------------------------------------
171
172-- Core pseudo-opcodes.
173local map_coreop = {}
174-- Dummy opcode map. Replaced by arch-specific map.
175local map_op = {}
176
177-- Forward declarations.
178local dostmt
179local readfile
180
181------------------------------------------------------------------------------
182
183-- Map for defines (initially empty, chains to arch-specific map).
184local map_def = {}
185
186-- Pseudo-opcode to define a substitution.
187map_coreop[".define_2"] = function(params, nparams)
188 if not params then return nparams == 1 and "name" or "name, subst" end
189 local name, def = params[1], params[2] or "1"
190 if not match(name, "^[%a_][%w_]*$") then werror("bad or duplicate define") end
191 map_def[name] = def
192end
193map_coreop[".define_1"] = map_coreop[".define_2"]
194
195-- Define a substitution on the command line.
196function opt_map.D(args)
197 local namesubst = optparam(args)
198 local name, subst = match(namesubst, "^([%a_][%w_]*)=(.*)$")
199 if name then
200 map_def[name] = subst
201 elseif match(namesubst, "^[%a_][%w_]*$") then
202 map_def[namesubst] = "1"
203 else
204 opterror("bad define")
205 end
206end
207
208-- Undefine a substitution on the command line.
209function opt_map.U(args)
210 local name = optparam(args)
211 if match(name, "^[%a_][%w_]*$") then
212 map_def[name] = nil
213 else
214 opterror("bad define")
215 end
216end
217
218-- Helper for definesubst.
219local gotsubst
220
221local function definesubst_one(word)
222 local subst = map_def[word]
223 if subst then gotsubst = word; return subst else return word end
224end
225
226-- Iteratively substitute defines.
227local function definesubst(stmt)
228 -- Limit number of iterations.
229 for i=1,100 do
230 gotsubst = false
231 stmt = gsub(stmt, "#?[%w_]+", definesubst_one)
232 if not gotsubst then break end
233 end
234 if gotsubst then wfatal("recursive define involving `"..gotsubst.."'") end
235 return stmt
236end
237
238-- Dump all defines.
239local function dumpdefines(out, lvl)
240 local t = {}
241 for name in pairs(map_def) do
242 t[#t+1] = name
243 end
244 sort(t)
245 out:write("Defines:\n")
246 for _,name in ipairs(t) do
247 local subst = map_def[name]
248 if g_arch then subst = g_arch.revdef(subst) end
249 out:write(format(" %-20s %s\n", name, subst))
250 end
251 out:write("\n")
252end
253
254------------------------------------------------------------------------------
255
256-- Support variables for conditional assembly.
257local condlevel = 0
258local condstack = {}
259
260-- Evaluate condition with a Lua expression. Substitutions already performed.
261local function cond_eval(cond)
262 local func, err = loadstring("return "..cond)
263 if func then
264 setfenv(func, {}) -- No globals. All unknown identifiers evaluate to nil.
265 local ok, res = pcall(func)
266 if ok then
267 if res == 0 then return false end -- Oh well.
268 return not not res
269 end
270 err = res
271 end
272 wfatal("bad condition: "..err)
273end
274
275-- Skip statements until next conditional pseudo-opcode at the same level.
276local function stmtskip()
277 local dostmt_save = dostmt
278 local lvl = 0
279 dostmt = function(stmt)
280 local op = match(stmt, "^%s*(%S+)")
281 if op == ".if" then
282 lvl = lvl + 1
283 elseif lvl ~= 0 then
284 if op == ".endif" then lvl = lvl - 1 end
285 elseif op == ".elif" or op == ".else" or op == ".endif" then
286 dostmt = dostmt_save
287 dostmt(stmt)
288 end
289 end
290end
291
292-- Pseudo-opcodes for conditional assembly.
293map_coreop[".if_1"] = function(params)
294 if not params then return "condition" end
295 local lvl = condlevel + 1
296 local res = cond_eval(params[1])
297 condlevel = lvl
298 condstack[lvl] = res
299 if not res then stmtskip() end
300end
301
302map_coreop[".elif_1"] = function(params)
303 if not params then return "condition" end
304 if condlevel == 0 then wfatal(".elif without .if") end
305 local lvl = condlevel
306 local res = condstack[lvl]
307 if res then
308 if res == "else" then wfatal(".elif after .else") end
309 else
310 res = cond_eval(params[1])
311 if res then
312 condstack[lvl] = res
313 return
314 end
315 end
316 stmtskip()
317end
318
319map_coreop[".else_0"] = function(params)
320 if condlevel == 0 then wfatal(".else without .if") end
321 local lvl = condlevel
322 local res = condstack[lvl]
323 condstack[lvl] = "else"
324 if res then
325 if res == "else" then wfatal(".else after .else") end
326 stmtskip()
327 end
328end
329
330map_coreop[".endif_0"] = function(params)
331 local lvl = condlevel
332 if lvl == 0 then wfatal(".endif without .if") end
333 condlevel = lvl - 1
334end
335
336-- Check for unfinished conditionals.
337local function checkconds()
338 if g_errcount ~= "fatal" and condlevel ~= 0 then
339 wprinterr(g_fname, ":*: error: unbalanced conditional\n")
340 end
341end
342
343------------------------------------------------------------------------------
344
345-- Search for a file in the given path and open it for reading.
346local function pathopen(path, name)
347 local dirsep = match(package.path, "\\") and "\\" or "/"
348 for _,p in ipairs(path) do
349 local fullname = p == "" and name or p..dirsep..name
350 local fin = io.open(fullname, "r")
351 if fin then
352 g_fname = fullname
353 return fin
354 end
355 end
356end
357
358-- Include a file.
359map_coreop[".include_1"] = function(params)
360 if not params then return "filename" end
361 local name = params[1]
362 -- Save state. Ugly, I know. but upvalues are fast.
363 local gf, gl, gcl, gi = g_fname, g_lineno, g_curline, g_indent
364 -- Read the included file.
365 local fatal = readfile(pathopen(g_opt.include, name) or
366 wfatal("include file `"..name.."' not found"))
367 -- Restore state.
368 g_synclineno = -1
369 g_fname, g_lineno, g_curline, g_indent = gf, gl, gcl, gi
370 if fatal then wfatal("in include file") end
371end
372
373-- Make .include and conditionals initially available, too.
374map_op[".include_1"] = map_coreop[".include_1"]
375map_op[".if_1"] = map_coreop[".if_1"]
376map_op[".elif_1"] = map_coreop[".elif_1"]
377map_op[".else_0"] = map_coreop[".else_0"]
378map_op[".endif_0"] = map_coreop[".endif_0"]
379
380------------------------------------------------------------------------------
381
382-- Support variables for macros.
383local mac_capture, mac_lineno, mac_name
384local mac_active = {}
385local mac_list = {}
386
387-- Pseudo-opcode to define a macro.
388map_coreop[".macro_*"] = function(mparams)
389 if not mparams then return "name [, params...]" end
390 -- Split off and validate macro name.
391 local name = remove(mparams, 1)
392 if not name then werror("missing macro name") end
393 if not (match(name, "^[%a_][%w_%.]*$") or match(name, "^%.[%w_%.]+$")) then
394 wfatal("bad macro name `"..name.."'")
395 end
396 -- Validate macro parameter names.
397 local mdup = {}
398 for _,mp in ipairs(mparams) do
399 if not match(mp, "^[%a_][%w_]*$") then
400 wfatal("bad macro parameter name `"..mp.."'")
401 end
402 if mdup[mp] then wfatal("duplicate macro parameter name `"..mp.."'") end
403 mdup[mp] = true
404 end
405 -- Check for duplicate or recursive macro definitions.
406 local opname = name.."_"..#mparams
407 if map_op[opname] or map_op[name.."_*"] then
408 wfatal("duplicate macro `"..name.."' ("..#mparams.." parameters)")
409 end
410 if mac_capture then wfatal("recursive macro definition") end
411
412 -- Enable statement capture.
413 local lines = {}
414 mac_lineno = g_lineno
415 mac_name = name
416 mac_capture = function(stmt) -- Statement capture function.
417 -- Stop macro definition with .endmacro pseudo-opcode.
418 if not match(stmt, "^%s*.endmacro%s*$") then
419 lines[#lines+1] = stmt
420 return
421 end
422 mac_capture = nil
423 mac_lineno = nil
424 mac_name = nil
425 mac_list[#mac_list+1] = opname
426 -- Add macro-op definition.
427 map_op[opname] = function(params)
428 if not params then return mparams, lines end
429 -- Protect against recursive macro invocation.
430 if mac_active[opname] then wfatal("recursive macro invocation") end
431 mac_active[opname] = true
432 -- Setup substitution map.
433 local subst = {}
434 for i,mp in ipairs(mparams) do subst[mp] = params[i] end
435 local mcom
436 if g_opt.maccomment and g_opt.comment then
437 mcom = " MACRO "..name.." ("..#mparams..")"
438 wcomment("{"..mcom)
439 end
440 -- Loop through all captured statements
441 for _,stmt in ipairs(lines) do
442 -- Substitute macro parameters.
443 local st = gsub(stmt, "[%w_]+", subst)
444 st = definesubst(st)
445 st = gsub(st, "%s*%.%.%s*", "") -- Token paste a..b.
446 if mcom and sub(st, 1, 1) ~= "|" then wcomment(st) end
447 -- Emit statement. Use a protected call for better diagnostics.
448 local ok, err = pcall(dostmt, st)
449 if not ok then
450 -- Add the captured statement to the error.
451 wprinterr(err, "\n", g_indent, "| ", stmt,
452 "\t[MACRO ", name, " (", #mparams, ")]\n")
453 end
454 end
455 if mcom then wcomment("}"..mcom) end
456 mac_active[opname] = nil
457 end
458 end
459end
460
461-- An .endmacro pseudo-opcode outside of a macro definition is an error.
462map_coreop[".endmacro_0"] = function(params)
463 wfatal(".endmacro without .macro")
464end
465
466-- Dump all macros and their contents (with -PP only).
467local function dumpmacros(out, lvl)
468 sort(mac_list)
469 out:write("Macros:\n")
470 for _,opname in ipairs(mac_list) do
471 local name = sub(opname, 1, -3)
472 local params, lines = map_op[opname]()
473 out:write(format(" %-20s %s\n", name, concat(params, ", ")))
474 if lvl > 1 then
475 for _,line in ipairs(lines) do
476 out:write(" |", line, "\n")
477 end
478 out:write("\n")
479 end
480 end
481 out:write("\n")
482end
483
484-- Check for unfinished macro definitions.
485local function checkmacros()
486 if mac_capture then
487 wprinterr(g_fname, ":", mac_lineno,
488 ": error: unfinished .macro `", mac_name ,"'\n")
489 end
490end
491
492------------------------------------------------------------------------------
493
494-- Support variables for captures.
495local cap_lineno, cap_name
496local cap_buffers = {}
497local cap_used = {}
498
499-- Start a capture.
500map_coreop[".capture_1"] = function(params)
501 if not params then return "name" end
502 wflush()
503 local name = params[1]
504 if not match(name, "^[%a_][%w_]*$") then
505 wfatal("bad capture name `"..name.."'")
506 end
507 if cap_name then
508 wfatal("already capturing to `"..cap_name.."' since line "..cap_lineno)
509 end
510 cap_name = name
511 cap_lineno = g_lineno
512 -- Create or continue a capture buffer and start the output line capture.
513 local buf = cap_buffers[name]
514 if not buf then buf = {}; cap_buffers[name] = buf end
515 g_capbuffer = buf
516 g_synclineno = 0
517end
518
519-- Stop a capture.
520map_coreop[".endcapture_0"] = function(params)
521 wflush()
522 if not cap_name then wfatal(".endcapture without a valid .capture") end
523 cap_name = nil
524 cap_lineno = nil
525 g_capbuffer = nil
526 g_synclineno = 0
527end
528
529-- Dump a capture buffer.
530map_coreop[".dumpcapture_1"] = function(params)
531 if not params then return "name" end
532 wflush()
533 local name = params[1]
534 if not match(name, "^[%a_][%w_]*$") then
535 wfatal("bad capture name `"..name.."'")
536 end
537 cap_used[name] = true
538 wline(function(out)
539 local buf = cap_buffers[name]
540 if buf then wdumplines(out, buf) end
541 end)
542 g_synclineno = 0
543end
544
545-- Dump all captures and their buffers (with -PP only).
546local function dumpcaptures(out, lvl)
547 out:write("Captures:\n")
548 for name,buf in pairs(cap_buffers) do
549 out:write(format(" %-20s %4s)\n", name, "("..#buf))
550 if lvl > 1 then
551 local bar = rep("=", 76)
552 out:write(" ", bar, "\n")
553 for _,line in ipairs(buf) do
554 out:write(" ", line, "\n")
555 end
556 out:write(" ", bar, "\n\n")
557 end
558 end
559 out:write("\n")
560end
561
562-- Check for unfinished or unused captures.
563local function checkcaptures()
564 if cap_name then
565 wprinterr(g_fname, ":", cap_lineno,
566 ": error: unfinished .capture `", cap_name,"'\n")
567 return
568 end
569 for name in pairs(cap_buffers) do
570 if not cap_used[name] then
571 wprinterr(g_fname, ":*: error: missing .dumpcapture ", name ,"\n")
572 end
573 end
574end
575
576------------------------------------------------------------------------------
577
578-- Sections names.
579local map_sections = {}
580
581-- Pseudo-opcode to define code sections.
582-- TODO: Data sections, BSS sections. Needs extra C code and API.
583map_coreop[".section_*"] = function(params)
584 if not params then return "name..." end
585 if #map_sections > 0 then werror("duplicate section definition") end
586 wflush()
587 for sn,name in ipairs(params) do
588 local opname = "."..name.."_0"
589 if not match(name, "^[%a][%w_]*$") or
590 map_op[opname] or map_op["."..name.."_*"] then
591 werror("bad section name `"..name.."'")
592 end
593 map_sections[#map_sections+1] = name
594 wline(format("#define DASM_SECTION_%s\t%d", upper(name), sn-1))
595 map_op[opname] = function(params) g_arch.section(sn-1) end
596 end
597 wline(format("#define DASM_MAXSECTION\t\t%d", #map_sections))
598end
599
600-- Dump all sections.
601local function dumpsections(out, lvl)
602 out:write("Sections:\n")
603 for _,name in ipairs(map_sections) do
604 out:write(format(" %s\n", name))
605 end
606 out:write("\n")
607end
608
609------------------------------------------------------------------------------
610
611-- Load architecture-specific module.
612local function loadarch(arch)
613 if not match(arch, "^[%w_]+$") then return "bad arch name" end
614 local ok, m_arch = pcall(require, "dasm_"..arch)
615 if not ok then return "cannot load module: "..m_arch end
616 g_arch = m_arch
617 wflush = m_arch.passcb(wline, werror, wfatal, wwarn)
618 m_arch.setup(arch, g_opt)
619 map_op, map_def = m_arch.mergemaps(map_coreop, map_def)
620end
621
622-- Dump architecture description.
623function opt_map.dumparch(args)
624 local name = optparam(args)
625 if not g_arch then
626 local err = loadarch(name)
627 if err then opterror(err) end
628 end
629
630 local t = {}
631 for name in pairs(map_coreop) do t[#t+1] = name end
632 for name in pairs(map_op) do t[#t+1] = name end
633 sort(t)
634
635 local out = stdout
636 local _arch = g_arch._info
637 out:write(format("%s version %s, released %s, %s\n",
638 _info.name, _info.version, _info.release, _info.url))
639 g_arch.dumparch(out)
640
641 local pseudo = true
642 out:write("Pseudo-Opcodes:\n")
643 for _,sname in ipairs(t) do
644 local name, nparam = match(sname, "^(.+)_([0-9%*])$")
645 if name then
646 if pseudo and sub(name, 1, 1) ~= "." then
647 out:write("\nOpcodes:\n")
648 pseudo = false
649 end
650 local f = map_op[sname]
651 local s
652 if nparam ~= "*" then nparam = nparam + 0 end
653 if nparam == 0 then
654 s = ""
655 elseif type(f) == "string" then
656 s = map_op[".template__"](nil, f, nparam)
657 else
658 s = f(nil, nparam)
659 end
660 if type(s) == "table" then
661 for _,s2 in ipairs(s) do
662 out:write(format(" %-12s %s\n", name, s2))
663 end
664 else
665 out:write(format(" %-12s %s\n", name, s))
666 end
667 end
668 end
669 out:write("\n")
670 exit(0)
671end
672
673-- Pseudo-opcode to set the architecture.
674-- Only initially available (map_op is replaced when called).
675map_op[".arch_1"] = function(params)
676 if not params then return "name" end
677 local err = loadarch(params[1])
678 if err then wfatal(err) end
679end
680
681-- Dummy .arch pseudo-opcode to improve the error report.
682map_coreop[".arch_1"] = function(params)
683 if not params then return "name" end
684 wfatal("duplicate .arch statement")
685end
686
687------------------------------------------------------------------------------
688
689-- Dummy pseudo-opcode. Don't confuse '.nop' with 'nop'.
690map_coreop[".nop_*"] = function(params)
691 if not params then return "[ignored...]" end
692end
693
694-- Pseudo-opcodes to raise errors.
695map_coreop[".error_1"] = function(params)
696 if not params then return "message" end
697 werror(params[1])
698end
699
700map_coreop[".fatal_1"] = function(params)
701 if not params then return "message" end
702 wfatal(params[1])
703end
704
705-- Dump all user defined elements.
706local function dumpdef(out)
707 local lvl = g_opt.dumpdef
708 if lvl == 0 then return end
709 dumpsections(out, lvl)
710 dumpdefines(out, lvl)
711 if g_arch then g_arch.dumpdef(out, lvl) end
712 dumpmacros(out, lvl)
713 dumpcaptures(out, lvl)
714end
715
716------------------------------------------------------------------------------
717
718-- Helper for splitstmt.
719local splitlvl
720
721local function splitstmt_one(c)
722 if c == "(" then
723 splitlvl = ")"..splitlvl
724 elseif c == "[" then
725 splitlvl = "]"..splitlvl
726 elseif c == "{" then
727 splitlvl = "}"..splitlvl
728 elseif c == ")" or c == "]" or c == "}" then
729 if sub(splitlvl, 1, 1) ~= c then werror("unbalanced (), [] or {}") end
730 splitlvl = sub(splitlvl, 2)
731 elseif splitlvl == "" then
732 return " \0 "
733 end
734 return c
735end
736
737-- Split statement into (pseudo-)opcode and params.
738local function splitstmt(stmt)
739 -- Convert label with trailing-colon into .label statement.
740 local label = match(stmt, "^%s*(.+):%s*$")
741 if label then return ".label", {label} end
742
743 -- Split at commas and equal signs, but obey parentheses and brackets.
744 splitlvl = ""
745 stmt = gsub(stmt, "[,%(%)%[%]{}]", splitstmt_one)
746 if splitlvl ~= "" then werror("unbalanced () or []") end
747
748 -- Split off opcode.
749 local op, other = match(stmt, "^%s*([^%s%z]+)%s*(.*)$")
750 if not op then werror("bad statement syntax") end
751
752 -- Split parameters.
753 local params = {}
754 for p in gmatch(other, "%s*(%Z+)%z?") do
755 params[#params+1] = gsub(p, "%s+$", "")
756 end
757 if #params > 16 then werror("too many parameters") end
758
759 params.op = op
760 return op, params
761end
762
763-- Process a single statement.
764dostmt = function(stmt)
765 -- Ignore empty statements.
766 if match(stmt, "^%s*$") then return end
767
768 -- Capture macro defs before substitution.
769 if mac_capture then return mac_capture(stmt) end
770 stmt = definesubst(stmt)
771
772 -- Emit C code without parsing the line.
773 if sub(stmt, 1, 1) == "|" then
774 local tail = sub(stmt, 2)
775 wflush()
776 if sub(tail, 1, 2) == "//" then wcomment(tail) else wline(tail, true) end
777 return
778 end
779
780 -- Split into (pseudo-)opcode and params.
781 local op, params = splitstmt(stmt)
782
783 -- Get opcode handler (matching # of parameters or generic handler).
784 local f = map_op[op.."_"..#params] or map_op[op.."_*"]
785 if not f then
786 if not g_arch then wfatal("first statement must be .arch") end
787 -- Improve error report.
788 for i=0,9 do
789 if map_op[op.."_"..i] then
790 werror("wrong number of parameters for `"..op.."'")
791 end
792 end
793 werror("unknown statement `"..op.."'")
794 end
795
796 -- Call opcode handler or special handler for template strings.
797 if type(f) == "string" then
798 map_op[".template__"](params, f)
799 else
800 f(params)
801 end
802end
803
804-- Process a single line.
805local function doline(line)
806 if g_opt.flushline then wflush() end
807
808 -- Assembler line?
809 local indent, aline = match(line, "^(%s*)%|(.*)$")
810 if not aline then
811 -- No, plain C code line, need to flush first.
812 wflush()
813 wsync()
814 wline(line, false)
815 return
816 end
817
818 g_indent = indent -- Remember current line indentation.
819
820 -- Emit C code (even from macros). Avoids echo and line parsing.
821 if sub(aline, 1, 1) == "|" then
822 if not mac_capture then
823 wsync()
824 elseif g_opt.comment then
825 wsync()
826 wcomment(aline)
827 end
828 dostmt(aline)
829 return
830 end
831
832 -- Echo assembler line as a comment.
833 if g_opt.comment then
834 wsync()
835 wcomment(aline)
836 end
837
838 -- Strip assembler comments.
839 aline = gsub(aline, "//.*$", "")
840
841 -- Split line into statements at semicolons.
842 if match(aline, ";") then
843 for stmt in gmatch(aline, "[^;]+") do dostmt(stmt) end
844 else
845 dostmt(aline)
846 end
847end
848
849------------------------------------------------------------------------------
850
851-- Write DynASM header.
852local function dasmhead(out)
853 out:write(format([[
854/*
855** This file has been pre-processed with DynASM.
856** %s
857** DynASM version %s, DynASM %s version %s
858** DO NOT EDIT! The original file is in "%s".
859*/
860
861#if DASM_VERSION != %d
862#error "Version mismatch between DynASM and included encoding engine"
863#endif
864
865]], _info.url,
866 _info.version, g_arch._info.arch, g_arch._info.version,
867 g_fname, _info.vernum))
868end
869
870-- Read input file.
871readfile = function(fin)
872 g_indent = ""
873 g_lineno = 0
874 g_synclineno = -1
875
876 -- Process all lines.
877 for line in fin:lines() do
878 g_lineno = g_lineno + 1
879 g_curline = line
880 local ok, err = pcall(doline, line)
881 if not ok and wprinterr(err, "\n") then return true end
882 end
883 wflush()
884
885 -- Close input file.
886 assert(fin == stdin or fin:close())
887end
888
889-- Write output file.
890local function writefile(outfile)
891 local fout
892
893 -- Open output file.
894 if outfile == nil or outfile == "-" then
895 fout = stdout
896 else
897 fout = assert(io.open(outfile, "w"))
898 end
899
900 -- Write all buffered lines
901 wdumplines(fout, g_wbuffer)
902
903 -- Close output file.
904 assert(fout == stdout or fout:close())
905
906 -- Optionally dump definitions.
907 dumpdef(fout == stdout and stderr or stdout)
908end
909
910-- Translate an input file to an output file.
911local function translate(infile, outfile)
912 g_wbuffer = {}
913 g_indent = ""
914 g_lineno = 0
915 g_synclineno = -1
916
917 -- Put header.
918 wline(dasmhead)
919
920 -- Read input file.
921 local fin
922 if infile == "-" then
923 g_fname = "(stdin)"
924 fin = stdin
925 else
926 g_fname = infile
927 fin = assert(io.open(infile, "r"))
928 end
929 readfile(fin)
930
931 -- Check for errors.
932 if not g_arch then
933 wprinterr(g_fname, ":*: error: missing .arch directive\n")
934 end
935 checkconds()
936 checkmacros()
937 checkcaptures()
938
939 if g_errcount ~= 0 then
940 stderr:write(g_fname, ":*: info: ", g_errcount, " error",
941 (type(g_errcount) == "number" and g_errcount > 1) and "s" or "",
942 " in input file -- no output file generated.\n")
943 dumpdef(stderr)
944 exit(1)
945 end
946
947 -- Write output file.
948 writefile(outfile)
949end
950
951------------------------------------------------------------------------------
952
953-- Print help text.
954function opt_map.help()
955 stdout:write("DynASM -- ", _info.description, ".\n")
956 stdout:write("DynASM ", _info.version, " ", _info.release, " ", _info.url, "\n")
957 stdout:write[[
958
959Usage: dynasm [OPTION]... INFILE.dasc|-
960
961 -h, --help Display this help text.
962 -V, --version Display version and copyright information.
963
964 -o, --outfile FILE Output file name (default is stdout).
965 -I, --include DIR Add directory to the include search path.
966
967 -c, --ccomment Use /* */ comments for assembler lines.
968 -C, --cppcomment Use // comments for assembler lines (default).
969 -N, --nocomment Suppress assembler lines in output.
970 -M, --maccomment Show macro expansions as comments (default off).
971
972 -L, --nolineno Suppress CPP line number information in output.
973 -F, --flushline Flush action list for every line.
974
975 -D NAME[=SUBST] Define a substitution.
976 -U NAME Undefine a substitution.
977
978 -P, --dumpdef Dump defines, macros, etc. Repeat for more output.
979 -A, --dumparch ARCH Load architecture ARCH and dump description.
980]]
981 exit(0)
982end
983
984-- Print version information.
985function opt_map.version()
986 stdout:write(format("%s version %s, released %s\n%s\n\n%s",
987 _info.name, _info.version, _info.release, _info.url, _info.copyright))
988 exit(0)
989end
990
991-- Misc. options.
992function opt_map.outfile(args) g_opt.outfile = optparam(args) end
993function opt_map.include(args) insert(g_opt.include, 1, optparam(args)) end
994function opt_map.ccomment() g_opt.comment = "/*|"; g_opt.endcomment = " */" end
995function opt_map.cppcomment() g_opt.comment = "//|"; g_opt.endcomment = "" end
996function opt_map.nocomment() g_opt.comment = false end
997function opt_map.maccomment() g_opt.maccomment = true end
998function opt_map.nolineno() g_opt.cpp = false end
999function opt_map.flushline() g_opt.flushline = true end
1000function opt_map.dumpdef() g_opt.dumpdef = g_opt.dumpdef + 1 end
1001
1002------------------------------------------------------------------------------
1003
1004-- Short aliases for long options.
1005local opt_alias = {
1006 h = "help", ["?"] = "help", V = "version",
1007 o = "outfile", I = "include",
1008 c = "ccomment", C = "cppcomment", N = "nocomment", M = "maccomment",
1009 L = "nolineno", F = "flushline",
1010 P = "dumpdef", A = "dumparch",
1011}
1012
1013-- Parse single option.
1014local function parseopt(opt, args)
1015 opt_current = #opt == 1 and "-"..opt or "--"..opt
1016 local f = opt_map[opt] or opt_map[opt_alias[opt]]
1017 if not f then
1018 opterror("unrecognized option `", opt_current, "'. Try `--help'.\n")
1019 end
1020 f(args)
1021end
1022
1023-- Parse arguments.
1024local function parseargs(args)
1025 -- Default options.
1026 g_opt.comment = "//|"
1027 g_opt.endcomment = ""
1028 g_opt.cpp = true
1029 g_opt.dumpdef = 0
1030 g_opt.include = { "" }
1031
1032 -- Process all option arguments.
1033 args.argn = 1
1034 repeat
1035 local a = args[args.argn]
1036 if not a then break end
1037 local lopt, opt = match(a, "^%-(%-?)(.+)")
1038 if not opt then break end
1039 args.argn = args.argn + 1
1040 if lopt == "" then
1041 -- Loop through short options.
1042 for o in gmatch(opt, ".") do parseopt(o, args) end
1043 else
1044 -- Long option.
1045 parseopt(opt, args)
1046 end
1047 until false
1048
1049 -- Check for proper number of arguments.
1050 local nargs = #args - args.argn + 1
1051 if nargs ~= 1 then
1052 if nargs == 0 then
1053 if g_opt.dumpdef > 0 then return dumpdef(stdout) end
1054 end
1055 opt_map.help()
1056 end
1057
1058 -- Translate a single input file to a single output file
1059 -- TODO: Handle multiple files?
1060 translate(args[args.argn], g_opt.outfile)
1061end
1062
1063------------------------------------------------------------------------------
1064
1065-- Add the directory dynasm.lua resides in to the Lua module search path.
1066local arg = arg
1067if arg and arg[0] then
1068 local prefix = match(arg[0], "^(.*[/\\])")
1069 if prefix then package.path = prefix.."?.lua;"..package.path end
1070end
1071
1072-- Start DynASM.
1073parseargs{...}
1074
1075------------------------------------------------------------------------------
1076
diff --git a/libraries/luajit-2.0/etc/luajit.1 b/libraries/luajit-2.0/etc/luajit.1
new file mode 100644
index 0000000..57080bc
--- /dev/null
+++ b/libraries/luajit-2.0/etc/luajit.1
@@ -0,0 +1,85 @@
1.TH luajit 1 "" "" "LuaJIT documentation"
2.SH NAME
3luajit \- Just-In-Time Compiler for the Lua Language
4\fB
5.SH SYNOPSIS
6.B luajit
7[\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
8.SH "WEB SITE"
9.IR http://luajit.org
10.SH DESCRIPTION
11.PP
12This is the command-line program to run Lua programs with \fBLuaJIT\fR.
13.PP
14\fBLuaJIT\fR is a just-in-time (JIT) compiler for the Lua language.
15The virtual machine (VM) is based on a fast interpreter combined with
16a trace compiler. It can significantly improve the performance of Lua programs.
17.PP
18\fBLuaJIT\fR is API\- and ABI-compatible with the VM of the standard
19Lua\ 5.1 interpreter. When embedding the VM into an application,
20the built library can be used as a drop-in replacement.
21.SH OPTIONS
22.TP
23.BI "\-e " chunk
24Run the given chunk of Lua code.
25.TP
26.BI "\-l " library
27Load the named library, just like \fBrequire("\fR\fIlibrary\fR\fB")\fR.
28.TP
29.BI "\-b " ...
30Save or list bytecode. Run without arguments to get help on options.
31.TP
32.BI "\-j " command
33Perform LuaJIT control command (optional space after \fB\-j\fR).
34.TP
35.BI "\-O" [opt]
36Control LuaJIT optimizations.
37.TP
38.B "\-i"
39Run in interactive mode.
40.TP
41.B "\-v"
42Show \fBLuaJIT\fR version.
43.TP
44.B "\-\-"
45Stop processing options.
46.TP
47.B "\-"
48Read script from stdin instead.
49.PP
50After all options are processed, the given \fIscript\fR is run.
51The arguments are passed in the global \fIarg\fR table.
52.PP
53Interactive mode is only entered, if no \fIscript\fR and no \fB\-e\fR
54option is given. Interactive mode can be left with EOF (\fICtrl\-Z\fB).
55.SH EXAMPLES
56.TP
57luajit hello.lua world
58
59Prints "Hello world", assuming \fIhello.lua\fR contains:
60.br
61 print("Hello", arg[1])
62.TP
63luajit \-e "local x=0; for i=1,1e9 do x=x+i end; print(x)"
64
65Calculates the sum of the numbers from 1 to 1000000000.
66.br
67And finishes in a reasonable amount of time, too.
68.TP
69luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"
70
71Runs some nested loops and shows the resulting traces.
72.SH COPYRIGHT
73.PP
74\fBLuaJIT\fR is Copyright \(co 2005-2011 Mike Pall.
75.br
76\fBLuaJIT\fR is open source software, released under the MIT license.
77.SH SEE ALSO
78.PP
79More details in the provided HTML docs or at:
80.IR http://luajit.org
81.br
82More about the Lua language can be found at:
83.IR http://lua.org/docs.html
84.PP
85lua(1)
diff --git a/libraries/luajit-2.0/etc/luajit.pc b/libraries/luajit-2.0/etc/luajit.pc
new file mode 100644
index 0000000..974abde
--- /dev/null
+++ b/libraries/luajit-2.0/etc/luajit.pc
@@ -0,0 +1,24 @@
1# Package information for LuaJIT to be used by pkg-config.
2majver=2
3minver=0
4relver=0
5version=${majver}.${minver}.${relver}-beta9
6abiver=5.1
7
8prefix=/usr/local
9exec_prefix=${prefix}
10libdir=${exec_prefix}/lib
11libname=luajit-${abiver}
12includedir=${prefix}/include/luajit-${majver}.${minver}
13
14INSTALL_LMOD=${prefix}/share/lua/${abiver}
15INSTALL_CMOD=${prefix}/lib/lua/${abiver}
16
17Name: LuaJIT
18Description: Just-in-time compiler for Lua
19URL: http://luajit.org
20Version: ${version}
21Requires:
22Libs: -L${libdir} -l${libname}
23Libs.private: -Wl,-E -lm -ldl
24Cflags: -I${includedir}
diff --git a/libraries/luajit-2.0/etc/strict.lua b/libraries/luajit-2.0/etc/strict.lua
new file mode 100644
index 0000000..e57b0cc
--- /dev/null
+++ b/libraries/luajit-2.0/etc/strict.lua
@@ -0,0 +1,41 @@
1--
2-- strict.lua
3-- checks uses of undeclared global variables
4-- All global variables must be 'declared' through a regular assignment
5-- (even assigning nil will do) in a main chunk before being used
6-- anywhere or assigned to inside a function.
7--
8
9local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget
10
11local mt = getmetatable(_G)
12if mt == nil then
13 mt = {}
14 setmetatable(_G, mt)
15end
16
17mt.__declared = {}
18
19local function what ()
20 local d = getinfo(3, "S")
21 return d and d.what or "C"
22end
23
24mt.__newindex = function (t, n, v)
25 if not mt.__declared[n] then
26 local w = what()
27 if w ~= "main" and w ~= "C" then
28 error("assign to undeclared variable '"..n.."'", 2)
29 end
30 mt.__declared[n] = true
31 end
32 rawset(t, n, v)
33end
34
35mt.__index = function (t, n)
36 if not mt.__declared[n] and what() ~= "C" then
37 error("variable '"..n.."' is not declared", 2)
38 end
39 return rawget(t, n)
40end
41
diff --git a/libraries/luajit-2.0/lib/.gitignore b/libraries/luajit-2.0/lib/.gitignore
new file mode 100644
index 0000000..500e285
--- /dev/null
+++ b/libraries/luajit-2.0/lib/.gitignore
@@ -0,0 +1 @@
vmdef.lua
diff --git a/libraries/luajit-2.0/lib/bc.lua b/libraries/luajit-2.0/lib/bc.lua
new file mode 100644
index 0000000..c2c9502
--- /dev/null
+++ b/libraries/luajit-2.0/lib/bc.lua
@@ -0,0 +1,192 @@
1----------------------------------------------------------------------------
2-- LuaJIT bytecode listing module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT license. See Copyright Notice in luajit.h
6----------------------------------------------------------------------------
7--
8-- This module lists the bytecode of a Lua function. If it's loaded by -jbc
9-- it hooks into the parser and lists all functions of a chunk as they
10-- are parsed.
11--
12-- Example usage:
13--
14-- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)'
15-- luajit -jbc=- foo.lua
16-- luajit -jbc=foo.list foo.lua
17--
18-- Default output is to stderr. To redirect the output to a file, pass a
19-- filename as an argument (use '-' for stdout) or set the environment
20-- variable LUAJIT_LISTFILE. The file is overwritten every time the module
21-- is started.
22--
23-- This module can also be used programmatically:
24--
25-- local bc = require("jit.bc")
26--
27-- local function foo() print("hello") end
28--
29-- bc.dump(foo) --> -- BYTECODE -- [...]
30-- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello"
31--
32-- local out = {
33-- -- Do something with each line:
34-- write = function(t, ...) io.write(...) end,
35-- close = function(t) end,
36-- flush = function(t) end,
37-- }
38-- bc.dump(foo, out)
39--
40------------------------------------------------------------------------------
41
42-- Cache some library functions and objects.
43local jit = require("jit")
44assert(jit.version_num == 20000, "LuaJIT core/library version mismatch")
45local jutil = require("jit.util")
46local vmdef = require("jit.vmdef")
47local bit = require("bit")
48local sub, gsub, format = string.sub, string.gsub, string.format
49local byte, band, shr = string.byte, bit.band, bit.rshift
50local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck
51local funcuvname = jutil.funcuvname
52local bcnames = vmdef.bcnames
53local stdout, stderr = io.stdout, io.stderr
54
55------------------------------------------------------------------------------
56
57local function ctlsub(c)
58 if c == "\n" then return "\\n"
59 elseif c == "\r" then return "\\r"
60 elseif c == "\t" then return "\\t"
61 elseif c == "\r" then return "\\r"
62 else return format("\\%03d", byte(c))
63 end
64end
65
66-- Return one bytecode line.
67local function bcline(func, pc, prefix)
68 local ins, m = funcbc(func, pc)
69 if not ins then return end
70 local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128)
71 local a = band(shr(ins, 8), 0xff)
72 local oidx = 6*band(ins, 0xff)
73 local op = sub(bcnames, oidx+1, oidx+6)
74 local s = format("%04d %s %-6s %3s ",
75 pc, prefix or " ", op, ma == 0 and "" or a)
76 local d = shr(ins, 16)
77 if mc == 13*128 then -- BCMjump
78 return format("%s=> %04d\n", s, pc+d-0x7fff)
79 end
80 if mb ~= 0 then
81 d = band(d, 0xff)
82 elseif mc == 0 then
83 return s.."\n"
84 end
85 local kc
86 if mc == 10*128 then -- BCMstr
87 kc = funck(func, -d-1)
88 kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub))
89 elseif mc == 9*128 then -- BCMnum
90 kc = funck(func, d)
91 if op == "TSETM " then kc = kc - 2^52 end
92 elseif mc == 12*128 then -- BCMfunc
93 local fi = funcinfo(funck(func, -d-1))
94 if fi.ffid then
95 kc = vmdef.ffnames[fi.ffid]
96 else
97 kc = fi.loc
98 end
99 elseif mc == 5*128 then -- BCMuv
100 kc = funcuvname(func, d)
101 end
102 if ma == 5 then -- BCMuv
103 local ka = funcuvname(func, a)
104 if kc then kc = ka.." ; "..kc else kc = ka end
105 end
106 if mb ~= 0 then
107 local b = shr(ins, 24)
108 if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end
109 return format("%s%3d %3d\n", s, b, d)
110 end
111 if kc then return format("%s%3d ; %s\n", s, d, kc) end
112 if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits
113 return format("%s%3d\n", s, d)
114end
115
116-- Collect branch targets of a function.
117local function bctargets(func)
118 local target = {}
119 for pc=1,1000000000 do
120 local ins, m = funcbc(func, pc)
121 if not ins then break end
122 if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end
123 end
124 return target
125end
126
127-- Dump bytecode instructions of a function.
128local function bcdump(func, out, all)
129 if not out then out = stdout end
130 local fi = funcinfo(func)
131 if all and fi.children then
132 for n=-1,-1000000000,-1 do
133 local k = funck(func, n)
134 if not k then break end
135 if type(k) == "proto" then bcdump(k, out, true) end
136 end
137 end
138 out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined))
139 local target = bctargets(func)
140 for pc=1,1000000000 do
141 local s = bcline(func, pc, target[pc] and "=>")
142 if not s then break end
143 out:write(s)
144 end
145 out:write("\n")
146 out:flush()
147end
148
149------------------------------------------------------------------------------
150
151-- Active flag and output file handle.
152local active, out
153
154-- List handler.
155local function h_list(func)
156 return bcdump(func, out)
157end
158
159-- Detach list handler.
160local function bclistoff()
161 if active then
162 active = false
163 jit.attach(h_list)
164 if out and out ~= stdout and out ~= stderr then out:close() end
165 out = nil
166 end
167end
168
169-- Open the output file and attach list handler.
170local function bcliston(outfile)
171 if active then bclistoff() end
172 if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end
173 if outfile then
174 out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
175 else
176 out = stderr
177 end
178 jit.attach(h_list, "bc")
179 active = true
180end
181
182-- Public module functions.
183module(...)
184
185line = bcline
186dump = bcdump
187targets = bctargets
188
189on = bcliston
190off = bclistoff
191start = bcliston -- For -j command line option.
192
diff --git a/libraries/luajit-2.0/lib/bcsave.lua b/libraries/luajit-2.0/lib/bcsave.lua
new file mode 100644
index 0000000..1783014
--- /dev/null
+++ b/libraries/luajit-2.0/lib/bcsave.lua
@@ -0,0 +1,496 @@
1----------------------------------------------------------------------------
2-- LuaJIT module to save/list bytecode.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT license. See Copyright Notice in luajit.h
6----------------------------------------------------------------------------
7--
8-- This module saves or lists the bytecode for an input file.
9-- It's run by the -b command line option.
10--
11------------------------------------------------------------------------------
12
13local jit = require("jit")
14assert(jit.version_num == 20000, "LuaJIT core/library version mismatch")
15
16-- Symbol name prefix for LuaJIT bytecode.
17local LJBC_PREFIX = "luaJIT_BC_"
18
19------------------------------------------------------------------------------
20
21local function usage()
22 io.stderr:write[[
23Save LuaJIT bytecode: luajit -b[options] input output
24 -l Only list bytecode.
25 -s Strip debug info (default).
26 -g Keep debug info.
27 -n name Set module name (default: auto-detect from input name).
28 -t type Set output file type (default: auto-detect from output name).
29 -a arch Override architecture for object files (default: native).
30 -o os Override OS for object files (default: native).
31 -e chunk Use chunk string as input.
32 -- Stop handling options.
33 - Use stdin as input and/or stdout as output.
34
35File types: c h obj o raw (default)
36]]
37 os.exit(1)
38end
39
40local function check(ok, ...)
41 if ok then return ok, ... end
42 io.stderr:write("luajit: ", ...)
43 io.stderr:write("\n")
44 os.exit(1)
45end
46
47local function readfile(input)
48 if type(input) == "function" then return input end
49 if input == "-" then input = nil end
50 return check(loadfile(input))
51end
52
53local function savefile(name, mode)
54 if name == "-" then return io.stdout end
55 return check(io.open(name, mode))
56end
57
58------------------------------------------------------------------------------
59
60local map_type = {
61 raw = "raw", c = "c", h = "h", o = "obj", obj = "obj",
62}
63
64local map_arch = {
65 x86 = true, x64 = true, arm = true, ppc = true, ppcspe = true,
66}
67
68local map_os = {
69 linux = true, windows = true, osx = true, freebsd = true, netbsd = true,
70 openbsd = true, solaris = true,
71}
72
73local function checkarg(str, map, err)
74 str = string.lower(str)
75 local s = check(map[str], "unknown ", err)
76 return s == true and str or s
77end
78
79local function detecttype(str)
80 local ext = string.match(string.lower(str), "%.(%a+)$")
81 return map_type[ext] or "raw"
82end
83
84local function checkmodname(str)
85 check(string.match(str, "^[%w_.%-]+$"), "bad module name")
86 return string.gsub(str, "[%.%-]", "_")
87end
88
89local function detectmodname(str)
90 if type(str) == "string" then
91 local tail = string.match(str, "[^/\\]+$")
92 if tail then str = tail end
93 local head = string.match(str, "^(.*)%.[^.]*$")
94 if head then str = head end
95 str = string.match(str, "^[%w_.%-]+")
96 else
97 str = nil
98 end
99 check(str, "cannot derive module name, use -n name")
100 return string.gsub(str, "[%.%-]", "_")
101end
102
103------------------------------------------------------------------------------
104
105local function bcsave_tail(fp, output, s)
106 local ok, err = fp:write(s)
107 if ok and output ~= "-" then ok, err = fp:close() end
108 check(ok, "cannot write ", output, ": ", err)
109end
110
111local function bcsave_raw(output, s)
112 local fp = savefile(output, "wb")
113 bcsave_tail(fp, output, s)
114end
115
116local function bcsave_c(ctx, output, s)
117 local fp = savefile(output, "w")
118 if ctx.type == "c" then
119 fp:write(string.format([[
120#ifdef _cplusplus
121extern "C"
122#endif
123#ifdef _WIN32
124__declspec(dllexport)
125#endif
126const char %s%s[] = {
127]], LJBC_PREFIX, ctx.modname))
128 else
129 fp:write(string.format([[
130#define %s%s_SIZE %d
131static const char %s%s[] = {
132]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname))
133 end
134 local t, n, m = {}, 0, 0
135 for i=1,#s do
136 local b = tostring(string.byte(s, i))
137 m = m + #b + 1
138 if m > 78 then
139 fp:write(table.concat(t, ",", 1, n), ",\n")
140 n, m = 0, #b + 1
141 end
142 n = n + 1
143 t[n] = b
144 end
145 bcsave_tail(fp, output, table.concat(t, ",", 1, n).."\n};\n")
146end
147
148local function bcsave_elfobj(ctx, output, s, ffi)
149 ffi.cdef[[
150typedef struct {
151 uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
152 uint16_t type, machine;
153 uint32_t version;
154 uint32_t entry, phofs, shofs;
155 uint32_t flags;
156 uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
157} ELF32header;
158typedef struct {
159 uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
160 uint16_t type, machine;
161 uint32_t version;
162 uint64_t entry, phofs, shofs;
163 uint32_t flags;
164 uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
165} ELF64header;
166typedef struct {
167 uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize;
168} ELF32sectheader;
169typedef struct {
170 uint32_t name, type;
171 uint64_t flags, addr, ofs, size;
172 uint32_t link, info;
173 uint64_t align, entsize;
174} ELF64sectheader;
175typedef struct {
176 uint32_t name, value, size;
177 uint8_t info, other;
178 uint16_t sectidx;
179} ELF32symbol;
180typedef struct {
181 uint32_t name;
182 uint8_t info, other;
183 uint16_t sectidx;
184 uint64_t value, size;
185} ELF64symbol;
186typedef struct {
187 ELF32header hdr;
188 ELF32sectheader sect[6];
189 ELF32symbol sym[2];
190 uint8_t space[4096];
191} ELF32obj;
192typedef struct {
193 ELF64header hdr;
194 ELF64sectheader sect[6];
195 ELF64symbol sym[2];
196 uint8_t space[4096];
197} ELF64obj;
198]]
199 local symname = LJBC_PREFIX..ctx.modname
200 local is64, isbe = false, false
201 if ctx.arch == "x64" then
202 is64 = true
203 elseif ctx.arch == "ppc" or ctx.arch == "ppcspe" then
204 isbe = true
205 end
206
207 -- Handle different host/target endianess.
208 local function f32(x) return x end
209 local f16, fofs = f32, f32
210 if ffi.abi("be") ~= isbe then
211 f32 = bit.bswap
212 function f16(x) return bit.rshift(bit.bswap(x), 16) end
213 if is64 then
214 function fofs(x) return bit.bswap(x)*(2ll^32) end
215 else
216 fofs = f32
217 end
218 end
219
220 -- Create ELF object and fill in header.
221 local o = ffi.new(is64 and "ELF64obj" or "ELF32obj")
222 local hdr = o.hdr
223 if ctx.os == "bsd" or ctx.os == "other" then -- Determine native hdr.eosabi.
224 local bf = assert(io.open("/bin/ls", "rb"))
225 local bs = bf:read(9)
226 bf:close()
227 ffi.copy(o, bs, 9)
228 check(hdr.emagic[0] == 127, "no support for writing native object files")
229 else
230 hdr.emagic = "\127ELF"
231 hdr.eosabi = ({ freebsd=9, netbsd=2, openbsd=12, solaris=6 })[ctx.os] or 0
232 end
233 hdr.eclass = is64 and 2 or 1
234 hdr.eendian = isbe and 2 or 1
235 hdr.eversion = 1
236 hdr.type = f16(1)
237 hdr.machine = f16(({ x86=3, x64=62, arm=40, ppc=20, ppcspe=20 })[ctx.arch])
238 hdr.version = f32(1)
239 hdr.shofs = fofs(ffi.offsetof(o, "sect"))
240 hdr.ehsize = f16(ffi.sizeof(hdr))
241 hdr.shentsize = f16(ffi.sizeof(o.sect[0]))
242 hdr.shnum = f16(6)
243 hdr.shstridx = f16(2)
244
245 -- Fill in sections and symbols.
246 local sofs, ofs = ffi.offsetof(o, "space"), 1
247 for i,name in ipairs{
248 ".symtab", ".shstrtab", ".strtab", ".rodata", ".note.GNU-stack",
249 } do
250 local sect = o.sect[i]
251 sect.align = fofs(1)
252 sect.name = f32(ofs)
253 ffi.copy(o.space+ofs, name)
254 ofs = ofs + #name+1
255 end
256 o.sect[1].type = f32(2) -- .symtab
257 o.sect[1].link = f32(3)
258 o.sect[1].info = f32(1)
259 o.sect[1].align = fofs(8)
260 o.sect[1].ofs = fofs(ffi.offsetof(o, "sym"))
261 o.sect[1].entsize = fofs(ffi.sizeof(o.sym[0]))
262 o.sect[1].size = fofs(ffi.sizeof(o.sym))
263 o.sym[1].name = f32(1)
264 o.sym[1].sectidx = f16(4)
265 o.sym[1].size = fofs(#s)
266 o.sym[1].info = 17
267 o.sect[2].type = f32(3) -- .shstrtab
268 o.sect[2].ofs = fofs(sofs)
269 o.sect[2].size = fofs(ofs)
270 o.sect[3].type = f32(3) -- .strtab
271 o.sect[3].ofs = fofs(sofs + ofs)
272 o.sect[3].size = fofs(#symname+1)
273 ffi.copy(o.space+ofs+1, symname)
274 ofs = ofs + #symname + 2
275 o.sect[4].type = f32(1) -- .rodata
276 o.sect[4].flags = fofs(2)
277 o.sect[4].ofs = fofs(sofs + ofs)
278 o.sect[4].size = fofs(#s)
279 o.sect[5].type = f32(1) -- .note.GNU-stack
280 o.sect[5].ofs = fofs(sofs + ofs + #s)
281
282 -- Write ELF object file.
283 local fp = savefile(output, "wb")
284 fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs))
285 bcsave_tail(fp, output, s)
286end
287
288local function bcsave_peobj(ctx, output, s, ffi)
289 ffi.cdef[[
290typedef struct {
291 uint16_t arch, nsects;
292 uint32_t time, symtabofs, nsyms;
293 uint16_t opthdrsz, flags;
294} PEheader;
295typedef struct {
296 char name[8];
297 uint32_t vsize, vaddr, size, ofs, relocofs, lineofs;
298 uint16_t nreloc, nline;
299 uint32_t flags;
300} PEsection;
301typedef struct __attribute((packed)) {
302 union {
303 char name[8];
304 uint32_t nameref[2];
305 };
306 uint32_t value;
307 int16_t sect;
308 uint16_t type;
309 uint8_t scl, naux;
310} PEsym;
311typedef struct __attribute((packed)) {
312 uint32_t size;
313 uint16_t nreloc, nline;
314 uint32_t cksum;
315 uint16_t assoc;
316 uint8_t comdatsel, unused[3];
317} PEsymaux;
318typedef struct {
319 PEheader hdr;
320 PEsection sect[2];
321 // Must be an even number of symbol structs.
322 PEsym sym0;
323 PEsymaux sym0aux;
324 PEsym sym1;
325 PEsymaux sym1aux;
326 PEsym sym2;
327 PEsym sym3;
328 uint32_t strtabsize;
329 uint8_t space[4096];
330} PEobj;
331]]
332 local symname = LJBC_PREFIX..ctx.modname
333 local is64 = false
334 if ctx.arch == "x86" then
335 symname = "_"..symname
336 elseif ctx.arch == "x64" then
337 is64 = true
338 end
339 local symexport = " /EXPORT:"..symname..",DATA "
340
341 -- The file format is always little-endian. Swap if the host is big-endian.
342 local function f32(x) return x end
343 local f16 = f32
344 if ffi.abi("be") then
345 f32 = bit.bswap
346 function f16(x) return bit.rshift(bit.bswap(x), 16) end
347 end
348
349 -- Create PE object and fill in header.
350 local o = ffi.new("PEobj")
351 local hdr = o.hdr
352 hdr.arch = f16(({ x86=0x14c, x64=0x8664, arm=0x1c0, ppc=0x1f2 })[ctx.arch])
353 hdr.nsects = f16(2)
354 hdr.symtabofs = f32(ffi.offsetof(o, "sym0"))
355 hdr.nsyms = f32(6)
356
357 -- Fill in sections and symbols.
358 o.sect[0].name = ".drectve"
359 o.sect[0].size = f32(#symexport)
360 o.sect[0].flags = f32(0x00100a00)
361 o.sym0.sect = f16(1)
362 o.sym0.scl = 3
363 o.sym0.name = ".drectve"
364 o.sym0.naux = 1
365 o.sym0aux.size = f32(#symexport)
366 o.sect[1].name = ".rdata"
367 o.sect[1].size = f32(#s)
368 o.sect[1].flags = f32(0x40300040)
369 o.sym1.sect = f16(2)
370 o.sym1.scl = 3
371 o.sym1.name = ".rdata"
372 o.sym1.naux = 1
373 o.sym1aux.size = f32(#s)
374 o.sym2.sect = f16(2)
375 o.sym2.scl = 2
376 o.sym2.nameref[1] = f32(4)
377 o.sym3.sect = f16(-1)
378 o.sym3.scl = 2
379 o.sym3.value = f32(1)
380 o.sym3.name = "@feat.00" -- Mark as SafeSEH compliant.
381 ffi.copy(o.space, symname)
382 local ofs = #symname + 1
383 o.strtabsize = f32(ofs + 4)
384 o.sect[0].ofs = f32(ffi.offsetof(o, "space") + ofs)
385 ffi.copy(o.space + ofs, symexport)
386 ofs = ofs + #symexport
387 o.sect[1].ofs = f32(ffi.offsetof(o, "space") + ofs)
388
389 -- Write PE object file.
390 local fp = savefile(output, "wb")
391 fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs))
392 bcsave_tail(fp, output, s)
393end
394
395local function bcsave_machobj(ctx, output, s, ffi)
396 check(false, "NYI: no support for writing OSX object files")
397end
398
399local function bcsave_obj(ctx, output, s)
400 local ok, ffi = pcall(require, "ffi")
401 check(ok, "FFI library required to write this file type")
402 if ctx.os == "windows" then
403 return bcsave_peobj(ctx, output, s, ffi)
404 elseif ctx.os == "osx" then
405 return bcsave_machobj(ctx, output, s, ffi)
406 else
407 return bcsave_elfobj(ctx, output, s, ffi)
408 end
409end
410
411------------------------------------------------------------------------------
412
413local function bclist(input, output)
414 local f = readfile(input)
415 require("jit.bc").dump(f, savefile(output, "w"), true)
416end
417
418local function bcsave(ctx, input, output)
419 local f = readfile(input)
420 local s = string.dump(f, ctx.strip)
421 local t = ctx.type
422 if not t then
423 t = detecttype(output)
424 ctx.type = t
425 end
426 if t == "raw" then
427 bcsave_raw(output, s)
428 else
429 if not ctx.modname then ctx.modname = detectmodname(input) end
430 if t == "obj" then
431 bcsave_obj(ctx, output, s)
432 else
433 bcsave_c(ctx, output, s)
434 end
435 end
436end
437
438local function docmd(...)
439 local arg = {...}
440 local n = 1
441 local list = false
442 local ctx = {
443 strip = true, arch = jit.arch, os = string.lower(jit.os),
444 type = false, modname = false,
445 }
446 while n <= #arg do
447 local a = arg[n]
448 if type(a) == "string" and string.sub(a, 1, 1) == "-" and a ~= "-" then
449 table.remove(arg, n)
450 if a == "--" then break end
451 for m=2,#a do
452 local opt = string.sub(a, m, m)
453 if opt == "l" then
454 list = true
455 elseif opt == "s" then
456 ctx.strip = true
457 elseif opt == "g" then
458 ctx.strip = false
459 else
460 if arg[n] == nil or m ~= #a then usage() end
461 if opt == "e" then
462 if n ~= 1 then usage() end
463 arg[1] = check(loadstring(arg[1]))
464 elseif opt == "n" then
465 ctx.modname = checkmodname(table.remove(arg, n))
466 elseif opt == "t" then
467 ctx.type = checkarg(table.remove(arg, n), map_type, "file type")
468 elseif opt == "a" then
469 ctx.arch = checkarg(table.remove(arg, n), map_arch, "architecture")
470 elseif opt == "o" then
471 ctx.os = checkarg(table.remove(arg, n), map_os, "OS name")
472 else
473 usage()
474 end
475 end
476 end
477 else
478 n = n + 1
479 end
480 end
481 if list then
482 if #arg == 0 or #arg > 2 then usage() end
483 bclist(arg[1], arg[2] or "-")
484 else
485 if #arg ~= 2 then usage() end
486 bcsave(ctx, arg[1], arg[2])
487 end
488end
489
490------------------------------------------------------------------------------
491
492-- Public module functions.
493module(...)
494
495start = docmd -- Process -b command line option.
496
diff --git a/libraries/luajit-2.0/lib/dis_arm.lua b/libraries/luajit-2.0/lib/dis_arm.lua
new file mode 100644
index 0000000..c2d1408
--- /dev/null
+++ b/libraries/luajit-2.0/lib/dis_arm.lua
@@ -0,0 +1,543 @@
1----------------------------------------------------------------------------
2-- LuaJIT ARM disassembler module.
3--
4-- Copyright (C) 2005-2010 Mike Pall. All rights reserved.
5-- Released under the MIT license. See Copyright Notice in luajit.h
6----------------------------------------------------------------------------
7-- This is a helper module used by the LuaJIT machine code dumper module.
8--
9-- It disassembles most user-mode ARMv7 instructions
10-- NYI: Advanced SIMD and VFP instructions.
11------------------------------------------------------------------------------
12
13local type = type
14local sub, byte, format = string.sub, string.byte, string.format
15local match, gmatch, gsub = string.match, string.gmatch, string.gsub
16local concat = table.concat
17local bit = require("bit")
18local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex
19local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
20
21------------------------------------------------------------------------------
22-- Opcode maps
23------------------------------------------------------------------------------
24
25local map_loadc = {
26 shift = 9, mask = 7,
27 [5] = {
28 shift = 0, mask = 0 -- NYI VFP load/store.
29 },
30 _ = {
31 shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc.
32 },
33}
34
35local map_datac = {
36 shift = 24, mask = 1,
37 [0] = {
38 shift = 9, mask = 7,
39 [5] = {
40 shift = 0, mask = 0 -- NYI VFP data.
41 },
42 _ = {
43 shift = 0, mask = 0 -- NYI cdp, mcr, mrc.
44 },
45 },
46 "svcT",
47}
48
49local map_loadcu = {
50 shift = 0, mask = 0, -- NYI unconditional CP load/store.
51}
52
53local map_datacu = {
54 shift = 0, mask = 0, -- NYI unconditional CP data.
55}
56
57local map_simddata = {
58 shift = 0, mask = 0, -- NYI SIMD data.
59}
60
61local map_simdload = {
62 shift = 0, mask = 0, -- NYI SIMD load/store, preload.
63}
64
65local map_preload = {
66 shift = 0, mask = 0, -- NYI preload.
67}
68
69local map_media = {
70 shift = 20, mask = 31,
71 [0] = false,
72 { --01
73 shift = 5, mask = 7,
74 [0] = "sadd16DNM", "sasxDNM", "ssaxDNM", "ssub16DNM",
75 "sadd8DNM", false, false, "ssub8DNM",
76 },
77 { --02
78 shift = 5, mask = 7,
79 [0] = "qadd16DNM", "qasxDNM", "qsaxDNM", "qsub16DNM",
80 "qadd8DNM", false, false, "qsub8DNM",
81 },
82 { --03
83 shift = 5, mask = 7,
84 [0] = "shadd16DNM", "shasxDNM", "shsaxDNM", "shsub16DNM",
85 "shadd8DNM", false, false, "shsub8DNM",
86 },
87 false,
88 { --05
89 shift = 5, mask = 7,
90 [0] = "uadd16DNM", "uasxDNM", "usaxDNM", "usub16DNM",
91 "uadd8DNM", false, false, "usub8DNM",
92 },
93 { --06
94 shift = 5, mask = 7,
95 [0] = "uqadd16DNM", "uqasxDNM", "uqsaxDNM", "uqsub16DNM",
96 "uqadd8DNM", false, false, "uqsub8DNM",
97 },
98 { --07
99 shift = 5, mask = 7,
100 [0] = "uhadd16DNM", "uhasxDNM", "uhsaxDNM", "uhsub16DNM",
101 "uhadd8DNM", false, false, "uhsub8DNM",
102 },
103 { --08
104 shift = 5, mask = 7,
105 [0] = "pkhbtDNMU", false, "pkhtbDNMU",
106 { shift = 16, mask = 15, [15] = "sxtb16DMU", _ = "sxtab16DNMU", },
107 "pkhbtDNMU", "selDNM", "pkhtbDNMU",
108 },
109 false,
110 { --0a
111 shift = 5, mask = 7,
112 [0] = "ssatDxMu", "ssat16DxM", "ssatDxMu",
113 { shift = 16, mask = 15, [15] = "sxtbDMU", _ = "sxtabDNMU", },
114 "ssatDxMu", false, "ssatDxMu",
115 },
116 { --0b
117 shift = 5, mask = 7,
118 [0] = "ssatDxMu", "revDM", "ssatDxMu",
119 { shift = 16, mask = 15, [15] = "sxthDMU", _ = "sxtahDNMU", },
120 "ssatDxMu", "rev16DM", "ssatDxMu",
121 },
122 { --0c
123 shift = 5, mask = 7,
124 [3] = { shift = 16, mask = 15, [15] = "uxtb16DMU", _ = "uxtab16DNMU", },
125 },
126 false,
127 { --0e
128 shift = 5, mask = 7,
129 [0] = "usatDwMu", "usat16DwM", "usatDwMu",
130 { shift = 16, mask = 15, [15] = "uxtbDMU", _ = "uxtabDNMU", },
131 "usatDwMu", false, "usatDwMu",
132 },
133 { --0f
134 shift = 5, mask = 7,
135 [0] = "usatDwMu", "rbitDM", "usatDwMu",
136 { shift = 16, mask = 15, [15] = "uxthDMU", _ = "uxtahDNMU", },
137 "usatDwMu", "revshDM", "usatDwMu",
138 },
139 { --10
140 shift = 12, mask = 15,
141 [15] = {
142 shift = 5, mask = 7,
143 "smuadNMS", "smuadxNMS", "smusdNMS", "smusdxNMS",
144 },
145 _ = {
146 shift = 5, mask = 7,
147 [0] = "smladNMSD", "smladxNMSD", "smlsdNMSD", "smlsdxNMSD",
148 },
149 },
150 false, false, false,
151 { --14
152 shift = 5, mask = 7,
153 [0] = "smlaldDNMS", "smlaldxDNMS", "smlsldDNMS", "smlsldxDNMS",
154 },
155 { --15
156 shift = 5, mask = 7,
157 [0] = { shift = 12, mask = 15, [15] = "smmulNMS", _ = "smmlaNMSD", },
158 { shift = 12, mask = 15, [15] = "smmulrNMS", _ = "smmlarNMSD", },
159 false, false, false, false,
160 "smmlsNMSD", "smmlsrNMSD",
161 },
162 false, false,
163 { --18
164 shift = 5, mask = 7,
165 [0] = { shift = 12, mask = 15, [15] = "usad8NMS", _ = "usada8NMSD", },
166 },
167 false,
168 { --1a
169 shift = 5, mask = 3, [2] = "sbfxDMvw",
170 },
171 { --1b
172 shift = 5, mask = 3, [2] = "sbfxDMvw",
173 },
174 { --1c
175 shift = 5, mask = 3,
176 [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", },
177 },
178 { --1d
179 shift = 5, mask = 3,
180 [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", },
181 },
182 { --1e
183 shift = 5, mask = 3, [2] = "ubfxDMvw",
184 },
185 { --1f
186 shift = 5, mask = 3, [2] = "ubfxDMvw",
187 },
188}
189
190local map_load = {
191 shift = 21, mask = 9,
192 {
193 shift = 20, mask = 5,
194 [0] = "strtDL", "ldrtDL", [4] = "strbtDL", [5] = "ldrbtDL",
195 },
196 _ = {
197 shift = 20, mask = 5,
198 [0] = "strDL", "ldrDL", [4] = "strbDL", [5] = "ldrbDL",
199 }
200}
201
202local map_load1 = {
203 shift = 4, mask = 1,
204 [0] = map_load, map_media,
205}
206
207local map_loadm = {
208 shift = 20, mask = 1,
209 [0] = {
210 shift = 23, mask = 3,
211 [0] = "stmdaNR", "stmNR",
212 { shift = 16, mask = 63, [45] = "pushR", _ = "stmdbNR", }, "stmibNR",
213 },
214 {
215 shift = 23, mask = 3,
216 [0] = "ldmdaNR", { shift = 16, mask = 63, [61] = "popR", _ = "ldmNR", },
217 "ldmdbNR", "ldmibNR",
218 },
219}
220
221local map_data = {
222 shift = 21, mask = 15,
223 [0] = "andDNPs", "eorDNPs", "subDNPs", "rsbDNPs",
224 "addDNPs", "adcDNPs", "sbcDNPs", "rscDNPs",
225 "tstNP", "teqNP", "cmpNP", "cmnNP",
226 "orrDNPs", "movDPs", "bicDNPs", "mvnDPs",
227}
228
229local map_mul = {
230 shift = 21, mask = 7,
231 [0] = "mulNMSs", "mlaNMSDs", "umaalDNMS", "mlsDNMS",
232 "umullDNMSs", "umlalDNMSs", "smullDNMSs", "smlalDNMSs",
233}
234
235local map_sync = {
236 shift = 20, mask = 15, -- NYI: brackets around N. R(D+1) for ldrexd/strexd.
237 [0] = "swpDMN", false, false, false,
238 "swpbDMN", false, false, false,
239 "strexDMN", "ldrexDN", "strexdDN", "ldrexdDN",
240 "strexbDMN", "ldrexbDN", "strexhDN", "ldrexhDN",
241}
242
243local map_mulh = {
244 shift = 21, mask = 3,
245 [0] = { shift = 5, mask = 3,
246 [0] = "smlabbNMSD", "smlatbNMSD", "smlabtNMSD", "smlattNMSD", },
247 { shift = 5, mask = 3,
248 [0] = "smlawbNMSD", "smulwbNMS", "smlawtNMSD", "smulwtNMS", },
249 { shift = 5, mask = 3,
250 [0] = "smlalbbDNMS", "smlaltbDNMS", "smlalbtDNMS", "smlalttDNMS", },
251 { shift = 5, mask = 3,
252 [0] = "smulbbNMS", "smultbNMS", "smulbtNMS", "smulttNMS", },
253}
254
255local map_misc = {
256 shift = 4, mask = 7,
257 -- NYI: decode PSR bits of msr.
258 [0] = { shift = 21, mask = 1, [0] = "mrsD", "msrM", },
259 { shift = 21, mask = 3, "bxM", false, "clzDM", },
260 { shift = 21, mask = 3, "bxjM", },
261 { shift = 21, mask = 3, "blxM", },
262 false,
263 { shift = 21, mask = 3, [0] = "qaddDMN", "qsubDMN", "qdaddDMN", "qdsubDMN", },
264 false,
265 { shift = 21, mask = 3, "bkptK", },
266}
267
268local map_datar = {
269 shift = 4, mask = 9,
270 [9] = {
271 shift = 5, mask = 3,
272 [0] = { shift = 24, mask = 1, [0] = map_mul, map_sync, },
273 { shift = 20, mask = 1, [0] = "strhDL", "ldrhDL", },
274 { shift = 20, mask = 1, [0] = "ldrdDL", "ldrsbDL", },
275 { shift = 20, mask = 1, [0] = "strdDL", "ldrshDL", },
276 },
277 _ = {
278 shift = 20, mask = 25,
279 [16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, },
280 _ = {
281 shift = 0, mask = 0xffffffff,
282 [bor(0xe1a00000)] = "nop",
283 _ = map_data,
284 }
285 },
286}
287
288local map_datai = {
289 shift = 20, mask = 31, -- NYI: decode PSR bits of msr. Decode imm12.
290 [16] = "movwDW", [20] = "movtDW",
291 [18] = { shift = 0, mask = 0xf00ff, [0] = "nopv6", _ = "msrNW", },
292 [22] = "msrNW",
293 _ = map_data,
294}
295
296local map_branch = {
297 shift = 24, mask = 1,
298 [0] = "bB", "blB"
299}
300
301local map_condins = {
302 [0] = map_datar, map_datai, map_load, map_load1,
303 map_loadm, map_branch, map_loadc, map_datac
304}
305
306-- NYI: setend.
307local map_uncondins = {
308 [0] = false, map_simddata, map_simdload, map_preload,
309 false, "blxB", map_loadcu, map_datacu,
310}
311
312------------------------------------------------------------------------------
313
314local map_gpr = {
315 [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
316 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
317}
318
319local map_cond = {
320 [0] = "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc",
321 "hi", "ls", "ge", "lt", "gt", "le", "al",
322}
323
324local map_shift = { [0] = "lsl", "lsr", "asr", "ror", }
325
326------------------------------------------------------------------------------
327
328-- Output a nicely formatted line with an opcode and operands.
329local function putop(ctx, text, operands)
330 local pos = ctx.pos
331 local extra = ""
332 if ctx.rel then
333 local sym = ctx.symtab[ctx.rel]
334 if sym then
335 extra = "\t->"..sym
336 elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then
337 extra = "\t; 0x"..tohex(ctx.rel)
338 end
339 end
340 if ctx.hexdump > 0 then
341 ctx.out(format("%08x %s %-5s %s%s\n",
342 ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
343 else
344 ctx.out(format("%08x %-5s %s%s\n",
345 ctx.addr+pos, text, concat(operands, ", "), extra))
346 end
347 ctx.pos = pos + 4
348end
349
350-- Fallback for unknown opcodes.
351local function unknown(ctx)
352 return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
353end
354
355-- Format operand 2 of load/store opcodes.
356local function fmtload(ctx, op, pos)
357 local base = map_gpr[band(rshift(op, 16), 15)]
358 local x, ofs
359 local ext = (band(op, 0x04000000) == 0)
360 if not ext and band(op, 0x02000000) == 0 then
361 ofs = band(op, 4095)
362 if band(op, 0x00800000) == 0 then ofs = -ofs end
363 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
364 ofs = "#"..ofs
365 elseif ext and band(op, 0x00400000) ~= 0 then
366 ofs = band(op, 15) + band(rshift(op, 4), 0xf0)
367 if band(op, 0x00800000) == 0 then ofs = -ofs end
368 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
369 ofs = "#"..ofs
370 else
371 ofs = map_gpr[band(op, 15)]
372 if ext or band(op, 0xfe0) == 0 then
373 elseif band(op, 0xfe0) == 0x60 then
374 ofs = format("%s, rrx", ofs)
375 else
376 local sh = band(rshift(op, 7), 31)
377 if sh == 0 then sh = 32 end
378 ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh)
379 end
380 if band(op, 0x00800000) == 0 then ofs = "-"..ofs end
381 end
382 if ofs == "#0" then
383 x = format("[%s]", base)
384 elseif band(op, 0x01000000) == 0 then
385 x = format("[%s], %s", base, ofs)
386 else
387 x = format("[%s, %s]", base, ofs)
388 end
389 if band(op, 0x01200000) == 0x01200000 then x = x.."!" end
390 return x
391end
392
393-- Disassemble a single instruction.
394local function disass_ins(ctx)
395 local pos = ctx.pos
396 local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
397 local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
398 local operands = {}
399 local suffix = ""
400 local last, name, pat
401 ctx.op = op
402 ctx.rel = nil
403
404 local cond = rshift(op, 28)
405 local opat
406 if cond == 15 then
407 opat = map_uncondins[band(rshift(op, 25), 7)]
408 else
409 if cond ~= 14 then suffix = map_cond[cond] end
410 opat = map_condins[band(rshift(op, 25), 7)]
411 end
412 while type(opat) ~= "string" do
413 if not opat then return unknown(ctx) end
414 opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
415 end
416 name, pat = match(opat, "^([a-z0-9]*)(.*)")
417
418 for p in gmatch(pat, ".") do
419 local x = nil
420 if p == "D" then
421 x = map_gpr[band(rshift(op, 12), 15)]
422 elseif p == "N" then
423 x = map_gpr[band(rshift(op, 16), 15)]
424 elseif p == "S" then
425 x = map_gpr[band(rshift(op, 8), 15)]
426 elseif p == "M" then
427 x = map_gpr[band(op, 15)]
428 elseif p == "P" then
429 if band(op, 0x02000000) ~= 0 then
430 x = ror(band(op, 255), 2*band(rshift(op, 8), 15))
431 else
432 x = map_gpr[band(op, 15)]
433 if band(op, 0xff0) ~= 0 then
434 operands[#operands+1] = x
435 local s = map_shift[band(rshift(op, 5), 3)]
436 local r = nil
437 if band(op, 0xf90) == 0 then
438 if s == "ror" then s = "rrx" else r = "#32" end
439 elseif band(op, 0x10) == 0 then
440 r = "#"..band(rshift(op, 7), 31)
441 else
442 r = map_gpr[band(rshift(op, 8), 15)]
443 end
444 if name == "mov" then name = s; x = r
445 elseif r then x = format("%s %s", s, r)
446 else x = s end
447 end
448 end
449 elseif p == "L" then
450 x = fmtload(ctx, op, pos, false)
451 elseif p == "B" then
452 local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6)
453 if cond == 15 then addr = addr + band(rshift(op, 23), 2) end
454 ctx.rel = addr
455 x = "0x"..tohex(addr)
456 elseif p == "R" then
457 if band(op, 0x00200000) ~= 0 and #operands == 1 then
458 operands[1] = operands[1].."!"
459 end
460 local t = {}
461 for i=0,15 do
462 if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end
463 end
464 x = "{"..concat(t, ", ").."}"
465 elseif p == "W" then
466 x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000)
467 elseif p == "T" then
468 x = "#0x"..tohex(band(op, 0x00ffffff), 6)
469 elseif p == "U" then
470 x = band(rshift(op, 7), 31)
471 if x == 0 then x = nil end
472 elseif p == "u" then
473 x = band(rshift(op, 7), 31)
474 if band(op, 0x40) == 0 then
475 if x == 0 then x = nil else x = "lsl #"..x end
476 else
477 if x == 0 then x = "asr #32" else x = "asr #"..x end
478 end
479 elseif p == "v" then
480 x = band(rshift(op, 7), 31)
481 elseif p == "w" then
482 x = band(rshift(op, 16), 31)
483 elseif p == "x" then
484 x = band(rshift(op, 16), 31) + 1
485 elseif p == "X" then
486 x = band(rshift(op, 16), 31) - last + 1
487 elseif p == "K" then
488 x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4)
489 elseif p == "s" then
490 if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end
491 else
492 assert(false)
493 end
494 if x then
495 last = x
496 if type(x) == "number" then x = "#"..x end
497 operands[#operands+1] = x
498 end
499 end
500
501 return putop(ctx, name..suffix, operands)
502end
503
504------------------------------------------------------------------------------
505
506-- Disassemble a block of code.
507local function disass_block(ctx, ofs, len)
508 if not ofs then ofs = 0 end
509 local stop = len and ofs+len or #ctx.code
510 ctx.pos = ofs
511 ctx.rel = nil
512 while ctx.pos < stop do disass_ins(ctx) end
513end
514
515-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
516local function create_(code, addr, out)
517 local ctx = {}
518 ctx.code = code
519 ctx.addr = addr or 0
520 ctx.out = out or io.write
521 ctx.symtab = {}
522 ctx.disass = disass_block
523 ctx.hexdump = 8
524 return ctx
525end
526
527-- Simple API: disassemble code (a string) at address and output via out.
528local function disass_(code, addr, out)
529 create_(code, addr, out):disass()
530end
531
532-- Return register name for RID.
533local function regname_(r)
534 return map_gpr[r]
535end
536
537-- Public module functions.
538module(...)
539
540create = create_
541disass = disass_
542regname = regname_
543
diff --git a/libraries/luajit-2.0/lib/dis_ppc.lua b/libraries/luajit-2.0/lib/dis_ppc.lua
new file mode 100644
index 0000000..79b306d
--- /dev/null
+++ b/libraries/luajit-2.0/lib/dis_ppc.lua
@@ -0,0 +1,591 @@
1----------------------------------------------------------------------------
2-- LuaJIT PPC disassembler module.
3--
4-- Copyright (C) 2005-2010 Mike Pall. All rights reserved.
5-- Released under the MIT/X license. See Copyright Notice in luajit.h
6----------------------------------------------------------------------------
7-- This is a helper module used by the LuaJIT machine code dumper module.
8--
9-- It disassembles all common, non-privileged 32/64 bit PowerPC instructions
10-- plus the e500 SPE instructions and some Cell/Xenon extensions.
11--
12-- NYI: VMX, VMX128
13------------------------------------------------------------------------------
14
15local type = type
16local sub, byte, format = string.sub, string.byte, string.format
17local match, gmatch, gsub = string.match, string.gmatch, string.gsub
18local concat = table.concat
19local bit = require("bit")
20local band, bor, tohex = bit.band, bit.bor, bit.tohex
21local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
22
23------------------------------------------------------------------------------
24-- Primary and extended opcode maps
25------------------------------------------------------------------------------
26
27local map_crops = {
28 shift = 1, mask = 1023,
29 [0] = "mcrfXX",
30 [33] = "crnor|crnotCCC=", [129] = "crandcCCC",
31 [193] = "crxor|crclrCCC%", [225] = "crnandCCC",
32 [257] = "crandCCC", [289] = "creqv|crsetCCC%",
33 [417] = "crorcCCC", [449] = "cror|crmoveCCC=",
34 [16] = "b_lrKB", [528] = "b_ctrKB",
35 [150] = "isync",
36}
37
38local map_rlwinm = setmetatable({
39 shift = 0, mask = -1,
40},
41{ __index = function(t, x)
42 local rot = band(rshift(x, 11), 31)
43 local mb = band(rshift(x, 6), 31)
44 local me = band(rshift(x, 1), 31)
45 if mb == 0 and me == 31-rot then
46 return "slwiRR~A."
47 elseif me == 31 and mb == 32-rot then
48 return "srwiRR~-A."
49 else
50 return "rlwinmRR~AAA."
51 end
52 end
53})
54
55local map_rld = {
56 shift = 2, mask = 7,
57 [0] = "rldiclRR~HM.", "rldicrRR~HM.", "rldicRR~HM.", "rldimiRR~HM.",
58 {
59 shift = 1, mask = 1,
60 [0] = "rldclRR~HM.", "rldcrRR~HM.",
61 },
62}
63
64local map_ext = setmetatable({
65 shift = 1, mask = 1023,
66
67 [0] = "cmp_YLRR", [32] = "cmpl_YLRR",
68 [4] = "twARR", [68] = "tdARR",
69
70 [8] = "subfcRRR.", [40] = "subfRRR.",
71 [104] = "negRR.", [136] = "subfeRRR.",
72 [200] = "subfzeRR.", [232] = "subfmeRR.",
73 [520] = "subfcoRRR.", [552] = "subfoRRR.",
74 [616] = "negoRR.", [648] = "subfeoRRR.",
75 [712] = "subfzeoRR.", [744] = "subfmeoRR.",
76
77 [9] = "mulhduRRR.", [73] = "mulhdRRR.", [233] = "mulldRRR.",
78 [457] = "divduRRR.", [489] = "divdRRR.",
79 [745] = "mulldoRRR.",
80 [969] = "divduoRRR.", [1001] = "divdoRRR.",
81
82 [10] = "addcRRR.", [138] = "addeRRR.",
83 [202] = "addzeRR.", [234] = "addmeRR.", [266] = "addRRR.",
84 [522] = "addcoRRR.", [650] = "addeoRRR.",
85 [714] = "addzeoRR.", [746] = "addmeoRR.", [778] = "addoRRR.",
86
87 [11] = "mulhwuRRR.", [75] = "mulhwRRR.", [235] = "mullwRRR.",
88 [459] = "divwuRRR.", [491] = "divwRRR.",
89 [747] = "mullwoRRR.",
90 [971] = "divwouRRR.", [1003] = "divwoRRR.",
91
92 [15] = "iselltRRR", [47] = "iselgtRRR", [79] = "iseleqRRR",
93
94 [144] = { shift = 20, mask = 1, [0] = "mtcrfRZ~", "mtocrfRZ~", },
95 [19] = { shift = 20, mask = 1, [0] = "mfcrR", "mfocrfRZ", },
96 [371] = { shift = 11, mask = 1023, [392] = "mftbR", [424] = "mftbuR", },
97 [339] = {
98 shift = 11, mask = 1023,
99 [32] = "mferR", [256] = "mflrR", [288] = "mfctrR", [16] = "mfspefscrR",
100 },
101 [467] = {
102 shift = 11, mask = 1023,
103 [32] = "mtxerR", [256] = "mtlrR", [288] = "mtctrR", [16] = "mtspefscrR",
104 },
105
106 [20] = "lwarxRR0R", [84] = "ldarxRR0R",
107
108 [21] = "ldxRR0R", [53] = "lduxRRR",
109 [149] = "stdxRR0R", [181] = "stduxRRR",
110 [341] = "lwaxRR0R", [373] = "lwauxRRR",
111
112 [23] = "lwzxRR0R", [55] = "lwzuxRRR",
113 [87] = "lbzxRR0R", [119] = "lbzuxRRR",
114 [151] = "stwxRR0R", [183] = "stwuxRRR",
115 [215] = "stbxRR0R", [247] = "stbuxRRR",
116 [279] = "lhzxRR0R", [311] = "lhzuxRRR",
117 [343] = "lhaxRR0R", [375] = "lhauxRRR",
118 [407] = "sthxRR0R", [439] = "sthuxRRR",
119
120 [54] = "dcbst-R0R", [86] = "dcbf-R0R",
121 [150] = "stwcxRR0R.", [214] = "stdcxRR0R.",
122 [246] = "dcbtst-R0R", [278] = "dcbt-R0R",
123 [310] = "eciwxRR0R", [438] = "ecowxRR0R",
124 [470] = "dcbi-RR",
125
126 [598] = {
127 shift = 21, mask = 3,
128 [0] = "sync", "lwsync", "ptesync",
129 },
130 [758] = "dcba-RR",
131 [854] = "eieio", [982] = "icbi-R0R", [1014] = "dcbz-R0R",
132
133 [26] = "cntlzwRR~", [58] = "cntlzdRR~",
134 [122] = "popcntbRR~",
135 [154] = "prtywRR~", [186] = "prtydRR~",
136
137 [28] = "andRR~R.", [60] = "andcRR~R.", [124] = "nor|notRR~R=.",
138 [284] = "eqvRR~R.", [316] = "xorRR~R.",
139 [412] = "orcRR~R.", [444] = "or|mrRR~R=.", [476] = "nandRR~R.",
140 [508] = "cmpbRR~R",
141
142 [512] = "mcrxrX",
143
144 [532] = "ldbrxRR0R", [660] = "stdbrxRR0R",
145
146 [533] = "lswxRR0R", [597] = "lswiRR0A",
147 [661] = "stswxRR0R", [725] = "stswiRR0A",
148
149 [534] = "lwbrxRR0R", [662] = "stwbrxRR0R",
150 [790] = "lhbrxRR0R", [918] = "sthbrxRR0R",
151
152 [535] = "lfsxFR0R", [567] = "lfsuxFRR",
153 [599] = "lfdxFR0R", [631] = "lfduxFRR",
154 [663] = "stfsxFR0R", [695] = "stfsuxFRR",
155 [727] = "stfdxFR0R", [759] = "stfduxFR0R",
156 [855] = "lfiwaxFR0R",
157 [983] = "stfiwxFR0R",
158
159 [24] = "slwRR~R.",
160
161 [27] = "sldRR~R.", [536] = "srwRR~R.",
162 [792] = "srawRR~R.", [824] = "srawiRR~A.",
163
164 [794] = "sradRR~R.", [826] = "sradiRR~H.", [827] = "sradiRR~H.",
165 [922] = "extshRR~.", [954] = "extsbRR~.", [986] = "extswRR~.",
166
167 [539] = "srdRR~R.",
168},
169{ __index = function(t, x)
170 if band(x, 31) == 15 then return "iselRRRC" end
171 end
172})
173
174local map_ld = {
175 shift = 0, mask = 3,
176 [0] = "ldRRE", "lduRRE", "lwaRRE",
177}
178
179local map_std = {
180 shift = 0, mask = 3,
181 [0] = "stdRRE", "stduRRE",
182}
183
184local map_fps = {
185 shift = 5, mask = 1,
186 {
187 shift = 1, mask = 15,
188 [0] = false, false, "fdivsFFF.", false,
189 "fsubsFFF.", "faddsFFF.", "fsqrtsF-F.", false,
190 "fresF-F.", "fmulsFF-F.", "frsqrtesF-F.", false,
191 "fmsubsFFFF~.", "fmaddsFFFF~.", "fnmsubsFFFF~.", "fnmaddsFFFF~.",
192 }
193}
194
195local map_fpd = {
196 shift = 5, mask = 1,
197 [0] = {
198 shift = 1, mask = 1023,
199 [0] = "fcmpuXFF", [32] = "fcmpoXFF", [64] = "mcrfsXX",
200 [38] = "mtfsb1A.", [70] = "mtfsb0A.", [134] = "mtfsfiA>>-A>",
201 [8] = "fcpsgnFFF.", [40] = "fnegF-F.", [72] = "fmrF-F.",
202 [136] = "fnabsF-F.", [264] = "fabsF-F.",
203 [12] = "frspF-F.",
204 [14] = "fctiwF-F.", [15] = "fctiwzF-F.",
205 [583] = "mffsF.", [711] = "mtfsfZF.",
206 [392] = "frinF-F.", [424] = "frizF-F.",
207 [456] = "fripF-F.", [488] = "frimF-F.",
208 [814] = "fctidF-F.", [815] = "fctidzF-F.", [846] = "fcfidF-F.",
209 },
210 {
211 shift = 1, mask = 15,
212 [0] = false, false, "fdivFFF.", false,
213 "fsubFFF.", "faddFFF.", "fsqrtF-F.", "fselFFFF~.",
214 "freF-F.", "fmulFF-F.", "frsqrteF-F.", false,
215 "fmsubFFFF~.", "fmaddFFFF~.", "fnmsubFFFF~.", "fnmaddFFFF~.",
216 }
217}
218
219local map_spe = {
220 shift = 0, mask = 2047,
221
222 [512] = "evaddwRRR", [514] = "evaddiwRAR~",
223 [516] = "evsubwRRR~", [518] = "evsubiwRAR~",
224 [520] = "evabsRR", [521] = "evnegRR",
225 [522] = "evextsbRR", [523] = "evextshRR", [524] = "evrndwRR",
226 [525] = "evcntlzwRR", [526] = "evcntlswRR",
227
228 [527] = "brincRRR",
229
230 [529] = "evandRRR", [530] = "evandcRRR", [534] = "evxorRRR",
231 [535] = "evor|evmrRRR=", [536] = "evnor|evnotRRR=",
232 [537] = "eveqvRRR", [539] = "evorcRRR", [542] = "evnandRRR",
233
234 [544] = "evsrwuRRR", [545] = "evsrwsRRR",
235 [546] = "evsrwiuRRA", [547] = "evsrwisRRA",
236 [548] = "evslwRRR", [550] = "evslwiRRA",
237 [552] = "evrlwRRR", [553] = "evsplatiRS",
238 [554] = "evrlwiRRA", [555] = "evsplatfiRS",
239 [556] = "evmergehiRRR", [557] = "evmergeloRRR",
240 [558] = "evmergehiloRRR", [559] = "evmergelohiRRR",
241
242 [560] = "evcmpgtuYRR", [561] = "evcmpgtsYRR",
243 [562] = "evcmpltuYRR", [563] = "evcmpltsYRR",
244 [564] = "evcmpeqYRR",
245
246 [632] = "evselRRR", [633] = "evselRRRW",
247 [634] = "evselRRRW", [635] = "evselRRRW",
248 [636] = "evselRRRW", [637] = "evselRRRW",
249 [638] = "evselRRRW", [639] = "evselRRRW",
250
251 [640] = "evfsaddRRR", [641] = "evfssubRRR",
252 [644] = "evfsabsRR", [645] = "evfsnabsRR", [646] = "evfsnegRR",
253 [648] = "evfsmulRRR", [649] = "evfsdivRRR",
254 [652] = "evfscmpgtYRR", [653] = "evfscmpltYRR", [654] = "evfscmpeqYRR",
255 [656] = "evfscfuiR-R", [657] = "evfscfsiR-R",
256 [658] = "evfscfufR-R", [659] = "evfscfsfR-R",
257 [660] = "evfsctuiR-R", [661] = "evfsctsiR-R",
258 [662] = "evfsctufR-R", [663] = "evfsctsfR-R",
259 [664] = "evfsctuizR-R", [666] = "evfsctsizR-R",
260 [668] = "evfststgtYRR", [669] = "evfststltYRR", [670] = "evfststeqYRR",
261
262 [704] = "efsaddRRR", [705] = "efssubRRR",
263 [708] = "efsabsRR", [709] = "efsnabsRR", [710] = "efsnegRR",
264 [712] = "efsmulRRR", [713] = "efsdivRRR",
265 [716] = "efscmpgtYRR", [717] = "efscmpltYRR", [718] = "efscmpeqYRR",
266 [719] = "efscfdR-R",
267 [720] = "efscfuiR-R", [721] = "efscfsiR-R",
268 [722] = "efscfufR-R", [723] = "efscfsfR-R",
269 [724] = "efsctuiR-R", [725] = "efsctsiR-R",
270 [726] = "efsctufR-R", [727] = "efsctsfR-R",
271 [728] = "efsctuizR-R", [730] = "efsctsizR-R",
272 [732] = "efststgtYRR", [733] = "efststltYRR", [734] = "efststeqYRR",
273
274 [736] = "efdaddRRR", [737] = "efdsubRRR",
275 [738] = "efdcfuidR-R", [739] = "efdcfsidR-R",
276 [740] = "efdabsRR", [741] = "efdnabsRR", [742] = "efdnegRR",
277 [744] = "efdmulRRR", [745] = "efddivRRR",
278 [746] = "efdctuidzR-R", [747] = "efdctsidzR-R",
279 [748] = "efdcmpgtYRR", [749] = "efdcmpltYRR", [750] = "efdcmpeqYRR",
280 [751] = "efdcfsR-R",
281 [752] = "efdcfuiR-R", [753] = "efdcfsiR-R",
282 [754] = "efdcfufR-R", [755] = "efdcfsfR-R",
283 [756] = "efdctuiR-R", [757] = "efdctsiR-R",
284 [758] = "efdctufR-R", [759] = "efdctsfR-R",
285 [760] = "efdctuizR-R", [762] = "efdctsizR-R",
286 [764] = "efdtstgtYRR", [765] = "efdtstltYRR", [766] = "efdtsteqYRR",
287
288 [768] = "evlddxRR0R", [769] = "evlddRR8",
289 [770] = "evldwxRR0R", [771] = "evldwRR8",
290 [772] = "evldhxRR0R", [773] = "evldhRR8",
291 [776] = "evlhhesplatxRR0R", [777] = "evlhhesplatRR2",
292 [780] = "evlhhousplatxRR0R", [781] = "evlhhousplatRR2",
293 [782] = "evlhhossplatxRR0R", [783] = "evlhhossplatRR2",
294 [784] = "evlwhexRR0R", [785] = "evlwheRR4",
295 [788] = "evlwhouxRR0R", [789] = "evlwhouRR4",
296 [790] = "evlwhosxRR0R", [791] = "evlwhosRR4",
297 [792] = "evlwwsplatxRR0R", [793] = "evlwwsplatRR4",
298 [796] = "evlwhsplatxRR0R", [797] = "evlwhsplatRR4",
299
300 [800] = "evstddxRR0R", [801] = "evstddRR8",
301 [802] = "evstdwxRR0R", [803] = "evstdwRR8",
302 [804] = "evstdhxRR0R", [805] = "evstdhRR8",
303 [816] = "evstwhexRR0R", [817] = "evstwheRR4",
304 [820] = "evstwhoxRR0R", [821] = "evstwhoRR4",
305 [824] = "evstwwexRR0R", [825] = "evstwweRR4",
306 [828] = "evstwwoxRR0R", [829] = "evstwwoRR4",
307
308 [1027] = "evmhessfRRR", [1031] = "evmhossfRRR", [1032] = "evmheumiRRR",
309 [1033] = "evmhesmiRRR", [1035] = "evmhesmfRRR", [1036] = "evmhoumiRRR",
310 [1037] = "evmhosmiRRR", [1039] = "evmhosmfRRR", [1059] = "evmhessfaRRR",
311 [1063] = "evmhossfaRRR", [1064] = "evmheumiaRRR", [1065] = "evmhesmiaRRR",
312 [1067] = "evmhesmfaRRR", [1068] = "evmhoumiaRRR", [1069] = "evmhosmiaRRR",
313 [1071] = "evmhosmfaRRR", [1095] = "evmwhssfRRR", [1096] = "evmwlumiRRR",
314 [1100] = "evmwhumiRRR", [1101] = "evmwhsmiRRR", [1103] = "evmwhsmfRRR",
315 [1107] = "evmwssfRRR", [1112] = "evmwumiRRR", [1113] = "evmwsmiRRR",
316 [1115] = "evmwsmfRRR", [1127] = "evmwhssfaRRR", [1128] = "evmwlumiaRRR",
317 [1132] = "evmwhumiaRRR", [1133] = "evmwhsmiaRRR", [1135] = "evmwhsmfaRRR",
318 [1139] = "evmwssfaRRR", [1144] = "evmwumiaRRR", [1145] = "evmwsmiaRRR",
319 [1147] = "evmwsmfaRRR",
320
321 [1216] = "evaddusiaawRR", [1217] = "evaddssiaawRR",
322 [1218] = "evsubfusiaawRR", [1219] = "evsubfssiaawRR",
323 [1220] = "evmraRR",
324 [1222] = "evdivwsRRR", [1223] = "evdivwuRRR",
325 [1224] = "evaddumiaawRR", [1225] = "evaddsmiaawRR",
326 [1226] = "evsubfumiaawRR", [1227] = "evsubfsmiaawRR",
327
328 [1280] = "evmheusiaawRRR", [1281] = "evmhessiaawRRR",
329 [1283] = "evmhessfaawRRR", [1284] = "evmhousiaawRRR",
330 [1285] = "evmhossiaawRRR", [1287] = "evmhossfaawRRR",
331 [1288] = "evmheumiaawRRR", [1289] = "evmhesmiaawRRR",
332 [1291] = "evmhesmfaawRRR", [1292] = "evmhoumiaawRRR",
333 [1293] = "evmhosmiaawRRR", [1295] = "evmhosmfaawRRR",
334 [1320] = "evmhegumiaaRRR", [1321] = "evmhegsmiaaRRR",
335 [1323] = "evmhegsmfaaRRR", [1324] = "evmhogumiaaRRR",
336 [1325] = "evmhogsmiaaRRR", [1327] = "evmhogsmfaaRRR",
337 [1344] = "evmwlusiaawRRR", [1345] = "evmwlssiaawRRR",
338 [1352] = "evmwlumiaawRRR", [1353] = "evmwlsmiaawRRR",
339 [1363] = "evmwssfaaRRR", [1368] = "evmwumiaaRRR",
340 [1369] = "evmwsmiaaRRR", [1371] = "evmwsmfaaRRR",
341 [1408] = "evmheusianwRRR", [1409] = "evmhessianwRRR",
342 [1411] = "evmhessfanwRRR", [1412] = "evmhousianwRRR",
343 [1413] = "evmhossianwRRR", [1415] = "evmhossfanwRRR",
344 [1416] = "evmheumianwRRR", [1417] = "evmhesmianwRRR",
345 [1419] = "evmhesmfanwRRR", [1420] = "evmhoumianwRRR",
346 [1421] = "evmhosmianwRRR", [1423] = "evmhosmfanwRRR",
347 [1448] = "evmhegumianRRR", [1449] = "evmhegsmianRRR",
348 [1451] = "evmhegsmfanRRR", [1452] = "evmhogumianRRR",
349 [1453] = "evmhogsmianRRR", [1455] = "evmhogsmfanRRR",
350 [1472] = "evmwlusianwRRR", [1473] = "evmwlssianwRRR",
351 [1480] = "evmwlumianwRRR", [1481] = "evmwlsmianwRRR",
352 [1491] = "evmwssfanRRR", [1496] = "evmwumianRRR",
353 [1497] = "evmwsmianRRR", [1499] = "evmwsmfanRRR",
354}
355
356local map_pri = {
357 [0] = false, false, "tdiARI", "twiARI",
358 map_spe, false, false, "mulliRRI",
359 "subficRRI", false, "cmpl_iYLRU", "cmp_iYLRI",
360 "addicRRI", "addic.RRI", "addi|liRR0I", "addis|lisRR0I",
361 "b_KBJ", "sc", "bKJ", map_crops,
362 "rlwimiRR~AAA.", map_rlwinm, false, "rlwnmRR~RAA.",
363 "oriNRR~U", "orisRR~U", "xoriRR~U", "xorisRR~U",
364 "andi.RR~U", "andis.RR~U", map_rld, map_ext,
365 "lwzRRD", "lwzuRRD", "lbzRRD", "lbzuRRD",
366 "stwRRD", "stwuRRD", "stbRRD", "stbuRRD",
367 "lhzRRD", "lhzuRRD", "lhaRRD", "lhauRRD",
368 "sthRRD", "sthuRRD", "lmwRRD", "stmwRRD",
369 "lfsFRD", "lfsuFRD", "lfdFRD", "lfduFRD",
370 "stfsFRD", "stfsuFRD", "stfdFRD", "stfduFRD",
371 false, false, map_ld, map_fps,
372 false, false, map_std, map_fpd,
373}
374
375------------------------------------------------------------------------------
376
377local map_gpr = {
378 [0] = "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7",
379 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
380 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
381 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
382}
383
384local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", }
385
386-- Format a condition bit.
387local function condfmt(cond)
388 if cond <= 3 then
389 return map_cond[band(cond, 3)]
390 else
391 return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)])
392 end
393end
394
395------------------------------------------------------------------------------
396
397-- Output a nicely formatted line with an opcode and operands.
398local function putop(ctx, text, operands)
399 local pos = ctx.pos
400 local extra = ""
401 if ctx.rel then
402 local sym = ctx.symtab[ctx.rel]
403 if sym then extra = "\t->"..sym end
404 end
405 if ctx.hexdump > 0 then
406 ctx.out(format("%08x %s %-7s %s%s\n",
407 ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
408 else
409 ctx.out(format("%08x %-7s %s%s\n",
410 ctx.addr+pos, text, concat(operands, ", "), extra))
411 end
412 ctx.pos = pos + 4
413end
414
415-- Fallback for unknown opcodes.
416local function unknown(ctx)
417 return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
418end
419
420-- Disassemble a single instruction.
421local function disass_ins(ctx)
422 local pos = ctx.pos
423 local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
424 local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3)
425 local operands = {}
426 local last = nil
427 local rs = 21
428 ctx.op = op
429 ctx.rel = nil
430
431 local opat = map_pri[rshift(b0, 2)]
432 while type(opat) ~= "string" do
433 if not opat then return unknown(ctx) end
434 opat = opat[band(rshift(op, opat.shift), opat.mask)]
435 end
436 local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
437 local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)")
438 if altname then pat = pat2 end
439
440 for p in gmatch(pat, ".") do
441 local x = nil
442 if p == "R" then
443 x = map_gpr[band(rshift(op, rs), 31)]
444 rs = rs - 5
445 elseif p == "F" then
446 x = "f"..band(rshift(op, rs), 31)
447 rs = rs - 5
448 elseif p == "A" then
449 x = band(rshift(op, rs), 31)
450 rs = rs - 5
451 elseif p == "S" then
452 x = arshift(lshift(op, 27-rs), 27)
453 rs = rs - 5
454 elseif p == "I" then
455 x = arshift(lshift(op, 16), 16)
456 elseif p == "U" then
457 x = band(op, 0xffff)
458 elseif p == "D" or p == "E" then
459 local disp = arshift(lshift(op, 16), 16)
460 if p == "E" then disp = band(disp, -4) end
461 if last == "r0" then last = "0" end
462 operands[#operands] = format("%d(%s)", disp, last)
463 elseif p >= "2" and p <= "8" then
464 local disp = band(rshift(op, rs), 31) * p
465 if last == "r0" then last = "0" end
466 operands[#operands] = format("%d(%s)", disp, last)
467 elseif p == "H" then
468 x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4)
469 rs = rs - 5
470 elseif p == "M" then
471 x = band(rshift(op, rs), 31) + band(op, 0x20)
472 elseif p == "C" then
473 x = condfmt(band(rshift(op, rs), 31))
474 rs = rs - 5
475 elseif p == "B" then
476 local bo = rshift(op, 21)
477 local cond = band(rshift(op, 16), 31)
478 local cn = ""
479 rs = rs - 10
480 if band(bo, 4) == 0 then
481 cn = band(bo, 2) == 0 and "dnz" or "dz"
482 if band(bo, 0x10) == 0 then
483 cn = cn..(band(bo, 8) == 0 and "f" or "t")
484 end
485 if band(bo, 0x10) == 0 then x = condfmt(cond) end
486 name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
487 elseif band(bo, 0x10) == 0 then
488 cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)]
489 if cond > 3 then x = "cr"..rshift(cond, 2) end
490 name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
491 end
492 name = gsub(name, "_", cn)
493 elseif p == "J" then
494 x = arshift(lshift(op, 27-rs), 29-rs)*4
495 if band(op, 2) == 0 then x = ctx.addr + pos + x end
496 ctx.rel = x
497 x = "0x"..tohex(x)
498 elseif p == "K" then
499 if band(op, 1) ~= 0 then name = name.."l" end
500 if band(op, 2) ~= 0 then name = name.."a" end
501 elseif p == "X" or p == "Y" then
502 x = band(rshift(op, rs+2), 7)
503 if x == 0 and p == "Y" then x = nil else x = "cr"..x end
504 rs = rs - 5
505 elseif p == "W" then
506 x = "cr"..band(op, 7)
507 elseif p == "Z" then
508 x = band(rshift(op, rs-4), 255)
509 rs = rs - 10
510 elseif p == ">" then
511 operands[#operands] = rshift(operands[#operands], 1)
512 elseif p == "0" then
513 if last == "r0" then
514 operands[#operands] = nil
515 if altname then name = altname end
516 end
517 elseif p == "L" then
518 name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w")
519 elseif p == "." then
520 if band(op, 1) == 1 then name = name.."." end
521 elseif p == "N" then
522 if op == 0x60000000 then name = "nop"; break end
523 elseif p == "~" then
524 local n = #operands
525 operands[n-1], operands[n] = operands[n], operands[n-1]
526 elseif p == "=" then
527 local n = #operands
528 if last == operands[n-1] then
529 operands[n] = nil
530 name = altname
531 end
532 elseif p == "%" then
533 local n = #operands
534 if last == operands[n-1] and last == operands[n-2] then
535 operands[n] = nil
536 operands[n-1] = nil
537 name = altname
538 end
539 elseif p == "-" then
540 rs = rs - 5
541 else
542 assert(false)
543 end
544 if x then operands[#operands+1] = x; last = x end
545 end
546
547 return putop(ctx, name, operands)
548end
549
550------------------------------------------------------------------------------
551
552-- Disassemble a block of code.
553local function disass_block(ctx, ofs, len)
554 if not ofs then ofs = 0 end
555 local stop = len and ofs+len or #ctx.code
556 stop = stop - stop % 4
557 ctx.pos = ofs - ofs % 4
558 ctx.rel = nil
559 while ctx.pos < stop do disass_ins(ctx) end
560end
561
562-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
563local function create_(code, addr, out)
564 local ctx = {}
565 ctx.code = code
566 ctx.addr = addr or 0
567 ctx.out = out or io.write
568 ctx.symtab = {}
569 ctx.disass = disass_block
570 ctx.hexdump = 8
571 return ctx
572end
573
574-- Simple API: disassemble code (a string) at address and output via out.
575local function disass_(code, addr, out)
576 create_(code, addr, out):disass()
577end
578
579-- Return register name for RID.
580local function regname_(r)
581 if r < 32 then return map_gpr[r] end
582 return "f"..(r-32)
583end
584
585-- Public module functions.
586module(...)
587
588create = create_
589disass = disass_
590regname = regname_
591
diff --git a/libraries/luajit-2.0/lib/dis_x64.lua b/libraries/luajit-2.0/lib/dis_x64.lua
new file mode 100644
index 0000000..8c9cb4f
--- /dev/null
+++ b/libraries/luajit-2.0/lib/dis_x64.lua
@@ -0,0 +1,20 @@
1----------------------------------------------------------------------------
2-- LuaJIT x64 disassembler wrapper module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT license. See Copyright Notice in luajit.h
6----------------------------------------------------------------------------
7-- This module just exports the 64 bit functions from the combined
8-- x86/x64 disassembler module. All the interesting stuff is there.
9------------------------------------------------------------------------------
10
11local require = require
12
13module(...)
14
15local dis_x86 = require(_PACKAGE.."dis_x86")
16
17create = dis_x86.create64
18disass = dis_x86.disass64
19regname = dis_x86.regname64
20
diff --git a/libraries/luajit-2.0/lib/dis_x86.lua b/libraries/luajit-2.0/lib/dis_x86.lua
new file mode 100644
index 0000000..d9a1f32
--- /dev/null
+++ b/libraries/luajit-2.0/lib/dis_x86.lua
@@ -0,0 +1,836 @@
1----------------------------------------------------------------------------
2-- LuaJIT x86/x64 disassembler module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT license. See Copyright Notice in luajit.h
6----------------------------------------------------------------------------
7-- This is a helper module used by the LuaJIT machine code dumper module.
8--
9-- Sending small code snippets to an external disassembler and mixing the
10-- output with our own stuff was too fragile. So I had to bite the bullet
11-- and write yet another x86 disassembler. Oh well ...
12--
13-- The output format is very similar to what ndisasm generates. But it has
14-- been developed independently by looking at the opcode tables from the
15-- Intel and AMD manuals. The supported instruction set is quite extensive
16-- and reflects what a current generation Intel or AMD CPU implements in
17-- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3,
18-- SSE4.1, SSE4.2, SSE4a and even privileged and hypervisor (VMX/SVM)
19-- instructions.
20--
21-- Notes:
22-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
23-- * No attempt at optimization has been made -- it's fast enough for my needs.
24-- * The public API may change when more architectures are added.
25------------------------------------------------------------------------------
26
27local type = type
28local sub, byte, format = string.sub, string.byte, string.format
29local match, gmatch, gsub = string.match, string.gmatch, string.gsub
30local lower, rep = string.lower, string.rep
31
32-- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on.
33local map_opc1_32 = {
34--0x
35[0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es",
36"orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*",
37--1x
38"adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss",
39"sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds",
40--2x
41"andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa",
42"subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das",
43--3x
44"xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa",
45"cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas",
46--4x
47"incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR",
48"decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR",
49--5x
50"pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR",
51"popUR","popUR","popUR","popUR","popUR","popUR","popUR","popUR",
52--6x
53"sz*pushaw,pusha","sz*popaw,popa","boundVrm","arplWmr",
54"fs:seg","gs:seg","o16:","a16",
55"pushUi","imulVrmi","pushBs","imulVrms",
56"insb","insVS","outsb","outsVS",
57--7x
58"joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj",
59"jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj",
60--8x
61"arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms",
62"testBmr","testVmr","xchgBrm","xchgVrm",
63"movBmr","movVmr","movBrm","movVrm",
64"movVmg","leaVrm","movWgm","popUm",
65--9x
66"nop*xchgVaR|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR",
67"xchgVaR","xchgVaR","xchgVaR","xchgVaR",
68"sz*cbw,cwde,cdqe","sz*cwd,cdq,cqo","call farViw","wait",
69"sz*pushfw,pushf","sz*popfw,popf","sahf","lahf",
70--Ax
71"movBao","movVao","movBoa","movVoa",
72"movsb","movsVS","cmpsb","cmpsVS",
73"testBai","testVai","stosb","stosVS",
74"lodsb","lodsVS","scasb","scasVS",
75--Bx
76"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
77"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI",
78--Cx
79"shift!Bmu","shift!Vmu","retBw","ret","$lesVrm","$ldsVrm","movBmi","movVmi",
80"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS",
81--Dx
82"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
83"fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7",
84--Ex
85"loopneBj","loopeBj","loopBj","sz*jcxzBj,jecxzBj,jrcxzBj",
86"inBau","inVau","outBua","outVua",
87"callVj","jmpVj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda",
88--Fx
89"lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm",
90"clc","stc","cli","sti","cld","std","incb!Bm","incd!Vm",
91}
92assert(#map_opc1_32 == 255)
93
94-- Map for 1st opcode byte in 64 bit mode (overrides only).
95local map_opc1_64 = setmetatable({
96 [0x06]=false, [0x07]=false, [0x0e]=false,
97 [0x16]=false, [0x17]=false, [0x1e]=false, [0x1f]=false,
98 [0x27]=false, [0x2f]=false, [0x37]=false, [0x3f]=false,
99 [0x60]=false, [0x61]=false, [0x62]=false, [0x63]="movsxdVrDmt", [0x67]="a32:",
100 [0x40]="rex*", [0x41]="rex*b", [0x42]="rex*x", [0x43]="rex*xb",
101 [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb",
102 [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
103 [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb",
104 [0x82]=false, [0x9a]=false, [0xc4]=false, [0xc5]=false, [0xce]=false,
105 [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false,
106}, { __index = map_opc1_32 })
107
108-- Map for 2nd opcode byte (0F xx). True CISC hell. Hey, I told you.
109-- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne, -|F3|66|F2
110local map_opc2 = {
111--0x
112[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
113"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
114--1x
115"movupsXrm|movssXrm|movupdXrm|movsdXrm",
116"movupsXmr|movssXmr|movupdXmr|movsdXmr",
117"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
118"movlpsXmr||movlpdXmr",
119"unpcklpsXrm||unpcklpdXrm",
120"unpckhpsXrm||unpckhpdXrm",
121"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
122"movhpsXmr||movhpdXmr",
123"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
124"hintnopVm","hintnopVm","hintnopVm","hintnopVm",
125--2x
126"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
127"movapsXrm||movapdXrm",
128"movapsXmr||movapdXmr",
129"cvtpi2psXrMm|cvtsi2ssXrVmt|cvtpi2pdXrMm|cvtsi2sdXrVmt",
130"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
131"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
132"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
133"ucomissXrm||ucomisdXrm",
134"comissXrm||comisdXrm",
135--3x
136"wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,"getsec",
137"opc3*38",nil,"opc3*3a",nil,nil,nil,nil,nil,
138--4x
139"cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm",
140"cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm",
141"cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm",
142"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
143--5x
144"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
145"rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm",
146"andpsXrm||andpdXrm","andnpsXrm||andnpdXrm",
147"orpsXrm||orpdXrm","xorpsXrm||xorpdXrm",
148"addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm",
149"cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm",
150"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
151"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm",
152"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm",
153--6x
154"punpcklbwPrm","punpcklwdPrm","punpckldqPrm","packsswbPrm",
155"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm",
156"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm",
157"||punpcklqdqXrm","||punpckhqdqXrm",
158"movPrVSm","movqMrm|movdquXrm|movdqaXrm",
159--7x
160"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pmu",
161"pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
162"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|",
163"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
164nil,nil,
165"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm",
166"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
167--8x
168"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
169"jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj",
170--9x
171"setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm",
172"setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm",
173--Ax
174"push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil,
175"push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm",
176--Bx
177"cmpxchgBmr","cmpxchgVmr","$lssVrm","btrVmr",
178"$lfsVrm","$lgsVrm","movzxVrBmt","movzxVrWmt",
179"|popcntVrm","ud2Dp","bt!Vmu","btcVmr",
180"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
181--Cx
182"xaddBmr","xaddVmr",
183"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","$movntiVmr|",
184"pinsrwPrWmu","pextrwDrPmu",
185"shufpsXrmu||shufpdXrmu","$cmpxchg!Qmp",
186"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
187--Dx
188"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm",
189"paddqPrm","pmullwPrm",
190"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
191"psubusbPrm","psubuswPrm","pminubPrm","pandPrm",
192"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm",
193--Ex
194"pavgbPrm","psrawPrm","psradPrm","pavgwPrm",
195"pmulhuwPrm","pmulhwPrm",
196"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
197"psubsbPrm","psubswPrm","pminswPrm","porPrm",
198"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm",
199--Fx
200"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm",
201"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm$",
202"psubbPrm","psubwPrm","psubdPrm","psubqPrm",
203"paddbPrm","paddwPrm","padddPrm","ud",
204}
205assert(map_opc2[255] == "ud")
206
207-- Map for three-byte opcodes. Can't wait for their next invention.
208local map_opc3 = {
209["38"] = { -- [66] 0f 38 xx
210--0x
211[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm",
212"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm",
213"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm",
214nil,nil,nil,nil,
215--1x
216"||pblendvbXrma",nil,nil,nil,
217"||blendvpsXrma","||blendvpdXrma",nil,"||ptestXrm",
218nil,nil,nil,nil,
219"pabsbPrm","pabswPrm","pabsdPrm",nil,
220--2x
221"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
222"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
223"||pmuldqXrm","||pcmpeqqXrm","||$movntdqaXrm","||packusdwXrm",
224nil,nil,nil,nil,
225--3x
226"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
227"||pmovzxwqXrm","||pmovzxdqXrm",nil,"||pcmpgtqXrm",
228"||pminsbXrm","||pminsdXrm","||pminuwXrm","||pminudXrm",
229"||pmaxsbXrm","||pmaxsdXrm","||pmaxuwXrm","||pmaxudXrm",
230--4x
231"||pmulddXrm","||phminposuwXrm",
232--Fx
233[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
234},
235
236["3a"] = { -- [66] 0f 3a xx
237--0x
238[0x00]=nil,nil,nil,nil,nil,nil,nil,nil,
239"||roundpsXrmu","||roundpdXrmu","||roundssXrmu","||roundsdXrmu",
240"||blendpsXrmu","||blendpdXrmu","||pblendwXrmu","palignrPrmu",
241--1x
242nil,nil,nil,nil,
243"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
244nil,nil,nil,nil,nil,nil,nil,nil,
245--2x
246"||pinsrbXrVmu","||insertpsXrmu","||pinsrXrVmuS",nil,
247--4x
248[0x40] = "||dppsXrmu",
249[0x41] = "||dppdXrmu",
250[0x42] = "||mpsadbwXrmu",
251--6x
252[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
253[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
254},
255}
256
257-- Map for VMX/SVM opcodes 0F 01 C0-FF (sgdt group with register operands).
258local map_opcvm = {
259[0xc1]="vmcall",[0xc2]="vmlaunch",[0xc3]="vmresume",[0xc4]="vmxoff",
260[0xc8]="monitor",[0xc9]="mwait",
261[0xd8]="vmrun",[0xd9]="vmmcall",[0xda]="vmload",[0xdb]="vmsave",
262[0xdc]="stgi",[0xdd]="clgi",[0xde]="skinit",[0xdf]="invlpga",
263[0xf8]="swapgs",[0xf9]="rdtscp",
264}
265
266-- Map for FP opcodes. And you thought stack machines are simple?
267local map_opcfp = {
268-- D8-DF 00-BF: opcodes with a memory operand.
269-- D8
270[0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm",
271"fldFm",nil,"fstFm","fstpFm","fldenvVm","fldcwWm","fnstenvVm","fnstcwWm",
272-- DA
273"fiaddDm","fimulDm","ficomDm","ficompDm",
274"fisubDm","fisubrDm","fidivDm","fidivrDm",
275-- DB
276"fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp",
277-- DC
278"faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm",
279-- DD
280"fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm",
281-- DE
282"fiaddWm","fimulWm","ficomWm","ficompWm",
283"fisubWm","fisubrWm","fidivWm","fidivrWm",
284-- DF
285"fildWm","fisttpWm","fistWm","fistpWm",
286"fbld twordFmp","fildQm","fbstp twordFmp","fistpQm",
287-- xx C0-FF: opcodes with a pseudo-register operand.
288-- D8
289"faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf",
290-- D9
291"fldFf","fxchFf",{"fnop"},nil,
292{"fchs","fabs",nil,nil,"ftst","fxam"},
293{"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"},
294{"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"},
295{"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"},
296-- DA
297"fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil,
298-- DB
299"fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf",
300{nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil,
301-- DC
302"fadd toFf","fmul toFf",nil,nil,
303"fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf",
304-- DD
305"ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil,
306-- DE
307"faddpFf","fmulpFf",nil,{nil,"fcompp"},
308"fsubrpFf","fsubpFf","fdivrpFf","fdivpFf",
309-- DF
310nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil,
311}
312assert(map_opcfp[126] == "fcomipFf")
313
314-- Map for opcode groups. The subkey is sp from the ModRM byte.
315local map_opcgroup = {
316 arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" },
317 shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" },
318 testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" },
319 testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" },
320 incb = { "inc", "dec" },
321 incd = { "inc", "dec", "callUmp", "$call farDmp",
322 "jmpUmp", "$jmp farDmp", "pushUm" },
323 sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" },
324 sgdt = { "vm*$sgdt", "vm*$sidt", "$lgdt", "vm*$lidt",
325 "smsw", nil, "lmsw", "vm*$invlpg" },
326 bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" },
327 cmpxchg = { nil, "sz*,cmpxchg8bQmp,cmpxchg16bXmp", nil, nil,
328 nil, nil, "vmptrld|vmxon|vmclear", "vmptrst" },
329 pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" },
330 pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" },
331 pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" },
332 pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" },
333 fxsave = { "$fxsave", "$fxrstor", "$ldmxcsr", "$stmxcsr",
334 nil, "lfenceDp$", "mfenceDp$", "sfenceDp$clflush" },
335 prefetch = { "prefetch", "prefetchw" },
336 prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" },
337}
338
339------------------------------------------------------------------------------
340
341-- Maps for register names.
342local map_regs = {
343 B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
344 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
345 B64 = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
346 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
347 W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
348 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" },
349 D = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
350 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" },
351 Q = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
352 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" },
353 M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
354 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
355 X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
356 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" },
357}
358local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
359
360-- Maps for size names.
361local map_sz2n = {
362 B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16,
363}
364local map_sz2prefix = {
365 B = "byte", W = "word", D = "dword",
366 Q = "qword",
367 M = "qword", X = "xword",
368 F = "dword", G = "qword", -- No need for sizes/register names for these two.
369}
370
371------------------------------------------------------------------------------
372
373-- Output a nicely formatted line with an opcode and operands.
374local function putop(ctx, text, operands)
375 local code, pos, hex = ctx.code, ctx.pos, ""
376 local hmax = ctx.hexdump
377 if hmax > 0 then
378 for i=ctx.start,pos-1 do
379 hex = hex..format("%02X", byte(code, i, i))
380 end
381 if #hex > hmax then hex = sub(hex, 1, hmax)..". "
382 else hex = hex..rep(" ", hmax-#hex+2) end
383 end
384 if operands then text = text.." "..operands end
385 if ctx.o16 then text = "o16 "..text; ctx.o16 = false end
386 if ctx.a32 then text = "a32 "..text; ctx.a32 = false end
387 if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
388 if ctx.rex then
389 local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
390 (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")
391 if t ~= "" then text = "rex."..t.." "..text end
392 ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
393 ctx.rex = false
394 end
395 if ctx.seg then
396 local text2, n = gsub(text, "%[", "["..ctx.seg..":")
397 if n == 0 then text = ctx.seg.." "..text else text = text2 end
398 ctx.seg = false
399 end
400 if ctx.lock then text = "lock "..text; ctx.lock = false end
401 local imm = ctx.imm
402 if imm then
403 local sym = ctx.symtab[imm]
404 if sym then text = text.."\t->"..sym end
405 end
406 ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
407 ctx.mrm = false
408 ctx.start = pos
409 ctx.imm = nil
410end
411
412-- Clear all prefix flags.
413local function clearprefixes(ctx)
414 ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
415 ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
416 ctx.rex = false; ctx.a32 = false
417end
418
419-- Fallback for incomplete opcodes at the end.
420local function incomplete(ctx)
421 ctx.pos = ctx.stop+1
422 clearprefixes(ctx)
423 return putop(ctx, "(incomplete)")
424end
425
426-- Fallback for unknown opcodes.
427local function unknown(ctx)
428 clearprefixes(ctx)
429 return putop(ctx, "(unknown)")
430end
431
432-- Return an immediate of the specified size.
433local function getimm(ctx, pos, n)
434 if pos+n-1 > ctx.stop then return incomplete(ctx) end
435 local code = ctx.code
436 if n == 1 then
437 local b1 = byte(code, pos, pos)
438 return b1
439 elseif n == 2 then
440 local b1, b2 = byte(code, pos, pos+1)
441 return b1+b2*256
442 else
443 local b1, b2, b3, b4 = byte(code, pos, pos+3)
444 local imm = b1+b2*256+b3*65536+b4*16777216
445 ctx.imm = imm
446 return imm
447 end
448end
449
450-- Process pattern string and generate the operands.
451local function putpat(ctx, name, pat)
452 local operands, regs, sz, mode, sp, rm, sc, rx, sdisp
453 local code, pos, stop = ctx.code, ctx.pos, ctx.stop
454
455 -- Chars used: 1DFGIMPQRSTUVWXacdfgijmoprstuwxyz
456 for p in gmatch(pat, ".") do
457 local x = nil
458 if p == "V" or p == "U" then
459 if ctx.rexw then sz = "Q"; ctx.rexw = false
460 elseif ctx.o16 then sz = "W"; ctx.o16 = false
461 elseif p == "U" and ctx.x64 then sz = "Q"
462 else sz = "D" end
463 regs = map_regs[sz]
464 elseif p == "T" then
465 if ctx.rexw then sz = "Q"; ctx.rexw = false else sz = "D" end
466 regs = map_regs[sz]
467 elseif p == "B" then
468 sz = "B"
469 regs = ctx.rex and map_regs.B64 or map_regs.B
470 elseif match(p, "[WDQMXFG]") then
471 sz = p
472 regs = map_regs[sz]
473 elseif p == "P" then
474 sz = ctx.o16 and "X" or "M"; ctx.o16 = false
475 regs = map_regs[sz]
476 elseif p == "S" then
477 name = name..lower(sz)
478 elseif p == "s" then
479 local imm = getimm(ctx, pos, 1); if not imm then return end
480 x = imm <= 127 and format("+0x%02x", imm)
481 or format("-0x%02x", 256-imm)
482 pos = pos+1
483 elseif p == "u" then
484 local imm = getimm(ctx, pos, 1); if not imm then return end
485 x = format("0x%02x", imm)
486 pos = pos+1
487 elseif p == "w" then
488 local imm = getimm(ctx, pos, 2); if not imm then return end
489 x = format("0x%x", imm)
490 pos = pos+2
491 elseif p == "o" then -- [offset]
492 if ctx.x64 then
493 local imm1 = getimm(ctx, pos, 4); if not imm1 then return end
494 local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end
495 x = format("[0x%08x%08x]", imm2, imm1)
496 pos = pos+8
497 else
498 local imm = getimm(ctx, pos, 4); if not imm then return end
499 x = format("[0x%08x]", imm)
500 pos = pos+4
501 end
502 elseif p == "i" or p == "I" then
503 local n = map_sz2n[sz]
504 if n == 8 and ctx.x64 and p == "I" then
505 local imm1 = getimm(ctx, pos, 4); if not imm1 then return end
506 local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end
507 x = format("0x%08x%08x", imm2, imm1)
508 else
509 if n == 8 then n = 4 end
510 local imm = getimm(ctx, pos, n); if not imm then return end
511 if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then
512 imm = (0xffffffff+1)-imm
513 x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm)
514 else
515 x = format(imm > 65535 and "0x%08x" or "0x%x", imm)
516 end
517 end
518 pos = pos+n
519 elseif p == "j" then
520 local n = map_sz2n[sz]
521 if n == 8 then n = 4 end
522 local imm = getimm(ctx, pos, n); if not imm then return end
523 if sz == "B" and imm > 127 then imm = imm-256
524 elseif imm > 2147483647 then imm = imm-4294967296 end
525 pos = pos+n
526 imm = imm + pos + ctx.addr
527 if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end
528 ctx.imm = imm
529 if sz == "W" then
530 x = format("word 0x%04x", imm%65536)
531 elseif ctx.x64 then
532 local lo = imm % 0x1000000
533 x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo)
534 else
535 x = format("0x%08x", imm)
536 end
537 elseif p == "R" then
538 local r = byte(code, pos-1, pos-1)%8
539 if ctx.rexb then r = r + 8; ctx.rexb = false end
540 x = regs[r+1]
541 elseif p == "a" then x = regs[1]
542 elseif p == "c" then x = "cl"
543 elseif p == "d" then x = "dx"
544 elseif p == "1" then x = "1"
545 else
546 if not mode then
547 mode = ctx.mrm
548 if not mode then
549 if pos > stop then return incomplete(ctx) end
550 mode = byte(code, pos, pos)
551 pos = pos+1
552 end
553 rm = mode%8; mode = (mode-rm)/8
554 sp = mode%8; mode = (mode-sp)/8
555 sdisp = ""
556 if mode < 3 then
557 if rm == 4 then
558 if pos > stop then return incomplete(ctx) end
559 sc = byte(code, pos, pos)
560 pos = pos+1
561 rm = sc%8; sc = (sc-rm)/8
562 rx = sc%8; sc = (sc-rx)/8
563 if ctx.rexx then rx = rx + 8; ctx.rexx = false end
564 if rx == 4 then rx = nil end
565 end
566 if mode > 0 or rm == 5 then
567 local dsz = mode
568 if dsz ~= 1 then dsz = 4 end
569 local disp = getimm(ctx, pos, dsz); if not disp then return end
570 if mode == 0 then rm = nil end
571 if rm or rx or (not sc and ctx.x64 and not ctx.a32) then
572 if dsz == 1 and disp > 127 then
573 sdisp = format("-0x%x", 256-disp)
574 elseif disp >= 0 and disp <= 0x7fffffff then
575 sdisp = format("+0x%x", disp)
576 else
577 sdisp = format("-0x%x", (0xffffffff+1)-disp)
578 end
579 else
580 sdisp = format(ctx.x64 and not ctx.a32 and
581 not (disp >= 0 and disp <= 0x7fffffff)
582 and "0xffffffff%08x" or "0x%08x", disp)
583 end
584 pos = pos+dsz
585 end
586 end
587 if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end
588 if ctx.rexr then sp = sp + 8; ctx.rexr = false end
589 end
590 if p == "m" then
591 if mode == 3 then x = regs[rm+1]
592 else
593 local aregs = ctx.a32 and map_regs.D or ctx.aregs
594 local srm, srx = "", ""
595 if rm then srm = aregs[rm+1]
596 elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end
597 ctx.a32 = false
598 if rx then
599 if rm then srm = srm.."+" end
600 srx = aregs[rx+1]
601 if sc > 0 then srx = srx.."*"..(2^sc) end
602 end
603 x = format("[%s%s%s]", srm, srx, sdisp)
604 end
605 if mode < 3 and
606 (not match(pat, "[aRrgp]") or match(pat, "t")) then -- Yuck.
607 x = map_sz2prefix[sz].." "..x
608 end
609 elseif p == "r" then x = regs[sp+1]
610 elseif p == "g" then x = map_segregs[sp+1]
611 elseif p == "p" then -- Suppress prefix.
612 elseif p == "f" then x = "st"..rm
613 elseif p == "x" then
614 if sp == 0 and ctx.lock and not ctx.x64 then
615 x = "CR8"; ctx.lock = false
616 else
617 x = "CR"..sp
618 end
619 elseif p == "y" then x = "DR"..sp
620 elseif p == "z" then x = "TR"..sp
621 elseif p == "t" then
622 else
623 error("bad pattern `"..pat.."'")
624 end
625 end
626 if x then operands = operands and operands..", "..x or x end
627 end
628 ctx.pos = pos
629 return putop(ctx, name, operands)
630end
631
632-- Forward declaration.
633local map_act
634
635-- Fetch and cache MRM byte.
636local function getmrm(ctx)
637 local mrm = ctx.mrm
638 if not mrm then
639 local pos = ctx.pos
640 if pos > ctx.stop then return nil end
641 mrm = byte(ctx.code, pos, pos)
642 ctx.pos = pos+1
643 ctx.mrm = mrm
644 end
645 return mrm
646end
647
648-- Dispatch to handler depending on pattern.
649local function dispatch(ctx, opat, patgrp)
650 if not opat then return unknown(ctx) end
651 if match(opat, "%|") then -- MMX/SSE variants depending on prefix.
652 local p
653 if ctx.rep then
654 p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)"
655 ctx.rep = false
656 elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false
657 else p = "^[^%|]*" end
658 opat = match(opat, p)
659 if not opat then return unknown(ctx) end
660-- ctx.rep = false; ctx.o16 = false
661 --XXX fails for 66 f2 0f 38 f1 06 crc32 eax,WORD PTR [esi]
662 --XXX remove in branches?
663 end
664 if match(opat, "%$") then -- reg$mem variants.
665 local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
666 opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)")
667 if opat == "" then return unknown(ctx) end
668 end
669 if opat == "" then return unknown(ctx) end
670 local name, pat = match(opat, "^([a-z0-9 ]*)(.*)")
671 if pat == "" and patgrp then pat = patgrp end
672 return map_act[sub(pat, 1, 1)](ctx, name, pat)
673end
674
675-- Get a pattern from an opcode map and dispatch to handler.
676local function dispatchmap(ctx, opcmap)
677 local pos = ctx.pos
678 local opat = opcmap[byte(ctx.code, pos, pos)]
679 pos = pos + 1
680 ctx.pos = pos
681 return dispatch(ctx, opat)
682end
683
684-- Map for action codes. The key is the first char after the name.
685map_act = {
686 -- Simple opcodes without operands.
687 [""] = function(ctx, name, pat)
688 return putop(ctx, name)
689 end,
690
691 -- Operand size chars fall right through.
692 B = putpat, W = putpat, D = putpat, Q = putpat,
693 V = putpat, U = putpat, T = putpat,
694 M = putpat, X = putpat, P = putpat,
695 F = putpat, G = putpat,
696
697 -- Collect prefixes.
698 [":"] = function(ctx, name, pat)
699 ctx[pat == ":" and name or sub(pat, 2)] = name
700 if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes.
701 end,
702
703 -- Chain to special handler specified by name.
704 ["*"] = function(ctx, name, pat)
705 return map_act[name](ctx, name, sub(pat, 2))
706 end,
707
708 -- Use named subtable for opcode group.
709 ["!"] = function(ctx, name, pat)
710 local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
711 return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2))
712 end,
713
714 -- o16,o32[,o64] variants.
715 sz = function(ctx, name, pat)
716 if ctx.o16 then ctx.o16 = false
717 else
718 pat = match(pat, ",(.*)")
719 if ctx.rexw then
720 local p = match(pat, ",(.*)")
721 if p then pat = p; ctx.rexw = false end
722 end
723 end
724 pat = match(pat, "^[^,]*")
725 return dispatch(ctx, pat)
726 end,
727
728 -- Two-byte opcode dispatch.
729 opc2 = function(ctx, name, pat)
730 return dispatchmap(ctx, map_opc2)
731 end,
732
733 -- Three-byte opcode dispatch.
734 opc3 = function(ctx, name, pat)
735 return dispatchmap(ctx, map_opc3[pat])
736 end,
737
738 -- VMX/SVM dispatch.
739 vm = function(ctx, name, pat)
740 return dispatch(ctx, map_opcvm[ctx.mrm])
741 end,
742
743 -- Floating point opcode dispatch.
744 fp = function(ctx, name, pat)
745 local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
746 local rm = mrm%8
747 local idx = pat*8 + ((mrm-rm)/8)%8
748 if mrm >= 192 then idx = idx + 64 end
749 local opat = map_opcfp[idx]
750 if type(opat) == "table" then opat = opat[rm+1] end
751 return dispatch(ctx, opat)
752 end,
753
754 -- REX prefix.
755 rex = function(ctx, name, pat)
756 if ctx.rex then return unknown(ctx) end -- Only 1 REX prefix allowed.
757 for p in gmatch(pat, ".") do ctx["rex"..p] = true end
758 ctx.rex = true
759 end,
760
761 -- Special case for nop with REX prefix.
762 nop = function(ctx, name, pat)
763 return dispatch(ctx, ctx.rex and pat or "nop")
764 end,
765}
766
767------------------------------------------------------------------------------
768
769-- Disassemble a block of code.
770local function disass_block(ctx, ofs, len)
771 if not ofs then ofs = 0 end
772 local stop = len and ofs+len or #ctx.code
773 ofs = ofs + 1
774 ctx.start = ofs
775 ctx.pos = ofs
776 ctx.stop = stop
777 ctx.imm = nil
778 ctx.mrm = false
779 clearprefixes(ctx)
780 while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end
781 if ctx.pos ~= ctx.start then incomplete(ctx) end
782end
783
784-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
785local function create_(code, addr, out)
786 local ctx = {}
787 ctx.code = code
788 ctx.addr = (addr or 0) - 1
789 ctx.out = out or io.write
790 ctx.symtab = {}
791 ctx.disass = disass_block
792 ctx.hexdump = 16
793 ctx.x64 = false
794 ctx.map1 = map_opc1_32
795 ctx.aregs = map_regs.D
796 return ctx
797end
798
799local function create64_(code, addr, out)
800 local ctx = create_(code, addr, out)
801 ctx.x64 = true
802 ctx.map1 = map_opc1_64
803 ctx.aregs = map_regs.Q
804 return ctx
805end
806
807-- Simple API: disassemble code (a string) at address and output via out.
808local function disass_(code, addr, out)
809 create_(code, addr, out):disass()
810end
811
812local function disass64_(code, addr, out)
813 create64_(code, addr, out):disass()
814end
815
816-- Return register name for RID.
817local function regname_(r)
818 if r < 8 then return map_regs.D[r+1] end
819 return map_regs.X[r-7]
820end
821
822local function regname64_(r)
823 if r < 16 then return map_regs.Q[r+1] end
824 return map_regs.X[r-15]
825end
826
827-- Public module functions.
828module(...)
829
830create = create_
831create64 = create64_
832disass = disass_
833disass64 = disass64_
834regname = regname_
835regname64 = regname64_
836
diff --git a/libraries/luajit-2.0/lib/dump.lua b/libraries/luajit-2.0/lib/dump.lua
new file mode 100644
index 0000000..0f0e905
--- /dev/null
+++ b/libraries/luajit-2.0/lib/dump.lua
@@ -0,0 +1,685 @@
1----------------------------------------------------------------------------
2-- LuaJIT compiler dump module.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT license. See Copyright Notice in luajit.h
6----------------------------------------------------------------------------
7--
8-- This module can be used to debug the JIT compiler itself. It dumps the
9-- code representations and structures used in various compiler stages.
10--
11-- Example usage:
12--
13-- luajit -jdump -e "local x=0; for i=1,1e6 do x=x+i end; print(x)"
14-- luajit -jdump=im -e "for i=1,1000 do for j=1,1000 do end end" | less -R
15-- luajit -jdump=is myapp.lua | less -R
16-- luajit -jdump=-b myapp.lua
17-- luajit -jdump=+aH,myapp.html myapp.lua
18-- luajit -jdump=ixT,myapp.dump myapp.lua
19--
20-- The first argument specifies the dump mode. The second argument gives
21-- the output file name. Default output is to stdout, unless the environment
22-- variable LUAJIT_DUMPFILE is set. The file is overwritten every time the
23-- module is started.
24--
25-- Different features can be turned on or off with the dump mode. If the
26-- mode starts with a '+', the following features are added to the default
27-- set of features; a '-' removes them. Otherwise the features are replaced.
28--
29-- The following dump features are available (* marks the default):
30--
31-- * t Print a line for each started, ended or aborted trace (see also -jv).
32-- * b Dump the traced bytecode.
33-- * i Dump the IR (intermediate representation).
34-- r Augment the IR with register/stack slots.
35-- s Dump the snapshot map.
36-- * m Dump the generated machine code.
37-- x Print each taken trace exit.
38-- X Print each taken trace exit and the contents of all registers.
39--
40-- The output format can be set with the following characters:
41--
42-- T Plain text output.
43-- A ANSI-colored text output
44-- H Colorized HTML + CSS output.
45--
46-- The default output format is plain text. It's set to ANSI-colored text
47-- if the COLORTERM variable is set. Note: this is independent of any output
48-- redirection, which is actually considered a feature.
49--
50-- You probably want to use less -R to enjoy viewing ANSI-colored text from
51-- a pipe or a file. Add this to your ~/.bashrc: export LESS="-R"
52--
53------------------------------------------------------------------------------
54
55-- Cache some library functions and objects.
56local jit = require("jit")
57assert(jit.version_num == 20000, "LuaJIT core/library version mismatch")
58local jutil = require("jit.util")
59local vmdef = require("jit.vmdef")
60local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc
61local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek
62local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap
63local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr
64local bit = require("bit")
65local band, shl, shr = bit.band, bit.lshift, bit.rshift
66local sub, gsub, format = string.sub, string.gsub, string.format
67local byte, char, rep = string.byte, string.char, string.rep
68local type, tostring = type, tostring
69local stdout, stderr = io.stdout, io.stderr
70
71-- Load other modules on-demand.
72local bcline, disass
73
74-- Active flag, output file handle and dump mode.
75local active, out, dumpmode
76
77------------------------------------------------------------------------------
78
79local symtabmt = { __index = false }
80local symtab = {}
81local nexitsym = 0
82
83-- Fill nested symbol table with per-trace exit stub addresses.
84local function fillsymtab_tr(tr, nexit)
85 local t = {}
86 symtabmt.__index = t
87 for i=0,nexit-1 do
88 local addr = traceexitstub(tr, i)
89 t[addr] = tostring(i)
90 end
91 local addr = traceexitstub(tr, nexit)
92 if addr then t[addr] = "stack_check" end
93end
94
95-- Fill symbol table with trace exit stub addresses.
96local function fillsymtab(tr, nexit)
97 local t = symtab
98 if nexitsym == 0 then
99 local ircall = vmdef.ircall
100 for i=0,#ircall do
101 local addr = ircalladdr(i)
102 if addr ~= 0 then t[addr] = ircall[i] end
103 end
104 end
105 if nexitsym == 1000000 then -- Per-trace exit stubs.
106 fillsymtab_tr(tr, nexit)
107 elseif nexit > nexitsym then -- Shared exit stubs.
108 for i=nexitsym,nexit-1 do
109 local addr = traceexitstub(i)
110 if addr == nil then -- Fall back to per-trace exit stubs.
111 fillsymtab_tr(tr, nexit)
112 setmetatable(symtab, symtabmt)
113 nexit = 1000000
114 break
115 end
116 t[addr] = tostring(i)
117 end
118 nexitsym = nexit
119 end
120 return t
121end
122
123local function dumpwrite(s)
124 out:write(s)
125end
126
127-- Disassemble machine code.
128local function dump_mcode(tr)
129 local info = traceinfo(tr)
130 if not info then return end
131 local mcode, addr, loop = tracemc(tr)
132 if not mcode then return end
133 if not disass then disass = require("jit.dis_"..jit.arch) end
134 out:write("---- TRACE ", tr, " mcode ", #mcode, "\n")
135 local ctx = disass.create(mcode, addr, dumpwrite)
136 ctx.hexdump = 0
137 ctx.symtab = fillsymtab(tr, info.nexit)
138 if loop ~= 0 then
139 symtab[addr+loop] = "LOOP"
140 ctx:disass(0, loop)
141 out:write("->LOOP:\n")
142 ctx:disass(loop, #mcode-loop)
143 symtab[addr+loop] = nil
144 else
145 ctx:disass(0, #mcode)
146 end
147end
148
149------------------------------------------------------------------------------
150
151local irtype_text = {
152 [0] = "nil",
153 "fal",
154 "tru",
155 "lud",
156 "str",
157 "p32",
158 "thr",
159 "pro",
160 "fun",
161 "p64",
162 "cdt",
163 "tab",
164 "udt",
165 "flt",
166 "num",
167 "i8 ",
168 "u8 ",
169 "i16",
170 "u16",
171 "int",
172 "u32",
173 "i64",
174 "u64",
175 "sfp",
176}
177
178local colortype_ansi = {
179 [0] = "%s",
180 "%s",
181 "%s",
182 "\027[36m%s\027[m",
183 "\027[32m%s\027[m",
184 "%s",
185 "\027[1m%s\027[m",
186 "%s",
187 "\027[1m%s\027[m",
188 "%s",
189 "\027[33m%s\027[m",
190 "\027[31m%s\027[m",
191 "\027[36m%s\027[m",
192 "\027[34m%s\027[m",
193 "\027[34m%s\027[m",
194 "\027[35m%s\027[m",
195 "\027[35m%s\027[m",
196 "\027[35m%s\027[m",
197 "\027[35m%s\027[m",
198 "\027[35m%s\027[m",
199 "\027[35m%s\027[m",
200 "\027[35m%s\027[m",
201 "\027[35m%s\027[m",
202 "\027[35m%s\027[m",
203}
204
205local function colorize_text(s, t)
206 return s
207end
208
209local function colorize_ansi(s, t)
210 return format(colortype_ansi[t], s)
211end
212
213local irtype_ansi = setmetatable({},
214 { __index = function(tab, t)
215 local s = colorize_ansi(irtype_text[t], t); tab[t] = s; return s; end })
216
217local html_escape = { ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;", }
218
219local function colorize_html(s, t)
220 s = gsub(s, "[<>&]", html_escape)
221 return format('<span class="irt_%s">%s</span>', irtype_text[t], s)
222end
223
224local irtype_html = setmetatable({},
225 { __index = function(tab, t)
226 local s = colorize_html(irtype_text[t], t); tab[t] = s; return s; end })
227
228local header_html = [[
229<style type="text/css">
230background { background: #ffffff; color: #000000; }
231pre.ljdump {
232font-size: 10pt;
233background: #f0f4ff;
234color: #000000;
235border: 1px solid #bfcfff;
236padding: 0.5em;
237margin-left: 2em;
238margin-right: 2em;
239}
240span.irt_str { color: #00a000; }
241span.irt_thr, span.irt_fun { color: #404040; font-weight: bold; }
242span.irt_tab { color: #c00000; }
243span.irt_udt, span.irt_lud { color: #00c0c0; }
244span.irt_num { color: #4040c0; }
245span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b040b0; }
246</style>
247]]
248
249local colorize, irtype
250
251-- Lookup tables to convert some literals into names.
252local litname = {
253 ["SLOAD "] = setmetatable({}, { __index = function(t, mode)
254 local s = ""
255 if band(mode, 1) ~= 0 then s = s.."P" end
256 if band(mode, 2) ~= 0 then s = s.."F" end
257 if band(mode, 4) ~= 0 then s = s.."T" end
258 if band(mode, 8) ~= 0 then s = s.."C" end
259 if band(mode, 16) ~= 0 then s = s.."R" end
260 if band(mode, 32) ~= 0 then s = s.."I" end
261 t[mode] = s
262 return s
263 end}),
264 ["XLOAD "] = { [0] = "", "R", "V", "RV", "U", "RU", "VU", "RVU", },
265 ["CONV "] = setmetatable({}, { __index = function(t, mode)
266 local s = irtype[band(mode, 31)]
267 s = irtype[band(shr(mode, 5), 31)].."."..s
268 if band(mode, 0x400) ~= 0 then s = s.." trunc"
269 elseif band(mode, 0x800) ~= 0 then s = s.." sext" end
270 local c = shr(mode, 14)
271 if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end
272 t[mode] = s
273 return s
274 end}),
275 ["FLOAD "] = vmdef.irfield,
276 ["FREF "] = vmdef.irfield,
277 ["FPMATH"] = vmdef.irfpm,
278}
279
280local function ctlsub(c)
281 if c == "\n" then return "\\n"
282 elseif c == "\r" then return "\\r"
283 elseif c == "\t" then return "\\t"
284 elseif c == "\r" then return "\\r"
285 else return format("\\%03d", byte(c))
286 end
287end
288
289local function fmtfunc(func, pc)
290 local fi = funcinfo(func, pc)
291 if fi.loc then
292 return fi.loc
293 elseif fi.ffid then
294 return vmdef.ffnames[fi.ffid]
295 elseif fi.addr then
296 return format("C:%x", fi.addr)
297 else
298 return "(?)"
299 end
300end
301
302local function formatk(tr, idx)
303 local k, t, slot = tracek(tr, idx)
304 local tn = type(k)
305 local s
306 if tn == "number" then
307 if k == 2^52+2^51 then
308 s = "bias"
309 else
310 s = format("%+.14g", k)
311 end
312 elseif tn == "string" then
313 s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub))
314 elseif tn == "function" then
315 s = fmtfunc(k)
316 elseif tn == "table" then
317 s = format("{%p}", k)
318 elseif tn == "userdata" then
319 if t == 12 then
320 s = format("userdata:%p", k)
321 else
322 s = format("[%p]", k)
323 if s == "[0x00000000]" then s = "NULL" end
324 end
325 elseif t == 21 then -- int64_t
326 s = sub(tostring(k), 1, -3)
327 if sub(s, 1, 1) ~= "-" then s = "+"..s end
328 else
329 s = tostring(k) -- For primitives.
330 end
331 s = colorize(format("%-4s", s), t)
332 if slot then
333 s = format("%s @%d", s, slot)
334 end
335 return s
336end
337
338local function printsnap(tr, snap)
339 local n = 2
340 for s=0,snap[1]-1 do
341 local sn = snap[n]
342 if shr(sn, 24) == s then
343 n = n + 1
344 local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS
345 if ref < 0 then
346 out:write(formatk(tr, ref))
347 elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM
348 out:write(colorize(format("%04d/%04d", ref, ref+1), 14))
349 else
350 local m, ot, op1, op2 = traceir(tr, ref)
351 out:write(colorize(format("%04d", ref), band(ot, 31)))
352 end
353 out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME
354 else
355 out:write("---- ")
356 end
357 end
358 out:write("]\n")
359end
360
361-- Dump snapshots (not interleaved with IR).
362local function dump_snap(tr)
363 out:write("---- TRACE ", tr, " snapshots\n")
364 for i=0,1000000000 do
365 local snap = tracesnap(tr, i)
366 if not snap then break end
367 out:write(format("#%-3d %04d [ ", i, snap[0]))
368 printsnap(tr, snap)
369 end
370end
371
372-- Return a register name or stack slot for a rid/sp location.
373local function ridsp_name(ridsp)
374 if not disass then disass = require("jit.dis_"..jit.arch) end
375 local rid = band(ridsp, 0xff)
376 if ridsp > 255 then return format("[%x]", shr(ridsp, 8)*4) end
377 if rid < 128 then return disass.regname(rid) end
378 return ""
379end
380
381-- Dump CALL* function ref and return optional ctype.
382local function dumpcallfunc(tr, ins)
383 local ctype
384 if ins > 0 then
385 local m, ot, op1, op2 = traceir(tr, ins)
386 if band(ot, 31) == 0 then -- nil type means CARG(func, ctype).
387 ins = op1
388 ctype = formatk(tr, op2)
389 end
390 end
391 if ins < 0 then
392 out:write(format("[0x%x](", tonumber((tracek(tr, ins)))))
393 else
394 out:write(format("%04d (", ins))
395 end
396 return ctype
397end
398
399-- Recursively gather CALL* args and dump them.
400local function dumpcallargs(tr, ins)
401 if ins < 0 then
402 out:write(formatk(tr, ins))
403 else
404 local m, ot, op1, op2 = traceir(tr, ins)
405 local oidx = 6*shr(ot, 8)
406 local op = sub(vmdef.irnames, oidx+1, oidx+6)
407 if op == "CARG " then
408 dumpcallargs(tr, op1)
409 if op2 < 0 then
410 out:write(" ", formatk(tr, op2))
411 else
412 out:write(" ", format("%04d", op2))
413 end
414 else
415 out:write(format("%04d", ins))
416 end
417 end
418end
419
420-- Dump IR and interleaved snapshots.
421local function dump_ir(tr, dumpsnap, dumpreg)
422 local info = traceinfo(tr)
423 if not info then return end
424 local nins = info.nins
425 out:write("---- TRACE ", tr, " IR\n")
426 local irnames = vmdef.irnames
427 local snapref = 65536
428 local snap, snapno
429 if dumpsnap then
430 snap = tracesnap(tr, 0)
431 snapref = snap[0]
432 snapno = 0
433 end
434 for ins=1,nins do
435 if ins >= snapref then
436 if dumpreg then
437 out:write(format(".... SNAP #%-3d [ ", snapno))
438 else
439 out:write(format(".... SNAP #%-3d [ ", snapno))
440 end
441 printsnap(tr, snap)
442 snapno = snapno + 1
443 snap = tracesnap(tr, snapno)
444 snapref = snap and snap[0] or 65536
445 end
446 local m, ot, op1, op2, ridsp = traceir(tr, ins)
447 local oidx, t = 6*shr(ot, 8), band(ot, 31)
448 local op = sub(irnames, oidx+1, oidx+6)
449 if op == "LOOP " then
450 if dumpreg then
451 out:write(format("%04d ------------ LOOP ------------\n", ins))
452 else
453 out:write(format("%04d ------ LOOP ------------\n", ins))
454 end
455 elseif op ~= "NOP " and op ~= "CARG " and
456 (dumpreg or op ~= "RENAME") then
457 if dumpreg then
458 out:write(format("%04d %-5s ", ins, ridsp_name(ridsp)))
459 else
460 out:write(format("%04d ", ins))
461 end
462 out:write(format("%s%s %s %s ",
463 band(ot, 128) == 0 and " " or ">",
464 band(ot, 64) == 0 and " " or "+",
465 irtype[t], op))
466 local m1, m2 = band(m, 3), band(m, 3*4)
467 if sub(op, 1, 4) == "CALL" then
468 local ctype
469 if m2 == 1*4 then -- op2 == IRMlit
470 out:write(format("%-10s (", vmdef.ircall[op2]))
471 else
472 ctype = dumpcallfunc(tr, op2)
473 end
474 if op1 ~= -1 then dumpcallargs(tr, op1) end
475 out:write(")")
476 if ctype then out:write(" ctype ", ctype) end
477 elseif op == "CNEW " and op2 == -1 then
478 out:write(formatk(tr, op1))
479 elseif m1 ~= 3 then -- op1 != IRMnone
480 if op1 < 0 then
481 out:write(formatk(tr, op1))
482 else
483 out:write(format(m1 == 0 and "%04d" or "#%-3d", op1))
484 end
485 if m2 ~= 3*4 then -- op2 != IRMnone
486 if m2 == 1*4 then -- op2 == IRMlit
487 local litn = litname[op]
488 if litn and litn[op2] then
489 out:write(" ", litn[op2])
490 elseif op == "UREFO " or op == "UREFC " then
491 out:write(format(" #%-3d", shr(op2, 8)))
492 else
493 out:write(format(" #%-3d", op2))
494 end
495 elseif op2 < 0 then
496 out:write(" ", formatk(tr, op2))
497 else
498 out:write(format(" %04d", op2))
499 end
500 end
501 end
502 out:write("\n")
503 end
504 end
505 if snap then
506 if dumpreg then
507 out:write(format(".... SNAP #%-3d [ ", snapno))
508 else
509 out:write(format(".... SNAP #%-3d [ ", snapno))
510 end
511 printsnap(tr, snap)
512 end
513end
514
515------------------------------------------------------------------------------
516
517local recprefix = ""
518local recdepth = 0
519
520-- Format trace error message.
521local function fmterr(err, info)
522 if type(err) == "number" then
523 if type(info) == "function" then info = fmtfunc(info) end
524 err = format(vmdef.traceerr[err], info)
525 end
526 return err
527end
528
529-- Dump trace states.
530local function dump_trace(what, tr, func, pc, otr, oex)
531 if what == "stop" or (what == "abort" and dumpmode.a) then
532 if dumpmode.i then dump_ir(tr, dumpmode.s, dumpmode.r and what == "stop")
533 elseif dumpmode.s then dump_snap(tr) end
534 if dumpmode.m then dump_mcode(tr) end
535 end
536 if what == "start" then
537 if dumpmode.H then out:write('<pre class="ljdump">\n') end
538 out:write("---- TRACE ", tr, " ", what)
539 if otr then out:write(" ", otr, "/", oex) end
540 out:write(" ", fmtfunc(func, pc), "\n")
541 recprefix = ""
542 elseif what == "stop" or what == "abort" then
543 out:write("---- TRACE ", tr, " ", what)
544 recprefix = nil
545 if what == "abort" then
546 out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
547 else
548 local info = traceinfo(tr)
549 local link, ltype = info.link, info.linktype
550 if link == tr or link == 0 then
551 out:write(" -> ", ltype, "\n")
552 elseif ltype == "root" then
553 out:write(" -> ", link, "\n")
554 else
555 out:write(" -> ", link, " ", ltype, "\n")
556 end
557 end
558 if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
559 else
560 out:write("---- TRACE ", what, "\n\n")
561 end
562 out:flush()
563end
564
565-- Dump recorded bytecode.
566local function dump_record(tr, func, pc, depth, callee)
567 if depth ~= recdepth then
568 recdepth = depth
569 recprefix = rep(" .", depth)
570 end
571 local line
572 if pc >= 0 then
573 line = bcline(func, pc, recprefix)
574 if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end
575 else
576 line = "0000 "..recprefix.." FUNCC \n"
577 callee = func
578 end
579 if pc <= 0 then
580 out:write(sub(line, 1, -2), " ; ", fmtfunc(func), "\n")
581 else
582 out:write(line)
583 end
584 if pc >= 0 and band(funcbc(func, pc), 0xff) < 16 then -- ORDER BC
585 out:write(bcline(func, pc+1, recprefix)) -- Write JMP for cond.
586 end
587end
588
589------------------------------------------------------------------------------
590
591-- Dump taken trace exits.
592local function dump_texit(tr, ex, ngpr, nfpr, ...)
593 out:write("---- TRACE ", tr, " exit ", ex, "\n")
594 if dumpmode.X then
595 local regs = {...}
596 if jit.arch == "x64" then
597 for i=1,ngpr do
598 out:write(format(" %016x", regs[i]))
599 if i % 4 == 0 then out:write("\n") end
600 end
601 else
602 for i=1,ngpr do
603 out:write(format(" %08x", regs[i]))
604 if i % 8 == 0 then out:write("\n") end
605 end
606 end
607 for i=1,nfpr do
608 out:write(format(" %+17.14g", regs[ngpr+i]))
609 if i % 4 == 0 then out:write("\n") end
610 end
611 end
612end
613
614------------------------------------------------------------------------------
615
616-- Detach dump handlers.
617local function dumpoff()
618 if active then
619 active = false
620 jit.attach(dump_texit)
621 jit.attach(dump_record)
622 jit.attach(dump_trace)
623 if out and out ~= stdout and out ~= stderr then out:close() end
624 out = nil
625 end
626end
627
628-- Open the output file and attach dump handlers.
629local function dumpon(opt, outfile)
630 if active then dumpoff() end
631
632 local colormode = os.getenv("COLORTERM") and "A" or "T"
633 if opt then
634 opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end)
635 end
636
637 local m = { t=true, b=true, i=true, m=true, }
638 if opt and opt ~= "" then
639 local o = sub(opt, 1, 1)
640 if o ~= "+" and o ~= "-" then m = {} end
641 for i=1,#opt do m[sub(opt, i, i)] = (o ~= "-") end
642 end
643 dumpmode = m
644
645 if m.t or m.b or m.i or m.s or m.m then
646 jit.attach(dump_trace, "trace")
647 end
648 if m.b then
649 jit.attach(dump_record, "record")
650 if not bcline then bcline = require("jit.bc").line end
651 end
652 if m.x or m.X then
653 jit.attach(dump_texit, "texit")
654 end
655
656 if not outfile then outfile = os.getenv("LUAJIT_DUMPFILE") end
657 if outfile then
658 out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
659 else
660 out = stdout
661 end
662
663 m[colormode] = true
664 if colormode == "A" then
665 colorize = colorize_ansi
666 irtype = irtype_ansi
667 elseif colormode == "H" then
668 colorize = colorize_html
669 irtype = irtype_html
670 out:write(header_html)
671 else
672 colorize = colorize_text
673 irtype = irtype_text
674 end
675
676 active = true
677end
678
679-- Public module functions.
680module(...)
681
682on = dumpon
683off = dumpoff
684start = dumpon -- For -j command line option.
685
diff --git a/libraries/luajit-2.0/lib/v.lua b/libraries/luajit-2.0/lib/v.lua
new file mode 100644
index 0000000..ca9b4ac
--- /dev/null
+++ b/libraries/luajit-2.0/lib/v.lua
@@ -0,0 +1,167 @@
1----------------------------------------------------------------------------
2-- Verbose mode of the LuaJIT compiler.
3--
4-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5-- Released under the MIT license. See Copyright Notice in luajit.h
6----------------------------------------------------------------------------
7--
8-- This module shows verbose information about the progress of the
9-- JIT compiler. It prints one line for each generated trace. This module
10-- is useful to see which code has been compiled or where the compiler
11-- punts and falls back to the interpreter.
12--
13-- Example usage:
14--
15-- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end"
16-- luajit -jv=myapp.out myapp.lua
17--
18-- Default output is to stderr. To redirect the output to a file, pass a
19-- filename as an argument (use '-' for stdout) or set the environment
20-- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the
21-- module is started.
22--
23-- The output from the first example should look like this:
24--
25-- [TRACE 1 (command line):1 loop]
26-- [TRACE 2 (1/3) (command line):1 -> 1]
27--
28-- The first number in each line is the internal trace number. Next are
29-- the file name ('(command line)') and the line number (':1') where the
30-- trace has started. Side traces also show the parent trace number and
31-- the exit number where they are attached to in parentheses ('(1/3)').
32-- An arrow at the end shows where the trace links to ('-> 1'), unless
33-- it loops to itself.
34--
35-- In this case the inner loop gets hot and is traced first, generating
36-- a root trace. Then the last exit from the 1st trace gets hot, too,
37-- and triggers generation of the 2nd trace. The side trace follows the
38-- path along the outer loop and *around* the inner loop, back to its
39-- start, and then links to the 1st trace. Yes, this may seem unusual,
40-- if you know how traditional compilers work. Trace compilers are full
41-- of surprises like this -- have fun! :-)
42--
43-- Aborted traces are shown like this:
44--
45-- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50]
46--
47-- Don't worry -- trace aborts are quite common, even in programs which
48-- can be fully compiled. The compiler may retry several times until it
49-- finds a suitable trace.
50--
51-- Of course this doesn't work with features that are not-yet-implemented
52-- (NYI error messages). The VM simply falls back to the interpreter. This
53-- may not matter at all if the particular trace is not very high up in
54-- the CPU usage profile. Oh, and the interpreter is quite fast, too.
55--
56-- Also check out the -jdump module, which prints all the gory details.
57--
58------------------------------------------------------------------------------
59
60-- Cache some library functions and objects.
61local jit = require("jit")
62assert(jit.version_num == 20000, "LuaJIT core/library version mismatch")
63local jutil = require("jit.util")
64local vmdef = require("jit.vmdef")
65local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
66local type, format = type, string.format
67local stdout, stderr = io.stdout, io.stderr
68
69-- Active flag and output file handle.
70local active, out
71
72------------------------------------------------------------------------------
73
74local startloc, startex
75
76local function fmtfunc(func, pc)
77 local fi = funcinfo(func, pc)
78 if fi.loc then
79 return fi.loc
80 elseif fi.ffid then
81 return vmdef.ffnames[fi.ffid]
82 elseif fi.addr then
83 return format("C:%x", fi.addr)
84 else
85 return "(?)"
86 end
87end
88
89-- Format trace error message.
90local function fmterr(err, info)
91 if type(err) == "number" then
92 if type(info) == "function" then info = fmtfunc(info) end
93 err = format(vmdef.traceerr[err], info)
94 end
95 return err
96end
97
98-- Dump trace states.
99local function dump_trace(what, tr, func, pc, otr, oex)
100 if what == "start" then
101 startloc = fmtfunc(func, pc)
102 startex = otr and "("..otr.."/"..oex..") " or ""
103 else
104 if what == "abort" then
105 local loc = fmtfunc(func, pc)
106 if loc ~= startloc then
107 out:write(format("[TRACE --- %s%s -- %s at %s]\n",
108 startex, startloc, fmterr(otr, oex), loc))
109 else
110 out:write(format("[TRACE --- %s%s -- %s]\n",
111 startex, startloc, fmterr(otr, oex)))
112 end
113 elseif what == "stop" then
114 local info = traceinfo(tr)
115 local link, ltype = info.link, info.linktype
116 if ltype == "interpreter" then
117 out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
118 tr, startex, startloc))
119 elseif link == tr or link == 0 then
120 out:write(format("[TRACE %3s %s%s %s]\n",
121 tr, startex, startloc, ltype))
122 elseif ltype == "root" then
123 out:write(format("[TRACE %3s %s%s -> %d]\n",
124 tr, startex, startloc, link))
125 else
126 out:write(format("[TRACE %3s %s%s -> %d %s]\n",
127 tr, startex, startloc, link, ltype))
128 end
129 else
130 out:write(format("[TRACE %s]\n", what))
131 end
132 out:flush()
133 end
134end
135
136------------------------------------------------------------------------------
137
138-- Detach dump handlers.
139local function dumpoff()
140 if active then
141 active = false
142 jit.attach(dump_trace)
143 if out and out ~= stdout and out ~= stderr then out:close() end
144 out = nil
145 end
146end
147
148-- Open the output file and attach dump handlers.
149local function dumpon(outfile)
150 if active then dumpoff() end
151 if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end
152 if outfile then
153 out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
154 else
155 out = stderr
156 end
157 jit.attach(dump_trace, "trace")
158 active = true
159end
160
161-- Public module functions.
162module(...)
163
164on = dumpon
165off = dumpoff
166start = dumpon -- For -j command line option.
167
diff --git a/libraries/luajit-2.0/src/.gitignore b/libraries/luajit-2.0/src/.gitignore
new file mode 100644
index 0000000..8373308
--- /dev/null
+++ b/libraries/luajit-2.0/src/.gitignore
@@ -0,0 +1,8 @@
1luajit
2buildvm
3lj_bcdef.h
4lj_ffdef.h
5lj_libdef.h
6lj_recdef.h
7lj_folddef.h
8lj_vm.s
diff --git a/libraries/luajit-2.0/src/Makefile b/libraries/luajit-2.0/src/Makefile
new file mode 100644
index 0000000..5a60612
--- /dev/null
+++ b/libraries/luajit-2.0/src/Makefile
@@ -0,0 +1,633 @@
1##############################################################################
2# LuaJIT Makefile. Requires GNU Make.
3#
4# Please read doc/install.html before changing any variables!
5#
6# Suitable for POSIX platforms (Linux, *BSD, OSX etc.).
7# Also works with MinGW and Cygwin on Windows.
8# Please check msvcbuild.bat for building with MSVC on Windows.
9#
10# Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
11##############################################################################
12
13MAJVER= 2
14MINVER= 0
15RELVER= 0
16ABIVER= 5.1
17NODOTABIVER= 51
18
19##############################################################################
20############################# COMPILER OPTIONS #############################
21##############################################################################
22# These options mainly affect the speed of the JIT compiler itself, not the
23# speed of the JIT-compiled code. Turn any of the optional settings on by
24# removing the '#' in front of them. Make sure you force a full recompile
25# with "make clean", followed by "make" if you change any options.
26#
27# LuaJIT builds as a native 32 or 64 bit binary by default.
28CC= gcc
29#
30# Use this if you want to force a 32 bit build on a 64 bit multilib OS.
31#CC= gcc -m32
32#
33# Since the assembler part does NOT maintain a frame pointer, it's pointless
34# to slow down the C part by not omitting it. Debugging, tracebacks and
35# unwinding are not affected -- the assembler part has frame unwind
36# information and GCC emits it where needed (x64) or with -g (see CCDEBUG).
37CCOPT= -O2 -fomit-frame-pointer
38# Use this if you want to generate a smaller binary (but it's slower):
39#CCOPT= -Os -fomit-frame-pointer
40# Note: it's no longer recommended to use -O3 with GCC 4.x.
41# The I-Cache bloat usually outweighs the benefits from aggressive inlining.
42#
43# Target-specific compiler options:
44#
45# x86 only: it's recommended to compile at least for i686. By default the
46# assembler part of the interpreter makes use of CMOV/FCOMI*/FUCOMI*
47# instructions, anyway.
48#
49# x86/x64 only: For GCC 4.2 or higher and if you don't intend to distribute
50# the binaries to a different machine you could also use: -march=native
51#
52CCOPT_X86= -march=i686
53CCOPT_X64=
54CCOPT_ARM=
55CCOPT_PPC=
56CCOPT_PPCSPE=
57CCOPT_MIPS=
58#
59CCDEBUG=
60# Uncomment the next line to generate debug information:
61#CCDEBUG= -g
62#
63CCWARN= -Wall
64# Uncomment the next line to enable more warnings:
65#CCWARN+= -Wextra -Wdeclaration-after-statement -Wredundant-decls -Wshadow -Wpointer-arith
66#
67##############################################################################
68
69##############################################################################
70################################ BUILD MODE ################################
71##############################################################################
72# The default build mode is mixed mode on POSIX. On Windows this is the same
73# as dynamic mode.
74#
75# Mixed mode creates a static + dynamic library and a statically linked luajit.
76BUILDMODE= mixed
77#
78# Static mode creates a static library and a statically linked luajit.
79#BUILDMODE= static
80#
81# Dynamic mode creates a dynamic library and a dynamically linked luajit.
82# Note: this executable will only run when the library is installed!
83#BUILDMODE= dynamic
84#
85##############################################################################
86
87##############################################################################
88################################# FEATURES #################################
89##############################################################################
90# Enable/disable these features as needed, but make sure you force a full
91# recompile with "make clean", followed by "make".
92XCFLAGS=
93#
94# Permanently disable the FFI extension to reduce the size of the LuaJIT
95# executable. But please consider that the FFI library is compiled-in,
96# but NOT loaded by default. It only allocates any memory, if you actually
97# make use of it.
98#XCFLAGS+= -DLUAJIT_DISABLE_FFI
99#
100# Enable some upwards-compatible features from Lua 5.2 that are unlikely
101# to break existing code (e.g. __pairs). Note that this does not provide
102# full compatibility with Lua 5.2 at this time.
103#XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
104#
105# Disable the JIT compiler, i.e. turn LuaJIT into a pure interpreter.
106#XCFLAGS+= -DLUAJIT_DISABLE_JIT
107#
108# x86 only: use SSE2 instead of x87 instructions in the interpreter
109# (always enabled for x64). A pure interpreter built with this flag won't
110# run on older CPUs (before P4 or K8). There isn't much of a speed
111# difference, so this is not enabled by default.
112# The JIT compiler is not affected by this flag. It always uses runtime
113# CPU feature detection before emitting code for SSE2 up to SSE4.1.
114#XCFLAGS+= -DLUAJIT_CPU_SSE2
115#
116# x86 only: Disable the use of CMOV and FCOMI*/FUCOMI* instructions in the
117# interpreter. Do this only if you intend to use REALLY ANCIENT CPUs
118# (before Pentium Pro, or on the VIA C3). This generally slows down the
119# interpreter. Don't bother if your OS wouldn't run on them, anyway.
120#XCFLAGS+= -DLUAJIT_CPU_NOCMOV
121#
122# Some architectures (e.g. PPC) can use either single-number (1) or
123# dual-number (2) mode. Uncomment one of these lines to override the
124# default mode. Please see LJ_ARCH_NUMMODE in lj_arch.h for details.
125#XCFLAGS+= -DLUAJIT_NUMMODE=1
126#XCFLAGS+= -DLUAJIT_NUMMODE=2
127#
128##############################################################################
129
130##############################################################################
131############################ DEBUGGING SUPPORT #############################
132##############################################################################
133# Enable these options as needed, but make sure you force a full recompile
134# with "make clean", followed by "make".
135# Note that most of these are NOT suitable for benchmarking or release mode!
136#
137# Use the system provided memory allocator (realloc) instead of the
138# bundled memory allocator. This is slower, but sometimes helpful for
139# debugging. It's helpful for Valgrind's memcheck tool, too. This option
140# cannot be enabled on x64, since the built-in allocator is mandatory.
141#XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
142#
143# This define is required to run LuaJIT under Valgrind. The Valgrind
144# header files must be installed. You should enable debug information, too.
145#XCFLAGS+= -DLUAJIT_USE_VALGRIND
146#
147# This is the client for the GDB JIT API. GDB 7.0 or higher is required
148# to make use of it. See lj_gdbjit.c for details. Enabling this causes
149# a non-negligible overhead, even when not running under GDB.
150#XCFLAGS+= -DLUAJIT_USE_GDBJIT
151#
152# Turn on assertions for the Lua/C API to debug problems with lua_* calls.
153# This is rather slow -- use only while developing C libraries/embeddings.
154#XCFLAGS+= -DLUA_USE_APICHECK
155#
156# Turn on assertions for the whole LuaJIT VM. This significantly slows down
157# everything. Use only if you suspect a problem with LuaJIT itself.
158#XCFLAGS+= -DLUA_USE_ASSERT
159#
160##############################################################################
161# You probably don't need to change anything below this line!
162##############################################################################
163
164##############################################################################
165# Flags and options for host and target.
166##############################################################################
167
168# You can override the following variables at the make command line:
169# CC HOST_CC STATIC_CC DYNAMIC_CC
170# CFLAGS HOST_CFLAGS TARGET_CFLAGS
171# LDFLAGS HOST_LDFLAGS TARGET_LDFLAGS TARGET_SHLDFLAGS
172# LIBS HOST_LIBS TARGET_LIBS
173# CROSS HOST_SYS TARGET_SYS TARGET_FLAGS
174#
175# Cross-compilation examples:
176# make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
177# make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
178
179CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(XCFLAGS) $(CFLAGS)
180LDOPTIONS= $(CCDEBUG) $(LDFLAGS)
181
182HOST_CC= $(CC)
183HOST_RM= rm -f
184# NOTE: The LuaJIT distribution comes with pre-generated buildvm_*.h files.
185# You DO NOT NEED an installed copy of (plain) Lua 5.1 to run DynASM unless
186# you want to MODIFY the corresponding *.dasc file. You can also use LuaJIT
187# itself (bootstrapped from a pre-generated file) to run DynASM of course.
188HOST_LUA= lua
189
190HOST_XCFLAGS=
191HOST_XLDFLAGS=
192HOST_XLIBS=
193HOST_ACFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH) $(HOST_CFLAGS)
194HOST_ALDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS) $(HOST_LDFLAGS)
195HOST_ALIBS= $(HOST_XLIBS) $(LIBS) $(HOST_LIBS)
196
197STATIC_CC = $(CROSS)$(CC)
198DYNAMIC_CC = $(CROSS)$(CC) -fPIC
199TARGET_CC= $(STATIC_CC)
200TARGET_STCC= $(STATIC_CC)
201TARGET_DYNCC= $(DYNAMIC_CC)
202TARGET_LD= $(CROSS)$(CC)
203TARGET_AR= $(CROSS)ar rcus
204TARGET_STRIP= $(CROSS)strip
205
206TARGET_SONAME= libluajit-$(ABIVER).so.$(MAJVER)
207TARGET_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).dylib
208TARGET_DYLIBPATH= $(or $(PREFIX),/usr/local)/lib/$(TARGET_DYLIBNAME)
209TARGET_DLLNAME= lua$(NODOTABIVER).dll
210TARGET_XSHLDFLAGS= -shared -fPIC -Wl,-soname,$(TARGET_SONAME)
211TARGET_DYNXLDOPTS=
212
213TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE
214TARGET_XLDFLAGS=
215TARGET_XLIBS= -lm
216TARGET_TCFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
217TARGET_ACFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_ARCH) $(TARGET_FLAGS) $(TARGET_CFLAGS)
218TARGET_ALDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) $(TARGET_FLAGS) $(TARGET_LDFLAGS)
219TARGET_ASHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS) $(TARGET_FLAGS) $(TARGET_SHLDFLAGS)
220TARGET_ALIBS= $(TARGET_XLIBS) $(LIBS) $(TARGET_LIBS)
221
222ifneq (,$(findstring stack-protector,$(shell $(TARGET_CC) -dumpspecs)))
223 TARGET_XCFLAGS+= -fno-stack-protector
224endif
225
226TARGET_TESTARCH=$(shell $(TARGET_CC) $(TARGET_TCFLAGS) -E lj_arch.h -dM)
227ifneq (,$(findstring LJ_TARGET_X64 ,$(TARGET_TESTARCH)))
228 TARGET_CCARCH= x64
229 TARGET_XCFLAGS+= $(CCOPT_X64)
230else
231ifneq (,$(findstring LJ_TARGET_X86 ,$(TARGET_TESTARCH)))
232 TARGET_CCARCH= x86
233 TARGET_XCFLAGS+= $(CCOPT_X86)
234else
235ifneq (,$(findstring LJ_TARGET_ARM ,$(TARGET_TESTARCH)))
236 TARGET_CCARCH= arm
237 TARGET_XCFLAGS+= $(CCOPT_ARM)
238else
239ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH)))
240 TARGET_CCARCH= ppc
241 TARGET_XCFLAGS+= $(CCOPT_PPC)
242else
243ifneq (,$(findstring LJ_TARGET_PPCSPE ,$(TARGET_TESTARCH)))
244 TARGET_CCARCH= ppcspe
245 TARGET_XCFLAGS+= $(CCOPT_PPCSPE)
246else
247ifneq (,$(findstring LJ_TARGET_MIPS ,$(TARGET_TESTARCH)))
248 ifneq (,$(findstring MIPSEL ,$(TARGET_TESTARCH)))
249 TARGET_ARCH= -D__MIPSEL__=1
250 endif
251 TARGET_CCARCH= mips
252 TARGET_XCFLAGS+= $(CCOPT_MIPS)
253else
254 $(error Unsupported target architecture)
255endif
256endif
257endif
258endif
259endif
260endif
261
262TARGET_ARCH+= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET_CCARCH))
263
264ifneq (,$(PREFIX))
265ifneq (/usr/local,$(PREFIX))
266 TARGET_XCFLAGS+= -DLUA_XROOT=\"$(PREFIX)/\"
267 ifneq (/usr,$(PREFIX))
268 TARGET_DYNXLDOPTS= -Wl,-rpath,$(PREFIX)/lib
269 endif
270endif
271endif
272
273##############################################################################
274# System detection.
275##############################################################################
276
277ifneq (,$(findstring Windows,$(OS)))
278 HOST_SYS= Windows
279else
280 HOST_SYS:= $(shell uname -s)
281 ifneq (,$(findstring CYGWIN,$(TARGET_SYS)))
282 HOST_SYS= Windows
283 endif
284endif
285ifeq (Windows,$(HOST_SYS))
286 HOST_RM= del
287endif
288
289TARGET_SYS= $(HOST_SYS)
290ifeq (Windows,$(TARGET_SYS))
291 TARGET_STRIP+= --strip-unneeded
292 TARGET_XSHLDFLAGS= -shared
293 TARGET_DYNXLDOPTS=
294else
295ifeq (Darwin,$(TARGET_SYS))
296 export MACOSX_DEPLOYMENT_TARGET=10.4
297 TARGET_STRIP+= -x
298 TARGET_AR+= 2>/dev/null
299 TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
300 TARGET_DYNXLDOPTS=
301 TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
302 ifeq (x64,$(TARGET_CCARCH))
303 TARGET_XLDFLAGS+= -pagezero_size 10000 -image_base 100000000
304 TARGET_XSHLDFLAGS+= -image_base 7fff04c4a000
305 endif
306else
307ifeq (iOS,$(TARGET_SYS))
308 TARGET_STRIP+= -x
309 TARGET_AR+= 2>/dev/null
310 TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
311 TARGET_DYNXLDOPTS=
312 TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
313else
314 ifneq (SunOS,$(TARGET_SYS))
315 TARGET_XLDFLAGS+= -Wl,-E
316 endif
317 ifeq (Linux,$(TARGET_SYS))
318 TARGET_XLIBS+= -ldl
319 endif
320 ifeq (GNU/kFreeBSD,$(TARGET_SYS))
321 TARGET_XLIBS+= -ldl
322 endif
323endif
324endif
325endif
326
327ifneq ($(HOST_SYS),$(TARGET_SYS))
328 ifeq (Windows,$(TARGET_SYS))
329 HOST_XCFLAGS+= -malign-double -DLUAJIT_OS=LUAJIT_OS_WINDOWS
330 else
331 ifeq (Linux,$(TARGET_SYS))
332 HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_LINUX
333 else
334 ifeq (Darwin,$(TARGET_SYS))
335 HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
336 else
337 ifeq (iOS,$(TARGET_SYS))
338 HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
339 else
340 HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OTHER
341 endif
342 endif
343 endif
344 endif
345endif
346
347ifneq (,$(CCDEBUG))
348 TARGET_STRIP= @:
349endif
350
351##############################################################################
352# Files and pathnames.
353##############################################################################
354
355DASM_DIR= ../dynasm
356DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua
357DASM_FLAGS=
358DASM_DISTFLAGS= -LN
359DASM_FLAGS_X86=
360DASM_FLAGS_X64= -D X64
361DASM_FLAGS_X64WIN= -D X64 -D X64WIN
362DASM_FLAGS_ARM=
363DASM_FLAGS_PPC=
364DASM_FLAGS_PPCSPE=
365DASM_FLAGS_MIPS=
366
367BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o
368BUILDVM_T= buildvm
369BUILDVM_X= ./$(BUILDVM_T)
370
371HOST_O= $(BUILDVM_O)
372HOST_T= $(BUILDVM_T)
373
374LJVM_S= lj_vm.s
375LJVM_O= lj_vm.o
376LJVM_BOUT= $(LJVM_S)
377LJVM_MODE= elfasm
378
379LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \
380 lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o
381LJLIB_C= $(LJLIB_O:.o=.c)
382
383LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \
384 lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \
385 lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_api.o \
386 lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o \
387 lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
388 lj_opt_dce.o lj_opt_loop.o lj_opt_split.o \
389 lj_mcode.o lj_snap.o lj_record.o lj_crecord.o lj_ffrecord.o \
390 lj_asm.o lj_trace.o lj_gdbjit.o \
391 lj_ctype.o lj_cdata.o lj_cconv.o lj_ccall.o lj_ccallback.o \
392 lj_carith.o lj_clib.o lj_cparse.o \
393 lj_lib.o lj_alloc.o lib_aux.o \
394 $(LJLIB_O) lib_init.o
395
396LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
397LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o)
398
399LIB_VMDEF= ../lib/vmdef.lua
400LIB_VMDEFP= $(LIB_VMDEF)
401
402LUAJIT_O= luajit.o
403LUAJIT_A= libluajit.a
404LUAJIT_SO= libluajit.so
405LUAJIT_T= luajit
406
407ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(BUILDVM_T)
408ALL_HDRGEN= lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h
409ALL_GEN= $(LJVM_S) $(ALL_HDRGEN) $(LIB_VMDEFP)
410ALL_DYNGEN= buildvm_x86.h buildvm_x64.h buildvm_x64win.h buildvm_arm.h \
411 buildvm_ppc.h buildvm_ppcspe.h
412###ALL_DYNGEN+= buildvm_mips.h
413WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
414ALL_RM= $(ALL_T) $(ALL_GEN) *.o $(WIN_RM)
415
416##############################################################################
417# Build mode handling.
418##############################################################################
419
420# Mixed mode defaults.
421TARGET_O= $(LUAJIT_A)
422TARGET_T= $(LUAJIT_T) $(LUAJIT_SO)
423TARGET_DEP= $(LIB_VMDEF) $(LUAJIT_SO)
424
425ifeq (Windows,$(HOST_SYS))
426 BUILDVM_T= buildvm.exe
427 LIB_VMDEFP= $(subst /,\\,$(LIB_VMDEF))
428endif
429ifeq (Windows,$(TARGET_SYS))
430 TARGET_DYNCC= $(STATIC_CC)
431 LJVM_MODE= coffasm
432 LUAJIT_SO= $(TARGET_DLLNAME)
433 LUAJIT_T= luajit.exe
434 # Mixed mode is not supported on Windows. And static mode doesn't work well.
435 # C modules cannot be loaded, because they bind to lua51.dll.
436 ifneq (static,$(BUILDMODE))
437 BUILDMODE= dynamic
438 TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL
439 endif
440endif
441ifeq (Darwin,$(TARGET_SYS))
442 LJVM_MODE= machasm
443endif
444ifeq (iOS,$(TARGET_SYS))
445 LJVM_MODE= machasm
446endif
447ifeq (SunOS,$(TARGET_SYS))
448 BUILDMODE= static
449endif
450
451ifeq (static,$(BUILDMODE))
452 TARGET_DYNCC= @:
453 TARGET_T= $(LUAJIT_T)
454 TARGET_DEP= $(LIB_VMDEF)
455else
456ifeq (dynamic,$(BUILDMODE))
457 ifneq (Windows,$(TARGET_SYS))
458 TARGET_CC= $(DYNAMIC_CC)
459 endif
460 TARGET_DYNCC= @:
461 LJVMCORE_DYNO= $(LJVMCORE_O)
462 TARGET_O= $(LUAJIT_SO)
463 TARGET_XLDFLAGS+= $(TARGET_DYNXLDOPTS)
464else
465ifeq (Darwin,$(TARGET_SYS))
466 TARGET_DYNCC= @:
467 LJVMCORE_DYNO= $(LJVMCORE_O)
468endif
469ifeq (iOS,$(TARGET_SYS))
470 TARGET_DYNCC= @:
471 LJVMCORE_DYNO= $(LJVMCORE_O)
472endif
473endif
474endif
475
476Q= @
477E= @echo
478#Q=
479#E= @:
480
481##############################################################################
482# Make targets.
483##############################################################################
484
485default all: $(TARGET_T)
486
487amalg:
488 @grep "^[+|]" ljamalg.c
489 $(MAKE) all "LJCORE_O=ljamalg.o"
490
491clean:
492 $(HOST_RM) $(ALL_RM)
493
494cleaner:
495 $(HOST_RM) $(ALL_RM) $(ALL_DYNGEN)
496
497distclean: clean
498 $(E) "DYNASM $@"
499 $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_X86) -o buildvm_x86.h buildvm_x86.dasc
500 $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_X64) -o buildvm_x64.h buildvm_x86.dasc
501 $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_X64WIN) -o buildvm_x64win.h buildvm_x86.dasc
502 $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_ARM) -o buildvm_arm.h buildvm_arm.dasc
503 $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_PPC) -o buildvm_ppc.h buildvm_ppc.dasc
504 $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_PPCSPE) -o buildvm_ppcspe.h buildvm_ppcspe.dasc
505 @### $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_MIPS) -o buildvm_mips.h buildvm_mips.dasc
506
507depend:
508 @for file in $(ALL_HDRGEN) $(ALL_DYNGEN); do \
509 test -f $$file || touch $$file; \
510 done
511 @$(HOST_CC) $(HOST_ACFLAGS) -MM *.c | \
512 sed -e "s| [^ ]*/dasm_\S*\.h||g" \
513 -e "s| buildvm_\S*\.h||g" \
514 -e "s| lj_target_\S*\.h| lj_target_*.h|g" \
515 -e "s| lj_emit_\S*\.h| lj_emit_*.h|g" \
516 -e "s| lj_asm_\S*\.h| lj_asm_*.h|g" >Makefile.dep
517 @for file in $(ALL_HDRGEN) $(ALL_DYNGEN); do \
518 test -s $$file || $(HOST_RM) $$file; \
519 done
520
521.PHONY: default all amalg clean cleaner distclean depend
522
523##############################################################################
524# Rules for generated files.
525##############################################################################
526
527buildvm_x86.h: buildvm_x86.dasc
528 $(E) "DYNASM $@"
529 $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_X86) -o $@ buildvm_x86.dasc
530
531buildvm_x64.h: buildvm_x86.dasc
532 $(E) "DYNASM $@"
533 $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_X64) -o $@ buildvm_x86.dasc
534
535buildvm_x64win.h: buildvm_x86.dasc
536 $(E) "DYNASM $@"
537 $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_X64WIN) -o $@ buildvm_x86.dasc
538
539buildvm_arm.h: buildvm_arm.dasc
540 $(E) "DYNASM $@"
541 $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_ARM) -o $@ buildvm_arm.dasc
542
543buildvm_ppc.h: buildvm_ppc.dasc
544 $(E) "DYNASM $@"
545 $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_PPC) -o $@ buildvm_ppc.dasc
546
547buildvm_ppcspe.h: buildvm_ppcspe.dasc
548 $(E) "DYNASM $@"
549 $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_PPCSPE) -o $@ buildvm_ppcspe.dasc
550
551buildvm_mips.h: buildvm_mips.dasc
552 $(E) "DYNASM $@"
553 $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_MIPS) -o $@ buildvm_mips.dasc
554
555buildvm.o: $(ALL_DYNGEN) $(DASM_DIR)/dasm_*.h
556
557$(BUILDVM_T): $(BUILDVM_O)
558 $(E) "HOSTLINK $@"
559 $(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(BUILDVM_O) $(HOST_ALIBS)
560
561$(LJVM_BOUT): $(BUILDVM_T)
562 $(E) "BUILDVM $@"
563 $(Q)$(BUILDVM_X) -m $(LJVM_MODE) -o $@
564
565lj_bcdef.h: $(BUILDVM_T) $(LJLIB_C)
566 $(E) "BUILDVM $@"
567 $(Q)$(BUILDVM_X) -m bcdef -o $@ $(LJLIB_C)
568
569lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
570 $(E) "BUILDVM $@"
571 $(Q)$(BUILDVM_X) -m ffdef -o $@ $(LJLIB_C)
572
573lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
574 $(E) "BUILDVM $@"
575 $(Q)$(BUILDVM_X) -m libdef -o $@ $(LJLIB_C)
576
577lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
578 $(E) "BUILDVM $@"
579 $(Q)$(BUILDVM_X) -m recdef -o $@ $(LJLIB_C)
580
581$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
582 $(E) "BUILDVM $@"
583 $(Q)$(BUILDVM_X) -m vmdef -o $(LIB_VMDEFP) $(LJLIB_C)
584
585lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
586 $(E) "BUILDVM $@"
587 $(Q)$(BUILDVM_X) -m folddef -o $@ lj_opt_fold.c
588
589##############################################################################
590# Object file rules.
591##############################################################################
592
593%.o: %.c
594 $(E) "CC $@"
595 $(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $<
596 $(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
597
598%.o: %.s
599 $(E) "ASM $@"
600 $(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $<
601 $(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
602
603$(LUAJIT_O):
604 $(E) "CC $@"
605 $(Q)$(TARGET_STCC) $(TARGET_ACFLAGS) -c -o $@ $<
606
607$(HOST_O): %.o: %.c
608 $(E) "HOSTCC $@"
609 $(Q)$(HOST_CC) $(HOST_ACFLAGS) -c -o $@ $<
610
611include Makefile.dep
612
613##############################################################################
614# Target file rules.
615##############################################################################
616
617$(LUAJIT_A): $(LJVMCORE_O)
618 $(E) "AR $@"
619 $(Q)$(TARGET_AR) $@ $(LJVMCORE_O)
620
621# The dependency on _O, but linking with _DYNO is intentional.
622$(LUAJIT_SO): $(LJVMCORE_O)
623 $(E) "DYNLINK $@"
624 $(Q)$(TARGET_LD) $(TARGET_ASHLDFLAGS) -o $@ $(LJVMCORE_DYNO) $(TARGET_ALIBS)
625 $(Q)$(TARGET_STRIP) $@
626
627$(LUAJIT_T): $(TARGET_O) $(LUAJIT_O) $(TARGET_DEP)
628 $(E) "LINK $@"
629 $(Q)$(TARGET_LD) $(TARGET_ALDFLAGS) -o $@ $(LUAJIT_O) $(TARGET_O) $(TARGET_ALIBS)
630 $(Q)$(TARGET_STRIP) $@
631 $(E) "OK Successfully built LuaJIT"
632
633##############################################################################
diff --git a/libraries/luajit-2.0/src/Makefile.dep b/libraries/luajit-2.0/src/Makefile.dep
new file mode 100644
index 0000000..add7508
--- /dev/null
+++ b/libraries/luajit-2.0/src/Makefile.dep
@@ -0,0 +1,207 @@
1buildvm.o: buildvm.c buildvm.h lj_def.h lua.h luaconf.h lj_arch.h \
2 lj_obj.h lj_gc.h lj_bc.h lj_ir.h lj_ircall.h lj_jit.h lj_frame.h \
3 lj_dispatch.h lj_ctype.h lj_ccall.h luajit.h \
4 lj_traceerr.h
5buildvm_asm.o: buildvm_asm.c buildvm.h lj_def.h lua.h luaconf.h lj_arch.h \
6 lj_bc.h
7buildvm_fold.o: buildvm_fold.c buildvm.h lj_def.h lua.h luaconf.h \
8 lj_arch.h lj_obj.h lj_ir.h
9buildvm_lib.o: buildvm_lib.c buildvm.h lj_def.h lua.h luaconf.h lj_arch.h \
10 lj_obj.h lj_lib.h
11buildvm_peobj.o: buildvm_peobj.c buildvm.h lj_def.h lua.h luaconf.h \
12 lj_arch.h lj_bc.h
13lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
14 lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_lib.h lj_alloc.h
15lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
16 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
17 lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
18 lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_lib.h lj_libdef.h
19lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
20 lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h lj_libdef.h
21lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
22 lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_libdef.h
23lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
24 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h \
25 lj_ctype.h lj_cparse.h lj_cdata.h lj_cconv.h lj_carith.h lj_ccall.h \
26 lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
27lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
28lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
29 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ff.h lj_ffdef.h \
30 lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h \
31 lj_libdef.h
32lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
33 lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
34 lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \
35 lj_target_*.h lj_dispatch.h lj_vm.h lj_vmevent.h lj_lib.h luajit.h \
36 lj_libdef.h
37lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
38 lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h
39lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
40 lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_libdef.h
41lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
42 lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
43lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
44 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \
45 lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h lj_char.h lj_lib.h \
46 lj_libdef.h
47lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
48 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
49 lj_libdef.h
50lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h
51lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
52 lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
53 lj_meta.h lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h \
54 lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
55lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
56 lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h \
57 lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \
58 lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h lj_emit_*.h \
59 lj_asm_*.h
60lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
61 lj_bcdef.h
62lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
63 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_bc.h lj_ctype.h \
64 lj_cdata.h lj_lex.h lj_bcdump.h lj_state.h
65lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
66 lj_gc.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h lj_ir.h \
67 lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
68lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
69 lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \
70 lj_cdata.h lj_carith.h
71lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
72 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
73 lj_cdata.h lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
74 lj_traceerr.h
75lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \
76 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_state.h lj_frame.h \
77 lj_bc.h lj_ctype.h lj_cconv.h lj_ccall.h lj_ccallback.h lj_target.h \
78 lj_target_*.h lj_mcode.h lj_jit.h lj_ir.h lj_vm.h
79lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
80 lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \
81 lj_ccallback.h
82lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
83 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
84 lj_cdata.h
85lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
86lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
87 lj_err.h lj_errmsg.h lj_tab.h lj_str.h lj_udata.h lj_ctype.h lj_cconv.h \
88 lj_cdata.h lj_clib.h
89lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
90 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cparse.h lj_frame.h \
91 lj_bc.h lj_vm.h lj_char.h
92lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
93 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h \
94 lj_gc.h lj_cdata.h lj_cparse.h lj_cconv.h lj_clib.h lj_ccall.h lj_ir.h \
95 lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \
96 lj_record.h lj_ffrecord.h lj_snap.h lj_crecord.h
97lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
98 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h
99lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
100 lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_state.h lj_frame.h \
101 lj_bc.h lj_jit.h lj_ir.h
102lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
103 lj_err.h lj_errmsg.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h \
104 lj_ffdef.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h lj_traceerr.h \
105 lj_vm.h luajit.h
106lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
107 lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
108 lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
109 lj_traceerr.h lj_vm.h
110lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
111 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \
112 lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
113 lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \
114 lj_vm.h lj_recdef.h
115lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
116 lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
117 lj_traceerr.h lj_vm.h
118lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
119 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_udata.h lj_meta.h \
120 lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h \
121 lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
122lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
123 lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_jit.h \
124 lj_ir.h lj_dispatch.h
125lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
126 lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
127 lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \
128 lj_vm.h lj_lib.h
129lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
130 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h lualib.h \
131 lj_state.h lj_lex.h lj_parse.h lj_char.h
132lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
133 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
134 lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_lib.h
135lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
136 lj_gc.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h lj_dispatch.h lj_bc.h \
137 lj_traceerr.h lj_vm.h
138lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
139 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
140 lj_vm.h
141lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
142lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
143 lj_ir.h lj_jit.h lj_iropt.h
144lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
145 lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
146 lj_bc.h lj_traceerr.h lj_carith.h lj_vm.h lj_folddef.h
147lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
148 lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \
149 lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h lj_vm.h
150lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
151 lj_tab.h lj_ir.h lj_jit.h lj_iropt.h
152lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
153 lj_arch.h lj_str.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \
154 lj_dispatch.h lj_traceerr.h lj_vm.h
155lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
156 lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_ircall.h \
157 lj_iropt.h lj_vm.h
158lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
159 lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h \
160 lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_parse.h lj_vm.h lj_vmevent.h
161lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
162 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
163 lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
164 lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h
165lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
166 lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \
167 lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h lj_target_*.h
168lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
169 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_meta.h \
170 lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h lj_ir.h \
171 lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_alloc.h
172lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
173 lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_char.h
174lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
175 lj_err.h lj_errmsg.h lj_tab.h
176lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
177 lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
178 lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
179 lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
180 lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h
181lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
182 lj_gc.h lj_udata.h
183lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
184 lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \
185 lj_vm.h lj_vmevent.h
186lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
187 lj_ir.h lj_vm.h
188ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
189 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h \
190 lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h \
191 lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_err.c \
192 lj_debug.h lj_ff.h lj_ffdef.h lj_char.c lj_char.h lj_bc.c lj_bcdef.h \
193 lj_obj.c lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_debug.c \
194 lj_state.c lj_lex.h lj_alloc.h lj_dispatch.c luajit.h lj_vmevent.c \
195 lj_vmevent.h lj_vmmath.c lj_api.c lj_bcdump.h lj_parse.h lj_lex.c \
196 lualib.h lj_parse.c lj_bcread.c lj_bcwrite.c lj_ctype.c lj_ccallback.h \
197 lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c \
198 lj_target.h lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c \
199 lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_lib.h lj_ir.c lj_ircall.h \
200 lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c \
201 lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c lj_mcode.c lj_snap.c \
202 lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c lj_crecord.h \
203 lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h lj_asm_*.h \
204 lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c lib_base.c \
205 lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c lib_os.c \
206 lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c lib_init.c
207luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
diff --git a/libraries/luajit-2.0/src/buildvm.c b/libraries/luajit-2.0/src/buildvm.c
new file mode 100644
index 0000000..43e6d88
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm.c
@@ -0,0 +1,513 @@
1/*
2** LuaJIT VM builder.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** This is a tool to build the hand-tuned assembler code required for
6** LuaJIT's bytecode interpreter. It supports a variety of output formats
7** to feed different toolchains (see usage() below).
8**
9** This tool is not particularly optimized because it's only used while
10** _building_ LuaJIT. There's no point in distributing or installing it.
11** Only the object code generated by this tool is linked into LuaJIT.
12**
13** Caveat: some memory is not free'd, error handling is lazy.
14** It's a one-shot tool -- any effort fixing this would be wasted.
15*/
16
17#include "buildvm.h"
18#include "lj_obj.h"
19#include "lj_gc.h"
20#include "lj_bc.h"
21#include "lj_ir.h"
22#include "lj_ircall.h"
23#include "lj_frame.h"
24#include "lj_dispatch.h"
25#if LJ_HASFFI
26#include "lj_ctype.h"
27#include "lj_ccall.h"
28#endif
29#include "luajit.h"
30
31#if defined(_WIN32)
32#include <fcntl.h>
33#include <io.h>
34#endif
35
36/* ------------------------------------------------------------------------ */
37
38/* DynASM glue definitions. */
39#define Dst ctx
40#define Dst_DECL BuildCtx *ctx
41#define Dst_REF (ctx->D)
42#define DASM_CHECKS 1
43
44#include "../dynasm/dasm_proto.h"
45
46/* Glue macros for DynASM. */
47static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type);
48
49#define DASM_EXTERN(ctx, addr, idx, type) \
50 collect_reloc(ctx, addr, idx, type)
51
52/* ------------------------------------------------------------------------ */
53
54/* Avoid trouble if cross-compiling for an x86 target. Speed doesn't matter. */
55#define DASM_ALIGNED_WRITES 1
56
57/* Embed architecture-specific DynASM encoder and backend. */
58#if LJ_TARGET_X86
59#include "../dynasm/dasm_x86.h"
60#include "buildvm_x86.h"
61#elif LJ_TARGET_X64
62#include "../dynasm/dasm_x86.h"
63#if LJ_ABI_WIN
64#include "buildvm_x64win.h"
65#else
66#include "buildvm_x64.h"
67#endif
68#elif LJ_TARGET_ARM
69#include "../dynasm/dasm_arm.h"
70#include "buildvm_arm.h"
71#elif LJ_TARGET_PPC
72#include "../dynasm/dasm_ppc.h"
73#include "buildvm_ppc.h"
74#elif LJ_TARGET_PPCSPE
75#include "../dynasm/dasm_ppc.h"
76#include "buildvm_ppcspe.h"
77#elif LJ_TARGET_MIPS
78#include "../dynasm/dasm_mips.h"
79#include "buildvm_mips.h"
80#else
81#error "No support for this architecture (yet)"
82#endif
83
84/* ------------------------------------------------------------------------ */
85
86void owrite(BuildCtx *ctx, const void *ptr, size_t sz)
87{
88 if (fwrite(ptr, 1, sz, ctx->fp) != sz) {
89 fprintf(stderr, "Error: cannot write to output file: %s\n",
90 strerror(errno));
91 exit(1);
92 }
93}
94
95/* ------------------------------------------------------------------------ */
96
97/* Emit code as raw bytes. Only used for DynASM debugging. */
98static void emit_raw(BuildCtx *ctx)
99{
100 owrite(ctx, ctx->code, ctx->codesz);
101}
102
103/* -- Build machine code -------------------------------------------------- */
104
105static const char *sym_decorate(BuildCtx *ctx,
106 const char *prefix, const char *suffix)
107{
108 char name[256];
109 char *p;
110#if LJ_64
111 const char *symprefix = ctx->mode == BUILD_machasm ? "_" : "";
112#else
113 const char *symprefix = ctx->mode != BUILD_elfasm ? "_" : "";
114#endif
115 sprintf(name, "%s%s%s", symprefix, prefix, suffix);
116 p = strchr(name, '@');
117 if (p) {
118 if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj))
119 name[0] = '@';
120 else
121 *p = '\0';
122 }
123 p = (char *)malloc(strlen(name)+1); /* MSVC doesn't like strdup. */
124 strcpy(p, name);
125 return p;
126}
127
128#define NRELOCSYM (sizeof(extnames)/sizeof(extnames[0])-1)
129
130static int relocmap[NRELOCSYM];
131
132/* Collect external relocations. */
133static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type)
134{
135 if (ctx->nreloc >= BUILD_MAX_RELOC) {
136 fprintf(stderr, "Error: too many relocations, increase BUILD_MAX_RELOC.\n");
137 exit(1);
138 }
139 if (relocmap[idx] < 0) {
140 relocmap[idx] = ctx->nrelocsym;
141 ctx->relocsym[ctx->nrelocsym] = sym_decorate(ctx, "", extnames[idx]);
142 ctx->nrelocsym++;
143 }
144 ctx->reloc[ctx->nreloc].ofs = (int32_t)(addr - ctx->code);
145 ctx->reloc[ctx->nreloc].sym = relocmap[idx];
146 ctx->reloc[ctx->nreloc].type = type;
147 ctx->nreloc++;
148 return 0; /* Encode symbol offset of 0. */
149}
150
151/* Naive insertion sort. Performance doesn't matter here. */
152static void sym_insert(BuildCtx *ctx, int32_t ofs,
153 const char *prefix, const char *suffix)
154{
155 ptrdiff_t i = ctx->nsym++;
156 while (i > 0) {
157 if (ctx->sym[i-1].ofs <= ofs)
158 break;
159 ctx->sym[i] = ctx->sym[i-1];
160 i--;
161 }
162 ctx->sym[i].ofs = ofs;
163 ctx->sym[i].name = sym_decorate(ctx, prefix, suffix);
164}
165
166/* Build the machine code. */
167static int build_code(BuildCtx *ctx)
168{
169 int status;
170 int i;
171
172 /* Initialize DynASM structures. */
173 ctx->nglob = GLOB__MAX;
174 ctx->glob = (void **)malloc(ctx->nglob*sizeof(void *));
175 memset(ctx->glob, 0, ctx->nglob*sizeof(void *));
176 ctx->nreloc = 0;
177
178 ctx->globnames = globnames;
179 ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *));
180 ctx->nrelocsym = 0;
181 for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1;
182
183 ctx->dasm_ident = DASM_IDENT;
184 ctx->dasm_arch = DASM_ARCH;
185
186 dasm_init(Dst, DASM_MAXSECTION);
187 dasm_setupglobal(Dst, ctx->glob, ctx->nglob);
188 dasm_setup(Dst, build_actionlist);
189
190 /* Call arch-specific backend to emit the code. */
191 ctx->npc = build_backend(ctx);
192
193 /* Finalize the code. */
194 (void)dasm_checkstep(Dst, -1);
195 if ((status = dasm_link(Dst, &ctx->codesz))) return status;
196 ctx->code = (uint8_t *)malloc(ctx->codesz);
197 if ((status = dasm_encode(Dst, (void *)ctx->code))) return status;
198
199 /* Allocate symbol table and bytecode offsets. */
200 ctx->beginsym = sym_decorate(ctx, "", LABEL_PREFIX "vm_asm_begin");
201 ctx->sym = (BuildSym *)malloc((ctx->npc+ctx->nglob+1)*sizeof(BuildSym));
202 ctx->nsym = 0;
203 ctx->bc_ofs = (int32_t *)malloc(ctx->npc*sizeof(int32_t));
204
205 /* Collect the opcodes (PC labels). */
206 for (i = 0; i < ctx->npc; i++) {
207 int32_t ofs = dasm_getpclabel(Dst, i);
208 if (ofs < 0) return 0x22000000|i;
209 ctx->bc_ofs[i] = ofs;
210 if ((LJ_HASJIT ||
211 !(i == BC_JFORI || i == BC_JFORL || i == BC_JITERL || i == BC_JLOOP ||
212 i == BC_IFORL || i == BC_IITERL || i == BC_ILOOP)) &&
213 (LJ_HASFFI || i != BC_KCDATA))
214 sym_insert(ctx, ofs, LABEL_PREFIX_BC, bc_names[i]);
215 }
216
217 /* Collect the globals (named labels). */
218 for (i = 0; i < ctx->nglob; i++) {
219 const char *gl = globnames[i];
220 int len = (int)strlen(gl);
221 if (!ctx->glob[i]) {
222 fprintf(stderr, "Error: undefined global %s\n", gl);
223 exit(2);
224 }
225 /* Skip the _Z symbols. */
226 if (!(len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z'))
227 sym_insert(ctx, (int32_t)((uint8_t *)(ctx->glob[i]) - ctx->code),
228 LABEL_PREFIX, globnames[i]);
229 }
230
231 /* Close the address range. */
232 sym_insert(ctx, (int32_t)ctx->codesz, "", "");
233 ctx->nsym--;
234
235 dasm_free(Dst);
236
237 return 0;
238}
239
240/* -- Generate VM enums --------------------------------------------------- */
241
242const char *const bc_names[] = {
243#define BCNAME(name, ma, mb, mc, mt) #name,
244BCDEF(BCNAME)
245#undef BCNAME
246 NULL
247};
248
249const char *const ir_names[] = {
250#define IRNAME(name, m, m1, m2) #name,
251IRDEF(IRNAME)
252#undef IRNAME
253 NULL
254};
255
256const char *const irt_names[] = {
257#define IRTNAME(name) #name,
258IRTDEF(IRTNAME)
259#undef IRTNAME
260 NULL
261};
262
263const char *const irfpm_names[] = {
264#define FPMNAME(name) #name,
265IRFPMDEF(FPMNAME)
266#undef FPMNAME
267 NULL
268};
269
270const char *const irfield_names[] = {
271#define FLNAME(name, ofs) #name,
272IRFLDEF(FLNAME)
273#undef FLNAME
274 NULL
275};
276
277const char *const ircall_names[] = {
278#define IRCALLNAME(cond, name, nargs, kind, type, flags) #name,
279IRCALLDEF(IRCALLNAME)
280#undef IRCALLNAME
281 NULL
282};
283
284static const char *const trace_errors[] = {
285#define TREDEF(name, msg) msg,
286#include "lj_traceerr.h"
287 NULL
288};
289
290static const char *lower(char *buf, const char *s)
291{
292 char *p = buf;
293 while (*s) {
294 *p++ = (*s >= 'A' && *s <= 'Z') ? *s+0x20 : *s;
295 s++;
296 }
297 *p = '\0';
298 return buf;
299}
300
301/* Emit C source code for bytecode-related definitions. */
302static void emit_bcdef(BuildCtx *ctx)
303{
304 int i;
305 fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n");
306 fprintf(ctx->fp, "LJ_DATADEF const uint16_t lj_bc_ofs[] = {\n");
307 for (i = 0; i < ctx->npc; i++) {
308 if (i != 0)
309 fprintf(ctx->fp, ",\n");
310 fprintf(ctx->fp, "%d", ctx->bc_ofs[i]);
311 }
312}
313
314/* Emit VM definitions as Lua code for debug modules. */
315static void emit_vmdef(BuildCtx *ctx)
316{
317 char buf[80];
318 int i;
319 fprintf(ctx->fp, "-- This is a generated file. DO NOT EDIT!\n\n");
320 fprintf(ctx->fp, "module(...)\n\n");
321
322 fprintf(ctx->fp, "bcnames = \"");
323 for (i = 0; bc_names[i]; i++) fprintf(ctx->fp, "%-6s", bc_names[i]);
324 fprintf(ctx->fp, "\"\n\n");
325
326 fprintf(ctx->fp, "irnames = \"");
327 for (i = 0; ir_names[i]; i++) fprintf(ctx->fp, "%-6s", ir_names[i]);
328 fprintf(ctx->fp, "\"\n\n");
329
330 fprintf(ctx->fp, "irfpm = { [0]=");
331 for (i = 0; irfpm_names[i]; i++)
332 fprintf(ctx->fp, "\"%s\", ", lower(buf, irfpm_names[i]));
333 fprintf(ctx->fp, "}\n\n");
334
335 fprintf(ctx->fp, "irfield = { [0]=");
336 for (i = 0; irfield_names[i]; i++) {
337 char *p;
338 lower(buf, irfield_names[i]);
339 p = strchr(buf, '_');
340 if (p) *p = '.';
341 fprintf(ctx->fp, "\"%s\", ", buf);
342 }
343 fprintf(ctx->fp, "}\n\n");
344
345 fprintf(ctx->fp, "ircall = {\n[0]=");
346 for (i = 0; ircall_names[i]; i++)
347 fprintf(ctx->fp, "\"%s\",\n", ircall_names[i]);
348 fprintf(ctx->fp, "}\n\n");
349
350 fprintf(ctx->fp, "traceerr = {\n[0]=");
351 for (i = 0; trace_errors[i]; i++)
352 fprintf(ctx->fp, "\"%s\",\n", trace_errors[i]);
353 fprintf(ctx->fp, "}\n\n");
354}
355
356/* -- Argument parsing ---------------------------------------------------- */
357
358/* Build mode names. */
359static const char *const modenames[] = {
360#define BUILDNAME(name) #name,
361BUILDDEF(BUILDNAME)
362#undef BUILDNAME
363 NULL
364};
365
366/* Print usage information and exit. */
367static void usage(void)
368{
369 int i;
370 fprintf(stderr, LUAJIT_VERSION " VM builder.\n");
371 fprintf(stderr, LUAJIT_COPYRIGHT ", " LUAJIT_URL "\n");
372 fprintf(stderr, "Target architecture: " LJ_ARCH_NAME "\n\n");
373 fprintf(stderr, "Usage: buildvm -m mode [-o outfile] [infiles...]\n\n");
374 fprintf(stderr, "Available modes:\n");
375 for (i = 0; i < BUILD__MAX; i++)
376 fprintf(stderr, " %s\n", modenames[i]);
377 exit(1);
378}
379
380/* Parse the output mode name. */
381static BuildMode parsemode(const char *mode)
382{
383 int i;
384 for (i = 0; modenames[i]; i++)
385 if (!strcmp(mode, modenames[i]))
386 return (BuildMode)i;
387 usage();
388 return (BuildMode)-1;
389}
390
391/* Parse arguments. */
392static void parseargs(BuildCtx *ctx, char **argv)
393{
394 const char *a;
395 int i;
396 ctx->mode = (BuildMode)-1;
397 ctx->outname = "-";
398 for (i = 1; (a = argv[i]) != NULL; i++) {
399 if (a[0] != '-')
400 break;
401 switch (a[1]) {
402 case '-':
403 if (a[2]) goto err;
404 i++;
405 goto ok;
406 case '\0':
407 goto ok;
408 case 'm':
409 i++;
410 if (a[2] || argv[i] == NULL) goto err;
411 ctx->mode = parsemode(argv[i]);
412 break;
413 case 'o':
414 i++;
415 if (a[2] || argv[i] == NULL) goto err;
416 ctx->outname = argv[i];
417 break;
418 default: err:
419 usage();
420 break;
421 }
422 }
423ok:
424 ctx->args = argv+i;
425 if (ctx->mode == (BuildMode)-1) goto err;
426}
427
428int main(int argc, char **argv)
429{
430 BuildCtx ctx_;
431 BuildCtx *ctx = &ctx_;
432 int status, binmode;
433
434 if (sizeof(void *) != 4*LJ_32+8*LJ_64) {
435 fprintf(stderr,"Error: pointer size mismatch in cross-build.\n");
436 fprintf(stderr,"Try: make HOST_CC=\"gcc -m32\" CROSS=... TARGET=...\n\n");
437 return 1;
438 }
439
440 UNUSED(argc);
441 parseargs(ctx, argv);
442
443 if ((status = build_code(ctx))) {
444 fprintf(stderr,"Error: DASM error %08x\n", status);
445 return 1;
446 }
447
448 switch (ctx->mode) {
449 case BUILD_peobj:
450 case BUILD_raw:
451 binmode = 1;
452 break;
453 default:
454 binmode = 0;
455 break;
456 }
457
458 if (ctx->outname[0] == '-' && ctx->outname[1] == '\0') {
459 ctx->fp = stdout;
460#if defined(_WIN32)
461 if (binmode)
462 _setmode(_fileno(stdout), _O_BINARY); /* Yuck. */
463#endif
464 } else if (!(ctx->fp = fopen(ctx->outname, binmode ? "wb" : "w"))) {
465 fprintf(stderr, "Error: cannot open output file '%s': %s\n",
466 ctx->outname, strerror(errno));
467 exit(1);
468 }
469
470 switch (ctx->mode) {
471 case BUILD_elfasm:
472 case BUILD_coffasm:
473 case BUILD_machasm:
474 emit_asm(ctx);
475 emit_asm_debug(ctx);
476 break;
477 case BUILD_peobj:
478 emit_peobj(ctx);
479 break;
480 case BUILD_raw:
481 emit_raw(ctx);
482 break;
483 case BUILD_bcdef:
484 emit_bcdef(ctx);
485 emit_lib(ctx);
486 break;
487 case BUILD_vmdef:
488 emit_vmdef(ctx);
489 emit_lib(ctx);
490 break;
491 case BUILD_ffdef:
492 case BUILD_libdef:
493 case BUILD_recdef:
494 emit_lib(ctx);
495 break;
496 case BUILD_folddef:
497 emit_fold(ctx);
498 break;
499 default:
500 break;
501 }
502
503 fflush(ctx->fp);
504 if (ferror(ctx->fp)) {
505 fprintf(stderr, "Error: cannot write to output file: %s\n",
506 strerror(errno));
507 exit(1);
508 }
509 fclose(ctx->fp);
510
511 return 0;
512}
513
diff --git a/libraries/luajit-2.0/src/buildvm.h b/libraries/luajit-2.0/src/buildvm.h
new file mode 100644
index 0000000..a24d945
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm.h
@@ -0,0 +1,104 @@
1/*
2** LuaJIT VM builder.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _BUILDVM_H
7#define _BUILDVM_H
8
9#include <sys/types.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <errno.h>
14
15#include "lj_def.h"
16#include "lj_arch.h"
17
18/* Hardcoded limits. Increase as needed. */
19#define BUILD_MAX_RELOC 200 /* Max. number of relocations. */
20#define BUILD_MAX_FOLD 4096 /* Max. number of fold rules. */
21
22/* Prefix for scanned library definitions. */
23#define LIBDEF_PREFIX "LJLIB_"
24
25/* Prefix for scanned fold definitions. */
26#define FOLDDEF_PREFIX "LJFOLD"
27
28/* Prefixes for generated labels. */
29#define LABEL_PREFIX "lj_"
30#define LABEL_PREFIX_BC LABEL_PREFIX "BC_"
31#define LABEL_PREFIX_FF LABEL_PREFIX "ff_"
32#define LABEL_PREFIX_CF LABEL_PREFIX "cf_"
33#define LABEL_PREFIX_FFH LABEL_PREFIX "ffh_"
34#define LABEL_PREFIX_LIBCF LABEL_PREFIX "lib_cf_"
35#define LABEL_PREFIX_LIBINIT LABEL_PREFIX "lib_init_"
36
37/* Forward declaration. */
38struct dasm_State;
39
40/* Build modes. */
41#define BUILDDEF(_) \
42 _(elfasm) _(coffasm) _(machasm) _(peobj) _(raw) \
43 _(bcdef) _(ffdef) _(libdef) _(recdef) _(vmdef) \
44 _(folddef)
45
46typedef enum {
47#define BUILDENUM(name) BUILD_##name,
48BUILDDEF(BUILDENUM)
49#undef BUILDENUM
50 BUILD__MAX
51} BuildMode;
52
53/* Code relocation. */
54typedef struct BuildReloc {
55 int32_t ofs;
56 int sym;
57 int type;
58} BuildReloc;
59
60typedef struct BuildSym {
61 const char *name;
62 int32_t ofs;
63} BuildSym;
64
65/* Build context structure. */
66typedef struct BuildCtx {
67 /* DynASM state pointer. Should be first member. */
68 struct dasm_State *D;
69 /* Parsed command line. */
70 BuildMode mode;
71 FILE *fp;
72 const char *outname;
73 char **args;
74 /* Code and symbols generated by DynASM. */
75 uint8_t *code;
76 size_t codesz;
77 int npc, nglob, nsym, nreloc, nrelocsym;
78 void **glob;
79 BuildSym *sym;
80 const char **relocsym;
81 int32_t *bc_ofs;
82 const char *beginsym;
83 /* Strings generated by DynASM. */
84 const char *const *globnames;
85 const char *dasm_ident;
86 const char *dasm_arch;
87 /* Relocations. */
88 BuildReloc reloc[BUILD_MAX_RELOC];
89} BuildCtx;
90
91extern void owrite(BuildCtx *ctx, const void *ptr, size_t sz);
92extern void emit_asm(BuildCtx *ctx);
93extern void emit_peobj(BuildCtx *ctx);
94extern void emit_lib(BuildCtx *ctx);
95extern void emit_fold(BuildCtx *ctx);
96
97extern const char *const bc_names[];
98extern const char *const ir_names[];
99extern const char *const irt_names[];
100extern const char *const irfpm_names[];
101extern const char *const irfield_names[];
102extern const char *const ircall_names[];
103
104#endif
diff --git a/libraries/luajit-2.0/src/buildvm_arm.dasc b/libraries/luajit-2.0/src/buildvm_arm.dasc
new file mode 100644
index 0000000..60857c0
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_arm.dasc
@@ -0,0 +1,4115 @@
1|// Low-level VM code for ARM CPUs.
2|// Bytecode interpreter, fast functions and helper functions.
3|// Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4|
5|.arch arm
6|.section code_op, code_sub
7|
8|.actionlist build_actionlist
9|.globals GLOB_
10|.globalnames globnames
11|.externnames extnames
12|
13|// Note: The ragged indentation of the instructions is intentional.
14|// The starting columns indicate data dependencies.
15|
16|//-----------------------------------------------------------------------
17|
18|// Fixed register assignments for the interpreter.
19|
20|// The following must be C callee-save.
21|.define MASKR8, r4 // 255*8 constant for fast bytecode decoding.
22|.define KBASE, r5 // Constants of current Lua function.
23|.define PC, r6 // Next PC.
24|.define DISPATCH, r7 // Opcode dispatch table.
25|.define LREG, r8 // Register holding lua_State (also in SAVE_L).
26|
27|// C callee-save in EABI, but often refetched. Temporary in iOS 3.0+.
28|.define BASE, r9 // Base of current Lua stack frame.
29|
30|// The following temporaries are not saved across C calls, except for RA/RC.
31|.define RA, r10 // Callee-save.
32|.define RC, r11 // Callee-save.
33|.define RB, r12
34|.define OP, r12 // Overlaps RB, must not be lr.
35|.define INS, lr
36|
37|// Calling conventions. Also used as temporaries.
38|.define CARG1, r0
39|.define CARG2, r1
40|.define CARG3, r2
41|.define CARG4, r3
42|.define CARG12, r0 // For 1st soft-fp double.
43|.define CARG34, r2 // For 2nd soft-fp double.
44|
45|.define CRET1, r0
46|.define CRET2, r1
47|
48|// Stack layout while in interpreter. Must match with lj_frame.h.
49|.define CFRAME_SPACE, #28
50|.define SAVE_ERRF, [sp, #24]
51|.define SAVE_NRES, [sp, #20]
52|.define SAVE_CFRAME, [sp, #16]
53|.define SAVE_L, [sp, #12]
54|.define SAVE_PC, [sp, #8]
55|.define SAVE_MULTRES, [sp, #4]
56|.define ARG5, [sp]
57|
58|.define TMPDhi, [sp, #4]
59|.define TMPDlo, [sp]
60|.define TMPD, [sp]
61|.define TMPDp, sp
62|
63|.macro saveregs
64| push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
65| sub sp, sp, CFRAME_SPACE
66|.endmacro
67|.macro restoreregs_ret
68| add sp, sp, CFRAME_SPACE
69| pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
70|.endmacro
71|
72|// Type definitions. Some of these are only used for documentation.
73|.type L, lua_State, LREG
74|.type GL, global_State
75|.type TVALUE, TValue
76|.type GCOBJ, GCobj
77|.type STR, GCstr
78|.type TAB, GCtab
79|.type LFUNC, GCfuncL
80|.type CFUNC, GCfuncC
81|.type PROTO, GCproto
82|.type UPVAL, GCupval
83|.type NODE, Node
84|.type NARGS8, int
85|.type TRACE, GCtrace
86|
87|//-----------------------------------------------------------------------
88|
89|// Trap for not-yet-implemented parts.
90|.macro NYI; ud; .endmacro
91|
92|//-----------------------------------------------------------------------
93|
94|// Access to frame relative to BASE.
95|.define FRAME_FUNC, #-8
96|.define FRAME_PC, #-4
97|
98|.macro decode_RA8, dst, ins; and dst, MASKR8, ins, lsr #5; .endmacro
99|.macro decode_RB8, dst, ins; and dst, MASKR8, ins, lsr #21; .endmacro
100|.macro decode_RC8, dst, ins; and dst, MASKR8, ins, lsr #13; .endmacro
101|.macro decode_RD, dst, ins; lsr dst, ins, #16; .endmacro
102|.macro decode_OP, dst, ins; and dst, ins, #255; .endmacro
103|
104|// Instruction fetch.
105|.macro ins_NEXT1
106| ldrb OP, [PC]
107|.endmacro
108|.macro ins_NEXT2
109| ldr INS, [PC], #4
110|.endmacro
111|// Instruction decode+dispatch.
112|.macro ins_NEXT3
113| ldr OP, [DISPATCH, OP, lsl #2]
114| decode_RA8 RA, INS
115| decode_RD RC, INS
116| bx OP
117|.endmacro
118|.macro ins_NEXT
119| ins_NEXT1
120| ins_NEXT2
121| ins_NEXT3
122|.endmacro
123|
124|// Instruction footer.
125|.if 1
126| // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
127| .define ins_next, ins_NEXT
128| .define ins_next_, ins_NEXT
129| .define ins_next1, ins_NEXT1
130| .define ins_next2, ins_NEXT2
131| .define ins_next3, ins_NEXT3
132|.else
133| // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
134| // Affects only certain kinds of benchmarks (and only with -j off).
135| .macro ins_next
136| b ->ins_next
137| .endmacro
138| .macro ins_next1
139| .endmacro
140| .macro ins_next2
141| .endmacro
142| .macro ins_next3
143| b ->ins_next
144| .endmacro
145| .macro ins_next_
146| ->ins_next:
147| ins_NEXT
148| .endmacro
149|.endif
150|
151|// Avoid register name substitution for field name.
152#define field_pc pc
153|
154|// Call decode and dispatch.
155|.macro ins_callt
156| // BASE = new base, CARG3 = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
157| ldr PC, LFUNC:CARG3->field_pc
158| ldrb OP, [PC] // STALL: load PC. early PC.
159| ldr INS, [PC], #4
160| ldr OP, [DISPATCH, OP, lsl #2] // STALL: load OP. early OP.
161| decode_RA8 RA, INS
162| add RA, RA, BASE
163| bx OP
164|.endmacro
165|
166|.macro ins_call
167| // BASE = new base, CARG3 = LFUNC/CFUNC, RC = nargs*8, PC = caller PC
168| str PC, [BASE, FRAME_PC]
169| ins_callt // STALL: locked PC.
170|.endmacro
171|
172|//-----------------------------------------------------------------------
173|
174|// Macros to test operand types.
175|.macro checktp, reg, tp; cmn reg, #-tp; .endmacro
176|.macro checktpeq, reg, tp; cmneq reg, #-tp; .endmacro
177|.macro checktpne, reg, tp; cmnne reg, #-tp; .endmacro
178|.macro checkstr, reg, target; checktp reg, LJ_TSTR; bne target; .endmacro
179|.macro checktab, reg, target; checktp reg, LJ_TTAB; bne target; .endmacro
180|.macro checkfunc, reg, target; checktp reg, LJ_TFUNC; bne target; .endmacro
181|
182|// Assumes DISPATCH is relative to GL.
183#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
184#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
185|
186#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
187|
188|.macro hotcheck, delta
189| lsr CARG1, PC, #1
190| and CARG1, CARG1, #126
191| sub CARG1, CARG1, #-GG_DISP2HOT
192| ldrh CARG2, [DISPATCH, CARG1]
193| subs CARG2, CARG2, #delta
194| strh CARG2, [DISPATCH, CARG1]
195|.endmacro
196|
197|.macro hotloop
198| hotcheck HOTCOUNT_LOOP
199| blo ->vm_hotloop
200|.endmacro
201|
202|.macro hotcall
203| hotcheck HOTCOUNT_CALL
204| blo ->vm_hotcall
205|.endmacro
206|
207|// Set current VM state.
208|.macro mv_vmstate, reg, st; mvn reg, #LJ_VMST_..st; .endmacro
209|.macro st_vmstate, reg; str reg, [DISPATCH, #DISPATCH_GL(vmstate)]; .endmacro
210|
211|// Move table write barrier back. Overwrites mark and tmp.
212|.macro barrierback, tab, mark, tmp
213| ldr tmp, [DISPATCH, #DISPATCH_GL(gc.grayagain)]
214| bic mark, mark, #LJ_GC_BLACK // black2gray(tab)
215| str tab, [DISPATCH, #DISPATCH_GL(gc.grayagain)]
216| strb mark, tab->marked
217| str tmp, tab->gclist
218|.endmacro
219|
220|.macro IOS, a, b
221||if (LJ_TARGET_OSX) {
222| a, b
223||}
224|.endmacro
225|
226|//-----------------------------------------------------------------------
227
228#if !LJ_DUALNUM
229#error "Only dual-number mode supported for ARM target"
230#endif
231
232/* Generate subroutines used by opcodes and other parts of the VM. */
233/* The .code_sub section should be last to help static branch prediction. */
234static void build_subroutines(BuildCtx *ctx)
235{
236 |.code_sub
237 |
238 |//-----------------------------------------------------------------------
239 |//-- Return handling ----------------------------------------------------
240 |//-----------------------------------------------------------------------
241 |
242 |->vm_returnp:
243 | // See vm_return. Also: RB = previous base.
244 | tst PC, #FRAME_P
245 | beq ->cont_dispatch
246 |
247 | // Return from pcall or xpcall fast func.
248 | ldr PC, [RB, FRAME_PC] // Fetch PC of previous frame.
249 | mvn CARG2, #~LJ_TTRUE
250 | mov BASE, RB
251 | // Prepending may overwrite the pcall frame, so do it at the end.
252 | str CARG2, [RA, FRAME_PC] // Prepend true to results.
253 | sub RA, RA, #8
254 |
255 |->vm_returnc:
256 | add RC, RC, #8 // RC = (nresults+1)*8.
257 | ands CARG1, PC, #FRAME_TYPE
258 | str RC, SAVE_MULTRES
259 | beq ->BC_RET_Z // Handle regular return to Lua.
260 |
261 |->vm_return:
262 | // BASE = base, RA = resultptr, RC/MULTRES = (nresults+1)*8, PC = return
263 | // CARG1 = PC & FRAME_TYPE
264 | bic RB, PC, #FRAME_TYPEP
265 | cmp CARG1, #FRAME_C
266 | sub RB, BASE, RB // RB = previous base.
267 | bne ->vm_returnp
268 |
269 | str RB, L->base
270 | ldr KBASE, SAVE_NRES
271 | mv_vmstate CARG4, C
272 | sub BASE, BASE, #8
273 | subs CARG3, RC, #8
274 | lsl KBASE, KBASE, #3 // KBASE = (nresults_wanted+1)*8
275 | st_vmstate CARG4
276 | beq >2
277 |1:
278 | subs CARG3, CARG3, #8
279 | ldrd CARG12, [RA], #8
280 | strd CARG12, [BASE], #8
281 | bne <1
282 |2:
283 | cmp KBASE, RC // More/less results wanted?
284 | bne >6
285 |3:
286 | str BASE, L->top // Store new top.
287 |
288 |->vm_leave_cp:
289 | ldr RC, SAVE_CFRAME // Restore previous C frame.
290 | mov CRET1, #0 // Ok return status for vm_pcall.
291 | str RC, L->cframe
292 |
293 |->vm_leave_unw:
294 | restoreregs_ret
295 |
296 |6:
297 | blt >7 // Less results wanted?
298 | // More results wanted. Check stack size and fill up results with nil.
299 | ldr CARG3, L->maxstack
300 | mvn CARG2, #~LJ_TNIL
301 | cmp BASE, CARG3
302 | bhs >8
303 | str CARG2, [BASE, #4]
304 | add RC, RC, #8
305 | add BASE, BASE, #8
306 | b <2
307 |
308 |7: // Less results wanted.
309 | sub CARG1, RC, KBASE
310 | cmp KBASE, #0 // LUA_MULTRET+1 case?
311 | subne BASE, BASE, CARG1 // Either keep top or shrink it.
312 | b <3
313 |
314 |8: // Corner case: need to grow stack for filling up results.
315 | // This can happen if:
316 | // - A C function grows the stack (a lot).
317 | // - The GC shrinks the stack in between.
318 | // - A return back from a lua_call() with (high) nresults adjustment.
319 | str BASE, L->top // Save current top held in BASE (yes).
320 | mov CARG2, KBASE
321 | mov CARG1, L
322 | bl extern lj_state_growstack // (lua_State *L, int n)
323 | ldr BASE, L->top // Need the (realloced) L->top in BASE.
324 | b <2
325 |
326 |->vm_unwind_c: // Unwind C stack, return from vm_pcall.
327 | // (void *cframe, int errcode)
328 | mov sp, CARG1
329 | mov CRET1, CARG2
330 |->vm_unwind_c_eh: // Landing pad for external unwinder.
331 | ldr L, SAVE_L
332 | mv_vmstate CARG4, C
333 | ldr GL:CARG3, L->glref
334 | str CARG4, GL:CARG3->vmstate
335 | b ->vm_leave_unw
336 |
337 |->vm_unwind_ff: // Unwind C stack, return from ff pcall.
338 | // (void *cframe)
339 | bic CARG1, CARG1, #~CFRAME_RAWMASK // Use two steps: bic sp is deprecated.
340 | mov sp, CARG1
341 |->vm_unwind_ff_eh: // Landing pad for external unwinder.
342 | ldr L, SAVE_L
343 | mov MASKR8, #255
344 | mov RC, #16 // 2 results: false + error message.
345 | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
346 | ldr BASE, L->base
347 | ldr DISPATCH, L->glref // Setup pointer to dispatch table.
348 | mvn CARG1, #~LJ_TFALSE
349 | sub RA, BASE, #8 // Results start at BASE-8.
350 | ldr PC, [BASE, FRAME_PC] // Fetch PC of previous frame.
351 | add DISPATCH, DISPATCH, #GG_G2DISP
352 | mv_vmstate CARG2, INTERP
353 | str CARG1, [BASE, #-4] // Prepend false to error message.
354 | st_vmstate CARG2
355 | b ->vm_returnc
356 |
357 |//-----------------------------------------------------------------------
358 |//-- Grow stack for calls -----------------------------------------------
359 |//-----------------------------------------------------------------------
360 |
361 |->vm_growstack_c: // Grow stack for C function.
362 | // CARG1 = L
363 | mov CARG2, #LUA_MINSTACK
364 | b >2
365 |
366 |->vm_growstack_l: // Grow stack for Lua function.
367 | // BASE = new base, RA = BASE+framesize*8, RC = nargs*8, PC = first PC
368 | add RC, BASE, RC
369 | sub RA, RA, BASE
370 | mov CARG1, L
371 | str BASE, L->base
372 | add PC, PC, #4 // Must point after first instruction.
373 | str RC, L->top
374 | lsr CARG3, RA, #3
375 |2:
376 | // L->base = new base, L->top = top
377 | str PC, SAVE_PC
378 | bl extern lj_state_growstack // (lua_State *L, int n)
379 | ldr BASE, L->base
380 | ldr RC, L->top
381 | ldr LFUNC:CARG3, [BASE, FRAME_FUNC]
382 | sub NARGS8:RC, RC, BASE
383 | // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
384 | ins_callt // Just retry the call.
385 |
386 |//-----------------------------------------------------------------------
387 |//-- Entry points into the assembler VM ---------------------------------
388 |//-----------------------------------------------------------------------
389 |
390 |->vm_resume: // Setup C frame and resume thread.
391 | // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
392 | saveregs
393 | mov L, CARG1
394 | ldr DISPATCH, L:CARG1->glref // Setup pointer to dispatch table.
395 | mov BASE, CARG2
396 | add DISPATCH, DISPATCH, #GG_G2DISP
397 | str L, SAVE_L
398 | mov PC, #FRAME_CP
399 | str CARG3, SAVE_NRES
400 | add CARG2, sp, #CFRAME_RESUME
401 | ldrb CARG1, L->status
402 | str CARG3, SAVE_ERRF
403 | str CARG2, L->cframe
404 | str CARG3, SAVE_CFRAME
405 | cmp CARG1, #0
406 | str L, SAVE_PC // Any value outside of bytecode is ok.
407 | beq >3
408 |
409 | // Resume after yield (like a return).
410 | mov RA, BASE
411 | ldr BASE, L->base
412 | ldr CARG1, L->top
413 | mov MASKR8, #255
414 | strb CARG3, L->status
415 | sub RC, CARG1, BASE
416 | ldr PC, [BASE, FRAME_PC]
417 | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
418 | mv_vmstate CARG2, INTERP
419 | add RC, RC, #8
420 | ands CARG1, PC, #FRAME_TYPE
421 | st_vmstate CARG2
422 | str RC, SAVE_MULTRES
423 | beq ->BC_RET_Z
424 | b ->vm_return
425 |
426 |->vm_pcall: // Setup protected C frame and enter VM.
427 | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
428 | saveregs
429 | mov PC, #FRAME_CP
430 | str CARG4, SAVE_ERRF
431 | b >1
432 |
433 |->vm_call: // Setup C frame and enter VM.
434 | // (lua_State *L, TValue *base, int nres1)
435 | saveregs
436 | mov PC, #FRAME_C
437 |
438 |1: // Entry point for vm_pcall above (PC = ftype).
439 | ldr RC, L:CARG1->cframe
440 | str CARG3, SAVE_NRES
441 | mov L, CARG1
442 | str CARG1, SAVE_L
443 | mov BASE, CARG2
444 | str sp, L->cframe // Add our C frame to cframe chain.
445 | ldr DISPATCH, L->glref // Setup pointer to dispatch table.
446 | str CARG1, SAVE_PC // Any value outside of bytecode is ok.
447 | str RC, SAVE_CFRAME
448 | add DISPATCH, DISPATCH, #GG_G2DISP
449 |
450 |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
451 | ldr RB, L->base // RB = old base (for vmeta_call).
452 | ldr CARG1, L->top
453 | mov MASKR8, #255
454 | add PC, PC, BASE
455 | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
456 | sub PC, PC, RB // PC = frame delta + frame type
457 | mv_vmstate CARG2, INTERP
458 | sub NARGS8:RC, CARG1, BASE
459 | st_vmstate CARG2
460 |
461 |->vm_call_dispatch:
462 | // RB = old base, BASE = new base, RC = nargs*8, PC = caller PC
463 | ldrd CARG34, [BASE, FRAME_FUNC]
464 | checkfunc CARG4, ->vmeta_call
465 |
466 |->vm_call_dispatch_f:
467 | ins_call
468 | // BASE = new base, CARG3 = func, RC = nargs*8, PC = caller PC
469 |
470 |->vm_cpcall: // Setup protected C frame, call C.
471 | // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
472 | saveregs
473 | mov L, CARG1
474 | ldr RA, L:CARG1->stack
475 | str CARG1, SAVE_L
476 | ldr RB, L->top
477 | str CARG1, SAVE_PC // Any value outside of bytecode is ok.
478 | ldr RC, L->cframe
479 | sub RA, RA, RB // Compute -savestack(L, L->top).
480 | str sp, L->cframe // Add our C frame to cframe chain.
481 | mov RB, #0
482 | str RA, SAVE_NRES // Neg. delta means cframe w/o frame.
483 | str RB, SAVE_ERRF // No error function.
484 | str RC, SAVE_CFRAME
485 | blx CARG4 // (lua_State *L, lua_CFunction func, void *ud)
486 | ldr DISPATCH, L->glref // Setup pointer to dispatch table.
487 | movs BASE, CRET1
488 | mov PC, #FRAME_CP
489 | add DISPATCH, DISPATCH, #GG_G2DISP
490 | bne <3 // Else continue with the call.
491 | b ->vm_leave_cp // No base? Just remove C frame.
492 |
493 |//-----------------------------------------------------------------------
494 |//-- Metamethod handling ------------------------------------------------
495 |//-----------------------------------------------------------------------
496 |
497 |//-- Continuation dispatch ----------------------------------------------
498 |
499 |->cont_dispatch:
500 | // BASE = meta base, RA = resultptr, RC = (nresults+1)*8
501 | ldr LFUNC:CARG3, [RB, FRAME_FUNC]
502 | ldr CARG1, [BASE, #-16] // Get continuation.
503 | mov CARG4, BASE
504 | mov BASE, RB // Restore caller BASE.
505#if LJ_HASFFI
506 | cmp CARG1, #1
507#endif
508 | ldr PC, [CARG4, #-12] // Restore PC from [cont|PC].
509 | ldr CARG3, LFUNC:CARG3->field_pc
510 | mvn INS, #~LJ_TNIL
511 | add CARG2, RA, RC
512 | str INS, [CARG2, #-4] // Ensure one valid arg.
513#if LJ_HASFFI
514 | bls >1
515#endif
516 | ldr KBASE, [CARG3, #PC2PROTO(k)]
517 | // BASE = base, RA = resultptr, CARG4 = meta base
518 | bx CARG1
519 |
520#if LJ_HASFFI
521 |1:
522 | beq ->cont_ffi_callback // cont = 1: return from FFI callback.
523 | // cont = 0: tailcall from C function.
524 | ldr CARG3, [BASE, FRAME_FUNC]
525 | sub CARG4, CARG4, #16
526 | sub RC, CARG4, BASE
527 | b ->vm_call_tail
528#endif
529 |
530 |->cont_cat: // RA = resultptr, CARG4 = meta base
531 | ldr INS, [PC, #-4]
532 | sub CARG2, CARG4, #16
533 | ldrd CARG34, [RA]
534 | str BASE, L->base
535 | decode_RB8 RC, INS
536 | decode_RA8 RA, INS
537 | add CARG1, BASE, RC
538 | subs CARG1, CARG2, CARG1
539 | strdne CARG34, [CARG2]
540 | movne CARG3, CARG1
541 | bne ->BC_CAT_Z
542 | strd CARG34, [BASE, RA]
543 | b ->cont_nop
544 |
545 |//-- Table indexing metamethods -----------------------------------------
546 |
547 |->vmeta_tgets1:
548 | add CARG2, BASE, RB
549 | b >2
550 |
551 |->vmeta_tgets:
552 | sub CARG2, DISPATCH, #-DISPATCH_GL(tmptv)
553 | mvn CARG4, #~LJ_TTAB
554 | str TAB:RB, [CARG2]
555 | str CARG4, [CARG2, #4]
556 |2:
557 | mvn CARG4, #~LJ_TSTR
558 | str STR:RC, TMPDlo
559 | str CARG4, TMPDhi
560 | mov CARG3, TMPDp
561 | b >1
562 |
563 |->vmeta_tgetb: // RC = index
564 | decode_RB8 RB, INS
565 | str RC, TMPDlo
566 | mvn CARG4, #~LJ_TISNUM
567 | add CARG2, BASE, RB
568 | str CARG4, TMPDhi
569 | mov CARG3, TMPDp
570 | b >1
571 |
572 |->vmeta_tgetv:
573 | add CARG2, BASE, RB
574 | add CARG3, BASE, RC
575 |1:
576 | str BASE, L->base
577 | mov CARG1, L
578 | str PC, SAVE_PC
579 | bl extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
580 | // Returns TValue * (finished) or NULL (metamethod).
581 | IOS ldr BASE, L->base
582 | cmp CRET1, #0
583 | beq >3
584 | ldrd CARG34, [CRET1]
585 | ins_next1
586 | ins_next2
587 | strd CARG34, [BASE, RA]
588 | ins_next3
589 |
590 |3: // Call __index metamethod.
591 | // BASE = base, L->top = new base, stack = cont/func/t/k
592 | rsb CARG1, BASE, #FRAME_CONT
593 | ldr BASE, L->top
594 | mov NARGS8:RC, #16 // 2 args for func(t, k).
595 | str PC, [BASE, #-12] // [cont|PC]
596 | add PC, CARG1, BASE
597 | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here.
598 | b ->vm_call_dispatch_f
599 |
600 |//-----------------------------------------------------------------------
601 |
602 |->vmeta_tsets1:
603 | add CARG2, BASE, RB
604 | b >2
605 |
606 |->vmeta_tsets:
607 | sub CARG2, DISPATCH, #-DISPATCH_GL(tmptv)
608 | mvn CARG4, #~LJ_TTAB
609 | str TAB:RB, [CARG2]
610 | str CARG4, [CARG2, #4]
611 |2:
612 | mvn CARG4, #~LJ_TSTR
613 | str STR:RC, TMPDlo
614 | str CARG4, TMPDhi
615 | mov CARG3, TMPDp
616 | b >1
617 |
618 |->vmeta_tsetb: // RC = index
619 | decode_RB8 RB, INS
620 | str RC, TMPDlo
621 | mvn CARG4, #~LJ_TISNUM
622 | add CARG2, BASE, RB
623 | str CARG4, TMPDhi
624 | mov CARG3, TMPDp
625 | b >1
626 |
627 |->vmeta_tsetv:
628 | add CARG2, BASE, RB
629 | add CARG3, BASE, RC
630 |1:
631 | str BASE, L->base
632 | mov CARG1, L
633 | str PC, SAVE_PC
634 | bl extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
635 | // Returns TValue * (finished) or NULL (metamethod).
636 | IOS ldr BASE, L->base
637 | cmp CRET1, #0
638 | ldrd CARG34, [BASE, RA]
639 | beq >3
640 | ins_next1
641 | // NOBARRIER: lj_meta_tset ensures the table is not black.
642 | strd CARG34, [CRET1]
643 | ins_next2
644 | ins_next3
645 |
646 |3: // Call __newindex metamethod.
647 | // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
648 | rsb CARG1, BASE, #FRAME_CONT
649 | ldr BASE, L->top
650 | mov NARGS8:RC, #24 // 3 args for func(t, k, v).
651 | strd CARG34, [BASE, #16] // Copy value to third argument.
652 | str PC, [BASE, #-12] // [cont|PC]
653 | add PC, CARG1, BASE
654 | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here.
655 | b ->vm_call_dispatch_f
656 |
657 |//-- Comparison metamethods ---------------------------------------------
658 |
659 |->vmeta_comp:
660 | mov CARG1, L
661 | sub PC, PC, #4
662 | mov CARG2, RA
663 | str BASE, L->base
664 | mov CARG3, RC
665 | str PC, SAVE_PC
666 | decode_OP CARG4, INS
667 | bl extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
668 | // Returns 0/1 or TValue * (metamethod).
669 |3:
670 | IOS ldr BASE, L->base
671 | cmp CRET1, #1
672 | bhi ->vmeta_binop
673 |4:
674 | ldrh RB, [PC, #2]
675 | add PC, PC, #4
676 | add RB, PC, RB, lsl #2
677 | subhs PC, RB, #0x20000
678 |->cont_nop:
679 | ins_next
680 |
681 |->cont_ra: // RA = resultptr
682 | ldr INS, [PC, #-4]
683 | ldrd CARG12, [RA]
684 | decode_RA8 CARG3, INS
685 | strd CARG12, [BASE, CARG3]
686 | b ->cont_nop
687 |
688 |->cont_condt: // RA = resultptr
689 | ldr CARG2, [RA, #4]
690 | mvn CARG1, #~LJ_TTRUE
691 | cmp CARG1, CARG2 // Branch if result is true.
692 | b <4
693 |
694 |->cont_condf: // RA = resultptr
695 | ldr CARG2, [RA, #4]
696 | checktp CARG2, LJ_TFALSE // Branch if result is false.
697 | b <4
698 |
699 |->vmeta_equal:
700 | // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV.
701 | sub PC, PC, #4
702 | str BASE, L->base
703 | mov CARG1, L
704 | str PC, SAVE_PC
705 | bl extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
706 | // Returns 0/1 or TValue * (metamethod).
707 | b <3
708 |
709 |->vmeta_equal_cd:
710#if LJ_HASFFI
711 | sub PC, PC, #4
712 | str BASE, L->base
713 | mov CARG1, L
714 | mov CARG2, INS
715 | str PC, SAVE_PC
716 | bl extern lj_meta_equal_cd // (lua_State *L, BCIns op)
717 | // Returns 0/1 or TValue * (metamethod).
718 | b <3
719#endif
720 |
721 |//-- Arithmetic metamethods ---------------------------------------------
722 |
723 |->vmeta_arith_vn:
724 | decode_RB8 RB, INS
725 | decode_RC8 RC, INS
726 | add CARG3, BASE, RB
727 | add CARG4, KBASE, RC
728 | b >1
729 |
730 |->vmeta_arith_nv:
731 | decode_RB8 RB, INS
732 | decode_RC8 RC, INS
733 | add CARG4, BASE, RB
734 | add CARG3, KBASE, RC
735 | b >1
736 |
737 |->vmeta_unm:
738 | ldr INS, [PC, #-8]
739 | sub PC, PC, #4
740 | add CARG3, BASE, RC
741 | add CARG4, BASE, RC
742 | b >1
743 |
744 |->vmeta_arith_vv:
745 | decode_RB8 RB, INS
746 | decode_RC8 RC, INS
747 | add CARG3, BASE, RB
748 | add CARG4, BASE, RC
749 |1:
750 | decode_OP OP, INS
751 | add CARG2, BASE, RA
752 | str BASE, L->base
753 | mov CARG1, L
754 | str PC, SAVE_PC
755 | str OP, ARG5
756 | bl extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
757 | // Returns NULL (finished) or TValue * (metamethod).
758 | IOS ldr BASE, L->base
759 | cmp CRET1, #0
760 | beq ->cont_nop
761 |
762 | // Call metamethod for binary op.
763 |->vmeta_binop:
764 | // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2
765 | sub CARG2, CRET1, BASE
766 | str PC, [CRET1, #-12] // [cont|PC]
767 | add PC, CARG2, #FRAME_CONT
768 | mov BASE, CRET1
769 | mov NARGS8:RC, #16 // 2 args for func(o1, o2).
770 | b ->vm_call_dispatch
771 |
772 |->vmeta_len:
773 | add CARG2, BASE, RC
774 | str BASE, L->base
775 | mov CARG1, L
776 | str PC, SAVE_PC
777 | bl extern lj_meta_len // (lua_State *L, TValue *o)
778 | // Returns NULL (retry) or TValue * (metamethod base).
779 | IOS ldr BASE, L->base
780#ifdef LUAJIT_ENABLE_LUA52COMPAT
781 | cmp CRET1, #0
782 | bne ->vmeta_binop // Binop call for compatibility.
783 | ldr TAB:CARG1, [BASE, RC]
784 | b ->BC_LEN_Z
785#else
786 | b ->vmeta_binop // Binop call for compatibility.
787#endif
788 |
789 |//-- Call metamethod ----------------------------------------------------
790 |
791 |->vmeta_call: // Resolve and call __call metamethod.
792 | // RB = old base, BASE = new base, RC = nargs*8
793 | mov CARG1, L
794 | str RB, L->base // This is the callers base!
795 | sub CARG2, BASE, #8
796 | str PC, SAVE_PC
797 | add CARG3, BASE, NARGS8:RC
798 | IOS mov RA, BASE
799 | bl extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
800 | IOS mov BASE, RA
801 | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here.
802 | add NARGS8:RC, NARGS8:RC, #8 // Got one more argument now.
803 | ins_call
804 |
805 |->vmeta_callt: // Resolve __call for BC_CALLT.
806 | // BASE = old base, RA = new base, RC = nargs*8
807 | mov CARG1, L
808 | str BASE, L->base
809 | sub CARG2, RA, #8
810 | str PC, SAVE_PC
811 | add CARG3, RA, NARGS8:RC
812 | bl extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
813 | IOS ldr BASE, L->base
814 | ldr LFUNC:CARG3, [RA, FRAME_FUNC] // Guaranteed to be a function here.
815 | ldr PC, [BASE, FRAME_PC]
816 | add NARGS8:RC, NARGS8:RC, #8 // Got one more argument now.
817 | b ->BC_CALLT2_Z
818 |
819 |//-- Argument coercion for 'for' statement ------------------------------
820 |
821 |->vmeta_for:
822 | mov CARG1, L
823 | str BASE, L->base
824 | mov CARG2, RA
825 | str PC, SAVE_PC
826 | bl extern lj_meta_for // (lua_State *L, TValue *base)
827 | IOS ldr BASE, L->base
828#if LJ_HASJIT
829 | ldrb OP, [PC, #-4]
830#endif
831 | ldr INS, [PC, #-4]
832#if LJ_HASJIT
833 | cmp OP, #BC_JFORI
834#endif
835 | decode_RA8 RA, INS
836 | decode_RD RC, INS
837#if LJ_HASJIT
838 | beq =>BC_JFORI
839#endif
840 | b =>BC_FORI
841 |
842 |//-----------------------------------------------------------------------
843 |//-- Fast functions -----------------------------------------------------
844 |//-----------------------------------------------------------------------
845 |
846 |.macro .ffunc, name
847 |->ff_ .. name:
848 |.endmacro
849 |
850 |.macro .ffunc_1, name
851 |->ff_ .. name:
852 | ldrd CARG12, [BASE]
853 | cmp NARGS8:RC, #8
854 | blo ->fff_fallback
855 |.endmacro
856 |
857 |.macro .ffunc_2, name
858 |->ff_ .. name:
859 | ldrd CARG12, [BASE]
860 | ldrd CARG34, [BASE, #8]
861 | cmp NARGS8:RC, #16
862 | blo ->fff_fallback
863 |.endmacro
864 |
865 |.macro .ffunc_n, name
866 | .ffunc_1 name
867 | checktp CARG2, LJ_TISNUM
868 | bhs ->fff_fallback
869 |.endmacro
870 |
871 |.macro .ffunc_nn, name
872 | .ffunc_2 name
873 | checktp CARG2, LJ_TISNUM
874 | cmnlo CARG4, #-LJ_TISNUM
875 | bhs ->fff_fallback
876 |.endmacro
877 |
878 |// Inlined GC threshold check. Caveat: uses CARG1 and CARG2.
879 |.macro ffgccheck
880 | ldr CARG1, [DISPATCH, #DISPATCH_GL(gc.total)]
881 | ldr CARG2, [DISPATCH, #DISPATCH_GL(gc.threshold)]
882 | cmp CARG1, CARG2
883 | blge ->fff_gcstep
884 |.endmacro
885 |
886 |//-- Base library: checks -----------------------------------------------
887 |
888 |.ffunc_1 assert
889 | checktp CARG2, LJ_TTRUE
890 | bhi ->fff_fallback
891 | ldr PC, [BASE, FRAME_PC]
892 | strd CARG12, [BASE, #-8]
893 | mov RB, BASE
894 | subs RA, NARGS8:RC, #8
895 | add RC, NARGS8:RC, #8 // Compute (nresults+1)*8.
896 | beq ->fff_res // Done if exactly 1 argument.
897 |1:
898 | ldrd CARG12, [RB, #8]
899 | subs RA, RA, #8
900 | strd CARG12, [RB], #8
901 | bne <1
902 | b ->fff_res
903 |
904 |.ffunc type
905 | ldr CARG2, [BASE, #4]
906 | cmp NARGS8:RC, #8
907 | blo ->fff_fallback
908 | checktp CARG2, LJ_TISNUM
909 | mvnlo CARG2, #~LJ_TISNUM
910 | rsb CARG4, CARG2, #(int)(offsetof(GCfuncC, upvalue)>>3)-1
911 | lsl CARG4, CARG4, #3
912 | ldrd CARG12, [CFUNC:CARG3, CARG4]
913 | b ->fff_restv
914 |
915 |//-- Base library: getters and setters ---------------------------------
916 |
917 |.ffunc_1 getmetatable
918 | checktp CARG2, LJ_TTAB
919 | cmnne CARG2, #-LJ_TUDATA
920 | bne >6
921 |1: // Field metatable must be at same offset for GCtab and GCudata!
922 | ldr TAB:RB, TAB:CARG1->metatable
923 |2:
924 | mvn CARG2, #~LJ_TNIL
925 | ldr STR:RC, [DISPATCH, #DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])]
926 | cmp TAB:RB, #0
927 | beq ->fff_restv
928 | ldr CARG3, TAB:RB->hmask
929 | ldr CARG4, STR:RC->hash
930 | ldr NODE:INS, TAB:RB->node
931 | and CARG3, CARG3, CARG4 // idx = str->hash & tab->hmask
932 | add CARG3, CARG3, CARG3, lsl #1
933 | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8
934 |3: // Rearranged logic, because we expect _not_ to find the key.
935 | ldrd CARG34, NODE:INS->key // STALL: early NODE:INS.
936 | ldrd CARG12, NODE:INS->val
937 | ldr NODE:INS, NODE:INS->next
938 | cmp CARG3, STR:RC
939 | checktpeq CARG4, LJ_TSTR
940 | beq >5
941 | cmp NODE:INS, #0
942 | bne <3
943 |4:
944 | mov CARG1, RB // Use metatable as default result.
945 | mvn CARG2, #~LJ_TTAB
946 | b ->fff_restv
947 |5:
948 | checktp CARG2, LJ_TNIL
949 | bne ->fff_restv
950 | b <4
951 |
952 |6:
953 | checktp CARG2, LJ_TISNUM
954 | mvnhs CARG2, CARG2
955 | movlo CARG2, #~LJ_TISNUM
956 | add CARG4, DISPATCH, CARG2, lsl #2
957 | ldr TAB:RB, [CARG4, #DISPATCH_GL(gcroot[GCROOT_BASEMT])]
958 | b <2
959 |
960 |.ffunc_2 setmetatable
961 | // Fast path: no mt for table yet and not clearing the mt.
962 | checktp CARG2, LJ_TTAB
963 | ldreq TAB:RB, TAB:CARG1->metatable
964 | checktpeq CARG4, LJ_TTAB
965 | ldrbeq CARG4, TAB:CARG1->marked
966 | cmpeq TAB:RB, #0
967 | bne ->fff_fallback
968 | tst CARG4, #LJ_GC_BLACK // isblack(table)
969 | str TAB:CARG3, TAB:CARG1->metatable
970 | beq ->fff_restv
971 | barrierback TAB:CARG1, CARG4, CARG3
972 | b ->fff_restv
973 |
974 |.ffunc rawget
975 | ldrd CARG34, [BASE]
976 | cmp NARGS8:RC, #16
977 | blo ->fff_fallback
978 | mov CARG2, CARG3
979 | checktab CARG4, ->fff_fallback
980 | mov CARG1, L
981 | add CARG3, BASE, #8
982 | IOS mov RA, BASE
983 | bl extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
984 | // Returns cTValue *.
985 | IOS mov BASE, RA
986 | ldrd CARG12, [CRET1]
987 | b ->fff_restv
988 |
989 |//-- Base library: conversions ------------------------------------------
990 |
991 |.ffunc_1 tonumber
992 | // Only handles the number case inline (without a base argument).
993 | checktp CARG2, LJ_TISNUM
994 | bls ->fff_restv
995 | b ->fff_fallback
996 |
997 |.ffunc_1 tostring
998 | // Only handles the string or number case inline.
999 | checktp CARG2, LJ_TSTR
1000 | // A __tostring method in the string base metatable is ignored.
1001 | beq ->fff_restv
1002 | // Handle numbers inline, unless a number base metatable is present.
1003 | ldr CARG4, [DISPATCH, #DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])]
1004 | str BASE, L->base
1005 | checktp CARG2, LJ_TISNUM
1006 | cmpls CARG4, #0
1007 | str PC, SAVE_PC // Redundant (but a defined value).
1008 | bhi ->fff_fallback
1009 | ffgccheck
1010 | mov CARG1, L
1011 | mov CARG2, BASE
1012 | bl extern lj_str_fromnumber // (lua_State *L, cTValue *o)
1013 | // Returns GCstr *.
1014 | ldr BASE, L->base
1015 | mvn CARG2, #~LJ_TSTR
1016 | b ->fff_restv
1017 |
1018 |//-- Base library: iterators -------------------------------------------
1019 |
1020 |.ffunc_1 next
1021 | mvn CARG4, #~LJ_TNIL
1022 | checktab CARG2, ->fff_fallback
1023 | strd CARG34, [BASE, NARGS8:RC] // Set missing 2nd arg to nil.
1024 | ldr PC, [BASE, FRAME_PC]
1025 | mov CARG2, CARG1
1026 | str BASE, L->base // Add frame since C call can throw.
1027 | mov CARG1, L
1028 | str BASE, L->top // Dummy frame length is ok.
1029 | add CARG3, BASE, #8
1030 | str PC, SAVE_PC
1031 | bl extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
1032 | // Returns 0 at end of traversal.
1033 | IOS ldr BASE, L->base
1034 | cmp CRET1, #0
1035 | mvneq CRET2, #~LJ_TNIL
1036 | beq ->fff_restv // End of traversal: return nil.
1037 | ldrd CARG12, [BASE, #8] // Copy key and value to results.
1038 | ldrd CARG34, [BASE, #16]
1039 | mov RC, #(2+1)*8
1040 | strd CARG12, [BASE, #-8]
1041 | strd CARG34, [BASE]
1042 | b ->fff_res
1043 |
1044 |.ffunc_1 pairs
1045 | checktab CARG2, ->fff_fallback
1046#ifdef LUAJIT_ENABLE_LUA52COMPAT
1047 | ldr TAB:RB, TAB:CARG1->metatable
1048#endif
1049 | ldrd CFUNC:CARG34, CFUNC:CARG3->upvalue[0]
1050 | ldr PC, [BASE, FRAME_PC]
1051#ifdef LUAJIT_ENABLE_LUA52COMPAT
1052 | cmp TAB:RB, #0
1053 | bne ->fff_fallback
1054#endif
1055 | mvn CARG2, #~LJ_TNIL
1056 | mov RC, #(3+1)*8
1057 | strd CFUNC:CARG34, [BASE, #-8]
1058 | str CARG2, [BASE, #12]
1059 | b ->fff_res
1060 |
1061 |.ffunc_2 ipairs_aux
1062 | checktp CARG2, LJ_TTAB
1063 | checktpeq CARG4, LJ_TISNUM
1064 | bne ->fff_fallback
1065 | ldr RB, TAB:CARG1->asize
1066 | ldr RC, TAB:CARG1->array
1067 | add CARG3, CARG3, #1
1068 | ldr PC, [BASE, FRAME_PC]
1069 | cmp CARG3, RB
1070 | add RC, RC, CARG3, lsl #3
1071 | strd CARG34, [BASE, #-8]
1072 | ldrdlo CARG12, [RC]
1073 | mov RC, #(0+1)*8
1074 | bhs >2 // Not in array part?
1075 |1:
1076 | checktp CARG2, LJ_TNIL
1077 | movne RC, #(2+1)*8
1078 | strdne CARG12, [BASE]
1079 | b ->fff_res
1080 |2: // Check for empty hash part first. Otherwise call C function.
1081 | ldr RB, TAB:CARG1->hmask
1082 | mov CARG2, CARG3
1083 | cmp RB, #0
1084 | beq ->fff_res
1085 | IOS mov RA, BASE
1086 | bl extern lj_tab_getinth // (GCtab *t, int32_t key)
1087 | // Returns cTValue * or NULL.
1088 | IOS mov BASE, RA
1089 | cmp CRET1, #0
1090 | beq ->fff_res
1091 | ldrd CARG12, [CRET1]
1092 | b <1
1093 |
1094 |.ffunc_1 ipairs
1095 | checktab CARG2, ->fff_fallback
1096#ifdef LUAJIT_ENABLE_LUA52COMPAT
1097 | ldr TAB:RB, TAB:CARG1->metatable
1098#endif
1099 | ldrd CFUNC:CARG34, CFUNC:CARG3->upvalue[0]
1100 | ldr PC, [BASE, FRAME_PC]
1101#ifdef LUAJIT_ENABLE_LUA52COMPAT
1102 | cmp TAB:RB, #0
1103 | bne ->fff_fallback
1104#endif
1105 | mov CARG1, #0
1106 | mvn CARG2, #~LJ_TISNUM
1107 | mov RC, #(3+1)*8
1108 | strd CFUNC:CARG34, [BASE, #-8]
1109 | strd CARG12, [BASE, #8]
1110 | b ->fff_res
1111 |
1112 |//-- Base library: catch errors ----------------------------------------
1113 |
1114 |.ffunc pcall
1115 | ldrb RA, [DISPATCH, #DISPATCH_GL(hookmask)]
1116 | cmp NARGS8:RC, #8
1117 | blo ->fff_fallback
1118 | tst RA, #HOOK_ACTIVE // Remember active hook before pcall.
1119 | mov RB, BASE
1120 | add BASE, BASE, #8
1121 | moveq PC, #8+FRAME_PCALL
1122 | movne PC, #8+FRAME_PCALLH
1123 | sub NARGS8:RC, NARGS8:RC, #8
1124 | b ->vm_call_dispatch
1125 |
1126 |.ffunc_2 xpcall
1127 | ldrb RA, [DISPATCH, #DISPATCH_GL(hookmask)]
1128 | checkfunc CARG4, ->fff_fallback // Traceback must be a function.
1129 | mov RB, BASE
1130 | strd CARG12, [BASE, #8] // Swap function and traceback.
1131 | strd CARG34, [BASE]
1132 | tst RA, #HOOK_ACTIVE // Remember active hook before pcall.
1133 | add BASE, BASE, #16
1134 | moveq PC, #16+FRAME_PCALL
1135 | movne PC, #16+FRAME_PCALLH
1136 | sub NARGS8:RC, NARGS8:RC, #16
1137 | b ->vm_call_dispatch
1138 |
1139 |//-- Coroutine library --------------------------------------------------
1140 |
1141 |.macro coroutine_resume_wrap, resume
1142 |.if resume
1143 |.ffunc_1 coroutine_resume
1144 | checktp CARG2, LJ_TTHREAD
1145 | bne ->fff_fallback
1146 |.else
1147 |.ffunc coroutine_wrap_aux
1148 | ldr L:CARG1, CFUNC:CARG3->upvalue[0].gcr
1149 |.endif
1150 | ldr PC, [BASE, FRAME_PC]
1151 | str BASE, L->base
1152 | ldr CARG2, L:CARG1->top
1153 | ldrb RA, L:CARG1->status
1154 | ldr RB, L:CARG1->base
1155 | add CARG3, CARG2, NARGS8:RC
1156 | add CARG4, CARG2, RA
1157 | str PC, SAVE_PC
1158 | cmp CARG4, RB
1159 | beq ->fff_fallback
1160 | ldr CARG4, L:CARG1->maxstack
1161 | ldr RB, L:CARG1->cframe
1162 | cmp RA, #LUA_YIELD
1163 | cmpls CARG3, CARG4
1164 | cmpls RB, #0
1165 | bhi ->fff_fallback
1166 |1:
1167 |.if resume
1168 | sub CARG3, CARG3, #8 // Keep resumed thread in stack for GC.
1169 | add BASE, BASE, #8
1170 | sub NARGS8:RC, NARGS8:RC, #8
1171 |.endif
1172 | str CARG3, L:CARG1->top
1173 | str BASE, L->top
1174 |2: // Move args to coroutine.
1175 | ldrd CARG34, [BASE, RB]
1176 | cmp RB, NARGS8:RC
1177 | strdne CARG34, [CARG2, RB]
1178 | add RB, RB, #8
1179 | bne <2
1180 |
1181 | mov CARG3, #0
1182 | mov L:RA, L:CARG1
1183 | mov CARG4, #0
1184 | bl ->vm_resume // (lua_State *L, TValue *base, 0, 0)
1185 | // Returns thread status.
1186 |4:
1187 | ldr CARG3, L:RA->base
1188 | mv_vmstate CARG2, INTERP
1189 | ldr CARG4, L:RA->top
1190 | st_vmstate CARG2
1191 | cmp CRET1, #LUA_YIELD
1192 | ldr BASE, L->base
1193 | bhi >8
1194 | subs RC, CARG4, CARG3
1195 | ldr CARG1, L->maxstack
1196 | add CARG2, BASE, RC
1197 | beq >6 // No results?
1198 | cmp CARG2, CARG1
1199 | mov RB, #0
1200 | bhi >9 // Need to grow stack?
1201 |
1202 | sub CARG4, RC, #8
1203 | str CARG3, L:RA->top // Clear coroutine stack.
1204 |5: // Move results from coroutine.
1205 | ldrd CARG12, [CARG3, RB]
1206 | cmp RB, CARG4
1207 | strd CARG12, [BASE, RB]
1208 | add RB, RB, #8
1209 | bne <5
1210 |6:
1211 |.if resume
1212 | mvn CARG3, #~LJ_TTRUE
1213 | add RC, RC, #16
1214 |7:
1215 | str CARG3, [BASE, #-4] // Prepend true/false to results.
1216 | sub RA, BASE, #8
1217 |.else
1218 | mov RA, BASE
1219 | add RC, RC, #8
1220 |.endif
1221 | ands CARG1, PC, #FRAME_TYPE
1222 | str PC, SAVE_PC
1223 | str RC, SAVE_MULTRES
1224 | beq ->BC_RET_Z
1225 | b ->vm_return
1226 |
1227 |8: // Coroutine returned with error (at co->top-1).
1228 |.if resume
1229 | ldrd CARG12, [CARG4, #-8]!
1230 | mvn CARG3, #~LJ_TFALSE
1231 | mov RC, #(2+1)*8
1232 | str CARG4, L:RA->top // Remove error from coroutine stack.
1233 | strd CARG12, [BASE] // Copy error message.
1234 | b <7
1235 |.else
1236 | mov CARG1, L
1237 | mov CARG2, L:RA
1238 | bl extern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co)
1239 | // Never returns.
1240 |.endif
1241 |
1242 |9: // Handle stack expansion on return from yield.
1243 | mov CARG1, L
1244 | lsr CARG2, RC, #3
1245 | bl extern lj_state_growstack // (lua_State *L, int n)
1246 | mov CRET1, #0
1247 | b <4
1248 |.endmacro
1249 |
1250 | coroutine_resume_wrap 1 // coroutine.resume
1251 | coroutine_resume_wrap 0 // coroutine.wrap
1252 |
1253 |.ffunc coroutine_yield
1254 | ldr CARG1, L->cframe
1255 | add CARG2, BASE, NARGS8:RC
1256 | str BASE, L->base
1257 | tst CARG1, #CFRAME_RESUME
1258 | str CARG2, L->top
1259 | mov CRET1, #LUA_YIELD
1260 | mov CARG3, #0
1261 | beq ->fff_fallback
1262 | str CARG3, L->cframe
1263 | strb CRET1, L->status
1264 | b ->vm_leave_unw
1265 |
1266 |//-- Math library -------------------------------------------------------
1267 |
1268 |.macro math_round, func
1269 | .ffunc_1 math_ .. func
1270 | checktp CARG2, LJ_TISNUM
1271 | beq ->fff_restv
1272 | bhi ->fff_fallback
1273 | // Round FP value and normalize result.
1274 | lsl CARG3, CARG2, #1
1275 | adds RB, CARG3, #0x00200000
1276 | bpl >2 // |x| < 1?
1277 | mvn CARG4, #0x3e0
1278 | subs RB, CARG4, RB, asr #21
1279 | lsl CARG4, CARG2, #11
1280 | lsl CARG3, CARG1, #11
1281 | orr CARG4, CARG4, #0x80000000
1282 | rsb INS, RB, #32
1283 | orr CARG4, CARG4, CARG1, lsr #21
1284 | bls >3 // |x| >= 2^31?
1285 | orr CARG3, CARG3, CARG4, lsl INS
1286 | lsr CARG1, CARG4, RB
1287 |.if "func" == "floor"
1288 | tst CARG3, CARG2, asr #31
1289 | addne CARG1, CARG1, #1
1290 |.else
1291 | bics CARG3, CARG3, CARG2, asr #31
1292 | addsne CARG1, CARG1, #1
1293 | ldrdvs CARG12, >9
1294 | bvs ->fff_restv
1295 |.endif
1296 | cmp CARG2, #0
1297 | rsblt CARG1, CARG1, #0
1298 |1:
1299 | mvn CARG2, #~LJ_TISNUM
1300 | b ->fff_restv
1301 |
1302 |2: // |x| < 1
1303 | orr CARG3, CARG3, CARG1 // ztest = abs(hi) | lo
1304 |.if "func" == "floor"
1305 | tst CARG3, CARG2, asr #31 // return (ztest & sign) == 0 ? 0 : -1
1306 | moveq CARG1, #0
1307 | mvnne CARG1, #0
1308 |.else
1309 | bics CARG3, CARG3, CARG2, asr #31 // return (ztest & ~sign) == 0 ? 0 : 1
1310 | moveq CARG1, #0
1311 | movne CARG1, #1
1312 |.endif
1313 | mvn CARG2, #~LJ_TISNUM
1314 | b ->fff_restv
1315 |
1316 |3: // |x| >= 2^31. Check for x == -(2^31).
1317 | cmpeq CARG4, #0x80000000
1318 |.if "func" == "floor"
1319 | cmpeq CARG3, #0
1320 |.endif
1321 | bne >4
1322 | cmp CARG2, #0
1323 | movmi CARG1, #0x80000000
1324 | bmi <1
1325 |4:
1326 | bl ->vm_..func
1327 | b ->fff_restv
1328 |.endmacro
1329 |
1330 | math_round floor
1331 | math_round ceil
1332 |
1333 |.align 8
1334 |9:
1335 | .long 0x00000000, 0x41e00000 // 2^31.
1336 |
1337 |.ffunc_1 math_abs
1338 | checktp CARG2, LJ_TISNUM
1339 | bhi ->fff_fallback
1340 | bicne CARG2, CARG2, #0x80000000
1341 | bne ->fff_restv
1342 | cmp CARG1, #0
1343 | rsbslt CARG1, CARG1, #0
1344 | ldrdvs CARG12, <9
1345 | // Fallthrough.
1346 |
1347 |->fff_restv:
1348 | // CARG12 = TValue result.
1349 | ldr PC, [BASE, FRAME_PC]
1350 | strd CARG12, [BASE, #-8]
1351 |->fff_res1:
1352 | // PC = return.
1353 | mov RC, #(1+1)*8
1354 |->fff_res:
1355 | // RC = (nresults+1)*8, PC = return.
1356 | ands CARG1, PC, #FRAME_TYPE
1357 | ldreq INS, [PC, #-4]
1358 | str RC, SAVE_MULTRES
1359 | sub RA, BASE, #8
1360 | bne ->vm_return
1361 | decode_RB8 RB, INS
1362 |5:
1363 | cmp RB, RC // More results expected?
1364 | bhi >6
1365 | decode_RA8 CARG1, INS
1366 | ins_next1
1367 | ins_next2
1368 | // Adjust BASE. KBASE is assumed to be set for the calling frame.
1369 | sub BASE, RA, CARG1
1370 | ins_next3
1371 |
1372 |6: // Fill up results with nil.
1373 | add CARG2, RA, RC
1374 | mvn CARG1, #~LJ_TNIL
1375 | add RC, RC, #8
1376 | str CARG1, [CARG2, #-4]
1377 | b <5
1378 |
1379 |.macro math_extern, func
1380 | .ffunc_n math_ .. func
1381 | IOS mov RA, BASE
1382 | bl extern func
1383 | IOS mov BASE, RA
1384 | b ->fff_restv
1385 |.endmacro
1386 |
1387 |.macro math_extern2, func
1388 | .ffunc_nn math_ .. func
1389 | IOS mov RA, BASE
1390 | bl extern func
1391 | IOS mov BASE, RA
1392 | b ->fff_restv
1393 |.endmacro
1394 |
1395 | math_extern sqrt
1396 | math_extern log
1397 | math_extern log10
1398 | math_extern exp
1399 | math_extern sin
1400 | math_extern cos
1401 | math_extern tan
1402 | math_extern asin
1403 | math_extern acos
1404 | math_extern atan
1405 | math_extern sinh
1406 | math_extern cosh
1407 | math_extern tanh
1408 | math_extern2 pow
1409 | math_extern2 atan2
1410 | math_extern2 fmod
1411 |
1412 |->ff_math_deg:
1413 |.ffunc_n math_rad
1414 | ldrd CARG34, CFUNC:CARG3->upvalue[0]
1415 | bl extern __aeabi_dmul
1416 | b ->fff_restv
1417 |
1418 |.ffunc_2 math_ldexp
1419 | checktp CARG2, LJ_TISNUM
1420 | bhs ->fff_fallback
1421 | checktp CARG4, LJ_TISNUM
1422 | bne ->fff_fallback
1423 | IOS mov RA, BASE
1424 | bl extern ldexp // (double x, int exp)
1425 | IOS mov BASE, RA
1426 | b ->fff_restv
1427 |
1428 |.ffunc_n math_frexp
1429 | mov CARG3, sp
1430 | IOS mov RA, BASE
1431 | bl extern frexp
1432 | IOS mov BASE, RA
1433 | ldr CARG3, [sp]
1434 | mvn CARG4, #~LJ_TISNUM
1435 | ldr PC, [BASE, FRAME_PC]
1436 | strd CARG12, [BASE, #-8]
1437 | mov RC, #(2+1)*8
1438 | strd CARG34, [BASE]
1439 | b ->fff_res
1440 |
1441 |.ffunc_n math_modf
1442 | sub CARG3, BASE, #8
1443 | ldr PC, [BASE, FRAME_PC]
1444 | IOS mov RA, BASE
1445 | bl extern modf
1446 | IOS mov BASE, RA
1447 | mov RC, #(2+1)*8
1448 | strd CARG12, [BASE]
1449 | b ->fff_res
1450 |
1451 |.macro math_minmax, name, cond, fcond
1452 | .ffunc_1 name
1453 | checktp CARG2, LJ_TISNUM
1454 | mov RA, #8
1455 | bne >4
1456 |1: // Handle integers.
1457 | ldrd CARG34, [BASE, RA]
1458 | cmp RA, RC
1459 | bhs ->fff_restv
1460 | checktp CARG4, LJ_TISNUM
1461 | bne >3
1462 | cmp CARG1, CARG3
1463 | add RA, RA, #8
1464 | mov..cond CARG1, CARG3
1465 | b <1
1466 |3:
1467 | bhi ->fff_fallback
1468 | // Convert intermediate result to number and continue below.
1469 | bl extern __aeabi_i2d
1470 | ldrd CARG34, [BASE, RA]
1471 | b >6
1472 |
1473 |4:
1474 | bhi ->fff_fallback
1475 |5: // Handle numbers.
1476 | ldrd CARG34, [BASE, RA]
1477 | cmp RA, RC
1478 | bhs ->fff_restv
1479 | checktp CARG4, LJ_TISNUM
1480 | bhs >7
1481 |6:
1482 | bl extern __aeabi_cdcmple
1483 | add RA, RA, #8
1484 | mov..fcond CARG1, CARG3
1485 | mov..fcond CARG2, CARG4
1486 | b <5
1487 |7: // Convert integer to number and continue above.
1488 | bhi ->fff_fallback
1489 | strd CARG12, TMPD
1490 | mov CARG1, CARG3
1491 | bl extern __aeabi_i2d
1492 | ldrd CARG34, TMPD
1493 | b <6
1494 |.endmacro
1495 |
1496 | math_minmax math_min, gt, hi
1497 | math_minmax math_max, lt, lo
1498 |
1499 |//-- String library -----------------------------------------------------
1500 |
1501 |.ffunc_1 string_len
1502 | checkstr CARG2, ->fff_fallback
1503 | ldr CARG1, STR:CARG1->len
1504 | mvn CARG2, #~LJ_TISNUM
1505 | b ->fff_restv
1506 |
1507 |.ffunc string_byte // Only handle the 1-arg case here.
1508 | ldrd CARG12, [BASE]
1509 | ldr PC, [BASE, FRAME_PC]
1510 | cmp NARGS8:RC, #8
1511 | checktpeq CARG2, LJ_TSTR // Need exactly 1 argument.
1512 | bne ->fff_fallback
1513 | ldr CARG3, STR:CARG1->len
1514 | ldrb CARG1, STR:CARG1[1] // Access is always ok (NUL at end).
1515 | mvn CARG2, #~LJ_TISNUM
1516 | cmp CARG3, #0
1517 | moveq RC, #(0+1)*8
1518 | movne RC, #(1+1)*8
1519 | strd CARG12, [BASE, #-8]
1520 | b ->fff_res
1521 |
1522 |.ffunc string_char // Only handle the 1-arg case here.
1523 | ffgccheck
1524 | ldrd CARG12, [BASE]
1525 | ldr PC, [BASE, FRAME_PC]
1526 | cmp NARGS8:RC, #8 // Need exactly 1 argument.
1527 | checktpeq CARG2, LJ_TISNUM
1528 | bicseq CARG4, CARG1, #255
1529 | mov CARG3, #1
1530 | bne ->fff_fallback
1531 | str CARG1, TMPD
1532 | mov CARG2, TMPDp // Points to stack. Little-endian.
1533 |->fff_newstr:
1534 | // CARG2 = str, CARG3 = len.
1535 | str BASE, L->base
1536 | mov CARG1, L
1537 | str PC, SAVE_PC
1538 | bl extern lj_str_new // (lua_State *L, char *str, size_t l)
1539 | // Returns GCstr *.
1540 | ldr BASE, L->base
1541 | mvn CARG2, #~LJ_TSTR
1542 | b ->fff_restv
1543 |
1544 |.ffunc string_sub
1545 | ffgccheck
1546 | ldrd CARG12, [BASE]
1547 | ldrd CARG34, [BASE, #16]
1548 | cmp NARGS8:RC, #16
1549 | mvn RB, #0
1550 | beq >1
1551 | blo ->fff_fallback
1552 | checktp CARG4, LJ_TISNUM
1553 | mov RB, CARG3
1554 | bne ->fff_fallback
1555 |1:
1556 | ldrd CARG34, [BASE, #8]
1557 | checktp CARG2, LJ_TSTR
1558 | ldreq CARG2, STR:CARG1->len
1559 | checktpeq CARG4, LJ_TISNUM
1560 | bne ->fff_fallback
1561 | // CARG1 = str, CARG2 = str->len, CARG3 = start, RB = end
1562 | add CARG4, CARG2, #1
1563 | cmp CARG3, #0 // if (start < 0) start += len+1
1564 | addlt CARG3, CARG3, CARG4
1565 | cmp CARG3, #1 // if (start < 1) start = 1
1566 | movlt CARG3, #1
1567 | cmp RB, #0 // if (end < 0) end += len+1
1568 | addlt RB, RB, CARG4
1569 | bic RB, RB, RB, asr #31 // if (end < 0) end = 0
1570 | cmp RB, CARG2 // if (end > len) end = len
1571 | add CARG1, STR:CARG1, #sizeof(GCstr)-1
1572 | movgt RB, CARG2
1573 | add CARG2, CARG1, CARG3
1574 | subs CARG3, RB, CARG3 // len = start - end
1575 | add CARG3, CARG3, #1 // len += 1
1576 | bge ->fff_newstr
1577 |->fff_emptystr:
1578 | sub STR:CARG1, DISPATCH, #-DISPATCH_GL(strempty)
1579 | mvn CARG2, #~LJ_TSTR
1580 | b ->fff_restv
1581 |
1582 |.ffunc string_rep // Only handle the 1-char case inline.
1583 | ffgccheck
1584 | ldrd CARG12, [BASE]
1585 | ldrd CARG34, [BASE, #8]
1586 | cmp NARGS8:RC, #16
1587 | blo ->fff_fallback
1588 | checktp CARG2, LJ_TSTR
1589 | checktpeq CARG4, LJ_TISNUM
1590 | bne ->fff_fallback
1591 | subs CARG4, CARG3, #1
1592 | ldr CARG2, STR:CARG1->len
1593 | blt ->fff_emptystr // Count <= 0?
1594 | cmp CARG2, #1
1595 | blo ->fff_emptystr // Zero-length string?
1596 | bne ->fff_fallback // Fallback for > 1-char strings.
1597 | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
1598 | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
1599 | ldr CARG1, STR:CARG1[1]
1600 | cmp RB, CARG3
1601 | blo ->fff_fallback
1602 |1: // Fill buffer with char.
1603 | strb CARG1, [CARG2, CARG4]
1604 | subs CARG4, CARG4, #1
1605 | bge <1
1606 | b ->fff_newstr
1607 |
1608 |.ffunc string_reverse
1609 | ffgccheck
1610 | ldrd CARG12, [BASE]
1611 | cmp NARGS8:RC, #8
1612 | blo ->fff_fallback
1613 | checkstr CARG2, ->fff_fallback
1614 | ldr CARG3, STR:CARG1->len
1615 | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
1616 | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
1617 | mov CARG4, CARG3
1618 | add CARG1, STR:CARG1, #sizeof(GCstr)
1619 | cmp RB, CARG3
1620 | blo ->fff_fallback
1621 |1: // Reverse string copy.
1622 | ldrb RB, [CARG1], #1
1623 | subs CARG4, CARG4, #1
1624 | blt ->fff_newstr
1625 | strb RB, [CARG2, CARG4]
1626 | b <1
1627 |
1628 |.macro ffstring_case, name, lo
1629 | .ffunc name
1630 | ffgccheck
1631 | ldrd CARG12, [BASE]
1632 | cmp NARGS8:RC, #8
1633 | blo ->fff_fallback
1634 | checkstr CARG2, ->fff_fallback
1635 | ldr CARG3, STR:CARG1->len
1636 | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
1637 | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
1638 | mov CARG4, #0
1639 | add CARG1, STR:CARG1, #sizeof(GCstr)
1640 | cmp RB, CARG3
1641 | blo ->fff_fallback
1642 |1: // ASCII case conversion.
1643 | ldrb RB, [CARG1, CARG4]
1644 | cmp CARG4, CARG3
1645 | bhs ->fff_newstr
1646 | sub RC, RB, #lo
1647 | cmp RC, #26
1648 | eorlo RB, RB, #0x20
1649 | strb RB, [CARG2, CARG4]
1650 | add CARG4, CARG4, #1
1651 | b <1
1652 |.endmacro
1653 |
1654 |ffstring_case string_lower, 65
1655 |ffstring_case string_upper, 97
1656 |
1657 |//-- Table library ------------------------------------------------------
1658 |
1659 |.ffunc_1 table_getn
1660 | checktab CARG2, ->fff_fallback
1661 | IOS mov RA, BASE
1662 | bl extern lj_tab_len // (GCtab *t)
1663 | // Returns uint32_t (but less than 2^31).
1664 | IOS mov BASE, RA
1665 | mvn CARG2, #~LJ_TISNUM
1666 | b ->fff_restv
1667 |
1668 |//-- Bit library --------------------------------------------------------
1669 |
1670 |// FP number to bit conversion for soft-float. Clobbers r0-r3.
1671 |->vm_tobit_fb:
1672 | bhi ->fff_fallback
1673 |->vm_tobit:
1674 | lsl RB, CARG2, #1
1675 | adds RB, RB, #0x00200000
1676 | movpl CARG1, #0 // |x| < 1?
1677 | bxpl lr
1678 | mvn CARG4, #0x3e0
1679 | subs RB, CARG4, RB, asr #21
1680 | bmi >1 // |x| >= 2^32?
1681 | lsl CARG4, CARG2, #11
1682 | orr CARG4, CARG4, #0x80000000
1683 | orr CARG4, CARG4, CARG1, lsr #21
1684 | cmp CARG2, #0
1685 | lsr CARG1, CARG4, RB
1686 | rsblt CARG1, CARG1, #0
1687 | bx lr
1688 |1:
1689 | add RB, RB, #21
1690 | lsr CARG4, CARG1, RB
1691 | rsb RB, RB, #20
1692 | lsl CARG1, CARG2, #12
1693 | cmp CARG2, #0
1694 | orr CARG1, CARG4, CARG1, lsl RB
1695 | rsblt CARG1, CARG1, #0
1696 | bx lr
1697 |
1698 |.macro .ffunc_bit, name
1699 | .ffunc_1 bit_..name
1700 | checktp CARG2, LJ_TISNUM
1701 | blne ->vm_tobit_fb
1702 |.endmacro
1703 |
1704 |.ffunc_bit tobit
1705 | mvn CARG2, #~LJ_TISNUM
1706 | b ->fff_restv
1707 |
1708 |.macro .ffunc_bit_op, name, ins
1709 | .ffunc_bit name
1710 | mov CARG3, CARG1
1711 | mov RA, #8
1712 |1:
1713 | ldrd CARG12, [BASE, RA]
1714 | cmp RA, NARGS8:RC
1715 | add RA, RA, #8
1716 | bge >2
1717 | checktp CARG2, LJ_TISNUM
1718 | blne ->vm_tobit_fb
1719 | ins CARG3, CARG3, CARG1
1720 | b <1
1721 |.endmacro
1722 |
1723 |.ffunc_bit_op band, and
1724 |.ffunc_bit_op bor, orr
1725 |.ffunc_bit_op bxor, eor
1726 |
1727 |2:
1728 | mvn CARG4, #~LJ_TISNUM
1729 | ldr PC, [BASE, FRAME_PC]
1730 | strd CARG34, [BASE, #-8]
1731 | b ->fff_res1
1732 |
1733 |.ffunc_bit bswap
1734 | eor CARG3, CARG1, CARG1, ror #16
1735 | bic CARG3, CARG3, #0x00ff0000
1736 | ror CARG1, CARG1, #8
1737 | mvn CARG2, #~LJ_TISNUM
1738 | eor CARG1, CARG1, CARG3, lsr #8
1739 | b ->fff_restv
1740 |
1741 |.ffunc_bit bnot
1742 | mvn CARG1, CARG1
1743 | mvn CARG2, #~LJ_TISNUM
1744 | b ->fff_restv
1745 |
1746 |.macro .ffunc_bit_sh, name, ins, shmod
1747 | .ffunc bit_..name
1748 | ldrd CARG12, [BASE, #8]
1749 | cmp NARGS8:RC, #16
1750 | blo ->fff_fallback
1751 | checktp CARG2, LJ_TISNUM
1752 | blne ->vm_tobit_fb
1753 |.if shmod == 0
1754 | and RA, CARG1, #31
1755 |.else
1756 | rsb RA, CARG1, #0
1757 |.endif
1758 | ldrd CARG12, [BASE]
1759 | checktp CARG2, LJ_TISNUM
1760 | blne ->vm_tobit_fb
1761 | ins CARG1, CARG1, RA
1762 | mvn CARG2, #~LJ_TISNUM
1763 | b ->fff_restv
1764 |.endmacro
1765 |
1766 |.ffunc_bit_sh lshift, lsl, 0
1767 |.ffunc_bit_sh rshift, lsr, 0
1768 |.ffunc_bit_sh arshift, asr, 0
1769 |.ffunc_bit_sh rol, ror, 1
1770 |.ffunc_bit_sh ror, ror, 0
1771 |
1772 |//-----------------------------------------------------------------------
1773 |
1774 |->fff_fallback: // Call fast function fallback handler.
1775 | // BASE = new base, RC = nargs*8
1776 | ldr CARG3, [BASE, FRAME_FUNC]
1777 | ldr CARG2, L->maxstack
1778 | add CARG1, BASE, NARGS8:RC
1779 | ldr PC, [BASE, FRAME_PC] // Fallback may overwrite PC.
1780 | str CARG1, L->top
1781 | ldr CARG3, CFUNC:CARG3->f
1782 | str BASE, L->base
1783 | add CARG1, CARG1, #8*LUA_MINSTACK
1784 | str PC, SAVE_PC // Redundant (but a defined value).
1785 | cmp CARG1, CARG2
1786 | mov CARG1, L
1787 | bhi >5 // Need to grow stack.
1788 | blx CARG3 // (lua_State *L)
1789 | // Either throws an error, or recovers and returns -1, 0 or nresults+1.
1790 | ldr BASE, L->base
1791 | cmp CRET1, #0
1792 | lsl RC, CRET1, #3
1793 | sub RA, BASE, #8
1794 | bgt ->fff_res // Returned nresults+1?
1795 |1: // Returned 0 or -1: retry fast path.
1796 | ldr CARG1, L->top
1797 | ldr LFUNC:CARG3, [BASE, FRAME_FUNC]
1798 | sub NARGS8:RC, CARG1, BASE
1799 | bne ->vm_call_tail // Returned -1?
1800 | ins_callt // Returned 0: retry fast path.
1801 |
1802 |// Reconstruct previous base for vmeta_call during tailcall.
1803 |->vm_call_tail:
1804 | ands CARG1, PC, #FRAME_TYPE
1805 | bic CARG2, PC, #FRAME_TYPEP
1806 | ldreq INS, [PC, #-4]
1807 | andeq CARG2, MASKR8, INS, lsr #5 // Conditional decode_RA8.
1808 | sub RB, BASE, CARG2
1809 | b ->vm_call_dispatch // Resolve again for tailcall.
1810 |
1811 |5: // Grow stack for fallback handler.
1812 | mov CARG2, #LUA_MINSTACK
1813 | bl extern lj_state_growstack // (lua_State *L, int n)
1814 | ldr BASE, L->base
1815 | cmp CARG1, CARG1 // Set zero-flag to force retry.
1816 | b <1
1817 |
1818 |->fff_gcstep: // Call GC step function.
1819 | // BASE = new base, RC = nargs*8
1820 | mov RA, lr
1821 | str BASE, L->base
1822 | add CARG2, BASE, NARGS8:RC
1823 | str PC, SAVE_PC // Redundant (but a defined value).
1824 | str CARG2, L->top
1825 | mov CARG1, L
1826 | bl extern lj_gc_step // (lua_State *L)
1827 | ldr BASE, L->base
1828 | mov lr, RA // Help return address predictor.
1829 | ldr CFUNC:CARG3, [BASE, FRAME_FUNC]
1830 | bx lr
1831 |
1832 |//-----------------------------------------------------------------------
1833 |//-- Special dispatch targets -------------------------------------------
1834 |//-----------------------------------------------------------------------
1835 |
1836 |->vm_record: // Dispatch target for recording phase.
1837#if LJ_HASJIT
1838 | ldrb CARG1, [DISPATCH, #DISPATCH_GL(hookmask)]
1839 | tst CARG1, #HOOK_VMEVENT // No recording while in vmevent.
1840 | bne >5
1841 | // Decrement the hookcount for consistency, but always do the call.
1842 | ldr CARG2, [DISPATCH, #DISPATCH_GL(hookcount)]
1843 | tst CARG1, #HOOK_ACTIVE
1844 | bne >1
1845 | sub CARG2, CARG2, #1
1846 | tst CARG1, #LUA_MASKLINE|LUA_MASKCOUNT
1847 | strne CARG2, [DISPATCH, #DISPATCH_GL(hookcount)]
1848 | b >1
1849#endif
1850 |
1851 |->vm_rethook: // Dispatch target for return hooks.
1852 | ldrb CARG1, [DISPATCH, #DISPATCH_GL(hookmask)]
1853 | tst CARG1, #HOOK_ACTIVE // Hook already active?
1854 | beq >1
1855 |5: // Re-dispatch to static ins.
1856 | decode_OP OP, INS
1857 | add OP, DISPATCH, OP, lsl #2
1858 | ldr pc, [OP, #GG_DISP2STATIC]
1859 |
1860 |->vm_inshook: // Dispatch target for instr/line hooks.
1861 | ldrb CARG1, [DISPATCH, #DISPATCH_GL(hookmask)]
1862 | ldr CARG2, [DISPATCH, #DISPATCH_GL(hookcount)]
1863 | tst CARG1, #HOOK_ACTIVE // Hook already active?
1864 | bne <5
1865 | tst CARG1, #LUA_MASKLINE|LUA_MASKCOUNT
1866 | beq <5
1867 | subs CARG2, CARG2, #1
1868 | str CARG2, [DISPATCH, #DISPATCH_GL(hookcount)]
1869 | beq >1
1870 | tst CARG1, #LUA_MASKLINE
1871 | beq <5
1872 |1:
1873 | mov CARG1, L
1874 | str BASE, L->base
1875 | mov CARG2, PC
1876 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
1877 | bl extern lj_dispatch_ins // (lua_State *L, const BCIns *pc)
1878 |3:
1879 | ldr BASE, L->base
1880 |4: // Re-dispatch to static ins.
1881 | ldrb OP, [PC, #-4]
1882 | ldr INS, [PC, #-4]
1883 | add OP, DISPATCH, OP, lsl #2
1884 | ldr OP, [OP, #GG_DISP2STATIC]
1885 | decode_RA8 RA, INS
1886 | decode_RD RC, INS
1887 | bx OP
1888 |
1889 |->cont_hook: // Continue from hook yield.
1890 | ldr CARG1, [CARG4, #-24]
1891 | add PC, PC, #4
1892 | str CARG1, SAVE_MULTRES // Restore MULTRES for *M ins.
1893 | b <4
1894 |
1895 |->vm_hotloop: // Hot loop counter underflow.
1896#if LJ_HASJIT
1897 | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Same as curr_topL(L).
1898 | sub CARG1, DISPATCH, #-GG_DISP2J
1899 | str PC, SAVE_PC
1900 | ldr CARG3, LFUNC:CARG3->field_pc
1901 | mov CARG2, PC
1902 | str L, [DISPATCH, #DISPATCH_J(L)]
1903 | ldrb CARG3, [CARG3, #PC2PROTO(framesize)]
1904 | str BASE, L->base
1905 | add CARG3, BASE, CARG3, lsl #3
1906 | str CARG3, L->top
1907 | bl extern lj_trace_hot // (jit_State *J, const BCIns *pc)
1908 | b <3
1909#endif
1910 |
1911 |->vm_callhook: // Dispatch target for call hooks.
1912 | mov CARG2, PC
1913#if LJ_HASJIT
1914 | b >1
1915#endif
1916 |
1917 |->vm_hotcall: // Hot call counter underflow.
1918#if LJ_HASJIT
1919 | orr CARG2, PC, #1
1920 |1:
1921#endif
1922 | add CARG4, BASE, RC
1923 | str PC, SAVE_PC
1924 | mov CARG1, L
1925 | str BASE, L->base
1926 | sub RA, RA, BASE
1927 | str CARG4, L->top
1928 | bl extern lj_dispatch_call // (lua_State *L, const BCIns *pc)
1929 | // Returns ASMFunction.
1930 | ldr BASE, L->base
1931 | ldr CARG4, L->top
1932 | mov CARG2, #0
1933 | add RA, BASE, RA
1934 | sub NARGS8:RC, CARG4, BASE
1935 | str CARG2, SAVE_PC // Invalidate for subsequent line hook.
1936 | ldr LFUNC:CARG3, [BASE, FRAME_FUNC]
1937 | ldr INS, [PC, #-4]
1938 | bx CRET1
1939 |
1940 |//-----------------------------------------------------------------------
1941 |//-- Trace exit handler -------------------------------------------------
1942 |//-----------------------------------------------------------------------
1943 |
1944 |->vm_exit_handler:
1945#if LJ_HASJIT
1946 | sub sp, sp, #12
1947 | push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12}
1948 | ldr CARG1, [sp, #64] // Load original value of lr.
1949 | ldr DISPATCH, [lr] // Load DISPATCH.
1950 | add CARG3, sp, #64 // Recompute original value of sp.
1951 | mv_vmstate CARG4, EXIT
1952 | str CARG3, [sp, #52] // Store sp in RID_SP
1953 | st_vmstate CARG4
1954 | ldr CARG2, [CARG1, #-4]! // Get exit instruction.
1955 | str CARG1, [sp, #56] // Store exit pc in RID_LR and RID_PC.
1956 | str CARG1, [sp, #60]
1957 | lsl CARG2, CARG2, #8
1958 | add CARG1, CARG1, CARG2, asr #6
1959 | ldr CARG2, [lr, #4] // Load exit stub group offset.
1960 | sub CARG1, CARG1, lr
1961 | ldr L, [DISPATCH, #DISPATCH_GL(jit_L)]
1962 | add CARG1, CARG2, CARG1, lsr #2 // Compute exit number.
1963 | ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)]
1964 | str CARG1, [DISPATCH, #DISPATCH_J(exitno)]
1965 | mov CARG4, #0
1966 | str L, [DISPATCH, #DISPATCH_J(L)]
1967 | str BASE, L->base
1968 | str CARG4, [DISPATCH, #DISPATCH_GL(jit_L)]
1969 | sub CARG1, DISPATCH, #-GG_DISP2J
1970 | mov CARG2, sp
1971 | bl extern lj_trace_exit // (jit_State *J, ExitState *ex)
1972 | // Returns MULTRES (unscaled) or negated error code.
1973 | ldr CARG2, L->cframe
1974 | ldr BASE, L->base
1975 | bic CARG2, CARG2, #~CFRAME_RAWMASK // Use two steps: bic sp is deprecated.
1976 | mov sp, CARG2
1977 | ldr PC, SAVE_PC // Get SAVE_PC.
1978 | str L, SAVE_L // Set SAVE_L (on-trace resume/yield).
1979 | b >1
1980#endif
1981 |->vm_exit_interp:
1982 | // CARG1 = MULTRES or negated error code, BASE, PC and DISPATCH set.
1983#if LJ_HASJIT
1984 | ldr L, SAVE_L
1985 |1:
1986 | cmp CARG1, #0
1987 | blt >3 // Check for error from exit.
1988 | lsl RC, CARG1, #3
1989 | ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
1990 | str RC, SAVE_MULTRES
1991 | mov CARG3, #0
1992 | ldr CARG2, LFUNC:CARG2->field_pc
1993 | str CARG3, [DISPATCH, #DISPATCH_GL(jit_L)]
1994 | mv_vmstate CARG4, INTERP
1995 | ldr KBASE, [CARG2, #PC2PROTO(k)]
1996 | // Modified copy of ins_next which handles function header dispatch, too.
1997 | ldrb OP, [PC]
1998 | mov MASKR8, #255
1999 | ldr INS, [PC], #4
2000 | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
2001 | st_vmstate CARG4
2002 | cmp OP, #BC_FUNCF // Function header?
2003 | ldr OP, [DISPATCH, OP, lsl #2]
2004 | decode_RA8 RA, INS
2005 | lsrlo RC, INS, #16 // No: Decode operands A*8 and D.
2006 | subhs RC, RC, #8
2007 | addhs RA, RA, BASE // Yes: RA = BASE+framesize*8, RC = nargs*8
2008 | bx OP
2009 |
2010 |3: // Rethrow error from the right C frame.
2011 | rsb CARG2, CARG1, #0
2012 | mov CARG1, L
2013 | bl extern lj_err_throw // (lua_State *L, int errcode)
2014#endif
2015 |
2016 |//-----------------------------------------------------------------------
2017 |//-- Math helper functions ----------------------------------------------
2018 |//-----------------------------------------------------------------------
2019 |
2020 |// FP value rounding. Called from JIT code.
2021 |//
2022 |// double lj_vm_floor/ceil/trunc(double x);
2023 |.macro vm_round, func
2024 |->vm_ .. func:
2025 | lsl CARG3, CARG2, #1
2026 | adds RB, CARG3, #0x00200000
2027 | bpl >2 // |x| < 1?
2028 | mvn CARG4, #0x3cc
2029 | subs RB, CARG4, RB, asr #21 // 2^0: RB = 51, 2^51: RB = 0.
2030 | bxlo lr // |x| >= 2^52: done.
2031 | mvn CARG4, #1
2032 | bic CARG3, CARG1, CARG4, lsl RB // ztest = lo & ~lomask
2033 | and CARG1, CARG1, CARG4, lsl RB // lo &= lomask
2034 | subs RB, RB, #32
2035 | bicpl CARG4, CARG2, CARG4, lsl RB // |x| <= 2^20: ztest |= hi & ~himask
2036 | orrpl CARG3, CARG3, CARG4
2037 | mvnpl CARG4, #1
2038 | andpl CARG2, CARG2, CARG4, lsl RB // |x| <= 2^20: hi &= himask
2039 |.if "func" == "floor"
2040 | tst CARG3, CARG2, asr #31 // iszero = ((ztest & signmask) == 0)
2041 |.else
2042 | bics CARG3, CARG3, CARG2, asr #31 // iszero = ((ztest & ~signmask) == 0)
2043 |.endif
2044 | bxeq lr // iszero: done.
2045 | mvn CARG4, #1
2046 | cmp RB, #0
2047 | lslpl CARG3, CARG4, RB
2048 | mvnmi CARG3, #0
2049 | add RB, RB, #32
2050 | subs CARG1, CARG1, CARG4, lsl RB // lo = lo-lomask
2051 | sbc CARG2, CARG2, CARG3 // hi = hi-himask+carry
2052 | bx lr
2053 |
2054 |2: // |x| < 1:
2055 | orr CARG3, CARG3, CARG1 // ztest = (2*hi) | lo
2056 |.if "func" == "floor"
2057 | tst CARG3, CARG2, asr #31 // iszero = ((ztest & signmask) == 0)
2058 |.else
2059 | bics CARG3, CARG3, CARG2, asr #31 // iszero = ((ztest & ~signmask) == 0)
2060 |.endif
2061 | mov CARG1, #0 // lo = 0
2062 | and CARG2, CARG2, #0x80000000
2063 | ldrne CARG4, <9 // hi = sign(x) | (iszero ? 0.0 : 1.0)
2064 | orrne CARG2, CARG2, CARG4
2065 | bx lr
2066 |.endmacro
2067 |
2068 |9:
2069 | .long 0x3ff00000 // hiword(1.0)
2070 | vm_round floor
2071 | vm_round ceil
2072 |
2073 |->vm_trunc:
2074#if LJ_HASJIT
2075 | lsl CARG3, CARG2, #1
2076 | adds RB, CARG3, #0x00200000
2077 | andpl CARG2, CARG2, #0x80000000 // |x| < 1? hi = sign(x), lo = 0.
2078 | movpl CARG1, #0
2079 | bxpl lr
2080 | mvn CARG4, #0x3cc
2081 | subs RB, CARG4, RB, asr #21 // 2^0: RB = 51, 2^51: RB = 0.
2082 | bxlo lr // |x| >= 2^52: already done.
2083 | mvn CARG4, #1
2084 | and CARG1, CARG1, CARG4, lsl RB // lo &= lomask
2085 | subs RB, RB, #32
2086 | andpl CARG2, CARG2, CARG4, lsl RB // |x| <= 2^20: hi &= himask
2087 | bx lr
2088#endif
2089 |
2090 | // double lj_vm_mod(double dividend, double divisor);
2091 |->vm_mod:
2092 | push {r0, r1, r2, r3, r4, lr}
2093 | bl extern __aeabi_ddiv
2094 | bl ->vm_floor
2095 | ldrd CARG34, [sp, #8]
2096 | bl extern __aeabi_dmul
2097 | ldrd CARG34, [sp]
2098 | eor CARG2, CARG2, #0x80000000
2099 | bl extern __aeabi_dadd
2100 | add sp, sp, #20
2101 | pop {pc}
2102 |
2103 | // int lj_vm_modi(int dividend, int divisor);
2104 |->vm_modi:
2105 | ands RB, CARG1, #0x80000000
2106 | rsbmi CARG1, CARG1, #0 // a = |dividend|
2107 | eor RB, RB, CARG2, asr #1 // Keep signdiff and sign(divisor).
2108 | cmp CARG2, #0
2109 | rsbmi CARG2, CARG2, #0 // b = |divisor|
2110 | subs CARG4, CARG2, #1
2111 | cmpne CARG1, CARG2
2112 | moveq CARG1, #0 // if (b == 1 || a == b) a = 0
2113 | tsthi CARG2, CARG4
2114 | andeq CARG1, CARG1, CARG4 // else if ((b & (b-1)) == 0) a &= b-1
2115 | bls >1
2116 | // Use repeated subtraction to get the remainder.
2117 | clz CARG3, CARG1
2118 | clz CARG4, CARG2
2119 | sub CARG4, CARG4, CARG3
2120 | rsbs CARG3, CARG4, #31 // entry = (31-(clz(b)-clz(a)))*8
2121 | addne pc, pc, CARG3, lsl #3 // Duff's device.
2122 | nop
2123 {
2124 int i;
2125 for (i = 31; i >= 0; i--) {
2126 | cmp CARG1, CARG2, lsl #i
2127 | subhs CARG1, CARG1, CARG2, lsl #i
2128 }
2129 }
2130 |1:
2131 | cmp CARG1, #0
2132 | cmpne RB, #0
2133 | submi CARG1, CARG1, CARG2 // if (y != 0 && signdiff) y = y - b
2134 | eors CARG2, CARG1, RB, lsl #1
2135 | rsbmi CARG1, CARG1, #0 // if (sign(divisor) != sign(y)) y = -y
2136 | bx lr
2137 |
2138 |// Callable from C: double lj_vm_foldarith(double x, double y, int op)
2139 |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
2140 |// and basic math functions. ORDER ARITH
2141 |->vm_foldarith:
2142 | ldr OP, [sp]
2143 | cmp OP, #1
2144 | blo extern __aeabi_dadd
2145 | beq extern __aeabi_dsub
2146 | cmp OP, #3
2147 | blo extern __aeabi_dmul
2148 | beq extern __aeabi_ddiv
2149 | cmp OP, #5
2150 | blo ->vm_mod
2151 | beq extern pow
2152 | cmp OP, #7
2153 | eorlo CARG2, CARG2, #0x80000000
2154 | biceq CARG2, CARG2, #0x80000000
2155 | bxls lr
2156#if LJ_HASJIT
2157 | cmp OP, #9
2158 | blo extern atan2
2159 | beq >9 // No support needed for IR_LDEXP.
2160 | cmp OP, #11
2161 | bhi >9
2162 | push {r4, lr}
2163 | beq >1
2164 | // IR_MIN
2165 | bl extern __aeabi_cdcmple
2166 | movhi CARG1, CARG3
2167 | movhi CARG2, CARG4
2168 | pop {r4, pc}
2169 |9:
2170 | NYI // Bad op.
2171 |
2172 |1: // IR_MAX
2173 | bl extern __aeabi_cdcmple
2174 | movlo CARG1, CARG3
2175 | movlo CARG2, CARG4
2176 | pop {r4, pc}
2177#else
2178 | NYI // Other operations only needed by JIT compiler.
2179#endif
2180 |
2181 |//-----------------------------------------------------------------------
2182 |//-- Miscellaneous functions --------------------------------------------
2183 |//-----------------------------------------------------------------------
2184 |
2185 |//-----------------------------------------------------------------------
2186 |//-- FFI helper functions -----------------------------------------------
2187 |//-----------------------------------------------------------------------
2188 |
2189 |// Handler for callback functions.
2190 |// Saveregs already performed. Callback slot number in [sp], g in r12.
2191 |->vm_ffi_callback:
2192#if LJ_HASFFI
2193 |.type CTSTATE, CTState, PC
2194 | ldr CTSTATE, GL:r12->ctype_state
2195 | add DISPATCH, r12, #GG_G2DISP
2196 | strd CARG12, CTSTATE->cb.gpr[0]
2197 | strd CARG34, CTSTATE->cb.gpr[2]
2198 | ldr CARG4, [sp]
2199 | add CARG3, sp, #CFRAME_SIZE
2200 | mov CARG1, CTSTATE
2201 | lsr CARG4, CARG4, #3
2202 | str CARG3, CTSTATE->cb.stack
2203 | mov CARG2, sp
2204 | str CARG4, CTSTATE->cb.slot
2205 | str CTSTATE, SAVE_PC // Any value outside of bytecode is ok.
2206 | bl extern lj_ccallback_enter // (CTState *cts, void *cf)
2207 | // Returns lua_State *.
2208 | ldr BASE, L:CRET1->base
2209 | mv_vmstate CARG2, INTERP
2210 | ldr RC, L:CRET1->top
2211 | mov MASKR8, #255
2212 | ldr LFUNC:CARG3, [BASE, FRAME_FUNC]
2213 | mov L, CRET1
2214 | sub RC, RC, BASE
2215 | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
2216 | st_vmstate CARG2
2217 | ins_callt
2218#endif
2219 |
2220 |->cont_ffi_callback: // Return from FFI callback.
2221#if LJ_HASFFI
2222 | ldr CTSTATE, [DISPATCH, #DISPATCH_GL(ctype_state)]
2223 | str BASE, L->base
2224 | str CARG4, L->top
2225 | str L, CTSTATE->L
2226 | mov CARG1, CTSTATE
2227 | mov CARG2, RA
2228 | bl extern lj_ccallback_leave // (CTState *cts, TValue *o)
2229 | ldrd CARG12, CTSTATE->cb.gpr[0]
2230 | b ->vm_leave_unw
2231#endif
2232 |
2233 |->vm_ffi_call: // Call C function via FFI.
2234 | // Caveat: needs special frame unwinding, see below.
2235#if LJ_HASFFI
2236 | .type CCSTATE, CCallState, r4
2237 | push {CCSTATE, r5, r11, lr}
2238 | mov CCSTATE, CARG1
2239 | ldr CARG1, CCSTATE:CARG1->spadj
2240 | ldrb CARG2, CCSTATE->nsp
2241 | add CARG3, CCSTATE, #offsetof(CCallState, stack)
2242 | mov r11, sp
2243 | sub sp, sp, CARG1 // Readjust stack.
2244 | subs CARG2, CARG2, #1
2245 | ldr RB, CCSTATE->func
2246 | bmi >2
2247 |1: // Copy stack slots.
2248 | ldr CARG4, [CARG3, CARG2, lsl #2]
2249 | str CARG4, [sp, CARG2, lsl #2]
2250 | subs CARG2, CARG2, #1
2251 | bpl <1
2252 |2:
2253 | ldr CARG1, CCSTATE->gpr[0]
2254 | ldr CARG2, CCSTATE->gpr[1]
2255 | ldr CARG3, CCSTATE->gpr[2]
2256 | ldr CARG4, CCSTATE->gpr[3]
2257 | blx RB
2258 | mov sp, r11
2259 | str CRET1, CCSTATE->gpr[0]
2260 | str CRET2, CCSTATE->gpr[1]
2261 | pop {CCSTATE, r5, r11, pc}
2262#endif
2263 |// Note: vm_ffi_call must be the last function in this object file!
2264 |
2265 |//-----------------------------------------------------------------------
2266}
2267
2268/* Generate the code for a single instruction. */
2269static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2270{
2271 int vk = 0;
2272 |=>defop:
2273
2274 switch (op) {
2275
2276 /* -- Comparison ops ---------------------------------------------------- */
2277
2278 /* Remember: all ops branch for a true comparison, fall through otherwise. */
2279
2280 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
2281 | // RA = src1*8, RC = src2, JMP with RC = target
2282 | lsl RC, RC, #3
2283 | ldrd CARG12, [RA, BASE]!
2284 | ldrh RB, [PC, #2]
2285 | ldrd CARG34, [RC, BASE]!
2286 | add PC, PC, #4
2287 | add RB, PC, RB, lsl #2
2288 | checktp CARG2, LJ_TISNUM
2289 | bne >3
2290 | checktp CARG4, LJ_TISNUM
2291 | bne >4
2292 | cmp CARG1, CARG3
2293 if (op == BC_ISLT) {
2294 | sublt PC, RB, #0x20000
2295 } else if (op == BC_ISGE) {
2296 | subge PC, RB, #0x20000
2297 } else if (op == BC_ISLE) {
2298 | suble PC, RB, #0x20000
2299 } else {
2300 | subgt PC, RB, #0x20000
2301 }
2302 |1:
2303 | ins_next
2304 |
2305 |3: // CARG12 is not an integer.
2306 | bhi ->vmeta_comp
2307 | // CARG12 is a number.
2308 | checktp CARG4, LJ_TISNUM
2309 | movlo RA, RB // Save RB.
2310 | blo >5
2311 | // CARG12 is a number, CARG3 is an integer.
2312 | mov CARG1, CARG3
2313 | mov RC, RA
2314 | mov RA, RB // Save RB.
2315 | bl extern __aeabi_i2d
2316 | mov CARG3, CARG1
2317 | mov CARG4, CARG2
2318 | ldrd CARG12, [RC] // Restore first operand.
2319 | b >5
2320 |4: // CARG1 is an integer, CARG34 is not an integer.
2321 | bhi ->vmeta_comp
2322 | // CARG1 is an integer, CARG34 is a number
2323 | mov RA, RB // Save RB.
2324 | bl extern __aeabi_i2d
2325 | ldrd CARG34, [RC] // Restore second operand.
2326 |5: // CARG12 and CARG34 are numbers.
2327 | bl extern __aeabi_cdcmple
2328 | // To preserve NaN semantics GE/GT branch on unordered, but LT/LE don't.
2329 if (op == BC_ISLT) {
2330 | sublo PC, RA, #0x20000
2331 } else if (op == BC_ISGE) {
2332 | subhs PC, RA, #0x20000
2333 } else if (op == BC_ISLE) {
2334 | subls PC, RA, #0x20000
2335 } else {
2336 | subhi PC, RA, #0x20000
2337 }
2338 | b <1
2339 break;
2340
2341 case BC_ISEQV: case BC_ISNEV:
2342 vk = op == BC_ISEQV;
2343 | // RA = src1*8, RC = src2, JMP with RC = target
2344 | lsl RC, RC, #3
2345 | ldrd CARG12, [RA, BASE]!
2346 | ldrh RB, [PC, #2]
2347 | ldrd CARG34, [RC, BASE]!
2348 | add PC, PC, #4
2349 | add RB, PC, RB, lsl #2
2350 | checktp CARG2, LJ_TISNUM
2351 | cmnls CARG4, #-LJ_TISNUM
2352 if (vk) {
2353 | bls ->BC_ISEQN_Z
2354 } else {
2355 | bls ->BC_ISNEN_Z
2356 }
2357 | // Either or both types are not numbers.
2358 if (LJ_HASFFI) {
2359 | checktp CARG2, LJ_TCDATA
2360 | checktpne CARG4, LJ_TCDATA
2361 | beq ->vmeta_equal_cd
2362 }
2363 | cmp CARG2, CARG4 // Compare types.
2364 | bne >2 // Not the same type?
2365 | checktp CARG2, LJ_TISPRI
2366 | bhs >1 // Same type and primitive type?
2367 |
2368 | // Same types and not a primitive type. Compare GCobj or pvalue.
2369 | cmp CARG1, CARG3
2370 if (vk) {
2371 | bne >3 // Different GCobjs or pvalues?
2372 |1: // Branch if same.
2373 | sub PC, RB, #0x20000
2374 |2: // Different.
2375 | ins_next
2376 |3:
2377 | checktp CARG2, LJ_TISTABUD
2378 | bhi <2 // Different objects and not table/ud?
2379 } else {
2380 | beq >1 // Same GCobjs or pvalues?
2381 | checktp CARG2, LJ_TISTABUD
2382 | bhi >2 // Different objects and not table/ud?
2383 }
2384 | // Different tables or userdatas. Need to check __eq metamethod.
2385 | // Field metatable must be at same offset for GCtab and GCudata!
2386 | ldr TAB:RA, TAB:CARG1->metatable
2387 | cmp TAB:RA, #0
2388 if (vk) {
2389 | beq <2 // No metatable?
2390 } else {
2391 | beq >2 // No metatable?
2392 }
2393 | ldrb RA, TAB:RA->nomm
2394 | mov CARG4, #1-vk // ne = 0 or 1.
2395 | mov CARG2, CARG1
2396 | tst RA, #1<<MM_eq
2397 | beq ->vmeta_equal // 'no __eq' flag not set?
2398 if (vk) {
2399 | b <2
2400 } else {
2401 |2: // Branch if different.
2402 | sub PC, RB, #0x20000
2403 |1: // Same.
2404 | ins_next
2405 }
2406 break;
2407
2408 case BC_ISEQS: case BC_ISNES:
2409 vk = op == BC_ISEQS;
2410 | // RA = src*8, RC = str_const (~), JMP with RC = target
2411 | mvn RC, RC
2412 | ldrd CARG12, [BASE, RA]
2413 | ldrh RB, [PC, #2]
2414 | ldr STR:CARG3, [KBASE, RC, lsl #2]
2415 | add PC, PC, #4
2416 | add RB, PC, RB, lsl #2
2417 | checktp CARG2, LJ_TSTR
2418 if (LJ_HASFFI) {
2419 | bne >7
2420 | cmp CARG1, CARG3
2421 } else {
2422 | cmpeq CARG1, CARG3
2423 }
2424 if (vk) {
2425 | subeq PC, RB, #0x20000
2426 |1:
2427 } else {
2428 |1:
2429 | subne PC, RB, #0x20000
2430 }
2431 | ins_next
2432 |
2433 if (LJ_HASFFI) {
2434 |7:
2435 | checktp CARG2, LJ_TCDATA
2436 | bne <1
2437 | b ->vmeta_equal_cd
2438 }
2439 break;
2440
2441 case BC_ISEQN: case BC_ISNEN:
2442 vk = op == BC_ISEQN;
2443 | // RA = src*8, RC = num_const (~), JMP with RC = target
2444 | lsl RC, RC, #3
2445 | ldrd CARG12, [RA, BASE]!
2446 | ldrh RB, [PC, #2]
2447 | ldrd CARG34, [RC, KBASE]!
2448 | add PC, PC, #4
2449 | add RB, PC, RB, lsl #2
2450 if (vk) {
2451 |->BC_ISEQN_Z:
2452 } else {
2453 |->BC_ISNEN_Z:
2454 }
2455 | checktp CARG2, LJ_TISNUM
2456 | bne >3
2457 | checktp CARG4, LJ_TISNUM
2458 | bne >4
2459 | cmp CARG1, CARG3
2460 if (vk) {
2461 | subeq PC, RB, #0x20000
2462 |1:
2463 } else {
2464 |1:
2465 | subne PC, RB, #0x20000
2466 }
2467 |2:
2468 | ins_next
2469 |
2470 |3: // CARG12 is not an integer.
2471 if (LJ_HASFFI) {
2472 | bhi >7
2473 } else {
2474 if (!vk) {
2475 | subhi PC, RB, #0x20000
2476 }
2477 | bhi <2
2478 }
2479 | // CARG12 is a number.
2480 | checktp CARG4, LJ_TISNUM
2481 | movlo RA, RB // Save RB.
2482 | blo >5
2483 | // CARG12 is a number, CARG3 is an integer.
2484 | mov CARG1, CARG3
2485 | mov RC, RA
2486 |4: // CARG1 is an integer, CARG34 is a number.
2487 | mov RA, RB // Save RB.
2488 | bl extern __aeabi_i2d
2489 | ldrd CARG34, [RC] // Restore other operand.
2490 |5: // CARG12 and CARG34 are numbers.
2491 | bl extern __aeabi_cdcmpeq
2492 if (vk) {
2493 | subeq PC, RA, #0x20000
2494 } else {
2495 | subne PC, RA, #0x20000
2496 }
2497 | b <2
2498 |
2499 if (LJ_HASFFI) {
2500 |7:
2501 | checktp CARG2, LJ_TCDATA
2502 | bne <1
2503 | b ->vmeta_equal_cd
2504 }
2505 break;
2506
2507 case BC_ISEQP: case BC_ISNEP:
2508 vk = op == BC_ISEQP;
2509 | // RA = src*8, RC = primitive_type (~), JMP with RC = target
2510 | ldrd CARG12, [BASE, RA]
2511 | ldrh RB, [PC, #2]
2512 | add PC, PC, #4
2513 | mvn RC, RC
2514 | add RB, PC, RB, lsl #2
2515 if (LJ_HASFFI) {
2516 | checktp CARG2, LJ_TCDATA
2517 | beq ->vmeta_equal_cd
2518 }
2519 | cmp CARG2, RC
2520 if (vk) {
2521 | subeq PC, RB, #0x20000
2522 } else {
2523 | subne PC, RB, #0x20000
2524 }
2525 | ins_next
2526 break;
2527
2528 /* -- Unary test and copy ops ------------------------------------------- */
2529
2530 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
2531 | // RA = dst*8 or unused, RC = src, JMP with RC = target
2532 | add RC, BASE, RC, lsl #3
2533 | ldrh RB, [PC, #2]
2534 | ldrd CARG12, [RC]
2535 | add PC, PC, #4
2536 | add RB, PC, RB, lsl #2
2537 | checktp CARG2, LJ_TTRUE
2538 if (op == BC_ISTC || op == BC_IST) {
2539 | subls PC, RB, #0x20000
2540 if (op == BC_ISTC) {
2541 | strdls CARG12, [BASE, RA]
2542 }
2543 } else {
2544 | subhi PC, RB, #0x20000
2545 if (op == BC_ISFC) {
2546 | strdhi CARG12, [BASE, RA]
2547 }
2548 }
2549 | ins_next
2550 break;
2551
2552 /* -- Unary ops --------------------------------------------------------- */
2553
2554 case BC_MOV:
2555 | // RA = dst*8, RC = src
2556 | lsl RC, RC, #3
2557 | ins_next1
2558 | ldrd CARG12, [BASE, RC]
2559 | ins_next2
2560 | strd CARG12, [BASE, RA]
2561 | ins_next3
2562 break;
2563 case BC_NOT:
2564 | // RA = dst*8, RC = src
2565 | add RC, BASE, RC, lsl #3
2566 | ins_next1
2567 | ldr CARG1, [RC, #4]
2568 | add RA, BASE, RA
2569 | ins_next2
2570 | checktp CARG1, LJ_TTRUE
2571 | mvnls CARG2, #~LJ_TFALSE
2572 | mvnhi CARG2, #~LJ_TTRUE
2573 | str CARG2, [RA, #4]
2574 | ins_next3
2575 break;
2576 case BC_UNM:
2577 | // RA = dst*8, RC = src
2578 | lsl RC, RC, #3
2579 | ldrd CARG12, [BASE, RC]
2580 | ins_next1
2581 | ins_next2
2582 | checktp CARG2, LJ_TISNUM
2583 | bhi ->vmeta_unm
2584 | eorne CARG2, CARG2, #0x80000000
2585 | bne >5
2586 | rsbseq CARG1, CARG1, #0
2587 | ldrdvs CARG12, >9
2588 |5:
2589 | strd CARG12, [BASE, RA]
2590 | ins_next3
2591 |
2592 |.align 8
2593 |9:
2594 | .long 0x00000000, 0x41e00000 // 2^31.
2595 break;
2596 case BC_LEN:
2597 | // RA = dst*8, RC = src
2598 | lsl RC, RC, #3
2599 | ldrd CARG12, [BASE, RC]
2600 | checkstr CARG2, >2
2601 | ldr CARG1, STR:CARG1->len
2602 |1:
2603 | mvn CARG2, #~LJ_TISNUM
2604 | ins_next1
2605 | ins_next2
2606 | strd CARG12, [BASE, RA]
2607 | ins_next3
2608 |2:
2609 | checktab CARG2, ->vmeta_len
2610#ifdef LUAJIT_ENABLE_LUA52COMPAT
2611 | ldr TAB:CARG3, TAB:CARG1->metatable
2612 | cmp TAB:CARG3, #0
2613 | bne >9
2614 |3:
2615#endif
2616 |->BC_LEN_Z:
2617 | IOS mov RC, BASE
2618 | bl extern lj_tab_len // (GCtab *t)
2619 | // Returns uint32_t (but less than 2^31).
2620 | IOS mov BASE, RC
2621 | b <1
2622#ifdef LUAJIT_ENABLE_LUA52COMPAT
2623 |9:
2624 | ldrb CARG4, TAB:CARG3->nomm
2625 | tst CARG4, #1<<MM_len
2626 | bne <3 // 'no __len' flag set: done.
2627 | b ->vmeta_len
2628#endif
2629 break;
2630
2631 /* -- Binary ops -------------------------------------------------------- */
2632
2633 |.macro ins_arithcheck, cond, ncond, target
2634 ||if (vk == 1) {
2635 | cmn CARG4, #-LJ_TISNUM
2636 | cmn..cond CARG2, #-LJ_TISNUM
2637 ||} else {
2638 | cmn CARG2, #-LJ_TISNUM
2639 | cmn..cond CARG4, #-LJ_TISNUM
2640 ||}
2641 | b..ncond target
2642 |.endmacro
2643 |.macro ins_arithcheck_int, target
2644 | ins_arithcheck eq, ne, target
2645 |.endmacro
2646 |.macro ins_arithcheck_num, target
2647 | ins_arithcheck lo, hs, target
2648 |.endmacro
2649 |
2650 |.macro ins_arithpre
2651 | decode_RB8 RB, INS
2652 | decode_RC8 RC, INS
2653 | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8
2654 ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2655 ||switch (vk) {
2656 ||case 0:
2657 | ldrd CARG12, [BASE, RB]
2658 | ldrd CARG34, [KBASE, RC]
2659 || break;
2660 ||case 1:
2661 | ldrd CARG34, [BASE, RB]
2662 | ldrd CARG12, [KBASE, RC]
2663 || break;
2664 ||default:
2665 | ldrd CARG12, [BASE, RB]
2666 | ldrd CARG34, [BASE, RC]
2667 || break;
2668 ||}
2669 |.endmacro
2670 |
2671 |.macro ins_arithfallback, ins
2672 ||switch (vk) {
2673 ||case 0:
2674 | ins ->vmeta_arith_vn
2675 || break;
2676 ||case 1:
2677 | ins ->vmeta_arith_nv
2678 || break;
2679 ||default:
2680 | ins ->vmeta_arith_vv
2681 || break;
2682 ||}
2683 |.endmacro
2684 |
2685 |.macro ins_arithdn, intins, fpcall
2686 | ins_arithpre
2687 |.if "intins" ~= "vm_modi"
2688 | ins_next1
2689 |.endif
2690 | ins_arithcheck_int >5
2691 |.if "intins" == "smull"
2692 | smull CARG1, RC, CARG3, CARG1
2693 | cmp RC, CARG1, asr #31
2694 | ins_arithfallback bne
2695 |.elif "intins" == "vm_modi"
2696 | movs CARG2, CARG3
2697 | ins_arithfallback beq
2698 | bl ->vm_modi
2699 | mvn CARG2, #~LJ_TISNUM
2700 |.else
2701 | intins CARG1, CARG1, CARG3
2702 | ins_arithfallback bvs
2703 |.endif
2704 |4:
2705 |.if "intins" == "vm_modi"
2706 | ins_next1
2707 |.endif
2708 | ins_next2
2709 | strd CARG12, [BASE, RA]
2710 | ins_next3
2711 |5: // FP variant.
2712 | ins_arithfallback ins_arithcheck_num
2713 |.if "intins" == "vm_modi"
2714 | bl fpcall
2715 |.else
2716 | bl fpcall
2717 | ins_next1
2718 |.endif
2719 | b <4
2720 |.endmacro
2721 |
2722 |.macro ins_arithfp, fpcall
2723 | ins_arithpre
2724 | ins_arithfallback ins_arithcheck_num
2725 |.if "fpcall" == "extern pow"
2726 | IOS mov RC, BASE
2727 | bl fpcall
2728 | IOS mov BASE, RC
2729 |.else
2730 | bl fpcall
2731 |.endif
2732 | ins_next1
2733 | ins_next2
2734 | strd CARG12, [BASE, RA]
2735 | ins_next3
2736 |.endmacro
2737
2738 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
2739 | ins_arithdn adds, extern __aeabi_dadd
2740 break;
2741 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
2742 | ins_arithdn subs, extern __aeabi_dsub
2743 break;
2744 case BC_MULVN: case BC_MULNV: case BC_MULVV:
2745 | ins_arithdn smull, extern __aeabi_dmul
2746 break;
2747 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
2748 | ins_arithfp extern __aeabi_ddiv
2749 break;
2750 case BC_MODVN: case BC_MODNV: case BC_MODVV:
2751 | ins_arithdn vm_modi, ->vm_mod
2752 break;
2753 case BC_POW:
2754 | // NYI: (partial) integer arithmetic.
2755 | ins_arithfp extern pow
2756 break;
2757
2758 case BC_CAT:
2759 | decode_RB8 RC, INS
2760 | decode_RC8 RB, INS
2761 | // RA = dst*8, RC = src_start*8, RB = src_end*8 (note: RB/RC swapped!)
2762 | sub CARG3, RB, RC
2763 | str BASE, L->base
2764 | add CARG2, BASE, RB
2765 |->BC_CAT_Z:
2766 | // RA = dst*8, RC = src_start*8, CARG2 = top-1
2767 | mov CARG1, L
2768 | str PC, SAVE_PC
2769 | lsr CARG3, CARG3, #3
2770 | bl extern lj_meta_cat // (lua_State *L, TValue *top, int left)
2771 | // Returns NULL (finished) or TValue * (metamethod).
2772 | ldr BASE, L->base
2773 | cmp CRET1, #0
2774 | bne ->vmeta_binop
2775 | ldrd CARG34, [BASE, RC]
2776 | ins_next1
2777 | ins_next2
2778 | strd CARG34, [BASE, RA] // Copy result to RA.
2779 | ins_next3
2780 break;
2781
2782 /* -- Constant ops ------------------------------------------------------ */
2783
2784 case BC_KSTR:
2785 | // RA = dst*8, RC = str_const (~)
2786 | mvn RC, RC
2787 | ins_next1
2788 | ldr CARG1, [KBASE, RC, lsl #2]
2789 | mvn CARG2, #~LJ_TSTR
2790 | ins_next2
2791 | strd CARG12, [BASE, RA]
2792 | ins_next3
2793 break;
2794 case BC_KCDATA:
2795#if LJ_HASFFI
2796 | // RA = dst*8, RC = cdata_const (~)
2797 | mvn RC, RC
2798 | ins_next1
2799 | ldr CARG1, [KBASE, RC, lsl #2]
2800 | mvn CARG2, #~LJ_TCDATA
2801 | ins_next2
2802 | strd CARG12, [BASE, RA]
2803 | ins_next3
2804#endif
2805 break;
2806 case BC_KSHORT:
2807 | // RA = dst*8, (RC = int16_literal)
2808 | mov CARG1, INS, asr #16 // Refetch sign-extended reg.
2809 | mvn CARG2, #~LJ_TISNUM
2810 | ins_next1
2811 | ins_next2
2812 | strd CARG12, [BASE, RA]
2813 | ins_next3
2814 break;
2815 case BC_KNUM:
2816 | // RA = dst*8, RC = num_const
2817 | lsl RC, RC, #3
2818 | ins_next1
2819 | ldrd CARG12, [KBASE, RC]
2820 | ins_next2
2821 | strd CARG12, [BASE, RA]
2822 | ins_next3
2823 break;
2824 case BC_KPRI:
2825 | // RA = dst*8, RC = primitive_type (~)
2826 | add RA, BASE, RA
2827 | mvn RC, RC
2828 | ins_next1
2829 | ins_next2
2830 | str RC, [RA, #4]
2831 | ins_next3
2832 break;
2833 case BC_KNIL:
2834 | // RA = base*8, RC = end
2835 | add RA, BASE, RA
2836 | add RC, BASE, RC, lsl #3
2837 | mvn CARG1, #~LJ_TNIL
2838 | str CARG1, [RA, #4]
2839 | add RA, RA, #8
2840 |1:
2841 | str CARG1, [RA, #4]
2842 | cmp RA, RC
2843 | add RA, RA, #8
2844 | blt <1
2845 | ins_next_
2846 break;
2847
2848 /* -- Upvalue and function ops ------------------------------------------ */
2849
2850 case BC_UGET:
2851 | // RA = dst*8, RC = uvnum
2852 | ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
2853 | lsl RC, RC, #2
2854 | add RC, RC, #offsetof(GCfuncL, uvptr)
2855 | ldr UPVAL:CARG2, [LFUNC:CARG2, RC]
2856 | ldr CARG2, UPVAL:CARG2->v
2857 | ldrd CARG34, [CARG2]
2858 | ins_next1
2859 | ins_next2
2860 | strd CARG34, [BASE, RA]
2861 | ins_next3
2862 break;
2863 case BC_USETV:
2864 | // RA = uvnum*8, RC = src
2865 | ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
2866 | lsr RA, RA, #1
2867 | add RA, RA, #offsetof(GCfuncL, uvptr)
2868 | lsl RC, RC, #3
2869 | ldr UPVAL:CARG2, [LFUNC:CARG2, RA]
2870 | ldrd CARG34, [BASE, RC]
2871 | ldrb RB, UPVAL:CARG2->marked
2872 | ldrb RC, UPVAL:CARG2->closed
2873 | ldr CARG2, UPVAL:CARG2->v
2874 | tst RB, #LJ_GC_BLACK // isblack(uv)
2875 | add RB, CARG4, #-LJ_TISGCV
2876 | cmpne RC, #0
2877 | strd CARG34, [CARG2]
2878 | bne >2 // Upvalue is closed and black?
2879 |1:
2880 | ins_next
2881 |
2882 |2: // Check if new value is collectable.
2883 | cmn RB, #-(LJ_TISNUM - LJ_TISGCV)
2884 | ldrbhi RC, GCOBJ:CARG3->gch.marked
2885 | bls <1 // tvisgcv(v)
2886 | sub CARG1, DISPATCH, #-GG_DISP2G
2887 | tst RC, #LJ_GC_WHITES
2888 | // Crossed a write barrier. Move the barrier forward.
2889 if (LJ_TARGET_OSX) {
2890 | beq <1
2891 | mov RC, BASE
2892 | bl extern lj_gc_barrieruv // (global_State *g, TValue *tv)
2893 | mov BASE, RC
2894 } else {
2895 | blne extern lj_gc_barrieruv // (global_State *g, TValue *tv)
2896 }
2897 | b <1
2898 break;
2899 case BC_USETS:
2900 | // RA = uvnum*8, RC = str_const (~)
2901 | ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
2902 | lsr RA, RA, #1
2903 | add RA, RA, #offsetof(GCfuncL, uvptr)
2904 | mvn RC, RC
2905 | ldr UPVAL:CARG2, [LFUNC:CARG2, RA]
2906 | ldr STR:CARG3, [KBASE, RC, lsl #2]
2907 | mvn CARG4, #~LJ_TSTR
2908 | ldrb RB, UPVAL:CARG2->marked
2909 | ldr CARG2, UPVAL:CARG2->v
2910 | ldrb RC, UPVAL:CARG2->closed
2911 | tst RB, #LJ_GC_BLACK // isblack(uv)
2912 | ldrb RB, STR:CARG3->marked
2913 | strd CARG34, [CARG2]
2914 | bne >2
2915 |1:
2916 | ins_next
2917 |
2918 |2: // Check if string is white and ensure upvalue is closed.
2919 | tst RB, #LJ_GC_WHITES // iswhite(str)
2920 | cmpne RC, #0
2921 | sub CARG1, DISPATCH, #-GG_DISP2G
2922 | // Crossed a write barrier. Move the barrier forward.
2923 if (LJ_TARGET_OSX) {
2924 | beq <1
2925 | mov RC, BASE
2926 | bl extern lj_gc_barrieruv // (global_State *g, TValue *tv)
2927 | mov BASE, RC
2928 } else {
2929 | blne extern lj_gc_barrieruv // (global_State *g, TValue *tv)
2930 }
2931 | b <1
2932 break;
2933 case BC_USETN:
2934 | // RA = uvnum*8, RC = num_const
2935 | ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
2936 | lsr RA, RA, #1
2937 | add RA, RA, #offsetof(GCfuncL, uvptr)
2938 | lsl RC, RC, #3
2939 | ldr UPVAL:CARG2, [LFUNC:CARG2, RA]
2940 | ldrd CARG34, [KBASE, RC]
2941 | ldr CARG2, UPVAL:CARG2->v
2942 | ins_next1
2943 | ins_next2
2944 | strd CARG34, [CARG2]
2945 | ins_next3
2946 break;
2947 case BC_USETP:
2948 | // RA = uvnum*8, RC = primitive_type (~)
2949 | ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
2950 | lsr RA, RA, #1
2951 | add RA, RA, #offsetof(GCfuncL, uvptr)
2952 | ldr UPVAL:CARG2, [LFUNC:CARG2, RA]
2953 | mvn RC, RC
2954 | ldr CARG2, UPVAL:CARG2->v
2955 | ins_next1
2956 | ins_next2
2957 | str RC, [CARG2, #4]
2958 | ins_next3
2959 break;
2960
2961 case BC_UCLO:
2962 | // RA = level*8, RC = target
2963 | ldr CARG3, L->openupval
2964 | add RC, PC, RC, lsl #2
2965 | str BASE, L->base
2966 | cmp CARG3, #0
2967 | sub PC, RC, #0x20000
2968 | beq >1
2969 | mov CARG1, L
2970 | add CARG2, BASE, RA
2971 | bl extern lj_func_closeuv // (lua_State *L, TValue *level)
2972 | ldr BASE, L->base
2973 |1:
2974 | ins_next
2975 break;
2976
2977 case BC_FNEW:
2978 | // RA = dst*8, RC = proto_const (~) (holding function prototype)
2979 | mvn RC, RC
2980 | str BASE, L->base
2981 | ldr CARG2, [KBASE, RC, lsl #2]
2982 | str PC, SAVE_PC
2983 | ldr CARG3, [BASE, FRAME_FUNC]
2984 | mov CARG1, L
2985 | // (lua_State *L, GCproto *pt, GCfuncL *parent)
2986 | bl extern lj_func_newL_gc
2987 | // Returns GCfuncL *.
2988 | ldr BASE, L->base
2989 | mvn CARG2, #~LJ_TFUNC
2990 | ins_next1
2991 | ins_next2
2992 | strd CARG12, [BASE, RA]
2993 | ins_next3
2994 break;
2995
2996 /* -- Table ops --------------------------------------------------------- */
2997
2998 case BC_TNEW:
2999 case BC_TDUP:
3000 | // RA = dst*8, RC = (hbits|asize) | tab_const (~)
3001 if (op == BC_TDUP) {
3002 | mvn RC, RC
3003 }
3004 | ldr CARG3, [DISPATCH, #DISPATCH_GL(gc.total)]
3005 | ldr CARG4, [DISPATCH, #DISPATCH_GL(gc.threshold)]
3006 | str BASE, L->base
3007 | str PC, SAVE_PC
3008 | cmp CARG3, CARG4
3009 | mov CARG1, L
3010 | bhs >5
3011 |1:
3012 if (op == BC_TNEW) {
3013 | lsl CARG2, RC, #21
3014 | lsr CARG3, RC, #11
3015 | asr RC, CARG2, #21
3016 | lsr CARG2, CARG2, #21
3017 | cmn RC, #1
3018 | addeq CARG2, CARG2, #2
3019 | bl extern lj_tab_new // (lua_State *L, int32_t asize, uint32_t hbits)
3020 | // Returns GCtab *.
3021 } else {
3022 | ldr CARG2, [KBASE, RC, lsl #2]
3023 | bl extern lj_tab_dup // (lua_State *L, Table *kt)
3024 | // Returns GCtab *.
3025 }
3026 | ldr BASE, L->base
3027 | mvn CARG2, #~LJ_TTAB
3028 | ins_next1
3029 | ins_next2
3030 | strd CARG12, [BASE, RA]
3031 | ins_next3
3032 |5:
3033 | bl extern lj_gc_step_fixtop // (lua_State *L)
3034 | mov CARG1, L
3035 | b <1
3036 break;
3037
3038 case BC_GGET:
3039 | // RA = dst*8, RC = str_const (~)
3040 case BC_GSET:
3041 | // RA = dst*8, RC = str_const (~)
3042 | ldr LFUNC:CARG2, [BASE, FRAME_FUNC]
3043 | mvn RC, RC
3044 | ldr TAB:CARG1, LFUNC:CARG2->env
3045 | ldr STR:RC, [KBASE, RC, lsl #2]
3046 if (op == BC_GGET) {
3047 | b ->BC_TGETS_Z
3048 } else {
3049 | b ->BC_TSETS_Z
3050 }
3051 break;
3052
3053 case BC_TGETV:
3054 | decode_RB8 RB, INS
3055 | decode_RC8 RC, INS
3056 | // RA = dst*8, RB = table*8, RC = key*8
3057 | ldrd TAB:CARG12, [BASE, RB]
3058 | ldrd CARG34, [BASE, RC]
3059 | checktab CARG2, ->vmeta_tgetv // STALL: load CARG12.
3060 | checktp CARG4, LJ_TISNUM // Integer key?
3061 | ldreq CARG4, TAB:CARG1->array
3062 | ldreq CARG2, TAB:CARG1->asize
3063 | bne >9
3064 |
3065 | add CARG4, CARG4, CARG3, lsl #3
3066 | cmp CARG3, CARG2 // In array part?
3067 | ldrdlo CARG34, [CARG4]
3068 | bhs ->vmeta_tgetv
3069 | ins_next1 // Overwrites RB!
3070 | checktp CARG4, LJ_TNIL
3071 | beq >5
3072 |1:
3073 | ins_next2
3074 | strd CARG34, [BASE, RA]
3075 | ins_next3
3076 |
3077 |5: // Check for __index if table value is nil.
3078 | ldr TAB:CARG2, TAB:CARG1->metatable
3079 | cmp TAB:CARG2, #0
3080 | beq <1 // No metatable: done.
3081 | ldrb CARG2, TAB:CARG2->nomm
3082 | tst CARG2, #1<<MM_index
3083 | bne <1 // 'no __index' flag set: done.
3084 | decode_RB8 RB, INS // Restore RB.
3085 | b ->vmeta_tgetv
3086 |
3087 |9:
3088 | checktp CARG4, LJ_TSTR // String key?
3089 | moveq STR:RC, CARG3
3090 | beq ->BC_TGETS_Z
3091 | b ->vmeta_tgetv
3092 break;
3093 case BC_TGETS:
3094 | decode_RB8 RB, INS
3095 | and RC, RC, #255
3096 | // RA = dst*8, RB = table*8, RC = str_const (~)
3097 | ldrd CARG12, [BASE, RB]
3098 | mvn RC, RC
3099 | ldr STR:RC, [KBASE, RC, lsl #2] // STALL: early RC.
3100 | checktab CARG2, ->vmeta_tgets1
3101 |->BC_TGETS_Z:
3102 | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8
3103 | ldr CARG3, TAB:CARG1->hmask
3104 | ldr CARG4, STR:RC->hash
3105 | ldr NODE:INS, TAB:CARG1->node
3106 | mov TAB:RB, TAB:CARG1
3107 | and CARG3, CARG3, CARG4 // idx = str->hash & tab->hmask
3108 | add CARG3, CARG3, CARG3, lsl #1
3109 | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8
3110 |1:
3111 | ldrd CARG12, NODE:INS->key // STALL: early NODE:INS.
3112 | ldrd CARG34, NODE:INS->val
3113 | ldr NODE:INS, NODE:INS->next
3114 | cmp CARG1, STR:RC
3115 | checktpeq CARG2, LJ_TSTR
3116 | bne >4
3117 | checktp CARG4, LJ_TNIL
3118 | beq >5
3119 |3:
3120 | ins_next1
3121 | ins_next2
3122 | strd CARG34, [BASE, RA]
3123 | ins_next3
3124 |
3125 |4: // Follow hash chain.
3126 | cmp NODE:INS, #0
3127 | bne <1
3128 | // End of hash chain: key not found, nil result.
3129 |
3130 |5: // Check for __index if table value is nil.
3131 | ldr TAB:CARG1, TAB:RB->metatable
3132 | mov CARG3, #0 // Optional clear of undef. value (during load stall).
3133 | mvn CARG4, #~LJ_TNIL
3134 | cmp TAB:CARG1, #0
3135 | beq <3 // No metatable: done.
3136 | ldrb CARG2, TAB:CARG1->nomm
3137 | tst CARG2, #1<<MM_index
3138 | bne <3 // 'no __index' flag set: done.
3139 | b ->vmeta_tgets
3140 break;
3141 case BC_TGETB:
3142 | decode_RB8 RB, INS
3143 | and RC, RC, #255
3144 | // RA = dst*8, RB = table*8, RC = index
3145 | ldrd CARG12, [BASE, RB]
3146 | checktab CARG2, ->vmeta_tgetb // STALL: load CARG12.
3147 | ldr CARG3, TAB:CARG1->asize
3148 | ldr CARG4, TAB:CARG1->array
3149 | lsl CARG2, RC, #3
3150 | cmp RC, CARG3
3151 | ldrdlo CARG34, [CARG4, CARG2]
3152 | bhs ->vmeta_tgetb
3153 | ins_next1 // Overwrites RB!
3154 | checktp CARG4, LJ_TNIL
3155 | beq >5
3156 |1:
3157 | ins_next2
3158 | strd CARG34, [BASE, RA]
3159 | ins_next3
3160 |
3161 |5: // Check for __index if table value is nil.
3162 | ldr TAB:CARG2, TAB:CARG1->metatable
3163 | cmp TAB:CARG2, #0
3164 | beq <1 // No metatable: done.
3165 | ldrb CARG2, TAB:CARG2->nomm
3166 | tst CARG2, #1<<MM_index
3167 | bne <1 // 'no __index' flag set: done.
3168 | b ->vmeta_tgetb
3169 break;
3170
3171 case BC_TSETV:
3172 | decode_RB8 RB, INS
3173 | decode_RC8 RC, INS
3174 | // RA = src*8, RB = table*8, RC = key*8
3175 | ldrd TAB:CARG12, [BASE, RB]
3176 | ldrd CARG34, [BASE, RC]
3177 | checktab CARG2, ->vmeta_tsetv // STALL: load CARG12.
3178 | checktp CARG4, LJ_TISNUM // Integer key?
3179 | ldreq CARG2, TAB:CARG1->array
3180 | ldreq CARG4, TAB:CARG1->asize
3181 | bne >9
3182 |
3183 | add CARG2, CARG2, CARG3, lsl #3
3184 | cmp CARG3, CARG4 // In array part?
3185 | ldrlo INS, [CARG2, #4]
3186 | bhs ->vmeta_tsetv
3187 | ins_next1 // Overwrites RB!
3188 | checktp INS, LJ_TNIL
3189 | ldrb INS, TAB:CARG1->marked
3190 | ldrd CARG34, [BASE, RA]
3191 | beq >5
3192 |1:
3193 | tst INS, #LJ_GC_BLACK // isblack(table)
3194 | strd CARG34, [CARG2]
3195 | bne >7
3196 |2:
3197 | ins_next2
3198 | ins_next3
3199 |
3200 |5: // Check for __newindex if previous value is nil.
3201 | ldr TAB:RA, TAB:CARG1->metatable
3202 | cmp TAB:RA, #0
3203 | beq <1 // No metatable: done.
3204 | ldrb RA, TAB:RA->nomm
3205 | tst RA, #1<<MM_newindex
3206 | bne <1 // 'no __newindex' flag set: done.
3207 | ldr INS, [PC, #-4] // Restore RA and RB.
3208 | decode_RB8 RB, INS
3209 | decode_RA8 RA, INS
3210 | b ->vmeta_tsetv
3211 |
3212 |7: // Possible table write barrier for the value. Skip valiswhite check.
3213 | barrierback TAB:CARG1, INS, CARG3
3214 | b <2
3215 |
3216 |9:
3217 | checktp CARG4, LJ_TSTR // String key?
3218 | moveq STR:RC, CARG3
3219 | beq ->BC_TSETS_Z
3220 | b ->vmeta_tsetv
3221 break;
3222 case BC_TSETS:
3223 | decode_RB8 RB, INS
3224 | and RC, RC, #255
3225 | // RA = src*8, RB = table*8, RC = str_const (~)
3226 | ldrd CARG12, [BASE, RB]
3227 | mvn RC, RC
3228 | ldr STR:RC, [KBASE, RC, lsl #2] // STALL: early RC.
3229 | checktab CARG2, ->vmeta_tsets1
3230 |->BC_TSETS_Z:
3231 | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8
3232 | ldr CARG3, TAB:CARG1->hmask
3233 | ldr CARG4, STR:RC->hash
3234 | ldr NODE:INS, TAB:CARG1->node
3235 | mov TAB:RB, TAB:CARG1
3236 | and CARG3, CARG3, CARG4 // idx = str->hash & tab->hmask
3237 | add CARG3, CARG3, CARG3, lsl #1
3238 | mov CARG4, #0
3239 | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8
3240 | strb CARG4, TAB:RB->nomm // Clear metamethod cache.
3241 |1:
3242 | ldrd CARG12, NODE:INS->key
3243 | ldr CARG4, NODE:INS->val.it
3244 | ldr NODE:CARG3, NODE:INS->next
3245 | cmp CARG1, STR:RC
3246 | checktpeq CARG2, LJ_TSTR
3247 | bne >5
3248 | ldrb CARG2, TAB:RB->marked
3249 | checktp CARG4, LJ_TNIL // Key found, but nil value?
3250 | ldrd CARG34, [BASE, RA]
3251 | beq >4
3252 |2:
3253 | tst CARG2, #LJ_GC_BLACK // isblack(table)
3254 | strd CARG34, NODE:INS->val
3255 | bne >7
3256 |3:
3257 | ins_next
3258 |
3259 |4: // Check for __newindex if previous value is nil.
3260 | ldr TAB:CARG1, TAB:RB->metatable
3261 | cmp TAB:CARG1, #0
3262 | beq <2 // No metatable: done.
3263 | ldrb CARG1, TAB:CARG1->nomm
3264 | tst CARG1, #1<<MM_newindex
3265 | bne <2 // 'no __newindex' flag set: done.
3266 | b ->vmeta_tsets
3267 |
3268 |5: // Follow hash chain.
3269 | movs NODE:INS, NODE:CARG3
3270 | bne <1
3271 | // End of hash chain: key not found, add a new one.
3272 |
3273 | // But check for __newindex first.
3274 | ldr TAB:CARG1, TAB:RB->metatable
3275 | mov CARG3, TMPDp
3276 | str PC, SAVE_PC
3277 | cmp TAB:CARG1, #0 // No metatable: continue.
3278 | str BASE, L->base
3279 | ldrbne CARG2, TAB:CARG1->nomm
3280 | mov CARG1, L
3281 | beq >6
3282 | tst CARG2, #1<<MM_newindex
3283 | beq ->vmeta_tsets // 'no __newindex' flag NOT set: check.
3284 |6:
3285 | mvn CARG4, #~LJ_TSTR
3286 | str STR:RC, TMPDlo
3287 | mov CARG2, TAB:RB
3288 | str CARG4, TMPDhi
3289 | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k)
3290 | // Returns TValue *.
3291 | ldr BASE, L->base
3292 | ldrd CARG34, [BASE, RA]
3293 | strd CARG34, [CRET1]
3294 | b <3 // No 2nd write barrier needed.
3295 |
3296 |7: // Possible table write barrier for the value. Skip valiswhite check.
3297 | barrierback TAB:RB, CARG2, CARG3
3298 | b <3
3299 break;
3300 case BC_TSETB:
3301 | decode_RB8 RB, INS
3302 | and RC, RC, #255
3303 | // RA = src*8, RB = table*8, RC = index
3304 | ldrd CARG12, [BASE, RB]
3305 | checktab CARG2, ->vmeta_tsetb // STALL: load CARG12.
3306 | ldr CARG3, TAB:CARG1->asize
3307 | ldr RB, TAB:CARG1->array
3308 | lsl CARG2, RC, #3
3309 | cmp RC, CARG3
3310 | ldrdlo CARG34, [CARG2, RB]!
3311 | bhs ->vmeta_tsetb
3312 | ins_next1 // Overwrites RB!
3313 | checktp CARG4, LJ_TNIL
3314 | ldrb INS, TAB:CARG1->marked
3315 | ldrd CARG34, [BASE, RA]
3316 | beq >5
3317 |1:
3318 | tst INS, #LJ_GC_BLACK // isblack(table)
3319 | strd CARG34, [CARG2]
3320 | bne >7
3321 |2:
3322 | ins_next2
3323 | ins_next3
3324 |
3325 |5: // Check for __newindex if previous value is nil.
3326 | ldr TAB:RA, TAB:CARG1->metatable
3327 | cmp TAB:RA, #0
3328 | beq <1 // No metatable: done.
3329 | ldrb RA, TAB:RA->nomm
3330 | tst RA, #1<<MM_newindex
3331 | bne <1 // 'no __newindex' flag set: done.
3332 | ldr INS, [PC, #-4] // Restore INS.
3333 | decode_RA8 RA, INS
3334 | b ->vmeta_tsetb
3335 |
3336 |7: // Possible table write barrier for the value. Skip valiswhite check.
3337 | barrierback TAB:CARG1, INS, CARG3
3338 | b <2
3339 break;
3340
3341 case BC_TSETM:
3342 | // RA = base*8 (table at base-1), RC = num_const (start index)
3343 | add RA, BASE, RA
3344 |1:
3345 | ldr RB, SAVE_MULTRES
3346 | ldr TAB:CARG2, [RA, #-8] // Guaranteed to be a table.
3347 | ldr CARG1, [KBASE, RC, lsl #3] // Integer constant is in lo-word.
3348 | subs RB, RB, #8
3349 | ldr CARG4, TAB:CARG2->asize
3350 | beq >4 // Nothing to copy?
3351 | add CARG3, CARG1, RB, lsr #3
3352 | cmp CARG3, CARG4
3353 | ldr CARG4, TAB:CARG2->array
3354 | add RB, RA, RB
3355 | bhi >5
3356 | add INS, CARG4, CARG1, lsl #3
3357 | ldrb CARG1, TAB:CARG2->marked
3358 |3: // Copy result slots to table.
3359 | ldrd CARG34, [RA], #8
3360 | strd CARG34, [INS], #8
3361 | cmp RA, RB
3362 | blo <3
3363 | tst CARG1, #LJ_GC_BLACK // isblack(table)
3364 | bne >7
3365 |4:
3366 | ins_next
3367 |
3368 |5: // Need to resize array part.
3369 | str BASE, L->base
3370 | mov CARG1, L
3371 | str PC, SAVE_PC
3372 | bl extern lj_tab_reasize // (lua_State *L, GCtab *t, int nasize)
3373 | // Must not reallocate the stack.
3374 | IOS ldr BASE, L->base
3375 | b <1
3376 |
3377 |7: // Possible table write barrier for any value. Skip valiswhite check.
3378 | barrierback TAB:CARG2, CARG1, CARG3
3379 | b <4
3380 break;
3381
3382 /* -- Calls and vararg handling ----------------------------------------- */
3383
3384 case BC_CALLM:
3385 | // RA = base*8, (RB = nresults+1,) RC = extra_nargs
3386 | ldr CARG1, SAVE_MULTRES
3387 | decode_RC8 NARGS8:RC, INS
3388 | add NARGS8:RC, NARGS8:RC, CARG1
3389 | b ->BC_CALL_Z
3390 break;
3391 case BC_CALL:
3392 | decode_RC8 NARGS8:RC, INS
3393 | // RA = base*8, (RB = nresults+1,) RC = (nargs+1)*8
3394 |->BC_CALL_Z:
3395 | mov RB, BASE // Save old BASE for vmeta_call.
3396 | ldrd CARG34, [BASE, RA]!
3397 | sub NARGS8:RC, NARGS8:RC, #8
3398 | add BASE, BASE, #8
3399 | checkfunc CARG4, ->vmeta_call
3400 | ins_call
3401 break;
3402
3403 case BC_CALLMT:
3404 | // RA = base*8, (RB = 0,) RC = extra_nargs
3405 | ldr CARG1, SAVE_MULTRES
3406 | add NARGS8:RC, CARG1, RC, lsl #3
3407 | b ->BC_CALLT1_Z
3408 break;
3409 case BC_CALLT:
3410 | lsl NARGS8:RC, RC, #3
3411 | // RA = base*8, (RB = 0,) RC = (nargs+1)*8
3412 |->BC_CALLT1_Z:
3413 | ldrd LFUNC:CARG34, [RA, BASE]!
3414 | sub NARGS8:RC, NARGS8:RC, #8
3415 | add RA, RA, #8
3416 | checkfunc CARG4, ->vmeta_callt
3417 | ldr PC, [BASE, FRAME_PC]
3418 |->BC_CALLT2_Z:
3419 | mov RB, #0
3420 | ldrb CARG4, LFUNC:CARG3->ffid
3421 | tst PC, #FRAME_TYPE
3422 | bne >7
3423 |1:
3424 | str LFUNC:CARG3, [BASE, FRAME_FUNC] // Copy function down, but keep PC.
3425 | cmp NARGS8:RC, #0
3426 | beq >3
3427 |2:
3428 | ldrd CARG12, [RA, RB]
3429 | add INS, RB, #8
3430 | cmp INS, NARGS8:RC
3431 | strd CARG12, [BASE, RB]
3432 | mov RB, INS
3433 | bne <2
3434 |3:
3435 | cmp CARG4, #1 // (> FF_C) Calling a fast function?
3436 | bhi >5
3437 |4:
3438 | ins_callt
3439 |
3440 |5: // Tailcall to a fast function with a Lua frame below.
3441 | ldr INS, [PC, #-4]
3442 | decode_RA8 RA, INS
3443 | sub CARG1, BASE, RA
3444 | ldr LFUNC:CARG1, [CARG1, #-16]
3445 | ldr CARG1, LFUNC:CARG1->field_pc
3446 | ldr KBASE, [CARG1, #PC2PROTO(k)]
3447 | b <4
3448 |
3449 |7: // Tailcall from a vararg function.
3450 | eor PC, PC, #FRAME_VARG
3451 | tst PC, #FRAME_TYPEP // Vararg frame below?
3452 | movne CARG4, #0 // Clear ffid if no Lua function below.
3453 | bne <1
3454 | sub BASE, BASE, PC
3455 | ldr PC, [BASE, FRAME_PC]
3456 | tst PC, #FRAME_TYPE
3457 | movne CARG4, #0 // Clear ffid if no Lua function below.
3458 | b <1
3459 break;
3460
3461 case BC_ITERC:
3462 | // RA = base*8, (RB = nresults+1, RC = nargs+1 (2+1))
3463 | add RA, BASE, RA
3464 | mov RB, BASE // Save old BASE for vmeta_call.
3465 | ldrd CARG34, [RA, #-16]
3466 | ldrd CARG12, [RA, #-8]
3467 | add BASE, RA, #8
3468 | strd CARG34, [RA, #8] // Copy state.
3469 | strd CARG12, [RA, #16] // Copy control var.
3470 | // STALL: locked CARG34.
3471 | ldrd LFUNC:CARG34, [RA, #-24]
3472 | mov NARGS8:RC, #16 // Iterators get 2 arguments.
3473 | // STALL: load CARG34.
3474 | strd LFUNC:CARG34, [RA] // Copy callable.
3475 | checkfunc CARG4, ->vmeta_call
3476 | ins_call
3477 break;
3478
3479 case BC_ITERN:
3480 | // RA = base*8, (RB = nresults+1, RC = nargs+1 (2+1))
3481#if LJ_HASJIT
3482 | // NYI: add hotloop, record BC_ITERN.
3483#endif
3484 | add RA, BASE, RA
3485 | ldr TAB:RB, [RA, #-16]
3486 | ldr CARG1, [RA, #-8] // Get index from control var.
3487 | ldr INS, TAB:RB->asize
3488 | ldr CARG2, TAB:RB->array
3489 | add PC, PC, #4
3490 |1: // Traverse array part.
3491 | subs RC, CARG1, INS
3492 | add CARG3, CARG2, CARG1, lsl #3
3493 | bhs >5 // Index points after array part?
3494 | ldrd CARG34, [CARG3]
3495 | checktp CARG4, LJ_TNIL
3496 | addeq CARG1, CARG1, #1 // Skip holes in array part.
3497 | beq <1
3498 | ldrh RC, [PC, #-2]
3499 | mvn CARG2, #~LJ_TISNUM
3500 | strd CARG34, [RA, #8]
3501 | add RC, PC, RC, lsl #2
3502 | add RB, CARG1, #1
3503 | strd CARG12, [RA]
3504 | sub PC, RC, #0x20000
3505 | str RB, [RA, #-8] // Update control var.
3506 |3:
3507 | ins_next
3508 |
3509 |5: // Traverse hash part.
3510 | ldr CARG4, TAB:RB->hmask
3511 | ldr NODE:RB, TAB:RB->node
3512 |6:
3513 | add CARG1, RC, RC, lsl #1
3514 | cmp RC, CARG4 // End of iteration? Branch to ITERL+1.
3515 | add NODE:CARG3, NODE:RB, CARG1, lsl #3 // node = tab->node + idx*3*8
3516 | bhi <3
3517 | ldrd CARG12, NODE:CARG3->val
3518 | checktp CARG2, LJ_TNIL
3519 | add RC, RC, #1
3520 | beq <6 // Skip holes in hash part.
3521 | ldrh RB, [PC, #-2]
3522 | add RC, RC, INS
3523 | ldrd CARG34, NODE:CARG3->key
3524 | str RC, [RA, #-8] // Update control var.
3525 | strd CARG12, [RA, #8]
3526 | add RC, PC, RB, lsl #2
3527 | sub PC, RC, #0x20000
3528 | strd CARG34, [RA]
3529 | b <3
3530 break;
3531
3532 case BC_ISNEXT:
3533 | // RA = base*8, RC = target (points to ITERN)
3534 | add RA, BASE, RA
3535 | add RC, PC, RC, lsl #2
3536 | ldrd CFUNC:CARG12, [RA, #-24]
3537 | ldr CARG3, [RA, #-12]
3538 | ldr CARG4, [RA, #-4]
3539 | checktp CARG2, LJ_TFUNC
3540 | ldrbeq CARG1, CFUNC:CARG1->ffid
3541 | checktpeq CARG3, LJ_TTAB
3542 | checktpeq CARG4, LJ_TNIL
3543 | cmpeq CARG1, #FF_next_N
3544 | subeq PC, RC, #0x20000
3545 | bne >5
3546 | ins_next1
3547 | ins_next2
3548 | mov CARG1, #0
3549 | str CARG1, [RA, #-8] // Initialize control var.
3550 |1:
3551 | ins_next3
3552 |5: // Despecialize bytecode if any of the checks fail.
3553 | mov CARG1, #BC_JMP
3554 | mov OP, #BC_ITERC
3555 | strb CARG1, [PC, #-4]
3556 | sub PC, RC, #0x20000
3557 | strb OP, [PC] // Subsumes ins_next1.
3558 | ins_next2
3559 | b <1
3560 break;
3561
3562 case BC_VARG:
3563 | decode_RB8 RB, INS
3564 | decode_RC8 RC, INS
3565 | // RA = base*8, RB = (nresults+1)*8, RC = numparams*8
3566 | ldr CARG1, [BASE, FRAME_PC]
3567 | add RC, BASE, RC
3568 | add RA, BASE, RA
3569 | add RC, RC, #FRAME_VARG
3570 | add CARG4, RA, RB
3571 | sub CARG3, BASE, #8 // CARG3 = vtop
3572 | sub RC, RC, CARG1 // RC = vbase
3573 | // Note: RC may now be even _above_ BASE if nargs was < numparams.
3574 | cmp RB, #0
3575 | sub CARG1, CARG3, RC
3576 | beq >5 // Copy all varargs?
3577 | sub CARG4, CARG4, #16
3578 |1: // Copy vararg slots to destination slots.
3579 | cmp RC, CARG3
3580 | ldrdlo CARG12, [RC], #8
3581 | mvnhs CARG2, #~LJ_TNIL
3582 | cmp RA, CARG4
3583 | strd CARG12, [RA], #8
3584 | blo <1
3585 |2:
3586 | ins_next
3587 |
3588 |5: // Copy all varargs.
3589 | ldr CARG4, L->maxstack
3590 | cmp CARG1, #0
3591 | movle RB, #8 // MULTRES = (0+1)*8
3592 | addgt RB, CARG1, #8
3593 | add CARG2, RA, CARG1
3594 | str RB, SAVE_MULTRES
3595 | ble <2
3596 | cmp CARG2, CARG4
3597 | bhi >7
3598 |6:
3599 | ldrd CARG12, [RC], #8
3600 | strd CARG12, [RA], #8
3601 | cmp RC, CARG3
3602 | blo <6
3603 | b <2
3604 |
3605 |7: // Grow stack for varargs.
3606 | lsr CARG2, CARG1, #3
3607 | str RA, L->top
3608 | mov CARG1, L
3609 | str BASE, L->base
3610 | sub RC, RC, BASE // Need delta, because BASE may change.
3611 | str PC, SAVE_PC
3612 | sub RA, RA, BASE
3613 | bl extern lj_state_growstack // (lua_State *L, int n)
3614 | ldr BASE, L->base
3615 | add RA, BASE, RA
3616 | add RC, BASE, RC
3617 | sub CARG3, BASE, #8
3618 | b <6
3619 break;
3620
3621 /* -- Returns ----------------------------------------------------------- */
3622
3623 case BC_RETM:
3624 | // RA = results*8, RC = extra results
3625 | ldr CARG1, SAVE_MULTRES
3626 | ldr PC, [BASE, FRAME_PC]
3627 | add RA, BASE, RA
3628 | add RC, CARG1, RC, lsl #3
3629 | b ->BC_RETM_Z
3630 break;
3631
3632 case BC_RET:
3633 | // RA = results*8, RC = nresults+1
3634 | ldr PC, [BASE, FRAME_PC]
3635 | lsl RC, RC, #3
3636 | add RA, BASE, RA
3637 |->BC_RETM_Z:
3638 | str RC, SAVE_MULTRES
3639 |1:
3640 | ands CARG1, PC, #FRAME_TYPE
3641 | eor CARG2, PC, #FRAME_VARG
3642 | bne ->BC_RETV2_Z
3643 |
3644 |->BC_RET_Z:
3645 | // BASE = base, RA = resultptr, RC = (nresults+1)*8, PC = return
3646 | ldr INS, [PC, #-4]
3647 | subs CARG4, RC, #8
3648 | sub CARG3, BASE, #8
3649 | beq >3
3650 |2:
3651 | ldrd CARG12, [RA], #8
3652 | add BASE, BASE, #8
3653 | subs CARG4, CARG4, #8
3654 | strd CARG12, [BASE, #-16]
3655 | bne <2
3656 |3:
3657 | decode_RA8 RA, INS
3658 | sub CARG4, CARG3, RA
3659 | decode_RB8 RB, INS
3660 | ldr LFUNC:CARG1, [CARG4, FRAME_FUNC]
3661 |5:
3662 | cmp RB, RC // More results expected?
3663 | bhi >6
3664 | mov BASE, CARG4
3665 | ldr CARG2, LFUNC:CARG1->field_pc
3666 | ins_next1
3667 | ins_next2
3668 | ldr KBASE, [CARG2, #PC2PROTO(k)]
3669 | ins_next3
3670 |
3671 |6: // Fill up results with nil.
3672 | mvn CARG2, #~LJ_TNIL
3673 | add BASE, BASE, #8
3674 | add RC, RC, #8
3675 | str CARG2, [BASE, #-12]
3676 | b <5
3677 |
3678 |->BC_RETV1_Z: // Non-standard return case.
3679 | add RA, BASE, RA
3680 |->BC_RETV2_Z:
3681 | tst CARG2, #FRAME_TYPEP
3682 | bne ->vm_return
3683 | // Return from vararg function: relocate BASE down.
3684 | sub BASE, BASE, CARG2
3685 | ldr PC, [BASE, FRAME_PC]
3686 | b <1
3687 break;
3688
3689 case BC_RET0: case BC_RET1:
3690 | // RA = results*8, RC = nresults+1
3691 | ldr PC, [BASE, FRAME_PC]
3692 | lsl RC, RC, #3
3693 | str RC, SAVE_MULTRES
3694 | ands CARG1, PC, #FRAME_TYPE
3695 | eor CARG2, PC, #FRAME_VARG
3696 | ldreq INS, [PC, #-4]
3697 | bne ->BC_RETV1_Z
3698 if (op == BC_RET1) {
3699 | ldrd CARG12, [BASE, RA]
3700 }
3701 | sub CARG4, BASE, #8
3702 | decode_RA8 RA, INS
3703 if (op == BC_RET1) {
3704 | strd CARG12, [CARG4]
3705 }
3706 | sub BASE, CARG4, RA
3707 | decode_RB8 RB, INS
3708 | ldr LFUNC:CARG1, [BASE, FRAME_FUNC]
3709 |5:
3710 | cmp RB, RC
3711 | bhi >6
3712 | ldr CARG2, LFUNC:CARG1->field_pc
3713 | ins_next1
3714 | ins_next2
3715 | ldr KBASE, [CARG2, #PC2PROTO(k)]
3716 | ins_next3
3717 |
3718 |6: // Fill up results with nil.
3719 | sub CARG2, CARG4, #4
3720 | mvn CARG3, #~LJ_TNIL
3721 | str CARG3, [CARG2, RC]
3722 | add RC, RC, #8
3723 | b <5
3724 break;
3725
3726 /* -- Loops and branches ------------------------------------------------ */
3727
3728 |.define FOR_IDX, [RA]; .define FOR_TIDX, [RA, #4]
3729 |.define FOR_STOP, [RA, #8]; .define FOR_TSTOP, [RA, #12]
3730 |.define FOR_STEP, [RA, #16]; .define FOR_TSTEP, [RA, #20]
3731 |.define FOR_EXT, [RA, #24]; .define FOR_TEXT, [RA, #28]
3732
3733 case BC_FORL:
3734#if LJ_HASJIT
3735 | hotloop
3736#endif
3737 | // Fall through. Assumes BC_IFORL follows.
3738 break;
3739
3740 case BC_JFORI:
3741 case BC_JFORL:
3742#if !LJ_HASJIT
3743 break;
3744#endif
3745 case BC_FORI:
3746 case BC_IFORL:
3747 | // RA = base*8, RC = target (after end of loop or start of loop)
3748 vk = (op == BC_IFORL || op == BC_JFORL);
3749 | ldrd CARG12, [RA, BASE]!
3750 if (op != BC_JFORL) {
3751 | add RC, PC, RC, lsl #2
3752 }
3753 if (!vk) {
3754 | ldrd CARG34, FOR_STOP
3755 | checktp CARG2, LJ_TISNUM
3756 | ldr RB, FOR_TSTEP
3757 | bne >5
3758 | checktp CARG4, LJ_TISNUM
3759 | ldr CARG4, FOR_STEP
3760 | checktpeq RB, LJ_TISNUM
3761 | bne ->vmeta_for
3762 | cmp CARG4, #0
3763 | blt >4
3764 | cmp CARG1, CARG3
3765 } else {
3766 | ldrd CARG34, FOR_STEP
3767 | checktp CARG2, LJ_TISNUM
3768 | bne >5
3769 | adds CARG1, CARG1, CARG3
3770 | ldr CARG4, FOR_STOP
3771 if (op == BC_IFORL) {
3772 | addvs RC, PC, #0x20000 // Overflow: prevent branch.
3773 } else {
3774 | bvs >2 // Overflow: do not enter mcode.
3775 }
3776 | cmp CARG3, #0
3777 | blt >4
3778 | cmp CARG1, CARG4
3779 }
3780 |1:
3781 if (op == BC_FORI) {
3782 | subgt PC, RC, #0x20000
3783 } else if (op == BC_JFORI) {
3784 | sub PC, RC, #0x20000
3785 | ldrhle RC, [PC, #-2]
3786 } else if (op == BC_IFORL) {
3787 | suble PC, RC, #0x20000
3788 }
3789 if (vk) {
3790 | strd CARG12, FOR_IDX
3791 }
3792 |2:
3793 | ins_next1
3794 | ins_next2
3795 | strd CARG12, FOR_EXT
3796 if (op == BC_JFORI || op == BC_JFORL) {
3797 | ble =>BC_JLOOP
3798 }
3799 |3:
3800 | ins_next3
3801 |
3802 |4: // Invert check for negative step.
3803 if (!vk) {
3804 | cmp CARG3, CARG1
3805 } else {
3806 | cmp CARG4, CARG1
3807 }
3808 | b <1
3809 |
3810 |5: // FP loop.
3811 if (!vk) {
3812 | cmnlo CARG4, #-LJ_TISNUM
3813 | cmnlo RB, #-LJ_TISNUM
3814 | bhs ->vmeta_for
3815 | cmp RB, #0
3816 | strd CARG12, FOR_IDX
3817 | strd CARG12, FOR_EXT
3818 | blt >8
3819 } else {
3820 | cmp CARG4, #0
3821 | blt >8
3822 | bl extern __aeabi_dadd
3823 | strd CARG12, FOR_IDX
3824 | ldrd CARG34, FOR_STOP
3825 | strd CARG12, FOR_EXT
3826 }
3827 |6:
3828 | bl extern __aeabi_cdcmple
3829 if (op == BC_FORI) {
3830 | subhi PC, RC, #0x20000
3831 } else if (op == BC_JFORI) {
3832 | sub PC, RC, #0x20000
3833 | ldrhls RC, [PC, #-2]
3834 | bls =>BC_JLOOP
3835 } else if (op == BC_IFORL) {
3836 | subls PC, RC, #0x20000
3837 } else {
3838 | bls =>BC_JLOOP
3839 }
3840 | ins_next1
3841 | ins_next2
3842 | b <3
3843 |
3844 |8: // Invert check for negative step.
3845 if (vk) {
3846 | bl extern __aeabi_dadd
3847 | strd CARG12, FOR_IDX
3848 | strd CARG12, FOR_EXT
3849 }
3850 | mov CARG3, CARG1
3851 | mov CARG4, CARG2
3852 | ldrd CARG12, FOR_STOP
3853 | b <6
3854 break;
3855
3856 case BC_ITERL:
3857#if LJ_HASJIT
3858 | hotloop
3859#endif
3860 | // Fall through. Assumes BC_IITERL follows.
3861 break;
3862
3863 case BC_JITERL:
3864#if !LJ_HASJIT
3865 break;
3866#endif
3867 case BC_IITERL:
3868 | // RA = base*8, RC = target
3869 | ldrd CARG12, [RA, BASE]!
3870 if (op == BC_JITERL) {
3871 | cmn CARG2, #-LJ_TNIL // Stop if iterator returned nil.
3872 | strdne CARG12, [RA, #-8]
3873 | bne =>BC_JLOOP
3874 } else {
3875 | add RC, PC, RC, lsl #2
3876 | // STALL: load CARG12.
3877 | cmn CARG2, #-LJ_TNIL // Stop if iterator returned nil.
3878 | subne PC, RC, #0x20000 // Otherwise save control var + branch.
3879 | strdne CARG12, [RA, #-8]
3880 }
3881 | ins_next
3882 break;
3883
3884 case BC_LOOP:
3885 | // RA = base*8, RC = target (loop extent)
3886 | // Note: RA/RC is only used by trace recorder to determine scope/extent
3887 | // This opcode does NOT jump, it's only purpose is to detect a hot loop.
3888#if LJ_HASJIT
3889 | hotloop
3890#endif
3891 | // Fall through. Assumes BC_ILOOP follows.
3892 break;
3893
3894 case BC_ILOOP:
3895 | // RA = base*8, RC = target (loop extent)
3896 | ins_next
3897 break;
3898
3899 case BC_JLOOP:
3900#if LJ_HASJIT
3901 | // RA = base (ignored), RC = traceno
3902 | ldr CARG1, [DISPATCH, #DISPATCH_J(trace)]
3903 | mov CARG2, #0 // Traces on ARM don't store the trace number, so use 0.
3904 | ldr TRACE:RC, [CARG1, RC, lsl #2]
3905 | st_vmstate CARG2
3906 | ldr RA, TRACE:RC->mcode
3907 | str BASE, [DISPATCH, #DISPATCH_GL(jit_base)]
3908 | str L, [DISPATCH, #DISPATCH_GL(jit_L)]
3909 | bx RA
3910#endif
3911 break;
3912
3913 case BC_JMP:
3914 | // RA = base*8 (only used by trace recorder), RC = target
3915 | add RC, PC, RC, lsl #2
3916 | sub PC, RC, #0x20000
3917 | ins_next
3918 break;
3919
3920 /* -- Function headers -------------------------------------------------- */
3921
3922 case BC_FUNCF:
3923#if LJ_HASJIT
3924 | hotcall
3925#endif
3926 case BC_FUNCV: /* NYI: compiled vararg functions. */
3927 | // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow.
3928 break;
3929
3930 case BC_JFUNCF:
3931#if !LJ_HASJIT
3932 break;
3933#endif
3934 case BC_IFUNCF:
3935 | // BASE = new base, RA = BASE+framesize*8, CARG3 = LFUNC, RC = nargs*8
3936 | ldr CARG1, L->maxstack
3937 | ldrb CARG2, [PC, #-4+PC2PROTO(numparams)]
3938 | ldr KBASE, [PC, #-4+PC2PROTO(k)]
3939 | cmp RA, CARG1
3940 | bhi ->vm_growstack_l
3941 if (op != BC_JFUNCF) {
3942 | ins_next1
3943 | ins_next2
3944 }
3945 |2:
3946 | cmp NARGS8:RC, CARG2, lsl #3 // Check for missing parameters.
3947 | mvn CARG4, #~LJ_TNIL
3948 | ble >3
3949 if (op == BC_JFUNCF) {
3950 | decode_RD RC, INS
3951 | b =>BC_JLOOP
3952 } else {
3953 | ins_next3
3954 }
3955 |
3956 |3: // Clear missing parameters.
3957 | strd CARG34, [BASE, NARGS8:RC]
3958 | add NARGS8:RC, NARGS8:RC, #8
3959 | b <2
3960 break;
3961
3962 case BC_JFUNCV:
3963#if !LJ_HASJIT
3964 break;
3965#endif
3966 | NYI // NYI: compiled vararg functions
3967 break; /* NYI: compiled vararg functions. */
3968
3969 case BC_IFUNCV:
3970 | // BASE = new base, RA = BASE+framesize*8, CARG3 = LFUNC, RC = nargs*8
3971 | ldr CARG1, L->maxstack
3972 | add CARG4, BASE, RC
3973 | add RA, RA, RC
3974 | str LFUNC:CARG3, [CARG4] // Store copy of LFUNC.
3975 | add CARG2, RC, #8+FRAME_VARG
3976 | ldr KBASE, [PC, #-4+PC2PROTO(k)]
3977 | cmp RA, CARG1
3978 | str CARG2, [CARG4, #4] // Store delta + FRAME_VARG.
3979 | bhs ->vm_growstack_l
3980 | ldrb RB, [PC, #-4+PC2PROTO(numparams)]
3981 | mov RA, BASE
3982 | mov RC, CARG4
3983 | cmp RB, #0
3984 | add BASE, CARG4, #8
3985 | beq >3
3986 | mvn CARG3, #~LJ_TNIL
3987 |1:
3988 | cmp RA, RC // Less args than parameters?
3989 | ldrdlo CARG12, [RA], #8
3990 | movhs CARG2, CARG3
3991 | strlo CARG3, [RA, #-4] // Clear old fixarg slot (help the GC).
3992 |2:
3993 | subs RB, RB, #1
3994 | strd CARG12, [CARG4, #8]!
3995 | bne <1
3996 |3:
3997 | ins_next
3998 break;
3999
4000 case BC_FUNCC:
4001 case BC_FUNCCW:
4002 | // BASE = new base, RA = BASE+framesize*8, CARG3 = CFUNC, RC = nargs*8
4003 if (op == BC_FUNCC) {
4004 | ldr CARG4, CFUNC:CARG3->f
4005 } else {
4006 | ldr CARG4, [DISPATCH, #DISPATCH_GL(wrapf)]
4007 }
4008 | add CARG2, RA, NARGS8:RC
4009 | ldr CARG1, L->maxstack
4010 | add RC, BASE, NARGS8:RC
4011 | str BASE, L->base
4012 | cmp CARG2, CARG1
4013 | str RC, L->top
4014 if (op == BC_FUNCCW) {
4015 | ldr CARG2, CFUNC:CARG3->f
4016 }
4017 | mv_vmstate CARG3, C
4018 | mov CARG1, L
4019 | bhi ->vm_growstack_c // Need to grow stack.
4020 | st_vmstate CARG3
4021 | blx CARG4 // (lua_State *L [, lua_CFunction f])
4022 | // Returns nresults.
4023 | ldr BASE, L->base
4024 | mv_vmstate CARG3, INTERP
4025 | ldr CRET2, L->top
4026 | lsl RC, CRET1, #3
4027 | st_vmstate CARG3
4028 | ldr PC, [BASE, FRAME_PC]
4029 | sub RA, CRET2, RC // RA = L->top - nresults*8
4030 | b ->vm_returnc
4031 break;
4032
4033 /* ---------------------------------------------------------------------- */
4034
4035 default:
4036 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
4037 exit(2);
4038 break;
4039 }
4040}
4041
4042static int build_backend(BuildCtx *ctx)
4043{
4044 int op;
4045
4046 dasm_growpc(Dst, BC__MAX);
4047
4048 build_subroutines(ctx);
4049
4050 |.code_op
4051 for (op = 0; op < BC__MAX; op++)
4052 build_ins(ctx, (BCOp)op, op);
4053
4054 return BC__MAX;
4055}
4056
4057/* Emit pseudo frame-info for all assembler functions. */
4058static void emit_asm_debug(BuildCtx *ctx)
4059{
4060 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
4061 int i;
4062 switch (ctx->mode) {
4063 case BUILD_elfasm:
4064 fprintf(ctx->fp, "\t.section .debug_frame,\"\",%%progbits\n");
4065 fprintf(ctx->fp,
4066 ".Lframe0:\n"
4067 "\t.long .LECIE0-.LSCIE0\n"
4068 ".LSCIE0:\n"
4069 "\t.long 0xffffffff\n"
4070 "\t.byte 0x1\n"
4071 "\t.string \"\"\n"
4072 "\t.uleb128 0x1\n"
4073 "\t.sleb128 -4\n"
4074 "\t.byte 0xe\n" /* Return address is in lr. */
4075 "\t.byte 0xc\n\t.uleb128 0xd\n\t.uleb128 0\n" /* def_cfa sp */
4076 "\t.align 2\n"
4077 ".LECIE0:\n\n");
4078 fprintf(ctx->fp,
4079 ".LSFDE0:\n"
4080 "\t.long .LEFDE0-.LASFDE0\n"
4081 ".LASFDE0:\n"
4082 "\t.long .Lframe0\n"
4083 "\t.long .Lbegin\n"
4084 "\t.long %d\n"
4085 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
4086 "\t.byte 0x8e\n\t.uleb128 1\n", /* offset lr */
4087 fcofs, CFRAME_SIZE);
4088 for (i = 11; i >= 4; i--) /* offset r4-r11 */
4089 fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 2+(11-i));
4090 fprintf(ctx->fp,
4091 "\t.align 2\n"
4092 ".LEFDE0:\n\n");
4093#if LJ_HASFFI
4094 fprintf(ctx->fp,
4095 ".LSFDE1:\n"
4096 "\t.long .LEFDE1-.LASFDE1\n"
4097 ".LASFDE1:\n"
4098 "\t.long .Lframe0\n"
4099 "\t.long lj_vm_ffi_call\n"
4100 "\t.long %d\n"
4101 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
4102 "\t.byte 0x8e\n\t.uleb128 1\n" /* offset lr */
4103 "\t.byte 0x8b\n\t.uleb128 2\n" /* offset r11 */
4104 "\t.byte 0x85\n\t.uleb128 3\n" /* offset r5 */
4105 "\t.byte 0x84\n\t.uleb128 4\n" /* offset r4 */
4106 "\t.byte 0xd\n\t.uleb128 0xb\n" /* def_cfa_register r11 */
4107 "\t.align 2\n"
4108 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
4109#endif
4110 break;
4111 default:
4112 break;
4113 }
4114}
4115
diff --git a/libraries/luajit-2.0/src/buildvm_arm.h b/libraries/luajit-2.0/src/buildvm_arm.h
new file mode 100644
index 0000000..9d26dd8
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_arm.h
@@ -0,0 +1,7487 @@
1/*
2** This file has been pre-processed with DynASM.
3** http://luajit.org/dynasm.html
4** DynASM version 1.3.0, DynASM arm version 1.3.0
5** DO NOT EDIT! The original file is in "buildvm_arm.dasc".
6*/
7
8#if DASM_VERSION != 10300
9#error "Version mismatch between DynASM and included encoding engine"
10#endif
11
12#define DASM_SECTION_CODE_OP 0
13#define DASM_SECTION_CODE_SUB 1
14#define DASM_MAXSECTION 2
15static const unsigned int build_actionlist[5777] = {
160x00010001,
170x00060014,
180xe3160000,
190x000a0000,
200x0a000000,
210x00050015,
220xe51c6004,
230xe3e01000,
240x000a0000,
250xe1a0900c,
260xe50a1004,
270xe24aa008,
280x00060016,
290xe28bb008,
300xe2160000,
310x000a0000,
320xe58db004,
330x0a000000,
340x00050017,
350x00060018,
360xe3c6c000,
370x000a0000,
380xe3500000,
390x000a0000,
400xe049c00c,
410x1a000000,
420x00050014,
430xe508c000,
440x000d8180,
450xe59d5014,
460xe3e03000,
470x000a0000,
480xe2499008,
490xe25b2008,
500xe1a05185,
510xe5073000,
520x000d8180,
530x0a000000,
540x00050002,
550x0006000b,
560xe2522008,
570xe0ca00d8,
580xe0c900f8,
590x1a000000,
600x0005000b,
610x0006000c,
620xe155000b,
630x1a000000,
640x00050006,
650x0006000d,
660xe5089000,
670x000d8180,
680x00060019,
690x00000000,
700xe59db010,
710xe3a00000,
720xe508b000,
730x000d8180,
740x0006001a,
750xe28dd01c,
760xe8bd8ff0,
770x00060010,
780xba000000,
790x00050007,
800xe5182000,
810x000d8180,
820xe3e01000,
830x000a0000,
840xe1590002,
850x2a000000,
860x00050008,
870xe5891004,
880xe28bb008,
890xe2899008,
900xea000000,
910x0005000c,
920x00060011,
930xe04b0005,
940xe3550000,
950x10499000,
960xea000000,
970x0005000d,
980x00060012,
990xe5089000,
1000x000d8180,
1010xe1a01005,
1020xe1a00008,
1030xeb000000,
1040x00030000,
1050xe5189000,
1060x000d8180,
1070xea000000,
1080x0005000c,
1090x0006001b,
1100xe1a0d000,
1110xe1a00001,
1120x0006001c,
1130xe59d800c,
1140xe3e03000,
1150x000a0000,
1160xe5182000,
1170x000d8180,
1180xe5023000,
1190x000d8180,
1200xea000000,
1210x0005001a,
1220x0006001d,
1230x00000000,
1240xe3c00000,
1250x000a0000,
1260xe1a0d000,
1270x0006001e,
1280xe59d800c,
1290xe3a040ff,
1300xe3a0b010,
1310xe1a04184,
1320xe5189000,
1330x000d8180,
1340xe5187000,
1350x000d8180,
1360xe3e00000,
1370x000a0000,
1380xe249a008,
1390xe5196004,
1400xe2877000,
1410x000a0000,
1420xe3e01000,
1430x000a0000,
1440xe5090004,
1450xe5071000,
1460x000d8180,
1470xea000000,
1480x00050016,
1490x0006001f,
1500xe3a01000,
1510x000a0000,
1520xea000000,
1530x00050002,
1540x00060020,
1550xe089b00b,
1560xe04aa009,
1570xe1a00008,
1580xe5089000,
1590x000d8180,
1600xe2866004,
1610xe508b000,
1620x000d8180,
1630xe1a021aa,
1640x0006000c,
1650xe58d6008,
1660xeb000000,
1670x00030000,
1680xe5189000,
1690x000d8180,
1700xe518b000,
1710x000d8180,
1720xe5192008,
1730xe04bb009,
1740xe5126000,
1750x000d8180,
1760xe5d6c000,
1770xe496e004,
1780xe797c10c,
1790xe004a2ae,
1800xe08aa009,
1810xe12fff1c,
1820x00060021,
1830xe92d4ff0,
1840xe24dd01c,
1850xe1a08000,
1860xe5107000,
1870x000d8180,
1880x00000000,
1890xe1a09001,
1900xe2877000,
1910x000a0000,
1920xe58d800c,
1930xe3a06000,
1940x000a0000,
1950xe58d2014,
1960xe28d1000,
1970x000a0000,
1980xe5580000,
1990x000d8180,
2000xe58d2018,
2010xe5081000,
2020x000d8180,
2030xe58d2010,
2040xe3500000,
2050xe58d8008,
2060x0a000000,
2070x00050003,
2080xe1a0a009,
2090xe5189000,
2100x000d8180,
2110xe5180000,
2120x000d8180,
2130xe3a040ff,
2140xe5482000,
2150x000d8180,
2160xe040b009,
2170xe5196004,
2180xe1a04184,
2190xe3e01000,
2200x000a0000,
2210xe28bb008,
2220xe2160000,
2230x000a0000,
2240xe5071000,
2250x000d8180,
2260xe58db004,
2270x0a000000,
2280x00050017,
2290xea000000,
2300x00050018,
2310x00060022,
2320xe92d4ff0,
2330xe24dd01c,
2340xe3a06000,
2350x000a0000,
2360xe58d3018,
2370xea000000,
2380x00050001,
2390x00060023,
2400xe92d4ff0,
2410xe24dd01c,
2420xe3a06000,
2430x000a0000,
2440x0006000b,
2450xe510b000,
2460x000d8180,
2470xe58d2014,
2480xe1a08000,
2490xe58d000c,
2500xe1a09001,
2510xe508d000,
2520x000d8180,
2530x00000000,
2540xe5187000,
2550x000d8180,
2560xe58d0008,
2570xe58db010,
2580xe2877000,
2590x000a0000,
2600x0006000d,
2610xe518c000,
2620x000d8180,
2630xe5180000,
2640x000d8180,
2650xe3a040ff,
2660xe0866009,
2670xe1a04184,
2680xe046600c,
2690xe3e01000,
2700x000a0000,
2710xe040b009,
2720xe5071000,
2730x000d8180,
2740x00060024,
2750xe14920d8,
2760xe3730000,
2770x000a0000,
2780x1a000000,
2790x00050025,
2800x00060026,
2810xe5096004,
2820xe5126000,
2830x000d8180,
2840xe5d6c000,
2850xe496e004,
2860xe797c10c,
2870xe004a2ae,
2880xe08aa009,
2890xe12fff1c,
2900x00060027,
2910xe92d4ff0,
2920xe24dd01c,
2930xe1a08000,
2940xe510a000,
2950x000d8180,
2960xe58d000c,
2970xe518c000,
2980x000d8180,
2990xe58d0008,
3000xe518b000,
3010x000d8180,
3020xe04aa00c,
3030xe508d000,
3040x000d8180,
3050xe3a0c000,
3060xe58da014,
3070xe58dc018,
3080xe58db010,
3090xe12fff33,
3100xe5187000,
3110x000d8180,
3120xe1b09000,
3130xe3a06000,
3140x000a0000,
3150xe2877000,
3160x000a0000,
3170x1a000000,
3180x0005000d,
3190xea000000,
3200x00050019,
3210x00060015,
3220x00000000,
3230xe51c2008,
3240xe5190010,
3250xe1a03009,
3260xe1a0900c,
3270x00000000,
3280xe3500001,
3290x00000000,
3300xe513600c,
3310xe5122000,
3320x000d8180,
3330xe3e0e000,
3340x000a0000,
3350xe08a100b,
3360xe501e004,
3370x00000000,
3380x9a000000,
3390x00050001,
3400x00000000,
3410xe5125000,
3420x000d8180,
3430xe12fff10,
3440x00000000,
3450x0006000b,
3460x0a000000,
3470x00050028,
3480xe5192008,
3490xe2433010,
3500xe043b009,
3510xea000000,
3520x00050029,
3530x00000000,
3540x0006002a,
3550xe516e004,
3560xe2431010,
3570xe1ca20d0,
3580xe5089000,
3590x000d8180,
3600xe004baae,
3610xe004a2ae,
3620xe089000b,
3630xe0510000,
3640x11c120f0,
3650x11a02000,
3660x1a000000,
3670x0005002b,
3680xe18920fa,
3690xea000000,
3700x0005002c,
3710x0006002d,
3720xe089100c,
3730xea000000,
3740x00050002,
3750x0006002e,
3760xe2471000,
3770x000a0000,
3780xe3e03000,
3790x000a0000,
3800xe581c000,
3810xe5813004,
3820x0006000c,
3830xe3e03000,
3840x000a0000,
3850xe58db000,
3860xe58d3004,
3870xe1a0200d,
3880xea000000,
3890x00050001,
3900x0006002f,
3910xe004caae,
3920xe58db000,
3930xe3e03000,
3940x000a0000,
3950xe089100c,
3960xe58d3004,
3970xe1a0200d,
3980xea000000,
3990x00050001,
4000x00060030,
4010xe089100c,
4020xe089200b,
4030x0006000b,
4040xe5089000,
4050x000d8180,
4060xe1a00008,
4070xe58d6008,
4080xeb000000,
4090x00030001,
4100x00000000,
4110xe5189000,
4120x000d8180,
4130x00000000,
4140xe3500000,
4150x0a000000,
4160x00050003,
4170xe1c020d0,
4180xe5d6c000,
4190xe496e004,
4200xe18920fa,
4210xe797c10c,
4220xe004a2ae,
4230xe1a0b82e,
4240xe12fff1c,
4250x0006000d,
4260xe2690000,
4270x000a0000,
4280xe5189000,
4290x000d8180,
4300xe3a0b010,
4310xe509600c,
4320xe0806009,
4330xe5192008,
4340xea000000,
4350x00050026,
4360x00060031,
4370xe089100c,
4380xea000000,
4390x00050002,
4400x00060032,
4410xe2471000,
4420x000a0000,
4430xe3e03000,
4440x000a0000,
4450xe581c000,
4460xe5813004,
4470x0006000c,
4480xe3e03000,
4490x000a0000,
4500xe58db000,
4510xe58d3004,
4520xe1a0200d,
4530xea000000,
4540x00050001,
4550x00060033,
4560xe004caae,
4570xe58db000,
4580xe3e03000,
4590x000a0000,
4600xe089100c,
4610xe58d3004,
4620xe1a0200d,
4630xea000000,
4640x00050001,
4650x00060034,
4660xe089100c,
4670xe089200b,
4680x0006000b,
4690xe5089000,
4700x000d8180,
4710xe1a00008,
4720xe58d6008,
4730xeb000000,
4740x00030002,
4750x00000000,
4760xe5189000,
4770x000d8180,
4780x00000000,
4790xe3500000,
4800xe18920da,
4810x0a000000,
4820x00050003,
4830xe5d6c000,
4840xe1c020f0,
4850xe496e004,
4860xe797c10c,
4870xe004a2ae,
4880xe1a0b82e,
4890xe12fff1c,
4900x0006000d,
4910xe2690000,
4920x000a0000,
4930xe5189000,
4940x000d8180,
4950xe3a0b018,
4960xe1c921f0,
4970xe509600c,
4980xe0806009,
4990xe5192008,
5000xea000000,
5010x00050026,
5020x00060035,
5030xe1a00008,
5040xe2466004,
5050xe1a0100a,
5060xe5089000,
5070x000d8180,
5080xe1a0200b,
5090xe58d6008,
5100xe20e30ff,
5110xeb000000,
5120x00030003,
5130x0006000d,
5140x00000000,
5150xe5189000,
5160x000d8180,
5170x00000000,
5180xe3500001,
5190x8a000000,
5200x00050036,
5210x0006000e,
5220xe1d6c0b2,
5230xe2866004,
5240xe086c10c,
5250x224c6b80,
5260x0006002c,
5270xe5d6c000,
5280xe496e004,
5290xe797c10c,
5300xe004a2ae,
5310xe1a0b82e,
5320xe12fff1c,
5330x00060037,
5340xe516e004,
5350xe1ca00d0,
5360xe00422ae,
5370xe18900f2,
5380xea000000,
5390x0005002c,
5400x00060038,
5410xe59a1004,
5420xe3e00000,
5430x000a0000,
5440xe1500001,
5450xea000000,
5460x0005000e,
5470x00060039,
5480xe59a1004,
5490xe3710000,
5500x000a0000,
5510xea000000,
5520x0005000e,
5530x0006003a,
5540xe2466004,
5550xe5089000,
5560x000d8180,
5570xe1a00008,
5580xe58d6008,
5590xeb000000,
5600x00030004,
5610xea000000,
5620x0005000d,
5630x0006003b,
5640x00000000,
5650xe2466004,
5660xe5089000,
5670x000d8180,
5680xe1a00008,
5690xe1a0100e,
5700xe58d6008,
5710xeb000000,
5720x00030005,
5730xea000000,
5740x0005000d,
5750x00000000,
5760x0006003c,
5770xe004caae,
5780xe004b6ae,
5790xe089200c,
5800xe085300b,
5810xea000000,
5820x00050001,
5830x0006003d,
5840xe004caae,
5850xe004b6ae,
5860xe089300c,
5870xe085200b,
5880xea000000,
5890x00050001,
5900x0006003e,
5910xe516e008,
5920xe2466004,
5930xe089200b,
5940xe089300b,
5950xea000000,
5960x00050001,
5970x0006003f,
5980xe004caae,
5990xe004b6ae,
6000xe089200c,
6010xe089300b,
6020x0006000b,
6030xe20ec0ff,
6040xe089100a,
6050xe5089000,
6060x000d8180,
6070xe1a00008,
6080xe58d6008,
6090xe58dc000,
6100xeb000000,
6110x00030006,
6120x00000000,
6130xe5189000,
6140x000d8180,
6150x00000000,
6160xe3500000,
6170x0a000000,
6180x0005002c,
6190x00060036,
6200xe0401009,
6210xe500600c,
6220xe2816000,
6230x000a0000,
6240xe1a09000,
6250xe3a0b010,
6260xea000000,
6270x00050024,
6280x00060040,
6290xe089100b,
6300xe5089000,
6310x000d8180,
6320xe1a00008,
6330xe58d6008,
6340xeb000000,
6350x00030007,
6360x00000000,
6370xe5189000,
6380x000d8180,
6390x00000000,
6400xe3500000,
6410x1a000000,
6420x00050036,
6430xe799000b,
6440xea000000,
6450x00050041,
6460x00000000,
6470xea000000,
6480x00050036,
6490x00000000,
6500x00060025,
6510xe1a00008,
6520xe508c000,
6530x000d8180,
6540xe2491008,
6550xe58d6008,
6560xe089200b,
6570x00000000,
6580xe1a0a009,
6590x00000000,
6600xeb000000,
6610x00030008,
6620x00000000,
6630xe1a0900a,
6640x00000000,
6650xe5192008,
6660xe28bb008,
6670xe5096004,
6680xe5126000,
6690x000d8180,
6700xe5d6c000,
6710xe496e004,
6720xe797c10c,
6730xe004a2ae,
6740xe08aa009,
6750xe12fff1c,
6760x00060042,
6770xe1a00008,
6780xe5089000,
6790x000d8180,
6800xe24a1008,
6810xe58d6008,
6820xe08a200b,
6830xeb000000,
6840x00030008,
6850x00000000,
6860xe5189000,
6870x000d8180,
6880x00000000,
6890xe51a2008,
6900xe5196004,
6910xe28bb008,
6920xea000000,
6930x00050043,
6940x00060044,
6950xe1a00008,
6960xe5089000,
6970x000d8180,
6980xe1a0100a,
6990xe58d6008,
7000xeb000000,
7010x00030009,
7020x00000000,
7030xe5189000,
7040x000d8180,
7050x00000000,
7060xe556c004,
7070x00000000,
7080xe516e004,
7090x00000000,
7100xe35c0000,
7110x000a0000,
7120x00000000,
7130xe004a2ae,
7140xe1a0b82e,
7150x00000000,
7160x0a000000,
7170x00070000,
7180x00000000,
7190xea000000,
7200x00070000,
7210x00060045,
7220xe1c900d0,
7230xe35b0008,
7240x3a000000,
7250x00050046,
7260xe3710000,
7270x000a0000,
7280x8a000000,
7290x00050046,
7300xe5196004,
7310xe14900f8,
7320xe1a0c009,
7330xe25ba008,
7340xe28bb008,
7350x0a000000,
7360x00050047,
7370x0006000b,
7380xe1cc00d8,
7390xe25aa008,
7400xe0cc00f8,
7410x1a000000,
7420x0005000b,
7430xea000000,
7440x00050047,
7450x00060048,
7460xe5991004,
7470xe35b0008,
7480x3a000000,
7490x00050046,
7500xe3710000,
7510x000a0000,
7520x33e01000,
7530x000a0000,
7540xe2613000,
7550x000a0000,
7560xe1a03183,
7570xe18200d3,
7580xea000000,
7590x00050049,
7600x0006004a,
7610xe1c900d0,
7620xe35b0008,
7630x3a000000,
7640x00050046,
7650xe3710000,
7660x000a0000,
7670x13710000,
7680x000a0000,
7690x1a000000,
7700x00050006,
7710x0006000b,
7720xe510c000,
7730x000d8180,
7740x0006000c,
7750x00000000,
7760xe3e01000,
7770x000a0000,
7780xe517b000,
7790x000d8180,
7800xe35c0000,
7810x0a000000,
7820x00050049,
7830xe51c2000,
7840x000d8180,
7850xe51b3000,
7860x000d8180,
7870xe51ce000,
7880x000d8180,
7890xe0022003,
7900xe0822082,
7910xe08ee182,
7920x0006000d,
7930xe14e20d0,
7940x000c8100,
7950xe14e00d0,
7960x000c8100,
7970xe51ee000,
7980x000d8180,
7990xe152000b,
8000x03730000,
8010x000a0000,
8020x0a000000,
8030x00050005,
8040xe35e0000,
8050x1a000000,
8060x0005000d,
8070x0006000e,
8080xe1a0000c,
8090xe3e01000,
8100x000a0000,
8110xea000000,
8120x00050049,
8130x0006000f,
8140xe3710000,
8150x000a0000,
8160x1a000000,
8170x00050049,
8180xea000000,
8190x0005000e,
8200x00060010,
8210xe3710000,
8220x000a0000,
8230x00000000,
8240x21e01001,
8250x33a01000,
8260x000a0000,
8270xe0873101,
8280xe513c000,
8290x000d8180,
8300xea000000,
8310x0005000c,
8320x0006004b,
8330xe1c900d0,
8340xe1c920d8,
8350xe35b0010,
8360x3a000000,
8370x00050046,
8380xe3710000,
8390x000a0000,
8400x0510c000,
8410x000d8180,
8420x03730000,
8430x000a0000,
8440x05503000,
8450x000d8180,
8460x035c0000,
8470x1a000000,
8480x00050046,
8490xe3130000,
8500x000a0000,
8510xe5002000,
8520x000d8180,
8530x0a000000,
8540x00050049,
8550xe5172000,
8560x000d8180,
8570xe3c33000,
8580x000a0000,
8590xe5070000,
8600x000d8180,
8610xe5403000,
8620x000d8180,
8630xe5002000,
8640x000d8180,
8650xea000000,
8660x00050049,
8670x0006004c,
8680xe1c920d0,
8690xe35b0010,
8700x3a000000,
8710x00050046,
8720xe1a01002,
8730xe3730000,
8740x000a0000,
8750x00000000,
8760x1a000000,
8770x00050046,
8780xe1a00008,
8790xe2892008,
8800x00000000,
8810xe1a0a009,
8820x00000000,
8830xeb000000,
8840x0003000a,
8850x00000000,
8860xe1a0900a,
8870x00000000,
8880xe1c000d0,
8890xea000000,
8900x00050049,
8910x0006004d,
8920xe1c900d0,
8930xe35b0008,
8940x3a000000,
8950x00050046,
8960xe3710000,
8970x000a0000,
8980x9a000000,
8990x00050049,
9000xea000000,
9010x00050046,
9020x0006004e,
9030xe1c900d0,
9040xe35b0008,
9050x3a000000,
9060x00050046,
9070xe3710000,
9080x000a0000,
9090x0a000000,
9100x00050049,
9110xe5173000,
9120x000d8180,
9130xe5089000,
9140x000d8180,
9150xe3710000,
9160x000a0000,
9170x93530000,
9180xe58d6008,
9190x8a000000,
9200x00050046,
9210xe5170000,
9220x000d8180,
9230xe5171000,
9240x000d8180,
9250xe1500001,
9260xab000000,
9270x0005004f,
9280xe1a00008,
9290xe1a01009,
9300xeb000000,
9310x0003000b,
9320xe5189000,
9330x000d8180,
9340xe3e01000,
9350x000a0000,
9360xea000000,
9370x00050049,
9380x00060050,
9390x00000000,
9400xe1c900d0,
9410xe35b0008,
9420x3a000000,
9430x00050046,
9440xe3e03000,
9450x000a0000,
9460xe3710000,
9470x000a0000,
9480x1a000000,
9490x00050046,
9500xe18920fb,
9510xe5196004,
9520xe1a01000,
9530xe5089000,
9540x000d8180,
9550xe1a00008,
9560xe5089000,
9570x000d8180,
9580xe2892008,
9590xe58d6008,
9600xeb000000,
9610x0003000c,
9620x00000000,
9630xe5189000,
9640x000d8180,
9650x00000000,
9660xe3500000,
9670x03e01000,
9680x000a0000,
9690x0a000000,
9700x00050049,
9710xe1c900d8,
9720xe1c921d0,
9730xe3a0b000,
9740x000a0000,
9750xe14900f8,
9760xe1c920f0,
9770xea000000,
9780x00050047,
9790x00060051,
9800xe1c900d0,
9810xe35b0008,
9820x3a000000,
9830x00050046,
9840xe3710000,
9850x000a0000,
9860x1a000000,
9870x00050046,
9880x00000000,
9890xe510c000,
9900x000d8180,
9910x00000000,
9920xe14220d0,
9930x000c8100,
9940xe5196004,
9950x00000000,
9960xe35c0000,
9970x1a000000,
9980x00050046,
9990x00000000,
10000xe3e01000,
10010x000a0000,
10020xe3a0b000,
10030x000a0000,
10040xe14920f8,
10050xe589100c,
10060xea000000,
10070x00050047,
10080x00060052,
10090xe1c900d0,
10100xe1c920d8,
10110xe35b0010,
10120x3a000000,
10130x00050046,
10140xe3710000,
10150x000a0000,
10160x03730000,
10170x000a0000,
10180x1a000000,
10190x00050046,
10200xe510c000,
10210x000d8180,
10220xe510b000,
10230x000d8180,
10240xe2822001,
10250xe5196004,
10260xe152000c,
10270xe08bb182,
10280xe14920f8,
10290x31cb00d0,
10300xe3a0b000,
10310x000a0000,
10320x2a000000,
10330x00050002,
10340x0006000b,
10350xe3710000,
10360x000a0000,
10370x13a0b000,
10380x000a0000,
10390x11c900f0,
10400xea000000,
10410x00050047,
10420x0006000c,
10430xe510c000,
10440x000d8180,
10450xe1a01002,
10460xe35c0000,
10470x0a000000,
10480x00050047,
10490x00000000,
10500xe1a0a009,
10510x00000000,
10520xeb000000,
10530x0003000d,
10540x00000000,
10550xe1a0900a,
10560x00000000,
10570xe3500000,
10580x0a000000,
10590x00050047,
10600xe1c000d0,
10610xea000000,
10620x0005000b,
10630x00060053,
10640xe1c900d0,
10650xe35b0008,
10660x3a000000,
10670x00050046,
10680xe3710000,
10690x000a0000,
10700x1a000000,
10710x00050046,
10720x00000000,
10730xe510c000,
10740x000d8180,
10750x00000000,
10760xe14220d0,
10770x000c8100,
10780xe5196004,
10790x00000000,
10800xe35c0000,
10810x1a000000,
10820x00050046,
10830x00000000,
10840xe3a00000,
10850xe3e01000,
10860x000a0000,
10870xe3a0b000,
10880x000a0000,
10890xe14920f8,
10900xe1c900f8,
10910xea000000,
10920x00050047,
10930x00060054,
10940xe557a000,
10950x000d8180,
10960xe35b0008,
10970x3a000000,
10980x00050046,
10990xe31a0000,
11000x000a0000,
11010xe1a0c009,
11020xe2899008,
11030x03a06000,
11040x000a0000,
11050x13a06000,
11060x000a0000,
11070xe24bb008,
11080xea000000,
11090x00050024,
11100x00060055,
11110xe1c900d0,
11120xe1c920d8,
11130xe35b0010,
11140x3a000000,
11150x00050046,
11160xe557a000,
11170x000d8180,
11180xe3730000,
11190x000a0000,
11200x1a000000,
11210x00050046,
11220xe1a0c009,
11230xe1c900f8,
11240xe1c920f0,
11250xe31a0000,
11260x000a0000,
11270xe2899010,
11280x03a06000,
11290x000a0000,
11300x13a06000,
11310x000a0000,
11320xe24bb010,
11330xea000000,
11340x00050024,
11350x00060056,
11360xe1c900d0,
11370xe35b0008,
11380x3a000000,
11390x00050046,
11400xe3710000,
11410x000a0000,
11420x00000000,
11430x1a000000,
11440x00050046,
11450xe5196004,
11460xe5089000,
11470x000d8180,
11480xe5101000,
11490x000d8180,
11500xe550a000,
11510x000d8180,
11520xe510c000,
11530x000d8180,
11540xe081200b,
11550xe081300a,
11560xe58d6008,
11570xe153000c,
11580x0a000000,
11590x00050046,
11600xe5103000,
11610x000d8180,
11620xe510c000,
11630x000d8180,
11640xe35a0000,
11650x000a0000,
11660x91520003,
11670x935c0000,
11680x8a000000,
11690x00050046,
11700x0006000b,
11710xe2422008,
11720xe2899008,
11730xe24bb008,
11740xe5002000,
11750x000d8180,
11760xe5089000,
11770x000d8180,
11780x0006000c,
11790xe18920dc,
11800xe15c000b,
11810x118120fc,
11820xe28cc008,
11830x1a000000,
11840x0005000c,
11850xe3a02000,
11860xe1a0a000,
11870xe3a03000,
11880xeb000000,
11890x00050021,
11900x0006000e,
11910xe51a2000,
11920x000d8180,
11930xe3e01000,
11940x000a0000,
11950xe51a3000,
11960x000d8180,
11970xe5071000,
11980x000d8180,
11990xe3500000,
12000x000a0000,
12010x00000000,
12020xe5189000,
12030x000d8180,
12040x8a000000,
12050x00050008,
12060xe053b002,
12070xe5180000,
12080x000d8180,
12090xe089100b,
12100x0a000000,
12110x00050006,
12120xe1510000,
12130xe3a0c000,
12140x8a000000,
12150x00050009,
12160xe24b3008,
12170xe50a2000,
12180x000d8180,
12190x0006000f,
12200xe18200dc,
12210xe15c0003,
12220xe18900fc,
12230xe28cc008,
12240x1a000000,
12250x0005000f,
12260x00060010,
12270xe3e02000,
12280x000a0000,
12290xe28bb010,
12300x00060011,
12310xe5092004,
12320xe249a008,
12330xe2160000,
12340x000a0000,
12350xe58d6008,
12360xe58db004,
12370x0a000000,
12380x00050017,
12390xea000000,
12400x00050018,
12410x00060012,
12420xe16300d8,
12430xe3e02000,
12440x000a0000,
12450xe3a0b000,
12460x000a0000,
12470xe50a3000,
12480x000d8180,
12490xe1c900f0,
12500xea000000,
12510x00050011,
12520x00060013,
12530xe1a00008,
12540xe1a011ab,
12550xeb000000,
12560x00030000,
12570xe3a00000,
12580xea000000,
12590x0005000e,
12600x00060057,
12610x00000000,
12620xe5120000,
12630x000d8180,
12640xe5196004,
12650xe5089000,
12660x000d8180,
12670xe5101000,
12680x000d8180,
12690xe550a000,
12700x000d8180,
12710xe510c000,
12720x000d8180,
12730xe081200b,
12740xe081300a,
12750xe58d6008,
12760xe153000c,
12770x0a000000,
12780x00050046,
12790xe5103000,
12800x000d8180,
12810xe510c000,
12820x000d8180,
12830xe35a0000,
12840x000a0000,
12850x91520003,
12860x935c0000,
12870x8a000000,
12880x00050046,
12890x0006000b,
12900xe5002000,
12910x000d8180,
12920xe5089000,
12930x000d8180,
12940x0006000c,
12950xe18920dc,
12960xe15c000b,
12970x118120fc,
12980xe28cc008,
12990x1a000000,
13000x0005000c,
13010xe3a02000,
13020xe1a0a000,
13030xe3a03000,
13040xeb000000,
13050x00050021,
13060x0006000e,
13070xe51a2000,
13080x000d8180,
13090xe3e01000,
13100x000a0000,
13110xe51a3000,
13120x000d8180,
13130xe5071000,
13140x000d8180,
13150xe3500000,
13160x000a0000,
13170x00000000,
13180xe5189000,
13190x000d8180,
13200x8a000000,
13210x00050008,
13220xe053b002,
13230xe5180000,
13240x000d8180,
13250xe089100b,
13260x0a000000,
13270x00050006,
13280xe1510000,
13290xe3a0c000,
13300x8a000000,
13310x00050009,
13320xe24b3008,
13330xe50a2000,
13340x000d8180,
13350x0006000f,
13360xe18200dc,
13370xe15c0003,
13380xe18900fc,
13390xe28cc008,
13400x1a000000,
13410x0005000f,
13420x00060010,
13430xe1a0a009,
13440xe28bb008,
13450xe2160000,
13460x000a0000,
13470xe58d6008,
13480xe58db004,
13490x0a000000,
13500x00050017,
13510xea000000,
13520x00050018,
13530x00060012,
13540xe1a00008,
13550xe1a0100a,
13560xeb000000,
13570x0003000e,
13580x00060013,
13590xe1a00008,
13600xe1a011ab,
13610xeb000000,
13620x00030000,
13630xe3a00000,
13640xea000000,
13650x0005000e,
13660x00060058,
13670xe5180000,
13680x000d8180,
13690xe089100b,
13700xe5089000,
13710x000d8180,
13720xe3100000,
13730x000a0000,
13740xe5081000,
13750x000d8180,
13760x00000000,
13770xe3a00000,
13780x000a0000,
13790xe3a02000,
13800x0a000000,
13810x00050046,
13820xe5082000,
13830x000d8180,
13840xe5480000,
13850x000d8180,
13860xea000000,
13870x0005001a,
13880x00060059,
13890xe1c900d0,
13900xe35b0008,
13910x3a000000,
13920x00050046,
13930xe3710000,
13940x000a0000,
13950x0a000000,
13960x00050049,
13970x8a000000,
13980x00050046,
13990xe1a02081,
14000xe292c980,
14010x5a000000,
14020x00050002,
14030xe3e03ff8,
14040xe053cacc,
14050xe1a03581,
14060xe1a02580,
14070xe3833480,
14080xe26ce020,
14090xe1833aa0,
14100x9a000000,
14110x00050003,
14120xe1822e13,
14130xe1a00c33,
14140xe1120fc1,
14150x12800001,
14160xe3510000,
14170xb2600000,
14180x0006000b,
14190xe3e01000,
14200x000a0000,
14210xea000000,
14220x00050049,
14230x0006000c,
14240xe1822000,
14250xe1120fc1,
14260x03a00000,
14270x13e00000,
14280xe3e01000,
14290x000a0000,
14300xea000000,
14310x00050049,
14320x0006000d,
14330x03530480,
14340x03520000,
14350x1a000000,
14360x00050004,
14370xe3510000,
14380x43a00480,
14390x4a000000,
14400x0005000b,
14410x0006000e,
14420x00000000,
14430xeb000000,
14440x0005005a,
14450xea000000,
14460x00050049,
14470x0006005b,
14480xe1c900d0,
14490xe35b0008,
14500x3a000000,
14510x00050046,
14520xe3710000,
14530x000a0000,
14540x0a000000,
14550x00050049,
14560x8a000000,
14570x00050046,
14580xe1a02081,
14590xe292c980,
14600x5a000000,
14610x00050002,
14620xe3e03ff8,
14630xe053cacc,
14640xe1a03581,
14650xe1a02580,
14660xe3833480,
14670xe26ce020,
14680xe1833aa0,
14690x9a000000,
14700x00050003,
14710xe1822e13,
14720xe1a00c33,
14730xe1d22fc1,
14740x12900001,
14750x614f00d0,
14760x00051809,
14770x6a000000,
14780x00050049,
14790xe3510000,
14800xb2600000,
14810x0006000b,
14820xe3e01000,
14830x000a0000,
14840xea000000,
14850x00050049,
14860x0006000c,
14870xe1822000,
14880xe1d22fc1,
14890x03a00000,
14900x13a00001,
14910xe3e01000,
14920x000a0000,
14930xea000000,
14940x00050049,
14950x0006000d,
14960x03530480,
14970x1a000000,
14980x00050004,
14990xe3510000,
15000x43a00480,
15010x4a000000,
15020x0005000b,
15030x0006000e,
15040xeb000000,
15050x0005005c,
15060x00000000,
15070xea000000,
15080x00050049,
15090x00040007,
15100x00060013,
15110x00020000,
15120x00000000,
15130x41e00000,
15140x0006005d,
15150xe1c900d0,
15160xe35b0008,
15170x3a000000,
15180x00050046,
15190xe3710000,
15200x000a0000,
15210x8a000000,
15220x00050046,
15230x13c11480,
15240x1a000000,
15250x00050049,
15260xe3500000,
15270xb2700000,
15280x614f00d0,
15290x00051813,
15300x00060049,
15310xe5196004,
15320xe14900f8,
15330x0006005e,
15340xe3a0b000,
15350x000a0000,
15360x00060047,
15370xe2160000,
15380x000a0000,
15390x0516e004,
15400xe58db004,
15410xe249a008,
15420x1a000000,
15430x00050018,
15440xe004caae,
15450x0006000f,
15460xe15c000b,
15470x8a000000,
15480x00050006,
15490xe00402ae,
15500xe5d6c000,
15510xe496e004,
15520xe04a9000,
15530xe797c10c,
15540xe004a2ae,
15550xe1a0b82e,
15560xe12fff1c,
15570x00060010,
15580xe08a100b,
15590xe3e00000,
15600x000a0000,
15610xe28bb008,
15620xe5010004,
15630xea000000,
15640x0005000f,
15650x0006005f,
15660xe1c900d0,
15670xe35b0008,
15680x3a000000,
15690x00050046,
15700x00000000,
15710xe3710000,
15720x000a0000,
15730x2a000000,
15740x00050046,
15750x00000000,
15760xe1a0a009,
15770x00000000,
15780xeb000000,
15790x0003000f,
15800x00000000,
15810xe1a0900a,
15820x00000000,
15830xea000000,
15840x00050049,
15850x00060060,
15860xe1c900d0,
15870xe35b0008,
15880x3a000000,
15890x00050046,
15900xe3710000,
15910x000a0000,
15920x2a000000,
15930x00050046,
15940x00000000,
15950xe1a0a009,
15960x00000000,
15970xeb000000,
15980x00030010,
15990x00000000,
16000xe1a0900a,
16010x00000000,
16020xea000000,
16030x00050049,
16040x00060061,
16050xe1c900d0,
16060xe35b0008,
16070x3a000000,
16080x00050046,
16090xe3710000,
16100x000a0000,
16110x2a000000,
16120x00050046,
16130x00000000,
16140xe1a0a009,
16150x00000000,
16160xeb000000,
16170x00030011,
16180x00000000,
16190xe1a0900a,
16200x00000000,
16210xea000000,
16220x00050049,
16230x00060062,
16240xe1c900d0,
16250xe35b0008,
16260x3a000000,
16270x00050046,
16280xe3710000,
16290x000a0000,
16300x2a000000,
16310x00050046,
16320x00000000,
16330xe1a0a009,
16340x00000000,
16350xeb000000,
16360x00030012,
16370x00000000,
16380xe1a0900a,
16390x00000000,
16400xea000000,
16410x00050049,
16420x00060063,
16430xe1c900d0,
16440xe35b0008,
16450x3a000000,
16460x00050046,
16470xe3710000,
16480x000a0000,
16490x2a000000,
16500x00050046,
16510x00000000,
16520xe1a0a009,
16530x00000000,
16540xeb000000,
16550x00030013,
16560x00000000,
16570xe1a0900a,
16580x00000000,
16590xea000000,
16600x00050049,
16610x00060064,
16620xe1c900d0,
16630xe35b0008,
16640x3a000000,
16650x00050046,
16660xe3710000,
16670x000a0000,
16680x2a000000,
16690x00050046,
16700x00000000,
16710xe1a0a009,
16720x00000000,
16730xeb000000,
16740x00030014,
16750x00000000,
16760xe1a0900a,
16770x00000000,
16780xea000000,
16790x00050049,
16800x00060065,
16810xe1c900d0,
16820xe35b0008,
16830x3a000000,
16840x00050046,
16850xe3710000,
16860x000a0000,
16870x2a000000,
16880x00050046,
16890x00000000,
16900xe1a0a009,
16910x00000000,
16920xeb000000,
16930x00030015,
16940x00000000,
16950xe1a0900a,
16960x00000000,
16970xea000000,
16980x00050049,
16990x00060066,
17000xe1c900d0,
17010xe35b0008,
17020x3a000000,
17030x00050046,
17040xe3710000,
17050x000a0000,
17060x2a000000,
17070x00050046,
17080x00000000,
17090xe1a0a009,
17100x00000000,
17110xeb000000,
17120x00030016,
17130x00000000,
17140xe1a0900a,
17150x00000000,
17160xea000000,
17170x00050049,
17180x00060067,
17190xe1c900d0,
17200xe35b0008,
17210x3a000000,
17220x00050046,
17230xe3710000,
17240x000a0000,
17250x2a000000,
17260x00050046,
17270x00000000,
17280xe1a0a009,
17290x00000000,
17300xeb000000,
17310x00030017,
17320x00000000,
17330xe1a0900a,
17340x00000000,
17350xea000000,
17360x00050049,
17370x00060068,
17380xe1c900d0,
17390xe35b0008,
17400x3a000000,
17410x00050046,
17420xe3710000,
17430x000a0000,
17440x2a000000,
17450x00050046,
17460x00000000,
17470xe1a0a009,
17480x00000000,
17490xeb000000,
17500x00030018,
17510x00000000,
17520xe1a0900a,
17530x00000000,
17540xea000000,
17550x00050049,
17560x00060069,
17570xe1c900d0,
17580xe35b0008,
17590x3a000000,
17600x00050046,
17610xe3710000,
17620x000a0000,
17630x2a000000,
17640x00050046,
17650x00000000,
17660xe1a0a009,
17670x00000000,
17680xeb000000,
17690x00030019,
17700x00000000,
17710xe1a0900a,
17720x00000000,
17730xea000000,
17740x00050049,
17750x0006006a,
17760xe1c900d0,
17770xe35b0008,
17780x3a000000,
17790x00050046,
17800xe3710000,
17810x000a0000,
17820x2a000000,
17830x00050046,
17840x00000000,
17850xe1a0a009,
17860x00000000,
17870xeb000000,
17880x0003001a,
17890x00000000,
17900xe1a0900a,
17910x00000000,
17920xea000000,
17930x00050049,
17940x0006006b,
17950xe1c900d0,
17960xe35b0008,
17970x3a000000,
17980x00050046,
17990xe3710000,
18000x000a0000,
18010x2a000000,
18020x00050046,
18030x00000000,
18040xe1a0a009,
18050x00000000,
18060xeb000000,
18070x0003001b,
18080x00000000,
18090xe1a0900a,
18100x00000000,
18110xea000000,
18120x00050049,
18130x0006006c,
18140xe1c900d0,
18150xe1c920d8,
18160xe35b0010,
18170x3a000000,
18180x00050046,
18190xe3710000,
18200x000a0000,
18210x33730000,
18220x000a0000,
18230x2a000000,
18240x00050046,
18250x00000000,
18260xe1a0a009,
18270x00000000,
18280xeb000000,
18290x0003001c,
18300x00000000,
18310xe1a0900a,
18320x00000000,
18330xea000000,
18340x00050049,
18350x0006006d,
18360xe1c900d0,
18370xe1c920d8,
18380xe35b0010,
18390x3a000000,
18400x00050046,
18410xe3710000,
18420x000a0000,
18430x33730000,
18440x000a0000,
18450x2a000000,
18460x00050046,
18470x00000000,
18480xe1a0a009,
18490x00000000,
18500xeb000000,
18510x0003001d,
18520x00000000,
18530xe1a0900a,
18540x00000000,
18550xea000000,
18560x00050049,
18570x0006006e,
18580xe1c900d0,
18590xe1c920d8,
18600xe35b0010,
18610x3a000000,
18620x00050046,
18630xe3710000,
18640x000a0000,
18650x33730000,
18660x000a0000,
18670x2a000000,
18680x00050046,
18690x00000000,
18700xe1a0a009,
18710x00000000,
18720xeb000000,
18730x0003001e,
18740x00000000,
18750xe1a0900a,
18760x00000000,
18770xea000000,
18780x00050049,
18790x0006006f,
18800x00060070,
18810xe1c900d0,
18820xe35b0008,
18830x3a000000,
18840x00050046,
18850xe3710000,
18860x000a0000,
18870x2a000000,
18880x00050046,
18890xe14220d0,
18900x000c8100,
18910xeb000000,
18920x0003001f,
18930xea000000,
18940x00050049,
18950x00060071,
18960xe1c900d0,
18970xe1c920d8,
18980xe35b0010,
18990x3a000000,
19000x00050046,
19010xe3710000,
19020x000a0000,
19030x2a000000,
19040x00050046,
19050xe3730000,
19060x000a0000,
19070x1a000000,
19080x00050046,
19090x00000000,
19100xe1a0a009,
19110x00000000,
19120xeb000000,
19130x00030020,
19140x00000000,
19150xe1a0900a,
19160x00000000,
19170xea000000,
19180x00050049,
19190x00060072,
19200xe1c900d0,
19210xe35b0008,
19220x3a000000,
19230x00050046,
19240xe3710000,
19250x000a0000,
19260x2a000000,
19270x00050046,
19280xe1a0200d,
19290x00000000,
19300xe1a0a009,
19310x00000000,
19320xeb000000,
19330x00030021,
19340x00000000,
19350xe1a0900a,
19360x00000000,
19370xe59d2000,
19380xe3e03000,
19390x000a0000,
19400xe5196004,
19410xe14900f8,
19420xe3a0b000,
19430x000a0000,
19440xe1c920f0,
19450xea000000,
19460x00050047,
19470x00060073,
19480xe1c900d0,
19490xe35b0008,
19500x3a000000,
19510x00050046,
19520xe3710000,
19530x000a0000,
19540x2a000000,
19550x00050046,
19560xe2492008,
19570xe5196004,
19580x00000000,
19590xe1a0a009,
19600x00000000,
19610xeb000000,
19620x00030022,
19630x00000000,
19640xe1a0900a,
19650x00000000,
19660xe3a0b000,
19670x000a0000,
19680xe1c900f0,
19690xea000000,
19700x00050047,
19710x00060074,
19720xe1c900d0,
19730xe35b0008,
19740x3a000000,
19750x00050046,
19760xe3710000,
19770x000a0000,
19780xe3a0a008,
19790x1a000000,
19800x00050004,
19810x0006000b,
19820xe18920da,
19830xe15a000b,
19840x2a000000,
19850x00050049,
19860xe3730000,
19870x000a0000,
19880x1a000000,
19890x00050003,
19900xe1500002,
19910xe28aa008,
19920xc1a00002,
19930xea000000,
19940x0005000b,
19950x0006000d,
19960x8a000000,
19970x00050046,
19980xeb000000,
19990x00030023,
20000xe18920da,
20010xea000000,
20020x00050006,
20030x0006000e,
20040x8a000000,
20050x00050046,
20060x0006000f,
20070xe18920da,
20080xe15a000b,
20090x2a000000,
20100x00050049,
20110xe3730000,
20120x000a0000,
20130x2a000000,
20140x00050007,
20150x00060010,
20160x00000000,
20170xeb000000,
20180x00030024,
20190xe28aa008,
20200x81a00002,
20210x81a01003,
20220xea000000,
20230x0005000f,
20240x00060011,
20250x8a000000,
20260x00050046,
20270xe1cd00f0,
20280xe1a00002,
20290xeb000000,
20300x00030023,
20310xe1cd20d0,
20320xea000000,
20330x00050010,
20340x00060075,
20350xe1c900d0,
20360xe35b0008,
20370x3a000000,
20380x00050046,
20390xe3710000,
20400x000a0000,
20410xe3a0a008,
20420x1a000000,
20430x00050004,
20440x0006000b,
20450xe18920da,
20460xe15a000b,
20470x2a000000,
20480x00050049,
20490xe3730000,
20500x000a0000,
20510x1a000000,
20520x00050003,
20530xe1500002,
20540xe28aa008,
20550xb1a00002,
20560xea000000,
20570x0005000b,
20580x0006000d,
20590x8a000000,
20600x00050046,
20610xeb000000,
20620x00030023,
20630xe18920da,
20640xea000000,
20650x00050006,
20660x0006000e,
20670x8a000000,
20680x00050046,
20690x0006000f,
20700x00000000,
20710xe18920da,
20720xe15a000b,
20730x2a000000,
20740x00050049,
20750xe3730000,
20760x000a0000,
20770x2a000000,
20780x00050007,
20790x00060010,
20800xeb000000,
20810x00030024,
20820xe28aa008,
20830x31a00002,
20840x31a01003,
20850xea000000,
20860x0005000f,
20870x00060011,
20880x8a000000,
20890x00050046,
20900xe1cd00f0,
20910xe1a00002,
20920xeb000000,
20930x00030023,
20940xe1cd20d0,
20950xea000000,
20960x00050010,
20970x00060076,
20980xe1c900d0,
20990xe35b0008,
21000x3a000000,
21010x00050046,
21020xe3710000,
21030x000a0000,
21040x1a000000,
21050x00050046,
21060xe5100000,
21070x000d8180,
21080xe3e01000,
21090x000a0000,
21100xea000000,
21110x00050049,
21120x00060077,
21130xe1c900d0,
21140xe5196004,
21150xe35b0008,
21160x03710000,
21170x000a0000,
21180x1a000000,
21190x00050046,
21200xe5102000,
21210x000d8180,
21220xe5500000,
21230x000d8180,
21240x00000000,
21250xe3e01000,
21260x000a0000,
21270xe3520000,
21280x03a0b000,
21290x000a0000,
21300x13a0b000,
21310x000a0000,
21320xe14900f8,
21330xea000000,
21340x00050047,
21350x00060078,
21360xe5170000,
21370x000d8180,
21380xe5171000,
21390x000d8180,
21400xe1500001,
21410xab000000,
21420x0005004f,
21430xe1c900d0,
21440xe5196004,
21450xe35b0008,
21460x03710000,
21470x000a0000,
21480x03d030ff,
21490xe3a02001,
21500x1a000000,
21510x00050046,
21520xe58d0000,
21530xe1a0100d,
21540x00060079,
21550xe5089000,
21560x000d8180,
21570xe1a00008,
21580xe58d6008,
21590xeb000000,
21600x00030025,
21610xe5189000,
21620x000d8180,
21630xe3e01000,
21640x000a0000,
21650xea000000,
21660x00050049,
21670x0006007a,
21680xe5170000,
21690x000d8180,
21700xe5171000,
21710x000d8180,
21720xe1500001,
21730xab000000,
21740x0005004f,
21750xe1c900d0,
21760xe1c921d0,
21770xe35b0010,
21780xe3e0c000,
21790x0a000000,
21800x00050001,
21810x3a000000,
21820x00050046,
21830x00000000,
21840xe3730000,
21850x000a0000,
21860xe1a0c002,
21870x1a000000,
21880x00050046,
21890x0006000b,
21900xe1c920d8,
21910xe3710000,
21920x000a0000,
21930x05101000,
21940x000d8180,
21950x03730000,
21960x000a0000,
21970x1a000000,
21980x00050046,
21990xe2813001,
22000xe3520000,
22010xb0822003,
22020xe3520001,
22030xb3a02001,
22040xe35c0000,
22050xb08cc003,
22060xe1cccfcc,
22070xe15c0001,
22080xe2800000,
22090x000a0000,
22100xc1a0c001,
22110xe0801002,
22120xe05c2002,
22130xe2822001,
22140xaa000000,
22150x00050079,
22160x0006007b,
22170xe2470000,
22180x000a0000,
22190xe3e01000,
22200x000a0000,
22210xea000000,
22220x00050049,
22230x0006007c,
22240xe5170000,
22250x000d8180,
22260xe5171000,
22270x000d8180,
22280xe1500001,
22290xab000000,
22300x0005004f,
22310xe1c900d0,
22320xe1c920d8,
22330xe35b0010,
22340x3a000000,
22350x00050046,
22360xe3710000,
22370x000a0000,
22380x03730000,
22390x000a0000,
22400x1a000000,
22410x00050046,
22420xe2523001,
22430xe5101000,
22440x000d8180,
22450x00000000,
22460xba000000,
22470x0005007b,
22480xe3510001,
22490x3a000000,
22500x0005007b,
22510x1a000000,
22520x00050046,
22530xe517c000,
22540x000d8180,
22550xe5171000,
22560x000d8180,
22570xe5100000,
22580x000d8180,
22590xe15c0002,
22600x3a000000,
22610x00050046,
22620x0006000b,
22630xe7c10003,
22640xe2533001,
22650xaa000000,
22660x0005000b,
22670xea000000,
22680x00050079,
22690x0006007d,
22700xe5170000,
22710x000d8180,
22720xe5171000,
22730x000d8180,
22740xe1500001,
22750xab000000,
22760x0005004f,
22770xe1c900d0,
22780xe35b0008,
22790x3a000000,
22800x00050046,
22810xe3710000,
22820x000a0000,
22830x1a000000,
22840x00050046,
22850xe5102000,
22860x000d8180,
22870xe517c000,
22880x000d8180,
22890xe5171000,
22900x000d8180,
22910xe1a03002,
22920xe2800000,
22930x000a0000,
22940xe15c0002,
22950x3a000000,
22960x00050046,
22970x0006000b,
22980x00000000,
22990xe4d0c001,
23000xe2533001,
23010xba000000,
23020x00050079,
23030xe7c1c003,
23040xea000000,
23050x0005000b,
23060x0006007e,
23070xe5170000,
23080x000d8180,
23090xe5171000,
23100x000d8180,
23110xe1500001,
23120xab000000,
23130x0005004f,
23140xe1c900d0,
23150xe35b0008,
23160x3a000000,
23170x00050046,
23180xe3710000,
23190x000a0000,
23200x1a000000,
23210x00050046,
23220xe5102000,
23230x000d8180,
23240xe517c000,
23250x000d8180,
23260xe5171000,
23270x000d8180,
23280xe3a03000,
23290xe2800000,
23300x000a0000,
23310xe15c0002,
23320x3a000000,
23330x00050046,
23340x0006000b,
23350xe7d0c003,
23360xe1530002,
23370x2a000000,
23380x00050079,
23390xe24cb041,
23400xe35b001a,
23410x322cc020,
23420xe7c1c003,
23430xe2833001,
23440xea000000,
23450x0005000b,
23460x0006007f,
23470xe5170000,
23480x000d8180,
23490xe5171000,
23500x000d8180,
23510xe1500001,
23520xab000000,
23530x0005004f,
23540xe1c900d0,
23550xe35b0008,
23560x3a000000,
23570x00050046,
23580x00000000,
23590xe3710000,
23600x000a0000,
23610x1a000000,
23620x00050046,
23630xe5102000,
23640x000d8180,
23650xe517c000,
23660x000d8180,
23670xe5171000,
23680x000d8180,
23690xe3a03000,
23700xe2800000,
23710x000a0000,
23720xe15c0002,
23730x3a000000,
23740x00050046,
23750x0006000b,
23760xe7d0c003,
23770xe1530002,
23780x2a000000,
23790x00050079,
23800xe24cb061,
23810xe35b001a,
23820x322cc020,
23830xe7c1c003,
23840xe2833001,
23850xea000000,
23860x0005000b,
23870x00060080,
23880xe1c900d0,
23890xe35b0008,
23900x3a000000,
23910x00050046,
23920xe3710000,
23930x000a0000,
23940x1a000000,
23950x00050046,
23960x00000000,
23970xe1a0a009,
23980x00000000,
23990xeb000000,
24000x00030026,
24010x00000000,
24020xe1a0900a,
24030x00000000,
24040xe3e01000,
24050x000a0000,
24060xea000000,
24070x00050049,
24080x00060081,
24090x8a000000,
24100x00050046,
24110x00060082,
24120xe1a0c081,
24130xe29cc980,
24140x53a00000,
24150x512fff1e,
24160xe3e03ff8,
24170xe053cacc,
24180x4a000000,
24190x00050001,
24200xe1a03581,
24210xe3833480,
24220xe1833aa0,
24230xe3510000,
24240xe1a00c33,
24250xb2600000,
24260xe12fff1e,
24270x0006000b,
24280xe28cc015,
24290xe1a03c30,
24300xe26cc014,
24310xe1a00601,
24320xe3510000,
24330xe1830c10,
24340xb2600000,
24350xe12fff1e,
24360x00060083,
24370xe1c900d0,
24380xe35b0008,
24390x3a000000,
24400x00050046,
24410xe3710000,
24420x000a0000,
24430x1b000000,
24440x00050081,
24450xe3e01000,
24460x000a0000,
24470xea000000,
24480x00050049,
24490x00060084,
24500xe1c900d0,
24510xe35b0008,
24520x3a000000,
24530x00050046,
24540xe3710000,
24550x000a0000,
24560x1b000000,
24570x00050081,
24580xe1a02000,
24590xe3a0a008,
24600x0006000b,
24610xe18900da,
24620xe15a000b,
24630xe28aa008,
24640xaa000000,
24650x00050002,
24660xe3710000,
24670x000a0000,
24680x1b000000,
24690x00050081,
24700xe0022000,
24710xea000000,
24720x0005000b,
24730x00060085,
24740x00000000,
24750xe1c900d0,
24760xe35b0008,
24770x3a000000,
24780x00050046,
24790xe3710000,
24800x000a0000,
24810x1b000000,
24820x00050081,
24830xe1a02000,
24840xe3a0a008,
24850x0006000b,
24860xe18900da,
24870xe15a000b,
24880xe28aa008,
24890xaa000000,
24900x00050002,
24910xe3710000,
24920x000a0000,
24930x1b000000,
24940x00050081,
24950xe1822000,
24960xea000000,
24970x0005000b,
24980x00060086,
24990xe1c900d0,
25000xe35b0008,
25010x3a000000,
25020x00050046,
25030xe3710000,
25040x000a0000,
25050x1b000000,
25060x00050081,
25070xe1a02000,
25080xe3a0a008,
25090x0006000b,
25100xe18900da,
25110xe15a000b,
25120xe28aa008,
25130xaa000000,
25140x00050002,
25150xe3710000,
25160x000a0000,
25170x1b000000,
25180x00050081,
25190xe0222000,
25200xea000000,
25210x0005000b,
25220x0006000c,
25230xe3e03000,
25240x000a0000,
25250xe5196004,
25260xe14920f8,
25270xea000000,
25280x0005005e,
25290x00060087,
25300xe1c900d0,
25310xe35b0008,
25320x3a000000,
25330x00050046,
25340x00000000,
25350xe3710000,
25360x000a0000,
25370x1b000000,
25380x00050081,
25390xe0202860,
25400xe3c228ff,
25410xe1a00460,
25420xe3e01000,
25430x000a0000,
25440xe0200422,
25450xea000000,
25460x00050049,
25470x00060088,
25480xe1c900d0,
25490xe35b0008,
25500x3a000000,
25510x00050046,
25520xe3710000,
25530x000a0000,
25540x1b000000,
25550x00050081,
25560xe1e00000,
25570xe3e01000,
25580x000a0000,
25590xea000000,
25600x00050049,
25610x00060089,
25620xe1c900d8,
25630xe35b0010,
25640x3a000000,
25650x00050046,
25660xe3710000,
25670x000a0000,
25680x1b000000,
25690x00050081,
25700xe200a01f,
25710xe1c900d0,
25720xe3710000,
25730x000a0000,
25740x1b000000,
25750x00050081,
25760xe1a00a10,
25770xe3e01000,
25780x000a0000,
25790xea000000,
25800x00050049,
25810x0006008a,
25820xe1c900d8,
25830xe35b0010,
25840x3a000000,
25850x00050046,
25860xe3710000,
25870x000a0000,
25880x1b000000,
25890x00050081,
25900x00000000,
25910xe200a01f,
25920xe1c900d0,
25930xe3710000,
25940x000a0000,
25950x1b000000,
25960x00050081,
25970xe1a00a30,
25980xe3e01000,
25990x000a0000,
26000xea000000,
26010x00050049,
26020x0006008b,
26030xe1c900d8,
26040xe35b0010,
26050x3a000000,
26060x00050046,
26070xe3710000,
26080x000a0000,
26090x1b000000,
26100x00050081,
26110xe200a01f,
26120xe1c900d0,
26130xe3710000,
26140x000a0000,
26150x1b000000,
26160x00050081,
26170xe1a00a50,
26180xe3e01000,
26190x000a0000,
26200xea000000,
26210x00050049,
26220x0006008c,
26230xe1c900d8,
26240xe35b0010,
26250x3a000000,
26260x00050046,
26270xe3710000,
26280x000a0000,
26290x1b000000,
26300x00050081,
26310xe260a000,
26320xe1c900d0,
26330xe3710000,
26340x000a0000,
26350x1b000000,
26360x00050081,
26370xe1a00a70,
26380xe3e01000,
26390x000a0000,
26400xea000000,
26410x00050049,
26420x0006008d,
26430xe1c900d8,
26440xe35b0010,
26450x3a000000,
26460x00050046,
26470x00000000,
26480xe3710000,
26490x000a0000,
26500x1b000000,
26510x00050081,
26520xe200a01f,
26530xe1c900d0,
26540xe3710000,
26550x000a0000,
26560x1b000000,
26570x00050081,
26580xe1a00a70,
26590xe3e01000,
26600x000a0000,
26610xea000000,
26620x00050049,
26630x00060046,
26640xe5192008,
26650xe5181000,
26660x000d8180,
26670xe089000b,
26680xe5196004,
26690xe5080000,
26700x000d8180,
26710xe5122000,
26720x000d8180,
26730xe5089000,
26740x000d8180,
26750xe2800000,
26760x000a0000,
26770xe58d6008,
26780xe1500001,
26790xe1a00008,
26800x8a000000,
26810x00050005,
26820xe12fff32,
26830xe5189000,
26840x000d8180,
26850xe3500000,
26860xe1a0b180,
26870xe249a008,
26880xca000000,
26890x00050047,
26900x0006000b,
26910xe5180000,
26920x000d8180,
26930xe5192008,
26940xe040b009,
26950x1a000000,
26960x00050029,
26970xe5126000,
26980x000d8180,
26990xe5d6c000,
27000xe496e004,
27010xe797c10c,
27020xe004a2ae,
27030xe08aa009,
27040xe12fff1c,
27050x00060029,
27060xe2160000,
27070x000a0000,
27080xe3c61000,
27090x000a0000,
27100x00000000,
27110x0516e004,
27120x00020000,
27130x000412ae,
27140xe049c001,
27150xea000000,
27160x00050024,
27170x0006000f,
27180xe3a01000,
27190x000a0000,
27200xeb000000,
27210x00030000,
27220xe5189000,
27230x000d8180,
27240xe1500000,
27250xea000000,
27260x0005000b,
27270x0006004f,
27280xe1a0a00e,
27290xe5089000,
27300x000d8180,
27310xe089100b,
27320xe58d6008,
27330xe5081000,
27340x000d8180,
27350xe1a00008,
27360xeb000000,
27370x00030027,
27380xe5189000,
27390x000d8180,
27400xe1a0e00a,
27410xe5192008,
27420xe12fff1e,
27430x0006008e,
27440x00000000,
27450xe5570000,
27460x000d8180,
27470xe3100000,
27480x000a0000,
27490x1a000000,
27500x00050005,
27510xe5171000,
27520x000d8180,
27530xe3100000,
27540x000a0000,
27550x1a000000,
27560x00050001,
27570xe2411001,
27580xe3100000,
27590x000a0000,
27600x15071000,
27610x000d8180,
27620xea000000,
27630x00050001,
27640x00000000,
27650x0006008f,
27660xe5570000,
27670x000d8180,
27680xe3100000,
27690x000a0000,
27700x0a000000,
27710x00050001,
27720x0006000f,
27730xe20ec0ff,
27740xe087c10c,
27750xe51cf000,
27760x000d8180,
27770x00060090,
27780xe5570000,
27790x000d8180,
27800xe5171000,
27810x000d8180,
27820xe3100000,
27830x000a0000,
27840x1a000000,
27850x0005000f,
27860xe3100000,
27870x000a0000,
27880x0a000000,
27890x0005000f,
27900xe2511001,
27910xe5071000,
27920x000d8180,
27930x0a000000,
27940x00050001,
27950xe3100000,
27960x000a0000,
27970x0a000000,
27980x0005000f,
27990x0006000b,
28000xe1a00008,
28010xe5089000,
28020x000d8180,
28030xe1a01006,
28040xeb000000,
28050x00030028,
28060x0006000d,
28070xe5189000,
28080x000d8180,
28090x0006000e,
28100x00000000,
28110xe556c004,
28120xe516e004,
28130xe087c10c,
28140xe51cc000,
28150x000d8180,
28160xe004a2ae,
28170xe1a0b82e,
28180xe12fff1c,
28190x00060091,
28200xe5130018,
28210xe2866004,
28220xe58d0004,
28230xea000000,
28240x0005000e,
28250x00060092,
28260x00000000,
28270xe5192008,
28280xe2470000,
28290x000a0000,
28300xe58d6008,
28310xe5122000,
28320x000d8180,
28330xe1a01006,
28340xe5078000,
28350x000d8180,
28360xe5522000,
28370x000d8180,
28380xe5089000,
28390x000d8180,
28400xe0892182,
28410xe5082000,
28420x000d8180,
28430xeb000000,
28440x00030029,
28450xea000000,
28460x0005000d,
28470x00000000,
28480x00060093,
28490xe1a01006,
28500x00000000,
28510xea000000,
28520x00050001,
28530x00000000,
28540x00060094,
28550x00000000,
28560xe3861001,
28570x0006000b,
28580x00000000,
28590xe089300b,
28600xe58d6008,
28610xe1a00008,
28620xe5089000,
28630x000d8180,
28640xe04aa009,
28650xe5083000,
28660x000d8180,
28670xeb000000,
28680x0003002a,
28690xe5189000,
28700x000d8180,
28710xe5183000,
28720x000d8180,
28730xe3a01000,
28740xe089a00a,
28750xe043b009,
28760xe58d1008,
28770xe5192008,
28780xe516e004,
28790xe12fff10,
28800x00060095,
28810x00000000,
28820xe24dd00c,
28830xe92d1fff,
28840xe59d0040,
28850xe59e7000,
28860xe28d2040,
28870xe3e03000,
28880x000a0000,
28890xe58d2034,
28900xe5073000,
28910x000d8180,
28920xe5301004,
28930xe58d0038,
28940xe58d003c,
28950xe1a01401,
28960xe0800341,
28970xe59e1004,
28980xe040000e,
28990xe5178000,
29000x000d8180,
29010xe0810120,
29020xe5179000,
29030x000d8180,
29040xe5070000,
29050x000d8180,
29060xe3a03000,
29070xe5078000,
29080x000d8180,
29090xe5089000,
29100x000d8180,
29110xe5073000,
29120x000d8180,
29130xe2470000,
29140x000a0000,
29150xe1a0100d,
29160xeb000000,
29170x0003002b,
29180xe5181000,
29190x000d8180,
29200xe5189000,
29210x000d8180,
29220xe3c11000,
29230x000a0000,
29240xe1a0d001,
29250xe59d6008,
29260xe58d800c,
29270xea000000,
29280x00050001,
29290x00000000,
29300x00060096,
29310x00000000,
29320xe59d800c,
29330x0006000b,
29340xe3500000,
29350xba000000,
29360x00050003,
29370xe1a0b180,
29380xe5191008,
29390xe58db004,
29400xe3a02000,
29410xe5111000,
29420x000d8180,
29430xe5072000,
29440x000d8180,
29450xe3e03000,
29460x000a0000,
29470xe5115000,
29480x000d8180,
29490xe5d6c000,
29500xe3a040ff,
29510xe496e004,
29520xe1a04184,
29530xe5073000,
29540x000d8180,
29550xe35c0000,
29560x000a0000,
29570xe797c10c,
29580xe004a2ae,
29590x31a0b82e,
29600x224bb008,
29610x208aa009,
29620xe12fff1c,
29630x0006000d,
29640xe2601000,
29650xe1a00008,
29660xeb000000,
29670x0003002c,
29680x00000000,
29690x00060013,
29700x3ff00000,
29710x0006005a,
29720xe1a02081,
29730xe292c980,
29740x5a000000,
29750x00050002,
29760xe3e03ff3,
29770xe053cacc,
29780x312fff1e,
29790xe3e03001,
29800xe1c02c13,
29810xe0000c13,
29820xe25cc020,
29830x51c13c13,
29840x51822003,
29850x53e03001,
29860x50011c13,
29870xe1120fc1,
29880x012fff1e,
29890xe3e03001,
29900xe35c0000,
29910x51a02c13,
29920x43e02000,
29930xe28cc020,
29940xe0500c13,
29950xe0c11002,
29960xe12fff1e,
29970x0006000c,
29980xe1822000,
29990xe1120fc1,
30000xe3a00000,
30010xe2011480,
30020x151f3000,
30030x00050813,
30040x11811003,
30050xe12fff1e,
30060x0006005c,
30070xe1a02081,
30080xe292c980,
30090x5a000000,
30100x00050002,
30110xe3e03ff3,
30120xe053cacc,
30130x312fff1e,
30140xe3e03001,
30150xe1c02c13,
30160xe0000c13,
30170xe25cc020,
30180x51c13c13,
30190x51822003,
30200x53e03001,
30210x50011c13,
30220xe1d22fc1,
30230x012fff1e,
30240xe3e03001,
30250xe35c0000,
30260x51a02c13,
30270x43e02000,
30280xe28cc020,
30290xe0500c13,
30300xe0c11002,
30310xe12fff1e,
30320x0006000c,
30330xe1822000,
30340xe1d22fc1,
30350xe3a00000,
30360xe2011480,
30370x151f3000,
30380x00050813,
30390x11811003,
30400xe12fff1e,
30410x00060097,
30420x00000000,
30430xe1a02081,
30440xe292c980,
30450x52011480,
30460x53a00000,
30470x512fff1e,
30480xe3e03ff3,
30490xe053cacc,
30500x312fff1e,
30510xe3e03001,
30520xe0000c13,
30530xe25cc020,
30540x50011c13,
30550xe12fff1e,
30560x00000000,
30570x00060098,
30580xe92d401f,
30590xeb000000,
30600x0003002d,
30610xeb000000,
30620x0005005a,
30630xe1cd20d8,
30640xeb000000,
30650x0003001f,
30660xe1cd20d0,
30670xe2211480,
30680xeb000000,
30690x0003002e,
30700xe28dd014,
30710xe8bd8000,
30720x00060099,
30730xe210c480,
30740x42600000,
30750xe02cc0c1,
30760xe3510000,
30770x42611000,
30780xe2513001,
30790x11500001,
30800x03a00000,
30810x81110003,
30820x00020000,
30830x00000003,
30840x9a000000,
30850x00050001,
30860xe16f2f10,
30870xe16f3f11,
30880xe0433002,
30890xe273201f,
30900x108ff182,
30910xe1a00000,
30920x00000000,
30930xe1500001,
30940x000900a7,
30950x20400001,
30960x000900a7,
30970x00000000,
30980x0006000b,
30990xe3500000,
31000x135c0000,
31010x40400001,
31020xe030108c,
31030x42600000,
31040xe12fff1e,
31050x0006009a,
31060xe59dc000,
31070xe35c0001,
31080x3a000000,
31090x0003002e,
31100x0a000000,
31110x0003002f,
31120xe35c0003,
31130x3a000000,
31140x0003001f,
31150x0a000000,
31160x0003002d,
31170xe35c0005,
31180x3a000000,
31190x00050098,
31200x0a000000,
31210x0003001c,
31220xe35c0007,
31230x32211480,
31240x03c11480,
31250x912fff1e,
31260x00000000,
31270xe35c0009,
31280x3a000000,
31290x0003001d,
31300x0a000000,
31310x00050009,
31320xe35c000b,
31330x8a000000,
31340x00050009,
31350xe92d4010,
31360x0a000000,
31370x00050001,
31380xeb000000,
31390x00030024,
31400x81a00002,
31410x81a01003,
31420xe8bd8010,
31430x00060013,
31440xe7f001f0,
31450x0006000b,
31460xeb000000,
31470x00030024,
31480x31a00002,
31490x31a01003,
31500xe8bd8010,
31510x00000000,
31520xe7f001f0,
31530x00000000,
31540x0006009b,
31550x00000000,
31560xe51c6000,
31570x000d8180,
31580xe28c7000,
31590x000a0000,
31600xe14600f0,
31610x000c8100,
31620xe14620f0,
31630x000c8100,
31640xe59d3000,
31650xe28d2000,
31660x000a0000,
31670xe1a00006,
31680xe1a031a3,
31690xe5062000,
31700x000d8180,
31710xe1a0100d,
31720xe5063000,
31730x000d8180,
31740xe58d6008,
31750xeb000000,
31760x00030030,
31770xe5109000,
31780x000d8180,
31790xe3e01000,
31800x000a0000,
31810xe510b000,
31820x000d8180,
31830xe3a040ff,
31840xe5192008,
31850xe1a08000,
31860xe04bb009,
31870xe1a04184,
31880xe5071000,
31890x000d8180,
31900xe5126000,
31910x000d8180,
31920xe5d6c000,
31930xe496e004,
31940xe797c10c,
31950xe004a2ae,
31960xe08aa009,
31970xe12fff1c,
31980x00000000,
31990x00060028,
32000x00000000,
32010xe5176000,
32020x000d8180,
32030xe5089000,
32040x000d8180,
32050xe5083000,
32060x000d8180,
32070xe5068000,
32080x000d8180,
32090xe1a00006,
32100xe1a0100a,
32110xeb000000,
32120x00030031,
32130xe14600d0,
32140x000c8100,
32150xea000000,
32160x0005001a,
32170x00000000,
32180x0006009c,
32190x00000000,
32200xe92d4830,
32210xe1a04000,
32220xe5100000,
32230x000d8180,
32240xe5541000,
32250x000d8180,
32260xe2842000,
32270x000a0000,
32280xe1a0b00d,
32290xe04dd000,
32300xe2511001,
32310xe514c000,
32320x000d8180,
32330x4a000000,
32340x00050002,
32350x0006000b,
32360xe7923101,
32370xe78d3101,
32380xe2511001,
32390x5a000000,
32400x0005000b,
32410x0006000c,
32420xe5140000,
32430x000d8180,
32440xe5141000,
32450x000d8180,
32460xe5142000,
32470x000d8180,
32480xe5143000,
32490x000d8180,
32500xe12fff3c,
32510xe1a0d00b,
32520xe5040000,
32530x000d8180,
32540xe5041000,
32550x000d8180,
32560xe8bd8830,
32570x00000000,
32580x00080000,
32590x00000000,
32600xe1a0b18b,
32610xe1aa00d9,
32620xe1d6c0b2,
32630xe1ab20d9,
32640xe2866004,
32650xe086c10c,
32660xe3710000,
32670x000a0000,
32680x1a000000,
32690x00050003,
32700xe3730000,
32710x000a0000,
32720x1a000000,
32730x00050004,
32740xe1500002,
32750x00000000,
32760xb24c6b80,
32770x00000000,
32780xa24c6b80,
32790x00000000,
32800xd24c6b80,
32810x00000000,
32820xc24c6b80,
32830x00000000,
32840x0006000b,
32850xe5d6c000,
32860xe496e004,
32870xe797c10c,
32880xe004a2ae,
32890xe1a0b82e,
32900xe12fff1c,
32910x0006000d,
32920x8a000000,
32930x00050035,
32940xe3730000,
32950x000a0000,
32960x31a0a00c,
32970x3a000000,
32980x00050005,
32990xe1a00002,
33000xe1a0b00a,
33010xe1a0a00c,
33020xeb000000,
33030x00030023,
33040xe1a02000,
33050xe1a03001,
33060xe1cb00d0,
33070xea000000,
33080x00050005,
33090x0006000e,
33100x8a000000,
33110x00050035,
33120xe1a0a00c,
33130xeb000000,
33140x00030023,
33150xe1cb20d0,
33160x0006000f,
33170xeb000000,
33180x00030024,
33190x00000000,
33200x324a6b80,
33210x00000000,
33220x224a6b80,
33230x00000000,
33240x924a6b80,
33250x00000000,
33260x824a6b80,
33270x00000000,
33280xea000000,
33290x0005000b,
33300x00000000,
33310xe1a0b18b,
33320xe1aa00d9,
33330xe1d6c0b2,
33340xe1ab20d9,
33350xe2866004,
33360xe086c10c,
33370xe3710000,
33380x000a0000,
33390x93730000,
33400x000a0000,
33410x00000000,
33420x9a000000,
33430x0005009d,
33440x00000000,
33450x9a000000,
33460x0005009e,
33470x00000000,
33480xe3710000,
33490x000a0000,
33500x13730000,
33510x000a0000,
33520x0a000000,
33530x0005003b,
33540x00000000,
33550xe1510003,
33560x1a000000,
33570x00050002,
33580xe3710000,
33590x000a0000,
33600x2a000000,
33610x00050001,
33620xe1500002,
33630x00000000,
33640x1a000000,
33650x00050003,
33660x0006000b,
33670xe24c6b80,
33680x0006000c,
33690xe5d6c000,
33700xe496e004,
33710xe797c10c,
33720xe004a2ae,
33730xe1a0b82e,
33740xe12fff1c,
33750x0006000d,
33760xe3710000,
33770x000a0000,
33780x8a000000,
33790x0005000c,
33800x00000000,
33810x0a000000,
33820x00050001,
33830xe3710000,
33840x000a0000,
33850x8a000000,
33860x00050002,
33870x00000000,
33880xe510a000,
33890x000d8180,
33900xe35a0000,
33910x00000000,
33920x0a000000,
33930x0005000c,
33940x00000000,
33950x0a000000,
33960x00050002,
33970x00000000,
33980xe55aa000,
33990x000d8180,
34000xe3a03000,
34010x000a0000,
34020xe1a01000,
34030xe31a0000,
34040x000a0000,
34050x0a000000,
34060x0005003a,
34070x00000000,
34080xea000000,
34090x0005000c,
34100x00000000,
34110x0006000c,
34120xe24c6b80,
34130x0006000b,
34140xe5d6c000,
34150xe496e004,
34160xe797c10c,
34170xe004a2ae,
34180xe1a0b82e,
34190xe12fff1c,
34200x00000000,
34210xe1e0b00b,
34220xe18900da,
34230xe1d6c0b2,
34240xe795210b,
34250xe2866004,
34260xe086c10c,
34270xe3710000,
34280x000a0000,
34290x00000000,
34300x1a000000,
34310x00050007,
34320xe1500002,
34330x00000000,
34340x01500002,
34350x00000000,
34360x024c6b80,
34370x0006000b,
34380x00000000,
34390x0006000b,
34400x124c6b80,
34410x00000000,
34420xe5d6c000,
34430xe496e004,
34440xe797c10c,
34450xe004a2ae,
34460xe1a0b82e,
34470xe12fff1c,
34480x00000000,
34490x00060011,
34500xe3710000,
34510x000a0000,
34520x1a000000,
34530x0005000b,
34540xea000000,
34550x0005003b,
34560x00000000,
34570xe1a0b18b,
34580xe1aa00d9,
34590xe1d6c0b2,
34600xe1ab20d5,
34610xe2866004,
34620xe086c10c,
34630x00000000,
34640x0006009d,
34650x00000000,
34660x0006009e,
34670x00000000,
34680xe3710000,
34690x000a0000,
34700x1a000000,
34710x00050003,
34720xe3730000,
34730x000a0000,
34740x1a000000,
34750x00050004,
34760xe1500002,
34770x00000000,
34780x024c6b80,
34790x0006000b,
34800x00000000,
34810x0006000b,
34820x124c6b80,
34830x00000000,
34840x0006000c,
34850xe5d6c000,
34860xe496e004,
34870xe797c10c,
34880xe004a2ae,
34890xe1a0b82e,
34900xe12fff1c,
34910x0006000d,
34920x00000000,
34930x8a000000,
34940x00050007,
34950x00000000,
34960x824c6b80,
34970x00000000,
34980x8a000000,
34990x0005000c,
35000x00000000,
35010xe3730000,
35020x000a0000,
35030x31a0a00c,
35040x3a000000,
35050x00050005,
35060xe1a00002,
35070xe1a0b00a,
35080x0006000e,
35090xe1a0a00c,
35100xeb000000,
35110x00030023,
35120xe1cb20d0,
35130x0006000f,
35140xeb000000,
35150x00030032,
35160x00000000,
35170x024a6b80,
35180x00000000,
35190x124a6b80,
35200x00000000,
35210xea000000,
35220x0005000c,
35230x00000000,
35240x00060011,
35250xe3710000,
35260x000a0000,
35270x1a000000,
35280x0005000b,
35290xea000000,
35300x0005003b,
35310x00000000,
35320xe18900da,
35330xe1d6c0b2,
35340xe2866004,
35350xe1e0b00b,
35360xe086c10c,
35370x00000000,
35380xe3710000,
35390x000a0000,
35400x0a000000,
35410x0005003b,
35420x00000000,
35430xe151000b,
35440x00000000,
35450x024c6b80,
35460x00000000,
35470x124c6b80,
35480x00000000,
35490xe5d6c000,
35500xe496e004,
35510xe797c10c,
35520xe004a2ae,
35530xe1a0b82e,
35540xe12fff1c,
35550x00000000,
35560xe089b18b,
35570xe1d6c0b2,
35580xe1cb00d0,
35590xe2866004,
35600xe086c10c,
35610xe3710000,
35620x000a0000,
35630x00000000,
35640x924c6b80,
35650x00000000,
35660x918900fa,
35670x00000000,
35680x824c6b80,
35690x00000000,
35700x818900fa,
35710x00000000,
35720xe5d6c000,
35730xe496e004,
35740xe797c10c,
35750xe004a2ae,
35760xe1a0b82e,
35770xe12fff1c,
35780x00000000,
35790xe1a0b18b,
35800xe5d6c000,
35810xe18900db,
35820xe496e004,
35830xe18900fa,
35840xe797c10c,
35850xe004a2ae,
35860xe1a0b82e,
35870xe12fff1c,
35880x00000000,
35890xe089b18b,
35900xe5d6c000,
35910xe59b0004,
35920xe089a00a,
35930xe496e004,
35940xe3700000,
35950x000a0000,
35960x93e01000,
35970x000a0000,
35980x83e01000,
35990x000a0000,
36000xe58a1004,
36010xe797c10c,
36020xe004a2ae,
36030xe1a0b82e,
36040xe12fff1c,
36050x00000000,
36060xe1a0b18b,
36070xe18900db,
36080xe5d6c000,
36090xe496e004,
36100xe3710000,
36110x000a0000,
36120x8a000000,
36130x0005003e,
36140x12211480,
36150x1a000000,
36160x00050005,
36170x02700000,
36180x614f00d0,
36190x00051809,
36200x0006000f,
36210xe18900fa,
36220xe797c10c,
36230xe004a2ae,
36240xe1a0b82e,
36250xe12fff1c,
36260x00040007,
36270x00060013,
36280x00020000,
36290x00000000,
36300x41e00000,
36310x00000000,
36320xe1a0b18b,
36330xe18900db,
36340xe3710000,
36350x000a0000,
36360x1a000000,
36370x00050002,
36380xe5100000,
36390x000d8180,
36400x0006000b,
36410xe3e01000,
36420x000a0000,
36430xe5d6c000,
36440xe496e004,
36450xe18900fa,
36460xe797c10c,
36470xe004a2ae,
36480xe1a0b82e,
36490xe12fff1c,
36500x0006000c,
36510xe3710000,
36520x000a0000,
36530x1a000000,
36540x00050040,
36550x00000000,
36560xe5102000,
36570x000d8180,
36580xe3520000,
36590x1a000000,
36600x00050009,
36610x0006000d,
36620x00000000,
36630x00060041,
36640x00000000,
36650xe1a0b009,
36660x00000000,
36670xeb000000,
36680x00030026,
36690x00000000,
36700xe1a0900b,
36710x00000000,
36720xea000000,
36730x0005000b,
36740x00000000,
36750x00060013,
36760xe5523000,
36770x000d8180,
36780xe3130000,
36790x000a0000,
36800x1a000000,
36810x0005000d,
36820xea000000,
36830x00050040,
36840x00000000,
36850xe004caae,
36860xe004b6ae,
36870x00000000,
36880xe18900dc,
36890xe18520db,
36900x00000000,
36910xe18920dc,
36920xe18500db,
36930x00000000,
36940xe18900dc,
36950xe18920db,
36960x00000000,
36970xe5d6c000,
36980x00000000,
36990xe3730000,
37000x000a0000,
37010x03710000,
37020x000a0000,
37030x00000000,
37040xe3710000,
37050x000a0000,
37060x03730000,
37070x000a0000,
37080x00000000,
37090x1a000000,
37100x00050005,
37110xe0900002,
37120x00000000,
37130x6a000000,
37140x0005003c,
37150x00000000,
37160x6a000000,
37170x0005003d,
37180x00000000,
37190x6a000000,
37200x0005003f,
37210x00000000,
37220x0006000e,
37230xe496e004,
37240xe18900fa,
37250xe797c10c,
37260xe004a2ae,
37270xe1a0b82e,
37280xe12fff1c,
37290x0006000f,
37300x00000000,
37310xe3730000,
37320x000a0000,
37330x33710000,
37340x000a0000,
37350x00000000,
37360xe3710000,
37370x000a0000,
37380x33730000,
37390x000a0000,
37400x00000000,
37410x2a000000,
37420x0005003c,
37430x00000000,
37440xe3730000,
37450x000a0000,
37460x33710000,
37470x000a0000,
37480x00000000,
37490xe3710000,
37500x000a0000,
37510x33730000,
37520x000a0000,
37530x00000000,
37540x2a000000,
37550x0005003d,
37560x00000000,
37570xe3730000,
37580x000a0000,
37590x33710000,
37600x000a0000,
37610x00000000,
37620xe3710000,
37630x000a0000,
37640x33730000,
37650x000a0000,
37660x00000000,
37670x2a000000,
37680x0005003f,
37690x00000000,
37700xeb000000,
37710x0003002e,
37720xe5d6c000,
37730xea000000,
37740x0005000e,
37750x00000000,
37760xe004caae,
37770xe004b6ae,
37780x00000000,
37790xe18900dc,
37800xe18520db,
37810x00000000,
37820xe18920dc,
37830xe18500db,
37840x00000000,
37850xe18900dc,
37860xe18920db,
37870x00000000,
37880xe5d6c000,
37890x00000000,
37900xe3730000,
37910x000a0000,
37920x03710000,
37930x000a0000,
37940x00000000,
37950xe3710000,
37960x000a0000,
37970x03730000,
37980x000a0000,
37990x00000000,
38000x1a000000,
38010x00050005,
38020xe0500002,
38030x00000000,
38040x6a000000,
38050x0005003c,
38060x00000000,
38070x6a000000,
38080x0005003d,
38090x00000000,
38100x6a000000,
38110x0005003f,
38120x00000000,
38130x0006000e,
38140xe496e004,
38150xe18900fa,
38160xe797c10c,
38170xe004a2ae,
38180xe1a0b82e,
38190xe12fff1c,
38200x0006000f,
38210x00000000,
38220xe3730000,
38230x000a0000,
38240x33710000,
38250x000a0000,
38260x00000000,
38270xe3710000,
38280x000a0000,
38290x33730000,
38300x000a0000,
38310x00000000,
38320x2a000000,
38330x0005003c,
38340x00000000,
38350xe3730000,
38360x000a0000,
38370x33710000,
38380x000a0000,
38390x00000000,
38400xe3710000,
38410x000a0000,
38420x33730000,
38430x000a0000,
38440x00000000,
38450x2a000000,
38460x0005003d,
38470x00000000,
38480xe3730000,
38490x000a0000,
38500x33710000,
38510x000a0000,
38520x00000000,
38530xe3710000,
38540x000a0000,
38550x33730000,
38560x000a0000,
38570x00000000,
38580x2a000000,
38590x0005003f,
38600x00000000,
38610xeb000000,
38620x0003002f,
38630xe5d6c000,
38640xea000000,
38650x0005000e,
38660x00000000,
38670xe004caae,
38680xe004b6ae,
38690x00000000,
38700xe18900dc,
38710xe18520db,
38720x00000000,
38730xe18920dc,
38740xe18500db,
38750x00000000,
38760xe18900dc,
38770xe18920db,
38780x00000000,
38790xe5d6c000,
38800x00000000,
38810xe3730000,
38820x000a0000,
38830x03710000,
38840x000a0000,
38850x00000000,
38860xe3710000,
38870x000a0000,
38880x03730000,
38890x000a0000,
38900x00000000,
38910x1a000000,
38920x00050005,
38930xe0cb0092,
38940xe15b0fc0,
38950x00000000,
38960x1a000000,
38970x0005003c,
38980x00000000,
38990x1a000000,
39000x0005003d,
39010x00000000,
39020x1a000000,
39030x0005003f,
39040x00000000,
39050x0006000e,
39060xe496e004,
39070xe18900fa,
39080xe797c10c,
39090xe004a2ae,
39100xe1a0b82e,
39110xe12fff1c,
39120x0006000f,
39130x00000000,
39140xe3730000,
39150x000a0000,
39160x33710000,
39170x000a0000,
39180x00000000,
39190xe3710000,
39200x000a0000,
39210x33730000,
39220x000a0000,
39230x00000000,
39240x2a000000,
39250x0005003c,
39260x00000000,
39270xe3730000,
39280x000a0000,
39290x33710000,
39300x000a0000,
39310x00000000,
39320xe3710000,
39330x000a0000,
39340x33730000,
39350x000a0000,
39360x00000000,
39370x2a000000,
39380x0005003d,
39390x00000000,
39400xe3730000,
39410x000a0000,
39420x33710000,
39430x000a0000,
39440x00000000,
39450xe3710000,
39460x000a0000,
39470x33730000,
39480x000a0000,
39490x00000000,
39500x2a000000,
39510x0005003f,
39520x00000000,
39530xeb000000,
39540x0003001f,
39550xe5d6c000,
39560xea000000,
39570x0005000e,
39580x00000000,
39590xe004caae,
39600xe004b6ae,
39610x00000000,
39620xe18900dc,
39630xe18520db,
39640x00000000,
39650xe18920dc,
39660xe18500db,
39670x00000000,
39680xe18900dc,
39690xe18920db,
39700x00000000,
39710xe3730000,
39720x000a0000,
39730x33710000,
39740x000a0000,
39750x00000000,
39760xe3710000,
39770x000a0000,
39780x33730000,
39790x000a0000,
39800x00000000,
39810x2a000000,
39820x0005003c,
39830x00000000,
39840xe3730000,
39850x000a0000,
39860x33710000,
39870x000a0000,
39880x00000000,
39890xe3710000,
39900x000a0000,
39910x33730000,
39920x000a0000,
39930x00000000,
39940x2a000000,
39950x0005003d,
39960x00000000,
39970xe3730000,
39980x000a0000,
39990x33710000,
40000x000a0000,
40010x00000000,
40020xe3710000,
40030x000a0000,
40040x33730000,
40050x000a0000,
40060x00000000,
40070x2a000000,
40080x0005003f,
40090x00000000,
40100xeb000000,
40110x0003002d,
40120xe5d6c000,
40130xe496e004,
40140xe18900fa,
40150xe797c10c,
40160xe004a2ae,
40170xe1a0b82e,
40180xe12fff1c,
40190x00000000,
40200xe004caae,
40210xe004b6ae,
40220x00000000,
40230xe18900dc,
40240xe18520db,
40250x00000000,
40260xe18920dc,
40270xe18500db,
40280x00000000,
40290xe18900dc,
40300xe18920db,
40310x00000000,
40320xe3730000,
40330x000a0000,
40340x03710000,
40350x000a0000,
40360x00000000,
40370xe3710000,
40380x000a0000,
40390x03730000,
40400x000a0000,
40410x00000000,
40420x1a000000,
40430x00050005,
40440xe1b01002,
40450x00000000,
40460x0a000000,
40470x0005003c,
40480x00000000,
40490x0a000000,
40500x0005003d,
40510x00000000,
40520x0a000000,
40530x0005003f,
40540x00000000,
40550xeb000000,
40560x00050099,
40570xe3e01000,
40580x000a0000,
40590x0006000e,
40600xe5d6c000,
40610xe496e004,
40620xe18900fa,
40630xe797c10c,
40640xe004a2ae,
40650xe1a0b82e,
40660xe12fff1c,
40670x0006000f,
40680x00000000,
40690xe3730000,
40700x000a0000,
40710x33710000,
40720x000a0000,
40730x00000000,
40740xe3710000,
40750x000a0000,
40760x33730000,
40770x000a0000,
40780x00000000,
40790x2a000000,
40800x0005003c,
40810x00000000,
40820xe3730000,
40830x000a0000,
40840x33710000,
40850x000a0000,
40860x00000000,
40870xe3710000,
40880x000a0000,
40890x33730000,
40900x000a0000,
40910x00000000,
40920x2a000000,
40930x0005003d,
40940x00000000,
40950xe3730000,
40960x000a0000,
40970x33710000,
40980x000a0000,
40990x00000000,
41000xe3710000,
41010x000a0000,
41020x33730000,
41030x000a0000,
41040x00000000,
41050x2a000000,
41060x0005003f,
41070x00000000,
41080xeb000000,
41090x00050098,
41100xea000000,
41110x0005000e,
41120x00000000,
41130xe004caae,
41140xe004b6ae,
41150x00000000,
41160xe18900dc,
41170xe18520db,
41180x00000000,
41190xe18920dc,
41200xe18500db,
41210x00000000,
41220xe18900dc,
41230xe18920db,
41240x00000000,
41250xe3730000,
41260x000a0000,
41270x33710000,
41280x000a0000,
41290x00000000,
41300xe3710000,
41310x000a0000,
41320x33730000,
41330x000a0000,
41340x00000000,
41350x2a000000,
41360x0005003c,
41370x00000000,
41380xe3730000,
41390x000a0000,
41400x33710000,
41410x000a0000,
41420x00000000,
41430xe3710000,
41440x000a0000,
41450x33730000,
41460x000a0000,
41470x00000000,
41480x2a000000,
41490x0005003d,
41500x00000000,
41510xe3730000,
41520x000a0000,
41530x33710000,
41540x000a0000,
41550x00000000,
41560xe3710000,
41570x000a0000,
41580x33730000,
41590x000a0000,
41600x00000000,
41610x2a000000,
41620x0005003f,
41630x00000000,
41640xe1a0b009,
41650x00000000,
41660xeb000000,
41670x0003001c,
41680x00000000,
41690xe1a0900b,
41700x00000000,
41710xe5d6c000,
41720xe496e004,
41730xe18900fa,
41740xe797c10c,
41750xe004a2ae,
41760xe1a0b82e,
41770xe12fff1c,
41780x00000000,
41790xe004baae,
41800xe004c6ae,
41810xe04c200b,
41820xe5089000,
41830x000d8180,
41840xe089100c,
41850x0006002b,
41860xe1a00008,
41870xe58d6008,
41880xe1a021a2,
41890xeb000000,
41900x00030033,
41910xe5189000,
41920x000d8180,
41930xe3500000,
41940x1a000000,
41950x00050036,
41960xe18920db,
41970xe5d6c000,
41980xe496e004,
41990xe18920fa,
42000xe797c10c,
42010xe004a2ae,
42020xe1a0b82e,
42030xe12fff1c,
42040x00000000,
42050xe1e0b00b,
42060xe5d6c000,
42070xe795010b,
42080xe3e01000,
42090x000a0000,
42100xe496e004,
42110xe18900fa,
42120xe797c10c,
42130xe004a2ae,
42140xe1a0b82e,
42150xe12fff1c,
42160x00000000,
42170xe1e0b00b,
42180xe5d6c000,
42190xe795010b,
42200xe3e01000,
42210x000a0000,
42220xe496e004,
42230xe18900fa,
42240xe797c10c,
42250xe004a2ae,
42260xe1a0b82e,
42270xe12fff1c,
42280x00000000,
42290xe1a0084e,
42300xe3e01000,
42310x000a0000,
42320xe5d6c000,
42330xe496e004,
42340xe18900fa,
42350xe797c10c,
42360xe004a2ae,
42370xe1a0b82e,
42380xe12fff1c,
42390x00000000,
42400xe1a0b18b,
42410xe5d6c000,
42420xe18500db,
42430xe496e004,
42440xe18900fa,
42450xe797c10c,
42460xe004a2ae,
42470xe1a0b82e,
42480xe12fff1c,
42490x00000000,
42500xe089a00a,
42510xe1e0b00b,
42520xe5d6c000,
42530xe496e004,
42540xe58ab004,
42550xe797c10c,
42560xe004a2ae,
42570xe1a0b82e,
42580xe12fff1c,
42590x00000000,
42600xe089a00a,
42610xe089b18b,
42620xe3e00000,
42630x000a0000,
42640xe58a0004,
42650xe28aa008,
42660x0006000b,
42670xe58a0004,
42680xe15a000b,
42690xe28aa008,
42700xba000000,
42710x0005000b,
42720xe5d6c000,
42730xe496e004,
42740xe797c10c,
42750xe004a2ae,
42760xe1a0b82e,
42770xe12fff1c,
42780x00000000,
42790xe5191008,
42800xe1a0b10b,
42810xe28bb000,
42820x000a0000,
42830xe791100b,
42840xe5111000,
42850x000d8180,
42860xe1c120d0,
42870xe5d6c000,
42880xe496e004,
42890xe18920fa,
42900xe797c10c,
42910xe004a2ae,
42920xe1a0b82e,
42930xe12fff1c,
42940x00000000,
42950xe5191008,
42960xe1a0a0aa,
42970xe28aa000,
42980x000a0000,
42990xe1a0b18b,
43000xe791100a,
43010xe18920db,
43020xe551c000,
43030x000d8180,
43040xe551b000,
43050x000d8180,
43060xe5111000,
43070x000d8180,
43080xe31c0000,
43090x000a0000,
43100xe283c000,
43110x000a0000,
43120x135b0000,
43130xe1c120f0,
43140x1a000000,
43150x00050002,
43160x0006000b,
43170xe5d6c000,
43180xe496e004,
43190xe797c10c,
43200xe004a2ae,
43210xe1a0b82e,
43220xe12fff1c,
43230x0006000c,
43240xe37c0000,
43250x000a0000,
43260x8552b000,
43270x000d8180,
43280x9a000000,
43290x0005000b,
43300xe2470000,
43310x000a0000,
43320xe31b0000,
43330x000a0000,
43340x00000000,
43350x0a000000,
43360x0005000b,
43370xe1a0b009,
43380xeb000000,
43390x00030034,
43400xe1a0900b,
43410x00000000,
43420x1b000000,
43430x00030034,
43440x00000000,
43450xea000000,
43460x0005000b,
43470x00000000,
43480xe5191008,
43490xe1a0a0aa,
43500xe28aa000,
43510x000a0000,
43520xe1e0b00b,
43530xe791100a,
43540xe795210b,
43550xe3e03000,
43560x000a0000,
43570xe551c000,
43580x000d8180,
43590xe5111000,
43600x000d8180,
43610xe551b000,
43620x000d8180,
43630xe31c0000,
43640x000a0000,
43650xe552c000,
43660x000d8180,
43670xe1c120f0,
43680x1a000000,
43690x00050002,
43700x0006000b,
43710xe5d6c000,
43720xe496e004,
43730xe797c10c,
43740xe004a2ae,
43750xe1a0b82e,
43760xe12fff1c,
43770x0006000c,
43780xe31c0000,
43790x000a0000,
43800x135b0000,
43810xe2470000,
43820x000a0000,
43830x00000000,
43840x0a000000,
43850x0005000b,
43860xe1a0b009,
43870xeb000000,
43880x00030034,
43890xe1a0900b,
43900x00000000,
43910x1b000000,
43920x00030034,
43930x00000000,
43940xea000000,
43950x0005000b,
43960x00000000,
43970xe5191008,
43980xe1a0a0aa,
43990xe28aa000,
44000x000a0000,
44010xe1a0b18b,
44020xe791100a,
44030xe18520db,
44040xe5111000,
44050x000d8180,
44060xe5d6c000,
44070xe496e004,
44080xe1c120f0,
44090xe797c10c,
44100xe004a2ae,
44110xe1a0b82e,
44120xe12fff1c,
44130x00000000,
44140xe5191008,
44150xe1a0a0aa,
44160xe28aa000,
44170x000a0000,
44180xe791100a,
44190xe1e0b00b,
44200xe5111000,
44210x000d8180,
44220xe5d6c000,
44230xe496e004,
44240xe581b004,
44250xe797c10c,
44260xe004a2ae,
44270xe1a0b82e,
44280xe12fff1c,
44290x00000000,
44300xe5182000,
44310x000d8180,
44320xe086b10b,
44330xe5089000,
44340x000d8180,
44350xe3520000,
44360xe24b6b80,
44370x0a000000,
44380x00050001,
44390xe1a00008,
44400xe089100a,
44410xeb000000,
44420x00030035,
44430xe5189000,
44440x000d8180,
44450x0006000b,
44460xe5d6c000,
44470xe496e004,
44480xe797c10c,
44490xe004a2ae,
44500xe1a0b82e,
44510xe12fff1c,
44520x00000000,
44530xe1e0b00b,
44540xe5089000,
44550x000d8180,
44560xe795110b,
44570xe58d6008,
44580xe5192008,
44590xe1a00008,
44600xeb000000,
44610x00030036,
44620xe5189000,
44630x000d8180,
44640xe3e01000,
44650x000a0000,
44660xe5d6c000,
44670xe496e004,
44680xe18900fa,
44690xe797c10c,
44700xe004a2ae,
44710xe1a0b82e,
44720xe12fff1c,
44730x00000000,
44740xe1e0b00b,
44750x00000000,
44760xe5172000,
44770x000d8180,
44780xe5173000,
44790x000d8180,
44800xe5089000,
44810x000d8180,
44820xe58d6008,
44830xe1520003,
44840xe1a00008,
44850x2a000000,
44860x00050005,
44870x0006000b,
44880x00000000,
44890xe1a01a8b,
44900xe1a025ab,
44910xe1a0bac1,
44920xe1a01aa1,
44930xe37b0001,
44940x02811002,
44950xeb000000,
44960x00030037,
44970x00000000,
44980xe795110b,
44990xeb000000,
45000x00030038,
45010x00000000,
45020xe5189000,
45030x000d8180,
45040xe3e01000,
45050x000a0000,
45060xe5d6c000,
45070xe496e004,
45080xe18900fa,
45090xe797c10c,
45100xe004a2ae,
45110xe1a0b82e,
45120xe12fff1c,
45130x0006000f,
45140xeb000000,
45150x00030039,
45160xe1a00008,
45170xea000000,
45180x0005000b,
45190x00000000,
45200xe5191008,
45210xe1e0b00b,
45220xe5110000,
45230x000d8180,
45240xe795b10b,
45250x00000000,
45260xea000000,
45270x0005009f,
45280x00000000,
45290xea000000,
45300x000500a0,
45310x00000000,
45320xe004caae,
45330xe004b6ae,
45340xe18900dc,
45350xe18920db,
45360xe3710000,
45370x000a0000,
45380x1a000000,
45390x00050030,
45400xe3730000,
45410x000a0000,
45420x05103000,
45430x000d8180,
45440x05101000,
45450x000d8180,
45460x1a000000,
45470x00050009,
45480xe0833182,
45490xe1520001,
45500x31c320d0,
45510x2a000000,
45520x00050030,
45530xe5d6c000,
45540xe3730000,
45550x000a0000,
45560x0a000000,
45570x00050005,
45580x0006000b,
45590xe496e004,
45600xe18920fa,
45610xe797c10c,
45620xe004a2ae,
45630xe1a0b82e,
45640xe12fff1c,
45650x0006000f,
45660xe5101000,
45670x000d8180,
45680xe3510000,
45690x0a000000,
45700x0005000b,
45710xe5511000,
45720x000d8180,
45730xe3110000,
45740x000a0000,
45750x1a000000,
45760x0005000b,
45770xe004caae,
45780xea000000,
45790x00050030,
45800x00060013,
45810xe3730000,
45820x000a0000,
45830x01a0b002,
45840x0a000000,
45850x0005009f,
45860xea000000,
45870x00050030,
45880x00000000,
45890xe004caae,
45900xe20bb0ff,
45910xe18900dc,
45920xe1e0b00b,
45930xe795b10b,
45940xe3710000,
45950x000a0000,
45960x1a000000,
45970x0005002d,
45980x0006009f,
45990xe5102000,
46000x000d8180,
46010xe51b3000,
46020x000d8180,
46030xe510e000,
46040x000d8180,
46050xe1a0c000,
46060xe0022003,
46070xe0822082,
46080xe08ee182,
46090x0006000b,
46100xe14e00d0,
46110x000c8100,
46120xe14e20d0,
46130x000c8100,
46140xe51ee000,
46150x000d8180,
46160xe150000b,
46170x03710000,
46180x000a0000,
46190x1a000000,
46200x00050004,
46210xe3730000,
46220x000a0000,
46230x0a000000,
46240x00050005,
46250x0006000d,
46260xe5d6c000,
46270xe496e004,
46280xe18920fa,
46290xe797c10c,
46300xe004a2ae,
46310xe1a0b82e,
46320xe12fff1c,
46330x0006000e,
46340xe35e0000,
46350x1a000000,
46360x0005000b,
46370x0006000f,
46380xe51c0000,
46390x000d8180,
46400xe3a02000,
46410xe3e03000,
46420x000a0000,
46430xe3500000,
46440x0a000000,
46450x0005000d,
46460xe5501000,
46470x000d8180,
46480x00000000,
46490xe3110000,
46500x000a0000,
46510x1a000000,
46520x0005000d,
46530xea000000,
46540x0005002e,
46550x00000000,
46560xe004caae,
46570xe20bb0ff,
46580xe18900dc,
46590xe3710000,
46600x000a0000,
46610x1a000000,
46620x0005002f,
46630xe5102000,
46640x000d8180,
46650xe5103000,
46660x000d8180,
46670xe1a0118b,
46680xe15b0002,
46690x318320d1,
46700x2a000000,
46710x0005002f,
46720xe5d6c000,
46730xe3730000,
46740x000a0000,
46750x0a000000,
46760x00050005,
46770x0006000b,
46780xe496e004,
46790xe18920fa,
46800xe797c10c,
46810xe004a2ae,
46820xe1a0b82e,
46830xe12fff1c,
46840x0006000f,
46850xe5101000,
46860x000d8180,
46870xe3510000,
46880x0a000000,
46890x0005000b,
46900xe5511000,
46910x000d8180,
46920xe3110000,
46930x000a0000,
46940x1a000000,
46950x0005000b,
46960xea000000,
46970x0005002f,
46980x00000000,
46990xe004caae,
47000xe004b6ae,
47010xe18900dc,
47020xe18920db,
47030xe3710000,
47040x000a0000,
47050x1a000000,
47060x00050034,
47070xe3730000,
47080x000a0000,
47090x05101000,
47100x000d8180,
47110x05103000,
47120x000d8180,
47130x1a000000,
47140x00050009,
47150xe0811182,
47160xe1520003,
47170x3591e004,
47180x2a000000,
47190x00050034,
47200xe5d6c000,
47210xe37e0000,
47220x000a0000,
47230xe550e000,
47240x000d8180,
47250xe18920da,
47260x0a000000,
47270x00050005,
47280x0006000b,
47290xe31e0000,
47300x000a0000,
47310xe1c120f0,
47320x1a000000,
47330x00050007,
47340x0006000c,
47350xe496e004,
47360xe797c10c,
47370xe004a2ae,
47380xe1a0b82e,
47390xe12fff1c,
47400x0006000f,
47410xe510a000,
47420x000d8180,
47430xe35a0000,
47440x0a000000,
47450x0005000b,
47460xe55aa000,
47470x000d8180,
47480xe31a0000,
47490x000a0000,
47500x1a000000,
47510x0005000b,
47520xe516e004,
47530xe004caae,
47540xe004a2ae,
47550xea000000,
47560x00050034,
47570x00060011,
47580x00000000,
47590xe5172000,
47600x000d8180,
47610xe3cee000,
47620x000a0000,
47630xe5070000,
47640x000d8180,
47650xe540e000,
47660x000d8180,
47670xe5002000,
47680x000d8180,
47690xea000000,
47700x0005000c,
47710x00060013,
47720xe3730000,
47730x000a0000,
47740x01a0b002,
47750x0a000000,
47760x000500a0,
47770xea000000,
47780x00050034,
47790x00000000,
47800xe004caae,
47810xe20bb0ff,
47820xe18900dc,
47830xe1e0b00b,
47840xe795b10b,
47850xe3710000,
47860x000a0000,
47870x1a000000,
47880x00050031,
47890x000600a0,
47900xe5102000,
47910x000d8180,
47920xe51b3000,
47930x000d8180,
47940xe510e000,
47950x000d8180,
47960xe1a0c000,
47970xe0022003,
47980xe0822082,
47990xe3a03000,
48000xe08ee182,
48010xe54c3000,
48020x000d8180,
48030x0006000b,
48040xe14e00d0,
48050x000c8100,
48060xe51e3000,
48070x000d8180,
48080xe51e2000,
48090x000d8180,
48100xe150000b,
48110x03710000,
48120x000a0000,
48130x1a000000,
48140x00050005,
48150xe55c1000,
48160x000d8180,
48170xe3730000,
48180x000a0000,
48190xe18920da,
48200x0a000000,
48210x00050004,
48220x0006000c,
48230xe3110000,
48240x000a0000,
48250xe14e20f0,
48260x000c8100,
48270x1a000000,
48280x00050007,
48290x0006000d,
48300xe5d6c000,
48310xe496e004,
48320xe797c10c,
48330xe004a2ae,
48340xe1a0b82e,
48350xe12fff1c,
48360x0006000e,
48370x00000000,
48380xe51c0000,
48390x000d8180,
48400xe3500000,
48410x0a000000,
48420x0005000c,
48430xe5500000,
48440x000d8180,
48450xe3100000,
48460x000a0000,
48470x1a000000,
48480x0005000c,
48490xea000000,
48500x00050032,
48510x0006000f,
48520xe1b0e002,
48530x1a000000,
48540x0005000b,
48550xe51c0000,
48560x000d8180,
48570xe1a0200d,
48580xe58d6008,
48590xe3500000,
48600xe5089000,
48610x000d8180,
48620x15501000,
48630x000d8180,
48640xe1a00008,
48650x0a000000,
48660x00050006,
48670xe3110000,
48680x000a0000,
48690x0a000000,
48700x00050032,
48710x00060010,
48720xe3e03000,
48730x000a0000,
48740xe58db000,
48750xe1a0100c,
48760xe58d3004,
48770xeb000000,
48780x0003003a,
48790xe5189000,
48800x000d8180,
48810xe18920da,
48820xe1c020f0,
48830xea000000,
48840x0005000d,
48850x00060011,
48860xe5172000,
48870x000d8180,
48880xe3c11000,
48890x000a0000,
48900x00000000,
48910xe507c000,
48920x000d8180,
48930xe54c1000,
48940x000d8180,
48950xe50c2000,
48960x000d8180,
48970xea000000,
48980x0005000d,
48990x00000000,
49000xe004caae,
49010xe20bb0ff,
49020xe18900dc,
49030xe3710000,
49040x000a0000,
49050x1a000000,
49060x00050033,
49070xe5102000,
49080x000d8180,
49090xe510c000,
49100x000d8180,
49110xe1a0118b,
49120xe15b0002,
49130x31a120dc,
49140x2a000000,
49150x00050033,
49160xe5d6c000,
49170xe3730000,
49180x000a0000,
49190xe550e000,
49200x000d8180,
49210xe18920da,
49220x0a000000,
49230x00050005,
49240x0006000b,
49250xe31e0000,
49260x000a0000,
49270xe1c120f0,
49280x1a000000,
49290x00050007,
49300x0006000c,
49310xe496e004,
49320xe797c10c,
49330xe004a2ae,
49340xe1a0b82e,
49350xe12fff1c,
49360x0006000f,
49370xe510a000,
49380x000d8180,
49390xe35a0000,
49400x0a000000,
49410x0005000b,
49420xe55aa000,
49430x000d8180,
49440xe31a0000,
49450x000a0000,
49460x1a000000,
49470x0005000b,
49480xe516e004,
49490xe004a2ae,
49500xea000000,
49510x00050033,
49520x00060011,
49530xe5172000,
49540x000d8180,
49550xe3cee000,
49560x000a0000,
49570x00000000,
49580xe5070000,
49590x000d8180,
49600xe540e000,
49610x000d8180,
49620xe5002000,
49630x000d8180,
49640xea000000,
49650x0005000c,
49660x00000000,
49670xe089a00a,
49680x0006000b,
49690xe59dc004,
49700xe51a1008,
49710xe795018b,
49720xe25cc008,
49730xe5113000,
49740x000d8180,
49750x0a000000,
49760x00050004,
49770xe08021ac,
49780xe1520003,
49790xe5113000,
49800x000d8180,
49810xe08ac00c,
49820x8a000000,
49830x00050005,
49840xe083e180,
49850xe5510000,
49860x000d8180,
49870x0006000d,
49880xe0ca20d8,
49890xe0ce20f8,
49900xe15a000c,
49910x3a000000,
49920x0005000d,
49930xe3100000,
49940x000a0000,
49950x1a000000,
49960x00050007,
49970x0006000e,
49980xe5d6c000,
49990xe496e004,
50000xe797c10c,
50010xe004a2ae,
50020xe1a0b82e,
50030xe12fff1c,
50040x0006000f,
50050xe5089000,
50060x000d8180,
50070xe1a00008,
50080xe58d6008,
50090xeb000000,
50100x0003003b,
50110x00000000,
50120xe5189000,
50130x000d8180,
50140x00000000,
50150xea000000,
50160x0005000b,
50170x00060011,
50180xe5172000,
50190x000d8180,
50200xe3c00000,
50210x000a0000,
50220xe5071000,
50230x000d8180,
50240xe5410000,
50250x000d8180,
50260xe5012000,
50270x000d8180,
50280xea000000,
50290x0005000e,
50300x00000000,
50310xe59d0004,
50320xe004b6ae,
50330xe08bb000,
50340xea000000,
50350x000500a1,
50360x00000000,
50370xe004b6ae,
50380x000600a1,
50390xe1a0c009,
50400xe1a920da,
50410xe24bb008,
50420xe2899008,
50430xe3730000,
50440x000a0000,
50450x1a000000,
50460x00050025,
50470xe5096004,
50480xe5126000,
50490x000d8180,
50500xe5d6c000,
50510xe496e004,
50520xe797c10c,
50530xe004a2ae,
50540xe08aa009,
50550xe12fff1c,
50560x00000000,
50570xe59d0004,
50580xe080b18b,
50590xea000000,
50600x000500a2,
50610x00000000,
50620xe1a0b18b,
50630x000600a2,
50640xe1aa20d9,
50650xe24bb008,
50660xe28aa008,
50670xe3730000,
50680x000a0000,
50690x1a000000,
50700x00050042,
50710xe5196004,
50720x00060043,
50730xe3a0c000,
50740xe5523000,
50750x000d8180,
50760xe3160000,
50770x000a0000,
50780x1a000000,
50790x00050007,
50800x0006000b,
50810xe5092008,
50820xe35b0000,
50830x0a000000,
50840x00050003,
50850x0006000c,
50860xe18a00dc,
50870xe28ce008,
50880xe15e000b,
50890xe18900fc,
50900xe1a0c00e,
50910x1a000000,
50920x0005000c,
50930x0006000d,
50940xe3530001,
50950x8a000000,
50960x00050005,
50970x0006000e,
50980xe5126000,
50990x000d8180,
51000xe5d6c000,
51010xe496e004,
51020xe797c10c,
51030xe004a2ae,
51040xe08aa009,
51050xe12fff1c,
51060x0006000f,
51070xe516e004,
51080xe004a2ae,
51090xe049000a,
51100xe5100010,
51110xe5100000,
51120x000d8180,
51130xe5105000,
51140x000d8180,
51150xea000000,
51160x0005000e,
51170x00060011,
51180xe2266000,
51190x000a0000,
51200xe3160000,
51210x000a0000,
51220x00000000,
51230x13a03000,
51240x1a000000,
51250x0005000b,
51260xe0499006,
51270xe5196004,
51280xe3160000,
51290x000a0000,
51300x13a03000,
51310xea000000,
51320x0005000b,
51330x00000000,
51340xe089a00a,
51350xe1a0c009,
51360xe14a21d0,
51370xe14a00d8,
51380xe28a9008,
51390xe1ca20f8,
51400xe1ca01f0,
51410xe14a21d8,
51420xe3a0b010,
51430xe1ca20f0,
51440xe3730000,
51450x000a0000,
51460x1a000000,
51470x00050025,
51480xe5096004,
51490xe5126000,
51500x000d8180,
51510xe5d6c000,
51520xe496e004,
51530xe797c10c,
51540xe004a2ae,
51550xe08aa009,
51560xe12fff1c,
51570x00000000,
51580xe089a00a,
51590xe51ac010,
51600xe51a0008,
51610xe51ce000,
51620x000d8180,
51630xe51c1000,
51640x000d8180,
51650xe2866004,
51660x0006000b,
51670xe050b00e,
51680xe0812180,
51690x2a000000,
51700x00050005,
51710xe1c220d0,
51720xe3730000,
51730x000a0000,
51740x02800001,
51750x0a000000,
51760x0005000b,
51770xe156b0b2,
51780xe3e01000,
51790x000a0000,
51800xe1ca20f8,
51810xe086b10b,
51820xe280c001,
51830xe1ca00f0,
51840xe24b6b80,
51850xe50ac008,
51860x0006000d,
51870xe5d6c000,
51880xe496e004,
51890xe797c10c,
51900xe004a2ae,
51910xe1a0b82e,
51920xe12fff1c,
51930x0006000f,
51940xe51c3000,
51950x000d8180,
51960xe51cc000,
51970x000d8180,
51980x00060010,
51990xe08b008b,
52000xe15b0003,
52010xe08c2180,
52020x8a000000,
52030x0005000d,
52040xe14200d0,
52050x000c8100,
52060xe3710000,
52070x000a0000,
52080xe28bb001,
52090x0a000000,
52100x00050010,
52110xe156c0b2,
52120xe08bb00e,
52130xe14220d0,
52140x000c8100,
52150xe50ab008,
52160xe1ca00f8,
52170xe086b10c,
52180xe24b6b80,
52190xe1ca20f0,
52200xea000000,
52210x0005000d,
52220x00000000,
52230xe089a00a,
52240xe086b10b,
52250xe14a01d8,
52260xe51a200c,
52270xe51a3004,
52280xe3710000,
52290x000a0000,
52300x05500000,
52310x000d8180,
52320x03720000,
52330x000a0000,
52340x03730000,
52350x000a0000,
52360x03500000,
52370x000a0000,
52380x024b6b80,
52390x1a000000,
52400x00050005,
52410xe5d6c000,
52420xe496e004,
52430xe3a00000,
52440xe50a0008,
52450x0006000b,
52460xe797c10c,
52470xe004a2ae,
52480xe1a0b82e,
52490xe12fff1c,
52500x0006000f,
52510xe3a00000,
52520x000a0000,
52530xe3a0c000,
52540x000a0000,
52550xe5460004,
52560xe24b6b80,
52570xe5c6c000,
52580xe496e004,
52590xea000000,
52600x0005000b,
52610x00000000,
52620xe004caae,
52630xe004b6ae,
52640xe5190004,
52650xe089b00b,
52660xe089a00a,
52670xe28bb000,
52680x000a0000,
52690xe08a300c,
52700xe2492008,
52710xe04bb000,
52720xe35c0000,
52730xe042000b,
52740x0a000000,
52750x00050005,
52760xe2433010,
52770x0006000b,
52780xe15b0002,
52790x30cb00d8,
52800x23e01000,
52810x000a0000,
52820xe15a0003,
52830xe0ca00f8,
52840x3a000000,
52850x0005000b,
52860x0006000c,
52870xe5d6c000,
52880xe496e004,
52890xe797c10c,
52900xe004a2ae,
52910xe1a0b82e,
52920xe12fff1c,
52930x0006000f,
52940xe5183000,
52950x000d8180,
52960xe3500000,
52970xd3a0c008,
52980xc280c008,
52990xe08a1000,
53000xe58dc004,
53010xda000000,
53020x0005000c,
53030xe1510003,
53040x8a000000,
53050x00050007,
53060x00060010,
53070xe0cb00d8,
53080xe0ca00f8,
53090xe15b0002,
53100x3a000000,
53110x00050010,
53120xea000000,
53130x0005000c,
53140x00060011,
53150xe1a011a0,
53160xe508a000,
53170x000d8180,
53180xe1a00008,
53190xe5089000,
53200x000d8180,
53210xe04bb009,
53220xe58d6008,
53230xe04aa009,
53240xeb000000,
53250x00030000,
53260xe5189000,
53270x000d8180,
53280xe089a00a,
53290xe089b00b,
53300xe2492008,
53310xea000000,
53320x00050010,
53330x00000000,
53340xe59d0004,
53350xe5196004,
53360xe089a00a,
53370xe080b18b,
53380xea000000,
53390x000500a3,
53400x00000000,
53410xe5196004,
53420xe1a0b18b,
53430xe089a00a,
53440x000600a3,
53450xe58db004,
53460x0006000b,
53470xe2160000,
53480x000a0000,
53490xe2261000,
53500x000a0000,
53510x1a000000,
53520x000500a4,
53530x00060017,
53540xe516e004,
53550xe25b3008,
53560xe2492008,
53570x0a000000,
53580x00050003,
53590x0006000c,
53600xe0ca00d8,
53610xe2899008,
53620xe2533008,
53630xe14901f0,
53640x1a000000,
53650x0005000c,
53660x0006000d,
53670xe004a2ae,
53680xe042300a,
53690xe004caae,
53700xe5130008,
53710x0006000f,
53720xe15c000b,
53730x8a000000,
53740x00050006,
53750xe1a09003,
53760xe5101000,
53770x000d8180,
53780xe5d6c000,
53790xe496e004,
53800xe5115000,
53810x000d8180,
53820xe797c10c,
53830xe004a2ae,
53840xe1a0b82e,
53850xe12fff1c,
53860x00060010,
53870xe3e01000,
53880x000a0000,
53890xe2899008,
53900xe28bb008,
53910xe509100c,
53920xea000000,
53930x0005000f,
53940x000600a5,
53950xe089a00a,
53960x000600a4,
53970xe3110000,
53980x000a0000,
53990x1a000000,
54000x00050018,
54010xe0499001,
54020xe5196004,
54030xea000000,
54040x0005000b,
54050x00000000,
54060xe5196004,
54070xe1a0b18b,
54080xe58db004,
54090xe2160000,
54100x000a0000,
54110xe2261000,
54120x000a0000,
54130x0516e004,
54140x1a000000,
54150x000500a5,
54160x00000000,
54170xe18900da,
54180x00000000,
54190xe2493008,
54200xe004a2ae,
54210x00000000,
54220xe1c300f0,
54230x00000000,
54240xe043900a,
54250xe004caae,
54260xe5190008,
54270x0006000f,
54280xe15c000b,
54290x8a000000,
54300x00050006,
54310xe5101000,
54320x000d8180,
54330xe5d6c000,
54340xe496e004,
54350xe5115000,
54360x000d8180,
54370xe797c10c,
54380xe004a2ae,
54390xe1a0b82e,
54400xe12fff1c,
54410x00060010,
54420xe2431004,
54430xe3e02000,
54440x000a0000,
54450xe781200b,
54460xe28bb008,
54470xea000000,
54480x0005000f,
54490x00000000,
54500xe1a000a6,
54510xe200007e,
54520xe2400000,
54530x000a0000,
54540xe19710b0,
54550xe2511000,
54560x000a0000,
54570xe18710b0,
54580x3a000000,
54590x00050092,
54600x00000000,
54610xe1aa00d9,
54620x00000000,
54630xe086b10b,
54640x00000000,
54650xe1ca20d8,
54660xe3710000,
54670x000a0000,
54680xe59ac014,
54690x1a000000,
54700x00050005,
54710xe3730000,
54720x000a0000,
54730xe59a3010,
54740x037c0000,
54750x000a0000,
54760x1a000000,
54770x00050044,
54780xe3530000,
54790xba000000,
54800x00050004,
54810xe1500002,
54820x00000000,
54830xe1ca21d0,
54840xe3710000,
54850x000a0000,
54860x1a000000,
54870x00050005,
54880xe0900002,
54890xe59a3008,
54900x00000000,
54910x6286bb80,
54920x00000000,
54930x6a000000,
54940x00050002,
54950x00000000,
54960xe3520000,
54970xba000000,
54980x00050004,
54990xe1500003,
55000x00000000,
55010x0006000b,
55020x00000000,
55030xc24b6b80,
55040x00000000,
55050xe24b6b80,
55060xd156b0b2,
55070x00000000,
55080xd24b6b80,
55090x00000000,
55100xe1ca00f0,
55110x00000000,
55120x0006000c,
55130xe5d6c000,
55140xe496e004,
55150xe1ca01f8,
55160x00000000,
55170xda000000,
55180x00070000,
55190x00000000,
55200x0006000d,
55210xe797c10c,
55220xe004a2ae,
55230xe1a0b82e,
55240xe12fff1c,
55250x0006000e,
55260x00000000,
55270xe1520000,
55280x00000000,
55290xe1530000,
55300x00000000,
55310xea000000,
55320x0005000b,
55330x0006000f,
55340x00000000,
55350x33730000,
55360x000a0000,
55370x337c0000,
55380x000a0000,
55390x2a000000,
55400x00050044,
55410xe35c0000,
55420xe1ca00f0,
55430xe1ca01f8,
55440xba000000,
55450x00050008,
55460x00000000,
55470xe3530000,
55480xba000000,
55490x00050008,
55500xeb000000,
55510x0003002e,
55520xe1ca00f0,
55530xe1ca20d8,
55540xe1ca01f8,
55550x00000000,
55560x00060010,
55570xeb000000,
55580x00030024,
55590x00000000,
55600x824b6b80,
55610x00000000,
55620xe24b6b80,
55630x9156b0b2,
55640x9a000000,
55650x00070000,
55660x00000000,
55670x924b6b80,
55680x00000000,
55690x9a000000,
55700x00070000,
55710x00000000,
55720xe5d6c000,
55730xe496e004,
55740xea000000,
55750x0005000d,
55760x00060012,
55770x00000000,
55780xeb000000,
55790x0003002e,
55800xe1ca00f0,
55810xe1ca01f8,
55820x00000000,
55830xe1a02000,
55840xe1a03001,
55850xe1ca00d8,
55860xea000000,
55870x00050010,
55880x00000000,
55890xe1a000a6,
55900xe200007e,
55910xe2400000,
55920x000a0000,
55930xe19710b0,
55940xe2511000,
55950x000a0000,
55960xe18710b0,
55970x3a000000,
55980x00050092,
55990x00000000,
56000xe1aa00d9,
56010x00000000,
56020xe3710000,
56030x000a0000,
56040x114a00f8,
56050x1a000000,
56060x00070000,
56070x00000000,
56080xe086b10b,
56090xe3710000,
56100x000a0000,
56110x124b6b80,
56120x114a00f8,
56130x00000000,
56140xe5d6c000,
56150xe496e004,
56160xe797c10c,
56170xe004a2ae,
56180xe1a0b82e,
56190xe12fff1c,
56200x00000000,
56210xe1a000a6,
56220xe200007e,
56230xe2400000,
56240x000a0000,
56250xe19710b0,
56260xe2511000,
56270x000a0000,
56280xe18710b0,
56290x3a000000,
56300x00050092,
56310x00000000,
56320xe5d6c000,
56330xe496e004,
56340xe797c10c,
56350xe004a2ae,
56360xe1a0b82e,
56370xe12fff1c,
56380x00000000,
56390xe5170000,
56400x000d8180,
56410xe3a01000,
56420xe790b10b,
56430xe5071000,
56440x000d8180,
56450xe51ba000,
56460x000d8180,
56470xe5079000,
56480x000d8180,
56490xe5078000,
56500x000d8180,
56510xe12fff1a,
56520x00000000,
56530xe086b10b,
56540xe24b6b80,
56550xe5d6c000,
56560xe496e004,
56570xe797c10c,
56580xe004a2ae,
56590xe1a0b82e,
56600xe12fff1c,
56610x00000000,
56620xe1a000a6,
56630xe200007e,
56640xe2400000,
56650x000a0000,
56660xe19710b0,
56670xe2511000,
56680x000a0000,
56690xe18710b0,
56700x3a000000,
56710x00050094,
56720x00000000,
56730xe5180000,
56740x000d8180,
56750xe5561000,
56760x000d8180,
56770xe5165000,
56780x000d8180,
56790xe15a0000,
56800x8a000000,
56810x00050020,
56820x00000000,
56830xe5d6c000,
56840xe496e004,
56850x00000000,
56860x0006000c,
56870xe15b0181,
56880xe3e03000,
56890x000a0000,
56900xda000000,
56910x00050003,
56920x00000000,
56930xe1a0b82e,
56940xea000000,
56950x00070000,
56960x00000000,
56970xe797c10c,
56980xe004a2ae,
56990xe1a0b82e,
57000xe12fff1c,
57010x00000000,
57020x0006000d,
57030xe18920fb,
57040xe28bb008,
57050xea000000,
57060x0005000c,
57070x00000000,
57080xe7f001f0,
57090x00000000,
57100xe5180000,
57110x000d8180,
57120xe089300b,
57130xe08aa00b,
57140xe5832000,
57150xe28b1000,
57160x000a0000,
57170xe5165000,
57180x000d8180,
57190xe15a0000,
57200xe5831004,
57210x2a000000,
57220x00050020,
57230xe556c000,
57240x000d8180,
57250xe1a0a009,
57260xe1a0b003,
57270xe35c0000,
57280xe2839008,
57290x0a000000,
57300x00050003,
57310xe3e02000,
57320x000a0000,
57330x0006000b,
57340xe15a000b,
57350x30ca00d8,
57360x21a01002,
57370x350a2004,
57380x0006000c,
57390xe25cc001,
57400xe1e300f8,
57410x1a000000,
57420x0005000b,
57430x0006000d,
57440xe5d6c000,
57450xe496e004,
57460xe797c10c,
57470xe004a2ae,
57480xe1a0b82e,
57490xe12fff1c,
57500x00000000,
57510xe5123000,
57520x000d8180,
57530x00000000,
57540xe5173000,
57550x000d8180,
57560x00000000,
57570xe08a100b,
57580xe5180000,
57590x000d8180,
57600xe089b00b,
57610xe5089000,
57620x000d8180,
57630xe1510000,
57640xe508b000,
57650x000d8180,
57660x00000000,
57670xe5121000,
57680x000d8180,
57690x00000000,
57700xe3e02000,
57710x000a0000,
57720xe1a00008,
57730x8a000000,
57740x0005001f,
57750xe5072000,
57760x000d8180,
57770xe12fff33,
57780xe5189000,
57790x000d8180,
57800xe3e02000,
57810x000a0000,
57820xe5181000,
57830x000d8180,
57840xe1a0b180,
57850xe5072000,
57860x000d8180,
57870xe5196004,
57880xe041a00b,
57890xea000000,
57900x00050016,
57910x00000000,
57920x00010000
5793};
5794
5795enum {
5796 GLOB_vm_returnp,
5797 GLOB_cont_dispatch,
5798 GLOB_vm_returnc,
5799 GLOB_BC_RET_Z,
5800 GLOB_vm_return,
5801 GLOB_vm_leave_cp,
5802 GLOB_vm_leave_unw,
5803 GLOB_vm_unwind_c,
5804 GLOB_vm_unwind_c_eh,
5805 GLOB_vm_unwind_ff,
5806 GLOB_vm_unwind_ff_eh,
5807 GLOB_vm_growstack_c,
5808 GLOB_vm_growstack_l,
5809 GLOB_vm_resume,
5810 GLOB_vm_pcall,
5811 GLOB_vm_call,
5812 GLOB_vm_call_dispatch,
5813 GLOB_vmeta_call,
5814 GLOB_vm_call_dispatch_f,
5815 GLOB_vm_cpcall,
5816 GLOB_cont_ffi_callback,
5817 GLOB_vm_call_tail,
5818 GLOB_cont_cat,
5819 GLOB_BC_CAT_Z,
5820 GLOB_cont_nop,
5821 GLOB_vmeta_tgets1,
5822 GLOB_vmeta_tgets,
5823 GLOB_vmeta_tgetb,
5824 GLOB_vmeta_tgetv,
5825 GLOB_vmeta_tsets1,
5826 GLOB_vmeta_tsets,
5827 GLOB_vmeta_tsetb,
5828 GLOB_vmeta_tsetv,
5829 GLOB_vmeta_comp,
5830 GLOB_vmeta_binop,
5831 GLOB_cont_ra,
5832 GLOB_cont_condt,
5833 GLOB_cont_condf,
5834 GLOB_vmeta_equal,
5835 GLOB_vmeta_equal_cd,
5836 GLOB_vmeta_arith_vn,
5837 GLOB_vmeta_arith_nv,
5838 GLOB_vmeta_unm,
5839 GLOB_vmeta_arith_vv,
5840 GLOB_vmeta_len,
5841 GLOB_BC_LEN_Z,
5842 GLOB_vmeta_callt,
5843 GLOB_BC_CALLT2_Z,
5844 GLOB_vmeta_for,
5845 GLOB_ff_assert,
5846 GLOB_fff_fallback,
5847 GLOB_fff_res,
5848 GLOB_ff_type,
5849 GLOB_fff_restv,
5850 GLOB_ff_getmetatable,
5851 GLOB_ff_setmetatable,
5852 GLOB_ff_rawget,
5853 GLOB_ff_tonumber,
5854 GLOB_ff_tostring,
5855 GLOB_fff_gcstep,
5856 GLOB_ff_next,
5857 GLOB_ff_pairs,
5858 GLOB_ff_ipairs_aux,
5859 GLOB_ff_ipairs,
5860 GLOB_ff_pcall,
5861 GLOB_ff_xpcall,
5862 GLOB_ff_coroutine_resume,
5863 GLOB_ff_coroutine_wrap_aux,
5864 GLOB_ff_coroutine_yield,
5865 GLOB_ff_math_floor,
5866 GLOB_vm_floor,
5867 GLOB_ff_math_ceil,
5868 GLOB_vm_ceil,
5869 GLOB_ff_math_abs,
5870 GLOB_fff_res1,
5871 GLOB_ff_math_sqrt,
5872 GLOB_ff_math_log,
5873 GLOB_ff_math_log10,
5874 GLOB_ff_math_exp,
5875 GLOB_ff_math_sin,
5876 GLOB_ff_math_cos,
5877 GLOB_ff_math_tan,
5878 GLOB_ff_math_asin,
5879 GLOB_ff_math_acos,
5880 GLOB_ff_math_atan,
5881 GLOB_ff_math_sinh,
5882 GLOB_ff_math_cosh,
5883 GLOB_ff_math_tanh,
5884 GLOB_ff_math_pow,
5885 GLOB_ff_math_atan2,
5886 GLOB_ff_math_fmod,
5887 GLOB_ff_math_deg,
5888 GLOB_ff_math_rad,
5889 GLOB_ff_math_ldexp,
5890 GLOB_ff_math_frexp,
5891 GLOB_ff_math_modf,
5892 GLOB_ff_math_min,
5893 GLOB_ff_math_max,
5894 GLOB_ff_string_len,
5895 GLOB_ff_string_byte,
5896 GLOB_ff_string_char,
5897 GLOB_fff_newstr,
5898 GLOB_ff_string_sub,
5899 GLOB_fff_emptystr,
5900 GLOB_ff_string_rep,
5901 GLOB_ff_string_reverse,
5902 GLOB_ff_string_lower,
5903 GLOB_ff_string_upper,
5904 GLOB_ff_table_getn,
5905 GLOB_vm_tobit_fb,
5906 GLOB_vm_tobit,
5907 GLOB_ff_bit_tobit,
5908 GLOB_ff_bit_band,
5909 GLOB_ff_bit_bor,
5910 GLOB_ff_bit_bxor,
5911 GLOB_ff_bit_bswap,
5912 GLOB_ff_bit_bnot,
5913 GLOB_ff_bit_lshift,
5914 GLOB_ff_bit_rshift,
5915 GLOB_ff_bit_arshift,
5916 GLOB_ff_bit_rol,
5917 GLOB_ff_bit_ror,
5918 GLOB_vm_record,
5919 GLOB_vm_rethook,
5920 GLOB_vm_inshook,
5921 GLOB_cont_hook,
5922 GLOB_vm_hotloop,
5923 GLOB_vm_callhook,
5924 GLOB_vm_hotcall,
5925 GLOB_vm_exit_handler,
5926 GLOB_vm_exit_interp,
5927 GLOB_vm_trunc,
5928 GLOB_vm_mod,
5929 GLOB_vm_modi,
5930 GLOB_vm_foldarith,
5931 GLOB_vm_ffi_callback,
5932 GLOB_vm_ffi_call,
5933 GLOB_BC_ISEQN_Z,
5934 GLOB_BC_ISNEN_Z,
5935 GLOB_BC_TGETS_Z,
5936 GLOB_BC_TSETS_Z,
5937 GLOB_BC_CALL_Z,
5938 GLOB_BC_CALLT1_Z,
5939 GLOB_BC_RETM_Z,
5940 GLOB_BC_RETV2_Z,
5941 GLOB_BC_RETV1_Z,
5942 GLOB__MAX
5943};
5944static const char *const globnames[] = {
5945 "vm_returnp",
5946 "cont_dispatch",
5947 "vm_returnc",
5948 "BC_RET_Z",
5949 "vm_return",
5950 "vm_leave_cp",
5951 "vm_leave_unw",
5952 "vm_unwind_c",
5953 "vm_unwind_c_eh",
5954 "vm_unwind_ff",
5955 "vm_unwind_ff_eh",
5956 "vm_growstack_c",
5957 "vm_growstack_l",
5958 "vm_resume",
5959 "vm_pcall",
5960 "vm_call",
5961 "vm_call_dispatch",
5962 "vmeta_call",
5963 "vm_call_dispatch_f",
5964 "vm_cpcall",
5965 "cont_ffi_callback",
5966 "vm_call_tail",
5967 "cont_cat",
5968 "BC_CAT_Z",
5969 "cont_nop",
5970 "vmeta_tgets1",
5971 "vmeta_tgets",
5972 "vmeta_tgetb",
5973 "vmeta_tgetv",
5974 "vmeta_tsets1",
5975 "vmeta_tsets",
5976 "vmeta_tsetb",
5977 "vmeta_tsetv",
5978 "vmeta_comp",
5979 "vmeta_binop",
5980 "cont_ra",
5981 "cont_condt",
5982 "cont_condf",
5983 "vmeta_equal",
5984 "vmeta_equal_cd",
5985 "vmeta_arith_vn",
5986 "vmeta_arith_nv",
5987 "vmeta_unm",
5988 "vmeta_arith_vv",
5989 "vmeta_len",
5990 "BC_LEN_Z",
5991 "vmeta_callt",
5992 "BC_CALLT2_Z",
5993 "vmeta_for",
5994 "ff_assert",
5995 "fff_fallback",
5996 "fff_res",
5997 "ff_type",
5998 "fff_restv",
5999 "ff_getmetatable",
6000 "ff_setmetatable",
6001 "ff_rawget",
6002 "ff_tonumber",
6003 "ff_tostring",
6004 "fff_gcstep",
6005 "ff_next",
6006 "ff_pairs",
6007 "ff_ipairs_aux",
6008 "ff_ipairs",
6009 "ff_pcall",
6010 "ff_xpcall",
6011 "ff_coroutine_resume",
6012 "ff_coroutine_wrap_aux",
6013 "ff_coroutine_yield",
6014 "ff_math_floor",
6015 "vm_floor",
6016 "ff_math_ceil",
6017 "vm_ceil",
6018 "ff_math_abs",
6019 "fff_res1",
6020 "ff_math_sqrt",
6021 "ff_math_log",
6022 "ff_math_log10",
6023 "ff_math_exp",
6024 "ff_math_sin",
6025 "ff_math_cos",
6026 "ff_math_tan",
6027 "ff_math_asin",
6028 "ff_math_acos",
6029 "ff_math_atan",
6030 "ff_math_sinh",
6031 "ff_math_cosh",
6032 "ff_math_tanh",
6033 "ff_math_pow",
6034 "ff_math_atan2",
6035 "ff_math_fmod",
6036 "ff_math_deg",
6037 "ff_math_rad",
6038 "ff_math_ldexp",
6039 "ff_math_frexp",
6040 "ff_math_modf",
6041 "ff_math_min",
6042 "ff_math_max",
6043 "ff_string_len",
6044 "ff_string_byte",
6045 "ff_string_char",
6046 "fff_newstr",
6047 "ff_string_sub",
6048 "fff_emptystr",
6049 "ff_string_rep",
6050 "ff_string_reverse",
6051 "ff_string_lower",
6052 "ff_string_upper",
6053 "ff_table_getn",
6054 "vm_tobit_fb",
6055 "vm_tobit",
6056 "ff_bit_tobit",
6057 "ff_bit_band",
6058 "ff_bit_bor",
6059 "ff_bit_bxor",
6060 "ff_bit_bswap",
6061 "ff_bit_bnot",
6062 "ff_bit_lshift",
6063 "ff_bit_rshift",
6064 "ff_bit_arshift",
6065 "ff_bit_rol",
6066 "ff_bit_ror",
6067 "vm_record",
6068 "vm_rethook",
6069 "vm_inshook",
6070 "cont_hook",
6071 "vm_hotloop",
6072 "vm_callhook",
6073 "vm_hotcall",
6074 "vm_exit_handler",
6075 "vm_exit_interp",
6076 "vm_trunc",
6077 "vm_mod",
6078 "vm_modi",
6079 "vm_foldarith",
6080 "vm_ffi_callback",
6081 "vm_ffi_call",
6082 "BC_ISEQN_Z",
6083 "BC_ISNEN_Z",
6084 "BC_TGETS_Z",
6085 "BC_TSETS_Z",
6086 "BC_CALL_Z",
6087 "BC_CALLT1_Z",
6088 "BC_RETM_Z",
6089 "BC_RETV2_Z",
6090 "BC_RETV1_Z",
6091 (const char *)0
6092};
6093static const char *const extnames[] = {
6094 "lj_state_growstack",
6095 "lj_meta_tget",
6096 "lj_meta_tset",
6097 "lj_meta_comp",
6098 "lj_meta_equal",
6099 "lj_meta_equal_cd",
6100 "lj_meta_arith",
6101 "lj_meta_len",
6102 "lj_meta_call",
6103 "lj_meta_for",
6104 "lj_tab_get",
6105 "lj_str_fromnumber",
6106 "lj_tab_next",
6107 "lj_tab_getinth",
6108 "lj_ffh_coroutine_wrap_err",
6109 "sqrt",
6110 "log",
6111 "log10",
6112 "exp",
6113 "sin",
6114 "cos",
6115 "tan",
6116 "asin",
6117 "acos",
6118 "atan",
6119 "sinh",
6120 "cosh",
6121 "tanh",
6122 "pow",
6123 "atan2",
6124 "fmod",
6125 "__aeabi_dmul",
6126 "ldexp",
6127 "frexp",
6128 "modf",
6129 "__aeabi_i2d",
6130 "__aeabi_cdcmple",
6131 "lj_str_new",
6132 "lj_tab_len",
6133 "lj_gc_step",
6134 "lj_dispatch_ins",
6135 "lj_trace_hot",
6136 "lj_dispatch_call",
6137 "lj_trace_exit",
6138 "lj_err_throw",
6139 "__aeabi_ddiv",
6140 "__aeabi_dadd",
6141 "__aeabi_dsub",
6142 "lj_ccallback_enter",
6143 "lj_ccallback_leave",
6144 "__aeabi_cdcmpeq",
6145 "lj_meta_cat",
6146 "lj_gc_barrieruv",
6147 "lj_func_closeuv",
6148 "lj_func_newL_gc",
6149 "lj_tab_new",
6150 "lj_tab_dup",
6151 "lj_gc_step_fixtop",
6152 "lj_tab_newkey",
6153 "lj_tab_reasize",
6154 (const char *)0
6155};
6156#define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V)
6157#define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V)
6158#define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V)
6159#define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V)
6160#define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V)
6161#define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V)
6162#define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V)
6163#define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V)
6164#define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V)
6165#define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V)
6166#define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V)
6167#define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V)
6168#define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V)
6169#define field_pc pc
6170#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
6171#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
6172#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
6173
6174#if !LJ_DUALNUM
6175#error "Only dual-number mode supported for ARM target"
6176#endif
6177
6178/* Generate subroutines used by opcodes and other parts of the VM. */
6179/* The .code_sub section should be last to help static branch prediction. */
6180static void build_subroutines(BuildCtx *ctx)
6181{
6182 dasm_put(Dst, 0);
6183 dasm_put(Dst, 1, FRAME_P, ~LJ_TTRUE, FRAME_TYPE, FRAME_TYPEP, FRAME_C, Dt1(->base), LJ_VMST_C, DISPATCH_GL(vmstate), Dt1(->top));
6184 dasm_put(Dst, 54, Dt1(->cframe), Dt1(->maxstack), ~LJ_TNIL, Dt1(->top), Dt1(->top), LJ_VMST_C, Dt1(->glref), Dt2(->vmstate));
6185 dasm_put(Dst, 108, ~CFRAME_RAWMASK, Dt1(->base), Dt1(->glref), ~LJ_TFALSE, GG_G2DISP, LJ_VMST_INTERP, DISPATCH_GL(vmstate), LUA_MINSTACK, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top), Dt7(->field_pc), Dt1(->glref));
6186 dasm_put(Dst, 173, GG_G2DISP, FRAME_CP, CFRAME_RESUME, Dt1(->status), Dt1(->cframe), Dt1(->base), Dt1(->top), Dt1(->status), LJ_VMST_INTERP, FRAME_TYPE, DISPATCH_GL(vmstate), FRAME_CP, FRAME_C, Dt1(->cframe), Dt1(->cframe));
6187 dasm_put(Dst, 238, Dt1(->glref), GG_G2DISP, Dt1(->base), Dt1(->top), LJ_VMST_INTERP, DISPATCH_GL(vmstate), -LJ_TFUNC, Dt7(->field_pc), Dt1(->stack), Dt1(->top), Dt1(->cframe), Dt1(->cframe), Dt1(->glref), FRAME_CP, GG_G2DISP);
6188 dasm_put(Dst, 307);
6189#if LJ_HASFFI
6190 dasm_put(Dst, 312);
6191#endif
6192 dasm_put(Dst, 314, Dt7(->field_pc), ~LJ_TNIL);
6193#if LJ_HASFFI
6194 dasm_put(Dst, 322);
6195#endif
6196 dasm_put(Dst, 325, PC2PROTO(k));
6197#if LJ_HASFFI
6198 dasm_put(Dst, 329);
6199#endif
6200 dasm_put(Dst, 338, Dt1(->base), -DISPATCH_GL(tmptv), ~LJ_TTAB, ~LJ_TSTR, ~LJ_TISNUM, Dt1(->base));
6201 if (LJ_TARGET_OSX) {
6202 dasm_put(Dst, 395, Dt1(->base));
6203 }
6204 dasm_put(Dst, 398, FRAME_CONT, Dt1(->top), -DISPATCH_GL(tmptv), ~LJ_TTAB, ~LJ_TSTR, ~LJ_TISNUM, Dt1(->base));
6205 if (LJ_TARGET_OSX) {
6206 dasm_put(Dst, 460, Dt1(->base));
6207 }
6208 dasm_put(Dst, 463, FRAME_CONT, Dt1(->top), Dt1(->base));
6209 if (LJ_TARGET_OSX) {
6210 dasm_put(Dst, 499, Dt1(->base));
6211 }
6212 dasm_put(Dst, 502, ~LJ_TTRUE, -LJ_TFALSE, Dt1(->base));
6213#if LJ_HASFFI
6214 dasm_put(Dst, 549, Dt1(->base));
6215#endif
6216 dasm_put(Dst, 560, Dt1(->base));
6217 if (LJ_TARGET_OSX) {
6218 dasm_put(Dst, 597, Dt1(->base));
6219 }
6220 dasm_put(Dst, 600, FRAME_CONT, Dt1(->base));
6221 if (LJ_TARGET_OSX) {
6222 dasm_put(Dst, 621, Dt1(->base));
6223 }
6224#ifdef LUAJIT_ENABLE_LUA52COMPAT
6225 dasm_put(Dst, 624);
6226#else
6227 dasm_put(Dst, 631);
6228#endif
6229 dasm_put(Dst, 634, Dt1(->base));
6230 if (LJ_TARGET_OSX) {
6231 dasm_put(Dst, 642);
6232 }
6233 dasm_put(Dst, 644);
6234 if (LJ_TARGET_OSX) {
6235 dasm_put(Dst, 647);
6236 }
6237 dasm_put(Dst, 649, Dt7(->field_pc), Dt1(->base));
6238 if (LJ_TARGET_OSX) {
6239 dasm_put(Dst, 670, Dt1(->base));
6240 }
6241 dasm_put(Dst, 673, Dt1(->base));
6242 if (LJ_TARGET_OSX) {
6243 dasm_put(Dst, 687, Dt1(->base));
6244 }
6245#if LJ_HASJIT
6246 dasm_put(Dst, 690);
6247#endif
6248 dasm_put(Dst, 692);
6249#if LJ_HASJIT
6250 dasm_put(Dst, 694, BC_JFORI);
6251#endif
6252 dasm_put(Dst, 697);
6253#if LJ_HASJIT
6254 dasm_put(Dst, 700, BC_JFORI);
6255#endif
6256 dasm_put(Dst, 703, BC_FORI, -LJ_TTRUE, -LJ_TISNUM, ~LJ_TISNUM, (int)(offsetof(GCfuncC, upvalue)>>3)-1, -LJ_TTAB, -LJ_TUDATA, Dt6(->metatable));
6257 dasm_put(Dst, 760, ~LJ_TNIL, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable]), Dt6(->hmask), Dt5(->hash), Dt6(->node), DtB(->key), DtB(->val), DtB(->next), -LJ_TSTR, ~LJ_TTAB, -LJ_TNIL, -LJ_TISNUM);
6258 dasm_put(Dst, 808, ~LJ_TISNUM, DISPATCH_GL(gcroot[GCROOT_BASEMT]), -LJ_TTAB, Dt6(->metatable), -LJ_TTAB, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), DISPATCH_GL(gc.grayagain), LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist), -LJ_TTAB);
6259 dasm_put(Dst, 860);
6260 if (LJ_TARGET_OSX) {
6261 dasm_put(Dst, 865);
6262 }
6263 dasm_put(Dst, 867);
6264 if (LJ_TARGET_OSX) {
6265 dasm_put(Dst, 870);
6266 }
6267 dasm_put(Dst, 872, -LJ_TISNUM, -LJ_TSTR, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]), Dt1(->base), -LJ_TISNUM, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), ~LJ_TSTR);
6268 dasm_put(Dst, 924, ~LJ_TNIL, -LJ_TTAB, Dt1(->base), Dt1(->top));
6269 if (LJ_TARGET_OSX) {
6270 dasm_put(Dst, 947, Dt1(->base));
6271 }
6272 dasm_put(Dst, 950, ~LJ_TNIL, (2+1)*8, -LJ_TTAB);
6273#ifdef LUAJIT_ENABLE_LUA52COMPAT
6274 dasm_put(Dst, 973, Dt6(->metatable));
6275#endif
6276 dasm_put(Dst, 976, Dt8(->upvalue[0]));
6277#ifdef LUAJIT_ENABLE_LUA52COMPAT
6278 dasm_put(Dst, 980);
6279#endif
6280 dasm_put(Dst, 984, ~LJ_TNIL, (3+1)*8, -LJ_TTAB, -LJ_TISNUM, Dt6(->asize), Dt6(->array), (0+1)*8, -LJ_TNIL, (2+1)*8, Dt6(->hmask));
6281 if (LJ_TARGET_OSX) {
6282 dasm_put(Dst, 1034);
6283 }
6284 dasm_put(Dst, 1036);
6285 if (LJ_TARGET_OSX) {
6286 dasm_put(Dst, 1039);
6287 }
6288 dasm_put(Dst, 1041, -LJ_TTAB);
6289#ifdef LUAJIT_ENABLE_LUA52COMPAT
6290 dasm_put(Dst, 1057, Dt6(->metatable));
6291#endif
6292 dasm_put(Dst, 1060, Dt8(->upvalue[0]));
6293#ifdef LUAJIT_ENABLE_LUA52COMPAT
6294 dasm_put(Dst, 1064);
6295#endif
6296 dasm_put(Dst, 1068, ~LJ_TISNUM, (3+1)*8, DISPATCH_GL(hookmask), HOOK_ACTIVE, 8+FRAME_PCALL, 8+FRAME_PCALLH, DISPATCH_GL(hookmask), -LJ_TFUNC, HOOK_ACTIVE, 16+FRAME_PCALL, 16+FRAME_PCALLH, -LJ_TTHREAD);
6297 dasm_put(Dst, 1127, Dt1(->base), Dt1(->top), Dt1(->status), Dt1(->base), Dt1(->maxstack), Dt1(->cframe), LUA_YIELD, Dt1(->top), Dt1(->top), Dt1(->base), LJ_VMST_INTERP, Dt1(->top), DISPATCH_GL(vmstate), LUA_YIELD);
6298 dasm_put(Dst, 1186, Dt1(->base), Dt1(->maxstack), Dt1(->top), ~LJ_TTRUE, FRAME_TYPE, ~LJ_TFALSE, (2+1)*8, Dt1(->top));
6299 dasm_put(Dst, 1246, Dt8(->upvalue[0].gcr), Dt1(->base), Dt1(->top), Dt1(->status), Dt1(->base), Dt1(->maxstack), Dt1(->cframe), LUA_YIELD, Dt1(->top), Dt1(->top), Dt1(->base), LJ_VMST_INTERP, Dt1(->top), DISPATCH_GL(vmstate), LUA_YIELD);
6300 dasm_put(Dst, 1302, Dt1(->base), Dt1(->maxstack), Dt1(->top), FRAME_TYPE, Dt1(->cframe), Dt1(->base), CFRAME_RESUME, Dt1(->top));
6301 dasm_put(Dst, 1361, LUA_YIELD, Dt1(->cframe), Dt1(->status), -LJ_TISNUM, ~LJ_TISNUM, ~LJ_TISNUM);
6302 dasm_put(Dst, 1427, -LJ_TISNUM, ~LJ_TISNUM, ~LJ_TISNUM);
6303 dasm_put(Dst, 1491, -LJ_TISNUM, (1+1)*8, FRAME_TYPE, ~LJ_TNIL);
6304 dasm_put(Dst, 1555, -LJ_TISNUM);
6305 if (LJ_TARGET_OSX) {
6306 dasm_put(Dst, 1560);
6307 }
6308 dasm_put(Dst, 1562);
6309 if (LJ_TARGET_OSX) {
6310 dasm_put(Dst, 1565);
6311 }
6312 dasm_put(Dst, 1567, -LJ_TISNUM);
6313 if (LJ_TARGET_OSX) {
6314 dasm_put(Dst, 1579);
6315 }
6316 dasm_put(Dst, 1581);
6317 if (LJ_TARGET_OSX) {
6318 dasm_put(Dst, 1584);
6319 }
6320 dasm_put(Dst, 1586, -LJ_TISNUM);
6321 if (LJ_TARGET_OSX) {
6322 dasm_put(Dst, 1598);
6323 }
6324 dasm_put(Dst, 1600);
6325 if (LJ_TARGET_OSX) {
6326 dasm_put(Dst, 1603);
6327 }
6328 dasm_put(Dst, 1605, -LJ_TISNUM);
6329 if (LJ_TARGET_OSX) {
6330 dasm_put(Dst, 1617);
6331 }
6332 dasm_put(Dst, 1619);
6333 if (LJ_TARGET_OSX) {
6334 dasm_put(Dst, 1622);
6335 }
6336 dasm_put(Dst, 1624, -LJ_TISNUM);
6337 if (LJ_TARGET_OSX) {
6338 dasm_put(Dst, 1636);
6339 }
6340 dasm_put(Dst, 1638);
6341 if (LJ_TARGET_OSX) {
6342 dasm_put(Dst, 1641);
6343 }
6344 dasm_put(Dst, 1643, -LJ_TISNUM);
6345 if (LJ_TARGET_OSX) {
6346 dasm_put(Dst, 1655);
6347 }
6348 dasm_put(Dst, 1657);
6349 if (LJ_TARGET_OSX) {
6350 dasm_put(Dst, 1660);
6351 }
6352 dasm_put(Dst, 1662, -LJ_TISNUM);
6353 if (LJ_TARGET_OSX) {
6354 dasm_put(Dst, 1674);
6355 }
6356 dasm_put(Dst, 1676);
6357 if (LJ_TARGET_OSX) {
6358 dasm_put(Dst, 1679);
6359 }
6360 dasm_put(Dst, 1681, -LJ_TISNUM);
6361 if (LJ_TARGET_OSX) {
6362 dasm_put(Dst, 1693);
6363 }
6364 dasm_put(Dst, 1695);
6365 if (LJ_TARGET_OSX) {
6366 dasm_put(Dst, 1698);
6367 }
6368 dasm_put(Dst, 1700, -LJ_TISNUM);
6369 if (LJ_TARGET_OSX) {
6370 dasm_put(Dst, 1712);
6371 }
6372 dasm_put(Dst, 1714);
6373 if (LJ_TARGET_OSX) {
6374 dasm_put(Dst, 1717);
6375 }
6376 dasm_put(Dst, 1719, -LJ_TISNUM);
6377 if (LJ_TARGET_OSX) {
6378 dasm_put(Dst, 1731);
6379 }
6380 dasm_put(Dst, 1733);
6381 if (LJ_TARGET_OSX) {
6382 dasm_put(Dst, 1736);
6383 }
6384 dasm_put(Dst, 1738, -LJ_TISNUM);
6385 if (LJ_TARGET_OSX) {
6386 dasm_put(Dst, 1750);
6387 }
6388 dasm_put(Dst, 1752);
6389 if (LJ_TARGET_OSX) {
6390 dasm_put(Dst, 1755);
6391 }
6392 dasm_put(Dst, 1757, -LJ_TISNUM);
6393 if (LJ_TARGET_OSX) {
6394 dasm_put(Dst, 1769);
6395 }
6396 dasm_put(Dst, 1771);
6397 if (LJ_TARGET_OSX) {
6398 dasm_put(Dst, 1774);
6399 }
6400 dasm_put(Dst, 1776, -LJ_TISNUM);
6401 if (LJ_TARGET_OSX) {
6402 dasm_put(Dst, 1788);
6403 }
6404 dasm_put(Dst, 1790);
6405 if (LJ_TARGET_OSX) {
6406 dasm_put(Dst, 1793);
6407 }
6408 dasm_put(Dst, 1795, -LJ_TISNUM, -LJ_TISNUM);
6409 if (LJ_TARGET_OSX) {
6410 dasm_put(Dst, 1810);
6411 }
6412 dasm_put(Dst, 1812);
6413 if (LJ_TARGET_OSX) {
6414 dasm_put(Dst, 1815);
6415 }
6416 dasm_put(Dst, 1817, -LJ_TISNUM, -LJ_TISNUM);
6417 if (LJ_TARGET_OSX) {
6418 dasm_put(Dst, 1832);
6419 }
6420 dasm_put(Dst, 1834);
6421 if (LJ_TARGET_OSX) {
6422 dasm_put(Dst, 1837);
6423 }
6424 dasm_put(Dst, 1839, -LJ_TISNUM, -LJ_TISNUM);
6425 if (LJ_TARGET_OSX) {
6426 dasm_put(Dst, 1854);
6427 }
6428 dasm_put(Dst, 1856);
6429 if (LJ_TARGET_OSX) {
6430 dasm_put(Dst, 1859);
6431 }
6432 dasm_put(Dst, 1861, -LJ_TISNUM, Dt8(->upvalue[0]), -LJ_TISNUM, -LJ_TISNUM);
6433 if (LJ_TARGET_OSX) {
6434 dasm_put(Dst, 1894);
6435 }
6436 dasm_put(Dst, 1896);
6437 if (LJ_TARGET_OSX) {
6438 dasm_put(Dst, 1899);
6439 }
6440 dasm_put(Dst, 1901, -LJ_TISNUM);
6441 if (LJ_TARGET_OSX) {
6442 dasm_put(Dst, 1914);
6443 }
6444 dasm_put(Dst, 1916);
6445 if (LJ_TARGET_OSX) {
6446 dasm_put(Dst, 1919);
6447 }
6448 dasm_put(Dst, 1921, ~LJ_TISNUM, (2+1)*8, -LJ_TISNUM);
6449 if (LJ_TARGET_OSX) {
6450 dasm_put(Dst, 1943);
6451 }
6452 dasm_put(Dst, 1945);
6453 if (LJ_TARGET_OSX) {
6454 dasm_put(Dst, 1948);
6455 }
6456 dasm_put(Dst, 1950, (2+1)*8, -LJ_TISNUM, -LJ_TISNUM, -LJ_TISNUM);
6457 dasm_put(Dst, 2001, -LJ_TISNUM, -LJ_TISNUM);
6458 dasm_put(Dst, 2055, -LJ_TISNUM, -LJ_TSTR, Dt5(->len), ~LJ_TISNUM, -LJ_TSTR, Dt5(->len), Dt5([1]));
6459 dasm_put(Dst, 2109, ~LJ_TISNUM, (0+1)*8, (1+1)*8, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), -LJ_TISNUM, Dt1(->base), Dt1(->base), ~LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
6460 dasm_put(Dst, 2168, -LJ_TISNUM, -LJ_TSTR, Dt5(->len), -LJ_TISNUM, sizeof(GCstr)-1, -DISPATCH_GL(strempty), ~LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), -LJ_TSTR, -LJ_TISNUM, Dt5(->len));
6461 dasm_put(Dst, 2230, DISPATCH_GL(tmpbuf.sz), DISPATCH_GL(tmpbuf.buf), Dt5([1]), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), -LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), DISPATCH_GL(tmpbuf.buf), sizeof(GCstr));
6462 dasm_put(Dst, 2283, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), -LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), DISPATCH_GL(tmpbuf.buf), sizeof(GCstr), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
6463 dasm_put(Dst, 2343, -LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), DISPATCH_GL(tmpbuf.buf), sizeof(GCstr), -LJ_TTAB);
6464 if (LJ_TARGET_OSX) {
6465 dasm_put(Dst, 2381);
6466 }
6467 dasm_put(Dst, 2383);
6468 if (LJ_TARGET_OSX) {
6469 dasm_put(Dst, 2386);
6470 }
6471 dasm_put(Dst, 2388, ~LJ_TISNUM, -LJ_TISNUM, ~LJ_TISNUM, -LJ_TISNUM, -LJ_TISNUM);
6472 dasm_put(Dst, 2459, -LJ_TISNUM, -LJ_TISNUM, -LJ_TISNUM, -LJ_TISNUM, ~LJ_TISNUM);
6473 dasm_put(Dst, 2519, -LJ_TISNUM, ~LJ_TISNUM, -LJ_TISNUM, ~LJ_TISNUM, -LJ_TISNUM, -LJ_TISNUM, ~LJ_TISNUM, -LJ_TISNUM);
6474 dasm_put(Dst, 2575, -LJ_TISNUM, ~LJ_TISNUM, -LJ_TISNUM, -LJ_TISNUM, ~LJ_TISNUM, -LJ_TISNUM, -LJ_TISNUM, ~LJ_TISNUM);
6475 dasm_put(Dst, 2632, -LJ_TISNUM, -LJ_TISNUM, ~LJ_TISNUM, Dt1(->maxstack), Dt1(->top), Dt8(->f), Dt1(->base), 8*LUA_MINSTACK, Dt1(->base), Dt1(->top), Dt7(->field_pc), FRAME_TYPE, FRAME_TYPEP);
6476 dasm_put(Dst, 2695, LUA_MINSTACK, Dt1(->base), Dt1(->base), Dt1(->top), Dt1(->base));
6477#if LJ_HASJIT
6478 dasm_put(Dst, 2729, DISPATCH_GL(hookmask), HOOK_VMEVENT, DISPATCH_GL(hookcount), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount));
6479#endif
6480 dasm_put(Dst, 2749, DISPATCH_GL(hookmask), HOOK_ACTIVE, GG_DISP2STATIC, DISPATCH_GL(hookmask), DISPATCH_GL(hookcount), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount), LUA_MASKLINE, Dt1(->base), Dt1(->base));
6481 dasm_put(Dst, 2795, GG_DISP2STATIC);
6482#if LJ_HASJIT
6483 dasm_put(Dst, 2811, -GG_DISP2J, Dt7(->field_pc), DISPATCH_J(L), PC2PROTO(framesize), Dt1(->base), Dt1(->top));
6484#endif
6485 dasm_put(Dst, 2832);
6486#if LJ_HASJIT
6487 dasm_put(Dst, 2835);
6488#endif
6489 dasm_put(Dst, 2838);
6490#if LJ_HASJIT
6491 dasm_put(Dst, 2840);
6492#endif
6493 dasm_put(Dst, 2843, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
6494#if LJ_HASJIT
6495 dasm_put(Dst, 2866, LJ_VMST_EXIT, DISPATCH_GL(vmstate), DISPATCH_GL(jit_L), DISPATCH_GL(jit_base), DISPATCH_J(exitno), DISPATCH_J(L), Dt1(->base), DISPATCH_GL(jit_L), -GG_DISP2J, Dt1(->cframe), Dt1(->base), ~CFRAME_RAWMASK);
6496#endif
6497 dasm_put(Dst, 2914);
6498#if LJ_HASJIT
6499 dasm_put(Dst, 2916, Dt7(->field_pc), DISPATCH_GL(jit_L), LJ_VMST_INTERP, PC2PROTO(k), DISPATCH_GL(vmstate), BC_FUNCF);
6500#endif
6501 dasm_put(Dst, 2953);
6502#if LJ_HASJIT
6503 dasm_put(Dst, 3027);
6504#endif
6505 dasm_put(Dst, 3041);
6506 {
6507 int i;
6508 for (i = 31; i >= 0; i--) {
6509 dasm_put(Dst, 3077, i, i);
6510 }
6511 }
6512 dasm_put(Dst, 3082);
6513#if LJ_HASJIT
6514 dasm_put(Dst, 3111);
6515#else
6516 dasm_put(Dst, 3136);
6517#endif
6518 dasm_put(Dst, 3138);
6519#if LJ_HASFFI
6520#define DtE(_V) (int)(ptrdiff_t)&(((CTState *)0)_V)
6521 dasm_put(Dst, 3140, Dt2(->ctype_state), GG_G2DISP, DtE(->cb.gpr[0]), DtE(->cb.gpr[2]), CFRAME_SIZE, DtE(->cb.stack), DtE(->cb.slot), Dt1(->base), LJ_VMST_INTERP, Dt1(->top), DISPATCH_GL(vmstate), Dt7(->field_pc));
6522#endif
6523 dasm_put(Dst, 3183);
6524#if LJ_HASFFI
6525 dasm_put(Dst, 3185, DISPATCH_GL(ctype_state), Dt1(->base), Dt1(->top), DtE(->L), DtE(->cb.gpr[0]));
6526#endif
6527 dasm_put(Dst, 3202);
6528#if LJ_HASFFI
6529#define DtF(_V) (int)(ptrdiff_t)&(((CCallState *)0)_V)
6530 dasm_put(Dst, 3204, DtF(->spadj), DtF(->nsp), offsetof(CCallState, stack), DtF(->func), DtF(->gpr[0]), DtF(->gpr[1]), DtF(->gpr[2]), DtF(->gpr[3]), DtF(->gpr[0]), DtF(->gpr[1]));
6531#endif
6532}
6533
6534/* Generate the code for a single instruction. */
6535static void build_ins(BuildCtx *ctx, BCOp op, int defop)
6536{
6537 int vk = 0;
6538 dasm_put(Dst, 3242, defop);
6539
6540 switch (op) {
6541
6542 /* -- Comparison ops ---------------------------------------------------- */
6543
6544 /* Remember: all ops branch for a true comparison, fall through otherwise. */
6545
6546 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
6547 dasm_put(Dst, 3244, -LJ_TISNUM, -LJ_TISNUM);
6548 if (op == BC_ISLT) {
6549 dasm_put(Dst, 3260);
6550 } else if (op == BC_ISGE) {
6551 dasm_put(Dst, 3262);
6552 } else if (op == BC_ISLE) {
6553 dasm_put(Dst, 3264);
6554 } else {
6555 dasm_put(Dst, 3266);
6556 }
6557 dasm_put(Dst, 3268, -LJ_TISNUM);
6558 if (op == BC_ISLT) {
6559 dasm_put(Dst, 3304);
6560 } else if (op == BC_ISGE) {
6561 dasm_put(Dst, 3306);
6562 } else if (op == BC_ISLE) {
6563 dasm_put(Dst, 3308);
6564 } else {
6565 dasm_put(Dst, 3310);
6566 }
6567 dasm_put(Dst, 3312);
6568 break;
6569
6570 case BC_ISEQV: case BC_ISNEV:
6571 vk = op == BC_ISEQV;
6572 dasm_put(Dst, 3315, -LJ_TISNUM, -LJ_TISNUM);
6573 if (vk) {
6574 dasm_put(Dst, 3326);
6575 } else {
6576 dasm_put(Dst, 3329);
6577 }
6578 if (LJ_HASFFI) {
6579 dasm_put(Dst, 3332, -LJ_TCDATA, -LJ_TCDATA);
6580 }
6581 dasm_put(Dst, 3339, -LJ_TISPRI);
6582 if (vk) {
6583 dasm_put(Dst, 3348, -LJ_TISTABUD);
6584 } else {
6585 dasm_put(Dst, 3365, -LJ_TISTABUD);
6586 }
6587 dasm_put(Dst, 3372, Dt6(->metatable));
6588 if (vk) {
6589 dasm_put(Dst, 3376);
6590 } else {
6591 dasm_put(Dst, 3379);
6592 }
6593 dasm_put(Dst, 3382, Dt6(->nomm), 1-vk, 1<<MM_eq);
6594 if (vk) {
6595 dasm_put(Dst, 3392);
6596 } else {
6597 dasm_put(Dst, 3395);
6598 }
6599 break;
6600
6601 case BC_ISEQS: case BC_ISNES:
6602 vk = op == BC_ISEQS;
6603 dasm_put(Dst, 3405, -LJ_TSTR);
6604 if (LJ_HASFFI) {
6605 dasm_put(Dst, 3414);
6606 } else {
6607 dasm_put(Dst, 3418);
6608 }
6609 if (vk) {
6610 dasm_put(Dst, 3420);
6611 } else {
6612 dasm_put(Dst, 3423);
6613 }
6614 dasm_put(Dst, 3426);
6615 if (LJ_HASFFI) {
6616 dasm_put(Dst, 3433, -LJ_TCDATA);
6617 }
6618 break;
6619
6620 case BC_ISEQN: case BC_ISNEN:
6621 vk = op == BC_ISEQN;
6622 dasm_put(Dst, 3441);
6623 if (vk) {
6624 dasm_put(Dst, 3448);
6625 } else {
6626 dasm_put(Dst, 3450);
6627 }
6628 dasm_put(Dst, 3452, -LJ_TISNUM, -LJ_TISNUM);
6629 if (vk) {
6630 dasm_put(Dst, 3462);
6631 } else {
6632 dasm_put(Dst, 3465);
6633 }
6634 dasm_put(Dst, 3468);
6635 if (LJ_HASFFI) {
6636 dasm_put(Dst, 3477);
6637 } else {
6638 if (!vk) {
6639 dasm_put(Dst, 3480);
6640 }
6641 dasm_put(Dst, 3482);
6642 }
6643 dasm_put(Dst, 3485, -LJ_TISNUM);
6644 if (vk) {
6645 dasm_put(Dst, 3501);
6646 } else {
6647 dasm_put(Dst, 3503);
6648 }
6649 dasm_put(Dst, 3505);
6650 if (LJ_HASFFI) {
6651 dasm_put(Dst, 3508, -LJ_TCDATA);
6652 }
6653 break;
6654
6655 case BC_ISEQP: case BC_ISNEP:
6656 vk = op == BC_ISEQP;
6657 dasm_put(Dst, 3516);
6658 if (LJ_HASFFI) {
6659 dasm_put(Dst, 3522, -LJ_TCDATA);
6660 }
6661 dasm_put(Dst, 3527);
6662 if (vk) {
6663 dasm_put(Dst, 3529);
6664 } else {
6665 dasm_put(Dst, 3531);
6666 }
6667 dasm_put(Dst, 3533);
6668 break;
6669
6670 /* -- Unary test and copy ops ------------------------------------------- */
6671
6672 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
6673 dasm_put(Dst, 3540, -LJ_TTRUE);
6674 if (op == BC_ISTC || op == BC_IST) {
6675 dasm_put(Dst, 3548);
6676 if (op == BC_ISTC) {
6677 dasm_put(Dst, 3550);
6678 }
6679 } else {
6680 dasm_put(Dst, 3552);
6681 if (op == BC_ISFC) {
6682 dasm_put(Dst, 3554);
6683 }
6684 }
6685 dasm_put(Dst, 3556);
6686 break;
6687
6688 /* -- Unary ops --------------------------------------------------------- */
6689
6690 case BC_MOV:
6691 dasm_put(Dst, 3563);
6692 break;
6693 case BC_NOT:
6694 dasm_put(Dst, 3573, -LJ_TTRUE, ~LJ_TFALSE, ~LJ_TTRUE);
6695 break;
6696 case BC_UNM:
6697 dasm_put(Dst, 3590, -LJ_TISNUM);
6698 break;
6699 case BC_LEN:
6700 dasm_put(Dst, 3616, -LJ_TSTR, Dt5(->len), ~LJ_TISNUM, -LJ_TTAB);
6701#ifdef LUAJIT_ENABLE_LUA52COMPAT
6702 dasm_put(Dst, 3640, Dt6(->metatable));
6703#endif
6704 dasm_put(Dst, 3647);
6705 if (LJ_TARGET_OSX) {
6706 dasm_put(Dst, 3649);
6707 }
6708 dasm_put(Dst, 3651);
6709 if (LJ_TARGET_OSX) {
6710 dasm_put(Dst, 3654);
6711 }
6712 dasm_put(Dst, 3656);
6713#ifdef LUAJIT_ENABLE_LUA52COMPAT
6714 dasm_put(Dst, 3659, Dt6(->nomm), 1<<MM_len);
6715#endif
6716 break;
6717
6718 /* -- Binary ops -------------------------------------------------------- */
6719
6720
6721 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
6722 dasm_put(Dst, 3669);
6723 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
6724 switch (vk) {
6725 case 0:
6726 dasm_put(Dst, 3672);
6727 break;
6728 case 1:
6729 dasm_put(Dst, 3675);
6730 break;
6731 default:
6732 dasm_put(Dst, 3678);
6733 break;
6734 }
6735 dasm_put(Dst, 3681);
6736 if (vk == 1) {
6737 dasm_put(Dst, 3683, -LJ_TISNUM, -LJ_TISNUM);
6738 } else {
6739 dasm_put(Dst, 3688, -LJ_TISNUM, -LJ_TISNUM);
6740 }
6741 dasm_put(Dst, 3693);
6742 switch (vk) {
6743 case 0:
6744 dasm_put(Dst, 3697);
6745 break;
6746 case 1:
6747 dasm_put(Dst, 3700);
6748 break;
6749 default:
6750 dasm_put(Dst, 3703);
6751 break;
6752 }
6753 dasm_put(Dst, 3706);
6754 switch (vk) {
6755 case 0:
6756 if (vk == 1) {
6757 dasm_put(Dst, 3715, -LJ_TISNUM, -LJ_TISNUM);
6758 } else {
6759 dasm_put(Dst, 3720, -LJ_TISNUM, -LJ_TISNUM);
6760 }
6761 dasm_put(Dst, 3725);
6762 break;
6763 case 1:
6764 if (vk == 1) {
6765 dasm_put(Dst, 3728, -LJ_TISNUM, -LJ_TISNUM);
6766 } else {
6767 dasm_put(Dst, 3733, -LJ_TISNUM, -LJ_TISNUM);
6768 }
6769 dasm_put(Dst, 3738);
6770 break;
6771 default:
6772 if (vk == 1) {
6773 dasm_put(Dst, 3741, -LJ_TISNUM, -LJ_TISNUM);
6774 } else {
6775 dasm_put(Dst, 3746, -LJ_TISNUM, -LJ_TISNUM);
6776 }
6777 dasm_put(Dst, 3751);
6778 break;
6779 }
6780 dasm_put(Dst, 3754);
6781 break;
6782 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
6783 dasm_put(Dst, 3760);
6784 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
6785 switch (vk) {
6786 case 0:
6787 dasm_put(Dst, 3763);
6788 break;
6789 case 1:
6790 dasm_put(Dst, 3766);
6791 break;
6792 default:
6793 dasm_put(Dst, 3769);
6794 break;
6795 }
6796 dasm_put(Dst, 3772);
6797 if (vk == 1) {
6798 dasm_put(Dst, 3774, -LJ_TISNUM, -LJ_TISNUM);
6799 } else {
6800 dasm_put(Dst, 3779, -LJ_TISNUM, -LJ_TISNUM);
6801 }
6802 dasm_put(Dst, 3784);
6803 switch (vk) {
6804 case 0:
6805 dasm_put(Dst, 3788);
6806 break;
6807 case 1:
6808 dasm_put(Dst, 3791);
6809 break;
6810 default:
6811 dasm_put(Dst, 3794);
6812 break;
6813 }
6814 dasm_put(Dst, 3797);
6815 switch (vk) {
6816 case 0:
6817 if (vk == 1) {
6818 dasm_put(Dst, 3806, -LJ_TISNUM, -LJ_TISNUM);
6819 } else {
6820 dasm_put(Dst, 3811, -LJ_TISNUM, -LJ_TISNUM);
6821 }
6822 dasm_put(Dst, 3816);
6823 break;
6824 case 1:
6825 if (vk == 1) {
6826 dasm_put(Dst, 3819, -LJ_TISNUM, -LJ_TISNUM);
6827 } else {
6828 dasm_put(Dst, 3824, -LJ_TISNUM, -LJ_TISNUM);
6829 }
6830 dasm_put(Dst, 3829);
6831 break;
6832 default:
6833 if (vk == 1) {
6834 dasm_put(Dst, 3832, -LJ_TISNUM, -LJ_TISNUM);
6835 } else {
6836 dasm_put(Dst, 3837, -LJ_TISNUM, -LJ_TISNUM);
6837 }
6838 dasm_put(Dst, 3842);
6839 break;
6840 }
6841 dasm_put(Dst, 3845);
6842 break;
6843 case BC_MULVN: case BC_MULNV: case BC_MULVV:
6844 dasm_put(Dst, 3851);
6845 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
6846 switch (vk) {
6847 case 0:
6848 dasm_put(Dst, 3854);
6849 break;
6850 case 1:
6851 dasm_put(Dst, 3857);
6852 break;
6853 default:
6854 dasm_put(Dst, 3860);
6855 break;
6856 }
6857 dasm_put(Dst, 3863);
6858 if (vk == 1) {
6859 dasm_put(Dst, 3865, -LJ_TISNUM, -LJ_TISNUM);
6860 } else {
6861 dasm_put(Dst, 3870, -LJ_TISNUM, -LJ_TISNUM);
6862 }
6863 dasm_put(Dst, 3875);
6864 switch (vk) {
6865 case 0:
6866 dasm_put(Dst, 3880);
6867 break;
6868 case 1:
6869 dasm_put(Dst, 3883);
6870 break;
6871 default:
6872 dasm_put(Dst, 3886);
6873 break;
6874 }
6875 dasm_put(Dst, 3889);
6876 switch (vk) {
6877 case 0:
6878 if (vk == 1) {
6879 dasm_put(Dst, 3898, -LJ_TISNUM, -LJ_TISNUM);
6880 } else {
6881 dasm_put(Dst, 3903, -LJ_TISNUM, -LJ_TISNUM);
6882 }
6883 dasm_put(Dst, 3908);
6884 break;
6885 case 1:
6886 if (vk == 1) {
6887 dasm_put(Dst, 3911, -LJ_TISNUM, -LJ_TISNUM);
6888 } else {
6889 dasm_put(Dst, 3916, -LJ_TISNUM, -LJ_TISNUM);
6890 }
6891 dasm_put(Dst, 3921);
6892 break;
6893 default:
6894 if (vk == 1) {
6895 dasm_put(Dst, 3924, -LJ_TISNUM, -LJ_TISNUM);
6896 } else {
6897 dasm_put(Dst, 3929, -LJ_TISNUM, -LJ_TISNUM);
6898 }
6899 dasm_put(Dst, 3934);
6900 break;
6901 }
6902 dasm_put(Dst, 3937);
6903 break;
6904 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
6905 dasm_put(Dst, 3943);
6906 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
6907 switch (vk) {
6908 case 0:
6909 dasm_put(Dst, 3946);
6910 break;
6911 case 1:
6912 dasm_put(Dst, 3949);
6913 break;
6914 default:
6915 dasm_put(Dst, 3952);
6916 break;
6917 }
6918 switch (vk) {
6919 case 0:
6920 if (vk == 1) {
6921 dasm_put(Dst, 3955, -LJ_TISNUM, -LJ_TISNUM);
6922 } else {
6923 dasm_put(Dst, 3960, -LJ_TISNUM, -LJ_TISNUM);
6924 }
6925 dasm_put(Dst, 3965);
6926 break;
6927 case 1:
6928 if (vk == 1) {
6929 dasm_put(Dst, 3968, -LJ_TISNUM, -LJ_TISNUM);
6930 } else {
6931 dasm_put(Dst, 3973, -LJ_TISNUM, -LJ_TISNUM);
6932 }
6933 dasm_put(Dst, 3978);
6934 break;
6935 default:
6936 if (vk == 1) {
6937 dasm_put(Dst, 3981, -LJ_TISNUM, -LJ_TISNUM);
6938 } else {
6939 dasm_put(Dst, 3986, -LJ_TISNUM, -LJ_TISNUM);
6940 }
6941 dasm_put(Dst, 3991);
6942 break;
6943 }
6944 dasm_put(Dst, 3994);
6945 break;
6946 case BC_MODVN: case BC_MODNV: case BC_MODVV:
6947 dasm_put(Dst, 4004);
6948 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
6949 switch (vk) {
6950 case 0:
6951 dasm_put(Dst, 4007);
6952 break;
6953 case 1:
6954 dasm_put(Dst, 4010);
6955 break;
6956 default:
6957 dasm_put(Dst, 4013);
6958 break;
6959 }
6960 if (vk == 1) {
6961 dasm_put(Dst, 4016, -LJ_TISNUM, -LJ_TISNUM);
6962 } else {
6963 dasm_put(Dst, 4021, -LJ_TISNUM, -LJ_TISNUM);
6964 }
6965 dasm_put(Dst, 4026);
6966 switch (vk) {
6967 case 0:
6968 dasm_put(Dst, 4030);
6969 break;
6970 case 1:
6971 dasm_put(Dst, 4033);
6972 break;
6973 default:
6974 dasm_put(Dst, 4036);
6975 break;
6976 }
6977 dasm_put(Dst, 4039, ~LJ_TISNUM);
6978 switch (vk) {
6979 case 0:
6980 if (vk == 1) {
6981 dasm_put(Dst, 4053, -LJ_TISNUM, -LJ_TISNUM);
6982 } else {
6983 dasm_put(Dst, 4058, -LJ_TISNUM, -LJ_TISNUM);
6984 }
6985 dasm_put(Dst, 4063);
6986 break;
6987 case 1:
6988 if (vk == 1) {
6989 dasm_put(Dst, 4066, -LJ_TISNUM, -LJ_TISNUM);
6990 } else {
6991 dasm_put(Dst, 4071, -LJ_TISNUM, -LJ_TISNUM);
6992 }
6993 dasm_put(Dst, 4076);
6994 break;
6995 default:
6996 if (vk == 1) {
6997 dasm_put(Dst, 4079, -LJ_TISNUM, -LJ_TISNUM);
6998 } else {
6999 dasm_put(Dst, 4084, -LJ_TISNUM, -LJ_TISNUM);
7000 }
7001 dasm_put(Dst, 4089);
7002 break;
7003 }
7004 dasm_put(Dst, 4092);
7005 break;
7006 case BC_POW:
7007 dasm_put(Dst, 4097);
7008 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
7009 switch (vk) {
7010 case 0:
7011 dasm_put(Dst, 4100);
7012 break;
7013 case 1:
7014 dasm_put(Dst, 4103);
7015 break;
7016 default:
7017 dasm_put(Dst, 4106);
7018 break;
7019 }
7020 switch (vk) {
7021 case 0:
7022 if (vk == 1) {
7023 dasm_put(Dst, 4109, -LJ_TISNUM, -LJ_TISNUM);
7024 } else {
7025 dasm_put(Dst, 4114, -LJ_TISNUM, -LJ_TISNUM);
7026 }
7027 dasm_put(Dst, 4119);
7028 break;
7029 case 1:
7030 if (vk == 1) {
7031 dasm_put(Dst, 4122, -LJ_TISNUM, -LJ_TISNUM);
7032 } else {
7033 dasm_put(Dst, 4127, -LJ_TISNUM, -LJ_TISNUM);
7034 }
7035 dasm_put(Dst, 4132);
7036 break;
7037 default:
7038 if (vk == 1) {
7039 dasm_put(Dst, 4135, -LJ_TISNUM, -LJ_TISNUM);
7040 } else {
7041 dasm_put(Dst, 4140, -LJ_TISNUM, -LJ_TISNUM);
7042 }
7043 dasm_put(Dst, 4145);
7044 break;
7045 }
7046 if (LJ_TARGET_OSX) {
7047 dasm_put(Dst, 4148);
7048 }
7049 dasm_put(Dst, 4150);
7050 if (LJ_TARGET_OSX) {
7051 dasm_put(Dst, 4153);
7052 }
7053 dasm_put(Dst, 4155);
7054 break;
7055
7056 case BC_CAT:
7057 dasm_put(Dst, 4163, Dt1(->base), Dt1(->base));
7058 break;
7059
7060 /* -- Constant ops ------------------------------------------------------ */
7061
7062 case BC_KSTR:
7063 dasm_put(Dst, 4189, ~LJ_TSTR);
7064 break;
7065 case BC_KCDATA:
7066#if LJ_HASFFI
7067 dasm_put(Dst, 4201, ~LJ_TCDATA);
7068#endif
7069 break;
7070 case BC_KSHORT:
7071 dasm_put(Dst, 4213, ~LJ_TISNUM);
7072 break;
7073 case BC_KNUM:
7074 dasm_put(Dst, 4224);
7075 break;
7076 case BC_KPRI:
7077 dasm_put(Dst, 4234);
7078 break;
7079 case BC_KNIL:
7080 dasm_put(Dst, 4244, ~LJ_TNIL);
7081 break;
7082
7083 /* -- Upvalue and function ops ------------------------------------------ */
7084
7085 case BC_UGET:
7086 dasm_put(Dst, 4263, offsetof(GCfuncL, uvptr), DtA(->v));
7087 break;
7088 case BC_USETV:
7089 dasm_put(Dst, 4279, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->closed), DtA(->v), LJ_GC_BLACK, -LJ_TISGCV, -(LJ_TISNUM - LJ_TISGCV), Dt4(->gch.marked), -GG_DISP2G, LJ_GC_WHITES);
7090 if (LJ_TARGET_OSX) {
7091 dasm_put(Dst, 4319);
7092 } else {
7093 dasm_put(Dst, 4326);
7094 }
7095 dasm_put(Dst, 4329);
7096 break;
7097 case BC_USETS:
7098 dasm_put(Dst, 4332, offsetof(GCfuncL, uvptr), ~LJ_TSTR, DtA(->marked), DtA(->v), DtA(->closed), LJ_GC_BLACK, Dt5(->marked), LJ_GC_WHITES, -GG_DISP2G);
7099 if (LJ_TARGET_OSX) {
7100 dasm_put(Dst, 4368);
7101 } else {
7102 dasm_put(Dst, 4375);
7103 }
7104 dasm_put(Dst, 4378);
7105 break;
7106 case BC_USETN:
7107 dasm_put(Dst, 4381, offsetof(GCfuncL, uvptr), DtA(->v));
7108 break;
7109 case BC_USETP:
7110 dasm_put(Dst, 4398, offsetof(GCfuncL, uvptr), DtA(->v));
7111 break;
7112
7113 case BC_UCLO:
7114 dasm_put(Dst, 4414, Dt1(->openupval), Dt1(->base), Dt1(->base));
7115 break;
7116
7117 case BC_FNEW:
7118 dasm_put(Dst, 4437, Dt1(->base), Dt1(->base), ~LJ_TFUNC);
7119 break;
7120
7121 /* -- Table ops --------------------------------------------------------- */
7122
7123 case BC_TNEW:
7124 case BC_TDUP:
7125 if (op == BC_TDUP) {
7126 dasm_put(Dst, 4458);
7127 }
7128 dasm_put(Dst, 4460, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base));
7129 if (op == BC_TNEW) {
7130 dasm_put(Dst, 4473);
7131 } else {
7132 dasm_put(Dst, 4482);
7133 }
7134 dasm_put(Dst, 4486, Dt1(->base), ~LJ_TTAB);
7135 break;
7136
7137 case BC_GGET:
7138 case BC_GSET:
7139 dasm_put(Dst, 4504, Dt7(->env));
7140 if (op == BC_GGET) {
7141 dasm_put(Dst, 4510);
7142 } else {
7143 dasm_put(Dst, 4513);
7144 }
7145 break;
7146
7147 case BC_TGETV:
7148 dasm_put(Dst, 4516, -LJ_TTAB, -LJ_TISNUM, Dt6(->array), Dt6(->asize), -LJ_TNIL, Dt6(->metatable), Dt6(->nomm), 1<<MM_index, -LJ_TSTR);
7149 break;
7150 case BC_TGETS:
7151 dasm_put(Dst, 4573, -LJ_TTAB, Dt6(->hmask), Dt5(->hash), Dt6(->node), DtB(->key), DtB(->val), DtB(->next), -LJ_TSTR, -LJ_TNIL, Dt6(->metatable), ~LJ_TNIL, Dt6(->nomm));
7152 dasm_put(Dst, 4633, 1<<MM_index);
7153 break;
7154 case BC_TGETB:
7155 dasm_put(Dst, 4640, -LJ_TTAB, Dt6(->asize), Dt6(->array), -LJ_TNIL, Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
7156 break;
7157
7158 case BC_TSETV:
7159 dasm_put(Dst, 4683, -LJ_TTAB, -LJ_TISNUM, Dt6(->array), Dt6(->asize), -LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex);
7160 dasm_put(Dst, 4743, DISPATCH_GL(gc.grayagain), LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist), -LJ_TSTR);
7161 break;
7162 case BC_TSETS:
7163 dasm_put(Dst, 4764, -LJ_TTAB, Dt6(->hmask), Dt5(->hash), Dt6(->node), Dt6(->nomm), DtB(->key), DtB(->val.it), DtB(->next), -LJ_TSTR, Dt6(->marked), -LJ_TNIL, LJ_GC_BLACK, DtB(->val));
7164 dasm_put(Dst, 4822, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, Dt6(->metatable), Dt1(->base), Dt6(->nomm), 1<<MM_newindex, ~LJ_TSTR, Dt1(->base), DISPATCH_GL(gc.grayagain), LJ_GC_BLACK);
7165 dasm_put(Dst, 4875, DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
7166 break;
7167 case BC_TSETB:
7168 dasm_put(Dst, 4884, -LJ_TTAB, Dt6(->asize), Dt6(->array), -LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DISPATCH_GL(gc.grayagain), LJ_GC_BLACK);
7169 dasm_put(Dst, 4942, DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
7170 break;
7171
7172 case BC_TSETM:
7173 dasm_put(Dst, 4951, Dt6(->asize), Dt6(->array), Dt6(->marked), LJ_GC_BLACK, Dt1(->base));
7174 if (LJ_TARGET_OSX) {
7175 dasm_put(Dst, 4996, Dt1(->base));
7176 }
7177 dasm_put(Dst, 4999, DISPATCH_GL(gc.grayagain), LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
7178 break;
7179
7180 /* -- Calls and vararg handling ----------------------------------------- */
7181
7182 case BC_CALLM:
7183 dasm_put(Dst, 5015);
7184 break;
7185 case BC_CALL:
7186 dasm_put(Dst, 5021, -LJ_TFUNC, Dt7(->field_pc));
7187 break;
7188
7189 case BC_CALLMT:
7190 dasm_put(Dst, 5041);
7191 break;
7192 case BC_CALLT:
7193 dasm_put(Dst, 5046, -LJ_TFUNC, Dt7(->ffid), FRAME_TYPE, Dt7(->field_pc), Dt7(->field_pc), PC2PROTO(k), FRAME_VARG, FRAME_TYPEP);
7194 dasm_put(Dst, 5107, FRAME_TYPE);
7195 break;
7196
7197 case BC_ITERC:
7198 dasm_put(Dst, 5118, -LJ_TFUNC, Dt7(->field_pc));
7199 break;
7200
7201 case BC_ITERN:
7202#if LJ_HASJIT
7203#endif
7204 dasm_put(Dst, 5142, Dt6(->asize), Dt6(->array), -LJ_TNIL, ~LJ_TISNUM, Dt6(->hmask), Dt6(->node), DtB(->val), -LJ_TNIL, DtB(->key));
7205 break;
7206
7207 case BC_ISNEXT:
7208 dasm_put(Dst, 5207, -LJ_TFUNC, Dt8(->ffid), -LJ_TTAB, -LJ_TNIL, FF_next_N, BC_JMP, BC_ITERC);
7209 break;
7210
7211 case BC_VARG:
7212 dasm_put(Dst, 5246, FRAME_VARG, ~LJ_TNIL, Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->base));
7213 break;
7214
7215 /* -- Returns ----------------------------------------------------------- */
7216
7217 case BC_RETM:
7218 dasm_put(Dst, 5318);
7219 break;
7220
7221 case BC_RET:
7222 dasm_put(Dst, 5325, FRAME_TYPE, FRAME_VARG, Dt7(->field_pc), PC2PROTO(k), ~LJ_TNIL, FRAME_TYPEP);
7223 break;
7224
7225 case BC_RET0: case BC_RET1:
7226 dasm_put(Dst, 5390, FRAME_TYPE, FRAME_VARG);
7227 if (op == BC_RET1) {
7228 dasm_put(Dst, 5401);
7229 }
7230 dasm_put(Dst, 5403);
7231 if (op == BC_RET1) {
7232 dasm_put(Dst, 5406);
7233 }
7234 dasm_put(Dst, 5408, Dt7(->field_pc), PC2PROTO(k), ~LJ_TNIL);
7235 break;
7236
7237 /* -- Loops and branches ------------------------------------------------ */
7238
7239
7240 case BC_FORL:
7241#if LJ_HASJIT
7242 dasm_put(Dst, 5434, -GG_DISP2HOT, HOTCOUNT_LOOP);
7243#endif
7244 break;
7245
7246 case BC_JFORI:
7247 case BC_JFORL:
7248#if !LJ_HASJIT
7249 break;
7250#endif
7251 case BC_FORI:
7252 case BC_IFORL:
7253 vk = (op == BC_IFORL || op == BC_JFORL);
7254 dasm_put(Dst, 5445);
7255 if (op != BC_JFORL) {
7256 dasm_put(Dst, 5447);
7257 }
7258 if (!vk) {
7259 dasm_put(Dst, 5449, -LJ_TISNUM, -LJ_TISNUM, -LJ_TISNUM);
7260 } else {
7261 dasm_put(Dst, 5467, -LJ_TISNUM);
7262 if (op == BC_IFORL) {
7263 dasm_put(Dst, 5475);
7264 } else {
7265 dasm_put(Dst, 5477);
7266 }
7267 dasm_put(Dst, 5480);
7268 }
7269 dasm_put(Dst, 5485);
7270 if (op == BC_FORI) {
7271 dasm_put(Dst, 5487);
7272 } else if (op == BC_JFORI) {
7273 dasm_put(Dst, 5489);
7274 } else if (op == BC_IFORL) {
7275 dasm_put(Dst, 5492);
7276 }
7277 if (vk) {
7278 dasm_put(Dst, 5494);
7279 }
7280 dasm_put(Dst, 5496);
7281 if (op == BC_JFORI || op == BC_JFORL) {
7282 dasm_put(Dst, 5501, BC_JLOOP);
7283 }
7284 dasm_put(Dst, 5504);
7285 if (!vk) {
7286 dasm_put(Dst, 5511);
7287 } else {
7288 dasm_put(Dst, 5513);
7289 }
7290 dasm_put(Dst, 5515);
7291 if (!vk) {
7292 dasm_put(Dst, 5519, -LJ_TISNUM, -LJ_TISNUM);
7293 } else {
7294 dasm_put(Dst, 5531);
7295 }
7296 dasm_put(Dst, 5540);
7297 if (op == BC_FORI) {
7298 dasm_put(Dst, 5544);
7299 } else if (op == BC_JFORI) {
7300 dasm_put(Dst, 5546, BC_JLOOP);
7301 } else if (op == BC_IFORL) {
7302 dasm_put(Dst, 5551);
7303 } else {
7304 dasm_put(Dst, 5553, BC_JLOOP);
7305 }
7306 dasm_put(Dst, 5556);
7307 if (vk) {
7308 dasm_put(Dst, 5562);
7309 }
7310 dasm_put(Dst, 5567);
7311 break;
7312
7313 case BC_ITERL:
7314#if LJ_HASJIT
7315 dasm_put(Dst, 5573, -GG_DISP2HOT, HOTCOUNT_LOOP);
7316#endif
7317 break;
7318
7319 case BC_JITERL:
7320#if !LJ_HASJIT
7321 break;
7322#endif
7323 case BC_IITERL:
7324 dasm_put(Dst, 5584);
7325 if (op == BC_JITERL) {
7326 dasm_put(Dst, 5586, -LJ_TNIL, BC_JLOOP);
7327 } else {
7328 dasm_put(Dst, 5592, -LJ_TNIL);
7329 }
7330 dasm_put(Dst, 5598);
7331 break;
7332
7333 case BC_LOOP:
7334#if LJ_HASJIT
7335 dasm_put(Dst, 5605, -GG_DISP2HOT, HOTCOUNT_LOOP);
7336#endif
7337 break;
7338
7339 case BC_ILOOP:
7340 dasm_put(Dst, 5616);
7341 break;
7342
7343 case BC_JLOOP:
7344#if LJ_HASJIT
7345 dasm_put(Dst, 5623, DISPATCH_J(trace), DISPATCH_GL(vmstate), DtD(->mcode), DISPATCH_GL(jit_base), DISPATCH_GL(jit_L));
7346#endif
7347 break;
7348
7349 case BC_JMP:
7350 dasm_put(Dst, 5637);
7351 break;
7352
7353 /* -- Function headers -------------------------------------------------- */
7354
7355 case BC_FUNCF:
7356#if LJ_HASJIT
7357 dasm_put(Dst, 5646, -GG_DISP2HOT, HOTCOUNT_CALL);
7358#endif
7359 case BC_FUNCV: /* NYI: compiled vararg functions. */
7360 break;
7361
7362 case BC_JFUNCF:
7363#if !LJ_HASJIT
7364 break;
7365#endif
7366 case BC_IFUNCF:
7367 dasm_put(Dst, 5657, Dt1(->maxstack), -4+PC2PROTO(numparams), -4+PC2PROTO(k));
7368 if (op != BC_JFUNCF) {
7369 dasm_put(Dst, 5667);
7370 }
7371 dasm_put(Dst, 5670, ~LJ_TNIL);
7372 if (op == BC_JFUNCF) {
7373 dasm_put(Dst, 5677, BC_JLOOP);
7374 } else {
7375 dasm_put(Dst, 5681);
7376 }
7377 dasm_put(Dst, 5686);
7378 break;
7379
7380 case BC_JFUNCV:
7381#if !LJ_HASJIT
7382 break;
7383#endif
7384 dasm_put(Dst, 5692);
7385 break; /* NYI: compiled vararg functions. */
7386
7387 case BC_IFUNCV:
7388 dasm_put(Dst, 5694, Dt1(->maxstack), 8+FRAME_VARG, -4+PC2PROTO(k), -4+PC2PROTO(numparams), ~LJ_TNIL);
7389 break;
7390
7391 case BC_FUNCC:
7392 case BC_FUNCCW:
7393 if (op == BC_FUNCC) {
7394 dasm_put(Dst, 5735, Dt8(->f));
7395 } else {
7396 dasm_put(Dst, 5738, DISPATCH_GL(wrapf));
7397 }
7398 dasm_put(Dst, 5741, Dt1(->maxstack), Dt1(->base), Dt1(->top));
7399 if (op == BC_FUNCCW) {
7400 dasm_put(Dst, 5751, Dt8(->f));
7401 }
7402 dasm_put(Dst, 5754, LJ_VMST_C, DISPATCH_GL(vmstate), Dt1(->base), LJ_VMST_INTERP, Dt1(->top), DISPATCH_GL(vmstate));
7403 break;
7404
7405 /* ---------------------------------------------------------------------- */
7406
7407 default:
7408 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
7409 exit(2);
7410 break;
7411 }
7412}
7413
7414static int build_backend(BuildCtx *ctx)
7415{
7416 int op;
7417
7418 dasm_growpc(Dst, BC__MAX);
7419
7420 build_subroutines(ctx);
7421
7422 dasm_put(Dst, 5776);
7423 for (op = 0; op < BC__MAX; op++)
7424 build_ins(ctx, (BCOp)op, op);
7425
7426 return BC__MAX;
7427}
7428
7429/* Emit pseudo frame-info for all assembler functions. */
7430static void emit_asm_debug(BuildCtx *ctx)
7431{
7432 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
7433 int i;
7434 switch (ctx->mode) {
7435 case BUILD_elfasm:
7436 fprintf(ctx->fp, "\t.section .debug_frame,\"\",%%progbits\n");
7437 fprintf(ctx->fp,
7438 ".Lframe0:\n"
7439 "\t.long .LECIE0-.LSCIE0\n"
7440 ".LSCIE0:\n"
7441 "\t.long 0xffffffff\n"
7442 "\t.byte 0x1\n"
7443 "\t.string \"\"\n"
7444 "\t.uleb128 0x1\n"
7445 "\t.sleb128 -4\n"
7446 "\t.byte 0xe\n" /* Return address is in lr. */
7447 "\t.byte 0xc\n\t.uleb128 0xd\n\t.uleb128 0\n" /* def_cfa sp */
7448 "\t.align 2\n"
7449 ".LECIE0:\n\n");
7450 fprintf(ctx->fp,
7451 ".LSFDE0:\n"
7452 "\t.long .LEFDE0-.LASFDE0\n"
7453 ".LASFDE0:\n"
7454 "\t.long .Lframe0\n"
7455 "\t.long .Lbegin\n"
7456 "\t.long %d\n"
7457 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
7458 "\t.byte 0x8e\n\t.uleb128 1\n", /* offset lr */
7459 fcofs, CFRAME_SIZE);
7460 for (i = 11; i >= 4; i--) /* offset r4-r11 */
7461 fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 2+(11-i));
7462 fprintf(ctx->fp,
7463 "\t.align 2\n"
7464 ".LEFDE0:\n\n");
7465#if LJ_HASFFI
7466 fprintf(ctx->fp,
7467 ".LSFDE1:\n"
7468 "\t.long .LEFDE1-.LASFDE1\n"
7469 ".LASFDE1:\n"
7470 "\t.long .Lframe0\n"
7471 "\t.long lj_vm_ffi_call\n"
7472 "\t.long %d\n"
7473 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
7474 "\t.byte 0x8e\n\t.uleb128 1\n" /* offset lr */
7475 "\t.byte 0x8b\n\t.uleb128 2\n" /* offset r11 */
7476 "\t.byte 0x85\n\t.uleb128 3\n" /* offset r5 */
7477 "\t.byte 0x84\n\t.uleb128 4\n" /* offset r4 */
7478 "\t.byte 0xd\n\t.uleb128 0xb\n" /* def_cfa_register r11 */
7479 "\t.align 2\n"
7480 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
7481#endif
7482 break;
7483 default:
7484 break;
7485 }
7486}
7487
diff --git a/libraries/luajit-2.0/src/buildvm_asm.c b/libraries/luajit-2.0/src/buildvm_asm.c
new file mode 100644
index 0000000..236dd17
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_asm.c
@@ -0,0 +1,277 @@
1/*
2** LuaJIT VM builder: Assembler source code emitter.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "buildvm.h"
7#include "lj_bc.h"
8
9/* ------------------------------------------------------------------------ */
10
11#if LJ_TARGET_X86ORX64
12/* Emit bytes piecewise as assembler text. */
13static void emit_asm_bytes(BuildCtx *ctx, uint8_t *p, int n)
14{
15 int i;
16 for (i = 0; i < n; i++) {
17 if ((i & 15) == 0)
18 fprintf(ctx->fp, "\t.byte %d", p[i]);
19 else
20 fprintf(ctx->fp, ",%d", p[i]);
21 if ((i & 15) == 15) putc('\n', ctx->fp);
22 }
23 if ((n & 15) != 0) putc('\n', ctx->fp);
24}
25
26/* Emit relocation */
27static void emit_asm_reloc(BuildCtx *ctx, int type, const char *sym)
28{
29 switch (ctx->mode) {
30 case BUILD_elfasm:
31 if (type)
32 fprintf(ctx->fp, "\t.long %s-.-4\n", sym);
33 else
34 fprintf(ctx->fp, "\t.long %s\n", sym);
35 break;
36 case BUILD_coffasm:
37 fprintf(ctx->fp, "\t.def %s; .scl 3; .type 32; .endef\n", sym);
38 if (type)
39 fprintf(ctx->fp, "\t.long %s-.-4\n", sym);
40 else
41 fprintf(ctx->fp, "\t.long %s\n", sym);
42 break;
43 default: /* BUILD_machasm for relative relocations handled below. */
44 fprintf(ctx->fp, "\t.long %s\n", sym);
45 break;
46 }
47}
48
49static const char *const jccnames[] = {
50 "jo", "jno", "jb", "jnb", "jz", "jnz", "jbe", "ja",
51 "js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg"
52};
53
54/* Emit relocation for the incredibly stupid OSX assembler. */
55static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n,
56 const char *sym)
57{
58 const char *opname = NULL;
59 if (--n < 0) goto err;
60 if (cp[n] == 0xe8) {
61 opname = "call";
62 } else if (cp[n] == 0xe9) {
63 opname = "jmp";
64 } else if (cp[n] >= 0x80 && cp[n] <= 0x8f && n > 0 && cp[n-1] == 0x0f) {
65 opname = jccnames[cp[n]-0x80];
66 n--;
67 } else {
68err:
69 fprintf(stderr, "Error: unsupported opcode for %s symbol relocation.\n",
70 sym);
71 exit(1);
72 }
73 emit_asm_bytes(ctx, cp, n);
74 fprintf(ctx->fp, "\t%s %s\n", opname, sym);
75}
76#else
77/* Emit words piecewise as assembler text. */
78static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n)
79{
80 int i;
81 for (i = 0; i < n; i += 4) {
82 if ((i & 15) == 0)
83 fprintf(ctx->fp, "\t.long 0x%08x", *(uint32_t *)(p+i));
84 else
85 fprintf(ctx->fp, ",0x%08x", *(uint32_t *)(p+i));
86 if ((i & 15) == 12) putc('\n', ctx->fp);
87 }
88 if ((n & 15) != 0) putc('\n', ctx->fp);
89}
90
91/* Emit relocation as part of an instruction. */
92static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
93 const char *sym)
94{
95 uint32_t ins;
96 emit_asm_words(ctx, p, n-4);
97 ins = *(uint32_t *)(p+n-4);
98#if LJ_TARGET_ARM
99 if ((ins & 0xff000000u) == 0xfa000000u) {
100 fprintf(ctx->fp, "\tblx %s\n", sym);
101 } else if ((ins & 0x0e000000u) == 0x0a000000u) {
102 fprintf(ctx->fp, "\t%s%.2s %s\n", (ins & 0x01000000u) ? "bl" : "b",
103 "eqnecsccmiplvsvchilsgeltgtle" + 2*(ins >> 28), sym);
104 } else {
105 fprintf(stderr,
106 "Error: unsupported opcode %08x for %s symbol relocation.\n",
107 ins, sym);
108 exit(1);
109 }
110#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
111 if ((ins >> 26) == 16) {
112 fprintf(ctx->fp, "\t%s %d, %d, %s\n",
113 (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
114 } else if ((ins >> 26) == 18) {
115 fprintf(ctx->fp, "\t%s %s\n", (ins & 1) ? "bl" : "b", sym);
116 } else {
117 fprintf(stderr,
118 "Error: unsupported opcode %08x for %s symbol relocation.\n",
119 ins, sym);
120 exit(1);
121 }
122#elif LJ_TARGET_MIPS
123 UNUSED(sym); /* NYI */
124#else
125#error "missing relocation support for this architecture"
126#endif
127}
128#endif
129
130#if LJ_TARGET_ARM
131#define ELFASM_PX "%%"
132#else
133#define ELFASM_PX "@"
134#endif
135
136/* Emit an assembler label. */
137static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc)
138{
139 switch (ctx->mode) {
140 case BUILD_elfasm:
141 fprintf(ctx->fp,
142 "\n\t.globl %s\n"
143 "\t.hidden %s\n"
144 "\t.type %s, " ELFASM_PX "%s\n"
145 "\t.size %s, %d\n"
146 "%s:\n",
147 name, name, name, isfunc ? "function" : "object", name, size, name);
148 break;
149 case BUILD_coffasm:
150 fprintf(ctx->fp, "\n\t.globl %s\n", name);
151 if (isfunc)
152 fprintf(ctx->fp, "\t.def %s; .scl 3; .type 32; .endef\n", name);
153 fprintf(ctx->fp, "%s:\n", name);
154 break;
155 case BUILD_machasm:
156 fprintf(ctx->fp,
157 "\n\t.private_extern %s\n"
158 "%s:\n", name, name);
159 break;
160 default:
161 break;
162 }
163}
164
165/* Emit alignment. */
166static void emit_asm_align(BuildCtx *ctx, int bits)
167{
168 switch (ctx->mode) {
169 case BUILD_elfasm:
170 case BUILD_coffasm:
171 fprintf(ctx->fp, "\t.p2align %d\n", bits);
172 break;
173 case BUILD_machasm:
174 fprintf(ctx->fp, "\t.align %d\n", bits);
175 break;
176 default:
177 break;
178 }
179}
180
181/* ------------------------------------------------------------------------ */
182
183/* Emit assembler source code. */
184void emit_asm(BuildCtx *ctx)
185{
186 int i, rel;
187
188 fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
189 fprintf(ctx->fp, "\t.text\n");
190 emit_asm_align(ctx, 4);
191
192 emit_asm_label(ctx, ctx->beginsym, 0, 0);
193 if (ctx->mode != BUILD_machasm)
194 fprintf(ctx->fp, ".Lbegin:\n");
195
196#if LJ_TARGET_ARM && defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND)
197 /* This should really be moved into buildvm_arm.dasc. */
198 fprintf(ctx->fp,
199 ".fnstart\n"
200 ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
201 ".pad #28\n");
202#endif
203
204 for (i = rel = 0; i < ctx->nsym; i++) {
205 int32_t ofs = ctx->sym[i].ofs;
206 int32_t next = ctx->sym[i+1].ofs;
207#if LJ_TARGET_ARM && defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND) && \
208 LJ_HASFFI
209 if (!strcmp(ctx->sym[i].name, "lj_vm_ffi_call"))
210 fprintf(ctx->fp,
211 ".globl lj_err_unwind_arm\n"
212 ".personality lj_err_unwind_arm\n"
213 ".fnend\n"
214 ".fnstart\n"
215 ".save {r4, r5, r11, lr}\n"
216 ".setfp r11, sp\n");
217#endif
218 emit_asm_label(ctx, ctx->sym[i].name, next - ofs, 1);
219 while (rel < ctx->nreloc && ctx->reloc[rel].ofs <= next) {
220 BuildReloc *r = &ctx->reloc[rel];
221 int n = r->ofs - ofs;
222#if LJ_TARGET_X86ORX64
223 if (ctx->mode == BUILD_machasm && r->type != 0) {
224 emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
225 } else {
226 emit_asm_bytes(ctx, ctx->code+ofs, n);
227 emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]);
228 }
229 ofs += n+4;
230#else
231 emit_asm_wordreloc(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
232 ofs += n;
233#endif
234 rel++;
235 }
236#if LJ_TARGET_X86ORX64
237 emit_asm_bytes(ctx, ctx->code+ofs, next-ofs);
238#else
239 emit_asm_words(ctx, ctx->code+ofs, next-ofs);
240#endif
241 }
242
243#if LJ_TARGET_ARM && defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND)
244 fprintf(ctx->fp,
245#if !LJ_HASFFI
246 ".globl lj_err_unwind_arm\n"
247 ".personality lj_err_unwind_arm\n"
248#endif
249 ".fnend\n");
250#endif
251
252 fprintf(ctx->fp, "\n");
253 switch (ctx->mode) {
254 case BUILD_elfasm:
255 fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
256#if LJ_TARGET_PPCSPE
257 /* Soft-float ABI + SPE. */
258 fprintf(ctx->fp, "\t.gnu_attribute 4, 2\n\t.gnu_attribute 8, 3\n");
259#elif LJ_TARGET_PPC
260 /* Hard-float ABI. */
261 fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
262#endif
263 /* fallthrough */
264 case BUILD_coffasm:
265 fprintf(ctx->fp, "\t.ident \"%s\"\n", ctx->dasm_ident);
266 break;
267 case BUILD_machasm:
268 fprintf(ctx->fp,
269 "\t.cstring\n"
270 "\t.ascii \"%s\\0\"\n", ctx->dasm_ident);
271 break;
272 default:
273 break;
274 }
275 fprintf(ctx->fp, "\n");
276}
277
diff --git a/libraries/luajit-2.0/src/buildvm_fold.c b/libraries/luajit-2.0/src/buildvm_fold.c
new file mode 100644
index 0000000..b43d2c4
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_fold.c
@@ -0,0 +1,229 @@
1/*
2** LuaJIT VM builder: IR folding hash table generator.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "buildvm.h"
7#include "lj_obj.h"
8#include "lj_ir.h"
9
10/* Context for the folding hash table generator. */
11static int lineno;
12static int funcidx;
13static uint32_t foldkeys[BUILD_MAX_FOLD];
14static uint32_t nkeys;
15
16/* Try to fill the hash table with keys using the hash parameters. */
17static int tryhash(uint32_t *htab, uint32_t sz, uint32_t r, int dorol)
18{
19 uint32_t i;
20 if (dorol && ((r & 31) == 0 || (r>>5) == 0))
21 return 0; /* Avoid zero rotates. */
22 memset(htab, 0xff, (sz+1)*sizeof(uint32_t));
23 for (i = 0; i < nkeys; i++) {
24 uint32_t key = foldkeys[i];
25 uint32_t k = key & 0xffffff;
26 uint32_t h = (dorol ? lj_rol(lj_rol(k, r>>5) - k, r&31) :
27 (((k << (r>>5)) - k) << (r&31))) % sz;
28 if (htab[h] != 0xffffffff) { /* Collision on primary slot. */
29 if (htab[h+1] != 0xffffffff) { /* Collision on secondary slot. */
30 /* Try to move the colliding key, if possible. */
31 if (h < sz-1 && htab[h+2] == 0xffffffff) {
32 uint32_t k2 = htab[h+1] & 0xffffff;
33 uint32_t h2 = (dorol ? lj_rol(lj_rol(k2, r>>5) - k2, r&31) :
34 (((k2 << (r>>5)) - k2) << (r&31))) % sz;
35 if (h2 != h+1) return 0; /* Cannot resolve collision. */
36 htab[h+2] = htab[h+1]; /* Move colliding key to secondary slot. */
37 } else {
38 return 0; /* Collision. */
39 }
40 }
41 htab[h+1] = key;
42 } else {
43 htab[h] = key;
44 }
45 }
46 return 1; /* Success, all keys could be stored. */
47}
48
49/* Print the generated hash table. */
50static void printhash(BuildCtx *ctx, uint32_t *htab, uint32_t sz)
51{
52 uint32_t i;
53 fprintf(ctx->fp, "static const uint32_t fold_hash[%d] = {\n0x%08x",
54 sz+1, htab[0]);
55 for (i = 1; i < sz+1; i++)
56 fprintf(ctx->fp, ",\n0x%08x", htab[i]);
57 fprintf(ctx->fp, "\n};\n\n");
58}
59
60/* Exhaustive search for the shortest semi-perfect hash table. */
61static void makehash(BuildCtx *ctx)
62{
63 uint32_t htab[BUILD_MAX_FOLD*2+1];
64 uint32_t sz, r;
65 /* Search for the smallest hash table with an odd size. */
66 for (sz = (nkeys|1); sz < BUILD_MAX_FOLD*2; sz += 2) {
67 /* First try all shift hash combinations. */
68 for (r = 0; r < 32*32; r++) {
69 if (tryhash(htab, sz, r, 0)) {
70 printhash(ctx, htab, sz);
71 fprintf(ctx->fp,
72 "#define fold_hashkey(k)\t(((((k)<<%u)-(k))<<%u)%%%u)\n\n",
73 r>>5, r&31, sz);
74 return;
75 }
76 }
77 /* Then try all rotate hash combinations. */
78 for (r = 0; r < 32*32; r++) {
79 if (tryhash(htab, sz, r, 1)) {
80 printhash(ctx, htab, sz);
81 fprintf(ctx->fp,
82 "#define fold_hashkey(k)\t(lj_rol(lj_rol((k),%u)-(k),%u)%%%u)\n\n",
83 r>>5, r&31, sz);
84 return;
85 }
86 }
87 }
88 fprintf(stderr, "Error: search for perfect hash failed\n");
89 exit(1);
90}
91
92/* Parse one token of a fold rule. */
93static uint32_t nexttoken(char **pp, int allowlit, int allowany)
94{
95 char *p = *pp;
96 if (p) {
97 uint32_t i;
98 char *q = strchr(p, ' ');
99 if (q) *q++ = '\0';
100 *pp = q;
101 if (allowlit && !strncmp(p, "IRFPM_", 6)) {
102 for (i = 0; irfpm_names[i]; i++)
103 if (!strcmp(irfpm_names[i], p+6))
104 return i;
105 } else if (allowlit && !strncmp(p, "IRFL_", 5)) {
106 for (i = 0; irfield_names[i]; i++)
107 if (!strcmp(irfield_names[i], p+5))
108 return i;
109 } else if (allowlit && !strncmp(p, "IRCALL_", 7)) {
110 for (i = 0; ircall_names[i]; i++)
111 if (!strcmp(ircall_names[i], p+7))
112 return i;
113 } else if (allowlit && !strncmp(p, "IRCONV_", 7)) {
114 for (i = 0; irt_names[i]; i++) {
115 const char *r = strchr(p+7, '_');
116 if (r && !strncmp(irt_names[i], p+7, r-(p+7))) {
117 uint32_t j;
118 for (j = 0; irt_names[j]; j++)
119 if (!strcmp(irt_names[j], r+1))
120 return (i << 5) + j;
121 }
122 }
123 } else if (allowlit && *p >= '0' && *p <= '9') {
124 for (i = 0; *p >= '0' && *p <= '9'; p++)
125 i = i*10 + (*p - '0');
126 if (*p == '\0')
127 return i;
128 } else if (allowany && !strcmp("any", p)) {
129 return allowany;
130 } else {
131 for (i = 0; ir_names[i]; i++)
132 if (!strcmp(ir_names[i], p))
133 return i;
134 }
135 fprintf(stderr, "Error: bad fold definition token \"%s\" at line %d\n", p, lineno);
136 exit(1);
137 }
138 return 0;
139}
140
141/* Parse a fold rule. */
142static void foldrule(char *p)
143{
144 uint32_t op = nexttoken(&p, 0, 0);
145 uint32_t left = nexttoken(&p, 0, 0x7f);
146 uint32_t right = nexttoken(&p, 1, 0x3ff);
147 uint32_t key = (funcidx << 24) | (op << 17) | (left << 10) | right;
148 uint32_t i;
149 if (nkeys >= BUILD_MAX_FOLD) {
150 fprintf(stderr, "Error: too many fold rules, increase BUILD_MAX_FOLD.\n");
151 exit(1);
152 }
153 /* Simple insertion sort to detect duplicates. */
154 for (i = nkeys; i > 0; i--) {
155 if ((foldkeys[i-1]&0xffffff) < (key & 0xffffff))
156 break;
157 if ((foldkeys[i-1]&0xffffff) == (key & 0xffffff)) {
158 fprintf(stderr, "Error: duplicate fold definition at line %d\n", lineno);
159 exit(1);
160 }
161 foldkeys[i] = foldkeys[i-1];
162 }
163 foldkeys[i] = key;
164 nkeys++;
165}
166
167/* Emit C source code for IR folding hash table. */
168void emit_fold(BuildCtx *ctx)
169{
170 char buf[256]; /* We don't care about analyzing lines longer than that. */
171 const char *fname = ctx->args[0];
172 FILE *fp;
173
174 if (fname == NULL) {
175 fprintf(stderr, "Error: missing input filename\n");
176 exit(1);
177 }
178
179 if (fname[0] == '-' && fname[1] == '\0') {
180 fp = stdin;
181 } else {
182 fp = fopen(fname, "r");
183 if (!fp) {
184 fprintf(stderr, "Error: cannot open input file '%s': %s\n",
185 fname, strerror(errno));
186 exit(1);
187 }
188 }
189
190 fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n");
191 fprintf(ctx->fp, "static const FoldFunc fold_func[] = {\n");
192
193 lineno = 0;
194 funcidx = 0;
195 nkeys = 0;
196 while (fgets(buf, sizeof(buf), fp) != NULL) {
197 lineno++;
198 /* The prefix must be at the start of a line, otherwise it's ignored. */
199 if (!strncmp(buf, FOLDDEF_PREFIX, sizeof(FOLDDEF_PREFIX)-1)) {
200 char *p = buf+sizeof(FOLDDEF_PREFIX)-1;
201 char *q = strchr(p, ')');
202 if (p[0] == '(' && q) {
203 p++;
204 *q = '\0';
205 foldrule(p);
206 } else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) {
207 p += 2;
208 *q = '\0';
209 if (funcidx)
210 fprintf(ctx->fp, ",\n");
211 if (p[-2] == 'X')
212 fprintf(ctx->fp, " %s", p);
213 else
214 fprintf(ctx->fp, " fold_%s", p);
215 funcidx++;
216 } else {
217 buf[strlen(buf)-1] = '\0';
218 fprintf(stderr, "Error: unknown fold definition tag %s%s at line %d\n",
219 FOLDDEF_PREFIX, p, lineno);
220 exit(1);
221 }
222 }
223 }
224 fclose(fp);
225 fprintf(ctx->fp, "\n};\n\n");
226
227 makehash(ctx);
228}
229
diff --git a/libraries/luajit-2.0/src/buildvm_lib.c b/libraries/luajit-2.0/src/buildvm_lib.c
new file mode 100644
index 0000000..8d9bcea
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_lib.c
@@ -0,0 +1,377 @@
1/*
2** LuaJIT VM builder: library definition compiler.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "buildvm.h"
7#include "lj_obj.h"
8#include "lj_lib.h"
9
10/* Context for library definitions. */
11static uint8_t obuf[8192];
12static uint8_t *optr;
13static char modname[80];
14static size_t modnamelen;
15static char funcname[80];
16static int modstate, regfunc;
17static int ffid, recffid, ffasmfunc;
18
19enum {
20 REGFUNC_OK,
21 REGFUNC_NOREG,
22 REGFUNC_NOREGUV
23};
24
25static void libdef_name(const char *p, int kind)
26{
27 size_t n = strlen(p);
28 if (kind != LIBINIT_STRING) {
29 if (n > modnamelen && p[modnamelen] == '_' &&
30 !strncmp(p, modname, modnamelen)) {
31 p += modnamelen+1;
32 n -= modnamelen+1;
33 }
34 }
35 if (n > LIBINIT_MAXSTR) {
36 fprintf(stderr, "Error: string too long: '%s'\n", p);
37 exit(1);
38 }
39 if (optr+1+n+2 > obuf+sizeof(obuf)) { /* +2 for caller. */
40 fprintf(stderr, "Error: output buffer overflow\n");
41 exit(1);
42 }
43 *optr++ = (uint8_t)(n | kind);
44 memcpy(optr, p, n);
45 optr += n;
46}
47
48static void libdef_endmodule(BuildCtx *ctx)
49{
50 if (modstate != 0) {
51 char line[80];
52 const uint8_t *p;
53 int n;
54 if (modstate == 1)
55 fprintf(ctx->fp, " (lua_CFunction)0");
56 fprintf(ctx->fp, "\n};\n");
57 fprintf(ctx->fp, "static const uint8_t %s%s[] = {\n",
58 LABEL_PREFIX_LIBINIT, modname);
59 line[0] = '\0';
60 for (n = 0, p = obuf; p < optr; p++) {
61 n += sprintf(line+n, "%d,", *p);
62 if (n >= 75) {
63 fprintf(ctx->fp, "%s\n", line);
64 n = 0;
65 line[0] = '\0';
66 }
67 }
68 fprintf(ctx->fp, "%s%d\n};\n#endif\n\n", line, LIBINIT_END);
69 }
70}
71
72static void libdef_module(BuildCtx *ctx, char *p, int arg)
73{
74 UNUSED(arg);
75 if (ctx->mode == BUILD_libdef) {
76 libdef_endmodule(ctx);
77 optr = obuf;
78 *optr++ = (uint8_t)ffid;
79 *optr++ = (uint8_t)ffasmfunc;
80 *optr++ = 0; /* Hash table size. */
81 modstate = 1;
82 fprintf(ctx->fp, "#ifdef %sMODULE_%s\n", LIBDEF_PREFIX, p);
83 fprintf(ctx->fp, "#undef %sMODULE_%s\n", LIBDEF_PREFIX, p);
84 fprintf(ctx->fp, "static const lua_CFunction %s%s[] = {\n",
85 LABEL_PREFIX_LIBCF, p);
86 }
87 modnamelen = strlen(p);
88 if (modnamelen > sizeof(modname)-1) {
89 fprintf(stderr, "Error: module name too long: '%s'\n", p);
90 exit(1);
91 }
92 strcpy(modname, p);
93}
94
95static int find_ffofs(BuildCtx *ctx, const char *name)
96{
97 int i;
98 for (i = 0; i < ctx->nglob; i++) {
99 const char *gl = ctx->globnames[i];
100 if (gl[0] == 'f' && gl[1] == 'f' && gl[2] == '_' && !strcmp(gl+3, name)) {
101 return (int)((uint8_t *)ctx->glob[i] - ctx->code);
102 }
103 }
104 fprintf(stderr, "Error: undefined fast function %s%s\n",
105 LABEL_PREFIX_FF, name);
106 exit(1);
107}
108
109static void libdef_func(BuildCtx *ctx, char *p, int arg)
110{
111 if (arg != LIBINIT_CF)
112 ffasmfunc++;
113 if (ctx->mode == BUILD_libdef) {
114 if (modstate == 0) {
115 fprintf(stderr, "Error: no module for function definition %s\n", p);
116 exit(1);
117 }
118 if (regfunc == REGFUNC_NOREG) {
119 if (optr+1 > obuf+sizeof(obuf)) {
120 fprintf(stderr, "Error: output buffer overflow\n");
121 exit(1);
122 }
123 *optr++ = LIBINIT_FFID;
124 } else {
125 if (arg != LIBINIT_ASM_) {
126 if (modstate != 1) fprintf(ctx->fp, ",\n");
127 modstate = 2;
128 fprintf(ctx->fp, " %s%s", arg ? LABEL_PREFIX_FFH : LABEL_PREFIX_CF, p);
129 }
130 if (regfunc != REGFUNC_NOREGUV) obuf[2]++; /* Bump hash table size. */
131 libdef_name(regfunc == REGFUNC_NOREGUV ? "" : p, arg);
132 }
133 } else if (ctx->mode == BUILD_ffdef) {
134 fprintf(ctx->fp, "FFDEF(%s)\n", p);
135 } else if (ctx->mode == BUILD_recdef) {
136 if (strlen(p) > sizeof(funcname)-1) {
137 fprintf(stderr, "Error: function name too long: '%s'\n", p);
138 exit(1);
139 }
140 strcpy(funcname, p);
141 } else if (ctx->mode == BUILD_vmdef) {
142 int i;
143 for (i = 1; p[i] && modname[i-1]; i++)
144 if (p[i] == '_') p[i] = '.';
145 fprintf(ctx->fp, "\"%s\",\n", p);
146 } else if (ctx->mode == BUILD_bcdef) {
147 if (arg != LIBINIT_CF)
148 fprintf(ctx->fp, ",\n%d", find_ffofs(ctx, p));
149 }
150 ffid++;
151 regfunc = REGFUNC_OK;
152}
153
154static uint32_t find_rec(char *name)
155{
156 char *p = (char *)obuf;
157 uint32_t n;
158 for (n = 2; *p; n++) {
159 if (strcmp(p, name) == 0)
160 return n;
161 p += strlen(p)+1;
162 }
163 if (p+strlen(name)+1 >= (char *)obuf+sizeof(obuf)) {
164 fprintf(stderr, "Error: output buffer overflow\n");
165 exit(1);
166 }
167 strcpy(p, name);
168 return n;
169}
170
171static void libdef_rec(BuildCtx *ctx, char *p, int arg)
172{
173 UNUSED(arg);
174 if (ctx->mode == BUILD_recdef) {
175 char *q;
176 uint32_t n;
177 for (; recffid+1 < ffid; recffid++)
178 fprintf(ctx->fp, ",\n0");
179 recffid = ffid;
180 if (*p == '.') p = funcname;
181 q = strchr(p, ' ');
182 if (q) *q++ = '\0';
183 n = find_rec(p);
184 if (q)
185 fprintf(ctx->fp, ",\n0x%02x00+(%s)", n, q);
186 else
187 fprintf(ctx->fp, ",\n0x%02x00", n);
188 }
189}
190
191static void memcpy_endian(void *dst, void *src, size_t n)
192{
193 union { uint8_t b; uint32_t u; } host_endian;
194 host_endian.u = 1;
195 if (host_endian.b == LJ_ENDIAN_SELECT(1, 0)) {
196 memcpy(dst, src, n);
197 } else {
198 size_t i;
199 for (i = 0; i < n; i++)
200 ((uint8_t *)dst)[i] = ((uint8_t *)src)[n-i-1];
201 }
202}
203
204static void libdef_push(BuildCtx *ctx, char *p, int arg)
205{
206 UNUSED(arg);
207 if (ctx->mode == BUILD_libdef) {
208 int len = (int)strlen(p);
209 if (*p == '"') {
210 if (len > 1 && p[len-1] == '"') {
211 p[len-1] = '\0';
212 libdef_name(p+1, LIBINIT_STRING);
213 return;
214 }
215 } else if (*p >= '0' && *p <= '9') {
216 char *ep;
217 double d = strtod(p, &ep);
218 if (*ep == '\0') {
219 if (optr+1+sizeof(double) > obuf+sizeof(obuf)) {
220 fprintf(stderr, "Error: output buffer overflow\n");
221 exit(1);
222 }
223 *optr++ = LIBINIT_NUMBER;
224 memcpy_endian(optr, &d, sizeof(double));
225 optr += sizeof(double);
226 return;
227 }
228 } else if (!strcmp(p, "lastcl")) {
229 if (optr+1 > obuf+sizeof(obuf)) {
230 fprintf(stderr, "Error: output buffer overflow\n");
231 exit(1);
232 }
233 *optr++ = LIBINIT_LASTCL;
234 return;
235 } else if (len > 4 && !strncmp(p, "top-", 4)) {
236 if (optr+2 > obuf+sizeof(obuf)) {
237 fprintf(stderr, "Error: output buffer overflow\n");
238 exit(1);
239 }
240 *optr++ = LIBINIT_COPY;
241 *optr++ = (uint8_t)atoi(p+4);
242 return;
243 }
244 fprintf(stderr, "Error: bad value for %sPUSH(%s)\n", LIBDEF_PREFIX, p);
245 exit(1);
246 }
247}
248
249static void libdef_set(BuildCtx *ctx, char *p, int arg)
250{
251 UNUSED(arg);
252 if (ctx->mode == BUILD_libdef) {
253 if (p[0] == '!' && p[1] == '\0') p[0] = '\0'; /* Set env. */
254 libdef_name(p, LIBINIT_STRING);
255 *optr++ = LIBINIT_SET;
256 obuf[2]++; /* Bump hash table size. */
257 }
258}
259
260static void libdef_regfunc(BuildCtx *ctx, char *p, int arg)
261{
262 UNUSED(ctx); UNUSED(p);
263 regfunc = arg;
264}
265
266typedef void (*LibDefFunc)(BuildCtx *ctx, char *p, int arg);
267
268typedef struct LibDefHandler {
269 const char *suffix;
270 const char *stop;
271 const LibDefFunc func;
272 const int arg;
273} LibDefHandler;
274
275static const LibDefHandler libdef_handlers[] = {
276 { "MODULE_", " \t\r\n", libdef_module, 0 },
277 { "CF(", ")", libdef_func, LIBINIT_CF },
278 { "ASM(", ")", libdef_func, LIBINIT_ASM },
279 { "ASM_(", ")", libdef_func, LIBINIT_ASM_ },
280 { "REC(", ")", libdef_rec, 0 },
281 { "PUSH(", ")", libdef_push, 0 },
282 { "SET(", ")", libdef_set, 0 },
283 { "NOREGUV", NULL, libdef_regfunc, REGFUNC_NOREGUV },
284 { "NOREG", NULL, libdef_regfunc, REGFUNC_NOREG },
285 { NULL, NULL, (LibDefFunc)0, 0 }
286};
287
288/* Emit C source code for library function definitions. */
289void emit_lib(BuildCtx *ctx)
290{
291 const char *fname;
292
293 if (ctx->mode == BUILD_ffdef || ctx->mode == BUILD_libdef ||
294 ctx->mode == BUILD_recdef)
295 fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n");
296 else if (ctx->mode == BUILD_vmdef)
297 fprintf(ctx->fp, "ffnames = {\n[0]=\"Lua\",\n\"C\",\n");
298 if (ctx->mode == BUILD_recdef)
299 fprintf(ctx->fp, "static const uint16_t recff_idmap[] = {\n0,\n0x0100");
300 recffid = ffid = FF_C+1;
301 ffasmfunc = 0;
302
303 while ((fname = *ctx->args++)) {
304 char buf[256]; /* We don't care about analyzing lines longer than that. */
305 FILE *fp;
306 if (fname[0] == '-' && fname[1] == '\0') {
307 fp = stdin;
308 } else {
309 fp = fopen(fname, "r");
310 if (!fp) {
311 fprintf(stderr, "Error: cannot open input file '%s': %s\n",
312 fname, strerror(errno));
313 exit(1);
314 }
315 }
316 modstate = 0;
317 regfunc = REGFUNC_OK;
318 while (fgets(buf, sizeof(buf), fp) != NULL) {
319 char *p;
320 for (p = buf; (p = strstr(p, LIBDEF_PREFIX)) != NULL; ) {
321 const LibDefHandler *ldh;
322 p += sizeof(LIBDEF_PREFIX)-1;
323 for (ldh = libdef_handlers; ldh->suffix != NULL; ldh++) {
324 size_t n, len = strlen(ldh->suffix);
325 if (!strncmp(p, ldh->suffix, len)) {
326 p += len;
327 n = ldh->stop ? strcspn(p, ldh->stop) : 0;
328 if (!p[n]) break;
329 p[n] = '\0';
330 ldh->func(ctx, p, ldh->arg);
331 p += n+1;
332 break;
333 }
334 }
335 if (ldh->suffix == NULL) {
336 buf[strlen(buf)-1] = '\0';
337 fprintf(stderr, "Error: unknown library definition tag %s%s\n",
338 LIBDEF_PREFIX, p);
339 exit(1);
340 }
341 }
342 }
343 fclose(fp);
344 if (ctx->mode == BUILD_libdef) {
345 libdef_endmodule(ctx);
346 }
347 }
348
349 if (ctx->mode == BUILD_ffdef) {
350 fprintf(ctx->fp, "\n#undef FFDEF\n\n");
351 fprintf(ctx->fp,
352 "#ifndef FF_NUM_ASMFUNC\n#define FF_NUM_ASMFUNC %d\n#endif\n\n",
353 ffasmfunc);
354 } else if (ctx->mode == BUILD_vmdef) {
355 fprintf(ctx->fp, "}\n\n");
356 } else if (ctx->mode == BUILD_bcdef) {
357 int i;
358 fprintf(ctx->fp, "\n};\n\n");
359 fprintf(ctx->fp, "LJ_DATADEF const uint16_t lj_bc_mode[] = {\n");
360 fprintf(ctx->fp, "BCDEF(BCMODE)\n");
361 for (i = ffasmfunc-1; i > 0; i--)
362 fprintf(ctx->fp, "BCMODE_FF,\n");
363 fprintf(ctx->fp, "BCMODE_FF\n};\n\n");
364 } else if (ctx->mode == BUILD_recdef) {
365 char *p = (char *)obuf;
366 fprintf(ctx->fp, "\n};\n\n");
367 fprintf(ctx->fp, "static const RecordFunc recff_func[] = {\n"
368 "recff_nyi,\n"
369 "recff_c");
370 while (*p) {
371 fprintf(ctx->fp, ",\nrecff_%s", p);
372 p += strlen(p)+1;
373 }
374 fprintf(ctx->fp, "\n};\n\n");
375 }
376}
377
diff --git a/libraries/luajit-2.0/src/buildvm_peobj.c b/libraries/luajit-2.0/src/buildvm_peobj.c
new file mode 100644
index 0000000..eb1d345
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_peobj.c
@@ -0,0 +1,352 @@
1/*
2** LuaJIT VM builder: PE object emitter.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Only used for building on Windows, since we cannot assume the presence
6** of a suitable assembler. The host and target byte order must match.
7*/
8
9#include "buildvm.h"
10#include "lj_bc.h"
11
12#if LJ_TARGET_X86ORX64
13
14/* Context for PE object emitter. */
15static char *strtab;
16static size_t strtabofs;
17
18/* -- PE object definitions ----------------------------------------------- */
19
20/* PE header. */
21typedef struct PEheader {
22 uint16_t arch;
23 uint16_t nsects;
24 uint32_t time;
25 uint32_t symtabofs;
26 uint32_t nsyms;
27 uint16_t opthdrsz;
28 uint16_t flags;
29} PEheader;
30
31/* PE section. */
32typedef struct PEsection {
33 char name[8];
34 uint32_t vsize;
35 uint32_t vaddr;
36 uint32_t size;
37 uint32_t ofs;
38 uint32_t relocofs;
39 uint32_t lineofs;
40 uint16_t nreloc;
41 uint16_t nline;
42 uint32_t flags;
43} PEsection;
44
45/* PE relocation. */
46typedef struct PEreloc {
47 uint32_t vaddr;
48 uint32_t symidx;
49 uint16_t type;
50} PEreloc;
51
52/* Cannot use sizeof, because it pads up to the max. alignment. */
53#define PEOBJ_RELOC_SIZE (4+4+2)
54
55/* PE symbol table entry. */
56typedef struct PEsym {
57 union {
58 char name[8];
59 uint32_t nameref[2];
60 } n;
61 uint32_t value;
62 int16_t sect;
63 uint16_t type;
64 uint8_t scl;
65 uint8_t naux;
66} PEsym;
67
68/* PE symbol table auxiliary entry for a section. */
69typedef struct PEsymaux {
70 uint32_t size;
71 uint16_t nreloc;
72 uint16_t nline;
73 uint32_t cksum;
74 uint16_t assoc;
75 uint8_t comdatsel;
76 uint8_t unused[3];
77} PEsymaux;
78
79/* Cannot use sizeof, because it pads up to the max. alignment. */
80#define PEOBJ_SYM_SIZE (8+4+2+2+1+1)
81
82/* PE object CPU specific defines. */
83#if LJ_TARGET_X86
84#define PEOBJ_ARCH_TARGET 0x014c
85#define PEOBJ_RELOC_REL32 0x14 /* MS: REL32, GNU: DISP32. */
86#define PEOBJ_RELOC_DIR32 0x06
87#elif LJ_TARGET_X64
88#define PEOBJ_ARCH_TARGET 0x8664
89#define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */
90#define PEOBJ_RELOC_DIR32 0x02
91#define PEOBJ_RELOC_ADDR32NB 0x03
92#endif
93
94/* Section numbers (0-based). */
95enum {
96 PEOBJ_SECT_ABS = -2,
97 PEOBJ_SECT_UNDEF = -1,
98 PEOBJ_SECT_TEXT,
99#if LJ_TARGET_X64
100 PEOBJ_SECT_PDATA,
101 PEOBJ_SECT_XDATA,
102#endif
103 PEOBJ_SECT_RDATA_Z,
104 PEOBJ_NSECTIONS
105};
106
107/* Symbol types. */
108#define PEOBJ_TYPE_NULL 0
109#define PEOBJ_TYPE_FUNC 0x20
110
111/* Symbol storage class. */
112#define PEOBJ_SCL_EXTERN 2
113#define PEOBJ_SCL_STATIC 3
114
115/* -- PE object emitter --------------------------------------------------- */
116
117/* Emit PE object symbol. */
118static void emit_peobj_sym(BuildCtx *ctx, const char *name, uint32_t value,
119 int sect, int type, int scl)
120{
121 PEsym sym;
122 size_t len = strlen(name);
123 if (!strtab) { /* Pass 1: only calculate string table length. */
124 if (len > 8) strtabofs += len+1;
125 return;
126 }
127 if (len <= 8) {
128 memcpy(sym.n.name, name, len);
129 memset(sym.n.name+len, 0, 8-len);
130 } else {
131 sym.n.nameref[0] = 0;
132 sym.n.nameref[1] = (uint32_t)strtabofs;
133 memcpy(strtab + strtabofs, name, len);
134 strtab[strtabofs+len] = 0;
135 strtabofs += len+1;
136 }
137 sym.value = value;
138 sym.sect = (int16_t)(sect+1); /* 1-based section number. */
139 sym.type = (uint16_t)type;
140 sym.scl = (uint8_t)scl;
141 sym.naux = 0;
142 owrite(ctx, &sym, PEOBJ_SYM_SIZE);
143}
144
145/* Emit PE object section symbol. */
146static void emit_peobj_sym_sect(BuildCtx *ctx, PEsection *pesect, int sect)
147{
148 PEsym sym;
149 PEsymaux aux;
150 if (!strtab) return; /* Pass 1: no output. */
151 memcpy(sym.n.name, pesect[sect].name, 8);
152 sym.value = 0;
153 sym.sect = (int16_t)(sect+1); /* 1-based section number. */
154 sym.type = PEOBJ_TYPE_NULL;
155 sym.scl = PEOBJ_SCL_STATIC;
156 sym.naux = 1;
157 owrite(ctx, &sym, PEOBJ_SYM_SIZE);
158 memset(&aux, 0, sizeof(PEsymaux));
159 aux.size = pesect[sect].size;
160 aux.nreloc = pesect[sect].nreloc;
161 owrite(ctx, &aux, PEOBJ_SYM_SIZE);
162}
163
164/* Emit Windows PE object file. */
165void emit_peobj(BuildCtx *ctx)
166{
167 PEheader pehdr;
168 PEsection pesect[PEOBJ_NSECTIONS];
169 uint32_t sofs;
170 int i, nrsym;
171 union { uint8_t b; uint32_t u; } host_endian;
172
173 host_endian.u = 1;
174 if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) {
175 fprintf(stderr, "Error: different byte order for host and target\n");
176 exit(1);
177 }
178
179 sofs = sizeof(PEheader) + PEOBJ_NSECTIONS*sizeof(PEsection);
180
181 /* Fill in PE sections. */
182 memset(&pesect, 0, PEOBJ_NSECTIONS*sizeof(PEsection));
183 memcpy(pesect[PEOBJ_SECT_TEXT].name, ".text", sizeof(".text")-1);
184 pesect[PEOBJ_SECT_TEXT].ofs = sofs;
185 sofs += (pesect[PEOBJ_SECT_TEXT].size = (uint32_t)ctx->codesz);
186 pesect[PEOBJ_SECT_TEXT].relocofs = sofs;
187 sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE;
188 /* Flags: 60 = read+execute, 50 = align16, 20 = code. */
189 pesect[PEOBJ_SECT_TEXT].flags = 0x60500020;
190
191#if LJ_TARGET_X64
192 memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1);
193 pesect[PEOBJ_SECT_PDATA].ofs = sofs;
194 sofs += (pesect[PEOBJ_SECT_PDATA].size = 6*4);
195 pesect[PEOBJ_SECT_PDATA].relocofs = sofs;
196 sofs += (pesect[PEOBJ_SECT_PDATA].nreloc = 6) * PEOBJ_RELOC_SIZE;
197 /* Flags: 40 = read, 30 = align4, 40 = initialized data. */
198 pesect[PEOBJ_SECT_PDATA].flags = 0x40300040;
199
200 memcpy(pesect[PEOBJ_SECT_XDATA].name, ".xdata", sizeof(".xdata")-1);
201 pesect[PEOBJ_SECT_XDATA].ofs = sofs;
202 sofs += (pesect[PEOBJ_SECT_XDATA].size = 8*2+4+6*2); /* See below. */
203 pesect[PEOBJ_SECT_XDATA].relocofs = sofs;
204 sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE;
205 /* Flags: 40 = read, 30 = align4, 40 = initialized data. */
206 pesect[PEOBJ_SECT_XDATA].flags = 0x40300040;
207#endif
208
209 memcpy(pesect[PEOBJ_SECT_RDATA_Z].name, ".rdata$Z", sizeof(".rdata$Z")-1);
210 pesect[PEOBJ_SECT_RDATA_Z].ofs = sofs;
211 sofs += (pesect[PEOBJ_SECT_RDATA_Z].size = (uint32_t)strlen(ctx->dasm_ident)+1);
212 /* Flags: 40 = read, 30 = align4, 40 = initialized data. */
213 pesect[PEOBJ_SECT_RDATA_Z].flags = 0x40300040;
214
215 /* Fill in PE header. */
216 pehdr.arch = PEOBJ_ARCH_TARGET;
217 pehdr.nsects = PEOBJ_NSECTIONS;
218 pehdr.time = 0; /* Timestamp is optional. */
219 pehdr.symtabofs = sofs;
220 pehdr.opthdrsz = 0;
221 pehdr.flags = 0;
222
223 /* Compute the size of the symbol table:
224 ** @feat.00 + nsections*2
225 ** + asm_start + nsym
226 ** + nrsym
227 */
228 nrsym = ctx->nrelocsym;
229 pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym;
230#if LJ_TARGET_X64
231 pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win64. */
232#endif
233
234 /* Write PE object header and all sections. */
235 owrite(ctx, &pehdr, sizeof(PEheader));
236 owrite(ctx, &pesect, sizeof(PEsection)*PEOBJ_NSECTIONS);
237
238 /* Write .text section. */
239 owrite(ctx, ctx->code, ctx->codesz);
240 for (i = 0; i < ctx->nreloc; i++) {
241 PEreloc reloc;
242 reloc.vaddr = (uint32_t)ctx->reloc[i].ofs;
243 reloc.symidx = 1+2+ctx->reloc[i].sym; /* Reloc syms are after .text sym. */
244 reloc.type = ctx->reloc[i].type ? PEOBJ_RELOC_REL32 : PEOBJ_RELOC_DIR32;
245 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
246 }
247
248#if LJ_TARGET_X64
249 { /* Write .pdata section. */
250 uint32_t fcofs = (uint32_t)ctx->sym[ctx->nsym-1].ofs;
251 uint32_t pdata[3]; /* Start of .text, end of .text and .xdata. */
252 PEreloc reloc;
253 pdata[0] = 0; pdata[1] = fcofs; pdata[2] = 0;
254 owrite(ctx, &pdata, sizeof(pdata));
255 pdata[0] = fcofs; pdata[1] = (uint32_t)ctx->codesz; pdata[2] = 20;
256 owrite(ctx, &pdata, sizeof(pdata));
257 reloc.vaddr = 0; reloc.symidx = 1+2+nrsym+2+2+1;
258 reloc.type = PEOBJ_RELOC_ADDR32NB;
259 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
260 reloc.vaddr = 4; reloc.symidx = 1+2+nrsym+2+2+1;
261 reloc.type = PEOBJ_RELOC_ADDR32NB;
262 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
263 reloc.vaddr = 8; reloc.symidx = 1+2+nrsym+2;
264 reloc.type = PEOBJ_RELOC_ADDR32NB;
265 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
266 reloc.vaddr = 12; reloc.symidx = 1+2+nrsym+2+2+1;
267 reloc.type = PEOBJ_RELOC_ADDR32NB;
268 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
269 reloc.vaddr = 16; reloc.symidx = 1+2+nrsym+2+2+1;
270 reloc.type = PEOBJ_RELOC_ADDR32NB;
271 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
272 reloc.vaddr = 20; reloc.symidx = 1+2+nrsym+2;
273 reloc.type = PEOBJ_RELOC_ADDR32NB;
274 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
275 }
276 { /* Write .xdata section. */
277 uint16_t xdata[8+2+6];
278 PEreloc reloc;
279 xdata[0] = 0x01|0x08|0x10; /* Ver. 1, uhandler/ehandler, prolog size 0. */
280 xdata[1] = 0x0005; /* Number of unwind codes, no frame pointer. */
281 xdata[2] = 0x4200; /* Stack offset 4*8+8 = aword*5. */
282 xdata[3] = 0x3000; /* Push rbx. */
283 xdata[4] = 0x6000; /* Push rsi. */
284 xdata[5] = 0x7000; /* Push rdi. */
285 xdata[6] = 0x5000; /* Push rbp. */
286 xdata[7] = 0; /* Alignment. */
287 xdata[8] = xdata[9] = 0; /* Relocated address of exception handler. */
288 xdata[10] = 0x01; /* Ver. 1, no handler, prolog size 0. */
289 xdata[11] = 0x1504; /* Number of unwind codes, fp = rbp, fpofs = 16. */
290 xdata[12] = 0x0300; /* set_fpreg. */
291 xdata[13] = 0x0200; /* stack offset 0*8+8 = aword*1. */
292 xdata[14] = 0x3000; /* Push rbx. */
293 xdata[15] = 0x5000; /* Push rbp. */
294 owrite(ctx, &xdata, sizeof(xdata));
295 reloc.vaddr = 2*8; reloc.symidx = 1+2+nrsym+2+2;
296 reloc.type = PEOBJ_RELOC_ADDR32NB;
297 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
298 }
299#endif
300
301 /* Write .rdata$Z section. */
302 owrite(ctx, ctx->dasm_ident, strlen(ctx->dasm_ident)+1);
303
304 /* Write symbol table. */
305 strtab = NULL; /* 1st pass: collect string sizes. */
306 for (;;) {
307 strtabofs = 4;
308 /* Mark as SafeSEH compliant. */
309 emit_peobj_sym(ctx, "@feat.00", 1,
310 PEOBJ_SECT_ABS, PEOBJ_TYPE_NULL, PEOBJ_SCL_STATIC);
311
312 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_TEXT);
313 for (i = 0; i < nrsym; i++)
314 emit_peobj_sym(ctx, ctx->relocsym[i], 0,
315 PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
316
317#if LJ_TARGET_X64
318 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA);
319 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA);
320 emit_peobj_sym(ctx, "lj_err_unwind_win64", 0,
321 PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
322#endif
323
324 emit_peobj_sym(ctx, ctx->beginsym, 0,
325 PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN);
326 for (i = 0; i < ctx->nsym; i++)
327 emit_peobj_sym(ctx, ctx->sym[i].name, (uint32_t)ctx->sym[i].ofs,
328 PEOBJ_SECT_TEXT, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
329
330 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_RDATA_Z);
331
332 if (strtab)
333 break;
334 /* 2nd pass: alloc strtab, write syms and copy strings. */
335 strtab = (char *)malloc(strtabofs);
336 *(uint32_t *)strtab = (uint32_t)strtabofs;
337 }
338
339 /* Write string table. */
340 owrite(ctx, strtab, strtabofs);
341}
342
343#else
344
345void emit_peobj(BuildCtx *ctx)
346{
347 UNUSED(ctx);
348 fprintf(stderr, "Error: no PE object support for this target\n");
349 exit(1);
350}
351
352#endif
diff --git a/libraries/luajit-2.0/src/buildvm_ppc.dasc b/libraries/luajit-2.0/src/buildvm_ppc.dasc
new file mode 100644
index 0000000..c26f392
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_ppc.dasc
@@ -0,0 +1,4873 @@
1|// Low-level VM code for PowerPC CPUs.
2|// Bytecode interpreter, fast functions and helper functions.
3|// Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4|
5|.arch ppc
6|.section code_op, code_sub
7|
8|.actionlist build_actionlist
9|.globals GLOB_
10|.globalnames globnames
11|.externnames extnames
12|
13|// Note: The ragged indentation of the instructions is intentional.
14|// The starting columns indicate data dependencies.
15|
16|//-----------------------------------------------------------------------
17|
18|// Fixed register assignments for the interpreter.
19|// Don't use: r1 = sp, r2 and r13 = reserved (TOC, TLS or SDATA)
20|
21|// The following must be C callee-save (but BASE is often refetched).
22|.define BASE, r14 // Base of current Lua stack frame.
23|.define KBASE, r15 // Constants of current Lua function.
24|.define PC, r16 // Next PC.
25|.define DISPATCH, r17 // Opcode dispatch table.
26|.define LREG, r18 // Register holding lua_State (also in SAVE_L).
27|.define MULTRES, r19 // Size of multi-result: (nresults+1)*8.
28|.define JGL, r31 // On-trace: global_State + 32768.
29|
30|// Constants for type-comparisons, stores and conversions. C callee-save.
31|.define TISNUM, r22
32|.define TISNIL, r23
33|.define ZERO, r24
34|.define TOBIT, f30 // 2^52 + 2^51.
35|.define TONUM, f31 // 2^52 + 2^51 + 2^31.
36|
37|// The following temporaries are not saved across C calls, except for RA.
38|.define RA, r20 // Callee-save.
39|.define RB, r10
40|.define RC, r11
41|.define RD, r12
42|.define INS, r7 // Overlaps CARG5.
43|
44|.define TMP0, r0
45|.define TMP1, r8
46|.define TMP2, r9
47|.define TMP3, r6 // Overlaps CARG4.
48|
49|// Saved temporaries.
50|.define SAVE0, r21
51|
52|// Calling conventions.
53|.define CARG1, r3
54|.define CARG2, r4
55|.define CARG3, r5
56|.define CARG4, r6 // Overlaps TMP3.
57|.define CARG5, r7 // Overlaps INS.
58|
59|.define FARG1, f1
60|.define FARG2, f2
61|
62|.define CRET1, r3
63|.define CRET2, r4
64|
65|// Stack layout while in interpreter. Must match with lj_frame.h.
66|.define SAVE_LR, 276(sp)
67|.define CFRAME_SPACE, 272 // Delta for sp.
68|// Back chain for sp: 272(sp) <-- sp entering interpreter
69|.define SAVE_FPR_, 128 // .. 128+18*8: 64 bit FPR saves.
70|.define SAVE_GPR_, 56 // .. 56+18*4: 32 bit GPR saves.
71|.define SAVE_CR, 52(sp) // 32 bit CR save.
72|.define SAVE_ERRF, 48(sp) // 32 bit C frame info.
73|.define SAVE_NRES, 44(sp)
74|.define SAVE_CFRAME, 40(sp)
75|.define SAVE_L, 36(sp)
76|.define SAVE_PC, 32(sp)
77|.define SAVE_MULTRES, 28(sp)
78|.define UNUSED1, 24(sp)
79|.define TMPD_LO, 20(sp)
80|.define TMPD_HI, 16(sp)
81|.define TONUM_LO, 12(sp)
82|.define TONUM_HI, 8(sp)
83|// Next frame lr: 4(sp)
84|// Back chain for sp: 0(sp) <-- sp while in interpreter
85|
86|.define TMPD_BLO, 23(sp)
87|.define TMPD, TMPD_HI
88|.define TONUM_D, TONUM_HI
89|
90|.macro save_, reg
91| stw r..reg, SAVE_GPR_+(reg-14)*4(sp)
92| stfd f..reg, SAVE_FPR_+(reg-14)*8(sp)
93|.endmacro
94|.macro rest_, reg
95| lwz r..reg, SAVE_GPR_+(reg-14)*4(sp)
96| lfd f..reg, SAVE_FPR_+(reg-14)*8(sp)
97|.endmacro
98|
99|.macro saveregs
100| stwu sp, -CFRAME_SPACE(sp)
101| save_ 14; save_ 15; save_ 16
102| mflr r0
103| save_ 17; save_ 18; save_ 19; save_ 20; save_ 21; save_ 22
104| stw r0, SAVE_LR
105| save_ 23; save_ 24; save_ 25
106| mfcr r0
107| save_ 26; save_ 27; save_ 28; save_ 29; save_ 30; save_ 31
108| stw r0, SAVE_CR
109|.endmacro
110|
111|.macro restoreregs
112| lwz r0, SAVE_LR; lwz r12, SAVE_CR
113| rest_ 14; rest_ 15; rest_ 16; rest_ 17; rest_ 18; rest_ 19
114| mtlr r0; mtcrf 0x38, r12
115| rest_ 20; rest_ 21; rest_ 22; rest_ 23; rest_ 24; rest_ 25
116| rest_ 26; rest_ 27; rest_ 28; rest_ 29; rest_ 30; rest_ 31
117| addi sp, sp, CFRAME_SPACE
118|.endmacro
119|
120|// Type definitions. Some of these are only used for documentation.
121|.type L, lua_State, LREG
122|.type GL, global_State
123|.type TVALUE, TValue
124|.type GCOBJ, GCobj
125|.type STR, GCstr
126|.type TAB, GCtab
127|.type LFUNC, GCfuncL
128|.type CFUNC, GCfuncC
129|.type PROTO, GCproto
130|.type UPVAL, GCupval
131|.type NODE, Node
132|.type NARGS8, int
133|.type TRACE, GCtrace
134|
135|//-----------------------------------------------------------------------
136|
137|// These basic macros should really be part of DynASM.
138|.macro srwi, rx, ry, n; rlwinm rx, ry, 32-n, n, 31; .endmacro
139|.macro slwi, rx, ry, n; rlwinm rx, ry, n, 0, 31-n; .endmacro
140|.macro rotlwi, rx, ry, n; rlwinm rx, ry, n, 0, 31; .endmacro
141|.macro rotlw, rx, ry, rn; rlwnm rx, ry, rn, 0, 31; .endmacro
142|.macro subi, rx, ry, i; addi rx, ry, -i; .endmacro
143|
144|// Trap for not-yet-implemented parts.
145|.macro NYI; tw 4, sp, sp; .endmacro
146|
147|// int/FP conversions.
148|.macro tonum_i, freg, reg
149| xoris reg, reg, 0x8000
150| stw reg, TONUM_LO
151| lfd freg, TONUM_D
152| fsub freg, freg, TONUM
153|.endmacro
154|
155|.macro tonum_u, freg, reg
156| stw reg, TONUM_LO
157| lfd freg, TONUM_D
158| fsub freg, freg, TOBIT
159|.endmacro
160|
161|.macro toint, reg, freg, tmpfreg
162| fctiwz tmpfreg, freg
163| stfd tmpfreg, TMPD
164| lwz reg, TMPD_LO
165|.endmacro
166|
167|.macro toint, reg, freg
168| toint reg, freg, freg
169|.endmacro
170|
171|//-----------------------------------------------------------------------
172|
173|// Access to frame relative to BASE.
174|.define FRAME_PC, -8
175|.define FRAME_FUNC, -4
176|
177|// Instruction decode.
178|.macro decode_OP4, dst, ins; rlwinm dst, ins, 2, 22, 29; .endmacro
179|.macro decode_RA8, dst, ins; rlwinm dst, ins, 27, 21, 28; .endmacro
180|.macro decode_RB8, dst, ins; rlwinm dst, ins, 11, 21, 28; .endmacro
181|.macro decode_RC8, dst, ins; rlwinm dst, ins, 19, 21, 28; .endmacro
182|.macro decode_RD8, dst, ins; rlwinm dst, ins, 19, 13, 28; .endmacro
183|
184|.macro decode_OP1, dst, ins; rlwinm dst, ins, 0, 24, 31; .endmacro
185|.macro decode_RD4, dst, ins; rlwinm dst, ins, 18, 14, 29; .endmacro
186|
187|// Instruction fetch.
188|.macro ins_NEXT1
189| lwz INS, 0(PC)
190| addi PC, PC, 4
191|.endmacro
192|// Instruction decode+dispatch. Note: optimized for e300!
193|.macro ins_NEXT2
194| decode_OP4 TMP1, INS
195| lwzx TMP0, DISPATCH, TMP1
196| mtctr TMP0
197| decode_RB8 RB, INS
198| decode_RD8 RD, INS
199| decode_RA8 RA, INS
200| decode_RC8 RC, INS
201| bctr
202|.endmacro
203|.macro ins_NEXT
204| ins_NEXT1
205| ins_NEXT2
206|.endmacro
207|
208|// Instruction footer.
209|.if 1
210| // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
211| .define ins_next, ins_NEXT
212| .define ins_next_, ins_NEXT
213| .define ins_next1, ins_NEXT1
214| .define ins_next2, ins_NEXT2
215|.else
216| // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
217| // Affects only certain kinds of benchmarks (and only with -j off).
218| .macro ins_next
219| b ->ins_next
220| .endmacro
221| .macro ins_next1
222| .endmacro
223| .macro ins_next2
224| b ->ins_next
225| .endmacro
226| .macro ins_next_
227| ->ins_next:
228| ins_NEXT
229| .endmacro
230|.endif
231|
232|// Call decode and dispatch.
233|.macro ins_callt
234| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
235| lwz PC, LFUNC:RB->pc
236| lwz INS, 0(PC)
237| addi PC, PC, 4
238| decode_OP4 TMP1, INS
239| decode_RA8 RA, INS
240| lwzx TMP0, DISPATCH, TMP1
241| add RA, RA, BASE
242| mtctr TMP0
243| bctr
244|.endmacro
245|
246|.macro ins_call
247| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, PC = caller PC
248| stw PC, FRAME_PC(BASE)
249| ins_callt
250|.endmacro
251|
252|//-----------------------------------------------------------------------
253|
254|// Macros to test operand types.
255|.macro checknum, reg; cmplw reg, TISNUM; .endmacro
256|.macro checknum, cr, reg; cmplw cr, reg, TISNUM; .endmacro
257|.macro checkstr, reg; cmpwi reg, LJ_TSTR; .endmacro
258|.macro checktab, reg; cmpwi reg, LJ_TTAB; .endmacro
259|.macro checkfunc, reg; cmpwi reg, LJ_TFUNC; .endmacro
260|.macro checknil, reg; cmpwi reg, LJ_TNIL; .endmacro
261|
262|.macro branch_RD
263| srwi TMP0, RD, 1
264| addis PC, PC, -(BCBIAS_J*4 >> 16)
265| add PC, PC, TMP0
266|.endmacro
267|
268|// Assumes DISPATCH is relative to GL.
269#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
270#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
271|
272#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
273|
274|.macro hotcheck, delta, target
275| rlwinm TMP1, PC, 31, 25, 30
276| addi TMP1, TMP1, GG_DISP2HOT
277| lhzx TMP2, DISPATCH, TMP1
278| addic. TMP2, TMP2, -delta
279| sthx TMP2, DISPATCH, TMP1
280| blt target
281|.endmacro
282|
283|.macro hotloop
284| hotcheck HOTCOUNT_LOOP, ->vm_hotloop
285|.endmacro
286|
287|.macro hotcall
288| hotcheck HOTCOUNT_CALL, ->vm_hotcall
289|.endmacro
290|
291|// Set current VM state. Uses TMP0.
292|.macro li_vmstate, st; li TMP0, ~LJ_VMST_..st; .endmacro
293|.macro st_vmstate; stw TMP0, DISPATCH_GL(vmstate)(DISPATCH); .endmacro
294|
295|// Move table write barrier back. Overwrites mark and tmp.
296|.macro barrierback, tab, mark, tmp
297| lwz tmp, DISPATCH_GL(gc.grayagain)(DISPATCH)
298| // Assumes LJ_GC_BLACK is 0x04.
299| rlwinm mark, mark, 0, 30, 28 // black2gray(tab)
300| stw tab, DISPATCH_GL(gc.grayagain)(DISPATCH)
301| stb mark, tab->marked
302| stw tmp, tab->gclist
303|.endmacro
304|
305|//-----------------------------------------------------------------------
306
307/* Generate subroutines used by opcodes and other parts of the VM. */
308/* The .code_sub section should be last to help static branch prediction. */
309static void build_subroutines(BuildCtx *ctx)
310{
311 |.code_sub
312 |
313 |//-----------------------------------------------------------------------
314 |//-- Return handling ----------------------------------------------------
315 |//-----------------------------------------------------------------------
316 |
317 |->vm_returnp:
318 | // See vm_return. Also: TMP2 = previous base.
319 | andi. TMP0, PC, FRAME_P
320 | li TMP1, LJ_TTRUE
321 | beq ->cont_dispatch
322 |
323 | // Return from pcall or xpcall fast func.
324 | lwz PC, FRAME_PC(TMP2) // Fetch PC of previous frame.
325 | mr BASE, TMP2 // Restore caller base.
326 | // Prepending may overwrite the pcall frame, so do it at the end.
327 | stwu TMP1, FRAME_PC(RA) // Prepend true to results.
328 |
329 |->vm_returnc:
330 | andi. TMP0, PC, FRAME_TYPE
331 | addi RD, RD, 8 // RD = (nresults+1)*8.
332 | mr MULTRES, RD
333 | beq ->BC_RET_Z // Handle regular return to Lua.
334 |
335 |->vm_return:
336 | // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return
337 | // TMP0 = PC & FRAME_TYPE
338 | cmpwi TMP0, FRAME_C
339 | rlwinm TMP2, PC, 0, 0, 28
340 | li_vmstate C
341 | sub TMP2, BASE, TMP2 // TMP2 = previous base.
342 | bney ->vm_returnp
343 |
344 | addic. TMP1, RD, -8
345 | stw TMP2, L->base
346 | lwz TMP2, SAVE_NRES
347 | subi BASE, BASE, 8
348 | st_vmstate
349 | slwi TMP2, TMP2, 3
350 | beq >2
351 |1:
352 | addic. TMP1, TMP1, -8
353 | lfd f0, 0(RA)
354 | addi RA, RA, 8
355 | stfd f0, 0(BASE)
356 | addi BASE, BASE, 8
357 | bney <1
358 |
359 |2:
360 | cmpw TMP2, RD // More/less results wanted?
361 | bne >6
362 |3:
363 | stw BASE, L->top // Store new top.
364 |
365 |->vm_leave_cp:
366 | lwz TMP0, SAVE_CFRAME // Restore previous C frame.
367 | li CRET1, 0 // Ok return status for vm_pcall.
368 | stw TMP0, L->cframe
369 |
370 |->vm_leave_unw:
371 | restoreregs
372 | blr
373 |
374 |6:
375 | ble >7 // Less results wanted?
376 | // More results wanted. Check stack size and fill up results with nil.
377 | lwz TMP1, L->maxstack
378 | cmplw BASE, TMP1
379 | bge >8
380 | stw TISNIL, 0(BASE)
381 | addi RD, RD, 8
382 | addi BASE, BASE, 8
383 | b <2
384 |
385 |7: // Less results wanted.
386 | subfic TMP3, TMP2, 0 // LUA_MULTRET+1 case?
387 | sub TMP0, RD, TMP2
388 | subfe TMP1, TMP1, TMP1 // TMP1 = TMP2 == 0 ? 0 : -1
389 | and TMP0, TMP0, TMP1
390 | sub BASE, BASE, TMP0 // Either keep top or shrink it.
391 | b <3
392 |
393 |8: // Corner case: need to grow stack for filling up results.
394 | // This can happen if:
395 | // - A C function grows the stack (a lot).
396 | // - The GC shrinks the stack in between.
397 | // - A return back from a lua_call() with (high) nresults adjustment.
398 | stw BASE, L->top // Save current top held in BASE (yes).
399 | mr SAVE0, RD
400 | mr CARG2, TMP2
401 | mr CARG1, L
402 | bl extern lj_state_growstack // (lua_State *L, int n)
403 | lwz TMP2, SAVE_NRES
404 | mr RD, SAVE0
405 | slwi TMP2, TMP2, 3
406 | lwz BASE, L->top // Need the (realloced) L->top in BASE.
407 | b <2
408 |
409 |->vm_unwind_c: // Unwind C stack, return from vm_pcall.
410 | // (void *cframe, int errcode)
411 | mr sp, CARG1
412 | mr CRET1, CARG2
413 |->vm_unwind_c_eh: // Landing pad for external unwinder.
414 | lwz L, SAVE_L
415 | li TMP0, ~LJ_VMST_C
416 | lwz GL:TMP1, L->glref
417 | stw TMP0, GL:TMP1->vmstate
418 | b ->vm_leave_unw
419 |
420 |->vm_unwind_ff: // Unwind C stack, return from ff pcall.
421 | // (void *cframe)
422 | rlwinm sp, CARG1, 0, 0, 29
423 |->vm_unwind_ff_eh: // Landing pad for external unwinder.
424 | lwz L, SAVE_L
425 | li TISNUM, LJ_TISNUM // Setup type comparison constants.
426 | lwz BASE, L->base
427 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
428 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
429 | li ZERO, 0
430 | stw TMP3, TMPD
431 | li TMP1, LJ_TFALSE
432 | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float).
433 | li TISNIL, LJ_TNIL
434 | li_vmstate INTERP
435 | lfs TOBIT, TMPD
436 | lwz PC, FRAME_PC(BASE) // Fetch PC of previous frame.
437 | la RA, -8(BASE) // Results start at BASE-8.
438 | stw TMP3, TMPD
439 | addi DISPATCH, DISPATCH, GG_G2DISP
440 | stw TMP1, 0(RA) // Prepend false to error message.
441 | li RD, 16 // 2 results: false + error message.
442 | st_vmstate
443 | lfs TONUM, TMPD
444 | b ->vm_returnc
445 |
446 |//-----------------------------------------------------------------------
447 |//-- Grow stack for calls -----------------------------------------------
448 |//-----------------------------------------------------------------------
449 |
450 |->vm_growstack_c: // Grow stack for C function.
451 | li CARG2, LUA_MINSTACK
452 | b >2
453 |
454 |->vm_growstack_l: // Grow stack for Lua function.
455 | // BASE = new base, RA = BASE+framesize*8, RC = nargs*8, PC = first PC
456 | add RC, BASE, RC
457 | sub RA, RA, BASE
458 | stw BASE, L->base
459 | addi PC, PC, 4 // Must point after first instruction.
460 | stw RC, L->top
461 | srwi CARG2, RA, 3
462 |2:
463 | // L->base = new base, L->top = top
464 | stw PC, SAVE_PC
465 | mr CARG1, L
466 | bl extern lj_state_growstack // (lua_State *L, int n)
467 | lwz BASE, L->base
468 | lwz RC, L->top
469 | lwz LFUNC:RB, FRAME_FUNC(BASE)
470 | sub RC, RC, BASE
471 | // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
472 | ins_callt // Just retry the call.
473 |
474 |//-----------------------------------------------------------------------
475 |//-- Entry points into the assembler VM ---------------------------------
476 |//-----------------------------------------------------------------------
477 |
478 |->vm_resume: // Setup C frame and resume thread.
479 | // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
480 | saveregs
481 | mr L, CARG1
482 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
483 | mr BASE, CARG2
484 | lbz TMP1, L->status
485 | stw L, SAVE_L
486 | li PC, FRAME_CP
487 | addi TMP0, sp, CFRAME_RESUME
488 | addi DISPATCH, DISPATCH, GG_G2DISP
489 | stw CARG3, SAVE_NRES
490 | cmplwi TMP1, 0
491 | stw CARG3, SAVE_ERRF
492 | stw TMP0, L->cframe
493 | stw CARG3, SAVE_CFRAME
494 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
495 | beq >3
496 |
497 | // Resume after yield (like a return).
498 | mr RA, BASE
499 | lwz BASE, L->base
500 | li TISNUM, LJ_TISNUM // Setup type comparison constants.
501 | lwz TMP1, L->top
502 | lwz PC, FRAME_PC(BASE)
503 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
504 | sub RD, TMP1, BASE
505 | stb CARG3, L->status
506 | stw TMP3, TMPD
507 | andi. TMP0, PC, FRAME_TYPE
508 | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float).
509 | lfs TOBIT, TMPD
510 | li ZERO, 0
511 | stw TMP3, TMPD
512 | addi RD, RD, 8
513 | lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double)
514 | mr MULTRES, RD
515 | stw TMP0, TONUM_HI
516 | li_vmstate INTERP
517 | lfs TONUM, TMPD
518 | li TISNIL, LJ_TNIL
519 | st_vmstate
520 | beq ->BC_RET_Z
521 | b ->vm_return
522 |
523 |->vm_pcall: // Setup protected C frame and enter VM.
524 | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
525 | saveregs
526 | li PC, FRAME_CP
527 | stw CARG4, SAVE_ERRF
528 | b >1
529 |
530 |->vm_call: // Setup C frame and enter VM.
531 | // (lua_State *L, TValue *base, int nres1)
532 | saveregs
533 | li PC, FRAME_C
534 |
535 |1: // Entry point for vm_pcall above (PC = ftype).
536 | lwz TMP1, L:CARG1->cframe
537 | stw CARG3, SAVE_NRES
538 | mr L, CARG1
539 | stw CARG1, SAVE_L
540 | mr BASE, CARG2
541 | stw sp, L->cframe // Add our C frame to cframe chain.
542 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
543 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
544 | stw TMP1, SAVE_CFRAME
545 | addi DISPATCH, DISPATCH, GG_G2DISP
546 |
547 |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
548 | lwz TMP2, L->base // TMP2 = old base (used in vmeta_call).
549 | li TISNUM, LJ_TISNUM // Setup type comparison constants.
550 | lwz TMP1, L->top
551 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
552 | add PC, PC, BASE
553 | stw TMP3, TMPD
554 | li ZERO, 0
555 | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float).
556 | lfs TOBIT, TMPD
557 | sub PC, PC, TMP2 // PC = frame delta + frame type
558 | stw TMP3, TMPD
559 | lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double)
560 | sub NARGS8:RC, TMP1, BASE
561 | stw TMP0, TONUM_HI
562 | li_vmstate INTERP
563 | lfs TONUM, TMPD
564 | li TISNIL, LJ_TNIL
565 | st_vmstate
566 |
567 |->vm_call_dispatch:
568 | // TMP2 = old base, BASE = new base, RC = nargs*8, PC = caller PC
569 | lwz TMP0, FRAME_PC(BASE)
570 | lwz LFUNC:RB, FRAME_FUNC(BASE)
571 | checkfunc TMP0; bne ->vmeta_call
572 |
573 |->vm_call_dispatch_f:
574 | ins_call
575 | // BASE = new base, RB = func, RC = nargs*8, PC = caller PC
576 |
577 |->vm_cpcall: // Setup protected C frame, call C.
578 | // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
579 | saveregs
580 | mr L, CARG1
581 | lwz TMP0, L:CARG1->stack
582 | stw CARG1, SAVE_L
583 | lwz TMP1, L->top
584 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
585 | sub TMP0, TMP0, TMP1 // Compute -savestack(L, L->top).
586 | lwz TMP1, L->cframe
587 | stw sp, L->cframe // Add our C frame to cframe chain.
588 | li TMP2, 0
589 | stw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame.
590 | stw TMP2, SAVE_ERRF // No error function.
591 | stw TMP1, SAVE_CFRAME
592 | mtctr CARG4
593 | bctrl // (lua_State *L, lua_CFunction func, void *ud)
594 | mr. BASE, CRET1
595 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
596 | li PC, FRAME_CP
597 | addi DISPATCH, DISPATCH, GG_G2DISP
598 | bne <3 // Else continue with the call.
599 | b ->vm_leave_cp // No base? Just remove C frame.
600 |
601 |//-----------------------------------------------------------------------
602 |//-- Metamethod handling ------------------------------------------------
603 |//-----------------------------------------------------------------------
604 |
605 |// The lj_meta_* functions (except for lj_meta_cat) don't reallocate the
606 |// stack, so BASE doesn't need to be reloaded across these calls.
607 |
608 |//-- Continuation dispatch ----------------------------------------------
609 |
610 |->cont_dispatch:
611 | // BASE = meta base, RA = resultptr, RD = (nresults+1)*8
612 | lwz TMP0, -12(BASE) // Continuation.
613 | mr RB, BASE
614 | mr BASE, TMP2 // Restore caller BASE.
615 | lwz LFUNC:TMP1, FRAME_FUNC(TMP2)
616#if LJ_HASFFI
617 | cmplwi TMP0, 1
618#endif
619 | lwz PC, -16(RB) // Restore PC from [cont|PC].
620 | subi TMP2, RD, 8
621 | lwz TMP1, LFUNC:TMP1->pc
622 | stwx TISNIL, RA, TMP2 // Ensure one valid arg.
623#if LJ_HASFFI
624 | ble >1
625#endif
626 | lwz KBASE, PC2PROTO(k)(TMP1)
627 | // BASE = base, RA = resultptr, RB = meta base
628 | mtctr TMP0
629 | bctr // Jump to continuation.
630 |
631#if LJ_HASFFI
632 |1:
633 | beq ->cont_ffi_callback // cont = 1: return from FFI callback.
634 | // cont = 0: tailcall from C function.
635 | subi TMP1, RB, 16
636 | sub RC, TMP1, BASE
637 | b ->vm_call_tail
638#endif
639 |
640 |->cont_cat: // RA = resultptr, RB = meta base
641 | lwz INS, -4(PC)
642 | subi CARG2, RB, 16
643 | decode_RB8 SAVE0, INS
644 | lfd f0, 0(RA)
645 | add TMP1, BASE, SAVE0
646 | stw BASE, L->base
647 | cmplw TMP1, CARG2
648 | sub CARG3, CARG2, TMP1
649 | decode_RA8 RA, INS
650 | stfd f0, 0(CARG2)
651 | bney ->BC_CAT_Z
652 | stfdx f0, BASE, RA
653 | b ->cont_nop
654 |
655 |//-- Table indexing metamethods -----------------------------------------
656 |
657 |->vmeta_tgets1:
658 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
659 | li TMP0, LJ_TSTR
660 | decode_RB8 RB, INS
661 | stw STR:RC, 4(CARG3)
662 | add CARG2, BASE, RB
663 | stw TMP0, 0(CARG3)
664 | b >1
665 |
666 |->vmeta_tgets:
667 | la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
668 | li TMP0, LJ_TTAB
669 | stw TAB:RB, 4(CARG2)
670 | la CARG3, DISPATCH_GL(tmptv2)(DISPATCH)
671 | stw TMP0, 0(CARG2)
672 | li TMP1, LJ_TSTR
673 | stw STR:RC, 4(CARG3)
674 | stw TMP1, 0(CARG3)
675 | b >1
676 |
677 |->vmeta_tgetb: // TMP0 = index
678 if (!LJ_DUALNUM) {
679 | tonum_u f0, TMP0
680 }
681 | decode_RB8 RB, INS
682 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
683 | add CARG2, BASE, RB
684 if (LJ_DUALNUM) {
685 | stw TISNUM, 0(CARG3)
686 | stw TMP0, 4(CARG3)
687 } else {
688 | stfd f0, 0(CARG3)
689 }
690 | b >1
691 |
692 |->vmeta_tgetv:
693 | decode_RB8 RB, INS
694 | decode_RC8 RC, INS
695 | add CARG2, BASE, RB
696 | add CARG3, BASE, RC
697 |1:
698 | stw BASE, L->base
699 | mr CARG1, L
700 | stw PC, SAVE_PC
701 | bl extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
702 | // Returns TValue * (finished) or NULL (metamethod).
703 | cmplwi CRET1, 0
704 | beq >3
705 | lfd f0, 0(CRET1)
706 | ins_next1
707 | stfdx f0, BASE, RA
708 | ins_next2
709 |
710 |3: // Call __index metamethod.
711 | // BASE = base, L->top = new base, stack = cont/func/t/k
712 | subfic TMP1, BASE, FRAME_CONT
713 | lwz BASE, L->top
714 | stw PC, -16(BASE) // [cont|PC]
715 | add PC, TMP1, BASE
716 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
717 | li NARGS8:RC, 16 // 2 args for func(t, k).
718 | b ->vm_call_dispatch_f
719 |
720 |//-----------------------------------------------------------------------
721 |
722 |->vmeta_tsets1:
723 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
724 | li TMP0, LJ_TSTR
725 | decode_RB8 RB, INS
726 | stw STR:RC, 4(CARG3)
727 | add CARG2, BASE, RB
728 | stw TMP0, 0(CARG3)
729 | b >1
730 |
731 |->vmeta_tsets:
732 | la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
733 | li TMP0, LJ_TTAB
734 | stw TAB:RB, 4(CARG2)
735 | la CARG3, DISPATCH_GL(tmptv2)(DISPATCH)
736 | stw TMP0, 0(CARG2)
737 | li TMP1, LJ_TSTR
738 | stw STR:RC, 4(CARG3)
739 | stw TMP1, 0(CARG3)
740 | b >1
741 |
742 |->vmeta_tsetb: // TMP0 = index
743 if (!LJ_DUALNUM) {
744 | tonum_u f0, TMP0
745 }
746 | decode_RB8 RB, INS
747 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
748 | add CARG2, BASE, RB
749 if (LJ_DUALNUM) {
750 | stw TISNUM, 0(CARG3)
751 | stw TMP0, 4(CARG3)
752 } else {
753 | stfd f0, 0(CARG3)
754 }
755 | b >1
756 |
757 |->vmeta_tsetv:
758 | decode_RB8 RB, INS
759 | decode_RC8 RC, INS
760 | add CARG2, BASE, RB
761 | add CARG3, BASE, RC
762 |1:
763 | stw BASE, L->base
764 | mr CARG1, L
765 | stw PC, SAVE_PC
766 | bl extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
767 | // Returns TValue * (finished) or NULL (metamethod).
768 | cmplwi CRET1, 0
769 | lfdx f0, BASE, RA
770 | beq >3
771 | // NOBARRIER: lj_meta_tset ensures the table is not black.
772 | ins_next1
773 | stfd f0, 0(CRET1)
774 | ins_next2
775 |
776 |3: // Call __newindex metamethod.
777 | // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
778 | subfic TMP1, BASE, FRAME_CONT
779 | lwz BASE, L->top
780 | stw PC, -16(BASE) // [cont|PC]
781 | add PC, TMP1, BASE
782 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
783 | li NARGS8:RC, 24 // 3 args for func(t, k, v)
784 | stfd f0, 16(BASE) // Copy value to third argument.
785 | b ->vm_call_dispatch_f
786 |
787 |//-- Comparison metamethods ---------------------------------------------
788 |
789 |->vmeta_comp:
790 | mr CARG1, L
791 | subi PC, PC, 4
792 if (LJ_DUALNUM) {
793 | mr CARG2, RA
794 } else {
795 | add CARG2, BASE, RA
796 }
797 | stw PC, SAVE_PC
798 if (LJ_DUALNUM) {
799 | mr CARG3, RD
800 } else {
801 | add CARG3, BASE, RD
802 }
803 | stw BASE, L->base
804 | decode_OP1 CARG4, INS
805 | bl extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
806 | // Returns 0/1 or TValue * (metamethod).
807 |3:
808 | cmplwi CRET1, 1
809 | bgt ->vmeta_binop
810 | subfic CRET1, CRET1, 0
811 |4:
812 | lwz INS, 0(PC)
813 | addi PC, PC, 4
814 | decode_RD4 TMP2, INS
815 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
816 | and TMP2, TMP2, CRET1
817 | add PC, PC, TMP2
818 |->cont_nop:
819 | ins_next
820 |
821 |->cont_ra: // RA = resultptr
822 | lwz INS, -4(PC)
823 | lfd f0, 0(RA)
824 | decode_RA8 TMP1, INS
825 | stfdx f0, BASE, TMP1
826 | b ->cont_nop
827 |
828 |->cont_condt: // RA = resultptr
829 | lwz TMP0, 0(RA)
830 | subfic TMP0, TMP0, LJ_TTRUE // Branch if result is true.
831 | subfe CRET1, CRET1, CRET1
832 | not CRET1, CRET1
833 | b <4
834 |
835 |->cont_condf: // RA = resultptr
836 | lwz TMP0, 0(RA)
837 | subfic TMP0, TMP0, LJ_TTRUE // Branch if result is false.
838 | subfe CRET1, CRET1, CRET1
839 | b <4
840 |
841 |->vmeta_equal:
842 | // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV.
843 | subi PC, PC, 4
844 | stw BASE, L->base
845 | mr CARG1, L
846 | stw PC, SAVE_PC
847 | bl extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
848 | // Returns 0/1 or TValue * (metamethod).
849 | b <3
850 |
851 |->vmeta_equal_cd:
852#if LJ_HASFFI
853 | mr CARG2, INS
854 | subi PC, PC, 4
855 | stw BASE, L->base
856 | mr CARG1, L
857 | stw PC, SAVE_PC
858 | bl extern lj_meta_equal_cd // (lua_State *L, BCIns op)
859 | // Returns 0/1 or TValue * (metamethod).
860 | b <3
861#endif
862 |
863 |//-- Arithmetic metamethods ---------------------------------------------
864 |
865 |->vmeta_arith_nv:
866 | add CARG3, KBASE, RC
867 | add CARG4, BASE, RB
868 | b >1
869 |->vmeta_arith_nv2:
870 if (LJ_DUALNUM) {
871 | mr CARG3, RC
872 | mr CARG4, RB
873 | b >1
874 }
875 |
876 |->vmeta_unm:
877 | mr CARG3, RD
878 | mr CARG4, RD
879 | b >1
880 |
881 |->vmeta_arith_vn:
882 | add CARG3, BASE, RB
883 | add CARG4, KBASE, RC
884 | b >1
885 |
886 |->vmeta_arith_vv:
887 | add CARG3, BASE, RB
888 | add CARG4, BASE, RC
889 if (LJ_DUALNUM) {
890 | b >1
891 }
892 |->vmeta_arith_vn2:
893 |->vmeta_arith_vv2:
894 if (LJ_DUALNUM) {
895 | mr CARG3, RB
896 | mr CARG4, RC
897 }
898 |1:
899 | add CARG2, BASE, RA
900 | stw BASE, L->base
901 | mr CARG1, L
902 | stw PC, SAVE_PC
903 | decode_OP1 CARG5, INS // Caveat: CARG5 overlaps INS.
904 | bl extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
905 | // Returns NULL (finished) or TValue * (metamethod).
906 | cmplwi CRET1, 0
907 | beq ->cont_nop
908 |
909 | // Call metamethod for binary op.
910 |->vmeta_binop:
911 | // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2
912 | sub TMP1, CRET1, BASE
913 | stw PC, -16(CRET1) // [cont|PC]
914 | mr TMP2, BASE
915 | addi PC, TMP1, FRAME_CONT
916 | mr BASE, CRET1
917 | li NARGS8:RC, 16 // 2 args for func(o1, o2).
918 | b ->vm_call_dispatch
919 |
920 |->vmeta_len:
921#ifdef LUAJIT_ENABLE_LUA52COMPAT
922 | mr SAVE0, CARG1
923#endif
924 | mr CARG2, RD
925 | stw BASE, L->base
926 | mr CARG1, L
927 | stw PC, SAVE_PC
928 | bl extern lj_meta_len // (lua_State *L, TValue *o)
929 | // Returns NULL (retry) or TValue * (metamethod base).
930#ifdef LUAJIT_ENABLE_LUA52COMPAT
931 | cmplwi CRET1, 0
932 | bne ->vmeta_binop // Binop call for compatibility.
933 | mr CARG1, SAVE0
934 | b ->BC_LEN_Z
935#else
936 | b ->vmeta_binop // Binop call for compatibility.
937#endif
938 |
939 |//-- Call metamethod ----------------------------------------------------
940 |
941 |->vmeta_call: // Resolve and call __call metamethod.
942 | // TMP2 = old base, BASE = new base, RC = nargs*8
943 | mr CARG1, L
944 | stw TMP2, L->base // This is the callers base!
945 | subi CARG2, BASE, 8
946 | stw PC, SAVE_PC
947 | add CARG3, BASE, RC
948 | mr SAVE0, NARGS8:RC
949 | bl extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
950 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
951 | addi NARGS8:RC, SAVE0, 8 // Got one more argument now.
952 | ins_call
953 |
954 |->vmeta_callt: // Resolve __call for BC_CALLT.
955 | // BASE = old base, RA = new base, RC = nargs*8
956 | mr CARG1, L
957 | stw BASE, L->base
958 | subi CARG2, RA, 8
959 | stw PC, SAVE_PC
960 | add CARG3, RA, RC
961 | mr SAVE0, NARGS8:RC
962 | bl extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
963 | lwz TMP1, FRAME_PC(BASE)
964 | addi NARGS8:RC, SAVE0, 8 // Got one more argument now.
965 | lwz LFUNC:RB, FRAME_FUNC(RA) // Guaranteed to be a function here.
966 | b ->BC_CALLT_Z
967 |
968 |//-- Argument coercion for 'for' statement ------------------------------
969 |
970 |->vmeta_for:
971 | mr CARG1, L
972 | stw BASE, L->base
973 | mr CARG2, RA
974 | stw PC, SAVE_PC
975 | mr SAVE0, INS
976 | bl extern lj_meta_for // (lua_State *L, TValue *base)
977#if LJ_HASJIT
978 | decode_OP1 TMP0, SAVE0
979#endif
980 | decode_RA8 RA, SAVE0
981#if LJ_HASJIT
982 | cmpwi TMP0, BC_JFORI
983#endif
984 | decode_RD8 RD, SAVE0
985#if LJ_HASJIT
986 | beqy =>BC_JFORI
987#endif
988 | b =>BC_FORI
989 |
990 |//-----------------------------------------------------------------------
991 |//-- Fast functions -----------------------------------------------------
992 |//-----------------------------------------------------------------------
993 |
994 |.macro .ffunc, name
995 |->ff_ .. name:
996 |.endmacro
997 |
998 |.macro .ffunc_1, name
999 |->ff_ .. name:
1000 | cmplwi NARGS8:RC, 8
1001 | lwz CARG3, 0(BASE)
1002 | lwz CARG1, 4(BASE)
1003 | blt ->fff_fallback
1004 |.endmacro
1005 |
1006 |.macro .ffunc_2, name
1007 |->ff_ .. name:
1008 | cmplwi NARGS8:RC, 16
1009 | lwz CARG3, 0(BASE)
1010 | lwz CARG4, 8(BASE)
1011 | lwz CARG1, 4(BASE)
1012 | lwz CARG2, 12(BASE)
1013 | blt ->fff_fallback
1014 |.endmacro
1015 |
1016 |.macro .ffunc_n, name
1017 |->ff_ .. name:
1018 | cmplwi NARGS8:RC, 8
1019 | lwz CARG3, 0(BASE)
1020 | lfd FARG1, 0(BASE)
1021 | blt ->fff_fallback
1022 | checknum CARG3; bge ->fff_fallback
1023 |.endmacro
1024 |
1025 |.macro .ffunc_nn, name
1026 |->ff_ .. name:
1027 | cmplwi NARGS8:RC, 16
1028 | lwz CARG3, 0(BASE)
1029 | lfd FARG1, 0(BASE)
1030 | lwz CARG4, 8(BASE)
1031 | lfd FARG2, 8(BASE)
1032 | blt ->fff_fallback
1033 | checknum CARG3; bge ->fff_fallback
1034 | checknum CARG4; bge ->fff_fallback
1035 |.endmacro
1036 |
1037 |// Inlined GC threshold check. Caveat: uses TMP0 and TMP1.
1038 |.macro ffgccheck
1039 | lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
1040 | lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
1041 | cmplw TMP0, TMP1
1042 | bgel ->fff_gcstep
1043 |.endmacro
1044 |
1045 |//-- Base library: checks -----------------------------------------------
1046 |
1047 |.ffunc_1 assert
1048 | li TMP1, LJ_TFALSE
1049 | la RA, -8(BASE)
1050 | cmplw cr1, CARG3, TMP1
1051 | lwz PC, FRAME_PC(BASE)
1052 | bge cr1, ->fff_fallback
1053 | stw CARG3, 0(RA)
1054 | addi RD, NARGS8:RC, 8 // Compute (nresults+1)*8.
1055 | stw CARG1, 4(RA)
1056 | beq ->fff_res // Done if exactly 1 argument.
1057 | li TMP1, 8
1058 | subi RC, RC, 8
1059 |1:
1060 | cmplw TMP1, RC
1061 | lfdx f0, BASE, TMP1
1062 | stfdx f0, RA, TMP1
1063 | addi TMP1, TMP1, 8
1064 | bney <1
1065 | b ->fff_res
1066 |
1067 |.ffunc type
1068 | cmplwi NARGS8:RC, 8
1069 | lwz CARG1, 0(BASE)
1070 | blt ->fff_fallback
1071 | subfc TMP0, TISNUM, CARG1
1072 | subfe TMP2, CARG1, CARG1
1073 | orc TMP1, TMP2, TMP0
1074 | addi TMP1, TMP1, ~LJ_TISNUM+1
1075 | slwi TMP1, TMP1, 3
1076 | la TMP2, CFUNC:RB->upvalue
1077 | lfdx FARG1, TMP2, TMP1
1078 | b ->fff_resn
1079 |
1080 |//-- Base library: getters and setters ---------------------------------
1081 |
1082 |.ffunc_1 getmetatable
1083 | checktab CARG3; bne >6
1084 |1: // Field metatable must be at same offset for GCtab and GCudata!
1085 | lwz TAB:CARG1, TAB:CARG1->metatable
1086 |2:
1087 | li CARG3, LJ_TNIL
1088 | cmplwi TAB:CARG1, 0
1089 | lwz STR:RC, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])(DISPATCH)
1090 | beq ->fff_restv
1091 | lwz TMP0, TAB:CARG1->hmask
1092 | li CARG3, LJ_TTAB // Use metatable as default result.
1093 | lwz TMP1, STR:RC->hash
1094 | lwz NODE:TMP2, TAB:CARG1->node
1095 | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
1096 | slwi TMP0, TMP1, 5
1097 | slwi TMP1, TMP1, 3
1098 | sub TMP1, TMP0, TMP1
1099 | add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
1100 |3: // Rearranged logic, because we expect _not_ to find the key.
1101 | lwz CARG4, NODE:TMP2->key
1102 | lwz TMP0, 4+offsetof(Node, key)(NODE:TMP2)
1103 | lwz CARG2, NODE:TMP2->val
1104 | lwz TMP1, 4+offsetof(Node, val)(NODE:TMP2)
1105 | checkstr CARG4; bne >4
1106 | cmpw TMP0, STR:RC; beq >5
1107 |4:
1108 | lwz NODE:TMP2, NODE:TMP2->next
1109 | cmplwi NODE:TMP2, 0
1110 | beq ->fff_restv // Not found, keep default result.
1111 | b <3
1112 |5:
1113 | checknil CARG2
1114 | beq ->fff_restv // Ditto for nil value.
1115 | mr CARG3, CARG2 // Return value of mt.__metatable.
1116 | mr CARG1, TMP1
1117 | b ->fff_restv
1118 |
1119 |6:
1120 | cmpwi CARG3, LJ_TUDATA; beq <1
1121 | subfc TMP0, TISNUM, CARG3
1122 | subfe TMP2, CARG3, CARG3
1123 | orc TMP1, TMP2, TMP0
1124 | addi TMP1, TMP1, ~LJ_TISNUM+1
1125 | slwi TMP1, TMP1, 2
1126 | la TMP2, DISPATCH_GL(gcroot[GCROOT_BASEMT])(DISPATCH)
1127 | lwzx TAB:CARG1, TMP2, TMP1
1128 | b <2
1129 |
1130 |.ffunc_2 setmetatable
1131 | // Fast path: no mt for table yet and not clearing the mt.
1132 | checktab CARG3; bne ->fff_fallback
1133 | lwz TAB:TMP1, TAB:CARG1->metatable
1134 | checktab CARG4; bne ->fff_fallback
1135 | cmplwi TAB:TMP1, 0
1136 | lbz TMP3, TAB:CARG1->marked
1137 | bne ->fff_fallback
1138 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
1139 | stw TAB:CARG2, TAB:CARG1->metatable
1140 | beq ->fff_restv
1141 | barrierback TAB:CARG1, TMP3, TMP0
1142 | b ->fff_restv
1143 |
1144 |.ffunc rawget
1145 | cmplwi NARGS8:RC, 8
1146 | lwz CARG4, 0(BASE)
1147 | lwz TAB:CARG2, 4(BASE)
1148 | blt ->fff_fallback
1149 | checktab CARG4; bne ->fff_fallback
1150 | la CARG3, 8(BASE)
1151 | mr CARG1, L
1152 | bl extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
1153 | // Returns cTValue *.
1154 | lfd FARG1, 0(CRET1)
1155 | b ->fff_resn
1156 |
1157 |//-- Base library: conversions ------------------------------------------
1158 |
1159 |.ffunc tonumber
1160 | // Only handles the number case inline (without a base argument).
1161 | cmplwi NARGS8:RC, 8
1162 | lwz CARG1, 0(BASE)
1163 | lfd FARG1, 0(BASE)
1164 | bne ->fff_fallback // Exactly one argument.
1165 | checknum CARG1; bgt ->fff_fallback
1166 | b ->fff_resn
1167 |
1168 |.ffunc_1 tostring
1169 | // Only handles the string or number case inline.
1170 | checkstr CARG3
1171 | // A __tostring method in the string base metatable is ignored.
1172 | beq ->fff_restv // String key?
1173 | // Handle numbers inline, unless a number base metatable is present.
1174 | lwz TMP0, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH)
1175 | checknum CARG3
1176 | cmplwi cr1, TMP0, 0
1177 | stw BASE, L->base // Add frame since C call can throw.
1178 | crorc 4*cr0+eq, 4*cr0+gt, 4*cr1+eq
1179 | stw PC, SAVE_PC // Redundant (but a defined value).
1180 | beq ->fff_fallback
1181 | ffgccheck
1182 | mr CARG1, L
1183 | mr CARG2, BASE
1184 if (LJ_DUALNUM) {
1185 | bl extern lj_str_fromnumber // (lua_State *L, cTValue *o)
1186 } else {
1187 | bl extern lj_str_fromnum // (lua_State *L, lua_Number *np)
1188 }
1189 | // Returns GCstr *.
1190 | li CARG3, LJ_TSTR
1191 | b ->fff_restv
1192 |
1193 |//-- Base library: iterators -------------------------------------------
1194 |
1195 |.ffunc next
1196 | cmplwi NARGS8:RC, 8
1197 | lwz CARG1, 0(BASE)
1198 | lwz TAB:CARG2, 4(BASE)
1199 | blt ->fff_fallback
1200 | stwx TISNIL, BASE, NARGS8:RC // Set missing 2nd arg to nil.
1201 | checktab CARG1
1202 | lwz PC, FRAME_PC(BASE)
1203 | bne ->fff_fallback
1204 | stw BASE, L->base // Add frame since C call can throw.
1205 | mr CARG1, L
1206 | stw BASE, L->top // Dummy frame length is ok.
1207 | la CARG3, 8(BASE)
1208 | stw PC, SAVE_PC
1209 | bl extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
1210 | // Returns 0 at end of traversal.
1211 | cmplwi CRET1, 0
1212 | li CARG3, LJ_TNIL
1213 | beq ->fff_restv // End of traversal: return nil.
1214 | lfd f0, 8(BASE) // Copy key and value to results.
1215 | la RA, -8(BASE)
1216 | lfd f1, 16(BASE)
1217 | stfd f0, 0(RA)
1218 | li RD, (2+1)*8
1219 | stfd f1, 8(RA)
1220 | b ->fff_res
1221 |
1222 |.ffunc_1 pairs
1223 | checktab CARG3
1224 | lwz PC, FRAME_PC(BASE)
1225 | bne ->fff_fallback
1226#ifdef LUAJIT_ENABLE_LUA52COMPAT
1227 | lwz TAB:TMP2, TAB:CARG1->metatable
1228 | lfd f0, CFUNC:RB->upvalue[0]
1229 | cmplwi TAB:TMP2, 0
1230 | la RA, -8(BASE)
1231 | bne ->fff_fallback
1232#else
1233 | lfd f0, CFUNC:RB->upvalue[0]
1234 | la RA, -8(BASE)
1235#endif
1236 | stw TISNIL, 8(BASE)
1237 | li RD, (3+1)*8
1238 | stfd f0, 0(RA)
1239 | b ->fff_res
1240 |
1241 |.ffunc ipairs_aux
1242 | cmplwi NARGS8:RC, 16
1243 | lwz CARG3, 0(BASE)
1244 | lwz TAB:CARG1, 4(BASE)
1245 | lwz CARG4, 8(BASE)
1246 if (LJ_DUALNUM) {
1247 | lwz TMP2, 12(BASE)
1248 } else {
1249 | lfd FARG2, 8(BASE)
1250 }
1251 | blt ->fff_fallback
1252 | checktab CARG3
1253 | checknum cr1, CARG4
1254 | lwz PC, FRAME_PC(BASE)
1255 if (LJ_DUALNUM) {
1256 | bne ->fff_fallback
1257 | bne cr1, ->fff_fallback
1258 } else {
1259 | lus TMP0, 0x3ff0
1260 | stw ZERO, TMPD_LO
1261 | bne ->fff_fallback
1262 | stw TMP0, TMPD_HI
1263 | bge cr1, ->fff_fallback
1264 | lfd FARG1, TMPD
1265 | toint TMP2, FARG2, f0
1266 }
1267 | lwz TMP0, TAB:CARG1->asize
1268 | lwz TMP1, TAB:CARG1->array
1269 if (!LJ_DUALNUM) {
1270 | fadd FARG2, FARG2, FARG1
1271 }
1272 | addi TMP2, TMP2, 1
1273 | la RA, -8(BASE)
1274 | cmplw TMP0, TMP2
1275 if (LJ_DUALNUM) {
1276 | stw TISNUM, 0(RA)
1277 | slwi TMP3, TMP2, 3
1278 | stw TMP2, 4(RA)
1279 } else {
1280 | slwi TMP3, TMP2, 3
1281 | stfd FARG2, 0(RA)
1282 }
1283 | ble >2 // Not in array part?
1284 | lwzx TMP2, TMP1, TMP3
1285 | lfdx f0, TMP1, TMP3
1286 |1:
1287 | checknil TMP2
1288 | li RD, (0+1)*8
1289 | beq ->fff_res // End of iteration, return 0 results.
1290 | li RD, (2+1)*8
1291 | stfd f0, 8(RA)
1292 | b ->fff_res
1293 |2: // Check for empty hash part first. Otherwise call C function.
1294 | lwz TMP0, TAB:CARG1->hmask
1295 | cmplwi TMP0, 0
1296 | li RD, (0+1)*8
1297 | beq ->fff_res
1298 | mr CARG2, TMP2
1299 | bl extern lj_tab_getinth // (GCtab *t, int32_t key)
1300 | // Returns cTValue * or NULL.
1301 | cmplwi CRET1, 0
1302 | li RD, (0+1)*8
1303 | beq ->fff_res
1304 | lwz TMP2, 0(CRET1)
1305 | lfd f0, 0(CRET1)
1306 | b <1
1307 |
1308 |.ffunc_1 ipairs
1309 | checktab CARG3
1310 | lwz PC, FRAME_PC(BASE)
1311 | bne ->fff_fallback
1312#ifdef LUAJIT_ENABLE_LUA52COMPAT
1313 | lwz TAB:TMP2, TAB:CARG1->metatable
1314 | lfd f0, CFUNC:RB->upvalue[0]
1315 | cmplwi TAB:TMP2, 0
1316 | la RA, -8(BASE)
1317 | bne ->fff_fallback
1318#else
1319 | lfd f0, CFUNC:RB->upvalue[0]
1320 | la RA, -8(BASE)
1321#endif
1322 if (LJ_DUALNUM) {
1323 | stw TISNUM, 8(BASE)
1324 } else {
1325 | stw ZERO, 8(BASE)
1326 }
1327 | stw ZERO, 12(BASE)
1328 | li RD, (3+1)*8
1329 | stfd f0, 0(RA)
1330 | b ->fff_res
1331 |
1332 |//-- Base library: catch errors ----------------------------------------
1333 |
1334 |.ffunc pcall
1335 | cmplwi NARGS8:RC, 8
1336 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1337 | blt ->fff_fallback
1338 | mr TMP2, BASE
1339 | la BASE, 8(BASE)
1340 | // Remember active hook before pcall.
1341 | rlwinm TMP3, TMP3, 32-HOOK_ACTIVE_SHIFT, 31, 31
1342 | subi NARGS8:RC, NARGS8:RC, 8
1343 | addi PC, TMP3, 8+FRAME_PCALL
1344 | b ->vm_call_dispatch
1345 |
1346 |.ffunc xpcall
1347 | cmplwi NARGS8:RC, 16
1348 | lwz CARG4, 8(BASE)
1349 | lfd FARG2, 8(BASE)
1350 | lwz CARG3, 0(BASE)
1351 | lfd FARG1, 0(BASE)
1352 | blt ->fff_fallback
1353 | lbz TMP1, DISPATCH_GL(hookmask)(DISPATCH)
1354 | mr TMP2, BASE
1355 | checkfunc CARG4; bne ->fff_fallback // Traceback must be a function.
1356 | la BASE, 16(BASE)
1357 | // Remember active hook before pcall.
1358 | rlwinm TMP1, TMP1, 32-HOOK_ACTIVE_SHIFT, 31, 31
1359 | stfd FARG2, 0(TMP2) // Swap function and traceback.
1360 | subi NARGS8:RC, NARGS8:RC, 16
1361 | stfd FARG1, 8(TMP2)
1362 | addi PC, TMP1, 16+FRAME_PCALL
1363 | b ->vm_call_dispatch
1364 |
1365 |//-- Coroutine library --------------------------------------------------
1366 |
1367 |.macro coroutine_resume_wrap, resume
1368 |.if resume
1369 |.ffunc_1 coroutine_resume
1370 | cmpwi CARG3, LJ_TTHREAD; bne ->fff_fallback
1371 |.else
1372 |.ffunc coroutine_wrap_aux
1373 | lwz L:CARG1, CFUNC:RB->upvalue[0].gcr
1374 |.endif
1375 | lbz TMP0, L:CARG1->status
1376 | lwz TMP1, L:CARG1->cframe
1377 | lwz CARG2, L:CARG1->top
1378 | cmplwi cr0, TMP0, LUA_YIELD
1379 | lwz TMP2, L:CARG1->base
1380 | cmplwi cr1, TMP1, 0
1381 | lwz TMP0, L:CARG1->maxstack
1382 | cmplw cr7, CARG2, TMP2
1383 | lwz PC, FRAME_PC(BASE)
1384 | crorc 4*cr6+lt, 4*cr0+gt, 4*cr1+eq // st>LUA_YIELD || cframe!=0
1385 | add TMP2, CARG2, NARGS8:RC
1386 | crandc 4*cr6+gt, 4*cr7+eq, 4*cr0+eq // base==top && st!=LUA_YIELD
1387 | cmplw cr1, TMP2, TMP0
1388 | cror 4*cr6+lt, 4*cr6+lt, 4*cr6+gt
1389 | stw PC, SAVE_PC
1390 | cror 4*cr6+lt, 4*cr6+lt, 4*cr1+gt // cond1 || cond2 || stackov
1391 | stw BASE, L->base
1392 | blt cr6, ->fff_fallback
1393 |1:
1394 |.if resume
1395 | addi BASE, BASE, 8 // Keep resumed thread in stack for GC.
1396 | subi NARGS8:RC, NARGS8:RC, 8
1397 | subi TMP2, TMP2, 8
1398 |.endif
1399 | stw TMP2, L:CARG1->top
1400 | li TMP1, 0
1401 | stw BASE, L->top
1402 |2: // Move args to coroutine.
1403 | cmpw TMP1, NARGS8:RC
1404 | lfdx f0, BASE, TMP1
1405 | beq >3
1406 | stfdx f0, CARG2, TMP1
1407 | addi TMP1, TMP1, 8
1408 | b <2
1409 |3:
1410 | li CARG3, 0
1411 | mr L:SAVE0, L:CARG1
1412 | li CARG4, 0
1413 | bl ->vm_resume // (lua_State *L, TValue *base, 0, 0)
1414 | // Returns thread status.
1415 |4:
1416 | lwz TMP2, L:SAVE0->base
1417 | cmplwi CRET1, LUA_YIELD
1418 | lwz TMP3, L:SAVE0->top
1419 | li_vmstate INTERP
1420 | lwz BASE, L->base
1421 | st_vmstate
1422 | bgt >8
1423 | sub RD, TMP3, TMP2
1424 | lwz TMP0, L->maxstack
1425 | cmplwi RD, 0
1426 | add TMP1, BASE, RD
1427 | beq >6 // No results?
1428 | cmplw TMP1, TMP0
1429 | li TMP1, 0
1430 | bgt >9 // Need to grow stack?
1431 |
1432 | subi TMP3, RD, 8
1433 | stw TMP2, L:SAVE0->top // Clear coroutine stack.
1434 |5: // Move results from coroutine.
1435 | cmplw TMP1, TMP3
1436 | lfdx f0, TMP2, TMP1
1437 | stfdx f0, BASE, TMP1
1438 | addi TMP1, TMP1, 8
1439 | bne <5
1440 |6:
1441 | andi. TMP0, PC, FRAME_TYPE
1442 |.if resume
1443 | li TMP1, LJ_TTRUE
1444 | la RA, -8(BASE)
1445 | stw TMP1, -8(BASE) // Prepend true to results.
1446 | addi RD, RD, 16
1447 |.else
1448 | mr RA, BASE
1449 | addi RD, RD, 8
1450 |.endif
1451 |7:
1452 | stw PC, SAVE_PC
1453 | mr MULTRES, RD
1454 | beq ->BC_RET_Z
1455 | b ->vm_return
1456 |
1457 |8: // Coroutine returned with error (at co->top-1).
1458 |.if resume
1459 | andi. TMP0, PC, FRAME_TYPE
1460 | la TMP3, -8(TMP3)
1461 | li TMP1, LJ_TFALSE
1462 | lfd f0, 0(TMP3)
1463 | stw TMP3, L:SAVE0->top // Remove error from coroutine stack.
1464 | li RD, (2+1)*8
1465 | stw TMP1, -8(BASE) // Prepend false to results.
1466 | la RA, -8(BASE)
1467 | stfd f0, 0(BASE) // Copy error message.
1468 | b <7
1469 |.else
1470 | mr CARG1, L
1471 | mr CARG2, L:SAVE0
1472 | bl extern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co)
1473 |.endif
1474 |
1475 |9: // Handle stack expansion on return from yield.
1476 | mr CARG1, L
1477 | srwi CARG2, RD, 3
1478 | bl extern lj_state_growstack // (lua_State *L, int n)
1479 | li CRET1, 0
1480 | b <4
1481 |.endmacro
1482 |
1483 | coroutine_resume_wrap 1 // coroutine.resume
1484 | coroutine_resume_wrap 0 // coroutine.wrap
1485 |
1486 |.ffunc coroutine_yield
1487 | lwz TMP0, L->cframe
1488 | add TMP1, BASE, NARGS8:RC
1489 | stw BASE, L->base
1490 | andi. TMP0, TMP0, CFRAME_RESUME
1491 | stw TMP1, L->top
1492 | li CRET1, LUA_YIELD
1493 | beq ->fff_fallback
1494 | stw ZERO, L->cframe
1495 | stb CRET1, L->status
1496 | b ->vm_leave_unw
1497 |
1498 |//-- Math library -------------------------------------------------------
1499 |
1500 |.ffunc_1 math_abs
1501 | checknum CARG3
1502 if (LJ_DUALNUM) {
1503 | bne >2
1504 | srawi TMP1, CARG1, 31
1505 | xor TMP2, TMP1, CARG1
1506 | sub. CARG1, TMP2, TMP1
1507 | blt >1
1508 |->fff_resi:
1509 | lwz PC, FRAME_PC(BASE)
1510 | la RA, -8(BASE)
1511 | stw TISNUM, -8(BASE)
1512 | stw CRET1, -4(BASE)
1513 | b ->fff_res1
1514 |1:
1515 | lus CARG3, 0x41e0 // 2^31.
1516 | li CARG1, 0
1517 | b ->fff_restv
1518 |2:
1519 }
1520 | bge ->fff_fallback
1521 | rlwinm CARG3, CARG3, 0, 1, 31
1522 | // Fallthrough.
1523 |
1524 |->fff_restv:
1525 | // CARG3/CARG1 = TValue result.
1526 | lwz PC, FRAME_PC(BASE)
1527 | stw CARG3, -8(BASE)
1528 | la RA, -8(BASE)
1529 | stw CARG1, -4(BASE)
1530 |->fff_res1:
1531 | // RA = results, PC = return.
1532 | li RD, (1+1)*8
1533 |->fff_res:
1534 | // RA = results, RD = (nresults+1)*8, PC = return.
1535 | andi. TMP0, PC, FRAME_TYPE
1536 | mr MULTRES, RD
1537 | bney ->vm_return
1538 | lwz INS, -4(PC)
1539 | decode_RB8 RB, INS
1540 |5:
1541 | cmplw RB, RD // More results expected?
1542 | decode_RA8 TMP0, INS
1543 | bgt >6
1544 | ins_next1
1545 | // Adjust BASE. KBASE is assumed to be set for the calling frame.
1546 | sub BASE, RA, TMP0
1547 | ins_next2
1548 |
1549 |6: // Fill up results with nil.
1550 | subi TMP1, RD, 8
1551 | addi RD, RD, 8
1552 | stwx TISNIL, RA, TMP1
1553 | b <5
1554 |
1555 |.macro math_extern, func
1556 | .ffunc_n math_ .. func
1557 | bl extern func
1558 | b ->fff_resn
1559 |.endmacro
1560 |
1561 |.macro math_extern2, func
1562 | .ffunc_nn math_ .. func
1563 | bl extern func
1564 | b ->fff_resn
1565 |.endmacro
1566 |
1567 |.macro math_round, func
1568 | .ffunc_1 math_ .. func
1569 | checknum CARG3; beqy ->fff_restv
1570 | rlwinm TMP2, CARG3, 12, 21, 31
1571 | bge ->fff_fallback
1572 | addic. TMP2, TMP2, -1023 // exp = exponent(x) - 1023
1573 | cmplwi cr1, TMP2, 31 // 0 <= exp < 31?
1574 | subfic TMP0, TMP2, 31
1575 | blt >3
1576 | slwi TMP1, CARG3, 11
1577 | srwi TMP3, CARG1, 21
1578 | oris TMP1, TMP1, 0x8000
1579 | addi TMP2, TMP2, 1
1580 | or TMP1, TMP1, TMP3
1581 | slwi CARG2, CARG1, 11
1582 | bge cr1, >4
1583 | slw TMP3, TMP1, TMP2
1584 | srw CARG1, TMP1, TMP0
1585 | or TMP3, TMP3, CARG2
1586 | srawi TMP2, CARG3, 31
1587 |.if "func" == "floor"
1588 | and TMP1, TMP3, TMP2
1589 | addic TMP0, TMP1, -1
1590 | subfe TMP1, TMP0, TMP1
1591 | add CARG1, CARG1, TMP1
1592 | xor CARG1, CARG1, TMP2
1593 | sub CARG1, CARG1, TMP2
1594 | b ->fff_resi
1595 |.else
1596 | andc TMP1, TMP3, TMP2
1597 | addic TMP0, TMP1, -1
1598 | subfe TMP1, TMP0, TMP1
1599 | addo. CARG1, CARG1, TMP1
1600 | xor CARG1, CARG1, TMP2
1601 | sub CARG1, CARG1, TMP2
1602 | bns ->fff_resi
1603 | // Potential overflow.
1604 | mcrxr cr0; bley ->fff_resi // Ignore unrelated overflow.
1605 | lus CARG3, 0x41e0 // 2^31.
1606 | li CARG1, 0
1607 | b ->fff_restv
1608 |.endif
1609 |3: // |x| < 1
1610 | add TMP2, CARG3, CARG3
1611 | srawi TMP1, CARG3, 31
1612 | or TMP2, CARG1, TMP2 // ztest = (hi+hi) | lo
1613 |.if "func" == "floor"
1614 | and TMP1, TMP2, TMP1 // (ztest & sign) == 0 ? 0 : -1
1615 | subfic TMP2, TMP1, 0
1616 | subfe CARG1, CARG1, CARG1
1617 |.else
1618 | andc TMP1, TMP2, TMP1 // (ztest & ~sign) == 0 ? 0 : 1
1619 | addic TMP2, TMP1, -1
1620 | subfe CARG1, TMP2, TMP1
1621 |.endif
1622 | b ->fff_resi
1623 |4: // exp >= 31. Check for -(2^31).
1624 | xoris TMP1, TMP1, 0x8000
1625 | srawi TMP2, CARG3, 31
1626 |.if "func" == "floor"
1627 | or TMP1, TMP1, CARG2
1628 |.endif
1629 | orc. TMP1, TMP1, TMP2
1630 | crand 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
1631 | lus CARG1, 0x8000 // -(2^31).
1632 | beqy ->fff_resi
1633 |5:
1634 | lfd FARG1, 0(BASE)
1635 | bl extern func
1636 | b ->fff_resn
1637 |.endmacro
1638 |
1639 if (LJ_DUALNUM) {
1640 | math_round floor
1641 | math_round ceil
1642 } else {
1643 | // NYI: use internal implementation.
1644 | math_extern floor
1645 | math_extern ceil
1646 }
1647 |
1648 | math_extern sqrt
1649 | math_extern log
1650 | math_extern log10
1651 | math_extern exp
1652 | math_extern sin
1653 | math_extern cos
1654 | math_extern tan
1655 | math_extern asin
1656 | math_extern acos
1657 | math_extern atan
1658 | math_extern sinh
1659 | math_extern cosh
1660 | math_extern tanh
1661 | math_extern2 pow
1662 | math_extern2 atan2
1663 | math_extern2 fmod
1664 |
1665 |->ff_math_deg:
1666 |.ffunc_n math_rad
1667 | lfd FARG2, CFUNC:RB->upvalue[0]
1668 | fmul FARG1, FARG1, FARG2
1669 | b ->fff_resn
1670 |
1671 if (LJ_DUALNUM) {
1672 |.ffunc math_ldexp
1673 | cmplwi NARGS8:RC, 16
1674 | lwz CARG3, 0(BASE)
1675 | lfd FARG1, 0(BASE)
1676 | lwz CARG4, 8(BASE)
1677 | lwz CARG1, 12(BASE)
1678 | blt ->fff_fallback
1679 | checknum CARG3; bge ->fff_fallback
1680 | checknum CARG4; bne ->fff_fallback
1681 } else {
1682 |.ffunc_nn math_ldexp
1683 | toint CARG1, FARG2
1684 }
1685 | bl extern ldexp
1686 | b ->fff_resn
1687 |
1688 |.ffunc_n math_frexp
1689 | la CARG1, DISPATCH_GL(tmptv)(DISPATCH)
1690 | lwz PC, FRAME_PC(BASE)
1691 | bl extern frexp
1692 | lwz TMP1, DISPATCH_GL(tmptv)(DISPATCH)
1693 | la RA, -8(BASE)
1694 if (!LJ_DUALNUM) {
1695 | tonum_i FARG2, TMP1
1696 }
1697 | stfd FARG1, 0(RA)
1698 | li RD, (2+1)*8
1699 if (LJ_DUALNUM) {
1700 | stw TISNUM, 8(RA)
1701 | stw TMP1, 12(RA)
1702 } else {
1703 | stfd FARG2, 8(RA)
1704 }
1705 | b ->fff_res
1706 |
1707 |.ffunc_n math_modf
1708 | la CARG1, -8(BASE)
1709 | lwz PC, FRAME_PC(BASE)
1710 | bl extern modf
1711 | la RA, -8(BASE)
1712 | stfd FARG1, 0(BASE)
1713 | li RD, (2+1)*8
1714 | b ->fff_res
1715 |
1716 |.macro math_minmax, name, ismax
1717 ||if (LJ_DUALNUM) {
1718 | .ffunc_1 name
1719 | checknum CARG3
1720 | addi TMP1, BASE, 8
1721 | add TMP2, BASE, NARGS8:RC
1722 | bne >4
1723 |1: // Handle integers.
1724 | lwz CARG4, 0(TMP1)
1725 | cmplw cr1, TMP1, TMP2
1726 | lwz CARG2, 4(TMP1)
1727 | bge cr1, ->fff_resi
1728 | checknum CARG4
1729 | xoris TMP0, CARG1, 0x8000
1730 | xoris TMP3, CARG2, 0x8000
1731 | bne >3
1732 | subfc TMP3, TMP3, TMP0
1733 | subfe TMP0, TMP0, TMP0
1734 |.if ismax
1735 | andc TMP3, TMP3, TMP0
1736 |.else
1737 | and TMP3, TMP3, TMP0
1738 |.endif
1739 | add CARG1, TMP3, CARG2
1740 | addi TMP1, TMP1, 8
1741 | b <1
1742 |3:
1743 | bge ->fff_fallback
1744 | // Convert intermediate result to number and continue below.
1745 | tonum_i FARG1, CARG1
1746 | lfd FARG2, 0(TMP1)
1747 | b >6
1748 |4:
1749 | lfd FARG1, 0(BASE)
1750 | bge ->fff_fallback
1751 |5: // Handle numbers.
1752 | lwz CARG4, 0(TMP1)
1753 | cmplw cr1, TMP1, TMP2
1754 | lfd FARG2, 0(TMP1)
1755 | bge cr1, ->fff_resn
1756 | checknum CARG4; bge >7
1757 |6:
1758 | fsub f0, FARG1, FARG2
1759 | addi TMP1, TMP1, 8
1760 |.if ismax
1761 | fsel FARG1, f0, FARG1, FARG2
1762 |.else
1763 | fsel FARG1, f0, FARG2, FARG1
1764 |.endif
1765 | b <5
1766 |7: // Convert integer to number and continue above.
1767 | lwz CARG2, 4(TMP1)
1768 | bne ->fff_fallback
1769 | tonum_i FARG2, CARG2
1770 | b <6
1771 ||} else {
1772 | .ffunc_n name
1773 | li TMP1, 8
1774 |1:
1775 | lwzx CARG2, BASE, TMP1
1776 | lfdx FARG2, BASE, TMP1
1777 | cmplw cr1, TMP1, NARGS8:RC
1778 | checknum CARG2
1779 | bge cr1, ->fff_resn
1780 | bge ->fff_fallback
1781 | fsub f0, FARG1, FARG2
1782 | addi TMP1, TMP1, 8
1783 |.if ismax
1784 | fsel FARG1, f0, FARG1, FARG2
1785 |.else
1786 | fsel FARG1, f0, FARG2, FARG1
1787 |.endif
1788 | b <1
1789 ||}
1790 |.endmacro
1791 |
1792 | math_minmax math_min, 0
1793 | math_minmax math_max, 1
1794 |
1795 |//-- String library -----------------------------------------------------
1796 |
1797 |.ffunc_1 string_len
1798 | checkstr CARG3; bne ->fff_fallback
1799 | lwz CRET1, STR:CARG1->len
1800 | b ->fff_resi
1801 |
1802 |.ffunc string_byte // Only handle the 1-arg case here.
1803 | cmplwi NARGS8:RC, 8
1804 | lwz CARG3, 0(BASE)
1805 | lwz STR:CARG1, 4(BASE)
1806 | bne ->fff_fallback // Need exactly 1 argument.
1807 | checkstr CARG3
1808 | bne ->fff_fallback
1809 | lwz TMP0, STR:CARG1->len
1810 if (LJ_DUALNUM) {
1811 | lbz CARG1, STR:CARG1[1] // Access is always ok (NUL at end).
1812 | li RD, (0+1)*8
1813 | lwz PC, FRAME_PC(BASE)
1814 | cmplwi TMP0, 0
1815 | la RA, -8(BASE)
1816 | beqy ->fff_res
1817 | b ->fff_resi
1818 } else {
1819 | lbz TMP1, STR:CARG1[1] // Access is always ok (NUL at end).
1820 | addic TMP3, TMP0, -1 // RD = ((str->len != 0)+1)*8
1821 | subfe RD, TMP3, TMP0
1822 | stw TMP1, TONUM_LO // Inlined tonum_u f0, TMP1.
1823 | addi RD, RD, 1
1824 | lfd f0, TONUM_D
1825 | la RA, -8(BASE)
1826 | lwz PC, FRAME_PC(BASE)
1827 | fsub f0, f0, TOBIT
1828 | slwi RD, RD, 3
1829 | stfd f0, 0(RA)
1830 | b ->fff_res
1831 }
1832 |
1833 |.ffunc string_char // Only handle the 1-arg case here.
1834 | ffgccheck
1835 | cmplwi NARGS8:RC, 8
1836 | lwz CARG3, 0(BASE)
1837 if (LJ_DUALNUM) {
1838 | lwz TMP0, 4(BASE)
1839 | bne ->fff_fallback // Exactly 1 argument.
1840 | checknum CARG3; bne ->fff_fallback
1841 | la CARG2, 7(BASE)
1842 } else {
1843 | lfd FARG1, 0(BASE)
1844 | bne ->fff_fallback // Exactly 1 argument.
1845 | checknum CARG3; bge ->fff_fallback
1846 | toint TMP0, FARG1
1847 | la CARG2, TMPD_BLO
1848 }
1849 | li CARG3, 1
1850 | cmplwi TMP0, 255; bgt ->fff_fallback
1851 |->fff_newstr:
1852 | mr CARG1, L
1853 | stw BASE, L->base
1854 | stw PC, SAVE_PC
1855 | bl extern lj_str_new // (lua_State *L, char *str, size_t l)
1856 | // Returns GCstr *.
1857 | lwz BASE, L->base
1858 | li CARG3, LJ_TSTR
1859 | b ->fff_restv
1860 |
1861 |.ffunc string_sub
1862 | ffgccheck
1863 | cmplwi NARGS8:RC, 16
1864 | lwz CARG3, 16(BASE)
1865 if (!LJ_DUALNUM) {
1866 | lfd f0, 16(BASE)
1867 }
1868 | lwz TMP0, 0(BASE)
1869 | lwz STR:CARG1, 4(BASE)
1870 | blt ->fff_fallback
1871 | lwz CARG2, 8(BASE)
1872 if (LJ_DUALNUM) {
1873 | lwz TMP1, 12(BASE)
1874 } else {
1875 | lfd f1, 8(BASE)
1876 }
1877 | li TMP2, -1
1878 | beq >1
1879 if (LJ_DUALNUM) {
1880 | checknum CARG3
1881 | lwz TMP2, 20(BASE)
1882 | bne ->fff_fallback
1883 |1:
1884 | checknum CARG2; bne ->fff_fallback
1885 } else {
1886 | checknum CARG3; bge ->fff_fallback
1887 | toint TMP2, f0
1888 |1:
1889 | checknum CARG2; bge ->fff_fallback
1890 }
1891 | checkstr TMP0; bne ->fff_fallback
1892 if (!LJ_DUALNUM) {
1893 | toint TMP1, f1
1894 }
1895 | lwz TMP0, STR:CARG1->len
1896 | cmplw TMP0, TMP2 // len < end? (unsigned compare)
1897 | addi TMP3, TMP2, 1
1898 | blt >5
1899 |2:
1900 | cmpwi TMP1, 0 // start <= 0?
1901 | add TMP3, TMP1, TMP0
1902 | ble >7
1903 |3:
1904 | sub CARG3, TMP2, TMP1
1905 | addi CARG2, STR:CARG1, #STR-1
1906 | srawi TMP0, CARG3, 31
1907 | addi CARG3, CARG3, 1
1908 | add CARG2, CARG2, TMP1
1909 | andc CARG3, CARG3, TMP0
1910 | b ->fff_newstr
1911 |
1912 |5: // Negative end or overflow.
1913 | sub CARG2, TMP0, TMP2
1914 | srawi CARG2, CARG2, 31
1915 | andc TMP3, TMP3, CARG2 // end = end > len ? len : end+len+1
1916 | add TMP2, TMP0, TMP3
1917 | b <2
1918 |
1919 |7: // Negative start or underflow.
1920 | addic CARG3, TMP1, -1
1921 | subfe CARG3, CARG3, CARG3
1922 | srawi CARG2, TMP3, 31 // Note: modifies carry.
1923 | andc TMP3, TMP3, CARG3
1924 | andc TMP1, TMP3, CARG2
1925 | addi TMP1, TMP1, 1 // start = 1 + (start ? start+len : 0)
1926 | b <3
1927 |
1928 |.ffunc string_rep // Only handle the 1-char case inline.
1929 | ffgccheck
1930 | cmplwi NARGS8:RC, 16
1931 | lwz TMP0, 0(BASE)
1932 | lwz STR:CARG1, 4(BASE)
1933 | lwz CARG4, 8(BASE)
1934 if (LJ_DUALNUM) {
1935 | lwz CARG3, 12(BASE)
1936 } else {
1937 | lfd FARG2, 8(BASE)
1938 }
1939 | blt ->fff_fallback
1940 | checkstr TMP0; bne ->fff_fallback
1941 if (LJ_DUALNUM) {
1942 | checknum CARG4; bne ->fff_fallback
1943 } else {
1944 | checknum CARG4; bge ->fff_fallback
1945 | toint CARG3, FARG2
1946 }
1947 | lwz TMP0, STR:CARG1->len
1948 | cmpwi CARG3, 0
1949 | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1950 | ble >2 // Count <= 0? (or non-int)
1951 | cmplwi TMP0, 1
1952 | subi TMP2, CARG3, 1
1953 | blt >2 // Zero length string?
1954 | cmplw cr1, TMP1, CARG3
1955 | bne ->fff_fallback // Fallback for > 1-char strings.
1956 | lbz TMP0, STR:CARG1[1]
1957 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1958 | blt cr1, ->fff_fallback
1959 |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
1960 | cmplwi TMP2, 0
1961 | stbx TMP0, CARG2, TMP2
1962 | subi TMP2, TMP2, 1
1963 | bne <1
1964 | b ->fff_newstr
1965 |2: // Return empty string.
1966 | la STR:CARG1, DISPATCH_GL(strempty)(DISPATCH)
1967 | li CARG3, LJ_TSTR
1968 | b ->fff_restv
1969 |
1970 |.ffunc string_reverse
1971 | ffgccheck
1972 | cmplwi NARGS8:RC, 8
1973 | lwz CARG3, 0(BASE)
1974 | lwz STR:CARG1, 4(BASE)
1975 | blt ->fff_fallback
1976 | checkstr CARG3
1977 | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1978 | bne ->fff_fallback
1979 | lwz CARG3, STR:CARG1->len
1980 | la CARG1, #STR(STR:CARG1)
1981 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1982 | li TMP2, 0
1983 | cmplw TMP1, CARG3
1984 | subi TMP3, CARG3, 1
1985 | blt ->fff_fallback
1986 |1: // Reverse string copy.
1987 | cmpwi TMP3, 0
1988 | lbzx TMP1, CARG1, TMP2
1989 | blty ->fff_newstr
1990 | stbx TMP1, CARG2, TMP3
1991 | subi TMP3, TMP3, 1
1992 | addi TMP2, TMP2, 1
1993 | b <1
1994 |
1995 |.macro ffstring_case, name, lo
1996 | .ffunc name
1997 | ffgccheck
1998 | cmplwi NARGS8:RC, 8
1999 | lwz CARG3, 0(BASE)
2000 | lwz STR:CARG1, 4(BASE)
2001 | blt ->fff_fallback
2002 | checkstr CARG3
2003 | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
2004 | bne ->fff_fallback
2005 | lwz CARG3, STR:CARG1->len
2006 | la CARG1, #STR(STR:CARG1)
2007 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
2008 | cmplw TMP1, CARG3
2009 | li TMP2, 0
2010 | blt ->fff_fallback
2011 |1: // ASCII case conversion.
2012 | cmplw TMP2, CARG3
2013 | lbzx TMP1, CARG1, TMP2
2014 | bgey ->fff_newstr
2015 | subi TMP0, TMP1, lo
2016 | xori TMP3, TMP1, 0x20
2017 | addic TMP0, TMP0, -26
2018 | subfe TMP3, TMP3, TMP3
2019 | andi. TMP3, TMP3, 0x20
2020 | xor TMP1, TMP1, TMP3
2021 | stbx TMP1, CARG2, TMP2
2022 | addi TMP2, TMP2, 1
2023 | b <1
2024 |.endmacro
2025 |
2026 |ffstring_case string_lower, 65
2027 |ffstring_case string_upper, 97
2028 |
2029 |//-- Table library ------------------------------------------------------
2030 |
2031 |.ffunc_1 table_getn
2032 | checktab CARG3; bne ->fff_fallback
2033 | bl extern lj_tab_len // (GCtab *t)
2034 | // Returns uint32_t (but less than 2^31).
2035 | b ->fff_resi
2036 |
2037 |//-- Bit library --------------------------------------------------------
2038 |
2039 |.macro .ffunc_bit, name
2040 ||if (LJ_DUALNUM) {
2041 | .ffunc_1 bit_..name
2042 | checknum CARG3; bnel ->fff_tobit_fb
2043 ||} else {
2044 | .ffunc_n bit_..name
2045 | fadd FARG1, FARG1, TOBIT
2046 | stfd FARG1, TMPD
2047 | lwz CARG1, TMPD_LO
2048 ||}
2049 |.endmacro
2050 |
2051 |.macro .ffunc_bit_op, name, ins
2052 | .ffunc_bit name
2053 | addi TMP1, BASE, 8
2054 | add TMP2, BASE, NARGS8:RC
2055 |1:
2056 | lwz CARG4, 0(TMP1)
2057 | cmplw cr1, TMP1, TMP2
2058 ||if (LJ_DUALNUM) {
2059 | lwz CARG2, 4(TMP1)
2060 ||} else {
2061 | lfd FARG1, 0(TMP1)
2062 ||}
2063 | bgey cr1, ->fff_resi
2064 | checknum CARG4
2065 ||if (LJ_DUALNUM) {
2066 | bnel ->fff_bitop_fb
2067 ||} else {
2068 | fadd FARG1, FARG1, TOBIT
2069 | bge ->fff_fallback
2070 | stfd FARG1, TMPD
2071 | lwz CARG2, TMPD_LO
2072 ||}
2073 | ins CARG1, CARG1, CARG2
2074 | addi TMP1, TMP1, 8
2075 | b <1
2076 |.endmacro
2077 |
2078 |.ffunc_bit_op band, and
2079 |.ffunc_bit_op bor, or
2080 |.ffunc_bit_op bxor, xor
2081 |
2082 |.ffunc_bit bswap
2083 | rotlwi TMP0, CARG1, 8
2084 | rlwimi TMP0, CARG1, 24, 0, 7
2085 | rlwimi TMP0, CARG1, 24, 16, 23
2086 | mr CRET1, TMP0
2087 | b ->fff_resi
2088 |
2089 |.ffunc_bit bnot
2090 | not CRET1, CARG1
2091 | b ->fff_resi
2092 |
2093 |.macro .ffunc_bit_sh, name, ins, shmod
2094 ||if (LJ_DUALNUM) {
2095 | .ffunc_2 bit_..name
2096 | checknum CARG3; bnel ->fff_tobit_fb
2097 | // Note: no inline conversion from number for 2nd argument!
2098 | checknum CARG4; bne ->fff_fallback
2099 ||} else {
2100 | .ffunc_nn bit_..name
2101 | fadd FARG1, FARG1, TOBIT
2102 | fadd FARG2, FARG2, TOBIT
2103 | stfd FARG1, TMPD
2104 | lwz CARG1, TMPD_LO
2105 | stfd FARG2, TMPD
2106 | lwz CARG2, TMPD_LO
2107 ||}
2108 |.if shmod == 1
2109 | rlwinm CARG2, CARG2, 0, 27, 31
2110 |.elif shmod == 2
2111 | neg CARG2, CARG2
2112 |.endif
2113 | ins CRET1, CARG1, CARG2
2114 | b ->fff_resi
2115 |.endmacro
2116 |
2117 |.ffunc_bit_sh lshift, slw, 1
2118 |.ffunc_bit_sh rshift, srw, 1
2119 |.ffunc_bit_sh arshift, sraw, 1
2120 |.ffunc_bit_sh rol, rotlw, 0
2121 |.ffunc_bit_sh ror, rotlw, 2
2122 |
2123 |.ffunc_bit tobit
2124 if (LJ_DUALNUM) {
2125 | b ->fff_resi
2126 } else {
2127 |->fff_resi:
2128 | tonum_i FARG1, CRET1
2129 }
2130 |->fff_resn:
2131 | lwz PC, FRAME_PC(BASE)
2132 | la RA, -8(BASE)
2133 | stfd FARG1, -8(BASE)
2134 | b ->fff_res1
2135 |
2136 |// Fallback FP number to bit conversion.
2137 |->fff_tobit_fb:
2138 if (LJ_DUALNUM) {
2139 | lfd FARG1, 0(BASE)
2140 | bgt ->fff_fallback
2141 | fadd FARG1, FARG1, TOBIT
2142 | stfd FARG1, TMPD
2143 | lwz CARG1, TMPD_LO
2144 | blr
2145 }
2146 |->fff_bitop_fb:
2147 if (LJ_DUALNUM) {
2148 | lfd FARG1, 0(TMP1)
2149 | bgt ->fff_fallback
2150 | fadd FARG1, FARG1, TOBIT
2151 | stfd FARG1, TMPD
2152 | lwz CARG2, TMPD_LO
2153 | blr
2154 }
2155 |
2156 |//-----------------------------------------------------------------------
2157 |
2158 |->fff_fallback: // Call fast function fallback handler.
2159 | // BASE = new base, RB = CFUNC, RC = nargs*8
2160 | lwz TMP3, CFUNC:RB->f
2161 | add TMP1, BASE, NARGS8:RC
2162 | lwz PC, FRAME_PC(BASE) // Fallback may overwrite PC.
2163 | addi TMP0, TMP1, 8*LUA_MINSTACK
2164 | lwz TMP2, L->maxstack
2165 | stw PC, SAVE_PC // Redundant (but a defined value).
2166 | cmplw TMP0, TMP2
2167 | stw BASE, L->base
2168 | stw TMP1, L->top
2169 | mr CARG1, L
2170 | bgt >5 // Need to grow stack.
2171 | mtctr TMP3
2172 | bctrl // (lua_State *L)
2173 | // Either throws an error, or recovers and returns -1, 0 or nresults+1.
2174 | lwz BASE, L->base
2175 | cmpwi CRET1, 0
2176 | slwi RD, CRET1, 3
2177 | la RA, -8(BASE)
2178 | bgt ->fff_res // Returned nresults+1?
2179 |1: // Returned 0 or -1: retry fast path.
2180 | lwz TMP0, L->top
2181 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2182 | sub NARGS8:RC, TMP0, BASE
2183 | bne ->vm_call_tail // Returned -1?
2184 | ins_callt // Returned 0: retry fast path.
2185 |
2186 |// Reconstruct previous base for vmeta_call during tailcall.
2187 |->vm_call_tail:
2188 | andi. TMP0, PC, FRAME_TYPE
2189 | rlwinm TMP1, PC, 0, 0, 28
2190 | bne >3
2191 | lwz INS, -4(PC)
2192 | decode_RA8 TMP1, INS
2193 |3:
2194 | sub TMP2, BASE, TMP1
2195 | b ->vm_call_dispatch // Resolve again for tailcall.
2196 |
2197 |5: // Grow stack for fallback handler.
2198 | li CARG2, LUA_MINSTACK
2199 | bl extern lj_state_growstack // (lua_State *L, int n)
2200 | lwz BASE, L->base
2201 | cmpw TMP0, TMP0 // Set 4*cr0+eq to force retry.
2202 | b <1
2203 |
2204 |->fff_gcstep: // Call GC step function.
2205 | // BASE = new base, RC = nargs*8
2206 | mflr SAVE0
2207 | stw BASE, L->base
2208 | add TMP0, BASE, NARGS8:RC
2209 | stw PC, SAVE_PC // Redundant (but a defined value).
2210 | stw TMP0, L->top
2211 | mr CARG1, L
2212 | bl extern lj_gc_step // (lua_State *L)
2213 | lwz BASE, L->base
2214 | mtlr SAVE0
2215 | lwz TMP0, L->top
2216 | sub NARGS8:RC, TMP0, BASE
2217 | lwz CFUNC:RB, FRAME_FUNC(BASE)
2218 | blr
2219 |
2220 |//-----------------------------------------------------------------------
2221 |//-- Special dispatch targets -------------------------------------------
2222 |//-----------------------------------------------------------------------
2223 |
2224 |->vm_record: // Dispatch target for recording phase.
2225#if LJ_HASJIT
2226 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
2227 | andi. TMP0, TMP3, HOOK_VMEVENT // No recording while in vmevent.
2228 | bne >5
2229 | // Decrement the hookcount for consistency, but always do the call.
2230 | lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH)
2231 | andi. TMP0, TMP3, HOOK_ACTIVE
2232 | bne >1
2233 | subi TMP2, TMP2, 1
2234 | andi. TMP0, TMP3, LUA_MASKLINE|LUA_MASKCOUNT
2235 | beqy >1
2236 | stw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
2237 | b >1
2238#endif
2239 |
2240 |->vm_rethook: // Dispatch target for return hooks.
2241 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
2242 | andi. TMP0, TMP3, HOOK_ACTIVE // Hook already active?
2243 | beq >1
2244 |5: // Re-dispatch to static ins.
2245 | addi TMP1, TMP1, GG_DISP2STATIC // Assumes decode_OP4 TMP1, INS.
2246 | lwzx TMP0, DISPATCH, TMP1
2247 | mtctr TMP0
2248 | bctr
2249 |
2250 |->vm_inshook: // Dispatch target for instr/line hooks.
2251 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
2252 | lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH)
2253 | andi. TMP0, TMP3, HOOK_ACTIVE // Hook already active?
2254 | rlwinm TMP0, TMP3, 31-LUA_HOOKLINE, 31, 0
2255 | bne <5
2256 |
2257 | cmpwi cr1, TMP0, 0
2258 | addic. TMP2, TMP2, -1
2259 | beq cr1, <5
2260 | stw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
2261 | beq >1
2262 | bge cr1, <5
2263 |1:
2264 | mr CARG1, L
2265 | stw MULTRES, SAVE_MULTRES
2266 | mr CARG2, PC
2267 | stw BASE, L->base
2268 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
2269 | bl extern lj_dispatch_ins // (lua_State *L, const BCIns *pc)
2270 |3:
2271 | lwz BASE, L->base
2272 |4: // Re-dispatch to static ins.
2273 | lwz INS, -4(PC)
2274 | decode_OP4 TMP1, INS
2275 | decode_RB8 RB, INS
2276 | addi TMP1, TMP1, GG_DISP2STATIC
2277 | decode_RD8 RD, INS
2278 | lwzx TMP0, DISPATCH, TMP1
2279 | decode_RA8 RA, INS
2280 | decode_RC8 RC, INS
2281 | mtctr TMP0
2282 | bctr
2283 |
2284 |->cont_hook: // Continue from hook yield.
2285 | addi PC, PC, 4
2286 | lwz MULTRES, -20(RB) // Restore MULTRES for *M ins.
2287 | b <4
2288 |
2289 |->vm_hotloop: // Hot loop counter underflow.
2290#if LJ_HASJIT
2291 | lwz LFUNC:TMP1, FRAME_FUNC(BASE)
2292 | addi CARG1, DISPATCH, GG_DISP2J
2293 | stw PC, SAVE_PC
2294 | lwz TMP1, LFUNC:TMP1->pc
2295 | mr CARG2, PC
2296 | stw L, DISPATCH_J(L)(DISPATCH)
2297 | lbz TMP1, PC2PROTO(framesize)(TMP1)
2298 | stw BASE, L->base
2299 | slwi TMP1, TMP1, 3
2300 | add TMP1, BASE, TMP1
2301 | stw TMP1, L->top
2302 | bl extern lj_trace_hot // (jit_State *J, const BCIns *pc)
2303 | b <3
2304#endif
2305 |
2306 |->vm_callhook: // Dispatch target for call hooks.
2307 | mr CARG2, PC
2308#if LJ_HASJIT
2309 | b >1
2310#endif
2311 |
2312 |->vm_hotcall: // Hot call counter underflow.
2313#if LJ_HASJIT
2314 | ori CARG2, PC, 1
2315 |1:
2316#endif
2317 | add TMP0, BASE, RC
2318 | stw PC, SAVE_PC
2319 | mr CARG1, L
2320 | stw BASE, L->base
2321 | sub RA, RA, BASE
2322 | stw TMP0, L->top
2323 | bl extern lj_dispatch_call // (lua_State *L, const BCIns *pc)
2324 | // Returns ASMFunction.
2325 | lwz BASE, L->base
2326 | lwz TMP0, L->top
2327 | stw ZERO, SAVE_PC // Invalidate for subsequent line hook.
2328 | sub NARGS8:RC, TMP0, BASE
2329 | add RA, BASE, RA
2330 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2331 | lwz INS, -4(PC)
2332 | mtctr CRET1
2333 | bctr
2334 |
2335 |//-----------------------------------------------------------------------
2336 |//-- Trace exit handler -------------------------------------------------
2337 |//-----------------------------------------------------------------------
2338 |
2339 |.macro savex_, a, b, c, d
2340 | stfd f..a, 16+a*8(sp)
2341 | stfd f..b, 16+b*8(sp)
2342 | stfd f..c, 16+c*8(sp)
2343 | stfd f..d, 16+d*8(sp)
2344 |.endmacro
2345 |
2346 |->vm_exit_handler:
2347#if LJ_HASJIT
2348 | addi sp, sp, -(16+32*8+32*4)
2349 | stmw r2, 16+32*8+2*4(sp)
2350 | addi DISPATCH, JGL, -GG_DISP2G-32768
2351 | li CARG2, ~LJ_VMST_EXIT
2352 | lwz CARG1, 16+32*8+32*4(sp) // Get stack chain.
2353 | stw CARG2, DISPATCH_GL(vmstate)(DISPATCH)
2354 | savex_ 0,1,2,3
2355 | stw CARG1, 0(sp) // Store extended stack chain.
2356 | mcrxr cr0 // Clear SO flag.
2357 | savex_ 4,5,6,7
2358 | addi CARG2, sp, 16+32*8+32*4 // Recompute original value of sp.
2359 | savex_ 8,9,10,11
2360 | stw CARG2, 16+32*8+1*4(sp) // Store sp in RID_SP.
2361 | savex_ 12,13,14,15
2362 | mflr CARG3
2363 | li TMP1, 0
2364 | savex_ 16,17,18,19
2365 | stw TMP1, 16+32*8+0*4(sp) // Clear RID_TMP.
2366 | savex_ 20,21,22,23
2367 | lhz CARG4, 2(CARG3) // Load trace number.
2368 | savex_ 24,25,26,27
2369 | lwz L, DISPATCH_GL(jit_L)(DISPATCH)
2370 | savex_ 28,29,30,31
2371 | sub CARG3, TMP0, CARG3 // Compute exit number.
2372 | lwz BASE, DISPATCH_GL(jit_base)(DISPATCH)
2373 | srwi CARG3, CARG3, 2
2374 | stw L, DISPATCH_J(L)(DISPATCH)
2375 | subi CARG3, CARG3, 2
2376 | stw TMP1, DISPATCH_GL(jit_L)(DISPATCH)
2377 | stw CARG4, DISPATCH_J(parent)(DISPATCH)
2378 | stw BASE, L->base
2379 | addi CARG1, DISPATCH, GG_DISP2J
2380 | stw CARG3, DISPATCH_J(exitno)(DISPATCH)
2381 | addi CARG2, sp, 16
2382 | bl extern lj_trace_exit // (jit_State *J, ExitState *ex)
2383 | // Returns MULTRES (unscaled) or negated error code.
2384 | lwz TMP1, L->cframe
2385 | lwz TMP2, 0(sp)
2386 | lwz BASE, L->base
2387 | rlwinm sp, TMP1, 0, 0, 29
2388 | lwz PC, SAVE_PC // Get SAVE_PC.
2389 | stw TMP2, 0(sp)
2390 | stw L, SAVE_L // Set SAVE_L (on-trace resume/yield).
2391 | b >1
2392#endif
2393 |->vm_exit_interp:
2394#if LJ_HASJIT
2395 | // CARG1 = MULTRES or negated error code, BASE, PC and JGL set.
2396 | lwz L, SAVE_L
2397 | addi DISPATCH, JGL, -GG_DISP2G-32768
2398 |1:
2399 | cmpwi CARG1, 0
2400 | blt >3 // Check for error from exit.
2401 | lwz LFUNC:TMP1, FRAME_FUNC(BASE)
2402 | slwi MULTRES, CARG1, 3
2403 | li TMP2, 0
2404 | stw MULTRES, SAVE_MULTRES
2405 | lwz TMP1, LFUNC:TMP1->pc
2406 | stw TMP2, DISPATCH_GL(jit_L)(DISPATCH)
2407 | lwz KBASE, PC2PROTO(k)(TMP1)
2408 | // Setup type comparison constants.
2409 | li TISNUM, LJ_TISNUM
2410 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
2411 | stw TMP3, TMPD
2412 | li ZERO, 0
2413 | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float).
2414 | lfs TOBIT, TMPD
2415 | stw TMP3, TMPD
2416 | lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double)
2417 | li TISNIL, LJ_TNIL
2418 | stw TMP0, TONUM_HI
2419 | lfs TONUM, TMPD
2420 | // Modified copy of ins_next which handles function header dispatch, too.
2421 | lwz INS, 0(PC)
2422 | addi PC, PC, 4
2423 | // Assumes TISNIL == ~LJ_VMST_INTERP == -1.
2424 | stw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
2425 | decode_OP4 TMP1, INS
2426 | decode_RA8 RA, INS
2427 | lwzx TMP0, DISPATCH, TMP1
2428 | mtctr TMP0
2429 | cmplwi TMP1, BC_FUNCF*4 // Function header?
2430 | bge >2
2431 | decode_RB8 RB, INS
2432 | decode_RD8 RD, INS
2433 | decode_RC8 RC, INS
2434 | bctr
2435 |2:
2436 | subi RC, MULTRES, 8
2437 | add RA, RA, BASE
2438 | bctr
2439 |
2440 |3: // Rethrow error from the right C frame.
2441 | neg CARG2, CARG1
2442 | mr CARG1, L
2443 | bl extern lj_err_throw // (lua_State *L, int errcode)
2444#endif
2445 |
2446 |//-----------------------------------------------------------------------
2447 |//-- Math helper functions ----------------------------------------------
2448 |//-----------------------------------------------------------------------
2449 |
2450 | // NYI: Use internal implementation.
2451 |->vm_floor:
2452 | b extern floor
2453 |->vm_ceil:
2454 | b extern ceil
2455 |->vm_trunc:
2456#if LJ_HASJIT
2457 | b extern trunc
2458#endif
2459 |
2460 |->vm_modi:
2461 | divwo. TMP0, CARG1, CARG2
2462 | bso >1
2463 | xor. CARG3, CARG1, CARG2
2464 | mullw TMP0, TMP0, CARG2
2465 | sub CARG1, CARG1, TMP0
2466 | bgelr
2467 | cmpwi CARG1, 0; beqlr
2468 | add CARG1, CARG1, CARG2
2469 | blr
2470 |1:
2471 | cmpwi CARG2, 0
2472 | li CARG1, 0
2473 | beqlr
2474 | mcrxr cr0 // Clear SO for -2147483648 % -1 and return 0.
2475 | blr
2476 |
2477 |// Callable from C: double lj_vm_foldarith(double x, double y, int op)
2478 |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
2479 |// and basic math functions. ORDER ARITH
2480 |->vm_foldarith:
2481 | cmplwi CARG1, 1
2482 | beq >1; bgt >2
2483 | fadd FARG1, FARG1, FARG2; blr
2484 |1:
2485 | fsub FARG1, FARG1, FARG2; blr
2486 |2:
2487 | cmplwi CARG1, 3; beq >1; bgt >2
2488 | fmul FARG1, FARG1, FARG2; blr
2489 |1:
2490 | fdiv FARG1, FARG1, FARG2; blr
2491 |2:
2492 | cmplwi CARG1, 5; beq >1; bgt >2
2493 | // NYI: Use internal implementation of floor and avoid spills.
2494 | stwu sp, -32(sp); stfd f14, 16(sp); stfd f15, 24(sp)
2495 | mflr r0
2496 | fmr f14, FARG1
2497 | fdiv FARG1, FARG1, FARG2
2498 | stw r0, 36(sp)
2499 | fmr f15, FARG2
2500 | bl extern floor
2501 | lwz r0, 36(sp)
2502 | fmul FARG1, FARG1, f15
2503 | mtlr r0
2504 | fsub FARG1, f14, FARG1
2505 | lfd f14, 16(sp); lfd f15, 24(sp); addi sp, sp, 32; blr
2506 |1:
2507 | b extern pow
2508 |2:
2509 | cmplwi CARG1, 7; beq >1; bgt >2
2510 | fneg FARG1, FARG1; blr
2511 |1:
2512 | fabs FARG1, FARG1; blr
2513 |2:
2514#if LJ_HASJIT
2515 | cmplwi CARG1, 9; beq >9; bgt >2
2516 | b extern atan2
2517 | // No support needed for IR_LDEXP.
2518 |2:
2519 | cmplwi CARG1, 11; bgt >9
2520 | fsub f0, FARG1, FARG2
2521 | beq >1
2522 | fsel FARG1, f0, FARG2, FARG1 // IR_MAX
2523 | blr
2524 |1:
2525 | fsel FARG1, f0, FARG1, FARG2 // IR_MIN
2526 | blr
2527 |9:
2528 | NYI // Bad op.
2529#else
2530 | NYI // Other operations only needed by JIT compiler.
2531#endif
2532 |
2533 |//-----------------------------------------------------------------------
2534 |//-- Miscellaneous functions --------------------------------------------
2535 |//-----------------------------------------------------------------------
2536 |
2537 |//-----------------------------------------------------------------------
2538 |//-- FFI helper functions -----------------------------------------------
2539 |//-----------------------------------------------------------------------
2540 |
2541 |// Handler for callback functions. Callback slot number in r11, g in r12.
2542 |->vm_ffi_callback:
2543#if LJ_HASFFI
2544 |.type CTSTATE, CTState, PC
2545 | saveregs
2546 | lwz CTSTATE, GL:r12->ctype_state
2547 | addi DISPATCH, r12, GG_G2DISP
2548 | stw r11, CTSTATE->cb.slot
2549 | stw r3, CTSTATE->cb.gpr[0]
2550 | stfd f1, CTSTATE->cb.fpr[0]
2551 | stw r4, CTSTATE->cb.gpr[1]
2552 | stfd f2, CTSTATE->cb.fpr[1]
2553 | stw r5, CTSTATE->cb.gpr[2]
2554 | stfd f3, CTSTATE->cb.fpr[2]
2555 | stw r6, CTSTATE->cb.gpr[3]
2556 | stfd f4, CTSTATE->cb.fpr[3]
2557 | stw r7, CTSTATE->cb.gpr[4]
2558 | stfd f5, CTSTATE->cb.fpr[4]
2559 | stw r8, CTSTATE->cb.gpr[5]
2560 | stfd f6, CTSTATE->cb.fpr[5]
2561 | stw r9, CTSTATE->cb.gpr[6]
2562 | stfd f7, CTSTATE->cb.fpr[6]
2563 | stw r10, CTSTATE->cb.gpr[7]
2564 | stfd f8, CTSTATE->cb.fpr[7]
2565 | addi TMP0, sp, CFRAME_SPACE+8
2566 | stw TMP0, CTSTATE->cb.stack
2567 | mr CARG1, CTSTATE
2568 | stw CTSTATE, SAVE_PC // Any value outside of bytecode is ok.
2569 | mr CARG2, sp
2570 | bl extern lj_ccallback_enter // (CTState *cts, void *cf)
2571 | // Returns lua_State *.
2572 | lwz BASE, L:CRET1->base
2573 | li TISNUM, LJ_TISNUM // Setup type comparison constants.
2574 | lwz RC, L:CRET1->top
2575 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
2576 | li ZERO, 0
2577 | mr L, CRET1
2578 | stw TMP3, TMPD
2579 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2580 | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float).
2581 | li TISNIL, LJ_TNIL
2582 | li_vmstate INTERP
2583 | lfs TOBIT, TMPD
2584 | stw TMP3, TMPD
2585 | sub RC, RC, BASE
2586 | st_vmstate
2587 | lfs TONUM, TMPD
2588 | ins_callt
2589#endif
2590 |
2591 |->cont_ffi_callback: // Return from FFI callback.
2592#if LJ_HASFFI
2593 | lwz CTSTATE, DISPATCH_GL(ctype_state)(DISPATCH)
2594 | stw BASE, L->base
2595 | stw RB, L->top
2596 | stw L, CTSTATE->L
2597 | mr CARG1, CTSTATE
2598 | mr CARG2, RA
2599 | bl extern lj_ccallback_leave // (CTState *cts, TValue *o)
2600 | lwz CRET1, CTSTATE->cb.gpr[0]
2601 | lfd FARG1, CTSTATE->cb.fpr[0]
2602 | lwz CRET2, CTSTATE->cb.gpr[1]
2603 | b ->vm_leave_unw
2604#endif
2605 |
2606 |->vm_ffi_call: // Call C function via FFI.
2607 | // Caveat: needs special frame unwinding, see below.
2608#if LJ_HASFFI
2609 | .type CCSTATE, CCallState, CARG1
2610 | lwz TMP1, CCSTATE->spadj
2611 | mflr TMP0
2612 | lbz CARG2, CCSTATE->nsp
2613 | lbz CARG3, CCSTATE->nfpr
2614 | neg TMP1, TMP1
2615 | stw TMP0, 4(sp)
2616 | cmpwi cr1, CARG3, 0
2617 | mr TMP2, sp
2618 | addic. CARG2, CARG2, -1
2619 | stwux sp, sp, TMP1
2620 | crnot 4*cr1+eq, 4*cr1+eq // For vararg calls.
2621 | stw r14, -4(TMP2)
2622 | li TMP3, 0
2623 | stw CCSTATE, -8(TMP2)
2624 | mr r14, TMP2
2625 | la TMP1, CCSTATE->stack
2626 | slwi CARG2, CARG2, 2
2627 | blty >2
2628 | la TMP2, 8(sp)
2629 |1:
2630 | lwzx TMP0, TMP1, CARG2
2631 | stwx TMP0, TMP2, CARG2
2632 | addic. CARG2, CARG2, -4
2633 | bge <1
2634 |2:
2635 | bney cr1, >3
2636 | lfd f1, CCSTATE->fpr[0]
2637 | lfd f2, CCSTATE->fpr[1]
2638 | lfd f3, CCSTATE->fpr[2]
2639 | lfd f4, CCSTATE->fpr[3]
2640 | lfd f5, CCSTATE->fpr[4]
2641 | lfd f6, CCSTATE->fpr[5]
2642 | lfd f7, CCSTATE->fpr[6]
2643 | lfd f8, CCSTATE->fpr[7]
2644 |3:
2645 | lwz TMP0, CCSTATE->func
2646 | lwz CARG2, CCSTATE->gpr[1]
2647 | lwz CARG3, CCSTATE->gpr[2]
2648 | lwz CARG4, CCSTATE->gpr[3]
2649 | lwz CARG5, CCSTATE->gpr[4]
2650 | mtctr TMP0
2651 | lwz r8, CCSTATE->gpr[5]
2652 | lwz r9, CCSTATE->gpr[6]
2653 | lwz r10, CCSTATE->gpr[7]
2654 | lwz CARG1, CCSTATE->gpr[0] // Do this last, since CCSTATE is CARG1.
2655 | bctrl
2656 | lwz CCSTATE:TMP1, -8(r14)
2657 | lwz TMP2, -4(r14)
2658 | lwz TMP0, 4(r14)
2659 | stw CARG1, CCSTATE:TMP1->gpr[0]
2660 | stfd FARG1, CCSTATE:TMP1->fpr[0]
2661 | stw CARG2, CCSTATE:TMP1->gpr[1]
2662 | mtlr TMP0
2663 | stw CARG3, CCSTATE:TMP1->gpr[2]
2664 | mr sp, r14
2665 | stw CARG4, CCSTATE:TMP1->gpr[3]
2666 | mr r14, TMP2
2667 | blr
2668#endif
2669 |// Note: vm_ffi_call must be the last function in this object file!
2670 |
2671 |//-----------------------------------------------------------------------
2672}
2673
2674/* Generate the code for a single instruction. */
2675static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2676{
2677 int vk = 0;
2678 |=>defop:
2679
2680 switch (op) {
2681
2682 /* -- Comparison ops ---------------------------------------------------- */
2683
2684 /* Remember: all ops branch for a true comparison, fall through otherwise. */
2685
2686 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
2687 | // RA = src1*8, RD = src2*8, JMP with RD = target
2688 if (LJ_DUALNUM) {
2689 | lwzux TMP0, RA, BASE
2690 | addi PC, PC, 4
2691 | lwz CARG2, 4(RA)
2692 | lwzux TMP1, RD, BASE
2693 | lwz TMP2, -4(PC)
2694 | checknum cr0, TMP0
2695 | lwz CARG3, 4(RD)
2696 | decode_RD4 TMP2, TMP2
2697 | checknum cr1, TMP1
2698 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
2699 | bne cr0, >7
2700 | bne cr1, >8
2701 | cmpw CARG2, CARG3
2702 if (op == BC_ISLT) {
2703 | bge >2
2704 } else if (op == BC_ISGE) {
2705 | blt >2
2706 } else if (op == BC_ISLE) {
2707 | bgt >2
2708 } else {
2709 | ble >2
2710 }
2711 |1:
2712 | add PC, PC, TMP2
2713 |2:
2714 | ins_next
2715 |
2716 |7: // RA is not an integer.
2717 | bgt cr0, ->vmeta_comp
2718 | // RA is a number.
2719 | lfd f0, 0(RA)
2720 | bgt cr1, ->vmeta_comp
2721 | blt cr1, >4
2722 | // RA is a number, RD is an integer.
2723 | tonum_i f1, CARG3
2724 | b >5
2725 |
2726 |8: // RA is an integer, RD is not an integer.
2727 | bgt cr1, ->vmeta_comp
2728 | // RA is an integer, RD is a number.
2729 | tonum_i f0, CARG2
2730 |4:
2731 | lfd f1, 0(RD)
2732 |5:
2733 | fcmpu cr0, f0, f1
2734 if (op == BC_ISLT) {
2735 | bge <2
2736 } else if (op == BC_ISGE) {
2737 | blt <2
2738 } else if (op == BC_ISLE) {
2739 | cror 4*cr0+lt, 4*cr0+lt, 4*cr0+eq
2740 | bge <2
2741 } else {
2742 | cror 4*cr0+lt, 4*cr0+lt, 4*cr0+eq
2743 | blt <2
2744 }
2745 | b <1
2746 } else {
2747 | lwzx TMP0, BASE, RA
2748 | addi PC, PC, 4
2749 | lfdx f0, BASE, RA
2750 | lwzx TMP1, BASE, RD
2751 | checknum cr0, TMP0
2752 | lwz TMP2, -4(PC)
2753 | lfdx f1, BASE, RD
2754 | checknum cr1, TMP1
2755 | decode_RD4 TMP2, TMP2
2756 | bge cr0, ->vmeta_comp
2757 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
2758 | bge cr1, ->vmeta_comp
2759 | fcmpu cr0, f0, f1
2760 if (op == BC_ISLT) {
2761 | bge >1
2762 } else if (op == BC_ISGE) {
2763 | blt >1
2764 } else if (op == BC_ISLE) {
2765 | cror 4*cr0+lt, 4*cr0+lt, 4*cr0+eq
2766 | bge >1
2767 } else {
2768 | cror 4*cr0+lt, 4*cr0+lt, 4*cr0+eq
2769 | blt >1
2770 }
2771 | add PC, PC, TMP2
2772 |1:
2773 | ins_next
2774 }
2775 break;
2776
2777 case BC_ISEQV: case BC_ISNEV:
2778 vk = op == BC_ISEQV;
2779 | // RA = src1*8, RD = src2*8, JMP with RD = target
2780 if (LJ_DUALNUM) {
2781 | lwzux TMP0, RA, BASE
2782 | addi PC, PC, 4
2783 | lwz CARG2, 4(RA)
2784 | lwzux TMP1, RD, BASE
2785 | checknum cr0, TMP0
2786 | lwz TMP2, -4(PC)
2787 | checknum cr1, TMP1
2788 | decode_RD4 TMP2, TMP2
2789 | lwz CARG3, 4(RD)
2790 | cror 4*cr7+gt, 4*cr0+gt, 4*cr1+gt
2791 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
2792 if (vk) {
2793 | ble cr7, ->BC_ISEQN_Z
2794 } else {
2795 | ble cr7, ->BC_ISNEN_Z
2796 }
2797 } else {
2798 | lwzux TMP0, RA, BASE
2799 | lwz TMP2, 0(PC)
2800 | lfd f0, 0(RA)
2801 | addi PC, PC, 4
2802 | lwzux TMP1, RD, BASE
2803 | checknum cr0, TMP0
2804 | decode_RD4 TMP2, TMP2
2805 | lfd f1, 0(RD)
2806 | checknum cr1, TMP1
2807 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
2808 | bge cr0, >5
2809 | bge cr1, >5
2810 | fcmpu cr0, f0, f1
2811 if (vk) {
2812 | bne >1
2813 | add PC, PC, TMP2
2814 } else {
2815 | beq >1
2816 | add PC, PC, TMP2
2817 }
2818 |1:
2819 | ins_next
2820 }
2821 |5: // Either or both types are not numbers.
2822 if (!LJ_DUALNUM) {
2823 | lwz CARG2, 4(RA)
2824 | lwz CARG3, 4(RD)
2825 }
2826 if (LJ_HASFFI) {
2827 | cmpwi cr7, TMP0, LJ_TCDATA
2828 | cmpwi cr5, TMP1, LJ_TCDATA
2829 }
2830 | not TMP3, TMP0
2831 | cmplw TMP0, TMP1
2832 | cmplwi cr1, TMP3, ~LJ_TISPRI // Primitive?
2833 if (LJ_HASFFI) {
2834 | cror 4*cr7+eq, 4*cr7+eq, 4*cr5+eq
2835 }
2836 | cmplwi cr6, TMP3, ~LJ_TISTABUD // Table or userdata?
2837 if (LJ_HASFFI) {
2838 | beq cr7, ->vmeta_equal_cd
2839 }
2840 | cmplw cr5, CARG2, CARG3
2841 | crandc 4*cr0+gt, 4*cr0+eq, 4*cr1+gt // 2: Same type and primitive.
2842 | crorc 4*cr0+lt, 4*cr5+eq, 4*cr0+eq // 1: Same tv or different type.
2843 | crand 4*cr0+eq, 4*cr0+eq, 4*cr5+eq // 0: Same type and same tv.
2844 | mr SAVE0, PC
2845 | cror 4*cr0+eq, 4*cr0+eq, 4*cr0+gt // 0 or 2.
2846 | cror 4*cr0+lt, 4*cr0+lt, 4*cr0+gt // 1 or 2.
2847 if (vk) {
2848 | bne cr0, >6
2849 | add PC, PC, TMP2
2850 |6:
2851 } else {
2852 | beq cr0, >6
2853 | add PC, PC, TMP2
2854 |6:
2855 }
2856 if (LJ_DUALNUM) {
2857 | bge cr0, >2 // Done if 1 or 2.
2858 |1:
2859 | ins_next
2860 |2:
2861 } else {
2862 | blt cr0, <1 // Done if 1 or 2.
2863 }
2864 | blt cr6, <1 // Done if not tab/ud.
2865 |
2866 | // Different tables or userdatas. Need to check __eq metamethod.
2867 | // Field metatable must be at same offset for GCtab and GCudata!
2868 | lwz TAB:TMP2, TAB:CARG2->metatable
2869 | li CARG4, 1-vk // ne = 0 or 1.
2870 | cmplwi TAB:TMP2, 0
2871 | beq <1 // No metatable?
2872 | lbz TMP2, TAB:TMP2->nomm
2873 | andi. TMP2, TMP2, 1<<MM_eq
2874 | bne <1 // Or 'no __eq' flag set?
2875 | mr PC, SAVE0 // Restore old PC.
2876 | b ->vmeta_equal // Handle __eq metamethod.
2877 break;
2878
2879 case BC_ISEQS: case BC_ISNES:
2880 vk = op == BC_ISEQS;
2881 | // RA = src*8, RD = str_const*8 (~), JMP with RD = target
2882 | lwzux TMP0, RA, BASE
2883 | srwi RD, RD, 1
2884 | lwz STR:TMP3, 4(RA)
2885 | lwz TMP2, 0(PC)
2886 | subfic RD, RD, -4
2887 | addi PC, PC, 4
2888 if (LJ_HASFFI) {
2889 | cmpwi TMP0, LJ_TCDATA
2890 }
2891 | lwzx STR:TMP1, KBASE, RD // KBASE-4-str_const*4
2892 | subfic TMP0, TMP0, LJ_TSTR
2893 if (LJ_HASFFI) {
2894 | beq ->vmeta_equal_cd
2895 }
2896 | sub TMP1, STR:TMP1, STR:TMP3
2897 | or TMP0, TMP0, TMP1
2898 | decode_RD4 TMP2, TMP2
2899 | subfic TMP0, TMP0, 0
2900 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
2901 | subfe TMP1, TMP1, TMP1
2902 if (vk) {
2903 | andc TMP2, TMP2, TMP1
2904 } else {
2905 | and TMP2, TMP2, TMP1
2906 }
2907 | add PC, PC, TMP2
2908 | ins_next
2909 break;
2910
2911 case BC_ISEQN: case BC_ISNEN:
2912 vk = op == BC_ISEQN;
2913 | // RA = src*8, RD = num_const*8, JMP with RD = target
2914 if (LJ_DUALNUM) {
2915 | lwzux TMP0, RA, BASE
2916 | addi PC, PC, 4
2917 | lwz CARG2, 4(RA)
2918 | lwzux TMP1, RD, KBASE
2919 | checknum cr0, TMP0
2920 | lwz TMP2, -4(PC)
2921 | checknum cr1, TMP1
2922 | decode_RD4 TMP2, TMP2
2923 | lwz CARG3, 4(RD)
2924 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
2925 if (vk) {
2926 |->BC_ISEQN_Z:
2927 } else {
2928 |->BC_ISNEN_Z:
2929 }
2930 | bne cr0, >7
2931 | bne cr1, >8
2932 | cmpw CARG2, CARG3
2933 |4:
2934 } else {
2935 if (vk) {
2936 |->BC_ISEQN_Z: // Dummy label.
2937 } else {
2938 |->BC_ISNEN_Z: // Dummy label.
2939 }
2940 | lwzx TMP0, BASE, RA
2941 | addi PC, PC, 4
2942 | lfdx f0, BASE, RA
2943 | lwz TMP2, -4(PC)
2944 | lfdx f1, KBASE, RD
2945 | decode_RD4 TMP2, TMP2
2946 | checknum TMP0
2947 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
2948 | bge >3
2949 | fcmpu cr0, f0, f1
2950 }
2951 if (vk) {
2952 | bne >1
2953 | add PC, PC, TMP2
2954 |1:
2955 if (!LJ_HASFFI) {
2956 |3:
2957 }
2958 } else {
2959 | beq >2
2960 |1:
2961 if (!LJ_HASFFI) {
2962 |3:
2963 }
2964 | add PC, PC, TMP2
2965 |2:
2966 }
2967 | ins_next
2968 if (LJ_HASFFI) {
2969 |3:
2970 | cmpwi TMP0, LJ_TCDATA
2971 | beq ->vmeta_equal_cd
2972 | b <1
2973 }
2974 if (LJ_DUALNUM) {
2975 |7: // RA is not an integer.
2976 | bge cr0, <3
2977 | // RA is a number.
2978 | lfd f0, 0(RA)
2979 | blt cr1, >1
2980 | // RA is a number, RD is an integer.
2981 | tonum_i f1, CARG3
2982 | b >2
2983 |
2984 |8: // RA is an integer, RD is a number.
2985 | tonum_i f0, CARG2
2986 |1:
2987 | lfd f1, 0(RD)
2988 |2:
2989 | fcmpu cr0, f0, f1
2990 | b <4
2991 }
2992 break;
2993
2994 case BC_ISEQP: case BC_ISNEP:
2995 vk = op == BC_ISEQP;
2996 | // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target
2997 | lwzx TMP0, BASE, RA
2998 | srwi TMP1, RD, 3
2999 | lwz TMP2, 0(PC)
3000 | not TMP1, TMP1
3001 | addi PC, PC, 4
3002 if (LJ_HASFFI) {
3003 | cmpwi TMP0, LJ_TCDATA
3004 }
3005 | sub TMP0, TMP0, TMP1
3006 if (LJ_HASFFI) {
3007 | beq ->vmeta_equal_cd
3008 }
3009 | decode_RD4 TMP2, TMP2
3010 | addic TMP0, TMP0, -1
3011 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
3012 | subfe TMP1, TMP1, TMP1
3013 if (vk) {
3014 | and TMP2, TMP2, TMP1
3015 } else {
3016 | andc TMP2, TMP2, TMP1
3017 }
3018 | add PC, PC, TMP2
3019 | ins_next
3020 break;
3021
3022 /* -- Unary test and copy ops ------------------------------------------- */
3023
3024 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
3025 | // RA = dst*8 or unused, RD = src*8, JMP with RD = target
3026 | lwzx TMP0, BASE, RD
3027 | lwz INS, 0(PC)
3028 | addi PC, PC, 4
3029 if (op == BC_IST || op == BC_ISF) {
3030 | subfic TMP0, TMP0, LJ_TTRUE
3031 | decode_RD4 TMP2, INS
3032 | subfe TMP1, TMP1, TMP1
3033 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
3034 if (op == BC_IST) {
3035 | andc TMP2, TMP2, TMP1
3036 } else {
3037 | and TMP2, TMP2, TMP1
3038 }
3039 | add PC, PC, TMP2
3040 } else {
3041 | li TMP1, LJ_TFALSE
3042 | lfdx f0, BASE, RD
3043 | cmplw TMP0, TMP1
3044 if (op == BC_ISTC) {
3045 | bge >1
3046 } else {
3047 | blt >1
3048 }
3049 | addis PC, PC, -(BCBIAS_J*4 >> 16)
3050 | decode_RD4 TMP2, INS
3051 | stfdx f0, BASE, RA
3052 | add PC, PC, TMP2
3053 |1:
3054 }
3055 | ins_next
3056 break;
3057
3058 /* -- Unary ops --------------------------------------------------------- */
3059
3060 case BC_MOV:
3061 | // RA = dst*8, RD = src*8
3062 | ins_next1
3063 | lfdx f0, BASE, RD
3064 | stfdx f0, BASE, RA
3065 | ins_next2
3066 break;
3067 case BC_NOT:
3068 | // RA = dst*8, RD = src*8
3069 | ins_next1
3070 | lwzx TMP0, BASE, RD
3071 | subfic TMP1, TMP0, LJ_TTRUE
3072 | adde TMP0, TMP0, TMP1
3073 | stwx TMP0, BASE, RA
3074 | ins_next2
3075 break;
3076 case BC_UNM:
3077 | // RA = dst*8, RD = src*8
3078 | lwzux TMP1, RD, BASE
3079 | lwz TMP0, 4(RD)
3080 | checknum TMP1
3081 if (LJ_DUALNUM) {
3082 | bne >5
3083 | nego. TMP0, TMP0
3084 | bso >4
3085 |1:
3086 | ins_next1
3087 | stwux TISNUM, RA, BASE
3088 | stw TMP0, 4(RA)
3089 |3:
3090 | ins_next2
3091 |4: // Potential overflow.
3092 | mcrxr cr0; bley <1 // Ignore unrelated overflow.
3093 | lus TMP1, 0x41e0 // 2^31.
3094 | li TMP0, 0
3095 | b >7
3096 }
3097 |5:
3098 | bge ->vmeta_unm
3099 | xoris TMP1, TMP1, 0x8000
3100 |7:
3101 | ins_next1
3102 | stwux TMP1, RA, BASE
3103 | stw TMP0, 4(RA)
3104 if (LJ_DUALNUM) {
3105 | b <3
3106 } else {
3107 | ins_next2
3108 }
3109 break;
3110 case BC_LEN:
3111 | // RA = dst*8, RD = src*8
3112 | lwzux TMP0, RD, BASE
3113 | lwz CARG1, 4(RD)
3114 | checkstr TMP0; bne >2
3115 | lwz CRET1, STR:CARG1->len
3116 |1:
3117 if (LJ_DUALNUM) {
3118 | ins_next1
3119 | stwux TISNUM, RA, BASE
3120 | stw CRET1, 4(RA)
3121 } else {
3122 | tonum_u f0, CRET1 // Result is a non-negative integer.
3123 | ins_next1
3124 | stfdx f0, BASE, RA
3125 }
3126 | ins_next2
3127 |2:
3128 | checktab TMP0; bne ->vmeta_len
3129#ifdef LUAJIT_ENABLE_LUA52COMPAT
3130 | lwz TAB:TMP2, TAB:CARG1->metatable
3131 | cmplwi TAB:TMP2, 0
3132 | bne >9
3133 |3:
3134#endif
3135 |->BC_LEN_Z:
3136 | bl extern lj_tab_len // (GCtab *t)
3137 | // Returns uint32_t (but less than 2^31).
3138 | b <1
3139#ifdef LUAJIT_ENABLE_LUA52COMPAT
3140 |9:
3141 | lbz TMP0, TAB:TMP2->nomm
3142 | andi. TMP0, TMP0, 1<<MM_len
3143 | bne <3 // 'no __len' flag set: done.
3144 | b ->vmeta_len
3145#endif
3146 break;
3147
3148 /* -- Binary ops -------------------------------------------------------- */
3149
3150 |.macro ins_arithpre
3151 | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8
3152 ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
3153 ||switch (vk) {
3154 ||case 0:
3155 | lwzx TMP1, BASE, RB
3156 ||if (LJ_DUALNUM) {
3157 | lwzx TMP2, KBASE, RC
3158 ||}
3159 | lfdx f14, BASE, RB
3160 | lfdx f15, KBASE, RC
3161 ||if (LJ_DUALNUM) {
3162 | checknum cr0, TMP1
3163 | checknum cr1, TMP2
3164 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3165 | bge ->vmeta_arith_vn
3166 ||} else {
3167 | checknum TMP1; bge ->vmeta_arith_vn
3168 ||}
3169 || break;
3170 ||case 1:
3171 | lwzx TMP1, BASE, RB
3172 ||if (LJ_DUALNUM) {
3173 | lwzx TMP2, KBASE, RC
3174 ||}
3175 | lfdx f15, BASE, RB
3176 | lfdx f14, KBASE, RC
3177 ||if (LJ_DUALNUM) {
3178 | checknum cr0, TMP1
3179 | checknum cr1, TMP2
3180 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3181 | bge ->vmeta_arith_nv
3182 ||} else {
3183 | checknum TMP1; bge ->vmeta_arith_nv
3184 ||}
3185 || break;
3186 ||default:
3187 | lwzx TMP1, BASE, RB
3188 | lwzx TMP2, BASE, RC
3189 | lfdx f14, BASE, RB
3190 | lfdx f15, BASE, RC
3191 | checknum cr0, TMP1
3192 | checknum cr1, TMP2
3193 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3194 | bge ->vmeta_arith_vv
3195 || break;
3196 ||}
3197 |.endmacro
3198 |
3199 |.macro ins_arithfallback, ins
3200 ||switch (vk) {
3201 ||case 0:
3202 | ins ->vmeta_arith_vn2
3203 || break;
3204 ||case 1:
3205 | ins ->vmeta_arith_nv2
3206 || break;
3207 ||default:
3208 | ins ->vmeta_arith_vv2
3209 || break;
3210 ||}
3211 |.endmacro
3212 |
3213 |.macro intmod, a, b, c
3214 | bl ->vm_modi
3215 |.endmacro
3216 |
3217 |.macro fpmod, a, b, c
3218 |->BC_MODVN_Z:
3219 | fdiv FARG1, b, c
3220 | // NYI: Use internal implementation of floor.
3221 | bl extern floor // floor(b/c)
3222 | fmul a, FARG1, c
3223 | fsub a, b, a // b - floor(b/c)*c
3224 |.endmacro
3225 |
3226 |.macro ins_arithfp, fpins
3227 | ins_arithpre
3228 |.if "fpins" == "fpmod_"
3229 | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway.
3230 |.else
3231 | fpins f0, f14, f15
3232 | ins_next1
3233 | stfdx f0, BASE, RA
3234 | ins_next2
3235 |.endif
3236 |.endmacro
3237 |
3238 |.macro ins_arithdn, intins, fpins
3239 | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8
3240 ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
3241 ||switch (vk) {
3242 ||case 0:
3243 | lwzux TMP1, RB, BASE
3244 | lwzux TMP2, RC, KBASE
3245 | lwz CARG1, 4(RB)
3246 | checknum cr0, TMP1
3247 | lwz CARG2, 4(RC)
3248 || break;
3249 ||case 1:
3250 | lwzux TMP1, RB, BASE
3251 | lwzux TMP2, RC, KBASE
3252 | lwz CARG2, 4(RB)
3253 | checknum cr0, TMP1
3254 | lwz CARG1, 4(RC)
3255 || break;
3256 ||default:
3257 | lwzux TMP1, RB, BASE
3258 | lwzux TMP2, RC, BASE
3259 | lwz CARG1, 4(RB)
3260 | checknum cr0, TMP1
3261 | lwz CARG2, 4(RC)
3262 || break;
3263 ||}
3264 | checknum cr1, TMP2
3265 | bne >5
3266 | bne cr1, >5
3267 | intins CARG1, CARG1, CARG2
3268 | bso >4
3269 |1:
3270 | ins_next1
3271 | stwux TISNUM, RA, BASE
3272 | stw CARG1, 4(RA)
3273 |2:
3274 | ins_next2
3275 |4: // Overflow.
3276 | mcrxr cr0; bley <1 // Ignore unrelated overflow.
3277 | ins_arithfallback b
3278 |5: // FP variant.
3279 ||if (vk == 1) {
3280 | lfd f15, 0(RB)
3281 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3282 | lfd f14, 0(RC)
3283 ||} else {
3284 | lfd f14, 0(RB)
3285 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3286 | lfd f15, 0(RC)
3287 ||}
3288 | ins_arithfallback bge
3289 |.if "fpins" == "fpmod_"
3290 | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway.
3291 |.else
3292 | fpins f0, f14, f15
3293 | ins_next1
3294 | stfdx f0, BASE, RA
3295 | b <2
3296 |.endif
3297 |.endmacro
3298 |
3299 |.macro ins_arith, intins, fpins
3300 ||if (LJ_DUALNUM) {
3301 | ins_arithdn intins, fpins
3302 ||} else {
3303 | ins_arithfp fpins
3304 ||}
3305 |.endmacro
3306
3307 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
3308 | ins_arith addo., fadd
3309 break;
3310 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
3311 | ins_arith subo., fsub
3312 break;
3313 case BC_MULVN: case BC_MULNV: case BC_MULVV:
3314 | ins_arith mullwo., fmul
3315 break;
3316 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
3317 | ins_arithfp fdiv
3318 break;
3319 case BC_MODVN:
3320 | ins_arith intmod, fpmod
3321 break;
3322 case BC_MODNV: case BC_MODVV:
3323 | ins_arith intmod, fpmod_
3324 break;
3325 case BC_POW:
3326 | // NYI: (partial) integer arithmetic.
3327 | lwzx TMP1, BASE, RB
3328 | lfdx FARG1, BASE, RB
3329 | lwzx TMP2, BASE, RC
3330 | lfdx FARG2, BASE, RC
3331 | checknum cr0, TMP1
3332 | checknum cr1, TMP2
3333 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3334 | bge ->vmeta_arith_vv
3335 | bl extern pow
3336 | ins_next1
3337 | stfdx FARG1, BASE, RA
3338 | ins_next2
3339 break;
3340
3341 case BC_CAT:
3342 | // RA = dst*8, RB = src_start*8, RC = src_end*8
3343 | sub CARG3, RC, RB
3344 | stw BASE, L->base
3345 | add CARG2, BASE, RC
3346 | mr SAVE0, RB
3347 |->BC_CAT_Z:
3348 | stw PC, SAVE_PC
3349 | mr CARG1, L
3350 | srwi CARG3, CARG3, 3
3351 | bl extern lj_meta_cat // (lua_State *L, TValue *top, int left)
3352 | // Returns NULL (finished) or TValue * (metamethod).
3353 | cmplwi CRET1, 0
3354 | lwz BASE, L->base
3355 | bne ->vmeta_binop
3356 | ins_next1
3357 | lfdx f0, BASE, SAVE0 // Copy result from RB to RA.
3358 | stfdx f0, BASE, RA
3359 | ins_next2
3360 break;
3361
3362 /* -- Constant ops ------------------------------------------------------ */
3363
3364 case BC_KSTR:
3365 | // RA = dst*8, RD = str_const*8 (~)
3366 | srwi TMP1, RD, 1
3367 | subfic TMP1, TMP1, -4
3368 | ins_next1
3369 | lwzx TMP0, KBASE, TMP1 // KBASE-4-str_const*4
3370 | li TMP2, LJ_TSTR
3371 | stwux TMP2, RA, BASE
3372 | stw TMP0, 4(RA)
3373 | ins_next2
3374 break;
3375 case BC_KCDATA:
3376#if LJ_HASFFI
3377 | // RA = dst*8, RD = cdata_const*8 (~)
3378 | srwi TMP1, RD, 1
3379 | subfic TMP1, TMP1, -4
3380 | ins_next1
3381 | lwzx TMP0, KBASE, TMP1 // KBASE-4-cdata_const*4
3382 | li TMP2, LJ_TCDATA
3383 | stwux TMP2, RA, BASE
3384 | stw TMP0, 4(RA)
3385 | ins_next2
3386#endif
3387 break;
3388 case BC_KSHORT:
3389 | // RA = dst*8, RD = int16_literal*8
3390 if (LJ_DUALNUM) {
3391 | slwi RD, RD, 13
3392 | srawi RD, RD, 16
3393 | ins_next1
3394 | stwux TISNUM, RA, BASE
3395 | stw RD, 4(RA)
3396 | ins_next2
3397 } else {
3398 | // The soft-float approach is faster.
3399 | slwi RD, RD, 13
3400 | srawi TMP1, RD, 31
3401 | xor TMP2, TMP1, RD
3402 | sub TMP2, TMP2, TMP1 // TMP2 = abs(x)
3403 | cntlzw TMP3, TMP2
3404 | subfic TMP1, TMP3, 0x40d // TMP1 = exponent-1
3405 | slw TMP2, TMP2, TMP3 // TMP2 = left aligned mantissa
3406 | subfic TMP3, RD, 0
3407 | slwi TMP1, TMP1, 20
3408 | rlwimi RD, TMP2, 21, 1, 31 // hi = sign(x) | (mantissa>>11)
3409 | subfe TMP0, TMP0, TMP0
3410 | add RD, RD, TMP1 // hi = hi + exponent-1
3411 | and RD, RD, TMP0 // hi = x == 0 ? 0 : hi
3412 | ins_next1
3413 | stwux RD, RA, BASE
3414 | stw ZERO, 4(RA)
3415 | ins_next2
3416 }
3417 break;
3418 case BC_KNUM:
3419 | // RA = dst*8, RD = num_const*8
3420 | ins_next1
3421 | lfdx f0, KBASE, RD
3422 | stfdx f0, BASE, RA
3423 | ins_next2
3424 break;
3425 case BC_KPRI:
3426 | // RA = dst*8, RD = primitive_type*8 (~)
3427 | srwi TMP1, RD, 3
3428 | not TMP0, TMP1
3429 | ins_next1
3430 | stwx TMP0, BASE, RA
3431 | ins_next2
3432 break;
3433 case BC_KNIL:
3434 | // RA = base*8, RD = end*8
3435 | stwx TISNIL, BASE, RA
3436 | addi RA, RA, 8
3437 |1:
3438 | stwx TISNIL, BASE, RA
3439 | cmpw RA, RD
3440 | addi RA, RA, 8
3441 | blt <1
3442 | ins_next_
3443 break;
3444
3445 /* -- Upvalue and function ops ------------------------------------------ */
3446
3447 case BC_UGET:
3448 | // RA = dst*8, RD = uvnum*8
3449 | lwz LFUNC:RB, FRAME_FUNC(BASE)
3450 | srwi RD, RD, 1
3451 | addi RD, RD, offsetof(GCfuncL, uvptr)
3452 | lwzx UPVAL:RB, LFUNC:RB, RD
3453 | ins_next1
3454 | lwz TMP1, UPVAL:RB->v
3455 | lfd f0, 0(TMP1)
3456 | stfdx f0, BASE, RA
3457 | ins_next2
3458 break;
3459 case BC_USETV:
3460 | // RA = uvnum*8, RD = src*8
3461 | lwz LFUNC:RB, FRAME_FUNC(BASE)
3462 | srwi RA, RA, 1
3463 | addi RA, RA, offsetof(GCfuncL, uvptr)
3464 | lfdux f0, RD, BASE
3465 | lwzx UPVAL:RB, LFUNC:RB, RA
3466 | lbz TMP3, UPVAL:RB->marked
3467 | lwz CARG2, UPVAL:RB->v
3468 | andi. TMP3, TMP3, LJ_GC_BLACK // isblack(uv)
3469 | lbz TMP0, UPVAL:RB->closed
3470 | lwz TMP2, 0(RD)
3471 | stfd f0, 0(CARG2)
3472 | cmplwi cr1, TMP0, 0
3473 | lwz TMP1, 4(RD)
3474 | cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
3475 | subi TMP2, TMP2, (LJ_TISNUM+1)
3476 | bne >2 // Upvalue is closed and black?
3477 |1:
3478 | ins_next
3479 |
3480 |2: // Check if new value is collectable.
3481 | cmplwi TMP2, LJ_TISGCV - (LJ_TISNUM+1)
3482 | bge <1 // tvisgcv(v)
3483 | lbz TMP3, GCOBJ:TMP1->gch.marked
3484 | andi. TMP3, TMP3, LJ_GC_WHITES // iswhite(v)
3485 | la CARG1, GG_DISP2G(DISPATCH)
3486 | // Crossed a write barrier. Move the barrier forward.
3487 | beq <1
3488 | bl extern lj_gc_barrieruv // (global_State *g, TValue *tv)
3489 | b <1
3490 break;
3491 case BC_USETS:
3492 | // RA = uvnum*8, RD = str_const*8 (~)
3493 | lwz LFUNC:RB, FRAME_FUNC(BASE)
3494 | srwi TMP1, RD, 1
3495 | srwi RA, RA, 1
3496 | subfic TMP1, TMP1, -4
3497 | addi RA, RA, offsetof(GCfuncL, uvptr)
3498 | lwzx STR:TMP1, KBASE, TMP1 // KBASE-4-str_const*4
3499 | lwzx UPVAL:RB, LFUNC:RB, RA
3500 | lbz TMP3, UPVAL:RB->marked
3501 | lwz CARG2, UPVAL:RB->v
3502 | andi. TMP3, TMP3, LJ_GC_BLACK // isblack(uv)
3503 | lbz TMP3, STR:TMP1->marked
3504 | lbz TMP2, UPVAL:RB->closed
3505 | li TMP0, LJ_TSTR
3506 | stw STR:TMP1, 4(CARG2)
3507 | stw TMP0, 0(CARG2)
3508 | bne >2
3509 |1:
3510 | ins_next
3511 |
3512 |2: // Check if string is white and ensure upvalue is closed.
3513 | andi. TMP3, TMP3, LJ_GC_WHITES // iswhite(str)
3514 | cmplwi cr1, TMP2, 0
3515 | cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
3516 | la CARG1, GG_DISP2G(DISPATCH)
3517 | // Crossed a write barrier. Move the barrier forward.
3518 | beq <1
3519 | bl extern lj_gc_barrieruv // (global_State *g, TValue *tv)
3520 | b <1
3521 break;
3522 case BC_USETN:
3523 | // RA = uvnum*8, RD = num_const*8
3524 | lwz LFUNC:RB, FRAME_FUNC(BASE)
3525 | srwi RA, RA, 1
3526 | addi RA, RA, offsetof(GCfuncL, uvptr)
3527 | lfdx f0, KBASE, RD
3528 | lwzx UPVAL:RB, LFUNC:RB, RA
3529 | ins_next1
3530 | lwz TMP1, UPVAL:RB->v
3531 | stfd f0, 0(TMP1)
3532 | ins_next2
3533 break;
3534 case BC_USETP:
3535 | // RA = uvnum*8, RD = primitive_type*8 (~)
3536 | lwz LFUNC:RB, FRAME_FUNC(BASE)
3537 | srwi RA, RA, 1
3538 | srwi TMP0, RD, 3
3539 | addi RA, RA, offsetof(GCfuncL, uvptr)
3540 | not TMP0, TMP0
3541 | lwzx UPVAL:RB, LFUNC:RB, RA
3542 | ins_next1
3543 | lwz TMP1, UPVAL:RB->v
3544 | stw TMP0, 0(TMP1)
3545 | ins_next2
3546 break;
3547
3548 case BC_UCLO:
3549 | // RA = level*8, RD = target
3550 | lwz TMP1, L->openupval
3551 | branch_RD // Do this first since RD is not saved.
3552 | stw BASE, L->base
3553 | cmplwi TMP1, 0
3554 | mr CARG1, L
3555 | beq >1
3556 | add CARG2, BASE, RA
3557 | bl extern lj_func_closeuv // (lua_State *L, TValue *level)
3558 | lwz BASE, L->base
3559 |1:
3560 | ins_next
3561 break;
3562
3563 case BC_FNEW:
3564 | // RA = dst*8, RD = proto_const*8 (~) (holding function prototype)
3565 | srwi TMP1, RD, 1
3566 | stw BASE, L->base
3567 | subfic TMP1, TMP1, -4
3568 | stw PC, SAVE_PC
3569 | lwzx CARG2, KBASE, TMP1 // KBASE-4-tab_const*4
3570 | mr CARG1, L
3571 | lwz CARG3, FRAME_FUNC(BASE)
3572 | // (lua_State *L, GCproto *pt, GCfuncL *parent)
3573 | bl extern lj_func_newL_gc
3574 | // Returns GCfuncL *.
3575 | lwz BASE, L->base
3576 | li TMP0, LJ_TFUNC
3577 | stwux TMP0, RA, BASE
3578 | stw LFUNC:CRET1, 4(RA)
3579 | ins_next
3580 break;
3581
3582 /* -- Table ops --------------------------------------------------------- */
3583
3584 case BC_TNEW:
3585 case BC_TDUP:
3586 | // RA = dst*8, RD = (hbits|asize)*8 | tab_const*8 (~)
3587 | lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
3588 | mr CARG1, L
3589 | lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
3590 | stw BASE, L->base
3591 | cmplw TMP0, TMP1
3592 | stw PC, SAVE_PC
3593 | bge >5
3594 |1:
3595 if (op == BC_TNEW) {
3596 | rlwinm CARG2, RD, 29, 21, 31
3597 | rlwinm CARG3, RD, 18, 27, 31
3598 | cmpwi CARG2, 0x7ff; beq >3
3599 |2:
3600 | bl extern lj_tab_new // (lua_State *L, int32_t asize, uint32_t hbits)
3601 | // Returns Table *.
3602 } else {
3603 | srwi TMP1, RD, 1
3604 | subfic TMP1, TMP1, -4
3605 | lwzx CARG2, KBASE, TMP1 // KBASE-4-tab_const*4
3606 | bl extern lj_tab_dup // (lua_State *L, Table *kt)
3607 | // Returns Table *.
3608 }
3609 | lwz BASE, L->base
3610 | li TMP0, LJ_TTAB
3611 | stwux TMP0, RA, BASE
3612 | stw TAB:CRET1, 4(RA)
3613 | ins_next
3614 if (op == BC_TNEW) {
3615 |3:
3616 | li CARG2, 0x801
3617 | b <2
3618 }
3619 |5:
3620 | mr SAVE0, RD
3621 | bl extern lj_gc_step_fixtop // (lua_State *L)
3622 | mr RD, SAVE0
3623 | mr CARG1, L
3624 | b <1
3625 break;
3626
3627 case BC_GGET:
3628 | // RA = dst*8, RD = str_const*8 (~)
3629 case BC_GSET:
3630 | // RA = src*8, RD = str_const*8 (~)
3631 | lwz LFUNC:TMP2, FRAME_FUNC(BASE)
3632 | srwi TMP1, RD, 1
3633 | lwz TAB:RB, LFUNC:TMP2->env
3634 | subfic TMP1, TMP1, -4
3635 | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4
3636 if (op == BC_GGET) {
3637 | b ->BC_TGETS_Z
3638 } else {
3639 | b ->BC_TSETS_Z
3640 }
3641 break;
3642
3643 case BC_TGETV:
3644 | // RA = dst*8, RB = table*8, RC = key*8
3645 | lwzux CARG1, RB, BASE
3646 | lwzux CARG2, RC, BASE
3647 | lwz TAB:RB, 4(RB)
3648 if (LJ_DUALNUM) {
3649 | lwz RC, 4(RC)
3650 } else {
3651 | lfd f0, 0(RC)
3652 }
3653 | checktab CARG1
3654 | checknum cr1, CARG2
3655 | bne ->vmeta_tgetv
3656 if (LJ_DUALNUM) {
3657 | lwz TMP0, TAB:RB->asize
3658 | bne cr1, >5
3659 | lwz TMP1, TAB:RB->array
3660 | cmplw TMP0, RC
3661 | slwi TMP2, RC, 3
3662 } else {
3663 | bge cr1, >5
3664 | // Convert number key to integer, check for integerness and range.
3665 | fctiwz f1, f0
3666 | fadd f2, f0, TOBIT
3667 | stfd f1, TMPD
3668 | lwz TMP0, TAB:RB->asize
3669 | fsub f2, f2, TOBIT
3670 | lwz TMP2, TMPD_LO
3671 | lwz TMP1, TAB:RB->array
3672 | fcmpu cr1, f0, f2
3673 | cmplw cr0, TMP0, TMP2
3674 | crand 4*cr0+gt, 4*cr0+gt, 4*cr1+eq
3675 | slwi TMP2, TMP2, 3
3676 }
3677 | ble ->vmeta_tgetv // Integer key and in array part?
3678 | lwzx TMP0, TMP1, TMP2
3679 | lfdx f14, TMP1, TMP2
3680 | checknil TMP0; beq >2
3681 |1:
3682 | ins_next1
3683 | stfdx f14, BASE, RA
3684 | ins_next2
3685 |
3686 |2: // Check for __index if table value is nil.
3687 | lwz TAB:TMP2, TAB:RB->metatable
3688 | cmplwi TAB:TMP2, 0
3689 | beq <1 // No metatable: done.
3690 | lbz TMP0, TAB:TMP2->nomm
3691 | andi. TMP0, TMP0, 1<<MM_index
3692 | bne <1 // 'no __index' flag set: done.
3693 | b ->vmeta_tgetv
3694 |
3695 |5:
3696 | checkstr CARG2; bne ->vmeta_tgetv
3697 if (!LJ_DUALNUM) {
3698 | lwz STR:RC, 4(RC)
3699 }
3700 | b ->BC_TGETS_Z // String key?
3701 break;
3702 case BC_TGETS:
3703 | // RA = dst*8, RB = table*8, RC = str_const*8 (~)
3704 | lwzux CARG1, RB, BASE
3705 | srwi TMP1, RC, 1
3706 | lwz TAB:RB, 4(RB)
3707 | subfic TMP1, TMP1, -4
3708 | checktab CARG1
3709 | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4
3710 | bne ->vmeta_tgets1
3711 |->BC_TGETS_Z:
3712 | // TAB:RB = GCtab *, STR:RC = GCstr *, RA = dst*8
3713 | lwz TMP0, TAB:RB->hmask
3714 | lwz TMP1, STR:RC->hash
3715 | lwz NODE:TMP2, TAB:RB->node
3716 | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
3717 | slwi TMP0, TMP1, 5
3718 | slwi TMP1, TMP1, 3
3719 | sub TMP1, TMP0, TMP1
3720 | add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
3721 |1:
3722 | lwz CARG1, NODE:TMP2->key
3723 | lwz TMP0, 4+offsetof(Node, key)(NODE:TMP2)
3724 | lwz CARG2, NODE:TMP2->val
3725 | lwz TMP1, 4+offsetof(Node, val)(NODE:TMP2)
3726 | checkstr CARG1; bne >4
3727 | cmpw TMP0, STR:RC; bne >4
3728 | checknil CARG2; beq >5 // Key found, but nil value?
3729 |3:
3730 | stwux CARG2, RA, BASE
3731 | stw TMP1, 4(RA)
3732 | ins_next
3733 |
3734 |4: // Follow hash chain.
3735 | lwz NODE:TMP2, NODE:TMP2->next
3736 | cmplwi NODE:TMP2, 0
3737 | bne <1
3738 | // End of hash chain: key not found, nil result.
3739 | li CARG2, LJ_TNIL
3740 |
3741 |5: // Check for __index if table value is nil.
3742 | lwz TAB:TMP2, TAB:RB->metatable
3743 | cmplwi TAB:TMP2, 0
3744 | beq <3 // No metatable: done.
3745 | lbz TMP0, TAB:TMP2->nomm
3746 | andi. TMP0, TMP0, 1<<MM_index
3747 | bne <3 // 'no __index' flag set: done.
3748 | b ->vmeta_tgets
3749 break;
3750 case BC_TGETB:
3751 | // RA = dst*8, RB = table*8, RC = index*8
3752 | lwzux CARG1, RB, BASE
3753 | srwi TMP0, RC, 3
3754 | lwz TAB:RB, 4(RB)
3755 | checktab CARG1; bne ->vmeta_tgetb
3756 | lwz TMP1, TAB:RB->asize
3757 | lwz TMP2, TAB:RB->array
3758 | cmplw TMP0, TMP1; bge ->vmeta_tgetb
3759 | lwzx TMP1, TMP2, RC
3760 | lfdx f0, TMP2, RC
3761 | checknil TMP1; beq >5
3762 |1:
3763 | ins_next1
3764 | stfdx f0, BASE, RA
3765 | ins_next2
3766 |
3767 |5: // Check for __index if table value is nil.
3768 | lwz TAB:TMP2, TAB:RB->metatable
3769 | cmplwi TAB:TMP2, 0
3770 | beq <1 // No metatable: done.
3771 | lbz TMP2, TAB:TMP2->nomm
3772 | andi. TMP2, TMP2, 1<<MM_index
3773 | bne <1 // 'no __index' flag set: done.
3774 | b ->vmeta_tgetb // Caveat: preserve TMP0!
3775 break;
3776
3777 case BC_TSETV:
3778 | // RA = src*8, RB = table*8, RC = key*8
3779 | lwzux CARG1, RB, BASE
3780 | lwzux CARG2, RC, BASE
3781 | lwz TAB:RB, 4(RB)
3782 if (LJ_DUALNUM) {
3783 | lwz RC, 4(RC)
3784 } else {
3785 | lfd f0, 0(RC)
3786 }
3787 | checktab CARG1
3788 | checknum cr1, CARG2
3789 | bne ->vmeta_tsetv
3790 if (LJ_DUALNUM) {
3791 | lwz TMP0, TAB:RB->asize
3792 | bne cr1, >5
3793 | lwz TMP1, TAB:RB->array
3794 | cmplw TMP0, RC
3795 | slwi TMP0, RC, 3
3796 } else {
3797 | bge cr1, >5
3798 | // Convert number key to integer, check for integerness and range.
3799 | fctiwz f1, f0
3800 | fadd f2, f0, TOBIT
3801 | stfd f1, TMPD
3802 | lwz TMP0, TAB:RB->asize
3803 | fsub f2, f2, TOBIT
3804 | lwz TMP2, TMPD_LO
3805 | lwz TMP1, TAB:RB->array
3806 | fcmpu cr1, f0, f2
3807 | cmplw cr0, TMP0, TMP2
3808 | crand 4*cr0+gt, 4*cr0+gt, 4*cr1+eq
3809 | slwi TMP0, TMP2, 3
3810 }
3811 | ble ->vmeta_tsetv // Integer key and in array part?
3812 | lwzx TMP2, TMP1, TMP0
3813 | lbz TMP3, TAB:RB->marked
3814 | lfdx f14, BASE, RA
3815 | checknil TMP2; beq >3
3816 |1:
3817 | andi. TMP2, TMP3, LJ_GC_BLACK // isblack(table)
3818 | stfdx f14, TMP1, TMP0
3819 | bne >7
3820 |2:
3821 | ins_next
3822 |
3823 |3: // Check for __newindex if previous value is nil.
3824 | lwz TAB:TMP2, TAB:RB->metatable
3825 | cmplwi TAB:TMP2, 0
3826 | beq <1 // No metatable: done.
3827 | lbz TMP2, TAB:TMP2->nomm
3828 | andi. TMP2, TMP2, 1<<MM_newindex
3829 | bne <1 // 'no __newindex' flag set: done.
3830 | b ->vmeta_tsetv
3831 |
3832 |5:
3833 | checkstr CARG2; bne ->vmeta_tsetv
3834 if (!LJ_DUALNUM) {
3835 | lwz STR:RC, 4(RC)
3836 }
3837 | b ->BC_TSETS_Z // String key?
3838 |
3839 |7: // Possible table write barrier for the value. Skip valiswhite check.
3840 | barrierback TAB:RB, TMP3, TMP0
3841 | b <2
3842 break;
3843 |1:
3844 | checkstr CARG1; bne >4
3845 | cmpw TMP0, STR:RC; bne >4
3846 | checknil CARG2; beq >5 // Key found, but nil value?
3847 |3:
3848 | stwux CARG2, RA, BASE
3849 | stw TMP1, 4(RA)
3850 | ins_next
3851 case BC_TSETS:
3852 | // RA = src*8, RB = table*8, RC = str_const*8 (~)
3853 | lwzux CARG1, RB, BASE
3854 | srwi TMP1, RC, 1
3855 | lwz TAB:RB, 4(RB)
3856 | subfic TMP1, TMP1, -4
3857 | checktab CARG1
3858 | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4
3859 | bne ->vmeta_tsets1
3860 |->BC_TSETS_Z:
3861 | // TAB:RB = GCtab *, STR:RC = GCstr *, RA = src*8
3862 | lwz TMP0, TAB:RB->hmask
3863 | lwz TMP1, STR:RC->hash
3864 | lwz NODE:TMP2, TAB:RB->node
3865 | stb ZERO, TAB:RB->nomm // Clear metamethod cache.
3866 | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
3867 | lfdx f14, BASE, RA
3868 | slwi TMP0, TMP1, 5
3869 | slwi TMP1, TMP1, 3
3870 | sub TMP1, TMP0, TMP1
3871 | lbz TMP3, TAB:RB->marked
3872 | add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
3873 |1:
3874 | lwz CARG1, NODE:TMP2->key
3875 | lwz TMP0, 4+offsetof(Node, key)(NODE:TMP2)
3876 | lwz CARG2, NODE:TMP2->val
3877 | lwz TMP1, 4+offsetof(Node, val)(NODE:TMP2)
3878 | checkstr CARG1; bne >5
3879 | cmpw TMP0, STR:RC; bne >5
3880 | checknil CARG2; beq >4 // Key found, but nil value?
3881 |2:
3882 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
3883 | stfd f14, NODE:TMP2->val
3884 | bne >7
3885 |3:
3886 | ins_next
3887 |
3888 |4: // Check for __newindex if previous value is nil.
3889 | lwz TAB:TMP1, TAB:RB->metatable
3890 | cmplwi TAB:TMP1, 0
3891 | beq <2 // No metatable: done.
3892 | lbz TMP0, TAB:TMP1->nomm
3893 | andi. TMP0, TMP0, 1<<MM_newindex
3894 | bne <2 // 'no __newindex' flag set: done.
3895 | b ->vmeta_tsets
3896 |
3897 |5: // Follow hash chain.
3898 | lwz NODE:TMP2, NODE:TMP2->next
3899 | cmplwi NODE:TMP2, 0
3900 | bne <1
3901 | // End of hash chain: key not found, add a new one.
3902 |
3903 | // But check for __newindex first.
3904 | lwz TAB:TMP1, TAB:RB->metatable
3905 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
3906 | stw PC, SAVE_PC
3907 | mr CARG1, L
3908 | cmplwi TAB:TMP1, 0
3909 | stw BASE, L->base
3910 | beq >6 // No metatable: continue.
3911 | lbz TMP0, TAB:TMP1->nomm
3912 | andi. TMP0, TMP0, 1<<MM_newindex
3913 | beq ->vmeta_tsets // 'no __newindex' flag NOT set: check.
3914 |6:
3915 | li TMP0, LJ_TSTR
3916 | stw STR:RC, 4(CARG3)
3917 | mr CARG2, TAB:RB
3918 | stw TMP0, 0(CARG3)
3919 | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k)
3920 | // Returns TValue *.
3921 | lwz BASE, L->base
3922 | stfd f14, 0(CRET1)
3923 | b <3 // No 2nd write barrier needed.
3924 |
3925 |7: // Possible table write barrier for the value. Skip valiswhite check.
3926 | barrierback TAB:RB, TMP3, TMP0
3927 | b <3
3928 break;
3929 case BC_TSETB:
3930 | // RA = src*8, RB = table*8, RC = index*8
3931 | lwzux CARG1, RB, BASE
3932 | srwi TMP0, RC, 3
3933 | lwz TAB:RB, 4(RB)
3934 | checktab CARG1; bne ->vmeta_tsetb
3935 | lwz TMP1, TAB:RB->asize
3936 | lwz TMP2, TAB:RB->array
3937 | lbz TMP3, TAB:RB->marked
3938 | cmplw TMP0, TMP1
3939 | lfdx f14, BASE, RA
3940 | bge ->vmeta_tsetb
3941 | lwzx TMP1, TMP2, RC
3942 | checknil TMP1; beq >5
3943 |1:
3944 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
3945 | stfdx f14, TMP2, RC
3946 | bne >7
3947 |2:
3948 | ins_next
3949 |
3950 |5: // Check for __newindex if previous value is nil.
3951 | lwz TAB:TMP1, TAB:RB->metatable
3952 | cmplwi TAB:TMP1, 0
3953 | beq <1 // No metatable: done.
3954 | lbz TMP1, TAB:TMP1->nomm
3955 | andi. TMP1, TMP1, 1<<MM_newindex
3956 | bne <1 // 'no __newindex' flag set: done.
3957 | b ->vmeta_tsetb // Caveat: preserve TMP0!
3958 |
3959 |7: // Possible table write barrier for the value. Skip valiswhite check.
3960 | barrierback TAB:RB, TMP3, TMP0
3961 | b <2
3962 break;
3963
3964 case BC_TSETM:
3965 | // RA = base*8 (table at base-1), RD = num_const*8 (start index)
3966 | add RA, BASE, RA
3967 |1:
3968 | add TMP3, KBASE, RD
3969 | lwz TAB:CARG2, -4(RA) // Guaranteed to be a table.
3970 | addic. TMP0, MULTRES, -8
3971 | lwz TMP3, 4(TMP3) // Integer constant is in lo-word.
3972 | srwi CARG3, TMP0, 3
3973 | beq >4 // Nothing to copy?
3974 | add CARG3, CARG3, TMP3
3975 | lwz TMP2, TAB:CARG2->asize
3976 | slwi TMP1, TMP3, 3
3977 | lbz TMP3, TAB:CARG2->marked
3978 | cmplw CARG3, TMP2
3979 | add TMP2, RA, TMP0
3980 | lwz TMP0, TAB:CARG2->array
3981 | bgt >5
3982 | add TMP1, TMP1, TMP0
3983 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
3984 |3: // Copy result slots to table.
3985 | lfd f0, 0(RA)
3986 | addi RA, RA, 8
3987 | cmpw cr1, RA, TMP2
3988 | stfd f0, 0(TMP1)
3989 | addi TMP1, TMP1, 8
3990 | blt cr1, <3
3991 | bne >7
3992 |4:
3993 | ins_next
3994 |
3995 |5: // Need to resize array part.
3996 | stw BASE, L->base
3997 | mr CARG1, L
3998 | stw PC, SAVE_PC
3999 | mr SAVE0, RD
4000 | bl extern lj_tab_reasize // (lua_State *L, GCtab *t, int nasize)
4001 | // Must not reallocate the stack.
4002 | mr RD, SAVE0
4003 | b <1
4004 |
4005 |7: // Possible table write barrier for any value. Skip valiswhite check.
4006 | barrierback TAB:CARG2, TMP3, TMP0
4007 | b <4
4008 break;
4009
4010 /* -- Calls and vararg handling ----------------------------------------- */
4011
4012 case BC_CALLM:
4013 | // RA = base*8, (RB = (nresults+1)*8,) RC = extra_nargs*8
4014 | add NARGS8:RC, NARGS8:RC, MULTRES
4015 | // Fall through. Assumes BC_CALL follows.
4016 break;
4017 case BC_CALL:
4018 | // RA = base*8, (RB = (nresults+1)*8,) RC = (nargs+1)*8
4019 | mr TMP2, BASE
4020 | lwzux TMP0, BASE, RA
4021 | lwz LFUNC:RB, 4(BASE)
4022 | subi NARGS8:RC, NARGS8:RC, 8
4023 | addi BASE, BASE, 8
4024 | checkfunc TMP0; bne ->vmeta_call
4025 | ins_call
4026 break;
4027
4028 case BC_CALLMT:
4029 | // RA = base*8, (RB = 0,) RC = extra_nargs*8
4030 | add NARGS8:RC, NARGS8:RC, MULTRES
4031 | // Fall through. Assumes BC_CALLT follows.
4032 break;
4033 case BC_CALLT:
4034 | // RA = base*8, (RB = 0,) RC = (nargs+1)*8
4035 | lwzux TMP0, RA, BASE
4036 | lwz LFUNC:RB, 4(RA)
4037 | subi NARGS8:RC, NARGS8:RC, 8
4038 | lwz TMP1, FRAME_PC(BASE)
4039 | checkfunc TMP0
4040 | addi RA, RA, 8
4041 | bne ->vmeta_callt
4042 |->BC_CALLT_Z:
4043 | andi. TMP0, TMP1, FRAME_TYPE // Caveat: preserve cr0 until the crand.
4044 | lbz TMP3, LFUNC:RB->ffid
4045 | xori TMP2, TMP1, FRAME_VARG
4046 | cmplwi cr1, NARGS8:RC, 0
4047 | bne >7
4048 |1:
4049 | stw LFUNC:RB, FRAME_FUNC(BASE) // Copy function down, but keep PC.
4050 | li TMP2, 0
4051 | cmplwi cr7, TMP3, 1 // (> FF_C) Calling a fast function?
4052 | beq cr1, >3
4053 |2:
4054 | addi TMP3, TMP2, 8
4055 | lfdx f0, RA, TMP2
4056 | cmplw cr1, TMP3, NARGS8:RC
4057 | stfdx f0, BASE, TMP2
4058 | mr TMP2, TMP3
4059 | bne cr1, <2
4060 |3:
4061 | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+gt
4062 | beq >5
4063 |4:
4064 | ins_callt
4065 |
4066 |5: // Tailcall to a fast function with a Lua frame below.
4067 | lwz INS, -4(TMP1)
4068 | decode_RA8 RA, INS
4069 | sub TMP1, BASE, RA
4070 | lwz LFUNC:TMP1, FRAME_FUNC-8(TMP1)
4071 | lwz TMP1, LFUNC:TMP1->pc
4072 | lwz KBASE, PC2PROTO(k)(TMP1) // Need to prepare KBASE.
4073 | b <4
4074 |
4075 |7: // Tailcall from a vararg function.
4076 | andi. TMP0, TMP2, FRAME_TYPEP
4077 | bne <1 // Vararg frame below?
4078 | sub BASE, BASE, TMP2 // Relocate BASE down.
4079 | lwz TMP1, FRAME_PC(BASE)
4080 | andi. TMP0, TMP1, FRAME_TYPE
4081 | b <1
4082 break;
4083
4084 case BC_ITERC:
4085 | // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 ((2+1)*8))
4086 | mr TMP2, BASE
4087 | add BASE, BASE, RA
4088 | lwz TMP1, -24(BASE)
4089 | lwz LFUNC:RB, -20(BASE)
4090 | lfd f1, -8(BASE)
4091 | lfd f0, -16(BASE)
4092 | stw TMP1, 0(BASE) // Copy callable.
4093 | stw LFUNC:RB, 4(BASE)
4094 | checkfunc TMP1
4095 | stfd f1, 16(BASE) // Copy control var.
4096 | li NARGS8:RC, 16 // Iterators get 2 arguments.
4097 | stfdu f0, 8(BASE) // Copy state.
4098 | bne ->vmeta_call
4099 | ins_call
4100 break;
4101
4102 case BC_ITERN:
4103 | // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 (2+1)*8)
4104#if LJ_HASJIT
4105 | // NYI: add hotloop, record BC_ITERN.
4106#endif
4107 | add RA, BASE, RA
4108 | lwz TAB:RB, -12(RA)
4109 | lwz RC, -4(RA) // Get index from control var.
4110 | lwz TMP0, TAB:RB->asize
4111 | lwz TMP1, TAB:RB->array
4112 | addi PC, PC, 4
4113 |1: // Traverse array part.
4114 | cmplw RC, TMP0
4115 | slwi TMP3, RC, 3
4116 | bge >5 // Index points after array part?
4117 | lwzx TMP2, TMP1, TMP3
4118 | lfdx f0, TMP1, TMP3
4119 | checknil TMP2
4120 | lwz INS, -4(PC)
4121 | beq >4
4122 if (LJ_DUALNUM) {
4123 | stw RC, 4(RA)
4124 | stw TISNUM, 0(RA)
4125 } else {
4126 | tonum_u f1, RC
4127 }
4128 | addi RC, RC, 1
4129 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
4130 | stfd f0, 8(RA)
4131 | decode_RD4 TMP1, INS
4132 | stw RC, -4(RA) // Update control var.
4133 | add PC, TMP1, TMP3
4134 if (!LJ_DUALNUM) {
4135 | stfd f1, 0(RA)
4136 }
4137 |3:
4138 | ins_next
4139 |
4140 |4: // Skip holes in array part.
4141 | addi RC, RC, 1
4142 | b <1
4143 |
4144 |5: // Traverse hash part.
4145 | lwz TMP1, TAB:RB->hmask
4146 | sub RC, RC, TMP0
4147 | lwz TMP2, TAB:RB->node
4148 |6:
4149 | cmplw RC, TMP1 // End of iteration? Branch to ITERL+1.
4150 | slwi TMP3, RC, 5
4151 | bgty <3
4152 | slwi RB, RC, 3
4153 | sub TMP3, TMP3, RB
4154 | lwzx RB, TMP2, TMP3
4155 | lfdx f0, TMP2, TMP3
4156 | add NODE:TMP3, TMP2, TMP3
4157 | checknil RB
4158 | lwz INS, -4(PC)
4159 | beq >7
4160 | lfd f1, NODE:TMP3->key
4161 | addis TMP2, PC, -(BCBIAS_J*4 >> 16)
4162 | stfd f0, 8(RA)
4163 | add RC, RC, TMP0
4164 | decode_RD4 TMP1, INS
4165 | stfd f1, 0(RA)
4166 | addi RC, RC, 1
4167 | add PC, TMP1, TMP2
4168 | stw RC, -4(RA) // Update control var.
4169 | b <3
4170 |
4171 |7: // Skip holes in hash part.
4172 | addi RC, RC, 1
4173 | b <6
4174 break;
4175
4176 case BC_ISNEXT:
4177 | // RA = base*8, RD = target (points to ITERN)
4178 | add RA, BASE, RA
4179 | lwz TMP0, -24(RA)
4180 | lwz CFUNC:TMP1, -20(RA)
4181 | lwz TMP2, -16(RA)
4182 | lwz TMP3, -8(RA)
4183 | cmpwi cr0, TMP2, LJ_TTAB
4184 | cmpwi cr1, TMP0, LJ_TFUNC
4185 | cmpwi cr6, TMP3, LJ_TNIL
4186 | bne cr1, >5
4187 | lbz TMP1, CFUNC:TMP1->ffid
4188 | crand 4*cr0+eq, 4*cr0+eq, 4*cr6+eq
4189 | cmpwi cr7, TMP1, FF_next_N
4190 | srwi TMP0, RD, 1
4191 | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+eq
4192 | add TMP3, PC, TMP0
4193 | bne cr0, >5
4194 | stw ZERO, -4(RA) // Initialize control var.
4195 | addis PC, TMP3, -(BCBIAS_J*4 >> 16)
4196 |1:
4197 | ins_next
4198 |5: // Despecialize bytecode if any of the checks fail.
4199 | li TMP0, BC_JMP
4200 | li TMP1, BC_ITERC
4201 | stb TMP0, -1(PC)
4202 | addis PC, TMP3, -(BCBIAS_J*4 >> 16)
4203 | stb TMP1, 3(PC)
4204 | b <1
4205 break;
4206
4207 case BC_VARG:
4208 | // RA = base*8, RB = (nresults+1)*8, RC = numparams*8
4209 | lwz TMP0, FRAME_PC(BASE)
4210 | add RC, BASE, RC
4211 | add RA, BASE, RA
4212 | addi RC, RC, FRAME_VARG
4213 | add TMP2, RA, RB
4214 | subi TMP3, BASE, 8 // TMP3 = vtop
4215 | sub RC, RC, TMP0 // RC = vbase
4216 | // Note: RC may now be even _above_ BASE if nargs was < numparams.
4217 | cmplwi cr1, RB, 0
4218 | sub. TMP1, TMP3, RC
4219 | beq cr1, >5 // Copy all varargs?
4220 | subi TMP2, TMP2, 16
4221 | ble >2 // No vararg slots?
4222 |1: // Copy vararg slots to destination slots.
4223 | lfd f0, 0(RC)
4224 | addi RC, RC, 8
4225 | stfd f0, 0(RA)
4226 | cmplw RA, TMP2
4227 | cmplw cr1, RC, TMP3
4228 | bge >3 // All destination slots filled?
4229 | addi RA, RA, 8
4230 | blt cr1, <1 // More vararg slots?
4231 |2: // Fill up remainder with nil.
4232 | stw TISNIL, 0(RA)
4233 | cmplw RA, TMP2
4234 | addi RA, RA, 8
4235 | blt <2
4236 |3:
4237 | ins_next
4238 |
4239 |5: // Copy all varargs.
4240 | lwz TMP0, L->maxstack
4241 | li MULTRES, 8 // MULTRES = (0+1)*8
4242 | bley <3 // No vararg slots?
4243 | add TMP2, RA, TMP1
4244 | cmplw TMP2, TMP0
4245 | addi MULTRES, TMP1, 8
4246 | bgt >7
4247 |6:
4248 | lfd f0, 0(RC)
4249 | addi RC, RC, 8
4250 | stfd f0, 0(RA)
4251 | cmplw RC, TMP3
4252 | addi RA, RA, 8
4253 | blt <6 // More vararg slots?
4254 | b <3
4255 |
4256 |7: // Grow stack for varargs.
4257 | mr CARG1, L
4258 | stw RA, L->top
4259 | sub SAVE0, RC, BASE // Need delta, because BASE may change.
4260 | stw BASE, L->base
4261 | sub RA, RA, BASE
4262 | stw PC, SAVE_PC
4263 | srwi CARG2, TMP1, 3
4264 | bl extern lj_state_growstack // (lua_State *L, int n)
4265 | lwz BASE, L->base
4266 | add RA, BASE, RA
4267 | add RC, BASE, SAVE0
4268 | subi TMP3, BASE, 8
4269 | b <6
4270 break;
4271
4272 /* -- Returns ----------------------------------------------------------- */
4273
4274 case BC_RETM:
4275 | // RA = results*8, RD = extra_nresults*8
4276 | add RD, RD, MULTRES // MULTRES >= 8, so RD >= 8.
4277 | // Fall through. Assumes BC_RET follows.
4278 break;
4279
4280 case BC_RET:
4281 | // RA = results*8, RD = (nresults+1)*8
4282 | lwz PC, FRAME_PC(BASE)
4283 | add RA, BASE, RA
4284 | mr MULTRES, RD
4285 |1:
4286 | andi. TMP0, PC, FRAME_TYPE
4287 | xori TMP1, PC, FRAME_VARG
4288 | bne ->BC_RETV_Z
4289 |
4290 |->BC_RET_Z:
4291 | // BASE = base, RA = resultptr, RD = (nresults+1)*8, PC = return
4292 | lwz INS, -4(PC)
4293 | cmpwi RD, 8
4294 | subi TMP2, BASE, 8
4295 | subi RC, RD, 8
4296 | decode_RB8 RB, INS
4297 | beq >3
4298 | li TMP1, 0
4299 |2:
4300 | addi TMP3, TMP1, 8
4301 | lfdx f0, RA, TMP1
4302 | cmpw TMP3, RC
4303 | stfdx f0, TMP2, TMP1
4304 | beq >3
4305 | addi TMP1, TMP3, 8
4306 | lfdx f1, RA, TMP3
4307 | cmpw TMP1, RC
4308 | stfdx f1, TMP2, TMP3
4309 | bne <2
4310 |3:
4311 |5:
4312 | cmplw RB, RD
4313 | decode_RA8 RA, INS
4314 | bgt >6
4315 | sub BASE, TMP2, RA
4316 | lwz LFUNC:TMP1, FRAME_FUNC(BASE)
4317 | ins_next1
4318 | lwz TMP1, LFUNC:TMP1->pc
4319 | lwz KBASE, PC2PROTO(k)(TMP1)
4320 | ins_next2
4321 |
4322 |6: // Fill up results with nil.
4323 | subi TMP1, RD, 8
4324 | addi RD, RD, 8
4325 | stwx TISNIL, TMP2, TMP1
4326 | b <5
4327 |
4328 |->BC_RETV_Z: // Non-standard return case.
4329 | andi. TMP2, TMP1, FRAME_TYPEP
4330 | bne ->vm_return
4331 | // Return from vararg function: relocate BASE down.
4332 | sub BASE, BASE, TMP1
4333 | lwz PC, FRAME_PC(BASE)
4334 | b <1
4335 break;
4336
4337 case BC_RET0: case BC_RET1:
4338 | // RA = results*8, RD = (nresults+1)*8
4339 | lwz PC, FRAME_PC(BASE)
4340 | add RA, BASE, RA
4341 | mr MULTRES, RD
4342 | andi. TMP0, PC, FRAME_TYPE
4343 | xori TMP1, PC, FRAME_VARG
4344 | bney ->BC_RETV_Z
4345 |
4346 | lwz INS, -4(PC)
4347 | subi TMP2, BASE, 8
4348 | decode_RB8 RB, INS
4349 if (op == BC_RET1) {
4350 | lfd f0, 0(RA)
4351 | stfd f0, 0(TMP2)
4352 }
4353 |5:
4354 | cmplw RB, RD
4355 | decode_RA8 RA, INS
4356 | bgt >6
4357 | sub BASE, TMP2, RA
4358 | lwz LFUNC:TMP1, FRAME_FUNC(BASE)
4359 | ins_next1
4360 | lwz TMP1, LFUNC:TMP1->pc
4361 | lwz KBASE, PC2PROTO(k)(TMP1)
4362 | ins_next2
4363 |
4364 |6: // Fill up results with nil.
4365 | subi TMP1, RD, 8
4366 | addi RD, RD, 8
4367 | stwx TISNIL, TMP2, TMP1
4368 | b <5
4369 break;
4370
4371 /* -- Loops and branches ------------------------------------------------ */
4372
4373 case BC_FORL:
4374#if LJ_HASJIT
4375 | hotloop
4376#endif
4377 | // Fall through. Assumes BC_IFORL follows.
4378 break;
4379
4380 case BC_JFORI:
4381 case BC_JFORL:
4382#if !LJ_HASJIT
4383 break;
4384#endif
4385 case BC_FORI:
4386 case BC_IFORL:
4387 | // RA = base*8, RD = target (after end of loop or start of loop)
4388 vk = (op == BC_IFORL || op == BC_JFORL);
4389 if (LJ_DUALNUM) {
4390 | // Integer loop.
4391 | lwzux TMP1, RA, BASE
4392 | lwz CARG1, FORL_IDX*8+4(RA)
4393 | cmplw cr0, TMP1, TISNUM
4394 if (vk) {
4395 | lwz CARG3, FORL_STEP*8+4(RA)
4396 | bne >9
4397 | addo. CARG1, CARG1, CARG3
4398 | cmpwi cr6, CARG3, 0
4399 | lwz CARG2, FORL_STOP*8+4(RA)
4400 | bso >6
4401 |4:
4402 | stw CARG1, FORL_IDX*8+4(RA)
4403 } else {
4404 | lwz TMP3, FORL_STEP*8(RA)
4405 | lwz CARG3, FORL_STEP*8+4(RA)
4406 | lwz TMP2, FORL_STOP*8(RA)
4407 | lwz CARG2, FORL_STOP*8+4(RA)
4408 | cmplw cr7, TMP3, TISNUM
4409 | cmplw cr1, TMP2, TISNUM
4410 | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+eq
4411 | crand 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
4412 | cmpwi cr6, CARG3, 0
4413 | bne >9
4414 }
4415 | blt cr6, >5
4416 | cmpw CARG1, CARG2
4417 |1:
4418 | stw TISNUM, FORL_EXT*8(RA)
4419 if (op != BC_JFORL) {
4420 | srwi RD, RD, 1
4421 }
4422 | stw CARG1, FORL_EXT*8+4(RA)
4423 if (op != BC_JFORL) {
4424 | add RD, PC, RD
4425 }
4426 if (op == BC_FORI) {
4427 | bgt >3 // See FP loop below.
4428 } else if (op == BC_JFORI) {
4429 | addis PC, RD, -(BCBIAS_J*4 >> 16)
4430 | bley >7
4431 } else if (op == BC_IFORL) {
4432 | bgt >2
4433 | addis PC, RD, -(BCBIAS_J*4 >> 16)
4434 } else {
4435 | bley =>BC_JLOOP
4436 }
4437 |2:
4438 | ins_next
4439 |5: // Invert check for negative step.
4440 | cmpw CARG2, CARG1
4441 | b <1
4442 if (vk) {
4443 |6: // Potential overflow.
4444 | mcrxr cr0; bley <4 // Ignore unrelated overflow.
4445 | b <2
4446 }
4447 }
4448 if (vk) {
4449 if (LJ_DUALNUM) {
4450 |9: // FP loop.
4451 | lfd f1, FORL_IDX*8(RA)
4452 } else {
4453 | lfdux f1, RA, BASE
4454 }
4455 | lfd f3, FORL_STEP*8(RA)
4456 | lfd f2, FORL_STOP*8(RA)
4457 | lwz TMP3, FORL_STEP*8(RA)
4458 | fadd f1, f1, f3
4459 | stfd f1, FORL_IDX*8(RA)
4460 } else {
4461 if (LJ_DUALNUM) {
4462 |9: // FP loop.
4463 } else {
4464 | lwzux TMP1, RA, BASE
4465 | lwz TMP3, FORL_STEP*8(RA)
4466 | lwz TMP2, FORL_STOP*8(RA)
4467 | cmplw cr0, TMP1, TISNUM
4468 | cmplw cr7, TMP3, TISNUM
4469 | cmplw cr1, TMP2, TISNUM
4470 }
4471 | lfd f1, FORL_IDX*8(RA)
4472 | crand 4*cr0+lt, 4*cr0+lt, 4*cr7+lt
4473 | lfd f3, FORL_STEP*8(RA)
4474 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
4475 | lfd f2, FORL_STOP*8(RA)
4476 | bge ->vmeta_for
4477 }
4478 | cmpwi cr6, TMP3, 0
4479 if (op != BC_JFORL) {
4480 | srwi RD, RD, 1
4481 }
4482 | stfd f1, FORL_EXT*8(RA)
4483 if (op != BC_JFORL) {
4484 | add RD, PC, RD
4485 }
4486 | fcmpu cr0, f1, f2
4487 if (op == BC_JFORI) {
4488 | addis PC, RD, -(BCBIAS_J*4 >> 16)
4489 }
4490 | blt cr6, >5
4491 if (op == BC_FORI) {
4492 | bgt >3
4493 } else if (op == BC_IFORL) {
4494 if (LJ_DUALNUM) {
4495 | bgty <2
4496 } else {
4497 | bgt >2
4498 }
4499 |1:
4500 | addis PC, RD, -(BCBIAS_J*4 >> 16)
4501 } else if (op == BC_JFORI) {
4502 | bley >7
4503 } else {
4504 | bley =>BC_JLOOP
4505 }
4506 if (LJ_DUALNUM) {
4507 | b <2
4508 } else {
4509 |2:
4510 | ins_next
4511 }
4512 |5: // Negative step.
4513 if (op == BC_FORI) {
4514 | bge <2
4515 |3: // Used by integer loop, too.
4516 | addis PC, RD, -(BCBIAS_J*4 >> 16)
4517 } else if (op == BC_IFORL) {
4518 | bgey <1
4519 } else if (op == BC_JFORI) {
4520 | bgey >7
4521 } else {
4522 | bgey =>BC_JLOOP
4523 }
4524 | b <2
4525 if (op == BC_JFORI) {
4526 |7:
4527 | lwz INS, -4(PC)
4528 | decode_RD8 RD, INS
4529 | b =>BC_JLOOP
4530 }
4531 break;
4532
4533 case BC_ITERL:
4534#if LJ_HASJIT
4535 | hotloop
4536#endif
4537 | // Fall through. Assumes BC_IITERL follows.
4538 break;
4539
4540 case BC_JITERL:
4541#if !LJ_HASJIT
4542 break;
4543#endif
4544 case BC_IITERL:
4545 | // RA = base*8, RD = target
4546 | lwzux TMP1, RA, BASE
4547 | lwz TMP2, 4(RA)
4548 | checknil TMP1; beq >1 // Stop if iterator returned nil.
4549 if (op == BC_JITERL) {
4550 | stw TMP1, -8(RA)
4551 | stw TMP2, -4(RA)
4552 | b =>BC_JLOOP
4553 } else {
4554 | branch_RD // Otherwise save control var + branch.
4555 | stw TMP1, -8(RA)
4556 | stw TMP2, -4(RA)
4557 }
4558 |1:
4559 | ins_next
4560 break;
4561
4562 case BC_LOOP:
4563 | // RA = base*8, RD = target (loop extent)
4564 | // Note: RA/RD is only used by trace recorder to determine scope/extent
4565 | // This opcode does NOT jump, it's only purpose is to detect a hot loop.
4566#if LJ_HASJIT
4567 | hotloop
4568#endif
4569 | // Fall through. Assumes BC_ILOOP follows.
4570 break;
4571
4572 case BC_ILOOP:
4573 | // RA = base*8, RD = target (loop extent)
4574 | ins_next
4575 break;
4576
4577 case BC_JLOOP:
4578#if LJ_HASJIT
4579 | // RA = base*8 (ignored), RD = traceno*8
4580 | lwz TMP1, DISPATCH_J(trace)(DISPATCH)
4581 | srwi RD, RD, 1
4582 | // Traces on PPC don't store the trace number, so use 0.
4583 | stw ZERO, DISPATCH_GL(vmstate)(DISPATCH)
4584 | lwzx TRACE:TMP2, TMP1, RD
4585 | mcrxr cr0 // Clear SO flag.
4586 | lwz TMP2, TRACE:TMP2->mcode
4587 | stw BASE, DISPATCH_GL(jit_base)(DISPATCH)
4588 | mtctr TMP2
4589 | stw L, DISPATCH_GL(jit_L)(DISPATCH)
4590 | addi JGL, DISPATCH, GG_DISP2G+32768
4591 | bctr
4592#endif
4593 break;
4594
4595 case BC_JMP:
4596 | // RA = base*8 (only used by trace recorder), RD = target
4597 | branch_RD
4598 | ins_next
4599 break;
4600
4601 /* -- Function headers -------------------------------------------------- */
4602
4603 case BC_FUNCF:
4604#if LJ_HASJIT
4605 | hotcall
4606#endif
4607 case BC_FUNCV: /* NYI: compiled vararg functions. */
4608 | // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow.
4609 break;
4610
4611 case BC_JFUNCF:
4612#if !LJ_HASJIT
4613 break;
4614#endif
4615 case BC_IFUNCF:
4616 | // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
4617 | lwz TMP2, L->maxstack
4618 | lbz TMP1, -4+PC2PROTO(numparams)(PC)
4619 | lwz KBASE, -4+PC2PROTO(k)(PC)
4620 | cmplw RA, TMP2
4621 | slwi TMP1, TMP1, 3
4622 | bgt ->vm_growstack_l
4623 if (op != BC_JFUNCF) {
4624 | ins_next1
4625 }
4626 |2:
4627 | cmplw NARGS8:RC, TMP1 // Check for missing parameters.
4628 | ble >3
4629 if (op == BC_JFUNCF) {
4630 | decode_RD8 RD, INS
4631 | b =>BC_JLOOP
4632 } else {
4633 | ins_next2
4634 }
4635 |
4636 |3: // Clear missing parameters.
4637 | stwx TISNIL, BASE, NARGS8:RC
4638 | addi NARGS8:RC, NARGS8:RC, 8
4639 | b <2
4640 break;
4641
4642 case BC_JFUNCV:
4643#if !LJ_HASJIT
4644 break;
4645#endif
4646 | NYI // NYI: compiled vararg functions
4647 break; /* NYI: compiled vararg functions. */
4648
4649 case BC_IFUNCV:
4650 | // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
4651 | lwz TMP2, L->maxstack
4652 | add TMP1, BASE, RC
4653 | add TMP0, RA, RC
4654 | stw LFUNC:RB, 4(TMP1) // Store copy of LFUNC.
4655 | addi TMP3, RC, 8+FRAME_VARG
4656 | lwz KBASE, -4+PC2PROTO(k)(PC)
4657 | cmplw TMP0, TMP2
4658 | stw TMP3, 0(TMP1) // Store delta + FRAME_VARG.
4659 | bge ->vm_growstack_l
4660 | lbz TMP2, -4+PC2PROTO(numparams)(PC)
4661 | mr RA, BASE
4662 | mr RC, TMP1
4663 | ins_next1
4664 | cmpwi TMP2, 0
4665 | addi BASE, TMP1, 8
4666 | beq >3
4667 |1:
4668 | cmplw RA, RC // Less args than parameters?
4669 | lwz TMP0, 0(RA)
4670 | lwz TMP3, 4(RA)
4671 | bge >4
4672 | stw TISNIL, 0(RA) // Clear old fixarg slot (help the GC).
4673 | addi RA, RA, 8
4674 |2:
4675 | addic. TMP2, TMP2, -1
4676 | stw TMP0, 8(TMP1)
4677 | stw TMP3, 12(TMP1)
4678 | addi TMP1, TMP1, 8
4679 | bne <1
4680 |3:
4681 | ins_next2
4682 |
4683 |4: // Clear missing parameters.
4684 | li TMP0, LJ_TNIL
4685 | b <2
4686 break;
4687
4688 case BC_FUNCC:
4689 case BC_FUNCCW:
4690 | // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8
4691 if (op == BC_FUNCC) {
4692 | lwz TMP3, CFUNC:RB->f
4693 } else {
4694 | lwz TMP3, DISPATCH_GL(wrapf)(DISPATCH)
4695 }
4696 | add TMP1, RA, NARGS8:RC
4697 | lwz TMP2, L->maxstack
4698 | add RC, BASE, NARGS8:RC
4699 | stw BASE, L->base
4700 | cmplw TMP1, TMP2
4701 | stw RC, L->top
4702 | li_vmstate C
4703 | mtctr TMP3
4704 if (op == BC_FUNCCW) {
4705 | lwz CARG2, CFUNC:RB->f
4706 }
4707 | mr CARG1, L
4708 | bgt ->vm_growstack_c // Need to grow stack.
4709 | st_vmstate
4710 | bctrl // (lua_State *L [, lua_CFunction f])
4711 | // Returns nresults.
4712 | lwz BASE, L->base
4713 | slwi RD, CRET1, 3
4714 | lwz TMP1, L->top
4715 | li_vmstate INTERP
4716 | lwz PC, FRAME_PC(BASE) // Fetch PC of caller.
4717 | sub RA, TMP1, RD // RA = L->top - nresults*8
4718 | st_vmstate
4719 | b ->vm_returnc
4720 break;
4721
4722 /* ---------------------------------------------------------------------- */
4723
4724 default:
4725 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
4726 exit(2);
4727 break;
4728 }
4729}
4730
4731static int build_backend(BuildCtx *ctx)
4732{
4733 int op;
4734
4735 dasm_growpc(Dst, BC__MAX);
4736
4737 build_subroutines(ctx);
4738
4739 |.code_op
4740 for (op = 0; op < BC__MAX; op++)
4741 build_ins(ctx, (BCOp)op, op);
4742
4743 return BC__MAX;
4744}
4745
4746/* Emit pseudo frame-info for all assembler functions. */
4747static void emit_asm_debug(BuildCtx *ctx)
4748{
4749 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
4750 int i;
4751 switch (ctx->mode) {
4752 case BUILD_elfasm:
4753 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
4754 fprintf(ctx->fp,
4755 ".Lframe0:\n"
4756 "\t.long .LECIE0-.LSCIE0\n"
4757 ".LSCIE0:\n"
4758 "\t.long 0xffffffff\n"
4759 "\t.byte 0x1\n"
4760 "\t.string \"\"\n"
4761 "\t.uleb128 0x1\n"
4762 "\t.sleb128 -4\n"
4763 "\t.byte 65\n"
4764 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
4765 "\t.align 2\n"
4766 ".LECIE0:\n\n");
4767 fprintf(ctx->fp,
4768 ".LSFDE0:\n"
4769 "\t.long .LEFDE0-.LASFDE0\n"
4770 ".LASFDE0:\n"
4771 "\t.long .Lframe0\n"
4772 "\t.long .Lbegin\n"
4773 "\t.long %d\n"
4774 "\t.byte 0xe\n\t.uleb128 %d\n"
4775 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
4776 "\t.byte 0x5\n\t.uleb128 70\n\t.uleb128 55\n",
4777 fcofs, CFRAME_SIZE);
4778 for (i = 14; i <= 31; i++)
4779 fprintf(ctx->fp,
4780 "\t.byte %d\n\t.uleb128 %d\n"
4781 "\t.byte %d\n\t.uleb128 %d\n",
4782 0x80+i, 37+(31-i), 0x80+32+i, 2+2*(31-i));
4783 fprintf(ctx->fp,
4784 "\t.align 2\n"
4785 ".LEFDE0:\n\n");
4786#if LJ_HASFFI
4787 fprintf(ctx->fp,
4788 ".LSFDE1:\n"
4789 "\t.long .LEFDE1-.LASFDE1\n"
4790 ".LASFDE1:\n"
4791 "\t.long .Lframe0\n"
4792 "\t.long lj_vm_ffi_call\n"
4793 "\t.long %d\n"
4794 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
4795 "\t.byte 0x8e\n\t.uleb128 2\n"
4796 "\t.byte 0xd\n\t.uleb128 0xe\n"
4797 "\t.align 2\n"
4798 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
4799#endif
4800 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
4801 fprintf(ctx->fp,
4802 ".Lframe1:\n"
4803 "\t.long .LECIE1-.LSCIE1\n"
4804 ".LSCIE1:\n"
4805 "\t.long 0\n"
4806 "\t.byte 0x1\n"
4807 "\t.string \"zPR\"\n"
4808 "\t.uleb128 0x1\n"
4809 "\t.sleb128 -4\n"
4810 "\t.byte 65\n"
4811 "\t.uleb128 6\n" /* augmentation length */
4812 "\t.byte 0x1b\n" /* pcrel|sdata4 */
4813 "\t.long lj_err_unwind_dwarf-.\n"
4814 "\t.byte 0x1b\n" /* pcrel|sdata4 */
4815 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
4816 "\t.align 2\n"
4817 ".LECIE1:\n\n");
4818 fprintf(ctx->fp,
4819 ".LSFDE2:\n"
4820 "\t.long .LEFDE2-.LASFDE2\n"
4821 ".LASFDE2:\n"
4822 "\t.long .LASFDE2-.Lframe1\n"
4823 "\t.long .Lbegin-.\n"
4824 "\t.long %d\n"
4825 "\t.uleb128 0\n" /* augmentation length */
4826 "\t.byte 0xe\n\t.uleb128 %d\n"
4827 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
4828 "\t.byte 0x5\n\t.uleb128 70\n\t.uleb128 55\n",
4829 fcofs, CFRAME_SIZE);
4830 for (i = 14; i <= 31; i++)
4831 fprintf(ctx->fp,
4832 "\t.byte %d\n\t.uleb128 %d\n"
4833 "\t.byte %d\n\t.uleb128 %d\n",
4834 0x80+i, 37+(31-i), 0x80+32+i, 2+2*(31-i));
4835 fprintf(ctx->fp,
4836 "\t.align 2\n"
4837 ".LEFDE2:\n\n");
4838#if LJ_HASFFI
4839 fprintf(ctx->fp,
4840 ".Lframe2:\n"
4841 "\t.long .LECIE2-.LSCIE2\n"
4842 ".LSCIE2:\n"
4843 "\t.long 0\n"
4844 "\t.byte 0x1\n"
4845 "\t.string \"zR\"\n"
4846 "\t.uleb128 0x1\n"
4847 "\t.sleb128 -4\n"
4848 "\t.byte 65\n"
4849 "\t.uleb128 1\n" /* augmentation length */
4850 "\t.byte 0x1b\n" /* pcrel|sdata4 */
4851 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
4852 "\t.align 2\n"
4853 ".LECIE2:\n\n");
4854 fprintf(ctx->fp,
4855 ".LSFDE3:\n"
4856 "\t.long .LEFDE3-.LASFDE3\n"
4857 ".LASFDE3:\n"
4858 "\t.long .LASFDE3-.Lframe2\n"
4859 "\t.long lj_vm_ffi_call-.\n"
4860 "\t.long %d\n"
4861 "\t.uleb128 0\n" /* augmentation length */
4862 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
4863 "\t.byte 0x8e\n\t.uleb128 2\n"
4864 "\t.byte 0xd\n\t.uleb128 0xe\n"
4865 "\t.align 2\n"
4866 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
4867#endif
4868 break;
4869 default:
4870 break;
4871 }
4872}
4873
diff --git a/libraries/luajit-2.0/src/buildvm_ppc.h b/libraries/luajit-2.0/src/buildvm_ppc.h
new file mode 100644
index 0000000..b42b5fa
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_ppc.h
@@ -0,0 +1,9804 @@
1/*
2** This file has been pre-processed with DynASM.
3** http://luajit.org/dynasm.html
4** DynASM version 1.3.0, DynASM ppc version 1.3.0
5** DO NOT EDIT! The original file is in "buildvm_ppc.dasc".
6*/
7
8#if DASM_VERSION != 10300
9#error "Version mismatch between DynASM and included encoding engine"
10#endif
11
12#define DASM_SECTION_CODE_OP 0
13#define DASM_SECTION_CODE_SUB 1
14#define DASM_MAXSECTION 2
15static const unsigned int build_actionlist[7771] = {
160x00010001,
170x00060014,
180x72000000,
190x00090200,
200x39000000,
210x00098200,
220x41820000,
230x00050815,
240x8209fff8,
250x7d2e4b78,
260x9514fff8,
270x00060016,
280x72000000,
290x00090200,
300x398c0008,
310x7d936378,
320x41820000,
330x00050817,
340x00060018,
350x2c000000,
360x00098200,
370x56090038,
380x38000000,
390x00098200,
400x7d297050,
410x40a20000,
420x00050814,
430x350cfff8,
440x91320000,
450x00098200,
460x8121002c,
470x39cefff8,
480x90110000,
490x00098200,
500x55291800,
510x000900a1,
520x41820000,
530x00050802,
540x0006000b,
550x3508fff8,
560xc8140000,
570x3a940008,
580xd80e0000,
590x39ce0008,
600x40a20000,
610x0005080b,
620x0006000c,
630x7c096000,
640x40820000,
650x00050806,
660x0006000d,
670x91d20000,
680x00098200,
690x00060019,
700x00000000,
710x80010028,
720x38600000,
730x90120000,
740x00098200,
750x0006001a,
760x80010114,
770x81810034,
780x81c10000,
790x00098200,
800xc9c10000,
810x00098200,
820x81e10000,
830x00098200,
840xc9e10000,
850x00098200,
860x82010000,
870x00098200,
880xca010000,
890x00098200,
900x82210000,
910x00098200,
920xca210000,
930x00098200,
940x82410000,
950x00098200,
960xca410000,
970x00098200,
980x82610000,
990x00098200,
1000xca610000,
1010x00098200,
1020x7c0803a6,
1030x7d838120,
1040x82810000,
1050x00098200,
1060xca810000,
1070x00098200,
1080x82a10000,
1090x00098200,
1100xcaa10000,
1110x00098200,
1120x82c10000,
1130x00098200,
1140xcac10000,
1150x00098200,
1160x82e10000,
1170x00098200,
1180xcae10000,
1190x00098200,
1200x00000000,
1210x83010000,
1220x00098200,
1230xcb010000,
1240x00098200,
1250x83210000,
1260x00098200,
1270xcb210000,
1280x00098200,
1290x83410000,
1300x00098200,
1310xcb410000,
1320x00098200,
1330x83610000,
1340x00098200,
1350xcb610000,
1360x00098200,
1370x83810000,
1380x00098200,
1390xcb810000,
1400x00098200,
1410x83a10000,
1420x00098200,
1430xcba10000,
1440x00098200,
1450x83c10000,
1460x00098200,
1470xcbc10000,
1480x00098200,
1490x83e10000,
1500x00098200,
1510xcbe10000,
1520x00098200,
1530x38210110,
1540x4e800020,
1550x00060010,
1560x40810000,
1570x00050807,
1580x81120000,
1590x00098200,
1600x7c0e4040,
1610x40800000,
1620x00050808,
1630x92ee0000,
1640x398c0008,
1650x39ce0008,
1660x48000000,
1670x0005000c,
1680x00060011,
1690x00000000,
1700x20c90000,
1710x7c096050,
1720x7d084110,
1730x7c004038,
1740x7dc07050,
1750x48000000,
1760x0005000d,
1770x00060012,
1780x91d20000,
1790x00098200,
1800x7d956378,
1810x7d244b78,
1820x7e439378,
1830x48000001,
1840x00030000,
1850x8121002c,
1860x7eacab78,
1870x55291800,
1880x000900a1,
1890x81d20000,
1900x00098200,
1910x48000000,
1920x0005000c,
1930x0006001b,
1940x7c611b78,
1950x7c832378,
1960x0006001c,
1970x82410024,
1980x38000000,
1990x00098200,
2000x81120000,
2010x00098200,
2020x90080000,
2030x00098200,
2040x48000000,
2050x0005001a,
2060x0006001d,
2070x5461003a,
2080x0006001e,
2090x82410024,
2100x3ac00000,
2110x00098200,
2120x81d20000,
2130x00098200,
2140x3cc059c0,
2150x82320000,
2160x00098200,
2170x3b000000,
2180x90c10010,
2190x39000000,
2200x00098200,
2210x60c60004,
2220x3ae00000,
2230x00098200,
2240x38000000,
2250x00098200,
2260xc3c10010,
2270x820efff8,
2280x3a8efff8,
2290x90c10010,
2300x3a310000,
2310x00098200,
2320x00000000,
2330x91140000,
2340x39800010,
2350x90110000,
2360x00098200,
2370xc3e10010,
2380x48000000,
2390x00050016,
2400x0006001f,
2410x38800000,
2420x00098200,
2430x48000000,
2440x00050002,
2450x00060020,
2460x7d6e5a14,
2470x7e8ea050,
2480x91d20000,
2490x00098200,
2500x3a100004,
2510x91720000,
2520x00098200,
2530x568400fe,
2540x000900ab,
2550x0006000c,
2560x92010020,
2570x7e439378,
2580x48000001,
2590x00030000,
2600x81d20000,
2610x00098200,
2620x81720000,
2630x00098200,
2640x814efffc,
2650x7d6e5850,
2660x820a0000,
2670x00098200,
2680x80f00000,
2690x3a100004,
2700x54e815ba,
2710x54f4dd78,
2720x7c11402e,
2730x7e947214,
2740x7c0903a6,
2750x4e800420,
2760x00060021,
2770x9421fef0,
2780x91c10000,
2790x00098200,
2800xd9c10000,
2810x00098200,
2820x91e10000,
2830x00098200,
2840xd9e10000,
2850x00098200,
2860x92010000,
2870x00098200,
2880xda010000,
2890x00098200,
2900x7c0802a6,
2910x92210000,
2920x00098200,
2930x00000000,
2940xda210000,
2950x00098200,
2960x92410000,
2970x00098200,
2980xda410000,
2990x00098200,
3000x92610000,
3010x00098200,
3020xda610000,
3030x00098200,
3040x92810000,
3050x00098200,
3060xda810000,
3070x00098200,
3080x92a10000,
3090x00098200,
3100xdaa10000,
3110x00098200,
3120x92c10000,
3130x00098200,
3140xdac10000,
3150x00098200,
3160x90010114,
3170x92e10000,
3180x00098200,
3190xdae10000,
3200x00098200,
3210x93010000,
3220x00098200,
3230xdb010000,
3240x00098200,
3250x93210000,
3260x00098200,
3270xdb210000,
3280x00098200,
3290x7c000026,
3300x93410000,
3310x00098200,
3320xdb410000,
3330x00098200,
3340x93610000,
3350x00098200,
3360xdb610000,
3370x00098200,
3380x93810000,
3390x00098200,
3400x00000000,
3410xdb810000,
3420x00098200,
3430x93a10000,
3440x00098200,
3450xdba10000,
3460x00098200,
3470x93c10000,
3480x00098200,
3490xdbc10000,
3500x00098200,
3510x93e10000,
3520x00098200,
3530xdbe10000,
3540x00098200,
3550x90010034,
3560x7c721b78,
3570x82320000,
3580x00098200,
3590x7c8e2378,
3600x89120000,
3610x00098200,
3620x92410024,
3630x3a000000,
3640x00098200,
3650x38010000,
3660x00098200,
3670x3a310000,
3680x00098200,
3690x90a1002c,
3700x28080000,
3710x90a10030,
3720x90120000,
3730x00098200,
3740x90a10028,
3750x90610020,
3760x41820000,
3770x00050803,
3780x7dd47378,
3790x81d20000,
3800x00098200,
3810x3ac00000,
3820x00098200,
3830x81120000,
3840x00098200,
3850x820efff8,
3860x3cc059c0,
3870x7d8e4050,
3880x98b20000,
3890x00098200,
3900x90c10010,
3910x72000000,
3920x00090200,
3930x60c60004,
3940xc3c10010,
3950x3b000000,
3960x90c10010,
3970x398c0008,
3980x3c004338,
3990x7d936378,
4000x90010008,
4010x38000000,
4020x00098200,
4030xc3e10010,
4040x3ae00000,
4050x00098200,
4060x90110000,
4070x00098200,
4080x00000000,
4090x41820000,
4100x00050817,
4110x48000000,
4120x00050018,
4130x00060022,
4140x9421fef0,
4150x91c10000,
4160x00098200,
4170xd9c10000,
4180x00098200,
4190x91e10000,
4200x00098200,
4210xd9e10000,
4220x00098200,
4230x92010000,
4240x00098200,
4250xda010000,
4260x00098200,
4270x7c0802a6,
4280x92210000,
4290x00098200,
4300xda210000,
4310x00098200,
4320x92410000,
4330x00098200,
4340xda410000,
4350x00098200,
4360x92610000,
4370x00098200,
4380xda610000,
4390x00098200,
4400x92810000,
4410x00098200,
4420xda810000,
4430x00098200,
4440x92a10000,
4450x00098200,
4460xdaa10000,
4470x00098200,
4480x92c10000,
4490x00098200,
4500xdac10000,
4510x00098200,
4520x90010114,
4530x92e10000,
4540x00098200,
4550x00000000,
4560xdae10000,
4570x00098200,
4580x93010000,
4590x00098200,
4600xdb010000,
4610x00098200,
4620x93210000,
4630x00098200,
4640xdb210000,
4650x00098200,
4660x7c000026,
4670x93410000,
4680x00098200,
4690xdb410000,
4700x00098200,
4710x93610000,
4720x00098200,
4730xdb610000,
4740x00098200,
4750x93810000,
4760x00098200,
4770xdb810000,
4780x00098200,
4790x93a10000,
4800x00098200,
4810xdba10000,
4820x00098200,
4830x93c10000,
4840x00098200,
4850xdbc10000,
4860x00098200,
4870x93e10000,
4880x00098200,
4890xdbe10000,
4900x00098200,
4910x90010034,
4920x3a000000,
4930x00098200,
4940x90c10030,
4950x48000000,
4960x00050001,
4970x00060023,
4980x9421fef0,
4990x91c10000,
5000x00098200,
5010xd9c10000,
5020x00098200,
5030x00000000,
5040x91e10000,
5050x00098200,
5060xd9e10000,
5070x00098200,
5080x92010000,
5090x00098200,
5100xda010000,
5110x00098200,
5120x7c0802a6,
5130x92210000,
5140x00098200,
5150xda210000,
5160x00098200,
5170x92410000,
5180x00098200,
5190xda410000,
5200x00098200,
5210x92610000,
5220x00098200,
5230xda610000,
5240x00098200,
5250x92810000,
5260x00098200,
5270xda810000,
5280x00098200,
5290x92a10000,
5300x00098200,
5310xdaa10000,
5320x00098200,
5330x92c10000,
5340x00098200,
5350xdac10000,
5360x00098200,
5370x90010114,
5380x92e10000,
5390x00098200,
5400xdae10000,
5410x00098200,
5420x93010000,
5430x00098200,
5440xdb010000,
5450x00098200,
5460x93210000,
5470x00098200,
5480xdb210000,
5490x00098200,
5500x00000000,
5510x7c000026,
5520x93410000,
5530x00098200,
5540xdb410000,
5550x00098200,
5560x93610000,
5570x00098200,
5580xdb610000,
5590x00098200,
5600x93810000,
5610x00098200,
5620xdb810000,
5630x00098200,
5640x93a10000,
5650x00098200,
5660xdba10000,
5670x00098200,
5680x93c10000,
5690x00098200,
5700xdbc10000,
5710x00098200,
5720x93e10000,
5730x00098200,
5740xdbe10000,
5750x00098200,
5760x90010034,
5770x3a000000,
5780x00098200,
5790x0006000b,
5800x81030000,
5810x00098200,
5820x90a1002c,
5830x7c721b78,
5840x90610024,
5850x7c8e2378,
5860x90320000,
5870x00098200,
5880x82320000,
5890x00098200,
5900x90610020,
5910x91010028,
5920x3a310000,
5930x00098200,
5940x0006000d,
5950x81320000,
5960x00098200,
5970x3ac00000,
5980x00098200,
5990x81120000,
6000x00098200,
6010x00000000,
6020x3cc059c0,
6030x7e107214,
6040x90c10010,
6050x3b000000,
6060x60c60004,
6070xc3c10010,
6080x7e098050,
6090x90c10010,
6100x3c004338,
6110x7d6e4050,
6120x90010008,
6130x38000000,
6140x00098200,
6150xc3e10010,
6160x3ae00000,
6170x00098200,
6180x90110000,
6190x00098200,
6200x00060024,
6210x800efff8,
6220x814efffc,
6230x2c000000,
6240x00098200,
6250x40820000,
6260x00050825,
6270x00060026,
6280x920efff8,
6290x820a0000,
6300x00098200,
6310x80f00000,
6320x3a100004,
6330x54e815ba,
6340x54f4dd78,
6350x7c11402e,
6360x7e947214,
6370x7c0903a6,
6380x4e800420,
6390x00060027,
6400x9421fef0,
6410x91c10000,
6420x00098200,
6430xd9c10000,
6440x00098200,
6450x91e10000,
6460x00098200,
6470xd9e10000,
6480x00098200,
6490x92010000,
6500x00098200,
6510xda010000,
6520x00098200,
6530x7c0802a6,
6540x92210000,
6550x00098200,
6560xda210000,
6570x00098200,
6580x92410000,
6590x00098200,
6600xda410000,
6610x00098200,
6620x92610000,
6630x00098200,
6640xda610000,
6650x00098200,
6660x92810000,
6670x00098200,
6680x00000000,
6690xda810000,
6700x00098200,
6710x92a10000,
6720x00098200,
6730xdaa10000,
6740x00098200,
6750x92c10000,
6760x00098200,
6770xdac10000,
6780x00098200,
6790x90010114,
6800x92e10000,
6810x00098200,
6820xdae10000,
6830x00098200,
6840x93010000,
6850x00098200,
6860xdb010000,
6870x00098200,
6880x93210000,
6890x00098200,
6900xdb210000,
6910x00098200,
6920x7c000026,
6930x93410000,
6940x00098200,
6950xdb410000,
6960x00098200,
6970x93610000,
6980x00098200,
6990xdb610000,
7000x00098200,
7010x93810000,
7020x00098200,
7030xdb810000,
7040x00098200,
7050x93a10000,
7060x00098200,
7070xdba10000,
7080x00098200,
7090x93c10000,
7100x00098200,
7110xdbc10000,
7120x00098200,
7130x93e10000,
7140x00098200,
7150x00000000,
7160xdbe10000,
7170x00098200,
7180x90010034,
7190x7c721b78,
7200x80030000,
7210x00098200,
7220x90610024,
7230x81120000,
7240x00098200,
7250x90610020,
7260x7c080050,
7270x81120000,
7280x00098200,
7290x90320000,
7300x00098200,
7310x39200000,
7320x9001002c,
7330x91210030,
7340x91010028,
7350x7cc903a6,
7360x4e800421,
7370x7c6e1b79,
7380x82320000,
7390x00098200,
7400x3a000000,
7410x00098200,
7420x3a310000,
7430x00098200,
7440x40820000,
7450x0005080d,
7460x48000000,
7470x00050019,
7480x00060015,
7490x800efff4,
7500x7dca7378,
7510x7d2e4b78,
7520x8109fffc,
7530x00000000,
7540x28000001,
7550x00000000,
7560x820afff0,
7570x392cfff8,
7580x81080000,
7590x00098200,
7600x7ef4492e,
7610x00000000,
7620x40810000,
7630x00050801,
7640x00000000,
7650x81e80000,
7660x00098200,
7670x7c0903a6,
7680x4e800420,
7690x00000000,
7700x0006000b,
7710x41820000,
7720x00050828,
7730x390afff0,
7740x7d6e4050,
7750x48000000,
7760x00050029,
7770x00000000,
7780x0006002a,
7790x80f0fffc,
7800x388afff0,
7810x54f55d78,
7820xc8140000,
7830x7d0eaa14,
7840x91d20000,
7850x00098200,
7860x7c082040,
7870x7ca82050,
7880x54f4dd78,
7890xd8040000,
7900x40a20000,
7910x0005082b,
7920x7c0ea5ae,
7930x48000000,
7940x0005002c,
7950x0006002d,
7960x38b10000,
7970x00098200,
7980x38000000,
7990x00098200,
8000x54ea5d78,
8010x91650004,
8020x7c8e5214,
8030x90050000,
8040x48000000,
8050x00050001,
8060x0006002e,
8070x38910000,
8080x00098200,
8090x38000000,
8100x00098200,
8110x91440004,
8120x38b10000,
8130x00098200,
8140x90040000,
8150x39000000,
8160x00098200,
8170x91650004,
8180x91050000,
8190x48000000,
8200x00050001,
8210x0006002f,
8220x00000000,
8230x9001000c,
8240xc8010008,
8250xfc00f028,
8260x00000000,
8270x54ea5d78,
8280x38b10000,
8290x00098200,
8300x7c8e5214,
8310x00000000,
8320x92c50000,
8330x90050004,
8340x00000000,
8350xd8050000,
8360x00000000,
8370x48000000,
8380x00050001,
8390x00060030,
8400x54ea5d78,
8410x54eb9d78,
8420x7c8e5214,
8430x7cae5a14,
8440x0006000b,
8450x91d20000,
8460x00098200,
8470x7e439378,
8480x92010020,
8490x48000001,
8500x00030001,
8510x28030000,
8520x41820000,
8530x00050803,
8540xc8030000,
8550x80f00000,
8560x3a100004,
8570x7c0ea5ae,
8580x54e815ba,
8590x7c11402e,
8600x7c0903a6,
8610x54ea5d78,
8620x54ec9b78,
8630x54f4dd78,
8640x54eb9d78,
8650x4e800420,
8660x0006000d,
8670x210e0000,
8680x00098200,
8690x81d20000,
8700x00098200,
8710x920efff0,
8720x7e087214,
8730x814efffc,
8740x39600010,
8750x48000000,
8760x00050026,
8770x00060031,
8780x38b10000,
8790x00098200,
8800x38000000,
8810x00098200,
8820x54ea5d78,
8830x91650004,
8840x7c8e5214,
8850x90050000,
8860x48000000,
8870x00050001,
8880x00060032,
8890x38910000,
8900x00098200,
8910x38000000,
8920x00098200,
8930x91440004,
8940x38b10000,
8950x00098200,
8960x90040000,
8970x39000000,
8980x00098200,
8990x91650004,
9000x91050000,
9010x48000000,
9020x00050001,
9030x00060033,
9040x00000000,
9050x9001000c,
9060xc8010008,
9070xfc00f028,
9080x00000000,
9090x54ea5d78,
9100x38b10000,
9110x00098200,
9120x7c8e5214,
9130x00000000,
9140x92c50000,
9150x90050004,
9160x00000000,
9170xd8050000,
9180x00000000,
9190x48000000,
9200x00050001,
9210x00060034,
9220x54ea5d78,
9230x54eb9d78,
9240x7c8e5214,
9250x7cae5a14,
9260x0006000b,
9270x91d20000,
9280x00098200,
9290x7e439378,
9300x92010020,
9310x48000001,
9320x00030002,
9330x28030000,
9340x7c0ea4ae,
9350x41820000,
9360x00050803,
9370x80f00000,
9380x3a100004,
9390xd8030000,
9400x54e815ba,
9410x7c11402e,
9420x7c0903a6,
9430x54ea5d78,
9440x54ec9b78,
9450x54f4dd78,
9460x54eb9d78,
9470x4e800420,
9480x0006000d,
9490x210e0000,
9500x00098200,
9510x81d20000,
9520x00098200,
9530x920efff0,
9540x7e087214,
9550x814efffc,
9560x39600018,
9570xd80e0010,
9580x48000000,
9590x00050026,
9600x00060035,
9610x7e439378,
9620x3a10fffc,
9630x00000000,
9640x7e84a378,
9650x00000000,
9660x7c8ea214,
9670x00000000,
9680x92010020,
9690x00000000,
9700x7d856378,
9710x00000000,
9720x7cae6214,
9730x00000000,
9740x91d20000,
9750x00098200,
9760x54e6063e,
9770x48000001,
9780x00030003,
9790x0006000d,
9800x28030001,
9810x41810000,
9820x00050836,
9830x20630000,
9840x0006000e,
9850x80f00000,
9860x3a100004,
9870x54e993ba,
9880x3d290000,
9890x00098200,
9900x7d291838,
9910x7e104a14,
9920x0006002c,
9930x80f00000,
9940x3a100004,
9950x54e815ba,
9960x7c11402e,
9970x7c0903a6,
9980x54ea5d78,
9990x54ec9b78,
10000x54f4dd78,
10010x54eb9d78,
10020x4e800420,
10030x00060037,
10040x80f0fffc,
10050xc8140000,
10060x54e8dd78,
10070x7c0e45ae,
10080x48000000,
10090x0005002c,
10100x00060038,
10110x80140000,
10120x20000000,
10130x00098200,
10140x7c631910,
10150x7c6318f8,
10160x48000000,
10170x0005000e,
10180x00060039,
10190x80140000,
10200x20000000,
10210x00098200,
10220x7c631910,
10230x48000000,
10240x0005000e,
10250x0006003a,
10260x3a10fffc,
10270x91d20000,
10280x00098200,
10290x7e439378,
10300x92010020,
10310x48000001,
10320x00030004,
10330x48000000,
10340x0005000d,
10350x0006003b,
10360x00000000,
10370x7ce43b78,
10380x3a10fffc,
10390x91d20000,
10400x00098200,
10410x7e439378,
10420x92010020,
10430x48000001,
10440x00030005,
10450x48000000,
10460x0005000d,
10470x00000000,
10480x0006003c,
10490x7caf5a14,
10500x7cce5214,
10510x48000000,
10520x00050001,
10530x0006003d,
10540x00000000,
10550x7d655b78,
10560x7d465378,
10570x48000000,
10580x00050001,
10590x00000000,
10600x0006003e,
10610x7d856378,
10620x7d866378,
10630x48000000,
10640x00050001,
10650x0006003f,
10660x7cae5214,
10670x7ccf5a14,
10680x48000000,
10690x00050001,
10700x00060040,
10710x7cae5214,
10720x7cce5a14,
10730x00000000,
10740x48000000,
10750x00050001,
10760x00000000,
10770x00060041,
10780x00060042,
10790x00000000,
10800x7d455378,
10810x7d665b78,
10820x00000000,
10830x0006000b,
10840x7c8ea214,
10850x91d20000,
10860x00098200,
10870x7e439378,
10880x92010020,
10890x54e7063e,
10900x48000001,
10910x00030006,
10920x28030000,
10930x41820000,
10940x0005082c,
10950x00060036,
10960x7d0e1850,
10970x9203fff0,
10980x7dc97378,
10990x3a080000,
11000x00098200,
11010x7c6e1b78,
11020x39600010,
11030x48000000,
11040x00050024,
11050x00060043,
11060x00000000,
11070x7c751b78,
11080x00000000,
11090x7d846378,
11100x91d20000,
11110x00098200,
11120x7e439378,
11130x92010020,
11140x48000001,
11150x00030007,
11160x00000000,
11170x28030000,
11180x40820000,
11190x00050836,
11200x7ea3ab78,
11210x48000000,
11220x00050044,
11230x00000000,
11240x48000000,
11250x00050036,
11260x00000000,
11270x00060025,
11280x7e439378,
11290x91320000,
11300x00098200,
11310x388efff8,
11320x92010020,
11330x7cae5a14,
11340x7d755b78,
11350x48000001,
11360x00030008,
11370x814efffc,
11380x39750008,
11390x920efff8,
11400x820a0000,
11410x00098200,
11420x80f00000,
11430x3a100004,
11440x54e815ba,
11450x54f4dd78,
11460x7c11402e,
11470x7e947214,
11480x7c0903a6,
11490x4e800420,
11500x00060045,
11510x7e439378,
11520x91d20000,
11530x00098200,
11540x3894fff8,
11550x92010020,
11560x7cb45a14,
11570x7d755b78,
11580x48000001,
11590x00030008,
11600x810efff8,
11610x39750008,
11620x8154fffc,
11630x48000000,
11640x00050046,
11650x00060047,
11660x7e439378,
11670x91d20000,
11680x00098200,
11690x7e84a378,
11700x92010020,
11710x7cf53b78,
11720x48000001,
11730x00030009,
11740x00000000,
11750x56a0063e,
11760x00000000,
11770x56b4dd78,
11780x00000000,
11790x2c000000,
11800x00098200,
11810x00000000,
11820x56ac9b78,
11830x00000000,
11840x41a20000,
11850x00070800,
11860x00000000,
11870x48000000,
11880x00070000,
11890x00060048,
11900x280b0008,
11910x80ae0000,
11920x806e0004,
11930x41800000,
11940x00050849,
11950x39000000,
11960x00098200,
11970x3a8efff8,
11980x7c854040,
11990x820efff8,
12000x40840000,
12010x00050849,
12020x90b40000,
12030x398b0008,
12040x90740004,
12050x41820000,
12060x0005084a,
12070x39000008,
12080x396bfff8,
12090x0006000b,
12100x7c085840,
12110x7c0e44ae,
12120x7c1445ae,
12130x39080008,
12140x40a20000,
12150x0005080b,
12160x48000000,
12170x0005004a,
12180x0006004b,
12190x280b0008,
12200x806e0000,
12210x41800000,
12220x00050849,
12230x7c161810,
12240x7d231910,
12250x7d280338,
12260x39080000,
12270x00098200,
12280x55081800,
12290x000900a1,
12300x392a0000,
12310x00098200,
12320x7c2944ae,
12330x48000000,
12340x0005004c,
12350x0006004d,
12360x280b0008,
12370x80ae0000,
12380x806e0004,
12390x41800000,
12400x00050849,
12410x2c050000,
12420x00098200,
12430x40820000,
12440x00050806,
12450x0006000b,
12460x80630000,
12470x00098200,
12480x0006000c,
12490x00000000,
12500x38a00000,
12510x00098200,
12520x28030000,
12530x81710000,
12540x00098200,
12550x41820000,
12560x0005084e,
12570x80030000,
12580x00098200,
12590x38a00000,
12600x00098200,
12610x810b0000,
12620x00098200,
12630x81230000,
12640x00098200,
12650x7d080038,
12660x55002800,
12670x000900a1,
12680x55081800,
12690x000900a1,
12700x7d080050,
12710x7d294214,
12720x0006000d,
12730x80c90000,
12740x00098200,
12750x80090000,
12760x00098200,
12770x80890000,
12780x00098200,
12790x81090000,
12800x00098200,
12810x2c060000,
12820x00098200,
12830x40820000,
12840x00050804,
12850x7c005800,
12860x41820000,
12870x00050805,
12880x0006000e,
12890x81290000,
12900x00098200,
12910x28090000,
12920x41820000,
12930x0005084e,
12940x48000000,
12950x0005000d,
12960x0006000f,
12970x00000000,
12980x2c040000,
12990x00098200,
13000x41820000,
13010x0005084e,
13020x7c852378,
13030x7d034378,
13040x48000000,
13050x0005004e,
13060x00060010,
13070x2c050000,
13080x00098200,
13090x41820000,
13100x0005080b,
13110x7c162810,
13120x7d252910,
13130x7d280338,
13140x39080000,
13150x00098200,
13160x55081000,
13170x000900a1,
13180x39310000,
13190x00098200,
13200x7c69402e,
13210x48000000,
13220x0005000c,
13230x0006004f,
13240x280b0010,
13250x80ae0000,
13260x80ce0008,
13270x806e0004,
13280x808e000c,
13290x41800000,
13300x00050849,
13310x2c050000,
13320x00098200,
13330x40820000,
13340x00050849,
13350x81030000,
13360x00098200,
13370x2c060000,
13380x00098200,
13390x40820000,
13400x00050849,
13410x28080000,
13420x88c30000,
13430x00098200,
13440x40820000,
13450x00050849,
13460x70c00000,
13470x00090200,
13480x90830000,
13490x00098200,
13500x41820000,
13510x0005084e,
13520x00000000,
13530x80110000,
13540x00098200,
13550x54c607b8,
13560x90710000,
13570x00098200,
13580x98c30000,
13590x00098200,
13600x90030000,
13610x00098200,
13620x48000000,
13630x0005004e,
13640x00060050,
13650x280b0008,
13660x80ce0000,
13670x808e0004,
13680x41800000,
13690x00050849,
13700x2c060000,
13710x00098200,
13720x40820000,
13730x00050849,
13740x38ae0008,
13750x7e439378,
13760x48000001,
13770x0003000a,
13780xc8230000,
13790x48000000,
13800x0005004c,
13810x00060051,
13820x280b0008,
13830x806e0000,
13840xc82e0000,
13850x40820000,
13860x00050849,
13870x7c03b040,
13880x41810000,
13890x00050849,
13900x48000000,
13910x0005004c,
13920x00060052,
13930x280b0008,
13940x80ae0000,
13950x806e0004,
13960x41800000,
13970x00050849,
13980x2c050000,
13990x00098200,
14000x41820000,
14010x0005084e,
14020x80110000,
14030x00098200,
14040x7c05b040,
14050x28800000,
14060x91d20000,
14070x00098200,
14080x4c413342,
14090x92010020,
14100x41820000,
14110x00050849,
14120x00000000,
14130x80110000,
14140x00098200,
14150x81110000,
14160x00098200,
14170x7c004040,
14180x40800001,
14190x00050853,
14200x7e439378,
14210x7dc47378,
14220x00000000,
14230x48000001,
14240x0003000b,
14250x00000000,
14260x48000001,
14270x0003000c,
14280x00000000,
14290x38a00000,
14300x00098200,
14310x48000000,
14320x0005004e,
14330x00060054,
14340x280b0008,
14350x806e0000,
14360x808e0004,
14370x41800000,
14380x00050849,
14390x7eee592e,
14400x2c030000,
14410x00098200,
14420x820efff8,
14430x40820000,
14440x00050849,
14450x91d20000,
14460x00098200,
14470x7e439378,
14480x91d20000,
14490x00098200,
14500x38ae0008,
14510x92010020,
14520x48000001,
14530x0003000d,
14540x28030000,
14550x38a00000,
14560x00098200,
14570x41820000,
14580x0005084e,
14590xc80e0008,
14600x3a8efff8,
14610xc82e0010,
14620xd8140000,
14630x39800000,
14640x00098200,
14650xd8340008,
14660x48000000,
14670x0005004a,
14680x00060055,
14690x280b0008,
14700x80ae0000,
14710x806e0004,
14720x41800000,
14730x00050849,
14740x2c050000,
14750x00098200,
14760x820efff8,
14770x40820000,
14780x00050849,
14790x00000000,
14800x81230000,
14810x00098200,
14820xc80a0000,
14830x00098200,
14840x28090000,
14850x3a8efff8,
14860x40820000,
14870x00050849,
14880x00000000,
14890xc80a0000,
14900x00098200,
14910x3a8efff8,
14920x00000000,
14930x92ee0008,
14940x39800000,
14950x00098200,
14960xd8140000,
14970x48000000,
14980x0005004a,
14990x00060056,
15000x280b0010,
15010x80ae0000,
15020x806e0004,
15030x80ce0008,
15040x00000000,
15050x812e000c,
15060x00000000,
15070xc84e0008,
15080x00000000,
15090x41800000,
15100x00050849,
15110x2c050000,
15120x00098200,
15130x7c86b040,
15140x820efff8,
15150x00000000,
15160x40820000,
15170x00050849,
15180x40860000,
15190x00050849,
15200x00000000,
15210x3c003ff0,
15220x93010014,
15230x40820000,
15240x00050849,
15250x90010010,
15260x40840000,
15270x00050849,
15280xc8210010,
15290xfc00101e,
15300xd8010010,
15310x81210014,
15320x00000000,
15330x80030000,
15340x00098200,
15350x81030000,
15360x00098200,
15370x00000000,
15380xfc42082a,
15390x00000000,
15400x39290001,
15410x3a8efff8,
15420x7c004840,
15430x00000000,
15440x92d40000,
15450x55261800,
15460x000900a1,
15470x91340004,
15480x00000000,
15490x55261800,
15500x000900a1,
15510xd8540000,
15520x00000000,
15530x40810000,
15540x00050802,
15550x7d28302e,
15560x7c0834ae,
15570x0006000b,
15580x2c090000,
15590x00098200,
15600x39800000,
15610x00098200,
15620x41820000,
15630x0005084a,
15640x39800000,
15650x00098200,
15660xd8140008,
15670x48000000,
15680x0005004a,
15690x0006000c,
15700x80030000,
15710x00098200,
15720x28000000,
15730x39800000,
15740x00098200,
15750x41820000,
15760x0005084a,
15770x7d244b78,
15780x48000001,
15790x0003000e,
15800x28030000,
15810x39800000,
15820x00098200,
15830x41820000,
15840x0005084a,
15850x81230000,
15860xc8030000,
15870x48000000,
15880x0005000b,
15890x00060057,
15900x280b0008,
15910x80ae0000,
15920x806e0004,
15930x41800000,
15940x00050849,
15950x2c050000,
15960x00098200,
15970x820efff8,
15980x40820000,
15990x00050849,
16000x00000000,
16010x81230000,
16020x00098200,
16030xc80a0000,
16040x00098200,
16050x28090000,
16060x3a8efff8,
16070x40820000,
16080x00050849,
16090x00000000,
16100xc80a0000,
16110x00098200,
16120x3a8efff8,
16130x00000000,
16140x92ce0008,
16150x00000000,
16160x930e0008,
16170x00000000,
16180x930e000c,
16190x39800000,
16200x00098200,
16210xd8140000,
16220x48000000,
16230x0005004a,
16240x00060058,
16250x280b0008,
16260x88d10000,
16270x00098200,
16280x41800000,
16290x00050849,
16300x7dc97378,
16310x39ce0008,
16320x54c607fe,
16330x000900ab,
16340x396bfff8,
16350x3a060000,
16360x00098200,
16370x48000000,
16380x00050024,
16390x00060059,
16400x280b0010,
16410x80ce0008,
16420xc84e0008,
16430x80ae0000,
16440xc82e0000,
16450x41800000,
16460x00050849,
16470x89110000,
16480x00098200,
16490x7dc97378,
16500x2c060000,
16510x00098200,
16520x40820000,
16530x00050849,
16540x39ce0010,
16550x550807fe,
16560x000900ab,
16570xd8490000,
16580x396bfff0,
16590xd8290008,
16600x3a080000,
16610x00098200,
16620x48000000,
16630x00050024,
16640x0006005a,
16650x280b0008,
16660x80ae0000,
16670x806e0004,
16680x41800000,
16690x00050849,
16700x2c050000,
16710x00098200,
16720x40820000,
16730x00050849,
16740x88030000,
16750x00098200,
16760x81030000,
16770x00098200,
16780x00000000,
16790x80830000,
16800x00098200,
16810x28000000,
16820x00090200,
16830x81230000,
16840x00098200,
16850x28880000,
16860x80030000,
16870x00098200,
16880x7f844840,
16890x820efff8,
16900x4f013342,
16910x7d245a14,
16920x4f3e1102,
16930x7c890040,
16940x4f18cb82,
16950x92010020,
16960x4f182b82,
16970x91d20000,
16980x00098200,
16990x41980000,
17000x00050849,
17010x0006000b,
17020x39ce0008,
17030x396bfff8,
17040x3929fff8,
17050x91230000,
17060x00098200,
17070x39000000,
17080x91d20000,
17090x00098200,
17100x0006000c,
17110x7c085800,
17120x7c0e44ae,
17130x41820000,
17140x00050803,
17150x7c0445ae,
17160x39080008,
17170x48000000,
17180x0005000c,
17190x0006000d,
17200x38a00000,
17210x7c751b78,
17220x38c00000,
17230x48000001,
17240x00050021,
17250x0006000e,
17260x81350000,
17270x00098200,
17280x28030000,
17290x00090200,
17300x80d50000,
17310x00098200,
17320x38000000,
17330x00098200,
17340x81d20000,
17350x00098200,
17360x90110000,
17370x00098200,
17380x41810000,
17390x00050808,
17400x00000000,
17410x7d893050,
17420x80120000,
17430x00098200,
17440x280c0000,
17450x7d0e6214,
17460x41820000,
17470x00050806,
17480x7c080040,
17490x39000000,
17500x41810000,
17510x00050809,
17520x38ccfff8,
17530x91350000,
17540x00098200,
17550x0006000f,
17560x7c083040,
17570x7c0944ae,
17580x7c0e45ae,
17590x39080008,
17600x40820000,
17610x0005080f,
17620x00060010,
17630x72000000,
17640x00090200,
17650x39000000,
17660x00098200,
17670x3a8efff8,
17680x910efff8,
17690x398c0010,
17700x00060011,
17710x92010020,
17720x7d936378,
17730x41820000,
17740x00050817,
17750x48000000,
17760x00050018,
17770x00060012,
17780x72000000,
17790x00090200,
17800x38c6fff8,
17810x39000000,
17820x00098200,
17830xc8060000,
17840x90d50000,
17850x00098200,
17860x39800000,
17870x00098200,
17880x910efff8,
17890x3a8efff8,
17900xd80e0000,
17910x48000000,
17920x00050011,
17930x00060013,
17940x7e439378,
17950x558400fe,
17960x000900ab,
17970x48000001,
17980x00030000,
17990x38600000,
18000x48000000,
18010x0005000e,
18020x0006005b,
18030x00000000,
18040x806a0000,
18050x00098200,
18060x88030000,
18070x00098200,
18080x81030000,
18090x00098200,
18100x80830000,
18110x00098200,
18120x28000000,
18130x00090200,
18140x81230000,
18150x00098200,
18160x28880000,
18170x80030000,
18180x00098200,
18190x7f844840,
18200x820efff8,
18210x4f013342,
18220x7d245a14,
18230x4f3e1102,
18240x7c890040,
18250x4f18cb82,
18260x92010020,
18270x4f182b82,
18280x91d20000,
18290x00098200,
18300x41980000,
18310x00050849,
18320x0006000b,
18330x91230000,
18340x00098200,
18350x39000000,
18360x91d20000,
18370x00098200,
18380x0006000c,
18390x7c085800,
18400x7c0e44ae,
18410x41820000,
18420x00050803,
18430x7c0445ae,
18440x39080008,
18450x48000000,
18460x0005000c,
18470x0006000d,
18480x38a00000,
18490x7c751b78,
18500x38c00000,
18510x48000001,
18520x00050021,
18530x0006000e,
18540x81350000,
18550x00098200,
18560x28030000,
18570x00090200,
18580x80d50000,
18590x00098200,
18600x38000000,
18610x00098200,
18620x00000000,
18630x81d20000,
18640x00098200,
18650x90110000,
18660x00098200,
18670x41810000,
18680x00050808,
18690x7d893050,
18700x80120000,
18710x00098200,
18720x280c0000,
18730x7d0e6214,
18740x41820000,
18750x00050806,
18760x7c080040,
18770x39000000,
18780x41810000,
18790x00050809,
18800x38ccfff8,
18810x91350000,
18820x00098200,
18830x0006000f,
18840x7c083040,
18850x7c0944ae,
18860x7c0e45ae,
18870x39080008,
18880x40820000,
18890x0005080f,
18900x00060010,
18910x72000000,
18920x00090200,
18930x7dd47378,
18940x398c0008,
18950x00060011,
18960x92010020,
18970x7d936378,
18980x41820000,
18990x00050817,
19000x48000000,
19010x00050018,
19020x00060012,
19030x7e439378,
19040x7ea4ab78,
19050x48000001,
19060x0003000f,
19070x00060013,
19080x7e439378,
19090x558400fe,
19100x000900ab,
19110x48000001,
19120x00030000,
19130x38600000,
19140x48000000,
19150x0005000e,
19160x0006005c,
19170x80120000,
19180x00098200,
19190x00000000,
19200x7d0e5a14,
19210x91d20000,
19220x00098200,
19230x70000000,
19240x00090200,
19250x91120000,
19260x00098200,
19270x38600000,
19280x00098200,
19290x41820000,
19300x00050849,
19310x93120000,
19320x00098200,
19330x98720000,
19340x00098200,
19350x48000000,
19360x0005001a,
19370x0006005d,
19380x280b0008,
19390x80ae0000,
19400x806e0004,
19410x41800000,
19420x00050849,
19430x7c05b040,
19440x00000000,
19450x40820000,
19460x00050802,
19470x7c68fe70,
19480x7d091a78,
19490x7c684851,
19500x41800000,
19510x00050801,
19520x0006005e,
19530x820efff8,
19540x3a8efff8,
19550x92cefff8,
19560x906efffc,
19570x48000000,
19580x0005005f,
19590x0006000b,
19600x3ca041e0,
19610x38600000,
19620x48000000,
19630x0005004e,
19640x0006000c,
19650x00000000,
19660x40800000,
19670x00050849,
19680x54a5007e,
19690x0006004e,
19700x820efff8,
19710x90aefff8,
19720x3a8efff8,
19730x906efffc,
19740x0006005f,
19750x39800000,
19760x00098200,
19770x0006004a,
19780x72000000,
19790x00090200,
19800x7d936378,
19810x40a20000,
19820x00050818,
19830x80f0fffc,
19840x54ea5d78,
19850x0006000f,
19860x7c0a6040,
19870x54e0dd78,
19880x41810000,
19890x00050806,
19900x80f00000,
19910x3a100004,
19920x7dc0a050,
19930x54e815ba,
19940x7c11402e,
19950x7c0903a6,
19960x54ea5d78,
19970x54ec9b78,
19980x54f4dd78,
19990x54eb9d78,
20000x4e800420,
20010x00060010,
20020x390cfff8,
20030x398c0008,
20040x7ef4412e,
20050x48000000,
20060x0005000f,
20070x00000000,
20080x00060060,
20090x280b0008,
20100x80ae0000,
20110x806e0004,
20120x41800000,
20130x00050849,
20140x7c05b040,
20150x41a20000,
20160x0005084e,
20170x54a9657e,
20180x40800000,
20190x00050849,
20200x3529fc01,
20210x2889001f,
20220x2009001f,
20230x41800000,
20240x00050803,
20250x54a85800,
20260x000900a1,
20270x5466057e,
20280x000900ab,
20290x65088000,
20300x39290001,
20310x7d083378,
20320x54645800,
20330x000900a1,
20340x40840000,
20350x00050804,
20360x7d064830,
20370x7d030430,
20380x7cc62378,
20390x7ca9fe70,
20400x7cc84838,
20410x3008ffff,
20420x7d004110,
20430x7c634214,
20440x7c634a78,
20450x7c691850,
20460x48000000,
20470x0005005e,
20480x0006000d,
20490x7d252a14,
20500x7ca8fe70,
20510x7c694b78,
20520x7d284038,
20530x21280000,
20540x7c631910,
20550x48000000,
20560x0005005e,
20570x0006000e,
20580x6d088000,
20590x7ca9fe70,
20600x7d082378,
20610x7d084b39,
20620x4c423202,
20630x3c608000,
20640x41a20000,
20650x0005085e,
20660x0006000f,
20670xc82e0000,
20680x48000001,
20690x00030010,
20700x48000000,
20710x0005004c,
20720x00060061,
20730x280b0008,
20740x80ae0000,
20750x806e0004,
20760x41800000,
20770x00050849,
20780x7c05b040,
20790x41a20000,
20800x0005084e,
20810x54a9657e,
20820x40800000,
20830x00050849,
20840x3529fc01,
20850x2889001f,
20860x2009001f,
20870x41800000,
20880x00050803,
20890x00000000,
20900x54a85800,
20910x000900a1,
20920x5466057e,
20930x000900ab,
20940x65088000,
20950x39290001,
20960x7d083378,
20970x54645800,
20980x000900a1,
20990x40840000,
21000x00050804,
21010x7d064830,
21020x7d030430,
21030x7cc62378,
21040x7ca9fe70,
21050x7cc84878,
21060x3008ffff,
21070x7d004110,
21080x7c634615,
21090x7c634a78,
21100x7c691850,
21110x40830000,
21120x0005085e,
21130x7c000400,
21140x40a10000,
21150x0005085e,
21160x3ca041e0,
21170x38600000,
21180x48000000,
21190x0005004e,
21200x0006000d,
21210x7d252a14,
21220x7ca8fe70,
21230x7c694b78,
21240x7d284078,
21250x3128ffff,
21260x7c694110,
21270x48000000,
21280x0005005e,
21290x0006000e,
21300x6d088000,
21310x7ca9fe70,
21320x7d084b39,
21330x4c423202,
21340x3c608000,
21350x41a20000,
21360x0005085e,
21370x0006000f,
21380xc82e0000,
21390x48000001,
21400x00030011,
21410x48000000,
21420x0005004c,
21430x00000000,
21440x00060060,
21450x280b0008,
21460x80ae0000,
21470xc82e0000,
21480x41800000,
21490x00050849,
21500x7c05b040,
21510x40800000,
21520x00050849,
21530x48000001,
21540x00030010,
21550x48000000,
21560x0005004c,
21570x00060061,
21580x280b0008,
21590x80ae0000,
21600xc82e0000,
21610x41800000,
21620x00050849,
21630x7c05b040,
21640x40800000,
21650x00050849,
21660x48000001,
21670x00030011,
21680x48000000,
21690x0005004c,
21700x00000000,
21710x00060062,
21720x280b0008,
21730x80ae0000,
21740xc82e0000,
21750x41800000,
21760x00050849,
21770x7c05b040,
21780x40800000,
21790x00050849,
21800x48000001,
21810x00030012,
21820x48000000,
21830x0005004c,
21840x00060063,
21850x280b0008,
21860x80ae0000,
21870xc82e0000,
21880x41800000,
21890x00050849,
21900x7c05b040,
21910x40800000,
21920x00050849,
21930x48000001,
21940x00030013,
21950x48000000,
21960x0005004c,
21970x00060064,
21980x280b0008,
21990x80ae0000,
22000xc82e0000,
22010x41800000,
22020x00050849,
22030x7c05b040,
22040x40800000,
22050x00050849,
22060x48000001,
22070x00030014,
22080x48000000,
22090x0005004c,
22100x00060065,
22110x280b0008,
22120x80ae0000,
22130xc82e0000,
22140x41800000,
22150x00050849,
22160x7c05b040,
22170x40800000,
22180x00050849,
22190x48000001,
22200x00030015,
22210x48000000,
22220x0005004c,
22230x00060066,
22240x280b0008,
22250x80ae0000,
22260xc82e0000,
22270x41800000,
22280x00050849,
22290x00000000,
22300x7c05b040,
22310x40800000,
22320x00050849,
22330x48000001,
22340x00030016,
22350x48000000,
22360x0005004c,
22370x00060067,
22380x280b0008,
22390x80ae0000,
22400xc82e0000,
22410x41800000,
22420x00050849,
22430x7c05b040,
22440x40800000,
22450x00050849,
22460x48000001,
22470x00030017,
22480x48000000,
22490x0005004c,
22500x00060068,
22510x280b0008,
22520x80ae0000,
22530xc82e0000,
22540x41800000,
22550x00050849,
22560x7c05b040,
22570x40800000,
22580x00050849,
22590x48000001,
22600x00030018,
22610x48000000,
22620x0005004c,
22630x00060069,
22640x280b0008,
22650x80ae0000,
22660xc82e0000,
22670x41800000,
22680x00050849,
22690x7c05b040,
22700x40800000,
22710x00050849,
22720x48000001,
22730x00030019,
22740x48000000,
22750x0005004c,
22760x0006006a,
22770x280b0008,
22780x80ae0000,
22790xc82e0000,
22800x41800000,
22810x00050849,
22820x7c05b040,
22830x40800000,
22840x00050849,
22850x48000001,
22860x0003001a,
22870x00000000,
22880x48000000,
22890x0005004c,
22900x0006006b,
22910x280b0008,
22920x80ae0000,
22930xc82e0000,
22940x41800000,
22950x00050849,
22960x7c05b040,
22970x40800000,
22980x00050849,
22990x48000001,
23000x0003001b,
23010x48000000,
23020x0005004c,
23030x0006006c,
23040x280b0008,
23050x80ae0000,
23060xc82e0000,
23070x41800000,
23080x00050849,
23090x7c05b040,
23100x40800000,
23110x00050849,
23120x48000001,
23130x0003001c,
23140x48000000,
23150x0005004c,
23160x0006006d,
23170x280b0008,
23180x80ae0000,
23190xc82e0000,
23200x41800000,
23210x00050849,
23220x7c05b040,
23230x40800000,
23240x00050849,
23250x48000001,
23260x0003001d,
23270x48000000,
23280x0005004c,
23290x0006006e,
23300x280b0008,
23310x80ae0000,
23320xc82e0000,
23330x41800000,
23340x00050849,
23350x7c05b040,
23360x40800000,
23370x00050849,
23380x48000001,
23390x0003001e,
23400x48000000,
23410x0005004c,
23420x0006006f,
23430x00000000,
23440x280b0010,
23450x80ae0000,
23460xc82e0000,
23470x80ce0008,
23480xc84e0008,
23490x41800000,
23500x00050849,
23510x7c05b040,
23520x40800000,
23530x00050849,
23540x7c06b040,
23550x40800000,
23560x00050849,
23570x48000001,
23580x0003001f,
23590x48000000,
23600x0005004c,
23610x00060070,
23620x280b0010,
23630x80ae0000,
23640xc82e0000,
23650x80ce0008,
23660xc84e0008,
23670x41800000,
23680x00050849,
23690x7c05b040,
23700x40800000,
23710x00050849,
23720x7c06b040,
23730x40800000,
23740x00050849,
23750x48000001,
23760x00030020,
23770x48000000,
23780x0005004c,
23790x00060071,
23800x280b0010,
23810x80ae0000,
23820xc82e0000,
23830x80ce0008,
23840xc84e0008,
23850x41800000,
23860x00050849,
23870x7c05b040,
23880x40800000,
23890x00050849,
23900x7c06b040,
23910x40800000,
23920x00050849,
23930x48000001,
23940x00030021,
23950x48000000,
23960x0005004c,
23970x00060072,
23980x00060073,
23990x280b0008,
24000x80ae0000,
24010xc82e0000,
24020x41800000,
24030x00050849,
24040x7c05b040,
24050x40800000,
24060x00050849,
24070xc84a0000,
24080x00098200,
24090x00000000,
24100xfc2100b2,
24110x48000000,
24120x0005004c,
24130x00000000,
24140x00060074,
24150x280b0010,
24160x80ae0000,
24170xc82e0000,
24180x80ce0008,
24190x806e000c,
24200x41800000,
24210x00050849,
24220x7c05b040,
24230x40800000,
24240x00050849,
24250x7c06b040,
24260x40820000,
24270x00050849,
24280x00000000,
24290x00060074,
24300x280b0010,
24310x80ae0000,
24320xc82e0000,
24330x80ce0008,
24340xc84e0008,
24350x41800000,
24360x00050849,
24370x7c05b040,
24380x40800000,
24390x00050849,
24400x7c06b040,
24410x40800000,
24420x00050849,
24430xfc40101e,
24440xd8410010,
24450x80610014,
24460x00000000,
24470x48000001,
24480x00030022,
24490x48000000,
24500x0005004c,
24510x00060075,
24520x280b0008,
24530x80ae0000,
24540xc82e0000,
24550x41800000,
24560x00050849,
24570x7c05b040,
24580x40800000,
24590x00050849,
24600x38710000,
24610x00098200,
24620x820efff8,
24630x48000001,
24640x00030023,
24650x81110000,
24660x00098200,
24670x3a8efff8,
24680x00000000,
24690x6d088000,
24700x9101000c,
24710xc8410008,
24720xfc42f828,
24730x00000000,
24740xd8340000,
24750x39800000,
24760x00098200,
24770x00000000,
24780x92d40008,
24790x9114000c,
24800x00000000,
24810xd8540008,
24820x00000000,
24830x48000000,
24840x0005004a,
24850x00060076,
24860x280b0008,
24870x80ae0000,
24880xc82e0000,
24890x41800000,
24900x00050849,
24910x7c05b040,
24920x40800000,
24930x00050849,
24940x386efff8,
24950x820efff8,
24960x48000001,
24970x00030024,
24980x3a8efff8,
24990xd82e0000,
25000x39800000,
25010x00098200,
25020x48000000,
25030x0005004a,
25040x00000000,
25050x00060077,
25060x280b0008,
25070x80ae0000,
25080x806e0004,
25090x41800000,
25100x00050849,
25110x7c05b040,
25120x390e0008,
25130x7d2e5a14,
25140x40820000,
25150x00050804,
25160x0006000b,
25170x80c80000,
25180x7c884840,
25190x80880004,
25200x40840000,
25210x0005085e,
25220x7c06b040,
25230x6c608000,
25240x6c868000,
25250x40820000,
25260x00050803,
25270x7cc60010,
25280x7c000110,
25290x7cc60038,
25300x7c662214,
25310x39080008,
25320x48000000,
25330x0005000b,
25340x0006000d,
25350x40800000,
25360x00050849,
25370x6c638000,
25380x9061000c,
25390xc8210008,
25400xfc21f828,
25410xc8480000,
25420x48000000,
25430x00050006,
25440x0006000e,
25450xc82e0000,
25460x40800000,
25470x00050849,
25480x0006000f,
25490x80c80000,
25500x7c884840,
25510xc8480000,
25520x40840000,
25530x0005084c,
25540x7c06b040,
25550x40800000,
25560x00050807,
25570x00060010,
25580xfc011028,
25590x39080008,
25600xfc2008ae,
25610x48000000,
25620x0005000f,
25630x00060011,
25640x80880004,
25650x40820000,
25660x00050849,
25670x6c848000,
25680x9081000c,
25690xc8410008,
25700xfc42f828,
25710x48000000,
25720x00050010,
25730x00000000,
25740x00060077,
25750x280b0008,
25760x80ae0000,
25770xc82e0000,
25780x41800000,
25790x00050849,
25800x7c05b040,
25810x40800000,
25820x00050849,
25830x39000008,
25840x0006000b,
25850x7c8e402e,
25860x7c4e44ae,
25870x7c885840,
25880x7c04b040,
25890x40840000,
25900x0005084c,
25910x40800000,
25920x00050849,
25930xfc011028,
25940x39080008,
25950xfc2008ae,
25960x48000000,
25970x0005000b,
25980x00000000,
25990x00060078,
26000x280b0008,
26010x80ae0000,
26020x806e0004,
26030x41800000,
26040x00050849,
26050x7c05b040,
26060x390e0008,
26070x7d2e5a14,
26080x40820000,
26090x00050804,
26100x0006000b,
26110x80c80000,
26120x7c884840,
26130x80880004,
26140x40840000,
26150x0005085e,
26160x7c06b040,
26170x6c608000,
26180x6c868000,
26190x40820000,
26200x00050803,
26210x7cc60010,
26220x7c000110,
26230x7cc60078,
26240x7c662214,
26250x39080008,
26260x48000000,
26270x0005000b,
26280x0006000d,
26290x40800000,
26300x00050849,
26310x6c638000,
26320x9061000c,
26330xc8210008,
26340xfc21f828,
26350xc8480000,
26360x48000000,
26370x00050006,
26380x0006000e,
26390xc82e0000,
26400x40800000,
26410x00050849,
26420x0006000f,
26430x80c80000,
26440x7c884840,
26450xc8480000,
26460x40840000,
26470x0005084c,
26480x7c06b040,
26490x40800000,
26500x00050807,
26510x00060010,
26520xfc011028,
26530x39080008,
26540xfc20106e,
26550x48000000,
26560x0005000f,
26570x00060011,
26580x80880004,
26590x40820000,
26600x00050849,
26610x6c848000,
26620x9081000c,
26630xc8410008,
26640xfc42f828,
26650x48000000,
26660x00050010,
26670x00000000,
26680x00060078,
26690x280b0008,
26700x80ae0000,
26710xc82e0000,
26720x41800000,
26730x00050849,
26740x7c05b040,
26750x40800000,
26760x00050849,
26770x39000008,
26780x0006000b,
26790x7c8e402e,
26800x7c4e44ae,
26810x7c885840,
26820x7c04b040,
26830x40840000,
26840x0005084c,
26850x40800000,
26860x00050849,
26870xfc011028,
26880x39080008,
26890xfc20106e,
26900x48000000,
26910x0005000b,
26920x00000000,
26930x00060079,
26940x280b0008,
26950x80ae0000,
26960x806e0004,
26970x41800000,
26980x00050849,
26990x2c050000,
27000x00098200,
27010x40820000,
27020x00050849,
27030x80630000,
27040x00098200,
27050x48000000,
27060x0005005e,
27070x0006007a,
27080x280b0008,
27090x80ae0000,
27100x806e0004,
27110x40820000,
27120x00050849,
27130x2c050000,
27140x00098200,
27150x40820000,
27160x00050849,
27170x80030000,
27180x00098200,
27190x00000000,
27200x88630000,
27210x00098200,
27220x39800000,
27230x00098200,
27240x820efff8,
27250x28000000,
27260x3a8efff8,
27270x41a20000,
27280x0005084a,
27290x48000000,
27300x0005005e,
27310x00000000,
27320x89030000,
27330x00098200,
27340x30c0ffff,
27350x7d860110,
27360x9101000c,
27370x398c0001,
27380xc8010008,
27390x3a8efff8,
27400x820efff8,
27410xfc00f028,
27420x558c1800,
27430x000900a1,
27440xd8140000,
27450x48000000,
27460x0005004a,
27470x00000000,
27480x0006007b,
27490x80110000,
27500x00098200,
27510x81110000,
27520x00098200,
27530x7c004040,
27540x40800001,
27550x00050853,
27560x280b0008,
27570x80ae0000,
27580x00000000,
27590x800e0004,
27600x40820000,
27610x00050849,
27620x7c05b040,
27630x40820000,
27640x00050849,
27650x388e0007,
27660x00000000,
27670xc82e0000,
27680x40820000,
27690x00050849,
27700x7c05b040,
27710x40800000,
27720x00050849,
27730xfc20081e,
27740xd8210010,
27750x80010014,
27760x38810017,
27770x00000000,
27780x38a00001,
27790x280000ff,
27800x41810000,
27810x00050849,
27820x0006007c,
27830x7e439378,
27840x91d20000,
27850x00098200,
27860x92010020,
27870x48000001,
27880x00030025,
27890x81d20000,
27900x00098200,
27910x38a00000,
27920x00098200,
27930x48000000,
27940x0005004e,
27950x0006007d,
27960x80110000,
27970x00098200,
27980x81110000,
27990x00098200,
28000x7c004040,
28010x40800001,
28020x00050853,
28030x280b0010,
28040x80ae0010,
28050x00000000,
28060xc80e0010,
28070x00000000,
28080x800e0000,
28090x806e0004,
28100x41800000,
28110x00050849,
28120x808e0008,
28130x00000000,
28140x810e000c,
28150x00000000,
28160xc82e0008,
28170x00000000,
28180x3920ffff,
28190x41820000,
28200x00050801,
28210x00000000,
28220x7c05b040,
28230x812e0014,
28240x40820000,
28250x00050849,
28260x0006000b,
28270x7c04b040,
28280x40820000,
28290x00050849,
28300x00000000,
28310x7c05b040,
28320x40800000,
28330x00050849,
28340xfc00001e,
28350xd8010010,
28360x81210014,
28370x0006000b,
28380x7c04b040,
28390x40800000,
28400x00050849,
28410x00000000,
28420x2c000000,
28430x00098200,
28440x40820000,
28450x00050849,
28460x00000000,
28470xfc20081e,
28480xd8210010,
28490x81010014,
28500x00000000,
28510x80030000,
28520x00098200,
28530x7c004840,
28540x38c90001,
28550x41800000,
28560x00050805,
28570x0006000c,
28580x2c080000,
28590x7cc80214,
28600x40810000,
28610x00050807,
28620x0006000d,
28630x7ca84850,
28640x38830000,
28650x00098200,
28660x7ca0fe70,
28670x38a50001,
28680x7c844214,
28690x7ca50078,
28700x48000000,
28710x0005007c,
28720x0006000f,
28730x7c890050,
28740x7c84fe70,
28750x7cc62078,
28760x7d203214,
28770x48000000,
28780x0005000c,
28790x00060011,
28800x30a8ffff,
28810x7ca52910,
28820x7cc4fe70,
28830x7cc62878,
28840x7cc82078,
28850x39080001,
28860x48000000,
28870x0005000d,
28880x0006007e,
28890x80110000,
28900x00098200,
28910x81110000,
28920x00098200,
28930x7c004040,
28940x40800001,
28950x00050853,
28960x280b0010,
28970x800e0000,
28980x806e0004,
28990x80ce0008,
29000x00000000,
29010x80ae000c,
29020x00000000,
29030xc84e0008,
29040x00000000,
29050x41800000,
29060x00050849,
29070x2c000000,
29080x00098200,
29090x40820000,
29100x00050849,
29110x00000000,
29120x7c06b040,
29130x40820000,
29140x00050849,
29150x00000000,
29160x7c06b040,
29170x40800000,
29180x00050849,
29190xfc40101e,
29200xd8410010,
29210x80a10014,
29220x00000000,
29230x80030000,
29240x00098200,
29250x2c050000,
29260x81110000,
29270x00098200,
29280x40810000,
29290x00050802,
29300x28000001,
29310x3925ffff,
29320x41800000,
29330x00050802,
29340x7c882840,
29350x40820000,
29360x00050849,
29370x88030000,
29380x00098200,
29390x80910000,
29400x00098200,
29410x41840000,
29420x00050849,
29430x0006000b,
29440x28090000,
29450x7c0449ae,
29460x3929ffff,
29470x40820000,
29480x0005080b,
29490x48000000,
29500x0005007c,
29510x0006000c,
29520x38710000,
29530x00098200,
29540x38a00000,
29550x00098200,
29560x48000000,
29570x0005004e,
29580x0006007f,
29590x80110000,
29600x00098200,
29610x81110000,
29620x00098200,
29630x7c004040,
29640x40800001,
29650x00050853,
29660x280b0008,
29670x80ae0000,
29680x806e0004,
29690x41800000,
29700x00050849,
29710x2c050000,
29720x00098200,
29730x81110000,
29740x00098200,
29750x00000000,
29760x40820000,
29770x00050849,
29780x80a30000,
29790x00098200,
29800x38630000,
29810x00098200,
29820x80910000,
29830x00098200,
29840x39200000,
29850x7c082840,
29860x38c5ffff,
29870x41800000,
29880x00050849,
29890x0006000b,
29900x2c060000,
29910x7d0348ae,
29920x41a00000,
29930x0005087c,
29940x7d0431ae,
29950x38c6ffff,
29960x39290001,
29970x48000000,
29980x0005000b,
29990x00060080,
30000x80110000,
30010x00098200,
30020x81110000,
30030x00098200,
30040x7c004040,
30050x40800001,
30060x00050853,
30070x280b0008,
30080x80ae0000,
30090x806e0004,
30100x41800000,
30110x00050849,
30120x2c050000,
30130x00098200,
30140x81110000,
30150x00098200,
30160x40820000,
30170x00050849,
30180x80a30000,
30190x00098200,
30200x38630000,
30210x00098200,
30220x80910000,
30230x00098200,
30240x7c082840,
30250x39200000,
30260x41800000,
30270x00050849,
30280x0006000b,
30290x7c092840,
30300x7d0348ae,
30310x40a00000,
30320x0005087c,
30330x00000000,
30340x3808ffbf,
30350x69060020,
30360x3000ffe6,
30370x7cc63110,
30380x70c60020,
30390x7d083278,
30400x7d0449ae,
30410x39290001,
30420x48000000,
30430x0005000b,
30440x00060081,
30450x80110000,
30460x00098200,
30470x81110000,
30480x00098200,
30490x7c004040,
30500x40800001,
30510x00050853,
30520x280b0008,
30530x80ae0000,
30540x806e0004,
30550x41800000,
30560x00050849,
30570x2c050000,
30580x00098200,
30590x81110000,
30600x00098200,
30610x40820000,
30620x00050849,
30630x80a30000,
30640x00098200,
30650x38630000,
30660x00098200,
30670x80910000,
30680x00098200,
30690x7c082840,
30700x39200000,
30710x41800000,
30720x00050849,
30730x0006000b,
30740x7c092840,
30750x7d0348ae,
30760x40a00000,
30770x0005087c,
30780x3808ff9f,
30790x69060020,
30800x3000ffe6,
30810x7cc63110,
30820x70c60020,
30830x7d083278,
30840x7d0449ae,
30850x39290001,
30860x48000000,
30870x0005000b,
30880x00060082,
30890x280b0008,
30900x80ae0000,
30910x806e0004,
30920x41800000,
30930x00050849,
30940x2c050000,
30950x00098200,
30960x40820000,
30970x00050849,
30980x48000001,
30990x00030026,
31000x48000000,
31010x0005005e,
31020x00000000,
31030x00060083,
31040x280b0008,
31050x80ae0000,
31060x806e0004,
31070x41800000,
31080x00050849,
31090x7c05b040,
31100x40820001,
31110x00050884,
31120x00000000,
31130x00060083,
31140x280b0008,
31150x80ae0000,
31160xc82e0000,
31170x41800000,
31180x00050849,
31190x7c05b040,
31200x40800000,
31210x00050849,
31220xfc21f02a,
31230xd8210010,
31240x80610014,
31250x00000000,
31260x390e0008,
31270x7d2e5a14,
31280x0006000b,
31290x80c80000,
31300x7c884840,
31310x00000000,
31320x80880004,
31330x00000000,
31340xc8280000,
31350x00000000,
31360x40a40000,
31370x0005085e,
31380x7c06b040,
31390x00000000,
31400x40820001,
31410x00050885,
31420x00000000,
31430xfc21f02a,
31440x40800000,
31450x00050849,
31460xd8210010,
31470x80810014,
31480x00000000,
31490x7c632038,
31500x39080008,
31510x48000000,
31520x0005000b,
31530x00000000,
31540x00060086,
31550x280b0008,
31560x80ae0000,
31570x806e0004,
31580x41800000,
31590x00050849,
31600x7c05b040,
31610x40820001,
31620x00050884,
31630x00000000,
31640x00060086,
31650x280b0008,
31660x80ae0000,
31670xc82e0000,
31680x41800000,
31690x00050849,
31700x7c05b040,
31710x40800000,
31720x00050849,
31730xfc21f02a,
31740xd8210010,
31750x80610014,
31760x00000000,
31770x390e0008,
31780x7d2e5a14,
31790x0006000b,
31800x80c80000,
31810x7c884840,
31820x00000000,
31830x80880004,
31840x00000000,
31850xc8280000,
31860x00000000,
31870x40a40000,
31880x0005085e,
31890x7c06b040,
31900x00000000,
31910x40820001,
31920x00050885,
31930x00000000,
31940xfc21f02a,
31950x40800000,
31960x00050849,
31970xd8210010,
31980x80810014,
31990x00000000,
32000x7c632378,
32010x39080008,
32020x48000000,
32030x0005000b,
32040x00000000,
32050x00060087,
32060x280b0008,
32070x80ae0000,
32080x806e0004,
32090x41800000,
32100x00050849,
32110x7c05b040,
32120x40820001,
32130x00050884,
32140x00000000,
32150x00060087,
32160x280b0008,
32170x80ae0000,
32180xc82e0000,
32190x41800000,
32200x00050849,
32210x7c05b040,
32220x40800000,
32230x00050849,
32240xfc21f02a,
32250xd8210010,
32260x80610014,
32270x00000000,
32280x390e0008,
32290x7d2e5a14,
32300x0006000b,
32310x80c80000,
32320x7c884840,
32330x00000000,
32340x80880004,
32350x00000000,
32360xc8280000,
32370x00000000,
32380x40a40000,
32390x0005085e,
32400x7c06b040,
32410x00000000,
32420x40820001,
32430x00050885,
32440x00000000,
32450xfc21f02a,
32460x40800000,
32470x00050849,
32480xd8210010,
32490x80810014,
32500x00000000,
32510x7c632278,
32520x39080008,
32530x48000000,
32540x0005000b,
32550x00000000,
32560x00060088,
32570x280b0008,
32580x80ae0000,
32590x806e0004,
32600x41800000,
32610x00050849,
32620x7c05b040,
32630x40820001,
32640x00050884,
32650x00000000,
32660x00060088,
32670x280b0008,
32680x80ae0000,
32690xc82e0000,
32700x41800000,
32710x00050849,
32720x7c05b040,
32730x40800000,
32740x00050849,
32750xfc21f02a,
32760xd8210010,
32770x80610014,
32780x00000000,
32790x5460403e,
32800x5060c00e,
32810x5060c42e,
32820x7c030378,
32830x48000000,
32840x0005005e,
32850x00000000,
32860x00060089,
32870x280b0008,
32880x80ae0000,
32890x806e0004,
32900x41800000,
32910x00050849,
32920x7c05b040,
32930x40820001,
32940x00050884,
32950x00000000,
32960x00060089,
32970x280b0008,
32980x80ae0000,
32990xc82e0000,
33000x41800000,
33010x00050849,
33020x7c05b040,
33030x40800000,
33040x00050849,
33050xfc21f02a,
33060xd8210010,
33070x80610014,
33080x00000000,
33090x7c6318f8,
33100x48000000,
33110x0005005e,
33120x00000000,
33130x0006008a,
33140x280b0010,
33150x80ae0000,
33160x80ce0008,
33170x806e0004,
33180x808e000c,
33190x41800000,
33200x00050849,
33210x7c05b040,
33220x40820001,
33230x00050884,
33240x7c06b040,
33250x40820000,
33260x00050849,
33270x00000000,
33280x0006008a,
33290x280b0010,
33300x80ae0000,
33310xc82e0000,
33320x80ce0008,
33330xc84e0008,
33340x41800000,
33350x00050849,
33360x7c05b040,
33370x40800000,
33380x00050849,
33390x7c06b040,
33400x40800000,
33410x00050849,
33420xfc21f02a,
33430xfc42f02a,
33440xd8210010,
33450x80610014,
33460xd8410010,
33470x80810014,
33480x00000000,
33490x548406fe,
33500x7c632030,
33510x48000000,
33520x0005005e,
33530x00000000,
33540x0006008b,
33550x280b0010,
33560x80ae0000,
33570x80ce0008,
33580x806e0004,
33590x808e000c,
33600x41800000,
33610x00050849,
33620x7c05b040,
33630x40820001,
33640x00050884,
33650x7c06b040,
33660x40820000,
33670x00050849,
33680x00000000,
33690x0006008b,
33700x280b0010,
33710x80ae0000,
33720xc82e0000,
33730x80ce0008,
33740xc84e0008,
33750x41800000,
33760x00050849,
33770x7c05b040,
33780x40800000,
33790x00050849,
33800x7c06b040,
33810x40800000,
33820x00050849,
33830xfc21f02a,
33840xfc42f02a,
33850xd8210010,
33860x80610014,
33870xd8410010,
33880x80810014,
33890x00000000,
33900x548406fe,
33910x7c632430,
33920x48000000,
33930x0005005e,
33940x00000000,
33950x0006008c,
33960x280b0010,
33970x80ae0000,
33980x80ce0008,
33990x806e0004,
34000x808e000c,
34010x41800000,
34020x00050849,
34030x7c05b040,
34040x40820001,
34050x00050884,
34060x7c06b040,
34070x40820000,
34080x00050849,
34090x00000000,
34100x0006008c,
34110x280b0010,
34120x80ae0000,
34130xc82e0000,
34140x80ce0008,
34150xc84e0008,
34160x41800000,
34170x00050849,
34180x7c05b040,
34190x40800000,
34200x00050849,
34210x7c06b040,
34220x40800000,
34230x00050849,
34240xfc21f02a,
34250xfc42f02a,
34260xd8210010,
34270x80610014,
34280xd8410010,
34290x80810014,
34300x00000000,
34310x548406fe,
34320x7c632630,
34330x48000000,
34340x0005005e,
34350x00000000,
34360x0006008d,
34370x280b0010,
34380x80ae0000,
34390x80ce0008,
34400x806e0004,
34410x808e000c,
34420x41800000,
34430x00050849,
34440x7c05b040,
34450x40820001,
34460x00050884,
34470x7c06b040,
34480x40820000,
34490x00050849,
34500x00000000,
34510x0006008d,
34520x280b0010,
34530x80ae0000,
34540xc82e0000,
34550x80ce0008,
34560xc84e0008,
34570x41800000,
34580x00050849,
34590x7c05b040,
34600x40800000,
34610x00050849,
34620x7c06b040,
34630x40800000,
34640x00050849,
34650xfc21f02a,
34660xfc42f02a,
34670xd8210010,
34680x80610014,
34690xd8410010,
34700x80810014,
34710x00000000,
34720x5c63203e,
34730x48000000,
34740x0005005e,
34750x00000000,
34760x0006008e,
34770x280b0010,
34780x80ae0000,
34790x80ce0008,
34800x806e0004,
34810x808e000c,
34820x41800000,
34830x00050849,
34840x7c05b040,
34850x40820001,
34860x00050884,
34870x7c06b040,
34880x40820000,
34890x00050849,
34900x00000000,
34910x0006008e,
34920x280b0010,
34930x80ae0000,
34940xc82e0000,
34950x80ce0008,
34960xc84e0008,
34970x41800000,
34980x00050849,
34990x7c05b040,
35000x40800000,
35010x00050849,
35020x7c06b040,
35030x40800000,
35040x00050849,
35050xfc21f02a,
35060xfc42f02a,
35070xd8210010,
35080x80610014,
35090xd8410010,
35100x80810014,
35110x00000000,
35120x7c8400d0,
35130x5c63203e,
35140x48000000,
35150x0005005e,
35160x00000000,
35170x0006008f,
35180x280b0008,
35190x80ae0000,
35200x806e0004,
35210x41800000,
35220x00050849,
35230x7c05b040,
35240x40820001,
35250x00050884,
35260x00000000,
35270x0006008f,
35280x280b0008,
35290x80ae0000,
35300xc82e0000,
35310x41800000,
35320x00050849,
35330x7c05b040,
35340x40800000,
35350x00050849,
35360xfc21f02a,
35370xd8210010,
35380x80610014,
35390x00000000,
35400x48000000,
35410x0005005e,
35420x00000000,
35430x0006005e,
35440x6c638000,
35450x9061000c,
35460xc8210008,
35470xfc21f828,
35480x00000000,
35490x0006004c,
35500x820efff8,
35510x3a8efff8,
35520xd82efff8,
35530x48000000,
35540x0005005f,
35550x00060084,
35560x00000000,
35570xc82e0000,
35580x41810000,
35590x00050849,
35600xfc21f02a,
35610xd8210010,
35620x80610014,
35630x4e800020,
35640x00000000,
35650x00060085,
35660x00000000,
35670xc8280000,
35680x41810000,
35690x00050849,
35700xfc21f02a,
35710xd8210010,
35720x80810014,
35730x4e800020,
35740x00000000,
35750x00060049,
35760x80ca0000,
35770x00098200,
35780x7d0e5a14,
35790x820efff8,
35800x38080000,
35810x00098200,
35820x81320000,
35830x00098200,
35840x92010020,
35850x7c004840,
35860x91d20000,
35870x00098200,
35880x91120000,
35890x00098200,
35900x7e439378,
35910x41810000,
35920x00050805,
35930x7cc903a6,
35940x4e800421,
35950x81d20000,
35960x00098200,
35970x2c030000,
35980x546c1800,
35990x000900a1,
36000x3a8efff8,
36010x41810000,
36020x0005084a,
36030x0006000b,
36040x80120000,
36050x00098200,
36060x814efffc,
36070x7d6e0050,
36080x40820000,
36090x00050829,
36100x820a0000,
36110x00098200,
36120x80f00000,
36130x3a100004,
36140x54e815ba,
36150x54f4dd78,
36160x7c11402e,
36170x7e947214,
36180x7c0903a6,
36190x4e800420,
36200x00060029,
36210x72000000,
36220x00090200,
36230x56080038,
36240x40820000,
36250x00050803,
36260x80f0fffc,
36270x54e8dd78,
36280x0006000d,
36290x7d287050,
36300x48000000,
36310x00050024,
36320x0006000f,
36330x38800000,
36340x00098200,
36350x48000001,
36360x00030000,
36370x00000000,
36380x81d20000,
36390x00098200,
36400x7c000000,
36410x48000000,
36420x0005000b,
36430x00060053,
36440x7ea802a6,
36450x91d20000,
36460x00098200,
36470x7c0e5a14,
36480x92010020,
36490x90120000,
36500x00098200,
36510x7e439378,
36520x48000001,
36530x00030027,
36540x81d20000,
36550x00098200,
36560x7ea803a6,
36570x80120000,
36580x00098200,
36590x7d6e0050,
36600x814efffc,
36610x4e800020,
36620x00060090,
36630x00000000,
36640x88d10000,
36650x00098200,
36660x70c00000,
36670x00090200,
36680x40820000,
36690x00050805,
36700x81310000,
36710x00098200,
36720x70c00000,
36730x00090200,
36740x40820000,
36750x00050801,
36760x3929ffff,
36770x70c00000,
36780x00090200,
36790x41a20000,
36800x00050801,
36810x91310000,
36820x00098200,
36830x48000000,
36840x00050001,
36850x00000000,
36860x00060091,
36870x88d10000,
36880x00098200,
36890x70c00000,
36900x00090200,
36910x41820000,
36920x00050801,
36930x0006000f,
36940x39080000,
36950x00098200,
36960x7c11402e,
36970x7c0903a6,
36980x4e800420,
36990x00060092,
37000x88d10000,
37010x00098200,
37020x81310000,
37030x00098200,
37040x70c00000,
37050x00090200,
37060x54c007c0,
37070x000900ab,
37080x40820000,
37090x0005080f,
37100x2c800000,
37110x3529ffff,
37120x41860000,
37130x0005080f,
37140x91310000,
37150x00098200,
37160x41820000,
37170x00050801,
37180x40840000,
37190x0005080f,
37200x0006000b,
37210x7e439378,
37220x9261001c,
37230x7e048378,
37240x91d20000,
37250x00098200,
37260x48000001,
37270x00030028,
37280x0006000d,
37290x81d20000,
37300x00098200,
37310x0006000e,
37320x00000000,
37330x80f0fffc,
37340x54e815ba,
37350x54ea5d78,
37360x39080000,
37370x00098200,
37380x54ec9b78,
37390x7c11402e,
37400x54f4dd78,
37410x54eb9d78,
37420x7c0903a6,
37430x4e800420,
37440x00060093,
37450x3a100004,
37460x826affec,
37470x48000000,
37480x0005000e,
37490x00060094,
37500x00000000,
37510x810efffc,
37520x38710000,
37530x00098200,
37540x92010020,
37550x81080000,
37560x00098200,
37570x7e048378,
37580x92510000,
37590x00098200,
37600x89080000,
37610x00098200,
37620x91d20000,
37630x00098200,
37640x55081800,
37650x000900a1,
37660x7d0e4214,
37670x91120000,
37680x00098200,
37690x48000001,
37700x00030029,
37710x48000000,
37720x0005000d,
37730x00000000,
37740x00060095,
37750x7e048378,
37760x00000000,
37770x48000000,
37780x00050001,
37790x00000000,
37800x00060096,
37810x00000000,
37820x62040001,
37830x0006000b,
37840x00000000,
37850x7c0e5a14,
37860x92010020,
37870x7e439378,
37880x91d20000,
37890x00098200,
37900x7e8ea050,
37910x90120000,
37920x00098200,
37930x48000001,
37940x0003002a,
37950x81d20000,
37960x00098200,
37970x80120000,
37980x00098200,
37990x93010020,
38000x7d6e0050,
38010x7e8ea214,
38020x814efffc,
38030x80f0fffc,
38040x7c6903a6,
38050x4e800420,
38060x00060097,
38070x00000000,
38080x38210000,
38090x00098200,
38100xbc410000,
38110x00098200,
38120x3a3f0000,
38130x00098200,
38140x38800000,
38150x00098200,
38160x80610000,
38170x00098200,
38180x90910000,
38190x00098200,
38200xd8010000,
38210x00098200,
38220xd8210000,
38230x00098200,
38240xd8410000,
38250x00098200,
38260xd8610000,
38270x00098200,
38280x90610000,
38290x7c000400,
38300xd8810000,
38310x00098200,
38320xd8a10000,
38330x00098200,
38340xd8c10000,
38350x00098200,
38360xd8e10000,
38370x00098200,
38380x38810000,
38390x00098200,
38400xd9010000,
38410x00098200,
38420xd9210000,
38430x00098200,
38440xd9410000,
38450x00098200,
38460xd9610000,
38470x00098200,
38480x90810000,
38490x00098200,
38500xd9810000,
38510x00098200,
38520xd9a10000,
38530x00098200,
38540x00000000,
38550xd9c10000,
38560x00098200,
38570xd9e10000,
38580x00098200,
38590x7ca802a6,
38600x39000000,
38610xda010000,
38620x00098200,
38630xda210000,
38640x00098200,
38650xda410000,
38660x00098200,
38670xda610000,
38680x00098200,
38690x91010000,
38700x00098200,
38710xda810000,
38720x00098200,
38730xdaa10000,
38740x00098200,
38750xdac10000,
38760x00098200,
38770xdae10000,
38780x00098200,
38790xa0c50002,
38800xdb010000,
38810x00098200,
38820xdb210000,
38830x00098200,
38840xdb410000,
38850x00098200,
38860xdb610000,
38870x00098200,
38880x82510000,
38890x00098200,
38900xdb810000,
38910x00098200,
38920xdba10000,
38930x00098200,
38940xdbc10000,
38950x00098200,
38960xdbe10000,
38970x00098200,
38980x7ca50050,
38990x81d10000,
39000x00098200,
39010x54a500be,
39020x000900ab,
39030x00000000,
39040x92510000,
39050x00098200,
39060x38a5fffe,
39070x91110000,
39080x00098200,
39090x90d10000,
39100x00098200,
39110x91d20000,
39120x00098200,
39130x38710000,
39140x00098200,
39150x90b10000,
39160x00098200,
39170x38810010,
39180x48000001,
39190x0003002b,
39200x81120000,
39210x00098200,
39220x81210000,
39230x81d20000,
39240x00098200,
39250x5501003a,
39260x82010020,
39270x91210000,
39280x92410024,
39290x48000000,
39300x00050001,
39310x00000000,
39320x00060098,
39330x00000000,
39340x82410024,
39350x3a3f0000,
39360x00098200,
39370x0006000b,
39380x2c030000,
39390x41800000,
39400x00050803,
39410x810efffc,
39420x54731800,
39430x000900a1,
39440x39200000,
39450x9261001c,
39460x81080000,
39470x00098200,
39480x91310000,
39490x00098200,
39500x81e80000,
39510x00098200,
39520x3ac00000,
39530x00098200,
39540x3cc059c0,
39550x90c10010,
39560x3b000000,
39570x60c60004,
39580xc3c10010,
39590x90c10010,
39600x3c004338,
39610x3ae00000,
39620x00098200,
39630x90010008,
39640xc3e10010,
39650x80f00000,
39660x3a100004,
39670x92f10000,
39680x00098200,
39690x54e815ba,
39700x54f4dd78,
39710x7c11402e,
39720x7c0903a6,
39730x28080000,
39740x00090200,
39750x40800000,
39760x00050802,
39770x54ea5d78,
39780x54ec9b78,
39790x54eb9d78,
39800x4e800420,
39810x0006000c,
39820x3973fff8,
39830x7e947214,
39840x4e800420,
39850x0006000d,
39860x7c8300d0,
39870x7e439378,
39880x48000001,
39890x0003002c,
39900x00000000,
39910x00060099,
39920x48000000,
39930x00030010,
39940x0006009a,
39950x48000000,
39960x00030011,
39970x0006009b,
39980x00000000,
39990x48000000,
40000x0003002d,
40010x00000000,
40020x0006009c,
40030x7c0327d7,
40040x41830000,
40050x00050801,
40060x7c652279,
40070x7c0021d6,
40080x7c601850,
40090x4c800020,
40100x2c030000,
40110x4d820020,
40120x7c632214,
40130x4e800020,
40140x0006000b,
40150x2c040000,
40160x38600000,
40170x4d820020,
40180x7c000400,
40190x4e800020,
40200x0006009d,
40210x28030001,
40220x41820000,
40230x00050801,
40240x41810000,
40250x00050802,
40260xfc21102a,
40270x4e800020,
40280x0006000b,
40290xfc211028,
40300x4e800020,
40310x0006000c,
40320x28030003,
40330x41820000,
40340x00050801,
40350x41810000,
40360x00050802,
40370xfc2100b2,
40380x4e800020,
40390x0006000b,
40400xfc211024,
40410x4e800020,
40420x0006000c,
40430x28030005,
40440x41820000,
40450x00050801,
40460x41810000,
40470x00050802,
40480x9421ffe0,
40490xd9c10010,
40500xd9e10018,
40510x7c0802a6,
40520xfdc00890,
40530xfc211024,
40540x90010024,
40550xfde01090,
40560x48000001,
40570x00030010,
40580x80010024,
40590xfc2103f2,
40600x7c0803a6,
40610xfc2e0828,
40620xc9c10010,
40630xc9e10018,
40640x38210020,
40650x4e800020,
40660x0006000b,
40670x48000000,
40680x0003001f,
40690x0006000c,
40700x28030007,
40710x41820000,
40720x00050801,
40730x41810000,
40740x00050802,
40750xfc200850,
40760x4e800020,
40770x0006000b,
40780xfc200a10,
40790x4e800020,
40800x0006000c,
40810x00000000,
40820x28030009,
40830x41820000,
40840x00050809,
40850x41810000,
40860x00050802,
40870x48000000,
40880x00030020,
40890x0006000c,
40900x2803000b,
40910x41810000,
40920x00050809,
40930xfc011028,
40940x41820000,
40950x00050801,
40960xfc2008ae,
40970x4e800020,
40980x0006000b,
40990xfc20106e,
41000x4e800020,
41010x00060013,
41020x7c810808,
41030x00000000,
41040x7c810808,
41050x00000000,
41060x0006009e,
41070x00000000,
41080x9421fef0,
41090x91c10000,
41100x00098200,
41110xd9c10000,
41120x00098200,
41130x91e10000,
41140x00098200,
41150xd9e10000,
41160x00098200,
41170x92010000,
41180x00098200,
41190xda010000,
41200x00098200,
41210x7c0802a6,
41220x92210000,
41230x00098200,
41240xda210000,
41250x00098200,
41260x92410000,
41270x00098200,
41280xda410000,
41290x00098200,
41300x92610000,
41310x00098200,
41320xda610000,
41330x00098200,
41340x92810000,
41350x00098200,
41360xda810000,
41370x00098200,
41380x92a10000,
41390x00098200,
41400xdaa10000,
41410x00098200,
41420x92c10000,
41430x00098200,
41440xdac10000,
41450x00098200,
41460x90010114,
41470x92e10000,
41480x00098200,
41490xdae10000,
41500x00098200,
41510x93010000,
41520x00098200,
41530xdb010000,
41540x00098200,
41550x00000000,
41560x93210000,
41570x00098200,
41580xdb210000,
41590x00098200,
41600x7c000026,
41610x93410000,
41620x00098200,
41630xdb410000,
41640x00098200,
41650x93610000,
41660x00098200,
41670xdb610000,
41680x00098200,
41690x93810000,
41700x00098200,
41710xdb810000,
41720x00098200,
41730x93a10000,
41740x00098200,
41750xdba10000,
41760x00098200,
41770x93c10000,
41780x00098200,
41790xdbc10000,
41800x00098200,
41810x93e10000,
41820x00098200,
41830xdbe10000,
41840x00098200,
41850x90010034,
41860x820c0000,
41870x00098200,
41880x3a2c0000,
41890x00098200,
41900x91700000,
41910x00098200,
41920x90700000,
41930x00098200,
41940xd8300000,
41950x00098200,
41960x90900000,
41970x00098200,
41980xd8500000,
41990x00098200,
42000x90b00000,
42010x00098200,
42020x00000000,
42030xd8700000,
42040x00098200,
42050x90d00000,
42060x00098200,
42070xd8900000,
42080x00098200,
42090x90f00000,
42100x00098200,
42110xd8b00000,
42120x00098200,
42130x91100000,
42140x00098200,
42150xd8d00000,
42160x00098200,
42170x91300000,
42180x00098200,
42190xd8f00000,
42200x00098200,
42210x91500000,
42220x00098200,
42230xd9100000,
42240x00098200,
42250x38010000,
42260x00098200,
42270x90100000,
42280x00098200,
42290x7e038378,
42300x92010020,
42310x7c240b78,
42320x48000001,
42330x0003002e,
42340x81c30000,
42350x00098200,
42360x3ac00000,
42370x00098200,
42380x81630000,
42390x00098200,
42400x3cc059c0,
42410x3b000000,
42420x7c721b78,
42430x90c10010,
42440x814efffc,
42450x60c60004,
42460x3ae00000,
42470x00098200,
42480x38000000,
42490x00098200,
42500xc3c10010,
42510x90c10010,
42520x7d6e5850,
42530x90110000,
42540x00098200,
42550xc3e10010,
42560x820a0000,
42570x00098200,
42580x80f00000,
42590x3a100004,
42600x54e815ba,
42610x54f4dd78,
42620x7c11402e,
42630x7e947214,
42640x7c0903a6,
42650x4e800420,
42660x00000000,
42670x00060028,
42680x00000000,
42690x82110000,
42700x00098200,
42710x91d20000,
42720x00098200,
42730x91520000,
42740x00098200,
42750x92500000,
42760x00098200,
42770x7e038378,
42780x7e84a378,
42790x48000001,
42800x0003002f,
42810x80700000,
42820x00098200,
42830xc8300000,
42840x00098200,
42850x80900000,
42860x00098200,
42870x48000000,
42880x0005001a,
42890x00000000,
42900x0006009f,
42910x00000000,
42920x81030000,
42930x00098200,
42940x7c0802a6,
42950x88830000,
42960x00098200,
42970x88a30000,
42980x00098200,
42990x7d0800d0,
43000x90010004,
43010x2c850000,
43020x7c290b78,
43030x3484ffff,
43040x7c21416e,
43050x4cc63042,
43060x91c9fffc,
43070x38c00000,
43080x9069fff8,
43090x7d2e4b78,
43100x39030000,
43110x00098200,
43120x54841000,
43130x000900a1,
43140x41a00000,
43150x00050802,
43160x39210008,
43170x0006000b,
43180x7c08202e,
43190x7c09212e,
43200x3484fffc,
43210x40800000,
43220x0005080b,
43230x0006000c,
43240x40a60000,
43250x00050803,
43260xc8230000,
43270x00098200,
43280xc8430000,
43290x00098200,
43300xc8630000,
43310x00098200,
43320xc8830000,
43330x00098200,
43340xc8a30000,
43350x00098200,
43360xc8c30000,
43370x00098200,
43380xc8e30000,
43390x00098200,
43400xc9030000,
43410x00098200,
43420x0006000d,
43430x80030000,
43440x00098200,
43450x80830000,
43460x00098200,
43470x80a30000,
43480x00098200,
43490x00000000,
43500x80c30000,
43510x00098200,
43520x80e30000,
43530x00098200,
43540x7c0903a6,
43550x81030000,
43560x00098200,
43570x81230000,
43580x00098200,
43590x81430000,
43600x00098200,
43610x80630000,
43620x00098200,
43630x4e800421,
43640x810efff8,
43650x812efffc,
43660x800e0004,
43670x90680000,
43680x00098200,
43690xd8280000,
43700x00098200,
43710x90880000,
43720x00098200,
43730x7c0803a6,
43740x90a80000,
43750x00098200,
43760x7dc17378,
43770x90c80000,
43780x00098200,
43790x7d2e4b78,
43800x4e800020,
43810x00000000,
43820x00080000,
43830x00000000,
43840x7c14706e,
43850x3a100004,
43860x80940004,
43870x7d0c706e,
43880x8130fffc,
43890x7c00b040,
43900x80ac0004,
43910x552993ba,
43920x7c88b040,
43930x3d290000,
43940x00098200,
43950x40820000,
43960x00050807,
43970x40860000,
43980x00050808,
43990x7c042800,
44000x00000000,
44010x40800000,
44020x00050802,
44030x00000000,
44040x41800000,
44050x00050802,
44060x00000000,
44070x41810000,
44080x00050802,
44090x00000000,
44100x40810000,
44110x00050802,
44120x00000000,
44130x0006000b,
44140x7e104a14,
44150x0006000c,
44160x80f00000,
44170x3a100004,
44180x54e815ba,
44190x7c11402e,
44200x7c0903a6,
44210x54ea5d78,
44220x54ec9b78,
44230x54f4dd78,
44240x54eb9d78,
44250x4e800420,
44260x00060011,
44270x41810000,
44280x00050835,
44290xc8140000,
44300x41850000,
44310x00050835,
44320x41840000,
44330x00050804,
44340x6ca58000,
44350x90a1000c,
44360xc8210008,
44370xfc21f828,
44380x48000000,
44390x00050005,
44400x00060012,
44410x41850000,
44420x00050835,
44430x6c848000,
44440x9081000c,
44450xc8010008,
44460xfc00f828,
44470x0006000e,
44480xc82c0000,
44490x0006000f,
44500xfc000800,
44510x00000000,
44520x40800000,
44530x0005080c,
44540x00000000,
44550x41800000,
44560x0005080c,
44570x00000000,
44580x4c001382,
44590x40800000,
44600x0005080c,
44610x00000000,
44620x4c001382,
44630x41800000,
44640x0005080c,
44650x00000000,
44660x48000000,
44670x0005000b,
44680x00000000,
44690x7c0ea02e,
44700x3a100004,
44710x7c0ea4ae,
44720x7d0e602e,
44730x7c00b040,
44740x8130fffc,
44750x7c2e64ae,
44760x7c88b040,
44770x552993ba,
44780x40800000,
44790x00050835,
44800x3d290000,
44810x00098200,
44820x40840000,
44830x00050835,
44840xfc000800,
44850x00000000,
44860x40800000,
44870x00050801,
44880x00000000,
44890x41800000,
44900x00050801,
44910x00000000,
44920x4c001382,
44930x40800000,
44940x00050801,
44950x00000000,
44960x4c001382,
44970x41800000,
44980x00050801,
44990x00000000,
45000x7e104a14,
45010x0006000b,
45020x80f00000,
45030x3a100004,
45040x54e815ba,
45050x7c11402e,
45060x7c0903a6,
45070x54ea5d78,
45080x54ec9b78,
45090x54f4dd78,
45100x54eb9d78,
45110x4e800420,
45120x00000000,
45130x7c14706e,
45140x3a100004,
45150x80940004,
45160x7d0c706e,
45170x7c00b040,
45180x8130fffc,
45190x7c88b040,
45200x552993ba,
45210x80ac0004,
45220x4fa12b82,
45230x3d290000,
45240x00098200,
45250x00000000,
45260x409d0000,
45270x000508a0,
45280x00000000,
45290x409d0000,
45300x000508a1,
45310x00000000,
45320x7c14706e,
45330x81300000,
45340xc8140000,
45350x3a100004,
45360x7d0c706e,
45370x7c00b040,
45380x552993ba,
45390xc82c0000,
45400x7c88b040,
45410x3d290000,
45420x00098200,
45430x40800000,
45440x00050805,
45450x40840000,
45460x00050805,
45470xfc000800,
45480x00000000,
45490x40820000,
45500x00050801,
45510x7e104a14,
45520x00000000,
45530x41820000,
45540x00050801,
45550x7e104a14,
45560x00000000,
45570x0006000b,
45580x80f00000,
45590x3a100004,
45600x54e815ba,
45610x7c11402e,
45620x7c0903a6,
45630x54ea5d78,
45640x54ec9b78,
45650x54f4dd78,
45660x54eb9d78,
45670x4e800420,
45680x00000000,
45690x0006000f,
45700x00000000,
45710x80940004,
45720x80ac0004,
45730x00000000,
45740x2f800000,
45750x00098200,
45760x2e880000,
45770x00098200,
45780x00000000,
45790x7c0600f8,
45800x7c004040,
45810x28860000,
45820x00090200,
45830x00000000,
45840x4fdeb382,
45850x00000000,
45860x2b060000,
45870x00090200,
45880x00000000,
45890x419e0000,
45900x0005083b,
45910x00000000,
45920x7e842840,
45930x4c222902,
45940x4c161342,
45950x4c42b202,
45960x7e158378,
45970x4c420b82,
45980x4c000b82,
45990x00000000,
46000x40820000,
46010x00050806,
46020x7e104a14,
46030x00060010,
46040x00000000,
46050x41820000,
46060x00050806,
46070x7e104a14,
46080x00060010,
46090x00000000,
46100x40800000,
46110x00050802,
46120x0006000b,
46130x80f00000,
46140x3a100004,
46150x54e815ba,
46160x7c11402e,
46170x7c0903a6,
46180x54ea5d78,
46190x54ec9b78,
46200x54f4dd78,
46210x54eb9d78,
46220x4e800420,
46230x0006000c,
46240x00000000,
46250x41800000,
46260x0005080b,
46270x00000000,
46280x41980000,
46290x0005080b,
46300x81240000,
46310x00098200,
46320x38c00000,
46330x00098200,
46340x28090000,
46350x41820000,
46360x0005080b,
46370x89290000,
46380x00098200,
46390x71290000,
46400x00090200,
46410x40820000,
46420x0005080b,
46430x7eb0ab78,
46440x48000000,
46450x0005003a,
46460x00000000,
46470x7c14706e,
46480x558c007e,
46490x000900ab,
46500x80d40004,
46510x81300000,
46520x218cfffc,
46530x3a100004,
46540x00000000,
46550x2c000000,
46560x00098200,
46570x00000000,
46580x7d0f602e,
46590x20000000,
46600x00098200,
46610x00000000,
46620x41820000,
46630x0005083b,
46640x00000000,
46650x7d064050,
46660x7c004378,
46670x552993ba,
46680x20000000,
46690x3d290000,
46700x00098200,
46710x7d084110,
46720x00000000,
46730x7d294078,
46740x00000000,
46750x7d294038,
46760x00000000,
46770x7e104a14,
46780x80f00000,
46790x3a100004,
46800x54e815ba,
46810x7c11402e,
46820x7c0903a6,
46830x54ea5d78,
46840x54ec9b78,
46850x54f4dd78,
46860x54eb9d78,
46870x4e800420,
46880x00000000,
46890x7c14706e,
46900x3a100004,
46910x80940004,
46920x7d0c786e,
46930x7c00b040,
46940x8130fffc,
46950x7c88b040,
46960x552993ba,
46970x80ac0004,
46980x3d290000,
46990x00098200,
47000x00000000,
47010x000600a0,
47020x00000000,
47030x000600a1,
47040x00000000,
47050x40820000,
47060x00050807,
47070x40860000,
47080x00050808,
47090x7c042800,
47100x0006000e,
47110x00000000,
47120x000600a0,
47130x00000000,
47140x000600a1,
47150x00000000,
47160x7c0ea02e,
47170x3a100004,
47180x7c0ea4ae,
47190x8130fffc,
47200x7c2f64ae,
47210x552993ba,
47220x7c00b040,
47230x3d290000,
47240x00098200,
47250x40800000,
47260x00050803,
47270xfc000800,
47280x00000000,
47290x40820000,
47300x00050801,
47310x7e104a14,
47320x0006000b,
47330x00000000,
47340x0006000d,
47350x00000000,
47360x41820000,
47370x00050802,
47380x0006000b,
47390x00000000,
47400x0006000d,
47410x00000000,
47420x7e104a14,
47430x0006000c,
47440x00000000,
47450x80f00000,
47460x3a100004,
47470x54e815ba,
47480x7c11402e,
47490x7c0903a6,
47500x54ea5d78,
47510x54ec9b78,
47520x54f4dd78,
47530x54eb9d78,
47540x4e800420,
47550x00000000,
47560x0006000d,
47570x2c000000,
47580x00098200,
47590x41820000,
47600x0005083b,
47610x48000000,
47620x0005000b,
47630x00000000,
47640x00060011,
47650x40800000,
47660x0005080d,
47670xc8140000,
47680x41840000,
47690x00050801,
47700x6ca58000,
47710x90a1000c,
47720xc8210008,
47730xfc21f828,
47740x48000000,
47750x00050002,
47760x00060012,
47770x6c848000,
47780x9081000c,
47790xc8010008,
47800xfc00f828,
47810x0006000b,
47820xc82c0000,
47830x0006000c,
47840xfc000800,
47850x48000000,
47860x0005000e,
47870x00000000,
47880x7c0ea02e,
47890x558800fe,
47900x000900ab,
47910x81300000,
47920x7d0840f8,
47930x3a100004,
47940x00000000,
47950x2c000000,
47960x00098200,
47970x00000000,
47980x7c080050,
47990x00000000,
48000x41820000,
48010x0005083b,
48020x00000000,
48030x552993ba,
48040x3000ffff,
48050x3d290000,
48060x00098200,
48070x7d084110,
48080x00000000,
48090x7d294038,
48100x00000000,
48110x7d294078,
48120x00000000,
48130x7e104a14,
48140x80f00000,
48150x3a100004,
48160x54e815ba,
48170x7c11402e,
48180x7c0903a6,
48190x54ea5d78,
48200x54ec9b78,
48210x54f4dd78,
48220x54eb9d78,
48230x4e800420,
48240x00000000,
48250x7c0e602e,
48260x80f00000,
48270x3a100004,
48280x00000000,
48290x20000000,
48300x00098200,
48310x54e993ba,
48320x7d084110,
48330x3d290000,
48340x00098200,
48350x00000000,
48360x7d294078,
48370x00000000,
48380x7d294038,
48390x00000000,
48400x7e104a14,
48410x00000000,
48420x39000000,
48430x00098200,
48440x7c0e64ae,
48450x7c004040,
48460x00000000,
48470x40800000,
48480x00050801,
48490x00000000,
48500x41800000,
48510x00050801,
48520x00000000,
48530x3e100000,
48540x00098200,
48550x54e993ba,
48560x7c0ea5ae,
48570x7e104a14,
48580x0006000b,
48590x00000000,
48600x80f00000,
48610x3a100004,
48620x54e815ba,
48630x7c11402e,
48640x7c0903a6,
48650x54ea5d78,
48660x54ec9b78,
48670x54f4dd78,
48680x54eb9d78,
48690x4e800420,
48700x00000000,
48710x80f00000,
48720x3a100004,
48730x7c0e64ae,
48740x7c0ea5ae,
48750x54e815ba,
48760x7c11402e,
48770x7c0903a6,
48780x54ea5d78,
48790x54ec9b78,
48800x54f4dd78,
48810x54eb9d78,
48820x4e800420,
48830x00000000,
48840x80f00000,
48850x3a100004,
48860x7c0e602e,
48870x21000000,
48880x00098200,
48890x7c004114,
48900x7c0ea12e,
48910x54e815ba,
48920x7c11402e,
48930x7c0903a6,
48940x54ea5d78,
48950x54ec9b78,
48960x54f4dd78,
48970x54eb9d78,
48980x4e800420,
48990x00000000,
49000x7d0c706e,
49010x800c0004,
49020x7c08b040,
49030x00000000,
49040x40820000,
49050x00050805,
49060x7c0004d1,
49070x41830000,
49080x00050804,
49090x0006000b,
49100x80f00000,
49110x3a100004,
49120x7ed4716e,
49130x90140004,
49140x0006000d,
49150x54e815ba,
49160x7c11402e,
49170x7c0903a6,
49180x54ea5d78,
49190x54ec9b78,
49200x54f4dd78,
49210x54eb9d78,
49220x4e800420,
49230x0006000e,
49240x7c000400,
49250x40a10000,
49260x0005080b,
49270x3d0041e0,
49280x38000000,
49290x48000000,
49300x00050007,
49310x00000000,
49320x0006000f,
49330x40800000,
49340x0005083e,
49350x6d088000,
49360x00060011,
49370x80f00000,
49380x3a100004,
49390x7d14716e,
49400x90140004,
49410x00000000,
49420x48000000,
49430x0005000d,
49440x00000000,
49450x54e815ba,
49460x7c11402e,
49470x7c0903a6,
49480x54ea5d78,
49490x54ec9b78,
49500x54f4dd78,
49510x54eb9d78,
49520x4e800420,
49530x00000000,
49540x7c0c706e,
49550x806c0004,
49560x2c000000,
49570x00098200,
49580x40820000,
49590x00050802,
49600x80630000,
49610x00098200,
49620x0006000b,
49630x00000000,
49640x80f00000,
49650x3a100004,
49660x7ed4716e,
49670x90740004,
49680x00000000,
49690x9061000c,
49700xc8010008,
49710xfc00f028,
49720x80f00000,
49730x3a100004,
49740x7c0ea5ae,
49750x00000000,
49760x54e815ba,
49770x7c11402e,
49780x7c0903a6,
49790x54ea5d78,
49800x54ec9b78,
49810x54f4dd78,
49820x54eb9d78,
49830x4e800420,
49840x0006000c,
49850x2c000000,
49860x00098200,
49870x40820000,
49880x00050843,
49890x00000000,
49900x81230000,
49910x00098200,
49920x28090000,
49930x40820000,
49940x00050809,
49950x0006000d,
49960x00000000,
49970x00060044,
49980x48000001,
49990x00030026,
50000x48000000,
50010x0005000b,
50020x00000000,
50030x00060013,
50040x88090000,
50050x00098200,
50060x70000000,
50070x00090200,
50080x40820000,
50090x0005080d,
50100x48000000,
50110x00050043,
50120x00000000,
50130x7d0a706e,
50140x7d2b786e,
50150x806a0004,
50160x7c08b040,
50170x808b0004,
50180x00000000,
50190x7d0a706e,
50200x7d2b786e,
50210x808a0004,
50220x7c08b040,
50230x806b0004,
50240x00000000,
50250x7d0a706e,
50260x7d2b706e,
50270x806a0004,
50280x7c08b040,
50290x808b0004,
50300x00000000,
50310x7c89b040,
50320x40820000,
50330x00050805,
50340x40860000,
50350x00050805,
50360x7c632615,
50370x41830000,
50380x00050804,
50390x0006000b,
50400x80f00000,
50410x3a100004,
50420x7ed4716e,
50430x90740004,
50440x0006000c,
50450x54e815ba,
50460x7c11402e,
50470x7c0903a6,
50480x54ea5d78,
50490x54ec9b78,
50500x54f4dd78,
50510x54eb9d78,
50520x4e800420,
50530x0006000e,
50540x7c000400,
50550x40a10000,
50560x0005080b,
50570x00000000,
50580x48000000,
50590x00050041,
50600x00000000,
50610x48000000,
50620x0005003d,
50630x00000000,
50640x48000000,
50650x00050042,
50660x00000000,
50670x0006000f,
50680x00000000,
50690xc9ea0000,
50700x4c002202,
50710xc9cb0000,
50720x00000000,
50730xc9ca0000,
50740x4c002202,
50750xc9eb0000,
50760x00000000,
50770x40800000,
50780x00050841,
50790x00000000,
50800x40800000,
50810x0005083d,
50820x00000000,
50830x40800000,
50840x00050842,
50850x00000000,
50860xfc0e782a,
50870x80f00000,
50880x3a100004,
50890x7c0ea5ae,
50900x48000000,
50910x0005000c,
50920x00000000,
50930x7d0e502e,
50940x00000000,
50950x7d2f582e,
50960x00000000,
50970x7dce54ae,
50980x7def5cae,
50990x00000000,
51000x7c08b040,
51010x7c89b040,
51020x4c002202,
51030x40800000,
51040x0005083f,
51050x00000000,
51060x7c08b040,
51070x40800000,
51080x0005083f,
51090x00000000,
51100x7d0e502e,
51110x00000000,
51120x7d2f582e,
51130x00000000,
51140x7dee54ae,
51150x7dcf5cae,
51160x00000000,
51170x7c08b040,
51180x7c89b040,
51190x4c002202,
51200x40800000,
51210x0005083c,
51220x00000000,
51230x7c08b040,
51240x40800000,
51250x0005083c,
51260x00000000,
51270x7d0e502e,
51280x7d2e582e,
51290x7dce54ae,
51300x7dee5cae,
51310x7c08b040,
51320x7c89b040,
51330x4c002202,
51340x40800000,
51350x00050840,
51360x00000000,
51370xfc0e782a,
51380x80f00000,
51390x3a100004,
51400x7c0ea5ae,
51410x54e815ba,
51420x7c11402e,
51430x7c0903a6,
51440x54ea5d78,
51450x54ec9b78,
51460x54f4dd78,
51470x54eb9d78,
51480x4e800420,
51490x00000000,
51500x7d0a706e,
51510x7d2b786e,
51520x806a0004,
51530x7c08b040,
51540x808b0004,
51550x00000000,
51560x7d0a706e,
51570x7d2b786e,
51580x808a0004,
51590x7c08b040,
51600x806b0004,
51610x00000000,
51620x7d0a706e,
51630x7d2b706e,
51640x806a0004,
51650x7c08b040,
51660x808b0004,
51670x00000000,
51680x7c89b040,
51690x40820000,
51700x00050805,
51710x40860000,
51720x00050805,
51730x7c641c51,
51740x41830000,
51750x00050804,
51760x0006000b,
51770x80f00000,
51780x3a100004,
51790x7ed4716e,
51800x90740004,
51810x0006000c,
51820x54e815ba,
51830x7c11402e,
51840x7c0903a6,
51850x54ea5d78,
51860x54ec9b78,
51870x54f4dd78,
51880x54eb9d78,
51890x4e800420,
51900x0006000e,
51910x7c000400,
51920x40a10000,
51930x0005080b,
51940x00000000,
51950x48000000,
51960x00050041,
51970x00000000,
51980x48000000,
51990x0005003d,
52000x00000000,
52010x48000000,
52020x00050042,
52030x00000000,
52040x0006000f,
52050x00000000,
52060xc9ea0000,
52070x4c002202,
52080xc9cb0000,
52090x00000000,
52100xc9ca0000,
52110x4c002202,
52120xc9eb0000,
52130x00000000,
52140x40800000,
52150x00050841,
52160x00000000,
52170x40800000,
52180x0005083d,
52190x00000000,
52200x40800000,
52210x00050842,
52220x00000000,
52230xfc0e7828,
52240x80f00000,
52250x3a100004,
52260x7c0ea5ae,
52270x48000000,
52280x0005000c,
52290x00000000,
52300x7d0e502e,
52310x00000000,
52320x7d2f582e,
52330x00000000,
52340x7dce54ae,
52350x7def5cae,
52360x00000000,
52370x7c08b040,
52380x7c89b040,
52390x4c002202,
52400x40800000,
52410x0005083f,
52420x00000000,
52430x7c08b040,
52440x40800000,
52450x0005083f,
52460x00000000,
52470x7d0e502e,
52480x00000000,
52490x7d2f582e,
52500x00000000,
52510x7dee54ae,
52520x7dcf5cae,
52530x00000000,
52540x7c08b040,
52550x7c89b040,
52560x4c002202,
52570x40800000,
52580x0005083c,
52590x00000000,
52600x7c08b040,
52610x40800000,
52620x0005083c,
52630x00000000,
52640x7d0e502e,
52650x7d2e582e,
52660x7dce54ae,
52670x7dee5cae,
52680x7c08b040,
52690x7c89b040,
52700x4c002202,
52710x40800000,
52720x00050840,
52730x00000000,
52740xfc0e7828,
52750x80f00000,
52760x3a100004,
52770x7c0ea5ae,
52780x54e815ba,
52790x7c11402e,
52800x7c0903a6,
52810x54ea5d78,
52820x54ec9b78,
52830x54f4dd78,
52840x54eb9d78,
52850x4e800420,
52860x00000000,
52870x7d0a706e,
52880x7d2b786e,
52890x806a0004,
52900x7c08b040,
52910x808b0004,
52920x00000000,
52930x7d0a706e,
52940x7d2b786e,
52950x808a0004,
52960x7c08b040,
52970x806b0004,
52980x00000000,
52990x7d0a706e,
53000x7d2b706e,
53010x806a0004,
53020x7c08b040,
53030x808b0004,
53040x00000000,
53050x7c89b040,
53060x40820000,
53070x00050805,
53080x40860000,
53090x00050805,
53100x7c6325d7,
53110x41830000,
53120x00050804,
53130x0006000b,
53140x80f00000,
53150x3a100004,
53160x7ed4716e,
53170x90740004,
53180x0006000c,
53190x54e815ba,
53200x7c11402e,
53210x7c0903a6,
53220x54ea5d78,
53230x54ec9b78,
53240x54f4dd78,
53250x54eb9d78,
53260x4e800420,
53270x0006000e,
53280x7c000400,
53290x40a10000,
53300x0005080b,
53310x00000000,
53320x48000000,
53330x00050041,
53340x00000000,
53350x48000000,
53360x0005003d,
53370x00000000,
53380x48000000,
53390x00050042,
53400x00000000,
53410x0006000f,
53420x00000000,
53430xc9ea0000,
53440x4c002202,
53450xc9cb0000,
53460x00000000,
53470xc9ca0000,
53480x4c002202,
53490xc9eb0000,
53500x00000000,
53510x40800000,
53520x00050841,
53530x00000000,
53540x40800000,
53550x0005083d,
53560x00000000,
53570x40800000,
53580x00050842,
53590x00000000,
53600xfc0e03f2,
53610x80f00000,
53620x3a100004,
53630x7c0ea5ae,
53640x48000000,
53650x0005000c,
53660x00000000,
53670x7d0e502e,
53680x00000000,
53690x7d2f582e,
53700x00000000,
53710x7dce54ae,
53720x7def5cae,
53730x00000000,
53740x7c08b040,
53750x7c89b040,
53760x4c002202,
53770x40800000,
53780x0005083f,
53790x00000000,
53800x7c08b040,
53810x40800000,
53820x0005083f,
53830x00000000,
53840x7d0e502e,
53850x00000000,
53860x7d2f582e,
53870x00000000,
53880x7dee54ae,
53890x7dcf5cae,
53900x00000000,
53910x7c08b040,
53920x7c89b040,
53930x4c002202,
53940x40800000,
53950x0005083c,
53960x00000000,
53970x7c08b040,
53980x40800000,
53990x0005083c,
54000x00000000,
54010x7d0e502e,
54020x7d2e582e,
54030x7dce54ae,
54040x7dee5cae,
54050x7c08b040,
54060x7c89b040,
54070x4c002202,
54080x40800000,
54090x00050840,
54100x00000000,
54110xfc0e03f2,
54120x80f00000,
54130x3a100004,
54140x7c0ea5ae,
54150x54e815ba,
54160x7c11402e,
54170x7c0903a6,
54180x54ea5d78,
54190x54ec9b78,
54200x54f4dd78,
54210x54eb9d78,
54220x4e800420,
54230x00000000,
54240x7d0e502e,
54250x00000000,
54260x7d2f582e,
54270x00000000,
54280x7dce54ae,
54290x7def5cae,
54300x00000000,
54310x7c08b040,
54320x7c89b040,
54330x4c002202,
54340x40800000,
54350x0005083f,
54360x00000000,
54370x7c08b040,
54380x40800000,
54390x0005083f,
54400x00000000,
54410x7d0e502e,
54420x00000000,
54430x7d2f582e,
54440x00000000,
54450x7dee54ae,
54460x7dcf5cae,
54470x00000000,
54480x7c08b040,
54490x7c89b040,
54500x4c002202,
54510x40800000,
54520x0005083c,
54530x00000000,
54540x7c08b040,
54550x40800000,
54560x0005083c,
54570x00000000,
54580x7d0e502e,
54590x7d2e582e,
54600x7dce54ae,
54610x7dee5cae,
54620x7c08b040,
54630x7c89b040,
54640x4c002202,
54650x40800000,
54660x00050840,
54670x00000000,
54680xfc0e7824,
54690x80f00000,
54700x3a100004,
54710x7c0ea5ae,
54720x54e815ba,
54730x7c11402e,
54740x7c0903a6,
54750x54ea5d78,
54760x54ec9b78,
54770x54f4dd78,
54780x54eb9d78,
54790x4e800420,
54800x00000000,
54810x7d0a706e,
54820x7d2b786e,
54830x806a0004,
54840x7c08b040,
54850x808b0004,
54860x00000000,
54870x7d0a706e,
54880x7d2b786e,
54890x808a0004,
54900x7c08b040,
54910x806b0004,
54920x00000000,
54930x7d0a706e,
54940x7d2b706e,
54950x806a0004,
54960x7c08b040,
54970x808b0004,
54980x00000000,
54990x7c89b040,
55000x40820000,
55010x00050805,
55020x40860000,
55030x00050805,
55040x48000001,
55050x0005009c,
55060x41830000,
55070x00050804,
55080x0006000b,
55090x80f00000,
55100x3a100004,
55110x7ed4716e,
55120x90740004,
55130x0006000c,
55140x54e815ba,
55150x7c11402e,
55160x7c0903a6,
55170x54ea5d78,
55180x54ec9b78,
55190x54f4dd78,
55200x54eb9d78,
55210x4e800420,
55220x0006000e,
55230x7c000400,
55240x40a10000,
55250x0005080b,
55260x00000000,
55270x48000000,
55280x00050041,
55290x00000000,
55300x48000000,
55310x0005003d,
55320x00000000,
55330x48000000,
55340x00050042,
55350x00000000,
55360x0006000f,
55370x00000000,
55380xc9ea0000,
55390x4c002202,
55400xc9cb0000,
55410x00000000,
55420xc9ca0000,
55430x4c002202,
55440xc9eb0000,
55450x00000000,
55460x40800000,
55470x00050841,
55480x00000000,
55490x40800000,
55500x0005083d,
55510x00000000,
55520x40800000,
55530x00050842,
55540x00000000,
55550x000600a2,
55560xfc2e7824,
55570x48000001,
55580x00030010,
55590xfc0103f2,
55600xfc0e0028,
55610x80f00000,
55620x3a100004,
55630x7c0ea5ae,
55640x48000000,
55650x0005000c,
55660x00000000,
55670x7d0e502e,
55680x00000000,
55690x7d2f582e,
55700x00000000,
55710x7dce54ae,
55720x7def5cae,
55730x00000000,
55740x7c08b040,
55750x7c89b040,
55760x4c002202,
55770x40800000,
55780x0005083f,
55790x00000000,
55800x7c08b040,
55810x40800000,
55820x0005083f,
55830x00000000,
55840x7d0e502e,
55850x00000000,
55860x7d2f582e,
55870x00000000,
55880x7dee54ae,
55890x7dcf5cae,
55900x00000000,
55910x7c08b040,
55920x7c89b040,
55930x4c002202,
55940x40800000,
55950x0005083c,
55960x00000000,
55970x7c08b040,
55980x40800000,
55990x0005083c,
56000x00000000,
56010x7d0e502e,
56020x7d2e582e,
56030x7dce54ae,
56040x7dee5cae,
56050x7c08b040,
56060x7c89b040,
56070x4c002202,
56080x40800000,
56090x00050840,
56100x00000000,
56110x000600a2,
56120xfc2e7824,
56130x48000001,
56140x00030010,
56150xfc0103f2,
56160xfc0e0028,
56170x80f00000,
56180x3a100004,
56190x7c0ea5ae,
56200x54e815ba,
56210x7c11402e,
56220x7c0903a6,
56230x54ea5d78,
56240x54ec9b78,
56250x54f4dd78,
56260x54eb9d78,
56270x4e800420,
56280x00000000,
56290x7d0a706e,
56300x7d2b786e,
56310x806a0004,
56320x7c08b040,
56330x808b0004,
56340x00000000,
56350x7d0a706e,
56360x7d2b786e,
56370x808a0004,
56380x7c08b040,
56390x806b0004,
56400x00000000,
56410x7d0a706e,
56420x7d2b706e,
56430x806a0004,
56440x7c08b040,
56450x808b0004,
56460x00000000,
56470x7c89b040,
56480x40820000,
56490x00050805,
56500x40860000,
56510x00050805,
56520x48000001,
56530x0005009c,
56540x41830000,
56550x00050804,
56560x0006000b,
56570x80f00000,
56580x3a100004,
56590x7ed4716e,
56600x90740004,
56610x0006000c,
56620x54e815ba,
56630x7c11402e,
56640x7c0903a6,
56650x54ea5d78,
56660x54ec9b78,
56670x54f4dd78,
56680x54eb9d78,
56690x4e800420,
56700x0006000e,
56710x7c000400,
56720x40a10000,
56730x0005080b,
56740x00000000,
56750x48000000,
56760x00050041,
56770x00000000,
56780x48000000,
56790x0005003d,
56800x00000000,
56810x48000000,
56820x00050042,
56830x00000000,
56840x0006000f,
56850x00000000,
56860xc9ea0000,
56870x4c002202,
56880xc9cb0000,
56890x00000000,
56900xc9ca0000,
56910x4c002202,
56920xc9eb0000,
56930x00000000,
56940x40800000,
56950x00050841,
56960x00000000,
56970x40800000,
56980x0005083d,
56990x00000000,
57000x40800000,
57010x00050842,
57020x00000000,
57030x48000000,
57040x000500a2,
57050x00000000,
57060x7d0e502e,
57070x00000000,
57080x7d2f582e,
57090x00000000,
57100x7dce54ae,
57110x7def5cae,
57120x00000000,
57130x7c08b040,
57140x7c89b040,
57150x4c002202,
57160x40800000,
57170x0005083f,
57180x00000000,
57190x7c08b040,
57200x40800000,
57210x0005083f,
57220x00000000,
57230x7d0e502e,
57240x00000000,
57250x7d2f582e,
57260x00000000,
57270x7dee54ae,
57280x7dcf5cae,
57290x00000000,
57300x7c08b040,
57310x7c89b040,
57320x4c002202,
57330x40800000,
57340x0005083c,
57350x00000000,
57360x7c08b040,
57370x40800000,
57380x0005083c,
57390x00000000,
57400x7d0e502e,
57410x7d2e582e,
57420x7dce54ae,
57430x7dee5cae,
57440x7c08b040,
57450x7c89b040,
57460x4c002202,
57470x40800000,
57480x00050840,
57490x00000000,
57500x48000000,
57510x000500a2,
57520x00000000,
57530x7d0e502e,
57540x7c2e54ae,
57550x7d2e582e,
57560x7c4e5cae,
57570x7c08b040,
57580x7c89b040,
57590x4c002202,
57600x40800000,
57610x00050840,
57620x48000001,
57630x0003001f,
57640x80f00000,
57650x3a100004,
57660x7c2ea5ae,
57670x54e815ba,
57680x7c11402e,
57690x7c0903a6,
57700x54ea5d78,
57710x54ec9b78,
57720x54f4dd78,
57730x54eb9d78,
57740x4e800420,
57750x00000000,
57760x7caa5850,
57770x91d20000,
57780x00098200,
57790x7c8e5a14,
57800x7d555378,
57810x0006002b,
57820x92010020,
57830x7e439378,
57840x54a500fe,
57850x000900ab,
57860x48000001,
57870x00030030,
57880x28030000,
57890x81d20000,
57900x00098200,
57910x40820000,
57920x00050836,
57930x80f00000,
57940x3a100004,
57950x7c0eacae,
57960x7c0ea5ae,
57970x54e815ba,
57980x7c11402e,
57990x7c0903a6,
58000x54ea5d78,
58010x54ec9b78,
58020x54f4dd78,
58030x54eb9d78,
58040x4e800420,
58050x00000000,
58060x5588007e,
58070x000900ab,
58080x2108fffc,
58090x80f00000,
58100x3a100004,
58110x7c0f402e,
58120x39200000,
58130x00098200,
58140x7d34716e,
58150x90140004,
58160x54e815ba,
58170x7c11402e,
58180x7c0903a6,
58190x54ea5d78,
58200x54ec9b78,
58210x54f4dd78,
58220x54eb9d78,
58230x4e800420,
58240x00000000,
58250x5588007e,
58260x000900ab,
58270x2108fffc,
58280x80f00000,
58290x3a100004,
58300x7c0f402e,
58310x39200000,
58320x00098200,
58330x7d34716e,
58340x90140004,
58350x54e815ba,
58360x7c11402e,
58370x7c0903a6,
58380x54ea5d78,
58390x54ec9b78,
58400x54f4dd78,
58410x54eb9d78,
58420x4e800420,
58430x00000000,
58440x558c6800,
58450x000900a1,
58460x7d8c8670,
58470x80f00000,
58480x3a100004,
58490x7ed4716e,
58500x91940004,
58510x54e815ba,
58520x7c11402e,
58530x7c0903a6,
58540x54ea5d78,
58550x54ec9b78,
58560x54f4dd78,
58570x54eb9d78,
58580x4e800420,
58590x00000000,
58600x558c6800,
58610x000900a1,
58620x7d88fe70,
58630x7d096278,
58640x7d284850,
58650x7d260034,
58660x2106040d,
58670x7d293030,
58680x20cc0000,
58690x5508a000,
58700x000900a1,
58710x512ca87e,
58720x7c000110,
58730x7d8c4214,
58740x7d8c0038,
58750x80f00000,
58760x3a100004,
58770x7d94716e,
58780x93140004,
58790x54e815ba,
58800x7c11402e,
58810x7c0903a6,
58820x54ea5d78,
58830x54ec9b78,
58840x54f4dd78,
58850x54eb9d78,
58860x4e800420,
58870x00000000,
58880x80f00000,
58890x3a100004,
58900x7c0f64ae,
58910x7c0ea5ae,
58920x54e815ba,
58930x7c11402e,
58940x7c0903a6,
58950x54ea5d78,
58960x54ec9b78,
58970x54f4dd78,
58980x54eb9d78,
58990x4e800420,
59000x00000000,
59010x558800fe,
59020x000900ab,
59030x7d0040f8,
59040x80f00000,
59050x3a100004,
59060x7c0ea12e,
59070x54e815ba,
59080x7c11402e,
59090x7c0903a6,
59100x54ea5d78,
59110x54ec9b78,
59120x54f4dd78,
59130x54eb9d78,
59140x4e800420,
59150x00000000,
59160x7eeea12e,
59170x3a940008,
59180x0006000b,
59190x7eeea12e,
59200x7c146000,
59210x3a940008,
59220x41800000,
59230x0005080b,
59240x80f00000,
59250x3a100004,
59260x54e815ba,
59270x7c11402e,
59280x7c0903a6,
59290x54ea5d78,
59300x54ec9b78,
59310x54f4dd78,
59320x54eb9d78,
59330x4e800420,
59340x00000000,
59350x814efffc,
59360x558c007e,
59370x000900ab,
59380x398c0000,
59390x00098200,
59400x7d4a602e,
59410x80f00000,
59420x3a100004,
59430x810a0000,
59440x00098200,
59450xc8080000,
59460x7c0ea5ae,
59470x54e815ba,
59480x7c11402e,
59490x7c0903a6,
59500x54ea5d78,
59510x54ec9b78,
59520x54f4dd78,
59530x54eb9d78,
59540x4e800420,
59550x00000000,
59560x814efffc,
59570x5694007e,
59580x000900ab,
59590x3a940000,
59600x00098200,
59610x7c0c74ee,
59620x7d4aa02e,
59630x88ca0000,
59640x00098200,
59650x808a0000,
59660x00098200,
59670x70c60000,
59680x00090200,
59690x880a0000,
59700x00098200,
59710x812c0000,
59720xd8040000,
59730x28800000,
59740x810c0004,
59750x4c423382,
59760x39290000,
59770x00098200,
59780x40820000,
59790x00050802,
59800x0006000b,
59810x80f00000,
59820x3a100004,
59830x54e815ba,
59840x7c11402e,
59850x7c0903a6,
59860x54ea5d78,
59870x54ec9b78,
59880x54f4dd78,
59890x54eb9d78,
59900x4e800420,
59910x0006000c,
59920x28090000,
59930x00090200,
59940x40800000,
59950x0005080b,
59960x88c80000,
59970x00098200,
59980x70c60000,
59990x00090200,
60000x38710000,
60010x00098200,
60020x41820000,
60030x0005080b,
60040x48000001,
60050x00030031,
60060x48000000,
60070x0005000b,
60080x00000000,
60090x814efffc,
60100x5588007e,
60110x000900ab,
60120x5694007e,
60130x000900ab,
60140x2108fffc,
60150x3a940000,
60160x00098200,
60170x7d0f402e,
60180x7d4aa02e,
60190x88ca0000,
60200x00098200,
60210x808a0000,
60220x00098200,
60230x70c60000,
60240x00090200,
60250x88c80000,
60260x00098200,
60270x892a0000,
60280x00098200,
60290x38000000,
60300x00098200,
60310x91040004,
60320x90040000,
60330x40820000,
60340x00050802,
60350x0006000b,
60360x80f00000,
60370x3a100004,
60380x54e815ba,
60390x7c11402e,
60400x7c0903a6,
60410x54ea5d78,
60420x54ec9b78,
60430x54f4dd78,
60440x54eb9d78,
60450x4e800420,
60460x0006000c,
60470x70c60000,
60480x00090200,
60490x28890000,
60500x4c423382,
60510x38710000,
60520x00098200,
60530x41820000,
60540x0005080b,
60550x48000001,
60560x00030031,
60570x48000000,
60580x0005000b,
60590x00000000,
60600x814efffc,
60610x5694007e,
60620x000900ab,
60630x3a940000,
60640x00098200,
60650x7c0f64ae,
60660x7d4aa02e,
60670x80f00000,
60680x3a100004,
60690x810a0000,
60700x00098200,
60710xd8080000,
60720x54e815ba,
60730x7c11402e,
60740x7c0903a6,
60750x54ea5d78,
60760x54ec9b78,
60770x54f4dd78,
60780x54eb9d78,
60790x4e800420,
60800x00000000,
60810x814efffc,
60820x5694007e,
60830x000900ab,
60840x558000fe,
60850x000900ab,
60860x3a940000,
60870x00098200,
60880x7c0000f8,
60890x7d4aa02e,
60900x80f00000,
60910x3a100004,
60920x810a0000,
60930x00098200,
60940x90080000,
60950x54e815ba,
60960x7c11402e,
60970x7c0903a6,
60980x54ea5d78,
60990x54ec9b78,
61000x54f4dd78,
61010x54eb9d78,
61020x4e800420,
61030x00000000,
61040x81120000,
61050x00098200,
61060x5580007e,
61070x000900ab,
61080x3e100000,
61090x00098200,
61100x7e100214,
61110x91d20000,
61120x00098200,
61130x28080000,
61140x7e439378,
61150x41820000,
61160x00050801,
61170x7c8ea214,
61180x48000001,
61190x00030032,
61200x81d20000,
61210x00098200,
61220x0006000b,
61230x80f00000,
61240x3a100004,
61250x54e815ba,
61260x7c11402e,
61270x7c0903a6,
61280x54ea5d78,
61290x54ec9b78,
61300x54f4dd78,
61310x54eb9d78,
61320x4e800420,
61330x00000000,
61340x5588007e,
61350x000900ab,
61360x91d20000,
61370x00098200,
61380x2108fffc,
61390x92010020,
61400x7c8f402e,
61410x7e439378,
61420x80aefffc,
61430x48000001,
61440x00030033,
61450x81d20000,
61460x00098200,
61470x38000000,
61480x00098200,
61490x7c14716e,
61500x90740004,
61510x80f00000,
61520x3a100004,
61530x54e815ba,
61540x7c11402e,
61550x7c0903a6,
61560x54ea5d78,
61570x54ec9b78,
61580x54f4dd78,
61590x54eb9d78,
61600x4e800420,
61610x00000000,
61620x80110000,
61630x00098200,
61640x7e439378,
61650x81110000,
61660x00098200,
61670x91d20000,
61680x00098200,
61690x7c004040,
61700x92010020,
61710x40800000,
61720x00050805,
61730x0006000b,
61740x00000000,
61750x5584ed7e,
61760x558596fe,
61770x2c0407ff,
61780x41820000,
61790x00050803,
61800x0006000c,
61810x48000001,
61820x00030034,
61830x00000000,
61840x5588007e,
61850x000900ab,
61860x2108fffc,
61870x7c8f402e,
61880x48000001,
61890x00030035,
61900x00000000,
61910x81d20000,
61920x00098200,
61930x38000000,
61940x00098200,
61950x7c14716e,
61960x90740004,
61970x80f00000,
61980x3a100004,
61990x54e815ba,
62000x7c11402e,
62010x7c0903a6,
62020x54ea5d78,
62030x54ec9b78,
62040x54f4dd78,
62050x54eb9d78,
62060x4e800420,
62070x00000000,
62080x0006000d,
62090x38800801,
62100x48000000,
62110x0005000c,
62120x00000000,
62130x0006000f,
62140x7d956378,
62150x48000001,
62160x00030036,
62170x7eacab78,
62180x7e439378,
62190x48000000,
62200x0005000b,
62210x00000000,
62220x812efffc,
62230x5588007e,
62240x000900ab,
62250x81490000,
62260x00098200,
62270x2108fffc,
62280x7d6f402e,
62290x00000000,
62300x48000000,
62310x000500a3,
62320x00000000,
62330x48000000,
62340x000500a4,
62350x00000000,
62360x7c6a706e,
62370x7c8b706e,
62380x814a0004,
62390x00000000,
62400x816b0004,
62410x00000000,
62420xc80b0000,
62430x00000000,
62440x2c030000,
62450x00098200,
62460x7c84b040,
62470x40820000,
62480x00050830,
62490x00000000,
62500x800a0000,
62510x00098200,
62520x40860000,
62530x00050805,
62540x810a0000,
62550x00098200,
62560x7c005840,
62570x55691800,
62580x000900a1,
62590x00000000,
62600x40840000,
62610x00050805,
62620xfc20001e,
62630xfc40f02a,
62640xd8210010,
62650x800a0000,
62660x00098200,
62670xfc42f028,
62680x81210014,
62690x810a0000,
62700x00098200,
62710xfc801000,
62720x7c004840,
62730x4c213202,
62740x55291800,
62750x000900a1,
62760x00000000,
62770x40810000,
62780x00050830,
62790x7c08482e,
62800x7dc84cae,
62810x2c000000,
62820x00098200,
62830x41820000,
62840x00050802,
62850x0006000b,
62860x80f00000,
62870x3a100004,
62880x7dcea5ae,
62890x54e815ba,
62900x7c11402e,
62910x7c0903a6,
62920x54ea5d78,
62930x54ec9b78,
62940x54f4dd78,
62950x54eb9d78,
62960x4e800420,
62970x0006000c,
62980x812a0000,
62990x00098200,
63000x28090000,
63010x41820000,
63020x0005080b,
63030x88090000,
63040x00098200,
63050x70000000,
63060x00090200,
63070x40820000,
63080x0005080b,
63090x48000000,
63100x00050030,
63110x0006000f,
63120x2c040000,
63130x00098200,
63140x40820000,
63150x00050830,
63160x00000000,
63170x816b0004,
63180x00000000,
63190x48000000,
63200x000500a3,
63210x00000000,
63220x7c6a706e,
63230x5568007e,
63240x000900ab,
63250x814a0004,
63260x2108fffc,
63270x2c030000,
63280x00098200,
63290x7d6f402e,
63300x40820000,
63310x0005082d,
63320x000600a3,
63330x800a0000,
63340x00098200,
63350x810b0000,
63360x00098200,
63370x812a0000,
63380x00098200,
63390x7d080038,
63400x55002800,
63410x000900a1,
63420x55081800,
63430x000900a1,
63440x7d080050,
63450x7d294214,
63460x0006000b,
63470x80690000,
63480x00098200,
63490x80090000,
63500x00098200,
63510x80890000,
63520x00098200,
63530x81090000,
63540x00098200,
63550x2c030000,
63560x00098200,
63570x40820000,
63580x00050804,
63590x7c005800,
63600x40820000,
63610x00050804,
63620x2c040000,
63630x00098200,
63640x41820000,
63650x00050805,
63660x0006000d,
63670x7c94716e,
63680x91140004,
63690x80f00000,
63700x3a100004,
63710x54e815ba,
63720x7c11402e,
63730x7c0903a6,
63740x54ea5d78,
63750x54ec9b78,
63760x54f4dd78,
63770x54eb9d78,
63780x4e800420,
63790x0006000e,
63800x81290000,
63810x00098200,
63820x00000000,
63830x28090000,
63840x40820000,
63850x0005080b,
63860x38800000,
63870x00098200,
63880x0006000f,
63890x812a0000,
63900x00098200,
63910x28090000,
63920x41820000,
63930x0005080d,
63940x88090000,
63950x00098200,
63960x70000000,
63970x00090200,
63980x40820000,
63990x0005080d,
64000x48000000,
64010x0005002e,
64020x00000000,
64030x7c6a706e,
64040x556000fe,
64050x000900ab,
64060x814a0004,
64070x2c030000,
64080x00098200,
64090x40820000,
64100x0005082f,
64110x810a0000,
64120x00098200,
64130x812a0000,
64140x00098200,
64150x7c004040,
64160x40800000,
64170x0005082f,
64180x7d09582e,
64190x7c095cae,
64200x2c080000,
64210x00098200,
64220x41820000,
64230x00050805,
64240x0006000b,
64250x80f00000,
64260x3a100004,
64270x7c0ea5ae,
64280x54e815ba,
64290x7c11402e,
64300x7c0903a6,
64310x54ea5d78,
64320x54ec9b78,
64330x54f4dd78,
64340x54eb9d78,
64350x4e800420,
64360x0006000f,
64370x812a0000,
64380x00098200,
64390x28090000,
64400x41820000,
64410x0005080b,
64420x89290000,
64430x00098200,
64440x71290000,
64450x00090200,
64460x40820000,
64470x0005080b,
64480x48000000,
64490x0005002f,
64500x00000000,
64510x7c6a706e,
64520x7c8b706e,
64530x814a0004,
64540x00000000,
64550x816b0004,
64560x00000000,
64570xc80b0000,
64580x00000000,
64590x2c030000,
64600x00098200,
64610x7c84b040,
64620x40820000,
64630x00050834,
64640x00000000,
64650x800a0000,
64660x00098200,
64670x40860000,
64680x00050805,
64690x810a0000,
64700x00098200,
64710x7c005840,
64720x55601800,
64730x000900a1,
64740x00000000,
64750x40840000,
64760x00050805,
64770xfc20001e,
64780xfc40f02a,
64790xd8210010,
64800x800a0000,
64810x00098200,
64820xfc42f028,
64830x81210014,
64840x810a0000,
64850x00098200,
64860xfc801000,
64870x7c004840,
64880x4c213202,
64890x55201800,
64900x000900a1,
64910x00000000,
64920x40810000,
64930x00050834,
64940x7d28002e,
64950x88ca0000,
64960x00098200,
64970x7dcea4ae,
64980x2c090000,
64990x00098200,
65000x41820000,
65010x00050803,
65020x0006000b,
65030x70c90000,
65040x00090200,
65050x7dc805ae,
65060x40820000,
65070x00050807,
65080x0006000c,
65090x80f00000,
65100x3a100004,
65110x54e815ba,
65120x7c11402e,
65130x7c0903a6,
65140x54ea5d78,
65150x54ec9b78,
65160x54f4dd78,
65170x54eb9d78,
65180x4e800420,
65190x0006000d,
65200x812a0000,
65210x00098200,
65220x28090000,
65230x41820000,
65240x0005080b,
65250x89290000,
65260x00098200,
65270x71290000,
65280x00090200,
65290x40820000,
65300x0005080b,
65310x48000000,
65320x00050034,
65330x0006000f,
65340x2c040000,
65350x00098200,
65360x40820000,
65370x00050834,
65380x00000000,
65390x816b0004,
65400x00000000,
65410x48000000,
65420x000500a4,
65430x00060011,
65440x80110000,
65450x00098200,
65460x54c607b8,
65470x91510000,
65480x00098200,
65490x98ca0000,
65500x00098200,
65510x900a0000,
65520x00098200,
65530x48000000,
65540x0005000c,
65550x00000000,
65560x0006000b,
65570x2c030000,
65580x00098200,
65590x40820000,
65600x00050804,
65610x7c005800,
65620x40820000,
65630x00050804,
65640x2c040000,
65650x00098200,
65660x41820000,
65670x00050805,
65680x0006000d,
65690x7c94716e,
65700x91140004,
65710x80f00000,
65720x3a100004,
65730x54e815ba,
65740x7c11402e,
65750x7c0903a6,
65760x54ea5d78,
65770x54ec9b78,
65780x54f4dd78,
65790x54eb9d78,
65800x4e800420,
65810x00000000,
65820x7c6a706e,
65830x5568007e,
65840x000900ab,
65850x814a0004,
65860x2108fffc,
65870x2c030000,
65880x00098200,
65890x7d6f402e,
65900x40820000,
65910x00050831,
65920x000600a4,
65930x800a0000,
65940x00098200,
65950x810b0000,
65960x00098200,
65970x812a0000,
65980x00098200,
65990x9b0a0000,
66000x00098200,
66010x7d080038,
66020x7dcea4ae,
66030x55002800,
66040x000900a1,
66050x55081800,
66060x000900a1,
66070x7d080050,
66080x88ca0000,
66090x00098200,
66100x7d294214,
66110x0006000b,
66120x80690000,
66130x00098200,
66140x80090000,
66150x00098200,
66160x80890000,
66170x00098200,
66180x81090000,
66190x00098200,
66200x2c030000,
66210x00098200,
66220x40820000,
66230x00050805,
66240x7c005800,
66250x40820000,
66260x00050805,
66270x2c040000,
66280x00098200,
66290x41820000,
66300x00050804,
66310x0006000c,
66320x00000000,
66330x70c00000,
66340x00090200,
66350xd9c90000,
66360x00098200,
66370x40820000,
66380x00050807,
66390x0006000d,
66400x80f00000,
66410x3a100004,
66420x54e815ba,
66430x7c11402e,
66440x7c0903a6,
66450x54ea5d78,
66460x54ec9b78,
66470x54f4dd78,
66480x54eb9d78,
66490x4e800420,
66500x0006000e,
66510x810a0000,
66520x00098200,
66530x28080000,
66540x41820000,
66550x0005080c,
66560x88080000,
66570x00098200,
66580x70000000,
66590x00090200,
66600x40820000,
66610x0005080c,
66620x48000000,
66630x00050032,
66640x0006000f,
66650x81290000,
66660x00098200,
66670x28090000,
66680x40820000,
66690x0005080b,
66700x810a0000,
66710x00098200,
66720x38b10000,
66730x00098200,
66740x92010020,
66750x7e439378,
66760x28080000,
66770x91d20000,
66780x00098200,
66790x41820000,
66800x00050806,
66810x88080000,
66820x00098200,
66830x70000000,
66840x00090200,
66850x41820000,
66860x00050832,
66870x00060010,
66880x00000000,
66890x38000000,
66900x00098200,
66910x91650004,
66920x7d445378,
66930x90050000,
66940x48000001,
66950x00030037,
66960x81d20000,
66970x00098200,
66980xd9c30000,
66990x48000000,
67000x0005000d,
67010x00060011,
67020x80110000,
67030x00098200,
67040x54c607b8,
67050x91510000,
67060x00098200,
67070x98ca0000,
67080x00098200,
67090x900a0000,
67100x00098200,
67110x48000000,
67120x0005000d,
67130x00000000,
67140x7c6a706e,
67150x556000fe,
67160x000900ab,
67170x814a0004,
67180x2c030000,
67190x00098200,
67200x40820000,
67210x00050833,
67220x810a0000,
67230x00098200,
67240x812a0000,
67250x00098200,
67260x88ca0000,
67270x00098200,
67280x7c004040,
67290x7dcea4ae,
67300x40800000,
67310x00050833,
67320x7d09582e,
67330x2c080000,
67340x00098200,
67350x41820000,
67360x00050805,
67370x0006000b,
67380x70c00000,
67390x00090200,
67400x7dc95dae,
67410x40820000,
67420x00050807,
67430x0006000c,
67440x80f00000,
67450x3a100004,
67460x54e815ba,
67470x7c11402e,
67480x7c0903a6,
67490x54ea5d78,
67500x54ec9b78,
67510x54f4dd78,
67520x54eb9d78,
67530x4e800420,
67540x0006000f,
67550x810a0000,
67560x00098200,
67570x28080000,
67580x41820000,
67590x0005080b,
67600x89080000,
67610x00098200,
67620x71080000,
67630x00090200,
67640x40820000,
67650x0005080b,
67660x48000000,
67670x00050033,
67680x00060011,
67690x80110000,
67700x00098200,
67710x00000000,
67720x54c607b8,
67730x91510000,
67740x00098200,
67750x98ca0000,
67760x00098200,
67770x900a0000,
67780x00098200,
67790x48000000,
67800x0005000c,
67810x00000000,
67820x7e8ea214,
67830x0006000b,
67840x7ccf6214,
67850x8094fffc,
67860x3413fff8,
67870x80c60004,
67880x540500fe,
67890x000900ab,
67900x41820000,
67910x00050804,
67920x7ca53214,
67930x81240000,
67940x00098200,
67950x54c81800,
67960x000900a1,
67970x88c40000,
67980x00098200,
67990x7c054840,
68000x7d340214,
68010x80040000,
68020x00098200,
68030x41810000,
68040x00050805,
68050x7d080214,
68060x70c00000,
68070x00090200,
68080x0006000d,
68090xc8140000,
68100x3a940008,
68110x7c944800,
68120xd8080000,
68130x39080008,
68140x41840000,
68150x0005080d,
68160x40820000,
68170x00050807,
68180x0006000e,
68190x80f00000,
68200x3a100004,
68210x54e815ba,
68220x7c11402e,
68230x7c0903a6,
68240x54ea5d78,
68250x54ec9b78,
68260x54f4dd78,
68270x54eb9d78,
68280x4e800420,
68290x0006000f,
68300x91d20000,
68310x00098200,
68320x7e439378,
68330x92010020,
68340x7d956378,
68350x48000001,
68360x00030038,
68370x7eacab78,
68380x48000000,
68390x0005000b,
68400x00060011,
68410x80110000,
68420x00098200,
68430x54c607b8,
68440x90910000,
68450x00098200,
68460x98c40000,
68470x00098200,
68480x90040000,
68490x00098200,
68500x00000000,
68510x48000000,
68520x0005000e,
68530x00000000,
68540x7d6b9a14,
68550x00000000,
68560x7dc97378,
68570x7c0ea06e,
68580x814e0004,
68590x396bfff8,
68600x39ce0008,
68610x2c000000,
68620x00098200,
68630x40820000,
68640x00050825,
68650x920efff8,
68660x820a0000,
68670x00098200,
68680x80f00000,
68690x3a100004,
68700x54e815ba,
68710x54f4dd78,
68720x7c11402e,
68730x7e947214,
68740x7c0903a6,
68750x4e800420,
68760x00000000,
68770x7d6b9a14,
68780x00000000,
68790x7c14706e,
68800x81540004,
68810x396bfff8,
68820x810efff8,
68830x2c000000,
68840x00098200,
68850x3a940008,
68860x40820000,
68870x00050845,
68880x00060046,
68890x71000000,
68900x00090200,
68910x88ca0000,
68920x00098200,
68930x69090000,
68940x00090200,
68950x288b0000,
68960x40820000,
68970x00050807,
68980x0006000b,
68990x914efffc,
69000x39200000,
69010x2b860001,
69020x41860000,
69030x00050803,
69040x0006000c,
69050x38c90008,
69060x7c144cae,
69070x7c865840,
69080x7c0e4dae,
69090x7cc93378,
69100x40860000,
69110x0005080c,
69120x0006000d,
69130x4c42ea02,
69140x41820000,
69150x00050805,
69160x0006000e,
69170x820a0000,
69180x00098200,
69190x80f00000,
69200x3a100004,
69210x54e815ba,
69220x54f4dd78,
69230x7c11402e,
69240x7e947214,
69250x7c0903a6,
69260x4e800420,
69270x0006000f,
69280x80e8fffc,
69290x54f4dd78,
69300x7d147050,
69310x81080000,
69320x00098200,
69330x81080000,
69340x00098200,
69350x81e80000,
69360x00098200,
69370x48000000,
69380x0005000e,
69390x00060011,
69400x71200000,
69410x00090200,
69420x00000000,
69430x40820000,
69440x0005080b,
69450x7dc97050,
69460x810efff8,
69470x71000000,
69480x00090200,
69490x48000000,
69500x0005000b,
69510x00000000,
69520x7dc97378,
69530x7dcea214,
69540x810effe8,
69550x814effec,
69560xc82efff8,
69570xc80efff0,
69580x910e0000,
69590x914e0004,
69600x2c080000,
69610x00098200,
69620xd82e0010,
69630x39600010,
69640xdc0e0008,
69650x40820000,
69660x00050825,
69670x920efff8,
69680x820a0000,
69690x00098200,
69700x80f00000,
69710x3a100004,
69720x54e815ba,
69730x54f4dd78,
69740x7c11402e,
69750x7e947214,
69760x7c0903a6,
69770x4e800420,
69780x00000000,
69790x7e8ea214,
69800x8154fff4,
69810x8174fffc,
69820x800a0000,
69830x00098200,
69840x810a0000,
69850x00098200,
69860x3a100004,
69870x0006000b,
69880x7c0b0040,
69890x55661800,
69900x000900a1,
69910x40800000,
69920x00050805,
69930x7d28302e,
69940x7c0834ae,
69950x2c090000,
69960x00098200,
69970x80f0fffc,
69980x41820000,
69990x00050804,
70000x00000000,
70010x91740004,
70020x92d40000,
70030x00000000,
70040x9161000c,
70050xc8210008,
70060xfc21f028,
70070x00000000,
70080x396b0001,
70090x3cd00000,
70100x00098200,
70110xd8140008,
70120x54e893ba,
70130x9174fffc,
70140x7e083214,
70150x00000000,
70160xd8340000,
70170x00000000,
70180x0006000d,
70190x80f00000,
70200x3a100004,
70210x54e815ba,
70220x7c11402e,
70230x7c0903a6,
70240x54ea5d78,
70250x54ec9b78,
70260x54f4dd78,
70270x54eb9d78,
70280x4e800420,
70290x0006000e,
70300x396b0001,
70310x48000000,
70320x0005000b,
70330x0006000f,
70340x810a0000,
70350x00098200,
70360x7d605850,
70370x812a0000,
70380x00098200,
70390x00060010,
70400x7c0b4040,
70410x55662800,
70420x000900a1,
70430x41a10000,
70440x0005080d,
70450x556a1800,
70460x000900a1,
70470x7cca3050,
70480x7d49302e,
70490x7c0934ae,
70500x7cc93214,
70510x2c0a0000,
70520x00098200,
70530x80f0fffc,
70540x41820000,
70550x00050807,
70560xc8260000,
70570x00098200,
70580x3d300000,
70590x00098200,
70600xd8140008,
70610x7d6b0214,
70620x54e893ba,
70630xd8340000,
70640x396b0001,
70650x7e084a14,
70660x9174fffc,
70670x48000000,
70680x0005000d,
70690x00060011,
70700x396b0001,
70710x48000000,
70720x00050010,
70730x00000000,
70740x7e8ea214,
70750x8014ffe8,
70760x8114ffec,
70770x8134fff0,
70780x80d4fff8,
70790x2c090000,
70800x00098200,
70810x2c800000,
70820x00098200,
70830x2f060000,
70840x00098200,
70850x40860000,
70860x00050805,
70870x89080000,
70880x00098200,
70890x4c42d202,
70900x2f880000,
70910x00098200,
70920x5580007e,
70930x000900ab,
70940x4c42f202,
70950x7cd00214,
70960x40820000,
70970x00050805,
70980x9314fffc,
70990x3e060000,
71000x00098200,
71010x0006000b,
71020x80f00000,
71030x3a100004,
71040x54e815ba,
71050x7c11402e,
71060x7c0903a6,
71070x54ea5d78,
71080x54ec9b78,
71090x54f4dd78,
71100x54eb9d78,
71110x4e800420,
71120x0006000f,
71130x38000000,
71140x00098200,
71150x39000000,
71160x00098200,
71170x9810ffff,
71180x3e060000,
71190x00098200,
71200x99100003,
71210x48000000,
71220x0005000b,
71230x00000000,
71240x800efff8,
71250x7d6e5a14,
71260x7e8ea214,
71270x396b0000,
71280x00098200,
71290x7d345214,
71300x38cefff8,
71310x7d605850,
71320x288a0000,
71330x7d0b3051,
71340x41860000,
71350x00050805,
71360x3929fff0,
71370x40810000,
71380x00050802,
71390x0006000b,
71400xc80b0000,
71410x396b0008,
71420xd8140000,
71430x7c144840,
71440x7c8b3040,
71450x40800000,
71460x00050803,
71470x3a940008,
71480x41840000,
71490x0005080b,
71500x0006000c,
71510x92f40000,
71520x7c144840,
71530x3a940008,
71540x41800000,
71550x0005080c,
71560x0006000d,
71570x80f00000,
71580x3a100004,
71590x54e815ba,
71600x7c11402e,
71610x7c0903a6,
71620x54ea5d78,
71630x54ec9b78,
71640x54f4dd78,
71650x54eb9d78,
71660x4e800420,
71670x0006000f,
71680x80120000,
71690x00098200,
71700x3a600008,
71710x40a10000,
71720x0005080d,
71730x7d344214,
71740x7c090040,
71750x3a680008,
71760x41810000,
71770x00050807,
71780x00060010,
71790xc80b0000,
71800x396b0008,
71810xd8140000,
71820x7c0b3040,
71830x3a940008,
71840x41800000,
71850x00050810,
71860x48000000,
71870x0005000d,
71880x00060011,
71890x7e439378,
71900x92920000,
71910x00098200,
71920x7eae5850,
71930x91d20000,
71940x00098200,
71950x7e8ea050,
71960x92010020,
71970x550400fe,
71980x000900ab,
71990x48000001,
72000x00030000,
72010x81d20000,
72020x00098200,
72030x00000000,
72040x7e8ea214,
72050x7d6eaa14,
72060x38cefff8,
72070x48000000,
72080x00050010,
72090x00000000,
72100x7d8c9a14,
72110x00000000,
72120x820efff8,
72130x7e8ea214,
72140x7d936378,
72150x0006000b,
72160x72000000,
72170x00090200,
72180x6a080000,
72190x00090200,
72200x40820000,
72210x000508a5,
72220x00060017,
72230x80f0fffc,
72240x2c0c0008,
72250x392efff8,
72260x396cfff8,
72270x54ea5d78,
72280x41820000,
72290x00050803,
72300x39000000,
72310x0006000c,
72320x38c80008,
72330x7c1444ae,
72340x7c065800,
72350x7c0945ae,
72360x41820000,
72370x00050803,
72380x39060008,
72390x7c3434ae,
72400x7c085800,
72410x7c2935ae,
72420x40820000,
72430x0005080c,
72440x0006000d,
72450x0006000f,
72460x7c0a6040,
72470x54f4dd78,
72480x41810000,
72490x00050806,
72500x7dd44850,
72510x810efffc,
72520x80f00000,
72530x3a100004,
72540x81080000,
72550x00098200,
72560x81e80000,
72570x00098200,
72580x54e815ba,
72590x7c11402e,
72600x7c0903a6,
72610x54ea5d78,
72620x54ec9b78,
72630x54f4dd78,
72640x54eb9d78,
72650x4e800420,
72660x00060010,
72670x390cfff8,
72680x398c0008,
72690x7ee9412e,
72700x48000000,
72710x0005000f,
72720x000600a5,
72730x71090000,
72740x00090200,
72750x40820000,
72760x00050818,
72770x7dc87050,
72780x820efff8,
72790x48000000,
72800x0005000b,
72810x00000000,
72820x820efff8,
72830x7e8ea214,
72840x7d936378,
72850x72000000,
72860x00090200,
72870x6a080000,
72880x00090200,
72890x40a20000,
72900x000508a5,
72910x80f0fffc,
72920x392efff8,
72930x54ea5d78,
72940x00000000,
72950xc8140000,
72960xd8090000,
72970x00000000,
72980x0006000f,
72990x7c0a6040,
73000x54f4dd78,
73010x41810000,
73020x00050806,
73030x7dd44850,
73040x810efffc,
73050x80f00000,
73060x3a100004,
73070x81080000,
73080x00098200,
73090x81e80000,
73100x00098200,
73110x54e815ba,
73120x7c11402e,
73130x7c0903a6,
73140x54ea5d78,
73150x54ec9b78,
73160x54f4dd78,
73170x54eb9d78,
73180x4e800420,
73190x00060010,
73200x390cfff8,
73210x398c0008,
73220x7ee9412e,
73230x48000000,
73240x0005000f,
73250x00000000,
73260x5608fe7c,
73270x39080000,
73280x00098200,
73290x7d31422e,
73300x35290000,
73310x00098200,
73320x7d31432e,
73330x41800000,
73340x00050894,
73350x00000000,
73360x7d14706e,
73370x80740000,
73380x00098200,
73390x7c08b040,
73400x00000000,
73410x80b40000,
73420x00098200,
73430x40820000,
73440x00050809,
73450x7c632e15,
73460x2f050000,
73470x80940000,
73480x00098200,
73490x41830000,
73500x00050806,
73510x0006000e,
73520x90740000,
73530x00098200,
73540x00000000,
73550x80d40000,
73560x00098200,
73570x80b40000,
73580x00098200,
73590x81340000,
73600x00098200,
73610x80940000,
73620x00098200,
73630x7f86b040,
73640x7c89b040,
73650x4c42f202,
73660x4c423202,
73670x2f050000,
73680x40820000,
73690x00050809,
73700x00000000,
73710x41980000,
73720x00050805,
73730x7c032000,
73740x0006000b,
73750x92d40000,
73760x00098200,
73770x00000000,
73780x558c007e,
73790x000900ab,
73800x00000000,
73810x90740000,
73820x00098200,
73830x00000000,
73840x7d906214,
73850x00000000,
73860x41810000,
73870x00050803,
73880x00000000,
73890x3e0c0000,
73900x00098200,
73910x40a10000,
73920x00050807,
73930x00000000,
73940x41810000,
73950x00050802,
73960x3e0c0000,
73970x00098200,
73980x00000000,
73990x40a10000,
74000x00070800,
74010x00000000,
74020x0006000c,
74030x80f00000,
74040x3a100004,
74050x54e815ba,
74060x7c11402e,
74070x7c0903a6,
74080x54ea5d78,
74090x54ec9b78,
74100x54f4dd78,
74110x54eb9d78,
74120x4e800420,
74130x0006000f,
74140x7c041800,
74150x48000000,
74160x0005000b,
74170x00000000,
74180x00060010,
74190x7c000400,
74200x40a10000,
74210x0005080e,
74220x48000000,
74230x0005000c,
74240x00000000,
74250x00060013,
74260xc8340000,
74270x00098200,
74280x00000000,
74290x7c3474ee,
74300x00000000,
74310xc8740000,
74320x00098200,
74330xc8540000,
74340x00098200,
74350x80d40000,
74360x00098200,
74370xfc21182a,
74380xd8340000,
74390x00098200,
74400x00000000,
74410x00060013,
74420x00000000,
74430x7d14706e,
74440x80d40000,
74450x00098200,
74460x81340000,
74470x00098200,
74480x7c08b040,
74490x7f86b040,
74500x7c89b040,
74510x00000000,
74520xc8340000,
74530x00098200,
74540x4c00e202,
74550xc8740000,
74560x00098200,
74570x4c002202,
74580xc8540000,
74590x00098200,
74600x40800000,
74610x00050847,
74620x00000000,
74630x2f060000,
74640x00000000,
74650x558c007e,
74660x000900ab,
74670x00000000,
74680xd8340000,
74690x00098200,
74700x00000000,
74710x7d906214,
74720x00000000,
74730xfc011000,
74740x00000000,
74750x3e0c0000,
74760x00098200,
74770x00000000,
74780x41980000,
74790x00050805,
74800x00000000,
74810x41810000,
74820x00050803,
74830x00000000,
74840x41a10000,
74850x0005080c,
74860x00000000,
74870x41810000,
74880x00050802,
74890x00000000,
74900x0006000b,
74910x3e0c0000,
74920x00098200,
74930x00000000,
74940x40a10000,
74950x00050807,
74960x00000000,
74970x40a10000,
74980x00070800,
74990x00000000,
75000x48000000,
75010x0005000c,
75020x00000000,
75030x0006000c,
75040x80f00000,
75050x3a100004,
75060x54e815ba,
75070x7c11402e,
75080x7c0903a6,
75090x54ea5d78,
75100x54ec9b78,
75110x54f4dd78,
75120x54eb9d78,
75130x4e800420,
75140x00000000,
75150x0006000f,
75160x00000000,
75170x40800000,
75180x0005080c,
75190x0006000d,
75200x3e0c0000,
75210x00098200,
75220x00000000,
75230x40a00000,
75240x0005080b,
75250x00000000,
75260x40a00000,
75270x00050807,
75280x00000000,
75290x40a00000,
75300x00070800,
75310x00000000,
75320x48000000,
75330x0005000c,
75340x00000000,
75350x00060011,
75360x80f0fffc,
75370x54ec9b78,
75380x48000000,
75390x00070000,
75400x00000000,
75410x5608fe7c,
75420x39080000,
75430x00098200,
75440x7d31422e,
75450x35290000,
75460x00098200,
75470x7d31432e,
75480x41800000,
75490x00050894,
75500x00000000,
75510x7d14706e,
75520x81340004,
75530x2c080000,
75540x00098200,
75550x41820000,
75560x00050801,
75570x00000000,
75580x9114fff8,
75590x9134fffc,
75600x48000000,
75610x00070000,
75620x00000000,
75630x5580007e,
75640x000900ab,
75650x3e100000,
75660x00098200,
75670x7e100214,
75680x9114fff8,
75690x9134fffc,
75700x00000000,
75710x0006000b,
75720x80f00000,
75730x3a100004,
75740x54e815ba,
75750x7c11402e,
75760x7c0903a6,
75770x54ea5d78,
75780x54ec9b78,
75790x54f4dd78,
75800x54eb9d78,
75810x4e800420,
75820x00000000,
75830x5608fe7c,
75840x39080000,
75850x00098200,
75860x7d31422e,
75870x35290000,
75880x00098200,
75890x7d31432e,
75900x41800000,
75910x00050894,
75920x00000000,
75930x80f00000,
75940x3a100004,
75950x54e815ba,
75960x7c11402e,
75970x7c0903a6,
75980x54ea5d78,
75990x54ec9b78,
76000x54f4dd78,
76010x54eb9d78,
76020x4e800420,
76030x00000000,
76040x81110000,
76050x00098200,
76060x558c007e,
76070x000900ab,
76080x93110000,
76090x00098200,
76100x7d28602e,
76110x7c000400,
76120x81290000,
76130x00098200,
76140x91d10000,
76150x00098200,
76160x7d2903a6,
76170x92510000,
76180x00098200,
76190x3bf10000,
76200x00098200,
76210x4e800420,
76220x00000000,
76230x5580007e,
76240x000900ab,
76250x3e100000,
76260x00098200,
76270x7e100214,
76280x80f00000,
76290x3a100004,
76300x54e815ba,
76310x7c11402e,
76320x7c0903a6,
76330x54ea5d78,
76340x54ec9b78,
76350x54f4dd78,
76360x54eb9d78,
76370x4e800420,
76380x00000000,
76390x5608fe7c,
76400x39080000,
76410x00098200,
76420x7d31422e,
76430x35290000,
76440x00098200,
76450x7d31432e,
76460x41800000,
76470x00050896,
76480x00000000,
76490x81320000,
76500x00098200,
76510x89100000,
76520x00098200,
76530x81f00000,
76540x00098200,
76550x7c144840,
76560x55081800,
76570x000900a1,
76580x41810000,
76590x00050820,
76600x00000000,
76610x80f00000,
76620x3a100004,
76630x00000000,
76640x0006000c,
76650x7c0b4040,
76660x40810000,
76670x00050803,
76680x00000000,
76690x54ec9b78,
76700x48000000,
76710x00070000,
76720x00000000,
76730x54e815ba,
76740x7c11402e,
76750x7c0903a6,
76760x54ea5d78,
76770x54ec9b78,
76780x54f4dd78,
76790x54eb9d78,
76800x4e800420,
76810x00000000,
76820x0006000d,
76830x7eee592e,
76840x396b0008,
76850x48000000,
76860x0005000c,
76870x00000000,
76880x7c810808,
76890x00000000,
76900x81320000,
76910x00098200,
76920x7d0e5a14,
76930x7c145a14,
76940x91480004,
76950x38cb0000,
76960x00098200,
76970x81f00000,
76980x00098200,
76990x7c004840,
77000x90c80000,
77010x40800000,
77020x00050820,
77030x89300000,
77040x00098200,
77050x7dd47378,
77060x7d0b4378,
77070x80f00000,
77080x3a100004,
77090x2c090000,
77100x39c80008,
77110x41820000,
77120x00050803,
77130x0006000b,
77140x7c145840,
77150x80140000,
77160x80d40004,
77170x40800000,
77180x00050804,
77190x92f40000,
77200x3a940008,
77210x0006000c,
77220x3529ffff,
77230x90080008,
77240x90c8000c,
77250x39080008,
77260x40820000,
77270x0005080b,
77280x0006000d,
77290x54e815ba,
77300x7c11402e,
77310x7c0903a6,
77320x54ea5d78,
77330x54ec9b78,
77340x54f4dd78,
77350x54eb9d78,
77360x4e800420,
77370x0006000e,
77380x38000000,
77390x00098200,
77400x48000000,
77410x0005000c,
77420x00000000,
77430x80ca0000,
77440x00098200,
77450x00000000,
77460x80d10000,
77470x00098200,
77480x00000000,
77490x7d145a14,
77500x81320000,
77510x00098200,
77520x7d6e5a14,
77530x91d20000,
77540x00098200,
77550x7c084840,
77560x91720000,
77570x00098200,
77580x38000000,
77590x00098200,
77600x7cc903a6,
77610x00000000,
77620x808a0000,
77630x00098200,
77640x00000000,
77650x7e439378,
77660x41810000,
77670x0005081f,
77680x90110000,
77690x00098200,
77700x4e800421,
77710x81d20000,
77720x00098200,
77730x546c1800,
77740x000900a1,
77750x81120000,
77760x00098200,
77770x38000000,
77780x00098200,
77790x820efff8,
77800x7e8c4050,
77810x90110000,
77820x00098200,
77830x48000000,
77840x00050016,
77850x00000000,
77860x00010000
7787};
7788
7789enum {
7790 GLOB_vm_returnp,
7791 GLOB_cont_dispatch,
7792 GLOB_vm_returnc,
7793 GLOB_BC_RET_Z,
7794 GLOB_vm_return,
7795 GLOB_vm_leave_cp,
7796 GLOB_vm_leave_unw,
7797 GLOB_vm_unwind_c,
7798 GLOB_vm_unwind_c_eh,
7799 GLOB_vm_unwind_ff,
7800 GLOB_vm_unwind_ff_eh,
7801 GLOB_vm_growstack_c,
7802 GLOB_vm_growstack_l,
7803 GLOB_vm_resume,
7804 GLOB_vm_pcall,
7805 GLOB_vm_call,
7806 GLOB_vm_call_dispatch,
7807 GLOB_vmeta_call,
7808 GLOB_vm_call_dispatch_f,
7809 GLOB_vm_cpcall,
7810 GLOB_cont_ffi_callback,
7811 GLOB_vm_call_tail,
7812 GLOB_cont_cat,
7813 GLOB_BC_CAT_Z,
7814 GLOB_cont_nop,
7815 GLOB_vmeta_tgets1,
7816 GLOB_vmeta_tgets,
7817 GLOB_vmeta_tgetb,
7818 GLOB_vmeta_tgetv,
7819 GLOB_vmeta_tsets1,
7820 GLOB_vmeta_tsets,
7821 GLOB_vmeta_tsetb,
7822 GLOB_vmeta_tsetv,
7823 GLOB_vmeta_comp,
7824 GLOB_vmeta_binop,
7825 GLOB_cont_ra,
7826 GLOB_cont_condt,
7827 GLOB_cont_condf,
7828 GLOB_vmeta_equal,
7829 GLOB_vmeta_equal_cd,
7830 GLOB_vmeta_arith_nv,
7831 GLOB_vmeta_arith_nv2,
7832 GLOB_vmeta_unm,
7833 GLOB_vmeta_arith_vn,
7834 GLOB_vmeta_arith_vv,
7835 GLOB_vmeta_arith_vn2,
7836 GLOB_vmeta_arith_vv2,
7837 GLOB_vmeta_len,
7838 GLOB_BC_LEN_Z,
7839 GLOB_vmeta_callt,
7840 GLOB_BC_CALLT_Z,
7841 GLOB_vmeta_for,
7842 GLOB_ff_assert,
7843 GLOB_fff_fallback,
7844 GLOB_fff_res,
7845 GLOB_ff_type,
7846 GLOB_fff_resn,
7847 GLOB_ff_getmetatable,
7848 GLOB_fff_restv,
7849 GLOB_ff_setmetatable,
7850 GLOB_ff_rawget,
7851 GLOB_ff_tonumber,
7852 GLOB_ff_tostring,
7853 GLOB_fff_gcstep,
7854 GLOB_ff_next,
7855 GLOB_ff_pairs,
7856 GLOB_ff_ipairs_aux,
7857 GLOB_ff_ipairs,
7858 GLOB_ff_pcall,
7859 GLOB_ff_xpcall,
7860 GLOB_ff_coroutine_resume,
7861 GLOB_ff_coroutine_wrap_aux,
7862 GLOB_ff_coroutine_yield,
7863 GLOB_ff_math_abs,
7864 GLOB_fff_resi,
7865 GLOB_fff_res1,
7866 GLOB_ff_math_floor,
7867 GLOB_ff_math_ceil,
7868 GLOB_ff_math_sqrt,
7869 GLOB_ff_math_log,
7870 GLOB_ff_math_log10,
7871 GLOB_ff_math_exp,
7872 GLOB_ff_math_sin,
7873 GLOB_ff_math_cos,
7874 GLOB_ff_math_tan,
7875 GLOB_ff_math_asin,
7876 GLOB_ff_math_acos,
7877 GLOB_ff_math_atan,
7878 GLOB_ff_math_sinh,
7879 GLOB_ff_math_cosh,
7880 GLOB_ff_math_tanh,
7881 GLOB_ff_math_pow,
7882 GLOB_ff_math_atan2,
7883 GLOB_ff_math_fmod,
7884 GLOB_ff_math_deg,
7885 GLOB_ff_math_rad,
7886 GLOB_ff_math_ldexp,
7887 GLOB_ff_math_frexp,
7888 GLOB_ff_math_modf,
7889 GLOB_ff_math_min,
7890 GLOB_ff_math_max,
7891 GLOB_ff_string_len,
7892 GLOB_ff_string_byte,
7893 GLOB_ff_string_char,
7894 GLOB_fff_newstr,
7895 GLOB_ff_string_sub,
7896 GLOB_ff_string_rep,
7897 GLOB_ff_string_reverse,
7898 GLOB_ff_string_lower,
7899 GLOB_ff_string_upper,
7900 GLOB_ff_table_getn,
7901 GLOB_ff_bit_band,
7902 GLOB_fff_tobit_fb,
7903 GLOB_fff_bitop_fb,
7904 GLOB_ff_bit_bor,
7905 GLOB_ff_bit_bxor,
7906 GLOB_ff_bit_bswap,
7907 GLOB_ff_bit_bnot,
7908 GLOB_ff_bit_lshift,
7909 GLOB_ff_bit_rshift,
7910 GLOB_ff_bit_arshift,
7911 GLOB_ff_bit_rol,
7912 GLOB_ff_bit_ror,
7913 GLOB_ff_bit_tobit,
7914 GLOB_vm_record,
7915 GLOB_vm_rethook,
7916 GLOB_vm_inshook,
7917 GLOB_cont_hook,
7918 GLOB_vm_hotloop,
7919 GLOB_vm_callhook,
7920 GLOB_vm_hotcall,
7921 GLOB_vm_exit_handler,
7922 GLOB_vm_exit_interp,
7923 GLOB_vm_floor,
7924 GLOB_vm_ceil,
7925 GLOB_vm_trunc,
7926 GLOB_vm_modi,
7927 GLOB_vm_foldarith,
7928 GLOB_vm_ffi_callback,
7929 GLOB_vm_ffi_call,
7930 GLOB_BC_ISEQN_Z,
7931 GLOB_BC_ISNEN_Z,
7932 GLOB_BC_MODVN_Z,
7933 GLOB_BC_TGETS_Z,
7934 GLOB_BC_TSETS_Z,
7935 GLOB_BC_RETV_Z,
7936 GLOB__MAX
7937};
7938static const char *const globnames[] = {
7939 "vm_returnp",
7940 "cont_dispatch",
7941 "vm_returnc",
7942 "BC_RET_Z",
7943 "vm_return",
7944 "vm_leave_cp",
7945 "vm_leave_unw",
7946 "vm_unwind_c",
7947 "vm_unwind_c_eh",
7948 "vm_unwind_ff",
7949 "vm_unwind_ff_eh",
7950 "vm_growstack_c",
7951 "vm_growstack_l",
7952 "vm_resume",
7953 "vm_pcall",
7954 "vm_call",
7955 "vm_call_dispatch",
7956 "vmeta_call",
7957 "vm_call_dispatch_f",
7958 "vm_cpcall",
7959 "cont_ffi_callback",
7960 "vm_call_tail",
7961 "cont_cat",
7962 "BC_CAT_Z",
7963 "cont_nop",
7964 "vmeta_tgets1",
7965 "vmeta_tgets",
7966 "vmeta_tgetb",
7967 "vmeta_tgetv",
7968 "vmeta_tsets1",
7969 "vmeta_tsets",
7970 "vmeta_tsetb",
7971 "vmeta_tsetv",
7972 "vmeta_comp",
7973 "vmeta_binop",
7974 "cont_ra",
7975 "cont_condt",
7976 "cont_condf",
7977 "vmeta_equal",
7978 "vmeta_equal_cd",
7979 "vmeta_arith_nv",
7980 "vmeta_arith_nv2",
7981 "vmeta_unm",
7982 "vmeta_arith_vn",
7983 "vmeta_arith_vv",
7984 "vmeta_arith_vn2",
7985 "vmeta_arith_vv2",
7986 "vmeta_len",
7987 "BC_LEN_Z",
7988 "vmeta_callt",
7989 "BC_CALLT_Z",
7990 "vmeta_for",
7991 "ff_assert",
7992 "fff_fallback",
7993 "fff_res",
7994 "ff_type",
7995 "fff_resn",
7996 "ff_getmetatable",
7997 "fff_restv",
7998 "ff_setmetatable",
7999 "ff_rawget",
8000 "ff_tonumber",
8001 "ff_tostring",
8002 "fff_gcstep",
8003 "ff_next",
8004 "ff_pairs",
8005 "ff_ipairs_aux",
8006 "ff_ipairs",
8007 "ff_pcall",
8008 "ff_xpcall",
8009 "ff_coroutine_resume",
8010 "ff_coroutine_wrap_aux",
8011 "ff_coroutine_yield",
8012 "ff_math_abs",
8013 "fff_resi",
8014 "fff_res1",
8015 "ff_math_floor",
8016 "ff_math_ceil",
8017 "ff_math_sqrt",
8018 "ff_math_log",
8019 "ff_math_log10",
8020 "ff_math_exp",
8021 "ff_math_sin",
8022 "ff_math_cos",
8023 "ff_math_tan",
8024 "ff_math_asin",
8025 "ff_math_acos",
8026 "ff_math_atan",
8027 "ff_math_sinh",
8028 "ff_math_cosh",
8029 "ff_math_tanh",
8030 "ff_math_pow",
8031 "ff_math_atan2",
8032 "ff_math_fmod",
8033 "ff_math_deg",
8034 "ff_math_rad",
8035 "ff_math_ldexp",
8036 "ff_math_frexp",
8037 "ff_math_modf",
8038 "ff_math_min",
8039 "ff_math_max",
8040 "ff_string_len",
8041 "ff_string_byte",
8042 "ff_string_char",
8043 "fff_newstr",
8044 "ff_string_sub",
8045 "ff_string_rep",
8046 "ff_string_reverse",
8047 "ff_string_lower",
8048 "ff_string_upper",
8049 "ff_table_getn",
8050 "ff_bit_band",
8051 "fff_tobit_fb",
8052 "fff_bitop_fb",
8053 "ff_bit_bor",
8054 "ff_bit_bxor",
8055 "ff_bit_bswap",
8056 "ff_bit_bnot",
8057 "ff_bit_lshift",
8058 "ff_bit_rshift",
8059 "ff_bit_arshift",
8060 "ff_bit_rol",
8061 "ff_bit_ror",
8062 "ff_bit_tobit",
8063 "vm_record",
8064 "vm_rethook",
8065 "vm_inshook",
8066 "cont_hook",
8067 "vm_hotloop",
8068 "vm_callhook",
8069 "vm_hotcall",
8070 "vm_exit_handler",
8071 "vm_exit_interp",
8072 "vm_floor",
8073 "vm_ceil",
8074 "vm_trunc",
8075 "vm_modi",
8076 "vm_foldarith",
8077 "vm_ffi_callback",
8078 "vm_ffi_call",
8079 "BC_ISEQN_Z",
8080 "BC_ISNEN_Z",
8081 "BC_MODVN_Z",
8082 "BC_TGETS_Z",
8083 "BC_TSETS_Z",
8084 "BC_RETV_Z",
8085 (const char *)0
8086};
8087static const char *const extnames[] = {
8088 "lj_state_growstack",
8089 "lj_meta_tget",
8090 "lj_meta_tset",
8091 "lj_meta_comp",
8092 "lj_meta_equal",
8093 "lj_meta_equal_cd",
8094 "lj_meta_arith",
8095 "lj_meta_len",
8096 "lj_meta_call",
8097 "lj_meta_for",
8098 "lj_tab_get",
8099 "lj_str_fromnumber",
8100 "lj_str_fromnum",
8101 "lj_tab_next",
8102 "lj_tab_getinth",
8103 "lj_ffh_coroutine_wrap_err",
8104 "floor",
8105 "ceil",
8106 "sqrt",
8107 "log",
8108 "log10",
8109 "exp",
8110 "sin",
8111 "cos",
8112 "tan",
8113 "asin",
8114 "acos",
8115 "atan",
8116 "sinh",
8117 "cosh",
8118 "tanh",
8119 "pow",
8120 "atan2",
8121 "fmod",
8122 "ldexp",
8123 "frexp",
8124 "modf",
8125 "lj_str_new",
8126 "lj_tab_len",
8127 "lj_gc_step",
8128 "lj_dispatch_ins",
8129 "lj_trace_hot",
8130 "lj_dispatch_call",
8131 "lj_trace_exit",
8132 "lj_err_throw",
8133 "trunc",
8134 "lj_ccallback_enter",
8135 "lj_ccallback_leave",
8136 "lj_meta_cat",
8137 "lj_gc_barrieruv",
8138 "lj_func_closeuv",
8139 "lj_func_newL_gc",
8140 "lj_tab_new",
8141 "lj_tab_dup",
8142 "lj_gc_step_fixtop",
8143 "lj_tab_newkey",
8144 "lj_tab_reasize",
8145 (const char *)0
8146};
8147#define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V)
8148#define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V)
8149#define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V)
8150#define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V)
8151#define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V)
8152#define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V)
8153#define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V)
8154#define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V)
8155#define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V)
8156#define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V)
8157#define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V)
8158#define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V)
8159#define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V)
8160#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
8161#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
8162#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
8163
8164/* Generate subroutines used by opcodes and other parts of the VM. */
8165/* The .code_sub section should be last to help static branch prediction. */
8166static void build_subroutines(BuildCtx *ctx)
8167{
8168 dasm_put(Dst, 0);
8169 dasm_put(Dst, 1, FRAME_P, LJ_TTRUE, FRAME_TYPE, FRAME_C, ~LJ_VMST_C, Dt1(->base), DISPATCH_GL(vmstate), 31-3, Dt1(->top));
8170 dasm_put(Dst, 55, Dt1(->cframe), 56+(14-14)*4, 128+(14-14)*8, 56+(15-14)*4, 128+(15-14)*8, 56+(16-14)*4, 128+(16-14)*8, 56+(17-14)*4, 128+(17-14)*8, 56+(18-14)*4, 128+(18-14)*8, 56+(19-14)*4, 128+(19-14)*8, 56+(20-14)*4, 128+(20-14)*8, 56+(21-14)*4, 128+(21-14)*8, 56+(22-14)*4, 128+(22-14)*8, 56+(23-14)*4, 128+(23-14)*8);
8171 dasm_put(Dst, 105, 56+(24-14)*4, 128+(24-14)*8, 56+(25-14)*4, 128+(25-14)*8, 56+(26-14)*4, 128+(26-14)*8, 56+(27-14)*4, 128+(27-14)*8, 56+(28-14)*4, 128+(28-14)*8, 56+(29-14)*4, 128+(29-14)*8, 56+(30-14)*4, 128+(30-14)*8, 56+(31-14)*4, 128+(31-14)*8, Dt1(->maxstack));
8172 dasm_put(Dst, 154, Dt1(->top), 31-3, Dt1(->top), ~LJ_VMST_C, Dt1(->glref), Dt2(->vmstate), LJ_TISNUM, Dt1(->base), Dt1(->glref), LJ_TFALSE, LJ_TNIL, ~LJ_VMST_INTERP, GG_G2DISP);
8173 dasm_put(Dst, 217, DISPATCH_GL(vmstate), LUA_MINSTACK, Dt1(->base), Dt1(->top), 32-3, Dt1(->base), Dt1(->top), Dt7(->pc), 56+(14-14)*4, 128+(14-14)*8, 56+(15-14)*4, 128+(15-14)*8, 56+(16-14)*4, 128+(16-14)*8, 56+(17-14)*4);
8174 dasm_put(Dst, 278, 128+(17-14)*8, 56+(18-14)*4, 128+(18-14)*8, 56+(19-14)*4, 128+(19-14)*8, 56+(20-14)*4, 128+(20-14)*8, 56+(21-14)*4, 128+(21-14)*8, 56+(22-14)*4, 128+(22-14)*8, 56+(23-14)*4, 128+(23-14)*8, 56+(24-14)*4, 128+(24-14)*8, 56+(25-14)*4, 128+(25-14)*8, 56+(26-14)*4, 128+(26-14)*8, 56+(27-14)*4, 128+(27-14)*8, 56+(28-14)*4);
8175 dasm_put(Dst, 325, 128+(28-14)*8, 56+(29-14)*4, 128+(29-14)*8, 56+(30-14)*4, 128+(30-14)*8, 56+(31-14)*4, 128+(31-14)*8, Dt1(->glref), Dt1(->status), FRAME_CP, CFRAME_RESUME, GG_G2DISP, Dt1(->cframe), Dt1(->base), LJ_TISNUM, Dt1(->top), Dt1(->status), FRAME_TYPE, ~LJ_VMST_INTERP, LJ_TNIL, DISPATCH_GL(vmstate));
8176 dasm_put(Dst, 393, 56+(14-14)*4, 128+(14-14)*8, 56+(15-14)*4, 128+(15-14)*8, 56+(16-14)*4, 128+(16-14)*8, 56+(17-14)*4, 128+(17-14)*8, 56+(18-14)*4, 128+(18-14)*8, 56+(19-14)*4, 128+(19-14)*8, 56+(20-14)*4, 128+(20-14)*8, 56+(21-14)*4, 128+(21-14)*8, 56+(22-14)*4, 128+(22-14)*8, 56+(23-14)*4);
8177 dasm_put(Dst, 440, 128+(23-14)*8, 56+(24-14)*4, 128+(24-14)*8, 56+(25-14)*4, 128+(25-14)*8, 56+(26-14)*4, 128+(26-14)*8, 56+(27-14)*4, 128+(27-14)*8, 56+(28-14)*4, 128+(28-14)*8, 56+(29-14)*4, 128+(29-14)*8, 56+(30-14)*4, 128+(30-14)*8, 56+(31-14)*4, 128+(31-14)*8, FRAME_CP, 56+(14-14)*4, 128+(14-14)*8);
8178 dasm_put(Dst, 488, 56+(15-14)*4, 128+(15-14)*8, 56+(16-14)*4, 128+(16-14)*8, 56+(17-14)*4, 128+(17-14)*8, 56+(18-14)*4, 128+(18-14)*8, 56+(19-14)*4, 128+(19-14)*8, 56+(20-14)*4, 128+(20-14)*8, 56+(21-14)*4, 128+(21-14)*8, 56+(22-14)*4, 128+(22-14)*8, 56+(23-14)*4, 128+(23-14)*8, 56+(24-14)*4, 128+(24-14)*8, 56+(25-14)*4, 128+(25-14)*8);
8179 dasm_put(Dst, 535, 56+(26-14)*4, 128+(26-14)*8, 56+(27-14)*4, 128+(27-14)*8, 56+(28-14)*4, 128+(28-14)*8, 56+(29-14)*4, 128+(29-14)*8, 56+(30-14)*4, 128+(30-14)*8, 56+(31-14)*4, 128+(31-14)*8, FRAME_C, Dt1(->cframe), Dt1(->cframe), Dt1(->glref), GG_G2DISP, Dt1(->base), LJ_TISNUM, Dt1(->top));
8180 dasm_put(Dst, 586, ~LJ_VMST_INTERP, LJ_TNIL, DISPATCH_GL(vmstate), LJ_TFUNC, Dt7(->pc), 56+(14-14)*4, 128+(14-14)*8, 56+(15-14)*4, 128+(15-14)*8, 56+(16-14)*4, 128+(16-14)*8, 56+(17-14)*4, 128+(17-14)*8, 56+(18-14)*4, 128+(18-14)*8, 56+(19-14)*4, 128+(19-14)*8, 56+(20-14)*4);
8181 dasm_put(Dst, 653, 128+(20-14)*8, 56+(21-14)*4, 128+(21-14)*8, 56+(22-14)*4, 128+(22-14)*8, 56+(23-14)*4, 128+(23-14)*8, 56+(24-14)*4, 128+(24-14)*8, 56+(25-14)*4, 128+(25-14)*8, 56+(26-14)*4, 128+(26-14)*8, 56+(27-14)*4, 128+(27-14)*8, 56+(28-14)*4, 128+(28-14)*8, 56+(29-14)*4, 128+(29-14)*8, 56+(30-14)*4, 128+(30-14)*8, 56+(31-14)*4);
8182 dasm_put(Dst, 700, 128+(31-14)*8, Dt1(->stack), Dt1(->top), Dt1(->cframe), Dt1(->cframe), Dt1(->glref), FRAME_CP, GG_G2DISP);
8183#if LJ_HASFFI
8184 dasm_put(Dst, 738);
8185#endif
8186 dasm_put(Dst, 740, Dt7(->pc));
8187#if LJ_HASFFI
8188 dasm_put(Dst, 746);
8189#endif
8190 dasm_put(Dst, 749, PC2PROTO(k));
8191#if LJ_HASFFI
8192 dasm_put(Dst, 754);
8193#endif
8194 dasm_put(Dst, 762, Dt1(->base), DISPATCH_GL(tmptv), LJ_TSTR, DISPATCH_GL(tmptv), LJ_TTAB, DISPATCH_GL(tmptv2), LJ_TSTR);
8195 if (!LJ_DUALNUM) {
8196 dasm_put(Dst, 807);
8197 }
8198 dasm_put(Dst, 811, DISPATCH_GL(tmptv));
8199 if (LJ_DUALNUM) {
8200 dasm_put(Dst, 816);
8201 } else {
8202 dasm_put(Dst, 819);
8203 }
8204 dasm_put(Dst, 821, Dt1(->base), FRAME_CONT, Dt1(->top), DISPATCH_GL(tmptv), LJ_TSTR, DISPATCH_GL(tmptv), LJ_TTAB, DISPATCH_GL(tmptv2), LJ_TSTR);
8205 if (!LJ_DUALNUM) {
8206 dasm_put(Dst, 889);
8207 }
8208 dasm_put(Dst, 893, DISPATCH_GL(tmptv));
8209 if (LJ_DUALNUM) {
8210 dasm_put(Dst, 898);
8211 } else {
8212 dasm_put(Dst, 901);
8213 }
8214 dasm_put(Dst, 903, Dt1(->base), FRAME_CONT, Dt1(->top));
8215 if (LJ_DUALNUM) {
8216 dasm_put(Dst, 948);
8217 } else {
8218 dasm_put(Dst, 950);
8219 }
8220 dasm_put(Dst, 952);
8221 if (LJ_DUALNUM) {
8222 dasm_put(Dst, 954);
8223 } else {
8224 dasm_put(Dst, 956);
8225 }
8226 dasm_put(Dst, 958, Dt1(->base), -(BCBIAS_J*4 >> 16), LJ_TTRUE, LJ_TTRUE, Dt1(->base));
8227#if LJ_HASFFI
8228 dasm_put(Dst, 1021, Dt1(->base));
8229#endif
8230 dasm_put(Dst, 1032);
8231 if (LJ_DUALNUM) {
8232 dasm_put(Dst, 1039);
8233 }
8234 dasm_put(Dst, 1044);
8235 if (LJ_DUALNUM) {
8236 dasm_put(Dst, 1058);
8237 }
8238 dasm_put(Dst, 1061);
8239 if (LJ_DUALNUM) {
8240 dasm_put(Dst, 1064);
8241 }
8242 dasm_put(Dst, 1067, Dt1(->base), FRAME_CONT);
8243#ifdef LUAJIT_ENABLE_LUA52COMPAT
8244 dasm_put(Dst, 1091);
8245#endif
8246 dasm_put(Dst, 1093, Dt1(->base));
8247#ifdef LUAJIT_ENABLE_LUA52COMPAT
8248 dasm_put(Dst, 1101);
8249#else
8250 dasm_put(Dst, 1108);
8251#endif
8252 dasm_put(Dst, 1111, Dt1(->base), Dt7(->pc), Dt1(->base), Dt1(->base));
8253#if LJ_HASJIT
8254 dasm_put(Dst, 1159);
8255#endif
8256 dasm_put(Dst, 1161);
8257#if LJ_HASJIT
8258 dasm_put(Dst, 1163, BC_JFORI);
8259#endif
8260 dasm_put(Dst, 1166);
8261#if LJ_HASJIT
8262 dasm_put(Dst, 1168, BC_JFORI);
8263#endif
8264 dasm_put(Dst, 1171, BC_FORI, LJ_TFALSE, ~LJ_TISNUM+1, 31-3, Dt8(->upvalue), LJ_TTAB, Dt6(->metatable));
8265 dasm_put(Dst, 1234, LJ_TNIL, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable]), Dt6(->hmask), LJ_TTAB, Dt5(->hash), Dt6(->node), 31-5, 31-3, DtB(->key), 4+offsetof(Node, key), DtB(->val), 4+offsetof(Node, val), LJ_TSTR, DtB(->next));
8266 dasm_put(Dst, 1282, LJ_TNIL, LJ_TUDATA, ~LJ_TISNUM+1, 31-2, DISPATCH_GL(gcroot[GCROOT_BASEMT]), LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable));
8267 dasm_put(Dst, 1337, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist), LJ_TTAB, LJ_TSTR, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]), Dt1(->base));
8268 dasm_put(Dst, 1397, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
8269 if (LJ_DUALNUM) {
8270 dasm_put(Dst, 1407);
8271 } else {
8272 dasm_put(Dst, 1410);
8273 }
8274 dasm_put(Dst, 1413, LJ_TSTR, LJ_TTAB, Dt1(->base), Dt1(->top), LJ_TNIL, (2+1)*8, LJ_TTAB);
8275#ifdef LUAJIT_ENABLE_LUA52COMPAT
8276 dasm_put(Dst, 1464, Dt6(->metatable), Dt8(->upvalue[0]));
8277#else
8278 dasm_put(Dst, 1473, Dt8(->upvalue[0]));
8279#endif
8280 dasm_put(Dst, 1477, (3+1)*8);
8281 if (LJ_DUALNUM) {
8282 dasm_put(Dst, 1489);
8283 } else {
8284 dasm_put(Dst, 1491);
8285 }
8286 dasm_put(Dst, 1493, LJ_TTAB);
8287 if (LJ_DUALNUM) {
8288 dasm_put(Dst, 1500);
8289 } else {
8290 dasm_put(Dst, 1505);
8291 }
8292 dasm_put(Dst, 1517, Dt6(->asize), Dt6(->array));
8293 if (!LJ_DUALNUM) {
8294 dasm_put(Dst, 1522);
8295 }
8296 dasm_put(Dst, 1524);
8297 if (LJ_DUALNUM) {
8298 dasm_put(Dst, 1528, 31-3);
8299 } else {
8300 dasm_put(Dst, 1533, 31-3);
8301 }
8302 dasm_put(Dst, 1537, LJ_TNIL, (0+1)*8, (2+1)*8, Dt6(->hmask), (0+1)*8, (0+1)*8, LJ_TTAB);
8303#ifdef LUAJIT_ENABLE_LUA52COMPAT
8304 dasm_put(Dst, 1585, Dt6(->metatable), Dt8(->upvalue[0]));
8305#else
8306 dasm_put(Dst, 1594, Dt8(->upvalue[0]));
8307#endif
8308 if (LJ_DUALNUM) {
8309 dasm_put(Dst, 1598);
8310 } else {
8311 dasm_put(Dst, 1600);
8312 }
8313 dasm_put(Dst, 1602, (3+1)*8, DISPATCH_GL(hookmask), 32-HOOK_ACTIVE_SHIFT, 8+FRAME_PCALL, DISPATCH_GL(hookmask), LJ_TFUNC, 32-HOOK_ACTIVE_SHIFT, 16+FRAME_PCALL, LJ_TTHREAD, Dt1(->status), Dt1(->cframe));
8314 dasm_put(Dst, 1663, Dt1(->top), LUA_YIELD, Dt1(->base), Dt1(->maxstack), Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->base), LUA_YIELD, Dt1(->top), ~LJ_VMST_INTERP, Dt1(->base), DISPATCH_GL(vmstate));
8315 dasm_put(Dst, 1725, Dt1(->maxstack), Dt1(->top), FRAME_TYPE, LJ_TTRUE, FRAME_TYPE, LJ_TFALSE, Dt1(->top), (2+1)*8, 32-3);
8316 dasm_put(Dst, 1788, Dt8(->upvalue[0].gcr), Dt1(->status), Dt1(->cframe), Dt1(->top), LUA_YIELD, Dt1(->base), Dt1(->maxstack), Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->base), LUA_YIELD, Dt1(->top), ~LJ_VMST_INTERP);
8317 dasm_put(Dst, 1847, Dt1(->base), DISPATCH_GL(vmstate), Dt1(->maxstack), Dt1(->top), FRAME_TYPE, 32-3, Dt1(->cframe));
8318 dasm_put(Dst, 1904, Dt1(->base), CFRAME_RESUME, Dt1(->top), LUA_YIELD, Dt1(->cframe), Dt1(->status));
8319 if (LJ_DUALNUM) {
8320 dasm_put(Dst, 1929);
8321 }
8322 dasm_put(Dst, 1950, (1+1)*8, FRAME_TYPE);
8323 if (LJ_DUALNUM) {
8324 dasm_put(Dst, 1992, 31-11, 32-21, 31-11);
8325 dasm_put(Dst, 2074, 31-11, 32-21, 31-11);
8326 } else {
8327 dasm_put(Dst, 2128);
8328 }
8329 dasm_put(Dst, 2155);
8330 dasm_put(Dst, 2214);
8331 dasm_put(Dst, 2272);
8332 dasm_put(Dst, 2328, Dt8(->upvalue[0]));
8333 dasm_put(Dst, 2394);
8334 if (LJ_DUALNUM) {
8335 dasm_put(Dst, 2398);
8336 } else {
8337 dasm_put(Dst, 2413);
8338 }
8339 dasm_put(Dst, 2431, DISPATCH_GL(tmptv), DISPATCH_GL(tmptv));
8340 if (!LJ_DUALNUM) {
8341 dasm_put(Dst, 2453);
8342 }
8343 dasm_put(Dst, 2458, (2+1)*8);
8344 if (LJ_DUALNUM) {
8345 dasm_put(Dst, 2462);
8346 } else {
8347 dasm_put(Dst, 2465);
8348 }
8349 dasm_put(Dst, 2467, (2+1)*8);
8350 if (LJ_DUALNUM) {
8351 dasm_put(Dst, 2489);
8352 } else {
8353 dasm_put(Dst, 2558);
8354 }
8355 if (LJ_DUALNUM) {
8356 dasm_put(Dst, 2583);
8357 } else {
8358 dasm_put(Dst, 2652);
8359 }
8360 dasm_put(Dst, 2677, LJ_TSTR, Dt5(->len), LJ_TSTR, Dt5(->len));
8361 if (LJ_DUALNUM) {
8362 dasm_put(Dst, 2704, Dt5([1]), (0+1)*8);
8363 } else {
8364 dasm_put(Dst, 2716, Dt5([1]), 31-3);
8365 }
8366 dasm_put(Dst, 2732, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
8367 if (LJ_DUALNUM) {
8368 dasm_put(Dst, 2743);
8369 } else {
8370 dasm_put(Dst, 2751);
8371 }
8372 dasm_put(Dst, 2762, Dt1(->base), Dt1(->base), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
8373 if (!LJ_DUALNUM) {
8374 dasm_put(Dst, 2790);
8375 }
8376 dasm_put(Dst, 2792);
8377 if (LJ_DUALNUM) {
8378 dasm_put(Dst, 2798);
8379 } else {
8380 dasm_put(Dst, 2800);
8381 }
8382 dasm_put(Dst, 2802);
8383 if (LJ_DUALNUM) {
8384 dasm_put(Dst, 2806);
8385 } else {
8386 dasm_put(Dst, 2815);
8387 }
8388 dasm_put(Dst, 2826, LJ_TSTR);
8389 if (!LJ_DUALNUM) {
8390 dasm_put(Dst, 2831);
8391 }
8392 dasm_put(Dst, 2835, Dt5(->len), sizeof(GCstr)-1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
8393 if (LJ_DUALNUM) {
8394 dasm_put(Dst, 2885);
8395 } else {
8396 dasm_put(Dst, 2887);
8397 }
8398 dasm_put(Dst, 2889, LJ_TSTR);
8399 if (LJ_DUALNUM) {
8400 dasm_put(Dst, 2896);
8401 } else {
8402 dasm_put(Dst, 2900);
8403 }
8404 dasm_put(Dst, 2907, Dt5(->len), DISPATCH_GL(tmpbuf.sz), Dt5([1]), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(strempty), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, DISPATCH_GL(tmpbuf.sz));
8405 dasm_put(Dst, 2960, Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, DISPATCH_GL(tmpbuf.sz), Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
8406 dasm_put(Dst, 3018, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, DISPATCH_GL(tmpbuf.sz), Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf), LJ_TTAB);
8407 if (LJ_DUALNUM) {
8408 dasm_put(Dst, 3087);
8409 } else {
8410 dasm_put(Dst, 3097);
8411 }
8412 dasm_put(Dst, 3110);
8413 if (LJ_DUALNUM) {
8414 dasm_put(Dst, 3116);
8415 } else {
8416 dasm_put(Dst, 3118);
8417 }
8418 dasm_put(Dst, 3120);
8419 if (LJ_DUALNUM) {
8420 dasm_put(Dst, 3124);
8421 } else {
8422 dasm_put(Dst, 3127);
8423 }
8424 dasm_put(Dst, 3133);
8425 if (LJ_DUALNUM) {
8426 dasm_put(Dst, 3138);
8427 } else {
8428 dasm_put(Dst, 3148);
8429 }
8430 dasm_put(Dst, 3161);
8431 if (LJ_DUALNUM) {
8432 dasm_put(Dst, 3167);
8433 } else {
8434 dasm_put(Dst, 3169);
8435 }
8436 dasm_put(Dst, 3171);
8437 if (LJ_DUALNUM) {
8438 dasm_put(Dst, 3175);
8439 } else {
8440 dasm_put(Dst, 3178);
8441 }
8442 dasm_put(Dst, 3184);
8443 if (LJ_DUALNUM) {
8444 dasm_put(Dst, 3189);
8445 } else {
8446 dasm_put(Dst, 3199);
8447 }
8448 dasm_put(Dst, 3212);
8449 if (LJ_DUALNUM) {
8450 dasm_put(Dst, 3218);
8451 } else {
8452 dasm_put(Dst, 3220);
8453 }
8454 dasm_put(Dst, 3222);
8455 if (LJ_DUALNUM) {
8456 dasm_put(Dst, 3226);
8457 } else {
8458 dasm_put(Dst, 3229);
8459 }
8460 dasm_put(Dst, 3235);
8461 if (LJ_DUALNUM) {
8462 dasm_put(Dst, 3240);
8463 } else {
8464 dasm_put(Dst, 3250);
8465 }
8466 dasm_put(Dst, 3263);
8467 if (LJ_DUALNUM) {
8468 dasm_put(Dst, 3270);
8469 } else {
8470 dasm_put(Dst, 3280);
8471 }
8472 dasm_put(Dst, 3293);
8473 if (LJ_DUALNUM) {
8474 dasm_put(Dst, 3297);
8475 } else {
8476 dasm_put(Dst, 3312);
8477 }
8478 dasm_put(Dst, 3333);
8479 if (LJ_DUALNUM) {
8480 dasm_put(Dst, 3338);
8481 } else {
8482 dasm_put(Dst, 3353);
8483 }
8484 dasm_put(Dst, 3374);
8485 if (LJ_DUALNUM) {
8486 dasm_put(Dst, 3379);
8487 } else {
8488 dasm_put(Dst, 3394);
8489 }
8490 dasm_put(Dst, 3415);
8491 if (LJ_DUALNUM) {
8492 dasm_put(Dst, 3420);
8493 } else {
8494 dasm_put(Dst, 3435);
8495 }
8496 dasm_put(Dst, 3456);
8497 if (LJ_DUALNUM) {
8498 dasm_put(Dst, 3460);
8499 } else {
8500 dasm_put(Dst, 3475);
8501 }
8502 dasm_put(Dst, 3496);
8503 if (LJ_DUALNUM) {
8504 dasm_put(Dst, 3501);
8505 } else {
8506 dasm_put(Dst, 3511);
8507 }
8508 if (LJ_DUALNUM) {
8509 dasm_put(Dst, 3524);
8510 } else {
8511 dasm_put(Dst, 3527);
8512 }
8513 dasm_put(Dst, 3533);
8514 if (LJ_DUALNUM) {
8515 dasm_put(Dst, 3541);
8516 }
8517 dasm_put(Dst, 3549);
8518 if (LJ_DUALNUM) {
8519 dasm_put(Dst, 3551);
8520 }
8521 dasm_put(Dst, 3559, Dt8(->f), 8*LUA_MINSTACK, Dt1(->maxstack), Dt1(->base), Dt1(->top), Dt1(->base), 31-3, Dt1(->top), Dt7(->pc), FRAME_TYPE, LUA_MINSTACK);
8522 dasm_put(Dst, 3622, Dt1(->base), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
8523#if LJ_HASJIT
8524 dasm_put(Dst, 3648, DISPATCH_GL(hookmask), HOOK_VMEVENT, DISPATCH_GL(hookcount), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount));
8525#endif
8526 dasm_put(Dst, 3670, DISPATCH_GL(hookmask), HOOK_ACTIVE, GG_DISP2STATIC, DISPATCH_GL(hookmask), DISPATCH_GL(hookcount), HOOK_ACTIVE, 31-LUA_HOOKLINE, DISPATCH_GL(hookcount), Dt1(->base), Dt1(->base));
8527 dasm_put(Dst, 3717, GG_DISP2STATIC);
8528#if LJ_HASJIT
8529 dasm_put(Dst, 3735, GG_DISP2J, Dt7(->pc), DISPATCH_J(L), PC2PROTO(framesize), Dt1(->base), 31-3, Dt1(->top));
8530#endif
8531 dasm_put(Dst, 3758);
8532#if LJ_HASJIT
8533 dasm_put(Dst, 3761);
8534#endif
8535 dasm_put(Dst, 3764);
8536#if LJ_HASJIT
8537 dasm_put(Dst, 3766);
8538#endif
8539 dasm_put(Dst, 3769, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
8540#if LJ_HASJIT
8541 dasm_put(Dst, 3792, -(16+32*8+32*4), 16+32*8+2*4, -GG_DISP2G-32768, ~LJ_VMST_EXIT, 16+32*8+32*4, DISPATCH_GL(vmstate), 16+0*8, 16+1*8, 16+2*8, 16+3*8, 16+4*8, 16+5*8, 16+6*8, 16+7*8, 16+32*8+32*4, 16+8*8, 16+9*8, 16+10*8, 16+11*8, 16+32*8+1*4, 16+12*8, 16+13*8);
8542 dasm_put(Dst, 3839, 16+14*8, 16+15*8, 16+16*8, 16+17*8, 16+18*8, 16+19*8, 16+32*8+0*4, 16+20*8, 16+21*8, 16+22*8, 16+23*8, 16+24*8, 16+25*8, 16+26*8, 16+27*8, DISPATCH_GL(jit_L), 16+28*8, 16+29*8, 16+30*8, 16+31*8, DISPATCH_GL(jit_base), 32-2);
8543 dasm_put(Dst, 3888, DISPATCH_J(L), DISPATCH_GL(jit_L), DISPATCH_J(parent), Dt1(->base), GG_DISP2J, DISPATCH_J(exitno), Dt1(->cframe), Dt1(->base));
8544#endif
8545 dasm_put(Dst, 3916);
8546#if LJ_HASJIT
8547 dasm_put(Dst, 3918, -GG_DISP2G-32768, 31-3, Dt7(->pc), DISPATCH_GL(jit_L), PC2PROTO(k), LJ_TISNUM, LJ_TNIL, DISPATCH_GL(vmstate), BC_FUNCF*4);
8548#endif
8549 dasm_put(Dst, 3975);
8550#if LJ_HASJIT
8551 dasm_put(Dst, 3983);
8552#endif
8553 dasm_put(Dst, 3986);
8554#if LJ_HASJIT
8555 dasm_put(Dst, 4066);
8556#else
8557 dasm_put(Dst, 4088);
8558#endif
8559 dasm_put(Dst, 4090);
8560#if LJ_HASFFI
8561#define DtE(_V) (int)(ptrdiff_t)&(((CTState *)0)_V)
8562 dasm_put(Dst, 4092, 56+(14-14)*4, 128+(14-14)*8, 56+(15-14)*4, 128+(15-14)*8, 56+(16-14)*4, 128+(16-14)*8, 56+(17-14)*4, 128+(17-14)*8, 56+(18-14)*4, 128+(18-14)*8, 56+(19-14)*4, 128+(19-14)*8, 56+(20-14)*4, 128+(20-14)*8, 56+(21-14)*4, 128+(21-14)*8, 56+(22-14)*4, 128+(22-14)*8, 56+(23-14)*4, 128+(23-14)*8, 56+(24-14)*4, 128+(24-14)*8);
8563 dasm_put(Dst, 4140, 56+(25-14)*4, 128+(25-14)*8, 56+(26-14)*4, 128+(26-14)*8, 56+(27-14)*4, 128+(27-14)*8, 56+(28-14)*4, 128+(28-14)*8, 56+(29-14)*4, 128+(29-14)*8, 56+(30-14)*4, 128+(30-14)*8, 56+(31-14)*4, 128+(31-14)*8, Dt2(->ctype_state), GG_G2DISP, DtE(->cb.slot), DtE(->cb.gpr[0]), DtE(->cb.fpr[0]), DtE(->cb.gpr[1]), DtE(->cb.fpr[1]), DtE(->cb.gpr[2]));
8564 dasm_put(Dst, 4187, DtE(->cb.fpr[2]), DtE(->cb.gpr[3]), DtE(->cb.fpr[3]), DtE(->cb.gpr[4]), DtE(->cb.fpr[4]), DtE(->cb.gpr[5]), DtE(->cb.fpr[5]), DtE(->cb.gpr[6]), DtE(->cb.fpr[6]), DtE(->cb.gpr[7]), DtE(->cb.fpr[7]), 272+8, DtE(->cb.stack), Dt1(->base), LJ_TISNUM, Dt1(->top), LJ_TNIL, ~LJ_VMST_INTERP, DISPATCH_GL(vmstate), Dt7(->pc));
8565#endif
8566 dasm_put(Dst, 4251);
8567#if LJ_HASFFI
8568 dasm_put(Dst, 4253, DISPATCH_GL(ctype_state), Dt1(->base), Dt1(->top), DtE(->L), DtE(->cb.gpr[0]), DtE(->cb.fpr[0]), DtE(->cb.gpr[1]));
8569#endif
8570 dasm_put(Dst, 4274);
8571#if LJ_HASFFI
8572#define DtF(_V) (int)(ptrdiff_t)&(((CCallState *)0)_V)
8573 dasm_put(Dst, 4276, DtF(->spadj), DtF(->nsp), DtF(->nfpr), DtF(->stack), 31-2, DtF(->fpr[0]), DtF(->fpr[1]), DtF(->fpr[2]), DtF(->fpr[3]), DtF(->fpr[4]), DtF(->fpr[5]), DtF(->fpr[6]), DtF(->fpr[7]), DtF(->func), DtF(->gpr[1]), DtF(->gpr[2]));
8574 dasm_put(Dst, 4334, DtF(->gpr[3]), DtF(->gpr[4]), DtF(->gpr[5]), DtF(->gpr[6]), DtF(->gpr[7]), DtF(->gpr[0]), DtF(->gpr[0]), DtF(->fpr[0]), DtF(->gpr[1]), DtF(->gpr[2]), DtF(->gpr[3]));
8575#endif
8576}
8577
8578/* Generate the code for a single instruction. */
8579static void build_ins(BuildCtx *ctx, BCOp op, int defop)
8580{
8581 int vk = 0;
8582 dasm_put(Dst, 4366, defop);
8583
8584 switch (op) {
8585
8586 /* -- Comparison ops ---------------------------------------------------- */
8587
8588 /* Remember: all ops branch for a true comparison, fall through otherwise. */
8589
8590 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
8591 if (LJ_DUALNUM) {
8592 dasm_put(Dst, 4368, -(BCBIAS_J*4 >> 16));
8593 if (op == BC_ISLT) {
8594 dasm_put(Dst, 4385);
8595 } else if (op == BC_ISGE) {
8596 dasm_put(Dst, 4388);
8597 } else if (op == BC_ISLE) {
8598 dasm_put(Dst, 4391);
8599 } else {
8600 dasm_put(Dst, 4394);
8601 }
8602 dasm_put(Dst, 4397);
8603 if (op == BC_ISLT) {
8604 dasm_put(Dst, 4436);
8605 } else if (op == BC_ISGE) {
8606 dasm_put(Dst, 4439);
8607 } else if (op == BC_ISLE) {
8608 dasm_put(Dst, 4442);
8609 } else {
8610 dasm_put(Dst, 4446);
8611 }
8612 dasm_put(Dst, 4450);
8613 } else {
8614 dasm_put(Dst, 4453, -(BCBIAS_J*4 >> 16));
8615 if (op == BC_ISLT) {
8616 dasm_put(Dst, 4470);
8617 } else if (op == BC_ISGE) {
8618 dasm_put(Dst, 4473);
8619 } else if (op == BC_ISLE) {
8620 dasm_put(Dst, 4476);
8621 } else {
8622 dasm_put(Dst, 4480);
8623 }
8624 dasm_put(Dst, 4484);
8625 }
8626 break;
8627
8628 case BC_ISEQV: case BC_ISNEV:
8629 vk = op == BC_ISEQV;
8630 if (LJ_DUALNUM) {
8631 dasm_put(Dst, 4497, -(BCBIAS_J*4 >> 16));
8632 if (vk) {
8633 dasm_put(Dst, 4510);
8634 } else {
8635 dasm_put(Dst, 4513);
8636 }
8637 } else {
8638 dasm_put(Dst, 4516, -(BCBIAS_J*4 >> 16));
8639 if (vk) {
8640 dasm_put(Dst, 4533);
8641 } else {
8642 dasm_put(Dst, 4537);
8643 }
8644 dasm_put(Dst, 4541);
8645 }
8646 dasm_put(Dst, 4553);
8647 if (!LJ_DUALNUM) {
8648 dasm_put(Dst, 4555);
8649 }
8650 if (LJ_HASFFI) {
8651 dasm_put(Dst, 4558, LJ_TCDATA, LJ_TCDATA);
8652 }
8653 dasm_put(Dst, 4563, ~LJ_TISPRI);
8654 if (LJ_HASFFI) {
8655 dasm_put(Dst, 4568);
8656 }
8657 dasm_put(Dst, 4570, ~LJ_TISTABUD);
8658 if (LJ_HASFFI) {
8659 dasm_put(Dst, 4573);
8660 }
8661 dasm_put(Dst, 4576);
8662 if (vk) {
8663 dasm_put(Dst, 4584);
8664 } else {
8665 dasm_put(Dst, 4589);
8666 }
8667 if (LJ_DUALNUM) {
8668 dasm_put(Dst, 4594);
8669 } else {
8670 dasm_put(Dst, 4609);
8671 }
8672 dasm_put(Dst, 4612, Dt6(->metatable), 1-vk, Dt6(->nomm), 1<<MM_eq);
8673 break;
8674
8675 case BC_ISEQS: case BC_ISNES:
8676 vk = op == BC_ISEQS;
8677 dasm_put(Dst, 4631, 32-1);
8678 if (LJ_HASFFI) {
8679 dasm_put(Dst, 4639, LJ_TCDATA);
8680 }
8681 dasm_put(Dst, 4642, LJ_TSTR);
8682 if (LJ_HASFFI) {
8683 dasm_put(Dst, 4646);
8684 }
8685 dasm_put(Dst, 4649, -(BCBIAS_J*4 >> 16));
8686 if (vk) {
8687 dasm_put(Dst, 4657);
8688 } else {
8689 dasm_put(Dst, 4659);
8690 }
8691 dasm_put(Dst, 4661);
8692 break;
8693
8694 case BC_ISEQN: case BC_ISNEN:
8695 vk = op == BC_ISEQN;
8696 if (LJ_DUALNUM) {
8697 dasm_put(Dst, 4673, -(BCBIAS_J*4 >> 16));
8698 if (vk) {
8699 dasm_put(Dst, 4685);
8700 } else {
8701 dasm_put(Dst, 4687);
8702 }
8703 dasm_put(Dst, 4689);
8704 } else {
8705 if (vk) {
8706 dasm_put(Dst, 4696);
8707 } else {
8708 dasm_put(Dst, 4698);
8709 }
8710 dasm_put(Dst, 4700, -(BCBIAS_J*4 >> 16));
8711 }
8712 if (vk) {
8713 dasm_put(Dst, 4713);
8714 if (!LJ_HASFFI) {
8715 dasm_put(Dst, 4718);
8716 }
8717 } else {
8718 dasm_put(Dst, 4720);
8719 if (!LJ_HASFFI) {
8720 dasm_put(Dst, 4724);
8721 }
8722 dasm_put(Dst, 4726);
8723 }
8724 dasm_put(Dst, 4729);
8725 if (LJ_HASFFI) {
8726 dasm_put(Dst, 4740, LJ_TCDATA);
8727 }
8728 if (LJ_DUALNUM) {
8729 dasm_put(Dst, 4748);
8730 }
8731 break;
8732
8733 case BC_ISEQP: case BC_ISNEP:
8734 vk = op == BC_ISEQP;
8735 dasm_put(Dst, 4772, 32-3);
8736 if (LJ_HASFFI) {
8737 dasm_put(Dst, 4779, LJ_TCDATA);
8738 }
8739 dasm_put(Dst, 4782);
8740 if (LJ_HASFFI) {
8741 dasm_put(Dst, 4784);
8742 }
8743 dasm_put(Dst, 4787, -(BCBIAS_J*4 >> 16));
8744 if (vk) {
8745 dasm_put(Dst, 4793);
8746 } else {
8747 dasm_put(Dst, 4795);
8748 }
8749 dasm_put(Dst, 4797);
8750 break;
8751
8752 /* -- Unary test and copy ops ------------------------------------------- */
8753
8754 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
8755 dasm_put(Dst, 4809);
8756 if (op == BC_IST || op == BC_ISF) {
8757 dasm_put(Dst, 4813, LJ_TTRUE, -(BCBIAS_J*4 >> 16));
8758 if (op == BC_IST) {
8759 dasm_put(Dst, 4820);
8760 } else {
8761 dasm_put(Dst, 4822);
8762 }
8763 dasm_put(Dst, 4824);
8764 } else {
8765 dasm_put(Dst, 4826, LJ_TFALSE);
8766 if (op == BC_ISTC) {
8767 dasm_put(Dst, 4831);
8768 } else {
8769 dasm_put(Dst, 4834);
8770 }
8771 dasm_put(Dst, 4837, -(BCBIAS_J*4 >> 16));
8772 }
8773 dasm_put(Dst, 4844);
8774 break;
8775
8776 /* -- Unary ops --------------------------------------------------------- */
8777
8778 case BC_MOV:
8779 dasm_put(Dst, 4855);
8780 break;
8781 case BC_NOT:
8782 dasm_put(Dst, 4868, LJ_TTRUE);
8783 break;
8784 case BC_UNM:
8785 dasm_put(Dst, 4884);
8786 if (LJ_DUALNUM) {
8787 dasm_put(Dst, 4888);
8788 }
8789 dasm_put(Dst, 4916);
8790 if (LJ_DUALNUM) {
8791 dasm_put(Dst, 4926);
8792 } else {
8793 dasm_put(Dst, 4929);
8794 }
8795 break;
8796 case BC_LEN:
8797 dasm_put(Dst, 4938, LJ_TSTR, Dt5(->len));
8798 if (LJ_DUALNUM) {
8799 dasm_put(Dst, 4948);
8800 } else {
8801 dasm_put(Dst, 4953);
8802 }
8803 dasm_put(Dst, 4960, LJ_TTAB);
8804#ifdef LUAJIT_ENABLE_LUA52COMPAT
8805 dasm_put(Dst, 4974, Dt6(->metatable));
8806#endif
8807 dasm_put(Dst, 4981);
8808#ifdef LUAJIT_ENABLE_LUA52COMPAT
8809 dasm_put(Dst, 4987, Dt6(->nomm), 1<<MM_len);
8810#endif
8811 break;
8812
8813 /* -- Binary ops -------------------------------------------------------- */
8814
8815
8816 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
8817 if (LJ_DUALNUM) {
8818 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
8819 switch (vk) {
8820 case 0:
8821 dasm_put(Dst, 4997);
8822 break;
8823 case 1:
8824 dasm_put(Dst, 5003);
8825 break;
8826 default:
8827 dasm_put(Dst, 5009);
8828 break;
8829 }
8830 dasm_put(Dst, 5015);
8831 switch (vk) {
8832 case 0:
8833 dasm_put(Dst, 5042);
8834 break;
8835 case 1:
8836 dasm_put(Dst, 5045);
8837 break;
8838 default:
8839 dasm_put(Dst, 5048);
8840 break;
8841 }
8842 dasm_put(Dst, 5051);
8843 if (vk == 1) {
8844 dasm_put(Dst, 5053);
8845 } else {
8846 dasm_put(Dst, 5057);
8847 }
8848 switch (vk) {
8849 case 0:
8850 dasm_put(Dst, 5061);
8851 break;
8852 case 1:
8853 dasm_put(Dst, 5064);
8854 break;
8855 default:
8856 dasm_put(Dst, 5067);
8857 break;
8858 }
8859 dasm_put(Dst, 5070);
8860 } else {
8861 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
8862 switch (vk) {
8863 case 0:
8864 dasm_put(Dst, 5077);
8865 if (LJ_DUALNUM) {
8866 dasm_put(Dst, 5079);
8867 }
8868 dasm_put(Dst, 5081);
8869 if (LJ_DUALNUM) {
8870 dasm_put(Dst, 5084);
8871 } else {
8872 dasm_put(Dst, 5090);
8873 }
8874 break;
8875 case 1:
8876 dasm_put(Dst, 5094);
8877 if (LJ_DUALNUM) {
8878 dasm_put(Dst, 5096);
8879 }
8880 dasm_put(Dst, 5098);
8881 if (LJ_DUALNUM) {
8882 dasm_put(Dst, 5101);
8883 } else {
8884 dasm_put(Dst, 5107);
8885 }
8886 break;
8887 default:
8888 dasm_put(Dst, 5111);
8889 break;
8890 }
8891 dasm_put(Dst, 5121);
8892 }
8893 break;
8894 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
8895 if (LJ_DUALNUM) {
8896 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
8897 switch (vk) {
8898 case 0:
8899 dasm_put(Dst, 5134);
8900 break;
8901 case 1:
8902 dasm_put(Dst, 5140);
8903 break;
8904 default:
8905 dasm_put(Dst, 5146);
8906 break;
8907 }
8908 dasm_put(Dst, 5152);
8909 switch (vk) {
8910 case 0:
8911 dasm_put(Dst, 5179);
8912 break;
8913 case 1:
8914 dasm_put(Dst, 5182);
8915 break;
8916 default:
8917 dasm_put(Dst, 5185);
8918 break;
8919 }
8920 dasm_put(Dst, 5188);
8921 if (vk == 1) {
8922 dasm_put(Dst, 5190);
8923 } else {
8924 dasm_put(Dst, 5194);
8925 }
8926 switch (vk) {
8927 case 0:
8928 dasm_put(Dst, 5198);
8929 break;
8930 case 1:
8931 dasm_put(Dst, 5201);
8932 break;
8933 default:
8934 dasm_put(Dst, 5204);
8935 break;
8936 }
8937 dasm_put(Dst, 5207);
8938 } else {
8939 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
8940 switch (vk) {
8941 case 0:
8942 dasm_put(Dst, 5214);
8943 if (LJ_DUALNUM) {
8944 dasm_put(Dst, 5216);
8945 }
8946 dasm_put(Dst, 5218);
8947 if (LJ_DUALNUM) {
8948 dasm_put(Dst, 5221);
8949 } else {
8950 dasm_put(Dst, 5227);
8951 }
8952 break;
8953 case 1:
8954 dasm_put(Dst, 5231);
8955 if (LJ_DUALNUM) {
8956 dasm_put(Dst, 5233);
8957 }
8958 dasm_put(Dst, 5235);
8959 if (LJ_DUALNUM) {
8960 dasm_put(Dst, 5238);
8961 } else {
8962 dasm_put(Dst, 5244);
8963 }
8964 break;
8965 default:
8966 dasm_put(Dst, 5248);
8967 break;
8968 }
8969 dasm_put(Dst, 5258);
8970 }
8971 break;
8972 case BC_MULVN: case BC_MULNV: case BC_MULVV:
8973 if (LJ_DUALNUM) {
8974 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
8975 switch (vk) {
8976 case 0:
8977 dasm_put(Dst, 5271);
8978 break;
8979 case 1:
8980 dasm_put(Dst, 5277);
8981 break;
8982 default:
8983 dasm_put(Dst, 5283);
8984 break;
8985 }
8986 dasm_put(Dst, 5289);
8987 switch (vk) {
8988 case 0:
8989 dasm_put(Dst, 5316);
8990 break;
8991 case 1:
8992 dasm_put(Dst, 5319);
8993 break;
8994 default:
8995 dasm_put(Dst, 5322);
8996 break;
8997 }
8998 dasm_put(Dst, 5325);
8999 if (vk == 1) {
9000 dasm_put(Dst, 5327);
9001 } else {
9002 dasm_put(Dst, 5331);
9003 }
9004 switch (vk) {
9005 case 0:
9006 dasm_put(Dst, 5335);
9007 break;
9008 case 1:
9009 dasm_put(Dst, 5338);
9010 break;
9011 default:
9012 dasm_put(Dst, 5341);
9013 break;
9014 }
9015 dasm_put(Dst, 5344);
9016 } else {
9017 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
9018 switch (vk) {
9019 case 0:
9020 dasm_put(Dst, 5351);
9021 if (LJ_DUALNUM) {
9022 dasm_put(Dst, 5353);
9023 }
9024 dasm_put(Dst, 5355);
9025 if (LJ_DUALNUM) {
9026 dasm_put(Dst, 5358);
9027 } else {
9028 dasm_put(Dst, 5364);
9029 }
9030 break;
9031 case 1:
9032 dasm_put(Dst, 5368);
9033 if (LJ_DUALNUM) {
9034 dasm_put(Dst, 5370);
9035 }
9036 dasm_put(Dst, 5372);
9037 if (LJ_DUALNUM) {
9038 dasm_put(Dst, 5375);
9039 } else {
9040 dasm_put(Dst, 5381);
9041 }
9042 break;
9043 default:
9044 dasm_put(Dst, 5385);
9045 break;
9046 }
9047 dasm_put(Dst, 5395);
9048 }
9049 break;
9050 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
9051 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
9052 switch (vk) {
9053 case 0:
9054 dasm_put(Dst, 5408);
9055 if (LJ_DUALNUM) {
9056 dasm_put(Dst, 5410);
9057 }
9058 dasm_put(Dst, 5412);
9059 if (LJ_DUALNUM) {
9060 dasm_put(Dst, 5415);
9061 } else {
9062 dasm_put(Dst, 5421);
9063 }
9064 break;
9065 case 1:
9066 dasm_put(Dst, 5425);
9067 if (LJ_DUALNUM) {
9068 dasm_put(Dst, 5427);
9069 }
9070 dasm_put(Dst, 5429);
9071 if (LJ_DUALNUM) {
9072 dasm_put(Dst, 5432);
9073 } else {
9074 dasm_put(Dst, 5438);
9075 }
9076 break;
9077 default:
9078 dasm_put(Dst, 5442);
9079 break;
9080 }
9081 dasm_put(Dst, 5452);
9082 break;
9083 case BC_MODVN:
9084 if (LJ_DUALNUM) {
9085 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
9086 switch (vk) {
9087 case 0:
9088 dasm_put(Dst, 5465);
9089 break;
9090 case 1:
9091 dasm_put(Dst, 5471);
9092 break;
9093 default:
9094 dasm_put(Dst, 5477);
9095 break;
9096 }
9097 dasm_put(Dst, 5483);
9098 switch (vk) {
9099 case 0:
9100 dasm_put(Dst, 5511);
9101 break;
9102 case 1:
9103 dasm_put(Dst, 5514);
9104 break;
9105 default:
9106 dasm_put(Dst, 5517);
9107 break;
9108 }
9109 dasm_put(Dst, 5520);
9110 if (vk == 1) {
9111 dasm_put(Dst, 5522);
9112 } else {
9113 dasm_put(Dst, 5526);
9114 }
9115 switch (vk) {
9116 case 0:
9117 dasm_put(Dst, 5530);
9118 break;
9119 case 1:
9120 dasm_put(Dst, 5533);
9121 break;
9122 default:
9123 dasm_put(Dst, 5536);
9124 break;
9125 }
9126 dasm_put(Dst, 5539);
9127 } else {
9128 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
9129 switch (vk) {
9130 case 0:
9131 dasm_put(Dst, 5551);
9132 if (LJ_DUALNUM) {
9133 dasm_put(Dst, 5553);
9134 }
9135 dasm_put(Dst, 5555);
9136 if (LJ_DUALNUM) {
9137 dasm_put(Dst, 5558);
9138 } else {
9139 dasm_put(Dst, 5564);
9140 }
9141 break;
9142 case 1:
9143 dasm_put(Dst, 5568);
9144 if (LJ_DUALNUM) {
9145 dasm_put(Dst, 5570);
9146 }
9147 dasm_put(Dst, 5572);
9148 if (LJ_DUALNUM) {
9149 dasm_put(Dst, 5575);
9150 } else {
9151 dasm_put(Dst, 5581);
9152 }
9153 break;
9154 default:
9155 dasm_put(Dst, 5585);
9156 break;
9157 }
9158 dasm_put(Dst, 5595);
9159 }
9160 break;
9161 case BC_MODNV: case BC_MODVV:
9162 if (LJ_DUALNUM) {
9163 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
9164 switch (vk) {
9165 case 0:
9166 dasm_put(Dst, 5613);
9167 break;
9168 case 1:
9169 dasm_put(Dst, 5619);
9170 break;
9171 default:
9172 dasm_put(Dst, 5625);
9173 break;
9174 }
9175 dasm_put(Dst, 5631);
9176 switch (vk) {
9177 case 0:
9178 dasm_put(Dst, 5659);
9179 break;
9180 case 1:
9181 dasm_put(Dst, 5662);
9182 break;
9183 default:
9184 dasm_put(Dst, 5665);
9185 break;
9186 }
9187 dasm_put(Dst, 5668);
9188 if (vk == 1) {
9189 dasm_put(Dst, 5670);
9190 } else {
9191 dasm_put(Dst, 5674);
9192 }
9193 switch (vk) {
9194 case 0:
9195 dasm_put(Dst, 5678);
9196 break;
9197 case 1:
9198 dasm_put(Dst, 5681);
9199 break;
9200 default:
9201 dasm_put(Dst, 5684);
9202 break;
9203 }
9204 dasm_put(Dst, 5687);
9205 } else {
9206 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
9207 switch (vk) {
9208 case 0:
9209 dasm_put(Dst, 5690);
9210 if (LJ_DUALNUM) {
9211 dasm_put(Dst, 5692);
9212 }
9213 dasm_put(Dst, 5694);
9214 if (LJ_DUALNUM) {
9215 dasm_put(Dst, 5697);
9216 } else {
9217 dasm_put(Dst, 5703);
9218 }
9219 break;
9220 case 1:
9221 dasm_put(Dst, 5707);
9222 if (LJ_DUALNUM) {
9223 dasm_put(Dst, 5709);
9224 }
9225 dasm_put(Dst, 5711);
9226 if (LJ_DUALNUM) {
9227 dasm_put(Dst, 5714);
9228 } else {
9229 dasm_put(Dst, 5720);
9230 }
9231 break;
9232 default:
9233 dasm_put(Dst, 5724);
9234 break;
9235 }
9236 dasm_put(Dst, 5734);
9237 }
9238 break;
9239 case BC_POW:
9240 dasm_put(Dst, 5737);
9241 break;
9242
9243 case BC_CAT:
9244 dasm_put(Dst, 5760, Dt1(->base), 32-3, Dt1(->base));
9245 break;
9246
9247 /* -- Constant ops ------------------------------------------------------ */
9248
9249 case BC_KSTR:
9250 dasm_put(Dst, 5790, 32-1, LJ_TSTR);
9251 break;
9252 case BC_KCDATA:
9253#if LJ_HASFFI
9254 dasm_put(Dst, 5809, 32-1, LJ_TCDATA);
9255#endif
9256 break;
9257 case BC_KSHORT:
9258 if (LJ_DUALNUM) {
9259 dasm_put(Dst, 5828, 31-13);
9260 } else {
9261 dasm_put(Dst, 5844, 31-13, 31-20);
9262 }
9263 break;
9264 case BC_KNUM:
9265 dasm_put(Dst, 5872);
9266 break;
9267 case BC_KPRI:
9268 dasm_put(Dst, 5885, 32-3);
9269 break;
9270 case BC_KNIL:
9271 dasm_put(Dst, 5900);
9272 break;
9273
9274 /* -- Upvalue and function ops ------------------------------------------ */
9275
9276 case BC_UGET:
9277 dasm_put(Dst, 5919, 32-1, offsetof(GCfuncL, uvptr), DtA(->v));
9278 break;
9279 case BC_USETV:
9280 dasm_put(Dst, 5940, 32-1, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, DtA(->closed), -(LJ_TISNUM+1), LJ_TISGCV - (LJ_TISNUM+1), Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
9281 break;
9282 case BC_USETS:
9283 dasm_put(Dst, 5993, 32-1, 32-1, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, Dt5(->marked), DtA(->closed), LJ_TSTR, LJ_GC_WHITES, GG_DISP2G);
9284 break;
9285 case BC_USETN:
9286 dasm_put(Dst, 6044, 32-1, offsetof(GCfuncL, uvptr), DtA(->v));
9287 break;
9288 case BC_USETP:
9289 dasm_put(Dst, 6065, 32-1, 32-3, offsetof(GCfuncL, uvptr), DtA(->v));
9290 break;
9291
9292 case BC_UCLO:
9293 dasm_put(Dst, 6088, Dt1(->openupval), 32-1, -(BCBIAS_J*4 >> 16), Dt1(->base), Dt1(->base));
9294 break;
9295
9296 case BC_FNEW:
9297 dasm_put(Dst, 6118, 32-1, Dt1(->base), Dt1(->base), LJ_TFUNC);
9298 break;
9299
9300 /* -- Table ops --------------------------------------------------------- */
9301
9302 case BC_TNEW:
9303 case BC_TDUP:
9304 dasm_put(Dst, 6146, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base));
9305 if (op == BC_TNEW) {
9306 dasm_put(Dst, 6159);
9307 } else {
9308 dasm_put(Dst, 6168, 32-1);
9309 }
9310 dasm_put(Dst, 6175, Dt1(->base), LJ_TTAB);
9311 if (op == BC_TNEW) {
9312 dasm_put(Dst, 6192);
9313 }
9314 dasm_put(Dst, 6197);
9315 break;
9316
9317 case BC_GGET:
9318 case BC_GSET:
9319 dasm_put(Dst, 6206, 32-1, Dt7(->env));
9320 if (op == BC_GGET) {
9321 dasm_put(Dst, 6214);
9322 } else {
9323 dasm_put(Dst, 6217);
9324 }
9325 break;
9326
9327 case BC_TGETV:
9328 dasm_put(Dst, 6220);
9329 if (LJ_DUALNUM) {
9330 dasm_put(Dst, 6224);
9331 } else {
9332 dasm_put(Dst, 6226);
9333 }
9334 dasm_put(Dst, 6228, LJ_TTAB);
9335 if (LJ_DUALNUM) {
9336 dasm_put(Dst, 6234, Dt6(->asize), Dt6(->array), 31-3);
9337 } else {
9338 dasm_put(Dst, 6244, Dt6(->asize), Dt6(->array), 31-3);
9339 }
9340 dasm_put(Dst, 6261, LJ_TNIL, Dt6(->metatable), Dt6(->nomm), 1<<MM_index, LJ_TSTR);
9341 if (!LJ_DUALNUM) {
9342 dasm_put(Dst, 6301);
9343 }
9344 dasm_put(Dst, 6303);
9345 break;
9346 case BC_TGETS:
9347 dasm_put(Dst, 6306, 32-1, LJ_TTAB, Dt6(->hmask), Dt5(->hash), Dt6(->node), 31-5, 31-3, DtB(->key), 4+offsetof(Node, key), DtB(->val), 4+offsetof(Node, val), LJ_TSTR, LJ_TNIL, DtB(->next));
9348 dasm_put(Dst, 6367, LJ_TNIL, Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
9349 break;
9350 case BC_TGETB:
9351 dasm_put(Dst, 6387, 32-3, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
9352 break;
9353
9354 case BC_TSETV:
9355 dasm_put(Dst, 6435);
9356 if (LJ_DUALNUM) {
9357 dasm_put(Dst, 6439);
9358 } else {
9359 dasm_put(Dst, 6441);
9360 }
9361 dasm_put(Dst, 6443, LJ_TTAB);
9362 if (LJ_DUALNUM) {
9363 dasm_put(Dst, 6449, Dt6(->asize), Dt6(->array), 31-3);
9364 } else {
9365 dasm_put(Dst, 6459, Dt6(->asize), Dt6(->array), 31-3);
9366 }
9367 dasm_put(Dst, 6476, Dt6(->marked), LJ_TNIL, LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, LJ_TSTR);
9368 if (!LJ_DUALNUM) {
9369 dasm_put(Dst, 6523);
9370 }
9371 dasm_put(Dst, 6525, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
9372 break;
9373 dasm_put(Dst, 6540, LJ_TSTR, LJ_TNIL);
9374 case BC_TSETS:
9375 dasm_put(Dst, 6566, 32-1, LJ_TTAB, Dt6(->hmask), Dt5(->hash), Dt6(->node), Dt6(->nomm), 31-5, 31-3, Dt6(->marked), DtB(->key), 4+offsetof(Node, key), DtB(->val), 4+offsetof(Node, val), LJ_TSTR, LJ_TNIL);
9376 dasm_put(Dst, 6617, LJ_GC_BLACK, DtB(->val), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DtB(->next), Dt6(->metatable), DISPATCH_GL(tmptv), Dt1(->base), Dt6(->nomm), 1<<MM_newindex);
9377 dasm_put(Dst, 6673, LJ_TSTR, Dt1(->base), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
9378 break;
9379 case BC_TSETB:
9380 dasm_put(Dst, 6698, 32-3, LJ_TTAB, Dt6(->asize), Dt6(->array), Dt6(->marked), LJ_TNIL, LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DISPATCH_GL(gc.grayagain));
9381 dasm_put(Dst, 6756, DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
9382 break;
9383
9384 case BC_TSETM:
9385 dasm_put(Dst, 6766, 32-3, Dt6(->asize), 31-3, Dt6(->marked), Dt6(->array), LJ_GC_BLACK, Dt1(->base), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
9386 dasm_put(Dst, 6835);
9387 break;
9388
9389 /* -- Calls and vararg handling ----------------------------------------- */
9390
9391 case BC_CALLM:
9392 dasm_put(Dst, 6838);
9393 break;
9394 case BC_CALL:
9395 dasm_put(Dst, 6840, LJ_TFUNC, Dt7(->pc));
9396 break;
9397
9398 case BC_CALLMT:
9399 dasm_put(Dst, 6861);
9400 break;
9401 case BC_CALLT:
9402 dasm_put(Dst, 6863, LJ_TFUNC, FRAME_TYPE, Dt7(->ffid), FRAME_VARG, Dt7(->pc), -4-8, Dt7(->pc), PC2PROTO(k), FRAME_TYPEP);
9403 dasm_put(Dst, 6927, FRAME_TYPE);
9404 break;
9405
9406 case BC_ITERC:
9407 dasm_put(Dst, 6936, LJ_TFUNC, Dt7(->pc));
9408 break;
9409
9410 case BC_ITERN:
9411#if LJ_HASJIT
9412#endif
9413 dasm_put(Dst, 6963, Dt6(->asize), Dt6(->array), 31-3, LJ_TNIL);
9414 if (LJ_DUALNUM) {
9415 dasm_put(Dst, 6985);
9416 } else {
9417 dasm_put(Dst, 6988);
9418 }
9419 dasm_put(Dst, 6992, -(BCBIAS_J*4 >> 16));
9420 if (!LJ_DUALNUM) {
9421 dasm_put(Dst, 7000);
9422 }
9423 dasm_put(Dst, 7002, Dt6(->hmask), Dt6(->node), 31-5, 31-3, LJ_TNIL, DtB(->key), -(BCBIAS_J*4 >> 16));
9424 break;
9425
9426 case BC_ISNEXT:
9427 dasm_put(Dst, 7058, LJ_TTAB, LJ_TFUNC, LJ_TNIL, Dt8(->ffid), FF_next_N, 32-1, -(BCBIAS_J*4 >> 16), BC_JMP, BC_ITERC, -(BCBIAS_J*4 >> 16));
9428 break;
9429
9430 case BC_VARG:
9431 dasm_put(Dst, 7108, FRAME_VARG, Dt1(->maxstack), Dt1(->top), Dt1(->base), 32-3, Dt1(->base));
9432 dasm_put(Dst, 7188);
9433 break;
9434
9435 /* -- Returns ----------------------------------------------------------- */
9436
9437 case BC_RETM:
9438 dasm_put(Dst, 7194);
9439 break;
9440
9441 case BC_RET:
9442 dasm_put(Dst, 7196, FRAME_TYPE, FRAME_VARG, Dt7(->pc), PC2PROTO(k), FRAME_TYPEP);
9443 break;
9444
9445 case BC_RET0: case BC_RET1:
9446 dasm_put(Dst, 7266, FRAME_TYPE, FRAME_VARG);
9447 if (op == BC_RET1) {
9448 dasm_put(Dst, 7279);
9449 }
9450 dasm_put(Dst, 7282, Dt7(->pc), PC2PROTO(k));
9451 break;
9452
9453 /* -- Loops and branches ------------------------------------------------ */
9454
9455 case BC_FORL:
9456#if LJ_HASJIT
9457 dasm_put(Dst, 7310, GG_DISP2HOT, -HOTCOUNT_LOOP);
9458#endif
9459 break;
9460
9461 case BC_JFORI:
9462 case BC_JFORL:
9463#if !LJ_HASJIT
9464 break;
9465#endif
9466 case BC_FORI:
9467 case BC_IFORL:
9468 vk = (op == BC_IFORL || op == BC_JFORL);
9469 if (LJ_DUALNUM) {
9470 dasm_put(Dst, 7320, FORL_IDX*8+4);
9471 if (vk) {
9472 dasm_put(Dst, 7325, FORL_STEP*8+4, FORL_STOP*8+4, FORL_IDX*8+4);
9473 } else {
9474 dasm_put(Dst, 7339, FORL_STEP*8, FORL_STEP*8+4, FORL_STOP*8, FORL_STOP*8+4);
9475 }
9476 dasm_put(Dst, 7355, FORL_EXT*8);
9477 if (op != BC_JFORL) {
9478 dasm_put(Dst, 7362, 32-1);
9479 }
9480 dasm_put(Dst, 7365, FORL_EXT*8+4);
9481 if (op != BC_JFORL) {
9482 dasm_put(Dst, 7368);
9483 }
9484 if (op == BC_FORI) {
9485 dasm_put(Dst, 7370);
9486 } else if (op == BC_JFORI) {
9487 dasm_put(Dst, 7373, -(BCBIAS_J*4 >> 16));
9488 } else if (op == BC_IFORL) {
9489 dasm_put(Dst, 7378, -(BCBIAS_J*4 >> 16));
9490 } else {
9491 dasm_put(Dst, 7383, BC_JLOOP);
9492 }
9493 dasm_put(Dst, 7386);
9494 if (vk) {
9495 dasm_put(Dst, 7402);
9496 }
9497 }
9498 if (vk) {
9499 if (LJ_DUALNUM) {
9500 dasm_put(Dst, 7409, FORL_IDX*8);
9501 } else {
9502 dasm_put(Dst, 7413);
9503 }
9504 dasm_put(Dst, 7415, FORL_STEP*8, FORL_STOP*8, FORL_STEP*8, FORL_IDX*8);
9505 } else {
9506 if (LJ_DUALNUM) {
9507 dasm_put(Dst, 7425);
9508 } else {
9509 dasm_put(Dst, 7427, FORL_STEP*8, FORL_STOP*8);
9510 }
9511 dasm_put(Dst, 7436, FORL_IDX*8, FORL_STEP*8, FORL_STOP*8);
9512 }
9513 dasm_put(Dst, 7447);
9514 if (op != BC_JFORL) {
9515 dasm_put(Dst, 7449, 32-1);
9516 }
9517 dasm_put(Dst, 7452, FORL_EXT*8);
9518 if (op != BC_JFORL) {
9519 dasm_put(Dst, 7455);
9520 }
9521 dasm_put(Dst, 7457);
9522 if (op == BC_JFORI) {
9523 dasm_put(Dst, 7459, -(BCBIAS_J*4 >> 16));
9524 }
9525 dasm_put(Dst, 7462);
9526 if (op == BC_FORI) {
9527 dasm_put(Dst, 7465);
9528 } else if (op == BC_IFORL) {
9529 if (LJ_DUALNUM) {
9530 dasm_put(Dst, 7468);
9531 } else {
9532 dasm_put(Dst, 7471);
9533 }
9534 dasm_put(Dst, 7474, -(BCBIAS_J*4 >> 16));
9535 } else if (op == BC_JFORI) {
9536 dasm_put(Dst, 7478);
9537 } else {
9538 dasm_put(Dst, 7481, BC_JLOOP);
9539 }
9540 if (LJ_DUALNUM) {
9541 dasm_put(Dst, 7484);
9542 } else {
9543 dasm_put(Dst, 7487);
9544 }
9545 dasm_put(Dst, 7499);
9546 if (op == BC_FORI) {
9547 dasm_put(Dst, 7501, -(BCBIAS_J*4 >> 16));
9548 } else if (op == BC_IFORL) {
9549 dasm_put(Dst, 7507);
9550 } else if (op == BC_JFORI) {
9551 dasm_put(Dst, 7510);
9552 } else {
9553 dasm_put(Dst, 7513, BC_JLOOP);
9554 }
9555 dasm_put(Dst, 7516);
9556 if (op == BC_JFORI) {
9557 dasm_put(Dst, 7519, BC_JLOOP);
9558 }
9559 break;
9560
9561 case BC_ITERL:
9562#if LJ_HASJIT
9563 dasm_put(Dst, 7525, GG_DISP2HOT, -HOTCOUNT_LOOP);
9564#endif
9565 break;
9566
9567 case BC_JITERL:
9568#if !LJ_HASJIT
9569 break;
9570#endif
9571 case BC_IITERL:
9572 dasm_put(Dst, 7535, LJ_TNIL);
9573 if (op == BC_JITERL) {
9574 dasm_put(Dst, 7542, BC_JLOOP);
9575 } else {
9576 dasm_put(Dst, 7547, 32-1, -(BCBIAS_J*4 >> 16));
9577 }
9578 dasm_put(Dst, 7555);
9579 break;
9580
9581 case BC_LOOP:
9582#if LJ_HASJIT
9583 dasm_put(Dst, 7567, GG_DISP2HOT, -HOTCOUNT_LOOP);
9584#endif
9585 break;
9586
9587 case BC_ILOOP:
9588 dasm_put(Dst, 7577);
9589 break;
9590
9591 case BC_JLOOP:
9592#if LJ_HASJIT
9593 dasm_put(Dst, 7588, DISPATCH_J(trace), 32-1, DISPATCH_GL(vmstate), DtD(->mcode), DISPATCH_GL(jit_base), DISPATCH_GL(jit_L), GG_DISP2G+32768);
9594#endif
9595 break;
9596
9597 case BC_JMP:
9598 dasm_put(Dst, 7607, 32-1, -(BCBIAS_J*4 >> 16));
9599 break;
9600
9601 /* -- Function headers -------------------------------------------------- */
9602
9603 case BC_FUNCF:
9604#if LJ_HASJIT
9605 dasm_put(Dst, 7623, GG_DISP2HOT, -HOTCOUNT_CALL);
9606#endif
9607 case BC_FUNCV: /* NYI: compiled vararg functions. */
9608 break;
9609
9610 case BC_JFUNCF:
9611#if !LJ_HASJIT
9612 break;
9613#endif
9614 case BC_IFUNCF:
9615 dasm_put(Dst, 7633, Dt1(->maxstack), -4+PC2PROTO(numparams), -4+PC2PROTO(k), 31-3);
9616 if (op != BC_JFUNCF) {
9617 dasm_put(Dst, 7645);
9618 }
9619 dasm_put(Dst, 7648);
9620 if (op == BC_JFUNCF) {
9621 dasm_put(Dst, 7653, BC_JLOOP);
9622 } else {
9623 dasm_put(Dst, 7657);
9624 }
9625 dasm_put(Dst, 7666);
9626 break;
9627
9628 case BC_JFUNCV:
9629#if !LJ_HASJIT
9630 break;
9631#endif
9632 dasm_put(Dst, 7672);
9633 break; /* NYI: compiled vararg functions. */
9634
9635 case BC_IFUNCV:
9636 dasm_put(Dst, 7674, Dt1(->maxstack), 8+FRAME_VARG, -4+PC2PROTO(k), -4+PC2PROTO(numparams), LJ_TNIL);
9637 break;
9638
9639 case BC_FUNCC:
9640 case BC_FUNCCW:
9641 if (op == BC_FUNCC) {
9642 dasm_put(Dst, 7727, Dt8(->f));
9643 } else {
9644 dasm_put(Dst, 7730, DISPATCH_GL(wrapf));
9645 }
9646 dasm_put(Dst, 7733, Dt1(->maxstack), Dt1(->base), Dt1(->top), ~LJ_VMST_C);
9647 if (op == BC_FUNCCW) {
9648 dasm_put(Dst, 7746, Dt8(->f));
9649 }
9650 dasm_put(Dst, 7749, DISPATCH_GL(vmstate), Dt1(->base), 31-3, Dt1(->top), ~LJ_VMST_INTERP, DISPATCH_GL(vmstate));
9651 break;
9652
9653 /* ---------------------------------------------------------------------- */
9654
9655 default:
9656 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
9657 exit(2);
9658 break;
9659 }
9660}
9661
9662static int build_backend(BuildCtx *ctx)
9663{
9664 int op;
9665
9666 dasm_growpc(Dst, BC__MAX);
9667
9668 build_subroutines(ctx);
9669
9670 dasm_put(Dst, 7770);
9671 for (op = 0; op < BC__MAX; op++)
9672 build_ins(ctx, (BCOp)op, op);
9673
9674 return BC__MAX;
9675}
9676
9677/* Emit pseudo frame-info for all assembler functions. */
9678static void emit_asm_debug(BuildCtx *ctx)
9679{
9680 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
9681 int i;
9682 switch (ctx->mode) {
9683 case BUILD_elfasm:
9684 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
9685 fprintf(ctx->fp,
9686 ".Lframe0:\n"
9687 "\t.long .LECIE0-.LSCIE0\n"
9688 ".LSCIE0:\n"
9689 "\t.long 0xffffffff\n"
9690 "\t.byte 0x1\n"
9691 "\t.string \"\"\n"
9692 "\t.uleb128 0x1\n"
9693 "\t.sleb128 -4\n"
9694 "\t.byte 65\n"
9695 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
9696 "\t.align 2\n"
9697 ".LECIE0:\n\n");
9698 fprintf(ctx->fp,
9699 ".LSFDE0:\n"
9700 "\t.long .LEFDE0-.LASFDE0\n"
9701 ".LASFDE0:\n"
9702 "\t.long .Lframe0\n"
9703 "\t.long .Lbegin\n"
9704 "\t.long %d\n"
9705 "\t.byte 0xe\n\t.uleb128 %d\n"
9706 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
9707 "\t.byte 0x5\n\t.uleb128 70\n\t.uleb128 55\n",
9708 fcofs, CFRAME_SIZE);
9709 for (i = 14; i <= 31; i++)
9710 fprintf(ctx->fp,
9711 "\t.byte %d\n\t.uleb128 %d\n"
9712 "\t.byte %d\n\t.uleb128 %d\n",
9713 0x80+i, 37+(31-i), 0x80+32+i, 2+2*(31-i));
9714 fprintf(ctx->fp,
9715 "\t.align 2\n"
9716 ".LEFDE0:\n\n");
9717#if LJ_HASFFI
9718 fprintf(ctx->fp,
9719 ".LSFDE1:\n"
9720 "\t.long .LEFDE1-.LASFDE1\n"
9721 ".LASFDE1:\n"
9722 "\t.long .Lframe0\n"
9723 "\t.long lj_vm_ffi_call\n"
9724 "\t.long %d\n"
9725 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
9726 "\t.byte 0x8e\n\t.uleb128 2\n"
9727 "\t.byte 0xd\n\t.uleb128 0xe\n"
9728 "\t.align 2\n"
9729 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
9730#endif
9731 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
9732 fprintf(ctx->fp,
9733 ".Lframe1:\n"
9734 "\t.long .LECIE1-.LSCIE1\n"
9735 ".LSCIE1:\n"
9736 "\t.long 0\n"
9737 "\t.byte 0x1\n"
9738 "\t.string \"zPR\"\n"
9739 "\t.uleb128 0x1\n"
9740 "\t.sleb128 -4\n"
9741 "\t.byte 65\n"
9742 "\t.uleb128 6\n" /* augmentation length */
9743 "\t.byte 0x1b\n" /* pcrel|sdata4 */
9744 "\t.long lj_err_unwind_dwarf-.\n"
9745 "\t.byte 0x1b\n" /* pcrel|sdata4 */
9746 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
9747 "\t.align 2\n"
9748 ".LECIE1:\n\n");
9749 fprintf(ctx->fp,
9750 ".LSFDE2:\n"
9751 "\t.long .LEFDE2-.LASFDE2\n"
9752 ".LASFDE2:\n"
9753 "\t.long .LASFDE2-.Lframe1\n"
9754 "\t.long .Lbegin-.\n"
9755 "\t.long %d\n"
9756 "\t.uleb128 0\n" /* augmentation length */
9757 "\t.byte 0xe\n\t.uleb128 %d\n"
9758 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
9759 "\t.byte 0x5\n\t.uleb128 70\n\t.uleb128 55\n",
9760 fcofs, CFRAME_SIZE);
9761 for (i = 14; i <= 31; i++)
9762 fprintf(ctx->fp,
9763 "\t.byte %d\n\t.uleb128 %d\n"
9764 "\t.byte %d\n\t.uleb128 %d\n",
9765 0x80+i, 37+(31-i), 0x80+32+i, 2+2*(31-i));
9766 fprintf(ctx->fp,
9767 "\t.align 2\n"
9768 ".LEFDE2:\n\n");
9769#if LJ_HASFFI
9770 fprintf(ctx->fp,
9771 ".Lframe2:\n"
9772 "\t.long .LECIE2-.LSCIE2\n"
9773 ".LSCIE2:\n"
9774 "\t.long 0\n"
9775 "\t.byte 0x1\n"
9776 "\t.string \"zR\"\n"
9777 "\t.uleb128 0x1\n"
9778 "\t.sleb128 -4\n"
9779 "\t.byte 65\n"
9780 "\t.uleb128 1\n" /* augmentation length */
9781 "\t.byte 0x1b\n" /* pcrel|sdata4 */
9782 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
9783 "\t.align 2\n"
9784 ".LECIE2:\n\n");
9785 fprintf(ctx->fp,
9786 ".LSFDE3:\n"
9787 "\t.long .LEFDE3-.LASFDE3\n"
9788 ".LASFDE3:\n"
9789 "\t.long .LASFDE3-.Lframe2\n"
9790 "\t.long lj_vm_ffi_call-.\n"
9791 "\t.long %d\n"
9792 "\t.uleb128 0\n" /* augmentation length */
9793 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
9794 "\t.byte 0x8e\n\t.uleb128 2\n"
9795 "\t.byte 0xd\n\t.uleb128 0xe\n"
9796 "\t.align 2\n"
9797 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
9798#endif
9799 break;
9800 default:
9801 break;
9802 }
9803}
9804
diff --git a/libraries/luajit-2.0/src/buildvm_ppcspe.dasc b/libraries/luajit-2.0/src/buildvm_ppcspe.dasc
new file mode 100644
index 0000000..3ec36f7
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_ppcspe.dasc
@@ -0,0 +1,3704 @@
1|// Low-level VM code for PowerPC/e500 CPUs.
2|// Bytecode interpreter, fast functions and helper functions.
3|// Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4|
5|.arch ppc
6|.section code_op, code_sub
7|
8|.actionlist build_actionlist
9|.globals GLOB_
10|.globalnames globnames
11|.externnames extnames
12|
13|// Note: The ragged indentation of the instructions is intentional.
14|// The starting columns indicate data dependencies.
15|
16|//-----------------------------------------------------------------------
17|
18|// Fixed register assignments for the interpreter.
19|// Don't use: r1 = sp, r2 and r13 = reserved and/or small data area ptr
20|
21|// The following must be C callee-save (but BASE is often refetched).
22|.define BASE, r14 // Base of current Lua stack frame.
23|.define KBASE, r15 // Constants of current Lua function.
24|.define PC, r16 // Next PC.
25|.define DISPATCH, r17 // Opcode dispatch table.
26|.define LREG, r18 // Register holding lua_State (also in SAVE_L).
27|.define MULTRES, r19 // Size of multi-result: (nresults+1)*8.
28|
29|// Constants for vectorized type-comparisons (hi+low GPR). C callee-save.
30|.define TISNUM, r22
31|.define TISSTR, r23
32|.define TISTAB, r24
33|.define TISFUNC, r25
34|.define TISNIL, r26
35|.define TOBIT, r27
36|.define ZERO, TOBIT // Zero in lo word.
37|
38|// The following temporaries are not saved across C calls, except for RA.
39|.define RA, r20 // Callee-save.
40|.define RB, r10
41|.define RC, r11
42|.define RD, r12
43|.define INS, r7 // Overlaps CARG5.
44|
45|.define TMP0, r0
46|.define TMP1, r8
47|.define TMP2, r9
48|.define TMP3, r6 // Overlaps CARG4.
49|
50|// Saved temporaries.
51|.define SAVE0, r21
52|
53|// Calling conventions.
54|.define CARG1, r3
55|.define CARG2, r4
56|.define CARG3, r5
57|.define CARG4, r6 // Overlaps TMP3.
58|.define CARG5, r7 // Overlaps INS.
59|
60|.define CRET1, r3
61|.define CRET2, r4
62|
63|// Stack layout while in interpreter. Must match with lj_frame.h.
64|.define SAVE_LR, 188(sp)
65|.define CFRAME_SPACE, 184 // Delta for sp.
66|// Back chain for sp: 184(sp) <-- sp entering interpreter
67|.define SAVE_r31, 176(sp) // 64 bit register saves.
68|.define SAVE_r30, 168(sp)
69|.define SAVE_r29, 160(sp)
70|.define SAVE_r28, 152(sp)
71|.define SAVE_r27, 144(sp)
72|.define SAVE_r26, 136(sp)
73|.define SAVE_r25, 128(sp)
74|.define SAVE_r24, 120(sp)
75|.define SAVE_r23, 112(sp)
76|.define SAVE_r22, 104(sp)
77|.define SAVE_r21, 96(sp)
78|.define SAVE_r20, 88(sp)
79|.define SAVE_r19, 80(sp)
80|.define SAVE_r18, 72(sp)
81|.define SAVE_r17, 64(sp)
82|.define SAVE_r16, 56(sp)
83|.define SAVE_r15, 48(sp)
84|.define SAVE_r14, 40(sp)
85|.define SAVE_CR, 36(sp)
86|.define UNUSED1, 32(sp)
87|.define SAVE_ERRF, 28(sp) // 32 bit C frame info.
88|.define SAVE_NRES, 24(sp)
89|.define SAVE_CFRAME, 20(sp)
90|.define SAVE_L, 16(sp)
91|.define SAVE_PC, 12(sp)
92|.define SAVE_MULTRES, 8(sp)
93|// Next frame lr: 4(sp)
94|// Back chain for sp: 0(sp) <-- sp while in interpreter
95|
96|.macro save_, reg; evstdd reg, SAVE_..reg; .endmacro
97|.macro rest_, reg; evldd reg, SAVE_..reg; .endmacro
98|
99|.macro saveregs
100| stwu sp, -CFRAME_SPACE(sp)
101| save_ r14; save_ r15; save_ r16; save_ r17; save_ r18; save_ r19
102| mflr r0; mfcr r12
103| save_ r20; save_ r21; save_ r22; save_ r23; save_ r24; save_ r25
104| stw r0, SAVE_LR; stw r12, SAVE_CR
105| save_ r26; save_ r27; save_ r28; save_ r29; save_ r30; save_ r31
106|.endmacro
107|
108|.macro restoreregs
109| lwz r0, SAVE_LR; lwz r12, SAVE_CR
110| rest_ r14; rest_ r15; rest_ r16; rest_ r17; rest_ r18; rest_ r19
111| mtlr r0; mtcrf 0x38, r12
112| rest_ r20; rest_ r21; rest_ r22; rest_ r23; rest_ r24; rest_ r25
113| rest_ r26; rest_ r27; rest_ r28; rest_ r29; rest_ r30; rest_ r31
114| addi sp, sp, CFRAME_SPACE
115|.endmacro
116|
117|// Type definitions. Some of these are only used for documentation.
118|.type L, lua_State, LREG
119|.type GL, global_State
120|.type TVALUE, TValue
121|.type GCOBJ, GCobj
122|.type STR, GCstr
123|.type TAB, GCtab
124|.type LFUNC, GCfuncL
125|.type CFUNC, GCfuncC
126|.type PROTO, GCproto
127|.type UPVAL, GCupval
128|.type NODE, Node
129|.type NARGS8, int
130|.type TRACE, GCtrace
131|
132|//-----------------------------------------------------------------------
133|
134|// These basic macros should really be part of DynASM.
135|.macro srwi, rx, ry, n; rlwinm rx, ry, 32-n, n, 31; .endmacro
136|.macro slwi, rx, ry, n; rlwinm rx, ry, n, 0, 31-n; .endmacro
137|.macro rotlwi, rx, ry, n; rlwinm rx, ry, n, 0, 31; .endmacro
138|.macro rotlw, rx, ry, rn; rlwnm rx, ry, rn, 0, 31; .endmacro
139|.macro subi, rx, ry, i; addi rx, ry, -i; .endmacro
140|
141|// Trap for not-yet-implemented parts.
142|.macro NYI; tw 4, sp, sp; .endmacro
143|
144|//-----------------------------------------------------------------------
145|
146|// Access to frame relative to BASE.
147|.define FRAME_PC, -8
148|.define FRAME_FUNC, -4
149|
150|// Instruction decode.
151|.macro decode_OP4, dst, ins; rlwinm dst, ins, 2, 22, 29; .endmacro
152|.macro decode_RA8, dst, ins; rlwinm dst, ins, 27, 21, 28; .endmacro
153|.macro decode_RB8, dst, ins; rlwinm dst, ins, 11, 21, 28; .endmacro
154|.macro decode_RC8, dst, ins; rlwinm dst, ins, 19, 21, 28; .endmacro
155|.macro decode_RD8, dst, ins; rlwinm dst, ins, 19, 13, 28; .endmacro
156|
157|.macro decode_OP1, dst, ins; rlwinm dst, ins, 0, 24, 31; .endmacro
158|.macro decode_RD4, dst, ins; rlwinm dst, ins, 18, 14, 29; .endmacro
159|
160|// Instruction fetch.
161|.macro ins_NEXT1
162| lwz INS, 0(PC)
163| addi PC, PC, 4
164|.endmacro
165|// Instruction decode+dispatch.
166|.macro ins_NEXT2
167| decode_OP4 TMP1, INS
168| decode_RB8 RB, INS
169| decode_RD8 RD, INS
170| lwzx TMP0, DISPATCH, TMP1
171| decode_RA8 RA, INS
172| decode_RC8 RC, INS
173| mtctr TMP0
174| bctr
175|.endmacro
176|.macro ins_NEXT
177| ins_NEXT1
178| ins_NEXT2
179|.endmacro
180|
181|// Instruction footer.
182|.if 1
183| // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
184| .define ins_next, ins_NEXT
185| .define ins_next_, ins_NEXT
186| .define ins_next1, ins_NEXT1
187| .define ins_next2, ins_NEXT2
188|.else
189| // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
190| // Affects only certain kinds of benchmarks (and only with -j off).
191| .macro ins_next
192| b ->ins_next
193| .endmacro
194| .macro ins_next1
195| .endmacro
196| .macro ins_next2
197| b ->ins_next
198| .endmacro
199| .macro ins_next_
200| ->ins_next:
201| ins_NEXT
202| .endmacro
203|.endif
204|
205|// Call decode and dispatch.
206|.macro ins_callt
207| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
208| lwz PC, LFUNC:RB->pc
209| lwz INS, 0(PC)
210| addi PC, PC, 4
211| decode_OP4 TMP1, INS
212| decode_RA8 RA, INS
213| lwzx TMP0, DISPATCH, TMP1
214| add RA, RA, BASE
215| mtctr TMP0
216| bctr
217|.endmacro
218|
219|.macro ins_call
220| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, PC = caller PC
221| stw PC, FRAME_PC(BASE)
222| ins_callt
223|.endmacro
224|
225|//-----------------------------------------------------------------------
226|
227|// Macros to test operand types.
228|.macro checknum, reg; evcmpltu reg, TISNUM; .endmacro
229|.macro checkstr, reg; evcmpeq reg, TISSTR; .endmacro
230|.macro checktab, reg; evcmpeq reg, TISTAB; .endmacro
231|.macro checkfunc, reg; evcmpeq reg, TISFUNC; .endmacro
232|.macro checknil, reg; evcmpeq reg, TISNIL; .endmacro
233|.macro checkok, label; blt label; .endmacro
234|.macro checkfail, label; bge label; .endmacro
235|.macro checkanyfail, label; bns label; .endmacro
236|.macro checkallok, label; bso label; .endmacro
237|
238|.macro branch_RD
239| srwi TMP0, RD, 1
240| add PC, PC, TMP0
241| addis PC, PC, -(BCBIAS_J*4 >> 16)
242|.endmacro
243|
244|// Assumes DISPATCH is relative to GL.
245#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
246#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
247|
248#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
249|
250|.macro hotloop
251| NYI
252|.endmacro
253|
254|.macro hotcall
255| NYI
256|.endmacro
257|
258|// Set current VM state. Uses TMP0.
259|.macro li_vmstate, st; li TMP0, ~LJ_VMST_..st; .endmacro
260|.macro st_vmstate; stw TMP0, DISPATCH_GL(vmstate)(DISPATCH); .endmacro
261|
262|// Move table write barrier back. Overwrites mark and tmp.
263|.macro barrierback, tab, mark, tmp
264| lwz tmp, DISPATCH_GL(gc.grayagain)(DISPATCH)
265| // Assumes LJ_GC_BLACK is 0x04.
266| rlwinm mark, mark, 0, 30, 28 // black2gray(tab)
267| stw tab, DISPATCH_GL(gc.grayagain)(DISPATCH)
268| stb mark, tab->marked
269| stw tmp, tab->gclist
270|.endmacro
271|
272|//-----------------------------------------------------------------------
273
274/* Generate subroutines used by opcodes and other parts of the VM. */
275/* The .code_sub section should be last to help static branch prediction. */
276static void build_subroutines(BuildCtx *ctx)
277{
278 |.code_sub
279 |
280 |//-----------------------------------------------------------------------
281 |//-- Return handling ----------------------------------------------------
282 |//-----------------------------------------------------------------------
283 |
284 |->vm_returnp:
285 | // See vm_return. Also: TMP2 = previous base.
286 | andi. TMP0, PC, FRAME_P
287 | evsplati TMP1, LJ_TTRUE
288 | beq ->cont_dispatch
289 |
290 | // Return from pcall or xpcall fast func.
291 | lwz PC, FRAME_PC(TMP2) // Fetch PC of previous frame.
292 | mr BASE, TMP2 // Restore caller base.
293 | // Prepending may overwrite the pcall frame, so do it at the end.
294 | stwu TMP1, FRAME_PC(RA) // Prepend true to results.
295 |
296 |->vm_returnc:
297 | andi. TMP0, PC, FRAME_TYPE
298 | addi RD, RD, 8 // RD = (nresults+1)*8.
299 | mr MULTRES, RD
300 | beq ->BC_RET_Z // Handle regular return to Lua.
301 |
302 |->vm_return:
303 | // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return
304 | // TMP0 = PC & FRAME_TYPE
305 | cmpwi TMP0, FRAME_C
306 | rlwinm TMP2, PC, 0, 0, 28
307 | li_vmstate C
308 | sub TMP2, BASE, TMP2 // TMP2 = previous base.
309 | bne ->vm_returnp
310 |
311 | addic. TMP1, RD, -8
312 | stw TMP2, L->base
313 | lwz TMP2, SAVE_NRES
314 | subi BASE, BASE, 8
315 | st_vmstate
316 | slwi TMP2, TMP2, 3
317 | beq >2
318 |1:
319 | addic. TMP1, TMP1, -8
320 | evldd TMP0, 0(RA)
321 | addi RA, RA, 8
322 | evstdd TMP0, 0(BASE)
323 | addi BASE, BASE, 8
324 | bne <1
325 |
326 |2:
327 | cmpw TMP2, RD // More/less results wanted?
328 | bne >6
329 |3:
330 | stw BASE, L->top // Store new top.
331 |
332 |->vm_leave_cp:
333 | lwz TMP0, SAVE_CFRAME // Restore previous C frame.
334 | li CRET1, 0 // Ok return status for vm_pcall.
335 | stw TMP0, L->cframe
336 |
337 |->vm_leave_unw:
338 | restoreregs
339 | blr
340 |
341 |6:
342 | ble >7 // Less results wanted?
343 | // More results wanted. Check stack size and fill up results with nil.
344 | lwz TMP1, L->maxstack
345 | cmplw BASE, TMP1
346 | bge >8
347 | evstdd TISNIL, 0(BASE)
348 | addi RD, RD, 8
349 | addi BASE, BASE, 8
350 | b <2
351 |
352 |7: // Less results wanted.
353 | sub TMP0, RD, TMP2
354 | cmpwi TMP2, 0 // LUA_MULTRET+1 case?
355 | sub TMP0, BASE, TMP0 // Subtract the difference.
356 | iseleq BASE, BASE, TMP0 // Either keep top or shrink it.
357 | b <3
358 |
359 |8: // Corner case: need to grow stack for filling up results.
360 | // This can happen if:
361 | // - A C function grows the stack (a lot).
362 | // - The GC shrinks the stack in between.
363 | // - A return back from a lua_call() with (high) nresults adjustment.
364 | stw BASE, L->top // Save current top held in BASE (yes).
365 | mr SAVE0, RD
366 | mr CARG2, TMP2
367 | mr CARG1, L
368 | bl extern lj_state_growstack // (lua_State *L, int n)
369 | lwz TMP2, SAVE_NRES
370 | mr RD, SAVE0
371 | slwi TMP2, TMP2, 3
372 | lwz BASE, L->top // Need the (realloced) L->top in BASE.
373 | b <2
374 |
375 |->vm_unwind_c: // Unwind C stack, return from vm_pcall.
376 | // (void *cframe, int errcode)
377 | mr sp, CARG1
378 | mr CRET1, CARG2
379 |->vm_unwind_c_eh: // Landing pad for external unwinder.
380 | lwz L, SAVE_L
381 | li TMP0, ~LJ_VMST_C
382 | lwz GL:TMP1, L->glref
383 | stw TMP0, GL:TMP1->vmstate
384 | b ->vm_leave_unw
385 |
386 |->vm_unwind_ff: // Unwind C stack, return from ff pcall.
387 | // (void *cframe)
388 | rlwinm sp, CARG1, 0, 0, 29
389 |->vm_unwind_ff_eh: // Landing pad for external unwinder.
390 | lwz L, SAVE_L
391 | evsplati TISNUM, LJ_TISNUM+1 // Setup type comparison constants.
392 | evsplati TISFUNC, LJ_TFUNC
393 | lus TOBIT, 0x4338
394 | evsplati TISTAB, LJ_TTAB
395 | li TMP0, 0
396 | lwz BASE, L->base
397 | evmergelo TOBIT, TOBIT, TMP0
398 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
399 | evsplati TISSTR, LJ_TSTR
400 | li TMP1, LJ_TFALSE
401 | evsplati TISNIL, LJ_TNIL
402 | li_vmstate INTERP
403 | lwz PC, FRAME_PC(BASE) // Fetch PC of previous frame.
404 | la RA, -8(BASE) // Results start at BASE-8.
405 | addi DISPATCH, DISPATCH, GG_G2DISP
406 | stw TMP1, 0(RA) // Prepend false to error message.
407 | li RD, 16 // 2 results: false + error message.
408 | st_vmstate
409 | b ->vm_returnc
410 |
411 |//-----------------------------------------------------------------------
412 |//-- Grow stack for calls -----------------------------------------------
413 |//-----------------------------------------------------------------------
414 |
415 |->vm_growstack_c: // Grow stack for C function.
416 | li CARG2, LUA_MINSTACK
417 | b >2
418 |
419 |->vm_growstack_l: // Grow stack for Lua function.
420 | // BASE = new base, RA = BASE+framesize*8, RC = nargs*8, PC = first PC
421 | add RC, BASE, RC
422 | sub RA, RA, BASE
423 | stw BASE, L->base
424 | addi PC, PC, 4 // Must point after first instruction.
425 | stw RC, L->top
426 | srwi CARG2, RA, 3
427 |2:
428 | // L->base = new base, L->top = top
429 | stw PC, SAVE_PC
430 | mr CARG1, L
431 | bl extern lj_state_growstack // (lua_State *L, int n)
432 | lwz BASE, L->base
433 | lwz RC, L->top
434 | lwz LFUNC:RB, FRAME_FUNC(BASE)
435 | sub RC, RC, BASE
436 | // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
437 | ins_callt // Just retry the call.
438 |
439 |//-----------------------------------------------------------------------
440 |//-- Entry points into the assembler VM ---------------------------------
441 |//-----------------------------------------------------------------------
442 |
443 |->vm_resume: // Setup C frame and resume thread.
444 | // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
445 | saveregs
446 | mr L, CARG1
447 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
448 | mr BASE, CARG2
449 | lbz TMP1, L->status
450 | stw L, SAVE_L
451 | li PC, FRAME_CP
452 | addi TMP0, sp, CFRAME_RESUME
453 | addi DISPATCH, DISPATCH, GG_G2DISP
454 | stw CARG3, SAVE_NRES
455 | cmplwi TMP1, 0
456 | stw CARG3, SAVE_ERRF
457 | stw TMP0, L->cframe
458 | stw CARG3, SAVE_CFRAME
459 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
460 | beq >3
461 |
462 | // Resume after yield (like a return).
463 | mr RA, BASE
464 | lwz BASE, L->base
465 | evsplati TISNUM, LJ_TISNUM+1 // Setup type comparison constants.
466 | lwz TMP1, L->top
467 | evsplati TISFUNC, LJ_TFUNC
468 | lus TOBIT, 0x4338
469 | evsplati TISTAB, LJ_TTAB
470 | lwz PC, FRAME_PC(BASE)
471 | li TMP2, 0
472 | evsplati TISSTR, LJ_TSTR
473 | sub RD, TMP1, BASE
474 | evmergelo TOBIT, TOBIT, TMP2
475 | stb CARG3, L->status
476 | andi. TMP0, PC, FRAME_TYPE
477 | li_vmstate INTERP
478 | addi RD, RD, 8
479 | evsplati TISNIL, LJ_TNIL
480 | mr MULTRES, RD
481 | st_vmstate
482 | beq ->BC_RET_Z
483 | b ->vm_return
484 |
485 |->vm_pcall: // Setup protected C frame and enter VM.
486 | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
487 | saveregs
488 | li PC, FRAME_CP
489 | stw CARG4, SAVE_ERRF
490 | b >1
491 |
492 |->vm_call: // Setup C frame and enter VM.
493 | // (lua_State *L, TValue *base, int nres1)
494 | saveregs
495 | li PC, FRAME_C
496 |
497 |1: // Entry point for vm_pcall above (PC = ftype).
498 | lwz TMP1, L:CARG1->cframe
499 | stw CARG3, SAVE_NRES
500 | mr L, CARG1
501 | stw CARG1, SAVE_L
502 | mr BASE, CARG2
503 | stw sp, L->cframe // Add our C frame to cframe chain.
504 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
505 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
506 | stw TMP1, SAVE_CFRAME
507 | addi DISPATCH, DISPATCH, GG_G2DISP
508 |
509 |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
510 | lwz TMP2, L->base // TMP2 = old base (used in vmeta_call).
511 | evsplati TISNUM, LJ_TISNUM+1 // Setup type comparison constants.
512 | lwz TMP1, L->top
513 | evsplati TISFUNC, LJ_TFUNC
514 | add PC, PC, BASE
515 | evsplati TISTAB, LJ_TTAB
516 | lus TOBIT, 0x4338
517 | li TMP0, 0
518 | sub PC, PC, TMP2 // PC = frame delta + frame type
519 | evsplati TISSTR, LJ_TSTR
520 | sub NARGS8:RC, TMP1, BASE
521 | evmergelo TOBIT, TOBIT, TMP0
522 | li_vmstate INTERP
523 | evsplati TISNIL, LJ_TNIL
524 | st_vmstate
525 |
526 |->vm_call_dispatch:
527 | // TMP2 = old base, BASE = new base, RC = nargs*8, PC = caller PC
528 | li TMP0, -8
529 | evlddx LFUNC:RB, BASE, TMP0
530 | checkfunc LFUNC:RB
531 | checkfail ->vmeta_call
532 |
533 |->vm_call_dispatch_f:
534 | ins_call
535 | // BASE = new base, RB = func, RC = nargs*8, PC = caller PC
536 |
537 |->vm_cpcall: // Setup protected C frame, call C.
538 | // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
539 | saveregs
540 | mr L, CARG1
541 | lwz TMP0, L:CARG1->stack
542 | stw CARG1, SAVE_L
543 | lwz TMP1, L->top
544 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
545 | sub TMP0, TMP0, TMP1 // Compute -savestack(L, L->top).
546 | lwz TMP1, L->cframe
547 | stw sp, L->cframe // Add our C frame to cframe chain.
548 | li TMP2, 0
549 | stw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame.
550 | stw TMP2, SAVE_ERRF // No error function.
551 | stw TMP1, SAVE_CFRAME
552 | mtctr CARG4
553 | bctrl // (lua_State *L, lua_CFunction func, void *ud)
554 | mr. BASE, CRET1
555 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
556 | li PC, FRAME_CP
557 | addi DISPATCH, DISPATCH, GG_G2DISP
558 | bne <3 // Else continue with the call.
559 | b ->vm_leave_cp // No base? Just remove C frame.
560 |
561 |//-----------------------------------------------------------------------
562 |//-- Metamethod handling ------------------------------------------------
563 |//-----------------------------------------------------------------------
564 |
565 |// The lj_meta_* functions (except for lj_meta_cat) don't reallocate the
566 |// stack, so BASE doesn't need to be reloaded across these calls.
567 |
568 |//-- Continuation dispatch ----------------------------------------------
569 |
570 |->cont_dispatch:
571 | // BASE = meta base, RA = resultptr, RD = (nresults+1)*8
572 | lwz TMP0, -12(BASE) // Continuation.
573 | mr RB, BASE
574 | mr BASE, TMP2 // Restore caller BASE.
575 | lwz LFUNC:TMP1, FRAME_FUNC(TMP2)
576 | cmplwi TMP0, 0
577 | lwz PC, -16(RB) // Restore PC from [cont|PC].
578 | beq >1
579 | subi TMP2, RD, 8
580 | lwz TMP1, LFUNC:TMP1->pc
581 | evstddx TISNIL, RA, TMP2 // Ensure one valid arg.
582 | lwz KBASE, PC2PROTO(k)(TMP1)
583 | // BASE = base, RA = resultptr, RB = meta base
584 | mtctr TMP0
585 | bctr // Jump to continuation.
586 |
587 |1: // Tail call from C function.
588 | subi TMP1, RB, 16
589 | sub RC, TMP1, BASE
590 | b ->vm_call_tail
591 |
592 |->cont_cat: // RA = resultptr, RB = meta base
593 | lwz INS, -4(PC)
594 | subi CARG2, RB, 16
595 | decode_RB8 SAVE0, INS
596 | evldd TMP0, 0(RA)
597 | add TMP1, BASE, SAVE0
598 | stw BASE, L->base
599 | cmplw TMP1, CARG2
600 | sub CARG3, CARG2, TMP1
601 | decode_RA8 RA, INS
602 | evstdd TMP0, 0(CARG2)
603 | bne ->BC_CAT_Z
604 | evstddx TMP0, BASE, RA
605 | b ->cont_nop
606 |
607 |//-- Table indexing metamethods -----------------------------------------
608 |
609 |->vmeta_tgets1:
610 | evmergelo STR:RC, TISSTR, STR:RC
611 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
612 | decode_RB8 RB, INS
613 | evstdd STR:RC, 0(CARG3)
614 | add CARG2, BASE, RB
615 | b >1
616 |
617 |->vmeta_tgets:
618 | evmergelo TAB:RB, TISTAB, TAB:RB
619 | la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
620 | evmergelo STR:RC, TISSTR, STR:RC
621 | evstdd TAB:RB, 0(CARG2)
622 | la CARG3, DISPATCH_GL(tmptv2)(DISPATCH)
623 | evstdd STR:RC, 0(CARG3)
624 | b >1
625 |
626 |->vmeta_tgetb: // TMP0 = index
627 | efdcfsi TMP0, TMP0
628 | decode_RB8 RB, INS
629 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
630 | add CARG2, BASE, RB
631 | evstdd TMP0, 0(CARG3)
632 | b >1
633 |
634 |->vmeta_tgetv:
635 | decode_RB8 RB, INS
636 | decode_RC8 RC, INS
637 | add CARG2, BASE, RB
638 | add CARG3, BASE, RC
639 |1:
640 | stw BASE, L->base
641 | mr CARG1, L
642 | stw PC, SAVE_PC
643 | bl extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
644 | // Returns TValue * (finished) or NULL (metamethod).
645 | cmplwi CRET1, 0
646 | beq >3
647 | evldd TMP0, 0(CRET1)
648 | evstddx TMP0, BASE, RA
649 | ins_next
650 |
651 |3: // Call __index metamethod.
652 | // BASE = base, L->top = new base, stack = cont/func/t/k
653 | subfic TMP1, BASE, FRAME_CONT
654 | lwz BASE, L->top
655 | stw PC, -16(BASE) // [cont|PC]
656 | add PC, TMP1, BASE
657 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
658 | li NARGS8:RC, 16 // 2 args for func(t, k).
659 | b ->vm_call_dispatch_f
660 |
661 |//-----------------------------------------------------------------------
662 |
663 |->vmeta_tsets1:
664 | evmergelo STR:RC, TISSTR, STR:RC
665 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
666 | decode_RB8 RB, INS
667 | evstdd STR:RC, 0(CARG3)
668 | add CARG2, BASE, RB
669 | b >1
670 |
671 |->vmeta_tsets:
672 | evmergelo TAB:RB, TISTAB, TAB:RB
673 | la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
674 | evmergelo STR:RC, TISSTR, STR:RC
675 | evstdd TAB:RB, 0(CARG2)
676 | la CARG3, DISPATCH_GL(tmptv2)(DISPATCH)
677 | evstdd STR:RC, 0(CARG3)
678 | b >1
679 |
680 |->vmeta_tsetb: // TMP0 = index
681 | efdcfsi TMP0, TMP0
682 | decode_RB8 RB, INS
683 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
684 | add CARG2, BASE, RB
685 | evstdd TMP0, 0(CARG3)
686 | b >1
687 |
688 |->vmeta_tsetv:
689 | decode_RB8 RB, INS
690 | decode_RC8 RC, INS
691 | add CARG2, BASE, RB
692 | add CARG3, BASE, RC
693 |1:
694 | stw BASE, L->base
695 | mr CARG1, L
696 | stw PC, SAVE_PC
697 | bl extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
698 | // Returns TValue * (finished) or NULL (metamethod).
699 | cmplwi CRET1, 0
700 | evlddx TMP0, BASE, RA
701 | beq >3
702 | // NOBARRIER: lj_meta_tset ensures the table is not black.
703 | evstdd TMP0, 0(CRET1)
704 | ins_next
705 |
706 |3: // Call __newindex metamethod.
707 | // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
708 | subfic TMP1, BASE, FRAME_CONT
709 | lwz BASE, L->top
710 | stw PC, -16(BASE) // [cont|PC]
711 | add PC, TMP1, BASE
712 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
713 | li NARGS8:RC, 24 // 3 args for func(t, k, v)
714 | evstdd TMP0, 16(BASE) // Copy value to third argument.
715 | b ->vm_call_dispatch_f
716 |
717 |//-- Comparison metamethods ---------------------------------------------
718 |
719 |->vmeta_comp:
720 | mr CARG1, L
721 | subi PC, PC, 4
722 | add CARG2, BASE, RA
723 | stw PC, SAVE_PC
724 | add CARG3, BASE, RD
725 | stw BASE, L->base
726 | decode_OP1 CARG4, INS
727 | bl extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
728 | // Returns 0/1 or TValue * (metamethod).
729 |3:
730 | cmplwi CRET1, 1
731 | bgt ->vmeta_binop
732 |4:
733 | lwz INS, 0(PC)
734 | addi PC, PC, 4
735 | decode_RD4 TMP2, INS
736 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
737 | add TMP2, TMP2, TMP3
738 | isellt PC, PC, TMP2
739 |->cont_nop:
740 | ins_next
741 |
742 |->cont_ra: // RA = resultptr
743 | lwz INS, -4(PC)
744 | evldd TMP0, 0(RA)
745 | decode_RA8 TMP1, INS
746 | evstddx TMP0, BASE, TMP1
747 | b ->cont_nop
748 |
749 |->cont_condt: // RA = resultptr
750 | lwz TMP0, 0(RA)
751 | li TMP1, LJ_TTRUE
752 | cmplw TMP1, TMP0 // Branch if result is true.
753 | b <4
754 |
755 |->cont_condf: // RA = resultptr
756 | lwz TMP0, 0(RA)
757 | li TMP1, LJ_TFALSE
758 | cmplw TMP0, TMP1 // Branch if result is false.
759 | b <4
760 |
761 |->vmeta_equal:
762 | // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV.
763 | subi PC, PC, 4
764 | stw BASE, L->base
765 | mr CARG1, L
766 | stw PC, SAVE_PC
767 | bl extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
768 | // Returns 0/1 or TValue * (metamethod).
769 | b <3
770 |
771 |//-- Arithmetic metamethods ---------------------------------------------
772 |
773 |->vmeta_arith_vn:
774 | add CARG3, BASE, RB
775 | add CARG4, KBASE, RC
776 | b >1
777 |
778 |->vmeta_arith_nv:
779 | add CARG3, KBASE, RC
780 | add CARG4, BASE, RB
781 | b >1
782 |
783 |->vmeta_unm:
784 | add CARG3, BASE, RD
785 | mr CARG4, CARG3
786 | b >1
787 |
788 |->vmeta_arith_vv:
789 | add CARG3, BASE, RB
790 | add CARG4, BASE, RC
791 |1:
792 | add CARG2, BASE, RA
793 | stw BASE, L->base
794 | mr CARG1, L
795 | stw PC, SAVE_PC
796 | decode_OP1 CARG5, INS // Caveat: CARG5 overlaps INS.
797 | bl extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
798 | // Returns NULL (finished) or TValue * (metamethod).
799 | cmplwi CRET1, 0
800 | beq ->cont_nop
801 |
802 | // Call metamethod for binary op.
803 |->vmeta_binop:
804 | // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2
805 | sub TMP1, CRET1, BASE
806 | stw PC, -16(CRET1) // [cont|PC]
807 | mr TMP2, BASE
808 | addi PC, TMP1, FRAME_CONT
809 | mr BASE, CRET1
810 | li NARGS8:RC, 16 // 2 args for func(o1, o2).
811 | b ->vm_call_dispatch
812 |
813 |->vmeta_len:
814#ifdef LUAJIT_ENABLE_LUA52COMPAT
815 | mr SAVE0, CARG1
816#endif
817 | add CARG2, BASE, RD
818 | stw BASE, L->base
819 | mr CARG1, L
820 | stw PC, SAVE_PC
821 | bl extern lj_meta_len // (lua_State *L, TValue *o)
822 | // Returns NULL (retry) or TValue * (metamethod base).
823#ifdef LUAJIT_ENABLE_LUA52COMPAT
824 | cmplwi CRET1, 0
825 | bne ->vmeta_binop // Binop call for compatibility.
826 | mr CARG1, SAVE0
827 | b ->BC_LEN_Z
828#else
829 | b ->vmeta_binop // Binop call for compatibility.
830#endif
831 |
832 |//-- Call metamethod ----------------------------------------------------
833 |
834 |->vmeta_call: // Resolve and call __call metamethod.
835 | // TMP2 = old base, BASE = new base, RC = nargs*8
836 | mr CARG1, L
837 | stw TMP2, L->base // This is the callers base!
838 | subi CARG2, BASE, 8
839 | stw PC, SAVE_PC
840 | add CARG3, BASE, RC
841 | mr SAVE0, NARGS8:RC
842 | bl extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
843 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
844 | addi NARGS8:RC, SAVE0, 8 // Got one more argument now.
845 | ins_call
846 |
847 |->vmeta_callt: // Resolve __call for BC_CALLT.
848 | // BASE = old base, RA = new base, RC = nargs*8
849 | mr CARG1, L
850 | stw BASE, L->base
851 | subi CARG2, RA, 8
852 | stw PC, SAVE_PC
853 | add CARG3, RA, RC
854 | mr SAVE0, NARGS8:RC
855 | bl extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
856 | lwz TMP1, FRAME_PC(BASE)
857 | addi NARGS8:RC, SAVE0, 8 // Got one more argument now.
858 | lwz LFUNC:RB, FRAME_FUNC(RA) // Guaranteed to be a function here.
859 | b ->BC_CALLT_Z
860 |
861 |//-- Argument coercion for 'for' statement ------------------------------
862 |
863 |->vmeta_for:
864 | mr CARG1, L
865 | stw BASE, L->base
866 | mr CARG2, RA
867 | stw PC, SAVE_PC
868 | mr SAVE0, INS
869 | bl extern lj_meta_for // (lua_State *L, TValue *base)
870#if LJ_HASJIT
871 | decode_OP1 TMP0, SAVE0
872#endif
873 | decode_RA8 RA, SAVE0
874#if LJ_HASJIT
875 | cmpwi TMP0, BC_JFORI
876#endif
877 | decode_RD8 RD, SAVE0
878#if LJ_HASJIT
879 | beq =>BC_JFORI
880#endif
881 | b =>BC_FORI
882 |
883 |//-----------------------------------------------------------------------
884 |//-- Fast functions -----------------------------------------------------
885 |//-----------------------------------------------------------------------
886 |
887 |.macro .ffunc, name
888 |->ff_ .. name:
889 |.endmacro
890 |
891 |.macro .ffunc_1, name
892 |->ff_ .. name:
893 | cmplwi NARGS8:RC, 8
894 | evldd CARG1, 0(BASE)
895 | blt ->fff_fallback
896 |.endmacro
897 |
898 |.macro .ffunc_2, name
899 |->ff_ .. name:
900 | cmplwi NARGS8:RC, 16
901 | evldd CARG1, 0(BASE)
902 | evldd CARG2, 8(BASE)
903 | blt ->fff_fallback
904 |.endmacro
905 |
906 |.macro .ffunc_n, name
907 | .ffunc_1 name
908 | checknum CARG1
909 | checkfail ->fff_fallback
910 |.endmacro
911 |
912 |.macro .ffunc_nn, name
913 | .ffunc_2 name
914 | evmergehi TMP0, CARG1, CARG2
915 | checknum TMP0
916 | checkanyfail ->fff_fallback
917 |.endmacro
918 |
919 |// Inlined GC threshold check. Caveat: uses TMP0 and TMP1.
920 |.macro ffgccheck
921 | lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
922 | lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
923 | cmplw TMP0, TMP1
924 | bgel ->fff_gcstep
925 |.endmacro
926 |
927 |//-- Base library: checks -----------------------------------------------
928 |
929 |.ffunc assert
930 | cmplwi NARGS8:RC, 8
931 | evldd TMP0, 0(BASE)
932 | blt ->fff_fallback
933 | evaddw TMP1, TISNIL, TISNIL // Synthesize LJ_TFALSE.
934 | la RA, -8(BASE)
935 | evcmpltu cr1, TMP0, TMP1
936 | lwz PC, FRAME_PC(BASE)
937 | bge cr1, ->fff_fallback
938 | evstdd TMP0, 0(RA)
939 | addi RD, NARGS8:RC, 8 // Compute (nresults+1)*8.
940 | beq ->fff_res // Done if exactly 1 argument.
941 | li TMP1, 8
942 | subi RC, RC, 8
943 |1:
944 | cmplw TMP1, RC
945 | evlddx TMP0, BASE, TMP1
946 | evstddx TMP0, RA, TMP1
947 | addi TMP1, TMP1, 8
948 | bne <1
949 | b ->fff_res
950 |
951 |.ffunc type
952 | cmplwi NARGS8:RC, 8
953 | lwz CARG1, 0(BASE)
954 | blt ->fff_fallback
955 | li TMP2, ~LJ_TNUMX
956 | cmplw CARG1, TISNUM
957 | not TMP1, CARG1
958 | isellt TMP1, TMP2, TMP1
959 | slwi TMP1, TMP1, 3
960 | la TMP2, CFUNC:RB->upvalue
961 | evlddx STR:CRET1, TMP2, TMP1
962 | b ->fff_restv
963 |
964 |//-- Base library: getters and setters ---------------------------------
965 |
966 |.ffunc_1 getmetatable
967 | checktab CARG1
968 | evmergehi TMP1, CARG1, CARG1
969 | checkfail >6
970 |1: // Field metatable must be at same offset for GCtab and GCudata!
971 | lwz TAB:RB, TAB:CARG1->metatable
972 |2:
973 | evmr CRET1, TISNIL
974 | cmplwi TAB:RB, 0
975 | lwz STR:RC, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])(DISPATCH)
976 | beq ->fff_restv
977 | lwz TMP0, TAB:RB->hmask
978 | evmergelo CRET1, TISTAB, TAB:RB // Use metatable as default result.
979 | lwz TMP1, STR:RC->hash
980 | lwz NODE:TMP2, TAB:RB->node
981 | evmergelo STR:RC, TISSTR, STR:RC
982 | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
983 | slwi TMP0, TMP1, 5
984 | slwi TMP1, TMP1, 3
985 | sub TMP1, TMP0, TMP1
986 | add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
987 |3: // Rearranged logic, because we expect _not_ to find the key.
988 | evldd TMP0, NODE:TMP2->key
989 | evldd TMP1, NODE:TMP2->val
990 | evcmpeq TMP0, STR:RC
991 | lwz NODE:TMP2, NODE:TMP2->next
992 | checkallok >5
993 | cmplwi NODE:TMP2, 0
994 | beq ->fff_restv // Not found, keep default result.
995 | b <3
996 |5:
997 | checknil TMP1
998 | checkok ->fff_restv // Ditto for nil value.
999 | evmr CRET1, TMP1 // Return value of mt.__metatable.
1000 | b ->fff_restv
1001 |
1002 |6:
1003 | cmpwi TMP1, LJ_TUDATA
1004 | not TMP1, TMP1
1005 | beq <1
1006 | checknum CARG1
1007 | slwi TMP1, TMP1, 2
1008 | li TMP2, 4*~LJ_TNUMX
1009 | isellt TMP1, TMP2, TMP1
1010 | la TMP2, DISPATCH_GL(gcroot[GCROOT_BASEMT])(DISPATCH)
1011 | lwzx TAB:RB, TMP2, TMP1
1012 | b <2
1013 |
1014 |.ffunc_2 setmetatable
1015 | // Fast path: no mt for table yet and not clearing the mt.
1016 | evmergehi TMP0, TAB:CARG1, TAB:CARG2
1017 | checktab TMP0
1018 | checkanyfail ->fff_fallback
1019 | lwz TAB:TMP1, TAB:CARG1->metatable
1020 | cmplwi TAB:TMP1, 0
1021 | lbz TMP3, TAB:CARG1->marked
1022 | bne ->fff_fallback
1023 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
1024 | stw TAB:CARG2, TAB:CARG1->metatable
1025 | beq ->fff_restv
1026 | barrierback TAB:CARG1, TMP3, TMP0
1027 | b ->fff_restv
1028 |
1029 |.ffunc rawget
1030 | cmplwi NARGS8:RC, 16
1031 | evldd CARG2, 0(BASE)
1032 | blt ->fff_fallback
1033 | checktab CARG2
1034 | la CARG3, 8(BASE)
1035 | checkfail ->fff_fallback
1036 | mr CARG1, L
1037 | bl extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
1038 | // Returns cTValue *.
1039 | evldd CRET1, 0(CRET1)
1040 | b ->fff_restv
1041 |
1042 |//-- Base library: conversions ------------------------------------------
1043 |
1044 |.ffunc tonumber
1045 | // Only handles the number case inline (without a base argument).
1046 | cmplwi NARGS8:RC, 8
1047 | evldd CARG1, 0(BASE)
1048 | bne ->fff_fallback // Exactly one argument.
1049 | checknum CARG1
1050 | checkok ->fff_restv
1051 | b ->fff_fallback
1052 |
1053 |.ffunc_1 tostring
1054 | // Only handles the string or number case inline.
1055 | checkstr CARG1
1056 | // A __tostring method in the string base metatable is ignored.
1057 | checkok ->fff_restv // String key?
1058 | // Handle numbers inline, unless a number base metatable is present.
1059 | lwz TMP0, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH)
1060 | checknum CARG1
1061 | cmplwi cr1, TMP0, 0
1062 | stw BASE, L->base // Add frame since C call can throw.
1063 | crand 4*cr0+eq, 4*cr0+lt, 4*cr1+eq
1064 | stw PC, SAVE_PC // Redundant (but a defined value).
1065 | bne ->fff_fallback
1066 | ffgccheck
1067 | mr CARG1, L
1068 | mr CARG2, BASE
1069 | bl extern lj_str_fromnum // (lua_State *L, lua_Number *np)
1070 | // Returns GCstr *.
1071 | evmergelo STR:CRET1, TISSTR, STR:CRET1
1072 | b ->fff_restv
1073 |
1074 |//-- Base library: iterators -------------------------------------------
1075 |
1076 |.ffunc next
1077 | cmplwi NARGS8:RC, 8
1078 | evldd CARG2, 0(BASE)
1079 | blt ->fff_fallback
1080 | evstddx TISNIL, BASE, NARGS8:RC // Set missing 2nd arg to nil.
1081 | checktab TAB:CARG2
1082 | lwz PC, FRAME_PC(BASE)
1083 | checkfail ->fff_fallback
1084 | stw BASE, L->base // Add frame since C call can throw.
1085 | mr CARG1, L
1086 | stw BASE, L->top // Dummy frame length is ok.
1087 | la CARG3, 8(BASE)
1088 | stw PC, SAVE_PC
1089 | bl extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
1090 | // Returns 0 at end of traversal.
1091 | cmplwi CRET1, 0
1092 | evmr CRET1, TISNIL
1093 | beq ->fff_restv // End of traversal: return nil.
1094 | evldd TMP0, 8(BASE) // Copy key and value to results.
1095 | la RA, -8(BASE)
1096 | evldd TMP1, 16(BASE)
1097 | evstdd TMP0, 0(RA)
1098 | li RD, (2+1)*8
1099 | evstdd TMP1, 8(RA)
1100 | b ->fff_res
1101 |
1102 |.ffunc_1 pairs
1103 | checktab TAB:CARG1
1104 | lwz PC, FRAME_PC(BASE)
1105 | checkfail ->fff_fallback
1106#ifdef LUAJIT_ENABLE_LUA52COMPAT
1107 | lwz TAB:TMP2, TAB:CARG1->metatable
1108 | evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
1109 | cmplwi TAB:TMP2, 0
1110 | la RA, -8(BASE)
1111 | bne ->fff_fallback
1112#else
1113 | evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
1114 | la RA, -8(BASE)
1115#endif
1116 | evstdd TISNIL, 8(BASE)
1117 | li RD, (3+1)*8
1118 | evstdd CFUNC:TMP0, 0(RA)
1119 | b ->fff_res
1120 |
1121 |.ffunc_2 ipairs_aux
1122 | checktab TAB:CARG1
1123 | lwz PC, FRAME_PC(BASE)
1124 | checkfail ->fff_fallback
1125 | checknum CARG2
1126 | lus TMP3, 0x3ff0
1127 | checkfail ->fff_fallback
1128 | efdctsi TMP2, CARG2
1129 | lwz TMP0, TAB:CARG1->asize
1130 | evmergelo TMP3, TMP3, ZERO
1131 | lwz TMP1, TAB:CARG1->array
1132 | efdadd CARG2, CARG2, TMP3
1133 | addi TMP2, TMP2, 1
1134 | la RA, -8(BASE)
1135 | cmplw TMP0, TMP2
1136 | slwi TMP3, TMP2, 3
1137 | evstdd CARG2, 0(RA)
1138 | ble >2 // Not in array part?
1139 | evlddx TMP1, TMP1, TMP3
1140 |1:
1141 | checknil TMP1
1142 | li RD, (0+1)*8
1143 | checkok ->fff_res // End of iteration, return 0 results.
1144 | li RD, (2+1)*8
1145 | evstdd TMP1, 8(RA)
1146 | b ->fff_res
1147 |2: // Check for empty hash part first. Otherwise call C function.
1148 | lwz TMP0, TAB:CARG1->hmask
1149 | cmplwi TMP0, 0
1150 | li RD, (0+1)*8
1151 | beq ->fff_res
1152 | mr CARG2, TMP2
1153 | bl extern lj_tab_getinth // (GCtab *t, int32_t key)
1154 | // Returns cTValue * or NULL.
1155 | cmplwi CRET1, 0
1156 | li RD, (0+1)*8
1157 | beq ->fff_res
1158 | evldd TMP1, 0(CRET1)
1159 | b <1
1160 |
1161 |.ffunc_1 ipairs
1162 | checktab TAB:CARG1
1163 | lwz PC, FRAME_PC(BASE)
1164 | checkfail ->fff_fallback
1165#ifdef LUAJIT_ENABLE_LUA52COMPAT
1166 | lwz TAB:TMP2, TAB:CARG1->metatable
1167 | evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
1168 | cmplwi TAB:TMP2, 0
1169 | la RA, -8(BASE)
1170 | bne ->fff_fallback
1171#else
1172 | evldd CFUNC:TMP0, CFUNC:RB->upvalue[0]
1173 | la RA, -8(BASE)
1174#endif
1175 | evsplati TMP1, 0
1176 | li RD, (3+1)*8
1177 | evstdd TMP1, 8(BASE)
1178 | evstdd CFUNC:TMP0, 0(RA)
1179 | b ->fff_res
1180 |
1181 |//-- Base library: catch errors ----------------------------------------
1182 |
1183 |.ffunc pcall
1184 | cmplwi NARGS8:RC, 8
1185 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1186 | blt ->fff_fallback
1187 | mr TMP2, BASE
1188 | la BASE, 8(BASE)
1189 | // Remember active hook before pcall.
1190 | rlwinm TMP3, TMP3, 32-HOOK_ACTIVE_SHIFT, 31, 31
1191 | subi NARGS8:RC, NARGS8:RC, 8
1192 | addi PC, TMP3, 8+FRAME_PCALL
1193 | b ->vm_call_dispatch
1194 |
1195 |.ffunc_2 xpcall
1196 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1197 | mr TMP2, BASE
1198 | checkfunc CARG2 // Traceback must be a function.
1199 | checkfail ->fff_fallback
1200 | la BASE, 16(BASE)
1201 | // Remember active hook before pcall.
1202 | rlwinm TMP3, TMP3, 32-HOOK_ACTIVE_SHIFT, 31, 31
1203 | evstdd CARG2, 0(TMP2) // Swap function and traceback.
1204 | subi NARGS8:RC, NARGS8:RC, 16
1205 | evstdd CARG1, 8(TMP2)
1206 | addi PC, TMP3, 16+FRAME_PCALL
1207 | b ->vm_call_dispatch
1208 |
1209 |//-- Coroutine library --------------------------------------------------
1210 |
1211 |.macro coroutine_resume_wrap, resume
1212 |.if resume
1213 |.ffunc_1 coroutine_resume
1214 | evmergehi TMP0, L:CARG1, L:CARG1
1215 |.else
1216 |.ffunc coroutine_wrap_aux
1217 | lwz L:CARG1, CFUNC:RB->upvalue[0].gcr
1218 |.endif
1219 |.if resume
1220 | cmpwi TMP0, LJ_TTHREAD
1221 | bne ->fff_fallback
1222 |.endif
1223 | lbz TMP0, L:CARG1->status
1224 | lwz TMP1, L:CARG1->cframe
1225 | lwz CARG2, L:CARG1->top
1226 | cmplwi cr0, TMP0, LUA_YIELD
1227 | lwz TMP2, L:CARG1->base
1228 | cmplwi cr1, TMP1, 0
1229 | lwz TMP0, L:CARG1->maxstack
1230 | cmplw cr7, CARG2, TMP2
1231 | lwz PC, FRAME_PC(BASE)
1232 | crorc 4*cr6+lt, 4*cr0+gt, 4*cr1+eq // st>LUA_YIELD || cframe!=0
1233 | add TMP2, CARG2, NARGS8:RC
1234 | crandc 4*cr6+gt, 4*cr7+eq, 4*cr0+eq // base==top && st!=LUA_YIELD
1235 | cmplw cr1, TMP2, TMP0
1236 | cror 4*cr6+lt, 4*cr6+lt, 4*cr6+gt
1237 | stw PC, SAVE_PC
1238 | cror 4*cr6+lt, 4*cr6+lt, 4*cr1+gt // cond1 || cond2 || stackov
1239 | stw BASE, L->base
1240 | blt cr6, ->fff_fallback
1241 |1:
1242 |.if resume
1243 | addi BASE, BASE, 8 // Keep resumed thread in stack for GC.
1244 | subi NARGS8:RC, NARGS8:RC, 8
1245 | subi TMP2, TMP2, 8
1246 |.endif
1247 | stw TMP2, L:CARG1->top
1248 | li TMP1, 0
1249 | stw BASE, L->top
1250 |2: // Move args to coroutine.
1251 | cmpw TMP1, NARGS8:RC
1252 | evlddx TMP0, BASE, TMP1
1253 | beq >3
1254 | evstddx TMP0, CARG2, TMP1
1255 | addi TMP1, TMP1, 8
1256 | b <2
1257 |3:
1258 | li CARG3, 0
1259 | mr L:SAVE0, L:CARG1
1260 | li CARG4, 0
1261 | bl ->vm_resume // (lua_State *L, TValue *base, 0, 0)
1262 | // Returns thread status.
1263 |4:
1264 | lwz TMP2, L:SAVE0->base
1265 | cmplwi CRET1, LUA_YIELD
1266 | lwz TMP3, L:SAVE0->top
1267 | li_vmstate INTERP
1268 | lwz BASE, L->base
1269 | st_vmstate
1270 | bgt >8
1271 | sub RD, TMP3, TMP2
1272 | lwz TMP0, L->maxstack
1273 | cmplwi RD, 0
1274 | add TMP1, BASE, RD
1275 | beq >6 // No results?
1276 | cmplw TMP1, TMP0
1277 | li TMP1, 0
1278 | bgt >9 // Need to grow stack?
1279 |
1280 | subi TMP3, RD, 8
1281 | stw TMP2, L:SAVE0->top // Clear coroutine stack.
1282 |5: // Move results from coroutine.
1283 | cmplw TMP1, TMP3
1284 | evlddx TMP0, TMP2, TMP1
1285 | evstddx TMP0, BASE, TMP1
1286 | addi TMP1, TMP1, 8
1287 | bne <5
1288 |6:
1289 | andi. TMP0, PC, FRAME_TYPE
1290 |.if resume
1291 | li TMP1, LJ_TTRUE
1292 | la RA, -8(BASE)
1293 | stw TMP1, -8(BASE) // Prepend true to results.
1294 | addi RD, RD, 16
1295 |.else
1296 | mr RA, BASE
1297 | addi RD, RD, 8
1298 |.endif
1299 |7:
1300 | stw PC, SAVE_PC
1301 | mr MULTRES, RD
1302 | beq ->BC_RET_Z
1303 | b ->vm_return
1304 |
1305 |8: // Coroutine returned with error (at co->top-1).
1306 |.if resume
1307 | andi. TMP0, PC, FRAME_TYPE
1308 | la TMP3, -8(TMP3)
1309 | li TMP1, LJ_TFALSE
1310 | evldd TMP0, 0(TMP3)
1311 | stw TMP3, L:SAVE0->top // Remove error from coroutine stack.
1312 | li RD, (2+1)*8
1313 | stw TMP1, -8(BASE) // Prepend false to results.
1314 | la RA, -8(BASE)
1315 | evstdd TMP0, 0(BASE) // Copy error message.
1316 | b <7
1317 |.else
1318 | mr CARG1, L
1319 | mr CARG2, L:SAVE0
1320 | bl extern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co)
1321 |.endif
1322 |
1323 |9: // Handle stack expansion on return from yield.
1324 | mr CARG1, L
1325 | srwi CARG2, RD, 3
1326 | bl extern lj_state_growstack // (lua_State *L, int n)
1327 | li CRET1, 0
1328 | b <4
1329 |.endmacro
1330 |
1331 | coroutine_resume_wrap 1 // coroutine.resume
1332 | coroutine_resume_wrap 0 // coroutine.wrap
1333 |
1334 |.ffunc coroutine_yield
1335 | lwz TMP0, L->cframe
1336 | add TMP1, BASE, NARGS8:RC
1337 | stw BASE, L->base
1338 | andi. TMP0, TMP0, CFRAME_RESUME
1339 | stw TMP1, L->top
1340 | li CRET1, LUA_YIELD
1341 | beq ->fff_fallback
1342 | stw ZERO, L->cframe
1343 | stb CRET1, L->status
1344 | b ->vm_leave_unw
1345 |
1346 |//-- Math library -------------------------------------------------------
1347 |
1348 |.ffunc_n math_abs
1349 | efdabs CRET1, CARG1
1350 | // Fallthrough.
1351 |
1352 |->fff_restv:
1353 | // CRET1 = TValue result.
1354 | lwz PC, FRAME_PC(BASE)
1355 | la RA, -8(BASE)
1356 | evstdd CRET1, 0(RA)
1357 |->fff_res1:
1358 | // RA = results, PC = return.
1359 | li RD, (1+1)*8
1360 |->fff_res:
1361 | // RA = results, RD = (nresults+1)*8, PC = return.
1362 | andi. TMP0, PC, FRAME_TYPE
1363 | mr MULTRES, RD
1364 | bne ->vm_return
1365 | lwz INS, -4(PC)
1366 | decode_RB8 RB, INS
1367 |5:
1368 | cmplw RB, RD // More results expected?
1369 | decode_RA8 TMP0, INS
1370 | bgt >6
1371 | ins_next1
1372 | // Adjust BASE. KBASE is assumed to be set for the calling frame.
1373 | sub BASE, RA, TMP0
1374 | ins_next2
1375 |
1376 |6: // Fill up results with nil.
1377 | subi TMP1, RD, 8
1378 | addi RD, RD, 8
1379 | evstddx TISNIL, RA, TMP1
1380 | b <5
1381 |
1382 |.macro math_extern, func
1383 | .ffunc math_ .. func
1384 | cmplwi NARGS8:RC, 8
1385 | evldd CARG2, 0(BASE)
1386 | blt ->fff_fallback
1387 | checknum CARG2
1388 | evmergehi CARG1, CARG2, CARG2
1389 | checkfail ->fff_fallback
1390 | bl extern func
1391 | evmergelo CRET1, CRET1, CRET2
1392 | b ->fff_restv
1393 |.endmacro
1394 |
1395 |.macro math_extern2, func
1396 | .ffunc math_ .. func
1397 | cmplwi NARGS8:RC, 16
1398 | evldd CARG2, 0(BASE)
1399 | evldd CARG4, 8(BASE)
1400 | blt ->fff_fallback
1401 | evmergehi CARG1, CARG4, CARG2
1402 | checknum CARG1
1403 | evmergehi CARG3, CARG4, CARG4
1404 | checkanyfail ->fff_fallback
1405 | bl extern func
1406 | evmergelo CRET1, CRET1, CRET2
1407 | b ->fff_restv
1408 |.endmacro
1409 |
1410 |.macro math_round, func
1411 | .ffunc math_ .. func
1412 | cmplwi NARGS8:RC, 8
1413 | evldd CARG2, 0(BASE)
1414 | blt ->fff_fallback
1415 | checknum CARG2
1416 | evmergehi CARG1, CARG2, CARG2
1417 | checkfail ->fff_fallback
1418 | lwz PC, FRAME_PC(BASE)
1419 | bl ->vm_..func.._hilo;
1420 | la RA, -8(BASE)
1421 | evstdd CRET2, 0(RA)
1422 | b ->fff_res1
1423 |.endmacro
1424 |
1425 | math_round floor
1426 | math_round ceil
1427 |
1428 | math_extern sqrt
1429 | math_extern log
1430 | math_extern log10
1431 | math_extern exp
1432 | math_extern sin
1433 | math_extern cos
1434 | math_extern tan
1435 | math_extern asin
1436 | math_extern acos
1437 | math_extern atan
1438 | math_extern sinh
1439 | math_extern cosh
1440 | math_extern tanh
1441 | math_extern2 pow
1442 | math_extern2 atan2
1443 | math_extern2 fmod
1444 |
1445 |->ff_math_deg:
1446 |.ffunc_n math_rad
1447 | evldd CARG2, CFUNC:RB->upvalue[0]
1448 | efdmul CRET1, CARG1, CARG2
1449 | b ->fff_restv
1450 |
1451 |.ffunc math_ldexp
1452 | cmplwi NARGS8:RC, 16
1453 | evldd CARG2, 0(BASE)
1454 | evldd CARG4, 8(BASE)
1455 | blt ->fff_fallback
1456 | evmergehi CARG1, CARG4, CARG2
1457 | checknum CARG1
1458 | checkanyfail ->fff_fallback
1459 | efdctsi CARG3, CARG4
1460 | bl extern ldexp
1461 | evmergelo CRET1, CRET1, CRET2
1462 | b ->fff_restv
1463 |
1464 |.ffunc math_frexp
1465 | cmplwi NARGS8:RC, 8
1466 | evldd CARG2, 0(BASE)
1467 | blt ->fff_fallback
1468 | checknum CARG2
1469 | evmergehi CARG1, CARG2, CARG2
1470 | checkfail ->fff_fallback
1471 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
1472 | lwz PC, FRAME_PC(BASE)
1473 | bl extern frexp
1474 | lwz TMP1, DISPATCH_GL(tmptv)(DISPATCH)
1475 | evmergelo CRET1, CRET1, CRET2
1476 | efdcfsi CRET2, TMP1
1477 | la RA, -8(BASE)
1478 | evstdd CRET1, 0(RA)
1479 | li RD, (2+1)*8
1480 | evstdd CRET2, 8(RA)
1481 | b ->fff_res
1482 |
1483 |.ffunc math_modf
1484 | cmplwi NARGS8:RC, 8
1485 | evldd CARG2, 0(BASE)
1486 | blt ->fff_fallback
1487 | checknum CARG2
1488 | evmergehi CARG1, CARG2, CARG2
1489 | checkfail ->fff_fallback
1490 | la CARG3, -8(BASE)
1491 | lwz PC, FRAME_PC(BASE)
1492 | bl extern modf
1493 | evmergelo CRET1, CRET1, CRET2
1494 | la RA, -8(BASE)
1495 | evstdd CRET1, 0(BASE)
1496 | li RD, (2+1)*8
1497 | b ->fff_res
1498 |
1499 |.macro math_minmax, name, cmpop
1500 | .ffunc_1 name
1501 | checknum CARG1
1502 | li TMP1, 8
1503 | checkfail ->fff_fallback
1504 |1:
1505 | evlddx CARG2, BASE, TMP1
1506 | cmplw cr1, TMP1, NARGS8:RC
1507 | checknum CARG2
1508 | bge cr1, ->fff_restv // Ok, since CRET1 = CARG1.
1509 | checkfail ->fff_fallback
1510 | cmpop CARG2, CARG1
1511 | addi TMP1, TMP1, 8
1512 | crmove 4*cr0+lt, 4*cr0+gt
1513 | evsel CARG1, CARG2, CARG1
1514 | b <1
1515 |.endmacro
1516 |
1517 | math_minmax math_min, efdtstlt
1518 | math_minmax math_max, efdtstgt
1519 |
1520 |//-- String library -----------------------------------------------------
1521 |
1522 |.ffunc_1 string_len
1523 | checkstr STR:CARG1
1524 | checkfail ->fff_fallback
1525 | lwz TMP0, STR:CARG1->len
1526 | efdcfsi CRET1, TMP0
1527 | b ->fff_restv
1528 |
1529 |.ffunc string_byte // Only handle the 1-arg case here.
1530 | cmplwi NARGS8:RC, 8
1531 | evldd STR:CARG1, 0(BASE)
1532 | bne ->fff_fallback // Need exactly 1 argument.
1533 | checkstr STR:CARG1
1534 | la RA, -8(BASE)
1535 | checkfail ->fff_fallback
1536 | lwz TMP0, STR:CARG1->len
1537 | li RD, (0+1)*8
1538 | lbz TMP1, STR:CARG1[1] // Access is always ok (NUL at end).
1539 | li TMP2, (1+1)*8
1540 | cmplwi TMP0, 0
1541 | lwz PC, FRAME_PC(BASE)
1542 | efdcfsi CRET1, TMP1
1543 | iseleq RD, RD, TMP2
1544 | evstdd CRET1, 0(RA)
1545 | b ->fff_res
1546 |
1547 |.ffunc string_char // Only handle the 1-arg case here.
1548 | ffgccheck
1549 | cmplwi NARGS8:RC, 8
1550 | evldd CARG1, 0(BASE)
1551 | bne ->fff_fallback // Exactly 1 argument.
1552 | checknum CARG1
1553 | la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
1554 | checkfail ->fff_fallback
1555 | efdctsiz TMP0, CARG1
1556 | li CARG3, 1
1557 | cmplwi TMP0, 255
1558 | stb TMP0, 0(CARG2)
1559 | bgt ->fff_fallback
1560 |->fff_newstr:
1561 | mr CARG1, L
1562 | stw BASE, L->base
1563 | stw PC, SAVE_PC
1564 | bl extern lj_str_new // (lua_State *L, char *str, size_t l)
1565 | // Returns GCstr *.
1566 | lwz BASE, L->base
1567 | evmergelo STR:CRET1, TISSTR, STR:CRET1
1568 | b ->fff_restv
1569 |
1570 |.ffunc string_sub
1571 | ffgccheck
1572 | cmplwi NARGS8:RC, 16
1573 | evldd CARG3, 16(BASE)
1574 | evldd STR:CARG1, 0(BASE)
1575 | blt ->fff_fallback
1576 | evldd CARG2, 8(BASE)
1577 | li TMP2, -1
1578 | beq >1
1579 | checknum CARG3
1580 | checkfail ->fff_fallback
1581 | efdctsiz TMP2, CARG3
1582 |1:
1583 | checknum CARG2
1584 | checkfail ->fff_fallback
1585 | checkstr STR:CARG1
1586 | efdctsiz TMP1, CARG2
1587 | checkfail ->fff_fallback
1588 | lwz TMP0, STR:CARG1->len
1589 | cmplw TMP0, TMP2 // len < end? (unsigned compare)
1590 | add TMP3, TMP2, TMP0
1591 | blt >5
1592 |2:
1593 | cmpwi TMP1, 0 // start <= 0?
1594 | add TMP3, TMP1, TMP0
1595 | ble >7
1596 |3:
1597 | sub. CARG3, TMP2, TMP1
1598 | addi CARG2, STR:CARG1, #STR-1
1599 | addi CARG3, CARG3, 1
1600 | add CARG2, CARG2, TMP1
1601 | isellt CARG3, r0, CARG3
1602 | b ->fff_newstr
1603 |
1604 |5: // Negative end or overflow.
1605 | cmpw TMP0, TMP2
1606 | addi TMP3, TMP3, 1
1607 | iselgt TMP2, TMP3, TMP0 // end = end > len ? len : end+len+1
1608 | b <2
1609 |
1610 |7: // Negative start or underflow.
1611 | cmpwi cr1, TMP3, 0
1612 | iseleq TMP1, r0, TMP3
1613 | isel TMP1, r0, TMP1, 4*cr1+lt
1614 | addi TMP1, TMP1, 1 // start = 1 + (start ? start+len : 0)
1615 | b <3
1616 |
1617 |.ffunc string_rep // Only handle the 1-char case inline.
1618 | ffgccheck
1619 | cmplwi NARGS8:RC, 16
1620 | evldd CARG1, 0(BASE)
1621 | evldd CARG2, 8(BASE)
1622 | blt ->fff_fallback
1623 | checknum CARG2
1624 | checkfail ->fff_fallback
1625 | checkstr STR:CARG1
1626 | efdctsiz CARG3, CARG2
1627 | checkfail ->fff_fallback
1628 | lwz TMP0, STR:CARG1->len
1629 | cmpwi CARG3, 0
1630 | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1631 | ble >2 // Count <= 0? (or non-int)
1632 | cmplwi TMP0, 1
1633 | subi TMP2, CARG3, 1
1634 | blt >2 // Zero length string?
1635 | cmplw cr1, TMP1, CARG3
1636 | bne ->fff_fallback // Fallback for > 1-char strings.
1637 | lbz TMP0, STR:CARG1[1]
1638 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1639 | blt cr1, ->fff_fallback
1640 |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
1641 | cmplwi TMP2, 0
1642 | stbx TMP0, CARG2, TMP2
1643 | subi TMP2, TMP2, 1
1644 | bne <1
1645 | b ->fff_newstr
1646 |2: // Return empty string.
1647 | la STR:CRET1, DISPATCH_GL(strempty)(DISPATCH)
1648 | evmergelo CRET1, TISSTR, STR:CRET1
1649 | b ->fff_restv
1650 |
1651 |.ffunc string_reverse
1652 | ffgccheck
1653 | cmplwi NARGS8:RC, 8
1654 | evldd CARG1, 0(BASE)
1655 | blt ->fff_fallback
1656 | checkstr STR:CARG1
1657 | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1658 | checkfail ->fff_fallback
1659 | lwz CARG3, STR:CARG1->len
1660 | la CARG1, #STR(STR:CARG1)
1661 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1662 | li TMP2, 0
1663 | cmplw TMP1, CARG3
1664 | subi TMP3, CARG3, 1
1665 | blt ->fff_fallback
1666 |1: // Reverse string copy.
1667 | cmpwi TMP3, 0
1668 | lbzx TMP1, CARG1, TMP2
1669 | blt ->fff_newstr
1670 | stbx TMP1, CARG2, TMP3
1671 | subi TMP3, TMP3, 1
1672 | addi TMP2, TMP2, 1
1673 | b <1
1674 |
1675 |.macro ffstring_case, name, lo
1676 | .ffunc name
1677 | ffgccheck
1678 | cmplwi NARGS8:RC, 8
1679 | evldd CARG1, 0(BASE)
1680 | blt ->fff_fallback
1681 | checkstr STR:CARG1
1682 | lwz TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1683 | checkfail ->fff_fallback
1684 | lwz CARG3, STR:CARG1->len
1685 | la CARG1, #STR(STR:CARG1)
1686 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1687 | cmplw TMP1, CARG3
1688 | li TMP2, 0
1689 | blt ->fff_fallback
1690 |1: // ASCII case conversion.
1691 | cmplw TMP2, CARG3
1692 | lbzx TMP1, CARG1, TMP2
1693 | bge ->fff_newstr
1694 | subi TMP0, TMP1, lo
1695 | xori TMP3, TMP1, 0x20
1696 | cmplwi TMP0, 26
1697 | isellt TMP1, TMP3, TMP1
1698 | stbx TMP1, CARG2, TMP2
1699 | addi TMP2, TMP2, 1
1700 | b <1
1701 |.endmacro
1702 |
1703 |ffstring_case string_lower, 65
1704 |ffstring_case string_upper, 97
1705 |
1706 |//-- Table library ------------------------------------------------------
1707 |
1708 |.ffunc_1 table_getn
1709 | checktab CARG1
1710 | checkfail ->fff_fallback
1711 | bl extern lj_tab_len // (GCtab *t)
1712 | // Returns uint32_t (but less than 2^31).
1713 | efdcfsi CRET1, CRET1
1714 | b ->fff_restv
1715 |
1716 |//-- Bit library --------------------------------------------------------
1717 |
1718 |.macro .ffunc_bit, name
1719 | .ffunc_n bit_..name
1720 | efdadd CARG1, CARG1, TOBIT
1721 |.endmacro
1722 |
1723 |.ffunc_bit tobit
1724 |->fff_resbit:
1725 | efdcfsi CRET1, CARG1
1726 | b ->fff_restv
1727 |
1728 |.macro .ffunc_bit_op, name, ins
1729 | .ffunc_bit name
1730 | li TMP1, 8
1731 |1:
1732 | evlddx CARG2, BASE, TMP1
1733 | cmplw cr1, TMP1, NARGS8:RC
1734 | checknum CARG2
1735 | bge cr1, ->fff_resbit
1736 | checkfail ->fff_fallback
1737 | efdadd CARG2, CARG2, TOBIT
1738 | ins CARG1, CARG1, CARG2
1739 | addi TMP1, TMP1, 8
1740 | b <1
1741 |.endmacro
1742 |
1743 |.ffunc_bit_op band, and
1744 |.ffunc_bit_op bor, or
1745 |.ffunc_bit_op bxor, xor
1746 |
1747 |.ffunc_bit bswap
1748 | rotlwi TMP0, CARG1, 8
1749 | rlwimi TMP0, CARG1, 24, 0, 7
1750 | rlwimi TMP0, CARG1, 24, 16, 23
1751 | efdcfsi CRET1, TMP0
1752 | b ->fff_restv
1753 |
1754 |.ffunc_bit bnot
1755 | not TMP0, CARG1
1756 | efdcfsi CRET1, TMP0
1757 | b ->fff_restv
1758 |
1759 |.macro .ffunc_bit_sh, name, ins, shmod
1760 | .ffunc_nn bit_..name
1761 | efdadd CARG2, CARG2, TOBIT
1762 | efdadd CARG1, CARG1, TOBIT
1763 |.if shmod == 1
1764 | rlwinm CARG2, CARG2, 0, 27, 31
1765 |.elif shmod == 2
1766 | neg CARG2, CARG2
1767 |.endif
1768 | ins TMP0, CARG1, CARG2
1769 | efdcfsi CRET1, TMP0
1770 | b ->fff_restv
1771 |.endmacro
1772 |
1773 |.ffunc_bit_sh lshift, slw, 1
1774 |.ffunc_bit_sh rshift, srw, 1
1775 |.ffunc_bit_sh arshift, sraw, 1
1776 |.ffunc_bit_sh rol, rotlw, 0
1777 |.ffunc_bit_sh ror, rotlw, 2
1778 |
1779 |//-----------------------------------------------------------------------
1780 |
1781 |->fff_fallback: // Call fast function fallback handler.
1782 | // BASE = new base, RB = CFUNC, RC = nargs*8
1783 | lwz TMP3, CFUNC:RB->f
1784 | add TMP1, BASE, NARGS8:RC
1785 | lwz PC, FRAME_PC(BASE) // Fallback may overwrite PC.
1786 | addi TMP0, TMP1, 8*LUA_MINSTACK
1787 | lwz TMP2, L->maxstack
1788 | stw PC, SAVE_PC // Redundant (but a defined value).
1789 | cmplw TMP0, TMP2
1790 | stw BASE, L->base
1791 | stw TMP1, L->top
1792 | mr CARG1, L
1793 | bgt >5 // Need to grow stack.
1794 | mtctr TMP3
1795 | bctrl // (lua_State *L)
1796 | // Either throws an error, or recovers and returns -1, 0 or nresults+1.
1797 | lwz BASE, L->base
1798 | cmpwi CRET1, 0
1799 | slwi RD, CRET1, 3
1800 | la RA, -8(BASE)
1801 | bgt ->fff_res // Returned nresults+1?
1802 |1: // Returned 0 or -1: retry fast path.
1803 | lwz TMP0, L->top
1804 | lwz LFUNC:RB, FRAME_FUNC(BASE)
1805 | sub NARGS8:RC, TMP0, BASE
1806 | bne ->vm_call_tail // Returned -1?
1807 | ins_callt // Returned 0: retry fast path.
1808 |
1809 |// Reconstruct previous base for vmeta_call during tailcall.
1810 |->vm_call_tail:
1811 | andi. TMP0, PC, FRAME_TYPE
1812 | rlwinm TMP1, PC, 0, 0, 28
1813 | bne >3
1814 | lwz INS, -4(PC)
1815 | decode_RA8 TMP1, INS
1816 |3:
1817 | sub TMP2, BASE, TMP1
1818 | b ->vm_call_dispatch // Resolve again for tailcall.
1819 |
1820 |5: // Grow stack for fallback handler.
1821 | li CARG2, LUA_MINSTACK
1822 | bl extern lj_state_growstack // (lua_State *L, int n)
1823 | lwz BASE, L->base
1824 | cmpw TMP0, TMP0 // Set 4*cr0+eq to force retry.
1825 | b <1
1826 |
1827 |->fff_gcstep: // Call GC step function.
1828 | // BASE = new base, RC = nargs*8
1829 | mflr SAVE0
1830 | stw BASE, L->base
1831 | add TMP0, BASE, NARGS8:RC
1832 | stw PC, SAVE_PC // Redundant (but a defined value).
1833 | stw TMP0, L->top
1834 | mr CARG1, L
1835 | bl extern lj_gc_step // (lua_State *L)
1836 | lwz BASE, L->base
1837 | mtlr SAVE0
1838 | lwz TMP0, L->top
1839 | sub NARGS8:RC, TMP0, BASE
1840 | lwz CFUNC:RB, FRAME_FUNC(BASE)
1841 | blr
1842 |
1843 |//-----------------------------------------------------------------------
1844 |//-- Special dispatch targets -------------------------------------------
1845 |//-----------------------------------------------------------------------
1846 |
1847 |->vm_record: // Dispatch target for recording phase.
1848#if LJ_HASJIT
1849 | NYI
1850#endif
1851 |
1852 |->vm_rethook: // Dispatch target for return hooks.
1853 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1854 | andi. TMP0, TMP3, HOOK_ACTIVE // Hook already active?
1855 | beq >1
1856 |5: // Re-dispatch to static ins.
1857 | addi TMP1, TMP1, GG_DISP2STATIC // Assumes decode_OP4 TMP1, INS.
1858 | lwzx TMP0, DISPATCH, TMP1
1859 | mtctr TMP0
1860 | bctr
1861 |
1862 |->vm_inshook: // Dispatch target for instr/line hooks.
1863 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
1864 | lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH)
1865 | andi. TMP0, TMP3, HOOK_ACTIVE // Hook already active?
1866 | rlwinm TMP0, TMP3, 31-LUA_HOOKLINE, 31, 0
1867 | bne <5
1868 |
1869 | cmpwi cr1, TMP0, 0
1870 | addic. TMP2, TMP2, -1
1871 | beq cr1, <5
1872 | stw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
1873 | beq >1
1874 | bge cr1, <5
1875 |1:
1876 | mr CARG1, L
1877 | stw MULTRES, SAVE_MULTRES
1878 | mr CARG2, PC
1879 | stw BASE, L->base
1880 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
1881 | bl extern lj_dispatch_ins // (lua_State *L, const BCIns *pc)
1882 |3:
1883 | lwz BASE, L->base
1884 |4: // Re-dispatch to static ins.
1885 | lwz INS, -4(PC)
1886 | decode_OP4 TMP1, INS
1887 | decode_RB8 RB, INS
1888 | addi TMP1, TMP1, GG_DISP2STATIC
1889 | decode_RD8 RD, INS
1890 | lwzx TMP0, DISPATCH, TMP1
1891 | decode_RA8 RA, INS
1892 | decode_RC8 RC, INS
1893 | mtctr TMP0
1894 | bctr
1895 |
1896 |->cont_hook: // Continue from hook yield.
1897 | addi PC, PC, 4
1898 | lwz MULTRES, -20(RB) // Restore MULTRES for *M ins.
1899 | b <4
1900 |
1901 |->vm_hotloop: // Hot loop counter underflow.
1902#if LJ_HASJIT
1903 | NYI
1904#endif
1905 |
1906 |->vm_callhook: // Dispatch target for call hooks.
1907 | mr CARG2, PC
1908#if LJ_HASJIT
1909 | b >1
1910#endif
1911 |
1912 |->vm_hotcall: // Hot call counter underflow.
1913#if LJ_HASJIT
1914 | ori CARG2, PC, 1
1915 |1:
1916#endif
1917 | add TMP0, BASE, RC
1918 | stw PC, SAVE_PC
1919 | mr CARG1, L
1920 | stw BASE, L->base
1921 | sub RA, RA, BASE
1922 | stw TMP0, L->top
1923 | bl extern lj_dispatch_call // (lua_State *L, const BCIns *pc)
1924 | // Returns ASMFunction.
1925 | lwz BASE, L->base
1926 | lwz TMP0, L->top
1927 | stw ZERO, SAVE_PC // Invalidate for subsequent line hook.
1928 | sub NARGS8:RC, TMP0, BASE
1929 | add RA, BASE, RA
1930 | lwz LFUNC:RB, FRAME_FUNC(BASE)
1931 | mtctr CRET1
1932 | bctr
1933 |
1934 |//-----------------------------------------------------------------------
1935 |//-- Trace exit handler -------------------------------------------------
1936 |//-----------------------------------------------------------------------
1937 |
1938 |->vm_exit_handler:
1939#if LJ_HASJIT
1940 | NYI
1941#endif
1942 |->vm_exit_interp:
1943#if LJ_HASJIT
1944 | NYI
1945#endif
1946 |
1947 |//-----------------------------------------------------------------------
1948 |//-- Math helper functions ----------------------------------------------
1949 |//-----------------------------------------------------------------------
1950 |
1951 |// FP value rounding. Called by math.floor/math.ceil fast functions
1952 |// and from JIT code.
1953 |//
1954 |// This can be inlined if the CPU has the frin/friz/frip/frim instructions.
1955 |// The alternative hard-float approaches have a deep dependency chain.
1956 |// The resulting latency is at least 3x-7x the double-precision FP latency
1957 |// (e500v2: 6cy, e600: 5cy, Cell: 10cy) or around 20-70 cycles.
1958 |//
1959 |// The soft-float approach is tedious, but much faster (e500v2: ~11cy/~6cy).
1960 |// However it relies on a fast way to transfer the FP value to GPRs
1961 |// (e500v2: 0cy for lo-word, 1cy for hi-word).
1962 |//
1963 |.macro vm_round, name, mode
1964 | // Used temporaries: TMP0, TMP1, TMP2, TMP3.
1965 |->name.._efd: // Input: CARG2, output: CRET2
1966 | evmergehi CARG1, CARG2, CARG2
1967 |->name.._hilo:
1968 | // Input: CARG1 (hi), CARG2 (hi, lo), output: CRET2
1969 | rlwinm TMP2, CARG1, 12, 21, 31
1970 | addic. TMP2, TMP2, -1023 // exp = exponent(x) - 1023
1971 | li TMP1, -1
1972 | cmplwi cr1, TMP2, 51 // 0 <= exp <= 51?
1973 | subfic TMP0, TMP2, 52
1974 | bgt cr1, >1
1975 | lus TMP3, 0xfff0
1976 | slw TMP0, TMP1, TMP0 // lomask = -1 << (52-exp)
1977 | sraw TMP1, TMP3, TMP2 // himask = (int32_t)0xfff00000 >> exp
1978 |.if mode == 2 // trunc(x):
1979 | evmergelo TMP0, TMP1, TMP0
1980 | evand CRET2, CARG2, TMP0 // hi &= himask, lo &= lomask
1981 |.else
1982 | andc TMP2, CARG2, TMP0
1983 | andc TMP3, CARG1, TMP1
1984 | or TMP2, TMP2, TMP3 // ztest = (hi&~himask) | (lo&~lomask)
1985 | srawi TMP3, CARG1, 31 // signmask = (int32_t)hi >> 31
1986 |.if mode == 0 // floor(x):
1987 | and. TMP2, TMP2, TMP3 // iszero = ((ztest & signmask) == 0)
1988 |.else // ceil(x):
1989 | andc. TMP2, TMP2, TMP3 // iszero = ((ztest & ~signmask) == 0)
1990 |.endif
1991 | and CARG2, CARG2, TMP0 // lo &= lomask
1992 | and CARG1, CARG1, TMP1 // hi &= himask
1993 | subc TMP0, CARG2, TMP0
1994 | iseleq TMP0, CARG2, TMP0 // lo = iszero ? lo : lo-lomask
1995 | sube TMP1, CARG1, TMP1
1996 | iseleq TMP1, CARG1, TMP1 // hi = iszero ? hi : hi-himask+carry
1997 | evmergelo CRET2, TMP1, TMP0
1998 |.endif
1999 | blr
2000 |1:
2001 | bgtlr // Already done if >=2^52, +-inf or nan.
2002 |.if mode == 2 // trunc(x):
2003 | rlwinm TMP1, CARG1, 0, 0, 0 // hi = sign(x)
2004 | li TMP0, 0
2005 | evmergelo CRET2, TMP1, TMP0
2006 |.else
2007 | rlwinm TMP2, CARG1, 0, 1, 31
2008 | srawi TMP0, CARG1, 31 // signmask = (int32_t)hi >> 31
2009 | or TMP2, TMP2, CARG2 // ztest = abs(hi) | lo
2010 | lus TMP1, 0x3ff0
2011 |.if mode == 0 // floor(x):
2012 | and. TMP2, TMP2, TMP0 // iszero = ((ztest & signmask) == 0)
2013 |.else // ceil(x):
2014 | andc. TMP2, TMP2, TMP0 // iszero = ((ztest & ~signmask) == 0)
2015 |.endif
2016 | li TMP0, 0
2017 | iseleq TMP1, r0, TMP1
2018 | rlwimi CARG1, TMP1, 0, 1, 31 // hi = sign(x) | (iszero ? 0.0 : 1.0)
2019 | evmergelo CRET2, CARG1, TMP0
2020 |.endif
2021 | blr
2022 |.endmacro
2023 |
2024 |->vm_floor:
2025 | mflr CARG3
2026 | bl ->vm_floor_hilo
2027 | mtlr CARG3
2028 | evmergehi CRET1, CRET2, CRET2
2029 | blr
2030 |
2031 | vm_round vm_floor, 0
2032 | vm_round vm_ceil, 1
2033#if LJ_HASJIT
2034 | vm_round vm_trunc, 2
2035#else
2036 |->vm_trunc_efd:
2037 |->vm_trunc_hilo:
2038#endif
2039 |
2040 |// Callable from C: double lj_vm_foldarith(double x, double y, int op)
2041 |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
2042 |// and basic math functions. ORDER ARITH
2043 |->vm_foldarith:
2044 | evmergelo CARG2, CARG1, CARG2
2045 | cmplwi CARG5, 1
2046 | evmergelo CARG4, CARG3, CARG4
2047 | beq >1; bgt >2
2048 | efdadd CRET2, CARG2, CARG4; evmergehi CRET1, CRET2, CRET2; blr
2049 |1:
2050 | efdsub CRET2, CARG2, CARG4; evmergehi CRET1, CRET2, CRET2; blr
2051 |2:
2052 | cmplwi CARG5, 3; beq >1; bgt >2
2053 | efdmul CRET2, CARG2, CARG4; evmergehi CRET1, CRET2, CRET2; blr
2054 |1:
2055 | efddiv CRET2, CARG2, CARG4; evmergehi CRET1, CRET2, CRET2; blr
2056 |2:
2057 | cmplwi CARG5, 5; beq >1; bgt >2
2058 | evmr CARG3, CARG2; efddiv CRET2, CARG2, CARG4; evmr RB, CARG4
2059 | mflr RC; bl ->vm_floor_efd; mtlr RC
2060 | efdmul CRET2, CRET2, RB; efdsub CRET2, CARG3, CRET2
2061 | evmergehi CRET1, CRET2, CRET2; blr
2062 |1:
2063 | b extern pow
2064 |2:
2065 | cmplwi CARG5, 7; beq >1; bgt >2
2066 | xoris CARG1, CARG1, 0x8000; blr
2067 |1:
2068 | rlwinm CARG1, CARG1, 0, 1, 31; blr
2069 |2:
2070 | NYI // Other operations only needed by JIT compiler.
2071 |
2072 |//-----------------------------------------------------------------------
2073 |//-- Miscellaneous functions --------------------------------------------
2074 |//-----------------------------------------------------------------------
2075 |
2076 |//-----------------------------------------------------------------------
2077 |//-- FFI helper functions -----------------------------------------------
2078 |//-----------------------------------------------------------------------
2079 |
2080 |->vm_ffi_call:
2081#if LJ_HASFFI
2082 | NYI
2083#endif
2084 |
2085 |//-----------------------------------------------------------------------
2086}
2087
2088/* Generate the code for a single instruction. */
2089static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2090{
2091 int vk = 0;
2092 |=>defop:
2093
2094 switch (op) {
2095
2096 /* -- Comparison ops ---------------------------------------------------- */
2097
2098 /* Remember: all ops branch for a true comparison, fall through otherwise. */
2099
2100 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
2101 | // RA = src1*8, RD = src2*8, JMP with RD = target
2102 | evlddx TMP0, BASE, RA
2103 | addi PC, PC, 4
2104 | evlddx TMP1, BASE, RD
2105 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2106 | lwz TMP2, -4(PC)
2107 | evmergehi RB, TMP0, TMP1
2108 | decode_RD4 TMP2, TMP2
2109 | checknum RB
2110 | add TMP2, TMP2, TMP3
2111 | checkanyfail ->vmeta_comp
2112 | efdcmplt TMP0, TMP1
2113 if (op == BC_ISLE || op == BC_ISGT) {
2114 | efdcmpeq cr1, TMP0, TMP1
2115 | cror 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
2116 }
2117 if (op == BC_ISLT || op == BC_ISLE) {
2118 | iselgt PC, TMP2, PC
2119 } else {
2120 | iselgt PC, PC, TMP2
2121 }
2122 | ins_next
2123 break;
2124
2125 case BC_ISEQV: case BC_ISNEV:
2126 vk = op == BC_ISEQV;
2127 | // RA = src1*8, RD = src2*8, JMP with RD = target
2128 | evlddx CARG2, BASE, RA
2129 | addi PC, PC, 4
2130 | evlddx CARG3, BASE, RD
2131 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2132 | lwz TMP2, -4(PC)
2133 | evmergehi RB, CARG2, CARG3
2134 | decode_RD4 TMP2, TMP2
2135 | checknum RB
2136 | add TMP2, TMP2, TMP3
2137 | checkanyfail >5
2138 | efdcmpeq CARG2, CARG3
2139 if (vk) {
2140 | iselgt PC, TMP2, PC
2141 } else {
2142 | iselgt PC, PC, TMP2
2143 }
2144 |1:
2145 | ins_next
2146 |
2147 |5: // Either or both types are not numbers.
2148 | evcmpeq CARG2, CARG3
2149 | not TMP3, RB
2150 | cmplwi cr1, TMP3, ~LJ_TISPRI // Primitive?
2151 | crorc 4*cr7+lt, 4*cr0+so, 4*cr0+lt // 1: Same tv or different type.
2152 | cmplwi cr6, TMP3, ~LJ_TISTABUD // Table or userdata?
2153 | crandc 4*cr7+gt, 4*cr0+lt, 4*cr1+gt // 2: Same type and primitive.
2154 | mr SAVE0, PC
2155 if (vk) {
2156 | isel PC, TMP2, PC, 4*cr7+gt
2157 } else {
2158 | isel TMP2, PC, TMP2, 4*cr7+gt
2159 }
2160 | cror 4*cr7+lt, 4*cr7+lt, 4*cr7+gt // 1 or 2.
2161 if (vk) {
2162 | isel PC, TMP2, PC, 4*cr0+so
2163 } else {
2164 | isel PC, PC, TMP2, 4*cr0+so
2165 }
2166 | blt cr7, <1 // Done if 1 or 2.
2167 | blt cr6, <1 // Done if not tab/ud.
2168 |
2169 | // Different tables or userdatas. Need to check __eq metamethod.
2170 | // Field metatable must be at same offset for GCtab and GCudata!
2171 | lwz TAB:TMP2, TAB:CARG2->metatable
2172 | li CARG4, 1-vk // ne = 0 or 1.
2173 | cmplwi TAB:TMP2, 0
2174 | beq <1 // No metatable?
2175 | lbz TMP2, TAB:TMP2->nomm
2176 | andi. TMP2, TMP2, 1<<MM_eq
2177 | bne <1 // Or 'no __eq' flag set?
2178 | mr PC, SAVE0 // Restore old PC.
2179 | b ->vmeta_equal // Handle __eq metamethod.
2180 break;
2181
2182 case BC_ISEQS: case BC_ISNES:
2183 vk = op == BC_ISEQS;
2184 | // RA = src*8, RD = str_const*8 (~), JMP with RD = target
2185 | evlddx TMP0, BASE, RA
2186 | srwi RD, RD, 1
2187 | lwz INS, 0(PC)
2188 | subfic RD, RD, -4
2189 | addi PC, PC, 4
2190 | lwzx STR:TMP1, KBASE, RD // KBASE-4-str_const*4
2191 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2192 | decode_RD4 TMP2, INS
2193 | evmergelo STR:TMP1, TISSTR, STR:TMP1
2194 | add TMP2, TMP2, TMP3
2195 | evcmpeq TMP0, STR:TMP1
2196 if (vk) {
2197 | isel PC, TMP2, PC, 4*cr0+so
2198 } else {
2199 | isel PC, PC, TMP2, 4*cr0+so
2200 }
2201 | ins_next
2202 break;
2203
2204 case BC_ISEQN: case BC_ISNEN:
2205 vk = op == BC_ISEQN;
2206 | // RA = src*8, RD = num_const*8, JMP with RD = target
2207 | evlddx TMP0, BASE, RA
2208 | addi PC, PC, 4
2209 | evlddx TMP1, KBASE, RD
2210 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2211 | lwz INS, -4(PC)
2212 | checknum TMP0
2213 | checkfail >5
2214 | efdcmpeq TMP0, TMP1
2215 |1:
2216 | decode_RD4 TMP2, INS
2217 | add TMP2, TMP2, TMP3
2218 if (vk) {
2219 | iselgt PC, TMP2, PC
2220 |5:
2221 } else {
2222 | iselgt PC, PC, TMP2
2223 }
2224 |3:
2225 | ins_next
2226 if (!vk) {
2227 |5:
2228 | decode_RD4 TMP2, INS
2229 | add PC, TMP2, TMP3
2230 | b <3
2231 }
2232 break;
2233
2234 case BC_ISEQP: case BC_ISNEP:
2235 vk = op == BC_ISEQP;
2236 | // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target
2237 | lwzx TMP0, BASE, RA
2238 | srwi TMP1, RD, 3
2239 | lwz INS, 0(PC)
2240 | addi PC, PC, 4
2241 | not TMP1, TMP1
2242 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2243 | cmplw TMP0, TMP1
2244 | decode_RD4 TMP2, INS
2245 | add TMP2, TMP2, TMP3
2246 if (vk) {
2247 | iseleq PC, TMP2, PC
2248 } else {
2249 | iseleq PC, PC, TMP2
2250 }
2251 | ins_next
2252 break;
2253
2254 /* -- Unary test and copy ops ------------------------------------------- */
2255
2256 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
2257 | // RA = dst*8 or unused, RD = src*8, JMP with RD = target
2258 | evlddx TMP0, BASE, RD
2259 | evaddw TMP1, TISNIL, TISNIL // Synthesize LJ_TFALSE.
2260 | lwz INS, 0(PC)
2261 | evcmpltu TMP0, TMP1
2262 | addi PC, PC, 4
2263 if (op == BC_IST || op == BC_ISF) {
2264 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
2265 | decode_RD4 TMP2, INS
2266 | add TMP2, TMP2, TMP3
2267 if (op == BC_IST) {
2268 | isellt PC, TMP2, PC
2269 } else {
2270 | isellt PC, PC, TMP2
2271 }
2272 } else {
2273 if (op == BC_ISTC) {
2274 | checkfail >1
2275 } else {
2276 | checkok >1
2277 }
2278 | addis PC, PC, -(BCBIAS_J*4 >> 16)
2279 | decode_RD4 TMP2, INS
2280 | evstddx TMP0, BASE, RA
2281 | add PC, PC, TMP2
2282 |1:
2283 }
2284 | ins_next
2285 break;
2286
2287 /* -- Unary ops --------------------------------------------------------- */
2288
2289 case BC_MOV:
2290 | // RA = dst*8, RD = src*8
2291 | ins_next1
2292 | evlddx TMP0, BASE, RD
2293 | evstddx TMP0, BASE, RA
2294 | ins_next2
2295 break;
2296 case BC_NOT:
2297 | // RA = dst*8, RD = src*8
2298 | ins_next1
2299 | lwzx TMP0, BASE, RD
2300 | subfic TMP1, TMP0, LJ_TTRUE
2301 | adde TMP0, TMP0, TMP1
2302 | stwx TMP0, BASE, RA
2303 | ins_next2
2304 break;
2305 case BC_UNM:
2306 | // RA = dst*8, RD = src*8
2307 | evlddx TMP0, BASE, RD
2308 | checknum TMP0
2309 | checkfail ->vmeta_unm
2310 | efdneg TMP0, TMP0
2311 | ins_next1
2312 | evstddx TMP0, BASE, RA
2313 | ins_next2
2314 break;
2315 case BC_LEN:
2316 | // RA = dst*8, RD = src*8
2317 | evlddx CARG1, BASE, RD
2318 | checkstr CARG1
2319 | checkfail >2
2320 | lwz CRET1, STR:CARG1->len
2321 |1:
2322 | ins_next1
2323 | efdcfsi TMP0, CRET1
2324 | evstddx TMP0, BASE, RA
2325 | ins_next2
2326 |2:
2327 | checktab CARG1
2328 | checkfail ->vmeta_len
2329#ifdef LUAJIT_ENABLE_LUA52COMPAT
2330 | lwz TAB:TMP2, TAB:CARG1->metatable
2331 | cmplwi TAB:TMP2, 0
2332 | bne >9
2333 |3:
2334#endif
2335 |->BC_LEN_Z:
2336 | bl extern lj_tab_len // (GCtab *t)
2337 | // Returns uint32_t (but less than 2^31).
2338 | b <1
2339#ifdef LUAJIT_ENABLE_LUA52COMPAT
2340 |9:
2341 | lbz TMP0, TAB:TMP2->nomm
2342 | andi. TMP0, TMP0, 1<<MM_len
2343 | bne <3 // 'no __len' flag set: done.
2344 | b ->vmeta_len
2345#endif
2346 break;
2347
2348 /* -- Binary ops -------------------------------------------------------- */
2349
2350 |.macro ins_arithpre, t0, t1
2351 | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8
2352 ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2353 ||switch (vk) {
2354 ||case 0:
2355 | evlddx t0, BASE, RB
2356 | checknum t0
2357 | evlddx t1, KBASE, RC
2358 | checkfail ->vmeta_arith_vn
2359 || break;
2360 ||case 1:
2361 | evlddx t1, BASE, RB
2362 | checknum t1
2363 | evlddx t0, KBASE, RC
2364 | checkfail ->vmeta_arith_nv
2365 || break;
2366 ||default:
2367 | evlddx t0, BASE, RB
2368 | evlddx t1, BASE, RC
2369 | evmergehi TMP2, t0, t1
2370 | checknum TMP2
2371 | checkanyfail ->vmeta_arith_vv
2372 || break;
2373 ||}
2374 |.endmacro
2375 |
2376 |.macro ins_arith, ins
2377 | ins_arithpre TMP0, TMP1
2378 | ins_next1
2379 | ins TMP0, TMP0, TMP1
2380 | evstddx TMP0, BASE, RA
2381 | ins_next2
2382 |.endmacro
2383
2384 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
2385 | ins_arith efdadd
2386 break;
2387 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
2388 | ins_arith efdsub
2389 break;
2390 case BC_MULVN: case BC_MULNV: case BC_MULVV:
2391 | ins_arith efdmul
2392 break;
2393 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
2394 | ins_arith efddiv
2395 break;
2396 case BC_MODVN:
2397 | ins_arithpre RD, SAVE0
2398 |->BC_MODVN_Z:
2399 | efddiv CARG2, RD, SAVE0
2400 | bl ->vm_floor_efd // floor(b/c)
2401 | efdmul TMP0, CRET2, SAVE0
2402 | ins_next1
2403 | efdsub TMP0, RD, TMP0 // b - floor(b/c)*c
2404 | evstddx TMP0, BASE, RA
2405 | ins_next2
2406 break;
2407 case BC_MODNV: case BC_MODVV:
2408 | ins_arithpre RD, SAVE0
2409 | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway.
2410 break;
2411 case BC_POW:
2412 | evlddx CARG2, BASE, RB
2413 | evlddx CARG4, BASE, RC
2414 | evmergehi CARG1, CARG4, CARG2
2415 | checknum CARG1
2416 | evmergehi CARG3, CARG4, CARG4
2417 | checkanyfail ->vmeta_arith_vv
2418 | bl extern pow
2419 | evmergelo CRET2, CRET1, CRET2
2420 | evstddx CRET2, BASE, RA
2421 | ins_next
2422 break;
2423
2424 case BC_CAT:
2425 | // RA = dst*8, RB = src_start*8, RC = src_end*8
2426 | sub CARG3, RC, RB
2427 | stw BASE, L->base
2428 | add CARG2, BASE, RC
2429 | mr SAVE0, RB
2430 |->BC_CAT_Z:
2431 | stw PC, SAVE_PC
2432 | mr CARG1, L
2433 | srwi CARG3, CARG3, 3
2434 | bl extern lj_meta_cat // (lua_State *L, TValue *top, int left)
2435 | // Returns NULL (finished) or TValue * (metamethod).
2436 | cmplwi CRET1, 0
2437 | lwz BASE, L->base
2438 | bne ->vmeta_binop
2439 | evlddx TMP0, BASE, SAVE0 // Copy result from RB to RA.
2440 | evstddx TMP0, BASE, RA
2441 | ins_next
2442 break;
2443
2444 /* -- Constant ops ------------------------------------------------------ */
2445
2446 case BC_KSTR:
2447 | // RA = dst*8, RD = str_const*8 (~)
2448 | ins_next1
2449 | srwi TMP1, RD, 1
2450 | subfic TMP1, TMP1, -4
2451 | lwzx TMP0, KBASE, TMP1 // KBASE-4-str_const*4
2452 | evmergelo TMP0, TISSTR, TMP0
2453 | evstddx TMP0, BASE, RA
2454 | ins_next2
2455 break;
2456 case BC_KCDATA:
2457#if LJ_HASFFI
2458 | // RA = dst*8, RD = cdata_const*8 (~)
2459 | ins_next1
2460 | srwi TMP1, RD, 1
2461 | subfic TMP1, TMP1, -4
2462 | lwzx TMP0, KBASE, TMP1 // KBASE-4-cdata_const*4
2463 | li TMP2, LJ_TCDATA
2464 | evmergelo TMP0, TMP2, TMP0
2465 | evstddx TMP0, BASE, RA
2466 | ins_next2
2467#endif
2468 break;
2469 case BC_KSHORT:
2470 | // RA = dst*8, RD = int16_literal*8
2471 | srwi TMP1, RD, 3
2472 | extsh TMP1, TMP1
2473 | ins_next1
2474 | efdcfsi TMP0, TMP1
2475 | evstddx TMP0, BASE, RA
2476 | ins_next2
2477 break;
2478 case BC_KNUM:
2479 | // RA = dst*8, RD = num_const*8
2480 | evlddx TMP0, KBASE, RD
2481 | ins_next1
2482 | evstddx TMP0, BASE, RA
2483 | ins_next2
2484 break;
2485 case BC_KPRI:
2486 | // RA = dst*8, RD = primitive_type*8 (~)
2487 | srwi TMP1, RD, 3
2488 | not TMP0, TMP1
2489 | ins_next1
2490 | stwx TMP0, BASE, RA
2491 | ins_next2
2492 break;
2493 case BC_KNIL:
2494 | // RA = base*8, RD = end*8
2495 | evstddx TISNIL, BASE, RA
2496 | addi RA, RA, 8
2497 |1:
2498 | evstddx TISNIL, BASE, RA
2499 | cmpw RA, RD
2500 | addi RA, RA, 8
2501 | blt <1
2502 | ins_next_
2503 break;
2504
2505 /* -- Upvalue and function ops ------------------------------------------ */
2506
2507 case BC_UGET:
2508 | // RA = dst*8, RD = uvnum*8
2509 | ins_next1
2510 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2511 | srwi RD, RD, 1
2512 | addi RD, RD, offsetof(GCfuncL, uvptr)
2513 | lwzx UPVAL:RB, LFUNC:RB, RD
2514 | lwz TMP1, UPVAL:RB->v
2515 | evldd TMP0, 0(TMP1)
2516 | evstddx TMP0, BASE, RA
2517 | ins_next2
2518 break;
2519 case BC_USETV:
2520 | // RA = uvnum*8, RD = src*8
2521 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2522 | srwi RA, RA, 1
2523 | addi RA, RA, offsetof(GCfuncL, uvptr)
2524 | evlddx TMP1, BASE, RD
2525 | lwzx UPVAL:RB, LFUNC:RB, RA
2526 | lbz TMP3, UPVAL:RB->marked
2527 | lwz CARG2, UPVAL:RB->v
2528 | andi. TMP3, TMP3, LJ_GC_BLACK // isblack(uv)
2529 | lbz TMP0, UPVAL:RB->closed
2530 | evmergehi TMP2, TMP1, TMP1
2531 | evstdd TMP1, 0(CARG2)
2532 | cmplwi cr1, TMP0, 0
2533 | cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
2534 | subi TMP2, TMP2, (LJ_TISNUM+1)
2535 | bne >2 // Upvalue is closed and black?
2536 |1:
2537 | ins_next
2538 |
2539 |2: // Check if new value is collectable.
2540 | cmplwi TMP2, LJ_TISGCV - (LJ_TISNUM+1)
2541 | bge <1 // tvisgcv(v)
2542 | lbz TMP3, GCOBJ:TMP1->gch.marked
2543 | andi. TMP3, TMP3, LJ_GC_WHITES // iswhite(v)
2544 | la CARG1, GG_DISP2G(DISPATCH)
2545 | // Crossed a write barrier. Move the barrier forward.
2546 | beq <1
2547 | bl extern lj_gc_barrieruv // (global_State *g, TValue *tv)
2548 | b <1
2549 break;
2550 case BC_USETS:
2551 | // RA = uvnum*8, RD = str_const*8 (~)
2552 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2553 | srwi TMP1, RD, 1
2554 | srwi RA, RA, 1
2555 | subfic TMP1, TMP1, -4
2556 | addi RA, RA, offsetof(GCfuncL, uvptr)
2557 | lwzx STR:TMP1, KBASE, TMP1 // KBASE-4-str_const*4
2558 | lwzx UPVAL:RB, LFUNC:RB, RA
2559 | evmergelo STR:TMP1, TISSTR, STR:TMP1
2560 | lbz TMP3, UPVAL:RB->marked
2561 | lwz CARG2, UPVAL:RB->v
2562 | andi. TMP3, TMP3, LJ_GC_BLACK // isblack(uv)
2563 | lbz TMP3, STR:TMP1->marked
2564 | lbz TMP2, UPVAL:RB->closed
2565 | evstdd STR:TMP1, 0(CARG2)
2566 | bne >2
2567 |1:
2568 | ins_next
2569 |
2570 |2: // Check if string is white and ensure upvalue is closed.
2571 | andi. TMP3, TMP3, LJ_GC_WHITES // iswhite(str)
2572 | cmplwi cr1, TMP2, 0
2573 | cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
2574 | la CARG1, GG_DISP2G(DISPATCH)
2575 | // Crossed a write barrier. Move the barrier forward.
2576 | beq <1
2577 | bl extern lj_gc_barrieruv // (global_State *g, TValue *tv)
2578 | b <1
2579 break;
2580 case BC_USETN:
2581 | // RA = uvnum*8, RD = num_const*8
2582 | ins_next1
2583 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2584 | srwi RA, RA, 1
2585 | addi RA, RA, offsetof(GCfuncL, uvptr)
2586 | evlddx TMP0, KBASE, RD
2587 | lwzx UPVAL:RB, LFUNC:RB, RA
2588 | lwz TMP1, UPVAL:RB->v
2589 | evstdd TMP0, 0(TMP1)
2590 | ins_next2
2591 break;
2592 case BC_USETP:
2593 | // RA = uvnum*8, RD = primitive_type*8 (~)
2594 | ins_next1
2595 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2596 | srwi RA, RA, 1
2597 | addi RA, RA, offsetof(GCfuncL, uvptr)
2598 | srwi TMP0, RD, 3
2599 | lwzx UPVAL:RB, LFUNC:RB, RA
2600 | not TMP0, TMP0
2601 | lwz TMP1, UPVAL:RB->v
2602 | stw TMP0, 0(TMP1)
2603 | ins_next2
2604 break;
2605
2606 case BC_UCLO:
2607 | // RA = level*8, RD = target
2608 | lwz TMP1, L->openupval
2609 | branch_RD // Do this first since RD is not saved.
2610 | stw BASE, L->base
2611 | cmplwi TMP1, 0
2612 | mr CARG1, L
2613 | beq >1
2614 | add CARG2, BASE, RA
2615 | bl extern lj_func_closeuv // (lua_State *L, TValue *level)
2616 | lwz BASE, L->base
2617 |1:
2618 | ins_next
2619 break;
2620
2621 case BC_FNEW:
2622 | // RA = dst*8, RD = proto_const*8 (~) (holding function prototype)
2623 | srwi TMP1, RD, 1
2624 | stw BASE, L->base
2625 | subfic TMP1, TMP1, -4
2626 | stw PC, SAVE_PC
2627 | lwzx CARG2, KBASE, TMP1 // KBASE-4-tab_const*4
2628 | mr CARG1, L
2629 | lwz CARG3, FRAME_FUNC(BASE)
2630 | // (lua_State *L, GCproto *pt, GCfuncL *parent)
2631 | bl extern lj_func_newL_gc
2632 | // Returns GCfuncL *.
2633 | lwz BASE, L->base
2634 | evmergelo LFUNC:CRET1, TISFUNC, LFUNC:CRET1
2635 | evstddx LFUNC:CRET1, BASE, RA
2636 | ins_next
2637 break;
2638
2639 /* -- Table ops --------------------------------------------------------- */
2640
2641 case BC_TNEW:
2642 case BC_TDUP:
2643 | // RA = dst*8, RD = (hbits|asize)*8 | tab_const*8 (~)
2644 | lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
2645 | mr CARG1, L
2646 | lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
2647 | stw BASE, L->base
2648 | cmplw TMP0, TMP1
2649 | stw PC, SAVE_PC
2650 | bge >5
2651 |1:
2652 if (op == BC_TNEW) {
2653 | rlwinm CARG2, RD, 29, 21, 31
2654 | rlwinm CARG3, RD, 18, 27, 31
2655 | cmpwi CARG2, 0x7ff
2656 | li TMP1, 0x801
2657 | iseleq CARG2, TMP1, CARG2
2658 | bl extern lj_tab_new // (lua_State *L, int32_t asize, uint32_t hbits)
2659 | // Returns Table *.
2660 } else {
2661 | srwi TMP1, RD, 1
2662 | subfic TMP1, TMP1, -4
2663 | lwzx CARG2, KBASE, TMP1 // KBASE-4-tab_const*4
2664 | bl extern lj_tab_dup // (lua_State *L, Table *kt)
2665 | // Returns Table *.
2666 }
2667 | lwz BASE, L->base
2668 | evmergelo TAB:CRET1, TISTAB, TAB:CRET1
2669 | evstddx TAB:CRET1, BASE, RA
2670 | ins_next
2671 |5:
2672 | mr SAVE0, RD
2673 | bl extern lj_gc_step_fixtop // (lua_State *L)
2674 | mr RD, SAVE0
2675 | mr CARG1, L
2676 | b <1
2677 break;
2678
2679 case BC_GGET:
2680 | // RA = dst*8, RD = str_const*8 (~)
2681 case BC_GSET:
2682 | // RA = src*8, RD = str_const*8 (~)
2683 | lwz LFUNC:TMP2, FRAME_FUNC(BASE)
2684 | srwi TMP1, RD, 1
2685 | lwz TAB:RB, LFUNC:TMP2->env
2686 | subfic TMP1, TMP1, -4
2687 | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4
2688 if (op == BC_GGET) {
2689 | b ->BC_TGETS_Z
2690 } else {
2691 | b ->BC_TSETS_Z
2692 }
2693 break;
2694
2695 case BC_TGETV:
2696 | // RA = dst*8, RB = table*8, RC = key*8
2697 | evlddx TAB:RB, BASE, RB
2698 | evlddx RC, BASE, RC
2699 | checktab TAB:RB
2700 | checkfail ->vmeta_tgetv
2701 | checknum RC
2702 | checkfail >5
2703 | // Convert number key to integer
2704 | efdctsi TMP2, RC
2705 | lwz TMP0, TAB:RB->asize
2706 | efdcfsi TMP1, TMP2
2707 | cmplw cr0, TMP0, TMP2
2708 | efdcmpeq cr1, RC, TMP1
2709 | lwz TMP1, TAB:RB->array
2710 | crand 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
2711 | slwi TMP2, TMP2, 3
2712 | ble ->vmeta_tgetv // Integer key and in array part?
2713 | evlddx TMP1, TMP1, TMP2
2714 | checknil TMP1
2715 | checkok >2
2716 |1:
2717 | evstddx TMP1, BASE, RA
2718 | ins_next
2719 |
2720 |2: // Check for __index if table value is nil.
2721 | lwz TAB:TMP2, TAB:RB->metatable
2722 | cmplwi TAB:TMP2, 0
2723 | beq <1 // No metatable: done.
2724 | lbz TMP0, TAB:TMP2->nomm
2725 | andi. TMP0, TMP0, 1<<MM_index
2726 | bne <1 // 'no __index' flag set: done.
2727 | b ->vmeta_tgetv
2728 |
2729 |5:
2730 | checkstr STR:RC // String key?
2731 | checkok ->BC_TGETS_Z
2732 | b ->vmeta_tgetv
2733 break;
2734 case BC_TGETS:
2735 | // RA = dst*8, RB = table*8, RC = str_const*8 (~)
2736 | evlddx TAB:RB, BASE, RB
2737 | srwi TMP1, RC, 1
2738 | checktab TAB:RB
2739 | subfic TMP1, TMP1, -4
2740 | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4
2741 | checkfail ->vmeta_tgets1
2742 |->BC_TGETS_Z:
2743 | // TAB:RB = GCtab *, STR:RC = GCstr *, RA = dst*8
2744 | lwz TMP0, TAB:RB->hmask
2745 | lwz TMP1, STR:RC->hash
2746 | lwz NODE:TMP2, TAB:RB->node
2747 | evmergelo STR:RC, TISSTR, STR:RC
2748 | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
2749 | slwi TMP0, TMP1, 5
2750 | slwi TMP1, TMP1, 3
2751 | sub TMP1, TMP0, TMP1
2752 | add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
2753 |1:
2754 | evldd TMP0, NODE:TMP2->key
2755 | evldd TMP1, NODE:TMP2->val
2756 | evcmpeq TMP0, STR:RC
2757 | checkanyfail >4
2758 | checknil TMP1
2759 | checkok >5 // Key found, but nil value?
2760 |3:
2761 | evstddx TMP1, BASE, RA
2762 | ins_next
2763 |
2764 |4: // Follow hash chain.
2765 | lwz NODE:TMP2, NODE:TMP2->next
2766 | cmplwi NODE:TMP2, 0
2767 | bne <1
2768 | // End of hash chain: key not found, nil result.
2769 | evmr TMP1, TISNIL
2770 |
2771 |5: // Check for __index if table value is nil.
2772 | lwz TAB:TMP2, TAB:RB->metatable
2773 | cmplwi TAB:TMP2, 0
2774 | beq <3 // No metatable: done.
2775 | lbz TMP0, TAB:TMP2->nomm
2776 | andi. TMP0, TMP0, 1<<MM_index
2777 | bne <3 // 'no __index' flag set: done.
2778 | b ->vmeta_tgets
2779 break;
2780 case BC_TGETB:
2781 | // RA = dst*8, RB = table*8, RC = index*8
2782 | evlddx TAB:RB, BASE, RB
2783 | srwi TMP0, RC, 3
2784 | checktab TAB:RB
2785 | checkfail ->vmeta_tgetb
2786 | lwz TMP1, TAB:RB->asize
2787 | lwz TMP2, TAB:RB->array
2788 | cmplw TMP0, TMP1
2789 | bge ->vmeta_tgetb
2790 | evlddx TMP1, TMP2, RC
2791 | checknil TMP1
2792 | checkok >5
2793 |1:
2794 | ins_next1
2795 | evstddx TMP1, BASE, RA
2796 | ins_next2
2797 |
2798 |5: // Check for __index if table value is nil.
2799 | lwz TAB:TMP2, TAB:RB->metatable
2800 | cmplwi TAB:TMP2, 0
2801 | beq <1 // No metatable: done.
2802 | lbz TMP2, TAB:TMP2->nomm
2803 | andi. TMP2, TMP2, 1<<MM_index
2804 | bne <1 // 'no __index' flag set: done.
2805 | b ->vmeta_tgetb // Caveat: preserve TMP0!
2806 break;
2807
2808 case BC_TSETV:
2809 | // RA = src*8, RB = table*8, RC = key*8
2810 | evlddx TAB:RB, BASE, RB
2811 | evlddx RC, BASE, RC
2812 | checktab TAB:RB
2813 | checkfail ->vmeta_tsetv
2814 | checknum RC
2815 | checkfail >5
2816 | // Convert number key to integer
2817 | efdctsi TMP2, RC
2818 | evlddx SAVE0, BASE, RA
2819 | lwz TMP0, TAB:RB->asize
2820 | efdcfsi TMP1, TMP2
2821 | cmplw cr0, TMP0, TMP2
2822 | efdcmpeq cr1, RC, TMP1
2823 | lwz TMP1, TAB:RB->array
2824 | crand 4*cr0+gt, 4*cr0+gt, 4*cr1+gt
2825 | slwi TMP0, TMP2, 3
2826 | ble ->vmeta_tsetv // Integer key and in array part?
2827 | lbz TMP3, TAB:RB->marked
2828 | evlddx TMP2, TMP1, TMP0
2829 | checknil TMP2
2830 | checkok >3
2831 |1:
2832 | andi. TMP2, TMP3, LJ_GC_BLACK // isblack(table)
2833 | evstddx SAVE0, TMP1, TMP0
2834 | bne >7
2835 |2:
2836 | ins_next
2837 |
2838 |3: // Check for __newindex if previous value is nil.
2839 | lwz TAB:TMP2, TAB:RB->metatable
2840 | cmplwi TAB:TMP2, 0
2841 | beq <1 // No metatable: done.
2842 | lbz TMP2, TAB:TMP2->nomm
2843 | andi. TMP2, TMP2, 1<<MM_newindex
2844 | bne <1 // 'no __newindex' flag set: done.
2845 | b ->vmeta_tsetv
2846 |
2847 |5:
2848 | checkstr STR:RC // String key?
2849 | checkok ->BC_TSETS_Z
2850 | b ->vmeta_tsetv
2851 |
2852 |7: // Possible table write barrier for the value. Skip valiswhite check.
2853 | barrierback TAB:RB, TMP3, TMP0
2854 | b <2
2855 break;
2856 case BC_TSETS:
2857 | // RA = src*8, RB = table*8, RC = str_const*8 (~)
2858 | evlddx TAB:RB, BASE, RB
2859 | srwi TMP1, RC, 1
2860 | checktab TAB:RB
2861 | subfic TMP1, TMP1, -4
2862 | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4
2863 | checkfail ->vmeta_tsets1
2864 |->BC_TSETS_Z:
2865 | // TAB:RB = GCtab *, STR:RC = GCstr *, RA = src*8
2866 | lwz TMP0, TAB:RB->hmask
2867 | lwz TMP1, STR:RC->hash
2868 | lwz NODE:TMP2, TAB:RB->node
2869 | evmergelo STR:RC, TISSTR, STR:RC
2870 | stb ZERO, TAB:RB->nomm // Clear metamethod cache.
2871 | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
2872 | evlddx SAVE0, BASE, RA
2873 | slwi TMP0, TMP1, 5
2874 | slwi TMP1, TMP1, 3
2875 | sub TMP1, TMP0, TMP1
2876 | lbz TMP3, TAB:RB->marked
2877 | add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
2878 |1:
2879 | evldd TMP0, NODE:TMP2->key
2880 | evldd TMP1, NODE:TMP2->val
2881 | evcmpeq TMP0, STR:RC
2882 | checkanyfail >5
2883 | checknil TMP1
2884 | checkok >4 // Key found, but nil value?
2885 |2:
2886 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
2887 | evstdd SAVE0, NODE:TMP2->val
2888 | bne >7
2889 |3:
2890 | ins_next
2891 |
2892 |4: // Check for __newindex if previous value is nil.
2893 | lwz TAB:TMP1, TAB:RB->metatable
2894 | cmplwi TAB:TMP1, 0
2895 | beq <2 // No metatable: done.
2896 | lbz TMP0, TAB:TMP1->nomm
2897 | andi. TMP0, TMP0, 1<<MM_newindex
2898 | bne <2 // 'no __newindex' flag set: done.
2899 | b ->vmeta_tsets
2900 |
2901 |5: // Follow hash chain.
2902 | lwz NODE:TMP2, NODE:TMP2->next
2903 | cmplwi NODE:TMP2, 0
2904 | bne <1
2905 | // End of hash chain: key not found, add a new one.
2906 |
2907 | // But check for __newindex first.
2908 | lwz TAB:TMP1, TAB:RB->metatable
2909 | la CARG3, DISPATCH_GL(tmptv)(DISPATCH)
2910 | stw PC, SAVE_PC
2911 | mr CARG1, L
2912 | cmplwi TAB:TMP1, 0
2913 | stw BASE, L->base
2914 | beq >6 // No metatable: continue.
2915 | lbz TMP0, TAB:TMP1->nomm
2916 | andi. TMP0, TMP0, 1<<MM_newindex
2917 | beq ->vmeta_tsets // 'no __newindex' flag NOT set: check.
2918 |6:
2919 | mr CARG2, TAB:RB
2920 | evstdd STR:RC, 0(CARG3)
2921 | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k)
2922 | // Returns TValue *.
2923 | lwz BASE, L->base
2924 | evstdd SAVE0, 0(CRET1)
2925 | b <3 // No 2nd write barrier needed.
2926 |
2927 |7: // Possible table write barrier for the value. Skip valiswhite check.
2928 | barrierback TAB:RB, TMP3, TMP0
2929 | b <3
2930 break;
2931 case BC_TSETB:
2932 | // RA = src*8, RB = table*8, RC = index*8
2933 | evlddx TAB:RB, BASE, RB
2934 | srwi TMP0, RC, 3
2935 | checktab TAB:RB
2936 | checkfail ->vmeta_tsetb
2937 | lwz TMP1, TAB:RB->asize
2938 | lwz TMP2, TAB:RB->array
2939 | lbz TMP3, TAB:RB->marked
2940 | cmplw TMP0, TMP1
2941 | evlddx SAVE0, BASE, RA
2942 | bge ->vmeta_tsetb
2943 | evlddx TMP1, TMP2, RC
2944 | checknil TMP1
2945 | checkok >5
2946 |1:
2947 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
2948 | evstddx SAVE0, TMP2, RC
2949 | bne >7
2950 |2:
2951 | ins_next
2952 |
2953 |5: // Check for __newindex if previous value is nil.
2954 | lwz TAB:TMP1, TAB:RB->metatable
2955 | cmplwi TAB:TMP1, 0
2956 | beq <1 // No metatable: done.
2957 | lbz TMP1, TAB:TMP1->nomm
2958 | andi. TMP1, TMP1, 1<<MM_newindex
2959 | bne <1 // 'no __newindex' flag set: done.
2960 | b ->vmeta_tsetb // Caveat: preserve TMP0!
2961 |
2962 |7: // Possible table write barrier for the value. Skip valiswhite check.
2963 | barrierback TAB:RB, TMP3, TMP0
2964 | b <2
2965 break;
2966
2967 case BC_TSETM:
2968 | // RA = base*8 (table at base-1), RD = num_const*8 (start index)
2969 | add RA, BASE, RA
2970 |1:
2971 | add TMP3, KBASE, RD
2972 | lwz TAB:CARG2, -4(RA) // Guaranteed to be a table.
2973 | addic. TMP0, MULTRES, -8
2974 | lwz TMP3, 4(TMP3) // Integer constant is in lo-word.
2975 | srwi CARG3, TMP0, 3
2976 | beq >4 // Nothing to copy?
2977 | add CARG3, CARG3, TMP3
2978 | lwz TMP2, TAB:CARG2->asize
2979 | slwi TMP1, TMP3, 3
2980 | lbz TMP3, TAB:CARG2->marked
2981 | cmplw CARG3, TMP2
2982 | add TMP2, RA, TMP0
2983 | lwz TMP0, TAB:CARG2->array
2984 | bgt >5
2985 | add TMP1, TMP1, TMP0
2986 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
2987 |3: // Copy result slots to table.
2988 | evldd TMP0, 0(RA)
2989 | addi RA, RA, 8
2990 | cmpw cr1, RA, TMP2
2991 | evstdd TMP0, 0(TMP1)
2992 | addi TMP1, TMP1, 8
2993 | blt cr1, <3
2994 | bne >7
2995 |4:
2996 | ins_next
2997 |
2998 |5: // Need to resize array part.
2999 | stw BASE, L->base
3000 | mr CARG1, L
3001 | stw PC, SAVE_PC
3002 | mr SAVE0, RD
3003 | bl extern lj_tab_reasize // (lua_State *L, GCtab *t, int nasize)
3004 | // Must not reallocate the stack.
3005 | mr RD, SAVE0
3006 | b <1
3007 |
3008 |7: // Possible table write barrier for any value. Skip valiswhite check.
3009 | barrierback TAB:CARG2, TMP3, TMP0
3010 | b <4
3011 break;
3012
3013 /* -- Calls and vararg handling ----------------------------------------- */
3014
3015 case BC_CALLM:
3016 | // RA = base*8, (RB = (nresults+1)*8,) RC = extra_nargs*8
3017 | add NARGS8:RC, NARGS8:RC, MULTRES
3018 | // Fall through. Assumes BC_CALL follows.
3019 break;
3020 case BC_CALL:
3021 | // RA = base*8, (RB = (nresults+1)*8,) RC = (nargs+1)*8
3022 | evlddx LFUNC:RB, BASE, RA
3023 | mr TMP2, BASE
3024 | add BASE, BASE, RA
3025 | subi NARGS8:RC, NARGS8:RC, 8
3026 | checkfunc LFUNC:RB
3027 | addi BASE, BASE, 8
3028 | checkfail ->vmeta_call
3029 | ins_call
3030 break;
3031
3032 case BC_CALLMT:
3033 | // RA = base*8, (RB = 0,) RC = extra_nargs*8
3034 | add NARGS8:RC, NARGS8:RC, MULTRES
3035 | // Fall through. Assumes BC_CALLT follows.
3036 break;
3037 case BC_CALLT:
3038 | // RA = base*8, (RB = 0,) RC = (nargs+1)*8
3039 | evlddx LFUNC:RB, BASE, RA
3040 | add RA, BASE, RA
3041 | lwz TMP1, FRAME_PC(BASE)
3042 | subi NARGS8:RC, NARGS8:RC, 8
3043 | checkfunc LFUNC:RB
3044 | addi RA, RA, 8
3045 | checkfail ->vmeta_callt
3046 |->BC_CALLT_Z:
3047 | andi. TMP0, TMP1, FRAME_TYPE // Caveat: preserve cr0 until the crand.
3048 | lbz TMP3, LFUNC:RB->ffid
3049 | xori TMP2, TMP1, FRAME_VARG
3050 | cmplwi cr1, NARGS8:RC, 0
3051 | bne >7
3052 |1:
3053 | stw LFUNC:RB, FRAME_FUNC(BASE) // Copy function down, but keep PC.
3054 | li TMP2, 0
3055 | cmplwi cr7, TMP3, 1 // (> FF_C) Calling a fast function?
3056 | beq cr1, >3
3057 |2:
3058 | addi TMP3, TMP2, 8
3059 | evlddx TMP0, RA, TMP2
3060 | cmplw cr1, TMP3, NARGS8:RC
3061 | evstddx TMP0, BASE, TMP2
3062 | mr TMP2, TMP3
3063 | bne cr1, <2
3064 |3:
3065 | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+gt
3066 | beq >5
3067 |4:
3068 | ins_callt
3069 |
3070 |5: // Tailcall to a fast function with a Lua frame below.
3071 | lwz INS, -4(TMP1)
3072 | decode_RA8 RA, INS
3073 | sub TMP1, BASE, RA
3074 | lwz LFUNC:TMP1, FRAME_FUNC-8(TMP1)
3075 | lwz TMP1, LFUNC:TMP1->pc
3076 | lwz KBASE, PC2PROTO(k)(TMP1) // Need to prepare KBASE.
3077 | b <4
3078 |
3079 |7: // Tailcall from a vararg function.
3080 | andi. TMP0, TMP2, FRAME_TYPEP
3081 | bne <1 // Vararg frame below?
3082 | sub BASE, BASE, TMP2 // Relocate BASE down.
3083 | lwz TMP1, FRAME_PC(BASE)
3084 | andi. TMP0, TMP1, FRAME_TYPE
3085 | b <1
3086 break;
3087
3088 case BC_ITERC:
3089 | // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 ((2+1)*8))
3090 | subi RA, RA, 24 // evldd doesn't support neg. offsets.
3091 | mr TMP2, BASE
3092 | evlddx LFUNC:RB, BASE, RA
3093 | add BASE, BASE, RA
3094 | evldd TMP0, 8(BASE)
3095 | evldd TMP1, 16(BASE)
3096 | evstdd LFUNC:RB, 24(BASE) // Copy callable.
3097 | checkfunc LFUNC:RB
3098 | evstdd TMP0, 32(BASE) // Copy state.
3099 | li NARGS8:RC, 16 // Iterators get 2 arguments.
3100 | evstdd TMP1, 40(BASE) // Copy control var.
3101 | addi BASE, BASE, 32
3102 | checkfail ->vmeta_call
3103 | ins_call
3104 break;
3105
3106 case BC_ITERN:
3107 | // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 (2+1)*8)
3108#if LJ_HASJIT
3109 | // NYI: add hotloop, record BC_ITERN.
3110#endif
3111 | add RA, BASE, RA
3112 | lwz TAB:RB, -12(RA)
3113 | lwz RC, -4(RA) // Get index from control var.
3114 | lwz TMP0, TAB:RB->asize
3115 | lwz TMP1, TAB:RB->array
3116 | addi PC, PC, 4
3117 |1: // Traverse array part.
3118 | cmplw RC, TMP0
3119 | slwi TMP3, RC, 3
3120 | bge >5 // Index points after array part?
3121 | evlddx TMP2, TMP1, TMP3
3122 | checknil TMP2
3123 | lwz INS, -4(PC)
3124 | checkok >4
3125 | efdcfsi TMP0, RC
3126 | addi RC, RC, 1
3127 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
3128 | evstdd TMP2, 8(RA)
3129 | decode_RD4 TMP1, INS
3130 | stw RC, -4(RA) // Update control var.
3131 | add PC, TMP1, TMP3
3132 | evstdd TMP0, 0(RA)
3133 |3:
3134 | ins_next
3135 |
3136 |4: // Skip holes in array part.
3137 | addi RC, RC, 1
3138 | b <1
3139 |
3140 |5: // Traverse hash part.
3141 | lwz TMP1, TAB:RB->hmask
3142 | sub RC, RC, TMP0
3143 | lwz TMP2, TAB:RB->node
3144 |6:
3145 | cmplw RC, TMP1 // End of iteration? Branch to ITERL+1.
3146 | slwi TMP3, RC, 5
3147 | bgt <3
3148 | slwi RB, RC, 3
3149 | sub TMP3, TMP3, RB
3150 | evlddx RB, TMP2, TMP3
3151 | add NODE:TMP3, TMP2, TMP3
3152 | checknil RB
3153 | lwz INS, -4(PC)
3154 | checkok >7
3155 | evldd TMP3, NODE:TMP3->key
3156 | addis TMP2, PC, -(BCBIAS_J*4 >> 16)
3157 | evstdd RB, 8(RA)
3158 | add RC, RC, TMP0
3159 | decode_RD4 TMP1, INS
3160 | evstdd TMP3, 0(RA)
3161 | addi RC, RC, 1
3162 | add PC, TMP1, TMP2
3163 | stw RC, -4(RA) // Update control var.
3164 | b <3
3165 |
3166 |7: // Skip holes in hash part.
3167 | addi RC, RC, 1
3168 | b <6
3169 break;
3170
3171 case BC_ISNEXT:
3172 | // RA = base*8, RD = target (points to ITERN)
3173 | add RA, BASE, RA
3174 | li TMP2, -24
3175 | evlddx CFUNC:TMP1, RA, TMP2
3176 | lwz TMP2, -16(RA)
3177 | lwz TMP3, -8(RA)
3178 | evmergehi TMP0, CFUNC:TMP1, CFUNC:TMP1
3179 | cmpwi cr0, TMP2, LJ_TTAB
3180 | cmpwi cr1, TMP0, LJ_TFUNC
3181 | cmpwi cr6, TMP3, LJ_TNIL
3182 | bne cr1, >5
3183 | lbz TMP1, CFUNC:TMP1->ffid
3184 | crand 4*cr0+eq, 4*cr0+eq, 4*cr6+eq
3185 | cmpwi cr7, TMP1, FF_next_N
3186 | srwi TMP0, RD, 1
3187 | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+eq
3188 | add TMP3, PC, TMP0
3189 | bne cr0, >5
3190 | stw ZERO, -4(RA) // Initialize control var.
3191 | addis PC, TMP3, -(BCBIAS_J*4 >> 16)
3192 |1:
3193 | ins_next
3194 |5: // Despecialize bytecode if any of the checks fail.
3195 | li TMP0, BC_JMP
3196 | li TMP1, BC_ITERC
3197 | stb TMP0, -1(PC)
3198 | addis PC, TMP3, -(BCBIAS_J*4 >> 16)
3199 | stb TMP1, 3(PC)
3200 | b <1
3201 break;
3202
3203 case BC_VARG:
3204 | // RA = base*8, RB = (nresults+1)*8, RC = numparams*8
3205 | lwz TMP0, FRAME_PC(BASE)
3206 | add RC, BASE, RC
3207 | add RA, BASE, RA
3208 | addi RC, RC, FRAME_VARG
3209 | add TMP2, RA, RB
3210 | subi TMP3, BASE, 8 // TMP3 = vtop
3211 | sub RC, RC, TMP0 // RC = vbase
3212 | // Note: RC may now be even _above_ BASE if nargs was < numparams.
3213 | cmplwi cr1, RB, 0
3214 | sub. TMP1, TMP3, RC
3215 | beq cr1, >5 // Copy all varargs?
3216 | subi TMP2, TMP2, 16
3217 | ble >2 // No vararg slots?
3218 |1: // Copy vararg slots to destination slots.
3219 | evldd TMP0, 0(RC)
3220 | addi RC, RC, 8
3221 | evstdd TMP0, 0(RA)
3222 | cmplw RA, TMP2
3223 | cmplw cr1, RC, TMP3
3224 | bge >3 // All destination slots filled?
3225 | addi RA, RA, 8
3226 | blt cr1, <1 // More vararg slots?
3227 |2: // Fill up remainder with nil.
3228 | evstdd TISNIL, 0(RA)
3229 | cmplw RA, TMP2
3230 | addi RA, RA, 8
3231 | blt <2
3232 |3:
3233 | ins_next
3234 |
3235 |5: // Copy all varargs.
3236 | lwz TMP0, L->maxstack
3237 | li MULTRES, 8 // MULTRES = (0+1)*8
3238 | ble <3 // No vararg slots?
3239 | add TMP2, RA, TMP1
3240 | cmplw TMP2, TMP0
3241 | addi MULTRES, TMP1, 8
3242 | bgt >7
3243 |6:
3244 | evldd TMP0, 0(RC)
3245 | addi RC, RC, 8
3246 | evstdd TMP0, 0(RA)
3247 | cmplw RC, TMP3
3248 | addi RA, RA, 8
3249 | blt <6 // More vararg slots?
3250 | b <3
3251 |
3252 |7: // Grow stack for varargs.
3253 | mr CARG1, L
3254 | stw RA, L->top
3255 | sub SAVE0, RC, BASE // Need delta, because BASE may change.
3256 | stw BASE, L->base
3257 | sub RA, RA, BASE
3258 | stw PC, SAVE_PC
3259 | srwi CARG2, TMP1, 3
3260 | bl extern lj_state_growstack // (lua_State *L, int n)
3261 | lwz BASE, L->base
3262 | add RA, BASE, RA
3263 | add RC, BASE, SAVE0
3264 | subi TMP3, BASE, 8
3265 | b <6
3266 break;
3267
3268 /* -- Returns ----------------------------------------------------------- */
3269
3270 case BC_RETM:
3271 | // RA = results*8, RD = extra_nresults*8
3272 | add RD, RD, MULTRES // MULTRES >= 8, so RD >= 8.
3273 | // Fall through. Assumes BC_RET follows.
3274 break;
3275
3276 case BC_RET:
3277 | // RA = results*8, RD = (nresults+1)*8
3278 | lwz PC, FRAME_PC(BASE)
3279 | add RA, BASE, RA
3280 | mr MULTRES, RD
3281 |1:
3282 | andi. TMP0, PC, FRAME_TYPE
3283 | xori TMP1, PC, FRAME_VARG
3284 | bne ->BC_RETV_Z
3285 |
3286 |->BC_RET_Z:
3287 | // BASE = base, RA = resultptr, RD = (nresults+1)*8, PC = return
3288 | lwz INS, -4(PC)
3289 | cmpwi RD, 8
3290 | subi TMP2, BASE, 8
3291 | subi RC, RD, 8
3292 | decode_RB8 RB, INS
3293 | beq >3
3294 | li TMP1, 0
3295 |2:
3296 | addi TMP3, TMP1, 8
3297 | evlddx TMP0, RA, TMP1
3298 | cmpw TMP3, RC
3299 | evstddx TMP0, TMP2, TMP1
3300 | beq >3
3301 | addi TMP1, TMP3, 8
3302 | evlddx TMP0, RA, TMP3
3303 | cmpw TMP1, RC
3304 | evstddx TMP0, TMP2, TMP3
3305 | bne <2
3306 |3:
3307 |5:
3308 | cmplw RB, RD
3309 | decode_RA8 RA, INS
3310 | bgt >6
3311 | sub BASE, TMP2, RA
3312 | lwz LFUNC:TMP1, FRAME_FUNC(BASE)
3313 | ins_next1
3314 | lwz TMP1, LFUNC:TMP1->pc
3315 | lwz KBASE, PC2PROTO(k)(TMP1)
3316 | ins_next2
3317 |
3318 |6: // Fill up results with nil.
3319 | subi TMP1, RD, 8
3320 | addi RD, RD, 8
3321 | evstddx TISNIL, TMP2, TMP1
3322 | b <5
3323 |
3324 |->BC_RETV_Z: // Non-standard return case.
3325 | andi. TMP2, TMP1, FRAME_TYPEP
3326 | bne ->vm_return
3327 | // Return from vararg function: relocate BASE down.
3328 | sub BASE, BASE, TMP1
3329 | lwz PC, FRAME_PC(BASE)
3330 | b <1
3331 break;
3332
3333 case BC_RET0: case BC_RET1:
3334 | // RA = results*8, RD = (nresults+1)*8
3335 | lwz PC, FRAME_PC(BASE)
3336 | add RA, BASE, RA
3337 | mr MULTRES, RD
3338 | andi. TMP0, PC, FRAME_TYPE
3339 | xori TMP1, PC, FRAME_VARG
3340 | bne ->BC_RETV_Z
3341 |
3342 | lwz INS, -4(PC)
3343 | subi TMP2, BASE, 8
3344 | decode_RB8 RB, INS
3345 if (op == BC_RET1) {
3346 | evldd TMP0, 0(RA)
3347 | evstdd TMP0, 0(TMP2)
3348 }
3349 |5:
3350 | cmplw RB, RD
3351 | decode_RA8 RA, INS
3352 | bgt >6
3353 | sub BASE, TMP2, RA
3354 | lwz LFUNC:TMP1, FRAME_FUNC(BASE)
3355 | ins_next1
3356 | lwz TMP1, LFUNC:TMP1->pc
3357 | lwz KBASE, PC2PROTO(k)(TMP1)
3358 | ins_next2
3359 |
3360 |6: // Fill up results with nil.
3361 | subi TMP1, RD, 8
3362 | addi RD, RD, 8
3363 | evstddx TISNIL, TMP2, TMP1
3364 | b <5
3365 break;
3366
3367 /* -- Loops and branches ------------------------------------------------ */
3368
3369 case BC_FORL:
3370#if LJ_HASJIT
3371 | hotloop
3372#endif
3373 | // Fall through. Assumes BC_IFORL follows.
3374 break;
3375
3376 case BC_JFORI:
3377 case BC_JFORL:
3378#if !LJ_HASJIT
3379 break;
3380#endif
3381 case BC_FORI:
3382 case BC_IFORL:
3383 | // RA = base*8, RD = target (after end of loop or start of loop)
3384 vk = (op == BC_IFORL || op == BC_JFORL);
3385 | add RA, BASE, RA
3386 | evldd TMP1, FORL_IDX*8(RA)
3387 | evldd TMP3, FORL_STEP*8(RA)
3388 | evldd TMP2, FORL_STOP*8(RA)
3389 if (!vk) {
3390 | evcmpgtu cr0, TMP1, TISNUM
3391 | evcmpgtu cr7, TMP3, TISNUM
3392 | evcmpgtu cr1, TMP2, TISNUM
3393 | cror 4*cr0+lt, 4*cr0+lt, 4*cr7+lt
3394 | cror 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3395 | blt ->vmeta_for
3396 }
3397 if (vk) {
3398 | efdadd TMP1, TMP1, TMP3
3399 | evstdd TMP1, FORL_IDX*8(RA)
3400 }
3401 | evcmpgts TMP3, TISNIL
3402 | evstdd TMP1, FORL_EXT*8(RA)
3403 | bge >2
3404 | efdcmpgt TMP1, TMP2
3405 |1:
3406 if (op != BC_JFORL) {
3407 | srwi RD, RD, 1
3408 | add RD, PC, RD
3409 if (op == BC_JFORI) {
3410 | addis PC, RD, -(BCBIAS_J*4 >> 16)
3411 } else {
3412 | addis RD, RD, -(BCBIAS_J*4 >> 16)
3413 }
3414 }
3415 if (op == BC_FORI) {
3416 | iselgt PC, RD, PC
3417 } else if (op == BC_IFORL) {
3418 | iselgt PC, PC, RD
3419 } else {
3420 | ble =>BC_JLOOP
3421 }
3422 | ins_next
3423 |2:
3424 | efdcmpgt TMP2, TMP1
3425 | b <1
3426 break;
3427
3428 case BC_ITERL:
3429#if LJ_HASJIT
3430 | hotloop
3431#endif
3432 | // Fall through. Assumes BC_IITERL follows.
3433 break;
3434
3435 case BC_JITERL:
3436#if !LJ_HASJIT
3437 break;
3438#endif
3439 case BC_IITERL:
3440 | // RA = base*8, RD = target
3441 | evlddx TMP1, BASE, RA
3442 | subi RA, RA, 8
3443 | checknil TMP1
3444 | checkok >1 // Stop if iterator returned nil.
3445 if (op == BC_JITERL) {
3446 | NYI
3447 } else {
3448 | branch_RD // Otherwise save control var + branch.
3449 | evstddx TMP1, BASE, RA
3450 }
3451 |1:
3452 | ins_next
3453 break;
3454
3455 case BC_LOOP:
3456 | // RA = base*8, RD = target (loop extent)
3457 | // Note: RA/RD is only used by trace recorder to determine scope/extent
3458 | // This opcode does NOT jump, it's only purpose is to detect a hot loop.
3459#if LJ_HASJIT
3460 | hotloop
3461#endif
3462 | // Fall through. Assumes BC_ILOOP follows.
3463 break;
3464
3465 case BC_ILOOP:
3466 | // RA = base*8, RD = target (loop extent)
3467 | ins_next
3468 break;
3469
3470 case BC_JLOOP:
3471#if LJ_HASJIT
3472 | NYI
3473#endif
3474 break;
3475
3476 case BC_JMP:
3477 | // RA = base*8 (only used by trace recorder), RD = target
3478 | branch_RD
3479 | ins_next
3480 break;
3481
3482 /* -- Function headers -------------------------------------------------- */
3483
3484 case BC_FUNCF:
3485#if LJ_HASJIT
3486 | hotcall
3487#endif
3488 case BC_FUNCV: /* NYI: compiled vararg functions. */
3489 | // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow.
3490 break;
3491
3492 case BC_JFUNCF:
3493#if !LJ_HASJIT
3494 break;
3495#endif
3496 case BC_IFUNCF:
3497 | // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
3498 | lwz TMP2, L->maxstack
3499 | lbz TMP1, -4+PC2PROTO(numparams)(PC)
3500 | lwz KBASE, -4+PC2PROTO(k)(PC)
3501 | cmplw RA, TMP2
3502 | slwi TMP1, TMP1, 3
3503 | bgt ->vm_growstack_l
3504 | ins_next1
3505 |2:
3506 | cmplw NARGS8:RC, TMP1 // Check for missing parameters.
3507 | ble >3
3508 if (op == BC_JFUNCF) {
3509 | NYI
3510 } else {
3511 | ins_next2
3512 }
3513 |
3514 |3: // Clear missing parameters.
3515 | evstddx TISNIL, BASE, NARGS8:RC
3516 | addi NARGS8:RC, NARGS8:RC, 8
3517 | b <2
3518 break;
3519
3520 case BC_JFUNCV:
3521#if !LJ_HASJIT
3522 break;
3523#endif
3524 | NYI // NYI: compiled vararg functions
3525 break; /* NYI: compiled vararg functions. */
3526
3527 case BC_IFUNCV:
3528 | // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
3529 | lwz TMP2, L->maxstack
3530 | add TMP1, BASE, RC
3531 | add TMP0, RA, RC
3532 | stw LFUNC:RB, 4(TMP1) // Store copy of LFUNC.
3533 | addi TMP3, RC, 8+FRAME_VARG
3534 | lwz KBASE, -4+PC2PROTO(k)(PC)
3535 | cmplw TMP0, TMP2
3536 | stw TMP3, 0(TMP1) // Store delta + FRAME_VARG.
3537 | bge ->vm_growstack_l
3538 | lbz TMP2, -4+PC2PROTO(numparams)(PC)
3539 | mr RA, BASE
3540 | mr RC, TMP1
3541 | ins_next1
3542 | cmpwi TMP2, 0
3543 | addi BASE, TMP1, 8
3544 | beq >3
3545 |1:
3546 | cmplw RA, RC // Less args than parameters?
3547 | evldd TMP0, 0(RA)
3548 | bge >4
3549 | evstdd TISNIL, 0(RA) // Clear old fixarg slot (help the GC).
3550 | addi RA, RA, 8
3551 |2:
3552 | addic. TMP2, TMP2, -1
3553 | evstdd TMP0, 8(TMP1)
3554 | addi TMP1, TMP1, 8
3555 | bne <1
3556 |3:
3557 | ins_next2
3558 |
3559 |4: // Clear missing parameters.
3560 | evmr TMP0, TISNIL
3561 | b <2
3562 break;
3563
3564 case BC_FUNCC:
3565 case BC_FUNCCW:
3566 | // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8
3567 if (op == BC_FUNCC) {
3568 | lwz TMP3, CFUNC:RB->f
3569 } else {
3570 | lwz TMP3, DISPATCH_GL(wrapf)(DISPATCH)
3571 }
3572 | add TMP1, RA, NARGS8:RC
3573 | lwz TMP2, L->maxstack
3574 | add RC, BASE, NARGS8:RC
3575 | stw BASE, L->base
3576 | cmplw TMP1, TMP2
3577 | stw RC, L->top
3578 | li_vmstate C
3579 | mtctr TMP3
3580 if (op == BC_FUNCCW) {
3581 | lwz CARG2, CFUNC:RB->f
3582 }
3583 | mr CARG1, L
3584 | bgt ->vm_growstack_c // Need to grow stack.
3585 | st_vmstate
3586 | bctrl // (lua_State *L [, lua_CFunction f])
3587 | // Returns nresults.
3588 | lwz TMP1, L->top
3589 | slwi RD, CRET1, 3
3590 | lwz BASE, L->base
3591 | li_vmstate INTERP
3592 | lwz PC, FRAME_PC(BASE) // Fetch PC of caller.
3593 | sub RA, TMP1, RD // RA = L->top - nresults*8
3594 | st_vmstate
3595 | b ->vm_returnc
3596 break;
3597
3598 /* ---------------------------------------------------------------------- */
3599
3600 default:
3601 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
3602 exit(2);
3603 break;
3604 }
3605}
3606
3607static int build_backend(BuildCtx *ctx)
3608{
3609 int op;
3610
3611 dasm_growpc(Dst, BC__MAX);
3612
3613 build_subroutines(ctx);
3614
3615 |.code_op
3616 for (op = 0; op < BC__MAX; op++)
3617 build_ins(ctx, (BCOp)op, op);
3618
3619 return BC__MAX;
3620}
3621
3622/* Emit pseudo frame-info for all assembler functions. */
3623static void emit_asm_debug(BuildCtx *ctx)
3624{
3625 int i;
3626 switch (ctx->mode) {
3627 case BUILD_elfasm:
3628 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
3629 fprintf(ctx->fp,
3630 ".Lframe0:\n"
3631 "\t.long .LECIE0-.LSCIE0\n"
3632 ".LSCIE0:\n"
3633 "\t.long 0xffffffff\n"
3634 "\t.byte 0x1\n"
3635 "\t.string \"\"\n"
3636 "\t.uleb128 0x1\n"
3637 "\t.sleb128 -4\n"
3638 "\t.byte 65\n"
3639 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
3640 "\t.align 2\n"
3641 ".LECIE0:\n\n");
3642 fprintf(ctx->fp,
3643 ".LSFDE0:\n"
3644 "\t.long .LEFDE0-.LASFDE0\n"
3645 ".LASFDE0:\n"
3646 "\t.long .Lframe0\n"
3647 "\t.long .Lbegin\n"
3648 "\t.long %d\n"
3649 "\t.byte 0xe\n\t.uleb128 %d\n"
3650 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
3651 "\t.byte 0x5\n\t.uleb128 70\n\t.sleb128 37\n",
3652 (int)ctx->codesz, CFRAME_SIZE);
3653 for (i = 14; i <= 31; i++)
3654 fprintf(ctx->fp,
3655 "\t.byte %d\n\t.uleb128 %d\n"
3656 "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n",
3657 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i));
3658 fprintf(ctx->fp,
3659 "\t.align 2\n"
3660 ".LEFDE0:\n\n");
3661 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
3662 fprintf(ctx->fp,
3663 ".Lframe1:\n"
3664 "\t.long .LECIE1-.LSCIE1\n"
3665 ".LSCIE1:\n"
3666 "\t.long 0\n"
3667 "\t.byte 0x1\n"
3668 "\t.string \"zPR\"\n"
3669 "\t.uleb128 0x1\n"
3670 "\t.sleb128 -4\n"
3671 "\t.byte 65\n"
3672 "\t.uleb128 6\n" /* augmentation length */
3673 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3674 "\t.long lj_err_unwind_dwarf-.\n"
3675 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3676 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
3677 "\t.align 2\n"
3678 ".LECIE1:\n\n");
3679 fprintf(ctx->fp,
3680 ".LSFDE1:\n"
3681 "\t.long .LEFDE1-.LASFDE1\n"
3682 ".LASFDE1:\n"
3683 "\t.long .LASFDE1-.Lframe1\n"
3684 "\t.long .Lbegin-.\n"
3685 "\t.long %d\n"
3686 "\t.uleb128 0\n" /* augmentation length */
3687 "\t.byte 0xe\n\t.uleb128 %d\n"
3688 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
3689 "\t.byte 0x5\n\t.uleb128 70\n\t.sleb128 37\n",
3690 (int)ctx->codesz, CFRAME_SIZE);
3691 for (i = 14; i <= 31; i++)
3692 fprintf(ctx->fp,
3693 "\t.byte %d\n\t.uleb128 %d\n"
3694 "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n",
3695 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i));
3696 fprintf(ctx->fp,
3697 "\t.align 2\n"
3698 ".LEFDE1:\n\n");
3699 break;
3700 default:
3701 break;
3702 }
3703}
3704
diff --git a/libraries/luajit-2.0/src/buildvm_ppcspe.h b/libraries/luajit-2.0/src/buildvm_ppcspe.h
new file mode 100644
index 0000000..32571eb
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_ppcspe.h
@@ -0,0 +1,6093 @@
1/*
2** This file has been pre-processed with DynASM.
3** http://luajit.org/dynasm.html
4** DynASM version 1.3.0, DynASM ppc version 1.3.0
5** DO NOT EDIT! The original file is in "buildvm_ppcspe.dasc".
6*/
7
8#if DASM_VERSION != 10300
9#error "Version mismatch between DynASM and included encoding engine"
10#endif
11
12#define DASM_SECTION_CODE_OP 0
13#define DASM_SECTION_CODE_SUB 1
14#define DASM_MAXSECTION 2
15static const unsigned int build_actionlist[4995] = {
160x00010001,
170x00060014,
180x72000000,
190x00090200,
200x11000229,
210x000980b0,
220x41820000,
230x00050815,
240x8209fff8,
250x7d2e4b78,
260x9514fff8,
270x00060016,
280x72000000,
290x00090200,
300x398c0008,
310x7d936378,
320x41820000,
330x00050817,
340x00060018,
350x2c000000,
360x00098200,
370x56090038,
380x38000000,
390x00098200,
400x7d297050,
410x40820000,
420x00050814,
430x350cfff8,
440x91320000,
450x00098200,
460x81210018,
470x39cefff8,
480x90110000,
490x00098200,
500x55291800,
510x000900a1,
520x41820000,
530x00050802,
540x0006000b,
550x3508fff8,
560x10140301,
570x3a940008,
580x100e0321,
590x39ce0008,
600x40820000,
610x0005080b,
620x0006000c,
630x7c096000,
640x40820000,
650x00050806,
660x0006000d,
670x91d20000,
680x00098200,
690x00060019,
700x00000000,
710x80010014,
720x38600000,
730x90120000,
740x00098200,
750x0006001a,
760x800100bc,
770x81810024,
780x11c12b01,
790x11e13301,
800x12013b01,
810x12214301,
820x12414b01,
830x12615301,
840x7c0803a6,
850x7d838120,
860x12815b01,
870x12a16301,
880x12c16b01,
890x12e17301,
900x13017b01,
910x13218301,
920x13418b01,
930x13619301,
940x13819b01,
950x13a1a301,
960x13c1ab01,
970x13e1b301,
980x382100b8,
990x4e800020,
1000x00060010,
1010x40810000,
1020x00050807,
1030x81120000,
1040x00098200,
1050x7c0e4040,
1060x40800000,
1070x00050808,
1080x134e0321,
1090x398c0008,
1100x39ce0008,
1110x48000000,
1120x0005000c,
1130x00060011,
1140x7c096050,
1150x2c090000,
1160x7c007050,
1170x7dce009e,
1180x48000000,
1190x0005000d,
1200x00060012,
1210x91d20000,
1220x00098200,
1230x7d956378,
1240x7d244b78,
1250x7e439378,
1260x48000001,
1270x00030000,
1280x81210018,
1290x7eacab78,
1300x55291800,
1310x000900a1,
1320x81d20000,
1330x00098200,
1340x48000000,
1350x0005000c,
1360x0006001b,
1370x7c611b78,
1380x7c832378,
1390x0006001c,
1400x82410010,
1410x38000000,
1420x00098200,
1430x81120000,
1440x00098200,
1450x90080000,
1460x00098200,
1470x48000000,
1480x0005001a,
1490x0006001d,
1500x00000000,
1510x5461003a,
1520x0006001e,
1530x82410010,
1540x12c00229,
1550x000980b0,
1560x13200229,
1570x000980b0,
1580x3f604338,
1590x13000229,
1600x000980b0,
1610x38000000,
1620x81d20000,
1630x00098200,
1640x137b022d,
1650x82320000,
1660x00098200,
1670x12e00229,
1680x000980b0,
1690x39000000,
1700x00098200,
1710x13400229,
1720x000980b0,
1730x38000000,
1740x00098200,
1750x820efff8,
1760x3a8efff8,
1770x3a310000,
1780x00098200,
1790x91140000,
1800x39800010,
1810x90110000,
1820x00098200,
1830x48000000,
1840x00050016,
1850x0006001f,
1860x38800000,
1870x00098200,
1880x48000000,
1890x00050002,
1900x00060020,
1910x7d6e5a14,
1920x7e8ea050,
1930x91d20000,
1940x00098200,
1950x3a100004,
1960x91720000,
1970x00098200,
1980x568400fe,
1990x000900ab,
2000x0006000c,
2010x9201000c,
2020x7e439378,
2030x48000001,
2040x00030000,
2050x00000000,
2060x81d20000,
2070x00098200,
2080x81720000,
2090x00098200,
2100x814efffc,
2110x7d6e5850,
2120x820a0000,
2130x00098200,
2140x80f00000,
2150x3a100004,
2160x54e815ba,
2170x54f4dd78,
2180x7c11402e,
2190x7e947214,
2200x7c0903a6,
2210x4e800420,
2220x00060021,
2230x9421ff48,
2240x11c12b21,
2250x11e13321,
2260x12013b21,
2270x12214321,
2280x12414b21,
2290x12615321,
2300x7c0802a6,
2310x7d800026,
2320x12815b21,
2330x12a16321,
2340x12c16b21,
2350x12e17321,
2360x13017b21,
2370x13218321,
2380x900100bc,
2390x91810024,
2400x13418b21,
2410x13619321,
2420x13819b21,
2430x13a1a321,
2440x13c1ab21,
2450x13e1b321,
2460x7c721b78,
2470x82320000,
2480x00098200,
2490x7c8e2378,
2500x89120000,
2510x00098200,
2520x92410010,
2530x3a000000,
2540x00098200,
2550x38010000,
2560x00098200,
2570x3a310000,
2580x00098200,
2590x90a10018,
2600x28080000,
2610x90a1001c,
2620x90120000,
2630x00098200,
2640x90a10014,
2650x9061000c,
2660x41820000,
2670x00050803,
2680x7dd47378,
2690x81d20000,
2700x00098200,
2710x12c00229,
2720x000980b0,
2730x81120000,
2740x00098200,
2750x13200229,
2760x000980b0,
2770x3f604338,
2780x13000229,
2790x000980b0,
2800x820efff8,
2810x39200000,
2820x12e00229,
2830x000980b0,
2840x7d8e4050,
2850x137b4a2d,
2860x98b20000,
2870x00098200,
2880x72000000,
2890x00090200,
2900x38000000,
2910x00098200,
2920x398c0008,
2930x13400229,
2940x000980b0,
2950x7d936378,
2960x90110000,
2970x00098200,
2980x00000000,
2990x41820000,
3000x00050817,
3010x48000000,
3020x00050018,
3030x00060022,
3040x9421ff48,
3050x11c12b21,
3060x11e13321,
3070x12013b21,
3080x12214321,
3090x12414b21,
3100x12615321,
3110x7c0802a6,
3120x7d800026,
3130x12815b21,
3140x12a16321,
3150x12c16b21,
3160x12e17321,
3170x13017b21,
3180x13218321,
3190x900100bc,
3200x91810024,
3210x13418b21,
3220x13619321,
3230x13819b21,
3240x13a1a321,
3250x13c1ab21,
3260x13e1b321,
3270x3a000000,
3280x00098200,
3290x90c1001c,
3300x48000000,
3310x00050001,
3320x00060023,
3330x9421ff48,
3340x11c12b21,
3350x11e13321,
3360x12013b21,
3370x12214321,
3380x12414b21,
3390x12615321,
3400x7c0802a6,
3410x7d800026,
3420x12815b21,
3430x12a16321,
3440x12c16b21,
3450x12e17321,
3460x13017b21,
3470x13218321,
3480x900100bc,
3490x91810024,
3500x13418b21,
3510x13619321,
3520x13819b21,
3530x13a1a321,
3540x13c1ab21,
3550x13e1b321,
3560x3a000000,
3570x00098200,
3580x0006000b,
3590x81030000,
3600x00098200,
3610x90a10018,
3620x7c721b78,
3630x90610010,
3640x7c8e2378,
3650x90320000,
3660x00098200,
3670x82320000,
3680x00098200,
3690x9061000c,
3700x91010014,
3710x3a310000,
3720x00098200,
3730x0006000d,
3740x81320000,
3750x00098200,
3760x12c00229,
3770x000980b0,
3780x81120000,
3790x00098200,
3800x13200229,
3810x000980b0,
3820x7e107214,
3830x13000229,
3840x000980b0,
3850x3f604338,
3860x38000000,
3870x7e098050,
3880x12e00229,
3890x000980b0,
3900x7d6e4050,
3910x137b022d,
3920x38000000,
3930x00098200,
3940x13400229,
3950x000980b0,
3960x90110000,
3970x00098200,
3980x00060024,
3990x00000000,
4000x3800fff8,
4010x114e0300,
4020x100aca34,
4030x40800000,
4040x00050825,
4050x00060026,
4060x920efff8,
4070x820a0000,
4080x00098200,
4090x80f00000,
4100x3a100004,
4110x54e815ba,
4120x54f4dd78,
4130x7c11402e,
4140x7e947214,
4150x7c0903a6,
4160x4e800420,
4170x00060027,
4180x9421ff48,
4190x11c12b21,
4200x11e13321,
4210x12013b21,
4220x12214321,
4230x12414b21,
4240x12615321,
4250x7c0802a6,
4260x7d800026,
4270x12815b21,
4280x12a16321,
4290x12c16b21,
4300x12e17321,
4310x13017b21,
4320x13218321,
4330x900100bc,
4340x91810024,
4350x13418b21,
4360x13619321,
4370x13819b21,
4380x13a1a321,
4390x13c1ab21,
4400x13e1b321,
4410x7c721b78,
4420x80030000,
4430x00098200,
4440x90610010,
4450x81120000,
4460x00098200,
4470x9061000c,
4480x7c080050,
4490x81120000,
4500x00098200,
4510x90320000,
4520x00098200,
4530x39200000,
4540x90010018,
4550x9121001c,
4560x91010014,
4570x7cc903a6,
4580x4e800421,
4590x7c6e1b79,
4600x82320000,
4610x00098200,
4620x3a000000,
4630x00098200,
4640x3a310000,
4650x00098200,
4660x40820000,
4670x0005080d,
4680x48000000,
4690x00050019,
4700x00060015,
4710x800efff4,
4720x7dca7378,
4730x7d2e4b78,
4740x8109fffc,
4750x28000000,
4760x820afff0,
4770x41820000,
4780x00050801,
4790x392cfff8,
4800x81080000,
4810x00098200,
4820x13544b20,
4830x81e80000,
4840x00098200,
4850x7c0903a6,
4860x4e800420,
4870x0006000b,
4880x390afff0,
4890x7d6e4050,
4900x48000000,
4910x00050028,
4920x00060029,
4930x80f0fffc,
4940x388afff0,
4950x54f55d78,
4960x10140301,
4970x7d0eaa14,
4980x91d20000,
4990x00098200,
5000x7c082040,
5010x7ca82050,
5020x54f4dd78,
5030x10040321,
5040x40820000,
5050x0005082a,
5060x00000000,
5070x100ea320,
5080x48000000,
5090x0005002b,
5100x0006002c,
5110x11775a2d,
5120x38b10000,
5130x00098200,
5140x54ea5d78,
5150x11650321,
5160x7c8e5214,
5170x48000000,
5180x00050001,
5190x0006002d,
5200x1158522d,
5210x38910000,
5220x00098200,
5230x11775a2d,
5240x11440321,
5250x38b10000,
5260x00098200,
5270x11650321,
5280x48000000,
5290x00050001,
5300x0006002e,
5310x100002f1,
5320x54ea5d78,
5330x38b10000,
5340x00098200,
5350x7c8e5214,
5360x10050321,
5370x48000000,
5380x00050001,
5390x0006002f,
5400x54ea5d78,
5410x54eb9d78,
5420x7c8e5214,
5430x7cae5a14,
5440x0006000b,
5450x91d20000,
5460x00098200,
5470x7e439378,
5480x9201000c,
5490x48000001,
5500x00030001,
5510x28030000,
5520x41820000,
5530x00050803,
5540x10030301,
5550x100ea320,
5560x80f00000,
5570x3a100004,
5580x54e815ba,
5590x54ea5d78,
5600x54ec9b78,
5610x7c11402e,
5620x54f4dd78,
5630x54eb9d78,
5640x7c0903a6,
5650x4e800420,
5660x0006000d,
5670x210e0000,
5680x00098200,
5690x81d20000,
5700x00098200,
5710x920efff0,
5720x7e087214,
5730x814efffc,
5740x39600010,
5750x48000000,
5760x00050026,
5770x00060030,
5780x11775a2d,
5790x38b10000,
5800x00098200,
5810x00000000,
5820x54ea5d78,
5830x11650321,
5840x7c8e5214,
5850x48000000,
5860x00050001,
5870x00060031,
5880x1158522d,
5890x38910000,
5900x00098200,
5910x11775a2d,
5920x11440321,
5930x38b10000,
5940x00098200,
5950x11650321,
5960x48000000,
5970x00050001,
5980x00060032,
5990x100002f1,
6000x54ea5d78,
6010x38b10000,
6020x00098200,
6030x7c8e5214,
6040x10050321,
6050x48000000,
6060x00050001,
6070x00060033,
6080x54ea5d78,
6090x54eb9d78,
6100x7c8e5214,
6110x7cae5a14,
6120x0006000b,
6130x91d20000,
6140x00098200,
6150x7e439378,
6160x9201000c,
6170x48000001,
6180x00030002,
6190x28030000,
6200x100ea300,
6210x41820000,
6220x00050803,
6230x10030321,
6240x80f00000,
6250x3a100004,
6260x54e815ba,
6270x54ea5d78,
6280x54ec9b78,
6290x7c11402e,
6300x54f4dd78,
6310x54eb9d78,
6320x7c0903a6,
6330x4e800420,
6340x0006000d,
6350x210e0000,
6360x00098200,
6370x81d20000,
6380x00098200,
6390x920efff0,
6400x7e087214,
6410x814efffc,
6420x39600018,
6430x100e1321,
6440x48000000,
6450x00050026,
6460x00060034,
6470x7e439378,
6480x3a10fffc,
6490x7c8ea214,
6500x9201000c,
6510x7cae6214,
6520x91d20000,
6530x00098200,
6540x54e6063e,
6550x48000001,
6560x00030003,
6570x0006000d,
6580x28030001,
6590x41810000,
6600x00050835,
6610x0006000e,
6620x00000000,
6630x80f00000,
6640x3a100004,
6650x54e993ba,
6660x3cd00000,
6670x00098200,
6680x7d293214,
6690x7e10481e,
6700x0006002b,
6710x80f00000,
6720x3a100004,
6730x54e815ba,
6740x54ea5d78,
6750x54ec9b78,
6760x7c11402e,
6770x54f4dd78,
6780x54eb9d78,
6790x7c0903a6,
6800x4e800420,
6810x00060036,
6820x80f0fffc,
6830x10140301,
6840x54e8dd78,
6850x100e4320,
6860x48000000,
6870x0005002b,
6880x00060037,
6890x80140000,
6900x39000000,
6910x00098200,
6920x7c080040,
6930x48000000,
6940x0005000e,
6950x00060038,
6960x80140000,
6970x39000000,
6980x00098200,
6990x7c004040,
7000x48000000,
7010x0005000e,
7020x00060039,
7030x3a10fffc,
7040x91d20000,
7050x00098200,
7060x7e439378,
7070x9201000c,
7080x48000001,
7090x00030004,
7100x48000000,
7110x0005000d,
7120x0006003a,
7130x7cae5214,
7140x7ccf5a14,
7150x48000000,
7160x00050001,
7170x0006003b,
7180x7caf5a14,
7190x7cce5214,
7200x48000000,
7210x00050001,
7220x0006003c,
7230x7cae6214,
7240x7ca62b78,
7250x48000000,
7260x00050001,
7270x0006003d,
7280x7cae5214,
7290x7cce5a14,
7300x0006000b,
7310x00000000,
7320x7c8ea214,
7330x91d20000,
7340x00098200,
7350x7e439378,
7360x9201000c,
7370x54e7063e,
7380x48000001,
7390x00030005,
7400x28030000,
7410x41820000,
7420x0005082b,
7430x00060035,
7440x7d0e1850,
7450x9203fff0,
7460x7dc97378,
7470x3a080000,
7480x00098200,
7490x7c6e1b78,
7500x39600010,
7510x48000000,
7520x00050024,
7530x0006003e,
7540x00000000,
7550x7c751b78,
7560x00000000,
7570x7c8e6214,
7580x91d20000,
7590x00098200,
7600x7e439378,
7610x9201000c,
7620x48000001,
7630x00030006,
7640x00000000,
7650x28030000,
7660x40820000,
7670x00050835,
7680x7ea3ab78,
7690x48000000,
7700x0005003f,
7710x00000000,
7720x48000000,
7730x00050035,
7740x00000000,
7750x00060025,
7760x7e439378,
7770x91320000,
7780x00098200,
7790x388efff8,
7800x9201000c,
7810x7cae5a14,
7820x7d755b78,
7830x48000001,
7840x00030007,
7850x814efffc,
7860x39750008,
7870x920efff8,
7880x820a0000,
7890x00098200,
7900x80f00000,
7910x3a100004,
7920x54e815ba,
7930x54f4dd78,
7940x7c11402e,
7950x7e947214,
7960x7c0903a6,
7970x4e800420,
7980x00060040,
7990x7e439378,
8000x91d20000,
8010x00098200,
8020x3894fff8,
8030x9201000c,
8040x7cb45a14,
8050x7d755b78,
8060x48000001,
8070x00030007,
8080x810efff8,
8090x39750008,
8100x8154fffc,
8110x48000000,
8120x00050041,
8130x00060042,
8140x7e439378,
8150x91d20000,
8160x00098200,
8170x7e84a378,
8180x9201000c,
8190x7cf53b78,
8200x48000001,
8210x00030008,
8220x00000000,
8230x56a0063e,
8240x00000000,
8250x56b4dd78,
8260x00000000,
8270x2c000000,
8280x00098200,
8290x00000000,
8300x56ac9b78,
8310x00000000,
8320x41820000,
8330x00070800,
8340x00000000,
8350x48000000,
8360x00070000,
8370x00060043,
8380x280b0008,
8390x100e0301,
8400x41800000,
8410x00050844,
8420x111ad200,
8430x3a8efff8,
8440x10804232,
8450x820efff8,
8460x40840000,
8470x00050844,
8480x10140321,
8490x398b0008,
8500x41820000,
8510x00050845,
8520x39000008,
8530x396bfff8,
8540x0006000b,
8550x7c085840,
8560x100e4300,
8570x10144320,
8580x39080008,
8590x40820000,
8600x0005080b,
8610x48000000,
8620x00050045,
8630x00060046,
8640x280b0008,
8650x806e0000,
8660x41800000,
8670x00050844,
8680x39200000,
8690x00098200,
8700x7c03b040,
8710x7c6818f8,
8720x7d09401e,
8730x55081800,
8740x000900a1,
8750x392a0000,
8760x00098200,
8770x10694300,
8780x48000000,
8790x00050047,
8800x00060048,
8810x280b0008,
8820x106e0301,
8830x41800000,
8840x00050844,
8850x1003c234,
8860x11031a2c,
8870x40800000,
8880x00050806,
8890x0006000b,
8900x81430000,
8910x00098200,
8920x0006000c,
8930x107ad217,
8940x280a0000,
8950x81710000,
8960x00098200,
8970x41820000,
8980x00050847,
8990x00000000,
9000x800a0000,
9010x00098200,
9020x1078522d,
9030x810b0000,
9040x00098200,
9050x812a0000,
9060x00098200,
9070x11775a2d,
9080x7d080038,
9090x55002800,
9100x000900a1,
9110x55081800,
9120x000900a1,
9130x7d080050,
9140x7d294214,
9150x0006000d,
9160x10090301,
9170x00090cab,
9180x11090301,
9190x00090cab,
9200x10005a34,
9210x81290000,
9220x00098200,
9230x41830000,
9240x00050805,
9250x28090000,
9260x41820000,
9270x00050847,
9280x48000000,
9290x0005000d,
9300x0006000f,
9310x1008d234,
9320x41800000,
9330x00050847,
9340x10684217,
9350x48000000,
9360x00050047,
9370x00060010,
9380x2c080000,
9390x00098200,
9400x7d0840f8,
9410x41820000,
9420x0005080b,
9430x1003b232,
9440x55081000,
9450x000900a1,
9460x39200000,
9470x00098200,
9480x7d09401e,
9490x39310000,
9500x00098200,
9510x7d49402e,
9520x48000000,
9530x0005000c,
9540x00060049,
9550x00000000,
9560x280b0010,
9570x106e0301,
9580x108e0b01,
9590x41800000,
9600x00050844,
9610x1003222c,
9620x1000c234,
9630x40830000,
9640x00050844,
9650x81030000,
9660x00098200,
9670x28080000,
9680x88c30000,
9690x00098200,
9700x40820000,
9710x00050844,
9720x70c00000,
9730x00090200,
9740x90830000,
9750x00098200,
9760x41820000,
9770x00050847,
9780x80110000,
9790x00098200,
9800x54c607b8,
9810x90710000,
9820x00098200,
9830x98c30000,
9840x00098200,
9850x90030000,
9860x00098200,
9870x48000000,
9880x00050047,
9890x0006004a,
9900x280b0010,
9910x108e0301,
9920x41800000,
9930x00050844,
9940x1004c234,
9950x38ae0008,
9960x40800000,
9970x00050844,
9980x7e439378,
9990x48000001,
10000x00030009,
10010x10630301,
10020x48000000,
10030x00050047,
10040x0006004b,
10050x280b0008,
10060x106e0301,
10070x40820000,
10080x00050844,
10090x1003b232,
10100x41800000,
10110x00050847,
10120x48000000,
10130x00050044,
10140x0006004c,
10150x00000000,
10160x280b0008,
10170x106e0301,
10180x41800000,
10190x00050844,
10200x1003ba34,
10210x41800000,
10220x00050847,
10230x80110000,
10240x00098200,
10250x1003b232,
10260x28800000,
10270x91d20000,
10280x00098200,
10290x4c403202,
10300x9201000c,
10310x40820000,
10320x00050844,
10330x80110000,
10340x00098200,
10350x81110000,
10360x00098200,
10370x7c004040,
10380x40800001,
10390x0005084d,
10400x7e439378,
10410x7dc47378,
10420x48000001,
10430x0003000a,
10440x10771a2d,
10450x48000000,
10460x00050047,
10470x0006004e,
10480x280b0008,
10490x108e0301,
10500x41800000,
10510x00050844,
10520x134e5b20,
10530x1004c234,
10540x820efff8,
10550x40800000,
10560x00050844,
10570x91d20000,
10580x00098200,
10590x7e439378,
10600x91d20000,
10610x00098200,
10620x38ae0008,
10630x9201000c,
10640x48000001,
10650x0003000b,
10660x28030000,
10670x107ad217,
10680x41820000,
10690x00050847,
10700x100e0b01,
10710x3a8efff8,
10720x110e1301,
10730x10140321,
10740x39800000,
10750x00098200,
10760x11140b21,
10770x48000000,
10780x00050045,
10790x0006004f,
10800x280b0008,
10810x106e0301,
10820x41800000,
10830x00050844,
10840x1003c234,
10850x820efff8,
10860x40800000,
10870x00050844,
10880x00000000,
10890x81230000,
10900x00098200,
10910x100a0301,
10920x00090cab,
10930x28090000,
10940x3a8efff8,
10950x40820000,
10960x00050844,
10970x00000000,
10980x100a0301,
10990x00090cab,
11000x3a8efff8,
11010x00000000,
11020x134e0b21,
11030x39800000,
11040x00098200,
11050x10140321,
11060x48000000,
11070x00050045,
11080x00060050,
11090x280b0010,
11100x106e0301,
11110x108e0b01,
11120x41800000,
11130x00050844,
11140x1003c234,
11150x820efff8,
11160x40800000,
11170x00050844,
11180x1004b232,
11190x3cc03ff0,
11200x40800000,
11210x00050844,
11220x112022f5,
11230x80030000,
11240x00098200,
11250x10c6da2d,
11260x81030000,
11270x00098200,
11280x108432e0,
11290x39290001,
11300x3a8efff8,
11310x7c004840,
11320x55261800,
11330x000900a1,
11340x10940321,
11350x40810000,
11360x00050802,
11370x11083300,
11380x0006000b,
11390x1008d234,
11400x39800000,
11410x00098200,
11420x41800000,
11430x00050845,
11440x39800000,
11450x00098200,
11460x11140b21,
11470x48000000,
11480x00050045,
11490x0006000c,
11500x80030000,
11510x00098200,
11520x28000000,
11530x39800000,
11540x00098200,
11550x41820000,
11560x00050845,
11570x7d244b78,
11580x48000001,
11590x0003000c,
11600x28030000,
11610x39800000,
11620x00098200,
11630x41820000,
11640x00050845,
11650x00000000,
11660x11030301,
11670x48000000,
11680x0005000b,
11690x00060051,
11700x280b0008,
11710x106e0301,
11720x41800000,
11730x00050844,
11740x1003c234,
11750x820efff8,
11760x40800000,
11770x00050844,
11780x00000000,
11790x81230000,
11800x00098200,
11810x100a0301,
11820x00090cab,
11830x28090000,
11840x3a8efff8,
11850x40820000,
11860x00050844,
11870x00000000,
11880x100a0301,
11890x00090cab,
11900x3a8efff8,
11910x00000000,
11920x11000229,
11930x39800000,
11940x00098200,
11950x110e0b21,
11960x10140321,
11970x48000000,
11980x00050045,
11990x00060052,
12000x280b0008,
12010x88d10000,
12020x00098200,
12030x41800000,
12040x00050844,
12050x7dc97378,
12060x39ce0008,
12070x54c607fe,
12080x000900ab,
12090x396bfff8,
12100x3a060000,
12110x00098200,
12120x48000000,
12130x00050024,
12140x00060053,
12150x280b0010,
12160x106e0301,
12170x108e0b01,
12180x41800000,
12190x00050844,
12200x88d10000,
12210x00098200,
12220x7dc97378,
12230x1004ca34,
12240x40800000,
12250x00050844,
12260x39ce0010,
12270x54c607fe,
12280x000900ab,
12290x10890321,
12300x396bfff0,
12310x10690b21,
12320x3a060000,
12330x00098200,
12340x48000000,
12350x00050024,
12360x00060054,
12370x280b0008,
12380x106e0301,
12390x41800000,
12400x00050844,
12410x10031a2c,
12420x2c000000,
12430x00098200,
12440x40820000,
12450x00050844,
12460x88030000,
12470x00098200,
12480x81030000,
12490x00098200,
12500x80830000,
12510x00098200,
12520x00000000,
12530x28000000,
12540x00090200,
12550x81230000,
12560x00098200,
12570x28880000,
12580x80030000,
12590x00098200,
12600x7f844840,
12610x820efff8,
12620x4f013342,
12630x7d245a14,
12640x4f3e1102,
12650x7c890040,
12660x4f18cb82,
12670x9201000c,
12680x4f182b82,
12690x91d20000,
12700x00098200,
12710x41980000,
12720x00050844,
12730x0006000b,
12740x39ce0008,
12750x396bfff8,
12760x3929fff8,
12770x91230000,
12780x00098200,
12790x39000000,
12800x91d20000,
12810x00098200,
12820x0006000c,
12830x7c085800,
12840x100e4300,
12850x41820000,
12860x00050803,
12870x10044320,
12880x39080008,
12890x48000000,
12900x0005000c,
12910x0006000d,
12920x38a00000,
12930x7c751b78,
12940x38c00000,
12950x48000001,
12960x00050021,
12970x0006000e,
12980x81350000,
12990x00098200,
13000x28030000,
13010x00090200,
13020x80d50000,
13030x00098200,
13040x38000000,
13050x00098200,
13060x81d20000,
13070x00098200,
13080x90110000,
13090x00098200,
13100x41810000,
13110x00050808,
13120x7d893050,
13130x80120000,
13140x00098200,
13150x00000000,
13160x280c0000,
13170x7d0e6214,
13180x41820000,
13190x00050806,
13200x7c080040,
13210x39000000,
13220x41810000,
13230x00050809,
13240x38ccfff8,
13250x91350000,
13260x00098200,
13270x0006000f,
13280x7c083040,
13290x10094300,
13300x100e4320,
13310x39080008,
13320x40820000,
13330x0005080f,
13340x00060010,
13350x72000000,
13360x00090200,
13370x39000000,
13380x00098200,
13390x3a8efff8,
13400x910efff8,
13410x398c0010,
13420x00060011,
13430x9201000c,
13440x7d936378,
13450x41820000,
13460x00050817,
13470x48000000,
13480x00050018,
13490x00060012,
13500x72000000,
13510x00090200,
13520x38c6fff8,
13530x39000000,
13540x00098200,
13550x10060301,
13560x90d50000,
13570x00098200,
13580x39800000,
13590x00098200,
13600x910efff8,
13610x3a8efff8,
13620x100e0321,
13630x48000000,
13640x00050011,
13650x00060013,
13660x7e439378,
13670x558400fe,
13680x000900ab,
13690x48000001,
13700x00030000,
13710x38600000,
13720x48000000,
13730x0005000e,
13740x00060055,
13750x00000000,
13760x806a0000,
13770x00098200,
13780x88030000,
13790x00098200,
13800x81030000,
13810x00098200,
13820x80830000,
13830x00098200,
13840x28000000,
13850x00090200,
13860x81230000,
13870x00098200,
13880x28880000,
13890x80030000,
13900x00098200,
13910x7f844840,
13920x820efff8,
13930x4f013342,
13940x7d245a14,
13950x4f3e1102,
13960x7c890040,
13970x4f18cb82,
13980x9201000c,
13990x4f182b82,
14000x91d20000,
14010x00098200,
14020x41980000,
14030x00050844,
14040x0006000b,
14050x91230000,
14060x00098200,
14070x39000000,
14080x91d20000,
14090x00098200,
14100x0006000c,
14110x7c085800,
14120x100e4300,
14130x41820000,
14140x00050803,
14150x10044320,
14160x39080008,
14170x48000000,
14180x0005000c,
14190x0006000d,
14200x38a00000,
14210x7c751b78,
14220x38c00000,
14230x48000001,
14240x00050021,
14250x0006000e,
14260x81350000,
14270x00098200,
14280x28030000,
14290x00090200,
14300x80d50000,
14310x00098200,
14320x38000000,
14330x00098200,
14340x00000000,
14350x81d20000,
14360x00098200,
14370x90110000,
14380x00098200,
14390x41810000,
14400x00050808,
14410x7d893050,
14420x80120000,
14430x00098200,
14440x280c0000,
14450x7d0e6214,
14460x41820000,
14470x00050806,
14480x7c080040,
14490x39000000,
14500x41810000,
14510x00050809,
14520x38ccfff8,
14530x91350000,
14540x00098200,
14550x0006000f,
14560x7c083040,
14570x10094300,
14580x100e4320,
14590x39080008,
14600x40820000,
14610x0005080f,
14620x00060010,
14630x72000000,
14640x00090200,
14650x7dd47378,
14660x398c0008,
14670x00060011,
14680x9201000c,
14690x7d936378,
14700x41820000,
14710x00050817,
14720x48000000,
14730x00050018,
14740x00060012,
14750x7e439378,
14760x7ea4ab78,
14770x48000001,
14780x0003000d,
14790x00060013,
14800x7e439378,
14810x558400fe,
14820x000900ab,
14830x48000001,
14840x00030000,
14850x38600000,
14860x48000000,
14870x0005000e,
14880x00060056,
14890x80120000,
14900x00098200,
14910x00000000,
14920x7d0e5a14,
14930x91d20000,
14940x00098200,
14950x70000000,
14960x00090200,
14970x91120000,
14980x00098200,
14990x38600000,
15000x00098200,
15010x41820000,
15020x00050844,
15030x93720000,
15040x00098200,
15050x98720000,
15060x00098200,
15070x48000000,
15080x0005001a,
15090x00060057,
15100x280b0008,
15110x106e0301,
15120x41800000,
15130x00050844,
15140x1003b232,
15150x40800000,
15160x00050844,
15170x106302e4,
15180x00060047,
15190x820efff8,
15200x3a8efff8,
15210x10740321,
15220x00060058,
15230x39800000,
15240x00098200,
15250x00060045,
15260x72000000,
15270x00090200,
15280x7d936378,
15290x40820000,
15300x00050818,
15310x80f0fffc,
15320x54ea5d78,
15330x0006000f,
15340x7c0a6040,
15350x54e0dd78,
15360x41810000,
15370x00050806,
15380x80f00000,
15390x3a100004,
15400x7dc0a050,
15410x54e815ba,
15420x54ea5d78,
15430x54ec9b78,
15440x7c11402e,
15450x54f4dd78,
15460x54eb9d78,
15470x7c0903a6,
15480x4e800420,
15490x00060010,
15500x390cfff8,
15510x398c0008,
15520x13544320,
15530x48000000,
15540x0005000f,
15550x00060059,
15560x00000000,
15570x280b0008,
15580x108e0301,
15590x41800000,
15600x00050844,
15610x1004b232,
15620x1064222c,
15630x40800000,
15640x00050844,
15650x820efff8,
15660x48000001,
15670x0005005a,
15680x3a8efff8,
15690x10940321,
15700x48000000,
15710x00050058,
15720x0006005b,
15730x280b0008,
15740x108e0301,
15750x41800000,
15760x00050844,
15770x1004b232,
15780x1064222c,
15790x40800000,
15800x00050844,
15810x820efff8,
15820x48000001,
15830x0005005c,
15840x3a8efff8,
15850x10940321,
15860x48000000,
15870x00050058,
15880x0006005d,
15890x280b0008,
15900x108e0301,
15910x41800000,
15920x00050844,
15930x1004b232,
15940x1064222c,
15950x40800000,
15960x00050844,
15970x48000001,
15980x0003000e,
15990x1063222d,
16000x48000000,
16010x00050047,
16020x0006005e,
16030x280b0008,
16040x108e0301,
16050x41800000,
16060x00050844,
16070x1004b232,
16080x1064222c,
16090x40800000,
16100x00050844,
16110x48000001,
16120x0003000f,
16130x1063222d,
16140x48000000,
16150x00050047,
16160x0006005f,
16170x280b0008,
16180x108e0301,
16190x41800000,
16200x00050844,
16210x1004b232,
16220x1064222c,
16230x40800000,
16240x00050844,
16250x00000000,
16260x48000001,
16270x00030010,
16280x1063222d,
16290x48000000,
16300x00050047,
16310x00060060,
16320x280b0008,
16330x108e0301,
16340x41800000,
16350x00050844,
16360x1004b232,
16370x1064222c,
16380x40800000,
16390x00050844,
16400x48000001,
16410x00030011,
16420x1063222d,
16430x48000000,
16440x00050047,
16450x00060061,
16460x280b0008,
16470x108e0301,
16480x41800000,
16490x00050844,
16500x1004b232,
16510x1064222c,
16520x40800000,
16530x00050844,
16540x48000001,
16550x00030012,
16560x1063222d,
16570x48000000,
16580x00050047,
16590x00060062,
16600x280b0008,
16610x108e0301,
16620x41800000,
16630x00050844,
16640x1004b232,
16650x1064222c,
16660x40800000,
16670x00050844,
16680x48000001,
16690x00030013,
16700x1063222d,
16710x48000000,
16720x00050047,
16730x00060063,
16740x280b0008,
16750x108e0301,
16760x41800000,
16770x00050844,
16780x1004b232,
16790x1064222c,
16800x40800000,
16810x00050844,
16820x48000001,
16830x00030014,
16840x1063222d,
16850x48000000,
16860x00050047,
16870x00060064,
16880x00000000,
16890x280b0008,
16900x108e0301,
16910x41800000,
16920x00050844,
16930x1004b232,
16940x1064222c,
16950x40800000,
16960x00050844,
16970x48000001,
16980x00030015,
16990x1063222d,
17000x48000000,
17010x00050047,
17020x00060065,
17030x280b0008,
17040x108e0301,
17050x41800000,
17060x00050844,
17070x1004b232,
17080x1064222c,
17090x40800000,
17100x00050844,
17110x48000001,
17120x00030016,
17130x1063222d,
17140x48000000,
17150x00050047,
17160x00060066,
17170x280b0008,
17180x108e0301,
17190x41800000,
17200x00050844,
17210x1004b232,
17220x1064222c,
17230x40800000,
17240x00050844,
17250x48000001,
17260x00030017,
17270x1063222d,
17280x48000000,
17290x00050047,
17300x00060067,
17310x280b0008,
17320x108e0301,
17330x41800000,
17340x00050844,
17350x1004b232,
17360x1064222c,
17370x40800000,
17380x00050844,
17390x48000001,
17400x00030018,
17410x1063222d,
17420x48000000,
17430x00050047,
17440x00060068,
17450x280b0008,
17460x108e0301,
17470x41800000,
17480x00050844,
17490x1004b232,
17500x1064222c,
17510x40800000,
17520x00050844,
17530x00000000,
17540x48000001,
17550x00030019,
17560x1063222d,
17570x48000000,
17580x00050047,
17590x00060069,
17600x280b0008,
17610x108e0301,
17620x41800000,
17630x00050844,
17640x1004b232,
17650x1064222c,
17660x40800000,
17670x00050844,
17680x48000001,
17690x0003001a,
17700x1063222d,
17710x48000000,
17720x00050047,
17730x0006006a,
17740x280b0010,
17750x108e0301,
17760x10ce0b01,
17770x41800000,
17780x00050844,
17790x1066222c,
17800x1003b232,
17810x10a6322c,
17820x40830000,
17830x00050844,
17840x48000001,
17850x0003001b,
17860x1063222d,
17870x48000000,
17880x00050047,
17890x0006006b,
17900x280b0010,
17910x108e0301,
17920x10ce0b01,
17930x41800000,
17940x00050844,
17950x1066222c,
17960x1003b232,
17970x10a6322c,
17980x40830000,
17990x00050844,
18000x48000001,
18010x0003001c,
18020x1063222d,
18030x48000000,
18040x00050047,
18050x0006006c,
18060x280b0010,
18070x108e0301,
18080x10ce0b01,
18090x41800000,
18100x00050844,
18110x1066222c,
18120x1003b232,
18130x10a6322c,
18140x40830000,
18150x00050844,
18160x48000001,
18170x0003001d,
18180x1063222d,
18190x48000000,
18200x00050047,
18210x0006006d,
18220x0006006e,
18230x00000000,
18240x280b0008,
18250x106e0301,
18260x41800000,
18270x00050844,
18280x1003b232,
18290x40800000,
18300x00050844,
18310x108a0301,
18320x00090cab,
18330x106322e8,
18340x48000000,
18350x00050047,
18360x0006006f,
18370x280b0010,
18380x108e0301,
18390x10ce0b01,
18400x41800000,
18410x00050844,
18420x1066222c,
18430x1003b232,
18440x40830000,
18450x00050844,
18460x10a032f5,
18470x48000001,
18480x0003001e,
18490x1063222d,
18500x48000000,
18510x00050047,
18520x00060070,
18530x280b0008,
18540x108e0301,
18550x41800000,
18560x00050844,
18570x1004b232,
18580x1064222c,
18590x40800000,
18600x00050844,
18610x38b10000,
18620x00098200,
18630x820efff8,
18640x48000001,
18650x0003001f,
18660x81110000,
18670x00098200,
18680x1063222d,
18690x108042f1,
18700x3a8efff8,
18710x10740321,
18720x39800000,
18730x00098200,
18740x10940b21,
18750x48000000,
18760x00050045,
18770x00060071,
18780x280b0008,
18790x108e0301,
18800x41800000,
18810x00050844,
18820x1004b232,
18830x1064222c,
18840x40800000,
18850x00050844,
18860x38aefff8,
18870x820efff8,
18880x48000001,
18890x00030020,
18900x1063222d,
18910x3a8efff8,
18920x106e0321,
18930x39800000,
18940x00098200,
18950x00000000,
18960x48000000,
18970x00050045,
18980x00060072,
18990x280b0008,
19000x106e0301,
19010x41800000,
19020x00050844,
19030x1003b232,
19040x39000008,
19050x40800000,
19060x00050844,
19070x0006000b,
19080x108e4300,
19090x7c885840,
19100x1004b232,
19110x40840000,
19120x00050847,
19130x40800000,
19140x00050844,
19150x10041afd,
19160x39080008,
19170x4c010b82,
19180x10641a78,
19190x48000000,
19200x0005000b,
19210x00060073,
19220x280b0008,
19230x106e0301,
19240x41800000,
19250x00050844,
19260x1003b232,
19270x39000008,
19280x40800000,
19290x00050844,
19300x0006000b,
19310x108e4300,
19320x7c885840,
19330x1004b232,
19340x40840000,
19350x00050847,
19360x40800000,
19370x00050844,
19380x10041afc,
19390x39080008,
19400x4c010b82,
19410x10641a78,
19420x48000000,
19430x0005000b,
19440x00060074,
19450x280b0008,
19460x106e0301,
19470x41800000,
19480x00050844,
19490x1003ba34,
19500x40800000,
19510x00050844,
19520x80030000,
19530x00098200,
19540x106002f1,
19550x48000000,
19560x00050047,
19570x00060075,
19580x280b0008,
19590x106e0301,
19600x40820000,
19610x00050844,
19620x00000000,
19630x1003ba34,
19640x3a8efff8,
19650x40800000,
19660x00050844,
19670x80030000,
19680x00098200,
19690x39800000,
19700x00098200,
19710x89030000,
19720x00098200,
19730x39200000,
19740x00098200,
19750x28000000,
19760x820efff8,
19770x106042f1,
19780x7d8c489e,
19790x10740321,
19800x48000000,
19810x00050045,
19820x00060076,
19830x80110000,
19840x00098200,
19850x81110000,
19860x00098200,
19870x7c004040,
19880x40800001,
19890x0005084d,
19900x280b0008,
19910x106e0301,
19920x40820000,
19930x00050844,
19940x1003b232,
19950x38910000,
19960x00098200,
19970x40800000,
19980x00050844,
19990x10001afa,
20000x38a00001,
20010x280000ff,
20020x98040000,
20030x41810000,
20040x00050844,
20050x00060077,
20060x7e439378,
20070x91d20000,
20080x00098200,
20090x9201000c,
20100x48000001,
20110x00030021,
20120x81d20000,
20130x00098200,
20140x10771a2d,
20150x48000000,
20160x00050047,
20170x00060078,
20180x80110000,
20190x00098200,
20200x81110000,
20210x00098200,
20220x00000000,
20230x7c004040,
20240x40800001,
20250x0005084d,
20260x280b0010,
20270x10ae1301,
20280x106e0301,
20290x41800000,
20300x00050844,
20310x108e0b01,
20320x3920ffff,
20330x41820000,
20340x00050801,
20350x1005b232,
20360x40800000,
20370x00050844,
20380x11202afa,
20390x0006000b,
20400x1004b232,
20410x40800000,
20420x00050844,
20430x1003ba34,
20440x110022fa,
20450x40800000,
20460x00050844,
20470x80030000,
20480x00098200,
20490x7c004840,
20500x7cc90214,
20510x41800000,
20520x00050805,
20530x0006000c,
20540x2c080000,
20550x7cc80214,
20560x40810000,
20570x00050807,
20580x0006000d,
20590x7ca84851,
20600x38830000,
20610x00098200,
20620x38a50001,
20630x7c844214,
20640x7ca0281e,
20650x48000000,
20660x00050077,
20670x0006000f,
20680x7c004800,
20690x38c60001,
20700x7d26005e,
20710x48000000,
20720x0005000c,
20730x00060011,
20740x2c860000,
20750x7d00309e,
20760x7d00411e,
20770x39080001,
20780x48000000,
20790x0005000d,
20800x00060079,
20810x80110000,
20820x00098200,
20830x81110000,
20840x00098200,
20850x7c004040,
20860x40800001,
20870x0005084d,
20880x00000000,
20890x280b0010,
20900x106e0301,
20910x108e0b01,
20920x41800000,
20930x00050844,
20940x1004b232,
20950x40800000,
20960x00050844,
20970x1003ba34,
20980x10a022fa,
20990x40800000,
21000x00050844,
21010x80030000,
21020x00098200,
21030x2c050000,
21040x81110000,
21050x00098200,
21060x40810000,
21070x00050802,
21080x28000001,
21090x3925ffff,
21100x41800000,
21110x00050802,
21120x7c882840,
21130x40820000,
21140x00050844,
21150x88030000,
21160x00098200,
21170x80910000,
21180x00098200,
21190x41840000,
21200x00050844,
21210x0006000b,
21220x28090000,
21230x7c0449ae,
21240x3929ffff,
21250x40820000,
21260x0005080b,
21270x48000000,
21280x00050077,
21290x0006000c,
21300x38710000,
21310x00098200,
21320x10771a2d,
21330x48000000,
21340x00050047,
21350x0006007a,
21360x80110000,
21370x00098200,
21380x81110000,
21390x00098200,
21400x7c004040,
21410x40800001,
21420x0005084d,
21430x280b0008,
21440x106e0301,
21450x41800000,
21460x00050844,
21470x00000000,
21480x1003ba34,
21490x81110000,
21500x00098200,
21510x40800000,
21520x00050844,
21530x80a30000,
21540x00098200,
21550x38630000,
21560x00098200,
21570x80910000,
21580x00098200,
21590x39200000,
21600x7c082840,
21610x38c5ffff,
21620x41800000,
21630x00050844,
21640x0006000b,
21650x2c060000,
21660x7d0348ae,
21670x41800000,
21680x00050877,
21690x7d0431ae,
21700x38c6ffff,
21710x39290001,
21720x48000000,
21730x0005000b,
21740x0006007b,
21750x80110000,
21760x00098200,
21770x81110000,
21780x00098200,
21790x7c004040,
21800x40800001,
21810x0005084d,
21820x280b0008,
21830x106e0301,
21840x41800000,
21850x00050844,
21860x1003ba34,
21870x81110000,
21880x00098200,
21890x40800000,
21900x00050844,
21910x80a30000,
21920x00098200,
21930x38630000,
21940x00098200,
21950x80910000,
21960x00098200,
21970x7c082840,
21980x39200000,
21990x41800000,
22000x00050844,
22010x0006000b,
22020x7c092840,
22030x7d0348ae,
22040x40800000,
22050x00050877,
22060x00000000,
22070x3808ffbf,
22080x69060020,
22090x2800001a,
22100x7d06401e,
22110x7d0449ae,
22120x39290001,
22130x48000000,
22140x0005000b,
22150x0006007c,
22160x80110000,
22170x00098200,
22180x81110000,
22190x00098200,
22200x7c004040,
22210x40800001,
22220x0005084d,
22230x280b0008,
22240x106e0301,
22250x41800000,
22260x00050844,
22270x1003ba34,
22280x81110000,
22290x00098200,
22300x40800000,
22310x00050844,
22320x80a30000,
22330x00098200,
22340x38630000,
22350x00098200,
22360x80910000,
22370x00098200,
22380x7c082840,
22390x39200000,
22400x41800000,
22410x00050844,
22420x0006000b,
22430x7c092840,
22440x7d0348ae,
22450x40800000,
22460x00050877,
22470x3808ff9f,
22480x69060020,
22490x2800001a,
22500x7d06401e,
22510x7d0449ae,
22520x39290001,
22530x48000000,
22540x0005000b,
22550x0006007d,
22560x280b0008,
22570x106e0301,
22580x41800000,
22590x00050844,
22600x1003c234,
22610x40800000,
22620x00050844,
22630x48000001,
22640x00030022,
22650x10601af1,
22660x48000000,
22670x00050047,
22680x0006007e,
22690x280b0008,
22700x106e0301,
22710x41800000,
22720x00050844,
22730x00000000,
22740x1003b232,
22750x40800000,
22760x00050844,
22770x1063dae0,
22780x0006007f,
22790x10601af1,
22800x48000000,
22810x00050047,
22820x00060080,
22830x280b0008,
22840x106e0301,
22850x41800000,
22860x00050844,
22870x1003b232,
22880x40800000,
22890x00050844,
22900x1063dae0,
22910x39000008,
22920x0006000b,
22930x108e4300,
22940x7c885840,
22950x1004b232,
22960x40840000,
22970x0005087f,
22980x40800000,
22990x00050844,
23000x1084dae0,
23010x7c632038,
23020x39080008,
23030x48000000,
23040x0005000b,
23050x00060081,
23060x280b0008,
23070x106e0301,
23080x41800000,
23090x00050844,
23100x1003b232,
23110x40800000,
23120x00050844,
23130x1063dae0,
23140x39000008,
23150x0006000b,
23160x108e4300,
23170x7c885840,
23180x1004b232,
23190x40840000,
23200x0005087f,
23210x40800000,
23220x00050844,
23230x1084dae0,
23240x7c632378,
23250x39080008,
23260x48000000,
23270x0005000b,
23280x00060082,
23290x280b0008,
23300x106e0301,
23310x41800000,
23320x00050844,
23330x1003b232,
23340x40800000,
23350x00050844,
23360x1063dae0,
23370x39000008,
23380x0006000b,
23390x108e4300,
23400x7c885840,
23410x1004b232,
23420x40840000,
23430x0005087f,
23440x00000000,
23450x40800000,
23460x00050844,
23470x1084dae0,
23480x7c632278,
23490x39080008,
23500x48000000,
23510x0005000b,
23520x00060083,
23530x280b0008,
23540x106e0301,
23550x41800000,
23560x00050844,
23570x1003b232,
23580x40800000,
23590x00050844,
23600x1063dae0,
23610x5460403e,
23620x5060c00e,
23630x5060c42e,
23640x106002f1,
23650x48000000,
23660x00050047,
23670x00060084,
23680x280b0008,
23690x106e0301,
23700x41800000,
23710x00050844,
23720x1003b232,
23730x40800000,
23740x00050844,
23750x1063dae0,
23760x7c6018f8,
23770x106002f1,
23780x48000000,
23790x00050047,
23800x00060085,
23810x280b0010,
23820x106e0301,
23830x108e0b01,
23840x41800000,
23850x00050844,
23860x1003222c,
23870x1000b232,
23880x40830000,
23890x00050844,
23900x1084dae0,
23910x1063dae0,
23920x548406fe,
23930x7c602030,
23940x106002f1,
23950x48000000,
23960x00050047,
23970x00060086,
23980x280b0010,
23990x106e0301,
24000x108e0b01,
24010x41800000,
24020x00050844,
24030x1003222c,
24040x1000b232,
24050x40830000,
24060x00050844,
24070x1084dae0,
24080x1063dae0,
24090x548406fe,
24100x7c602430,
24110x106002f1,
24120x48000000,
24130x00050047,
24140x00060087,
24150x280b0010,
24160x106e0301,
24170x108e0b01,
24180x41800000,
24190x00050844,
24200x1003222c,
24210x1000b232,
24220x40830000,
24230x00050844,
24240x1084dae0,
24250x1063dae0,
24260x548406fe,
24270x7c602630,
24280x106002f1,
24290x48000000,
24300x00050047,
24310x00060088,
24320x00000000,
24330x280b0010,
24340x106e0301,
24350x108e0b01,
24360x41800000,
24370x00050844,
24380x1003222c,
24390x1000b232,
24400x40830000,
24410x00050844,
24420x1084dae0,
24430x1063dae0,
24440x5c60203e,
24450x106002f1,
24460x48000000,
24470x00050047,
24480x00060089,
24490x280b0010,
24500x106e0301,
24510x108e0b01,
24520x41800000,
24530x00050844,
24540x1003222c,
24550x1000b232,
24560x40830000,
24570x00050844,
24580x1084dae0,
24590x1063dae0,
24600x7c8400d0,
24610x5c60203e,
24620x106002f1,
24630x48000000,
24640x00050047,
24650x00060044,
24660x80ca0000,
24670x00098200,
24680x7d0e5a14,
24690x820efff8,
24700x38080000,
24710x00098200,
24720x81320000,
24730x00098200,
24740x9201000c,
24750x7c004840,
24760x91d20000,
24770x00098200,
24780x91120000,
24790x00098200,
24800x7e439378,
24810x41810000,
24820x00050805,
24830x7cc903a6,
24840x4e800421,
24850x81d20000,
24860x00098200,
24870x2c030000,
24880x546c1800,
24890x000900a1,
24900x3a8efff8,
24910x41810000,
24920x00050845,
24930x0006000b,
24940x80120000,
24950x00098200,
24960x814efffc,
24970x7d6e0050,
24980x40820000,
24990x00050828,
25000x820a0000,
25010x00098200,
25020x80f00000,
25030x3a100004,
25040x54e815ba,
25050x54f4dd78,
25060x7c11402e,
25070x7e947214,
25080x7c0903a6,
25090x4e800420,
25100x00060028,
25110x00000000,
25120x72000000,
25130x00090200,
25140x56080038,
25150x40820000,
25160x00050803,
25170x80f0fffc,
25180x54e8dd78,
25190x0006000d,
25200x7d287050,
25210x48000000,
25220x00050024,
25230x0006000f,
25240x38800000,
25250x00098200,
25260x48000001,
25270x00030000,
25280x81d20000,
25290x00098200,
25300x7c000000,
25310x48000000,
25320x0005000b,
25330x0006004d,
25340x7ea802a6,
25350x91d20000,
25360x00098200,
25370x7c0e5a14,
25380x9201000c,
25390x90120000,
25400x00098200,
25410x7e439378,
25420x48000001,
25430x00030023,
25440x81d20000,
25450x00098200,
25460x7ea803a6,
25470x80120000,
25480x00098200,
25490x7d6e0050,
25500x814efffc,
25510x4e800020,
25520x0006008a,
25530x00000000,
25540x7c810808,
25550x00000000,
25560x0006008b,
25570x88d10000,
25580x00098200,
25590x70c00000,
25600x00090200,
25610x41820000,
25620x00050801,
25630x0006000f,
25640x39080000,
25650x00098200,
25660x7c11402e,
25670x7c0903a6,
25680x4e800420,
25690x0006008c,
25700x88d10000,
25710x00098200,
25720x81310000,
25730x00098200,
25740x70c00000,
25750x00090200,
25760x54c007c0,
25770x000900ab,
25780x40820000,
25790x0005080f,
25800x2c800000,
25810x3529ffff,
25820x41860000,
25830x0005080f,
25840x91310000,
25850x00098200,
25860x41820000,
25870x00050801,
25880x40840000,
25890x0005080f,
25900x0006000b,
25910x7e439378,
25920x92610008,
25930x7e048378,
25940x91d20000,
25950x00098200,
25960x48000001,
25970x00030024,
25980x0006000d,
25990x81d20000,
26000x00098200,
26010x0006000e,
26020x00000000,
26030x80f0fffc,
26040x54e815ba,
26050x54ea5d78,
26060x39080000,
26070x00098200,
26080x54ec9b78,
26090x7c11402e,
26100x54f4dd78,
26110x54eb9d78,
26120x7c0903a6,
26130x4e800420,
26140x0006008d,
26150x3a100004,
26160x826affec,
26170x48000000,
26180x0005000e,
26190x0006008e,
26200x00000000,
26210x7c810808,
26220x00000000,
26230x0006008f,
26240x7e048378,
26250x00000000,
26260x48000000,
26270x00050001,
26280x00000000,
26290x00060090,
26300x00000000,
26310x62040001,
26320x0006000b,
26330x00000000,
26340x7c0e5a14,
26350x9201000c,
26360x7e439378,
26370x91d20000,
26380x00098200,
26390x7e8ea050,
26400x90120000,
26410x00098200,
26420x48000001,
26430x00030025,
26440x81d20000,
26450x00098200,
26460x80120000,
26470x00098200,
26480x9361000c,
26490x7d6e0050,
26500x7e8ea214,
26510x814efffc,
26520x7c6903a6,
26530x4e800420,
26540x00060091,
26550x00000000,
26560x7c810808,
26570x00000000,
26580x00060092,
26590x00000000,
26600x7c810808,
26610x00000000,
26620x00060093,
26630x7ca802a6,
26640x48000001,
26650x0005005a,
26660x7ca803a6,
26670x1064222c,
26680x4e800020,
26690x00060094,
26700x1064222c,
26710x0006005a,
26720x5469657e,
26730x3529fc01,
26740x3900ffff,
26750x28890033,
26760x20090034,
26770x41850000,
26780x00050801,
26790x3cc0fff0,
26800x7d000030,
26810x7cc84e30,
26820x7c890078,
26830x7c664078,
26840x7d293378,
26850x7c66fe70,
26860x7d293039,
26870x7c840038,
26880x7c634038,
26890x7c002010,
26900x7c04009e,
26910x7d081910,
26920x7d03409e,
26930x1088022d,
26940x4e800020,
26950x0006000b,
26960x4d810020,
26970x5469007e,
26980x7c60fe70,
26990x7d292378,
27000x3d003ff0,
27010x7d290039,
27020x38000000,
27030x7d00409e,
27040x5103007e,
27050x1083022d,
27060x4e800020,
27070x00060095,
27080x1064222c,
27090x0006005c,
27100x5469657e,
27110x3529fc01,
27120x3900ffff,
27130x28890033,
27140x20090034,
27150x41850000,
27160x00050801,
27170x3cc0fff0,
27180x7d000030,
27190x7cc84e30,
27200x7c890078,
27210x7c664078,
27220x7d293378,
27230x7c66fe70,
27240x7d293079,
27250x7c840038,
27260x7c634038,
27270x7c002010,
27280x7c04009e,
27290x7d081910,
27300x7d03409e,
27310x1088022d,
27320x4e800020,
27330x0006000b,
27340x4d810020,
27350x5469007e,
27360x7c60fe70,
27370x7d292378,
27380x3d003ff0,
27390x7d290079,
27400x38000000,
27410x7d00409e,
27420x5103007e,
27430x1083022d,
27440x4e800020,
27450x00000000,
27460x00060096,
27470x1064222c,
27480x00060097,
27490x5469657e,
27500x3529fc01,
27510x3900ffff,
27520x28890033,
27530x20090034,
27540x41850000,
27550x00050801,
27560x3cc0fff0,
27570x7d000030,
27580x7cc84e30,
27590x1008022d,
27600x10840211,
27610x4e800020,
27620x0006000b,
27630x4d810020,
27640x54680000,
27650x38000000,
27660x1088022d,
27670x4e800020,
27680x00000000,
27690x00060096,
27700x00060097,
27710x00000000,
27720x00060098,
27730x1083222d,
27740x28070001,
27750x10c5322d,
27760x41820000,
27770x00050801,
27780x41810000,
27790x00050802,
27800x108432e0,
27810x1064222c,
27820x4e800020,
27830x0006000b,
27840x108432e1,
27850x1064222c,
27860x4e800020,
27870x0006000c,
27880x28070003,
27890x41820000,
27900x00050801,
27910x41810000,
27920x00050802,
27930x108432e8,
27940x1064222c,
27950x4e800020,
27960x0006000b,
27970x108432e9,
27980x1064222c,
27990x4e800020,
28000x0006000c,
28010x28070005,
28020x41820000,
28030x00050801,
28040x41810000,
28050x00050802,
28060x10a42217,
28070x108432e9,
28080x11463217,
28090x7d6802a6,
28100x48000001,
28110x00050094,
28120x7d6803a6,
28130x108452e8,
28140x108522e1,
28150x1064222c,
28160x4e800020,
28170x0006000b,
28180x48000000,
28190x0003001b,
28200x0006000c,
28210x28070007,
28220x41820000,
28230x00050801,
28240x41810000,
28250x00050802,
28260x6c638000,
28270x4e800020,
28280x0006000b,
28290x5463007e,
28300x4e800020,
28310x0006000c,
28320x7c810808,
28330x00060099,
28340x00000000,
28350x7c810808,
28360x00000000,
28370x00080000,
28380x00000000,
28390x100ea300,
28400x3a100004,
28410x110e6300,
28420x3cd00000,
28430x00098200,
28440x8130fffc,
28450x1140422c,
28460x552993ba,
28470x100ab232,
28480x7d293214,
28490x40830000,
28500x00050834,
28510x100042ed,
28520x00000000,
28530x108042ee,
28540x4c212b82,
28550x00000000,
28560x7e09805e,
28570x00000000,
28580x7e10485e,
28590x00000000,
28600x80f00000,
28610x3a100004,
28620x54e815ba,
28630x54ea5d78,
28640x54ec9b78,
28650x7c11402e,
28660x54f4dd78,
28670x54eb9d78,
28680x7c0903a6,
28690x4e800420,
28700x00000000,
28710x108ea300,
28720x3a100004,
28730x10ae6300,
28740x3cd00000,
28750x00098200,
28760x8130fffc,
28770x11442a2c,
28780x552993ba,
28790x100ab232,
28800x7d293214,
28810x40830000,
28820x00050805,
28830x10042aee,
28840x00000000,
28850x7e09805e,
28860x00000000,
28870x7e10485e,
28880x00000000,
28890x0006000b,
28900x80f00000,
28910x3a100004,
28920x54e815ba,
28930x54ea5d78,
28940x54ec9b78,
28950x7c11402e,
28960x54f4dd78,
28970x54eb9d78,
28980x7c0903a6,
28990x4e800420,
29000x0006000f,
29010x10042a34,
29020x7d4650f8,
29030x28860000,
29040x00090200,
29050x4f830342,
29060x2b060000,
29070x00090200,
29080x4fa02902,
29090x7e158378,
29100x00000000,
29110x7e09875e,
29120x00000000,
29130x7d304f5e,
29140x00000000,
29150x4f9ceb82,
29160x00000000,
29170x7e0980de,
29180x00000000,
29190x7e1048de,
29200x00000000,
29210x419c0000,
29220x0005080b,
29230x41980000,
29240x0005080b,
29250x81240000,
29260x00098200,
29270x38c00000,
29280x00098200,
29290x28090000,
29300x41820000,
29310x0005080b,
29320x89290000,
29330x00098200,
29340x71290000,
29350x00090200,
29360x40820000,
29370x0005080b,
29380x7eb0ab78,
29390x48000000,
29400x00050039,
29410x00000000,
29420x100ea300,
29430x558c007e,
29440x000900ab,
29450x80f00000,
29460x218cfffc,
29470x3a100004,
29480x7d0f602e,
29490x3cd00000,
29500x00098200,
29510x54e993ba,
29520x1117422d,
29530x7d293214,
29540x10004234,
29550x00000000,
29560x7e0980de,
29570x00000000,
29580x7e1048de,
29590x00000000,
29600x80f00000,
29610x3a100004,
29620x54e815ba,
29630x54ea5d78,
29640x54ec9b78,
29650x7c11402e,
29660x54f4dd78,
29670x54eb9d78,
29680x7c0903a6,
29690x4e800420,
29700x00000000,
29710x100ea300,
29720x3a100004,
29730x110f6300,
29740x3cd00000,
29750x00098200,
29760x80f0fffc,
29770x1000b232,
29780x40800000,
29790x00050805,
29800x100042ee,
29810x0006000b,
29820x54e993ba,
29830x7d293214,
29840x00000000,
29850x7e09805e,
29860x0006000f,
29870x00000000,
29880x7e10485e,
29890x00000000,
29900x0006000d,
29910x80f00000,
29920x3a100004,
29930x54e815ba,
29940x54ea5d78,
29950x54ec9b78,
29960x7c11402e,
29970x54f4dd78,
29980x54eb9d78,
29990x7c0903a6,
30000x4e800420,
30010x00000000,
30020x0006000f,
30030x54e993ba,
30040x7e093214,
30050x48000000,
30060x0005000d,
30070x00000000,
30080x7c0ea02e,
30090x558800fe,
30100x000900ab,
30110x80f00000,
30120x3a100004,
30130x7d0840f8,
30140x3cd00000,
30150x00098200,
30160x7c004040,
30170x54e993ba,
30180x7d293214,
30190x00000000,
30200x7e09809e,
30210x00000000,
30220x7e10489e,
30230x00000000,
30240x80f00000,
30250x3a100004,
30260x54e815ba,
30270x54ea5d78,
30280x54ec9b78,
30290x7c11402e,
30300x54f4dd78,
30310x54eb9d78,
30320x7c0903a6,
30330x4e800420,
30340x00000000,
30350x100e6300,
30360x111ad200,
30370x80f00000,
30380x10004232,
30390x3a100004,
30400x00000000,
30410x3cd00000,
30420x00098200,
30430x54e993ba,
30440x7d293214,
30450x00000000,
30460x7e09801e,
30470x00000000,
30480x7e10481e,
30490x00000000,
30500x40800000,
30510x00050801,
30520x00000000,
30530x41800000,
30540x00050801,
30550x00000000,
30560x3e100000,
30570x00098200,
30580x54e993ba,
30590x100ea320,
30600x7e104a14,
30610x0006000b,
30620x00000000,
30630x80f00000,
30640x3a100004,
30650x54e815ba,
30660x54ea5d78,
30670x54ec9b78,
30680x7c11402e,
30690x54f4dd78,
30700x54eb9d78,
30710x7c0903a6,
30720x4e800420,
30730x00000000,
30740x80f00000,
30750x3a100004,
30760x100e6300,
30770x100ea320,
30780x54e815ba,
30790x54ea5d78,
30800x54ec9b78,
30810x7c11402e,
30820x54f4dd78,
30830x54eb9d78,
30840x7c0903a6,
30850x4e800420,
30860x00000000,
30870x80f00000,
30880x3a100004,
30890x7c0e602e,
30900x21000000,
30910x00098200,
30920x7c004114,
30930x7c0ea12e,
30940x54e815ba,
30950x54ea5d78,
30960x54ec9b78,
30970x7c11402e,
30980x54f4dd78,
30990x54eb9d78,
31000x7c0903a6,
31010x4e800420,
31020x00000000,
31030x100e6300,
31040x1000b232,
31050x40800000,
31060x0005083c,
31070x100002e6,
31080x80f00000,
31090x3a100004,
31100x100ea320,
31110x54e815ba,
31120x54ea5d78,
31130x54ec9b78,
31140x7c11402e,
31150x54f4dd78,
31160x54eb9d78,
31170x7c0903a6,
31180x4e800420,
31190x00000000,
31200x106e6300,
31210x1003ba34,
31220x40800000,
31230x00050802,
31240x80630000,
31250x00098200,
31260x0006000b,
31270x80f00000,
31280x3a100004,
31290x10001af1,
31300x100ea320,
31310x54e815ba,
31320x54ea5d78,
31330x54ec9b78,
31340x7c11402e,
31350x54f4dd78,
31360x54eb9d78,
31370x7c0903a6,
31380x4e800420,
31390x0006000c,
31400x1003c234,
31410x40800000,
31420x0005083e,
31430x00000000,
31440x81230000,
31450x00098200,
31460x28090000,
31470x40820000,
31480x00050809,
31490x0006000d,
31500x00000000,
31510x0006003f,
31520x48000001,
31530x00030022,
31540x48000000,
31550x0005000b,
31560x00000000,
31570x00060013,
31580x88090000,
31590x00098200,
31600x70000000,
31610x00090200,
31620x40820000,
31630x0005080d,
31640x48000000,
31650x0005003e,
31660x00000000,
31670x100e5300,
31680x1000b232,
31690x110f5b00,
31700x40800000,
31710x0005083a,
31720x00000000,
31730x110e5300,
31740x1008b232,
31750x100f5b00,
31760x40800000,
31770x0005083b,
31780x00000000,
31790x100e5300,
31800x110e5b00,
31810x1120422c,
31820x1009b232,
31830x40830000,
31840x0005083d,
31850x00000000,
31860x80f00000,
31870x3a100004,
31880x100042e0,
31890x100ea320,
31900x54e815ba,
31910x54ea5d78,
31920x54ec9b78,
31930x7c11402e,
31940x54f4dd78,
31950x54eb9d78,
31960x7c0903a6,
31970x4e800420,
31980x00000000,
31990x100e5300,
32000x1000b232,
32010x110f5b00,
32020x40800000,
32030x0005083a,
32040x00000000,
32050x110e5300,
32060x1008b232,
32070x100f5b00,
32080x40800000,
32090x0005083b,
32100x00000000,
32110x100e5300,
32120x110e5b00,
32130x1120422c,
32140x1009b232,
32150x40830000,
32160x0005083d,
32170x00000000,
32180x80f00000,
32190x3a100004,
32200x100042e1,
32210x100ea320,
32220x54e815ba,
32230x54ea5d78,
32240x54ec9b78,
32250x7c11402e,
32260x54f4dd78,
32270x54eb9d78,
32280x7c0903a6,
32290x4e800420,
32300x00000000,
32310x100e5300,
32320x1000b232,
32330x110f5b00,
32340x40800000,
32350x0005083a,
32360x00000000,
32370x110e5300,
32380x1008b232,
32390x100f5b00,
32400x40800000,
32410x0005083b,
32420x00000000,
32430x100e5300,
32440x110e5b00,
32450x1120422c,
32460x1009b232,
32470x40830000,
32480x0005083d,
32490x00000000,
32500x80f00000,
32510x3a100004,
32520x100042e8,
32530x100ea320,
32540x54e815ba,
32550x54ea5d78,
32560x54ec9b78,
32570x7c11402e,
32580x54f4dd78,
32590x54eb9d78,
32600x7c0903a6,
32610x4e800420,
32620x00000000,
32630x100e5300,
32640x1000b232,
32650x110f5b00,
32660x40800000,
32670x0005083a,
32680x00000000,
32690x110e5300,
32700x1008b232,
32710x100f5b00,
32720x40800000,
32730x0005083b,
32740x00000000,
32750x100e5300,
32760x110e5b00,
32770x1120422c,
32780x1009b232,
32790x40830000,
32800x0005083d,
32810x00000000,
32820x80f00000,
32830x3a100004,
32840x100042e9,
32850x100ea320,
32860x54e815ba,
32870x54ea5d78,
32880x54ec9b78,
32890x7c11402e,
32900x54f4dd78,
32910x54eb9d78,
32920x7c0903a6,
32930x4e800420,
32940x00000000,
32950x118e5300,
32960x100cb232,
32970x12af5b00,
32980x40800000,
32990x0005083a,
33000x00000000,
33010x12ae5300,
33020x1015b232,
33030x118f5b00,
33040x40800000,
33050x0005083b,
33060x00000000,
33070x118e5300,
33080x12ae5b00,
33090x112caa2c,
33100x1009b232,
33110x40830000,
33120x0005083d,
33130x00000000,
33140x0006009a,
33150x108caae9,
33160x48000001,
33170x00050094,
33180x1004aae8,
33190x80f00000,
33200x3a100004,
33210x100c02e1,
33220x100ea320,
33230x54e815ba,
33240x54ea5d78,
33250x54ec9b78,
33260x7c11402e,
33270x54f4dd78,
33280x54eb9d78,
33290x7c0903a6,
33300x4e800420,
33310x00000000,
33320x118e5300,
33330x100cb232,
33340x12af5b00,
33350x40800000,
33360x0005083a,
33370x00000000,
33380x12ae5300,
33390x1015b232,
33400x118f5b00,
33410x40800000,
33420x0005083b,
33430x00000000,
33440x118e5300,
33450x12ae5b00,
33460x112caa2c,
33470x1009b232,
33480x40830000,
33490x0005083d,
33500x00000000,
33510x48000000,
33520x0005009a,
33530x00000000,
33540x108e5300,
33550x10ce5b00,
33560x1066222c,
33570x1003b232,
33580x10a6322c,
33590x40830000,
33600x0005083d,
33610x48000001,
33620x0003001b,
33630x1083222d,
33640x108ea320,
33650x80f00000,
33660x3a100004,
33670x54e815ba,
33680x54ea5d78,
33690x54ec9b78,
33700x7c11402e,
33710x54f4dd78,
33720x54eb9d78,
33730x7c0903a6,
33740x4e800420,
33750x00000000,
33760x7caa5850,
33770x91d20000,
33780x00098200,
33790x7c8e5a14,
33800x7d555378,
33810x0006002a,
33820x9201000c,
33830x7e439378,
33840x54a500fe,
33850x000900ab,
33860x48000001,
33870x00030026,
33880x28030000,
33890x81d20000,
33900x00098200,
33910x40820000,
33920x00050835,
33930x100eab00,
33940x100ea320,
33950x80f00000,
33960x3a100004,
33970x54e815ba,
33980x54ea5d78,
33990x54ec9b78,
34000x7c11402e,
34010x54f4dd78,
34020x54eb9d78,
34030x7c0903a6,
34040x4e800420,
34050x00000000,
34060x80f00000,
34070x3a100004,
34080x5588007e,
34090x000900ab,
34100x2108fffc,
34110x7c0f402e,
34120x1017022d,
34130x100ea320,
34140x54e815ba,
34150x54ea5d78,
34160x54ec9b78,
34170x7c11402e,
34180x54f4dd78,
34190x54eb9d78,
34200x7c0903a6,
34210x4e800420,
34220x00000000,
34230x80f00000,
34240x3a100004,
34250x5588007e,
34260x000900ab,
34270x2108fffc,
34280x7c0f402e,
34290x39200000,
34300x00098200,
34310x1009022d,
34320x100ea320,
34330x54e815ba,
34340x54ea5d78,
34350x54ec9b78,
34360x7c11402e,
34370x54f4dd78,
34380x54eb9d78,
34390x7c0903a6,
34400x4e800420,
34410x00000000,
34420x558800fe,
34430x000900ab,
34440x7d080734,
34450x80f00000,
34460x3a100004,
34470x100042f1,
34480x100ea320,
34490x54e815ba,
34500x54ea5d78,
34510x54ec9b78,
34520x7c11402e,
34530x54f4dd78,
34540x54eb9d78,
34550x7c0903a6,
34560x4e800420,
34570x00000000,
34580x100f6300,
34590x80f00000,
34600x3a100004,
34610x100ea320,
34620x54e815ba,
34630x54ea5d78,
34640x54ec9b78,
34650x7c11402e,
34660x54f4dd78,
34670x54eb9d78,
34680x7c0903a6,
34690x4e800420,
34700x00000000,
34710x558800fe,
34720x000900ab,
34730x7d0040f8,
34740x80f00000,
34750x3a100004,
34760x7c0ea12e,
34770x54e815ba,
34780x54ea5d78,
34790x54ec9b78,
34800x7c11402e,
34810x54f4dd78,
34820x54eb9d78,
34830x7c0903a6,
34840x4e800420,
34850x00000000,
34860x134ea320,
34870x3a940008,
34880x0006000b,
34890x134ea320,
34900x7c146000,
34910x3a940008,
34920x41800000,
34930x0005080b,
34940x80f00000,
34950x3a100004,
34960x54e815ba,
34970x54ea5d78,
34980x54ec9b78,
34990x7c11402e,
35000x54f4dd78,
35010x54eb9d78,
35020x7c0903a6,
35030x4e800420,
35040x00000000,
35050x80f00000,
35060x3a100004,
35070x814efffc,
35080x558c007e,
35090x000900ab,
35100x398c0000,
35110x00098200,
35120x7d4a602e,
35130x810a0000,
35140x00098200,
35150x10080301,
35160x100ea320,
35170x54e815ba,
35180x54ea5d78,
35190x54ec9b78,
35200x7c11402e,
35210x54f4dd78,
35220x54eb9d78,
35230x7c0903a6,
35240x4e800420,
35250x00000000,
35260x814efffc,
35270x5694007e,
35280x000900ab,
35290x3a940000,
35300x00098200,
35310x110e6300,
35320x7d4aa02e,
35330x88ca0000,
35340x00098200,
35350x808a0000,
35360x00098200,
35370x70c60000,
35380x00090200,
35390x880a0000,
35400x00098200,
35410x1128422c,
35420x11040321,
35430x28800000,
35440x4c423382,
35450x39290000,
35460x00098200,
35470x40820000,
35480x00050802,
35490x0006000b,
35500x80f00000,
35510x3a100004,
35520x54e815ba,
35530x54ea5d78,
35540x54ec9b78,
35550x7c11402e,
35560x54f4dd78,
35570x54eb9d78,
35580x7c0903a6,
35590x4e800420,
35600x0006000c,
35610x28090000,
35620x00090200,
35630x40800000,
35640x0005080b,
35650x88c80000,
35660x00098200,
35670x70c60000,
35680x00090200,
35690x38710000,
35700x00098200,
35710x41820000,
35720x0005080b,
35730x48000001,
35740x00030027,
35750x48000000,
35760x0005000b,
35770x00000000,
35780x814efffc,
35790x5588007e,
35800x000900ab,
35810x5694007e,
35820x000900ab,
35830x2108fffc,
35840x3a940000,
35850x00098200,
35860x7d0f402e,
35870x7d4aa02e,
35880x1117422d,
35890x88ca0000,
35900x00098200,
35910x808a0000,
35920x00098200,
35930x70c60000,
35940x00090200,
35950x88c80000,
35960x00098200,
35970x892a0000,
35980x00098200,
35990x11040321,
36000x40820000,
36010x00050802,
36020x0006000b,
36030x80f00000,
36040x3a100004,
36050x54e815ba,
36060x54ea5d78,
36070x54ec9b78,
36080x7c11402e,
36090x54f4dd78,
36100x54eb9d78,
36110x7c0903a6,
36120x4e800420,
36130x0006000c,
36140x70c60000,
36150x00090200,
36160x28890000,
36170x4c423382,
36180x38710000,
36190x00098200,
36200x41820000,
36210x0005080b,
36220x48000001,
36230x00030027,
36240x48000000,
36250x0005000b,
36260x00000000,
36270x80f00000,
36280x3a100004,
36290x814efffc,
36300x5694007e,
36310x000900ab,
36320x3a940000,
36330x00098200,
36340x100f6300,
36350x7d4aa02e,
36360x810a0000,
36370x00098200,
36380x10080321,
36390x54e815ba,
36400x54ea5d78,
36410x54ec9b78,
36420x7c11402e,
36430x54f4dd78,
36440x54eb9d78,
36450x7c0903a6,
36460x4e800420,
36470x00000000,
36480x80f00000,
36490x3a100004,
36500x814efffc,
36510x5694007e,
36520x000900ab,
36530x3a940000,
36540x00098200,
36550x558000fe,
36560x000900ab,
36570x7d4aa02e,
36580x7c0000f8,
36590x810a0000,
36600x00098200,
36610x90080000,
36620x54e815ba,
36630x54ea5d78,
36640x54ec9b78,
36650x7c11402e,
36660x54f4dd78,
36670x54eb9d78,
36680x7c0903a6,
36690x4e800420,
36700x00000000,
36710x81120000,
36720x00098200,
36730x5580007e,
36740x000900ab,
36750x7e100214,
36760x3e100000,
36770x00098200,
36780x91d20000,
36790x00098200,
36800x28080000,
36810x7e439378,
36820x41820000,
36830x00050801,
36840x7c8ea214,
36850x48000001,
36860x00030028,
36870x81d20000,
36880x00098200,
36890x0006000b,
36900x80f00000,
36910x3a100004,
36920x54e815ba,
36930x54ea5d78,
36940x54ec9b78,
36950x7c11402e,
36960x54f4dd78,
36970x54eb9d78,
36980x7c0903a6,
36990x4e800420,
37000x00000000,
37010x5588007e,
37020x000900ab,
37030x91d20000,
37040x00098200,
37050x2108fffc,
37060x9201000c,
37070x7c8f402e,
37080x7e439378,
37090x80aefffc,
37100x48000001,
37110x00030029,
37120x81d20000,
37130x00098200,
37140x10791a2d,
37150x106ea320,
37160x80f00000,
37170x3a100004,
37180x54e815ba,
37190x54ea5d78,
37200x54ec9b78,
37210x7c11402e,
37220x54f4dd78,
37230x54eb9d78,
37240x7c0903a6,
37250x4e800420,
37260x00000000,
37270x80110000,
37280x00098200,
37290x7e439378,
37300x81110000,
37310x00098200,
37320x91d20000,
37330x00098200,
37340x7c004040,
37350x9201000c,
37360x40800000,
37370x00050805,
37380x0006000b,
37390x00000000,
37400x5584ed7e,
37410x558596fe,
37420x2c0407ff,
37430x39000801,
37440x7c88209e,
37450x48000001,
37460x0003002a,
37470x00000000,
37480x5588007e,
37490x000900ab,
37500x2108fffc,
37510x7c8f402e,
37520x48000001,
37530x0003002b,
37540x00000000,
37550x81d20000,
37560x00098200,
37570x10781a2d,
37580x106ea320,
37590x80f00000,
37600x3a100004,
37610x54e815ba,
37620x54ea5d78,
37630x54ec9b78,
37640x7c11402e,
37650x54f4dd78,
37660x54eb9d78,
37670x7c0903a6,
37680x4e800420,
37690x0006000f,
37700x7d956378,
37710x48000001,
37720x0003002c,
37730x7eacab78,
37740x7e439378,
37750x48000000,
37760x0005000b,
37770x00000000,
37780x812efffc,
37790x5588007e,
37800x000900ab,
37810x81490000,
37820x00098200,
37830x2108fffc,
37840x7d6f402e,
37850x00000000,
37860x48000000,
37870x0005009b,
37880x00000000,
37890x48000000,
37900x0005009c,
37910x00000000,
37920x114e5300,
37930x116e5b00,
37940x100ac234,
37950x40800000,
37960x0005082f,
37970x100bb232,
37980x40800000,
37990x00050805,
38000x11205af5,
38010x800a0000,
38020x00098200,
38030x11004af1,
38040x7c004840,
38050x108b42ee,
38060x810a0000,
38070x00098200,
38080x4c212a02,
38090x55291800,
38100x000900a1,
38110x40810000,
38120x0005082f,
38130x11084b00,
38140x1008d234,
38150x41800000,
38160x00050802,
38170x0006000b,
38180x110ea320,
38190x80f00000,
38200x3a100004,
38210x54e815ba,
38220x54ea5d78,
38230x54ec9b78,
38240x7c11402e,
38250x54f4dd78,
38260x54eb9d78,
38270x7c0903a6,
38280x4e800420,
38290x0006000c,
38300x812a0000,
38310x00098200,
38320x28090000,
38330x41820000,
38340x0005080b,
38350x88090000,
38360x00098200,
38370x70000000,
38380x00090200,
38390x40820000,
38400x0005080b,
38410x48000000,
38420x0005002f,
38430x0006000f,
38440x100bba34,
38450x41800000,
38460x0005089b,
38470x48000000,
38480x0005002f,
38490x00000000,
38500x114e5300,
38510x5568007e,
38520x000900ab,
38530x100ac234,
38540x2108fffc,
38550x7d6f402e,
38560x40800000,
38570x0005082c,
38580x0006009b,
38590x800a0000,
38600x00098200,
38610x810b0000,
38620x00098200,
38630x812a0000,
38640x00098200,
38650x11775a2d,
38660x7d080038,
38670x55002800,
38680x000900a1,
38690x55081800,
38700x000900a1,
38710x7d080050,
38720x7d294214,
38730x0006000b,
38740x10090301,
38750x00090cab,
38760x11090301,
38770x00090cab,
38780x10005a34,
38790x40830000,
38800x00050804,
38810x1008d234,
38820x41800000,
38830x00050805,
38840x0006000d,
38850x110ea320,
38860x80f00000,
38870x3a100004,
38880x54e815ba,
38890x54ea5d78,
38900x54ec9b78,
38910x7c11402e,
38920x54f4dd78,
38930x54eb9d78,
38940x7c0903a6,
38950x4e800420,
38960x0006000e,
38970x81290000,
38980x00098200,
38990x28090000,
39000x40820000,
39010x0005080b,
39020x111ad217,
39030x0006000f,
39040x812a0000,
39050x00098200,
39060x28090000,
39070x41820000,
39080x0005080d,
39090x88090000,
39100x00098200,
39110x70000000,
39120x00090200,
39130x00000000,
39140x40820000,
39150x0005080d,
39160x48000000,
39170x0005002d,
39180x00000000,
39190x114e5300,
39200x556000fe,
39210x000900ab,
39220x100ac234,
39230x40800000,
39240x0005082e,
39250x810a0000,
39260x00098200,
39270x812a0000,
39280x00098200,
39290x7c004040,
39300x40800000,
39310x0005082e,
39320x11095b00,
39330x1008d234,
39340x41800000,
39350x00050805,
39360x0006000b,
39370x80f00000,
39380x3a100004,
39390x110ea320,
39400x54e815ba,
39410x54ea5d78,
39420x54ec9b78,
39430x7c11402e,
39440x54f4dd78,
39450x54eb9d78,
39460x7c0903a6,
39470x4e800420,
39480x0006000f,
39490x812a0000,
39500x00098200,
39510x28090000,
39520x41820000,
39530x0005080b,
39540x89290000,
39550x00098200,
39560x71290000,
39570x00090200,
39580x40820000,
39590x0005080b,
39600x48000000,
39610x0005002e,
39620x00000000,
39630x114e5300,
39640x116e5b00,
39650x100ac234,
39660x40800000,
39670x00050833,
39680x100bb232,
39690x40800000,
39700x00050805,
39710x11205af5,
39720x12aea300,
39730x800a0000,
39740x00098200,
39750x11004af1,
39760x7c004840,
39770x108b42ee,
39780x810a0000,
39790x00098200,
39800x4c212a02,
39810x55201800,
39820x000900a1,
39830x40810000,
39840x00050833,
39850x88ca0000,
39860x00098200,
39870x11280300,
39880x1009d234,
39890x41800000,
39900x00050803,
39910x0006000b,
39920x70c90000,
39930x00090200,
39940x12a80320,
39950x40820000,
39960x00050807,
39970x0006000c,
39980x80f00000,
39990x3a100004,
40000x54e815ba,
40010x54ea5d78,
40020x54ec9b78,
40030x7c11402e,
40040x54f4dd78,
40050x54eb9d78,
40060x7c0903a6,
40070x4e800420,
40080x0006000d,
40090x812a0000,
40100x00098200,
40110x28090000,
40120x41820000,
40130x0005080b,
40140x89290000,
40150x00098200,
40160x71290000,
40170x00090200,
40180x40820000,
40190x0005080b,
40200x48000000,
40210x00050033,
40220x0006000f,
40230x100bba34,
40240x41800000,
40250x0005089c,
40260x48000000,
40270x00050033,
40280x00060011,
40290x00000000,
40300x80110000,
40310x00098200,
40320x54c607b8,
40330x91510000,
40340x00098200,
40350x98ca0000,
40360x00098200,
40370x900a0000,
40380x00098200,
40390x48000000,
40400x0005000c,
40410x00000000,
40420x114e5300,
40430x5568007e,
40440x000900ab,
40450x100ac234,
40460x2108fffc,
40470x7d6f402e,
40480x40800000,
40490x00050830,
40500x0006009c,
40510x800a0000,
40520x00098200,
40530x810b0000,
40540x00098200,
40550x812a0000,
40560x00098200,
40570x11775a2d,
40580x9b6a0000,
40590x00098200,
40600x7d080038,
40610x12aea300,
40620x55002800,
40630x000900a1,
40640x55081800,
40650x000900a1,
40660x7d080050,
40670x88ca0000,
40680x00098200,
40690x7d294214,
40700x0006000b,
40710x10090301,
40720x00090cab,
40730x11090301,
40740x00090cab,
40750x10005a34,
40760x40830000,
40770x00050805,
40780x1008d234,
40790x41800000,
40800x00050804,
40810x0006000c,
40820x70c00000,
40830x00090200,
40840x12a90321,
40850x00090cab,
40860x40820000,
40870x00050807,
40880x0006000d,
40890x80f00000,
40900x3a100004,
40910x54e815ba,
40920x54ea5d78,
40930x54ec9b78,
40940x7c11402e,
40950x54f4dd78,
40960x54eb9d78,
40970x7c0903a6,
40980x4e800420,
40990x0006000e,
41000x810a0000,
41010x00098200,
41020x00000000,
41030x28080000,
41040x41820000,
41050x0005080c,
41060x88080000,
41070x00098200,
41080x70000000,
41090x00090200,
41100x40820000,
41110x0005080c,
41120x48000000,
41130x00050031,
41140x0006000f,
41150x81290000,
41160x00098200,
41170x28090000,
41180x40820000,
41190x0005080b,
41200x810a0000,
41210x00098200,
41220x38b10000,
41230x00098200,
41240x9201000c,
41250x7e439378,
41260x28080000,
41270x91d20000,
41280x00098200,
41290x41820000,
41300x00050806,
41310x88080000,
41320x00098200,
41330x70000000,
41340x00090200,
41350x41820000,
41360x00050831,
41370x00060010,
41380x7d445378,
41390x11650321,
41400x48000001,
41410x0003002d,
41420x81d20000,
41430x00098200,
41440x12a30321,
41450x48000000,
41460x0005000d,
41470x00060011,
41480x80110000,
41490x00098200,
41500x54c607b8,
41510x91510000,
41520x00098200,
41530x00000000,
41540x98ca0000,
41550x00098200,
41560x900a0000,
41570x00098200,
41580x48000000,
41590x0005000d,
41600x00000000,
41610x114e5300,
41620x556000fe,
41630x000900ab,
41640x100ac234,
41650x40800000,
41660x00050832,
41670x810a0000,
41680x00098200,
41690x812a0000,
41700x00098200,
41710x88ca0000,
41720x00098200,
41730x7c004040,
41740x12aea300,
41750x40800000,
41760x00050832,
41770x11095b00,
41780x1008d234,
41790x41800000,
41800x00050805,
41810x0006000b,
41820x70c00000,
41830x00090200,
41840x12a95b20,
41850x40820000,
41860x00050807,
41870x0006000c,
41880x80f00000,
41890x3a100004,
41900x54e815ba,
41910x54ea5d78,
41920x54ec9b78,
41930x7c11402e,
41940x54f4dd78,
41950x54eb9d78,
41960x7c0903a6,
41970x4e800420,
41980x0006000f,
41990x810a0000,
42000x00098200,
42010x28080000,
42020x41820000,
42030x0005080b,
42040x89080000,
42050x00098200,
42060x71080000,
42070x00090200,
42080x40820000,
42090x0005080b,
42100x48000000,
42110x00050032,
42120x00060011,
42130x80110000,
42140x00098200,
42150x54c607b8,
42160x91510000,
42170x00098200,
42180x98ca0000,
42190x00098200,
42200x00000000,
42210x900a0000,
42220x00098200,
42230x48000000,
42240x0005000c,
42250x00000000,
42260x7e8ea214,
42270x0006000b,
42280x7ccf6214,
42290x8094fffc,
42300x3413fff8,
42310x80c60004,
42320x540500fe,
42330x000900ab,
42340x41820000,
42350x00050804,
42360x7ca53214,
42370x81240000,
42380x00098200,
42390x54c81800,
42400x000900a1,
42410x88c40000,
42420x00098200,
42430x7c054840,
42440x7d340214,
42450x80040000,
42460x00098200,
42470x41810000,
42480x00050805,
42490x7d080214,
42500x70c00000,
42510x00090200,
42520x0006000d,
42530x10140301,
42540x3a940008,
42550x7c944800,
42560x10080321,
42570x39080008,
42580x41840000,
42590x0005080d,
42600x40820000,
42610x00050807,
42620x0006000e,
42630x80f00000,
42640x3a100004,
42650x54e815ba,
42660x54ea5d78,
42670x54ec9b78,
42680x7c11402e,
42690x54f4dd78,
42700x54eb9d78,
42710x7c0903a6,
42720x4e800420,
42730x0006000f,
42740x91d20000,
42750x00098200,
42760x7e439378,
42770x9201000c,
42780x7d956378,
42790x48000001,
42800x0003002e,
42810x7eacab78,
42820x48000000,
42830x0005000b,
42840x00060011,
42850x80110000,
42860x00098200,
42870x54c607b8,
42880x90910000,
42890x00098200,
42900x98c40000,
42910x00098200,
42920x90040000,
42930x00098200,
42940x00000000,
42950x48000000,
42960x0005000e,
42970x00000000,
42980x7d6b9a14,
42990x00000000,
43000x114ea300,
43010x7dc97378,
43020x7dcea214,
43030x396bfff8,
43040x100aca34,
43050x39ce0008,
43060x40800000,
43070x00050825,
43080x920efff8,
43090x820a0000,
43100x00098200,
43110x80f00000,
43120x3a100004,
43130x54e815ba,
43140x54f4dd78,
43150x7c11402e,
43160x7e947214,
43170x7c0903a6,
43180x4e800420,
43190x00000000,
43200x7d6b9a14,
43210x00000000,
43220x114ea300,
43230x7e8ea214,
43240x810efff8,
43250x396bfff8,
43260x100aca34,
43270x3a940008,
43280x40800000,
43290x00050840,
43300x00060041,
43310x71000000,
43320x00090200,
43330x88ca0000,
43340x00098200,
43350x69090000,
43360x00090200,
43370x288b0000,
43380x40820000,
43390x00050807,
43400x0006000b,
43410x914efffc,
43420x39200000,
43430x2b860001,
43440x41860000,
43450x00050803,
43460x0006000c,
43470x38c90008,
43480x10144b00,
43490x7c865840,
43500x100e4b20,
43510x7cc93378,
43520x40860000,
43530x0005080c,
43540x0006000d,
43550x4c42ea02,
43560x41820000,
43570x00050805,
43580x0006000e,
43590x820a0000,
43600x00098200,
43610x80f00000,
43620x3a100004,
43630x54e815ba,
43640x54f4dd78,
43650x7c11402e,
43660x7e947214,
43670x7c0903a6,
43680x4e800420,
43690x0006000f,
43700x80e8fffc,
43710x54f4dd78,
43720x7d147050,
43730x81080000,
43740x00098200,
43750x81080000,
43760x00098200,
43770x81e80000,
43780x00098200,
43790x48000000,
43800x0005000e,
43810x00060011,
43820x71200000,
43830x00090200,
43840x40820000,
43850x0005080b,
43860x00000000,
43870x7dc97050,
43880x810efff8,
43890x71000000,
43900x00090200,
43910x48000000,
43920x0005000b,
43930x00000000,
43940x3a94ffe8,
43950x7dc97378,
43960x114ea300,
43970x7dcea214,
43980x100e0b01,
43990x110e1301,
44000x114e1b21,
44010x100aca34,
44020x100e2321,
44030x39600010,
44040x110e2b21,
44050x39ce0020,
44060x40800000,
44070x00050825,
44080x920efff8,
44090x820a0000,
44100x00098200,
44110x80f00000,
44120x3a100004,
44130x54e815ba,
44140x54f4dd78,
44150x7c11402e,
44160x7e947214,
44170x7c0903a6,
44180x4e800420,
44190x00000000,
44200x7e8ea214,
44210x8154fff4,
44220x8174fffc,
44230x800a0000,
44240x00098200,
44250x810a0000,
44260x00098200,
44270x3a100004,
44280x0006000b,
44290x7c0b0040,
44300x55661800,
44310x000900a1,
44320x40800000,
44330x00050805,
44340x11283300,
44350x1009d234,
44360x80f0fffc,
44370x41800000,
44380x00050804,
44390x10005af1,
44400x396b0001,
44410x3cd00000,
44420x00098200,
44430x11340b21,
44440x54e893ba,
44450x9174fffc,
44460x7e083214,
44470x10140321,
44480x0006000d,
44490x80f00000,
44500x3a100004,
44510x54e815ba,
44520x54ea5d78,
44530x54ec9b78,
44540x7c11402e,
44550x54f4dd78,
44560x54eb9d78,
44570x7c0903a6,
44580x4e800420,
44590x0006000e,
44600x396b0001,
44610x48000000,
44620x0005000b,
44630x0006000f,
44640x810a0000,
44650x00098200,
44660x7d605850,
44670x812a0000,
44680x00098200,
44690x00060010,
44700x7c0b4040,
44710x55662800,
44720x000900a1,
44730x41810000,
44740x0005080d,
44750x556a1800,
44760x000900a1,
44770x7cca3050,
44780x11493300,
44790x7cc93214,
44800x100ad234,
44810x80f0fffc,
44820x41800000,
44830x00050807,
44840x10c60301,
44850x00090cab,
44860x3d300000,
44870x00098200,
44880x11540b21,
44890x7d6b0214,
44900x54e893ba,
44910x10d40321,
44920x396b0001,
44930x7e084a14,
44940x9174fffc,
44950x48000000,
44960x0005000d,
44970x00060011,
44980x00000000,
44990x396b0001,
45000x48000000,
45010x00050010,
45020x00000000,
45030x7e8ea214,
45040x3920ffe8,
45050x11144b00,
45060x8134fff0,
45070x80d4fff8,
45080x1008422c,
45090x2c090000,
45100x00098200,
45110x2c800000,
45120x00098200,
45130x2f060000,
45140x00098200,
45150x40860000,
45160x00050805,
45170x89080000,
45180x00098200,
45190x4c42d202,
45200x2f880000,
45210x00098200,
45220x5580007e,
45230x000900ab,
45240x4c42f202,
45250x7cd00214,
45260x40820000,
45270x00050805,
45280x9374fffc,
45290x3e060000,
45300x00098200,
45310x0006000b,
45320x80f00000,
45330x3a100004,
45340x54e815ba,
45350x54ea5d78,
45360x54ec9b78,
45370x7c11402e,
45380x54f4dd78,
45390x54eb9d78,
45400x7c0903a6,
45410x4e800420,
45420x0006000f,
45430x38000000,
45440x00098200,
45450x39000000,
45460x00098200,
45470x9810ffff,
45480x3e060000,
45490x00098200,
45500x99100003,
45510x48000000,
45520x0005000b,
45530x00000000,
45540x800efff8,
45550x7d6e5a14,
45560x7e8ea214,
45570x396b0000,
45580x00098200,
45590x7d345214,
45600x38cefff8,
45610x7d605850,
45620x288a0000,
45630x7d0b3051,
45640x41860000,
45650x00050805,
45660x3929fff0,
45670x40810000,
45680x00050802,
45690x0006000b,
45700x100b0301,
45710x396b0008,
45720x10140321,
45730x7c144840,
45740x7c8b3040,
45750x40800000,
45760x00050803,
45770x3a940008,
45780x41840000,
45790x0005080b,
45800x0006000c,
45810x13540321,
45820x7c144840,
45830x3a940008,
45840x41800000,
45850x0005080c,
45860x0006000d,
45870x80f00000,
45880x3a100004,
45890x54e815ba,
45900x54ea5d78,
45910x54ec9b78,
45920x7c11402e,
45930x54f4dd78,
45940x54eb9d78,
45950x7c0903a6,
45960x4e800420,
45970x0006000f,
45980x80120000,
45990x00098200,
46000x3a600008,
46010x40810000,
46020x0005080d,
46030x7d344214,
46040x7c090040,
46050x3a680008,
46060x41810000,
46070x00050807,
46080x00060010,
46090x100b0301,
46100x396b0008,
46110x10140321,
46120x7c0b3040,
46130x3a940008,
46140x41800000,
46150x00050810,
46160x48000000,
46170x0005000d,
46180x00060011,
46190x7e439378,
46200x92920000,
46210x00098200,
46220x7eae5850,
46230x91d20000,
46240x00098200,
46250x7e8ea050,
46260x9201000c,
46270x550400fe,
46280x000900ab,
46290x48000001,
46300x00030000,
46310x81d20000,
46320x00098200,
46330x00000000,
46340x7e8ea214,
46350x7d6eaa14,
46360x38cefff8,
46370x48000000,
46380x00050010,
46390x00000000,
46400x7d8c9a14,
46410x00000000,
46420x820efff8,
46430x7e8ea214,
46440x7d936378,
46450x0006000b,
46460x72000000,
46470x00090200,
46480x6a080000,
46490x00090200,
46500x40820000,
46510x0005089d,
46520x00060017,
46530x80f0fffc,
46540x2c0c0008,
46550x392efff8,
46560x396cfff8,
46570x54ea5d78,
46580x41820000,
46590x00050803,
46600x39000000,
46610x0006000c,
46620x38c80008,
46630x10144300,
46640x7c065800,
46650x10094320,
46660x41820000,
46670x00050803,
46680x39060008,
46690x10143300,
46700x7c085800,
46710x10093320,
46720x40820000,
46730x0005080c,
46740x0006000d,
46750x0006000f,
46760x7c0a6040,
46770x54f4dd78,
46780x41810000,
46790x00050806,
46800x7dd44850,
46810x810efffc,
46820x80f00000,
46830x3a100004,
46840x81080000,
46850x00098200,
46860x81e80000,
46870x00098200,
46880x54e815ba,
46890x54ea5d78,
46900x54ec9b78,
46910x7c11402e,
46920x54f4dd78,
46930x54eb9d78,
46940x7c0903a6,
46950x4e800420,
46960x00060010,
46970x390cfff8,
46980x398c0008,
46990x13494320,
47000x48000000,
47010x0005000f,
47020x0006009d,
47030x71090000,
47040x00090200,
47050x40820000,
47060x00050818,
47070x7dc87050,
47080x820efff8,
47090x48000000,
47100x0005000b,
47110x00000000,
47120x820efff8,
47130x7e8ea214,
47140x7d936378,
47150x72000000,
47160x00090200,
47170x6a080000,
47180x00090200,
47190x40820000,
47200x0005089d,
47210x80f0fffc,
47220x392efff8,
47230x54ea5d78,
47240x00000000,
47250x10140301,
47260x10090321,
47270x00000000,
47280x0006000f,
47290x7c0a6040,
47300x54f4dd78,
47310x41810000,
47320x00050806,
47330x7dd44850,
47340x810efffc,
47350x80f00000,
47360x3a100004,
47370x81080000,
47380x00098200,
47390x81e80000,
47400x00098200,
47410x54e815ba,
47420x54ea5d78,
47430x54ec9b78,
47440x7c11402e,
47450x54f4dd78,
47460x54eb9d78,
47470x7c0903a6,
47480x4e800420,
47490x00060010,
47500x390cfff8,
47510x398c0008,
47520x13494320,
47530x48000000,
47540x0005000f,
47550x00000000,
47560x7c810808,
47570x00000000,
47580x7e8ea214,
47590x11140301,
47600x00090cab,
47610x10d40301,
47620x00090cab,
47630x11340301,
47640x00090cab,
47650x00000000,
47660x1008b230,
47670x1386b230,
47680x1089b230,
47690x4c00e382,
47700x4c002382,
47710x41800000,
47720x00050842,
47730x00000000,
47740x110832e0,
47750x11140321,
47760x00090cab,
47770x00000000,
47780x1006d231,
47790x11140321,
47800x00090cab,
47810x40800000,
47820x00050802,
47830x10084aec,
47840x0006000b,
47850x00000000,
47860x558c007e,
47870x000900ab,
47880x7d906214,
47890x00000000,
47900x3e0c0000,
47910x00098200,
47920x00000000,
47930x3d8c0000,
47940x00098200,
47950x00000000,
47960x7e0c805e,
47970x00000000,
47980x7e10605e,
47990x00000000,
48000x40810000,
48010x00070800,
48020x00000000,
48030x80f00000,
48040x3a100004,
48050x54e815ba,
48060x54ea5d78,
48070x54ec9b78,
48080x7c11402e,
48090x54f4dd78,
48100x54eb9d78,
48110x7c0903a6,
48120x4e800420,
48130x0006000c,
48140x100942ec,
48150x48000000,
48160x0005000b,
48170x00000000,
48180x7c810808,
48190x00000000,
48200x110ea300,
48210x3a94fff8,
48220x1008d234,
48230x41800000,
48240x00050801,
48250x00000000,
48260x7c810808,
48270x00000000,
48280x5580007e,
48290x000900ab,
48300x7e100214,
48310x3e100000,
48320x00098200,
48330x110ea320,
48340x00000000,
48350x0006000b,
48360x80f00000,
48370x3a100004,
48380x54e815ba,
48390x54ea5d78,
48400x54ec9b78,
48410x7c11402e,
48420x54f4dd78,
48430x54eb9d78,
48440x7c0903a6,
48450x4e800420,
48460x00000000,
48470x7c810808,
48480x00000000,
48490x80f00000,
48500x3a100004,
48510x54e815ba,
48520x54ea5d78,
48530x54ec9b78,
48540x7c11402e,
48550x54f4dd78,
48560x54eb9d78,
48570x7c0903a6,
48580x4e800420,
48590x00000000,
48600x7c810808,
48610x00000000,
48620x5580007e,
48630x000900ab,
48640x7e100214,
48650x3e100000,
48660x00098200,
48670x80f00000,
48680x3a100004,
48690x54e815ba,
48700x54ea5d78,
48710x54ec9b78,
48720x7c11402e,
48730x54f4dd78,
48740x54eb9d78,
48750x7c0903a6,
48760x4e800420,
48770x00000000,
48780x7c810808,
48790x00000000,
48800x81320000,
48810x00098200,
48820x89100000,
48830x00098200,
48840x81f00000,
48850x00098200,
48860x7c144840,
48870x55081800,
48880x000900a1,
48890x41810000,
48900x00050820,
48910x80f00000,
48920x3a100004,
48930x0006000c,
48940x7c0b4040,
48950x40810000,
48960x00050803,
48970x00000000,
48980x7c810808,
48990x00000000,
49000x54e815ba,
49010x54ea5d78,
49020x54ec9b78,
49030x7c11402e,
49040x54f4dd78,
49050x54eb9d78,
49060x7c0903a6,
49070x4e800420,
49080x00000000,
49090x0006000d,
49100x134e5b20,
49110x396b0008,
49120x48000000,
49130x0005000c,
49140x00000000,
49150x7c810808,
49160x00000000,
49170x81320000,
49180x00098200,
49190x7d0e5a14,
49200x7c145a14,
49210x91480004,
49220x38cb0000,
49230x00098200,
49240x81f00000,
49250x00098200,
49260x7c004840,
49270x90c80000,
49280x40800000,
49290x00050820,
49300x89300000,
49310x00098200,
49320x7dd47378,
49330x7d0b4378,
49340x80f00000,
49350x3a100004,
49360x2c090000,
49370x39c80008,
49380x41820000,
49390x00050803,
49400x0006000b,
49410x7c145840,
49420x10140301,
49430x40800000,
49440x00050804,
49450x13540321,
49460x3a940008,
49470x0006000c,
49480x3529ffff,
49490x10080b21,
49500x39080008,
49510x40820000,
49520x0005080b,
49530x0006000d,
49540x54e815ba,
49550x54ea5d78,
49560x54ec9b78,
49570x7c11402e,
49580x54f4dd78,
49590x54eb9d78,
49600x7c0903a6,
49610x4e800420,
49620x0006000e,
49630x101ad217,
49640x48000000,
49650x0005000c,
49660x00000000,
49670x80ca0000,
49680x00098200,
49690x00000000,
49700x80d10000,
49710x00098200,
49720x00000000,
49730x7d145a14,
49740x81320000,
49750x00098200,
49760x7d6e5a14,
49770x91d20000,
49780x00098200,
49790x7c084840,
49800x91720000,
49810x00098200,
49820x38000000,
49830x00098200,
49840x7cc903a6,
49850x00000000,
49860x808a0000,
49870x00098200,
49880x00000000,
49890x7e439378,
49900x41810000,
49910x0005081f,
49920x90110000,
49930x00098200,
49940x4e800421,
49950x81120000,
49960x00098200,
49970x546c1800,
49980x000900a1,
49990x81d20000,
50000x00098200,
50010x38000000,
50020x00098200,
50030x820efff8,
50040x7e8c4050,
50050x90110000,
50060x00098200,
50070x48000000,
50080x00050016,
50090x00000000,
50100x00010000
5011};
5012
5013enum {
5014 GLOB_vm_returnp,
5015 GLOB_cont_dispatch,
5016 GLOB_vm_returnc,
5017 GLOB_BC_RET_Z,
5018 GLOB_vm_return,
5019 GLOB_vm_leave_cp,
5020 GLOB_vm_leave_unw,
5021 GLOB_vm_unwind_c,
5022 GLOB_vm_unwind_c_eh,
5023 GLOB_vm_unwind_ff,
5024 GLOB_vm_unwind_ff_eh,
5025 GLOB_vm_growstack_c,
5026 GLOB_vm_growstack_l,
5027 GLOB_vm_resume,
5028 GLOB_vm_pcall,
5029 GLOB_vm_call,
5030 GLOB_vm_call_dispatch,
5031 GLOB_vmeta_call,
5032 GLOB_vm_call_dispatch_f,
5033 GLOB_vm_cpcall,
5034 GLOB_vm_call_tail,
5035 GLOB_cont_cat,
5036 GLOB_BC_CAT_Z,
5037 GLOB_cont_nop,
5038 GLOB_vmeta_tgets1,
5039 GLOB_vmeta_tgets,
5040 GLOB_vmeta_tgetb,
5041 GLOB_vmeta_tgetv,
5042 GLOB_vmeta_tsets1,
5043 GLOB_vmeta_tsets,
5044 GLOB_vmeta_tsetb,
5045 GLOB_vmeta_tsetv,
5046 GLOB_vmeta_comp,
5047 GLOB_vmeta_binop,
5048 GLOB_cont_ra,
5049 GLOB_cont_condt,
5050 GLOB_cont_condf,
5051 GLOB_vmeta_equal,
5052 GLOB_vmeta_arith_vn,
5053 GLOB_vmeta_arith_nv,
5054 GLOB_vmeta_unm,
5055 GLOB_vmeta_arith_vv,
5056 GLOB_vmeta_len,
5057 GLOB_BC_LEN_Z,
5058 GLOB_vmeta_callt,
5059 GLOB_BC_CALLT_Z,
5060 GLOB_vmeta_for,
5061 GLOB_ff_assert,
5062 GLOB_fff_fallback,
5063 GLOB_fff_res,
5064 GLOB_ff_type,
5065 GLOB_fff_restv,
5066 GLOB_ff_getmetatable,
5067 GLOB_ff_setmetatable,
5068 GLOB_ff_rawget,
5069 GLOB_ff_tonumber,
5070 GLOB_ff_tostring,
5071 GLOB_fff_gcstep,
5072 GLOB_ff_next,
5073 GLOB_ff_pairs,
5074 GLOB_ff_ipairs_aux,
5075 GLOB_ff_ipairs,
5076 GLOB_ff_pcall,
5077 GLOB_ff_xpcall,
5078 GLOB_ff_coroutine_resume,
5079 GLOB_ff_coroutine_wrap_aux,
5080 GLOB_ff_coroutine_yield,
5081 GLOB_ff_math_abs,
5082 GLOB_fff_res1,
5083 GLOB_ff_math_floor,
5084 GLOB_vm_floor_hilo,
5085 GLOB_ff_math_ceil,
5086 GLOB_vm_ceil_hilo,
5087 GLOB_ff_math_sqrt,
5088 GLOB_ff_math_log,
5089 GLOB_ff_math_log10,
5090 GLOB_ff_math_exp,
5091 GLOB_ff_math_sin,
5092 GLOB_ff_math_cos,
5093 GLOB_ff_math_tan,
5094 GLOB_ff_math_asin,
5095 GLOB_ff_math_acos,
5096 GLOB_ff_math_atan,
5097 GLOB_ff_math_sinh,
5098 GLOB_ff_math_cosh,
5099 GLOB_ff_math_tanh,
5100 GLOB_ff_math_pow,
5101 GLOB_ff_math_atan2,
5102 GLOB_ff_math_fmod,
5103 GLOB_ff_math_deg,
5104 GLOB_ff_math_rad,
5105 GLOB_ff_math_ldexp,
5106 GLOB_ff_math_frexp,
5107 GLOB_ff_math_modf,
5108 GLOB_ff_math_min,
5109 GLOB_ff_math_max,
5110 GLOB_ff_string_len,
5111 GLOB_ff_string_byte,
5112 GLOB_ff_string_char,
5113 GLOB_fff_newstr,
5114 GLOB_ff_string_sub,
5115 GLOB_ff_string_rep,
5116 GLOB_ff_string_reverse,
5117 GLOB_ff_string_lower,
5118 GLOB_ff_string_upper,
5119 GLOB_ff_table_getn,
5120 GLOB_ff_bit_tobit,
5121 GLOB_fff_resbit,
5122 GLOB_ff_bit_band,
5123 GLOB_ff_bit_bor,
5124 GLOB_ff_bit_bxor,
5125 GLOB_ff_bit_bswap,
5126 GLOB_ff_bit_bnot,
5127 GLOB_ff_bit_lshift,
5128 GLOB_ff_bit_rshift,
5129 GLOB_ff_bit_arshift,
5130 GLOB_ff_bit_rol,
5131 GLOB_ff_bit_ror,
5132 GLOB_vm_record,
5133 GLOB_vm_rethook,
5134 GLOB_vm_inshook,
5135 GLOB_cont_hook,
5136 GLOB_vm_hotloop,
5137 GLOB_vm_callhook,
5138 GLOB_vm_hotcall,
5139 GLOB_vm_exit_handler,
5140 GLOB_vm_exit_interp,
5141 GLOB_vm_floor,
5142 GLOB_vm_floor_efd,
5143 GLOB_vm_ceil_efd,
5144 GLOB_vm_trunc_efd,
5145 GLOB_vm_trunc_hilo,
5146 GLOB_vm_foldarith,
5147 GLOB_vm_ffi_call,
5148 GLOB_BC_MODVN_Z,
5149 GLOB_BC_TGETS_Z,
5150 GLOB_BC_TSETS_Z,
5151 GLOB_BC_RETV_Z,
5152 GLOB__MAX
5153};
5154static const char *const globnames[] = {
5155 "vm_returnp",
5156 "cont_dispatch",
5157 "vm_returnc",
5158 "BC_RET_Z",
5159 "vm_return",
5160 "vm_leave_cp",
5161 "vm_leave_unw",
5162 "vm_unwind_c",
5163 "vm_unwind_c_eh",
5164 "vm_unwind_ff",
5165 "vm_unwind_ff_eh",
5166 "vm_growstack_c",
5167 "vm_growstack_l",
5168 "vm_resume",
5169 "vm_pcall",
5170 "vm_call",
5171 "vm_call_dispatch",
5172 "vmeta_call",
5173 "vm_call_dispatch_f",
5174 "vm_cpcall",
5175 "vm_call_tail",
5176 "cont_cat",
5177 "BC_CAT_Z",
5178 "cont_nop",
5179 "vmeta_tgets1",
5180 "vmeta_tgets",
5181 "vmeta_tgetb",
5182 "vmeta_tgetv",
5183 "vmeta_tsets1",
5184 "vmeta_tsets",
5185 "vmeta_tsetb",
5186 "vmeta_tsetv",
5187 "vmeta_comp",
5188 "vmeta_binop",
5189 "cont_ra",
5190 "cont_condt",
5191 "cont_condf",
5192 "vmeta_equal",
5193 "vmeta_arith_vn",
5194 "vmeta_arith_nv",
5195 "vmeta_unm",
5196 "vmeta_arith_vv",
5197 "vmeta_len",
5198 "BC_LEN_Z",
5199 "vmeta_callt",
5200 "BC_CALLT_Z",
5201 "vmeta_for",
5202 "ff_assert",
5203 "fff_fallback",
5204 "fff_res",
5205 "ff_type",
5206 "fff_restv",
5207 "ff_getmetatable",
5208 "ff_setmetatable",
5209 "ff_rawget",
5210 "ff_tonumber",
5211 "ff_tostring",
5212 "fff_gcstep",
5213 "ff_next",
5214 "ff_pairs",
5215 "ff_ipairs_aux",
5216 "ff_ipairs",
5217 "ff_pcall",
5218 "ff_xpcall",
5219 "ff_coroutine_resume",
5220 "ff_coroutine_wrap_aux",
5221 "ff_coroutine_yield",
5222 "ff_math_abs",
5223 "fff_res1",
5224 "ff_math_floor",
5225 "vm_floor_hilo",
5226 "ff_math_ceil",
5227 "vm_ceil_hilo",
5228 "ff_math_sqrt",
5229 "ff_math_log",
5230 "ff_math_log10",
5231 "ff_math_exp",
5232 "ff_math_sin",
5233 "ff_math_cos",
5234 "ff_math_tan",
5235 "ff_math_asin",
5236 "ff_math_acos",
5237 "ff_math_atan",
5238 "ff_math_sinh",
5239 "ff_math_cosh",
5240 "ff_math_tanh",
5241 "ff_math_pow",
5242 "ff_math_atan2",
5243 "ff_math_fmod",
5244 "ff_math_deg",
5245 "ff_math_rad",
5246 "ff_math_ldexp",
5247 "ff_math_frexp",
5248 "ff_math_modf",
5249 "ff_math_min",
5250 "ff_math_max",
5251 "ff_string_len",
5252 "ff_string_byte",
5253 "ff_string_char",
5254 "fff_newstr",
5255 "ff_string_sub",
5256 "ff_string_rep",
5257 "ff_string_reverse",
5258 "ff_string_lower",
5259 "ff_string_upper",
5260 "ff_table_getn",
5261 "ff_bit_tobit",
5262 "fff_resbit",
5263 "ff_bit_band",
5264 "ff_bit_bor",
5265 "ff_bit_bxor",
5266 "ff_bit_bswap",
5267 "ff_bit_bnot",
5268 "ff_bit_lshift",
5269 "ff_bit_rshift",
5270 "ff_bit_arshift",
5271 "ff_bit_rol",
5272 "ff_bit_ror",
5273 "vm_record",
5274 "vm_rethook",
5275 "vm_inshook",
5276 "cont_hook",
5277 "vm_hotloop",
5278 "vm_callhook",
5279 "vm_hotcall",
5280 "vm_exit_handler",
5281 "vm_exit_interp",
5282 "vm_floor",
5283 "vm_floor_efd",
5284 "vm_ceil_efd",
5285 "vm_trunc_efd",
5286 "vm_trunc_hilo",
5287 "vm_foldarith",
5288 "vm_ffi_call",
5289 "BC_MODVN_Z",
5290 "BC_TGETS_Z",
5291 "BC_TSETS_Z",
5292 "BC_RETV_Z",
5293 (const char *)0
5294};
5295static const char *const extnames[] = {
5296 "lj_state_growstack",
5297 "lj_meta_tget",
5298 "lj_meta_tset",
5299 "lj_meta_comp",
5300 "lj_meta_equal",
5301 "lj_meta_arith",
5302 "lj_meta_len",
5303 "lj_meta_call",
5304 "lj_meta_for",
5305 "lj_tab_get",
5306 "lj_str_fromnum",
5307 "lj_tab_next",
5308 "lj_tab_getinth",
5309 "lj_ffh_coroutine_wrap_err",
5310 "sqrt",
5311 "log",
5312 "log10",
5313 "exp",
5314 "sin",
5315 "cos",
5316 "tan",
5317 "asin",
5318 "acos",
5319 "atan",
5320 "sinh",
5321 "cosh",
5322 "tanh",
5323 "pow",
5324 "atan2",
5325 "fmod",
5326 "ldexp",
5327 "frexp",
5328 "modf",
5329 "lj_str_new",
5330 "lj_tab_len",
5331 "lj_gc_step",
5332 "lj_dispatch_ins",
5333 "lj_dispatch_call",
5334 "lj_meta_cat",
5335 "lj_gc_barrieruv",
5336 "lj_func_closeuv",
5337 "lj_func_newL_gc",
5338 "lj_tab_new",
5339 "lj_tab_dup",
5340 "lj_gc_step_fixtop",
5341 "lj_tab_newkey",
5342 "lj_tab_reasize",
5343 (const char *)0
5344};
5345#define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V)
5346#define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V)
5347#define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V)
5348#define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V)
5349#define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V)
5350#define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V)
5351#define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V)
5352#define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V)
5353#define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V)
5354#define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V)
5355#define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V)
5356#define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V)
5357#define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V)
5358#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
5359#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
5360#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
5361
5362/* Generate subroutines used by opcodes and other parts of the VM. */
5363/* The .code_sub section should be last to help static branch prediction. */
5364static void build_subroutines(BuildCtx *ctx)
5365{
5366 dasm_put(Dst, 0);
5367 dasm_put(Dst, 1, FRAME_P, LJ_TTRUE, FRAME_TYPE, FRAME_C, ~LJ_VMST_C, Dt1(->base), DISPATCH_GL(vmstate), 31-3, Dt1(->top));
5368 dasm_put(Dst, 55, Dt1(->cframe), Dt1(->maxstack), Dt1(->top), 31-3, Dt1(->top), ~LJ_VMST_C, Dt1(->glref), Dt2(->vmstate));
5369 dasm_put(Dst, 135, LJ_TISNUM+1, LJ_TFUNC, LJ_TTAB, Dt1(->base), Dt1(->glref), LJ_TSTR, LJ_TFALSE, LJ_TNIL, ~LJ_VMST_INTERP, GG_G2DISP, DISPATCH_GL(vmstate), LUA_MINSTACK, Dt1(->base), Dt1(->top), 32-3);
5370 dasm_put(Dst, 190, Dt1(->base), Dt1(->top), Dt7(->pc), Dt1(->glref), Dt1(->status), FRAME_CP, CFRAME_RESUME, GG_G2DISP, Dt1(->cframe), Dt1(->base), LJ_TISNUM+1, Dt1(->top), LJ_TFUNC, LJ_TTAB, LJ_TSTR, Dt1(->status), FRAME_TYPE, ~LJ_VMST_INTERP, LJ_TNIL, DISPATCH_GL(vmstate));
5371 dasm_put(Dst, 283, FRAME_CP, FRAME_C, Dt1(->cframe), Dt1(->cframe), Dt1(->glref), GG_G2DISP, Dt1(->base), LJ_TISNUM+1, Dt1(->top), LJ_TFUNC, LJ_TTAB, LJ_TSTR, ~LJ_VMST_INTERP, LJ_TNIL, DISPATCH_GL(vmstate));
5372 dasm_put(Dst, 384, Dt7(->pc), Dt1(->stack), Dt1(->top), Dt1(->cframe), Dt1(->cframe), Dt1(->glref), FRAME_CP, GG_G2DISP, Dt7(->pc), PC2PROTO(k), Dt1(->base));
5373 dasm_put(Dst, 491, DISPATCH_GL(tmptv), DISPATCH_GL(tmptv), DISPATCH_GL(tmptv2), DISPATCH_GL(tmptv), Dt1(->base), FRAME_CONT, Dt1(->top), DISPATCH_GL(tmptv));
5374 dasm_put(Dst, 566, DISPATCH_GL(tmptv), DISPATCH_GL(tmptv2), DISPATCH_GL(tmptv), Dt1(->base), FRAME_CONT, Dt1(->top), Dt1(->base));
5375 dasm_put(Dst, 647, -(BCBIAS_J*4 >> 16), LJ_TTRUE, LJ_TFALSE, Dt1(->base));
5376 dasm_put(Dst, 716, Dt1(->base), FRAME_CONT);
5377#ifdef LUAJIT_ENABLE_LUA52COMPAT
5378 dasm_put(Dst, 739);
5379#endif
5380 dasm_put(Dst, 741, Dt1(->base));
5381#ifdef LUAJIT_ENABLE_LUA52COMPAT
5382 dasm_put(Dst, 749);
5383#else
5384 dasm_put(Dst, 756);
5385#endif
5386 dasm_put(Dst, 759, Dt1(->base), Dt7(->pc), Dt1(->base), Dt1(->base));
5387#if LJ_HASJIT
5388 dasm_put(Dst, 807);
5389#endif
5390 dasm_put(Dst, 809);
5391#if LJ_HASJIT
5392 dasm_put(Dst, 811, BC_JFORI);
5393#endif
5394 dasm_put(Dst, 814);
5395#if LJ_HASJIT
5396 dasm_put(Dst, 816, BC_JFORI);
5397#endif
5398 dasm_put(Dst, 819, BC_FORI, ~LJ_TNUMX, 31-3, Dt8(->upvalue), Dt6(->metatable), DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable]));
5399 dasm_put(Dst, 884, Dt6(->hmask), Dt5(->hash), Dt6(->node), 31-5, 31-3, DtB(->key), DtB(->val), DtB(->next), LJ_TUDATA, 31-2, 4*~LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT]));
5400 dasm_put(Dst, 940, Dt6(->metatable), Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
5401 dasm_put(Dst, 1000, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]), Dt1(->base), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), Dt1(->top), (2+1)*8);
5402#ifdef LUAJIT_ENABLE_LUA52COMPAT
5403 dasm_put(Dst, 1073, Dt6(->metatable), Dt8(->upvalue[0]));
5404#else
5405 dasm_put(Dst, 1082, Dt8(->upvalue[0]));
5406#endif
5407 dasm_put(Dst, 1086, (3+1)*8, Dt6(->asize), Dt6(->array), 31-3, (0+1)*8, (2+1)*8, Dt6(->hmask), (0+1)*8, (0+1)*8);
5408 dasm_put(Dst, 1150);
5409#ifdef LUAJIT_ENABLE_LUA52COMPAT
5410 dasm_put(Dst, 1163, Dt6(->metatable), Dt8(->upvalue[0]));
5411#else
5412 dasm_put(Dst, 1172, Dt8(->upvalue[0]));
5413#endif
5414 dasm_put(Dst, 1176, (3+1)*8, DISPATCH_GL(hookmask), 32-HOOK_ACTIVE_SHIFT, 8+FRAME_PCALL, DISPATCH_GL(hookmask), 32-HOOK_ACTIVE_SHIFT, 16+FRAME_PCALL, LJ_TTHREAD, Dt1(->status), Dt1(->cframe), Dt1(->top));
5415 dasm_put(Dst, 1237, LUA_YIELD, Dt1(->base), Dt1(->maxstack), Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->base), LUA_YIELD, Dt1(->top), ~LJ_VMST_INTERP, Dt1(->base), DISPATCH_GL(vmstate), Dt1(->maxstack));
5416 dasm_put(Dst, 1300, Dt1(->top), FRAME_TYPE, LJ_TTRUE, FRAME_TYPE, LJ_TFALSE, Dt1(->top), (2+1)*8, 32-3);
5417 dasm_put(Dst, 1360, Dt8(->upvalue[0].gcr), Dt1(->status), Dt1(->cframe), Dt1(->top), LUA_YIELD, Dt1(->base), Dt1(->maxstack), Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->base), LUA_YIELD, Dt1(->top), ~LJ_VMST_INTERP);
5418 dasm_put(Dst, 1419, Dt1(->base), DISPATCH_GL(vmstate), Dt1(->maxstack), Dt1(->top), FRAME_TYPE, 32-3, Dt1(->cframe));
5419 dasm_put(Dst, 1476, Dt1(->base), CFRAME_RESUME, Dt1(->top), LUA_YIELD, Dt1(->cframe), Dt1(->status), (1+1)*8, FRAME_TYPE);
5420 dasm_put(Dst, 1541);
5421 dasm_put(Dst, 1610);
5422 dasm_put(Dst, 1673);
5423 dasm_put(Dst, 1738);
5424 dasm_put(Dst, 1808, Dt8(->upvalue[0]), DISPATCH_GL(tmptv), DISPATCH_GL(tmptv), (2+1)*8, (2+1)*8);
5425 dasm_put(Dst, 1880, Dt5(->len));
5426 dasm_put(Dst, 1947, Dt5(->len), (0+1)*8, Dt5([1]), (1+1)*8, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), DISPATCH_GL(tmptv), Dt1(->base), Dt1(->base), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
5427 dasm_put(Dst, 2007, Dt5(->len), sizeof(GCstr)-1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
5428 dasm_put(Dst, 2073, Dt5(->len), DISPATCH_GL(tmpbuf.sz), Dt5([1]), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(strempty), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
5429 dasm_put(Dst, 2132, DISPATCH_GL(tmpbuf.sz), Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), DISPATCH_GL(tmpbuf.sz), Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
5430 dasm_put(Dst, 2191, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), DISPATCH_GL(tmpbuf.sz), Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
5431 dasm_put(Dst, 2258);
5432 dasm_put(Dst, 2329);
5433 dasm_put(Dst, 2417, Dt8(->f), 8*LUA_MINSTACK, Dt1(->maxstack), Dt1(->base), Dt1(->top), Dt1(->base), 31-3, Dt1(->top), Dt7(->pc));
5434 dasm_put(Dst, 2496, FRAME_TYPE, LUA_MINSTACK, Dt1(->base), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
5435#if LJ_HASJIT
5436 dasm_put(Dst, 2538);
5437#endif
5438 dasm_put(Dst, 2540, DISPATCH_GL(hookmask), HOOK_ACTIVE, GG_DISP2STATIC, DISPATCH_GL(hookmask), DISPATCH_GL(hookcount), HOOK_ACTIVE, 31-LUA_HOOKLINE, DISPATCH_GL(hookcount), Dt1(->base), Dt1(->base));
5439 dasm_put(Dst, 2587, GG_DISP2STATIC);
5440#if LJ_HASJIT
5441 dasm_put(Dst, 2605);
5442#endif
5443 dasm_put(Dst, 2607);
5444#if LJ_HASJIT
5445 dasm_put(Dst, 2610);
5446#endif
5447 dasm_put(Dst, 2613);
5448#if LJ_HASJIT
5449 dasm_put(Dst, 2615);
5450#endif
5451 dasm_put(Dst, 2618, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
5452#if LJ_HASJIT
5453 dasm_put(Dst, 2640);
5454#endif
5455 dasm_put(Dst, 2642);
5456#if LJ_HASJIT
5457 dasm_put(Dst, 2644);
5458#endif
5459 dasm_put(Dst, 2646);
5460#if LJ_HASJIT
5461 dasm_put(Dst, 2730);
5462#else
5463 dasm_put(Dst, 2753);
5464#endif
5465 dasm_put(Dst, 2756);
5466#if LJ_HASFFI
5467 dasm_put(Dst, 2819);
5468#endif
5469}
5470
5471/* Generate the code for a single instruction. */
5472static void build_ins(BuildCtx *ctx, BCOp op, int defop)
5473{
5474 int vk = 0;
5475 dasm_put(Dst, 2821, defop);
5476
5477 switch (op) {
5478
5479 /* -- Comparison ops ---------------------------------------------------- */
5480
5481 /* Remember: all ops branch for a true comparison, fall through otherwise. */
5482
5483 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
5484 dasm_put(Dst, 2823, -(BCBIAS_J*4 >> 16));
5485 if (op == BC_ISLE || op == BC_ISGT) {
5486 dasm_put(Dst, 2837);
5487 }
5488 if (op == BC_ISLT || op == BC_ISLE) {
5489 dasm_put(Dst, 2840);
5490 } else {
5491 dasm_put(Dst, 2842);
5492 }
5493 dasm_put(Dst, 2844);
5494 break;
5495
5496 case BC_ISEQV: case BC_ISNEV:
5497 vk = op == BC_ISEQV;
5498 dasm_put(Dst, 2855, -(BCBIAS_J*4 >> 16));
5499 if (vk) {
5500 dasm_put(Dst, 2869);
5501 } else {
5502 dasm_put(Dst, 2871);
5503 }
5504 dasm_put(Dst, 2873, ~LJ_TISPRI, ~LJ_TISTABUD);
5505 if (vk) {
5506 dasm_put(Dst, 2895);
5507 } else {
5508 dasm_put(Dst, 2897);
5509 }
5510 dasm_put(Dst, 2899);
5511 if (vk) {
5512 dasm_put(Dst, 2901);
5513 } else {
5514 dasm_put(Dst, 2903);
5515 }
5516 dasm_put(Dst, 2905, Dt6(->metatable), 1-vk, Dt6(->nomm), 1<<MM_eq);
5517 break;
5518
5519 case BC_ISEQS: case BC_ISNES:
5520 vk = op == BC_ISEQS;
5521 dasm_put(Dst, 2926, 32-1, -(BCBIAS_J*4 >> 16));
5522 if (vk) {
5523 dasm_put(Dst, 2940);
5524 } else {
5525 dasm_put(Dst, 2942);
5526 }
5527 dasm_put(Dst, 2944);
5528 break;
5529
5530 case BC_ISEQN: case BC_ISNEN:
5531 vk = op == BC_ISEQN;
5532 dasm_put(Dst, 2955, -(BCBIAS_J*4 >> 16));
5533 if (vk) {
5534 dasm_put(Dst, 2969);
5535 } else {
5536 dasm_put(Dst, 2972);
5537 }
5538 dasm_put(Dst, 2974);
5539 if (!vk) {
5540 dasm_put(Dst, 2986);
5541 }
5542 break;
5543
5544 case BC_ISEQP: case BC_ISNEP:
5545 vk = op == BC_ISEQP;
5546 dasm_put(Dst, 2992, 32-3, -(BCBIAS_J*4 >> 16));
5547 if (vk) {
5548 dasm_put(Dst, 3004);
5549 } else {
5550 dasm_put(Dst, 3006);
5551 }
5552 dasm_put(Dst, 3008);
5553 break;
5554
5555 /* -- Unary test and copy ops ------------------------------------------- */
5556
5557 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
5558 dasm_put(Dst, 3019);
5559 if (op == BC_IST || op == BC_ISF) {
5560 dasm_put(Dst, 3025, -(BCBIAS_J*4 >> 16));
5561 if (op == BC_IST) {
5562 dasm_put(Dst, 3030);
5563 } else {
5564 dasm_put(Dst, 3032);
5565 }
5566 } else {
5567 if (op == BC_ISTC) {
5568 dasm_put(Dst, 3034);
5569 } else {
5570 dasm_put(Dst, 3037);
5571 }
5572 dasm_put(Dst, 3040, -(BCBIAS_J*4 >> 16));
5573 }
5574 dasm_put(Dst, 3047);
5575 break;
5576
5577 /* -- Unary ops --------------------------------------------------------- */
5578
5579 case BC_MOV:
5580 dasm_put(Dst, 3058);
5581 break;
5582 case BC_NOT:
5583 dasm_put(Dst, 3071, LJ_TTRUE);
5584 break;
5585 case BC_UNM:
5586 dasm_put(Dst, 3087);
5587 break;
5588 case BC_LEN:
5589 dasm_put(Dst, 3104, Dt5(->len));
5590#ifdef LUAJIT_ENABLE_LUA52COMPAT
5591 dasm_put(Dst, 3128, Dt6(->metatable));
5592#endif
5593 dasm_put(Dst, 3135);
5594#ifdef LUAJIT_ENABLE_LUA52COMPAT
5595 dasm_put(Dst, 3141, Dt6(->nomm), 1<<MM_len);
5596#endif
5597 break;
5598
5599 /* -- Binary ops -------------------------------------------------------- */
5600
5601
5602 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
5603 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5604 switch (vk) {
5605 case 0:
5606 dasm_put(Dst, 3151);
5607 break;
5608 case 1:
5609 dasm_put(Dst, 3157);
5610 break;
5611 default:
5612 dasm_put(Dst, 3163);
5613 break;
5614 }
5615 dasm_put(Dst, 3170);
5616 break;
5617 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
5618 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5619 switch (vk) {
5620 case 0:
5621 dasm_put(Dst, 3183);
5622 break;
5623 case 1:
5624 dasm_put(Dst, 3189);
5625 break;
5626 default:
5627 dasm_put(Dst, 3195);
5628 break;
5629 }
5630 dasm_put(Dst, 3202);
5631 break;
5632 case BC_MULVN: case BC_MULNV: case BC_MULVV:
5633 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5634 switch (vk) {
5635 case 0:
5636 dasm_put(Dst, 3215);
5637 break;
5638 case 1:
5639 dasm_put(Dst, 3221);
5640 break;
5641 default:
5642 dasm_put(Dst, 3227);
5643 break;
5644 }
5645 dasm_put(Dst, 3234);
5646 break;
5647 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
5648 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5649 switch (vk) {
5650 case 0:
5651 dasm_put(Dst, 3247);
5652 break;
5653 case 1:
5654 dasm_put(Dst, 3253);
5655 break;
5656 default:
5657 dasm_put(Dst, 3259);
5658 break;
5659 }
5660 dasm_put(Dst, 3266);
5661 break;
5662 case BC_MODVN:
5663 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5664 switch (vk) {
5665 case 0:
5666 dasm_put(Dst, 3279);
5667 break;
5668 case 1:
5669 dasm_put(Dst, 3285);
5670 break;
5671 default:
5672 dasm_put(Dst, 3291);
5673 break;
5674 }
5675 dasm_put(Dst, 3298);
5676 break;
5677 case BC_MODNV: case BC_MODVV:
5678 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5679 switch (vk) {
5680 case 0:
5681 dasm_put(Dst, 3316);
5682 break;
5683 case 1:
5684 dasm_put(Dst, 3322);
5685 break;
5686 default:
5687 dasm_put(Dst, 3328);
5688 break;
5689 }
5690 dasm_put(Dst, 3335);
5691 break;
5692 case BC_POW:
5693 dasm_put(Dst, 3338);
5694 break;
5695
5696 case BC_CAT:
5697 dasm_put(Dst, 3360, Dt1(->base), 32-3, Dt1(->base));
5698 break;
5699
5700 /* -- Constant ops ------------------------------------------------------ */
5701
5702 case BC_KSTR:
5703 dasm_put(Dst, 3390, 32-1);
5704 break;
5705 case BC_KCDATA:
5706#if LJ_HASFFI
5707 dasm_put(Dst, 3407, 32-1, LJ_TCDATA);
5708#endif
5709 break;
5710 case BC_KSHORT:
5711 dasm_put(Dst, 3426, 32-3);
5712 break;
5713 case BC_KNUM:
5714 dasm_put(Dst, 3442);
5715 break;
5716 case BC_KPRI:
5717 dasm_put(Dst, 3455, 32-3);
5718 break;
5719 case BC_KNIL:
5720 dasm_put(Dst, 3470);
5721 break;
5722
5723 /* -- Upvalue and function ops ------------------------------------------ */
5724
5725 case BC_UGET:
5726 dasm_put(Dst, 3489, 32-1, offsetof(GCfuncL, uvptr), DtA(->v));
5727 break;
5728 case BC_USETV:
5729 dasm_put(Dst, 3510, 32-1, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, DtA(->closed), -(LJ_TISNUM+1), LJ_TISGCV - (LJ_TISNUM+1), Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
5730 break;
5731 case BC_USETS:
5732 dasm_put(Dst, 3562, 32-1, 32-1, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, Dt5(->marked), DtA(->closed), LJ_GC_WHITES, GG_DISP2G);
5733 break;
5734 case BC_USETN:
5735 dasm_put(Dst, 3611, 32-1, offsetof(GCfuncL, uvptr), DtA(->v));
5736 break;
5737 case BC_USETP:
5738 dasm_put(Dst, 3632, 32-1, offsetof(GCfuncL, uvptr), 32-3, DtA(->v));
5739 break;
5740
5741 case BC_UCLO:
5742 dasm_put(Dst, 3655, Dt1(->openupval), 32-1, -(BCBIAS_J*4 >> 16), Dt1(->base), Dt1(->base));
5743 break;
5744
5745 case BC_FNEW:
5746 dasm_put(Dst, 3685, 32-1, Dt1(->base), Dt1(->base));
5747 break;
5748
5749 /* -- Table ops --------------------------------------------------------- */
5750
5751 case BC_TNEW:
5752 case BC_TDUP:
5753 dasm_put(Dst, 3711, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base));
5754 if (op == BC_TNEW) {
5755 dasm_put(Dst, 3724);
5756 } else {
5757 dasm_put(Dst, 3732, 32-1);
5758 }
5759 dasm_put(Dst, 3739, Dt1(->base));
5760 break;
5761
5762 case BC_GGET:
5763 case BC_GSET:
5764 dasm_put(Dst, 3762, 32-1, Dt7(->env));
5765 if (op == BC_GGET) {
5766 dasm_put(Dst, 3770);
5767 } else {
5768 dasm_put(Dst, 3773);
5769 }
5770 break;
5771
5772 case BC_TGETV:
5773 dasm_put(Dst, 3776, Dt6(->asize), Dt6(->array), 31-3, Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
5774 break;
5775 case BC_TGETS:
5776 dasm_put(Dst, 3834, 32-1, Dt6(->hmask), Dt5(->hash), Dt6(->node), 31-5, 31-3, DtB(->key), DtB(->val), DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
5777 dasm_put(Dst, 3898);
5778 break;
5779 case BC_TGETB:
5780 dasm_put(Dst, 3903, 32-3, Dt6(->asize), Dt6(->array), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
5781 break;
5782
5783 case BC_TSETV:
5784 dasm_put(Dst, 3947, Dt6(->asize), Dt6(->array), 31-3, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex);
5785 dasm_put(Dst, 4014, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
5786 break;
5787 case BC_TSETS:
5788 dasm_put(Dst, 4026, 32-1, Dt6(->hmask), Dt5(->hash), Dt6(->node), Dt6(->nomm), 31-5, 31-3, Dt6(->marked), DtB(->key), DtB(->val), LJ_GC_BLACK, DtB(->val), Dt6(->metatable));
5789 dasm_put(Dst, 4087, Dt6(->nomm), 1<<MM_newindex, DtB(->next), Dt6(->metatable), DISPATCH_GL(tmptv), Dt1(->base), Dt6(->nomm), 1<<MM_newindex, Dt1(->base), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain));
5790 dasm_put(Dst, 4138, Dt6(->marked), Dt6(->gclist));
5791 break;
5792 case BC_TSETB:
5793 dasm_put(Dst, 4145, 32-3, Dt6(->asize), Dt6(->array), Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked));
5794 dasm_put(Dst, 4205, Dt6(->gclist));
5795 break;
5796
5797 case BC_TSETM:
5798 dasm_put(Dst, 4210, 32-3, Dt6(->asize), 31-3, Dt6(->marked), Dt6(->array), LJ_GC_BLACK, Dt1(->base), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
5799 dasm_put(Dst, 4279);
5800 break;
5801
5802 /* -- Calls and vararg handling ----------------------------------------- */
5803
5804 case BC_CALLM:
5805 dasm_put(Dst, 4282);
5806 break;
5807 case BC_CALL:
5808 dasm_put(Dst, 4284, Dt7(->pc));
5809 break;
5810
5811 case BC_CALLMT:
5812 dasm_put(Dst, 4304);
5813 break;
5814 case BC_CALLT:
5815 dasm_put(Dst, 4306, FRAME_TYPE, Dt7(->ffid), FRAME_VARG, Dt7(->pc), -4-8, Dt7(->pc), PC2PROTO(k), FRAME_TYPEP);
5816 dasm_put(Dst, 4371, FRAME_TYPE);
5817 break;
5818
5819 case BC_ITERC:
5820 dasm_put(Dst, 4378, Dt7(->pc));
5821 break;
5822
5823 case BC_ITERN:
5824#if LJ_HASJIT
5825#endif
5826 dasm_put(Dst, 4404, Dt6(->asize), Dt6(->array), 31-3, -(BCBIAS_J*4 >> 16), Dt6(->hmask), Dt6(->node), 31-5, 31-3, DtB(->key), -(BCBIAS_J*4 >> 16));
5827 dasm_put(Dst, 4483);
5828 break;
5829
5830 case BC_ISNEXT:
5831 dasm_put(Dst, 4487, LJ_TTAB, LJ_TFUNC, LJ_TNIL, Dt8(->ffid), FF_next_N, 32-1, -(BCBIAS_J*4 >> 16), BC_JMP, BC_ITERC, -(BCBIAS_J*4 >> 16));
5832 break;
5833
5834 case BC_VARG:
5835 dasm_put(Dst, 4538, FRAME_VARG, Dt1(->maxstack), Dt1(->top), Dt1(->base), 32-3, Dt1(->base));
5836 dasm_put(Dst, 4618);
5837 break;
5838
5839 /* -- Returns ----------------------------------------------------------- */
5840
5841 case BC_RETM:
5842 dasm_put(Dst, 4624);
5843 break;
5844
5845 case BC_RET:
5846 dasm_put(Dst, 4626, FRAME_TYPE, FRAME_VARG, Dt7(->pc), PC2PROTO(k), FRAME_TYPEP);
5847 break;
5848
5849 case BC_RET0: case BC_RET1:
5850 dasm_put(Dst, 4696, FRAME_TYPE, FRAME_VARG);
5851 if (op == BC_RET1) {
5852 dasm_put(Dst, 4709);
5853 }
5854 dasm_put(Dst, 4712, Dt7(->pc), PC2PROTO(k));
5855 break;
5856
5857 /* -- Loops and branches ------------------------------------------------ */
5858
5859 case BC_FORL:
5860#if LJ_HASJIT
5861 dasm_put(Dst, 4740);
5862#endif
5863 break;
5864
5865 case BC_JFORI:
5866 case BC_JFORL:
5867#if !LJ_HASJIT
5868 break;
5869#endif
5870 case BC_FORI:
5871 case BC_IFORL:
5872 vk = (op == BC_IFORL || op == BC_JFORL);
5873 dasm_put(Dst, 4742, FORL_IDX*8, FORL_STEP*8, FORL_STOP*8);
5874 if (!vk) {
5875 dasm_put(Dst, 4750);
5876 }
5877 if (vk) {
5878 dasm_put(Dst, 4758, FORL_IDX*8);
5879 }
5880 dasm_put(Dst, 4762, FORL_EXT*8);
5881 if (op != BC_JFORL) {
5882 dasm_put(Dst, 4770, 32-1);
5883 if (op == BC_JFORI) {
5884 dasm_put(Dst, 4774, -(BCBIAS_J*4 >> 16));
5885 } else {
5886 dasm_put(Dst, 4777, -(BCBIAS_J*4 >> 16));
5887 }
5888 }
5889 if (op == BC_FORI) {
5890 dasm_put(Dst, 4780);
5891 } else if (op == BC_IFORL) {
5892 dasm_put(Dst, 4782);
5893 } else {
5894 dasm_put(Dst, 4784, BC_JLOOP);
5895 }
5896 dasm_put(Dst, 4787);
5897 break;
5898
5899 case BC_ITERL:
5900#if LJ_HASJIT
5901 dasm_put(Dst, 4802);
5902#endif
5903 break;
5904
5905 case BC_JITERL:
5906#if !LJ_HASJIT
5907 break;
5908#endif
5909 case BC_IITERL:
5910 dasm_put(Dst, 4804);
5911 if (op == BC_JITERL) {
5912 dasm_put(Dst, 4810);
5913 } else {
5914 dasm_put(Dst, 4812, 32-1, -(BCBIAS_J*4 >> 16));
5915 }
5916 dasm_put(Dst, 4819);
5917 break;
5918
5919 case BC_LOOP:
5920#if LJ_HASJIT
5921 dasm_put(Dst, 4831);
5922#endif
5923 break;
5924
5925 case BC_ILOOP:
5926 dasm_put(Dst, 4833);
5927 break;
5928
5929 case BC_JLOOP:
5930#if LJ_HASJIT
5931 dasm_put(Dst, 4844);
5932#endif
5933 break;
5934
5935 case BC_JMP:
5936 dasm_put(Dst, 4846, 32-1, -(BCBIAS_J*4 >> 16));
5937 break;
5938
5939 /* -- Function headers -------------------------------------------------- */
5940
5941 case BC_FUNCF:
5942#if LJ_HASJIT
5943 dasm_put(Dst, 4862);
5944#endif
5945 case BC_FUNCV: /* NYI: compiled vararg functions. */
5946 break;
5947
5948 case BC_JFUNCF:
5949#if !LJ_HASJIT
5950 break;
5951#endif
5952 case BC_IFUNCF:
5953 dasm_put(Dst, 4864, Dt1(->maxstack), -4+PC2PROTO(numparams), -4+PC2PROTO(k), 31-3);
5954 if (op == BC_JFUNCF) {
5955 dasm_put(Dst, 4882);
5956 } else {
5957 dasm_put(Dst, 4884);
5958 }
5959 dasm_put(Dst, 4893);
5960 break;
5961
5962 case BC_JFUNCV:
5963#if !LJ_HASJIT
5964 break;
5965#endif
5966 dasm_put(Dst, 4899);
5967 break; /* NYI: compiled vararg functions. */
5968
5969 case BC_IFUNCV:
5970 dasm_put(Dst, 4901, Dt1(->maxstack), 8+FRAME_VARG, -4+PC2PROTO(k), -4+PC2PROTO(numparams));
5971 break;
5972
5973 case BC_FUNCC:
5974 case BC_FUNCCW:
5975 if (op == BC_FUNCC) {
5976 dasm_put(Dst, 4951, Dt8(->f));
5977 } else {
5978 dasm_put(Dst, 4954, DISPATCH_GL(wrapf));
5979 }
5980 dasm_put(Dst, 4957, Dt1(->maxstack), Dt1(->base), Dt1(->top), ~LJ_VMST_C);
5981 if (op == BC_FUNCCW) {
5982 dasm_put(Dst, 4970, Dt8(->f));
5983 }
5984 dasm_put(Dst, 4973, DISPATCH_GL(vmstate), Dt1(->top), 31-3, Dt1(->base), ~LJ_VMST_INTERP, DISPATCH_GL(vmstate));
5985 break;
5986
5987 /* ---------------------------------------------------------------------- */
5988
5989 default:
5990 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
5991 exit(2);
5992 break;
5993 }
5994}
5995
5996static int build_backend(BuildCtx *ctx)
5997{
5998 int op;
5999
6000 dasm_growpc(Dst, BC__MAX);
6001
6002 build_subroutines(ctx);
6003
6004 dasm_put(Dst, 4994);
6005 for (op = 0; op < BC__MAX; op++)
6006 build_ins(ctx, (BCOp)op, op);
6007
6008 return BC__MAX;
6009}
6010
6011/* Emit pseudo frame-info for all assembler functions. */
6012static void emit_asm_debug(BuildCtx *ctx)
6013{
6014 int i;
6015 switch (ctx->mode) {
6016 case BUILD_elfasm:
6017 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
6018 fprintf(ctx->fp,
6019 ".Lframe0:\n"
6020 "\t.long .LECIE0-.LSCIE0\n"
6021 ".LSCIE0:\n"
6022 "\t.long 0xffffffff\n"
6023 "\t.byte 0x1\n"
6024 "\t.string \"\"\n"
6025 "\t.uleb128 0x1\n"
6026 "\t.sleb128 -4\n"
6027 "\t.byte 65\n"
6028 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
6029 "\t.align 2\n"
6030 ".LECIE0:\n\n");
6031 fprintf(ctx->fp,
6032 ".LSFDE0:\n"
6033 "\t.long .LEFDE0-.LASFDE0\n"
6034 ".LASFDE0:\n"
6035 "\t.long .Lframe0\n"
6036 "\t.long .Lbegin\n"
6037 "\t.long %d\n"
6038 "\t.byte 0xe\n\t.uleb128 %d\n"
6039 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
6040 "\t.byte 0x5\n\t.uleb128 70\n\t.sleb128 37\n",
6041 (int)ctx->codesz, CFRAME_SIZE);
6042 for (i = 14; i <= 31; i++)
6043 fprintf(ctx->fp,
6044 "\t.byte %d\n\t.uleb128 %d\n"
6045 "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n",
6046 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i));
6047 fprintf(ctx->fp,
6048 "\t.align 2\n"
6049 ".LEFDE0:\n\n");
6050 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
6051 fprintf(ctx->fp,
6052 ".Lframe1:\n"
6053 "\t.long .LECIE1-.LSCIE1\n"
6054 ".LSCIE1:\n"
6055 "\t.long 0\n"
6056 "\t.byte 0x1\n"
6057 "\t.string \"zPR\"\n"
6058 "\t.uleb128 0x1\n"
6059 "\t.sleb128 -4\n"
6060 "\t.byte 65\n"
6061 "\t.uleb128 6\n" /* augmentation length */
6062 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6063 "\t.long lj_err_unwind_dwarf-.\n"
6064 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6065 "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n"
6066 "\t.align 2\n"
6067 ".LECIE1:\n\n");
6068 fprintf(ctx->fp,
6069 ".LSFDE1:\n"
6070 "\t.long .LEFDE1-.LASFDE1\n"
6071 ".LASFDE1:\n"
6072 "\t.long .LASFDE1-.Lframe1\n"
6073 "\t.long .Lbegin-.\n"
6074 "\t.long %d\n"
6075 "\t.uleb128 0\n" /* augmentation length */
6076 "\t.byte 0xe\n\t.uleb128 %d\n"
6077 "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n"
6078 "\t.byte 0x5\n\t.uleb128 70\n\t.sleb128 37\n",
6079 (int)ctx->codesz, CFRAME_SIZE);
6080 for (i = 14; i <= 31; i++)
6081 fprintf(ctx->fp,
6082 "\t.byte %d\n\t.uleb128 %d\n"
6083 "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n",
6084 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i));
6085 fprintf(ctx->fp,
6086 "\t.align 2\n"
6087 ".LEFDE1:\n\n");
6088 break;
6089 default:
6090 break;
6091 }
6092}
6093
diff --git a/libraries/luajit-2.0/src/buildvm_x64.h b/libraries/luajit-2.0/src/buildvm_x64.h
new file mode 100644
index 0000000..55b22b2
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_x64.h
@@ -0,0 +1,3406 @@
1/*
2** This file has been pre-processed with DynASM.
3** http://luajit.org/dynasm.html
4** DynASM version 1.3.0, DynASM x64 version 1.3.0
5** DO NOT EDIT! The original file is in "buildvm_x86.dasc".
6*/
7
8#if DASM_VERSION != 10300
9#error "Version mismatch between DynASM and included encoding engine"
10#endif
11
12#define DASM_SECTION_CODE_OP 0
13#define DASM_SECTION_CODE_SUB 1
14#define DASM_MAXSECTION 2
15static const unsigned char build_actionlist[16378] = {
16 254,1,248,10,252,247,195,237,15,132,244,11,131,227,252,248,41,218,72,141,
17 76,25,252,248,139,90,252,252,199,68,10,4,237,248,12,131,192,1,137,68,36,4,
18 252,247,195,237,15,132,244,13,248,14,129,252,243,239,252,247,195,237,15,133,
19 244,10,65,199,134,233,237,131,227,252,248,41,211,252,247,219,131,232,1,15,
20 132,244,248,248,1,72,139,44,10,72,137,106,252,248,131,194,8,131,232,1,15,
21 133,244,1,248,2,255,139,108,36,24,137,157,233,248,3,139,68,36,4,139,76,36,
22 16,248,4,57,193,15,133,244,252,248,5,131,252,234,8,137,149,233,248,15,72,
23 139,76,36,32,72,137,141,233,49,192,248,16,72,131,196,40,65,94,65,95,91,93,
24 195,248,6,15,130,244,253,59,149,233,15,135,244,254,199,66,252,252,237,131,
25 194,8,131,192,1,252,233,244,4,248,7,255,133,201,15,132,244,5,41,193,141,20,
26 202,252,233,244,5,248,8,137,149,233,137,68,36,4,137,206,137,252,239,232,251,
27 1,0,139,149,233,252,233,244,3,248,17,137,252,240,72,137,252,252,248,18,139,
28 108,36,24,139,173,233,199,133,233,237,252,233,244,16,248,19,139,124,36,24,
29 137,198,72,131,196,40,65,94,65,95,91,93,252,233,251,1,1,248,20,72,129,231,
30 239,72,137,252,252,248,21,255,139,108,36,24,72,199,193,252,248,252,255,252,
31 255,252,255,184,237,139,149,233,68,139,181,233,65,129,198,239,139,90,252,
32 252,199,66,252,252,237,65,199,134,233,237,252,233,244,12,248,22,190,237,252,
33 233,244,248,248,23,131,232,8,252,233,244,247,248,24,141,68,194,252,248,248,
34 1,15,182,139,233,131,195,4,137,149,233,255,137,133,233,137,92,36,28,137,206,
35 248,2,137,252,239,232,251,1,0,139,149,233,139,133,233,139,106,252,248,41,
36 208,193,232,3,131,192,1,139,157,233,139,11,15,182,252,233,15,182,205,131,
37 195,4,65,252,255,36,252,238,248,25,85,83,65,87,65,86,72,131,252,236,40,137,
38 252,253,137,124,36,24,137,252,241,187,237,49,192,76,141,188,253,36,233,68,
39 139,181,233,65,129,198,239,76,137,189,233,137,68,36,28,72,137,68,36,32,137,
40 68,36,16,137,68,36,20,56,133,233,15,132,244,249,65,199,134,233,237,136,133,
41 233,139,149,233,139,133,233,41,200,193,232,3,131,192,1,41,209,139,90,252,
42 252,137,68,36,4,252,247,195,237,255,15,132,244,13,252,233,244,14,248,26,85,
43 83,65,87,65,86,72,131,252,236,40,187,237,137,76,36,20,252,233,244,247,248,
44 27,85,83,65,87,65,86,72,131,252,236,40,187,237,248,1,137,84,36,16,137,252,
45 253,137,124,36,24,137,252,241,76,139,189,233,76,137,124,36,32,137,108,36,
46 28,72,137,165,233,248,2,68,139,181,233,65,129,198,239,248,3,65,199,134,233,
47 237,139,149,233,255,1,203,41,211,139,133,233,41,200,193,232,3,131,192,1,248,
48 28,139,105,252,248,129,121,253,252,252,239,15,133,244,29,248,30,137,202,137,
49 90,252,252,139,157,233,139,11,15,182,252,233,15,182,205,131,195,4,65,252,
50 255,36,252,238,248,31,85,83,65,87,65,86,72,131,252,236,40,137,252,253,137,
51 124,36,24,137,108,36,28,68,139,189,233,68,43,189,233,199,68,36,20,0,0,0,0,
52 68,137,124,36,16,76,139,189,233,76,137,124,36,32,72,137,165,233,252,255,209,
53 133,192,15,132,244,15,137,193,187,237,252,233,244,2,248,11,1,209,131,227,
54 252,248,137,213,41,218,199,68,193,252,252,237,137,200,139,93,252,244,72,99,
55 77,252,240,255,131,252,249,1,15,134,244,247,255,76,141,61,245,76,1,252,249,
56 255,68,139,122,252,248,69,139,191,233,69,139,191,233,252,255,225,255,248,
57 1,15,132,244,32,41,213,193,252,237,3,141,69,252,255,252,233,244,33,255,248,
58 34,15,182,75,252,255,131,252,237,16,141,12,202,41,252,233,15,132,244,35,252,
59 247,217,193,252,233,3,139,124,36,24,137,151,233,137,202,72,139,8,72,137,77,
60 0,137,252,238,252,233,244,36,248,37,137,4,36,199,68,36,4,237,72,141,4,36,
61 128,123,252,252,235,15,133,244,247,65,141,142,233,137,41,199,65,4,237,137,
62 205,252,233,244,248,248,38,15,182,67,252,254,255,199,68,36,4,237,137,4,36,
63 255,252,242,15,42,192,252,242,15,17,4,36,255,72,141,4,36,252,233,244,247,
64 248,39,15,182,67,252,254,141,4,194,248,1,15,182,107,252,255,141,44,252,234,
65 248,2,139,124,36,24,137,151,233,137,252,238,72,137,194,137,252,253,137,92,
66 36,28,232,251,1,2,139,149,233,133,192,15,132,244,249,248,35,15,182,75,252,
67 253,72,139,40,72,137,44,202,139,3,15,182,204,15,182,232,131,195,4,193,232,
68 16,65,252,255,36,252,238,248,3,139,141,233,137,89,252,244,141,153,233,41,
69 211,139,105,252,248,184,237,252,233,244,30,248,40,137,4,36,199,68,36,4,237,
70 72,141,4,36,128,123,252,252,235,15,133,244,247,255,65,141,142,233,137,41,
71 199,65,4,237,137,205,252,233,244,248,248,41,15,182,67,252,254,255,72,141,
72 4,36,252,233,244,247,248,42,15,182,67,252,254,141,4,194,248,1,15,182,107,
73 252,255,141,44,252,234,248,2,139,124,36,24,137,151,233,137,252,238,72,137,
74 194,137,252,253,137,92,36,28,232,251,1,3,139,149,233,133,192,15,132,244,249,
75 15,182,75,252,253,72,139,44,202,72,137,40,248,43,139,3,15,182,204,15,182,
76 232,131,195,4,193,232,16,65,252,255,36,252,238,248,3,139,141,233,137,89,252,
77 244,15,182,67,252,253,72,139,44,194,72,137,105,16,141,153,233,41,211,139,
78 105,252,248,184,237,252,233,244,30,248,44,139,108,36,24,137,149,233,141,52,
79 202,141,20,194,137,252,239,15,182,75,252,252,137,92,36,28,232,251,1,4,248,
80 3,139,149,233,255,131,252,248,1,15,135,244,45,248,4,141,91,4,15,130,244,252,
81 248,5,15,183,67,252,254,141,156,253,131,233,248,6,139,3,15,182,204,15,182,
82 232,131,195,4,193,232,16,65,252,255,36,252,238,248,46,131,195,4,129,120,253,
83 4,239,15,130,244,5,252,233,244,6,248,47,129,120,253,4,239,252,233,244,4,248,
84 48,131,252,235,4,137,206,137,252,233,139,108,36,24,137,149,233,255,137,194,
85 137,252,239,137,92,36,28,232,251,1,5,252,233,244,3,248,49,255,131,252,235,
86 4,139,108,36,24,137,149,233,137,252,239,139,115,252,252,137,92,36,28,232,
87 251,1,6,252,233,244,3,255,248,50,255,15,182,107,252,255,255,248,51,65,141,
88 4,199,252,233,244,247,248,52,255,248,53,65,141,4,199,141,44,252,234,149,252,
89 233,244,248,248,54,141,4,194,137,197,252,233,244,248,248,55,255,248,56,141,
90 4,194,248,1,141,44,252,234,248,2,141,12,202,68,15,182,67,252,252,137,206,
91 137,193,139,124,36,24,137,151,233,137,252,234,137,252,253,137,92,36,28,232,
92 251,1,7,139,149,233,133,192,15,132,244,43,248,45,137,193,41,208,137,89,252,
93 244,141,152,233,184,237,252,233,244,28,248,57,139,108,36,24,137,149,233,141,
94 52,194,137,252,239,137,92,36,28,232,251,1,8,139,149,233,255,133,192,15,133,
95 244,45,15,183,67,252,254,139,60,194,252,233,244,58,255,252,233,244,45,255,
96 248,59,141,76,202,8,248,29,137,76,36,4,137,4,36,131,252,233,8,139,108,36,
97 24,137,149,233,137,206,141,20,193,137,252,239,137,92,36,28,232,251,1,9,139,
98 149,233,139,76,36,4,139,4,36,139,105,252,248,131,192,1,65,57,215,15,132,244,
99 60,137,202,137,90,252,252,139,157,233,139,11,15,182,252,233,15,182,205,131,
100 195,4,65,252,255,36,252,238,248,61,139,108,36,24,137,149,233,137,206,137,
101 252,239,137,92,36,28,232,251,1,10,139,149,233,139,67,252,252,15,182,204,15,
102 182,232,193,232,16,65,252,255,164,253,252,238,233,248,62,129,252,248,239,
103 15,130,244,63,139,106,4,129,252,253,239,15,131,244,63,139,90,252,252,137,
104 68,36,4,137,106,252,252,139,42,137,106,252,248,131,232,2,15,132,244,248,255,
105 137,209,248,1,131,193,8,72,139,41,72,137,105,252,248,131,232,1,15,133,244,
106 1,248,2,139,68,36,4,252,233,244,64,248,65,129,252,248,239,15,130,244,63,139,
107 106,4,137,252,233,193,252,249,15,131,252,249,252,254,15,132,244,249,184,237,
108 252,247,213,57,232,255,15,71,197,255,15,134,244,247,137,232,248,1,255,248,
109 2,139,106,252,248,139,132,253,197,233,139,90,252,252,199,66,252,252,237,137,
110 66,252,248,252,233,244,66,248,3,184,237,252,233,244,2,248,67,129,252,248,
111 239,15,130,244,63,139,106,4,139,90,252,252,129,252,253,239,15,133,244,252,
112 248,1,139,42,139,173,233,248,2,133,252,237,199,66,252,252,237,255,15,132,
113 244,66,65,139,134,233,199,66,252,252,237,137,106,252,248,139,141,233,35,136,
114 233,105,201,239,3,141,233,248,3,129,185,233,239,15,133,244,250,57,129,233,
115 15,132,244,251,248,4,139,137,233,133,201,15,133,244,3,255,252,233,244,66,
116 248,5,139,105,4,129,252,253,239,15,132,244,66,139,1,137,106,252,252,137,66,
117 252,248,252,233,244,66,248,6,129,252,253,239,15,132,244,1,129,252,253,239,
118 15,135,244,254,129,252,253,239,15,134,244,253,189,237,252,233,244,254,248,
119 7,255,189,237,248,8,252,247,213,65,139,172,253,174,233,252,233,244,2,248,
120 68,129,252,248,239,15,130,244,63,129,122,253,4,239,15,133,244,63,139,42,131,
121 189,233,0,15,133,244,63,129,122,253,12,239,15,133,244,63,139,66,8,137,133,
122 233,139,90,252,252,199,66,252,252,237,255,137,106,252,248,252,246,133,233,
123 235,15,132,244,247,128,165,233,235,65,139,134,233,65,137,174,233,137,133,
124 233,248,1,252,233,244,66,248,69,129,252,248,239,15,130,244,63,129,122,253,
125 4,239,15,133,244,63,137,213,139,50,141,82,8,139,124,36,24,232,251,1,11,137,
126 252,234,72,139,40,139,90,252,252,72,137,106,252,248,252,233,244,66,248,70,
127 255,129,252,248,239,15,133,244,63,129,122,253,4,239,255,15,133,244,247,139,
128 42,252,233,244,71,248,1,15,135,244,63,255,15,131,244,63,255,252,242,15,16,
129 2,252,233,244,72,255,221,2,252,233,244,73,255,248,74,129,252,248,239,15,130,
130 244,63,139,90,252,252,129,122,253,4,239,15,133,244,249,139,2,248,2,199,66,
131 252,252,237,137,66,252,248,252,233,244,66,248,3,129,122,253,4,239,15,135,
132 244,63,65,131,190,233,0,15,133,244,63,65,139,174,233,65,59,174,233,255,15,
133 130,244,247,232,244,75,248,1,139,108,36,24,137,149,233,137,92,36,28,137,214,
134 137,252,239,255,232,251,1,12,255,232,251,1,13,255,139,149,233,252,233,244,
135 2,248,76,129,252,248,239,15,130,244,63,15,132,244,248,248,1,129,122,253,4,
136 239,15,133,244,63,139,108,36,24,137,149,233,137,149,233,139,90,252,252,139,
137 50,141,82,8,137,252,239,137,92,36,28,232,251,1,14,139,149,233,133,192,15,
138 132,244,249,72,139,106,8,72,139,66,16,72,137,106,252,248,72,137,2,248,77,
139 184,237,255,252,233,244,78,248,2,199,66,12,237,252,233,244,1,248,3,199,66,
140 252,252,237,252,233,244,66,248,79,129,252,248,239,15,130,244,63,139,42,129,
141 122,253,4,239,15,133,244,63,255,131,189,233,0,15,133,244,63,255,139,106,252,
142 248,139,133,233,139,90,252,252,199,66,252,252,237,137,66,252,248,199,66,12,
143 237,184,237,252,233,244,78,248,80,129,252,248,239,15,130,244,63,129,122,253,
144 4,239,15,133,244,63,129,122,253,12,239,255,139,90,252,252,255,139,66,8,131,
145 192,1,199,66,252,252,237,137,66,252,248,255,252,242,15,16,66,8,72,189,237,
146 237,102,72,15,110,205,252,242,15,88,193,252,242,15,45,192,252,242,15,17,66,
147 252,248,255,139,42,59,133,233,15,131,244,248,193,224,3,3,133,233,248,1,129,
148 120,253,4,239,15,132,244,81,72,139,40,72,137,42,252,233,244,77,248,2,131,
149 189,233,0,15,132,244,81,137,252,239,137,213,137,198,232,251,1,15,137,252,
150 234,133,192,15,133,244,1,248,81,184,237,252,233,244,78,248,82,255,139,106,
151 252,248,139,133,233,139,90,252,252,199,66,252,252,237,137,66,252,248,255,
152 199,66,12,237,199,66,8,0,0,0,0,255,15,87,192,252,242,15,17,66,8,255,217,252,
153 238,221,90,8,255,184,237,252,233,244,78,248,83,129,252,248,239,15,130,244,
154 63,141,74,8,131,232,1,187,237,248,1,65,15,182,174,233,193,252,237,235,131,
155 229,1,1,252,235,252,233,244,28,248,84,129,252,248,239,15,130,244,63,129,122,
156 253,12,239,15,133,244,63,255,139,106,4,137,106,12,199,66,4,237,139,42,139,
157 90,8,137,106,8,137,26,141,74,16,131,232,2,187,237,252,233,244,1,248,85,129,
158 252,248,239,15,130,244,63,139,42,139,90,252,252,137,92,36,28,137,44,36,129,
159 122,253,4,239,15,133,244,63,72,131,189,233,0,15,133,244,63,128,189,233,235,
160 15,135,244,63,139,141,233,15,132,244,247,255,59,141,233,15,132,244,63,248,
161 1,141,92,193,252,240,59,157,233,15,135,244,63,137,157,233,139,108,36,24,137,
162 149,233,131,194,8,137,149,233,141,108,194,232,72,41,221,57,203,15,132,244,
163 249,248,2,72,139,4,43,72,137,67,252,248,131,252,235,8,57,203,15,133,244,2,
164 248,3,137,206,139,60,36,232,244,25,65,199,134,233,237,255,139,108,36,24,139,
165 28,36,139,149,233,129,252,248,239,15,135,244,254,248,4,139,139,233,68,139,
166 187,233,137,139,233,68,137,252,251,41,203,15,132,244,252,141,4,26,193,252,
167 235,3,59,133,233,15,135,244,255,137,213,72,41,205,248,5,72,139,1,72,137,4,
168 41,131,193,8,68,57,252,249,15,133,244,5,248,6,141,67,2,199,66,252,252,237,
169 248,7,139,92,36,28,137,68,36,4,72,199,193,252,248,252,255,252,255,252,255,
170 252,247,195,237,255,15,132,244,13,252,233,244,14,248,8,199,66,252,252,237,
171 139,139,233,131,252,233,8,137,139,233,72,139,1,72,137,2,184,237,252,233,244,
172 7,248,9,139,12,36,68,137,185,233,137,222,137,252,239,232,251,1,0,139,28,36,
173 139,149,233,252,233,244,4,248,86,139,106,252,248,139,173,233,139,90,252,252,
174 137,92,36,28,137,44,36,72,131,189,233,0,15,133,244,63,255,128,189,233,235,
175 15,135,244,63,139,141,233,15,132,244,247,59,141,233,15,132,244,63,248,1,141,
176 92,193,252,248,59,157,233,15,135,244,63,137,157,233,139,108,36,24,137,149,
177 233,137,149,233,141,108,194,252,240,72,41,221,57,203,15,132,244,249,248,2,
178 255,72,139,4,43,72,137,67,252,248,131,252,235,8,57,203,15,133,244,2,248,3,
179 137,206,139,60,36,232,244,25,65,199,134,233,237,139,108,36,24,139,28,36,139,
180 149,233,129,252,248,239,15,135,244,254,248,4,139,139,233,68,139,187,233,137,
181 139,233,68,137,252,251,41,203,15,132,244,252,141,4,26,193,252,235,3,59,133,
182 233,15,135,244,255,255,137,213,72,41,205,248,5,72,139,1,72,137,4,41,131,193,
183 8,68,57,252,249,15,133,244,5,248,6,141,67,1,248,7,139,92,36,28,137,68,36,
184 4,49,201,252,247,195,237,15,132,244,13,252,233,244,14,248,8,137,222,137,252,
185 239,232,251,1,16,248,9,139,12,36,68,137,185,233,137,222,137,252,239,232,251,
186 1,0,139,28,36,139,149,233,252,233,244,4,248,87,139,108,36,24,72,252,247,133,
187 233,237,15,132,244,63,255,137,149,233,141,68,194,252,248,137,133,233,49,192,
188 72,137,133,233,176,235,136,133,233,252,233,244,16,255,248,71,255,248,73,139,
189 90,252,252,221,90,252,248,252,233,244,66,255,248,88,129,252,248,239,15,130,
190 244,63,255,129,122,253,4,239,15,133,244,248,139,42,131,252,253,0,15,137,244,
191 71,252,247,221,15,136,244,247,248,89,248,71,139,90,252,252,199,66,252,252,
192 237,137,106,252,248,252,233,244,66,248,1,139,90,252,252,199,66,252,252,0,
193 0,224,65,199,66,252,248,0,0,0,0,252,233,244,66,248,2,15,135,244,63,255,129,
194 122,253,4,239,15,131,244,63,255,252,242,15,16,2,72,184,237,237,102,72,15,
195 110,200,15,84,193,248,72,139,90,252,252,252,242,15,17,66,252,248,255,221,
196 2,217,225,248,72,248,73,139,90,252,252,221,90,252,248,255,248,66,184,237,
197 248,78,137,68,36,4,248,64,252,247,195,237,15,133,244,253,248,5,56,67,252,
198 255,15,135,244,252,15,182,75,252,253,72,252,247,209,141,20,202,139,3,15,182,
199 204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,6,199,68,194,
200 252,244,237,131,192,1,252,233,244,5,248,7,72,199,193,252,248,252,255,252,
201 255,252,255,252,233,244,14,248,90,255,129,122,253,4,239,15,133,244,247,139,
202 42,252,233,244,71,248,1,15,135,244,63,255,252,242,15,16,2,232,244,91,255,
203 252,242,15,45,232,129,252,253,0,0,0,128,15,133,244,71,252,242,15,42,205,102,
204 15,46,193,15,138,244,72,15,132,244,71,255,221,2,232,244,91,255,248,92,255,
205 252,242,15,16,2,232,244,93,255,221,2,232,244,93,255,248,94,129,252,248,239,
206 15,130,244,63,129,122,253,4,239,15,131,244,63,252,242,15,81,2,252,233,244,
207 72,255,248,94,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,
208 63,221,2,217,252,250,252,233,244,73,255,248,95,129,252,248,239,15,130,244,
209 63,129,122,253,4,239,15,131,244,63,217,252,237,221,2,217,252,241,252,233,
210 244,73,248,96,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,
211 63,217,252,236,221,2,217,252,241,252,233,244,73,248,97,129,252,248,239,255,
212 15,130,244,63,129,122,253,4,239,15,131,244,63,221,2,232,244,98,252,233,244,
213 73,248,99,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,221,
214 2,217,252,254,252,233,244,73,248,100,129,252,248,239,255,15,130,244,63,129,
215 122,253,4,239,15,131,244,63,221,2,217,252,255,252,233,244,73,248,101,129,
216 252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,221,2,217,252,242,
217 221,216,252,233,244,73,248,102,129,252,248,239,15,130,244,63,255,129,122,
218 253,4,239,15,131,244,63,221,2,217,192,216,200,217,232,222,225,217,252,250,
219 217,252,243,252,233,244,73,248,103,129,252,248,239,15,130,244,63,129,122,
220 253,4,239,15,131,244,63,221,2,217,192,216,200,217,232,222,225,217,252,250,
221 217,201,217,252,243,252,233,244,73,248,104,129,252,248,239,15,130,244,63,
222 129,122,253,4,239,15,131,244,63,255,221,2,217,232,217,252,243,252,233,244,
223 73,255,248,105,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,
224 63,252,242,15,16,2,255,137,213,232,251,1,17,137,252,234,252,233,244,72,255,
225 248,106,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,252,
226 242,15,16,2,255,137,213,232,251,1,18,137,252,234,252,233,244,72,255,248,107,
227 129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,252,242,15,
228 16,2,255,137,213,232,251,1,19,137,252,234,252,233,244,72,248,108,255,248,
229 109,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,252,242,
230 15,16,2,139,106,252,248,252,242,15,89,133,233,252,233,244,72,255,248,109,
231 129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,221,2,139,106,
232 252,248,220,141,233,252,233,244,73,255,248,110,129,252,248,239,15,130,244,
233 63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,63,221,2,
234 221,66,8,217,252,243,252,233,244,73,248,111,129,252,248,239,15,130,244,63,
235 129,122,253,4,239,15,131,244,63,129,122,253,12,239,255,15,131,244,63,221,
236 66,8,221,2,217,252,253,221,217,252,233,244,73,248,112,129,252,248,239,15,
237 130,244,63,139,106,4,129,252,253,239,15,131,244,63,139,90,252,252,139,2,137,
238 106,252,252,137,66,252,248,209,229,129,252,253,0,0,224,252,255,15,131,244,
239 249,9,232,15,132,244,249,184,252,254,3,0,0,129,252,253,0,0,32,0,15,130,244,
240 250,248,1,193,252,237,21,41,197,255,252,242,15,42,197,255,137,44,36,219,4,
241 36,255,139,106,252,252,129,229,252,255,252,255,15,128,129,205,0,0,224,63,
242 137,106,252,252,248,2,255,252,242,15,17,2,255,221,26,255,184,237,252,233,
243 244,78,248,3,255,15,87,192,252,233,244,2,255,217,252,238,252,233,244,2,255,
244 248,4,255,252,242,15,16,2,72,189,237,237,102,72,15,110,205,252,242,15,89,
245 193,252,242,15,17,66,252,248,255,221,2,199,4,36,0,0,128,90,216,12,36,221,
246 90,252,248,255,139,106,252,252,184,52,4,0,0,209,229,252,233,244,1,255,248,
247 113,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,252,242,
248 15,16,2,255,248,113,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,
249 244,63,221,2,255,139,106,4,139,90,252,252,209,229,129,252,253,0,0,224,252,
250 255,15,132,244,250,255,15,40,224,232,244,114,252,242,15,92,224,248,1,252,
251 242,15,17,66,252,248,252,242,15,17,34,255,217,192,232,244,114,220,252,233,
252 248,1,221,90,252,248,221,26,255,139,66,252,252,139,106,4,49,232,15,136,244,
253 249,248,2,184,237,252,233,244,78,248,3,129,252,245,0,0,0,128,137,106,4,252,
254 233,244,2,248,4,255,15,87,228,252,233,244,1,255,217,252,238,217,201,252,233,
255 244,1,255,248,115,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,
256 244,63,129,122,253,12,239,15,131,244,63,221,66,8,221,2,248,1,217,252,248,
257 223,224,158,15,138,244,1,221,217,252,233,244,73,255,248,116,129,252,248,239,
258 15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
259 63,252,242,15,16,2,252,242,15,16,74,8,232,244,117,252,233,244,72,255,248,
260 116,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,
261 253,12,239,15,131,244,63,221,2,221,66,8,232,244,117,252,233,244,73,255,248,
262 118,185,2,0,0,0,129,122,253,4,239,255,15,133,244,250,139,42,248,1,57,193,
263 15,131,244,71,129,124,253,202,252,252,239,15,133,244,249,59,108,202,252,248,
264 15,79,108,202,252,248,131,193,1,252,233,244,1,248,3,15,135,244,63,255,252,
265 233,244,252,248,4,15,135,244,63,255,252,242,15,16,2,248,5,57,193,15,131,244,
266 72,129,124,253,202,252,252,239,255,15,130,244,252,15,135,244,63,252,242,15,
267 42,76,202,252,248,252,233,244,253,255,248,6,252,242,15,16,76,202,252,248,
268 248,7,252,242,15,93,193,131,193,1,252,233,244,5,255,248,119,185,2,0,0,0,129,
269 122,253,4,239,255,15,133,244,250,139,42,248,1,57,193,15,131,244,71,129,124,
270 253,202,252,252,239,15,133,244,249,59,108,202,252,248,15,76,108,202,252,248,
271 131,193,1,252,233,244,1,248,3,15,135,244,63,255,248,6,252,242,15,16,76,202,
272 252,248,248,7,252,242,15,95,193,131,193,1,252,233,244,5,255,248,9,221,216,
273 252,233,244,63,255,248,120,129,252,248,239,15,130,244,63,129,122,253,4,239,
274 15,133,244,63,139,42,255,139,173,233,252,233,244,71,255,252,242,15,42,133,
275 233,252,233,244,72,255,219,133,233,252,233,244,73,255,248,121,129,252,248,
276 239,15,133,244,63,129,122,253,4,239,15,133,244,63,139,42,139,90,252,252,131,
277 189,233,1,15,130,244,81,15,182,173,233,255,252,242,15,42,197,252,233,244,
278 72,255,137,44,36,219,4,36,252,233,244,73,255,248,122,65,139,174,233,65,59,
279 174,233,15,130,244,247,232,244,75,248,1,129,252,248,239,15,133,244,63,129,
280 122,253,4,239,255,15,133,244,63,139,42,129,252,253,252,255,0,0,0,15,135,244,
281 63,137,108,36,4,255,15,131,244,63,252,242,15,44,42,129,252,253,252,255,0,
282 0,0,15,135,244,63,137,108,36,4,255,15,131,244,63,221,2,219,92,36,4,129,124,
283 36,4,252,255,0,0,0,15,135,244,63,255,199,68,36,8,1,0,0,0,72,141,68,36,4,248,
284 123,139,108,36,24,137,149,233,139,84,36,8,72,137,198,137,252,239,137,92,36,
285 28,232,251,1,20,139,149,233,139,90,252,252,199,66,252,252,237,137,66,252,
286 248,252,233,244,66,248,124,65,139,174,233,65,59,174,233,15,130,244,247,232,
287 244,75,248,1,199,68,36,4,252,255,252,255,252,255,252,255,129,252,248,239,
288 15,130,244,63,15,134,244,247,129,122,253,20,239,255,15,133,244,63,139,106,
289 16,137,108,36,4,255,15,131,244,63,252,242,15,44,106,16,137,108,36,4,255,15,
290 131,244,63,221,66,16,219,92,36,4,255,248,1,129,122,253,4,239,15,133,244,63,
291 129,122,253,12,239,255,139,42,137,108,36,8,139,173,233,255,139,74,8,255,252,
292 242,15,44,74,8,255,139,68,36,4,57,197,15,130,244,251,248,2,133,201,15,142,
293 244,253,248,3,139,108,36,8,41,200,15,140,244,125,141,172,253,13,233,131,192,
294 1,248,4,137,68,36,8,137,232,252,233,244,123,248,5,15,140,244,252,141,68,40,
295 1,252,233,244,2,248,6,137,232,252,233,244,2,248,7,255,15,132,244,254,1,252,
296 233,131,193,1,15,143,244,3,248,8,185,1,0,0,0,252,233,244,3,248,125,49,192,
297 252,233,244,4,248,126,129,252,248,239,15,130,244,63,65,139,174,233,65,59,
298 174,233,15,130,244,247,232,244,75,248,1,255,129,122,253,4,239,15,133,244,
299 63,129,122,253,12,239,139,42,255,15,133,244,63,139,66,8,255,15,131,244,63,
300 252,242,15,44,66,8,255,15,131,244,63,221,66,8,219,92,36,4,139,68,36,4,255,
301 133,192,15,142,244,125,131,189,233,1,15,130,244,125,15,133,244,127,65,57,
302 134,233,15,130,244,127,15,182,141,233,65,139,174,233,137,68,36,8,248,1,136,
303 77,0,131,197,1,131,232,1,15,133,244,1,65,139,134,233,252,233,244,123,248,
304 128,129,252,248,239,255,15,130,244,63,65,139,174,233,65,59,174,233,15,130,
305 244,247,232,244,75,248,1,129,122,253,4,239,15,133,244,63,139,42,139,133,233,
306 133,192,15,132,244,125,65,57,134,233,15,130,244,129,129,197,239,137,92,36,
307 4,137,68,36,8,65,139,158,233,248,1,255,15,182,77,0,131,197,1,131,232,1,136,
308 12,3,15,133,244,1,137,216,139,92,36,4,252,233,244,123,248,130,129,252,248,
309 239,15,130,244,63,65,139,174,233,65,59,174,233,15,130,244,247,232,244,75,
310 248,1,129,122,253,4,239,15,133,244,63,139,42,139,133,233,65,57,134,233,255,
311 15,130,244,129,129,197,239,137,92,36,4,137,68,36,8,65,139,158,233,252,233,
312 244,249,248,1,15,182,76,5,0,131,252,249,65,15,130,244,248,131,252,249,90,
313 15,135,244,248,131,252,241,32,248,2,136,12,3,248,3,131,232,1,15,137,244,1,
314 137,216,139,92,36,4,252,233,244,123,248,131,129,252,248,239,15,130,244,63,
315 255,65,139,174,233,65,59,174,233,15,130,244,247,232,244,75,248,1,129,122,
316 253,4,239,15,133,244,63,139,42,139,133,233,65,57,134,233,15,130,244,129,129,
317 197,239,137,92,36,4,137,68,36,8,65,139,158,233,252,233,244,249,248,1,15,182,
318 76,5,0,131,252,249,97,15,130,244,248,255,131,252,249,122,15,135,244,248,131,
319 252,241,32,248,2,136,12,3,248,3,131,232,1,15,137,244,1,137,216,139,92,36,
320 4,252,233,244,123,248,132,129,252,248,239,15,130,244,63,129,122,253,4,239,
321 15,133,244,63,137,213,139,58,232,251,1,21,137,252,234,255,137,197,252,233,
322 244,71,255,252,242,15,42,192,252,233,244,72,255,248,133,129,252,248,239,15,
323 130,244,63,129,122,253,4,239,255,15,133,244,247,139,42,252,233,244,89,248,
324 1,15,135,244,63,255,252,242,15,16,2,72,189,237,237,102,72,15,110,205,252,
325 242,15,88,193,102,15,126,197,255,252,233,244,89,255,248,134,129,252,248,239,
326 15,130,244,63,255,72,189,237,237,102,72,15,110,205,255,199,4,36,0,0,192,89,
327 255,15,133,244,247,139,42,252,233,244,248,248,1,15,135,244,63,255,252,242,
328 15,16,2,252,242,15,88,193,102,15,126,197,255,248,2,137,68,36,4,141,68,194,
329 252,240,248,1,57,208,15,134,244,89,129,120,253,4,239,255,15,133,244,248,35,
330 40,131,232,8,252,233,244,1,248,2,15,135,244,135,255,15,131,244,135,255,252,
331 242,15,16,0,252,242,15,88,193,102,15,126,193,33,205,255,131,232,8,252,233,
332 244,1,248,136,129,252,248,239,15,130,244,63,255,15,133,244,248,11,40,131,
333 232,8,252,233,244,1,248,2,15,135,244,135,255,252,242,15,16,0,252,242,15,88,
334 193,102,15,126,193,9,205,255,131,232,8,252,233,244,1,248,137,129,252,248,
335 239,15,130,244,63,255,15,133,244,248,51,40,131,232,8,252,233,244,1,248,2,
336 15,135,244,135,255,252,242,15,16,0,252,242,15,88,193,102,15,126,193,49,205,
337 255,131,232,8,252,233,244,1,248,138,129,252,248,239,15,130,244,63,129,122,
338 253,4,239,255,248,2,15,205,252,233,244,89,248,139,129,252,248,239,15,130,
339 244,63,129,122,253,4,239,255,248,2,252,247,213,255,248,89,252,242,15,42,197,
340 252,233,244,72,255,248,135,139,68,36,4,252,233,244,63,255,248,140,129,252,
341 248,239,15,130,244,63,129,122,253,4,239,255,248,2,129,122,253,12,239,15,133,
342 244,63,139,74,8,255,248,140,129,252,248,239,15,130,244,63,129,122,253,4,239,
343 15,131,244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,15,
344 16,74,8,72,189,237,237,102,72,15,110,213,252,242,15,88,194,252,242,15,88,
345 202,102,15,126,197,102,15,126,201,255,211,229,252,233,244,89,255,248,141,
346 129,252,248,239,15,130,244,63,129,122,253,4,239,255,248,141,129,252,248,239,
347 15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
348 63,252,242,15,16,2,252,242,15,16,74,8,72,189,237,237,102,72,15,110,213,252,
349 242,15,88,194,252,242,15,88,202,102,15,126,197,102,15,126,201,255,211,252,
350 237,252,233,244,89,255,248,142,129,252,248,239,15,130,244,63,129,122,253,
351 4,239,255,248,142,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,
352 244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,15,16,74,
353 8,72,189,237,237,102,72,15,110,213,252,242,15,88,194,252,242,15,88,202,102,
354 15,126,197,102,15,126,201,255,211,252,253,252,233,244,89,255,248,143,129,
355 252,248,239,15,130,244,63,129,122,253,4,239,255,248,143,129,252,248,239,15,
356 130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
357 63,252,242,15,16,2,252,242,15,16,74,8,72,189,237,237,102,72,15,110,213,252,
358 242,15,88,194,252,242,15,88,202,102,15,126,197,102,15,126,201,255,211,197,
359 252,233,244,89,255,248,144,129,252,248,239,15,130,244,63,129,122,253,4,239,
360 255,248,144,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,
361 129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,15,16,74,8,72,189,
362 237,237,102,72,15,110,213,252,242,15,88,194,252,242,15,88,202,102,15,126,
363 197,102,15,126,201,255,211,205,252,233,244,89,248,127,184,237,252,233,244,
364 63,248,129,184,237,248,63,139,108,36,24,139,90,252,252,137,92,36,28,137,149,
365 233,141,68,194,252,248,141,136,233,137,133,233,139,66,252,248,59,141,233,
366 15,135,244,251,137,252,239,252,255,144,233,139,149,233,133,192,15,143,244,
367 78,248,1,255,139,141,233,41,209,193,252,233,3,133,192,141,65,1,139,106,252,
368 248,15,133,244,33,139,157,233,139,11,15,182,252,233,15,182,205,131,195,4,
369 65,252,255,36,252,238,248,33,137,209,252,247,195,237,15,133,244,249,15,182,
370 107,252,253,72,252,247,213,141,20,252,234,252,233,244,28,248,3,137,221,131,
371 229,252,248,41,252,234,252,233,244,28,248,5,190,237,137,252,239,232,251,1,
372 0,139,149,233,49,192,252,233,244,1,248,75,93,72,137,108,36,8,139,108,36,24,
373 137,92,36,28,137,149,233,255,141,68,194,252,248,137,252,239,137,133,233,232,
374 251,1,22,139,149,233,139,133,233,41,208,193,232,3,131,192,1,72,139,108,36,
375 8,85,195,248,145,255,65,15,182,134,233,168,235,15,133,244,251,168,235,15,
376 133,244,247,168,235,15,132,244,247,65,252,255,142,233,252,233,244,247,255,
377 248,146,65,15,182,134,233,168,235,15,133,244,251,252,233,244,247,248,147,
378 65,15,182,134,233,168,235,15,133,244,251,168,235,15,132,244,251,65,252,255,
379 142,233,15,132,244,247,168,235,15,132,244,251,248,1,255,139,108,36,24,137,
380 149,233,137,222,137,252,239,232,251,1,23,248,3,139,149,233,248,4,15,182,75,
381 252,253,248,5,15,182,107,252,252,15,183,67,252,254,65,252,255,164,253,252,
382 238,233,248,148,131,195,4,139,77,232,137,76,36,4,252,233,244,4,248,149,255,
383 139,106,252,248,139,173,233,15,182,133,233,141,4,194,139,108,36,24,137,149,
384 233,137,133,233,137,222,65,141,190,233,73,137,174,233,137,92,36,28,232,251,
385 1,24,252,233,244,3,255,248,150,137,92,36,28,255,248,151,255,137,92,36,28,
386 131,203,1,248,1,255,141,68,194,252,248,139,108,36,24,137,149,233,137,133,
387 233,137,222,137,252,239,232,251,1,25,199,68,36,28,0,0,0,0,255,131,227,252,
388 254,255,139,149,233,72,137,193,139,133,233,41,208,72,137,205,15,182,75,252,
389 253,193,232,3,131,192,1,252,255,229,248,152,255,65,85,65,84,65,83,65,82,65,
390 81,65,80,87,86,85,72,141,108,36,88,85,83,82,81,80,15,182,69,252,248,138,101,
391 252,240,76,137,125,252,248,76,137,117,252,240,68,139,117,0,65,139,142,233,
392 65,199,134,233,237,65,137,134,233,65,137,142,233,72,129,252,236,239,72,131,
393 197,128,252,242,68,15,17,125,252,248,252,242,68,15,17,117,252,240,252,242,
394 68,15,17,109,232,252,242,68,15,17,101,224,252,242,68,15,17,93,216,252,242,
395 68,15,17,85,208,252,242,68,15,17,77,200,252,242,68,15,17,69,192,252,242,15,
396 17,125,184,252,242,15,17,117,176,252,242,15,17,109,168,252,242,15,17,101,
397 160,252,242,15,17,93,152,252,242,15,17,85,144,252,242,15,17,77,136,252,242,
398 15,17,69,128,65,139,174,233,65,139,150,233,73,137,174,233,65,199,134,233,
399 0,0,0,0,137,149,233,72,137,230,65,141,190,233,232,251,1,26,72,139,141,233,
400 72,129,225,239,72,137,204,137,169,233,139,149,233,139,153,233,252,233,244,
401 247,255,248,153,255,72,131,196,16,248,1,76,139,108,36,8,76,139,36,36,133,
402 192,15,136,244,249,137,68,36,4,68,139,122,252,248,69,139,191,233,69,139,191,
403 233,65,199,134,233,0,0,0,0,65,199,134,233,237,139,3,15,182,204,15,182,232,
404 131,195,4,193,232,16,129,252,253,239,15,130,244,248,139,68,36,4,248,2,65,
405 252,255,36,252,238,248,3,252,247,216,137,252,239,137,198,232,251,1,1,255,
406 248,91,255,217,124,36,4,137,68,36,8,102,184,0,4,102,11,68,36,4,102,37,252,
407 255,252,247,102,137,68,36,6,217,108,36,6,217,252,252,217,108,36,4,139,68,
408 36,8,195,255,248,154,72,184,237,237,102,72,15,110,208,72,184,237,237,102,
409 72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,247,102,15,
410 85,208,252,242,15,88,203,252,242,15,92,203,102,15,86,202,72,184,237,237,102,
411 72,15,110,208,252,242,15,194,193,1,102,15,84,194,252,242,15,92,200,15,40,
412 193,248,1,195,248,93,255,217,124,36,4,137,68,36,8,102,184,0,8,102,11,68,36,
413 4,102,37,252,255,252,251,102,137,68,36,6,217,108,36,6,217,252,252,217,108,
414 36,4,139,68,36,8,195,255,248,155,72,184,237,237,102,72,15,110,208,72,184,
415 237,237,102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,
416 247,102,15,85,208,252,242,15,88,203,252,242,15,92,203,102,15,86,202,72,184,
417 237,237,102,72,15,110,208,252,242,15,194,193,6,102,15,84,194,252,242,15,92,
418 200,15,40,193,248,1,195,248,114,255,217,124,36,4,137,68,36,8,102,184,0,12,
419 102,11,68,36,4,102,137,68,36,6,217,108,36,6,217,252,252,217,108,36,4,139,
420 68,36,8,195,255,248,156,72,184,237,237,102,72,15,110,208,72,184,237,237,102,
421 72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,247,102,15,
422 85,208,15,40,193,252,242,15,88,203,252,242,15,92,203,72,184,237,237,102,72,
423 15,110,216,252,242,15,194,193,1,102,15,84,195,252,242,15,92,200,102,15,86,
424 202,15,40,193,248,1,195,248,157,255,15,40,232,252,242,15,94,193,72,184,237,
425 237,102,72,15,110,208,72,184,237,237,102,72,15,110,216,15,40,224,102,15,84,
426 226,102,15,46,220,15,134,244,247,102,15,85,208,252,242,15,88,227,252,242,
427 15,92,227,102,15,86,226,72,184,237,237,102,72,15,110,208,252,242,15,194,196,
428 1,102,15,84,194,252,242,15,92,224,15,40,197,252,242,15,89,204,252,242,15,
429 92,193,195,248,1,252,242,15,89,200,15,40,197,252,242,15,92,193,195,255,217,
430 193,216,252,241,217,124,36,4,102,184,0,4,102,11,68,36,4,102,37,252,255,252,
431 247,102,137,68,36,6,217,108,36,6,217,252,252,217,108,36,4,222,201,222,252,
432 233,195,255,248,98,217,252,234,222,201,248,158,217,84,36,252,248,129,124,
433 36,252,248,0,0,128,127,15,132,244,247,129,124,36,252,248,0,0,128,252,255,
434 15,132,244,248,248,159,217,192,217,252,252,220,252,233,217,201,217,252,240,
435 217,232,222,193,217,252,253,221,217,248,1,195,248,2,221,216,217,252,238,195,
436 255,248,117,255,248,160,252,242,15,45,193,252,242,15,42,208,102,15,46,202,
437 15,133,244,254,15,138,244,255,248,161,131,252,248,1,15,142,244,252,248,1,
438 169,1,0,0,0,15,133,244,248,252,242,15,89,192,209,232,252,233,244,1,248,2,
439 209,232,15,132,244,251,15,40,200,248,3,252,242,15,89,192,209,232,15,132,244,
440 250,15,131,244,3,255,252,242,15,89,200,252,233,244,3,248,4,252,242,15,89,
441 193,248,5,195,248,6,15,132,244,5,15,130,244,253,252,247,216,232,244,1,72,
442 184,237,237,102,72,15,110,200,252,242,15,94,200,15,40,193,195,248,7,72,184,
443 237,237,102,72,15,110,192,195,248,8,102,72,15,126,200,72,209,224,72,193,192,
444 12,72,61,252,254,15,0,0,15,132,244,248,102,72,15,126,192,72,209,224,15,132,
445 244,250,255,72,193,192,12,72,61,252,254,15,0,0,15,132,244,251,252,242,15,
446 17,76,36,252,240,252,242,15,17,68,36,252,248,221,68,36,252,240,221,68,36,
447 252,248,217,252,241,217,192,217,252,252,220,252,233,217,201,217,252,240,217,
448 232,222,193,217,252,253,221,217,221,92,36,252,248,252,242,15,16,68,36,252,
449 248,195,248,9,72,184,237,237,102,72,15,110,208,102,15,46,194,15,132,244,247,
450 15,40,193,248,1,195,248,2,72,184,237,237,102,72,15,110,208,102,15,84,194,
451 72,184,237,237,102,72,15,110,208,102,15,46,194,15,132,244,1,102,15,80,193,
452 15,87,192,136,196,15,146,208,48,224,15,133,244,1,248,3,72,184,237,237,255,
453 102,72,15,110,192,195,248,4,102,15,80,193,133,192,15,133,244,3,15,87,192,
454 195,248,5,102,15,80,193,133,192,15,132,244,3,15,87,192,195,248,162,255,131,
455 252,255,1,15,130,244,91,15,132,244,93,131,252,255,3,15,130,244,114,15,135,
456 244,248,252,242,15,81,192,195,248,2,252,242,15,17,68,36,252,248,221,68,36,
457 252,248,131,252,255,5,15,135,244,248,15,132,244,247,232,244,98,252,233,244,
458 253,248,1,232,244,158,255,252,233,244,253,248,2,131,252,255,7,15,132,244,
459 247,15,135,244,248,217,252,237,217,201,217,252,241,252,233,244,253,248,1,
460 217,232,217,201,217,252,241,252,233,244,253,248,2,131,252,255,9,15,132,244,
461 247,15,135,244,248,217,252,236,217,201,217,252,241,252,233,244,253,248,1,
462 255,217,252,254,252,233,244,253,248,2,131,252,255,11,15,132,244,247,15,135,
463 244,255,217,252,255,252,233,244,253,248,1,217,252,242,221,216,248,7,221,92,
464 36,252,248,252,242,15,16,68,36,252,248,195,255,139,124,36,12,221,68,36,4,
465 131,252,255,1,15,130,244,91,15,132,244,93,131,252,255,3,15,130,244,114,15,
466 135,244,248,217,252,250,195,248,2,131,252,255,5,15,130,244,98,15,132,244,
467 158,131,252,255,7,15,132,244,247,15,135,244,248,217,252,237,217,201,217,252,
468 241,195,248,1,217,232,217,201,217,252,241,195,248,2,131,252,255,9,15,132,
469 244,247,255,15,135,244,248,217,252,236,217,201,217,252,241,195,248,1,217,
470 252,254,195,248,2,131,252,255,11,15,132,244,247,15,135,244,255,217,252,255,
471 195,248,1,217,252,242,221,216,195,255,248,9,204,255,248,163,255,131,252,255,
472 1,15,132,244,247,15,135,244,248,252,242,15,88,193,195,248,1,252,242,15,92,
473 193,195,248,2,131,252,255,3,15,132,244,247,15,135,244,248,252,242,15,89,193,
474 195,248,1,252,242,15,94,193,195,248,2,131,252,255,5,15,130,244,157,15,132,
475 244,117,131,252,255,7,15,132,244,247,15,135,244,248,72,184,237,237,255,102,
476 72,15,110,200,15,87,193,195,248,1,72,184,237,237,102,72,15,110,200,15,84,
477 193,195,248,2,131,252,255,9,15,135,244,248,252,242,15,17,68,36,252,248,252,
478 242,15,17,76,36,252,240,221,68,36,252,248,221,68,36,252,240,15,132,244,247,
479 217,252,243,248,7,221,92,36,252,248,252,242,15,16,68,36,252,248,195,248,1,
480 217,201,217,252,253,221,217,252,233,244,7,248,2,131,252,255,11,15,132,244,
481 247,15,135,244,255,252,242,15,93,193,195,248,1,252,242,15,95,193,195,248,
482 9,204,255,139,68,36,20,221,68,36,4,221,68,36,12,131,252,248,1,15,132,244,
483 247,15,135,244,248,222,193,195,248,1,222,252,233,195,248,2,131,252,248,3,
484 15,132,244,247,15,135,244,248,222,201,195,248,1,222,252,249,195,248,2,131,
485 252,248,5,15,130,244,157,15,132,244,117,131,252,248,7,15,132,244,247,15,135,
486 244,248,255,221,216,217,224,195,248,1,221,216,217,225,195,248,2,131,252,248,
487 9,15,132,244,247,15,135,244,248,217,252,243,195,248,1,217,201,217,252,253,
488 221,217,195,248,2,131,252,248,11,15,132,244,247,15,135,244,255,255,219,252,
489 233,219,209,221,217,195,248,1,219,252,233,218,209,221,217,195,255,221,225,
490 223,224,252,246,196,1,15,132,244,248,217,201,248,2,221,216,195,248,1,221,
491 225,223,224,252,246,196,1,15,133,244,248,217,201,248,2,221,216,195,255,248,
492 164,137,252,248,83,15,162,137,6,137,94,4,137,78,8,137,86,12,91,195,248,165,
493 255,204,248,166,255,83,65,87,65,86,72,131,252,236,40,68,141,181,233,139,157,
494 233,15,183,192,137,131,233,72,137,187,233,72,137,179,233,72,137,147,233,72,
495 137,139,233,252,242,15,17,131,233,252,242,15,17,139,233,252,242,15,17,147,
496 233,252,242,15,17,155,233,72,141,132,253,36,233,76,137,131,233,76,137,139,
497 233,252,242,15,17,163,233,252,242,15,17,171,233,252,242,15,17,179,233,252,
498 242,15,17,187,233,72,137,131,233,72,137,230,137,92,36,28,137,223,232,251,
499 1,27,65,199,134,233,237,255,139,144,233,139,128,233,41,208,139,106,252,248,
500 193,232,3,131,192,1,139,157,233,139,11,15,182,252,233,15,182,205,131,195,
501 4,65,252,255,36,252,238,255,248,32,255,139,76,36,24,65,139,158,233,72,137,
502 139,233,137,145,233,137,169,233,137,223,137,198,232,251,1,28,72,139,131,233,
503 252,242,15,16,131,233,252,233,244,16,255,248,167,255,85,72,137,229,83,72,
504 137,252,251,139,131,233,72,41,196,255,15,182,139,233,131,252,233,1,15,136,
505 244,248,248,1,72,139,132,253,203,233,72,137,132,253,204,233,131,252,233,1,
506 15,137,244,1,248,2,15,182,131,233,72,139,187,233,72,139,179,233,72,139,147,
507 233,72,139,139,233,76,139,131,233,76,139,139,233,133,192,15,132,244,251,15,
508 40,131,233,15,40,139,233,255,15,40,147,233,15,40,155,233,131,252,248,4,15,
509 134,244,251,15,40,163,233,15,40,171,233,15,40,179,233,15,40,187,233,248,5,
510 252,255,147,233,72,137,131,233,15,41,131,233,72,137,147,233,15,41,139,233,
511 255,72,139,93,252,248,201,195,255,129,124,253,202,4,239,15,133,244,253,129,
512 124,253,194,4,239,15,133,244,254,139,44,202,131,195,4,59,44,194,255,15,141,
513 244,255,255,15,140,244,255,255,15,143,244,255,255,15,142,244,255,255,248,
514 6,15,183,67,252,254,141,156,253,131,233,248,9,139,3,15,182,204,15,182,232,
515 131,195,4,193,232,16,65,252,255,36,252,238,248,7,15,135,244,44,129,124,253,
516 194,4,239,15,130,244,247,15,133,244,44,255,252,242,15,42,4,194,252,233,244,
517 248,255,221,4,202,219,4,194,252,233,244,249,255,248,8,15,135,244,44,255,252,
518 242,15,42,12,202,252,242,15,16,4,194,131,195,4,102,15,46,193,255,15,134,244,
519 9,255,15,135,244,9,255,15,130,244,9,255,15,131,244,9,255,252,233,244,6,255,
520 219,4,202,252,233,244,248,255,129,124,253,202,4,239,15,131,244,44,129,124,
521 253,194,4,239,15,131,244,44,255,248,1,252,242,15,16,4,194,248,2,131,195,4,
522 102,15,46,4,202,248,3,255,248,1,221,4,202,248,2,221,4,194,248,3,131,195,4,
523 255,223,252,233,221,216,255,218,252,233,223,224,158,255,15,135,244,247,255,
524 15,130,244,247,255,15,131,244,247,255,15,183,67,252,254,141,156,253,131,233,
525 248,1,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
526 238,255,139,108,194,4,131,195,4,255,129,252,253,239,15,133,244,253,129,124,
527 253,202,4,239,15,133,244,254,139,44,194,59,44,202,255,15,133,244,255,255,
528 15,132,244,255,255,15,183,67,252,254,141,156,253,131,233,248,9,139,3,15,182,
529 204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,7,15,135,244,
530 251,129,124,253,202,4,239,15,130,244,247,15,133,244,251,255,252,242,15,42,
531 4,202,255,219,4,202,255,252,233,244,248,248,8,15,135,244,251,255,252,242,
532 15,42,4,194,102,15,46,4,202,255,219,4,194,221,4,202,255,252,233,244,250,255,
533 129,252,253,239,15,131,244,251,129,124,253,202,4,239,15,131,244,251,255,248,
534 1,252,242,15,16,4,202,248,2,102,15,46,4,194,248,4,255,248,1,221,4,202,248,
535 2,221,4,194,248,4,255,15,138,244,248,15,133,244,248,255,15,138,244,248,15,
536 132,244,247,255,248,1,15,183,67,252,254,141,156,253,131,233,248,2,255,248,
537 2,15,183,67,252,254,141,156,253,131,233,248,1,255,252,233,244,9,255,248,5,
538 255,129,252,253,239,15,132,244,49,129,124,253,202,4,239,15,132,244,49,255,
539 57,108,202,4,15,133,244,2,129,252,253,239,15,131,244,1,139,12,202,139,4,194,
540 57,193,15,132,244,1,129,252,253,239,15,135,244,2,129,252,253,239,15,130,244,
541 2,139,169,233,133,252,237,15,132,244,2,252,246,133,233,235,15,133,244,2,255,
542 49,252,237,255,189,1,0,0,0,255,252,233,244,48,255,248,3,129,252,253,239,255,
543 15,133,244,9,255,252,233,244,49,255,72,252,247,208,139,108,202,4,131,195,
544 4,129,252,253,239,15,133,244,249,139,12,202,65,59,12,135,255,139,108,202,
545 4,131,195,4,255,129,252,253,239,15,133,244,253,65,129,124,253,199,4,239,15,
546 133,244,254,65,139,44,199,59,44,202,255,15,183,67,252,254,141,156,253,131,
547 233,248,9,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,
548 252,238,248,7,15,135,244,249,65,129,124,253,199,4,239,15,130,244,247,255,
549 252,242,65,15,42,4,199,255,65,219,4,199,255,252,233,244,248,248,8,255,252,
550 242,15,42,4,202,102,65,15,46,4,199,255,219,4,202,65,221,4,199,255,129,252,
551 253,239,15,131,244,249,255,248,1,252,242,65,15,16,4,199,248,2,102,15,46,4,
552 202,248,4,255,248,1,65,221,4,199,248,2,221,4,202,248,4,255,72,252,247,208,
553 139,108,202,4,131,195,4,57,197,255,15,133,244,249,15,183,67,252,254,141,156,
554 253,131,233,248,2,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
555 255,36,252,238,248,3,129,252,253,239,15,133,244,2,252,233,244,49,255,15,132,
556 244,248,129,252,253,239,15,132,244,49,15,183,67,252,254,141,156,253,131,233,
557 248,2,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
558 238,255,139,108,194,4,131,195,4,129,252,253,239,255,137,108,202,4,139,44,
559 194,137,44,202,255,72,139,44,194,72,137,44,202,139,3,15,182,204,15,182,232,
560 131,195,4,193,232,16,65,252,255,36,252,238,255,49,252,237,129,124,253,194,
561 4,239,129,213,239,137,108,202,4,139,3,15,182,204,15,182,232,131,195,4,193,
562 232,16,65,252,255,36,252,238,255,129,124,253,194,4,239,15,133,244,251,139,
563 44,194,252,247,221,15,128,244,250,199,68,202,4,237,137,44,202,248,9,139,3,
564 15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,4,199,
565 68,202,4,0,0,224,65,199,4,202,0,0,0,0,252,233,244,9,248,5,15,135,244,54,255,
566 129,124,253,194,4,239,15,131,244,54,255,252,242,15,16,4,194,72,184,237,237,
567 102,72,15,110,200,15,87,193,252,242,15,17,4,202,255,221,4,194,217,224,221,
568 28,202,255,129,124,253,194,4,239,15,133,244,248,139,4,194,255,139,128,233,
569 248,1,199,68,202,4,237,137,4,202,255,15,87,192,252,242,15,42,128,233,248,
570 1,252,242,15,17,4,202,255,219,128,233,248,1,221,28,202,255,139,3,15,182,204,
571 15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,2,129,124,253,194,
572 4,239,15,133,244,57,139,60,194,255,139,175,233,131,252,253,0,15,133,244,255,
573 248,3,255,248,58,137,213,232,251,1,21,255,252,242,15,42,192,255,137,252,234,
574 15,182,75,252,253,252,233,244,1,255,248,9,252,246,133,233,235,15,133,244,
575 3,252,233,244,57,255,15,182,252,236,15,182,192,255,129,124,253,252,234,4,
576 239,15,133,244,51,65,129,124,253,199,4,239,15,133,244,51,139,44,252,234,65,
577 3,44,199,15,128,244,50,255,129,124,253,252,234,4,239,15,133,244,53,65,129,
578 124,253,199,4,239,15,133,244,53,65,139,4,199,3,4,252,234,15,128,244,52,255,
579 129,124,253,252,234,4,239,15,133,244,56,129,124,253,194,4,239,15,133,244,
580 56,139,44,252,234,3,44,194,15,128,244,55,255,199,68,202,4,237,255,129,124,
581 253,252,234,4,239,15,131,244,51,255,65,129,124,253,199,4,239,15,131,244,51,
582 255,252,242,15,16,4,252,234,252,242,65,15,88,4,199,255,221,4,252,234,65,220,
583 4,199,255,129,124,253,252,234,4,239,15,131,244,53,255,65,129,124,253,199,
584 4,239,15,131,244,53,255,252,242,65,15,16,4,199,252,242,15,88,4,252,234,255,
585 65,221,4,199,220,4,252,234,255,129,124,253,252,234,4,239,15,131,244,56,129,
586 124,253,194,4,239,15,131,244,56,255,252,242,15,16,4,252,234,252,242,15,88,
587 4,194,255,221,4,252,234,220,4,194,255,129,124,253,252,234,4,239,15,133,244,
588 51,65,129,124,253,199,4,239,15,133,244,51,139,44,252,234,65,43,44,199,15,
589 128,244,50,255,129,124,253,252,234,4,239,15,133,244,53,65,129,124,253,199,
590 4,239,15,133,244,53,65,139,4,199,43,4,252,234,15,128,244,52,255,129,124,253,
591 252,234,4,239,15,133,244,56,129,124,253,194,4,239,15,133,244,56,139,44,252,
592 234,43,44,194,15,128,244,55,255,252,242,15,16,4,252,234,252,242,65,15,92,
593 4,199,255,221,4,252,234,65,220,36,199,255,252,242,65,15,16,4,199,252,242,
594 15,92,4,252,234,255,65,221,4,199,220,36,252,234,255,252,242,15,16,4,252,234,
595 252,242,15,92,4,194,255,221,4,252,234,220,36,194,255,129,124,253,252,234,
596 4,239,15,133,244,51,65,129,124,253,199,4,239,15,133,244,51,139,44,252,234,
597 65,15,175,44,199,15,128,244,50,255,129,124,253,252,234,4,239,15,133,244,53,
598 65,129,124,253,199,4,239,15,133,244,53,65,139,4,199,15,175,4,252,234,15,128,
599 244,52,255,129,124,253,252,234,4,239,15,133,244,56,129,124,253,194,4,239,
600 15,133,244,56,139,44,252,234,15,175,44,194,15,128,244,55,255,252,242,15,16,
601 4,252,234,252,242,65,15,89,4,199,255,221,4,252,234,65,220,12,199,255,252,
602 242,65,15,16,4,199,252,242,15,89,4,252,234,255,65,221,4,199,220,12,252,234,
603 255,252,242,15,16,4,252,234,252,242,15,89,4,194,255,221,4,252,234,220,12,
604 194,255,252,242,15,16,4,252,234,252,242,65,15,94,4,199,255,221,4,252,234,
605 65,220,52,199,255,252,242,65,15,16,4,199,252,242,15,94,4,252,234,255,65,221,
606 4,199,220,52,252,234,255,252,242,15,16,4,252,234,252,242,15,94,4,194,255,
607 221,4,252,234,220,52,194,255,252,242,15,16,4,252,234,252,242,65,15,16,12,
608 199,255,221,4,252,234,65,221,4,199,255,252,242,65,15,16,4,199,252,242,15,
609 16,12,252,234,255,65,221,4,199,221,4,252,234,255,252,242,15,16,4,252,234,
610 252,242,15,16,12,194,255,221,4,252,234,221,4,194,255,248,168,232,244,157,
611 255,252,233,244,168,255,232,244,117,255,15,182,252,236,15,182,192,139,124,
612 36,24,137,151,233,141,52,194,137,194,41,252,234,248,36,137,252,253,137,92,
613 36,28,232,251,1,29,139,149,233,133,192,15,133,244,45,15,182,107,252,255,15,
614 182,75,252,253,72,139,4,252,234,72,137,4,202,139,3,15,182,204,15,182,232,
615 131,195,4,193,232,16,65,252,255,36,252,238,255,72,252,247,208,65,139,4,135,
616 199,68,202,4,237,137,4,202,139,3,15,182,204,15,182,232,131,195,4,193,232,
617 16,65,252,255,36,252,238,255,15,191,192,199,68,202,4,237,137,4,202,255,15,
618 191,192,252,242,15,42,192,252,242,15,17,4,202,255,223,67,252,254,221,28,202,
619 255,252,242,65,15,16,4,199,252,242,15,17,4,202,255,65,221,4,199,221,28,202,
620 255,72,252,247,208,137,68,202,4,139,3,15,182,204,15,182,232,131,195,4,193,
621 232,16,65,252,255,36,252,238,255,141,76,202,12,141,68,194,4,189,237,137,105,
622 252,248,248,1,137,41,131,193,8,57,193,15,134,244,1,139,3,15,182,204,15,182,
623 232,131,195,4,193,232,16,65,252,255,36,252,238,255,139,106,252,248,139,172,
624 253,133,233,139,173,233,72,139,69,0,72,137,4,202,139,3,15,182,204,15,182,
625 232,131,195,4,193,232,16,65,252,255,36,252,238,255,139,106,252,248,139,172,
626 253,141,233,128,189,233,0,139,173,233,139,12,194,139,68,194,4,137,77,0,137,
627 69,4,15,132,244,247,252,246,133,233,235,15,133,244,248,248,1,139,3,15,182,
628 204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,2,129,232,239,
629 129,252,248,239,15,134,244,1,252,246,129,233,235,15,132,244,1,137,252,238,
630 137,213,65,141,190,233,255,232,251,1,30,137,252,234,252,233,244,1,255,72,
631 252,247,208,139,106,252,248,139,172,253,141,233,65,139,12,135,139,133,233,
632 137,8,199,64,4,237,252,246,133,233,235,15,133,244,248,248,1,139,3,15,182,
633 204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,2,252,246,129,
634 233,235,15,132,244,1,128,189,233,0,15,132,244,1,137,213,137,198,65,141,190,
635 233,232,251,1,30,137,252,234,252,233,244,1,255,139,106,252,248,255,252,242,
636 65,15,16,4,199,255,139,172,253,141,233,139,141,233,255,252,242,15,17,1,255,
637 221,25,255,72,252,247,208,139,106,252,248,139,172,253,141,233,139,141,233,
638 137,65,4,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
639 238,255,141,156,253,131,233,139,108,36,24,131,189,233,0,15,132,244,247,137,
640 149,233,141,52,202,137,252,239,232,251,1,31,139,149,233,248,1,139,3,15,182,
641 204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,72,252,247,
642 208,139,108,36,24,137,149,233,139,82,252,248,65,139,52,135,137,252,239,137,
643 92,36,28,232,251,1,32,139,149,233,15,182,75,252,253,137,4,202,199,68,202,
644 4,237,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
645 238,255,139,108,36,24,137,149,233,65,139,142,233,65,59,142,233,137,92,36,
646 28,15,131,244,251,248,1,137,194,37,252,255,7,0,0,193,252,234,11,61,252,255,
647 7,0,0,15,132,244,249,248,2,137,252,239,137,198,232,251,1,33,139,149,233,15,
648 182,75,252,253,137,4,202,199,68,202,4,237,139,3,15,182,204,15,182,232,131,
649 195,4,193,232,16,65,252,255,36,252,238,248,3,184,1,8,0,0,252,233,244,2,248,
650 5,137,252,239,232,251,1,34,15,183,67,252,254,252,233,244,1,255,72,252,247,
651 208,139,108,36,24,65,139,142,233,137,92,36,28,65,59,142,233,137,149,233,15,
652 131,244,249,248,2,65,139,52,135,137,252,239,232,251,1,35,139,149,233,15,182,
653 75,252,253,137,4,202,199,68,202,4,237,139,3,15,182,204,15,182,232,131,195,
654 4,193,232,16,65,252,255,36,252,238,248,3,137,252,239,232,251,1,34,15,183,
655 67,252,254,72,252,247,208,252,233,244,2,255,72,252,247,208,139,106,252,248,
656 139,173,233,65,139,4,135,252,233,244,169,255,72,252,247,208,139,106,252,248,
657 139,173,233,65,139,4,135,252,233,244,170,255,15,182,252,236,15,182,192,129,
658 124,253,252,234,4,239,15,133,244,39,139,44,252,234,255,129,124,253,194,4,
659 239,15,133,244,251,139,4,194,255,129,124,253,194,4,239,15,131,244,251,255,
660 252,242,15,16,4,194,252,242,15,45,192,252,242,15,42,200,102,15,46,193,255,
661 15,133,244,39,255,59,133,233,15,131,244,39,193,224,3,3,133,233,129,120,253,
662 4,239,15,132,244,248,72,139,40,72,137,44,202,248,1,139,3,15,182,204,15,182,
663 232,131,195,4,193,232,16,65,252,255,36,252,238,248,2,131,189,233,0,15,132,
664 244,249,139,141,233,252,246,129,233,235,15,132,244,39,15,182,75,252,253,248,
665 3,199,68,202,4,237,252,233,244,1,248,5,255,129,124,253,194,4,239,15,133,244,
666 39,139,4,194,252,233,244,169,255,15,182,252,236,15,182,192,72,252,247,208,
667 65,139,4,135,129,124,253,252,234,4,239,15,133,244,37,139,44,252,234,248,169,
668 139,141,233,35,136,233,105,201,239,3,141,233,248,1,129,185,233,239,15,133,
669 244,250,57,129,233,15,133,244,250,129,121,253,4,239,15,132,244,251,15,182,
670 67,252,253,72,139,41,72,137,44,194,248,2,255,139,3,15,182,204,15,182,232,
671 131,195,4,193,232,16,65,252,255,36,252,238,248,3,15,182,67,252,253,199,68,
672 194,4,237,252,233,244,2,248,4,139,137,233,133,201,15,133,244,1,248,5,139,
673 141,233,133,201,15,132,244,3,252,246,129,233,235,15,133,244,3,252,233,244,
674 37,255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,38,
675 139,44,252,234,59,133,233,15,131,244,38,193,224,3,3,133,233,129,120,253,4,
676 239,15,132,244,248,72,139,40,72,137,44,202,248,1,139,3,15,182,204,15,182,
677 232,131,195,4,193,232,16,65,252,255,36,252,238,248,2,131,189,233,0,15,132,
678 244,249,139,141,233,252,246,129,233,235,15,132,244,38,255,15,182,75,252,253,
679 248,3,199,68,202,4,237,252,233,244,1,255,15,182,252,236,15,182,192,129,124,
680 253,252,234,4,239,15,133,244,42,139,44,252,234,255,15,133,244,42,255,59,133,
681 233,15,131,244,42,193,224,3,3,133,233,129,120,253,4,239,15,132,244,249,248,
682 1,252,246,133,233,235,15,133,244,253,248,2,72,139,44,202,72,137,40,139,3,
683 15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,3,131,
684 189,233,0,15,132,244,1,139,141,233,252,246,129,233,235,255,15,132,244,42,
685 15,182,75,252,253,252,233,244,1,248,5,129,124,253,194,4,239,15,133,244,42,
686 139,4,194,252,233,244,170,248,7,128,165,233,235,65,139,142,233,65,137,174,
687 233,137,141,233,15,182,75,252,253,252,233,244,2,255,15,182,252,236,15,182,
688 192,72,252,247,208,65,139,4,135,129,124,253,252,234,4,239,15,133,244,40,139,
689 44,252,234,248,170,139,141,233,35,136,233,105,201,239,198,133,233,0,3,141,
690 233,248,1,129,185,233,239,15,133,244,251,57,129,233,15,133,244,251,129,121,
691 253,4,239,15,132,244,250,248,2,255,252,246,133,233,235,15,133,244,253,248,
692 3,15,182,67,252,253,72,139,44,194,72,137,41,139,3,15,182,204,15,182,232,131,
693 195,4,193,232,16,65,252,255,36,252,238,248,4,131,189,233,0,15,132,244,2,137,
694 12,36,139,141,233,252,246,129,233,235,15,132,244,40,139,12,36,252,233,244,
695 2,248,5,139,137,233,133,201,15,133,244,1,255,139,141,233,133,201,15,132,244,
696 252,252,246,129,233,235,15,132,244,40,248,6,137,4,36,199,68,36,4,237,137,
697 108,36,8,139,124,36,24,137,151,233,72,141,20,36,137,252,238,137,252,253,137,
698 92,36,28,232,251,1,36,139,149,233,139,108,36,8,137,193,252,233,244,2,248,
699 7,128,165,233,235,65,139,134,233,65,137,174,233,137,133,233,252,233,244,3,
700 255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,41,139,
701 44,252,234,59,133,233,15,131,244,41,193,224,3,3,133,233,129,120,253,4,239,
702 15,132,244,249,248,1,252,246,133,233,235,15,133,244,253,248,2,72,139,12,202,
703 72,137,8,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
704 238,248,3,131,189,233,0,15,132,244,1,255,139,141,233,252,246,129,233,235,
705 15,132,244,41,15,182,75,252,253,252,233,244,1,248,7,128,165,233,235,65,139,
706 142,233,65,137,174,233,137,141,233,15,182,75,252,253,252,233,244,2,255,68,
707 137,60,36,69,139,60,199,248,1,141,12,202,139,105,252,248,252,246,133,233,
708 235,15,133,244,253,248,2,139,68,36,4,131,232,1,15,132,244,250,68,1,252,248,
709 59,133,233,15,135,244,251,68,41,252,248,65,193,231,3,68,3,189,233,248,3,72,
710 139,41,131,193,8,73,137,47,65,131,199,8,131,232,1,15,133,244,3,248,4,68,139,
711 60,36,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
712 238,248,5,139,124,36,24,137,151,233,137,252,238,137,194,137,252,253,137,92,
713 36,28,232,251,1,37,139,149,233,15,182,75,252,253,252,233,244,1,248,7,255,
714 128,165,233,235,65,139,134,233,65,137,174,233,137,133,233,252,233,244,2,255,
715 3,68,36,4,255,129,124,253,202,4,239,139,44,202,15,133,244,59,141,84,202,8,
716 137,90,252,252,139,157,233,139,11,15,182,252,233,15,182,205,131,195,4,65,
717 252,255,36,252,238,255,141,76,202,8,65,137,215,139,105,252,248,129,121,253,
718 252,252,239,15,133,244,29,248,60,139,90,252,252,252,247,195,237,15,133,244,
719 253,248,1,137,106,252,248,137,68,36,4,131,232,1,15,132,244,249,248,2,72,139,
720 41,131,193,8,73,137,47,65,131,199,8,131,232,1,15,133,244,2,139,106,252,248,
721 248,3,139,68,36,4,128,189,233,1,15,135,244,251,248,4,139,157,233,139,11,15,
722 182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,248,5,255,252,247,
723 195,237,15,133,244,4,15,182,75,252,253,72,252,247,209,141,12,202,68,139,121,
724 252,248,69,139,191,233,69,139,191,233,252,233,244,4,248,7,129,252,235,239,
725 252,247,195,237,15,133,244,254,41,218,65,137,215,139,90,252,252,252,233,244,
726 1,248,8,129,195,239,252,233,244,1,255,141,76,202,8,72,139,105,232,72,139,
727 65,252,240,72,137,41,72,137,65,8,139,105,224,139,65,228,137,105,252,248,137,
728 65,252,252,129,252,248,239,184,237,15,133,244,29,137,202,137,90,252,252,139,
729 157,233,139,11,15,182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,
730 255,68,137,60,36,68,137,116,36,4,139,108,202,252,240,139,68,202,252,248,68,
731 139,181,233,131,195,4,68,139,189,233,248,1,68,57,252,240,15,131,244,251,65,
732 129,124,253,199,4,239,15,132,244,250,255,219,68,202,252,248,255,73,139,44,
733 199,72,137,108,202,8,131,192,1,255,137,68,202,252,248,248,2,15,183,67,252,
734 254,141,156,253,131,233,248,3,68,139,116,36,4,68,139,60,36,139,3,15,182,204,
735 15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,4,131,192,1,255,
736 137,68,202,252,248,255,252,233,244,1,248,5,68,41,252,240,248,6,59,133,233,
737 15,135,244,3,68,105,252,248,239,68,3,189,233,65,129,191,233,239,15,132,244,
738 253,70,141,116,48,1,73,139,175,233,73,139,135,233,72,137,44,202,72,137,68,
739 202,8,68,137,116,202,252,248,252,233,244,2,248,7,131,192,1,252,233,244,6,
740 255,129,124,253,202,252,236,239,15,133,244,251,139,108,202,232,129,124,253,
741 202,252,244,239,15,133,244,251,129,124,253,202,252,252,239,15,133,244,251,
742 128,189,233,235,15,133,244,251,141,156,253,131,233,199,68,202,252,248,0,0,
743 0,0,248,1,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,
744 252,238,248,5,198,67,252,252,235,141,156,253,131,233,198,3,235,252,233,244,
745 1,255,15,182,252,236,15,182,192,68,137,60,36,68,141,188,253,194,233,141,12,
746 202,68,43,122,252,252,133,252,237,15,132,244,251,141,108,252,233,252,248,
747 65,57,215,15,131,244,248,248,1,73,139,71,252,248,65,131,199,8,72,137,1,131,
748 193,8,57,252,233,15,131,244,249,65,57,215,15,130,244,1,248,2,199,65,4,237,
749 131,193,8,57,252,233,15,130,244,2,248,3,68,139,60,36,139,3,15,182,204,15,
750 182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,5,199,68,36,4,1,0,
751 0,0,137,208,68,41,252,248,15,134,244,3,137,197,193,252,237,3,131,197,1,137,
752 108,36,4,139,108,36,24,1,200,59,133,233,15,135,244,253,248,6,255,73,139,71,
753 252,248,65,131,199,8,72,137,1,131,193,8,65,57,215,15,130,244,6,252,233,244,
754 3,248,7,137,149,233,137,141,233,137,92,36,28,65,41,215,139,116,36,4,131,252,
755 238,1,137,252,239,232,251,1,0,139,149,233,139,141,233,65,1,215,252,233,244,
756 6,255,193,225,3,255,248,1,139,90,252,252,137,68,36,4,252,247,195,237,15,133,
757 244,253,255,248,13,65,137,215,131,232,1,15,132,244,249,248,2,73,139,44,15,
758 73,137,111,252,248,65,131,199,8,131,232,1,15,133,244,2,248,3,139,68,36,4,
759 15,182,107,252,255,248,5,57,197,15,135,244,252,255,72,139,44,10,72,137,106,
760 252,248,255,248,5,56,67,252,255,15,135,244,252,255,15,182,75,252,253,72,252,
761 247,209,141,20,202,68,139,122,252,248,69,139,191,233,69,139,191,233,139,3,
762 15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,6,255,
763 65,199,71,252,252,237,65,131,199,8,255,199,68,194,252,244,237,255,131,192,
764 1,252,233,244,5,248,7,141,171,233,252,247,197,237,15,133,244,14,41,252,234,
765 255,1,252,233,255,137,221,209,252,237,129,229,239,102,65,129,172,253,46,233,
766 238,15,130,244,149,255,141,12,202,255,129,121,253,4,239,15,133,244,255,255,
767 129,121,253,12,239,15,133,244,61,129,121,253,20,239,15,133,244,61,139,41,
768 131,121,16,0,15,140,244,251,255,129,121,253,12,239,15,133,244,165,129,121,
769 253,20,239,15,133,244,165,255,139,105,16,133,252,237,15,136,244,251,3,41,
770 15,128,244,247,137,41,255,59,105,8,199,65,28,237,137,105,24,255,15,142,244,
771 253,248,1,248,6,141,156,253,131,233,255,141,156,253,131,233,15,183,67,252,
772 254,15,142,245,248,1,248,6,255,15,143,244,253,248,6,141,156,253,131,233,248,
773 1,255,248,7,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,
774 252,238,248,5,255,3,41,15,128,244,1,137,41,255,15,141,244,7,255,141,156,253,
775 131,233,15,183,67,252,254,15,141,245,255,15,140,244,7,255,252,233,244,6,248,
776 9,255,129,121,253,4,239,255,15,131,244,61,129,121,253,12,239,15,131,244,61,
777 255,129,121,253,12,239,15,131,244,165,129,121,253,20,239,15,131,244,165,255,
778 139,105,20,255,129,252,253,239,15,131,244,61,255,252,242,15,16,1,252,242,
779 15,16,73,8,255,252,242,15,88,65,16,252,242,15,17,1,133,252,237,15,136,244,
780 249,255,15,140,244,249,255,102,15,46,200,248,1,252,242,15,17,65,24,255,221,
781 65,8,221,1,255,220,65,16,221,17,221,81,24,133,252,237,15,136,244,247,255,
782 221,81,24,15,140,244,247,255,217,201,248,1,255,15,183,67,252,254,255,15,131,
783 244,7,255,15,131,244,248,141,156,253,131,233,255,141,156,253,131,233,15,183,
784 67,252,254,15,131,245,255,15,130,244,7,255,15,130,244,248,141,156,253,131,
785 233,255,248,3,102,15,46,193,252,233,244,1,255,141,12,202,139,105,4,129,252,
786 253,239,15,132,244,247,255,137,105,252,252,139,41,137,105,252,248,252,233,
787 245,255,141,156,253,131,233,139,1,137,105,252,252,137,65,252,248,255,65,139,
788 142,233,139,4,129,72,139,128,233,139,108,36,24,65,137,150,233,65,137,174,
789 233,76,137,36,36,76,137,108,36,8,72,131,252,236,16,252,255,224,255,141,156,
790 253,131,233,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,
791 252,238,255,137,221,209,252,237,129,229,239,102,65,129,172,253,46,233,238,
792 15,130,244,151,255,68,139,187,233,139,108,36,24,141,12,202,59,141,233,15,
793 135,244,24,15,182,139,233,57,200,15,134,244,249,248,2,255,15,183,67,252,254,
794 252,233,245,255,248,3,199,68,194,252,252,237,131,192,1,57,200,15,134,244,
795 3,252,233,244,2,255,141,44,197,237,141,4,194,68,139,122,252,248,137,104,252,
796 252,68,137,120,252,248,139,108,36,24,141,12,200,59,141,233,15,135,244,23,
797 137,209,137,194,15,182,171,233,133,252,237,15,132,244,248,248,1,131,193,8,
798 57,209,15,131,244,249,68,139,121,252,248,68,137,56,68,139,121,252,252,68,
799 137,120,4,131,192,8,199,65,252,252,237,131,252,237,1,15,133,244,1,248,2,255,
800 68,139,187,233,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,
801 36,252,238,255,248,3,199,64,4,237,131,192,8,131,252,237,1,15,133,244,3,252,
802 233,244,2,255,139,106,252,248,76,139,189,233,139,108,36,24,141,68,194,252,
803 248,137,149,233,141,136,233,59,141,233,137,133,233,255,76,137,252,254,137,
804 252,239,255,15,135,244,22,65,199,134,233,237,255,65,252,255,215,255,65,252,
805 255,150,233,255,65,199,134,233,237,139,149,233,141,12,194,252,247,217,3,141,
806 233,139,90,252,252,252,233,244,12,255,254,0
807};
808
809enum {
810 GLOB_vm_returnp,
811 GLOB_cont_dispatch,
812 GLOB_vm_returnc,
813 GLOB_BC_RET_Z,
814 GLOB_vm_return,
815 GLOB_vm_leave_cp,
816 GLOB_vm_leave_unw,
817 GLOB_vm_unwind_c,
818 GLOB_vm_unwind_c_eh,
819 GLOB_vm_unwind_rethrow,
820 GLOB_vm_unwind_ff,
821 GLOB_vm_unwind_ff_eh,
822 GLOB_vm_growstack_c,
823 GLOB_vm_growstack_v,
824 GLOB_vm_growstack_f,
825 GLOB_vm_resume,
826 GLOB_vm_pcall,
827 GLOB_vm_call,
828 GLOB_vm_call_dispatch,
829 GLOB_vmeta_call,
830 GLOB_vm_call_dispatch_f,
831 GLOB_vm_cpcall,
832 GLOB_cont_ffi_callback,
833 GLOB_vm_call_tail,
834 GLOB_cont_cat,
835 GLOB_cont_ra,
836 GLOB_BC_CAT_Z,
837 GLOB_vmeta_tgets,
838 GLOB_vmeta_tgetb,
839 GLOB_vmeta_tgetv,
840 GLOB_vmeta_tsets,
841 GLOB_vmeta_tsetb,
842 GLOB_vmeta_tsetv,
843 GLOB_cont_nop,
844 GLOB_vmeta_comp,
845 GLOB_vmeta_binop,
846 GLOB_cont_condt,
847 GLOB_cont_condf,
848 GLOB_vmeta_equal,
849 GLOB_vmeta_equal_cd,
850 GLOB_vmeta_arith_vno,
851 GLOB_vmeta_arith_vn,
852 GLOB_vmeta_arith_nvo,
853 GLOB_vmeta_arith_nv,
854 GLOB_vmeta_unm,
855 GLOB_vmeta_arith_vvo,
856 GLOB_vmeta_arith_vv,
857 GLOB_vmeta_len,
858 GLOB_BC_LEN_Z,
859 GLOB_vmeta_call_ra,
860 GLOB_BC_CALLT_Z,
861 GLOB_vmeta_for,
862 GLOB_ff_assert,
863 GLOB_fff_fallback,
864 GLOB_fff_res_,
865 GLOB_ff_type,
866 GLOB_fff_res1,
867 GLOB_ff_getmetatable,
868 GLOB_ff_setmetatable,
869 GLOB_ff_rawget,
870 GLOB_ff_tonumber,
871 GLOB_fff_resi,
872 GLOB_fff_resxmm0,
873 GLOB_fff_resn,
874 GLOB_ff_tostring,
875 GLOB_fff_gcstep,
876 GLOB_ff_next,
877 GLOB_fff_res2,
878 GLOB_fff_res,
879 GLOB_ff_pairs,
880 GLOB_ff_ipairs_aux,
881 GLOB_fff_res0,
882 GLOB_ff_ipairs,
883 GLOB_ff_pcall,
884 GLOB_ff_xpcall,
885 GLOB_ff_coroutine_resume,
886 GLOB_ff_coroutine_wrap_aux,
887 GLOB_ff_coroutine_yield,
888 GLOB_ff_math_abs,
889 GLOB_fff_resbit,
890 GLOB_ff_math_floor,
891 GLOB_vm_floor,
892 GLOB_ff_math_ceil,
893 GLOB_vm_ceil,
894 GLOB_ff_math_sqrt,
895 GLOB_ff_math_log,
896 GLOB_ff_math_log10,
897 GLOB_ff_math_exp,
898 GLOB_vm_exp_x87,
899 GLOB_ff_math_sin,
900 GLOB_ff_math_cos,
901 GLOB_ff_math_tan,
902 GLOB_ff_math_asin,
903 GLOB_ff_math_acos,
904 GLOB_ff_math_atan,
905 GLOB_ff_math_sinh,
906 GLOB_ff_math_cosh,
907 GLOB_ff_math_tanh,
908 GLOB_ff_math_deg,
909 GLOB_ff_math_rad,
910 GLOB_ff_math_atan2,
911 GLOB_ff_math_ldexp,
912 GLOB_ff_math_frexp,
913 GLOB_ff_math_modf,
914 GLOB_vm_trunc,
915 GLOB_ff_math_fmod,
916 GLOB_ff_math_pow,
917 GLOB_vm_pow,
918 GLOB_ff_math_min,
919 GLOB_ff_math_max,
920 GLOB_ff_string_len,
921 GLOB_ff_string_byte,
922 GLOB_ff_string_char,
923 GLOB_fff_newstr,
924 GLOB_ff_string_sub,
925 GLOB_fff_emptystr,
926 GLOB_ff_string_rep,
927 GLOB_fff_fallback_2,
928 GLOB_ff_string_reverse,
929 GLOB_fff_fallback_1,
930 GLOB_ff_string_lower,
931 GLOB_ff_string_upper,
932 GLOB_ff_table_getn,
933 GLOB_ff_bit_tobit,
934 GLOB_ff_bit_band,
935 GLOB_fff_fallback_bit_op,
936 GLOB_ff_bit_bor,
937 GLOB_ff_bit_bxor,
938 GLOB_ff_bit_bswap,
939 GLOB_ff_bit_bnot,
940 GLOB_ff_bit_lshift,
941 GLOB_ff_bit_rshift,
942 GLOB_ff_bit_arshift,
943 GLOB_ff_bit_rol,
944 GLOB_ff_bit_ror,
945 GLOB_vm_record,
946 GLOB_vm_rethook,
947 GLOB_vm_inshook,
948 GLOB_cont_hook,
949 GLOB_vm_hotloop,
950 GLOB_vm_callhook,
951 GLOB_vm_hotcall,
952 GLOB_vm_exit_handler,
953 GLOB_vm_exit_interp,
954 GLOB_vm_floor_sse,
955 GLOB_vm_ceil_sse,
956 GLOB_vm_trunc_sse,
957 GLOB_vm_mod,
958 GLOB_vm_exp2_x87,
959 GLOB_vm_exp2raw,
960 GLOB_vm_pow_sse,
961 GLOB_vm_powi_sse,
962 GLOB_vm_foldfpm,
963 GLOB_vm_foldarith,
964 GLOB_vm_cpuid,
965 GLOB_assert_bad_for_arg_type,
966 GLOB_vm_ffi_callback,
967 GLOB_vm_ffi_call,
968 GLOB_BC_MODVN_Z,
969 GLOB_BC_TGETS_Z,
970 GLOB_BC_TSETS_Z,
971 GLOB__MAX
972};
973static const char *const globnames[] = {
974 "vm_returnp",
975 "cont_dispatch",
976 "vm_returnc",
977 "BC_RET_Z",
978 "vm_return",
979 "vm_leave_cp",
980 "vm_leave_unw",
981 "vm_unwind_c@8",
982 "vm_unwind_c_eh",
983 "vm_unwind_rethrow",
984 "vm_unwind_ff@4",
985 "vm_unwind_ff_eh",
986 "vm_growstack_c",
987 "vm_growstack_v",
988 "vm_growstack_f",
989 "vm_resume",
990 "vm_pcall",
991 "vm_call",
992 "vm_call_dispatch",
993 "vmeta_call",
994 "vm_call_dispatch_f",
995 "vm_cpcall",
996 "cont_ffi_callback",
997 "vm_call_tail",
998 "cont_cat",
999 "cont_ra",
1000 "BC_CAT_Z",
1001 "vmeta_tgets",
1002 "vmeta_tgetb",
1003 "vmeta_tgetv",
1004 "vmeta_tsets",
1005 "vmeta_tsetb",
1006 "vmeta_tsetv",
1007 "cont_nop",
1008 "vmeta_comp",
1009 "vmeta_binop",
1010 "cont_condt",
1011 "cont_condf",
1012 "vmeta_equal",
1013 "vmeta_equal_cd",
1014 "vmeta_arith_vno",
1015 "vmeta_arith_vn",
1016 "vmeta_arith_nvo",
1017 "vmeta_arith_nv",
1018 "vmeta_unm",
1019 "vmeta_arith_vvo",
1020 "vmeta_arith_vv",
1021 "vmeta_len",
1022 "BC_LEN_Z",
1023 "vmeta_call_ra",
1024 "BC_CALLT_Z",
1025 "vmeta_for",
1026 "ff_assert",
1027 "fff_fallback",
1028 "fff_res_",
1029 "ff_type",
1030 "fff_res1",
1031 "ff_getmetatable",
1032 "ff_setmetatable",
1033 "ff_rawget",
1034 "ff_tonumber",
1035 "fff_resi",
1036 "fff_resxmm0",
1037 "fff_resn",
1038 "ff_tostring",
1039 "fff_gcstep",
1040 "ff_next",
1041 "fff_res2",
1042 "fff_res",
1043 "ff_pairs",
1044 "ff_ipairs_aux",
1045 "fff_res0",
1046 "ff_ipairs",
1047 "ff_pcall",
1048 "ff_xpcall",
1049 "ff_coroutine_resume",
1050 "ff_coroutine_wrap_aux",
1051 "ff_coroutine_yield",
1052 "ff_math_abs",
1053 "fff_resbit",
1054 "ff_math_floor",
1055 "vm_floor",
1056 "ff_math_ceil",
1057 "vm_ceil",
1058 "ff_math_sqrt",
1059 "ff_math_log",
1060 "ff_math_log10",
1061 "ff_math_exp",
1062 "vm_exp_x87",
1063 "ff_math_sin",
1064 "ff_math_cos",
1065 "ff_math_tan",
1066 "ff_math_asin",
1067 "ff_math_acos",
1068 "ff_math_atan",
1069 "ff_math_sinh",
1070 "ff_math_cosh",
1071 "ff_math_tanh",
1072 "ff_math_deg",
1073 "ff_math_rad",
1074 "ff_math_atan2",
1075 "ff_math_ldexp",
1076 "ff_math_frexp",
1077 "ff_math_modf",
1078 "vm_trunc",
1079 "ff_math_fmod",
1080 "ff_math_pow",
1081 "vm_pow",
1082 "ff_math_min",
1083 "ff_math_max",
1084 "ff_string_len",
1085 "ff_string_byte",
1086 "ff_string_char",
1087 "fff_newstr",
1088 "ff_string_sub",
1089 "fff_emptystr",
1090 "ff_string_rep",
1091 "fff_fallback_2",
1092 "ff_string_reverse",
1093 "fff_fallback_1",
1094 "ff_string_lower",
1095 "ff_string_upper",
1096 "ff_table_getn",
1097 "ff_bit_tobit",
1098 "ff_bit_band",
1099 "fff_fallback_bit_op",
1100 "ff_bit_bor",
1101 "ff_bit_bxor",
1102 "ff_bit_bswap",
1103 "ff_bit_bnot",
1104 "ff_bit_lshift",
1105 "ff_bit_rshift",
1106 "ff_bit_arshift",
1107 "ff_bit_rol",
1108 "ff_bit_ror",
1109 "vm_record",
1110 "vm_rethook",
1111 "vm_inshook",
1112 "cont_hook",
1113 "vm_hotloop",
1114 "vm_callhook",
1115 "vm_hotcall",
1116 "vm_exit_handler",
1117 "vm_exit_interp",
1118 "vm_floor_sse",
1119 "vm_ceil_sse",
1120 "vm_trunc_sse",
1121 "vm_mod",
1122 "vm_exp2_x87",
1123 "vm_exp2raw",
1124 "vm_pow_sse",
1125 "vm_powi_sse",
1126 "vm_foldfpm",
1127 "vm_foldarith",
1128 "vm_cpuid",
1129 "assert_bad_for_arg_type",
1130 "vm_ffi_callback",
1131 "vm_ffi_call@4",
1132 "BC_MODVN_Z",
1133 "BC_TGETS_Z",
1134 "BC_TSETS_Z",
1135 (const char *)0
1136};
1137static const char *const extnames[] = {
1138 "lj_state_growstack@8",
1139 "lj_err_throw@8",
1140 "lj_meta_tget",
1141 "lj_meta_tset",
1142 "lj_meta_comp",
1143 "lj_meta_equal",
1144 "lj_meta_equal_cd@8",
1145 "lj_meta_arith",
1146 "lj_meta_len@8",
1147 "lj_meta_call",
1148 "lj_meta_for@8",
1149 "lj_tab_get",
1150 "lj_str_fromnumber@8",
1151 "lj_str_fromnum@8",
1152 "lj_tab_next",
1153 "lj_tab_getinth@8",
1154 "lj_ffh_coroutine_wrap_err@8",
1155 "lj_vm_sinh",
1156 "lj_vm_cosh",
1157 "lj_vm_tanh",
1158 "lj_str_new",
1159 "lj_tab_len@4",
1160 "lj_gc_step@4",
1161 "lj_dispatch_ins@8",
1162 "lj_trace_hot@8",
1163 "lj_dispatch_call@8",
1164 "lj_trace_exit@8",
1165 "lj_ccallback_enter@8",
1166 "lj_ccallback_leave@8",
1167 "lj_meta_cat",
1168 "lj_gc_barrieruv@8",
1169 "lj_func_closeuv@8",
1170 "lj_func_newL_gc",
1171 "lj_tab_new",
1172 "lj_gc_step_fixtop@4",
1173 "lj_tab_dup@8",
1174 "lj_tab_newkey",
1175 "lj_tab_reasize",
1176 (const char *)0
1177};
1178#define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V)
1179#define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V)
1180#define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V)
1181#define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V)
1182#define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V)
1183#define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V)
1184#define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V)
1185#define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V)
1186#define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V)
1187#define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V)
1188#define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V)
1189#define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V)
1190#define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V)
1191#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
1192#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
1193#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
1194
1195/* Generate subroutines used by opcodes and other parts of the VM. */
1196/* The .code_sub section should be last to help static branch prediction. */
1197static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
1198{
1199 dasm_put(Dst, 0);
1200 dasm_put(Dst, 2, FRAME_P, LJ_TTRUE, FRAME_TYPE, FRAME_C, FRAME_TYPE, DISPATCH_GL(vmstate), ~LJ_VMST_C);
1201 dasm_put(Dst, 109, Dt1(->base), Dt1(->top), Dt1(->cframe), Dt1(->maxstack), LJ_TNIL);
1202 dasm_put(Dst, 200, Dt1(->top), Dt1(->top), Dt1(->glref), Dt2(->vmstate), ~LJ_VMST_C, CFRAME_RAWMASK);
1203 dasm_put(Dst, 302, 1+1, Dt1(->base), Dt1(->glref), GG_G2DISP, LJ_TFALSE, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, LUA_MINSTACK, -4+PC2PROTO(framesize), Dt1(->base));
1204 dasm_put(Dst, 385, Dt1(->top), Dt1(->base), Dt1(->top), Dt7(->pc), FRAME_CP, CFRAME_RESUME, Dt1(->glref), GG_G2DISP, Dt1(->cframe), Dt1(->status), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->status), Dt1(->base), Dt1(->top), FRAME_TYPE);
1205 dasm_put(Dst, 548, FRAME_CP, FRAME_C, Dt1(->cframe), Dt1(->cframe), Dt1(->glref), GG_G2DISP, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base));
1206 dasm_put(Dst, 648, Dt1(->top), LJ_TFUNC, Dt7(->pc), Dt1(->stack), Dt1(->top), Dt1(->cframe), Dt1(->cframe), FRAME_CP, LJ_TNIL);
1207#if LJ_HASFFI
1208 dasm_put(Dst, 813);
1209#endif
1210 dasm_put(Dst, 822, 0);
1211#if LJ_HASFFI
1212#endif
1213 dasm_put(Dst, 831, Dt7(->pc), PC2PROTO(k));
1214#if LJ_HASFFI
1215 dasm_put(Dst, 848);
1216#endif
1217 dasm_put(Dst, 869, Dt1(->base), LJ_TSTR, BC_GGET, DISPATCH_GL(tmptv), LJ_TTAB);
1218 if (LJ_DUALNUM) {
1219 dasm_put(Dst, 967, LJ_TISNUM);
1220 } else if (sse) {
1221 dasm_put(Dst, 976);
1222 } else {
1223 }
1224 dasm_put(Dst, 988, Dt1(->base), Dt1(->base), Dt1(->top), FRAME_CONT, 2+1, LJ_TSTR, BC_GSET);
1225 dasm_put(Dst, 1134, DISPATCH_GL(tmptv), LJ_TTAB);
1226 if (LJ_DUALNUM) {
1227 dasm_put(Dst, 967, LJ_TISNUM);
1228 } else if (sse) {
1229 dasm_put(Dst, 976);
1230 } else {
1231 }
1232 dasm_put(Dst, 1158, Dt1(->base), Dt1(->base), Dt1(->top), FRAME_CONT, 3+1, Dt1(->base), Dt1(->base));
1233 dasm_put(Dst, 1330, -BCBIAS_J*4, LJ_TISTRUECOND, LJ_TISTRUECOND, Dt1(->base));
1234 dasm_put(Dst, 1429);
1235#if LJ_HASFFI
1236 dasm_put(Dst, 1449, Dt1(->base));
1237#endif
1238 dasm_put(Dst, 1480);
1239#if LJ_DUALNUM
1240 dasm_put(Dst, 1483);
1241#endif
1242 dasm_put(Dst, 1489);
1243#if LJ_DUALNUM
1244 dasm_put(Dst, 961);
1245#endif
1246 dasm_put(Dst, 1502);
1247#if LJ_DUALNUM
1248 dasm_put(Dst, 1483);
1249#endif
1250 dasm_put(Dst, 1531, Dt1(->base), Dt1(->base), FRAME_CONT, 2+1, Dt1(->base), Dt1(->base));
1251#ifdef LUAJIT_ENABLE_LUA52COMPAT
1252 dasm_put(Dst, 1633);
1253#else
1254 dasm_put(Dst, 1652);
1255#endif
1256 dasm_put(Dst, 1657, Dt1(->base), Dt1(->base), Dt7(->pc), Dt1(->base), Dt1(->base), GG_DISP2STATIC, 1+1, LJ_TISTRUECOND);
1257 dasm_put(Dst, 1843, 1+1, ~LJ_TNUMX);
1258 if (cmov) {
1259 dasm_put(Dst, 1912);
1260 } else {
1261 dasm_put(Dst, 1916);
1262 }
1263 dasm_put(Dst, 1925, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, ~LJ_TLIGHTUD, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL);
1264 dasm_put(Dst, 2004, DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable), LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next));
1265 dasm_put(Dst, 2062, LJ_TNIL, LJ_TUDATA, LJ_TNUMX, LJ_TISNUM, LJ_TLIGHTUD);
1266 dasm_put(Dst, 2128, LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT]), 2+1, LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->metatable), LJ_TTAB);
1267 dasm_put(Dst, 2199, Dt6(->marked), LJ_GC_BLACK, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist), 2+1, LJ_TTAB);
1268 dasm_put(Dst, 2289, 1+1, LJ_TISNUM);
1269 if (LJ_DUALNUM) {
1270 dasm_put(Dst, 2303);
1271 } else {
1272 dasm_put(Dst, 2320);
1273 }
1274 if (sse) {
1275 dasm_put(Dst, 2325);
1276 } else {
1277 dasm_put(Dst, 2335);
1278 }
1279 dasm_put(Dst, 2342, 1+1, LJ_TSTR, LJ_TSTR, LJ_TISNUM, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
1280 dasm_put(Dst, 2411, Dt1(->base));
1281 if (LJ_DUALNUM) {
1282 dasm_put(Dst, 2437);
1283 } else {
1284 dasm_put(Dst, 2442);
1285 }
1286 dasm_put(Dst, 2447, Dt1(->base), 1+1, LJ_TTAB, Dt1(->base), Dt1(->top), Dt1(->base), 1+2);
1287 dasm_put(Dst, 2539, LJ_TNIL, LJ_TNIL, 1+1, LJ_TTAB);
1288#ifdef LUAJIT_ENABLE_LUA52COMPAT
1289 dasm_put(Dst, 2586, Dt6(->metatable));
1290#endif
1291 dasm_put(Dst, 2595, Dt8(->upvalue[0]), LJ_TFUNC, LJ_TNIL, 1+3, 1+1, LJ_TTAB, LJ_TISNUM);
1292 if (LJ_DUALNUM) {
1293 dasm_put(Dst, 2581);
1294 } else {
1295 dasm_put(Dst, 2320);
1296 }
1297 dasm_put(Dst, 2650);
1298 if (LJ_DUALNUM) {
1299 dasm_put(Dst, 2655, LJ_TISNUM);
1300 } else if (sse) {
1301 dasm_put(Dst, 2671, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1302 } else {
1303 }
1304 dasm_put(Dst, 2704, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->hmask), 1+0);
1305 dasm_put(Dst, 2566, 1+1, LJ_TTAB);
1306#ifdef LUAJIT_ENABLE_LUA52COMPAT
1307 dasm_put(Dst, 2586, Dt6(->metatable));
1308#endif
1309 dasm_put(Dst, 2781, Dt8(->upvalue[0]), LJ_TFUNC);
1310 if (LJ_DUALNUM) {
1311 dasm_put(Dst, 2802, LJ_TISNUM);
1312 } else if (sse) {
1313 dasm_put(Dst, 2814);
1314 } else {
1315 dasm_put(Dst, 2824);
1316 }
1317 dasm_put(Dst, 2831, 1+3, 1+1, 8+FRAME_PCALL, DISPATCH_GL(hookmask), HOOK_ACTIVE_SHIFT, 2+1, LJ_TFUNC);
1318 dasm_put(Dst, 2896, LJ_TFUNC, 16+FRAME_PCALL, 1+1, LJ_TTHREAD, Dt1(->cframe), Dt1(->status), LUA_YIELD, Dt1(->top));
1319 dasm_put(Dst, 2985, Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP);
1320 dasm_put(Dst, 3072, Dt1(->base), LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack), LJ_TTRUE, FRAME_TYPE);
1321 dasm_put(Dst, 3187, LJ_TFALSE, Dt1(->top), Dt1(->top), 1+2, Dt1(->top), Dt1(->base), Dt8(->upvalue[0].gcr), Dt1(->cframe));
1322 dasm_put(Dst, 3282, Dt1(->status), LUA_YIELD, Dt1(->top), Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top));
1323 dasm_put(Dst, 3348, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack));
1324 dasm_put(Dst, 3437, FRAME_TYPE, Dt1(->top), Dt1(->base), Dt1(->cframe), CFRAME_RESUME);
1325 dasm_put(Dst, 3547, Dt1(->base), Dt1(->top), Dt1(->cframe), LUA_YIELD, Dt1(->status));
1326 if (!LJ_DUALNUM) {
1327 dasm_put(Dst, 3574);
1328 }
1329 if (sse) {
1330 dasm_put(Dst, 3577);
1331 }
1332 dasm_put(Dst, 3592, 1+1);
1333 if (LJ_DUALNUM) {
1334 dasm_put(Dst, 3603, LJ_TISNUM, LJ_TISNUM);
1335 } else {
1336 dasm_put(Dst, 3683, LJ_TISNUM);
1337 }
1338 if (sse) {
1339 dasm_put(Dst, 3693, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32));
1340 } else {
1341 dasm_put(Dst, 3724);
1342 }
1343 dasm_put(Dst, 3741, 1+1, FRAME_TYPE, LJ_TNIL);
1344 if (LJ_DUALNUM) {
1345 dasm_put(Dst, 3838, LJ_TISNUM);
1346 } else {
1347 dasm_put(Dst, 3683, LJ_TISNUM);
1348 }
1349 if (sse) {
1350 dasm_put(Dst, 3860);
1351 if (LJ_DUALNUM) {
1352 dasm_put(Dst, 3869);
1353 }
1354 dasm_put(Dst, 2330);
1355 } else {
1356 dasm_put(Dst, 3903);
1357 if (LJ_DUALNUM) {
1358 } else {
1359 dasm_put(Dst, 2337);
1360 }
1361 }
1362 dasm_put(Dst, 3909);
1363 if (LJ_DUALNUM) {
1364 dasm_put(Dst, 3838, LJ_TISNUM);
1365 } else {
1366 dasm_put(Dst, 3683, LJ_TISNUM);
1367 }
1368 if (sse) {
1369 dasm_put(Dst, 3912);
1370 if (LJ_DUALNUM) {
1371 dasm_put(Dst, 3869);
1372 }
1373 dasm_put(Dst, 2330);
1374 } else {
1375 dasm_put(Dst, 3921);
1376 if (LJ_DUALNUM) {
1377 } else {
1378 dasm_put(Dst, 2337);
1379 }
1380 }
1381 if (sse) {
1382 dasm_put(Dst, 3927, 1+1, LJ_TISNUM);
1383 } else {
1384 dasm_put(Dst, 3956, 1+1, LJ_TISNUM);
1385 }
1386 dasm_put(Dst, 3985, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1387 dasm_put(Dst, 4054, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1388 dasm_put(Dst, 4111, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1389 dasm_put(Dst, 4174, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
1390 dasm_put(Dst, 4264);
1391 if (sse) {
1392 dasm_put(Dst, 4276, 1+1, LJ_TISNUM);
1393 } else {
1394 }
1395 dasm_put(Dst, 4301);
1396 if (sse) {
1397 dasm_put(Dst, 4315, 1+1, LJ_TISNUM);
1398 } else {
1399 }
1400 dasm_put(Dst, 4340);
1401 if (sse) {
1402 dasm_put(Dst, 4354, 1+1, LJ_TISNUM);
1403 } else {
1404 }
1405 dasm_put(Dst, 4379);
1406 if (sse) {
1407 dasm_put(Dst, 4395, 1+1, LJ_TISNUM, Dt8(->upvalue[0]));
1408 } else {
1409 dasm_put(Dst, 4434, 1+1, LJ_TISNUM, Dt8(->upvalue[0]));
1410 }
1411 dasm_put(Dst, 4467, 2+1, LJ_TISNUM, LJ_TISNUM, 2+1, LJ_TISNUM, LJ_TISNUM);
1412 dasm_put(Dst, 4532, 1+1, LJ_TISNUM);
1413 if (sse) {
1414 dasm_put(Dst, 4631);
1415 } else {
1416 dasm_put(Dst, 4637);
1417 }
1418 dasm_put(Dst, 4644);
1419 if (sse) {
1420 dasm_put(Dst, 4669);
1421 } else {
1422 dasm_put(Dst, 4675);
1423 }
1424 dasm_put(Dst, 4678, 1+2);
1425 if (sse) {
1426 dasm_put(Dst, 4687);
1427 } else {
1428 dasm_put(Dst, 4695);
1429 }
1430 dasm_put(Dst, 4703);
1431 if (sse) {
1432 dasm_put(Dst, 4706, (unsigned int)(U64x(43500000,00000000)), (unsigned int)((U64x(43500000,00000000))>>32));
1433 } else {
1434 dasm_put(Dst, 4733);
1435 }
1436 dasm_put(Dst, 4750);
1437 if (sse) {
1438 dasm_put(Dst, 4766, 1+1, LJ_TISNUM);
1439 } else {
1440 dasm_put(Dst, 4791, 1+1, LJ_TISNUM);
1441 }
1442 dasm_put(Dst, 4813);
1443 if (sse) {
1444 dasm_put(Dst, 4835);
1445 } else {
1446 dasm_put(Dst, 4861);
1447 }
1448 dasm_put(Dst, 4878, 1+2);
1449 if (sse) {
1450 dasm_put(Dst, 4918);
1451 } else {
1452 dasm_put(Dst, 4926);
1453 }
1454 dasm_put(Dst, 4936, 2+1, LJ_TISNUM, LJ_TISNUM);
1455 if (sse) {
1456 dasm_put(Dst, 4988, 2+1, LJ_TISNUM, LJ_TISNUM);
1457 } else {
1458 dasm_put(Dst, 5035, 2+1, LJ_TISNUM, LJ_TISNUM);
1459 }
1460 dasm_put(Dst, 5076, LJ_TISNUM);
1461 if (LJ_DUALNUM) {
1462 dasm_put(Dst, 5089, LJ_TISNUM);
1463 if (sse) {
1464 dasm_put(Dst, 4631);
1465 } else {
1466 }
1467 dasm_put(Dst, 5139);
1468 } else {
1469 dasm_put(Dst, 2320);
1470 }
1471 if (sse) {
1472 dasm_put(Dst, 5150, LJ_TISNUM);
1473 if (LJ_DUALNUM) {
1474 dasm_put(Dst, 5171);
1475 } else {
1476 dasm_put(Dst, 2320);
1477 }
1478 dasm_put(Dst, 5192);
1479 } else {
1480 }
1481 dasm_put(Dst, 5217, LJ_TISNUM);
1482 if (LJ_DUALNUM) {
1483 dasm_put(Dst, 5230, LJ_TISNUM);
1484 if (sse) {
1485 dasm_put(Dst, 4631);
1486 } else {
1487 }
1488 dasm_put(Dst, 5139);
1489 } else {
1490 dasm_put(Dst, 2320);
1491 }
1492 if (sse) {
1493 dasm_put(Dst, 5150, LJ_TISNUM);
1494 if (LJ_DUALNUM) {
1495 dasm_put(Dst, 5171);
1496 } else {
1497 dasm_put(Dst, 2320);
1498 }
1499 dasm_put(Dst, 5280);
1500 } else {
1501 }
1502 if (!sse) {
1503 dasm_put(Dst, 5305);
1504 }
1505 dasm_put(Dst, 5314, 1+1, LJ_TSTR);
1506 if (LJ_DUALNUM) {
1507 dasm_put(Dst, 5336, Dt5(->len));
1508 } else if (sse) {
1509 dasm_put(Dst, 5344, Dt5(->len));
1510 } else {
1511 dasm_put(Dst, 5355, Dt5(->len));
1512 }
1513 dasm_put(Dst, 5363, 1+1, LJ_TSTR, Dt5(->len), Dt5([1]));
1514 if (LJ_DUALNUM) {
1515 dasm_put(Dst, 5339);
1516 } else if (sse) {
1517 dasm_put(Dst, 5401);
1518 } else {
1519 dasm_put(Dst, 5411);
1520 }
1521 dasm_put(Dst, 5422, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 1+1, LJ_TISNUM);
1522 if (LJ_DUALNUM) {
1523 dasm_put(Dst, 5455);
1524 } else if (sse) {
1525 dasm_put(Dst, 5478);
1526 } else {
1527 dasm_put(Dst, 5504);
1528 }
1529 dasm_put(Dst, 5528, Dt1(->base), Dt1(->base), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 1+2, LJ_TISNUM);
1530 if (LJ_DUALNUM) {
1531 dasm_put(Dst, 5637);
1532 } else if (sse) {
1533 dasm_put(Dst, 5649);
1534 } else {
1535 dasm_put(Dst, 5664);
1536 }
1537 dasm_put(Dst, 5676, LJ_TSTR, LJ_TISNUM);
1538 if (LJ_DUALNUM) {
1539 dasm_put(Dst, 2581);
1540 } else {
1541 dasm_put(Dst, 2320);
1542 }
1543 dasm_put(Dst, 5693, Dt5(->len));
1544 if (LJ_DUALNUM) {
1545 dasm_put(Dst, 5703);
1546 } else if (sse) {
1547 dasm_put(Dst, 5707);
1548 } else {
1549 }
1550 dasm_put(Dst, 5714, sizeof(GCstr)-1);
1551 dasm_put(Dst, 5789, 2+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
1552 dasm_put(Dst, 5850, LJ_TSTR, LJ_TISNUM);
1553 if (LJ_DUALNUM) {
1554 dasm_put(Dst, 5867);
1555 } else if (sse) {
1556 dasm_put(Dst, 5875);
1557 } else {
1558 dasm_put(Dst, 5886);
1559 }
1560 dasm_put(Dst, 5902, Dt5(->len), DISPATCH_GL(tmpbuf.sz), Dt5([1]), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(tmpbuf.buf), 1+1);
1561 dasm_put(Dst, 5970, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
1562 dasm_put(Dst, 6037, 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz));
1563 dasm_put(Dst, 6110, sizeof(GCstr), DISPATCH_GL(tmpbuf.buf), 1+1);
1564 dasm_put(Dst, 6195, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
1565 dasm_put(Dst, 6269, 1+1, LJ_TTAB);
1566 if (LJ_DUALNUM) {
1567 dasm_put(Dst, 6336);
1568 } else if (sse) {
1569 dasm_put(Dst, 6343);
1570 } else {
1571 }
1572 dasm_put(Dst, 6353, 1+1, LJ_TISNUM);
1573 if (LJ_DUALNUM) {
1574 dasm_put(Dst, 6369);
1575 } else {
1576 dasm_put(Dst, 2320);
1577 }
1578 if (sse) {
1579 dasm_put(Dst, 6386, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1580 } else {
1581 }
1582 dasm_put(Dst, 106);
1583 if (LJ_DUALNUM || sse) {
1584 if (!sse) {
1585 }
1586 dasm_put(Dst, 6410);
1587 } else {
1588 }
1589 dasm_put(Dst, 6415, 1+1);
1590 if (sse) {
1591 dasm_put(Dst, 6426, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1592 } else {
1593 dasm_put(Dst, 6436);
1594 }
1595 dasm_put(Dst, 2297, LJ_TISNUM);
1596 if (LJ_DUALNUM) {
1597 dasm_put(Dst, 6444);
1598 } else {
1599 dasm_put(Dst, 2320);
1600 }
1601 if (sse) {
1602 dasm_put(Dst, 6461);
1603 } else {
1604 }
1605 dasm_put(Dst, 6476, LJ_TISNUM);
1606 if (LJ_DUALNUM) {
1607 dasm_put(Dst, 6501);
1608 } else {
1609 dasm_put(Dst, 6521);
1610 }
1611 if (sse) {
1612 dasm_put(Dst, 6526);
1613 } else {
1614 }
1615 dasm_put(Dst, 6543, 1+1);
1616 if (sse) {
1617 dasm_put(Dst, 6426, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1618 } else {
1619 dasm_put(Dst, 6436);
1620 }
1621 dasm_put(Dst, 2297, LJ_TISNUM);
1622 if (LJ_DUALNUM) {
1623 dasm_put(Dst, 6444);
1624 } else {
1625 dasm_put(Dst, 2320);
1626 }
1627 if (sse) {
1628 dasm_put(Dst, 6461);
1629 } else {
1630 }
1631 dasm_put(Dst, 6476, LJ_TISNUM);
1632 if (LJ_DUALNUM) {
1633 dasm_put(Dst, 6561);
1634 } else {
1635 dasm_put(Dst, 6521);
1636 }
1637 if (sse) {
1638 dasm_put(Dst, 6581);
1639 } else {
1640 }
1641 dasm_put(Dst, 6598, 1+1);
1642 if (sse) {
1643 dasm_put(Dst, 6426, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1644 } else {
1645 dasm_put(Dst, 6436);
1646 }
1647 dasm_put(Dst, 2297, LJ_TISNUM);
1648 if (LJ_DUALNUM) {
1649 dasm_put(Dst, 6444);
1650 } else {
1651 dasm_put(Dst, 2320);
1652 }
1653 if (sse) {
1654 dasm_put(Dst, 6461);
1655 } else {
1656 }
1657 dasm_put(Dst, 6476, LJ_TISNUM);
1658 if (LJ_DUALNUM) {
1659 dasm_put(Dst, 6616);
1660 } else {
1661 dasm_put(Dst, 6521);
1662 }
1663 if (sse) {
1664 dasm_put(Dst, 6636);
1665 } else {
1666 }
1667 dasm_put(Dst, 6653, 1+1, LJ_TISNUM);
1668 if (LJ_DUALNUM) {
1669 dasm_put(Dst, 6444);
1670 } else {
1671 dasm_put(Dst, 2320);
1672 }
1673 if (sse) {
1674 dasm_put(Dst, 6386, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1675 } else {
1676 }
1677 dasm_put(Dst, 6676, 1+1, LJ_TISNUM);
1678 if (LJ_DUALNUM) {
1679 dasm_put(Dst, 6444);
1680 } else {
1681 dasm_put(Dst, 2320);
1682 }
1683 if (sse) {
1684 dasm_put(Dst, 6386, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1685 } else {
1686 }
1687 dasm_put(Dst, 6700);
1688 if (LJ_DUALNUM) {
1689 dasm_put(Dst, 6410);
1690 } else if (sse) {
1691 dasm_put(Dst, 6706);
1692 } else {
1693 }
1694 dasm_put(Dst, 6718);
1695 if (LJ_DUALNUM) {
1696 dasm_put(Dst, 6729, 1+1, LJ_TISNUM);
1697 if (LJ_DUALNUM) {
1698 dasm_put(Dst, 6444);
1699 } else {
1700 dasm_put(Dst, 2320);
1701 }
1702 if (sse) {
1703 dasm_put(Dst, 6386, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1704 } else {
1705 }
1706 dasm_put(Dst, 6745, LJ_TISNUM);
1707 } else if (sse) {
1708 dasm_put(Dst, 6760, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1709 } else {
1710 }
1711 dasm_put(Dst, 6827);
1712 if (LJ_DUALNUM) {
1713 dasm_put(Dst, 6834, 1+1, LJ_TISNUM);
1714 if (LJ_DUALNUM) {
1715 dasm_put(Dst, 6444);
1716 } else {
1717 dasm_put(Dst, 2320);
1718 }
1719 if (sse) {
1720 dasm_put(Dst, 6386, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1721 } else {
1722 }
1723 dasm_put(Dst, 6745, LJ_TISNUM);
1724 } else if (sse) {
1725 dasm_put(Dst, 6850, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1726 } else {
1727 }
1728 dasm_put(Dst, 6917);
1729 if (LJ_DUALNUM) {
1730 dasm_put(Dst, 6925, 1+1, LJ_TISNUM);
1731 if (LJ_DUALNUM) {
1732 dasm_put(Dst, 6444);
1733 } else {
1734 dasm_put(Dst, 2320);
1735 }
1736 if (sse) {
1737 dasm_put(Dst, 6386, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1738 } else {
1739 }
1740 dasm_put(Dst, 6745, LJ_TISNUM);
1741 } else if (sse) {
1742 dasm_put(Dst, 6941, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1743 } else {
1744 }
1745 dasm_put(Dst, 7008);
1746 if (LJ_DUALNUM) {
1747 dasm_put(Dst, 7016, 1+1, LJ_TISNUM);
1748 if (LJ_DUALNUM) {
1749 dasm_put(Dst, 6444);
1750 } else {
1751 dasm_put(Dst, 2320);
1752 }
1753 if (sse) {
1754 dasm_put(Dst, 6386, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1755 } else {
1756 }
1757 dasm_put(Dst, 6745, LJ_TISNUM);
1758 } else if (sse) {
1759 dasm_put(Dst, 7032, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1760 } else {
1761 }
1762 dasm_put(Dst, 7099);
1763 if (LJ_DUALNUM) {
1764 dasm_put(Dst, 7106, 1+1, LJ_TISNUM);
1765 if (LJ_DUALNUM) {
1766 dasm_put(Dst, 6444);
1767 } else {
1768 dasm_put(Dst, 2320);
1769 }
1770 if (sse) {
1771 dasm_put(Dst, 6386, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1772 } else {
1773 }
1774 dasm_put(Dst, 6745, LJ_TISNUM);
1775 } else if (sse) {
1776 dasm_put(Dst, 7122, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1777 } else {
1778 }
1779 dasm_put(Dst, 7189, 1+2, 1+1, Dt1(->base), 8*LUA_MINSTACK, Dt1(->top), Dt1(->maxstack), Dt8(->f), Dt1(->base));
1780 dasm_put(Dst, 7265, Dt1(->top), Dt7(->pc), FRAME_TYPE, LUA_MINSTACK, Dt1(->base), Dt1(->base));
1781 dasm_put(Dst, 7392, Dt1(->top), Dt1(->base), Dt1(->top));
1782#if LJ_HASJIT
1783 dasm_put(Dst, 7431, DISPATCH_GL(hookmask), HOOK_VMEVENT, HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount));
1784#endif
1785 dasm_put(Dst, 7464, DISPATCH_GL(hookmask), HOOK_ACTIVE, DISPATCH_GL(hookmask), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount), LUA_MASKLINE);
1786 dasm_put(Dst, 7518, Dt1(->base), Dt1(->base), GG_DISP2STATIC);
1787#if LJ_HASJIT
1788 dasm_put(Dst, 7585, Dt7(->pc), PC2PROTO(framesize), Dt1(->base), Dt1(->top), GG_DISP2J, DISPATCH_J(L));
1789#endif
1790 dasm_put(Dst, 7632);
1791#if LJ_HASJIT
1792 dasm_put(Dst, 7459);
1793#endif
1794 dasm_put(Dst, 7639);
1795#if LJ_HASJIT
1796 dasm_put(Dst, 7642);
1797#endif
1798 dasm_put(Dst, 7652, Dt1(->base), Dt1(->top));
1799#if LJ_HASJIT
1800 dasm_put(Dst, 7685);
1801#endif
1802 dasm_put(Dst, 7690, Dt1(->base), Dt1(->top));
1803#if LJ_HASJIT
1804 dasm_put(Dst, 7721, DISPATCH_GL(vmstate), DISPATCH_GL(vmstate), ~LJ_VMST_EXIT, DISPATCH_J(exitno), DISPATCH_J(parent), 16*8, DISPATCH_GL(jit_L), DISPATCH_GL(jit_base), DISPATCH_J(L), DISPATCH_GL(jit_L), Dt1(->base), GG_DISP2J, Dt1(->cframe), CFRAME_RAWMASK, CFRAME_OFS_L, Dt1(->base), CFRAME_OFS_PC);
1805#endif
1806 dasm_put(Dst, 7960);
1807#if LJ_HASJIT
1808 dasm_put(Dst, 7963, Dt7(->pc), PC2PROTO(k), DISPATCH_GL(jit_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, BC_FUNCF);
1809#endif
1810 dasm_put(Dst, 8063);
1811 if (!sse) {
1812 dasm_put(Dst, 8066);
1813 }
1814 dasm_put(Dst, 8111, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1815 if (!sse) {
1816 dasm_put(Dst, 8197);
1817 }
1818 dasm_put(Dst, 8242, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(bff00000,00000000)), (unsigned int)((U64x(bff00000,00000000))>>32));
1819 if (!sse) {
1820 dasm_put(Dst, 8328);
1821 }
1822 dasm_put(Dst, 8367, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1823 if (sse) {
1824 dasm_put(Dst, 8456, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1825 } else {
1826 dasm_put(Dst, 8570);
1827 }
1828 dasm_put(Dst, 8617);
1829 if (!sse) {
1830 } else {
1831 dasm_put(Dst, 8694);
1832 }
1833 dasm_put(Dst, 8697);
1834 dasm_put(Dst, 8782, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1835 dasm_put(Dst, 8885, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7ff00000,00000000)), (unsigned int)((U64x(7ff00000,00000000))>>32));
1836 dasm_put(Dst, 9047);
1837#if LJ_HASJIT
1838 if (sse) {
1839 dasm_put(Dst, 9088);
1840 dasm_put(Dst, 9158);
1841 dasm_put(Dst, 9230);
1842 } else {
1843 dasm_put(Dst, 9282);
1844 dasm_put(Dst, 9374);
1845 }
1846 dasm_put(Dst, 9420);
1847#endif
1848 dasm_put(Dst, 9424);
1849 if (sse) {
1850 dasm_put(Dst, 9427, (unsigned int)(U64x(80000000,00000000)), (unsigned int)((U64x(80000000,00000000))>>32));
1851 dasm_put(Dst, 9512, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32));
1852 } else {
1853 dasm_put(Dst, 9640);
1854 dasm_put(Dst, 9723);
1855 if (cmov) {
1856 dasm_put(Dst, 9778);
1857 } else {
1858 dasm_put(Dst, 9797);
1859 }
1860 dasm_put(Dst, 9420);
1861 }
1862 dasm_put(Dst, 9838);
1863#ifdef LUA_USE_ASSERT
1864 dasm_put(Dst, 9422);
1865#endif
1866 dasm_put(Dst, 9862);
1867#if LJ_HASFFI
1868#define DtE(_V) (int)(ptrdiff_t)&(((CTState *)0)_V)
1869 dasm_put(Dst, 9866, GG_G2DISP, Dt2(->ctype_state), DtE(->cb.slot), DtE(->cb.gpr[0]), DtE(->cb.gpr[1]), DtE(->cb.gpr[2]), DtE(->cb.gpr[3]), DtE(->cb.fpr[0]), DtE(->cb.fpr[1]), DtE(->cb.fpr[2]), DtE(->cb.fpr[3]), CFRAME_SIZE, DtE(->cb.gpr[4]), DtE(->cb.gpr[5]), DtE(->cb.fpr[4]), DtE(->cb.fpr[5]), DtE(->cb.fpr[6]), DtE(->cb.fpr[7]), DtE(->cb.stack), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP);
1870 dasm_put(Dst, 9990, Dt1(->base), Dt1(->top), Dt7(->pc));
1871#endif
1872 dasm_put(Dst, 10030);
1873#if LJ_HASFFI
1874 dasm_put(Dst, 10033, DISPATCH_GL(ctype_state), DtE(->L), Dt1(->base), Dt1(->top), DtE(->cb.gpr[0]), DtE(->cb.fpr[0]));
1875#endif
1876 dasm_put(Dst, 10074);
1877#if LJ_HASFFI
1878#define DtF(_V) (int)(ptrdiff_t)&(((CCallState *)0)_V)
1879 dasm_put(Dst, 10077, DtF(->spadj));
1880#if LJ_TARGET_WINDOWS
1881#endif
1882 dasm_put(Dst, 10093, DtF(->nsp), offsetof(CCallState, stack), CCALL_SPS_EXTRA*8, DtF(->nfpr), DtF(->gpr[0]), DtF(->gpr[1]), DtF(->gpr[2]), DtF(->gpr[3]), DtF(->gpr[4]), DtF(->gpr[5]), DtF(->fpr[0]), DtF(->fpr[1]));
1883 dasm_put(Dst, 10172, DtF(->fpr[2]), DtF(->fpr[3]), DtF(->fpr[4]), DtF(->fpr[5]), DtF(->fpr[6]), DtF(->fpr[7]), DtF(->func), DtF(->gpr[0]), DtF(->fpr[0]), DtF(->gpr[1]), DtF(->fpr[1]));
1884#if LJ_TARGET_WINDOWS
1885#endif
1886 dasm_put(Dst, 10227);
1887#endif
1888}
1889
1890/* Generate the code for a single instruction. */
1891static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse)
1892{
1893 int vk = 0;
1894 dasm_put(Dst, 829, defop);
1895
1896 switch (op) {
1897
1898 /* -- Comparison ops ---------------------------------------------------- */
1899
1900 /* Remember: all ops branch for a true comparison, fall through otherwise. */
1901
1902
1903 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
1904 if (LJ_DUALNUM) {
1905 dasm_put(Dst, 10235, LJ_TISNUM, LJ_TISNUM);
1906 switch (op) {
1907 case BC_ISLT:
1908 dasm_put(Dst, 10265);
1909 break;
1910 case BC_ISGE:
1911 dasm_put(Dst, 10270);
1912 break;
1913 case BC_ISLE:
1914 dasm_put(Dst, 10275);
1915 break;
1916 case BC_ISGT:
1917 dasm_put(Dst, 10280);
1918 break;
1919 default: break; /* Shut up GCC. */
1920 }
1921 dasm_put(Dst, 10285, -BCBIAS_J*4, LJ_TISNUM);
1922 if (sse) {
1923 dasm_put(Dst, 10340);
1924 } else {
1925 dasm_put(Dst, 10351);
1926 }
1927 dasm_put(Dst, 10362);
1928 if (sse) {
1929 dasm_put(Dst, 10369);
1930 switch (op) {
1931 case BC_ISLT:
1932 dasm_put(Dst, 10389);
1933 break;
1934 case BC_ISGE:
1935 dasm_put(Dst, 10394);
1936 break;
1937 case BC_ISLE:
1938 dasm_put(Dst, 10399);
1939 break;
1940 case BC_ISGT:
1941 dasm_put(Dst, 10404);
1942 break;
1943 default: break; /* Shut up GCC. */
1944 }
1945 dasm_put(Dst, 10409);
1946 } else {
1947 dasm_put(Dst, 10414);
1948 }
1949 } else {
1950 dasm_put(Dst, 10422, LJ_TISNUM, LJ_TISNUM);
1951 }
1952 if (sse) {
1953 dasm_put(Dst, 10443);
1954 } else {
1955 dasm_put(Dst, 10464);
1956 if (cmov) {
1957 dasm_put(Dst, 10480);
1958 } else {
1959 dasm_put(Dst, 10486);
1960 }
1961 }
1962 if (LJ_DUALNUM) {
1963 switch (op) {
1964 case BC_ISLT:
1965 dasm_put(Dst, 10389);
1966 break;
1967 case BC_ISGE:
1968 dasm_put(Dst, 10394);
1969 break;
1970 case BC_ISLE:
1971 dasm_put(Dst, 10399);
1972 break;
1973 case BC_ISGT:
1974 dasm_put(Dst, 10404);
1975 break;
1976 default: break; /* Shut up GCC. */
1977 }
1978 dasm_put(Dst, 10409);
1979 } else {
1980 switch (op) {
1981 case BC_ISLT:
1982 dasm_put(Dst, 817);
1983 break;
1984 case BC_ISGE:
1985 dasm_put(Dst, 10493);
1986 break;
1987 case BC_ISLE:
1988 dasm_put(Dst, 10498);
1989 break;
1990 case BC_ISGT:
1991 dasm_put(Dst, 10503);
1992 break;
1993 default: break; /* Shut up GCC. */
1994 }
1995 dasm_put(Dst, 10508, -BCBIAS_J*4);
1996 }
1997 break;
1998
1999 case BC_ISEQV: case BC_ISNEV:
2000 vk = op == BC_ISEQV;
2001 dasm_put(Dst, 10541);
2002 if (LJ_DUALNUM) {
2003 dasm_put(Dst, 10549, LJ_TISNUM, LJ_TISNUM);
2004 if (vk) {
2005 dasm_put(Dst, 10574);
2006 } else {
2007 dasm_put(Dst, 10579);
2008 }
2009 dasm_put(Dst, 10584, -BCBIAS_J*4, LJ_TISNUM);
2010 if (sse) {
2011 dasm_put(Dst, 10637);
2012 } else {
2013 dasm_put(Dst, 10644);
2014 }
2015 dasm_put(Dst, 10648);
2016 if (sse) {
2017 dasm_put(Dst, 10659);
2018 } else {
2019 dasm_put(Dst, 10671);
2020 }
2021 dasm_put(Dst, 10678);
2022 } else {
2023 dasm_put(Dst, 10683, LJ_TISNUM, LJ_TISNUM);
2024 }
2025 if (sse) {
2026 dasm_put(Dst, 10702);
2027 } else {
2028 dasm_put(Dst, 10720);
2029 if (cmov) {
2030 dasm_put(Dst, 10480);
2031 } else {
2032 dasm_put(Dst, 10486);
2033 }
2034 }
2035 iseqne_fp:
2036 if (vk) {
2037 dasm_put(Dst, 10733);
2038 } else {
2039 dasm_put(Dst, 10742);
2040 }
2041 iseqne_end:
2042 if (vk) {
2043 dasm_put(Dst, 10751, -BCBIAS_J*4);
2044 if (!LJ_HASFFI) {
2045 dasm_put(Dst, 4684);
2046 }
2047 } else {
2048 if (!LJ_HASFFI) {
2049 dasm_put(Dst, 4684);
2050 }
2051 dasm_put(Dst, 10766, -BCBIAS_J*4);
2052 }
2053 if (LJ_DUALNUM && (op == BC_ISEQV || op == BC_ISNEV ||
2054 op == BC_ISEQN || op == BC_ISNEN)) {
2055 dasm_put(Dst, 10781);
2056 } else {
2057 dasm_put(Dst, 10520);
2058 }
2059 if (op == BC_ISEQV || op == BC_ISNEV) {
2060 dasm_put(Dst, 10786);
2061 if (LJ_HASFFI) {
2062 dasm_put(Dst, 10789, LJ_TCDATA, LJ_TCDATA);
2063 }
2064 dasm_put(Dst, 10808, LJ_TISPRI, LJ_TISTABUD, LJ_TUDATA, Dt6(->metatable), Dt6(->nomm), 1<<MM_eq);
2065 if (vk) {
2066 dasm_put(Dst, 10872);
2067 } else {
2068 dasm_put(Dst, 10876);
2069 }
2070 dasm_put(Dst, 10882);
2071 } else if (LJ_HASFFI) {
2072 dasm_put(Dst, 10887, LJ_TCDATA);
2073 if (LJ_DUALNUM && vk) {
2074 dasm_put(Dst, 10894);
2075 } else {
2076 dasm_put(Dst, 10867);
2077 }
2078 dasm_put(Dst, 10899);
2079 }
2080 break;
2081 case BC_ISEQS: case BC_ISNES:
2082 vk = op == BC_ISEQS;
2083 dasm_put(Dst, 10904, LJ_TSTR);
2084 iseqne_test:
2085 if (vk) {
2086 dasm_put(Dst, 10737);
2087 } else {
2088 dasm_put(Dst, 2980);
2089 }
2090 goto iseqne_end;
2091 case BC_ISEQN: case BC_ISNEN:
2092 vk = op == BC_ISEQN;
2093 dasm_put(Dst, 10931);
2094 if (LJ_DUALNUM) {
2095 dasm_put(Dst, 10939, LJ_TISNUM, LJ_TISNUM);
2096 if (vk) {
2097 dasm_put(Dst, 10574);
2098 } else {
2099 dasm_put(Dst, 10579);
2100 }
2101 dasm_put(Dst, 10966, -BCBIAS_J*4, LJ_TISNUM);
2102 if (sse) {
2103 dasm_put(Dst, 11016);
2104 } else {
2105 dasm_put(Dst, 11024);
2106 }
2107 dasm_put(Dst, 11029);
2108 if (sse) {
2109 dasm_put(Dst, 11036);
2110 } else {
2111 dasm_put(Dst, 11049);
2112 }
2113 dasm_put(Dst, 10678);
2114 } else {
2115 dasm_put(Dst, 11057, LJ_TISNUM);
2116 }
2117 if (sse) {
2118 dasm_put(Dst, 11066);
2119 } else {
2120 dasm_put(Dst, 11085);
2121 if (cmov) {
2122 dasm_put(Dst, 10480);
2123 } else {
2124 dasm_put(Dst, 10486);
2125 }
2126 }
2127 goto iseqne_fp;
2128 case BC_ISEQP: case BC_ISNEP:
2129 vk = op == BC_ISEQP;
2130 dasm_put(Dst, 11099);
2131 if (!LJ_HASFFI) goto iseqne_test;
2132 if (vk) {
2133 dasm_put(Dst, 11113, -BCBIAS_J*4, LJ_TCDATA);
2134 } else {
2135 dasm_put(Dst, 11164, LJ_TCDATA, -BCBIAS_J*4);
2136 }
2137 break;
2138
2139 /* -- Unary test and copy ops ------------------------------------------- */
2140
2141 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
2142 dasm_put(Dst, 11209, LJ_TISTRUECOND);
2143 if (op == BC_IST || op == BC_ISTC) {
2144 dasm_put(Dst, 10503);
2145 } else {
2146 dasm_put(Dst, 10498);
2147 }
2148 if (op == BC_ISTC || op == BC_ISFC) {
2149 dasm_put(Dst, 11221);
2150 }
2151 dasm_put(Dst, 10508, -BCBIAS_J*4);
2152 break;
2153
2154 /* -- Unary ops --------------------------------------------------------- */
2155
2156 case BC_MOV:
2157 dasm_put(Dst, 11232);
2158 break;
2159 case BC_NOT:
2160 dasm_put(Dst, 11261, LJ_TISTRUECOND, LJ_TTRUE);
2161 break;
2162 case BC_UNM:
2163 if (LJ_DUALNUM) {
2164 dasm_put(Dst, 11298, LJ_TISNUM, LJ_TISNUM);
2165 } else {
2166 dasm_put(Dst, 11376, LJ_TISNUM);
2167 }
2168 if (sse) {
2169 dasm_put(Dst, 11387, (unsigned int)(U64x(80000000,00000000)), (unsigned int)((U64x(80000000,00000000))>>32));
2170 } else {
2171 dasm_put(Dst, 11412);
2172 }
2173 if (LJ_DUALNUM) {
2174 dasm_put(Dst, 10781);
2175 } else {
2176 dasm_put(Dst, 10520);
2177 }
2178 break;
2179 case BC_LEN:
2180 dasm_put(Dst, 11421, LJ_TSTR);
2181 if (LJ_DUALNUM) {
2182 dasm_put(Dst, 11435, Dt5(->len), LJ_TISNUM);
2183 } else if (sse) {
2184 dasm_put(Dst, 11449, Dt5(->len));
2185 } else {
2186 dasm_put(Dst, 11467, Dt5(->len));
2187 }
2188 dasm_put(Dst, 11476, LJ_TTAB);
2189#ifdef LUAJIT_ENABLE_LUA52COMPAT
2190 dasm_put(Dst, 11512, Dt6(->metatable));
2191#endif
2192 dasm_put(Dst, 11526);
2193 if (LJ_DUALNUM) {
2194 } else if (sse) {
2195 dasm_put(Dst, 11535);
2196 } else {
2197 }
2198 dasm_put(Dst, 11541);
2199#ifdef LUAJIT_ENABLE_LUA52COMPAT
2200 dasm_put(Dst, 11554, Dt6(->nomm), 1<<MM_len);
2201#endif
2202 break;
2203
2204 /* -- Binary ops -------------------------------------------------------- */
2205
2206
2207 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
2208 if (LJ_DUALNUM) {
2209 dasm_put(Dst, 11570);
2210 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2211 switch (vk) {
2212 case 0:
2213 dasm_put(Dst, 11578, LJ_TISNUM, LJ_TISNUM);
2214 break;
2215 case 1:
2216 dasm_put(Dst, 11613, LJ_TISNUM, LJ_TISNUM);
2217 break;
2218 default:
2219 dasm_put(Dst, 11648, LJ_TISNUM, LJ_TISNUM);
2220 break;
2221 }
2222 dasm_put(Dst, 11681, LJ_TISNUM);
2223 if (vk == 1) {
2224 dasm_put(Dst, 11445);
2225 } else {
2226 dasm_put(Dst, 11228);
2227 }
2228 dasm_put(Dst, 10520);
2229 } else {
2230 dasm_put(Dst, 11570);
2231 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2232 switch (vk) {
2233 case 0:
2234 dasm_put(Dst, 11687, LJ_TISNUM);
2235 if (LJ_DUALNUM) {
2236 dasm_put(Dst, 11699, LJ_TISNUM);
2237 }
2238 if (sse) {
2239 dasm_put(Dst, 11711);
2240 } else {
2241 dasm_put(Dst, 11726);
2242 }
2243 break;
2244 case 1:
2245 dasm_put(Dst, 11735, LJ_TISNUM);
2246 if (LJ_DUALNUM) {
2247 dasm_put(Dst, 11747, LJ_TISNUM);
2248 }
2249 if (sse) {
2250 dasm_put(Dst, 11759);
2251 } else {
2252 dasm_put(Dst, 11774);
2253 }
2254 break;
2255 default:
2256 dasm_put(Dst, 11783, LJ_TISNUM, LJ_TISNUM);
2257 if (sse) {
2258 dasm_put(Dst, 11805);
2259 } else {
2260 dasm_put(Dst, 11819);
2261 }
2262 break;
2263 }
2264 if (sse) {
2265 dasm_put(Dst, 11405);
2266 } else {
2267 dasm_put(Dst, 11417);
2268 }
2269 dasm_put(Dst, 10520);
2270 }
2271 break;
2272 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
2273 if (LJ_DUALNUM) {
2274 dasm_put(Dst, 11570);
2275 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2276 switch (vk) {
2277 case 0:
2278 dasm_put(Dst, 11827, LJ_TISNUM, LJ_TISNUM);
2279 break;
2280 case 1:
2281 dasm_put(Dst, 11862, LJ_TISNUM, LJ_TISNUM);
2282 break;
2283 default:
2284 dasm_put(Dst, 11897, LJ_TISNUM, LJ_TISNUM);
2285 break;
2286 }
2287 dasm_put(Dst, 11681, LJ_TISNUM);
2288 if (vk == 1) {
2289 dasm_put(Dst, 11445);
2290 } else {
2291 dasm_put(Dst, 11228);
2292 }
2293 dasm_put(Dst, 10520);
2294 } else {
2295 dasm_put(Dst, 11570);
2296 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2297 switch (vk) {
2298 case 0:
2299 dasm_put(Dst, 11687, LJ_TISNUM);
2300 if (LJ_DUALNUM) {
2301 dasm_put(Dst, 11699, LJ_TISNUM);
2302 }
2303 if (sse) {
2304 dasm_put(Dst, 11930);
2305 } else {
2306 dasm_put(Dst, 11945);
2307 }
2308 break;
2309 case 1:
2310 dasm_put(Dst, 11735, LJ_TISNUM);
2311 if (LJ_DUALNUM) {
2312 dasm_put(Dst, 11747, LJ_TISNUM);
2313 }
2314 if (sse) {
2315 dasm_put(Dst, 11954);
2316 } else {
2317 dasm_put(Dst, 11969);
2318 }
2319 break;
2320 default:
2321 dasm_put(Dst, 11783, LJ_TISNUM, LJ_TISNUM);
2322 if (sse) {
2323 dasm_put(Dst, 11978);
2324 } else {
2325 dasm_put(Dst, 11992);
2326 }
2327 break;
2328 }
2329 if (sse) {
2330 dasm_put(Dst, 11405);
2331 } else {
2332 dasm_put(Dst, 11417);
2333 }
2334 dasm_put(Dst, 10520);
2335 }
2336 break;
2337 case BC_MULVN: case BC_MULNV: case BC_MULVV:
2338 if (LJ_DUALNUM) {
2339 dasm_put(Dst, 11570);
2340 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2341 switch (vk) {
2342 case 0:
2343 dasm_put(Dst, 12000, LJ_TISNUM, LJ_TISNUM);
2344 break;
2345 case 1:
2346 dasm_put(Dst, 12036, LJ_TISNUM, LJ_TISNUM);
2347 break;
2348 default:
2349 dasm_put(Dst, 12072, LJ_TISNUM, LJ_TISNUM);
2350 break;
2351 }
2352 dasm_put(Dst, 11681, LJ_TISNUM);
2353 if (vk == 1) {
2354 dasm_put(Dst, 11445);
2355 } else {
2356 dasm_put(Dst, 11228);
2357 }
2358 dasm_put(Dst, 10520);
2359 } else {
2360 dasm_put(Dst, 11570);
2361 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2362 switch (vk) {
2363 case 0:
2364 dasm_put(Dst, 11687, LJ_TISNUM);
2365 if (LJ_DUALNUM) {
2366 dasm_put(Dst, 11699, LJ_TISNUM);
2367 }
2368 if (sse) {
2369 dasm_put(Dst, 12106);
2370 } else {
2371 dasm_put(Dst, 12121);
2372 }
2373 break;
2374 case 1:
2375 dasm_put(Dst, 11735, LJ_TISNUM);
2376 if (LJ_DUALNUM) {
2377 dasm_put(Dst, 11747, LJ_TISNUM);
2378 }
2379 if (sse) {
2380 dasm_put(Dst, 12130);
2381 } else {
2382 dasm_put(Dst, 12145);
2383 }
2384 break;
2385 default:
2386 dasm_put(Dst, 11783, LJ_TISNUM, LJ_TISNUM);
2387 if (sse) {
2388 dasm_put(Dst, 12154);
2389 } else {
2390 dasm_put(Dst, 12168);
2391 }
2392 break;
2393 }
2394 if (sse) {
2395 dasm_put(Dst, 11405);
2396 } else {
2397 dasm_put(Dst, 11417);
2398 }
2399 dasm_put(Dst, 10520);
2400 }
2401 break;
2402 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
2403 dasm_put(Dst, 11570);
2404 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2405 switch (vk) {
2406 case 0:
2407 dasm_put(Dst, 11687, LJ_TISNUM);
2408 if (LJ_DUALNUM) {
2409 dasm_put(Dst, 11699, LJ_TISNUM);
2410 }
2411 if (sse) {
2412 dasm_put(Dst, 12176);
2413 } else {
2414 dasm_put(Dst, 12191);
2415 }
2416 break;
2417 case 1:
2418 dasm_put(Dst, 11735, LJ_TISNUM);
2419 if (LJ_DUALNUM) {
2420 dasm_put(Dst, 11747, LJ_TISNUM);
2421 }
2422 if (sse) {
2423 dasm_put(Dst, 12200);
2424 } else {
2425 dasm_put(Dst, 12215);
2426 }
2427 break;
2428 default:
2429 dasm_put(Dst, 11783, LJ_TISNUM, LJ_TISNUM);
2430 if (sse) {
2431 dasm_put(Dst, 12224);
2432 } else {
2433 dasm_put(Dst, 12238);
2434 }
2435 break;
2436 }
2437 if (sse) {
2438 dasm_put(Dst, 11405);
2439 } else {
2440 dasm_put(Dst, 11417);
2441 }
2442 dasm_put(Dst, 10520);
2443 break;
2444 case BC_MODVN:
2445 dasm_put(Dst, 11570);
2446 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2447 switch (vk) {
2448 case 0:
2449 dasm_put(Dst, 11687, LJ_TISNUM);
2450 if (LJ_DUALNUM) {
2451 dasm_put(Dst, 11699, LJ_TISNUM);
2452 }
2453 if (sse) {
2454 dasm_put(Dst, 12246);
2455 } else {
2456 dasm_put(Dst, 12261);
2457 }
2458 break;
2459 case 1:
2460 dasm_put(Dst, 11735, LJ_TISNUM);
2461 if (LJ_DUALNUM) {
2462 dasm_put(Dst, 11747, LJ_TISNUM);
2463 }
2464 if (sse) {
2465 dasm_put(Dst, 12270);
2466 } else {
2467 dasm_put(Dst, 12285);
2468 }
2469 break;
2470 default:
2471 dasm_put(Dst, 11783, LJ_TISNUM, LJ_TISNUM);
2472 if (sse) {
2473 dasm_put(Dst, 12294);
2474 } else {
2475 dasm_put(Dst, 12308);
2476 }
2477 break;
2478 }
2479 dasm_put(Dst, 12316);
2480 if (sse) {
2481 dasm_put(Dst, 11405);
2482 } else {
2483 dasm_put(Dst, 11417);
2484 }
2485 dasm_put(Dst, 10520);
2486 break;
2487 case BC_MODNV: case BC_MODVV:
2488 dasm_put(Dst, 11570);
2489 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2490 switch (vk) {
2491 case 0:
2492 dasm_put(Dst, 11687, LJ_TISNUM);
2493 if (LJ_DUALNUM) {
2494 dasm_put(Dst, 11699, LJ_TISNUM);
2495 }
2496 if (sse) {
2497 dasm_put(Dst, 12246);
2498 } else {
2499 dasm_put(Dst, 12261);
2500 }
2501 break;
2502 case 1:
2503 dasm_put(Dst, 11735, LJ_TISNUM);
2504 if (LJ_DUALNUM) {
2505 dasm_put(Dst, 11747, LJ_TISNUM);
2506 }
2507 if (sse) {
2508 dasm_put(Dst, 12270);
2509 } else {
2510 dasm_put(Dst, 12285);
2511 }
2512 break;
2513 default:
2514 dasm_put(Dst, 11783, LJ_TISNUM, LJ_TISNUM);
2515 if (sse) {
2516 dasm_put(Dst, 12294);
2517 } else {
2518 dasm_put(Dst, 12308);
2519 }
2520 break;
2521 }
2522 dasm_put(Dst, 12322);
2523 break;
2524 case BC_POW:
2525 dasm_put(Dst, 11570);
2526 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2527 switch (vk) {
2528 case 0:
2529 dasm_put(Dst, 11687, LJ_TISNUM);
2530 if (LJ_DUALNUM) {
2531 dasm_put(Dst, 11699, LJ_TISNUM);
2532 }
2533 if (sse) {
2534 dasm_put(Dst, 12246);
2535 } else {
2536 dasm_put(Dst, 12261);
2537 }
2538 break;
2539 case 1:
2540 dasm_put(Dst, 11735, LJ_TISNUM);
2541 if (LJ_DUALNUM) {
2542 dasm_put(Dst, 11747, LJ_TISNUM);
2543 }
2544 if (sse) {
2545 dasm_put(Dst, 12270);
2546 } else {
2547 dasm_put(Dst, 12285);
2548 }
2549 break;
2550 default:
2551 dasm_put(Dst, 11783, LJ_TISNUM, LJ_TISNUM);
2552 if (sse) {
2553 dasm_put(Dst, 12294);
2554 } else {
2555 dasm_put(Dst, 12308);
2556 }
2557 break;
2558 }
2559 dasm_put(Dst, 12327);
2560 if (sse) {
2561 dasm_put(Dst, 11405);
2562 } else {
2563 dasm_put(Dst, 11417);
2564 }
2565 dasm_put(Dst, 10520);
2566 break;
2567
2568 case BC_CAT:
2569 dasm_put(Dst, 12331, Dt1(->base), Dt1(->base));
2570 break;
2571
2572 /* -- Constant ops ------------------------------------------------------ */
2573
2574 case BC_KSTR:
2575 dasm_put(Dst, 12415, LJ_TSTR);
2576 break;
2577 case BC_KCDATA:
2578#if LJ_HASFFI
2579 dasm_put(Dst, 12415, LJ_TCDATA);
2580#endif
2581 break;
2582 case BC_KSHORT:
2583 if (LJ_DUALNUM) {
2584 dasm_put(Dst, 12452, LJ_TISNUM);
2585 } else if (sse) {
2586 dasm_put(Dst, 12464);
2587 } else {
2588 dasm_put(Dst, 12479);
2589 }
2590 dasm_put(Dst, 10520);
2591 break;
2592 case BC_KNUM:
2593 if (sse) {
2594 dasm_put(Dst, 12487);
2595 } else {
2596 dasm_put(Dst, 12501);
2597 }
2598 dasm_put(Dst, 10520);
2599 break;
2600 case BC_KPRI:
2601 dasm_put(Dst, 12509);
2602 break;
2603 case BC_KNIL:
2604 dasm_put(Dst, 12538, LJ_TNIL);
2605 break;
2606
2607 /* -- Upvalue and function ops ------------------------------------------ */
2608
2609 case BC_UGET:
2610 dasm_put(Dst, 12586, offsetof(GCfuncL, uvptr), DtA(->v));
2611 break;
2612 case BC_USETV:
2613#define TV2MARKOFS \
2614 ((int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv))
2615 dasm_put(Dst, 12627, offsetof(GCfuncL, uvptr), DtA(->closed), DtA(->v), TV2MARKOFS, LJ_GC_BLACK, LJ_TISGCV, LJ_TISNUM - LJ_TISGCV, Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
2616 dasm_put(Dst, 12723);
2617 break;
2618#undef TV2MARKOFS
2619 case BC_USETS:
2620 dasm_put(Dst, 12735, offsetof(GCfuncL, uvptr), DtA(->v), LJ_TSTR, DtA(->marked), LJ_GC_BLACK, Dt4(->gch.marked), LJ_GC_WHITES, DtA(->closed), GG_DISP2G);
2621 break;
2622 case BC_USETN:
2623 dasm_put(Dst, 12831);
2624 if (sse) {
2625 dasm_put(Dst, 12836);
2626 } else {
2627 dasm_put(Dst, 11052);
2628 }
2629 dasm_put(Dst, 12844, offsetof(GCfuncL, uvptr), DtA(->v));
2630 if (sse) {
2631 dasm_put(Dst, 12853);
2632 } else {
2633 dasm_put(Dst, 12859);
2634 }
2635 dasm_put(Dst, 10520);
2636 break;
2637 case BC_USETP:
2638 dasm_put(Dst, 12862, offsetof(GCfuncL, uvptr), DtA(->v));
2639 break;
2640 case BC_UCLO:
2641 dasm_put(Dst, 12902, -BCBIAS_J*4, Dt1(->openupval), Dt1(->base), Dt1(->base));
2642 break;
2643
2644 case BC_FNEW:
2645 dasm_put(Dst, 12958, Dt1(->base), Dt1(->base), LJ_TFUNC);
2646 break;
2647
2648 /* -- Table ops --------------------------------------------------------- */
2649
2650 case BC_TNEW:
2651 dasm_put(Dst, 13025, Dt1(->base), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), LJ_TTAB);
2652 break;
2653 case BC_TDUP:
2654 dasm_put(Dst, 13149, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), Dt1(->base), LJ_TTAB);
2655 break;
2656
2657 case BC_GGET:
2658 dasm_put(Dst, 13248, Dt7(->env));
2659 break;
2660 case BC_GSET:
2661 dasm_put(Dst, 13268, Dt7(->env));
2662 break;
2663
2664 case BC_TGETV:
2665 dasm_put(Dst, 13288, LJ_TTAB);
2666 if (LJ_DUALNUM) {
2667 dasm_put(Dst, 13311, LJ_TISNUM);
2668 } else {
2669 dasm_put(Dst, 13325, LJ_TISNUM);
2670 if (sse) {
2671 dasm_put(Dst, 13336);
2672 } else {
2673 }
2674 dasm_put(Dst, 13357);
2675 }
2676 dasm_put(Dst, 13362, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index, LJ_TNIL);
2677 dasm_put(Dst, 13454, LJ_TSTR);
2678 break;
2679 case BC_TGETS:
2680 dasm_put(Dst, 13472, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
2681 dasm_put(Dst, 13557, LJ_TNIL, DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
2682 break;
2683 case BC_TGETB:
2684 dasm_put(Dst, 13629, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
2685 dasm_put(Dst, 13725, LJ_TNIL);
2686 break;
2687
2688 case BC_TSETV:
2689 dasm_put(Dst, 13742, LJ_TTAB);
2690 if (LJ_DUALNUM) {
2691 dasm_put(Dst, 13311, LJ_TISNUM);
2692 } else {
2693 dasm_put(Dst, 13325, LJ_TISNUM);
2694 if (sse) {
2695 dasm_put(Dst, 13336);
2696 } else {
2697 }
2698 dasm_put(Dst, 13765);
2699 }
2700 dasm_put(Dst, 13770, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex);
2701 dasm_put(Dst, 13851, LJ_TSTR, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2702 break;
2703 case BC_TSETS:
2704 dasm_put(Dst, 13910, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->nomm), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
2705 dasm_put(Dst, 13987, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DtB(->next));
2706 dasm_put(Dst, 14074, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, LJ_TSTR, Dt1(->base), Dt1(->base), Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2707 break;
2708 case BC_TSETB:
2709 dasm_put(Dst, 14166, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable));
2710 dasm_put(Dst, 14261, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2711 break;
2712
2713 case BC_TSETM:
2714 dasm_put(Dst, 14309, Dt6(->marked), LJ_GC_BLACK, Dt6(->asize), Dt6(->array), Dt1(->base), Dt1(->base));
2715 dasm_put(Dst, 14459, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2716 break;
2717
2718 /* -- Calls and vararg handling ----------------------------------------- */
2719
2720 case BC_CALL: case BC_CALLM:
2721 dasm_put(Dst, 11574);
2722 if (op == BC_CALLM) {
2723 dasm_put(Dst, 14479);
2724 }
2725 dasm_put(Dst, 14484, LJ_TFUNC, Dt7(->pc));
2726 break;
2727
2728 case BC_CALLMT:
2729 dasm_put(Dst, 14479);
2730 break;
2731 case BC_CALLT:
2732 dasm_put(Dst, 14527, LJ_TFUNC, FRAME_TYPE, Dt7(->ffid), Dt7(->pc));
2733 dasm_put(Dst, 14645, FRAME_TYPE, Dt7(->pc), PC2PROTO(k), FRAME_VARG, FRAME_TYPEP, FRAME_VARG);
2734 break;
2735
2736 case BC_ITERC:
2737 dasm_put(Dst, 14719, LJ_TFUNC, 2+1, Dt7(->pc));
2738 break;
2739
2740 case BC_ITERN:
2741#if LJ_HASJIT
2742#endif
2743 dasm_put(Dst, 14791, Dt6(->asize), Dt6(->array), LJ_TNIL);
2744 if (LJ_DUALNUM) {
2745 dasm_put(Dst, 11440, LJ_TISNUM);
2746 } else if (sse) {
2747 dasm_put(Dst, 11535);
2748 } else {
2749 dasm_put(Dst, 14843);
2750 }
2751 dasm_put(Dst, 14849);
2752 if (LJ_DUALNUM) {
2753 } else if (sse) {
2754 dasm_put(Dst, 11405);
2755 } else {
2756 dasm_put(Dst, 11417);
2757 }
2758 dasm_put(Dst, 14862, -BCBIAS_J*4);
2759 if (!LJ_DUALNUM && !sse) {
2760 dasm_put(Dst, 14916);
2761 }
2762 dasm_put(Dst, 14922, Dt6(->hmask), sizeof(Node), Dt6(->node), DtB(->val.it), LJ_TNIL, DtB(->key), DtB(->val));
2763 break;
2764
2765 case BC_ISNEXT:
2766 dasm_put(Dst, 15001, LJ_TFUNC, LJ_TTAB, LJ_TNIL, Dt8(->ffid), FF_next_N, -BCBIAS_J*4, BC_JMP, -BCBIAS_J*4, BC_ITERC);
2767 break;
2768
2769 case BC_VARG:
2770 dasm_put(Dst, 15102, (8+FRAME_VARG), LJ_TNIL, Dt1(->maxstack));
2771 dasm_put(Dst, 15269, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
2772 break;
2773
2774 /* -- Returns ----------------------------------------------------------- */
2775
2776 case BC_RETM:
2777 dasm_put(Dst, 14479);
2778 break;
2779
2780 case BC_RET: case BC_RET0: case BC_RET1:
2781 if (op != BC_RET0) {
2782 dasm_put(Dst, 15339);
2783 }
2784 dasm_put(Dst, 15343, FRAME_TYPE);
2785 switch (op) {
2786 case BC_RET:
2787 dasm_put(Dst, 15362);
2788 break;
2789 case BC_RET1:
2790 dasm_put(Dst, 15416);
2791 /* fallthrough */
2792 case BC_RET0:
2793 dasm_put(Dst, 15426);
2794 default:
2795 break;
2796 }
2797 dasm_put(Dst, 15437, Dt7(->pc), PC2PROTO(k));
2798 if (op == BC_RET) {
2799 dasm_put(Dst, 15485, LJ_TNIL);
2800 } else {
2801 dasm_put(Dst, 15496, LJ_TNIL);
2802 }
2803 dasm_put(Dst, 15503, -FRAME_VARG, FRAME_TYPEP);
2804 if (op != BC_RET0) {
2805 dasm_put(Dst, 15527);
2806 }
2807 dasm_put(Dst, 4761);
2808 break;
2809
2810 /* -- Loops and branches ------------------------------------------------ */
2811
2812
2813 case BC_FORL:
2814#if LJ_HASJIT
2815 dasm_put(Dst, 15531, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
2816#endif
2817 break;
2818
2819 case BC_JFORI:
2820 case BC_JFORL:
2821#if !LJ_HASJIT
2822 break;
2823#endif
2824 case BC_FORI:
2825 case BC_IFORL:
2826 vk = (op == BC_IFORL || op == BC_JFORL);
2827 dasm_put(Dst, 15552);
2828 if (LJ_DUALNUM) {
2829 dasm_put(Dst, 15556, LJ_TISNUM);
2830 if (!vk) {
2831 dasm_put(Dst, 15566, LJ_TISNUM, LJ_TISNUM);
2832 } else {
2833#ifdef LUA_USE_ASSERT
2834 dasm_put(Dst, 15595, LJ_TISNUM, LJ_TISNUM);
2835#endif
2836 dasm_put(Dst, 15614);
2837 }
2838 dasm_put(Dst, 15633, LJ_TISNUM);
2839 if (op == BC_FORI) {
2840 dasm_put(Dst, 15644, -BCBIAS_J*4);
2841 } else if (op == BC_JFORI) {
2842 dasm_put(Dst, 15658, -BCBIAS_J*4, BC_JLOOP);
2843 } else if (op == BC_IFORL) {
2844 dasm_put(Dst, 15676, -BCBIAS_J*4);
2845 } else {
2846 dasm_put(Dst, 15668, BC_JLOOP);
2847 }
2848 dasm_put(Dst, 15690);
2849 if (vk) {
2850 dasm_put(Dst, 15715);
2851 }
2852 dasm_put(Dst, 15633, LJ_TISNUM);
2853 if (op == BC_FORI) {
2854 dasm_put(Dst, 15724);
2855 } else if (op == BC_JFORI) {
2856 dasm_put(Dst, 15729, -BCBIAS_J*4, BC_JLOOP);
2857 } else if (op == BC_IFORL) {
2858 dasm_put(Dst, 15743);
2859 } else {
2860 dasm_put(Dst, 15739, BC_JLOOP);
2861 }
2862 dasm_put(Dst, 15748);
2863 } else if (!vk) {
2864 dasm_put(Dst, 15755, LJ_TISNUM);
2865 }
2866 if (!vk) {
2867 dasm_put(Dst, 15761, LJ_TISNUM);
2868 } else {
2869#ifdef LUA_USE_ASSERT
2870 dasm_put(Dst, 15775, LJ_TISNUM, LJ_TISNUM);
2871#endif
2872 }
2873 dasm_put(Dst, 15794);
2874 if (!vk) {
2875 dasm_put(Dst, 15798, LJ_TISNUM);
2876 }
2877 if (sse) {
2878 dasm_put(Dst, 15807);
2879 if (vk) {
2880 dasm_put(Dst, 15819);
2881 } else {
2882 dasm_put(Dst, 15838);
2883 }
2884 dasm_put(Dst, 15843);
2885 } else {
2886 dasm_put(Dst, 15856);
2887 if (vk) {
2888 dasm_put(Dst, 15862);
2889 } else {
2890 dasm_put(Dst, 15878);
2891 }
2892 dasm_put(Dst, 15886);
2893 if (cmov) {
2894 dasm_put(Dst, 10480);
2895 } else {
2896 dasm_put(Dst, 10486);
2897 }
2898 if (!cmov) {
2899 dasm_put(Dst, 15891);
2900 }
2901 }
2902 if (op == BC_FORI) {
2903 if (LJ_DUALNUM) {
2904 dasm_put(Dst, 15897);
2905 } else {
2906 dasm_put(Dst, 15902, -BCBIAS_J*4);
2907 }
2908 } else if (op == BC_JFORI) {
2909 dasm_put(Dst, 15912, -BCBIAS_J*4, BC_JLOOP);
2910 } else if (op == BC_IFORL) {
2911 if (LJ_DUALNUM) {
2912 dasm_put(Dst, 15926);
2913 } else {
2914 dasm_put(Dst, 15931, -BCBIAS_J*4);
2915 }
2916 } else {
2917 dasm_put(Dst, 15922, BC_JLOOP);
2918 }
2919 if (LJ_DUALNUM) {
2920 dasm_put(Dst, 10409);
2921 } else {
2922 dasm_put(Dst, 11186);
2923 }
2924 if (sse) {
2925 dasm_put(Dst, 15941);
2926 }
2927 break;
2928
2929 case BC_ITERL:
2930#if LJ_HASJIT
2931 dasm_put(Dst, 15531, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
2932#endif
2933 break;
2934
2935 case BC_JITERL:
2936#if !LJ_HASJIT
2937 break;
2938#endif
2939 case BC_IITERL:
2940 dasm_put(Dst, 15952, LJ_TNIL);
2941 if (op == BC_JITERL) {
2942 dasm_put(Dst, 15967, BC_JLOOP);
2943 } else {
2944 dasm_put(Dst, 15981, -BCBIAS_J*4);
2945 }
2946 dasm_put(Dst, 10518);
2947 break;
2948
2949 case BC_LOOP:
2950#if LJ_HASJIT
2951 dasm_put(Dst, 15531, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
2952#endif
2953 break;
2954
2955 case BC_ILOOP:
2956 dasm_put(Dst, 10520);
2957 break;
2958
2959 case BC_JLOOP:
2960#if LJ_HASJIT
2961 dasm_put(Dst, 15997, DISPATCH_J(trace), DtD(->mcode), DISPATCH_GL(jit_base), DISPATCH_GL(jit_L));
2962#endif
2963 break;
2964
2965 case BC_JMP:
2966 dasm_put(Dst, 16038, -BCBIAS_J*4);
2967 break;
2968
2969 /* -- Function headers -------------------------------------------------- */
2970
2971 /*
2972 ** Reminder: A function may be called with func/args above L->maxstack,
2973 ** i.e. occupying EXTRA_STACK slots. And vmeta_call may add one extra slot,
2974 ** too. This means all FUNC* ops (including fast functions) must check
2975 ** for stack overflow _before_ adding more slots!
2976 */
2977
2978 case BC_FUNCF:
2979#if LJ_HASJIT
2980 dasm_put(Dst, 16064, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_CALL);
2981#endif
2982 case BC_FUNCV: /* NYI: compiled vararg functions. */
2983 break;
2984
2985 case BC_JFUNCF:
2986#if !LJ_HASJIT
2987 break;
2988#endif
2989 case BC_IFUNCF:
2990 dasm_put(Dst, 16085, -4+PC2PROTO(k), Dt1(->maxstack), -4+PC2PROTO(numparams));
2991 if (op == BC_JFUNCF) {
2992 dasm_put(Dst, 16116, BC_JLOOP);
2993 } else {
2994 dasm_put(Dst, 10520);
2995 }
2996 dasm_put(Dst, 16125, LJ_TNIL);
2997 break;
2998
2999 case BC_JFUNCV:
3000#if !LJ_HASJIT
3001 break;
3002#endif
3003 dasm_put(Dst, 9422);
3004 break; /* NYI: compiled vararg functions. */
3005
3006 case BC_IFUNCV:
3007 dasm_put(Dst, 16147, FRAME_VARG, Dt1(->maxstack), -4+PC2PROTO(numparams), LJ_TNIL);
3008 if (op == BC_JFUNCV) {
3009 dasm_put(Dst, 16116, BC_JLOOP);
3010 } else {
3011 dasm_put(Dst, 16244, -4+PC2PROTO(k));
3012 }
3013 dasm_put(Dst, 16269, LJ_TNIL);
3014 break;
3015
3016 case BC_FUNCC:
3017 case BC_FUNCCW:
3018 dasm_put(Dst, 16291, Dt8(->f), Dt1(->base), 8*LUA_MINSTACK, Dt1(->maxstack), Dt1(->top));
3019 if (op == BC_FUNCC) {
3020 dasm_put(Dst, 2433);
3021 } else {
3022 dasm_put(Dst, 16321);
3023 }
3024 dasm_put(Dst, 16329, DISPATCH_GL(vmstate), ~LJ_VMST_C);
3025 if (op == BC_FUNCC) {
3026 dasm_put(Dst, 16339);
3027 } else {
3028 dasm_put(Dst, 16344, DISPATCH_GL(wrapf));
3029 }
3030 dasm_put(Dst, 16350, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top));
3031 break;
3032
3033 /* ---------------------------------------------------------------------- */
3034
3035 default:
3036 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
3037 exit(2);
3038 break;
3039 }
3040}
3041
3042static int build_backend(BuildCtx *ctx)
3043{
3044 int op;
3045 int cmov = 1;
3046 int sse = 0;
3047#ifdef LUAJIT_CPU_NOCMOV
3048 cmov = 0;
3049#endif
3050#if defined(LUAJIT_CPU_SSE2) || defined(LJ_TARGET_X64)
3051 sse = 1;
3052#endif
3053
3054 dasm_growpc(Dst, BC__MAX);
3055
3056 build_subroutines(ctx, cmov, sse);
3057
3058 dasm_put(Dst, 16376);
3059 for (op = 0; op < BC__MAX; op++)
3060 build_ins(ctx, (BCOp)op, op, cmov, sse);
3061
3062 return BC__MAX;
3063}
3064
3065/* Emit pseudo frame-info for all assembler functions. */
3066static void emit_asm_debug(BuildCtx *ctx)
3067{
3068 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
3069#if LJ_64
3070#define SZPTR "8"
3071#define BSZPTR "3"
3072#define REG_SP "0x7"
3073#define REG_RA "0x10"
3074#else
3075#define SZPTR "4"
3076#define BSZPTR "2"
3077#define REG_SP "0x4"
3078#define REG_RA "0x8"
3079#endif
3080 switch (ctx->mode) {
3081 case BUILD_elfasm:
3082 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
3083 fprintf(ctx->fp,
3084 ".Lframe0:\n"
3085 "\t.long .LECIE0-.LSCIE0\n"
3086 ".LSCIE0:\n"
3087 "\t.long 0xffffffff\n"
3088 "\t.byte 0x1\n"
3089 "\t.string \"\"\n"
3090 "\t.uleb128 0x1\n"
3091 "\t.sleb128 -" SZPTR "\n"
3092 "\t.byte " REG_RA "\n"
3093 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3094 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3095 "\t.align " SZPTR "\n"
3096 ".LECIE0:\n\n");
3097 fprintf(ctx->fp,
3098 ".LSFDE0:\n"
3099 "\t.long .LEFDE0-.LASFDE0\n"
3100 ".LASFDE0:\n"
3101 "\t.long .Lframe0\n"
3102#if LJ_64
3103 "\t.quad .Lbegin\n"
3104 "\t.quad %d\n"
3105 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3106 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3107 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3108 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3109 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3110#else
3111 "\t.long .Lbegin\n"
3112 "\t.long %d\n"
3113 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3114 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3115 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3116 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3117 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3118#endif
3119 "\t.align " SZPTR "\n"
3120 ".LEFDE0:\n\n", fcofs, CFRAME_SIZE);
3121#if LJ_HASFFI
3122 fprintf(ctx->fp,
3123 ".LSFDE1:\n"
3124 "\t.long .LEFDE1-.LASFDE1\n"
3125 ".LASFDE1:\n"
3126 "\t.long .Lframe0\n"
3127#if LJ_64
3128 "\t.quad lj_vm_ffi_call\n"
3129 "\t.quad %d\n"
3130 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
3131 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3132 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3133 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3134#else
3135 "\t.long lj_vm_ffi_call\n"
3136 "\t.long %d\n"
3137 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
3138 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3139 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
3140 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
3141#endif
3142 "\t.align " SZPTR "\n"
3143 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
3144#endif
3145#if (defined(__sun__) && defined(__svr4__)) || defined(__solaris_)
3146 fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n");
3147#else
3148 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
3149#endif
3150 fprintf(ctx->fp,
3151 ".Lframe1:\n"
3152 "\t.long .LECIE1-.LSCIE1\n"
3153 ".LSCIE1:\n"
3154 "\t.long 0\n"
3155 "\t.byte 0x1\n"
3156 "\t.string \"zPR\"\n"
3157 "\t.uleb128 0x1\n"
3158 "\t.sleb128 -" SZPTR "\n"
3159 "\t.byte " REG_RA "\n"
3160 "\t.uleb128 6\n" /* augmentation length */
3161 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3162 "\t.long lj_err_unwind_dwarf-.\n"
3163 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3164 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3165 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3166 "\t.align " SZPTR "\n"
3167 ".LECIE1:\n\n");
3168 fprintf(ctx->fp,
3169 ".LSFDE2:\n"
3170 "\t.long .LEFDE2-.LASFDE2\n"
3171 ".LASFDE2:\n"
3172 "\t.long .LASFDE2-.Lframe1\n"
3173 "\t.long .Lbegin-.\n"
3174 "\t.long %d\n"
3175 "\t.uleb128 0\n" /* augmentation length */
3176 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3177#if LJ_64
3178 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3179 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3180 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3181 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3182#else
3183 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3184 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3185 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3186 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3187#endif
3188 "\t.align " SZPTR "\n"
3189 ".LEFDE2:\n\n", fcofs, CFRAME_SIZE);
3190#if LJ_HASFFI
3191 fprintf(ctx->fp,
3192 ".Lframe2:\n"
3193 "\t.long .LECIE2-.LSCIE2\n"
3194 ".LSCIE2:\n"
3195 "\t.long 0\n"
3196 "\t.byte 0x1\n"
3197 "\t.string \"zR\"\n"
3198 "\t.uleb128 0x1\n"
3199 "\t.sleb128 -" SZPTR "\n"
3200 "\t.byte " REG_RA "\n"
3201 "\t.uleb128 1\n" /* augmentation length */
3202 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3203 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3204 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3205 "\t.align " SZPTR "\n"
3206 ".LECIE2:\n\n");
3207 fprintf(ctx->fp,
3208 ".LSFDE3:\n"
3209 "\t.long .LEFDE3-.LASFDE3\n"
3210 ".LASFDE3:\n"
3211 "\t.long .LASFDE3-.Lframe2\n"
3212 "\t.long lj_vm_ffi_call-.\n"
3213 "\t.long %d\n"
3214 "\t.uleb128 0\n" /* augmentation length */
3215#if LJ_64
3216 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
3217 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3218 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3219 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3220#else
3221 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
3222 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3223 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
3224 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
3225#endif
3226 "\t.align " SZPTR "\n"
3227 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
3228#endif
3229 break;
3230 case BUILD_coffasm:
3231 fprintf(ctx->fp, "\t.section .eh_frame,\"dr\"\n");
3232 fprintf(ctx->fp,
3233 "\t.def %slj_err_unwind_dwarf; .scl 2; .type 32; .endef\n",
3234 LJ_32 ? "_" : "");
3235 fprintf(ctx->fp,
3236 "Lframe1:\n"
3237 "\t.long LECIE1-LSCIE1\n"
3238 "LSCIE1:\n"
3239 "\t.long 0\n"
3240 "\t.byte 0x1\n"
3241 "\t.string \"zP\"\n"
3242 "\t.uleb128 0x1\n"
3243 "\t.sleb128 -" SZPTR "\n"
3244 "\t.byte " REG_RA "\n"
3245 "\t.uleb128 5\n" /* augmentation length */
3246 "\t.byte 0x00\n" /* absptr */
3247 "\t.long %slj_err_unwind_dwarf\n"
3248 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3249 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3250 "\t.align " SZPTR "\n"
3251 "LECIE1:\n\n", LJ_32 ? "_" : "");
3252 fprintf(ctx->fp,
3253 "LSFDE1:\n"
3254 "\t.long LEFDE1-LASFDE1\n"
3255 "LASFDE1:\n"
3256 "\t.long LASFDE1-Lframe1\n"
3257 "\t.long %slj_vm_asm_begin\n"
3258 "\t.long %d\n"
3259 "\t.uleb128 0\n" /* augmentation length */
3260 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3261#if LJ_64
3262 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3263 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3264 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3265 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3266#else
3267 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3268 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3269 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3270 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3271#endif
3272 "\t.align " SZPTR "\n"
3273 "LEFDE1:\n\n", LJ_32 ? "_" : "", (int)ctx->codesz, CFRAME_SIZE);
3274 break;
3275 /* Mental note: never let Apple design an assembler.
3276 ** Or a linker. Or a plastic case. But I digress.
3277 */
3278 case BUILD_machasm: {
3279#if LJ_HASFFI
3280 int fcsize = 0;
3281#endif
3282 int i;
3283 fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
3284 fprintf(ctx->fp,
3285 "EH_frame1:\n"
3286 "\t.set L$set$x,LECIEX-LSCIEX\n"
3287 "\t.long L$set$x\n"
3288 "LSCIEX:\n"
3289 "\t.long 0\n"
3290 "\t.byte 0x1\n"
3291 "\t.ascii \"zPR\\0\"\n"
3292 "\t.byte 0x1\n"
3293 "\t.byte 128-" SZPTR "\n"
3294 "\t.byte " REG_RA "\n"
3295 "\t.byte 6\n" /* augmentation length */
3296 "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
3297#if LJ_64
3298 "\t.long _lj_err_unwind_dwarf+4@GOTPCREL\n"
3299 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3300 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
3301#else
3302 "\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
3303 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3304 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
3305#endif
3306 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
3307 "\t.align " BSZPTR "\n"
3308 "LECIEX:\n\n");
3309 for (i = 0; i < ctx->nsym; i++) {
3310 const char *name = ctx->sym[i].name;
3311 int32_t size = ctx->sym[i+1].ofs - ctx->sym[i].ofs;
3312 if (size == 0) continue;
3313#if LJ_HASFFI
3314 if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; }
3315#endif
3316 fprintf(ctx->fp,
3317 "%s.eh:\n"
3318 "LSFDE%d:\n"
3319 "\t.set L$set$%d,LEFDE%d-LASFDE%d\n"
3320 "\t.long L$set$%d\n"
3321 "LASFDE%d:\n"
3322 "\t.long LASFDE%d-EH_frame1\n"
3323 "\t.long %s-.\n"
3324 "\t.long %d\n"
3325 "\t.byte 0\n" /* augmentation length */
3326 "\t.byte 0xe\n\t.byte %d\n" /* def_cfa_offset */
3327#if LJ_64
3328 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
3329 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
3330 "\t.byte 0x8f\n\t.byte 0x4\n" /* offset r15 */
3331 "\t.byte 0x8e\n\t.byte 0x5\n" /* offset r14 */
3332#else
3333 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
3334 "\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
3335 "\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
3336 "\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
3337#endif
3338 "\t.align " BSZPTR "\n"
3339 "LEFDE%d:\n\n",
3340 name, i, i, i, i, i, i, i, name, size, CFRAME_SIZE, i);
3341 }
3342#if LJ_HASFFI
3343 if (fcsize) {
3344 fprintf(ctx->fp,
3345 "EH_frame2:\n"
3346 "\t.set L$set$y,LECIEY-LSCIEY\n"
3347 "\t.long L$set$y\n"
3348 "LSCIEY:\n"
3349 "\t.long 0\n"
3350 "\t.byte 0x1\n"
3351 "\t.ascii \"zR\\0\"\n"
3352 "\t.byte 0x1\n"
3353 "\t.byte 128-" SZPTR "\n"
3354 "\t.byte " REG_RA "\n"
3355 "\t.byte 1\n" /* augmentation length */
3356#if LJ_64
3357 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3358 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
3359#else
3360 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3361 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH. */
3362#endif
3363 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
3364 "\t.align " BSZPTR "\n"
3365 "LECIEY:\n\n");
3366 fprintf(ctx->fp,
3367 "_lj_vm_ffi_call.eh:\n"
3368 "LSFDEY:\n"
3369 "\t.set L$set$yy,LEFDEY-LASFDEY\n"
3370 "\t.long L$set$yy\n"
3371 "LASFDEY:\n"
3372 "\t.long LASFDEY-EH_frame2\n"
3373 "\t.long _lj_vm_ffi_call-.\n"
3374 "\t.long %d\n"
3375 "\t.byte 0\n" /* augmentation length */
3376#if LJ_64
3377 "\t.byte 0xe\n\t.byte 16\n" /* def_cfa_offset */
3378 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
3379 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3380 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
3381#else
3382 "\t.byte 0xe\n\t.byte 8\n" /* def_cfa_offset */
3383 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
3384 "\t.byte 0xd\n\t.uleb128 0x4\n" /* def_cfa_register ebp */
3385 "\t.byte 0x83\n\t.byte 0x3\n" /* offset ebx */
3386#endif
3387 "\t.align " BSZPTR "\n"
3388 "LEFDEY:\n\n", fcsize);
3389 }
3390#endif
3391#if LJ_64
3392 fprintf(ctx->fp, "\t.subsections_via_symbols\n");
3393#else
3394 fprintf(ctx->fp,
3395 "\t.non_lazy_symbol_pointer\n"
3396 "L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
3397 ".indirect_symbol _lj_err_unwind_dwarf\n"
3398 ".long 0\n");
3399#endif
3400 }
3401 break;
3402 default: /* Difficult for other modes. */
3403 break;
3404 }
3405}
3406
diff --git a/libraries/luajit-2.0/src/buildvm_x64win.h b/libraries/luajit-2.0/src/buildvm_x64win.h
new file mode 100644
index 0000000..533d5b0
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_x64win.h
@@ -0,0 +1,3401 @@
1/*
2** This file has been pre-processed with DynASM.
3** http://luajit.org/dynasm.html
4** DynASM version 1.3.0, DynASM x64 version 1.3.0
5** DO NOT EDIT! The original file is in "buildvm_x86.dasc".
6*/
7
8#if DASM_VERSION != 10300
9#error "Version mismatch between DynASM and included encoding engine"
10#endif
11
12#define DASM_SECTION_CODE_OP 0
13#define DASM_SECTION_CODE_SUB 1
14#define DASM_MAXSECTION 2
15static const unsigned char build_actionlist[16196] = {
16 254,1,248,10,252,247,198,237,15,132,244,11,131,230,252,248,41,252,242,72,
17 141,76,49,252,248,139,114,252,252,199,68,10,4,237,248,12,131,192,1,137,68,
18 36,84,252,247,198,237,15,132,244,13,248,14,129,252,246,239,252,247,198,237,
19 15,133,244,10,199,131,233,237,131,230,252,248,41,214,252,247,222,131,232,
20 1,15,132,244,248,248,1,72,139,44,10,72,137,106,252,248,131,194,8,131,232,
21 1,15,133,244,1,248,2,255,139,108,36,96,137,181,233,248,3,139,68,36,84,139,
22 76,36,88,248,4,57,193,15,133,244,252,248,5,131,252,234,8,137,149,233,248,
23 15,72,139,76,36,104,72,137,141,233,49,192,248,16,72,131,196,40,91,94,95,93,
24 195,248,6,15,130,244,253,59,149,233,15,135,244,254,199,66,252,252,237,131,
25 194,8,131,192,1,252,233,244,4,248,7,255,133,201,15,132,244,5,41,193,141,20,
26 202,252,233,244,5,248,8,137,149,233,137,68,36,84,137,202,137,252,233,232,
27 251,1,0,139,149,233,252,233,244,3,248,17,137,208,72,137,204,248,18,139,108,
28 36,96,139,173,233,199,133,233,237,252,233,244,16,248,19,248,20,72,129,225,
29 239,72,137,204,248,21,255,139,108,36,96,72,199,193,252,248,252,255,252,255,
30 252,255,184,237,139,149,233,139,157,233,129,195,239,139,114,252,252,199,66,
31 252,252,237,199,131,233,237,252,233,244,12,248,22,186,237,252,233,244,248,
32 248,23,131,232,8,252,233,244,247,248,24,141,68,194,252,248,248,1,15,182,142,
33 233,131,198,4,137,149,233,255,137,133,233,137,116,36,100,137,202,248,2,137,
34 252,233,232,251,1,0,139,149,233,139,133,233,139,106,252,248,41,208,193,232,
35 3,131,192,1,139,181,233,139,14,15,182,252,233,15,182,205,131,198,4,252,255,
36 36,252,235,248,25,85,87,86,83,72,131,252,236,40,137,205,137,76,36,96,137,
37 209,190,237,49,192,72,141,188,253,36,233,139,157,233,129,195,239,72,137,189,
38 233,137,68,36,100,72,137,68,36,104,137,68,36,88,137,68,36,92,56,133,233,15,
39 132,244,249,199,131,233,237,136,133,233,139,149,233,139,133,233,41,200,193,
40 232,3,131,192,1,41,209,139,114,252,252,137,68,36,84,252,247,198,237,255,15,
41 132,244,13,252,233,244,14,248,26,85,87,86,83,72,131,252,236,40,190,237,68,
42 137,76,36,92,252,233,244,247,248,27,85,87,86,83,72,131,252,236,40,190,237,
43 248,1,68,137,68,36,88,137,205,137,76,36,96,137,209,72,139,189,233,72,137,
44 124,36,104,137,108,36,100,72,137,165,233,248,2,139,157,233,129,195,239,248,
45 3,199,131,233,237,139,149,233,255,1,206,41,214,139,133,233,41,200,193,232,
46 3,131,192,1,248,28,139,105,252,248,129,121,253,252,252,239,15,133,244,29,
47 248,30,137,202,137,114,252,252,139,181,233,139,14,15,182,252,233,15,182,205,
48 131,198,4,252,255,36,252,235,248,31,85,87,86,83,72,131,252,236,40,137,205,
49 137,76,36,96,137,108,36,100,139,189,233,43,189,233,199,68,36,92,0,0,0,0,137,
50 124,36,88,72,139,189,233,72,137,124,36,104,72,137,165,233,65,252,255,209,
51 133,192,15,132,244,15,137,193,190,237,252,233,244,2,248,11,1,209,131,230,
52 252,248,137,213,41,252,242,199,68,193,252,252,237,137,200,139,117,252,244,
53 72,99,77,252,240,255,131,252,249,1,15,134,244,247,255,72,141,61,245,72,1,
54 252,249,255,139,122,252,248,139,191,233,139,191,233,252,255,225,255,248,1,
55 15,132,244,32,41,213,193,252,237,3,141,69,252,255,252,233,244,33,255,248,
56 34,15,182,78,252,255,131,252,237,16,141,12,202,41,252,233,15,132,244,35,252,
57 247,217,193,252,233,3,65,137,200,139,76,36,96,137,145,233,72,139,0,72,137,
58 69,0,137,252,234,252,233,244,36,248,37,137,68,36,80,199,68,36,84,237,72,141,
59 68,36,80,128,126,252,252,235,15,133,244,247,141,139,233,137,41,199,65,4,237,
60 137,205,252,233,244,248,248,38,15,182,70,252,254,255,199,68,36,84,237,137,
61 68,36,80,255,252,242,15,42,192,252,242,15,17,68,36,80,255,72,141,68,36,80,
62 252,233,244,247,248,39,15,182,70,252,254,141,4,194,248,1,15,182,110,252,255,
63 141,44,252,234,248,2,139,76,36,96,137,145,233,137,252,234,73,137,192,137,
64 205,137,116,36,100,232,251,1,1,139,149,233,133,192,15,132,244,249,248,35,
65 15,182,78,252,253,72,139,40,72,137,44,202,139,6,15,182,204,15,182,232,131,
66 198,4,193,232,16,252,255,36,252,235,248,3,139,141,233,137,113,252,244,141,
67 177,233,41,214,139,105,252,248,184,237,252,233,244,30,248,40,137,68,36,80,
68 199,68,36,84,237,72,141,68,36,80,128,126,252,252,235,15,133,244,247,255,141,
69 139,233,137,41,199,65,4,237,137,205,252,233,244,248,248,41,15,182,70,252,
70 254,255,72,141,68,36,80,252,233,244,247,248,42,15,182,70,252,254,141,4,194,
71 248,1,15,182,110,252,255,141,44,252,234,248,2,139,76,36,96,137,145,233,137,
72 252,234,73,137,192,137,205,137,116,36,100,232,251,1,2,139,149,233,133,192,
73 15,132,244,249,15,182,78,252,253,72,139,44,202,72,137,40,248,43,139,6,15,
74 182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,3,139,141,
75 233,137,113,252,244,15,182,70,252,253,72,139,44,194,72,137,105,16,141,177,
76 233,41,214,139,105,252,248,184,237,252,233,244,30,248,44,139,108,36,96,137,
77 149,233,68,141,4,194,141,20,202,137,252,233,68,15,182,78,252,252,137,116,
78 36,100,232,251,1,3,248,3,139,149,233,255,131,252,248,1,15,135,244,45,248,
79 4,141,118,4,15,130,244,252,248,5,15,183,70,252,254,141,180,253,134,233,248,
80 6,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,
81 46,131,198,4,129,120,253,4,239,15,130,244,5,252,233,244,6,248,47,129,120,
82 253,4,239,252,233,244,4,248,48,131,252,238,4,65,137,192,65,137,252,233,139,
83 108,36,96,137,149,233,255,137,202,137,252,233,137,116,36,100,232,251,1,4,
84 252,233,244,3,248,49,255,131,252,238,4,139,108,36,96,137,149,233,137,252,
85 233,139,86,252,252,137,116,36,100,232,251,1,5,252,233,244,3,255,248,50,255,
86 15,182,110,252,255,255,248,51,141,4,199,252,233,244,247,248,52,255,248,53,
87 141,4,199,141,44,252,234,149,252,233,244,248,248,54,141,4,194,137,197,252,
88 233,244,248,248,55,255,248,56,141,4,194,248,1,141,44,252,234,248,2,141,12,
89 202,65,137,232,65,137,193,15,182,70,252,252,137,68,36,32,139,108,36,96,137,
90 149,233,137,202,137,252,233,137,116,36,100,232,251,1,6,139,149,233,133,192,
91 15,132,244,43,248,45,137,193,41,208,137,113,252,244,141,176,233,184,237,252,
92 233,244,28,248,57,139,108,36,96,137,149,233,141,20,194,137,252,233,137,116,
93 36,100,232,251,1,7,139,149,233,255,133,192,15,133,244,45,15,183,70,252,254,
94 139,12,194,252,233,244,58,255,252,233,244,45,255,248,59,141,76,202,8,248,
95 29,137,76,36,84,137,68,36,80,131,252,233,8,139,108,36,96,137,149,233,137,
96 202,68,141,4,193,137,252,233,137,116,36,100,232,251,1,8,139,149,233,139,76,
97 36,84,139,68,36,80,139,105,252,248,131,192,1,57,215,15,132,244,60,137,202,
98 137,114,252,252,139,181,233,139,14,15,182,252,233,15,182,205,131,198,4,252,
99 255,36,252,235,248,61,139,108,36,96,137,149,233,137,202,137,252,233,137,116,
100 36,100,232,251,1,9,139,149,233,139,70,252,252,15,182,204,15,182,232,193,232,
101 16,252,255,164,253,252,235,233,248,62,129,252,248,239,15,130,244,63,139,106,
102 4,129,252,253,239,15,131,244,63,139,114,252,252,137,68,36,84,137,106,252,
103 252,139,42,137,106,252,248,131,232,2,15,132,244,248,255,137,209,248,1,131,
104 193,8,72,139,41,72,137,105,252,248,131,232,1,15,133,244,1,248,2,139,68,36,
105 84,252,233,244,64,248,65,129,252,248,239,15,130,244,63,139,106,4,137,252,
106 233,193,252,249,15,131,252,249,252,254,15,132,244,249,184,237,252,247,213,
107 57,232,255,15,71,197,255,15,134,244,247,137,232,248,1,255,248,2,139,106,252,
108 248,139,132,253,197,233,139,114,252,252,199,66,252,252,237,137,66,252,248,
109 252,233,244,66,248,3,184,237,252,233,244,2,248,67,129,252,248,239,15,130,
110 244,63,139,106,4,139,114,252,252,129,252,253,239,15,133,244,252,248,1,139,
111 42,139,173,233,248,2,133,252,237,199,66,252,252,237,255,15,132,244,66,139,
112 131,233,199,66,252,252,237,137,106,252,248,139,141,233,35,136,233,105,201,
113 239,3,141,233,248,3,129,185,233,239,15,133,244,250,57,129,233,15,132,244,
114 251,248,4,139,137,233,133,201,15,133,244,3,255,252,233,244,66,248,5,139,105,
115 4,129,252,253,239,15,132,244,66,139,1,137,106,252,252,137,66,252,248,252,
116 233,244,66,248,6,129,252,253,239,15,132,244,1,129,252,253,239,15,135,244,
117 254,129,252,253,239,15,134,244,253,189,237,252,233,244,254,248,7,255,189,
118 237,248,8,252,247,213,139,172,253,171,233,252,233,244,2,248,68,129,252,248,
119 239,15,130,244,63,129,122,253,4,239,15,133,244,63,139,42,131,189,233,0,15,
120 133,244,63,129,122,253,12,239,15,133,244,63,139,66,8,137,133,233,139,114,
121 252,252,199,66,252,252,237,255,137,106,252,248,252,246,133,233,235,15,132,
122 244,247,128,165,233,235,139,131,233,137,171,233,137,133,233,248,1,252,233,
123 244,66,248,69,129,252,248,239,15,130,244,63,129,122,253,4,239,15,133,244,
124 63,137,213,68,141,66,8,139,18,139,76,36,96,232,251,1,10,137,252,234,72,139,
125 40,139,114,252,252,72,137,106,252,248,252,233,244,66,248,70,255,129,252,248,
126 239,15,133,244,63,129,122,253,4,239,255,15,133,244,247,139,42,252,233,244,
127 71,248,1,15,135,244,63,255,15,131,244,63,255,252,242,15,16,2,252,233,244,
128 72,255,221,2,252,233,244,73,255,248,74,129,252,248,239,15,130,244,63,139,
129 114,252,252,129,122,253,4,239,15,133,244,249,139,2,248,2,199,66,252,252,237,
130 137,66,252,248,252,233,244,66,248,3,129,122,253,4,239,15,135,244,63,131,187,
131 233,0,15,133,244,63,139,171,233,59,171,233,255,15,130,244,247,232,244,75,
132 248,1,139,108,36,96,137,149,233,137,116,36,100,137,252,233,255,232,251,1,
133 11,255,232,251,1,12,255,139,149,233,252,233,244,2,248,76,129,252,248,239,
134 15,130,244,63,15,132,244,248,248,1,129,122,253,4,239,15,133,244,63,139,108,
135 36,96,137,149,233,137,149,233,139,114,252,252,68,141,66,8,139,18,137,252,
136 233,137,116,36,100,232,251,1,13,139,149,233,133,192,15,132,244,249,72,139,
137 106,8,72,139,66,16,72,137,106,252,248,72,137,2,248,77,184,237,255,252,233,
138 244,78,248,2,199,66,12,237,252,233,244,1,248,3,199,66,252,252,237,252,233,
139 244,66,248,79,129,252,248,239,15,130,244,63,139,42,129,122,253,4,239,15,133,
140 244,63,255,131,189,233,0,15,133,244,63,255,139,106,252,248,139,133,233,139,
141 114,252,252,199,66,252,252,237,137,66,252,248,199,66,12,237,184,237,252,233,
142 244,78,248,80,129,252,248,239,15,130,244,63,129,122,253,4,239,15,133,244,
143 63,129,122,253,12,239,255,139,114,252,252,255,139,66,8,131,192,1,199,66,252,
144 252,237,137,66,252,248,255,252,242,15,16,66,8,72,189,237,237,102,72,15,110,
145 205,252,242,15,88,193,252,242,15,45,192,252,242,15,17,66,252,248,255,139,
146 42,59,133,233,15,131,244,248,193,224,3,3,133,233,248,1,129,120,253,4,239,
147 15,132,244,81,72,139,40,72,137,42,252,233,244,77,248,2,131,189,233,0,15,132,
148 244,81,137,252,233,137,213,137,194,232,251,1,14,137,252,234,133,192,15,133,
149 244,1,248,81,184,237,252,233,244,78,248,82,255,139,106,252,248,139,133,233,
150 139,114,252,252,199,66,252,252,237,137,66,252,248,255,199,66,12,237,199,66,
151 8,0,0,0,0,255,15,87,192,252,242,15,17,66,8,255,217,252,238,221,90,8,255,184,
152 237,252,233,244,78,248,83,129,252,248,239,15,130,244,63,141,74,8,131,232,
153 1,190,237,248,1,15,182,171,233,193,252,237,235,131,229,1,1,252,238,252,233,
154 244,28,248,84,129,252,248,239,15,130,244,63,129,122,253,12,239,15,133,244,
155 63,255,139,106,4,137,106,12,199,66,4,237,139,42,139,114,8,137,106,8,137,50,
156 141,74,16,131,232,2,190,237,252,233,244,1,248,85,129,252,248,239,15,130,244,
157 63,139,42,139,114,252,252,137,116,36,100,137,108,36,80,129,122,253,4,239,
158 15,133,244,63,72,131,189,233,0,15,133,244,63,128,189,233,235,15,135,244,63,
159 139,141,233,15,132,244,247,255,59,141,233,15,132,244,63,248,1,141,116,193,
160 252,240,59,181,233,15,135,244,63,137,181,233,139,108,36,96,137,149,233,131,
161 194,8,137,149,233,141,108,194,232,72,41,252,245,57,206,15,132,244,249,248,
162 2,72,139,4,46,72,137,70,252,248,131,252,238,8,57,206,15,133,244,2,248,3,137,
163 202,139,76,36,80,232,244,25,199,131,233,237,255,139,108,36,96,139,116,36,
164 80,139,149,233,129,252,248,239,15,135,244,254,248,4,139,142,233,139,190,233,
165 137,142,233,137,252,254,41,206,15,132,244,252,141,4,50,193,252,238,3,59,133,
166 233,15,135,244,255,137,213,72,41,205,248,5,72,139,1,72,137,4,41,131,193,8,
167 57,252,249,15,133,244,5,248,6,141,70,2,199,66,252,252,237,248,7,139,116,36,
168 100,137,68,36,84,72,199,193,252,248,252,255,252,255,252,255,252,247,198,237,
169 255,15,132,244,13,252,233,244,14,248,8,199,66,252,252,237,139,142,233,131,
170 252,233,8,137,142,233,72,139,1,72,137,2,184,237,252,233,244,7,248,9,139,76,
171 36,80,137,185,233,137,252,242,137,252,233,232,251,1,0,139,116,36,80,139,149,
172 233,252,233,244,4,248,86,139,106,252,248,139,173,233,139,114,252,252,137,
173 116,36,100,137,108,36,80,72,131,189,233,0,15,133,244,63,255,128,189,233,235,
174 15,135,244,63,139,141,233,15,132,244,247,59,141,233,15,132,244,63,248,1,141,
175 116,193,252,248,59,181,233,15,135,244,63,137,181,233,139,108,36,96,137,149,
176 233,137,149,233,141,108,194,252,240,72,41,252,245,57,206,15,132,244,249,248,
177 2,255,72,139,4,46,72,137,70,252,248,131,252,238,8,57,206,15,133,244,2,248,
178 3,137,202,139,76,36,80,232,244,25,199,131,233,237,139,108,36,96,139,116,36,
179 80,139,149,233,129,252,248,239,15,135,244,254,248,4,139,142,233,139,190,233,
180 137,142,233,137,252,254,41,206,15,132,244,252,141,4,50,193,252,238,3,59,133,
181 233,15,135,244,255,255,137,213,72,41,205,248,5,72,139,1,72,137,4,41,131,193,
182 8,57,252,249,15,133,244,5,248,6,141,70,1,248,7,139,116,36,100,137,68,36,84,
183 49,201,252,247,198,237,15,132,244,13,252,233,244,14,248,8,137,252,242,137,
184 252,233,232,251,1,15,248,9,139,76,36,80,137,185,233,137,252,242,137,252,233,
185 232,251,1,0,139,116,36,80,139,149,233,252,233,244,4,248,87,139,108,36,96,
186 72,252,247,133,233,237,15,132,244,63,255,137,149,233,141,68,194,252,248,137,
187 133,233,49,192,72,137,133,233,176,235,136,133,233,252,233,244,16,255,248,
188 71,255,248,73,139,114,252,252,221,90,252,248,252,233,244,66,255,248,88,129,
189 252,248,239,15,130,244,63,255,129,122,253,4,239,15,133,244,248,139,42,131,
190 252,253,0,15,137,244,71,252,247,221,15,136,244,247,248,89,248,71,139,114,
191 252,252,199,66,252,252,237,137,106,252,248,252,233,244,66,248,1,139,114,252,
192 252,199,66,252,252,0,0,224,65,199,66,252,248,0,0,0,0,252,233,244,66,248,2,
193 15,135,244,63,255,129,122,253,4,239,15,131,244,63,255,252,242,15,16,2,72,
194 184,237,237,102,72,15,110,200,15,84,193,248,72,139,114,252,252,252,242,15,
195 17,66,252,248,255,221,2,217,225,248,72,248,73,139,114,252,252,221,90,252,
196 248,255,248,66,184,237,248,78,137,68,36,84,248,64,252,247,198,237,15,133,
197 244,253,248,5,56,70,252,255,15,135,244,252,15,182,78,252,253,72,252,247,209,
198 141,20,202,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,
199 235,248,6,199,68,194,252,244,237,131,192,1,252,233,244,5,248,7,72,199,193,
200 252,248,252,255,252,255,252,255,252,233,244,14,248,90,255,129,122,253,4,239,
201 15,133,244,247,139,42,252,233,244,71,248,1,15,135,244,63,255,252,242,15,16,
202 2,232,244,91,255,252,242,15,45,232,129,252,253,0,0,0,128,15,133,244,71,252,
203 242,15,42,205,102,15,46,193,15,138,244,72,15,132,244,71,255,221,2,232,244,
204 91,255,248,92,255,252,242,15,16,2,232,244,93,255,221,2,232,244,93,255,248,
205 94,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,252,242,
206 15,81,2,252,233,244,72,255,248,94,129,252,248,239,15,130,244,63,129,122,253,
207 4,239,15,131,244,63,221,2,217,252,250,252,233,244,73,255,248,95,129,252,248,
208 239,15,130,244,63,129,122,253,4,239,15,131,244,63,217,252,237,221,2,217,252,
209 241,252,233,244,73,248,96,129,252,248,239,15,130,244,63,129,122,253,4,239,
210 15,131,244,63,217,252,236,221,2,217,252,241,252,233,244,73,248,97,129,252,
211 248,239,255,15,130,244,63,129,122,253,4,239,15,131,244,63,221,2,232,244,98,
212 252,233,244,73,248,99,129,252,248,239,15,130,244,63,129,122,253,4,239,15,
213 131,244,63,221,2,217,252,254,252,233,244,73,248,100,129,252,248,239,255,15,
214 130,244,63,129,122,253,4,239,15,131,244,63,221,2,217,252,255,252,233,244,
215 73,248,101,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,
216 221,2,217,252,242,221,216,252,233,244,73,248,102,129,252,248,239,15,130,244,
217 63,255,129,122,253,4,239,15,131,244,63,221,2,217,192,216,200,217,232,222,
218 225,217,252,250,217,252,243,252,233,244,73,248,103,129,252,248,239,15,130,
219 244,63,129,122,253,4,239,15,131,244,63,221,2,217,192,216,200,217,232,222,
220 225,217,252,250,217,201,217,252,243,252,233,244,73,248,104,129,252,248,239,
221 15,130,244,63,129,122,253,4,239,15,131,244,63,255,221,2,217,232,217,252,243,
222 252,233,244,73,255,248,105,129,252,248,239,15,130,244,63,129,122,253,4,239,
223 15,131,244,63,252,242,15,16,2,255,137,213,232,251,1,16,137,252,234,252,233,
224 244,72,255,248,106,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,
225 244,63,252,242,15,16,2,255,137,213,232,251,1,17,137,252,234,252,233,244,72,
226 255,248,107,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,
227 252,242,15,16,2,255,137,213,232,251,1,18,137,252,234,252,233,244,72,248,108,
228 255,248,109,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,
229 252,242,15,16,2,139,106,252,248,252,242,15,89,133,233,252,233,244,72,255,
230 248,109,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,221,
231 2,139,106,252,248,220,141,233,252,233,244,73,255,248,110,129,252,248,239,
232 15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
233 63,221,2,221,66,8,217,252,243,252,233,244,73,248,111,129,252,248,239,15,130,
234 244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,255,15,131,244,
235 63,221,66,8,221,2,217,252,253,221,217,252,233,244,73,248,112,129,252,248,
236 239,15,130,244,63,139,106,4,129,252,253,239,15,131,244,63,139,114,252,252,
237 139,2,137,106,252,252,137,66,252,248,209,229,129,252,253,0,0,224,252,255,
238 15,131,244,249,9,232,15,132,244,249,184,252,254,3,0,0,129,252,253,0,0,32,
239 0,15,130,244,250,248,1,193,252,237,21,41,197,255,252,242,15,42,197,255,137,
240 108,36,80,219,68,36,80,255,139,106,252,252,129,229,252,255,252,255,15,128,
241 129,205,0,0,224,63,137,106,252,252,248,2,255,252,242,15,17,2,255,221,26,255,
242 184,237,252,233,244,78,248,3,255,15,87,192,252,233,244,2,255,217,252,238,
243 252,233,244,2,255,248,4,255,252,242,15,16,2,72,189,237,237,102,72,15,110,
244 205,252,242,15,89,193,252,242,15,17,66,252,248,255,221,2,199,68,36,80,0,0,
245 128,90,216,76,36,80,221,90,252,248,255,139,106,252,252,184,52,4,0,0,209,229,
246 252,233,244,1,255,248,113,129,252,248,239,15,130,244,63,129,122,253,4,239,
247 15,131,244,63,252,242,15,16,2,255,248,113,129,252,248,239,15,130,244,63,129,
248 122,253,4,239,15,131,244,63,221,2,255,139,106,4,139,114,252,252,209,229,129,
249 252,253,0,0,224,252,255,15,132,244,250,255,15,40,224,232,244,114,252,242,
250 15,92,224,248,1,252,242,15,17,66,252,248,252,242,15,17,34,255,217,192,232,
251 244,114,220,252,233,248,1,221,90,252,248,221,26,255,139,66,252,252,139,106,
252 4,49,232,15,136,244,249,248,2,184,237,252,233,244,78,248,3,129,252,245,0,
253 0,0,128,137,106,4,252,233,244,2,248,4,255,15,87,228,252,233,244,1,255,217,
254 252,238,217,201,252,233,244,1,255,248,115,129,252,248,239,15,130,244,63,129,
255 122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,63,221,66,8,221,
256 2,248,1,217,252,248,223,224,158,15,138,244,1,221,217,252,233,244,73,255,248,
257 116,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,
258 253,12,239,15,131,244,63,252,242,15,16,2,252,242,15,16,74,8,232,244,117,252,
259 233,244,72,255,248,116,129,252,248,239,15,130,244,63,129,122,253,4,239,15,
260 131,244,63,129,122,253,12,239,15,131,244,63,221,2,221,66,8,232,244,117,252,
261 233,244,73,255,248,118,185,2,0,0,0,129,122,253,4,239,255,15,133,244,250,139,
262 42,248,1,57,193,15,131,244,71,129,124,253,202,252,252,239,15,133,244,249,
263 59,108,202,252,248,15,79,108,202,252,248,131,193,1,252,233,244,1,248,3,15,
264 135,244,63,255,252,233,244,252,248,4,15,135,244,63,255,252,242,15,16,2,248,
265 5,57,193,15,131,244,72,129,124,253,202,252,252,239,255,15,130,244,252,15,
266 135,244,63,252,242,15,42,76,202,252,248,252,233,244,253,255,248,6,252,242,
267 15,16,76,202,252,248,248,7,252,242,15,93,193,131,193,1,252,233,244,5,255,
268 248,119,185,2,0,0,0,129,122,253,4,239,255,15,133,244,250,139,42,248,1,57,
269 193,15,131,244,71,129,124,253,202,252,252,239,15,133,244,249,59,108,202,252,
270 248,15,76,108,202,252,248,131,193,1,252,233,244,1,248,3,15,135,244,63,255,
271 248,6,252,242,15,16,76,202,252,248,248,7,252,242,15,95,193,131,193,1,252,
272 233,244,5,255,248,9,221,216,252,233,244,63,255,248,120,129,252,248,239,15,
273 130,244,63,129,122,253,4,239,15,133,244,63,139,42,255,139,173,233,252,233,
274 244,71,255,252,242,15,42,133,233,252,233,244,72,255,219,133,233,252,233,244,
275 73,255,248,121,129,252,248,239,15,133,244,63,129,122,253,4,239,15,133,244,
276 63,139,42,139,114,252,252,131,189,233,1,15,130,244,81,15,182,173,233,255,
277 252,242,15,42,197,252,233,244,72,255,137,108,36,80,219,68,36,80,252,233,244,
278 73,255,248,122,139,171,233,59,171,233,15,130,244,247,232,244,75,248,1,129,
279 252,248,239,15,133,244,63,129,122,253,4,239,255,15,133,244,63,139,42,129,
280 252,253,252,255,0,0,0,15,135,244,63,137,108,36,84,255,15,131,244,63,252,242,
281 15,44,42,129,252,253,252,255,0,0,0,15,135,244,63,137,108,36,84,255,15,131,
282 244,63,221,2,219,92,36,84,129,124,36,84,252,255,0,0,0,15,135,244,63,255,199,
283 68,36,32,1,0,0,0,72,141,68,36,84,248,123,139,108,36,96,137,149,233,68,139,
284 68,36,32,72,137,194,137,252,233,137,116,36,100,232,251,1,19,139,149,233,139,
285 114,252,252,199,66,252,252,237,137,66,252,248,252,233,244,66,248,124,139,
286 171,233,59,171,233,15,130,244,247,232,244,75,248,1,199,68,36,84,252,255,252,
287 255,252,255,252,255,129,252,248,239,15,130,244,63,15,134,244,247,129,122,
288 253,20,239,255,15,133,244,63,139,106,16,137,108,36,84,255,15,131,244,63,252,
289 242,15,44,106,16,137,108,36,84,255,15,131,244,63,221,66,16,219,92,36,84,255,
290 248,1,129,122,253,4,239,15,133,244,63,129,122,253,12,239,255,139,42,137,108,
291 36,32,139,173,233,255,139,74,8,255,252,242,15,44,74,8,255,139,68,36,84,57,
292 197,15,130,244,251,248,2,133,201,15,142,244,253,248,3,139,108,36,32,41,200,
293 15,140,244,125,141,172,253,13,233,131,192,1,248,4,137,68,36,32,137,232,252,
294 233,244,123,248,5,15,140,244,252,141,68,40,1,252,233,244,2,248,6,137,232,
295 252,233,244,2,248,7,255,15,132,244,254,1,252,233,131,193,1,15,143,244,3,248,
296 8,185,1,0,0,0,252,233,244,3,248,125,49,192,252,233,244,4,248,126,129,252,
297 248,239,15,130,244,63,139,171,233,59,171,233,15,130,244,247,232,244,75,248,
298 1,255,129,122,253,4,239,15,133,244,63,129,122,253,12,239,139,42,255,15,133,
299 244,63,139,66,8,255,15,131,244,63,252,242,15,44,66,8,255,15,131,244,63,221,
300 66,8,219,92,36,84,139,68,36,84,255,133,192,15,142,244,125,131,189,233,1,15,
301 130,244,125,15,133,244,127,57,131,233,15,130,244,127,15,182,141,233,139,171,
302 233,137,68,36,32,248,1,136,77,0,131,197,1,131,232,1,15,133,244,1,139,131,
303 233,252,233,244,123,248,128,129,252,248,239,255,15,130,244,63,139,171,233,
304 59,171,233,15,130,244,247,232,244,75,248,1,129,122,253,4,239,15,133,244,63,
305 139,42,139,133,233,133,192,15,132,244,125,57,131,233,15,130,244,129,129,197,
306 239,137,116,36,84,137,68,36,32,139,179,233,248,1,255,15,182,77,0,131,197,
307 1,131,232,1,136,12,6,15,133,244,1,137,252,240,139,116,36,84,252,233,244,123,
308 248,130,129,252,248,239,15,130,244,63,139,171,233,59,171,233,15,130,244,247,
309 232,244,75,248,1,129,122,253,4,239,15,133,244,63,139,42,139,133,233,57,131,
310 233,255,15,130,244,129,129,197,239,137,116,36,84,137,68,36,32,139,179,233,
311 252,233,244,249,248,1,15,182,76,5,0,131,252,249,65,15,130,244,248,131,252,
312 249,90,15,135,244,248,131,252,241,32,248,2,136,12,6,248,3,131,232,1,15,137,
313 244,1,137,252,240,139,116,36,84,252,233,244,123,248,131,129,252,248,239,15,
314 130,244,63,255,139,171,233,59,171,233,15,130,244,247,232,244,75,248,1,129,
315 122,253,4,239,15,133,244,63,139,42,139,133,233,57,131,233,15,130,244,129,
316 129,197,239,137,116,36,84,137,68,36,32,139,179,233,252,233,244,249,248,1,
317 15,182,76,5,0,131,252,249,97,15,130,244,248,255,131,252,249,122,15,135,244,
318 248,131,252,241,32,248,2,136,12,6,248,3,131,232,1,15,137,244,1,137,252,240,
319 139,116,36,84,252,233,244,123,248,132,129,252,248,239,15,130,244,63,129,122,
320 253,4,239,15,133,244,63,137,213,139,10,232,251,1,20,137,252,234,255,137,197,
321 252,233,244,71,255,252,242,15,42,192,252,233,244,72,255,248,133,129,252,248,
322 239,15,130,244,63,129,122,253,4,239,255,15,133,244,247,139,42,252,233,244,
323 89,248,1,15,135,244,63,255,252,242,15,16,2,72,189,237,237,102,72,15,110,205,
324 252,242,15,88,193,102,15,126,197,255,252,233,244,89,255,248,134,129,252,248,
325 239,15,130,244,63,255,72,189,237,237,102,72,15,110,205,255,199,68,36,80,0,
326 0,192,89,255,15,133,244,247,139,42,252,233,244,248,248,1,15,135,244,63,255,
327 252,242,15,16,2,252,242,15,88,193,102,15,126,197,255,248,2,137,68,36,84,141,
328 68,194,252,240,248,1,57,208,15,134,244,89,129,120,253,4,239,255,15,133,244,
329 248,35,40,131,232,8,252,233,244,1,248,2,15,135,244,135,255,15,131,244,135,
330 255,252,242,15,16,0,252,242,15,88,193,102,15,126,193,33,205,255,131,232,8,
331 252,233,244,1,248,136,129,252,248,239,15,130,244,63,255,15,133,244,248,11,
332 40,131,232,8,252,233,244,1,248,2,15,135,244,135,255,252,242,15,16,0,252,242,
333 15,88,193,102,15,126,193,9,205,255,131,232,8,252,233,244,1,248,137,129,252,
334 248,239,15,130,244,63,255,15,133,244,248,51,40,131,232,8,252,233,244,1,248,
335 2,15,135,244,135,255,252,242,15,16,0,252,242,15,88,193,102,15,126,193,49,
336 205,255,131,232,8,252,233,244,1,248,138,129,252,248,239,15,130,244,63,129,
337 122,253,4,239,255,248,2,15,205,252,233,244,89,248,139,129,252,248,239,15,
338 130,244,63,129,122,253,4,239,255,248,2,252,247,213,255,248,89,252,242,15,
339 42,197,252,233,244,72,255,248,135,139,68,36,84,252,233,244,63,255,248,140,
340 129,252,248,239,15,130,244,63,129,122,253,4,239,255,248,2,129,122,253,12,
341 239,15,133,244,63,139,74,8,255,248,140,129,252,248,239,15,130,244,63,129,
342 122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,
343 2,252,242,15,16,74,8,72,189,237,237,102,72,15,110,213,252,242,15,88,194,252,
344 242,15,88,202,102,15,126,197,102,15,126,201,255,211,229,252,233,244,89,255,
345 248,141,129,252,248,239,15,130,244,63,129,122,253,4,239,255,248,141,129,252,
346 248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,
347 15,131,244,63,252,242,15,16,2,252,242,15,16,74,8,72,189,237,237,102,72,15,
348 110,213,252,242,15,88,194,252,242,15,88,202,102,15,126,197,102,15,126,201,
349 255,211,252,237,252,233,244,89,255,248,142,129,252,248,239,15,130,244,63,
350 129,122,253,4,239,255,248,142,129,252,248,239,15,130,244,63,129,122,253,4,
351 239,15,131,244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,
352 15,16,74,8,72,189,237,237,102,72,15,110,213,252,242,15,88,194,252,242,15,
353 88,202,102,15,126,197,102,15,126,201,255,211,252,253,252,233,244,89,255,248,
354 143,129,252,248,239,15,130,244,63,129,122,253,4,239,255,248,143,129,252,248,
355 239,15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,
356 244,63,252,242,15,16,2,252,242,15,16,74,8,72,189,237,237,102,72,15,110,213,
357 252,242,15,88,194,252,242,15,88,202,102,15,126,197,102,15,126,201,255,211,
358 197,252,233,244,89,255,248,144,129,252,248,239,15,130,244,63,129,122,253,
359 4,239,255,248,144,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,
360 244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,15,16,74,
361 8,72,189,237,237,102,72,15,110,213,252,242,15,88,194,252,242,15,88,202,102,
362 15,126,197,102,15,126,201,255,211,205,252,233,244,89,248,127,184,237,252,
363 233,244,63,248,129,184,237,248,63,139,108,36,96,139,114,252,252,137,116,36,
364 100,137,149,233,141,68,194,252,248,141,136,233,137,133,233,139,66,252,248,
365 59,141,233,15,135,244,251,137,252,233,252,255,144,233,139,149,233,133,192,
366 15,143,244,78,248,1,255,139,141,233,41,209,193,252,233,3,133,192,141,65,1,
367 139,106,252,248,15,133,244,33,139,181,233,139,14,15,182,252,233,15,182,205,
368 131,198,4,252,255,36,252,235,248,33,137,209,252,247,198,237,15,133,244,249,
369 15,182,110,252,253,72,252,247,213,141,20,252,234,252,233,244,28,248,3,137,
370 252,245,131,229,252,248,41,252,234,252,233,244,28,248,5,186,237,137,252,233,
371 232,251,1,0,139,149,233,49,192,252,233,244,1,248,75,93,72,137,108,36,32,139,
372 108,36,96,137,116,36,100,137,149,233,255,141,68,194,252,248,137,252,233,137,
373 133,233,232,251,1,21,139,149,233,139,133,233,41,208,193,232,3,131,192,1,72,
374 139,108,36,32,85,195,248,145,255,15,182,131,233,168,235,15,133,244,251,168,
375 235,15,133,244,247,168,235,15,132,244,247,252,255,139,233,252,233,244,247,
376 255,248,146,15,182,131,233,168,235,15,133,244,251,252,233,244,247,248,147,
377 15,182,131,233,168,235,15,133,244,251,168,235,15,132,244,251,252,255,139,
378 233,15,132,244,247,168,235,15,132,244,251,248,1,255,139,108,36,96,137,149,
379 233,137,252,242,137,252,233,232,251,1,22,248,3,139,149,233,248,4,15,182,78,
380 252,253,248,5,15,182,110,252,252,15,183,70,252,254,252,255,164,253,252,235,
381 233,248,148,131,198,4,139,77,232,137,76,36,84,252,233,244,4,248,149,255,139,
382 106,252,248,139,173,233,15,182,133,233,141,4,194,139,108,36,96,137,149,233,
383 137,133,233,137,252,242,141,139,233,72,137,171,233,137,116,36,100,232,251,
384 1,23,252,233,244,3,255,248,150,137,116,36,100,255,248,151,255,137,116,36,
385 100,131,206,1,248,1,255,141,68,194,252,248,139,108,36,96,137,149,233,137,
386 133,233,137,252,242,137,252,233,232,251,1,24,199,68,36,100,0,0,0,0,255,131,
387 230,252,254,255,139,149,233,72,137,193,139,133,233,41,208,72,137,205,15,182,
388 78,252,253,193,232,3,131,192,1,252,255,229,248,152,255,65,85,65,84,65,83,
389 65,82,65,81,65,80,87,86,85,72,141,108,36,88,85,83,82,81,80,15,182,69,252,
390 248,138,101,252,240,76,137,125,252,248,76,137,117,252,240,139,93,0,139,139,
391 233,199,131,233,237,137,131,233,137,139,233,72,129,252,236,239,72,131,197,
392 128,252,242,68,15,17,125,252,248,252,242,68,15,17,117,252,240,252,242,68,
393 15,17,109,232,252,242,68,15,17,101,224,252,242,68,15,17,93,216,252,242,68,
394 15,17,85,208,252,242,68,15,17,77,200,252,242,68,15,17,69,192,252,242,15,17,
395 125,184,252,242,15,17,117,176,252,242,15,17,109,168,252,242,15,17,101,160,
396 252,242,15,17,93,152,252,242,15,17,85,144,252,242,15,17,77,136,252,242,15,
397 17,69,128,139,171,233,139,147,233,72,137,171,233,199,131,233,0,0,0,0,137,
398 149,233,72,141,148,253,36,233,141,139,233,232,251,1,25,72,139,141,233,72,
399 129,225,239,137,169,233,139,149,233,139,177,233,252,233,244,247,255,248,153,
400 255,72,141,140,253,36,233,248,1,102,68,15,111,185,233,102,68,15,111,177,233,
401 102,68,15,111,169,233,102,68,15,111,161,233,102,68,15,111,153,233,102,68,
402 15,111,145,233,102,68,15,111,137,233,102,68,15,111,129,233,102,15,111,185,
403 233,72,137,204,102,15,111,49,76,139,124,36,16,76,139,116,36,24,76,139,108,
404 36,32,76,139,100,36,80,133,192,15,136,244,249,137,68,36,84,139,122,252,248,
405 139,191,233,139,191,233,199,131,233,0,0,0,0,199,131,233,237,139,6,15,182,
406 204,15,182,232,131,198,4,193,232,16,129,252,253,239,15,130,244,248,255,139,
407 68,36,84,248,2,252,255,36,252,235,248,3,252,247,216,137,252,233,137,194,232,
408 251,1,26,255,248,91,255,217,124,36,4,137,68,36,8,102,184,0,4,102,11,68,36,
409 4,102,37,252,255,252,247,102,137,68,36,6,217,108,36,6,217,252,252,217,108,
410 36,4,139,68,36,8,195,255,248,154,72,184,237,237,102,72,15,110,208,72,184,
411 237,237,102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,
412 247,102,15,85,208,252,242,15,88,203,252,242,15,92,203,102,15,86,202,72,184,
413 237,237,102,72,15,110,208,252,242,15,194,193,1,102,15,84,194,252,242,15,92,
414 200,15,40,193,248,1,195,248,93,255,217,124,36,4,137,68,36,8,102,184,0,8,102,
415 11,68,36,4,102,37,252,255,252,251,102,137,68,36,6,217,108,36,6,217,252,252,
416 217,108,36,4,139,68,36,8,195,255,248,155,72,184,237,237,102,72,15,110,208,
417 72,184,237,237,102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,
418 134,244,247,102,15,85,208,252,242,15,88,203,252,242,15,92,203,102,15,86,202,
419 72,184,237,237,102,72,15,110,208,252,242,15,194,193,6,102,15,84,194,252,242,
420 15,92,200,15,40,193,248,1,195,248,114,255,217,124,36,4,137,68,36,8,102,184,
421 0,12,102,11,68,36,4,102,137,68,36,6,217,108,36,6,217,252,252,217,108,36,4,
422 139,68,36,8,195,255,248,156,72,184,237,237,102,72,15,110,208,72,184,237,237,
423 102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,247,102,
424 15,85,208,15,40,193,252,242,15,88,203,252,242,15,92,203,72,184,237,237,102,
425 72,15,110,216,252,242,15,194,193,1,102,15,84,195,252,242,15,92,200,102,15,
426 86,202,15,40,193,248,1,195,248,157,255,15,40,232,252,242,15,94,193,72,184,
427 237,237,102,72,15,110,208,72,184,237,237,102,72,15,110,216,15,40,224,102,
428 15,84,226,102,15,46,220,15,134,244,247,102,15,85,208,252,242,15,88,227,252,
429 242,15,92,227,102,15,86,226,72,184,237,237,102,72,15,110,208,252,242,15,194,
430 196,1,102,15,84,194,252,242,15,92,224,15,40,197,252,242,15,89,204,252,242,
431 15,92,193,195,248,1,252,242,15,89,200,15,40,197,252,242,15,92,193,195,255,
432 217,193,216,252,241,217,124,36,4,102,184,0,4,102,11,68,36,4,102,37,252,255,
433 252,247,102,137,68,36,6,217,108,36,6,217,252,252,217,108,36,4,222,201,222,
434 252,233,195,255,248,98,217,252,234,222,201,248,158,217,84,36,8,129,124,36,
435 8,0,0,128,127,15,132,244,247,129,124,36,8,0,0,128,252,255,15,132,244,248,
436 248,159,217,192,217,252,252,220,252,233,217,201,217,252,240,217,232,222,193,
437 217,252,253,221,217,248,1,195,248,2,221,216,217,252,238,195,255,248,117,255,
438 248,160,252,242,15,45,193,252,242,15,42,208,102,15,46,202,15,133,244,254,
439 15,138,244,255,248,161,131,252,248,1,15,142,244,252,248,1,169,1,0,0,0,15,
440 133,244,248,252,242,15,89,192,209,232,252,233,244,1,248,2,209,232,15,132,
441 244,251,15,40,200,248,3,252,242,15,89,192,209,232,15,132,244,250,15,131,244,
442 3,255,252,242,15,89,200,252,233,244,3,248,4,252,242,15,89,193,248,5,195,248,
443 6,15,132,244,5,15,130,244,253,252,247,216,232,244,1,72,184,237,237,102,72,
444 15,110,200,252,242,15,94,200,15,40,193,195,248,7,72,184,237,237,102,72,15,
445 110,192,195,248,8,102,72,15,126,200,72,209,224,72,193,192,12,72,61,252,254,
446 15,0,0,15,132,244,248,102,72,15,126,192,72,209,224,15,132,244,250,255,72,
447 193,192,12,72,61,252,254,15,0,0,15,132,244,251,252,242,15,17,76,36,16,252,
448 242,15,17,68,36,8,221,68,36,16,221,68,36,8,217,252,241,217,192,217,252,252,
449 220,252,233,217,201,217,252,240,217,232,222,193,217,252,253,221,217,221,92,
450 36,8,252,242,15,16,68,36,8,195,248,9,72,184,237,237,102,72,15,110,208,102,
451 15,46,194,15,132,244,247,15,40,193,248,1,195,248,2,72,184,237,237,102,72,
452 15,110,208,102,15,84,194,72,184,237,237,102,72,15,110,208,102,15,46,194,15,
453 132,244,1,102,15,80,193,15,87,192,136,196,15,146,208,48,224,15,133,244,1,
454 248,3,72,184,237,237,255,102,72,15,110,192,195,248,4,102,15,80,193,133,192,
455 15,133,244,3,15,87,192,195,248,5,102,15,80,193,133,192,15,132,244,3,15,87,
456 192,195,248,162,255,131,252,250,1,15,130,244,91,15,132,244,93,131,252,250,
457 3,15,130,244,114,15,135,244,248,252,242,15,81,192,195,248,2,252,242,15,17,
458 68,36,8,221,68,36,8,131,252,250,5,15,135,244,248,88,15,132,244,247,232,244,
459 98,80,252,233,244,253,248,1,232,244,158,255,80,252,233,244,253,248,2,131,
460 252,250,7,15,132,244,247,15,135,244,248,217,252,237,217,201,217,252,241,252,
461 233,244,253,248,1,217,232,217,201,217,252,241,252,233,244,253,248,2,131,252,
462 250,9,15,132,244,247,15,135,244,248,217,252,236,217,201,217,252,241,252,233,
463 244,253,248,1,255,217,252,254,252,233,244,253,248,2,131,252,250,11,15,132,
464 244,247,15,135,244,255,217,252,255,252,233,244,253,248,1,217,252,242,221,
465 216,248,7,221,92,36,8,252,242,15,16,68,36,8,195,255,139,84,36,12,221,68,36,
466 4,131,252,250,1,15,130,244,91,15,132,244,93,131,252,250,3,15,130,244,114,
467 15,135,244,248,217,252,250,195,248,2,131,252,250,5,15,130,244,98,15,132,244,
468 158,131,252,250,7,15,132,244,247,15,135,244,248,217,252,237,217,201,217,252,
469 241,195,248,1,217,232,217,201,217,252,241,195,248,2,131,252,250,9,15,132,
470 244,247,255,15,135,244,248,217,252,236,217,201,217,252,241,195,248,1,217,
471 252,254,195,248,2,131,252,250,11,15,132,244,247,15,135,244,255,217,252,255,
472 195,248,1,217,252,242,221,216,195,255,248,9,204,255,248,163,255,65,131,252,
473 248,1,15,132,244,247,15,135,244,248,252,242,15,88,193,195,248,1,252,242,15,
474 92,193,195,248,2,65,131,252,248,3,15,132,244,247,15,135,244,248,252,242,15,
475 89,193,195,248,1,252,242,15,94,193,195,248,2,65,131,252,248,5,15,130,244,
476 157,15,132,244,117,65,131,252,248,7,15,132,244,247,15,135,244,248,72,184,
477 237,237,255,102,72,15,110,200,15,87,193,195,248,1,72,184,237,237,102,72,15,
478 110,200,15,84,193,195,248,2,65,131,252,248,9,15,135,244,248,252,242,15,17,
479 68,36,8,252,242,15,17,76,36,16,221,68,36,8,221,68,36,16,15,132,244,247,217,
480 252,243,248,7,221,92,36,8,252,242,15,16,68,36,8,195,248,1,217,201,217,252,
481 253,221,217,252,233,244,7,248,2,65,131,252,248,11,15,132,244,247,15,135,244,
482 255,252,242,15,93,193,195,248,1,252,242,15,95,193,195,248,9,204,255,139,68,
483 36,20,221,68,36,4,221,68,36,12,131,252,248,1,15,132,244,247,15,135,244,248,
484 222,193,195,248,1,222,252,233,195,248,2,131,252,248,3,15,132,244,247,15,135,
485 244,248,222,201,195,248,1,222,252,249,195,248,2,131,252,248,5,15,130,244,
486 157,15,132,244,117,131,252,248,7,15,132,244,247,15,135,244,248,255,221,216,
487 217,224,195,248,1,221,216,217,225,195,248,2,131,252,248,9,15,132,244,247,
488 15,135,244,248,217,252,243,195,248,1,217,201,217,252,253,221,217,195,248,
489 2,131,252,248,11,15,132,244,247,15,135,244,255,255,219,252,233,219,209,221,
490 217,195,248,1,219,252,233,218,209,221,217,195,255,221,225,223,224,252,246,
491 196,1,15,132,244,248,217,201,248,2,221,216,195,248,1,221,225,223,224,252,
492 246,196,1,15,133,244,248,217,201,248,2,221,216,195,255,248,164,137,200,86,
493 72,137,214,83,15,162,137,6,137,94,4,137,78,8,137,86,12,91,94,195,248,165,
494 255,204,248,166,255,87,86,83,72,131,252,236,40,141,157,233,139,181,233,15,
495 183,192,137,134,233,72,137,142,233,72,137,150,233,76,137,134,233,76,137,142,
496 233,252,242,15,17,134,233,252,242,15,17,142,233,252,242,15,17,150,233,252,
497 242,15,17,158,233,72,141,132,253,36,233,72,137,134,233,72,137,226,137,116,
498 36,100,137,252,241,232,251,1,27,199,131,233,237,139,144,233,139,128,233,41,
499 208,139,106,252,248,193,232,3,131,192,1,139,181,233,139,14,15,182,252,233,
500 15,182,205,131,198,4,252,255,36,252,235,255,248,32,255,139,76,36,96,139,179,
501 233,72,137,142,233,137,145,233,137,169,233,137,252,241,137,194,232,251,1,
502 28,72,139,134,233,252,242,15,16,134,233,252,233,244,16,255,248,167,255,85,
503 72,137,229,83,72,137,203,139,131,233,72,41,196,255,15,182,139,233,131,252,
504 233,1,15,136,244,248,248,1,72,139,132,253,203,233,72,137,132,253,204,233,
505 131,252,233,1,15,137,244,1,248,2,15,182,131,233,72,139,139,233,72,139,147,
506 233,76,139,131,233,76,139,139,233,133,192,15,132,244,251,15,40,131,233,15,
507 40,139,233,15,40,147,233,15,40,155,233,248,5,255,252,255,147,233,72,137,131,
508 233,15,41,131,233,255,72,139,93,252,248,201,195,255,129,124,253,202,4,239,
509 15,133,244,253,129,124,253,194,4,239,15,133,244,254,139,44,202,131,198,4,
510 59,44,194,255,15,141,244,255,255,15,140,244,255,255,15,143,244,255,255,15,
511 142,244,255,255,248,6,15,183,70,252,254,141,180,253,134,233,248,9,139,6,15,
512 182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,7,15,135,244,
513 44,129,124,253,194,4,239,15,130,244,247,15,133,244,44,255,252,242,15,42,4,
514 194,252,233,244,248,255,221,4,202,219,4,194,252,233,244,249,255,248,8,15,
515 135,244,44,255,252,242,15,42,12,202,252,242,15,16,4,194,131,198,4,102,15,
516 46,193,255,15,134,244,9,255,15,135,244,9,255,15,130,244,9,255,15,131,244,
517 9,255,252,233,244,6,255,219,4,202,252,233,244,248,255,129,124,253,202,4,239,
518 15,131,244,44,129,124,253,194,4,239,15,131,244,44,255,248,1,252,242,15,16,
519 4,194,248,2,131,198,4,102,15,46,4,202,248,3,255,248,1,221,4,202,248,2,221,
520 4,194,248,3,131,198,4,255,223,252,233,221,216,255,218,252,233,223,224,158,
521 255,15,135,244,247,255,15,130,244,247,255,15,131,244,247,255,15,183,70,252,
522 254,141,180,253,134,233,248,1,139,6,15,182,204,15,182,232,131,198,4,193,232,
523 16,252,255,36,252,235,255,139,108,194,4,131,198,4,255,129,252,253,239,15,
524 133,244,253,129,124,253,202,4,239,15,133,244,254,139,44,194,59,44,202,255,
525 15,133,244,255,255,15,132,244,255,255,15,183,70,252,254,141,180,253,134,233,
526 248,9,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,
527 248,7,15,135,244,251,129,124,253,202,4,239,15,130,244,247,15,133,244,251,
528 255,252,242,15,42,4,202,255,219,4,202,255,252,233,244,248,248,8,15,135,244,
529 251,255,252,242,15,42,4,194,102,15,46,4,202,255,219,4,194,221,4,202,255,252,
530 233,244,250,255,129,252,253,239,15,131,244,251,129,124,253,202,4,239,15,131,
531 244,251,255,248,1,252,242,15,16,4,202,248,2,102,15,46,4,194,248,4,255,248,
532 1,221,4,202,248,2,221,4,194,248,4,255,15,138,244,248,15,133,244,248,255,15,
533 138,244,248,15,132,244,247,255,248,1,15,183,70,252,254,141,180,253,134,233,
534 248,2,255,248,2,15,183,70,252,254,141,180,253,134,233,248,1,255,252,233,244,
535 9,255,129,252,253,239,15,132,244,49,129,124,253,202,4,239,15,132,244,49,255,
536 57,108,202,4,15,133,244,2,129,252,253,239,15,131,244,1,139,12,202,139,4,194,
537 57,193,15,132,244,1,129,252,253,239,15,135,244,2,129,252,253,239,15,130,244,
538 2,139,169,233,133,252,237,15,132,244,2,252,246,133,233,235,15,133,244,2,255,
539 49,252,237,255,189,1,0,0,0,255,252,233,244,48,255,248,3,129,252,253,239,255,
540 15,133,244,9,255,252,233,244,49,255,72,252,247,208,139,108,202,4,131,198,
541 4,129,252,253,239,15,133,244,249,139,12,202,59,12,135,255,139,108,202,4,131,
542 198,4,255,129,252,253,239,15,133,244,253,129,124,253,199,4,239,15,133,244,
543 254,139,44,199,59,44,202,255,15,183,70,252,254,141,180,253,134,233,248,9,
544 139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,7,
545 15,135,244,249,129,124,253,199,4,239,15,130,244,247,255,252,242,15,42,4,199,
546 255,219,4,199,255,252,233,244,248,248,8,255,252,242,15,42,4,202,102,15,46,
547 4,199,255,219,4,202,221,4,199,255,129,252,253,239,15,131,244,249,255,248,
548 1,252,242,15,16,4,199,248,2,102,15,46,4,202,248,4,255,248,1,221,4,199,248,
549 2,221,4,202,248,4,255,72,252,247,208,139,108,202,4,131,198,4,57,197,255,15,
550 133,244,249,15,183,70,252,254,141,180,253,134,233,248,2,139,6,15,182,204,
551 15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,3,129,252,253,239,
552 15,133,244,2,252,233,244,49,255,15,132,244,248,129,252,253,239,15,132,244,
553 49,15,183,70,252,254,141,180,253,134,233,248,2,139,6,15,182,204,15,182,232,
554 131,198,4,193,232,16,252,255,36,252,235,255,139,108,194,4,131,198,4,129,252,
555 253,239,255,137,108,202,4,139,44,194,137,44,202,255,72,139,44,194,72,137,
556 44,202,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,
557 255,49,252,237,129,124,253,194,4,239,129,213,239,137,108,202,4,139,6,15,182,
558 204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,255,129,124,253,194,
559 4,239,15,133,244,251,139,44,194,252,247,221,15,128,244,250,199,68,202,4,237,
560 137,44,202,248,9,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,
561 36,252,235,248,4,199,68,202,4,0,0,224,65,199,4,202,0,0,0,0,252,233,244,9,
562 248,5,15,135,244,54,255,129,124,253,194,4,239,15,131,244,54,255,252,242,15,
563 16,4,194,72,184,237,237,102,72,15,110,200,15,87,193,252,242,15,17,4,202,255,
564 221,4,194,217,224,221,28,202,255,129,124,253,194,4,239,15,133,244,248,139,
565 4,194,255,139,128,233,248,1,199,68,202,4,237,137,4,202,255,15,87,192,252,
566 242,15,42,128,233,248,1,252,242,15,17,4,202,255,219,128,233,248,1,221,28,
567 202,255,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,
568 248,2,129,124,253,194,4,239,15,133,244,57,139,12,194,255,139,169,233,131,
569 252,253,0,15,133,244,255,248,3,255,248,58,137,213,232,251,1,20,255,252,242,
570 15,42,192,255,137,252,234,15,182,78,252,253,252,233,244,1,255,248,9,252,246,
571 133,233,235,15,133,244,3,252,233,244,57,255,15,182,252,236,15,182,192,255,
572 129,124,253,252,234,4,239,15,133,244,51,129,124,253,199,4,239,15,133,244,
573 51,139,44,252,234,3,44,199,15,128,244,50,255,129,124,253,252,234,4,239,15,
574 133,244,53,129,124,253,199,4,239,15,133,244,53,139,4,199,3,4,252,234,15,128,
575 244,52,255,129,124,253,252,234,4,239,15,133,244,56,129,124,253,194,4,239,
576 15,133,244,56,139,44,252,234,3,44,194,15,128,244,55,255,199,68,202,4,237,
577 255,129,124,253,252,234,4,239,15,131,244,51,255,129,124,253,199,4,239,15,
578 131,244,51,255,252,242,15,16,4,252,234,252,242,15,88,4,199,255,221,4,252,
579 234,220,4,199,255,129,124,253,252,234,4,239,15,131,244,53,255,129,124,253,
580 199,4,239,15,131,244,53,255,252,242,15,16,4,199,252,242,15,88,4,252,234,255,
581 221,4,199,220,4,252,234,255,129,124,253,252,234,4,239,15,131,244,56,129,124,
582 253,194,4,239,15,131,244,56,255,252,242,15,16,4,252,234,252,242,15,88,4,194,
583 255,221,4,252,234,220,4,194,255,129,124,253,252,234,4,239,15,133,244,51,129,
584 124,253,199,4,239,15,133,244,51,139,44,252,234,43,44,199,15,128,244,50,255,
585 129,124,253,252,234,4,239,15,133,244,53,129,124,253,199,4,239,15,133,244,
586 53,139,4,199,43,4,252,234,15,128,244,52,255,129,124,253,252,234,4,239,15,
587 133,244,56,129,124,253,194,4,239,15,133,244,56,139,44,252,234,43,44,194,15,
588 128,244,55,255,252,242,15,16,4,252,234,252,242,15,92,4,199,255,221,4,252,
589 234,220,36,199,255,252,242,15,16,4,199,252,242,15,92,4,252,234,255,221,4,
590 199,220,36,252,234,255,252,242,15,16,4,252,234,252,242,15,92,4,194,255,221,
591 4,252,234,220,36,194,255,129,124,253,252,234,4,239,15,133,244,51,129,124,
592 253,199,4,239,15,133,244,51,139,44,252,234,15,175,44,199,15,128,244,50,255,
593 129,124,253,252,234,4,239,15,133,244,53,129,124,253,199,4,239,15,133,244,
594 53,139,4,199,15,175,4,252,234,15,128,244,52,255,129,124,253,252,234,4,239,
595 15,133,244,56,129,124,253,194,4,239,15,133,244,56,139,44,252,234,15,175,44,
596 194,15,128,244,55,255,252,242,15,16,4,252,234,252,242,15,89,4,199,255,221,
597 4,252,234,220,12,199,255,252,242,15,16,4,199,252,242,15,89,4,252,234,255,
598 221,4,199,220,12,252,234,255,252,242,15,16,4,252,234,252,242,15,89,4,194,
599 255,221,4,252,234,220,12,194,255,252,242,15,16,4,252,234,252,242,15,94,4,
600 199,255,221,4,252,234,220,52,199,255,252,242,15,16,4,199,252,242,15,94,4,
601 252,234,255,221,4,199,220,52,252,234,255,252,242,15,16,4,252,234,252,242,
602 15,94,4,194,255,221,4,252,234,220,52,194,255,252,242,15,16,4,252,234,252,
603 242,15,16,12,199,255,221,4,252,234,221,4,199,255,252,242,15,16,4,199,252,
604 242,15,16,12,252,234,255,221,4,199,221,4,252,234,255,252,242,15,16,4,252,
605 234,252,242,15,16,12,194,255,221,4,252,234,221,4,194,255,248,168,232,244,
606 157,255,252,233,244,168,255,232,244,117,255,15,182,252,236,15,182,192,139,
607 76,36,96,137,145,233,141,20,194,65,137,192,65,41,232,248,36,137,205,137,116,
608 36,100,232,251,1,29,139,149,233,133,192,15,133,244,45,15,182,110,252,255,
609 15,182,78,252,253,72,139,4,252,234,72,137,4,202,139,6,15,182,204,15,182,232,
610 131,198,4,193,232,16,252,255,36,252,235,255,72,252,247,208,139,4,135,199,
611 68,202,4,237,137,4,202,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,
612 255,36,252,235,255,15,191,192,199,68,202,4,237,137,4,202,255,15,191,192,252,
613 242,15,42,192,252,242,15,17,4,202,255,223,70,252,254,221,28,202,255,252,242,
614 15,16,4,199,252,242,15,17,4,202,255,221,4,199,221,28,202,255,72,252,247,208,
615 137,68,202,4,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,
616 252,235,255,141,76,202,12,141,68,194,4,189,237,137,105,252,248,248,1,137,
617 41,131,193,8,57,193,15,134,244,1,139,6,15,182,204,15,182,232,131,198,4,193,
618 232,16,252,255,36,252,235,255,139,106,252,248,139,172,253,133,233,139,173,
619 233,72,139,69,0,72,137,4,202,139,6,15,182,204,15,182,232,131,198,4,193,232,
620 16,252,255,36,252,235,255,139,106,252,248,139,172,253,141,233,128,189,233,
621 0,139,173,233,139,12,194,139,68,194,4,137,77,0,137,69,4,15,132,244,247,252,
622 246,133,233,235,15,133,244,248,248,1,139,6,15,182,204,15,182,232,131,198,
623 4,193,232,16,252,255,36,252,235,248,2,129,232,239,129,252,248,239,15,134,
624 244,1,252,246,129,233,235,15,132,244,1,135,213,141,139,233,255,232,251,1,
625 30,137,252,234,252,233,244,1,255,72,252,247,208,139,106,252,248,139,172,253,
626 141,233,139,12,135,139,133,233,137,8,199,64,4,237,252,246,133,233,235,15,
627 133,244,248,248,1,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,
628 36,252,235,248,2,252,246,129,233,235,15,132,244,1,128,189,233,0,15,132,244,
629 1,137,213,137,194,141,139,233,232,251,1,30,137,252,234,252,233,244,1,255,
630 139,106,252,248,255,252,242,15,16,4,199,255,139,172,253,141,233,139,141,233,
631 255,252,242,15,17,1,255,221,25,255,72,252,247,208,139,106,252,248,139,172,
632 253,141,233,139,141,233,137,65,4,139,6,15,182,204,15,182,232,131,198,4,193,
633 232,16,252,255,36,252,235,255,141,180,253,134,233,139,108,36,96,131,189,233,
634 0,15,132,244,247,137,149,233,141,20,202,137,252,233,232,251,1,31,139,149,
635 233,248,1,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,
636 235,255,72,252,247,208,139,108,36,96,137,149,233,68,139,66,252,248,139,20,
637 135,137,252,233,137,116,36,100,232,251,1,32,139,149,233,15,182,78,252,253,
638 137,4,202,199,68,202,4,237,139,6,15,182,204,15,182,232,131,198,4,193,232,
639 16,252,255,36,252,235,255,139,108,36,96,137,149,233,139,139,233,59,139,233,
640 137,116,36,100,15,131,244,251,248,1,65,137,192,37,252,255,7,0,0,65,193,232,
641 11,61,252,255,7,0,0,15,132,244,249,248,2,137,252,233,137,194,232,251,1,33,
642 139,149,233,15,182,78,252,253,137,4,202,199,68,202,4,237,139,6,15,182,204,
643 15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,3,184,1,8,0,0,252,
644 233,244,2,248,5,137,252,233,232,251,1,34,15,183,70,252,254,252,233,244,1,
645 255,72,252,247,208,139,108,36,96,139,139,233,137,116,36,100,59,139,233,137,
646 149,233,15,131,244,249,248,2,139,20,135,137,252,233,232,251,1,35,139,149,
647 233,15,182,78,252,253,137,4,202,199,68,202,4,237,139,6,15,182,204,15,182,
648 232,131,198,4,193,232,16,252,255,36,252,235,248,3,137,252,233,232,251,1,34,
649 15,183,70,252,254,72,252,247,208,252,233,244,2,255,72,252,247,208,139,106,
650 252,248,139,173,233,139,4,135,252,233,244,169,255,72,252,247,208,139,106,
651 252,248,139,173,233,139,4,135,252,233,244,170,255,15,182,252,236,15,182,192,
652 129,124,253,252,234,4,239,15,133,244,39,139,44,252,234,255,129,124,253,194,
653 4,239,15,133,244,251,139,4,194,255,129,124,253,194,4,239,15,131,244,251,255,
654 252,242,15,16,4,194,252,242,15,45,192,252,242,15,42,200,102,15,46,193,255,
655 15,133,244,39,255,59,133,233,15,131,244,39,193,224,3,3,133,233,129,120,253,
656 4,239,15,132,244,248,72,139,40,72,137,44,202,248,1,139,6,15,182,204,15,182,
657 232,131,198,4,193,232,16,252,255,36,252,235,248,2,131,189,233,0,15,132,244,
658 249,139,141,233,252,246,129,233,235,15,132,244,39,15,182,78,252,253,248,3,
659 199,68,202,4,237,252,233,244,1,248,5,255,129,124,253,194,4,239,15,133,244,
660 39,139,4,194,252,233,244,169,255,15,182,252,236,15,182,192,72,252,247,208,
661 139,4,135,129,124,253,252,234,4,239,15,133,244,37,139,44,252,234,248,169,
662 139,141,233,35,136,233,105,201,239,3,141,233,248,1,129,185,233,239,15,133,
663 244,250,57,129,233,15,133,244,250,129,121,253,4,239,15,132,244,251,15,182,
664 70,252,253,72,139,41,72,137,44,194,248,2,255,139,6,15,182,204,15,182,232,
665 131,198,4,193,232,16,252,255,36,252,235,248,3,15,182,70,252,253,199,68,194,
666 4,237,252,233,244,2,248,4,139,137,233,133,201,15,133,244,1,248,5,139,141,
667 233,133,201,15,132,244,3,252,246,129,233,235,15,133,244,3,252,233,244,37,
668 255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,38,139,
669 44,252,234,59,133,233,15,131,244,38,193,224,3,3,133,233,129,120,253,4,239,
670 15,132,244,248,72,139,40,72,137,44,202,248,1,139,6,15,182,204,15,182,232,
671 131,198,4,193,232,16,252,255,36,252,235,248,2,131,189,233,0,15,132,244,249,
672 139,141,233,252,246,129,233,235,15,132,244,38,255,15,182,78,252,253,248,3,
673 199,68,202,4,237,252,233,244,1,255,15,182,252,236,15,182,192,129,124,253,
674 252,234,4,239,15,133,244,42,139,44,252,234,255,15,133,244,42,255,59,133,233,
675 15,131,244,42,193,224,3,3,133,233,129,120,253,4,239,15,132,244,249,248,1,
676 252,246,133,233,235,15,133,244,253,248,2,72,139,44,202,72,137,40,139,6,15,
677 182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,3,131,189,
678 233,0,15,132,244,1,139,141,233,252,246,129,233,235,255,15,132,244,42,15,182,
679 78,252,253,252,233,244,1,248,5,129,124,253,194,4,239,15,133,244,42,139,4,
680 194,252,233,244,170,248,7,128,165,233,235,139,139,233,137,171,233,137,141,
681 233,15,182,78,252,253,252,233,244,2,255,15,182,252,236,15,182,192,72,252,
682 247,208,139,4,135,129,124,253,252,234,4,239,15,133,244,40,139,44,252,234,
683 248,170,139,141,233,35,136,233,105,201,239,198,133,233,0,3,141,233,248,1,
684 129,185,233,239,15,133,244,251,57,129,233,15,133,244,251,129,121,253,4,239,
685 15,132,244,250,248,2,255,252,246,133,233,235,15,133,244,253,248,3,15,182,
686 70,252,253,72,139,44,194,72,137,41,139,6,15,182,204,15,182,232,131,198,4,
687 193,232,16,252,255,36,252,235,248,4,131,189,233,0,15,132,244,2,137,76,36,
688 80,139,141,233,252,246,129,233,235,15,132,244,40,139,76,36,80,252,233,244,
689 2,248,5,139,137,233,133,201,15,133,244,1,255,139,141,233,133,201,15,132,244,
690 252,252,246,129,233,235,15,132,244,40,248,6,137,68,36,80,199,68,36,84,237,
691 137,108,36,32,139,76,36,96,137,145,233,76,141,68,36,80,137,252,234,137,205,
692 137,116,36,100,232,251,1,36,139,149,233,139,108,36,32,137,193,252,233,244,
693 2,248,7,128,165,233,235,139,131,233,137,171,233,137,133,233,252,233,244,3,
694 255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,41,139,
695 44,252,234,59,133,233,15,131,244,41,193,224,3,3,133,233,129,120,253,4,239,
696 15,132,244,249,248,1,252,246,133,233,235,15,133,244,253,248,2,72,139,12,202,
697 72,137,8,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,
698 235,248,3,131,189,233,0,15,132,244,1,255,139,141,233,252,246,129,233,235,
699 15,132,244,41,15,182,78,252,253,252,233,244,1,248,7,128,165,233,235,139,139,
700 233,137,171,233,137,141,233,15,182,78,252,253,252,233,244,2,255,137,124,36,
701 80,139,60,199,248,1,141,12,202,139,105,252,248,252,246,133,233,235,15,133,
702 244,253,248,2,139,68,36,84,131,232,1,15,132,244,250,1,252,248,59,133,233,
703 15,135,244,251,41,252,248,193,231,3,3,189,233,248,3,72,139,41,131,193,8,72,
704 137,47,131,199,8,131,232,1,15,133,244,3,248,4,139,124,36,80,139,6,15,182,
705 204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,5,139,76,36,96,
706 137,145,233,137,252,234,65,137,192,137,205,137,116,36,100,232,251,1,37,139,
707 149,233,15,182,78,252,253,252,233,244,1,248,7,255,128,165,233,235,139,131,
708 233,137,171,233,137,133,233,252,233,244,2,255,3,68,36,84,255,129,124,253,
709 202,4,239,139,44,202,15,133,244,59,141,84,202,8,137,114,252,252,139,181,233,
710 139,14,15,182,252,233,15,182,205,131,198,4,252,255,36,252,235,255,141,76,
711 202,8,137,215,139,105,252,248,129,121,253,252,252,239,15,133,244,29,248,60,
712 139,114,252,252,252,247,198,237,15,133,244,253,248,1,137,106,252,248,137,
713 68,36,84,131,232,1,15,132,244,249,248,2,72,139,41,131,193,8,72,137,47,131,
714 199,8,131,232,1,15,133,244,2,139,106,252,248,248,3,139,68,36,84,128,189,233,
715 1,15,135,244,251,248,4,139,181,233,139,14,15,182,252,233,15,182,205,131,198,
716 4,252,255,36,252,235,248,5,255,252,247,198,237,15,133,244,4,15,182,78,252,
717 253,72,252,247,209,141,12,202,139,121,252,248,139,191,233,139,191,233,252,
718 233,244,4,248,7,129,252,238,239,252,247,198,237,15,133,244,254,41,252,242,
719 137,215,139,114,252,252,252,233,244,1,248,8,129,198,239,252,233,244,1,255,
720 141,76,202,8,72,139,105,232,72,139,65,252,240,72,137,41,72,137,65,8,139,105,
721 224,139,65,228,137,105,252,248,137,65,252,252,129,252,248,239,184,237,15,
722 133,244,29,137,202,137,114,252,252,139,181,233,139,14,15,182,252,233,15,182,
723 205,131,198,4,252,255,36,252,235,255,137,124,36,80,137,92,36,84,139,108,202,
724 252,240,139,68,202,252,248,139,157,233,131,198,4,139,189,233,248,1,57,216,
725 15,131,244,251,129,124,253,199,4,239,15,132,244,250,255,219,68,202,252,248,
726 255,72,139,44,199,72,137,108,202,8,131,192,1,255,137,68,202,252,248,248,2,
727 15,183,70,252,254,141,180,253,134,233,248,3,139,92,36,84,139,124,36,80,139,
728 6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,4,131,
729 192,1,255,137,68,202,252,248,255,252,233,244,1,248,5,41,216,248,6,59,133,
730 233,15,135,244,3,105,252,248,239,3,189,233,129,191,233,239,15,132,244,253,
731 141,92,24,1,72,139,175,233,72,139,135,233,72,137,44,202,72,137,68,202,8,137,
732 92,202,252,248,252,233,244,2,248,7,131,192,1,252,233,244,6,255,129,124,253,
733 202,252,236,239,15,133,244,251,139,108,202,232,129,124,253,202,252,244,239,
734 15,133,244,251,129,124,253,202,252,252,239,15,133,244,251,128,189,233,235,
735 15,133,244,251,141,180,253,134,233,199,68,202,252,248,0,0,0,0,248,1,139,6,
736 15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,248,5,198,70,
737 252,252,235,141,180,253,134,233,198,6,235,252,233,244,1,255,15,182,252,236,
738 15,182,192,137,124,36,80,141,188,253,194,233,141,12,202,43,122,252,252,133,
739 252,237,15,132,244,251,141,108,252,233,252,248,57,215,15,131,244,248,248,
740 1,72,139,71,252,248,131,199,8,72,137,1,131,193,8,57,252,233,15,131,244,249,
741 57,215,15,130,244,1,248,2,199,65,4,237,131,193,8,57,252,233,15,130,244,2,
742 248,3,139,124,36,80,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,
743 255,36,252,235,248,5,199,68,36,84,1,0,0,0,137,208,41,252,248,15,134,244,3,
744 137,197,193,252,237,3,131,197,1,137,108,36,84,139,108,36,96,1,200,59,133,
745 233,15,135,244,253,248,6,255,72,139,71,252,248,131,199,8,72,137,1,131,193,
746 8,57,215,15,130,244,6,252,233,244,3,248,7,137,149,233,137,141,233,137,116,
747 36,100,41,215,139,84,36,84,131,252,234,1,137,252,233,232,251,1,0,139,149,
748 233,139,141,233,1,215,252,233,244,6,255,193,225,3,255,248,1,139,114,252,252,
749 137,68,36,84,252,247,198,237,15,133,244,253,255,248,13,137,215,131,232,1,
750 15,132,244,249,248,2,72,139,44,15,72,137,111,252,248,131,199,8,131,232,1,
751 15,133,244,2,248,3,139,68,36,84,15,182,110,252,255,248,5,57,197,15,135,244,
752 252,255,72,139,44,10,72,137,106,252,248,255,248,5,56,70,252,255,15,135,244,
753 252,255,15,182,78,252,253,72,252,247,209,141,20,202,139,122,252,248,139,191,
754 233,139,191,233,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,
755 36,252,235,248,6,255,199,71,252,252,237,131,199,8,255,199,68,194,252,244,
756 237,255,131,192,1,252,233,244,5,248,7,141,174,233,252,247,197,237,15,133,
757 244,14,41,252,234,255,1,252,233,255,137,252,245,209,252,237,129,229,239,102,
758 129,172,253,43,233,238,15,130,244,149,255,141,12,202,255,129,121,253,4,239,
759 15,133,244,255,255,129,121,253,12,239,15,133,244,61,129,121,253,20,239,15,
760 133,244,61,139,41,131,121,16,0,15,140,244,251,255,129,121,253,12,239,15,133,
761 244,165,129,121,253,20,239,15,133,244,165,255,139,105,16,133,252,237,15,136,
762 244,251,3,41,15,128,244,247,137,41,255,59,105,8,199,65,28,237,137,105,24,
763 255,15,142,244,253,248,1,248,6,141,180,253,134,233,255,141,180,253,134,233,
764 15,183,70,252,254,15,142,245,248,1,248,6,255,15,143,244,253,248,6,141,180,
765 253,134,233,248,1,255,248,7,139,6,15,182,204,15,182,232,131,198,4,193,232,
766 16,252,255,36,252,235,248,5,255,3,41,15,128,244,1,137,41,255,15,141,244,7,
767 255,141,180,253,134,233,15,183,70,252,254,15,141,245,255,15,140,244,7,255,
768 252,233,244,6,248,9,255,129,121,253,4,239,255,15,131,244,61,129,121,253,12,
769 239,15,131,244,61,255,129,121,253,12,239,15,131,244,165,129,121,253,20,239,
770 15,131,244,165,255,139,105,20,255,129,252,253,239,15,131,244,61,255,252,242,
771 15,16,1,252,242,15,16,73,8,255,252,242,15,88,65,16,252,242,15,17,1,133,252,
772 237,15,136,244,249,255,15,140,244,249,255,102,15,46,200,248,1,252,242,15,
773 17,65,24,255,221,65,8,221,1,255,220,65,16,221,17,221,81,24,133,252,237,15,
774 136,244,247,255,221,81,24,15,140,244,247,255,217,201,248,1,255,15,183,70,
775 252,254,255,15,131,244,7,255,15,131,244,248,141,180,253,134,233,255,141,180,
776 253,134,233,15,183,70,252,254,15,131,245,255,15,130,244,7,255,15,130,244,
777 248,141,180,253,134,233,255,248,3,102,15,46,193,252,233,244,1,255,141,12,
778 202,139,105,4,129,252,253,239,15,132,244,247,255,137,105,252,252,139,41,137,
779 105,252,248,252,233,245,255,141,180,253,134,233,139,1,137,105,252,252,137,
780 65,252,248,255,139,139,233,139,4,129,72,139,128,233,139,108,36,96,137,147,
781 233,137,171,233,76,137,100,36,80,76,137,108,36,32,76,137,116,36,24,76,137,
782 124,36,16,72,137,225,72,129,252,236,239,102,15,127,49,102,15,127,185,233,
783 102,68,15,127,129,233,102,68,15,127,137,233,102,68,15,127,145,233,102,68,
784 15,127,153,233,102,68,15,127,161,233,102,68,15,127,169,233,102,68,15,127,
785 177,233,102,68,15,127,185,233,252,255,224,255,141,180,253,134,233,139,6,15,
786 182,204,15,182,232,131,198,4,193,232,16,252,255,36,252,235,255,137,252,245,
787 209,252,237,129,229,239,102,129,172,253,43,233,238,15,130,244,151,255,139,
788 190,233,139,108,36,96,141,12,202,59,141,233,15,135,244,24,15,182,142,233,
789 57,200,15,134,244,249,248,2,255,15,183,70,252,254,252,233,245,255,248,3,199,
790 68,194,252,252,237,131,192,1,57,200,15,134,244,3,252,233,244,2,255,141,44,
791 197,237,141,4,194,139,122,252,248,137,104,252,252,137,120,252,248,139,108,
792 36,96,141,12,200,59,141,233,15,135,244,23,137,209,137,194,15,182,174,233,
793 133,252,237,15,132,244,248,248,1,131,193,8,57,209,15,131,244,249,139,121,
794 252,248,137,56,139,121,252,252,137,120,4,131,192,8,199,65,252,252,237,131,
795 252,237,1,15,133,244,1,248,2,255,139,190,233,139,6,15,182,204,15,182,232,
796 131,198,4,193,232,16,252,255,36,252,235,255,248,3,199,64,4,237,131,192,8,
797 131,252,237,1,15,133,244,3,252,233,244,2,255,139,106,252,248,72,139,189,233,
798 139,108,36,96,141,68,194,252,248,137,149,233,141,136,233,59,141,233,137,133,
799 233,255,72,137,252,250,137,252,233,255,15,135,244,22,199,131,233,237,255,
800 252,255,215,255,252,255,147,233,255,199,131,233,237,139,149,233,141,12,194,
801 252,247,217,3,141,233,139,114,252,252,252,233,244,12,255,254,0
802};
803
804enum {
805 GLOB_vm_returnp,
806 GLOB_cont_dispatch,
807 GLOB_vm_returnc,
808 GLOB_BC_RET_Z,
809 GLOB_vm_return,
810 GLOB_vm_leave_cp,
811 GLOB_vm_leave_unw,
812 GLOB_vm_unwind_c,
813 GLOB_vm_unwind_c_eh,
814 GLOB_vm_unwind_rethrow,
815 GLOB_vm_unwind_ff,
816 GLOB_vm_unwind_ff_eh,
817 GLOB_vm_growstack_c,
818 GLOB_vm_growstack_v,
819 GLOB_vm_growstack_f,
820 GLOB_vm_resume,
821 GLOB_vm_pcall,
822 GLOB_vm_call,
823 GLOB_vm_call_dispatch,
824 GLOB_vmeta_call,
825 GLOB_vm_call_dispatch_f,
826 GLOB_vm_cpcall,
827 GLOB_cont_ffi_callback,
828 GLOB_vm_call_tail,
829 GLOB_cont_cat,
830 GLOB_cont_ra,
831 GLOB_BC_CAT_Z,
832 GLOB_vmeta_tgets,
833 GLOB_vmeta_tgetb,
834 GLOB_vmeta_tgetv,
835 GLOB_vmeta_tsets,
836 GLOB_vmeta_tsetb,
837 GLOB_vmeta_tsetv,
838 GLOB_cont_nop,
839 GLOB_vmeta_comp,
840 GLOB_vmeta_binop,
841 GLOB_cont_condt,
842 GLOB_cont_condf,
843 GLOB_vmeta_equal,
844 GLOB_vmeta_equal_cd,
845 GLOB_vmeta_arith_vno,
846 GLOB_vmeta_arith_vn,
847 GLOB_vmeta_arith_nvo,
848 GLOB_vmeta_arith_nv,
849 GLOB_vmeta_unm,
850 GLOB_vmeta_arith_vvo,
851 GLOB_vmeta_arith_vv,
852 GLOB_vmeta_len,
853 GLOB_BC_LEN_Z,
854 GLOB_vmeta_call_ra,
855 GLOB_BC_CALLT_Z,
856 GLOB_vmeta_for,
857 GLOB_ff_assert,
858 GLOB_fff_fallback,
859 GLOB_fff_res_,
860 GLOB_ff_type,
861 GLOB_fff_res1,
862 GLOB_ff_getmetatable,
863 GLOB_ff_setmetatable,
864 GLOB_ff_rawget,
865 GLOB_ff_tonumber,
866 GLOB_fff_resi,
867 GLOB_fff_resxmm0,
868 GLOB_fff_resn,
869 GLOB_ff_tostring,
870 GLOB_fff_gcstep,
871 GLOB_ff_next,
872 GLOB_fff_res2,
873 GLOB_fff_res,
874 GLOB_ff_pairs,
875 GLOB_ff_ipairs_aux,
876 GLOB_fff_res0,
877 GLOB_ff_ipairs,
878 GLOB_ff_pcall,
879 GLOB_ff_xpcall,
880 GLOB_ff_coroutine_resume,
881 GLOB_ff_coroutine_wrap_aux,
882 GLOB_ff_coroutine_yield,
883 GLOB_ff_math_abs,
884 GLOB_fff_resbit,
885 GLOB_ff_math_floor,
886 GLOB_vm_floor,
887 GLOB_ff_math_ceil,
888 GLOB_vm_ceil,
889 GLOB_ff_math_sqrt,
890 GLOB_ff_math_log,
891 GLOB_ff_math_log10,
892 GLOB_ff_math_exp,
893 GLOB_vm_exp_x87,
894 GLOB_ff_math_sin,
895 GLOB_ff_math_cos,
896 GLOB_ff_math_tan,
897 GLOB_ff_math_asin,
898 GLOB_ff_math_acos,
899 GLOB_ff_math_atan,
900 GLOB_ff_math_sinh,
901 GLOB_ff_math_cosh,
902 GLOB_ff_math_tanh,
903 GLOB_ff_math_deg,
904 GLOB_ff_math_rad,
905 GLOB_ff_math_atan2,
906 GLOB_ff_math_ldexp,
907 GLOB_ff_math_frexp,
908 GLOB_ff_math_modf,
909 GLOB_vm_trunc,
910 GLOB_ff_math_fmod,
911 GLOB_ff_math_pow,
912 GLOB_vm_pow,
913 GLOB_ff_math_min,
914 GLOB_ff_math_max,
915 GLOB_ff_string_len,
916 GLOB_ff_string_byte,
917 GLOB_ff_string_char,
918 GLOB_fff_newstr,
919 GLOB_ff_string_sub,
920 GLOB_fff_emptystr,
921 GLOB_ff_string_rep,
922 GLOB_fff_fallback_2,
923 GLOB_ff_string_reverse,
924 GLOB_fff_fallback_1,
925 GLOB_ff_string_lower,
926 GLOB_ff_string_upper,
927 GLOB_ff_table_getn,
928 GLOB_ff_bit_tobit,
929 GLOB_ff_bit_band,
930 GLOB_fff_fallback_bit_op,
931 GLOB_ff_bit_bor,
932 GLOB_ff_bit_bxor,
933 GLOB_ff_bit_bswap,
934 GLOB_ff_bit_bnot,
935 GLOB_ff_bit_lshift,
936 GLOB_ff_bit_rshift,
937 GLOB_ff_bit_arshift,
938 GLOB_ff_bit_rol,
939 GLOB_ff_bit_ror,
940 GLOB_vm_record,
941 GLOB_vm_rethook,
942 GLOB_vm_inshook,
943 GLOB_cont_hook,
944 GLOB_vm_hotloop,
945 GLOB_vm_callhook,
946 GLOB_vm_hotcall,
947 GLOB_vm_exit_handler,
948 GLOB_vm_exit_interp,
949 GLOB_vm_floor_sse,
950 GLOB_vm_ceil_sse,
951 GLOB_vm_trunc_sse,
952 GLOB_vm_mod,
953 GLOB_vm_exp2_x87,
954 GLOB_vm_exp2raw,
955 GLOB_vm_pow_sse,
956 GLOB_vm_powi_sse,
957 GLOB_vm_foldfpm,
958 GLOB_vm_foldarith,
959 GLOB_vm_cpuid,
960 GLOB_assert_bad_for_arg_type,
961 GLOB_vm_ffi_callback,
962 GLOB_vm_ffi_call,
963 GLOB_BC_MODVN_Z,
964 GLOB_BC_TGETS_Z,
965 GLOB_BC_TSETS_Z,
966 GLOB__MAX
967};
968static const char *const globnames[] = {
969 "vm_returnp",
970 "cont_dispatch",
971 "vm_returnc",
972 "BC_RET_Z",
973 "vm_return",
974 "vm_leave_cp",
975 "vm_leave_unw",
976 "vm_unwind_c@8",
977 "vm_unwind_c_eh",
978 "vm_unwind_rethrow",
979 "vm_unwind_ff@4",
980 "vm_unwind_ff_eh",
981 "vm_growstack_c",
982 "vm_growstack_v",
983 "vm_growstack_f",
984 "vm_resume",
985 "vm_pcall",
986 "vm_call",
987 "vm_call_dispatch",
988 "vmeta_call",
989 "vm_call_dispatch_f",
990 "vm_cpcall",
991 "cont_ffi_callback",
992 "vm_call_tail",
993 "cont_cat",
994 "cont_ra",
995 "BC_CAT_Z",
996 "vmeta_tgets",
997 "vmeta_tgetb",
998 "vmeta_tgetv",
999 "vmeta_tsets",
1000 "vmeta_tsetb",
1001 "vmeta_tsetv",
1002 "cont_nop",
1003 "vmeta_comp",
1004 "vmeta_binop",
1005 "cont_condt",
1006 "cont_condf",
1007 "vmeta_equal",
1008 "vmeta_equal_cd",
1009 "vmeta_arith_vno",
1010 "vmeta_arith_vn",
1011 "vmeta_arith_nvo",
1012 "vmeta_arith_nv",
1013 "vmeta_unm",
1014 "vmeta_arith_vvo",
1015 "vmeta_arith_vv",
1016 "vmeta_len",
1017 "BC_LEN_Z",
1018 "vmeta_call_ra",
1019 "BC_CALLT_Z",
1020 "vmeta_for",
1021 "ff_assert",
1022 "fff_fallback",
1023 "fff_res_",
1024 "ff_type",
1025 "fff_res1",
1026 "ff_getmetatable",
1027 "ff_setmetatable",
1028 "ff_rawget",
1029 "ff_tonumber",
1030 "fff_resi",
1031 "fff_resxmm0",
1032 "fff_resn",
1033 "ff_tostring",
1034 "fff_gcstep",
1035 "ff_next",
1036 "fff_res2",
1037 "fff_res",
1038 "ff_pairs",
1039 "ff_ipairs_aux",
1040 "fff_res0",
1041 "ff_ipairs",
1042 "ff_pcall",
1043 "ff_xpcall",
1044 "ff_coroutine_resume",
1045 "ff_coroutine_wrap_aux",
1046 "ff_coroutine_yield",
1047 "ff_math_abs",
1048 "fff_resbit",
1049 "ff_math_floor",
1050 "vm_floor",
1051 "ff_math_ceil",
1052 "vm_ceil",
1053 "ff_math_sqrt",
1054 "ff_math_log",
1055 "ff_math_log10",
1056 "ff_math_exp",
1057 "vm_exp_x87",
1058 "ff_math_sin",
1059 "ff_math_cos",
1060 "ff_math_tan",
1061 "ff_math_asin",
1062 "ff_math_acos",
1063 "ff_math_atan",
1064 "ff_math_sinh",
1065 "ff_math_cosh",
1066 "ff_math_tanh",
1067 "ff_math_deg",
1068 "ff_math_rad",
1069 "ff_math_atan2",
1070 "ff_math_ldexp",
1071 "ff_math_frexp",
1072 "ff_math_modf",
1073 "vm_trunc",
1074 "ff_math_fmod",
1075 "ff_math_pow",
1076 "vm_pow",
1077 "ff_math_min",
1078 "ff_math_max",
1079 "ff_string_len",
1080 "ff_string_byte",
1081 "ff_string_char",
1082 "fff_newstr",
1083 "ff_string_sub",
1084 "fff_emptystr",
1085 "ff_string_rep",
1086 "fff_fallback_2",
1087 "ff_string_reverse",
1088 "fff_fallback_1",
1089 "ff_string_lower",
1090 "ff_string_upper",
1091 "ff_table_getn",
1092 "ff_bit_tobit",
1093 "ff_bit_band",
1094 "fff_fallback_bit_op",
1095 "ff_bit_bor",
1096 "ff_bit_bxor",
1097 "ff_bit_bswap",
1098 "ff_bit_bnot",
1099 "ff_bit_lshift",
1100 "ff_bit_rshift",
1101 "ff_bit_arshift",
1102 "ff_bit_rol",
1103 "ff_bit_ror",
1104 "vm_record",
1105 "vm_rethook",
1106 "vm_inshook",
1107 "cont_hook",
1108 "vm_hotloop",
1109 "vm_callhook",
1110 "vm_hotcall",
1111 "vm_exit_handler",
1112 "vm_exit_interp",
1113 "vm_floor_sse",
1114 "vm_ceil_sse",
1115 "vm_trunc_sse",
1116 "vm_mod",
1117 "vm_exp2_x87",
1118 "vm_exp2raw",
1119 "vm_pow_sse",
1120 "vm_powi_sse",
1121 "vm_foldfpm",
1122 "vm_foldarith",
1123 "vm_cpuid",
1124 "assert_bad_for_arg_type",
1125 "vm_ffi_callback",
1126 "vm_ffi_call@4",
1127 "BC_MODVN_Z",
1128 "BC_TGETS_Z",
1129 "BC_TSETS_Z",
1130 (const char *)0
1131};
1132static const char *const extnames[] = {
1133 "lj_state_growstack@8",
1134 "lj_meta_tget",
1135 "lj_meta_tset",
1136 "lj_meta_comp",
1137 "lj_meta_equal",
1138 "lj_meta_equal_cd@8",
1139 "lj_meta_arith",
1140 "lj_meta_len@8",
1141 "lj_meta_call",
1142 "lj_meta_for@8",
1143 "lj_tab_get",
1144 "lj_str_fromnumber@8",
1145 "lj_str_fromnum@8",
1146 "lj_tab_next",
1147 "lj_tab_getinth@8",
1148 "lj_ffh_coroutine_wrap_err@8",
1149 "lj_vm_sinh",
1150 "lj_vm_cosh",
1151 "lj_vm_tanh",
1152 "lj_str_new",
1153 "lj_tab_len@4",
1154 "lj_gc_step@4",
1155 "lj_dispatch_ins@8",
1156 "lj_trace_hot@8",
1157 "lj_dispatch_call@8",
1158 "lj_trace_exit@8",
1159 "lj_err_throw@8",
1160 "lj_ccallback_enter@8",
1161 "lj_ccallback_leave@8",
1162 "lj_meta_cat",
1163 "lj_gc_barrieruv@8",
1164 "lj_func_closeuv@8",
1165 "lj_func_newL_gc",
1166 "lj_tab_new",
1167 "lj_gc_step_fixtop@4",
1168 "lj_tab_dup@8",
1169 "lj_tab_newkey",
1170 "lj_tab_reasize",
1171 (const char *)0
1172};
1173#define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V)
1174#define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V)
1175#define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V)
1176#define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V)
1177#define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V)
1178#define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V)
1179#define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V)
1180#define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V)
1181#define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V)
1182#define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V)
1183#define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V)
1184#define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V)
1185#define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V)
1186#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
1187#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
1188#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
1189
1190/* Generate subroutines used by opcodes and other parts of the VM. */
1191/* The .code_sub section should be last to help static branch prediction. */
1192static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
1193{
1194 dasm_put(Dst, 0);
1195 dasm_put(Dst, 2, FRAME_P, LJ_TTRUE, FRAME_TYPE, FRAME_C, FRAME_TYPE, DISPATCH_GL(vmstate), ~LJ_VMST_C);
1196 dasm_put(Dst, 109, Dt1(->base), Dt1(->top), Dt1(->cframe), Dt1(->maxstack), LJ_TNIL);
1197 dasm_put(Dst, 198, Dt1(->top), Dt1(->top), Dt1(->glref), Dt2(->vmstate), ~LJ_VMST_C, CFRAME_RAWMASK);
1198 dasm_put(Dst, 276, 1+1, Dt1(->base), Dt1(->glref), GG_G2DISP, LJ_TFALSE, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, LUA_MINSTACK, -4+PC2PROTO(framesize), Dt1(->base));
1199 dasm_put(Dst, 356, Dt1(->top), Dt1(->base), Dt1(->top), Dt7(->pc), FRAME_CP, CFRAME_RESUME, Dt1(->glref), GG_G2DISP, Dt1(->cframe), Dt1(->status), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->status), Dt1(->base), Dt1(->top), FRAME_TYPE);
1200 dasm_put(Dst, 511, FRAME_CP, FRAME_C, Dt1(->cframe), Dt1(->cframe), Dt1(->glref), GG_G2DISP, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base));
1201 dasm_put(Dst, 604, Dt1(->top), LJ_TFUNC, Dt7(->pc), Dt1(->stack), Dt1(->top), Dt1(->cframe), Dt1(->cframe), FRAME_CP, LJ_TNIL);
1202#if LJ_HASFFI
1203 dasm_put(Dst, 764);
1204#endif
1205 dasm_put(Dst, 773, 0);
1206#if LJ_HASFFI
1207#endif
1208 dasm_put(Dst, 782, Dt7(->pc), PC2PROTO(k));
1209#if LJ_HASFFI
1210 dasm_put(Dst, 796);
1211#endif
1212 dasm_put(Dst, 817, Dt1(->base), LJ_TSTR, BC_GGET, DISPATCH_GL(tmptv), LJ_TTAB);
1213 if (LJ_DUALNUM) {
1214 dasm_put(Dst, 917, LJ_TISNUM);
1215 } else if (sse) {
1216 dasm_put(Dst, 927);
1217 } else {
1218 }
1219 dasm_put(Dst, 940, Dt1(->base), Dt1(->base), Dt1(->top), FRAME_CONT, 2+1, LJ_TSTR, BC_GSET);
1220 dasm_put(Dst, 1087, DISPATCH_GL(tmptv), LJ_TTAB);
1221 if (LJ_DUALNUM) {
1222 dasm_put(Dst, 917, LJ_TISNUM);
1223 } else if (sse) {
1224 dasm_put(Dst, 927);
1225 } else {
1226 }
1227 dasm_put(Dst, 1110, Dt1(->base), Dt1(->base), Dt1(->top), FRAME_CONT, 3+1, Dt1(->base), Dt1(->base));
1228 dasm_put(Dst, 1283, -BCBIAS_J*4, LJ_TISTRUECOND, LJ_TISTRUECOND, Dt1(->base));
1229 dasm_put(Dst, 1383);
1230#if LJ_HASFFI
1231 dasm_put(Dst, 1403, Dt1(->base));
1232#endif
1233 dasm_put(Dst, 1434);
1234#if LJ_DUALNUM
1235 dasm_put(Dst, 1437);
1236#endif
1237 dasm_put(Dst, 1443);
1238#if LJ_DUALNUM
1239 dasm_put(Dst, 911);
1240#endif
1241 dasm_put(Dst, 1455);
1242#if LJ_DUALNUM
1243 dasm_put(Dst, 1437);
1244#endif
1245 dasm_put(Dst, 1483, Dt1(->base), Dt1(->base), FRAME_CONT, 2+1, Dt1(->base), Dt1(->base));
1246#ifdef LUAJIT_ENABLE_LUA52COMPAT
1247 dasm_put(Dst, 1589);
1248#else
1249 dasm_put(Dst, 1608);
1250#endif
1251 dasm_put(Dst, 1613, Dt1(->base), Dt1(->base), Dt7(->pc), Dt1(->base), Dt1(->base), GG_DISP2STATIC, 1+1, LJ_TISTRUECOND);
1252 dasm_put(Dst, 1799, 1+1, ~LJ_TNUMX);
1253 if (cmov) {
1254 dasm_put(Dst, 1868);
1255 } else {
1256 dasm_put(Dst, 1872);
1257 }
1258 dasm_put(Dst, 1881, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, ~LJ_TLIGHTUD, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL);
1259 dasm_put(Dst, 1960, DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable), LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next));
1260 dasm_put(Dst, 2017, LJ_TNIL, LJ_TUDATA, LJ_TNUMX, LJ_TISNUM, LJ_TLIGHTUD);
1261 dasm_put(Dst, 2083, LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT]), 2+1, LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->metatable), LJ_TTAB);
1262 dasm_put(Dst, 2153, Dt6(->marked), LJ_GC_BLACK, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist), 2+1, LJ_TTAB);
1263 dasm_put(Dst, 2242, 1+1, LJ_TISNUM);
1264 if (LJ_DUALNUM) {
1265 dasm_put(Dst, 2256);
1266 } else {
1267 dasm_put(Dst, 2273);
1268 }
1269 if (sse) {
1270 dasm_put(Dst, 2278);
1271 } else {
1272 dasm_put(Dst, 2288);
1273 }
1274 dasm_put(Dst, 2295, 1+1, LJ_TSTR, LJ_TSTR, LJ_TISNUM, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
1275 dasm_put(Dst, 2361, Dt1(->base));
1276 if (LJ_DUALNUM) {
1277 dasm_put(Dst, 2385);
1278 } else {
1279 dasm_put(Dst, 2390);
1280 }
1281 dasm_put(Dst, 2395, Dt1(->base), 1+1, LJ_TTAB, Dt1(->base), Dt1(->top), Dt1(->base), 1+2);
1282 dasm_put(Dst, 2488, LJ_TNIL, LJ_TNIL, 1+1, LJ_TTAB);
1283#ifdef LUAJIT_ENABLE_LUA52COMPAT
1284 dasm_put(Dst, 2535, Dt6(->metatable));
1285#endif
1286 dasm_put(Dst, 2544, Dt8(->upvalue[0]), LJ_TFUNC, LJ_TNIL, 1+3, 1+1, LJ_TTAB, LJ_TISNUM);
1287 if (LJ_DUALNUM) {
1288 dasm_put(Dst, 2530);
1289 } else {
1290 dasm_put(Dst, 2273);
1291 }
1292 dasm_put(Dst, 2599);
1293 if (LJ_DUALNUM) {
1294 dasm_put(Dst, 2604, LJ_TISNUM);
1295 } else if (sse) {
1296 dasm_put(Dst, 2620, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1297 } else {
1298 }
1299 dasm_put(Dst, 2653, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->hmask), 1+0);
1300 dasm_put(Dst, 2515, 1+1, LJ_TTAB);
1301#ifdef LUAJIT_ENABLE_LUA52COMPAT
1302 dasm_put(Dst, 2535, Dt6(->metatable));
1303#endif
1304 dasm_put(Dst, 2730, Dt8(->upvalue[0]), LJ_TFUNC);
1305 if (LJ_DUALNUM) {
1306 dasm_put(Dst, 2751, LJ_TISNUM);
1307 } else if (sse) {
1308 dasm_put(Dst, 2763);
1309 } else {
1310 dasm_put(Dst, 2773);
1311 }
1312 dasm_put(Dst, 2780, 1+3, 1+1, 8+FRAME_PCALL, DISPATCH_GL(hookmask), HOOK_ACTIVE_SHIFT, 2+1, LJ_TFUNC);
1313 dasm_put(Dst, 2844, LJ_TFUNC, 16+FRAME_PCALL, 1+1, LJ_TTHREAD, Dt1(->cframe), Dt1(->status), LUA_YIELD, Dt1(->top));
1314 dasm_put(Dst, 2934, Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP);
1315 dasm_put(Dst, 3022, Dt1(->base), LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack), LJ_TTRUE, FRAME_TYPE);
1316 dasm_put(Dst, 3135, LJ_TFALSE, Dt1(->top), Dt1(->top), 1+2, Dt1(->top), Dt1(->base), Dt8(->upvalue[0].gcr), Dt1(->cframe));
1317 dasm_put(Dst, 3233, Dt1(->status), LUA_YIELD, Dt1(->top), Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top));
1318 dasm_put(Dst, 3300, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack));
1319 dasm_put(Dst, 3388, FRAME_TYPE, Dt1(->top), Dt1(->base), Dt1(->cframe), CFRAME_RESUME);
1320 dasm_put(Dst, 3500, Dt1(->base), Dt1(->top), Dt1(->cframe), LUA_YIELD, Dt1(->status));
1321 if (!LJ_DUALNUM) {
1322 dasm_put(Dst, 3527);
1323 }
1324 if (sse) {
1325 dasm_put(Dst, 3530);
1326 }
1327 dasm_put(Dst, 3545, 1+1);
1328 if (LJ_DUALNUM) {
1329 dasm_put(Dst, 3556, LJ_TISNUM, LJ_TISNUM);
1330 } else {
1331 dasm_put(Dst, 3636, LJ_TISNUM);
1332 }
1333 if (sse) {
1334 dasm_put(Dst, 3646, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32));
1335 } else {
1336 dasm_put(Dst, 3677);
1337 }
1338 dasm_put(Dst, 3694, 1+1, FRAME_TYPE, LJ_TNIL);
1339 if (LJ_DUALNUM) {
1340 dasm_put(Dst, 3790, LJ_TISNUM);
1341 } else {
1342 dasm_put(Dst, 3636, LJ_TISNUM);
1343 }
1344 if (sse) {
1345 dasm_put(Dst, 3812);
1346 if (LJ_DUALNUM) {
1347 dasm_put(Dst, 3821);
1348 }
1349 dasm_put(Dst, 2283);
1350 } else {
1351 dasm_put(Dst, 3855);
1352 if (LJ_DUALNUM) {
1353 } else {
1354 dasm_put(Dst, 2290);
1355 }
1356 }
1357 dasm_put(Dst, 3861);
1358 if (LJ_DUALNUM) {
1359 dasm_put(Dst, 3790, LJ_TISNUM);
1360 } else {
1361 dasm_put(Dst, 3636, LJ_TISNUM);
1362 }
1363 if (sse) {
1364 dasm_put(Dst, 3864);
1365 if (LJ_DUALNUM) {
1366 dasm_put(Dst, 3821);
1367 }
1368 dasm_put(Dst, 2283);
1369 } else {
1370 dasm_put(Dst, 3873);
1371 if (LJ_DUALNUM) {
1372 } else {
1373 dasm_put(Dst, 2290);
1374 }
1375 }
1376 if (sse) {
1377 dasm_put(Dst, 3879, 1+1, LJ_TISNUM);
1378 } else {
1379 dasm_put(Dst, 3908, 1+1, LJ_TISNUM);
1380 }
1381 dasm_put(Dst, 3937, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1382 dasm_put(Dst, 4006, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1383 dasm_put(Dst, 4063, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1384 dasm_put(Dst, 4126, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
1385 dasm_put(Dst, 4216);
1386 if (sse) {
1387 dasm_put(Dst, 4228, 1+1, LJ_TISNUM);
1388 } else {
1389 }
1390 dasm_put(Dst, 4253);
1391 if (sse) {
1392 dasm_put(Dst, 4267, 1+1, LJ_TISNUM);
1393 } else {
1394 }
1395 dasm_put(Dst, 4292);
1396 if (sse) {
1397 dasm_put(Dst, 4306, 1+1, LJ_TISNUM);
1398 } else {
1399 }
1400 dasm_put(Dst, 4331);
1401 if (sse) {
1402 dasm_put(Dst, 4347, 1+1, LJ_TISNUM, Dt8(->upvalue[0]));
1403 } else {
1404 dasm_put(Dst, 4386, 1+1, LJ_TISNUM, Dt8(->upvalue[0]));
1405 }
1406 dasm_put(Dst, 4419, 2+1, LJ_TISNUM, LJ_TISNUM, 2+1, LJ_TISNUM, LJ_TISNUM);
1407 dasm_put(Dst, 4484, 1+1, LJ_TISNUM);
1408 if (sse) {
1409 dasm_put(Dst, 4583);
1410 } else {
1411 dasm_put(Dst, 4589);
1412 }
1413 dasm_put(Dst, 4598);
1414 if (sse) {
1415 dasm_put(Dst, 4623);
1416 } else {
1417 dasm_put(Dst, 4629);
1418 }
1419 dasm_put(Dst, 4632, 1+2);
1420 if (sse) {
1421 dasm_put(Dst, 4641);
1422 } else {
1423 dasm_put(Dst, 4649);
1424 }
1425 dasm_put(Dst, 4657);
1426 if (sse) {
1427 dasm_put(Dst, 4660, (unsigned int)(U64x(43500000,00000000)), (unsigned int)((U64x(43500000,00000000))>>32));
1428 } else {
1429 dasm_put(Dst, 4687);
1430 }
1431 dasm_put(Dst, 4706);
1432 if (sse) {
1433 dasm_put(Dst, 4722, 1+1, LJ_TISNUM);
1434 } else {
1435 dasm_put(Dst, 4747, 1+1, LJ_TISNUM);
1436 }
1437 dasm_put(Dst, 4769);
1438 if (sse) {
1439 dasm_put(Dst, 4791);
1440 } else {
1441 dasm_put(Dst, 4817);
1442 }
1443 dasm_put(Dst, 4834, 1+2);
1444 if (sse) {
1445 dasm_put(Dst, 4874);
1446 } else {
1447 dasm_put(Dst, 4882);
1448 }
1449 dasm_put(Dst, 4892, 2+1, LJ_TISNUM, LJ_TISNUM);
1450 if (sse) {
1451 dasm_put(Dst, 4944, 2+1, LJ_TISNUM, LJ_TISNUM);
1452 } else {
1453 dasm_put(Dst, 4991, 2+1, LJ_TISNUM, LJ_TISNUM);
1454 }
1455 dasm_put(Dst, 5032, LJ_TISNUM);
1456 if (LJ_DUALNUM) {
1457 dasm_put(Dst, 5045, LJ_TISNUM);
1458 if (sse) {
1459 dasm_put(Dst, 4583);
1460 } else {
1461 }
1462 dasm_put(Dst, 5095);
1463 } else {
1464 dasm_put(Dst, 2273);
1465 }
1466 if (sse) {
1467 dasm_put(Dst, 5106, LJ_TISNUM);
1468 if (LJ_DUALNUM) {
1469 dasm_put(Dst, 5127);
1470 } else {
1471 dasm_put(Dst, 2273);
1472 }
1473 dasm_put(Dst, 5148);
1474 } else {
1475 }
1476 dasm_put(Dst, 5173, LJ_TISNUM);
1477 if (LJ_DUALNUM) {
1478 dasm_put(Dst, 5186, LJ_TISNUM);
1479 if (sse) {
1480 dasm_put(Dst, 4583);
1481 } else {
1482 }
1483 dasm_put(Dst, 5095);
1484 } else {
1485 dasm_put(Dst, 2273);
1486 }
1487 if (sse) {
1488 dasm_put(Dst, 5106, LJ_TISNUM);
1489 if (LJ_DUALNUM) {
1490 dasm_put(Dst, 5127);
1491 } else {
1492 dasm_put(Dst, 2273);
1493 }
1494 dasm_put(Dst, 5236);
1495 } else {
1496 }
1497 if (!sse) {
1498 dasm_put(Dst, 5261);
1499 }
1500 dasm_put(Dst, 5270, 1+1, LJ_TSTR);
1501 if (LJ_DUALNUM) {
1502 dasm_put(Dst, 5292, Dt5(->len));
1503 } else if (sse) {
1504 dasm_put(Dst, 5300, Dt5(->len));
1505 } else {
1506 dasm_put(Dst, 5311, Dt5(->len));
1507 }
1508 dasm_put(Dst, 5319, 1+1, LJ_TSTR, Dt5(->len), Dt5([1]));
1509 if (LJ_DUALNUM) {
1510 dasm_put(Dst, 5295);
1511 } else if (sse) {
1512 dasm_put(Dst, 5357);
1513 } else {
1514 dasm_put(Dst, 5367);
1515 }
1516 dasm_put(Dst, 5380, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 1+1, LJ_TISNUM);
1517 if (LJ_DUALNUM) {
1518 dasm_put(Dst, 5411);
1519 } else if (sse) {
1520 dasm_put(Dst, 5434);
1521 } else {
1522 dasm_put(Dst, 5460);
1523 }
1524 dasm_put(Dst, 5484, Dt1(->base), Dt1(->base), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 1+2, LJ_TISNUM);
1525 if (LJ_DUALNUM) {
1526 dasm_put(Dst, 5592);
1527 } else if (sse) {
1528 dasm_put(Dst, 5604);
1529 } else {
1530 dasm_put(Dst, 5619);
1531 }
1532 dasm_put(Dst, 5631, LJ_TSTR, LJ_TISNUM);
1533 if (LJ_DUALNUM) {
1534 dasm_put(Dst, 2530);
1535 } else {
1536 dasm_put(Dst, 2273);
1537 }
1538 dasm_put(Dst, 5648, Dt5(->len));
1539 if (LJ_DUALNUM) {
1540 dasm_put(Dst, 5658);
1541 } else if (sse) {
1542 dasm_put(Dst, 5662);
1543 } else {
1544 }
1545 dasm_put(Dst, 5669, sizeof(GCstr)-1);
1546 dasm_put(Dst, 5744, 2+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
1547 dasm_put(Dst, 5803, LJ_TSTR, LJ_TISNUM);
1548 if (LJ_DUALNUM) {
1549 dasm_put(Dst, 5820);
1550 } else if (sse) {
1551 dasm_put(Dst, 5828);
1552 } else {
1553 dasm_put(Dst, 5839);
1554 }
1555 dasm_put(Dst, 5855, Dt5(->len), DISPATCH_GL(tmpbuf.sz), Dt5([1]), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(tmpbuf.buf), 1+1);
1556 dasm_put(Dst, 5920, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
1557 dasm_put(Dst, 5983, 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz));
1558 dasm_put(Dst, 6054, sizeof(GCstr), DISPATCH_GL(tmpbuf.buf), 1+1);
1559 dasm_put(Dst, 6139, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
1560 dasm_put(Dst, 6209, 1+1, LJ_TTAB);
1561 if (LJ_DUALNUM) {
1562 dasm_put(Dst, 6277);
1563 } else if (sse) {
1564 dasm_put(Dst, 6284);
1565 } else {
1566 }
1567 dasm_put(Dst, 6294, 1+1, LJ_TISNUM);
1568 if (LJ_DUALNUM) {
1569 dasm_put(Dst, 6310);
1570 } else {
1571 dasm_put(Dst, 2273);
1572 }
1573 if (sse) {
1574 dasm_put(Dst, 6327, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1575 } else {
1576 }
1577 dasm_put(Dst, 106);
1578 if (LJ_DUALNUM || sse) {
1579 if (!sse) {
1580 }
1581 dasm_put(Dst, 6351);
1582 } else {
1583 }
1584 dasm_put(Dst, 6356, 1+1);
1585 if (sse) {
1586 dasm_put(Dst, 6367, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1587 } else {
1588 dasm_put(Dst, 6377);
1589 }
1590 dasm_put(Dst, 2250, LJ_TISNUM);
1591 if (LJ_DUALNUM) {
1592 dasm_put(Dst, 6386);
1593 } else {
1594 dasm_put(Dst, 2273);
1595 }
1596 if (sse) {
1597 dasm_put(Dst, 6403);
1598 } else {
1599 }
1600 dasm_put(Dst, 6418, LJ_TISNUM);
1601 if (LJ_DUALNUM) {
1602 dasm_put(Dst, 6443);
1603 } else {
1604 dasm_put(Dst, 6463);
1605 }
1606 if (sse) {
1607 dasm_put(Dst, 6468);
1608 } else {
1609 }
1610 dasm_put(Dst, 6485, 1+1);
1611 if (sse) {
1612 dasm_put(Dst, 6367, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1613 } else {
1614 dasm_put(Dst, 6377);
1615 }
1616 dasm_put(Dst, 2250, LJ_TISNUM);
1617 if (LJ_DUALNUM) {
1618 dasm_put(Dst, 6386);
1619 } else {
1620 dasm_put(Dst, 2273);
1621 }
1622 if (sse) {
1623 dasm_put(Dst, 6403);
1624 } else {
1625 }
1626 dasm_put(Dst, 6418, LJ_TISNUM);
1627 if (LJ_DUALNUM) {
1628 dasm_put(Dst, 6503);
1629 } else {
1630 dasm_put(Dst, 6463);
1631 }
1632 if (sse) {
1633 dasm_put(Dst, 6523);
1634 } else {
1635 }
1636 dasm_put(Dst, 6540, 1+1);
1637 if (sse) {
1638 dasm_put(Dst, 6367, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1639 } else {
1640 dasm_put(Dst, 6377);
1641 }
1642 dasm_put(Dst, 2250, LJ_TISNUM);
1643 if (LJ_DUALNUM) {
1644 dasm_put(Dst, 6386);
1645 } else {
1646 dasm_put(Dst, 2273);
1647 }
1648 if (sse) {
1649 dasm_put(Dst, 6403);
1650 } else {
1651 }
1652 dasm_put(Dst, 6418, LJ_TISNUM);
1653 if (LJ_DUALNUM) {
1654 dasm_put(Dst, 6558);
1655 } else {
1656 dasm_put(Dst, 6463);
1657 }
1658 if (sse) {
1659 dasm_put(Dst, 6578);
1660 } else {
1661 }
1662 dasm_put(Dst, 6595, 1+1, LJ_TISNUM);
1663 if (LJ_DUALNUM) {
1664 dasm_put(Dst, 6386);
1665 } else {
1666 dasm_put(Dst, 2273);
1667 }
1668 if (sse) {
1669 dasm_put(Dst, 6327, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1670 } else {
1671 }
1672 dasm_put(Dst, 6618, 1+1, LJ_TISNUM);
1673 if (LJ_DUALNUM) {
1674 dasm_put(Dst, 6386);
1675 } else {
1676 dasm_put(Dst, 2273);
1677 }
1678 if (sse) {
1679 dasm_put(Dst, 6327, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1680 } else {
1681 }
1682 dasm_put(Dst, 6642);
1683 if (LJ_DUALNUM) {
1684 dasm_put(Dst, 6351);
1685 } else if (sse) {
1686 dasm_put(Dst, 6648);
1687 } else {
1688 }
1689 dasm_put(Dst, 6660);
1690 if (LJ_DUALNUM) {
1691 dasm_put(Dst, 6671, 1+1, LJ_TISNUM);
1692 if (LJ_DUALNUM) {
1693 dasm_put(Dst, 6386);
1694 } else {
1695 dasm_put(Dst, 2273);
1696 }
1697 if (sse) {
1698 dasm_put(Dst, 6327, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1699 } else {
1700 }
1701 dasm_put(Dst, 6687, LJ_TISNUM);
1702 } else if (sse) {
1703 dasm_put(Dst, 6702, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1704 } else {
1705 }
1706 dasm_put(Dst, 6769);
1707 if (LJ_DUALNUM) {
1708 dasm_put(Dst, 6776, 1+1, LJ_TISNUM);
1709 if (LJ_DUALNUM) {
1710 dasm_put(Dst, 6386);
1711 } else {
1712 dasm_put(Dst, 2273);
1713 }
1714 if (sse) {
1715 dasm_put(Dst, 6327, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1716 } else {
1717 }
1718 dasm_put(Dst, 6687, LJ_TISNUM);
1719 } else if (sse) {
1720 dasm_put(Dst, 6792, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1721 } else {
1722 }
1723 dasm_put(Dst, 6859);
1724 if (LJ_DUALNUM) {
1725 dasm_put(Dst, 6867, 1+1, LJ_TISNUM);
1726 if (LJ_DUALNUM) {
1727 dasm_put(Dst, 6386);
1728 } else {
1729 dasm_put(Dst, 2273);
1730 }
1731 if (sse) {
1732 dasm_put(Dst, 6327, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1733 } else {
1734 }
1735 dasm_put(Dst, 6687, LJ_TISNUM);
1736 } else if (sse) {
1737 dasm_put(Dst, 6883, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1738 } else {
1739 }
1740 dasm_put(Dst, 6950);
1741 if (LJ_DUALNUM) {
1742 dasm_put(Dst, 6958, 1+1, LJ_TISNUM);
1743 if (LJ_DUALNUM) {
1744 dasm_put(Dst, 6386);
1745 } else {
1746 dasm_put(Dst, 2273);
1747 }
1748 if (sse) {
1749 dasm_put(Dst, 6327, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1750 } else {
1751 }
1752 dasm_put(Dst, 6687, LJ_TISNUM);
1753 } else if (sse) {
1754 dasm_put(Dst, 6974, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1755 } else {
1756 }
1757 dasm_put(Dst, 7041);
1758 if (LJ_DUALNUM) {
1759 dasm_put(Dst, 7048, 1+1, LJ_TISNUM);
1760 if (LJ_DUALNUM) {
1761 dasm_put(Dst, 6386);
1762 } else {
1763 dasm_put(Dst, 2273);
1764 }
1765 if (sse) {
1766 dasm_put(Dst, 6327, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1767 } else {
1768 }
1769 dasm_put(Dst, 6687, LJ_TISNUM);
1770 } else if (sse) {
1771 dasm_put(Dst, 7064, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
1772 } else {
1773 }
1774 dasm_put(Dst, 7131, 1+2, 1+1, Dt1(->base), 8*LUA_MINSTACK, Dt1(->top), Dt1(->maxstack), Dt8(->f), Dt1(->base));
1775 dasm_put(Dst, 7207, Dt1(->top), Dt7(->pc), FRAME_TYPE, LUA_MINSTACK, Dt1(->base), Dt1(->base));
1776 dasm_put(Dst, 7334, Dt1(->top), Dt1(->base), Dt1(->top));
1777#if LJ_HASJIT
1778 dasm_put(Dst, 7373, DISPATCH_GL(hookmask), HOOK_VMEVENT, HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount));
1779#endif
1780 dasm_put(Dst, 7404, DISPATCH_GL(hookmask), HOOK_ACTIVE, DISPATCH_GL(hookmask), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount), LUA_MASKLINE);
1781 dasm_put(Dst, 7455, Dt1(->base), Dt1(->base), GG_DISP2STATIC);
1782#if LJ_HASJIT
1783 dasm_put(Dst, 7522, Dt7(->pc), PC2PROTO(framesize), Dt1(->base), Dt1(->top), GG_DISP2J, DISPATCH_J(L));
1784#endif
1785 dasm_put(Dst, 7569);
1786#if LJ_HASJIT
1787 dasm_put(Dst, 7399);
1788#endif
1789 dasm_put(Dst, 7576);
1790#if LJ_HASJIT
1791 dasm_put(Dst, 7579);
1792#endif
1793 dasm_put(Dst, 7589, Dt1(->base), Dt1(->top));
1794#if LJ_HASJIT
1795 dasm_put(Dst, 7623);
1796#endif
1797 dasm_put(Dst, 7628, Dt1(->base), Dt1(->top));
1798#if LJ_HASJIT
1799 dasm_put(Dst, 7659, DISPATCH_GL(vmstate), DISPATCH_GL(vmstate), ~LJ_VMST_EXIT, DISPATCH_J(exitno), DISPATCH_J(parent), 16*8+4*8, DISPATCH_GL(jit_L), DISPATCH_GL(jit_base), DISPATCH_J(L), DISPATCH_GL(jit_L), Dt1(->base), 4*8, GG_DISP2J, Dt1(->cframe), CFRAME_RAWMASK, CFRAME_OFS_L, Dt1(->base), CFRAME_OFS_PC);
1800#endif
1801 dasm_put(Dst, 7889);
1802#if LJ_HASJIT
1803 dasm_put(Dst, 7892, 9*16+4*8, -9*16, -8*16, -7*16, -6*16, -5*16, -4*16, -3*16, -2*16, -1*16, Dt7(->pc), PC2PROTO(k), DISPATCH_GL(jit_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, BC_FUNCF);
1804 dasm_put(Dst, 8034);
1805#endif
1806 dasm_put(Dst, 8060);
1807 if (!sse) {
1808 dasm_put(Dst, 8063);
1809 }
1810 dasm_put(Dst, 8108, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1811 if (!sse) {
1812 dasm_put(Dst, 8194);
1813 }
1814 dasm_put(Dst, 8239, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(bff00000,00000000)), (unsigned int)((U64x(bff00000,00000000))>>32));
1815 if (!sse) {
1816 dasm_put(Dst, 8325);
1817 }
1818 dasm_put(Dst, 8364, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1819 if (sse) {
1820 dasm_put(Dst, 8453, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1821 } else {
1822 dasm_put(Dst, 8567);
1823 }
1824 dasm_put(Dst, 8614);
1825 if (!sse) {
1826 } else {
1827 dasm_put(Dst, 8688);
1828 }
1829 dasm_put(Dst, 8691);
1830 dasm_put(Dst, 8776, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
1831 dasm_put(Dst, 8879, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7ff00000,00000000)), (unsigned int)((U64x(7ff00000,00000000))>>32));
1832 dasm_put(Dst, 9035);
1833#if LJ_HASJIT
1834 if (sse) {
1835 dasm_put(Dst, 9076);
1836 dasm_put(Dst, 9146);
1837 dasm_put(Dst, 9219);
1838 } else {
1839 dasm_put(Dst, 9269);
1840 dasm_put(Dst, 9361);
1841 }
1842 dasm_put(Dst, 9407);
1843#endif
1844 dasm_put(Dst, 9411);
1845 if (sse) {
1846 dasm_put(Dst, 9414, (unsigned int)(U64x(80000000,00000000)), (unsigned int)((U64x(80000000,00000000))>>32));
1847 dasm_put(Dst, 9503, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32));
1848 } else {
1849 dasm_put(Dst, 9627);
1850 dasm_put(Dst, 9710);
1851 if (cmov) {
1852 dasm_put(Dst, 9765);
1853 } else {
1854 dasm_put(Dst, 9784);
1855 }
1856 dasm_put(Dst, 9407);
1857 }
1858 dasm_put(Dst, 9825);
1859#ifdef LUA_USE_ASSERT
1860 dasm_put(Dst, 9409);
1861#endif
1862 dasm_put(Dst, 9853);
1863#if LJ_HASFFI
1864#define DtE(_V) (int)(ptrdiff_t)&(((CTState *)0)_V)
1865 dasm_put(Dst, 9857, GG_G2DISP, Dt2(->ctype_state), DtE(->cb.slot), DtE(->cb.gpr[0]), DtE(->cb.gpr[1]), DtE(->cb.gpr[2]), DtE(->cb.gpr[3]), DtE(->cb.fpr[0]), DtE(->cb.fpr[1]), DtE(->cb.fpr[2]), DtE(->cb.fpr[3]), CFRAME_SIZE+4*8, DtE(->cb.stack), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top), Dt7(->pc));
1866#endif
1867 dasm_put(Dst, 9984);
1868#if LJ_HASFFI
1869 dasm_put(Dst, 9987, DISPATCH_GL(ctype_state), DtE(->L), Dt1(->base), Dt1(->top), DtE(->cb.gpr[0]), DtE(->cb.fpr[0]));
1870#endif
1871 dasm_put(Dst, 10028);
1872#if LJ_HASFFI
1873#define DtF(_V) (int)(ptrdiff_t)&(((CCallState *)0)_V)
1874 dasm_put(Dst, 10031, DtF(->spadj));
1875#if LJ_TARGET_WINDOWS
1876#endif
1877 dasm_put(Dst, 10046, DtF(->nsp), offsetof(CCallState, stack), CCALL_SPS_EXTRA*8, DtF(->nfpr), DtF(->gpr[0]), DtF(->gpr[1]), DtF(->gpr[2]), DtF(->gpr[3]), DtF(->fpr[0]), DtF(->fpr[1]), DtF(->fpr[2]), DtF(->fpr[3]));
1878 dasm_put(Dst, 10127, DtF(->func), DtF(->gpr[0]), DtF(->fpr[0]));
1879#if LJ_TARGET_WINDOWS
1880#endif
1881 dasm_put(Dst, 10140);
1882#endif
1883}
1884
1885/* Generate the code for a single instruction. */
1886static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse)
1887{
1888 int vk = 0;
1889 dasm_put(Dst, 780, defop);
1890
1891 switch (op) {
1892
1893 /* -- Comparison ops ---------------------------------------------------- */
1894
1895 /* Remember: all ops branch for a true comparison, fall through otherwise. */
1896
1897
1898 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
1899 if (LJ_DUALNUM) {
1900 dasm_put(Dst, 10148, LJ_TISNUM, LJ_TISNUM);
1901 switch (op) {
1902 case BC_ISLT:
1903 dasm_put(Dst, 10178);
1904 break;
1905 case BC_ISGE:
1906 dasm_put(Dst, 10183);
1907 break;
1908 case BC_ISLE:
1909 dasm_put(Dst, 10188);
1910 break;
1911 case BC_ISGT:
1912 dasm_put(Dst, 10193);
1913 break;
1914 default: break; /* Shut up GCC. */
1915 }
1916 dasm_put(Dst, 10198, -BCBIAS_J*4, LJ_TISNUM);
1917 if (sse) {
1918 dasm_put(Dst, 10252);
1919 } else {
1920 dasm_put(Dst, 10263);
1921 }
1922 dasm_put(Dst, 10274);
1923 if (sse) {
1924 dasm_put(Dst, 10281);
1925 switch (op) {
1926 case BC_ISLT:
1927 dasm_put(Dst, 10301);
1928 break;
1929 case BC_ISGE:
1930 dasm_put(Dst, 10306);
1931 break;
1932 case BC_ISLE:
1933 dasm_put(Dst, 10311);
1934 break;
1935 case BC_ISGT:
1936 dasm_put(Dst, 10316);
1937 break;
1938 default: break; /* Shut up GCC. */
1939 }
1940 dasm_put(Dst, 10321);
1941 } else {
1942 dasm_put(Dst, 10326);
1943 }
1944 } else {
1945 dasm_put(Dst, 10334, LJ_TISNUM, LJ_TISNUM);
1946 }
1947 if (sse) {
1948 dasm_put(Dst, 10355);
1949 } else {
1950 dasm_put(Dst, 10376);
1951 if (cmov) {
1952 dasm_put(Dst, 10392);
1953 } else {
1954 dasm_put(Dst, 10398);
1955 }
1956 }
1957 if (LJ_DUALNUM) {
1958 switch (op) {
1959 case BC_ISLT:
1960 dasm_put(Dst, 10301);
1961 break;
1962 case BC_ISGE:
1963 dasm_put(Dst, 10306);
1964 break;
1965 case BC_ISLE:
1966 dasm_put(Dst, 10311);
1967 break;
1968 case BC_ISGT:
1969 dasm_put(Dst, 10316);
1970 break;
1971 default: break; /* Shut up GCC. */
1972 }
1973 dasm_put(Dst, 10321);
1974 } else {
1975 switch (op) {
1976 case BC_ISLT:
1977 dasm_put(Dst, 768);
1978 break;
1979 case BC_ISGE:
1980 dasm_put(Dst, 10405);
1981 break;
1982 case BC_ISLE:
1983 dasm_put(Dst, 10410);
1984 break;
1985 case BC_ISGT:
1986 dasm_put(Dst, 10415);
1987 break;
1988 default: break; /* Shut up GCC. */
1989 }
1990 dasm_put(Dst, 10420, -BCBIAS_J*4);
1991 }
1992 break;
1993
1994 case BC_ISEQV: case BC_ISNEV:
1995 vk = op == BC_ISEQV;
1996 dasm_put(Dst, 10452);
1997 if (LJ_DUALNUM) {
1998 dasm_put(Dst, 10460, LJ_TISNUM, LJ_TISNUM);
1999 if (vk) {
2000 dasm_put(Dst, 10485);
2001 } else {
2002 dasm_put(Dst, 10490);
2003 }
2004 dasm_put(Dst, 10495, -BCBIAS_J*4, LJ_TISNUM);
2005 if (sse) {
2006 dasm_put(Dst, 10547);
2007 } else {
2008 dasm_put(Dst, 10554);
2009 }
2010 dasm_put(Dst, 10558);
2011 if (sse) {
2012 dasm_put(Dst, 10569);
2013 } else {
2014 dasm_put(Dst, 10581);
2015 }
2016 dasm_put(Dst, 10588);
2017 } else {
2018 dasm_put(Dst, 10593, LJ_TISNUM, LJ_TISNUM);
2019 }
2020 if (sse) {
2021 dasm_put(Dst, 10612);
2022 } else {
2023 dasm_put(Dst, 10630);
2024 if (cmov) {
2025 dasm_put(Dst, 10392);
2026 } else {
2027 dasm_put(Dst, 10398);
2028 }
2029 }
2030 iseqne_fp:
2031 if (vk) {
2032 dasm_put(Dst, 10643);
2033 } else {
2034 dasm_put(Dst, 10652);
2035 }
2036 iseqne_end:
2037 if (vk) {
2038 dasm_put(Dst, 10661, -BCBIAS_J*4);
2039 if (!LJ_HASFFI) {
2040 dasm_put(Dst, 4638);
2041 }
2042 } else {
2043 if (!LJ_HASFFI) {
2044 dasm_put(Dst, 4638);
2045 }
2046 dasm_put(Dst, 10676, -BCBIAS_J*4);
2047 }
2048 if (LJ_DUALNUM && (op == BC_ISEQV || op == BC_ISNEV ||
2049 op == BC_ISEQN || op == BC_ISNEN)) {
2050 dasm_put(Dst, 10691);
2051 } else {
2052 dasm_put(Dst, 10432);
2053 }
2054 if (op == BC_ISEQV || op == BC_ISNEV) {
2055 dasm_put(Dst, 10124);
2056 if (LJ_HASFFI) {
2057 dasm_put(Dst, 10696, LJ_TCDATA, LJ_TCDATA);
2058 }
2059 dasm_put(Dst, 10715, LJ_TISPRI, LJ_TISTABUD, LJ_TUDATA, Dt6(->metatable), Dt6(->nomm), 1<<MM_eq);
2060 if (vk) {
2061 dasm_put(Dst, 10779);
2062 } else {
2063 dasm_put(Dst, 10783);
2064 }
2065 dasm_put(Dst, 10789);
2066 } else if (LJ_HASFFI) {
2067 dasm_put(Dst, 10794, LJ_TCDATA);
2068 if (LJ_DUALNUM && vk) {
2069 dasm_put(Dst, 10801);
2070 } else {
2071 dasm_put(Dst, 10774);
2072 }
2073 dasm_put(Dst, 10806);
2074 }
2075 break;
2076 case BC_ISEQS: case BC_ISNES:
2077 vk = op == BC_ISEQS;
2078 dasm_put(Dst, 10811, LJ_TSTR);
2079 iseqne_test:
2080 if (vk) {
2081 dasm_put(Dst, 10647);
2082 } else {
2083 dasm_put(Dst, 2929);
2084 }
2085 goto iseqne_end;
2086 case BC_ISEQN: case BC_ISNEN:
2087 vk = op == BC_ISEQN;
2088 dasm_put(Dst, 10837);
2089 if (LJ_DUALNUM) {
2090 dasm_put(Dst, 10845, LJ_TISNUM, LJ_TISNUM);
2091 if (vk) {
2092 dasm_put(Dst, 10485);
2093 } else {
2094 dasm_put(Dst, 10490);
2095 }
2096 dasm_put(Dst, 10870, -BCBIAS_J*4, LJ_TISNUM);
2097 if (sse) {
2098 dasm_put(Dst, 10918);
2099 } else {
2100 dasm_put(Dst, 10925);
2101 }
2102 dasm_put(Dst, 10929);
2103 if (sse) {
2104 dasm_put(Dst, 10936);
2105 } else {
2106 dasm_put(Dst, 10948);
2107 }
2108 dasm_put(Dst, 10588);
2109 } else {
2110 dasm_put(Dst, 10955, LJ_TISNUM);
2111 }
2112 if (sse) {
2113 dasm_put(Dst, 10964);
2114 } else {
2115 dasm_put(Dst, 10982);
2116 if (cmov) {
2117 dasm_put(Dst, 10392);
2118 } else {
2119 dasm_put(Dst, 10398);
2120 }
2121 }
2122 goto iseqne_fp;
2123 case BC_ISEQP: case BC_ISNEP:
2124 vk = op == BC_ISEQP;
2125 dasm_put(Dst, 10995);
2126 if (!LJ_HASFFI) goto iseqne_test;
2127 if (vk) {
2128 dasm_put(Dst, 11009, -BCBIAS_J*4, LJ_TCDATA);
2129 } else {
2130 dasm_put(Dst, 11059, LJ_TCDATA, -BCBIAS_J*4);
2131 }
2132 break;
2133
2134 /* -- Unary test and copy ops ------------------------------------------- */
2135
2136 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
2137 dasm_put(Dst, 11103, LJ_TISTRUECOND);
2138 if (op == BC_IST || op == BC_ISTC) {
2139 dasm_put(Dst, 10415);
2140 } else {
2141 dasm_put(Dst, 10410);
2142 }
2143 if (op == BC_ISTC || op == BC_ISFC) {
2144 dasm_put(Dst, 11115);
2145 }
2146 dasm_put(Dst, 10420, -BCBIAS_J*4);
2147 break;
2148
2149 /* -- Unary ops --------------------------------------------------------- */
2150
2151 case BC_MOV:
2152 dasm_put(Dst, 11126);
2153 break;
2154 case BC_NOT:
2155 dasm_put(Dst, 11154, LJ_TISTRUECOND, LJ_TTRUE);
2156 break;
2157 case BC_UNM:
2158 if (LJ_DUALNUM) {
2159 dasm_put(Dst, 11190, LJ_TISNUM, LJ_TISNUM);
2160 } else {
2161 dasm_put(Dst, 11267, LJ_TISNUM);
2162 }
2163 if (sse) {
2164 dasm_put(Dst, 11278, (unsigned int)(U64x(80000000,00000000)), (unsigned int)((U64x(80000000,00000000))>>32));
2165 } else {
2166 dasm_put(Dst, 11303);
2167 }
2168 if (LJ_DUALNUM) {
2169 dasm_put(Dst, 10691);
2170 } else {
2171 dasm_put(Dst, 10432);
2172 }
2173 break;
2174 case BC_LEN:
2175 dasm_put(Dst, 11312, LJ_TSTR);
2176 if (LJ_DUALNUM) {
2177 dasm_put(Dst, 11326, Dt5(->len), LJ_TISNUM);
2178 } else if (sse) {
2179 dasm_put(Dst, 11340, Dt5(->len));
2180 } else {
2181 dasm_put(Dst, 11358, Dt5(->len));
2182 }
2183 dasm_put(Dst, 11367, LJ_TTAB);
2184#ifdef LUAJIT_ENABLE_LUA52COMPAT
2185 dasm_put(Dst, 11402, Dt6(->metatable));
2186#endif
2187 dasm_put(Dst, 11416);
2188 if (LJ_DUALNUM) {
2189 } else if (sse) {
2190 dasm_put(Dst, 11425);
2191 } else {
2192 }
2193 dasm_put(Dst, 11431);
2194#ifdef LUAJIT_ENABLE_LUA52COMPAT
2195 dasm_put(Dst, 11444, Dt6(->nomm), 1<<MM_len);
2196#endif
2197 break;
2198
2199 /* -- Binary ops -------------------------------------------------------- */
2200
2201
2202 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
2203 if (LJ_DUALNUM) {
2204 dasm_put(Dst, 11460);
2205 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2206 switch (vk) {
2207 case 0:
2208 dasm_put(Dst, 11468, LJ_TISNUM, LJ_TISNUM);
2209 break;
2210 case 1:
2211 dasm_put(Dst, 11501, LJ_TISNUM, LJ_TISNUM);
2212 break;
2213 default:
2214 dasm_put(Dst, 11534, LJ_TISNUM, LJ_TISNUM);
2215 break;
2216 }
2217 dasm_put(Dst, 11567, LJ_TISNUM);
2218 if (vk == 1) {
2219 dasm_put(Dst, 11336);
2220 } else {
2221 dasm_put(Dst, 11122);
2222 }
2223 dasm_put(Dst, 10432);
2224 } else {
2225 dasm_put(Dst, 11460);
2226 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2227 switch (vk) {
2228 case 0:
2229 dasm_put(Dst, 11573, LJ_TISNUM);
2230 if (LJ_DUALNUM) {
2231 dasm_put(Dst, 11585, LJ_TISNUM);
2232 }
2233 if (sse) {
2234 dasm_put(Dst, 11596);
2235 } else {
2236 dasm_put(Dst, 11610);
2237 }
2238 break;
2239 case 1:
2240 dasm_put(Dst, 11618, LJ_TISNUM);
2241 if (LJ_DUALNUM) {
2242 dasm_put(Dst, 11630, LJ_TISNUM);
2243 }
2244 if (sse) {
2245 dasm_put(Dst, 11641);
2246 } else {
2247 dasm_put(Dst, 11655);
2248 }
2249 break;
2250 default:
2251 dasm_put(Dst, 11663, LJ_TISNUM, LJ_TISNUM);
2252 if (sse) {
2253 dasm_put(Dst, 11685);
2254 } else {
2255 dasm_put(Dst, 11699);
2256 }
2257 break;
2258 }
2259 if (sse) {
2260 dasm_put(Dst, 11296);
2261 } else {
2262 dasm_put(Dst, 11308);
2263 }
2264 dasm_put(Dst, 10432);
2265 }
2266 break;
2267 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
2268 if (LJ_DUALNUM) {
2269 dasm_put(Dst, 11460);
2270 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2271 switch (vk) {
2272 case 0:
2273 dasm_put(Dst, 11707, LJ_TISNUM, LJ_TISNUM);
2274 break;
2275 case 1:
2276 dasm_put(Dst, 11740, LJ_TISNUM, LJ_TISNUM);
2277 break;
2278 default:
2279 dasm_put(Dst, 11773, LJ_TISNUM, LJ_TISNUM);
2280 break;
2281 }
2282 dasm_put(Dst, 11567, LJ_TISNUM);
2283 if (vk == 1) {
2284 dasm_put(Dst, 11336);
2285 } else {
2286 dasm_put(Dst, 11122);
2287 }
2288 dasm_put(Dst, 10432);
2289 } else {
2290 dasm_put(Dst, 11460);
2291 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2292 switch (vk) {
2293 case 0:
2294 dasm_put(Dst, 11573, LJ_TISNUM);
2295 if (LJ_DUALNUM) {
2296 dasm_put(Dst, 11585, LJ_TISNUM);
2297 }
2298 if (sse) {
2299 dasm_put(Dst, 11806);
2300 } else {
2301 dasm_put(Dst, 11820);
2302 }
2303 break;
2304 case 1:
2305 dasm_put(Dst, 11618, LJ_TISNUM);
2306 if (LJ_DUALNUM) {
2307 dasm_put(Dst, 11630, LJ_TISNUM);
2308 }
2309 if (sse) {
2310 dasm_put(Dst, 11828);
2311 } else {
2312 dasm_put(Dst, 11842);
2313 }
2314 break;
2315 default:
2316 dasm_put(Dst, 11663, LJ_TISNUM, LJ_TISNUM);
2317 if (sse) {
2318 dasm_put(Dst, 11850);
2319 } else {
2320 dasm_put(Dst, 11864);
2321 }
2322 break;
2323 }
2324 if (sse) {
2325 dasm_put(Dst, 11296);
2326 } else {
2327 dasm_put(Dst, 11308);
2328 }
2329 dasm_put(Dst, 10432);
2330 }
2331 break;
2332 case BC_MULVN: case BC_MULNV: case BC_MULVV:
2333 if (LJ_DUALNUM) {
2334 dasm_put(Dst, 11460);
2335 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2336 switch (vk) {
2337 case 0:
2338 dasm_put(Dst, 11872, LJ_TISNUM, LJ_TISNUM);
2339 break;
2340 case 1:
2341 dasm_put(Dst, 11906, LJ_TISNUM, LJ_TISNUM);
2342 break;
2343 default:
2344 dasm_put(Dst, 11940, LJ_TISNUM, LJ_TISNUM);
2345 break;
2346 }
2347 dasm_put(Dst, 11567, LJ_TISNUM);
2348 if (vk == 1) {
2349 dasm_put(Dst, 11336);
2350 } else {
2351 dasm_put(Dst, 11122);
2352 }
2353 dasm_put(Dst, 10432);
2354 } else {
2355 dasm_put(Dst, 11460);
2356 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2357 switch (vk) {
2358 case 0:
2359 dasm_put(Dst, 11573, LJ_TISNUM);
2360 if (LJ_DUALNUM) {
2361 dasm_put(Dst, 11585, LJ_TISNUM);
2362 }
2363 if (sse) {
2364 dasm_put(Dst, 11974);
2365 } else {
2366 dasm_put(Dst, 11988);
2367 }
2368 break;
2369 case 1:
2370 dasm_put(Dst, 11618, LJ_TISNUM);
2371 if (LJ_DUALNUM) {
2372 dasm_put(Dst, 11630, LJ_TISNUM);
2373 }
2374 if (sse) {
2375 dasm_put(Dst, 11996);
2376 } else {
2377 dasm_put(Dst, 12010);
2378 }
2379 break;
2380 default:
2381 dasm_put(Dst, 11663, LJ_TISNUM, LJ_TISNUM);
2382 if (sse) {
2383 dasm_put(Dst, 12018);
2384 } else {
2385 dasm_put(Dst, 12032);
2386 }
2387 break;
2388 }
2389 if (sse) {
2390 dasm_put(Dst, 11296);
2391 } else {
2392 dasm_put(Dst, 11308);
2393 }
2394 dasm_put(Dst, 10432);
2395 }
2396 break;
2397 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
2398 dasm_put(Dst, 11460);
2399 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2400 switch (vk) {
2401 case 0:
2402 dasm_put(Dst, 11573, LJ_TISNUM);
2403 if (LJ_DUALNUM) {
2404 dasm_put(Dst, 11585, LJ_TISNUM);
2405 }
2406 if (sse) {
2407 dasm_put(Dst, 12040);
2408 } else {
2409 dasm_put(Dst, 12054);
2410 }
2411 break;
2412 case 1:
2413 dasm_put(Dst, 11618, LJ_TISNUM);
2414 if (LJ_DUALNUM) {
2415 dasm_put(Dst, 11630, LJ_TISNUM);
2416 }
2417 if (sse) {
2418 dasm_put(Dst, 12062);
2419 } else {
2420 dasm_put(Dst, 12076);
2421 }
2422 break;
2423 default:
2424 dasm_put(Dst, 11663, LJ_TISNUM, LJ_TISNUM);
2425 if (sse) {
2426 dasm_put(Dst, 12084);
2427 } else {
2428 dasm_put(Dst, 12098);
2429 }
2430 break;
2431 }
2432 if (sse) {
2433 dasm_put(Dst, 11296);
2434 } else {
2435 dasm_put(Dst, 11308);
2436 }
2437 dasm_put(Dst, 10432);
2438 break;
2439 case BC_MODVN:
2440 dasm_put(Dst, 11460);
2441 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2442 switch (vk) {
2443 case 0:
2444 dasm_put(Dst, 11573, LJ_TISNUM);
2445 if (LJ_DUALNUM) {
2446 dasm_put(Dst, 11585, LJ_TISNUM);
2447 }
2448 if (sse) {
2449 dasm_put(Dst, 12106);
2450 } else {
2451 dasm_put(Dst, 12120);
2452 }
2453 break;
2454 case 1:
2455 dasm_put(Dst, 11618, LJ_TISNUM);
2456 if (LJ_DUALNUM) {
2457 dasm_put(Dst, 11630, LJ_TISNUM);
2458 }
2459 if (sse) {
2460 dasm_put(Dst, 12128);
2461 } else {
2462 dasm_put(Dst, 12142);
2463 }
2464 break;
2465 default:
2466 dasm_put(Dst, 11663, LJ_TISNUM, LJ_TISNUM);
2467 if (sse) {
2468 dasm_put(Dst, 12150);
2469 } else {
2470 dasm_put(Dst, 12164);
2471 }
2472 break;
2473 }
2474 dasm_put(Dst, 12172);
2475 if (sse) {
2476 dasm_put(Dst, 11296);
2477 } else {
2478 dasm_put(Dst, 11308);
2479 }
2480 dasm_put(Dst, 10432);
2481 break;
2482 case BC_MODNV: case BC_MODVV:
2483 dasm_put(Dst, 11460);
2484 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2485 switch (vk) {
2486 case 0:
2487 dasm_put(Dst, 11573, LJ_TISNUM);
2488 if (LJ_DUALNUM) {
2489 dasm_put(Dst, 11585, LJ_TISNUM);
2490 }
2491 if (sse) {
2492 dasm_put(Dst, 12106);
2493 } else {
2494 dasm_put(Dst, 12120);
2495 }
2496 break;
2497 case 1:
2498 dasm_put(Dst, 11618, LJ_TISNUM);
2499 if (LJ_DUALNUM) {
2500 dasm_put(Dst, 11630, LJ_TISNUM);
2501 }
2502 if (sse) {
2503 dasm_put(Dst, 12128);
2504 } else {
2505 dasm_put(Dst, 12142);
2506 }
2507 break;
2508 default:
2509 dasm_put(Dst, 11663, LJ_TISNUM, LJ_TISNUM);
2510 if (sse) {
2511 dasm_put(Dst, 12150);
2512 } else {
2513 dasm_put(Dst, 12164);
2514 }
2515 break;
2516 }
2517 dasm_put(Dst, 12178);
2518 break;
2519 case BC_POW:
2520 dasm_put(Dst, 11460);
2521 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2522 switch (vk) {
2523 case 0:
2524 dasm_put(Dst, 11573, LJ_TISNUM);
2525 if (LJ_DUALNUM) {
2526 dasm_put(Dst, 11585, LJ_TISNUM);
2527 }
2528 if (sse) {
2529 dasm_put(Dst, 12106);
2530 } else {
2531 dasm_put(Dst, 12120);
2532 }
2533 break;
2534 case 1:
2535 dasm_put(Dst, 11618, LJ_TISNUM);
2536 if (LJ_DUALNUM) {
2537 dasm_put(Dst, 11630, LJ_TISNUM);
2538 }
2539 if (sse) {
2540 dasm_put(Dst, 12128);
2541 } else {
2542 dasm_put(Dst, 12142);
2543 }
2544 break;
2545 default:
2546 dasm_put(Dst, 11663, LJ_TISNUM, LJ_TISNUM);
2547 if (sse) {
2548 dasm_put(Dst, 12150);
2549 } else {
2550 dasm_put(Dst, 12164);
2551 }
2552 break;
2553 }
2554 dasm_put(Dst, 12183);
2555 if (sse) {
2556 dasm_put(Dst, 11296);
2557 } else {
2558 dasm_put(Dst, 11308);
2559 }
2560 dasm_put(Dst, 10432);
2561 break;
2562
2563 case BC_CAT:
2564 dasm_put(Dst, 12187, Dt1(->base), Dt1(->base));
2565 break;
2566
2567 /* -- Constant ops ------------------------------------------------------ */
2568
2569 case BC_KSTR:
2570 dasm_put(Dst, 12270, LJ_TSTR);
2571 break;
2572 case BC_KCDATA:
2573#if LJ_HASFFI
2574 dasm_put(Dst, 12270, LJ_TCDATA);
2575#endif
2576 break;
2577 case BC_KSHORT:
2578 if (LJ_DUALNUM) {
2579 dasm_put(Dst, 12305, LJ_TISNUM);
2580 } else if (sse) {
2581 dasm_put(Dst, 12317);
2582 } else {
2583 dasm_put(Dst, 12332);
2584 }
2585 dasm_put(Dst, 10432);
2586 break;
2587 case BC_KNUM:
2588 if (sse) {
2589 dasm_put(Dst, 12340);
2590 } else {
2591 dasm_put(Dst, 12353);
2592 }
2593 dasm_put(Dst, 10432);
2594 break;
2595 case BC_KPRI:
2596 dasm_put(Dst, 12360);
2597 break;
2598 case BC_KNIL:
2599 dasm_put(Dst, 12388, LJ_TNIL);
2600 break;
2601
2602 /* -- Upvalue and function ops ------------------------------------------ */
2603
2604 case BC_UGET:
2605 dasm_put(Dst, 12435, offsetof(GCfuncL, uvptr), DtA(->v));
2606 break;
2607 case BC_USETV:
2608#define TV2MARKOFS \
2609 ((int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv))
2610 dasm_put(Dst, 12475, offsetof(GCfuncL, uvptr), DtA(->closed), DtA(->v), TV2MARKOFS, LJ_GC_BLACK, LJ_TISGCV, LJ_TISNUM - LJ_TISGCV, Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
2611 dasm_put(Dst, 12566);
2612 break;
2613#undef TV2MARKOFS
2614 case BC_USETS:
2615 dasm_put(Dst, 12578, offsetof(GCfuncL, uvptr), DtA(->v), LJ_TSTR, DtA(->marked), LJ_GC_BLACK, Dt4(->gch.marked), LJ_GC_WHITES, DtA(->closed), GG_DISP2G);
2616 break;
2617 case BC_USETN:
2618 dasm_put(Dst, 12671);
2619 if (sse) {
2620 dasm_put(Dst, 12676);
2621 } else {
2622 dasm_put(Dst, 10951);
2623 }
2624 dasm_put(Dst, 12683, offsetof(GCfuncL, uvptr), DtA(->v));
2625 if (sse) {
2626 dasm_put(Dst, 12692);
2627 } else {
2628 dasm_put(Dst, 12698);
2629 }
2630 dasm_put(Dst, 10432);
2631 break;
2632 case BC_USETP:
2633 dasm_put(Dst, 12701, offsetof(GCfuncL, uvptr), DtA(->v));
2634 break;
2635 case BC_UCLO:
2636 dasm_put(Dst, 12740, -BCBIAS_J*4, Dt1(->openupval), Dt1(->base), Dt1(->base));
2637 break;
2638
2639 case BC_FNEW:
2640 dasm_put(Dst, 12795, Dt1(->base), Dt1(->base), LJ_TFUNC);
2641 break;
2642
2643 /* -- Table ops --------------------------------------------------------- */
2644
2645 case BC_TNEW:
2646 dasm_put(Dst, 12861, Dt1(->base), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), LJ_TTAB);
2647 break;
2648 case BC_TDUP:
2649 dasm_put(Dst, 12983, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), Dt1(->base), LJ_TTAB);
2650 break;
2651
2652 case BC_GGET:
2653 dasm_put(Dst, 13078, Dt7(->env));
2654 break;
2655 case BC_GSET:
2656 dasm_put(Dst, 13097, Dt7(->env));
2657 break;
2658
2659 case BC_TGETV:
2660 dasm_put(Dst, 13116, LJ_TTAB);
2661 if (LJ_DUALNUM) {
2662 dasm_put(Dst, 13139, LJ_TISNUM);
2663 } else {
2664 dasm_put(Dst, 13153, LJ_TISNUM);
2665 if (sse) {
2666 dasm_put(Dst, 13164);
2667 } else {
2668 }
2669 dasm_put(Dst, 13185);
2670 }
2671 dasm_put(Dst, 13190, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index, LJ_TNIL);
2672 dasm_put(Dst, 13281, LJ_TSTR);
2673 break;
2674 case BC_TGETS:
2675 dasm_put(Dst, 13299, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
2676 dasm_put(Dst, 13383, LJ_TNIL, DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
2677 break;
2678 case BC_TGETB:
2679 dasm_put(Dst, 13454, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
2680 dasm_put(Dst, 13549, LJ_TNIL);
2681 break;
2682
2683 case BC_TSETV:
2684 dasm_put(Dst, 13566, LJ_TTAB);
2685 if (LJ_DUALNUM) {
2686 dasm_put(Dst, 13139, LJ_TISNUM);
2687 } else {
2688 dasm_put(Dst, 13153, LJ_TISNUM);
2689 if (sse) {
2690 dasm_put(Dst, 13164);
2691 } else {
2692 }
2693 dasm_put(Dst, 13589);
2694 }
2695 dasm_put(Dst, 13594, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex);
2696 dasm_put(Dst, 13674, LJ_TSTR, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2697 break;
2698 case BC_TSETS:
2699 dasm_put(Dst, 13731, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->nomm), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
2700 dasm_put(Dst, 13807, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DtB(->next));
2701 dasm_put(Dst, 13895, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, LJ_TSTR, Dt1(->base), Dt1(->base), Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2702 break;
2703 case BC_TSETB:
2704 dasm_put(Dst, 13986, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable));
2705 dasm_put(Dst, 14080, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2706 break;
2707
2708 case BC_TSETM:
2709 dasm_put(Dst, 14126, Dt6(->marked), LJ_GC_BLACK, Dt6(->asize), Dt6(->array), Dt1(->base), Dt1(->base));
2710 dasm_put(Dst, 14269, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2711 break;
2712
2713 /* -- Calls and vararg handling ----------------------------------------- */
2714
2715 case BC_CALL: case BC_CALLM:
2716 dasm_put(Dst, 11464);
2717 if (op == BC_CALLM) {
2718 dasm_put(Dst, 14287);
2719 }
2720 dasm_put(Dst, 14292, LJ_TFUNC, Dt7(->pc));
2721 break;
2722
2723 case BC_CALLMT:
2724 dasm_put(Dst, 14287);
2725 break;
2726 case BC_CALLT:
2727 dasm_put(Dst, 14334, LJ_TFUNC, FRAME_TYPE, Dt7(->ffid), Dt7(->pc));
2728 dasm_put(Dst, 14449, FRAME_TYPE, Dt7(->pc), PC2PROTO(k), FRAME_VARG, FRAME_TYPEP, FRAME_VARG);
2729 break;
2730
2731 case BC_ITERC:
2732 dasm_put(Dst, 14520, LJ_TFUNC, 2+1, Dt7(->pc));
2733 break;
2734
2735 case BC_ITERN:
2736#if LJ_HASJIT
2737#endif
2738 dasm_put(Dst, 14591, Dt6(->asize), Dt6(->array), LJ_TNIL);
2739 if (LJ_DUALNUM) {
2740 dasm_put(Dst, 11331, LJ_TISNUM);
2741 } else if (sse) {
2742 dasm_put(Dst, 11425);
2743 } else {
2744 dasm_put(Dst, 14637);
2745 }
2746 dasm_put(Dst, 14643);
2747 if (LJ_DUALNUM) {
2748 } else if (sse) {
2749 dasm_put(Dst, 11296);
2750 } else {
2751 dasm_put(Dst, 11308);
2752 }
2753 dasm_put(Dst, 14656, -BCBIAS_J*4);
2754 if (!LJ_DUALNUM && !sse) {
2755 dasm_put(Dst, 14708);
2756 }
2757 dasm_put(Dst, 14714, Dt6(->hmask), sizeof(Node), Dt6(->node), DtB(->val.it), LJ_TNIL, DtB(->key), DtB(->val));
2758 break;
2759
2760 case BC_ISNEXT:
2761 dasm_put(Dst, 14786, LJ_TFUNC, LJ_TTAB, LJ_TNIL, Dt8(->ffid), FF_next_N, -BCBIAS_J*4, BC_JMP, -BCBIAS_J*4, BC_ITERC);
2762 break;
2763
2764 case BC_VARG:
2765 dasm_put(Dst, 14886, (8+FRAME_VARG), LJ_TNIL, Dt1(->maxstack));
2766 dasm_put(Dst, 15046, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
2767 break;
2768
2769 /* -- Returns ----------------------------------------------------------- */
2770
2771 case BC_RETM:
2772 dasm_put(Dst, 14287);
2773 break;
2774
2775 case BC_RET: case BC_RET0: case BC_RET1:
2776 if (op != BC_RET0) {
2777 dasm_put(Dst, 15112);
2778 }
2779 dasm_put(Dst, 15116, FRAME_TYPE);
2780 switch (op) {
2781 case BC_RET:
2782 dasm_put(Dst, 15135);
2783 break;
2784 case BC_RET1:
2785 dasm_put(Dst, 15187);
2786 /* fallthrough */
2787 case BC_RET0:
2788 dasm_put(Dst, 15197);
2789 default:
2790 break;
2791 }
2792 dasm_put(Dst, 15208, Dt7(->pc), PC2PROTO(k));
2793 if (op == BC_RET) {
2794 dasm_put(Dst, 15252, LJ_TNIL);
2795 } else {
2796 dasm_put(Dst, 15261, LJ_TNIL);
2797 }
2798 dasm_put(Dst, 15268, -FRAME_VARG, FRAME_TYPEP);
2799 if (op != BC_RET0) {
2800 dasm_put(Dst, 15292);
2801 }
2802 dasm_put(Dst, 4717);
2803 break;
2804
2805 /* -- Loops and branches ------------------------------------------------ */
2806
2807
2808 case BC_FORL:
2809#if LJ_HASJIT
2810 dasm_put(Dst, 15296, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
2811#endif
2812 break;
2813
2814 case BC_JFORI:
2815 case BC_JFORL:
2816#if !LJ_HASJIT
2817 break;
2818#endif
2819 case BC_FORI:
2820 case BC_IFORL:
2821 vk = (op == BC_IFORL || op == BC_JFORL);
2822 dasm_put(Dst, 15317);
2823 if (LJ_DUALNUM) {
2824 dasm_put(Dst, 15321, LJ_TISNUM);
2825 if (!vk) {
2826 dasm_put(Dst, 15331, LJ_TISNUM, LJ_TISNUM);
2827 } else {
2828#ifdef LUA_USE_ASSERT
2829 dasm_put(Dst, 15360, LJ_TISNUM, LJ_TISNUM);
2830#endif
2831 dasm_put(Dst, 15379);
2832 }
2833 dasm_put(Dst, 15398, LJ_TISNUM);
2834 if (op == BC_FORI) {
2835 dasm_put(Dst, 15409, -BCBIAS_J*4);
2836 } else if (op == BC_JFORI) {
2837 dasm_put(Dst, 15423, -BCBIAS_J*4, BC_JLOOP);
2838 } else if (op == BC_IFORL) {
2839 dasm_put(Dst, 15441, -BCBIAS_J*4);
2840 } else {
2841 dasm_put(Dst, 15433, BC_JLOOP);
2842 }
2843 dasm_put(Dst, 15455);
2844 if (vk) {
2845 dasm_put(Dst, 15479);
2846 }
2847 dasm_put(Dst, 15398, LJ_TISNUM);
2848 if (op == BC_FORI) {
2849 dasm_put(Dst, 15488);
2850 } else if (op == BC_JFORI) {
2851 dasm_put(Dst, 15493, -BCBIAS_J*4, BC_JLOOP);
2852 } else if (op == BC_IFORL) {
2853 dasm_put(Dst, 15507);
2854 } else {
2855 dasm_put(Dst, 15503, BC_JLOOP);
2856 }
2857 dasm_put(Dst, 15512);
2858 } else if (!vk) {
2859 dasm_put(Dst, 15519, LJ_TISNUM);
2860 }
2861 if (!vk) {
2862 dasm_put(Dst, 15525, LJ_TISNUM);
2863 } else {
2864#ifdef LUA_USE_ASSERT
2865 dasm_put(Dst, 15539, LJ_TISNUM, LJ_TISNUM);
2866#endif
2867 }
2868 dasm_put(Dst, 15558);
2869 if (!vk) {
2870 dasm_put(Dst, 15562, LJ_TISNUM);
2871 }
2872 if (sse) {
2873 dasm_put(Dst, 15571);
2874 if (vk) {
2875 dasm_put(Dst, 15583);
2876 } else {
2877 dasm_put(Dst, 15602);
2878 }
2879 dasm_put(Dst, 15607);
2880 } else {
2881 dasm_put(Dst, 15620);
2882 if (vk) {
2883 dasm_put(Dst, 15626);
2884 } else {
2885 dasm_put(Dst, 15642);
2886 }
2887 dasm_put(Dst, 15650);
2888 if (cmov) {
2889 dasm_put(Dst, 10392);
2890 } else {
2891 dasm_put(Dst, 10398);
2892 }
2893 if (!cmov) {
2894 dasm_put(Dst, 15655);
2895 }
2896 }
2897 if (op == BC_FORI) {
2898 if (LJ_DUALNUM) {
2899 dasm_put(Dst, 15661);
2900 } else {
2901 dasm_put(Dst, 15666, -BCBIAS_J*4);
2902 }
2903 } else if (op == BC_JFORI) {
2904 dasm_put(Dst, 15676, -BCBIAS_J*4, BC_JLOOP);
2905 } else if (op == BC_IFORL) {
2906 if (LJ_DUALNUM) {
2907 dasm_put(Dst, 15690);
2908 } else {
2909 dasm_put(Dst, 15695, -BCBIAS_J*4);
2910 }
2911 } else {
2912 dasm_put(Dst, 15686, BC_JLOOP);
2913 }
2914 if (LJ_DUALNUM) {
2915 dasm_put(Dst, 10321);
2916 } else {
2917 dasm_put(Dst, 11081);
2918 }
2919 if (sse) {
2920 dasm_put(Dst, 15705);
2921 }
2922 break;
2923
2924 case BC_ITERL:
2925#if LJ_HASJIT
2926 dasm_put(Dst, 15296, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
2927#endif
2928 break;
2929
2930 case BC_JITERL:
2931#if !LJ_HASJIT
2932 break;
2933#endif
2934 case BC_IITERL:
2935 dasm_put(Dst, 15716, LJ_TNIL);
2936 if (op == BC_JITERL) {
2937 dasm_put(Dst, 15731, BC_JLOOP);
2938 } else {
2939 dasm_put(Dst, 15745, -BCBIAS_J*4);
2940 }
2941 dasm_put(Dst, 10430);
2942 break;
2943
2944 case BC_LOOP:
2945#if LJ_HASJIT
2946 dasm_put(Dst, 15296, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
2947#endif
2948 break;
2949
2950 case BC_ILOOP:
2951 dasm_put(Dst, 10432);
2952 break;
2953
2954 case BC_JLOOP:
2955#if LJ_HASJIT
2956 dasm_put(Dst, 15761, DISPATCH_J(trace), DtD(->mcode), DISPATCH_GL(jit_base), DISPATCH_GL(jit_L), 9*16+4*8, -1*16, -2*16, -3*16, -4*16, -5*16, -6*16, -7*16, -8*16, -9*16);
2957#endif
2958 break;
2959
2960 case BC_JMP:
2961 dasm_put(Dst, 15870, -BCBIAS_J*4);
2962 break;
2963
2964 /* -- Function headers -------------------------------------------------- */
2965
2966 /*
2967 ** Reminder: A function may be called with func/args above L->maxstack,
2968 ** i.e. occupying EXTRA_STACK slots. And vmeta_call may add one extra slot,
2969 ** too. This means all FUNC* ops (including fast functions) must check
2970 ** for stack overflow _before_ adding more slots!
2971 */
2972
2973 case BC_FUNCF:
2974#if LJ_HASJIT
2975 dasm_put(Dst, 15895, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_CALL);
2976#endif
2977 case BC_FUNCV: /* NYI: compiled vararg functions. */
2978 break;
2979
2980 case BC_JFUNCF:
2981#if !LJ_HASJIT
2982 break;
2983#endif
2984 case BC_IFUNCF:
2985 dasm_put(Dst, 15916, -4+PC2PROTO(k), Dt1(->maxstack), -4+PC2PROTO(numparams));
2986 if (op == BC_JFUNCF) {
2987 dasm_put(Dst, 15946, BC_JLOOP);
2988 } else {
2989 dasm_put(Dst, 10432);
2990 }
2991 dasm_put(Dst, 15955, LJ_TNIL);
2992 break;
2993
2994 case BC_JFUNCV:
2995#if !LJ_HASJIT
2996 break;
2997#endif
2998 dasm_put(Dst, 9409);
2999 break; /* NYI: compiled vararg functions. */
3000
3001 case BC_IFUNCV:
3002 dasm_put(Dst, 15977, FRAME_VARG, Dt1(->maxstack), -4+PC2PROTO(numparams), LJ_TNIL);
3003 if (op == BC_JFUNCV) {
3004 dasm_put(Dst, 15946, BC_JLOOP);
3005 } else {
3006 dasm_put(Dst, 16068, -4+PC2PROTO(k));
3007 }
3008 dasm_put(Dst, 16091, LJ_TNIL);
3009 break;
3010
3011 case BC_FUNCC:
3012 case BC_FUNCCW:
3013 dasm_put(Dst, 16113, Dt8(->f), Dt1(->base), 8*LUA_MINSTACK, Dt1(->maxstack), Dt1(->top));
3014 if (op == BC_FUNCC) {
3015 dasm_put(Dst, 2381);
3016 } else {
3017 dasm_put(Dst, 16143);
3018 }
3019 dasm_put(Dst, 16151, DISPATCH_GL(vmstate), ~LJ_VMST_C);
3020 if (op == BC_FUNCC) {
3021 dasm_put(Dst, 16160);
3022 } else {
3023 dasm_put(Dst, 16164, DISPATCH_GL(wrapf));
3024 }
3025 dasm_put(Dst, 16169, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top));
3026 break;
3027
3028 /* ---------------------------------------------------------------------- */
3029
3030 default:
3031 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
3032 exit(2);
3033 break;
3034 }
3035}
3036
3037static int build_backend(BuildCtx *ctx)
3038{
3039 int op;
3040 int cmov = 1;
3041 int sse = 0;
3042#ifdef LUAJIT_CPU_NOCMOV
3043 cmov = 0;
3044#endif
3045#if defined(LUAJIT_CPU_SSE2) || defined(LJ_TARGET_X64)
3046 sse = 1;
3047#endif
3048
3049 dasm_growpc(Dst, BC__MAX);
3050
3051 build_subroutines(ctx, cmov, sse);
3052
3053 dasm_put(Dst, 16194);
3054 for (op = 0; op < BC__MAX; op++)
3055 build_ins(ctx, (BCOp)op, op, cmov, sse);
3056
3057 return BC__MAX;
3058}
3059
3060/* Emit pseudo frame-info for all assembler functions. */
3061static void emit_asm_debug(BuildCtx *ctx)
3062{
3063 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
3064#if LJ_64
3065#define SZPTR "8"
3066#define BSZPTR "3"
3067#define REG_SP "0x7"
3068#define REG_RA "0x10"
3069#else
3070#define SZPTR "4"
3071#define BSZPTR "2"
3072#define REG_SP "0x4"
3073#define REG_RA "0x8"
3074#endif
3075 switch (ctx->mode) {
3076 case BUILD_elfasm:
3077 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
3078 fprintf(ctx->fp,
3079 ".Lframe0:\n"
3080 "\t.long .LECIE0-.LSCIE0\n"
3081 ".LSCIE0:\n"
3082 "\t.long 0xffffffff\n"
3083 "\t.byte 0x1\n"
3084 "\t.string \"\"\n"
3085 "\t.uleb128 0x1\n"
3086 "\t.sleb128 -" SZPTR "\n"
3087 "\t.byte " REG_RA "\n"
3088 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3089 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3090 "\t.align " SZPTR "\n"
3091 ".LECIE0:\n\n");
3092 fprintf(ctx->fp,
3093 ".LSFDE0:\n"
3094 "\t.long .LEFDE0-.LASFDE0\n"
3095 ".LASFDE0:\n"
3096 "\t.long .Lframe0\n"
3097#if LJ_64
3098 "\t.quad .Lbegin\n"
3099 "\t.quad %d\n"
3100 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3101 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3102 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3103 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3104 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3105#else
3106 "\t.long .Lbegin\n"
3107 "\t.long %d\n"
3108 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3109 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3110 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3111 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3112 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3113#endif
3114 "\t.align " SZPTR "\n"
3115 ".LEFDE0:\n\n", fcofs, CFRAME_SIZE);
3116#if LJ_HASFFI
3117 fprintf(ctx->fp,
3118 ".LSFDE1:\n"
3119 "\t.long .LEFDE1-.LASFDE1\n"
3120 ".LASFDE1:\n"
3121 "\t.long .Lframe0\n"
3122#if LJ_64
3123 "\t.quad lj_vm_ffi_call\n"
3124 "\t.quad %d\n"
3125 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
3126 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3127 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3128 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3129#else
3130 "\t.long lj_vm_ffi_call\n"
3131 "\t.long %d\n"
3132 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
3133 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3134 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
3135 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
3136#endif
3137 "\t.align " SZPTR "\n"
3138 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
3139#endif
3140#if (defined(__sun__) && defined(__svr4__)) || defined(__solaris_)
3141 fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n");
3142#else
3143 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
3144#endif
3145 fprintf(ctx->fp,
3146 ".Lframe1:\n"
3147 "\t.long .LECIE1-.LSCIE1\n"
3148 ".LSCIE1:\n"
3149 "\t.long 0\n"
3150 "\t.byte 0x1\n"
3151 "\t.string \"zPR\"\n"
3152 "\t.uleb128 0x1\n"
3153 "\t.sleb128 -" SZPTR "\n"
3154 "\t.byte " REG_RA "\n"
3155 "\t.uleb128 6\n" /* augmentation length */
3156 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3157 "\t.long lj_err_unwind_dwarf-.\n"
3158 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3159 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3160 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3161 "\t.align " SZPTR "\n"
3162 ".LECIE1:\n\n");
3163 fprintf(ctx->fp,
3164 ".LSFDE2:\n"
3165 "\t.long .LEFDE2-.LASFDE2\n"
3166 ".LASFDE2:\n"
3167 "\t.long .LASFDE2-.Lframe1\n"
3168 "\t.long .Lbegin-.\n"
3169 "\t.long %d\n"
3170 "\t.uleb128 0\n" /* augmentation length */
3171 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3172#if LJ_64
3173 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3174 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3175 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3176 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3177#else
3178 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3179 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3180 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3181 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3182#endif
3183 "\t.align " SZPTR "\n"
3184 ".LEFDE2:\n\n", fcofs, CFRAME_SIZE);
3185#if LJ_HASFFI
3186 fprintf(ctx->fp,
3187 ".Lframe2:\n"
3188 "\t.long .LECIE2-.LSCIE2\n"
3189 ".LSCIE2:\n"
3190 "\t.long 0\n"
3191 "\t.byte 0x1\n"
3192 "\t.string \"zR\"\n"
3193 "\t.uleb128 0x1\n"
3194 "\t.sleb128 -" SZPTR "\n"
3195 "\t.byte " REG_RA "\n"
3196 "\t.uleb128 1\n" /* augmentation length */
3197 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3198 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3199 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3200 "\t.align " SZPTR "\n"
3201 ".LECIE2:\n\n");
3202 fprintf(ctx->fp,
3203 ".LSFDE3:\n"
3204 "\t.long .LEFDE3-.LASFDE3\n"
3205 ".LASFDE3:\n"
3206 "\t.long .LASFDE3-.Lframe2\n"
3207 "\t.long lj_vm_ffi_call-.\n"
3208 "\t.long %d\n"
3209 "\t.uleb128 0\n" /* augmentation length */
3210#if LJ_64
3211 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
3212 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3213 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3214 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3215#else
3216 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
3217 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3218 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
3219 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
3220#endif
3221 "\t.align " SZPTR "\n"
3222 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
3223#endif
3224 break;
3225 case BUILD_coffasm:
3226 fprintf(ctx->fp, "\t.section .eh_frame,\"dr\"\n");
3227 fprintf(ctx->fp,
3228 "\t.def %slj_err_unwind_dwarf; .scl 2; .type 32; .endef\n",
3229 LJ_32 ? "_" : "");
3230 fprintf(ctx->fp,
3231 "Lframe1:\n"
3232 "\t.long LECIE1-LSCIE1\n"
3233 "LSCIE1:\n"
3234 "\t.long 0\n"
3235 "\t.byte 0x1\n"
3236 "\t.string \"zP\"\n"
3237 "\t.uleb128 0x1\n"
3238 "\t.sleb128 -" SZPTR "\n"
3239 "\t.byte " REG_RA "\n"
3240 "\t.uleb128 5\n" /* augmentation length */
3241 "\t.byte 0x00\n" /* absptr */
3242 "\t.long %slj_err_unwind_dwarf\n"
3243 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3244 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3245 "\t.align " SZPTR "\n"
3246 "LECIE1:\n\n", LJ_32 ? "_" : "");
3247 fprintf(ctx->fp,
3248 "LSFDE1:\n"
3249 "\t.long LEFDE1-LASFDE1\n"
3250 "LASFDE1:\n"
3251 "\t.long LASFDE1-Lframe1\n"
3252 "\t.long %slj_vm_asm_begin\n"
3253 "\t.long %d\n"
3254 "\t.uleb128 0\n" /* augmentation length */
3255 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3256#if LJ_64
3257 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3258 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3259 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3260 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3261#else
3262 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3263 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3264 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3265 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3266#endif
3267 "\t.align " SZPTR "\n"
3268 "LEFDE1:\n\n", LJ_32 ? "_" : "", (int)ctx->codesz, CFRAME_SIZE);
3269 break;
3270 /* Mental note: never let Apple design an assembler.
3271 ** Or a linker. Or a plastic case. But I digress.
3272 */
3273 case BUILD_machasm: {
3274#if LJ_HASFFI
3275 int fcsize = 0;
3276#endif
3277 int i;
3278 fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
3279 fprintf(ctx->fp,
3280 "EH_frame1:\n"
3281 "\t.set L$set$x,LECIEX-LSCIEX\n"
3282 "\t.long L$set$x\n"
3283 "LSCIEX:\n"
3284 "\t.long 0\n"
3285 "\t.byte 0x1\n"
3286 "\t.ascii \"zPR\\0\"\n"
3287 "\t.byte 0x1\n"
3288 "\t.byte 128-" SZPTR "\n"
3289 "\t.byte " REG_RA "\n"
3290 "\t.byte 6\n" /* augmentation length */
3291 "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
3292#if LJ_64
3293 "\t.long _lj_err_unwind_dwarf+4@GOTPCREL\n"
3294 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3295 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
3296#else
3297 "\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
3298 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3299 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
3300#endif
3301 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
3302 "\t.align " BSZPTR "\n"
3303 "LECIEX:\n\n");
3304 for (i = 0; i < ctx->nsym; i++) {
3305 const char *name = ctx->sym[i].name;
3306 int32_t size = ctx->sym[i+1].ofs - ctx->sym[i].ofs;
3307 if (size == 0) continue;
3308#if LJ_HASFFI
3309 if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; }
3310#endif
3311 fprintf(ctx->fp,
3312 "%s.eh:\n"
3313 "LSFDE%d:\n"
3314 "\t.set L$set$%d,LEFDE%d-LASFDE%d\n"
3315 "\t.long L$set$%d\n"
3316 "LASFDE%d:\n"
3317 "\t.long LASFDE%d-EH_frame1\n"
3318 "\t.long %s-.\n"
3319 "\t.long %d\n"
3320 "\t.byte 0\n" /* augmentation length */
3321 "\t.byte 0xe\n\t.byte %d\n" /* def_cfa_offset */
3322#if LJ_64
3323 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
3324 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
3325 "\t.byte 0x8f\n\t.byte 0x4\n" /* offset r15 */
3326 "\t.byte 0x8e\n\t.byte 0x5\n" /* offset r14 */
3327#else
3328 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
3329 "\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
3330 "\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
3331 "\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
3332#endif
3333 "\t.align " BSZPTR "\n"
3334 "LEFDE%d:\n\n",
3335 name, i, i, i, i, i, i, i, name, size, CFRAME_SIZE, i);
3336 }
3337#if LJ_HASFFI
3338 if (fcsize) {
3339 fprintf(ctx->fp,
3340 "EH_frame2:\n"
3341 "\t.set L$set$y,LECIEY-LSCIEY\n"
3342 "\t.long L$set$y\n"
3343 "LSCIEY:\n"
3344 "\t.long 0\n"
3345 "\t.byte 0x1\n"
3346 "\t.ascii \"zR\\0\"\n"
3347 "\t.byte 0x1\n"
3348 "\t.byte 128-" SZPTR "\n"
3349 "\t.byte " REG_RA "\n"
3350 "\t.byte 1\n" /* augmentation length */
3351#if LJ_64
3352 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3353 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
3354#else
3355 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3356 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH. */
3357#endif
3358 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
3359 "\t.align " BSZPTR "\n"
3360 "LECIEY:\n\n");
3361 fprintf(ctx->fp,
3362 "_lj_vm_ffi_call.eh:\n"
3363 "LSFDEY:\n"
3364 "\t.set L$set$yy,LEFDEY-LASFDEY\n"
3365 "\t.long L$set$yy\n"
3366 "LASFDEY:\n"
3367 "\t.long LASFDEY-EH_frame2\n"
3368 "\t.long _lj_vm_ffi_call-.\n"
3369 "\t.long %d\n"
3370 "\t.byte 0\n" /* augmentation length */
3371#if LJ_64
3372 "\t.byte 0xe\n\t.byte 16\n" /* def_cfa_offset */
3373 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
3374 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3375 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
3376#else
3377 "\t.byte 0xe\n\t.byte 8\n" /* def_cfa_offset */
3378 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
3379 "\t.byte 0xd\n\t.uleb128 0x4\n" /* def_cfa_register ebp */
3380 "\t.byte 0x83\n\t.byte 0x3\n" /* offset ebx */
3381#endif
3382 "\t.align " BSZPTR "\n"
3383 "LEFDEY:\n\n", fcsize);
3384 }
3385#endif
3386#if LJ_64
3387 fprintf(ctx->fp, "\t.subsections_via_symbols\n");
3388#else
3389 fprintf(ctx->fp,
3390 "\t.non_lazy_symbol_pointer\n"
3391 "L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
3392 ".indirect_symbol _lj_err_unwind_dwarf\n"
3393 ".long 0\n");
3394#endif
3395 }
3396 break;
3397 default: /* Difficult for other modes. */
3398 break;
3399 }
3400}
3401
diff --git a/libraries/luajit-2.0/src/buildvm_x86.dasc b/libraries/luajit-2.0/src/buildvm_x86.dasc
new file mode 100644
index 0000000..d6dfde8
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_x86.dasc
@@ -0,0 +1,6458 @@
1|// Low-level VM code for x86 CPUs.
2|// Bytecode interpreter, fast functions and helper functions.
3|// Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4|
5|.if X64
6|.arch x64
7|.else
8|.arch x86
9|.endif
10|.section code_op, code_sub
11|
12|.actionlist build_actionlist
13|.globals GLOB_
14|.globalnames globnames
15|.externnames extnames
16|
17|//-----------------------------------------------------------------------
18|
19|// Fixed register assignments for the interpreter.
20|// This is very fragile and has many dependencies. Caveat emptor.
21|.define BASE, edx // Not C callee-save, refetched anyway.
22|.if not X64
23|.define KBASE, edi // Must be C callee-save.
24|.define KBASEa, KBASE
25|.define PC, esi // Must be C callee-save.
26|.define PCa, PC
27|.define DISPATCH, ebx // Must be C callee-save.
28|.elif X64WIN
29|.define KBASE, edi // Must be C callee-save.
30|.define KBASEa, rdi
31|.define PC, esi // Must be C callee-save.
32|.define PCa, rsi
33|.define DISPATCH, ebx // Must be C callee-save.
34|.else
35|.define KBASE, r15d // Must be C callee-save.
36|.define KBASEa, r15
37|.define PC, ebx // Must be C callee-save.
38|.define PCa, rbx
39|.define DISPATCH, r14d // Must be C callee-save.
40|.endif
41|
42|.define RA, ecx
43|.define RAH, ch
44|.define RAL, cl
45|.define RB, ebp // Must be ebp (C callee-save).
46|.define RC, eax // Must be eax (fcomparepp and others).
47|.define RCW, ax
48|.define RCH, ah
49|.define RCL, al
50|.define OP, RB
51|.define RD, RC
52|.define RDW, RCW
53|.define RDL, RCL
54|.if X64
55|.define RAa, rcx
56|.define RBa, rbp
57|.define RCa, rax
58|.define RDa, rax
59|.else
60|.define RAa, RA
61|.define RBa, RB
62|.define RCa, RC
63|.define RDa, RD
64|.endif
65|
66|.if not X64
67|.define FCARG1, ecx // x86 fastcall arguments.
68|.define FCARG2, edx
69|.elif X64WIN
70|.define CARG1, rcx // x64/WIN64 C call arguments.
71|.define CARG2, rdx
72|.define CARG3, r8
73|.define CARG4, r9
74|.define CARG1d, ecx
75|.define CARG2d, edx
76|.define CARG3d, r8d
77|.define CARG4d, r9d
78|.define FCARG1, CARG1d // Upwards compatible to x86 fastcall.
79|.define FCARG2, CARG2d
80|.else
81|.define CARG1, rdi // x64/POSIX C call arguments.
82|.define CARG2, rsi
83|.define CARG3, rdx
84|.define CARG4, rcx
85|.define CARG5, r8
86|.define CARG6, r9
87|.define CARG1d, edi
88|.define CARG2d, esi
89|.define CARG3d, edx
90|.define CARG4d, ecx
91|.define CARG5d, r8d
92|.define CARG6d, r9d
93|.define FCARG1, CARG1d // Simulate x86 fastcall.
94|.define FCARG2, CARG2d
95|.endif
96|
97|// Type definitions. Some of these are only used for documentation.
98|.type L, lua_State
99|.type GL, global_State
100|.type TVALUE, TValue
101|.type GCOBJ, GCobj
102|.type STR, GCstr
103|.type TAB, GCtab
104|.type LFUNC, GCfuncL
105|.type CFUNC, GCfuncC
106|.type PROTO, GCproto
107|.type UPVAL, GCupval
108|.type NODE, Node
109|.type NARGS, int
110|.type TRACE, GCtrace
111|
112|// Stack layout while in interpreter. Must match with lj_frame.h.
113|//-----------------------------------------------------------------------
114|.if not X64 // x86 stack layout.
115|
116|.define CFRAME_SPACE, aword*7 // Delta for esp (see <--).
117|.macro saveregs_
118| push edi; push esi; push ebx
119| sub esp, CFRAME_SPACE
120|.endmacro
121|.macro saveregs
122| push ebp; saveregs_
123|.endmacro
124|.macro restoreregs
125| add esp, CFRAME_SPACE
126| pop ebx; pop esi; pop edi; pop ebp
127|.endmacro
128|
129|.define SAVE_ERRF, aword [esp+aword*15] // vm_pcall/vm_cpcall only.
130|.define SAVE_NRES, aword [esp+aword*14]
131|.define SAVE_CFRAME, aword [esp+aword*13]
132|.define SAVE_L, aword [esp+aword*12]
133|//----- 16 byte aligned, ^^^ arguments from C caller
134|.define SAVE_RET, aword [esp+aword*11] //<-- esp entering interpreter.
135|.define SAVE_R4, aword [esp+aword*10]
136|.define SAVE_R3, aword [esp+aword*9]
137|.define SAVE_R2, aword [esp+aword*8]
138|//----- 16 byte aligned
139|.define SAVE_R1, aword [esp+aword*7] //<-- esp after register saves.
140|.define SAVE_PC, aword [esp+aword*6]
141|.define TMP2, aword [esp+aword*5]
142|.define TMP1, aword [esp+aword*4]
143|//----- 16 byte aligned
144|.define ARG4, aword [esp+aword*3]
145|.define ARG3, aword [esp+aword*2]
146|.define ARG2, aword [esp+aword*1]
147|.define ARG1, aword [esp] //<-- esp while in interpreter.
148|//----- 16 byte aligned, ^^^ arguments for C callee
149|
150|// FPARGx overlaps ARGx and ARG(x+1) on x86.
151|.define FPARG3, qword [esp+qword*1]
152|.define FPARG1, qword [esp]
153|// TMPQ overlaps TMP1/TMP2. ARG5/MULTRES overlap TMP1/TMP2 (and TMPQ).
154|.define TMPQ, qword [esp+aword*4]
155|.define TMP3, ARG4
156|.define ARG5, TMP1
157|.define TMPa, TMP1
158|.define MULTRES, TMP2
159|
160|// Arguments for vm_call and vm_pcall.
161|.define INARG_BASE, SAVE_CFRAME // Overwritten by SAVE_CFRAME!
162|
163|// Arguments for vm_cpcall.
164|.define INARG_CP_CALL, SAVE_ERRF
165|.define INARG_CP_UD, SAVE_NRES
166|.define INARG_CP_FUNC, SAVE_CFRAME
167|
168|//-----------------------------------------------------------------------
169|.elif X64WIN // x64/Windows stack layout
170|
171|.define CFRAME_SPACE, aword*5 // Delta for rsp (see <--).
172|.macro saveregs_
173| push rdi; push rsi; push rbx
174| sub rsp, CFRAME_SPACE
175|.endmacro
176|.macro saveregs
177| push rbp; saveregs_
178|.endmacro
179|.macro restoreregs
180| add rsp, CFRAME_SPACE
181| pop rbx; pop rsi; pop rdi; pop rbp
182|.endmacro
183|
184|.define SAVE_CFRAME, aword [rsp+aword*13]
185|.define SAVE_PC, dword [rsp+dword*25]
186|.define SAVE_L, dword [rsp+dword*24]
187|.define SAVE_ERRF, dword [rsp+dword*23]
188|.define SAVE_NRES, dword [rsp+dword*22]
189|.define TMP2, dword [rsp+dword*21]
190|.define TMP1, dword [rsp+dword*20]
191|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by interpreter
192|.define SAVE_RET, aword [rsp+aword*9] //<-- rsp entering interpreter.
193|.define SAVE_R4, aword [rsp+aword*8]
194|.define SAVE_R3, aword [rsp+aword*7]
195|.define SAVE_R2, aword [rsp+aword*6]
196|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves.
197|.define ARG5, aword [rsp+aword*4]
198|.define CSAVE_4, aword [rsp+aword*3]
199|.define CSAVE_3, aword [rsp+aword*2]
200|.define CSAVE_2, aword [rsp+aword*1]
201|.define CSAVE_1, aword [rsp] //<-- rsp while in interpreter.
202|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by callee
203|
204|// TMPQ overlaps TMP1/TMP2. MULTRES overlaps TMP2 (and TMPQ).
205|.define TMPQ, qword [rsp+aword*10]
206|.define MULTRES, TMP2
207|.define TMPa, ARG5
208|.define ARG5d, dword [rsp+aword*4]
209|.define TMP3, ARG5d
210|
211|//-----------------------------------------------------------------------
212|.else // x64/POSIX stack layout
213|
214|.define CFRAME_SPACE, aword*5 // Delta for rsp (see <--).
215|.macro saveregs_
216| push rbx; push r15; push r14
217| sub rsp, CFRAME_SPACE
218|.endmacro
219|.macro saveregs
220| push rbp; saveregs_
221|.endmacro
222|.macro restoreregs
223| add rsp, CFRAME_SPACE
224| pop r14; pop r15; pop rbx; pop rbp
225|.endmacro
226|
227|//----- 16 byte aligned,
228|.define SAVE_RET, aword [rsp+aword*9] //<-- rsp entering interpreter.
229|.define SAVE_R4, aword [rsp+aword*8]
230|.define SAVE_R3, aword [rsp+aword*7]
231|.define SAVE_R2, aword [rsp+aword*6]
232|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves.
233|.define SAVE_CFRAME, aword [rsp+aword*4]
234|.define SAVE_PC, dword [rsp+dword*7]
235|.define SAVE_L, dword [rsp+dword*6]
236|.define SAVE_ERRF, dword [rsp+dword*5]
237|.define SAVE_NRES, dword [rsp+dword*4]
238|.define TMPa, aword [rsp+aword*1]
239|.define TMP2, dword [rsp+dword*1]
240|.define TMP1, dword [rsp] //<-- rsp while in interpreter.
241|//----- 16 byte aligned
242|
243|// TMPQ overlaps TMP1/TMP2. MULTRES overlaps TMP2 (and TMPQ).
244|.define TMPQ, qword [rsp]
245|.define TMP3, dword [rsp+aword*1]
246|.define MULTRES, TMP2
247|
248|.endif
249|
250|//-----------------------------------------------------------------------
251|
252|// Instruction headers.
253|.macro ins_A; .endmacro
254|.macro ins_AD; .endmacro
255|.macro ins_AJ; .endmacro
256|.macro ins_ABC; movzx RB, RCH; movzx RC, RCL; .endmacro
257|.macro ins_AB_; movzx RB, RCH; .endmacro
258|.macro ins_A_C; movzx RC, RCL; .endmacro
259|.macro ins_AND; not RDa; .endmacro
260|
261|// Instruction decode+dispatch. Carefully tuned (nope, lodsd is not faster).
262|.macro ins_NEXT
263| mov RC, [PC]
264| movzx RA, RCH
265| movzx OP, RCL
266| add PC, 4
267| shr RC, 16
268|.if X64
269| jmp aword [DISPATCH+OP*8]
270|.else
271| jmp aword [DISPATCH+OP*4]
272|.endif
273|.endmacro
274|
275|// Instruction footer.
276|.if 1
277| // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
278| .define ins_next, ins_NEXT
279| .define ins_next_, ins_NEXT
280|.else
281| // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
282| // Affects only certain kinds of benchmarks (and only with -j off).
283| // Around 10%-30% slower on Core2, a lot more slower on P4.
284| .macro ins_next
285| jmp ->ins_next
286| .endmacro
287| .macro ins_next_
288| ->ins_next:
289| ins_NEXT
290| .endmacro
291|.endif
292|
293|// Call decode and dispatch.
294|.macro ins_callt
295| // BASE = new base, RB = LFUNC, RD = nargs+1, [BASE-4] = PC
296| mov PC, LFUNC:RB->pc
297| mov RA, [PC]
298| movzx OP, RAL
299| movzx RA, RAH
300| add PC, 4
301|.if X64
302| jmp aword [DISPATCH+OP*8]
303|.else
304| jmp aword [DISPATCH+OP*4]
305|.endif
306|.endmacro
307|
308|.macro ins_call
309| // BASE = new base, RB = LFUNC, RD = nargs+1
310| mov [BASE-4], PC
311| ins_callt
312|.endmacro
313|
314|//-----------------------------------------------------------------------
315|
316|// Macros to test operand types.
317|.macro checktp, reg, tp; cmp dword [BASE+reg*8+4], tp; .endmacro
318|.macro checknum, reg, target; checktp reg, LJ_TISNUM; jae target; .endmacro
319|.macro checkint, reg, target; checktp reg, LJ_TISNUM; jne target; .endmacro
320|.macro checkstr, reg, target; checktp reg, LJ_TSTR; jne target; .endmacro
321|.macro checktab, reg, target; checktp reg, LJ_TTAB; jne target; .endmacro
322|
323|// These operands must be used with movzx.
324|.define PC_OP, byte [PC-4]
325|.define PC_RA, byte [PC-3]
326|.define PC_RB, byte [PC-1]
327|.define PC_RC, byte [PC-2]
328|.define PC_RD, word [PC-2]
329|
330|.macro branchPC, reg
331| lea PC, [PC+reg*4-BCBIAS_J*4]
332|.endmacro
333|
334|// Assumes DISPATCH is relative to GL.
335#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
336#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
337|
338#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
339|
340|// Decrement hashed hotcount and trigger trace recorder if zero.
341|.macro hotloop, reg
342| mov reg, PC
343| shr reg, 1
344| and reg, HOTCOUNT_PCMASK
345| sub word [DISPATCH+reg+GG_DISP2HOT], HOTCOUNT_LOOP
346| jb ->vm_hotloop
347|.endmacro
348|
349|.macro hotcall, reg
350| mov reg, PC
351| shr reg, 1
352| and reg, HOTCOUNT_PCMASK
353| sub word [DISPATCH+reg+GG_DISP2HOT], HOTCOUNT_CALL
354| jb ->vm_hotcall
355|.endmacro
356|
357|// Set current VM state.
358|.macro set_vmstate, st
359| mov dword [DISPATCH+DISPATCH_GL(vmstate)], ~LJ_VMST_..st
360|.endmacro
361|
362|// Annoying x87 stuff: support for two compare variants.
363|.macro fcomparepp // Compare and pop st0 >< st1.
364||if (cmov) {
365| fucomip st1
366| fpop
367||} else {
368| fucompp
369| fnstsw ax // eax modified!
370| sahf
371||}
372|.endmacro
373|
374|.macro fdup; fld st0; .endmacro
375|.macro fpop1; fstp st1; .endmacro
376|
377|// Synthesize SSE FP constants.
378|.macro sseconst_abs, reg, tmp // Synthesize abs mask.
379|.if X64
380| mov64 tmp, U64x(7fffffff,ffffffff); movd reg, tmp
381|.else
382| pxor reg, reg; pcmpeqd reg, reg; psrlq reg, 1
383|.endif
384|.endmacro
385|
386|.macro sseconst_hi, reg, tmp, val // Synthesize hi-32 bit const.
387|.if X64
388| mov64 tmp, U64x(val,00000000); movd reg, tmp
389|.else
390| mov tmp, 0x .. val; movd reg, tmp; pshufd reg, reg, 0x51
391|.endif
392|.endmacro
393|
394|.macro sseconst_sign, reg, tmp // Synthesize sign mask.
395| sseconst_hi reg, tmp, 80000000
396|.endmacro
397|.macro sseconst_1, reg, tmp // Synthesize 1.0.
398| sseconst_hi reg, tmp, 3ff00000
399|.endmacro
400|.macro sseconst_m1, reg, tmp // Synthesize -1.0.
401| sseconst_hi reg, tmp, bff00000
402|.endmacro
403|.macro sseconst_2p52, reg, tmp // Synthesize 2^52.
404| sseconst_hi reg, tmp, 43300000
405|.endmacro
406|.macro sseconst_tobit, reg, tmp // Synthesize 2^52 + 2^51.
407| sseconst_hi reg, tmp, 43380000
408|.endmacro
409|
410|// Move table write barrier back. Overwrites reg.
411|.macro barrierback, tab, reg
412| and byte tab->marked, (uint8_t)~LJ_GC_BLACK // black2gray(tab)
413| mov reg, [DISPATCH+DISPATCH_GL(gc.grayagain)]
414| mov [DISPATCH+DISPATCH_GL(gc.grayagain)], tab
415| mov tab->gclist, reg
416|.endmacro
417|
418|//-----------------------------------------------------------------------
419
420/* Generate subroutines used by opcodes and other parts of the VM. */
421/* The .code_sub section should be last to help static branch prediction. */
422static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
423{
424 |.code_sub
425 |
426 |//-----------------------------------------------------------------------
427 |//-- Return handling ----------------------------------------------------
428 |//-----------------------------------------------------------------------
429 |
430 |->vm_returnp:
431 | test PC, FRAME_P
432 | jz ->cont_dispatch
433 |
434 | // Return from pcall or xpcall fast func.
435 | and PC, -8
436 | sub BASE, PC // Restore caller base.
437 | lea RAa, [RA+PC-8] // Rebase RA and prepend one result.
438 | mov PC, [BASE-4] // Fetch PC of previous frame.
439 | // Prepending may overwrite the pcall frame, so do it at the end.
440 | mov dword [BASE+RA+4], LJ_TTRUE // Prepend true to results.
441 |
442 |->vm_returnc:
443 | add RD, 1 // RD = nresults+1
444 | mov MULTRES, RD
445 | test PC, FRAME_TYPE
446 | jz ->BC_RET_Z // Handle regular return to Lua.
447 |
448 |->vm_return:
449 | // BASE = base, RA = resultofs, RD = nresults+1 (= MULTRES), PC = return
450 | xor PC, FRAME_C
451 | test PC, FRAME_TYPE
452 | jnz ->vm_returnp
453 |
454 | // Return to C.
455 | set_vmstate C
456 | and PC, -8
457 | sub PC, BASE
458 | neg PC // Previous base = BASE - delta.
459 |
460 | sub RD, 1
461 | jz >2
462 |1: // Move results down.
463 |.if X64
464 | mov RBa, [BASE+RA]
465 | mov [BASE-8], RBa
466 |.else
467 | mov RB, [BASE+RA]
468 | mov [BASE-8], RB
469 | mov RB, [BASE+RA+4]
470 | mov [BASE-4], RB
471 |.endif
472 | add BASE, 8
473 | sub RD, 1
474 | jnz <1
475 |2:
476 | mov L:RB, SAVE_L
477 | mov L:RB->base, PC
478 |3:
479 | mov RD, MULTRES
480 | mov RA, SAVE_NRES // RA = wanted nresults+1
481 |4:
482 | cmp RA, RD
483 | jne >6 // More/less results wanted?
484 |5:
485 | sub BASE, 8
486 | mov L:RB->top, BASE
487 |
488 |->vm_leave_cp:
489 | mov RAa, SAVE_CFRAME // Restore previous C frame.
490 | mov L:RB->cframe, RAa
491 | xor eax, eax // Ok return status for vm_pcall.
492 |
493 |->vm_leave_unw:
494 | restoreregs
495 | ret
496 |
497 |6:
498 | jb >7 // Less results wanted?
499 | // More results wanted. Check stack size and fill up results with nil.
500 | cmp BASE, L:RB->maxstack
501 | ja >8
502 | mov dword [BASE-4], LJ_TNIL
503 | add BASE, 8
504 | add RD, 1
505 | jmp <4
506 |
507 |7: // Less results wanted.
508 | test RA, RA
509 | jz <5 // But check for LUA_MULTRET+1.
510 | sub RA, RD // Negative result!
511 | lea BASE, [BASE+RA*8] // Correct top.
512 | jmp <5
513 |
514 |8: // Corner case: need to grow stack for filling up results.
515 | // This can happen if:
516 | // - A C function grows the stack (a lot).
517 | // - The GC shrinks the stack in between.
518 | // - A return back from a lua_call() with (high) nresults adjustment.
519 | mov L:RB->top, BASE // Save current top held in BASE (yes).
520 | mov MULTRES, RD // Need to fill only remainder with nil.
521 | mov FCARG2, RA
522 | mov FCARG1, L:RB
523 | call extern lj_state_growstack@8 // (lua_State *L, int n)
524 | mov BASE, L:RB->top // Need the (realloced) L->top in BASE.
525 | jmp <3
526 |
527 |->vm_unwind_c@8: // Unwind C stack, return from vm_pcall.
528 | // (void *cframe, int errcode)
529 |.if X64
530 | mov eax, CARG2d // Error return status for vm_pcall.
531 | mov rsp, CARG1
532 |.else
533 | mov eax, FCARG2 // Error return status for vm_pcall.
534 | mov esp, FCARG1
535 |.endif
536 |->vm_unwind_c_eh: // Landing pad for external unwinder.
537 | mov L:RB, SAVE_L
538 | mov GL:RB, L:RB->glref
539 | mov dword GL:RB->vmstate, ~LJ_VMST_C
540 | jmp ->vm_leave_unw
541 |
542 |->vm_unwind_rethrow:
543 |.if X64 and not X64WIN
544 | mov FCARG1, SAVE_L
545 | mov FCARG2, eax
546 | restoreregs
547 | jmp extern lj_err_throw@8 // (lua_State *L, int errcode)
548 |.endif
549 |
550 |->vm_unwind_ff@4: // Unwind C stack, return from ff pcall.
551 | // (void *cframe)
552 |.if X64
553 | and CARG1, CFRAME_RAWMASK
554 | mov rsp, CARG1
555 |.else
556 | and FCARG1, CFRAME_RAWMASK
557 | mov esp, FCARG1
558 |.endif
559 |->vm_unwind_ff_eh: // Landing pad for external unwinder.
560 | mov L:RB, SAVE_L
561 | mov RAa, -8 // Results start at BASE+RA = BASE-8.
562 | mov RD, 1+1 // Really 1+2 results, incr. later.
563 | mov BASE, L:RB->base
564 | mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
565 | add DISPATCH, GG_G2DISP
566 | mov PC, [BASE-4] // Fetch PC of previous frame.
567 | mov dword [BASE-4], LJ_TFALSE // Prepend false to error message.
568 | set_vmstate INTERP
569 | jmp ->vm_returnc // Increments RD/MULTRES and returns.
570 |
571 |//-----------------------------------------------------------------------
572 |//-- Grow stack for calls -----------------------------------------------
573 |//-----------------------------------------------------------------------
574 |
575 |->vm_growstack_c: // Grow stack for C function.
576 | mov FCARG2, LUA_MINSTACK
577 | jmp >2
578 |
579 |->vm_growstack_v: // Grow stack for vararg Lua function.
580 | sub RD, 8
581 | jmp >1
582 |
583 |->vm_growstack_f: // Grow stack for fixarg Lua function.
584 | // BASE = new base, RD = nargs+1, RB = L, PC = first PC
585 | lea RD, [BASE+NARGS:RD*8-8]
586 |1:
587 | movzx RA, byte [PC-4+PC2PROTO(framesize)]
588 | add PC, 4 // Must point after first instruction.
589 | mov L:RB->base, BASE
590 | mov L:RB->top, RD
591 | mov SAVE_PC, PC
592 | mov FCARG2, RA
593 |2:
594 | // RB = L, L->base = new base, L->top = top
595 | mov FCARG1, L:RB
596 | call extern lj_state_growstack@8 // (lua_State *L, int n)
597 | mov BASE, L:RB->base
598 | mov RD, L:RB->top
599 | mov LFUNC:RB, [BASE-8]
600 | sub RD, BASE
601 | shr RD, 3
602 | add NARGS:RD, 1
603 | // BASE = new base, RB = LFUNC, RD = nargs+1
604 | ins_callt // Just retry the call.
605 |
606 |//-----------------------------------------------------------------------
607 |//-- Entry points into the assembler VM ---------------------------------
608 |//-----------------------------------------------------------------------
609 |
610 |->vm_resume: // Setup C frame and resume thread.
611 | // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
612 | saveregs
613 |.if X64
614 | mov L:RB, CARG1d // Caveat: CARG1d may be RA.
615 | mov SAVE_L, CARG1d
616 | mov RA, CARG2d
617 |.else
618 | mov L:RB, SAVE_L
619 | mov RA, INARG_BASE // Caveat: overlaps SAVE_CFRAME!
620 |.endif
621 | mov PC, FRAME_CP
622 | xor RD, RD
623 | lea KBASEa, [esp+CFRAME_RESUME]
624 | mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
625 | add DISPATCH, GG_G2DISP
626 | mov L:RB->cframe, KBASEa
627 | mov SAVE_PC, RD // Any value outside of bytecode is ok.
628 | mov SAVE_CFRAME, RDa
629 |.if X64
630 | mov SAVE_NRES, RD
631 | mov SAVE_ERRF, RD
632 |.endif
633 | cmp byte L:RB->status, RDL
634 | je >3 // Initial resume (like a call).
635 |
636 | // Resume after yield (like a return).
637 | set_vmstate INTERP
638 | mov byte L:RB->status, RDL
639 | mov BASE, L:RB->base
640 | mov RD, L:RB->top
641 | sub RD, RA
642 | shr RD, 3
643 | add RD, 1 // RD = nresults+1
644 | sub RA, BASE // RA = resultofs
645 | mov PC, [BASE-4]
646 | mov MULTRES, RD
647 | test PC, FRAME_TYPE
648 | jz ->BC_RET_Z
649 | jmp ->vm_return
650 |
651 |->vm_pcall: // Setup protected C frame and enter VM.
652 | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
653 | saveregs
654 | mov PC, FRAME_CP
655 |.if X64
656 | mov SAVE_ERRF, CARG4d
657 |.endif
658 | jmp >1
659 |
660 |->vm_call: // Setup C frame and enter VM.
661 | // (lua_State *L, TValue *base, int nres1)
662 | saveregs
663 | mov PC, FRAME_C
664 |
665 |1: // Entry point for vm_pcall above (PC = ftype).
666 |.if X64
667 | mov SAVE_NRES, CARG3d
668 | mov L:RB, CARG1d // Caveat: CARG1d may be RA.
669 | mov SAVE_L, CARG1d
670 | mov RA, CARG2d
671 |.else
672 | mov L:RB, SAVE_L
673 | mov RA, INARG_BASE // Caveat: overlaps SAVE_CFRAME!
674 |.endif
675 |
676 | mov KBASEa, L:RB->cframe // Add our C frame to cframe chain.
677 | mov SAVE_CFRAME, KBASEa
678 | mov SAVE_PC, L:RB // Any value outside of bytecode is ok.
679 |.if X64
680 | mov L:RB->cframe, rsp
681 |.else
682 | mov L:RB->cframe, esp
683 |.endif
684 |
685 |2: // Entry point for vm_cpcall below (RA = base, RB = L, PC = ftype).
686 | mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
687 | add DISPATCH, GG_G2DISP
688 |
689 |3: // Entry point for vm_resume above (RA = base, RB = L, PC = ftype).
690 | set_vmstate INTERP
691 | mov BASE, L:RB->base // BASE = old base (used in vmeta_call).
692 | add PC, RA
693 | sub PC, BASE // PC = frame delta + frame type
694 |
695 | mov RD, L:RB->top
696 | sub RD, RA
697 | shr NARGS:RD, 3
698 | add NARGS:RD, 1 // RD = nargs+1
699 |
700 |->vm_call_dispatch:
701 | mov LFUNC:RB, [RA-8]
702 | cmp dword [RA-4], LJ_TFUNC
703 | jne ->vmeta_call // Ensure KBASE defined and != BASE.
704 |
705 |->vm_call_dispatch_f:
706 | mov BASE, RA
707 | ins_call
708 | // BASE = new base, RB = func, RD = nargs+1, PC = caller PC
709 |
710 |->vm_cpcall: // Setup protected C frame, call C.
711 | // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
712 | saveregs
713 |.if X64
714 | mov L:RB, CARG1d // Caveat: CARG1d may be RA.
715 | mov SAVE_L, CARG1d
716 |.else
717 | mov L:RB, SAVE_L
718 | // Caveat: INARG_CP_* and SAVE_CFRAME/SAVE_NRES/SAVE_ERRF overlap!
719 | mov RC, INARG_CP_UD // Get args before they are overwritten.
720 | mov RA, INARG_CP_FUNC
721 | mov BASE, INARG_CP_CALL
722 |.endif
723 | mov SAVE_PC, L:RB // Any value outside of bytecode is ok.
724 |
725 | mov KBASE, L:RB->stack // Compute -savestack(L, L->top).
726 | sub KBASE, L:RB->top
727 | mov SAVE_ERRF, 0 // No error function.
728 | mov SAVE_NRES, KBASE // Neg. delta means cframe w/o frame.
729 | // Handler may change cframe_nres(L->cframe) or cframe_errfunc(L->cframe).
730 |
731 |.if X64
732 | mov KBASEa, L:RB->cframe // Add our C frame to cframe chain.
733 | mov SAVE_CFRAME, KBASEa
734 | mov L:RB->cframe, rsp
735 |
736 | call CARG4 // (lua_State *L, lua_CFunction func, void *ud)
737 |.else
738 | mov ARG3, RC // Have to copy args downwards.
739 | mov ARG2, RA
740 | mov ARG1, L:RB
741 |
742 | mov KBASE, L:RB->cframe // Add our C frame to cframe chain.
743 | mov SAVE_CFRAME, KBASE
744 | mov L:RB->cframe, esp
745 |
746 | call BASE // (lua_State *L, lua_CFunction func, void *ud)
747 |.endif
748 | // TValue * (new base) or NULL returned in eax (RC).
749 | test RC, RC
750 | jz ->vm_leave_cp // No base? Just remove C frame.
751 | mov RA, RC
752 | mov PC, FRAME_CP
753 | jmp <2 // Else continue with the call.
754 |
755 |//-----------------------------------------------------------------------
756 |//-- Metamethod handling ------------------------------------------------
757 |//-----------------------------------------------------------------------
758 |
759 |//-- Continuation dispatch ----------------------------------------------
760 |
761 |->cont_dispatch:
762 | // BASE = meta base, RA = resultofs, RD = nresults+1 (also in MULTRES)
763 | add RA, BASE
764 | and PC, -8
765 | mov RB, BASE
766 | sub BASE, PC // Restore caller BASE.
767 | mov dword [RA+RD*8-4], LJ_TNIL // Ensure one valid arg.
768 | mov RC, RA // ... in [RC]
769 | mov PC, [RB-12] // Restore PC from [cont|PC].
770 |.if X64
771 | movsxd RAa, dword [RB-16] // May be negative on WIN64 with debug.
772#if LJ_HASFFI
773 | cmp RA, 1
774 | jbe >1
775#endif
776 | lea KBASEa, qword [=>0]
777 | add RAa, KBASEa
778 |.else
779 | mov RA, dword [RB-16]
780#if LJ_HASFFI
781 | cmp RA, 1
782 | jbe >1
783#endif
784 |.endif
785 | mov LFUNC:KBASE, [BASE-8]
786 | mov KBASE, LFUNC:KBASE->pc
787 | mov KBASE, [KBASE+PC2PROTO(k)]
788 | // BASE = base, RC = result, RB = meta base
789 | jmp RAa // Jump to continuation.
790 |
791#if LJ_HASFFI
792 |1:
793 | je ->cont_ffi_callback // cont = 1: return from FFI callback.
794 | // cont = 0: Tail call from C function.
795 | sub RB, BASE
796 | shr RB, 3
797 | lea RD, [RB-1]
798 | jmp ->vm_call_tail
799#endif
800 |
801 |->cont_cat: // BASE = base, RC = result, RB = mbase
802 | movzx RA, PC_RB
803 | sub RB, 16
804 | lea RA, [BASE+RA*8]
805 | sub RA, RB
806 | je ->cont_ra
807 | neg RA
808 | shr RA, 3
809 |.if X64WIN
810 | mov CARG3d, RA
811 | mov L:CARG1d, SAVE_L
812 | mov L:CARG1d->base, BASE
813 | mov RCa, [RC]
814 | mov [RB], RCa
815 | mov CARG2d, RB
816 |.elif X64
817 | mov L:CARG1d, SAVE_L
818 | mov L:CARG1d->base, BASE
819 | mov CARG3d, RA
820 | mov RAa, [RC]
821 | mov [RB], RAa
822 | mov CARG2d, RB
823 |.else
824 | mov ARG3, RA
825 | mov RA, [RC+4]
826 | mov RC, [RC]
827 | mov [RB+4], RA
828 | mov [RB], RC
829 | mov ARG2, RB
830 |.endif
831 | jmp ->BC_CAT_Z
832 |
833 |//-- Table indexing metamethods -----------------------------------------
834 |
835 |->vmeta_tgets:
836 | mov TMP1, RC // RC = GCstr *
837 | mov TMP2, LJ_TSTR
838 | lea RCa, TMP1 // Store temp. TValue in TMP1/TMP2.
839 | cmp PC_OP, BC_GGET
840 | jne >1
841 | lea RA, [DISPATCH+DISPATCH_GL(tmptv)] // Store fn->l.env in g->tmptv.
842 | mov [RA], TAB:RB // RB = GCtab *
843 | mov dword [RA+4], LJ_TTAB
844 | mov RB, RA
845 | jmp >2
846 |
847 |->vmeta_tgetb:
848 | movzx RC, PC_RC
849 if (LJ_DUALNUM) {
850 | mov TMP2, LJ_TISNUM
851 | mov TMP1, RC
852 } else if (sse) {
853 | cvtsi2sd xmm0, RC
854 | movsd TMPQ, xmm0
855 } else {
856 |.if not X64
857 | mov ARG4, RC
858 | fild ARG4
859 | fstp TMPQ
860 |.endif
861 }
862 | lea RCa, TMPQ // Store temp. TValue in TMPQ.
863 | jmp >1
864 |
865 |->vmeta_tgetv:
866 | movzx RC, PC_RC // Reload TValue *k from RC.
867 | lea RC, [BASE+RC*8]
868 |1:
869 | movzx RB, PC_RB // Reload TValue *t from RB.
870 | lea RB, [BASE+RB*8]
871 |2:
872 |.if X64
873 | mov L:CARG1d, SAVE_L
874 | mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
875 | mov CARG2d, RB
876 | mov CARG3, RCa // May be 64 bit ptr to stack.
877 | mov L:RB, L:CARG1d
878 |.else
879 | mov ARG2, RB
880 | mov L:RB, SAVE_L
881 | mov ARG3, RC
882 | mov ARG1, L:RB
883 | mov L:RB->base, BASE
884 |.endif
885 | mov SAVE_PC, PC
886 | call extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
887 | // TValue * (finished) or NULL (metamethod) returned in eax (RC).
888 | mov BASE, L:RB->base
889 | test RC, RC
890 | jz >3
891 |->cont_ra: // BASE = base, RC = result
892 | movzx RA, PC_RA
893 |.if X64
894 | mov RBa, [RC]
895 | mov [BASE+RA*8], RBa
896 |.else
897 | mov RB, [RC+4]
898 | mov RC, [RC]
899 | mov [BASE+RA*8+4], RB
900 | mov [BASE+RA*8], RC
901 |.endif
902 | ins_next
903 |
904 |3: // Call __index metamethod.
905 | // BASE = base, L->top = new base, stack = cont/func/t/k
906 | mov RA, L:RB->top
907 | mov [RA-12], PC // [cont|PC]
908 | lea PC, [RA+FRAME_CONT]
909 | sub PC, BASE
910 | mov LFUNC:RB, [RA-8] // Guaranteed to be a function here.
911 | mov NARGS:RD, 2+1 // 2 args for func(t, k).
912 | jmp ->vm_call_dispatch_f
913 |
914 |//-----------------------------------------------------------------------
915 |
916 |->vmeta_tsets:
917 | mov TMP1, RC // RC = GCstr *
918 | mov TMP2, LJ_TSTR
919 | lea RCa, TMP1 // Store temp. TValue in TMP1/TMP2.
920 | cmp PC_OP, BC_GSET
921 | jne >1
922 | lea RA, [DISPATCH+DISPATCH_GL(tmptv)] // Store fn->l.env in g->tmptv.
923 | mov [RA], TAB:RB // RB = GCtab *
924 | mov dword [RA+4], LJ_TTAB
925 | mov RB, RA
926 | jmp >2
927 |
928 |->vmeta_tsetb:
929 | movzx RC, PC_RC
930 if (LJ_DUALNUM) {
931 | mov TMP2, LJ_TISNUM
932 | mov TMP1, RC
933 } else if (sse) {
934 | cvtsi2sd xmm0, RC
935 | movsd TMPQ, xmm0
936 } else {
937 |.if not X64
938 | mov ARG4, RC
939 | fild ARG4
940 | fstp TMPQ
941 |.endif
942 }
943 | lea RCa, TMPQ // Store temp. TValue in TMPQ.
944 | jmp >1
945 |
946 |->vmeta_tsetv:
947 | movzx RC, PC_RC // Reload TValue *k from RC.
948 | lea RC, [BASE+RC*8]
949 |1:
950 | movzx RB, PC_RB // Reload TValue *t from RB.
951 | lea RB, [BASE+RB*8]
952 |2:
953 |.if X64
954 | mov L:CARG1d, SAVE_L
955 | mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
956 | mov CARG2d, RB
957 | mov CARG3, RCa // May be 64 bit ptr to stack.
958 | mov L:RB, L:CARG1d
959 |.else
960 | mov ARG2, RB
961 | mov L:RB, SAVE_L
962 | mov ARG3, RC
963 | mov ARG1, L:RB
964 | mov L:RB->base, BASE
965 |.endif
966 | mov SAVE_PC, PC
967 | call extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
968 | // TValue * (finished) or NULL (metamethod) returned in eax (RC).
969 | mov BASE, L:RB->base
970 | test RC, RC
971 | jz >3
972 | // NOBARRIER: lj_meta_tset ensures the table is not black.
973 | movzx RA, PC_RA
974 |.if X64
975 | mov RBa, [BASE+RA*8]
976 | mov [RC], RBa
977 |.else
978 | mov RB, [BASE+RA*8+4]
979 | mov RA, [BASE+RA*8]
980 | mov [RC+4], RB
981 | mov [RC], RA
982 |.endif
983 |->cont_nop: // BASE = base, (RC = result)
984 | ins_next
985 |
986 |3: // Call __newindex metamethod.
987 | // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
988 | mov RA, L:RB->top
989 | mov [RA-12], PC // [cont|PC]
990 | movzx RC, PC_RA
991 | // Copy value to third argument.
992 |.if X64
993 | mov RBa, [BASE+RC*8]
994 | mov [RA+16], RBa
995 |.else
996 | mov RB, [BASE+RC*8+4]
997 | mov RC, [BASE+RC*8]
998 | mov [RA+20], RB
999 | mov [RA+16], RC
1000 |.endif
1001 | lea PC, [RA+FRAME_CONT]
1002 | sub PC, BASE
1003 | mov LFUNC:RB, [RA-8] // Guaranteed to be a function here.
1004 | mov NARGS:RD, 3+1 // 3 args for func(t, k, v).
1005 | jmp ->vm_call_dispatch_f
1006 |
1007 |//-- Comparison metamethods ---------------------------------------------
1008 |
1009 |->vmeta_comp:
1010 |.if X64
1011 | mov L:RB, SAVE_L
1012 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d == BASE.
1013 |.if X64WIN
1014 | lea CARG3d, [BASE+RD*8]
1015 | lea CARG2d, [BASE+RA*8]
1016 |.else
1017 | lea CARG2d, [BASE+RA*8]
1018 | lea CARG3d, [BASE+RD*8]
1019 |.endif
1020 | mov CARG1d, L:RB // Caveat: CARG1d/CARG4d == RA.
1021 | movzx CARG4d, PC_OP
1022 |.else
1023 | movzx RB, PC_OP
1024 | lea RD, [BASE+RD*8]
1025 | lea RA, [BASE+RA*8]
1026 | mov ARG4, RB
1027 | mov L:RB, SAVE_L
1028 | mov ARG3, RD
1029 | mov ARG2, RA
1030 | mov ARG1, L:RB
1031 | mov L:RB->base, BASE
1032 |.endif
1033 | mov SAVE_PC, PC
1034 | call extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
1035 | // 0/1 or TValue * (metamethod) returned in eax (RC).
1036 |3:
1037 | mov BASE, L:RB->base
1038 | cmp RC, 1
1039 | ja ->vmeta_binop
1040 |4:
1041 | lea PC, [PC+4]
1042 | jb >6
1043 |5:
1044 | movzx RD, PC_RD
1045 | branchPC RD
1046 |6:
1047 | ins_next
1048 |
1049 |->cont_condt: // BASE = base, RC = result
1050 | add PC, 4
1051 | cmp dword [RC+4], LJ_TISTRUECOND // Branch if result is true.
1052 | jb <5
1053 | jmp <6
1054 |
1055 |->cont_condf: // BASE = base, RC = result
1056 | cmp dword [RC+4], LJ_TISTRUECOND // Branch if result is false.
1057 | jmp <4
1058 |
1059 |->vmeta_equal:
1060 | sub PC, 4
1061 |.if X64WIN
1062 | mov CARG3d, RD
1063 | mov CARG4d, RB
1064 | mov L:RB, SAVE_L
1065 | mov L:RB->base, BASE // Caveat: CARG2d == BASE.
1066 | mov CARG2d, RA
1067 | mov CARG1d, L:RB // Caveat: CARG1d == RA.
1068 |.elif X64
1069 | mov CARG2d, RA
1070 | mov CARG4d, RB // Caveat: CARG4d == RA.
1071 | mov L:RB, SAVE_L
1072 | mov L:RB->base, BASE // Caveat: CARG3d == BASE.
1073 | mov CARG3d, RD
1074 | mov CARG1d, L:RB
1075 |.else
1076 | mov ARG4, RB
1077 | mov L:RB, SAVE_L
1078 | mov ARG3, RD
1079 | mov ARG2, RA
1080 | mov ARG1, L:RB
1081 | mov L:RB->base, BASE
1082 |.endif
1083 | mov SAVE_PC, PC
1084 | call extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
1085 | // 0/1 or TValue * (metamethod) returned in eax (RC).
1086 | jmp <3
1087 |
1088 |->vmeta_equal_cd:
1089#if LJ_HASFFI
1090 | sub PC, 4
1091 | mov L:RB, SAVE_L
1092 | mov L:RB->base, BASE
1093 | mov FCARG1, L:RB
1094 | mov FCARG2, dword [PC-4]
1095 | mov SAVE_PC, PC
1096 | call extern lj_meta_equal_cd@8 // (lua_State *L, BCIns ins)
1097 | // 0/1 or TValue * (metamethod) returned in eax (RC).
1098 | jmp <3
1099#endif
1100 |
1101 |//-- Arithmetic metamethods ---------------------------------------------
1102 |
1103 |->vmeta_arith_vno:
1104#if LJ_DUALNUM
1105 | movzx RB, PC_RB
1106#endif
1107 |->vmeta_arith_vn:
1108 | lea RC, [KBASE+RC*8]
1109 | jmp >1
1110 |
1111 |->vmeta_arith_nvo:
1112#if LJ_DUALNUM
1113 | movzx RC, PC_RC
1114#endif
1115 |->vmeta_arith_nv:
1116 | lea RC, [KBASE+RC*8]
1117 | lea RB, [BASE+RB*8]
1118 | xchg RB, RC
1119 | jmp >2
1120 |
1121 |->vmeta_unm:
1122 | lea RC, [BASE+RD*8]
1123 | mov RB, RC
1124 | jmp >2
1125 |
1126 |->vmeta_arith_vvo:
1127#if LJ_DUALNUM
1128 | movzx RB, PC_RB
1129#endif
1130 |->vmeta_arith_vv:
1131 | lea RC, [BASE+RC*8]
1132 |1:
1133 | lea RB, [BASE+RB*8]
1134 |2:
1135 | lea RA, [BASE+RA*8]
1136 |.if X64WIN
1137 | mov CARG3d, RB
1138 | mov CARG4d, RC
1139 | movzx RC, PC_OP
1140 | mov ARG5d, RC
1141 | mov L:RB, SAVE_L
1142 | mov L:RB->base, BASE // Caveat: CARG2d == BASE.
1143 | mov CARG2d, RA
1144 | mov CARG1d, L:RB // Caveat: CARG1d == RA.
1145 |.elif X64
1146 | movzx CARG5d, PC_OP
1147 | mov CARG2d, RA
1148 | mov CARG4d, RC // Caveat: CARG4d == RA.
1149 | mov L:CARG1d, SAVE_L
1150 | mov L:CARG1d->base, BASE // Caveat: CARG3d == BASE.
1151 | mov CARG3d, RB
1152 | mov L:RB, L:CARG1d
1153 |.else
1154 | mov ARG3, RB
1155 | mov L:RB, SAVE_L
1156 | mov ARG4, RC
1157 | movzx RC, PC_OP
1158 | mov ARG2, RA
1159 | mov ARG5, RC
1160 | mov ARG1, L:RB
1161 | mov L:RB->base, BASE
1162 |.endif
1163 | mov SAVE_PC, PC
1164 | call extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
1165 | // NULL (finished) or TValue * (metamethod) returned in eax (RC).
1166 | mov BASE, L:RB->base
1167 | test RC, RC
1168 | jz ->cont_nop
1169 |
1170 | // Call metamethod for binary op.
1171 |->vmeta_binop:
1172 | // BASE = base, RC = new base, stack = cont/func/o1/o2
1173 | mov RA, RC
1174 | sub RC, BASE
1175 | mov [RA-12], PC // [cont|PC]
1176 | lea PC, [RC+FRAME_CONT]
1177 | mov NARGS:RD, 2+1 // 2 args for func(o1, o2).
1178 | jmp ->vm_call_dispatch
1179 |
1180 |->vmeta_len:
1181 | mov L:RB, SAVE_L
1182 | mov L:RB->base, BASE
1183 | lea FCARG2, [BASE+RD*8] // Caveat: FCARG2 == BASE
1184 | mov L:FCARG1, L:RB
1185 | mov SAVE_PC, PC
1186 | call extern lj_meta_len@8 // (lua_State *L, TValue *o)
1187 | // NULL (retry) or TValue * (metamethod) returned in eax (RC).
1188 | mov BASE, L:RB->base
1189#ifdef LUAJIT_ENABLE_LUA52COMPAT
1190 | test RC, RC
1191 | jne ->vmeta_binop // Binop call for compatibility.
1192 | movzx RD, PC_RD
1193 | mov TAB:FCARG1, [BASE+RD*8]
1194 | jmp ->BC_LEN_Z
1195#else
1196 | jmp ->vmeta_binop // Binop call for compatibility.
1197#endif
1198 |
1199 |//-- Call metamethod ----------------------------------------------------
1200 |
1201 |->vmeta_call_ra:
1202 | lea RA, [BASE+RA*8+8]
1203 |->vmeta_call: // Resolve and call __call metamethod.
1204 | // BASE = old base, RA = new base, RC = nargs+1, PC = return
1205 | mov TMP2, RA // Save RA, RC for us.
1206 | mov TMP1, NARGS:RD
1207 | sub RA, 8
1208 |.if X64
1209 | mov L:RB, SAVE_L
1210 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
1211 | mov CARG2d, RA
1212 | lea CARG3d, [RA+NARGS:RD*8]
1213 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
1214 |.else
1215 | lea RC, [RA+NARGS:RD*8]
1216 | mov L:RB, SAVE_L
1217 | mov ARG2, RA
1218 | mov ARG3, RC
1219 | mov ARG1, L:RB
1220 | mov L:RB->base, BASE // This is the callers base!
1221 |.endif
1222 | mov SAVE_PC, PC
1223 | call extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
1224 | mov BASE, L:RB->base
1225 | mov RA, TMP2
1226 | mov NARGS:RD, TMP1
1227 | mov LFUNC:RB, [RA-8]
1228 | add NARGS:RD, 1
1229 | // This is fragile. L->base must not move, KBASE must always be defined.
1230 | cmp KBASE, BASE // Continue with CALLT if flag set.
1231 | je ->BC_CALLT_Z
1232 | mov BASE, RA
1233 | ins_call // Otherwise call resolved metamethod.
1234 |
1235 |//-- Argument coercion for 'for' statement ------------------------------
1236 |
1237 |->vmeta_for:
1238 | mov L:RB, SAVE_L
1239 | mov L:RB->base, BASE
1240 | mov FCARG2, RA // Caveat: FCARG2 == BASE
1241 | mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
1242 | mov SAVE_PC, PC
1243 | call extern lj_meta_for@8 // (lua_State *L, TValue *base)
1244 | mov BASE, L:RB->base
1245 | mov RC, [PC-4]
1246 | movzx RA, RCH
1247 | movzx OP, RCL
1248 | shr RC, 16
1249 |.if X64
1250 | jmp aword [DISPATCH+OP*8+GG_DISP2STATIC] // Retry FORI or JFORI.
1251 |.else
1252 | jmp aword [DISPATCH+OP*4+GG_DISP2STATIC] // Retry FORI or JFORI.
1253 |.endif
1254 |
1255 |//-----------------------------------------------------------------------
1256 |//-- Fast functions -----------------------------------------------------
1257 |//-----------------------------------------------------------------------
1258 |
1259 |.macro .ffunc, name
1260 |->ff_ .. name:
1261 |.endmacro
1262 |
1263 |.macro .ffunc_1, name
1264 |->ff_ .. name:
1265 | cmp NARGS:RD, 1+1; jb ->fff_fallback
1266 |.endmacro
1267 |
1268 |.macro .ffunc_2, name
1269 |->ff_ .. name:
1270 | cmp NARGS:RD, 2+1; jb ->fff_fallback
1271 |.endmacro
1272 |
1273 |.macro .ffunc_n, name
1274 | .ffunc_1 name
1275 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1276 | fld qword [BASE]
1277 |.endmacro
1278 |
1279 |.macro .ffunc_n, name, op
1280 | .ffunc_1 name
1281 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1282 | op
1283 | fld qword [BASE]
1284 |.endmacro
1285 |
1286 |.macro .ffunc_nsse, name, op
1287 | .ffunc_1 name
1288 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1289 | op xmm0, qword [BASE]
1290 |.endmacro
1291 |
1292 |.macro .ffunc_nsse, name
1293 | .ffunc_nsse name, movsd
1294 |.endmacro
1295 |
1296 |.macro .ffunc_nn, name
1297 | .ffunc_2 name
1298 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1299 | cmp dword [BASE+12], LJ_TISNUM; jae ->fff_fallback
1300 | fld qword [BASE]
1301 | fld qword [BASE+8]
1302 |.endmacro
1303 |
1304 |.macro .ffunc_nnsse, name
1305 | .ffunc_2 name
1306 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1307 | cmp dword [BASE+12], LJ_TISNUM; jae ->fff_fallback
1308 | movsd xmm0, qword [BASE]
1309 | movsd xmm1, qword [BASE+8]
1310 |.endmacro
1311 |
1312 |.macro .ffunc_nnr, name
1313 | .ffunc_2 name
1314 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1315 | cmp dword [BASE+12], LJ_TISNUM; jae ->fff_fallback
1316 | fld qword [BASE+8]
1317 | fld qword [BASE]
1318 |.endmacro
1319 |
1320 |// Inlined GC threshold check. Caveat: uses label 1.
1321 |.macro ffgccheck
1322 | mov RB, [DISPATCH+DISPATCH_GL(gc.total)]
1323 | cmp RB, [DISPATCH+DISPATCH_GL(gc.threshold)]
1324 | jb >1
1325 | call ->fff_gcstep
1326 |1:
1327 |.endmacro
1328 |
1329 |//-- Base library: checks -----------------------------------------------
1330 |
1331 |.ffunc_1 assert
1332 | mov RB, [BASE+4]
1333 | cmp RB, LJ_TISTRUECOND; jae ->fff_fallback
1334 | mov PC, [BASE-4]
1335 | mov MULTRES, RD
1336 | mov [BASE-4], RB
1337 | mov RB, [BASE]
1338 | mov [BASE-8], RB
1339 | sub RD, 2
1340 | jz >2
1341 | mov RA, BASE
1342 |1:
1343 | add RA, 8
1344 |.if X64
1345 | mov RBa, [RA]
1346 | mov [RA-8], RBa
1347 |.else
1348 | mov RB, [RA+4]
1349 | mov [RA-4], RB
1350 | mov RB, [RA]
1351 | mov [RA-8], RB
1352 |.endif
1353 | sub RD, 1
1354 | jnz <1
1355 |2:
1356 | mov RD, MULTRES
1357 | jmp ->fff_res_
1358 |
1359 |.ffunc_1 type
1360 | mov RB, [BASE+4]
1361 |.if X64
1362 | mov RA, RB
1363 | sar RA, 15
1364 | cmp RA, -2
1365 | je >3
1366 |.endif
1367 | mov RC, ~LJ_TNUMX
1368 | not RB
1369 | cmp RC, RB
1370 ||if (cmov) {
1371 | cmova RC, RB
1372 ||} else {
1373 | jbe >1; mov RC, RB; 1:
1374 ||}
1375 |2:
1376 | mov CFUNC:RB, [BASE-8]
1377 | mov STR:RC, [CFUNC:RB+RC*8+((char *)(&((GCfuncC *)0)->upvalue))]
1378 | mov PC, [BASE-4]
1379 | mov dword [BASE-4], LJ_TSTR
1380 | mov [BASE-8], STR:RC
1381 | jmp ->fff_res1
1382 |.if X64
1383 |3:
1384 | mov RC, ~LJ_TLIGHTUD
1385 | jmp <2
1386 |.endif
1387 |
1388 |//-- Base library: getters and setters ---------------------------------
1389 |
1390 |.ffunc_1 getmetatable
1391 | mov RB, [BASE+4]
1392 | mov PC, [BASE-4]
1393 | cmp RB, LJ_TTAB; jne >6
1394 |1: // Field metatable must be at same offset for GCtab and GCudata!
1395 | mov TAB:RB, [BASE]
1396 | mov TAB:RB, TAB:RB->metatable
1397 |2:
1398 | test TAB:RB, TAB:RB
1399 | mov dword [BASE-4], LJ_TNIL
1400 | jz ->fff_res1
1401 | mov STR:RC, [DISPATCH+DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable)]
1402 | mov dword [BASE-4], LJ_TTAB // Store metatable as default result.
1403 | mov [BASE-8], TAB:RB
1404 | mov RA, TAB:RB->hmask
1405 | and RA, STR:RC->hash
1406 | imul RA, #NODE
1407 | add NODE:RA, TAB:RB->node
1408 |3: // Rearranged logic, because we expect _not_ to find the key.
1409 | cmp dword NODE:RA->key.it, LJ_TSTR
1410 | jne >4
1411 | cmp dword NODE:RA->key.gcr, STR:RC
1412 | je >5
1413 |4:
1414 | mov NODE:RA, NODE:RA->next
1415 | test NODE:RA, NODE:RA
1416 | jnz <3
1417 | jmp ->fff_res1 // Not found, keep default result.
1418 |5:
1419 | mov RB, [RA+4]
1420 | cmp RB, LJ_TNIL; je ->fff_res1 // Ditto for nil value.
1421 | mov RC, [RA]
1422 | mov [BASE-4], RB // Return value of mt.__metatable.
1423 | mov [BASE-8], RC
1424 | jmp ->fff_res1
1425 |
1426 |6:
1427 | cmp RB, LJ_TUDATA; je <1
1428 |.if X64
1429 | cmp RB, LJ_TNUMX; ja >8
1430 | cmp RB, LJ_TISNUM; jbe >7
1431 | mov RB, LJ_TLIGHTUD
1432 | jmp >8
1433 |7:
1434 |.else
1435 | cmp RB, LJ_TISNUM; ja >8
1436 |.endif
1437 | mov RB, LJ_TNUMX
1438 |8:
1439 | not RB
1440 | mov TAB:RB, [DISPATCH+RB*4+DISPATCH_GL(gcroot[GCROOT_BASEMT])]
1441 | jmp <2
1442 |
1443 |.ffunc_2 setmetatable
1444 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1445 | // Fast path: no mt for table yet and not clearing the mt.
1446 | mov TAB:RB, [BASE]
1447 | cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
1448 | cmp dword [BASE+12], LJ_TTAB; jne ->fff_fallback
1449 | mov TAB:RC, [BASE+8]
1450 | mov TAB:RB->metatable, TAB:RC
1451 | mov PC, [BASE-4]
1452 | mov dword [BASE-4], LJ_TTAB // Return original table.
1453 | mov [BASE-8], TAB:RB
1454 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
1455 | jz >1
1456 | // Possible write barrier. Table is black, but skip iswhite(mt) check.
1457 | barrierback TAB:RB, RC
1458 |1:
1459 | jmp ->fff_res1
1460 |
1461 |.ffunc_2 rawget
1462 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1463 |.if X64WIN
1464 | mov RB, BASE // Save BASE.
1465 | lea CARG3d, [BASE+8]
1466 | mov CARG2d, [BASE] // Caveat: CARG2d == BASE.
1467 | mov CARG1d, SAVE_L
1468 |.elif X64
1469 | mov RB, BASE // Save BASE.
1470 | mov CARG2d, [BASE]
1471 | lea CARG3d, [BASE+8] // Caveat: CARG3d == BASE.
1472 | mov CARG1d, SAVE_L
1473 |.else
1474 | mov TAB:RD, [BASE]
1475 | mov L:RB, SAVE_L
1476 | mov ARG2, TAB:RD
1477 | mov ARG1, L:RB
1478 | mov RB, BASE // Save BASE.
1479 | add BASE, 8
1480 | mov ARG3, BASE
1481 |.endif
1482 | call extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
1483 | // cTValue * returned in eax (RD).
1484 | mov BASE, RB // Restore BASE.
1485 | // Copy table slot.
1486 |.if X64
1487 | mov RBa, [RD]
1488 | mov PC, [BASE-4]
1489 | mov [BASE-8], RBa
1490 |.else
1491 | mov RB, [RD]
1492 | mov RD, [RD+4]
1493 | mov PC, [BASE-4]
1494 | mov [BASE-8], RB
1495 | mov [BASE-4], RD
1496 |.endif
1497 | jmp ->fff_res1
1498 |
1499 |//-- Base library: conversions ------------------------------------------
1500 |
1501 |.ffunc tonumber
1502 | // Only handles the number case inline (without a base argument).
1503 | cmp NARGS:RD, 1+1; jne ->fff_fallback // Exactly one argument.
1504 | cmp dword [BASE+4], LJ_TISNUM
1505 if (LJ_DUALNUM) {
1506 | jne >1
1507 | mov RB, dword [BASE]; jmp ->fff_resi
1508 |1:
1509 | ja ->fff_fallback
1510 } else {
1511 | jae ->fff_fallback
1512 }
1513 if (sse) {
1514 | movsd xmm0, qword [BASE]; jmp ->fff_resxmm0
1515 } else {
1516 | fld qword [BASE]; jmp ->fff_resn
1517 }
1518 |
1519 |.ffunc_1 tostring
1520 | // Only handles the string or number case inline.
1521 | mov PC, [BASE-4]
1522 | cmp dword [BASE+4], LJ_TSTR; jne >3
1523 | // A __tostring method in the string base metatable is ignored.
1524 | mov STR:RD, [BASE]
1525 |2:
1526 | mov dword [BASE-4], LJ_TSTR
1527 | mov [BASE-8], STR:RD
1528 | jmp ->fff_res1
1529 |3: // Handle numbers inline, unless a number base metatable is present.
1530 | cmp dword [BASE+4], LJ_TISNUM; ja ->fff_fallback
1531 | cmp dword [DISPATCH+DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])], 0
1532 | jne ->fff_fallback
1533 | ffgccheck // Caveat: uses label 1.
1534 | mov L:RB, SAVE_L
1535 | mov L:RB->base, BASE // Add frame since C call can throw.
1536 | mov SAVE_PC, PC // Redundant (but a defined value).
1537 |.if X64 and not X64WIN
1538 | mov FCARG2, BASE // Otherwise: FCARG2 == BASE
1539 |.endif
1540 | mov L:FCARG1, L:RB
1541 if (LJ_DUALNUM) {
1542 | call extern lj_str_fromnumber@8 // (lua_State *L, cTValue *o)
1543 } else {
1544 | call extern lj_str_fromnum@8 // (lua_State *L, lua_Number *np)
1545 }
1546 | // GCstr returned in eax (RD).
1547 | mov BASE, L:RB->base
1548 | jmp <2
1549 |
1550 |//-- Base library: iterators -------------------------------------------
1551 |
1552 |.ffunc_1 next
1553 | je >2 // Missing 2nd arg?
1554 |1:
1555 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1556 | mov L:RB, SAVE_L
1557 | mov L:RB->base, BASE // Add frame since C call can throw.
1558 | mov L:RB->top, BASE // Dummy frame length is ok.
1559 | mov PC, [BASE-4]
1560 |.if X64WIN
1561 | lea CARG3d, [BASE+8]
1562 | mov CARG2d, [BASE] // Caveat: CARG2d == BASE.
1563 | mov CARG1d, L:RB
1564 |.elif X64
1565 | mov CARG2d, [BASE]
1566 | lea CARG3d, [BASE+8] // Caveat: CARG3d == BASE.
1567 | mov CARG1d, L:RB
1568 |.else
1569 | mov TAB:RD, [BASE]
1570 | mov ARG2, TAB:RD
1571 | mov ARG1, L:RB
1572 | add BASE, 8
1573 | mov ARG3, BASE
1574 |.endif
1575 | mov SAVE_PC, PC // Redundant (but a defined value).
1576 | call extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
1577 | // Flag returned in eax (RD).
1578 | mov BASE, L:RB->base
1579 | test RD, RD; jz >3 // End of traversal?
1580 | // Copy key and value to results.
1581 |.if X64
1582 | mov RBa, [BASE+8]
1583 | mov RDa, [BASE+16]
1584 | mov [BASE-8], RBa
1585 | mov [BASE], RDa
1586 |.else
1587 | mov RB, [BASE+8]
1588 | mov RD, [BASE+12]
1589 | mov [BASE-8], RB
1590 | mov [BASE-4], RD
1591 | mov RB, [BASE+16]
1592 | mov RD, [BASE+20]
1593 | mov [BASE], RB
1594 | mov [BASE+4], RD
1595 |.endif
1596 |->fff_res2:
1597 | mov RD, 1+2
1598 | jmp ->fff_res
1599 |2: // Set missing 2nd arg to nil.
1600 | mov dword [BASE+12], LJ_TNIL
1601 | jmp <1
1602 |3: // End of traversal: return nil.
1603 | mov dword [BASE-4], LJ_TNIL
1604 | jmp ->fff_res1
1605 |
1606 |.ffunc_1 pairs
1607 | mov TAB:RB, [BASE]
1608 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1609#ifdef LUAJIT_ENABLE_LUA52COMPAT
1610 | cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
1611#endif
1612 | mov CFUNC:RB, [BASE-8]
1613 | mov CFUNC:RD, CFUNC:RB->upvalue[0]
1614 | mov PC, [BASE-4]
1615 | mov dword [BASE-4], LJ_TFUNC
1616 | mov [BASE-8], CFUNC:RD
1617 | mov dword [BASE+12], LJ_TNIL
1618 | mov RD, 1+3
1619 | jmp ->fff_res
1620 |
1621 |.ffunc_1 ipairs_aux
1622 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1623 | cmp dword [BASE+12], LJ_TISNUM
1624 if (LJ_DUALNUM) {
1625 | jne ->fff_fallback
1626 } else {
1627 | jae ->fff_fallback
1628 }
1629 | mov PC, [BASE-4]
1630 if (LJ_DUALNUM) {
1631 | mov RD, dword [BASE+8]
1632 | add RD, 1
1633 | mov dword [BASE-4], LJ_TISNUM
1634 | mov dword [BASE-8], RD
1635 } else if (sse) {
1636 | movsd xmm0, qword [BASE+8]
1637 | sseconst_1 xmm1, RBa
1638 | addsd xmm0, xmm1
1639 | cvtsd2si RD, xmm0
1640 | movsd qword [BASE-8], xmm0
1641 } else {
1642 |.if not X64
1643 | fld qword [BASE+8]
1644 | fld1
1645 | faddp st1
1646 | fist ARG1
1647 | fstp qword [BASE-8]
1648 | mov RD, ARG1
1649 |.endif
1650 }
1651 | mov TAB:RB, [BASE]
1652 | cmp RD, TAB:RB->asize; jae >2 // Not in array part?
1653 | shl RD, 3
1654 | add RD, TAB:RB->array
1655 |1:
1656 | cmp dword [RD+4], LJ_TNIL; je ->fff_res0
1657 | // Copy array slot.
1658 |.if X64
1659 | mov RBa, [RD]
1660 | mov [BASE], RBa
1661 |.else
1662 | mov RB, [RD]
1663 | mov RD, [RD+4]
1664 | mov [BASE], RB
1665 | mov [BASE+4], RD
1666 |.endif
1667 | jmp ->fff_res2
1668 |2: // Check for empty hash part first. Otherwise call C function.
1669 | cmp dword TAB:RB->hmask, 0; je ->fff_res0
1670 | mov FCARG1, TAB:RB
1671 | mov RB, BASE // Save BASE.
1672 | mov FCARG2, RD // Caveat: FCARG2 == BASE
1673 | call extern lj_tab_getinth@8 // (GCtab *t, int32_t key)
1674 | // cTValue * or NULL returned in eax (RD).
1675 | mov BASE, RB
1676 | test RD, RD
1677 | jnz <1
1678 |->fff_res0:
1679 | mov RD, 1+0
1680 | jmp ->fff_res
1681 |
1682 |.ffunc_1 ipairs
1683 | mov TAB:RB, [BASE]
1684 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1685#ifdef LUAJIT_ENABLE_LUA52COMPAT
1686 | cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
1687#endif
1688 | mov CFUNC:RB, [BASE-8]
1689 | mov CFUNC:RD, CFUNC:RB->upvalue[0]
1690 | mov PC, [BASE-4]
1691 | mov dword [BASE-4], LJ_TFUNC
1692 | mov [BASE-8], CFUNC:RD
1693 if (LJ_DUALNUM) {
1694 | mov dword [BASE+12], LJ_TISNUM
1695 | mov dword [BASE+8], 0
1696 } else if (sse) {
1697 | xorps xmm0, xmm0
1698 | movsd qword [BASE+8], xmm0
1699 } else {
1700 | fldz
1701 | fstp qword [BASE+8]
1702 }
1703 | mov RD, 1+3
1704 | jmp ->fff_res
1705 |
1706 |//-- Base library: catch errors ----------------------------------------
1707 |
1708 |.ffunc_1 pcall
1709 | lea RA, [BASE+8]
1710 | sub NARGS:RD, 1
1711 | mov PC, 8+FRAME_PCALL
1712 |1:
1713 | movzx RB, byte [DISPATCH+DISPATCH_GL(hookmask)]
1714 | shr RB, HOOK_ACTIVE_SHIFT
1715 | and RB, 1
1716 | add PC, RB // Remember active hook before pcall.
1717 | jmp ->vm_call_dispatch
1718 |
1719 |.ffunc_2 xpcall
1720 | cmp dword [BASE+12], LJ_TFUNC; jne ->fff_fallback
1721 | mov RB, [BASE+4] // Swap function and traceback.
1722 | mov [BASE+12], RB
1723 | mov dword [BASE+4], LJ_TFUNC
1724 | mov LFUNC:RB, [BASE]
1725 | mov PC, [BASE+8]
1726 | mov [BASE+8], LFUNC:RB
1727 | mov [BASE], PC
1728 | lea RA, [BASE+16]
1729 | sub NARGS:RD, 2
1730 | mov PC, 16+FRAME_PCALL
1731 | jmp <1
1732 |
1733 |//-- Coroutine library --------------------------------------------------
1734 |
1735 |.macro coroutine_resume_wrap, resume
1736 |.if resume
1737 |.ffunc_1 coroutine_resume
1738 | mov L:RB, [BASE]
1739 |.else
1740 |.ffunc coroutine_wrap_aux
1741 | mov CFUNC:RB, [BASE-8]
1742 | mov L:RB, CFUNC:RB->upvalue[0].gcr
1743 |.endif
1744 | mov PC, [BASE-4]
1745 | mov SAVE_PC, PC
1746 |.if X64
1747 | mov TMP1, L:RB
1748 |.else
1749 | mov ARG1, L:RB
1750 |.endif
1751 |.if resume
1752 | cmp dword [BASE+4], LJ_TTHREAD; jne ->fff_fallback
1753 |.endif
1754 | cmp aword L:RB->cframe, 0; jne ->fff_fallback
1755 | cmp byte L:RB->status, LUA_YIELD; ja ->fff_fallback
1756 | mov RA, L:RB->top
1757 | je >1 // Status != LUA_YIELD (i.e. 0)?
1758 | cmp RA, L:RB->base // Check for presence of initial func.
1759 | je ->fff_fallback
1760 |1:
1761 |.if resume
1762 | lea PC, [RA+NARGS:RD*8-16] // Check stack space (-1-thread).
1763 |.else
1764 | lea PC, [RA+NARGS:RD*8-8] // Check stack space (-1).
1765 |.endif
1766 | cmp PC, L:RB->maxstack; ja ->fff_fallback
1767 | mov L:RB->top, PC
1768 |
1769 | mov L:RB, SAVE_L
1770 | mov L:RB->base, BASE
1771 |.if resume
1772 | add BASE, 8 // Keep resumed thread in stack for GC.
1773 |.endif
1774 | mov L:RB->top, BASE
1775 |.if resume
1776 | lea RB, [BASE+NARGS:RD*8-24] // RB = end of source for stack move.
1777 |.else
1778 | lea RB, [BASE+NARGS:RD*8-16] // RB = end of source for stack move.
1779 |.endif
1780 | sub RBa, PCa // Relative to PC.
1781 |
1782 | cmp PC, RA
1783 | je >3
1784 |2: // Move args to coroutine.
1785 |.if X64
1786 | mov RCa, [PC+RB]
1787 | mov [PC-8], RCa
1788 |.else
1789 | mov RC, [PC+RB+4]
1790 | mov [PC-4], RC
1791 | mov RC, [PC+RB]
1792 | mov [PC-8], RC
1793 |.endif
1794 | sub PC, 8
1795 | cmp PC, RA
1796 | jne <2
1797 |3:
1798 |.if X64
1799 | mov CARG2d, RA
1800 | mov CARG1d, TMP1
1801 |.else
1802 | mov ARG2, RA
1803 | xor RA, RA
1804 | mov ARG4, RA
1805 | mov ARG3, RA
1806 |.endif
1807 | call ->vm_resume // (lua_State *L, TValue *base, 0, 0)
1808 | set_vmstate INTERP
1809 |
1810 | mov L:RB, SAVE_L
1811 |.if X64
1812 | mov L:PC, TMP1
1813 |.else
1814 | mov L:PC, ARG1 // The callee doesn't modify SAVE_L.
1815 |.endif
1816 | mov BASE, L:RB->base
1817 | cmp eax, LUA_YIELD
1818 | ja >8
1819 |4:
1820 | mov RA, L:PC->base
1821 | mov KBASE, L:PC->top
1822 | mov L:PC->top, RA // Clear coroutine stack.
1823 | mov PC, KBASE
1824 | sub PC, RA
1825 | je >6 // No results?
1826 | lea RD, [BASE+PC]
1827 | shr PC, 3
1828 | cmp RD, L:RB->maxstack
1829 | ja >9 // Need to grow stack?
1830 |
1831 | mov RB, BASE
1832 | sub RBa, RAa
1833 |5: // Move results from coroutine.
1834 |.if X64
1835 | mov RDa, [RA]
1836 | mov [RA+RB], RDa
1837 |.else
1838 | mov RD, [RA]
1839 | mov [RA+RB], RD
1840 | mov RD, [RA+4]
1841 | mov [RA+RB+4], RD
1842 |.endif
1843 | add RA, 8
1844 | cmp RA, KBASE
1845 | jne <5
1846 |6:
1847 |.if resume
1848 | lea RD, [PC+2] // nresults+1 = 1 + true + results.
1849 | mov dword [BASE-4], LJ_TTRUE // Prepend true to results.
1850 |.else
1851 | lea RD, [PC+1] // nresults+1 = 1 + results.
1852 |.endif
1853 |7:
1854 | mov PC, SAVE_PC
1855 | mov MULTRES, RD
1856 |.if resume
1857 | mov RAa, -8
1858 |.else
1859 | xor RA, RA
1860 |.endif
1861 | test PC, FRAME_TYPE
1862 | jz ->BC_RET_Z
1863 | jmp ->vm_return
1864 |
1865 |8: // Coroutine returned with error (at co->top-1).
1866 |.if resume
1867 | mov dword [BASE-4], LJ_TFALSE // Prepend false to results.
1868 | mov RA, L:PC->top
1869 | sub RA, 8
1870 | mov L:PC->top, RA // Clear error from coroutine stack.
1871 | // Copy error message.
1872 |.if X64
1873 | mov RDa, [RA]
1874 | mov [BASE], RDa
1875 |.else
1876 | mov RD, [RA]
1877 | mov [BASE], RD
1878 | mov RD, [RA+4]
1879 | mov [BASE+4], RD
1880 |.endif
1881 | mov RD, 1+2 // nresults+1 = 1 + false + error.
1882 | jmp <7
1883 |.else
1884 | mov FCARG2, L:PC
1885 | mov FCARG1, L:RB
1886 | call extern lj_ffh_coroutine_wrap_err@8 // (lua_State *L, lua_State *co)
1887 | // Error function does not return.
1888 |.endif
1889 |
1890 |9: // Handle stack expansion on return from yield.
1891 |.if X64
1892 | mov L:RA, TMP1
1893 |.else
1894 | mov L:RA, ARG1 // The callee doesn't modify SAVE_L.
1895 |.endif
1896 | mov L:RA->top, KBASE // Undo coroutine stack clearing.
1897 | mov FCARG2, PC
1898 | mov FCARG1, L:RB
1899 | call extern lj_state_growstack@8 // (lua_State *L, int n)
1900 |.if X64
1901 | mov L:PC, TMP1
1902 |.else
1903 | mov L:PC, ARG1
1904 |.endif
1905 | mov BASE, L:RB->base
1906 | jmp <4 // Retry the stack move.
1907 |.endmacro
1908 |
1909 | coroutine_resume_wrap 1 // coroutine.resume
1910 | coroutine_resume_wrap 0 // coroutine.wrap
1911 |
1912 |.ffunc coroutine_yield
1913 | mov L:RB, SAVE_L
1914 | test aword L:RB->cframe, CFRAME_RESUME
1915 | jz ->fff_fallback
1916 | mov L:RB->base, BASE
1917 | lea RD, [BASE+NARGS:RD*8-8]
1918 | mov L:RB->top, RD
1919 | xor RD, RD
1920 | mov aword L:RB->cframe, RDa
1921 | mov al, LUA_YIELD
1922 | mov byte L:RB->status, al
1923 | jmp ->vm_leave_unw
1924 |
1925 |//-- Math library -------------------------------------------------------
1926 |
1927 if (!LJ_DUALNUM) {
1928 |->fff_resi: // Dummy.
1929 }
1930 if (sse) {
1931 |->fff_resn:
1932 | mov PC, [BASE-4]
1933 | fstp qword [BASE-8]
1934 | jmp ->fff_res1
1935 }
1936 | .ffunc_1 math_abs
1937 if (LJ_DUALNUM) {
1938 | cmp dword [BASE+4], LJ_TISNUM; jne >2
1939 | mov RB, dword [BASE]
1940 | cmp RB, 0; jns ->fff_resi
1941 | neg RB; js >1
1942 |->fff_resbit:
1943 |->fff_resi:
1944 | mov PC, [BASE-4]
1945 | mov dword [BASE-4], LJ_TISNUM
1946 | mov dword [BASE-8], RB
1947 | jmp ->fff_res1
1948 |1:
1949 | mov PC, [BASE-4]
1950 | mov dword [BASE-4], 0x41e00000 // 2^31.
1951 | mov dword [BASE-8], 0
1952 | jmp ->fff_res1
1953 |2:
1954 | ja ->fff_fallback
1955 } else {
1956 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1957 }
1958 if (sse) {
1959 | movsd xmm0, qword [BASE]
1960 | sseconst_abs xmm1, RDa
1961 | andps xmm0, xmm1
1962 |->fff_resxmm0:
1963 | mov PC, [BASE-4]
1964 | movsd qword [BASE-8], xmm0
1965 | // fallthrough
1966 } else {
1967 | fld qword [BASE]
1968 | fabs
1969 | // fallthrough
1970 |->fff_resxmm0: // Dummy.
1971 |->fff_resn:
1972 | mov PC, [BASE-4]
1973 | fstp qword [BASE-8]
1974 }
1975 |->fff_res1:
1976 | mov RD, 1+1
1977 |->fff_res:
1978 | mov MULTRES, RD
1979 |->fff_res_:
1980 | test PC, FRAME_TYPE
1981 | jnz >7
1982 |5:
1983 | cmp PC_RB, RDL // More results expected?
1984 | ja >6
1985 | // Adjust BASE. KBASE is assumed to be set for the calling frame.
1986 | movzx RA, PC_RA
1987 | not RAa // Note: ~RA = -(RA+1)
1988 | lea BASE, [BASE+RA*8] // base = base - (RA+1)*8
1989 | ins_next
1990 |
1991 |6: // Fill up results with nil.
1992 | mov dword [BASE+RD*8-12], LJ_TNIL
1993 | add RD, 1
1994 | jmp <5
1995 |
1996 |7: // Non-standard return case.
1997 | mov RAa, -8 // Results start at BASE+RA = BASE-8.
1998 | jmp ->vm_return
1999 |
2000 |.macro math_round, func
2001 | .ffunc math_ .. func
2002 ||if (LJ_DUALNUM) {
2003 | cmp dword [BASE+4], LJ_TISNUM; jne >1
2004 | mov RB, dword [BASE]; jmp ->fff_resi
2005 |1:
2006 | ja ->fff_fallback
2007 ||} else {
2008 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2009 ||}
2010 ||if (sse) {
2011 | movsd xmm0, qword [BASE]
2012 | call ->vm_ .. func
2013 || if (LJ_DUALNUM) {
2014 | cvtsd2si RB, xmm0
2015 | cmp RB, 0x80000000
2016 | jne ->fff_resi
2017 | cvtsi2sd xmm1, RB
2018 | ucomisd xmm0, xmm1
2019 | jp ->fff_resxmm0
2020 | je ->fff_resi
2021 || }
2022 | jmp ->fff_resxmm0
2023 ||} else {
2024 | fld qword [BASE]
2025 | call ->vm_ .. func
2026 || if (LJ_DUALNUM) {
2027 |.if not X64
2028 | fist ARG1
2029 | mov RB, ARG1
2030 | cmp RB, 0x80000000; jne >2
2031 | fdup
2032 | fild ARG1
2033 | fcomparepp
2034 | jp ->fff_resn
2035 | jne ->fff_resn
2036 |2:
2037 | fpop
2038 | jmp ->fff_resi
2039 |.endif
2040 || } else {
2041 | jmp ->fff_resn
2042 || }
2043 ||}
2044 |.endmacro
2045 |
2046 | math_round floor
2047 | math_round ceil
2048 |
2049 if (sse) {
2050 |.ffunc_nsse math_sqrt, sqrtsd; jmp ->fff_resxmm0
2051 } else {
2052 |.ffunc_n math_sqrt; fsqrt; jmp ->fff_resn
2053 }
2054 |.ffunc_n math_log, fldln2; fyl2x; jmp ->fff_resn
2055 |.ffunc_n math_log10, fldlg2; fyl2x; jmp ->fff_resn
2056 |.ffunc_n math_exp; call ->vm_exp_x87; jmp ->fff_resn
2057 |
2058 |.ffunc_n math_sin; fsin; jmp ->fff_resn
2059 |.ffunc_n math_cos; fcos; jmp ->fff_resn
2060 |.ffunc_n math_tan; fptan; fpop; jmp ->fff_resn
2061 |
2062 |.ffunc_n math_asin
2063 | fdup; fmul st0; fld1; fsubrp st1; fsqrt; fpatan
2064 | jmp ->fff_resn
2065 |.ffunc_n math_acos
2066 | fdup; fmul st0; fld1; fsubrp st1; fsqrt; fxch; fpatan
2067 | jmp ->fff_resn
2068 |.ffunc_n math_atan; fld1; fpatan; jmp ->fff_resn
2069 |
2070 |.macro math_extern, func
2071 ||if (sse) {
2072 | .ffunc_nsse math_ .. func
2073 | .if not X64
2074 | movsd FPARG1, xmm0
2075 | .endif
2076 ||} else {
2077 | .if not X64
2078 | .ffunc_n math_ .. func
2079 | fstp FPARG1
2080 | .endif
2081 ||}
2082 | mov RB, BASE
2083 | call extern lj_vm_ .. func
2084 | mov BASE, RB
2085 | .if X64
2086 | jmp ->fff_resxmm0
2087 | .else
2088 | jmp ->fff_resn
2089 | .endif
2090 |.endmacro
2091 |
2092 | math_extern sinh
2093 | math_extern cosh
2094 | math_extern tanh
2095 |
2096 |->ff_math_deg:
2097 if (sse) {
2098 |.ffunc_nsse math_rad
2099 | mov CFUNC:RB, [BASE-8]
2100 | mulsd xmm0, qword CFUNC:RB->upvalue[0]
2101 | jmp ->fff_resxmm0
2102 } else {
2103 |.ffunc_n math_rad
2104 | mov CFUNC:RB, [BASE-8]
2105 | fmul qword CFUNC:RB->upvalue[0]
2106 | jmp ->fff_resn
2107 }
2108 |
2109 |.ffunc_nn math_atan2; fpatan; jmp ->fff_resn
2110 |.ffunc_nnr math_ldexp; fscale; fpop1; jmp ->fff_resn
2111 |
2112 |.ffunc_1 math_frexp
2113 | mov RB, [BASE+4]
2114 | cmp RB, LJ_TISNUM; jae ->fff_fallback
2115 | mov PC, [BASE-4]
2116 | mov RC, [BASE]
2117 | mov [BASE-4], RB; mov [BASE-8], RC
2118 | shl RB, 1; cmp RB, 0xffe00000; jae >3
2119 | or RC, RB; jz >3
2120 | mov RC, 1022
2121 | cmp RB, 0x00200000; jb >4
2122 |1:
2123 | shr RB, 21; sub RB, RC // Extract and unbias exponent.
2124 if (sse) {
2125 | cvtsi2sd xmm0, RB
2126 } else {
2127 | mov TMP1, RB; fild TMP1
2128 }
2129 | mov RB, [BASE-4]
2130 | and RB, 0x800fffff // Mask off exponent.
2131 | or RB, 0x3fe00000 // Put mantissa in range [0.5,1) or 0.
2132 | mov [BASE-4], RB
2133 |2:
2134 if (sse) {
2135 | movsd qword [BASE], xmm0
2136 } else {
2137 | fstp qword [BASE]
2138 }
2139 | mov RD, 1+2
2140 | jmp ->fff_res
2141 |3: // Return +-0, +-Inf, NaN unmodified and an exponent of 0.
2142 if (sse) {
2143 | xorps xmm0, xmm0; jmp <2
2144 } else {
2145 | fldz; jmp <2
2146 }
2147 |4: // Handle denormals by multiplying with 2^54 and adjusting the bias.
2148 if (sse) {
2149 | movsd xmm0, qword [BASE]
2150 | sseconst_hi xmm1, RBa, 43500000 // 2^54.
2151 | mulsd xmm0, xmm1
2152 | movsd qword [BASE-8], xmm0
2153 } else {
2154 | fld qword [BASE]
2155 | mov TMP1, 0x5a800000; fmul TMP1 // x = x*2^54
2156 | fstp qword [BASE-8]
2157 }
2158 | mov RB, [BASE-4]; mov RC, 1076; shl RB, 1; jmp <1
2159 |
2160 if (sse) {
2161 |.ffunc_nsse math_modf
2162 } else {
2163 |.ffunc_n math_modf
2164 }
2165 | mov RB, [BASE+4]
2166 | mov PC, [BASE-4]
2167 | shl RB, 1; cmp RB, 0xffe00000; je >4 // +-Inf?
2168 if (sse) {
2169 | movaps xmm4, xmm0
2170 | call ->vm_trunc
2171 | subsd xmm4, xmm0
2172 |1:
2173 | movsd qword [BASE-8], xmm0
2174 | movsd qword [BASE], xmm4
2175 } else {
2176 | fdup
2177 | call ->vm_trunc
2178 | fsub st1, st0
2179 |1:
2180 | fstp qword [BASE-8]
2181 | fstp qword [BASE]
2182 }
2183 | mov RC, [BASE-4]; mov RB, [BASE+4]
2184 | xor RC, RB; js >3 // Need to adjust sign?
2185 |2:
2186 | mov RD, 1+2
2187 | jmp ->fff_res
2188 |3:
2189 | xor RB, 0x80000000; mov [BASE+4], RB // Flip sign of fraction.
2190 | jmp <2
2191 |4:
2192 if (sse) {
2193 | xorps xmm4, xmm4; jmp <1 // Return +-Inf and +-0.
2194 } else {
2195 | fldz; fxch; jmp <1 // Return +-Inf and +-0.
2196 }
2197 |
2198 |.ffunc_nnr math_fmod
2199 |1: ; fprem; fnstsw ax; sahf; jp <1
2200 | fpop1
2201 | jmp ->fff_resn
2202 |
2203 if (sse) {
2204 |.ffunc_nnsse math_pow; call ->vm_pow; jmp ->fff_resxmm0
2205 } else {
2206 |.ffunc_nn math_pow; call ->vm_pow; jmp ->fff_resn
2207 }
2208 |
2209 |.macro math_minmax, name, cmovop, fcmovop, nofcmovop, sseop
2210 | .ffunc name
2211 | mov RA, 2
2212 | cmp dword [BASE+4], LJ_TISNUM
2213 ||if (LJ_DUALNUM) {
2214 | jne >4
2215 | mov RB, dword [BASE]
2216 |1: // Handle integers.
2217 | cmp RA, RD; jae ->fff_resi
2218 | cmp dword [BASE+RA*8-4], LJ_TISNUM; jne >3
2219 | cmp RB, dword [BASE+RA*8-8]
2220 | cmovop RB, dword [BASE+RA*8-8]
2221 | add RA, 1
2222 | jmp <1
2223 |3:
2224 | ja ->fff_fallback
2225 | // Convert intermediate result to number and continue below.
2226 ||if (sse) {
2227 | cvtsi2sd xmm0, RB
2228 ||} else {
2229 |.if not X64
2230 | mov TMP1, RB
2231 | fild TMP1
2232 |.endif
2233 ||}
2234 | jmp >6
2235 |4:
2236 | ja ->fff_fallback
2237 ||} else {
2238 | jae ->fff_fallback
2239 ||}
2240 |
2241 ||if (sse) {
2242 | movsd xmm0, qword [BASE]
2243 |5: // Handle numbers or integers.
2244 | cmp RA, RD; jae ->fff_resxmm0
2245 | cmp dword [BASE+RA*8-4], LJ_TISNUM
2246 ||if (LJ_DUALNUM) {
2247 | jb >6
2248 | ja ->fff_fallback
2249 | cvtsi2sd xmm1, dword [BASE+RA*8-8]
2250 | jmp >7
2251 ||} else {
2252 | jae ->fff_fallback
2253 ||}
2254 |6:
2255 | movsd xmm1, qword [BASE+RA*8-8]
2256 |7:
2257 | sseop xmm0, xmm1
2258 | add RA, 1
2259 | jmp <5
2260 ||} else {
2261 |.if not X64
2262 | fld qword [BASE]
2263 |5: // Handle numbers or integers.
2264 | cmp RA, RD; jae ->fff_resn
2265 | cmp dword [BASE+RA*8-4], LJ_TISNUM
2266 ||if (LJ_DUALNUM) {
2267 | jb >6
2268 | ja >9
2269 | fild dword [BASE+RA*8-8]
2270 | jmp >7
2271 ||} else {
2272 | jae >9
2273 ||}
2274 |6:
2275 | fld qword [BASE+RA*8-8]
2276 |7:
2277 ||if (cmov) {
2278 | fucomi st1; fcmovop st1; fpop1
2279 ||} else {
2280 | push eax
2281 | fucom st1; fnstsw ax; test ah, 1; nofcmovop >2; fxch; 2: ; fpop
2282 | pop eax
2283 ||}
2284 | add RA, 1
2285 | jmp <5
2286 |.endif
2287 ||}
2288 |.endmacro
2289 |
2290 | math_minmax math_min, cmovg, fcmovnbe, jz, minsd
2291 | math_minmax math_max, cmovl, fcmovbe, jnz, maxsd
2292 if (!sse) {
2293 |9:
2294 | fpop; jmp ->fff_fallback
2295 }
2296 |
2297 |//-- String library -----------------------------------------------------
2298 |
2299 |.ffunc_1 string_len
2300 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2301 | mov STR:RB, [BASE]
2302 if (LJ_DUALNUM) {
2303 | mov RB, dword STR:RB->len; jmp ->fff_resi
2304 } else if (sse) {
2305 | cvtsi2sd xmm0, dword STR:RB->len; jmp ->fff_resxmm0
2306 } else {
2307 | fild dword STR:RB->len; jmp ->fff_resn
2308 }
2309 |
2310 |.ffunc string_byte // Only handle the 1-arg case here.
2311 | cmp NARGS:RD, 1+1; jne ->fff_fallback
2312 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2313 | mov STR:RB, [BASE]
2314 | mov PC, [BASE-4]
2315 | cmp dword STR:RB->len, 1
2316 | jb ->fff_res0 // Return no results for empty string.
2317 | movzx RB, byte STR:RB[1]
2318 if (LJ_DUALNUM) {
2319 | jmp ->fff_resi
2320 } else if (sse) {
2321 | cvtsi2sd xmm0, RB; jmp ->fff_resxmm0
2322 } else {
2323 | mov TMP1, RB; fild TMP1; jmp ->fff_resn
2324 }
2325 |
2326 |.ffunc string_char // Only handle the 1-arg case here.
2327 | ffgccheck
2328 | cmp NARGS:RD, 1+1; jne ->fff_fallback // *Exactly* 1 arg.
2329 | cmp dword [BASE+4], LJ_TISNUM
2330 if (LJ_DUALNUM) {
2331 | jne ->fff_fallback
2332 | mov RB, dword [BASE]
2333 | cmp RB, 255; ja ->fff_fallback
2334 | mov TMP2, RB
2335 } else if (sse) {
2336 | jae ->fff_fallback
2337 | cvttsd2si RB, qword [BASE]
2338 | cmp RB, 255; ja ->fff_fallback
2339 | mov TMP2, RB
2340 } else {
2341 | jae ->fff_fallback
2342 | fld qword [BASE]
2343 | fistp TMP2
2344 | cmp TMP2, 255; ja ->fff_fallback
2345 }
2346 |.if X64
2347 | mov TMP3, 1
2348 |.else
2349 | mov ARG3, 1
2350 |.endif
2351 | lea RDa, TMP2 // Points to stack. Little-endian.
2352 |->fff_newstr:
2353 | mov L:RB, SAVE_L
2354 | mov L:RB->base, BASE
2355 |.if X64
2356 | mov CARG3d, TMP3 // Zero-extended to size_t.
2357 | mov CARG2, RDa // May be 64 bit ptr to stack.
2358 | mov CARG1d, L:RB
2359 |.else
2360 | mov ARG2, RD
2361 | mov ARG1, L:RB
2362 |.endif
2363 | mov SAVE_PC, PC
2364 | call extern lj_str_new // (lua_State *L, char *str, size_t l)
2365 | // GCstr * returned in eax (RD).
2366 | mov BASE, L:RB->base
2367 | mov PC, [BASE-4]
2368 | mov dword [BASE-4], LJ_TSTR
2369 | mov [BASE-8], STR:RD
2370 | jmp ->fff_res1
2371 |
2372 |.ffunc string_sub
2373 | ffgccheck
2374 | mov TMP2, -1
2375 | cmp NARGS:RD, 1+2; jb ->fff_fallback
2376 | jna >1
2377 | cmp dword [BASE+20], LJ_TISNUM
2378 if (LJ_DUALNUM) {
2379 | jne ->fff_fallback
2380 | mov RB, dword [BASE+16]
2381 | mov TMP2, RB
2382 } else if (sse) {
2383 | jae ->fff_fallback
2384 | cvttsd2si RB, qword [BASE+16]
2385 | mov TMP2, RB
2386 } else {
2387 | jae ->fff_fallback
2388 | fld qword [BASE+16]
2389 | fistp TMP2
2390 }
2391 |1:
2392 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2393 | cmp dword [BASE+12], LJ_TISNUM
2394 if (LJ_DUALNUM) {
2395 | jne ->fff_fallback
2396 } else {
2397 | jae ->fff_fallback
2398 }
2399 | mov STR:RB, [BASE]
2400 | mov TMP3, STR:RB
2401 | mov RB, STR:RB->len
2402 if (LJ_DUALNUM) {
2403 | mov RA, dword [BASE+8]
2404 } else if (sse) {
2405 | cvttsd2si RA, qword [BASE+8]
2406 } else {
2407 |.if not X64
2408 | fld qword [BASE+8]
2409 | fistp ARG3
2410 | mov RA, ARG3
2411 |.endif
2412 }
2413 | mov RC, TMP2
2414 | cmp RB, RC // len < end? (unsigned compare)
2415 | jb >5
2416 |2:
2417 | test RA, RA // start <= 0?
2418 | jle >7
2419 |3:
2420 | mov STR:RB, TMP3
2421 | sub RC, RA // start > end?
2422 | jl ->fff_emptystr
2423 | lea RB, [STR:RB+RA+#STR-1]
2424 | add RC, 1
2425 |4:
2426 |.if X64
2427 | mov TMP3, RC
2428 |.else
2429 | mov ARG3, RC
2430 |.endif
2431 | mov RD, RB
2432 | jmp ->fff_newstr
2433 |
2434 |5: // Negative end or overflow.
2435 | jl >6
2436 | lea RC, [RC+RB+1] // end = end+(len+1)
2437 | jmp <2
2438 |6: // Overflow.
2439 | mov RC, RB // end = len
2440 | jmp <2
2441 |
2442 |7: // Negative start or underflow.
2443 | je >8
2444 | add RA, RB // start = start+(len+1)
2445 | add RA, 1
2446 | jg <3 // start > 0?
2447 |8: // Underflow.
2448 | mov RA, 1 // start = 1
2449 | jmp <3
2450 |
2451 |->fff_emptystr: // Range underflow.
2452 | xor RC, RC // Zero length. Any ptr in RB is ok.
2453 | jmp <4
2454 |
2455 |.ffunc_2 string_rep // Only handle the 1-char case inline.
2456 | ffgccheck
2457 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2458 | cmp dword [BASE+12], LJ_TISNUM
2459 | mov STR:RB, [BASE]
2460 if (LJ_DUALNUM) {
2461 | jne ->fff_fallback
2462 | mov RC, dword [BASE+8]
2463 } else if (sse) {
2464 | jae ->fff_fallback
2465 | cvttsd2si RC, qword [BASE+8]
2466 } else {
2467 | jae ->fff_fallback
2468 | fld qword [BASE+8]
2469 | fistp TMP2
2470 | mov RC, TMP2
2471 }
2472 | test RC, RC
2473 | jle ->fff_emptystr // Count <= 0? (or non-int)
2474 | cmp dword STR:RB->len, 1
2475 | jb ->fff_emptystr // Zero length string?
2476 | jne ->fff_fallback_2 // Fallback for > 1-char strings.
2477 | cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_2
2478 | movzx RA, byte STR:RB[1]
2479 | mov RB, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
2480 |.if X64
2481 | mov TMP3, RC
2482 |.else
2483 | mov ARG3, RC
2484 |.endif
2485 |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
2486 | mov [RB], RAL
2487 | add RB, 1
2488 | sub RC, 1
2489 | jnz <1
2490 | mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
2491 | jmp ->fff_newstr
2492 |
2493 |.ffunc_1 string_reverse
2494 | ffgccheck
2495 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2496 | mov STR:RB, [BASE]
2497 | mov RC, STR:RB->len
2498 | test RC, RC
2499 | jz ->fff_emptystr // Zero length string?
2500 | cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_1
2501 | add RB, #STR
2502 | mov TMP2, PC // Need another temp register.
2503 |.if X64
2504 | mov TMP3, RC
2505 |.else
2506 | mov ARG3, RC
2507 |.endif
2508 | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
2509 |1:
2510 | movzx RA, byte [RB]
2511 | add RB, 1
2512 | sub RC, 1
2513 | mov [PC+RC], RAL
2514 | jnz <1
2515 | mov RD, PC
2516 | mov PC, TMP2
2517 | jmp ->fff_newstr
2518 |
2519 |.macro ffstring_case, name, lo, hi
2520 | .ffunc_1 name
2521 | ffgccheck
2522 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2523 | mov STR:RB, [BASE]
2524 | mov RC, STR:RB->len
2525 | cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_1
2526 | add RB, #STR
2527 | mov TMP2, PC // Need another temp register.
2528 |.if X64
2529 | mov TMP3, RC
2530 |.else
2531 | mov ARG3, RC
2532 |.endif
2533 | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
2534 | jmp >3
2535 |1: // ASCII case conversion. Yes, this is suboptimal code (do you care?).
2536 | movzx RA, byte [RB+RC]
2537 | cmp RA, lo
2538 | jb >2
2539 | cmp RA, hi
2540 | ja >2
2541 | xor RA, 0x20
2542 |2:
2543 | mov [PC+RC], RAL
2544 |3:
2545 | sub RC, 1
2546 | jns <1
2547 | mov RD, PC
2548 | mov PC, TMP2
2549 | jmp ->fff_newstr
2550 |.endmacro
2551 |
2552 |ffstring_case string_lower, 0x41, 0x5a
2553 |ffstring_case string_upper, 0x61, 0x7a
2554 |
2555 |//-- Table library ------------------------------------------------------
2556 |
2557 |.ffunc_1 table_getn
2558 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
2559 | mov RB, BASE // Save BASE.
2560 | mov TAB:FCARG1, [BASE]
2561 | call extern lj_tab_len@4 // LJ_FASTCALL (GCtab *t)
2562 | // Length of table returned in eax (RD).
2563 | mov BASE, RB // Restore BASE.
2564 if (LJ_DUALNUM) {
2565 | mov RB, RD; jmp ->fff_resi
2566 } else if (sse) {
2567 | cvtsi2sd xmm0, RD; jmp ->fff_resxmm0
2568 } else {
2569 |.if not X64
2570 | mov ARG1, RD; fild ARG1; jmp ->fff_resn
2571 |.endif
2572 }
2573 |
2574 |//-- Bit library --------------------------------------------------------
2575 |
2576 |.define TOBIT_BIAS, 0x59c00000 // 2^52 + 2^51 (float, not double!).
2577 |
2578 |.macro .ffunc_bit, name, kind
2579 | .ffunc_1 name
2580 |.if kind == 2
2581 ||if (sse) {
2582 | sseconst_tobit xmm1, RBa
2583 ||} else {
2584 | mov TMP1, TOBIT_BIAS
2585 ||}
2586 |.endif
2587 | cmp dword [BASE+4], LJ_TISNUM
2588 ||if (LJ_DUALNUM) {
2589 | jne >1
2590 | mov RB, dword [BASE]
2591 |.if kind > 0
2592 | jmp >2
2593 |.else
2594 | jmp ->fff_resbit
2595 |.endif
2596 |1:
2597 | ja ->fff_fallback
2598 ||} else {
2599 | jae ->fff_fallback
2600 ||}
2601 ||if (sse) {
2602 | movsd xmm0, qword [BASE]
2603 |.if kind < 2
2604 | sseconst_tobit xmm1, RBa
2605 |.endif
2606 | addsd xmm0, xmm1
2607 | movd RB, xmm0
2608 ||} else {
2609 |.if not X64
2610 | fld qword [BASE]
2611 |.if kind < 2
2612 | mov TMP1, TOBIT_BIAS
2613 |.endif
2614 | fadd TMP1
2615 | fstp FPARG1
2616 |.if kind > 0
2617 | mov RB, ARG1
2618 |.endif
2619 |.endif
2620 ||}
2621 |2:
2622 |.endmacro
2623 |
2624 |.ffunc_bit bit_tobit, 0
2625 if (LJ_DUALNUM || sse) {
2626 if (!sse) {
2627 |.if not X64
2628 | mov RB, ARG1
2629 |.endif
2630 }
2631 | jmp ->fff_resbit
2632 } else {
2633 |.if not X64
2634 | fild ARG1
2635 | jmp ->fff_resn
2636 |.endif
2637 }
2638 |
2639 |.macro .ffunc_bit_op, name, ins
2640 | .ffunc_bit name, 2
2641 | mov TMP2, NARGS:RD // Save for fallback.
2642 | lea RD, [BASE+NARGS:RD*8-16]
2643 |1:
2644 | cmp RD, BASE
2645 | jbe ->fff_resbit
2646 | cmp dword [RD+4], LJ_TISNUM
2647 ||if (LJ_DUALNUM) {
2648 | jne >2
2649 | ins RB, dword [RD]
2650 | sub RD, 8
2651 | jmp <1
2652 |2:
2653 | ja ->fff_fallback_bit_op
2654 ||} else {
2655 | jae ->fff_fallback_bit_op
2656 ||}
2657 ||if (sse) {
2658 | movsd xmm0, qword [RD]
2659 | addsd xmm0, xmm1
2660 | movd RA, xmm0
2661 | ins RB, RA
2662 ||} else {
2663 |.if not X64
2664 | fld qword [RD]
2665 | fadd TMP1
2666 | fstp FPARG1
2667 | ins RB, ARG1
2668 |.endif
2669 ||}
2670 | sub RD, 8
2671 | jmp <1
2672 |.endmacro
2673 |
2674 |.ffunc_bit_op bit_band, and
2675 |.ffunc_bit_op bit_bor, or
2676 |.ffunc_bit_op bit_bxor, xor
2677 |
2678 |.ffunc_bit bit_bswap, 1
2679 | bswap RB
2680 | jmp ->fff_resbit
2681 |
2682 |.ffunc_bit bit_bnot, 1
2683 | not RB
2684 if (LJ_DUALNUM) {
2685 | jmp ->fff_resbit
2686 } else if (sse) {
2687 |->fff_resbit:
2688 | cvtsi2sd xmm0, RB
2689 | jmp ->fff_resxmm0
2690 } else {
2691 |.if not X64
2692 |->fff_resbit:
2693 | mov ARG1, RB
2694 | fild ARG1
2695 | jmp ->fff_resn
2696 |.endif
2697 }
2698 |
2699 |->fff_fallback_bit_op:
2700 | mov NARGS:RD, TMP2 // Restore for fallback
2701 | jmp ->fff_fallback
2702 |
2703 |.macro .ffunc_bit_sh, name, ins
2704 ||if (LJ_DUALNUM) {
2705 | .ffunc_bit name, 1
2706 | // Note: no inline conversion from number for 2nd argument!
2707 | cmp dword [BASE+12], LJ_TISNUM; jne ->fff_fallback
2708 | mov RA, dword [BASE+8]
2709 ||} else if (sse) {
2710 | .ffunc_nnsse name
2711 | sseconst_tobit xmm2, RBa
2712 | addsd xmm0, xmm2
2713 | addsd xmm1, xmm2
2714 | movd RB, xmm0
2715 | movd RA, xmm1
2716 ||} else {
2717 |.if not X64
2718 | .ffunc_nn name
2719 | mov TMP1, TOBIT_BIAS
2720 | fadd TMP1
2721 | fstp FPARG3
2722 | fadd TMP1
2723 | fstp FPARG1
2724 | mov RA, ARG3
2725 | mov RB, ARG1
2726 |.endif
2727 ||}
2728 | ins RB, cl // Assumes RA is ecx.
2729 | jmp ->fff_resbit
2730 |.endmacro
2731 |
2732 |.ffunc_bit_sh bit_lshift, shl
2733 |.ffunc_bit_sh bit_rshift, shr
2734 |.ffunc_bit_sh bit_arshift, sar
2735 |.ffunc_bit_sh bit_rol, rol
2736 |.ffunc_bit_sh bit_ror, ror
2737 |
2738 |//-----------------------------------------------------------------------
2739 |
2740 |->fff_fallback_2:
2741 | mov NARGS:RD, 1+2 // Other args are ignored, anyway.
2742 | jmp ->fff_fallback
2743 |->fff_fallback_1:
2744 | mov NARGS:RD, 1+1 // Other args are ignored, anyway.
2745 |->fff_fallback: // Call fast function fallback handler.
2746 | // BASE = new base, RD = nargs+1
2747 | mov L:RB, SAVE_L
2748 | mov PC, [BASE-4] // Fallback may overwrite PC.
2749 | mov SAVE_PC, PC // Redundant (but a defined value).
2750 | mov L:RB->base, BASE
2751 | lea RD, [BASE+NARGS:RD*8-8]
2752 | lea RA, [RD+8*LUA_MINSTACK] // Ensure enough space for handler.
2753 | mov L:RB->top, RD
2754 | mov CFUNC:RD, [BASE-8]
2755 | cmp RA, L:RB->maxstack
2756 | ja >5 // Need to grow stack.
2757 |.if X64
2758 | mov CARG1d, L:RB
2759 |.else
2760 | mov ARG1, L:RB
2761 |.endif
2762 | call aword CFUNC:RD->f // (lua_State *L)
2763 | mov BASE, L:RB->base
2764 | // Either throws an error, or recovers and returns -1, 0 or nresults+1.
2765 | test RD, RD; jg ->fff_res // Returned nresults+1?
2766 |1:
2767 | mov RA, L:RB->top
2768 | sub RA, BASE
2769 | shr RA, 3
2770 | test RD, RD
2771 | lea NARGS:RD, [RA+1]
2772 | mov LFUNC:RB, [BASE-8]
2773 | jne ->vm_call_tail // Returned -1?
2774 | ins_callt // Returned 0: retry fast path.
2775 |
2776 |// Reconstruct previous base for vmeta_call during tailcall.
2777 |->vm_call_tail:
2778 | mov RA, BASE
2779 | test PC, FRAME_TYPE
2780 | jnz >3
2781 | movzx RB, PC_RA
2782 | not RBa // Note: ~RB = -(RB+1)
2783 | lea BASE, [BASE+RB*8] // base = base - (RB+1)*8
2784 | jmp ->vm_call_dispatch // Resolve again for tailcall.
2785 |3:
2786 | mov RB, PC
2787 | and RB, -8
2788 | sub BASE, RB
2789 | jmp ->vm_call_dispatch // Resolve again for tailcall.
2790 |
2791 |5: // Grow stack for fallback handler.
2792 | mov FCARG2, LUA_MINSTACK
2793 | mov FCARG1, L:RB
2794 | call extern lj_state_growstack@8 // (lua_State *L, int n)
2795 | mov BASE, L:RB->base
2796 | xor RD, RD // Simulate a return 0.
2797 | jmp <1 // Dumb retry (goes through ff first).
2798 |
2799 |->fff_gcstep: // Call GC step function.
2800 | // BASE = new base, RD = nargs+1
2801 | pop RBa // Must keep stack at same level.
2802 | mov TMPa, RBa // Save return address
2803 | mov L:RB, SAVE_L
2804 | mov SAVE_PC, PC // Redundant (but a defined value).
2805 | mov L:RB->base, BASE
2806 | lea RD, [BASE+NARGS:RD*8-8]
2807 | mov FCARG1, L:RB
2808 | mov L:RB->top, RD
2809 | call extern lj_gc_step@4 // (lua_State *L)
2810 | mov BASE, L:RB->base
2811 | mov RD, L:RB->top
2812 | sub RD, BASE
2813 | shr RD, 3
2814 | add NARGS:RD, 1
2815 | mov RBa, TMPa
2816 | push RBa // Restore return address.
2817 | ret
2818 |
2819 |//-----------------------------------------------------------------------
2820 |//-- Special dispatch targets -------------------------------------------
2821 |//-----------------------------------------------------------------------
2822 |
2823 |->vm_record: // Dispatch target for recording phase.
2824#if LJ_HASJIT
2825 | movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
2826 | test RDL, HOOK_VMEVENT // No recording while in vmevent.
2827 | jnz >5
2828 | // Decrement the hookcount for consistency, but always do the call.
2829 | test RDL, HOOK_ACTIVE
2830 | jnz >1
2831 | test RDL, LUA_MASKLINE|LUA_MASKCOUNT
2832 | jz >1
2833 | dec dword [DISPATCH+DISPATCH_GL(hookcount)]
2834 | jmp >1
2835#endif
2836 |
2837 |->vm_rethook: // Dispatch target for return hooks.
2838 | movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
2839 | test RDL, HOOK_ACTIVE // Hook already active?
2840 | jnz >5
2841 | jmp >1
2842 |
2843 |->vm_inshook: // Dispatch target for instr/line hooks.
2844 | movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
2845 | test RDL, HOOK_ACTIVE // Hook already active?
2846 | jnz >5
2847 |
2848 | test RDL, LUA_MASKLINE|LUA_MASKCOUNT
2849 | jz >5
2850 | dec dword [DISPATCH+DISPATCH_GL(hookcount)]
2851 | jz >1
2852 | test RDL, LUA_MASKLINE
2853 | jz >5
2854 |1:
2855 | mov L:RB, SAVE_L
2856 | mov L:RB->base, BASE
2857 | mov FCARG2, PC // Caveat: FCARG2 == BASE
2858 | mov FCARG1, L:RB
2859 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
2860 | call extern lj_dispatch_ins@8 // (lua_State *L, BCIns *pc)
2861 |3:
2862 | mov BASE, L:RB->base
2863 |4:
2864 | movzx RA, PC_RA
2865 |5:
2866 | movzx OP, PC_OP
2867 | movzx RD, PC_RD
2868 |.if X64
2869 | jmp aword [DISPATCH+OP*8+GG_DISP2STATIC] // Re-dispatch to static ins.
2870 |.else
2871 | jmp aword [DISPATCH+OP*4+GG_DISP2STATIC] // Re-dispatch to static ins.
2872 |.endif
2873 |
2874 |->cont_hook: // Continue from hook yield.
2875 | add PC, 4
2876 | mov RA, [RB-24]
2877 | mov MULTRES, RA // Restore MULTRES for *M ins.
2878 | jmp <4
2879 |
2880 |->vm_hotloop: // Hot loop counter underflow.
2881#if LJ_HASJIT
2882 | mov LFUNC:RB, [BASE-8] // Same as curr_topL(L).
2883 | mov RB, LFUNC:RB->pc
2884 | movzx RD, byte [RB+PC2PROTO(framesize)]
2885 | lea RD, [BASE+RD*8]
2886 | mov L:RB, SAVE_L
2887 | mov L:RB->base, BASE
2888 | mov L:RB->top, RD
2889 | mov FCARG2, PC
2890 | lea FCARG1, [DISPATCH+GG_DISP2J]
2891 | mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
2892 | mov SAVE_PC, PC
2893 | call extern lj_trace_hot@8 // (jit_State *J, const BCIns *pc)
2894 | jmp <3
2895#endif
2896 |
2897 |->vm_callhook: // Dispatch target for call hooks.
2898 | mov SAVE_PC, PC
2899#if LJ_HASJIT
2900 | jmp >1
2901#endif
2902 |
2903 |->vm_hotcall: // Hot call counter underflow.
2904#if LJ_HASJIT
2905 | mov SAVE_PC, PC
2906 | or PC, 1 // Marker for hot call.
2907 |1:
2908#endif
2909 | lea RD, [BASE+NARGS:RD*8-8]
2910 | mov L:RB, SAVE_L
2911 | mov L:RB->base, BASE
2912 | mov L:RB->top, RD
2913 | mov FCARG2, PC
2914 | mov FCARG1, L:RB
2915 | call extern lj_dispatch_call@8 // (lua_State *L, const BCIns *pc)
2916 | // ASMFunction returned in eax/rax (RDa).
2917 | mov SAVE_PC, 0 // Invalidate for subsequent line hook.
2918#if LJ_HASJIT
2919 | and PC, -2
2920#endif
2921 | mov BASE, L:RB->base
2922 | mov RAa, RDa
2923 | mov RD, L:RB->top
2924 | sub RD, BASE
2925 | mov RBa, RAa
2926 | movzx RA, PC_RA
2927 | shr RD, 3
2928 | add NARGS:RD, 1
2929 | jmp RBa
2930 |
2931 |//-----------------------------------------------------------------------
2932 |//-- Trace exit handler -------------------------------------------------
2933 |//-----------------------------------------------------------------------
2934 |
2935 |// Called from an exit stub with the exit number on the stack.
2936 |// The 16 bit exit number is stored with two (sign-extended) push imm8.
2937 |->vm_exit_handler:
2938#if LJ_HASJIT
2939 |.if X64
2940 | push r13; push r12
2941 | push r11; push r10; push r9; push r8
2942 | push rdi; push rsi; push rbp; lea rbp, [rsp+88]; push rbp
2943 | push rbx; push rdx; push rcx; push rax
2944 | movzx RC, byte [rbp-8] // Reconstruct exit number.
2945 | mov RCH, byte [rbp-16]
2946 | mov [rbp-8], r15; mov [rbp-16], r14
2947 |.else
2948 | push ebp; lea ebp, [esp+12]; push ebp
2949 | push ebx; push edx; push ecx; push eax
2950 | movzx RC, byte [ebp-4] // Reconstruct exit number.
2951 | mov RCH, byte [ebp-8]
2952 | mov [ebp-4], edi; mov [ebp-8], esi
2953 |.endif
2954 | // Caveat: DISPATCH is ebx.
2955 | mov DISPATCH, [ebp]
2956 | mov RA, [DISPATCH+DISPATCH_GL(vmstate)] // Get trace number.
2957 | set_vmstate EXIT
2958 | mov [DISPATCH+DISPATCH_J(exitno)], RC
2959 | mov [DISPATCH+DISPATCH_J(parent)], RA
2960 |.if X64
2961 |.if X64WIN
2962 | sub rsp, 16*8+4*8 // Room for SSE regs + save area.
2963 |.else
2964 | sub rsp, 16*8 // Room for SSE regs.
2965 |.endif
2966 | add rbp, -128
2967 | movsd qword [rbp-8], xmm15; movsd qword [rbp-16], xmm14
2968 | movsd qword [rbp-24], xmm13; movsd qword [rbp-32], xmm12
2969 | movsd qword [rbp-40], xmm11; movsd qword [rbp-48], xmm10
2970 | movsd qword [rbp-56], xmm9; movsd qword [rbp-64], xmm8
2971 | movsd qword [rbp-72], xmm7; movsd qword [rbp-80], xmm6
2972 | movsd qword [rbp-88], xmm5; movsd qword [rbp-96], xmm4
2973 | movsd qword [rbp-104], xmm3; movsd qword [rbp-112], xmm2
2974 | movsd qword [rbp-120], xmm1; movsd qword [rbp-128], xmm0
2975 |.else
2976 | sub esp, 8*8+16 // Room for SSE regs + args.
2977 | movsd qword [ebp-40], xmm7; movsd qword [ebp-48], xmm6
2978 | movsd qword [ebp-56], xmm5; movsd qword [ebp-64], xmm4
2979 | movsd qword [ebp-72], xmm3; movsd qword [ebp-80], xmm2
2980 | movsd qword [ebp-88], xmm1; movsd qword [ebp-96], xmm0
2981 |.endif
2982 | // Caveat: RB is ebp.
2983 | mov L:RB, [DISPATCH+DISPATCH_GL(jit_L)]
2984 | mov BASE, [DISPATCH+DISPATCH_GL(jit_base)]
2985 | mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
2986 | mov dword [DISPATCH+DISPATCH_GL(jit_L)], 0
2987 | mov L:RB->base, BASE
2988 |.if X64WIN
2989 | lea CARG2, [rsp+4*8]
2990 |.elif X64
2991 | mov CARG2, rsp
2992 |.else
2993 | lea FCARG2, [esp+16]
2994 |.endif
2995 | lea FCARG1, [DISPATCH+GG_DISP2J]
2996 | call extern lj_trace_exit@8 // (jit_State *J, ExitState *ex)
2997 | // MULTRES or negated error code returned in eax (RD).
2998 | mov RAa, L:RB->cframe
2999 | and RAa, CFRAME_RAWMASK
3000 |.if X64WIN
3001 | // Reposition stack later.
3002 |.elif X64
3003 | mov rsp, RAa // Reposition stack to C frame.
3004 |.else
3005 | mov esp, RAa // Reposition stack to C frame.
3006 |.endif
3007 | mov [RAa+CFRAME_OFS_L], L:RB // Set SAVE_L (on-trace resume/yield).
3008 | mov BASE, L:RB->base
3009 | mov PC, [RAa+CFRAME_OFS_PC] // Get SAVE_PC.
3010 |.if X64
3011 | jmp >1
3012 |.endif
3013#endif
3014 |->vm_exit_interp:
3015 | // RD = MULTRES or negated error code, BASE, PC and DISPATCH set.
3016#if LJ_HASJIT
3017 |.if X64
3018 | // Restore additional callee-save registers only used in compiled code.
3019 |.if X64WIN
3020 | lea RAa, [rsp+9*16+4*8]
3021 |1:
3022 | movdqa xmm15, [RAa-9*16]
3023 | movdqa xmm14, [RAa-8*16]
3024 | movdqa xmm13, [RAa-7*16]
3025 | movdqa xmm12, [RAa-6*16]
3026 | movdqa xmm11, [RAa-5*16]
3027 | movdqa xmm10, [RAa-4*16]
3028 | movdqa xmm9, [RAa-3*16]
3029 | movdqa xmm8, [RAa-2*16]
3030 | movdqa xmm7, [RAa-1*16]
3031 | mov rsp, RAa // Reposition stack to C frame.
3032 | movdqa xmm6, [RAa]
3033 | mov r15, CSAVE_3
3034 | mov r14, CSAVE_4
3035 |.else
3036 | add rsp, 16 // Reposition stack to C frame.
3037 |1:
3038 |.endif
3039 | mov r13, TMPa
3040 | mov r12, TMPQ
3041 |.endif
3042 | test RD, RD; js >3 // Check for error from exit.
3043 | mov MULTRES, RD
3044 | mov LFUNC:KBASE, [BASE-8]
3045 | mov KBASE, LFUNC:KBASE->pc
3046 | mov KBASE, [KBASE+PC2PROTO(k)]
3047 | mov dword [DISPATCH+DISPATCH_GL(jit_L)], 0
3048 | set_vmstate INTERP
3049 | // Modified copy of ins_next which handles function header dispatch, too.
3050 | mov RC, [PC]
3051 | movzx RA, RCH
3052 | movzx OP, RCL
3053 | add PC, 4
3054 | shr RC, 16
3055 | cmp OP, BC_FUNCF // Function header?
3056 | jb >2
3057 | mov RC, MULTRES // RC/RD holds nres+1.
3058 |2:
3059 |.if X64
3060 | jmp aword [DISPATCH+OP*8]
3061 |.else
3062 | jmp aword [DISPATCH+OP*4]
3063 |.endif
3064 |
3065 |3: // Rethrow error from the right C frame.
3066 | neg RD
3067 | mov FCARG1, L:RB
3068 | mov FCARG2, RD
3069 | call extern lj_err_throw@8 // (lua_State *L, int errcode)
3070#endif
3071 |
3072 |//-----------------------------------------------------------------------
3073 |//-- Math helper functions ----------------------------------------------
3074 |//-----------------------------------------------------------------------
3075 |
3076 |// FP value rounding. Called by math.floor/math.ceil fast functions
3077 |// and from JIT code.
3078 |
3079 |// x87 variant: Arg/ret on x87 stack. No int/xmm registers modified.
3080 |.macro vm_round_x87, mode1, mode2
3081 | fnstcw word [esp+4] // Caveat: overwrites ARG1 and ARG2.
3082 | mov [esp+8], eax
3083 | mov ax, mode1
3084 | or ax, [esp+4]
3085 |.if mode2 ~= 0xffff
3086 | and ax, mode2
3087 |.endif
3088 | mov [esp+6], ax
3089 | fldcw word [esp+6]
3090 | frndint
3091 | fldcw word [esp+4]
3092 | mov eax, [esp+8]
3093 | ret
3094 |.endmacro
3095 |
3096 |// SSE variant: arg/ret is xmm0. xmm0-xmm3 and RD (eax) modified.
3097 |.macro vm_round_sse, mode
3098 | sseconst_abs xmm2, RDa
3099 | sseconst_2p52 xmm3, RDa
3100 | movaps xmm1, xmm0
3101 | andpd xmm1, xmm2 // |x|
3102 | ucomisd xmm3, xmm1 // No truncation if 2^52 <= |x|.
3103 | jbe >1
3104 | andnpd xmm2, xmm0 // Isolate sign bit.
3105 |.if mode == 2 // trunc(x)?
3106 | movaps xmm0, xmm1
3107 | addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
3108 | subsd xmm1, xmm3
3109 | sseconst_1 xmm3, RDa
3110 | cmpsd xmm0, xmm1, 1 // |x| < result?
3111 | andpd xmm0, xmm3
3112 | subsd xmm1, xmm0 // If yes, subtract -1.
3113 | orpd xmm1, xmm2 // Merge sign bit back in.
3114 |.else
3115 | addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
3116 | subsd xmm1, xmm3
3117 | orpd xmm1, xmm2 // Merge sign bit back in.
3118 | .if mode == 1 // ceil(x)?
3119 | sseconst_m1 xmm2, RDa // Must subtract -1 to preserve -0.
3120 | cmpsd xmm0, xmm1, 6 // x > result?
3121 | .else // floor(x)?
3122 | sseconst_1 xmm2, RDa
3123 | cmpsd xmm0, xmm1, 1 // x < result?
3124 | .endif
3125 | andpd xmm0, xmm2
3126 | subsd xmm1, xmm0 // If yes, subtract +-1.
3127 |.endif
3128 | movaps xmm0, xmm1
3129 |1:
3130 | ret
3131 |.endmacro
3132 |
3133 |.macro vm_round, name, ssemode, mode1, mode2
3134 |->name:
3135 ||if (!sse) {
3136 | vm_round_x87 mode1, mode2
3137 ||}
3138 |->name .. _sse:
3139 | vm_round_sse ssemode
3140 |.endmacro
3141 |
3142 | vm_round vm_floor, 0, 0x0400, 0xf7ff
3143 | vm_round vm_ceil, 1, 0x0800, 0xfbff
3144 | vm_round vm_trunc, 2, 0x0c00, 0xffff
3145 |
3146 |// FP modulo x%y. Called by BC_MOD* and vm_arith.
3147 |->vm_mod:
3148 if (sse) {
3149 |// Args in xmm0/xmm1, return value in xmm0.
3150 |// Caveat: xmm0-xmm5 and RC (eax) modified!
3151 | movaps xmm5, xmm0
3152 | divsd xmm0, xmm1
3153 | sseconst_abs xmm2, RDa
3154 | sseconst_2p52 xmm3, RDa
3155 | movaps xmm4, xmm0
3156 | andpd xmm4, xmm2 // |x/y|
3157 | ucomisd xmm3, xmm4 // No truncation if 2^52 <= |x/y|.
3158 | jbe >1
3159 | andnpd xmm2, xmm0 // Isolate sign bit.
3160 | addsd xmm4, xmm3 // (|x/y| + 2^52) - 2^52
3161 | subsd xmm4, xmm3
3162 | orpd xmm4, xmm2 // Merge sign bit back in.
3163 | sseconst_1 xmm2, RDa
3164 | cmpsd xmm0, xmm4, 1 // x/y < result?
3165 | andpd xmm0, xmm2
3166 | subsd xmm4, xmm0 // If yes, subtract 1.0.
3167 | movaps xmm0, xmm5
3168 | mulsd xmm1, xmm4
3169 | subsd xmm0, xmm1
3170 | ret
3171 |1:
3172 | mulsd xmm1, xmm0
3173 | movaps xmm0, xmm5
3174 | subsd xmm0, xmm1
3175 | ret
3176 } else {
3177 |// Args/ret on x87 stack (y on top). No xmm registers modified.
3178 |// Caveat: needs 3 slots on x87 stack! RC (eax) modified!
3179 | fld st1
3180 | fdiv st1
3181 | fnstcw word [esp+4]
3182 | mov ax, 0x0400
3183 | or ax, [esp+4]
3184 | and ax, 0xf7ff
3185 | mov [esp+6], ax
3186 | fldcw word [esp+6]
3187 | frndint
3188 | fldcw word [esp+4]
3189 | fmulp st1
3190 | fsubp st1
3191 | ret
3192 }
3193 |
3194 |// FP exponentiation e^x and 2^x. Called by math.exp fast function and
3195 |// from JIT code. Arg/ret on x87 stack. No int/xmm regs modified.
3196 |// Caveat: needs 3 slots on x87 stack!
3197 |->vm_exp_x87:
3198 | fldl2e; fmulp st1 // e^x ==> 2^(x*log2(e))
3199 |->vm_exp2_x87:
3200 | .if X64WIN
3201 | .define expscratch, dword [rsp+8] // Use scratch area.
3202 | .elif X64
3203 | .define expscratch, dword [rsp-8] // Use red zone.
3204 | .else
3205 | .define expscratch, dword [esp+4] // Needs 4 byte scratch area.
3206 | .endif
3207 | fst expscratch // Caveat: overwrites ARG1.
3208 | cmp expscratch, 0x7f800000; je >1 // Special case: e^+Inf = +Inf
3209 | cmp expscratch, 0xff800000; je >2 // Special case: e^-Inf = 0
3210 |->vm_exp2raw: // Entry point for vm_pow. Without +-Inf check.
3211 | fdup; frndint; fsub st1, st0; fxch // Split into frac/int part.
3212 | f2xm1; fld1; faddp st1; fscale; fpop1 // ==> (2^frac-1 +1) << int
3213 |1:
3214 | ret
3215 |2:
3216 | fpop; fldz; ret
3217 |
3218 |// Generic power function x^y. Called by BC_POW, math.pow fast function,
3219 |// and vm_arith.
3220 if (!sse) {
3221 |.if not X64
3222 |// Args/ret on x87 stack (y on top). RC (eax) modified.
3223 |// Caveat: needs 3 slots on x87 stack!
3224 |->vm_pow:
3225 | fist dword [esp+4] // Store/reload int before comparison.
3226 | fild dword [esp+4] // Integral exponent used in vm_powi.
3227 ||if (cmov) {
3228 | fucomip st1
3229 ||} else {
3230 | fucomp st1; fnstsw ax; sahf
3231 ||}
3232 | jnz >8 // Branch for FP exponents.
3233 | jp >9 // Branch for NaN exponent.
3234 | fpop // Pop y and fallthrough to vm_powi.
3235 |
3236 |// FP/int power function x^i. Arg1/ret on x87 stack.
3237 |// Arg2 (int) on C stack. RC (eax) modified.
3238 |// Caveat: needs 2 slots on x87 stack!
3239 | mov eax, [esp+4]
3240 | cmp eax, 1; jle >6 // i<=1?
3241 | // Now 1 < (unsigned)i <= 0x80000000.
3242 |1: // Handle leading zeros.
3243 | test eax, 1; jnz >2
3244 | fmul st0
3245 | shr eax, 1
3246 | jmp <1
3247 |2:
3248 | shr eax, 1; jz >5
3249 | fdup
3250 |3: // Handle trailing bits.
3251 | fmul st0
3252 | shr eax, 1; jz >4
3253 | jnc <3
3254 | fmul st1, st0
3255 | jmp <3
3256 |4:
3257 | fmulp st1
3258 |5:
3259 | ret
3260 |6:
3261 | je <5 // x^1 ==> x
3262 | jb >7
3263 | fld1; fdivrp st1
3264 | neg eax
3265 | cmp eax, 1; je <5 // x^-1 ==> 1/x
3266 | jmp <1 // x^-i ==> (1/x)^i
3267 |7:
3268 | fpop; fld1 // x^0 ==> 1
3269 | ret
3270 |
3271 |8: // FP/FP power function x^y.
3272 | fst dword [esp+4]
3273 | fxch
3274 | fst dword [esp+8]
3275 | mov eax, [esp+4]; shl eax, 1
3276 | cmp eax, 0xff000000; je >2 // x^+-Inf?
3277 | mov eax, [esp+8]; shl eax, 1; je >4 // +-0^y?
3278 | cmp eax, 0xff000000; je >4 // +-Inf^y?
3279 | fyl2x
3280 | jmp ->vm_exp2raw
3281 |
3282 |9: // Handle x^NaN.
3283 | fld1
3284 ||if (cmov) {
3285 | fucomip st2
3286 ||} else {
3287 | fucomp st2; fnstsw ax; sahf
3288 ||}
3289 | je >1 // 1^NaN ==> 1
3290 | fxch // x^NaN ==> NaN
3291 |1:
3292 | fpop
3293 | ret
3294 |
3295 |2: // Handle x^+-Inf.
3296 | fabs
3297 | fld1
3298 ||if (cmov) {
3299 | fucomip st1
3300 ||} else {
3301 | fucomp st1; fnstsw ax; sahf
3302 ||}
3303 | je >3 // +-1^+-Inf ==> 1
3304 | fpop; fabs; fldz; mov eax, 0; setc al
3305 | ror eax, 1; xor eax, [esp+4]; jns >3 // |x|<>1, x^+-Inf ==> +Inf/0
3306 | fxch
3307 |3:
3308 | fpop1; fabs
3309 | ret
3310 |
3311 |4: // Handle +-0^y or +-Inf^y.
3312 | cmp dword [esp+4], 0; jge <3 // y >= 0, x^y ==> |x|
3313 | fpop; fpop
3314 | test eax, eax; jz >5 // y < 0, +-0^y ==> +Inf
3315 | fldz // y < 0, +-Inf^y ==> 0
3316 | ret
3317 |5:
3318 | mov dword [esp+4], 0x7f800000 // Return +Inf.
3319 | fld dword [esp+4]
3320 | ret
3321 |.endif
3322 } else {
3323 |->vm_pow:
3324 }
3325 |
3326 |// Args in xmm0/xmm1. Ret in xmm0. xmm0-xmm2 and RC (eax) modified.
3327 |// Needs 16 byte scratch area for x86. Also called from JIT code.
3328 |->vm_pow_sse:
3329 | cvtsd2si eax, xmm1
3330 | cvtsi2sd xmm2, eax
3331 | ucomisd xmm1, xmm2
3332 | jnz >8 // Branch for FP exponents.
3333 | jp >9 // Branch for NaN exponent.
3334 | // Fallthrough to vm_powi_sse.
3335 |
3336 |// Args in xmm0/eax. Ret in xmm0. xmm0-xmm1 and eax modified.
3337 |->vm_powi_sse:
3338 | cmp eax, 1; jle >6 // i<=1?
3339 | // Now 1 < (unsigned)i <= 0x80000000.
3340 |1: // Handle leading zeros.
3341 | test eax, 1; jnz >2
3342 | mulsd xmm0, xmm0
3343 | shr eax, 1
3344 | jmp <1
3345 |2:
3346 | shr eax, 1; jz >5
3347 | movaps xmm1, xmm0
3348 |3: // Handle trailing bits.
3349 | mulsd xmm0, xmm0
3350 | shr eax, 1; jz >4
3351 | jnc <3
3352 | mulsd xmm1, xmm0
3353 | jmp <3
3354 |4:
3355 | mulsd xmm0, xmm1
3356 |5:
3357 | ret
3358 |6:
3359 | je <5 // x^1 ==> x
3360 | jb >7 // x^0 ==> 1
3361 | neg eax
3362 | call <1
3363 | sseconst_1 xmm1, RDa
3364 | divsd xmm1, xmm0
3365 | movaps xmm0, xmm1
3366 | ret
3367 |7:
3368 | sseconst_1 xmm0, RDa
3369 | ret
3370 |
3371 |8: // FP/FP power function x^y.
3372 |.if X64
3373 | movd rax, xmm1; shl rax, 1
3374 | rol rax, 12; cmp rax, 0xffe; je >2 // x^+-Inf?
3375 | movd rax, xmm0; shl rax, 1; je >4 // +-0^y?
3376 | rol rax, 12; cmp rax, 0xffe; je >5 // +-Inf^y?
3377 | .if X64WIN
3378 | movsd qword [rsp+16], xmm1 // Use scratch area.
3379 | movsd qword [rsp+8], xmm0
3380 | fld qword [rsp+16]
3381 | fld qword [rsp+8]
3382 | .else
3383 | movsd qword [rsp-16], xmm1 // Use red zone.
3384 | movsd qword [rsp-8], xmm0
3385 | fld qword [rsp-16]
3386 | fld qword [rsp-8]
3387 | .endif
3388 |.else
3389 | movsd qword [esp+12], xmm1 // Needs 16 byte scratch area.
3390 | movsd qword [esp+4], xmm0
3391 | cmp dword [esp+12], 0; jne >1
3392 | mov eax, [esp+16]; shl eax, 1
3393 | cmp eax, 0xffe00000; je >2 // x^+-Inf?
3394 |1:
3395 | cmp dword [esp+4], 0; jne >1
3396 | mov eax, [esp+8]; shl eax, 1; je >4 // +-0^y?
3397 | cmp eax, 0xffe00000; je >5 // +-Inf^y?
3398 |1:
3399 | fld qword [esp+12]
3400 | fld qword [esp+4]
3401 |.endif
3402 | fyl2x // y*log2(x)
3403 | fdup; frndint; fsub st1, st0; fxch // Split into frac/int part.
3404 | f2xm1; fld1; faddp st1; fscale; fpop1 // ==> (2^frac-1 +1) << int
3405 |.if X64WIN
3406 | fstp qword [rsp+8] // Use scratch area.
3407 | movsd xmm0, qword [rsp+8]
3408 |.elif X64
3409 | fstp qword [rsp-8] // Use red zone.
3410 | movsd xmm0, qword [rsp-8]
3411 |.else
3412 | fstp qword [esp+4] // Needs 8 byte scratch area.
3413 | movsd xmm0, qword [esp+4]
3414 |.endif
3415 | ret
3416 |
3417 |9: // Handle x^NaN.
3418 | sseconst_1 xmm2, RDa
3419 | ucomisd xmm0, xmm2; je >1 // 1^NaN ==> 1
3420 | movaps xmm0, xmm1 // x^NaN ==> NaN
3421 |1:
3422 | ret
3423 |
3424 |2: // Handle x^+-Inf.
3425 | sseconst_abs xmm2, RDa
3426 | andpd xmm0, xmm2 // |x|
3427 | sseconst_1 xmm2, RDa
3428 | ucomisd xmm0, xmm2; je <1 // +-1^+-Inf ==> 1
3429 | movmskpd eax, xmm1
3430 | xorps xmm0, xmm0
3431 | mov ah, al; setc al; xor al, ah; jne <1 // |x|<>1, x^+-Inf ==> +Inf/0
3432 |3:
3433 | sseconst_hi xmm0, RDa, 7ff00000 // +Inf
3434 | ret
3435 |
3436 |4: // Handle +-0^y.
3437 | movmskpd eax, xmm1; test eax, eax; jnz <3 // y < 0, +-0^y ==> +Inf
3438 | xorps xmm0, xmm0 // y >= 0, +-0^y ==> 0
3439 | ret
3440 |
3441 |5: // Handle +-Inf^y.
3442 | movmskpd eax, xmm1; test eax, eax; jz <3 // y >= 0, +-Inf^y ==> +Inf
3443 | xorps xmm0, xmm0 // y < 0, +-Inf^y ==> 0
3444 | ret
3445 |
3446 |// Callable from C: double lj_vm_foldfpm(double x, int fpm)
3447 |// Computes fpm(x) for extended math functions. ORDER FPM.
3448 |->vm_foldfpm:
3449#if LJ_HASJIT
3450 if (sse) {
3451 |.if X64
3452 |
3453 | .if X64WIN
3454 | .define fpmop, CARG2d
3455 | .else
3456 | .define fpmop, CARG1d
3457 | .endif
3458 | cmp fpmop, 1; jb ->vm_floor; je ->vm_ceil
3459 | cmp fpmop, 3; jb ->vm_trunc; ja >2
3460 | sqrtsd xmm0, xmm0; ret
3461 |2:
3462 | .if X64WIN
3463 | movsd qword [rsp+8], xmm0 // Use scratch area.
3464 | fld qword [rsp+8]
3465 | .else
3466 | movsd qword [rsp-8], xmm0 // Use red zone.
3467 | fld qword [rsp-8]
3468 | .endif
3469 | cmp fpmop, 5; ja >2
3470 | .if X64WIN; pop rax; .endif
3471 | je >1
3472 | call ->vm_exp_x87
3473 | .if X64WIN; push rax; .endif
3474 | jmp >7
3475 |1:
3476 | call ->vm_exp2_x87
3477 | .if X64WIN; push rax; .endif
3478 | jmp >7
3479 |2: ; cmp fpmop, 7; je >1; ja >2
3480 | fldln2; fxch; fyl2x; jmp >7
3481 |1: ; fld1; fxch; fyl2x; jmp >7
3482 |2: ; cmp fpmop, 9; je >1; ja >2
3483 | fldlg2; fxch; fyl2x; jmp >7
3484 |1: ; fsin; jmp >7
3485 |2: ; cmp fpmop, 11; je >1; ja >9
3486 | fcos; jmp >7
3487 |1: ; fptan; fpop
3488 |7:
3489 | .if X64WIN
3490 | fstp qword [rsp+8] // Use scratch area.
3491 | movsd xmm0, qword [rsp+8]
3492 | .else
3493 | fstp qword [rsp-8] // Use red zone.
3494 | movsd xmm0, qword [rsp-8]
3495 | .endif
3496 | ret
3497 |
3498 |.else // x86 calling convention.
3499 |
3500 | .define fpmop, eax
3501 | mov fpmop, [esp+12]
3502 | movsd xmm0, qword [esp+4]
3503 | cmp fpmop, 1; je >1; ja >2
3504 | call ->vm_floor; jmp >7
3505 |1: ; call ->vm_ceil; jmp >7
3506 |2: ; cmp fpmop, 3; je >1; ja >2
3507 | call ->vm_trunc; jmp >7
3508 |1:
3509 | sqrtsd xmm0, xmm0
3510 |7:
3511 | movsd qword [esp+4], xmm0 // Overwrite callee-owned args.
3512 | fld qword [esp+4]
3513 | ret
3514 |2: ; fld qword [esp+4]
3515 | cmp fpmop, 5; jb ->vm_exp_x87; je ->vm_exp2_x87
3516 |2: ; cmp fpmop, 7; je >1; ja >2
3517 | fldln2; fxch; fyl2x; ret
3518 |1: ; fld1; fxch; fyl2x; ret
3519 |2: ; cmp fpmop, 9; je >1; ja >2
3520 | fldlg2; fxch; fyl2x; ret
3521 |1: ; fsin; ret
3522 |2: ; cmp fpmop, 11; je >1; ja >9
3523 | fcos; ret
3524 |1: ; fptan; fpop; ret
3525 |
3526 |.endif
3527 } else {
3528 | mov fpmop, [esp+12]
3529 | fld qword [esp+4]
3530 | cmp fpmop, 1; jb ->vm_floor; je ->vm_ceil
3531 | cmp fpmop, 3; jb ->vm_trunc; ja >2
3532 | fsqrt; ret
3533 |2: ; cmp fpmop, 5; jb ->vm_exp_x87; je ->vm_exp2_x87
3534 | cmp fpmop, 7; je >1; ja >2
3535 | fldln2; fxch; fyl2x; ret
3536 |1: ; fld1; fxch; fyl2x; ret
3537 |2: ; cmp fpmop, 9; je >1; ja >2
3538 | fldlg2; fxch; fyl2x; ret
3539 |1: ; fsin; ret
3540 |2: ; cmp fpmop, 11; je >1; ja >9
3541 | fcos; ret
3542 |1: ; fptan; fpop; ret
3543 }
3544 |9: ; int3 // Bad fpm.
3545#endif
3546 |
3547 |// Callable from C: double lj_vm_foldarith(double x, double y, int op)
3548 |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
3549 |// and basic math functions. ORDER ARITH
3550 |->vm_foldarith:
3551 if (sse) {
3552 |.if X64
3553 |
3554 | .if X64WIN
3555 | .define foldop, CARG3d
3556 | .else
3557 | .define foldop, CARG1d
3558 | .endif
3559 | cmp foldop, 1; je >1; ja >2
3560 | addsd xmm0, xmm1; ret
3561 |1: ; subsd xmm0, xmm1; ret
3562 |2: ; cmp foldop, 3; je >1; ja >2
3563 | mulsd xmm0, xmm1; ret
3564 |1: ; divsd xmm0, xmm1; ret
3565 |2: ; cmp foldop, 5; jb ->vm_mod; je ->vm_pow
3566 | cmp foldop, 7; je >1; ja >2
3567 | sseconst_sign xmm1, RDa; xorps xmm0, xmm1; ret
3568 |1: ; sseconst_abs xmm1, RDa; andps xmm0, xmm1; ret
3569 |2: ; cmp foldop, 9; ja >2
3570 |.if X64WIN
3571 | movsd qword [rsp+8], xmm0 // Use scratch area.
3572 | movsd qword [rsp+16], xmm1
3573 | fld qword [rsp+8]
3574 | fld qword [rsp+16]
3575 |.else
3576 | movsd qword [rsp-8], xmm0 // Use red zone.
3577 | movsd qword [rsp-16], xmm1
3578 | fld qword [rsp-8]
3579 | fld qword [rsp-16]
3580 |.endif
3581 | je >1
3582 | fpatan
3583 |7:
3584 |.if X64WIN
3585 | fstp qword [rsp+8] // Use scratch area.
3586 | movsd xmm0, qword [rsp+8]
3587 |.else
3588 | fstp qword [rsp-8] // Use red zone.
3589 | movsd xmm0, qword [rsp-8]
3590 |.endif
3591 | ret
3592 |1: ; fxch; fscale; fpop1; jmp <7
3593 |2: ; cmp foldop, 11; je >1; ja >9
3594 | minsd xmm0, xmm1; ret
3595 |1: ; maxsd xmm0, xmm1; ret
3596 |9: ; int3 // Bad op.
3597 |
3598 |.else // x86 calling convention.
3599 |
3600 | .define foldop, eax
3601 | mov foldop, [esp+20]
3602 | movsd xmm0, qword [esp+4]
3603 | movsd xmm1, qword [esp+12]
3604 | cmp foldop, 1; je >1; ja >2
3605 | addsd xmm0, xmm1
3606 |7:
3607 | movsd qword [esp+4], xmm0 // Overwrite callee-owned args.
3608 | fld qword [esp+4]
3609 | ret
3610 |1: ; subsd xmm0, xmm1; jmp <7
3611 |2: ; cmp foldop, 3; je >1; ja >2
3612 | mulsd xmm0, xmm1; jmp <7
3613 |1: ; divsd xmm0, xmm1; jmp <7
3614 |2: ; cmp foldop, 5
3615 | je >1; ja >2
3616 | call ->vm_mod; jmp <7
3617 |1: ; pop edx; call ->vm_pow; push edx; jmp <7 // Writes to scratch area.
3618 |2: ; cmp foldop, 7; je >1; ja >2
3619 | sseconst_sign xmm1, RDa; xorps xmm0, xmm1; jmp <7
3620 |1: ; sseconst_abs xmm1, RDa; andps xmm0, xmm1; jmp <7
3621 |2: ; cmp foldop, 9; ja >2
3622 | fld qword [esp+4] // Reload from stack
3623 | fld qword [esp+12]
3624 | je >1
3625 | fpatan; ret
3626 |1: ; fxch; fscale; fpop1; ret
3627 |2: ; cmp foldop, 11; je >1; ja >9
3628 | minsd xmm0, xmm1; jmp <7
3629 |1: ; maxsd xmm0, xmm1; jmp <7
3630 |9: ; int3 // Bad op.
3631 |
3632 |.endif
3633 } else {
3634 | mov eax, [esp+20]
3635 | fld qword [esp+4]
3636 | fld qword [esp+12]
3637 | cmp eax, 1; je >1; ja >2
3638 | faddp st1; ret
3639 |1: ; fsubp st1; ret
3640 |2: ; cmp eax, 3; je >1; ja >2
3641 | fmulp st1; ret
3642 |1: ; fdivp st1; ret
3643 |2: ; cmp eax, 5; jb ->vm_mod; je ->vm_pow
3644 | cmp eax, 7; je >1; ja >2
3645 | fpop; fchs; ret
3646 |1: ; fpop; fabs; ret
3647 |2: ; cmp eax, 9; je >1; ja >2
3648 | fpatan; ret
3649 |1: ; fxch; fscale; fpop1; ret
3650 |2: ; cmp eax, 11; je >1; ja >9
3651 ||if (cmov) {
3652 | fucomi st1; fcmovnbe st1; fpop1; ret
3653 |1: ; fucomi st1; fcmovbe st1; fpop1; ret
3654 ||} else {
3655 | fucom st1; fnstsw ax; test ah, 1; jz >2; fxch; 2: ; fpop; ret
3656 |1: ; fucom st1; fnstsw ax; test ah, 1; jnz >2; fxch; 2: ; fpop; ret
3657 ||}
3658 |9: ; int3 // Bad op.
3659 }
3660 |
3661 |//-----------------------------------------------------------------------
3662 |//-- Miscellaneous functions --------------------------------------------
3663 |//-----------------------------------------------------------------------
3664 |
3665 |// int lj_vm_cpuid(uint32_t f, uint32_t res[4])
3666 |->vm_cpuid:
3667 |.if X64
3668 | mov eax, CARG1d
3669 | .if X64WIN; push rsi; mov rsi, CARG2; .endif
3670 | push rbx
3671 | cpuid
3672 | mov [rsi], eax
3673 | mov [rsi+4], ebx
3674 | mov [rsi+8], ecx
3675 | mov [rsi+12], edx
3676 | pop rbx
3677 | .if X64WIN; pop rsi; .endif
3678 | ret
3679 |.else
3680 | pushfd
3681 | pop edx
3682 | mov ecx, edx
3683 | xor edx, 0x00200000 // Toggle ID bit in flags.
3684 | push edx
3685 | popfd
3686 | pushfd
3687 | pop edx
3688 | xor eax, eax // Zero means no features supported.
3689 | cmp ecx, edx
3690 | jz >1 // No ID toggle means no CPUID support.
3691 | mov eax, [esp+4] // Argument 1 is function number.
3692 | push edi
3693 | push ebx
3694 | cpuid
3695 | mov edi, [esp+16] // Argument 2 is result area.
3696 | mov [edi], eax
3697 | mov [edi+4], ebx
3698 | mov [edi+8], ecx
3699 | mov [edi+12], edx
3700 | pop ebx
3701 | pop edi
3702 |1:
3703 | ret
3704 |.endif
3705 |
3706 |//-----------------------------------------------------------------------
3707 |//-- Assertions ---------------------------------------------------------
3708 |//-----------------------------------------------------------------------
3709 |
3710 |->assert_bad_for_arg_type:
3711#ifdef LUA_USE_ASSERT
3712 | int3
3713#endif
3714 | int3
3715 |
3716 |//-----------------------------------------------------------------------
3717 |//-- FFI helper functions -----------------------------------------------
3718 |//-----------------------------------------------------------------------
3719 |
3720 |// Handler for callback functions. Callback slot number in ah/al.
3721 |->vm_ffi_callback:
3722#if LJ_HASFFI
3723 |.type CTSTATE, CTState, PC
3724 |.if not X64
3725 | sub esp, 16 // Leave room for SAVE_ERRF etc.
3726 |.endif
3727 | saveregs_ // ebp/rbp already saved. ebp now holds global_State *.
3728 | lea DISPATCH, [ebp+GG_G2DISP]
3729 | mov CTSTATE, GL:ebp->ctype_state
3730 | movzx eax, ax
3731 | mov CTSTATE->cb.slot, eax
3732 |.if X64
3733 | mov CTSTATE->cb.gpr[0], CARG1
3734 | mov CTSTATE->cb.gpr[1], CARG2
3735 | mov CTSTATE->cb.gpr[2], CARG3
3736 | mov CTSTATE->cb.gpr[3], CARG4
3737 | movsd qword CTSTATE->cb.fpr[0], xmm0
3738 | movsd qword CTSTATE->cb.fpr[1], xmm1
3739 | movsd qword CTSTATE->cb.fpr[2], xmm2
3740 | movsd qword CTSTATE->cb.fpr[3], xmm3
3741 |.if X64WIN
3742 | lea rax, [rsp+CFRAME_SIZE+4*8]
3743 |.else
3744 | lea rax, [rsp+CFRAME_SIZE]
3745 | mov CTSTATE->cb.gpr[4], CARG5
3746 | mov CTSTATE->cb.gpr[5], CARG6
3747 | movsd qword CTSTATE->cb.fpr[4], xmm4
3748 | movsd qword CTSTATE->cb.fpr[5], xmm5
3749 | movsd qword CTSTATE->cb.fpr[6], xmm6
3750 | movsd qword CTSTATE->cb.fpr[7], xmm7
3751 |.endif
3752 | mov CTSTATE->cb.stack, rax
3753 | mov CARG2, rsp
3754 |.else
3755 | lea eax, [esp+CFRAME_SIZE+16]
3756 | mov CTSTATE->cb.gpr[0], FCARG1
3757 | mov CTSTATE->cb.gpr[1], FCARG2
3758 | mov CTSTATE->cb.stack, eax
3759 | mov FCARG1, [esp+CFRAME_SIZE+12] // Move around misplaced retaddr/ebp.
3760 | mov FCARG2, [esp+CFRAME_SIZE+8]
3761 | mov SAVE_RET, FCARG1
3762 | mov SAVE_R4, FCARG2
3763 | mov FCARG2, esp
3764 |.endif
3765 | mov SAVE_PC, CTSTATE // Any value outside of bytecode is ok.
3766 | mov FCARG1, CTSTATE
3767 | call extern lj_ccallback_enter@8 // (CTState *cts, void *cf)
3768 | // lua_State * returned in eax (RD).
3769 | set_vmstate INTERP
3770 | mov BASE, L:RD->base
3771 | mov RD, L:RD->top
3772 | sub RD, BASE
3773 | mov LFUNC:RB, [BASE-8]
3774 | shr RD, 3
3775 | add RD, 1
3776 | ins_callt
3777#endif
3778 |
3779 |->cont_ffi_callback: // Return from FFI callback.
3780#if LJ_HASFFI
3781 | mov L:RA, SAVE_L
3782 | mov CTSTATE, [DISPATCH+DISPATCH_GL(ctype_state)]
3783 | mov aword CTSTATE->L, L:RAa
3784 | mov L:RA->base, BASE
3785 | mov L:RA->top, RB
3786 | mov FCARG1, CTSTATE
3787 | mov FCARG2, RC
3788 | call extern lj_ccallback_leave@8 // (CTState *cts, TValue *o)
3789 |.if X64
3790 | mov rax, CTSTATE->cb.gpr[0]
3791 | movsd xmm0, qword CTSTATE->cb.fpr[0]
3792 | jmp ->vm_leave_unw
3793 |.else
3794 | mov L:RB, SAVE_L
3795 | mov eax, CTSTATE->cb.gpr[0]
3796 | mov edx, CTSTATE->cb.gpr[1]
3797 | cmp dword CTSTATE->cb.gpr[2], 1
3798 | jb >7
3799 | je >6
3800 | fld qword CTSTATE->cb.fpr[0].d
3801 | jmp >7
3802 |6:
3803 | fld dword CTSTATE->cb.fpr[0].f
3804 |7:
3805 | mov ecx, L:RB->top
3806 | movzx ecx, word [ecx+6] // Get stack adjustment and copy up.
3807 | mov SAVE_L, ecx // Must be one slot above SAVE_RET
3808 | restoreregs
3809 | pop ecx // Move return addr from SAVE_RET.
3810 | add esp, [esp] // Adjust stack.
3811 | add esp, 16
3812 | push ecx
3813 | ret
3814 |.endif
3815#endif
3816 |
3817 |->vm_ffi_call@4: // Call C function via FFI.
3818 | // Caveat: needs special frame unwinding, see below.
3819#if LJ_HASFFI
3820 |.if X64
3821 | .type CCSTATE, CCallState, rbx
3822 | push rbp; mov rbp, rsp; push rbx; mov CCSTATE, CARG1
3823 |.else
3824 | .type CCSTATE, CCallState, ebx
3825 | push ebp; mov ebp, esp; push ebx; mov CCSTATE, FCARG1
3826 |.endif
3827 |
3828 | // Readjust stack.
3829 |.if X64
3830 | mov eax, CCSTATE->spadj
3831 | sub rsp, rax
3832 |.else
3833 | sub esp, CCSTATE->spadj
3834#if LJ_TARGET_WINDOWS
3835 | mov CCSTATE->spadj, esp
3836#endif
3837 |.endif
3838 |
3839 | // Copy stack slots.
3840 | movzx ecx, byte CCSTATE->nsp
3841 | sub ecx, 1
3842 | js >2
3843 |1:
3844 |.if X64
3845 | mov rax, [CCSTATE+rcx*8+offsetof(CCallState, stack)]
3846 | mov [rsp+rcx*8+CCALL_SPS_EXTRA*8], rax
3847 |.else
3848 | mov eax, [CCSTATE+ecx*4+offsetof(CCallState, stack)]
3849 | mov [esp+ecx*4], eax
3850 |.endif
3851 | sub ecx, 1
3852 | jns <1
3853 |2:
3854 |
3855 |.if X64
3856 | movzx eax, byte CCSTATE->nfpr
3857 | mov CARG1, CCSTATE->gpr[0]
3858 | mov CARG2, CCSTATE->gpr[1]
3859 | mov CARG3, CCSTATE->gpr[2]
3860 | mov CARG4, CCSTATE->gpr[3]
3861 |.if not X64WIN
3862 | mov CARG5, CCSTATE->gpr[4]
3863 | mov CARG6, CCSTATE->gpr[5]
3864 |.endif
3865 | test eax, eax; jz >5
3866 | movaps xmm0, CCSTATE->fpr[0]
3867 | movaps xmm1, CCSTATE->fpr[1]
3868 | movaps xmm2, CCSTATE->fpr[2]
3869 | movaps xmm3, CCSTATE->fpr[3]
3870 |.if not X64WIN
3871 | cmp eax, 4; jbe >5
3872 | movaps xmm4, CCSTATE->fpr[4]
3873 | movaps xmm5, CCSTATE->fpr[5]
3874 | movaps xmm6, CCSTATE->fpr[6]
3875 | movaps xmm7, CCSTATE->fpr[7]
3876 |.endif
3877 |5:
3878 |.else
3879 | mov FCARG1, CCSTATE->gpr[0]
3880 | mov FCARG2, CCSTATE->gpr[1]
3881 |.endif
3882 |
3883 | call aword CCSTATE->func
3884 |
3885 |.if X64
3886 | mov CCSTATE->gpr[0], rax
3887 | movaps CCSTATE->fpr[0], xmm0
3888 |.if not X64WIN
3889 | mov CCSTATE->gpr[1], rdx
3890 | movaps CCSTATE->fpr[1], xmm1
3891 |.endif
3892 |.else
3893 | mov CCSTATE->gpr[0], eax
3894 | mov CCSTATE->gpr[1], edx
3895 | cmp byte CCSTATE->resx87, 1
3896 | jb >7
3897 | je >6
3898 | fstp qword CCSTATE->fpr[0].d[0]
3899 | jmp >7
3900 |6:
3901 | fstp dword CCSTATE->fpr[0].f[0]
3902 |7:
3903#if LJ_TARGET_WINDOWS
3904 | sub CCSTATE->spadj, esp
3905#endif
3906 |.endif
3907 |
3908 |.if X64
3909 | mov rbx, [rbp-8]; leave; ret
3910 |.else
3911 | mov ebx, [ebp-4]; leave; ret
3912 |.endif
3913#endif
3914 |// Note: vm_ffi_call must be the last function in this object file!
3915 |
3916 |//-----------------------------------------------------------------------
3917}
3918
3919/* Generate the code for a single instruction. */
3920static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse)
3921{
3922 int vk = 0;
3923 |// Note: aligning all instructions does not pay off.
3924 |=>defop:
3925
3926 switch (op) {
3927
3928 /* -- Comparison ops ---------------------------------------------------- */
3929
3930 /* Remember: all ops branch for a true comparison, fall through otherwise. */
3931
3932 |.macro jmp_comp, lt, ge, le, gt, target
3933 ||switch (op) {
3934 ||case BC_ISLT:
3935 | lt target
3936 ||break;
3937 ||case BC_ISGE:
3938 | ge target
3939 ||break;
3940 ||case BC_ISLE:
3941 | le target
3942 ||break;
3943 ||case BC_ISGT:
3944 | gt target
3945 ||break;
3946 ||default: break; /* Shut up GCC. */
3947 ||}
3948 |.endmacro
3949
3950 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
3951 | // RA = src1, RD = src2, JMP with RD = target
3952 | ins_AD
3953 if (LJ_DUALNUM) {
3954 | checkint RA, >7
3955 | checkint RD, >8
3956 | mov RB, dword [BASE+RA*8]
3957 | add PC, 4
3958 | cmp RB, dword [BASE+RD*8]
3959 | jmp_comp jge, jl, jg, jle, >9
3960 |6:
3961 | movzx RD, PC_RD
3962 | branchPC RD
3963 |9:
3964 | ins_next
3965 |
3966 |7: // RA is not an integer.
3967 | ja ->vmeta_comp
3968 | // RA is a number.
3969 | cmp dword [BASE+RD*8+4], LJ_TISNUM; jb >1; jne ->vmeta_comp
3970 | // RA is a number, RD is an integer.
3971 if (sse) {
3972 | cvtsi2sd xmm0, dword [BASE+RD*8]
3973 | jmp >2
3974 } else {
3975 | fld qword [BASE+RA*8]
3976 | fild dword [BASE+RD*8]
3977 | jmp >3
3978 }
3979 |
3980 |8: // RA is an integer, RD is not an integer.
3981 | ja ->vmeta_comp
3982 | // RA is an integer, RD is a number.
3983 if (sse) {
3984 | cvtsi2sd xmm1, dword [BASE+RA*8]
3985 | movsd xmm0, qword [BASE+RD*8]
3986 | add PC, 4
3987 | ucomisd xmm0, xmm1
3988 | jmp_comp jbe, ja, jb, jae, <9
3989 | jmp <6
3990 } else {
3991 | fild dword [BASE+RA*8]
3992 | jmp >2
3993 }
3994 } else {
3995 | checknum RA, ->vmeta_comp
3996 | checknum RD, ->vmeta_comp
3997 }
3998 if (sse) {
3999 |1:
4000 | movsd xmm0, qword [BASE+RD*8]
4001 |2:
4002 | add PC, 4
4003 | ucomisd xmm0, qword [BASE+RA*8]
4004 |3:
4005 } else {
4006 |1:
4007 | fld qword [BASE+RA*8] // Reverse order, i.e like cmp D, A.
4008 |2:
4009 | fld qword [BASE+RD*8]
4010 |3:
4011 | add PC, 4
4012 | fcomparepp // eax (RD) modified!
4013 }
4014 | // Unordered: all of ZF CF PF set, ordered: PF clear.
4015 | // To preserve NaN semantics GE/GT branch on unordered, but LT/LE don't.
4016 if (LJ_DUALNUM) {
4017 | jmp_comp jbe, ja, jb, jae, <9
4018 | jmp <6
4019 } else {
4020 | jmp_comp jbe, ja, jb, jae, >1
4021 | movzx RD, PC_RD
4022 | branchPC RD
4023 |1:
4024 | ins_next
4025 }
4026 break;
4027
4028 case BC_ISEQV: case BC_ISNEV:
4029 vk = op == BC_ISEQV;
4030 | ins_AD // RA = src1, RD = src2, JMP with RD = target
4031 | mov RB, [BASE+RD*8+4]
4032 | add PC, 4
4033 if (LJ_DUALNUM) {
4034 | cmp RB, LJ_TISNUM; jne >7
4035 | checkint RA, >8
4036 | mov RB, dword [BASE+RD*8]
4037 | cmp RB, dword [BASE+RA*8]
4038 if (vk) {
4039 | jne >9
4040 } else {
4041 | je >9
4042 }
4043 | movzx RD, PC_RD
4044 | branchPC RD
4045 |9:
4046 | ins_next
4047 |
4048 |7: // RD is not an integer.
4049 | ja >5
4050 | // RD is a number.
4051 | cmp dword [BASE+RA*8+4], LJ_TISNUM; jb >1; jne >5
4052 | // RD is a number, RA is an integer.
4053 if (sse) {
4054 | cvtsi2sd xmm0, dword [BASE+RA*8]
4055 } else {
4056 | fild dword [BASE+RA*8]
4057 }
4058 | jmp >2
4059 |
4060 |8: // RD is an integer, RA is not an integer.
4061 | ja >5
4062 | // RD is an integer, RA is a number.
4063 if (sse) {
4064 | cvtsi2sd xmm0, dword [BASE+RD*8]
4065 | ucomisd xmm0, qword [BASE+RA*8]
4066 } else {
4067 | fild dword [BASE+RD*8]
4068 | fld qword [BASE+RA*8]
4069 }
4070 | jmp >4
4071 |
4072 } else {
4073 | cmp RB, LJ_TISNUM; jae >5
4074 | checknum RA, >5
4075 }
4076 if (sse) {
4077 |1:
4078 | movsd xmm0, qword [BASE+RA*8]
4079 |2:
4080 | ucomisd xmm0, qword [BASE+RD*8]
4081 |4:
4082 } else {
4083 |1:
4084 | fld qword [BASE+RA*8]
4085 |2:
4086 | fld qword [BASE+RD*8]
4087 |4:
4088 | fcomparepp // eax (RD) modified!
4089 }
4090 iseqne_fp:
4091 if (vk) {
4092 | jp >2 // Unordered means not equal.
4093 | jne >2
4094 } else {
4095 | jp >2 // Unordered means not equal.
4096 | je >1
4097 }
4098 iseqne_end:
4099 if (vk) {
4100 |1: // EQ: Branch to the target.
4101 | movzx RD, PC_RD
4102 | branchPC RD
4103 |2: // NE: Fallthrough to next instruction.
4104 if (!LJ_HASFFI) {
4105 |3:
4106 }
4107 } else {
4108 if (!LJ_HASFFI) {
4109 |3:
4110 }
4111 |2: // NE: Branch to the target.
4112 | movzx RD, PC_RD
4113 | branchPC RD
4114 |1: // EQ: Fallthrough to next instruction.
4115 }
4116 if (LJ_DUALNUM && (op == BC_ISEQV || op == BC_ISNEV ||
4117 op == BC_ISEQN || op == BC_ISNEN)) {
4118 | jmp <9
4119 } else {
4120 | ins_next
4121 }
4122 |
4123 if (op == BC_ISEQV || op == BC_ISNEV) {
4124 |5: // Either or both types are not numbers.
4125 if (LJ_HASFFI) {
4126 | cmp RB, LJ_TCDATA; je ->vmeta_equal_cd
4127 | checktp RA, LJ_TCDATA; je ->vmeta_equal_cd
4128 }
4129 | checktp RA, RB // Compare types.
4130 | jne <2 // Not the same type?
4131 | cmp RB, LJ_TISPRI
4132 | jae <1 // Same type and primitive type?
4133 |
4134 | // Same types and not a primitive type. Compare GCobj or pvalue.
4135 | mov RA, [BASE+RA*8]
4136 | mov RD, [BASE+RD*8]
4137 | cmp RA, RD
4138 | je <1 // Same GCobjs or pvalues?
4139 | cmp RB, LJ_TISTABUD
4140 | ja <2 // Different objects and not table/ud?
4141 |.if X64
4142 | cmp RB, LJ_TUDATA // And not 64 bit lightuserdata.
4143 | jb <2
4144 |.endif
4145 |
4146 | // Different tables or userdatas. Need to check __eq metamethod.
4147 | // Field metatable must be at same offset for GCtab and GCudata!
4148 | mov TAB:RB, TAB:RA->metatable
4149 | test TAB:RB, TAB:RB
4150 | jz <2 // No metatable?
4151 | test byte TAB:RB->nomm, 1<<MM_eq
4152 | jnz <2 // Or 'no __eq' flag set?
4153 if (vk) {
4154 | xor RB, RB // ne = 0
4155 } else {
4156 | mov RB, 1 // ne = 1
4157 }
4158 | jmp ->vmeta_equal // Handle __eq metamethod.
4159 } else if (LJ_HASFFI) {
4160 |3:
4161 | cmp RB, LJ_TCDATA
4162 if (LJ_DUALNUM && vk) {
4163 | jne <9
4164 } else {
4165 | jne <2
4166 }
4167 | jmp ->vmeta_equal_cd
4168 }
4169 break;
4170 case BC_ISEQS: case BC_ISNES:
4171 vk = op == BC_ISEQS;
4172 | ins_AND // RA = src, RD = str const, JMP with RD = target
4173 | mov RB, [BASE+RA*8+4]
4174 | add PC, 4
4175 | cmp RB, LJ_TSTR; jne >3
4176 | mov RA, [BASE+RA*8]
4177 | cmp RA, [KBASE+RD*4]
4178 iseqne_test:
4179 if (vk) {
4180 | jne >2
4181 } else {
4182 | je >1
4183 }
4184 goto iseqne_end;
4185 case BC_ISEQN: case BC_ISNEN:
4186 vk = op == BC_ISEQN;
4187 | ins_AD // RA = src, RD = num const, JMP with RD = target
4188 | mov RB, [BASE+RA*8+4]
4189 | add PC, 4
4190 if (LJ_DUALNUM) {
4191 | cmp RB, LJ_TISNUM; jne >7
4192 | cmp dword [KBASE+RD*8+4], LJ_TISNUM; jne >8
4193 | mov RB, dword [KBASE+RD*8]
4194 | cmp RB, dword [BASE+RA*8]
4195 if (vk) {
4196 | jne >9
4197 } else {
4198 | je >9
4199 }
4200 | movzx RD, PC_RD
4201 | branchPC RD
4202 |9:
4203 | ins_next
4204 |
4205 |7: // RA is not an integer.
4206 | ja >3
4207 | // RA is a number.
4208 | cmp dword [KBASE+RD*8+4], LJ_TISNUM; jb >1
4209 | // RA is a number, RD is an integer.
4210 if (sse) {
4211 | cvtsi2sd xmm0, dword [KBASE+RD*8]
4212 } else {
4213 | fild dword [KBASE+RD*8]
4214 }
4215 | jmp >2
4216 |
4217 |8: // RA is an integer, RD is a number.
4218 if (sse) {
4219 | cvtsi2sd xmm0, dword [BASE+RA*8]
4220 | ucomisd xmm0, qword [KBASE+RD*8]
4221 } else {
4222 | fild dword [BASE+RA*8]
4223 | fld qword [KBASE+RD*8]
4224 }
4225 | jmp >4
4226 } else {
4227 | cmp RB, LJ_TISNUM; jae >3
4228 }
4229 if (sse) {
4230 |1:
4231 | movsd xmm0, qword [KBASE+RD*8]
4232 |2:
4233 | ucomisd xmm0, qword [BASE+RA*8]
4234 |4:
4235 } else {
4236 |1:
4237 | fld qword [KBASE+RD*8]
4238 |2:
4239 | fld qword [BASE+RA*8]
4240 |4:
4241 | fcomparepp // eax (RD) modified!
4242 }
4243 goto iseqne_fp;
4244 case BC_ISEQP: case BC_ISNEP:
4245 vk = op == BC_ISEQP;
4246 | ins_AND // RA = src, RD = primitive type (~), JMP with RD = target
4247 | mov RB, [BASE+RA*8+4]
4248 | add PC, 4
4249 | cmp RB, RD
4250 if (!LJ_HASFFI) goto iseqne_test;
4251 if (vk) {
4252 | jne >3
4253 | movzx RD, PC_RD
4254 | branchPC RD
4255 |2:
4256 | ins_next
4257 |3:
4258 | cmp RB, LJ_TCDATA; jne <2
4259 | jmp ->vmeta_equal_cd
4260 } else {
4261 | je >2
4262 | cmp RB, LJ_TCDATA; je ->vmeta_equal_cd
4263 | movzx RD, PC_RD
4264 | branchPC RD
4265 |2:
4266 | ins_next
4267 }
4268 break;
4269
4270 /* -- Unary test and copy ops ------------------------------------------- */
4271
4272 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
4273 | ins_AD // RA = dst or unused, RD = src, JMP with RD = target
4274 | mov RB, [BASE+RD*8+4]
4275 | add PC, 4
4276 | cmp RB, LJ_TISTRUECOND
4277 if (op == BC_IST || op == BC_ISTC) {
4278 | jae >1
4279 } else {
4280 | jb >1
4281 }
4282 if (op == BC_ISTC || op == BC_ISFC) {
4283 | mov [BASE+RA*8+4], RB
4284 | mov RB, [BASE+RD*8]
4285 | mov [BASE+RA*8], RB
4286 }
4287 | movzx RD, PC_RD
4288 | branchPC RD
4289 |1: // Fallthrough to the next instruction.
4290 | ins_next
4291 break;
4292
4293 /* -- Unary ops --------------------------------------------------------- */
4294
4295 case BC_MOV:
4296 | ins_AD // RA = dst, RD = src
4297 |.if X64
4298 | mov RBa, [BASE+RD*8]
4299 | mov [BASE+RA*8], RBa
4300 |.else
4301 | mov RB, [BASE+RD*8+4]
4302 | mov RD, [BASE+RD*8]
4303 | mov [BASE+RA*8+4], RB
4304 | mov [BASE+RA*8], RD
4305 |.endif
4306 | ins_next_
4307 break;
4308 case BC_NOT:
4309 | ins_AD // RA = dst, RD = src
4310 | xor RB, RB
4311 | checktp RD, LJ_TISTRUECOND
4312 | adc RB, LJ_TTRUE
4313 | mov [BASE+RA*8+4], RB
4314 | ins_next
4315 break;
4316 case BC_UNM:
4317 | ins_AD // RA = dst, RD = src
4318 if (LJ_DUALNUM) {
4319 | checkint RD, >5
4320 | mov RB, [BASE+RD*8]
4321 | neg RB
4322 | jo >4
4323 | mov dword [BASE+RA*8+4], LJ_TISNUM
4324 | mov dword [BASE+RA*8], RB
4325 |9:
4326 | ins_next
4327 |4:
4328 | mov dword [BASE+RA*8+4], 0x41e00000 // 2^31.
4329 | mov dword [BASE+RA*8], 0
4330 | jmp <9
4331 |5:
4332 | ja ->vmeta_unm
4333 } else {
4334 | checknum RD, ->vmeta_unm
4335 }
4336 if (sse) {
4337 | movsd xmm0, qword [BASE+RD*8]
4338 | sseconst_sign xmm1, RDa
4339 | xorps xmm0, xmm1
4340 | movsd qword [BASE+RA*8], xmm0
4341 } else {
4342 | fld qword [BASE+RD*8]
4343 | fchs
4344 | fstp qword [BASE+RA*8]
4345 }
4346 if (LJ_DUALNUM) {
4347 | jmp <9
4348 } else {
4349 | ins_next
4350 }
4351 break;
4352 case BC_LEN:
4353 | ins_AD // RA = dst, RD = src
4354 | checkstr RD, >2
4355 | mov STR:RD, [BASE+RD*8]
4356 if (LJ_DUALNUM) {
4357 | mov RD, dword STR:RD->len
4358 |1:
4359 | mov dword [BASE+RA*8+4], LJ_TISNUM
4360 | mov dword [BASE+RA*8], RD
4361 } else if (sse) {
4362 | xorps xmm0, xmm0
4363 | cvtsi2sd xmm0, dword STR:RD->len
4364 |1:
4365 | movsd qword [BASE+RA*8], xmm0
4366 } else {
4367 | fild dword STR:RD->len
4368 |1:
4369 | fstp qword [BASE+RA*8]
4370 }
4371 | ins_next
4372 |2:
4373 | checktab RD, ->vmeta_len
4374 | mov TAB:FCARG1, [BASE+RD*8]
4375#ifdef LUAJIT_ENABLE_LUA52COMPAT
4376 | mov TAB:RB, TAB:FCARG1->metatable
4377 | cmp TAB:RB, 0
4378 | jnz >9
4379 |3:
4380#endif
4381 |->BC_LEN_Z:
4382 | mov RB, BASE // Save BASE.
4383 | call extern lj_tab_len@4 // (GCtab *t)
4384 | // Length of table returned in eax (RD).
4385 if (LJ_DUALNUM) {
4386 | // Nothing to do.
4387 } else if (sse) {
4388 | cvtsi2sd xmm0, RD
4389 } else {
4390 |.if not X64
4391 | mov ARG1, RD
4392 | fild ARG1
4393 |.endif
4394 }
4395 | mov BASE, RB // Restore BASE.
4396 | movzx RA, PC_RA
4397 | jmp <1
4398#ifdef LUAJIT_ENABLE_LUA52COMPAT
4399 |9: // Check for __len.
4400 | test byte TAB:RB->nomm, 1<<MM_len
4401 | jnz <3
4402 | jmp ->vmeta_len // 'no __len' flag NOT set: check.
4403#endif
4404 break;
4405
4406 /* -- Binary ops -------------------------------------------------------- */
4407
4408 |.macro ins_arithpre, x87ins, sseins, ssereg
4409 | ins_ABC
4410 ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
4411 ||switch (vk) {
4412 ||case 0:
4413 | checknum RB, ->vmeta_arith_vn
4414 ||if (LJ_DUALNUM) {
4415 | cmp dword [KBASE+RC*8+4], LJ_TISNUM; jae ->vmeta_arith_vn
4416 ||}
4417 ||if (sse) {
4418 | movsd xmm0, qword [BASE+RB*8]
4419 | sseins ssereg, qword [KBASE+RC*8]
4420 ||} else {
4421 | fld qword [BASE+RB*8]
4422 | x87ins qword [KBASE+RC*8]
4423 ||}
4424 || break;
4425 ||case 1:
4426 | checknum RB, ->vmeta_arith_nv
4427 ||if (LJ_DUALNUM) {
4428 | cmp dword [KBASE+RC*8+4], LJ_TISNUM; jae ->vmeta_arith_nv
4429 ||}
4430 ||if (sse) {
4431 | movsd xmm0, qword [KBASE+RC*8]
4432 | sseins ssereg, qword [BASE+RB*8]
4433 ||} else {
4434 | fld qword [KBASE+RC*8]
4435 | x87ins qword [BASE+RB*8]
4436 ||}
4437 || break;
4438 ||default:
4439 | checknum RB, ->vmeta_arith_vv
4440 | checknum RC, ->vmeta_arith_vv
4441 ||if (sse) {
4442 | movsd xmm0, qword [BASE+RB*8]
4443 | sseins ssereg, qword [BASE+RC*8]
4444 ||} else {
4445 | fld qword [BASE+RB*8]
4446 | x87ins qword [BASE+RC*8]
4447 ||}
4448 || break;
4449 ||}
4450 |.endmacro
4451 |
4452 |.macro ins_arithdn, intins
4453 | ins_ABC
4454 ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
4455 ||switch (vk) {
4456 ||case 0:
4457 | checkint RB, ->vmeta_arith_vn
4458 | cmp dword [KBASE+RC*8+4], LJ_TISNUM; jne ->vmeta_arith_vn
4459 | mov RB, [BASE+RB*8]
4460 | intins RB, [KBASE+RC*8]; jo ->vmeta_arith_vno
4461 || break;
4462 ||case 1:
4463 | checkint RB, ->vmeta_arith_nv
4464 | cmp dword [KBASE+RC*8+4], LJ_TISNUM; jne ->vmeta_arith_nv
4465 | mov RC, [KBASE+RC*8]
4466 | intins RC, [BASE+RB*8]; jo ->vmeta_arith_nvo
4467 || break;
4468 ||default:
4469 | checkint RB, ->vmeta_arith_vv
4470 | checkint RC, ->vmeta_arith_vv
4471 | mov RB, [BASE+RB*8]
4472 | intins RB, [BASE+RC*8]; jo ->vmeta_arith_vvo
4473 || break;
4474 ||}
4475 | mov dword [BASE+RA*8+4], LJ_TISNUM
4476 ||if (vk == 1) {
4477 | mov dword [BASE+RA*8], RC
4478 ||} else {
4479 | mov dword [BASE+RA*8], RB
4480 ||}
4481 | ins_next
4482 |.endmacro
4483 |
4484 |.macro ins_arithpost
4485 ||if (sse) {
4486 | movsd qword [BASE+RA*8], xmm0
4487 ||} else {
4488 | fstp qword [BASE+RA*8]
4489 ||}
4490 |.endmacro
4491 |
4492 |.macro ins_arith, x87ins, sseins
4493 | ins_arithpre x87ins, sseins, xmm0
4494 | ins_arithpost
4495 | ins_next
4496 |.endmacro
4497 |
4498 |.macro ins_arith, intins, x87ins, sseins
4499 ||if (LJ_DUALNUM) {
4500 | ins_arithdn intins
4501 ||} else {
4502 | ins_arith, x87ins, sseins
4503 ||}
4504 |.endmacro
4505
4506 | // RA = dst, RB = src1 or num const, RC = src2 or num const
4507 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
4508 | ins_arith add, fadd, addsd
4509 break;
4510 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
4511 | ins_arith sub, fsub, subsd
4512 break;
4513 case BC_MULVN: case BC_MULNV: case BC_MULVV:
4514 | ins_arith imul, fmul, mulsd
4515 break;
4516 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
4517 | ins_arith fdiv, divsd
4518 break;
4519 case BC_MODVN:
4520 | ins_arithpre fld, movsd, xmm1
4521 |->BC_MODVN_Z:
4522 | call ->vm_mod
4523 | ins_arithpost
4524 | ins_next
4525 break;
4526 case BC_MODNV: case BC_MODVV:
4527 | ins_arithpre fld, movsd, xmm1
4528 | jmp ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway.
4529 break;
4530 case BC_POW:
4531 | ins_arithpre fld, movsd, xmm1
4532 | call ->vm_pow
4533 | ins_arithpost
4534 | ins_next
4535 break;
4536
4537 case BC_CAT:
4538 | ins_ABC // RA = dst, RB = src_start, RC = src_end
4539 |.if X64
4540 | mov L:CARG1d, SAVE_L
4541 | mov L:CARG1d->base, BASE
4542 | lea CARG2d, [BASE+RC*8]
4543 | mov CARG3d, RC
4544 | sub CARG3d, RB
4545 |->BC_CAT_Z:
4546 | mov L:RB, L:CARG1d
4547 |.else
4548 | lea RA, [BASE+RC*8]
4549 | sub RC, RB
4550 | mov ARG2, RA
4551 | mov ARG3, RC
4552 |->BC_CAT_Z:
4553 | mov L:RB, SAVE_L
4554 | mov ARG1, L:RB
4555 | mov L:RB->base, BASE
4556 |.endif
4557 | mov SAVE_PC, PC
4558 | call extern lj_meta_cat // (lua_State *L, TValue *top, int left)
4559 | // NULL (finished) or TValue * (metamethod) returned in eax (RC).
4560 | mov BASE, L:RB->base
4561 | test RC, RC
4562 | jnz ->vmeta_binop
4563 | movzx RB, PC_RB // Copy result to Stk[RA] from Stk[RB].
4564 | movzx RA, PC_RA
4565 |.if X64
4566 | mov RCa, [BASE+RB*8]
4567 | mov [BASE+RA*8], RCa
4568 |.else
4569 | mov RC, [BASE+RB*8+4]
4570 | mov RB, [BASE+RB*8]
4571 | mov [BASE+RA*8+4], RC
4572 | mov [BASE+RA*8], RB
4573 |.endif
4574 | ins_next
4575 break;
4576
4577 /* -- Constant ops ------------------------------------------------------ */
4578
4579 case BC_KSTR:
4580 | ins_AND // RA = dst, RD = str const (~)
4581 | mov RD, [KBASE+RD*4]
4582 | mov dword [BASE+RA*8+4], LJ_TSTR
4583 | mov [BASE+RA*8], RD
4584 | ins_next
4585 break;
4586 case BC_KCDATA:
4587#if LJ_HASFFI
4588 | ins_AND // RA = dst, RD = cdata const (~)
4589 | mov RD, [KBASE+RD*4]
4590 | mov dword [BASE+RA*8+4], LJ_TCDATA
4591 | mov [BASE+RA*8], RD
4592 | ins_next
4593#endif
4594 break;
4595 case BC_KSHORT:
4596 | ins_AD // RA = dst, RD = signed int16 literal
4597 if (LJ_DUALNUM) {
4598 | movsx RD, RDW
4599 | mov dword [BASE+RA*8+4], LJ_TISNUM
4600 | mov dword [BASE+RA*8], RD
4601 } else if (sse) {
4602 | movsx RD, RDW // Sign-extend literal.
4603 | cvtsi2sd xmm0, RD
4604 | movsd qword [BASE+RA*8], xmm0
4605 } else {
4606 | fild PC_RD // Refetch signed RD from instruction.
4607 | fstp qword [BASE+RA*8]
4608 }
4609 | ins_next
4610 break;
4611 case BC_KNUM:
4612 | ins_AD // RA = dst, RD = num const
4613 if (sse) {
4614 | movsd xmm0, qword [KBASE+RD*8]
4615 | movsd qword [BASE+RA*8], xmm0
4616 } else {
4617 | fld qword [KBASE+RD*8]
4618 | fstp qword [BASE+RA*8]
4619 }
4620 | ins_next
4621 break;
4622 case BC_KPRI:
4623 | ins_AND // RA = dst, RD = primitive type (~)
4624 | mov [BASE+RA*8+4], RD
4625 | ins_next
4626 break;
4627 case BC_KNIL:
4628 | ins_AD // RA = dst_start, RD = dst_end
4629 | lea RA, [BASE+RA*8+12]
4630 | lea RD, [BASE+RD*8+4]
4631 | mov RB, LJ_TNIL
4632 | mov [RA-8], RB // Sets minimum 2 slots.
4633 |1:
4634 | mov [RA], RB
4635 | add RA, 8
4636 | cmp RA, RD
4637 | jbe <1
4638 | ins_next
4639 break;
4640
4641 /* -- Upvalue and function ops ------------------------------------------ */
4642
4643 case BC_UGET:
4644 | ins_AD // RA = dst, RD = upvalue #
4645 | mov LFUNC:RB, [BASE-8]
4646 | mov UPVAL:RB, [LFUNC:RB+RD*4+offsetof(GCfuncL, uvptr)]
4647 | mov RB, UPVAL:RB->v
4648 |.if X64
4649 | mov RDa, [RB]
4650 | mov [BASE+RA*8], RDa
4651 |.else
4652 | mov RD, [RB+4]
4653 | mov RB, [RB]
4654 | mov [BASE+RA*8+4], RD
4655 | mov [BASE+RA*8], RB
4656 |.endif
4657 | ins_next
4658 break;
4659 case BC_USETV:
4660#define TV2MARKOFS \
4661 ((int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv))
4662 | ins_AD // RA = upvalue #, RD = src
4663 | mov LFUNC:RB, [BASE-8]
4664 | mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
4665 | cmp byte UPVAL:RB->closed, 0
4666 | mov RB, UPVAL:RB->v
4667 | mov RA, [BASE+RD*8]
4668 | mov RD, [BASE+RD*8+4]
4669 | mov [RB], RA
4670 | mov [RB+4], RD
4671 | jz >1
4672 | // Check barrier for closed upvalue.
4673 | test byte [RB+TV2MARKOFS], LJ_GC_BLACK // isblack(uv)
4674 | jnz >2
4675 |1:
4676 | ins_next
4677 |
4678 |2: // Upvalue is black. Check if new value is collectable and white.
4679 | sub RD, LJ_TISGCV
4680 | cmp RD, LJ_TISNUM - LJ_TISGCV // tvisgcv(v)
4681 | jbe <1
4682 | test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES // iswhite(v)
4683 | jz <1
4684 | // Crossed a write barrier. Move the barrier forward.
4685 |.if X64 and not X64WIN
4686 | mov FCARG2, RB
4687 | mov RB, BASE // Save BASE.
4688 |.else
4689 | xchg FCARG2, RB // Save BASE (FCARG2 == BASE).
4690 |.endif
4691 | lea GL:FCARG1, [DISPATCH+GG_DISP2G]
4692 | call extern lj_gc_barrieruv@8 // (global_State *g, TValue *tv)
4693 | mov BASE, RB // Restore BASE.
4694 | jmp <1
4695 break;
4696#undef TV2MARKOFS
4697 case BC_USETS:
4698 | ins_AND // RA = upvalue #, RD = str const (~)
4699 | mov LFUNC:RB, [BASE-8]
4700 | mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
4701 | mov GCOBJ:RA, [KBASE+RD*4]
4702 | mov RD, UPVAL:RB->v
4703 | mov [RD], GCOBJ:RA
4704 | mov dword [RD+4], LJ_TSTR
4705 | test byte UPVAL:RB->marked, LJ_GC_BLACK // isblack(uv)
4706 | jnz >2
4707 |1:
4708 | ins_next
4709 |
4710 |2: // Check if string is white and ensure upvalue is closed.
4711 | test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES // iswhite(str)
4712 | jz <1
4713 | cmp byte UPVAL:RB->closed, 0
4714 | jz <1
4715 | // Crossed a write barrier. Move the barrier forward.
4716 | mov RB, BASE // Save BASE (FCARG2 == BASE).
4717 | mov FCARG2, RD
4718 | lea GL:FCARG1, [DISPATCH+GG_DISP2G]
4719 | call extern lj_gc_barrieruv@8 // (global_State *g, TValue *tv)
4720 | mov BASE, RB // Restore BASE.
4721 | jmp <1
4722 break;
4723 case BC_USETN:
4724 | ins_AD // RA = upvalue #, RD = num const
4725 | mov LFUNC:RB, [BASE-8]
4726 if (sse) {
4727 | movsd xmm0, qword [KBASE+RD*8]
4728 } else {
4729 | fld qword [KBASE+RD*8]
4730 }
4731 | mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
4732 | mov RA, UPVAL:RB->v
4733 if (sse) {
4734 | movsd qword [RA], xmm0
4735 } else {
4736 | fstp qword [RA]
4737 }
4738 | ins_next
4739 break;
4740 case BC_USETP:
4741 | ins_AND // RA = upvalue #, RD = primitive type (~)
4742 | mov LFUNC:RB, [BASE-8]
4743 | mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
4744 | mov RA, UPVAL:RB->v
4745 | mov [RA+4], RD
4746 | ins_next
4747 break;
4748 case BC_UCLO:
4749 | ins_AD // RA = level, RD = target
4750 | branchPC RD // Do this first to free RD.
4751 | mov L:RB, SAVE_L
4752 | cmp dword L:RB->openupval, 0
4753 | je >1
4754 | mov L:RB->base, BASE
4755 | lea FCARG2, [BASE+RA*8] // Caveat: FCARG2 == BASE
4756 | mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
4757 | call extern lj_func_closeuv@8 // (lua_State *L, TValue *level)
4758 | mov BASE, L:RB->base
4759 |1:
4760 | ins_next
4761 break;
4762
4763 case BC_FNEW:
4764 | ins_AND // RA = dst, RD = proto const (~) (holding function prototype)
4765 |.if X64
4766 | mov L:RB, SAVE_L
4767 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
4768 | mov CARG3d, [BASE-8]
4769 | mov CARG2d, [KBASE+RD*4] // Fetch GCproto *.
4770 | mov CARG1d, L:RB
4771 |.else
4772 | mov LFUNC:RA, [BASE-8]
4773 | mov PROTO:RD, [KBASE+RD*4] // Fetch GCproto *.
4774 | mov L:RB, SAVE_L
4775 | mov ARG3, LFUNC:RA
4776 | mov ARG2, PROTO:RD
4777 | mov ARG1, L:RB
4778 | mov L:RB->base, BASE
4779 |.endif
4780 | mov SAVE_PC, PC
4781 | // (lua_State *L, GCproto *pt, GCfuncL *parent)
4782 | call extern lj_func_newL_gc
4783 | // GCfuncL * returned in eax (RC).
4784 | mov BASE, L:RB->base
4785 | movzx RA, PC_RA
4786 | mov [BASE+RA*8], LFUNC:RC
4787 | mov dword [BASE+RA*8+4], LJ_TFUNC
4788 | ins_next
4789 break;
4790
4791 /* -- Table ops --------------------------------------------------------- */
4792
4793 case BC_TNEW:
4794 | ins_AD // RA = dst, RD = hbits|asize
4795 | mov L:RB, SAVE_L
4796 | mov L:RB->base, BASE
4797 | mov RA, [DISPATCH+DISPATCH_GL(gc.total)]
4798 | cmp RA, [DISPATCH+DISPATCH_GL(gc.threshold)]
4799 | mov SAVE_PC, PC
4800 | jae >5
4801 |1:
4802 |.if X64
4803 | mov CARG3d, RD
4804 | and RD, 0x7ff
4805 | shr CARG3d, 11
4806 |.else
4807 | mov RA, RD
4808 | and RD, 0x7ff
4809 | shr RA, 11
4810 | mov ARG3, RA
4811 |.endif
4812 | cmp RD, 0x7ff
4813 | je >3
4814 |2:
4815 |.if X64
4816 | mov L:CARG1d, L:RB
4817 | mov CARG2d, RD
4818 |.else
4819 | mov ARG1, L:RB
4820 | mov ARG2, RD
4821 |.endif
4822 | call extern lj_tab_new // (lua_State *L, int32_t asize, uint32_t hbits)
4823 | // Table * returned in eax (RC).
4824 | mov BASE, L:RB->base
4825 | movzx RA, PC_RA
4826 | mov [BASE+RA*8], TAB:RC
4827 | mov dword [BASE+RA*8+4], LJ_TTAB
4828 | ins_next
4829 |3: // Turn 0x7ff into 0x801.
4830 | mov RD, 0x801
4831 | jmp <2
4832 |5:
4833 | mov L:FCARG1, L:RB
4834 | call extern lj_gc_step_fixtop@4 // (lua_State *L)
4835 | movzx RD, PC_RD
4836 | jmp <1
4837 break;
4838 case BC_TDUP:
4839 | ins_AND // RA = dst, RD = table const (~) (holding template table)
4840 | mov L:RB, SAVE_L
4841 | mov RA, [DISPATCH+DISPATCH_GL(gc.total)]
4842 | mov SAVE_PC, PC
4843 | cmp RA, [DISPATCH+DISPATCH_GL(gc.threshold)]
4844 | mov L:RB->base, BASE
4845 | jae >3
4846 |2:
4847 | mov TAB:FCARG2, [KBASE+RD*4] // Caveat: FCARG2 == BASE
4848 | mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
4849 | call extern lj_tab_dup@8 // (lua_State *L, Table *kt)
4850 | // Table * returned in eax (RC).
4851 | mov BASE, L:RB->base
4852 | movzx RA, PC_RA
4853 | mov [BASE+RA*8], TAB:RC
4854 | mov dword [BASE+RA*8+4], LJ_TTAB
4855 | ins_next
4856 |3:
4857 | mov L:FCARG1, L:RB
4858 | call extern lj_gc_step_fixtop@4 // (lua_State *L)
4859 | movzx RD, PC_RD // Need to reload RD.
4860 | not RDa
4861 | jmp <2
4862 break;
4863
4864 case BC_GGET:
4865 | ins_AND // RA = dst, RD = str const (~)
4866 | mov LFUNC:RB, [BASE-8]
4867 | mov TAB:RB, LFUNC:RB->env
4868 | mov STR:RC, [KBASE+RD*4]
4869 | jmp ->BC_TGETS_Z
4870 break;
4871 case BC_GSET:
4872 | ins_AND // RA = src, RD = str const (~)
4873 | mov LFUNC:RB, [BASE-8]
4874 | mov TAB:RB, LFUNC:RB->env
4875 | mov STR:RC, [KBASE+RD*4]
4876 | jmp ->BC_TSETS_Z
4877 break;
4878
4879 case BC_TGETV:
4880 | ins_ABC // RA = dst, RB = table, RC = key
4881 | checktab RB, ->vmeta_tgetv
4882 | mov TAB:RB, [BASE+RB*8]
4883 |
4884 | // Integer key?
4885 if (LJ_DUALNUM) {
4886 | checkint RC, >5
4887 | mov RC, dword [BASE+RC*8]
4888 } else {
4889 | // Convert number to int and back and compare.
4890 | checknum RC, >5
4891 if (sse) {
4892 | movsd xmm0, qword [BASE+RC*8]
4893 | cvtsd2si RC, xmm0
4894 | cvtsi2sd xmm1, RC
4895 | ucomisd xmm0, xmm1
4896 } else {
4897 |.if not X64
4898 | fld qword [BASE+RC*8]
4899 | fist ARG1
4900 | fild ARG1
4901 | fcomparepp // eax (RC) modified!
4902 | mov RC, ARG1
4903 |.endif
4904 }
4905 | jne ->vmeta_tgetv // Generic numeric key? Use fallback.
4906 }
4907 | cmp RC, TAB:RB->asize // Takes care of unordered, too.
4908 | jae ->vmeta_tgetv // Not in array part? Use fallback.
4909 | shl RC, 3
4910 | add RC, TAB:RB->array
4911 | cmp dword [RC+4], LJ_TNIL // Avoid overwriting RB in fastpath.
4912 | je >2
4913 | // Get array slot.
4914 |.if X64
4915 | mov RBa, [RC]
4916 | mov [BASE+RA*8], RBa
4917 |.else
4918 | mov RB, [RC]
4919 | mov RC, [RC+4]
4920 | mov [BASE+RA*8], RB
4921 | mov [BASE+RA*8+4], RC
4922 |.endif
4923 |1:
4924 | ins_next
4925 |
4926 |2: // Check for __index if table value is nil.
4927 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
4928 | jz >3
4929 | mov TAB:RA, TAB:RB->metatable
4930 | test byte TAB:RA->nomm, 1<<MM_index
4931 | jz ->vmeta_tgetv // 'no __index' flag NOT set: check.
4932 | movzx RA, PC_RA // Restore RA.
4933 |3:
4934 | mov dword [BASE+RA*8+4], LJ_TNIL
4935 | jmp <1
4936 |
4937 |5: // String key?
4938 | checkstr RC, ->vmeta_tgetv
4939 | mov STR:RC, [BASE+RC*8]
4940 | jmp ->BC_TGETS_Z
4941 break;
4942 case BC_TGETS:
4943 | ins_ABC // RA = dst, RB = table, RC = str const (~)
4944 | not RCa
4945 | mov STR:RC, [KBASE+RC*4]
4946 | checktab RB, ->vmeta_tgets
4947 | mov TAB:RB, [BASE+RB*8]
4948 |->BC_TGETS_Z: // RB = GCtab *, RC = GCstr *, refetches PC_RA.
4949 | mov RA, TAB:RB->hmask
4950 | and RA, STR:RC->hash
4951 | imul RA, #NODE
4952 | add NODE:RA, TAB:RB->node
4953 |1:
4954 | cmp dword NODE:RA->key.it, LJ_TSTR
4955 | jne >4
4956 | cmp dword NODE:RA->key.gcr, STR:RC
4957 | jne >4
4958 | // Ok, key found. Assumes: offsetof(Node, val) == 0
4959 | cmp dword [RA+4], LJ_TNIL // Avoid overwriting RB in fastpath.
4960 | je >5 // Key found, but nil value?
4961 | movzx RC, PC_RA
4962 | // Get node value.
4963 |.if X64
4964 | mov RBa, [RA]
4965 | mov [BASE+RC*8], RBa
4966 |.else
4967 | mov RB, [RA]
4968 | mov RA, [RA+4]
4969 | mov [BASE+RC*8], RB
4970 | mov [BASE+RC*8+4], RA
4971 |.endif
4972 |2:
4973 | ins_next
4974 |
4975 |3:
4976 | movzx RC, PC_RA
4977 | mov dword [BASE+RC*8+4], LJ_TNIL
4978 | jmp <2
4979 |
4980 |4: // Follow hash chain.
4981 | mov NODE:RA, NODE:RA->next
4982 | test NODE:RA, NODE:RA
4983 | jnz <1
4984 | // End of hash chain: key not found, nil result.
4985 |
4986 |5: // Check for __index if table value is nil.
4987 | mov TAB:RA, TAB:RB->metatable
4988 | test TAB:RA, TAB:RA
4989 | jz <3 // No metatable: done.
4990 | test byte TAB:RA->nomm, 1<<MM_index
4991 | jnz <3 // 'no __index' flag set: done.
4992 | jmp ->vmeta_tgets // Caveat: preserve STR:RC.
4993 break;
4994 case BC_TGETB:
4995 | ins_ABC // RA = dst, RB = table, RC = byte literal
4996 | checktab RB, ->vmeta_tgetb
4997 | mov TAB:RB, [BASE+RB*8]
4998 | cmp RC, TAB:RB->asize
4999 | jae ->vmeta_tgetb
5000 | shl RC, 3
5001 | add RC, TAB:RB->array
5002 | cmp dword [RC+4], LJ_TNIL // Avoid overwriting RB in fastpath.
5003 | je >2
5004 | // Get array slot.
5005 |.if X64
5006 | mov RBa, [RC]
5007 | mov [BASE+RA*8], RBa
5008 |.else
5009 | mov RB, [RC]
5010 | mov RC, [RC+4]
5011 | mov [BASE+RA*8], RB
5012 | mov [BASE+RA*8+4], RC
5013 |.endif
5014 |1:
5015 | ins_next
5016 |
5017 |2: // Check for __index if table value is nil.
5018 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
5019 | jz >3
5020 | mov TAB:RA, TAB:RB->metatable
5021 | test byte TAB:RA->nomm, 1<<MM_index
5022 | jz ->vmeta_tgetb // 'no __index' flag NOT set: check.
5023 | movzx RA, PC_RA // Restore RA.
5024 |3:
5025 | mov dword [BASE+RA*8+4], LJ_TNIL
5026 | jmp <1
5027 break;
5028
5029 case BC_TSETV:
5030 | ins_ABC // RA = src, RB = table, RC = key
5031 | checktab RB, ->vmeta_tsetv
5032 | mov TAB:RB, [BASE+RB*8]
5033 |
5034 | // Integer key?
5035 if (LJ_DUALNUM) {
5036 | checkint RC, >5
5037 | mov RC, dword [BASE+RC*8]
5038 } else {
5039 | // Convert number to int and back and compare.
5040 | checknum RC, >5
5041 if (sse) {
5042 | movsd xmm0, qword [BASE+RC*8]
5043 | cvtsd2si RC, xmm0
5044 | cvtsi2sd xmm1, RC
5045 | ucomisd xmm0, xmm1
5046 } else {
5047 |.if not X64
5048 | fld qword [BASE+RC*8]
5049 | fist ARG1
5050 | fild ARG1
5051 | fcomparepp // eax (RC) modified!
5052 | mov RC, ARG1
5053 |.endif
5054 }
5055 | jne ->vmeta_tsetv // Generic numeric key? Use fallback.
5056 }
5057 | cmp RC, TAB:RB->asize // Takes care of unordered, too.
5058 | jae ->vmeta_tsetv
5059 | shl RC, 3
5060 | add RC, TAB:RB->array
5061 | cmp dword [RC+4], LJ_TNIL
5062 | je >3 // Previous value is nil?
5063 |1:
5064 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
5065 | jnz >7
5066 |2: // Set array slot.
5067 |.if X64
5068 | mov RBa, [BASE+RA*8]
5069 | mov [RC], RBa
5070 |.else
5071 | mov RB, [BASE+RA*8+4]
5072 | mov RA, [BASE+RA*8]
5073 | mov [RC+4], RB
5074 | mov [RC], RA
5075 |.endif
5076 | ins_next
5077 |
5078 |3: // Check for __newindex if previous value is nil.
5079 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
5080 | jz <1
5081 | mov TAB:RA, TAB:RB->metatable
5082 | test byte TAB:RA->nomm, 1<<MM_newindex
5083 | jz ->vmeta_tsetv // 'no __newindex' flag NOT set: check.
5084 | movzx RA, PC_RA // Restore RA.
5085 | jmp <1
5086 |
5087 |5: // String key?
5088 | checkstr RC, ->vmeta_tsetv
5089 | mov STR:RC, [BASE+RC*8]
5090 | jmp ->BC_TSETS_Z
5091 |
5092 |7: // Possible table write barrier for the value. Skip valiswhite check.
5093 | barrierback TAB:RB, RA
5094 | movzx RA, PC_RA // Restore RA.
5095 | jmp <2
5096 break;
5097 case BC_TSETS:
5098 | ins_ABC // RA = src, RB = table, RC = str const (~)
5099 | not RCa
5100 | mov STR:RC, [KBASE+RC*4]
5101 | checktab RB, ->vmeta_tsets
5102 | mov TAB:RB, [BASE+RB*8]
5103 |->BC_TSETS_Z: // RB = GCtab *, RC = GCstr *, refetches PC_RA.
5104 | mov RA, TAB:RB->hmask
5105 | and RA, STR:RC->hash
5106 | imul RA, #NODE
5107 | mov byte TAB:RB->nomm, 0 // Clear metamethod cache.
5108 | add NODE:RA, TAB:RB->node
5109 |1:
5110 | cmp dword NODE:RA->key.it, LJ_TSTR
5111 | jne >5
5112 | cmp dword NODE:RA->key.gcr, STR:RC
5113 | jne >5
5114 | // Ok, key found. Assumes: offsetof(Node, val) == 0
5115 | cmp dword [RA+4], LJ_TNIL
5116 | je >4 // Previous value is nil?
5117 |2:
5118 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
5119 | jnz >7
5120 |3: // Set node value.
5121 | movzx RC, PC_RA
5122 |.if X64
5123 | mov RBa, [BASE+RC*8]
5124 | mov [RA], RBa
5125 |.else
5126 | mov RB, [BASE+RC*8+4]
5127 | mov RC, [BASE+RC*8]
5128 | mov [RA+4], RB
5129 | mov [RA], RC
5130 |.endif
5131 | ins_next
5132 |
5133 |4: // Check for __newindex if previous value is nil.
5134 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
5135 | jz <2
5136 | mov TMP1, RA // Save RA.
5137 | mov TAB:RA, TAB:RB->metatable
5138 | test byte TAB:RA->nomm, 1<<MM_newindex
5139 | jz ->vmeta_tsets // 'no __newindex' flag NOT set: check.
5140 | mov RA, TMP1 // Restore RA.
5141 | jmp <2
5142 |
5143 |5: // Follow hash chain.
5144 | mov NODE:RA, NODE:RA->next
5145 | test NODE:RA, NODE:RA
5146 | jnz <1
5147 | // End of hash chain: key not found, add a new one.
5148 |
5149 | // But check for __newindex first.
5150 | mov TAB:RA, TAB:RB->metatable
5151 | test TAB:RA, TAB:RA
5152 | jz >6 // No metatable: continue.
5153 | test byte TAB:RA->nomm, 1<<MM_newindex
5154 | jz ->vmeta_tsets // 'no __newindex' flag NOT set: check.
5155 |6:
5156 | mov TMP1, STR:RC
5157 | mov TMP2, LJ_TSTR
5158 | mov TMP3, TAB:RB // Save TAB:RB for us.
5159 |.if X64
5160 | mov L:CARG1d, SAVE_L
5161 | mov L:CARG1d->base, BASE
5162 | lea CARG3, TMP1
5163 | mov CARG2d, TAB:RB
5164 | mov L:RB, L:CARG1d
5165 |.else
5166 | lea RC, TMP1 // Store temp. TValue in TMP1/TMP2.
5167 | mov ARG2, TAB:RB
5168 | mov L:RB, SAVE_L
5169 | mov ARG3, RC
5170 | mov ARG1, L:RB
5171 | mov L:RB->base, BASE
5172 |.endif
5173 | mov SAVE_PC, PC
5174 | call extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k)
5175 | // Handles write barrier for the new key. TValue * returned in eax (RC).
5176 | mov BASE, L:RB->base
5177 | mov TAB:RB, TMP3 // Need TAB:RB for barrier.
5178 | mov RA, eax
5179 | jmp <2 // Must check write barrier for value.
5180 |
5181 |7: // Possible table write barrier for the value. Skip valiswhite check.
5182 | barrierback TAB:RB, RC // Destroys STR:RC.
5183 | jmp <3
5184 break;
5185 case BC_TSETB:
5186 | ins_ABC // RA = src, RB = table, RC = byte literal
5187 | checktab RB, ->vmeta_tsetb
5188 | mov TAB:RB, [BASE+RB*8]
5189 | cmp RC, TAB:RB->asize
5190 | jae ->vmeta_tsetb
5191 | shl RC, 3
5192 | add RC, TAB:RB->array
5193 | cmp dword [RC+4], LJ_TNIL
5194 | je >3 // Previous value is nil?
5195 |1:
5196 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
5197 | jnz >7
5198 |2: // Set array slot.
5199 |.if X64
5200 | mov RAa, [BASE+RA*8]
5201 | mov [RC], RAa
5202 |.else
5203 | mov RB, [BASE+RA*8+4]
5204 | mov RA, [BASE+RA*8]
5205 | mov [RC+4], RB
5206 | mov [RC], RA
5207 |.endif
5208 | ins_next
5209 |
5210 |3: // Check for __newindex if previous value is nil.
5211 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
5212 | jz <1
5213 | mov TAB:RA, TAB:RB->metatable
5214 | test byte TAB:RA->nomm, 1<<MM_newindex
5215 | jz ->vmeta_tsetb // 'no __newindex' flag NOT set: check.
5216 | movzx RA, PC_RA // Restore RA.
5217 | jmp <1
5218 |
5219 |7: // Possible table write barrier for the value. Skip valiswhite check.
5220 | barrierback TAB:RB, RA
5221 | movzx RA, PC_RA // Restore RA.
5222 | jmp <2
5223 break;
5224
5225 case BC_TSETM:
5226 | ins_AD // RA = base (table at base-1), RD = num const (start index)
5227 | mov TMP1, KBASE // Need one more free register.
5228 | mov KBASE, dword [KBASE+RD*8] // Integer constant is in lo-word.
5229 |1:
5230 | lea RA, [BASE+RA*8]
5231 | mov TAB:RB, [RA-8] // Guaranteed to be a table.
5232 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
5233 | jnz >7
5234 |2:
5235 | mov RD, MULTRES
5236 | sub RD, 1
5237 | jz >4 // Nothing to copy?
5238 | add RD, KBASE // Compute needed size.
5239 | cmp RD, TAB:RB->asize
5240 | ja >5 // Doesn't fit into array part?
5241 | sub RD, KBASE
5242 | shl KBASE, 3
5243 | add KBASE, TAB:RB->array
5244 |3: // Copy result slots to table.
5245 |.if X64
5246 | mov RBa, [RA]
5247 | add RA, 8
5248 | mov [KBASE], RBa
5249 |.else
5250 | mov RB, [RA]
5251 | mov [KBASE], RB
5252 | mov RB, [RA+4]
5253 | add RA, 8
5254 | mov [KBASE+4], RB
5255 |.endif
5256 | add KBASE, 8
5257 | sub RD, 1
5258 | jnz <3
5259 |4:
5260 | mov KBASE, TMP1
5261 | ins_next
5262 |
5263 |5: // Need to resize array part.
5264 |.if X64
5265 | mov L:CARG1d, SAVE_L
5266 | mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
5267 | mov CARG2d, TAB:RB
5268 | mov CARG3d, RD
5269 | mov L:RB, L:CARG1d
5270 |.else
5271 | mov ARG2, TAB:RB
5272 | mov L:RB, SAVE_L
5273 | mov L:RB->base, BASE
5274 | mov ARG3, RD
5275 | mov ARG1, L:RB
5276 |.endif
5277 | mov SAVE_PC, PC
5278 | call extern lj_tab_reasize // (lua_State *L, GCtab *t, int nasize)
5279 | mov BASE, L:RB->base
5280 | movzx RA, PC_RA // Restore RA.
5281 | jmp <1 // Retry.
5282 |
5283 |7: // Possible table write barrier for any value. Skip valiswhite check.
5284 | barrierback TAB:RB, RD
5285 | jmp <2
5286 break;
5287
5288 /* -- Calls and vararg handling ----------------------------------------- */
5289
5290 case BC_CALL: case BC_CALLM:
5291 | ins_A_C // RA = base, (RB = nresults+1,) RC = nargs+1 | extra_nargs
5292 if (op == BC_CALLM) {
5293 | add NARGS:RD, MULTRES
5294 }
5295 | cmp dword [BASE+RA*8+4], LJ_TFUNC
5296 | mov LFUNC:RB, [BASE+RA*8]
5297 | jne ->vmeta_call_ra
5298 | lea BASE, [BASE+RA*8+8]
5299 | ins_call
5300 break;
5301
5302 case BC_CALLMT:
5303 | ins_AD // RA = base, RD = extra_nargs
5304 | add NARGS:RD, MULTRES
5305 | // Fall through. Assumes BC_CALLT follows and ins_AD is a no-op.
5306 break;
5307 case BC_CALLT:
5308 | ins_AD // RA = base, RD = nargs+1
5309 | lea RA, [BASE+RA*8+8]
5310 | mov KBASE, BASE // Use KBASE for move + vmeta_call hint.
5311 | mov LFUNC:RB, [RA-8]
5312 | cmp dword [RA-4], LJ_TFUNC
5313 | jne ->vmeta_call
5314 |->BC_CALLT_Z:
5315 | mov PC, [BASE-4]
5316 | test PC, FRAME_TYPE
5317 | jnz >7
5318 |1:
5319 | mov [BASE-8], LFUNC:RB // Copy function down, reloaded below.
5320 | mov MULTRES, NARGS:RD
5321 | sub NARGS:RD, 1
5322 | jz >3
5323 |2: // Move args down.
5324 |.if X64
5325 | mov RBa, [RA]
5326 | add RA, 8
5327 | mov [KBASE], RBa
5328 |.else
5329 | mov RB, [RA]
5330 | mov [KBASE], RB
5331 | mov RB, [RA+4]
5332 | add RA, 8
5333 | mov [KBASE+4], RB
5334 |.endif
5335 | add KBASE, 8
5336 | sub NARGS:RD, 1
5337 | jnz <2
5338 |
5339 | mov LFUNC:RB, [BASE-8]
5340 |3:
5341 | mov NARGS:RD, MULTRES
5342 | cmp byte LFUNC:RB->ffid, 1 // (> FF_C) Calling a fast function?
5343 | ja >5
5344 |4:
5345 | ins_callt
5346 |
5347 |5: // Tailcall to a fast function.
5348 | test PC, FRAME_TYPE // Lua frame below?
5349 | jnz <4
5350 | movzx RA, PC_RA
5351 | not RAa
5352 | lea RA, [BASE+RA*8]
5353 | mov LFUNC:KBASE, [RA-8] // Need to prepare KBASE.
5354 | mov KBASE, LFUNC:KBASE->pc
5355 | mov KBASE, [KBASE+PC2PROTO(k)]
5356 | jmp <4
5357 |
5358 |7: // Tailcall from a vararg function.
5359 | sub PC, FRAME_VARG
5360 | test PC, FRAME_TYPEP
5361 | jnz >8 // Vararg frame below?
5362 | sub BASE, PC // Need to relocate BASE/KBASE down.
5363 | mov KBASE, BASE
5364 | mov PC, [BASE-4]
5365 | jmp <1
5366 |8:
5367 | add PC, FRAME_VARG
5368 | jmp <1
5369 break;
5370
5371 case BC_ITERC:
5372 | ins_A // RA = base, (RB = nresults+1,) RC = nargs+1 (2+1)
5373 | lea RA, [BASE+RA*8+8] // fb = base+1
5374 |.if X64
5375 | mov RBa, [RA-24] // Copy state. fb[0] = fb[-3].
5376 | mov RCa, [RA-16] // Copy control var. fb[1] = fb[-2].
5377 | mov [RA], RBa
5378 | mov [RA+8], RCa
5379 |.else
5380 | mov RB, [RA-24] // Copy state. fb[0] = fb[-3].
5381 | mov RC, [RA-20]
5382 | mov [RA], RB
5383 | mov [RA+4], RC
5384 | mov RB, [RA-16] // Copy control var. fb[1] = fb[-2].
5385 | mov RC, [RA-12]
5386 | mov [RA+8], RB
5387 | mov [RA+12], RC
5388 |.endif
5389 | mov LFUNC:RB, [RA-32] // Copy callable. fb[-1] = fb[-4]
5390 | mov RC, [RA-28]
5391 | mov [RA-8], LFUNC:RB
5392 | mov [RA-4], RC
5393 | cmp RC, LJ_TFUNC // Handle like a regular 2-arg call.
5394 | mov NARGS:RD, 2+1
5395 | jne ->vmeta_call
5396 | mov BASE, RA
5397 | ins_call
5398 break;
5399
5400 case BC_ITERN:
5401 | ins_A // RA = base, (RB = nresults+1, RC = nargs+1 (2+1))
5402#if LJ_HASJIT
5403 | // NYI: add hotloop, record BC_ITERN.
5404#endif
5405 | mov TMP1, KBASE // Need two more free registers.
5406 | mov TMP2, DISPATCH
5407 | mov TAB:RB, [BASE+RA*8-16]
5408 | mov RC, [BASE+RA*8-8] // Get index from control var.
5409 | mov DISPATCH, TAB:RB->asize
5410 | add PC, 4
5411 | mov KBASE, TAB:RB->array
5412 |1: // Traverse array part.
5413 | cmp RC, DISPATCH; jae >5 // Index points after array part?
5414 | cmp dword [KBASE+RC*8+4], LJ_TNIL; je >4
5415 if (LJ_DUALNUM) {
5416 | mov dword [BASE+RA*8+4], LJ_TISNUM
5417 | mov dword [BASE+RA*8], RC
5418 } else if (sse) {
5419 | cvtsi2sd xmm0, RC
5420 } else {
5421 | fild dword [BASE+RA*8-8]
5422 }
5423 | // Copy array slot to returned value.
5424 |.if X64
5425 | mov RBa, [KBASE+RC*8]
5426 | mov [BASE+RA*8+8], RBa
5427 |.else
5428 | mov RB, [KBASE+RC*8+4]
5429 | mov [BASE+RA*8+12], RB
5430 | mov RB, [KBASE+RC*8]
5431 | mov [BASE+RA*8+8], RB
5432 |.endif
5433 | add RC, 1
5434 | // Return array index as a numeric key.
5435 if (LJ_DUALNUM) {
5436 | // See above.
5437 } else if (sse) {
5438 | movsd qword [BASE+RA*8], xmm0
5439 } else {
5440 | fstp qword [BASE+RA*8]
5441 }
5442 | mov [BASE+RA*8-8], RC // Update control var.
5443 |2:
5444 | movzx RD, PC_RD // Get target from ITERL.
5445 | branchPC RD
5446 |3:
5447 | mov DISPATCH, TMP2
5448 | mov KBASE, TMP1
5449 | ins_next
5450 |
5451 |4: // Skip holes in array part.
5452 | add RC, 1
5453 if (!LJ_DUALNUM && !sse) {
5454 | mov [BASE+RA*8-8], RC
5455 }
5456 | jmp <1
5457 |
5458 |5: // Traverse hash part.
5459 | sub RC, DISPATCH
5460 |6:
5461 | cmp RC, TAB:RB->hmask; ja <3 // End of iteration? Branch to ITERL+1.
5462 | imul KBASE, RC, #NODE
5463 | add NODE:KBASE, TAB:RB->node
5464 | cmp dword NODE:KBASE->val.it, LJ_TNIL; je >7
5465 | lea DISPATCH, [RC+DISPATCH+1]
5466 | // Copy key and value from hash slot.
5467 |.if X64
5468 | mov RBa, NODE:KBASE->key
5469 | mov RCa, NODE:KBASE->val
5470 | mov [BASE+RA*8], RBa
5471 | mov [BASE+RA*8+8], RCa
5472 |.else
5473 | mov RB, NODE:KBASE->key.gcr
5474 | mov RC, NODE:KBASE->key.it
5475 | mov [BASE+RA*8], RB
5476 | mov [BASE+RA*8+4], RC
5477 | mov RB, NODE:KBASE->val.gcr
5478 | mov RC, NODE:KBASE->val.it
5479 | mov [BASE+RA*8+8], RB
5480 | mov [BASE+RA*8+12], RC
5481 |.endif
5482 | mov [BASE+RA*8-8], DISPATCH
5483 | jmp <2
5484 |
5485 |7: // Skip holes in hash part.
5486 | add RC, 1
5487 | jmp <6
5488 break;
5489
5490 case BC_ISNEXT:
5491 | ins_AD // RA = base, RD = target (points to ITERN)
5492 | cmp dword [BASE+RA*8-20], LJ_TFUNC; jne >5
5493 | mov CFUNC:RB, [BASE+RA*8-24]
5494 | cmp dword [BASE+RA*8-12], LJ_TTAB; jne >5
5495 | cmp dword [BASE+RA*8-4], LJ_TNIL; jne >5
5496 | cmp byte CFUNC:RB->ffid, FF_next_N; jne >5
5497 | branchPC RD
5498 | mov dword [BASE+RA*8-8], 0 // Initialize control var.
5499 |1:
5500 | ins_next
5501 |5: // Despecialize bytecode if any of the checks fail.
5502 | mov PC_OP, BC_JMP
5503 | branchPC RD
5504 | mov byte [PC], BC_ITERC
5505 | jmp <1
5506 break;
5507
5508 case BC_VARG:
5509 | ins_ABC // RA = base, RB = nresults+1, RC = numparams
5510 | mov TMP1, KBASE // Need one more free register.
5511 | lea KBASE, [BASE+RC*8+(8+FRAME_VARG)]
5512 | lea RA, [BASE+RA*8]
5513 | sub KBASE, [BASE-4]
5514 | // Note: KBASE may now be even _above_ BASE if nargs was < numparams.
5515 | test RB, RB
5516 | jz >5 // Copy all varargs?
5517 | lea RB, [RA+RB*8-8]
5518 | cmp KBASE, BASE // No vararg slots?
5519 | jnb >2
5520 |1: // Copy vararg slots to destination slots.
5521 |.if X64
5522 | mov RCa, [KBASE-8]
5523 | add KBASE, 8
5524 | mov [RA], RCa
5525 |.else
5526 | mov RC, [KBASE-8]
5527 | mov [RA], RC
5528 | mov RC, [KBASE-4]
5529 | add KBASE, 8
5530 | mov [RA+4], RC
5531 |.endif
5532 | add RA, 8
5533 | cmp RA, RB // All destination slots filled?
5534 | jnb >3
5535 | cmp KBASE, BASE // No more vararg slots?
5536 | jb <1
5537 |2: // Fill up remainder with nil.
5538 | mov dword [RA+4], LJ_TNIL
5539 | add RA, 8
5540 | cmp RA, RB
5541 | jb <2
5542 |3:
5543 | mov KBASE, TMP1
5544 | ins_next
5545 |
5546 |5: // Copy all varargs.
5547 | mov MULTRES, 1 // MULTRES = 0+1
5548 | mov RC, BASE
5549 | sub RC, KBASE
5550 | jbe <3 // No vararg slots?
5551 | mov RB, RC
5552 | shr RB, 3
5553 | add RB, 1
5554 | mov MULTRES, RB // MULTRES = #varargs+1
5555 | mov L:RB, SAVE_L
5556 | add RC, RA
5557 | cmp RC, L:RB->maxstack
5558 | ja >7 // Need to grow stack?
5559 |6: // Copy all vararg slots.
5560 |.if X64
5561 | mov RCa, [KBASE-8]
5562 | add KBASE, 8
5563 | mov [RA], RCa
5564 |.else
5565 | mov RC, [KBASE-8]
5566 | mov [RA], RC
5567 | mov RC, [KBASE-4]
5568 | add KBASE, 8
5569 | mov [RA+4], RC
5570 |.endif
5571 | add RA, 8
5572 | cmp KBASE, BASE // No more vararg slots?
5573 | jb <6
5574 | jmp <3
5575 |
5576 |7: // Grow stack for varargs.
5577 | mov L:RB->base, BASE
5578 | mov L:RB->top, RA
5579 | mov SAVE_PC, PC
5580 | sub KBASE, BASE // Need delta, because BASE may change.
5581 | mov FCARG2, MULTRES
5582 | sub FCARG2, 1
5583 | mov FCARG1, L:RB
5584 | call extern lj_state_growstack@8 // (lua_State *L, int n)
5585 | mov BASE, L:RB->base
5586 | mov RA, L:RB->top
5587 | add KBASE, BASE
5588 | jmp <6
5589 break;
5590
5591 /* -- Returns ----------------------------------------------------------- */
5592
5593 case BC_RETM:
5594 | ins_AD // RA = results, RD = extra_nresults
5595 | add RD, MULTRES // MULTRES >=1, so RD >=1.
5596 | // Fall through. Assumes BC_RET follows and ins_AD is a no-op.
5597 break;
5598
5599 case BC_RET: case BC_RET0: case BC_RET1:
5600 | ins_AD // RA = results, RD = nresults+1
5601 if (op != BC_RET0) {
5602 | shl RA, 3
5603 }
5604 |1:
5605 | mov PC, [BASE-4]
5606 | mov MULTRES, RD // Save nresults+1.
5607 | test PC, FRAME_TYPE // Check frame type marker.
5608 | jnz >7 // Not returning to a fixarg Lua func?
5609 switch (op) {
5610 case BC_RET:
5611 |->BC_RET_Z:
5612 | mov KBASE, BASE // Use KBASE for result move.
5613 | sub RD, 1
5614 | jz >3
5615 |2: // Move results down.
5616 |.if X64
5617 | mov RBa, [KBASE+RA]
5618 | mov [KBASE-8], RBa
5619 |.else
5620 | mov RB, [KBASE+RA]
5621 | mov [KBASE-8], RB
5622 | mov RB, [KBASE+RA+4]
5623 | mov [KBASE-4], RB
5624 |.endif
5625 | add KBASE, 8
5626 | sub RD, 1
5627 | jnz <2
5628 |3:
5629 | mov RD, MULTRES // Note: MULTRES may be >255.
5630 | movzx RB, PC_RB // So cannot compare with RDL!
5631 |5:
5632 | cmp RB, RD // More results expected?
5633 | ja >6
5634 break;
5635 case BC_RET1:
5636 |.if X64
5637 | mov RBa, [BASE+RA]
5638 | mov [BASE-8], RBa
5639 |.else
5640 | mov RB, [BASE+RA+4]
5641 | mov [BASE-4], RB
5642 | mov RB, [BASE+RA]
5643 | mov [BASE-8], RB
5644 |.endif
5645 /* fallthrough */
5646 case BC_RET0:
5647 |5:
5648 | cmp PC_RB, RDL // More results expected?
5649 | ja >6
5650 default:
5651 break;
5652 }
5653 | movzx RA, PC_RA
5654 | not RAa // Note: ~RA = -(RA+1)
5655 | lea BASE, [BASE+RA*8] // base = base - (RA+1)*8
5656 | mov LFUNC:KBASE, [BASE-8]
5657 | mov KBASE, LFUNC:KBASE->pc
5658 | mov KBASE, [KBASE+PC2PROTO(k)]
5659 | ins_next
5660 |
5661 |6: // Fill up results with nil.
5662 if (op == BC_RET) {
5663 | mov dword [KBASE-4], LJ_TNIL // Note: relies on shifted base.
5664 | add KBASE, 8
5665 } else {
5666 | mov dword [BASE+RD*8-12], LJ_TNIL
5667 }
5668 | add RD, 1
5669 | jmp <5
5670 |
5671 |7: // Non-standard return case.
5672 | lea RB, [PC-FRAME_VARG]
5673 | test RB, FRAME_TYPEP
5674 | jnz ->vm_return
5675 | // Return from vararg function: relocate BASE down and RA up.
5676 | sub BASE, RB
5677 if (op != BC_RET0) {
5678 | add RA, RB
5679 }
5680 | jmp <1
5681 break;
5682
5683 /* -- Loops and branches ------------------------------------------------ */
5684
5685 |.define FOR_IDX, [RA]; .define FOR_TIDX, dword [RA+4]
5686 |.define FOR_STOP, [RA+8]; .define FOR_TSTOP, dword [RA+12]
5687 |.define FOR_STEP, [RA+16]; .define FOR_TSTEP, dword [RA+20]
5688 |.define FOR_EXT, [RA+24]; .define FOR_TEXT, dword [RA+28]
5689
5690 case BC_FORL:
5691#if LJ_HASJIT
5692 | hotloop RB
5693#endif
5694 | // Fall through. Assumes BC_IFORL follows and ins_AJ is a no-op.
5695 break;
5696
5697 case BC_JFORI:
5698 case BC_JFORL:
5699#if !LJ_HASJIT
5700 break;
5701#endif
5702 case BC_FORI:
5703 case BC_IFORL:
5704 vk = (op == BC_IFORL || op == BC_JFORL);
5705 | ins_AJ // RA = base, RD = target (after end of loop or start of loop)
5706 | lea RA, [BASE+RA*8]
5707 if (LJ_DUALNUM) {
5708 | cmp FOR_TIDX, LJ_TISNUM; jne >9
5709 if (!vk) {
5710 | cmp FOR_TSTOP, LJ_TISNUM; jne ->vmeta_for
5711 | cmp FOR_TSTEP, LJ_TISNUM; jne ->vmeta_for
5712 | mov RB, dword FOR_IDX
5713 | cmp dword FOR_STEP, 0; jl >5
5714 } else {
5715#ifdef LUA_USE_ASSERT
5716 | cmp FOR_TSTOP, LJ_TISNUM; jne ->assert_bad_for_arg_type
5717 | cmp FOR_TSTEP, LJ_TISNUM; jne ->assert_bad_for_arg_type
5718#endif
5719 | mov RB, dword FOR_STEP
5720 | test RB, RB; js >5
5721 | add RB, dword FOR_IDX; jo >1
5722 | mov dword FOR_IDX, RB
5723 }
5724 | cmp RB, dword FOR_STOP
5725 | mov FOR_TEXT, LJ_TISNUM
5726 | mov dword FOR_EXT, RB
5727 if (op == BC_FORI) {
5728 | jle >7
5729 |1:
5730 |6:
5731 | branchPC RD
5732 } else if (op == BC_JFORI) {
5733 | branchPC RD
5734 | movzx RD, PC_RD
5735 | jle =>BC_JLOOP
5736 |1:
5737 |6:
5738 } else if (op == BC_IFORL) {
5739 | jg >7
5740 |6:
5741 | branchPC RD
5742 |1:
5743 } else {
5744 | jle =>BC_JLOOP
5745 |1:
5746 |6:
5747 }
5748 |7:
5749 | ins_next
5750 |
5751 |5: // Invert check for negative step.
5752 if (vk) {
5753 | add RB, dword FOR_IDX; jo <1
5754 | mov dword FOR_IDX, RB
5755 }
5756 | cmp RB, dword FOR_STOP
5757 | mov FOR_TEXT, LJ_TISNUM
5758 | mov dword FOR_EXT, RB
5759 if (op == BC_FORI) {
5760 | jge <7
5761 } else if (op == BC_JFORI) {
5762 | branchPC RD
5763 | movzx RD, PC_RD
5764 | jge =>BC_JLOOP
5765 } else if (op == BC_IFORL) {
5766 | jl <7
5767 } else {
5768 | jge =>BC_JLOOP
5769 }
5770 | jmp <6
5771 |9: // Fallback to FP variant.
5772 } else if (!vk) {
5773 | cmp FOR_TIDX, LJ_TISNUM
5774 }
5775 if (!vk) {
5776 | jae ->vmeta_for
5777 | cmp FOR_TSTOP, LJ_TISNUM; jae ->vmeta_for
5778 } else {
5779#ifdef LUA_USE_ASSERT
5780 | cmp FOR_TSTOP, LJ_TISNUM; jae ->assert_bad_for_arg_type
5781 | cmp FOR_TSTEP, LJ_TISNUM; jae ->assert_bad_for_arg_type
5782#endif
5783 }
5784 | mov RB, FOR_TSTEP // Load type/hiword of for step.
5785 if (!vk) {
5786 | cmp RB, LJ_TISNUM; jae ->vmeta_for
5787 }
5788 if (sse) {
5789 | movsd xmm0, qword FOR_IDX
5790 | movsd xmm1, qword FOR_STOP
5791 if (vk) {
5792 | addsd xmm0, qword FOR_STEP
5793 | movsd qword FOR_IDX, xmm0
5794 | test RB, RB; js >3
5795 } else {
5796 | jl >3
5797 }
5798 | ucomisd xmm1, xmm0
5799 |1:
5800 | movsd qword FOR_EXT, xmm0
5801 } else {
5802 | fld qword FOR_STOP
5803 | fld qword FOR_IDX
5804 if (vk) {
5805 | fadd qword FOR_STEP // nidx = idx + step
5806 | fst qword FOR_IDX
5807 | fst qword FOR_EXT
5808 | test RB, RB; js >1
5809 } else {
5810 | fst qword FOR_EXT
5811 | jl >1
5812 }
5813 | fxch // Swap lim/(n)idx if step non-negative.
5814 |1:
5815 | fcomparepp // eax (RD) modified if !cmov.
5816 if (!cmov) {
5817 | movzx RD, PC_RD // Need to reload RD.
5818 }
5819 }
5820 if (op == BC_FORI) {
5821 if (LJ_DUALNUM) {
5822 | jnb <7
5823 } else {
5824 | jnb >2
5825 | branchPC RD
5826 }
5827 } else if (op == BC_JFORI) {
5828 | branchPC RD
5829 | movzx RD, PC_RD
5830 | jnb =>BC_JLOOP
5831 } else if (op == BC_IFORL) {
5832 if (LJ_DUALNUM) {
5833 | jb <7
5834 } else {
5835 | jb >2
5836 | branchPC RD
5837 }
5838 } else {
5839 | jnb =>BC_JLOOP
5840 }
5841 if (LJ_DUALNUM) {
5842 | jmp <6
5843 } else {
5844 |2:
5845 | ins_next
5846 }
5847 if (sse) {
5848 |3: // Invert comparison if step is negative.
5849 | ucomisd xmm0, xmm1
5850 | jmp <1
5851 }
5852 break;
5853
5854 case BC_ITERL:
5855#if LJ_HASJIT
5856 | hotloop RB
5857#endif
5858 | // Fall through. Assumes BC_IITERL follows and ins_AJ is a no-op.
5859 break;
5860
5861 case BC_JITERL:
5862#if !LJ_HASJIT
5863 break;
5864#endif
5865 case BC_IITERL:
5866 | ins_AJ // RA = base, RD = target
5867 | lea RA, [BASE+RA*8]
5868 | mov RB, [RA+4]
5869 | cmp RB, LJ_TNIL; je >1 // Stop if iterator returned nil.
5870 if (op == BC_JITERL) {
5871 | mov [RA-4], RB
5872 | mov RB, [RA]
5873 | mov [RA-8], RB
5874 | jmp =>BC_JLOOP
5875 } else {
5876 | branchPC RD // Otherwise save control var + branch.
5877 | mov RD, [RA]
5878 | mov [RA-4], RB
5879 | mov [RA-8], RD
5880 }
5881 |1:
5882 | ins_next
5883 break;
5884
5885 case BC_LOOP:
5886 | ins_A // RA = base, RD = target (loop extent)
5887 | // Note: RA/RD is only used by trace recorder to determine scope/extent
5888 | // This opcode does NOT jump, it's only purpose is to detect a hot loop.
5889#if LJ_HASJIT
5890 | hotloop RB
5891#endif
5892 | // Fall through. Assumes BC_ILOOP follows and ins_A is a no-op.
5893 break;
5894
5895 case BC_ILOOP:
5896 | ins_A // RA = base, RD = target (loop extent)
5897 | ins_next
5898 break;
5899
5900 case BC_JLOOP:
5901#if LJ_HASJIT
5902 | ins_AD // RA = base (ignored), RD = traceno
5903 | mov RA, [DISPATCH+DISPATCH_J(trace)]
5904 | mov TRACE:RD, [RA+RD*4]
5905 | mov RDa, TRACE:RD->mcode
5906 | mov L:RB, SAVE_L
5907 | mov [DISPATCH+DISPATCH_GL(jit_base)], BASE
5908 | mov [DISPATCH+DISPATCH_GL(jit_L)], L:RB
5909 | // Save additional callee-save registers only used in compiled code.
5910 |.if X64WIN
5911 | mov TMPQ, r12
5912 | mov TMPa, r13
5913 | mov CSAVE_4, r14
5914 | mov CSAVE_3, r15
5915 | mov RAa, rsp
5916 | sub rsp, 9*16+4*8
5917 | movdqa [RAa], xmm6
5918 | movdqa [RAa-1*16], xmm7
5919 | movdqa [RAa-2*16], xmm8
5920 | movdqa [RAa-3*16], xmm9
5921 | movdqa [RAa-4*16], xmm10
5922 | movdqa [RAa-5*16], xmm11
5923 | movdqa [RAa-6*16], xmm12
5924 | movdqa [RAa-7*16], xmm13
5925 | movdqa [RAa-8*16], xmm14
5926 | movdqa [RAa-9*16], xmm15
5927 |.elif X64
5928 | mov TMPQ, r12
5929 | mov TMPa, r13
5930 | sub rsp, 16
5931 |.endif
5932 | jmp RDa
5933#endif
5934 break;
5935
5936 case BC_JMP:
5937 | ins_AJ // RA = unused, RD = target
5938 | branchPC RD
5939 | ins_next
5940 break;
5941
5942 /* -- Function headers -------------------------------------------------- */
5943
5944 /*
5945 ** Reminder: A function may be called with func/args above L->maxstack,
5946 ** i.e. occupying EXTRA_STACK slots. And vmeta_call may add one extra slot,
5947 ** too. This means all FUNC* ops (including fast functions) must check
5948 ** for stack overflow _before_ adding more slots!
5949 */
5950
5951 case BC_FUNCF:
5952#if LJ_HASJIT
5953 | hotcall RB
5954#endif
5955 case BC_FUNCV: /* NYI: compiled vararg functions. */
5956 | // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow and ins_AD is a no-op.
5957 break;
5958
5959 case BC_JFUNCF:
5960#if !LJ_HASJIT
5961 break;
5962#endif
5963 case BC_IFUNCF:
5964 | ins_AD // BASE = new base, RA = framesize, RD = nargs+1
5965 | mov KBASE, [PC-4+PC2PROTO(k)]
5966 | mov L:RB, SAVE_L
5967 | lea RA, [BASE+RA*8] // Top of frame.
5968 | cmp RA, L:RB->maxstack
5969 | ja ->vm_growstack_f
5970 | movzx RA, byte [PC-4+PC2PROTO(numparams)]
5971 | cmp NARGS:RD, RA // Check for missing parameters.
5972 | jbe >3
5973 |2:
5974 if (op == BC_JFUNCF) {
5975 | movzx RD, PC_RD
5976 | jmp =>BC_JLOOP
5977 } else {
5978 | ins_next
5979 }
5980 |
5981 |3: // Clear missing parameters.
5982 | mov dword [BASE+NARGS:RD*8-4], LJ_TNIL
5983 | add NARGS:RD, 1
5984 | cmp NARGS:RD, RA
5985 | jbe <3
5986 | jmp <2
5987 break;
5988
5989 case BC_JFUNCV:
5990#if !LJ_HASJIT
5991 break;
5992#endif
5993 | int3 // NYI: compiled vararg functions
5994 break; /* NYI: compiled vararg functions. */
5995
5996 case BC_IFUNCV:
5997 | ins_AD // BASE = new base, RA = framesize, RD = nargs+1
5998 | lea RB, [NARGS:RD*8+FRAME_VARG]
5999 | lea RD, [BASE+NARGS:RD*8]
6000 | mov LFUNC:KBASE, [BASE-8]
6001 | mov [RD-4], RB // Store delta + FRAME_VARG.
6002 | mov [RD-8], LFUNC:KBASE // Store copy of LFUNC.
6003 | mov L:RB, SAVE_L
6004 | lea RA, [RD+RA*8]
6005 | cmp RA, L:RB->maxstack
6006 | ja ->vm_growstack_v // Need to grow stack.
6007 | mov RA, BASE
6008 | mov BASE, RD
6009 | movzx RB, byte [PC-4+PC2PROTO(numparams)]
6010 | test RB, RB
6011 | jz >2
6012 |1: // Copy fixarg slots up to new frame.
6013 | add RA, 8
6014 | cmp RA, BASE
6015 | jnb >3 // Less args than parameters?
6016 | mov KBASE, [RA-8]
6017 | mov [RD], KBASE
6018 | mov KBASE, [RA-4]
6019 | mov [RD+4], KBASE
6020 | add RD, 8
6021 | mov dword [RA-4], LJ_TNIL // Clear old fixarg slot (help the GC).
6022 | sub RB, 1
6023 | jnz <1
6024 |2:
6025 if (op == BC_JFUNCV) {
6026 | movzx RD, PC_RD
6027 | jmp =>BC_JLOOP
6028 } else {
6029 | mov KBASE, [PC-4+PC2PROTO(k)]
6030 | ins_next
6031 }
6032 |
6033 |3: // Clear missing parameters.
6034 | mov dword [RD+4], LJ_TNIL
6035 | add RD, 8
6036 | sub RB, 1
6037 | jnz <3
6038 | jmp <2
6039 break;
6040
6041 case BC_FUNCC:
6042 case BC_FUNCCW:
6043 | ins_AD // BASE = new base, RA = ins RA|RD (unused), RD = nargs+1
6044 | mov CFUNC:RB, [BASE-8]
6045 | mov KBASEa, CFUNC:RB->f
6046 | mov L:RB, SAVE_L
6047 | lea RD, [BASE+NARGS:RD*8-8]
6048 | mov L:RB->base, BASE
6049 | lea RA, [RD+8*LUA_MINSTACK]
6050 | cmp RA, L:RB->maxstack
6051 | mov L:RB->top, RD
6052 if (op == BC_FUNCC) {
6053 |.if X64
6054 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
6055 |.else
6056 | mov ARG1, L:RB
6057 |.endif
6058 } else {
6059 |.if X64
6060 | mov CARG2, KBASEa
6061 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
6062 |.else
6063 | mov ARG2, KBASEa
6064 | mov ARG1, L:RB
6065 |.endif
6066 }
6067 | ja ->vm_growstack_c // Need to grow stack.
6068 | set_vmstate C
6069 if (op == BC_FUNCC) {
6070 | call KBASEa // (lua_State *L)
6071 } else {
6072 | // (lua_State *L, lua_CFunction f)
6073 | call aword [DISPATCH+DISPATCH_GL(wrapf)]
6074 }
6075 | set_vmstate INTERP
6076 | // nresults returned in eax (RD).
6077 | mov BASE, L:RB->base
6078 | lea RA, [BASE+RD*8]
6079 | neg RA
6080 | add RA, L:RB->top // RA = (L->top-(L->base+nresults))*8
6081 | mov PC, [BASE-4] // Fetch PC of caller.
6082 | jmp ->vm_returnc
6083 break;
6084
6085 /* ---------------------------------------------------------------------- */
6086
6087 default:
6088 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
6089 exit(2);
6090 break;
6091 }
6092}
6093
6094static int build_backend(BuildCtx *ctx)
6095{
6096 int op;
6097 int cmov = 1;
6098 int sse = 0;
6099#ifdef LUAJIT_CPU_NOCMOV
6100 cmov = 0;
6101#endif
6102#if defined(LUAJIT_CPU_SSE2) || defined(LJ_TARGET_X64)
6103 sse = 1;
6104#endif
6105
6106 dasm_growpc(Dst, BC__MAX);
6107
6108 build_subroutines(ctx, cmov, sse);
6109
6110 |.code_op
6111 for (op = 0; op < BC__MAX; op++)
6112 build_ins(ctx, (BCOp)op, op, cmov, sse);
6113
6114 return BC__MAX;
6115}
6116
6117/* Emit pseudo frame-info for all assembler functions. */
6118static void emit_asm_debug(BuildCtx *ctx)
6119{
6120 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
6121#if LJ_64
6122#define SZPTR "8"
6123#define BSZPTR "3"
6124#define REG_SP "0x7"
6125#define REG_RA "0x10"
6126#else
6127#define SZPTR "4"
6128#define BSZPTR "2"
6129#define REG_SP "0x4"
6130#define REG_RA "0x8"
6131#endif
6132 switch (ctx->mode) {
6133 case BUILD_elfasm:
6134 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
6135 fprintf(ctx->fp,
6136 ".Lframe0:\n"
6137 "\t.long .LECIE0-.LSCIE0\n"
6138 ".LSCIE0:\n"
6139 "\t.long 0xffffffff\n"
6140 "\t.byte 0x1\n"
6141 "\t.string \"\"\n"
6142 "\t.uleb128 0x1\n"
6143 "\t.sleb128 -" SZPTR "\n"
6144 "\t.byte " REG_RA "\n"
6145 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
6146 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
6147 "\t.align " SZPTR "\n"
6148 ".LECIE0:\n\n");
6149 fprintf(ctx->fp,
6150 ".LSFDE0:\n"
6151 "\t.long .LEFDE0-.LASFDE0\n"
6152 ".LASFDE0:\n"
6153 "\t.long .Lframe0\n"
6154#if LJ_64
6155 "\t.quad .Lbegin\n"
6156 "\t.quad %d\n"
6157 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
6158 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
6159 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
6160 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
6161 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
6162#else
6163 "\t.long .Lbegin\n"
6164 "\t.long %d\n"
6165 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
6166 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
6167 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
6168 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
6169 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
6170#endif
6171 "\t.align " SZPTR "\n"
6172 ".LEFDE0:\n\n", fcofs, CFRAME_SIZE);
6173#if LJ_HASFFI
6174 fprintf(ctx->fp,
6175 ".LSFDE1:\n"
6176 "\t.long .LEFDE1-.LASFDE1\n"
6177 ".LASFDE1:\n"
6178 "\t.long .Lframe0\n"
6179#if LJ_64
6180 "\t.quad lj_vm_ffi_call\n"
6181 "\t.quad %d\n"
6182 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
6183 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
6184 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
6185 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
6186#else
6187 "\t.long lj_vm_ffi_call\n"
6188 "\t.long %d\n"
6189 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
6190 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
6191 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
6192 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
6193#endif
6194 "\t.align " SZPTR "\n"
6195 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
6196#endif
6197#if (defined(__sun__) && defined(__svr4__)) || defined(__solaris_)
6198 fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n");
6199#else
6200 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
6201#endif
6202 fprintf(ctx->fp,
6203 ".Lframe1:\n"
6204 "\t.long .LECIE1-.LSCIE1\n"
6205 ".LSCIE1:\n"
6206 "\t.long 0\n"
6207 "\t.byte 0x1\n"
6208 "\t.string \"zPR\"\n"
6209 "\t.uleb128 0x1\n"
6210 "\t.sleb128 -" SZPTR "\n"
6211 "\t.byte " REG_RA "\n"
6212 "\t.uleb128 6\n" /* augmentation length */
6213 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6214 "\t.long lj_err_unwind_dwarf-.\n"
6215 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6216 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
6217 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
6218 "\t.align " SZPTR "\n"
6219 ".LECIE1:\n\n");
6220 fprintf(ctx->fp,
6221 ".LSFDE2:\n"
6222 "\t.long .LEFDE2-.LASFDE2\n"
6223 ".LASFDE2:\n"
6224 "\t.long .LASFDE2-.Lframe1\n"
6225 "\t.long .Lbegin-.\n"
6226 "\t.long %d\n"
6227 "\t.uleb128 0\n" /* augmentation length */
6228 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
6229#if LJ_64
6230 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
6231 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
6232 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
6233 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
6234#else
6235 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
6236 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
6237 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
6238 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
6239#endif
6240 "\t.align " SZPTR "\n"
6241 ".LEFDE2:\n\n", fcofs, CFRAME_SIZE);
6242#if LJ_HASFFI
6243 fprintf(ctx->fp,
6244 ".Lframe2:\n"
6245 "\t.long .LECIE2-.LSCIE2\n"
6246 ".LSCIE2:\n"
6247 "\t.long 0\n"
6248 "\t.byte 0x1\n"
6249 "\t.string \"zR\"\n"
6250 "\t.uleb128 0x1\n"
6251 "\t.sleb128 -" SZPTR "\n"
6252 "\t.byte " REG_RA "\n"
6253 "\t.uleb128 1\n" /* augmentation length */
6254 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6255 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
6256 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
6257 "\t.align " SZPTR "\n"
6258 ".LECIE2:\n\n");
6259 fprintf(ctx->fp,
6260 ".LSFDE3:\n"
6261 "\t.long .LEFDE3-.LASFDE3\n"
6262 ".LASFDE3:\n"
6263 "\t.long .LASFDE3-.Lframe2\n"
6264 "\t.long lj_vm_ffi_call-.\n"
6265 "\t.long %d\n"
6266 "\t.uleb128 0\n" /* augmentation length */
6267#if LJ_64
6268 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
6269 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
6270 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
6271 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
6272#else
6273 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
6274 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
6275 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
6276 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
6277#endif
6278 "\t.align " SZPTR "\n"
6279 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
6280#endif
6281 break;
6282 case BUILD_coffasm:
6283 fprintf(ctx->fp, "\t.section .eh_frame,\"dr\"\n");
6284 fprintf(ctx->fp,
6285 "\t.def %slj_err_unwind_dwarf; .scl 2; .type 32; .endef\n",
6286 LJ_32 ? "_" : "");
6287 fprintf(ctx->fp,
6288 "Lframe1:\n"
6289 "\t.long LECIE1-LSCIE1\n"
6290 "LSCIE1:\n"
6291 "\t.long 0\n"
6292 "\t.byte 0x1\n"
6293 "\t.string \"zP\"\n"
6294 "\t.uleb128 0x1\n"
6295 "\t.sleb128 -" SZPTR "\n"
6296 "\t.byte " REG_RA "\n"
6297 "\t.uleb128 5\n" /* augmentation length */
6298 "\t.byte 0x00\n" /* absptr */
6299 "\t.long %slj_err_unwind_dwarf\n"
6300 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
6301 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
6302 "\t.align " SZPTR "\n"
6303 "LECIE1:\n\n", LJ_32 ? "_" : "");
6304 fprintf(ctx->fp,
6305 "LSFDE1:\n"
6306 "\t.long LEFDE1-LASFDE1\n"
6307 "LASFDE1:\n"
6308 "\t.long LASFDE1-Lframe1\n"
6309 "\t.long %slj_vm_asm_begin\n"
6310 "\t.long %d\n"
6311 "\t.uleb128 0\n" /* augmentation length */
6312 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
6313#if LJ_64
6314 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
6315 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
6316 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
6317 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
6318#else
6319 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
6320 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
6321 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
6322 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
6323#endif
6324 "\t.align " SZPTR "\n"
6325 "LEFDE1:\n\n", LJ_32 ? "_" : "", (int)ctx->codesz, CFRAME_SIZE);
6326 break;
6327 /* Mental note: never let Apple design an assembler.
6328 ** Or a linker. Or a plastic case. But I digress.
6329 */
6330 case BUILD_machasm: {
6331#if LJ_HASFFI
6332 int fcsize = 0;
6333#endif
6334 int i;
6335 fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
6336 fprintf(ctx->fp,
6337 "EH_frame1:\n"
6338 "\t.set L$set$x,LECIEX-LSCIEX\n"
6339 "\t.long L$set$x\n"
6340 "LSCIEX:\n"
6341 "\t.long 0\n"
6342 "\t.byte 0x1\n"
6343 "\t.ascii \"zPR\\0\"\n"
6344 "\t.byte 0x1\n"
6345 "\t.byte 128-" SZPTR "\n"
6346 "\t.byte " REG_RA "\n"
6347 "\t.byte 6\n" /* augmentation length */
6348 "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
6349#if LJ_64
6350 "\t.long _lj_err_unwind_dwarf+4@GOTPCREL\n"
6351 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6352 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
6353#else
6354 "\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
6355 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6356 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
6357#endif
6358 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
6359 "\t.align " BSZPTR "\n"
6360 "LECIEX:\n\n");
6361 for (i = 0; i < ctx->nsym; i++) {
6362 const char *name = ctx->sym[i].name;
6363 int32_t size = ctx->sym[i+1].ofs - ctx->sym[i].ofs;
6364 if (size == 0) continue;
6365#if LJ_HASFFI
6366 if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; }
6367#endif
6368 fprintf(ctx->fp,
6369 "%s.eh:\n"
6370 "LSFDE%d:\n"
6371 "\t.set L$set$%d,LEFDE%d-LASFDE%d\n"
6372 "\t.long L$set$%d\n"
6373 "LASFDE%d:\n"
6374 "\t.long LASFDE%d-EH_frame1\n"
6375 "\t.long %s-.\n"
6376 "\t.long %d\n"
6377 "\t.byte 0\n" /* augmentation length */
6378 "\t.byte 0xe\n\t.byte %d\n" /* def_cfa_offset */
6379#if LJ_64
6380 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
6381 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
6382 "\t.byte 0x8f\n\t.byte 0x4\n" /* offset r15 */
6383 "\t.byte 0x8e\n\t.byte 0x5\n" /* offset r14 */
6384#else
6385 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
6386 "\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
6387 "\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
6388 "\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
6389#endif
6390 "\t.align " BSZPTR "\n"
6391 "LEFDE%d:\n\n",
6392 name, i, i, i, i, i, i, i, name, size, CFRAME_SIZE, i);
6393 }
6394#if LJ_HASFFI
6395 if (fcsize) {
6396 fprintf(ctx->fp,
6397 "EH_frame2:\n"
6398 "\t.set L$set$y,LECIEY-LSCIEY\n"
6399 "\t.long L$set$y\n"
6400 "LSCIEY:\n"
6401 "\t.long 0\n"
6402 "\t.byte 0x1\n"
6403 "\t.ascii \"zR\\0\"\n"
6404 "\t.byte 0x1\n"
6405 "\t.byte 128-" SZPTR "\n"
6406 "\t.byte " REG_RA "\n"
6407 "\t.byte 1\n" /* augmentation length */
6408#if LJ_64
6409 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6410 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
6411#else
6412 "\t.byte 0x1b\n" /* pcrel|sdata4 */
6413 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH. */
6414#endif
6415 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
6416 "\t.align " BSZPTR "\n"
6417 "LECIEY:\n\n");
6418 fprintf(ctx->fp,
6419 "_lj_vm_ffi_call.eh:\n"
6420 "LSFDEY:\n"
6421 "\t.set L$set$yy,LEFDEY-LASFDEY\n"
6422 "\t.long L$set$yy\n"
6423 "LASFDEY:\n"
6424 "\t.long LASFDEY-EH_frame2\n"
6425 "\t.long _lj_vm_ffi_call-.\n"
6426 "\t.long %d\n"
6427 "\t.byte 0\n" /* augmentation length */
6428#if LJ_64
6429 "\t.byte 0xe\n\t.byte 16\n" /* def_cfa_offset */
6430 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
6431 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
6432 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
6433#else
6434 "\t.byte 0xe\n\t.byte 8\n" /* def_cfa_offset */
6435 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
6436 "\t.byte 0xd\n\t.uleb128 0x4\n" /* def_cfa_register ebp */
6437 "\t.byte 0x83\n\t.byte 0x3\n" /* offset ebx */
6438#endif
6439 "\t.align " BSZPTR "\n"
6440 "LEFDEY:\n\n", fcsize);
6441 }
6442#endif
6443#if LJ_64
6444 fprintf(ctx->fp, "\t.subsections_via_symbols\n");
6445#else
6446 fprintf(ctx->fp,
6447 "\t.non_lazy_symbol_pointer\n"
6448 "L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
6449 ".indirect_symbol _lj_err_unwind_dwarf\n"
6450 ".long 0\n");
6451#endif
6452 }
6453 break;
6454 default: /* Difficult for other modes. */
6455 break;
6456 }
6457}
6458
diff --git a/libraries/luajit-2.0/src/buildvm_x86.h b/libraries/luajit-2.0/src/buildvm_x86.h
new file mode 100644
index 0000000..cd33cf8
--- /dev/null
+++ b/libraries/luajit-2.0/src/buildvm_x86.h
@@ -0,0 +1,3561 @@
1/*
2** This file has been pre-processed with DynASM.
3** http://luajit.org/dynasm.html
4** DynASM version 1.3.0, DynASM x86 version 1.3.0
5** DO NOT EDIT! The original file is in "buildvm_x86.dasc".
6*/
7
8#if DASM_VERSION != 10300
9#error "Version mismatch between DynASM and included encoding engine"
10#endif
11
12#define DASM_SECTION_CODE_OP 0
13#define DASM_SECTION_CODE_SUB 1
14#define DASM_MAXSECTION 2
15static const unsigned char build_actionlist[17321] = {
16 254,1,248,10,252,247,198,237,15,132,244,11,131,230,252,248,41,252,242,141,
17 76,49,252,248,139,114,252,252,199,68,10,4,237,248,12,131,192,1,137,68,36,
18 20,252,247,198,237,15,132,244,13,248,14,129,252,246,239,252,247,198,237,15,
19 133,244,10,199,131,233,237,131,230,252,248,41,214,252,247,222,131,232,1,15,
20 132,244,248,248,1,139,44,10,137,106,252,248,139,108,10,4,137,106,252,252,
21 131,194,8,131,232,1,15,133,244,1,248,2,255,139,108,36,48,137,181,233,248,
22 3,139,68,36,20,139,76,36,56,248,4,57,193,15,133,244,252,248,5,131,252,234,
23 8,137,149,233,248,15,139,76,36,52,137,141,233,49,192,248,16,131,196,28,91,
24 94,95,93,195,248,6,15,130,244,253,59,149,233,15,135,244,254,199,66,252,252,
25 237,131,194,8,131,192,1,252,233,244,4,248,7,255,133,201,15,132,244,5,41,193,
26 141,20,202,252,233,244,5,248,8,137,149,233,137,68,36,20,137,202,137,252,233,
27 232,251,1,0,139,149,233,252,233,244,3,248,17,137,208,137,204,248,18,139,108,
28 36,48,139,173,233,199,133,233,237,252,233,244,16,248,19,248,20,129,225,239,
29 137,204,248,21,255,139,108,36,48,185,252,248,252,255,252,255,252,255,184,
30 237,139,149,233,139,157,233,129,195,239,139,114,252,252,199,66,252,252,237,
31 199,131,233,237,252,233,244,12,248,22,186,237,252,233,244,248,248,23,131,
32 232,8,252,233,244,247,248,24,141,68,194,252,248,248,1,15,182,142,233,131,
33 198,4,137,149,233,255,137,133,233,137,116,36,24,137,202,248,2,137,252,233,
34 232,251,1,0,139,149,233,139,133,233,139,106,252,248,41,208,193,232,3,131,
35 192,1,139,181,233,139,14,15,182,252,233,15,182,205,131,198,4,252,255,36,171,
36 248,25,85,87,86,83,131,252,236,28,139,108,36,48,139,76,36,52,190,237,49,192,
37 141,188,253,36,233,139,157,233,129,195,239,137,189,233,137,68,36,24,137,68,
38 36,52,56,133,233,15,132,244,249,199,131,233,237,136,133,233,139,149,233,139,
39 133,233,41,200,193,232,3,131,192,1,41,209,139,114,252,252,137,68,36,20,252,
40 247,198,237,255,15,132,244,13,252,233,244,14,248,26,85,87,86,83,131,252,236,
41 28,190,237,252,233,244,247,248,27,85,87,86,83,131,252,236,28,190,237,248,
42 1,139,108,36,48,139,76,36,52,139,189,233,137,124,36,52,137,108,36,24,137,
43 165,233,248,2,139,157,233,129,195,239,248,3,199,131,233,237,139,149,233,255,
44 1,206,41,214,139,133,233,41,200,193,232,3,131,192,1,248,28,139,105,252,248,
45 129,121,253,252,252,239,15,133,244,29,248,30,137,202,137,114,252,252,139,
46 181,233,139,14,15,182,252,233,15,182,205,131,198,4,252,255,36,171,248,31,
47 85,87,86,83,131,252,236,28,139,108,36,48,139,68,36,56,139,76,36,52,139,84,
48 36,60,137,108,36,24,139,189,233,43,189,233,199,68,36,60,0,0,0,0,137,124,36,
49 56,137,68,36,8,137,76,36,4,137,44,36,139,189,233,137,124,36,52,137,165,233,
50 252,255,210,133,192,15,132,244,15,137,193,190,237,252,233,244,2,248,11,1,
51 209,131,230,252,248,137,213,41,252,242,199,68,193,252,252,237,137,200,139,
52 117,252,244,255,139,77,252,240,255,131,252,249,1,15,134,244,247,255,139,122,
53 252,248,139,191,233,139,191,233,252,255,225,255,248,1,15,132,244,32,41,213,
54 193,252,237,3,141,69,252,255,252,233,244,33,255,248,34,15,182,78,252,255,
55 131,252,237,16,141,12,202,41,252,233,15,132,244,35,252,247,217,193,252,233,
56 3,137,76,36,8,139,72,4,139,0,137,77,4,137,69,0,137,108,36,4,252,233,244,36,
57 248,37,137,68,36,16,199,68,36,20,237,141,68,36,16,128,126,252,252,235,15,
58 133,244,247,141,139,233,137,41,199,65,4,237,137,205,252,233,244,248,248,38,
59 15,182,70,252,254,255,199,68,36,20,237,137,68,36,16,255,252,242,15,42,192,
60 252,242,15,17,68,36,16,255,137,68,36,12,219,68,36,12,221,92,36,16,255,141,
61 68,36,16,252,233,244,247,248,39,15,182,70,252,254,141,4,194,248,1,15,182,
62 110,252,255,141,44,252,234,248,2,137,108,36,4,139,108,36,48,137,68,36,8,137,
63 44,36,137,149,233,137,116,36,24,232,251,1,1,139,149,233,133,192,15,132,244,
64 249,248,35,15,182,78,252,253,139,104,4,139,0,137,108,202,4,137,4,202,139,
65 6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,3,139,141,
66 233,137,113,252,244,141,177,233,41,214,139,105,252,248,184,237,252,233,244,
67 30,248,40,137,68,36,16,199,68,36,20,237,141,68,36,16,128,126,252,252,235,
68 15,133,244,247,255,141,139,233,137,41,199,65,4,237,137,205,252,233,244,248,
69 248,41,15,182,70,252,254,255,141,68,36,16,252,233,244,247,248,42,15,182,70,
70 252,254,141,4,194,248,1,15,182,110,252,255,141,44,252,234,248,2,137,108,36,
71 4,139,108,36,48,137,68,36,8,137,44,36,137,149,233,137,116,36,24,232,251,1,
72 2,139,149,233,133,192,15,132,244,249,15,182,78,252,253,139,108,202,4,139,
73 12,202,137,104,4,137,8,248,43,139,6,15,182,204,15,182,232,131,198,4,193,232,
74 16,252,255,36,171,248,3,139,141,233,137,113,252,244,15,182,70,252,253,139,
75 108,194,4,139,4,194,137,105,20,137,65,16,141,177,233,41,214,139,105,252,248,
76 184,237,252,233,244,30,248,44,15,182,110,252,252,141,4,194,141,12,202,137,
77 108,36,12,139,108,36,48,137,68,36,8,137,76,36,4,137,44,36,137,149,233,137,
78 116,36,24,232,251,1,3,248,3,139,149,233,255,131,252,248,1,15,135,244,45,248,
79 4,141,118,4,15,130,244,252,248,5,15,183,70,252,254,141,180,253,134,233,248,
80 6,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,46,
81 131,198,4,129,120,253,4,239,15,130,244,5,252,233,244,6,248,47,129,120,253,
82 4,239,252,233,244,4,248,48,131,252,238,4,137,108,36,12,139,108,36,48,137,
83 68,36,8,137,76,36,4,137,44,36,137,149,233,255,137,116,36,24,232,251,1,4,252,
84 233,244,3,248,49,255,131,252,238,4,139,108,36,48,137,149,233,137,252,233,
85 139,86,252,252,137,116,36,24,232,251,1,5,252,233,244,3,255,248,50,255,15,
86 182,110,252,255,255,248,51,141,4,199,252,233,244,247,248,52,255,248,53,141,
87 4,199,141,44,252,234,149,252,233,244,248,248,54,141,4,194,137,197,252,233,
88 244,248,248,55,255,248,56,141,4,194,248,1,141,44,252,234,248,2,141,12,202,
89 137,108,36,8,139,108,36,48,137,68,36,12,15,182,70,252,252,137,76,36,4,137,
90 68,36,16,137,44,36,137,149,233,137,116,36,24,232,251,1,6,139,149,233,133,
91 192,15,132,244,43,248,45,137,193,41,208,137,113,252,244,141,176,233,184,237,
92 252,233,244,28,248,57,139,108,36,48,137,149,233,141,20,194,137,252,233,137,
93 116,36,24,232,251,1,7,139,149,233,255,133,192,15,133,244,45,15,183,70,252,
94 254,139,12,194,252,233,244,58,255,252,233,244,45,255,248,59,141,76,202,8,
95 248,29,137,76,36,20,137,68,36,16,131,252,233,8,141,4,193,139,108,36,48,137,
96 76,36,4,137,68,36,8,137,44,36,137,149,233,137,116,36,24,232,251,1,8,139,149,
97 233,139,76,36,20,139,68,36,16,139,105,252,248,131,192,1,57,215,15,132,244,
98 60,137,202,137,114,252,252,139,181,233,139,14,15,182,252,233,15,182,205,131,
99 198,4,252,255,36,171,248,61,139,108,36,48,137,149,233,137,202,137,252,233,
100 137,116,36,24,232,251,1,9,139,149,233,139,70,252,252,15,182,204,15,182,232,
101 193,232,16,252,255,164,253,171,233,248,62,129,252,248,239,15,130,244,63,139,
102 106,4,129,252,253,239,15,131,244,63,139,114,252,252,137,68,36,20,137,106,
103 252,252,139,42,137,106,252,248,131,232,2,15,132,244,248,255,137,209,248,1,
104 131,193,8,139,105,4,137,105,252,252,139,41,137,105,252,248,131,232,1,15,133,
105 244,1,248,2,139,68,36,20,252,233,244,64,248,65,129,252,248,239,15,130,244,
106 63,139,106,4,184,237,252,247,213,57,232,255,15,71,197,255,15,134,244,247,
107 137,232,248,1,255,248,2,139,106,252,248,139,132,253,197,233,139,114,252,252,
108 199,66,252,252,237,137,66,252,248,252,233,244,66,248,67,129,252,248,239,15,
109 130,244,63,139,106,4,139,114,252,252,129,252,253,239,15,133,244,252,248,1,
110 139,42,139,173,233,248,2,133,252,237,199,66,252,252,237,15,132,244,66,139,
111 131,233,199,66,252,252,237,255,137,106,252,248,139,141,233,35,136,233,105,
112 201,239,3,141,233,248,3,129,185,233,239,15,133,244,250,57,129,233,15,132,
113 244,251,248,4,139,137,233,133,201,15,133,244,3,252,233,244,66,248,5,139,105,
114 4,129,252,253,239,255,15,132,244,66,139,1,137,106,252,252,137,66,252,248,
115 252,233,244,66,248,6,129,252,253,239,15,132,244,1,129,252,253,239,15,135,
116 244,254,189,237,248,8,252,247,213,139,172,253,171,233,252,233,244,2,248,68,
117 129,252,248,239,15,130,244,63,255,129,122,253,4,239,15,133,244,63,139,42,
118 131,189,233,0,15,133,244,63,129,122,253,12,239,15,133,244,63,139,66,8,137,
119 133,233,139,114,252,252,199,66,252,252,237,137,106,252,248,252,246,133,233,
120 235,15,132,244,247,128,165,233,235,139,131,233,137,171,233,137,133,233,248,
121 1,255,252,233,244,66,248,69,129,252,248,239,15,130,244,63,129,122,253,4,239,
122 15,133,244,63,139,2,139,108,36,48,137,68,36,4,137,44,36,137,213,131,194,8,
123 137,84,36,8,232,251,1,10,137,252,234,139,40,139,64,4,139,114,252,252,137,
124 106,252,248,137,66,252,252,252,233,244,66,248,70,129,252,248,239,15,133,244,
125 63,129,122,253,4,239,255,15,133,244,247,139,42,252,233,244,71,248,1,15,135,
126 244,63,255,15,131,244,63,255,252,242,15,16,2,252,233,244,72,255,221,2,252,
127 233,244,73,255,248,74,129,252,248,239,15,130,244,63,139,114,252,252,129,122,
128 253,4,239,15,133,244,249,139,2,248,2,199,66,252,252,237,137,66,252,248,252,
129 233,244,66,248,3,129,122,253,4,239,15,135,244,63,131,187,233,0,15,133,244,
130 63,139,171,233,59,171,233,255,15,130,244,247,232,244,75,248,1,139,108,36,
131 48,137,149,233,137,116,36,24,137,252,233,255,232,251,1,11,255,232,251,1,12,
132 255,139,149,233,252,233,244,2,248,76,129,252,248,239,15,130,244,63,15,132,
133 244,248,248,1,129,122,253,4,239,15,133,244,63,139,108,36,48,137,149,233,137,
134 149,233,139,114,252,252,139,2,137,68,36,4,137,44,36,131,194,8,137,84,36,8,
135 137,116,36,24,232,251,1,13,139,149,233,133,192,15,132,244,249,139,106,8,139,
136 66,12,137,106,252,248,137,66,252,252,139,106,16,139,66,20,137,42,137,66,4,
137 248,77,184,237,255,252,233,244,78,248,2,199,66,12,237,252,233,244,1,248,3,
138 199,66,252,252,237,252,233,244,66,248,79,129,252,248,239,15,130,244,63,139,
139 42,129,122,253,4,239,15,133,244,63,255,131,189,233,0,15,133,244,63,255,139,
140 106,252,248,139,133,233,139,114,252,252,199,66,252,252,237,137,66,252,248,
141 199,66,12,237,184,237,252,233,244,78,248,80,129,252,248,239,15,130,244,63,
142 129,122,253,4,239,15,133,244,63,129,122,253,12,239,255,139,114,252,252,255,
143 139,66,8,131,192,1,199,66,252,252,237,137,66,252,248,255,252,242,15,16,66,
144 8,189,0,0,252,240,63,102,15,110,205,102,15,112,201,81,252,242,15,88,193,252,
145 242,15,45,192,252,242,15,17,66,252,248,255,221,66,8,217,232,222,193,219,20,
146 36,221,90,252,248,139,4,36,255,139,42,59,133,233,15,131,244,248,193,224,3,
147 3,133,233,248,1,129,120,253,4,239,15,132,244,81,139,40,139,64,4,137,42,137,
148 66,4,252,233,244,77,248,2,131,189,233,0,15,132,244,81,137,252,233,137,213,
149 137,194,232,251,1,14,137,252,234,133,192,15,133,244,1,248,81,184,237,252,
150 233,244,78,248,82,255,139,106,252,248,139,133,233,139,114,252,252,199,66,
151 252,252,237,137,66,252,248,255,199,66,12,237,199,66,8,0,0,0,0,255,15,87,192,
152 252,242,15,17,66,8,255,217,252,238,221,90,8,255,184,237,252,233,244,78,248,
153 83,129,252,248,239,15,130,244,63,141,74,8,131,232,1,190,237,248,1,15,182,
154 171,233,193,252,237,235,131,229,1,1,252,238,252,233,244,28,248,84,129,252,
155 248,239,15,130,244,63,129,122,253,12,239,15,133,244,63,255,139,106,4,137,
156 106,12,199,66,4,237,139,42,139,114,8,137,106,8,137,50,141,74,16,131,232,2,
157 190,237,252,233,244,1,248,85,129,252,248,239,15,130,244,63,139,42,139,114,
158 252,252,137,116,36,24,137,44,36,129,122,253,4,239,15,133,244,63,131,189,233,
159 0,15,133,244,63,128,189,233,235,15,135,244,63,139,141,233,15,132,244,247,
160 255,59,141,233,15,132,244,63,248,1,141,116,193,252,240,59,181,233,15,135,
161 244,63,137,181,233,139,108,36,48,137,149,233,131,194,8,137,149,233,141,108,
162 194,232,41,252,245,57,206,15,132,244,249,248,2,139,68,46,4,137,70,252,252,
163 139,4,46,137,70,252,248,131,252,238,8,57,206,15,133,244,2,248,3,137,76,36,
164 4,49,201,137,76,36,12,137,76,36,8,232,244,25,199,131,233,237,255,139,108,
165 36,48,139,52,36,139,149,233,129,252,248,239,15,135,244,254,248,4,139,142,
166 233,139,190,233,137,142,233,137,252,254,41,206,15,132,244,252,141,4,50,193,
167 252,238,3,59,133,233,15,135,244,255,137,213,41,205,248,5,139,1,137,4,41,139,
168 65,4,137,68,41,4,131,193,8,57,252,249,15,133,244,5,248,6,141,70,2,199,66,
169 252,252,237,248,7,139,116,36,24,137,68,36,20,185,252,248,252,255,252,255,
170 252,255,252,247,198,237,255,15,132,244,13,252,233,244,14,248,8,199,66,252,
171 252,237,139,142,233,131,252,233,8,137,142,233,139,1,137,2,139,65,4,137,66,
172 4,184,237,252,233,244,7,248,9,139,12,36,137,185,233,137,252,242,137,252,233,
173 232,251,1,0,139,52,36,139,149,233,252,233,244,4,248,86,139,106,252,248,139,
174 173,233,139,114,252,252,137,116,36,24,137,44,36,131,189,233,0,15,133,244,
175 63,255,128,189,233,235,15,135,244,63,139,141,233,15,132,244,247,59,141,233,
176 15,132,244,63,248,1,141,116,193,252,248,59,181,233,15,135,244,63,137,181,
177 233,139,108,36,48,137,149,233,137,149,233,141,108,194,252,240,41,252,245,
178 57,206,15,132,244,249,248,2,255,139,68,46,4,137,70,252,252,139,4,46,137,70,
179 252,248,131,252,238,8,57,206,15,133,244,2,248,3,137,76,36,4,49,201,137,76,
180 36,12,137,76,36,8,232,244,25,199,131,233,237,139,108,36,48,139,52,36,139,
181 149,233,129,252,248,239,15,135,244,254,248,4,139,142,233,139,190,233,137,
182 142,233,137,252,254,41,206,15,132,244,252,141,4,50,193,252,238,3,59,133,233,
183 15,135,244,255,255,137,213,41,205,248,5,139,1,137,4,41,139,65,4,137,68,41,
184 4,131,193,8,57,252,249,15,133,244,5,248,6,141,70,1,248,7,139,116,36,24,137,
185 68,36,20,49,201,252,247,198,237,15,132,244,13,252,233,244,14,248,8,137,252,
186 242,137,252,233,232,251,1,15,248,9,139,12,36,137,185,233,137,252,242,137,
187 252,233,232,251,1,0,139,52,36,139,149,233,252,233,244,4,248,87,139,108,36,
188 48,252,247,133,233,237,15,132,244,63,255,137,149,233,141,68,194,252,248,137,
189 133,233,49,192,137,133,233,176,235,136,133,233,252,233,244,16,255,248,71,
190 255,248,73,139,114,252,252,221,90,252,248,252,233,244,66,255,248,88,129,252,
191 248,239,15,130,244,63,255,129,122,253,4,239,15,133,244,248,139,42,131,252,
192 253,0,15,137,244,71,252,247,221,15,136,244,247,248,89,248,71,139,114,252,
193 252,199,66,252,252,237,137,106,252,248,252,233,244,66,248,1,139,114,252,252,
194 199,66,252,252,0,0,224,65,199,66,252,248,0,0,0,0,252,233,244,66,248,2,15,
195 135,244,63,255,129,122,253,4,239,15,131,244,63,255,252,242,15,16,2,102,15,
196 252,239,201,102,15,118,201,102,15,115,209,1,15,84,193,248,72,139,114,252,
197 252,252,242,15,17,66,252,248,255,221,2,217,225,248,72,248,73,139,114,252,
198 252,221,90,252,248,255,248,66,184,237,248,78,137,68,36,20,248,64,252,247,
199 198,237,15,133,244,253,248,5,56,70,252,255,15,135,244,252,15,182,78,252,253,
200 252,247,209,141,20,202,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,
201 255,36,171,248,6,199,68,194,252,244,237,131,192,1,252,233,244,5,248,7,185,
202 252,248,252,255,252,255,252,255,252,233,244,14,248,90,255,129,122,253,4,239,
203 15,133,244,247,139,42,252,233,244,71,248,1,15,135,244,63,255,252,242,15,16,
204 2,232,244,91,255,252,242,15,45,232,129,252,253,0,0,0,128,15,133,244,71,252,
205 242,15,42,205,102,15,46,193,15,138,244,72,15,132,244,71,255,221,2,232,244,
206 91,255,219,20,36,139,44,36,129,252,253,0,0,0,128,15,133,244,248,217,192,219,
207 4,36,255,223,252,233,221,216,255,218,252,233,223,224,158,255,15,138,244,73,
208 15,133,244,73,248,2,221,216,252,233,244,71,255,248,92,255,252,242,15,16,2,
209 232,244,93,255,221,2,232,244,93,255,248,94,129,252,248,239,15,130,244,63,
210 129,122,253,4,239,15,131,244,63,252,242,15,81,2,252,233,244,72,255,248,94,
211 129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,221,2,217,252,
212 250,252,233,244,73,255,248,95,129,252,248,239,15,130,244,63,129,122,253,4,
213 239,15,131,244,63,217,252,237,221,2,217,252,241,252,233,244,73,248,96,129,
214 252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,217,252,236,221,
215 2,217,252,241,252,233,244,73,248,97,129,252,248,239,255,15,130,244,63,129,
216 122,253,4,239,15,131,244,63,221,2,232,244,98,252,233,244,73,248,99,129,252,
217 248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,221,2,217,252,254,252,
218 233,244,73,248,100,129,252,248,239,255,15,130,244,63,129,122,253,4,239,15,
219 131,244,63,221,2,217,252,255,252,233,244,73,248,101,129,252,248,239,15,130,
220 244,63,129,122,253,4,239,15,131,244,63,221,2,217,252,242,221,216,252,233,
221 244,73,248,102,129,252,248,239,15,130,244,63,255,129,122,253,4,239,15,131,
222 244,63,221,2,217,192,216,200,217,232,222,225,217,252,250,217,252,243,252,
223 233,244,73,248,103,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,
224 244,63,221,2,217,192,216,200,217,232,222,225,217,252,250,217,201,217,252,
225 243,252,233,244,73,248,104,129,252,248,239,15,130,244,63,129,122,253,4,239,
226 15,131,244,63,255,221,2,217,232,217,252,243,252,233,244,73,255,248,105,129,
227 252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,252,242,15,16,2,
228 252,242,15,17,4,36,255,248,105,129,252,248,239,15,130,244,63,129,122,253,
229 4,239,15,131,244,63,221,2,221,28,36,255,137,213,232,251,1,16,137,252,234,
230 252,233,244,73,255,248,106,129,252,248,239,15,130,244,63,129,122,253,4,239,
231 15,131,244,63,252,242,15,16,2,252,242,15,17,4,36,255,248,106,129,252,248,
232 239,15,130,244,63,129,122,253,4,239,15,131,244,63,221,2,221,28,36,255,137,
233 213,232,251,1,17,137,252,234,252,233,244,73,255,248,107,129,252,248,239,15,
234 130,244,63,129,122,253,4,239,15,131,244,63,252,242,15,16,2,252,242,15,17,
235 4,36,255,248,107,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,
236 63,221,2,221,28,36,255,137,213,232,251,1,18,137,252,234,252,233,244,73,248,
237 108,255,248,109,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,
238 63,252,242,15,16,2,139,106,252,248,252,242,15,89,133,233,252,233,244,72,255,
239 248,109,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,221,
240 2,139,106,252,248,220,141,233,252,233,244,73,255,248,110,129,252,248,239,
241 15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
242 63,221,2,221,66,8,217,252,243,252,233,244,73,248,111,129,252,248,239,15,130,
243 244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,255,15,131,244,
244 63,221,66,8,221,2,217,252,253,221,217,252,233,244,73,248,112,129,252,248,
245 239,15,130,244,63,139,106,4,129,252,253,239,15,131,244,63,139,114,252,252,
246 139,2,137,106,252,252,137,66,252,248,209,229,129,252,253,0,0,224,252,255,
247 15,131,244,249,9,232,15,132,244,249,184,252,254,3,0,0,129,252,253,0,0,32,
248 0,15,130,244,250,248,1,193,252,237,21,41,197,255,252,242,15,42,197,255,137,
249 108,36,16,219,68,36,16,255,139,106,252,252,129,229,252,255,252,255,15,128,
250 129,205,0,0,224,63,137,106,252,252,248,2,255,252,242,15,17,2,255,221,26,255,
251 184,237,252,233,244,78,248,3,255,15,87,192,252,233,244,2,255,217,252,238,
252 252,233,244,2,255,248,4,255,252,242,15,16,2,189,0,0,80,67,102,15,110,205,
253 102,15,112,201,81,252,242,15,89,193,252,242,15,17,66,252,248,255,221,2,199,
254 68,36,16,0,0,128,90,216,76,36,16,221,90,252,248,255,139,106,252,252,184,52,
255 4,0,0,209,229,252,233,244,1,255,248,113,129,252,248,239,15,130,244,63,129,
256 122,253,4,239,15,131,244,63,252,242,15,16,2,255,248,113,129,252,248,239,15,
257 130,244,63,129,122,253,4,239,15,131,244,63,221,2,255,139,106,4,139,114,252,
258 252,209,229,129,252,253,0,0,224,252,255,15,132,244,250,255,15,40,224,232,
259 244,114,252,242,15,92,224,248,1,252,242,15,17,66,252,248,252,242,15,17,34,
260 255,217,192,232,244,114,220,252,233,248,1,221,90,252,248,221,26,255,139,66,
261 252,252,139,106,4,49,232,15,136,244,249,248,2,184,237,252,233,244,78,248,
262 3,129,252,245,0,0,0,128,137,106,4,252,233,244,2,248,4,255,15,87,228,252,233,
263 244,1,255,217,252,238,217,201,252,233,244,1,255,248,115,129,252,248,239,15,
264 130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
265 63,221,66,8,221,2,248,1,217,252,248,223,224,158,15,138,244,1,221,217,252,
266 233,244,73,255,248,116,129,252,248,239,15,130,244,63,129,122,253,4,239,15,
267 131,244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,15,16,
268 74,8,232,244,117,252,233,244,72,255,248,116,129,252,248,239,15,130,244,63,
269 129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,63,221,2,221,
270 66,8,232,244,117,252,233,244,73,255,248,118,185,2,0,0,0,129,122,253,4,239,
271 255,15,133,244,250,139,42,248,1,57,193,15,131,244,71,129,124,253,202,252,
272 252,239,15,133,244,249,59,108,202,252,248,15,79,108,202,252,248,131,193,1,
273 252,233,244,1,248,3,15,135,244,63,255,252,233,244,252,248,4,15,135,244,63,
274 255,252,242,15,16,2,248,5,57,193,15,131,244,72,129,124,253,202,252,252,239,
275 255,15,130,244,252,15,135,244,63,252,242,15,42,76,202,252,248,252,233,244,
276 253,255,248,6,252,242,15,16,76,202,252,248,248,7,252,242,15,93,193,131,193,
277 1,252,233,244,5,255,221,2,248,5,57,193,15,131,244,73,129,124,253,202,252,
278 252,239,255,15,130,244,252,15,135,244,255,219,68,202,252,248,252,233,244,
279 253,255,15,131,244,255,255,248,6,221,68,202,252,248,248,7,255,219,252,233,
280 219,209,221,217,255,80,221,225,223,224,252,246,196,1,15,132,244,248,217,201,
281 248,2,221,216,88,255,248,119,185,2,0,0,0,129,122,253,4,239,255,15,133,244,
282 250,139,42,248,1,57,193,15,131,244,71,129,124,253,202,252,252,239,15,133,
283 244,249,59,108,202,252,248,15,76,108,202,252,248,131,193,1,252,233,244,1,
284 248,3,15,135,244,63,255,248,6,252,242,15,16,76,202,252,248,248,7,252,242,
285 15,95,193,131,193,1,252,233,244,5,255,219,252,233,218,209,221,217,255,80,
286 221,225,223,224,252,246,196,1,15,133,244,248,217,201,248,2,221,216,88,255,
287 248,9,221,216,252,233,244,63,255,248,120,129,252,248,239,15,130,244,63,129,
288 122,253,4,239,15,133,244,63,139,42,255,139,173,233,252,233,244,71,255,252,
289 242,15,42,133,233,252,233,244,72,255,219,133,233,252,233,244,73,255,248,121,
290 129,252,248,239,15,133,244,63,129,122,253,4,239,15,133,244,63,139,42,139,
291 114,252,252,131,189,233,1,15,130,244,81,15,182,173,233,255,252,242,15,42,
292 197,252,233,244,72,255,137,108,36,16,219,68,36,16,252,233,244,73,255,248,
293 122,139,171,233,59,171,233,15,130,244,247,232,244,75,248,1,129,252,248,239,
294 15,133,244,63,129,122,253,4,239,255,15,133,244,63,139,42,129,252,253,252,
295 255,0,0,0,15,135,244,63,137,108,36,20,255,15,131,244,63,252,242,15,44,42,
296 129,252,253,252,255,0,0,0,15,135,244,63,137,108,36,20,255,15,131,244,63,221,
297 2,219,92,36,20,129,124,36,20,252,255,0,0,0,15,135,244,63,255,199,68,36,8,
298 1,0,0,0,141,68,36,20,248,123,139,108,36,48,137,149,233,137,68,36,4,137,44,
299 36,137,116,36,24,232,251,1,19,139,149,233,139,114,252,252,199,66,252,252,
300 237,137,66,252,248,252,233,244,66,248,124,139,171,233,59,171,233,15,130,244,
301 247,232,244,75,248,1,199,68,36,20,252,255,252,255,252,255,252,255,129,252,
302 248,239,15,130,244,63,15,134,244,247,129,122,253,20,239,255,15,133,244,63,
303 139,106,16,137,108,36,20,255,15,131,244,63,252,242,15,44,106,16,137,108,36,
304 20,255,15,131,244,63,221,66,16,219,92,36,20,255,248,1,129,122,253,4,239,15,
305 133,244,63,129,122,253,12,239,255,139,42,137,108,36,12,139,173,233,255,139,
306 74,8,255,252,242,15,44,74,8,255,221,66,8,219,92,36,8,139,76,36,8,255,139,
307 68,36,20,57,197,15,130,244,251,248,2,133,201,15,142,244,253,248,3,139,108,
308 36,12,41,200,15,140,244,125,141,172,253,13,233,131,192,1,248,4,137,68,36,
309 8,137,232,252,233,244,123,248,5,15,140,244,252,141,68,40,1,252,233,244,2,
310 248,6,137,232,252,233,244,2,248,7,255,15,132,244,254,1,252,233,131,193,1,
311 15,143,244,3,248,8,185,1,0,0,0,252,233,244,3,248,125,49,192,252,233,244,4,
312 248,126,129,252,248,239,15,130,244,63,139,171,233,59,171,233,15,130,244,247,
313 232,244,75,248,1,255,129,122,253,4,239,15,133,244,63,129,122,253,12,239,139,
314 42,255,15,133,244,63,139,66,8,255,15,131,244,63,252,242,15,44,66,8,255,15,
315 131,244,63,221,66,8,219,92,36,20,139,68,36,20,255,133,192,15,142,244,125,
316 131,189,233,1,15,130,244,125,15,133,244,127,57,131,233,15,130,244,127,15,
317 182,141,233,139,171,233,137,68,36,8,248,1,136,77,0,131,197,1,131,232,1,15,
318 133,244,1,139,131,233,252,233,244,123,248,128,129,252,248,239,255,15,130,
319 244,63,139,171,233,59,171,233,15,130,244,247,232,244,75,248,1,129,122,253,
320 4,239,15,133,244,63,139,42,139,133,233,133,192,15,132,244,125,57,131,233,
321 15,130,244,129,129,197,239,137,116,36,20,137,68,36,8,139,179,233,248,1,255,
322 15,182,77,0,131,197,1,131,232,1,136,12,6,15,133,244,1,137,252,240,139,116,
323 36,20,252,233,244,123,248,130,129,252,248,239,15,130,244,63,139,171,233,59,
324 171,233,15,130,244,247,232,244,75,248,1,129,122,253,4,239,15,133,244,63,139,
325 42,139,133,233,57,131,233,255,15,130,244,129,129,197,239,137,116,36,20,137,
326 68,36,8,139,179,233,252,233,244,249,248,1,15,182,76,5,0,131,252,249,65,15,
327 130,244,248,131,252,249,90,15,135,244,248,131,252,241,32,248,2,136,12,6,248,
328 3,131,232,1,15,137,244,1,137,252,240,139,116,36,20,252,233,244,123,248,131,
329 129,252,248,239,15,130,244,63,255,139,171,233,59,171,233,15,130,244,247,232,
330 244,75,248,1,129,122,253,4,239,15,133,244,63,139,42,139,133,233,57,131,233,
331 15,130,244,129,129,197,239,137,116,36,20,137,68,36,8,139,179,233,252,233,
332 244,249,248,1,15,182,76,5,0,131,252,249,97,15,130,244,248,255,131,252,249,
333 122,15,135,244,248,131,252,241,32,248,2,136,12,6,248,3,131,232,1,15,137,244,
334 1,137,252,240,139,116,36,20,252,233,244,123,248,132,129,252,248,239,15,130,
335 244,63,129,122,253,4,239,15,133,244,63,137,213,139,10,232,251,1,20,137,252,
336 234,255,137,197,252,233,244,71,255,252,242,15,42,192,252,233,244,72,255,137,
337 4,36,219,4,36,252,233,244,73,255,248,133,129,252,248,239,15,130,244,63,129,
338 122,253,4,239,255,15,133,244,247,139,42,252,233,244,89,248,1,15,135,244,63,
339 255,252,242,15,16,2,189,0,0,56,67,102,15,110,205,102,15,112,201,81,252,242,
340 15,88,193,102,15,126,197,255,221,2,199,68,36,16,0,0,192,89,216,68,36,16,221,
341 28,36,255,139,44,36,255,252,233,244,89,255,248,134,129,252,248,239,15,130,
342 244,63,255,189,0,0,56,67,102,15,110,205,102,15,112,201,81,255,199,68,36,16,
343 0,0,192,89,255,15,133,244,247,139,42,252,233,244,248,248,1,15,135,244,63,
344 255,252,242,15,16,2,252,242,15,88,193,102,15,126,197,255,221,2,216,68,36,
345 16,221,28,36,139,44,36,255,248,2,137,68,36,20,141,68,194,252,240,248,1,57,
346 208,15,134,244,89,129,120,253,4,239,255,15,133,244,248,35,40,131,232,8,252,
347 233,244,1,248,2,15,135,244,135,255,15,131,244,135,255,252,242,15,16,0,252,
348 242,15,88,193,102,15,126,193,33,205,255,221,0,216,68,36,16,221,28,36,35,44,
349 36,255,131,232,8,252,233,244,1,248,136,129,252,248,239,15,130,244,63,255,
350 15,133,244,248,11,40,131,232,8,252,233,244,1,248,2,15,135,244,135,255,252,
351 242,15,16,0,252,242,15,88,193,102,15,126,193,9,205,255,221,0,216,68,36,16,
352 221,28,36,11,44,36,255,131,232,8,252,233,244,1,248,137,129,252,248,239,15,
353 130,244,63,255,15,133,244,248,51,40,131,232,8,252,233,244,1,248,2,15,135,
354 244,135,255,252,242,15,16,0,252,242,15,88,193,102,15,126,193,49,205,255,221,
355 0,216,68,36,16,221,28,36,51,44,36,255,131,232,8,252,233,244,1,248,138,129,
356 252,248,239,15,130,244,63,129,122,253,4,239,255,221,2,199,68,36,16,0,0,192,
357 89,216,68,36,16,221,28,36,139,44,36,255,248,2,15,205,252,233,244,89,248,139,
358 129,252,248,239,15,130,244,63,129,122,253,4,239,255,248,2,252,247,213,255,
359 248,89,252,242,15,42,197,252,233,244,72,255,248,89,137,44,36,219,4,36,252,
360 233,244,73,255,248,135,139,68,36,20,252,233,244,63,255,248,140,129,252,248,
361 239,15,130,244,63,129,122,253,4,239,255,248,2,129,122,253,12,239,15,133,244,
362 63,139,74,8,255,248,140,129,252,248,239,15,130,244,63,129,122,253,4,239,15,
363 131,244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,15,16,
364 74,8,189,0,0,56,67,102,15,110,213,102,15,112,210,81,252,242,15,88,194,252,
365 242,15,88,202,102,15,126,197,102,15,126,201,255,248,140,129,252,248,239,15,
366 130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
367 63,221,2,221,66,8,199,68,36,16,0,0,192,89,216,68,36,16,221,92,36,8,216,68,
368 36,16,221,28,36,139,76,36,8,139,44,36,255,211,229,252,233,244,89,255,248,
369 141,129,252,248,239,15,130,244,63,129,122,253,4,239,255,248,141,129,252,248,
370 239,15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,
371 244,63,252,242,15,16,2,252,242,15,16,74,8,189,0,0,56,67,102,15,110,213,102,
372 15,112,210,81,252,242,15,88,194,252,242,15,88,202,102,15,126,197,102,15,126,
373 201,255,248,141,129,252,248,239,15,130,244,63,129,122,253,4,239,15,131,244,
374 63,129,122,253,12,239,15,131,244,63,221,2,221,66,8,199,68,36,16,0,0,192,89,
375 216,68,36,16,221,92,36,8,216,68,36,16,221,28,36,139,76,36,8,139,44,36,255,
376 211,252,237,252,233,244,89,255,248,142,129,252,248,239,15,130,244,63,129,
377 122,253,4,239,255,248,142,129,252,248,239,15,130,244,63,129,122,253,4,239,
378 15,131,244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,15,
379 16,74,8,189,0,0,56,67,102,15,110,213,102,15,112,210,81,252,242,15,88,194,
380 252,242,15,88,202,102,15,126,197,102,15,126,201,255,248,142,129,252,248,239,
381 15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
382 63,221,2,221,66,8,199,68,36,16,0,0,192,89,216,68,36,16,221,92,36,8,216,68,
383 36,16,221,28,36,139,76,36,8,139,44,36,255,211,252,253,252,233,244,89,255,
384 248,143,129,252,248,239,15,130,244,63,129,122,253,4,239,255,248,143,129,252,
385 248,239,15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,
386 15,131,244,63,252,242,15,16,2,252,242,15,16,74,8,189,0,0,56,67,102,15,110,
387 213,102,15,112,210,81,252,242,15,88,194,252,242,15,88,202,102,15,126,197,
388 102,15,126,201,255,248,143,129,252,248,239,15,130,244,63,129,122,253,4,239,
389 15,131,244,63,129,122,253,12,239,15,131,244,63,221,2,221,66,8,199,68,36,16,
390 0,0,192,89,216,68,36,16,221,92,36,8,216,68,36,16,221,28,36,139,76,36,8,139,
391 44,36,255,211,197,252,233,244,89,255,248,144,129,252,248,239,15,130,244,63,
392 129,122,253,4,239,255,248,144,129,252,248,239,15,130,244,63,129,122,253,4,
393 239,15,131,244,63,129,122,253,12,239,15,131,244,63,252,242,15,16,2,252,242,
394 15,16,74,8,189,0,0,56,67,102,15,110,213,102,15,112,210,81,252,242,15,88,194,
395 252,242,15,88,202,102,15,126,197,102,15,126,201,255,248,144,129,252,248,239,
396 15,130,244,63,129,122,253,4,239,15,131,244,63,129,122,253,12,239,15,131,244,
397 63,221,2,221,66,8,199,68,36,16,0,0,192,89,216,68,36,16,221,92,36,8,216,68,
398 36,16,221,28,36,139,76,36,8,139,44,36,255,211,205,252,233,244,89,248,127,
399 184,237,252,233,244,63,248,129,184,237,248,63,139,108,36,48,139,114,252,252,
400 137,116,36,24,137,149,233,141,68,194,252,248,141,136,233,137,133,233,139,
401 66,252,248,59,141,233,15,135,244,251,137,44,36,252,255,144,233,139,149,233,
402 133,192,15,143,244,78,248,1,255,139,141,233,41,209,193,252,233,3,133,192,
403 141,65,1,139,106,252,248,15,133,244,33,139,181,233,139,14,15,182,252,233,
404 15,182,205,131,198,4,252,255,36,171,248,33,137,209,252,247,198,237,15,133,
405 244,249,15,182,110,252,253,252,247,213,141,20,252,234,252,233,244,28,248,
406 3,137,252,245,131,229,252,248,41,252,234,252,233,244,28,248,5,186,237,137,
407 252,233,232,251,1,0,139,149,233,49,192,252,233,244,1,248,75,93,137,108,36,
408 16,139,108,36,48,137,116,36,24,137,149,233,255,141,68,194,252,248,137,252,
409 233,137,133,233,232,251,1,21,139,149,233,139,133,233,41,208,193,232,3,131,
410 192,1,139,108,36,16,85,195,248,145,255,15,182,131,233,168,235,15,133,244,
411 251,168,235,15,133,244,247,168,235,15,132,244,247,252,255,139,233,252,233,
412 244,247,255,248,146,15,182,131,233,168,235,15,133,244,251,252,233,244,247,
413 248,147,15,182,131,233,168,235,15,133,244,251,168,235,15,132,244,251,252,
414 255,139,233,15,132,244,247,168,235,15,132,244,251,248,1,255,139,108,36,48,
415 137,149,233,137,252,242,137,252,233,232,251,1,22,248,3,139,149,233,248,4,
416 15,182,78,252,253,248,5,15,182,110,252,252,15,183,70,252,254,252,255,164,
417 253,171,233,248,148,131,198,4,139,77,232,137,76,36,20,252,233,244,4,248,149,
418 255,139,106,252,248,139,173,233,15,182,133,233,141,4,194,139,108,36,48,137,
419 149,233,137,133,233,137,252,242,141,139,233,137,171,233,137,116,36,24,232,
420 251,1,23,252,233,244,3,255,248,150,137,116,36,24,255,248,151,255,137,116,
421 36,24,131,206,1,248,1,255,141,68,194,252,248,139,108,36,48,137,149,233,137,
422 133,233,137,252,242,137,252,233,232,251,1,24,199,68,36,24,0,0,0,0,255,131,
423 230,252,254,255,139,149,233,137,193,139,133,233,41,208,137,205,15,182,78,
424 252,253,193,232,3,131,192,1,252,255,229,248,152,255,85,141,108,36,12,85,83,
425 82,81,80,15,182,69,252,252,138,101,252,248,137,125,252,252,137,117,252,248,
426 139,93,0,139,139,233,199,131,233,237,137,131,233,137,139,233,129,252,236,
427 239,252,242,15,17,125,216,252,242,15,17,117,208,252,242,15,17,109,200,252,
428 242,15,17,101,192,252,242,15,17,93,184,252,242,15,17,85,176,252,242,15,17,
429 77,168,252,242,15,17,69,160,139,171,233,139,147,233,137,171,233,199,131,233,
430 0,0,0,0,137,149,233,141,84,36,16,141,139,233,232,251,1,25,139,141,233,129,
431 225,239,137,204,137,169,233,139,149,233,139,177,233,255,248,153,255,133,192,
432 15,136,244,249,137,68,36,20,139,122,252,248,139,191,233,139,191,233,199,131,
433 233,0,0,0,0,199,131,233,237,139,6,15,182,204,15,182,232,131,198,4,193,232,
434 16,129,252,253,239,15,130,244,248,139,68,36,20,248,2,252,255,36,171,248,3,
435 252,247,216,137,252,233,137,194,232,251,1,26,255,248,91,255,217,124,36,4,
436 137,68,36,8,102,184,0,4,102,11,68,36,4,102,37,252,255,252,247,102,137,68,
437 36,6,217,108,36,6,217,252,252,217,108,36,4,139,68,36,8,195,255,248,154,102,
438 15,252,239,210,102,15,118,210,102,15,115,210,1,184,0,0,48,67,102,15,110,216,
439 102,15,112,219,81,15,40,200,102,15,84,202,102,15,46,217,15,134,244,247,102,
440 15,85,208,252,242,15,88,203,252,242,15,92,203,102,15,86,202,184,0,0,252,240,
441 63,102,15,110,208,102,15,112,210,81,252,242,15,194,193,1,102,15,84,194,252,
442 242,15,92,200,15,40,193,248,1,195,248,93,255,217,124,36,4,137,68,36,8,102,
443 184,0,8,102,11,68,36,4,102,37,252,255,252,251,102,137,68,36,6,217,108,36,
444 6,217,252,252,217,108,36,4,139,68,36,8,195,255,248,155,102,15,252,239,210,
445 102,15,118,210,102,15,115,210,1,184,0,0,48,67,102,15,110,216,102,15,112,219,
446 81,15,40,200,102,15,84,202,102,15,46,217,15,134,244,247,102,15,85,208,252,
447 242,15,88,203,252,242,15,92,203,102,15,86,202,184,0,0,252,240,191,102,15,
448 110,208,102,15,112,210,81,252,242,15,194,193,6,102,15,84,194,252,242,15,92,
449 200,15,40,193,248,1,195,248,114,255,217,124,36,4,137,68,36,8,102,184,0,12,
450 102,11,68,36,4,102,137,68,36,6,217,108,36,6,217,252,252,217,108,36,4,139,
451 68,36,8,195,255,248,156,102,15,252,239,210,102,15,118,210,102,15,115,210,
452 1,184,0,0,48,67,102,15,110,216,102,15,112,219,81,15,40,200,102,15,84,202,
453 102,15,46,217,15,134,244,247,102,15,85,208,15,40,193,252,242,15,88,203,252,
454 242,15,92,203,184,0,0,252,240,63,102,15,110,216,102,15,112,219,81,252,242,
455 15,194,193,1,102,15,84,195,252,242,15,92,200,102,15,86,202,15,40,193,248,
456 1,195,248,157,255,15,40,232,252,242,15,94,193,102,15,252,239,210,102,15,118,
457 210,102,15,115,210,1,184,0,0,48,67,102,15,110,216,102,15,112,219,81,15,40,
458 224,102,15,84,226,102,15,46,220,15,134,244,247,102,15,85,208,252,242,15,88,
459 227,252,242,15,92,227,102,15,86,226,184,0,0,252,240,63,102,15,110,208,102,
460 15,112,210,81,252,242,15,194,196,1,102,15,84,194,252,242,15,92,224,15,40,
461 197,252,242,15,89,204,252,242,15,92,193,195,248,1,252,242,15,89,200,15,40,
462 197,252,242,15,92,193,195,255,217,193,216,252,241,217,124,36,4,102,184,0,
463 4,102,11,68,36,4,102,37,252,255,252,247,102,137,68,36,6,217,108,36,6,217,
464 252,252,217,108,36,4,222,201,222,252,233,195,255,248,98,217,252,234,222,201,
465 248,158,217,84,36,4,129,124,36,4,0,0,128,127,15,132,244,247,129,124,36,4,
466 0,0,128,252,255,15,132,244,248,248,159,217,192,217,252,252,220,252,233,217,
467 201,217,252,240,217,232,222,193,217,252,253,221,217,248,1,195,248,2,221,216,
468 217,252,238,195,255,248,117,219,84,36,4,219,68,36,4,255,223,252,233,255,221,
469 252,233,223,224,158,255,15,133,244,254,15,138,244,255,221,216,139,68,36,4,
470 131,252,248,1,15,142,244,252,248,1,169,1,0,0,0,15,133,244,248,216,200,209,
471 232,252,233,244,1,248,2,209,232,15,132,244,251,217,192,248,3,216,200,209,
472 232,15,132,244,250,15,131,244,3,220,201,252,233,244,3,248,4,255,222,201,248,
473 5,195,248,6,15,132,244,5,15,130,244,253,217,232,222,252,241,252,247,216,131,
474 252,248,1,15,132,244,5,252,233,244,1,248,7,221,216,217,232,195,248,8,217,
475 84,36,4,217,201,217,84,36,8,139,68,36,4,209,224,61,0,0,0,252,255,15,132,244,
476 248,139,68,36,8,209,224,15,132,244,250,61,0,0,0,252,255,15,132,244,250,217,
477 252,241,252,233,244,159,248,9,255,217,232,255,223,252,234,255,221,252,234,
478 223,224,158,255,15,132,244,247,217,201,248,1,221,216,195,248,2,217,225,217,
479 232,255,15,132,244,249,221,216,217,225,217,252,238,184,0,0,0,0,15,146,208,
480 209,200,51,68,36,4,15,137,244,249,217,201,248,3,221,217,217,225,195,248,4,
481 131,124,36,4,0,15,141,244,3,221,216,221,216,133,192,15,132,244,251,217,252,
482 238,195,248,5,199,68,36,4,0,0,128,127,217,68,36,4,195,255,248,117,255,248,
483 160,252,242,15,45,193,252,242,15,42,208,102,15,46,202,15,133,244,254,15,138,
484 244,255,248,161,131,252,248,1,15,142,244,252,248,1,169,1,0,0,0,15,133,244,
485 248,252,242,15,89,192,209,232,252,233,244,1,248,2,209,232,15,132,244,251,
486 15,40,200,248,3,252,242,15,89,192,209,232,15,132,244,250,15,131,244,3,255,
487 252,242,15,89,200,252,233,244,3,248,4,252,242,15,89,193,248,5,195,248,6,15,
488 132,244,5,15,130,244,253,252,247,216,232,244,1,184,0,0,252,240,63,102,15,
489 110,200,102,15,112,201,81,252,242,15,94,200,15,40,193,195,248,7,184,0,0,252,
490 240,63,102,15,110,192,102,15,112,192,81,195,248,8,252,242,15,17,76,36,12,
491 252,242,15,17,68,36,4,131,124,36,12,0,15,133,244,247,139,68,36,16,209,224,
492 61,0,0,224,252,255,15,132,244,248,248,1,131,124,36,4,0,15,133,244,247,255,
493 139,68,36,8,209,224,15,132,244,250,61,0,0,224,252,255,15,132,244,251,248,
494 1,221,68,36,12,221,68,36,4,217,252,241,217,192,217,252,252,220,252,233,217,
495 201,217,252,240,217,232,222,193,217,252,253,221,217,221,92,36,4,252,242,15,
496 16,68,36,4,195,248,9,184,0,0,252,240,63,102,15,110,208,102,15,112,210,81,
497 102,15,46,194,15,132,244,247,15,40,193,248,1,195,248,2,102,15,252,239,210,
498 102,15,118,210,102,15,115,210,1,102,15,84,194,184,0,0,252,240,63,102,15,110,
499 208,102,15,112,210,81,102,15,46,194,15,132,244,1,102,15,80,193,15,87,192,
500 136,196,15,146,208,48,224,15,133,244,1,248,3,184,0,0,252,240,127,102,15,110,
501 192,102,15,112,192,81,195,248,4,102,15,80,193,133,192,15,133,244,3,15,87,
502 192,195,248,5,102,15,80,193,133,192,15,132,244,3,255,15,87,192,195,248,162,
503 255,139,68,36,12,252,242,15,16,68,36,4,131,252,248,1,15,132,244,247,15,135,
504 244,248,232,244,91,252,233,244,253,248,1,232,244,93,252,233,244,253,248,2,
505 131,252,248,3,15,132,244,247,15,135,244,248,232,244,114,255,252,233,244,253,
506 248,1,252,242,15,81,192,248,7,252,242,15,17,68,36,4,221,68,36,4,195,248,2,
507 221,68,36,4,131,252,248,5,15,130,244,98,15,132,244,158,248,2,131,252,248,
508 7,15,132,244,247,15,135,244,248,217,252,237,217,201,217,252,241,195,248,1,
509 217,232,217,201,217,252,241,195,248,2,131,252,248,9,15,132,244,247,15,135,
510 244,248,255,217,252,236,217,201,217,252,241,195,248,1,217,252,254,195,248,
511 2,131,252,248,11,15,132,244,247,15,135,244,255,217,252,255,195,248,1,217,
512 252,242,221,216,195,255,139,68,36,12,221,68,36,4,131,252,248,1,15,130,244,
513 91,15,132,244,93,131,252,248,3,15,130,244,114,15,135,244,248,217,252,250,
514 195,248,2,131,252,248,5,15,130,244,98,15,132,244,158,131,252,248,7,15,132,
515 244,247,15,135,244,248,217,252,237,217,201,217,252,241,195,248,1,217,232,
516 217,201,217,252,241,195,248,2,131,252,248,9,15,132,244,247,255,15,135,244,
517 248,217,252,236,217,201,217,252,241,195,248,1,217,252,254,195,248,2,131,252,
518 248,11,15,132,244,247,15,135,244,255,217,252,255,195,248,1,217,252,242,221,
519 216,195,255,248,9,204,255,248,163,255,139,68,36,20,252,242,15,16,68,36,4,
520 252,242,15,16,76,36,12,131,252,248,1,15,132,244,247,15,135,244,248,252,242,
521 15,88,193,248,7,252,242,15,17,68,36,4,221,68,36,4,195,248,1,252,242,15,92,
522 193,252,233,244,7,248,2,131,252,248,3,15,132,244,247,15,135,244,248,252,242,
523 15,89,193,252,233,244,7,248,1,252,242,15,94,193,252,233,244,7,248,2,131,252,
524 248,5,15,132,244,247,255,15,135,244,248,232,244,157,252,233,244,7,248,1,90,
525 232,244,117,82,252,233,244,7,248,2,131,252,248,7,15,132,244,247,15,135,244,
526 248,184,0,0,0,128,102,15,110,200,102,15,112,201,81,15,87,193,252,233,244,
527 7,248,1,102,15,252,239,201,102,15,118,201,102,15,115,209,1,15,84,193,252,
528 233,244,7,248,2,255,131,252,248,9,15,135,244,248,221,68,36,4,221,68,36,12,
529 15,132,244,247,217,252,243,195,248,1,217,201,217,252,253,221,217,195,248,
530 2,131,252,248,11,15,132,244,247,15,135,244,255,252,242,15,93,193,252,233,
531 244,7,248,1,252,242,15,95,193,252,233,244,7,248,9,204,255,139,68,36,20,221,
532 68,36,4,221,68,36,12,131,252,248,1,15,132,244,247,15,135,244,248,222,193,
533 195,248,1,222,252,233,195,248,2,131,252,248,3,15,132,244,247,15,135,244,248,
534 222,201,195,248,1,222,252,249,195,248,2,131,252,248,5,15,130,244,157,15,132,
535 244,117,131,252,248,7,15,132,244,247,15,135,244,248,255,221,216,217,224,195,
536 248,1,221,216,217,225,195,248,2,131,252,248,9,15,132,244,247,15,135,244,248,
537 217,252,243,195,248,1,217,201,217,252,253,221,217,195,248,2,131,252,248,11,
538 15,132,244,247,15,135,244,255,255,219,252,233,219,209,221,217,195,248,1,219,
539 252,233,218,209,221,217,195,255,221,225,223,224,252,246,196,1,15,132,244,
540 248,217,201,248,2,221,216,195,248,1,221,225,223,224,252,246,196,1,15,133,
541 244,248,217,201,248,2,221,216,195,255,248,164,156,90,137,209,129,252,242,
542 0,0,32,0,82,157,156,90,49,192,57,209,15,132,244,247,139,68,36,4,87,83,15,
543 162,139,124,36,16,137,7,137,95,4,137,79,8,137,87,12,91,95,248,1,195,248,165,
544 255,204,248,166,255,131,252,236,16,87,86,83,131,252,236,28,141,157,233,139,
545 181,233,15,183,192,137,134,233,141,132,253,36,233,137,142,233,137,150,233,
546 137,134,233,139,140,253,36,233,139,148,253,36,233,137,76,36,44,137,84,36,
547 40,137,226,137,116,36,24,137,252,241,232,251,1,27,199,131,233,237,139,144,
548 233,139,128,233,41,208,139,106,252,248,193,232,3,131,192,1,139,181,233,139,
549 14,15,182,252,233,15,182,205,131,198,4,252,255,36,171,255,248,32,255,139,
550 76,36,48,139,179,233,137,142,233,137,145,233,137,169,233,137,252,241,137,
551 194,232,251,1,28,139,108,36,48,139,134,233,139,150,233,131,190,233,1,15,130,
552 244,253,15,132,244,252,221,134,233,252,233,244,253,248,6,217,134,233,248,
553 7,139,141,233,15,183,73,6,137,76,36,48,131,196,28,91,94,95,93,89,3,36,36,
554 131,196,16,81,195,255,248,167,255,85,137,229,83,137,203,43,163,233,255,137,
555 163,233,255,15,182,139,233,131,252,233,1,15,136,244,248,248,1,139,132,253,
556 139,233,137,4,140,131,252,233,1,15,137,244,1,248,2,139,139,233,139,147,233,
557 252,255,147,233,137,131,233,137,147,233,128,187,233,1,15,130,244,253,15,132,
558 244,252,221,155,233,252,233,244,253,248,6,255,217,155,233,248,7,255,41,163,
559 233,255,139,93,252,252,201,195,255,249,255,129,124,253,202,4,239,15,133,244,
560 253,129,124,253,194,4,239,15,133,244,254,139,44,202,131,198,4,59,44,194,255,
561 15,141,244,255,255,15,140,244,255,255,15,143,244,255,255,15,142,244,255,255,
562 248,6,15,183,70,252,254,141,180,253,134,233,248,9,139,6,15,182,204,15,182,
563 232,131,198,4,193,232,16,252,255,36,171,248,7,15,135,244,44,129,124,253,194,
564 4,239,15,130,244,247,15,133,244,44,255,252,242,15,42,4,194,252,233,244,248,
565 255,221,4,202,219,4,194,252,233,244,249,255,248,8,15,135,244,44,255,252,242,
566 15,42,12,202,252,242,15,16,4,194,131,198,4,102,15,46,193,255,15,134,244,9,
567 255,15,135,244,9,255,15,130,244,9,255,15,131,244,9,255,252,233,244,6,255,
568 219,4,202,252,233,244,248,255,129,124,253,202,4,239,15,131,244,44,129,124,
569 253,194,4,239,15,131,244,44,255,248,1,252,242,15,16,4,194,248,2,131,198,4,
570 102,15,46,4,202,248,3,255,248,1,221,4,202,248,2,221,4,194,248,3,131,198,4,
571 255,15,135,244,247,255,15,130,244,247,255,15,131,244,247,255,15,183,70,252,
572 254,141,180,253,134,233,248,1,139,6,15,182,204,15,182,232,131,198,4,193,232,
573 16,252,255,36,171,255,139,108,194,4,131,198,4,255,129,252,253,239,15,133,
574 244,253,129,124,253,202,4,239,15,133,244,254,139,44,194,59,44,202,255,15,
575 133,244,255,255,15,132,244,255,255,15,183,70,252,254,141,180,253,134,233,
576 248,9,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,
577 7,15,135,244,251,129,124,253,202,4,239,15,130,244,247,15,133,244,251,255,
578 252,242,15,42,4,202,255,219,4,202,255,252,233,244,248,248,8,15,135,244,251,
579 255,252,242,15,42,4,194,102,15,46,4,202,255,219,4,194,221,4,202,255,252,233,
580 244,250,255,129,252,253,239,15,131,244,251,129,124,253,202,4,239,15,131,244,
581 251,255,248,1,252,242,15,16,4,202,248,2,102,15,46,4,194,248,4,255,248,1,221,
582 4,202,248,2,221,4,194,248,4,255,15,138,244,248,15,133,244,248,255,15,138,
583 244,248,15,132,244,247,255,248,1,15,183,70,252,254,141,180,253,134,233,248,
584 2,255,248,2,15,183,70,252,254,141,180,253,134,233,248,1,255,252,233,244,9,
585 255,248,5,255,129,252,253,239,15,132,244,49,129,124,253,202,4,239,15,132,
586 244,49,255,57,108,202,4,15,133,244,2,129,252,253,239,15,131,244,1,139,12,
587 202,139,4,194,57,193,15,132,244,1,129,252,253,239,15,135,244,2,139,169,233,
588 133,252,237,15,132,244,2,252,246,133,233,235,15,133,244,2,255,49,252,237,
589 255,189,1,0,0,0,255,252,233,244,48,255,248,3,129,252,253,239,255,15,133,244,
590 9,255,252,233,244,49,255,252,247,208,139,108,202,4,131,198,4,129,252,253,
591 239,15,133,244,249,139,12,202,59,12,135,255,139,108,202,4,131,198,4,255,129,
592 252,253,239,15,133,244,253,129,124,253,199,4,239,15,133,244,254,139,44,199,
593 59,44,202,255,15,183,70,252,254,141,180,253,134,233,248,9,139,6,15,182,204,
594 15,182,232,131,198,4,193,232,16,252,255,36,171,248,7,15,135,244,249,129,124,
595 253,199,4,239,15,130,244,247,255,252,242,15,42,4,199,255,219,4,199,255,252,
596 233,244,248,248,8,255,252,242,15,42,4,202,102,15,46,4,199,255,219,4,202,221,
597 4,199,255,129,252,253,239,15,131,244,249,255,248,1,252,242,15,16,4,199,248,
598 2,102,15,46,4,202,248,4,255,248,1,221,4,199,248,2,221,4,202,248,4,255,252,
599 247,208,139,108,202,4,131,198,4,57,197,255,15,133,244,249,15,183,70,252,254,
600 141,180,253,134,233,248,2,139,6,15,182,204,15,182,232,131,198,4,193,232,16,
601 252,255,36,171,248,3,129,252,253,239,15,133,244,2,252,233,244,49,255,15,132,
602 244,248,129,252,253,239,15,132,244,49,15,183,70,252,254,141,180,253,134,233,
603 248,2,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,255,
604 139,108,194,4,131,198,4,129,252,253,239,255,137,108,202,4,139,44,194,137,
605 44,202,255,139,108,194,4,139,4,194,137,108,202,4,137,4,202,139,6,15,182,204,
606 15,182,232,131,198,4,193,232,16,252,255,36,171,255,49,252,237,129,124,253,
607 194,4,239,129,213,239,137,108,202,4,139,6,15,182,204,15,182,232,131,198,4,
608 193,232,16,252,255,36,171,255,129,124,253,194,4,239,15,133,244,251,139,44,
609 194,252,247,221,15,128,244,250,199,68,202,4,237,137,44,202,248,9,139,6,15,
610 182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,4,199,68,202,4,
611 0,0,224,65,199,4,202,0,0,0,0,252,233,244,9,248,5,15,135,244,54,255,129,124,
612 253,194,4,239,15,131,244,54,255,252,242,15,16,4,194,184,0,0,0,128,102,15,
613 110,200,102,15,112,201,81,15,87,193,252,242,15,17,4,202,255,221,4,194,217,
614 224,221,28,202,255,129,124,253,194,4,239,15,133,244,248,139,4,194,255,139,
615 128,233,248,1,199,68,202,4,237,137,4,202,255,15,87,192,252,242,15,42,128,
616 233,248,1,252,242,15,17,4,202,255,219,128,233,248,1,221,28,202,255,139,6,
617 15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,2,129,124,253,
618 194,4,239,15,133,244,57,139,12,194,255,139,169,233,131,252,253,0,15,133,244,
619 255,248,3,255,248,58,137,213,232,251,1,20,255,252,242,15,42,192,255,137,4,
620 36,219,4,36,255,137,252,234,15,182,78,252,253,252,233,244,1,255,248,9,252,
621 246,133,233,235,15,133,244,3,252,233,244,57,255,15,182,252,236,15,182,192,
622 255,129,124,253,252,234,4,239,15,133,244,51,129,124,253,199,4,239,15,133,
623 244,51,139,44,252,234,3,44,199,15,128,244,50,255,129,124,253,252,234,4,239,
624 15,133,244,53,129,124,253,199,4,239,15,133,244,53,139,4,199,3,4,252,234,15,
625 128,244,52,255,129,124,253,252,234,4,239,15,133,244,56,129,124,253,194,4,
626 239,15,133,244,56,139,44,252,234,3,44,194,15,128,244,55,255,199,68,202,4,
627 237,255,129,124,253,252,234,4,239,15,131,244,51,255,129,124,253,199,4,239,
628 15,131,244,51,255,252,242,15,16,4,252,234,252,242,15,88,4,199,255,221,4,252,
629 234,220,4,199,255,129,124,253,252,234,4,239,15,131,244,53,255,129,124,253,
630 199,4,239,15,131,244,53,255,252,242,15,16,4,199,252,242,15,88,4,252,234,255,
631 221,4,199,220,4,252,234,255,129,124,253,252,234,4,239,15,131,244,56,129,124,
632 253,194,4,239,15,131,244,56,255,252,242,15,16,4,252,234,252,242,15,88,4,194,
633 255,221,4,252,234,220,4,194,255,129,124,253,252,234,4,239,15,133,244,51,129,
634 124,253,199,4,239,15,133,244,51,139,44,252,234,43,44,199,15,128,244,50,255,
635 129,124,253,252,234,4,239,15,133,244,53,129,124,253,199,4,239,15,133,244,
636 53,139,4,199,43,4,252,234,15,128,244,52,255,129,124,253,252,234,4,239,15,
637 133,244,56,129,124,253,194,4,239,15,133,244,56,139,44,252,234,43,44,194,15,
638 128,244,55,255,252,242,15,16,4,252,234,252,242,15,92,4,199,255,221,4,252,
639 234,220,36,199,255,252,242,15,16,4,199,252,242,15,92,4,252,234,255,221,4,
640 199,220,36,252,234,255,252,242,15,16,4,252,234,252,242,15,92,4,194,255,221,
641 4,252,234,220,36,194,255,129,124,253,252,234,4,239,15,133,244,51,129,124,
642 253,199,4,239,15,133,244,51,139,44,252,234,15,175,44,199,15,128,244,50,255,
643 129,124,253,252,234,4,239,15,133,244,53,129,124,253,199,4,239,15,133,244,
644 53,139,4,199,15,175,4,252,234,15,128,244,52,255,129,124,253,252,234,4,239,
645 15,133,244,56,129,124,253,194,4,239,15,133,244,56,139,44,252,234,15,175,44,
646 194,15,128,244,55,255,252,242,15,16,4,252,234,252,242,15,89,4,199,255,221,
647 4,252,234,220,12,199,255,252,242,15,16,4,199,252,242,15,89,4,252,234,255,
648 221,4,199,220,12,252,234,255,252,242,15,16,4,252,234,252,242,15,89,4,194,
649 255,221,4,252,234,220,12,194,255,252,242,15,16,4,252,234,252,242,15,94,4,
650 199,255,221,4,252,234,220,52,199,255,252,242,15,16,4,199,252,242,15,94,4,
651 252,234,255,221,4,199,220,52,252,234,255,252,242,15,16,4,252,234,252,242,
652 15,94,4,194,255,221,4,252,234,220,52,194,255,252,242,15,16,4,252,234,252,
653 242,15,16,12,199,255,221,4,252,234,221,4,199,255,252,242,15,16,4,199,252,
654 242,15,16,12,252,234,255,221,4,199,221,4,252,234,255,252,242,15,16,4,252,
655 234,252,242,15,16,12,194,255,221,4,252,234,221,4,194,255,248,168,232,244,
656 157,255,252,233,244,168,255,232,244,117,255,15,182,252,236,15,182,192,141,
657 12,194,41,232,137,76,36,4,137,68,36,8,248,36,139,108,36,48,137,44,36,137,
658 149,233,137,116,36,24,232,251,1,29,139,149,233,133,192,15,133,244,45,15,182,
659 110,252,255,15,182,78,252,253,139,68,252,234,4,139,44,252,234,137,68,202,
660 4,137,44,202,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,
661 171,255,252,247,208,139,4,135,199,68,202,4,237,137,4,202,139,6,15,182,204,
662 15,182,232,131,198,4,193,232,16,252,255,36,171,255,15,191,192,199,68,202,
663 4,237,137,4,202,255,15,191,192,252,242,15,42,192,252,242,15,17,4,202,255,
664 223,70,252,254,221,28,202,255,252,242,15,16,4,199,252,242,15,17,4,202,255,
665 221,4,199,221,28,202,255,252,247,208,137,68,202,4,139,6,15,182,204,15,182,
666 232,131,198,4,193,232,16,252,255,36,171,255,141,76,202,12,141,68,194,4,189,
667 237,137,105,252,248,248,1,137,41,131,193,8,57,193,15,134,244,1,139,6,15,182,
668 204,15,182,232,131,198,4,193,232,16,252,255,36,171,255,139,106,252,248,139,
669 172,253,133,233,139,173,233,139,69,4,139,109,0,137,68,202,4,137,44,202,139,
670 6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,255,139,106,252,
671 248,139,172,253,141,233,128,189,233,0,139,173,233,139,12,194,139,68,194,4,
672 137,77,0,137,69,4,15,132,244,247,252,246,133,233,235,15,133,244,248,248,1,
673 139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,2,129,
674 232,239,129,252,248,239,15,134,244,1,252,246,129,233,235,15,132,244,1,135,
675 213,141,139,233,255,232,251,1,30,137,252,234,252,233,244,1,255,252,247,208,
676 139,106,252,248,139,172,253,141,233,139,12,135,139,133,233,137,8,199,64,4,
677 237,252,246,133,233,235,15,133,244,248,248,1,139,6,15,182,204,15,182,232,
678 131,198,4,193,232,16,252,255,36,171,248,2,252,246,129,233,235,15,132,244,
679 1,128,189,233,0,15,132,244,1,137,213,137,194,141,139,233,232,251,1,30,137,
680 252,234,252,233,244,1,255,139,106,252,248,255,252,242,15,16,4,199,255,139,
681 172,253,141,233,139,141,233,255,252,242,15,17,1,255,221,25,255,252,247,208,
682 139,106,252,248,139,172,253,141,233,139,141,233,137,65,4,139,6,15,182,204,
683 15,182,232,131,198,4,193,232,16,252,255,36,171,255,141,180,253,134,233,139,
684 108,36,48,131,189,233,0,15,132,244,247,137,149,233,141,20,202,137,252,233,
685 232,251,1,31,139,149,233,248,1,139,6,15,182,204,15,182,232,131,198,4,193,
686 232,16,252,255,36,171,255,252,247,208,139,74,252,248,139,4,135,139,108,36,
687 48,137,76,36,8,137,68,36,4,137,44,36,137,149,233,137,116,36,24,232,251,1,
688 32,139,149,233,15,182,78,252,253,137,4,202,199,68,202,4,237,139,6,15,182,
689 204,15,182,232,131,198,4,193,232,16,252,255,36,171,255,139,108,36,48,137,
690 149,233,139,139,233,59,139,233,137,116,36,24,15,131,244,251,248,1,137,193,
691 37,252,255,7,0,0,193,252,233,11,137,76,36,8,61,252,255,7,0,0,15,132,244,249,
692 248,2,137,44,36,137,68,36,4,232,251,1,33,139,149,233,15,182,78,252,253,137,
693 4,202,199,68,202,4,237,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,
694 255,36,171,248,3,184,1,8,0,0,252,233,244,2,248,5,137,252,233,232,251,1,34,
695 15,183,70,252,254,252,233,244,1,255,252,247,208,139,108,36,48,139,139,233,
696 137,116,36,24,59,139,233,137,149,233,15,131,244,249,248,2,139,20,135,137,
697 252,233,232,251,1,35,139,149,233,15,182,78,252,253,137,4,202,199,68,202,4,
698 237,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,3,
699 137,252,233,232,251,1,34,15,183,70,252,254,252,247,208,252,233,244,2,255,
700 252,247,208,139,106,252,248,139,173,233,139,4,135,252,233,244,169,255,252,
701 247,208,139,106,252,248,139,173,233,139,4,135,252,233,244,170,255,15,182,
702 252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,39,139,44,252,234,
703 255,129,124,253,194,4,239,15,133,244,251,139,4,194,255,129,124,253,194,4,
704 239,15,131,244,251,255,252,242,15,16,4,194,252,242,15,45,192,252,242,15,42,
705 200,102,15,46,193,255,221,4,194,219,20,36,219,4,36,255,15,133,244,39,255,
706 59,133,233,15,131,244,39,193,224,3,3,133,233,129,120,253,4,239,15,132,244,
707 248,139,40,139,64,4,137,44,202,137,68,202,4,248,1,139,6,15,182,204,15,182,
708 232,131,198,4,193,232,16,252,255,36,171,248,2,131,189,233,0,15,132,244,249,
709 139,141,233,252,246,129,233,235,15,132,244,39,15,182,78,252,253,248,3,199,
710 68,202,4,237,252,233,244,1,248,5,255,129,124,253,194,4,239,15,133,244,39,
711 139,4,194,252,233,244,169,255,15,182,252,236,15,182,192,252,247,208,139,4,
712 135,129,124,253,252,234,4,239,15,133,244,37,139,44,252,234,248,169,139,141,
713 233,35,136,233,105,201,239,3,141,233,248,1,129,185,233,239,15,133,244,250,
714 57,129,233,15,133,244,250,129,121,253,4,239,15,132,244,251,15,182,70,252,
715 253,139,41,139,73,4,137,44,194,137,76,194,4,248,2,255,139,6,15,182,204,15,
716 182,232,131,198,4,193,232,16,252,255,36,171,248,3,15,182,70,252,253,199,68,
717 194,4,237,252,233,244,2,248,4,139,137,233,133,201,15,133,244,1,248,5,139,
718 141,233,133,201,15,132,244,3,252,246,129,233,235,15,133,244,3,252,233,244,
719 37,255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,38,
720 139,44,252,234,59,133,233,15,131,244,38,193,224,3,3,133,233,129,120,253,4,
721 239,15,132,244,248,139,40,139,64,4,137,44,202,137,68,202,4,248,1,139,6,15,
722 182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,2,131,189,233,
723 0,15,132,244,249,139,141,233,252,246,129,233,235,15,132,244,38,255,15,182,
724 78,252,253,248,3,199,68,202,4,237,252,233,244,1,255,15,182,252,236,15,182,
725 192,129,124,253,252,234,4,239,15,133,244,42,139,44,252,234,255,15,133,244,
726 42,255,59,133,233,15,131,244,42,193,224,3,3,133,233,129,120,253,4,239,15,
727 132,244,249,248,1,252,246,133,233,235,15,133,244,253,248,2,139,108,202,4,
728 139,12,202,137,104,4,137,8,139,6,15,182,204,15,182,232,131,198,4,193,232,
729 16,252,255,36,171,248,3,131,189,233,0,15,132,244,1,139,141,233,252,246,129,
730 233,235,255,15,132,244,42,15,182,78,252,253,252,233,244,1,248,5,129,124,253,
731 194,4,239,15,133,244,42,139,4,194,252,233,244,170,248,7,128,165,233,235,139,
732 139,233,137,171,233,137,141,233,15,182,78,252,253,252,233,244,2,255,15,182,
733 252,236,15,182,192,252,247,208,139,4,135,129,124,253,252,234,4,239,15,133,
734 244,40,139,44,252,234,248,170,139,141,233,35,136,233,105,201,239,198,133,
735 233,0,3,141,233,248,1,129,185,233,239,15,133,244,251,57,129,233,15,133,244,
736 251,129,121,253,4,239,15,132,244,250,248,2,255,252,246,133,233,235,15,133,
737 244,253,248,3,15,182,70,252,253,139,108,194,4,139,4,194,137,105,4,137,1,139,
738 6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,4,131,189,
739 233,0,15,132,244,2,137,76,36,16,139,141,233,252,246,129,233,235,15,132,244,
740 40,139,76,36,16,252,233,244,2,248,5,139,137,233,133,201,15,133,244,1,255,
741 139,141,233,133,201,15,132,244,252,252,246,129,233,235,15,132,244,40,248,
742 6,137,68,36,16,199,68,36,20,237,137,108,36,12,141,68,36,16,137,108,36,4,139,
743 108,36,48,137,68,36,8,137,44,36,137,149,233,137,116,36,24,232,251,1,36,139,
744 149,233,139,108,36,12,137,193,252,233,244,2,248,7,128,165,233,235,139,131,
745 233,137,171,233,137,133,233,252,233,244,3,255,15,182,252,236,15,182,192,129,
746 124,253,252,234,4,239,15,133,244,41,139,44,252,234,59,133,233,15,131,244,
747 41,193,224,3,3,133,233,129,120,253,4,239,15,132,244,249,248,1,252,246,133,
748 233,235,15,133,244,253,248,2,139,108,202,4,139,12,202,137,104,4,137,8,139,
749 6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,3,131,189,
750 233,0,15,132,244,1,255,139,141,233,252,246,129,233,235,15,132,244,41,15,182,
751 78,252,253,252,233,244,1,248,7,128,165,233,235,139,139,233,137,171,233,137,
752 141,233,15,182,78,252,253,252,233,244,2,255,137,124,36,16,139,60,199,248,
753 1,141,12,202,139,105,252,248,252,246,133,233,235,15,133,244,253,248,2,139,
754 68,36,20,131,232,1,15,132,244,250,1,252,248,59,133,233,15,135,244,251,41,
755 252,248,193,231,3,3,189,233,248,3,139,41,137,47,139,105,4,131,193,8,137,111,
756 4,131,199,8,131,232,1,15,133,244,3,248,4,139,124,36,16,139,6,15,182,204,15,
757 182,232,131,198,4,193,232,16,252,255,36,171,248,5,137,108,36,4,139,108,36,
758 48,137,149,233,137,68,36,8,137,44,36,137,116,36,24,232,251,1,37,139,149,233,
759 15,182,78,252,253,252,233,244,1,248,7,255,128,165,233,235,139,131,233,137,
760 171,233,137,133,233,252,233,244,2,255,3,68,36,20,255,129,124,253,202,4,239,
761 139,44,202,15,133,244,59,141,84,202,8,137,114,252,252,139,181,233,139,14,
762 15,182,252,233,15,182,205,131,198,4,252,255,36,171,255,141,76,202,8,137,215,
763 139,105,252,248,129,121,253,252,252,239,15,133,244,29,248,60,139,114,252,
764 252,252,247,198,237,15,133,244,253,248,1,137,106,252,248,137,68,36,20,131,
765 232,1,15,132,244,249,248,2,139,41,137,47,139,105,4,131,193,8,137,111,4,131,
766 199,8,131,232,1,15,133,244,2,139,106,252,248,248,3,139,68,36,20,128,189,233,
767 1,15,135,244,251,248,4,139,181,233,139,14,15,182,252,233,15,182,205,131,198,
768 4,252,255,36,171,248,5,255,252,247,198,237,15,133,244,4,15,182,78,252,253,
769 252,247,209,141,12,202,139,121,252,248,139,191,233,139,191,233,252,233,244,
770 4,248,7,129,252,238,239,252,247,198,237,15,133,244,254,41,252,242,137,215,
771 139,114,252,252,252,233,244,1,248,8,129,198,239,252,233,244,1,255,141,76,
772 202,8,139,105,232,139,65,252,236,137,41,137,65,4,139,105,252,240,139,65,252,
773 244,137,105,8,137,65,12,139,105,224,139,65,228,137,105,252,248,137,65,252,
774 252,129,252,248,239,184,237,15,133,244,29,137,202,137,114,252,252,139,181,
775 233,139,14,15,182,252,233,15,182,205,131,198,4,252,255,36,171,255,137,124,
776 36,16,137,92,36,20,139,108,202,252,240,139,68,202,252,248,139,157,233,131,
777 198,4,139,189,233,248,1,57,216,15,131,244,251,129,124,253,199,4,239,15,132,
778 244,250,255,219,68,202,252,248,255,139,108,199,4,137,108,202,12,139,44,199,
779 137,108,202,8,131,192,1,255,137,68,202,252,248,248,2,15,183,70,252,254,141,
780 180,253,134,233,248,3,139,92,36,20,139,124,36,16,139,6,15,182,204,15,182,
781 232,131,198,4,193,232,16,252,255,36,171,248,4,131,192,1,255,137,68,202,252,
782 248,255,252,233,244,1,248,5,41,216,248,6,59,133,233,15,135,244,3,105,252,
783 248,239,3,189,233,129,191,233,239,15,132,244,253,141,92,24,1,139,175,233,
784 139,135,233,137,44,202,137,68,202,4,139,175,233,139,135,233,137,108,202,8,
785 137,68,202,12,137,92,202,252,248,252,233,244,2,248,7,255,131,192,1,252,233,
786 244,6,255,129,124,253,202,252,236,239,15,133,244,251,139,108,202,232,129,
787 124,253,202,252,244,239,15,133,244,251,129,124,253,202,252,252,239,15,133,
788 244,251,128,189,233,235,15,133,244,251,141,180,253,134,233,199,68,202,252,
789 248,0,0,0,0,248,1,139,6,15,182,204,15,182,232,131,198,4,193,232,16,252,255,
790 36,171,248,5,198,70,252,252,235,141,180,253,134,233,198,6,235,252,233,244,
791 1,255,15,182,252,236,15,182,192,137,124,36,16,141,188,253,194,233,141,12,
792 202,43,122,252,252,133,252,237,15,132,244,251,141,108,252,233,252,248,57,
793 215,15,131,244,248,248,1,139,71,252,248,137,1,139,71,252,252,131,199,8,137,
794 65,4,131,193,8,57,252,233,15,131,244,249,57,215,15,130,244,1,248,2,199,65,
795 4,237,131,193,8,57,252,233,15,130,244,2,248,3,139,124,36,16,139,6,15,182,
796 204,15,182,232,131,198,4,193,232,16,252,255,36,171,248,5,199,68,36,20,1,0,
797 0,0,137,208,41,252,248,15,134,244,3,137,197,193,252,237,3,131,197,1,137,108,
798 36,20,139,108,36,48,1,200,59,133,233,15,135,244,253,248,6,255,139,71,252,
799 248,137,1,139,71,252,252,131,199,8,137,65,4,131,193,8,57,215,15,130,244,6,
800 252,233,244,3,248,7,137,149,233,137,141,233,137,116,36,24,41,215,139,84,36,
801 20,131,252,234,1,137,252,233,232,251,1,0,139,149,233,139,141,233,1,215,252,
802 233,244,6,255,193,225,3,255,248,1,139,114,252,252,137,68,36,20,252,247,198,
803 237,15,133,244,253,255,248,13,137,215,131,232,1,15,132,244,249,248,2,139,
804 44,15,137,111,252,248,139,108,15,4,137,111,252,252,131,199,8,131,232,1,15,
805 133,244,2,248,3,139,68,36,20,15,182,110,252,255,248,5,57,197,15,135,244,252,
806 255,139,108,10,4,137,106,252,252,139,44,10,137,106,252,248,255,248,5,56,70,
807 252,255,15,135,244,252,255,15,182,78,252,253,252,247,209,141,20,202,139,122,
808 252,248,139,191,233,139,191,233,139,6,15,182,204,15,182,232,131,198,4,193,
809 232,16,252,255,36,171,248,6,255,199,71,252,252,237,131,199,8,255,199,68,194,
810 252,244,237,255,131,192,1,252,233,244,5,248,7,141,174,233,252,247,197,237,
811 15,133,244,14,41,252,234,255,1,252,233,255,137,252,245,209,252,237,129,229,
812 239,102,129,172,253,43,233,238,15,130,244,149,255,141,12,202,255,129,121,
813 253,4,239,15,133,244,255,255,129,121,253,12,239,15,133,244,61,129,121,253,
814 20,239,15,133,244,61,139,41,131,121,16,0,15,140,244,251,255,129,121,253,12,
815 239,15,133,244,165,129,121,253,20,239,15,133,244,165,255,139,105,16,133,252,
816 237,15,136,244,251,3,41,15,128,244,247,137,41,255,59,105,8,199,65,28,237,
817 137,105,24,255,15,142,244,253,248,1,248,6,141,180,253,134,233,255,141,180,
818 253,134,233,15,183,70,252,254,15,142,245,248,1,248,6,255,15,143,244,253,248,
819 6,141,180,253,134,233,248,1,255,248,7,139,6,15,182,204,15,182,232,131,198,
820 4,193,232,16,252,255,36,171,248,5,255,3,41,15,128,244,1,137,41,255,15,141,
821 244,7,255,141,180,253,134,233,15,183,70,252,254,15,141,245,255,15,140,244,
822 7,255,252,233,244,6,248,9,255,129,121,253,4,239,255,15,131,244,61,129,121,
823 253,12,239,15,131,244,61,255,129,121,253,12,239,15,131,244,165,129,121,253,
824 20,239,15,131,244,165,255,139,105,20,255,129,252,253,239,15,131,244,61,255,
825 252,242,15,16,1,252,242,15,16,73,8,255,252,242,15,88,65,16,252,242,15,17,
826 1,133,252,237,15,136,244,249,255,15,140,244,249,255,102,15,46,200,248,1,252,
827 242,15,17,65,24,255,221,65,8,221,1,255,220,65,16,221,17,221,81,24,133,252,
828 237,15,136,244,247,255,221,81,24,15,140,244,247,255,217,201,248,1,255,15,
829 183,70,252,254,255,15,131,244,7,255,15,131,244,248,141,180,253,134,233,255,
830 141,180,253,134,233,15,183,70,252,254,15,131,245,255,15,130,244,7,255,15,
831 130,244,248,141,180,253,134,233,255,248,3,102,15,46,193,252,233,244,1,255,
832 141,12,202,139,105,4,129,252,253,239,15,132,244,247,255,137,105,252,252,139,
833 41,137,105,252,248,252,233,245,255,141,180,253,134,233,139,1,137,105,252,
834 252,137,65,252,248,255,139,139,233,139,4,129,139,128,233,139,108,36,48,137,
835 147,233,137,171,233,252,255,224,255,141,180,253,134,233,139,6,15,182,204,
836 15,182,232,131,198,4,193,232,16,252,255,36,171,255,137,252,245,209,252,237,
837 129,229,239,102,129,172,253,43,233,238,15,130,244,151,255,139,190,233,139,
838 108,36,48,141,12,202,59,141,233,15,135,244,24,15,182,142,233,57,200,15,134,
839 244,249,248,2,255,15,183,70,252,254,252,233,245,255,248,3,199,68,194,252,
840 252,237,131,192,1,57,200,15,134,244,3,252,233,244,2,255,141,44,197,237,141,
841 4,194,139,122,252,248,137,104,252,252,137,120,252,248,139,108,36,48,141,12,
842 200,59,141,233,15,135,244,23,137,209,137,194,15,182,174,233,133,252,237,15,
843 132,244,248,248,1,131,193,8,57,209,15,131,244,249,139,121,252,248,137,56,
844 139,121,252,252,137,120,4,131,192,8,199,65,252,252,237,131,252,237,1,15,133,
845 244,1,248,2,255,139,190,233,139,6,15,182,204,15,182,232,131,198,4,193,232,
846 16,252,255,36,171,255,248,3,199,64,4,237,131,192,8,131,252,237,1,15,133,244,
847 3,252,233,244,2,255,139,106,252,248,139,189,233,139,108,36,48,141,68,194,
848 252,248,137,149,233,141,136,233,59,141,233,137,133,233,255,137,44,36,255,
849 137,124,36,4,137,44,36,255,15,135,244,22,199,131,233,237,255,252,255,215,
850 255,252,255,147,233,255,199,131,233,237,139,149,233,141,12,194,252,247,217,
851 3,141,233,139,114,252,252,252,233,244,12,255,254,0
852};
853
854enum {
855 GLOB_vm_returnp,
856 GLOB_cont_dispatch,
857 GLOB_vm_returnc,
858 GLOB_BC_RET_Z,
859 GLOB_vm_return,
860 GLOB_vm_leave_cp,
861 GLOB_vm_leave_unw,
862 GLOB_vm_unwind_c,
863 GLOB_vm_unwind_c_eh,
864 GLOB_vm_unwind_rethrow,
865 GLOB_vm_unwind_ff,
866 GLOB_vm_unwind_ff_eh,
867 GLOB_vm_growstack_c,
868 GLOB_vm_growstack_v,
869 GLOB_vm_growstack_f,
870 GLOB_vm_resume,
871 GLOB_vm_pcall,
872 GLOB_vm_call,
873 GLOB_vm_call_dispatch,
874 GLOB_vmeta_call,
875 GLOB_vm_call_dispatch_f,
876 GLOB_vm_cpcall,
877 GLOB_cont_ffi_callback,
878 GLOB_vm_call_tail,
879 GLOB_cont_cat,
880 GLOB_cont_ra,
881 GLOB_BC_CAT_Z,
882 GLOB_vmeta_tgets,
883 GLOB_vmeta_tgetb,
884 GLOB_vmeta_tgetv,
885 GLOB_vmeta_tsets,
886 GLOB_vmeta_tsetb,
887 GLOB_vmeta_tsetv,
888 GLOB_cont_nop,
889 GLOB_vmeta_comp,
890 GLOB_vmeta_binop,
891 GLOB_cont_condt,
892 GLOB_cont_condf,
893 GLOB_vmeta_equal,
894 GLOB_vmeta_equal_cd,
895 GLOB_vmeta_arith_vno,
896 GLOB_vmeta_arith_vn,
897 GLOB_vmeta_arith_nvo,
898 GLOB_vmeta_arith_nv,
899 GLOB_vmeta_unm,
900 GLOB_vmeta_arith_vvo,
901 GLOB_vmeta_arith_vv,
902 GLOB_vmeta_len,
903 GLOB_BC_LEN_Z,
904 GLOB_vmeta_call_ra,
905 GLOB_BC_CALLT_Z,
906 GLOB_vmeta_for,
907 GLOB_ff_assert,
908 GLOB_fff_fallback,
909 GLOB_fff_res_,
910 GLOB_ff_type,
911 GLOB_fff_res1,
912 GLOB_ff_getmetatable,
913 GLOB_ff_setmetatable,
914 GLOB_ff_rawget,
915 GLOB_ff_tonumber,
916 GLOB_fff_resi,
917 GLOB_fff_resxmm0,
918 GLOB_fff_resn,
919 GLOB_ff_tostring,
920 GLOB_fff_gcstep,
921 GLOB_ff_next,
922 GLOB_fff_res2,
923 GLOB_fff_res,
924 GLOB_ff_pairs,
925 GLOB_ff_ipairs_aux,
926 GLOB_fff_res0,
927 GLOB_ff_ipairs,
928 GLOB_ff_pcall,
929 GLOB_ff_xpcall,
930 GLOB_ff_coroutine_resume,
931 GLOB_ff_coroutine_wrap_aux,
932 GLOB_ff_coroutine_yield,
933 GLOB_ff_math_abs,
934 GLOB_fff_resbit,
935 GLOB_ff_math_floor,
936 GLOB_vm_floor,
937 GLOB_ff_math_ceil,
938 GLOB_vm_ceil,
939 GLOB_ff_math_sqrt,
940 GLOB_ff_math_log,
941 GLOB_ff_math_log10,
942 GLOB_ff_math_exp,
943 GLOB_vm_exp_x87,
944 GLOB_ff_math_sin,
945 GLOB_ff_math_cos,
946 GLOB_ff_math_tan,
947 GLOB_ff_math_asin,
948 GLOB_ff_math_acos,
949 GLOB_ff_math_atan,
950 GLOB_ff_math_sinh,
951 GLOB_ff_math_cosh,
952 GLOB_ff_math_tanh,
953 GLOB_ff_math_deg,
954 GLOB_ff_math_rad,
955 GLOB_ff_math_atan2,
956 GLOB_ff_math_ldexp,
957 GLOB_ff_math_frexp,
958 GLOB_ff_math_modf,
959 GLOB_vm_trunc,
960 GLOB_ff_math_fmod,
961 GLOB_ff_math_pow,
962 GLOB_vm_pow,
963 GLOB_ff_math_min,
964 GLOB_ff_math_max,
965 GLOB_ff_string_len,
966 GLOB_ff_string_byte,
967 GLOB_ff_string_char,
968 GLOB_fff_newstr,
969 GLOB_ff_string_sub,
970 GLOB_fff_emptystr,
971 GLOB_ff_string_rep,
972 GLOB_fff_fallback_2,
973 GLOB_ff_string_reverse,
974 GLOB_fff_fallback_1,
975 GLOB_ff_string_lower,
976 GLOB_ff_string_upper,
977 GLOB_ff_table_getn,
978 GLOB_ff_bit_tobit,
979 GLOB_ff_bit_band,
980 GLOB_fff_fallback_bit_op,
981 GLOB_ff_bit_bor,
982 GLOB_ff_bit_bxor,
983 GLOB_ff_bit_bswap,
984 GLOB_ff_bit_bnot,
985 GLOB_ff_bit_lshift,
986 GLOB_ff_bit_rshift,
987 GLOB_ff_bit_arshift,
988 GLOB_ff_bit_rol,
989 GLOB_ff_bit_ror,
990 GLOB_vm_record,
991 GLOB_vm_rethook,
992 GLOB_vm_inshook,
993 GLOB_cont_hook,
994 GLOB_vm_hotloop,
995 GLOB_vm_callhook,
996 GLOB_vm_hotcall,
997 GLOB_vm_exit_handler,
998 GLOB_vm_exit_interp,
999 GLOB_vm_floor_sse,
1000 GLOB_vm_ceil_sse,
1001 GLOB_vm_trunc_sse,
1002 GLOB_vm_mod,
1003 GLOB_vm_exp2_x87,
1004 GLOB_vm_exp2raw,
1005 GLOB_vm_pow_sse,
1006 GLOB_vm_powi_sse,
1007 GLOB_vm_foldfpm,
1008 GLOB_vm_foldarith,
1009 GLOB_vm_cpuid,
1010 GLOB_assert_bad_for_arg_type,
1011 GLOB_vm_ffi_callback,
1012 GLOB_vm_ffi_call,
1013 GLOB_BC_MODVN_Z,
1014 GLOB_BC_TGETS_Z,
1015 GLOB_BC_TSETS_Z,
1016 GLOB__MAX
1017};
1018static const char *const globnames[] = {
1019 "vm_returnp",
1020 "cont_dispatch",
1021 "vm_returnc",
1022 "BC_RET_Z",
1023 "vm_return",
1024 "vm_leave_cp",
1025 "vm_leave_unw",
1026 "vm_unwind_c@8",
1027 "vm_unwind_c_eh",
1028 "vm_unwind_rethrow",
1029 "vm_unwind_ff@4",
1030 "vm_unwind_ff_eh",
1031 "vm_growstack_c",
1032 "vm_growstack_v",
1033 "vm_growstack_f",
1034 "vm_resume",
1035 "vm_pcall",
1036 "vm_call",
1037 "vm_call_dispatch",
1038 "vmeta_call",
1039 "vm_call_dispatch_f",
1040 "vm_cpcall",
1041 "cont_ffi_callback",
1042 "vm_call_tail",
1043 "cont_cat",
1044 "cont_ra",
1045 "BC_CAT_Z",
1046 "vmeta_tgets",
1047 "vmeta_tgetb",
1048 "vmeta_tgetv",
1049 "vmeta_tsets",
1050 "vmeta_tsetb",
1051 "vmeta_tsetv",
1052 "cont_nop",
1053 "vmeta_comp",
1054 "vmeta_binop",
1055 "cont_condt",
1056 "cont_condf",
1057 "vmeta_equal",
1058 "vmeta_equal_cd",
1059 "vmeta_arith_vno",
1060 "vmeta_arith_vn",
1061 "vmeta_arith_nvo",
1062 "vmeta_arith_nv",
1063 "vmeta_unm",
1064 "vmeta_arith_vvo",
1065 "vmeta_arith_vv",
1066 "vmeta_len",
1067 "BC_LEN_Z",
1068 "vmeta_call_ra",
1069 "BC_CALLT_Z",
1070 "vmeta_for",
1071 "ff_assert",
1072 "fff_fallback",
1073 "fff_res_",
1074 "ff_type",
1075 "fff_res1",
1076 "ff_getmetatable",
1077 "ff_setmetatable",
1078 "ff_rawget",
1079 "ff_tonumber",
1080 "fff_resi",
1081 "fff_resxmm0",
1082 "fff_resn",
1083 "ff_tostring",
1084 "fff_gcstep",
1085 "ff_next",
1086 "fff_res2",
1087 "fff_res",
1088 "ff_pairs",
1089 "ff_ipairs_aux",
1090 "fff_res0",
1091 "ff_ipairs",
1092 "ff_pcall",
1093 "ff_xpcall",
1094 "ff_coroutine_resume",
1095 "ff_coroutine_wrap_aux",
1096 "ff_coroutine_yield",
1097 "ff_math_abs",
1098 "fff_resbit",
1099 "ff_math_floor",
1100 "vm_floor",
1101 "ff_math_ceil",
1102 "vm_ceil",
1103 "ff_math_sqrt",
1104 "ff_math_log",
1105 "ff_math_log10",
1106 "ff_math_exp",
1107 "vm_exp_x87",
1108 "ff_math_sin",
1109 "ff_math_cos",
1110 "ff_math_tan",
1111 "ff_math_asin",
1112 "ff_math_acos",
1113 "ff_math_atan",
1114 "ff_math_sinh",
1115 "ff_math_cosh",
1116 "ff_math_tanh",
1117 "ff_math_deg",
1118 "ff_math_rad",
1119 "ff_math_atan2",
1120 "ff_math_ldexp",
1121 "ff_math_frexp",
1122 "ff_math_modf",
1123 "vm_trunc",
1124 "ff_math_fmod",
1125 "ff_math_pow",
1126 "vm_pow",
1127 "ff_math_min",
1128 "ff_math_max",
1129 "ff_string_len",
1130 "ff_string_byte",
1131 "ff_string_char",
1132 "fff_newstr",
1133 "ff_string_sub",
1134 "fff_emptystr",
1135 "ff_string_rep",
1136 "fff_fallback_2",
1137 "ff_string_reverse",
1138 "fff_fallback_1",
1139 "ff_string_lower",
1140 "ff_string_upper",
1141 "ff_table_getn",
1142 "ff_bit_tobit",
1143 "ff_bit_band",
1144 "fff_fallback_bit_op",
1145 "ff_bit_bor",
1146 "ff_bit_bxor",
1147 "ff_bit_bswap",
1148 "ff_bit_bnot",
1149 "ff_bit_lshift",
1150 "ff_bit_rshift",
1151 "ff_bit_arshift",
1152 "ff_bit_rol",
1153 "ff_bit_ror",
1154 "vm_record",
1155 "vm_rethook",
1156 "vm_inshook",
1157 "cont_hook",
1158 "vm_hotloop",
1159 "vm_callhook",
1160 "vm_hotcall",
1161 "vm_exit_handler",
1162 "vm_exit_interp",
1163 "vm_floor_sse",
1164 "vm_ceil_sse",
1165 "vm_trunc_sse",
1166 "vm_mod",
1167 "vm_exp2_x87",
1168 "vm_exp2raw",
1169 "vm_pow_sse",
1170 "vm_powi_sse",
1171 "vm_foldfpm",
1172 "vm_foldarith",
1173 "vm_cpuid",
1174 "assert_bad_for_arg_type",
1175 "vm_ffi_callback",
1176 "vm_ffi_call@4",
1177 "BC_MODVN_Z",
1178 "BC_TGETS_Z",
1179 "BC_TSETS_Z",
1180 (const char *)0
1181};
1182static const char *const extnames[] = {
1183 "lj_state_growstack@8",
1184 "lj_meta_tget",
1185 "lj_meta_tset",
1186 "lj_meta_comp",
1187 "lj_meta_equal",
1188 "lj_meta_equal_cd@8",
1189 "lj_meta_arith",
1190 "lj_meta_len@8",
1191 "lj_meta_call",
1192 "lj_meta_for@8",
1193 "lj_tab_get",
1194 "lj_str_fromnumber@8",
1195 "lj_str_fromnum@8",
1196 "lj_tab_next",
1197 "lj_tab_getinth@8",
1198 "lj_ffh_coroutine_wrap_err@8",
1199 "lj_vm_sinh",
1200 "lj_vm_cosh",
1201 "lj_vm_tanh",
1202 "lj_str_new",
1203 "lj_tab_len@4",
1204 "lj_gc_step@4",
1205 "lj_dispatch_ins@8",
1206 "lj_trace_hot@8",
1207 "lj_dispatch_call@8",
1208 "lj_trace_exit@8",
1209 "lj_err_throw@8",
1210 "lj_ccallback_enter@8",
1211 "lj_ccallback_leave@8",
1212 "lj_meta_cat",
1213 "lj_gc_barrieruv@8",
1214 "lj_func_closeuv@8",
1215 "lj_func_newL_gc",
1216 "lj_tab_new",
1217 "lj_gc_step_fixtop@4",
1218 "lj_tab_dup@8",
1219 "lj_tab_newkey",
1220 "lj_tab_reasize",
1221 (const char *)0
1222};
1223#define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V)
1224#define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V)
1225#define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V)
1226#define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V)
1227#define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V)
1228#define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V)
1229#define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V)
1230#define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V)
1231#define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V)
1232#define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V)
1233#define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V)
1234#define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V)
1235#define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V)
1236#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
1237#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
1238#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
1239
1240/* Generate subroutines used by opcodes and other parts of the VM. */
1241/* The .code_sub section should be last to help static branch prediction. */
1242static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
1243{
1244 dasm_put(Dst, 0);
1245 dasm_put(Dst, 2, FRAME_P, LJ_TTRUE, FRAME_TYPE, FRAME_C, FRAME_TYPE, DISPATCH_GL(vmstate), ~LJ_VMST_C);
1246 dasm_put(Dst, 114, Dt1(->base), Dt1(->top), Dt1(->cframe), Dt1(->maxstack), LJ_TNIL);
1247 dasm_put(Dst, 200, Dt1(->top), Dt1(->top), Dt1(->glref), Dt2(->vmstate), ~LJ_VMST_C, CFRAME_RAWMASK);
1248 dasm_put(Dst, 275, 1+1, Dt1(->base), Dt1(->glref), GG_G2DISP, LJ_TFALSE, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, LUA_MINSTACK, -4+PC2PROTO(framesize), Dt1(->base));
1249 dasm_put(Dst, 353, Dt1(->top), Dt1(->base), Dt1(->top), Dt7(->pc), FRAME_CP, CFRAME_RESUME, Dt1(->glref), GG_G2DISP, Dt1(->cframe), Dt1(->status), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->status), Dt1(->base), Dt1(->top), FRAME_TYPE);
1250 dasm_put(Dst, 495, FRAME_CP, FRAME_C, Dt1(->cframe), Dt1(->cframe), Dt1(->glref), GG_G2DISP, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base));
1251 dasm_put(Dst, 573, Dt1(->top), LJ_TFUNC, Dt7(->pc), Dt1(->stack), Dt1(->top), Dt1(->cframe), Dt1(->cframe), FRAME_CP, LJ_TNIL);
1252#if LJ_HASFFI
1253#endif
1254 dasm_put(Dst, 743);
1255#if LJ_HASFFI
1256 dasm_put(Dst, 748);
1257#endif
1258 dasm_put(Dst, 757, Dt7(->pc), PC2PROTO(k));
1259#if LJ_HASFFI
1260 dasm_put(Dst, 771);
1261#endif
1262 dasm_put(Dst, 792, LJ_TSTR, BC_GGET, DISPATCH_GL(tmptv), LJ_TTAB);
1263 if (LJ_DUALNUM) {
1264 dasm_put(Dst, 890, LJ_TISNUM);
1265 } else if (sse) {
1266 dasm_put(Dst, 900);
1267 } else {
1268 dasm_put(Dst, 913);
1269 }
1270 dasm_put(Dst, 926, Dt1(->base), Dt1(->base), Dt1(->top), FRAME_CONT, 2+1, LJ_TSTR, BC_GSET);
1271 dasm_put(Dst, 1078, DISPATCH_GL(tmptv), LJ_TTAB);
1272 if (LJ_DUALNUM) {
1273 dasm_put(Dst, 890, LJ_TISNUM);
1274 } else if (sse) {
1275 dasm_put(Dst, 900);
1276 } else {
1277 dasm_put(Dst, 913);
1278 }
1279 dasm_put(Dst, 1101, Dt1(->base), Dt1(->base), Dt1(->top), FRAME_CONT, 3+1, Dt1(->base), Dt1(->base));
1280 dasm_put(Dst, 1295, -BCBIAS_J*4, LJ_TISTRUECOND, LJ_TISTRUECOND, Dt1(->base));
1281 dasm_put(Dst, 1402);
1282#if LJ_HASFFI
1283 dasm_put(Dst, 1417, Dt1(->base));
1284#endif
1285 dasm_put(Dst, 1448);
1286#if LJ_DUALNUM
1287 dasm_put(Dst, 1451);
1288#endif
1289 dasm_put(Dst, 1457);
1290#if LJ_DUALNUM
1291 dasm_put(Dst, 884);
1292#endif
1293 dasm_put(Dst, 1469);
1294#if LJ_DUALNUM
1295 dasm_put(Dst, 1451);
1296#endif
1297 dasm_put(Dst, 1497, Dt1(->base), Dt1(->base), FRAME_CONT, 2+1, Dt1(->base), Dt1(->base));
1298#ifdef LUAJIT_ENABLE_LUA52COMPAT
1299 dasm_put(Dst, 1607);
1300#else
1301 dasm_put(Dst, 1626);
1302#endif
1303 dasm_put(Dst, 1631, Dt1(->base), Dt1(->base), Dt7(->pc), Dt1(->base), Dt1(->base), GG_DISP2STATIC, 1+1, LJ_TISTRUECOND);
1304 dasm_put(Dst, 1820, 1+1, ~LJ_TNUMX);
1305 if (cmov) {
1306 dasm_put(Dst, 1878);
1307 } else {
1308 dasm_put(Dst, 1882);
1309 }
1310 dasm_put(Dst, 1891, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL, DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable), LJ_TTAB);
1311 dasm_put(Dst, 1974, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next), LJ_TNIL);
1312 dasm_put(Dst, 2032, LJ_TUDATA, LJ_TISNUM, LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT]), 2+1);
1313 dasm_put(Dst, 2095, LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->marked), LJ_GC_BLACK, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
1314 dasm_put(Dst, 2167, 2+1, LJ_TTAB, 1+1, LJ_TISNUM);
1315 if (LJ_DUALNUM) {
1316 dasm_put(Dst, 2256);
1317 } else {
1318 dasm_put(Dst, 2273);
1319 }
1320 if (sse) {
1321 dasm_put(Dst, 2278);
1322 } else {
1323 dasm_put(Dst, 2288);
1324 }
1325 dasm_put(Dst, 2295, 1+1, LJ_TSTR, LJ_TSTR, LJ_TISNUM, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
1326 dasm_put(Dst, 2361, Dt1(->base));
1327 if (LJ_DUALNUM) {
1328 dasm_put(Dst, 2385);
1329 } else {
1330 dasm_put(Dst, 2390);
1331 }
1332 dasm_put(Dst, 2395, Dt1(->base), 1+1, LJ_TTAB, Dt1(->base), Dt1(->top), Dt1(->base), 1+2);
1333 dasm_put(Dst, 2504, LJ_TNIL, LJ_TNIL, 1+1, LJ_TTAB);
1334#ifdef LUAJIT_ENABLE_LUA52COMPAT
1335 dasm_put(Dst, 2551, Dt6(->metatable));
1336#endif
1337 dasm_put(Dst, 2560, Dt8(->upvalue[0]), LJ_TFUNC, LJ_TNIL, 1+3, 1+1, LJ_TTAB, LJ_TISNUM);
1338 if (LJ_DUALNUM) {
1339 dasm_put(Dst, 2546);
1340 } else {
1341 dasm_put(Dst, 2273);
1342 }
1343 dasm_put(Dst, 2615);
1344 if (LJ_DUALNUM) {
1345 dasm_put(Dst, 2620, LJ_TISNUM);
1346 } else if (sse) {
1347 dasm_put(Dst, 2636);
1348 } else {
1349 dasm_put(Dst, 2675);
1350 }
1351 dasm_put(Dst, 2693, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->hmask), 1+0);
1352 dasm_put(Dst, 2531, 1+1, LJ_TTAB);
1353#ifdef LUAJIT_ENABLE_LUA52COMPAT
1354 dasm_put(Dst, 2551, Dt6(->metatable));
1355#endif
1356 dasm_put(Dst, 2774, Dt8(->upvalue[0]), LJ_TFUNC);
1357 if (LJ_DUALNUM) {
1358 dasm_put(Dst, 2795, LJ_TISNUM);
1359 } else if (sse) {
1360 dasm_put(Dst, 2807);
1361 } else {
1362 dasm_put(Dst, 2817);
1363 }
1364 dasm_put(Dst, 2824, 1+3, 1+1, 8+FRAME_PCALL, DISPATCH_GL(hookmask), HOOK_ACTIVE_SHIFT, 2+1, LJ_TFUNC);
1365 dasm_put(Dst, 2888, LJ_TFUNC, 16+FRAME_PCALL, 1+1, LJ_TTHREAD, Dt1(->cframe), Dt1(->status), LUA_YIELD, Dt1(->top));
1366 dasm_put(Dst, 2976, Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP);
1367 dasm_put(Dst, 3077, Dt1(->base), LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack), LJ_TTRUE, FRAME_TYPE);
1368 dasm_put(Dst, 3191, LJ_TFALSE, Dt1(->top), Dt1(->top), 1+2, Dt1(->top), Dt1(->base), Dt8(->upvalue[0].gcr), Dt1(->cframe));
1369 dasm_put(Dst, 3289, Dt1(->status), LUA_YIELD, Dt1(->top), Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top));
1370 dasm_put(Dst, 3355, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack));
1371 dasm_put(Dst, 3456, FRAME_TYPE, Dt1(->top), Dt1(->base), Dt1(->cframe), CFRAME_RESUME);
1372 dasm_put(Dst, 3569, Dt1(->base), Dt1(->top), Dt1(->cframe), LUA_YIELD, Dt1(->status));
1373 if (!LJ_DUALNUM) {
1374 dasm_put(Dst, 3595);
1375 }
1376 if (sse) {
1377 dasm_put(Dst, 3598);
1378 }
1379 dasm_put(Dst, 3613, 1+1);
1380 if (LJ_DUALNUM) {
1381 dasm_put(Dst, 3624, LJ_TISNUM, LJ_TISNUM);
1382 } else {
1383 dasm_put(Dst, 3704, LJ_TISNUM);
1384 }
1385 if (sse) {
1386 dasm_put(Dst, 3714);
1387 } else {
1388 dasm_put(Dst, 3750);
1389 }
1390 dasm_put(Dst, 3767, 1+1, FRAME_TYPE, LJ_TNIL);
1391 if (LJ_DUALNUM) {
1392 dasm_put(Dst, 3859, LJ_TISNUM);
1393 } else {
1394 dasm_put(Dst, 3704, LJ_TISNUM);
1395 }
1396 if (sse) {
1397 dasm_put(Dst, 3881);
1398 if (LJ_DUALNUM) {
1399 dasm_put(Dst, 3890);
1400 }
1401 dasm_put(Dst, 2283);
1402 } else {
1403 dasm_put(Dst, 3924);
1404 if (LJ_DUALNUM) {
1405 dasm_put(Dst, 3930);
1406 if (cmov) {
1407 dasm_put(Dst, 3953);
1408 } else {
1409 dasm_put(Dst, 3959);
1410 }
1411 dasm_put(Dst, 3966);
1412 } else {
1413 dasm_put(Dst, 2290);
1414 }
1415 }
1416 dasm_put(Dst, 3983);
1417 if (LJ_DUALNUM) {
1418 dasm_put(Dst, 3859, LJ_TISNUM);
1419 } else {
1420 dasm_put(Dst, 3704, LJ_TISNUM);
1421 }
1422 if (sse) {
1423 dasm_put(Dst, 3986);
1424 if (LJ_DUALNUM) {
1425 dasm_put(Dst, 3890);
1426 }
1427 dasm_put(Dst, 2283);
1428 } else {
1429 dasm_put(Dst, 3995);
1430 if (LJ_DUALNUM) {
1431 dasm_put(Dst, 3930);
1432 if (cmov) {
1433 dasm_put(Dst, 3953);
1434 } else {
1435 dasm_put(Dst, 3959);
1436 }
1437 dasm_put(Dst, 3966);
1438 } else {
1439 dasm_put(Dst, 2290);
1440 }
1441 }
1442 if (sse) {
1443 dasm_put(Dst, 4001, 1+1, LJ_TISNUM);
1444 } else {
1445 dasm_put(Dst, 4030, 1+1, LJ_TISNUM);
1446 }
1447 dasm_put(Dst, 4059, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1448 dasm_put(Dst, 4128, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1449 dasm_put(Dst, 4185, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
1450 dasm_put(Dst, 4248, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
1451 dasm_put(Dst, 4338);
1452 if (sse) {
1453 dasm_put(Dst, 4350, 1+1, LJ_TISNUM);
1454 } else {
1455 dasm_put(Dst, 4381, 1+1, LJ_TISNUM);
1456 }
1457 dasm_put(Dst, 4406);
1458 if (sse) {
1459 dasm_put(Dst, 4420, 1+1, LJ_TISNUM);
1460 } else {
1461 dasm_put(Dst, 4451, 1+1, LJ_TISNUM);
1462 }
1463 dasm_put(Dst, 4476);
1464 if (sse) {
1465 dasm_put(Dst, 4490, 1+1, LJ_TISNUM);
1466 } else {
1467 dasm_put(Dst, 4521, 1+1, LJ_TISNUM);
1468 }
1469 dasm_put(Dst, 4546);
1470 if (sse) {
1471 dasm_put(Dst, 4562, 1+1, LJ_TISNUM, Dt8(->upvalue[0]));
1472 } else {
1473 dasm_put(Dst, 4601, 1+1, LJ_TISNUM, Dt8(->upvalue[0]));
1474 }
1475 dasm_put(Dst, 4634, 2+1, LJ_TISNUM, LJ_TISNUM, 2+1, LJ_TISNUM, LJ_TISNUM);
1476 dasm_put(Dst, 4699, 1+1, LJ_TISNUM);
1477 if (sse) {
1478 dasm_put(Dst, 4798);
1479 } else {
1480 dasm_put(Dst, 4804);
1481 }
1482 dasm_put(Dst, 4813);
1483 if (sse) {
1484 dasm_put(Dst, 4838);
1485 } else {
1486 dasm_put(Dst, 4844);
1487 }
1488 dasm_put(Dst, 4847, 1+2);
1489 if (sse) {
1490 dasm_put(Dst, 4856);
1491 } else {
1492 dasm_put(Dst, 4864);
1493 }
1494 dasm_put(Dst, 4872);
1495 if (sse) {
1496 dasm_put(Dst, 4875);
1497 } else {
1498 dasm_put(Dst, 4907);
1499 }
1500 dasm_put(Dst, 4926);
1501 if (sse) {
1502 dasm_put(Dst, 4942, 1+1, LJ_TISNUM);
1503 } else {
1504 dasm_put(Dst, 4967, 1+1, LJ_TISNUM);
1505 }
1506 dasm_put(Dst, 4989);
1507 if (sse) {
1508 dasm_put(Dst, 5011);
1509 } else {
1510 dasm_put(Dst, 5037);
1511 }
1512 dasm_put(Dst, 5054, 1+2);
1513 if (sse) {
1514 dasm_put(Dst, 5094);
1515 } else {
1516 dasm_put(Dst, 5102);
1517 }
1518 dasm_put(Dst, 5112, 2+1, LJ_TISNUM, LJ_TISNUM);
1519 if (sse) {
1520 dasm_put(Dst, 5164, 2+1, LJ_TISNUM, LJ_TISNUM);
1521 } else {
1522 dasm_put(Dst, 5211, 2+1, LJ_TISNUM, LJ_TISNUM);
1523 }
1524 dasm_put(Dst, 5252, LJ_TISNUM);
1525 if (LJ_DUALNUM) {
1526 dasm_put(Dst, 5265, LJ_TISNUM);
1527 if (sse) {
1528 dasm_put(Dst, 4798);
1529 } else {
1530 dasm_put(Dst, 4804);
1531 }
1532 dasm_put(Dst, 5315);
1533 } else {
1534 dasm_put(Dst, 2273);
1535 }
1536 if (sse) {
1537 dasm_put(Dst, 5326, LJ_TISNUM);
1538 if (LJ_DUALNUM) {
1539 dasm_put(Dst, 5347);
1540 } else {
1541 dasm_put(Dst, 2273);
1542 }
1543 dasm_put(Dst, 5368);
1544 } else {
1545 dasm_put(Dst, 5393, LJ_TISNUM);
1546 if (LJ_DUALNUM) {
1547 dasm_put(Dst, 5411);
1548 } else {
1549 dasm_put(Dst, 5429);
1550 }
1551 dasm_put(Dst, 5434);
1552 if (cmov) {
1553 dasm_put(Dst, 5444);
1554 } else {
1555 dasm_put(Dst, 5452);
1556 }
1557 dasm_put(Dst, 5385);
1558 }
1559 dasm_put(Dst, 5473, LJ_TISNUM);
1560 if (LJ_DUALNUM) {
1561 dasm_put(Dst, 5486, LJ_TISNUM);
1562 if (sse) {
1563 dasm_put(Dst, 4798);
1564 } else {
1565 dasm_put(Dst, 4804);
1566 }
1567 dasm_put(Dst, 5315);
1568 } else {
1569 dasm_put(Dst, 2273);
1570 }
1571 if (sse) {
1572 dasm_put(Dst, 5326, LJ_TISNUM);
1573 if (LJ_DUALNUM) {
1574 dasm_put(Dst, 5347);
1575 } else {
1576 dasm_put(Dst, 2273);
1577 }
1578 dasm_put(Dst, 5536);
1579 } else {
1580 dasm_put(Dst, 5393, LJ_TISNUM);
1581 if (LJ_DUALNUM) {
1582 dasm_put(Dst, 5411);
1583 } else {
1584 dasm_put(Dst, 5429);
1585 }
1586 dasm_put(Dst, 5434);
1587 if (cmov) {
1588 dasm_put(Dst, 5561);
1589 } else {
1590 dasm_put(Dst, 5569);
1591 }
1592 dasm_put(Dst, 5385);
1593 }
1594 if (!sse) {
1595 dasm_put(Dst, 5590);
1596 }
1597 dasm_put(Dst, 5599, 1+1, LJ_TSTR);
1598 if (LJ_DUALNUM) {
1599 dasm_put(Dst, 5621, Dt5(->len));
1600 } else if (sse) {
1601 dasm_put(Dst, 5629, Dt5(->len));
1602 } else {
1603 dasm_put(Dst, 5640, Dt5(->len));
1604 }
1605 dasm_put(Dst, 5648, 1+1, LJ_TSTR, Dt5(->len), Dt5([1]));
1606 if (LJ_DUALNUM) {
1607 dasm_put(Dst, 3978);
1608 } else if (sse) {
1609 dasm_put(Dst, 5686);
1610 } else {
1611 dasm_put(Dst, 5696);
1612 }
1613 dasm_put(Dst, 5709, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 1+1, LJ_TISNUM);
1614 if (LJ_DUALNUM) {
1615 dasm_put(Dst, 5740);
1616 } else if (sse) {
1617 dasm_put(Dst, 5763);
1618 } else {
1619 dasm_put(Dst, 5789);
1620 }
1621 dasm_put(Dst, 5813, Dt1(->base), Dt1(->base), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 1+2, LJ_TISNUM);
1622 if (LJ_DUALNUM) {
1623 dasm_put(Dst, 5916);
1624 } else if (sse) {
1625 dasm_put(Dst, 5928);
1626 } else {
1627 dasm_put(Dst, 5943);
1628 }
1629 dasm_put(Dst, 5955, LJ_TSTR, LJ_TISNUM);
1630 if (LJ_DUALNUM) {
1631 dasm_put(Dst, 2546);
1632 } else {
1633 dasm_put(Dst, 2273);
1634 }
1635 dasm_put(Dst, 5972, Dt5(->len));
1636 if (LJ_DUALNUM) {
1637 dasm_put(Dst, 5982);
1638 } else if (sse) {
1639 dasm_put(Dst, 5986);
1640 } else {
1641 dasm_put(Dst, 5993);
1642 }
1643 dasm_put(Dst, 6005, sizeof(GCstr)-1);
1644 dasm_put(Dst, 6080, 2+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold));
1645 dasm_put(Dst, 6139, LJ_TSTR, LJ_TISNUM);
1646 if (LJ_DUALNUM) {
1647 dasm_put(Dst, 6156);
1648 } else if (sse) {
1649 dasm_put(Dst, 6164);
1650 } else {
1651 dasm_put(Dst, 6175);
1652 }
1653 dasm_put(Dst, 6191, Dt5(->len), DISPATCH_GL(tmpbuf.sz), Dt5([1]), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(tmpbuf.buf), 1+1);
1654 dasm_put(Dst, 6256, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
1655 dasm_put(Dst, 6319, 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz));
1656 dasm_put(Dst, 6390, sizeof(GCstr), DISPATCH_GL(tmpbuf.buf), 1+1);
1657 dasm_put(Dst, 6475, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
1658 dasm_put(Dst, 6545, 1+1, LJ_TTAB);
1659 if (LJ_DUALNUM) {
1660 dasm_put(Dst, 6613);
1661 } else if (sse) {
1662 dasm_put(Dst, 6620);
1663 } else {
1664 dasm_put(Dst, 6630);
1665 }
1666 dasm_put(Dst, 6641, 1+1, LJ_TISNUM);
1667 if (LJ_DUALNUM) {
1668 dasm_put(Dst, 6657);
1669 } else {
1670 dasm_put(Dst, 2273);
1671 }
1672 if (sse) {
1673 dasm_put(Dst, 6674);
1674 } else {
1675 dasm_put(Dst, 6703);
1676 }
1677 dasm_put(Dst, 111);
1678 if (LJ_DUALNUM || sse) {
1679 if (!sse) {
1680 dasm_put(Dst, 6721);
1681 }
1682 dasm_put(Dst, 6725);
1683 } else {
1684 dasm_put(Dst, 6633);
1685 }
1686 dasm_put(Dst, 6730, 1+1);
1687 if (sse) {
1688 dasm_put(Dst, 6741);
1689 } else {
1690 dasm_put(Dst, 6756);
1691 }
1692 dasm_put(Dst, 2250, LJ_TISNUM);
1693 if (LJ_DUALNUM) {
1694 dasm_put(Dst, 6765);
1695 } else {
1696 dasm_put(Dst, 2273);
1697 }
1698 if (sse) {
1699 dasm_put(Dst, 6782);
1700 } else {
1701 dasm_put(Dst, 6797);
1702 }
1703 dasm_put(Dst, 6810, LJ_TISNUM);
1704 if (LJ_DUALNUM) {
1705 dasm_put(Dst, 6835);
1706 } else {
1707 dasm_put(Dst, 6855);
1708 }
1709 if (sse) {
1710 dasm_put(Dst, 6860);
1711 } else {
1712 dasm_put(Dst, 6877);
1713 }
1714 dasm_put(Dst, 6890, 1+1);
1715 if (sse) {
1716 dasm_put(Dst, 6741);
1717 } else {
1718 dasm_put(Dst, 6756);
1719 }
1720 dasm_put(Dst, 2250, LJ_TISNUM);
1721 if (LJ_DUALNUM) {
1722 dasm_put(Dst, 6765);
1723 } else {
1724 dasm_put(Dst, 2273);
1725 }
1726 if (sse) {
1727 dasm_put(Dst, 6782);
1728 } else {
1729 dasm_put(Dst, 6797);
1730 }
1731 dasm_put(Dst, 6810, LJ_TISNUM);
1732 if (LJ_DUALNUM) {
1733 dasm_put(Dst, 6908);
1734 } else {
1735 dasm_put(Dst, 6855);
1736 }
1737 if (sse) {
1738 dasm_put(Dst, 6928);
1739 } else {
1740 dasm_put(Dst, 6945);
1741 }
1742 dasm_put(Dst, 6958, 1+1);
1743 if (sse) {
1744 dasm_put(Dst, 6741);
1745 } else {
1746 dasm_put(Dst, 6756);
1747 }
1748 dasm_put(Dst, 2250, LJ_TISNUM);
1749 if (LJ_DUALNUM) {
1750 dasm_put(Dst, 6765);
1751 } else {
1752 dasm_put(Dst, 2273);
1753 }
1754 if (sse) {
1755 dasm_put(Dst, 6782);
1756 } else {
1757 dasm_put(Dst, 6797);
1758 }
1759 dasm_put(Dst, 6810, LJ_TISNUM);
1760 if (LJ_DUALNUM) {
1761 dasm_put(Dst, 6976);
1762 } else {
1763 dasm_put(Dst, 6855);
1764 }
1765 if (sse) {
1766 dasm_put(Dst, 6996);
1767 } else {
1768 dasm_put(Dst, 7013);
1769 }
1770 dasm_put(Dst, 7026, 1+1, LJ_TISNUM);
1771 if (LJ_DUALNUM) {
1772 dasm_put(Dst, 6765);
1773 } else {
1774 dasm_put(Dst, 2273);
1775 }
1776 if (sse) {
1777 dasm_put(Dst, 6674);
1778 } else {
1779 dasm_put(Dst, 7049);
1780 }
1781 dasm_put(Dst, 7070, 1+1, LJ_TISNUM);
1782 if (LJ_DUALNUM) {
1783 dasm_put(Dst, 6765);
1784 } else {
1785 dasm_put(Dst, 2273);
1786 }
1787 if (sse) {
1788 dasm_put(Dst, 6674);
1789 } else {
1790 dasm_put(Dst, 7049);
1791 }
1792 dasm_put(Dst, 7094);
1793 if (LJ_DUALNUM) {
1794 dasm_put(Dst, 6725);
1795 } else if (sse) {
1796 dasm_put(Dst, 7100);
1797 } else {
1798 dasm_put(Dst, 7112);
1799 }
1800 dasm_put(Dst, 7125);
1801 if (LJ_DUALNUM) {
1802 dasm_put(Dst, 7136, 1+1, LJ_TISNUM);
1803 if (LJ_DUALNUM) {
1804 dasm_put(Dst, 6765);
1805 } else {
1806 dasm_put(Dst, 2273);
1807 }
1808 if (sse) {
1809 dasm_put(Dst, 6674);
1810 } else {
1811 dasm_put(Dst, 7049);
1812 }
1813 dasm_put(Dst, 7152, LJ_TISNUM);
1814 } else if (sse) {
1815 dasm_put(Dst, 7167, 2+1, LJ_TISNUM, LJ_TISNUM);
1816 } else {
1817 dasm_put(Dst, 7239, 2+1, LJ_TISNUM, LJ_TISNUM);
1818 }
1819 dasm_put(Dst, 7303);
1820 if (LJ_DUALNUM) {
1821 dasm_put(Dst, 7310, 1+1, LJ_TISNUM);
1822 if (LJ_DUALNUM) {
1823 dasm_put(Dst, 6765);
1824 } else {
1825 dasm_put(Dst, 2273);
1826 }
1827 if (sse) {
1828 dasm_put(Dst, 6674);
1829 } else {
1830 dasm_put(Dst, 7049);
1831 }
1832 dasm_put(Dst, 7152, LJ_TISNUM);
1833 } else if (sse) {
1834 dasm_put(Dst, 7326, 2+1, LJ_TISNUM, LJ_TISNUM);
1835 } else {
1836 dasm_put(Dst, 7398, 2+1, LJ_TISNUM, LJ_TISNUM);
1837 }
1838 dasm_put(Dst, 7462);
1839 if (LJ_DUALNUM) {
1840 dasm_put(Dst, 7470, 1+1, LJ_TISNUM);
1841 if (LJ_DUALNUM) {
1842 dasm_put(Dst, 6765);
1843 } else {
1844 dasm_put(Dst, 2273);
1845 }
1846 if (sse) {
1847 dasm_put(Dst, 6674);
1848 } else {
1849 dasm_put(Dst, 7049);
1850 }
1851 dasm_put(Dst, 7152, LJ_TISNUM);
1852 } else if (sse) {
1853 dasm_put(Dst, 7486, 2+1, LJ_TISNUM, LJ_TISNUM);
1854 } else {
1855 dasm_put(Dst, 7558, 2+1, LJ_TISNUM, LJ_TISNUM);
1856 }
1857 dasm_put(Dst, 7622);
1858 if (LJ_DUALNUM) {
1859 dasm_put(Dst, 7630, 1+1, LJ_TISNUM);
1860 if (LJ_DUALNUM) {
1861 dasm_put(Dst, 6765);
1862 } else {
1863 dasm_put(Dst, 2273);
1864 }
1865 if (sse) {
1866 dasm_put(Dst, 6674);
1867 } else {
1868 dasm_put(Dst, 7049);
1869 }
1870 dasm_put(Dst, 7152, LJ_TISNUM);
1871 } else if (sse) {
1872 dasm_put(Dst, 7646, 2+1, LJ_TISNUM, LJ_TISNUM);
1873 } else {
1874 dasm_put(Dst, 7718, 2+1, LJ_TISNUM, LJ_TISNUM);
1875 }
1876 dasm_put(Dst, 7782);
1877 if (LJ_DUALNUM) {
1878 dasm_put(Dst, 7789, 1+1, LJ_TISNUM);
1879 if (LJ_DUALNUM) {
1880 dasm_put(Dst, 6765);
1881 } else {
1882 dasm_put(Dst, 2273);
1883 }
1884 if (sse) {
1885 dasm_put(Dst, 6674);
1886 } else {
1887 dasm_put(Dst, 7049);
1888 }
1889 dasm_put(Dst, 7152, LJ_TISNUM);
1890 } else if (sse) {
1891 dasm_put(Dst, 7805, 2+1, LJ_TISNUM, LJ_TISNUM);
1892 } else {
1893 dasm_put(Dst, 7877, 2+1, LJ_TISNUM, LJ_TISNUM);
1894 }
1895 dasm_put(Dst, 7941, 1+2, 1+1, Dt1(->base), 8*LUA_MINSTACK, Dt1(->top), Dt1(->maxstack), Dt8(->f), Dt1(->base));
1896 dasm_put(Dst, 8017, Dt1(->top), Dt7(->pc), FRAME_TYPE, LUA_MINSTACK, Dt1(->base), Dt1(->base));
1897 dasm_put(Dst, 8141, Dt1(->top), Dt1(->base), Dt1(->top));
1898#if LJ_HASJIT
1899 dasm_put(Dst, 8179, DISPATCH_GL(hookmask), HOOK_VMEVENT, HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount));
1900#endif
1901 dasm_put(Dst, 8210, DISPATCH_GL(hookmask), HOOK_ACTIVE, DISPATCH_GL(hookmask), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount), LUA_MASKLINE);
1902 dasm_put(Dst, 8261, Dt1(->base), Dt1(->base), GG_DISP2STATIC);
1903#if LJ_HASJIT
1904 dasm_put(Dst, 8327, Dt7(->pc), PC2PROTO(framesize), Dt1(->base), Dt1(->top), GG_DISP2J, DISPATCH_J(L));
1905#endif
1906 dasm_put(Dst, 8373);
1907#if LJ_HASJIT
1908 dasm_put(Dst, 8205);
1909#endif
1910 dasm_put(Dst, 8380);
1911#if LJ_HASJIT
1912 dasm_put(Dst, 8383);
1913#endif
1914 dasm_put(Dst, 8393, Dt1(->base), Dt1(->top));
1915#if LJ_HASJIT
1916 dasm_put(Dst, 8427);
1917#endif
1918 dasm_put(Dst, 8432, Dt1(->base), Dt1(->top));
1919#if LJ_HASJIT
1920 dasm_put(Dst, 8461, DISPATCH_GL(vmstate), DISPATCH_GL(vmstate), ~LJ_VMST_EXIT, DISPATCH_J(exitno), DISPATCH_J(parent), 8*8+16, DISPATCH_GL(jit_L), DISPATCH_GL(jit_base), DISPATCH_J(L), DISPATCH_GL(jit_L), Dt1(->base), GG_DISP2J, Dt1(->cframe), CFRAME_RAWMASK, CFRAME_OFS_L, Dt1(->base), CFRAME_OFS_PC);
1921#endif
1922 dasm_put(Dst, 8604);
1923#if LJ_HASJIT
1924 dasm_put(Dst, 8607, Dt7(->pc), PC2PROTO(k), DISPATCH_GL(jit_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, BC_FUNCF);
1925#endif
1926 dasm_put(Dst, 8685);
1927 if (!sse) {
1928 dasm_put(Dst, 8688);
1929 }
1930 dasm_put(Dst, 8733);
1931 if (!sse) {
1932 dasm_put(Dst, 8835);
1933 }
1934 dasm_put(Dst, 8880);
1935 if (!sse) {
1936 dasm_put(Dst, 8982);
1937 }
1938 dasm_put(Dst, 9021);
1939 if (sse) {
1940 dasm_put(Dst, 9126);
1941 } else {
1942 dasm_put(Dst, 9256);
1943 }
1944 dasm_put(Dst, 9303);
1945 if (!sse) {
1946 dasm_put(Dst, 9377);
1947 if (cmov) {
1948 dasm_put(Dst, 9388);
1949 } else {
1950 dasm_put(Dst, 9392);
1951 }
1952 dasm_put(Dst, 9399);
1953 dasm_put(Dst, 9473);
1954 dasm_put(Dst, 9573);
1955 if (cmov) {
1956 dasm_put(Dst, 9576);
1957 } else {
1958 dasm_put(Dst, 9580);
1959 }
1960 dasm_put(Dst, 9587);
1961 if (cmov) {
1962 dasm_put(Dst, 9388);
1963 } else {
1964 dasm_put(Dst, 9392);
1965 }
1966 dasm_put(Dst, 9605);
1967 } else {
1968 dasm_put(Dst, 9684);
1969 }
1970 dasm_put(Dst, 9687);
1971 dasm_put(Dst, 9772);
1972 dasm_put(Dst, 9902);
1973 dasm_put(Dst, 10108);
1974#if LJ_HASJIT
1975 if (sse) {
1976 dasm_put(Dst, 10115);
1977 dasm_put(Dst, 10172);
1978 dasm_put(Dst, 10263);
1979 } else {
1980 dasm_put(Dst, 10305);
1981 dasm_put(Dst, 10397);
1982 }
1983 dasm_put(Dst, 10443);
1984#endif
1985 dasm_put(Dst, 10447);
1986 if (sse) {
1987 dasm_put(Dst, 10450);
1988 dasm_put(Dst, 10555);
1989 dasm_put(Dst, 10638);
1990 } else {
1991 dasm_put(Dst, 10710);
1992 dasm_put(Dst, 10793);
1993 if (cmov) {
1994 dasm_put(Dst, 10848);
1995 } else {
1996 dasm_put(Dst, 10867);
1997 }
1998 dasm_put(Dst, 10443);
1999 }
2000 dasm_put(Dst, 10908);
2001#ifdef LUA_USE_ASSERT
2002 dasm_put(Dst, 10445);
2003#endif
2004 dasm_put(Dst, 10964);
2005#if LJ_HASFFI
2006#define DtE(_V) (int)(ptrdiff_t)&(((CTState *)0)_V)
2007 dasm_put(Dst, 10968, GG_G2DISP, Dt2(->ctype_state), DtE(->cb.slot), CFRAME_SIZE+16, DtE(->cb.gpr[0]), DtE(->cb.gpr[1]), DtE(->cb.stack), CFRAME_SIZE+12, CFRAME_SIZE+8, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top), Dt7(->pc));
2008#endif
2009 dasm_put(Dst, 11078);
2010#if LJ_HASFFI
2011 dasm_put(Dst, 11081, DISPATCH_GL(ctype_state), DtE(->L), Dt1(->base), Dt1(->top), DtE(->cb.gpr[0]), DtE(->cb.gpr[1]), DtE(->cb.gpr[2]), DtE(->cb.fpr[0].d), DtE(->cb.fpr[0].f), Dt1(->top));
2012#endif
2013 dasm_put(Dst, 11170);
2014#if LJ_HASFFI
2015#define DtF(_V) (int)(ptrdiff_t)&(((CCallState *)0)_V)
2016 dasm_put(Dst, 11173, DtF(->spadj));
2017#if LJ_TARGET_WINDOWS
2018 dasm_put(Dst, 11183, DtF(->spadj));
2019#endif
2020 dasm_put(Dst, 11187, DtF(->nsp), offsetof(CCallState, stack), DtF(->gpr[0]), DtF(->gpr[1]), DtF(->func), DtF(->gpr[0]), DtF(->gpr[1]), DtF(->resx87), DtF(->fpr[0].d[0]));
2021 dasm_put(Dst, 11257, DtF(->fpr[0].f[0]));
2022#if LJ_TARGET_WINDOWS
2023 dasm_put(Dst, 11263, DtF(->spadj));
2024#endif
2025 dasm_put(Dst, 11267);
2026#endif
2027}
2028
2029/* Generate the code for a single instruction. */
2030static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse)
2031{
2032 int vk = 0;
2033 dasm_put(Dst, 11274, defop);
2034
2035 switch (op) {
2036
2037 /* -- Comparison ops ---------------------------------------------------- */
2038
2039 /* Remember: all ops branch for a true comparison, fall through otherwise. */
2040
2041
2042 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
2043 if (LJ_DUALNUM) {
2044 dasm_put(Dst, 11276, LJ_TISNUM, LJ_TISNUM);
2045 switch (op) {
2046 case BC_ISLT:
2047 dasm_put(Dst, 11306);
2048 break;
2049 case BC_ISGE:
2050 dasm_put(Dst, 11311);
2051 break;
2052 case BC_ISLE:
2053 dasm_put(Dst, 11316);
2054 break;
2055 case BC_ISGT:
2056 dasm_put(Dst, 11321);
2057 break;
2058 default: break; /* Shut up GCC. */
2059 }
2060 dasm_put(Dst, 11326, -BCBIAS_J*4, LJ_TISNUM);
2061 if (sse) {
2062 dasm_put(Dst, 11379);
2063 } else {
2064 dasm_put(Dst, 11390);
2065 }
2066 dasm_put(Dst, 11401);
2067 if (sse) {
2068 dasm_put(Dst, 11408);
2069 switch (op) {
2070 case BC_ISLT:
2071 dasm_put(Dst, 11428);
2072 break;
2073 case BC_ISGE:
2074 dasm_put(Dst, 11433);
2075 break;
2076 case BC_ISLE:
2077 dasm_put(Dst, 11438);
2078 break;
2079 case BC_ISGT:
2080 dasm_put(Dst, 11443);
2081 break;
2082 default: break; /* Shut up GCC. */
2083 }
2084 dasm_put(Dst, 11448);
2085 } else {
2086 dasm_put(Dst, 11453);
2087 }
2088 } else {
2089 dasm_put(Dst, 11461, LJ_TISNUM, LJ_TISNUM);
2090 }
2091 if (sse) {
2092 dasm_put(Dst, 11482);
2093 } else {
2094 dasm_put(Dst, 11503);
2095 if (cmov) {
2096 dasm_put(Dst, 3953);
2097 } else {
2098 dasm_put(Dst, 3959);
2099 }
2100 }
2101 if (LJ_DUALNUM) {
2102 switch (op) {
2103 case BC_ISLT:
2104 dasm_put(Dst, 11428);
2105 break;
2106 case BC_ISGE:
2107 dasm_put(Dst, 11433);
2108 break;
2109 case BC_ISLE:
2110 dasm_put(Dst, 11438);
2111 break;
2112 case BC_ISGT:
2113 dasm_put(Dst, 11443);
2114 break;
2115 default: break; /* Shut up GCC. */
2116 }
2117 dasm_put(Dst, 11448);
2118 } else {
2119 switch (op) {
2120 case BC_ISLT:
2121 dasm_put(Dst, 752);
2122 break;
2123 case BC_ISGE:
2124 dasm_put(Dst, 11519);
2125 break;
2126 case BC_ISLE:
2127 dasm_put(Dst, 11524);
2128 break;
2129 case BC_ISGT:
2130 dasm_put(Dst, 11529);
2131 break;
2132 default: break; /* Shut up GCC. */
2133 }
2134 dasm_put(Dst, 11534, -BCBIAS_J*4);
2135 }
2136 break;
2137
2138 case BC_ISEQV: case BC_ISNEV:
2139 vk = op == BC_ISEQV;
2140 dasm_put(Dst, 11565);
2141 if (LJ_DUALNUM) {
2142 dasm_put(Dst, 11573, LJ_TISNUM, LJ_TISNUM);
2143 if (vk) {
2144 dasm_put(Dst, 11598);
2145 } else {
2146 dasm_put(Dst, 11603);
2147 }
2148 dasm_put(Dst, 11608, -BCBIAS_J*4, LJ_TISNUM);
2149 if (sse) {
2150 dasm_put(Dst, 11659);
2151 } else {
2152 dasm_put(Dst, 11666);
2153 }
2154 dasm_put(Dst, 11670);
2155 if (sse) {
2156 dasm_put(Dst, 11681);
2157 } else {
2158 dasm_put(Dst, 11693);
2159 }
2160 dasm_put(Dst, 11700);
2161 } else {
2162 dasm_put(Dst, 11705, LJ_TISNUM, LJ_TISNUM);
2163 }
2164 if (sse) {
2165 dasm_put(Dst, 11724);
2166 } else {
2167 dasm_put(Dst, 11742);
2168 if (cmov) {
2169 dasm_put(Dst, 3953);
2170 } else {
2171 dasm_put(Dst, 3959);
2172 }
2173 }
2174 iseqne_fp:
2175 if (vk) {
2176 dasm_put(Dst, 11755);
2177 } else {
2178 dasm_put(Dst, 11764);
2179 }
2180 iseqne_end:
2181 if (vk) {
2182 dasm_put(Dst, 11773, -BCBIAS_J*4);
2183 if (!LJ_HASFFI) {
2184 dasm_put(Dst, 4853);
2185 }
2186 } else {
2187 if (!LJ_HASFFI) {
2188 dasm_put(Dst, 4853);
2189 }
2190 dasm_put(Dst, 11788, -BCBIAS_J*4);
2191 }
2192 if (LJ_DUALNUM && (op == BC_ISEQV || op == BC_ISNEV ||
2193 op == BC_ISEQN || op == BC_ISNEN)) {
2194 dasm_put(Dst, 11803);
2195 } else {
2196 dasm_put(Dst, 11546);
2197 }
2198 if (op == BC_ISEQV || op == BC_ISNEV) {
2199 dasm_put(Dst, 11808);
2200 if (LJ_HASFFI) {
2201 dasm_put(Dst, 11811, LJ_TCDATA, LJ_TCDATA);
2202 }
2203 dasm_put(Dst, 11830, LJ_TISPRI, LJ_TISTABUD, Dt6(->metatable), Dt6(->nomm), 1<<MM_eq);
2204 if (vk) {
2205 dasm_put(Dst, 11886);
2206 } else {
2207 dasm_put(Dst, 11890);
2208 }
2209 dasm_put(Dst, 11896);
2210 } else if (LJ_HASFFI) {
2211 dasm_put(Dst, 11901, LJ_TCDATA);
2212 if (LJ_DUALNUM && vk) {
2213 dasm_put(Dst, 11908);
2214 } else {
2215 dasm_put(Dst, 11881);
2216 }
2217 dasm_put(Dst, 11913);
2218 }
2219 break;
2220 case BC_ISEQS: case BC_ISNES:
2221 vk = op == BC_ISEQS;
2222 dasm_put(Dst, 11918, LJ_TSTR);
2223 iseqne_test:
2224 if (vk) {
2225 dasm_put(Dst, 11759);
2226 } else {
2227 dasm_put(Dst, 2971);
2228 }
2229 goto iseqne_end;
2230 case BC_ISEQN: case BC_ISNEN:
2231 vk = op == BC_ISEQN;
2232 dasm_put(Dst, 11943);
2233 if (LJ_DUALNUM) {
2234 dasm_put(Dst, 11951, LJ_TISNUM, LJ_TISNUM);
2235 if (vk) {
2236 dasm_put(Dst, 11598);
2237 } else {
2238 dasm_put(Dst, 11603);
2239 }
2240 dasm_put(Dst, 11976, -BCBIAS_J*4, LJ_TISNUM);
2241 if (sse) {
2242 dasm_put(Dst, 12023);
2243 } else {
2244 dasm_put(Dst, 12030);
2245 }
2246 dasm_put(Dst, 12034);
2247 if (sse) {
2248 dasm_put(Dst, 12041);
2249 } else {
2250 dasm_put(Dst, 12053);
2251 }
2252 dasm_put(Dst, 11700);
2253 } else {
2254 dasm_put(Dst, 12060, LJ_TISNUM);
2255 }
2256 if (sse) {
2257 dasm_put(Dst, 12069);
2258 } else {
2259 dasm_put(Dst, 12087);
2260 if (cmov) {
2261 dasm_put(Dst, 3953);
2262 } else {
2263 dasm_put(Dst, 3959);
2264 }
2265 }
2266 goto iseqne_fp;
2267 case BC_ISEQP: case BC_ISNEP:
2268 vk = op == BC_ISEQP;
2269 dasm_put(Dst, 12100);
2270 if (!LJ_HASFFI) goto iseqne_test;
2271 if (vk) {
2272 dasm_put(Dst, 12113, -BCBIAS_J*4, LJ_TCDATA);
2273 } else {
2274 dasm_put(Dst, 12162, LJ_TCDATA, -BCBIAS_J*4);
2275 }
2276 break;
2277
2278 /* -- Unary test and copy ops ------------------------------------------- */
2279
2280 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
2281 dasm_put(Dst, 12205, LJ_TISTRUECOND);
2282 if (op == BC_IST || op == BC_ISTC) {
2283 dasm_put(Dst, 11529);
2284 } else {
2285 dasm_put(Dst, 11524);
2286 }
2287 if (op == BC_ISTC || op == BC_ISFC) {
2288 dasm_put(Dst, 12217);
2289 }
2290 dasm_put(Dst, 11534, -BCBIAS_J*4);
2291 break;
2292
2293 /* -- Unary ops --------------------------------------------------------- */
2294
2295 case BC_MOV:
2296 dasm_put(Dst, 12228);
2297 break;
2298 case BC_NOT:
2299 dasm_put(Dst, 12261, LJ_TISTRUECOND, LJ_TTRUE);
2300 break;
2301 case BC_UNM:
2302 if (LJ_DUALNUM) {
2303 dasm_put(Dst, 12296, LJ_TISNUM, LJ_TISNUM);
2304 } else {
2305 dasm_put(Dst, 12372, LJ_TISNUM);
2306 }
2307 if (sse) {
2308 dasm_put(Dst, 12383);
2309 } else {
2310 dasm_put(Dst, 12413);
2311 }
2312 if (LJ_DUALNUM) {
2313 dasm_put(Dst, 11803);
2314 } else {
2315 dasm_put(Dst, 11546);
2316 }
2317 break;
2318 case BC_LEN:
2319 dasm_put(Dst, 12422, LJ_TSTR);
2320 if (LJ_DUALNUM) {
2321 dasm_put(Dst, 12436, Dt5(->len), LJ_TISNUM);
2322 } else if (sse) {
2323 dasm_put(Dst, 12450, Dt5(->len));
2324 } else {
2325 dasm_put(Dst, 12468, Dt5(->len));
2326 }
2327 dasm_put(Dst, 12477, LJ_TTAB);
2328#ifdef LUAJIT_ENABLE_LUA52COMPAT
2329 dasm_put(Dst, 12511, Dt6(->metatable));
2330#endif
2331 dasm_put(Dst, 12525);
2332 if (LJ_DUALNUM) {
2333 } else if (sse) {
2334 dasm_put(Dst, 12534);
2335 } else {
2336 dasm_put(Dst, 12540);
2337 }
2338 dasm_put(Dst, 12547);
2339#ifdef LUAJIT_ENABLE_LUA52COMPAT
2340 dasm_put(Dst, 12560, Dt6(->nomm), 1<<MM_len);
2341#endif
2342 break;
2343
2344 /* -- Binary ops -------------------------------------------------------- */
2345
2346
2347 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
2348 if (LJ_DUALNUM) {
2349 dasm_put(Dst, 12576);
2350 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2351 switch (vk) {
2352 case 0:
2353 dasm_put(Dst, 12584, LJ_TISNUM, LJ_TISNUM);
2354 break;
2355 case 1:
2356 dasm_put(Dst, 12617, LJ_TISNUM, LJ_TISNUM);
2357 break;
2358 default:
2359 dasm_put(Dst, 12650, LJ_TISNUM, LJ_TISNUM);
2360 break;
2361 }
2362 dasm_put(Dst, 12683, LJ_TISNUM);
2363 if (vk == 1) {
2364 dasm_put(Dst, 12446);
2365 } else {
2366 dasm_put(Dst, 12224);
2367 }
2368 dasm_put(Dst, 11546);
2369 } else {
2370 dasm_put(Dst, 12576);
2371 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2372 switch (vk) {
2373 case 0:
2374 dasm_put(Dst, 12689, LJ_TISNUM);
2375 if (LJ_DUALNUM) {
2376 dasm_put(Dst, 12701, LJ_TISNUM);
2377 }
2378 if (sse) {
2379 dasm_put(Dst, 12712);
2380 } else {
2381 dasm_put(Dst, 12726);
2382 }
2383 break;
2384 case 1:
2385 dasm_put(Dst, 12734, LJ_TISNUM);
2386 if (LJ_DUALNUM) {
2387 dasm_put(Dst, 12746, LJ_TISNUM);
2388 }
2389 if (sse) {
2390 dasm_put(Dst, 12757);
2391 } else {
2392 dasm_put(Dst, 12771);
2393 }
2394 break;
2395 default:
2396 dasm_put(Dst, 12779, LJ_TISNUM, LJ_TISNUM);
2397 if (sse) {
2398 dasm_put(Dst, 12801);
2399 } else {
2400 dasm_put(Dst, 12815);
2401 }
2402 break;
2403 }
2404 if (sse) {
2405 dasm_put(Dst, 12406);
2406 } else {
2407 dasm_put(Dst, 12418);
2408 }
2409 dasm_put(Dst, 11546);
2410 }
2411 break;
2412 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
2413 if (LJ_DUALNUM) {
2414 dasm_put(Dst, 12576);
2415 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2416 switch (vk) {
2417 case 0:
2418 dasm_put(Dst, 12823, LJ_TISNUM, LJ_TISNUM);
2419 break;
2420 case 1:
2421 dasm_put(Dst, 12856, LJ_TISNUM, LJ_TISNUM);
2422 break;
2423 default:
2424 dasm_put(Dst, 12889, LJ_TISNUM, LJ_TISNUM);
2425 break;
2426 }
2427 dasm_put(Dst, 12683, LJ_TISNUM);
2428 if (vk == 1) {
2429 dasm_put(Dst, 12446);
2430 } else {
2431 dasm_put(Dst, 12224);
2432 }
2433 dasm_put(Dst, 11546);
2434 } else {
2435 dasm_put(Dst, 12576);
2436 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2437 switch (vk) {
2438 case 0:
2439 dasm_put(Dst, 12689, LJ_TISNUM);
2440 if (LJ_DUALNUM) {
2441 dasm_put(Dst, 12701, LJ_TISNUM);
2442 }
2443 if (sse) {
2444 dasm_put(Dst, 12922);
2445 } else {
2446 dasm_put(Dst, 12936);
2447 }
2448 break;
2449 case 1:
2450 dasm_put(Dst, 12734, LJ_TISNUM);
2451 if (LJ_DUALNUM) {
2452 dasm_put(Dst, 12746, LJ_TISNUM);
2453 }
2454 if (sse) {
2455 dasm_put(Dst, 12944);
2456 } else {
2457 dasm_put(Dst, 12958);
2458 }
2459 break;
2460 default:
2461 dasm_put(Dst, 12779, LJ_TISNUM, LJ_TISNUM);
2462 if (sse) {
2463 dasm_put(Dst, 12966);
2464 } else {
2465 dasm_put(Dst, 12980);
2466 }
2467 break;
2468 }
2469 if (sse) {
2470 dasm_put(Dst, 12406);
2471 } else {
2472 dasm_put(Dst, 12418);
2473 }
2474 dasm_put(Dst, 11546);
2475 }
2476 break;
2477 case BC_MULVN: case BC_MULNV: case BC_MULVV:
2478 if (LJ_DUALNUM) {
2479 dasm_put(Dst, 12576);
2480 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2481 switch (vk) {
2482 case 0:
2483 dasm_put(Dst, 12988, LJ_TISNUM, LJ_TISNUM);
2484 break;
2485 case 1:
2486 dasm_put(Dst, 13022, LJ_TISNUM, LJ_TISNUM);
2487 break;
2488 default:
2489 dasm_put(Dst, 13056, LJ_TISNUM, LJ_TISNUM);
2490 break;
2491 }
2492 dasm_put(Dst, 12683, LJ_TISNUM);
2493 if (vk == 1) {
2494 dasm_put(Dst, 12446);
2495 } else {
2496 dasm_put(Dst, 12224);
2497 }
2498 dasm_put(Dst, 11546);
2499 } else {
2500 dasm_put(Dst, 12576);
2501 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2502 switch (vk) {
2503 case 0:
2504 dasm_put(Dst, 12689, LJ_TISNUM);
2505 if (LJ_DUALNUM) {
2506 dasm_put(Dst, 12701, LJ_TISNUM);
2507 }
2508 if (sse) {
2509 dasm_put(Dst, 13090);
2510 } else {
2511 dasm_put(Dst, 13104);
2512 }
2513 break;
2514 case 1:
2515 dasm_put(Dst, 12734, LJ_TISNUM);
2516 if (LJ_DUALNUM) {
2517 dasm_put(Dst, 12746, LJ_TISNUM);
2518 }
2519 if (sse) {
2520 dasm_put(Dst, 13112);
2521 } else {
2522 dasm_put(Dst, 13126);
2523 }
2524 break;
2525 default:
2526 dasm_put(Dst, 12779, LJ_TISNUM, LJ_TISNUM);
2527 if (sse) {
2528 dasm_put(Dst, 13134);
2529 } else {
2530 dasm_put(Dst, 13148);
2531 }
2532 break;
2533 }
2534 if (sse) {
2535 dasm_put(Dst, 12406);
2536 } else {
2537 dasm_put(Dst, 12418);
2538 }
2539 dasm_put(Dst, 11546);
2540 }
2541 break;
2542 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
2543 dasm_put(Dst, 12576);
2544 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2545 switch (vk) {
2546 case 0:
2547 dasm_put(Dst, 12689, LJ_TISNUM);
2548 if (LJ_DUALNUM) {
2549 dasm_put(Dst, 12701, LJ_TISNUM);
2550 }
2551 if (sse) {
2552 dasm_put(Dst, 13156);
2553 } else {
2554 dasm_put(Dst, 13170);
2555 }
2556 break;
2557 case 1:
2558 dasm_put(Dst, 12734, LJ_TISNUM);
2559 if (LJ_DUALNUM) {
2560 dasm_put(Dst, 12746, LJ_TISNUM);
2561 }
2562 if (sse) {
2563 dasm_put(Dst, 13178);
2564 } else {
2565 dasm_put(Dst, 13192);
2566 }
2567 break;
2568 default:
2569 dasm_put(Dst, 12779, LJ_TISNUM, LJ_TISNUM);
2570 if (sse) {
2571 dasm_put(Dst, 13200);
2572 } else {
2573 dasm_put(Dst, 13214);
2574 }
2575 break;
2576 }
2577 if (sse) {
2578 dasm_put(Dst, 12406);
2579 } else {
2580 dasm_put(Dst, 12418);
2581 }
2582 dasm_put(Dst, 11546);
2583 break;
2584 case BC_MODVN:
2585 dasm_put(Dst, 12576);
2586 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2587 switch (vk) {
2588 case 0:
2589 dasm_put(Dst, 12689, LJ_TISNUM);
2590 if (LJ_DUALNUM) {
2591 dasm_put(Dst, 12701, LJ_TISNUM);
2592 }
2593 if (sse) {
2594 dasm_put(Dst, 13222);
2595 } else {
2596 dasm_put(Dst, 13236);
2597 }
2598 break;
2599 case 1:
2600 dasm_put(Dst, 12734, LJ_TISNUM);
2601 if (LJ_DUALNUM) {
2602 dasm_put(Dst, 12746, LJ_TISNUM);
2603 }
2604 if (sse) {
2605 dasm_put(Dst, 13244);
2606 } else {
2607 dasm_put(Dst, 13258);
2608 }
2609 break;
2610 default:
2611 dasm_put(Dst, 12779, LJ_TISNUM, LJ_TISNUM);
2612 if (sse) {
2613 dasm_put(Dst, 13266);
2614 } else {
2615 dasm_put(Dst, 13280);
2616 }
2617 break;
2618 }
2619 dasm_put(Dst, 13288);
2620 if (sse) {
2621 dasm_put(Dst, 12406);
2622 } else {
2623 dasm_put(Dst, 12418);
2624 }
2625 dasm_put(Dst, 11546);
2626 break;
2627 case BC_MODNV: case BC_MODVV:
2628 dasm_put(Dst, 12576);
2629 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2630 switch (vk) {
2631 case 0:
2632 dasm_put(Dst, 12689, LJ_TISNUM);
2633 if (LJ_DUALNUM) {
2634 dasm_put(Dst, 12701, LJ_TISNUM);
2635 }
2636 if (sse) {
2637 dasm_put(Dst, 13222);
2638 } else {
2639 dasm_put(Dst, 13236);
2640 }
2641 break;
2642 case 1:
2643 dasm_put(Dst, 12734, LJ_TISNUM);
2644 if (LJ_DUALNUM) {
2645 dasm_put(Dst, 12746, LJ_TISNUM);
2646 }
2647 if (sse) {
2648 dasm_put(Dst, 13244);
2649 } else {
2650 dasm_put(Dst, 13258);
2651 }
2652 break;
2653 default:
2654 dasm_put(Dst, 12779, LJ_TISNUM, LJ_TISNUM);
2655 if (sse) {
2656 dasm_put(Dst, 13266);
2657 } else {
2658 dasm_put(Dst, 13280);
2659 }
2660 break;
2661 }
2662 dasm_put(Dst, 13294);
2663 break;
2664 case BC_POW:
2665 dasm_put(Dst, 12576);
2666 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
2667 switch (vk) {
2668 case 0:
2669 dasm_put(Dst, 12689, LJ_TISNUM);
2670 if (LJ_DUALNUM) {
2671 dasm_put(Dst, 12701, LJ_TISNUM);
2672 }
2673 if (sse) {
2674 dasm_put(Dst, 13222);
2675 } else {
2676 dasm_put(Dst, 13236);
2677 }
2678 break;
2679 case 1:
2680 dasm_put(Dst, 12734, LJ_TISNUM);
2681 if (LJ_DUALNUM) {
2682 dasm_put(Dst, 12746, LJ_TISNUM);
2683 }
2684 if (sse) {
2685 dasm_put(Dst, 13244);
2686 } else {
2687 dasm_put(Dst, 13258);
2688 }
2689 break;
2690 default:
2691 dasm_put(Dst, 12779, LJ_TISNUM, LJ_TISNUM);
2692 if (sse) {
2693 dasm_put(Dst, 13266);
2694 } else {
2695 dasm_put(Dst, 13280);
2696 }
2697 break;
2698 }
2699 dasm_put(Dst, 13299);
2700 if (sse) {
2701 dasm_put(Dst, 12406);
2702 } else {
2703 dasm_put(Dst, 12418);
2704 }
2705 dasm_put(Dst, 11546);
2706 break;
2707
2708 case BC_CAT:
2709 dasm_put(Dst, 13303, Dt1(->base), Dt1(->base));
2710 break;
2711
2712 /* -- Constant ops ------------------------------------------------------ */
2713
2714 case BC_KSTR:
2715 dasm_put(Dst, 13397, LJ_TSTR);
2716 break;
2717 case BC_KCDATA:
2718#if LJ_HASFFI
2719 dasm_put(Dst, 13397, LJ_TCDATA);
2720#endif
2721 break;
2722 case BC_KSHORT:
2723 if (LJ_DUALNUM) {
2724 dasm_put(Dst, 13430, LJ_TISNUM);
2725 } else if (sse) {
2726 dasm_put(Dst, 13442);
2727 } else {
2728 dasm_put(Dst, 13457);
2729 }
2730 dasm_put(Dst, 11546);
2731 break;
2732 case BC_KNUM:
2733 if (sse) {
2734 dasm_put(Dst, 13465);
2735 } else {
2736 dasm_put(Dst, 13478);
2737 }
2738 dasm_put(Dst, 11546);
2739 break;
2740 case BC_KPRI:
2741 dasm_put(Dst, 13485);
2742 break;
2743 case BC_KNIL:
2744 dasm_put(Dst, 13511, LJ_TNIL);
2745 break;
2746
2747 /* -- Upvalue and function ops ------------------------------------------ */
2748
2749 case BC_UGET:
2750 dasm_put(Dst, 13557, offsetof(GCfuncL, uvptr), DtA(->v));
2751 break;
2752 case BC_USETV:
2753#define TV2MARKOFS \
2754 ((int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv))
2755 dasm_put(Dst, 13601, offsetof(GCfuncL, uvptr), DtA(->closed), DtA(->v), TV2MARKOFS, LJ_GC_BLACK, LJ_TISGCV, LJ_TISNUM - LJ_TISGCV, Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
2756 dasm_put(Dst, 13691);
2757 break;
2758#undef TV2MARKOFS
2759 case BC_USETS:
2760 dasm_put(Dst, 13703, offsetof(GCfuncL, uvptr), DtA(->v), LJ_TSTR, DtA(->marked), LJ_GC_BLACK, Dt4(->gch.marked), LJ_GC_WHITES, DtA(->closed), GG_DISP2G);
2761 break;
2762 case BC_USETN:
2763 dasm_put(Dst, 13794);
2764 if (sse) {
2765 dasm_put(Dst, 13799);
2766 } else {
2767 dasm_put(Dst, 12056);
2768 }
2769 dasm_put(Dst, 13806, offsetof(GCfuncL, uvptr), DtA(->v));
2770 if (sse) {
2771 dasm_put(Dst, 13815);
2772 } else {
2773 dasm_put(Dst, 13821);
2774 }
2775 dasm_put(Dst, 11546);
2776 break;
2777 case BC_USETP:
2778 dasm_put(Dst, 13824, offsetof(GCfuncL, uvptr), DtA(->v));
2779 break;
2780 case BC_UCLO:
2781 dasm_put(Dst, 13861, -BCBIAS_J*4, Dt1(->openupval), Dt1(->base), Dt1(->base));
2782 break;
2783
2784 case BC_FNEW:
2785 dasm_put(Dst, 13915, Dt1(->base), Dt1(->base), LJ_TFUNC);
2786 break;
2787
2788 /* -- Table ops --------------------------------------------------------- */
2789
2790 case BC_TNEW:
2791 dasm_put(Dst, 13986, Dt1(->base), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), LJ_TTAB);
2792 break;
2793 case BC_TDUP:
2794 dasm_put(Dst, 14112, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), Dt1(->base), LJ_TTAB);
2795 break;
2796
2797 case BC_GGET:
2798 dasm_put(Dst, 14204, Dt7(->env));
2799 break;
2800 case BC_GSET:
2801 dasm_put(Dst, 14222, Dt7(->env));
2802 break;
2803
2804 case BC_TGETV:
2805 dasm_put(Dst, 14240, LJ_TTAB);
2806 if (LJ_DUALNUM) {
2807 dasm_put(Dst, 14263, LJ_TISNUM);
2808 } else {
2809 dasm_put(Dst, 14277, LJ_TISNUM);
2810 if (sse) {
2811 dasm_put(Dst, 14288);
2812 } else {
2813 dasm_put(Dst, 14309);
2814 if (cmov) {
2815 dasm_put(Dst, 3953);
2816 } else {
2817 dasm_put(Dst, 3959);
2818 }
2819 dasm_put(Dst, 2689);
2820 }
2821 dasm_put(Dst, 14319);
2822 }
2823 dasm_put(Dst, 14324, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index, LJ_TNIL);
2824 dasm_put(Dst, 14419, LJ_TSTR);
2825 break;
2826 case BC_TGETS:
2827 dasm_put(Dst, 14437, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
2828 dasm_put(Dst, 14525, LJ_TNIL, DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
2829 break;
2830 case BC_TGETB:
2831 dasm_put(Dst, 14595, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
2832 dasm_put(Dst, 14694, LJ_TNIL);
2833 break;
2834
2835 case BC_TSETV:
2836 dasm_put(Dst, 14711, LJ_TTAB);
2837 if (LJ_DUALNUM) {
2838 dasm_put(Dst, 14263, LJ_TISNUM);
2839 } else {
2840 dasm_put(Dst, 14277, LJ_TISNUM);
2841 if (sse) {
2842 dasm_put(Dst, 14288);
2843 } else {
2844 dasm_put(Dst, 14309);
2845 if (cmov) {
2846 dasm_put(Dst, 3953);
2847 } else {
2848 dasm_put(Dst, 3959);
2849 }
2850 dasm_put(Dst, 2689);
2851 }
2852 dasm_put(Dst, 14734);
2853 }
2854 dasm_put(Dst, 14739, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex);
2855 dasm_put(Dst, 14823, LJ_TSTR, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2856 break;
2857 case BC_TSETS:
2858 dasm_put(Dst, 14880, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->nomm), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
2859 dasm_put(Dst, 14955, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DtB(->next));
2860 dasm_put(Dst, 15047, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, LJ_TSTR, Dt1(->base), Dt1(->base), Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2861 break;
2862 case BC_TSETB:
2863 dasm_put(Dst, 15143, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable));
2864 dasm_put(Dst, 15241, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2865 break;
2866
2867 case BC_TSETM:
2868 dasm_put(Dst, 15287, Dt6(->marked), LJ_GC_BLACK, Dt6(->asize), Dt6(->array), Dt1(->base), Dt1(->base));
2869 dasm_put(Dst, 15436, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
2870 break;
2871
2872 /* -- Calls and vararg handling ----------------------------------------- */
2873
2874 case BC_CALL: case BC_CALLM:
2875 dasm_put(Dst, 12580);
2876 if (op == BC_CALLM) {
2877 dasm_put(Dst, 15454);
2878 }
2879 dasm_put(Dst, 15459, LJ_TFUNC, Dt7(->pc));
2880 break;
2881
2882 case BC_CALLMT:
2883 dasm_put(Dst, 15454);
2884 break;
2885 case BC_CALLT:
2886 dasm_put(Dst, 15500, LJ_TFUNC, FRAME_TYPE, Dt7(->ffid), Dt7(->pc));
2887 dasm_put(Dst, 15618, FRAME_TYPE, Dt7(->pc), PC2PROTO(k), FRAME_VARG, FRAME_TYPEP, FRAME_VARG);
2888 break;
2889
2890 case BC_ITERC:
2891 dasm_put(Dst, 15688, LJ_TFUNC, 2+1, Dt7(->pc));
2892 break;
2893
2894 case BC_ITERN:
2895#if LJ_HASJIT
2896#endif
2897 dasm_put(Dst, 15768, Dt6(->asize), Dt6(->array), LJ_TNIL);
2898 if (LJ_DUALNUM) {
2899 dasm_put(Dst, 12441, LJ_TISNUM);
2900 } else if (sse) {
2901 dasm_put(Dst, 12534);
2902 } else {
2903 dasm_put(Dst, 15814);
2904 }
2905 dasm_put(Dst, 15820);
2906 if (LJ_DUALNUM) {
2907 } else if (sse) {
2908 dasm_put(Dst, 12406);
2909 } else {
2910 dasm_put(Dst, 12418);
2911 }
2912 dasm_put(Dst, 15839, -BCBIAS_J*4);
2913 if (!LJ_DUALNUM && !sse) {
2914 dasm_put(Dst, 15890);
2915 }
2916 dasm_put(Dst, 15896, Dt6(->hmask), sizeof(Node), Dt6(->node), DtB(->val.it), LJ_TNIL, DtB(->key.gcr), DtB(->key.it), DtB(->val.gcr), DtB(->val.it));
2917 dasm_put(Dst, 15971);
2918 break;
2919
2920 case BC_ISNEXT:
2921 dasm_put(Dst, 15979, LJ_TFUNC, LJ_TTAB, LJ_TNIL, Dt8(->ffid), FF_next_N, -BCBIAS_J*4, BC_JMP, -BCBIAS_J*4, BC_ITERC);
2922 break;
2923
2924 case BC_VARG:
2925 dasm_put(Dst, 16078, (8+FRAME_VARG), LJ_TNIL, Dt1(->maxstack));
2926 dasm_put(Dst, 16242, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
2927 break;
2928
2929 /* -- Returns ----------------------------------------------------------- */
2930
2931 case BC_RETM:
2932 dasm_put(Dst, 15454);
2933 break;
2934
2935 case BC_RET: case BC_RET0: case BC_RET1:
2936 if (op != BC_RET0) {
2937 dasm_put(Dst, 16313);
2938 }
2939 dasm_put(Dst, 16317, FRAME_TYPE);
2940 switch (op) {
2941 case BC_RET:
2942 dasm_put(Dst, 16336);
2943 break;
2944 case BC_RET1:
2945 dasm_put(Dst, 16394);
2946 /* fallthrough */
2947 case BC_RET0:
2948 dasm_put(Dst, 16410);
2949 default:
2950 break;
2951 }
2952 dasm_put(Dst, 16421, Dt7(->pc), PC2PROTO(k));
2953 if (op == BC_RET) {
2954 dasm_put(Dst, 16463, LJ_TNIL);
2955 } else {
2956 dasm_put(Dst, 16472, LJ_TNIL);
2957 }
2958 dasm_put(Dst, 16479, -FRAME_VARG, FRAME_TYPEP);
2959 if (op != BC_RET0) {
2960 dasm_put(Dst, 16503);
2961 }
2962 dasm_put(Dst, 4937);
2963 break;
2964
2965 /* -- Loops and branches ------------------------------------------------ */
2966
2967
2968 case BC_FORL:
2969#if LJ_HASJIT
2970 dasm_put(Dst, 16507, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
2971#endif
2972 break;
2973
2974 case BC_JFORI:
2975 case BC_JFORL:
2976#if !LJ_HASJIT
2977 break;
2978#endif
2979 case BC_FORI:
2980 case BC_IFORL:
2981 vk = (op == BC_IFORL || op == BC_JFORL);
2982 dasm_put(Dst, 16528);
2983 if (LJ_DUALNUM) {
2984 dasm_put(Dst, 16532, LJ_TISNUM);
2985 if (!vk) {
2986 dasm_put(Dst, 16542, LJ_TISNUM, LJ_TISNUM);
2987 } else {
2988#ifdef LUA_USE_ASSERT
2989 dasm_put(Dst, 16571, LJ_TISNUM, LJ_TISNUM);
2990#endif
2991 dasm_put(Dst, 16590);
2992 }
2993 dasm_put(Dst, 16609, LJ_TISNUM);
2994 if (op == BC_FORI) {
2995 dasm_put(Dst, 16620, -BCBIAS_J*4);
2996 } else if (op == BC_JFORI) {
2997 dasm_put(Dst, 16634, -BCBIAS_J*4, BC_JLOOP);
2998 } else if (op == BC_IFORL) {
2999 dasm_put(Dst, 16652, -BCBIAS_J*4);
3000 } else {
3001 dasm_put(Dst, 16644, BC_JLOOP);
3002 }
3003 dasm_put(Dst, 16666);
3004 if (vk) {
3005 dasm_put(Dst, 16689);
3006 }
3007 dasm_put(Dst, 16609, LJ_TISNUM);
3008 if (op == BC_FORI) {
3009 dasm_put(Dst, 16698);
3010 } else if (op == BC_JFORI) {
3011 dasm_put(Dst, 16703, -BCBIAS_J*4, BC_JLOOP);
3012 } else if (op == BC_IFORL) {
3013 dasm_put(Dst, 16717);
3014 } else {
3015 dasm_put(Dst, 16713, BC_JLOOP);
3016 }
3017 dasm_put(Dst, 16722);
3018 } else if (!vk) {
3019 dasm_put(Dst, 16729, LJ_TISNUM);
3020 }
3021 if (!vk) {
3022 dasm_put(Dst, 16735, LJ_TISNUM);
3023 } else {
3024#ifdef LUA_USE_ASSERT
3025 dasm_put(Dst, 16749, LJ_TISNUM, LJ_TISNUM);
3026#endif
3027 }
3028 dasm_put(Dst, 16768);
3029 if (!vk) {
3030 dasm_put(Dst, 16772, LJ_TISNUM);
3031 }
3032 if (sse) {
3033 dasm_put(Dst, 16781);
3034 if (vk) {
3035 dasm_put(Dst, 16793);
3036 } else {
3037 dasm_put(Dst, 16812);
3038 }
3039 dasm_put(Dst, 16817);
3040 } else {
3041 dasm_put(Dst, 16830);
3042 if (vk) {
3043 dasm_put(Dst, 16836);
3044 } else {
3045 dasm_put(Dst, 16852);
3046 }
3047 dasm_put(Dst, 16860);
3048 if (cmov) {
3049 dasm_put(Dst, 3953);
3050 } else {
3051 dasm_put(Dst, 3959);
3052 }
3053 if (!cmov) {
3054 dasm_put(Dst, 16865);
3055 }
3056 }
3057 if (op == BC_FORI) {
3058 if (LJ_DUALNUM) {
3059 dasm_put(Dst, 16871);
3060 } else {
3061 dasm_put(Dst, 16876, -BCBIAS_J*4);
3062 }
3063 } else if (op == BC_JFORI) {
3064 dasm_put(Dst, 16886, -BCBIAS_J*4, BC_JLOOP);
3065 } else if (op == BC_IFORL) {
3066 if (LJ_DUALNUM) {
3067 dasm_put(Dst, 16900);
3068 } else {
3069 dasm_put(Dst, 16905, -BCBIAS_J*4);
3070 }
3071 } else {
3072 dasm_put(Dst, 16896, BC_JLOOP);
3073 }
3074 if (LJ_DUALNUM) {
3075 dasm_put(Dst, 11448);
3076 } else {
3077 dasm_put(Dst, 12184);
3078 }
3079 if (sse) {
3080 dasm_put(Dst, 16915);
3081 }
3082 break;
3083
3084 case BC_ITERL:
3085#if LJ_HASJIT
3086 dasm_put(Dst, 16507, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
3087#endif
3088 break;
3089
3090 case BC_JITERL:
3091#if !LJ_HASJIT
3092 break;
3093#endif
3094 case BC_IITERL:
3095 dasm_put(Dst, 16926, LJ_TNIL);
3096 if (op == BC_JITERL) {
3097 dasm_put(Dst, 16941, BC_JLOOP);
3098 } else {
3099 dasm_put(Dst, 16955, -BCBIAS_J*4);
3100 }
3101 dasm_put(Dst, 11544);
3102 break;
3103
3104 case BC_LOOP:
3105#if LJ_HASJIT
3106 dasm_put(Dst, 16507, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
3107#endif
3108 break;
3109
3110 case BC_ILOOP:
3111 dasm_put(Dst, 11546);
3112 break;
3113
3114 case BC_JLOOP:
3115#if LJ_HASJIT
3116 dasm_put(Dst, 16971, DISPATCH_J(trace), DtD(->mcode), DISPATCH_GL(jit_base), DISPATCH_GL(jit_L));
3117#endif
3118 break;
3119
3120 case BC_JMP:
3121 dasm_put(Dst, 16994, -BCBIAS_J*4);
3122 break;
3123
3124 /* -- Function headers -------------------------------------------------- */
3125
3126 /*
3127 ** Reminder: A function may be called with func/args above L->maxstack,
3128 ** i.e. occupying EXTRA_STACK slots. And vmeta_call may add one extra slot,
3129 ** too. This means all FUNC* ops (including fast functions) must check
3130 ** for stack overflow _before_ adding more slots!
3131 */
3132
3133 case BC_FUNCF:
3134#if LJ_HASJIT
3135 dasm_put(Dst, 17018, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_CALL);
3136#endif
3137 case BC_FUNCV: /* NYI: compiled vararg functions. */
3138 break;
3139
3140 case BC_JFUNCF:
3141#if !LJ_HASJIT
3142 break;
3143#endif
3144 case BC_IFUNCF:
3145 dasm_put(Dst, 17039, -4+PC2PROTO(k), Dt1(->maxstack), -4+PC2PROTO(numparams));
3146 if (op == BC_JFUNCF) {
3147 dasm_put(Dst, 17069, BC_JLOOP);
3148 } else {
3149 dasm_put(Dst, 11546);
3150 }
3151 dasm_put(Dst, 17078, LJ_TNIL);
3152 break;
3153
3154 case BC_JFUNCV:
3155#if !LJ_HASJIT
3156 break;
3157#endif
3158 dasm_put(Dst, 10445);
3159 break; /* NYI: compiled vararg functions. */
3160
3161 case BC_IFUNCV:
3162 dasm_put(Dst, 17100, FRAME_VARG, Dt1(->maxstack), -4+PC2PROTO(numparams), LJ_TNIL);
3163 if (op == BC_JFUNCV) {
3164 dasm_put(Dst, 17069, BC_JLOOP);
3165 } else {
3166 dasm_put(Dst, 17191, -4+PC2PROTO(k));
3167 }
3168 dasm_put(Dst, 17213, LJ_TNIL);
3169 break;
3170
3171 case BC_FUNCC:
3172 case BC_FUNCCW:
3173 dasm_put(Dst, 17235, Dt8(->f), Dt1(->base), 8*LUA_MINSTACK, Dt1(->maxstack), Dt1(->top));
3174 if (op == BC_FUNCC) {
3175 dasm_put(Dst, 17264);
3176 } else {
3177 dasm_put(Dst, 17268);
3178 }
3179 dasm_put(Dst, 17276, DISPATCH_GL(vmstate), ~LJ_VMST_C);
3180 if (op == BC_FUNCC) {
3181 dasm_put(Dst, 17285);
3182 } else {
3183 dasm_put(Dst, 17289, DISPATCH_GL(wrapf));
3184 }
3185 dasm_put(Dst, 17294, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top));
3186 break;
3187
3188 /* ---------------------------------------------------------------------- */
3189
3190 default:
3191 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
3192 exit(2);
3193 break;
3194 }
3195}
3196
3197static int build_backend(BuildCtx *ctx)
3198{
3199 int op;
3200 int cmov = 1;
3201 int sse = 0;
3202#ifdef LUAJIT_CPU_NOCMOV
3203 cmov = 0;
3204#endif
3205#if defined(LUAJIT_CPU_SSE2) || defined(LJ_TARGET_X64)
3206 sse = 1;
3207#endif
3208
3209 dasm_growpc(Dst, BC__MAX);
3210
3211 build_subroutines(ctx, cmov, sse);
3212
3213 dasm_put(Dst, 17319);
3214 for (op = 0; op < BC__MAX; op++)
3215 build_ins(ctx, (BCOp)op, op, cmov, sse);
3216
3217 return BC__MAX;
3218}
3219
3220/* Emit pseudo frame-info for all assembler functions. */
3221static void emit_asm_debug(BuildCtx *ctx)
3222{
3223 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
3224#if LJ_64
3225#define SZPTR "8"
3226#define BSZPTR "3"
3227#define REG_SP "0x7"
3228#define REG_RA "0x10"
3229#else
3230#define SZPTR "4"
3231#define BSZPTR "2"
3232#define REG_SP "0x4"
3233#define REG_RA "0x8"
3234#endif
3235 switch (ctx->mode) {
3236 case BUILD_elfasm:
3237 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
3238 fprintf(ctx->fp,
3239 ".Lframe0:\n"
3240 "\t.long .LECIE0-.LSCIE0\n"
3241 ".LSCIE0:\n"
3242 "\t.long 0xffffffff\n"
3243 "\t.byte 0x1\n"
3244 "\t.string \"\"\n"
3245 "\t.uleb128 0x1\n"
3246 "\t.sleb128 -" SZPTR "\n"
3247 "\t.byte " REG_RA "\n"
3248 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3249 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3250 "\t.align " SZPTR "\n"
3251 ".LECIE0:\n\n");
3252 fprintf(ctx->fp,
3253 ".LSFDE0:\n"
3254 "\t.long .LEFDE0-.LASFDE0\n"
3255 ".LASFDE0:\n"
3256 "\t.long .Lframe0\n"
3257#if LJ_64
3258 "\t.quad .Lbegin\n"
3259 "\t.quad %d\n"
3260 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3261 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3262 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3263 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3264 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3265#else
3266 "\t.long .Lbegin\n"
3267 "\t.long %d\n"
3268 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3269 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3270 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3271 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3272 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3273#endif
3274 "\t.align " SZPTR "\n"
3275 ".LEFDE0:\n\n", fcofs, CFRAME_SIZE);
3276#if LJ_HASFFI
3277 fprintf(ctx->fp,
3278 ".LSFDE1:\n"
3279 "\t.long .LEFDE1-.LASFDE1\n"
3280 ".LASFDE1:\n"
3281 "\t.long .Lframe0\n"
3282#if LJ_64
3283 "\t.quad lj_vm_ffi_call\n"
3284 "\t.quad %d\n"
3285 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
3286 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3287 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3288 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3289#else
3290 "\t.long lj_vm_ffi_call\n"
3291 "\t.long %d\n"
3292 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
3293 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3294 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
3295 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
3296#endif
3297 "\t.align " SZPTR "\n"
3298 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
3299#endif
3300#if (defined(__sun__) && defined(__svr4__)) || defined(__solaris_)
3301 fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n");
3302#else
3303 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
3304#endif
3305 fprintf(ctx->fp,
3306 ".Lframe1:\n"
3307 "\t.long .LECIE1-.LSCIE1\n"
3308 ".LSCIE1:\n"
3309 "\t.long 0\n"
3310 "\t.byte 0x1\n"
3311 "\t.string \"zPR\"\n"
3312 "\t.uleb128 0x1\n"
3313 "\t.sleb128 -" SZPTR "\n"
3314 "\t.byte " REG_RA "\n"
3315 "\t.uleb128 6\n" /* augmentation length */
3316 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3317 "\t.long lj_err_unwind_dwarf-.\n"
3318 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3319 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3320 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3321 "\t.align " SZPTR "\n"
3322 ".LECIE1:\n\n");
3323 fprintf(ctx->fp,
3324 ".LSFDE2:\n"
3325 "\t.long .LEFDE2-.LASFDE2\n"
3326 ".LASFDE2:\n"
3327 "\t.long .LASFDE2-.Lframe1\n"
3328 "\t.long .Lbegin-.\n"
3329 "\t.long %d\n"
3330 "\t.uleb128 0\n" /* augmentation length */
3331 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3332#if LJ_64
3333 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3334 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3335 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3336 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3337#else
3338 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3339 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3340 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3341 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3342#endif
3343 "\t.align " SZPTR "\n"
3344 ".LEFDE2:\n\n", fcofs, CFRAME_SIZE);
3345#if LJ_HASFFI
3346 fprintf(ctx->fp,
3347 ".Lframe2:\n"
3348 "\t.long .LECIE2-.LSCIE2\n"
3349 ".LSCIE2:\n"
3350 "\t.long 0\n"
3351 "\t.byte 0x1\n"
3352 "\t.string \"zR\"\n"
3353 "\t.uleb128 0x1\n"
3354 "\t.sleb128 -" SZPTR "\n"
3355 "\t.byte " REG_RA "\n"
3356 "\t.uleb128 1\n" /* augmentation length */
3357 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3358 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3359 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3360 "\t.align " SZPTR "\n"
3361 ".LECIE2:\n\n");
3362 fprintf(ctx->fp,
3363 ".LSFDE3:\n"
3364 "\t.long .LEFDE3-.LASFDE3\n"
3365 ".LASFDE3:\n"
3366 "\t.long .LASFDE3-.Lframe2\n"
3367 "\t.long lj_vm_ffi_call-.\n"
3368 "\t.long %d\n"
3369 "\t.uleb128 0\n" /* augmentation length */
3370#if LJ_64
3371 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
3372 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3373 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3374 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3375#else
3376 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
3377 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3378 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
3379 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
3380#endif
3381 "\t.align " SZPTR "\n"
3382 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
3383#endif
3384 break;
3385 case BUILD_coffasm:
3386 fprintf(ctx->fp, "\t.section .eh_frame,\"dr\"\n");
3387 fprintf(ctx->fp,
3388 "\t.def %slj_err_unwind_dwarf; .scl 2; .type 32; .endef\n",
3389 LJ_32 ? "_" : "");
3390 fprintf(ctx->fp,
3391 "Lframe1:\n"
3392 "\t.long LECIE1-LSCIE1\n"
3393 "LSCIE1:\n"
3394 "\t.long 0\n"
3395 "\t.byte 0x1\n"
3396 "\t.string \"zP\"\n"
3397 "\t.uleb128 0x1\n"
3398 "\t.sleb128 -" SZPTR "\n"
3399 "\t.byte " REG_RA "\n"
3400 "\t.uleb128 5\n" /* augmentation length */
3401 "\t.byte 0x00\n" /* absptr */
3402 "\t.long %slj_err_unwind_dwarf\n"
3403 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
3404 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
3405 "\t.align " SZPTR "\n"
3406 "LECIE1:\n\n", LJ_32 ? "_" : "");
3407 fprintf(ctx->fp,
3408 "LSFDE1:\n"
3409 "\t.long LEFDE1-LASFDE1\n"
3410 "LASFDE1:\n"
3411 "\t.long LASFDE1-Lframe1\n"
3412 "\t.long %slj_vm_asm_begin\n"
3413 "\t.long %d\n"
3414 "\t.uleb128 0\n" /* augmentation length */
3415 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3416#if LJ_64
3417 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
3418 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
3419 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
3420 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
3421#else
3422 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3423 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3424 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3425 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3426#endif
3427 "\t.align " SZPTR "\n"
3428 "LEFDE1:\n\n", LJ_32 ? "_" : "", (int)ctx->codesz, CFRAME_SIZE);
3429 break;
3430 /* Mental note: never let Apple design an assembler.
3431 ** Or a linker. Or a plastic case. But I digress.
3432 */
3433 case BUILD_machasm: {
3434#if LJ_HASFFI
3435 int fcsize = 0;
3436#endif
3437 int i;
3438 fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
3439 fprintf(ctx->fp,
3440 "EH_frame1:\n"
3441 "\t.set L$set$x,LECIEX-LSCIEX\n"
3442 "\t.long L$set$x\n"
3443 "LSCIEX:\n"
3444 "\t.long 0\n"
3445 "\t.byte 0x1\n"
3446 "\t.ascii \"zPR\\0\"\n"
3447 "\t.byte 0x1\n"
3448 "\t.byte 128-" SZPTR "\n"
3449 "\t.byte " REG_RA "\n"
3450 "\t.byte 6\n" /* augmentation length */
3451 "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
3452#if LJ_64
3453 "\t.long _lj_err_unwind_dwarf+4@GOTPCREL\n"
3454 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3455 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
3456#else
3457 "\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
3458 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3459 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
3460#endif
3461 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
3462 "\t.align " BSZPTR "\n"
3463 "LECIEX:\n\n");
3464 for (i = 0; i < ctx->nsym; i++) {
3465 const char *name = ctx->sym[i].name;
3466 int32_t size = ctx->sym[i+1].ofs - ctx->sym[i].ofs;
3467 if (size == 0) continue;
3468#if LJ_HASFFI
3469 if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; }
3470#endif
3471 fprintf(ctx->fp,
3472 "%s.eh:\n"
3473 "LSFDE%d:\n"
3474 "\t.set L$set$%d,LEFDE%d-LASFDE%d\n"
3475 "\t.long L$set$%d\n"
3476 "LASFDE%d:\n"
3477 "\t.long LASFDE%d-EH_frame1\n"
3478 "\t.long %s-.\n"
3479 "\t.long %d\n"
3480 "\t.byte 0\n" /* augmentation length */
3481 "\t.byte 0xe\n\t.byte %d\n" /* def_cfa_offset */
3482#if LJ_64
3483 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
3484 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
3485 "\t.byte 0x8f\n\t.byte 0x4\n" /* offset r15 */
3486 "\t.byte 0x8e\n\t.byte 0x5\n" /* offset r14 */
3487#else
3488 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
3489 "\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
3490 "\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
3491 "\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
3492#endif
3493 "\t.align " BSZPTR "\n"
3494 "LEFDE%d:\n\n",
3495 name, i, i, i, i, i, i, i, name, size, CFRAME_SIZE, i);
3496 }
3497#if LJ_HASFFI
3498 if (fcsize) {
3499 fprintf(ctx->fp,
3500 "EH_frame2:\n"
3501 "\t.set L$set$y,LECIEY-LSCIEY\n"
3502 "\t.long L$set$y\n"
3503 "LSCIEY:\n"
3504 "\t.long 0\n"
3505 "\t.byte 0x1\n"
3506 "\t.ascii \"zR\\0\"\n"
3507 "\t.byte 0x1\n"
3508 "\t.byte 128-" SZPTR "\n"
3509 "\t.byte " REG_RA "\n"
3510 "\t.byte 1\n" /* augmentation length */
3511#if LJ_64
3512 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3513 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
3514#else
3515 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3516 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH. */
3517#endif
3518 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
3519 "\t.align " BSZPTR "\n"
3520 "LECIEY:\n\n");
3521 fprintf(ctx->fp,
3522 "_lj_vm_ffi_call.eh:\n"
3523 "LSFDEY:\n"
3524 "\t.set L$set$yy,LEFDEY-LASFDEY\n"
3525 "\t.long L$set$yy\n"
3526 "LASFDEY:\n"
3527 "\t.long LASFDEY-EH_frame2\n"
3528 "\t.long _lj_vm_ffi_call-.\n"
3529 "\t.long %d\n"
3530 "\t.byte 0\n" /* augmentation length */
3531#if LJ_64
3532 "\t.byte 0xe\n\t.byte 16\n" /* def_cfa_offset */
3533 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
3534 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
3535 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
3536#else
3537 "\t.byte 0xe\n\t.byte 8\n" /* def_cfa_offset */
3538 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
3539 "\t.byte 0xd\n\t.uleb128 0x4\n" /* def_cfa_register ebp */
3540 "\t.byte 0x83\n\t.byte 0x3\n" /* offset ebx */
3541#endif
3542 "\t.align " BSZPTR "\n"
3543 "LEFDEY:\n\n", fcsize);
3544 }
3545#endif
3546#if LJ_64
3547 fprintf(ctx->fp, "\t.subsections_via_symbols\n");
3548#else
3549 fprintf(ctx->fp,
3550 "\t.non_lazy_symbol_pointer\n"
3551 "L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
3552 ".indirect_symbol _lj_err_unwind_dwarf\n"
3553 ".long 0\n");
3554#endif
3555 }
3556 break;
3557 default: /* Difficult for other modes. */
3558 break;
3559 }
3560}
3561
diff --git a/libraries/luajit-2.0/src/lauxlib.h b/libraries/luajit-2.0/src/lauxlib.h
new file mode 100644
index 0000000..505a9f5
--- /dev/null
+++ b/libraries/luajit-2.0/src/lauxlib.h
@@ -0,0 +1,159 @@
1/*
2** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lauxlib_h
9#define lauxlib_h
10
11
12#include <stddef.h>
13#include <stdio.h>
14
15#include "lua.h"
16
17
18#define luaL_getn(L,i) ((int)lua_objlen(L, i))
19#define luaL_setn(L,i,j) ((void)0) /* no op! */
20
21/* extra error code for `luaL_load' */
22#define LUA_ERRFILE (LUA_ERRERR+1)
23
24typedef struct luaL_Reg {
25 const char *name;
26 lua_CFunction func;
27} luaL_Reg;
28
29LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
30 const luaL_Reg *l, int nup);
31LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
32 const luaL_Reg *l);
33LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
34LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
35LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
36LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
37LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
38 size_t *l);
39LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
40 const char *def, size_t *l);
41LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
42LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
43
44LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
45LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
46 lua_Integer def);
47
48LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
49LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
50LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
51
52LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
53LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
54
55LUALIB_API void (luaL_where) (lua_State *L, int lvl);
56LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
57
58LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
59 const char *const lst[]);
60
61LUALIB_API int (luaL_ref) (lua_State *L, int t);
62LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
63
64LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
65LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
66 const char *name);
67LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
68
69LUALIB_API lua_State *(luaL_newstate) (void);
70
71
72LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
73 const char *r);
74
75LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
76 const char *fname, int szhint);
77
78
79
80
81/*
82** ===============================================================
83** some useful macros
84** ===============================================================
85*/
86
87#define luaL_argcheck(L, cond,numarg,extramsg) \
88 ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
89#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
90#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
91#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
92#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
93#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
94#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
95
96#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
97
98#define luaL_dofile(L, fn) \
99 (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
100
101#define luaL_dostring(L, s) \
102 (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
103
104#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
105
106#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
107
108/*
109** {======================================================
110** Generic Buffer manipulation
111** =======================================================
112*/
113
114
115
116typedef struct luaL_Buffer {
117 char *p; /* current position in buffer */
118 int lvl; /* number of strings in the stack (level) */
119 lua_State *L;
120 char buffer[LUAL_BUFFERSIZE];
121} luaL_Buffer;
122
123#define luaL_addchar(B,c) \
124 ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
125 (*(B)->p++ = (char)(c)))
126
127/* compatibility only */
128#define luaL_putchar(B,c) luaL_addchar(B,c)
129
130#define luaL_addsize(B,n) ((B)->p += (n))
131
132LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
133LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
134LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
135LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
136LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
137LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
138
139
140/* }====================================================== */
141
142
143/* compatibility with ref system */
144
145/* pre-defined references */
146#define LUA_NOREF (-2)
147#define LUA_REFNIL (-1)
148
149#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
150 (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
151
152#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
153
154#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
155
156
157#define luaL_reg luaL_Reg
158
159#endif
diff --git a/libraries/luajit-2.0/src/lib_aux.c b/libraries/luajit-2.0/src/lib_aux.c
new file mode 100644
index 0000000..628d6a5
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_aux.c
@@ -0,0 +1,375 @@
1/*
2** Auxiliary library for the Lua/C API.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major parts taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#include <errno.h>
10#include <stdarg.h>
11#include <stdio.h>
12
13#define lib_aux_c
14#define LUA_LIB
15
16#include "lua.h"
17#include "lauxlib.h"
18
19#include "lj_obj.h"
20#include "lj_err.h"
21#include "lj_state.h"
22#include "lj_lib.h"
23
24/* -- Module registration ------------------------------------------------- */
25
26LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
27 const char *fname, int szhint)
28{
29 const char *e;
30 lua_pushvalue(L, idx);
31 do {
32 e = strchr(fname, '.');
33 if (e == NULL) e = fname + strlen(fname);
34 lua_pushlstring(L, fname, (size_t)(e - fname));
35 lua_rawget(L, -2);
36 if (lua_isnil(L, -1)) { /* no such field? */
37 lua_pop(L, 1); /* remove this nil */
38 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
39 lua_pushlstring(L, fname, (size_t)(e - fname));
40 lua_pushvalue(L, -2);
41 lua_settable(L, -4); /* set new table into field */
42 } else if (!lua_istable(L, -1)) { /* field has a non-table value? */
43 lua_pop(L, 2); /* remove table and value */
44 return fname; /* return problematic part of the name */
45 }
46 lua_remove(L, -2); /* remove previous table */
47 fname = e + 1;
48 } while (*e == '.');
49 return NULL;
50}
51
52static int libsize(const luaL_Reg *l)
53{
54 int size = 0;
55 for (; l->name; l++) size++;
56 return size;
57}
58
59LUALIB_API void luaL_openlib(lua_State *L, const char *libname,
60 const luaL_Reg *l, int nup)
61{
62 lj_lib_checkfpu(L);
63 if (libname) {
64 int size = libsize(l);
65 /* check whether lib already exists */
66 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
67 lua_getfield(L, -1, libname); /* get _LOADED[libname] */
68 if (!lua_istable(L, -1)) { /* not found? */
69 lua_pop(L, 1); /* remove previous result */
70 /* try global variable (and create one if it does not exist) */
71 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
72 lj_err_callerv(L, LJ_ERR_BADMODN, libname);
73 lua_pushvalue(L, -1);
74 lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
75 }
76 lua_remove(L, -2); /* remove _LOADED table */
77 lua_insert(L, -(nup+1)); /* move library table to below upvalues */
78 }
79 for (; l->name; l++) {
80 int i;
81 for (i = 0; i < nup; i++) /* copy upvalues to the top */
82 lua_pushvalue(L, -nup);
83 lua_pushcclosure(L, l->func, nup);
84 lua_setfield(L, -(nup+2), l->name);
85 }
86 lua_pop(L, nup); /* remove upvalues */
87}
88
89LUALIB_API void luaL_register(lua_State *L, const char *libname,
90 const luaL_Reg *l)
91{
92 luaL_openlib(L, libname, l, 0);
93}
94
95LUALIB_API const char *luaL_gsub(lua_State *L, const char *s,
96 const char *p, const char *r)
97{
98 const char *wild;
99 size_t l = strlen(p);
100 luaL_Buffer b;
101 luaL_buffinit(L, &b);
102 while ((wild = strstr(s, p)) != NULL) {
103 luaL_addlstring(&b, s, (size_t)(wild - s)); /* push prefix */
104 luaL_addstring(&b, r); /* push replacement in place of pattern */
105 s = wild + l; /* continue after `p' */
106 }
107 luaL_addstring(&b, s); /* push last suffix */
108 luaL_pushresult(&b);
109 return lua_tostring(L, -1);
110}
111
112/* -- Buffer handling ----------------------------------------------------- */
113
114#define bufflen(B) ((size_t)((B)->p - (B)->buffer))
115#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
116
117static int emptybuffer(luaL_Buffer *B)
118{
119 size_t l = bufflen(B);
120 if (l == 0)
121 return 0; /* put nothing on stack */
122 lua_pushlstring(B->L, B->buffer, l);
123 B->p = B->buffer;
124 B->lvl++;
125 return 1;
126}
127
128static void adjuststack(luaL_Buffer *B)
129{
130 if (B->lvl > 1) {
131 lua_State *L = B->L;
132 int toget = 1; /* number of levels to concat */
133 size_t toplen = lua_strlen(L, -1);
134 do {
135 size_t l = lua_strlen(L, -(toget+1));
136 if (!(B->lvl - toget + 1 >= LUA_MINSTACK/2 || toplen > l))
137 break;
138 toplen += l;
139 toget++;
140 } while (toget < B->lvl);
141 lua_concat(L, toget);
142 B->lvl = B->lvl - toget + 1;
143 }
144}
145
146LUALIB_API char *luaL_prepbuffer(luaL_Buffer *B)
147{
148 if (emptybuffer(B))
149 adjuststack(B);
150 return B->buffer;
151}
152
153LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l)
154{
155 while (l--)
156 luaL_addchar(B, *s++);
157}
158
159LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s)
160{
161 luaL_addlstring(B, s, strlen(s));
162}
163
164LUALIB_API void luaL_pushresult(luaL_Buffer *B)
165{
166 emptybuffer(B);
167 lua_concat(B->L, B->lvl);
168 B->lvl = 1;
169}
170
171LUALIB_API void luaL_addvalue(luaL_Buffer *B)
172{
173 lua_State *L = B->L;
174 size_t vl;
175 const char *s = lua_tolstring(L, -1, &vl);
176 if (vl <= bufffree(B)) { /* fit into buffer? */
177 memcpy(B->p, s, vl); /* put it there */
178 B->p += vl;
179 lua_pop(L, 1); /* remove from stack */
180 } else {
181 if (emptybuffer(B))
182 lua_insert(L, -2); /* put buffer before new value */
183 B->lvl++; /* add new value into B stack */
184 adjuststack(B);
185 }
186}
187
188LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
189{
190 B->L = L;
191 B->p = B->buffer;
192 B->lvl = 0;
193}
194
195/* -- Reference management ------------------------------------------------ */
196
197#define FREELIST_REF 0
198
199/* Convert a stack index to an absolute index. */
200#define abs_index(L, i) \
201 ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
202
203LUALIB_API int luaL_ref(lua_State *L, int t)
204{
205 int ref;
206 t = abs_index(L, t);
207 if (lua_isnil(L, -1)) {
208 lua_pop(L, 1); /* remove from stack */
209 return LUA_REFNIL; /* `nil' has a unique fixed reference */
210 }
211 lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
212 ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
213 lua_pop(L, 1); /* remove it from stack */
214 if (ref != 0) { /* any free element? */
215 lua_rawgeti(L, t, ref); /* remove it from list */
216 lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
217 } else { /* no free elements */
218 ref = (int)lua_objlen(L, t);
219 ref++; /* create new reference */
220 }
221 lua_rawseti(L, t, ref);
222 return ref;
223}
224
225LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
226{
227 if (ref >= 0) {
228 t = abs_index(L, t);
229 lua_rawgeti(L, t, FREELIST_REF);
230 lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
231 lua_pushinteger(L, ref);
232 lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
233 }
234}
235
236/* -- Load Lua code ------------------------------------------------------- */
237
238typedef struct FileReaderCtx {
239 FILE *fp;
240 char buf[LUAL_BUFFERSIZE];
241} FileReaderCtx;
242
243static const char *reader_file(lua_State *L, void *ud, size_t *size)
244{
245 FileReaderCtx *ctx = (FileReaderCtx *)ud;
246 UNUSED(L);
247 if (feof(ctx->fp)) return NULL;
248 *size = fread(ctx->buf, 1, sizeof(ctx->buf), ctx->fp);
249 return *size > 0 ? ctx->buf : NULL;
250}
251
252LUALIB_API int luaL_loadfile(lua_State *L, const char *filename)
253{
254 FileReaderCtx ctx;
255 int status;
256 const char *chunkname;
257 if (filename) {
258 ctx.fp = fopen(filename, "rb");
259 if (ctx.fp == NULL) {
260 lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
261 return LUA_ERRFILE;
262 }
263 chunkname = lua_pushfstring(L, "@%s", filename);
264 } else {
265 ctx.fp = stdin;
266 chunkname = "=stdin";
267 }
268 status = lua_load(L, reader_file, &ctx, chunkname);
269 if (ferror(ctx.fp)) {
270 L->top -= filename ? 2 : 1;
271 lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(errno));
272 if (filename)
273 fclose(ctx.fp);
274 return LUA_ERRFILE;
275 }
276 if (filename) {
277 L->top--;
278 copyTV(L, L->top-1, L->top);
279 fclose(ctx.fp);
280 }
281 return status;
282}
283
284typedef struct StringReaderCtx {
285 const char *str;
286 size_t size;
287} StringReaderCtx;
288
289static const char *reader_string(lua_State *L, void *ud, size_t *size)
290{
291 StringReaderCtx *ctx = (StringReaderCtx *)ud;
292 UNUSED(L);
293 if (ctx->size == 0) return NULL;
294 *size = ctx->size;
295 ctx->size = 0;
296 return ctx->str;
297}
298
299LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size,
300 const char *name)
301{
302 StringReaderCtx ctx;
303 ctx.str = buf;
304 ctx.size = size;
305 return lua_load(L, reader_string, &ctx, name);
306}
307
308LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
309{
310 return luaL_loadbuffer(L, s, strlen(s), s);
311}
312
313/* -- Default allocator and panic function -------------------------------- */
314
315static int panic(lua_State *L)
316{
317 fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
318 lua_tostring(L, -1));
319 return 0;
320}
321
322#ifdef LUAJIT_USE_SYSMALLOC
323
324#if LJ_64
325#error "Must use builtin allocator for 64 bit target"
326#endif
327
328static void *mem_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
329{
330 (void)ud;
331 (void)osize;
332 if (nsize == 0) {
333 free(ptr);
334 return NULL;
335 } else {
336 return realloc(ptr, nsize);
337 }
338}
339
340LUALIB_API lua_State *luaL_newstate(void)
341{
342 lua_State *L = lua_newstate(mem_alloc, NULL);
343 if (L) G(L)->panic = panic;
344 return L;
345}
346
347#else
348
349#include "lj_alloc.h"
350
351LUALIB_API lua_State *luaL_newstate(void)
352{
353 lua_State *L;
354 void *ud = lj_alloc_create();
355 if (ud == NULL) return NULL;
356#if LJ_64
357 L = lj_state_newstate(lj_alloc_f, ud);
358#else
359 L = lua_newstate(lj_alloc_f, ud);
360#endif
361 if (L) G(L)->panic = panic;
362 return L;
363}
364
365#if LJ_64
366LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
367{
368 UNUSED(f); UNUSED(ud);
369 fprintf(stderr, "Must use luaL_newstate() for 64 bit target\n");
370 return NULL;
371}
372#endif
373
374#endif
375
diff --git a/libraries/luajit-2.0/src/lib_base.c b/libraries/luajit-2.0/src/lib_base.c
new file mode 100644
index 0000000..f897598
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_base.c
@@ -0,0 +1,650 @@
1/*
2** Base and coroutine library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#include <stdio.h>
10
11#define lib_base_c
12#define LUA_LIB
13
14#include "lua.h"
15#include "lauxlib.h"
16#include "lualib.h"
17
18#include "lj_obj.h"
19#include "lj_gc.h"
20#include "lj_err.h"
21#include "lj_debug.h"
22#include "lj_str.h"
23#include "lj_tab.h"
24#include "lj_meta.h"
25#include "lj_state.h"
26#if LJ_HASFFI
27#include "lj_ctype.h"
28#include "lj_cconv.h"
29#endif
30#include "lj_bc.h"
31#include "lj_ff.h"
32#include "lj_dispatch.h"
33#include "lj_char.h"
34#include "lj_lib.h"
35
36/* -- Base library: checks ------------------------------------------------ */
37
38#define LJLIB_MODULE_base
39
40LJLIB_ASM(assert) LJLIB_REC(.)
41{
42 GCstr *s;
43 lj_lib_checkany(L, 1);
44 s = lj_lib_optstr(L, 2);
45 if (s)
46 lj_err_callermsg(L, strdata(s));
47 else
48 lj_err_caller(L, LJ_ERR_ASSERT);
49 return FFH_UNREACHABLE;
50}
51
52/* ORDER LJ_T */
53LJLIB_PUSH("nil")
54LJLIB_PUSH("boolean")
55LJLIB_PUSH(top-1) /* boolean */
56LJLIB_PUSH("userdata")
57LJLIB_PUSH("string")
58LJLIB_PUSH("upval")
59LJLIB_PUSH("thread")
60LJLIB_PUSH("proto")
61LJLIB_PUSH("function")
62LJLIB_PUSH("trace")
63LJLIB_PUSH("cdata")
64LJLIB_PUSH("table")
65LJLIB_PUSH(top-9) /* userdata */
66LJLIB_PUSH("number")
67LJLIB_ASM_(type) LJLIB_REC(.)
68/* Recycle the lj_lib_checkany(L, 1) from assert. */
69
70/* -- Base library: getters and setters ----------------------------------- */
71
72LJLIB_ASM_(getmetatable) LJLIB_REC(.)
73/* Recycle the lj_lib_checkany(L, 1) from assert. */
74
75LJLIB_ASM(setmetatable) LJLIB_REC(.)
76{
77 GCtab *t = lj_lib_checktab(L, 1);
78 GCtab *mt = lj_lib_checktabornil(L, 2);
79 if (!tvisnil(lj_meta_lookup(L, L->base, MM_metatable)))
80 lj_err_caller(L, LJ_ERR_PROTMT);
81 setgcref(t->metatable, obj2gco(mt));
82 if (mt) { lj_gc_objbarriert(L, t, mt); }
83 settabV(L, L->base-1, t);
84 return FFH_RES(1);
85}
86
87LJLIB_CF(getfenv)
88{
89 GCfunc *fn;
90 cTValue *o = L->base;
91 if (!(o < L->top && tvisfunc(o))) {
92 int level = lj_lib_optint(L, 1, 1);
93 o = lj_debug_frame(L, level, &level);
94 if (o == NULL)
95 lj_err_arg(L, 1, LJ_ERR_INVLVL);
96 }
97 fn = &gcval(o)->fn;
98 settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env));
99 return 1;
100}
101
102LJLIB_CF(setfenv)
103{
104 GCfunc *fn;
105 GCtab *t = lj_lib_checktab(L, 2);
106 cTValue *o = L->base;
107 if (!(o < L->top && tvisfunc(o))) {
108 int level = lj_lib_checkint(L, 1);
109 if (level == 0) {
110 /* NOBARRIER: A thread (i.e. L) is never black. */
111 setgcref(L->env, obj2gco(t));
112 return 0;
113 }
114 o = lj_debug_frame(L, level, &level);
115 if (o == NULL)
116 lj_err_arg(L, 1, LJ_ERR_INVLVL);
117 }
118 fn = &gcval(o)->fn;
119 if (!isluafunc(fn))
120 lj_err_caller(L, LJ_ERR_SETFENV);
121 setgcref(fn->l.env, obj2gco(t));
122 lj_gc_objbarrier(L, obj2gco(fn), t);
123 setfuncV(L, L->top++, fn);
124 return 1;
125}
126
127LJLIB_ASM(rawget) LJLIB_REC(.)
128{
129 lj_lib_checktab(L, 1);
130 lj_lib_checkany(L, 2);
131 return FFH_UNREACHABLE;
132}
133
134LJLIB_CF(rawset) LJLIB_REC(.)
135{
136 lj_lib_checktab(L, 1);
137 lj_lib_checkany(L, 2);
138 L->top = 1+lj_lib_checkany(L, 3);
139 lua_rawset(L, 1);
140 return 1;
141}
142
143LJLIB_CF(rawequal) LJLIB_REC(.)
144{
145 cTValue *o1 = lj_lib_checkany(L, 1);
146 cTValue *o2 = lj_lib_checkany(L, 2);
147 setboolV(L->top-1, lj_obj_equal(o1, o2));
148 return 1;
149}
150
151LJLIB_CF(unpack)
152{
153 GCtab *t = lj_lib_checktab(L, 1);
154 int32_t n, i = lj_lib_optint(L, 2, 1);
155 int32_t e = (L->base+3-1 < L->top && !tvisnil(L->base+3-1)) ?
156 lj_lib_checkint(L, 3) : (int32_t)lj_tab_len(t);
157 if (i > e) return 0;
158 n = e - i + 1;
159 if (n <= 0 || !lua_checkstack(L, n))
160 lj_err_caller(L, LJ_ERR_UNPACK);
161 do {
162 cTValue *tv = lj_tab_getint(t, i);
163 if (tv) {
164 copyTV(L, L->top++, tv);
165 } else {
166 setnilV(L->top++);
167 }
168 } while (i++ < e);
169 return n;
170}
171
172LJLIB_CF(select) LJLIB_REC(.)
173{
174 int32_t n = (int32_t)(L->top - L->base);
175 if (n >= 1 && tvisstr(L->base) && *strVdata(L->base) == '#') {
176 setintV(L->top-1, n-1);
177 return 1;
178 } else {
179 int32_t i = lj_lib_checkint(L, 1);
180 if (i < 0) i = n + i; else if (i > n) i = n;
181 if (i < 1)
182 lj_err_arg(L, 1, LJ_ERR_IDXRNG);
183 return n - i;
184 }
185}
186
187/* -- Base library: conversions ------------------------------------------- */
188
189LJLIB_ASM(tonumber) LJLIB_REC(.)
190{
191 int32_t base = lj_lib_optint(L, 2, 10);
192 if (base == 10) {
193 TValue *o = lj_lib_checkany(L, 1);
194 if (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o))) {
195 copyTV(L, L->base-1, o);
196 return FFH_RES(1);
197 }
198#if LJ_HASFFI
199 if (tviscdata(o)) {
200 CTState *cts = ctype_cts(L);
201 CType *ct = lj_ctype_rawref(cts, cdataV(o)->typeid);
202 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
203 if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
204 if (LJ_DUALNUM && ctype_isinteger_or_bool(ct->info) &&
205 ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) {
206 int32_t i;
207 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0);
208 setintV(L->base-1, i);
209 return FFH_RES(1);
210 }
211 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
212 (uint8_t *)&(L->base-1)->n, o, 0);
213 return FFH_RES(1);
214 }
215 }
216#endif
217 } else {
218 const char *p = strdata(lj_lib_checkstr(L, 1));
219 char *ep;
220 unsigned long ul;
221 if (base < 2 || base > 36)
222 lj_err_arg(L, 2, LJ_ERR_BASERNG);
223 ul = strtoul(p, &ep, base);
224 if (p != ep) {
225 while (lj_char_isspace((unsigned char)(*ep))) ep++;
226 if (*ep == '\0') {
227 if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u))
228 setintV(L->base-1, (int32_t)ul);
229 else
230 setnumV(L->base-1, (lua_Number)ul);
231 return FFH_RES(1);
232 }
233 }
234 }
235 setnilV(L->base-1);
236 return FFH_RES(1);
237}
238
239LJLIB_PUSH("nil")
240LJLIB_PUSH("false")
241LJLIB_PUSH("true")
242LJLIB_ASM(tostring) LJLIB_REC(.)
243{
244 TValue *o = lj_lib_checkany(L, 1);
245 cTValue *mo;
246 L->top = o+1; /* Only keep one argument. */
247 if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
248 copyTV(L, L->base-1, mo); /* Replace callable. */
249 return FFH_TAILCALL;
250 } else {
251 GCstr *s;
252 if (tvisnumber(o)) {
253 s = lj_str_fromnumber(L, o);
254 } else if (tvispri(o)) {
255 s = strV(lj_lib_upvalue(L, -(int32_t)itype(o)));
256 } else {
257 if (tvisfunc(o) && isffunc(funcV(o)))
258 lua_pushfstring(L, "function: fast#%d", funcV(o)->c.ffid);
259 else
260 lua_pushfstring(L, "%s: %p", typename(o), lua_topointer(L, 1));
261 /* Note: lua_pushfstring calls the GC which may invalidate o. */
262 s = strV(L->top-1);
263 }
264 setstrV(L, L->base-1, s);
265 return FFH_RES(1);
266 }
267}
268
269/* -- Base library: iterators --------------------------------------------- */
270
271/* This solves a circular dependency problem -- change FF_next_N as needed. */
272LJ_STATIC_ASSERT((int)FF_next == FF_next_N);
273
274LJLIB_ASM(next)
275{
276 lj_lib_checktab(L, 1);
277 return FFH_UNREACHABLE;
278}
279
280#ifdef LUAJIT_ENABLE_LUA52COMPAT
281static int ffh_pairs(lua_State *L, MMS mm)
282{
283 TValue *o = lj_lib_checkany(L, 1);
284 cTValue *mo = lj_meta_lookup(L, o, mm);
285 if (!tvisnil(mo)) {
286 L->top = o+1; /* Only keep one argument. */
287 copyTV(L, L->base-1, mo); /* Replace callable. */
288 return FFH_TAILCALL;
289 } else {
290 if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE);
291 setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1)));
292 if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0);
293 return FFH_RES(3);
294 }
295}
296#else
297#define ffh_pairs(L, mm) (lj_lib_checktab(L, 1), FFH_UNREACHABLE)
298#endif
299
300LJLIB_PUSH(lastcl)
301LJLIB_ASM(pairs)
302{
303 return ffh_pairs(L, MM_pairs);
304}
305
306LJLIB_NOREGUV LJLIB_ASM(ipairs_aux) LJLIB_REC(.)
307{
308 lj_lib_checktab(L, 1);
309 lj_lib_checkint(L, 2);
310 return FFH_UNREACHABLE;
311}
312
313LJLIB_PUSH(lastcl)
314LJLIB_ASM(ipairs) LJLIB_REC(.)
315{
316 return ffh_pairs(L, MM_ipairs);
317}
318
319/* -- Base library: throw and catch errors -------------------------------- */
320
321LJLIB_CF(error)
322{
323 int32_t level = lj_lib_optint(L, 2, 1);
324 lua_settop(L, 1);
325 if (lua_isstring(L, 1) && level > 0) {
326 luaL_where(L, level);
327 lua_pushvalue(L, 1);
328 lua_concat(L, 2);
329 }
330 return lua_error(L);
331}
332
333LJLIB_ASM(pcall) LJLIB_REC(.)
334{
335 lj_lib_checkany(L, 1);
336 lj_lib_checkfunc(L, 2); /* For xpcall only. */
337 return FFH_UNREACHABLE;
338}
339LJLIB_ASM_(xpcall) LJLIB_REC(.)
340
341/* -- Base library: load Lua code ----------------------------------------- */
342
343static int load_aux(lua_State *L, int status)
344{
345 if (status == 0)
346 return 1;
347 copyTV(L, L->top, L->top-1);
348 setnilV(L->top-1);
349 L->top++;
350 return 2;
351}
352
353LJLIB_CF(loadstring)
354{
355 GCstr *s = lj_lib_checkstr(L, 1);
356 GCstr *name = lj_lib_optstr(L, 2);
357 return load_aux(L,
358 luaL_loadbuffer(L, strdata(s), s->len, strdata(name ? name : s)));
359}
360
361LJLIB_CF(loadfile)
362{
363 GCstr *fname = lj_lib_optstr(L, 1);
364 return load_aux(L, luaL_loadfile(L, fname ? strdata(fname) : NULL));
365}
366
367static const char *reader_func(lua_State *L, void *ud, size_t *size)
368{
369 UNUSED(ud);
370 luaL_checkstack(L, 2, "too many nested functions");
371 copyTV(L, L->top++, L->base);
372 lua_call(L, 0, 1); /* Call user-supplied function. */
373 L->top--;
374 if (tvisnil(L->top)) {
375 *size = 0;
376 return NULL;
377 } else if (tvisstr(L->top) || tvisnumber(L->top)) {
378 copyTV(L, L->base+2, L->top); /* Anchor string in reserved stack slot. */
379 return lua_tolstring(L, 3, size);
380 } else {
381 lj_err_caller(L, LJ_ERR_RDRSTR);
382 return NULL;
383 }
384}
385
386LJLIB_CF(load)
387{
388 GCstr *name;
389 if (L->base < L->top && (tvisstr(L->base) || tvisnumber(L->base)))
390 return lj_cf_loadstring(L);
391 lj_lib_checkfunc(L, 1);
392 name = lj_lib_optstr(L, 2);
393 lua_settop(L, 3); /* Reserve a slot for the string from the reader. */
394 return load_aux(L,
395 lua_load(L, reader_func, NULL, name ? strdata(name) : "=(load)"));
396}
397
398LJLIB_CF(dofile)
399{
400 GCstr *fname = lj_lib_optstr(L, 1);
401 setnilV(L->top);
402 L->top = L->base+1;
403 if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0)
404 lua_error(L);
405 lua_call(L, 0, LUA_MULTRET);
406 return (int)(L->top - L->base) - 1;
407}
408
409/* -- Base library: GC control -------------------------------------------- */
410
411LJLIB_CF(gcinfo)
412{
413 setintV(L->top++, (G(L)->gc.total >> 10));
414 return 1;
415}
416
417LJLIB_CF(collectgarbage)
418{
419 int opt = lj_lib_checkopt(L, 1, LUA_GCCOLLECT, /* ORDER LUA_GC* */
420 "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul");
421 int32_t data = lj_lib_optint(L, 2, 0);
422 if (opt == LUA_GCCOUNT) {
423 setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0);
424 } else {
425 int res = lua_gc(L, opt, data);
426 if (opt == LUA_GCSTEP)
427 setboolV(L->top, res);
428 else
429 setintV(L->top, res);
430 }
431 L->top++;
432 return 1;
433}
434
435/* -- Base library: miscellaneous functions ------------------------------- */
436
437LJLIB_PUSH(top-2) /* Upvalue holds weak table. */
438LJLIB_CF(newproxy)
439{
440 lua_settop(L, 1);
441 lua_newuserdata(L, 0);
442 if (lua_toboolean(L, 1) == 0) { /* newproxy(): without metatable. */
443 return 1;
444 } else if (lua_isboolean(L, 1)) { /* newproxy(true): with metatable. */
445 lua_newtable(L);
446 lua_pushvalue(L, -1);
447 lua_pushboolean(L, 1);
448 lua_rawset(L, lua_upvalueindex(1)); /* Remember mt in weak table. */
449 } else { /* newproxy(proxy): inherit metatable. */
450 int validproxy = 0;
451 if (lua_getmetatable(L, 1)) {
452 lua_rawget(L, lua_upvalueindex(1));
453 validproxy = lua_toboolean(L, -1);
454 lua_pop(L, 1);
455 }
456 if (!validproxy)
457 lj_err_arg(L, 1, LJ_ERR_NOPROXY);
458 lua_getmetatable(L, 1);
459 }
460 lua_setmetatable(L, 2);
461 return 1;
462}
463
464LJLIB_PUSH("tostring")
465LJLIB_CF(print)
466{
467 ptrdiff_t i, nargs = L->top - L->base;
468 cTValue *tv = lj_tab_getstr(tabref(L->env), strV(lj_lib_upvalue(L, 1)));
469 int shortcut;
470 if (tv && !tvisnil(tv)) {
471 copyTV(L, L->top++, tv);
472 } else {
473 setstrV(L, L->top++, strV(lj_lib_upvalue(L, 1)));
474 lua_gettable(L, LUA_GLOBALSINDEX);
475 tv = L->top-1;
476 }
477 shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring);
478 for (i = 0; i < nargs; i++) {
479 const char *str;
480 size_t size;
481 cTValue *o = &L->base[i];
482 if (shortcut && tvisstr(o)) {
483 str = strVdata(o);
484 size = strV(o)->len;
485 } else if (shortcut && tvisint(o)) {
486 char buf[LJ_STR_INTBUF];
487 char *p = lj_str_bufint(buf, intV(o));
488 size = (size_t)(buf+LJ_STR_INTBUF-p);
489 str = p;
490 } else if (shortcut && tvisnum(o)) {
491 char buf[LJ_STR_NUMBUF];
492 size = lj_str_bufnum(buf, o);
493 str = buf;
494 } else {
495 copyTV(L, L->top+1, o);
496 copyTV(L, L->top, L->top-1);
497 L->top += 2;
498 lua_call(L, 1, 1);
499 str = lua_tolstring(L, -1, &size);
500 if (!str)
501 lj_err_caller(L, LJ_ERR_PRTOSTR);
502 L->top--;
503 }
504 if (i)
505 putchar('\t');
506 fwrite(str, 1, size, stdout);
507 }
508 putchar('\n');
509 return 0;
510}
511
512LJLIB_PUSH(top-3)
513LJLIB_SET(_VERSION)
514
515#include "lj_libdef.h"
516
517/* -- Coroutine library --------------------------------------------------- */
518
519#define LJLIB_MODULE_coroutine
520
521LJLIB_CF(coroutine_status)
522{
523 const char *s;
524 lua_State *co;
525 if (!(L->top > L->base && tvisthread(L->base)))
526 lj_err_arg(L, 1, LJ_ERR_NOCORO);
527 co = threadV(L->base);
528 if (co == L) s = "running";
529 else if (co->status == LUA_YIELD) s = "suspended";
530 else if (co->status != 0) s = "dead";
531 else if (co->base > tvref(co->stack)+1) s = "normal";
532 else if (co->top == co->base) s = "dead";
533 else s = "suspended";
534 lua_pushstring(L, s);
535 return 1;
536}
537
538LJLIB_CF(coroutine_running)
539{
540#ifdef LUAJIT_ENABLE_LUA52COMPAT
541 int ismain = lua_pushthread(L);
542 setboolV(L->top++, ismain);
543 return 2;
544#else
545 if (lua_pushthread(L))
546 setnilV(L->top++);
547 return 1;
548#endif
549}
550
551LJLIB_CF(coroutine_create)
552{
553 lua_State *L1 = lua_newthread(L);
554 if (!(L->base < L->top && tvisfunc(L->base)))
555 lj_err_argt(L, 1, LUA_TFUNCTION);
556 setfuncV(L, L1->top++, funcV(L->base));
557 return 1;
558}
559
560LJLIB_ASM(coroutine_yield)
561{
562 lj_err_caller(L, LJ_ERR_CYIELD);
563 return FFH_UNREACHABLE;
564}
565
566static int ffh_resume(lua_State *L, lua_State *co, int wrap)
567{
568 if (co->cframe != NULL || co->status > LUA_YIELD ||
569 (co->status == 0 && co->top == co->base)) {
570 ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD;
571 if (wrap) lj_err_caller(L, em);
572 setboolV(L->base-1, 0);
573 setstrV(L, L->base, lj_err_str(L, em));
574 return FFH_RES(2);
575 }
576 lj_state_growstack(co, (MSize)(L->top - L->base));
577 return FFH_RETRY;
578}
579
580LJLIB_ASM(coroutine_resume)
581{
582 if (!(L->top > L->base && tvisthread(L->base)))
583 lj_err_arg(L, 1, LJ_ERR_NOCORO);
584 return ffh_resume(L, threadV(L->base), 0);
585}
586
587LJLIB_NOREG LJLIB_ASM(coroutine_wrap_aux)
588{
589 return ffh_resume(L, threadV(lj_lib_upvalue(L, 1)), 1);
590}
591
592/* Inline declarations. */
593LJ_ASMF void lj_ff_coroutine_wrap_aux(void);
594LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L,
595 lua_State *co);
596
597/* Error handler, called from assembler VM. */
598void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L, lua_State *co)
599{
600 co->top--; copyTV(L, L->top, co->top); L->top++;
601 if (tvisstr(L->top-1))
602 lj_err_callermsg(L, strVdata(L->top-1));
603 else
604 lj_err_run(L);
605}
606
607/* Forward declaration. */
608static void setpc_wrap_aux(lua_State *L, GCfunc *fn);
609
610LJLIB_CF(coroutine_wrap)
611{
612 lj_cf_coroutine_create(L);
613 lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1);
614 setpc_wrap_aux(L, funcV(L->top-1));
615 return 1;
616}
617
618#include "lj_libdef.h"
619
620/* Fix the PC of wrap_aux. Really ugly workaround. */
621static void setpc_wrap_aux(lua_State *L, GCfunc *fn)
622{
623 setmref(fn->c.pc, &L2GG(L)->bcff[lj_lib_init_coroutine[1]+2]);
624}
625
626/* ------------------------------------------------------------------------ */
627
628static void newproxy_weaktable(lua_State *L)
629{
630 /* NOBARRIER: The table is new (marked white). */
631 GCtab *t = lj_tab_new(L, 0, 1);
632 settabV(L, L->top++, t);
633 setgcref(t->metatable, obj2gco(t));
634 setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
635 lj_str_newlit(L, "kv"));
636 t->nomm = (uint8_t)(~(1u<<MM_mode));
637}
638
639LUALIB_API int luaopen_base(lua_State *L)
640{
641 /* NOBARRIER: Table and value are the same. */
642 GCtab *env = tabref(L->env);
643 settabV(L, lj_tab_setstr(L, env, lj_str_newlit(L, "_G")), env);
644 lua_pushliteral(L, LUA_VERSION); /* top-3. */
645 newproxy_weaktable(L); /* top-2. */
646 LJ_LIB_REG(L, "_G", base);
647 LJ_LIB_REG(L, LUA_COLIBNAME, coroutine);
648 return 2;
649}
650
diff --git a/libraries/luajit-2.0/src/lib_bit.c b/libraries/luajit-2.0/src/lib_bit.c
new file mode 100644
index 0000000..c6c5c6f
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_bit.c
@@ -0,0 +1,74 @@
1/*
2** Bit manipulation library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lib_bit_c
7#define LUA_LIB
8
9#include "lua.h"
10#include "lauxlib.h"
11#include "lualib.h"
12
13#include "lj_obj.h"
14#include "lj_err.h"
15#include "lj_str.h"
16#include "lj_lib.h"
17
18/* ------------------------------------------------------------------------ */
19
20#define LJLIB_MODULE_bit
21
22LJLIB_ASM(bit_tobit) LJLIB_REC(bit_unary IR_TOBIT)
23{
24 lj_lib_checknumber(L, 1);
25 return FFH_RETRY;
26}
27LJLIB_ASM_(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
28LJLIB_ASM_(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
29
30LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
31{
32 lj_lib_checknumber(L, 1);
33 lj_lib_checkbit(L, 2);
34 return FFH_RETRY;
35}
36LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
37LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR)
38LJLIB_ASM_(bit_rol) LJLIB_REC(bit_shift IR_BROL)
39LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR)
40
41LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
42{
43 int i = 0;
44 do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
45 return FFH_RETRY;
46}
47LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
48LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
49
50/* ------------------------------------------------------------------------ */
51
52LJLIB_CF(bit_tohex)
53{
54 uint32_t b = (uint32_t)lj_lib_checkbit(L, 1);
55 int32_t i, n = L->base+1 >= L->top ? 8 : lj_lib_checkbit(L, 2);
56 const char *hexdigits = "0123456789abcdef";
57 char buf[8];
58 if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
59 if (n > 8) n = 8;
60 for (i = n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
61 lua_pushlstring(L, buf, (size_t)n);
62 return 1;
63}
64
65/* ------------------------------------------------------------------------ */
66
67#include "lj_libdef.h"
68
69LUALIB_API int luaopen_bit(lua_State *L)
70{
71 LJ_LIB_REG(L, LUA_BITLIBNAME, bit);
72 return 1;
73}
74
diff --git a/libraries/luajit-2.0/src/lib_debug.c b/libraries/luajit-2.0/src/lib_debug.c
new file mode 100644
index 0000000..3f1cb8c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_debug.c
@@ -0,0 +1,366 @@
1/*
2** Debug library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lib_debug_c
10#define LUA_LIB
11
12#include "lua.h"
13#include "lauxlib.h"
14#include "lualib.h"
15
16#include "lj_obj.h"
17#include "lj_err.h"
18#include "lj_lib.h"
19
20/* ------------------------------------------------------------------------ */
21
22#define LJLIB_MODULE_debug
23
24LJLIB_CF(debug_getregistry)
25{
26 copyTV(L, L->top++, registry(L));
27 return 1;
28}
29
30LJLIB_CF(debug_getmetatable)
31{
32 lj_lib_checkany(L, 1);
33 if (!lua_getmetatable(L, 1)) {
34 setnilV(L->top-1);
35 }
36 return 1;
37}
38
39LJLIB_CF(debug_setmetatable)
40{
41 lj_lib_checktabornil(L, 2);
42 L->top = L->base+2;
43 lua_setmetatable(L, 1);
44 setboolV(L->top-1, 1);
45 return 1;
46}
47
48LJLIB_CF(debug_getfenv)
49{
50 lj_lib_checkany(L, 1);
51 lua_getfenv(L, 1);
52 return 1;
53}
54
55LJLIB_CF(debug_setfenv)
56{
57 lj_lib_checktab(L, 2);
58 L->top = L->base+2;
59 if (!lua_setfenv(L, 1))
60 lj_err_caller(L, LJ_ERR_SETFENV);
61 return 1;
62}
63
64/* ------------------------------------------------------------------------ */
65
66static void settabss(lua_State *L, const char *i, const char *v)
67{
68 lua_pushstring(L, v);
69 lua_setfield(L, -2, i);
70}
71
72static void settabsi(lua_State *L, const char *i, int v)
73{
74 lua_pushinteger(L, v);
75 lua_setfield(L, -2, i);
76}
77
78static lua_State *getthread(lua_State *L, int *arg)
79{
80 if (L->base < L->top && tvisthread(L->base)) {
81 *arg = 1;
82 return threadV(L->base);
83 } else {
84 *arg = 0;
85 return L;
86 }
87}
88
89static void treatstackoption(lua_State *L, lua_State *L1, const char *fname)
90{
91 if (L == L1) {
92 lua_pushvalue(L, -2);
93 lua_remove(L, -3);
94 }
95 else
96 lua_xmove(L1, L, 1);
97 lua_setfield(L, -2, fname);
98}
99
100LJLIB_CF(debug_getinfo)
101{
102 lua_Debug ar;
103 int arg;
104 lua_State *L1 = getthread(L, &arg);
105 const char *options = luaL_optstring(L, arg+2, "flnSu");
106 if (lua_isnumber(L, arg+1)) {
107 if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
108 setnilV(L->top-1);
109 return 1;
110 }
111 } else if (L->base+arg < L->top && tvisfunc(L->base+arg)) {
112 options = lua_pushfstring(L, ">%s", options);
113 setfuncV(L1, L1->top++, funcV(L->base+arg));
114 } else {
115 lj_err_arg(L, arg+1, LJ_ERR_NOFUNCL);
116 }
117 if (!lua_getinfo(L1, options, &ar))
118 lj_err_arg(L, arg+2, LJ_ERR_INVOPT);
119 lua_createtable(L, 0, 16);
120 if (strchr(options, 'S')) {
121 settabss(L, "source", ar.source);
122 settabss(L, "short_src", ar.short_src);
123 settabsi(L, "linedefined", ar.linedefined);
124 settabsi(L, "lastlinedefined", ar.lastlinedefined);
125 settabss(L, "what", ar.what);
126 }
127 if (strchr(options, 'l'))
128 settabsi(L, "currentline", ar.currentline);
129 if (strchr(options, 'u'))
130 settabsi(L, "nups", ar.nups);
131 if (strchr(options, 'n')) {
132 settabss(L, "name", ar.name);
133 settabss(L, "namewhat", ar.namewhat);
134 }
135 if (strchr(options, 'L'))
136 treatstackoption(L, L1, "activelines");
137 if (strchr(options, 'f'))
138 treatstackoption(L, L1, "func");
139 return 1; /* return table */
140}
141
142LJLIB_CF(debug_getlocal)
143{
144 int arg;
145 lua_State *L1 = getthread(L, &arg);
146 lua_Debug ar;
147 const char *name;
148 if (!lua_getstack(L1, lj_lib_checkint(L, arg+1), &ar))
149 lj_err_arg(L, arg+1, LJ_ERR_LVLRNG);
150 name = lua_getlocal(L1, &ar, lj_lib_checkint(L, arg+2));
151 if (name) {
152 lua_xmove(L1, L, 1);
153 lua_pushstring(L, name);
154 lua_pushvalue(L, -2);
155 return 2;
156 } else {
157 setnilV(L->top-1);
158 return 1;
159 }
160}
161
162LJLIB_CF(debug_setlocal)
163{
164 int arg;
165 lua_State *L1 = getthread(L, &arg);
166 lua_Debug ar;
167 TValue *tv;
168 if (!lua_getstack(L1, lj_lib_checkint(L, arg+1), &ar))
169 lj_err_arg(L, arg+1, LJ_ERR_LVLRNG);
170 tv = lj_lib_checkany(L, arg+3);
171 copyTV(L1, L1->top++, tv);
172 lua_pushstring(L, lua_setlocal(L1, &ar, lj_lib_checkint(L, arg+2)));
173 return 1;
174}
175
176static int debug_getupvalue(lua_State *L, int get)
177{
178 int32_t n = lj_lib_checkint(L, 2);
179 if (isluafunc(lj_lib_checkfunc(L, 1))) {
180 const char *name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
181 if (name) {
182 lua_pushstring(L, name);
183 if (!get) return 1;
184 copyTV(L, L->top, L->top-2);
185 L->top++;
186 return 2;
187 }
188 }
189 return 0;
190}
191
192LJLIB_CF(debug_getupvalue)
193{
194 return debug_getupvalue(L, 1);
195}
196
197LJLIB_CF(debug_setupvalue)
198{
199 lj_lib_checkany(L, 3);
200 return debug_getupvalue(L, 0);
201}
202
203/* ------------------------------------------------------------------------ */
204
205static const char KEY_HOOK = 'h';
206
207static void hookf(lua_State *L, lua_Debug *ar)
208{
209 static const char *const hooknames[] =
210 {"call", "return", "line", "count", "tail return"};
211 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
212 lua_rawget(L, LUA_REGISTRYINDEX);
213 if (lua_isfunction(L, -1)) {
214 lua_pushstring(L, hooknames[(int)ar->event]);
215 if (ar->currentline >= 0)
216 lua_pushinteger(L, ar->currentline);
217 else lua_pushnil(L);
218 lua_call(L, 2, 0);
219 }
220}
221
222static int makemask(const char *smask, int count)
223{
224 int mask = 0;
225 if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
226 if (strchr(smask, 'r')) mask |= LUA_MASKRET;
227 if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
228 if (count > 0) mask |= LUA_MASKCOUNT;
229 return mask;
230}
231
232static char *unmakemask(int mask, char *smask)
233{
234 int i = 0;
235 if (mask & LUA_MASKCALL) smask[i++] = 'c';
236 if (mask & LUA_MASKRET) smask[i++] = 'r';
237 if (mask & LUA_MASKLINE) smask[i++] = 'l';
238 smask[i] = '\0';
239 return smask;
240}
241
242LJLIB_CF(debug_sethook)
243{
244 int arg, mask, count;
245 lua_Hook func;
246 (void)getthread(L, &arg);
247 if (lua_isnoneornil(L, arg+1)) {
248 lua_settop(L, arg+1);
249 func = NULL; mask = 0; count = 0; /* turn off hooks */
250 } else {
251 const char *smask = luaL_checkstring(L, arg+2);
252 luaL_checktype(L, arg+1, LUA_TFUNCTION);
253 count = luaL_optint(L, arg+3, 0);
254 func = hookf; mask = makemask(smask, count);
255 }
256 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
257 lua_pushvalue(L, arg+1);
258 lua_rawset(L, LUA_REGISTRYINDEX);
259 lua_sethook(L, func, mask, count);
260 return 0;
261}
262
263LJLIB_CF(debug_gethook)
264{
265 char buff[5];
266 int mask = lua_gethookmask(L);
267 lua_Hook hook = lua_gethook(L);
268 if (hook != NULL && hook != hookf) { /* external hook? */
269 lua_pushliteral(L, "external hook");
270 } else {
271 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
272 lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
273 }
274 lua_pushstring(L, unmakemask(mask, buff));
275 lua_pushinteger(L, lua_gethookcount(L));
276 return 3;
277}
278
279/* ------------------------------------------------------------------------ */
280
281LJLIB_CF(debug_debug)
282{
283 for (;;) {
284 char buffer[250];
285 fputs("lua_debug> ", stderr);
286 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
287 strcmp(buffer, "cont\n") == 0)
288 return 0;
289 if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
290 lua_pcall(L, 0, 0, 0)) {
291 fputs(lua_tostring(L, -1), stderr);
292 fputs("\n", stderr);
293 }
294 lua_settop(L, 0); /* remove eventual returns */
295 }
296}
297
298/* ------------------------------------------------------------------------ */
299
300#define LEVELS1 12 /* size of the first part of the stack */
301#define LEVELS2 10 /* size of the second part of the stack */
302
303LJLIB_CF(debug_traceback)
304{
305 int level;
306 int firstpart = 1; /* still before eventual `...' */
307 int arg;
308 lua_State *L1 = getthread(L, &arg);
309 lua_Debug ar;
310 if (lua_isnumber(L, arg+2)) {
311 level = (int)lua_tointeger(L, arg+2);
312 lua_pop(L, 1);
313 }
314 else
315 level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
316 if (lua_gettop(L) == arg)
317 lua_pushliteral(L, "");
318 else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
319 else lua_pushliteral(L, "\n");
320 lua_pushliteral(L, "stack traceback:");
321 while (lua_getstack(L1, level++, &ar)) {
322 if (level > LEVELS1 && firstpart) {
323 /* no more than `LEVELS2' more levels? */
324 if (!lua_getstack(L1, level+LEVELS2, &ar)) {
325 level--; /* keep going */
326 } else {
327 lua_pushliteral(L, "\n\t..."); /* too many levels */
328 /* This only works with LuaJIT 2.x. Avoids O(n^2) behaviour. */
329 lua_getstack(L1, -10, &ar);
330 level = ar.i_ci - LEVELS2;
331 }
332 firstpart = 0;
333 continue;
334 }
335 lua_pushliteral(L, "\n\t");
336 lua_getinfo(L1, "Snl", &ar);
337 lua_pushfstring(L, "%s:", ar.short_src);
338 if (ar.currentline > 0)
339 lua_pushfstring(L, "%d:", ar.currentline);
340 if (*ar.namewhat != '\0') { /* is there a name? */
341 lua_pushfstring(L, " in function " LUA_QS, ar.name);
342 } else {
343 if (*ar.what == 'm') /* main? */
344 lua_pushfstring(L, " in main chunk");
345 else if (*ar.what == 'C' || *ar.what == 't')
346 lua_pushliteral(L, " ?"); /* C function or tail call */
347 else
348 lua_pushfstring(L, " in function <%s:%d>",
349 ar.short_src, ar.linedefined);
350 }
351 lua_concat(L, lua_gettop(L) - arg);
352 }
353 lua_concat(L, lua_gettop(L) - arg);
354 return 1;
355}
356
357/* ------------------------------------------------------------------------ */
358
359#include "lj_libdef.h"
360
361LUALIB_API int luaopen_debug(lua_State *L)
362{
363 LJ_LIB_REG(L, LUA_DBLIBNAME, debug);
364 return 1;
365}
366
diff --git a/libraries/luajit-2.0/src/lib_ffi.c b/libraries/luajit-2.0/src/lib_ffi.c
new file mode 100644
index 0000000..0a8a728
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_ffi.c
@@ -0,0 +1,811 @@
1/*
2** FFI library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lib_ffi_c
7#define LUA_LIB
8
9#include <errno.h>
10
11#include "lua.h"
12#include "lauxlib.h"
13#include "lualib.h"
14
15#include "lj_obj.h"
16
17#if LJ_HASFFI
18
19#include "lj_gc.h"
20#include "lj_err.h"
21#include "lj_str.h"
22#include "lj_tab.h"
23#include "lj_meta.h"
24#include "lj_ctype.h"
25#include "lj_cparse.h"
26#include "lj_cdata.h"
27#include "lj_cconv.h"
28#include "lj_carith.h"
29#include "lj_ccall.h"
30#include "lj_ccallback.h"
31#include "lj_clib.h"
32#include "lj_ff.h"
33#include "lj_lib.h"
34
35/* -- C type checks ------------------------------------------------------- */
36
37/* Check first argument for a C type and returns its ID. */
38static CTypeID ffi_checkctype(lua_State *L, CTState *cts)
39{
40 TValue *o = L->base;
41 if (!(o < L->top)) {
42 err_argtype:
43 lj_err_argtype(L, 1, "C type");
44 }
45 if (tvisstr(o)) { /* Parse an abstract C type declaration. */
46 GCstr *s = strV(o);
47 CPState cp;
48 int errcode;
49 cp.L = L;
50 cp.cts = cts;
51 cp.srcname = strdata(s);
52 cp.p = strdata(s);
53 cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT;
54 errcode = lj_cparse(&cp);
55 if (errcode) lj_err_throw(L, errcode); /* Propagate errors. */
56 return cp.val.id;
57 } else {
58 GCcdata *cd;
59 if (!tviscdata(o)) goto err_argtype;
60 cd = cdataV(o);
61 return cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->typeid;
62 }
63}
64
65/* Check argument for C data and return it. */
66static GCcdata *ffi_checkcdata(lua_State *L, int narg)
67{
68 TValue *o = L->base + narg-1;
69 if (!(o < L->top && tviscdata(o)))
70 lj_err_argt(L, narg, LUA_TCDATA);
71 return cdataV(o);
72}
73
74/* Convert argument to C pointer. */
75static void *ffi_checkptr(lua_State *L, int narg, CTypeID id)
76{
77 CTState *cts = ctype_cts(L);
78 TValue *o = L->base + narg-1;
79 void *p;
80 if (o >= L->top)
81 lj_err_arg(L, narg, LJ_ERR_NOVAL);
82 lj_cconv_ct_tv(cts, ctype_get(cts, id), (uint8_t *)&p, o, CCF_ARG(narg));
83 return p;
84}
85
86/* Convert argument to int32_t. */
87static int32_t ffi_checkint(lua_State *L, int narg)
88{
89 CTState *cts = ctype_cts(L);
90 TValue *o = L->base + narg-1;
91 int32_t i;
92 if (o >= L->top)
93 lj_err_arg(L, narg, LJ_ERR_NOVAL);
94 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o,
95 CCF_ARG(narg));
96 return i;
97}
98
99/* -- C type metamethods -------------------------------------------------- */
100
101#define LJLIB_MODULE_ffi_meta
102
103/* Handle ctype __index/__newindex metamethods. */
104static int ffi_index_meta(lua_State *L, CTState *cts, CType *ct, MMS mm)
105{
106 CTypeID id = ctype_typeid(cts, ct);
107 cTValue *tv = lj_ctype_meta(cts, id, mm);
108 TValue *base = L->base;
109 if (!tv) {
110 const char *s;
111 err_index:
112 s = strdata(lj_ctype_repr(L, id, NULL));
113 if (tvisstr(L->base+1))
114 lj_err_callerv(L, LJ_ERR_FFI_BADMEMBER, s, strVdata(L->base+1));
115 else
116 lj_err_callerv(L, LJ_ERR_FFI_BADIDX, s);
117 }
118 if (!tvisfunc(tv)) {
119 if (mm == MM_index) {
120 cTValue *o = lj_meta_tget(L, tv, base+1);
121 if (o) {
122 if (tvisnil(o)) goto err_index;
123 copyTV(L, L->top-1, o);
124 return 1;
125 }
126 } else {
127 TValue *o = lj_meta_tset(L, tv, base+1);
128 if (o) {
129 copyTV(L, o, base+2);
130 return 0;
131 }
132 }
133 tv = L->top-1;
134 }
135 return lj_meta_tailcall(L, tv);
136}
137
138LJLIB_CF(ffi_meta___index) LJLIB_REC(cdata_index 0)
139{
140 CTState *cts = ctype_cts(L);
141 CTInfo qual = 0;
142 CType *ct;
143 uint8_t *p;
144 TValue *o = L->base;
145 if (!(o+1 < L->top && tviscdata(o))) /* Also checks for presence of key. */
146 lj_err_argt(L, 1, LUA_TCDATA);
147 ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual);
148 if ((qual & 1))
149 return ffi_index_meta(L, cts, ct, MM_index);
150 if (lj_cdata_get(cts, ct, L->top-1, p))
151 lj_gc_check(L);
152 return 1;
153}
154
155LJLIB_CF(ffi_meta___newindex) LJLIB_REC(cdata_index 1)
156{
157 CTState *cts = ctype_cts(L);
158 CTInfo qual = 0;
159 CType *ct;
160 uint8_t *p;
161 TValue *o = L->base;
162 if (!(o+2 < L->top && tviscdata(o))) /* Also checks for key and value. */
163 lj_err_argt(L, 1, LUA_TCDATA);
164 ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual);
165 if ((qual & 1)) {
166 if ((qual & CTF_CONST))
167 lj_err_caller(L, LJ_ERR_FFI_WRCONST);
168 return ffi_index_meta(L, cts, ct, MM_newindex);
169 }
170 lj_cdata_set(cts, ct, p, o+2, qual);
171 return 0;
172}
173
174/* Common handler for cdata arithmetic. */
175static int ffi_arith(lua_State *L)
176{
177 MMS mm = (MMS)(curr_func(L)->c.ffid - (int)FF_ffi_meta___eq + (int)MM_eq);
178 return lj_carith_op(L, mm);
179}
180
181/* The following functions must be in contiguous ORDER MM. */
182LJLIB_CF(ffi_meta___eq) LJLIB_REC(cdata_arith MM_eq)
183{
184 return ffi_arith(L);
185}
186
187LJLIB_CF(ffi_meta___len) LJLIB_REC(cdata_arith MM_len)
188{
189 return ffi_arith(L);
190}
191
192LJLIB_CF(ffi_meta___lt) LJLIB_REC(cdata_arith MM_lt)
193{
194 return ffi_arith(L);
195}
196
197LJLIB_CF(ffi_meta___le) LJLIB_REC(cdata_arith MM_le)
198{
199 return ffi_arith(L);
200}
201
202LJLIB_CF(ffi_meta___concat) LJLIB_REC(cdata_arith MM_concat)
203{
204 return ffi_arith(L);
205}
206
207/* Handle ctype __call metamethod. */
208static int ffi_call_meta(lua_State *L, CTypeID id)
209{
210 CTState *cts = ctype_cts(L);
211 CType *ct = ctype_raw(cts, id);
212 cTValue *tv;
213 if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
214 tv = lj_ctype_meta(cts, id, MM_call);
215 if (!tv)
216 lj_err_callerv(L, LJ_ERR_FFI_BADCALL, strdata(lj_ctype_repr(L, id, NULL)));
217 return lj_meta_tailcall(L, tv);
218}
219
220/* Forward declaration. */
221static int lj_cf_ffi_new(lua_State *L);
222
223LJLIB_CF(ffi_meta___call) LJLIB_REC(cdata_call)
224{
225 GCcdata *cd = ffi_checkcdata(L, 1);
226 int ret;
227 if (cd->typeid == CTID_CTYPEID)
228 return lj_cf_ffi_new(L);
229 if ((ret = lj_ccall_func(L, cd)) < 0)
230 return ffi_call_meta(L, cd->typeid);
231 return ret;
232}
233
234LJLIB_CF(ffi_meta___add) LJLIB_REC(cdata_arith MM_add)
235{
236 return ffi_arith(L);
237}
238
239LJLIB_CF(ffi_meta___sub) LJLIB_REC(cdata_arith MM_sub)
240{
241 return ffi_arith(L);
242}
243
244LJLIB_CF(ffi_meta___mul) LJLIB_REC(cdata_arith MM_mul)
245{
246 return ffi_arith(L);
247}
248
249LJLIB_CF(ffi_meta___div) LJLIB_REC(cdata_arith MM_div)
250{
251 return ffi_arith(L);
252}
253
254LJLIB_CF(ffi_meta___mod) LJLIB_REC(cdata_arith MM_mod)
255{
256 return ffi_arith(L);
257}
258
259LJLIB_CF(ffi_meta___pow) LJLIB_REC(cdata_arith MM_pow)
260{
261 return ffi_arith(L);
262}
263
264LJLIB_CF(ffi_meta___unm) LJLIB_REC(cdata_arith MM_unm)
265{
266 return ffi_arith(L);
267}
268/* End of contiguous ORDER MM. */
269
270LJLIB_CF(ffi_meta___tostring)
271{
272 GCcdata *cd = ffi_checkcdata(L, 1);
273 const char *msg = "cdata<%s>: %p";
274 CTypeID id = cd->typeid;
275 void *p = cdataptr(cd);
276 if (id == CTID_CTYPEID) {
277 msg = "ctype<%s>";
278 id = *(CTypeID *)p;
279 } else {
280 CTState *cts = ctype_cts(L);
281 CType *ct = ctype_raw(cts, id);
282 if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
283 if (ctype_iscomplex(ct->info)) {
284 setstrV(L, L->top-1, lj_ctype_repr_complex(L, cdataptr(cd), ct->size));
285 goto checkgc;
286 } else if (ct->size == 8 && ctype_isinteger(ct->info)) {
287 setstrV(L, L->top-1, lj_ctype_repr_int64(L, *(uint64_t *)cdataptr(cd),
288 (ct->info & CTF_UNSIGNED)));
289 goto checkgc;
290 } else if (ctype_isfunc(ct->info)) {
291 p = *(void **)p;
292 } else {
293 if (ctype_isptr(ct->info)) {
294 p = cdata_getptr(p, ct->size);
295 ct = ctype_rawchild(cts, ct);
296 }
297 if (ctype_isstruct(ct->info) || ctype_isvector(ct->info)) {
298 /* Handle ctype __tostring metamethod. */
299 cTValue *tv = lj_ctype_meta(cts, ctype_typeid(cts, ct), MM_tostring);
300 if (tv)
301 return lj_meta_tailcall(L, tv);
302 }
303 }
304 }
305 lj_str_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), p);
306checkgc:
307 lj_gc_check(L);
308 return 1;
309}
310
311LJLIB_PUSH("ffi") LJLIB_SET(__metatable)
312
313#include "lj_libdef.h"
314
315/* -- C library metamethods ----------------------------------------------- */
316
317#define LJLIB_MODULE_ffi_clib
318
319/* Index C library by a name. */
320static TValue *ffi_clib_index(lua_State *L)
321{
322 TValue *o = L->base;
323 CLibrary *cl;
324 if (!(o < L->top && tvisudata(o) && udataV(o)->udtype == UDTYPE_FFI_CLIB))
325 lj_err_argt(L, 1, LUA_TUSERDATA);
326 cl = (CLibrary *)uddata(udataV(o));
327 if (!(o+1 < L->top && tvisstr(o+1)))
328 lj_err_argt(L, 2, LUA_TSTRING);
329 return lj_clib_index(L, cl, strV(o+1));
330}
331
332LJLIB_CF(ffi_clib___index) LJLIB_REC(clib_index 1)
333{
334 TValue *tv = ffi_clib_index(L);
335 if (tviscdata(tv)) {
336 CTState *cts = ctype_cts(L);
337 GCcdata *cd = cdataV(tv);
338 CType *s = ctype_get(cts, cd->typeid);
339 if (ctype_isextern(s->info)) {
340 CTypeID sid = ctype_cid(s->info);
341 void *sp = *(void **)cdataptr(cd);
342 CType *ct = ctype_raw(cts, sid);
343 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
344 if (lj_cconv_tv_ct(cts, ct, sid, L->top-1, sp))
345 lj_gc_check(L);
346 return 1;
347 }
348 }
349 copyTV(L, L->top-1, tv);
350 return 1;
351}
352
353LJLIB_CF(ffi_clib___newindex) LJLIB_REC(clib_index 0)
354{
355 TValue *tv = ffi_clib_index(L);
356 TValue *o = L->base+2;
357 if (o < L->top && tviscdata(tv)) {
358 CTState *cts = ctype_cts(L);
359 GCcdata *cd = cdataV(tv);
360 CType *d = ctype_get(cts, cd->typeid);
361 if (ctype_isextern(d->info)) {
362 CTInfo qual = 0;
363 for (;;) { /* Skip attributes and collect qualifiers. */
364 d = ctype_child(cts, d);
365 if (!ctype_isattrib(d->info)) break;
366 if (ctype_attrib(d->info) == CTA_QUAL) qual |= d->size;
367 }
368 if (!((d->info|qual) & CTF_CONST)) {
369 lj_cconv_ct_tv(cts, d, *(void **)cdataptr(cd), o, 0);
370 return 0;
371 }
372 }
373 }
374 lj_err_caller(L, LJ_ERR_FFI_WRCONST);
375 return 0; /* unreachable */
376}
377
378LJLIB_CF(ffi_clib___gc)
379{
380 TValue *o = L->base;
381 if (o < L->top && tvisudata(o) && udataV(o)->udtype == UDTYPE_FFI_CLIB)
382 lj_clib_unload((CLibrary *)uddata(udataV(o)));
383 return 0;
384}
385
386#include "lj_libdef.h"
387
388/* -- Callback function metamethods --------------------------------------- */
389
390#define LJLIB_MODULE_ffi_callback
391
392static int ffi_callback_set(lua_State *L, GCfunc *fn)
393{
394 GCcdata *cd = ffi_checkcdata(L, 1);
395 CTState *cts = ctype_cts(L);
396 CType *ct = ctype_raw(cts, cd->typeid);
397 if (ctype_isptr(ct->info) && (LJ_32 || ct->size == 8)) {
398 MSize slot = lj_ccallback_ptr2slot(cts, *(void **)cdataptr(cd));
399 if (slot < cts->cb.sizeid && cts->cb.cbid[slot] != 0) {
400 GCtab *t = cts->miscmap;
401 TValue *tv = lj_tab_setint(L, t, (int32_t)slot);
402 if (fn) {
403 setfuncV(L, tv, fn);
404 lj_gc_anybarriert(L, t);
405 } else {
406 setnilV(tv);
407 cts->cb.cbid[slot] = 0;
408 cts->cb.topid = slot < cts->cb.topid ? slot : cts->cb.topid;
409 }
410 return 0;
411 }
412 }
413 lj_err_caller(L, LJ_ERR_FFI_BADCBACK);
414 return 0;
415}
416
417LJLIB_CF(ffi_callback_free)
418{
419 return ffi_callback_set(L, NULL);
420}
421
422LJLIB_CF(ffi_callback_set)
423{
424 GCfunc *fn = lj_lib_checkfunc(L, 2);
425 return ffi_callback_set(L, fn);
426}
427
428LJLIB_PUSH(top-1) LJLIB_SET(__index)
429
430#include "lj_libdef.h"
431
432/* -- FFI library functions ----------------------------------------------- */
433
434#define LJLIB_MODULE_ffi
435
436LJLIB_CF(ffi_cdef)
437{
438 GCstr *s = lj_lib_checkstr(L, 1);
439 CPState cp;
440 int errcode;
441 cp.L = L;
442 cp.cts = ctype_cts(L);
443 cp.srcname = strdata(s);
444 cp.p = strdata(s);
445 cp.mode = CPARSE_MODE_MULTI|CPARSE_MODE_DIRECT;
446 errcode = lj_cparse(&cp);
447 if (errcode) lj_err_throw(L, errcode); /* Propagate errors. */
448 lj_gc_check(L);
449 return 0;
450}
451
452LJLIB_CF(ffi_new) LJLIB_REC(.)
453{
454 CTState *cts = ctype_cts(L);
455 CTypeID id = ffi_checkctype(L, cts);
456 CType *ct = ctype_raw(cts, id);
457 CTSize sz;
458 CTInfo info = lj_ctype_info(cts, id, &sz);
459 TValue *o = L->base+1;
460 GCcdata *cd;
461 if ((info & CTF_VLA)) {
462 o++;
463 sz = lj_ctype_vlsize(cts, ct, (CTSize)ffi_checkint(L, 2));
464 }
465 if (sz == CTSIZE_INVALID)
466 lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE);
467 if (!(info & CTF_VLA) && ctype_align(info) <= CT_MEMALIGN)
468 cd = lj_cdata_new(cts, id, sz);
469 else
470 cd = lj_cdata_newv(cts, id, sz, ctype_align(info));
471 setcdataV(L, o-1, cd); /* Anchor the uninitialized cdata. */
472 lj_cconv_ct_init(cts, ct, sz, cdataptr(cd),
473 o, (MSize)(L->top - o)); /* Initialize cdata. */
474 if (ctype_isstruct(ct->info)) {
475 /* Handle ctype __gc metamethod. Use the fast lookup here. */
476 cTValue *tv = lj_tab_getinth(cts->miscmap, -(int32_t)id);
477 if (tv && tvistab(tv) && (tv = lj_meta_fast(L, tabV(tv), MM_gc))) {
478 GCtab *t = cts->finalizer;
479 if (gcref(t->metatable)) {
480 /* Add to finalizer table, if still enabled. */
481 copyTV(L, lj_tab_set(L, t, o-1), tv);
482 lj_gc_anybarriert(L, t);
483 cd->marked |= LJ_GC_CDATA_FIN;
484 }
485 }
486 }
487 L->top = o; /* Only return the cdata itself. */
488 lj_gc_check(L);
489 return 1;
490}
491
492LJLIB_CF(ffi_cast) LJLIB_REC(ffi_new)
493{
494 CTState *cts = ctype_cts(L);
495 CTypeID id = ffi_checkctype(L, cts);
496 CType *d = ctype_raw(cts, id);
497 TValue *o = lj_lib_checkany(L, 2);
498 L->top = o+1; /* Make sure this is the last item on the stack. */
499 if (!(ctype_isnum(d->info) || ctype_isptr(d->info) || ctype_isenum(d->info)))
500 lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
501 if (!(tviscdata(o) && cdataV(o)->typeid == id)) {
502 GCcdata *cd = lj_cdata_new(cts, id, d->size);
503 lj_cconv_ct_tv(cts, d, cdataptr(cd), o, CCF_CAST);
504 setcdataV(L, o, cd);
505 lj_gc_check(L);
506 }
507 return 1;
508}
509
510LJLIB_CF(ffi_typeof)
511{
512 CTState *cts = ctype_cts(L);
513 CTypeID id = ffi_checkctype(L, cts);
514 GCcdata *cd = lj_cdata_new(cts, CTID_CTYPEID, 4);
515 *(CTypeID *)cdataptr(cd) = id;
516 setcdataV(L, L->top-1, cd);
517 lj_gc_check(L);
518 return 1;
519}
520
521LJLIB_CF(ffi_istype) LJLIB_REC(ffi_istype)
522{
523 CTState *cts = ctype_cts(L);
524 CTypeID id1 = ffi_checkctype(L, cts);
525 TValue *o = lj_lib_checkany(L, 2);
526 int b = 0;
527 if (tviscdata(o)) {
528 GCcdata *cd = cdataV(o);
529 CTypeID id2 = cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) :
530 cd->typeid;
531 CType *ct1 = lj_ctype_rawref(cts, id1);
532 CType *ct2 = lj_ctype_rawref(cts, id2);
533 if (ct1 == ct2) {
534 b = 1;
535 } else if (ctype_type(ct1->info) == ctype_type(ct2->info) &&
536 ct1->size == ct2->size) {
537 if (ctype_ispointer(ct1->info))
538 b = lj_cconv_compatptr(cts, ct1, ct2, CCF_IGNQUAL);
539 else if (ctype_isnum(ct1->info) || ctype_isvoid(ct1->info))
540 b = (((ct1->info ^ ct2->info) & ~CTF_QUAL) == 0);
541 } else if (ctype_isstruct(ct1->info) && ctype_isptr(ct2->info) &&
542 ct1 == ctype_rawchild(cts, ct2)) {
543 b = 1;
544 }
545 }
546 setboolV(L->top-1, b);
547 setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */
548 return 1;
549}
550
551LJLIB_CF(ffi_sizeof)
552{
553 CTState *cts = ctype_cts(L);
554 CTypeID id = ffi_checkctype(L, cts);
555 CTSize sz;
556 if (LJ_UNLIKELY(tviscdata(L->base) && cdataisv(cdataV(L->base)))) {
557 sz = cdatavlen(cdataV(L->base));
558 } else {
559 CType *ct = lj_ctype_rawref(cts, id);
560 if (ctype_isvltype(ct->info))
561 sz = lj_ctype_vlsize(cts, ct, (CTSize)ffi_checkint(L, 2));
562 else
563 sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_INVALID;
564 if (LJ_UNLIKELY(sz == CTSIZE_INVALID)) {
565 setnilV(L->top-1);
566 return 1;
567 }
568 }
569 setintV(L->top-1, (int32_t)sz);
570 return 1;
571}
572
573LJLIB_CF(ffi_alignof)
574{
575 CTState *cts = ctype_cts(L);
576 CTypeID id = ffi_checkctype(L, cts);
577 CTSize sz = 0;
578 CTInfo info = lj_ctype_info(cts, id, &sz);
579 setintV(L->top-1, 1 << ctype_align(info));
580 return 1;
581}
582
583LJLIB_CF(ffi_offsetof)
584{
585 CTState *cts = ctype_cts(L);
586 CTypeID id = ffi_checkctype(L, cts);
587 GCstr *name = lj_lib_checkstr(L, 2);
588 CType *ct = lj_ctype_rawref(cts, id);
589 CTSize ofs;
590 if (ctype_isstruct(ct->info) && ct->size != CTSIZE_INVALID) {
591 CType *fct = lj_ctype_getfield(cts, ct, name, &ofs);
592 if (fct) {
593 setintV(L->top-1, ofs);
594 if (ctype_isfield(fct->info)) {
595 return 1;
596 } else if (ctype_isbitfield(fct->info)) {
597 setintV(L->top++, ctype_bitpos(fct->info));
598 setintV(L->top++, ctype_bitbsz(fct->info));
599 return 3;
600 }
601 }
602 }
603 return 0;
604}
605
606LJLIB_CF(ffi_errno) LJLIB_REC(.)
607{
608 int err = errno;
609 if (L->top > L->base)
610 errno = ffi_checkint(L, 1);
611 setintV(L->top++, err);
612 return 1;
613}
614
615LJLIB_CF(ffi_string) LJLIB_REC(.)
616{
617 CTState *cts = ctype_cts(L);
618 TValue *o = lj_lib_checkany(L, 1);
619 const char *p;
620 size_t len;
621 if (o+1 < L->top) {
622 len = (size_t)ffi_checkint(L, 2);
623 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o,
624 CCF_ARG(1));
625 } else {
626 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o,
627 CCF_ARG(1));
628 len = strlen(p);
629 }
630 L->top = o+1; /* Make sure this is the last item on the stack. */
631 setstrV(L, o, lj_str_new(L, p, len));
632 lj_gc_check(L);
633 return 1;
634}
635
636LJLIB_CF(ffi_copy) LJLIB_REC(.)
637{
638 void *dp = ffi_checkptr(L, 1, CTID_P_VOID);
639 void *sp = ffi_checkptr(L, 2, CTID_P_CVOID);
640 TValue *o = L->base+1;
641 CTSize len;
642 if (tvisstr(o) && o+1 >= L->top)
643 len = strV(o)->len+1; /* Copy Lua string including trailing '\0'. */
644 else
645 len = (CTSize)ffi_checkint(L, 3);
646 memcpy(dp, sp, len);
647 return 0;
648}
649
650LJLIB_CF(ffi_fill) LJLIB_REC(.)
651{
652 void *dp = ffi_checkptr(L, 1, CTID_P_VOID);
653 CTSize len = (CTSize)ffi_checkint(L, 2);
654 int32_t fill = 0;
655 if (L->base+2 < L->top && !tvisnil(L->base+2)) fill = ffi_checkint(L, 3);
656 memset(dp, fill, len);
657 return 0;
658}
659
660#define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be)
661
662/* Test ABI string. */
663LJLIB_CF(ffi_abi) LJLIB_REC(.)
664{
665 GCstr *s = lj_lib_checkstr(L, 1);
666 int b = 0;
667 switch (s->hash) {
668#if LJ_64
669 case H_(849858eb,ad35fd06): b = 1; break; /* 64bit */
670#else
671 case H_(662d3c79,d0e22477): b = 1; break; /* 32bit */
672#endif
673#if LJ_ARCH_HASFPU
674 case H_(e33ee463,e33ee463): b = 1; break; /* fpu */
675#endif
676#if LJ_ABI_SOFTFP
677 case H_(61211a23,c2e8c81c): b = 1; break; /* softfp */
678#else
679 case H_(539417a8,8ce0812f): b = 1; break; /* hardfp */
680#endif
681#if LJ_ABI_EABI
682 case H_(2182df8f,f2ed1152): b = 1; break; /* eabi */
683#endif
684#if LJ_ABI_WIN
685 case H_(4ab624a8,4ab624a8): b = 1; break; /* win */
686#endif
687 case H_(3af93066,1f001464): b = 1; break; /* le/be */
688 default:
689 break;
690 }
691 setboolV(L->top-1, b);
692 setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */
693 return 1;
694}
695
696#undef H_
697
698LJLIB_PUSH(top-8) LJLIB_SET(!) /* Store reference to miscmap table. */
699
700LJLIB_CF(ffi_metatype)
701{
702 CTState *cts = ctype_cts(L);
703 CTypeID id = ffi_checkctype(L, cts);
704 GCtab *mt = lj_lib_checktab(L, 2);
705 GCtab *t = cts->miscmap;
706 CType *ct = ctype_get(cts, id); /* Only allow raw types. */
707 TValue *tv;
708 GCcdata *cd;
709 if (!(ctype_isstruct(ct->info) || ctype_iscomplex(ct->info) ||
710 ctype_isvector(ct->info)))
711 lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
712 tv = lj_tab_setinth(L, t, -(int32_t)id);
713 if (!tvisnil(tv))
714 lj_err_caller(L, LJ_ERR_PROTMT);
715 settabV(L, tv, mt);
716 lj_gc_anybarriert(L, t);
717 cd = lj_cdata_new(cts, CTID_CTYPEID, 4);
718 *(CTypeID *)cdataptr(cd) = id;
719 setcdataV(L, L->top-1, cd);
720 lj_gc_check(L);
721 return 1;
722}
723
724LJLIB_PUSH(top-7) LJLIB_SET(!) /* Store reference to finalizer table. */
725
726LJLIB_CF(ffi_gc)
727{
728 GCcdata *cd = ffi_checkcdata(L, 1);
729 TValue *fin = lj_lib_checkany(L, 2);
730 CTState *cts = ctype_cts(L);
731 GCtab *t = cts->finalizer;
732 CType *ct = ctype_raw(cts, cd->typeid);
733 if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) ||
734 ctype_isrefarray(ct->info)))
735 lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
736 if (gcref(t->metatable)) { /* Update finalizer table, if still enabled. */
737 copyTV(L, lj_tab_set(L, t, L->base), fin);
738 lj_gc_anybarriert(L, t);
739 if (!tvisnil(fin))
740 cd->marked |= LJ_GC_CDATA_FIN;
741 else
742 cd->marked &= ~LJ_GC_CDATA_FIN;
743 }
744 L->top = L->base+1; /* Pass through the cdata object. */
745 return 1;
746}
747
748LJLIB_PUSH(top-5) LJLIB_SET(!) /* Store clib metatable in func environment. */
749
750LJLIB_CF(ffi_load)
751{
752 GCstr *name = lj_lib_checkstr(L, 1);
753 int global = (L->base+1 < L->top && tvistruecond(L->base+1));
754 lj_clib_load(L, tabref(curr_func(L)->c.env), name, global);
755 return 1;
756}
757
758LJLIB_PUSH(top-4) LJLIB_SET(C)
759LJLIB_PUSH(top-3) LJLIB_SET(os)
760LJLIB_PUSH(top-2) LJLIB_SET(arch)
761
762#include "lj_libdef.h"
763
764/* ------------------------------------------------------------------------ */
765
766/* Create special weak-keyed finalizer table. */
767static GCtab *ffi_finalizer(lua_State *L)
768{
769 /* NOBARRIER: The table is new (marked white). */
770 GCtab *t = lj_tab_new(L, 0, 1);
771 settabV(L, L->top++, t);
772 setgcref(t->metatable, obj2gco(t));
773 setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
774 lj_str_newlit(L, "K"));
775 t->nomm = (uint8_t)(~(1u<<MM_mode));
776 return t;
777}
778
779/* Register FFI module as loaded. */
780static void ffi_register_module(lua_State *L)
781{
782 cTValue *tmp = lj_tab_getstr(tabV(registry(L)), lj_str_newlit(L, "_LOADED"));
783 if (tmp && tvistab(tmp)) {
784 GCtab *t = tabV(tmp);
785 copyTV(L, lj_tab_setstr(L, t, lj_str_newlit(L, LUA_FFILIBNAME)), L->top-1);
786 lj_gc_anybarriert(L, t);
787 }
788}
789
790LUALIB_API int luaopen_ffi(lua_State *L)
791{
792 CTState *cts = lj_ctype_init(L);
793 settabV(L, L->top++, (cts->miscmap = lj_tab_new(L, 0, 1)));
794 cts->finalizer = ffi_finalizer(L);
795 LJ_LIB_REG(L, NULL, ffi_meta);
796 /* NOBARRIER: basemt is a GC root. */
797 setgcref(basemt_it(G(L), LJ_TCDATA), obj2gco(tabV(L->top-1)));
798 LJ_LIB_REG(L, NULL, ffi_clib);
799 LJ_LIB_REG(L, NULL, ffi_callback);
800 /* NOBARRIER: the key is new and lj_tab_newkey() handles the barrier. */
801 settabV(L, lj_tab_setstr(L, cts->miscmap, &cts->g->strempty), tabV(L->top-1));
802 L->top--;
803 lj_clib_default(L, tabV(L->top-1)); /* Create ffi.C default namespace. */
804 lua_pushliteral(L, LJ_OS_NAME);
805 lua_pushliteral(L, LJ_ARCH_NAME);
806 LJ_LIB_REG(L, NULL, ffi); /* Note: no global "ffi" created! */
807 ffi_register_module(L);
808 return 1;
809}
810
811#endif
diff --git a/libraries/luajit-2.0/src/lib_init.c b/libraries/luajit-2.0/src/lib_init.c
new file mode 100644
index 0000000..8501e21
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_init.c
@@ -0,0 +1,53 @@
1/*
2** Library initialization.
3** Major parts taken verbatim from the Lua interpreter.
4** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
5*/
6
7#define lib_init_c
8#define LUA_LIB
9
10#include "lua.h"
11#include "lauxlib.h"
12#include "lualib.h"
13
14#include "lj_arch.h"
15
16static const luaL_Reg lj_lib_load[] = {
17 { "", luaopen_base },
18 { LUA_LOADLIBNAME, luaopen_package },
19 { LUA_TABLIBNAME, luaopen_table },
20 { LUA_IOLIBNAME, luaopen_io },
21 { LUA_OSLIBNAME, luaopen_os },
22 { LUA_STRLIBNAME, luaopen_string },
23 { LUA_MATHLIBNAME, luaopen_math },
24 { LUA_DBLIBNAME, luaopen_debug },
25 { LUA_BITLIBNAME, luaopen_bit },
26 { LUA_JITLIBNAME, luaopen_jit },
27 { NULL, NULL }
28};
29
30static const luaL_Reg lj_lib_preload[] = {
31#if LJ_HASFFI
32 { LUA_FFILIBNAME, luaopen_ffi },
33#endif
34 { NULL, NULL }
35};
36
37LUALIB_API void luaL_openlibs(lua_State *L)
38{
39 const luaL_Reg *lib;
40 for (lib = lj_lib_load; lib->func; lib++) {
41 lua_pushcfunction(L, lib->func);
42 lua_pushstring(L, lib->name);
43 lua_call(L, 1, 0);
44 }
45 luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD",
46 sizeof(lj_lib_preload)/sizeof(lj_lib_preload[0])-1);
47 for (lib = lj_lib_preload; lib->func; lib++) {
48 lua_pushcfunction(L, lib->func);
49 lua_setfield(L, -2, lib->name);
50 }
51 lua_pop(L, 1);
52}
53
diff --git a/libraries/luajit-2.0/src/lib_io.c b/libraries/luajit-2.0/src/lib_io.c
new file mode 100644
index 0000000..7a59cc4
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_io.c
@@ -0,0 +1,533 @@
1/*
2** I/O library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#include <errno.h>
10#include <stdio.h>
11
12#define lib_io_c
13#define LUA_LIB
14
15#include "lua.h"
16#include "lauxlib.h"
17#include "lualib.h"
18
19#include "lj_obj.h"
20#include "lj_gc.h"
21#include "lj_err.h"
22#include "lj_str.h"
23#include "lj_ff.h"
24#include "lj_trace.h"
25#include "lj_lib.h"
26
27/* Userdata payload for I/O file. */
28typedef struct IOFileUD {
29 FILE *fp; /* File handle. */
30 uint32_t type; /* File type. */
31} IOFileUD;
32
33#define IOFILE_TYPE_FILE 0 /* Regular file. */
34#define IOFILE_TYPE_PIPE 1 /* Pipe. */
35#define IOFILE_TYPE_STDF 2 /* Standard file handle. */
36#define IOFILE_TYPE_MASK 3
37
38#define IOFILE_FLAG_CLOSE 4 /* Close after io.lines() iterator. */
39
40#define IOSTDF_UD(L, id) (&gcref(G(L)->gcroot[(id)])->ud)
41#define IOSTDF_IOF(L, id) ((IOFileUD *)uddata(IOSTDF_UD(L, (id))))
42
43/* -- Error handling ------------------------------------------------------ */
44
45static int io_pushresult(lua_State *L, int ok, const char *fname)
46{
47 if (ok) {
48 setboolV(L->top++, 1);
49 return 1;
50 } else {
51 int en = errno; /* Lua API calls may change this value. */
52 setnilV(L->top++);
53 if (fname)
54 lua_pushfstring(L, "%s: %s", fname, strerror(en));
55 else
56 lua_pushfstring(L, "%s", strerror(en));
57 setintV(L->top++, en);
58 lj_trace_abort(G(L));
59 return 3;
60 }
61}
62
63/* -- Open/close helpers -------------------------------------------------- */
64
65static IOFileUD *io_tofilep(lua_State *L)
66{
67 if (!(L->base < L->top && tvisudata(L->base) &&
68 udataV(L->base)->udtype == UDTYPE_IO_FILE))
69 lj_err_argtype(L, 1, "FILE*");
70 return (IOFileUD *)uddata(udataV(L->base));
71}
72
73static IOFileUD *io_tofile(lua_State *L)
74{
75 IOFileUD *iof = io_tofilep(L);
76 if (iof->fp == NULL)
77 lj_err_caller(L, LJ_ERR_IOCLFL);
78 return iof;
79}
80
81static FILE *io_stdfile(lua_State *L, ptrdiff_t id)
82{
83 IOFileUD *iof = IOSTDF_IOF(L, id);
84 if (iof->fp == NULL)
85 lj_err_caller(L, LJ_ERR_IOSTDCL);
86 return iof->fp;
87}
88
89static IOFileUD *io_file_new(lua_State *L)
90{
91 IOFileUD *iof = (IOFileUD *)lua_newuserdata(L, sizeof(IOFileUD));
92 GCudata *ud = udataV(L->top-1);
93 ud->udtype = UDTYPE_IO_FILE;
94 /* NOBARRIER: The GCudata is new (marked white). */
95 setgcrefr(ud->metatable, curr_func(L)->c.env);
96 iof->fp = NULL;
97 iof->type = IOFILE_TYPE_FILE;
98 return iof;
99}
100
101static IOFileUD *io_file_open(lua_State *L, const char *mode)
102{
103 const char *fname = strdata(lj_lib_checkstr(L, 1));
104 IOFileUD *iof = io_file_new(L);
105 iof->fp = fopen(fname, mode);
106 if (iof->fp == NULL)
107 luaL_argerror(L, 1, lj_str_pushf(L, "%s: %s", fname, strerror(errno)));
108 return iof;
109}
110
111static int io_file_close(lua_State *L, IOFileUD *iof)
112{
113 int ok;
114 if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_FILE) {
115 ok = (fclose(iof->fp) == 0);
116 } else if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_PIPE) {
117#if LJ_TARGET_POSIX
118 ok = (pclose(iof->fp) != -1);
119#elif LJ_TARGET_WINDOWS
120 ok = (_pclose(iof->fp) != -1);
121#else
122 ok = 0;
123#endif
124 } else {
125 lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF);
126 setnilV(L->top++);
127 lua_pushliteral(L, "cannot close standard file");
128 return 2;
129 }
130 iof->fp = NULL;
131 return io_pushresult(L, ok, NULL);
132}
133
134/* -- Read/write helpers -------------------------------------------------- */
135
136static int io_file_readnum(lua_State *L, FILE *fp)
137{
138 lua_Number d;
139 if (fscanf(fp, LUA_NUMBER_SCAN, &d) == 1) {
140 if (LJ_DUALNUM) {
141 int32_t i = lj_num2int(d);
142 if (d == (lua_Number)i && !tvismzero((cTValue *)&d)) {
143 setintV(L->top++, i);
144 return 1;
145 }
146 }
147 setnumV(L->top++, d);
148 return 1;
149 } else {
150 setnilV(L->top++);
151 return 0;
152 }
153}
154
155static int io_file_testeof(lua_State *L, FILE *fp)
156{
157 int c = getc(fp);
158 ungetc(c, fp);
159 lua_pushlstring(L, NULL, 0);
160 return (c != EOF);
161}
162
163static int io_file_readline(lua_State *L, FILE *fp, size_t chop)
164{
165 luaL_Buffer b;
166 luaL_buffinit(L, &b);
167 for (;;) {
168 size_t len;
169 char *p = luaL_prepbuffer(&b);
170 if (fgets(p, LUAL_BUFFERSIZE, fp) == NULL) { /* EOF? */
171 luaL_pushresult(&b);
172 return (strV(L->top-1)->len > 0); /* Anything read? */
173 }
174 len = strlen(p);
175 if (len == 0 || p[len-1] != '\n') { /* Partial line? */
176 luaL_addsize(&b, len);
177 } else {
178 luaL_addsize(&b, len - chop); /* Keep or remove EOL. */
179 luaL_pushresult(&b);
180 return 1; /* Got at least an EOL. */
181 }
182 }
183}
184
185static int io_file_readchars(lua_State *L, FILE *fp, size_t n)
186{
187 size_t rlen; /* how much to read */
188 size_t nr; /* number of chars actually read */
189 luaL_Buffer b;
190 luaL_buffinit(L, &b);
191 rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
192 do {
193 char *p = luaL_prepbuffer(&b);
194 if (rlen > n) rlen = n; /* cannot read more than asked */
195 nr = fread(p, 1, rlen, fp);
196 luaL_addsize(&b, nr);
197 n -= nr; /* still have to read `n' chars */
198 } while (n > 0 && nr == rlen); /* until end of count or eof */
199 luaL_pushresult(&b); /* close buffer */
200 return (n == 0 || strV(L->top-1)->len > 0);
201}
202
203static int io_file_read(lua_State *L, FILE *fp, int start)
204{
205 int ok, n, nargs = (int)(L->top - L->base) - start;
206 clearerr(fp);
207 if (nargs == 0) {
208 ok = io_file_readline(L, fp, 1);
209 n = start+1; /* Return 1 result. */
210 } else {
211 /* The results plus the buffers go on top of the args. */
212 luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
213 ok = 1;
214 for (n = start; nargs-- && ok; n++) {
215 if (tvisstr(L->base+n)) {
216 const char *p = strVdata(L->base+n);
217 if (p[0] != '*')
218 lj_err_arg(L, n+1, LJ_ERR_INVOPT);
219 if (p[1] == 'n')
220 ok = io_file_readnum(L, fp);
221 else if ((p[1] & ~0x20) == 'L')
222 ok = io_file_readline(L, fp, (p[1] == 'l'));
223 else if (p[1] == 'a')
224 io_file_readchars(L, fp, ~((size_t)0));
225 else
226 lj_err_arg(L, n+1, LJ_ERR_INVFMT);
227 } else if (tvisnumber(L->base+n)) {
228 size_t len = (size_t)lj_lib_checkint(L, n+1);
229 ok = len ? io_file_readchars(L, fp, len) : io_file_testeof(L, fp);
230 } else {
231 lj_err_arg(L, n+1, LJ_ERR_INVOPT);
232 }
233 }
234 }
235 if (ferror(fp))
236 return io_pushresult(L, 0, NULL);
237 if (!ok)
238 setnilV(L->top-1); /* Replace last result with nil. */
239 return n - start;
240}
241
242static int io_file_write(lua_State *L, FILE *fp, int start)
243{
244 cTValue *tv;
245 int status = 1;
246 for (tv = L->base+start; tv < L->top; tv++) {
247 if (tvisstr(tv)) {
248 MSize len = strV(tv)->len;
249 status = status && (fwrite(strVdata(tv), 1, len, fp) == len);
250 } else if (tvisint(tv)) {
251 char buf[LJ_STR_INTBUF];
252 char *p = lj_str_bufint(buf, intV(tv));
253 size_t len = (size_t)(buf+LJ_STR_INTBUF-p);
254 status = status && (fwrite(p, 1, len, fp) == len);
255 } else if (tvisnum(tv)) {
256 status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
257 } else {
258 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
259 }
260 }
261 return io_pushresult(L, status, NULL);
262}
263
264/* -- I/O file methods ---------------------------------------------------- */
265
266#define LJLIB_MODULE_io_method
267
268LJLIB_CF(io_method_close)
269{
270 IOFileUD *iof = L->base < L->top ? io_tofile(L) :
271 IOSTDF_IOF(L, GCROOT_IO_OUTPUT);
272 return io_file_close(L, iof);
273}
274
275LJLIB_CF(io_method_read)
276{
277 return io_file_read(L, io_tofile(L)->fp, 1);
278}
279
280LJLIB_CF(io_method_write) LJLIB_REC(io_write 0)
281{
282 return io_file_write(L, io_tofile(L)->fp, 1);
283}
284
285LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0)
286{
287 return io_pushresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
288}
289
290LJLIB_CF(io_method_seek)
291{
292 FILE *fp = io_tofile(L)->fp;
293 int opt = lj_lib_checkopt(L, 2, 1, "\3set\3cur\3end");
294 int64_t ofs = 0;
295 cTValue *o;
296 int res;
297 if (opt == 0) opt = SEEK_SET;
298 else if (opt == 1) opt = SEEK_CUR;
299 else if (opt == 2) opt = SEEK_END;
300 o = L->base+2;
301 if (o < L->top) {
302 if (tvisint(o))
303 ofs = (int64_t)intV(o);
304 else if (tvisnum(o))
305 ofs = (int64_t)numV(o);
306 else if (!tvisnil(o))
307 lj_err_argt(L, 3, LUA_TNUMBER);
308 }
309#if LJ_TARGET_POSIX
310 res = fseeko(fp, ofs, opt);
311#elif _MSC_VER >= 1400
312 res = _fseeki64(fp, ofs, opt);
313#elif defined(__MINGW32__)
314 res = fseeko64(fp, ofs, opt);
315#else
316 res = fseek(fp, (long)ofs, opt);
317#endif
318 if (res)
319 return io_pushresult(L, 0, NULL);
320#if LJ_TARGET_POSIX
321 ofs = ftello(fp);
322#elif _MSC_VER >= 1400
323 ofs = _ftelli64(fp);
324#elif defined(__MINGW32__)
325 ofs = ftello64(fp);
326#else
327 ofs = (int64_t)ftell(fp);
328#endif
329 setint64V(L->top-1, ofs);
330 return 1;
331}
332
333LJLIB_CF(io_method_setvbuf)
334{
335 FILE *fp = io_tofile(L)->fp;
336 int opt = lj_lib_checkopt(L, 2, -1, "\4full\4line\2no");
337 size_t sz = (size_t)lj_lib_optint(L, 3, LUAL_BUFFERSIZE);
338 if (opt == 0) opt = _IOFBF;
339 else if (opt == 1) opt = _IOLBF;
340 else if (opt == 2) opt = _IONBF;
341 return io_pushresult(L, setvbuf(fp, NULL, opt, sz) == 0, NULL);
342}
343
344LJLIB_PUSH(top-2) /* io_lines_iter */
345LJLIB_CF(io_method_lines)
346{
347 io_tofile(L);
348 setfuncV(L, L->top, funcV(lj_lib_upvalue(L, 1)));
349 setudataV(L, L->top+1, udataV(L->base));
350 L->top += 2;
351 return 2;
352}
353
354LJLIB_CF(io_method___gc)
355{
356 IOFileUD *iof = io_tofilep(L);
357 if (iof->fp != NULL && (iof->type & IOFILE_TYPE_MASK) != IOFILE_TYPE_STDF)
358 io_file_close(L, iof);
359 return 0;
360}
361
362LJLIB_CF(io_method___tostring)
363{
364 IOFileUD *iof = io_tofilep(L);
365 if (iof->fp != NULL)
366 lua_pushfstring(L, "file (%p)", iof->fp);
367 else
368 lua_pushliteral(L, "file (closed)");
369 return 1;
370}
371
372LJLIB_PUSH(top-1) LJLIB_SET(__index)
373
374#include "lj_libdef.h"
375
376/* -- I/O library functions ----------------------------------------------- */
377
378#define LJLIB_MODULE_io
379
380LJLIB_PUSH(top-2) LJLIB_SET(!) /* Set environment. */
381
382LJLIB_CF(io_open)
383{
384 const char *fname = strdata(lj_lib_checkstr(L, 1));
385 GCstr *s = lj_lib_optstr(L, 2);
386 const char *mode = s ? strdata(s) : "r";
387 IOFileUD *iof = io_file_new(L);
388 iof->fp = fopen(fname, mode);
389 return iof->fp != NULL ? 1 : io_pushresult(L, 0, fname);
390}
391
392LJLIB_CF(io_popen)
393{
394#if LJ_TARGET_POSIX || LJ_TARGET_WINDOWS
395 const char *fname = strdata(lj_lib_checkstr(L, 1));
396 GCstr *s = lj_lib_optstr(L, 2);
397 const char *mode = s ? strdata(s) : "r";
398 IOFileUD *iof = io_file_new(L);
399 iof->type = IOFILE_TYPE_PIPE;
400#if LJ_TARGET_POSIX
401 fflush(NULL);
402 iof->fp = popen(fname, mode);
403#else
404 iof->fp = _popen(fname, mode);
405#endif
406 return iof->fp != NULL ? 1 : io_pushresult(L, 0, fname);
407#else
408 luaL_error(L, LUA_QL("popen") " not supported");
409#endif
410}
411
412LJLIB_CF(io_tmpfile)
413{
414 IOFileUD *iof = io_file_new(L);
415 iof->fp = tmpfile();
416 return iof->fp != NULL ? 1 : io_pushresult(L, 0, NULL);
417}
418
419LJLIB_CF(io_close)
420{
421 return lj_cf_io_method_close(L);
422}
423
424LJLIB_CF(io_read)
425{
426 return io_file_read(L, io_stdfile(L, GCROOT_IO_INPUT), 0);
427}
428
429LJLIB_CF(io_write) LJLIB_REC(io_write GCROOT_IO_OUTPUT)
430{
431 return io_file_write(L, io_stdfile(L, GCROOT_IO_OUTPUT), 0);
432}
433
434LJLIB_CF(io_flush) LJLIB_REC(io_flush GCROOT_IO_OUTPUT)
435{
436 return io_pushresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)) == 0, NULL);
437}
438
439static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode)
440{
441 if (L->base < L->top && !tvisnil(L->base)) {
442 if (tvisudata(L->base)) {
443 io_tofile(L);
444 L->top = L->base+1;
445 } else {
446 io_file_open(L, mode);
447 }
448 /* NOBARRIER: The standard I/O handles are GC roots. */
449 setgcref(G(L)->gcroot[id], gcV(L->top-1));
450 } else {
451 setudataV(L, L->top++, IOSTDF_UD(L, id));
452 }
453 return 1;
454}
455
456LJLIB_CF(io_input)
457{
458 return io_std_getset(L, GCROOT_IO_INPUT, "r");
459}
460
461LJLIB_CF(io_output)
462{
463 return io_std_getset(L, GCROOT_IO_OUTPUT, "w");
464}
465
466LJLIB_NOREG LJLIB_CF(io_lines_iter)
467{
468 IOFileUD *iof = io_tofile(L);
469 int ok = io_file_readline(L, iof->fp, 1);
470 if (ferror(iof->fp))
471 lj_err_callermsg(L, strerror(errno));
472 if (!ok && (iof->type & IOFILE_FLAG_CLOSE))
473 io_file_close(L, iof); /* Return values are ignored (ok is 0). */
474 return ok;
475}
476
477LJLIB_PUSH(top-3) /* io_lines_iter */
478LJLIB_CF(io_lines)
479{
480 if (L->base < L->top && !tvisnil(L->base)) { /* io.lines(fname) */
481 IOFileUD *iof = io_file_open(L, "r");
482 iof->type = IOFILE_TYPE_FILE|IOFILE_FLAG_CLOSE;
483 setfuncV(L, L->top-2, funcV(lj_lib_upvalue(L, 1)));
484 } else { /* io.lines() iterates over stdin. */
485 setfuncV(L, L->top, funcV(lj_lib_upvalue(L, 1)));
486 setudataV(L, L->top+1, IOSTDF_UD(L, GCROOT_IO_INPUT));
487 L->top += 2;
488 }
489 return 2;
490}
491
492LJLIB_CF(io_type)
493{
494 cTValue *o = lj_lib_checkany(L, 1);
495 if (!(tvisudata(o) && udataV(o)->udtype == UDTYPE_IO_FILE))
496 setnilV(L->top++);
497 else if (((IOFileUD *)uddata(udataV(o)))->fp != NULL)
498 lua_pushliteral(L, "file");
499 else
500 lua_pushliteral(L, "closed file");
501 return 1;
502}
503
504#include "lj_libdef.h"
505
506/* ------------------------------------------------------------------------ */
507
508static GCobj *io_std_new(lua_State *L, FILE *fp, const char *name)
509{
510 IOFileUD *iof = (IOFileUD *)lua_newuserdata(L, sizeof(IOFileUD));
511 GCudata *ud = udataV(L->top-1);
512 ud->udtype = UDTYPE_IO_FILE;
513 /* NOBARRIER: The GCudata is new (marked white). */
514 setgcref(ud->metatable, gcV(L->top-3));
515 iof->fp = fp;
516 iof->type = IOFILE_TYPE_STDF;
517 lua_setfield(L, -2, name);
518 return obj2gco(ud);
519}
520
521LUALIB_API int luaopen_io(lua_State *L)
522{
523 lj_lib_pushcf(L, lj_cf_io_lines_iter, FF_io_lines_iter);
524 LJ_LIB_REG(L, NULL, io_method);
525 copyTV(L, L->top, L->top-1); L->top++;
526 lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
527 LJ_LIB_REG(L, LUA_IOLIBNAME, io);
528 setgcref(G(L)->gcroot[GCROOT_IO_INPUT], io_std_new(L, stdin, "stdin"));
529 setgcref(G(L)->gcroot[GCROOT_IO_OUTPUT], io_std_new(L, stdout, "stdout"));
530 io_std_new(L, stderr, "stderr");
531 return 1;
532}
533
diff --git a/libraries/luajit-2.0/src/lib_jit.c b/libraries/luajit-2.0/src/lib_jit.c
new file mode 100644
index 0000000..8cb511c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_jit.c
@@ -0,0 +1,659 @@
1/*
2** JIT library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lib_jit_c
7#define LUA_LIB
8
9#include "lua.h"
10#include "lauxlib.h"
11#include "lualib.h"
12
13#include "lj_arch.h"
14#include "lj_obj.h"
15#include "lj_err.h"
16#include "lj_debug.h"
17#include "lj_str.h"
18#include "lj_tab.h"
19#include "lj_bc.h"
20#if LJ_HASJIT
21#include "lj_ir.h"
22#include "lj_jit.h"
23#include "lj_ircall.h"
24#include "lj_iropt.h"
25#include "lj_target.h"
26#endif
27#include "lj_dispatch.h"
28#include "lj_vm.h"
29#include "lj_vmevent.h"
30#include "lj_lib.h"
31
32#include "luajit.h"
33
34/* -- jit.* functions ----------------------------------------------------- */
35
36#define LJLIB_MODULE_jit
37
38static int setjitmode(lua_State *L, int mode)
39{
40 int idx = 0;
41 if (L->base == L->top || tvisnil(L->base)) { /* jit.on/off/flush([nil]) */
42 mode |= LUAJIT_MODE_ENGINE;
43 } else {
44 /* jit.on/off/flush(func|proto, nil|true|false) */
45 if (tvisfunc(L->base) || tvisproto(L->base))
46 idx = 1;
47 else if (!tvistrue(L->base)) /* jit.on/off/flush(true, nil|true|false) */
48 goto err;
49 if (L->base+1 < L->top && tvisbool(L->base+1))
50 mode |= boolV(L->base+1) ? LUAJIT_MODE_ALLFUNC : LUAJIT_MODE_ALLSUBFUNC;
51 else
52 mode |= LUAJIT_MODE_FUNC;
53 }
54 if (luaJIT_setmode(L, idx, mode) != 1) {
55 if ((mode & LUAJIT_MODE_MASK) == LUAJIT_MODE_ENGINE)
56 lj_err_caller(L, LJ_ERR_NOJIT);
57 err:
58 lj_err_argt(L, 1, LUA_TFUNCTION);
59 }
60 return 0;
61}
62
63LJLIB_CF(jit_on)
64{
65 return setjitmode(L, LUAJIT_MODE_ON);
66}
67
68LJLIB_CF(jit_off)
69{
70 return setjitmode(L, LUAJIT_MODE_OFF);
71}
72
73LJLIB_CF(jit_flush)
74{
75#if LJ_HASJIT
76 if (L->base < L->top && !tvisnil(L->base)) {
77 int traceno = lj_lib_checkint(L, 1);
78 luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE);
79 return 0;
80 }
81#endif
82 return setjitmode(L, LUAJIT_MODE_FLUSH);
83}
84
85#if LJ_HASJIT
86/* Push a string for every flag bit that is set. */
87static void flagbits_to_strings(lua_State *L, uint32_t flags, uint32_t base,
88 const char *str)
89{
90 for (; *str; base <<= 1, str += 1+*str)
91 if (flags & base)
92 setstrV(L, L->top++, lj_str_new(L, str+1, *(uint8_t *)str));
93}
94#endif
95
96LJLIB_CF(jit_status)
97{
98#if LJ_HASJIT
99 jit_State *J = L2J(L);
100 L->top = L->base;
101 setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0);
102 flagbits_to_strings(L, J->flags, JIT_F_CPU_FIRST, JIT_F_CPUSTRING);
103 flagbits_to_strings(L, J->flags, JIT_F_OPT_FIRST, JIT_F_OPTSTRING);
104 return (int)(L->top - L->base);
105#else
106 setboolV(L->top++, 0);
107 return 1;
108#endif
109}
110
111LJLIB_CF(jit_attach)
112{
113#ifdef LUAJIT_DISABLE_VMEVENT
114 luaL_error(L, "vmevent API disabled");
115#else
116 GCfunc *fn = lj_lib_checkfunc(L, 1);
117 GCstr *s = lj_lib_optstr(L, 2);
118 luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE);
119 if (s) { /* Attach to given event. */
120 const uint8_t *p = (const uint8_t *)strdata(s);
121 uint32_t h = s->len;
122 while (*p) h = h ^ (lj_rol(h, 6) + *p++);
123 lua_pushvalue(L, 1);
124 lua_rawseti(L, -2, VMEVENT_HASHIDX(h));
125 G(L)->vmevmask = VMEVENT_NOCACHE; /* Invalidate cache. */
126 } else { /* Detach if no event given. */
127 setnilV(L->top++);
128 while (lua_next(L, -2)) {
129 L->top--;
130 if (tvisfunc(L->top) && funcV(L->top) == fn) {
131 setnilV(lj_tab_set(L, tabV(L->top-2), L->top-1));
132 }
133 }
134 }
135#endif
136 return 0;
137}
138
139LJLIB_PUSH(top-5) LJLIB_SET(os)
140LJLIB_PUSH(top-4) LJLIB_SET(arch)
141LJLIB_PUSH(top-3) LJLIB_SET(version_num)
142LJLIB_PUSH(top-2) LJLIB_SET(version)
143
144#include "lj_libdef.h"
145
146/* -- jit.util.* functions ------------------------------------------------ */
147
148#define LJLIB_MODULE_jit_util
149
150/* -- Reflection API for Lua functions ------------------------------------ */
151
152/* Return prototype of first argument (Lua function or prototype object) */
153static GCproto *check_Lproto(lua_State *L, int nolua)
154{
155 TValue *o = L->base;
156 if (L->top > o) {
157 if (tvisproto(o)) {
158 return protoV(o);
159 } else if (tvisfunc(o)) {
160 if (isluafunc(funcV(o)))
161 return funcproto(funcV(o));
162 else if (nolua)
163 return NULL;
164 }
165 }
166 lj_err_argt(L, 1, LUA_TFUNCTION);
167 return NULL; /* unreachable */
168}
169
170static void setintfield(lua_State *L, GCtab *t, const char *name, int32_t val)
171{
172 setintV(lj_tab_setstr(L, t, lj_str_newz(L, name)), val);
173}
174
175/* local info = jit.util.funcinfo(func [,pc]) */
176LJLIB_CF(jit_util_funcinfo)
177{
178 GCproto *pt = check_Lproto(L, 1);
179 if (pt) {
180 BCPos pc = (BCPos)lj_lib_optint(L, 2, 0);
181 GCtab *t;
182 lua_createtable(L, 0, 16); /* Increment hash size if fields are added. */
183 t = tabV(L->top-1);
184 setintfield(L, t, "linedefined", pt->firstline);
185 setintfield(L, t, "lastlinedefined", pt->firstline + pt->numline);
186 setintfield(L, t, "stackslots", pt->framesize);
187 setintfield(L, t, "params", pt->numparams);
188 setintfield(L, t, "bytecodes", (int32_t)pt->sizebc);
189 setintfield(L, t, "gcconsts", (int32_t)pt->sizekgc);
190 setintfield(L, t, "nconsts", (int32_t)pt->sizekn);
191 setintfield(L, t, "upvalues", (int32_t)pt->sizeuv);
192 if (pc < pt->sizebc)
193 setintfield(L, t, "currentline", lj_debug_line(pt, pc));
194 lua_pushboolean(L, (pt->flags & PROTO_VARARG));
195 lua_setfield(L, -2, "isvararg");
196 lua_pushboolean(L, (pt->flags & PROTO_CHILD));
197 lua_setfield(L, -2, "children");
198 setstrV(L, L->top++, proto_chunkname(pt));
199 lua_setfield(L, -2, "source");
200 lj_debug_pushloc(L, pt, pc);
201 lua_setfield(L, -2, "loc");
202 } else {
203 GCfunc *fn = funcV(L->base);
204 GCtab *t;
205 lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */
206 t = tabV(L->top-1);
207 if (!iscfunc(fn))
208 setintfield(L, t, "ffid", fn->c.ffid);
209 setintptrV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")),
210 (intptr_t)(void *)fn->c.f);
211 setintfield(L, t, "upvalues", fn->c.nupvalues);
212 }
213 return 1;
214}
215
216/* local ins, m = jit.util.funcbc(func, pc) */
217LJLIB_CF(jit_util_funcbc)
218{
219 GCproto *pt = check_Lproto(L, 0);
220 BCPos pc = (BCPos)lj_lib_checkint(L, 2);
221 if (pc < pt->sizebc) {
222 BCIns ins = proto_bc(pt)[pc];
223 BCOp op = bc_op(ins);
224 lua_assert(op < BC__MAX);
225 setintV(L->top, ins);
226 setintV(L->top+1, lj_bc_mode[op]);
227 L->top += 2;
228 return 2;
229 }
230 return 0;
231}
232
233/* local k = jit.util.funck(func, idx) */
234LJLIB_CF(jit_util_funck)
235{
236 GCproto *pt = check_Lproto(L, 0);
237 ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2);
238 if (idx >= 0) {
239 if (idx < (ptrdiff_t)pt->sizekn) {
240 copyTV(L, L->top-1, proto_knumtv(pt, idx));
241 return 1;
242 }
243 } else {
244 if (~idx < (ptrdiff_t)pt->sizekgc) {
245 GCobj *gc = proto_kgc(pt, idx);
246 setgcV(L, L->top-1, gc, ~gc->gch.gct);
247 return 1;
248 }
249 }
250 return 0;
251}
252
253/* local name = jit.util.funcuvname(func, idx) */
254LJLIB_CF(jit_util_funcuvname)
255{
256 GCproto *pt = check_Lproto(L, 0);
257 uint32_t idx = (uint32_t)lj_lib_checkint(L, 2);
258 if (idx < pt->sizeuv) {
259 setstrV(L, L->top-1, lj_str_newz(L, lj_debug_uvname(pt, idx)));
260 return 1;
261 }
262 return 0;
263}
264
265/* -- Reflection API for traces ------------------------------------------- */
266
267#if LJ_HASJIT
268
269/* Check trace argument. Must not throw for non-existent trace numbers. */
270static GCtrace *jit_checktrace(lua_State *L)
271{
272 TraceNo tr = (TraceNo)lj_lib_checkint(L, 1);
273 jit_State *J = L2J(L);
274 if (tr > 0 && tr < J->sizetrace)
275 return traceref(J, tr);
276 return NULL;
277}
278
279/* Names of link types. ORDER LJ_TRLINK */
280static const char *const jit_trlinkname[] = {
281 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
282 "interpreter", "return"
283};
284
285/* local info = jit.util.traceinfo(tr) */
286LJLIB_CF(jit_util_traceinfo)
287{
288 GCtrace *T = jit_checktrace(L);
289 if (T) {
290 GCtab *t;
291 lua_createtable(L, 0, 8); /* Increment hash size if fields are added. */
292 t = tabV(L->top-1);
293 setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1);
294 setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk);
295 setintfield(L, t, "link", T->link);
296 setintfield(L, t, "nexit", T->nsnap);
297 setstrV(L, L->top++, lj_str_newz(L, jit_trlinkname[T->linktype]));
298 lua_setfield(L, -2, "linktype");
299 /* There are many more fields. Add them only when needed. */
300 return 1;
301 }
302 return 0;
303}
304
305/* local m, ot, op1, op2, prev = jit.util.traceir(tr, idx) */
306LJLIB_CF(jit_util_traceir)
307{
308 GCtrace *T = jit_checktrace(L);
309 IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS;
310 if (T && ref >= REF_BIAS && ref < T->nins) {
311 IRIns *ir = &T->ir[ref];
312 int32_t m = lj_ir_mode[ir->o];
313 setintV(L->top-2, m);
314 setintV(L->top-1, ir->ot);
315 setintV(L->top++, (int32_t)ir->op1 - (irm_op1(m)==IRMref ? REF_BIAS : 0));
316 setintV(L->top++, (int32_t)ir->op2 - (irm_op2(m)==IRMref ? REF_BIAS : 0));
317 setintV(L->top++, ir->prev);
318 return 5;
319 }
320 return 0;
321}
322
323/* local k, t [, slot] = jit.util.tracek(tr, idx) */
324LJLIB_CF(jit_util_tracek)
325{
326 GCtrace *T = jit_checktrace(L);
327 IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS;
328 if (T && ref >= T->nk && ref < REF_BIAS) {
329 IRIns *ir = &T->ir[ref];
330 int32_t slot = -1;
331 if (ir->o == IR_KSLOT) {
332 slot = ir->op2;
333 ir = &T->ir[ir->op1];
334 }
335 lj_ir_kvalue(L, L->top-2, ir);
336 setintV(L->top-1, (int32_t)irt_type(ir->t));
337 if (slot == -1)
338 return 2;
339 setintV(L->top++, slot);
340 return 3;
341 }
342 return 0;
343}
344
345/* local snap = jit.util.tracesnap(tr, sn) */
346LJLIB_CF(jit_util_tracesnap)
347{
348 GCtrace *T = jit_checktrace(L);
349 SnapNo sn = (SnapNo)lj_lib_checkint(L, 2);
350 if (T && sn < T->nsnap) {
351 SnapShot *snap = &T->snap[sn];
352 SnapEntry *map = &T->snapmap[snap->mapofs];
353 MSize n, nent = snap->nent;
354 GCtab *t;
355 lua_createtable(L, nent+2, 0);
356 t = tabV(L->top-1);
357 setintV(lj_tab_setint(L, t, 0), (int32_t)snap->ref - REF_BIAS);
358 setintV(lj_tab_setint(L, t, 1), (int32_t)snap->nslots);
359 for (n = 0; n < nent; n++)
360 setintV(lj_tab_setint(L, t, (int32_t)(n+2)), (int32_t)map[n]);
361 setintV(lj_tab_setint(L, t, (int32_t)(nent+2)), (int32_t)SNAP(255, 0, 0));
362 return 1;
363 }
364 return 0;
365}
366
367/* local mcode, addr, loop = jit.util.tracemc(tr) */
368LJLIB_CF(jit_util_tracemc)
369{
370 GCtrace *T = jit_checktrace(L);
371 if (T && T->mcode != NULL) {
372 setstrV(L, L->top-1, lj_str_new(L, (const char *)T->mcode, T->szmcode));
373 setintptrV(L->top++, (intptr_t)(void *)T->mcode);
374 setintV(L->top++, T->mcloop);
375 return 3;
376 }
377 return 0;
378}
379
380/* local addr = jit.util.traceexitstub([tr,] exitno) */
381LJLIB_CF(jit_util_traceexitstub)
382{
383#ifdef EXITSTUBS_PER_GROUP
384 ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1);
385 jit_State *J = L2J(L);
386 if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) {
387 setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno));
388 return 1;
389 }
390#else
391 if (L->top > L->base+1) { /* Don't throw for one-argument variant. */
392 GCtrace *T = jit_checktrace(L);
393 ExitNo exitno = (ExitNo)lj_lib_checkint(L, 2);
394 ExitNo maxexit = T->root ? T->nsnap+1 : T->nsnap;
395 if (T && T->mcode != NULL && exitno < maxexit) {
396 setintptrV(L->top-1, (intptr_t)(void *)exitstub_trace_addr(T, exitno));
397 return 1;
398 }
399 }
400#endif
401 return 0;
402}
403
404/* local addr = jit.util.ircalladdr(idx) */
405LJLIB_CF(jit_util_ircalladdr)
406{
407 uint32_t idx = (uint32_t)lj_lib_checkint(L, 1);
408 if (idx < IRCALL__MAX) {
409 setintptrV(L->top-1, (intptr_t)(void *)lj_ir_callinfo[idx].func);
410 return 1;
411 }
412 return 0;
413}
414
415#else
416
417static int trace_nojit(lua_State *L)
418{
419 UNUSED(L);
420 return 0;
421}
422#define lj_cf_jit_util_traceinfo trace_nojit
423#define lj_cf_jit_util_traceir trace_nojit
424#define lj_cf_jit_util_tracek trace_nojit
425#define lj_cf_jit_util_tracesnap trace_nojit
426#define lj_cf_jit_util_tracemc trace_nojit
427#define lj_cf_jit_util_traceexitstub trace_nojit
428#define lj_cf_jit_util_ircalladdr trace_nojit
429
430#endif
431
432#include "lj_libdef.h"
433
434/* -- jit.opt module ------------------------------------------------------ */
435
436#define LJLIB_MODULE_jit_opt
437
438#if LJ_HASJIT
439/* Parse optimization level. */
440static int jitopt_level(jit_State *J, const char *str)
441{
442 if (str[0] >= '0' && str[0] <= '9' && str[1] == '\0') {
443 uint32_t flags;
444 if (str[0] == '0') flags = JIT_F_OPT_0;
445 else if (str[0] == '1') flags = JIT_F_OPT_1;
446 else if (str[0] == '2') flags = JIT_F_OPT_2;
447 else flags = JIT_F_OPT_3;
448 J->flags = (J->flags & ~JIT_F_OPT_MASK) | flags;
449 return 1; /* Ok. */
450 }
451 return 0; /* No match. */
452}
453
454/* Parse optimization flag. */
455static int jitopt_flag(jit_State *J, const char *str)
456{
457 const char *lst = JIT_F_OPTSTRING;
458 uint32_t opt;
459 int set = 1;
460 if (str[0] == '+') {
461 str++;
462 } else if (str[0] == '-') {
463 str++;
464 set = 0;
465 } else if (str[0] == 'n' && str[1] == 'o') {
466 str += str[2] == '-' ? 3 : 2;
467 set = 0;
468 }
469 for (opt = JIT_F_OPT_FIRST; ; opt <<= 1) {
470 size_t len = *(const uint8_t *)lst;
471 if (len == 0)
472 break;
473 if (strncmp(str, lst+1, len) == 0 && str[len] == '\0') {
474 if (set) J->flags |= opt; else J->flags &= ~opt;
475 return 1; /* Ok. */
476 }
477 lst += 1+len;
478 }
479 return 0; /* No match. */
480}
481
482/* Parse optimization parameter. */
483static int jitopt_param(jit_State *J, const char *str)
484{
485 const char *lst = JIT_P_STRING;
486 int i;
487 for (i = 0; i < JIT_P__MAX; i++) {
488 size_t len = *(const uint8_t *)lst;
489 lua_assert(len != 0);
490 if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
491 int32_t n = 0;
492 const char *p = &str[len+1];
493 while (*p >= '0' && *p <= '9')
494 n = n*10 + (*p++ - '0');
495 if (*p) return 0; /* Malformed number. */
496 J->param[i] = n;
497 if (i == JIT_P_hotloop)
498 lj_dispatch_init_hotcount(J2G(J));
499 return 1; /* Ok. */
500 }
501 lst += 1+len;
502 }
503 return 0; /* No match. */
504}
505#endif
506
507/* jit.opt.start(flags...) */
508LJLIB_CF(jit_opt_start)
509{
510#if LJ_HASJIT
511 jit_State *J = L2J(L);
512 int nargs = (int)(L->top - L->base);
513 if (nargs == 0) {
514 J->flags = (J->flags & ~JIT_F_OPT_MASK) | JIT_F_OPT_DEFAULT;
515 } else {
516 int i;
517 for (i = 1; i <= nargs; i++) {
518 const char *str = strdata(lj_lib_checkstr(L, i));
519 if (!jitopt_level(J, str) &&
520 !jitopt_flag(J, str) &&
521 !jitopt_param(J, str))
522 lj_err_callerv(L, LJ_ERR_JITOPT, str);
523 }
524 }
525#else
526 lj_err_caller(L, LJ_ERR_NOJIT);
527#endif
528 return 0;
529}
530
531#include "lj_libdef.h"
532
533/* -- JIT compiler initialization ----------------------------------------- */
534
535#if LJ_HASJIT
536/* Default values for JIT parameters. */
537static const int32_t jit_param_default[JIT_P__MAX+1] = {
538#define JIT_PARAMINIT(len, name, value) (value),
539JIT_PARAMDEF(JIT_PARAMINIT)
540#undef JIT_PARAMINIT
541 0
542};
543#endif
544
545#if LJ_TARGET_ARM && LJ_TARGET_LINUX
546#include <sys/utsname.h>
547#endif
548
549/* Arch-dependent CPU detection. */
550static uint32_t jit_cpudetect(lua_State *L)
551{
552 uint32_t flags = 0;
553#if LJ_TARGET_X86ORX64
554 uint32_t vendor[4];
555 uint32_t features[4];
556 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
557#if !LJ_HASJIT
558#define JIT_F_CMOV 1
559#define JIT_F_SSE2 2
560#endif
561 flags |= ((features[3] >> 15)&1) * JIT_F_CMOV;
562 flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
563#if LJ_HASJIT
564 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
565 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
566 if (vendor[2] == 0x6c65746e) { /* Intel. */
567 if ((features[0] & 0x0ff00f00) == 0x00000f00) /* P4. */
568 flags |= JIT_F_P4; /* Currently unused. */
569 else if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */
570 flags |= JIT_F_LEA_AGU;
571 } else if (vendor[2] == 0x444d4163) { /* AMD. */
572 uint32_t fam = (features[0] & 0x0ff00f00);
573 if (fam == 0x00000f00) /* K8. */
574 flags |= JIT_F_SPLIT_XMM;
575 if (fam >= 0x00000f00) /* K8, K10. */
576 flags |= JIT_F_PREFER_IMUL;
577 }
578#endif
579 }
580 /* Check for required instruction set support on x86 (unnecessary on x64). */
581#if LJ_TARGET_X86
582#if !defined(LUAJIT_CPU_NOCMOV)
583 if (!(flags & JIT_F_CMOV))
584 luaL_error(L, "Ancient CPU lacks CMOV support (recompile with -DLUAJIT_CPU_NOCMOV)");
585#endif
586#if defined(LUAJIT_CPU_SSE2)
587 if (!(flags & JIT_F_SSE2))
588 luaL_error(L, "CPU does not support SSE2 (recompile without -DLUAJIT_CPU_SSE2)");
589#endif
590#endif
591#elif LJ_TARGET_ARM
592#if LJ_HASJIT
593 /* Compile-time ARM CPU detection. */
594#if __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__
595 flags |= JIT_F_ARMV6|JIT_F_ARMV6T2|JIT_F_ARMV7;
596#elif __ARM_ARCH_6T2__
597 flags |= JIT_F_ARMV6|JIT_F_ARMV6T2;
598#elif __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6Z__ || __ARM_ARCH_6ZK__
599 flags |= JIT_F_ARMV6;
600#endif
601 /* Runtime ARM CPU detection. */
602#if LJ_TARGET_LINUX
603 if (!(flags & JIT_F_ARMV7)) {
604 struct utsname ut;
605 uname(&ut);
606 if (strncmp(ut.machine, "armv", 4) == 0) {
607 if (ut.machine[4] >= '7')
608 flags |= JIT_F_ARMV6|JIT_F_ARMV6T2|JIT_F_ARMV7;
609 else if (ut.machine[4] == '6')
610 flags |= JIT_F_ARMV6;
611 }
612 }
613#endif
614#endif
615#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
616 /* Nothing to do. */
617#elif LJ_TARGET_MIPS
618 /* NYI */
619#else
620#error "Missing CPU detection for this architecture"
621#endif
622 UNUSED(L);
623 return flags;
624}
625
626/* Initialize JIT compiler. */
627static void jit_init(lua_State *L)
628{
629 uint32_t flags = jit_cpudetect(L);
630#if LJ_HASJIT
631 jit_State *J = L2J(L);
632#if LJ_TARGET_X86
633 /* Silently turn off the JIT compiler on CPUs without SSE2. */
634 if ((flags & JIT_F_SSE2))
635#endif
636 J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
637 memcpy(J->param, jit_param_default, sizeof(J->param));
638 lj_dispatch_update(G(L));
639#else
640 UNUSED(flags);
641#endif
642}
643
644LUALIB_API int luaopen_jit(lua_State *L)
645{
646 lua_pushliteral(L, LJ_OS_NAME);
647 lua_pushliteral(L, LJ_ARCH_NAME);
648 lua_pushinteger(L, LUAJIT_VERSION_NUM);
649 lua_pushliteral(L, LUAJIT_VERSION);
650 LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
651#ifndef LUAJIT_DISABLE_JITUTIL
652 LJ_LIB_REG(L, "jit.util", jit_util);
653#endif
654 LJ_LIB_REG(L, "jit.opt", jit_opt);
655 L->top -= 2;
656 jit_init(L);
657 return 1;
658}
659
diff --git a/libraries/luajit-2.0/src/lib_math.c b/libraries/luajit-2.0/src/lib_math.c
new file mode 100644
index 0000000..599f948
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_math.c
@@ -0,0 +1,218 @@
1/*
2** Math library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include <math.h>
7
8#define lib_math_c
9#define LUA_LIB
10
11#include "lua.h"
12#include "lauxlib.h"
13#include "lualib.h"
14
15#include "lj_obj.h"
16#include "lj_lib.h"
17#include "lj_vm.h"
18
19/* ------------------------------------------------------------------------ */
20
21#define LJLIB_MODULE_math
22
23LJLIB_ASM(math_abs) LJLIB_REC(.)
24{
25 lj_lib_checknumber(L, 1);
26 return FFH_RETRY;
27}
28LJLIB_ASM_(math_floor) LJLIB_REC(math_round IRFPM_FLOOR)
29LJLIB_ASM_(math_ceil) LJLIB_REC(math_round IRFPM_CEIL)
30
31LJLIB_ASM(math_sqrt) LJLIB_REC(math_unary IRFPM_SQRT)
32{
33 lj_lib_checknum(L, 1);
34 return FFH_RETRY;
35}
36LJLIB_ASM_(math_log) LJLIB_REC(math_unary IRFPM_LOG)
37LJLIB_ASM_(math_log10) LJLIB_REC(math_unary IRFPM_LOG10)
38LJLIB_ASM_(math_exp) LJLIB_REC(math_unary IRFPM_EXP)
39LJLIB_ASM_(math_sin) LJLIB_REC(math_unary IRFPM_SIN)
40LJLIB_ASM_(math_cos) LJLIB_REC(math_unary IRFPM_COS)
41LJLIB_ASM_(math_tan) LJLIB_REC(math_unary IRFPM_TAN)
42LJLIB_ASM_(math_asin) LJLIB_REC(math_atrig FF_math_asin)
43LJLIB_ASM_(math_acos) LJLIB_REC(math_atrig FF_math_acos)
44LJLIB_ASM_(math_atan) LJLIB_REC(math_atrig FF_math_atan)
45LJLIB_ASM_(math_sinh) LJLIB_REC(math_htrig IRCALL_sinh)
46LJLIB_ASM_(math_cosh) LJLIB_REC(math_htrig IRCALL_cosh)
47LJLIB_ASM_(math_tanh) LJLIB_REC(math_htrig IRCALL_tanh)
48LJLIB_ASM_(math_frexp)
49LJLIB_ASM_(math_modf) LJLIB_REC(.)
50
51LJLIB_PUSH(57.29577951308232)
52LJLIB_ASM_(math_deg) LJLIB_REC(math_degrad)
53
54LJLIB_PUSH(0.017453292519943295)
55LJLIB_ASM_(math_rad) LJLIB_REC(math_degrad)
56
57LJLIB_ASM(math_atan2) LJLIB_REC(.)
58{
59 lj_lib_checknum(L, 1);
60 lj_lib_checknum(L, 2);
61 return FFH_RETRY;
62}
63LJLIB_ASM_(math_pow) LJLIB_REC(.)
64LJLIB_ASM_(math_fmod)
65
66LJLIB_ASM(math_ldexp) LJLIB_REC(.)
67{
68 lj_lib_checknum(L, 1);
69#if LJ_DUALNUM && !LJ_TARGET_X86ORX64
70 lj_lib_checkint(L, 2);
71#else
72 lj_lib_checknum(L, 2);
73#endif
74 return FFH_RETRY;
75}
76
77LJLIB_ASM(math_min) LJLIB_REC(math_minmax IR_MIN)
78{
79 int i = 0;
80 do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
81 return FFH_RETRY;
82}
83LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
84
85LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi)
86LJLIB_PUSH(1e310) LJLIB_SET(huge)
87
88/* ------------------------------------------------------------------------ */
89
90/* This implements a Tausworthe PRNG with period 2^223. Based on:
91** Tables of maximally-equidistributed combined LFSR generators,
92** Pierre L'Ecuyer, 1991, table 3, 1st entry.
93** Full-period ME-CF generator with L=64, J=4, k=223, N1=49.
94*/
95
96/* PRNG state. */
97struct RandomState {
98 uint64_t gen[4]; /* State of the 4 LFSR generators. */
99 int valid; /* State is valid. */
100};
101
102/* Union needed for bit-pattern conversion between uint64_t and double. */
103typedef union { uint64_t u64; double d; } U64double;
104
105/* Update generator i and compute a running xor of all states. */
106#define TW223_GEN(i, k, q, s) \
107 z = rs->gen[i]; \
108 z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \
109 r ^= z; rs->gen[i] = z;
110
111/* PRNG step function. Returns a double in the range 1.0 <= d < 2.0. */
112LJ_NOINLINE uint64_t LJ_FASTCALL lj_math_random_step(RandomState *rs)
113{
114 uint64_t z, r = 0;
115 TW223_GEN(0, 63, 31, 18)
116 TW223_GEN(1, 58, 19, 28)
117 TW223_GEN(2, 55, 24, 7)
118 TW223_GEN(3, 47, 21, 8)
119 return (r & U64x(000fffff,ffffffff)) | U64x(3ff00000,00000000);
120}
121
122/* PRNG initialization function. */
123static void random_init(RandomState *rs, double d)
124{
125 uint32_t r = 0x11090601; /* 64-k[i] as four 8 bit constants. */
126 int i;
127 for (i = 0; i < 4; i++) {
128 U64double u;
129 uint32_t m = 1u << (r&255);
130 r >>= 8;
131 u.d = d = d * 3.14159265358979323846 + 2.7182818284590452354;
132 if (u.u64 < m) u.u64 += m; /* Ensure k[i] MSB of gen[i] are non-zero. */
133 rs->gen[i] = u.u64;
134 }
135 rs->valid = 1;
136 for (i = 0; i < 10; i++)
137 lj_math_random_step(rs);
138}
139
140/* PRNG extract function. */
141LJLIB_PUSH(top-2) /* Upvalue holds userdata with RandomState. */
142LJLIB_CF(math_random) LJLIB_REC(.)
143{
144 int n = (int)(L->top - L->base);
145 RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
146 U64double u;
147 double d;
148 if (LJ_UNLIKELY(!rs->valid)) random_init(rs, 0.0);
149 u.u64 = lj_math_random_step(rs);
150 d = u.d - 1.0;
151 if (n > 0) {
152#if LJ_DUALNUM
153 int isint = 1;
154 double r1;
155 lj_lib_checknumber(L, 1);
156 if (tvisint(L->base)) {
157 r1 = (lua_Number)intV(L->base);
158 } else {
159 isint = 0;
160 r1 = numV(L->base);
161 }
162#else
163 double r1 = lj_lib_checknum(L, 1);
164#endif
165 if (n == 1) {
166 d = lj_vm_floor(d*r1) + 1.0; /* d is an int in range [1, r1] */
167 } else {
168#if LJ_DUALNUM
169 double r2;
170 lj_lib_checknumber(L, 2);
171 if (tvisint(L->base+1)) {
172 r2 = (lua_Number)intV(L->base+1);
173 } else {
174 isint = 0;
175 r2 = numV(L->base+1);
176 }
177#else
178 double r2 = lj_lib_checknum(L, 2);
179#endif
180 d = lj_vm_floor(d*(r2-r1+1.0)) + r1; /* d is an int in range [r1, r2] */
181 }
182#if LJ_DUALNUM
183 if (isint) {
184 setintV(L->top-1, lj_num2int(d));
185 return 1;
186 }
187#endif
188 } /* else: d is a double in range [0, 1] */
189 setnumV(L->top++, d);
190 return 1;
191}
192
193/* PRNG seed function. */
194LJLIB_PUSH(top-2) /* Upvalue holds userdata with RandomState. */
195LJLIB_CF(math_randomseed)
196{
197 RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
198 random_init(rs, lj_lib_checknum(L, 1));
199 return 0;
200}
201
202/* ------------------------------------------------------------------------ */
203
204#include "lj_libdef.h"
205
206LUALIB_API int luaopen_math(lua_State *L)
207{
208 RandomState *rs;
209 rs = (RandomState *)lua_newuserdata(L, sizeof(RandomState));
210 rs->valid = 0; /* Use lazy initialization to save some time on startup. */
211 LJ_LIB_REG(L, LUA_MATHLIBNAME, math);
212#if defined(LUA_COMPAT_MOD)
213 lua_getfield(L, -1, "fmod");
214 lua_setfield(L, -2, "mod");
215#endif
216 return 1;
217}
218
diff --git a/libraries/luajit-2.0/src/lib_os.c b/libraries/luajit-2.0/src/lib_os.c
new file mode 100644
index 0000000..7292940
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_os.c
@@ -0,0 +1,256 @@
1/*
2** OS library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#include <errno.h>
10#include <locale.h>
11#include <time.h>
12
13#define lib_os_c
14#define LUA_LIB
15
16#include "lua.h"
17#include "lauxlib.h"
18#include "lualib.h"
19
20#include "lj_obj.h"
21#include "lj_err.h"
22#include "lj_lib.h"
23
24#if LJ_TARGET_POSIX
25#include <unistd.h>
26#else
27#include <stdio.h>
28#endif
29
30/* ------------------------------------------------------------------------ */
31
32#define LJLIB_MODULE_os
33
34static int os_pushresult(lua_State *L, int i, const char *filename)
35{
36 int en = errno; /* calls to Lua API may change this value */
37 if (i) {
38 setboolV(L->top-1, 1);
39 return 1;
40 } else {
41 setnilV(L->top-1);
42 lua_pushfstring(L, "%s: %s", filename, strerror(en));
43 lua_pushinteger(L, en);
44 return 3;
45 }
46}
47
48LJLIB_CF(os_execute)
49{
50 lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
51 return 1;
52}
53
54LJLIB_CF(os_remove)
55{
56 const char *filename = luaL_checkstring(L, 1);
57 return os_pushresult(L, remove(filename) == 0, filename);
58}
59
60LJLIB_CF(os_rename)
61{
62 const char *fromname = luaL_checkstring(L, 1);
63 const char *toname = luaL_checkstring(L, 2);
64 return os_pushresult(L, rename(fromname, toname) == 0, fromname);
65}
66
67LJLIB_CF(os_tmpname)
68{
69#if LJ_TARGET_POSIX
70 char buf[15+1];
71 int fp;
72 strcpy(buf, "/tmp/lua_XXXXXX");
73 fp = mkstemp(buf);
74 if (fp != -1)
75 close(fp);
76 else
77 lj_err_caller(L, LJ_ERR_OSUNIQF);
78#else
79 char buf[L_tmpnam];
80 if (tmpnam(buf) == NULL)
81 lj_err_caller(L, LJ_ERR_OSUNIQF);
82#endif
83 lua_pushstring(L, buf);
84 return 1;
85}
86
87LJLIB_CF(os_getenv)
88{
89 lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
90 return 1;
91}
92
93LJLIB_CF(os_exit)
94{
95 int status;
96 if (L->base < L->top && tvisbool(L->base))
97 status = boolV(L->base) ? EXIT_SUCCESS : EXIT_FAILURE;
98 else
99 status = lj_lib_optint(L, 1, EXIT_SUCCESS);
100 if (L->base+1 < L->top && tvistruecond(L->base+1))
101 lua_close(L);
102 exit(status);
103 return 0; /* Unreachable. */
104}
105
106LJLIB_CF(os_clock)
107{
108 setnumV(L->top++, ((lua_Number)clock())*(1.0/(lua_Number)CLOCKS_PER_SEC));
109 return 1;
110}
111
112/* ------------------------------------------------------------------------ */
113
114static void setfield(lua_State *L, const char *key, int value)
115{
116 lua_pushinteger(L, value);
117 lua_setfield(L, -2, key);
118}
119
120static void setboolfield(lua_State *L, const char *key, int value)
121{
122 if (value < 0) /* undefined? */
123 return; /* does not set field */
124 lua_pushboolean(L, value);
125 lua_setfield(L, -2, key);
126}
127
128static int getboolfield(lua_State *L, const char *key)
129{
130 int res;
131 lua_getfield(L, -1, key);
132 res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
133 lua_pop(L, 1);
134 return res;
135}
136
137static int getfield(lua_State *L, const char *key, int d)
138{
139 int res;
140 lua_getfield(L, -1, key);
141 if (lua_isnumber(L, -1)) {
142 res = (int)lua_tointeger(L, -1);
143 } else {
144 if (d < 0)
145 lj_err_callerv(L, LJ_ERR_OSDATEF, key);
146 res = d;
147 }
148 lua_pop(L, 1);
149 return res;
150}
151
152LJLIB_CF(os_date)
153{
154 const char *s = luaL_optstring(L, 1, "%c");
155 time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
156 struct tm *stm;
157 if (*s == '!') { /* UTC? */
158 stm = gmtime(&t);
159 s++; /* skip `!' */
160 } else {
161 stm = localtime(&t);
162 }
163 if (stm == NULL) { /* invalid date? */
164 setnilV(L->top-1);
165 } else if (strcmp(s, "*t") == 0) {
166 lua_createtable(L, 0, 9); /* 9 = number of fields */
167 setfield(L, "sec", stm->tm_sec);
168 setfield(L, "min", stm->tm_min);
169 setfield(L, "hour", stm->tm_hour);
170 setfield(L, "day", stm->tm_mday);
171 setfield(L, "month", stm->tm_mon+1);
172 setfield(L, "year", stm->tm_year+1900);
173 setfield(L, "wday", stm->tm_wday+1);
174 setfield(L, "yday", stm->tm_yday+1);
175 setboolfield(L, "isdst", stm->tm_isdst);
176 } else {
177 char cc[3];
178 luaL_Buffer b;
179 cc[0] = '%'; cc[2] = '\0';
180 luaL_buffinit(L, &b);
181 for (; *s; s++) {
182 if (*s != '%' || *(s + 1) == '\0') { /* no conversion specifier? */
183 luaL_addchar(&b, *s);
184 } else {
185 size_t reslen;
186 char buff[200]; /* should be big enough for any conversion result */
187 cc[1] = *(++s);
188 reslen = strftime(buff, sizeof(buff), cc, stm);
189 luaL_addlstring(&b, buff, reslen);
190 }
191 }
192 luaL_pushresult(&b);
193 }
194 return 1;
195}
196
197LJLIB_CF(os_time)
198{
199 time_t t;
200 if (lua_isnoneornil(L, 1)) { /* called without args? */
201 t = time(NULL); /* get current time */
202 } else {
203 struct tm ts;
204 luaL_checktype(L, 1, LUA_TTABLE);
205 lua_settop(L, 1); /* make sure table is at the top */
206 ts.tm_sec = getfield(L, "sec", 0);
207 ts.tm_min = getfield(L, "min", 0);
208 ts.tm_hour = getfield(L, "hour", 12);
209 ts.tm_mday = getfield(L, "day", -1);
210 ts.tm_mon = getfield(L, "month", -1) - 1;
211 ts.tm_year = getfield(L, "year", -1) - 1900;
212 ts.tm_isdst = getboolfield(L, "isdst");
213 t = mktime(&ts);
214 }
215 if (t == (time_t)(-1))
216 lua_pushnil(L);
217 else
218 lua_pushnumber(L, (lua_Number)t);
219 return 1;
220}
221
222LJLIB_CF(os_difftime)
223{
224 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
225 (time_t)(luaL_optnumber(L, 2, (lua_Number)0))));
226 return 1;
227}
228
229/* ------------------------------------------------------------------------ */
230
231LJLIB_CF(os_setlocale)
232{
233 GCstr *s = lj_lib_optstr(L, 1);
234 const char *str = s ? strdata(s) : NULL;
235 int opt = lj_lib_checkopt(L, 2, 6,
236 "\5ctype\7numeric\4time\7collate\10monetary\1\377\3all");
237 if (opt == 0) opt = LC_CTYPE;
238 else if (opt == 1) opt = LC_NUMERIC;
239 else if (opt == 2) opt = LC_TIME;
240 else if (opt == 3) opt = LC_COLLATE;
241 else if (opt == 4) opt = LC_MONETARY;
242 else if (opt == 6) opt = LC_ALL;
243 lua_pushstring(L, setlocale(opt, str));
244 return 1;
245}
246
247/* ------------------------------------------------------------------------ */
248
249#include "lj_libdef.h"
250
251LUALIB_API int luaopen_os(lua_State *L)
252{
253 LJ_LIB_REG(L, LUA_OSLIBNAME, os);
254 return 1;
255}
256
diff --git a/libraries/luajit-2.0/src/lib_package.c b/libraries/luajit-2.0/src/lib_package.c
new file mode 100644
index 0000000..a13c45b
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_package.c
@@ -0,0 +1,585 @@
1/*
2** Package library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lib_package_c
10#define LUA_LIB
11
12#include "lua.h"
13#include "lauxlib.h"
14#include "lualib.h"
15
16#include "lj_obj.h"
17#include "lj_err.h"
18#include "lj_lib.h"
19
20/* ------------------------------------------------------------------------ */
21
22/* Error codes for ll_loadfunc. */
23#define PACKAGE_ERR_LIB 1
24#define PACKAGE_ERR_FUNC 2
25#define PACKAGE_ERR_LOAD 3
26
27/* Redefined in platform specific part. */
28#define PACKAGE_LIB_FAIL "open"
29#define setprogdir(L) ((void)0)
30
31/* Symbol name prefixes. */
32#define SYMPREFIX_CF "luaopen_%s"
33#define SYMPREFIX_BC "luaJIT_BC_%s"
34
35#if LJ_TARGET_DLOPEN
36
37#include <dlfcn.h>
38
39static void ll_unloadlib(void *lib)
40{
41 dlclose(lib);
42}
43
44static void *ll_load(lua_State *L, const char *path)
45{
46 void *lib = dlopen(path, RTLD_NOW);
47 if (lib == NULL) lua_pushstring(L, dlerror());
48 return lib;
49}
50
51static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
52{
53 lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
54 if (f == NULL) lua_pushstring(L, dlerror());
55 return f;
56}
57
58static const char *ll_bcsym(void *lib, const char *sym)
59{
60#if defined(RTLD_DEFAULT)
61 if (lib == NULL) lib = RTLD_DEFAULT;
62#elif LJ_TARGET_OSX || LJ_TARGET_BSD
63 if (lib == NULL) lib = (void *)(intptr_t)-2;
64#endif
65 return (const char *)dlsym(lib, sym);
66}
67
68#elif LJ_TARGET_WINDOWS
69
70#define WIN32_LEAN_AND_MEAN
71#ifndef WINVER
72#define WINVER 0x0500
73#endif
74#include <windows.h>
75
76#ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
77#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
78#define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
79BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);
80#endif
81
82#undef setprogdir
83
84static void setprogdir(lua_State *L)
85{
86 char buff[MAX_PATH + 1];
87 char *lb;
88 DWORD nsize = sizeof(buff);
89 DWORD n = GetModuleFileNameA(NULL, buff, nsize);
90 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) {
91 luaL_error(L, "unable to get ModuleFileName");
92 } else {
93 *lb = '\0';
94 luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
95 lua_remove(L, -2); /* remove original string */
96 }
97}
98
99static void pusherror(lua_State *L)
100{
101 DWORD error = GetLastError();
102 char buffer[128];
103 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
104 NULL, error, 0, buffer, sizeof(buffer), NULL))
105 lua_pushstring(L, buffer);
106 else
107 lua_pushfstring(L, "system error %d\n", error);
108}
109
110static void ll_unloadlib(void *lib)
111{
112 FreeLibrary((HINSTANCE)lib);
113}
114
115static void *ll_load(lua_State *L, const char *path)
116{
117 HINSTANCE lib = LoadLibraryA(path);
118 if (lib == NULL) pusherror(L);
119 return lib;
120}
121
122static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
123{
124 lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
125 if (f == NULL) pusherror(L);
126 return f;
127}
128
129static const char *ll_bcsym(void *lib, const char *sym)
130{
131 if (lib) {
132 return (const char *)GetProcAddress((HINSTANCE)lib, sym);
133 } else {
134 HINSTANCE h = GetModuleHandleA(NULL);
135 const char *p = (const char *)GetProcAddress(h, sym);
136 if (p == NULL && GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
137 (const char *)ll_bcsym, &h))
138 p = (const char *)GetProcAddress(h, sym);
139 return p;
140 }
141}
142
143#else
144
145#undef PACKAGE_LIB_FAIL
146#define PACKAGE_LIB_FAIL "absent"
147
148#define DLMSG "dynamic libraries not enabled; no support for target OS"
149
150static void ll_unloadlib(void *lib)
151{
152 (void)lib;
153}
154
155static void *ll_load(lua_State *L, const char *path)
156{
157 (void)path;
158 lua_pushliteral(L, DLMSG);
159 return NULL;
160}
161
162static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
163{
164 (void)lib; (void)sym;
165 lua_pushliteral(L, DLMSG);
166 return NULL;
167}
168
169static const char *ll_bcsym(void *lib, const char *sym)
170{
171 (void)lib; (void)sym;
172 return NULL;
173}
174
175#endif
176
177/* ------------------------------------------------------------------------ */
178
179static void **ll_register(lua_State *L, const char *path)
180{
181 void **plib;
182 lua_pushfstring(L, "LOADLIB: %s", path);
183 lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
184 if (!lua_isnil(L, -1)) { /* is there an entry? */
185 plib = (void **)lua_touserdata(L, -1);
186 } else { /* no entry yet; create one */
187 lua_pop(L, 1);
188 plib = (void **)lua_newuserdata(L, sizeof(void *));
189 *plib = NULL;
190 luaL_getmetatable(L, "_LOADLIB");
191 lua_setmetatable(L, -2);
192 lua_pushfstring(L, "LOADLIB: %s", path);
193 lua_pushvalue(L, -2);
194 lua_settable(L, LUA_REGISTRYINDEX);
195 }
196 return plib;
197}
198
199static const char *mksymname(lua_State *L, const char *modname,
200 const char *prefix)
201{
202 const char *funcname;
203 const char *mark = strchr(modname, *LUA_IGMARK);
204 if (mark) modname = mark + 1;
205 funcname = luaL_gsub(L, modname, ".", "_");
206 funcname = lua_pushfstring(L, prefix, funcname);
207 lua_remove(L, -2); /* remove 'gsub' result */
208 return funcname;
209}
210
211static int ll_loadfunc(lua_State *L, const char *path, const char *name, int r)
212{
213 void **reg = ll_register(L, path);
214 if (*reg == NULL) *reg = ll_load(L, path);
215 if (*reg == NULL) {
216 return PACKAGE_ERR_LIB; /* unable to load library */
217 } else {
218 const char *sym = r ? name : mksymname(L, name, SYMPREFIX_CF);
219 lua_CFunction f = ll_sym(L, *reg, sym);
220 if (f) {
221 lua_pushcfunction(L, f);
222 return 0;
223 }
224 if (!r) {
225 const char *bcdata = ll_bcsym(*reg, mksymname(L, name, SYMPREFIX_BC));
226 lua_pop(L, 1);
227 if (bcdata) {
228 if (luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
229 return PACKAGE_ERR_LOAD;
230 return 0;
231 }
232 }
233 return PACKAGE_ERR_FUNC; /* unable to find function */
234 }
235}
236
237static int lj_cf_package_loadlib(lua_State *L)
238{
239 const char *path = luaL_checkstring(L, 1);
240 const char *init = luaL_checkstring(L, 2);
241 int st = ll_loadfunc(L, path, init, 1);
242 if (st == 0) { /* no errors? */
243 return 1; /* return the loaded function */
244 } else { /* error; error message is on stack top */
245 lua_pushnil(L);
246 lua_insert(L, -2);
247 lua_pushstring(L, (st == PACKAGE_ERR_LIB) ? PACKAGE_LIB_FAIL : "init");
248 return 3; /* return nil, error message, and where */
249 }
250}
251
252static int lj_cf_package_unloadlib(lua_State *L)
253{
254 void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
255 if (*lib) ll_unloadlib(*lib);
256 *lib = NULL; /* mark library as closed */
257 return 0;
258}
259
260/* ------------------------------------------------------------------------ */
261
262static int readable(const char *filename)
263{
264 FILE *f = fopen(filename, "r"); /* try to open file */
265 if (f == NULL) return 0; /* open failed */
266 fclose(f);
267 return 1;
268}
269
270static const char *pushnexttemplate(lua_State *L, const char *path)
271{
272 const char *l;
273 while (*path == *LUA_PATHSEP) path++; /* skip separators */
274 if (*path == '\0') return NULL; /* no more templates */
275 l = strchr(path, *LUA_PATHSEP); /* find next separator */
276 if (l == NULL) l = path + strlen(path);
277 lua_pushlstring(L, path, (size_t)(l - path)); /* template */
278 return l;
279}
280
281static const char *searchpath (lua_State *L, const char *name,
282 const char *path)
283{
284 name = luaL_gsub(L, name, ".", LUA_DIRSEP);
285 lua_pushliteral(L, ""); /* error accumulator */
286 while ((path = pushnexttemplate(L, path)) != NULL) {
287 const char *filename = luaL_gsub(L, lua_tostring(L, -1),
288 LUA_PATH_MARK, name);
289 lua_remove(L, -2); /* remove path template */
290 if (readable(filename)) /* does file exist and is readable? */
291 return filename; /* return that file name */
292 lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
293 lua_remove(L, -2); /* remove file name */
294 lua_concat(L, 2); /* add entry to possible error message */
295 }
296 return NULL; /* not found */
297}
298
299static int lj_cf_package_searchpath(lua_State *L)
300{
301 const char *f = searchpath(L, luaL_checkstring(L, 1), luaL_checkstring(L, 2));
302 if (f != NULL) {
303 return 1;
304 } else { /* error message is on top of the stack */
305 lua_pushnil(L);
306 lua_insert(L, -2);
307 return 2; /* return nil + error message */
308 }
309}
310
311static const char *findfile(lua_State *L, const char *name,
312 const char *pname)
313{
314 const char *path;
315 lua_getfield(L, LUA_ENVIRONINDEX, pname);
316 path = lua_tostring(L, -1);
317 if (path == NULL)
318 luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
319 return searchpath(L, name, path);
320}
321
322static void loaderror(lua_State *L, const char *filename)
323{
324 luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
325 lua_tostring(L, 1), filename, lua_tostring(L, -1));
326}
327
328static int lj_cf_package_loader_lua(lua_State *L)
329{
330 const char *filename;
331 const char *name = luaL_checkstring(L, 1);
332 filename = findfile(L, name, "path");
333 if (filename == NULL) return 1; /* library not found in this path */
334 if (luaL_loadfile(L, filename) != 0)
335 loaderror(L, filename);
336 return 1; /* library loaded successfully */
337}
338
339static int lj_cf_package_loader_c(lua_State *L)
340{
341 const char *name = luaL_checkstring(L, 1);
342 const char *filename = findfile(L, name, "cpath");
343 if (filename == NULL) return 1; /* library not found in this path */
344 if (ll_loadfunc(L, filename, name, 0) != 0)
345 loaderror(L, filename);
346 return 1; /* library loaded successfully */
347}
348
349static int lj_cf_package_loader_croot(lua_State *L)
350{
351 const char *filename;
352 const char *name = luaL_checkstring(L, 1);
353 const char *p = strchr(name, '.');
354 int st;
355 if (p == NULL) return 0; /* is root */
356 lua_pushlstring(L, name, (size_t)(p - name));
357 filename = findfile(L, lua_tostring(L, -1), "cpath");
358 if (filename == NULL) return 1; /* root not found */
359 if ((st = ll_loadfunc(L, filename, name, 0)) != 0) {
360 if (st != PACKAGE_ERR_FUNC) loaderror(L, filename); /* real error */
361 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
362 name, filename);
363 return 1; /* function not found */
364 }
365 return 1;
366}
367
368static int lj_cf_package_loader_preload(lua_State *L)
369{
370 const char *name = luaL_checkstring(L, 1);
371 lua_getfield(L, LUA_ENVIRONINDEX, "preload");
372 if (!lua_istable(L, -1))
373 luaL_error(L, LUA_QL("package.preload") " must be a table");
374 lua_getfield(L, -1, name);
375 if (lua_isnil(L, -1)) { /* Not found? */
376 const char *bcname = mksymname(L, name, SYMPREFIX_BC);
377 const char *bcdata = ll_bcsym(NULL, bcname);
378 if (bcdata == NULL || luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
379 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
380 }
381 return 1;
382}
383
384/* ------------------------------------------------------------------------ */
385
386static const int sentinel_ = 0;
387#define sentinel ((void *)&sentinel_)
388
389static int lj_cf_package_require(lua_State *L)
390{
391 const char *name = luaL_checkstring(L, 1);
392 int i;
393 lua_settop(L, 1); /* _LOADED table will be at index 2 */
394 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
395 lua_getfield(L, 2, name);
396 if (lua_toboolean(L, -1)) { /* is it there? */
397 if (lua_touserdata(L, -1) == sentinel) /* check loops */
398 luaL_error(L, "loop or previous error loading module " LUA_QS, name);
399 return 1; /* package is already loaded */
400 }
401 /* else must load it; iterate over available loaders */
402 lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
403 if (!lua_istable(L, -1))
404 luaL_error(L, LUA_QL("package.loaders") " must be a table");
405 lua_pushliteral(L, ""); /* error message accumulator */
406 for (i = 1; ; i++) {
407 lua_rawgeti(L, -2, i); /* get a loader */
408 if (lua_isnil(L, -1))
409 luaL_error(L, "module " LUA_QS " not found:%s",
410 name, lua_tostring(L, -2));
411 lua_pushstring(L, name);
412 lua_call(L, 1, 1); /* call it */
413 if (lua_isfunction(L, -1)) /* did it find module? */
414 break; /* module loaded successfully */
415 else if (lua_isstring(L, -1)) /* loader returned error message? */
416 lua_concat(L, 2); /* accumulate it */
417 else
418 lua_pop(L, 1);
419 }
420 lua_pushlightuserdata(L, sentinel);
421 lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
422 lua_pushstring(L, name); /* pass name as argument to module */
423 lua_call(L, 1, 1); /* run loaded module */
424 if (!lua_isnil(L, -1)) /* non-nil return? */
425 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
426 lua_getfield(L, 2, name);
427 if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
428 lua_pushboolean(L, 1); /* use true as result */
429 lua_pushvalue(L, -1); /* extra copy to be returned */
430 lua_setfield(L, 2, name); /* _LOADED[name] = true */
431 }
432 lj_lib_checkfpu(L);
433 return 1;
434}
435
436/* ------------------------------------------------------------------------ */
437
438static void setfenv(lua_State *L)
439{
440 lua_Debug ar;
441 if (lua_getstack(L, 1, &ar) == 0 ||
442 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
443 lua_iscfunction(L, -1))
444 luaL_error(L, LUA_QL("module") " not called from a Lua function");
445 lua_pushvalue(L, -2);
446 lua_setfenv(L, -2);
447 lua_pop(L, 1);
448}
449
450static void dooptions(lua_State *L, int n)
451{
452 int i;
453 for (i = 2; i <= n; i++) {
454 lua_pushvalue(L, i); /* get option (a function) */
455 lua_pushvalue(L, -2); /* module */
456 lua_call(L, 1, 0);
457 }
458}
459
460static void modinit(lua_State *L, const char *modname)
461{
462 const char *dot;
463 lua_pushvalue(L, -1);
464 lua_setfield(L, -2, "_M"); /* module._M = module */
465 lua_pushstring(L, modname);
466 lua_setfield(L, -2, "_NAME");
467 dot = strrchr(modname, '.'); /* look for last dot in module name */
468 if (dot == NULL) dot = modname; else dot++;
469 /* set _PACKAGE as package name (full module name minus last part) */
470 lua_pushlstring(L, modname, (size_t)(dot - modname));
471 lua_setfield(L, -2, "_PACKAGE");
472}
473
474static int lj_cf_package_module(lua_State *L)
475{
476 const char *modname = luaL_checkstring(L, 1);
477 int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
478 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
479 lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
480 if (!lua_istable(L, -1)) { /* not found? */
481 lua_pop(L, 1); /* remove previous result */
482 /* try global variable (and create one if it does not exist) */
483 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
484 lj_err_callerv(L, LJ_ERR_BADMODN, modname);
485 lua_pushvalue(L, -1);
486 lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
487 }
488 /* check whether table already has a _NAME field */
489 lua_getfield(L, -1, "_NAME");
490 if (!lua_isnil(L, -1)) { /* is table an initialized module? */
491 lua_pop(L, 1);
492 } else { /* no; initialize it */
493 lua_pop(L, 1);
494 modinit(L, modname);
495 }
496 lua_pushvalue(L, -1);
497 setfenv(L);
498 dooptions(L, loaded - 1);
499 return 0;
500}
501
502static int lj_cf_package_seeall(lua_State *L)
503{
504 luaL_checktype(L, 1, LUA_TTABLE);
505 if (!lua_getmetatable(L, 1)) {
506 lua_createtable(L, 0, 1); /* create new metatable */
507 lua_pushvalue(L, -1);
508 lua_setmetatable(L, 1);
509 }
510 lua_pushvalue(L, LUA_GLOBALSINDEX);
511 lua_setfield(L, -2, "__index"); /* mt.__index = _G */
512 return 0;
513}
514
515/* ------------------------------------------------------------------------ */
516
517#define AUXMARK "\1"
518
519static void setpath(lua_State *L, const char *fieldname, const char *envname,
520 const char *def)
521{
522 const char *path = getenv(envname);
523 if (path == NULL) {
524 lua_pushstring(L, def);
525 } else {
526 path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
527 LUA_PATHSEP AUXMARK LUA_PATHSEP);
528 luaL_gsub(L, path, AUXMARK, def);
529 lua_remove(L, -2);
530 }
531 setprogdir(L);
532 lua_setfield(L, -2, fieldname);
533}
534
535static const luaL_Reg package_lib[] = {
536 { "loadlib", lj_cf_package_loadlib },
537 { "searchpath", lj_cf_package_searchpath },
538 { "seeall", lj_cf_package_seeall },
539 { NULL, NULL }
540};
541
542static const luaL_Reg package_global[] = {
543 { "module", lj_cf_package_module },
544 { "require", lj_cf_package_require },
545 { NULL, NULL }
546};
547
548static const lua_CFunction package_loaders[] =
549{
550 lj_cf_package_loader_preload,
551 lj_cf_package_loader_lua,
552 lj_cf_package_loader_c,
553 lj_cf_package_loader_croot,
554 NULL
555};
556
557LUALIB_API int luaopen_package(lua_State *L)
558{
559 int i;
560 luaL_newmetatable(L, "_LOADLIB");
561 lj_lib_pushcf(L, lj_cf_package_unloadlib, 1);
562 lua_setfield(L, -2, "__gc");
563 luaL_register(L, LUA_LOADLIBNAME, package_lib);
564 lua_pushvalue(L, -1);
565 lua_replace(L, LUA_ENVIRONINDEX);
566 lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0);
567 for (i = 0; package_loaders[i] != NULL; i++) {
568 lj_lib_pushcf(L, package_loaders[i], 1);
569 lua_rawseti(L, -2, i+1);
570 }
571 lua_setfield(L, -2, "loaders");
572 setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT);
573 setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT);
574 lua_pushliteral(L, LUA_PATH_CONFIG);
575 lua_setfield(L, -2, "config");
576 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
577 lua_setfield(L, -2, "loaded");
578 luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
579 lua_setfield(L, -2, "preload");
580 lua_pushvalue(L, LUA_GLOBALSINDEX);
581 luaL_register(L, NULL, package_global);
582 lua_pop(L, 1);
583 return 1;
584}
585
diff --git a/libraries/luajit-2.0/src/lib_string.c b/libraries/luajit-2.0/src/lib_string.c
new file mode 100644
index 0000000..5cbe6e4
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_string.c
@@ -0,0 +1,855 @@
1/*
2** String library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#include <stdio.h>
10
11#define lib_string_c
12#define LUA_LIB
13
14#include "lua.h"
15#include "lauxlib.h"
16#include "lualib.h"
17
18#include "lj_obj.h"
19#include "lj_gc.h"
20#include "lj_err.h"
21#include "lj_str.h"
22#include "lj_tab.h"
23#include "lj_state.h"
24#include "lj_ff.h"
25#include "lj_bcdump.h"
26#include "lj_char.h"
27#include "lj_lib.h"
28
29/* ------------------------------------------------------------------------ */
30
31#define LJLIB_MODULE_string
32
33LJLIB_ASM(string_len) LJLIB_REC(.)
34{
35 lj_lib_checkstr(L, 1);
36 return FFH_RETRY;
37}
38
39LJLIB_ASM(string_byte) LJLIB_REC(string_range 0)
40{
41 GCstr *s = lj_lib_checkstr(L, 1);
42 int32_t len = (int32_t)s->len;
43 int32_t start = lj_lib_optint(L, 2, 1);
44 int32_t stop = lj_lib_optint(L, 3, start);
45 int32_t n, i;
46 const unsigned char *p;
47 if (stop < 0) stop += len+1;
48 if (start < 0) start += len+1;
49 if (start <= 0) start = 1;
50 if (stop > len) stop = len;
51 if (start > stop) return FFH_RES(0); /* Empty interval: return no results. */
52 start--;
53 n = stop - start;
54 if ((uint32_t)n > LUAI_MAXCSTACK)
55 lj_err_caller(L, LJ_ERR_STRSLC);
56 lj_state_checkstack(L, (MSize)n);
57 p = (const unsigned char *)strdata(s) + start;
58 for (i = 0; i < n; i++)
59 setintV(L->base + i-1, p[i]);
60 return FFH_RES(n);
61}
62
63LJLIB_ASM(string_char)
64{
65 int i, nargs = (int)(L->top - L->base);
66 char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, (size_t)nargs);
67 for (i = 1; i <= nargs; i++) {
68 int32_t k = lj_lib_checkint(L, i);
69 if (!checku8(k))
70 lj_err_arg(L, i, LJ_ERR_BADVAL);
71 buf[i-1] = (char)k;
72 }
73 setstrV(L, L->base-1, lj_str_new(L, buf, (size_t)nargs));
74 return FFH_RES(1);
75}
76
77LJLIB_ASM(string_sub) LJLIB_REC(string_range 1)
78{
79 lj_lib_checkstr(L, 1);
80 lj_lib_checkint(L, 2);
81 setintV(L->base+2, lj_lib_optint(L, 3, -1));
82 return FFH_RETRY;
83}
84
85LJLIB_ASM(string_rep)
86{
87 GCstr *s = lj_lib_checkstr(L, 1);
88 int32_t len = (int32_t)s->len;
89 int32_t k = lj_lib_checkint(L, 2);
90 int64_t tlen = (int64_t)k * len;
91 const char *src;
92 char *buf;
93 if (k <= 0) return FFH_RETRY;
94 if (tlen > LJ_MAX_STR)
95 lj_err_caller(L, LJ_ERR_STROV);
96 buf = lj_str_needbuf(L, &G(L)->tmpbuf, (MSize)tlen);
97 if (len <= 1) return FFH_RETRY; /* ASM code only needed buffer resize. */
98 src = strdata(s);
99 do {
100 int32_t i = 0;
101 do { *buf++ = src[i++]; } while (i < len);
102 } while (--k > 0);
103 setstrV(L, L->base-1, lj_str_new(L, G(L)->tmpbuf.buf, (size_t)tlen));
104 return FFH_RES(1);
105}
106
107LJLIB_ASM(string_reverse)
108{
109 GCstr *s = lj_lib_checkstr(L, 1);
110 lj_str_needbuf(L, &G(L)->tmpbuf, s->len);
111 return FFH_RETRY;
112}
113LJLIB_ASM_(string_lower)
114LJLIB_ASM_(string_upper)
115
116/* ------------------------------------------------------------------------ */
117
118static int writer_buf(lua_State *L, const void *p, size_t size, void *b)
119{
120 luaL_addlstring((luaL_Buffer *)b, (const char *)p, size);
121 UNUSED(L);
122 return 0;
123}
124
125LJLIB_CF(string_dump)
126{
127 GCfunc *fn = lj_lib_checkfunc(L, 1);
128 int strip = L->base+1 < L->top && tvistruecond(L->base+1);
129 luaL_Buffer b;
130 L->top = L->base+1;
131 luaL_buffinit(L, &b);
132 if (!isluafunc(fn) || lj_bcwrite(L, funcproto(fn), writer_buf, &b, strip))
133 lj_err_caller(L, LJ_ERR_STRDUMP);
134 luaL_pushresult(&b);
135 return 1;
136}
137
138/* ------------------------------------------------------------------------ */
139
140/* macro to `unsign' a character */
141#define uchar(c) ((unsigned char)(c))
142
143#define CAP_UNFINISHED (-1)
144#define CAP_POSITION (-2)
145
146typedef struct MatchState {
147 const char *src_init; /* init of source string */
148 const char *src_end; /* end (`\0') of source string */
149 lua_State *L;
150 int level; /* total number of captures (finished or unfinished) */
151 struct {
152 const char *init;
153 ptrdiff_t len;
154 } capture[LUA_MAXCAPTURES];
155} MatchState;
156
157#define L_ESC '%'
158#define SPECIALS "^$*+?.([%-"
159
160static int check_capture(MatchState *ms, int l)
161{
162 l -= '1';
163 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
164 lj_err_caller(ms->L, LJ_ERR_STRCAPI);
165 return l;
166}
167
168static int capture_to_close(MatchState *ms)
169{
170 int level = ms->level;
171 for (level--; level>=0; level--)
172 if (ms->capture[level].len == CAP_UNFINISHED) return level;
173 lj_err_caller(ms->L, LJ_ERR_STRPATC);
174 return 0; /* unreachable */
175}
176
177static const char *classend(MatchState *ms, const char *p)
178{
179 switch (*p++) {
180 case L_ESC:
181 if (*p == '\0')
182 lj_err_caller(ms->L, LJ_ERR_STRPATE);
183 return p+1;
184 case '[':
185 if (*p == '^') p++;
186 do { /* look for a `]' */
187 if (*p == '\0')
188 lj_err_caller(ms->L, LJ_ERR_STRPATM);
189 if (*(p++) == L_ESC && *p != '\0')
190 p++; /* skip escapes (e.g. `%]') */
191 } while (*p != ']');
192 return p+1;
193 default:
194 return p;
195 }
196}
197
198static const unsigned char match_class_map[32] = {
199 0,LJ_CHAR_ALPHA,0,LJ_CHAR_CNTRL,LJ_CHAR_DIGIT,0,0,LJ_CHAR_GRAPH,0,0,0,0,
200 LJ_CHAR_LOWER,0,0,0,LJ_CHAR_PUNCT,0,0,LJ_CHAR_SPACE,0,
201 LJ_CHAR_UPPER,0,LJ_CHAR_ALNUM,LJ_CHAR_XDIGIT,0,0,0,0,0,0,0
202};
203
204static int match_class(int c, int cl)
205{
206 if ((cl & 0xc0) == 0x40) {
207 int t = match_class_map[(cl&0x1f)];
208 if (t) {
209 t = lj_char_isa(c, t);
210 return (cl & 0x20) ? t : !t;
211 }
212 if (cl == 'z') return c == 0;
213 if (cl == 'Z') return c != 0;
214 }
215 return (cl == c);
216}
217
218static int matchbracketclass(int c, const char *p, const char *ec)
219{
220 int sig = 1;
221 if (*(p+1) == '^') {
222 sig = 0;
223 p++; /* skip the `^' */
224 }
225 while (++p < ec) {
226 if (*p == L_ESC) {
227 p++;
228 if (match_class(c, uchar(*p)))
229 return sig;
230 }
231 else if ((*(p+1) == '-') && (p+2 < ec)) {
232 p+=2;
233 if (uchar(*(p-2)) <= c && c <= uchar(*p))
234 return sig;
235 }
236 else if (uchar(*p) == c) return sig;
237 }
238 return !sig;
239}
240
241static int singlematch(int c, const char *p, const char *ep)
242{
243 switch (*p) {
244 case '.': return 1; /* matches any char */
245 case L_ESC: return match_class(c, uchar(*(p+1)));
246 case '[': return matchbracketclass(c, p, ep-1);
247 default: return (uchar(*p) == c);
248 }
249}
250
251static const char *match(MatchState *ms, const char *s, const char *p);
252
253static const char *matchbalance(MatchState *ms, const char *s, const char *p)
254{
255 if (*p == 0 || *(p+1) == 0)
256 lj_err_caller(ms->L, LJ_ERR_STRPATU);
257 if (*s != *p) {
258 return NULL;
259 } else {
260 int b = *p;
261 int e = *(p+1);
262 int cont = 1;
263 while (++s < ms->src_end) {
264 if (*s == e) {
265 if (--cont == 0) return s+1;
266 } else if (*s == b) {
267 cont++;
268 }
269 }
270 }
271 return NULL; /* string ends out of balance */
272}
273
274static const char *max_expand(MatchState *ms, const char *s,
275 const char *p, const char *ep)
276{
277 ptrdiff_t i = 0; /* counts maximum expand for item */
278 while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
279 i++;
280 /* keeps trying to match with the maximum repetitions */
281 while (i>=0) {
282 const char *res = match(ms, (s+i), ep+1);
283 if (res) return res;
284 i--; /* else didn't match; reduce 1 repetition to try again */
285 }
286 return NULL;
287}
288
289static const char *min_expand(MatchState *ms, const char *s,
290 const char *p, const char *ep)
291{
292 for (;;) {
293 const char *res = match(ms, s, ep+1);
294 if (res != NULL)
295 return res;
296 else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
297 s++; /* try with one more repetition */
298 else
299 return NULL;
300 }
301}
302
303static const char *start_capture(MatchState *ms, const char *s,
304 const char *p, int what)
305{
306 const char *res;
307 int level = ms->level;
308 if (level >= LUA_MAXCAPTURES) lj_err_caller(ms->L, LJ_ERR_STRCAPN);
309 ms->capture[level].init = s;
310 ms->capture[level].len = what;
311 ms->level = level+1;
312 if ((res=match(ms, s, p)) == NULL) /* match failed? */
313 ms->level--; /* undo capture */
314 return res;
315}
316
317static const char *end_capture(MatchState *ms, const char *s,
318 const char *p)
319{
320 int l = capture_to_close(ms);
321 const char *res;
322 ms->capture[l].len = s - ms->capture[l].init; /* close capture */
323 if ((res = match(ms, s, p)) == NULL) /* match failed? */
324 ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
325 return res;
326}
327
328static const char *match_capture(MatchState *ms, const char *s, int l)
329{
330 size_t len;
331 l = check_capture(ms, l);
332 len = (size_t)ms->capture[l].len;
333 if ((size_t)(ms->src_end-s) >= len &&
334 memcmp(ms->capture[l].init, s, len) == 0)
335 return s+len;
336 else
337 return NULL;
338}
339
340static const char *match(MatchState *ms, const char *s, const char *p)
341{
342 init: /* using goto's to optimize tail recursion */
343 switch (*p) {
344 case '(': /* start capture */
345 if (*(p+1) == ')') /* position capture? */
346 return start_capture(ms, s, p+2, CAP_POSITION);
347 else
348 return start_capture(ms, s, p+1, CAP_UNFINISHED);
349 case ')': /* end capture */
350 return end_capture(ms, s, p+1);
351 case L_ESC:
352 switch (*(p+1)) {
353 case 'b': /* balanced string? */
354 s = matchbalance(ms, s, p+2);
355 if (s == NULL) return NULL;
356 p+=4;
357 goto init; /* else return match(ms, s, p+4); */
358 case 'f': { /* frontier? */
359 const char *ep; char previous;
360 p += 2;
361 if (*p != '[')
362 lj_err_caller(ms->L, LJ_ERR_STRPATB);
363 ep = classend(ms, p); /* points to what is next */
364 previous = (s == ms->src_init) ? '\0' : *(s-1);
365 if (matchbracketclass(uchar(previous), p, ep-1) ||
366 !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
367 p=ep;
368 goto init; /* else return match(ms, s, ep); */
369 }
370 default:
371 if (lj_char_isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
372 s = match_capture(ms, s, uchar(*(p+1)));
373 if (s == NULL) return NULL;
374 p+=2;
375 goto init; /* else return match(ms, s, p+2) */
376 }
377 goto dflt; /* case default */
378 }
379 case '\0': /* end of pattern */
380 return s; /* match succeeded */
381 case '$':
382 if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
383 return (s == ms->src_end) ? s : NULL; /* check end of string */
384 else
385 goto dflt;
386 default: dflt: { /* it is a pattern item */
387 const char *ep = classend(ms, p); /* points to what is next */
388 int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
389 switch (*ep) {
390 case '?': { /* optional */
391 const char *res;
392 if (m && ((res=match(ms, s+1, ep+1)) != NULL))
393 return res;
394 p=ep+1;
395 goto init; /* else return match(ms, s, ep+1); */
396 }
397 case '*': /* 0 or more repetitions */
398 return max_expand(ms, s, p, ep);
399 case '+': /* 1 or more repetitions */
400 return (m ? max_expand(ms, s+1, p, ep) : NULL);
401 case '-': /* 0 or more repetitions (minimum) */
402 return min_expand(ms, s, p, ep);
403 default:
404 if (!m) return NULL;
405 s++; p=ep;
406 goto init; /* else return match(ms, s+1, ep); */
407 }
408 }
409 }
410}
411
412static const char *lmemfind(const char *s1, size_t l1,
413 const char *s2, size_t l2)
414{
415 if (l2 == 0) {
416 return s1; /* empty strings are everywhere */
417 } else if (l2 > l1) {
418 return NULL; /* avoids a negative `l1' */
419 } else {
420 const char *init; /* to search for a `*s2' inside `s1' */
421 l2--; /* 1st char will be checked by `memchr' */
422 l1 = l1-l2; /* `s2' cannot be found after that */
423 while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
424 init++; /* 1st char is already checked */
425 if (memcmp(init, s2+1, l2) == 0) {
426 return init-1;
427 } else { /* correct `l1' and `s1' to try again */
428 l1 -= (size_t)(init-s1);
429 s1 = init;
430 }
431 }
432 return NULL; /* not found */
433 }
434}
435
436static void push_onecapture(MatchState *ms, int i, const char *s, const char *e)
437{
438 if (i >= ms->level) {
439 if (i == 0) /* ms->level == 0, too */
440 lua_pushlstring(ms->L, s, (size_t)(e - s)); /* add whole match */
441 else
442 lj_err_caller(ms->L, LJ_ERR_STRCAPI);
443 } else {
444 ptrdiff_t l = ms->capture[i].len;
445 if (l == CAP_UNFINISHED) lj_err_caller(ms->L, LJ_ERR_STRCAPU);
446 if (l == CAP_POSITION)
447 lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
448 else
449 lua_pushlstring(ms->L, ms->capture[i].init, (size_t)l);
450 }
451}
452
453static int push_captures(MatchState *ms, const char *s, const char *e)
454{
455 int i;
456 int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
457 luaL_checkstack(ms->L, nlevels, "too many captures");
458 for (i = 0; i < nlevels; i++)
459 push_onecapture(ms, i, s, e);
460 return nlevels; /* number of strings pushed */
461}
462
463static ptrdiff_t posrelat(ptrdiff_t pos, size_t len)
464{
465 /* relative string position: negative means back from end */
466 if (pos < 0) pos += (ptrdiff_t)len + 1;
467 return (pos >= 0) ? pos : 0;
468}
469
470static int str_find_aux(lua_State *L, int find)
471{
472 size_t l1, l2;
473 const char *s = luaL_checklstring(L, 1, &l1);
474 const char *p = luaL_checklstring(L, 2, &l2);
475 ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
476 if (init < 0)
477 init = 0;
478 else if ((size_t)(init) > l1)
479 init = (ptrdiff_t)l1;
480 if (find && (lua_toboolean(L, 4) || /* explicit request? */
481 strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
482 /* do a plain search */
483 const char *s2 = lmemfind(s+init, l1-(size_t)init, p, l2);
484 if (s2) {
485 lua_pushinteger(L, s2-s+1);
486 lua_pushinteger(L, s2-s+(ptrdiff_t)l2);
487 return 2;
488 }
489 } else {
490 MatchState ms;
491 int anchor = (*p == '^') ? (p++, 1) : 0;
492 const char *s1=s+init;
493 ms.L = L;
494 ms.src_init = s;
495 ms.src_end = s+l1;
496 do {
497 const char *res;
498 ms.level = 0;
499 if ((res=match(&ms, s1, p)) != NULL) {
500 if (find) {
501 lua_pushinteger(L, s1-s+1); /* start */
502 lua_pushinteger(L, res-s); /* end */
503 return push_captures(&ms, NULL, 0) + 2;
504 } else {
505 return push_captures(&ms, s1, res);
506 }
507 }
508 } while (s1++ < ms.src_end && !anchor);
509 }
510 lua_pushnil(L); /* not found */
511 return 1;
512}
513
514LJLIB_CF(string_find)
515{
516 return str_find_aux(L, 1);
517}
518
519LJLIB_CF(string_match)
520{
521 return str_find_aux(L, 0);
522}
523
524LJLIB_NOREG LJLIB_CF(string_gmatch_aux)
525{
526 const char *p = strVdata(lj_lib_upvalue(L, 2));
527 GCstr *str = strV(lj_lib_upvalue(L, 1));
528 const char *s = strdata(str);
529 TValue *tvpos = lj_lib_upvalue(L, 3);
530 const char *src = s + tvpos->u32.lo;
531 MatchState ms;
532 ms.L = L;
533 ms.src_init = s;
534 ms.src_end = s + str->len;
535 for (; src <= ms.src_end; src++) {
536 const char *e;
537 ms.level = 0;
538 if ((e = match(&ms, src, p)) != NULL) {
539 int32_t pos = (int32_t)(e - s);
540 if (e == src) pos++; /* Ensure progress for empty match. */
541 tvpos->u32.lo = (uint32_t)pos;
542 return push_captures(&ms, src, e);
543 }
544 }
545 return 0; /* not found */
546}
547
548LJLIB_CF(string_gmatch)
549{
550 lj_lib_checkstr(L, 1);
551 lj_lib_checkstr(L, 2);
552 L->top = L->base+3;
553 (L->top-1)->u64 = 0;
554 lj_lib_pushcc(L, lj_cf_string_gmatch_aux, FF_string_gmatch_aux, 3);
555 return 1;
556}
557
558static void add_s(MatchState *ms, luaL_Buffer *b, const char *s, const char *e)
559{
560 size_t l, i;
561 const char *news = lua_tolstring(ms->L, 3, &l);
562 for (i = 0; i < l; i++) {
563 if (news[i] != L_ESC) {
564 luaL_addchar(b, news[i]);
565 } else {
566 i++; /* skip ESC */
567 if (!lj_char_isdigit(uchar(news[i]))) {
568 luaL_addchar(b, news[i]);
569 } else if (news[i] == '0') {
570 luaL_addlstring(b, s, (size_t)(e - s));
571 } else {
572 push_onecapture(ms, news[i] - '1', s, e);
573 luaL_addvalue(b); /* add capture to accumulated result */
574 }
575 }
576 }
577}
578
579static void add_value(MatchState *ms, luaL_Buffer *b,
580 const char *s, const char *e)
581{
582 lua_State *L = ms->L;
583 switch (lua_type(L, 3)) {
584 case LUA_TNUMBER:
585 case LUA_TSTRING: {
586 add_s(ms, b, s, e);
587 return;
588 }
589 case LUA_TFUNCTION: {
590 int n;
591 lua_pushvalue(L, 3);
592 n = push_captures(ms, s, e);
593 lua_call(L, n, 1);
594 break;
595 }
596 case LUA_TTABLE: {
597 push_onecapture(ms, 0, s, e);
598 lua_gettable(L, 3);
599 break;
600 }
601 }
602 if (!lua_toboolean(L, -1)) { /* nil or false? */
603 lua_pop(L, 1);
604 lua_pushlstring(L, s, (size_t)(e - s)); /* keep original text */
605 } else if (!lua_isstring(L, -1)) {
606 lj_err_callerv(L, LJ_ERR_STRGSRV, luaL_typename(L, -1));
607 }
608 luaL_addvalue(b); /* add result to accumulator */
609}
610
611LJLIB_CF(string_gsub)
612{
613 size_t srcl;
614 const char *src = luaL_checklstring(L, 1, &srcl);
615 const char *p = luaL_checkstring(L, 2);
616 int tr = lua_type(L, 3);
617 int max_s = luaL_optint(L, 4, (int)(srcl+1));
618 int anchor = (*p == '^') ? (p++, 1) : 0;
619 int n = 0;
620 MatchState ms;
621 luaL_Buffer b;
622 if (!(tr == LUA_TNUMBER || tr == LUA_TSTRING ||
623 tr == LUA_TFUNCTION || tr == LUA_TTABLE))
624 lj_err_arg(L, 3, LJ_ERR_NOSFT);
625 luaL_buffinit(L, &b);
626 ms.L = L;
627 ms.src_init = src;
628 ms.src_end = src+srcl;
629 while (n < max_s) {
630 const char *e;
631 ms.level = 0;
632 e = match(&ms, src, p);
633 if (e) {
634 n++;
635 add_value(&ms, &b, src, e);
636 }
637 if (e && e>src) /* non empty match? */
638 src = e; /* skip it */
639 else if (src < ms.src_end)
640 luaL_addchar(&b, *src++);
641 else
642 break;
643 if (anchor)
644 break;
645 }
646 luaL_addlstring(&b, src, (size_t)(ms.src_end-src));
647 luaL_pushresult(&b);
648 lua_pushinteger(L, n); /* number of substitutions */
649 return 2;
650}
651
652/* ------------------------------------------------------------------------ */
653
654/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
655#define MAX_FMTITEM 512
656/* valid flags in a format specification */
657#define FMT_FLAGS "-+ #0"
658/*
659** maximum size of each format specification (such as '%-099.99d')
660** (+10 accounts for %99.99x plus margin of error)
661*/
662#define MAX_FMTSPEC (sizeof(FMT_FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
663
664static void addquoted(lua_State *L, luaL_Buffer *b, int arg)
665{
666 GCstr *str = lj_lib_checkstr(L, arg);
667 int32_t len = (int32_t)str->len;
668 const char *s = strdata(str);
669 luaL_addchar(b, '"');
670 while (len--) {
671 if (*s == '"' || *s == '\\' || *s == '\n') {
672 luaL_addchar(b, '\\');
673 luaL_addchar(b, *s);
674 } else if (lj_char_iscntrl(uchar(*s))) {
675 uint32_t c1, c2, c3;
676 luaL_addchar(b, '\\');
677 c1 = uchar(*s); c3 = c1 % 10; c1 /= 10; c2 = c1 % 10; c1 /= 10;
678 if (c1 + lj_char_isdigit(uchar(s[1]))) luaL_addchar(b, '0' + c1);
679 if (c2 + (c1 + lj_char_isdigit(uchar(s[1])))) luaL_addchar(b, '0' + c2);
680 luaL_addchar(b, '0' + c3);
681 } else {
682 luaL_addchar(b, *s);
683 }
684 s++;
685 }
686 luaL_addchar(b, '"');
687}
688
689static const char *scanformat(lua_State *L, const char *strfrmt, char *form)
690{
691 const char *p = strfrmt;
692 while (*p != '\0' && strchr(FMT_FLAGS, *p) != NULL) p++; /* skip flags */
693 if ((size_t)(p - strfrmt) >= sizeof(FMT_FLAGS))
694 lj_err_caller(L, LJ_ERR_STRFMTR);
695 if (lj_char_isdigit(uchar(*p))) p++; /* skip width */
696 if (lj_char_isdigit(uchar(*p))) p++; /* (2 digits at most) */
697 if (*p == '.') {
698 p++;
699 if (lj_char_isdigit(uchar(*p))) p++; /* skip precision */
700 if (lj_char_isdigit(uchar(*p))) p++; /* (2 digits at most) */
701 }
702 if (lj_char_isdigit(uchar(*p)))
703 lj_err_caller(L, LJ_ERR_STRFMTW);
704 *(form++) = '%';
705 strncpy(form, strfrmt, (size_t)(p - strfrmt + 1));
706 form += p - strfrmt + 1;
707 *form = '\0';
708 return p;
709}
710
711static void addintlen(char *form)
712{
713 size_t l = strlen(form);
714 char spec = form[l - 1];
715 strcpy(form + l - 1, LUA_INTFRMLEN);
716 form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
717 form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
718}
719
720static unsigned LUA_INTFRM_T num2intfrm(lua_State *L, int arg)
721{
722 if (sizeof(LUA_INTFRM_T) == 4) {
723 return (LUA_INTFRM_T)lj_lib_checkbit(L, arg);
724 } else {
725 cTValue *o;
726 lj_lib_checknumber(L, arg);
727 o = L->base+arg-1;
728 if (tvisint(o))
729 return (LUA_INTFRM_T)intV(o);
730 else
731 return (LUA_INTFRM_T)numV(o);
732 }
733}
734
735static unsigned LUA_INTFRM_T num2uintfrm(lua_State *L, int arg)
736{
737 if (sizeof(LUA_INTFRM_T) == 4) {
738 return (unsigned LUA_INTFRM_T)lj_lib_checkbit(L, arg);
739 } else {
740 cTValue *o;
741 lj_lib_checknumber(L, arg);
742 o = L->base+arg-1;
743 if (tvisint(o))
744 return (unsigned LUA_INTFRM_T)intV(o);
745 else if ((int32_t)o->u32.hi < 0)
746 return (unsigned LUA_INTFRM_T)(LUA_INTFRM_T)numV(o);
747 else
748 return (unsigned LUA_INTFRM_T)numV(o);
749 }
750}
751
752LJLIB_CF(string_format)
753{
754 int arg = 1, top = (int)(L->top - L->base);
755 GCstr *fmt = lj_lib_checkstr(L, arg);
756 const char *strfrmt = strdata(fmt);
757 const char *strfrmt_end = strfrmt + fmt->len;
758 luaL_Buffer b;
759 luaL_buffinit(L, &b);
760 while (strfrmt < strfrmt_end) {
761 if (*strfrmt != L_ESC) {
762 luaL_addchar(&b, *strfrmt++);
763 } else if (*++strfrmt == L_ESC) {
764 luaL_addchar(&b, *strfrmt++); /* %% */
765 } else { /* format item */
766 char form[MAX_FMTSPEC]; /* to store the format (`%...') */
767 char buff[MAX_FMTITEM]; /* to store the formatted item */
768 if (++arg > top)
769 luaL_argerror(L, arg, lj_obj_typename[0]);
770 strfrmt = scanformat(L, strfrmt, form);
771 switch (*strfrmt++) {
772 case 'c':
773 sprintf(buff, form, lj_lib_checkint(L, arg));
774 break;
775 case 'd': case 'i':
776 addintlen(form);
777 sprintf(buff, form, num2intfrm(L, arg));
778 break;
779 case 'o': case 'u': case 'x': case 'X':
780 addintlen(form);
781 sprintf(buff, form, num2uintfrm(L, arg));
782 break;
783 case 'e': case 'E': case 'f': case 'g': case 'G': {
784 TValue tv;
785 tv.n = lj_lib_checknum(L, arg);
786 if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) {
787 /* Canonicalize output of non-finite values. */
788 char *p, nbuf[LJ_STR_NUMBUF];
789 size_t len = lj_str_bufnum(nbuf, &tv);
790 if (strfrmt[-1] == 'E' || strfrmt[-1] == 'G') {
791 nbuf[len-3] = nbuf[len-3] - 0x20;
792 nbuf[len-2] = nbuf[len-2] - 0x20;
793 nbuf[len-1] = nbuf[len-1] - 0x20;
794 }
795 nbuf[len] = '\0';
796 for (p = form; *p < 'e' && *p != '.'; p++) ;
797 *p++ = 's'; *p = '\0';
798 sprintf(buff, form, nbuf);
799 break;
800 }
801 sprintf(buff, form, (double)tv.n);
802 break;
803 }
804 case 'q':
805 addquoted(L, &b, arg);
806 continue;
807 case 'p':
808 lj_str_pushf(L, "%p", lua_topointer(L, arg));
809 luaL_addvalue(&b);
810 continue;
811 case 's': {
812 GCstr *str = lj_lib_checkstr(L, arg);
813 if (!strchr(form, '.') && str->len >= 100) {
814 /* no precision and string is too long to be formatted;
815 keep original string */
816 setstrV(L, L->top++, str);
817 luaL_addvalue(&b);
818 continue;
819 }
820 sprintf(buff, form, strdata(str));
821 break;
822 }
823 default:
824 lj_err_callerv(L, LJ_ERR_STRFMTO, *(strfrmt -1));
825 break;
826 }
827 luaL_addlstring(&b, buff, strlen(buff));
828 }
829 }
830 luaL_pushresult(&b);
831 return 1;
832}
833
834/* ------------------------------------------------------------------------ */
835
836#include "lj_libdef.h"
837
838LUALIB_API int luaopen_string(lua_State *L)
839{
840 GCtab *mt;
841 global_State *g;
842 LJ_LIB_REG(L, LUA_STRLIBNAME, string);
843#if defined(LUA_COMPAT_GFIND)
844 lua_getfield(L, -1, "gmatch");
845 lua_setfield(L, -2, "gfind");
846#endif
847 mt = lj_tab_new(L, 0, 1);
848 /* NOBARRIER: basemt is a GC root. */
849 g = G(L);
850 setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt));
851 settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1));
852 mt->nomm = (uint8_t)(~(1u<<MM_index));
853 return 1;
854}
855
diff --git a/libraries/luajit-2.0/src/lib_table.c b/libraries/luajit-2.0/src/lib_table.c
new file mode 100644
index 0000000..64684b7
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_table.c
@@ -0,0 +1,282 @@
1/*
2** Table library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lib_table_c
10#define LUA_LIB
11
12#include "lua.h"
13#include "lauxlib.h"
14#include "lualib.h"
15
16#include "lj_obj.h"
17#include "lj_gc.h"
18#include "lj_err.h"
19#include "lj_tab.h"
20#include "lj_lib.h"
21
22/* ------------------------------------------------------------------------ */
23
24#define LJLIB_MODULE_table
25
26LJLIB_CF(table_foreachi)
27{
28 GCtab *t = lj_lib_checktab(L, 1);
29 GCfunc *func = lj_lib_checkfunc(L, 2);
30 MSize i, n = lj_tab_len(t);
31 for (i = 1; i <= n; i++) {
32 cTValue *val;
33 setfuncV(L, L->top, func);
34 setintV(L->top+1, i);
35 val = lj_tab_getint(t, (int32_t)i);
36 if (val) { copyTV(L, L->top+2, val); } else { setnilV(L->top+2); }
37 L->top += 3;
38 lua_call(L, 2, 1);
39 if (!tvisnil(L->top-1))
40 return 1;
41 L->top--;
42 }
43 return 0;
44}
45
46LJLIB_CF(table_foreach)
47{
48 GCtab *t = lj_lib_checktab(L, 1);
49 GCfunc *func = lj_lib_checkfunc(L, 2);
50 L->top = L->base+3;
51 setnilV(L->top-1);
52 while (lj_tab_next(L, t, L->top-1)) {
53 copyTV(L, L->top+2, L->top);
54 copyTV(L, L->top+1, L->top-1);
55 setfuncV(L, L->top, func);
56 L->top += 3;
57 lua_call(L, 2, 1);
58 if (!tvisnil(L->top-1))
59 return 1;
60 L->top--;
61 }
62 return 0;
63}
64
65LJLIB_ASM(table_getn) LJLIB_REC(.)
66{
67 lj_lib_checktab(L, 1);
68 return FFH_UNREACHABLE;
69}
70
71LJLIB_CF(table_maxn)
72{
73 GCtab *t = lj_lib_checktab(L, 1);
74 TValue *array = tvref(t->array);
75 Node *node;
76 lua_Number m = 0;
77 ptrdiff_t i;
78 for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
79 if (!tvisnil(&array[i])) {
80 m = (lua_Number)(int32_t)i;
81 break;
82 }
83 node = noderef(t->node);
84 for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
85 if (!tvisnil(&node[i].val) && tvisnumber(&node[i].key)) {
86 lua_Number n = numberVnum(&node[i].key);
87 if (n > m) m = n;
88 }
89 setnumV(L->top-1, m);
90 return 1;
91}
92
93LJLIB_CF(table_insert) LJLIB_REC(.)
94{
95 GCtab *t = lj_lib_checktab(L, 1);
96 int32_t n, i = (int32_t)lj_tab_len(t) + 1;
97 int nargs = (int)((char *)L->top - (char *)L->base);
98 if (nargs != 2*sizeof(TValue)) {
99 if (nargs != 3*sizeof(TValue))
100 lj_err_caller(L, LJ_ERR_TABINS);
101 /* NOBARRIER: This just moves existing elements around. */
102 for (n = lj_lib_checkint(L, 2); i > n; i--) {
103 /* The set may invalidate the get pointer, so need to do it first! */
104 TValue *dst = lj_tab_setint(L, t, i);
105 cTValue *src = lj_tab_getint(t, i-1);
106 if (src) {
107 copyTV(L, dst, src);
108 } else {
109 setnilV(dst);
110 }
111 }
112 i = n;
113 }
114 {
115 TValue *dst = lj_tab_setint(L, t, i);
116 copyTV(L, dst, L->top-1); /* Set new value. */
117 lj_gc_barriert(L, t, dst);
118 }
119 return 0;
120}
121
122LJLIB_CF(table_remove) LJLIB_REC(.)
123{
124 GCtab *t = lj_lib_checktab(L, 1);
125 int32_t e = (int32_t)lj_tab_len(t);
126 int32_t pos = lj_lib_optint(L, 2, e);
127 if (!(1 <= pos && pos <= e)) /* Nothing to remove? */
128 return 0;
129 lua_rawgeti(L, 1, pos); /* Get previous value. */
130 /* NOBARRIER: This just moves existing elements around. */
131 for (; pos < e; pos++) {
132 cTValue *src = lj_tab_getint(t, pos+1);
133 TValue *dst = lj_tab_setint(L, t, pos);
134 if (src) {
135 copyTV(L, dst, src);
136 } else {
137 setnilV(dst);
138 }
139 }
140 setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */
141 return 1; /* Return previous value. */
142}
143
144LJLIB_CF(table_concat)
145{
146 luaL_Buffer b;
147 GCtab *t = lj_lib_checktab(L, 1);
148 GCstr *sep = lj_lib_optstr(L, 2);
149 MSize seplen = sep ? sep->len : 0;
150 int32_t i = lj_lib_optint(L, 3, 1);
151 int32_t e = L->base+3 < L->top ? lj_lib_checkint(L, 4) :
152 (int32_t)lj_tab_len(t);
153 luaL_buffinit(L, &b);
154 if (i <= e) {
155 for (;;) {
156 cTValue *o;
157 lua_rawgeti(L, 1, i);
158 o = L->top-1;
159 if (!(tvisstr(o) || tvisnumber(o)))
160 lj_err_callerv(L, LJ_ERR_TABCAT, typename(o), i);
161 luaL_addvalue(&b);
162 if (i++ == e) break;
163 if (seplen)
164 luaL_addlstring(&b, strdata(sep), seplen);
165 }
166 }
167 luaL_pushresult(&b);
168 return 1;
169}
170
171/* ------------------------------------------------------------------------ */
172
173static void set2(lua_State *L, int i, int j)
174{
175 lua_rawseti(L, 1, i);
176 lua_rawseti(L, 1, j);
177}
178
179static int sort_comp(lua_State *L, int a, int b)
180{
181 if (!lua_isnil(L, 2)) { /* function? */
182 int res;
183 lua_pushvalue(L, 2);
184 lua_pushvalue(L, a-1); /* -1 to compensate function */
185 lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
186 lua_call(L, 2, 1);
187 res = lua_toboolean(L, -1);
188 lua_pop(L, 1);
189 return res;
190 } else { /* a < b? */
191 return lua_lessthan(L, a, b);
192 }
193}
194
195static void auxsort(lua_State *L, int l, int u)
196{
197 while (l < u) { /* for tail recursion */
198 int i, j;
199 /* sort elements a[l], a[(l+u)/2] and a[u] */
200 lua_rawgeti(L, 1, l);
201 lua_rawgeti(L, 1, u);
202 if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
203 set2(L, l, u); /* swap a[l] - a[u] */
204 else
205 lua_pop(L, 2);
206 if (u-l == 1) break; /* only 2 elements */
207 i = (l+u)/2;
208 lua_rawgeti(L, 1, i);
209 lua_rawgeti(L, 1, l);
210 if (sort_comp(L, -2, -1)) { /* a[i]<a[l]? */
211 set2(L, i, l);
212 } else {
213 lua_pop(L, 1); /* remove a[l] */
214 lua_rawgeti(L, 1, u);
215 if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
216 set2(L, i, u);
217 else
218 lua_pop(L, 2);
219 }
220 if (u-l == 2) break; /* only 3 elements */
221 lua_rawgeti(L, 1, i); /* Pivot */
222 lua_pushvalue(L, -1);
223 lua_rawgeti(L, 1, u-1);
224 set2(L, i, u-1);
225 /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
226 i = l; j = u-1;
227 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
228 /* repeat ++i until a[i] >= P */
229 while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
230 if (i>=u) lj_err_caller(L, LJ_ERR_TABSORT);
231 lua_pop(L, 1); /* remove a[i] */
232 }
233 /* repeat --j until a[j] <= P */
234 while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
235 if (j<=l) lj_err_caller(L, LJ_ERR_TABSORT);
236 lua_pop(L, 1); /* remove a[j] */
237 }
238 if (j<i) {
239 lua_pop(L, 3); /* pop pivot, a[i], a[j] */
240 break;
241 }
242 set2(L, i, j);
243 }
244 lua_rawgeti(L, 1, u-1);
245 lua_rawgeti(L, 1, i);
246 set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
247 /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
248 /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
249 if (i-l < u-i) {
250 j=l; i=i-1; l=i+2;
251 } else {
252 j=i+1; i=u; u=j-2;
253 }
254 auxsort(L, j, i); /* call recursively the smaller one */
255 } /* repeat the routine for the larger one */
256}
257
258LJLIB_CF(table_sort)
259{
260 GCtab *t = lj_lib_checktab(L, 1);
261 int32_t n = (int32_t)lj_tab_len(t);
262 lua_settop(L, 2);
263 if (!tvisnil(L->base+1))
264 lj_lib_checkfunc(L, 2);
265 auxsort(L, 1, n);
266 return 0;
267}
268
269/* ------------------------------------------------------------------------ */
270
271#include "lj_libdef.h"
272
273LUALIB_API int luaopen_table(lua_State *L)
274{
275 LJ_LIB_REG(L, LUA_TABLIBNAME, table);
276#ifdef LUAJIT_ENABLE_LUA52COMPAT
277 lua_getglobal(L, "unpack");
278 lua_setfield(L, -2, "unpack");
279#endif
280 return 1;
281}
282
diff --git a/libraries/luajit-2.0/src/lj.supp b/libraries/luajit-2.0/src/lj.supp
new file mode 100644
index 0000000..f1126ad
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj.supp
@@ -0,0 +1,16 @@
1# Valgrind suppression file for LuaJIT 2.x.
2{
3 Optimized string compare
4 Memcheck:Addr4
5 fun:lj_str_cmp
6}
7{
8 Optimized string compare
9 Memcheck:Addr4
10 fun:lj_str_new
11}
12{
13 Optimized string compare
14 Memcheck:Cond
15 fun:lj_str_new
16}
diff --git a/libraries/luajit-2.0/src/lj_alloc.c b/libraries/luajit-2.0/src/lj_alloc.c
new file mode 100644
index 0000000..c1aac00
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_alloc.c
@@ -0,0 +1,1381 @@
1/*
2** Bundled memory allocator.
3**
4** Beware: this is a HEAVILY CUSTOMIZED version of dlmalloc.
5** The original bears the following remark:
6**
7** This is a version (aka dlmalloc) of malloc/free/realloc written by
8** Doug Lea and released to the public domain, as explained at
9** http://creativecommons.org/licenses/publicdomain.
10**
11** * Version pre-2.8.4 Wed Mar 29 19:46:29 2006 (dl at gee)
12**
13** No additional copyright is claimed over the customizations.
14** Please do NOT bother the original author about this version here!
15**
16** If you want to use dlmalloc in another project, you should get
17** the original from: ftp://gee.cs.oswego.edu/pub/misc/
18** For thread-safe derivatives, take a look at:
19** - ptmalloc: http://www.malloc.de/
20** - nedmalloc: http://www.nedprod.com/programs/portable/nedmalloc/
21*/
22
23#define lj_alloc_c
24#define LUA_CORE
25
26/* To get the mremap prototype. Must be defined before any system includes. */
27#if defined(__linux__) && !defined(_GNU_SOURCE)
28#define _GNU_SOURCE
29#endif
30
31#include "lj_def.h"
32#include "lj_arch.h"
33#include "lj_alloc.h"
34
35#ifndef LUAJIT_USE_SYSMALLOC
36
37#define MAX_SIZE_T (~(size_t)0)
38#define MALLOC_ALIGNMENT ((size_t)8U)
39
40#define DEFAULT_GRANULARITY ((size_t)128U * (size_t)1024U)
41#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
42#define DEFAULT_MMAP_THRESHOLD ((size_t)128U * (size_t)1024U)
43#define MAX_RELEASE_CHECK_RATE 255
44
45/* ------------------- size_t and alignment properties -------------------- */
46
47/* The byte and bit size of a size_t */
48#define SIZE_T_SIZE (sizeof(size_t))
49#define SIZE_T_BITSIZE (sizeof(size_t) << 3)
50
51/* Some constants coerced to size_t */
52/* Annoying but necessary to avoid errors on some platforms */
53#define SIZE_T_ZERO ((size_t)0)
54#define SIZE_T_ONE ((size_t)1)
55#define SIZE_T_TWO ((size_t)2)
56#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1)
57#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2)
58#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
59
60/* The bit mask value corresponding to MALLOC_ALIGNMENT */
61#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE)
62
63/* the number of bytes to offset an address to align it */
64#define align_offset(A)\
65 ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
66 ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
67
68/* -------------------------- MMAP support ------------------------------- */
69
70#define MFAIL ((void *)(MAX_SIZE_T))
71#define CMFAIL ((char *)(MFAIL)) /* defined for convenience */
72
73#define IS_DIRECT_BIT (SIZE_T_ONE)
74
75#if LJ_TARGET_WINDOWS
76
77#define WIN32_LEAN_AND_MEAN
78#include <windows.h>
79
80#if LJ_64
81
82/* Undocumented, but hey, that's what we all love so much about Windows. */
83typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG zbits,
84 size_t *size, ULONG alloctype, ULONG prot);
85static PNTAVM ntavm;
86
87/* Number of top bits of the lower 32 bits of an address that must be zero.
88** Apparently 0 gives us full 64 bit addresses and 1 gives us the lower 2GB.
89*/
90#define NTAVM_ZEROBITS 1
91
92static void INIT_MMAP(void)
93{
94 ntavm = (PNTAVM)GetProcAddress(GetModuleHandleA("ntdll.dll"),
95 "NtAllocateVirtualMemory");
96}
97
98/* Win64 32 bit MMAP via NtAllocateVirtualMemory. */
99static LJ_AINLINE void *CALL_MMAP(size_t size)
100{
101 DWORD olderr = GetLastError();
102 void *ptr = NULL;
103 long st = ntavm(INVALID_HANDLE_VALUE, &ptr, NTAVM_ZEROBITS, &size,
104 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
105 SetLastError(olderr);
106 return st == 0 ? ptr : MFAIL;
107}
108
109/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
110static LJ_AINLINE void *DIRECT_MMAP(size_t size)
111{
112 DWORD olderr = GetLastError();
113 void *ptr = NULL;
114 long st = ntavm(INVALID_HANDLE_VALUE, &ptr, NTAVM_ZEROBITS, &size,
115 MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
116 SetLastError(olderr);
117 return st == 0 ? ptr : MFAIL;
118}
119
120#else
121
122#define INIT_MMAP() ((void)0)
123
124/* Win32 MMAP via VirtualAlloc */
125static LJ_AINLINE void *CALL_MMAP(size_t size)
126{
127 DWORD olderr = GetLastError();
128 void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
129 SetLastError(olderr);
130 return ptr ? ptr : MFAIL;
131}
132
133/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
134static LJ_AINLINE void *DIRECT_MMAP(size_t size)
135{
136 DWORD olderr = GetLastError();
137 void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
138 PAGE_READWRITE);
139 SetLastError(olderr);
140 return ptr ? ptr : MFAIL;
141}
142
143#endif
144
145/* This function supports releasing coalesed segments */
146static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size)
147{
148 DWORD olderr = GetLastError();
149 MEMORY_BASIC_INFORMATION minfo;
150 char *cptr = (char *)ptr;
151 while (size) {
152 if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
153 return -1;
154 if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
155 minfo.State != MEM_COMMIT || minfo.RegionSize > size)
156 return -1;
157 if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
158 return -1;
159 cptr += minfo.RegionSize;
160 size -= minfo.RegionSize;
161 }
162 SetLastError(olderr);
163 return 0;
164}
165
166#else
167
168#include <errno.h>
169#include <sys/mman.h>
170
171#define MMAP_PROT (PROT_READ|PROT_WRITE)
172#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
173#define MAP_ANONYMOUS MAP_ANON
174#endif
175#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS)
176
177#if LJ_64
178/* 64 bit mode needs special support for allocating memory in the lower 2GB. */
179
180#if LJ_TARGET_LINUX
181
182/* Actually this only gives us max. 1GB in current Linux kernels. */
183static LJ_AINLINE void *CALL_MMAP(size_t size)
184{
185 int olderr = errno;
186 void *ptr = mmap(NULL, size, MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0);
187 errno = olderr;
188 return ptr;
189}
190
191#elif LJ_TARGET_OSX || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
192
193/* OSX and FreeBSD mmap() use a naive first-fit linear search.
194** That's perfect for us. Except that -pagezero_size must be set for OSX,
195** otherwise the lower 4GB are blocked. And the 32GB RLIMIT_DATA needs
196** to be reduced to 250MB on FreeBSD.
197*/
198#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
199#include <sys/resource.h>
200#define MMAP_REGION_START ((uintptr_t)0x10000000)
201#else
202#define MMAP_REGION_START ((uintptr_t)0x10000)
203#endif
204#define MMAP_REGION_END ((uintptr_t)0x80000000)
205
206static LJ_AINLINE void *CALL_MMAP(size_t size)
207{
208 int olderr = errno;
209 /* Hint for next allocation. Doesn't need to be thread-safe. */
210 static uintptr_t alloc_hint = MMAP_REGION_START;
211 int retry = 0;
212#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
213 static int rlimit_modified = 0;
214 if (LJ_UNLIKELY(rlimit_modified == 0)) {
215 struct rlimit rlim;
216 rlim.rlim_cur = rlim.rlim_max = MMAP_REGION_START;
217 setrlimit(RLIMIT_DATA, &rlim); /* Ignore result. May fail below. */
218 rlimit_modified = 1;
219 }
220#endif
221 for (;;) {
222 void *p = mmap((void *)alloc_hint, size, MMAP_PROT, MMAP_FLAGS, -1, 0);
223 if ((uintptr_t)p >= MMAP_REGION_START &&
224 (uintptr_t)p + size < MMAP_REGION_END) {
225 alloc_hint = (uintptr_t)p + size;
226 errno = olderr;
227 return p;
228 }
229 if (p != CMFAIL) munmap(p, size);
230 if (retry) break;
231 retry = 1;
232 alloc_hint = MMAP_REGION_START;
233 }
234 errno = olderr;
235 return CMFAIL;
236}
237
238#else
239
240#error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS"
241
242#endif
243
244#else
245
246/* 32 bit mode is easy. */
247static LJ_AINLINE void *CALL_MMAP(size_t size)
248{
249 int olderr = errno;
250 void *ptr = mmap(NULL, size, MMAP_PROT, MMAP_FLAGS, -1, 0);
251 errno = olderr;
252 return ptr;
253}
254
255#endif
256
257#define INIT_MMAP() ((void)0)
258#define DIRECT_MMAP(s) CALL_MMAP(s)
259
260static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size)
261{
262 int olderr = errno;
263 int ret = munmap(ptr, size);
264 errno = olderr;
265 return ret;
266}
267
268#if LJ_TARGET_LINUX
269/* Need to define _GNU_SOURCE to get the mremap prototype. */
270static LJ_AINLINE void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz,
271 int flags)
272{
273 int olderr = errno;
274 ptr = mremap(ptr, osz, nsz, flags);
275 errno = olderr;
276 return ptr;
277}
278
279#define CALL_MREMAP(addr, osz, nsz, mv) CALL_MREMAP_((addr), (osz), (nsz), (mv))
280#define CALL_MREMAP_NOMOVE 0
281#define CALL_MREMAP_MAYMOVE 1
282#if LJ_64
283#define CALL_MREMAP_MV CALL_MREMAP_NOMOVE
284#else
285#define CALL_MREMAP_MV CALL_MREMAP_MAYMOVE
286#endif
287#endif
288
289#endif
290
291#ifndef CALL_MREMAP
292#define CALL_MREMAP(addr, osz, nsz, mv) ((void)osz, MFAIL)
293#endif
294
295/* ----------------------- Chunk representations ------------------------ */
296
297struct malloc_chunk {
298 size_t prev_foot; /* Size of previous chunk (if free). */
299 size_t head; /* Size and inuse bits. */
300 struct malloc_chunk *fd; /* double links -- used only if free. */
301 struct malloc_chunk *bk;
302};
303
304typedef struct malloc_chunk mchunk;
305typedef struct malloc_chunk *mchunkptr;
306typedef struct malloc_chunk *sbinptr; /* The type of bins of chunks */
307typedef size_t bindex_t; /* Described below */
308typedef unsigned int binmap_t; /* Described below */
309typedef unsigned int flag_t; /* The type of various bit flag sets */
310
311/* ------------------- Chunks sizes and alignments ----------------------- */
312
313#define MCHUNK_SIZE (sizeof(mchunk))
314
315#define CHUNK_OVERHEAD (SIZE_T_SIZE)
316
317/* Direct chunks need a second word of overhead ... */
318#define DIRECT_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
319/* ... and additional padding for fake next-chunk at foot */
320#define DIRECT_FOOT_PAD (FOUR_SIZE_T_SIZES)
321
322/* The smallest size we can malloc is an aligned minimal chunk */
323#define MIN_CHUNK_SIZE\
324 ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
325
326/* conversion from malloc headers to user pointers, and back */
327#define chunk2mem(p) ((void *)((char *)(p) + TWO_SIZE_T_SIZES))
328#define mem2chunk(mem) ((mchunkptr)((char *)(mem) - TWO_SIZE_T_SIZES))
329/* chunk associated with aligned address A */
330#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A)))
331
332/* Bounds on request (not chunk) sizes. */
333#define MAX_REQUEST ((~MIN_CHUNK_SIZE+1) << 2)
334#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
335
336/* pad request bytes into a usable size */
337#define pad_request(req) \
338 (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
339
340/* pad request, checking for minimum (but not maximum) */
341#define request2size(req) \
342 (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
343
344/* ------------------ Operations on head and foot fields ----------------- */
345
346#define PINUSE_BIT (SIZE_T_ONE)
347#define CINUSE_BIT (SIZE_T_TWO)
348#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT)
349
350/* Head value for fenceposts */
351#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE)
352
353/* extraction of fields from head words */
354#define cinuse(p) ((p)->head & CINUSE_BIT)
355#define pinuse(p) ((p)->head & PINUSE_BIT)
356#define chunksize(p) ((p)->head & ~(INUSE_BITS))
357
358#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT)
359#define clear_cinuse(p) ((p)->head &= ~CINUSE_BIT)
360
361/* Treat space at ptr +/- offset as a chunk */
362#define chunk_plus_offset(p, s) ((mchunkptr)(((char *)(p)) + (s)))
363#define chunk_minus_offset(p, s) ((mchunkptr)(((char *)(p)) - (s)))
364
365/* Ptr to next or previous physical malloc_chunk. */
366#define next_chunk(p) ((mchunkptr)(((char *)(p)) + ((p)->head & ~INUSE_BITS)))
367#define prev_chunk(p) ((mchunkptr)(((char *)(p)) - ((p)->prev_foot) ))
368
369/* extract next chunk's pinuse bit */
370#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT)
371
372/* Get/set size at footer */
373#define get_foot(p, s) (((mchunkptr)((char *)(p) + (s)))->prev_foot)
374#define set_foot(p, s) (((mchunkptr)((char *)(p) + (s)))->prev_foot = (s))
375
376/* Set size, pinuse bit, and foot */
377#define set_size_and_pinuse_of_free_chunk(p, s)\
378 ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
379
380/* Set size, pinuse bit, foot, and clear next pinuse */
381#define set_free_with_pinuse(p, s, n)\
382 (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
383
384#define is_direct(p)\
385 (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_DIRECT_BIT))
386
387/* Get the internal overhead associated with chunk p */
388#define overhead_for(p)\
389 (is_direct(p)? DIRECT_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
390
391/* ---------------------- Overlaid data structures ----------------------- */
392
393struct malloc_tree_chunk {
394 /* The first four fields must be compatible with malloc_chunk */
395 size_t prev_foot;
396 size_t head;
397 struct malloc_tree_chunk *fd;
398 struct malloc_tree_chunk *bk;
399
400 struct malloc_tree_chunk *child[2];
401 struct malloc_tree_chunk *parent;
402 bindex_t index;
403};
404
405typedef struct malloc_tree_chunk tchunk;
406typedef struct malloc_tree_chunk *tchunkptr;
407typedef struct malloc_tree_chunk *tbinptr; /* The type of bins of trees */
408
409/* A little helper macro for trees */
410#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
411
412/* ----------------------------- Segments -------------------------------- */
413
414struct malloc_segment {
415 char *base; /* base address */
416 size_t size; /* allocated size */
417 struct malloc_segment *next; /* ptr to next segment */
418};
419
420typedef struct malloc_segment msegment;
421typedef struct malloc_segment *msegmentptr;
422
423/* ---------------------------- malloc_state ----------------------------- */
424
425/* Bin types, widths and sizes */
426#define NSMALLBINS (32U)
427#define NTREEBINS (32U)
428#define SMALLBIN_SHIFT (3U)
429#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT)
430#define TREEBIN_SHIFT (8U)
431#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT)
432#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE)
433#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
434
435struct malloc_state {
436 binmap_t smallmap;
437 binmap_t treemap;
438 size_t dvsize;
439 size_t topsize;
440 mchunkptr dv;
441 mchunkptr top;
442 size_t trim_check;
443 size_t release_checks;
444 mchunkptr smallbins[(NSMALLBINS+1)*2];
445 tbinptr treebins[NTREEBINS];
446 msegment seg;
447};
448
449typedef struct malloc_state *mstate;
450
451#define is_initialized(M) ((M)->top != 0)
452
453/* -------------------------- system alloc setup ------------------------- */
454
455/* page-align a size */
456#define page_align(S)\
457 (((S) + (LJ_PAGESIZE - SIZE_T_ONE)) & ~(LJ_PAGESIZE - SIZE_T_ONE))
458
459/* granularity-align a size */
460#define granularity_align(S)\
461 (((S) + (DEFAULT_GRANULARITY - SIZE_T_ONE))\
462 & ~(DEFAULT_GRANULARITY - SIZE_T_ONE))
463
464#if LJ_TARGET_WINDOWS
465#define mmap_align(S) granularity_align(S)
466#else
467#define mmap_align(S) page_align(S)
468#endif
469
470/* True if segment S holds address A */
471#define segment_holds(S, A)\
472 ((char *)(A) >= S->base && (char *)(A) < S->base + S->size)
473
474/* Return segment holding given address */
475static msegmentptr segment_holding(mstate m, char *addr)
476{
477 msegmentptr sp = &m->seg;
478 for (;;) {
479 if (addr >= sp->base && addr < sp->base + sp->size)
480 return sp;
481 if ((sp = sp->next) == 0)
482 return 0;
483 }
484}
485
486/* Return true if segment contains a segment link */
487static int has_segment_link(mstate m, msegmentptr ss)
488{
489 msegmentptr sp = &m->seg;
490 for (;;) {
491 if ((char *)sp >= ss->base && (char *)sp < ss->base + ss->size)
492 return 1;
493 if ((sp = sp->next) == 0)
494 return 0;
495 }
496}
497
498/*
499 TOP_FOOT_SIZE is padding at the end of a segment, including space
500 that may be needed to place segment records and fenceposts when new
501 noncontiguous segments are added.
502*/
503#define TOP_FOOT_SIZE\
504 (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
505
506/* ---------------------------- Indexing Bins ---------------------------- */
507
508#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
509#define small_index(s) ((s) >> SMALLBIN_SHIFT)
510#define small_index2size(i) ((i) << SMALLBIN_SHIFT)
511#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE))
512
513/* addressing by index. See above about smallbin repositioning */
514#define smallbin_at(M, i) ((sbinptr)((char *)&((M)->smallbins[(i)<<1])))
515#define treebin_at(M,i) (&((M)->treebins[i]))
516
517/* assign tree index for size S to variable I */
518#define compute_tree_index(S, I)\
519{\
520 unsigned int X = (unsigned int)(S >> TREEBIN_SHIFT);\
521 if (X == 0) {\
522 I = 0;\
523 } else if (X > 0xFFFF) {\
524 I = NTREEBINS-1;\
525 } else {\
526 unsigned int K = lj_fls(X);\
527 I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
528 }\
529}
530
531/* Bit representing maximum resolved size in a treebin at i */
532#define bit_for_tree_index(i) \
533 (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
534
535/* Shift placing maximum resolved bit in a treebin at i as sign bit */
536#define leftshift_for_tree_index(i) \
537 ((i == NTREEBINS-1)? 0 : \
538 ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
539
540/* The size of the smallest chunk held in bin with index i */
541#define minsize_for_tree_index(i) \
542 ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \
543 (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
544
545/* ------------------------ Operations on bin maps ----------------------- */
546
547/* bit corresponding to given index */
548#define idx2bit(i) ((binmap_t)(1) << (i))
549
550/* Mark/Clear bits with given index */
551#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i))
552#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i))
553#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i))
554
555#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i))
556#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i))
557#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i))
558
559/* mask with all bits to left of least bit of x on */
560#define left_bits(x) ((x<<1) | (~(x<<1)+1))
561
562/* Set cinuse bit and pinuse bit of next chunk */
563#define set_inuse(M,p,s)\
564 ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
565 ((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT)
566
567/* Set cinuse and pinuse of this chunk and pinuse of next chunk */
568#define set_inuse_and_pinuse(M,p,s)\
569 ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
570 ((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT)
571
572/* Set size, cinuse and pinuse bit of this chunk */
573#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
574 ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
575
576/* ----------------------- Operations on smallbins ----------------------- */
577
578/* Link a free chunk into a smallbin */
579#define insert_small_chunk(M, P, S) {\
580 bindex_t I = small_index(S);\
581 mchunkptr B = smallbin_at(M, I);\
582 mchunkptr F = B;\
583 if (!smallmap_is_marked(M, I))\
584 mark_smallmap(M, I);\
585 else\
586 F = B->fd;\
587 B->fd = P;\
588 F->bk = P;\
589 P->fd = F;\
590 P->bk = B;\
591}
592
593/* Unlink a chunk from a smallbin */
594#define unlink_small_chunk(M, P, S) {\
595 mchunkptr F = P->fd;\
596 mchunkptr B = P->bk;\
597 bindex_t I = small_index(S);\
598 if (F == B) {\
599 clear_smallmap(M, I);\
600 } else {\
601 F->bk = B;\
602 B->fd = F;\
603 }\
604}
605
606/* Unlink the first chunk from a smallbin */
607#define unlink_first_small_chunk(M, B, P, I) {\
608 mchunkptr F = P->fd;\
609 if (B == F) {\
610 clear_smallmap(M, I);\
611 } else {\
612 B->fd = F;\
613 F->bk = B;\
614 }\
615}
616
617/* Replace dv node, binning the old one */
618/* Used only when dvsize known to be small */
619#define replace_dv(M, P, S) {\
620 size_t DVS = M->dvsize;\
621 if (DVS != 0) {\
622 mchunkptr DV = M->dv;\
623 insert_small_chunk(M, DV, DVS);\
624 }\
625 M->dvsize = S;\
626 M->dv = P;\
627}
628
629/* ------------------------- Operations on trees ------------------------- */
630
631/* Insert chunk into tree */
632#define insert_large_chunk(M, X, S) {\
633 tbinptr *H;\
634 bindex_t I;\
635 compute_tree_index(S, I);\
636 H = treebin_at(M, I);\
637 X->index = I;\
638 X->child[0] = X->child[1] = 0;\
639 if (!treemap_is_marked(M, I)) {\
640 mark_treemap(M, I);\
641 *H = X;\
642 X->parent = (tchunkptr)H;\
643 X->fd = X->bk = X;\
644 } else {\
645 tchunkptr T = *H;\
646 size_t K = S << leftshift_for_tree_index(I);\
647 for (;;) {\
648 if (chunksize(T) != S) {\
649 tchunkptr *C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
650 K <<= 1;\
651 if (*C != 0) {\
652 T = *C;\
653 } else {\
654 *C = X;\
655 X->parent = T;\
656 X->fd = X->bk = X;\
657 break;\
658 }\
659 } else {\
660 tchunkptr F = T->fd;\
661 T->fd = F->bk = X;\
662 X->fd = F;\
663 X->bk = T;\
664 X->parent = 0;\
665 break;\
666 }\
667 }\
668 }\
669}
670
671#define unlink_large_chunk(M, X) {\
672 tchunkptr XP = X->parent;\
673 tchunkptr R;\
674 if (X->bk != X) {\
675 tchunkptr F = X->fd;\
676 R = X->bk;\
677 F->bk = R;\
678 R->fd = F;\
679 } else {\
680 tchunkptr *RP;\
681 if (((R = *(RP = &(X->child[1]))) != 0) ||\
682 ((R = *(RP = &(X->child[0]))) != 0)) {\
683 tchunkptr *CP;\
684 while ((*(CP = &(R->child[1])) != 0) ||\
685 (*(CP = &(R->child[0])) != 0)) {\
686 R = *(RP = CP);\
687 }\
688 *RP = 0;\
689 }\
690 }\
691 if (XP != 0) {\
692 tbinptr *H = treebin_at(M, X->index);\
693 if (X == *H) {\
694 if ((*H = R) == 0) \
695 clear_treemap(M, X->index);\
696 } else {\
697 if (XP->child[0] == X) \
698 XP->child[0] = R;\
699 else \
700 XP->child[1] = R;\
701 }\
702 if (R != 0) {\
703 tchunkptr C0, C1;\
704 R->parent = XP;\
705 if ((C0 = X->child[0]) != 0) {\
706 R->child[0] = C0;\
707 C0->parent = R;\
708 }\
709 if ((C1 = X->child[1]) != 0) {\
710 R->child[1] = C1;\
711 C1->parent = R;\
712 }\
713 }\
714 }\
715}
716
717/* Relays to large vs small bin operations */
718
719#define insert_chunk(M, P, S)\
720 if (is_small(S)) { insert_small_chunk(M, P, S)\
721 } else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
722
723#define unlink_chunk(M, P, S)\
724 if (is_small(S)) { unlink_small_chunk(M, P, S)\
725 } else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
726
727/* ----------------------- Direct-mmapping chunks ----------------------- */
728
729static void *direct_alloc(size_t nb)
730{
731 size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
732 if (LJ_LIKELY(mmsize > nb)) { /* Check for wrap around 0 */
733 char *mm = (char *)(DIRECT_MMAP(mmsize));
734 if (mm != CMFAIL) {
735 size_t offset = align_offset(chunk2mem(mm));
736 size_t psize = mmsize - offset - DIRECT_FOOT_PAD;
737 mchunkptr p = (mchunkptr)(mm + offset);
738 p->prev_foot = offset | IS_DIRECT_BIT;
739 p->head = psize|CINUSE_BIT;
740 chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
741 chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
742 return chunk2mem(p);
743 }
744 }
745 return NULL;
746}
747
748static mchunkptr direct_resize(mchunkptr oldp, size_t nb)
749{
750 size_t oldsize = chunksize(oldp);
751 if (is_small(nb)) /* Can't shrink direct regions below small size */
752 return NULL;
753 /* Keep old chunk if big enough but not too big */
754 if (oldsize >= nb + SIZE_T_SIZE &&
755 (oldsize - nb) <= (DEFAULT_GRANULARITY << 1)) {
756 return oldp;
757 } else {
758 size_t offset = oldp->prev_foot & ~IS_DIRECT_BIT;
759 size_t oldmmsize = oldsize + offset + DIRECT_FOOT_PAD;
760 size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
761 char *cp = (char *)CALL_MREMAP((char *)oldp - offset,
762 oldmmsize, newmmsize, CALL_MREMAP_MV);
763 if (cp != CMFAIL) {
764 mchunkptr newp = (mchunkptr)(cp + offset);
765 size_t psize = newmmsize - offset - DIRECT_FOOT_PAD;
766 newp->head = psize|CINUSE_BIT;
767 chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
768 chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
769 return newp;
770 }
771 }
772 return NULL;
773}
774
775/* -------------------------- mspace management -------------------------- */
776
777/* Initialize top chunk and its size */
778static void init_top(mstate m, mchunkptr p, size_t psize)
779{
780 /* Ensure alignment */
781 size_t offset = align_offset(chunk2mem(p));
782 p = (mchunkptr)((char *)p + offset);
783 psize -= offset;
784
785 m->top = p;
786 m->topsize = psize;
787 p->head = psize | PINUSE_BIT;
788 /* set size of fake trailing chunk holding overhead space only once */
789 chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
790 m->trim_check = DEFAULT_TRIM_THRESHOLD; /* reset on each update */
791}
792
793/* Initialize bins for a new mstate that is otherwise zeroed out */
794static void init_bins(mstate m)
795{
796 /* Establish circular links for smallbins */
797 bindex_t i;
798 for (i = 0; i < NSMALLBINS; i++) {
799 sbinptr bin = smallbin_at(m,i);
800 bin->fd = bin->bk = bin;
801 }
802}
803
804/* Allocate chunk and prepend remainder with chunk in successor base. */
805static void *prepend_alloc(mstate m, char *newbase, char *oldbase, size_t nb)
806{
807 mchunkptr p = align_as_chunk(newbase);
808 mchunkptr oldfirst = align_as_chunk(oldbase);
809 size_t psize = (size_t)((char *)oldfirst - (char *)p);
810 mchunkptr q = chunk_plus_offset(p, nb);
811 size_t qsize = psize - nb;
812 set_size_and_pinuse_of_inuse_chunk(m, p, nb);
813
814 /* consolidate remainder with first chunk of old base */
815 if (oldfirst == m->top) {
816 size_t tsize = m->topsize += qsize;
817 m->top = q;
818 q->head = tsize | PINUSE_BIT;
819 } else if (oldfirst == m->dv) {
820 size_t dsize = m->dvsize += qsize;
821 m->dv = q;
822 set_size_and_pinuse_of_free_chunk(q, dsize);
823 } else {
824 if (!cinuse(oldfirst)) {
825 size_t nsize = chunksize(oldfirst);
826 unlink_chunk(m, oldfirst, nsize);
827 oldfirst = chunk_plus_offset(oldfirst, nsize);
828 qsize += nsize;
829 }
830 set_free_with_pinuse(q, qsize, oldfirst);
831 insert_chunk(m, q, qsize);
832 }
833
834 return chunk2mem(p);
835}
836
837/* Add a segment to hold a new noncontiguous region */
838static void add_segment(mstate m, char *tbase, size_t tsize)
839{
840 /* Determine locations and sizes of segment, fenceposts, old top */
841 char *old_top = (char *)m->top;
842 msegmentptr oldsp = segment_holding(m, old_top);
843 char *old_end = oldsp->base + oldsp->size;
844 size_t ssize = pad_request(sizeof(struct malloc_segment));
845 char *rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
846 size_t offset = align_offset(chunk2mem(rawsp));
847 char *asp = rawsp + offset;
848 char *csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
849 mchunkptr sp = (mchunkptr)csp;
850 msegmentptr ss = (msegmentptr)(chunk2mem(sp));
851 mchunkptr tnext = chunk_plus_offset(sp, ssize);
852 mchunkptr p = tnext;
853
854 /* reset top to new space */
855 init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
856
857 /* Set up segment record */
858 set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
859 *ss = m->seg; /* Push current record */
860 m->seg.base = tbase;
861 m->seg.size = tsize;
862 m->seg.next = ss;
863
864 /* Insert trailing fenceposts */
865 for (;;) {
866 mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
867 p->head = FENCEPOST_HEAD;
868 if ((char *)(&(nextp->head)) < old_end)
869 p = nextp;
870 else
871 break;
872 }
873
874 /* Insert the rest of old top into a bin as an ordinary free chunk */
875 if (csp != old_top) {
876 mchunkptr q = (mchunkptr)old_top;
877 size_t psize = (size_t)(csp - old_top);
878 mchunkptr tn = chunk_plus_offset(q, psize);
879 set_free_with_pinuse(q, psize, tn);
880 insert_chunk(m, q, psize);
881 }
882}
883
884/* -------------------------- System allocation -------------------------- */
885
886static void *alloc_sys(mstate m, size_t nb)
887{
888 char *tbase = CMFAIL;
889 size_t tsize = 0;
890
891 /* Directly map large chunks */
892 if (LJ_UNLIKELY(nb >= DEFAULT_MMAP_THRESHOLD)) {
893 void *mem = direct_alloc(nb);
894 if (mem != 0)
895 return mem;
896 }
897
898 {
899 size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE;
900 size_t rsize = granularity_align(req);
901 if (LJ_LIKELY(rsize > nb)) { /* Fail if wraps around zero */
902 char *mp = (char *)(CALL_MMAP(rsize));
903 if (mp != CMFAIL) {
904 tbase = mp;
905 tsize = rsize;
906 }
907 }
908 }
909
910 if (tbase != CMFAIL) {
911 msegmentptr sp = &m->seg;
912 /* Try to merge with an existing segment */
913 while (sp != 0 && tbase != sp->base + sp->size)
914 sp = sp->next;
915 if (sp != 0 && segment_holds(sp, m->top)) { /* append */
916 sp->size += tsize;
917 init_top(m, m->top, m->topsize + tsize);
918 } else {
919 sp = &m->seg;
920 while (sp != 0 && sp->base != tbase + tsize)
921 sp = sp->next;
922 if (sp != 0) {
923 char *oldbase = sp->base;
924 sp->base = tbase;
925 sp->size += tsize;
926 return prepend_alloc(m, tbase, oldbase, nb);
927 } else {
928 add_segment(m, tbase, tsize);
929 }
930 }
931
932 if (nb < m->topsize) { /* Allocate from new or extended top space */
933 size_t rsize = m->topsize -= nb;
934 mchunkptr p = m->top;
935 mchunkptr r = m->top = chunk_plus_offset(p, nb);
936 r->head = rsize | PINUSE_BIT;
937 set_size_and_pinuse_of_inuse_chunk(m, p, nb);
938 return chunk2mem(p);
939 }
940 }
941
942 return NULL;
943}
944
945/* ----------------------- system deallocation -------------------------- */
946
947/* Unmap and unlink any mmapped segments that don't contain used chunks */
948static size_t release_unused_segments(mstate m)
949{
950 size_t released = 0;
951 size_t nsegs = 0;
952 msegmentptr pred = &m->seg;
953 msegmentptr sp = pred->next;
954 while (sp != 0) {
955 char *base = sp->base;
956 size_t size = sp->size;
957 msegmentptr next = sp->next;
958 nsegs++;
959 {
960 mchunkptr p = align_as_chunk(base);
961 size_t psize = chunksize(p);
962 /* Can unmap if first chunk holds entire segment and not pinned */
963 if (!cinuse(p) && (char *)p + psize >= base + size - TOP_FOOT_SIZE) {
964 tchunkptr tp = (tchunkptr)p;
965 if (p == m->dv) {
966 m->dv = 0;
967 m->dvsize = 0;
968 } else {
969 unlink_large_chunk(m, tp);
970 }
971 if (CALL_MUNMAP(base, size) == 0) {
972 released += size;
973 /* unlink obsoleted record */
974 sp = pred;
975 sp->next = next;
976 } else { /* back out if cannot unmap */
977 insert_large_chunk(m, tp, psize);
978 }
979 }
980 }
981 pred = sp;
982 sp = next;
983 }
984 /* Reset check counter */
985 m->release_checks = nsegs > MAX_RELEASE_CHECK_RATE ?
986 nsegs : MAX_RELEASE_CHECK_RATE;
987 return released;
988}
989
990static int alloc_trim(mstate m, size_t pad)
991{
992 size_t released = 0;
993 if (pad < MAX_REQUEST && is_initialized(m)) {
994 pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
995
996 if (m->topsize > pad) {
997 /* Shrink top space in granularity-size units, keeping at least one */
998 size_t unit = DEFAULT_GRANULARITY;
999 size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
1000 SIZE_T_ONE) * unit;
1001 msegmentptr sp = segment_holding(m, (char *)m->top);
1002
1003 if (sp->size >= extra &&
1004 !has_segment_link(m, sp)) { /* can't shrink if pinned */
1005 size_t newsize = sp->size - extra;
1006 /* Prefer mremap, fall back to munmap */
1007 if ((CALL_MREMAP(sp->base, sp->size, newsize, CALL_MREMAP_NOMOVE) != MFAIL) ||
1008 (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
1009 released = extra;
1010 }
1011 }
1012
1013 if (released != 0) {
1014 sp->size -= released;
1015 init_top(m, m->top, m->topsize - released);
1016 }
1017 }
1018
1019 /* Unmap any unused mmapped segments */
1020 released += release_unused_segments(m);
1021
1022 /* On failure, disable autotrim to avoid repeated failed future calls */
1023 if (released == 0 && m->topsize > m->trim_check)
1024 m->trim_check = MAX_SIZE_T;
1025 }
1026
1027 return (released != 0)? 1 : 0;
1028}
1029
1030/* ---------------------------- malloc support --------------------------- */
1031
1032/* allocate a large request from the best fitting chunk in a treebin */
1033static void *tmalloc_large(mstate m, size_t nb)
1034{
1035 tchunkptr v = 0;
1036 size_t rsize = ~nb+1; /* Unsigned negation */
1037 tchunkptr t;
1038 bindex_t idx;
1039 compute_tree_index(nb, idx);
1040
1041 if ((t = *treebin_at(m, idx)) != 0) {
1042 /* Traverse tree for this bin looking for node with size == nb */
1043 size_t sizebits = nb << leftshift_for_tree_index(idx);
1044 tchunkptr rst = 0; /* The deepest untaken right subtree */
1045 for (;;) {
1046 tchunkptr rt;
1047 size_t trem = chunksize(t) - nb;
1048 if (trem < rsize) {
1049 v = t;
1050 if ((rsize = trem) == 0)
1051 break;
1052 }
1053 rt = t->child[1];
1054 t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
1055 if (rt != 0 && rt != t)
1056 rst = rt;
1057 if (t == 0) {
1058 t = rst; /* set t to least subtree holding sizes > nb */
1059 break;
1060 }
1061 sizebits <<= 1;
1062 }
1063 }
1064
1065 if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
1066 binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
1067 if (leftbits != 0)
1068 t = *treebin_at(m, lj_ffs(leftbits));
1069 }
1070
1071 while (t != 0) { /* find smallest of tree or subtree */
1072 size_t trem = chunksize(t) - nb;
1073 if (trem < rsize) {
1074 rsize = trem;
1075 v = t;
1076 }
1077 t = leftmost_child(t);
1078 }
1079
1080 /* If dv is a better fit, return NULL so malloc will use it */
1081 if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
1082 mchunkptr r = chunk_plus_offset(v, nb);
1083 unlink_large_chunk(m, v);
1084 if (rsize < MIN_CHUNK_SIZE) {
1085 set_inuse_and_pinuse(m, v, (rsize + nb));
1086 } else {
1087 set_size_and_pinuse_of_inuse_chunk(m, v, nb);
1088 set_size_and_pinuse_of_free_chunk(r, rsize);
1089 insert_chunk(m, r, rsize);
1090 }
1091 return chunk2mem(v);
1092 }
1093 return NULL;
1094}
1095
1096/* allocate a small request from the best fitting chunk in a treebin */
1097static void *tmalloc_small(mstate m, size_t nb)
1098{
1099 tchunkptr t, v;
1100 mchunkptr r;
1101 size_t rsize;
1102 bindex_t i = lj_ffs(m->treemap);
1103
1104 v = t = *treebin_at(m, i);
1105 rsize = chunksize(t) - nb;
1106
1107 while ((t = leftmost_child(t)) != 0) {
1108 size_t trem = chunksize(t) - nb;
1109 if (trem < rsize) {
1110 rsize = trem;
1111 v = t;
1112 }
1113 }
1114
1115 r = chunk_plus_offset(v, nb);
1116 unlink_large_chunk(m, v);
1117 if (rsize < MIN_CHUNK_SIZE) {
1118 set_inuse_and_pinuse(m, v, (rsize + nb));
1119 } else {
1120 set_size_and_pinuse_of_inuse_chunk(m, v, nb);
1121 set_size_and_pinuse_of_free_chunk(r, rsize);
1122 replace_dv(m, r, rsize);
1123 }
1124 return chunk2mem(v);
1125}
1126
1127/* ----------------------------------------------------------------------- */
1128
1129void *lj_alloc_create(void)
1130{
1131 size_t tsize = DEFAULT_GRANULARITY;
1132 char *tbase;
1133 INIT_MMAP();
1134 tbase = (char *)(CALL_MMAP(tsize));
1135 if (tbase != CMFAIL) {
1136 size_t msize = pad_request(sizeof(struct malloc_state));
1137 mchunkptr mn;
1138 mchunkptr msp = align_as_chunk(tbase);
1139 mstate m = (mstate)(chunk2mem(msp));
1140 memset(m, 0, msize);
1141 msp->head = (msize|PINUSE_BIT|CINUSE_BIT);
1142 m->seg.base = tbase;
1143 m->seg.size = tsize;
1144 m->release_checks = MAX_RELEASE_CHECK_RATE;
1145 init_bins(m);
1146 mn = next_chunk(mem2chunk(m));
1147 init_top(m, mn, (size_t)((tbase + tsize) - (char *)mn) - TOP_FOOT_SIZE);
1148 return m;
1149 }
1150 return NULL;
1151}
1152
1153void lj_alloc_destroy(void *msp)
1154{
1155 mstate ms = (mstate)msp;
1156 msegmentptr sp = &ms->seg;
1157 while (sp != 0) {
1158 char *base = sp->base;
1159 size_t size = sp->size;
1160 sp = sp->next;
1161 CALL_MUNMAP(base, size);
1162 }
1163}
1164
1165static LJ_NOINLINE void *lj_alloc_malloc(void *msp, size_t nsize)
1166{
1167 mstate ms = (mstate)msp;
1168 void *mem;
1169 size_t nb;
1170 if (nsize <= MAX_SMALL_REQUEST) {
1171 bindex_t idx;
1172 binmap_t smallbits;
1173 nb = (nsize < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(nsize);
1174 idx = small_index(nb);
1175 smallbits = ms->smallmap >> idx;
1176
1177 if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
1178 mchunkptr b, p;
1179 idx += ~smallbits & 1; /* Uses next bin if idx empty */
1180 b = smallbin_at(ms, idx);
1181 p = b->fd;
1182 unlink_first_small_chunk(ms, b, p, idx);
1183 set_inuse_and_pinuse(ms, p, small_index2size(idx));
1184 mem = chunk2mem(p);
1185 return mem;
1186 } else if (nb > ms->dvsize) {
1187 if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
1188 mchunkptr b, p, r;
1189 size_t rsize;
1190 binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
1191 bindex_t i = lj_ffs(leftbits);
1192 b = smallbin_at(ms, i);
1193 p = b->fd;
1194 unlink_first_small_chunk(ms, b, p, i);
1195 rsize = small_index2size(i) - nb;
1196 /* Fit here cannot be remainderless if 4byte sizes */
1197 if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) {
1198 set_inuse_and_pinuse(ms, p, small_index2size(i));
1199 } else {
1200 set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
1201 r = chunk_plus_offset(p, nb);
1202 set_size_and_pinuse_of_free_chunk(r, rsize);
1203 replace_dv(ms, r, rsize);
1204 }
1205 mem = chunk2mem(p);
1206 return mem;
1207 } else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
1208 return mem;
1209 }
1210 }
1211 } else if (nsize >= MAX_REQUEST) {
1212 nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
1213 } else {
1214 nb = pad_request(nsize);
1215 if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
1216 return mem;
1217 }
1218 }
1219
1220 if (nb <= ms->dvsize) {
1221 size_t rsize = ms->dvsize - nb;
1222 mchunkptr p = ms->dv;
1223 if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
1224 mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
1225 ms->dvsize = rsize;
1226 set_size_and_pinuse_of_free_chunk(r, rsize);
1227 set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
1228 } else { /* exhaust dv */
1229 size_t dvs = ms->dvsize;
1230 ms->dvsize = 0;
1231 ms->dv = 0;
1232 set_inuse_and_pinuse(ms, p, dvs);
1233 }
1234 mem = chunk2mem(p);
1235 return mem;
1236 } else if (nb < ms->topsize) { /* Split top */
1237 size_t rsize = ms->topsize -= nb;
1238 mchunkptr p = ms->top;
1239 mchunkptr r = ms->top = chunk_plus_offset(p, nb);
1240 r->head = rsize | PINUSE_BIT;
1241 set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
1242 mem = chunk2mem(p);
1243 return mem;
1244 }
1245 return alloc_sys(ms, nb);
1246}
1247
1248static LJ_NOINLINE void *lj_alloc_free(void *msp, void *ptr)
1249{
1250 if (ptr != 0) {
1251 mchunkptr p = mem2chunk(ptr);
1252 mstate fm = (mstate)msp;
1253 size_t psize = chunksize(p);
1254 mchunkptr next = chunk_plus_offset(p, psize);
1255 if (!pinuse(p)) {
1256 size_t prevsize = p->prev_foot;
1257 if ((prevsize & IS_DIRECT_BIT) != 0) {
1258 prevsize &= ~IS_DIRECT_BIT;
1259 psize += prevsize + DIRECT_FOOT_PAD;
1260 CALL_MUNMAP((char *)p - prevsize, psize);
1261 return NULL;
1262 } else {
1263 mchunkptr prev = chunk_minus_offset(p, prevsize);
1264 psize += prevsize;
1265 p = prev;
1266 /* consolidate backward */
1267 if (p != fm->dv) {
1268 unlink_chunk(fm, p, prevsize);
1269 } else if ((next->head & INUSE_BITS) == INUSE_BITS) {
1270 fm->dvsize = psize;
1271 set_free_with_pinuse(p, psize, next);
1272 return NULL;
1273 }
1274 }
1275 }
1276 if (!cinuse(next)) { /* consolidate forward */
1277 if (next == fm->top) {
1278 size_t tsize = fm->topsize += psize;
1279 fm->top = p;
1280 p->head = tsize | PINUSE_BIT;
1281 if (p == fm->dv) {
1282 fm->dv = 0;
1283 fm->dvsize = 0;
1284 }
1285 if (tsize > fm->trim_check)
1286 alloc_trim(fm, 0);
1287 return NULL;
1288 } else if (next == fm->dv) {
1289 size_t dsize = fm->dvsize += psize;
1290 fm->dv = p;
1291 set_size_and_pinuse_of_free_chunk(p, dsize);
1292 return NULL;
1293 } else {
1294 size_t nsize = chunksize(next);
1295 psize += nsize;
1296 unlink_chunk(fm, next, nsize);
1297 set_size_and_pinuse_of_free_chunk(p, psize);
1298 if (p == fm->dv) {
1299 fm->dvsize = psize;
1300 return NULL;
1301 }
1302 }
1303 } else {
1304 set_free_with_pinuse(p, psize, next);
1305 }
1306
1307 if (is_small(psize)) {
1308 insert_small_chunk(fm, p, psize);
1309 } else {
1310 tchunkptr tp = (tchunkptr)p;
1311 insert_large_chunk(fm, tp, psize);
1312 if (--fm->release_checks == 0)
1313 release_unused_segments(fm);
1314 }
1315 }
1316 return NULL;
1317}
1318
1319static LJ_NOINLINE void *lj_alloc_realloc(void *msp, void *ptr, size_t nsize)
1320{
1321 if (nsize >= MAX_REQUEST) {
1322 return NULL;
1323 } else {
1324 mstate m = (mstate)msp;
1325 mchunkptr oldp = mem2chunk(ptr);
1326 size_t oldsize = chunksize(oldp);
1327 mchunkptr next = chunk_plus_offset(oldp, oldsize);
1328 mchunkptr newp = 0;
1329 size_t nb = request2size(nsize);
1330
1331 /* Try to either shrink or extend into top. Else malloc-copy-free */
1332 if (is_direct(oldp)) {
1333 newp = direct_resize(oldp, nb); /* this may return NULL. */
1334 } else if (oldsize >= nb) { /* already big enough */
1335 size_t rsize = oldsize - nb;
1336 newp = oldp;
1337 if (rsize >= MIN_CHUNK_SIZE) {
1338 mchunkptr rem = chunk_plus_offset(newp, nb);
1339 set_inuse(m, newp, nb);
1340 set_inuse(m, rem, rsize);
1341 lj_alloc_free(m, chunk2mem(rem));
1342 }
1343 } else if (next == m->top && oldsize + m->topsize > nb) {
1344 /* Expand into top */
1345 size_t newsize = oldsize + m->topsize;
1346 size_t newtopsize = newsize - nb;
1347 mchunkptr newtop = chunk_plus_offset(oldp, nb);
1348 set_inuse(m, oldp, nb);
1349 newtop->head = newtopsize |PINUSE_BIT;
1350 m->top = newtop;
1351 m->topsize = newtopsize;
1352 newp = oldp;
1353 }
1354
1355 if (newp != 0) {
1356 return chunk2mem(newp);
1357 } else {
1358 void *newmem = lj_alloc_malloc(m, nsize);
1359 if (newmem != 0) {
1360 size_t oc = oldsize - overhead_for(oldp);
1361 memcpy(newmem, ptr, oc < nsize ? oc : nsize);
1362 lj_alloc_free(m, ptr);
1363 }
1364 return newmem;
1365 }
1366 }
1367}
1368
1369void *lj_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize)
1370{
1371 (void)osize;
1372 if (nsize == 0) {
1373 return lj_alloc_free(msp, ptr);
1374 } else if (ptr == NULL) {
1375 return lj_alloc_malloc(msp, nsize);
1376 } else {
1377 return lj_alloc_realloc(msp, ptr, nsize);
1378 }
1379}
1380
1381#endif
diff --git a/libraries/luajit-2.0/src/lj_alloc.h b/libraries/luajit-2.0/src/lj_alloc.h
new file mode 100644
index 0000000..f87a7cf
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_alloc.h
@@ -0,0 +1,17 @@
1/*
2** Bundled memory allocator.
3** Donated to the public domain.
4*/
5
6#ifndef _LJ_ALLOC_H
7#define _LJ_ALLOC_H
8
9#include "lj_def.h"
10
11#ifndef LUAJIT_USE_SYSMALLOC
12LJ_FUNC void *lj_alloc_create(void);
13LJ_FUNC void lj_alloc_destroy(void *msp);
14LJ_FUNC void *lj_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize);
15#endif
16
17#endif
diff --git a/libraries/luajit-2.0/src/lj_api.c b/libraries/luajit-2.0/src/lj_api.c
new file mode 100644
index 0000000..5ef2dff
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_api.c
@@ -0,0 +1,1220 @@
1/*
2** Public Lua/C API.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lj_api_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_debug.h"
16#include "lj_str.h"
17#include "lj_tab.h"
18#include "lj_func.h"
19#include "lj_udata.h"
20#include "lj_meta.h"
21#include "lj_state.h"
22#include "lj_bc.h"
23#include "lj_frame.h"
24#include "lj_trace.h"
25#include "lj_vm.h"
26#include "lj_lex.h"
27#include "lj_bcdump.h"
28#include "lj_parse.h"
29
30/* -- Common helper functions --------------------------------------------- */
31
32#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
33#define api_checkvalidindex(L, i) api_check(L, (i) != niltv(L))
34
35static TValue *index2adr(lua_State *L, int idx)
36{
37 if (idx > 0) {
38 TValue *o = L->base + (idx - 1);
39 return o < L->top ? o : niltv(L);
40 } else if (idx > LUA_REGISTRYINDEX) {
41 api_check(L, idx != 0 && -idx <= L->top - L->base);
42 return L->top + idx;
43 } else if (idx == LUA_GLOBALSINDEX) {
44 TValue *o = &G(L)->tmptv;
45 settabV(L, o, tabref(L->env));
46 return o;
47 } else if (idx == LUA_REGISTRYINDEX) {
48 return registry(L);
49 } else {
50 GCfunc *fn = curr_func(L);
51 api_check(L, fn->c.gct == ~LJ_TFUNC && !isluafunc(fn));
52 if (idx == LUA_ENVIRONINDEX) {
53 TValue *o = &G(L)->tmptv;
54 settabV(L, o, tabref(fn->c.env));
55 return o;
56 } else {
57 idx = LUA_GLOBALSINDEX - idx;
58 return idx <= fn->c.nupvalues ? &fn->c.upvalue[idx-1] : niltv(L);
59 }
60 }
61}
62
63static TValue *stkindex2adr(lua_State *L, int idx)
64{
65 if (idx > 0) {
66 TValue *o = L->base + (idx - 1);
67 return o < L->top ? o : niltv(L);
68 } else {
69 api_check(L, idx != 0 && -idx <= L->top - L->base);
70 return L->top + idx;
71 }
72}
73
74static GCtab *getcurrenv(lua_State *L)
75{
76 GCfunc *fn = curr_func(L);
77 return fn->c.gct == ~LJ_TFUNC ? tabref(fn->c.env) : tabref(L->env);
78}
79
80/* -- Miscellaneous API functions ----------------------------------------- */
81
82LUA_API int lua_status(lua_State *L)
83{
84 return L->status;
85}
86
87LUA_API int lua_checkstack(lua_State *L, int size)
88{
89 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) {
90 return 0; /* Stack overflow. */
91 } else if (size > 0) {
92 lj_state_checkstack(L, (MSize)size);
93 }
94 return 1;
95}
96
97LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
98{
99 if (!lua_checkstack(L, size))
100 lj_err_callerv(L, LJ_ERR_STKOVM, msg);
101}
102
103LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
104{
105 TValue *f, *t;
106 if (from == to) return;
107 api_checknelems(from, n);
108 api_check(from, G(from) == G(to));
109 lj_state_checkstack(to, (MSize)n);
110 f = from->top;
111 t = to->top = to->top + n;
112 while (--n >= 0) copyTV(to, --t, --f);
113 from->top = f;
114}
115
116/* -- Stack manipulation -------------------------------------------------- */
117
118LUA_API int lua_gettop(lua_State *L)
119{
120 return (int)(L->top - L->base);
121}
122
123LUA_API void lua_settop(lua_State *L, int idx)
124{
125 if (idx >= 0) {
126 api_check(L, idx <= tvref(L->maxstack) - L->base);
127 if (L->base + idx > L->top) {
128 if (L->base + idx >= tvref(L->maxstack))
129 lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
130 do { setnilV(L->top++); } while (L->top < L->base + idx);
131 } else {
132 L->top = L->base + idx;
133 }
134 } else {
135 api_check(L, -(idx+1) <= (L->top - L->base));
136 L->top += idx+1; /* Shrinks top (idx < 0). */
137 }
138}
139
140LUA_API void lua_remove(lua_State *L, int idx)
141{
142 TValue *p = stkindex2adr(L, idx);
143 api_checkvalidindex(L, p);
144 while (++p < L->top) copyTV(L, p-1, p);
145 L->top--;
146}
147
148LUA_API void lua_insert(lua_State *L, int idx)
149{
150 TValue *q, *p = stkindex2adr(L, idx);
151 api_checkvalidindex(L, p);
152 for (q = L->top; q > p; q--) copyTV(L, q, q-1);
153 copyTV(L, p, L->top);
154}
155
156LUA_API void lua_replace(lua_State *L, int idx)
157{
158 api_checknelems(L, 1);
159 if (idx == LUA_GLOBALSINDEX) {
160 api_check(L, tvistab(L->top-1));
161 /* NOBARRIER: A thread (i.e. L) is never black. */
162 setgcref(L->env, obj2gco(tabV(L->top-1)));
163 } else if (idx == LUA_ENVIRONINDEX) {
164 GCfunc *fn = curr_func(L);
165 if (fn->c.gct != ~LJ_TFUNC)
166 lj_err_msg(L, LJ_ERR_NOENV);
167 api_check(L, tvistab(L->top-1));
168 setgcref(fn->c.env, obj2gco(tabV(L->top-1)));
169 lj_gc_barrier(L, fn, L->top-1);
170 } else {
171 TValue *o = index2adr(L, idx);
172 api_checkvalidindex(L, o);
173 copyTV(L, o, L->top-1);
174 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
175 lj_gc_barrier(L, curr_func(L), L->top-1);
176 }
177 L->top--;
178}
179
180LUA_API void lua_pushvalue(lua_State *L, int idx)
181{
182 copyTV(L, L->top, index2adr(L, idx));
183 incr_top(L);
184}
185
186/* -- Stack getters ------------------------------------------------------- */
187
188LUA_API int lua_type(lua_State *L, int idx)
189{
190 cTValue *o = index2adr(L, idx);
191 if (tvisnumber(o)) {
192 return LUA_TNUMBER;
193#if LJ_64
194 } else if (tvislightud(o)) {
195 return LUA_TLIGHTUSERDATA;
196#endif
197 } else if (o == niltv(L)) {
198 return LUA_TNONE;
199 } else { /* Magic internal/external tag conversion. ORDER LJ_T */
200 uint32_t t = ~itype(o);
201#if LJ_64
202 int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u);
203#else
204 int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
205#endif
206 lua_assert(tt != LUA_TNIL || tvisnil(o));
207 return tt;
208 }
209}
210
211LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
212{
213 if (lua_type(L, idx) != tt)
214 lj_err_argt(L, idx, tt);
215}
216
217LUALIB_API void luaL_checkany(lua_State *L, int idx)
218{
219 if (index2adr(L, idx) == niltv(L))
220 lj_err_arg(L, idx, LJ_ERR_NOVAL);
221}
222
223LUA_API const char *lua_typename(lua_State *L, int t)
224{
225 UNUSED(L);
226 return lj_obj_typename[t+1];
227}
228
229LUA_API int lua_iscfunction(lua_State *L, int idx)
230{
231 cTValue *o = index2adr(L, idx);
232 return tvisfunc(o) && !isluafunc(funcV(o));
233}
234
235LUA_API int lua_isnumber(lua_State *L, int idx)
236{
237 cTValue *o = index2adr(L, idx);
238 TValue tmp;
239 return (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), &tmp)));
240}
241
242LUA_API int lua_isstring(lua_State *L, int idx)
243{
244 cTValue *o = index2adr(L, idx);
245 return (tvisstr(o) || tvisnumber(o));
246}
247
248LUA_API int lua_isuserdata(lua_State *L, int idx)
249{
250 cTValue *o = index2adr(L, idx);
251 return (tvisudata(o) || tvislightud(o));
252}
253
254LUA_API int lua_rawequal(lua_State *L, int idx1, int idx2)
255{
256 cTValue *o1 = index2adr(L, idx1);
257 cTValue *o2 = index2adr(L, idx2);
258 return (o1 == niltv(L) || o2 == niltv(L)) ? 0 : lj_obj_equal(o1, o2);
259}
260
261LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
262{
263 cTValue *o1 = index2adr(L, idx1);
264 cTValue *o2 = index2adr(L, idx2);
265 if (tvisint(o1) && tvisint(o2)) {
266 return intV(o1) == intV(o2);
267 } else if (tvisnumber(o1) && tvisnumber(o2)) {
268 return numberVnum(o1) == numberVnum(o2);
269 } else if (itype(o1) != itype(o2)) {
270 return 0;
271 } else if (tvispri(o1)) {
272 return o1 != niltv(L) && o2 != niltv(L);
273#if LJ_64
274 } else if (tvislightud(o1)) {
275 return o1->u64 == o2->u64;
276#endif
277 } else if (gcrefeq(o1->gcr, o2->gcr)) {
278 return 1;
279 } else if (!tvistabud(o1)) {
280 return 0;
281 } else {
282 TValue *base = lj_meta_equal(L, gcV(o1), gcV(o2), 0);
283 if ((uintptr_t)base <= 1) {
284 return (int)(uintptr_t)base;
285 } else {
286 L->top = base+2;
287 lj_vm_call(L, base, 1+1);
288 L->top -= 2;
289 return tvistruecond(L->top+1);
290 }
291 }
292}
293
294LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
295{
296 cTValue *o1 = index2adr(L, idx1);
297 cTValue *o2 = index2adr(L, idx2);
298 if (o1 == niltv(L) || o2 == niltv(L)) {
299 return 0;
300 } else if (tvisint(o1) && tvisint(o2)) {
301 return intV(o1) < intV(o2);
302 } else if (tvisnumber(o1) && tvisnumber(o2)) {
303 return numberVnum(o1) < numberVnum(o2);
304 } else {
305 TValue *base = lj_meta_comp(L, o1, o2, 0);
306 if ((uintptr_t)base <= 1) {
307 return (int)(uintptr_t)base;
308 } else {
309 L->top = base+2;
310 lj_vm_call(L, base, 1+1);
311 L->top -= 2;
312 return tvistruecond(L->top+1);
313 }
314 }
315}
316
317LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
318{
319 cTValue *o = index2adr(L, idx);
320 TValue tmp;
321 if (LJ_LIKELY(tvisnumber(o)))
322 return numberVnum(o);
323 else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp))
324 return numV(&tmp);
325 else
326 return 0;
327}
328
329LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
330{
331 cTValue *o = index2adr(L, idx);
332 TValue tmp;
333 if (LJ_LIKELY(tvisnumber(o)))
334 return numberVnum(o);
335 else if (!(tvisstr(o) && lj_str_tonum(strV(o), &tmp)))
336 lj_err_argt(L, idx, LUA_TNUMBER);
337 return numV(&tmp);
338}
339
340LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
341{
342 cTValue *o = index2adr(L, idx);
343 TValue tmp;
344 if (LJ_LIKELY(tvisnumber(o)))
345 return numberVnum(o);
346 else if (tvisnil(o))
347 return def;
348 else if (!(tvisstr(o) && lj_str_tonum(strV(o), &tmp)))
349 lj_err_argt(L, idx, LUA_TNUMBER);
350 return numV(&tmp);
351}
352
353LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
354{
355 cTValue *o = index2adr(L, idx);
356 TValue tmp;
357 lua_Number n;
358 if (LJ_LIKELY(tvisint(o))) {
359 return intV(o);
360 } else if (LJ_LIKELY(tvisnum(o))) {
361 n = numV(o);
362 } else {
363 if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp)))
364 return 0;
365 if (tvisint(&tmp))
366 return (lua_Integer)intV(&tmp);
367 n = numV(&tmp);
368 }
369#if LJ_64
370 return (lua_Integer)n;
371#else
372 return lj_num2int(n);
373#endif
374}
375
376LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
377{
378 cTValue *o = index2adr(L, idx);
379 TValue tmp;
380 lua_Number n;
381 if (LJ_LIKELY(tvisint(o))) {
382 return intV(o);
383 } else if (LJ_LIKELY(tvisnum(o))) {
384 n = numV(o);
385 } else {
386 if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp)))
387 lj_err_argt(L, idx, LUA_TNUMBER);
388 if (tvisint(&tmp))
389 return (lua_Integer)intV(&tmp);
390 n = numV(&tmp);
391 }
392#if LJ_64
393 return (lua_Integer)n;
394#else
395 return lj_num2int(n);
396#endif
397}
398
399LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
400{
401 cTValue *o = index2adr(L, idx);
402 TValue tmp;
403 lua_Number n;
404 if (LJ_LIKELY(tvisint(o))) {
405 return intV(o);
406 } else if (LJ_LIKELY(tvisnum(o))) {
407 n = numV(o);
408 } else if (tvisnil(o)) {
409 return def;
410 } else {
411 if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp)))
412 lj_err_argt(L, idx, LUA_TNUMBER);
413 if (tvisint(&tmp))
414 return (lua_Integer)intV(&tmp);
415 n = numV(&tmp);
416 }
417#if LJ_64
418 return (lua_Integer)n;
419#else
420 return lj_num2int(n);
421#endif
422}
423
424LUA_API int lua_toboolean(lua_State *L, int idx)
425{
426 cTValue *o = index2adr(L, idx);
427 return tvistruecond(o);
428}
429
430LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
431{
432 TValue *o = index2adr(L, idx);
433 GCstr *s;
434 if (LJ_LIKELY(tvisstr(o))) {
435 s = strV(o);
436 } else if (tvisnumber(o)) {
437 lj_gc_check(L);
438 o = index2adr(L, idx); /* GC may move the stack. */
439 s = lj_str_fromnumber(L, o);
440 setstrV(L, o, s);
441 } else {
442 if (len != NULL) *len = 0;
443 return NULL;
444 }
445 if (len != NULL) *len = s->len;
446 return strdata(s);
447}
448
449LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
450{
451 TValue *o = index2adr(L, idx);
452 GCstr *s;
453 if (LJ_LIKELY(tvisstr(o))) {
454 s = strV(o);
455 } else if (tvisnumber(o)) {
456 lj_gc_check(L);
457 o = index2adr(L, idx); /* GC may move the stack. */
458 s = lj_str_fromnumber(L, o);
459 setstrV(L, o, s);
460 } else {
461 lj_err_argt(L, idx, LUA_TSTRING);
462 }
463 if (len != NULL) *len = s->len;
464 return strdata(s);
465}
466
467LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
468 const char *def, size_t *len)
469{
470 TValue *o = index2adr(L, idx);
471 GCstr *s;
472 if (LJ_LIKELY(tvisstr(o))) {
473 s = strV(o);
474 } else if (tvisnil(o)) {
475 if (len != NULL) *len = def ? strlen(def) : 0;
476 return def;
477 } else if (tvisnumber(o)) {
478 lj_gc_check(L);
479 o = index2adr(L, idx); /* GC may move the stack. */
480 s = lj_str_fromnumber(L, o);
481 setstrV(L, o, s);
482 } else {
483 lj_err_argt(L, idx, LUA_TSTRING);
484 }
485 if (len != NULL) *len = s->len;
486 return strdata(s);
487}
488
489LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
490 const char *const lst[])
491{
492 ptrdiff_t i;
493 const char *s = lua_tolstring(L, idx, NULL);
494 if (s == NULL && (s = def) == NULL)
495 lj_err_argt(L, idx, LUA_TSTRING);
496 for (i = 0; lst[i]; i++)
497 if (strcmp(lst[i], s) == 0)
498 return (int)i;
499 lj_err_argv(L, idx, LJ_ERR_INVOPTM, s);
500}
501
502LUA_API size_t lua_objlen(lua_State *L, int idx)
503{
504 TValue *o = index2adr(L, idx);
505 if (tvisstr(o)) {
506 return strV(o)->len;
507 } else if (tvistab(o)) {
508 return (size_t)lj_tab_len(tabV(o));
509 } else if (tvisudata(o)) {
510 return udataV(o)->len;
511 } else if (tvisnumber(o)) {
512 GCstr *s = lj_str_fromnumber(L, o);
513 setstrV(L, o, s);
514 return s->len;
515 } else {
516 return 0;
517 }
518}
519
520LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
521{
522 cTValue *o = index2adr(L, idx);
523 if (tvisfunc(o)) {
524 BCOp op = bc_op(*mref(funcV(o)->c.pc, BCIns));
525 if (op == BC_FUNCC || op == BC_FUNCCW)
526 return funcV(o)->c.f;
527 }
528 return NULL;
529}
530
531LUA_API void *lua_touserdata(lua_State *L, int idx)
532{
533 cTValue *o = index2adr(L, idx);
534 if (tvisudata(o))
535 return uddata(udataV(o));
536 else if (tvislightud(o))
537 return lightudV(o);
538 else
539 return NULL;
540}
541
542LUA_API lua_State *lua_tothread(lua_State *L, int idx)
543{
544 cTValue *o = index2adr(L, idx);
545 return (!tvisthread(o)) ? NULL : threadV(o);
546}
547
548LUA_API const void *lua_topointer(lua_State *L, int idx)
549{
550 cTValue *o = index2adr(L, idx);
551 if (tvisudata(o))
552 return uddata(udataV(o));
553 else if (tvislightud(o))
554 return lightudV(o);
555 else if (tviscdata(o))
556 return cdataptr(cdataV(o));
557 else if (tvisgcv(o))
558 return gcV(o);
559 else
560 return NULL;
561}
562
563/* -- Stack setters (object creation) ------------------------------------- */
564
565LUA_API void lua_pushnil(lua_State *L)
566{
567 setnilV(L->top);
568 incr_top(L);
569}
570
571LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
572{
573 setnumV(L->top, n);
574 if (LJ_UNLIKELY(tvisnan(L->top)))
575 setnanV(L->top); /* Canonicalize injected NaNs. */
576 incr_top(L);
577}
578
579LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
580{
581 setintptrV(L->top, n);
582 incr_top(L);
583}
584
585LUA_API void lua_pushlstring(lua_State *L, const char *str, size_t len)
586{
587 GCstr *s;
588 lj_gc_check(L);
589 s = lj_str_new(L, str, len);
590 setstrV(L, L->top, s);
591 incr_top(L);
592}
593
594LUA_API void lua_pushstring(lua_State *L, const char *str)
595{
596 if (str == NULL) {
597 setnilV(L->top);
598 } else {
599 GCstr *s;
600 lj_gc_check(L);
601 s = lj_str_newz(L, str);
602 setstrV(L, L->top, s);
603 }
604 incr_top(L);
605}
606
607LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
608 va_list argp)
609{
610 lj_gc_check(L);
611 return lj_str_pushvf(L, fmt, argp);
612}
613
614LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
615{
616 const char *ret;
617 va_list argp;
618 lj_gc_check(L);
619 va_start(argp, fmt);
620 ret = lj_str_pushvf(L, fmt, argp);
621 va_end(argp);
622 return ret;
623}
624
625LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
626{
627 GCfunc *fn;
628 lj_gc_check(L);
629 api_checknelems(L, n);
630 fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
631 fn->c.f = f;
632 L->top -= n;
633 while (n--)
634 copyTV(L, &fn->c.upvalue[n], L->top+n);
635 setfuncV(L, L->top, fn);
636 lua_assert(iswhite(obj2gco(fn)));
637 incr_top(L);
638}
639
640LUA_API void lua_pushboolean(lua_State *L, int b)
641{
642 setboolV(L->top, (b != 0));
643 incr_top(L);
644}
645
646LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
647{
648 setlightudV(L->top, checklightudptr(L, p));
649 incr_top(L);
650}
651
652LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
653{
654 GCtab *t;
655 lj_gc_check(L);
656 t = lj_tab_new(L, (uint32_t)(narray > 0 ? narray+1 : 0), hsize2hbits(nrec));
657 settabV(L, L->top, t);
658 incr_top(L);
659}
660
661LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
662{
663 GCtab *regt = tabV(registry(L));
664 TValue *tv = lj_tab_setstr(L, regt, lj_str_newz(L, tname));
665 if (tvisnil(tv)) {
666 GCtab *mt = lj_tab_new(L, 0, 1);
667 settabV(L, tv, mt);
668 settabV(L, L->top++, mt);
669 lj_gc_anybarriert(L, regt);
670 return 1;
671 } else {
672 copyTV(L, L->top++, tv);
673 return 0;
674 }
675}
676
677LUA_API int lua_pushthread(lua_State *L)
678{
679 setthreadV(L, L->top, L);
680 incr_top(L);
681 return (mainthread(G(L)) == L);
682}
683
684LUA_API lua_State *lua_newthread(lua_State *L)
685{
686 lua_State *L1;
687 lj_gc_check(L);
688 L1 = lj_state_new(L);
689 setthreadV(L, L->top, L1);
690 incr_top(L);
691 return L1;
692}
693
694LUA_API void *lua_newuserdata(lua_State *L, size_t size)
695{
696 GCudata *ud;
697 lj_gc_check(L);
698 if (size > LJ_MAX_UDATA)
699 lj_err_msg(L, LJ_ERR_UDATAOV);
700 ud = lj_udata_new(L, (MSize)size, getcurrenv(L));
701 setudataV(L, L->top, ud);
702 incr_top(L);
703 return uddata(ud);
704}
705
706LUA_API void lua_concat(lua_State *L, int n)
707{
708 api_checknelems(L, n);
709 if (n >= 2) {
710 n--;
711 do {
712 TValue *top = lj_meta_cat(L, L->top-1, n);
713 if (top == NULL) {
714 L->top -= n;
715 break;
716 }
717 n -= (int)(L->top - top);
718 L->top = top+2;
719 lj_vm_call(L, top, 1+1);
720 L->top--;
721 copyTV(L, L->top-1, L->top);
722 } while (--n > 0);
723 } else if (n == 0) { /* Push empty string. */
724 setstrV(L, L->top, &G(L)->strempty);
725 incr_top(L);
726 }
727 /* else n == 1: nothing to do. */
728}
729
730/* -- Object getters ------------------------------------------------------ */
731
732LUA_API void lua_gettable(lua_State *L, int idx)
733{
734 cTValue *v, *t = index2adr(L, idx);
735 api_checkvalidindex(L, t);
736 v = lj_meta_tget(L, t, L->top-1);
737 if (v == NULL) {
738 L->top += 2;
739 lj_vm_call(L, L->top-2, 1+1);
740 L->top -= 2;
741 v = L->top+1;
742 }
743 copyTV(L, L->top-1, v);
744}
745
746LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
747{
748 cTValue *v, *t = index2adr(L, idx);
749 TValue key;
750 api_checkvalidindex(L, t);
751 setstrV(L, &key, lj_str_newz(L, k));
752 v = lj_meta_tget(L, t, &key);
753 if (v == NULL) {
754 L->top += 2;
755 lj_vm_call(L, L->top-2, 1+1);
756 L->top -= 2;
757 v = L->top+1;
758 }
759 copyTV(L, L->top, v);
760 incr_top(L);
761}
762
763LUA_API void lua_rawget(lua_State *L, int idx)
764{
765 cTValue *t = index2adr(L, idx);
766 api_check(L, tvistab(t));
767 copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
768}
769
770LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
771{
772 cTValue *v, *t = index2adr(L, idx);
773 api_check(L, tvistab(t));
774 v = lj_tab_getint(tabV(t), n);
775 if (v) {
776 copyTV(L, L->top, v);
777 } else {
778 setnilV(L->top);
779 }
780 incr_top(L);
781}
782
783LUA_API int lua_getmetatable(lua_State *L, int idx)
784{
785 cTValue *o = index2adr(L, idx);
786 GCtab *mt = NULL;
787 if (tvistab(o))
788 mt = tabref(tabV(o)->metatable);
789 else if (tvisudata(o))
790 mt = tabref(udataV(o)->metatable);
791 else
792 mt = tabref(basemt_obj(G(L), o));
793 if (mt == NULL)
794 return 0;
795 settabV(L, L->top, mt);
796 incr_top(L);
797 return 1;
798}
799
800LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
801{
802 if (lua_getmetatable(L, idx)) {
803 cTValue *tv = lj_tab_getstr(tabV(L->top-1), lj_str_newz(L, field));
804 if (tv && !tvisnil(tv)) {
805 copyTV(L, L->top-1, tv);
806 return 1;
807 }
808 L->top--;
809 }
810 return 0;
811}
812
813LUA_API void lua_getfenv(lua_State *L, int idx)
814{
815 cTValue *o = index2adr(L, idx);
816 api_checkvalidindex(L, o);
817 if (tvisfunc(o)) {
818 settabV(L, L->top, tabref(funcV(o)->c.env));
819 } else if (tvisudata(o)) {
820 settabV(L, L->top, tabref(udataV(o)->env));
821 } else if (tvisthread(o)) {
822 settabV(L, L->top, tabref(threadV(o)->env));
823 } else {
824 setnilV(L->top);
825 }
826 incr_top(L);
827}
828
829LUA_API int lua_next(lua_State *L, int idx)
830{
831 cTValue *t = index2adr(L, idx);
832 int more;
833 api_check(L, tvistab(t));
834 more = lj_tab_next(L, tabV(t), L->top-1);
835 if (more) {
836 incr_top(L); /* Return new key and value slot. */
837 } else { /* End of traversal. */
838 L->top--; /* Remove key slot. */
839 }
840 return more;
841}
842
843LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
844{
845 TValue *val;
846 const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val);
847 if (name) {
848 copyTV(L, L->top, val);
849 incr_top(L);
850 }
851 return name;
852}
853
854LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
855{
856 cTValue *o = index2adr(L, idx);
857 if (tvisudata(o)) {
858 GCudata *ud = udataV(o);
859 cTValue *tv = lj_tab_getstr(tabV(registry(L)), lj_str_newz(L, tname));
860 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
861 return uddata(ud);
862 }
863 lj_err_argtype(L, idx, tname);
864 return NULL; /* unreachable */
865}
866
867/* -- Object setters ------------------------------------------------------ */
868
869LUA_API void lua_settable(lua_State *L, int idx)
870{
871 TValue *o;
872 cTValue *t = index2adr(L, idx);
873 api_checknelems(L, 2);
874 api_checkvalidindex(L, t);
875 o = lj_meta_tset(L, t, L->top-2);
876 if (o) {
877 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
878 copyTV(L, o, L->top-1);
879 L->top -= 2;
880 } else {
881 L->top += 3;
882 copyTV(L, L->top-1, L->top-6);
883 lj_vm_call(L, L->top-3, 0+1);
884 L->top -= 3;
885 }
886}
887
888LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
889{
890 TValue *o;
891 TValue key;
892 cTValue *t = index2adr(L, idx);
893 api_checknelems(L, 1);
894 api_checkvalidindex(L, t);
895 setstrV(L, &key, lj_str_newz(L, k));
896 o = lj_meta_tset(L, t, &key);
897 if (o) {
898 L->top--;
899 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
900 copyTV(L, o, L->top);
901 } else {
902 L->top += 3;
903 copyTV(L, L->top-1, L->top-6);
904 lj_vm_call(L, L->top-3, 0+1);
905 L->top -= 2;
906 }
907}
908
909LUA_API void lua_rawset(lua_State *L, int idx)
910{
911 GCtab *t = tabV(index2adr(L, idx));
912 TValue *dst, *key;
913 api_checknelems(L, 2);
914 key = L->top-2;
915 dst = lj_tab_set(L, t, key);
916 copyTV(L, dst, key+1);
917 lj_gc_anybarriert(L, t);
918 L->top = key;
919}
920
921LUA_API void lua_rawseti(lua_State *L, int idx, int n)
922{
923 GCtab *t = tabV(index2adr(L, idx));
924 TValue *dst, *src;
925 api_checknelems(L, 1);
926 dst = lj_tab_setint(L, t, n);
927 src = L->top-1;
928 copyTV(L, dst, src);
929 lj_gc_barriert(L, t, dst);
930 L->top = src;
931}
932
933LUA_API int lua_setmetatable(lua_State *L, int idx)
934{
935 global_State *g;
936 GCtab *mt;
937 cTValue *o = index2adr(L, idx);
938 api_checknelems(L, 1);
939 api_checkvalidindex(L, o);
940 if (tvisnil(L->top-1)) {
941 mt = NULL;
942 } else {
943 api_check(L, tvistab(L->top-1));
944 mt = tabV(L->top-1);
945 }
946 g = G(L);
947 if (tvistab(o)) {
948 setgcref(tabV(o)->metatable, obj2gco(mt));
949 if (mt)
950 lj_gc_objbarriert(L, tabV(o), mt);
951 } else if (tvisudata(o)) {
952 setgcref(udataV(o)->metatable, obj2gco(mt));
953 if (mt)
954 lj_gc_objbarrier(L, udataV(o), mt);
955 } else {
956 /* Flush cache, since traces specialize to basemt. But not during __gc. */
957 if (lj_trace_flushall(L))
958 lj_err_caller(L, LJ_ERR_NOGCMM);
959 if (tvisbool(o)) {
960 /* NOBARRIER: basemt is a GC root. */
961 setgcref(basemt_it(g, LJ_TTRUE), obj2gco(mt));
962 setgcref(basemt_it(g, LJ_TFALSE), obj2gco(mt));
963 } else {
964 /* NOBARRIER: basemt is a GC root. */
965 setgcref(basemt_obj(g, o), obj2gco(mt));
966 }
967 }
968 L->top--;
969 return 1;
970}
971
972LUA_API int lua_setfenv(lua_State *L, int idx)
973{
974 cTValue *o = index2adr(L, idx);
975 GCtab *t;
976 api_checknelems(L, 1);
977 api_checkvalidindex(L, o);
978 api_check(L, tvistab(L->top-1));
979 t = tabV(L->top-1);
980 if (tvisfunc(o)) {
981 setgcref(funcV(o)->c.env, obj2gco(t));
982 } else if (tvisudata(o)) {
983 setgcref(udataV(o)->env, obj2gco(t));
984 } else if (tvisthread(o)) {
985 setgcref(threadV(o)->env, obj2gco(t));
986 } else {
987 L->top--;
988 return 0;
989 }
990 lj_gc_objbarrier(L, gcV(o), t);
991 L->top--;
992 return 1;
993}
994
995LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
996{
997 cTValue *f = index2adr(L, idx);
998 TValue *val;
999 const char *name;
1000 api_checknelems(L, 1);
1001 name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val);
1002 if (name) {
1003 L->top--;
1004 copyTV(L, val, L->top);
1005 lj_gc_barrier(L, funcV(f), L->top);
1006 }
1007 return name;
1008}
1009
1010/* -- Calls --------------------------------------------------------------- */
1011
1012LUA_API void lua_call(lua_State *L, int nargs, int nresults)
1013{
1014 api_check(L, L->status == 0 || L->status == LUA_ERRERR);
1015 api_checknelems(L, nargs+1);
1016 lj_vm_call(L, L->top - nargs, nresults+1);
1017}
1018
1019LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1020{
1021 global_State *g = G(L);
1022 uint8_t oldh = hook_save(g);
1023 ptrdiff_t ef;
1024 int status;
1025 api_check(L, L->status == 0 || L->status == LUA_ERRERR);
1026 api_checknelems(L, nargs+1);
1027 if (errfunc == 0) {
1028 ef = 0;
1029 } else {
1030 cTValue *o = stkindex2adr(L, errfunc);
1031 api_checkvalidindex(L, o);
1032 ef = savestack(L, o);
1033 }
1034 status = lj_vm_pcall(L, L->top - nargs, nresults+1, ef);
1035 if (status) hook_restore(g, oldh);
1036 return status;
1037}
1038
1039static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
1040{
1041 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
1042 fn->c.f = func;
1043 setfuncV(L, L->top, fn);
1044 setlightudV(L->top+1, checklightudptr(L, ud));
1045 cframe_nres(L->cframe) = 1+0; /* Zero results. */
1046 L->top += 2;
1047 return L->top-1; /* Now call the newly allocated C function. */
1048}
1049
1050LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1051{
1052 global_State *g = G(L);
1053 uint8_t oldh = hook_save(g);
1054 int status;
1055 api_check(L, L->status == 0 || L->status == LUA_ERRERR);
1056 status = lj_vm_cpcall(L, func, ud, cpcall);
1057 if (status) hook_restore(g, oldh);
1058 return status;
1059}
1060
1061LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1062{
1063 if (luaL_getmetafield(L, idx, field)) {
1064 TValue *base = L->top--;
1065 copyTV(L, base, index2adr(L, idx));
1066 L->top = base+1;
1067 lj_vm_call(L, base, 1+1);
1068 return 1;
1069 }
1070 return 0;
1071}
1072
1073/* -- Coroutine yield and resume ------------------------------------------ */
1074
1075LUA_API int lua_yield(lua_State *L, int nresults)
1076{
1077 void *cf = L->cframe;
1078 global_State *g = G(L);
1079 if (cframe_canyield(cf)) {
1080 cf = cframe_raw(cf);
1081 if (!hook_active(g)) { /* Regular yield: move results down if needed. */
1082 cTValue *f = L->top - nresults;
1083 if (f > L->base) {
1084 TValue *t = L->base;
1085 while (--nresults >= 0) copyTV(L, t++, f++);
1086 L->top = t;
1087 }
1088 } else { /* Yield from hook: add a pseudo-frame. */
1089 TValue *top = L->top;
1090 hook_leave(g);
1091 top->u64 = cframe_multres(cf);
1092 setcont(top+1, lj_cont_hook);
1093 setframe_pc(top+1, cframe_pc(cf)-1);
1094 setframe_gc(top+2, obj2gco(L));
1095 setframe_ftsz(top+2, (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT);
1096 L->top = L->base = top+3;
1097 }
1098#if LJ_TARGET_X64
1099 lj_err_throw(L, LUA_YIELD);
1100#else
1101 L->cframe = NULL;
1102 L->status = LUA_YIELD;
1103 lj_vm_unwind_c(cf, LUA_YIELD);
1104#endif
1105 }
1106 lj_err_msg(L, LJ_ERR_CYIELD);
1107 return 0; /* unreachable */
1108}
1109
1110LUA_API int lua_resume(lua_State *L, int nargs)
1111{
1112 if (L->cframe == NULL && L->status <= LUA_YIELD)
1113 return lj_vm_resume(L, L->top - nargs, 0, 0);
1114 L->top = L->base;
1115 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
1116 incr_top(L);
1117 return LUA_ERRRUN;
1118}
1119
1120/* -- Load and dump Lua code ---------------------------------------------- */
1121
1122static TValue *cpparser(lua_State *L, lua_CFunction dummy, void *ud)
1123{
1124 LexState *ls = (LexState *)ud;
1125 GCproto *pt;
1126 GCfunc *fn;
1127 UNUSED(dummy);
1128 cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
1129 pt = lj_lex_setup(L, ls) ? lj_bcread(ls) : lj_parse(ls);
1130 fn = lj_func_newL_empty(L, pt, tabref(L->env));
1131 /* Don't combine above/below into one statement. */
1132 setfuncV(L, L->top++, fn);
1133 return NULL;
1134}
1135
1136LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data,
1137 const char *chunkname)
1138{
1139 LexState ls;
1140 int status;
1141 ls.rfunc = reader;
1142 ls.rdata = data;
1143 ls.chunkarg = chunkname ? chunkname : "?";
1144 lj_str_initbuf(&ls.sb);
1145 status = lj_vm_cpcall(L, NULL, &ls, cpparser);
1146 lj_lex_cleanup(L, &ls);
1147 lj_gc_check(L);
1148 return status;
1149}
1150
1151LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data)
1152{
1153 cTValue *o = L->top-1;
1154 api_checknelems(L, 1);
1155 if (tvisfunc(o) && isluafunc(funcV(o)))
1156 return lj_bcwrite(L, funcproto(funcV(o)), writer, data, 0);
1157 else
1158 return 1;
1159}
1160
1161/* -- GC and memory management -------------------------------------------- */
1162
1163LUA_API int lua_gc(lua_State *L, int what, int data)
1164{
1165 global_State *g = G(L);
1166 int res = 0;
1167 switch (what) {
1168 case LUA_GCSTOP:
1169 g->gc.threshold = LJ_MAX_MEM;
1170 break;
1171 case LUA_GCRESTART:
1172 g->gc.threshold = data == -1 ? (g->gc.total/100)*g->gc.pause : g->gc.total;
1173 break;
1174 case LUA_GCCOLLECT:
1175 lj_gc_fullgc(L);
1176 break;
1177 case LUA_GCCOUNT:
1178 res = (int)(g->gc.total >> 10);
1179 break;
1180 case LUA_GCCOUNTB:
1181 res = (int)(g->gc.total & 0x3ff);
1182 break;
1183 case LUA_GCSTEP: {
1184 MSize a = (MSize)data << 10;
1185 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
1186 while (g->gc.total >= g->gc.threshold)
1187 if (lj_gc_step(L)) {
1188 res = 1;
1189 break;
1190 }
1191 break;
1192 }
1193 case LUA_GCSETPAUSE:
1194 res = (int)(g->gc.pause);
1195 g->gc.pause = (MSize)data;
1196 break;
1197 case LUA_GCSETSTEPMUL:
1198 res = (int)(g->gc.stepmul);
1199 g->gc.stepmul = (MSize)data;
1200 break;
1201 default:
1202 res = -1; /* Invalid option. */
1203 }
1204 return res;
1205}
1206
1207LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
1208{
1209 global_State *g = G(L);
1210 if (ud) *ud = g->allocd;
1211 return g->allocf;
1212}
1213
1214LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
1215{
1216 global_State *g = G(L);
1217 g->allocd = ud;
1218 g->allocf = f;
1219}
1220
diff --git a/libraries/luajit-2.0/src/lj_arch.h b/libraries/luajit-2.0/src/lj_arch.h
new file mode 100644
index 0000000..3a52c21
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_arch.h
@@ -0,0 +1,324 @@
1/*
2** Target architecture selection.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_ARCH_H
7#define _LJ_ARCH_H
8
9#include "lua.h"
10
11/* Target endianess. */
12#define LUAJIT_LE 0
13#define LUAJIT_BE 1
14
15/* Target architectures. */
16#define LUAJIT_ARCH_X86 1
17#define LUAJIT_ARCH_x86 1
18#define LUAJIT_ARCH_X64 2
19#define LUAJIT_ARCH_x64 2
20#define LUAJIT_ARCH_ARM 3
21#define LUAJIT_ARCH_arm 3
22#define LUAJIT_ARCH_PPC 4
23#define LUAJIT_ARCH_ppc 4
24#define LUAJIT_ARCH_PPCSPE 5
25#define LUAJIT_ARCH_ppcspe 5
26#define LUAJIT_ARCH_MIPS 6
27#define LUAJIT_ARCH_mips 6
28
29/* Target OS. */
30#define LUAJIT_OS_OTHER 0
31#define LUAJIT_OS_WINDOWS 1
32#define LUAJIT_OS_LINUX 2
33#define LUAJIT_OS_OSX 3
34#define LUAJIT_OS_BSD 4
35#define LUAJIT_OS_POSIX 5
36
37/* Select native target if no target defined. */
38#ifndef LUAJIT_TARGET
39
40#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
41#define LUAJIT_TARGET LUAJIT_ARCH_X86
42#elif defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
43#define LUAJIT_TARGET LUAJIT_ARCH_X64
44#elif defined(__arm__) || defined(__arm) || defined(__ARM__) || defined(__ARM)
45#define LUAJIT_TARGET LUAJIT_ARCH_ARM
46#elif defined(__ppc__) || defined(__ppc) || defined(__PPC__) || defined(__PPC) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(__POWERPC) || defined(_M_PPC)
47#ifdef __NO_FPRS__
48#define LUAJIT_TARGET LUAJIT_ARCH_PPCSPE
49#else
50#define LUAJIT_TARGET LUAJIT_ARCH_PPC
51#endif
52#elif defined(__mips__) || defined(__mips) || defined(__MIPS__) || defined(__MIPS)
53#define LUAJIT_TARGET LUAJIT_ARCH_MIPS
54#else
55#error "No support for this architecture (yet)"
56#endif
57
58#endif
59
60/* Select native OS if no target OS defined. */
61#ifndef LUAJIT_OS
62
63#if defined(_WIN32)
64#define LUAJIT_OS LUAJIT_OS_WINDOWS
65#elif defined(__linux__)
66#define LUAJIT_OS LUAJIT_OS_LINUX
67#elif defined(__MACH__) && defined(__APPLE__)
68#define LUAJIT_OS LUAJIT_OS_OSX
69#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
70 defined(__NetBSD__) || defined(__OpenBSD__)
71#define LUAJIT_OS LUAJIT_OS_BSD
72#elif (defined(__sun__) && defined(__svr4__)) || defined(__solaris__) || \
73 defined(__CYGWIN__)
74#define LUAJIT_OS LUAJIT_OS_POSIX
75#else
76#define LUAJIT_OS LUAJIT_OS_OTHER
77#endif
78
79#endif
80
81/* Set target OS properties. */
82#if LUAJIT_OS == LUAJIT_OS_WINDOWS
83#define LJ_OS_NAME "Windows"
84#elif LUAJIT_OS == LUAJIT_OS_LINUX
85#define LJ_OS_NAME "Linux"
86#elif LUAJIT_OS == LUAJIT_OS_OSX
87#define LJ_OS_NAME "OSX"
88#elif LUAJIT_OS == LUAJIT_OS_BSD
89#define LJ_OS_NAME "BSD"
90#elif LUAJIT_OS == LUAJIT_OS_POSIX
91#define LJ_OS_NAME "POSIX"
92#else
93#define LJ_OS_NAME "Other"
94#endif
95
96#define LJ_TARGET_WINDOWS (LUAJIT_OS == LUAJIT_OS_WINDOWS)
97#define LJ_TARGET_LINUX (LUAJIT_OS == LUAJIT_OS_LINUX)
98#define LJ_TARGET_OSX (LUAJIT_OS == LUAJIT_OS_OSX)
99#define LJ_TARGET_POSIX (LUAJIT_OS > LUAJIT_OS_WINDOWS)
100#define LJ_TARGET_DLOPEN LJ_TARGET_POSIX
101
102#define LJ_NUMMODE_SINGLE 0 /* Single-number mode only. */
103#define LJ_NUMMODE_SINGLE_DUAL 1 /* Default to single-number mode. */
104#define LJ_NUMMODE_DUAL 2 /* Dual-number mode only. */
105#define LJ_NUMMODE_DUAL_SINGLE 3 /* Default to dual-number mode. */
106
107/* Set target architecture properties. */
108#if LUAJIT_TARGET == LUAJIT_ARCH_X86
109
110#define LJ_ARCH_NAME "x86"
111#define LJ_ARCH_BITS 32
112#define LJ_ARCH_ENDIAN LUAJIT_LE
113#define LJ_ARCH_HASFPU 1
114#define LJ_ABI_WIN LJ_TARGET_WINDOWS
115#define LJ_TARGET_X86 1
116#define LJ_TARGET_X86ORX64 1
117#define LJ_TARGET_EHRETREG 0
118#define LJ_TARGET_MASKSHIFT 1
119#define LJ_TARGET_MASKROT 1
120#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE_DUAL
121
122#elif LUAJIT_TARGET == LUAJIT_ARCH_X64
123
124#define LJ_ARCH_NAME "x64"
125#define LJ_ARCH_BITS 64
126#define LJ_ARCH_ENDIAN LUAJIT_LE
127#define LJ_ARCH_HASFPU 1
128#define LJ_ABI_WIN LJ_TARGET_WINDOWS
129#define LJ_TARGET_X64 1
130#define LJ_TARGET_X86ORX64 1
131#define LJ_TARGET_EHRETREG 0
132#define LJ_TARGET_JUMPRANGE 31 /* +-2^31 = +-2GB */
133#define LJ_TARGET_MASKSHIFT 1
134#define LJ_TARGET_MASKROT 1
135#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE_DUAL
136
137#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM
138
139#define LJ_ARCH_NAME "arm"
140#define LJ_ARCH_BITS 32
141#define LJ_ARCH_ENDIAN LUAJIT_LE
142#define LJ_ARCH_HASFPU 0
143#define LJ_ABI_SOFTFP 1
144#define LJ_ABI_EABI 1
145#define LJ_TARGET_ARM 1
146#define LJ_TARGET_EHRETREG 0
147#define LJ_TARGET_JUMPRANGE 25 /* +-2^25 = +-32MB */
148#define LJ_TARGET_MASKSHIFT 0
149#define LJ_TARGET_MASKROT 1
150#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
151#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
152#if LJ_TARGET_OSX
153/* Runtime code generation is restricted on iOS. Complain to Apple, not me. */
154#define LJ_ARCH_NOJIT 1
155#endif
156
157#elif LUAJIT_TARGET == LUAJIT_ARCH_PPC
158
159#define LJ_ARCH_NAME "ppc"
160#define LJ_ARCH_BITS 32
161#define LJ_ARCH_ENDIAN LUAJIT_BE
162#define LJ_ARCH_HASFPU 1
163#define LJ_TARGET_PPC 1
164#define LJ_TARGET_EHRETREG 3
165#define LJ_TARGET_JUMPRANGE 25 /* +-2^25 = +-32MB */
166#define LJ_TARGET_MASKSHIFT 0
167#define LJ_TARGET_MASKROT 1
168#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
169#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
170
171#elif LUAJIT_TARGET == LUAJIT_ARCH_PPCSPE
172
173#define LJ_ARCH_NAME "ppcspe"
174#define LJ_ARCH_BITS 32
175#define LJ_ARCH_ENDIAN LUAJIT_BE
176#define LJ_ARCH_HASFPU 1
177#define LJ_ABI_SOFTFP 1
178#define LJ_ABI_EABI 1
179#define LJ_TARGET_PPCSPE 1
180#define LJ_TARGET_EHRETREG 3
181#define LJ_TARGET_JUMPRANGE 25 /* +-2^25 = +-32MB */
182#define LJ_TARGET_MASKSHIFT 0
183#define LJ_TARGET_MASKROT 1
184#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
185#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE
186#define LJ_ARCH_NOFFI 1 /* NYI: comparisons, calls. */
187#define LJ_ARCH_NOJIT 1
188
189#elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS
190
191#define LJ_ARCH_NAME "mips"
192#define LJ_ARCH_BITS 32
193#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
194#define LJ_ARCH_ENDIAN LUAJIT_LE
195#else
196#define LJ_ARCH_ENDIAN LUAJIT_BE
197#endif
198#define LJ_ARCH_HASFPU 1
199#define LJ_TARGET_MIPS 1
200#define LJ_TARGET_EHRETREG 4
201#define LJ_TARGET_JUMPRANGE 27 /* 2*2^27 = 256MB-aligned region */
202#define LJ_TARGET_MASKSHIFT 1
203#define LJ_TARGET_MASKROT 1
204#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
205#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE
206#define LJ_ARCH_NOFFI 1
207#define LJ_ARCH_NOJIT 1
208
209#else
210#error "No target architecture defined"
211#endif
212
213#ifndef LJ_PAGESIZE
214#define LJ_PAGESIZE 4096
215#endif
216
217/* Check for minimum required compiler versions. */
218#if defined(__GNUC__)
219#if LJ_TARGET_X64
220#if __GNUC__ < 4
221#error "Need at least GCC 4.0 or newer"
222#endif
223#elif LJ_TARGET_ARM
224#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 2)
225#error "Need at least GCC 4.2 or newer"
226#endif
227#elif LJ_TARGET_PPC
228#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 3)
229#error "Need at least GCC 4.3 or newer"
230#endif
231#else
232#if (__GNUC__ < 3) || ((__GNUC__ == 3) && __GNUC_MINOR__ < 4)
233#error "Need at least GCC 3.4 or newer"
234#endif
235#endif
236#endif
237
238/* Check target-specific constraints. */
239#ifndef _BUILDVM_H
240#if LJ_TARGET_ARM
241#if defined(__ARMEB__)
242#error "No support for big-endian ARM"
243#endif
244#if defined(__ARM_PCS_VFP)
245#error "No support for ARM hard-float ABI (yet)"
246#endif
247#if !(__ARM_EABI__ || LJ_TARGET_OSX)
248#error "Only ARM EABI or iOS 3.0+ ABI is supported"
249#endif
250#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
251#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
252#error "No support for PowerPC CPUs without double-precision FPU"
253#endif
254#if defined(_LITTLE_ENDIAN)
255#error "No support for little-endian PowerPC"
256#endif
257#if defined(_LP64)
258#error "No support for PowerPC 64 bit mode"
259#endif
260#endif
261#endif
262
263/* Enable or disable the dual-number mode for the VM. */
264#if (LJ_ARCH_NUMMODE == LJ_NUMMODE_SINGLE && LUAJIT_NUMMODE == 2) || \
265 (LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL && LUAJIT_NUMMODE == 1)
266#error "No support for this number mode on this architecture"
267#endif
268#if LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL || \
269 (LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL_SINGLE && LUAJIT_NUMMODE != 1) || \
270 (LJ_ARCH_NUMMODE == LJ_NUMMODE_SINGLE_DUAL && LUAJIT_NUMMODE == 2)
271#define LJ_DUALNUM 1
272#else
273#define LJ_DUALNUM 0
274#endif
275
276/* Disable or enable the JIT compiler. */
277#if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT)
278#define LJ_HASJIT 0
279#else
280#define LJ_HASJIT 1
281#endif
282
283/* Disable or enable the FFI extension. */
284#if defined(LUAJIT_DISABLE_FFI) || defined(LJ_ARCH_NOFFI)
285#define LJ_HASFFI 0
286#else
287#define LJ_HASFFI 1
288#endif
289
290#define LJ_SOFTFP (!LJ_ARCH_HASFPU)
291
292#if LJ_ARCH_ENDIAN == LUAJIT_BE
293#define LJ_LE 0
294#define LJ_BE 1
295#define LJ_ENDIAN_SELECT(le, be) be
296#define LJ_ENDIAN_LOHI(lo, hi) hi lo
297#else
298#define LJ_LE 1
299#define LJ_BE 0
300#define LJ_ENDIAN_SELECT(le, be) le
301#define LJ_ENDIAN_LOHI(lo, hi) lo hi
302#endif
303
304#if LJ_ARCH_BITS == 32
305#define LJ_32 1
306#define LJ_64 0
307#else
308#define LJ_32 0
309#define LJ_64 1
310#endif
311
312/* Various workarounds for embedded operating systems. */
313#if defined(__ANDROID__) || defined(__symbian__)
314#define LUAJIT_NO_LOG2
315#endif
316#if defined(__symbian__)
317#define LUAJIT_NO_EXP2
318#endif
319
320#if defined(__symbian__) || (LJ_TARGET_ARM && LJ_TARGET_OSX)
321#define LUAJIT_NO_UNWIND
322#endif
323
324#endif
diff --git a/libraries/luajit-2.0/src/lj_asm.c b/libraries/luajit-2.0/src/lj_asm.c
new file mode 100644
index 0000000..1103e99
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_asm.c
@@ -0,0 +1,1741 @@
1/*
2** IR assembler (SSA IR -> machine code).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_asm_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12
13#include "lj_gc.h"
14#include "lj_str.h"
15#include "lj_tab.h"
16#include "lj_frame.h"
17#if LJ_HASFFI
18#include "lj_ctype.h"
19#endif
20#include "lj_ir.h"
21#include "lj_jit.h"
22#include "lj_ircall.h"
23#include "lj_iropt.h"
24#include "lj_mcode.h"
25#include "lj_iropt.h"
26#include "lj_trace.h"
27#include "lj_snap.h"
28#include "lj_asm.h"
29#include "lj_dispatch.h"
30#include "lj_vm.h"
31#include "lj_target.h"
32
33/* -- Assembler state and common macros ----------------------------------- */
34
35/* Assembler state. */
36typedef struct ASMState {
37 RegCost cost[RID_MAX]; /* Reference and blended allocation cost for regs. */
38
39 MCode *mcp; /* Current MCode pointer (grows down). */
40 MCode *mclim; /* Lower limit for MCode memory + red zone. */
41
42 IRIns *ir; /* Copy of pointer to IR instructions/constants. */
43 jit_State *J; /* JIT compiler state. */
44
45#if LJ_TARGET_X86ORX64
46 x86ModRM mrm; /* Fused x86 address operand. */
47#endif
48
49 RegSet freeset; /* Set of free registers. */
50 RegSet modset; /* Set of registers modified inside the loop. */
51 RegSet weakset; /* Set of weakly referenced registers. */
52 RegSet phiset; /* Set of PHI registers. */
53
54 uint32_t flags; /* Copy of JIT compiler flags. */
55 int loopinv; /* Loop branch inversion (0:no, 1:yes, 2:yes+CC_P). */
56
57 int32_t evenspill; /* Next even spill slot. */
58 int32_t oddspill; /* Next odd spill slot (or 0). */
59
60 IRRef curins; /* Reference of current instruction. */
61 IRRef stopins; /* Stop assembly before hitting this instruction. */
62 IRRef orignins; /* Original T->nins. */
63
64 IRRef snapref; /* Current snapshot is active after this reference. */
65 IRRef snaprename; /* Rename highwater mark for snapshot check. */
66 SnapNo snapno; /* Current snapshot number. */
67 SnapNo loopsnapno; /* Loop snapshot number. */
68
69 IRRef fuseref; /* Fusion limit (loopref, 0 or FUSE_DISABLED). */
70 IRRef sectref; /* Section base reference (loopref or 0). */
71 IRRef loopref; /* Reference of LOOP instruction (or 0). */
72
73 BCReg topslot; /* Number of slots for stack check (unless 0). */
74 MSize gcsteps; /* Accumulated number of GC steps (per section). */
75
76 GCtrace *T; /* Trace to assemble. */
77 GCtrace *parent; /* Parent trace (or NULL). */
78
79 MCode *mcbot; /* Bottom of reserved MCode. */
80 MCode *mctop; /* Top of generated MCode. */
81 MCode *mcloop; /* Pointer to loop MCode (or NULL). */
82 MCode *invmcp; /* Points to invertible loop branch (or NULL). */
83 MCode *flagmcp; /* Pending opportunity to merge flag setting ins. */
84 MCode *realign; /* Realign loop if not NULL. */
85
86#ifdef RID_NUM_KREF
87 int32_t krefk[RID_NUM_KREF];
88#endif
89 IRRef1 phireg[RID_MAX]; /* PHI register references. */
90 uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent slot to RegSP map. */
91#if LJ_SOFTFP
92 uint16_t parentmaphi[LJ_MAX_JSLOTS]; /* Parent slot to hi RegSP map. */
93#endif
94} ASMState;
95
96#define IR(ref) (&as->ir[(ref)])
97
98#define ASMREF_TMP1 REF_TRUE /* Temp. register. */
99#define ASMREF_TMP2 REF_FALSE /* Temp. register. */
100#define ASMREF_L REF_NIL /* Stores register for L. */
101
102/* Check for variant to invariant references. */
103#define iscrossref(as, ref) ((ref) < as->sectref)
104
105/* Inhibit memory op fusion from variant to invariant references. */
106#define FUSE_DISABLED (~(IRRef)0)
107#define mayfuse(as, ref) ((ref) > as->fuseref)
108#define neverfuse(as) (as->fuseref == FUSE_DISABLED)
109#define canfuse(as, ir) (!neverfuse(as) && !irt_isphi((ir)->t))
110#define opisfusableload(o) \
111 ((o) == IR_ALOAD || (o) == IR_HLOAD || (o) == IR_ULOAD || \
112 (o) == IR_FLOAD || (o) == IR_XLOAD || (o) == IR_SLOAD || (o) == IR_VLOAD)
113
114/* Sparse limit checks using a red zone before the actual limit. */
115#define MCLIM_REDZONE 64
116#define checkmclim(as) \
117 if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as)
118
119static LJ_NORET LJ_NOINLINE void asm_mclimit(ASMState *as)
120{
121 lj_mcode_limiterr(as->J, (size_t)(as->mctop - as->mcp + 4*MCLIM_REDZONE));
122}
123
124#ifdef RID_NUM_KREF
125#define ra_iskref(ref) ((ref) < RID_NUM_KREF)
126#define ra_krefreg(ref) ((Reg)(RID_MIN_KREF + (Reg)(ref)))
127#define ra_krefk(as, ref) (as->krefk[(ref)])
128
129static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, int32_t k)
130{
131 IRRef ref = (IRRef)(r - RID_MIN_KREF);
132 as->krefk[ref] = k;
133 as->cost[r] = REGCOST(ref, ref);
134}
135
136#else
137#define ra_iskref(ref) 0
138#define ra_krefreg(ref) RID_MIN_GPR
139#define ra_krefk(as, ref) 0
140#endif
141
142/* Arch-specific field offsets. */
143static const uint8_t field_ofs[IRFL__MAX+1] = {
144#define FLOFS(name, ofs) (uint8_t)(ofs),
145IRFLDEF(FLOFS)
146#undef FLOFS
147 0
148};
149
150/* -- Target-specific instruction emitter --------------------------------- */
151
152#if LJ_TARGET_X86ORX64
153#include "lj_emit_x86.h"
154#elif LJ_TARGET_ARM
155#include "lj_emit_arm.h"
156#elif LJ_TARGET_PPC
157#include "lj_emit_ppc.h"
158#else
159#error "Missing instruction emitter for target CPU"
160#endif
161
162/* -- Register allocator debugging ---------------------------------------- */
163
164/* #define LUAJIT_DEBUG_RA */
165
166#ifdef LUAJIT_DEBUG_RA
167
168#include <stdio.h>
169#include <stdarg.h>
170
171#define RIDNAME(name) #name,
172static const char *const ra_regname[] = {
173 GPRDEF(RIDNAME)
174 FPRDEF(RIDNAME)
175 VRIDDEF(RIDNAME)
176 NULL
177};
178#undef RIDNAME
179
180static char ra_dbg_buf[65536];
181static char *ra_dbg_p;
182static char *ra_dbg_merge;
183static MCode *ra_dbg_mcp;
184
185static void ra_dstart(void)
186{
187 ra_dbg_p = ra_dbg_buf;
188 ra_dbg_merge = NULL;
189 ra_dbg_mcp = NULL;
190}
191
192static void ra_dflush(void)
193{
194 fwrite(ra_dbg_buf, 1, (size_t)(ra_dbg_p-ra_dbg_buf), stdout);
195 ra_dstart();
196}
197
198static void ra_dprintf(ASMState *as, const char *fmt, ...)
199{
200 char *p;
201 va_list argp;
202 va_start(argp, fmt);
203 p = ra_dbg_mcp == as->mcp ? ra_dbg_merge : ra_dbg_p;
204 ra_dbg_mcp = NULL;
205 p += sprintf(p, "%08x \e[36m%04d ", (uintptr_t)as->mcp, as->curins-REF_BIAS);
206 for (;;) {
207 const char *e = strchr(fmt, '$');
208 if (e == NULL) break;
209 memcpy(p, fmt, (size_t)(e-fmt));
210 p += e-fmt;
211 if (e[1] == 'r') {
212 Reg r = va_arg(argp, Reg) & RID_MASK;
213 if (r <= RID_MAX) {
214 const char *q;
215 for (q = ra_regname[r]; *q; q++)
216 *p++ = *q >= 'A' && *q <= 'Z' ? *q + 0x20 : *q;
217 } else {
218 *p++ = '?';
219 lua_assert(0);
220 }
221 } else if (e[1] == 'f' || e[1] == 'i') {
222 IRRef ref;
223 if (e[1] == 'f')
224 ref = va_arg(argp, IRRef);
225 else
226 ref = va_arg(argp, IRIns *) - as->ir;
227 if (ref >= REF_BIAS)
228 p += sprintf(p, "%04d", ref - REF_BIAS);
229 else
230 p += sprintf(p, "K%03d", REF_BIAS - ref);
231 } else if (e[1] == 's') {
232 uint32_t slot = va_arg(argp, uint32_t);
233 p += sprintf(p, "[sp+0x%x]", sps_scale(slot));
234 } else if (e[1] == 'x') {
235 p += sprintf(p, "%08x", va_arg(argp, int32_t));
236 } else {
237 lua_assert(0);
238 }
239 fmt = e+2;
240 }
241 va_end(argp);
242 while (*fmt)
243 *p++ = *fmt++;
244 *p++ = '\e'; *p++ = '['; *p++ = 'm'; *p++ = '\n';
245 if (p > ra_dbg_buf+sizeof(ra_dbg_buf)-256) {
246 fwrite(ra_dbg_buf, 1, (size_t)(p-ra_dbg_buf), stdout);
247 p = ra_dbg_buf;
248 }
249 ra_dbg_p = p;
250}
251
252#define RA_DBG_START() ra_dstart()
253#define RA_DBG_FLUSH() ra_dflush()
254#define RA_DBG_REF() \
255 do { char *_p = ra_dbg_p; ra_dprintf(as, ""); \
256 ra_dbg_merge = _p; ra_dbg_mcp = as->mcp; } while (0)
257#define RA_DBGX(x) ra_dprintf x
258
259#else
260#define RA_DBG_START() ((void)0)
261#define RA_DBG_FLUSH() ((void)0)
262#define RA_DBG_REF() ((void)0)
263#define RA_DBGX(x) ((void)0)
264#endif
265
266/* -- Register allocator -------------------------------------------------- */
267
268#define ra_free(as, r) rset_set(as->freeset, (r))
269#define ra_modified(as, r) rset_set(as->modset, (r))
270#define ra_weak(as, r) rset_set(as->weakset, (r))
271#define ra_noweak(as, r) rset_clear(as->weakset, (r))
272
273#define ra_used(ir) (ra_hasreg((ir)->r) || ra_hasspill((ir)->s))
274
275/* Setup register allocator. */
276static void ra_setup(ASMState *as)
277{
278 Reg r;
279 /* Initially all regs (except the stack pointer) are free for use. */
280 as->freeset = RSET_INIT;
281 as->modset = RSET_EMPTY;
282 as->weakset = RSET_EMPTY;
283 as->phiset = RSET_EMPTY;
284 memset(as->phireg, 0, sizeof(as->phireg));
285 for (r = RID_MIN_GPR; r < RID_MAX; r++)
286 as->cost[r] = REGCOST(~0u, 0u);
287}
288
289/* Rematerialize constants. */
290static Reg ra_rematk(ASMState *as, IRRef ref)
291{
292 IRIns *ir;
293 Reg r;
294 if (ra_iskref(ref)) {
295 r = ra_krefreg(ref);
296 lua_assert(!rset_test(as->freeset, r));
297 ra_free(as, r);
298 ra_modified(as, r);
299 emit_loadi(as, r, ra_krefk(as, ref));
300 return r;
301 }
302 ir = IR(ref);
303 r = ir->r;
304 lua_assert(ra_hasreg(r) && !ra_hasspill(ir->s));
305 ra_free(as, r);
306 ra_modified(as, r);
307 ir->r = RID_INIT; /* Do not keep any hint. */
308 RA_DBGX((as, "remat $i $r", ir, r));
309#if !LJ_SOFTFP
310 if (ir->o == IR_KNUM) {
311 emit_loadn(as, r, ir_knum(ir));
312 } else
313#endif
314 if (emit_canremat(REF_BASE) && ir->o == IR_BASE) {
315 ra_sethint(ir->r, RID_BASE); /* Restore BASE register hint. */
316 emit_getgl(as, r, jit_base);
317 } else if (emit_canremat(ASMREF_L) && ir->o == IR_KPRI) {
318 lua_assert(irt_isnil(ir->t)); /* REF_NIL stores ASMREF_L register. */
319 emit_getgl(as, r, jit_L);
320#if LJ_64
321 } else if (ir->o == IR_KINT64) {
322 emit_loadu64(as, r, ir_kint64(ir)->u64);
323#endif
324 } else {
325 lua_assert(ir->o == IR_KINT || ir->o == IR_KGC ||
326 ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL);
327 emit_loadi(as, r, ir->i);
328 }
329 return r;
330}
331
332/* Force a spill. Allocate a new spill slot if needed. */
333static int32_t ra_spill(ASMState *as, IRIns *ir)
334{
335 int32_t slot = ir->s;
336 if (!ra_hasspill(slot)) {
337 if (irt_is64(ir->t)) {
338 slot = as->evenspill;
339 as->evenspill += 2;
340 } else if (as->oddspill) {
341 slot = as->oddspill;
342 as->oddspill = 0;
343 } else {
344 slot = as->evenspill;
345 as->oddspill = slot+1;
346 as->evenspill += 2;
347 }
348 if (as->evenspill > 256)
349 lj_trace_err(as->J, LJ_TRERR_SPILLOV);
350 ir->s = (uint8_t)slot;
351 }
352 return sps_scale(slot);
353}
354
355/* Release the temporarily allocated register in ASMREF_TMP1/ASMREF_TMP2. */
356static Reg ra_releasetmp(ASMState *as, IRRef ref)
357{
358 IRIns *ir = IR(ref);
359 Reg r = ir->r;
360 lua_assert(ra_hasreg(r) && !ra_hasspill(ir->s));
361 ra_free(as, r);
362 ra_modified(as, r);
363 ir->r = RID_INIT;
364 return r;
365}
366
367/* Restore a register (marked as free). Rematerialize or force a spill. */
368static Reg ra_restore(ASMState *as, IRRef ref)
369{
370 if (emit_canremat(ref)) {
371 return ra_rematk(as, ref);
372 } else {
373 IRIns *ir = IR(ref);
374 int32_t ofs = ra_spill(as, ir); /* Force a spill slot. */
375 Reg r = ir->r;
376 lua_assert(ra_hasreg(r));
377 ra_sethint(ir->r, r); /* Keep hint. */
378 ra_free(as, r);
379 if (!rset_test(as->weakset, r)) { /* Only restore non-weak references. */
380 ra_modified(as, r);
381 RA_DBGX((as, "restore $i $r", ir, r));
382 emit_spload(as, ir, r, ofs);
383 }
384 return r;
385 }
386}
387
388/* Save a register to a spill slot. */
389static void ra_save(ASMState *as, IRIns *ir, Reg r)
390{
391 RA_DBGX((as, "save $i $r", ir, r));
392 emit_spstore(as, ir, r, sps_scale(ir->s));
393}
394
395#define MINCOST(name) \
396 if (rset_test(RSET_ALL, RID_##name) && \
397 LJ_LIKELY(allow&RID2RSET(RID_##name)) && as->cost[RID_##name] < cost) \
398 cost = as->cost[RID_##name];
399
400/* Evict the register with the lowest cost, forcing a restore. */
401static Reg ra_evict(ASMState *as, RegSet allow)
402{
403 IRRef ref;
404 RegCost cost = ~(RegCost)0;
405 lua_assert(allow != RSET_EMPTY);
406 if (RID_NUM_FPR == 0 || allow < RID2RSET(RID_MAX_GPR)) {
407 GPRDEF(MINCOST)
408 } else {
409 FPRDEF(MINCOST)
410 }
411 ref = regcost_ref(cost);
412 lua_assert(ra_iskref(ref) || (ref >= as->T->nk && ref < as->T->nins));
413 /* Preferably pick any weak ref instead of a non-weak, non-const ref. */
414 if (!irref_isk(ref) && (as->weakset & allow)) {
415 IRIns *ir = IR(ref);
416 if (!rset_test(as->weakset, ir->r))
417 ref = regcost_ref(as->cost[rset_pickbot((as->weakset & allow))]);
418 }
419 return ra_restore(as, ref);
420}
421
422/* Pick any register (marked as free). Evict on-demand. */
423static Reg ra_pick(ASMState *as, RegSet allow)
424{
425 RegSet pick = as->freeset & allow;
426 if (!pick)
427 return ra_evict(as, allow);
428 else
429 return rset_picktop(pick);
430}
431
432/* Get a scratch register (marked as free). */
433static Reg ra_scratch(ASMState *as, RegSet allow)
434{
435 Reg r = ra_pick(as, allow);
436 ra_modified(as, r);
437 RA_DBGX((as, "scratch $r", r));
438 return r;
439}
440
441/* Evict all registers from a set (if not free). */
442static void ra_evictset(ASMState *as, RegSet drop)
443{
444 as->modset |= drop;
445 drop &= ~as->freeset;
446 while (drop) {
447 Reg r = rset_pickbot(drop);
448 ra_restore(as, regcost_ref(as->cost[r]));
449 rset_clear(drop, r);
450 checkmclim(as);
451 }
452}
453
454/* Evict (rematerialize) all registers allocated to constants. */
455static void ra_evictk(ASMState *as)
456{
457 RegSet work;
458#if !LJ_SOFTFP
459 work = ~as->freeset & RSET_FPR;
460 while (work) {
461 Reg r = rset_pickbot(work);
462 IRRef ref = regcost_ref(as->cost[r]);
463 if (emit_canremat(ref) && irref_isk(ref)) {
464 ra_rematk(as, ref);
465 checkmclim(as);
466 }
467 rset_clear(work, r);
468 }
469#endif
470 work = ~as->freeset & RSET_GPR;
471 while (work) {
472 Reg r = rset_pickbot(work);
473 IRRef ref = regcost_ref(as->cost[r]);
474 if (emit_canremat(ref) && irref_isk(ref)) {
475 ra_rematk(as, ref);
476 checkmclim(as);
477 }
478 rset_clear(work, r);
479 }
480}
481
482#ifdef RID_NUM_KREF
483/* Allocate a register for a constant. */
484static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
485{
486 /* First try to find a register which already holds the same constant. */
487 RegSet pick, work = ~as->freeset & RSET_GPR;
488 Reg r;
489 while (work) {
490 IRRef ref;
491 r = rset_pickbot(work);
492 ref = regcost_ref(as->cost[r]);
493 if (ref < ASMREF_L &&
494 k == (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i))
495 return r;
496 rset_clear(work, r);
497 }
498 pick = as->freeset & allow;
499 if (pick) {
500 /* Constants should preferably get unmodified registers. */
501 if ((pick & ~as->modset))
502 pick &= ~as->modset;
503 r = rset_pickbot(pick); /* Reduce conflicts with inverse allocation. */
504 } else {
505 r = ra_evict(as, allow);
506 }
507 RA_DBGX((as, "allock $x $r", k, r));
508 ra_setkref(as, r, k);
509 rset_clear(as->freeset, r);
510 ra_noweak(as, r);
511 return r;
512}
513
514/* Allocate a specific register for a constant. */
515static void ra_allockreg(ASMState *as, int32_t k, Reg r)
516{
517 Reg kr = ra_allock(as, k, RID2RSET(r));
518 if (kr != r) {
519 IRIns irdummy;
520 irdummy.t.irt = IRT_INT;
521 ra_scratch(as, RID2RSET(r));
522 emit_movrr(as, &irdummy, r, kr);
523 }
524}
525#else
526#define ra_allockreg(as, k, r) emit_loadi(as, (r), (k))
527#endif
528
529/* Allocate a register for ref from the allowed set of registers.
530** Note: this function assumes the ref does NOT have a register yet!
531** Picks an optimal register, sets the cost and marks the register as non-free.
532*/
533static Reg ra_allocref(ASMState *as, IRRef ref, RegSet allow)
534{
535 IRIns *ir = IR(ref);
536 RegSet pick = as->freeset & allow;
537 Reg r;
538 lua_assert(ra_noreg(ir->r));
539 if (pick) {
540 /* First check register hint from propagation or PHI. */
541 if (ra_hashint(ir->r)) {
542 r = ra_gethint(ir->r);
543 if (rset_test(pick, r)) /* Use hint register if possible. */
544 goto found;
545 /* Rematerialization is cheaper than missing a hint. */
546 if (rset_test(allow, r) && emit_canremat(regcost_ref(as->cost[r]))) {
547 ra_rematk(as, regcost_ref(as->cost[r]));
548 goto found;
549 }
550 RA_DBGX((as, "hintmiss $f $r", ref, r));
551 }
552 /* Invariants should preferably get unmodified registers. */
553 if (ref < as->loopref && !irt_isphi(ir->t)) {
554 if ((pick & ~as->modset))
555 pick &= ~as->modset;
556 r = rset_pickbot(pick); /* Reduce conflicts with inverse allocation. */
557 } else {
558 /* We've got plenty of regs, so get callee-save regs if possible. */
559 if (RID_NUM_GPR > 8 && (pick & ~RSET_SCRATCH))
560 pick &= ~RSET_SCRATCH;
561 r = rset_picktop(pick);
562 }
563 } else {
564 r = ra_evict(as, allow);
565 }
566found:
567 RA_DBGX((as, "alloc $f $r", ref, r));
568 ir->r = (uint8_t)r;
569 rset_clear(as->freeset, r);
570 ra_noweak(as, r);
571 as->cost[r] = REGCOST_REF_T(ref, irt_t(ir->t));
572 return r;
573}
574
575/* Allocate a register on-demand. */
576static Reg ra_alloc1(ASMState *as, IRRef ref, RegSet allow)
577{
578 Reg r = IR(ref)->r;
579 /* Note: allow is ignored if the register is already allocated. */
580 if (ra_noreg(r)) r = ra_allocref(as, ref, allow);
581 ra_noweak(as, r);
582 return r;
583}
584
585/* Rename register allocation and emit move. */
586static void ra_rename(ASMState *as, Reg down, Reg up)
587{
588 IRRef ren, ref = regcost_ref(as->cost[up] = as->cost[down]);
589 IRIns *ir = IR(ref);
590 ir->r = (uint8_t)up;
591 as->cost[down] = 0;
592 lua_assert((down < RID_MAX_GPR) == (up < RID_MAX_GPR));
593 lua_assert(!rset_test(as->freeset, down) && rset_test(as->freeset, up));
594 ra_free(as, down); /* 'down' is free ... */
595 ra_modified(as, down);
596 rset_clear(as->freeset, up); /* ... and 'up' is now allocated. */
597 ra_noweak(as, up);
598 RA_DBGX((as, "rename $f $r $r", regcost_ref(as->cost[up]), down, up));
599 emit_movrr(as, ir, down, up); /* Backwards codegen needs inverse move. */
600 if (!ra_hasspill(IR(ref)->s)) { /* Add the rename to the IR. */
601 lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), ref, as->snapno);
602 ren = tref_ref(lj_ir_emit(as->J));
603 as->ir = as->T->ir; /* The IR may have been reallocated. */
604 IR(ren)->r = (uint8_t)down;
605 IR(ren)->s = SPS_NONE;
606 }
607}
608
609/* Pick a destination register (marked as free).
610** Caveat: allow is ignored if there's already a destination register.
611** Use ra_destreg() to get a specific register.
612*/
613static Reg ra_dest(ASMState *as, IRIns *ir, RegSet allow)
614{
615 Reg dest = ir->r;
616 if (ra_hasreg(dest)) {
617 ra_free(as, dest);
618 ra_modified(as, dest);
619 } else {
620 if (ra_hashint(dest) && rset_test((as->freeset&allow), ra_gethint(dest))) {
621 dest = ra_gethint(dest);
622 ra_modified(as, dest);
623 RA_DBGX((as, "dest $r", dest));
624 } else {
625 dest = ra_scratch(as, allow);
626 }
627 ir->r = dest;
628 }
629 if (LJ_UNLIKELY(ra_hasspill(ir->s))) ra_save(as, ir, dest);
630 return dest;
631}
632
633/* Force a specific destination register (marked as free). */
634static void ra_destreg(ASMState *as, IRIns *ir, Reg r)
635{
636 Reg dest = ra_dest(as, ir, RID2RSET(r));
637 if (dest != r) {
638 ra_scratch(as, RID2RSET(r));
639 emit_movrr(as, ir, dest, r);
640 }
641}
642
643#if LJ_TARGET_X86ORX64
644/* Propagate dest register to left reference. Emit moves as needed.
645** This is a required fixup step for all 2-operand machine instructions.
646*/
647static void ra_left(ASMState *as, Reg dest, IRRef lref)
648{
649 IRIns *ir = IR(lref);
650 Reg left = ir->r;
651 if (ra_noreg(left)) {
652 if (irref_isk(lref)) {
653 if (ir->o == IR_KNUM) {
654 cTValue *tv = ir_knum(ir);
655 /* FP remat needs a load except for +0. Still better than eviction. */
656 if (tvispzero(tv) || !(as->freeset & RSET_FPR)) {
657 emit_loadn(as, dest, tv);
658 return;
659 }
660#if LJ_64
661 } else if (ir->o == IR_KINT64) {
662 emit_loadu64(as, dest, ir_kint64(ir)->u64);
663 return;
664#endif
665 } else {
666 lua_assert(ir->o == IR_KINT || ir->o == IR_KGC ||
667 ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL);
668 emit_loadi(as, dest, ir->i);
669 return;
670 }
671 }
672 if (!ra_hashint(left) && !iscrossref(as, lref))
673 ra_sethint(ir->r, dest); /* Propagate register hint. */
674 left = ra_allocref(as, lref, dest < RID_MAX_GPR ? RSET_GPR : RSET_FPR);
675 }
676 ra_noweak(as, left);
677 /* Move needed for true 3-operand instruction: y=a+b ==> y=a; y+=b. */
678 if (dest != left) {
679 /* Use register renaming if dest is the PHI reg. */
680 if (irt_isphi(ir->t) && as->phireg[dest] == lref) {
681 ra_modified(as, left);
682 ra_rename(as, left, dest);
683 } else {
684 emit_movrr(as, ir, dest, left);
685 }
686 }
687}
688#else
689/* Similar to ra_left, except we override any hints. */
690static void ra_leftov(ASMState *as, Reg dest, IRRef lref)
691{
692 IRIns *ir = IR(lref);
693 Reg left = ir->r;
694 if (ra_noreg(left)) {
695 ra_sethint(ir->r, dest); /* Propagate register hint. */
696 left = ra_allocref(as, lref,
697 (LJ_SOFTFP || dest < RID_MAX_GPR) ? RSET_GPR : RSET_FPR);
698 }
699 ra_noweak(as, left);
700 if (dest != left) {
701 /* Use register renaming if dest is the PHI reg. */
702 if (irt_isphi(ir->t) && as->phireg[dest] == lref) {
703 ra_modified(as, left);
704 ra_rename(as, left, dest);
705 } else {
706 emit_movrr(as, ir, dest, left);
707 }
708 }
709}
710#endif
711
712#if !LJ_TARGET_X86ORX64
713/* Force a RID_RETLO/RID_RETHI destination register pair (marked as free). */
714static void ra_destpair(ASMState *as, IRIns *ir)
715{
716 Reg destlo = ir->r, desthi = (ir+1)->r;
717 /* First spill unrelated refs blocking the destination registers. */
718 if (!rset_test(as->freeset, RID_RETLO) &&
719 destlo != RID_RETLO && desthi != RID_RETLO)
720 ra_restore(as, regcost_ref(as->cost[RID_RETLO]));
721 if (!rset_test(as->freeset, RID_RETHI) &&
722 destlo != RID_RETHI && desthi != RID_RETHI)
723 ra_restore(as, regcost_ref(as->cost[RID_RETHI]));
724 /* Next free the destination registers (if any). */
725 if (ra_hasreg(destlo)) {
726 ra_free(as, destlo);
727 ra_modified(as, destlo);
728 } else {
729 destlo = RID_RETLO;
730 }
731 if (ra_hasreg(desthi)) {
732 ra_free(as, desthi);
733 ra_modified(as, desthi);
734 } else {
735 desthi = RID_RETHI;
736 }
737 /* Check for conflicts and shuffle the registers as needed. */
738 if (destlo == RID_RETHI) {
739 if (desthi == RID_RETLO) {
740 emit_movrr(as, ir, RID_RETHI, RID_TMP);
741 emit_movrr(as, ir, RID_RETLO, RID_RETHI);
742 emit_movrr(as, ir, RID_TMP, RID_RETLO);
743 } else {
744 emit_movrr(as, ir, RID_RETHI, RID_RETLO);
745 if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI);
746 }
747 } else if (desthi == RID_RETLO) {
748 emit_movrr(as, ir, RID_RETLO, RID_RETHI);
749 if (destlo != RID_RETLO) emit_movrr(as, ir, destlo, RID_RETLO);
750 } else {
751 if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI);
752 if (destlo != RID_RETLO) emit_movrr(as, ir, destlo, RID_RETLO);
753 }
754 /* Restore spill slots (if any). */
755 if (ra_hasspill((ir+1)->s)) ra_save(as, ir+1, RID_RETHI);
756 if (ra_hasspill(ir->s)) ra_save(as, ir, RID_RETLO);
757}
758#endif
759
760/* -- Snapshot handling --------- ----------------------------------------- */
761
762/* Can we rematerialize a KNUM instead of forcing a spill? */
763static int asm_snap_canremat(ASMState *as)
764{
765 Reg r;
766 for (r = RID_MIN_FPR; r < RID_MAX_FPR; r++)
767 if (irref_isk(regcost_ref(as->cost[r])))
768 return 1;
769 return 0;
770}
771
772/* Allocate register or spill slot for a ref that escapes to a snapshot. */
773static void asm_snap_alloc1(ASMState *as, IRRef ref)
774{
775 IRIns *ir = IR(ref);
776 if (!ra_used(ir)) {
777 RegSet allow = (!LJ_SOFTFP && irt_isnum(ir->t)) ? RSET_FPR : RSET_GPR;
778 /* Get a weak register if we have a free one or can rematerialize. */
779 if ((as->freeset & allow) ||
780 (allow == RSET_FPR && asm_snap_canremat(as))) {
781 Reg r = ra_allocref(as, ref, allow); /* Allocate a register. */
782 if (!irt_isphi(ir->t))
783 ra_weak(as, r); /* But mark it as weakly referenced. */
784 checkmclim(as);
785 RA_DBGX((as, "snapreg $f $r", ref, ir->r));
786 } else {
787 ra_spill(as, ir); /* Otherwise force a spill slot. */
788 RA_DBGX((as, "snapspill $f $s", ref, ir->s));
789 }
790 }
791}
792
793/* Allocate refs escaping to a snapshot. */
794static void asm_snap_alloc(ASMState *as)
795{
796 SnapShot *snap = &as->T->snap[as->snapno];
797 SnapEntry *map = &as->T->snapmap[snap->mapofs];
798 MSize n, nent = snap->nent;
799 for (n = 0; n < nent; n++) {
800 SnapEntry sn = map[n];
801 IRRef ref = snap_ref(sn);
802 if (!irref_isk(ref)) {
803 asm_snap_alloc1(as, ref);
804 if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) {
805 lua_assert(irt_type(IR(ref+1)->t) == IRT_SOFTFP);
806 asm_snap_alloc1(as, ref+1);
807 }
808 }
809 }
810}
811
812/* All guards for a snapshot use the same exitno. This is currently the
813** same as the snapshot number. Since the exact origin of the exit cannot
814** be determined, all guards for the same snapshot must exit with the same
815** RegSP mapping.
816** A renamed ref which has been used in a prior guard for the same snapshot
817** would cause an inconsistency. The easy way out is to force a spill slot.
818*/
819static int asm_snap_checkrename(ASMState *as, IRRef ren)
820{
821 SnapShot *snap = &as->T->snap[as->snapno];
822 SnapEntry *map = &as->T->snapmap[snap->mapofs];
823 MSize n, nent = snap->nent;
824 for (n = 0; n < nent; n++) {
825 SnapEntry sn = map[n];
826 IRRef ref = snap_ref(sn);
827 if (ref == ren || (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && ++ref == ren)) {
828 IRIns *ir = IR(ref);
829 ra_spill(as, ir); /* Register renamed, so force a spill slot. */
830 RA_DBGX((as, "snaprensp $f $s", ref, ir->s));
831 return 1; /* Found. */
832 }
833 }
834 return 0; /* Not found. */
835}
836
837/* Prepare snapshot for next guard instruction. */
838static void asm_snap_prep(ASMState *as)
839{
840 if (as->curins < as->snapref) {
841 do {
842 lua_assert(as->snapno != 0);
843 as->snapno--;
844 as->snapref = as->T->snap[as->snapno].ref;
845 } while (as->curins < as->snapref);
846 asm_snap_alloc(as);
847 as->snaprename = as->T->nins;
848 } else {
849 /* Process any renames above the highwater mark. */
850 for (; as->snaprename < as->T->nins; as->snaprename++) {
851 IRIns *ir = IR(as->snaprename);
852 if (asm_snap_checkrename(as, ir->op1))
853 ir->op2 = REF_BIAS-1; /* Kill rename. */
854 }
855 }
856}
857
858/* -- Miscellaneous helpers ----------------------------------------------- */
859
860/* Collect arguments from CALL* and CARG instructions. */
861static void asm_collectargs(ASMState *as, IRIns *ir,
862 const CCallInfo *ci, IRRef *args)
863{
864 uint32_t n = CCI_NARGS(ci);
865 lua_assert(n <= CCI_NARGS_MAX);
866 if ((ci->flags & CCI_L)) { *args++ = ASMREF_L; n--; }
867 while (n-- > 1) {
868 ir = IR(ir->op1);
869 lua_assert(ir->o == IR_CARG);
870 args[n] = ir->op2 == REF_NIL ? 0 : ir->op2;
871 }
872 args[0] = ir->op1 == REF_NIL ? 0 : ir->op1;
873 lua_assert(IR(ir->op1)->o != IR_CARG);
874}
875
876/* Reconstruct CCallInfo flags for CALLX*. */
877static uint32_t asm_callx_flags(ASMState *as, IRIns *ir)
878{
879 uint32_t nargs = 0;
880 if (ir->op1 != REF_NIL) { /* Count number of arguments first. */
881 IRIns *ira = IR(ir->op1);
882 nargs++;
883 while (ira->o == IR_CARG) { nargs++; ira = IR(ira->op1); }
884 }
885#if LJ_HASFFI
886 if (IR(ir->op2)->o == IR_CARG) { /* Copy calling convention info. */
887 CTypeID id = (CTypeID)IR(IR(ir->op2)->op2)->i;
888 CType *ct = ctype_get(ctype_ctsG(J2G(as->J)), id);
889 nargs |= ((ct->info & CTF_VARARG) ? CCI_VARARG : 0);
890#if LJ_TARGET_X86
891 nargs |= (ctype_cconv(ct->info) << CCI_CC_SHIFT);
892#endif
893 }
894#endif
895 return (nargs | (ir->t.irt << CCI_OTSHIFT));
896}
897
898/* Calculate stack adjustment. */
899static int32_t asm_stack_adjust(ASMState *as)
900{
901 if (as->evenspill <= SPS_FIXED)
902 return 0;
903 return sps_scale(sps_align(as->evenspill));
904}
905
906/* Must match with hash*() in lj_tab.c. */
907static uint32_t ir_khash(IRIns *ir)
908{
909 uint32_t lo, hi;
910 if (irt_isstr(ir->t)) {
911 return ir_kstr(ir)->hash;
912 } else if (irt_isnum(ir->t)) {
913 lo = ir_knum(ir)->u32.lo;
914 hi = ir_knum(ir)->u32.hi << 1;
915 } else if (irt_ispri(ir->t)) {
916 lua_assert(!irt_isnil(ir->t));
917 return irt_type(ir->t)-IRT_FALSE;
918 } else {
919 lua_assert(irt_isgcv(ir->t));
920 lo = u32ptr(ir_kgc(ir));
921 hi = lo + HASH_BIAS;
922 }
923 return hashrot(lo, hi);
924}
925
926/* -- Allocations --------------------------------------------------------- */
927
928static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args);
929static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci);
930
931static void asm_snew(ASMState *as, IRIns *ir)
932{
933 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_new];
934 IRRef args[3];
935 args[0] = ASMREF_L; /* lua_State *L */
936 args[1] = ir->op1; /* const char *str */
937 args[2] = ir->op2; /* size_t len */
938 as->gcsteps++;
939 asm_setupresult(as, ir, ci); /* GCstr * */
940 asm_gencall(as, ci, args);
941}
942
943static void asm_tnew(ASMState *as, IRIns *ir)
944{
945 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_new1];
946 IRRef args[2];
947 args[0] = ASMREF_L; /* lua_State *L */
948 args[1] = ASMREF_TMP1; /* uint32_t ahsize */
949 as->gcsteps++;
950 asm_setupresult(as, ir, ci); /* GCtab * */
951 asm_gencall(as, ci, args);
952 ra_allockreg(as, ir->op1 | (ir->op2 << 24), ra_releasetmp(as, ASMREF_TMP1));
953}
954
955static void asm_tdup(ASMState *as, IRIns *ir)
956{
957 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_dup];
958 IRRef args[2];
959 args[0] = ASMREF_L; /* lua_State *L */
960 args[1] = ir->op1; /* const GCtab *kt */
961 as->gcsteps++;
962 asm_setupresult(as, ir, ci); /* GCtab * */
963 asm_gencall(as, ci, args);
964}
965
966/* -- PHI and loop handling ----------------------------------------------- */
967
968/* Break a PHI cycle by renaming to a free register (evict if needed). */
969static void asm_phi_break(ASMState *as, RegSet blocked, RegSet blockedby,
970 RegSet allow)
971{
972 RegSet candidates = blocked & allow;
973 if (candidates) { /* If this register file has candidates. */
974 /* Note: the set for ra_pick cannot be empty, since each register file
975 ** has some registers never allocated to PHIs.
976 */
977 Reg down, up = ra_pick(as, ~blocked & allow); /* Get a free register. */
978 if (candidates & ~blockedby) /* Optimize shifts, else it's a cycle. */
979 candidates = candidates & ~blockedby;
980 down = rset_picktop(candidates); /* Pick candidate PHI register. */
981 ra_rename(as, down, up); /* And rename it to the free register. */
982 }
983}
984
985/* PHI register shuffling.
986**
987** The allocator tries hard to preserve PHI register assignments across
988** the loop body. Most of the time this loop does nothing, since there
989** are no register mismatches.
990**
991** If a register mismatch is detected and ...
992** - the register is currently free: rename it.
993** - the register is blocked by an invariant: restore/remat and rename it.
994** - Otherwise the register is used by another PHI, so mark it as blocked.
995**
996** The renames are order-sensitive, so just retry the loop if a register
997** is marked as blocked, but has been freed in the meantime. A cycle is
998** detected if all of the blocked registers are allocated. To break the
999** cycle rename one of them to a free register and retry.
1000**
1001** Note that PHI spill slots are kept in sync and don't need to be shuffled.
1002*/
1003static void asm_phi_shuffle(ASMState *as)
1004{
1005 RegSet work;
1006
1007 /* Find and resolve PHI register mismatches. */
1008 for (;;) {
1009 RegSet blocked = RSET_EMPTY;
1010 RegSet blockedby = RSET_EMPTY;
1011 RegSet phiset = as->phiset;
1012 while (phiset) { /* Check all left PHI operand registers. */
1013 Reg r = rset_pickbot(phiset);
1014 IRIns *irl = IR(as->phireg[r]);
1015 Reg left = irl->r;
1016 if (r != left) { /* Mismatch? */
1017 if (!rset_test(as->freeset, r)) { /* PHI register blocked? */
1018 IRRef ref = regcost_ref(as->cost[r]);
1019 /* Blocked by other PHI (w/reg)? */
1020 if (!ra_iskref(ref) && irt_ismarked(IR(ref)->t)) {
1021 rset_set(blocked, r);
1022 if (ra_hasreg(left))
1023 rset_set(blockedby, left);
1024 left = RID_NONE;
1025 } else { /* Otherwise grab register from invariant. */
1026 ra_restore(as, ref);
1027 checkmclim(as);
1028 }
1029 }
1030 if (ra_hasreg(left)) {
1031 ra_rename(as, left, r);
1032 checkmclim(as);
1033 }
1034 }
1035 rset_clear(phiset, r);
1036 }
1037 if (!blocked) break; /* Finished. */
1038 if (!(as->freeset & blocked)) { /* Break cycles if none are free. */
1039 asm_phi_break(as, blocked, blockedby, RSET_GPR);
1040 if (!LJ_SOFTFP) asm_phi_break(as, blocked, blockedby, RSET_FPR);
1041 checkmclim(as);
1042 } /* Else retry some more renames. */
1043 }
1044
1045 /* Restore/remat invariants whose registers are modified inside the loop. */
1046 work = as->modset & ~(as->freeset | as->phiset);
1047 while (work) {
1048 Reg r = rset_pickbot(work);
1049 ra_restore(as, regcost_ref(as->cost[r]));
1050 rset_clear(work, r);
1051 checkmclim(as);
1052 }
1053
1054 /* Allocate and save all unsaved PHI regs and clear marks. */
1055 work = as->phiset;
1056 while (work) {
1057 Reg r = rset_picktop(work);
1058 IRRef lref = as->phireg[r];
1059 IRIns *ir = IR(lref);
1060 if (ra_hasspill(ir->s)) { /* Left PHI gained a spill slot? */
1061 irt_clearmark(ir->t); /* Handled here, so clear marker now. */
1062 ra_alloc1(as, lref, RID2RSET(r));
1063 ra_save(as, ir, r); /* Save to spill slot inside the loop. */
1064 checkmclim(as);
1065 }
1066 rset_clear(work, r);
1067 }
1068}
1069
1070/* Emit renames for left PHIs which are only spilled outside the loop. */
1071static void asm_phi_fixup(ASMState *as)
1072{
1073 RegSet work = as->phiset;
1074 while (work) {
1075 Reg r = rset_picktop(work);
1076 IRRef lref = as->phireg[r];
1077 IRIns *ir = IR(lref);
1078 /* Left PHI gained a spill slot before the loop? */
1079 if (irt_ismarked(ir->t) && ra_hasspill(ir->s)) {
1080 IRRef ren;
1081 lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), lref, as->loopsnapno);
1082 ren = tref_ref(lj_ir_emit(as->J));
1083 as->ir = as->T->ir; /* The IR may have been reallocated. */
1084 IR(ren)->r = (uint8_t)r;
1085 IR(ren)->s = SPS_NONE;
1086 }
1087 irt_clearmark(ir->t); /* Always clear marker. */
1088 rset_clear(work, r);
1089 }
1090}
1091
1092/* Setup right PHI reference. */
1093static void asm_phi(ASMState *as, IRIns *ir)
1094{
1095 RegSet allow = ((!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR) &
1096 ~as->phiset;
1097 RegSet afree = (as->freeset & allow);
1098 IRIns *irl = IR(ir->op1);
1099 IRIns *irr = IR(ir->op2);
1100 /* Spill slot shuffling is not implemented yet (but rarely needed). */
1101 if (ra_hasspill(irl->s) || ra_hasspill(irr->s))
1102 lj_trace_err(as->J, LJ_TRERR_NYIPHI);
1103 /* Leave at least one register free for non-PHIs (and PHI cycle breaking). */
1104 if ((afree & (afree-1))) { /* Two or more free registers? */
1105 Reg r;
1106 if (ra_noreg(irr->r)) { /* Get a register for the right PHI. */
1107 r = ra_allocref(as, ir->op2, allow);
1108 } else { /* Duplicate right PHI, need a copy (rare). */
1109 r = ra_scratch(as, allow);
1110 emit_movrr(as, irr, r, irr->r);
1111 }
1112 ir->r = (uint8_t)r;
1113 rset_set(as->phiset, r);
1114 as->phireg[r] = (IRRef1)ir->op1;
1115 irt_setmark(irl->t); /* Marks left PHIs _with_ register. */
1116 if (ra_noreg(irl->r))
1117 ra_sethint(irl->r, r); /* Set register hint for left PHI. */
1118 } else { /* Otherwise allocate a spill slot. */
1119 /* This is overly restrictive, but it triggers only on synthetic code. */
1120 if (ra_hasreg(irl->r) || ra_hasreg(irr->r))
1121 lj_trace_err(as->J, LJ_TRERR_NYIPHI);
1122 ra_spill(as, ir);
1123 irl->s = irr->s = ir->s; /* Sync left/right PHI spill slots. */
1124 }
1125}
1126
1127static void asm_gc_check(ASMState *as);
1128static void asm_loop_fixup(ASMState *as);
1129
1130/* Middle part of a loop. */
1131static void asm_loop(ASMState *as)
1132{
1133 /* LOOP is a guard, so the snapno is up to date. */
1134 as->loopsnapno = as->snapno;
1135 if (as->gcsteps)
1136 asm_gc_check(as);
1137 /* LOOP marks the transition from the variant to the invariant part. */
1138 as->flagmcp = as->invmcp = NULL;
1139 as->sectref = 0;
1140 if (!neverfuse(as)) as->fuseref = 0;
1141 asm_phi_shuffle(as);
1142 asm_loop_fixup(as);
1143 as->mcloop = as->mcp;
1144 RA_DBGX((as, "===== LOOP ====="));
1145 if (!as->realign) RA_DBG_FLUSH();
1146}
1147
1148/* -- Target-specific assembler ------------------------------------------- */
1149
1150#if LJ_TARGET_X86ORX64
1151#include "lj_asm_x86.h"
1152#elif LJ_TARGET_ARM
1153#include "lj_asm_arm.h"
1154#elif LJ_TARGET_PPC
1155#include "lj_asm_ppc.h"
1156#else
1157#error "Missing assembler for target CPU"
1158#endif
1159
1160/* -- Head of trace ------------------------------------------------------- */
1161
1162/* Head of a root trace. */
1163static void asm_head_root(ASMState *as)
1164{
1165 int32_t spadj;
1166 asm_head_root_base(as);
1167 emit_setvmstate(as, (int32_t)as->T->traceno);
1168 spadj = asm_stack_adjust(as);
1169 as->T->spadjust = (uint16_t)spadj;
1170 emit_spsub(as, spadj);
1171 /* Root traces assume a checked stack for the starting proto. */
1172 as->T->topslot = gcref(as->T->startpt)->pt.framesize;
1173}
1174
1175/* Get RegSP for parent slot. */
1176static LJ_AINLINE RegSP asm_head_parentrs(ASMState *as, IRIns *ir)
1177{
1178#if LJ_SOFTFP
1179 if (ir->o == IR_HIOP) return as->parentmaphi[(ir-1)->op1];
1180#endif
1181 return as->parentmap[ir->op1];
1182}
1183
1184/* Head of a side trace.
1185**
1186** The current simplistic algorithm requires that all slots inherited
1187** from the parent are live in a register between pass 2 and pass 3. This
1188** avoids the complexity of stack slot shuffling. But of course this may
1189** overflow the register set in some cases and cause the dreaded error:
1190** "NYI: register coalescing too complex". A refined algorithm is needed.
1191*/
1192static void asm_head_side(ASMState *as)
1193{
1194 IRRef1 sloadins[RID_MAX];
1195 RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */
1196 RegSet live = RSET_EMPTY; /* Live parent registers. */
1197 IRIns *irp = &as->parent->ir[REF_BASE]; /* Parent base. */
1198 int32_t spadj, spdelta;
1199 int pass2 = 0;
1200 int pass3 = 0;
1201 IRRef i;
1202
1203 allow = asm_head_side_base(as, irp, allow);
1204
1205 /* Scan all parent SLOADs and collect register dependencies. */
1206 for (i = as->stopins; i > REF_BASE; i--) {
1207 IRIns *ir = IR(i);
1208 RegSP rs;
1209 lua_assert((ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT)) ||
1210 (LJ_SOFTFP && ir->o == IR_HIOP));
1211 rs = asm_head_parentrs(as, ir);
1212 if (ra_hasreg(ir->r)) {
1213 rset_clear(allow, ir->r);
1214 if (ra_hasspill(ir->s))
1215 ra_save(as, ir, ir->r);
1216 } else if (ra_hasspill(ir->s)) {
1217 irt_setmark(ir->t);
1218 pass2 = 1;
1219 }
1220 if (ir->r == rs) { /* Coalesce matching registers right now. */
1221 ra_free(as, ir->r);
1222 } else if (ra_hasspill(regsp_spill(rs))) {
1223 if (ra_hasreg(ir->r))
1224 pass3 = 1;
1225 } else if (ra_used(ir)) {
1226 sloadins[rs] = (IRRef1)i;
1227 rset_set(live, rs); /* Block live parent register. */
1228 }
1229 }
1230
1231 /* Calculate stack frame adjustment. */
1232 spadj = asm_stack_adjust(as);
1233 spdelta = spadj - (int32_t)as->parent->spadjust;
1234 if (spdelta < 0) { /* Don't shrink the stack frame. */
1235 spadj = (int32_t)as->parent->spadjust;
1236 spdelta = 0;
1237 }
1238 as->T->spadjust = (uint16_t)spadj;
1239
1240 /* Reload spilled target registers. */
1241 if (pass2) {
1242 for (i = as->stopins; i > REF_BASE; i--) {
1243 IRIns *ir = IR(i);
1244 if (irt_ismarked(ir->t)) {
1245 RegSet mask;
1246 Reg r;
1247 RegSP rs;
1248 irt_clearmark(ir->t);
1249 rs = asm_head_parentrs(as, ir);
1250 if (!ra_hasspill(regsp_spill(rs)))
1251 ra_sethint(ir->r, rs); /* Hint may be gone, set it again. */
1252 else if (sps_scale(regsp_spill(rs))+spdelta == sps_scale(ir->s))
1253 continue; /* Same spill slot, do nothing. */
1254 mask = ((!LJ_SOFTFP && irt_isnum(ir->t)) ? RSET_FPR : RSET_GPR) & allow;
1255 if (mask == RSET_EMPTY)
1256 lj_trace_err(as->J, LJ_TRERR_NYICOAL);
1257 r = ra_allocref(as, i, mask);
1258 ra_save(as, ir, r);
1259 rset_clear(allow, r);
1260 if (r == rs) { /* Coalesce matching registers right now. */
1261 ra_free(as, r);
1262 rset_clear(live, r);
1263 } else if (ra_hasspill(regsp_spill(rs))) {
1264 pass3 = 1;
1265 }
1266 checkmclim(as);
1267 }
1268 }
1269 }
1270
1271 /* Store trace number and adjust stack frame relative to the parent. */
1272 emit_setvmstate(as, (int32_t)as->T->traceno);
1273 emit_spsub(as, spdelta);
1274
1275#if !LJ_TARGET_X86ORX64
1276 /* Restore BASE register from parent spill slot. */
1277 if (ra_hasspill(irp->s))
1278 emit_spload(as, IR(REF_BASE), IR(REF_BASE)->r, sps_scale(irp->s));
1279#endif
1280
1281 /* Restore target registers from parent spill slots. */
1282 if (pass3) {
1283 RegSet work = ~as->freeset & RSET_ALL;
1284 while (work) {
1285 Reg r = rset_pickbot(work);
1286 IRIns *ir = IR(regcost_ref(as->cost[r]));
1287 RegSP rs = asm_head_parentrs(as, ir);
1288 rset_clear(work, r);
1289 if (ra_hasspill(regsp_spill(rs))) {
1290 int32_t ofs = sps_scale(regsp_spill(rs));
1291 ra_free(as, r);
1292 emit_spload(as, ir, r, ofs);
1293 checkmclim(as);
1294 }
1295 }
1296 }
1297
1298 /* Shuffle registers to match up target regs with parent regs. */
1299 for (;;) {
1300 RegSet work;
1301
1302 /* Repeatedly coalesce free live registers by moving to their target. */
1303 while ((work = as->freeset & live) != RSET_EMPTY) {
1304 Reg rp = rset_pickbot(work);
1305 IRIns *ir = IR(sloadins[rp]);
1306 rset_clear(live, rp);
1307 rset_clear(allow, rp);
1308 ra_free(as, ir->r);
1309 emit_movrr(as, ir, ir->r, rp);
1310 checkmclim(as);
1311 }
1312
1313 /* We're done if no live registers remain. */
1314 if (live == RSET_EMPTY)
1315 break;
1316
1317 /* Break cycles by renaming one target to a temp. register. */
1318 if (live & RSET_GPR) {
1319 RegSet tmpset = as->freeset & ~live & allow & RSET_GPR;
1320 if (tmpset == RSET_EMPTY)
1321 lj_trace_err(as->J, LJ_TRERR_NYICOAL);
1322 ra_rename(as, rset_pickbot(live & RSET_GPR), rset_pickbot(tmpset));
1323 }
1324 if (!LJ_SOFTFP && (live & RSET_FPR)) {
1325 RegSet tmpset = as->freeset & ~live & allow & RSET_FPR;
1326 if (tmpset == RSET_EMPTY)
1327 lj_trace_err(as->J, LJ_TRERR_NYICOAL);
1328 ra_rename(as, rset_pickbot(live & RSET_FPR), rset_pickbot(tmpset));
1329 }
1330 checkmclim(as);
1331 /* Continue with coalescing to fix up the broken cycle(s). */
1332 }
1333
1334 /* Inherit top stack slot already checked by parent trace. */
1335 as->T->topslot = as->parent->topslot;
1336 if (as->topslot > as->T->topslot) { /* Need to check for higher slot? */
1337#ifdef EXITSTATE_CHECKEXIT
1338 /* Highest exit + 1 indicates stack check. */
1339 ExitNo exitno = as->T->nsnap;
1340#else
1341 /* Reuse the parent exit in the context of the parent trace. */
1342 ExitNo exitno = as->J->exitno;
1343#endif
1344 as->T->topslot = (uint8_t)as->topslot; /* Remember for child traces. */
1345 asm_stack_check(as, as->topslot, irp, allow & RSET_GPR, exitno);
1346 }
1347}
1348
1349/* -- Tail of trace ------------------------------------------------------- */
1350
1351/* Get base slot for a snapshot. */
1352static BCReg asm_baseslot(ASMState *as, SnapShot *snap, int *gotframe)
1353{
1354 SnapEntry *map = &as->T->snapmap[snap->mapofs];
1355 MSize n;
1356 for (n = snap->nent; n > 0; n--) {
1357 SnapEntry sn = map[n-1];
1358 if ((sn & SNAP_FRAME)) {
1359 *gotframe = 1;
1360 return snap_slot(sn);
1361 }
1362 }
1363 return 0;
1364}
1365
1366/* Link to another trace. */
1367static void asm_tail_link(ASMState *as)
1368{
1369 SnapNo snapno = as->T->nsnap-1; /* Last snapshot. */
1370 SnapShot *snap = &as->T->snap[snapno];
1371 int gotframe = 0;
1372 BCReg baseslot = asm_baseslot(as, snap, &gotframe);
1373
1374 as->topslot = snap->topslot;
1375 checkmclim(as);
1376 ra_allocref(as, REF_BASE, RID2RSET(RID_BASE));
1377
1378 if (as->T->link == 0) {
1379 /* Setup fixed registers for exit to interpreter. */
1380 const BCIns *pc = snap_pc(as->T->snapmap[snap->mapofs + snap->nent]);
1381 int32_t mres;
1382 if (bc_op(*pc) == BC_JLOOP) { /* NYI: find a better way to do this. */
1383 BCIns *retpc = &traceref(as->J, bc_d(*pc))->startins;
1384 if (bc_isret(bc_op(*retpc)))
1385 pc = retpc;
1386 }
1387 ra_allockreg(as, i32ptr(J2GG(as->J)->dispatch), RID_DISPATCH);
1388 ra_allockreg(as, i32ptr(pc), RID_LPC);
1389 mres = (int32_t)(snap->nslots - baseslot);
1390 switch (bc_op(*pc)) {
1391 case BC_CALLM: case BC_CALLMT:
1392 mres -= (int32_t)(1 + bc_a(*pc) + bc_c(*pc)); break;
1393 case BC_RETM: mres -= (int32_t)(bc_a(*pc) + bc_d(*pc)); break;
1394 case BC_TSETM: mres -= (int32_t)bc_a(*pc); break;
1395 default: if (bc_op(*pc) < BC_FUNCF) mres = 0; break;
1396 }
1397 ra_allockreg(as, mres, RID_RET); /* Return MULTRES or 0. */
1398 } else if (baseslot) {
1399 /* Save modified BASE for linking to trace with higher start frame. */
1400 emit_setgl(as, RID_BASE, jit_base);
1401 }
1402 emit_addptr(as, RID_BASE, 8*(int32_t)baseslot);
1403
1404 /* Sync the interpreter state with the on-trace state. */
1405 asm_stack_restore(as, snap);
1406
1407 /* Root traces that add frames need to check the stack at the end. */
1408 if (!as->parent && gotframe)
1409 asm_stack_check(as, as->topslot, NULL, as->freeset & RSET_GPR, snapno);
1410}
1411
1412/* -- Trace setup --------------------------------------------------------- */
1413
1414/* Clear reg/sp for all instructions and add register hints. */
1415static void asm_setup_regsp(ASMState *as)
1416{
1417 GCtrace *T = as->T;
1418 IRRef i, nins;
1419 int inloop;
1420#if LJ_TARGET_ARM
1421 uint32_t rload = 0xa6402a64;
1422#endif
1423
1424 ra_setup(as);
1425
1426 /* Clear reg/sp for constants. */
1427 for (i = T->nk; i < REF_BIAS; i++)
1428 IR(i)->prev = REGSP_INIT;
1429
1430 /* REF_BASE is used for implicit references to the BASE register. */
1431 IR(REF_BASE)->prev = REGSP_HINT(RID_BASE);
1432
1433 nins = T->nins;
1434 if (IR(nins-1)->o == IR_RENAME) {
1435 do { nins--; } while (IR(nins-1)->o == IR_RENAME);
1436 T->nins = nins; /* Remove any renames left over from ASM restart. */
1437 }
1438 as->snaprename = nins;
1439 as->snapref = nins;
1440 as->snapno = T->nsnap;
1441
1442 as->stopins = REF_BASE;
1443 as->orignins = nins;
1444 as->curins = nins;
1445
1446 inloop = 0;
1447 as->evenspill = SPS_FIRST;
1448 for (i = REF_FIRST; i < nins; i++) {
1449 IRIns *ir = IR(i);
1450 switch (ir->o) {
1451 case IR_LOOP:
1452 inloop = 1;
1453 break;
1454 /* Set hints for slot loads from a parent trace. */
1455 case IR_SLOAD:
1456 if ((ir->op2 & IRSLOAD_PARENT)) {
1457 RegSP rs = as->parentmap[ir->op1];
1458 lua_assert(regsp_used(rs));
1459 as->stopins = i;
1460 if (!ra_hasspill(regsp_spill(rs)) && ra_hasreg(regsp_reg(rs))) {
1461 ir->prev = (uint16_t)REGSP_HINT(regsp_reg(rs));
1462 continue;
1463 }
1464 }
1465#if LJ_TARGET_ARM
1466 if ((ir->op2 & IRSLOAD_TYPECHECK) || (ir+1)->o == IR_HIOP) {
1467 ir->prev = (uint16_t)REGSP_HINT((rload & 15));
1468 rload = lj_ror(rload, 4);
1469 continue;
1470 }
1471#endif
1472 break;
1473#if LJ_TARGET_ARM
1474 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1475 ir->prev = (uint16_t)REGSP_HINT((rload & 15));
1476 rload = lj_ror(rload, 4);
1477 continue;
1478#endif
1479 case IR_CALLXS: {
1480 CCallInfo ci;
1481 ci.flags = asm_callx_flags(as, ir);
1482 ir->prev = asm_setup_call_slots(as, ir, &ci);
1483 if (inloop)
1484 as->modset |= RSET_SCRATCH;
1485 continue;
1486 }
1487 case IR_CALLN: case IR_CALLL: case IR_CALLS: {
1488 const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
1489 ir->prev = asm_setup_call_slots(as, ir, ci);
1490 if (inloop)
1491 as->modset |= (ci->flags & CCI_NOFPRCLOBBER) ?
1492 (RSET_SCRATCH & ~RSET_FPR) : RSET_SCRATCH;
1493 continue;
1494 }
1495#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
1496 case IR_HIOP:
1497 switch ((ir-1)->o) {
1498#if LJ_SOFTFP
1499 case IR_SLOAD:
1500 if (((ir-1)->op2 & IRSLOAD_PARENT)) {
1501 RegSP rs = as->parentmaphi[(ir-1)->op1];
1502 lua_assert(regsp_used(rs));
1503 as->stopins = i;
1504 if (!ra_hasspill(regsp_spill(rs)) && ra_hasreg(regsp_reg(rs))) {
1505 ir->prev = (uint16_t)REGSP_HINT(regsp_reg(rs));
1506 continue;
1507 }
1508 }
1509#if LJ_TARGET_ARM
1510 /* fallthrough */
1511 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1512 if (ra_hashint((ir-1)->r)) {
1513 ir->prev = (ir-1)->prev + 1;
1514 continue;
1515 }
1516#endif
1517 break;
1518#endif
1519#if LJ_NEED_FP64
1520 case IR_CONV:
1521 if (irt_isfp((ir-1)->t)) {
1522 ir->prev = REGSP_HINT(RID_FPRET);
1523 continue;
1524 }
1525 /* fallthrough */
1526#endif
1527 case IR_CALLN: case IR_CALLXS:
1528#if LJ_SOFTFP
1529 case IR_MIN: case IR_MAX:
1530#endif
1531#if LJ_BE
1532 (ir-1)->prev = REGSP_HINT(RID_RETLO);
1533#endif
1534 ir->prev = REGSP_HINT(RID_RETHI);
1535 continue;
1536 default:
1537 break;
1538 }
1539 break;
1540#endif
1541#if LJ_SOFTFP
1542 case IR_MIN: case IR_MAX:
1543 if ((ir+1)->o != IR_HIOP) break;
1544 /* fallthrough */
1545#endif
1546 /* C calls evict all scratch regs and return results in RID_RET. */
1547 case IR_SNEW: case IR_XSNEW: case IR_NEWREF:
1548 if (REGARG_NUMGPR < 3 && as->evenspill < 3)
1549 as->evenspill = 3; /* lj_str_new and lj_tab_newkey need 3 args. */
1550 case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR:
1551 ir->prev = REGSP_HINT(RID_RET);
1552 if (inloop)
1553 as->modset = RSET_SCRATCH;
1554 continue;
1555 case IR_STRTO: case IR_OBAR:
1556 if (inloop)
1557 as->modset = RSET_SCRATCH;
1558 break;
1559#if !LJ_TARGET_X86ORX64 && !LJ_SOFTFP
1560 case IR_ATAN2: case IR_LDEXP:
1561#endif
1562 case IR_POW:
1563 if (!LJ_SOFTFP && irt_isnum(ir->t)) {
1564#if LJ_TARGET_X86ORX64
1565 ir->prev = REGSP_HINT(RID_XMM0);
1566 if (inloop)
1567 as->modset |= RSET_RANGE(RID_XMM0, RID_XMM1+1)|RID2RSET(RID_EAX);
1568#else
1569 ir->prev = REGSP_HINT(RID_FPRET);
1570 if (inloop)
1571 as->modset |= RSET_SCRATCH;
1572#endif
1573 continue;
1574 }
1575 /* fallthrough for integer POW */
1576 case IR_DIV: case IR_MOD:
1577 if (!irt_isnum(ir->t)) {
1578 ir->prev = REGSP_HINT(RID_RET);
1579 if (inloop)
1580 as->modset |= (RSET_SCRATCH & RSET_GPR);
1581 continue;
1582 }
1583 break;
1584 case IR_FPMATH:
1585#if LJ_TARGET_X86ORX64
1586 if (ir->op2 == IRFPM_EXP2) { /* May be joined to lj_vm_pow_sse. */
1587 ir->prev = REGSP_HINT(RID_XMM0);
1588#if !LJ_64
1589 if (as->evenspill < 4) /* Leave room for 16 byte scratch area. */
1590 as->evenspill = 4;
1591#endif
1592 if (inloop)
1593 as->modset |= RSET_RANGE(RID_XMM0, RID_XMM2+1)|RID2RSET(RID_EAX);
1594 continue;
1595 } else if (ir->op2 <= IRFPM_TRUNC && !(as->flags & JIT_F_SSE4_1)) {
1596 ir->prev = REGSP_HINT(RID_XMM0);
1597 if (inloop)
1598 as->modset |= RSET_RANGE(RID_XMM0, RID_XMM3+1)|RID2RSET(RID_EAX);
1599 continue;
1600 }
1601 break;
1602#else
1603 ir->prev = REGSP_HINT(RID_FPRET);
1604 if (inloop)
1605 as->modset |= RSET_SCRATCH;
1606 continue;
1607#endif
1608#if LJ_TARGET_X86ORX64
1609 /* Non-constant shift counts need to be in RID_ECX on x86/x64. */
1610 case IR_BSHL: case IR_BSHR: case IR_BSAR: case IR_BROL: case IR_BROR:
1611 if (!irref_isk(ir->op2) && !ra_hashint(IR(ir->op2)->r)) {
1612 IR(ir->op2)->r = REGSP_HINT(RID_ECX);
1613 if (inloop)
1614 rset_set(as->modset, RID_ECX);
1615 }
1616 break;
1617#endif
1618 /* Do not propagate hints across type conversions. */
1619 case IR_TOBIT:
1620 break;
1621 case IR_CONV:
1622 if (irt_isfp(ir->t) || (ir->op2 & IRCONV_SRCMASK) == IRT_NUM ||
1623 (ir->op2 & IRCONV_SRCMASK) == IRT_FLOAT)
1624 break;
1625 /* fallthrough */
1626 default:
1627 /* Propagate hints across likely 'op reg, imm' or 'op reg'. */
1628 if (irref_isk(ir->op2) && !irref_isk(ir->op1)) {
1629 ir->prev = IR(ir->op1)->prev;
1630 continue;
1631 }
1632 break;
1633 }
1634 ir->prev = REGSP_INIT;
1635 }
1636 if ((as->evenspill & 1))
1637 as->oddspill = as->evenspill++;
1638 else
1639 as->oddspill = 0;
1640}
1641
1642/* -- Assembler core ------------------------------------------------------ */
1643
1644/* Assemble a trace. */
1645void lj_asm_trace(jit_State *J, GCtrace *T)
1646{
1647 ASMState as_;
1648 ASMState *as = &as_;
1649 MCode *origtop;
1650
1651 /* Ensure an initialized instruction beyond the last one for HIOP checks. */
1652 J->cur.nins = lj_ir_nextins(J);
1653 J->cur.ir[J->cur.nins].o = IR_NOP;
1654
1655 /* Setup initial state. Copy some fields to reduce indirections. */
1656 as->J = J;
1657 as->T = T;
1658 as->ir = T->ir;
1659 as->flags = J->flags;
1660 as->loopref = J->loopref;
1661 as->realign = NULL;
1662 as->loopinv = 0;
1663 if (J->parent) {
1664 as->parent = traceref(J, J->parent);
1665 lj_snap_regspmap(as->parentmap, as->parent, J->exitno, 0);
1666#if LJ_SOFTFP
1667 lj_snap_regspmap(as->parentmaphi, as->parent, J->exitno, 1);
1668#endif
1669 } else {
1670 as->parent = NULL;
1671 }
1672 /* Reserve MCode memory. */
1673 as->mctop = origtop = lj_mcode_reserve(J, &as->mcbot);
1674 as->mcp = as->mctop;
1675 as->mclim = as->mcbot + MCLIM_REDZONE;
1676 asm_setup_target(as);
1677
1678 do {
1679 as->mcp = as->mctop;
1680 as->curins = T->nins;
1681 RA_DBG_START();
1682 RA_DBGX((as, "===== STOP ====="));
1683
1684 /* General trace setup. Emit tail of trace. */
1685 asm_tail_prep(as);
1686 as->mcloop = NULL;
1687 as->flagmcp = NULL;
1688 as->topslot = 0;
1689 as->gcsteps = 0;
1690 as->sectref = as->loopref;
1691 as->fuseref = (as->flags & JIT_F_OPT_FUSE) ? as->loopref : FUSE_DISABLED;
1692 asm_setup_regsp(as);
1693 if (!as->loopref)
1694 asm_tail_link(as);
1695
1696 /* Assemble a trace in linear backwards order. */
1697 for (as->curins--; as->curins > as->stopins; as->curins--) {
1698 IRIns *ir = IR(as->curins);
1699 lua_assert(!(LJ_32 && irt_isint64(ir->t))); /* Handled by SPLIT. */
1700 if (!ra_used(ir) && !ir_sideeff(ir) && (as->flags & JIT_F_OPT_DCE))
1701 continue; /* Dead-code elimination can be soooo easy. */
1702 if (irt_isguard(ir->t))
1703 asm_snap_prep(as);
1704 RA_DBG_REF();
1705 checkmclim(as);
1706 asm_ir(as, ir);
1707 }
1708 } while (as->realign); /* Retry in case the MCode needs to be realigned. */
1709
1710 /* Emit head of trace. */
1711 RA_DBG_REF();
1712 checkmclim(as);
1713 if (as->gcsteps) {
1714 as->curins = as->T->snap[0].ref;
1715 asm_snap_prep(as); /* The GC check is a guard. */
1716 asm_gc_check(as);
1717 }
1718 ra_evictk(as);
1719 if (as->parent)
1720 asm_head_side(as);
1721 else
1722 asm_head_root(as);
1723 asm_phi_fixup(as);
1724
1725 RA_DBGX((as, "===== START ===="));
1726 RA_DBG_FLUSH();
1727 if (as->freeset != RSET_ALL)
1728 lj_trace_err(as->J, LJ_TRERR_BADRA); /* Ouch! Should never happen. */
1729
1730 /* Set trace entry point before fixing up tail to allow link to self. */
1731 T->mcode = as->mcp;
1732 T->mcloop = as->mcloop ? (MSize)((char *)as->mcloop - (char *)as->mcp) : 0;
1733 if (!as->loopref)
1734 asm_tail_fixup(as, T->link); /* Note: this may change as->mctop! */
1735 T->szmcode = (MSize)((char *)as->mctop - (char *)as->mcp);
1736 lj_mcode_sync(T->mcode, origtop);
1737}
1738
1739#undef IR
1740
1741#endif
diff --git a/libraries/luajit-2.0/src/lj_asm.h b/libraries/luajit-2.0/src/lj_asm.h
new file mode 100644
index 0000000..64240ef
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_asm.h
@@ -0,0 +1,17 @@
1/*
2** IR assembler (SSA IR -> machine code).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_ASM_H
7#define _LJ_ASM_H
8
9#include "lj_jit.h"
10
11#if LJ_HASJIT
12LJ_FUNC void lj_asm_trace(jit_State *J, GCtrace *T);
13LJ_FUNC void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno,
14 MCode *target);
15#endif
16
17#endif
diff --git a/libraries/luajit-2.0/src/lj_asm_arm.h b/libraries/luajit-2.0/src/lj_asm_arm.h
new file mode 100644
index 0000000..087fc0f
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_asm_arm.h
@@ -0,0 +1,1785 @@
1/*
2** ARM IR assembler (SSA IR -> machine code).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* -- Register allocator extensions --------------------------------------- */
7
8/* Allocate a register with a hint. */
9static Reg ra_hintalloc(ASMState *as, IRRef ref, Reg hint, RegSet allow)
10{
11 Reg r = IR(ref)->r;
12 if (ra_noreg(r)) {
13 if (!ra_hashint(r) && !iscrossref(as, ref))
14 ra_sethint(IR(ref)->r, hint); /* Propagate register hint. */
15 r = ra_allocref(as, ref, allow);
16 }
17 ra_noweak(as, r);
18 return r;
19}
20
21/* Allocate a scratch register pair. */
22static Reg ra_scratchpair(ASMState *as, RegSet allow)
23{
24 RegSet pick1 = as->freeset & allow;
25 RegSet pick2 = pick1 & (pick1 >> 1) & RSET_GPREVEN;
26 Reg r;
27 if (pick2) {
28 r = rset_picktop(pick2);
29 } else {
30 RegSet pick = pick1 & (allow >> 1) & RSET_GPREVEN;
31 if (pick) {
32 r = rset_picktop(pick);
33 ra_restore(as, regcost_ref(as->cost[r+1]));
34 } else {
35 pick = pick1 & (allow << 1) & RSET_GPRODD;
36 if (pick) {
37 r = ra_restore(as, regcost_ref(as->cost[rset_picktop(pick)-1]));
38 } else {
39 r = ra_evict(as, allow & (allow >> 1) & RSET_GPREVEN);
40 ra_restore(as, regcost_ref(as->cost[r+1]));
41 }
42 }
43 }
44 lua_assert(rset_test(RSET_GPREVEN, r));
45 ra_modified(as, r);
46 ra_modified(as, r+1);
47 RA_DBGX((as, "scratchpair $r $r", r, r+1));
48 return r;
49}
50
51/* -- Guard handling ------------------------------------------------------ */
52
53/* Generate an exit stub group at the bottom of the reserved MCode memory. */
54static MCode *asm_exitstub_gen(ASMState *as, ExitNo group)
55{
56 MCode *mxp = as->mcbot;
57 int i;
58 if (mxp + 4*4+4*EXITSTUBS_PER_GROUP >= as->mctop)
59 asm_mclimit(as);
60 /* str lr, [sp]; bl ->vm_exit_handler; .long DISPATCH_address, group. */
61 *mxp++ = ARMI_STR|ARMI_LS_P|ARMI_LS_U|ARMF_D(RID_LR)|ARMF_N(RID_SP);
62 *mxp = ARMI_BL|((((MCode *)(void *)lj_vm_exit_handler-mxp)-2)&0x00ffffffu);
63 mxp++;
64 *mxp++ = (MCode)i32ptr(J2GG(as->J)->dispatch); /* DISPATCH address */
65 *mxp++ = group*EXITSTUBS_PER_GROUP;
66 for (i = 0; i < EXITSTUBS_PER_GROUP; i++)
67 *mxp++ = ARMI_B|((-6-i)&0x00ffffffu);
68 lj_mcode_commitbot(as->J, mxp);
69 as->mcbot = mxp;
70 as->mclim = as->mcbot + MCLIM_REDZONE;
71 return mxp - EXITSTUBS_PER_GROUP;
72}
73
74/* Setup all needed exit stubs. */
75static void asm_exitstub_setup(ASMState *as, ExitNo nexits)
76{
77 ExitNo i;
78 if (nexits >= EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR)
79 lj_trace_err(as->J, LJ_TRERR_SNAPOV);
80 for (i = 0; i < (nexits+EXITSTUBS_PER_GROUP-1)/EXITSTUBS_PER_GROUP; i++)
81 if (as->J->exitstubgroup[i] == NULL)
82 as->J->exitstubgroup[i] = asm_exitstub_gen(as, i);
83}
84
85/* Emit conditional branch to exit for guard. */
86static void asm_guardcc(ASMState *as, ARMCC cc)
87{
88 MCode *target = exitstub_addr(as->J, as->snapno);
89 MCode *p = as->mcp;
90 if (LJ_UNLIKELY(p == as->invmcp)) {
91 as->loopinv = 1;
92 *p = ARMI_BL | ((target-p-2) & 0x00ffffffu);
93 emit_branch(as, ARMF_CC(ARMI_B, cc^1), p+1);
94 return;
95 }
96 emit_branch(as, ARMF_CC(ARMI_BL, cc), target);
97}
98
99/* -- Operand fusion ------------------------------------------------------ */
100
101/* Limit linear search to this distance. Avoids O(n^2) behavior. */
102#define CONFLICT_SEARCH_LIM 31
103
104/* Check if there's no conflicting instruction between curins and ref. */
105static int noconflict(ASMState *as, IRRef ref, IROp conflict)
106{
107 IRIns *ir = as->ir;
108 IRRef i = as->curins;
109 if (i > ref + CONFLICT_SEARCH_LIM)
110 return 0; /* Give up, ref is too far away. */
111 while (--i > ref)
112 if (ir[i].o == conflict)
113 return 0; /* Conflict found. */
114 return 1; /* Ok, no conflict. */
115}
116
117/* Fuse the array base of colocated arrays. */
118static int32_t asm_fuseabase(ASMState *as, IRRef ref)
119{
120 IRIns *ir = IR(ref);
121 if (ir->o == IR_TNEW && ir->op1 <= LJ_MAX_COLOSIZE &&
122 !neverfuse(as) && noconflict(as, ref, IR_NEWREF))
123 return (int32_t)sizeof(GCtab);
124 return 0;
125}
126
127/* Fuse array/hash/upvalue reference into register+offset operand. */
128static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow)
129{
130 IRIns *ir = IR(ref);
131 if (ra_noreg(ir->r)) {
132 if (ir->o == IR_AREF) {
133 if (mayfuse(as, ref)) {
134 if (irref_isk(ir->op2)) {
135 IRRef tab = IR(ir->op1)->op1;
136 int32_t ofs = asm_fuseabase(as, tab);
137 IRRef refa = ofs ? tab : ir->op1;
138 ofs += 8*IR(ir->op2)->i;
139 if (ofs > -4096 && ofs < 4096) {
140 *ofsp = ofs;
141 return ra_alloc1(as, refa, allow);
142 }
143 }
144 }
145 } else if (ir->o == IR_HREFK) {
146 if (mayfuse(as, ref)) {
147 int32_t ofs = (int32_t)(IR(ir->op2)->op2 * sizeof(Node));
148 if (ofs < 4096) {
149 *ofsp = ofs;
150 return ra_alloc1(as, ir->op1, allow);
151 }
152 }
153 } else if (ir->o == IR_UREFC) {
154 if (irref_isk(ir->op1)) {
155 GCfunc *fn = ir_kfunc(IR(ir->op1));
156 int32_t ofs = i32ptr(&gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.tv);
157 *ofsp = (ofs & 255); /* Mask out less bits to allow LDRD. */
158 return ra_allock(as, (ofs & ~255), allow);
159 }
160 }
161 }
162 *ofsp = 0;
163 return ra_alloc1(as, ref, allow);
164}
165
166/* Fuse m operand into arithmetic/logic instructions. */
167static uint32_t asm_fuseopm(ASMState *as, ARMIns ai, IRRef ref, RegSet allow)
168{
169 IRIns *ir = IR(ref);
170 if (ra_hasreg(ir->r)) {
171 ra_noweak(as, ir->r);
172 return ARMF_M(ir->r);
173 } else if (irref_isk(ref)) {
174 uint32_t k = emit_isk12(ai, ir->i);
175 if (k)
176 return k;
177 } else if (mayfuse(as, ref)) {
178 if (ir->o >= IR_BSHL && ir->o <= IR_BROR) {
179 Reg m = ra_alloc1(as, ir->op1, allow);
180 ARMShift sh = ir->o == IR_BSHL ? ARMSH_LSL :
181 ir->o == IR_BSHR ? ARMSH_LSR :
182 ir->o == IR_BSAR ? ARMSH_ASR : ARMSH_ROR;
183 if (irref_isk(ir->op2)) {
184 return m | ARMF_SH(sh, (IR(ir->op2)->i & 31));
185 } else {
186 Reg s = ra_alloc1(as, ir->op2, rset_exclude(allow, m));
187 return m | ARMF_RSH(sh, s);
188 }
189 } else if (ir->o == IR_ADD && ir->op1 == ir->op2) {
190 Reg m = ra_alloc1(as, ir->op1, allow);
191 return m | ARMF_SH(ARMSH_LSL, 1);
192 }
193 }
194 return ra_allocref(as, ref, allow);
195}
196
197/* Fuse shifts into loads/stores. Only bother with BSHL 2 => lsl #2. */
198static IRRef asm_fuselsl2(ASMState *as, IRRef ref)
199{
200 IRIns *ir = IR(ref);
201 if (ra_noreg(ir->r) && mayfuse(as, ref) && ir->o == IR_BSHL &&
202 irref_isk(ir->op2) && IR(ir->op2)->i == 2)
203 return ir->op1;
204 return 0; /* No fusion. */
205}
206
207/* Fuse XLOAD/XSTORE reference into load/store operand. */
208static void asm_fusexref(ASMState *as, ARMIns ai, Reg rd, IRRef ref,
209 RegSet allow)
210{
211 IRIns *ir = IR(ref);
212 int32_t ofs = 0;
213 Reg base;
214 if (ra_noreg(ir->r) && mayfuse(as, ref)) {
215 int32_t lim = (ai & 0x04000000) ? 4096 : 256;
216 if (ir->o == IR_ADD) {
217 if (irref_isk(ir->op2) && (ofs = IR(ir->op2)->i) > -lim && ofs < lim) {
218 ref = ir->op1;
219 } else {
220 IRRef lref = ir->op1, rref = ir->op2;
221 Reg rn, rm;
222 if ((ai & 0x04000000)) {
223 IRRef sref = asm_fuselsl2(as, rref);
224 if (sref) {
225 rref = sref;
226 ai |= ARMF_SH(ARMSH_LSL, 2);
227 } else if ((sref = asm_fuselsl2(as, lref)) != 0) {
228 lref = rref;
229 rref = sref;
230 ai |= ARMF_SH(ARMSH_LSL, 2);
231 }
232 }
233 rn = ra_alloc1(as, lref, allow);
234 rm = ra_alloc1(as, rref, rset_exclude(allow, rn));
235 if ((ai & 0x04000000)) ai |= ARMI_LS_R;
236 emit_dnm(as, ai|ARMI_LS_P|ARMI_LS_U, rd, rn, rm);
237 return;
238 }
239 } else if (ir->o == IR_STRREF) {
240 ofs = (int32_t)sizeof(GCstr);
241 if (irref_isk(ir->op2)) {
242 ofs += IR(ir->op2)->i;
243 ref = ir->op1;
244 } else if (irref_isk(ir->op1)) {
245 ofs += IR(ir->op1)->i;
246 ref = ir->op2;
247 } else {
248 /* NYI: Fuse ADD with constant. */
249 Reg rn = ra_alloc1(as, ir->op1, allow);
250 uint32_t m = asm_fuseopm(as, 0, ir->op2, rset_exclude(allow, rn));
251 if ((ai & 0x04000000))
252 emit_lso(as, ai, rd, rd, ofs);
253 else
254 emit_lsox(as, ai, rd, rd, ofs);
255 emit_dn(as, ARMI_ADD^m, rd, rn);
256 return;
257 }
258 if (ofs <= -lim || ofs >= lim) {
259 Reg rn = ra_alloc1(as, ref, allow);
260 Reg rm = ra_allock(as, ofs, rset_exclude(allow, rn));
261 if ((ai & 0x04000000)) ai |= ARMI_LS_R;
262 emit_dnm(as, ai|ARMI_LS_P|ARMI_LS_U, rd, rn, rm);
263 return;
264 }
265 }
266 }
267 base = ra_alloc1(as, ref, allow);
268 if ((ai & 0x04000000))
269 emit_lso(as, ai, rd, base, ofs);
270 else
271 emit_lsox(as, ai, rd, base, ofs);
272}
273
274/* -- Calls --------------------------------------------------------------- */
275
276/* Generate a call to a C function. */
277static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
278{
279 uint32_t n, nargs = CCI_NARGS(ci);
280 int32_t ofs = 0;
281 Reg gpr = REGARG_FIRSTGPR;
282 if ((void *)ci->func)
283 emit_call(as, (void *)ci->func);
284 for (n = 0; n < nargs; n++) { /* Setup args. */
285 IRRef ref = args[n];
286 IRIns *ir = IR(ref);
287 if (gpr <= REGARG_LASTGPR) {
288 lua_assert(rset_test(as->freeset, gpr)); /* Must have been evicted. */
289 if (ref) ra_leftov(as, gpr, ref);
290 gpr++;
291 } else {
292 if (ref) {
293 Reg r = ra_alloc1(as, ref, RSET_GPR);
294 emit_spstore(as, ir, r, ofs);
295 }
296 ofs += 4;
297 }
298 }
299}
300
301/* Setup result reg/sp for call. Evict scratch regs. */
302static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
303{
304 RegSet drop = RSET_SCRATCH;
305 int hiop = ((ir+1)->o == IR_HIOP);
306 if (ra_hasreg(ir->r))
307 rset_clear(drop, ir->r); /* Dest reg handled below. */
308 if (hiop && ra_hasreg((ir+1)->r))
309 rset_clear(drop, (ir+1)->r); /* Dest reg handled below. */
310 ra_evictset(as, drop); /* Evictions must be performed first. */
311 if (ra_used(ir)) {
312 lua_assert(!irt_ispri(ir->t));
313 if (hiop)
314 ra_destpair(as, ir);
315 else
316 ra_destreg(as, ir, RID_RET);
317 }
318 UNUSED(ci);
319}
320
321static void asm_call(ASMState *as, IRIns *ir)
322{
323 IRRef args[CCI_NARGS_MAX];
324 const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
325 asm_collectargs(as, ir, ci, args);
326 asm_setupresult(as, ir, ci);
327 asm_gencall(as, ci, args);
328}
329
330static void asm_callx(ASMState *as, IRIns *ir)
331{
332 IRRef args[CCI_NARGS_MAX];
333 CCallInfo ci;
334 IRRef func;
335 IRIns *irf;
336 ci.flags = asm_callx_flags(as, ir);
337 asm_collectargs(as, ir, &ci, args);
338 asm_setupresult(as, ir, &ci);
339 func = ir->op2; irf = IR(func);
340 if (irf->o == IR_CARG) { func = irf->op1; irf = IR(func); }
341 if (irref_isk(func)) { /* Call to constant address. */
342 ci.func = (ASMFunction)(void *)(irf->i);
343 } else { /* Need a non-argument register for indirect calls. */
344 Reg freg = ra_alloc1(as, func, RSET_RANGE(RID_R4, RID_R12+1));
345 emit_m(as, ARMI_BLXr, freg);
346 ci.func = (ASMFunction)(void *)0;
347 }
348 asm_gencall(as, &ci, args);
349}
350
351/* -- Returns ------------------------------------------------------------- */
352
353/* Return to lower frame. Guard that it goes to the right spot. */
354static void asm_retf(ASMState *as, IRIns *ir)
355{
356 Reg base = ra_alloc1(as, REF_BASE, RSET_GPR);
357 void *pc = ir_kptr(IR(ir->op2));
358 int32_t delta = 1+bc_a(*((const BCIns *)pc - 1));
359 as->topslot -= (BCReg)delta;
360 if ((int32_t)as->topslot < 0) as->topslot = 0;
361 /* Need to force a spill on REF_BASE now to update the stack slot. */
362 emit_lso(as, ARMI_STR, base, RID_SP, ra_spill(as, IR(REF_BASE)));
363 emit_setgl(as, base, jit_base);
364 emit_addptr(as, base, -8*delta);
365 asm_guardcc(as, CC_NE);
366 emit_nm(as, ARMI_CMP, RID_TMP,
367 ra_allock(as, i32ptr(pc), rset_exclude(RSET_GPR, base)));
368 emit_lso(as, ARMI_LDR, RID_TMP, base, -4);
369}
370
371/* -- Type conversions ---------------------------------------------------- */
372
373static void asm_conv(ASMState *as, IRIns *ir)
374{
375 Reg dest = ra_dest(as, ir, RSET_GPR);
376 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
377 /* FP conversions and 64 bit integer conversions are handled by SPLIT. */
378 lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));
379 lua_assert(!irt_isint64(ir->t) && !(st == IRT_I64 || st == IRT_U64));
380 if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */
381 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
382 lua_assert(irt_isint(ir->t) || irt_isu32(ir->t));
383 if ((as->flags & JIT_F_ARMV6)) {
384 ARMIns ai = st == IRT_I8 ? ARMI_SXTB :
385 st == IRT_U8 ? ARMI_UXTB :
386 st == IRT_I16 ? ARMI_SXTH : ARMI_UXTH;
387 emit_dm(as, ai, dest, left);
388 } else if (st == IRT_U8) {
389 emit_dn(as, ARMI_AND|ARMI_K12|255, dest, left);
390 } else {
391 uint32_t shift = st == IRT_I8 ? 24 : 16;
392 ARMShift sh = st == IRT_U16 ? ARMSH_LSR : ARMSH_ASR;
393 emit_dm(as, ARMI_MOV|ARMF_SH(sh, shift), dest, RID_TMP);
394 emit_dm(as, ARMI_MOV|ARMF_SH(ARMSH_LSL, shift), RID_TMP, left);
395 }
396 } else { /* Handle 32/32 bit no-op (cast). */
397 ra_leftov(as, dest, ir->op1); /* Do nothing, but may need to move regs. */
398 }
399}
400
401static void asm_strto(ASMState *as, IRIns *ir)
402{
403 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_tonum];
404 IRRef args[2];
405 Reg rlo = 0, rhi = 0, tmp;
406 int destused = ra_used(ir);
407 int32_t ofs = 0;
408 ra_evictset(as, RSET_SCRATCH);
409 if (destused) {
410 if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) &&
411 (ir->s & 1) == 0 && ir->s + 1 == (ir+1)->s) {
412 int i;
413 for (i = 0; i < 2; i++) {
414 Reg r = (ir+i)->r;
415 if (ra_hasreg(r)) {
416 ra_free(as, r);
417 ra_modified(as, r);
418 emit_spload(as, ir+i, r, sps_scale((ir+i)->s));
419 }
420 }
421 ofs = sps_scale(ir->s);
422 destused = 0;
423 } else {
424 rhi = ra_dest(as, ir+1, RSET_GPR);
425 rlo = ra_dest(as, ir, rset_exclude(RSET_GPR, rhi));
426 }
427 }
428 asm_guardcc(as, CC_EQ);
429 if (destused) {
430 emit_lso(as, ARMI_LDR, rhi, RID_SP, 4);
431 emit_lso(as, ARMI_LDR, rlo, RID_SP, 0);
432 }
433 emit_n(as, ARMI_CMP|ARMI_K12|0, RID_RET); /* Test return status. */
434 args[0] = ir->op1; /* GCstr *str */
435 args[1] = ASMREF_TMP1; /* TValue *n */
436 asm_gencall(as, ci, args);
437 tmp = ra_releasetmp(as, ASMREF_TMP1);
438 if (ofs == 0)
439 emit_dm(as, ARMI_MOV, tmp, RID_SP);
440 else
441 emit_opk(as, ARMI_ADD, tmp, RID_SP, ofs, RSET_GPR);
442}
443
444/* Get pointer to TValue. */
445static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
446{
447 IRIns *ir = IR(ref);
448 if (irt_isnum(ir->t)) { /* Use the number constant itself as a TValue. */
449 lua_assert(irref_isk(ref));
450 ra_allockreg(as, i32ptr(ir_knum(ir)), dest);
451 } else {
452 /* Otherwise use [sp] and [sp+4] to hold the TValue. */
453 RegSet allow = rset_exclude(RSET_GPR, dest);
454 Reg type;
455 emit_dm(as, ARMI_MOV, dest, RID_SP);
456 if (!irt_ispri(ir->t)) {
457 Reg src = ra_alloc1(as, ref, allow);
458 emit_lso(as, ARMI_STR, src, RID_SP, 0);
459 }
460 if ((ir+1)->o == IR_HIOP)
461 type = ra_alloc1(as, ref+1, allow);
462 else
463 type = ra_allock(as, irt_toitype(ir->t), allow);
464 emit_lso(as, ARMI_STR, type, RID_SP, 4);
465 }
466}
467
468static void asm_tostr(ASMState *as, IRIns *ir)
469{
470 IRRef args[2];
471 args[0] = ASMREF_L;
472 as->gcsteps++;
473 if (irt_isnum(IR(ir->op1)->t) || (ir+1)->o == IR_HIOP) {
474 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum];
475 args[1] = ASMREF_TMP1; /* const lua_Number * */
476 asm_setupresult(as, ir, ci); /* GCstr * */
477 asm_gencall(as, ci, args);
478 asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1);
479 } else {
480 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromint];
481 args[1] = ir->op1; /* int32_t k */
482 asm_setupresult(as, ir, ci); /* GCstr * */
483 asm_gencall(as, ci, args);
484 }
485}
486
487/* -- Memory references --------------------------------------------------- */
488
489static void asm_aref(ASMState *as, IRIns *ir)
490{
491 Reg dest = ra_dest(as, ir, RSET_GPR);
492 Reg idx, base;
493 if (irref_isk(ir->op2)) {
494 IRRef tab = IR(ir->op1)->op1;
495 int32_t ofs = asm_fuseabase(as, tab);
496 IRRef refa = ofs ? tab : ir->op1;
497 uint32_t k = emit_isk12(ARMI_ADD, ofs + 8*IR(ir->op2)->i);
498 if (k) {
499 base = ra_alloc1(as, refa, RSET_GPR);
500 emit_dn(as, ARMI_ADD^k, dest, base);
501 return;
502 }
503 }
504 base = ra_alloc1(as, ir->op1, RSET_GPR);
505 idx = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, base));
506 emit_dnm(as, ARMI_ADD|ARMF_SH(ARMSH_LSL, 3), dest, base, idx);
507}
508
509/* Inlined hash lookup. Specialized for key type and for const keys.
510** The equivalent C code is:
511** Node *n = hashkey(t, key);
512** do {
513** if (lj_obj_equal(&n->key, key)) return &n->val;
514** } while ((n = nextnode(n)));
515** return niltv(L);
516*/
517static void asm_href(ASMState *as, IRIns *ir, IROp merge)
518{
519 RegSet allow = RSET_GPR;
520 int destused = ra_used(ir);
521 Reg dest = ra_dest(as, ir, allow);
522 Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
523 Reg key = 0, keyhi = 0, keynumhi = RID_NONE, tmp = RID_TMP;
524 IRRef refkey = ir->op2;
525 IRIns *irkey = IR(refkey);
526 IRType1 kt = irkey->t;
527 int32_t k = 0, khi = emit_isk12(ARMI_CMP, irt_toitype(kt));
528 uint32_t khash;
529 MCLabel l_end, l_loop;
530 rset_clear(allow, tab);
531 if (!irref_isk(refkey) || irt_isstr(kt)) {
532 key = ra_alloc1(as, refkey, allow);
533 rset_clear(allow, key);
534 if (irkey[1].o == IR_HIOP) {
535 if (ra_hasreg((irkey+1)->r)) {
536 keynumhi = (irkey+1)->r;
537 keyhi = RID_TMP;
538 ra_noweak(as, keynumhi);
539 } else {
540 keyhi = keynumhi = ra_allocref(as, refkey+1, allow);
541 }
542 rset_clear(allow, keynumhi);
543 khi = 0;
544 }
545 } else if (irt_isnum(kt)) {
546 int32_t val = (int32_t)ir_knum(irkey)->u32.lo;
547 k = emit_isk12(ARMI_CMP, val);
548 if (!k) {
549 key = ra_allock(as, val, allow);
550 rset_clear(allow, key);
551 }
552 val = (int32_t)ir_knum(irkey)->u32.hi;
553 khi = emit_isk12(ARMI_CMP, val);
554 if (!khi) {
555 keyhi = ra_allock(as, val, allow);
556 rset_clear(allow, keyhi);
557 }
558 } else if (!irt_ispri(kt)) {
559 k = emit_isk12(ARMI_CMP, irkey->i);
560 if (!k) {
561 key = ra_alloc1(as, refkey, allow);
562 rset_clear(allow, key);
563 }
564 }
565 if (!irt_ispri(kt))
566 tmp = ra_scratchpair(as, allow);
567
568 /* Key not found in chain: jump to exit (if merged) or load niltv. */
569 l_end = emit_label(as);
570 as->invmcp = NULL;
571 if (merge == IR_NE)
572 asm_guardcc(as, CC_AL);
573 else if (destused)
574 emit_loada(as, dest, niltvg(J2G(as->J)));
575
576 /* Follow hash chain until the end. */
577 l_loop = --as->mcp;
578 emit_n(as, ARMI_CMP|ARMI_K12|0, dest);
579 emit_lso(as, ARMI_LDR, dest, dest, (int32_t)offsetof(Node, next));
580
581 /* Type and value comparison. */
582 if (merge == IR_EQ)
583 asm_guardcc(as, CC_EQ);
584 else
585 emit_branch(as, ARMF_CC(ARMI_B, CC_EQ), l_end);
586 if (!irt_ispri(kt)) {
587 emit_nm(as, ARMF_CC(ARMI_CMP, CC_EQ)^khi, tmp+1, keyhi);
588 emit_nm(as, ARMI_CMP^k, tmp, key);
589 emit_lsox(as, ARMI_LDRD, tmp, dest, (int32_t)offsetof(Node, key));
590 } else {
591 emit_n(as, ARMI_CMP^khi, tmp);
592 emit_lso(as, ARMI_LDR, tmp, dest, (int32_t)offsetof(Node, key.it));
593 }
594 *l_loop = ARMF_CC(ARMI_B, CC_NE) | ((as->mcp-l_loop-2) & 0x00ffffffu);
595
596 /* Load main position relative to tab->node into dest. */
597 khash = irref_isk(refkey) ? ir_khash(irkey) : 1;
598 if (khash == 0) {
599 emit_lso(as, ARMI_LDR, dest, tab, (int32_t)offsetof(GCtab, node));
600 } else {
601 emit_dnm(as, ARMI_ADD|ARMF_SH(ARMSH_LSL, 3), dest, dest, tmp);
602 emit_dnm(as, ARMI_ADD|ARMF_SH(ARMSH_LSL, 1), tmp, tmp, tmp);
603 if (irt_isstr(kt)) { /* Fetch of str->hash is cheaper than ra_allock. */
604 emit_dnm(as, ARMI_AND, tmp, tmp+1, RID_TMP);
605 emit_lso(as, ARMI_LDR, dest, tab, (int32_t)offsetof(GCtab, node));
606 emit_lso(as, ARMI_LDR, tmp+1, key, (int32_t)offsetof(GCstr, hash));
607 emit_lso(as, ARMI_LDR, RID_TMP, tab, (int32_t)offsetof(GCtab, hmask));
608 } else if (irref_isk(refkey)) {
609 emit_opk(as, ARMI_AND, tmp, RID_TMP, (int32_t)khash,
610 rset_exclude(rset_exclude(RSET_GPR, tab), dest));
611 emit_lso(as, ARMI_LDR, dest, tab, (int32_t)offsetof(GCtab, node));
612 emit_lso(as, ARMI_LDR, RID_TMP, tab, (int32_t)offsetof(GCtab, hmask));
613 } else { /* Must match with hash*() in lj_tab.c. */
614 if (ra_hasreg(keynumhi)) { /* Canonicalize +-0.0 to 0.0. */
615 if (keyhi == RID_TMP)
616 emit_dm(as, ARMF_CC(ARMI_MOV, CC_NE), keyhi, keynumhi);
617 emit_d(as, ARMF_CC(ARMI_MOV, CC_EQ)|ARMI_K12|0, keyhi);
618 }
619 emit_dnm(as, ARMI_AND, tmp, tmp, RID_TMP);
620 emit_dnm(as, ARMI_SUB|ARMF_SH(ARMSH_ROR, 32-HASH_ROT3), tmp, tmp, tmp+1);
621 emit_lso(as, ARMI_LDR, dest, tab, (int32_t)offsetof(GCtab, node));
622 emit_dnm(as, ARMI_EOR|ARMF_SH(ARMSH_ROR, 32-((HASH_ROT2+HASH_ROT1)&31)),
623 tmp, tmp+1, tmp);
624 emit_lso(as, ARMI_LDR, RID_TMP, tab, (int32_t)offsetof(GCtab, hmask));
625 emit_dnm(as, ARMI_SUB|ARMF_SH(ARMSH_ROR, 32-HASH_ROT1), tmp+1, tmp+1, tmp);
626 if (ra_hasreg(keynumhi)) {
627 emit_dnm(as, ARMI_EOR, tmp+1, tmp, key);
628 emit_dnm(as, ARMI_ORR|ARMI_S, RID_TMP, tmp, key); /* Test for +-0.0. */
629 emit_dnm(as, ARMI_ADD, tmp, keynumhi, keynumhi);
630 } else {
631 emit_dnm(as, ARMI_EOR, tmp+1, tmp, key);
632 emit_opk(as, ARMI_ADD, tmp, key, (int32_t)HASH_BIAS,
633 rset_exclude(rset_exclude(RSET_GPR, tab), key));
634 }
635 }
636 }
637}
638
639static void asm_hrefk(ASMState *as, IRIns *ir)
640{
641 IRIns *kslot = IR(ir->op2);
642 IRIns *irkey = IR(kslot->op1);
643 int32_t ofs = (int32_t)(kslot->op2 * sizeof(Node));
644 int32_t kofs = ofs + (int32_t)offsetof(Node, key);
645 Reg dest = (ra_used(ir) || ofs > 4095) ? ra_dest(as, ir, RSET_GPR) : RID_NONE;
646 Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
647 Reg key = RID_NONE, type = RID_TMP, idx = node;
648 RegSet allow = rset_exclude(RSET_GPR, node);
649 lua_assert(ofs % sizeof(Node) == 0);
650 if (ofs > 4095) {
651 idx = dest;
652 rset_clear(allow, dest);
653 kofs = (int32_t)offsetof(Node, key);
654 } else if (ra_hasreg(dest)) {
655 emit_opk(as, ARMI_ADD, dest, node, ofs, allow);
656 }
657 asm_guardcc(as, CC_NE);
658 if (!irt_ispri(irkey->t)) {
659 RegSet even = (as->freeset & (as->freeset >> 1) & allow & RSET_GPREVEN);
660 if (even) {
661 key = ra_scratch(as, even);
662 if (rset_test(as->freeset, key+1)) {
663 type = key+1;
664 ra_modified(as, type);
665 }
666 } else {
667 key = ra_scratch(as, allow);
668 }
669 rset_clear(allow, key);
670 }
671 rset_clear(allow, type);
672 if (irt_isnum(irkey->t)) {
673 emit_opk(as, ARMF_CC(ARMI_CMP, CC_EQ), 0, type,
674 (int32_t)ir_knum(irkey)->u32.hi, allow);
675 emit_opk(as, ARMI_CMP, 0, key,
676 (int32_t)ir_knum(irkey)->u32.lo, allow);
677 } else if (ra_hasreg(key)) {
678 emit_n(as, ARMF_CC(ARMI_CMN, CC_EQ)|ARMI_K12|-irt_toitype(irkey->t), type);
679 emit_opk(as, ARMI_CMP, 0, key, irkey->i, allow);
680 } else {
681 emit_n(as, ARMI_CMN|ARMI_K12|-irt_toitype(irkey->t), type);
682 }
683 emit_lso(as, ARMI_LDR, type, idx, kofs+4);
684 if (ra_hasreg(key)) emit_lso(as, ARMI_LDR, key, idx, kofs);
685 if (ofs > 4095)
686 emit_opk(as, ARMI_ADD, dest, node, ofs, RSET_GPR);
687}
688
689static void asm_newref(ASMState *as, IRIns *ir)
690{
691 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_newkey];
692 IRRef args[3];
693 args[0] = ASMREF_L; /* lua_State *L */
694 args[1] = ir->op1; /* GCtab *t */
695 args[2] = ASMREF_TMP1; /* cTValue *key */
696 asm_setupresult(as, ir, ci); /* TValue * */
697 asm_gencall(as, ci, args);
698 asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2);
699}
700
701static void asm_uref(ASMState *as, IRIns *ir)
702{
703 /* NYI: Check that UREFO is still open and not aliasing a slot. */
704 Reg dest = ra_dest(as, ir, RSET_GPR);
705 if (irref_isk(ir->op1)) {
706 GCfunc *fn = ir_kfunc(IR(ir->op1));
707 MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v;
708 emit_lsptr(as, ARMI_LDR, dest, v);
709 } else {
710 Reg uv = ra_scratch(as, RSET_GPR);
711 Reg func = ra_alloc1(as, ir->op1, RSET_GPR);
712 if (ir->o == IR_UREFC) {
713 asm_guardcc(as, CC_NE);
714 emit_n(as, ARMI_CMP|ARMI_K12|1, RID_TMP);
715 emit_opk(as, ARMI_ADD, dest, uv,
716 (int32_t)offsetof(GCupval, tv), RSET_GPR);
717 emit_lso(as, ARMI_LDRB, RID_TMP, uv, (int32_t)offsetof(GCupval, closed));
718 } else {
719 emit_lso(as, ARMI_LDR, dest, uv, (int32_t)offsetof(GCupval, v));
720 }
721 emit_lso(as, ARMI_LDR, uv, func,
722 (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8));
723 }
724}
725
726static void asm_fref(ASMState *as, IRIns *ir)
727{
728 UNUSED(as); UNUSED(ir);
729 lua_assert(!ra_used(ir));
730}
731
732static void asm_strref(ASMState *as, IRIns *ir)
733{
734 Reg dest = ra_dest(as, ir, RSET_GPR);
735 IRRef ref = ir->op2, refk = ir->op1;
736 Reg r;
737 if (irref_isk(ref)) {
738 IRRef tmp = refk; refk = ref; ref = tmp;
739 } else if (!irref_isk(refk)) {
740 uint32_t k, m = ARMI_K12|sizeof(GCstr);
741 Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR);
742 IRIns *irr = IR(ir->op2);
743 if (ra_hasreg(irr->r)) {
744 ra_noweak(as, irr->r);
745 right = irr->r;
746 } else if (mayfuse(as, irr->op2) &&
747 irr->o == IR_ADD && irref_isk(irr->op2) &&
748 (k = emit_isk12(ARMI_ADD,
749 (int32_t)sizeof(GCstr) + IR(irr->op2)->i))) {
750 m = k;
751 right = ra_alloc1(as, irr->op1, rset_exclude(RSET_GPR, left));
752 } else {
753 right = ra_allocref(as, ir->op2, rset_exclude(RSET_GPR, left));
754 }
755 emit_dn(as, ARMI_ADD^m, dest, dest);
756 emit_dnm(as, ARMI_ADD, dest, left, right);
757 return;
758 }
759 r = ra_alloc1(as, ref, RSET_GPR);
760 emit_opk(as, ARMI_ADD, dest, r,
761 sizeof(GCstr) + IR(refk)->i, rset_exclude(RSET_GPR, r));
762}
763
764/* -- Loads and stores ---------------------------------------------------- */
765
766static ARMIns asm_fxloadins(IRIns *ir)
767{
768 switch (irt_type(ir->t)) {
769 case IRT_I8: return ARMI_LDRSB;
770 case IRT_U8: return ARMI_LDRB;
771 case IRT_I16: return ARMI_LDRSH;
772 case IRT_U16: return ARMI_LDRH;
773 case IRT_NUM: lua_assert(0);
774 case IRT_FLOAT:
775 default: return ARMI_LDR;
776 }
777}
778
779static ARMIns asm_fxstoreins(IRIns *ir)
780{
781 switch (irt_type(ir->t)) {
782 case IRT_I8: case IRT_U8: return ARMI_STRB;
783 case IRT_I16: case IRT_U16: return ARMI_STRH;
784 case IRT_NUM: lua_assert(0);
785 case IRT_FLOAT:
786 default: return ARMI_STR;
787 }
788}
789
790static void asm_fload(ASMState *as, IRIns *ir)
791{
792 Reg dest = ra_dest(as, ir, RSET_GPR);
793 Reg idx = ra_alloc1(as, ir->op1, RSET_GPR);
794 ARMIns ai = asm_fxloadins(ir);
795 int32_t ofs;
796 if (ir->op2 == IRFL_TAB_ARRAY) {
797 ofs = asm_fuseabase(as, ir->op1);
798 if (ofs) { /* Turn the t->array load into an add for colocated arrays. */
799 emit_dn(as, ARMI_ADD|ARMI_K12|ofs, dest, idx);
800 return;
801 }
802 }
803 ofs = field_ofs[ir->op2];
804 if ((ai & 0x04000000))
805 emit_lso(as, ai, dest, idx, ofs);
806 else
807 emit_lsox(as, ai, dest, idx, ofs);
808}
809
810static void asm_fstore(ASMState *as, IRIns *ir)
811{
812 Reg src = ra_alloc1(as, ir->op2, RSET_GPR);
813 IRIns *irf = IR(ir->op1);
814 Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
815 int32_t ofs = field_ofs[irf->op2];
816 ARMIns ai = asm_fxstoreins(ir);
817 if ((ai & 0x04000000))
818 emit_lso(as, ai, src, idx, ofs);
819 else
820 emit_lsox(as, ai, src, idx, ofs);
821}
822
823static void asm_xload(ASMState *as, IRIns *ir)
824{
825 Reg dest = ra_dest(as, ir, RSET_GPR);
826 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
827 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR);
828}
829
830static void asm_xstore(ASMState *as, IRIns *ir)
831{
832 Reg src = ra_alloc1(as, ir->op2, RSET_GPR);
833 asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
834 rset_exclude(RSET_GPR, src));
835}
836
837static void asm_ahuvload(ASMState *as, IRIns *ir)
838{
839 int hiop = ((ir+1)->o == IR_HIOP);
840 IRType t = hiop ? IRT_NUM : irt_type(ir->t);
841 Reg dest = RID_NONE, type = RID_NONE, idx;
842 RegSet allow = RSET_GPR;
843 int32_t ofs = 0;
844 if (hiop && ra_used(ir+1)) {
845 type = ra_dest(as, ir+1, allow);
846 rset_clear(allow, type);
847 }
848 if (ra_used(ir)) {
849 lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t));
850 dest = ra_dest(as, ir, allow);
851 rset_clear(allow, dest);
852 }
853 idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
854 if (!hiop || type == RID_NONE) {
855 rset_clear(allow, idx);
856 if (ofs < 256 && ra_hasreg(dest) && (dest & 1) == 0 &&
857 rset_test((as->freeset & allow), dest+1)) {
858 type = dest+1;
859 ra_modified(as, type);
860 } else {
861 type = RID_TMP;
862 }
863 }
864 asm_guardcc(as, t == IRT_NUM ? CC_HS : CC_NE);
865 emit_n(as, ARMI_CMN|ARMI_K12|-irt_toitype_(t), type);
866 if (ra_hasreg(dest)) emit_lso(as, ARMI_LDR, dest, idx, ofs);
867 emit_lso(as, ARMI_LDR, type, idx, ofs+4);
868}
869
870static void asm_ahustore(ASMState *as, IRIns *ir)
871{
872 RegSet allow = RSET_GPR;
873 Reg idx, src = RID_NONE, type = RID_NONE;
874 int32_t ofs = 0;
875 int hiop = ((ir+1)->o == IR_HIOP);
876 if (!irt_ispri(ir->t)) {
877 src = ra_alloc1(as, ir->op2, allow);
878 rset_clear(allow, src);
879 }
880 if (hiop)
881 type = ra_alloc1(as, (ir+1)->op2, allow);
882 else
883 type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
884 idx = asm_fuseahuref(as, ir->op1, &ofs, rset_exclude(allow, type));
885 if (ra_hasreg(src)) emit_lso(as, ARMI_STR, src, idx, ofs);
886 emit_lso(as, ARMI_STR, type, idx, ofs+4);
887}
888
889static void asm_sload(ASMState *as, IRIns *ir)
890{
891 int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0);
892 int hiop = ((ir+1)->o == IR_HIOP);
893 IRType t = hiop ? IRT_NUM : irt_type(ir->t);
894 Reg dest = RID_NONE, type = RID_NONE, base;
895 RegSet allow = RSET_GPR;
896 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
897 lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));
898 lua_assert(!(ir->op2 & IRSLOAD_CONVERT)); /* Handled by LJ_SOFTFP SPLIT. */
899 if (hiop && ra_used(ir+1)) {
900 type = ra_dest(as, ir+1, allow);
901 rset_clear(allow, type);
902 }
903 if (ra_used(ir)) {
904 lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t));
905 dest = ra_dest(as, ir, allow);
906 rset_clear(allow, dest);
907 }
908 base = ra_alloc1(as, REF_BASE, allow);
909 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
910 if (ra_noreg(type)) {
911 rset_clear(allow, base);
912 if (ofs < 256 && ra_hasreg(dest) && (dest & 1) == 0 &&
913 rset_test((as->freeset & allow), dest+1)) {
914 type = dest+1;
915 ra_modified(as, type);
916 } else {
917 type = RID_TMP;
918 }
919 }
920 asm_guardcc(as, t == IRT_NUM ? CC_HS : CC_NE);
921 emit_n(as, ARMI_CMN|ARMI_K12|-irt_toitype_(t), type);
922 }
923 if (ra_hasreg(dest)) emit_lso(as, ARMI_LDR, dest, base, ofs);
924 if (ra_hasreg(type)) emit_lso(as, ARMI_LDR, type, base, ofs+4);
925}
926
927/* -- Allocations --------------------------------------------------------- */
928
929#if LJ_HASFFI
930static void asm_cnew(ASMState *as, IRIns *ir)
931{
932 CTState *cts = ctype_ctsG(J2G(as->J));
933 CTypeID typeid = (CTypeID)IR(ir->op1)->i;
934 CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ?
935 lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i;
936 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
937 IRRef args[2];
938 RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
939 RegSet drop = RSET_SCRATCH;
940 lua_assert(sz != CTSIZE_INVALID);
941
942 args[0] = ASMREF_L; /* lua_State *L */
943 args[1] = ASMREF_TMP1; /* MSize size */
944 as->gcsteps++;
945
946 if (ra_hasreg(ir->r))
947 rset_clear(drop, ir->r); /* Dest reg handled below. */
948 ra_evictset(as, drop);
949 if (ra_used(ir))
950 ra_destreg(as, ir, RID_RET); /* GCcdata * */
951
952 /* Initialize immutable cdata object. */
953 if (ir->o == IR_CNEWI) {
954 int32_t ofs = sizeof(GCcdata);
955 lua_assert(sz == 4 || sz == 8);
956 if (sz == 8) {
957 ofs += 4; ir++;
958 lua_assert(ir->o == IR_HIOP);
959 }
960 for (;;) {
961 Reg r = ra_alloc1(as, ir->op2, allow);
962 emit_lso(as, ARMI_STR, r, RID_RET, ofs);
963 rset_clear(allow, r);
964 if (ofs == sizeof(GCcdata)) break;
965 ofs -= 4; ir--;
966 }
967 }
968 /* Initialize gct and typeid. lj_mem_newgco() already sets marked. */
969 {
970 uint32_t k = emit_isk12(ARMI_MOV, typeid);
971 Reg r = k ? RID_R1 : ra_allock(as, typeid, allow);
972 emit_lso(as, ARMI_STRB, RID_TMP, RID_RET, offsetof(GCcdata, gct));
973 emit_lsox(as, ARMI_STRH, r, RID_RET, offsetof(GCcdata, typeid));
974 emit_d(as, ARMI_MOV|ARMI_K12|~LJ_TCDATA, RID_TMP);
975 if (k) emit_d(as, ARMI_MOV^k, RID_R1);
976 }
977 asm_gencall(as, ci, args);
978 ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
979 ra_releasetmp(as, ASMREF_TMP1));
980}
981#else
982#define asm_cnew(as, ir) ((void)0)
983#endif
984
985/* -- Write barriers ------------------------------------------------------ */
986
987static void asm_tbar(ASMState *as, IRIns *ir)
988{
989 Reg tab = ra_alloc1(as, ir->op1, RSET_GPR);
990 Reg link = ra_scratch(as, rset_exclude(RSET_GPR, tab));
991 Reg gr = ra_allock(as, i32ptr(J2G(as->J)),
992 rset_exclude(rset_exclude(RSET_GPR, tab), link));
993 Reg mark = RID_TMP;
994 MCLabel l_end = emit_label(as);
995 emit_lso(as, ARMI_STR, link, tab, (int32_t)offsetof(GCtab, gclist));
996 emit_lso(as, ARMI_STRB, mark, tab, (int32_t)offsetof(GCtab, marked));
997 emit_lso(as, ARMI_STR, tab, gr,
998 (int32_t)offsetof(global_State, gc.grayagain));
999 emit_dn(as, ARMI_BIC|ARMI_K12|LJ_GC_BLACK, mark, mark);
1000 emit_lso(as, ARMI_LDR, link, gr,
1001 (int32_t)offsetof(global_State, gc.grayagain));
1002 emit_branch(as, ARMF_CC(ARMI_B, CC_EQ), l_end);
1003 emit_n(as, ARMI_TST|ARMI_K12|LJ_GC_BLACK, mark);
1004 emit_lso(as, ARMI_LDRB, mark, tab, (int32_t)offsetof(GCtab, marked));
1005}
1006
1007static void asm_obar(ASMState *as, IRIns *ir)
1008{
1009 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_gc_barrieruv];
1010 IRRef args[2];
1011 MCLabel l_end;
1012 Reg obj, val, tmp;
1013 /* No need for other object barriers (yet). */
1014 lua_assert(IR(ir->op1)->o == IR_UREFC);
1015 ra_evictset(as, RSET_SCRATCH);
1016 l_end = emit_label(as);
1017 args[0] = ASMREF_TMP1; /* global_State *g */
1018 args[1] = ir->op1; /* TValue *tv */
1019 asm_gencall(as, ci, args);
1020 if ((*as->mcp >> 28) == CC_AL)
1021 *as->mcp = ARMF_CC(*as->mcp, CC_NE);
1022 else
1023 emit_branch(as, ARMF_CC(ARMI_B, CC_EQ), l_end);
1024 ra_allockreg(as, i32ptr(J2G(as->J)), ra_releasetmp(as, ASMREF_TMP1));
1025 obj = IR(ir->op1)->r;
1026 tmp = ra_scratch(as, rset_exclude(RSET_GPR, obj));
1027 emit_n(as, ARMF_CC(ARMI_TST, CC_NE)|ARMI_K12|LJ_GC_BLACK, tmp);
1028 emit_n(as, ARMI_TST|ARMI_K12|LJ_GC_WHITES, RID_TMP);
1029 val = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, obj));
1030 emit_lso(as, ARMI_LDRB, tmp, obj,
1031 (int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv));
1032 emit_lso(as, ARMI_LDRB, RID_TMP, val, (int32_t)offsetof(GChead, marked));
1033}
1034
1035/* -- Arithmetic and logic operations ------------------------------------- */
1036
1037static int asm_swapops(ASMState *as, IRRef lref, IRRef rref)
1038{
1039 IRIns *ir;
1040 if (irref_isk(rref))
1041 return 0; /* Don't swap constants to the left. */
1042 if (irref_isk(lref))
1043 return 1; /* But swap constants to the right. */
1044 ir = IR(rref);
1045 if ((ir->o >= IR_BSHL && ir->o <= IR_BROR) ||
1046 (ir->o == IR_ADD && ir->op1 == ir->op2))
1047 return 0; /* Don't swap fusable operands to the left. */
1048 ir = IR(lref);
1049 if ((ir->o >= IR_BSHL && ir->o <= IR_BROR) ||
1050 (ir->o == IR_ADD && ir->op1 == ir->op2))
1051 return 1; /* But swap fusable operands to the right. */
1052 return 0; /* Otherwise don't swap. */
1053}
1054
1055static void asm_intop(ASMState *as, IRIns *ir, ARMIns ai)
1056{
1057 IRRef lref = ir->op1, rref = ir->op2;
1058 Reg left, dest = ra_dest(as, ir, RSET_GPR);
1059 uint32_t m;
1060 if (asm_swapops(as, lref, rref)) {
1061 IRRef tmp = lref; lref = rref; rref = tmp;
1062 if ((ai & ~ARMI_S) == ARMI_SUB || (ai & ~ARMI_S) == ARMI_SBC)
1063 ai ^= (ARMI_SUB^ARMI_RSB);
1064 }
1065 left = ra_hintalloc(as, lref, dest, RSET_GPR);
1066 m = asm_fuseopm(as, ai, rref, rset_exclude(RSET_GPR, left));
1067 if (irt_isguard(ir->t)) { /* For IR_ADDOV etc. */
1068 asm_guardcc(as, CC_VS);
1069 ai |= ARMI_S;
1070 }
1071 emit_dn(as, ai^m, dest, left);
1072}
1073
1074static void asm_bitop(ASMState *as, IRIns *ir, ARMIns ai)
1075{
1076 if (as->flagmcp == as->mcp) { /* Try to drop cmp r, #0. */
1077 uint32_t cc = (as->mcp[1] >> 28);
1078 as->flagmcp = NULL;
1079 if (cc <= CC_NE) {
1080 as->mcp++;
1081 ai |= ARMI_S;
1082 } else if (cc == CC_GE) {
1083 *++as->mcp ^= ((CC_GE^CC_PL) << 28);
1084 ai |= ARMI_S;
1085 } else if (cc == CC_LT) {
1086 *++as->mcp ^= ((CC_LT^CC_MI) << 28);
1087 ai |= ARMI_S;
1088 } /* else: other conds don't work with bit ops. */
1089 }
1090 if (ir->op2 == 0) {
1091 Reg dest = ra_dest(as, ir, RSET_GPR);
1092 uint32_t m = asm_fuseopm(as, ai, ir->op1, RSET_GPR);
1093 emit_d(as, ai^m, dest);
1094 } else {
1095 /* NYI: Turn BAND !k12 into uxtb, uxth or bfc or shl+shr. */
1096 asm_intop(as, ir, ai);
1097 }
1098}
1099
1100static void asm_arithop(ASMState *as, IRIns *ir, ARMIns ai)
1101{
1102 if (as->flagmcp == as->mcp) { /* Drop cmp r, #0. */
1103 as->flagmcp = NULL;
1104 as->mcp++;
1105 ai |= ARMI_S;
1106 }
1107 asm_intop(as, ir, ai);
1108}
1109
1110static void asm_intneg(ASMState *as, IRIns *ir, ARMIns ai)
1111{
1112 Reg dest = ra_dest(as, ir, RSET_GPR);
1113 Reg left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1114 emit_dn(as, ai|ARMI_K12|0, dest, left);
1115}
1116
1117/* NYI: use add/shift for MUL(OV) with constants. FOLD only does 2^k. */
1118static void asm_intmul(ASMState *as, IRIns *ir)
1119{
1120 Reg dest = ra_dest(as, ir, RSET_GPR);
1121 Reg left = ra_alloc1(as, ir->op1, rset_exclude(RSET_GPR, dest));
1122 Reg right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1123 Reg tmp = RID_NONE;
1124 /* ARMv5 restriction: dest != left and dest_hi != left. */
1125 if (dest == left && left != right) { left = right; right = dest; }
1126 if (irt_isguard(ir->t)) { /* IR_MULOV */
1127 if (!(as->flags & JIT_F_ARMV6) && dest == left)
1128 tmp = left = ra_scratch(as, rset_exclude(RSET_FPR, left));
1129 asm_guardcc(as, CC_NE);
1130 emit_nm(as, ARMI_TEQ|ARMF_SH(ARMSH_ASR, 31), RID_TMP, dest);
1131 emit_dnm(as, ARMI_SMULL|ARMF_S(right), dest, RID_TMP, left);
1132 } else {
1133 if (!(as->flags & JIT_F_ARMV6) && dest == left) tmp = left = RID_TMP;
1134 emit_nm(as, ARMI_MUL|ARMF_S(right), dest, left);
1135 }
1136 /* Only need this for the dest == left == right case. */
1137 if (ra_hasreg(tmp)) emit_dm(as, ARMI_MOV, tmp, right);
1138}
1139
1140static void asm_intmod(ASMState *as, IRIns *ir)
1141{
1142 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_vm_modi];
1143 IRRef args[2];
1144 args[0] = ir->op1;
1145 args[1] = ir->op2;
1146 asm_setupresult(as, ir, ci);
1147 asm_gencall(as, ci, args);
1148}
1149
1150static void asm_bitswap(ASMState *as, IRIns *ir)
1151{
1152 Reg dest = ra_dest(as, ir, RSET_GPR);
1153 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
1154 if ((as->flags & JIT_F_ARMV6)) {
1155 emit_dm(as, ARMI_REV, dest, left);
1156 } else {
1157 Reg tmp2 = dest;
1158 if (tmp2 == left)
1159 tmp2 = ra_scratch(as, rset_exclude(rset_exclude(RSET_GPR, dest), left));
1160 emit_dnm(as, ARMI_EOR|ARMF_SH(ARMSH_LSR, 8), dest, tmp2, RID_TMP);
1161 emit_dm(as, ARMI_MOV|ARMF_SH(ARMSH_ROR, 8), tmp2, left);
1162 emit_dn(as, ARMI_BIC|ARMI_K12|256*8|255, RID_TMP, RID_TMP);
1163 emit_dnm(as, ARMI_EOR|ARMF_SH(ARMSH_ROR, 16), RID_TMP, left, left);
1164 }
1165}
1166
1167static void asm_bitshift(ASMState *as, IRIns *ir, ARMShift sh)
1168{
1169 if (irref_isk(ir->op2)) { /* Constant shifts. */
1170 /* NYI: Turn SHL+SHR or BAND+SHR into uxtb, uxth or ubfx. */
1171 /* NYI: Turn SHL+ASR into sxtb, sxth or sbfx. */
1172 Reg dest = ra_dest(as, ir, RSET_GPR);
1173 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
1174 int32_t shift = (IR(ir->op2)->i & 31);
1175 emit_dm(as, ARMI_MOV|ARMF_SH(sh, shift), dest, left);
1176 } else {
1177 Reg dest = ra_dest(as, ir, RSET_GPR);
1178 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
1179 Reg right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1180 emit_dm(as, ARMI_MOV|ARMF_RSH(sh, right), dest, left);
1181 }
1182}
1183
1184static void asm_intmin_max(ASMState *as, IRIns *ir, int cc)
1185{
1186 uint32_t kcmp = 0, kmov = 0;
1187 Reg dest = ra_dest(as, ir, RSET_GPR);
1188 Reg left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1189 Reg right = 0;
1190 if (irref_isk(ir->op2)) {
1191 kcmp = emit_isk12(ARMI_CMP, IR(ir->op2)->i);
1192 if (kcmp) kmov = emit_isk12(ARMI_MOV, IR(ir->op2)->i);
1193 }
1194 if (!kmov) {
1195 kcmp = 0;
1196 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1197 }
1198 if (dest != right) {
1199 emit_dm(as, ARMF_CC(ARMI_MOV, cc)^kmov, dest, right);
1200 cc ^= 1; /* Must use opposite conditions for paired moves. */
1201 } else {
1202 cc ^= (CC_LT^CC_GT); /* Otherwise may swap CC_LT <-> CC_GT. */
1203 }
1204 if (dest != left) emit_dm(as, ARMF_CC(ARMI_MOV, cc)^kmov, dest, left);
1205 emit_nm(as, ARMI_CMP^kcmp, left, right);
1206}
1207
1208static void asm_fpmin_max(ASMState *as, IRIns *ir, int cc)
1209{
1210 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp];
1211 RegSet drop = RSET_SCRATCH;
1212 Reg r;
1213 IRRef args[4];
1214 args[0] = ir->op1; args[1] = (ir+1)->op1;
1215 args[2] = ir->op2; args[3] = (ir+1)->op2;
1216 /* __aeabi_cdcmple preserves r0-r3. */
1217 if (ra_hasreg(ir->r)) rset_clear(drop, ir->r);
1218 if (ra_hasreg((ir+1)->r)) rset_clear(drop, (ir+1)->r);
1219 if (!rset_test(as->freeset, RID_R2) &&
1220 regcost_ref(as->cost[RID_R2]) == args[2]) rset_clear(drop, RID_R2);
1221 if (!rset_test(as->freeset, RID_R3) &&
1222 regcost_ref(as->cost[RID_R3]) == args[3]) rset_clear(drop, RID_R3);
1223 ra_evictset(as, drop);
1224 ra_destpair(as, ir);
1225 emit_dm(as, ARMF_CC(ARMI_MOV, cc), RID_RETHI, RID_R3);
1226 emit_dm(as, ARMF_CC(ARMI_MOV, cc), RID_RETLO, RID_R2);
1227 emit_call(as, (void *)ci->func);
1228 for (r = RID_R0; r <= RID_R3; r++)
1229 ra_leftov(as, r, args[r-RID_R0]);
1230}
1231
1232/* -- Comparisons --------------------------------------------------------- */
1233
1234/* Map of comparisons to flags. ORDER IR. */
1235static const uint8_t asm_compmap[IR_ABC+1] = {
1236 /* op FP swp int cc FP cc */
1237 /* LT */ CC_GE + (CC_HS << 4),
1238 /* GE x */ CC_LT + (CC_HI << 4),
1239 /* LE */ CC_GT + (CC_HI << 4),
1240 /* GT x */ CC_LE + (CC_HS << 4),
1241 /* ULT x */ CC_HS + (CC_LS << 4),
1242 /* UGE */ CC_LO + (CC_LO << 4),
1243 /* ULE x */ CC_HI + (CC_LO << 4),
1244 /* UGT */ CC_LS + (CC_LS << 4),
1245 /* EQ */ CC_NE + (CC_NE << 4),
1246 /* NE */ CC_EQ + (CC_EQ << 4),
1247 /* ABC */ CC_LS + (CC_LS << 4) /* Same as UGT. */
1248};
1249
1250/* FP comparisons. */
1251static void asm_fpcomp(ASMState *as, IRIns *ir)
1252{
1253 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp];
1254 RegSet drop = RSET_SCRATCH;
1255 Reg r;
1256 IRRef args[4];
1257 int swp = (((ir->o ^ (ir->o >> 2)) & ~(ir->o >> 3) & 1) << 1);
1258 args[swp^0] = ir->op1; args[swp^1] = (ir+1)->op1;
1259 args[swp^2] = ir->op2; args[swp^3] = (ir+1)->op2;
1260 /* __aeabi_cdcmple preserves r0-r3. This helps to reduce spills. */
1261 for (r = RID_R0; r <= RID_R3; r++)
1262 if (!rset_test(as->freeset, r) &&
1263 regcost_ref(as->cost[r]) == args[r-RID_R0]) rset_clear(drop, r);
1264 ra_evictset(as, drop);
1265 asm_guardcc(as, (asm_compmap[ir->o] >> 4));
1266 emit_call(as, (void *)ci->func);
1267 for (r = RID_R0; r <= RID_R3; r++)
1268 ra_leftov(as, r, args[r-RID_R0]);
1269}
1270
1271/* Integer comparisons. */
1272static void asm_intcomp(ASMState *as, IRIns *ir)
1273{
1274 ARMCC cc = (asm_compmap[ir->o] & 15);
1275 IRRef lref = ir->op1, rref = ir->op2;
1276 Reg left;
1277 uint32_t m;
1278 int cmpprev0 = 0;
1279 lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t));
1280 if (asm_swapops(as, lref, rref)) {
1281 Reg tmp = lref; lref = rref; rref = tmp;
1282 if (cc >= CC_GE) cc ^= 7; /* LT <-> GT, LE <-> GE */
1283 else if (cc > CC_NE) cc ^= 11; /* LO <-> HI, LS <-> HS */
1284 }
1285 if (irref_isk(rref) && IR(rref)->i == 0) {
1286 IRIns *irl = IR(lref);
1287 cmpprev0 = (irl+1 == ir);
1288 /* Combine comp(BAND(left, right), 0) into tst left, right. */
1289 if (cmpprev0 && irl->o == IR_BAND && !ra_used(irl)) {
1290 IRRef blref = irl->op1, brref = irl->op2;
1291 uint32_t m2 = 0;
1292 Reg bleft;
1293 if (asm_swapops(as, blref, brref)) {
1294 Reg tmp = blref; blref = brref; brref = tmp;
1295 }
1296 if (irref_isk(brref)) {
1297 m2 = emit_isk12(ARMI_AND, IR(brref)->i);
1298 if ((m2 & (ARMI_AND^ARMI_BIC)))
1299 goto notst; /* Not beneficial if we miss a constant operand. */
1300 }
1301 if (cc == CC_GE) cc = CC_PL;
1302 else if (cc == CC_LT) cc = CC_MI;
1303 else if (cc > CC_NE) goto notst; /* Other conds don't work with tst. */
1304 bleft = ra_alloc1(as, blref, RSET_GPR);
1305 if (!m2) m2 = asm_fuseopm(as, 0, brref, rset_exclude(RSET_GPR, bleft));
1306 asm_guardcc(as, cc);
1307 emit_n(as, ARMI_TST^m2, bleft);
1308 return;
1309 }
1310 }
1311notst:
1312 left = ra_alloc1(as, lref, RSET_GPR);
1313 m = asm_fuseopm(as, ARMI_CMP, rref, rset_exclude(RSET_GPR, left));
1314 asm_guardcc(as, cc);
1315 emit_n(as, ARMI_CMP^m, left);
1316 /* Signed comparison with zero and referencing previous ins? */
1317 if (cmpprev0 && (cc <= CC_NE || cc >= CC_GE))
1318 as->flagmcp = as->mcp; /* Allow elimination of the compare. */
1319}
1320
1321/* 64 bit integer comparisons. */
1322static void asm_int64comp(ASMState *as, IRIns *ir)
1323{
1324 int signedcomp = (ir->o <= IR_GT);
1325 ARMCC cclo, cchi;
1326 Reg leftlo, lefthi;
1327 uint32_t mlo, mhi;
1328 RegSet allow = RSET_GPR, oldfree;
1329
1330 /* Always use unsigned comparison for loword. */
1331 cclo = asm_compmap[ir->o + (signedcomp ? 4 : 0)] & 15;
1332 leftlo = ra_alloc1(as, ir->op1, allow);
1333 oldfree = as->freeset;
1334 mlo = asm_fuseopm(as, ARMI_CMP, ir->op2, rset_clear(allow, leftlo));
1335 allow &= ~(oldfree & ~as->freeset); /* Update for allocs of asm_fuseopm. */
1336
1337 /* Use signed or unsigned comparison for hiword. */
1338 cchi = asm_compmap[ir->o] & 15;
1339 lefthi = ra_alloc1(as, (ir+1)->op1, allow);
1340 mhi = asm_fuseopm(as, ARMI_CMP, (ir+1)->op2, rset_clear(allow, lefthi));
1341
1342 /* All register allocations must be performed _before_ this point. */
1343 if (signedcomp) {
1344 MCLabel l_around = emit_label(as);
1345 asm_guardcc(as, cclo);
1346 emit_n(as, ARMI_CMP^mlo, leftlo);
1347 emit_branch(as, ARMF_CC(ARMI_B, CC_NE), l_around);
1348 if (cchi == CC_GE || cchi == CC_LE) cchi ^= 6; /* GE -> GT, LE -> LT */
1349 asm_guardcc(as, cchi);
1350 } else {
1351 asm_guardcc(as, cclo);
1352 emit_n(as, ARMF_CC(ARMI_CMP, CC_EQ)^mlo, leftlo);
1353 }
1354 emit_n(as, ARMI_CMP^mhi, lefthi);
1355}
1356
1357/* -- Support for 64 bit ops in 32 bit mode ------------------------------- */
1358
1359/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
1360static void asm_hiop(ASMState *as, IRIns *ir)
1361{
1362 /* HIOP is marked as a store because it needs its own DCE logic. */
1363 int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */
1364 if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
1365 if ((ir-1)->o <= IR_NE) { /* 64 bit integer or FP comparisons. ORDER IR. */
1366 as->curins--; /* Always skip the loword comparison. */
1367 if (irt_isint(ir->t))
1368 asm_int64comp(as, ir-1);
1369 else
1370 asm_fpcomp(as, ir-1);
1371 return;
1372 } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
1373 as->curins--; /* Always skip the loword min/max. */
1374 if (uselo || usehi)
1375 asm_fpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HI : CC_LO);
1376 return;
1377 }
1378 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
1379 switch ((ir-1)->o) {
1380#if LJ_HASFFI
1381 case IR_ADD:
1382 as->curins--;
1383 asm_intop(as, ir, ARMI_ADC);
1384 asm_intop(as, ir-1, ARMI_ADD|ARMI_S);
1385 break;
1386 case IR_SUB:
1387 as->curins--;
1388 asm_intop(as, ir, ARMI_SBC);
1389 asm_intop(as, ir-1, ARMI_SUB|ARMI_S);
1390 break;
1391 case IR_NEG:
1392 as->curins--;
1393 asm_intneg(as, ir, ARMI_RSC);
1394 asm_intneg(as, ir-1, ARMI_RSB|ARMI_S);
1395 break;
1396#endif
1397 case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1398 case IR_STRTO:
1399 if (!uselo)
1400 ra_allocref(as, ir->op1, RSET_GPR); /* Mark lo op as used. */
1401 break;
1402 case IR_CALLN:
1403 case IR_CALLS:
1404 case IR_CALLXS:
1405 if (!uselo)
1406 ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */
1407 break;
1408 case IR_ASTORE: case IR_HSTORE: case IR_USTORE:
1409 case IR_TOSTR: case IR_CNEWI:
1410 /* Nothing to do here. Handled by lo op itself. */
1411 break;
1412 default: lua_assert(0); break;
1413 }
1414}
1415
1416/* -- Stack handling ------------------------------------------------------ */
1417
1418/* Check Lua stack size for overflow. Use exit handler as fallback. */
1419static void asm_stack_check(ASMState *as, BCReg topslot,
1420 IRIns *irp, RegSet allow, ExitNo exitno)
1421{
1422 Reg pbase;
1423 uint32_t k;
1424 if (irp) {
1425 if (!ra_hasspill(irp->s)) {
1426 pbase = irp->r;
1427 lua_assert(ra_hasreg(pbase));
1428 } else if (allow) {
1429 pbase = rset_pickbot(allow);
1430 } else {
1431 pbase = RID_RET;
1432 emit_lso(as, ARMI_LDR, RID_RET, RID_SP, 0); /* Restore temp. register. */
1433 }
1434 } else {
1435 pbase = RID_BASE;
1436 }
1437 emit_branch(as, ARMF_CC(ARMI_BL, CC_LS), exitstub_addr(as->J, exitno));
1438 k = emit_isk12(0, (int32_t)(8*topslot));
1439 lua_assert(k);
1440 emit_n(as, ARMI_CMP^k, RID_TMP);
1441 emit_dnm(as, ARMI_SUB, RID_TMP, RID_TMP, pbase);
1442 emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP,
1443 (int32_t)offsetof(lua_State, maxstack));
1444 if (irp) { /* Must not spill arbitrary registers in head of side trace. */
1445 int32_t i = i32ptr(&J2G(as->J)->jit_L);
1446 if (ra_hasspill(irp->s))
1447 emit_lso(as, ARMI_LDR, pbase, RID_SP, sps_scale(irp->s));
1448 emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP, (i & 4095));
1449 if (ra_hasspill(irp->s) && !allow)
1450 emit_lso(as, ARMI_STR, RID_RET, RID_SP, 0); /* Save temp. register. */
1451 emit_loadi(as, RID_TMP, (i & ~4095));
1452 } else {
1453 emit_getgl(as, RID_TMP, jit_L);
1454 }
1455}
1456
1457/* Restore Lua stack from on-trace state. */
1458static void asm_stack_restore(ASMState *as, SnapShot *snap)
1459{
1460 SnapEntry *map = &as->T->snapmap[snap->mapofs];
1461 SnapEntry *flinks = &as->T->snapmap[snap_nextofs(as->T, snap)-1];
1462 MSize n, nent = snap->nent;
1463 /* Store the value of all modified slots to the Lua stack. */
1464 for (n = 0; n < nent; n++) {
1465 SnapEntry sn = map[n];
1466 BCReg s = snap_slot(sn);
1467 int32_t ofs = 8*((int32_t)s-1);
1468 IRRef ref = snap_ref(sn);
1469 IRIns *ir = IR(ref);
1470 if ((sn & SNAP_NORESTORE))
1471 continue;
1472 if (irt_isnum(ir->t)) {
1473 RegSet odd = rset_exclude(RSET_GPRODD, RID_BASE);
1474 Reg tmp;
1475 lua_assert(irref_isk(ref)); /* LJ_SOFTFP: must be a number constant. */
1476 tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo,
1477 rset_exclude(RSET_GPREVEN, RID_BASE));
1478 emit_lso(as, ARMI_STR, tmp, RID_BASE, ofs);
1479 if (rset_test(as->freeset, tmp+1)) odd = RID2RSET(tmp+1);
1480 tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, odd);
1481 emit_lso(as, ARMI_STR, tmp, RID_BASE, ofs+4);
1482 } else {
1483 RegSet odd = rset_exclude(RSET_GPRODD, RID_BASE);
1484 Reg type;
1485 lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t));
1486 if (!irt_ispri(ir->t)) {
1487 Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPREVEN, RID_BASE));
1488 emit_lso(as, ARMI_STR, src, RID_BASE, ofs);
1489 if (rset_test(as->freeset, src+1)) odd = RID2RSET(src+1);
1490 }
1491 if ((sn & (SNAP_CONT|SNAP_FRAME))) {
1492 if (s == 0) continue; /* Do not overwrite link to previous frame. */
1493 type = ra_allock(as, (int32_t)(*flinks--), odd);
1494 } else if ((sn & SNAP_SOFTFPNUM)) {
1495 type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPRODD, RID_BASE));
1496 } else {
1497 type = ra_allock(as, (int32_t)irt_toitype(ir->t), odd);
1498 }
1499 emit_lso(as, ARMI_STR, type, RID_BASE, ofs+4);
1500 }
1501 checkmclim(as);
1502 }
1503 lua_assert(map + nent == flinks);
1504}
1505
1506/* -- GC handling --------------------------------------------------------- */
1507
1508/* Check GC threshold and do one or more GC steps. */
1509static void asm_gc_check(ASMState *as)
1510{
1511 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_gc_step_jit];
1512 IRRef args[2];
1513 MCLabel l_end;
1514 Reg tmp1, tmp2;
1515 ra_evictset(as, RSET_SCRATCH);
1516 l_end = emit_label(as);
1517 /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
1518 asm_guardcc(as, CC_NE); /* Assumes asm_snap_prep() already done. */
1519 emit_n(as, ARMI_CMP|ARMI_K12|0, RID_RET);
1520 args[0] = ASMREF_TMP1; /* global_State *g */
1521 args[1] = ASMREF_TMP2; /* MSize steps */
1522 asm_gencall(as, ci, args);
1523 tmp1 = ra_releasetmp(as, ASMREF_TMP1);
1524 tmp2 = ra_releasetmp(as, ASMREF_TMP2);
1525 emit_loadi(as, tmp2, (int32_t)as->gcsteps);
1526 /* Jump around GC step if GC total < GC threshold. */
1527 emit_branch(as, ARMF_CC(ARMI_B, CC_LS), l_end);
1528 emit_nm(as, ARMI_CMP, RID_TMP, tmp2);
1529 emit_lso(as, ARMI_LDR, tmp2, tmp1,
1530 (int32_t)offsetof(global_State, gc.threshold));
1531 emit_lso(as, ARMI_LDR, RID_TMP, tmp1,
1532 (int32_t)offsetof(global_State, gc.total));
1533 ra_allockreg(as, i32ptr(J2G(as->J)), tmp1);
1534 as->gcsteps = 0;
1535 checkmclim(as);
1536}
1537
1538/* -- Loop handling ------------------------------------------------------- */
1539
1540/* Fixup the loop branch. */
1541static void asm_loop_fixup(ASMState *as)
1542{
1543 MCode *p = as->mctop;
1544 MCode *target = as->mcp;
1545 if (as->loopinv) { /* Inverted loop branch? */
1546 /* asm_guardcc already inverted the bcc and patched the final bl. */
1547 p[-2] |= ((uint32_t)(target-p) & 0x00ffffffu);
1548 } else {
1549 p[-1] = ARMI_B | ((uint32_t)((target-p)-1) & 0x00ffffffu);
1550 }
1551}
1552
1553/* -- Head of trace ------------------------------------------------------- */
1554
1555/* Reload L register from g->jit_L. */
1556static void asm_head_lreg(ASMState *as)
1557{
1558 IRIns *ir = IR(ASMREF_L);
1559 if (ra_used(ir)) {
1560 Reg r = ra_dest(as, ir, RSET_GPR);
1561 emit_getgl(as, r, jit_L);
1562 ra_evictk(as);
1563 }
1564}
1565
1566/* Coalesce BASE register for a root trace. */
1567static void asm_head_root_base(ASMState *as)
1568{
1569 IRIns *ir;
1570 asm_head_lreg(as);
1571 ir = IR(REF_BASE);
1572 if (ra_hasreg(ir->r) && rset_test(as->modset, ir->r)) ra_spill(as, ir);
1573 ra_destreg(as, ir, RID_BASE);
1574}
1575
1576/* Coalesce BASE register for a side trace. */
1577static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
1578{
1579 IRIns *ir;
1580 asm_head_lreg(as);
1581 ir = IR(REF_BASE);
1582 if (ra_hasreg(ir->r) && rset_test(as->modset, ir->r)) ra_spill(as, ir);
1583 if (ra_hasspill(irp->s)) {
1584 rset_clear(allow, ra_dest(as, ir, allow));
1585 } else {
1586 lua_assert(ra_hasreg(irp->r));
1587 rset_clear(allow, irp->r);
1588 ra_destreg(as, ir, irp->r);
1589 }
1590 return allow;
1591}
1592
1593/* -- Tail of trace ------------------------------------------------------- */
1594
1595/* Fixup the tail code. */
1596static void asm_tail_fixup(ASMState *as, TraceNo lnk)
1597{
1598 MCode *p = as->mctop;
1599 MCode *target;
1600 int32_t spadj = as->T->spadjust;
1601 if (spadj == 0) {
1602 as->mctop = --p;
1603 } else {
1604 /* Patch stack adjustment. */
1605 uint32_t k = emit_isk12(ARMI_ADD, spadj);
1606 lua_assert(k);
1607 p[-2] = (ARMI_ADD^k) | ARMF_D(RID_SP) | ARMF_N(RID_SP);
1608 }
1609 /* Patch exit branch. */
1610 target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
1611 p[-1] = ARMI_B|(((target-p)-1)&0x00ffffffu);
1612}
1613
1614/* Prepare tail of code. */
1615static void asm_tail_prep(ASMState *as)
1616{
1617 MCode *p = as->mctop - 1; /* Leave room for exit branch. */
1618 if (as->loopref) {
1619 as->invmcp = as->mcp = p;
1620 } else {
1621 as->mcp = p-1; /* Leave room for stack pointer adjustment. */
1622 as->invmcp = NULL;
1623 }
1624 *p = 0; /* Prevent load/store merging. */
1625}
1626
1627/* -- Instruction dispatch ------------------------------------------------ */
1628
1629/* Assemble a single instruction. */
1630static void asm_ir(ASMState *as, IRIns *ir)
1631{
1632 switch ((IROp)ir->o) {
1633 /* Miscellaneous ops. */
1634 case IR_LOOP: asm_loop(as); break;
1635 case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
1636 case IR_USE: ra_alloc1(as, ir->op1, RSET_GPR); break;
1637 case IR_PHI: asm_phi(as, ir); break;
1638 case IR_HIOP: asm_hiop(as, ir); break;
1639
1640 /* Guarded assertions. */
1641 case IR_EQ: case IR_NE:
1642 if ((ir-1)->o == IR_HREF && ir->op1 == as->curins-1) {
1643 as->curins--;
1644 asm_href(as, ir-1, (IROp)ir->o);
1645 break;
1646 }
1647 /* fallthrough */
1648 case IR_LT: case IR_GE: case IR_LE: case IR_GT:
1649 case IR_ULT: case IR_UGE: case IR_ULE: case IR_UGT:
1650 case IR_ABC:
1651 asm_intcomp(as, ir);
1652 break;
1653
1654 case IR_RETF: asm_retf(as, ir); break;
1655
1656 /* Bit ops. */
1657 case IR_BNOT: asm_bitop(as, ir, ARMI_MVN); break;
1658 case IR_BSWAP: asm_bitswap(as, ir); break;
1659
1660 case IR_BAND: asm_bitop(as, ir, ARMI_AND); break;
1661 case IR_BOR: asm_bitop(as, ir, ARMI_ORR); break;
1662 case IR_BXOR: asm_bitop(as, ir, ARMI_EOR); break;
1663
1664 case IR_BSHL: asm_bitshift(as, ir, ARMSH_LSL); break;
1665 case IR_BSHR: asm_bitshift(as, ir, ARMSH_LSR); break;
1666 case IR_BSAR: asm_bitshift(as, ir, ARMSH_ASR); break;
1667 case IR_BROR: asm_bitshift(as, ir, ARMSH_ROR); break;
1668 case IR_BROL: lua_assert(0); break;
1669
1670 /* Arithmetic ops. */
1671 case IR_ADD: case IR_ADDOV: asm_arithop(as, ir, ARMI_ADD); break;
1672 case IR_SUB: case IR_SUBOV: asm_arithop(as, ir, ARMI_SUB); break;
1673 case IR_MUL: case IR_MULOV: asm_intmul(as, ir); break;
1674 case IR_MOD: asm_intmod(as, ir); break;
1675
1676 case IR_NEG: asm_intneg(as, ir, ARMI_RSB); break;
1677
1678 case IR_MIN: asm_intmin_max(as, ir, CC_GT); break;
1679 case IR_MAX: asm_intmin_max(as, ir, CC_LT); break;
1680
1681 case IR_FPMATH: case IR_ATAN2: case IR_LDEXP:
1682 case IR_DIV: case IR_POW: case IR_ABS: case IR_TOBIT:
1683 lua_assert(0); /* Unused for LJ_SOFTFP. */
1684 break;
1685
1686 /* Memory references. */
1687 case IR_AREF: asm_aref(as, ir); break;
1688 case IR_HREF: asm_href(as, ir, 0); break;
1689 case IR_HREFK: asm_hrefk(as, ir); break;
1690 case IR_NEWREF: asm_newref(as, ir); break;
1691 case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
1692 case IR_FREF: asm_fref(as, ir); break;
1693 case IR_STRREF: asm_strref(as, ir); break;
1694
1695 /* Loads and stores. */
1696 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1697 asm_ahuvload(as, ir);
1698 break;
1699 case IR_FLOAD: asm_fload(as, ir); break;
1700 case IR_XLOAD: asm_xload(as, ir); break;
1701 case IR_SLOAD: asm_sload(as, ir); break;
1702
1703 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
1704 case IR_FSTORE: asm_fstore(as, ir); break;
1705 case IR_XSTORE: asm_xstore(as, ir); break;
1706
1707 /* Allocations. */
1708 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
1709 case IR_TNEW: asm_tnew(as, ir); break;
1710 case IR_TDUP: asm_tdup(as, ir); break;
1711 case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
1712
1713 /* Write barriers. */
1714 case IR_TBAR: asm_tbar(as, ir); break;
1715 case IR_OBAR: asm_obar(as, ir); break;
1716
1717 /* Type conversions. */
1718 case IR_CONV: asm_conv(as, ir); break;
1719 case IR_TOSTR: asm_tostr(as, ir); break;
1720 case IR_STRTO: asm_strto(as, ir); break;
1721
1722 /* Calls. */
1723 case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break;
1724 case IR_CALLXS: asm_callx(as, ir); break;
1725 case IR_CARG: break;
1726
1727 default:
1728 setintV(&as->J->errinfo, ir->o);
1729 lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
1730 break;
1731 }
1732}
1733
1734/* -- Trace setup --------------------------------------------------------- */
1735
1736/* Ensure there are enough stack slots for call arguments. */
1737static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
1738{
1739 IRRef args[CCI_NARGS_MAX];
1740 uint32_t i, nargs = (int)CCI_NARGS(ci);
1741 int nslots = 0, ngpr = REGARG_NUMGPR;
1742 asm_collectargs(as, ir, ci, args);
1743 for (i = 0; i < nargs; i++)
1744 if (!LJ_SOFTFP && args[i] && irt_isnum(IR(args[i])->t)) {
1745 ngpr &= ~1;
1746 if (ngpr > 0) ngpr -= 2; else nslots += 2;
1747 } else {
1748 if (ngpr > 0) ngpr--; else nslots++;
1749 }
1750 if (nslots > as->evenspill) /* Leave room for args in stack slots. */
1751 as->evenspill = nslots;
1752 return REGSP_HINT(RID_RET);
1753}
1754
1755static void asm_setup_target(ASMState *as)
1756{
1757 /* May need extra exit for asm_stack_check on side traces. */
1758 asm_exitstub_setup(as, as->T->nsnap + (as->parent ? 1 : 0));
1759}
1760
1761/* -- Trace patching ------------------------------------------------------ */
1762
1763/* Patch exit jumps of existing machine code to a new target. */
1764void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
1765{
1766 MCode *p = T->mcode;
1767 MCode *pe = (MCode *)((char *)p + T->szmcode);
1768 MCode *cstart = NULL, *cend = p;
1769 MCode *mcarea = lj_mcode_patch(J, p, 0);
1770 MCode *px = exitstub_addr(J, exitno) - 2;
1771 for (; p < pe; p++) {
1772 /* Look for bl_cc exitstub, replace with b_cc target. */
1773 uint32_t ins = *p;
1774 if ((ins & 0x0f000000u) == 0x0b000000u && ins < 0xf0000000u &&
1775 ((ins ^ (px-p)) & 0x00ffffffu) == 0) {
1776 *p = (ins & 0xfe000000u) | (((target-p)-2) & 0x00ffffffu);
1777 cend = p+1;
1778 if (!cstart) cstart = p;
1779 }
1780 }
1781 lua_assert(cstart != NULL);
1782 lj_mcode_sync(cstart, cend);
1783 lj_mcode_patch(J, mcarea, 1);
1784}
1785
diff --git a/libraries/luajit-2.0/src/lj_asm_ppc.h b/libraries/luajit-2.0/src/lj_asm_ppc.h
new file mode 100644
index 0000000..f3f9e2e
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_asm_ppc.h
@@ -0,0 +1,2143 @@
1/*
2** PPC IR assembler (SSA IR -> machine code).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* -- Register allocator extensions --------------------------------------- */
7
8/* Allocate a register with a hint. */
9static Reg ra_hintalloc(ASMState *as, IRRef ref, Reg hint, RegSet allow)
10{
11 Reg r = IR(ref)->r;
12 if (ra_noreg(r)) {
13 if (!ra_hashint(r) && !iscrossref(as, ref))
14 ra_sethint(IR(ref)->r, hint); /* Propagate register hint. */
15 r = ra_allocref(as, ref, allow);
16 }
17 ra_noweak(as, r);
18 return r;
19}
20
21/* Allocate two source registers for three-operand instructions. */
22static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow)
23{
24 IRIns *irl = IR(ir->op1), *irr = IR(ir->op2);
25 Reg left = irl->r, right = irr->r;
26 if (ra_hasreg(left)) {
27 ra_noweak(as, left);
28 if (ra_noreg(right))
29 right = ra_allocref(as, ir->op2, rset_exclude(allow, left));
30 else
31 ra_noweak(as, right);
32 } else if (ra_hasreg(right)) {
33 ra_noweak(as, right);
34 left = ra_allocref(as, ir->op1, rset_exclude(allow, right));
35 } else if (ra_hashint(right)) {
36 right = ra_allocref(as, ir->op2, allow);
37 left = ra_alloc1(as, ir->op1, rset_exclude(allow, right));
38 } else {
39 left = ra_allocref(as, ir->op1, allow);
40 right = ra_alloc1(as, ir->op2, rset_exclude(allow, left));
41 }
42 return left | (right << 8);
43}
44
45/* -- Guard handling ------------------------------------------------------ */
46
47/* Setup exit stubs after the end of each trace. */
48static void asm_exitstub_setup(ASMState *as, ExitNo nexits)
49{
50 ExitNo i;
51 MCode *mxp = as->mctop;
52 /* 1: mflr r0; bl ->vm_exit_handler; li r0, traceno; bl <1; bl <1; ... */
53 for (i = nexits-1; (int32_t)i >= 0; i--)
54 *--mxp = PPCI_BL|(((-3-i)&0x00ffffffu)<<2);
55 *--mxp = PPCI_LI|PPCF_T(RID_TMP)|as->T->traceno; /* Read by exit handler. */
56 mxp--;
57 *mxp = PPCI_BL|((((MCode *)(void *)lj_vm_exit_handler-mxp)&0x00ffffffu)<<2);
58 *--mxp = PPCI_MFLR|PPCF_T(RID_TMP);
59 as->mctop = mxp;
60}
61
62static MCode *asm_exitstub_addr(ASMState *as, ExitNo exitno)
63{
64 /* Keep this in-sync with exitstub_trace_addr(). */
65 return as->mctop + exitno + 3;
66}
67
68/* Emit conditional branch to exit for guard. */
69static void asm_guardcc(ASMState *as, PPCCC cc)
70{
71 MCode *target = asm_exitstub_addr(as, as->snapno);
72 MCode *p = as->mcp;
73 if (LJ_UNLIKELY(p == as->invmcp)) {
74 as->loopinv = 1;
75 *p = PPCI_B | (((target-p) & 0x00ffffffu) << 2);
76 emit_condbranch(as, PPCI_BC, cc^4, p);
77 return;
78 }
79 emit_condbranch(as, PPCI_BC, cc, target);
80}
81
82/* -- Operand fusion ------------------------------------------------------ */
83
84/* Limit linear search to this distance. Avoids O(n^2) behavior. */
85#define CONFLICT_SEARCH_LIM 31
86
87/* Check if there's no conflicting instruction between curins and ref. */
88static int noconflict(ASMState *as, IRRef ref, IROp conflict)
89{
90 IRIns *ir = as->ir;
91 IRRef i = as->curins;
92 if (i > ref + CONFLICT_SEARCH_LIM)
93 return 0; /* Give up, ref is too far away. */
94 while (--i > ref)
95 if (ir[i].o == conflict)
96 return 0; /* Conflict found. */
97 return 1; /* Ok, no conflict. */
98}
99
100/* Fuse the array base of colocated arrays. */
101static int32_t asm_fuseabase(ASMState *as, IRRef ref)
102{
103 IRIns *ir = IR(ref);
104 if (ir->o == IR_TNEW && ir->op1 <= LJ_MAX_COLOSIZE &&
105 !neverfuse(as) && noconflict(as, ref, IR_NEWREF))
106 return (int32_t)sizeof(GCtab);
107 return 0;
108}
109
110/* Indicates load/store indexed is ok. */
111#define AHUREF_LSX ((int32_t)0x80000000)
112
113/* Fuse array/hash/upvalue reference into register+offset operand. */
114static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow)
115{
116 IRIns *ir = IR(ref);
117 if (ra_noreg(ir->r)) {
118 if (ir->o == IR_AREF) {
119 if (mayfuse(as, ref)) {
120 if (irref_isk(ir->op2)) {
121 IRRef tab = IR(ir->op1)->op1;
122 int32_t ofs = asm_fuseabase(as, tab);
123 IRRef refa = ofs ? tab : ir->op1;
124 ofs += 8*IR(ir->op2)->i;
125 if (checki16(ofs)) {
126 *ofsp = ofs;
127 return ra_alloc1(as, refa, allow);
128 }
129 }
130 if (*ofsp == AHUREF_LSX) {
131 Reg base = ra_alloc1(as, ir->op1, allow);
132 Reg idx = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, base));
133 return base | (idx << 8);
134 }
135 }
136 } else if (ir->o == IR_HREFK) {
137 if (mayfuse(as, ref)) {
138 int32_t ofs = (int32_t)(IR(ir->op2)->op2 * sizeof(Node));
139 if (checki16(ofs)) {
140 *ofsp = ofs;
141 return ra_alloc1(as, ir->op1, allow);
142 }
143 }
144 } else if (ir->o == IR_UREFC) {
145 if (irref_isk(ir->op1)) {
146 GCfunc *fn = ir_kfunc(IR(ir->op1));
147 int32_t ofs = i32ptr(&gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.tv);
148 int32_t jgl = (intptr_t)J2G(as->J);
149 if ((uint32_t)(ofs-jgl) < 65536) {
150 *ofsp = ofs-jgl-32768;
151 return RID_JGL;
152 } else {
153 *ofsp = (int16_t)ofs;
154 return ra_allock(as, ofs-(int16_t)ofs, allow);
155 }
156 }
157 }
158 }
159 *ofsp = 0;
160 return ra_alloc1(as, ref, allow);
161}
162
163/* Fuse XLOAD/XSTORE reference into load/store operand. */
164static void asm_fusexref(ASMState *as, PPCIns pi, Reg rt, IRRef ref,
165 RegSet allow)
166{
167 IRIns *ir = IR(ref);
168 int32_t ofs = 0;
169 Reg base;
170 if (ra_noreg(ir->r) && mayfuse(as, ref)) {
171 if (ir->o == IR_ADD) {
172 if (irref_isk(ir->op2) && (ofs = IR(ir->op2)->i, checki16(ofs))) {
173 ref = ir->op1;
174 } else {
175 Reg right, left = ra_alloc2(as, ir, allow);
176 right = (left >> 8); left &= 255;
177 emit_fab(as, PPCI_LWZX | ((pi >> 20) & 0x780), rt, left, right);
178 return;
179 }
180 } else if (ir->o == IR_STRREF) {
181 ofs = (int32_t)sizeof(GCstr);
182 if (irref_isk(ir->op2)) {
183 ofs += IR(ir->op2)->i;
184 ref = ir->op1;
185 } else if (irref_isk(ir->op1)) {
186 ofs += IR(ir->op1)->i;
187 ref = ir->op2;
188 } else {
189 /* NYI: Fuse ADD with constant. */
190 Reg right, left = ra_alloc2(as, ir, allow);
191 right = (left >> 8); left &= 255;
192 emit_fai(as, pi, rt, rt, ofs);
193 emit_tab(as, PPCI_ADD, rt, left, right);
194 return;
195 }
196 if (!checki16(ofs)) {
197 Reg left = ra_alloc1(as, ref, allow);
198 Reg right = ra_allock(as, ofs, rset_exclude(allow, left));
199 emit_fab(as, PPCI_LWZX | ((pi >> 20) & 0x780), rt, left, right);
200 return;
201 }
202 }
203 }
204 base = ra_alloc1(as, ref, allow);
205 emit_fai(as, pi, rt, base, ofs);
206}
207
208/* Fuse XLOAD/XSTORE reference into indexed-only load/store operand. */
209static void asm_fusexrefx(ASMState *as, PPCIns pi, Reg rt, IRRef ref,
210 RegSet allow)
211{
212 IRIns *ira = IR(ref);
213 Reg right, left;
214 if (mayfuse(as, ref) && ira->o == IR_ADD && ra_noreg(ira->r)) {
215 left = ra_alloc2(as, ira, allow);
216 right = (left >> 8); left &= 255;
217 } else {
218 right = ra_alloc1(as, ref, allow);
219 left = RID_R0;
220 }
221 emit_tab(as, pi, rt, left, right);
222}
223
224/* Fuse to multiply-add/sub instruction. */
225static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir)
226{
227 IRRef lref = ir->op1, rref = ir->op2;
228 IRIns *irm;
229 if (lref != rref &&
230 ((mayfuse(as, lref) && (irm = IR(lref), irm->o == IR_MUL) &&
231 ra_noreg(irm->r)) ||
232 (mayfuse(as, rref) && (irm = IR(rref), irm->o == IR_MUL) &&
233 (rref = lref, pi = pir, ra_noreg(irm->r))))) {
234 Reg dest = ra_dest(as, ir, RSET_FPR);
235 Reg add = ra_alloc1(as, rref, RSET_FPR);
236 Reg right, left = ra_alloc2(as, irm, rset_exclude(RSET_FPR, add));
237 right = (left >> 8); left &= 255;
238 emit_facb(as, pi, dest, left, right, add);
239 return 1;
240 }
241 return 0;
242}
243
244/* -- Calls --------------------------------------------------------------- */
245
246/* Generate a call to a C function. */
247static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
248{
249 uint32_t n, nargs = CCI_NARGS(ci);
250 int32_t ofs = 8;
251 Reg gpr = REGARG_FIRSTGPR, fpr = REGARG_FIRSTFPR;
252 if ((void *)ci->func)
253 emit_call(as, (void *)ci->func);
254 for (n = 0; n < nargs; n++) { /* Setup args. */
255 IRRef ref = args[n];
256 if (ref) {
257 IRIns *ir = IR(ref);
258 if (irt_isfp(ir->t)) {
259 if (fpr <= REGARG_LASTFPR) {
260 lua_assert(rset_test(as->freeset, fpr)); /* Already evicted. */
261 ra_leftov(as, fpr, ref);
262 fpr++;
263 } else {
264 Reg r = ra_alloc1(as, ref, RSET_FPR);
265 if (irt_isnum(ir->t)) ofs = (ofs + 4) & ~4;
266 emit_spstore(as, ir, r, ofs);
267 ofs += irt_isnum(ir->t) ? 8 : 4;
268 }
269 } else {
270 if (gpr <= REGARG_LASTGPR) {
271 lua_assert(rset_test(as->freeset, gpr)); /* Already evicted. */
272 ra_leftov(as, gpr, ref);
273 gpr++;
274 } else {
275 Reg r = ra_alloc1(as, ref, RSET_GPR);
276 emit_spstore(as, ir, r, ofs);
277 ofs += 4;
278 }
279 }
280 } else {
281 if (gpr <= REGARG_LASTGPR)
282 gpr++;
283 else
284 ofs += 4;
285 }
286 }
287 if ((ci->flags & CCI_VARARG)) /* Vararg calls need to know about FPR use. */
288 emit_tab(as, fpr == REGARG_FIRSTFPR ? PPCI_CRXOR : PPCI_CREQV, 6, 6, 6);
289}
290
291/* Setup result reg/sp for call. Evict scratch regs. */
292static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
293{
294 RegSet drop = RSET_SCRATCH;
295 int hiop = ((ir+1)->o == IR_HIOP);
296 if ((ci->flags & CCI_NOFPRCLOBBER))
297 drop &= ~RSET_FPR;
298 if (ra_hasreg(ir->r))
299 rset_clear(drop, ir->r); /* Dest reg handled below. */
300 if (hiop && ra_hasreg((ir+1)->r))
301 rset_clear(drop, (ir+1)->r); /* Dest reg handled below. */
302 ra_evictset(as, drop); /* Evictions must be performed first. */
303 if (ra_used(ir)) {
304 lua_assert(!irt_ispri(ir->t));
305 if (irt_isfp(ir->t)) {
306 if ((ci->flags & CCI_CASTU64)) {
307 /* Use spill slot or temp slots. */
308 int32_t ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP;
309 Reg dest = ir->r;
310 if (ra_hasreg(dest)) {
311 ra_free(as, dest);
312 ra_modified(as, dest);
313 emit_fai(as, PPCI_LFD, dest, RID_SP, ofs);
314 }
315 emit_tai(as, PPCI_STW, RID_RETHI, RID_SP, ofs);
316 emit_tai(as, PPCI_STW, RID_RETLO, RID_SP, ofs+4);
317 } else {
318 ra_destreg(as, ir, RID_FPRET);
319 }
320 } else if (hiop) {
321 ra_destpair(as, ir);
322 } else {
323 ra_destreg(as, ir, RID_RET);
324 }
325 }
326}
327
328static void asm_call(ASMState *as, IRIns *ir)
329{
330 IRRef args[CCI_NARGS_MAX];
331 const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
332 asm_collectargs(as, ir, ci, args);
333 asm_setupresult(as, ir, ci);
334 asm_gencall(as, ci, args);
335}
336
337static void asm_callx(ASMState *as, IRIns *ir)
338{
339 IRRef args[CCI_NARGS_MAX];
340 CCallInfo ci;
341 IRRef func;
342 IRIns *irf;
343 ci.flags = asm_callx_flags(as, ir);
344 asm_collectargs(as, ir, &ci, args);
345 asm_setupresult(as, ir, &ci);
346 func = ir->op2; irf = IR(func);
347 if (irf->o == IR_CARG) { func = irf->op1; irf = IR(func); }
348 if (irref_isk(func)) { /* Call to constant address. */
349 ci.func = (ASMFunction)(void *)(irf->i);
350 } else { /* Need a non-argument register for indirect calls. */
351 RegSet allow = RSET_GPR & ~RSET_RANGE(RID_R0, REGARG_LASTGPR+1);
352 Reg freg = ra_alloc1(as, func, allow);
353 *--as->mcp = PPCI_BCTRL;
354 *--as->mcp = PPCI_MTCTR | PPCF_T(freg);
355 ci.func = (ASMFunction)(void *)0;
356 }
357 asm_gencall(as, &ci, args);
358}
359
360static void asm_callid(ASMState *as, IRIns *ir, IRCallID id)
361{
362 const CCallInfo *ci = &lj_ir_callinfo[id];
363 IRRef args[2];
364 args[0] = ir->op1;
365 args[1] = ir->op2;
366 asm_setupresult(as, ir, ci);
367 asm_gencall(as, ci, args);
368}
369
370/* -- Returns ------------------------------------------------------------- */
371
372/* Return to lower frame. Guard that it goes to the right spot. */
373static void asm_retf(ASMState *as, IRIns *ir)
374{
375 Reg base = ra_alloc1(as, REF_BASE, RSET_GPR);
376 void *pc = ir_kptr(IR(ir->op2));
377 int32_t delta = 1+bc_a(*((const BCIns *)pc - 1));
378 as->topslot -= (BCReg)delta;
379 if ((int32_t)as->topslot < 0) as->topslot = 0;
380 emit_setgl(as, base, jit_base);
381 emit_addptr(as, base, -8*delta);
382 asm_guardcc(as, CC_NE);
383 emit_ab(as, PPCI_CMPW, RID_TMP,
384 ra_allock(as, i32ptr(pc), rset_exclude(RSET_GPR, base)));
385 emit_tai(as, PPCI_LWZ, RID_TMP, base, -8);
386}
387
388/* -- Type conversions ---------------------------------------------------- */
389
390static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
391{
392 RegSet allow = RSET_FPR;
393 Reg tmp = ra_scratch(as, rset_clear(allow, left));
394 Reg fbias = ra_scratch(as, rset_clear(allow, tmp));
395 Reg dest = ra_dest(as, ir, RSET_GPR);
396 Reg hibias = ra_allock(as, 0x43300000, rset_exclude(RSET_GPR, dest));
397 asm_guardcc(as, CC_NE);
398 emit_fab(as, PPCI_FCMPU, 0, tmp, left);
399 emit_fab(as, PPCI_FSUB, tmp, tmp, fbias);
400 emit_fai(as, PPCI_LFD, tmp, RID_SP, SPOFS_TMP);
401 emit_tai(as, PPCI_STW, RID_TMP, RID_SP, SPOFS_TMPLO);
402 emit_tai(as, PPCI_STW, hibias, RID_SP, SPOFS_TMPHI);
403 emit_asi(as, PPCI_XORIS, RID_TMP, dest, 0x8000);
404 emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO);
405 emit_lsptr(as, PPCI_LFS, (fbias & 31),
406 (void *)lj_ir_k64_find(as->J, U64x(59800004,59800000)),
407 RSET_GPR);
408 emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP);
409 emit_fb(as, PPCI_FCTIWZ, tmp, left);
410}
411
412static void asm_tobit(ASMState *as, IRIns *ir)
413{
414 RegSet allow = RSET_FPR;
415 Reg dest = ra_dest(as, ir, RSET_GPR);
416 Reg left = ra_alloc1(as, ir->op1, allow);
417 Reg right = ra_alloc1(as, ir->op2, rset_clear(allow, left));
418 Reg tmp = ra_scratch(as, rset_clear(allow, right));
419 emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO);
420 emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP);
421 emit_fab(as, PPCI_FADD, tmp, left, right);
422}
423
424static void asm_conv(ASMState *as, IRIns *ir)
425{
426 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
427 int stfp = (st == IRT_NUM || st == IRT_FLOAT);
428 IRRef lref = ir->op1;
429 lua_assert(irt_type(ir->t) != st);
430 lua_assert(!(irt_isint64(ir->t) ||
431 (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */
432 if (irt_isfp(ir->t)) {
433 Reg dest = ra_dest(as, ir, RSET_FPR);
434 if (stfp) { /* FP to FP conversion. */
435 if (st == IRT_NUM) /* double -> float conversion. */
436 emit_fb(as, PPCI_FRSP, dest, ra_alloc1(as, lref, RSET_FPR));
437 else /* float -> double conversion is a no-op on PPC. */
438 ra_leftov(as, dest, lref); /* Do nothing, but may need to move regs. */
439 } else { /* Integer to FP conversion. */
440 /* IRT_INT: Flip hibit, bias with 2^52, subtract 2^52+2^31. */
441 /* IRT_U32: Bias with 2^52, subtract 2^52. */
442 RegSet allow = RSET_GPR;
443 Reg left = ra_alloc1(as, lref, allow);
444 Reg hibias = ra_allock(as, 0x43300000, rset_clear(allow, left));
445 Reg fbias = ra_scratch(as, rset_exclude(RSET_FPR, dest));
446 const float *kbias;
447 if (irt_isfloat(ir->t)) emit_fb(as, PPCI_FRSP, dest, dest);
448 emit_fab(as, PPCI_FSUB, dest, dest, fbias);
449 emit_fai(as, PPCI_LFD, dest, RID_SP, SPOFS_TMP);
450 kbias = (const float *)lj_ir_k64_find(as->J, U64x(59800004,59800000));
451 if (st == IRT_U32) kbias++;
452 emit_lsptr(as, PPCI_LFS, (fbias & 31), (void *)kbias,
453 rset_clear(allow, hibias));
454 emit_tai(as, PPCI_STW, st == IRT_U32 ? left : RID_TMP,
455 RID_SP, SPOFS_TMPLO);
456 emit_tai(as, PPCI_STW, hibias, RID_SP, SPOFS_TMPHI);
457 if (st != IRT_U32) emit_asi(as, PPCI_XORIS, RID_TMP, left, 0x8000);
458 }
459 } else if (stfp) { /* FP to integer conversion. */
460 if (irt_isguard(ir->t)) {
461 /* Checked conversions are only supported from number to int. */
462 lua_assert(irt_isint(ir->t) && st == IRT_NUM);
463 asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
464 } else {
465 Reg dest = ra_dest(as, ir, RSET_GPR);
466 Reg left = ra_alloc1(as, lref, RSET_FPR);
467 Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, left));
468 if (irt_isu32(ir->t)) {
469 /* Convert both x and x-2^31 to int and merge results. */
470 Reg tmpi = ra_scratch(as, rset_exclude(RSET_GPR, dest));
471 emit_asb(as, PPCI_OR, dest, dest, tmpi); /* Select with mask idiom. */
472 emit_asb(as, PPCI_AND, tmpi, tmpi, RID_TMP);
473 emit_asb(as, PPCI_ANDC, dest, dest, RID_TMP);
474 emit_tai(as, PPCI_LWZ, tmpi, RID_SP, SPOFS_TMPLO); /* tmp = (int)(x) */
475 emit_tai(as, PPCI_ADDIS, dest, dest, 0x8000); /* dest += 2^31 */
476 emit_asb(as, PPCI_SRAWI, RID_TMP, dest, 31); /* mask = -(dest < 0) */
477 emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP);
478 emit_tai(as, PPCI_LWZ, dest,
479 RID_SP, SPOFS_TMPLO); /* dest = (int)(x-2^31) */
480 emit_fb(as, PPCI_FCTIWZ, tmp, left);
481 emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP);
482 emit_fb(as, PPCI_FCTIWZ, tmp, tmp);
483 emit_fab(as, PPCI_FSUB, tmp, left, tmp);
484 emit_lsptr(as, PPCI_LFS, (tmp & 31),
485 (void *)lj_ir_k64_find(as->J, U64x(4f000000,00000000)),
486 RSET_GPR);
487 } else {
488 emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO);
489 emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP);
490 emit_fb(as, PPCI_FCTIWZ, tmp, left);
491 }
492 }
493 } else {
494 Reg dest = ra_dest(as, ir, RSET_GPR);
495 if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */
496 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
497 lua_assert(irt_isint(ir->t) || irt_isu32(ir->t));
498 if ((ir->op2 & IRCONV_SEXT))
499 emit_as(as, st == IRT_I8 ? PPCI_EXTSB : PPCI_EXTSH, dest, left);
500 else
501 emit_rot(as, PPCI_RLWINM, dest, left, 0, st == IRT_U8 ? 24 : 16, 31);
502 } else { /* 32/64 bit integer conversions. */
503 /* Only need to handle 32/32 bit no-op (cast) on 32 bit archs. */
504 ra_leftov(as, dest, lref); /* Do nothing, but may need to move regs. */
505 }
506 }
507}
508
509#if LJ_HASFFI
510static void asm_conv64(ASMState *as, IRIns *ir)
511{
512 IRType st = (IRType)((ir-1)->op2 & IRCONV_SRCMASK);
513 IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
514 IRCallID id;
515 const CCallInfo *ci;
516 IRRef args[2];
517 args[0] = ir->op1;
518 args[1] = (ir-1)->op1;
519 if (st == IRT_NUM || st == IRT_FLOAT) {
520 id = IRCALL_fp64_d2l + ((st == IRT_FLOAT) ? 2 : 0) + (dt - IRT_I64);
521 ir--;
522 } else {
523 id = IRCALL_fp64_l2d + ((dt == IRT_FLOAT) ? 2 : 0) + (st - IRT_I64);
524 }
525 ci = &lj_ir_callinfo[id];
526 asm_setupresult(as, ir, ci);
527 asm_gencall(as, ci, args);
528}
529#endif
530
531static void asm_strto(ASMState *as, IRIns *ir)
532{
533 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_tonum];
534 IRRef args[2];
535 int32_t ofs;
536 RegSet drop = RSET_SCRATCH;
537 if (ra_hasreg(ir->r)) rset_set(drop, ir->r); /* Spill dest reg (if any). */
538 ra_evictset(as, drop);
539 asm_guardcc(as, CC_EQ);
540 emit_ai(as, PPCI_CMPWI, RID_RET, 0); /* Test return status. */
541 args[0] = ir->op1; /* GCstr *str */
542 args[1] = ASMREF_TMP1; /* TValue *n */
543 asm_gencall(as, ci, args);
544 /* Store the result to the spill slot or temp slots. */
545 ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP;
546 emit_tai(as, PPCI_ADDI, ra_releasetmp(as, ASMREF_TMP1), RID_SP, ofs);
547}
548
549/* Get pointer to TValue. */
550static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
551{
552 IRIns *ir = IR(ref);
553 if (irt_isnum(ir->t)) {
554 if (irref_isk(ref)) /* Use the number constant itself as a TValue. */
555 ra_allockreg(as, i32ptr(ir_knum(ir)), dest);
556 else /* Otherwise force a spill and use the spill slot. */
557 emit_tai(as, PPCI_ADDI, dest, RID_SP, ra_spill(as, ir));
558 } else {
559 /* Otherwise use g->tmptv to hold the TValue. */
560 RegSet allow = rset_exclude(RSET_GPR, dest);
561 Reg type;
562 emit_tai(as, PPCI_ADDI, dest, RID_JGL, offsetof(global_State, tmptv)-32768);
563 if (!irt_ispri(ir->t)) {
564 Reg src = ra_alloc1(as, ref, allow);
565 emit_setgl(as, src, tmptv.gcr);
566 }
567 type = ra_allock(as, irt_toitype(ir->t), allow);
568 emit_setgl(as, type, tmptv.it);
569 }
570}
571
572static void asm_tostr(ASMState *as, IRIns *ir)
573{
574 IRRef args[2];
575 args[0] = ASMREF_L;
576 as->gcsteps++;
577 if (irt_isnum(IR(ir->op1)->t) || (ir+1)->o == IR_HIOP) {
578 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum];
579 args[1] = ASMREF_TMP1; /* const lua_Number * */
580 asm_setupresult(as, ir, ci); /* GCstr * */
581 asm_gencall(as, ci, args);
582 asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1);
583 } else {
584 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromint];
585 args[1] = ir->op1; /* int32_t k */
586 asm_setupresult(as, ir, ci); /* GCstr * */
587 asm_gencall(as, ci, args);
588 }
589}
590
591/* -- Memory references --------------------------------------------------- */
592
593static void asm_aref(ASMState *as, IRIns *ir)
594{
595 Reg dest = ra_dest(as, ir, RSET_GPR);
596 Reg idx, base;
597 if (irref_isk(ir->op2)) {
598 IRRef tab = IR(ir->op1)->op1;
599 int32_t ofs = asm_fuseabase(as, tab);
600 IRRef refa = ofs ? tab : ir->op1;
601 ofs += 8*IR(ir->op2)->i;
602 if (checki16(ofs)) {
603 base = ra_alloc1(as, refa, RSET_GPR);
604 emit_tai(as, PPCI_ADDI, dest, base, ofs);
605 return;
606 }
607 }
608 base = ra_alloc1(as, ir->op1, RSET_GPR);
609 idx = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, base));
610 emit_tab(as, PPCI_ADD, dest, RID_TMP, base);
611 emit_slwi(as, RID_TMP, idx, 3);
612}
613
614/* Inlined hash lookup. Specialized for key type and for const keys.
615** The equivalent C code is:
616** Node *n = hashkey(t, key);
617** do {
618** if (lj_obj_equal(&n->key, key)) return &n->val;
619** } while ((n = nextnode(n)));
620** return niltv(L);
621*/
622static void asm_href(ASMState *as, IRIns *ir, IROp merge)
623{
624 RegSet allow = RSET_GPR;
625 int destused = ra_used(ir);
626 Reg dest = ra_dest(as, ir, allow);
627 Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
628 Reg key = RID_NONE, tmp1 = RID_TMP, tmp2;
629 Reg tisnum = RID_NONE, tmpnum = RID_NONE;
630 IRRef refkey = ir->op2;
631 IRIns *irkey = IR(refkey);
632 IRType1 kt = irkey->t;
633 uint32_t khash;
634 MCLabel l_end, l_loop, l_next;
635
636 rset_clear(allow, tab);
637 if (irt_isnum(kt)) {
638 key = ra_alloc1(as, refkey, RSET_FPR);
639 tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key));
640 tisnum = ra_allock(as, (int32_t)LJ_TISNUM, allow);
641 rset_clear(allow, tisnum);
642 } else if (!irt_ispri(kt)) {
643 key = ra_alloc1(as, refkey, allow);
644 rset_clear(allow, key);
645 }
646 tmp2 = ra_scratch(as, allow);
647 rset_clear(allow, tmp2);
648
649 /* Key not found in chain: jump to exit (if merged) or load niltv. */
650 l_end = emit_label(as);
651 as->invmcp = NULL;
652 if (merge == IR_NE)
653 asm_guardcc(as, CC_EQ);
654 else if (destused)
655 emit_loada(as, dest, niltvg(J2G(as->J)));
656
657 /* Follow hash chain until the end. */
658 l_loop = --as->mcp;
659 emit_ai(as, PPCI_CMPWI, dest, 0);
660 emit_tai(as, PPCI_LWZ, dest, dest, (int32_t)offsetof(Node, next));
661 l_next = emit_label(as);
662
663 /* Type and value comparison. */
664 if (merge == IR_EQ)
665 asm_guardcc(as, CC_EQ);
666 else
667 emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end);
668 if (irt_isnum(kt)) {
669 emit_fab(as, PPCI_FCMPU, 0, tmpnum, key);
670 emit_condbranch(as, PPCI_BC, CC_GE, l_next);
671 emit_ab(as, PPCI_CMPLW, tmp1, tisnum);
672 emit_fai(as, PPCI_LFD, tmpnum, dest, (int32_t)offsetof(Node, key.n));
673 } else {
674 if (!irt_ispri(kt)) {
675 emit_ab(as, PPCI_CMPW, tmp2, key);
676 emit_condbranch(as, PPCI_BC, CC_NE, l_next);
677 }
678 emit_ai(as, PPCI_CMPWI, tmp1, irt_toitype(irkey->t));
679 if (!irt_ispri(kt))
680 emit_tai(as, PPCI_LWZ, tmp2, dest, (int32_t)offsetof(Node, key.gcr));
681 }
682 emit_tai(as, PPCI_LWZ, tmp1, dest, (int32_t)offsetof(Node, key.it));
683 *l_loop = PPCI_BC | PPCF_Y | PPCF_CC(CC_NE) |
684 (((char *)as->mcp-(char *)l_loop) & 0xffffu);
685
686 /* Load main position relative to tab->node into dest. */
687 khash = irref_isk(refkey) ? ir_khash(irkey) : 1;
688 if (khash == 0) {
689 emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));
690 } else {
691 Reg tmphash = tmp1;
692 if (irref_isk(refkey))
693 tmphash = ra_allock(as, khash, allow);
694 emit_tab(as, PPCI_ADD, dest, dest, tmp1);
695 emit_tai(as, PPCI_MULLI, tmp1, tmp1, sizeof(Node));
696 emit_asb(as, PPCI_AND, tmp1, tmp2, tmphash);
697 emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));
698 emit_tai(as, PPCI_LWZ, tmp2, tab, (int32_t)offsetof(GCtab, hmask));
699 if (irref_isk(refkey)) {
700 /* Nothing to do. */
701 } else if (irt_isstr(kt)) {
702 emit_tai(as, PPCI_LWZ, tmp1, key, (int32_t)offsetof(GCstr, hash));
703 } else { /* Must match with hash*() in lj_tab.c. */
704 emit_tab(as, PPCI_SUBF, tmp1, tmp2, tmp1);
705 emit_rotlwi(as, tmp2, tmp2, HASH_ROT3);
706 emit_asb(as, PPCI_XOR, tmp1, tmp1, tmp2);
707 emit_rotlwi(as, tmp1, tmp1, (HASH_ROT2+HASH_ROT1)&31);
708 emit_tab(as, PPCI_SUBF, tmp2, dest, tmp2);
709 if (irt_isnum(kt)) {
710 int32_t ofs = ra_spill(as, irkey);
711 emit_asb(as, PPCI_XOR, tmp2, tmp2, tmp1);
712 emit_rotlwi(as, dest, tmp1, HASH_ROT1);
713 emit_tab(as, PPCI_ADD, tmp1, tmp1, tmp1);
714 emit_tai(as, PPCI_LWZ, tmp2, RID_SP, ofs+4);
715 emit_tai(as, PPCI_LWZ, tmp1, RID_SP, ofs);
716 } else {
717 emit_asb(as, PPCI_XOR, tmp2, key, tmp1);
718 emit_rotlwi(as, dest, tmp1, HASH_ROT1);
719 emit_tai(as, PPCI_ADDI, tmp1, tmp2, HASH_BIAS);
720 emit_tai(as, PPCI_ADDIS, tmp2, key, (HASH_BIAS + 32768)>>16);
721 }
722 }
723 }
724}
725
726static void asm_hrefk(ASMState *as, IRIns *ir)
727{
728 IRIns *kslot = IR(ir->op2);
729 IRIns *irkey = IR(kslot->op1);
730 int32_t ofs = (int32_t)(kslot->op2 * sizeof(Node));
731 int32_t kofs = ofs + (int32_t)offsetof(Node, key);
732 Reg dest = (ra_used(ir)||ofs > 65535) ? ra_dest(as, ir, RSET_GPR) : RID_NONE;
733 Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
734 Reg key = RID_NONE, type = RID_TMP, idx = node;
735 RegSet allow = rset_exclude(RSET_GPR, node);
736 lua_assert(ofs % sizeof(Node) == 0);
737 if (ofs > 65535) {
738 idx = dest;
739 rset_clear(allow, dest);
740 kofs = (int32_t)offsetof(Node, key);
741 } else if (ra_hasreg(dest)) {
742 emit_tai(as, PPCI_ADDI, dest, node, ofs);
743 }
744 asm_guardcc(as, CC_NE);
745 if (!irt_ispri(irkey->t)) {
746 key = ra_scratch(as, allow);
747 rset_clear(allow, key);
748 }
749 rset_clear(allow, type);
750 if (irt_isnum(irkey->t)) {
751 emit_cmpi(as, key, (int32_t)ir_knum(irkey)->u32.lo);
752 asm_guardcc(as, CC_NE);
753 emit_cmpi(as, type, (int32_t)ir_knum(irkey)->u32.hi);
754 } else {
755 if (ra_hasreg(key)) {
756 emit_cmpi(as, key, irkey->i); /* May use RID_TMP, i.e. type. */
757 asm_guardcc(as, CC_NE);
758 }
759 emit_ai(as, PPCI_CMPWI, type, irt_toitype(irkey->t));
760 }
761 if (ra_hasreg(key)) emit_tai(as, PPCI_LWZ, key, idx, kofs+4);
762 emit_tai(as, PPCI_LWZ, type, idx, kofs);
763 if (ofs > 65535) {
764 emit_tai(as, PPCI_ADDIS, dest, dest, (ofs + 32768) >> 16);
765 emit_tai(as, PPCI_ADDI, dest, node, ofs);
766 }
767}
768
769static void asm_newref(ASMState *as, IRIns *ir)
770{
771 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_newkey];
772 IRRef args[3];
773 args[0] = ASMREF_L; /* lua_State *L */
774 args[1] = ir->op1; /* GCtab *t */
775 args[2] = ASMREF_TMP1; /* cTValue *key */
776 asm_setupresult(as, ir, ci); /* TValue * */
777 asm_gencall(as, ci, args);
778 asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2);
779}
780
781static void asm_uref(ASMState *as, IRIns *ir)
782{
783 /* NYI: Check that UREFO is still open and not aliasing a slot. */
784 Reg dest = ra_dest(as, ir, RSET_GPR);
785 if (irref_isk(ir->op1)) {
786 GCfunc *fn = ir_kfunc(IR(ir->op1));
787 MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v;
788 emit_lsptr(as, PPCI_LWZ, dest, v, RSET_GPR);
789 } else {
790 Reg uv = ra_scratch(as, RSET_GPR);
791 Reg func = ra_alloc1(as, ir->op1, RSET_GPR);
792 if (ir->o == IR_UREFC) {
793 asm_guardcc(as, CC_NE);
794 emit_ai(as, PPCI_CMPWI, RID_TMP, 1);
795 emit_tai(as, PPCI_ADDI, dest, uv, (int32_t)offsetof(GCupval, tv));
796 emit_tai(as, PPCI_LBZ, RID_TMP, uv, (int32_t)offsetof(GCupval, closed));
797 } else {
798 emit_tai(as, PPCI_LWZ, dest, uv, (int32_t)offsetof(GCupval, v));
799 }
800 emit_tai(as, PPCI_LWZ, uv, func,
801 (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8));
802 }
803}
804
805static void asm_fref(ASMState *as, IRIns *ir)
806{
807 UNUSED(as); UNUSED(ir);
808 lua_assert(!ra_used(ir));
809}
810
811static void asm_strref(ASMState *as, IRIns *ir)
812{
813 Reg dest = ra_dest(as, ir, RSET_GPR);
814 IRRef ref = ir->op2, refk = ir->op1;
815 int32_t ofs = (int32_t)sizeof(GCstr);
816 Reg r;
817 if (irref_isk(ref)) {
818 IRRef tmp = refk; refk = ref; ref = tmp;
819 } else if (!irref_isk(refk)) {
820 Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR);
821 IRIns *irr = IR(ir->op2);
822 if (ra_hasreg(irr->r)) {
823 ra_noweak(as, irr->r);
824 right = irr->r;
825 } else if (mayfuse(as, irr->op2) &&
826 irr->o == IR_ADD && irref_isk(irr->op2) &&
827 checki16(ofs + IR(irr->op2)->i)) {
828 ofs += IR(irr->op2)->i;
829 right = ra_alloc1(as, irr->op1, rset_exclude(RSET_GPR, left));
830 } else {
831 right = ra_allocref(as, ir->op2, rset_exclude(RSET_GPR, left));
832 }
833 emit_tai(as, PPCI_ADDI, dest, dest, ofs);
834 emit_tab(as, PPCI_ADD, dest, left, right);
835 return;
836 }
837 r = ra_alloc1(as, ref, RSET_GPR);
838 ofs += IR(refk)->i;
839 if (checki16(ofs))
840 emit_tai(as, PPCI_ADDI, dest, r, ofs);
841 else
842 emit_tab(as, PPCI_ADD, dest, r,
843 ra_allock(as, ofs, rset_exclude(RSET_GPR, r)));
844}
845
846/* -- Loads and stores ---------------------------------------------------- */
847
848static PPCIns asm_fxloadins(IRIns *ir)
849{
850 switch (irt_type(ir->t)) {
851 case IRT_I8: return PPCI_LBZ; /* Needs sign-extension. */
852 case IRT_U8: return PPCI_LBZ;
853 case IRT_I16: return PPCI_LHA;
854 case IRT_U16: return PPCI_LHZ;
855 case IRT_NUM: return PPCI_LFD;
856 case IRT_FLOAT: return PPCI_LFS;
857 default: return PPCI_LWZ;
858 }
859}
860
861static PPCIns asm_fxstoreins(IRIns *ir)
862{
863 switch (irt_type(ir->t)) {
864 case IRT_I8: case IRT_U8: return PPCI_STB;
865 case IRT_I16: case IRT_U16: return PPCI_STH;
866 case IRT_NUM: return PPCI_STFD;
867 case IRT_FLOAT: return PPCI_STFS;
868 default: return PPCI_STW;
869 }
870}
871
872static void asm_fload(ASMState *as, IRIns *ir)
873{
874 Reg dest = ra_dest(as, ir, RSET_GPR);
875 Reg idx = ra_alloc1(as, ir->op1, RSET_GPR);
876 PPCIns pi = asm_fxloadins(ir);
877 int32_t ofs;
878 if (ir->op2 == IRFL_TAB_ARRAY) {
879 ofs = asm_fuseabase(as, ir->op1);
880 if (ofs) { /* Turn the t->array load into an add for colocated arrays. */
881 emit_tai(as, PPCI_ADDI, dest, idx, ofs);
882 return;
883 }
884 }
885 ofs = field_ofs[ir->op2];
886 lua_assert(!irt_isi8(ir->t));
887 emit_tai(as, pi, dest, idx, ofs);
888}
889
890static void asm_fstore(ASMState *as, IRIns *ir)
891{
892 Reg src = ra_alloc1(as, ir->op2, RSET_GPR);
893 IRIns *irf = IR(ir->op1);
894 Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
895 int32_t ofs = field_ofs[irf->op2];
896 PPCIns pi = asm_fxstoreins(ir);
897 emit_tai(as, pi, src, idx, ofs);
898}
899
900static void asm_xload(ASMState *as, IRIns *ir)
901{
902 Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
903 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
904 if (irt_isi8(ir->t))
905 emit_as(as, PPCI_EXTSB, dest, dest);
906 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR);
907}
908
909static void asm_xstore(ASMState *as, IRIns *ir)
910{
911 IRIns *irb;
912 if (mayfuse(as, ir->op2) && (irb = IR(ir->op2))->o == IR_BSWAP &&
913 ra_noreg(irb->r) && (irt_isint(ir->t) || irt_isu32(ir->t))) {
914 /* Fuse BSWAP with XSTORE to stwbrx. */
915 Reg src = ra_alloc1(as, irb->op1, RSET_GPR);
916 asm_fusexrefx(as, PPCI_STWBRX, src, ir->op1, rset_exclude(RSET_GPR, src));
917 } else {
918 Reg src = ra_alloc1(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
919 asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
920 rset_exclude(RSET_GPR, src));
921 }
922}
923
924static void asm_ahuvload(ASMState *as, IRIns *ir)
925{
926 IRType1 t = ir->t;
927 Reg dest = RID_NONE, type = RID_TMP, tmp = RID_TMP, idx;
928 RegSet allow = RSET_GPR;
929 int32_t ofs = AHUREF_LSX;
930 if (ra_used(ir)) {
931 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
932 if (!irt_isnum(t)) ofs = 0;
933 dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR);
934 rset_clear(allow, dest);
935 }
936 idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
937 if (irt_isnum(t)) {
938 Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, rset_exclude(allow, idx));
939 asm_guardcc(as, CC_GE);
940 emit_ab(as, PPCI_CMPLW, type, tisnum);
941 if (ra_hasreg(dest)) {
942 if (ofs == AHUREF_LSX) {
943 tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_GPR,
944 (idx&255)), (idx>>8)));
945 emit_fab(as, PPCI_LFDX, dest, (idx&255), tmp);
946 } else {
947 emit_fai(as, PPCI_LFD, dest, idx, ofs);
948 }
949 }
950 } else {
951 asm_guardcc(as, CC_NE);
952 emit_ai(as, PPCI_CMPWI, type, irt_toitype(t));
953 if (ra_hasreg(dest)) emit_tai(as, PPCI_LWZ, dest, idx, ofs+4);
954 }
955 if (ofs == AHUREF_LSX) {
956 emit_tab(as, PPCI_LWZX, type, (idx&255), tmp);
957 emit_slwi(as, tmp, (idx>>8), 3);
958 } else {
959 emit_tai(as, PPCI_LWZ, type, idx, ofs);
960 }
961}
962
963static void asm_ahustore(ASMState *as, IRIns *ir)
964{
965 RegSet allow = RSET_GPR;
966 Reg idx, src = RID_NONE, type = RID_NONE;
967 int32_t ofs = AHUREF_LSX;
968 if (irt_isnum(ir->t)) {
969 src = ra_alloc1(as, ir->op2, RSET_FPR);
970 } else {
971 if (!irt_ispri(ir->t)) {
972 src = ra_alloc1(as, ir->op2, allow);
973 rset_clear(allow, src);
974 ofs = 0;
975 }
976 type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
977 rset_clear(allow, type);
978 }
979 idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
980 if (irt_isnum(ir->t)) {
981 if (ofs == AHUREF_LSX) {
982 emit_fab(as, PPCI_STFDX, src, (idx&255), RID_TMP);
983 emit_slwi(as, RID_TMP, (idx>>8), 3);
984 } else {
985 emit_fai(as, PPCI_STFD, src, idx, ofs);
986 }
987 } else {
988 if (ra_hasreg(src))
989 emit_tai(as, PPCI_STW, src, idx, ofs+4);
990 if (ofs == AHUREF_LSX) {
991 emit_tab(as, PPCI_STWX, type, (idx&255), RID_TMP);
992 emit_slwi(as, RID_TMP, (idx>>8), 3);
993 } else {
994 emit_tai(as, PPCI_STW, type, idx, ofs);
995 }
996 }
997}
998
999static void asm_sload(ASMState *as, IRIns *ir)
1000{
1001 int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 0 : 4);
1002 IRType1 t = ir->t;
1003 Reg dest = RID_NONE, type = RID_NONE, base;
1004 RegSet allow = RSET_GPR;
1005 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
1006 lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK));
1007 lua_assert(LJ_DUALNUM ||
1008 !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
1009 if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
1010 dest = ra_scratch(as, RSET_FPR);
1011 asm_tointg(as, ir, dest);
1012 t.irt = IRT_NUM; /* Continue with a regular number type check. */
1013 } else if (ra_used(ir)) {
1014 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
1015 dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR);
1016 rset_clear(allow, dest);
1017 base = ra_alloc1(as, REF_BASE, allow);
1018 rset_clear(allow, base);
1019 if ((ir->op2 & IRSLOAD_CONVERT)) {
1020 if (irt_isint(t)) {
1021 emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO);
1022 dest = ra_scratch(as, RSET_FPR);
1023 emit_fai(as, PPCI_STFD, dest, RID_SP, SPOFS_TMP);
1024 emit_fb(as, PPCI_FCTIWZ, dest, dest);
1025 t.irt = IRT_NUM; /* Check for original type. */
1026 } else {
1027 Reg tmp = ra_scratch(as, allow);
1028 Reg hibias = ra_allock(as, 0x43300000, rset_clear(allow, tmp));
1029 Reg fbias = ra_scratch(as, rset_exclude(RSET_FPR, dest));
1030 emit_fab(as, PPCI_FSUB, dest, dest, fbias);
1031 emit_fai(as, PPCI_LFD, dest, RID_SP, SPOFS_TMP);
1032 emit_lsptr(as, PPCI_LFS, (fbias & 31),
1033 (void *)lj_ir_k64_find(as->J, U64x(59800004,59800000)),
1034 rset_clear(allow, hibias));
1035 emit_tai(as, PPCI_STW, tmp, RID_SP, SPOFS_TMPLO);
1036 emit_tai(as, PPCI_STW, hibias, RID_SP, SPOFS_TMPHI);
1037 emit_asi(as, PPCI_XORIS, tmp, tmp, 0x8000);
1038 dest = tmp;
1039 t.irt = IRT_INT; /* Check for original type. */
1040 }
1041 }
1042 goto dotypecheck;
1043 }
1044 base = ra_alloc1(as, REF_BASE, allow);
1045 rset_clear(allow, base);
1046dotypecheck:
1047 if (irt_isnum(t)) {
1048 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
1049 Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, allow);
1050 asm_guardcc(as, CC_GE);
1051 emit_ab(as, PPCI_CMPLW, RID_TMP, tisnum);
1052 type = RID_TMP;
1053 }
1054 if (ra_hasreg(dest)) emit_fai(as, PPCI_LFD, dest, base, ofs-4);
1055 } else {
1056 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
1057 asm_guardcc(as, CC_NE);
1058 emit_ai(as, PPCI_CMPWI, RID_TMP, irt_toitype(t));
1059 type = RID_TMP;
1060 }
1061 if (ra_hasreg(dest)) emit_tai(as, PPCI_LWZ, dest, base, ofs);
1062 }
1063 if (ra_hasreg(type)) emit_tai(as, PPCI_LWZ, type, base, ofs-4);
1064}
1065
1066/* -- Allocations --------------------------------------------------------- */
1067
1068#if LJ_HASFFI
1069static void asm_cnew(ASMState *as, IRIns *ir)
1070{
1071 CTState *cts = ctype_ctsG(J2G(as->J));
1072 CTypeID typeid = (CTypeID)IR(ir->op1)->i;
1073 CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ?
1074 lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i;
1075 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
1076 IRRef args[2];
1077 RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
1078 RegSet drop = RSET_SCRATCH;
1079 lua_assert(sz != CTSIZE_INVALID);
1080
1081 args[0] = ASMREF_L; /* lua_State *L */
1082 args[1] = ASMREF_TMP1; /* MSize size */
1083 as->gcsteps++;
1084
1085 if (ra_hasreg(ir->r))
1086 rset_clear(drop, ir->r); /* Dest reg handled below. */
1087 ra_evictset(as, drop);
1088 if (ra_used(ir))
1089 ra_destreg(as, ir, RID_RET); /* GCcdata * */
1090
1091 /* Initialize immutable cdata object. */
1092 if (ir->o == IR_CNEWI) {
1093 int32_t ofs = sizeof(GCcdata);
1094 lua_assert(sz == 4 || sz == 8);
1095 if (sz == 8) {
1096 ofs += 4;
1097 lua_assert((ir+1)->o == IR_HIOP);
1098 }
1099 for (;;) {
1100 Reg r = ra_alloc1(as, ir->op2, allow);
1101 emit_tai(as, PPCI_STW, r, RID_RET, ofs);
1102 rset_clear(allow, r);
1103 if (ofs == sizeof(GCcdata)) break;
1104 ofs -= 4; ir++;
1105 }
1106 }
1107 /* Initialize gct and typeid. lj_mem_newgco() already sets marked. */
1108 emit_tai(as, PPCI_STB, RID_RET+1, RID_RET, offsetof(GCcdata, gct));
1109 emit_tai(as, PPCI_STH, RID_TMP, RID_RET, offsetof(GCcdata, typeid));
1110 emit_ti(as, PPCI_LI, RID_RET+1, ~LJ_TCDATA);
1111 emit_ti(as, PPCI_LI, RID_TMP, typeid); /* Lower 16 bit used. Sign-ext ok. */
1112 asm_gencall(as, ci, args);
1113 ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
1114 ra_releasetmp(as, ASMREF_TMP1));
1115}
1116#else
1117#define asm_cnew(as, ir) ((void)0)
1118#endif
1119
1120/* -- Write barriers ------------------------------------------------------ */
1121
1122static void asm_tbar(ASMState *as, IRIns *ir)
1123{
1124 Reg tab = ra_alloc1(as, ir->op1, RSET_GPR);
1125 Reg mark = ra_scratch(as, rset_exclude(RSET_GPR, tab));
1126 Reg link = RID_TMP;
1127 MCLabel l_end = emit_label(as);
1128 emit_tai(as, PPCI_STW, link, tab, (int32_t)offsetof(GCtab, gclist));
1129 emit_tai(as, PPCI_STB, mark, tab, (int32_t)offsetof(GCtab, marked));
1130 emit_setgl(as, tab, gc.grayagain);
1131 lua_assert(LJ_GC_BLACK == 0x04);
1132 emit_rot(as, PPCI_RLWINM, mark, mark, 0, 30, 28); /* Clear black bit. */
1133 emit_getgl(as, link, gc.grayagain);
1134 emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end);
1135 emit_asi(as, PPCI_ANDIDOT, RID_TMP, mark, LJ_GC_BLACK);
1136 emit_tai(as, PPCI_LBZ, mark, tab, (int32_t)offsetof(GCtab, marked));
1137}
1138
1139static void asm_obar(ASMState *as, IRIns *ir)
1140{
1141 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_gc_barrieruv];
1142 IRRef args[2];
1143 MCLabel l_end;
1144 Reg obj, val, tmp;
1145 /* No need for other object barriers (yet). */
1146 lua_assert(IR(ir->op1)->o == IR_UREFC);
1147 ra_evictset(as, RSET_SCRATCH);
1148 l_end = emit_label(as);
1149 args[0] = ASMREF_TMP1; /* global_State *g */
1150 args[1] = ir->op1; /* TValue *tv */
1151 asm_gencall(as, ci, args);
1152 emit_tai(as, PPCI_ADDI, ra_releasetmp(as, ASMREF_TMP1), RID_JGL, -32768);
1153 obj = IR(ir->op1)->r;
1154 tmp = ra_scratch(as, rset_exclude(RSET_GPR, obj));
1155 emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end);
1156 emit_asi(as, PPCI_ANDIDOT, tmp, tmp, LJ_GC_BLACK);
1157 emit_condbranch(as, PPCI_BC, CC_EQ, l_end);
1158 emit_asi(as, PPCI_ANDIDOT, RID_TMP, RID_TMP, LJ_GC_WHITES);
1159 val = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, obj));
1160 emit_tai(as, PPCI_LBZ, tmp, obj,
1161 (int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv));
1162 emit_tai(as, PPCI_LBZ, RID_TMP, val, (int32_t)offsetof(GChead, marked));
1163}
1164
1165/* -- Arithmetic and logic operations ------------------------------------- */
1166
1167static void asm_fparith(ASMState *as, IRIns *ir, PPCIns pi)
1168{
1169 Reg dest = ra_dest(as, ir, RSET_FPR);
1170 Reg right, left = ra_alloc2(as, ir, RSET_FPR);
1171 right = (left >> 8); left &= 255;
1172 if (pi == PPCI_FMUL)
1173 emit_fac(as, pi, dest, left, right);
1174 else
1175 emit_fab(as, pi, dest, left, right);
1176}
1177
1178static void asm_fpunary(ASMState *as, IRIns *ir, PPCIns pi)
1179{
1180 Reg dest = ra_dest(as, ir, RSET_FPR);
1181 Reg left = ra_hintalloc(as, ir->op1, dest, RSET_FPR);
1182 emit_fb(as, pi, dest, left);
1183}
1184
1185static int asm_fpjoin_pow(ASMState *as, IRIns *ir)
1186{
1187 IRIns *irp = IR(ir->op1);
1188 if (irp == ir-1 && irp->o == IR_MUL && !ra_used(irp)) {
1189 IRIns *irpp = IR(irp->op1);
1190 if (irpp == ir-2 && irpp->o == IR_FPMATH &&
1191 irpp->op2 == IRFPM_LOG2 && !ra_used(irpp)) {
1192 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_pow];
1193 IRRef args[2];
1194 args[0] = irpp->op1;
1195 args[1] = irp->op2;
1196 asm_setupresult(as, ir, ci);
1197 asm_gencall(as, ci, args);
1198 return 1;
1199 }
1200 }
1201 return 0;
1202}
1203
1204static void asm_add(ASMState *as, IRIns *ir)
1205{
1206 if (irt_isnum(ir->t)) {
1207 if (!asm_fusemadd(as, ir, PPCI_FMADD, PPCI_FMADD))
1208 asm_fparith(as, ir, PPCI_FADD);
1209 } else {
1210 Reg dest = ra_dest(as, ir, RSET_GPR);
1211 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1212 PPCIns pi;
1213 if (irref_isk(ir->op2)) {
1214 int32_t k = IR(ir->op2)->i;
1215 if (checki16(k)) {
1216 pi = PPCI_ADDI;
1217 /* May fail due to spills/restores above, but simplifies the logic. */
1218 if (as->flagmcp == as->mcp) {
1219 as->flagmcp = NULL;
1220 as->mcp++;
1221 pi = PPCI_ADDICDOT;
1222 }
1223 emit_tai(as, pi, dest, left, k);
1224 return;
1225 } else if ((k & 0xffff) == 0) {
1226 emit_tai(as, PPCI_ADDIS, dest, left, (k >> 16));
1227 return;
1228 } else if (!as->sectref) {
1229 emit_tai(as, PPCI_ADDIS, dest, dest, (k + 32768) >> 16);
1230 emit_tai(as, PPCI_ADDI, dest, left, k);
1231 return;
1232 }
1233 }
1234 pi = PPCI_ADD;
1235 /* May fail due to spills/restores above, but simplifies the logic. */
1236 if (as->flagmcp == as->mcp) {
1237 as->flagmcp = NULL;
1238 as->mcp++;
1239 pi |= PPCF_DOT;
1240 }
1241 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1242 emit_tab(as, pi, dest, left, right);
1243 }
1244}
1245
1246static void asm_sub(ASMState *as, IRIns *ir)
1247{
1248 if (irt_isnum(ir->t)) {
1249 if (!asm_fusemadd(as, ir, PPCI_FMSUB, PPCI_FNMSUB))
1250 asm_fparith(as, ir, PPCI_FSUB);
1251 } else {
1252 PPCIns pi = PPCI_SUBF;
1253 Reg dest = ra_dest(as, ir, RSET_GPR);
1254 Reg left, right;
1255 if (irref_isk(ir->op1)) {
1256 int32_t k = IR(ir->op1)->i;
1257 if (checki16(k)) {
1258 right = ra_alloc1(as, ir->op2, RSET_GPR);
1259 emit_tai(as, PPCI_SUBFIC, dest, right, k);
1260 return;
1261 }
1262 }
1263 /* May fail due to spills/restores above, but simplifies the logic. */
1264 if (as->flagmcp == as->mcp) {
1265 as->flagmcp = NULL;
1266 as->mcp++;
1267 pi |= PPCF_DOT;
1268 }
1269 left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1270 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1271 emit_tab(as, pi, dest, right, left); /* Subtract right _from_ left. */
1272 }
1273}
1274
1275static void asm_mul(ASMState *as, IRIns *ir)
1276{
1277 if (irt_isnum(ir->t)) {
1278 asm_fparith(as, ir, PPCI_FMUL);
1279 } else {
1280 PPCIns pi = PPCI_MULLW;
1281 Reg dest = ra_dest(as, ir, RSET_GPR);
1282 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1283 if (irref_isk(ir->op2)) {
1284 int32_t k = IR(ir->op2)->i;
1285 if (checki16(k)) {
1286 emit_tai(as, PPCI_MULLI, dest, left, k);
1287 return;
1288 }
1289 }
1290 /* May fail due to spills/restores above, but simplifies the logic. */
1291 if (as->flagmcp == as->mcp) {
1292 as->flagmcp = NULL;
1293 as->mcp++;
1294 pi |= PPCF_DOT;
1295 }
1296 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1297 emit_tab(as, pi, dest, left, right);
1298 }
1299}
1300
1301static void asm_neg(ASMState *as, IRIns *ir)
1302{
1303 if (irt_isnum(ir->t)) {
1304 asm_fpunary(as, ir, PPCI_FNEG);
1305 } else {
1306 Reg dest, left;
1307 PPCIns pi = PPCI_NEG;
1308 if (as->flagmcp == as->mcp) {
1309 as->flagmcp = NULL;
1310 as->mcp++;
1311 pi |= PPCF_DOT;
1312 }
1313 dest = ra_dest(as, ir, RSET_GPR);
1314 left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1315 emit_tab(as, pi, dest, left, 0);
1316 }
1317}
1318
1319static void asm_arithov(ASMState *as, IRIns *ir, PPCIns pi)
1320{
1321 Reg dest, left, right;
1322 if (as->flagmcp == as->mcp) {
1323 as->flagmcp = NULL;
1324 as->mcp++;
1325 }
1326 asm_guardcc(as, CC_SO);
1327 dest = ra_dest(as, ir, RSET_GPR);
1328 left = ra_alloc2(as, ir, RSET_GPR);
1329 right = (left >> 8); left &= 255;
1330 if (pi == PPCI_SUBFO) { Reg tmp = left; left = right; right = tmp; }
1331 emit_tab(as, pi|PPCF_DOT, dest, left, right);
1332}
1333
1334#if LJ_HASFFI
1335static void asm_add64(ASMState *as, IRIns *ir)
1336{
1337 Reg dest = ra_dest(as, ir, RSET_GPR);
1338 Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR);
1339 PPCIns pi = PPCI_ADDE;
1340 if (irref_isk(ir->op2)) {
1341 int32_t k = IR(ir->op2)->i;
1342 if (k == 0)
1343 pi = PPCI_ADDZE;
1344 else if (k == -1)
1345 pi = PPCI_ADDME;
1346 else
1347 goto needright;
1348 right = 0;
1349 } else {
1350 needright:
1351 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1352 }
1353 emit_tab(as, pi, dest, left, right);
1354 ir--;
1355 dest = ra_dest(as, ir, RSET_GPR);
1356 left = ra_alloc1(as, ir->op1, RSET_GPR);
1357 if (irref_isk(ir->op2)) {
1358 int32_t k = IR(ir->op2)->i;
1359 if (checki16(k)) {
1360 emit_tai(as, PPCI_ADDIC, dest, left, k);
1361 return;
1362 }
1363 }
1364 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1365 emit_tab(as, PPCI_ADDC, dest, left, right);
1366}
1367
1368static void asm_sub64(ASMState *as, IRIns *ir)
1369{
1370 Reg dest = ra_dest(as, ir, RSET_GPR);
1371 Reg left, right = ra_alloc1(as, ir->op2, RSET_GPR);
1372 PPCIns pi = PPCI_SUBFE;
1373 if (irref_isk(ir->op1)) {
1374 int32_t k = IR(ir->op1)->i;
1375 if (k == 0)
1376 pi = PPCI_SUBFZE;
1377 else if (k == -1)
1378 pi = PPCI_SUBFME;
1379 else
1380 goto needleft;
1381 left = 0;
1382 } else {
1383 needleft:
1384 left = ra_alloc1(as, ir->op1, rset_exclude(RSET_GPR, right));
1385 }
1386 emit_tab(as, pi, dest, right, left); /* Subtract right _from_ left. */
1387 ir--;
1388 dest = ra_dest(as, ir, RSET_GPR);
1389 right = ra_alloc1(as, ir->op2, RSET_GPR);
1390 if (irref_isk(ir->op1)) {
1391 int32_t k = IR(ir->op1)->i;
1392 if (checki16(k)) {
1393 emit_tai(as, PPCI_SUBFIC, dest, right, k);
1394 return;
1395 }
1396 }
1397 left = ra_alloc1(as, ir->op1, rset_exclude(RSET_GPR, right));
1398 emit_tab(as, PPCI_SUBFC, dest, right, left);
1399}
1400
1401static void asm_neg64(ASMState *as, IRIns *ir)
1402{
1403 Reg dest = ra_dest(as, ir, RSET_GPR);
1404 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
1405 emit_tab(as, PPCI_SUBFZE, dest, left, 0);
1406 ir--;
1407 dest = ra_dest(as, ir, RSET_GPR);
1408 left = ra_alloc1(as, ir->op1, RSET_GPR);
1409 emit_tai(as, PPCI_SUBFIC, dest, left, 0);
1410}
1411#endif
1412
1413static void asm_bitnot(ASMState *as, IRIns *ir)
1414{
1415 Reg dest, left, right;
1416 PPCIns pi = PPCI_NOR;
1417 if (as->flagmcp == as->mcp) {
1418 as->flagmcp = NULL;
1419 as->mcp++;
1420 pi |= PPCF_DOT;
1421 }
1422 dest = ra_dest(as, ir, RSET_GPR);
1423 if (mayfuse(as, ir->op1)) {
1424 IRIns *irl = IR(ir->op1);
1425 if (irl->o == IR_BAND)
1426 pi ^= (PPCI_NOR ^ PPCI_NAND);
1427 else if (irl->o == IR_BXOR)
1428 pi ^= (PPCI_NOR ^ PPCI_EQV);
1429 else if (irl->o != IR_BOR)
1430 goto nofuse;
1431 left = ra_hintalloc(as, irl->op1, dest, RSET_GPR);
1432 right = ra_alloc1(as, irl->op2, rset_exclude(RSET_GPR, left));
1433 } else {
1434nofuse:
1435 left = right = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1436 }
1437 emit_asb(as, pi, dest, left, right);
1438}
1439
1440static void asm_bitswap(ASMState *as, IRIns *ir)
1441{
1442 Reg dest = ra_dest(as, ir, RSET_GPR);
1443 IRIns *irx;
1444 if (mayfuse(as, ir->op1) && (irx = IR(ir->op1))->o == IR_XLOAD &&
1445 ra_noreg(irx->r) && (irt_isint(irx->t) || irt_isu32(irx->t))) {
1446 /* Fuse BSWAP with XLOAD to lwbrx. */
1447 asm_fusexrefx(as, PPCI_LWBRX, dest, irx->op1, RSET_GPR);
1448 } else {
1449 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
1450 Reg tmp = dest;
1451 if (tmp == left) {
1452 tmp = RID_TMP;
1453 emit_mr(as, dest, RID_TMP);
1454 }
1455 emit_rot(as, PPCI_RLWIMI, tmp, left, 24, 16, 23);
1456 emit_rot(as, PPCI_RLWIMI, tmp, left, 24, 0, 7);
1457 emit_rotlwi(as, tmp, left, 8);
1458 }
1459}
1460
1461static void asm_bitop(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
1462{
1463 Reg dest = ra_dest(as, ir, RSET_GPR);
1464 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1465 if (irref_isk(ir->op2)) {
1466 int32_t k = IR(ir->op2)->i;
1467 Reg tmp = left;
1468 if ((checku16(k) || (k & 0xffff) == 0) || (tmp = dest, !as->sectref)) {
1469 if (!checku16(k)) {
1470 emit_asi(as, pik ^ (PPCI_ORI ^ PPCI_ORIS), dest, tmp, (k >> 16));
1471 if ((k & 0xffff) == 0) return;
1472 }
1473 emit_asi(as, pik, dest, left, k);
1474 return;
1475 }
1476 }
1477 /* May fail due to spills/restores above, but simplifies the logic. */
1478 if (as->flagmcp == as->mcp) {
1479 as->flagmcp = NULL;
1480 as->mcp++;
1481 pi |= PPCF_DOT;
1482 }
1483 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1484 emit_asb(as, pi, dest, left, right);
1485}
1486
1487/* Fuse BAND with contiguous bitmask and a shift to rlwinm. */
1488static void asm_fuseandsh(ASMState *as, PPCIns pi, int32_t mask, IRRef ref)
1489{
1490 IRIns *ir;
1491 Reg left;
1492 if (mayfuse(as, ref) && (ir = IR(ref), ra_noreg(ir->r)) &&
1493 irref_isk(ir->op2) && ir->o >= IR_BSHL && ir->o <= IR_BROR) {
1494 int32_t sh = (IR(ir->op2)->i & 31);
1495 switch (ir->o) {
1496 case IR_BSHL:
1497 if ((mask & ((1u<<sh)-1))) goto nofuse;
1498 break;
1499 case IR_BSHR:
1500 if ((mask & ~((~0u)>>sh))) goto nofuse;
1501 sh = ((32-sh)&31);
1502 break;
1503 case IR_BROL:
1504 break;
1505 default:
1506 goto nofuse;
1507 }
1508 left = ra_alloc1(as, ir->op1, RSET_GPR);
1509 *--as->mcp = pi | PPCF_T(left) | PPCF_B(sh);
1510 return;
1511 }
1512nofuse:
1513 left = ra_alloc1(as, ref, RSET_GPR);
1514 *--as->mcp = pi | PPCF_T(left);
1515}
1516
1517static void asm_bitand(ASMState *as, IRIns *ir)
1518{
1519 Reg dest, left, right;
1520 IRRef lref = ir->op1;
1521 PPCIns dot = 0;
1522 IRRef op2;
1523 if (as->flagmcp == as->mcp) {
1524 as->flagmcp = NULL;
1525 as->mcp++;
1526 dot = PPCF_DOT;
1527 }
1528 dest = ra_dest(as, ir, RSET_GPR);
1529 if (irref_isk(ir->op2)) {
1530 int32_t k = IR(ir->op2)->i;
1531 if (k) {
1532 /* First check for a contiguous bitmask as used by rlwinm. */
1533 uint32_t s1 = lj_ffs((uint32_t)k);
1534 uint32_t k1 = ((uint32_t)k >> s1);
1535 if ((k1 & (k1+1)) == 0) {
1536 asm_fuseandsh(as, PPCI_RLWINM|dot | PPCF_A(dest) |
1537 PPCF_MB(31-lj_fls((uint32_t)k)) | PPCF_ME(31-s1),
1538 k, lref);
1539 return;
1540 }
1541 if (~(uint32_t)k) {
1542 uint32_t s2 = lj_ffs(~(uint32_t)k);
1543 uint32_t k2 = (~(uint32_t)k >> s2);
1544 if ((k2 & (k2+1)) == 0) {
1545 asm_fuseandsh(as, PPCI_RLWINM|dot | PPCF_A(dest) |
1546 PPCF_MB(32-s2) | PPCF_ME(30-lj_fls(~(uint32_t)k)),
1547 k, lref);
1548 return;
1549 }
1550 }
1551 }
1552 if (checku16(k)) {
1553 left = ra_alloc1(as, lref, RSET_GPR);
1554 emit_asi(as, PPCI_ANDIDOT, dest, left, k);
1555 return;
1556 } else if ((k & 0xffff) == 0) {
1557 left = ra_alloc1(as, lref, RSET_GPR);
1558 emit_asi(as, PPCI_ANDISDOT, dest, left, (k >> 16));
1559 return;
1560 }
1561 }
1562 op2 = ir->op2;
1563 if (mayfuse(as, op2) && IR(op2)->o == IR_BNOT && ra_noreg(IR(op2)->r)) {
1564 dot ^= (PPCI_AND ^ PPCI_ANDC);
1565 op2 = IR(op2)->op1;
1566 }
1567 left = ra_hintalloc(as, lref, dest, RSET_GPR);
1568 right = ra_alloc1(as, op2, rset_exclude(RSET_GPR, left));
1569 emit_asb(as, PPCI_AND ^ dot, dest, left, right);
1570}
1571
1572static void asm_bitshift(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
1573{
1574 Reg dest, left;
1575 Reg dot = 0;
1576 if (as->flagmcp == as->mcp) {
1577 as->flagmcp = NULL;
1578 as->mcp++;
1579 dot = PPCF_DOT;
1580 }
1581 dest = ra_dest(as, ir, RSET_GPR);
1582 left = ra_alloc1(as, ir->op1, RSET_GPR);
1583 if (irref_isk(ir->op2)) { /* Constant shifts. */
1584 int32_t shift = (IR(ir->op2)->i & 31);
1585 if (pik == 0) /* SLWI */
1586 emit_rot(as, PPCI_RLWINM|dot, dest, left, shift, 0, 31-shift);
1587 else if (pik == 1) /* SRWI */
1588 emit_rot(as, PPCI_RLWINM|dot, dest, left, (32-shift)&31, shift, 31);
1589 else
1590 emit_asb(as, pik|dot, dest, left, shift);
1591 } else {
1592 Reg right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1593 emit_asb(as, pi|dot, dest, left, right);
1594 }
1595}
1596
1597static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
1598{
1599 if (irt_isnum(ir->t)) {
1600 Reg dest = ra_dest(as, ir, RSET_FPR);
1601 Reg tmp = dest;
1602 Reg right, left = ra_alloc2(as, ir, RSET_FPR);
1603 right = (left >> 8); left &= 255;
1604 if (tmp == left || tmp == right)
1605 tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_FPR,
1606 dest), left), right));
1607 emit_facb(as, PPCI_FSEL, dest, tmp,
1608 ismax ? left : right, ismax ? right : left);
1609 emit_fab(as, PPCI_FSUB, tmp, left, right);
1610 } else {
1611 Reg dest = ra_dest(as, ir, RSET_GPR);
1612 Reg tmp1 = RID_TMP, tmp2 = dest;
1613 Reg right, left = ra_alloc2(as, ir, RSET_GPR);
1614 right = (left >> 8); left &= 255;
1615 if (tmp2 == left || tmp2 == right)
1616 tmp2 = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_GPR,
1617 dest), left), right));
1618 emit_tab(as, PPCI_ADD, dest, tmp2, right);
1619 emit_asb(as, ismax ? PPCI_ANDC : PPCI_AND, tmp2, tmp2, tmp1);
1620 emit_tab(as, PPCI_SUBFE, tmp1, tmp1, tmp1);
1621 emit_tab(as, PPCI_SUBFC, tmp2, tmp2, tmp1);
1622 emit_asi(as, PPCI_XORIS, tmp2, right, 0x8000);
1623 emit_asi(as, PPCI_XORIS, tmp1, left, 0x8000);
1624 }
1625}
1626
1627/* -- Comparisons --------------------------------------------------------- */
1628
1629#define CC_UNSIGNED 0x08 /* Unsigned integer comparison. */
1630#define CC_TWO 0x80 /* Check two flags for FP comparison. */
1631
1632/* Map of comparisons to flags. ORDER IR. */
1633static const uint8_t asm_compmap[IR_ABC+1] = {
1634 /* op int cc FP cc */
1635 /* LT */ CC_GE + (CC_GE<<4),
1636 /* GE */ CC_LT + (CC_LE<<4) + CC_TWO,
1637 /* LE */ CC_GT + (CC_GE<<4) + CC_TWO,
1638 /* GT */ CC_LE + (CC_LE<<4),
1639 /* ULT */ CC_GE + CC_UNSIGNED + (CC_GT<<4) + CC_TWO,
1640 /* UGE */ CC_LT + CC_UNSIGNED + (CC_LT<<4),
1641 /* ULE */ CC_GT + CC_UNSIGNED + (CC_GT<<4),
1642 /* UGT */ CC_LE + CC_UNSIGNED + (CC_LT<<4) + CC_TWO,
1643 /* EQ */ CC_NE + (CC_NE<<4),
1644 /* NE */ CC_EQ + (CC_EQ<<4),
1645 /* ABC */ CC_LE + CC_UNSIGNED + (CC_LT<<4) + CC_TWO /* Same as UGT. */
1646};
1647
1648static void asm_intcomp_(ASMState *as, IRRef lref, IRRef rref, Reg cr, PPCCC cc)
1649{
1650 Reg right, left = ra_alloc1(as, lref, RSET_GPR);
1651 if (irref_isk(rref)) {
1652 int32_t k = IR(rref)->i;
1653 if ((cc & CC_UNSIGNED) == 0) { /* Signed comparison with constant. */
1654 if (checki16(k)) {
1655 emit_tai(as, PPCI_CMPWI, cr, left, k);
1656 /* Signed comparison with zero and referencing previous ins? */
1657 if (k == 0 && lref == as->curins-1)
1658 as->flagmcp = as->mcp; /* Allow elimination of the compare. */
1659 return;
1660 } else if ((cc & 3) == (CC_EQ & 3)) { /* Use CMPLWI for EQ or NE. */
1661 if (checku16(k)) {
1662 emit_tai(as, PPCI_CMPLWI, cr, left, k);
1663 return;
1664 } else if (!as->sectref && ra_noreg(IR(rref)->r)) {
1665 emit_tai(as, PPCI_CMPLWI, cr, RID_TMP, k);
1666 emit_asi(as, PPCI_XORIS, RID_TMP, left, (k >> 16));
1667 return;
1668 }
1669 }
1670 } else { /* Unsigned comparison with constant. */
1671 if (checku16(k)) {
1672 emit_tai(as, PPCI_CMPLWI, cr, left, k);
1673 return;
1674 }
1675 }
1676 }
1677 right = ra_alloc1(as, rref, rset_exclude(RSET_GPR, left));
1678 emit_tab(as, (cc & CC_UNSIGNED) ? PPCI_CMPLW : PPCI_CMPW, cr, left, right);
1679}
1680
1681static void asm_comp(ASMState *as, IRIns *ir)
1682{
1683 PPCCC cc = asm_compmap[ir->o];
1684 if (irt_isnum(ir->t)) {
1685 Reg right, left = ra_alloc2(as, ir, RSET_FPR);
1686 right = (left >> 8); left &= 255;
1687 asm_guardcc(as, (cc >> 4));
1688 if ((cc & CC_TWO))
1689 emit_tab(as, PPCI_CROR, ((cc>>4)&3), ((cc>>4)&3), (CC_EQ&3));
1690 emit_fab(as, PPCI_FCMPU, 0, left, right);
1691 } else {
1692 IRRef lref = ir->op1, rref = ir->op2;
1693 if (irref_isk(lref) && !irref_isk(rref)) {
1694 /* Swap constants to the right (only for ABC). */
1695 IRRef tmp = lref; lref = rref; rref = tmp;
1696 if ((cc & 2) == 0) cc ^= 1; /* LT <-> GT, LE <-> GE */
1697 }
1698 asm_guardcc(as, cc);
1699 asm_intcomp_(as, lref, rref, 0, cc);
1700 }
1701}
1702
1703#if LJ_HASFFI
1704/* 64 bit integer comparisons. */
1705static void asm_comp64(ASMState *as, IRIns *ir)
1706{
1707 PPCCC cc = asm_compmap[(ir-1)->o];
1708 if ((cc&3) == (CC_EQ&3)) {
1709 asm_guardcc(as, cc);
1710 emit_tab(as, (cc&4) ? PPCI_CRAND : PPCI_CROR,
1711 (CC_EQ&3), (CC_EQ&3), 4+(CC_EQ&3));
1712 } else {
1713 asm_guardcc(as, CC_EQ);
1714 emit_tab(as, PPCI_CROR, (CC_EQ&3), (CC_EQ&3), ((cc^~(cc>>2))&1));
1715 emit_tab(as, (cc&4) ? PPCI_CRAND : PPCI_CRANDC,
1716 (CC_EQ&3), (CC_EQ&3), 4+(cc&3));
1717 }
1718 /* Loword comparison sets cr1 and is unsigned, except for equality. */
1719 asm_intcomp_(as, (ir-1)->op1, (ir-1)->op2, 4,
1720 cc | ((cc&3) == (CC_EQ&3) ? 0 : CC_UNSIGNED));
1721 /* Hiword comparison sets cr0. */
1722 asm_intcomp_(as, ir->op1, ir->op2, 0, cc);
1723 as->flagmcp = NULL; /* Doesn't work here. */
1724}
1725#endif
1726
1727/* -- Support for 64 bit ops in 32 bit mode ------------------------------- */
1728
1729/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
1730static void asm_hiop(ASMState *as, IRIns *ir)
1731{
1732#if LJ_HASFFI
1733 /* HIOP is marked as a store because it needs its own DCE logic. */
1734 int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */
1735 if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
1736 if ((ir-1)->o == IR_CONV) { /* Conversions to/from 64 bit. */
1737 as->curins--; /* Always skip the CONV. */
1738 if (usehi || uselo)
1739 asm_conv64(as, ir);
1740 return;
1741 } else if ((ir-1)->o <= IR_NE) { /* 64 bit integer comparisons. ORDER IR. */
1742 as->curins--; /* Always skip the loword comparison. */
1743 asm_comp64(as, ir);
1744 return;
1745 }
1746 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
1747 switch ((ir-1)->o) {
1748 case IR_ADD: as->curins--; asm_add64(as, ir); break;
1749 case IR_SUB: as->curins--; asm_sub64(as, ir); break;
1750 case IR_NEG: as->curins--; asm_neg64(as, ir); break;
1751 case IR_CALLN:
1752 case IR_CALLXS:
1753 if (!uselo)
1754 ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */
1755 break;
1756 case IR_CNEWI:
1757 /* Nothing to do here. Handled by lo op itself. */
1758 break;
1759 default: lua_assert(0); break;
1760 }
1761#else
1762 UNUSED(as); UNUSED(ir); lua_assert(0); /* Unused without FFI. */
1763#endif
1764}
1765
1766/* -- Stack handling ------------------------------------------------------ */
1767
1768/* Check Lua stack size for overflow. Use exit handler as fallback. */
1769static void asm_stack_check(ASMState *as, BCReg topslot,
1770 IRIns *irp, RegSet allow, ExitNo exitno)
1771{
1772 /* Try to get an unused temp. register, otherwise spill/restore RID_RET*. */
1773 Reg tmp, pbase = irp ? (ra_hasreg(irp->r) ? irp->r : RID_TMP) : RID_BASE;
1774 rset_clear(allow, pbase);
1775 tmp = allow ? rset_pickbot(allow) :
1776 (pbase == RID_RETHI ? RID_RETLO : RID_RETHI);
1777 emit_condbranch(as, PPCI_BC, CC_LT, asm_exitstub_addr(as, exitno));
1778 if (allow == RSET_EMPTY) /* Restore temp. register. */
1779 emit_tai(as, PPCI_LWZ, tmp, RID_SP, SPOFS_TMPW);
1780 else
1781 ra_modified(as, tmp);
1782 emit_ai(as, PPCI_CMPLWI, RID_TMP, (int32_t)(8*topslot));
1783 emit_tab(as, PPCI_SUBF, RID_TMP, pbase, tmp);
1784 emit_tai(as, PPCI_LWZ, tmp, tmp, offsetof(lua_State, maxstack));
1785 if (pbase == RID_TMP)
1786 emit_getgl(as, RID_TMP, jit_base);
1787 emit_getgl(as, tmp, jit_L);
1788 if (allow == RSET_EMPTY) /* Spill temp. register. */
1789 emit_tai(as, PPCI_STW, tmp, RID_SP, SPOFS_TMPW);
1790}
1791
1792/* Restore Lua stack from on-trace state. */
1793static void asm_stack_restore(ASMState *as, SnapShot *snap)
1794{
1795 SnapEntry *map = &as->T->snapmap[snap->mapofs];
1796 SnapEntry *flinks = &as->T->snapmap[snap_nextofs(as->T, snap)-1];
1797 MSize n, nent = snap->nent;
1798 /* Store the value of all modified slots to the Lua stack. */
1799 for (n = 0; n < nent; n++) {
1800 SnapEntry sn = map[n];
1801 BCReg s = snap_slot(sn);
1802 int32_t ofs = 8*((int32_t)s-1);
1803 IRRef ref = snap_ref(sn);
1804 IRIns *ir = IR(ref);
1805 if ((sn & SNAP_NORESTORE))
1806 continue;
1807 if (irt_isnum(ir->t)) {
1808 Reg src = ra_alloc1(as, ref, RSET_FPR);
1809 emit_fai(as, PPCI_STFD, src, RID_BASE, ofs);
1810 } else {
1811 Reg type;
1812 RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
1813 lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t));
1814 if (!irt_ispri(ir->t)) {
1815 Reg src = ra_alloc1(as, ref, allow);
1816 rset_clear(allow, src);
1817 emit_tai(as, PPCI_STW, src, RID_BASE, ofs+4);
1818 }
1819 if ((sn & (SNAP_CONT|SNAP_FRAME))) {
1820 if (s == 0) continue; /* Do not overwrite link to previous frame. */
1821 type = ra_allock(as, (int32_t)(*flinks--), allow);
1822 } else {
1823 type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
1824 }
1825 emit_tai(as, PPCI_STW, type, RID_BASE, ofs);
1826 }
1827 checkmclim(as);
1828 }
1829 lua_assert(map + nent == flinks);
1830}
1831
1832/* -- GC handling --------------------------------------------------------- */
1833
1834/* Check GC threshold and do one or more GC steps. */
1835static void asm_gc_check(ASMState *as)
1836{
1837 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_gc_step_jit];
1838 IRRef args[2];
1839 MCLabel l_end;
1840 Reg tmp;
1841 ra_evictset(as, RSET_SCRATCH);
1842 l_end = emit_label(as);
1843 /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
1844 asm_guardcc(as, CC_NE); /* Assumes asm_snap_prep() already done. */
1845 emit_ai(as, PPCI_CMPWI, RID_RET, 0);
1846 args[0] = ASMREF_TMP1; /* global_State *g */
1847 args[1] = ASMREF_TMP2; /* MSize steps */
1848 asm_gencall(as, ci, args);
1849 emit_tai(as, PPCI_ADDI, ra_releasetmp(as, ASMREF_TMP1), RID_JGL, -32768);
1850 tmp = ra_releasetmp(as, ASMREF_TMP2);
1851 emit_loadi(as, tmp, (int32_t)as->gcsteps);
1852 /* Jump around GC step if GC total < GC threshold. */
1853 emit_condbranch(as, PPCI_BC|PPCF_Y, CC_LT, l_end);
1854 emit_ab(as, PPCI_CMPLW, RID_TMP, tmp);
1855 emit_getgl(as, tmp, gc.threshold);
1856 emit_getgl(as, RID_TMP, gc.total);
1857 as->gcsteps = 0;
1858 checkmclim(as);
1859}
1860
1861/* -- Loop handling ------------------------------------------------------- */
1862
1863/* Fixup the loop branch. */
1864static void asm_loop_fixup(ASMState *as)
1865{
1866 MCode *p = as->mctop;
1867 MCode *target = as->mcp;
1868 if (as->loopinv) { /* Inverted loop branch? */
1869 /* asm_guardcc already inverted the cond branch and patched the final b. */
1870 p[-2] = (p[-2] & (0xffff0000u & ~PPCF_Y)) | (((target-p+2) & 0x3fffu) << 2);
1871 } else {
1872 p[-1] = PPCI_B|(((target-p+1)&0x00ffffffu)<<2);
1873 }
1874}
1875
1876/* -- Head of trace ------------------------------------------------------- */
1877
1878/* Coalesce BASE register for a root trace. */
1879static void asm_head_root_base(ASMState *as)
1880{
1881 IRIns *ir = IR(REF_BASE);
1882 Reg r = ir->r;
1883 if (ra_hasreg(r)) {
1884 ra_free(as, r);
1885 if (rset_test(as->modset, r))
1886 ir->r = RID_INIT; /* No inheritance for modified BASE register. */
1887 if (r != RID_BASE)
1888 emit_mr(as, r, RID_BASE);
1889 }
1890}
1891
1892/* Coalesce BASE register for a side trace. */
1893static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
1894{
1895 IRIns *ir = IR(REF_BASE);
1896 Reg r = ir->r;
1897 if (ra_hasreg(r)) {
1898 ra_free(as, r);
1899 if (rset_test(as->modset, r))
1900 ir->r = RID_INIT; /* No inheritance for modified BASE register. */
1901 if (irp->r == r) {
1902 rset_clear(allow, r); /* Mark same BASE register as coalesced. */
1903 } else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
1904 rset_clear(allow, irp->r);
1905 emit_mr(as, r, irp->r); /* Move from coalesced parent reg. */
1906 } else {
1907 emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
1908 }
1909 }
1910 return allow;
1911}
1912
1913/* -- Tail of trace ------------------------------------------------------- */
1914
1915/* Fixup the tail code. */
1916static void asm_tail_fixup(ASMState *as, TraceNo lnk)
1917{
1918 MCode *p = as->mctop;
1919 MCode *target;
1920 int32_t spadj = as->T->spadjust;
1921 if (spadj == 0) {
1922 *--p = PPCI_NOP;
1923 *--p = PPCI_NOP;
1924 as->mctop = p;
1925 } else {
1926 /* Patch stack adjustment. */
1927 lua_assert(checki16(CFRAME_SIZE+spadj));
1928 p[-3] = PPCI_ADDI | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | (CFRAME_SIZE+spadj);
1929 p[-2] = PPCI_STWU | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | spadj;
1930 }
1931 /* Patch exit branch. */
1932 target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
1933 p[-1] = PPCI_B|(((target-p+1)&0x00ffffffu)<<2);
1934}
1935
1936/* Prepare tail of code. */
1937static void asm_tail_prep(ASMState *as)
1938{
1939 MCode *p = as->mctop - 1; /* Leave room for exit branch. */
1940 if (as->loopref) {
1941 as->invmcp = as->mcp = p;
1942 } else {
1943 as->mcp = p-2; /* Leave room for stack pointer adjustment. */
1944 as->invmcp = NULL;
1945 }
1946}
1947
1948/* -- Instruction dispatch ------------------------------------------------ */
1949
1950/* Assemble a single instruction. */
1951static void asm_ir(ASMState *as, IRIns *ir)
1952{
1953 switch ((IROp)ir->o) {
1954 /* Miscellaneous ops. */
1955 case IR_LOOP: asm_loop(as); break;
1956 case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
1957 case IR_USE:
1958 ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
1959 case IR_PHI: asm_phi(as, ir); break;
1960 case IR_HIOP: asm_hiop(as, ir); break;
1961
1962 /* Guarded assertions. */
1963 case IR_EQ: case IR_NE:
1964 if ((ir-1)->o == IR_HREF && ir->op1 == as->curins-1) {
1965 as->curins--;
1966 asm_href(as, ir-1, (IROp)ir->o);
1967 break;
1968 }
1969 /* fallthrough */
1970 case IR_LT: case IR_GE: case IR_LE: case IR_GT:
1971 case IR_ULT: case IR_UGE: case IR_ULE: case IR_UGT:
1972 case IR_ABC:
1973 asm_comp(as, ir);
1974 break;
1975
1976 case IR_RETF: asm_retf(as, ir); break;
1977
1978 /* Bit ops. */
1979 case IR_BNOT: asm_bitnot(as, ir); break;
1980 case IR_BSWAP: asm_bitswap(as, ir); break;
1981
1982 case IR_BAND: asm_bitand(as, ir); break;
1983 case IR_BOR: asm_bitop(as, ir, PPCI_OR, PPCI_ORI); break;
1984 case IR_BXOR: asm_bitop(as, ir, PPCI_XOR, PPCI_XORI); break;
1985
1986 case IR_BSHL: asm_bitshift(as, ir, PPCI_SLW, 0); break;
1987 case IR_BSHR: asm_bitshift(as, ir, PPCI_SRW, 1); break;
1988 case IR_BSAR: asm_bitshift(as, ir, PPCI_SRAW, PPCI_SRAWI); break;
1989 case IR_BROL: asm_bitshift(as, ir, PPCI_RLWNM|PPCF_MB(0)|PPCF_ME(31),
1990 PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31)); break;
1991 case IR_BROR: lua_assert(0); break;
1992
1993 /* Arithmetic ops. */
1994 case IR_ADD: asm_add(as, ir); break;
1995 case IR_SUB: asm_sub(as, ir); break;
1996 case IR_MUL: asm_mul(as, ir); break;
1997 case IR_DIV: asm_fparith(as, ir, PPCI_FDIV); break;
1998 case IR_MOD: asm_callid(as, ir, IRCALL_lj_vm_modi); break;
1999 case IR_POW: asm_callid(as, ir, IRCALL_lj_vm_powi); break;
2000 case IR_NEG: asm_neg(as, ir); break;
2001
2002 case IR_ABS: asm_fpunary(as, ir, PPCI_FABS); break;
2003 case IR_ATAN2: asm_callid(as, ir, IRCALL_atan2); break;
2004 case IR_LDEXP: asm_callid(as, ir, IRCALL_ldexp); break;
2005 case IR_MIN: asm_min_max(as, ir, 0); break;
2006 case IR_MAX: asm_min_max(as, ir, 1); break;
2007 case IR_FPMATH:
2008 if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
2009 break;
2010 asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
2011 break;
2012
2013 /* Overflow-checking arithmetic ops. */
2014 case IR_ADDOV: asm_arithov(as, ir, PPCI_ADDO); break;
2015 case IR_SUBOV: asm_arithov(as, ir, PPCI_SUBFO); break;
2016 case IR_MULOV: asm_arithov(as, ir, PPCI_MULLWO); break;
2017
2018 /* Memory references. */
2019 case IR_AREF: asm_aref(as, ir); break;
2020 case IR_HREF: asm_href(as, ir, 0); break;
2021 case IR_HREFK: asm_hrefk(as, ir); break;
2022 case IR_NEWREF: asm_newref(as, ir); break;
2023 case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
2024 case IR_FREF: asm_fref(as, ir); break;
2025 case IR_STRREF: asm_strref(as, ir); break;
2026
2027 /* Loads and stores. */
2028 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
2029 asm_ahuvload(as, ir);
2030 break;
2031 case IR_FLOAD: asm_fload(as, ir); break;
2032 case IR_XLOAD: asm_xload(as, ir); break;
2033 case IR_SLOAD: asm_sload(as, ir); break;
2034
2035 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
2036 case IR_FSTORE: asm_fstore(as, ir); break;
2037 case IR_XSTORE: asm_xstore(as, ir); break;
2038
2039 /* Allocations. */
2040 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
2041 case IR_TNEW: asm_tnew(as, ir); break;
2042 case IR_TDUP: asm_tdup(as, ir); break;
2043 case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
2044
2045 /* Write barriers. */
2046 case IR_TBAR: asm_tbar(as, ir); break;
2047 case IR_OBAR: asm_obar(as, ir); break;
2048
2049 /* Type conversions. */
2050 case IR_CONV: asm_conv(as, ir); break;
2051 case IR_TOBIT: asm_tobit(as, ir); break;
2052 case IR_TOSTR: asm_tostr(as, ir); break;
2053 case IR_STRTO: asm_strto(as, ir); break;
2054
2055 /* Calls. */
2056 case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break;
2057 case IR_CALLXS: asm_callx(as, ir); break;
2058 case IR_CARG: break;
2059
2060 default:
2061 setintV(&as->J->errinfo, ir->o);
2062 lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
2063 break;
2064 }
2065}
2066
2067/* -- Trace setup --------------------------------------------------------- */
2068
2069/* Ensure there are enough stack slots for call arguments. */
2070static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
2071{
2072 IRRef args[CCI_NARGS_MAX];
2073 uint32_t i, nargs = (int)CCI_NARGS(ci);
2074 int nslots = 2, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR;
2075 asm_collectargs(as, ir, ci, args);
2076 for (i = 0; i < nargs; i++)
2077 if (args[i] && irt_isfp(IR(args[i])->t)) {
2078 if (nfpr > 0) nfpr--; else nslots = (nslots+3) & ~1;
2079 } else {
2080 if (ngpr > 0) ngpr--; else nslots++;
2081 }
2082 if (nslots > as->evenspill) /* Leave room for args in stack slots. */
2083 as->evenspill = nslots;
2084 return irt_isfp(ir->t) ? REGSP_HINT(RID_FPRET) : REGSP_HINT(RID_RET);
2085}
2086
2087static void asm_setup_target(ASMState *as)
2088{
2089 asm_exitstub_setup(as, as->T->nsnap + (as->parent ? 1 : 0));
2090}
2091
2092/* -- Trace patching ------------------------------------------------------ */
2093
2094/* Patch exit jumps of existing machine code to a new target. */
2095void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2096{
2097 MCode *p = T->mcode;
2098 MCode *pe = (MCode *)((char *)p + T->szmcode);
2099 MCode *px = exitstub_trace_addr(T, exitno);
2100 MCode *cstart = NULL;
2101 MCode *mcarea = lj_mcode_patch(J, p, 0);
2102 int clearso = 0;
2103 for (; p < pe; p++) {
2104 /* Look for exitstub branch, try to replace with branch to target. */
2105 uint32_t ins = *p;
2106 if ((ins & 0xfc000000u) == 0x40000000u &&
2107 ((ins ^ ((char *)px-(char *)p)) & 0xffffu) == 0) {
2108 ptrdiff_t delta = (char *)target - (char *)p;
2109 if (((ins >> 16) & 3) == (CC_SO&3)) {
2110 clearso = sizeof(MCode);
2111 delta -= sizeof(MCode);
2112 }
2113 /* Many, but not all short-range branches can be patched directly. */
2114 if (((delta + 0x8000) >> 16) == 0) {
2115 *p = (ins & 0xffdf0000u) | ((uint32_t)delta & 0xffffu) |
2116 ((delta & 0x8000) * (PPCF_Y/0x8000));
2117 if (!cstart) cstart = p;
2118 }
2119 } else if ((ins & 0xfc000000u) == PPCI_B &&
2120 ((ins ^ ((char *)px-(char *)p)) & 0x03ffffffu) == 0) {
2121 ptrdiff_t delta = (char *)target - (char *)p;
2122 lua_assert(((delta + 0x02000000) >> 26) == 0);
2123 *p = PPCI_B | ((uint32_t)delta & 0x03ffffffu);
2124 if (!cstart) cstart = p;
2125 }
2126 }
2127 { /* Always patch long-range branch in exit stub itself. */
2128 ptrdiff_t delta = (char *)target - (char *)px - clearso;
2129 lua_assert(((delta + 0x02000000) >> 26) == 0);
2130 *px = PPCI_B | ((uint32_t)delta & 0x03ffffffu);
2131 }
2132 if (!cstart) cstart = px;
2133 lj_mcode_sync(cstart, px+1);
2134 if (clearso) { /* Extend the current trace. Ugly workaround. */
2135 MCode *pp = J->cur.mcode;
2136 J->cur.szmcode += sizeof(MCode);
2137 *--pp = PPCI_MCRXR; /* Clear SO flag. */
2138 J->cur.mcode = pp;
2139 lj_mcode_sync(pp, pp+1);
2140 }
2141 lj_mcode_patch(J, mcarea, 1);
2142}
2143
diff --git a/libraries/luajit-2.0/src/lj_asm_x86.h b/libraries/luajit-2.0/src/lj_asm_x86.h
new file mode 100644
index 0000000..1170b66
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_asm_x86.h
@@ -0,0 +1,2751 @@
1/*
2** x86/x64 IR assembler (SSA IR -> machine code).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* -- Guard handling ------------------------------------------------------ */
7
8/* Generate an exit stub group at the bottom of the reserved MCode memory. */
9static MCode *asm_exitstub_gen(ASMState *as, ExitNo group)
10{
11 ExitNo i, groupofs = (group*EXITSTUBS_PER_GROUP) & 0xff;
12 MCode *mxp = as->mcbot;
13 MCode *mxpstart = mxp;
14 if (mxp + (2+2)*EXITSTUBS_PER_GROUP+8+5 >= as->mctop)
15 asm_mclimit(as);
16 /* Push low byte of exitno for each exit stub. */
17 *mxp++ = XI_PUSHi8; *mxp++ = (MCode)groupofs;
18 for (i = 1; i < EXITSTUBS_PER_GROUP; i++) {
19 *mxp++ = XI_JMPs; *mxp++ = (MCode)((2+2)*(EXITSTUBS_PER_GROUP - i) - 2);
20 *mxp++ = XI_PUSHi8; *mxp++ = (MCode)(groupofs + i);
21 }
22 /* Push the high byte of the exitno for each exit stub group. */
23 *mxp++ = XI_PUSHi8; *mxp++ = (MCode)((group*EXITSTUBS_PER_GROUP)>>8);
24 /* Store DISPATCH at original stack slot 0. Account for the two push ops. */
25 *mxp++ = XI_MOVmi;
26 *mxp++ = MODRM(XM_OFS8, 0, RID_ESP);
27 *mxp++ = MODRM(XM_SCALE1, RID_ESP, RID_ESP);
28 *mxp++ = 2*sizeof(void *);
29 *(int32_t *)mxp = ptr2addr(J2GG(as->J)->dispatch); mxp += 4;
30 /* Jump to exit handler which fills in the ExitState. */
31 *mxp++ = XI_JMP; mxp += 4;
32 *((int32_t *)(mxp-4)) = jmprel(mxp, (MCode *)(void *)lj_vm_exit_handler);
33 /* Commit the code for this group (even if assembly fails later on). */
34 lj_mcode_commitbot(as->J, mxp);
35 as->mcbot = mxp;
36 as->mclim = as->mcbot + MCLIM_REDZONE;
37 return mxpstart;
38}
39
40/* Setup all needed exit stubs. */
41static void asm_exitstub_setup(ASMState *as, ExitNo nexits)
42{
43 ExitNo i;
44 if (nexits >= EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR)
45 lj_trace_err(as->J, LJ_TRERR_SNAPOV);
46 for (i = 0; i < (nexits+EXITSTUBS_PER_GROUP-1)/EXITSTUBS_PER_GROUP; i++)
47 if (as->J->exitstubgroup[i] == NULL)
48 as->J->exitstubgroup[i] = asm_exitstub_gen(as, i);
49}
50
51/* Emit conditional branch to exit for guard.
52** It's important to emit this *after* all registers have been allocated,
53** because rematerializations may invalidate the flags.
54*/
55static void asm_guardcc(ASMState *as, int cc)
56{
57 MCode *target = exitstub_addr(as->J, as->snapno);
58 MCode *p = as->mcp;
59 if (LJ_UNLIKELY(p == as->invmcp)) {
60 as->loopinv = 1;
61 *(int32_t *)(p+1) = jmprel(p+5, target);
62 target = p;
63 cc ^= 1;
64 if (as->realign) {
65 emit_sjcc(as, cc, target);
66 return;
67 }
68 }
69 emit_jcc(as, cc, target);
70}
71
72/* -- Memory operand fusion ----------------------------------------------- */
73
74/* Limit linear search to this distance. Avoids O(n^2) behavior. */
75#define CONFLICT_SEARCH_LIM 31
76
77/* Check if a reference is a signed 32 bit constant. */
78static int asm_isk32(ASMState *as, IRRef ref, int32_t *k)
79{
80 if (irref_isk(ref)) {
81 IRIns *ir = IR(ref);
82 if (ir->o != IR_KINT64) {
83 *k = ir->i;
84 return 1;
85 } else if (checki32((int64_t)ir_kint64(ir)->u64)) {
86 *k = (int32_t)ir_kint64(ir)->u64;
87 return 1;
88 }
89 }
90 return 0;
91}
92
93/* Check if there's no conflicting instruction between curins and ref.
94** Also avoid fusing loads if there are multiple references.
95*/
96static int noconflict(ASMState *as, IRRef ref, IROp conflict, int noload)
97{
98 IRIns *ir = as->ir;
99 IRRef i = as->curins;
100 if (i > ref + CONFLICT_SEARCH_LIM)
101 return 0; /* Give up, ref is too far away. */
102 while (--i > ref) {
103 if (ir[i].o == conflict)
104 return 0; /* Conflict found. */
105 else if (!noload && (ir[i].op1 == ref || ir[i].op2 == ref))
106 return 0;
107 }
108 return 1; /* Ok, no conflict. */
109}
110
111/* Fuse array base into memory operand. */
112static IRRef asm_fuseabase(ASMState *as, IRRef ref)
113{
114 IRIns *irb = IR(ref);
115 as->mrm.ofs = 0;
116 if (irb->o == IR_FLOAD) {
117 IRIns *ira = IR(irb->op1);
118 lua_assert(irb->op2 == IRFL_TAB_ARRAY);
119 /* We can avoid the FLOAD of t->array for colocated arrays. */
120 if (ira->o == IR_TNEW && ira->op1 <= LJ_MAX_COLOSIZE &&
121 !neverfuse(as) && noconflict(as, irb->op1, IR_NEWREF, 1)) {
122 as->mrm.ofs = (int32_t)sizeof(GCtab); /* Ofs to colocated array. */
123 return irb->op1; /* Table obj. */
124 }
125 } else if (irb->o == IR_ADD && irref_isk(irb->op2)) {
126 /* Fuse base offset (vararg load). */
127 as->mrm.ofs = IR(irb->op2)->i;
128 return irb->op1;
129 }
130 return ref; /* Otherwise use the given array base. */
131}
132
133/* Fuse array reference into memory operand. */
134static void asm_fusearef(ASMState *as, IRIns *ir, RegSet allow)
135{
136 IRIns *irx;
137 lua_assert(ir->o == IR_AREF);
138 as->mrm.base = (uint8_t)ra_alloc1(as, asm_fuseabase(as, ir->op1), allow);
139 irx = IR(ir->op2);
140 if (irref_isk(ir->op2)) {
141 as->mrm.ofs += 8*irx->i;
142 as->mrm.idx = RID_NONE;
143 } else {
144 rset_clear(allow, as->mrm.base);
145 as->mrm.scale = XM_SCALE8;
146 /* Fuse a constant ADD (e.g. t[i+1]) into the offset.
147 ** Doesn't help much without ABCelim, but reduces register pressure.
148 */
149 if (!LJ_64 && /* Has bad effects with negative index on x64. */
150 mayfuse(as, ir->op2) && ra_noreg(irx->r) &&
151 irx->o == IR_ADD && irref_isk(irx->op2)) {
152 as->mrm.ofs += 8*IR(irx->op2)->i;
153 as->mrm.idx = (uint8_t)ra_alloc1(as, irx->op1, allow);
154 } else {
155 as->mrm.idx = (uint8_t)ra_alloc1(as, ir->op2, allow);
156 }
157 }
158}
159
160/* Fuse array/hash/upvalue reference into memory operand.
161** Caveat: this may allocate GPRs for the base/idx registers. Be sure to
162** pass the final allow mask, excluding any GPRs used for other inputs.
163** In particular: 2-operand GPR instructions need to call ra_dest() first!
164*/
165static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow)
166{
167 IRIns *ir = IR(ref);
168 if (ra_noreg(ir->r)) {
169 switch ((IROp)ir->o) {
170 case IR_AREF:
171 if (mayfuse(as, ref)) {
172 asm_fusearef(as, ir, allow);
173 return;
174 }
175 break;
176 case IR_HREFK:
177 if (mayfuse(as, ref)) {
178 as->mrm.base = (uint8_t)ra_alloc1(as, ir->op1, allow);
179 as->mrm.ofs = (int32_t)(IR(ir->op2)->op2 * sizeof(Node));
180 as->mrm.idx = RID_NONE;
181 return;
182 }
183 break;
184 case IR_UREFC:
185 if (irref_isk(ir->op1)) {
186 GCfunc *fn = ir_kfunc(IR(ir->op1));
187 GCupval *uv = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv;
188 as->mrm.ofs = ptr2addr(&uv->tv);
189 as->mrm.base = as->mrm.idx = RID_NONE;
190 return;
191 }
192 break;
193 default:
194 lua_assert(ir->o == IR_HREF || ir->o == IR_NEWREF || ir->o == IR_UREFO ||
195 ir->o == IR_KKPTR);
196 break;
197 }
198 }
199 as->mrm.base = (uint8_t)ra_alloc1(as, ref, allow);
200 as->mrm.ofs = 0;
201 as->mrm.idx = RID_NONE;
202}
203
204/* Fuse FLOAD/FREF reference into memory operand. */
205static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow)
206{
207 lua_assert(ir->o == IR_FLOAD || ir->o == IR_FREF);
208 as->mrm.ofs = field_ofs[ir->op2];
209 as->mrm.idx = RID_NONE;
210 if (irref_isk(ir->op1)) {
211 as->mrm.ofs += IR(ir->op1)->i;
212 as->mrm.base = RID_NONE;
213 } else {
214 as->mrm.base = (uint8_t)ra_alloc1(as, ir->op1, allow);
215 }
216}
217
218/* Fuse string reference into memory operand. */
219static void asm_fusestrref(ASMState *as, IRIns *ir, RegSet allow)
220{
221 IRIns *irr;
222 lua_assert(ir->o == IR_STRREF);
223 as->mrm.base = as->mrm.idx = RID_NONE;
224 as->mrm.scale = XM_SCALE1;
225 as->mrm.ofs = sizeof(GCstr);
226 if (irref_isk(ir->op1)) {
227 as->mrm.ofs += IR(ir->op1)->i;
228 } else {
229 Reg r = ra_alloc1(as, ir->op1, allow);
230 rset_clear(allow, r);
231 as->mrm.base = (uint8_t)r;
232 }
233 irr = IR(ir->op2);
234 if (irref_isk(ir->op2)) {
235 as->mrm.ofs += irr->i;
236 } else {
237 Reg r;
238 /* Fuse a constant add into the offset, e.g. string.sub(s, i+10). */
239 if (!LJ_64 && /* Has bad effects with negative index on x64. */
240 mayfuse(as, ir->op2) && irr->o == IR_ADD && irref_isk(irr->op2)) {
241 as->mrm.ofs += IR(irr->op2)->i;
242 r = ra_alloc1(as, irr->op1, allow);
243 } else {
244 r = ra_alloc1(as, ir->op2, allow);
245 }
246 if (as->mrm.base == RID_NONE)
247 as->mrm.base = (uint8_t)r;
248 else
249 as->mrm.idx = (uint8_t)r;
250 }
251}
252
253static void asm_fusexref(ASMState *as, IRRef ref, RegSet allow)
254{
255 IRIns *ir = IR(ref);
256 as->mrm.idx = RID_NONE;
257 if (ir->o == IR_KPTR || ir->o == IR_KKPTR) {
258 as->mrm.ofs = ir->i;
259 as->mrm.base = RID_NONE;
260 } else if (ir->o == IR_STRREF) {
261 asm_fusestrref(as, ir, allow);
262 } else {
263 as->mrm.ofs = 0;
264 if (canfuse(as, ir) && ir->o == IR_ADD && ra_noreg(ir->r)) {
265 /* Gather (base+idx*sz)+ofs as emitted by cdata ptr/array indexing. */
266 IRIns *irx;
267 IRRef idx;
268 Reg r;
269 if (asm_isk32(as, ir->op2, &as->mrm.ofs)) { /* Recognize x+ofs. */
270 ref = ir->op1;
271 ir = IR(ref);
272 if (!(ir->o == IR_ADD && canfuse(as, ir) && ra_noreg(ir->r)))
273 goto noadd;
274 }
275 as->mrm.scale = XM_SCALE1;
276 idx = ir->op1;
277 ref = ir->op2;
278 irx = IR(idx);
279 if (!(irx->o == IR_BSHL || irx->o == IR_ADD)) { /* Try other operand. */
280 idx = ir->op2;
281 ref = ir->op1;
282 irx = IR(idx);
283 }
284 if (canfuse(as, irx) && ra_noreg(irx->r)) {
285 if (irx->o == IR_BSHL && irref_isk(irx->op2) && IR(irx->op2)->i <= 3) {
286 /* Recognize idx<<b with b = 0-3, corresponding to sz = (1),2,4,8. */
287 idx = irx->op1;
288 as->mrm.scale = (uint8_t)(IR(irx->op2)->i << 6);
289 } else if (irx->o == IR_ADD && irx->op1 == irx->op2) {
290 /* FOLD does idx*2 ==> idx<<1 ==> idx+idx. */
291 idx = irx->op1;
292 as->mrm.scale = XM_SCALE2;
293 }
294 }
295 r = ra_alloc1(as, idx, allow);
296 rset_clear(allow, r);
297 as->mrm.idx = (uint8_t)r;
298 }
299 noadd:
300 as->mrm.base = (uint8_t)ra_alloc1(as, ref, allow);
301 }
302}
303
304/* Fuse load into memory operand. */
305static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
306{
307 IRIns *ir = IR(ref);
308 if (ra_hasreg(ir->r)) {
309 if (allow != RSET_EMPTY) { /* Fast path. */
310 ra_noweak(as, ir->r);
311 return ir->r;
312 }
313 fusespill:
314 /* Force a spill if only memory operands are allowed (asm_x87load). */
315 as->mrm.base = RID_ESP;
316 as->mrm.ofs = ra_spill(as, ir);
317 as->mrm.idx = RID_NONE;
318 return RID_MRM;
319 }
320 if (ir->o == IR_KNUM) {
321 RegSet avail = as->freeset & ~as->modset & RSET_FPR;
322 lua_assert(allow != RSET_EMPTY);
323 if (!(avail & (avail-1))) { /* Fuse if less than two regs available. */
324 as->mrm.ofs = ptr2addr(ir_knum(ir));
325 as->mrm.base = as->mrm.idx = RID_NONE;
326 return RID_MRM;
327 }
328 } else if (mayfuse(as, ref)) {
329 RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR;
330 if (ir->o == IR_SLOAD) {
331 if (!(ir->op2 & (IRSLOAD_PARENT|IRSLOAD_CONVERT)) &&
332 noconflict(as, ref, IR_RETF, 0)) {
333 as->mrm.base = (uint8_t)ra_alloc1(as, REF_BASE, xallow);
334 as->mrm.ofs = 8*((int32_t)ir->op1-1) + ((ir->op2&IRSLOAD_FRAME)?4:0);
335 as->mrm.idx = RID_NONE;
336 return RID_MRM;
337 }
338 } else if (ir->o == IR_FLOAD) {
339 /* Generic fusion is only ok for 32 bit operand (but see asm_comp). */
340 if ((irt_isint(ir->t) || irt_isaddr(ir->t)) &&
341 noconflict(as, ref, IR_FSTORE, 0)) {
342 asm_fusefref(as, ir, xallow);
343 return RID_MRM;
344 }
345 } else if (ir->o == IR_ALOAD || ir->o == IR_HLOAD || ir->o == IR_ULOAD) {
346 if (noconflict(as, ref, ir->o + IRDELTA_L2S, 0)) {
347 asm_fuseahuref(as, ir->op1, xallow);
348 return RID_MRM;
349 }
350 } else if (ir->o == IR_XLOAD) {
351 /* Generic fusion is not ok for 8/16 bit operands (but see asm_comp).
352 ** Fusing unaligned memory operands is ok on x86 (except for SIMD types).
353 */
354 if ((!irt_typerange(ir->t, IRT_I8, IRT_U16)) &&
355 noconflict(as, ref, IR_XSTORE, 0)) {
356 asm_fusexref(as, ir->op1, xallow);
357 return RID_MRM;
358 }
359 } else if (ir->o == IR_VLOAD) {
360 asm_fuseahuref(as, ir->op1, xallow);
361 return RID_MRM;
362 }
363 }
364 if (!(as->freeset & allow) &&
365 (allow == RSET_EMPTY || ra_hasspill(ir->s) || iscrossref(as, ref)))
366 goto fusespill;
367 return ra_allocref(as, ref, allow);
368}
369
370/* -- Calls --------------------------------------------------------------- */
371
372/* Count the required number of stack slots for a call. */
373static int asm_count_call_slots(ASMState *as, const CCallInfo *ci, IRRef *args)
374{
375 uint32_t i, nargs = CCI_NARGS(ci);
376 int nslots = 0;
377#if LJ_64
378 if (LJ_ABI_WIN) {
379 nslots = (int)(nargs*2); /* Only matters for more than four args. */
380 } else {
381 int ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR;
382 for (i = 0; i < nargs; i++)
383 if (args[i] && irt_isfp(IR(args[i])->t)) {
384 if (nfpr > 0) nfpr--; else nslots += 2;
385 } else {
386 if (ngpr > 0) ngpr--; else nslots += 2;
387 }
388 }
389#else
390 int ngpr = 0;
391 if ((ci->flags & CCI_CC_MASK) == CCI_CC_FASTCALL)
392 ngpr = 2;
393 else if ((ci->flags & CCI_CC_MASK) == CCI_CC_THISCALL)
394 ngpr = 1;
395 for (i = 0; i < nargs; i++)
396 if (args[i] && irt_isfp(IR(args[i])->t)) {
397 nslots += irt_isnum(IR(args[i])->t) ? 2 : 1;
398 } else {
399 if (ngpr > 0) ngpr--; else nslots++;
400 }
401#endif
402 return nslots;
403}
404
405/* Generate a call to a C function. */
406static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
407{
408 uint32_t n, nargs = CCI_NARGS(ci);
409 int32_t ofs = STACKARG_OFS;
410#if LJ_64
411 uint32_t gprs = REGARG_GPRS;
412 Reg fpr = REGARG_FIRSTFPR;
413#if !LJ_ABI_WIN
414 MCode *patchnfpr = NULL;
415#endif
416#else
417 uint32_t gprs = 0;
418 if ((ci->flags & CCI_CC_MASK) != CCI_CC_CDECL) {
419 if ((ci->flags & CCI_CC_MASK) == CCI_CC_THISCALL)
420 gprs = (REGARG_GPRS & 31);
421 else if ((ci->flags & CCI_CC_MASK) == CCI_CC_FASTCALL)
422 gprs = REGARG_GPRS;
423 }
424#endif
425 if ((void *)ci->func)
426 emit_call(as, ci->func);
427#if LJ_64
428 if ((ci->flags & CCI_VARARG)) { /* Special handling for vararg calls. */
429#if LJ_ABI_WIN
430 for (n = 0; n < 4 && n < nargs; n++) {
431 IRIns *ir = IR(args[n]);
432 if (irt_isfp(ir->t)) /* Duplicate FPRs in GPRs. */
433 emit_rr(as, XO_MOVDto, (irt_isnum(ir->t) ? REX_64 : 0) | (fpr+n),
434 ((gprs >> (n*5)) & 31)); /* Either MOVD or MOVQ. */
435 }
436#else
437 patchnfpr = --as->mcp; /* Indicate number of used FPRs in register al. */
438 *--as->mcp = XI_MOVrib | RID_EAX;
439#endif
440 }
441#endif
442 for (n = 0; n < nargs; n++) { /* Setup args. */
443 IRRef ref = args[n];
444 IRIns *ir = IR(ref);
445 Reg r;
446#if LJ_64 && LJ_ABI_WIN
447 /* Windows/x64 argument registers are strictly positional. */
448 r = irt_isfp(ir->t) ? (fpr <= REGARG_LASTFPR ? fpr : 0) : (gprs & 31);
449 fpr++; gprs >>= 5;
450#elif LJ_64
451 /* POSIX/x64 argument registers are used in order of appearance. */
452 if (irt_isfp(ir->t)) {
453 r = fpr <= REGARG_LASTFPR ? fpr++ : 0;
454 } else {
455 r = gprs & 31; gprs >>= 5;
456 }
457#else
458 if (ref && irt_isfp(ir->t)) {
459 r = 0;
460 } else {
461 r = gprs & 31; gprs >>= 5;
462 if (!ref) continue;
463 }
464#endif
465 if (r) { /* Argument is in a register. */
466 if (r < RID_MAX_GPR && ref < ASMREF_TMP1) {
467#if LJ_64
468 if (ir->o == IR_KINT64)
469 emit_loadu64(as, r, ir_kint64(ir)->u64);
470 else
471#endif
472 emit_loadi(as, r, ir->i);
473 } else {
474 lua_assert(rset_test(as->freeset, r)); /* Must have been evicted. */
475 if (ra_hasreg(ir->r)) {
476 ra_noweak(as, ir->r);
477 emit_movrr(as, ir, r, ir->r);
478 } else {
479 ra_allocref(as, ref, RID2RSET(r));
480 }
481 }
482 } else if (irt_isfp(ir->t)) { /* FP argument is on stack. */
483 lua_assert(!(irt_isfloat(ir->t) && irref_isk(ref))); /* No float k. */
484 if (LJ_32 && (ofs & 4) && irref_isk(ref)) {
485 /* Split stores for unaligned FP consts. */
486 emit_movmroi(as, RID_ESP, ofs, (int32_t)ir_knum(ir)->u32.lo);
487 emit_movmroi(as, RID_ESP, ofs+4, (int32_t)ir_knum(ir)->u32.hi);
488 } else {
489 r = ra_alloc1(as, ref, RSET_FPR);
490 emit_rmro(as, irt_isnum(ir->t) ? XO_MOVSDto : XO_MOVSSto,
491 r, RID_ESP, ofs);
492 }
493 ofs += (LJ_32 && irt_isfloat(ir->t)) ? 4 : 8;
494 } else { /* Non-FP argument is on stack. */
495 if (LJ_32 && ref < ASMREF_TMP1) {
496 emit_movmroi(as, RID_ESP, ofs, ir->i);
497 } else {
498 r = ra_alloc1(as, ref, RSET_GPR);
499 emit_movtomro(as, REX_64 + r, RID_ESP, ofs);
500 }
501 ofs += sizeof(intptr_t);
502 }
503 }
504#if LJ_64 && !LJ_ABI_WIN
505 if (patchnfpr) *patchnfpr = fpr - REGARG_FIRSTFPR;
506#endif
507}
508
509/* Setup result reg/sp for call. Evict scratch regs. */
510static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
511{
512 RegSet drop = RSET_SCRATCH;
513 if ((ci->flags & CCI_NOFPRCLOBBER))
514 drop &= ~RSET_FPR;
515 if (ra_hasreg(ir->r))
516 rset_clear(drop, ir->r); /* Dest reg handled below. */
517 ra_evictset(as, drop); /* Evictions must be performed first. */
518 if (ra_used(ir)) {
519 if (irt_isfp(ir->t)) {
520 int32_t ofs = sps_scale(ir->s); /* Use spill slot or temp slots. */
521#if LJ_64
522 if ((ci->flags & CCI_CASTU64)) {
523 Reg dest = ir->r;
524 if (ra_hasreg(dest)) {
525 ra_free(as, dest);
526 ra_modified(as, dest);
527 emit_rr(as, XO_MOVD, dest|REX_64, RID_RET); /* Really MOVQ. */
528 }
529 if (ofs) emit_movtomro(as, RID_RET|REX_64, RID_ESP, ofs);
530 } else {
531 ra_destreg(as, ir, RID_FPRET);
532 }
533#else
534 /* Number result is in x87 st0 for x86 calling convention. */
535 Reg dest = ir->r;
536 if (ra_hasreg(dest)) {
537 ra_free(as, dest);
538 ra_modified(as, dest);
539 emit_rmro(as, irt_isnum(ir->t) ? XMM_MOVRM(as) : XO_MOVSS,
540 dest, RID_ESP, ofs);
541 }
542 if ((ci->flags & CCI_CASTU64)) {
543 emit_movtomro(as, RID_RETLO, RID_ESP, ofs);
544 emit_movtomro(as, RID_RETHI, RID_ESP, ofs+4);
545 } else {
546 emit_rmro(as, irt_isnum(ir->t) ? XO_FSTPq : XO_FSTPd,
547 irt_isnum(ir->t) ? XOg_FSTPq : XOg_FSTPd, RID_ESP, ofs);
548 }
549#endif
550 } else {
551 lua_assert(!irt_ispri(ir->t));
552 ra_destreg(as, ir, RID_RET);
553 }
554 } else if (LJ_32 && irt_isfp(ir->t)) {
555 emit_x87op(as, XI_FPOP); /* Pop unused result from x87 st0. */
556 }
557}
558
559static void asm_call(ASMState *as, IRIns *ir)
560{
561 IRRef args[CCI_NARGS_MAX];
562 const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
563 asm_collectargs(as, ir, ci, args);
564 asm_setupresult(as, ir, ci);
565 asm_gencall(as, ci, args);
566}
567
568/* Return a constant function pointer or NULL for indirect calls. */
569static void *asm_callx_func(ASMState *as, IRIns *irf, IRRef func)
570{
571#if LJ_32
572 UNUSED(as);
573 if (irref_isk(func))
574 return (void *)irf->i;
575#else
576 if (irref_isk(func)) {
577 MCode *p;
578 if (irf->o == IR_KINT64)
579 p = (MCode *)(void *)ir_k64(irf)->u64;
580 else
581 p = (MCode *)(void *)(uintptr_t)(uint32_t)irf->i;
582 if (p - as->mcp == (int32_t)(p - as->mcp))
583 return p; /* Call target is still in +-2GB range. */
584 /* Avoid the indirect case of emit_call(). Try to hoist func addr. */
585 }
586#endif
587 return NULL;
588}
589
590static void asm_callx(ASMState *as, IRIns *ir)
591{
592 IRRef args[CCI_NARGS_MAX];
593 CCallInfo ci;
594 IRRef func;
595 IRIns *irf;
596 int32_t spadj = 0;
597 ci.flags = asm_callx_flags(as, ir);
598 asm_collectargs(as, ir, &ci, args);
599 asm_setupresult(as, ir, &ci);
600#if LJ_32
601 /* Have to readjust stack after non-cdecl calls due to callee cleanup. */
602 if ((ci.flags & CCI_CC_MASK) != CCI_CC_CDECL)
603 spadj = 4 * asm_count_call_slots(as, &ci, args);
604#endif
605 func = ir->op2; irf = IR(func);
606 if (irf->o == IR_CARG) { func = irf->op1; irf = IR(func); }
607 ci.func = (ASMFunction)asm_callx_func(as, irf, func);
608 if (!(void *)ci.func) {
609 /* Use a (hoistable) non-scratch register for indirect calls. */
610 RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
611 Reg r = ra_alloc1(as, func, allow);
612 if (LJ_32) emit_spsub(as, spadj); /* Above code may cause restores! */
613 emit_rr(as, XO_GROUP5, XOg_CALL, r);
614 } else if (LJ_32) {
615 emit_spsub(as, spadj);
616 }
617 asm_gencall(as, &ci, args);
618}
619
620/* -- Returns ------------------------------------------------------------- */
621
622/* Return to lower frame. Guard that it goes to the right spot. */
623static void asm_retf(ASMState *as, IRIns *ir)
624{
625 Reg base = ra_alloc1(as, REF_BASE, RSET_GPR);
626 void *pc = ir_kptr(IR(ir->op2));
627 int32_t delta = 1+bc_a(*((const BCIns *)pc - 1));
628 as->topslot -= (BCReg)delta;
629 if ((int32_t)as->topslot < 0) as->topslot = 0;
630 emit_setgl(as, base, jit_base);
631 emit_addptr(as, base, -8*delta);
632 asm_guardcc(as, CC_NE);
633 emit_gmroi(as, XG_ARITHi(XOg_CMP), base, -4, ptr2addr(pc));
634}
635
636/* -- Type conversions ---------------------------------------------------- */
637
638static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
639{
640 Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, left));
641 Reg dest = ra_dest(as, ir, RSET_GPR);
642 asm_guardcc(as, CC_P);
643 asm_guardcc(as, CC_NE);
644 emit_rr(as, XO_UCOMISD, left, tmp);
645 emit_rr(as, XO_CVTSI2SD, tmp, dest);
646 if (!(as->flags & JIT_F_SPLIT_XMM))
647 emit_rr(as, XO_XORPS, tmp, tmp); /* Avoid partial register stall. */
648 emit_rr(as, XO_CVTTSD2SI, dest, left);
649 /* Can't fuse since left is needed twice. */
650}
651
652static void asm_tobit(ASMState *as, IRIns *ir)
653{
654 Reg dest = ra_dest(as, ir, RSET_GPR);
655 Reg tmp = ra_noreg(IR(ir->op1)->r) ?
656 ra_alloc1(as, ir->op1, RSET_FPR) :
657 ra_scratch(as, RSET_FPR);
658 Reg right = asm_fuseload(as, ir->op2, rset_exclude(RSET_FPR, tmp));
659 emit_rr(as, XO_MOVDto, tmp, dest);
660 emit_mrm(as, XO_ADDSD, tmp, right);
661 ra_left(as, tmp, ir->op1);
662}
663
664static void asm_conv(ASMState *as, IRIns *ir)
665{
666 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
667 int st64 = (st == IRT_I64 || st == IRT_U64 || (LJ_64 && st == IRT_P64));
668 int stfp = (st == IRT_NUM || st == IRT_FLOAT);
669 IRRef lref = ir->op1;
670 lua_assert(irt_type(ir->t) != st);
671 lua_assert(!(LJ_32 && (irt_isint64(ir->t) || st64))); /* Handled by SPLIT. */
672 if (irt_isfp(ir->t)) {
673 Reg dest = ra_dest(as, ir, RSET_FPR);
674 if (stfp) { /* FP to FP conversion. */
675 Reg left = asm_fuseload(as, lref, RSET_FPR);
676 emit_mrm(as, st == IRT_NUM ? XO_CVTSD2SS : XO_CVTSS2SD, dest, left);
677 if (left == dest) return; /* Avoid the XO_XORPS. */
678 } else if (LJ_32 && st == IRT_U32) { /* U32 to FP conversion on x86. */
679 /* number = (2^52+2^51 .. u32) - (2^52+2^51) */
680 cTValue *k = lj_ir_k64_find(as->J, U64x(43380000,00000000));
681 Reg bias = ra_scratch(as, rset_exclude(RSET_FPR, dest));
682 if (irt_isfloat(ir->t))
683 emit_rr(as, XO_CVTSD2SS, dest, dest);
684 emit_rr(as, XO_SUBSD, dest, bias); /* Subtract 2^52+2^51 bias. */
685 emit_rr(as, XO_XORPS, dest, bias); /* Merge bias and integer. */
686 emit_loadn(as, bias, k);
687 emit_mrm(as, XO_MOVD, dest, asm_fuseload(as, lref, RSET_GPR));
688 return;
689 } else { /* Integer to FP conversion. */
690 Reg left = (LJ_64 && (st == IRT_U32 || st == IRT_U64)) ?
691 ra_alloc1(as, lref, RSET_GPR) :
692 asm_fuseload(as, lref, RSET_GPR);
693 if (LJ_64 && st == IRT_U64) {
694 MCLabel l_end = emit_label(as);
695 const void *k = lj_ir_k64_find(as->J, U64x(43f00000,00000000));
696 emit_rma(as, XO_ADDSD, dest, k); /* Add 2^64 to compensate. */
697 emit_sjcc(as, CC_NS, l_end);
698 emit_rr(as, XO_TEST, left|REX_64, left); /* Check if u64 >= 2^63. */
699 }
700 emit_mrm(as, irt_isnum(ir->t) ? XO_CVTSI2SD : XO_CVTSI2SS,
701 dest|((LJ_64 && (st64 || st == IRT_U32)) ? REX_64 : 0), left);
702 }
703 if (!(as->flags & JIT_F_SPLIT_XMM))
704 emit_rr(as, XO_XORPS, dest, dest); /* Avoid partial register stall. */
705 } else if (stfp) { /* FP to integer conversion. */
706 if (irt_isguard(ir->t)) {
707 /* Checked conversions are only supported from number to int. */
708 lua_assert(irt_isint(ir->t) && st == IRT_NUM);
709 asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
710 } else {
711 Reg dest = ra_dest(as, ir, RSET_GPR);
712 x86Op op = st == IRT_NUM ?
713 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSD2SI : XO_CVTSD2SI) :
714 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSS2SI : XO_CVTSS2SI);
715 if (LJ_64 ? irt_isu64(ir->t) : irt_isu32(ir->t)) {
716 /* LJ_64: For inputs >= 2^63 add -2^64, convert again. */
717 /* LJ_32: For inputs >= 2^31 add -2^31, convert again and add 2^31. */
718 Reg tmp = ra_noreg(IR(lref)->r) ? ra_alloc1(as, lref, RSET_FPR) :
719 ra_scratch(as, RSET_FPR);
720 MCLabel l_end = emit_label(as);
721 if (LJ_32)
722 emit_gri(as, XG_ARITHi(XOg_ADD), dest, (int32_t)0x80000000);
723 emit_rr(as, op, dest|REX_64, tmp);
724 if (st == IRT_NUM)
725 emit_rma(as, XO_ADDSD, tmp, lj_ir_k64_find(as->J,
726 LJ_64 ? U64x(c3f00000,00000000) : U64x(c1e00000,00000000)));
727 else
728 emit_rma(as, XO_ADDSS, tmp, lj_ir_k64_find(as->J,
729 LJ_64 ? U64x(00000000,df800000) : U64x(00000000,cf000000)));
730 emit_sjcc(as, CC_NS, l_end);
731 emit_rr(as, XO_TEST, dest|REX_64, dest); /* Check if dest negative. */
732 emit_rr(as, op, dest|REX_64, tmp);
733 ra_left(as, tmp, lref);
734 } else {
735 Reg left = asm_fuseload(as, lref, RSET_FPR);
736 if (LJ_64 && irt_isu32(ir->t))
737 emit_rr(as, XO_MOV, dest, dest); /* Zero hiword. */
738 emit_mrm(as, op,
739 dest|((LJ_64 &&
740 (irt_is64(ir->t) || irt_isu32(ir->t))) ? REX_64 : 0),
741 left);
742 }
743 }
744 } else if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */
745 Reg left, dest = ra_dest(as, ir, RSET_GPR);
746 RegSet allow = RSET_GPR;
747 x86Op op;
748 lua_assert(irt_isint(ir->t) || irt_isu32(ir->t));
749 if (st == IRT_I8) {
750 op = XO_MOVSXb; allow = RSET_GPR8; dest |= FORCE_REX;
751 } else if (st == IRT_U8) {
752 op = XO_MOVZXb; allow = RSET_GPR8; dest |= FORCE_REX;
753 } else if (st == IRT_I16) {
754 op = XO_MOVSXw;
755 } else {
756 op = XO_MOVZXw;
757 }
758 left = asm_fuseload(as, lref, allow);
759 /* Add extra MOV if source is already in wrong register. */
760 if (!LJ_64 && left != RID_MRM && !rset_test(allow, left)) {
761 Reg tmp = ra_scratch(as, allow);
762 emit_rr(as, op, dest, tmp);
763 emit_rr(as, XO_MOV, tmp, left);
764 } else {
765 emit_mrm(as, op, dest, left);
766 }
767 } else { /* 32/64 bit integer conversions. */
768 if (LJ_32) { /* Only need to handle 32/32 bit no-op (cast) on x86. */
769 Reg dest = ra_dest(as, ir, RSET_GPR);
770 ra_left(as, dest, lref); /* Do nothing, but may need to move regs. */
771 } else if (irt_is64(ir->t)) {
772 Reg dest = ra_dest(as, ir, RSET_GPR);
773 if (st64 || !(ir->op2 & IRCONV_SEXT)) {
774 /* 64/64 bit no-op (cast) or 32 to 64 bit zero extension. */
775 ra_left(as, dest, lref); /* Do nothing, but may need to move regs. */
776 } else { /* 32 to 64 bit sign extension. */
777 Reg left = asm_fuseload(as, lref, RSET_GPR);
778 emit_mrm(as, XO_MOVSXd, dest|REX_64, left);
779 }
780 } else {
781 Reg dest = ra_dest(as, ir, RSET_GPR);
782 if (st64) {
783 Reg left = asm_fuseload(as, lref, RSET_GPR);
784 /* This is either a 32 bit reg/reg mov which zeroes the hiword
785 ** or a load of the loword from a 64 bit address.
786 */
787 emit_mrm(as, XO_MOV, dest, left);
788 } else { /* 32/32 bit no-op (cast). */
789 ra_left(as, dest, lref); /* Do nothing, but may need to move regs. */
790 }
791 }
792 }
793}
794
795#if LJ_32 && LJ_HASFFI
796/* No SSE conversions to/from 64 bit on x86, so resort to ugly x87 code. */
797
798/* 64 bit integer to FP conversion in 32 bit mode. */
799static void asm_conv_fp_int64(ASMState *as, IRIns *ir)
800{
801 Reg hi = ra_alloc1(as, ir->op1, RSET_GPR);
802 Reg lo = ra_alloc1(as, (ir-1)->op1, rset_exclude(RSET_GPR, hi));
803 int32_t ofs = sps_scale(ir->s); /* Use spill slot or temp slots. */
804 Reg dest = ir->r;
805 if (ra_hasreg(dest)) {
806 ra_free(as, dest);
807 ra_modified(as, dest);
808 emit_rmro(as, irt_isnum(ir->t) ? XMM_MOVRM(as) : XO_MOVSS,
809 dest, RID_ESP, ofs);
810 }
811 emit_rmro(as, irt_isnum(ir->t) ? XO_FSTPq : XO_FSTPd,
812 irt_isnum(ir->t) ? XOg_FSTPq : XOg_FSTPd, RID_ESP, ofs);
813 if (((ir-1)->op2 & IRCONV_SRCMASK) == IRT_U64) {
814 /* For inputs in [2^63,2^64-1] add 2^64 to compensate. */
815 MCLabel l_end = emit_label(as);
816 emit_rma(as, XO_FADDq, XOg_FADDq,
817 lj_ir_k64_find(as->J, U64x(43f00000,00000000)));
818 emit_sjcc(as, CC_NS, l_end);
819 emit_rr(as, XO_TEST, hi, hi); /* Check if u64 >= 2^63. */
820 } else {
821 lua_assert(((ir-1)->op2 & IRCONV_SRCMASK) == IRT_I64);
822 }
823 emit_rmro(as, XO_FILDq, XOg_FILDq, RID_ESP, 0);
824 /* NYI: Avoid narrow-to-wide store-to-load forwarding stall. */
825 emit_rmro(as, XO_MOVto, hi, RID_ESP, 4);
826 emit_rmro(as, XO_MOVto, lo, RID_ESP, 0);
827}
828
829/* FP to 64 bit integer conversion in 32 bit mode. */
830static void asm_conv_int64_fp(ASMState *as, IRIns *ir)
831{
832 IRType st = (IRType)((ir-1)->op2 & IRCONV_SRCMASK);
833 IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
834 Reg lo, hi;
835 lua_assert(st == IRT_NUM || st == IRT_FLOAT);
836 lua_assert(dt == IRT_I64 || dt == IRT_U64);
837 lua_assert(((ir-1)->op2 & IRCONV_TRUNC));
838 hi = ra_dest(as, ir, RSET_GPR);
839 lo = ra_dest(as, ir-1, rset_exclude(RSET_GPR, hi));
840 if (ra_used(ir-1)) emit_rmro(as, XO_MOV, lo, RID_ESP, 0);
841 /* NYI: Avoid wide-to-narrow store-to-load forwarding stall. */
842 if (!(as->flags & JIT_F_SSE3)) { /* Set FPU rounding mode to default. */
843 emit_rmro(as, XO_FLDCW, XOg_FLDCW, RID_ESP, 4);
844 emit_rmro(as, XO_MOVto, lo, RID_ESP, 4);
845 emit_gri(as, XG_ARITHi(XOg_AND), lo, 0xf3ff);
846 }
847 if (dt == IRT_U64) {
848 /* For inputs in [2^63,2^64-1] add -2^64 and convert again. */
849 MCLabel l_pop, l_end = emit_label(as);
850 emit_x87op(as, XI_FPOP);
851 l_pop = emit_label(as);
852 emit_sjmp(as, l_end);
853 emit_rmro(as, XO_MOV, hi, RID_ESP, 4);
854 if ((as->flags & JIT_F_SSE3))
855 emit_rmro(as, XO_FISTTPq, XOg_FISTTPq, RID_ESP, 0);
856 else
857 emit_rmro(as, XO_FISTPq, XOg_FISTPq, RID_ESP, 0);
858 emit_rma(as, XO_FADDq, XOg_FADDq,
859 lj_ir_k64_find(as->J, U64x(c3f00000,00000000)));
860 emit_sjcc(as, CC_NS, l_pop);
861 emit_rr(as, XO_TEST, hi, hi); /* Check if out-of-range (2^63). */
862 }
863 emit_rmro(as, XO_MOV, hi, RID_ESP, 4);
864 if ((as->flags & JIT_F_SSE3)) { /* Truncation is easy with SSE3. */
865 emit_rmro(as, XO_FISTTPq, XOg_FISTTPq, RID_ESP, 0);
866 } else { /* Otherwise set FPU rounding mode to truncate before the store. */
867 emit_rmro(as, XO_FISTPq, XOg_FISTPq, RID_ESP, 0);
868 emit_rmro(as, XO_FLDCW, XOg_FLDCW, RID_ESP, 0);
869 emit_rmro(as, XO_MOVtow, lo, RID_ESP, 0);
870 emit_rmro(as, XO_ARITHw(XOg_OR), lo, RID_ESP, 0);
871 emit_loadi(as, lo, 0xc00);
872 emit_rmro(as, XO_FNSTCW, XOg_FNSTCW, RID_ESP, 0);
873 }
874 if (dt == IRT_U64)
875 emit_x87op(as, XI_FDUP);
876 emit_mrm(as, st == IRT_NUM ? XO_FLDq : XO_FLDd,
877 st == IRT_NUM ? XOg_FLDq: XOg_FLDd,
878 asm_fuseload(as, ir->op1, RSET_EMPTY));
879}
880#endif
881
882static void asm_strto(ASMState *as, IRIns *ir)
883{
884 /* Force a spill slot for the destination register (if any). */
885 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_tonum];
886 IRRef args[2];
887 RegSet drop = RSET_SCRATCH;
888 if ((drop & RSET_FPR) != RSET_FPR && ra_hasreg(ir->r))
889 rset_set(drop, ir->r); /* WIN64 doesn't spill all FPRs. */
890 ra_evictset(as, drop);
891 asm_guardcc(as, CC_E);
892 emit_rr(as, XO_TEST, RID_RET, RID_RET); /* Test return status. */
893 args[0] = ir->op1; /* GCstr *str */
894 args[1] = ASMREF_TMP1; /* TValue *n */
895 asm_gencall(as, ci, args);
896 /* Store the result to the spill slot or temp slots. */
897 emit_rmro(as, XO_LEA, ra_releasetmp(as, ASMREF_TMP1)|REX_64,
898 RID_ESP, sps_scale(ir->s));
899}
900
901static void asm_tostr(ASMState *as, IRIns *ir)
902{
903 IRIns *irl = IR(ir->op1);
904 IRRef args[2];
905 args[0] = ASMREF_L;
906 as->gcsteps++;
907 if (irt_isnum(irl->t)) {
908 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum];
909 args[1] = ASMREF_TMP1; /* const lua_Number * */
910 asm_setupresult(as, ir, ci); /* GCstr * */
911 asm_gencall(as, ci, args);
912 emit_rmro(as, XO_LEA, ra_releasetmp(as, ASMREF_TMP1)|REX_64,
913 RID_ESP, ra_spill(as, irl));
914 } else {
915 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromint];
916 args[1] = ir->op1; /* int32_t k */
917 asm_setupresult(as, ir, ci); /* GCstr * */
918 asm_gencall(as, ci, args);
919 }
920}
921
922/* -- Memory references --------------------------------------------------- */
923
924static void asm_aref(ASMState *as, IRIns *ir)
925{
926 Reg dest = ra_dest(as, ir, RSET_GPR);
927 asm_fusearef(as, ir, RSET_GPR);
928 if (!(as->mrm.idx == RID_NONE && as->mrm.ofs == 0))
929 emit_mrm(as, XO_LEA, dest, RID_MRM);
930 else if (as->mrm.base != dest)
931 emit_rr(as, XO_MOV, dest, as->mrm.base);
932}
933
934/* Merge NE(HREF, niltv) check. */
935static MCode *merge_href_niltv(ASMState *as, IRIns *ir)
936{
937 /* Assumes nothing else generates NE of HREF. */
938 if ((ir[1].o == IR_NE || ir[1].o == IR_EQ) && ir[1].op1 == as->curins &&
939 ra_hasreg(ir->r)) {
940 MCode *p = as->mcp;
941 p += (LJ_64 && *p != XI_ARITHi) ? 7+6 : 6+6;
942 /* Ensure no loop branch inversion happened. */
943 if (p[-6] == 0x0f && p[-5] == XI_JCCn+(CC_NE^(ir[1].o & 1))) {
944 as->mcp = p; /* Kill cmp reg, imm32 + jz exit. */
945 return p + *(int32_t *)(p-4); /* Return exit address. */
946 }
947 }
948 return NULL;
949}
950
951/* Inlined hash lookup. Specialized for key type and for const keys.
952** The equivalent C code is:
953** Node *n = hashkey(t, key);
954** do {
955** if (lj_obj_equal(&n->key, key)) return &n->val;
956** } while ((n = nextnode(n)));
957** return niltv(L);
958*/
959static void asm_href(ASMState *as, IRIns *ir)
960{
961 MCode *nilexit = merge_href_niltv(as, ir); /* Do this before any restores. */
962 RegSet allow = RSET_GPR;
963 Reg dest = ra_dest(as, ir, allow);
964 Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
965 Reg key = RID_NONE, tmp = RID_NONE;
966 IRIns *irkey = IR(ir->op2);
967 int isk = irref_isk(ir->op2);
968 IRType1 kt = irkey->t;
969 uint32_t khash;
970 MCLabel l_end, l_loop, l_next;
971
972 if (!isk) {
973 rset_clear(allow, tab);
974 key = ra_alloc1(as, ir->op2, irt_isnum(kt) ? RSET_FPR : allow);
975 if (!irt_isstr(kt))
976 tmp = ra_scratch(as, rset_exclude(allow, key));
977 }
978
979 /* Key not found in chain: jump to exit (if merged with NE) or load niltv. */
980 l_end = emit_label(as);
981 if (nilexit && ir[1].o == IR_NE) {
982 emit_jcc(as, CC_E, nilexit); /* XI_JMP is not found by lj_asm_patchexit. */
983 nilexit = NULL;
984 } else {
985 emit_loada(as, dest, niltvg(J2G(as->J)));
986 }
987
988 /* Follow hash chain until the end. */
989 l_loop = emit_sjcc_label(as, CC_NZ);
990 emit_rr(as, XO_TEST, dest, dest);
991 emit_rmro(as, XO_MOV, dest, dest, offsetof(Node, next));
992 l_next = emit_label(as);
993
994 /* Type and value comparison. */
995 if (nilexit)
996 emit_jcc(as, CC_E, nilexit);
997 else
998 emit_sjcc(as, CC_E, l_end);
999 if (irt_isnum(kt)) {
1000 if (isk) {
1001 /* Assumes -0.0 is already canonicalized to +0.0. */
1002 emit_gmroi(as, XG_ARITHi(XOg_CMP), dest, offsetof(Node, key.u32.lo),
1003 (int32_t)ir_knum(irkey)->u32.lo);
1004 emit_sjcc(as, CC_NE, l_next);
1005 emit_gmroi(as, XG_ARITHi(XOg_CMP), dest, offsetof(Node, key.u32.hi),
1006 (int32_t)ir_knum(irkey)->u32.hi);
1007 } else {
1008 emit_sjcc(as, CC_P, l_next);
1009 emit_rmro(as, XO_UCOMISD, key, dest, offsetof(Node, key.n));
1010 emit_sjcc(as, CC_AE, l_next);
1011 /* The type check avoids NaN penalties and complaints from Valgrind. */
1012#if LJ_64
1013 emit_u32(as, LJ_TISNUM);
1014 emit_rmro(as, XO_ARITHi, XOg_CMP, dest, offsetof(Node, key.it));
1015#else
1016 emit_i8(as, LJ_TISNUM);
1017 emit_rmro(as, XO_ARITHi8, XOg_CMP, dest, offsetof(Node, key.it));
1018#endif
1019 }
1020#if LJ_64
1021 } else if (irt_islightud(kt)) {
1022 emit_rmro(as, XO_CMP, key|REX_64, dest, offsetof(Node, key.u64));
1023#endif
1024 } else {
1025 if (!irt_ispri(kt)) {
1026 lua_assert(irt_isaddr(kt));
1027 if (isk)
1028 emit_gmroi(as, XG_ARITHi(XOg_CMP), dest, offsetof(Node, key.gcr),
1029 ptr2addr(ir_kgc(irkey)));
1030 else
1031 emit_rmro(as, XO_CMP, key, dest, offsetof(Node, key.gcr));
1032 emit_sjcc(as, CC_NE, l_next);
1033 }
1034 lua_assert(!irt_isnil(kt));
1035 emit_i8(as, irt_toitype(kt));
1036 emit_rmro(as, XO_ARITHi8, XOg_CMP, dest, offsetof(Node, key.it));
1037 }
1038 emit_sfixup(as, l_loop);
1039 checkmclim(as);
1040
1041 /* Load main position relative to tab->node into dest. */
1042 khash = isk ? ir_khash(irkey) : 1;
1043 if (khash == 0) {
1044 emit_rmro(as, XO_MOV, dest, tab, offsetof(GCtab, node));
1045 } else {
1046 emit_rmro(as, XO_ARITH(XOg_ADD), dest, tab, offsetof(GCtab, node));
1047 if ((as->flags & JIT_F_PREFER_IMUL)) {
1048 emit_i8(as, sizeof(Node));
1049 emit_rr(as, XO_IMULi8, dest, dest);
1050 } else {
1051 emit_shifti(as, XOg_SHL, dest, 3);
1052 emit_rmrxo(as, XO_LEA, dest, dest, dest, XM_SCALE2, 0);
1053 }
1054 if (isk) {
1055 emit_gri(as, XG_ARITHi(XOg_AND), dest, (int32_t)khash);
1056 emit_rmro(as, XO_MOV, dest, tab, offsetof(GCtab, hmask));
1057 } else if (irt_isstr(kt)) {
1058 emit_rmro(as, XO_ARITH(XOg_AND), dest, key, offsetof(GCstr, hash));
1059 emit_rmro(as, XO_MOV, dest, tab, offsetof(GCtab, hmask));
1060 } else { /* Must match with hashrot() in lj_tab.c. */
1061 emit_rmro(as, XO_ARITH(XOg_AND), dest, tab, offsetof(GCtab, hmask));
1062 emit_rr(as, XO_ARITH(XOg_SUB), dest, tmp);
1063 emit_shifti(as, XOg_ROL, tmp, HASH_ROT3);
1064 emit_rr(as, XO_ARITH(XOg_XOR), dest, tmp);
1065 emit_shifti(as, XOg_ROL, dest, HASH_ROT2);
1066 emit_rr(as, XO_ARITH(XOg_SUB), tmp, dest);
1067 emit_shifti(as, XOg_ROL, dest, HASH_ROT1);
1068 emit_rr(as, XO_ARITH(XOg_XOR), tmp, dest);
1069 if (irt_isnum(kt)) {
1070 emit_rr(as, XO_ARITH(XOg_ADD), dest, dest);
1071#if LJ_64
1072 emit_shifti(as, XOg_SHR|REX_64, dest, 32);
1073 emit_rr(as, XO_MOV, tmp, dest);
1074 emit_rr(as, XO_MOVDto, key|REX_64, dest);
1075#else
1076 emit_rmro(as, XO_MOV, dest, RID_ESP, ra_spill(as, irkey)+4);
1077 emit_rr(as, XO_MOVDto, key, tmp);
1078#endif
1079 } else {
1080 emit_rr(as, XO_MOV, tmp, key);
1081 emit_rmro(as, XO_LEA, dest, key, HASH_BIAS);
1082 }
1083 }
1084 }
1085}
1086
1087static void asm_hrefk(ASMState *as, IRIns *ir)
1088{
1089 IRIns *kslot = IR(ir->op2);
1090 IRIns *irkey = IR(kslot->op1);
1091 int32_t ofs = (int32_t)(kslot->op2 * sizeof(Node));
1092 Reg dest = ra_used(ir) ? ra_dest(as, ir, RSET_GPR) : RID_NONE;
1093 Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
1094#if !LJ_64
1095 MCLabel l_exit;
1096#endif
1097 lua_assert(ofs % sizeof(Node) == 0);
1098 if (ra_hasreg(dest)) {
1099 if (ofs != 0) {
1100 if (dest == node && !(as->flags & JIT_F_LEA_AGU))
1101 emit_gri(as, XG_ARITHi(XOg_ADD), dest, ofs);
1102 else
1103 emit_rmro(as, XO_LEA, dest, node, ofs);
1104 } else if (dest != node) {
1105 emit_rr(as, XO_MOV, dest, node);
1106 }
1107 }
1108 asm_guardcc(as, CC_NE);
1109#if LJ_64
1110 if (!irt_ispri(irkey->t)) {
1111 Reg key = ra_scratch(as, rset_exclude(RSET_GPR, node));
1112 emit_rmro(as, XO_CMP, key|REX_64, node,
1113 ofs + (int32_t)offsetof(Node, key.u64));
1114 lua_assert(irt_isnum(irkey->t) || irt_isgcv(irkey->t));
1115 /* Assumes -0.0 is already canonicalized to +0.0. */
1116 emit_loadu64(as, key, irt_isnum(irkey->t) ? ir_knum(irkey)->u64 :
1117 ((uint64_t)irt_toitype(irkey->t) << 32) |
1118 (uint64_t)(uint32_t)ptr2addr(ir_kgc(irkey)));
1119 } else {
1120 lua_assert(!irt_isnil(irkey->t));
1121 emit_i8(as, irt_toitype(irkey->t));
1122 emit_rmro(as, XO_ARITHi8, XOg_CMP, node,
1123 ofs + (int32_t)offsetof(Node, key.it));
1124 }
1125#else
1126 l_exit = emit_label(as);
1127 if (irt_isnum(irkey->t)) {
1128 /* Assumes -0.0 is already canonicalized to +0.0. */
1129 emit_gmroi(as, XG_ARITHi(XOg_CMP), node,
1130 ofs + (int32_t)offsetof(Node, key.u32.lo),
1131 (int32_t)ir_knum(irkey)->u32.lo);
1132 emit_sjcc(as, CC_NE, l_exit);
1133 emit_gmroi(as, XG_ARITHi(XOg_CMP), node,
1134 ofs + (int32_t)offsetof(Node, key.u32.hi),
1135 (int32_t)ir_knum(irkey)->u32.hi);
1136 } else {
1137 if (!irt_ispri(irkey->t)) {
1138 lua_assert(irt_isgcv(irkey->t));
1139 emit_gmroi(as, XG_ARITHi(XOg_CMP), node,
1140 ofs + (int32_t)offsetof(Node, key.gcr),
1141 ptr2addr(ir_kgc(irkey)));
1142 emit_sjcc(as, CC_NE, l_exit);
1143 }
1144 lua_assert(!irt_isnil(irkey->t));
1145 emit_i8(as, irt_toitype(irkey->t));
1146 emit_rmro(as, XO_ARITHi8, XOg_CMP, node,
1147 ofs + (int32_t)offsetof(Node, key.it));
1148 }
1149#endif
1150}
1151
1152static void asm_newref(ASMState *as, IRIns *ir)
1153{
1154 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_newkey];
1155 IRRef args[3];
1156 IRIns *irkey;
1157 Reg tmp;
1158 args[0] = ASMREF_L; /* lua_State *L */
1159 args[1] = ir->op1; /* GCtab *t */
1160 args[2] = ASMREF_TMP1; /* cTValue *key */
1161 asm_setupresult(as, ir, ci); /* TValue * */
1162 asm_gencall(as, ci, args);
1163 tmp = ra_releasetmp(as, ASMREF_TMP1);
1164 irkey = IR(ir->op2);
1165 if (irt_isnum(irkey->t)) {
1166 /* For numbers use the constant itself or a spill slot as a TValue. */
1167 if (irref_isk(ir->op2))
1168 emit_loada(as, tmp, ir_knum(irkey));
1169 else
1170 emit_rmro(as, XO_LEA, tmp|REX_64, RID_ESP, ra_spill(as, irkey));
1171 } else {
1172 /* Otherwise use g->tmptv to hold the TValue. */
1173 if (!irref_isk(ir->op2)) {
1174 Reg src = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, tmp));
1175 emit_movtomro(as, REX_64IR(irkey, src), tmp, 0);
1176 } else if (!irt_ispri(irkey->t)) {
1177 emit_movmroi(as, tmp, 0, irkey->i);
1178 }
1179 if (!(LJ_64 && irt_islightud(irkey->t)))
1180 emit_movmroi(as, tmp, 4, irt_toitype(irkey->t));
1181 emit_loada(as, tmp, &J2G(as->J)->tmptv);
1182 }
1183}
1184
1185static void asm_uref(ASMState *as, IRIns *ir)
1186{
1187 /* NYI: Check that UREFO is still open and not aliasing a slot. */
1188 Reg dest = ra_dest(as, ir, RSET_GPR);
1189 if (irref_isk(ir->op1)) {
1190 GCfunc *fn = ir_kfunc(IR(ir->op1));
1191 MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v;
1192 emit_rma(as, XO_MOV, dest, v);
1193 } else {
1194 Reg uv = ra_scratch(as, RSET_GPR);
1195 Reg func = ra_alloc1(as, ir->op1, RSET_GPR);
1196 if (ir->o == IR_UREFC) {
1197 emit_rmro(as, XO_LEA, dest, uv, offsetof(GCupval, tv));
1198 asm_guardcc(as, CC_NE);
1199 emit_i8(as, 1);
1200 emit_rmro(as, XO_ARITHib, XOg_CMP, uv, offsetof(GCupval, closed));
1201 } else {
1202 emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v));
1203 }
1204 emit_rmro(as, XO_MOV, uv, func,
1205 (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8));
1206 }
1207}
1208
1209static void asm_fref(ASMState *as, IRIns *ir)
1210{
1211 Reg dest = ra_dest(as, ir, RSET_GPR);
1212 asm_fusefref(as, ir, RSET_GPR);
1213 emit_mrm(as, XO_LEA, dest, RID_MRM);
1214}
1215
1216static void asm_strref(ASMState *as, IRIns *ir)
1217{
1218 Reg dest = ra_dest(as, ir, RSET_GPR);
1219 asm_fusestrref(as, ir, RSET_GPR);
1220 if (as->mrm.base == RID_NONE)
1221 emit_loadi(as, dest, as->mrm.ofs);
1222 else if (as->mrm.base == dest && as->mrm.idx == RID_NONE)
1223 emit_gri(as, XG_ARITHi(XOg_ADD), dest, as->mrm.ofs);
1224 else
1225 emit_mrm(as, XO_LEA, dest, RID_MRM);
1226}
1227
1228/* -- Loads and stores ---------------------------------------------------- */
1229
1230static void asm_fxload(ASMState *as, IRIns *ir)
1231{
1232 Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
1233 x86Op xo;
1234 if (ir->o == IR_FLOAD)
1235 asm_fusefref(as, ir, RSET_GPR);
1236 else
1237 asm_fusexref(as, ir->op1, RSET_GPR);
1238 /* ir->op2 is ignored -- unaligned loads are ok on x86. */
1239 switch (irt_type(ir->t)) {
1240 case IRT_I8: xo = XO_MOVSXb; break;
1241 case IRT_U8: xo = XO_MOVZXb; break;
1242 case IRT_I16: xo = XO_MOVSXw; break;
1243 case IRT_U16: xo = XO_MOVZXw; break;
1244 case IRT_NUM: xo = XMM_MOVRM(as); break;
1245 case IRT_FLOAT: xo = XO_MOVSS; break;
1246 default:
1247 if (LJ_64 && irt_is64(ir->t))
1248 dest |= REX_64;
1249 else
1250 lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t));
1251 xo = XO_MOV;
1252 break;
1253 }
1254 emit_mrm(as, xo, dest, RID_MRM);
1255}
1256
1257static void asm_fxstore(ASMState *as, IRIns *ir)
1258{
1259 RegSet allow = RSET_GPR;
1260 Reg src = RID_NONE, osrc = RID_NONE;
1261 int32_t k = 0;
1262 /* The IRT_I16/IRT_U16 stores should never be simplified for constant
1263 ** values since mov word [mem], imm16 has a length-changing prefix.
1264 */
1265 if (irt_isi16(ir->t) || irt_isu16(ir->t) || irt_isfp(ir->t) ||
1266 !asm_isk32(as, ir->op2, &k)) {
1267 RegSet allow8 = irt_isfp(ir->t) ? RSET_FPR :
1268 (irt_isi8(ir->t) || irt_isu8(ir->t)) ? RSET_GPR8 : RSET_GPR;
1269 src = osrc = ra_alloc1(as, ir->op2, allow8);
1270 if (!LJ_64 && !rset_test(allow8, src)) { /* Already in wrong register. */
1271 rset_clear(allow, osrc);
1272 src = ra_scratch(as, allow8);
1273 }
1274 rset_clear(allow, src);
1275 }
1276 if (ir->o == IR_FSTORE)
1277 asm_fusefref(as, IR(ir->op1), allow);
1278 else
1279 asm_fusexref(as, ir->op1, allow);
1280 /* ir->op2 is ignored -- unaligned stores are ok on x86. */
1281 if (ra_hasreg(src)) {
1282 x86Op xo;
1283 switch (irt_type(ir->t)) {
1284 case IRT_I8: case IRT_U8: xo = XO_MOVtob; src |= FORCE_REX; break;
1285 case IRT_I16: case IRT_U16: xo = XO_MOVtow; break;
1286 case IRT_NUM: xo = XO_MOVSDto; break;
1287 case IRT_FLOAT: xo = XO_MOVSSto; break;
1288#if LJ_64
1289 case IRT_LIGHTUD: lua_assert(0); /* NYI: mask 64 bit lightuserdata. */
1290#endif
1291 default:
1292 if (LJ_64 && irt_is64(ir->t))
1293 src |= REX_64;
1294 else
1295 lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t));
1296 xo = XO_MOVto;
1297 break;
1298 }
1299 emit_mrm(as, xo, src, RID_MRM);
1300 if (!LJ_64 && src != osrc) {
1301 ra_noweak(as, osrc);
1302 emit_rr(as, XO_MOV, src, osrc);
1303 }
1304 } else {
1305 if (irt_isi8(ir->t) || irt_isu8(ir->t)) {
1306 emit_i8(as, k);
1307 emit_mrm(as, XO_MOVmib, 0, RID_MRM);
1308 } else {
1309 lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || irt_isu32(ir->t) ||
1310 irt_isaddr(ir->t));
1311 emit_i32(as, k);
1312 emit_mrm(as, XO_MOVmi, REX_64IR(ir, 0), RID_MRM);
1313 }
1314 }
1315}
1316
1317#if LJ_64
1318static Reg asm_load_lightud64(ASMState *as, IRIns *ir, int typecheck)
1319{
1320 if (ra_used(ir) || typecheck) {
1321 Reg dest = ra_dest(as, ir, RSET_GPR);
1322 if (typecheck) {
1323 Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, dest));
1324 asm_guardcc(as, CC_NE);
1325 emit_i8(as, -2);
1326 emit_rr(as, XO_ARITHi8, XOg_CMP, tmp);
1327 emit_shifti(as, XOg_SAR|REX_64, tmp, 47);
1328 emit_rr(as, XO_MOV, tmp|REX_64, dest);
1329 }
1330 return dest;
1331 } else {
1332 return RID_NONE;
1333 }
1334}
1335#endif
1336
1337static void asm_ahuvload(ASMState *as, IRIns *ir)
1338{
1339 lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t) ||
1340 (LJ_DUALNUM && irt_isint(ir->t)));
1341#if LJ_64
1342 if (irt_islightud(ir->t)) {
1343 Reg dest = asm_load_lightud64(as, ir, 1);
1344 if (ra_hasreg(dest)) {
1345 asm_fuseahuref(as, ir->op1, RSET_GPR);
1346 emit_mrm(as, XO_MOV, dest|REX_64, RID_MRM);
1347 }
1348 return;
1349 } else
1350#endif
1351 if (ra_used(ir)) {
1352 RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR;
1353 Reg dest = ra_dest(as, ir, allow);
1354 asm_fuseahuref(as, ir->op1, RSET_GPR);
1355 emit_mrm(as, dest < RID_MAX_GPR ? XO_MOV : XMM_MOVRM(as), dest, RID_MRM);
1356 } else {
1357 asm_fuseahuref(as, ir->op1, RSET_GPR);
1358 }
1359 /* Always do the type check, even if the load result is unused. */
1360 as->mrm.ofs += 4;
1361 asm_guardcc(as, irt_isnum(ir->t) ? CC_AE : CC_NE);
1362 if (LJ_64 && irt_type(ir->t) >= IRT_NUM) {
1363 lua_assert(irt_isinteger(ir->t) || irt_isnum(ir->t));
1364 emit_u32(as, LJ_TISNUM);
1365 emit_mrm(as, XO_ARITHi, XOg_CMP, RID_MRM);
1366 } else {
1367 emit_i8(as, irt_toitype(ir->t));
1368 emit_mrm(as, XO_ARITHi8, XOg_CMP, RID_MRM);
1369 }
1370}
1371
1372static void asm_ahustore(ASMState *as, IRIns *ir)
1373{
1374 if (irt_isnum(ir->t)) {
1375 Reg src = ra_alloc1(as, ir->op2, RSET_FPR);
1376 asm_fuseahuref(as, ir->op1, RSET_GPR);
1377 emit_mrm(as, XO_MOVSDto, src, RID_MRM);
1378#if LJ_64
1379 } else if (irt_islightud(ir->t)) {
1380 Reg src = ra_alloc1(as, ir->op2, RSET_GPR);
1381 asm_fuseahuref(as, ir->op1, rset_exclude(RSET_GPR, src));
1382 emit_mrm(as, XO_MOVto, src|REX_64, RID_MRM);
1383#endif
1384 } else {
1385 IRIns *irr = IR(ir->op2);
1386 RegSet allow = RSET_GPR;
1387 Reg src = RID_NONE;
1388 if (!irref_isk(ir->op2)) {
1389 src = ra_alloc1(as, ir->op2, allow);
1390 rset_clear(allow, src);
1391 }
1392 asm_fuseahuref(as, ir->op1, allow);
1393 if (ra_hasreg(src)) {
1394 emit_mrm(as, XO_MOVto, src, RID_MRM);
1395 } else if (!irt_ispri(irr->t)) {
1396 lua_assert(irt_isaddr(ir->t) || (LJ_DUALNUM && irt_isinteger(ir->t)));
1397 emit_i32(as, irr->i);
1398 emit_mrm(as, XO_MOVmi, 0, RID_MRM);
1399 }
1400 as->mrm.ofs += 4;
1401 emit_i32(as, (int32_t)irt_toitype(ir->t));
1402 emit_mrm(as, XO_MOVmi, 0, RID_MRM);
1403 }
1404}
1405
1406static void asm_sload(ASMState *as, IRIns *ir)
1407{
1408 int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0);
1409 IRType1 t = ir->t;
1410 Reg base;
1411 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
1412 lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK));
1413 lua_assert(LJ_DUALNUM ||
1414 !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
1415 if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
1416 Reg left = ra_scratch(as, RSET_FPR);
1417 asm_tointg(as, ir, left); /* Frees dest reg. Do this before base alloc. */
1418 base = ra_alloc1(as, REF_BASE, RSET_GPR);
1419 emit_rmro(as, XMM_MOVRM(as), left, base, ofs);
1420 t.irt = IRT_NUM; /* Continue with a regular number type check. */
1421#if LJ_64
1422 } else if (irt_islightud(t)) {
1423 Reg dest = asm_load_lightud64(as, ir, (ir->op2 & IRSLOAD_TYPECHECK));
1424 if (ra_hasreg(dest)) {
1425 base = ra_alloc1(as, REF_BASE, RSET_GPR);
1426 emit_rmro(as, XO_MOV, dest|REX_64, base, ofs);
1427 }
1428 return;
1429#endif
1430 } else if (ra_used(ir)) {
1431 RegSet allow = irt_isnum(t) ? RSET_FPR : RSET_GPR;
1432 Reg dest = ra_dest(as, ir, allow);
1433 base = ra_alloc1(as, REF_BASE, RSET_GPR);
1434 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
1435 if ((ir->op2 & IRSLOAD_CONVERT)) {
1436 t.irt = irt_isint(t) ? IRT_NUM : IRT_INT; /* Check for original type. */
1437 emit_rmro(as, irt_isint(t) ? XO_CVTSI2SD : XO_CVTSD2SI, dest, base, ofs);
1438 } else if (irt_isnum(t)) {
1439 emit_rmro(as, XMM_MOVRM(as), dest, base, ofs);
1440 } else {
1441 emit_rmro(as, XO_MOV, dest, base, ofs);
1442 }
1443 } else {
1444 if (!(ir->op2 & IRSLOAD_TYPECHECK))
1445 return; /* No type check: avoid base alloc. */
1446 base = ra_alloc1(as, REF_BASE, RSET_GPR);
1447 }
1448 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
1449 /* Need type check, even if the load result is unused. */
1450 asm_guardcc(as, irt_isnum(t) ? CC_AE : CC_NE);
1451 if (LJ_64 && irt_type(t) >= IRT_NUM) {
1452 lua_assert(irt_isinteger(t) || irt_isnum(t));
1453 emit_u32(as, LJ_TISNUM);
1454 emit_rmro(as, XO_ARITHi, XOg_CMP, base, ofs+4);
1455 } else {
1456 emit_i8(as, irt_toitype(t));
1457 emit_rmro(as, XO_ARITHi8, XOg_CMP, base, ofs+4);
1458 }
1459 }
1460}
1461
1462/* -- Allocations --------------------------------------------------------- */
1463
1464#if LJ_HASFFI
1465static void asm_cnew(ASMState *as, IRIns *ir)
1466{
1467 CTState *cts = ctype_ctsG(J2G(as->J));
1468 CTypeID typeid = (CTypeID)IR(ir->op1)->i;
1469 CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ?
1470 lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i;
1471 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
1472 IRRef args[2];
1473 lua_assert(sz != CTSIZE_INVALID);
1474
1475 args[0] = ASMREF_L; /* lua_State *L */
1476 args[1] = ASMREF_TMP1; /* MSize size */
1477 as->gcsteps++;
1478 asm_setupresult(as, ir, ci); /* GCcdata * */
1479
1480 /* Initialize immutable cdata object. */
1481 if (ir->o == IR_CNEWI) {
1482 RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
1483#if LJ_64
1484 Reg r64 = sz == 8 ? REX_64 : 0;
1485 if (irref_isk(ir->op2)) {
1486 IRIns *irk = IR(ir->op2);
1487 uint64_t k = irk->o == IR_KINT64 ? ir_k64(irk)->u64 :
1488 (uint64_t)(uint32_t)irk->i;
1489 if (sz == 4 || checki32((int64_t)k)) {
1490 emit_i32(as, (int32_t)k);
1491 emit_rmro(as, XO_MOVmi, r64, RID_RET, sizeof(GCcdata));
1492 } else {
1493 emit_movtomro(as, RID_ECX + r64, RID_RET, sizeof(GCcdata));
1494 emit_loadu64(as, RID_ECX, k);
1495 }
1496 } else {
1497 Reg r = ra_alloc1(as, ir->op2, allow);
1498 emit_movtomro(as, r + r64, RID_RET, sizeof(GCcdata));
1499 }
1500#else
1501 int32_t ofs = sizeof(GCcdata);
1502 if (sz == 8) {
1503 ofs += 4; ir++;
1504 lua_assert(ir->o == IR_HIOP);
1505 }
1506 do {
1507 if (irref_isk(ir->op2)) {
1508 emit_movmroi(as, RID_RET, ofs, IR(ir->op2)->i);
1509 } else {
1510 Reg r = ra_alloc1(as, ir->op2, allow);
1511 emit_movtomro(as, r, RID_RET, ofs);
1512 rset_clear(allow, r);
1513 }
1514 if (ofs == sizeof(GCcdata)) break;
1515 ofs -= 4; ir--;
1516 } while (1);
1517#endif
1518 lua_assert(sz == 4 || sz == 8);
1519 }
1520
1521 /* Combine initialization of marked, gct and typeid. */
1522 emit_movtomro(as, RID_ECX, RID_RET, offsetof(GCcdata, marked));
1523 emit_gri(as, XG_ARITHi(XOg_OR), RID_ECX,
1524 (int32_t)((~LJ_TCDATA<<8)+(typeid<<16)));
1525 emit_gri(as, XG_ARITHi(XOg_AND), RID_ECX, LJ_GC_WHITES);
1526 emit_opgl(as, XO_MOVZXb, RID_ECX, gc.currentwhite);
1527
1528 asm_gencall(as, ci, args);
1529 emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)(sz+sizeof(GCcdata)));
1530}
1531#else
1532#define asm_cnew(as, ir) ((void)0)
1533#endif
1534
1535/* -- Write barriers ------------------------------------------------------ */
1536
1537static void asm_tbar(ASMState *as, IRIns *ir)
1538{
1539 Reg tab = ra_alloc1(as, ir->op1, RSET_GPR);
1540 Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, tab));
1541 MCLabel l_end = emit_label(as);
1542 emit_movtomro(as, tmp, tab, offsetof(GCtab, gclist));
1543 emit_setgl(as, tab, gc.grayagain);
1544 emit_getgl(as, tmp, gc.grayagain);
1545 emit_i8(as, ~LJ_GC_BLACK);
1546 emit_rmro(as, XO_ARITHib, XOg_AND, tab, offsetof(GCtab, marked));
1547 emit_sjcc(as, CC_Z, l_end);
1548 emit_i8(as, LJ_GC_BLACK);
1549 emit_rmro(as, XO_GROUP3b, XOg_TEST, tab, offsetof(GCtab, marked));
1550}
1551
1552static void asm_obar(ASMState *as, IRIns *ir)
1553{
1554 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_gc_barrieruv];
1555 IRRef args[2];
1556 MCLabel l_end;
1557 Reg obj;
1558 /* No need for other object barriers (yet). */
1559 lua_assert(IR(ir->op1)->o == IR_UREFC);
1560 ra_evictset(as, RSET_SCRATCH);
1561 l_end = emit_label(as);
1562 args[0] = ASMREF_TMP1; /* global_State *g */
1563 args[1] = ir->op1; /* TValue *tv */
1564 asm_gencall(as, ci, args);
1565 emit_loada(as, ra_releasetmp(as, ASMREF_TMP1), J2G(as->J));
1566 obj = IR(ir->op1)->r;
1567 emit_sjcc(as, CC_Z, l_end);
1568 emit_i8(as, LJ_GC_WHITES);
1569 if (irref_isk(ir->op2)) {
1570 GCobj *vp = ir_kgc(IR(ir->op2));
1571 emit_rma(as, XO_GROUP3b, XOg_TEST, &vp->gch.marked);
1572 } else {
1573 Reg val = ra_alloc1(as, ir->op2, rset_exclude(RSET_SCRATCH&RSET_GPR, obj));
1574 emit_rmro(as, XO_GROUP3b, XOg_TEST, val, (int32_t)offsetof(GChead, marked));
1575 }
1576 emit_sjcc(as, CC_Z, l_end);
1577 emit_i8(as, LJ_GC_BLACK);
1578 emit_rmro(as, XO_GROUP3b, XOg_TEST, obj,
1579 (int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv));
1580}
1581
1582/* -- FP/int arithmetic and logic operations ------------------------------ */
1583
1584/* Load reference onto x87 stack. Force a spill to memory if needed. */
1585static void asm_x87load(ASMState *as, IRRef ref)
1586{
1587 IRIns *ir = IR(ref);
1588 if (ir->o == IR_KNUM) {
1589 cTValue *tv = ir_knum(ir);
1590 if (tvispzero(tv)) /* Use fldz only for +0. */
1591 emit_x87op(as, XI_FLDZ);
1592 else if (tvispone(tv))
1593 emit_x87op(as, XI_FLD1);
1594 else
1595 emit_rma(as, XO_FLDq, XOg_FLDq, tv);
1596 } else if (ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT && !ra_used(ir) &&
1597 !irref_isk(ir->op1) && mayfuse(as, ir->op1)) {
1598 IRIns *iri = IR(ir->op1);
1599 emit_rmro(as, XO_FILDd, XOg_FILDd, RID_ESP, ra_spill(as, iri));
1600 } else {
1601 emit_mrm(as, XO_FLDq, XOg_FLDq, asm_fuseload(as, ref, RSET_EMPTY));
1602 }
1603}
1604
1605/* Try to rejoin pow from EXP2, MUL and LOG2 (if still unsplit). */
1606static int fpmjoin_pow(ASMState *as, IRIns *ir)
1607{
1608 IRIns *irp = IR(ir->op1);
1609 if (irp == ir-1 && irp->o == IR_MUL && !ra_used(irp)) {
1610 IRIns *irpp = IR(irp->op1);
1611 if (irpp == ir-2 && irpp->o == IR_FPMATH &&
1612 irpp->op2 == IRFPM_LOG2 && !ra_used(irpp)) {
1613 /* The modified regs must match with the *.dasc implementation. */
1614 RegSet drop = RSET_RANGE(RID_XMM0, RID_XMM2+1)|RID2RSET(RID_EAX);
1615 IRIns *irx;
1616 if (ra_hasreg(ir->r))
1617 rset_clear(drop, ir->r); /* Dest reg handled below. */
1618 ra_evictset(as, drop);
1619 ra_destreg(as, ir, RID_XMM0);
1620 emit_call(as, lj_vm_pow_sse);
1621 irx = IR(irpp->op1);
1622 if (ra_noreg(irx->r) && ra_gethint(irx->r) == RID_XMM1)
1623 irx->r = RID_INIT; /* Avoid allocating xmm1 for x. */
1624 ra_left(as, RID_XMM0, irpp->op1);
1625 ra_left(as, RID_XMM1, irp->op2);
1626 return 1;
1627 }
1628 }
1629 return 0;
1630}
1631
1632static void asm_fpmath(ASMState *as, IRIns *ir)
1633{
1634 IRFPMathOp fpm = ir->o == IR_FPMATH ? (IRFPMathOp)ir->op2 : IRFPM_OTHER;
1635 if (fpm == IRFPM_SQRT) {
1636 Reg dest = ra_dest(as, ir, RSET_FPR);
1637 Reg left = asm_fuseload(as, ir->op1, RSET_FPR);
1638 emit_mrm(as, XO_SQRTSD, dest, left);
1639 } else if (fpm <= IRFPM_TRUNC) {
1640 if (as->flags & JIT_F_SSE4_1) { /* SSE4.1 has a rounding instruction. */
1641 Reg dest = ra_dest(as, ir, RSET_FPR);
1642 Reg left = asm_fuseload(as, ir->op1, RSET_FPR);
1643 /* ROUNDSD has a 4-byte opcode which doesn't fit in x86Op.
1644 ** Let's pretend it's a 3-byte opcode, and compensate afterwards.
1645 ** This is atrocious, but the alternatives are much worse.
1646 */
1647 /* Round down/up/trunc == 1001/1010/1011. */
1648 emit_i8(as, 0x09 + fpm);
1649 emit_mrm(as, XO_ROUNDSD, dest, left);
1650 if (LJ_64 && as->mcp[1] != (MCode)(XO_ROUNDSD >> 16)) {
1651 as->mcp[0] = as->mcp[1]; as->mcp[1] = 0x0f; /* Swap 0F and REX. */
1652 }
1653 *--as->mcp = 0x66; /* 1st byte of ROUNDSD opcode. */
1654 } else { /* Call helper functions for SSE2 variant. */
1655 /* The modified regs must match with the *.dasc implementation. */
1656 RegSet drop = RSET_RANGE(RID_XMM0, RID_XMM3+1)|RID2RSET(RID_EAX);
1657 if (ra_hasreg(ir->r))
1658 rset_clear(drop, ir->r); /* Dest reg handled below. */
1659 ra_evictset(as, drop);
1660 ra_destreg(as, ir, RID_XMM0);
1661 emit_call(as, fpm == IRFPM_FLOOR ? lj_vm_floor_sse :
1662 fpm == IRFPM_CEIL ? lj_vm_ceil_sse : lj_vm_trunc_sse);
1663 ra_left(as, RID_XMM0, ir->op1);
1664 }
1665 } else if (fpm == IRFPM_EXP2 && fpmjoin_pow(as, ir)) {
1666 /* Rejoined to pow(). */
1667 } else { /* Handle x87 ops. */
1668 int32_t ofs = sps_scale(ir->s); /* Use spill slot or temp slots. */
1669 Reg dest = ir->r;
1670 if (ra_hasreg(dest)) {
1671 ra_free(as, dest);
1672 ra_modified(as, dest);
1673 emit_rmro(as, XMM_MOVRM(as), dest, RID_ESP, ofs);
1674 }
1675 emit_rmro(as, XO_FSTPq, XOg_FSTPq, RID_ESP, ofs);
1676 switch (fpm) { /* st0 = lj_vm_*(st0) */
1677 case IRFPM_EXP: emit_call(as, lj_vm_exp_x87); break;
1678 case IRFPM_EXP2: emit_call(as, lj_vm_exp2_x87); break;
1679 case IRFPM_SIN: emit_x87op(as, XI_FSIN); break;
1680 case IRFPM_COS: emit_x87op(as, XI_FCOS); break;
1681 case IRFPM_TAN: emit_x87op(as, XI_FPOP); emit_x87op(as, XI_FPTAN); break;
1682 case IRFPM_LOG: case IRFPM_LOG2: case IRFPM_LOG10:
1683 /* Note: the use of fyl2xp1 would be pointless here. When computing
1684 ** log(1.0+eps) the precision is already lost after 1.0 is added.
1685 ** Subtracting 1.0 won't recover it. OTOH math.log1p would make sense.
1686 */
1687 emit_x87op(as, XI_FYL2X); break;
1688 case IRFPM_OTHER:
1689 switch (ir->o) {
1690 case IR_ATAN2:
1691 emit_x87op(as, XI_FPATAN); asm_x87load(as, ir->op2); break;
1692 case IR_LDEXP:
1693 emit_x87op(as, XI_FPOP1); emit_x87op(as, XI_FSCALE); break;
1694 default: lua_assert(0); break;
1695 }
1696 break;
1697 default: lua_assert(0); break;
1698 }
1699 asm_x87load(as, ir->op1);
1700 switch (fpm) {
1701 case IRFPM_LOG: emit_x87op(as, XI_FLDLN2); break;
1702 case IRFPM_LOG2: emit_x87op(as, XI_FLD1); break;
1703 case IRFPM_LOG10: emit_x87op(as, XI_FLDLG2); break;
1704 case IRFPM_OTHER:
1705 if (ir->o == IR_LDEXP) asm_x87load(as, ir->op2);
1706 break;
1707 default: break;
1708 }
1709 }
1710}
1711
1712static void asm_fppowi(ASMState *as, IRIns *ir)
1713{
1714 /* The modified regs must match with the *.dasc implementation. */
1715 RegSet drop = RSET_RANGE(RID_XMM0, RID_XMM1+1)|RID2RSET(RID_EAX);
1716 if (ra_hasreg(ir->r))
1717 rset_clear(drop, ir->r); /* Dest reg handled below. */
1718 ra_evictset(as, drop);
1719 ra_destreg(as, ir, RID_XMM0);
1720 emit_call(as, lj_vm_powi_sse);
1721 ra_left(as, RID_XMM0, ir->op1);
1722 ra_left(as, RID_EAX, ir->op2);
1723}
1724
1725#if LJ_64 && LJ_HASFFI
1726static void asm_arith64(ASMState *as, IRIns *ir, IRCallID id)
1727{
1728 const CCallInfo *ci = &lj_ir_callinfo[id];
1729 IRRef args[2];
1730 args[0] = ir->op1;
1731 args[1] = ir->op2;
1732 asm_setupresult(as, ir, ci);
1733 asm_gencall(as, ci, args);
1734}
1735#endif
1736
1737static void asm_intmod(ASMState *as, IRIns *ir)
1738{
1739 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_vm_modi];
1740 IRRef args[2];
1741 args[0] = ir->op1;
1742 args[1] = ir->op2;
1743 asm_setupresult(as, ir, ci);
1744 asm_gencall(as, ci, args);
1745}
1746
1747static int asm_swapops(ASMState *as, IRIns *ir)
1748{
1749 IRIns *irl = IR(ir->op1);
1750 IRIns *irr = IR(ir->op2);
1751 lua_assert(ra_noreg(irr->r));
1752 if (!irm_iscomm(lj_ir_mode[ir->o]))
1753 return 0; /* Can't swap non-commutative operations. */
1754 if (irref_isk(ir->op2))
1755 return 0; /* Don't swap constants to the left. */
1756 if (ra_hasreg(irl->r))
1757 return 1; /* Swap if left already has a register. */
1758 if (ra_samehint(ir->r, irr->r))
1759 return 1; /* Swap if dest and right have matching hints. */
1760 if (as->curins > as->loopref) { /* In variant part? */
1761 if (ir->op2 < as->loopref && !irt_isphi(irr->t))
1762 return 0; /* Keep invariants on the right. */
1763 if (ir->op1 < as->loopref && !irt_isphi(irl->t))
1764 return 1; /* Swap invariants to the right. */
1765 }
1766 if (opisfusableload(irl->o))
1767 return 1; /* Swap fusable loads to the right. */
1768 return 0; /* Otherwise don't swap. */
1769}
1770
1771static void asm_fparith(ASMState *as, IRIns *ir, x86Op xo)
1772{
1773 IRRef lref = ir->op1;
1774 IRRef rref = ir->op2;
1775 RegSet allow = RSET_FPR;
1776 Reg dest;
1777 Reg right = IR(rref)->r;
1778 if (ra_hasreg(right)) {
1779 rset_clear(allow, right);
1780 ra_noweak(as, right);
1781 }
1782 dest = ra_dest(as, ir, allow);
1783 if (lref == rref) {
1784 right = dest;
1785 } else if (ra_noreg(right)) {
1786 if (asm_swapops(as, ir)) {
1787 IRRef tmp = lref; lref = rref; rref = tmp;
1788 }
1789 right = asm_fuseload(as, rref, rset_clear(allow, dest));
1790 }
1791 emit_mrm(as, xo, dest, right);
1792 ra_left(as, dest, lref);
1793}
1794
1795static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa)
1796{
1797 IRRef lref = ir->op1;
1798 IRRef rref = ir->op2;
1799 RegSet allow = RSET_GPR;
1800 Reg dest, right;
1801 int32_t k = 0;
1802 if (as->flagmcp == as->mcp) { /* Drop test r,r instruction. */
1803 as->flagmcp = NULL;
1804 as->mcp += (LJ_64 && *as->mcp != XI_TEST) ? 3 : 2;
1805 }
1806 right = IR(rref)->r;
1807 if (ra_hasreg(right)) {
1808 rset_clear(allow, right);
1809 ra_noweak(as, right);
1810 }
1811 dest = ra_dest(as, ir, allow);
1812 if (lref == rref) {
1813 right = dest;
1814 } else if (ra_noreg(right) && !asm_isk32(as, rref, &k)) {
1815 if (asm_swapops(as, ir)) {
1816 IRRef tmp = lref; lref = rref; rref = tmp;
1817 }
1818 right = asm_fuseload(as, rref, rset_clear(allow, dest));
1819 }
1820 if (irt_isguard(ir->t)) /* For IR_ADDOV etc. */
1821 asm_guardcc(as, CC_O);
1822 if (xa != XOg_X_IMUL) {
1823 if (ra_hasreg(right))
1824 emit_mrm(as, XO_ARITH(xa), REX_64IR(ir, dest), right);
1825 else
1826 emit_gri(as, XG_ARITHi(xa), REX_64IR(ir, dest), k);
1827 } else if (ra_hasreg(right)) { /* IMUL r, mrm. */
1828 emit_mrm(as, XO_IMUL, REX_64IR(ir, dest), right);
1829 } else { /* IMUL r, r, k. */
1830 /* NYI: use lea/shl/add/sub (FOLD only does 2^k) depending on CPU. */
1831 Reg left = asm_fuseload(as, lref, RSET_GPR);
1832 x86Op xo;
1833 if (checki8(k)) { emit_i8(as, k); xo = XO_IMULi8;
1834 } else { emit_i32(as, k); xo = XO_IMULi; }
1835 emit_mrm(as, xo, REX_64IR(ir, dest), left);
1836 return;
1837 }
1838 ra_left(as, dest, lref);
1839}
1840
1841/* LEA is really a 4-operand ADD with an independent destination register,
1842** up to two source registers and an immediate. One register can be scaled
1843** by 1, 2, 4 or 8. This can be used to avoid moves or to fuse several
1844** instructions.
1845**
1846** Currently only a few common cases are supported:
1847** - 3-operand ADD: y = a+b; y = a+k with a and b already allocated
1848** - Left ADD fusion: y = (a+b)+k; y = (a+k)+b
1849** - Right ADD fusion: y = a+(b+k)
1850** The ommited variants have already been reduced by FOLD.
1851**
1852** There are more fusion opportunities, like gathering shifts or joining
1853** common references. But these are probably not worth the trouble, since
1854** array indexing is not decomposed and already makes use of all fields
1855** of the ModRM operand.
1856*/
1857static int asm_lea(ASMState *as, IRIns *ir)
1858{
1859 IRIns *irl = IR(ir->op1);
1860 IRIns *irr = IR(ir->op2);
1861 RegSet allow = RSET_GPR;
1862 Reg dest;
1863 as->mrm.base = as->mrm.idx = RID_NONE;
1864 as->mrm.scale = XM_SCALE1;
1865 as->mrm.ofs = 0;
1866 if (ra_hasreg(irl->r)) {
1867 rset_clear(allow, irl->r);
1868 ra_noweak(as, irl->r);
1869 as->mrm.base = irl->r;
1870 if (irref_isk(ir->op2) || ra_hasreg(irr->r)) {
1871 /* The PHI renaming logic does a better job in some cases. */
1872 if (ra_hasreg(ir->r) &&
1873 ((irt_isphi(irl->t) && as->phireg[ir->r] == ir->op1) ||
1874 (irt_isphi(irr->t) && as->phireg[ir->r] == ir->op2)))
1875 return 0;
1876 if (irref_isk(ir->op2)) {
1877 as->mrm.ofs = irr->i;
1878 } else {
1879 rset_clear(allow, irr->r);
1880 ra_noweak(as, irr->r);
1881 as->mrm.idx = irr->r;
1882 }
1883 } else if (irr->o == IR_ADD && mayfuse(as, ir->op2) &&
1884 irref_isk(irr->op2)) {
1885 Reg idx = ra_alloc1(as, irr->op1, allow);
1886 rset_clear(allow, idx);
1887 as->mrm.idx = (uint8_t)idx;
1888 as->mrm.ofs = IR(irr->op2)->i;
1889 } else {
1890 return 0;
1891 }
1892 } else if (ir->op1 != ir->op2 && irl->o == IR_ADD && mayfuse(as, ir->op1) &&
1893 (irref_isk(ir->op2) || irref_isk(irl->op2))) {
1894 Reg idx, base = ra_alloc1(as, irl->op1, allow);
1895 rset_clear(allow, base);
1896 as->mrm.base = (uint8_t)base;
1897 if (irref_isk(ir->op2)) {
1898 as->mrm.ofs = irr->i;
1899 idx = ra_alloc1(as, irl->op2, allow);
1900 } else {
1901 as->mrm.ofs = IR(irl->op2)->i;
1902 idx = ra_alloc1(as, ir->op2, allow);
1903 }
1904 rset_clear(allow, idx);
1905 as->mrm.idx = (uint8_t)idx;
1906 } else {
1907 return 0;
1908 }
1909 dest = ra_dest(as, ir, allow);
1910 emit_mrm(as, XO_LEA, dest, RID_MRM);
1911 return 1; /* Success. */
1912}
1913
1914static void asm_add(ASMState *as, IRIns *ir)
1915{
1916 if (irt_isnum(ir->t))
1917 asm_fparith(as, ir, XO_ADDSD);
1918 else if ((as->flags & JIT_F_LEA_AGU) || as->flagmcp == as->mcp ||
1919 irt_is64(ir->t) || !asm_lea(as, ir))
1920 asm_intarith(as, ir, XOg_ADD);
1921}
1922
1923static void asm_neg_not(ASMState *as, IRIns *ir, x86Group3 xg)
1924{
1925 Reg dest = ra_dest(as, ir, RSET_GPR);
1926 emit_rr(as, XO_GROUP3, REX_64IR(ir, xg), dest);
1927 ra_left(as, dest, ir->op1);
1928}
1929
1930static void asm_min_max(ASMState *as, IRIns *ir, int cc)
1931{
1932 Reg right, dest = ra_dest(as, ir, RSET_GPR);
1933 IRRef lref = ir->op1, rref = ir->op2;
1934 if (irref_isk(rref)) { lref = rref; rref = ir->op1; }
1935 right = ra_alloc1(as, rref, rset_exclude(RSET_GPR, dest));
1936 emit_rr(as, XO_CMOV + (cc<<24), REX_64IR(ir, dest), right);
1937 emit_rr(as, XO_CMP, REX_64IR(ir, dest), right);
1938 ra_left(as, dest, lref);
1939}
1940
1941static void asm_bitswap(ASMState *as, IRIns *ir)
1942{
1943 Reg dest = ra_dest(as, ir, RSET_GPR);
1944 as->mcp = emit_op(XO_BSWAP + ((dest&7) << 24),
1945 REX_64IR(ir, 0), dest, 0, as->mcp, 1);
1946 ra_left(as, dest, ir->op1);
1947}
1948
1949static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs)
1950{
1951 IRRef rref = ir->op2;
1952 IRIns *irr = IR(rref);
1953 Reg dest;
1954 if (irref_isk(rref)) { /* Constant shifts. */
1955 int shift;
1956 dest = ra_dest(as, ir, RSET_GPR);
1957 shift = irr->i & (irt_is64(ir->t) ? 63 : 31);
1958 switch (shift) {
1959 case 0: break;
1960 case 1: emit_rr(as, XO_SHIFT1, REX_64IR(ir, xs), dest); break;
1961 default: emit_shifti(as, REX_64IR(ir, xs), dest, shift); break;
1962 }
1963 } else { /* Variable shifts implicitly use register cl (i.e. ecx). */
1964 Reg right;
1965 dest = ra_dest(as, ir, rset_exclude(RSET_GPR, RID_ECX));
1966 if (dest == RID_ECX) {
1967 dest = ra_scratch(as, rset_exclude(RSET_GPR, RID_ECX));
1968 emit_rr(as, XO_MOV, RID_ECX, dest);
1969 }
1970 right = irr->r;
1971 if (ra_noreg(right))
1972 right = ra_allocref(as, rref, RID2RSET(RID_ECX));
1973 else if (right != RID_ECX)
1974 ra_scratch(as, RID2RSET(RID_ECX));
1975 emit_rr(as, XO_SHIFTcl, REX_64IR(ir, xs), dest);
1976 if (right != RID_ECX) {
1977 ra_noweak(as, right);
1978 emit_rr(as, XO_MOV, RID_ECX, right);
1979 }
1980 }
1981 ra_left(as, dest, ir->op1);
1982 /*
1983 ** Note: avoid using the flags resulting from a shift or rotate!
1984 ** All of them cause a partial flag stall, except for r,1 shifts
1985 ** (but not rotates). And a shift count of 0 leaves the flags unmodified.
1986 */
1987}
1988
1989/* -- Comparisons --------------------------------------------------------- */
1990
1991/* Virtual flags for unordered FP comparisons. */
1992#define VCC_U 0x1000 /* Unordered. */
1993#define VCC_P 0x2000 /* Needs extra CC_P branch. */
1994#define VCC_S 0x4000 /* Swap avoids CC_P branch. */
1995#define VCC_PS (VCC_P|VCC_S)
1996
1997/* Map of comparisons to flags. ORDER IR. */
1998#define COMPFLAGS(ci, cin, cu, cf) ((ci)+((cu)<<4)+((cin)<<8)+(cf))
1999static const uint16_t asm_compmap[IR_ABC+1] = {
2000 /* signed non-eq unsigned flags */
2001 /* LT */ COMPFLAGS(CC_GE, CC_G, CC_AE, VCC_PS),
2002 /* GE */ COMPFLAGS(CC_L, CC_L, CC_B, 0),
2003 /* LE */ COMPFLAGS(CC_G, CC_G, CC_A, VCC_PS),
2004 /* GT */ COMPFLAGS(CC_LE, CC_L, CC_BE, 0),
2005 /* ULT */ COMPFLAGS(CC_AE, CC_A, CC_AE, VCC_U),
2006 /* UGE */ COMPFLAGS(CC_B, CC_B, CC_B, VCC_U|VCC_PS),
2007 /* ULE */ COMPFLAGS(CC_A, CC_A, CC_A, VCC_U),
2008 /* UGT */ COMPFLAGS(CC_BE, CC_B, CC_BE, VCC_U|VCC_PS),
2009 /* EQ */ COMPFLAGS(CC_NE, CC_NE, CC_NE, VCC_P),
2010 /* NE */ COMPFLAGS(CC_E, CC_E, CC_E, VCC_U|VCC_P),
2011 /* ABC */ COMPFLAGS(CC_BE, CC_B, CC_BE, VCC_U|VCC_PS) /* Same as UGT. */
2012};
2013
2014/* FP and integer comparisons. */
2015static void asm_comp(ASMState *as, IRIns *ir, uint32_t cc)
2016{
2017 if (irt_isnum(ir->t)) {
2018 IRRef lref = ir->op1;
2019 IRRef rref = ir->op2;
2020 Reg left, right;
2021 MCLabel l_around;
2022 /*
2023 ** An extra CC_P branch is required to preserve ordered/unordered
2024 ** semantics for FP comparisons. This can be avoided by swapping
2025 ** the operands and inverting the condition (except for EQ and UNE).
2026 ** So always try to swap if possible.
2027 **
2028 ** Another option would be to swap operands to achieve better memory
2029 ** operand fusion. But it's unlikely that this outweighs the cost
2030 ** of the extra branches.
2031 */
2032 if (cc & VCC_S) { /* Swap? */
2033 IRRef tmp = lref; lref = rref; rref = tmp;
2034 cc ^= (VCC_PS|(5<<4)); /* A <-> B, AE <-> BE, PS <-> none */
2035 }
2036 left = ra_alloc1(as, lref, RSET_FPR);
2037 right = asm_fuseload(as, rref, rset_exclude(RSET_FPR, left));
2038 l_around = emit_label(as);
2039 asm_guardcc(as, cc >> 4);
2040 if (cc & VCC_P) { /* Extra CC_P branch required? */
2041 if (!(cc & VCC_U)) {
2042 asm_guardcc(as, CC_P); /* Branch to exit for ordered comparisons. */
2043 } else if (l_around != as->invmcp) {
2044 emit_sjcc(as, CC_P, l_around); /* Branch around for unordered. */
2045 } else {
2046 /* Patched to mcloop by asm_loop_fixup. */
2047 as->loopinv = 2;
2048 if (as->realign)
2049 emit_sjcc(as, CC_P, as->mcp);
2050 else
2051 emit_jcc(as, CC_P, as->mcp);
2052 }
2053 }
2054 emit_mrm(as, XO_UCOMISD, left, right);
2055 } else {
2056 IRRef lref = ir->op1, rref = ir->op2;
2057 IROp leftop = (IROp)(IR(lref)->o);
2058 Reg r64 = REX_64IR(ir, 0);
2059 int32_t imm = 0;
2060 lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || irt_isaddr(ir->t));
2061 /* Swap constants (only for ABC) and fusable loads to the right. */
2062 if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) {
2063 if ((cc & 0xc) == 0xc) cc ^= 3; /* L <-> G, LE <-> GE */
2064 else if ((cc & 0xa) == 0x2) cc ^= 5; /* A <-> B, AE <-> BE */
2065 lref = ir->op2; rref = ir->op1;
2066 }
2067 if (asm_isk32(as, rref, &imm)) {
2068 IRIns *irl = IR(lref);
2069 /* Check wether we can use test ins. Not for unsigned, since CF=0. */
2070 int usetest = (imm == 0 && (cc & 0xa) != 0x2);
2071 if (usetest && irl->o == IR_BAND && irl+1 == ir && !ra_used(irl)) {
2072 /* Combine comp(BAND(ref, r/imm), 0) into test mrm, r/imm. */
2073 Reg right, left = RID_NONE;
2074 RegSet allow = RSET_GPR;
2075 if (!asm_isk32(as, irl->op2, &imm)) {
2076 left = ra_alloc1(as, irl->op2, allow);
2077 rset_clear(allow, left);
2078 } else { /* Try to Fuse IRT_I8/IRT_U8 loads, too. See below. */
2079 IRIns *irll = IR(irl->op1);
2080 if (opisfusableload((IROp)irll->o) &&
2081 (irt_isi8(irll->t) || irt_isu8(irll->t))) {
2082 IRType1 origt = irll->t; /* Temporarily flip types. */
2083 irll->t.irt = (irll->t.irt & ~IRT_TYPE) | IRT_INT;
2084 as->curins--; /* Skip to BAND to avoid failing in noconflict(). */
2085 right = asm_fuseload(as, irl->op1, RSET_GPR);
2086 as->curins++;
2087 irll->t = origt;
2088 if (right != RID_MRM) goto test_nofuse;
2089 /* Fusion succeeded, emit test byte mrm, imm8. */
2090 asm_guardcc(as, cc);
2091 emit_i8(as, (imm & 0xff));
2092 emit_mrm(as, XO_GROUP3b, XOg_TEST, RID_MRM);
2093 return;
2094 }
2095 }
2096 as->curins--; /* Skip to BAND to avoid failing in noconflict(). */
2097 right = asm_fuseload(as, irl->op1, allow);
2098 as->curins++; /* Undo the above. */
2099 test_nofuse:
2100 asm_guardcc(as, cc);
2101 if (ra_noreg(left)) {
2102 emit_i32(as, imm);
2103 emit_mrm(as, XO_GROUP3, r64 + XOg_TEST, right);
2104 } else {
2105 emit_mrm(as, XO_TEST, r64 + left, right);
2106 }
2107 } else {
2108 Reg left;
2109 if (opisfusableload((IROp)irl->o) &&
2110 ((irt_isu8(irl->t) && checku8(imm)) ||
2111 ((irt_isi8(irl->t) || irt_isi16(irl->t)) && checki8(imm)) ||
2112 (irt_isu16(irl->t) && checku16(imm) && checki8((int16_t)imm)))) {
2113 /* Only the IRT_INT case is fused by asm_fuseload.
2114 ** The IRT_I8/IRT_U8 loads and some IRT_I16/IRT_U16 loads
2115 ** are handled here.
2116 ** Note that cmp word [mem], imm16 should not be generated,
2117 ** since it has a length-changing prefix. Compares of a word
2118 ** against a sign-extended imm8 are ok, however.
2119 */
2120 IRType1 origt = irl->t; /* Temporarily flip types. */
2121 irl->t.irt = (irl->t.irt & ~IRT_TYPE) | IRT_INT;
2122 left = asm_fuseload(as, lref, RSET_GPR);
2123 irl->t = origt;
2124 if (left == RID_MRM) { /* Fusion succeeded? */
2125 if (irt_isu8(irl->t) || irt_isu16(irl->t))
2126 cc >>= 4; /* Need unsigned compare. */
2127 asm_guardcc(as, cc);
2128 emit_i8(as, imm);
2129 emit_mrm(as, (irt_isi8(origt) || irt_isu8(origt)) ?
2130 XO_ARITHib : XO_ARITHiw8, r64 + XOg_CMP, RID_MRM);
2131 return;
2132 } /* Otherwise handle register case as usual. */
2133 } else {
2134 left = asm_fuseload(as, lref, RSET_GPR);
2135 }
2136 asm_guardcc(as, cc);
2137 if (usetest && left != RID_MRM) {
2138 /* Use test r,r instead of cmp r,0. */
2139 emit_rr(as, XO_TEST, r64 + left, left);
2140 if (irl+1 == ir) /* Referencing previous ins? */
2141 as->flagmcp = as->mcp; /* Set flag to drop test r,r if possible. */
2142 } else {
2143 emit_gmrmi(as, XG_ARITHi(XOg_CMP), r64 + left, imm);
2144 }
2145 }
2146 } else {
2147 Reg left = ra_alloc1(as, lref, RSET_GPR);
2148 Reg right = asm_fuseload(as, rref, rset_exclude(RSET_GPR, left));
2149 asm_guardcc(as, cc);
2150 emit_mrm(as, XO_CMP, r64 + left, right);
2151 }
2152 }
2153}
2154
2155#if LJ_32 && LJ_HASFFI
2156/* 64 bit integer comparisons in 32 bit mode. */
2157static void asm_comp_int64(ASMState *as, IRIns *ir)
2158{
2159 uint32_t cc = asm_compmap[(ir-1)->o];
2160 RegSet allow = RSET_GPR;
2161 Reg lefthi = RID_NONE, leftlo = RID_NONE;
2162 Reg righthi = RID_NONE, rightlo = RID_NONE;
2163 MCLabel l_around;
2164 x86ModRM mrm;
2165
2166 as->curins--; /* Skip loword ins. Avoids failing in noconflict(), too. */
2167
2168 /* Allocate/fuse hiword operands. */
2169 if (irref_isk(ir->op2)) {
2170 lefthi = asm_fuseload(as, ir->op1, allow);
2171 } else {
2172 lefthi = ra_alloc1(as, ir->op1, allow);
2173 righthi = asm_fuseload(as, ir->op2, allow);
2174 if (righthi == RID_MRM) {
2175 if (as->mrm.base != RID_NONE) rset_clear(allow, as->mrm.base);
2176 if (as->mrm.idx != RID_NONE) rset_clear(allow, as->mrm.idx);
2177 } else {
2178 rset_clear(allow, righthi);
2179 }
2180 }
2181 mrm = as->mrm; /* Save state for hiword instruction. */
2182
2183 /* Allocate/fuse loword operands. */
2184 if (irref_isk((ir-1)->op2)) {
2185 leftlo = asm_fuseload(as, (ir-1)->op1, allow);
2186 } else {
2187 leftlo = ra_alloc1(as, (ir-1)->op1, allow);
2188 rightlo = asm_fuseload(as, (ir-1)->op2, allow);
2189 if (rightlo == RID_MRM) {
2190 if (as->mrm.base != RID_NONE) rset_clear(allow, as->mrm.base);
2191 if (as->mrm.idx != RID_NONE) rset_clear(allow, as->mrm.idx);
2192 } else {
2193 rset_clear(allow, rightlo);
2194 }
2195 }
2196
2197 /* All register allocations must be performed _before_ this point. */
2198 l_around = emit_label(as);
2199 as->invmcp = as->flagmcp = NULL; /* Cannot use these optimizations. */
2200
2201 /* Loword comparison and branch. */
2202 asm_guardcc(as, cc >> 4); /* Always use unsigned compare for loword. */
2203 if (ra_noreg(rightlo)) {
2204 int32_t imm = IR((ir-1)->op2)->i;
2205 if (imm == 0 && ((cc >> 4) & 0xa) != 0x2 && leftlo != RID_MRM)
2206 emit_rr(as, XO_TEST, leftlo, leftlo);
2207 else
2208 emit_gmrmi(as, XG_ARITHi(XOg_CMP), leftlo, imm);
2209 } else {
2210 emit_mrm(as, XO_CMP, leftlo, rightlo);
2211 }
2212
2213 /* Hiword comparison and branches. */
2214 if ((cc & 15) != CC_NE)
2215 emit_sjcc(as, CC_NE, l_around); /* Hiword unequal: skip loword compare. */
2216 if ((cc & 15) != CC_E)
2217 asm_guardcc(as, cc >> 8); /* Hiword compare without equality check. */
2218 as->mrm = mrm; /* Restore state. */
2219 if (ra_noreg(righthi)) {
2220 int32_t imm = IR(ir->op2)->i;
2221 if (imm == 0 && (cc & 0xa) != 0x2 && lefthi != RID_MRM)
2222 emit_rr(as, XO_TEST, lefthi, lefthi);
2223 else
2224 emit_gmrmi(as, XG_ARITHi(XOg_CMP), lefthi, imm);
2225 } else {
2226 emit_mrm(as, XO_CMP, lefthi, righthi);
2227 }
2228}
2229#endif
2230
2231/* -- Support for 64 bit ops in 32 bit mode ------------------------------- */
2232
2233/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
2234static void asm_hiop(ASMState *as, IRIns *ir)
2235{
2236#if LJ_32 && LJ_HASFFI
2237 /* HIOP is marked as a store because it needs its own DCE logic. */
2238 int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */
2239 if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
2240 if ((ir-1)->o == IR_CONV) { /* Conversions to/from 64 bit. */
2241 if (usehi || uselo) {
2242 if (irt_isfp(ir->t))
2243 asm_conv_fp_int64(as, ir);
2244 else
2245 asm_conv_int64_fp(as, ir);
2246 }
2247 as->curins--; /* Always skip the CONV. */
2248 return;
2249 } else if ((ir-1)->o <= IR_NE) { /* 64 bit integer comparisons. ORDER IR. */
2250 asm_comp_int64(as, ir);
2251 return;
2252 }
2253 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
2254 switch ((ir-1)->o) {
2255 case IR_ADD:
2256 as->flagmcp = NULL;
2257 as->curins--;
2258 asm_intarith(as, ir, XOg_ADC);
2259 asm_intarith(as, ir-1, XOg_ADD);
2260 break;
2261 case IR_SUB:
2262 as->flagmcp = NULL;
2263 as->curins--;
2264 asm_intarith(as, ir, XOg_SBB);
2265 asm_intarith(as, ir-1, XOg_SUB);
2266 break;
2267 case IR_NEG: {
2268 Reg dest = ra_dest(as, ir, RSET_GPR);
2269 emit_rr(as, XO_GROUP3, XOg_NEG, dest);
2270 emit_i8(as, 0);
2271 emit_rr(as, XO_ARITHi8, XOg_ADC, dest);
2272 ra_left(as, dest, ir->op1);
2273 as->curins--;
2274 asm_neg_not(as, ir-1, XOg_NEG);
2275 break;
2276 }
2277 case IR_CALLN:
2278 case IR_CALLXS:
2279 ra_destreg(as, ir, RID_RETHI);
2280 if (!uselo)
2281 ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark call as used. */
2282 break;
2283 case IR_CNEWI:
2284 /* Nothing to do here. Handled by CNEWI itself. */
2285 break;
2286 default: lua_assert(0); break;
2287 }
2288#else
2289 UNUSED(as); UNUSED(ir); lua_assert(0); /* Unused on x64 or without FFI. */
2290#endif
2291}
2292
2293/* -- Stack handling ------------------------------------------------------ */
2294
2295/* Check Lua stack size for overflow. Use exit handler as fallback. */
2296static void asm_stack_check(ASMState *as, BCReg topslot,
2297 IRIns *irp, RegSet allow, ExitNo exitno)
2298{
2299 /* Try to get an unused temp. register, otherwise spill/restore eax. */
2300 Reg pbase = irp ? irp->r : RID_BASE;
2301 Reg r = allow ? rset_pickbot(allow) : RID_EAX;
2302 emit_jcc(as, CC_B, exitstub_addr(as->J, exitno));
2303 if (allow == RSET_EMPTY) /* Restore temp. register. */
2304 emit_rmro(as, XO_MOV, r|REX_64, RID_ESP, 0);
2305 else
2306 ra_modified(as, r);
2307 emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*topslot));
2308 if (ra_hasreg(pbase) && pbase != r)
2309 emit_rr(as, XO_ARITH(XOg_SUB), r, pbase);
2310 else
2311 emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE,
2312 ptr2addr(&J2G(as->J)->jit_base));
2313 emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack));
2314 emit_getgl(as, r, jit_L);
2315 if (allow == RSET_EMPTY) /* Spill temp. register. */
2316 emit_rmro(as, XO_MOVto, r|REX_64, RID_ESP, 0);
2317}
2318
2319/* Restore Lua stack from on-trace state. */
2320static void asm_stack_restore(ASMState *as, SnapShot *snap)
2321{
2322 SnapEntry *map = &as->T->snapmap[snap->mapofs];
2323 SnapEntry *flinks = &as->T->snapmap[snap_nextofs(as->T, snap)-1];
2324 MSize n, nent = snap->nent;
2325 /* Store the value of all modified slots to the Lua stack. */
2326 for (n = 0; n < nent; n++) {
2327 SnapEntry sn = map[n];
2328 BCReg s = snap_slot(sn);
2329 int32_t ofs = 8*((int32_t)s-1);
2330 IRRef ref = snap_ref(sn);
2331 IRIns *ir = IR(ref);
2332 if ((sn & SNAP_NORESTORE))
2333 continue;
2334 if (irt_isnum(ir->t)) {
2335 Reg src = ra_alloc1(as, ref, RSET_FPR);
2336 emit_rmro(as, XO_MOVSDto, src, RID_BASE, ofs);
2337 } else {
2338 lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) ||
2339 (LJ_DUALNUM && irt_isinteger(ir->t)));
2340 if (!irref_isk(ref)) {
2341 Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE));
2342 emit_movtomro(as, REX_64IR(ir, src), RID_BASE, ofs);
2343 } else if (!irt_ispri(ir->t)) {
2344 emit_movmroi(as, RID_BASE, ofs, ir->i);
2345 }
2346 if ((sn & (SNAP_CONT|SNAP_FRAME))) {
2347 if (s != 0) /* Do not overwrite link to previous frame. */
2348 emit_movmroi(as, RID_BASE, ofs+4, (int32_t)(*flinks--));
2349 } else {
2350 if (!(LJ_64 && irt_islightud(ir->t)))
2351 emit_movmroi(as, RID_BASE, ofs+4, irt_toitype(ir->t));
2352 }
2353 }
2354 checkmclim(as);
2355 }
2356 lua_assert(map + nent == flinks);
2357}
2358
2359/* -- GC handling --------------------------------------------------------- */
2360
2361/* Check GC threshold and do one or more GC steps. */
2362static void asm_gc_check(ASMState *as)
2363{
2364 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_gc_step_jit];
2365 IRRef args[2];
2366 MCLabel l_end;
2367 Reg tmp;
2368 ra_evictset(as, RSET_SCRATCH);
2369 l_end = emit_label(as);
2370 /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
2371 asm_guardcc(as, CC_NE); /* Assumes asm_snap_prep() already done. */
2372 emit_rr(as, XO_TEST, RID_RET, RID_RET);
2373 args[0] = ASMREF_TMP1; /* global_State *g */
2374 args[1] = ASMREF_TMP2; /* MSize steps */
2375 asm_gencall(as, ci, args);
2376 tmp = ra_releasetmp(as, ASMREF_TMP1);
2377 emit_loada(as, tmp, J2G(as->J));
2378 emit_loadi(as, ra_releasetmp(as, ASMREF_TMP2), (int32_t)as->gcsteps);
2379 /* Jump around GC step if GC total < GC threshold. */
2380 emit_sjcc(as, CC_B, l_end);
2381 emit_opgl(as, XO_ARITH(XOg_CMP), tmp, gc.threshold);
2382 emit_getgl(as, tmp, gc.total);
2383 as->gcsteps = 0;
2384 checkmclim(as);
2385}
2386
2387/* -- Loop handling ------------------------------------------------------- */
2388
2389/* Fixup the loop branch. */
2390static void asm_loop_fixup(ASMState *as)
2391{
2392 MCode *p = as->mctop;
2393 MCode *target = as->mcp;
2394 if (as->realign) { /* Realigned loops use short jumps. */
2395 as->realign = NULL; /* Stop another retry. */
2396 lua_assert(((intptr_t)target & 15) == 0);
2397 if (as->loopinv) { /* Inverted loop branch? */
2398 p -= 5;
2399 p[0] = XI_JMP;
2400 lua_assert(target - p >= -128);
2401 p[-1] = (MCode)(target - p); /* Patch sjcc. */
2402 if (as->loopinv == 2)
2403 p[-3] = (MCode)(target - p + 2); /* Patch opt. short jp. */
2404 } else {
2405 lua_assert(target - p >= -128);
2406 p[-1] = (MCode)(int8_t)(target - p); /* Patch short jmp. */
2407 p[-2] = XI_JMPs;
2408 }
2409 } else {
2410 MCode *newloop;
2411 p[-5] = XI_JMP;
2412 if (as->loopinv) { /* Inverted loop branch? */
2413 /* asm_guardcc already inverted the jcc and patched the jmp. */
2414 p -= 5;
2415 newloop = target+4;
2416 *(int32_t *)(p-4) = (int32_t)(target - p); /* Patch jcc. */
2417 if (as->loopinv == 2) {
2418 *(int32_t *)(p-10) = (int32_t)(target - p + 6); /* Patch opt. jp. */
2419 newloop = target+8;
2420 }
2421 } else { /* Otherwise just patch jmp. */
2422 *(int32_t *)(p-4) = (int32_t)(target - p);
2423 newloop = target+3;
2424 }
2425 /* Realign small loops and shorten the loop branch. */
2426 if (newloop >= p - 128) {
2427 as->realign = newloop; /* Force a retry and remember alignment. */
2428 as->curins = as->stopins; /* Abort asm_trace now. */
2429 as->T->nins = as->orignins; /* Remove any added renames. */
2430 }
2431 }
2432}
2433
2434/* -- Head of trace ------------------------------------------------------- */
2435
2436/* Coalesce BASE register for a root trace. */
2437static void asm_head_root_base(ASMState *as)
2438{
2439 IRIns *ir = IR(REF_BASE);
2440 Reg r = ir->r;
2441 if (ra_hasreg(r)) {
2442 ra_free(as, r);
2443 if (rset_test(as->modset, r))
2444 ir->r = RID_INIT; /* No inheritance for modified BASE register. */
2445 if (r != RID_BASE)
2446 emit_rr(as, XO_MOV, r, RID_BASE);
2447 }
2448}
2449
2450/* Coalesce or reload BASE register for a side trace. */
2451static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
2452{
2453 IRIns *ir = IR(REF_BASE);
2454 Reg r = ir->r;
2455 if (ra_hasreg(r)) {
2456 ra_free(as, r);
2457 if (rset_test(as->modset, r))
2458 ir->r = RID_INIT; /* No inheritance for modified BASE register. */
2459 if (irp->r == r) {
2460 rset_clear(allow, r); /* Mark same BASE register as coalesced. */
2461 } else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
2462 rset_clear(allow, irp->r);
2463 emit_rr(as, XO_MOV, r, irp->r); /* Move from coalesced parent reg. */
2464 } else {
2465 emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
2466 }
2467 }
2468 return allow;
2469}
2470
2471/* -- Tail of trace ------------------------------------------------------- */
2472
2473/* Fixup the tail code. */
2474static void asm_tail_fixup(ASMState *as, TraceNo lnk)
2475{
2476 /* Note: don't use as->mcp swap + emit_*: emit_op overwrites more bytes. */
2477 MCode *p = as->mctop;
2478 MCode *target, *q;
2479 int32_t spadj = as->T->spadjust;
2480 if (spadj == 0) {
2481 p -= ((as->flags & JIT_F_LEA_AGU) ? 7 : 6) + (LJ_64 ? 1 : 0);
2482 } else {
2483 MCode *p1;
2484 /* Patch stack adjustment. */
2485 if (checki8(spadj)) {
2486 p -= 3;
2487 p1 = p-6;
2488 *p1 = (MCode)spadj;
2489 } else {
2490 p1 = p-9;
2491 *(int32_t *)p1 = spadj;
2492 }
2493 if ((as->flags & JIT_F_LEA_AGU)) {
2494#if LJ_64
2495 p1[-4] = 0x48;
2496#endif
2497 p1[-3] = (MCode)XI_LEA;
2498 p1[-2] = MODRM(checki8(spadj) ? XM_OFS8 : XM_OFS32, RID_ESP, RID_ESP);
2499 p1[-1] = MODRM(XM_SCALE1, RID_ESP, RID_ESP);
2500 } else {
2501#if LJ_64
2502 p1[-3] = 0x48;
2503#endif
2504 p1[-2] = (MCode)(checki8(spadj) ? XI_ARITHi8 : XI_ARITHi);
2505 p1[-1] = MODRM(XM_REG, XOg_ADD, RID_ESP);
2506 }
2507 }
2508 /* Patch exit branch. */
2509 target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
2510 *(int32_t *)(p-4) = jmprel(p, target);
2511 p[-5] = XI_JMP;
2512 /* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */
2513 for (q = as->mctop-1; q >= p; q--)
2514 *q = XI_NOP;
2515 as->mctop = p;
2516}
2517
2518/* Prepare tail of code. */
2519static void asm_tail_prep(ASMState *as)
2520{
2521 MCode *p = as->mctop;
2522 /* Realign and leave room for backwards loop branch or exit branch. */
2523 if (as->realign) {
2524 int i = ((int)(intptr_t)as->realign) & 15;
2525 /* Fill unused mcode tail with NOPs to make the prefetcher happy. */
2526 while (i-- > 0)
2527 *--p = XI_NOP;
2528 as->mctop = p;
2529 p -= (as->loopinv ? 5 : 2); /* Space for short/near jmp. */
2530 } else {
2531 p -= 5; /* Space for exit branch (near jmp). */
2532 }
2533 if (as->loopref) {
2534 as->invmcp = as->mcp = p;
2535 } else {
2536 /* Leave room for ESP adjustment: add esp, imm or lea esp, [esp+imm] */
2537 as->mcp = p - (((as->flags & JIT_F_LEA_AGU) ? 7 : 6) + (LJ_64 ? 1 : 0));
2538 as->invmcp = NULL;
2539 }
2540}
2541
2542/* -- Instruction dispatch ------------------------------------------------ */
2543
2544/* Assemble a single instruction. */
2545static void asm_ir(ASMState *as, IRIns *ir)
2546{
2547 switch ((IROp)ir->o) {
2548 /* Miscellaneous ops. */
2549 case IR_LOOP: asm_loop(as); break;
2550 case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
2551 case IR_USE:
2552 ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
2553 case IR_PHI: asm_phi(as, ir); break;
2554 case IR_HIOP: asm_hiop(as, ir); break;
2555
2556 /* Guarded assertions. */
2557 case IR_LT: case IR_GE: case IR_LE: case IR_GT:
2558 case IR_ULT: case IR_UGE: case IR_ULE: case IR_UGT:
2559 case IR_EQ: case IR_NE: case IR_ABC:
2560 asm_comp(as, ir, asm_compmap[ir->o]);
2561 break;
2562
2563 case IR_RETF: asm_retf(as, ir); break;
2564
2565 /* Bit ops. */
2566 case IR_BNOT: asm_neg_not(as, ir, XOg_NOT); break;
2567 case IR_BSWAP: asm_bitswap(as, ir); break;
2568
2569 case IR_BAND: asm_intarith(as, ir, XOg_AND); break;
2570 case IR_BOR: asm_intarith(as, ir, XOg_OR); break;
2571 case IR_BXOR: asm_intarith(as, ir, XOg_XOR); break;
2572
2573 case IR_BSHL: asm_bitshift(as, ir, XOg_SHL); break;
2574 case IR_BSHR: asm_bitshift(as, ir, XOg_SHR); break;
2575 case IR_BSAR: asm_bitshift(as, ir, XOg_SAR); break;
2576 case IR_BROL: asm_bitshift(as, ir, XOg_ROL); break;
2577 case IR_BROR: asm_bitshift(as, ir, XOg_ROR); break;
2578
2579 /* Arithmetic ops. */
2580 case IR_ADD: asm_add(as, ir); break;
2581 case IR_SUB:
2582 if (irt_isnum(ir->t))
2583 asm_fparith(as, ir, XO_SUBSD);
2584 else /* Note: no need for LEA trick here. i-k is encoded as i+(-k). */
2585 asm_intarith(as, ir, XOg_SUB);
2586 break;
2587 case IR_MUL:
2588 if (irt_isnum(ir->t))
2589 asm_fparith(as, ir, XO_MULSD);
2590 else
2591 asm_intarith(as, ir, XOg_X_IMUL);
2592 break;
2593 case IR_DIV:
2594#if LJ_64 && LJ_HASFFI
2595 if (!irt_isnum(ir->t))
2596 asm_arith64(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 :
2597 IRCALL_lj_carith_divu64);
2598 else
2599#endif
2600 asm_fparith(as, ir, XO_DIVSD);
2601 break;
2602 case IR_MOD:
2603#if LJ_64 && LJ_HASFFI
2604 if (!irt_isint(ir->t))
2605 asm_arith64(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 :
2606 IRCALL_lj_carith_modu64);
2607 else
2608#endif
2609 asm_intmod(as, ir);
2610 break;
2611
2612 case IR_NEG:
2613 if (irt_isnum(ir->t))
2614 asm_fparith(as, ir, XO_XORPS);
2615 else
2616 asm_neg_not(as, ir, XOg_NEG);
2617 break;
2618 case IR_ABS: asm_fparith(as, ir, XO_ANDPS); break;
2619
2620 case IR_MIN:
2621 if (irt_isnum(ir->t))
2622 asm_fparith(as, ir, XO_MINSD);
2623 else
2624 asm_min_max(as, ir, CC_G);
2625 break;
2626 case IR_MAX:
2627 if (irt_isnum(ir->t))
2628 asm_fparith(as, ir, XO_MAXSD);
2629 else
2630 asm_min_max(as, ir, CC_L);
2631 break;
2632
2633 case IR_FPMATH: case IR_ATAN2: case IR_LDEXP:
2634 asm_fpmath(as, ir);
2635 break;
2636 case IR_POW:
2637#if LJ_64 && LJ_HASFFI
2638 if (!irt_isnum(ir->t))
2639 asm_arith64(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
2640 IRCALL_lj_carith_powu64);
2641 else
2642#endif
2643 asm_fppowi(as, ir);
2644 break;
2645
2646 /* Overflow-checking arithmetic ops. Note: don't use LEA here! */
2647 case IR_ADDOV: asm_intarith(as, ir, XOg_ADD); break;
2648 case IR_SUBOV: asm_intarith(as, ir, XOg_SUB); break;
2649 case IR_MULOV: asm_intarith(as, ir, XOg_X_IMUL); break;
2650
2651 /* Memory references. */
2652 case IR_AREF: asm_aref(as, ir); break;
2653 case IR_HREF: asm_href(as, ir); break;
2654 case IR_HREFK: asm_hrefk(as, ir); break;
2655 case IR_NEWREF: asm_newref(as, ir); break;
2656 case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
2657 case IR_FREF: asm_fref(as, ir); break;
2658 case IR_STRREF: asm_strref(as, ir); break;
2659
2660 /* Loads and stores. */
2661 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
2662 asm_ahuvload(as, ir);
2663 break;
2664 case IR_FLOAD: case IR_XLOAD: asm_fxload(as, ir); break;
2665 case IR_SLOAD: asm_sload(as, ir); break;
2666
2667 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
2668 case IR_FSTORE: case IR_XSTORE: asm_fxstore(as, ir); break;
2669
2670 /* Allocations. */
2671 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
2672 case IR_TNEW: asm_tnew(as, ir); break;
2673 case IR_TDUP: asm_tdup(as, ir); break;
2674 case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
2675
2676 /* Write barriers. */
2677 case IR_TBAR: asm_tbar(as, ir); break;
2678 case IR_OBAR: asm_obar(as, ir); break;
2679
2680 /* Type conversions. */
2681 case IR_TOBIT: asm_tobit(as, ir); break;
2682 case IR_CONV: asm_conv(as, ir); break;
2683 case IR_TOSTR: asm_tostr(as, ir); break;
2684 case IR_STRTO: asm_strto(as, ir); break;
2685
2686 /* Calls. */
2687 case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break;
2688 case IR_CALLXS: asm_callx(as, ir); break;
2689 case IR_CARG: break;
2690
2691 default:
2692 setintV(&as->J->errinfo, ir->o);
2693 lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
2694 break;
2695 }
2696}
2697
2698/* -- Trace setup --------------------------------------------------------- */
2699
2700/* Ensure there are enough stack slots for call arguments. */
2701static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
2702{
2703 IRRef args[CCI_NARGS_MAX];
2704 int nslots;
2705 asm_collectargs(as, ir, ci, args);
2706 nslots = asm_count_call_slots(as, ci, args);
2707 if (nslots > as->evenspill) /* Leave room for args in stack slots. */
2708 as->evenspill = nslots;
2709#if LJ_64
2710 return irt_isfp(ir->t) ? REGSP_HINT(RID_FPRET) : REGSP_HINT(RID_RET);
2711#else
2712 return irt_isfp(ir->t) ? REGSP_INIT : REGSP_HINT(RID_RET);
2713#endif
2714}
2715
2716/* Target-specific setup. */
2717static void asm_setup_target(ASMState *as)
2718{
2719 asm_exitstub_setup(as, as->T->nsnap);
2720}
2721
2722/* -- Trace patching ------------------------------------------------------ */
2723
2724/* Patch exit jumps of existing machine code to a new target. */
2725void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2726{
2727 MCode *p = T->mcode;
2728 MCode *mcarea = lj_mcode_patch(J, p, 0);
2729 MSize len = T->szmcode;
2730 MCode *px = exitstub_addr(J, exitno) - 6;
2731 MCode *pe = p+len-6;
2732 uint32_t stateaddr = u32ptr(&J2G(J)->vmstate);
2733 if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px)
2734 *(int32_t *)(p+len-4) = jmprel(p+len, target);
2735 /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */
2736 for (; p < pe; p++)
2737 if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) {
2738 p += LJ_64 ? 11 : 10;
2739 break;
2740 }
2741 lua_assert(p < pe);
2742 for (; p < pe; p++) {
2743 if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) {
2744 *(int32_t *)(p+2) = jmprel(p+6, target);
2745 p += 5;
2746 }
2747 }
2748 lj_mcode_sync(T->mcode, T->mcode + T->szmcode);
2749 lj_mcode_patch(J, mcarea, 1);
2750}
2751
diff --git a/libraries/luajit-2.0/src/lj_bc.c b/libraries/luajit-2.0/src/lj_bc.c
new file mode 100644
index 0000000..feb8e44
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_bc.c
@@ -0,0 +1,14 @@
1/*
2** Bytecode instruction modes.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_bc_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#include "lj_bc.h"
11
12/* Bytecode offsets and bytecode instruction modes. */
13#include "lj_bcdef.h"
14
diff --git a/libraries/luajit-2.0/src/lj_bc.h b/libraries/luajit-2.0/src/lj_bc.h
new file mode 100644
index 0000000..97e4d92
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_bc.h
@@ -0,0 +1,261 @@
1/*
2** Bytecode instruction format.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_BC_H
7#define _LJ_BC_H
8
9#include "lj_def.h"
10#include "lj_arch.h"
11
12/* Bytecode instruction format, 32 bit wide, fields of 8 or 16 bit:
13**
14** +----+----+----+----+
15** | B | C | A | OP | Format ABC
16** +----+----+----+----+
17** | D | A | OP | Format AD
18** +--------------------
19** MSB LSB
20**
21** In-memory instructions are always stored in host byte order.
22*/
23
24/* Operand ranges and related constants. */
25#define BCMAX_A 0xff
26#define BCMAX_B 0xff
27#define BCMAX_C 0xff
28#define BCMAX_D 0xffff
29#define BCBIAS_J 0x8000
30#define NO_REG BCMAX_A
31#define NO_JMP (~(BCPos)0)
32
33/* Macros to get instruction fields. */
34#define bc_op(i) ((BCOp)((i)&0xff))
35#define bc_a(i) ((BCReg)(((i)>>8)&0xff))
36#define bc_b(i) ((BCReg)((i)>>24))
37#define bc_c(i) ((BCReg)(((i)>>16)&0xff))
38#define bc_d(i) ((BCReg)((i)>>16))
39#define bc_j(i) ((ptrdiff_t)bc_d(i)-BCBIAS_J)
40
41/* Macros to set instruction fields. */
42#define setbc_byte(p, x, ofs) \
43 ((uint8_t *)(p))[LJ_ENDIAN_SELECT(ofs, 3-ofs)] = (uint8_t)(x)
44#define setbc_op(p, x) setbc_byte(p, (x), 0)
45#define setbc_a(p, x) setbc_byte(p, (x), 1)
46#define setbc_b(p, x) setbc_byte(p, (x), 3)
47#define setbc_c(p, x) setbc_byte(p, (x), 2)
48#define setbc_d(p, x) \
49 ((uint16_t *)(p))[LJ_ENDIAN_SELECT(1, 0)] = (uint16_t)(x)
50#define setbc_j(p, x) setbc_d(p, (BCPos)((int32_t)(x)+BCBIAS_J))
51
52/* Macros to compose instructions. */
53#define BCINS_ABC(o, a, b, c) \
54 (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(b)<<24)|((BCIns)(c)<<16))
55#define BCINS_AD(o, a, d) \
56 (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(d)<<16))
57#define BCINS_AJ(o, a, j) BCINS_AD(o, a, (BCPos)((int32_t)(j)+BCBIAS_J))
58
59/* Bytecode instruction definition. Order matters, see below.
60**
61** (name, filler, Amode, Bmode, Cmode or Dmode, metamethod)
62**
63** The opcode name suffixes specify the type for RB/RC or RD:
64** V = variable slot
65** S = string const
66** N = number const
67** P = primitive type (~itype)
68** B = unsigned byte literal
69** M = multiple args/results
70*/
71#define BCDEF(_) \
72 /* Comparison ops. ORDER OPR. */ \
73 _(ISLT, var, ___, var, lt) \
74 _(ISGE, var, ___, var, lt) \
75 _(ISLE, var, ___, var, le) \
76 _(ISGT, var, ___, var, le) \
77 \
78 _(ISEQV, var, ___, var, eq) \
79 _(ISNEV, var, ___, var, eq) \
80 _(ISEQS, var, ___, str, eq) \
81 _(ISNES, var, ___, str, eq) \
82 _(ISEQN, var, ___, num, eq) \
83 _(ISNEN, var, ___, num, eq) \
84 _(ISEQP, var, ___, pri, eq) \
85 _(ISNEP, var, ___, pri, eq) \
86 \
87 /* Unary test and copy ops. */ \
88 _(ISTC, dst, ___, var, ___) \
89 _(ISFC, dst, ___, var, ___) \
90 _(IST, ___, ___, var, ___) \
91 _(ISF, ___, ___, var, ___) \
92 \
93 /* Unary ops. */ \
94 _(MOV, dst, ___, var, ___) \
95 _(NOT, dst, ___, var, ___) \
96 _(UNM, dst, ___, var, unm) \
97 _(LEN, dst, ___, var, len) \
98 \
99 /* Binary ops. ORDER OPR. VV last, POW must be next. */ \
100 _(ADDVN, dst, var, num, add) \
101 _(SUBVN, dst, var, num, sub) \
102 _(MULVN, dst, var, num, mul) \
103 _(DIVVN, dst, var, num, div) \
104 _(MODVN, dst, var, num, mod) \
105 \
106 _(ADDNV, dst, var, num, add) \
107 _(SUBNV, dst, var, num, sub) \
108 _(MULNV, dst, var, num, mul) \
109 _(DIVNV, dst, var, num, div) \
110 _(MODNV, dst, var, num, mod) \
111 \
112 _(ADDVV, dst, var, var, add) \
113 _(SUBVV, dst, var, var, sub) \
114 _(MULVV, dst, var, var, mul) \
115 _(DIVVV, dst, var, var, div) \
116 _(MODVV, dst, var, var, mod) \
117 \
118 _(POW, dst, var, var, pow) \
119 _(CAT, dst, rbase, rbase, concat) \
120 \
121 /* Constant ops. */ \
122 _(KSTR, dst, ___, str, ___) \
123 _(KCDATA, dst, ___, cdata, ___) \
124 _(KSHORT, dst, ___, lits, ___) \
125 _(KNUM, dst, ___, num, ___) \
126 _(KPRI, dst, ___, pri, ___) \
127 _(KNIL, base, ___, base, ___) \
128 \
129 /* Upvalue and function ops. */ \
130 _(UGET, dst, ___, uv, ___) \
131 _(USETV, uv, ___, var, ___) \
132 _(USETS, uv, ___, str, ___) \
133 _(USETN, uv, ___, num, ___) \
134 _(USETP, uv, ___, pri, ___) \
135 _(UCLO, rbase, ___, jump, ___) \
136 _(FNEW, dst, ___, func, gc) \
137 \
138 /* Table ops. */ \
139 _(TNEW, dst, ___, lit, gc) \
140 _(TDUP, dst, ___, tab, gc) \
141 _(GGET, dst, ___, str, index) \
142 _(GSET, var, ___, str, newindex) \
143 _(TGETV, dst, var, var, index) \
144 _(TGETS, dst, var, str, index) \
145 _(TGETB, dst, var, lit, index) \
146 _(TSETV, var, var, var, newindex) \
147 _(TSETS, var, var, str, newindex) \
148 _(TSETB, var, var, lit, newindex) \
149 _(TSETM, base, ___, num, newindex) \
150 \
151 /* Calls and vararg handling. T = tail call. */ \
152 _(CALLM, base, lit, lit, call) \
153 _(CALL, base, lit, lit, call) \
154 _(CALLMT, base, ___, lit, call) \
155 _(CALLT, base, ___, lit, call) \
156 _(ITERC, base, lit, lit, call) \
157 _(ITERN, base, lit, lit, call) \
158 _(VARG, base, lit, lit, ___) \
159 _(ISNEXT, base, ___, jump, ___) \
160 \
161 /* Returns. */ \
162 _(RETM, base, ___, lit, ___) \
163 _(RET, rbase, ___, lit, ___) \
164 _(RET0, rbase, ___, lit, ___) \
165 _(RET1, rbase, ___, lit, ___) \
166 \
167 /* Loops and branches. I/J = interp/JIT, I/C/L = init/call/loop. */ \
168 _(FORI, base, ___, jump, ___) \
169 _(JFORI, base, ___, jump, ___) \
170 \
171 _(FORL, base, ___, jump, ___) \
172 _(IFORL, base, ___, jump, ___) \
173 _(JFORL, base, ___, lit, ___) \
174 \
175 _(ITERL, base, ___, jump, ___) \
176 _(IITERL, base, ___, jump, ___) \
177 _(JITERL, base, ___, lit, ___) \
178 \
179 _(LOOP, rbase, ___, jump, ___) \
180 _(ILOOP, rbase, ___, jump, ___) \
181 _(JLOOP, rbase, ___, lit, ___) \
182 \
183 _(JMP, rbase, ___, jump, ___) \
184 \
185 /* Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func. */ \
186 _(FUNCF, rbase, ___, ___, ___) \
187 _(IFUNCF, rbase, ___, ___, ___) \
188 _(JFUNCF, rbase, ___, lit, ___) \
189 _(FUNCV, rbase, ___, ___, ___) \
190 _(IFUNCV, rbase, ___, ___, ___) \
191 _(JFUNCV, rbase, ___, lit, ___) \
192 _(FUNCC, rbase, ___, ___, ___) \
193 _(FUNCCW, rbase, ___, ___, ___)
194
195/* Bytecode opcode numbers. */
196typedef enum {
197#define BCENUM(name, ma, mb, mc, mt) BC_##name,
198BCDEF(BCENUM)
199#undef BCENUM
200 BC__MAX
201} BCOp;
202
203LJ_STATIC_ASSERT((int)BC_ISEQV+1 == (int)BC_ISNEV);
204LJ_STATIC_ASSERT(((int)BC_ISEQV^1) == (int)BC_ISNEV);
205LJ_STATIC_ASSERT(((int)BC_ISEQS^1) == (int)BC_ISNES);
206LJ_STATIC_ASSERT(((int)BC_ISEQN^1) == (int)BC_ISNEN);
207LJ_STATIC_ASSERT(((int)BC_ISEQP^1) == (int)BC_ISNEP);
208LJ_STATIC_ASSERT(((int)BC_ISLT^1) == (int)BC_ISGE);
209LJ_STATIC_ASSERT(((int)BC_ISLE^1) == (int)BC_ISGT);
210LJ_STATIC_ASSERT(((int)BC_ISLT^3) == (int)BC_ISGT);
211LJ_STATIC_ASSERT((int)BC_IST-(int)BC_ISTC == (int)BC_ISF-(int)BC_ISFC);
212LJ_STATIC_ASSERT((int)BC_CALLT-(int)BC_CALL == (int)BC_CALLMT-(int)BC_CALLM);
213LJ_STATIC_ASSERT((int)BC_CALLMT + 1 == (int)BC_CALLT);
214LJ_STATIC_ASSERT((int)BC_RETM + 1 == (int)BC_RET);
215LJ_STATIC_ASSERT((int)BC_FORL + 1 == (int)BC_IFORL);
216LJ_STATIC_ASSERT((int)BC_FORL + 2 == (int)BC_JFORL);
217LJ_STATIC_ASSERT((int)BC_ITERL + 1 == (int)BC_IITERL);
218LJ_STATIC_ASSERT((int)BC_ITERL + 2 == (int)BC_JITERL);
219LJ_STATIC_ASSERT((int)BC_LOOP + 1 == (int)BC_ILOOP);
220LJ_STATIC_ASSERT((int)BC_LOOP + 2 == (int)BC_JLOOP);
221LJ_STATIC_ASSERT((int)BC_FUNCF + 1 == (int)BC_IFUNCF);
222LJ_STATIC_ASSERT((int)BC_FUNCF + 2 == (int)BC_JFUNCF);
223LJ_STATIC_ASSERT((int)BC_FUNCV + 1 == (int)BC_IFUNCV);
224LJ_STATIC_ASSERT((int)BC_FUNCV + 2 == (int)BC_JFUNCV);
225
226/* This solves a circular dependency problem, change as needed. */
227#define FF_next_N 15
228
229/* Stack slots used by FORI/FORL, relative to operand A. */
230enum {
231 FORL_IDX, FORL_STOP, FORL_STEP, FORL_EXT
232};
233
234/* Bytecode operand modes. ORDER BCMode */
235typedef enum {
236 BCMnone, BCMdst, BCMbase, BCMvar, BCMrbase, BCMuv, /* Mode A must be <= 7 */
237 BCMlit, BCMlits, BCMpri, BCMnum, BCMstr, BCMtab, BCMfunc, BCMjump, BCMcdata,
238 BCM_max
239} BCMode;
240#define BCM___ BCMnone
241
242#define bcmode_a(op) ((BCMode)(lj_bc_mode[op] & 7))
243#define bcmode_b(op) ((BCMode)((lj_bc_mode[op]>>3) & 15))
244#define bcmode_c(op) ((BCMode)((lj_bc_mode[op]>>7) & 15))
245#define bcmode_d(op) bcmode_c(op)
246#define bcmode_hasd(op) ((lj_bc_mode[op] & (15<<3)) == (BCMnone<<3))
247#define bcmode_mm(op) ((MMS)(lj_bc_mode[op]>>11))
248
249#define BCMODE(name, ma, mb, mc, mm) \
250 (BCM##ma|(BCM##mb<<3)|(BCM##mc<<7)|(MM_##mm<<11)),
251#define BCMODE_FF 0
252
253static LJ_AINLINE int bc_isret(BCOp op)
254{
255 return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1);
256}
257
258LJ_DATA const uint16_t lj_bc_mode[];
259LJ_DATA const uint16_t lj_bc_ofs[];
260
261#endif
diff --git a/libraries/luajit-2.0/src/lj_bcdump.h b/libraries/luajit-2.0/src/lj_bcdump.h
new file mode 100644
index 0000000..49b59e8
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_bcdump.h
@@ -0,0 +1,66 @@
1/*
2** Bytecode dump definitions.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_BCDUMP_H
7#define _LJ_BCDUMP_H
8
9#include "lj_obj.h"
10#include "lj_lex.h"
11
12/* -- Bytecode dump format ------------------------------------------------ */
13
14/*
15** dump = header proto+ 0U
16** header = ESC 'L' 'J' versionB flagsU [namelenU nameB*]
17** proto = lengthU pdata
18** pdata = phead bcinsW* uvdataH* kgc* knum* [debugB*]
19** phead = flagsB numparamsB framesizeB numuvB numkgcU numknU numbcU
20** [debuglenU [firstlineU numlineU]]
21** kgc = kgctypeU { ktab | (loU hiU) | (rloU rhiU iloU ihiU) | strB* }
22** knum = intU0 | (loU1 hiU)
23** ktab = narrayU nhashU karray* khash*
24** karray = ktabk
25** khash = ktabk ktabk
26** ktabk = ktabtypeU { intU | (loU hiU) | strB* }
27**
28** B = 8 bit, H = 16 bit, W = 32 bit, U = ULEB128 of W, U0/U1 = ULEB128 of W+1
29*/
30
31/* Bytecode dump header. */
32#define BCDUMP_HEAD1 0x1b
33#define BCDUMP_HEAD2 0x4c
34#define BCDUMP_HEAD3 0x4a
35
36/* If you perform *any* kind of private modifications to the bytecode itself
37** or to the dump format, you *must* set BCDUMP_VERSION to 0x80 or higher.
38*/
39#define BCDUMP_VERSION 1
40
41/* Compatibility flags. */
42#define BCDUMP_F_BE 0x01
43#define BCDUMP_F_STRIP 0x02
44#define BCDUMP_F_FFI 0x04
45
46#define BCDUMP_F_KNOWN (BCDUMP_F_FFI*2-1)
47
48/* Type codes for the GC constants of a prototype. Plus length for strings. */
49enum {
50 BCDUMP_KGC_CHILD, BCDUMP_KGC_TAB, BCDUMP_KGC_I64, BCDUMP_KGC_U64,
51 BCDUMP_KGC_COMPLEX, BCDUMP_KGC_STR
52};
53
54/* Type codes for the keys/values of a constant table. */
55enum {
56 BCDUMP_KTAB_NIL, BCDUMP_KTAB_FALSE, BCDUMP_KTAB_TRUE,
57 BCDUMP_KTAB_INT, BCDUMP_KTAB_NUM, BCDUMP_KTAB_STR
58};
59
60/* -- Bytecode reader/writer ---------------------------------------------- */
61
62LJ_FUNC int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer,
63 void *data, int strip);
64LJ_FUNC GCproto *lj_bcread(LexState *ls);
65
66#endif
diff --git a/libraries/luajit-2.0/src/lj_bcread.c b/libraries/luajit-2.0/src/lj_bcread.c
new file mode 100644
index 0000000..3047923
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_bcread.c
@@ -0,0 +1,466 @@
1/*
2** Bytecode reader.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_bcread_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#include "lj_gc.h"
11#include "lj_err.h"
12#include "lj_str.h"
13#include "lj_tab.h"
14#include "lj_bc.h"
15#if LJ_HASFFI
16#include "lj_ctype.h"
17#include "lj_cdata.h"
18#endif
19#include "lj_lex.h"
20#include "lj_bcdump.h"
21#include "lj_state.h"
22
23/* Reuse some lexer fields for our own purposes. */
24#define bcread_flags(ls) ls->level
25#define bcread_swap(ls) \
26 ((bcread_flags(ls) & BCDUMP_F_BE) != LJ_BE*BCDUMP_F_BE)
27#define bcread_oldtop(L, ls) restorestack(L, ls->lastline)
28#define bcread_savetop(L, ls, top) \
29 ls->lastline = (BCLine)savestack(L, (top))
30
31/* -- Input buffer handling ----------------------------------------------- */
32
33/* Throw reader error. */
34static LJ_NOINLINE void bcread_error(LexState *ls, ErrMsg em)
35{
36 lua_State *L = ls->L;
37 const char *name = ls->chunkarg;
38 if (*name == BCDUMP_HEAD1) name = "(binary)";
39 else if (*name == '@' || *name == '=') name++;
40 lj_str_pushf(L, "%s: %s", name, err2msg(em));
41 lj_err_throw(L, LUA_ERRSYNTAX);
42}
43
44/* Resize input buffer. */
45static void bcread_resize(LexState *ls, MSize len)
46{
47 if (ls->sb.sz < len) {
48 MSize sz = ls->sb.sz * 2;
49 while (len > sz) sz = sz * 2;
50 lj_str_resizebuf(ls->L, &ls->sb, sz);
51 /* Caveat: this may change ls->sb.buf which may affect ls->p. */
52 }
53}
54
55/* Refill buffer if needed. */
56static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
57{
58 lua_assert(len != 0);
59 if (len > LJ_MAX_MEM || ls->current < 0)
60 bcread_error(ls, LJ_ERR_BCBAD);
61 do {
62 const char *buf;
63 size_t size;
64 if (ls->n) { /* Copy remainder to buffer. */
65 if (ls->sb.n) { /* Move down in buffer. */
66 lua_assert(ls->p + ls->n == ls->sb.buf + ls->sb.n);
67 if (ls->n != ls->sb.n)
68 memmove(ls->sb.buf, ls->p, ls->n);
69 } else { /* Copy from buffer provided by reader. */
70 bcread_resize(ls, len);
71 memcpy(ls->sb.buf, ls->p, ls->n);
72 }
73 ls->p = ls->sb.buf;
74 }
75 ls->sb.n = ls->n;
76 buf = ls->rfunc(ls->L, ls->rdata, &size); /* Get more data from reader. */
77 if (buf == NULL || size == 0) { /* EOF? */
78 if (need) bcread_error(ls, LJ_ERR_BCBAD);
79 ls->current = -1; /* Only bad if we get called again. */
80 break;
81 }
82 if (ls->sb.n) { /* Append to buffer. */
83 MSize n = ls->sb.n + (MSize)size;
84 bcread_resize(ls, n < len ? len : n);
85 memcpy(ls->sb.buf + ls->sb.n, buf, size);
86 ls->n = ls->sb.n = n;
87 ls->p = ls->sb.buf;
88 } else { /* Return buffer provided by reader. */
89 ls->n = (MSize)size;
90 ls->p = buf;
91 }
92 } while (ls->n < len);
93}
94
95/* Need a certain number of bytes. */
96static LJ_AINLINE void bcread_need(LexState *ls, MSize len)
97{
98 if (LJ_UNLIKELY(ls->n < len))
99 bcread_fill(ls, len, 1);
100}
101
102/* Want to read up to a certain number of bytes, but may need less. */
103static LJ_AINLINE void bcread_want(LexState *ls, MSize len)
104{
105 if (LJ_UNLIKELY(ls->n < len))
106 bcread_fill(ls, len, 0);
107}
108
109#define bcread_dec(ls) check_exp(ls->n > 0, ls->n--)
110#define bcread_consume(ls, len) check_exp(ls->n >= (len), ls->n -= (len))
111
112/* Return memory block from buffer. */
113static uint8_t *bcread_mem(LexState *ls, MSize len)
114{
115 uint8_t *p = (uint8_t *)ls->p;
116 bcread_consume(ls, len);
117 ls->p = (char *)p + len;
118 return p;
119}
120
121/* Copy memory block from buffer. */
122static void bcread_block(LexState *ls, void *q, MSize len)
123{
124 memcpy(q, bcread_mem(ls, len), len);
125}
126
127/* Read byte from buffer. */
128static LJ_AINLINE uint32_t bcread_byte(LexState *ls)
129{
130 bcread_dec(ls);
131 return (uint32_t)(uint8_t)*ls->p++;
132}
133
134/* Read ULEB128 value from buffer. */
135static uint32_t bcread_uleb128(LexState *ls)
136{
137 const uint8_t *p = (const uint8_t *)ls->p;
138 uint32_t v = *p++;
139 if (LJ_UNLIKELY(v >= 0x80)) {
140 int sh = 0;
141 v &= 0x7f;
142 do {
143 v |= ((*p & 0x7f) << (sh += 7));
144 bcread_dec(ls);
145 } while (*p++ >= 0x80);
146 }
147 bcread_dec(ls);
148 ls->p = (char *)p;
149 return v;
150}
151
152/* Read top 32 bits of 33 bit ULEB128 value from buffer. */
153static uint32_t bcread_uleb128_33(LexState *ls)
154{
155 const uint8_t *p = (const uint8_t *)ls->p;
156 uint32_t v = (*p++ >> 1);
157 if (LJ_UNLIKELY(v >= 0x40)) {
158 int sh = -1;
159 v &= 0x3f;
160 do {
161 v |= ((*p & 0x7f) << (sh += 7));
162 bcread_dec(ls);
163 } while (*p++ >= 0x80);
164 }
165 bcread_dec(ls);
166 ls->p = (char *)p;
167 return v;
168}
169
170/* -- Bytecode reader ----------------------------------------------------- */
171
172/* Read debug info of a prototype. */
173static void bcread_dbg(LexState *ls, GCproto *pt, MSize sizedbg)
174{
175 void *lineinfo = (void *)proto_lineinfo(pt);
176 bcread_block(ls, lineinfo, sizedbg);
177 /* Swap lineinfo if the endianess differs. */
178 if (bcread_swap(ls) && pt->numline >= 256) {
179 MSize i, n = pt->sizebc-1;
180 if (pt->numline < 65536) {
181 uint16_t *p = (uint16_t *)lineinfo;
182 for (i = 0; i < n; i++) p[i] = (uint16_t)((p[i] >> 8)|(p[i] << 8));
183 } else {
184 uint32_t *p = (uint32_t *)lineinfo;
185 for (i = 0; i < n; i++) p[i] = lj_bswap(p[i]);
186 }
187 }
188}
189
190/* Find pointer to varinfo. */
191static const void *bcread_varinfo(GCproto *pt)
192{
193 const uint8_t *p = proto_uvinfo(pt);
194 MSize n = pt->sizeuv;
195 if (n) while (*p++ || --n) ;
196 return p;
197}
198
199/* Read a single constant key/value of a template table. */
200static void bcread_ktabk(LexState *ls, TValue *o)
201{
202 MSize tp = bcread_uleb128(ls);
203 if (tp >= BCDUMP_KTAB_STR) {
204 MSize len = tp - BCDUMP_KTAB_STR;
205 const char *p = (const char *)bcread_mem(ls, len);
206 setstrV(ls->L, o, lj_str_new(ls->L, p, len));
207 } else if (tp == BCDUMP_KTAB_INT) {
208 setintV(o, (int32_t)bcread_uleb128(ls));
209 } else if (tp == BCDUMP_KTAB_NUM) {
210 o->u32.lo = bcread_uleb128(ls);
211 o->u32.hi = bcread_uleb128(ls);
212 } else {
213 lua_assert(tp <= BCDUMP_KTAB_TRUE);
214 setitype(o, ~tp);
215 }
216}
217
218/* Read a template table. */
219static GCtab *bcread_ktab(LexState *ls)
220{
221 MSize narray = bcread_uleb128(ls);
222 MSize nhash = bcread_uleb128(ls);
223 GCtab *t = lj_tab_new(ls->L, narray, hsize2hbits(nhash));
224 if (narray) { /* Read array entries. */
225 MSize i;
226 TValue *o = tvref(t->array);
227 for (i = 0; i < narray; i++, o++)
228 bcread_ktabk(ls, o);
229 }
230 if (nhash) { /* Read hash entries. */
231 MSize i;
232 for (i = 0; i < nhash; i++) {
233 TValue key;
234 bcread_ktabk(ls, &key);
235 lua_assert(!tvisnil(&key));
236 bcread_ktabk(ls, lj_tab_set(ls->L, t, &key));
237 }
238 }
239 return t;
240}
241
242/* Read GC constants of a prototype. */
243static void bcread_kgc(LexState *ls, GCproto *pt, MSize sizekgc)
244{
245 MSize i;
246 GCRef *kr = mref(pt->k, GCRef) - (ptrdiff_t)sizekgc;
247 for (i = 0; i < sizekgc; i++, kr++) {
248 MSize tp = bcread_uleb128(ls);
249 if (tp >= BCDUMP_KGC_STR) {
250 MSize len = tp - BCDUMP_KGC_STR;
251 const char *p = (const char *)bcread_mem(ls, len);
252 setgcref(*kr, obj2gco(lj_str_new(ls->L, p, len)));
253 } else if (tp == BCDUMP_KGC_TAB) {
254 setgcref(*kr, obj2gco(bcread_ktab(ls)));
255#if LJ_HASFFI
256 } else if (tp != BCDUMP_KGC_CHILD) {
257 CTypeID id = tp == BCDUMP_KGC_COMPLEX ? CTID_COMPLEX_DOUBLE :
258 tp == BCDUMP_KGC_I64 ? CTID_INT64 : CTID_UINT64;
259 CTSize sz = tp == BCDUMP_KGC_COMPLEX ? 16 : 8;
260 GCcdata *cd = lj_cdata_new_(ls->L, id, sz);
261 TValue *p = (TValue *)cdataptr(cd);
262 setgcref(*kr, obj2gco(cd));
263 p[0].u32.lo = bcread_uleb128(ls);
264 p[0].u32.hi = bcread_uleb128(ls);
265 if (tp == BCDUMP_KGC_COMPLEX) {
266 p[1].u32.lo = bcread_uleb128(ls);
267 p[1].u32.hi = bcread_uleb128(ls);
268 }
269#endif
270 } else {
271 lua_State *L = ls->L;
272 lua_assert(tp == BCDUMP_KGC_CHILD);
273 if (L->top <= bcread_oldtop(L, ls)) /* Stack underflow? */
274 bcread_error(ls, LJ_ERR_BCBAD);
275 L->top--;
276 setgcref(*kr, obj2gco(protoV(L->top)));
277 }
278 }
279}
280
281/* Read number constants of a prototype. */
282static void bcread_knum(LexState *ls, GCproto *pt, MSize sizekn)
283{
284 MSize i;
285 TValue *o = mref(pt->k, TValue);
286 for (i = 0; i < sizekn; i++, o++) {
287 int isnum = (ls->p[0] & 1);
288 uint32_t lo = bcread_uleb128_33(ls);
289 if (isnum) {
290 o->u32.lo = lo;
291 o->u32.hi = bcread_uleb128(ls);
292 } else {
293 setintV(o, lo);
294 }
295 }
296}
297
298/* Read bytecode instructions. */
299static void bcread_bytecode(LexState *ls, GCproto *pt, MSize sizebc)
300{
301 BCIns *bc = proto_bc(pt);
302 bc[0] = BCINS_AD((pt->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
303 pt->framesize, 0);
304 bcread_block(ls, bc+1, (sizebc-1)*(MSize)sizeof(BCIns));
305 /* Swap bytecode instructions if the endianess differs. */
306 if (bcread_swap(ls)) {
307 MSize i;
308 for (i = 1; i < sizebc; i++) bc[i] = lj_bswap(bc[i]);
309 }
310}
311
312/* Read upvalue refs. */
313static void bcread_uv(LexState *ls, GCproto *pt, MSize sizeuv)
314{
315 if (sizeuv) {
316 uint16_t *uv = proto_uv(pt);
317 bcread_block(ls, uv, sizeuv*2);
318 /* Swap upvalue refs if the endianess differs. */
319 if (bcread_swap(ls)) {
320 MSize i;
321 for (i = 0; i < sizeuv; i++)
322 uv[i] = (uint16_t)((uv[i] >> 8)|(uv[i] << 8));
323 }
324 }
325}
326
327/* Read a prototype. */
328static GCproto *bcread_proto(LexState *ls)
329{
330 GCproto *pt;
331 MSize framesize, numparams, flags, sizeuv, sizekgc, sizekn, sizebc, sizept;
332 MSize ofsk, ofsuv, ofsdbg;
333 MSize sizedbg = 0;
334 BCLine firstline = 0, numline = 0;
335 MSize len, startn;
336
337 /* Read length. */
338 if (ls->n > 0 && ls->p[0] == 0) { /* Shortcut EOF. */
339 ls->n--; ls->p++;
340 return NULL;
341 }
342 bcread_want(ls, 5);
343 len = bcread_uleb128(ls);
344 if (!len) return NULL; /* EOF */
345 bcread_need(ls, len);
346 startn = ls->n;
347
348 /* Read prototype header. */
349 flags = bcread_byte(ls);
350 numparams = bcread_byte(ls);
351 framesize = bcread_byte(ls);
352 sizeuv = bcread_byte(ls);
353 sizekgc = bcread_uleb128(ls);
354 sizekn = bcread_uleb128(ls);
355 sizebc = bcread_uleb128(ls) + 1;
356 if (!(bcread_flags(ls) & BCDUMP_F_STRIP)) {
357 sizedbg = bcread_uleb128(ls);
358 if (sizedbg) {
359 firstline = bcread_uleb128(ls);
360 numline = bcread_uleb128(ls);
361 }
362 }
363
364 /* Calculate total size of prototype including all colocated arrays. */
365 sizept = (MSize)sizeof(GCproto) +
366 sizebc*(MSize)sizeof(BCIns) +
367 sizekgc*(MSize)sizeof(GCRef);
368 sizept = (sizept + (MSize)sizeof(TValue)-1) & ~((MSize)sizeof(TValue)-1);
369 ofsk = sizept; sizept += sizekn*(MSize)sizeof(TValue);
370 ofsuv = sizept; sizept += ((sizeuv+1)&~1)*2;
371 ofsdbg = sizept; sizept += sizedbg;
372
373 /* Allocate prototype object and initialize its fields. */
374 pt = (GCproto *)lj_mem_newgco(ls->L, (MSize)sizept);
375 pt->gct = ~LJ_TPROTO;
376 pt->numparams = (uint8_t)numparams;
377 pt->framesize = (uint8_t)framesize;
378 pt->sizebc = sizebc;
379 setmref(pt->k, (char *)pt + ofsk);
380 setmref(pt->uv, (char *)pt + ofsuv);
381 pt->sizekgc = 0; /* Set to zero until fully initialized. */
382 pt->sizekn = sizekn;
383 pt->sizept = sizept;
384 pt->sizeuv = (uint8_t)sizeuv;
385 pt->flags = (uint8_t)flags;
386 pt->trace = 0;
387 setgcref(pt->chunkname, obj2gco(ls->chunkname));
388
389 /* Close potentially uninitialized gap between bc and kgc. */
390 *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(sizekgc+1)) = 0;
391
392 /* Read bytecode instructions and upvalue refs. */
393 bcread_bytecode(ls, pt, sizebc);
394 bcread_uv(ls, pt, sizeuv);
395
396 /* Read constants. */
397 bcread_kgc(ls, pt, sizekgc);
398 pt->sizekgc = sizekgc;
399 bcread_knum(ls, pt, sizekn);
400
401 /* Read and initialize debug info. */
402 pt->firstline = firstline;
403 pt->numline = numline;
404 if (sizedbg) {
405 MSize sizeli = (sizebc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2);
406 setmref(pt->lineinfo, (char *)pt + ofsdbg);
407 setmref(pt->uvinfo, (char *)pt + ofsdbg + sizeli);
408 bcread_dbg(ls, pt, sizedbg);
409 setmref(pt->varinfo, bcread_varinfo(pt));
410 } else {
411 setmref(pt->lineinfo, NULL);
412 setmref(pt->uvinfo, NULL);
413 setmref(pt->varinfo, NULL);
414 }
415
416 if (len != startn - ls->n)
417 bcread_error(ls, LJ_ERR_BCBAD);
418 return pt;
419}
420
421/* Read and check header of bytecode dump. */
422static int bcread_header(LexState *ls)
423{
424 uint32_t flags;
425 bcread_want(ls, 3+5+5);
426 if (bcread_byte(ls) != BCDUMP_HEAD2 ||
427 bcread_byte(ls) != BCDUMP_HEAD3 ||
428 bcread_byte(ls) != BCDUMP_VERSION) return 0;
429 bcread_flags(ls) = flags = bcread_uleb128(ls);
430 if ((flags & ~(BCDUMP_F_KNOWN)) != 0) return 0;
431#if !LJ_HASFFI
432 if ((flags & BCDUMP_F_FFI)) return 0;
433#endif
434 if ((flags & BCDUMP_F_STRIP)) {
435 ls->chunkname = lj_str_newz(ls->L, ls->chunkarg);
436 } else {
437 MSize len = bcread_uleb128(ls);
438 bcread_need(ls, len);
439 ls->chunkname = lj_str_new(ls->L, (const char *)bcread_mem(ls, len), len);
440 }
441 return 1; /* Ok. */
442}
443
444/* Read a bytecode dump. */
445GCproto *lj_bcread(LexState *ls)
446{
447 lua_State *L = ls->L;
448 lua_assert(ls->current == BCDUMP_HEAD1);
449 bcread_savetop(L, ls, L->top);
450 lj_str_resetbuf(&ls->sb);
451 /* Check for a valid bytecode dump header. */
452 if (!bcread_header(ls))
453 bcread_error(ls, LJ_ERR_BCFMT);
454 for (;;) { /* Process all prototypes in the bytecode dump. */
455 GCproto *pt = bcread_proto(ls);
456 if (!pt) break;
457 setprotoV(L, L->top, pt);
458 incr_top(L);
459 }
460 if ((int32_t)ls->n > 0 || L->top-1 != bcread_oldtop(L, ls))
461 bcread_error(ls, LJ_ERR_BCBAD);
462 /* Pop off last prototype. */
463 L->top--;
464 return protoV(L->top);
465}
466
diff --git a/libraries/luajit-2.0/src/lj_bcwrite.c b/libraries/luajit-2.0/src/lj_bcwrite.c
new file mode 100644
index 0000000..de9b4cf
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_bcwrite.c
@@ -0,0 +1,389 @@
1/*
2** Bytecode writer.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_bcwrite_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#include "lj_gc.h"
11#include "lj_str.h"
12#include "lj_bc.h"
13#if LJ_HASFFI
14#include "lj_ctype.h"
15#endif
16#if LJ_HASJIT
17#include "lj_dispatch.h"
18#include "lj_jit.h"
19#endif
20#include "lj_bcdump.h"
21#include "lj_vm.h"
22
23/* Context for bytecode writer. */
24typedef struct BCWriteCtx {
25 SBuf sb; /* Output buffer. */
26 lua_State *L; /* Lua state. */
27 GCproto *pt; /* Root prototype. */
28 lua_Writer wfunc; /* Writer callback. */
29 void *wdata; /* Writer callback data. */
30 int strip; /* Strip debug info. */
31 int status; /* Status from writer callback. */
32} BCWriteCtx;
33
34/* -- Output buffer handling ---------------------------------------------- */
35
36/* Resize buffer if needed. */
37static LJ_NOINLINE void bcwrite_resize(BCWriteCtx *ctx, MSize len)
38{
39 MSize sz = ctx->sb.sz * 2;
40 while (ctx->sb.n + len > sz) sz = sz * 2;
41 lj_str_resizebuf(ctx->L, &ctx->sb, sz);
42}
43
44/* Need a certain amount of buffer space. */
45static LJ_AINLINE void bcwrite_need(BCWriteCtx *ctx, MSize len)
46{
47 if (LJ_UNLIKELY(ctx->sb.n + len > ctx->sb.sz))
48 bcwrite_resize(ctx, len);
49}
50
51/* Add memory block to buffer. */
52static void bcwrite_block(BCWriteCtx *ctx, const void *p, MSize len)
53{
54 uint8_t *q = (uint8_t *)(ctx->sb.buf + ctx->sb.n);
55 MSize i;
56 ctx->sb.n += len;
57 for (i = 0; i < len; i++) q[i] = ((uint8_t *)p)[i];
58}
59
60/* Add byte to buffer. */
61static LJ_AINLINE void bcwrite_byte(BCWriteCtx *ctx, uint8_t b)
62{
63 ctx->sb.buf[ctx->sb.n++] = b;
64}
65
66/* Add ULEB128 value to buffer. */
67static void bcwrite_uleb128(BCWriteCtx *ctx, uint32_t v)
68{
69 MSize n = ctx->sb.n;
70 uint8_t *p = (uint8_t *)ctx->sb.buf;
71 for (; v >= 0x80; v >>= 7)
72 p[n++] = (uint8_t)((v & 0x7f) | 0x80);
73 p[n++] = (uint8_t)v;
74 ctx->sb.n = n;
75}
76
77/* -- Bytecode writer ----------------------------------------------------- */
78
79/* Write a single constant key/value of a template table. */
80static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
81{
82 bcwrite_need(ctx, 1+10);
83 if (tvisstr(o)) {
84 const GCstr *str = strV(o);
85 MSize len = str->len;
86 bcwrite_need(ctx, 5+len);
87 bcwrite_uleb128(ctx, BCDUMP_KTAB_STR+len);
88 bcwrite_block(ctx, strdata(str), len);
89 } else if (tvisint(o)) {
90 bcwrite_byte(ctx, BCDUMP_KTAB_INT);
91 bcwrite_uleb128(ctx, intV(o));
92 } else if (tvisnum(o)) {
93 if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */
94 lua_Number num = numV(o);
95 int32_t k = lj_num2int(num);
96 if (num == (lua_Number)k) { /* -0 is never a constant. */
97 bcwrite_byte(ctx, BCDUMP_KTAB_INT);
98 bcwrite_uleb128(ctx, k);
99 return;
100 }
101 }
102 bcwrite_byte(ctx, BCDUMP_KTAB_NUM);
103 bcwrite_uleb128(ctx, o->u32.lo);
104 bcwrite_uleb128(ctx, o->u32.hi);
105 } else {
106 lua_assert(tvispri(o));
107 bcwrite_byte(ctx, BCDUMP_KTAB_NIL+~itype(o));
108 }
109}
110
111/* Write a template table. */
112static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t)
113{
114 MSize narray = 0, nhash = 0;
115 if (t->asize > 0) { /* Determine max. length of array part. */
116 ptrdiff_t i;
117 TValue *array = tvref(t->array);
118 for (i = (ptrdiff_t)t->asize-1; i >= 0; i--)
119 if (!tvisnil(&array[i]))
120 break;
121 narray = (MSize)(i+1);
122 }
123 if (t->hmask > 0) { /* Count number of used hash slots. */
124 MSize i, hmask = t->hmask;
125 Node *node = noderef(t->node);
126 for (i = 0; i <= hmask; i++)
127 nhash += !tvisnil(&node[i].val);
128 }
129 /* Write number of array slots and hash slots. */
130 bcwrite_uleb128(ctx, narray);
131 bcwrite_uleb128(ctx, nhash);
132 if (narray) { /* Write array entries (may contain nil). */
133 MSize i;
134 TValue *o = tvref(t->array);
135 for (i = 0; i < narray; i++, o++)
136 bcwrite_ktabk(ctx, o, 1);
137 }
138 if (nhash) { /* Write hash entries. */
139 MSize i = nhash;
140 Node *node = noderef(t->node) + t->hmask;
141 for (;; node--)
142 if (!tvisnil(&node->val)) {
143 bcwrite_ktabk(ctx, &node->key, 0);
144 bcwrite_ktabk(ctx, &node->val, 1);
145 if (--i == 0) break;
146 }
147 }
148}
149
150/* Write GC constants of a prototype. */
151static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
152{
153 MSize i, sizekgc = pt->sizekgc;
154 GCRef *kr = mref(pt->k, GCRef) - (ptrdiff_t)sizekgc;
155 for (i = 0; i < sizekgc; i++, kr++) {
156 GCobj *o = gcref(*kr);
157 MSize tp, need = 1;
158 /* Determine constant type and needed size. */
159 if (o->gch.gct == ~LJ_TSTR) {
160 tp = BCDUMP_KGC_STR + gco2str(o)->len;
161 need = 5+gco2str(o)->len;
162 } else if (o->gch.gct == ~LJ_TPROTO) {
163 lua_assert((pt->flags & PROTO_CHILD));
164 tp = BCDUMP_KGC_CHILD;
165#if LJ_HASFFI
166 } else if (o->gch.gct == ~LJ_TCDATA) {
167 CTypeID id = gco2cd(o)->typeid;
168 need = 1+4*5;
169 if (id == CTID_INT64) {
170 tp = BCDUMP_KGC_I64;
171 } else if (id == CTID_UINT64) {
172 tp = BCDUMP_KGC_U64;
173 } else {
174 lua_assert(id == CTID_COMPLEX_DOUBLE);
175 tp = BCDUMP_KGC_COMPLEX;
176 }
177#endif
178 } else {
179 lua_assert(o->gch.gct == ~LJ_TTAB);
180 tp = BCDUMP_KGC_TAB;
181 }
182 /* Write constant type. */
183 bcwrite_need(ctx, need);
184 bcwrite_uleb128(ctx, tp);
185 /* Write constant data (if any). */
186 if (tp >= BCDUMP_KGC_STR) {
187 bcwrite_block(ctx, strdata(gco2str(o)), gco2str(o)->len);
188 } else if (tp == BCDUMP_KGC_TAB) {
189 bcwrite_ktab(ctx, gco2tab(o));
190#if LJ_HASFFI
191 } else if (tp != BCDUMP_KGC_CHILD) {
192 cTValue *p = (TValue *)cdataptr(gco2cd(o));
193 bcwrite_uleb128(ctx, p[0].u32.lo);
194 bcwrite_uleb128(ctx, p[0].u32.hi);
195 if (tp == BCDUMP_KGC_COMPLEX) {
196 bcwrite_uleb128(ctx, p[1].u32.lo);
197 bcwrite_uleb128(ctx, p[1].u32.hi);
198 }
199#endif
200 }
201 }
202}
203
204/* Write number constants of a prototype. */
205static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
206{
207 MSize i, sizekn = pt->sizekn;
208 cTValue *o = mref(pt->k, TValue);
209 bcwrite_need(ctx, 10*sizekn);
210 for (i = 0; i < sizekn; i++, o++) {
211 int32_t k;
212 if (tvisint(o)) {
213 k = intV(o);
214 goto save_int;
215 } else {
216 /* Write a 33 bit ULEB128 for the int (lsb=0) or loword (lsb=1). */
217 if (!LJ_DUALNUM) { /* Narrow number constants to integers. */
218 lua_Number num = numV(o);
219 k = lj_num2int(num);
220 if (num == (lua_Number)k) { /* -0 is never a constant. */
221 save_int:
222 bcwrite_uleb128(ctx, 2*(uint32_t)k);
223 if (k < 0) ctx->sb.buf[ctx->sb.n-1] |= 0x10;
224 continue;
225 }
226 }
227 bcwrite_uleb128(ctx, 1+2*o->u32.lo);
228 if (o->u32.lo >= 0x80000000u) ctx->sb.buf[ctx->sb.n-1] |= 0x10;
229 bcwrite_uleb128(ctx, o->u32.hi);
230 }
231 }
232}
233
234/* Write bytecode instructions. */
235static void bcwrite_bytecode(BCWriteCtx *ctx, GCproto *pt)
236{
237 MSize nbc = pt->sizebc-1; /* Omit the [JI]FUNC* header. */
238#if LJ_HASJIT
239 uint8_t *p = (uint8_t *)&ctx->sb.buf[ctx->sb.n];
240#endif
241 bcwrite_block(ctx, proto_bc(pt)+1, nbc*(MSize)sizeof(BCIns));
242#if LJ_HASJIT
243 /* Unpatch modified bytecode containing ILOOP/JLOOP etc. */
244 if ((pt->flags & PROTO_ILOOP) || pt->trace) {
245 jit_State *J = L2J(ctx->L);
246 MSize i;
247 for (i = 0; i < nbc; i++, p += sizeof(BCIns)) {
248 BCOp op = (BCOp)p[LJ_ENDIAN_SELECT(0, 3)];
249 if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP ||
250 op == BC_JFORI) {
251 p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_IFORL+BC_FORL);
252 } else if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) {
253 BCReg rd = p[LJ_ENDIAN_SELECT(2, 1)] + (p[LJ_ENDIAN_SELECT(3, 0)] << 8);
254 BCIns ins = traceref(J, rd)->startins;
255 p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_JFORL+BC_FORL);
256 p[LJ_ENDIAN_SELECT(2, 1)] = bc_c(ins);
257 p[LJ_ENDIAN_SELECT(3, 0)] = bc_b(ins);
258 }
259 }
260 }
261#endif
262}
263
264/* Write prototype. */
265static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
266{
267 MSize sizedbg = 0;
268
269 /* Recursively write children of prototype. */
270 if ((pt->flags & PROTO_CHILD)) {
271 ptrdiff_t i, n = pt->sizekgc;
272 GCRef *kr = mref(pt->k, GCRef) - 1;
273 for (i = 0; i < n; i++, kr--) {
274 GCobj *o = gcref(*kr);
275 if (o->gch.gct == ~LJ_TPROTO)
276 bcwrite_proto(ctx, gco2pt(o));
277 }
278 }
279
280 /* Start writing the prototype info to a buffer. */
281 lj_str_resetbuf(&ctx->sb);
282 ctx->sb.n = 5; /* Leave room for final size. */
283 bcwrite_need(ctx, 4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2);
284
285 /* Write prototype header. */
286 bcwrite_byte(ctx, (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI)));
287 bcwrite_byte(ctx, pt->numparams);
288 bcwrite_byte(ctx, pt->framesize);
289 bcwrite_byte(ctx, pt->sizeuv);
290 bcwrite_uleb128(ctx, pt->sizekgc);
291 bcwrite_uleb128(ctx, pt->sizekn);
292 bcwrite_uleb128(ctx, pt->sizebc-1);
293 if (!ctx->strip) {
294 if (proto_lineinfo(pt))
295 sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt);
296 bcwrite_uleb128(ctx, sizedbg);
297 if (sizedbg) {
298 bcwrite_uleb128(ctx, pt->firstline);
299 bcwrite_uleb128(ctx, pt->numline);
300 }
301 }
302
303 /* Write bytecode instructions and upvalue refs. */
304 bcwrite_bytecode(ctx, pt);
305 bcwrite_block(ctx, proto_uv(pt), pt->sizeuv*2);
306
307 /* Write constants. */
308 bcwrite_kgc(ctx, pt);
309 bcwrite_knum(ctx, pt);
310
311 /* Write debug info, if not stripped. */
312 if (sizedbg) {
313 bcwrite_need(ctx, sizedbg);
314 bcwrite_block(ctx, proto_lineinfo(pt), sizedbg);
315 }
316
317 /* Pass buffer to writer function. */
318 if (ctx->status == 0) {
319 MSize n = ctx->sb.n - 5;
320 MSize nn = 1 + lj_fls(n)/7;
321 ctx->sb.n = 5 - nn;
322 bcwrite_uleb128(ctx, n); /* Fill in final size. */
323 lua_assert(ctx->sb.n == 5);
324 ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf+5-nn, nn+n, ctx->wdata);
325 }
326}
327
328/* Write header of bytecode dump. */
329static void bcwrite_header(BCWriteCtx *ctx)
330{
331 GCstr *chunkname = proto_chunkname(ctx->pt);
332 const char *name = strdata(chunkname);
333 MSize len = chunkname->len;
334 lj_str_resetbuf(&ctx->sb);
335 bcwrite_need(ctx, 5+5+len);
336 bcwrite_byte(ctx, BCDUMP_HEAD1);
337 bcwrite_byte(ctx, BCDUMP_HEAD2);
338 bcwrite_byte(ctx, BCDUMP_HEAD3);
339 bcwrite_byte(ctx, BCDUMP_VERSION);
340 bcwrite_byte(ctx, (ctx->strip ? BCDUMP_F_STRIP : 0) +
341 (LJ_BE ? BCDUMP_F_BE : 0) +
342 ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0));
343 if (!ctx->strip) {
344 bcwrite_uleb128(ctx, len);
345 bcwrite_block(ctx, name, len);
346 }
347 ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf, ctx->sb.n, ctx->wdata);
348}
349
350/* Write footer of bytecode dump. */
351static void bcwrite_footer(BCWriteCtx *ctx)
352{
353 if (ctx->status == 0) {
354 uint8_t zero = 0;
355 ctx->status = ctx->wfunc(ctx->L, &zero, 1, ctx->wdata);
356 }
357}
358
359/* Protected callback for bytecode writer. */
360static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud)
361{
362 BCWriteCtx *ctx = (BCWriteCtx *)ud;
363 UNUSED(dummy);
364 lj_str_resizebuf(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */
365 bcwrite_header(ctx);
366 bcwrite_proto(ctx, ctx->pt);
367 bcwrite_footer(ctx);
368 return NULL;
369}
370
371/* Write bytecode for a prototype. */
372int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data,
373 int strip)
374{
375 BCWriteCtx ctx;
376 int status;
377 ctx.L = L;
378 ctx.pt = pt;
379 ctx.wfunc = writer;
380 ctx.wdata = data;
381 ctx.strip = strip;
382 ctx.status = 0;
383 lj_str_initbuf(&ctx.sb);
384 status = lj_vm_cpcall(L, NULL, &ctx, cpwriter);
385 if (status == 0) status = ctx.status;
386 lj_str_freebuf(G(ctx.L), &ctx.sb);
387 return status;
388}
389
diff --git a/libraries/luajit-2.0/src/lj_carith.c b/libraries/luajit-2.0/src/lj_carith.c
new file mode 100644
index 0000000..b0f4c65
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_carith.c
@@ -0,0 +1,314 @@
1/*
2** C data arithmetic.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "lj_obj.h"
7
8#if LJ_HASFFI
9
10#include "lj_gc.h"
11#include "lj_err.h"
12#include "lj_tab.h"
13#include "lj_meta.h"
14#include "lj_ctype.h"
15#include "lj_cconv.h"
16#include "lj_cdata.h"
17#include "lj_carith.h"
18
19/* -- C data arithmetic --------------------------------------------------- */
20
21/* Binary operands of an operator converted to ctypes. */
22typedef struct CDArith {
23 uint8_t *p[2];
24 CType *ct[2];
25} CDArith;
26
27/* Check arguments for arithmetic metamethods. */
28static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca)
29{
30 TValue *o = L->base;
31 int ok = 1;
32 MSize i;
33 if (o+1 >= L->top)
34 lj_err_argt(L, 1, LUA_TCDATA);
35 for (i = 0; i < 2; i++, o++) {
36 if (tviscdata(o)) {
37 GCcdata *cd = cdataV(o);
38 CTypeID id = (CTypeID)cd->typeid;
39 CType *ct = ctype_raw(cts, id);
40 uint8_t *p = (uint8_t *)cdataptr(cd);
41 if (ctype_isptr(ct->info)) {
42 p = (uint8_t *)cdata_getptr(p, ct->size);
43 if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
44 } else if (ctype_isfunc(ct->info)) {
45 p = (uint8_t *)*(void **)p;
46 ct = ctype_get(cts,
47 lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
48 }
49 ca->ct[i] = ct;
50 ca->p[i] = p;
51 } else if (tvisint(o)) {
52 ca->ct[i] = ctype_get(cts, CTID_INT32);
53 ca->p[i] = (uint8_t *)&o->i;
54 } else if (tvisnum(o)) {
55 ca->ct[i] = ctype_get(cts, CTID_DOUBLE);
56 ca->p[i] = (uint8_t *)&o->n;
57 } else if (tvisnil(o)) {
58 ca->ct[i] = ctype_get(cts, CTID_P_VOID);
59 ca->p[i] = (uint8_t *)0;
60 } else {
61 ca->ct[i] = NULL;
62 ca->p[i] = NULL;
63 ok = 0;
64 }
65 }
66 return ok;
67}
68
69/* Pointer arithmetic. */
70static int carith_ptr(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
71{
72 CType *ctp = ca->ct[0];
73 uint8_t *pp = ca->p[0];
74 ptrdiff_t idx;
75 CTSize sz;
76 CTypeID id;
77 GCcdata *cd;
78 if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) {
79 if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) &&
80 (ctype_isptr(ca->ct[1]->info) || ctype_isrefarray(ca->ct[1]->info))) {
81 uint8_t *pp2 = ca->p[1];
82 if (mm == MM_eq) { /* Pointer equality. Incompatible pointers are ok. */
83 setboolV(L->top-1, (pp == pp2));
84 return 1;
85 }
86 if (!lj_cconv_compatptr(cts, ctp, ca->ct[1], CCF_IGNQUAL))
87 return 0;
88 if (mm == MM_sub) { /* Pointer difference. */
89 intptr_t diff;
90 sz = lj_ctype_size(cts, ctype_cid(ctp->info)); /* Element size. */
91 if (sz == 0 || sz == CTSIZE_INVALID)
92 return 0;
93 diff = ((intptr_t)pp - (intptr_t)pp2) / (int32_t)sz;
94 /* All valid pointer differences on x64 are in (-2^47, +2^47),
95 ** which fits into a double without loss of precision.
96 */
97 setintptrV(L->top-1, (int32_t)diff);
98 return 1;
99 } else if (mm == MM_lt) { /* Pointer comparison (unsigned). */
100 setboolV(L->top-1, ((uintptr_t)pp < (uintptr_t)pp2));
101 return 1;
102 } else {
103 lua_assert(mm == MM_le);
104 setboolV(L->top-1, ((uintptr_t)pp <= (uintptr_t)pp2));
105 return 1;
106 }
107 }
108 if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(ca->ct[1]->info)))
109 return 0;
110 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), ca->ct[1],
111 (uint8_t *)&idx, ca->p[1], 0);
112 if (mm == MM_sub) idx = -idx;
113 } else if (mm == MM_add && ctype_isnum(ctp->info) &&
114 (ctype_isptr(ca->ct[1]->info) || ctype_isrefarray(ca->ct[1]->info))) {
115 /* Swap pointer and index. */
116 ctp = ca->ct[1]; pp = ca->p[1];
117 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), ca->ct[0],
118 (uint8_t *)&idx, ca->p[0], 0);
119 } else {
120 return 0;
121 }
122 sz = lj_ctype_size(cts, ctype_cid(ctp->info)); /* Element size. */
123 if (sz == CTSIZE_INVALID)
124 return 0;
125 pp += idx*(int32_t)sz; /* Compute pointer + index. */
126 id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)),
127 CTSIZE_PTR);
128 cd = lj_cdata_new(cts, id, CTSIZE_PTR);
129 *(uint8_t **)cdataptr(cd) = pp;
130 setcdataV(L, L->top-1, cd);
131 lj_gc_check(L);
132 return 1;
133}
134
135/* 64 bit integer arithmetic. */
136static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
137{
138 if (ctype_isnum(ca->ct[0]->info) && ca->ct[0]->size <= 8 &&
139 ctype_isnum(ca->ct[1]->info) && ca->ct[1]->size <= 8) {
140 CTypeID id = (((ca->ct[0]->info & CTF_UNSIGNED) && ca->ct[0]->size == 8) ||
141 ((ca->ct[1]->info & CTF_UNSIGNED) && ca->ct[1]->size == 8)) ?
142 CTID_UINT64 : CTID_INT64;
143 CType *ct = ctype_get(cts, id);
144 GCcdata *cd;
145 uint64_t u0, u1, *up;
146 lj_cconv_ct_ct(cts, ct, ca->ct[0], (uint8_t *)&u0, ca->p[0], 0);
147 if (mm != MM_unm)
148 lj_cconv_ct_ct(cts, ct, ca->ct[1], (uint8_t *)&u1, ca->p[1], 0);
149 switch (mm) {
150 case MM_eq:
151 setboolV(L->top-1, (u0 == u1));
152 return 1;
153 case MM_lt:
154 setboolV(L->top-1,
155 id == CTID_INT64 ? ((int64_t)u0 < (int64_t)u1) : (u0 < u1));
156 return 1;
157 case MM_le:
158 setboolV(L->top-1,
159 id == CTID_INT64 ? ((int64_t)u0 <= (int64_t)u1) : (u0 <= u1));
160 return 1;
161 default: break;
162 }
163 cd = lj_cdata_new(cts, id, 8);
164 up = (uint64_t *)cdataptr(cd);
165 setcdataV(L, L->top-1, cd);
166 switch (mm) {
167 case MM_add: *up = u0 + u1; break;
168 case MM_sub: *up = u0 - u1; break;
169 case MM_mul: *up = u0 * u1; break;
170 case MM_div:
171 if (id == CTID_INT64)
172 *up = (uint64_t)lj_carith_divi64((int64_t)u0, (int64_t)u1);
173 else
174 *up = lj_carith_divu64(u0, u1);
175 break;
176 case MM_mod:
177 if (id == CTID_INT64)
178 *up = (uint64_t)lj_carith_modi64((int64_t)u0, (int64_t)u1);
179 else
180 *up = lj_carith_modu64(u0, u1);
181 break;
182 case MM_pow:
183 if (id == CTID_INT64)
184 *up = (uint64_t)lj_carith_powi64((int64_t)u0, (int64_t)u1);
185 else
186 *up = lj_carith_powu64(u0, u1);
187 break;
188 case MM_unm: *up = (uint64_t)-(int64_t)u0; break;
189 default: lua_assert(0); break;
190 }
191 lj_gc_check(L);
192 return 1;
193 }
194 return 0;
195}
196
197/* Handle ctype arithmetic metamethods. */
198static int lj_carith_meta(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
199{
200 cTValue *tv = NULL;
201 if (tviscdata(L->base))
202 tv = lj_ctype_meta(cts, cdataV(L->base)->typeid, mm);
203 if (!tv && L->base+1 < L->top && tviscdata(L->base+1))
204 tv = lj_ctype_meta(cts, cdataV(L->base+1)->typeid, mm);
205 if (!tv) {
206 const char *repr[2];
207 int i;
208 for (i = 0; i < 2; i++) {
209 if (ca->ct[i])
210 repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca->ct[i]), NULL));
211 else
212 repr[i] = typename(&L->base[i]);
213 }
214 lj_err_callerv(L, mm == MM_len ? LJ_ERR_FFI_BADLEN :
215 mm == MM_concat ? LJ_ERR_FFI_BADCONCAT :
216 mm < MM_add ? LJ_ERR_FFI_BADCOMP : LJ_ERR_FFI_BADARITH,
217 repr[0], repr[1]);
218 }
219 return lj_meta_tailcall(L, tv);
220}
221
222/* Arithmetic operators for cdata. */
223int lj_carith_op(lua_State *L, MMS mm)
224{
225 CTState *cts = ctype_cts(L);
226 CDArith ca;
227 if (carith_checkarg(L, cts, &ca)) {
228 if (carith_int64(L, cts, &ca, mm) || carith_ptr(L, cts, &ca, mm)) {
229 copyTV(L, &G(L)->tmptv2, L->top-1); /* Remember for trace recorder. */
230 return 1;
231 }
232 }
233 return lj_carith_meta(L, cts, &ca, mm);
234}
235
236/* -- 64 bit integer arithmetic helpers ----------------------------------- */
237
238#if LJ_32 && LJ_HASJIT
239/* Signed/unsigned 64 bit multiplication. */
240int64_t lj_carith_mul64(int64_t a, int64_t b)
241{
242 return a * b;
243}
244#endif
245
246/* Unsigned 64 bit division. */
247uint64_t lj_carith_divu64(uint64_t a, uint64_t b)
248{
249 if (b == 0) return U64x(80000000,00000000);
250 return a / b;
251}
252
253/* Signed 64 bit division. */
254int64_t lj_carith_divi64(int64_t a, int64_t b)
255{
256 if (b == 0 || (a == (int64_t)U64x(80000000,00000000) && b == -1))
257 return U64x(80000000,00000000);
258 return a / b;
259}
260
261/* Unsigned 64 bit modulo. */
262uint64_t lj_carith_modu64(uint64_t a, uint64_t b)
263{
264 if (b == 0) return U64x(80000000,00000000);
265 return a % b;
266}
267
268/* Signed 64 bit modulo. */
269int64_t lj_carith_modi64(int64_t a, int64_t b)
270{
271 if (b == 0) return U64x(80000000,00000000);
272 if (a == (int64_t)U64x(80000000,00000000) && b == -1) return 0;
273 return a % b;
274}
275
276/* Unsigned 64 bit x^k. */
277uint64_t lj_carith_powu64(uint64_t x, uint64_t k)
278{
279 uint64_t y;
280 if (k == 0)
281 return 1;
282 for (; (k & 1) == 0; k >>= 1) x *= x;
283 y = x;
284 if ((k >>= 1) != 0) {
285 for (;;) {
286 x *= x;
287 if (k == 1) break;
288 if (k & 1) y *= x;
289 k >>= 1;
290 }
291 y *= x;
292 }
293 return y;
294}
295
296/* Signed 64 bit x^k. */
297int64_t lj_carith_powi64(int64_t x, int64_t k)
298{
299 if (k == 0)
300 return 1;
301 if (k < 0) {
302 if (x == 0)
303 return U64x(7fffffff,ffffffff);
304 else if (x == 1)
305 return 1;
306 else if (x == -1)
307 return (k & 1) ? -1 : 1;
308 else
309 return 0;
310 }
311 return (int64_t)lj_carith_powu64((uint64_t)x, (uint64_t)k);
312}
313
314#endif
diff --git a/libraries/luajit-2.0/src/lj_carith.h b/libraries/luajit-2.0/src/lj_carith.h
new file mode 100644
index 0000000..c39594a
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_carith.h
@@ -0,0 +1,27 @@
1/*
2** C data arithmetic.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CARITH_H
7#define _LJ_CARITH_H
8
9#include "lj_obj.h"
10
11#if LJ_HASFFI
12
13LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
14
15#if LJ_32 && LJ_HASJIT
16LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k);
17#endif
18LJ_FUNC uint64_t lj_carith_divu64(uint64_t a, uint64_t b);
19LJ_FUNC int64_t lj_carith_divi64(int64_t a, int64_t b);
20LJ_FUNC uint64_t lj_carith_modu64(uint64_t a, uint64_t b);
21LJ_FUNC int64_t lj_carith_modi64(int64_t a, int64_t b);
22LJ_FUNC uint64_t lj_carith_powu64(uint64_t x, uint64_t k);
23LJ_FUNC int64_t lj_carith_powi64(int64_t x, int64_t k);
24
25#endif
26
27#endif
diff --git a/libraries/luajit-2.0/src/lj_ccall.c b/libraries/luajit-2.0/src/lj_ccall.c
new file mode 100644
index 0000000..5ed1bf5
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ccall.c
@@ -0,0 +1,675 @@
1/*
2** FFI C call handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "lj_obj.h"
7
8#if LJ_HASFFI
9
10#include "lj_gc.h"
11#include "lj_err.h"
12#include "lj_str.h"
13#include "lj_tab.h"
14#include "lj_ctype.h"
15#include "lj_cconv.h"
16#include "lj_cdata.h"
17#include "lj_ccall.h"
18#include "lj_trace.h"
19
20/* Target-specific handling of register arguments. */
21#if LJ_TARGET_X86
22/* -- x86 calling conventions --------------------------------------------- */
23
24#if LJ_ABI_WIN
25
26#define CCALL_HANDLE_STRUCTRET \
27 /* Return structs bigger than 8 by reference (on stack only). */ \
28 cc->retref = (sz > 8); \
29 if (cc->retref) cc->stack[nsp++] = (GPRArg)dp;
30
31#define CCALL_HANDLE_COMPLEXRET CCALL_HANDLE_STRUCTRET
32
33#else
34
35#define CCALL_HANDLE_STRUCTRET \
36 cc->retref = 1; /* Return all structs by reference (in reg or on stack). */ \
37 if (ngpr < maxgpr) \
38 cc->gpr[ngpr++] = (GPRArg)dp; \
39 else \
40 cc->stack[nsp++] = (GPRArg)dp;
41
42#define CCALL_HANDLE_COMPLEXRET \
43 /* Return complex float in GPRs and complex double by reference. */ \
44 cc->retref = (sz > 8); \
45 if (cc->retref) { \
46 if (ngpr < maxgpr) \
47 cc->gpr[ngpr++] = (GPRArg)dp; \
48 else \
49 cc->stack[nsp++] = (GPRArg)dp; \
50 }
51
52#endif
53
54#define CCALL_HANDLE_COMPLEXRET2 \
55 if (!cc->retref) \
56 *(int64_t *)dp = *(int64_t *)sp; /* Copy complex float from GPRs. */
57
58#define CCALL_HANDLE_STRUCTARG \
59 ngpr = maxgpr; /* Pass all structs by value on the stack. */
60
61#define CCALL_HANDLE_COMPLEXARG \
62 isfp = 1; /* Pass complex by value on stack. */
63
64#define CCALL_HANDLE_REGARG \
65 if (!isfp) { /* Only non-FP values may be passed in registers. */ \
66 if (n > 1) { /* Anything > 32 bit is passed on the stack. */ \
67 if (!LJ_ABI_WIN) ngpr = maxgpr; /* Prevent reordering. */ \
68 } else if (ngpr + 1 <= maxgpr) { \
69 dp = &cc->gpr[ngpr]; \
70 ngpr += n; \
71 goto done; \
72 } \
73 }
74
75#elif LJ_TARGET_X64 && LJ_ABI_WIN
76/* -- Windows/x64 calling conventions ------------------------------------- */
77
78#define CCALL_HANDLE_STRUCTRET \
79 /* Return structs of size 1, 2, 4 or 8 in a GPR. */ \
80 cc->retref = !(sz == 1 || sz == 2 || sz == 4 || sz == 8); \
81 if (cc->retref) cc->gpr[ngpr++] = (GPRArg)dp;
82
83#define CCALL_HANDLE_COMPLEXRET CCALL_HANDLE_STRUCTRET
84
85#define CCALL_HANDLE_COMPLEXRET2 \
86 if (!cc->retref) \
87 *(int64_t *)dp = *(int64_t *)sp; /* Copy complex float from GPRs. */
88
89#define CCALL_HANDLE_STRUCTARG \
90 /* Pass structs of size 1, 2, 4 or 8 in a GPR by value. */ \
91 if (!(sz == 1 || sz == 2 || sz == 4 || sz == 8)) { \
92 rp = cdataptr(lj_cdata_new(cts, did, sz)); \
93 sz = CTSIZE_PTR; /* Pass all other structs by reference. */ \
94 }
95
96#define CCALL_HANDLE_COMPLEXARG \
97 /* Pass complex float in a GPR and complex double by reference. */ \
98 if (sz != 2*sizeof(float)) { \
99 rp = cdataptr(lj_cdata_new(cts, did, sz)); \
100 sz = CTSIZE_PTR; \
101 }
102
103/* Windows/x64 argument registers are strictly positional (use ngpr). */
104#define CCALL_HANDLE_REGARG \
105 if (isfp) { \
106 if (ngpr < 4) { dp = &cc->fpr[ngpr++]; nfpr = ngpr; goto done; } \
107 } else { \
108 if (ngpr < 4) { dp = &cc->gpr[ngpr++]; goto done; } \
109 }
110
111#elif LJ_TARGET_X64
112/* -- POSIX/x64 calling conventions --------------------------------------- */
113
114#define CCALL_HANDLE_STRUCTRET \
115 int rcl[2]; rcl[0] = rcl[1] = 0; \
116 if (ccall_classify_struct(cts, ctr, rcl, 0)) { \
117 cc->retref = 1; /* Return struct by reference. */ \
118 cc->gpr[ngpr++] = (GPRArg)dp; \
119 } else { \
120 cc->retref = 0; /* Return small structs in registers. */ \
121 }
122
123#define CCALL_HANDLE_STRUCTRET2 \
124 int rcl[2]; rcl[0] = rcl[1] = 0; \
125 ccall_classify_struct(cts, ctr, rcl, 0); \
126 ccall_struct_ret(cc, rcl, dp, ctr->size);
127
128#define CCALL_HANDLE_COMPLEXRET \
129 /* Complex values are returned in one or two FPRs. */ \
130 cc->retref = 0;
131
132#define CCALL_HANDLE_COMPLEXRET2 \
133 if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPR. */ \
134 *(int64_t *)dp = cc->fpr[0].l[0]; \
135 } else { /* Copy non-contiguous complex double from FPRs. */ \
136 ((int64_t *)dp)[0] = cc->fpr[0].l[0]; \
137 ((int64_t *)dp)[1] = cc->fpr[1].l[0]; \
138 }
139
140#define CCALL_HANDLE_STRUCTARG \
141 int rcl[2]; rcl[0] = rcl[1] = 0; \
142 if (!ccall_classify_struct(cts, d, rcl, 0)) { \
143 cc->nsp = nsp; cc->ngpr = ngpr; cc->nfpr = nfpr; \
144 if (ccall_struct_arg(cc, cts, d, rcl, o, narg)) goto err_nyi; \
145 nsp = cc->nsp; ngpr = cc->ngpr; nfpr = cc->nfpr; \
146 continue; \
147 } /* Pass all other structs by value on stack. */
148
149#define CCALL_HANDLE_COMPLEXARG \
150 isfp = 2; /* Pass complex in FPRs or on stack. Needs postprocessing. */
151
152#define CCALL_HANDLE_REGARG \
153 if (isfp) { /* Try to pass argument in FPRs. */ \
154 if (nfpr + n <= CCALL_NARG_FPR) { \
155 dp = &cc->fpr[nfpr]; \
156 nfpr += n; \
157 goto done; \
158 } \
159 } else { /* Try to pass argument in GPRs. */ \
160 /* Note that reordering is explicitly allowed in the x64 ABI. */ \
161 if (n <= 2 && ngpr + n <= maxgpr) { \
162 dp = &cc->gpr[ngpr]; \
163 ngpr += n; \
164 goto done; \
165 } \
166 }
167
168#elif LJ_TARGET_ARM
169/* -- ARM calling conventions --------------------------------------------- */
170
171#define CCALL_HANDLE_STRUCTRET \
172 /* Return structs of size <= 4 in a GPR. */ \
173 cc->retref = !(sz <= 4); \
174 if (cc->retref) cc->gpr[ngpr++] = (GPRArg)dp;
175
176#define CCALL_HANDLE_COMPLEXRET \
177 cc->retref = 1; /* Return all complex values by reference. */ \
178 cc->gpr[ngpr++] = (GPRArg)dp;
179
180#define CCALL_HANDLE_COMPLEXRET2 \
181 UNUSED(dp); /* Nothing to do. */
182
183#define CCALL_HANDLE_STRUCTARG \
184 /* Pass all structs by value in registers and/or on the stack. */
185
186#define CCALL_HANDLE_COMPLEXARG \
187 /* Pass complex by value in 2 or 4 GPRs. */
188
189/* ARM has a softfp ABI. */
190#define CCALL_HANDLE_REGARG \
191 if ((d->info & CTF_ALIGN) > CTALIGN_PTR) { \
192 if (ngpr < maxgpr) \
193 ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \
194 else \
195 nsp = (nsp + 1u) & ~1u; /* Align argument on stack. */ \
196 } \
197 if (ngpr < maxgpr) { \
198 dp = &cc->gpr[ngpr]; \
199 if (ngpr + n > maxgpr) { \
200 nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \
201 if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \
202 ngpr = maxgpr; \
203 } else { \
204 ngpr += n; \
205 } \
206 goto done; \
207 }
208
209#elif LJ_TARGET_PPC
210/* -- PPC calling conventions --------------------------------------------- */
211
212#define CCALL_HANDLE_STRUCTRET \
213 cc->retref = 1; /* Return all structs by reference. */ \
214 cc->gpr[ngpr++] = (GPRArg)dp;
215
216#define CCALL_HANDLE_COMPLEXRET \
217 /* Complex values are returned in 2 or 4 GPRs. */ \
218 cc->retref = 0;
219
220#define CCALL_HANDLE_COMPLEXRET2 \
221 memcpy(dp, sp, ctr->size); /* Copy complex from GPRs. */
222
223#define CCALL_HANDLE_STRUCTARG \
224 rp = cdataptr(lj_cdata_new(cts, did, sz)); \
225 sz = CTSIZE_PTR; /* Pass all structs by reference. */
226
227#define CCALL_HANDLE_COMPLEXARG \
228 /* Pass complex by value in 2 or 4 GPRs. */
229
230#define CCALL_HANDLE_REGARG \
231 if (isfp) { /* Try to pass argument in FPRs. */ \
232 if (nfpr + 1 <= CCALL_NARG_FPR) { \
233 dp = &cc->fpr[nfpr]; \
234 nfpr += 1; \
235 d = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \
236 goto done; \
237 } \
238 } else { /* Try to pass argument in GPRs. */ \
239 if (n > 1) { \
240 lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
241 if (ctype_isinteger(d->info)) \
242 ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
243 else if (ngpr + n > maxgpr) \
244 ngpr = maxgpr; /* Prevent reordering. */ \
245 } \
246 if (ngpr + n <= maxgpr) { \
247 dp = &cc->gpr[ngpr]; \
248 ngpr += n; \
249 goto done; \
250 } \
251 }
252
253#define CCALL_HANDLE_RET \
254 if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
255 ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */
256
257#elif LJ_TARGET_PPCSPE
258/* -- PPC/SPE calling conventions ----------------------------------------- */
259
260#define CCALL_HANDLE_STRUCTRET \
261 cc->retref = 1; /* Return all structs by reference. */ \
262 cc->gpr[ngpr++] = (GPRArg)dp;
263
264#define CCALL_HANDLE_COMPLEXRET \
265 /* Complex values are returned in 2 or 4 GPRs. */ \
266 cc->retref = 0;
267
268#define CCALL_HANDLE_COMPLEXRET2 \
269 memcpy(dp, sp, ctr->size); /* Copy complex from GPRs. */
270
271#define CCALL_HANDLE_STRUCTARG \
272 rp = cdataptr(lj_cdata_new(cts, did, sz)); \
273 sz = CTSIZE_PTR; /* Pass all structs by reference. */
274
275#define CCALL_HANDLE_COMPLEXARG \
276 /* Pass complex by value in 2 or 4 GPRs. */
277
278/* PPC/SPE has a softfp ABI. */
279#define CCALL_HANDLE_REGARG \
280 if (n > 1) { /* Doesn't fit in a single GPR? */ \
281 lua_assert(n == 2 || n == 4); /* int64_t, double or complex (float). */ \
282 if (n == 2) \
283 ngpr = (ngpr + 1u) & ~1u; /* Only align 64 bit value to regpair. */ \
284 else if (ngpr + n > maxgpr) \
285 ngpr = maxgpr; /* Prevent reordering. */ \
286 } \
287 if (ngpr + n <= maxgpr) { \
288 dp = &cc->gpr[ngpr]; \
289 ngpr += n; \
290 goto done; \
291 }
292
293#else
294#error "Missing calling convention definitions for this architecture"
295#endif
296
297#ifndef CCALL_HANDLE_STRUCTRET2
298#define CCALL_HANDLE_STRUCTRET2 \
299 memcpy(dp, sp, ctr->size); /* Copy struct return value from GPRs. */
300#endif
301
302/* -- x64 struct classification ------------------------------------------- */
303
304#if LJ_TARGET_X64 && !LJ_ABI_WIN
305
306/* Register classes for x64 struct classification. */
307#define CCALL_RCL_INT 1
308#define CCALL_RCL_SSE 2
309#define CCALL_RCL_MEM 4
310/* NYI: classify vectors. */
311
312static int ccall_classify_struct(CTState *cts, CType *ct, int *rcl, CTSize ofs);
313
314/* Classify a C type. */
315static void ccall_classify_ct(CTState *cts, CType *ct, int *rcl, CTSize ofs)
316{
317 if (ctype_isarray(ct->info)) {
318 CType *cct = ctype_rawchild(cts, ct);
319 CTSize eofs, esz = cct->size, asz = ct->size;
320 for (eofs = 0; eofs < asz; eofs += esz)
321 ccall_classify_ct(cts, cct, rcl, ofs+eofs);
322 } else if (ctype_isstruct(ct->info)) {
323 ccall_classify_struct(cts, ct, rcl, ofs);
324 } else {
325 int cl = ctype_isfp(ct->info) ? CCALL_RCL_SSE : CCALL_RCL_INT;
326 lua_assert(ctype_hassize(ct->info));
327 if ((ofs & (ct->size-1))) cl = CCALL_RCL_MEM; /* Unaligned. */
328 rcl[(ofs >= 8)] |= cl;
329 }
330}
331
332/* Recursively classify a struct based on its fields. */
333static int ccall_classify_struct(CTState *cts, CType *ct, int *rcl, CTSize ofs)
334{
335 if (ct->size > 16) return CCALL_RCL_MEM; /* Too big, gets memory class. */
336 while (ct->sib) {
337 CTSize fofs;
338 ct = ctype_get(cts, ct->sib);
339 fofs = ofs+ct->size;
340 if (ctype_isfield(ct->info))
341 ccall_classify_ct(cts, ctype_rawchild(cts, ct), rcl, fofs);
342 else if (ctype_isbitfield(ct->info))
343 rcl[(fofs >= 8)] |= CCALL_RCL_INT; /* NYI: unaligned bitfields? */
344 else if (ctype_isxattrib(ct->info, CTA_SUBTYPE))
345 ccall_classify_struct(cts, ctype_child(cts, ct), rcl, fofs);
346 }
347 return ((rcl[0]|rcl[1]) & CCALL_RCL_MEM); /* Memory class? */
348}
349
350/* Try to split up a small struct into registers. */
351static int ccall_struct_reg(CCallState *cc, GPRArg *dp, int *rcl)
352{
353 MSize ngpr = cc->ngpr, nfpr = cc->nfpr;
354 uint32_t i;
355 for (i = 0; i < 2; i++) {
356 lua_assert(!(rcl[i] & CCALL_RCL_MEM));
357 if ((rcl[i] & CCALL_RCL_INT)) { /* Integer class takes precedence. */
358 if (ngpr >= CCALL_NARG_GPR) return 1; /* Register overflow. */
359 cc->gpr[ngpr++] = dp[i];
360 } else if ((rcl[i] & CCALL_RCL_SSE)) {
361 if (nfpr >= CCALL_NARG_FPR) return 1; /* Register overflow. */
362 cc->fpr[nfpr++].l[0] = dp[i];
363 }
364 }
365 cc->ngpr = ngpr; cc->nfpr = nfpr;
366 return 0; /* Ok. */
367}
368
369/* Pass a small struct argument. */
370static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl,
371 TValue *o, int narg)
372{
373 GPRArg dp[2];
374 dp[0] = dp[1] = 0;
375 /* Convert to temp. struct. */
376 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
377 if (ccall_struct_reg(cc, dp, rcl)) { /* Register overflow? Pass on stack. */
378 MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1;
379 if (nsp + n > CCALL_MAXSTACK) return 1; /* Too many arguments. */
380 cc->nsp = nsp + n;
381 memcpy(&cc->stack[nsp], dp, n*CTSIZE_PTR);
382 }
383 return 0; /* Ok. */
384}
385
386/* Combine returned small struct. */
387static void ccall_struct_ret(CCallState *cc, int *rcl, uint8_t *dp, CTSize sz)
388{
389 GPRArg sp[2];
390 MSize ngpr = 0, nfpr = 0;
391 uint32_t i;
392 for (i = 0; i < 2; i++) {
393 if ((rcl[i] & CCALL_RCL_INT)) { /* Integer class takes precedence. */
394 sp[i] = cc->gpr[ngpr++];
395 } else if ((rcl[i] & CCALL_RCL_SSE)) {
396 sp[i] = cc->fpr[nfpr++].l[0];
397 }
398 }
399 memcpy(dp, sp, sz);
400}
401#endif
402
403/* -- Common C call handling ---------------------------------------------- */
404
405/* Infer the destination CTypeID for a vararg argument. */
406CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
407{
408 if (tvisnumber(o)) {
409 return CTID_DOUBLE;
410 } else if (tviscdata(o)) {
411 CTypeID id = cdataV(o)->typeid;
412 CType *s = ctype_get(cts, id);
413 if (ctype_isrefarray(s->info)) {
414 return lj_ctype_intern(cts,
415 CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(s->info)), CTSIZE_PTR);
416 } else if (ctype_isstruct(s->info) || ctype_isfunc(s->info)) {
417 /* NYI: how to pass a struct by value in a vararg argument? */
418 return lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR);
419 } else if (ctype_isfp(s->info) && s->size == sizeof(float)) {
420 return CTID_DOUBLE;
421 } else {
422 return id;
423 }
424 } else if (tvisstr(o)) {
425 return CTID_P_CCHAR;
426 } else if (tvisbool(o)) {
427 return CTID_BOOL;
428 } else {
429 return CTID_P_VOID;
430 }
431}
432
433/* Setup arguments for C call. */
434static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
435 CCallState *cc)
436{
437 int gcsteps = 0;
438 TValue *o, *top = L->top;
439 CTypeID fid;
440 CType *ctr;
441 MSize maxgpr, ngpr = 0, nsp = 0, narg;
442#if CCALL_NARG_FPR
443 MSize nfpr = 0;
444#endif
445
446 /* Clear unused regs to get some determinism in case of misdeclaration. */
447 memset(cc->gpr, 0, sizeof(cc->gpr));
448#if CCALL_NUM_FPR
449 memset(cc->fpr, 0, sizeof(cc->fpr));
450#endif
451
452#if LJ_TARGET_X86
453 /* x86 has several different calling conventions. */
454 cc->resx87 = 0;
455 switch (ctype_cconv(ct->info)) {
456 case CTCC_FASTCALL: maxgpr = 2; break;
457 case CTCC_THISCALL: maxgpr = 1; break;
458 default: maxgpr = 0; break;
459 }
460#else
461 maxgpr = CCALL_NARG_GPR;
462#endif
463
464 /* Perform required setup for some result types. */
465 ctr = ctype_rawchild(cts, ct);
466 if (ctype_isvector(ctr->info)) {
467 if (!(CCALL_VECTOR_REG && (ctr->size == 8 || ctr->size == 16)))
468 goto err_nyi;
469 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) {
470 /* Preallocate cdata object and anchor it after arguments. */
471 CTSize sz = ctr->size;
472 GCcdata *cd = lj_cdata_new(cts, ctype_cid(ct->info), sz);
473 void *dp = cdataptr(cd);
474 setcdataV(L, L->top++, cd);
475 if (ctype_isstruct(ctr->info)) {
476 CCALL_HANDLE_STRUCTRET
477 } else {
478 CCALL_HANDLE_COMPLEXRET
479 }
480#if LJ_TARGET_X86
481 } else if (ctype_isfp(ctr->info)) {
482 cc->resx87 = ctr->size == sizeof(float) ? 1 : 2;
483#endif
484 }
485
486 /* Skip initial attributes. */
487 fid = ct->sib;
488 while (fid) {
489 CType *ctf = ctype_get(cts, fid);
490 if (!ctype_isattrib(ctf->info)) break;
491 fid = ctf->sib;
492 }
493
494 /* Walk through all passed arguments. */
495 for (o = L->base+1, narg = 1; o < top; o++, narg++) {
496 CTypeID did;
497 CType *d;
498 CTSize sz;
499 MSize n, isfp = 0, isva = 0;
500 void *dp, *rp = NULL;
501
502 if (fid) { /* Get argument type from field. */
503 CType *ctf = ctype_get(cts, fid);
504 fid = ctf->sib;
505 lua_assert(ctype_isfield(ctf->info));
506 did = ctype_cid(ctf->info);
507 } else {
508 if (!(ct->info & CTF_VARARG))
509 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */
510 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
511 isva = 1;
512 }
513 d = ctype_raw(cts, did);
514 sz = d->size;
515
516 /* Find out how (by value/ref) and where (GPR/FPR) to pass an argument. */
517 if (ctype_isnum(d->info)) {
518 if (sz > 8) goto err_nyi;
519 if ((d->info & CTF_FP))
520 isfp = 1;
521 } else if (ctype_isvector(d->info)) {
522 if (CCALL_VECTOR_REG && (sz == 8 || sz == 16))
523 isfp = 1;
524 else
525 goto err_nyi;
526 } else if (ctype_isstruct(d->info)) {
527 CCALL_HANDLE_STRUCTARG
528 } else if (ctype_iscomplex(d->info)) {
529 CCALL_HANDLE_COMPLEXARG
530 } else {
531 sz = CTSIZE_PTR;
532 }
533 sz = (sz + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1);
534 n = sz / CTSIZE_PTR; /* Number of GPRs or stack slots needed. */
535
536 CCALL_HANDLE_REGARG /* Handle register arguments. */
537
538 /* Otherwise pass argument on stack. */
539 if (CCALL_ALIGN_STACKARG && !rp && (d->info & CTF_ALIGN) > CTALIGN_PTR) {
540 MSize align = (1u << ctype_align(d->info-CTALIGN_PTR)) -1;
541 nsp = (nsp + align) & ~align; /* Align argument on stack. */
542 }
543 if (nsp + n > CCALL_MAXSTACK) { /* Too many arguments. */
544 err_nyi:
545 lj_err_caller(L, LJ_ERR_FFI_NYICALL);
546 }
547 dp = &cc->stack[nsp];
548 nsp += n;
549 isva = 0;
550
551 done:
552 if (rp) { /* Pass by reference. */
553 gcsteps++;
554 *(void **)dp = rp;
555 dp = rp;
556 }
557 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
558 /* Extend passed integers to 32 bits at least. */
559 if (ctype_isinteger_or_bool(d->info) && d->size < 4) {
560 if (d->info & CTF_UNSIGNED)
561 *(uint32_t *)dp = d->size == 1 ? (uint32_t)*(uint8_t *)dp :
562 (uint32_t)*(uint16_t *)dp;
563 else
564 *(int32_t *)dp = d->size == 1 ? (int32_t)*(int8_t *)dp :
565 (int32_t)*(int16_t *)dp;
566 }
567#if LJ_TARGET_X64 && LJ_ABI_WIN
568 if (isva) { /* Windows/x64 mirrors varargs in both register sets. */
569 if (nfpr == ngpr)
570 cc->gpr[ngpr-1] = cc->fpr[ngpr-1].l[0];
571 else
572 cc->fpr[ngpr-1].l[0] = cc->gpr[ngpr-1];
573 }
574#else
575 UNUSED(isva);
576#endif
577#if LJ_TARGET_X64 && !LJ_ABI_WIN
578 if (isfp == 2 && n == 2 && (uint8_t *)dp == (uint8_t *)&cc->fpr[nfpr-2]) {
579 cc->fpr[nfpr-1].d[0] = cc->fpr[nfpr-2].d[1]; /* Split complex double. */
580 cc->fpr[nfpr-2].d[1] = 0;
581 }
582#else
583 UNUSED(isfp);
584#endif
585 }
586 if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */
587
588#if LJ_TARGET_X64 || LJ_TARGET_PPC
589 cc->nfpr = nfpr; /* Required for vararg functions. */
590#endif
591 cc->nsp = nsp;
592 cc->spadj = (CCALL_SPS_FREE + CCALL_SPS_EXTRA)*CTSIZE_PTR;
593 if (nsp > CCALL_SPS_FREE)
594 cc->spadj += (((nsp-CCALL_SPS_FREE)*CTSIZE_PTR + 15u) & ~15u);
595 return gcsteps;
596}
597
598/* Get results from C call. */
599static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
600 CCallState *cc, int *ret)
601{
602 CType *ctr = ctype_rawchild(cts, ct);
603 uint8_t *sp = (uint8_t *)&cc->gpr[0];
604 if (ctype_isvoid(ctr->info)) {
605 *ret = 0; /* Zero results. */
606 return 0; /* No additional GC step. */
607 }
608 *ret = 1; /* One result. */
609 if (ctype_isstruct(ctr->info)) {
610 /* Return cdata object which is already on top of stack. */
611 if (!cc->retref) {
612 void *dp = cdataptr(cdataV(L->top-1)); /* Use preallocated object. */
613 CCALL_HANDLE_STRUCTRET2
614 }
615 return 1; /* One GC step. */
616 }
617 if (ctype_iscomplex(ctr->info)) {
618 /* Return cdata object which is already on top of stack. */
619 void *dp = cdataptr(cdataV(L->top-1)); /* Use preallocated object. */
620 CCALL_HANDLE_COMPLEXRET2
621 return 1; /* One GC step. */
622 }
623 if (LJ_BE && ctype_isinteger_or_bool(ctr->info) && ctr->size < CTSIZE_PTR)
624 sp += (CTSIZE_PTR - ctr->size);
625#ifdef CCALL_HANDLE_RET
626 CCALL_HANDLE_RET
627#endif
628#if CCALL_NUM_FPR
629 if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
630 sp = (uint8_t *)&cc->fpr[0];
631#endif
632 /* No reference types end up here, so there's no need for the CTypeID. */
633 lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info)));
634 if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr);
635 return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, sp);
636}
637
638/* Call C function. */
639int lj_ccall_func(lua_State *L, GCcdata *cd)
640{
641 CTState *cts = ctype_cts(L);
642 CType *ct = ctype_raw(cts, cd->typeid);
643 CTSize sz = CTSIZE_PTR;
644 if (ctype_isptr(ct->info)) {
645 sz = ct->size;
646 ct = ctype_rawchild(cts, ct);
647 }
648 if (ctype_isfunc(ct->info)) {
649 CCallState cc;
650 int gcsteps, ret;
651 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz);
652 gcsteps = ccall_set_args(L, cts, ct, &cc);
653 cts->cb.slot = ~0u;
654 lj_vm_ffi_call(&cc);
655 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */
656 TValue tv;
657 setlightudV(&tv, (void *)cc.func);
658 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1);
659 }
660 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret);
661#if LJ_TARGET_X86 && LJ_ABI_WIN
662 /* Automatically detect __stdcall and fix up C function declaration. */
663 if (cc.spadj && ctype_cconv(ct->info) == CTCC_CDECL) {
664 CTF_INSERT(ct->info, CCONV, CTCC_STDCALL);
665 lj_trace_abort(G(L));
666 }
667#endif
668 while (gcsteps-- > 0)
669 lj_gc_check(L);
670 return ret;
671 }
672 return -1; /* Not a function. */
673}
674
675#endif
diff --git a/libraries/luajit-2.0/src/lj_ccall.h b/libraries/luajit-2.0/src/lj_ccall.h
new file mode 100644
index 0000000..0641625
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ccall.h
@@ -0,0 +1,143 @@
1/*
2** FFI C call handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CCALL_H
7#define _LJ_CCALL_H
8
9#include "lj_obj.h"
10#include "lj_ctype.h"
11
12#if LJ_HASFFI
13
14/* -- C calling conventions ----------------------------------------------- */
15
16#if LJ_TARGET_X86ORX64
17
18#if LJ_TARGET_X86
19#define CCALL_NARG_GPR 2 /* For fastcall arguments. */
20#define CCALL_NARG_FPR 0
21#define CCALL_NRET_GPR 2
22#define CCALL_NRET_FPR 1 /* For FP results on x87 stack. */
23#define CCALL_ALIGN_STACKARG 0 /* Don't align argument on stack. */
24#elif LJ_ABI_WIN
25#define CCALL_NARG_GPR 4
26#define CCALL_NARG_FPR 4
27#define CCALL_NRET_GPR 1
28#define CCALL_NRET_FPR 1
29#define CCALL_SPS_EXTRA 4
30#else
31#define CCALL_NARG_GPR 6
32#define CCALL_NARG_FPR 8
33#define CCALL_NRET_GPR 2
34#define CCALL_NRET_FPR 2
35#define CCALL_VECTOR_REG 1 /* Pass vectors in registers. */
36#endif
37
38#define CCALL_SPS_FREE 1
39
40typedef LJ_ALIGN(16) union FPRArg {
41 double d[2];
42 float f[4];
43 uint8_t b[16];
44 uint16_t s[8];
45 int i[4];
46 int64_t l[2];
47} FPRArg;
48
49typedef intptr_t GPRArg;
50
51#elif LJ_TARGET_ARM
52
53#define CCALL_NARG_GPR 4
54#define CCALL_NARG_FPR 0
55#define CCALL_NRET_GPR 2 /* For softfp double. */
56#define CCALL_NRET_FPR 0
57#define CCALL_SPS_FREE 0
58
59typedef intptr_t GPRArg;
60
61#elif LJ_TARGET_PPC
62
63#define CCALL_NARG_GPR 8
64#define CCALL_NARG_FPR 8
65#define CCALL_NRET_GPR 4 /* For complex double. */
66#define CCALL_NRET_FPR 1
67#define CCALL_SPS_EXTRA 4
68#define CCALL_SPS_FREE 0
69
70typedef intptr_t GPRArg;
71typedef double FPRArg;
72
73#elif LJ_TARGET_PPCSPE
74
75#define CCALL_NARG_GPR 8
76#define CCALL_NARG_FPR 0
77#define CCALL_NRET_GPR 4 /* For softfp complex double. */
78#define CCALL_NRET_FPR 0
79#define CCALL_SPS_FREE 0 /* NYI */
80
81typedef intptr_t GPRArg;
82
83#else
84#error "Missing calling convention definitions for this architecture"
85#endif
86
87#ifndef CCALL_SPS_EXTRA
88#define CCALL_SPS_EXTRA 0
89#endif
90#ifndef CCALL_VECTOR_REG
91#define CCALL_VECTOR_REG 0
92#endif
93#ifndef CCALL_ALIGN_STACKARG
94#define CCALL_ALIGN_STACKARG 1
95#endif
96
97#define CCALL_NUM_GPR \
98 (CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR)
99#define CCALL_NUM_FPR \
100 (CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR)
101
102/* Check against constants in lj_ctype.h. */
103LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR);
104LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR);
105
106#define CCALL_MAXSTACK 32
107
108/* -- C call state -------------------------------------------------------- */
109
110typedef struct CCallState {
111 void (*func)(void); /* Pointer to called function. */
112 uint32_t spadj; /* Stack pointer adjustment. */
113 uint8_t nsp; /* Number of stack slots. */
114 uint8_t retref; /* Return value by reference. */
115#if LJ_TARGET_X64
116 uint8_t ngpr; /* Number of arguments in GPRs. */
117 uint8_t nfpr; /* Number of arguments in FPRs. */
118#elif LJ_TARGET_X86
119 uint8_t resx87; /* Result on x87 stack: 1:float, 2:double. */
120#elif LJ_TARGET_PPC
121 uint8_t nfpr; /* Number of arguments in FPRs. */
122#endif
123#if CCALL_NUM_FPR
124#if LJ_32
125 int32_t align1;
126#endif
127 FPRArg fpr[CCALL_NUM_FPR]; /* Arguments/results in FPRs. */
128#endif
129 GPRArg gpr[CCALL_NUM_GPR]; /* Arguments/results in GPRs. */
130 GPRArg stack[CCALL_MAXSTACK]; /* Stack slots. */
131} CCallState;
132
133/* -- C call handling ----------------------------------------------------- */
134
135/* Really belongs to lj_vm.h. */
136LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);
137
138LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
139LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);
140
141#endif
142
143#endif
diff --git a/libraries/luajit-2.0/src/lj_ccallback.c b/libraries/luajit-2.0/src/lj_ccallback.c
new file mode 100644
index 0000000..f347458
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ccallback.c
@@ -0,0 +1,544 @@
1/*
2** FFI C callback handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "lj_obj.h"
7
8#if LJ_HASFFI
9
10#include "lj_gc.h"
11#include "lj_err.h"
12#include "lj_tab.h"
13#include "lj_state.h"
14#include "lj_frame.h"
15#include "lj_ctype.h"
16#include "lj_cconv.h"
17#include "lj_ccall.h"
18#include "lj_ccallback.h"
19#include "lj_target.h"
20#include "lj_mcode.h"
21#include "lj_vm.h"
22
23/* -- Target-specific handling of callback slots -------------------------- */
24
25#define CALLBACK_MCODE_SIZE (LJ_PAGESIZE * LJ_NUM_CBPAGE)
26
27#if LJ_TARGET_X86ORX64
28
29#define CALLBACK_MCODE_HEAD (LJ_64 ? 8 : 0)
30#define CALLBACK_MCODE_GROUP (-2+1+2+5+(LJ_64 ? 6 : 5))
31
32#define CALLBACK_SLOT2OFS(slot) \
33 (CALLBACK_MCODE_HEAD + CALLBACK_MCODE_GROUP*((slot)/32) + 4*(slot))
34
35static MSize CALLBACK_OFS2SLOT(MSize ofs)
36{
37 MSize group;
38 ofs -= CALLBACK_MCODE_HEAD;
39 group = ofs / (32*4 + CALLBACK_MCODE_GROUP);
40 return (ofs % (32*4 + CALLBACK_MCODE_GROUP))/4 + group*32;
41}
42
43#define CALLBACK_MAX_SLOT \
44 (((CALLBACK_MCODE_SIZE-CALLBACK_MCODE_HEAD)/(CALLBACK_MCODE_GROUP+4*32))*32)
45
46#elif LJ_TARGET_ARM
47
48#define CALLBACK_MCODE_HEAD 32
49#define CALLBACK_SLOT2OFS(slot) (CALLBACK_MCODE_HEAD + 8*(slot))
50#define CALLBACK_OFS2SLOT(ofs) (((ofs)-CALLBACK_MCODE_HEAD)/8)
51#define CALLBACK_MAX_SLOT (CALLBACK_OFS2SLOT(CALLBACK_MCODE_SIZE))
52
53#elif LJ_TARGET_PPC
54
55#define CALLBACK_MCODE_HEAD 24
56#define CALLBACK_SLOT2OFS(slot) (CALLBACK_MCODE_HEAD + 8*(slot))
57#define CALLBACK_OFS2SLOT(ofs) (((ofs)-CALLBACK_MCODE_HEAD)/8)
58#define CALLBACK_MAX_SLOT (CALLBACK_OFS2SLOT(CALLBACK_MCODE_SIZE))
59
60#else
61
62/* Missing support for this architecture. */
63#define CALLBACK_SLOT2OFS(slot) (0*(slot))
64#define CALLBACK_OFS2SLOT(ofs) (0*(ofs))
65#define CALLBACK_MAX_SLOT 0
66
67#endif
68
69/* Convert callback slot number to callback function pointer. */
70static void *callback_slot2ptr(CTState *cts, MSize slot)
71{
72 return (uint8_t *)cts->cb.mcode + CALLBACK_SLOT2OFS(slot);
73}
74
75/* Convert callback function pointer to slot number. */
76MSize lj_ccallback_ptr2slot(CTState *cts, void *p)
77{
78 uintptr_t ofs = (uintptr_t)((uint8_t *)p -(uint8_t *)cts->cb.mcode);
79 if (ofs < CALLBACK_MCODE_SIZE) {
80 MSize slot = CALLBACK_OFS2SLOT((MSize)ofs);
81 if (CALLBACK_SLOT2OFS(slot) == (MSize)ofs)
82 return slot;
83 }
84 return ~0u; /* Not a known callback function pointer. */
85}
86
87/* Initialize machine code for callback function pointers. */
88#if LJ_TARGET_X86ORX64
89static void callback_mcode_init(global_State *g, uint8_t *page)
90{
91 uint8_t *p = page;
92 uint8_t *target = (uint8_t *)(void *)lj_vm_ffi_callback;
93 MSize slot;
94#if LJ_64
95 *(void **)p = target; p += 8;
96#endif
97 for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
98 /* mov al, slot; jmp group */
99 *p++ = XI_MOVrib | RID_EAX; *p++ = (uint8_t)slot;
100 if ((slot & 31) == 31 || slot == CALLBACK_MAX_SLOT-1) {
101 /* push ebp/rbp; mov ah, slot>>8; mov ebp, &g. */
102 *p++ = XI_PUSH + RID_EBP;
103 *p++ = XI_MOVrib | (RID_EAX+4); *p++ = (uint8_t)(slot >> 8);
104 *p++ = XI_MOVri | RID_EBP;
105 *(int32_t *)p = i32ptr(g); p += 4;
106#if LJ_64
107 /* jmp [rip-pageofs] where lj_vm_ffi_callback is stored. */
108 *p++ = XI_GROUP5; *p++ = XM_OFS0 + (XOg_JMP<<3) + RID_EBP;
109 *(int32_t *)p = (int32_t)(page-(p+4)); p += 4;
110#else
111 /* jmp lj_vm_ffi_callback. */
112 *p++ = XI_JMP; *(int32_t *)p = target-(p+4); p += 4;
113#endif
114 } else {
115 *p++ = XI_JMPs; *p++ = (uint8_t)((2+2)*(31-(slot&31)) - 2);
116 }
117 }
118 lua_assert(p - page <= CALLBACK_MCODE_SIZE);
119}
120#elif LJ_TARGET_ARM
121static void callback_mcode_init(global_State *g, uint32_t *page)
122{
123 uint32_t *p = page;
124 void *target = (void *)lj_vm_ffi_callback;
125 MSize slot;
126 /* This must match with the saveregs macro in buildvm_arm.dasc. */
127 *p++ = ARMI_SUB|ARMF_D(RID_R12)|ARMF_N(RID_R12)|ARMF_M(RID_PC);
128 *p++ = ARMI_PUSH|ARMF_N(RID_SP)|RSET_RANGE(RID_R4,RID_R11+1)|RID2RSET(RID_LR);
129 *p++ = ARMI_SUB|ARMI_K12|ARMF_D(RID_R12)|ARMF_N(RID_R12)|CALLBACK_MCODE_HEAD;
130 *p++ = ARMI_STR|ARMI_LS_P|ARMI_LS_W|ARMF_D(RID_R12)|ARMF_N(RID_SP)|(CFRAME_SIZE-4*9);
131 *p++ = ARMI_LDR|ARMI_LS_P|ARMI_LS_U|ARMF_D(RID_R12)|ARMF_N(RID_PC);
132 *p++ = ARMI_LDR|ARMI_LS_P|ARMI_LS_U|ARMF_D(RID_PC)|ARMF_N(RID_PC);
133 *p++ = u32ptr(g);
134 *p++ = u32ptr(target);
135 for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
136 *p++ = ARMI_MOV|ARMF_D(RID_R12)|ARMF_M(RID_PC);
137 *p = ARMI_B | ((page-p-2) & 0x00ffffffu);
138 p++;
139 }
140 lua_assert(p - page <= CALLBACK_MCODE_SIZE);
141}
142#elif LJ_TARGET_PPC
143static void callback_mcode_init(global_State *g, uint32_t *page)
144{
145 uint32_t *p = page;
146 void *target = (void *)lj_vm_ffi_callback;
147 MSize slot;
148 *p++ = PPCI_LIS | PPCF_T(RID_TMP) | (u32ptr(target) >> 16);
149 *p++ = PPCI_LIS | PPCF_T(RID_R12) | (u32ptr(g) >> 16);
150 *p++ = PPCI_ORI | PPCF_A(RID_TMP)|PPCF_T(RID_TMP) | (u32ptr(target) & 0xffff);
151 *p++ = PPCI_ORI | PPCF_A(RID_R12)|PPCF_T(RID_R12) | (u32ptr(g) & 0xffff);
152 *p++ = PPCI_MTCTR | PPCF_T(RID_TMP);
153 *p++ = PPCI_BCTR;
154 for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
155 *p++ = PPCI_LI | PPCF_T(RID_R11) | slot;
156 *p = PPCI_B | (((page-p) & 0x00ffffffu) << 2);
157 p++;
158 }
159 lua_assert(p - page <= CALLBACK_MCODE_SIZE);
160}
161#else
162/* Missing support for this architecture. */
163#define callback_mcode_init(g, p) UNUSED(p)
164#endif
165
166/* -- Machine code management --------------------------------------------- */
167
168#if LJ_TARGET_WINDOWS
169
170#define WIN32_LEAN_AND_MEAN
171#include <windows.h>
172
173#elif LJ_TARGET_POSIX
174
175#include <sys/mman.h>
176#ifndef MAP_ANONYMOUS
177#define MAP_ANONYMOUS MAP_ANON
178#endif
179
180#endif
181
182/* Allocate and initialize area for callback function pointers. */
183static void callback_mcode_new(CTState *cts)
184{
185 size_t sz = (size_t)CALLBACK_MCODE_SIZE;
186 void *p;
187 if (CALLBACK_MAX_SLOT == 0)
188 lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
189#if LJ_TARGET_WINDOWS
190 p = VirtualAlloc(NULL, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
191 if (!p)
192 lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
193#elif LJ_TARGET_POSIX
194 p = mmap(NULL, sz, (PROT_READ|PROT_WRITE), MAP_PRIVATE|MAP_ANONYMOUS,
195 -1, 0);
196 if (p == MAP_FAILED)
197 lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
198#else
199 /* Fallback allocator. Fails if memory is not executable by default. */
200 p = lj_mem_new(cts->L, sz);
201#endif
202 cts->cb.mcode = p;
203 callback_mcode_init(cts->g, p);
204 lj_mcode_sync(p, (char *)p + sz);
205#if LJ_TARGET_WINDOWS
206 {
207 DWORD oprot;
208 VirtualProtect(p, sz, PAGE_EXECUTE_READ, &oprot);
209 }
210#elif LJ_TARGET_POSIX
211 mprotect(p, sz, (PROT_READ|PROT_EXEC));
212#endif
213}
214
215/* Free area for callback function pointers. */
216void lj_ccallback_mcode_free(CTState *cts)
217{
218 size_t sz = (size_t)CALLBACK_MCODE_SIZE;
219 void *p = cts->cb.mcode;
220 if (p == NULL) return;
221#if LJ_TARGET_WINDOWS
222 VirtualFree(p, 0, MEM_RELEASE);
223 UNUSED(sz);
224#elif LJ_TARGET_POSIX
225 munmap(p, sz);
226#else
227 lj_mem_free(cts->g, p, sz);
228#endif
229}
230
231/* -- C callback entry ---------------------------------------------------- */
232
233/* Target-specific handling of register arguments. Similar to lj_ccall.c. */
234#if LJ_TARGET_X86
235
236#define CALLBACK_HANDLE_REGARG \
237 if (!isfp) { /* Only non-FP values may be passed in registers. */ \
238 if (n > 1) { /* Anything > 32 bit is passed on the stack. */ \
239 if (!LJ_ABI_WIN) ngpr = maxgpr; /* Prevent reordering. */ \
240 } else if (ngpr + 1 <= maxgpr) { \
241 sp = &cts->cb.gpr[ngpr]; \
242 ngpr += n; \
243 goto done; \
244 } \
245 }
246
247#elif LJ_TARGET_X64 && LJ_ABI_WIN
248
249/* Windows/x64 argument registers are strictly positional (use ngpr). */
250#define CALLBACK_HANDLE_REGARG \
251 if (isfp) { \
252 if (ngpr < 4) { sp = &cts->cb.fpr[ngpr++]; nfpr = ngpr; goto done; } \
253 } else { \
254 if (ngpr < 4) { sp = &cts->cb.gpr[ngpr++]; goto done; } \
255 }
256
257#elif LJ_TARGET_X64
258
259#define CALLBACK_HANDLE_REGARG \
260 if (isfp) { \
261 if (nfpr + n <= CCALL_NARG_FPR) { \
262 sp = &cts->cb.fpr[nfpr]; \
263 nfpr += n; \
264 goto done; \
265 } \
266 } else { \
267 if (ngpr + n <= maxgpr) { \
268 sp = &cts->cb.gpr[ngpr]; \
269 ngpr += n; \
270 goto done; \
271 } \
272 }
273
274#elif LJ_TARGET_ARM
275
276#define CALLBACK_HANDLE_REGARG \
277 if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \
278 if (ngpr + n <= maxgpr) { \
279 sp = &cts->cb.gpr[ngpr]; \
280 ngpr += n; \
281 goto done; \
282 }
283
284#elif LJ_TARGET_PPC
285
286#define CALLBACK_HANDLE_REGARG \
287 if (isfp) { \
288 if (nfpr + 1 <= CCALL_NARG_FPR) { \
289 sp = &cts->cb.fpr[nfpr]; \
290 nfpr += 1; \
291 cta = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \
292 goto done; \
293 } \
294 } else { /* Try to pass argument in GPRs. */ \
295 if (n > 1) { \
296 lua_assert(ctype_isinteger(cta->info) && n == 2); /* int64_t. */ \
297 ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
298 } \
299 if (ngpr + n <= maxgpr) { \
300 sp = &cts->cb.gpr[ngpr]; \
301 ngpr += n; \
302 goto done; \
303 } \
304 }
305
306#define CALLBACK_HANDLE_RET \
307 if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
308 *(double *)dp = *(float *)dp; /* FPRs always hold doubles. */
309
310#else
311#error "Missing calling convention definitions for this architecture"
312#endif
313
314/* Convert and push callback arguments to Lua stack. */
315static void callback_conv_args(CTState *cts, lua_State *L)
316{
317 TValue *o = L->top;
318 intptr_t *stack = cts->cb.stack;
319 MSize slot = cts->cb.slot;
320 CTypeID id = 0, rid, fid;
321 CType *ct;
322 GCfunc *fn;
323 MSize ngpr = 0, nsp = 0, maxgpr = CCALL_NARG_GPR;
324#if CCALL_NARG_FPR
325 MSize nfpr = 0;
326#endif
327
328 if (slot < cts->cb.sizeid && (id = cts->cb.cbid[slot]) != 0) {
329 ct = ctype_get(cts, id);
330 rid = ctype_cid(ct->info);
331 fn = funcV(lj_tab_getint(cts->miscmap, (int32_t)slot));
332 } else { /* Must set up frame first, before throwing the error. */
333 ct = NULL;
334 rid = 0;
335 fn = (GCfunc *)L;
336 }
337 o->u32.lo = LJ_CONT_FFI_CALLBACK; /* Continuation returns from callback. */
338 o->u32.hi = rid; /* Return type. x86: +(spadj<<16). */
339 o++;
340 setframe_gc(o, obj2gco(fn));
341 setframe_ftsz(o, (int)((char *)(o+1) - (char *)L->base) + FRAME_CONT);
342 L->top = L->base = ++o;
343 if (!ct)
344 lj_err_caller(cts->L, LJ_ERR_FFI_BADCBACK);
345 if (isluafunc(fn))
346 setcframe_pc(L->cframe, proto_bc(funcproto(fn))+1);
347 lj_state_checkstack(L, LUA_MINSTACK); /* May throw. */
348 o = L->base; /* Might have been reallocated. */
349
350#if LJ_TARGET_X86
351 /* x86 has several different calling conventions. */
352 switch (ctype_cconv(ct->info)) {
353 case CTCC_FASTCALL: maxgpr = 2; break;
354 case CTCC_THISCALL: maxgpr = 1; break;
355 default: maxgpr = 0; break;
356 }
357#endif
358
359 fid = ct->sib;
360 while (fid) {
361 CType *ctf = ctype_get(cts, fid);
362 if (!ctype_isattrib(ctf->info)) {
363 CType *cta;
364 void *sp;
365 CTSize sz;
366 int isfp;
367 MSize n;
368 lua_assert(ctype_isfield(ctf->info));
369 cta = ctype_rawchild(cts, ctf);
370 if (ctype_isenum(cta->info)) cta = ctype_child(cts, cta);
371 isfp = ctype_isfp(cta->info);
372 sz = (cta->size + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1);
373 n = sz / CTSIZE_PTR; /* Number of GPRs or stack slots needed. */
374
375 CALLBACK_HANDLE_REGARG /* Handle register arguments. */
376
377 /* Otherwise pass argument on stack. */
378 if (CCALL_ALIGN_STACKARG && LJ_32 && sz == 8)
379 nsp = (nsp + 1) & ~1u; /* Align 64 bit argument on stack. */
380 sp = &stack[nsp];
381 nsp += n;
382
383 done:
384 if (LJ_BE && cta->size < CTSIZE_PTR)
385 sp = (void *)((uint8_t *)sp + CTSIZE_PTR-cta->size);
386 lj_cconv_tv_ct(cts, cta, 0, o++, sp);
387 }
388 fid = ctf->sib;
389 }
390 L->top = o;
391#if LJ_TARGET_X86
392 /* Store stack adjustment for returns from fastcall/stdcall callbacks. */
393 switch (ctype_cconv(ct->info)) {
394 case CTCC_FASTCALL: case CTCC_STDCALL:
395 (L->base-2)->u32.hi |= (nsp << (16+2));
396 break;
397 }
398#endif
399}
400
401/* Convert Lua object to callback result. */
402static void callback_conv_result(CTState *cts, lua_State *L, TValue *o)
403{
404 CType *ctr = ctype_raw(cts, (uint16_t)(L->base-2)->u32.hi);
405#if LJ_TARGET_X86
406 cts->cb.gpr[2] = 0;
407#endif
408 if (!ctype_isvoid(ctr->info)) {
409 uint8_t *dp = (uint8_t *)&cts->cb.gpr[0];
410#if CCALL_NUM_FPR
411 if (ctype_isfp(ctr->info))
412 dp = (uint8_t *)&cts->cb.fpr[0];
413#endif
414 lj_cconv_ct_tv(cts, ctr, dp, o, 0);
415#ifdef CALLBACK_HANDLE_RET
416 CALLBACK_HANDLE_RET
417#endif
418 /* Extend returned integers to (at least) 32 bits. */
419 if (ctype_isinteger_or_bool(ctr->info) && ctr->size < 4) {
420 if (ctr->info & CTF_UNSIGNED)
421 *(uint32_t *)dp = ctr->size == 1 ? (uint32_t)*(uint8_t *)dp :
422 (uint32_t)*(uint16_t *)dp;
423 else
424 *(int32_t *)dp = ctr->size == 1 ? (int32_t)*(int8_t *)dp :
425 (int32_t)*(int16_t *)dp;
426 }
427#if LJ_TARGET_X86
428 if (ctype_isfp(ctr->info))
429 cts->cb.gpr[2] = ctr->size == sizeof(float) ? 1 : 2;
430#endif
431 }
432}
433
434/* Enter callback. */
435lua_State * LJ_FASTCALL lj_ccallback_enter(CTState *cts, void *cf)
436{
437 lua_State *L = cts->L;
438 lua_assert(L != NULL);
439 if (gcref(cts->g->jit_L))
440 lj_err_caller(gco2th(gcref(cts->g->jit_L)), LJ_ERR_FFI_BADCBACK);
441 /* Setup C frame. */
442 cframe_prev(cf) = L->cframe;
443 setcframe_L(cf, L);
444 cframe_errfunc(cf) = -1;
445 cframe_nres(cf) = 0;
446 L->cframe = cf;
447 callback_conv_args(cts, L);
448 return L; /* Now call the function on this stack. */
449}
450
451/* Leave callback. */
452void LJ_FASTCALL lj_ccallback_leave(CTState *cts, TValue *o)
453{
454 lua_State *L = cts->L;
455 GCfunc *fn;
456 TValue *obase = L->base;
457 L->base = L->top; /* Keep continuation frame for throwing errors. */
458 /* PC of RET* is lost. Point to last line for result conv. errors. */
459 fn = curr_func(L);
460 if (isluafunc(fn)) {
461 GCproto *pt = funcproto(fn);
462 setcframe_pc(L->cframe, proto_bc(pt)+pt->sizebc+1);
463 }
464 callback_conv_result(cts, L, o);
465 /* Finally drop C frame and continuation frame. */
466 L->cframe = cframe_prev(L->cframe);
467 L->top -= 2;
468 L->base = obase;
469}
470
471/* -- C callback management ----------------------------------------------- */
472
473/* Get an unused slot in the callback slot table. */
474static MSize callback_slot_new(CTState *cts, CType *ct)
475{
476 CTypeID id = ctype_typeid(cts, ct);
477 CTypeID1 *cbid = cts->cb.cbid;
478 MSize top;
479 for (top = cts->cb.topid; top < cts->cb.sizeid; top++)
480 if (LJ_LIKELY(cbid[top] == 0))
481 goto found;
482#if CALLBACK_MAX_SLOT
483 if (top >= CALLBACK_MAX_SLOT)
484#endif
485 lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
486 if (!cts->cb.mcode)
487 callback_mcode_new(cts);
488 lj_mem_growvec(cts->L, cbid, cts->cb.sizeid, CALLBACK_MAX_SLOT, CTypeID1);
489 cts->cb.cbid = cbid;
490 memset(cbid+top, 0, (cts->cb.sizeid-top)*sizeof(CTypeID1));
491found:
492 cbid[top] = id;
493 cts->cb.topid = top+1;
494 return top;
495}
496
497/* Check for function pointer and supported argument/result types. */
498static CType *callback_checkfunc(CTState *cts, CType *ct)
499{
500 int narg = 0;
501 if (!ctype_isptr(ct->info) || (LJ_64 && ct->size != CTSIZE_PTR))
502 return NULL;
503 ct = ctype_rawchild(cts, ct);
504 if (ctype_isfunc(ct->info)) {
505 CType *ctr = ctype_rawchild(cts, ct);
506 CTypeID fid = ct->sib;
507 if (!(ctype_isvoid(ctr->info) || ctype_isenum(ctr->info) ||
508 ctype_isptr(ctr->info) || (ctype_isnum(ctr->info) && ctr->size <= 8)))
509 return NULL;
510 if ((ct->info & CTF_VARARG))
511 return NULL;
512 while (fid) {
513 CType *ctf = ctype_get(cts, fid);
514 if (!ctype_isattrib(ctf->info)) {
515 CType *cta;
516 lua_assert(ctype_isfield(ctf->info));
517 cta = ctype_rawchild(cts, ctf);
518 if (!(ctype_isenum(cta->info) || ctype_isptr(cta->info) ||
519 (ctype_isnum(cta->info) && cta->size <= 8)) ||
520 ++narg >= LUA_MINSTACK-3)
521 return NULL;
522 }
523 fid = ctf->sib;
524 }
525 return ct;
526 }
527 return NULL;
528}
529
530/* Create a new callback and return the callback function pointer. */
531void *lj_ccallback_new(CTState *cts, CType *ct, GCfunc *fn)
532{
533 ct = callback_checkfunc(cts, ct);
534 if (ct) {
535 MSize slot = callback_slot_new(cts, ct);
536 GCtab *t = cts->miscmap;
537 setfuncV(cts->L, lj_tab_setint(cts->L, t, (int32_t)slot), fn);
538 lj_gc_anybarriert(cts->L, t);
539 return callback_slot2ptr(cts, slot);
540 }
541 return NULL; /* Bad conversion. */
542}
543
544#endif
diff --git a/libraries/luajit-2.0/src/lj_ccallback.h b/libraries/luajit-2.0/src/lj_ccallback.h
new file mode 100644
index 0000000..cbdc1e8
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ccallback.h
@@ -0,0 +1,25 @@
1/*
2** FFI C callback handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CCALLBACK_H
7#define _LJ_CCALLBACK_H
8
9#include "lj_obj.h"
10#include "lj_ctype.h"
11
12#if LJ_HASFFI
13
14/* Really belongs to lj_vm.h. */
15LJ_ASMF void lj_vm_ffi_callback(void);
16
17LJ_FUNC MSize lj_ccallback_ptr2slot(CTState *cts, void *p);
18LJ_FUNCA lua_State * LJ_FASTCALL lj_ccallback_enter(CTState *cts, void *cf);
19LJ_FUNCA void LJ_FASTCALL lj_ccallback_leave(CTState *cts, TValue *o);
20LJ_FUNC void *lj_ccallback_new(CTState *cts, CType *ct, GCfunc *fn);
21LJ_FUNC void lj_ccallback_mcode_free(CTState *cts);
22
23#endif
24
25#endif
diff --git a/libraries/luajit-2.0/src/lj_cconv.c b/libraries/luajit-2.0/src/lj_cconv.c
new file mode 100644
index 0000000..9d47835
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_cconv.c
@@ -0,0 +1,742 @@
1/*
2** C type conversions.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "lj_obj.h"
7
8#if LJ_HASFFI
9
10#include "lj_err.h"
11#include "lj_tab.h"
12#include "lj_ctype.h"
13#include "lj_cdata.h"
14#include "lj_cconv.h"
15#include "lj_ccallback.h"
16
17/* -- Conversion errors --------------------------------------------------- */
18
19/* Bad conversion. */
20LJ_NORET static void cconv_err_conv(CTState *cts, CType *d, CType *s,
21 CTInfo flags)
22{
23 const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
24 const char *src;
25 if ((flags & CCF_FROMTV))
26 src = lj_obj_typename[1+(ctype_isnum(s->info) ? LUA_TNUMBER :
27 ctype_isarray(s->info) ? LUA_TSTRING : LUA_TNIL)];
28 else
29 src = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, s), NULL));
30 if (CCF_GETARG(flags))
31 lj_err_argv(cts->L, CCF_GETARG(flags), LJ_ERR_FFI_BADCONV, src, dst);
32 else
33 lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst);
34}
35
36/* Bad conversion from TValue. */
37LJ_NORET static void cconv_err_convtv(CTState *cts, CType *d, TValue *o,
38 CTInfo flags)
39{
40 const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
41 const char *src = typename(o);
42 if (CCF_GETARG(flags))
43 lj_err_argv(cts->L, CCF_GETARG(flags), LJ_ERR_FFI_BADCONV, src, dst);
44 else
45 lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst);
46}
47
48/* Initializer overflow. */
49LJ_NORET static void cconv_err_initov(CTState *cts, CType *d)
50{
51 const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
52 lj_err_callerv(cts->L, LJ_ERR_FFI_INITOV, dst);
53}
54
55/* -- C type compatibility checks ----------------------------------------- */
56
57/* Get raw type and qualifiers for a child type. Resolves enums, too. */
58static CType *cconv_childqual(CTState *cts, CType *ct, CTInfo *qual)
59{
60 ct = ctype_child(cts, ct);
61 for (;;) {
62 if (ctype_isattrib(ct->info)) {
63 if (ctype_attrib(ct->info) == CTA_QUAL) *qual |= ct->size;
64 } else if (!ctype_isenum(ct->info)) {
65 break;
66 }
67 ct = ctype_child(cts, ct);
68 }
69 *qual |= (ct->info & CTF_QUAL);
70 return ct;
71}
72
73/* Check for compatible types when converting to a pointer.
74** Note: these checks are more relaxed than what C99 mandates.
75*/
76int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags)
77{
78 if (!((flags & CCF_CAST) || d == s)) {
79 CTInfo dqual = 0, squal = 0;
80 d = cconv_childqual(cts, d, &dqual);
81 if (!ctype_isstruct(s->info))
82 s = cconv_childqual(cts, s, &squal);
83 if ((flags & CCF_SAME)) {
84 if (dqual != squal)
85 return 0; /* Different qualifiers. */
86 } else if (!(flags & CCF_IGNQUAL)) {
87 if ((dqual & squal) != squal)
88 return 0; /* Discarded qualifiers. */
89 if (ctype_isvoid(d->info) || ctype_isvoid(s->info))
90 return 1; /* Converting to/from void * is always ok. */
91 }
92 if (ctype_type(d->info) != ctype_type(s->info) ||
93 d->size != s->size)
94 return 0; /* Different type or different size. */
95 if (ctype_isnum(d->info)) {
96 if (((d->info ^ s->info) & (CTF_BOOL|CTF_FP)))
97 return 0; /* Different numeric types. */
98 } else if (ctype_ispointer(d->info)) {
99 /* Check child types for compatibility. */
100 return lj_cconv_compatptr(cts, d, s, flags|CCF_SAME);
101 } else if (ctype_isstruct(d->info)) {
102 if (d != s)
103 return 0; /* Must be exact same type for struct/union. */
104 } else if (ctype_isfunc(d->info)) {
105 /* NYI: structural equality of functions. */
106 }
107 }
108 return 1; /* Types are compatible. */
109}
110
111/* -- C type to C type conversion ----------------------------------------- */
112
113/* Convert C type to C type. Caveat: expects to get the raw CType!
114**
115** Note: This is only used by the interpreter and not optimized at all.
116** The JIT compiler will do a much better job specializing for each case.
117*/
118void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
119 uint8_t *dp, uint8_t *sp, CTInfo flags)
120{
121 CTSize dsize = d->size, ssize = s->size;
122 CTInfo dinfo = d->info, sinfo = s->info;
123 void *tmpptr;
124
125 lua_assert(!ctype_isenum(dinfo) && !ctype_isenum(sinfo));
126 lua_assert(!ctype_isattrib(dinfo) && !ctype_isattrib(sinfo));
127
128 if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
129 goto err_conv;
130
131 /* Some basic sanity checks. */
132 lua_assert(!ctype_isnum(dinfo) || dsize > 0);
133 lua_assert(!ctype_isnum(sinfo) || ssize > 0);
134 lua_assert(!ctype_isbool(dinfo) || dsize == 1);
135 lua_assert(!ctype_isbool(sinfo) || ssize == 1);
136 lua_assert(!ctype_isinteger(dinfo) || (1u<<lj_fls(dsize)) == dsize);
137 lua_assert(!ctype_isinteger(sinfo) || (1u<<lj_fls(ssize)) == ssize);
138
139 switch (cconv_idx2(dinfo, sinfo)) {
140 /* Destination is a bool. */
141 case CCX(B, B):
142 *dp = *sp; /* Source operand is already normalized. */
143 break;
144 case CCX(B, I): {
145 MSize i;
146 uint8_t b = 0;
147 for (i = 0; i < ssize; i++) b |= sp[i];
148 *dp = (b != 0);
149 break;
150 }
151 case CCX(B, F): {
152 uint8_t b;
153 if (ssize == sizeof(double)) b = (*(double *)sp != 0);
154 else if (ssize == sizeof(float)) b = (*(float *)sp != 0);
155 else goto err_conv; /* NYI: long double. */
156 *dp = b;
157 break;
158 }
159
160 /* Destination is an integer. */
161 case CCX(I, B):
162 case CCX(I, I):
163 conv_I_I:
164 if (dsize > ssize) { /* Zero-extend or sign-extend LSB. */
165#if LJ_LE
166 uint8_t fill = (!(sinfo & CTF_UNSIGNED) && (sp[ssize-1]&0x80)) ? 0xff : 0;
167 memcpy(dp, sp, ssize);
168 memset(dp + ssize, fill, dsize-ssize);
169#else
170 uint8_t fill = (!(sinfo & CTF_UNSIGNED) && (sp[0]&0x80)) ? 0xff : 0;
171 memset(dp, fill, dsize-ssize);
172 memcpy(dp + (dsize-ssize), sp, ssize);
173#endif
174 } else { /* Copy LSB. */
175#if LJ_LE
176 memcpy(dp, sp, dsize);
177#else
178 memcpy(dp, sp + (ssize-dsize), dsize);
179#endif
180 }
181 break;
182 case CCX(I, F): {
183 double n; /* Always convert via double. */
184 conv_I_F:
185 /* Convert source to double. */
186 if (ssize == sizeof(double)) n = *(double *)sp;
187 else if (ssize == sizeof(float)) n = (double)*(float *)sp;
188 else goto err_conv; /* NYI: long double. */
189 /* Then convert double to integer. */
190 /* The conversion must exactly match the semantics of JIT-compiled code! */
191 if (dsize < 4 || (dsize == 4 && !(dinfo & CTF_UNSIGNED))) {
192 int32_t i = (int32_t)n;
193 if (dsize == 4) *(int32_t *)dp = i;
194 else if (dsize == 2) *(int16_t *)dp = (int16_t)i;
195 else *(int8_t *)dp = (int8_t)i;
196 } else if (dsize == 4) {
197 *(uint32_t *)dp = (uint32_t)n;
198 } else if (dsize == 8) {
199 if (!(dinfo & CTF_UNSIGNED))
200 *(int64_t *)dp = (int64_t)n;
201 else
202 *(uint64_t *)dp = lj_num2u64(n);
203 } else {
204 goto err_conv; /* NYI: conversion to >64 bit integers. */
205 }
206 break;
207 }
208 case CCX(I, C):
209 s = ctype_child(cts, s);
210 sinfo = s->info;
211 ssize = s->size;
212 goto conv_I_F; /* Just convert re. */
213 case CCX(I, P):
214 if (!(flags & CCF_CAST)) goto err_conv;
215 sinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
216 goto conv_I_I;
217 case CCX(I, A):
218 if (!(flags & CCF_CAST)) goto err_conv;
219 sinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
220 ssize = CTSIZE_PTR;
221 tmpptr = sp;
222 sp = (uint8_t *)&tmpptr;
223 goto conv_I_I;
224
225 /* Destination is a floating-point number. */
226 case CCX(F, B):
227 case CCX(F, I): {
228 double n; /* Always convert via double. */
229 conv_F_I:
230 /* First convert source to double. */
231 /* The conversion must exactly match the semantics of JIT-compiled code! */
232 if (ssize < 4 || (ssize == 4 && !(sinfo & CTF_UNSIGNED))) {
233 int32_t i;
234 if (ssize == 4) {
235 i = *(int32_t *)sp;
236 } else if (!(sinfo & CTF_UNSIGNED)) {
237 if (ssize == 2) i = *(int16_t *)sp;
238 else i = *(int8_t *)sp;
239 } else {
240 if (ssize == 2) i = *(uint16_t *)sp;
241 else i = *(uint8_t *)sp;
242 }
243 n = (double)i;
244 } else if (ssize == 4) {
245 n = (double)*(uint32_t *)sp;
246 } else if (ssize == 8) {
247 if (!(sinfo & CTF_UNSIGNED)) n = (double)*(int64_t *)sp;
248 else n = (double)*(uint64_t *)sp;
249 } else {
250 goto err_conv; /* NYI: conversion from >64 bit integers. */
251 }
252 /* Convert double to destination. */
253 if (dsize == sizeof(double)) *(double *)dp = n;
254 else if (dsize == sizeof(float)) *(float *)dp = (float)n;
255 else goto err_conv; /* NYI: long double. */
256 break;
257 }
258 case CCX(F, F): {
259 double n; /* Always convert via double. */
260 conv_F_F:
261 if (ssize == dsize) goto copyval;
262 /* Convert source to double. */
263 if (ssize == sizeof(double)) n = *(double *)sp;
264 else if (ssize == sizeof(float)) n = (double)*(float *)sp;
265 else goto err_conv; /* NYI: long double. */
266 /* Convert double to destination. */
267 if (dsize == sizeof(double)) *(double *)dp = n;
268 else if (dsize == sizeof(float)) *(float *)dp = (float)n;
269 else goto err_conv; /* NYI: long double. */
270 break;
271 }
272 case CCX(F, C):
273 s = ctype_child(cts, s);
274 sinfo = s->info;
275 ssize = s->size;
276 goto conv_F_F; /* Ignore im, and convert from re. */
277
278 /* Destination is a complex number. */
279 case CCX(C, I):
280 d = ctype_child(cts, d);
281 dinfo = d->info;
282 dsize = d->size;
283 memset(dp + dsize, 0, dsize); /* Clear im. */
284 goto conv_F_I; /* Convert to re. */
285 case CCX(C, F):
286 d = ctype_child(cts, d);
287 dinfo = d->info;
288 dsize = d->size;
289 memset(dp + dsize, 0, dsize); /* Clear im. */
290 goto conv_F_F; /* Convert to re. */
291
292 case CCX(C, C):
293 if (dsize != ssize) { /* Different types: convert re/im separately. */
294 CType *dc = ctype_child(cts, d);
295 CType *sc = ctype_child(cts, s);
296 lj_cconv_ct_ct(cts, dc, sc, dp, sp, flags);
297 lj_cconv_ct_ct(cts, dc, sc, dp + dc->size, sp + sc->size, flags);
298 return;
299 }
300 goto copyval; /* Otherwise this is easy. */
301
302 /* Destination is a vector. */
303 case CCX(V, I):
304 case CCX(V, F):
305 case CCX(V, C): {
306 CType *dc = ctype_child(cts, d);
307 CTSize esize;
308 /* First convert the scalar to the first element. */
309 lj_cconv_ct_ct(cts, dc, s, dp, sp, flags);
310 /* Then replicate it to the other elements (splat). */
311 for (sp = dp, esize = dc->size; dsize > esize; dsize -= esize) {
312 dp += esize;
313 memcpy(dp, sp, esize);
314 }
315 break;
316 }
317
318 case CCX(V, V):
319 /* Copy same-sized vectors, even for different lengths/element-types. */
320 if (dsize != ssize) goto err_conv;
321 goto copyval;
322
323 /* Destination is a pointer. */
324 case CCX(P, I):
325 if (!(flags & CCF_CAST)) goto err_conv;
326 dinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
327 goto conv_I_I;
328
329 case CCX(P, F):
330 if (!(flags & CCF_CAST) || !(flags & CCF_FROMTV)) goto err_conv;
331 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
332 dinfo = CTINFO(CT_NUM, (LJ_64 && dsize == 8) ? 0 : CTF_UNSIGNED);
333 goto conv_I_F;
334
335 case CCX(P, P):
336 if (!lj_cconv_compatptr(cts, d, s, flags)) goto err_conv;
337 cdata_setptr(dp, dsize, cdata_getptr(sp, ssize));
338 break;
339
340 case CCX(P, A):
341 case CCX(P, S):
342 if (!lj_cconv_compatptr(cts, d, s, flags)) goto err_conv;
343 cdata_setptr(dp, dsize, sp);
344 break;
345
346 /* Destination is an array. */
347 case CCX(A, A):
348 if ((flags & CCF_CAST) || (d->info & CTF_VLA) || dsize != ssize ||
349 d->size == CTSIZE_INVALID || !lj_cconv_compatptr(cts, d, s, flags))
350 goto err_conv;
351 goto copyval;
352
353 /* Destination is a struct/union. */
354 case CCX(S, S):
355 if ((flags & CCF_CAST) || (d->info & CTF_VLA) || d != s)
356 goto err_conv; /* Must be exact same type. */
357copyval: /* Copy value. */
358 lua_assert(dsize == ssize);
359 memcpy(dp, sp, dsize);
360 break;
361
362 default:
363 err_conv:
364 cconv_err_conv(cts, d, s, flags);
365 }
366}
367
368/* -- C type to TValue conversion ----------------------------------------- */
369
370/* Convert C type to TValue. Caveat: expects to get the raw CType! */
371int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
372 TValue *o, uint8_t *sp)
373{
374 CTInfo sinfo = s->info;
375 lua_assert(!ctype_isenum(sinfo));
376 if (ctype_isnum(sinfo)) {
377 if (!ctype_isbool(sinfo)) {
378 if (ctype_isinteger(sinfo) && s->size > 4) goto copyval;
379 if (LJ_DUALNUM && ctype_isinteger(sinfo)) {
380 int32_t i;
381 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT32), s,
382 (uint8_t *)&i, sp, 0);
383 if ((sinfo & CTF_UNSIGNED) && i < 0)
384 setnumV(o, (lua_Number)(uint32_t)i);
385 else
386 setintV(o, i);
387 } else {
388 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s,
389 (uint8_t *)&o->n, sp, 0);
390 /* Numbers are NOT canonicalized here! Beware of uninitialized data. */
391 lua_assert(tvisnum(o));
392 }
393 } else {
394 uint32_t b = (*sp != 0);
395 setboolV(o, b);
396 setboolV(&cts->g->tmptv2, b); /* Remember for trace recorder. */
397 }
398 return 0;
399 } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
400 /* Create reference. */
401 setcdataV(cts->L, o, lj_cdata_newref(cts, sp, sid));
402 return 1; /* Need GC step. */
403 } else {
404 GCcdata *cd;
405 CTSize sz;
406 copyval: /* Copy value. */
407 sz = s->size;
408 lua_assert(sz != CTSIZE_INVALID);
409 /* Attributes are stripped, qualifiers are kept (but mostly ignored). */
410 cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz);
411 setcdataV(cts->L, o, cd);
412 memcpy(cdataptr(cd), sp, sz);
413 return 1; /* Need GC step. */
414 }
415}
416
417/* Convert bitfield to TValue. */
418int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp)
419{
420 CTInfo info = s->info;
421 CTSize pos, bsz;
422 uint32_t val;
423 lua_assert(ctype_isbitfield(info));
424 /* NYI: packed bitfields may cause misaligned reads. */
425 switch (ctype_bitcsz(info)) {
426 case 4: val = *(uint32_t *)sp; break;
427 case 2: val = *(uint16_t *)sp; break;
428 case 1: val = *(uint8_t *)sp; break;
429 default: lua_assert(0); val = 0; break;
430 }
431 /* Check if a packed bitfield crosses a container boundary. */
432 pos = ctype_bitpos(info);
433 bsz = ctype_bitbsz(info);
434 lua_assert(pos < 8*ctype_bitcsz(info));
435 lua_assert(bsz > 0 && bsz <= 8*ctype_bitcsz(info));
436 if (pos + bsz > 8*ctype_bitcsz(info))
437 lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT);
438 if (!(info & CTF_BOOL)) {
439 CTSize shift = 32 - bsz;
440 if (!(info & CTF_UNSIGNED)) {
441 setintV(o, (int32_t)(val << (shift-pos)) >> shift);
442 } else {
443 val = (val << (shift-pos)) >> shift;
444 if (!LJ_DUALNUM || (int32_t)val < 0)
445 setnumV(o, (lua_Number)(uint32_t)val);
446 else
447 setintV(o, (int32_t)val);
448 }
449 } else {
450 lua_assert(bsz == 1);
451 setboolV(o, (val >> pos) & 1);
452 }
453 return 0; /* No GC step needed. */
454}
455
456/* -- TValue to C type conversion ----------------------------------------- */
457
458/* Convert table to array. */
459static void cconv_array_tab(CTState *cts, CType *d,
460 uint8_t *dp, GCtab *t, CTInfo flags)
461{
462 int32_t i;
463 CType *dc = ctype_rawchild(cts, d); /* Array element type. */
464 CTSize size = d->size, esize = dc->size, ofs = 0;
465 for (i = 0; ; i++) {
466 TValue *tv = (TValue *)lj_tab_getint(t, i);
467 if (!tv || tvisnil(tv)) {
468 if (i == 0) continue; /* Try again for 1-based tables. */
469 break; /* Stop at first nil. */
470 }
471 if (ofs >= size)
472 cconv_err_initov(cts, d);
473 lj_cconv_ct_tv(cts, dc, dp + ofs, tv, flags);
474 ofs += esize;
475 }
476 if (size != CTSIZE_INVALID) { /* Only fill up arrays with known size. */
477 if (ofs == esize) { /* Replicate a single element. */
478 for (; ofs < size; ofs += esize) memcpy(dp + ofs, dp, esize);
479 } else { /* Otherwise fill the remainder with zero. */
480 memset(dp + ofs, 0, size - ofs);
481 }
482 }
483}
484
485/* Convert table to sub-struct/union. */
486static void cconv_substruct_tab(CTState *cts, CType *d, uint8_t *dp,
487 GCtab *t, int32_t *ip, CTInfo flags)
488{
489 CTypeID id = d->sib;
490 while (id) {
491 CType *df = ctype_get(cts, id);
492 id = df->sib;
493 if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) {
494 TValue *tv;
495 int32_t i = *ip;
496 if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
497 if (i >= 0) {
498 retry:
499 tv = (TValue *)lj_tab_getint(t, i);
500 if (!tv || tvisnil(tv)) {
501 if (i == 0) { i = 1; goto retry; } /* 1-based tables. */
502 break; /* Stop at first nil. */
503 }
504 *ip = i + 1;
505 } else {
506 tv = (TValue *)lj_tab_getstr(t, gco2str(gcref(df->name)));
507 if (!tv || tvisnil(tv)) continue;
508 }
509 if (ctype_isfield(df->info))
510 lj_cconv_ct_tv(cts, ctype_rawchild(cts, df), dp+df->size, tv, flags);
511 else
512 lj_cconv_bf_tv(cts, df, dp+df->size, tv);
513 if ((d->info & CTF_UNION)) break;
514 } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
515 cconv_substruct_tab(cts, ctype_child(cts, df), dp+df->size, t, ip, flags);
516 } /* Ignore all other entries in the chain. */
517 }
518}
519
520/* Convert table to struct/union. */
521static void cconv_struct_tab(CTState *cts, CType *d,
522 uint8_t *dp, GCtab *t, CTInfo flags)
523{
524 int32_t i = 0;
525 memset(dp, 0, d->size); /* Much simpler to clear the struct first. */
526 if (t->hmask) i = -1; else if (t->asize == 0) return; /* Fast exit. */
527 cconv_substruct_tab(cts, d, dp, t, &i, flags);
528}
529
530/* Convert TValue to C type. Caveat: expects to get the raw CType! */
531void lj_cconv_ct_tv(CTState *cts, CType *d,
532 uint8_t *dp, TValue *o, CTInfo flags)
533{
534 CTypeID sid = CTID_P_VOID;
535 CType *s;
536 void *tmpptr;
537 uint8_t tmpbool, *sp = (uint8_t *)&tmpptr;
538 if (LJ_LIKELY(tvisint(o))) {
539 sp = (uint8_t *)&o->i;
540 sid = CTID_INT32;
541 flags |= CCF_FROMTV;
542 } else if (LJ_LIKELY(tvisnum(o))) {
543 sp = (uint8_t *)&o->n;
544 sid = CTID_DOUBLE;
545 flags |= CCF_FROMTV;
546 } else if (tviscdata(o)) {
547 sp = cdataptr(cdataV(o));
548 sid = cdataV(o)->typeid;
549 s = ctype_get(cts, sid);
550 if (ctype_isref(s->info)) { /* Resolve reference for value. */
551 lua_assert(s->size == CTSIZE_PTR);
552 sp = *(void **)sp;
553 sid = ctype_cid(s->info);
554 }
555 s = ctype_raw(cts, sid);
556 if (ctype_isfunc(s->info)) {
557 sid = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|sid), CTSIZE_PTR);
558 } else {
559 if (ctype_isenum(s->info)) s = ctype_child(cts, s);
560 goto doconv;
561 }
562 } else if (tvisstr(o)) {
563 GCstr *str = strV(o);
564 if (ctype_isenum(d->info)) { /* Match string against enum constant. */
565 CTSize ofs;
566 CType *cct = lj_ctype_getfield(cts, d, str, &ofs);
567 if (!cct || !ctype_isconstval(cct->info))
568 goto err_conv;
569 lua_assert(d->size == 4);
570 sp = (uint8_t *)&cct->size;
571 sid = ctype_cid(cct->info);
572 } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */
573 CType *dc = ctype_rawchild(cts, d);
574 CTSize sz = str->len+1;
575 if (!ctype_isinteger(dc->info) || dc->size != 1)
576 goto err_conv;
577 if (d->size != 0 && d->size < sz)
578 sz = d->size;
579 memcpy(dp, strdata(str), sz);
580 return;
581 } else { /* Otherwise pass it as a const char[]. */
582 sp = (uint8_t *)strdata(str);
583 sid = CTID_A_CCHAR;
584 flags |= CCF_FROMTV;
585 }
586 } else if (tvistab(o)) {
587 if (ctype_isarray(d->info)) {
588 cconv_array_tab(cts, d, dp, tabV(o), flags);
589 return;
590 } else if (ctype_isstruct(d->info)) {
591 cconv_struct_tab(cts, d, dp, tabV(o), flags);
592 return;
593 } else {
594 goto err_conv;
595 }
596 } else if (tvisbool(o)) {
597 tmpbool = boolV(o);
598 sp = &tmpbool;
599 sid = CTID_BOOL;
600 } else if (tvisnil(o)) {
601 tmpptr = (void *)0;
602 flags |= CCF_FROMTV;
603 } else if (tvisudata(o)) {
604 tmpptr = uddata(udataV(o));
605 } else if (tvislightud(o)) {
606 tmpptr = lightudV(o);
607 } else if (tvisfunc(o)) {
608 void *p = lj_ccallback_new(cts, d, funcV(o));
609 if (p) {
610 *(void **)dp = p;
611 return;
612 }
613 goto err_conv;
614 } else {
615 err_conv:
616 cconv_err_convtv(cts, d, o, flags);
617 }
618 s = ctype_get(cts, sid);
619doconv:
620 if (ctype_isenum(d->info)) d = ctype_child(cts, d);
621 lj_cconv_ct_ct(cts, d, s, dp, sp, flags);
622}
623
624/* Convert TValue to bitfield. */
625void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o)
626{
627 CTInfo info = d->info;
628 CTSize pos, bsz;
629 uint32_t val, mask;
630 lua_assert(ctype_isbitfield(info));
631 if ((info & CTF_BOOL)) {
632 uint8_t tmpbool;
633 lua_assert(ctype_bitbsz(info) == 1);
634 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_BOOL), &tmpbool, o, 0);
635 val = tmpbool;
636 } else {
637 CTypeID did = (info & CTF_UNSIGNED) ? CTID_UINT32 : CTID_INT32;
638 lj_cconv_ct_tv(cts, ctype_get(cts, did), (uint8_t *)&val, o, 0);
639 }
640 pos = ctype_bitpos(info);
641 bsz = ctype_bitbsz(info);
642 lua_assert(pos < 8*ctype_bitcsz(info));
643 lua_assert(bsz > 0 && bsz <= 8*ctype_bitcsz(info));
644 /* Check if a packed bitfield crosses a container boundary. */
645 if (pos + bsz > 8*ctype_bitcsz(info))
646 lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT);
647 mask = ((1u << bsz) - 1u) << pos;
648 val = (val << pos) & mask;
649 /* NYI: packed bitfields may cause misaligned reads/writes. */
650 switch (ctype_bitcsz(info)) {
651 case 4: *(uint32_t *)dp = (*(uint32_t *)dp & ~mask) | (uint32_t)val; break;
652 case 2: *(uint16_t *)dp = (*(uint16_t *)dp & ~mask) | (uint16_t)val; break;
653 case 1: *(uint8_t *)dp = (*(uint8_t *)dp & ~mask) | (uint8_t)val; break;
654 default: lua_assert(0); break;
655 }
656}
657
658/* -- Initialize C type with TValues -------------------------------------- */
659
660/* Initialize an array with TValues. */
661static void cconv_array_init(CTState *cts, CType *d, CTSize sz, uint8_t *dp,
662 TValue *o, MSize len)
663{
664 CType *dc = ctype_rawchild(cts, d); /* Array element type. */
665 CTSize ofs, esize = dc->size;
666 MSize i;
667 if (len*esize > sz)
668 cconv_err_initov(cts, d);
669 for (i = 0, ofs = 0; i < len; i++, ofs += esize)
670 lj_cconv_ct_tv(cts, dc, dp + ofs, o + i, 0);
671 if (ofs == esize) { /* Replicate a single element. */
672 for (; ofs < sz; ofs += esize) memcpy(dp + ofs, dp, esize);
673 } else { /* Otherwise fill the remainder with zero. */
674 memset(dp + ofs, 0, sz - ofs);
675 }
676}
677
678/* Initialize a sub-struct/union with TValues. */
679static void cconv_substruct_init(CTState *cts, CType *d, uint8_t *dp,
680 TValue *o, MSize len, MSize *ip)
681{
682 CTypeID id = d->sib;
683 while (id) {
684 CType *df = ctype_get(cts, id);
685 id = df->sib;
686 if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) {
687 MSize i = *ip;
688 if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
689 if (i >= len) break;
690 *ip = i + 1;
691 if (ctype_isfield(df->info))
692 lj_cconv_ct_tv(cts, ctype_rawchild(cts, df), dp+df->size, o + i, 0);
693 else
694 lj_cconv_bf_tv(cts, df, dp+df->size, o + i);
695 if ((d->info & CTF_UNION)) break;
696 } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
697 cconv_substruct_init(cts, ctype_child(cts, df), dp+df->size, o, len, ip);
698 } /* Ignore all other entries in the chain. */
699 }
700}
701
702/* Initialize a struct/union with TValues. */
703static void cconv_struct_init(CTState *cts, CType *d, CTSize sz, uint8_t *dp,
704 TValue *o, MSize len)
705{
706 MSize i = 0;
707 memset(dp, 0, sz); /* Much simpler to clear the struct first. */
708 cconv_substruct_init(cts, d, dp, o, len, &i);
709 if (i < len)
710 cconv_err_initov(cts, d);
711}
712
713/* Check whether to use a multi-value initializer.
714** This is true if an aggregate is to be initialized with a value.
715** Valarrays are treated as values here so ct_tv handles (V|C, I|F).
716*/
717int lj_cconv_multi_init(CType *d, TValue *o)
718{
719 if (!(ctype_isrefarray(d->info) || ctype_isstruct(d->info)))
720 return 0; /* Destination is not an aggregate. */
721 if (tvistab(o) || (tvisstr(o) && !ctype_isstruct(d->info)))
722 return 0; /* Initializer is not a value. */
723 return 1; /* Otherwise the initializer is a value. */
724}
725
726/* Initialize C type with TValues. Caveat: expects to get the raw CType! */
727void lj_cconv_ct_init(CTState *cts, CType *d, CTSize sz,
728 uint8_t *dp, TValue *o, MSize len)
729{
730 if (len == 0)
731 memset(dp, 0, sz);
732 else if (len == 1 && !lj_cconv_multi_init(d, o))
733 lj_cconv_ct_tv(cts, d, dp, o, 0);
734 else if (ctype_isarray(d->info)) /* Also handles valarray init with len>1. */
735 cconv_array_init(cts, d, sz, dp, o, len);
736 else if (ctype_isstruct(d->info))
737 cconv_struct_init(cts, d, sz, dp, o, len);
738 else
739 cconv_err_initov(cts, d);
740}
741
742#endif
diff --git a/libraries/luajit-2.0/src/lj_cconv.h b/libraries/luajit-2.0/src/lj_cconv.h
new file mode 100644
index 0000000..47c1459
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_cconv.h
@@ -0,0 +1,70 @@
1/*
2** C type conversions.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CCONV_H
7#define _LJ_CCONV_H
8
9#include "lj_obj.h"
10#include "lj_ctype.h"
11
12#if LJ_HASFFI
13
14/* Compressed C type index. ORDER CCX. */
15enum {
16 CCX_B, /* Bool. */
17 CCX_I, /* Integer. */
18 CCX_F, /* Floating-point number. */
19 CCX_C, /* Complex. */
20 CCX_V, /* Vector. */
21 CCX_P, /* Pointer. */
22 CCX_A, /* Refarray. */
23 CCX_S /* Struct/union. */
24};
25
26/* Convert C type info to compressed C type index. ORDER CT. ORDER CCX. */
27static LJ_AINLINE uint32_t cconv_idx(CTInfo info)
28{
29 uint32_t idx = ((info >> 26) & 15u); /* Dispatch bits. */
30 lua_assert(ctype_type(info) <= CT_MAYCONVERT);
31#if LJ_64
32 idx = ((U64x(f436fff5,fff7f021) >> 4*idx) & 15u);
33#else
34 idx = (((idx < 8 ? 0xfff7f021u : 0xf436fff5) >> 4*(idx & 7u)) & 15u);
35#endif
36 lua_assert(idx < 8);
37 return idx;
38}
39
40#define cconv_idx2(dinfo, sinfo) \
41 ((cconv_idx((dinfo)) << 3) + cconv_idx((sinfo)))
42
43#define CCX(dst, src) ((CCX_##dst << 3) + CCX_##src)
44
45/* Conversion flags. */
46#define CCF_CAST 0x00000001u
47#define CCF_FROMTV 0x00000002u
48#define CCF_SAME 0x00000004u
49#define CCF_IGNQUAL 0x00000008u
50
51#define CCF_ARG_SHIFT 8
52#define CCF_ARG(n) ((n) << CCF_ARG_SHIFT)
53#define CCF_GETARG(f) ((f) >> CCF_ARG_SHIFT)
54
55LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags);
56LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
57 uint8_t *dp, uint8_t *sp, CTInfo flags);
58LJ_FUNC int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
59 TValue *o, uint8_t *sp);
60LJ_FUNC int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp);
61LJ_FUNC void lj_cconv_ct_tv(CTState *cts, CType *d,
62 uint8_t *dp, TValue *o, CTInfo flags);
63LJ_FUNC void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o);
64LJ_FUNC int lj_cconv_multi_init(CType *d, TValue *o);
65LJ_FUNC void lj_cconv_ct_init(CTState *cts, CType *d, CTSize sz,
66 uint8_t *dp, TValue *o, MSize len);
67
68#endif
69
70#endif
diff --git a/libraries/luajit-2.0/src/lj_cdata.c b/libraries/luajit-2.0/src/lj_cdata.c
new file mode 100644
index 0000000..497b84e
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_cdata.c
@@ -0,0 +1,284 @@
1/*
2** C data management.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "lj_obj.h"
7
8#if LJ_HASFFI
9
10#include "lj_gc.h"
11#include "lj_err.h"
12#include "lj_str.h"
13#include "lj_tab.h"
14#include "lj_ctype.h"
15#include "lj_cconv.h"
16#include "lj_cdata.h"
17
18/* -- C data allocation --------------------------------------------------- */
19
20/* Allocate a new C data object holding a reference to another object. */
21GCcdata *lj_cdata_newref(CTState *cts, const void *p, CTypeID id)
22{
23 CTypeID refid = lj_ctype_intern(cts, CTINFO_REF(id), CTSIZE_PTR);
24 GCcdata *cd = lj_cdata_new(cts, refid, CTSIZE_PTR);
25 *(const void **)cdataptr(cd) = p;
26 return cd;
27}
28
29/* Allocate variable-sized or specially aligned C data object. */
30GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz, CTSize align)
31{
32 global_State *g;
33 MSize extra = sizeof(GCcdataVar) + sizeof(GCcdata) +
34 (align > CT_MEMALIGN ? (1u<<align) - (1u<<CT_MEMALIGN) : 0);
35 char *p = lj_mem_newt(cts->L, extra + sz, char);
36 uintptr_t adata = (uintptr_t)p + sizeof(GCcdataVar) + sizeof(GCcdata);
37 uintptr_t almask = (1u << align) - 1u;
38 GCcdata *cd = (GCcdata *)(((adata + almask) & ~almask) - sizeof(GCcdata));
39 lua_assert((char *)cd - p < 65536);
40 cdatav(cd)->offset = (uint16_t)((char *)cd - p);
41 cdatav(cd)->extra = extra;
42 cdatav(cd)->len = sz;
43 g = cts->g;
44 setgcrefr(cd->nextgc, g->gc.root);
45 setgcref(g->gc.root, obj2gco(cd));
46 newwhite(g, obj2gco(cd));
47 cd->marked |= 0x80;
48 cd->gct = ~LJ_TCDATA;
49 cd->typeid = id;
50 return cd;
51}
52
53/* Free a C data object. */
54void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd)
55{
56 if (LJ_UNLIKELY(cd->marked & LJ_GC_CDATA_FIN)) {
57 GCobj *root;
58 makewhite(g, obj2gco(cd));
59 obj2gco(cd)->gch.marked |= LJ_GC_FINALIZED;
60 if ((root = gcref(g->gc.mmudata)) != NULL) {
61 setgcrefr(cd->nextgc, root->gch.nextgc);
62 setgcref(root->gch.nextgc, obj2gco(cd));
63 setgcref(g->gc.mmudata, obj2gco(cd));
64 } else {
65 setgcref(cd->nextgc, obj2gco(cd));
66 setgcref(g->gc.mmudata, obj2gco(cd));
67 }
68 } else if (LJ_LIKELY(!cdataisv(cd))) {
69 CType *ct = ctype_raw(ctype_ctsG(g), cd->typeid);
70 CTSize sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR;
71 lua_assert(ctype_hassize(ct->info) || ctype_isfunc(ct->info) ||
72 ctype_isextern(ct->info));
73 lj_mem_free(g, cd, sizeof(GCcdata) + sz);
74 } else {
75 lj_mem_free(g, memcdatav(cd), sizecdatav(cd));
76 }
77}
78
79TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd)
80{
81 global_State *g = G(L);
82 GCtab *t = ctype_ctsG(g)->finalizer;
83 if (gcref(t->metatable)) {
84 /* Add cdata to finalizer table, if still enabled. */
85 TValue *tv, tmp;
86 setcdataV(L, &tmp, cd);
87 lj_gc_anybarriert(L, t);
88 tv = lj_tab_set(L, t, &tmp);
89 cd->marked |= LJ_GC_CDATA_FIN;
90 return tv;
91 } else {
92 /* Otherwise return dummy TValue. */
93 return &g->tmptv;
94 }
95}
96
97/* -- C data indexing ----------------------------------------------------- */
98
99/* Index C data by a TValue. Return CType and pointer. */
100CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, uint8_t **pp,
101 CTInfo *qual)
102{
103 uint8_t *p = (uint8_t *)cdataptr(cd);
104 CType *ct = ctype_get(cts, cd->typeid);
105 ptrdiff_t idx;
106
107 /* Resolve reference for cdata object. */
108 if (ctype_isref(ct->info)) {
109 lua_assert(ct->size == CTSIZE_PTR);
110 p = *(uint8_t **)p;
111 ct = ctype_child(cts, ct);
112 }
113
114collect_attrib:
115 /* Skip attributes and collect qualifiers. */
116 while (ctype_isattrib(ct->info)) {
117 if (ctype_attrib(ct->info) == CTA_QUAL) *qual |= ct->size;
118 ct = ctype_child(cts, ct);
119 }
120 lua_assert(!ctype_isref(ct->info)); /* Interning rejects refs to refs. */
121
122 if (tvisint(key)) {
123 idx = (ptrdiff_t)intV(key);
124 goto integer_key;
125 } else if (tvisnum(key)) { /* Numeric key. */
126 idx = LJ_64 ? (ptrdiff_t)numV(key) : (ptrdiff_t)lj_num2int(numV(key));
127 integer_key:
128 if (ctype_ispointer(ct->info)) {
129 CTSize sz = lj_ctype_size(cts, ctype_cid(ct->info)); /* Element size. */
130 if (sz != CTSIZE_INVALID) {
131 if (ctype_isptr(ct->info)) {
132 p = (uint8_t *)cdata_getptr(p, ct->size);
133 } else if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) {
134 if ((ct->info & CTF_COMPLEX)) idx &= 1;
135 *qual |= CTF_CONST; /* Valarray elements are constant. */
136 }
137 *pp = p + idx*(int32_t)sz;
138 return ct;
139 }
140 }
141 } else if (tviscdata(key)) { /* Integer cdata key. */
142 GCcdata *cdk = cdataV(key);
143 CType *ctk = ctype_raw(cts, cdk->typeid);
144 if (ctype_isenum(ctk->info)) ctk = ctype_child(cts, ctk);
145 if (ctype_isinteger(ctk->info)) {
146 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), ctk,
147 (uint8_t *)&idx, cdataptr(cdk), 0);
148 goto integer_key;
149 }
150 } else if (tvisstr(key)) { /* String key. */
151 GCstr *name = strV(key);
152 if (ctype_isstruct(ct->info)) {
153 CTSize ofs;
154 CType *fct = lj_ctype_getfield(cts, ct, name, &ofs);
155 if (fct) {
156 *pp = p + ofs;
157 return fct;
158 }
159 } else if (ctype_iscomplex(ct->info)) {
160 if (name->len == 2) {
161 *qual |= CTF_CONST; /* Complex fields are constant. */
162 if (strdata(name)[0] == 'r' && strdata(name)[1] == 'e') {
163 *pp = p;
164 return ct;
165 } else if (strdata(name)[0] == 'i' && strdata(name)[1] == 'm') {
166 *pp = p + (ct->size >> 1);
167 return ct;
168 }
169 }
170 } else if (cd->typeid == CTID_CTYPEID) {
171 /* Allow indexing a (pointer to) struct constructor to get constants. */
172 CType *sct = ctype_raw(cts, *(CTypeID *)p);
173 if (ctype_isptr(sct->info))
174 sct = ctype_rawchild(cts, sct);
175 if (ctype_isstruct(sct->info)) {
176 CTSize ofs;
177 CType *fct = lj_ctype_getfield(cts, sct, name, &ofs);
178 if (fct && ctype_isconstval(fct->info))
179 return fct;
180 }
181 }
182 }
183 if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */
184 if (ctype_isstruct(ctype_rawchild(cts, ct)->info)) {
185 p = (uint8_t *)cdata_getptr(p, ct->size);
186 ct = ctype_child(cts, ct);
187 goto collect_attrib;
188 }
189 }
190 *qual |= 1; /* Lookup failed. */
191 return ct; /* But return the resolved raw type. */
192}
193
194/* -- C data getters ------------------------------------------------------ */
195
196/* Get constant value and convert to TValue. */
197static void cdata_getconst(CTState *cts, TValue *o, CType *ct)
198{
199 CType *ctt = ctype_child(cts, ct);
200 lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4);
201 /* Constants are already zero-extended/sign-extended to 32 bits. */
202 if ((ctt->info & CTF_UNSIGNED) && (int32_t)ct->size < 0)
203 setnumV(o, (lua_Number)(uint32_t)ct->size);
204 else
205 setintV(o, (int32_t)ct->size);
206}
207
208/* Get C data value and convert to TValue. */
209int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp)
210{
211 CTypeID sid;
212
213 if (ctype_isconstval(s->info)) {
214 cdata_getconst(cts, o, s);
215 return 0; /* No GC step needed. */
216 } else if (ctype_isbitfield(s->info)) {
217 return lj_cconv_tv_bf(cts, s, o, sp);
218 }
219
220 /* Get child type of pointer/array/field. */
221 lua_assert(ctype_ispointer(s->info) || ctype_isfield(s->info));
222 sid = ctype_cid(s->info);
223 s = ctype_get(cts, sid);
224
225 /* Resolve reference for field. */
226 if (ctype_isref(s->info)) {
227 lua_assert(s->size == CTSIZE_PTR);
228 sp = *(uint8_t **)sp;
229 sid = ctype_cid(s->info);
230 s = ctype_get(cts, sid);
231 }
232
233 /* Skip attributes and enums. */
234 while (ctype_isattrib(s->info) || ctype_isenum(s->info))
235 s = ctype_child(cts, s);
236
237 return lj_cconv_tv_ct(cts, s, sid, o, sp);
238}
239
240/* -- C data setters ------------------------------------------------------ */
241
242/* Convert TValue and set C data value. */
243void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o, CTInfo qual)
244{
245 if (ctype_isconstval(d->info)) {
246 goto err_const;
247 } else if (ctype_isbitfield(d->info)) {
248 if (((d->info|qual) & CTF_CONST)) goto err_const;
249 lj_cconv_bf_tv(cts, d, dp, o);
250 return;
251 }
252
253 /* Get child type of pointer/array/field. */
254 lua_assert(ctype_ispointer(d->info) || ctype_isfield(d->info));
255 d = ctype_child(cts, d);
256
257 /* Resolve reference for field. */
258 if (ctype_isref(d->info)) {
259 lua_assert(d->size == CTSIZE_PTR);
260 dp = *(uint8_t **)dp;
261 d = ctype_child(cts, d);
262 }
263
264 /* Skip attributes and collect qualifiers. */
265 for (;;) {
266 if (ctype_isattrib(d->info)) {
267 if (ctype_attrib(d->info) == CTA_QUAL) qual |= d->size;
268 } else {
269 break;
270 }
271 d = ctype_child(cts, d);
272 }
273
274 lua_assert(ctype_hassize(d->info) && !ctype_isvoid(d->info));
275
276 if (((d->info|qual) & CTF_CONST)) {
277 err_const:
278 lj_err_caller(cts->L, LJ_ERR_FFI_WRCONST);
279 }
280
281 lj_cconv_ct_tv(cts, d, dp, o, 0);
282}
283
284#endif
diff --git a/libraries/luajit-2.0/src/lj_cdata.h b/libraries/luajit-2.0/src/lj_cdata.h
new file mode 100644
index 0000000..feb1bbf
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_cdata.h
@@ -0,0 +1,75 @@
1/*
2** C data management.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CDATA_H
7#define _LJ_CDATA_H
8
9#include "lj_obj.h"
10#include "lj_gc.h"
11#include "lj_ctype.h"
12
13#if LJ_HASFFI
14
15/* Get C data pointer. */
16static LJ_AINLINE void *cdata_getptr(void *p, CTSize sz)
17{
18 if (LJ_64 && sz == 4) { /* Support 32 bit pointers on 64 bit targets. */
19 return ((void *)(uintptr_t)*(uint32_t *)p);
20 } else {
21 lua_assert(sz == CTSIZE_PTR);
22 return *(void **)p;
23 }
24}
25
26/* Set C data pointer. */
27static LJ_AINLINE void cdata_setptr(void *p, CTSize sz, const void *v)
28{
29 if (LJ_64 && sz == 4) { /* Support 32 bit pointers on 64 bit targets. */
30 *(uint32_t *)p = (uint32_t)(uintptr_t)v;
31 } else {
32 lua_assert(sz == CTSIZE_PTR);
33 *(void **)p = (void *)v;
34 }
35}
36
37/* Allocate fixed-size C data object. */
38static LJ_AINLINE GCcdata *lj_cdata_new(CTState *cts, CTypeID id, CTSize sz)
39{
40 GCcdata *cd;
41#ifdef LUA_USE_ASSERT
42 CType *ct = ctype_raw(cts, id);
43 lua_assert((ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR) == sz);
44#endif
45 cd = (GCcdata *)lj_mem_newgco(cts->L, sizeof(GCcdata) + sz);
46 cd->gct = ~LJ_TCDATA;
47 cd->typeid = ctype_check(cts, id);
48 return cd;
49}
50
51/* Variant which works without a valid CTState. */
52static LJ_AINLINE GCcdata *lj_cdata_new_(lua_State *L, CTypeID id, CTSize sz)
53{
54 GCcdata *cd = (GCcdata *)lj_mem_newgco(L, sizeof(GCcdata) + sz);
55 cd->gct = ~LJ_TCDATA;
56 cd->typeid = id;
57 return cd;
58}
59
60LJ_FUNC GCcdata *lj_cdata_newref(CTState *cts, const void *pp, CTypeID id);
61LJ_FUNC GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz,
62 CTSize align);
63
64LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd);
65LJ_FUNCA TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd);
66
67LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key,
68 uint8_t **pp, CTInfo *qual);
69LJ_FUNC int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp);
70LJ_FUNC void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o,
71 CTInfo qual);
72
73#endif
74
75#endif
diff --git a/libraries/luajit-2.0/src/lj_char.c b/libraries/luajit-2.0/src/lj_char.c
new file mode 100644
index 0000000..11f23ef
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_char.c
@@ -0,0 +1,43 @@
1/*
2** Character types.
3** Donated to the public domain.
4**
5** This is intended to replace the problematic libc single-byte NLS functions.
6** These just don't make sense anymore with UTF-8 locales becoming the norm
7** on POSIX systems. It never worked too well on Windows systems since hardly
8** anyone bothered to call setlocale().
9**
10** This table is hardcoded for ASCII. Identifiers include the characters
11** 128-255, too. This allows for the use of all non-ASCII chars as identifiers
12** in the lexer. This is a broad definition, but works well in practice
13** for both UTF-8 locales and most single-byte locales (such as ISO-8859-*).
14**
15** If you really need proper character types for UTF-8 strings, please use
16** an add-on library such as slnunicode: http://luaforge.net/projects/sln/
17*/
18
19#define lj_char_c
20#define LUA_CORE
21
22#include "lj_char.h"
23
24LJ_DATADEF const uint8_t lj_char_bits[257] = {
25 0,
26 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1,
27 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
28 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
29 152,152,152,152,152,152,152,152,152,152, 4, 4, 4, 4, 4, 4,
30 4,176,176,176,176,176,176,160,160,160,160,160,160,160,160,160,
31 160,160,160,160,160,160,160,160,160,160,160, 4, 4, 4, 4,132,
32 4,208,208,208,208,208,208,192,192,192,192,192,192,192,192,192,
33 192,192,192,192,192,192,192,192,192,192,192, 4, 4, 4, 4, 1,
34 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
35 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
36 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
37 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
38 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
39 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
40 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
41 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
42};
43
diff --git a/libraries/luajit-2.0/src/lj_char.h b/libraries/luajit-2.0/src/lj_char.h
new file mode 100644
index 0000000..7b7c132
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_char.h
@@ -0,0 +1,42 @@
1/*
2** Character types.
3** Donated to the public domain.
4*/
5
6#ifndef _LJ_CHAR_H
7#define _LJ_CHAR_H
8
9#include "lj_def.h"
10
11#define LJ_CHAR_CNTRL 0x01
12#define LJ_CHAR_SPACE 0x02
13#define LJ_CHAR_PUNCT 0x04
14#define LJ_CHAR_DIGIT 0x08
15#define LJ_CHAR_XDIGIT 0x10
16#define LJ_CHAR_UPPER 0x20
17#define LJ_CHAR_LOWER 0x40
18#define LJ_CHAR_IDENT 0x80
19#define LJ_CHAR_ALPHA (LJ_CHAR_LOWER|LJ_CHAR_UPPER)
20#define LJ_CHAR_ALNUM (LJ_CHAR_ALPHA|LJ_CHAR_DIGIT)
21#define LJ_CHAR_GRAPH (LJ_CHAR_ALNUM|LJ_CHAR_PUNCT)
22
23/* Only pass -1 or 0..255 to these macros. Never pass a signed char! */
24#define lj_char_isa(c, t) (lj_char_bits[(c)+1] & t)
25#define lj_char_iscntrl(c) lj_char_isa((c), LJ_CHAR_CNTRL)
26#define lj_char_isspace(c) lj_char_isa((c), LJ_CHAR_SPACE)
27#define lj_char_ispunct(c) lj_char_isa((c), LJ_CHAR_PUNCT)
28#define lj_char_isdigit(c) lj_char_isa((c), LJ_CHAR_DIGIT)
29#define lj_char_isxdigit(c) lj_char_isa((c), LJ_CHAR_XDIGIT)
30#define lj_char_isupper(c) lj_char_isa((c), LJ_CHAR_UPPER)
31#define lj_char_islower(c) lj_char_isa((c), LJ_CHAR_LOWER)
32#define lj_char_isident(c) lj_char_isa((c), LJ_CHAR_IDENT)
33#define lj_char_isalpha(c) lj_char_isa((c), LJ_CHAR_ALPHA)
34#define lj_char_isalnum(c) lj_char_isa((c), LJ_CHAR_ALNUM)
35#define lj_char_isgraph(c) lj_char_isa((c), LJ_CHAR_GRAPH)
36
37#define lj_char_toupper(c) ((c) - (lj_char_islower(c) >> 1))
38#define lj_char_tolower(c) ((c) + lj_char_isupper(c))
39
40LJ_DATA const uint8_t lj_char_bits[257];
41
42#endif
diff --git a/libraries/luajit-2.0/src/lj_clib.c b/libraries/luajit-2.0/src/lj_clib.c
new file mode 100644
index 0000000..68398cf
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_clib.c
@@ -0,0 +1,389 @@
1/*
2** FFI C library loader.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "lj_obj.h"
7
8#if LJ_HASFFI
9
10#include "lj_gc.h"
11#include "lj_err.h"
12#include "lj_tab.h"
13#include "lj_str.h"
14#include "lj_udata.h"
15#include "lj_ctype.h"
16#include "lj_cconv.h"
17#include "lj_cdata.h"
18#include "lj_clib.h"
19
20/* -- OS-specific functions ----------------------------------------------- */
21
22#if LJ_TARGET_DLOPEN
23
24#include <dlfcn.h>
25#include <stdio.h>
26
27#if defined(RTLD_DEFAULT)
28#define CLIB_DEFHANDLE RTLD_DEFAULT
29#elif LJ_TARGET_OSX || LJ_TARGET_BSD
30#define CLIB_DEFHANDLE ((void *)(intptr_t)-2)
31#else
32#define CLIB_DEFHANDLE NULL
33#endif
34
35LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L)
36{
37 lj_err_callermsg(L, dlerror());
38}
39
40#define clib_error(L, fmt, name) clib_error_(L)
41
42#if LJ_TARGET_OSX
43#define CLIB_SOEXT "%s.dylib"
44#else
45#define CLIB_SOEXT "%s.so"
46#endif
47
48static const char *clib_extname(lua_State *L, const char *name)
49{
50 if (!strchr(name, '/')) {
51 if (!strchr(name, '.')) {
52 name = lj_str_pushf(L, CLIB_SOEXT, name);
53 L->top--;
54 }
55 if (!(name[0] == 'l' && name[1] == 'i' && name[2] == 'b')) {
56 name = lj_str_pushf(L, "lib%s", name);
57 L->top--;
58 }
59 }
60 return name;
61}
62
63/* Check for a recognized ld script line. */
64static const char *clib_check_lds(lua_State *L, const char *buf)
65{
66 char *p, *e;
67 if ((!strncmp(buf, "GROUP", 5) || !strncmp(buf, "INPUT", 5)) &&
68 (p = strchr(buf, '('))) {
69 while (*++p == ' ') ;
70 for (e = p; *e && *e != ' ' && *e != ')'; e++) ;
71 return strdata(lj_str_new(L, p, e-p));
72 }
73 return NULL;
74}
75
76/* Quick and dirty solution to resolve shared library name from ld script. */
77static const char *clib_resolve_lds(lua_State *L, const char *name)
78{
79 FILE *fp = fopen(name, "r");
80 const char *p = NULL;
81 if (fp) {
82 char buf[256];
83 if (fgets(buf, sizeof(buf), fp)) {
84 if (!strncmp(buf, "/* GNU ld script", 16)) { /* ld script magic? */
85 while (fgets(buf, sizeof(buf), fp)) { /* Check all lines. */
86 p = clib_check_lds(L, buf);
87 if (p) break;
88 }
89 } else { /* Otherwise check only the first line. */
90 p = clib_check_lds(L, buf);
91 }
92 }
93 fclose(fp);
94 }
95 return p;
96}
97
98static void *clib_loadlib(lua_State *L, const char *name, int global)
99{
100 void *h = dlopen(clib_extname(L, name),
101 RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL));
102 if (!h) {
103 const char *e, *err = dlerror();
104 if (*err == '/' && (e = strchr(err, ':')) &&
105 (name = clib_resolve_lds(L, strdata(lj_str_new(L, err, e-err))))) {
106 h = dlopen(name, RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL));
107 if (h) return h;
108 err = dlerror();
109 }
110 lj_err_callermsg(L, err);
111 }
112 return h;
113}
114
115static void clib_unloadlib(CLibrary *cl)
116{
117 if (!cl->handle && cl->handle != CLIB_DEFHANDLE)
118 dlclose(cl->handle);
119}
120
121static void *clib_getsym(CLibrary *cl, const char *name)
122{
123 void *p = dlsym(cl->handle, name);
124 return p;
125}
126
127#elif LJ_TARGET_WINDOWS
128
129#define WIN32_LEAN_AND_MEAN
130#ifndef WINVER
131#define WINVER 0x0500
132#endif
133#include <windows.h>
134
135#ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
136#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
137#define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
138BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);
139#endif
140
141#define CLIB_DEFHANDLE ((void *)-1)
142
143/* Default libraries. */
144enum {
145 CLIB_HANDLE_EXE,
146 CLIB_HANDLE_DLL,
147 CLIB_HANDLE_CRT,
148 CLIB_HANDLE_KERNEL32,
149 CLIB_HANDLE_USER32,
150 CLIB_HANDLE_GDI32,
151 CLIB_HANDLE_MAX
152};
153
154static void *clib_def_handle[CLIB_HANDLE_MAX];
155
156LJ_NORET LJ_NOINLINE static void clib_error(lua_State *L, const char *fmt,
157 const char *name)
158{
159 DWORD err = GetLastError();
160 char buf[128];
161 if (!FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_FROM_SYSTEM,
162 NULL, err, 0, buf, sizeof(buf), NULL))
163 buf[0] = '\0';
164 lj_err_callermsg(L, lj_str_pushf(L, fmt, name, buf));
165}
166
167static int clib_needext(const char *s)
168{
169 while (*s) {
170 if (*s == '/' || *s == '\\' || *s == '.') return 0;
171 s++;
172 }
173 return 1;
174}
175
176static const char *clib_extname(lua_State *L, const char *name)
177{
178 if (clib_needext(name)) {
179 name = lj_str_pushf(L, "%s.dll", name);
180 L->top--;
181 }
182 return name;
183}
184
185static void *clib_loadlib(lua_State *L, const char *name, int global)
186{
187 DWORD oldwerr = GetLastError();
188 void *h = (void *)LoadLibraryA(clib_extname(L, name));
189 if (!h) clib_error(L, "cannot load module " LUA_QS ": %s", name);
190 SetLastError(oldwerr);
191 UNUSED(global);
192 return h;
193}
194
195static void clib_unloadlib(CLibrary *cl)
196{
197 if (cl->handle == CLIB_DEFHANDLE) {
198 MSize i;
199 for (i = 0; i < CLIB_HANDLE_MAX; i++) {
200 void *h = clib_def_handle[i];
201 if (h) {
202 clib_def_handle[i] = NULL;
203 FreeLibrary((HINSTANCE)h);
204 }
205 }
206 } else if (!cl->handle) {
207 FreeLibrary((HINSTANCE)cl->handle);
208 }
209}
210
211static void *clib_getsym(CLibrary *cl, const char *name)
212{
213 void *p = NULL;
214 DWORD oldwerr = GetLastError();
215 if (cl->handle == CLIB_DEFHANDLE) { /* Search default libraries. */
216 MSize i;
217 for (i = 0; i < CLIB_HANDLE_MAX; i++) {
218 HINSTANCE h = (HINSTANCE)clib_def_handle[i];
219 if (!(void *)h) { /* Resolve default library handles (once). */
220 switch (i) {
221 case CLIB_HANDLE_EXE: GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, &h); break;
222 case CLIB_HANDLE_DLL:
223 GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
224 (const char *)clib_def_handle, &h);
225 break;
226 case CLIB_HANDLE_CRT:
227 GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
228 (const char *)&_fmode, &h);
229 break;
230 case CLIB_HANDLE_KERNEL32: h = LoadLibraryA("kernel32.dll"); break;
231 case CLIB_HANDLE_USER32: h = LoadLibraryA("user32.dll"); break;
232 case CLIB_HANDLE_GDI32: h = LoadLibraryA("gdi32.dll"); break;
233 }
234 if (!h) continue;
235 clib_def_handle[i] = (void *)h;
236 }
237 p = (void *)GetProcAddress(h, name);
238 if (p) break;
239 }
240 } else {
241 p = (void *)GetProcAddress((HINSTANCE)cl->handle, name);
242 }
243 SetLastError(oldwerr);
244 return p;
245}
246
247#else
248
249#define CLIB_DEFHANDLE NULL
250
251LJ_NORET LJ_NOINLINE static void clib_error(lua_State *L, const char *fmt,
252 const char *name)
253{
254 lj_err_callermsg(L, lj_str_pushf(L, fmt, name, "no support for this OS"));
255}
256
257static void *clib_loadlib(lua_State *L, const char *name, int global)
258{
259 lj_err_callermsg(L, "no support for loading dynamic libraries for this OS");
260 UNUSED(name); UNUSED(global);
261 return NULL;
262}
263
264static void clib_unloadlib(CLibrary *cl)
265{
266 UNUSED(cl);
267}
268
269static void *clib_getsym(CLibrary *cl, const char *name)
270{
271 UNUSED(cl); UNUSED(name);
272 return NULL;
273}
274
275#endif
276
277/* -- C library indexing -------------------------------------------------- */
278
279#if LJ_TARGET_X86 && LJ_ABI_WIN
280/* Compute argument size for fastcall/stdcall functions. */
281static CTSize clib_func_argsize(CTState *cts, CType *ct)
282{
283 CTSize n = 0;
284 while (ct->sib) {
285 CType *d;
286 ct = ctype_get(cts, ct->sib);
287 lua_assert(ctype_isfield(ct->info));
288 d = ctype_rawchild(cts, ct);
289 n += ((d->size + 3) & ~3);
290 }
291 return n;
292}
293#endif
294
295/* Get redirected or mangled external symbol. */
296static const char *clib_extsym(CTState *cts, CType *ct, GCstr *name)
297{
298 if (ct->sib) {
299 CType *ctf = ctype_get(cts, ct->sib);
300 if (ctype_isxattrib(ctf->info, CTA_REDIR))
301 return strdata(gco2str(gcref(ctf->name)));
302 }
303 return strdata(name);
304}
305
306/* Index a C library by name. */
307TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
308{
309 TValue *tv = lj_tab_setstr(L, cl->cache, name);
310 if (LJ_UNLIKELY(tvisnil(tv))) {
311 CTState *cts = ctype_cts(L);
312 CType *ct;
313 CTypeID id = lj_ctype_getname(cts, &ct, name, CLNS_INDEX);
314 if (!id)
315 lj_err_callerv(L, LJ_ERR_FFI_NODECL, strdata(name));
316 if (ctype_isconstval(ct->info)) {
317 CType *ctt = ctype_child(cts, ct);
318 lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4);
319 if ((ctt->info & CTF_UNSIGNED) && (int32_t)ct->size < 0)
320 setnumV(tv, (lua_Number)(uint32_t)ct->size);
321 else
322 setintV(tv, (int32_t)ct->size);
323 } else {
324 const char *sym = clib_extsym(cts, ct, name);
325 void *p = clib_getsym(cl, sym);
326 GCcdata *cd;
327 lua_assert(ctype_isfunc(ct->info) || ctype_isextern(ct->info));
328#if LJ_TARGET_X86 && LJ_ABI_WIN
329 /* Retry with decorated name for fastcall/stdcall functions. */
330 if (!p && ctype_isfunc(ct->info)) {
331 CTInfo cconv = ctype_cconv(ct->info);
332 if (cconv == CTCC_FASTCALL || cconv == CTCC_STDCALL) {
333 CTSize sz = clib_func_argsize(cts, ct);
334 sym = lj_str_pushf(L, cconv == CTCC_FASTCALL ? "@%s@%d" : "_%s@%d",
335 sym, sz);
336 L->top--;
337 p = clib_getsym(cl, sym);
338 }
339 }
340#endif
341 if (!p)
342 clib_error(L, "cannot resolve symbol " LUA_QS ": %s", strdata(name));
343 cd = lj_cdata_new(cts, id, CTSIZE_PTR);
344 *(void **)cdataptr(cd) = p;
345 setcdataV(L, tv, cd);
346 }
347 }
348 return tv;
349}
350
351/* -- C library management ------------------------------------------------ */
352
353/* Create a new CLibrary object and push it on the stack. */
354static CLibrary *clib_new(lua_State *L, GCtab *mt)
355{
356 GCtab *t = lj_tab_new(L, 0, 0);
357 GCudata *ud = lj_udata_new(L, sizeof(CLibrary), t);
358 CLibrary *cl = (CLibrary *)uddata(ud);
359 cl->cache = t;
360 ud->udtype = UDTYPE_FFI_CLIB;
361 /* NOBARRIER: The GCudata is new (marked white). */
362 setgcref(ud->metatable, obj2gco(mt));
363 setudataV(L, L->top++, ud);
364 return cl;
365}
366
367/* Load a C library. */
368void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global)
369{
370 void *handle = clib_loadlib(L, strdata(name), global);
371 CLibrary *cl = clib_new(L, mt);
372 cl->handle = handle;
373}
374
375/* Unload a C library. */
376void lj_clib_unload(CLibrary *cl)
377{
378 clib_unloadlib(cl);
379 cl->handle = NULL;
380}
381
382/* Create the default C library object. */
383void lj_clib_default(lua_State *L, GCtab *mt)
384{
385 CLibrary *cl = clib_new(L, mt);
386 cl->handle = CLIB_DEFHANDLE;
387}
388
389#endif
diff --git a/libraries/luajit-2.0/src/lj_clib.h b/libraries/luajit-2.0/src/lj_clib.h
new file mode 100644
index 0000000..51c3270
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_clib.h
@@ -0,0 +1,29 @@
1/*
2** FFI C library loader.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CLIB_H
7#define _LJ_CLIB_H
8
9#include "lj_obj.h"
10
11#if LJ_HASFFI
12
13/* Namespace for C library indexing. */
14#define CLNS_INDEX ((1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
15
16/* C library namespace. */
17typedef struct CLibrary {
18 void *handle; /* Opaque handle for dynamic library loader. */
19 GCtab *cache; /* Cache for resolved symbols. Anchored in ud->env. */
20} CLibrary;
21
22LJ_FUNC TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name);
23LJ_FUNC void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global);
24LJ_FUNC void lj_clib_unload(CLibrary *cl);
25LJ_FUNC void lj_clib_default(lua_State *L, GCtab *mt);
26
27#endif
28
29#endif
diff --git a/libraries/luajit-2.0/src/lj_cparse.c b/libraries/luajit-2.0/src/lj_cparse.c
new file mode 100644
index 0000000..4f562df
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_cparse.c
@@ -0,0 +1,1839 @@
1/*
2** C declaration parser.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "lj_obj.h"
7
8#if LJ_HASFFI
9
10#include "lj_gc.h"
11#include "lj_err.h"
12#include "lj_str.h"
13#include "lj_ctype.h"
14#include "lj_cparse.h"
15#include "lj_frame.h"
16#include "lj_vm.h"
17#include "lj_char.h"
18
19/*
20** Important note: this is NOT a validating C parser! This is a minimal
21** C declaration parser, solely for use by the LuaJIT FFI.
22**
23** It ought to return correct results for properly formed C declarations,
24** but it may accept some invalid declarations, too (and return nonsense).
25** Also, it shows rather generic error messages to avoid unnecessary bloat.
26** If in doubt, please check the input against your favorite C compiler.
27*/
28
29/* -- C lexer ------------------------------------------------------------- */
30
31/* C lexer token names. */
32static const char *const ctoknames[] = {
33#define CTOKSTR(name, str) str,
34CTOKDEF(CTOKSTR)
35#undef CTOKSTR
36 NULL
37};
38
39/* Forward declaration. */
40LJ_NORET static void cp_err(CPState *cp, ErrMsg em);
41
42static const char *cp_tok2str(CPState *cp, CPToken tok)
43{
44 lua_assert(tok < CTOK_FIRSTDECL);
45 if (tok > CTOK_OFS)
46 return ctoknames[tok-CTOK_OFS-1];
47 else if (!lj_char_iscntrl(tok))
48 return lj_str_pushf(cp->L, "%c", tok);
49 else
50 return lj_str_pushf(cp->L, "char(%d)", tok);
51}
52
53/* End-of-line? */
54static LJ_AINLINE int cp_iseol(CPChar c)
55{
56 return (c == '\n' || c == '\r');
57}
58
59static LJ_AINLINE CPChar cp_get(CPState *cp);
60
61/* Peek next raw character. */
62static LJ_AINLINE CPChar cp_rawpeek(CPState *cp)
63{
64 return (CPChar)(uint8_t)(*cp->p);
65}
66
67/* Transparently skip backslash-escaped line breaks. */
68static LJ_NOINLINE CPChar cp_get_bs(CPState *cp)
69{
70 CPChar c2, c = cp_rawpeek(cp);
71 if (!cp_iseol(c)) return cp->c;
72 cp->p++;
73 c2 = cp_rawpeek(cp);
74 if (cp_iseol(c2) && c2 != c) cp->p++;
75 cp->linenumber++;
76 return cp_get(cp);
77}
78
79/* Get next character. */
80static LJ_AINLINE CPChar cp_get(CPState *cp)
81{
82 cp->c = (CPChar)(uint8_t)(*cp->p++);
83 if (LJ_LIKELY(cp->c != '\\')) return cp->c;
84 return cp_get_bs(cp);
85}
86
87/* Grow save buffer. */
88static LJ_NOINLINE void cp_save_grow(CPState *cp, CPChar c)
89{
90 MSize newsize;
91 if (cp->sb.sz >= CPARSE_MAX_BUF/2)
92 cp_err(cp, LJ_ERR_XELEM);
93 newsize = cp->sb.sz * 2;
94 lj_str_resizebuf(cp->L, &cp->sb, newsize);
95 cp->sb.buf[cp->sb.n++] = (char)c;
96}
97
98/* Save character in buffer. */
99static LJ_AINLINE void cp_save(CPState *cp, CPChar c)
100{
101 if (LJ_UNLIKELY(cp->sb.n + 1 > cp->sb.sz))
102 cp_save_grow(cp, c);
103 else
104 cp->sb.buf[cp->sb.n++] = (char)c;
105}
106
107/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
108static void cp_newline(CPState *cp)
109{
110 CPChar c = cp_rawpeek(cp);
111 if (cp_iseol(c) && c != cp->c) cp->p++;
112 cp->linenumber++;
113}
114
115LJ_NORET static void cp_errmsg(CPState *cp, CPToken tok, ErrMsg em, ...)
116{
117 const char *msg, *tokstr;
118 lua_State *L;
119 va_list argp;
120 if (tok == 0) {
121 tokstr = NULL;
122 } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING ||
123 tok >= CTOK_FIRSTDECL) {
124 cp_save(cp, '\0');
125 tokstr = cp->sb.buf;
126 } else {
127 tokstr = cp_tok2str(cp, tok);
128 }
129 L = cp->L;
130 va_start(argp, em);
131 msg = lj_str_pushvf(L, err2msg(em), argp);
132 va_end(argp);
133 if (tokstr)
134 msg = lj_str_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tokstr);
135 if (cp->linenumber > 1)
136 msg = lj_str_pushf(L, "%s at line %d", msg, cp->linenumber);
137 lj_err_callermsg(L, msg);
138}
139
140LJ_NORET LJ_NOINLINE static void cp_err_token(CPState *cp, CPToken tok)
141{
142 cp_errmsg(cp, cp->tok, LJ_ERR_XTOKEN, cp_tok2str(cp, tok));
143}
144
145LJ_NORET LJ_NOINLINE static void cp_err_badidx(CPState *cp, CType *ct)
146{
147 GCstr *s = lj_ctype_repr(cp->cts->L, ctype_typeid(cp->cts, ct), NULL);
148 cp_errmsg(cp, 0, LJ_ERR_FFI_BADIDX, strdata(s));
149}
150
151LJ_NORET LJ_NOINLINE static void cp_err(CPState *cp, ErrMsg em)
152{
153 cp_errmsg(cp, 0, em);
154}
155
156/* -- Main lexical scanner ------------------------------------------------ */
157
158/* Parse integer literal. */
159static CPToken cp_integer(CPState *cp)
160{
161 uint32_t n = 0;
162 cp->val.id = CTID_INT32;
163 if (cp->c != '0') { /* Decimal. */
164 do {
165 n = n*10 + (cp->c - '0');
166 } while (lj_char_isdigit(cp_get(cp)));
167 } else if ((cp_get(cp)& ~0x20) == 'X') { /* Hexadecimal. */
168 if (!lj_char_isxdigit(cp_get(cp)))
169 cp_err(cp, LJ_ERR_XNUMBER);
170 do {
171 n = n*16 + (cp->c & 15);
172 if (!lj_char_isdigit(cp->c)) n += 9;
173 } while (lj_char_isxdigit(cp_get(cp)));
174 if (n >= 0x80000000u) cp->val.id = CTID_UINT32;
175 } else { /* Octal. */
176 while (cp->c >= '0' && cp->c <= '7') {
177 n = n*8 + (cp->c - '0');
178 cp_get(cp);
179 }
180 if (n >= 0x80000000u) cp->val.id = CTID_UINT32;
181 }
182 cp->val.u32 = n;
183 for (;;) { /* Parse suffixes. */
184 if ((cp->c & ~0x20) == 'U')
185 cp->val.id = CTID_UINT32;
186 else if ((cp->c & ~0x20) != 'L')
187 break;
188 cp_get(cp);
189 }
190 if (lj_char_isident(cp->c) && !(cp->mode & CPARSE_MODE_SKIP))
191 cp_errmsg(cp, cp->c, LJ_ERR_XNUMBER);
192 return CTOK_INTEGER;
193}
194
195/* Parse identifier or keyword. */
196static CPToken cp_ident(CPState *cp)
197{
198 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
199 cp->str = lj_str_new(cp->L, cp->sb.buf, cp->sb.n);
200 cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask);
201 if (ctype_type(cp->ct->info) == CT_KW)
202 return ctype_cid(cp->ct->info);
203 return CTOK_IDENT;
204}
205
206/* Parse string or character constant. */
207static CPToken cp_string(CPState *cp)
208{
209 CPChar delim = cp->c;
210 cp_get(cp);
211 while (cp->c != delim) {
212 CPChar c = cp->c;
213 if (c == '\0') cp_errmsg(cp, CTOK_EOF, LJ_ERR_XSTR);
214 if (c == '\\') {
215 c = cp_get(cp);
216 switch (c) {
217 case '\0': cp_errmsg(cp, CTOK_EOF, LJ_ERR_XSTR); break;
218 case 'a': c = '\a'; break;
219 case 'b': c = '\b'; break;
220 case 'f': c = '\f'; break;
221 case 'n': c = '\n'; break;
222 case 'r': c = '\r'; break;
223 case 't': c = '\t'; break;
224 case 'v': c = '\v'; break;
225 case 'e': c = 27; break;
226 case 'x':
227 c = 0;
228 while (lj_char_isxdigit(cp_get(cp)))
229 c = (c<<4) + (lj_char_isdigit(cp->c) ? cp->c-'0' : (cp->c&15)+9);
230 cp_save(cp, (c & 0xff));
231 continue;
232 default:
233 if (lj_char_isdigit(c)) {
234 c -= '0';
235 if (lj_char_isdigit(cp_get(cp))) {
236 c = c*8 + (cp->c - '0');
237 if (lj_char_isdigit(cp_get(cp))) {
238 c = c*8 + (cp->c - '0');
239 cp_get(cp);
240 }
241 }
242 cp_save(cp, (c & 0xff));
243 continue;
244 }
245 break;
246 }
247 }
248 cp_save(cp, c);
249 cp_get(cp);
250 }
251 cp_get(cp);
252 if (delim == '"') {
253 cp->str = lj_str_new(cp->L, cp->sb.buf, cp->sb.n);
254 return CTOK_STRING;
255 } else {
256 if (cp->sb.n != 1) cp_err_token(cp, '\'');
257 cp->val.i32 = (int32_t)(char)cp->sb.buf[0];
258 cp->val.id = CTID_INT32;
259 return CTOK_INTEGER;
260 }
261}
262
263/* Skip C comment. */
264static void cp_comment_c(CPState *cp)
265{
266 do {
267 if (cp_get(cp) == '*') {
268 do {
269 if (cp_get(cp) == '/') { cp_get(cp); return; }
270 } while (cp->c == '*');
271 }
272 if (cp_iseol(cp->c)) cp_newline(cp);
273 } while (cp->c != '\0');
274}
275
276/* Skip C++ comment. */
277static void cp_comment_cpp(CPState *cp)
278{
279 while (!cp_iseol(cp_get(cp)) && cp->c != '\0')
280 ;
281}
282
283/* Lexical scanner for C. Only a minimal subset is implemented. */
284static CPToken cp_next_(CPState *cp)
285{
286 lj_str_resetbuf(&cp->sb);
287 for (;;) {
288 if (lj_char_isident(cp->c))
289 return lj_char_isdigit(cp->c) ? cp_integer(cp) : cp_ident(cp);
290 switch (cp->c) {
291 case '\n': case '\r': cp_newline(cp); /* fallthrough. */
292 case ' ': case '\t': case '\v': case '\f': cp_get(cp); break;
293 case '"': case '\'': return cp_string(cp);
294 case '/':
295 cp_get(cp);
296 if (cp->c == '*') cp_comment_c(cp);
297 else if (cp->c == '/') cp_comment_cpp(cp);
298 else return '/';
299 break;
300 case '|':
301 cp_get(cp); if (cp->c != '|') return '|'; cp_get(cp); return CTOK_OROR;
302 case '&':
303 cp_get(cp); if (cp->c != '&') return '&'; cp_get(cp); return CTOK_ANDAND;
304 case '=':
305 cp_get(cp); if (cp->c != '=') return '='; cp_get(cp); return CTOK_EQ;
306 case '!':
307 cp_get(cp); if (cp->c != '=') return '!'; cp_get(cp); return CTOK_NE;
308 case '<':
309 cp_get(cp);
310 if (cp->c == '=') { cp_get(cp); return CTOK_LE; }
311 else if (cp->c == '<') { cp_get(cp); return CTOK_SHL; }
312 return '<';
313 case '>':
314 cp_get(cp);
315 if (cp->c == '=') { cp_get(cp); return CTOK_GE; }
316 else if (cp->c == '>') { cp_get(cp); return CTOK_SHR; }
317 return '>';
318 case '-':
319 cp_get(cp); if (cp->c != '>') return '-'; cp_get(cp); return CTOK_DEREF;
320 case '\0': return CTOK_EOF;
321 default: { CPToken c = cp->c; cp_get(cp); return c; }
322 }
323 }
324}
325
326static LJ_NOINLINE CPToken cp_next(CPState *cp)
327{
328 return (cp->tok = cp_next_(cp));
329}
330
331/* -- C parser ------------------------------------------------------------ */
332
333/* Namespaces for resolving identifiers. */
334#define CPNS_DEFAULT \
335 ((1u<<CT_KW)|(1u<<CT_TYPEDEF)|(1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
336#define CPNS_STRUCT ((1u<<CT_KW)|(1u<<CT_STRUCT)|(1u<<CT_ENUM))
337
338typedef CTypeID CPDeclIdx; /* Index into declaration stack. */
339typedef uint32_t CPscl; /* Storage class flags. */
340
341/* Type declaration context. */
342typedef struct CPDecl {
343 CPDeclIdx top; /* Top of declaration stack. */
344 CPDeclIdx pos; /* Insertion position in declaration chain. */
345 CPDeclIdx specpos; /* Saved position for declaration specifier. */
346 uint32_t mode; /* Declarator mode. */
347 CPState *cp; /* C parser state. */
348 GCstr *name; /* Name of declared identifier (if direct). */
349 GCstr *redir; /* Redirected symbol name. */
350 CTypeID nameid; /* Existing typedef for declared identifier. */
351 CTInfo attr; /* Attributes. */
352 CTInfo fattr; /* Function attributes. */
353 CTInfo specattr; /* Saved attributes. */
354 CTInfo specfattr; /* Saved function attributes. */
355 CTSize bits; /* Field size in bits (if any). */
356 CType stack[CPARSE_MAX_DECLSTACK]; /* Type declaration stack. */
357} CPDecl;
358
359/* Forward declarations. */
360static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl);
361static void cp_declarator(CPState *cp, CPDecl *decl);
362static CTypeID cp_decl_abstract(CPState *cp);
363
364/* Initialize C parser state. Caller must set up: L, p, srcname, mode. */
365static void cp_init(CPState *cp)
366{
367 cp->linenumber = 1;
368 cp->depth = 0;
369 cp->curpack = 0;
370 cp->packstack[0] = 255;
371 lj_str_initbuf(&cp->sb);
372 lj_str_resizebuf(cp->L, &cp->sb, LJ_MIN_SBUF);
373 lua_assert(cp->p != NULL);
374 cp_get(cp); /* Read-ahead first char. */
375 cp->tok = 0;
376 cp->tmask = CPNS_DEFAULT;
377 cp_next(cp); /* Read-ahead first token. */
378}
379
380/* Cleanup C parser state. */
381static void cp_cleanup(CPState *cp)
382{
383 global_State *g = G(cp->L);
384 lj_str_freebuf(g, &cp->sb);
385}
386
387/* Check and consume optional token. */
388static int cp_opt(CPState *cp, CPToken tok)
389{
390 if (cp->tok == tok) { cp_next(cp); return 1; }
391 return 0;
392}
393
394/* Check and consume token. */
395static void cp_check(CPState *cp, CPToken tok)
396{
397 if (cp->tok != tok) cp_err_token(cp, tok);
398 cp_next(cp);
399}
400
401/* Check if the next token may start a type declaration. */
402static int cp_istypedecl(CPState *cp)
403{
404 if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECL) return 1;
405 if (cp->tok == CTOK_IDENT && ctype_istypedef(cp->ct->info)) return 1;
406 return 0;
407}
408
409/* -- Constant expression evaluator --------------------------------------- */
410
411/* Forward declarations. */
412static void cp_expr_unary(CPState *cp, CPValue *k);
413static void cp_expr_sub(CPState *cp, CPValue *k, int pri);
414
415/* Please note that type handling is very weak here. Most ops simply
416** assume integer operands. Accessors are only needed to compute types and
417** return synthetic values. The only purpose of the expression evaluator
418** is to compute the values of constant expressions one would typically
419** find in C header files. And again: this is NOT a validating C parser!
420*/
421
422/* Parse comma separated expression and return last result. */
423static void cp_expr_comma(CPState *cp, CPValue *k)
424{
425 do { cp_expr_sub(cp, k, 0); } while (cp_opt(cp, ','));
426}
427
428/* Parse sizeof/alignof operator. */
429static void cp_expr_sizeof(CPState *cp, CPValue *k, int wantsz)
430{
431 CTSize sz;
432 CTInfo info;
433 if (cp_opt(cp, '(')) {
434 if (cp_istypedecl(cp))
435 k->id = cp_decl_abstract(cp);
436 else
437 cp_expr_comma(cp, k);
438 cp_check(cp, ')');
439 } else {
440 cp_expr_unary(cp, k);
441 }
442 info = lj_ctype_info(cp->cts, k->id, &sz);
443 if (wantsz) {
444 if (sz != CTSIZE_INVALID)
445 k->u32 = sz;
446 else if (k->id != CTID_A_CCHAR) /* Special case for sizeof("string"). */
447 cp_err(cp, LJ_ERR_FFI_INVSIZE);
448 } else {
449 k->u32 = 1u << ctype_align(info);
450 }
451 k->id = CTID_UINT32; /* Really size_t. */
452}
453
454/* Parse prefix operators. */
455static void cp_expr_prefix(CPState *cp, CPValue *k)
456{
457 if (cp->tok == CTOK_INTEGER) {
458 *k = cp->val; cp_next(cp);
459 } else if (cp_opt(cp, '+')) {
460 cp_expr_unary(cp, k); /* Nothing to do (well, integer promotion). */
461 } else if (cp_opt(cp, '-')) {
462 cp_expr_unary(cp, k); k->i32 = -k->i32;
463 } else if (cp_opt(cp, '~')) {
464 cp_expr_unary(cp, k); k->i32 = ~k->i32;
465 } else if (cp_opt(cp, '!')) {
466 cp_expr_unary(cp, k); k->i32 = !k->i32; k->id = CTID_INT32;
467 } else if (cp_opt(cp, '(')) {
468 if (cp_istypedecl(cp)) { /* Cast operator. */
469 CTypeID id = cp_decl_abstract(cp);
470 cp_check(cp, ')');
471 cp_expr_unary(cp, k);
472 k->id = id; /* No conversion performed. */
473 } else { /* Sub-expression. */
474 cp_expr_comma(cp, k);
475 cp_check(cp, ')');
476 }
477 } else if (cp_opt(cp, '*')) { /* Indirection. */
478 CType *ct;
479 cp_expr_unary(cp, k);
480 ct = lj_ctype_rawref(cp->cts, k->id);
481 if (!ctype_ispointer(ct->info))
482 cp_err_badidx(cp, ct);
483 k->u32 = 0; k->id = ctype_cid(ct->info);
484 } else if (cp_opt(cp, '&')) { /* Address operator. */
485 cp_expr_unary(cp, k);
486 k->id = lj_ctype_intern(cp->cts, CTINFO(CT_PTR, CTALIGN_PTR+k->id),
487 CTSIZE_PTR);
488 } else if (cp_opt(cp, CTOK_SIZEOF)) {
489 cp_expr_sizeof(cp, k, 1);
490 } else if (cp_opt(cp, CTOK_ALIGNOF)) {
491 cp_expr_sizeof(cp, k, 0);
492 } else if (cp->tok == CTOK_IDENT) {
493 if (ctype_type(cp->ct->info) == CT_CONSTVAL) {
494 k->u32 = cp->ct->size; k->id = ctype_cid(cp->ct->info);
495 } else if (ctype_type(cp->ct->info) == CT_EXTERN) {
496 k->u32 = cp->val.id; k->id = ctype_cid(cp->ct->info);
497 } else if (ctype_type(cp->ct->info) == CT_FUNC) {
498 k->u32 = cp->val.id; k->id = cp->val.id;
499 } else {
500 goto err_expr;
501 }
502 cp_next(cp);
503 } else if (cp->tok == CTOK_STRING) {
504 CTSize sz = cp->str->len;
505 while (cp_next(cp) == CTOK_STRING)
506 sz += cp->str->len;
507 k->u32 = sz + 1;
508 k->id = CTID_A_CCHAR;
509 } else {
510 err_expr:
511 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
512 }
513}
514
515/* Parse postfix operators. */
516static void cp_expr_postfix(CPState *cp, CPValue *k)
517{
518 for (;;) {
519 CType *ct;
520 if (cp_opt(cp, '[')) { /* Array/pointer index. */
521 CPValue k2;
522 cp_expr_comma(cp, &k2);
523 ct = lj_ctype_rawref(cp->cts, k->id);
524 if (!ctype_ispointer(ct->info)) {
525 ct = lj_ctype_rawref(cp->cts, k2.id);
526 if (!ctype_ispointer(ct->info))
527 cp_err_badidx(cp, ct);
528 }
529 cp_check(cp, ']');
530 k->u32 = 0;
531 } else if (cp->tok == '.' || cp->tok == CTOK_DEREF) { /* Struct deref. */
532 CTSize ofs;
533 CType *fct;
534 ct = lj_ctype_rawref(cp->cts, k->id);
535 if (cp->tok == CTOK_DEREF) {
536 if (!ctype_ispointer(ct->info))
537 cp_err_badidx(cp, ct);
538 ct = lj_ctype_rawref(cp->cts, ctype_cid(ct->info));
539 }
540 cp_next(cp);
541 if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
542 if (!ctype_isstruct(ct->info) || ct->size == CTSIZE_INVALID ||
543 !(fct = lj_ctype_getfield(cp->cts, ct, cp->str, &ofs)) ||
544 ctype_isbitfield(fct->info)) {
545 GCstr *s = lj_ctype_repr(cp->cts->L, ctype_typeid(cp->cts, ct), NULL);
546 cp_errmsg(cp, 0, LJ_ERR_FFI_BADMEMBER, strdata(s), strdata(cp->str));
547 }
548 ct = fct;
549 k->u32 = ctype_isconstval(ct->info) ? ct->size : 0;
550 cp_next(cp);
551 } else {
552 return;
553 }
554 k->id = ctype_cid(ct->info);
555 }
556}
557
558/* Parse infix operators. */
559static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
560{
561 CPValue k2;
562 k2.u32 = 0; k2.id = 0; /* Silence the compiler. */
563 for (;;) {
564 switch (pri) {
565 case 0:
566 if (cp_opt(cp, '?')) {
567 CPValue k3;
568 cp_expr_comma(cp, &k2); /* Right-associative. */
569 cp_check(cp, ':');
570 cp_expr_sub(cp, &k3, 0);
571 k->u32 = k->u32 ? k2.u32 : k3.u32;
572 k->id = k2.id > k3.id ? k2.id : k3.id;
573 continue;
574 }
575 case 1:
576 if (cp_opt(cp, CTOK_OROR)) {
577 cp_expr_sub(cp, &k2, 2); k->i32 = k->u32 || k2.u32; k->id = CTID_INT32;
578 continue;
579 }
580 case 2:
581 if (cp_opt(cp, CTOK_ANDAND)) {
582 cp_expr_sub(cp, &k2, 3); k->i32 = k->u32 && k2.u32; k->id = CTID_INT32;
583 continue;
584 }
585 case 3:
586 if (cp_opt(cp, '|')) {
587 cp_expr_sub(cp, &k2, 4); k->u32 = k->u32 | k2.u32; goto arith_result;
588 }
589 case 4:
590 if (cp_opt(cp, '^')) {
591 cp_expr_sub(cp, &k2, 5); k->u32 = k->u32 ^ k2.u32; goto arith_result;
592 }
593 case 5:
594 if (cp_opt(cp, '&')) {
595 cp_expr_sub(cp, &k2, 6); k->u32 = k->u32 & k2.u32; goto arith_result;
596 }
597 case 6:
598 if (cp_opt(cp, CTOK_EQ)) {
599 cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 == k2.u32; k->id = CTID_INT32;
600 continue;
601 } else if (cp_opt(cp, CTOK_NE)) {
602 cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 != k2.u32; k->id = CTID_INT32;
603 continue;
604 }
605 case 7:
606 if (cp_opt(cp, '<')) {
607 cp_expr_sub(cp, &k2, 8);
608 if (k->id == CTID_INT32 && k2.id == CTID_INT32)
609 k->i32 = k->i32 < k2.i32;
610 else
611 k->i32 = k->u32 < k2.u32;
612 k->id = CTID_INT32;
613 continue;
614 } else if (cp_opt(cp, '>')) {
615 cp_expr_sub(cp, &k2, 8);
616 if (k->id == CTID_INT32 && k2.id == CTID_INT32)
617 k->i32 = k->i32 > k2.i32;
618 else
619 k->i32 = k->u32 > k2.u32;
620 k->id = CTID_INT32;
621 continue;
622 } else if (cp_opt(cp, CTOK_LE)) {
623 cp_expr_sub(cp, &k2, 8);
624 if (k->id == CTID_INT32 && k2.id == CTID_INT32)
625 k->i32 = k->i32 <= k2.i32;
626 else
627 k->i32 = k->u32 <= k2.u32;
628 k->id = CTID_INT32;
629 continue;
630 } else if (cp_opt(cp, CTOK_GE)) {
631 cp_expr_sub(cp, &k2, 8);
632 if (k->id == CTID_INT32 && k2.id == CTID_INT32)
633 k->i32 = k->i32 >= k2.i32;
634 else
635 k->i32 = k->u32 >= k2.u32;
636 k->id = CTID_INT32;
637 continue;
638 }
639 case 8:
640 if (cp_opt(cp, CTOK_SHL)) {
641 cp_expr_sub(cp, &k2, 9); k->u32 = k->u32 << k2.u32;
642 continue;
643 } else if (cp_opt(cp, CTOK_SHR)) {
644 cp_expr_sub(cp, &k2, 9);
645 if (k->id == CTID_INT32)
646 k->i32 = k->i32 >> k2.i32;
647 else
648 k->u32 = k->u32 >> k2.u32;
649 continue;
650 }
651 case 9:
652 if (cp_opt(cp, '+')) {
653 cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 + k2.u32;
654 arith_result:
655 if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
656 continue;
657 } else if (cp_opt(cp, '-')) {
658 cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 - k2.u32; goto arith_result;
659 }
660 case 10:
661 if (cp_opt(cp, '*')) {
662 cp_expr_unary(cp, &k2); k->u32 = k->u32 * k2.u32; goto arith_result;
663 } else if (cp_opt(cp, '/')) {
664 cp_expr_unary(cp, &k2);
665 if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
666 if (k2.u32 == 0 ||
667 (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
668 cp_err(cp, LJ_ERR_BADVAL);
669 if (k->id == CTID_INT32)
670 k->i32 = k->i32 / k2.i32;
671 else
672 k->u32 = k->u32 / k2.u32;
673 continue;
674 } else if (cp_opt(cp, '%')) {
675 cp_expr_unary(cp, &k2);
676 if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
677 if (k2.u32 == 0 ||
678 (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
679 cp_err(cp, LJ_ERR_BADVAL);
680 if (k->id == CTID_INT32)
681 k->i32 = k->i32 % k2.i32;
682 else
683 k->u32 = k->u32 % k2.u32;
684 continue;
685 }
686 default:
687 return;
688 }
689 }
690}
691
692/* Parse and evaluate unary expression. */
693static void cp_expr_unary(CPState *cp, CPValue *k)
694{
695 if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS);
696 cp_expr_prefix(cp, k);
697 cp_expr_postfix(cp, k);
698 cp->depth--;
699}
700
701/* Parse and evaluate sub-expression. */
702static void cp_expr_sub(CPState *cp, CPValue *k, int pri)
703{
704 cp_expr_unary(cp, k);
705 cp_expr_infix(cp, k, pri);
706}
707
708/* Parse constant integer expression. */
709static void cp_expr_kint(CPState *cp, CPValue *k)
710{
711 CType *ct;
712 cp_expr_sub(cp, k, 0);
713 ct = ctype_raw(cp->cts, k->id);
714 if (!ctype_isinteger(ct->info)) cp_err(cp, LJ_ERR_BADVAL);
715}
716
717/* Parse (non-negative) size expression. */
718static CTSize cp_expr_ksize(CPState *cp)
719{
720 CPValue k;
721 cp_expr_kint(cp, &k);
722 if (k.u32 >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE);
723 return k.u32;
724}
725
726/* -- Type declaration stack management ----------------------------------- */
727
728/* Add declaration element behind the insertion position. */
729static CPDeclIdx cp_add(CPDecl *decl, CTInfo info, CTSize size)
730{
731 CPDeclIdx top = decl->top;
732 if (top >= CPARSE_MAX_DECLSTACK) cp_err(decl->cp, LJ_ERR_XLEVELS);
733 decl->stack[top].info = info;
734 decl->stack[top].size = size;
735 decl->stack[top].sib = 0;
736 setgcrefnull(decl->stack[top].name);
737 decl->stack[top].next = decl->stack[decl->pos].next;
738 decl->stack[decl->pos].next = (CTypeID1)top;
739 decl->top = top+1;
740 return top;
741}
742
743/* Push declaration element before the insertion position. */
744static CPDeclIdx cp_push(CPDecl *decl, CTInfo info, CTSize size)
745{
746 return (decl->pos = cp_add(decl, info, size));
747}
748
749/* Push or merge attributes. */
750static void cp_push_attributes(CPDecl *decl)
751{
752 CType *ct = &decl->stack[decl->pos];
753 if (ctype_isfunc(ct->info)) { /* Ok to modify in-place. */
754#if LJ_TARGET_X86
755 if ((decl->fattr & CTFP_CCONV))
756 ct->info = (ct->info & (CTMASK_NUM|CTF_VARARG|CTMASK_CID)) +
757 (decl->fattr & ~CTMASK_CID);
758#endif
759 } else {
760 if ((decl->attr & CTFP_ALIGNED) && !(decl->mode & CPARSE_MODE_FIELD))
761 cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_ALIGN)),
762 ctype_align(decl->attr));
763 }
764}
765
766/* Push unrolled type to declaration stack and merge qualifiers. */
767static void cp_push_type(CPDecl *decl, CTypeID id)
768{
769 CType *ct = ctype_get(decl->cp->cts, id);
770 CTInfo info = ct->info;
771 CTSize size = ct->size;
772 switch (ctype_type(info)) {
773 case CT_STRUCT: case CT_ENUM:
774 cp_push(decl, CTINFO(CT_TYPEDEF, id), 0); /* Don't copy unique types. */
775 if ((decl->attr & CTF_QUAL)) { /* Push unmerged qualifiers. */
776 cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_QUAL)),
777 (decl->attr & CTF_QUAL));
778 decl->attr &= ~CTF_QUAL;
779 }
780 break;
781 case CT_ATTRIB:
782 if (ctype_isxattrib(info, CTA_QUAL))
783 decl->attr &= ~size; /* Remove redundant qualifiers. */
784 cp_push_type(decl, ctype_cid(info)); /* Unroll. */
785 cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */
786 break;
787 case CT_ARRAY:
788 cp_push_type(decl, ctype_cid(info)); /* Unroll. */
789 cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */
790 decl->stack[decl->pos].sib = 1; /* Mark as already checked and sized. */
791 /* Note: this is not copied to the ct->sib in the C type table. */
792 break;
793 case CT_FUNC:
794 /* Copy type, link parameters (shared). */
795 decl->stack[cp_push(decl, info, size)].sib = ct->sib;
796 break;
797 default:
798 /* Copy type, merge common qualifiers. */
799 cp_push(decl, info|(decl->attr & CTF_QUAL), size);
800 decl->attr &= ~CTF_QUAL;
801 break;
802 }
803}
804
805/* Consume the declaration element chain and intern the C type. */
806static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl)
807{
808 CTypeID id = 0;
809 CPDeclIdx idx = 0;
810 CTSize csize = CTSIZE_INVALID;
811 CTSize cinfo = 0;
812 do {
813 CType *ct = &decl->stack[idx];
814 CTInfo info = ct->info;
815 CTInfo size = ct->size;
816 /* The cid is already part of info for copies of pointers/functions. */
817 idx = ct->next;
818 if (ctype_istypedef(info)) {
819 lua_assert(id == 0);
820 id = ctype_cid(info);
821 /* Always refetch info/size, since struct/enum may have been completed. */
822 cinfo = ctype_get(cp->cts, id)->info;
823 csize = ctype_get(cp->cts, id)->size;
824 lua_assert(ctype_isstruct(cinfo) || ctype_isenum(cinfo));
825 } else if (ctype_isfunc(info)) { /* Intern function. */
826 CType *fct;
827 CTypeID fid;
828 CTypeID sib;
829 if (id) {
830 CType *refct = ctype_raw(cp->cts, id);
831 /* Reject function or refarray return types. */
832 if (ctype_isfunc(refct->info) || ctype_isrefarray(refct->info))
833 cp_err(cp, LJ_ERR_FFI_INVTYPE);
834 }
835 /* No intervening attributes allowed, skip forward. */
836 while (idx) {
837 CType *ctn = &decl->stack[idx];
838 if (!ctype_isattrib(ctn->info)) break;
839 idx = ctn->next; /* Skip attribute. */
840 }
841 sib = ct->sib; /* Next line may reallocate the C type table. */
842 fid = lj_ctype_new(cp->cts, &fct);
843 csize = CTSIZE_INVALID;
844 fct->info = cinfo = info + id;
845 fct->size = size;
846 fct->sib = sib;
847 id = fid;
848 } else if (ctype_isattrib(info)) {
849 if (ctype_isxattrib(info, CTA_QUAL))
850 cinfo |= size;
851 else if (ctype_isxattrib(info, CTA_ALIGN))
852 CTF_INSERT(cinfo, ALIGN, size);
853 id = lj_ctype_intern(cp->cts, info+id, size);
854 /* Inherit csize/cinfo from original type. */
855 } else {
856 if (ctype_isnum(info)) { /* Handle mode/vector-size attributes. */
857 lua_assert(id == 0);
858 if (!(info & CTF_BOOL)) {
859 CTSize msize = ctype_msizeP(decl->attr);
860 CTSize vsize = ctype_vsizeP(decl->attr);
861 if (msize && (!(info & CTF_FP) || (msize == 4 || msize == 8))) {
862 CTSize malign = lj_fls(msize);
863 if (malign > 4) malign = 4; /* Limit alignment. */
864 CTF_INSERT(info, ALIGN, malign);
865 size = msize; /* Override size via mode. */
866 }
867 if (vsize) { /* Vector size set? */
868 CTSize esize = lj_fls(size);
869 if (vsize >= esize) {
870 /* Intern the element type first. */
871 id = lj_ctype_intern(cp->cts, info, size);
872 /* Then create a vector (array) with vsize alignment. */
873 size = (1u << vsize);
874 if (vsize > 4) vsize = 4; /* Limit alignment. */
875 if (ctype_align(info) > vsize) vsize = ctype_align(info);
876 info = CTINFO(CT_ARRAY, (info & CTF_QUAL) + CTF_VECTOR +
877 CTALIGN(vsize));
878 }
879 }
880 }
881 } else if (ctype_isptr(info)) {
882 /* Reject pointer/ref to ref. */
883 if (id && ctype_isref(ctype_raw(cp->cts, id)->info))
884 cp_err(cp, LJ_ERR_FFI_INVTYPE);
885 if (ctype_isref(info)) {
886 info &= ~CTF_VOLATILE; /* Refs are always const, never volatile. */
887 /* No intervening attributes allowed, skip forward. */
888 while (idx) {
889 CType *ctn = &decl->stack[idx];
890 if (!ctype_isattrib(ctn->info)) break;
891 idx = ctn->next; /* Skip attribute. */
892 }
893 }
894 } else if (ctype_isarray(info)) { /* Check for valid array size etc. */
895 if (ct->sib == 0) { /* Only check/size arrays not copied by unroll. */
896 if (ctype_isref(cinfo)) /* Reject arrays of refs. */
897 cp_err(cp, LJ_ERR_FFI_INVTYPE);
898 /* Reject VLS or unknown-sized types. */
899 if (ctype_isvltype(cinfo) || csize == CTSIZE_INVALID)
900 cp_err(cp, LJ_ERR_FFI_INVSIZE);
901 /* a[] and a[?] keep their invalid size. */
902 if (size != CTSIZE_INVALID) {
903 uint64_t xsz = (uint64_t)size * csize;
904 if (xsz >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE);
905 size = (CTSize)xsz;
906 }
907 }
908 info |= (cinfo & (CTF_QUAL|CTF_ALIGN)); /* Inherit qual and align. */
909 } else {
910 lua_assert(ctype_isvoid(info));
911 }
912 csize = size;
913 cinfo = info+id;
914 id = lj_ctype_intern(cp->cts, info+id, size);
915 }
916 } while (idx);
917 return id;
918}
919
920/* -- C declaration parser ------------------------------------------------ */
921
922#define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be)
923
924/* Reset declaration state to declaration specifier. */
925static void cp_decl_reset(CPDecl *decl)
926{
927 decl->pos = decl->specpos;
928 decl->top = decl->specpos+1;
929 decl->stack[decl->specpos].next = 0;
930 decl->attr = decl->specattr;
931 decl->fattr = decl->specfattr;
932 decl->name = NULL;
933 decl->redir = NULL;
934}
935
936/* Parse constant initializer. */
937/* NYI: FP constants and strings as initializers. */
938static CTypeID cp_decl_constinit(CPState *cp, CType **ctp, CTypeID typeid)
939{
940 CType *ctt = ctype_get(cp->cts, typeid);
941 CTInfo info;
942 CTSize size;
943 CPValue k;
944 CTypeID constid;
945 while (ctype_isattrib(ctt->info)) { /* Skip attributes. */
946 typeid = ctype_cid(ctt->info); /* Update ID, too. */
947 ctt = ctype_get(cp->cts, typeid);
948 }
949 info = ctt->info;
950 size = ctt->size;
951 if (!ctype_isinteger(info) || !(info & CTF_CONST) || size > 4)
952 cp_err(cp, LJ_ERR_FFI_INVTYPE);
953 cp_check(cp, '=');
954 cp_expr_sub(cp, &k, 0);
955 constid = lj_ctype_new(cp->cts, ctp);
956 (*ctp)->info = CTINFO(CT_CONSTVAL, CTF_CONST|typeid);
957 k.u32 <<= 8*(4-size);
958 if ((info & CTF_UNSIGNED))
959 k.u32 >>= 8*(4-size);
960 else
961 k.u32 = (uint32_t)((int32_t)k.u32 >> 8*(4-size));
962 (*ctp)->size = k.u32;
963 return constid;
964}
965
966/* Parse size in parentheses as part of attribute. */
967static CTSize cp_decl_sizeattr(CPState *cp)
968{
969 CTSize sz;
970 uint32_t oldtmask = cp->tmask;
971 cp->tmask = CPNS_DEFAULT; /* Required for expression evaluator. */
972 cp_check(cp, '(');
973 sz = cp_expr_ksize(cp);
974 cp->tmask = oldtmask;
975 cp_check(cp, ')');
976 return sz;
977}
978
979/* Parse alignment attribute. */
980static void cp_decl_align(CPState *cp, CPDecl *decl)
981{
982 CTSize al = 4; /* Unspecified alignment is 16 bytes. */
983 if (cp->tok == '(') {
984 al = cp_decl_sizeattr(cp);
985 al = al ? lj_fls(al) : 0;
986 }
987 CTF_INSERT(decl->attr, ALIGN, al);
988 decl->attr |= CTFP_ALIGNED;
989}
990
991/* Parse GCC asm("name") redirect. */
992static void cp_decl_asm(CPState *cp, CPDecl *decl)
993{
994 UNUSED(decl);
995 cp_next(cp);
996 cp_check(cp, '(');
997 if (cp->tok == CTOK_STRING) {
998 GCstr *str = cp->str;
999 while (cp_next(cp) == CTOK_STRING) {
1000 lj_str_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str));
1001 cp->L->top--;
1002 str = strV(cp->L->top);
1003 }
1004 decl->redir = str;
1005 }
1006 cp_check(cp, ')');
1007}
1008
1009/* Parse GCC __attribute__((mode(...))). */
1010static void cp_decl_mode(CPState *cp, CPDecl *decl)
1011{
1012 cp_check(cp, '(');
1013 if (cp->tok == CTOK_IDENT) {
1014 const char *s = strdata(cp->str);
1015 CTSize sz = 0, vlen = 0;
1016 if (s[0] == '_' && s[1] == '_') s += 2;
1017 if (*s == 'V') {
1018 s++;
1019 vlen = *s++ - '0';
1020 if (*s >= '0' && *s <= '9')
1021 vlen = vlen*10 + (*s++ - '0');
1022 }
1023 switch (*s++) {
1024 case 'Q': sz = 1; break;
1025 case 'H': sz = 2; break;
1026 case 'S': sz = 4; break;
1027 case 'D': sz = 8; break;
1028 case 'T': sz = 16; break;
1029 case 'O': sz = 32; break;
1030 default: goto bad_size;
1031 }
1032 if (*s == 'I' || *s == 'F') {
1033 CTF_INSERT(decl->attr, MSIZEP, sz);
1034 if (vlen) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vlen*sz));
1035 }
1036 bad_size:
1037 cp_next(cp);
1038 }
1039 cp_check(cp, ')');
1040}
1041
1042/* Parse GCC __attribute__((...)). */
1043static void cp_decl_gccattribute(CPState *cp, CPDecl *decl)
1044{
1045 cp_next(cp);
1046 cp_check(cp, '(');
1047 cp_check(cp, '(');
1048 while (cp->tok != ')') {
1049 if (cp->tok == CTOK_IDENT) {
1050 GCstr *attrstr = cp->str;
1051 cp_next(cp);
1052 switch (attrstr->hash) {
1053 case H_(64a9208e,8ce14319): case H_(8e6331b2,95a282af): /* aligned */
1054 cp_decl_align(cp, decl);
1055 break;
1056 case H_(42eb47de,f0ede26c): case H_(29f48a09,cf383e0c): /* packed */
1057 decl->attr |= CTFP_PACKED;
1058 break;
1059 case H_(0a84eef6,8dfab04c): case H_(995cf92c,d5696591): /* mode */
1060 cp_decl_mode(cp, decl);
1061 break;
1062 case H_(0ab31997,2d5213fa): case H_(bf875611,200e9990): /* vector_size */
1063 {
1064 CTSize vsize = cp_decl_sizeattr(cp);
1065 if (vsize) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vsize));
1066 }
1067 break;
1068#if LJ_TARGET_X86
1069 case H_(5ad22db8,c689b848): case H_(439150fa,65ea78cb): /* regparm */
1070 CTF_INSERT(decl->fattr, REGPARM, cp_decl_sizeattr(cp));
1071 decl->fattr |= CTFP_CCONV;
1072 break;
1073 case H_(18fc0b98,7ff4c074): case H_(4e62abed,0a747424): /* cdecl */
1074 CTF_INSERT(decl->fattr, CCONV, CTCC_CDECL);
1075 decl->fattr |= CTFP_CCONV;
1076 break;
1077 case H_(72b2e41b,494c5a44): case H_(f2356d59,f25fc9bd): /* thiscall */
1078 CTF_INSERT(decl->fattr, CCONV, CTCC_THISCALL);
1079 decl->fattr |= CTFP_CCONV;
1080 break;
1081 case H_(0d0ffc42,ab746f88): case H_(21c54ba1,7f0ca7e3): /* fastcall */
1082 CTF_INSERT(decl->fattr, CCONV, CTCC_FASTCALL);
1083 decl->fattr |= CTFP_CCONV;
1084 break;
1085 case H_(ef76b040,9412e06a): case H_(de56697b,c750e6e1): /* stdcall */
1086 CTF_INSERT(decl->fattr, CCONV, CTCC_STDCALL);
1087 decl->fattr |= CTFP_CCONV;
1088 break;
1089 case H_(ea78b622,f234bd8e): case H_(252ffb06,8d50f34b): /* sseregparm */
1090 decl->fattr |= CTF_SSEREGPARM;
1091 decl->fattr |= CTFP_CCONV;
1092 break;
1093#endif
1094 default: /* Skip all other attributes. */
1095 goto skip_attr;
1096 }
1097 } else if (cp->tok >= CTOK_FIRSTDECL) { /* For __attribute((const)) etc. */
1098 cp_next(cp);
1099 skip_attr:
1100 if (cp_opt(cp, '(')) {
1101 while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
1102 cp_check(cp, ')');
1103 }
1104 } else {
1105 break;
1106 }
1107 if (!cp_opt(cp, ',')) break;
1108 }
1109 cp_check(cp, ')');
1110 cp_check(cp, ')');
1111}
1112
1113/* Parse MSVC __declspec(...). */
1114static void cp_decl_msvcattribute(CPState *cp, CPDecl *decl)
1115{
1116 cp_next(cp);
1117 cp_check(cp, '(');
1118 while (cp->tok == CTOK_IDENT) {
1119 GCstr *attrstr = cp->str;
1120 cp_next(cp);
1121 switch (attrstr->hash) {
1122 case H_(bc2395fa,98f267f8): /* align */
1123 cp_decl_align(cp, decl);
1124 break;
1125 default: /* Ignore all other attributes. */
1126 if (cp_opt(cp, '(')) {
1127 while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
1128 cp_check(cp, ')');
1129 }
1130 break;
1131 }
1132 }
1133 cp_check(cp, ')');
1134}
1135
1136/* Parse declaration attributes (and common qualifiers). */
1137static void cp_decl_attributes(CPState *cp, CPDecl *decl)
1138{
1139 for (;;) {
1140 switch (cp->tok) {
1141 case CTOK_CONST: decl->attr |= CTF_CONST; break;
1142 case CTOK_VOLATILE: decl->attr |= CTF_VOLATILE; break;
1143 case CTOK_RESTRICT: break; /* Ignore. */
1144 case CTOK_EXTENSION: break; /* Ignore. */
1145 case CTOK_ATTRIBUTE: cp_decl_gccattribute(cp, decl); continue;
1146 case CTOK_ASM: cp_decl_asm(cp, decl); continue;
1147 case CTOK_DECLSPEC: cp_decl_msvcattribute(cp, decl); continue;
1148 case CTOK_CCDECL:
1149#if LJ_TARGET_X86
1150 CTF_INSERT(decl->fattr, CCONV, cp->ct->size);
1151 decl->fattr |= CTFP_CCONV;
1152#endif
1153 break;
1154 case CTOK_PTRSZ:
1155#if LJ_64
1156 CTF_INSERT(decl->attr, MSIZEP, cp->ct->size);
1157#endif
1158 break;
1159 default: return;
1160 }
1161 cp_next(cp);
1162 }
1163}
1164
1165/* Parse struct/union/enum name. */
1166static CTypeID cp_struct_name(CPState *cp, CPDecl *sdecl, CTInfo info)
1167{
1168 CTypeID sid;
1169 CType *ct;
1170 cp->tmask = CPNS_STRUCT;
1171 cp_next(cp);
1172 cp_decl_attributes(cp, sdecl);
1173 cp->tmask = CPNS_DEFAULT;
1174 if (cp->tok != '{') {
1175 if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
1176 if (cp->val.id) { /* Name of existing struct/union/enum. */
1177 sid = cp->val.id;
1178 ct = cp->ct;
1179 if ((ct->info ^ info) & (CTMASK_NUM|CTF_UNION)) /* Wrong type. */
1180 cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name))));
1181 } else { /* Create named, incomplete struct/union/enum. */
1182 if ((cp->mode & CPARSE_MODE_NOIMPLICIT))
1183 cp_errmsg(cp, 0, LJ_ERR_FFI_BADTAG, strdata(cp->str));
1184 sid = lj_ctype_new(cp->cts, &ct);
1185 ct->info = info;
1186 ct->size = CTSIZE_INVALID;
1187 ctype_setname(ct, cp->str);
1188 lj_ctype_addname(cp->cts, ct, sid);
1189 }
1190 cp_next(cp);
1191 } else { /* Create anonymous, incomplete struct/union/enum. */
1192 sid = lj_ctype_new(cp->cts, &ct);
1193 ct->info = info;
1194 ct->size = CTSIZE_INVALID;
1195 }
1196 if (cp->tok == '{') {
1197 if (ct->size != CTSIZE_INVALID || ct->sib)
1198 cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name))));
1199 ct->sib = 1; /* Indicate the type is currently being defined. */
1200 }
1201 return sid;
1202}
1203
1204/* Determine field alignment. */
1205static CTSize cp_field_align(CPState *cp, CType *ct, CTInfo info)
1206{
1207 CTSize align = ctype_align(info);
1208 UNUSED(cp); UNUSED(ct);
1209#if (LJ_TARGET_X86 && !LJ_ABI_WIN) || (LJ_TARGET_ARM && __APPLE__)
1210 /* The SYSV i386 and iOS ABIs limit alignment of non-vector fields to 2^2. */
1211 if (align > 2 && !(info & CTFP_ALIGNED)) {
1212 if (ctype_isarray(info) && !(info & CTF_VECTOR)) {
1213 do {
1214 ct = ctype_rawchild(cp->cts, ct);
1215 info = ct->info;
1216 } while (ctype_isarray(info) && !(info & CTF_VECTOR));
1217 }
1218 if (ctype_isnum(info) || ctype_isenum(info))
1219 align = 2;
1220 }
1221#endif
1222 return align;
1223}
1224
1225/* Layout struct/union fields. */
1226static void cp_struct_layout(CPState *cp, CTypeID sid, CTInfo sattr)
1227{
1228 CTSize bofs = 0, bmaxofs = 0; /* Bit offset and max. bit offset. */
1229 CTSize maxalign = ctype_align(sattr);
1230 CType *sct = ctype_get(cp->cts, sid);
1231 CTInfo sinfo = sct->info;
1232 CTypeID fieldid = sct->sib;
1233 while (fieldid) {
1234 CType *ct = ctype_get(cp->cts, fieldid);
1235 CTInfo attr = ct->size; /* Field declaration attributes (temp.). */
1236
1237 if (ctype_isfield(ct->info) ||
1238 (ctype_isxattrib(ct->info, CTA_SUBTYPE) && attr)) {
1239 CTSize align, amask; /* Alignment (pow2) and alignment mask (bits). */
1240 CTSize sz;
1241 CTInfo info = lj_ctype_info(cp->cts, ctype_cid(ct->info), &sz);
1242 CTSize bsz, csz = 8*sz; /* Field size and container size (in bits). */
1243 sinfo |= (info & (CTF_QUAL|CTF_VLA)); /* Merge pseudo-qualifiers. */
1244
1245 /* Check for size overflow and determine alignment. */
1246 if (sz >= 0x20000000u || bofs + csz < bofs) {
1247 if (!(sz == CTSIZE_INVALID && ctype_isarray(info) &&
1248 !(sinfo & CTF_UNION)))
1249 cp_err(cp, LJ_ERR_FFI_INVSIZE);
1250 csz = sz = 0; /* Treat a[] and a[?] as zero-sized. */
1251 }
1252 align = cp_field_align(cp, ct, info);
1253 if (((attr|sattr) & CTFP_PACKED) ||
1254 ((attr & CTFP_ALIGNED) && ctype_align(attr) > align))
1255 align = ctype_align(attr);
1256 if (cp->packstack[cp->curpack] < align)
1257 align = cp->packstack[cp->curpack];
1258 if (align > maxalign) maxalign = align;
1259 amask = (8u << align) - 1;
1260
1261 bsz = ctype_bitcsz(ct->info); /* Bitfield size (temp.). */
1262 if (bsz == CTBSZ_FIELD || !ctype_isfield(ct->info)) {
1263 bsz = csz; /* Regular fields or subtypes always fill the container. */
1264 bofs = (bofs + amask) & ~amask; /* Start new aligned field. */
1265 ct->size = (bofs >> 3); /* Store field offset. */
1266 } else { /* Bitfield. */
1267 if (bsz == 0 || (attr & CTFP_ALIGNED) ||
1268 (!((attr|sattr) & CTFP_PACKED) && (bofs & amask) + bsz > csz))
1269 bofs = (bofs + amask) & ~amask; /* Start new aligned field. */
1270
1271 /* Prefer regular field over bitfield. */
1272 if (bsz == csz && (bofs & amask) == 0) {
1273 ct->info = CTINFO(CT_FIELD, ctype_cid(ct->info));
1274 ct->size = (bofs >> 3); /* Store field offset. */
1275 } else {
1276 ct->info = CTINFO(CT_BITFIELD,
1277 (info & (CTF_QUAL|CTF_UNSIGNED|CTF_BOOL)) +
1278 (csz << (CTSHIFT_BITCSZ-3)) + (bsz << CTSHIFT_BITBSZ));
1279#if LJ_BE
1280 ct->info += ((csz - (bofs & (csz-1)) - bsz) << CTSHIFT_BITPOS);
1281#else
1282 ct->info += ((bofs & (csz-1)) << CTSHIFT_BITPOS);
1283#endif
1284 ct->size = ((bofs & ~(csz-1)) >> 3); /* Store container offset. */
1285 }
1286 }
1287
1288 /* Determine next offset or max. offset. */
1289 if ((sinfo & CTF_UNION)) {
1290 if (bsz > bmaxofs) bmaxofs = bsz;
1291 } else {
1292 bofs += bsz;
1293 }
1294 } /* All other fields in the chain are already set up. */
1295
1296 fieldid = ct->sib;
1297 }
1298
1299 /* Complete struct/union. */
1300 sct->info = sinfo + CTALIGN(maxalign);
1301 bofs = (sinfo & CTF_UNION) ? bmaxofs : bofs;
1302 maxalign = (8u << maxalign) - 1;
1303 sct->size = (((bofs + maxalign) & ~maxalign) >> 3);
1304}
1305
1306/* Parse struct/union declaration. */
1307static CTypeID cp_decl_struct(CPState *cp, CPDecl *sdecl, CTInfo sinfo)
1308{
1309 CTypeID sid = cp_struct_name(cp, sdecl, sinfo);
1310 if (cp_opt(cp, '{')) { /* Struct/union definition. */
1311 CTypeID lastid = sid;
1312 int lastdecl = 0;
1313 while (cp->tok != '}') {
1314 CPDecl decl;
1315 CPscl scl = cp_decl_spec(cp, &decl, CDF_STATIC);
1316 decl.mode = scl ? CPARSE_MODE_DIRECT :
1317 CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT|CPARSE_MODE_FIELD;
1318
1319 for (;;) {
1320 CTypeID typeid;
1321
1322 if (lastdecl) cp_err_token(cp, '}');
1323
1324 /* Parse field declarator. */
1325 decl.bits = CTSIZE_INVALID;
1326 cp_declarator(cp, &decl);
1327 typeid = cp_decl_intern(cp, &decl);
1328
1329 if ((scl & CDF_STATIC)) { /* Static constant in struct namespace. */
1330 CType *ct;
1331 CTypeID fieldid = cp_decl_constinit(cp, &ct, typeid);
1332 ctype_get(cp->cts, lastid)->sib = fieldid;
1333 lastid = fieldid;
1334 ctype_setname(ct, decl.name);
1335 } else {
1336 CTSize bsz = CTBSZ_FIELD; /* Temp. for layout phase. */
1337 CType *ct;
1338 CTypeID fieldid = lj_ctype_new(cp->cts, &ct); /* Do this first. */
1339 CType *tct = ctype_raw(cp->cts, typeid);
1340
1341 if (decl.bits == CTSIZE_INVALID) { /* Regular field. */
1342 if (ctype_isarray(tct->info) && tct->size == CTSIZE_INVALID)
1343 lastdecl = 1; /* a[] or a[?] must be the last declared field. */
1344
1345 /* Accept transparent struct/union/enum. */
1346 if (!decl.name) {
1347 if (!((ctype_isstruct(tct->info) && !(tct->info & CTF_VLA)) ||
1348 ctype_isenum(tct->info)))
1349 cp_err_token(cp, CTOK_IDENT);
1350 ct->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_SUBTYPE) + typeid);
1351 ct->size = ctype_isstruct(tct->info) ?
1352 (decl.attr|0x80000000u) : 0; /* For layout phase. */
1353 goto add_field;
1354 }
1355 } else { /* Bitfield. */
1356 bsz = decl.bits;
1357 if (!ctype_isinteger_or_bool(tct->info) ||
1358 (bsz == 0 && decl.name) || 8*tct->size > CTBSZ_MAX ||
1359 bsz > ((tct->info & CTF_BOOL) ? 1 : 8*tct->size))
1360 cp_errmsg(cp, ':', LJ_ERR_BADVAL);
1361 }
1362
1363 /* Create temporary field for layout phase. */
1364 ct->info = CTINFO(CT_FIELD, typeid + (bsz << CTSHIFT_BITCSZ));
1365 ct->size = decl.attr;
1366 if (decl.name) ctype_setname(ct, decl.name);
1367
1368 add_field:
1369 ctype_get(cp->cts, lastid)->sib = fieldid;
1370 lastid = fieldid;
1371 }
1372 if (!cp_opt(cp, ',')) break;
1373 cp_decl_reset(&decl);
1374 }
1375 cp_check(cp, ';');
1376 }
1377 cp_check(cp, '}');
1378 ctype_get(cp->cts, lastid)->sib = 0; /* Drop sib = 1 for empty structs. */
1379 cp_decl_attributes(cp, sdecl); /* Layout phase needs postfix attributes. */
1380 cp_struct_layout(cp, sid, sdecl->attr);
1381 }
1382 return sid;
1383}
1384
1385/* Parse enum declaration. */
1386static CTypeID cp_decl_enum(CPState *cp, CPDecl *sdecl)
1387{
1388 CTypeID eid = cp_struct_name(cp, sdecl, CTINFO(CT_ENUM, CTID_VOID));
1389 CTInfo einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_UINT32);
1390 CTSize esize = 4; /* Only 32 bit enums are supported. */
1391 if (cp_opt(cp, '{')) { /* Enum definition. */
1392 CPValue k;
1393 CTypeID lastid = eid;
1394 k.u32 = 0;
1395 k.id = CTID_INT32;
1396 do {
1397 GCstr *name = cp->str;
1398 if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
1399 if (cp->val.id) cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(name));
1400 cp_next(cp);
1401 if (cp_opt(cp, '=')) {
1402 cp_expr_kint(cp, &k);
1403 if (k.id == CTID_UINT32) {
1404 /* C99 says that enum constants are always (signed) integers.
1405 ** But since unsigned constants like 0x80000000 are quite common,
1406 ** those are left as uint32_t.
1407 */
1408 if (k.i32 >= 0) k.id = CTID_INT32;
1409 } else {
1410 /* OTOH it's common practice and even mandated by some ABIs
1411 ** that the enum type itself is unsigned, unless there are any
1412 ** negative constants.
1413 */
1414 k.id = CTID_INT32;
1415 if (k.i32 < 0) einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_INT32);
1416 }
1417 }
1418 /* Add named enum constant. */
1419 {
1420 CType *ct;
1421 CTypeID constid = lj_ctype_new(cp->cts, &ct);
1422 ctype_get(cp->cts, lastid)->sib = constid;
1423 lastid = constid;
1424 ctype_setname(ct, name);
1425 ct->info = CTINFO(CT_CONSTVAL, CTF_CONST|k.id);
1426 ct->size = k.u32++;
1427 if (k.u32 == 0x80000000u) k.id = CTID_UINT32;
1428 lj_ctype_addname(cp->cts, ct, constid);
1429 }
1430 if (!cp_opt(cp, ',')) break;
1431 } while (cp->tok != '}'); /* Trailing ',' is ok. */
1432 cp_check(cp, '}');
1433 /* Complete enum. */
1434 ctype_get(cp->cts, eid)->info = einfo;
1435 ctype_get(cp->cts, eid)->size = esize;
1436 }
1437 return eid;
1438}
1439
1440/* Parse declaration specifiers. */
1441static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl)
1442{
1443 uint32_t cds = 0, sz = 0;
1444 CTInfo tdef = 0;
1445
1446 decl->cp = cp;
1447 decl->mode = cp->mode;
1448 decl->name = NULL;
1449 decl->redir = NULL;
1450 decl->attr = 0;
1451 decl->fattr = 0;
1452 decl->pos = decl->top = 0;
1453 decl->stack[0].next = 0;
1454
1455 for (;;) { /* Parse basic types. */
1456 cp_decl_attributes(cp, decl);
1457 switch (cp->tok) {
1458 case CTOK_STRUCT:
1459 tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, 0));
1460 break;
1461 case CTOK_UNION:
1462 tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, CTF_UNION));
1463 break;
1464 case CTOK_ENUM:
1465 tdef = cp_decl_enum(cp, decl);
1466 break;
1467 case CTOK_IDENT:
1468 if (!ctype_istypedef(cp->ct->info) || sz || tdef ||
1469 (cds & (CDF_SHORT|CDF_LONG|CDF_SIGNED|CDF_UNSIGNED|CDF_COMPLEX)))
1470 goto end_decl;
1471 tdef = ctype_cid(cp->ct->info); /* Get typedef. */
1472 cp_next(cp);
1473 break;
1474 default:
1475 if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECLFLAG) {
1476 uint32_t cbit;
1477 if (cp->ct->size) {
1478 if (sz) goto end_decl;
1479 sz = cp->ct->size;
1480 }
1481 cbit = (1u << (cp->tok - CTOK_FIRSTDECL));
1482 cds = cds | cbit | ((cbit & cds & CDF_LONG) << 1);
1483 if (cp->tok >= CTOK_FIRSTSCL && !(scl & cbit))
1484 cp_errmsg(cp, cp->tok, LJ_ERR_FFI_BADSCL);
1485 cp_next(cp);
1486 break;
1487 }
1488 goto end_decl;
1489 }
1490 }
1491end_decl:
1492
1493 if ((cds & CDF_COMPLEX)) /* Use predefined complex types. */
1494 tdef = sz == 4 ? CTID_COMPLEX_FLOAT : CTID_COMPLEX_DOUBLE;
1495
1496 if (tdef) {
1497 cp_push_type(decl, tdef);
1498 } else if ((cds & CDF_VOID)) {
1499 cp_push(decl, CTINFO(CT_VOID, (decl->attr & CTF_QUAL)), CTSIZE_INVALID);
1500 decl->attr &= ~CTF_QUAL;
1501 } else {
1502 /* Determine type info and size. */
1503 CTInfo info = CTINFO(CT_NUM, (cds & CDF_UNSIGNED) ? CTF_UNSIGNED : 0);
1504 if ((cds & CDF_BOOL)) {
1505 info = CTINFO(CT_NUM, CTF_UNSIGNED|CTF_BOOL);
1506 lua_assert(sz == 1);
1507 } else if ((cds & CDF_FP)) {
1508 info = CTINFO(CT_NUM, CTF_FP);
1509 if ((cds & CDF_LONG)) sz = sizeof(long double);
1510 } else if ((cds & CDF_CHAR)) {
1511 if ((cds & (CDF_CHAR|CDF_SIGNED|CDF_UNSIGNED)) == CDF_CHAR)
1512 info |= CTF_UCHAR; /* Handle platforms where char is unsigned. */
1513 } else if ((cds & CDF_SHORT)) {
1514 sz = sizeof(short);
1515 } else if ((cds & CDF_LONGLONG)) {
1516 sz = 8;
1517 } else if ((cds & CDF_LONG)) {
1518 info |= CTF_LONG;
1519 sz = sizeof(long);
1520 } else if (!sz) {
1521 if (!(cds & (CDF_SIGNED|CDF_UNSIGNED)))
1522 cp_errmsg(cp, cp->tok, LJ_ERR_FFI_DECLSPEC);
1523 sz = sizeof(int);
1524 }
1525 lua_assert(sz != 0);
1526 info += CTALIGN(lj_fls(sz)); /* Use natural alignment. */
1527 info += (decl->attr & CTF_QUAL); /* Merge qualifiers. */
1528 cp_push(decl, info, sz);
1529 decl->attr &= ~CTF_QUAL;
1530 }
1531 decl->specpos = decl->pos;
1532 decl->specattr = decl->attr;
1533 decl->specfattr = decl->fattr;
1534 return (cds & CDF_SCL); /* Return storage class. */
1535}
1536
1537/* Parse array declaration. */
1538static void cp_decl_array(CPState *cp, CPDecl *decl)
1539{
1540 CTInfo info = CTINFO(CT_ARRAY, 0);
1541 CTSize nelem = CTSIZE_INVALID; /* Default size for a[] or a[?]. */
1542 cp_decl_attributes(cp, decl);
1543 if (cp_opt(cp, '?'))
1544 info |= CTF_VLA; /* Create variable-length array a[?]. */
1545 else if (cp->tok != ']')
1546 nelem = cp_expr_ksize(cp);
1547 cp_check(cp, ']');
1548 cp_add(decl, info, nelem);
1549}
1550
1551/* Parse function declaration. */
1552static void cp_decl_func(CPState *cp, CPDecl *fdecl)
1553{
1554 CTSize nargs = 0;
1555 CTInfo info = CTINFO(CT_FUNC, 0);
1556 CTypeID lastid = 0, anchor = 0;
1557 if (cp->tok != ')') {
1558 do {
1559 CPDecl decl;
1560 CTypeID typeid, fieldid;
1561 CType *ct;
1562 if (cp_opt(cp, '.')) { /* Vararg function. */
1563 cp_check(cp, '.'); /* Workaround for the minimalistic lexer. */
1564 cp_check(cp, '.');
1565 info |= CTF_VARARG;
1566 break;
1567 }
1568 cp_decl_spec(cp, &decl, CDF_REGISTER);
1569 decl.mode = CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT;
1570 cp_declarator(cp, &decl);
1571 typeid = cp_decl_intern(cp, &decl);
1572 ct = ctype_raw(cp->cts, typeid);
1573 if (ctype_isvoid(ct->info))
1574 break;
1575 else if (ctype_isrefarray(ct->info))
1576 typeid = lj_ctype_intern(cp->cts,
1577 CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ct->info)), CTSIZE_PTR);
1578 else if (ctype_isfunc(ct->info))
1579 typeid = lj_ctype_intern(cp->cts,
1580 CTINFO(CT_PTR, CTALIGN_PTR|typeid), CTSIZE_PTR);
1581 /* Add new parameter. */
1582 fieldid = lj_ctype_new(cp->cts, &ct);
1583 if (anchor)
1584 ctype_get(cp->cts, lastid)->sib = fieldid;
1585 else
1586 anchor = fieldid;
1587 lastid = fieldid;
1588 if (decl.name) ctype_setname(ct, decl.name);
1589 ct->info = CTINFO(CT_FIELD, typeid);
1590 ct->size = nargs++;
1591 } while (cp_opt(cp, ','));
1592 }
1593 cp_check(cp, ')');
1594 if (cp_opt(cp, '{')) { /* Skip function definition. */
1595 int level = 1;
1596 cp->mode |= CPARSE_MODE_SKIP;
1597 for (;;) {
1598 if (cp->tok == '{') level++;
1599 else if (cp->tok == '}' && --level == 0) break;
1600 else if (cp->tok == CTOK_EOF) cp_err_token(cp, '}');
1601 cp_next(cp);
1602 }
1603 cp->mode &= ~CPARSE_MODE_SKIP;
1604 cp->tok = ';'; /* Ok for cp_decl_multi(), error in cp_decl_single(). */
1605 }
1606 info |= (fdecl->fattr & ~CTMASK_CID);
1607 fdecl->fattr = 0;
1608 fdecl->stack[cp_add(fdecl, info, nargs)].sib = anchor;
1609}
1610
1611/* Parse declarator. */
1612static void cp_declarator(CPState *cp, CPDecl *decl)
1613{
1614 if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS);
1615
1616 for (;;) { /* Head of declarator. */
1617 if (cp_opt(cp, '*')) { /* Pointer. */
1618 CTSize sz;
1619 CTInfo info;
1620 cp_decl_attributes(cp, decl);
1621 sz = CTSIZE_PTR;
1622 info = CTINFO(CT_PTR, CTALIGN_PTR);
1623#if LJ_64
1624 if (ctype_msizeP(decl->attr) == 4) {
1625 sz = 4;
1626 info = CTINFO(CT_PTR, CTALIGN(2));
1627 }
1628#endif
1629 info += (decl->attr & (CTF_QUAL|CTF_REF));
1630 decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP));
1631 cp_push(decl, info, sz);
1632 } else if (cp_opt(cp, '&') || cp_opt(cp, CTOK_ANDAND)) { /* Reference. */
1633 decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP));
1634 cp_push(decl, CTINFO_REF(0), CTSIZE_PTR);
1635 } else {
1636 break;
1637 }
1638 }
1639
1640 if (cp_opt(cp, '(')) { /* Inner declarator. */
1641 CPDeclIdx pos;
1642 cp_decl_attributes(cp, decl);
1643 /* Resolve ambiguity between inner declarator and 1st function parameter. */
1644 if ((decl->mode & CPARSE_MODE_ABSTRACT) &&
1645 (cp->tok == ')' || cp_istypedecl(cp))) goto func_decl;
1646 pos = decl->pos;
1647 cp_declarator(cp, decl);
1648 cp_check(cp, ')');
1649 decl->pos = pos;
1650 } else if (cp->tok == CTOK_IDENT) { /* Direct declarator. */
1651 if (!(decl->mode & CPARSE_MODE_DIRECT)) cp_err_token(cp, CTOK_EOF);
1652 decl->name = cp->str;
1653 decl->nameid = cp->val.id;
1654 cp_next(cp);
1655 } else { /* Abstract declarator. */
1656 if (!(decl->mode & CPARSE_MODE_ABSTRACT)) cp_err_token(cp, CTOK_IDENT);
1657 }
1658
1659 for (;;) { /* Tail of declarator. */
1660 if (cp_opt(cp, '[')) { /* Array. */
1661 cp_decl_array(cp, decl);
1662 } else if (cp_opt(cp, '(')) { /* Function. */
1663 func_decl:
1664 cp_decl_func(cp, decl);
1665 } else {
1666 break;
1667 }
1668 }
1669
1670 if ((decl->mode & CPARSE_MODE_FIELD) && cp_opt(cp, ':')) /* Field width. */
1671 decl->bits = cp_expr_ksize(cp);
1672
1673 /* Process postfix attributes. */
1674 cp_decl_attributes(cp, decl);
1675 cp_push_attributes(decl);
1676
1677 cp->depth--;
1678}
1679
1680/* Parse an abstract type declaration and return it's C type ID. */
1681static CTypeID cp_decl_abstract(CPState *cp)
1682{
1683 CPDecl decl;
1684 cp_decl_spec(cp, &decl, 0);
1685 decl.mode = CPARSE_MODE_ABSTRACT;
1686 cp_declarator(cp, &decl);
1687 return cp_decl_intern(cp, &decl);
1688}
1689
1690/* Handle pragmas. */
1691static void cp_pragma(CPState *cp, BCLine pragmaline)
1692{
1693 cp_next(cp);
1694 if (cp->tok == CTOK_IDENT &&
1695 cp->str->hash == H_(e79b999f,42ca3e85)) { /* pack */
1696 cp_next(cp);
1697 cp_check(cp, '(');
1698 if (cp->tok == CTOK_IDENT) {
1699 if (cp->str->hash == H_(738e923c,a1b65954)) { /* push */
1700 if (cp->curpack < CPARSE_MAX_PACKSTACK) {
1701 cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack];
1702 cp->curpack++;
1703 }
1704 } else if (cp->str->hash == H_(6c71cf27,6c71cf27)) { /* pop */
1705 if (cp->curpack > 0) cp->curpack--;
1706 } else {
1707 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
1708 }
1709 cp_next(cp);
1710 if (!cp_opt(cp, ',')) goto end_pack;
1711 }
1712 if (cp->tok == CTOK_INTEGER) {
1713 cp->packstack[cp->curpack] = cp->val.u32 ? lj_fls(cp->val.u32) : 0;
1714 cp_next(cp);
1715 } else {
1716 cp->packstack[cp->curpack] = 255;
1717 }
1718 end_pack:
1719 cp_check(cp, ')');
1720 } else { /* Ignore all other pragmas. */
1721 while (cp->tok != CTOK_EOF && cp->linenumber == pragmaline)
1722 cp_next(cp);
1723 }
1724}
1725
1726/* Parse multiple C declarations of types or extern identifiers. */
1727static void cp_decl_multi(CPState *cp)
1728{
1729 int first = 1;
1730 while (cp->tok != CTOK_EOF) {
1731 CPDecl decl;
1732 CPscl scl;
1733 if (cp_opt(cp, ';')) { /* Skip empty statements. */
1734 first = 0;
1735 continue;
1736 }
1737 if (cp->tok == '#') { /* Workaround, since we have no preprocessor, yet. */
1738 BCLine pragmaline = cp->linenumber;
1739 if (!(cp_next(cp) == CTOK_IDENT &&
1740 cp->str->hash == H_(f5e6b4f8,1d509107))) /* pragma */
1741 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
1742 cp_pragma(cp, pragmaline);
1743 continue;
1744 }
1745 scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC);
1746 if ((cp->tok == ';' || cp->tok == CTOK_EOF) &&
1747 ctype_istypedef(decl.stack[0].info)) {
1748 CTInfo info = ctype_rawchild(cp->cts, &decl.stack[0])->info;
1749 if (ctype_isstruct(info) || ctype_isenum(info))
1750 goto decl_end; /* Accept empty declaration of struct/union/enum. */
1751 }
1752 for (;;) {
1753 CTypeID typeid;
1754 cp_declarator(cp, &decl);
1755 typeid = cp_decl_intern(cp, &decl);
1756 if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */
1757 CType *ct;
1758 CTypeID id;
1759 if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */
1760 id = lj_ctype_new(cp->cts, &ct);
1761 ct->info = CTINFO(CT_TYPEDEF, typeid);
1762 goto noredir;
1763 } else if (ctype_isfunc(ctype_get(cp->cts, typeid)->info)) {
1764 /* Treat both static and extern function declarations as extern. */
1765 ct = ctype_get(cp->cts, typeid);
1766 /* We always get new anonymous functions (typedefs are copied). */
1767 lua_assert(gcref(ct->name) == NULL);
1768 id = typeid; /* Just name it. */
1769 } else if ((scl & CDF_STATIC)) { /* Accept static constants. */
1770 id = cp_decl_constinit(cp, &ct, typeid);
1771 goto noredir;
1772 } else { /* External references have extern or no storage class. */
1773 id = lj_ctype_new(cp->cts, &ct);
1774 ct->info = CTINFO(CT_EXTERN, typeid);
1775 }
1776 if (decl.redir) { /* Add attribute for redirected symbol name. */
1777 CType *cta;
1778 CTypeID aid = lj_ctype_new(cp->cts, &cta);
1779 ct = ctype_get(cp->cts, id); /* Table may have been reallocated. */
1780 cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR));
1781 cta->sib = ct->sib;
1782 ct->sib = aid;
1783 ctype_setname(cta, decl.redir);
1784 }
1785 noredir:
1786 ctype_setname(ct, decl.name);
1787 lj_ctype_addname(cp->cts, ct, id);
1788 }
1789 if (!cp_opt(cp, ',')) break;
1790 cp_decl_reset(&decl);
1791 }
1792 decl_end:
1793 if (cp->tok == CTOK_EOF && first) break; /* May omit ';' for 1 decl. */
1794 first = 0;
1795 cp_check(cp, ';');
1796 }
1797}
1798
1799/* Parse a single C type declaration. */
1800static void cp_decl_single(CPState *cp)
1801{
1802 CPDecl decl;
1803 cp_decl_spec(cp, &decl, 0);
1804 cp_declarator(cp, &decl);
1805 cp->val.id = cp_decl_intern(cp, &decl);
1806 if (cp->tok != CTOK_EOF) cp_err_token(cp, CTOK_EOF);
1807}
1808
1809#undef H_
1810
1811/* ------------------------------------------------------------------------ */
1812
1813/* Protected callback for C parser. */
1814static TValue *cpcparser(lua_State *L, lua_CFunction dummy, void *ud)
1815{
1816 CPState *cp = (CPState *)ud;
1817 UNUSED(dummy);
1818 cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
1819 cp_init(cp);
1820 if ((cp->mode & CPARSE_MODE_MULTI))
1821 cp_decl_multi(cp);
1822 else
1823 cp_decl_single(cp);
1824 lua_assert(cp->depth == 0);
1825 return NULL;
1826}
1827
1828/* C parser. */
1829int lj_cparse(CPState *cp)
1830{
1831 LJ_CTYPE_SAVE(cp->cts);
1832 int errcode = lj_vm_cpcall(cp->L, NULL, cp, cpcparser);
1833 if (errcode)
1834 LJ_CTYPE_RESTORE(cp->cts);
1835 cp_cleanup(cp);
1836 return errcode;
1837}
1838
1839#endif
diff --git a/libraries/luajit-2.0/src/lj_cparse.h b/libraries/luajit-2.0/src/lj_cparse.h
new file mode 100644
index 0000000..c947700
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_cparse.h
@@ -0,0 +1,64 @@
1/*
2** C declaration parser.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CPARSE_H
7#define _LJ_CPARSE_H
8
9#include "lj_obj.h"
10#include "lj_ctype.h"
11
12#if LJ_HASFFI
13
14/* C parser limits. */
15#define CPARSE_MAX_BUF 32768 /* Max. token buffer size. */
16#define CPARSE_MAX_DECLSTACK 100 /* Max. declaration stack depth. */
17#define CPARSE_MAX_DECLDEPTH 20 /* Max. recursive declaration depth. */
18#define CPARSE_MAX_PACKSTACK 7 /* Max. pack pragma stack depth. */
19
20/* Flags for C parser mode. */
21#define CPARSE_MODE_MULTI 1 /* Process multiple declarations. */
22#define CPARSE_MODE_ABSTRACT 2 /* Accept abstract declarators. */
23#define CPARSE_MODE_DIRECT 4 /* Accept direct declarators. */
24#define CPARSE_MODE_FIELD 8 /* Accept field width in bits, too. */
25#define CPARSE_MODE_NOIMPLICIT 16 /* Reject implicit declarations. */
26#define CPARSE_MODE_SKIP 32 /* Skip definitions, ignore errors. */
27
28typedef int CPChar; /* C parser character. Unsigned ext. from char. */
29typedef int CPToken; /* C parser token. */
30
31/* C parser internal value representation. */
32typedef struct CPValue {
33 union {
34 int32_t i32; /* Value for CTID_INT32. */
35 uint32_t u32; /* Value for CTID_UINT32. */
36 };
37 CTypeID id; /* C Type ID of the value. */
38} CPValue;
39
40/* C parser state. */
41typedef struct CPState {
42 CPChar c; /* Current character. */
43 CPToken tok; /* Current token. */
44 CPValue val; /* Token value. */
45 GCstr *str; /* Interned string of identifier/keyword. */
46 CType *ct; /* C type table entry. */
47 const char *p; /* Current position in input buffer. */
48 SBuf sb; /* String buffer for tokens. */
49 lua_State *L; /* Lua state. */
50 CTState *cts; /* C type state. */
51 const char *srcname; /* Current source name. */
52 BCLine linenumber; /* Input line counter. */
53 int depth; /* Recursive declaration depth. */
54 uint32_t tmask; /* Type mask for next identifier. */
55 uint32_t mode; /* C parser mode. */
56 uint8_t packstack[CPARSE_MAX_PACKSTACK]; /* Stack for pack pragmas. */
57 uint8_t curpack; /* Current position in pack pragma stack. */
58} CPState;
59
60LJ_FUNC int lj_cparse(CPState *cp);
61
62#endif
63
64#endif
diff --git a/libraries/luajit-2.0/src/lj_crecord.c b/libraries/luajit-2.0/src/lj_crecord.c
new file mode 100644
index 0000000..27001f6
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_crecord.c
@@ -0,0 +1,1316 @@
1/*
2** Trace recorder for C data operations.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_ffrecord_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT && LJ_HASFFI
12
13#include "lj_err.h"
14#include "lj_str.h"
15#include "lj_tab.h"
16#include "lj_frame.h"
17#include "lj_ctype.h"
18#include "lj_cdata.h"
19#include "lj_cparse.h"
20#include "lj_cconv.h"
21#include "lj_clib.h"
22#include "lj_ccall.h"
23#include "lj_ir.h"
24#include "lj_jit.h"
25#include "lj_ircall.h"
26#include "lj_iropt.h"
27#include "lj_trace.h"
28#include "lj_record.h"
29#include "lj_ffrecord.h"
30#include "lj_snap.h"
31#include "lj_crecord.h"
32#include "lj_dispatch.h"
33
34/* Some local macros to save typing. Undef'd at the end. */
35#define IR(ref) (&J->cur.ir[(ref)])
36
37/* Pass IR on to next optimization in chain (FOLD). */
38#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
39
40#define emitconv(a, dt, st, flags) \
41 emitir(IRT(IR_CONV, (dt)), (a), (st)|((dt) << 5)|(flags))
42
43/* -- C type checks ------------------------------------------------------- */
44
45static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o)
46{
47 GCcdata *cd;
48 TRef trtypeid;
49 if (!tref_iscdata(tr))
50 lj_trace_err(J, LJ_TRERR_BADTYPE);
51 cd = cdataV(o);
52 /* Specialize to the CTypeID. */
53 trtypeid = emitir(IRT(IR_FLOAD, IRT_U16), tr, IRFL_CDATA_TYPEID);
54 emitir(IRTG(IR_EQ, IRT_INT), trtypeid, lj_ir_kint(J, (int32_t)cd->typeid));
55 return cd;
56}
57
58/* Specialize to the CTypeID held by a cdata constructor. */
59static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr)
60{
61 CTypeID id;
62 lua_assert(tref_iscdata(tr) && cd->typeid == CTID_CTYPEID);
63 id = *(CTypeID *)cdataptr(cd);
64 tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
65 tr = emitir(IRT(IR_XLOAD, IRT_INT), tr, 0);
66 emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id));
67 return id;
68}
69
70static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o)
71{
72 if (tref_isstr(tr)) {
73 GCstr *s = strV(o);
74 CPState cp;
75 CTypeID oldtop;
76 /* Specialize to the string containing the C type declaration. */
77 emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, s));
78 cp.L = J->L;
79 cp.cts = ctype_ctsG(J2G(J));
80 oldtop = cp.cts->top;
81 cp.srcname = strdata(s);
82 cp.p = strdata(s);
83 cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT;
84 if (lj_cparse(&cp) || cp.cts->top > oldtop) /* Avoid new struct defs. */
85 lj_trace_err(J, LJ_TRERR_BADTYPE);
86 return cp.val.id;
87 } else {
88 GCcdata *cd = argv2cdata(J, tr, o);
89 return cd->typeid == CTID_CTYPEID ? crec_constructor(J, cd, tr) :
90 cd->typeid;
91 }
92}
93
94/* -- Convert C type to C type -------------------------------------------- */
95
96/*
97** This code mirrors the code in lj_cconv.c. It performs the same steps
98** for the trace recorder that lj_cconv.c does for the interpreter.
99**
100** One major difference is that we can get away with much fewer checks
101** here. E.g. checks for casts, constness or correct types can often be
102** omitted, even if they might fail. The interpreter subsequently throws
103** an error, which aborts the trace.
104**
105** All operations are specialized to their C types, so the on-trace
106** outcome must be the same as the outcome in the interpreter. If the
107** interpreter doesn't throw an error, then the trace is correct, too.
108** Care must be taken not to generate invalid (temporary) IR or to
109** trigger asserts.
110*/
111
112/* Convert CType to IRType. */
113static IRType crec_ct2irt(CType *ct)
114{
115 if (LJ_LIKELY(ctype_isnum(ct->info))) {
116 if ((ct->info & CTF_FP)) {
117 if (ct->size == sizeof(double))
118 return IRT_NUM;
119 else if (ct->size == sizeof(float))
120 return IRT_FLOAT;
121 } else {
122 uint32_t b = lj_fls(ct->size);
123 if (b <= 3)
124 return IRT_I8 + 2*b + ((ct->info & CTF_UNSIGNED) ? 1 : 0);
125 }
126 } else if (ctype_isptr(ct->info)) {
127 return (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
128 } else if (ctype_iscomplex(ct->info)) {
129 if (ct->size == 2*sizeof(double))
130 return IRT_NUM;
131 else if (ct->size == 2*sizeof(float))
132 return IRT_FLOAT;
133 }
134 return IRT_CDATA;
135}
136
137/* Determine whether a passed number or cdata number is non-zero. */
138static int crec_isnonzero(CType *s, void *p)
139{
140 if (p == (void *)0)
141 return 0;
142 if (p == (void *)1)
143 return 1;
144 if ((s->info & CTF_FP)) {
145 if (s->size == sizeof(float))
146 return (*(float *)p != 0);
147 else
148 return (*(double *)p != 0);
149 } else {
150 if (s->size == 1)
151 return (*(uint8_t *)p != 0);
152 else if (s->size == 2)
153 return (*(uint16_t *)p != 0);
154 else if (s->size == 4)
155 return (*(uint32_t *)p != 0);
156 else
157 return (*(uint64_t *)p != 0);
158 }
159}
160
161static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
162 void *svisnz)
163{
164 CTSize dsize = d->size, ssize = s->size;
165 CTInfo dinfo = d->info, sinfo = s->info;
166 IRType dt = crec_ct2irt(d);
167 IRType st = crec_ct2irt(s);
168
169 if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
170 goto err_conv;
171
172 /*
173 ** Note: Unlike lj_cconv_ct_ct(), sp holds the _value_ of pointers and
174 ** numbers up to 8 bytes. Otherwise sp holds a pointer.
175 */
176
177 switch (cconv_idx2(dinfo, sinfo)) {
178 /* Destination is a bool. */
179 case CCX(B, B):
180 goto xstore; /* Source operand is already normalized. */
181 case CCX(B, I):
182 case CCX(B, F):
183 if (st != IRT_CDATA) {
184 /* Specialize to the result of a comparison against 0. */
185 TRef zero = (st == IRT_NUM || st == IRT_FLOAT) ? lj_ir_knum(J, 0) :
186 (st == IRT_I64 || st == IRT_U64) ? lj_ir_kint64(J, 0) :
187 lj_ir_kint(J, 0);
188 int isnz = crec_isnonzero(s, svisnz);
189 emitir(IRTG(isnz ? IR_NE : IR_EQ, st), sp, zero);
190 sp = lj_ir_kint(J, isnz);
191 goto xstore;
192 }
193 goto err_nyi;
194
195 /* Destination is an integer. */
196 case CCX(I, B):
197 case CCX(I, I):
198 conv_I_I:
199 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
200 /* Extend 32 to 64 bit integer. */
201 if (dsize == 8 && ssize < 8 && !(LJ_64 && (sinfo & CTF_UNSIGNED)))
202 sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st,
203 (sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
204 else if (dsize < 8 && ssize == 8) /* Truncate from 64 bit integer. */
205 sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, 0);
206 else if (st == IRT_INT)
207 sp = lj_opt_narrow_toint(J, sp);
208 xstore:
209 if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J);
210 if (dp == 0) return sp;
211 emitir(IRT(IR_XSTORE, dt), dp, sp);
212 break;
213 case CCX(I, C):
214 sp = emitir(IRT(IR_XLOAD, st), sp, 0); /* Load re. */
215 /* fallthrough */
216 case CCX(I, F):
217 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
218 sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_TRUNC|IRCONV_ANY);
219 goto xstore;
220 case CCX(I, P):
221 case CCX(I, A):
222 sinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
223 ssize = CTSIZE_PTR;
224 st = IRT_UINTP;
225 goto conv_I_I;
226
227 /* Destination is a floating-point number. */
228 case CCX(F, B):
229 case CCX(F, I):
230 conv_F_I:
231 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
232 sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st, 0);
233 goto xstore;
234 case CCX(F, C):
235 sp = emitir(IRT(IR_XLOAD, st), sp, 0); /* Load re. */
236 /* fallthrough */
237 case CCX(F, F):
238 conv_F_F:
239 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
240 if (dt != st) sp = emitconv(sp, dt, st, 0);
241 goto xstore;
242
243 /* Destination is a complex number. */
244 case CCX(C, I):
245 case CCX(C, F):
246 { /* Clear im. */
247 TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
248 emitir(IRT(IR_XSTORE, dt), ptr, lj_ir_knum(J, 0));
249 }
250 /* Convert to re. */
251 if ((sinfo & CTF_FP)) goto conv_F_F; else goto conv_F_I;
252
253 case CCX(C, C):
254 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
255 {
256 TRef re, im, ptr;
257 re = emitir(IRT(IR_XLOAD, st), sp, 0);
258 ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, (ssize >> 1)));
259 im = emitir(IRT(IR_XLOAD, st), ptr, 0);
260 if (dt != st) {
261 re = emitconv(re, dt, st, 0);
262 im = emitconv(im, dt, st, 0);
263 }
264 emitir(IRT(IR_XSTORE, dt), dp, re);
265 ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
266 emitir(IRT(IR_XSTORE, dt), ptr, im);
267 }
268 break;
269
270 /* Destination is a vector. */
271 case CCX(V, I):
272 case CCX(V, F):
273 case CCX(V, C):
274 case CCX(V, V):
275 goto err_nyi;
276
277 /* Destination is a pointer. */
278 case CCX(P, P):
279 case CCX(P, A):
280 case CCX(P, S):
281 /* There are only 32 bit pointers/addresses on 32 bit machines.
282 ** Also ok on x64, since all 32 bit ops clear the upper part of the reg.
283 */
284 goto xstore;
285 case CCX(P, I):
286 if (st == IRT_CDATA) goto err_nyi;
287 if (!LJ_64 && ssize == 8) /* Truncate from 64 bit integer. */
288 sp = emitconv(sp, IRT_U32, st, 0);
289 goto xstore;
290 case CCX(P, F):
291 if (st == IRT_CDATA) goto err_nyi;
292 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
293 sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32,
294 st, IRCONV_TRUNC|IRCONV_ANY);
295 goto xstore;
296
297 /* Destination is an array. */
298 case CCX(A, A):
299 goto err_nyi;
300
301 /* Destination is a struct/union. */
302 case CCX(S, S):
303 goto err_nyi;
304
305 default:
306 err_conv:
307 err_nyi:
308 lj_trace_err(J, LJ_TRERR_NYICONV);
309 break;
310 }
311 return 0;
312}
313
314/* -- Convert C type to TValue (load) ------------------------------------- */
315
316static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
317{
318 CTState *cts = ctype_ctsG(J2G(J));
319 CTInfo sinfo = s->info;
320 lua_assert(!ctype_isenum(sinfo));
321 if (ctype_isnum(sinfo)) {
322 IRType t = crec_ct2irt(s);
323 TRef tr;
324 if (t == IRT_CDATA)
325 goto err_nyi; /* NYI: copyval of >64 bit integers. */
326 tr = emitir(IRT(IR_XLOAD, t), sp, 0);
327 if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */
328 return emitconv(tr, IRT_NUM, t, 0);
329 } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */
330 sp = tr;
331 lj_needsplit(J);
332 } else if ((sinfo & CTF_BOOL)) {
333 /* Assume not equal to zero. Fixup and emit pending guard later. */
334 lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
335 J->postproc = LJ_POST_FIXGUARD;
336 return TREF_TRUE;
337 } else {
338 return tr;
339 }
340 } else if (ctype_isptr(sinfo)) {
341 IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32;
342 sp = emitir(IRT(IR_XLOAD, t), sp, 0);
343 } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
344 cts->L = J->L;
345 sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */
346 } else if (ctype_iscomplex(sinfo)) { /* Unbox/box complex. */
347 IRType t = s->size == 2*sizeof(double) ? IRT_NUM : IRT_FLOAT;
348 ptrdiff_t esz = (ptrdiff_t)(s->size >> 1);
349 TRef ptr, tr1, tr2, dp;
350 dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL);
351 tr1 = emitir(IRT(IR_XLOAD, t), sp, 0);
352 ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, esz));
353 tr2 = emitir(IRT(IR_XLOAD, t), ptr, 0);
354 ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)));
355 emitir(IRT(IR_XSTORE, t), ptr, tr1);
356 ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)+esz));
357 emitir(IRT(IR_XSTORE, t), ptr, tr2);
358 return dp;
359 } else {
360 /* NYI: copyval of vectors. */
361 err_nyi:
362 lj_trace_err(J, LJ_TRERR_NYICONV);
363 }
364 /* Box pointer, ref or 64 bit integer. */
365 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp);
366}
367
368/* -- Convert TValue to C type (store) ------------------------------------ */
369
370static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
371{
372 CTState *cts = ctype_ctsG(J2G(J));
373 CTypeID sid = CTID_P_VOID;
374 void *svisnz = 0;
375 CType *s;
376 if (LJ_LIKELY(tref_isinteger(sp))) {
377 sid = CTID_INT32;
378 svisnz = (void *)(intptr_t)(tvisint(sval)?(intV(sval)!=0):!tviszero(sval));
379 } else if (tref_isnum(sp)) {
380 sid = CTID_DOUBLE;
381 svisnz = (void *)(intptr_t)(tvisint(sval)?(intV(sval)!=0):!tviszero(sval));
382 } else if (tref_isbool(sp)) {
383 sp = lj_ir_kint(J, tref_istrue(sp) ? 1 : 0);
384 sid = CTID_BOOL;
385 } else if (tref_isnil(sp)) {
386 sp = lj_ir_kptr(J, NULL);
387 } else if (tref_isudata(sp)) {
388 sp = emitir(IRT(IR_ADD, IRT_P32), sp, lj_ir_kint(J, sizeof(GCudata)));
389 } else if (tref_isstr(sp)) {
390 if (ctype_isenum(d->info)) { /* Match string against enum constant. */
391 GCstr *str = strV(sval);
392 CTSize ofs;
393 CType *cct = lj_ctype_getfield(cts, d, str, &ofs);
394 /* Specialize to the name of the enum constant. */
395 emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str));
396 if (cct && ctype_isconstval(cct->info)) {
397 lua_assert(ctype_child(cts, cct)->size == 4);
398 svisnz = (void *)(intptr_t)(cct->size != 0);
399 sp = lj_ir_kint(J, (int32_t)cct->size);
400 sid = ctype_cid(cct->info);
401 } /* else: interpreter will throw. */
402 } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */
403 lj_trace_err(J, LJ_TRERR_BADTYPE); /* NYI */
404 } else { /* Otherwise pass the string data as a const char[]. */
405 sp = emitir(IRT(IR_STRREF, IRT_P32), sp, lj_ir_kint(J, 0));
406 sid = CTID_A_CCHAR;
407 }
408 } else { /* NYI: tref_istab(sp), tref_islightud(sp). */
409 sid = argv2cdata(J, sp, sval)->typeid;
410 s = ctype_raw(cts, sid);
411 svisnz = cdataptr(cdataV(sval));
412 if (ctype_isptr(s->info)) {
413 IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32;
414 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR);
415 if (ctype_isref(s->info)) {
416 svisnz = *(void **)svisnz;
417 s = ctype_rawchild(cts, s);
418 } else {
419 goto doconv; /* The pointer value was loaded, don't load number. */
420 }
421 } else if (ctype_isinteger(s->info) && s->size == 8) {
422 IRType t = (s->info & CTF_UNSIGNED) ? IRT_U64 : IRT_I64;
423 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INT64);
424 lj_needsplit(J);
425 goto doconv;
426 } else {
427 sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata)));
428 }
429 if (ctype_isenum(s->info)) s = ctype_child(cts, s);
430 if (ctype_isnum(s->info)) { /* Load number value. */
431 IRType t = crec_ct2irt(s);
432 if (t != IRT_CDATA) {
433 sp = emitir(IRT(IR_XLOAD, t), sp, 0);
434 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
435 }
436 }
437 goto doconv;
438 }
439 s = ctype_get(cts, sid);
440doconv:
441 if (ctype_isenum(d->info)) d = ctype_child(cts, d);
442 return crec_ct_ct(J, d, s, dp, sp, svisnz);
443}
444
445/* -- C data metamethods -------------------------------------------------- */
446
447/* This would be rather difficult in FOLD, so do it here:
448** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k)
449** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz)
450*/
451static TRef crec_reassoc_ofs(jit_State *J, TRef tr, ptrdiff_t *ofsp, MSize sz)
452{
453 IRIns *ir = IR(tref_ref(tr));
454 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && irref_isk(ir->op2) &&
455 (ir->o == IR_ADD || ir->o == IR_ADDOV || ir->o == IR_SUBOV)) {
456 IRIns *irk = IR(ir->op2);
457 ptrdiff_t k;
458 if (LJ_64 && irk->o == IR_KINT64)
459 k = (ptrdiff_t)ir_kint64(irk)->u64 * sz;
460 else
461 k = (ptrdiff_t)irk->i * sz;
462 if (ir->o == IR_SUBOV) *ofsp -= k; else *ofsp += k;
463 tr = ir->op1; /* Not a TRef, but the caller doesn't care. */
464 }
465 return tr;
466}
467
468/* Record ctype __index/__newindex metamethods. */
469static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
470 RecordFFData *rd)
471{
472 CTypeID id = ctype_typeid(cts, ct);
473 cTValue *tv = lj_ctype_meta(cts, id, rd->data ? MM_newindex : MM_index);
474 if (!tv)
475 lj_trace_err(J, LJ_TRERR_BADTYPE);
476 if (tvisfunc(tv)) {
477 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
478 rd->nres = -1; /* Pending tailcall. */
479 } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) {
480 /* Specialize to result of __index lookup. */
481 cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]);
482 IRType t = itype2irt(o);
483 if (tvisgcv(o))
484 J->base[0] = lj_ir_kgc(J, gcV(o), t);
485 else if (tvisint(o))
486 J->base[0] = lj_ir_kint(J, intV(o));
487 else if (tvisnum(o))
488 J->base[0] = lj_ir_knumint(J, numV(o));
489 else if (tvisbool(o))
490 J->base[0] = TREF_PRI(t);
491 else
492 lj_trace_err(J, LJ_TRERR_BADTYPE);
493 /* Always specialize to the key. */
494 emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, strV(&rd->argv[1])));
495 } else {
496 /* NYI: resolving of non-function metamethods. */
497 /* NYI: non-string keys for __index table. */
498 /* NYI: stores to __newindex table. */
499 lj_trace_err(J, LJ_TRERR_BADTYPE);
500 }
501}
502
503void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
504{
505 TRef idx, ptr = J->base[0];
506 ptrdiff_t ofs = sizeof(GCcdata);
507 GCcdata *cd = argv2cdata(J, ptr, &rd->argv[0]);
508 CTState *cts = ctype_ctsG(J2G(J));
509 CType *ct = ctype_raw(cts, cd->typeid);
510 CTypeID sid = 0;
511
512 /* Resolve pointer or reference for cdata object. */
513 if (ctype_isptr(ct->info)) {
514 IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
515 if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
516 ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_PTR);
517 ofs = 0;
518 ptr = crec_reassoc_ofs(J, ptr, &ofs, 1);
519 }
520
521again:
522 idx = J->base[1];
523 if (tref_isnumber(idx)) {
524 idx = lj_opt_narrow_cindex(J, idx);
525 if (ctype_ispointer(ct->info)) {
526 CTSize sz;
527 integer_key:
528 if ((ct->info & CTF_COMPLEX))
529 idx = emitir(IRT(IR_BAND, IRT_INTP), idx, lj_ir_kintp(J, 1));
530 sz = lj_ctype_size(cts, (sid = ctype_cid(ct->info)));
531 idx = crec_reassoc_ofs(J, idx, &ofs, sz);
532#if LJ_TARGET_ARM || LJ_TARGET_PPC
533 /* Hoist base add to allow fusion of index/shift into operands. */
534 if (LJ_LIKELY(J->flags & JIT_F_OPT_LOOP) && ofs
535#if LJ_TARGET_ARM
536 && (sz == 1 || sz == 4)
537#endif
538 ) {
539 ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
540 ofs = 0;
541 }
542#endif
543 idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz));
544 ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr);
545 }
546 } else if (tref_iscdata(idx)) {
547 GCcdata *cdk = cdataV(&rd->argv[1]);
548 CType *ctk = ctype_raw(cts, cdk->typeid);
549 IRType t;
550 if (ctype_isenum(ctk->info)) ctk = ctype_child(cts, ctk);
551 if (ctype_ispointer(ct->info) &&
552 ctype_isinteger(ctk->info) && (t = crec_ct2irt(ctk)) != IRT_CDATA) {
553 if (ctk->size == 8) {
554 idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64);
555 } else {
556 idx = emitir(IRT(IR_ADD, IRT_PTR), idx,
557 lj_ir_kintp(J, sizeof(GCcdata)));
558 idx = emitir(IRT(IR_XLOAD, t), idx, 0);
559 }
560 if (LJ_64 && ctk->size < sizeof(intptr_t) && !(ctk->info & CTF_UNSIGNED))
561 idx = emitconv(idx, IRT_INTP, IRT_INT, IRCONV_SEXT);
562 if (!LJ_64 && ctk->size > sizeof(intptr_t)) {
563 idx = emitconv(idx, IRT_INTP, t, 0);
564 lj_needsplit(J);
565 }
566 goto integer_key;
567 }
568 } else if (tref_isstr(idx)) {
569 GCstr *name = strV(&rd->argv[1]);
570 if (cd->typeid == CTID_CTYPEID)
571 ct = ctype_raw(cts, crec_constructor(J, cd, ptr));
572 if (ctype_isstruct(ct->info)) {
573 CTSize fofs;
574 CType *fct;
575 fct = lj_ctype_getfield(cts, ct, name, &fofs);
576 if (fct) {
577 /* Always specialize to the field name. */
578 emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
579 if (ctype_isconstval(fct->info)) {
580 if (fct->size >= 0x80000000u &&
581 (ctype_child(cts, fct)->info & CTF_UNSIGNED)) {
582 J->base[0] = lj_ir_knum(J, (lua_Number)(uint32_t)fct->size);
583 return;
584 }
585 J->base[0] = lj_ir_kint(J, (int32_t)fct->size);
586 return; /* Interpreter will throw for newindex. */
587 } else if (ctype_isbitfield(fct->info)) {
588 lj_trace_err(J, LJ_TRERR_NYICONV);
589 } else {
590 lua_assert(ctype_isfield(fct->info));
591 sid = ctype_cid(fct->info);
592 }
593 ofs += (ptrdiff_t)fofs;
594 }
595 } else if (ctype_iscomplex(ct->info)) {
596 if (name->len == 2 &&
597 ((strdata(name)[0] == 'r' && strdata(name)[1] == 'e') ||
598 (strdata(name)[0] == 'i' && strdata(name)[1] == 'm'))) {
599 /* Always specialize to the field name. */
600 emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
601 if (strdata(name)[0] == 'i') ofs += (ct->size >> 1);
602 sid = ctype_cid(ct->info);
603 }
604 }
605 }
606 if (!sid) {
607 if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */
608 CType *cct = ctype_rawchild(cts, ct);
609 if (ctype_isstruct(cct->info)) {
610 ct = cct;
611 if (tref_isstr(idx)) goto again;
612 }
613 }
614 crec_index_meta(J, cts, ct, rd);
615 return;
616 }
617
618 if (ofs)
619 ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
620
621 /* Resolve reference for field. */
622 ct = ctype_get(cts, sid);
623 if (ctype_isref(ct->info))
624 ptr = emitir(IRT(IR_XLOAD, IRT_PTR), ptr, 0);
625
626 while (ctype_isattrib(ct->info))
627 ct = ctype_child(cts, ct); /* Skip attributes. */
628
629 if (rd->data == 0) { /* __index metamethod. */
630 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); /* Skip enums. */
631 J->base[0] = crec_tv_ct(J, ct, sid, ptr);
632 } else { /* __newindex metamethod. */
633 rd->nres = 0;
634 J->needsnap = 1;
635 crec_ct_tv(J, ct, ptr, J->base[2], &rd->argv[2]);
636 }
637}
638
639/* Record cdata allocation. */
640static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
641{
642 CTState *cts = ctype_ctsG(J2G(J));
643 CTSize sz;
644 CTInfo info = lj_ctype_info(cts, id, &sz);
645 CType *d = ctype_raw(cts, id);
646 TRef trid;
647 if (sz == 0 || sz > 64 || (info & CTF_VLA) || ctype_align(info) > CT_MEMALIGN)
648 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: large/special allocations. */
649 trid = lj_ir_kint(J, id);
650 /* Use special instruction to box pointer or 64 bit integer. */
651 if (ctype_isptr(info) || (ctype_isinteger(info) && sz == 8)) {
652 TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) :
653 ctype_isptr(info) ? lj_ir_kptr(J, NULL) :
654 (lj_needsplit(J), lj_ir_kint64(J, 0));
655 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp);
656 } else {
657 TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL);
658 cTValue *fin;
659 J->base[0] = trcd;
660 if (J->base[1] && !J->base[2] && !lj_cconv_multi_init(d, &rd->argv[1])) {
661 goto single_init;
662 } else if (ctype_isarray(d->info)) {
663 CType *dc = ctype_rawchild(cts, d); /* Array element type. */
664 CTSize ofs, esize = dc->size;
665 TRef sp = 0;
666 TValue tv;
667 TValue *sval = &tv;
668 MSize i;
669 tv.u64 = 0;
670 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info)))
671 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */
672 for (i = 1, ofs = 0; ofs < sz; ofs += esize) {
673 TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
674 lj_ir_kintp(J, ofs + sizeof(GCcdata)));
675 if (J->base[i]) {
676 sp = J->base[i];
677 sval = &rd->argv[i];
678 i++;
679 } else if (i != 2) {
680 sp = ctype_isnum(dc->info) ? lj_ir_kint(J, 0) : TREF_NIL;
681 }
682 crec_ct_tv(J, dc, dp, sp, sval);
683 }
684 } else if (ctype_isstruct(d->info)) {
685 CTypeID fid = d->sib;
686 MSize i = 1;
687 while (fid) {
688 CType *df = ctype_get(cts, fid);
689 fid = df->sib;
690 if (ctype_isfield(df->info)) {
691 CType *dc;
692 TRef sp, dp;
693 TValue tv;
694 TValue *sval = &tv;
695 setintV(&tv, 0);
696 if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
697 dc = ctype_rawchild(cts, df); /* Field type. */
698 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info)))
699 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init aggregates. */
700 if (J->base[i]) {
701 sp = J->base[i];
702 sval = &rd->argv[i];
703 i++;
704 } else {
705 sp = ctype_isnum(dc->info) ? lj_ir_kint(J, 0) : TREF_NIL;
706 }
707 dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
708 lj_ir_kintp(J, df->size + sizeof(GCcdata)));
709 crec_ct_tv(J, dc, dp, sp, sval);
710 } else if (!ctype_isconstval(df->info)) {
711 /* NYI: init bitfields and sub-structures. */
712 lj_trace_err(J, LJ_TRERR_NYICONV);
713 }
714 }
715 } else {
716 TRef dp;
717 single_init:
718 dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
719 if (J->base[1]) {
720 crec_ct_tv(J, d, dp, J->base[1], &rd->argv[1]);
721 } else {
722 TValue tv;
723 tv.u64 = 0;
724 crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv);
725 }
726 }
727 /* Handle __gc metamethod. */
728 fin = lj_ctype_meta(cts, id, MM_gc);
729 if (fin) {
730 TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd);
731 TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4));
732 if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; }
733 if (tvisfunc(fin)) {
734 emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin)));
735 emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC));
736 } else if (tviscdata(fin)) {
737 emitir(IRT(IR_XSTORE, IRT_P32), trlo,
738 lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA));
739 emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA));
740 } else {
741 lj_trace_err(J, LJ_TRERR_BADTYPE);
742 }
743 J->needsnap = 1;
744 }
745 }
746}
747
748/* Record argument conversions. */
749static TRef crec_call_args(jit_State *J, RecordFFData *rd,
750 CTState *cts, CType *ct)
751{
752 TRef args[CCI_NARGS_MAX];
753 CTypeID fid;
754 MSize i, n;
755 TRef tr, *base;
756 cTValue *o;
757#if LJ_TARGET_X86
758#if LJ_ABI_WIN
759 TRef *arg0 = NULL, *arg1 = NULL;
760#endif
761 int ngpr = 0;
762 if (ctype_cconv(ct->info) == CTCC_THISCALL)
763 ngpr = 1;
764 else if (ctype_cconv(ct->info) == CTCC_FASTCALL)
765 ngpr = 2;
766#endif
767
768 /* Skip initial attributes. */
769 fid = ct->sib;
770 while (fid) {
771 CType *ctf = ctype_get(cts, fid);
772 if (!ctype_isattrib(ctf->info)) break;
773 fid = ctf->sib;
774 }
775 args[0] = TREF_NIL;
776 for (n = 0, base = J->base+1, o = rd->argv+1; *base; n++, base++, o++) {
777 CTypeID did;
778 CType *d;
779
780 if (n >= CCI_NARGS_MAX)
781 lj_trace_err(J, LJ_TRERR_NYICALL);
782
783 if (fid) { /* Get argument type from field. */
784 CType *ctf = ctype_get(cts, fid);
785 fid = ctf->sib;
786 lua_assert(ctype_isfield(ctf->info));
787 did = ctype_cid(ctf->info);
788 } else {
789 if (!(ct->info & CTF_VARARG))
790 lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */
791 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
792 }
793 d = ctype_raw(cts, did);
794 if (!(ctype_isnum(d->info) || ctype_isptr(d->info) ||
795 ctype_isenum(d->info)))
796 lj_trace_err(J, LJ_TRERR_NYICALL);
797 tr = crec_ct_tv(J, d, 0, *base, o);
798 if (ctype_isinteger_or_bool(d->info)) {
799 if (d->size < 4) {
800 if ((d->info & CTF_UNSIGNED))
801 tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_U8 : IRT_U16, 0);
802 else
803 tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT);
804 }
805 }
806#if LJ_TARGET_X86
807 /* 64 bit args must not end up in registers for fastcall/thiscall. */
808#if LJ_ABI_WIN
809 if (!ctype_isfp(d->info)) {
810 /* Sigh, the Windows/x86 ABI allows reordering across 64 bit args. */
811 if (tref_typerange(tr, IRT_I64, IRT_U64)) {
812 if (ngpr) {
813 arg0 = &args[n]; args[n++] = TREF_NIL; ngpr--;
814 if (ngpr) {
815 arg1 = &args[n]; args[n++] = TREF_NIL; ngpr--;
816 }
817 }
818 } else {
819 if (arg0) { *arg0 = tr; arg0 = NULL; n--; continue; }
820 if (arg1) { *arg1 = tr; arg1 = NULL; n--; continue; }
821 if (ngpr) ngpr--;
822 }
823 }
824#else
825 if (!ctype_isfp(d->info) && ngpr) {
826 if (tref_typerange(tr, IRT_I64, IRT_U64)) {
827 /* No reordering for other x86 ABIs. Simply add alignment args. */
828 do { args[n++] = TREF_NIL; } while (--ngpr);
829 } else {
830 ngpr--;
831 }
832 }
833#endif
834#endif
835 args[n] = tr;
836 }
837 tr = args[0];
838 for (i = 1; i < n; i++)
839 tr = emitir(IRT(IR_CARG, IRT_NIL), tr, args[i]);
840 return tr;
841}
842
843/* Create a snapshot for the caller, simulating a 'false' return value. */
844static void crec_snap_caller(jit_State *J)
845{
846 lua_State *L = J->L;
847 TValue *base = L->base, *top = L->top;
848 const BCIns *pc = J->pc;
849 TRef ftr = J->base[-1];
850 ptrdiff_t delta;
851 if (!frame_islua(base-1))
852 lj_trace_err(J, LJ_TRERR_NYICALL);
853 J->pc = frame_pc(base-1); delta = 1+bc_a(J->pc[-1]);
854 L->top = base; L->base = base - delta;
855 J->base[-1] = TREF_FALSE;
856 J->base -= delta; J->baseslot -= (BCReg)delta;
857 J->maxslot = (BCReg)delta; J->framedepth--;
858 lj_snap_add(J);
859 L->base = base; L->top = top;
860 J->framedepth++; J->maxslot = 1;
861 J->base += delta; J->baseslot += (BCReg)delta;
862 J->base[-1] = ftr; J->pc = pc;
863}
864
865/* Record function call. */
866static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
867{
868 CTState *cts = ctype_ctsG(J2G(J));
869 CType *ct = ctype_raw(cts, cd->typeid);
870 IRType tp = IRT_PTR;
871 if (ctype_isptr(ct->info)) {
872 tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
873 ct = ctype_rawchild(cts, ct);
874 }
875 if (ctype_isfunc(ct->info)) {
876 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
877 CType *ctr = ctype_rawchild(cts, ct);
878 IRType t = crec_ct2irt(ctr);
879 TRef tr;
880 TValue tv;
881 /* Check for blacklisted C functions that might call a callback. */
882 setlightudV(&tv,
883 cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4));
884 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv)))
885 lj_trace_err(J, LJ_TRERR_BLACKL);
886 if (ctype_isvoid(ctr->info)) {
887 t = IRT_NIL;
888 rd->nres = 0;
889 } else if (ctype_isenum(ctr->info)) {
890 ctr = ctype_child(cts, ctr);
891 }
892 if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) ||
893 ctype_isvoid(ctr->info)) || t == IRT_CDATA)
894 lj_trace_err(J, LJ_TRERR_NYICALL);
895 if ((ct->info & CTF_VARARG)
896#if LJ_TARGET_X86
897 || ctype_cconv(ct->info) != CTCC_CDECL
898#endif
899 )
900 func = emitir(IRT(IR_CARG, IRT_NIL), func,
901 lj_ir_kint(J, ctype_typeid(cts, ct)));
902 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
903 if (ctype_isbool(ctr->info)) {
904 crec_snap_caller(J);
905 lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
906 J->postproc = LJ_POST_FIXGUARDSNAP;
907 tr = TREF_TRUE;
908 } else if (t == IRT_FLOAT || t == IRT_U32) {
909 tr = emitconv(tr, IRT_NUM, t, 0);
910 } else if (t == IRT_I8 || t == IRT_I16) {
911 tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
912 } else if (t == IRT_U8 || t == IRT_U16) {
913 tr = emitconv(tr, IRT_INT, t, 0);
914 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
915 (t == IRT_I64 || t == IRT_U64)) {
916 TRef trid = lj_ir_kint(J, ctype_cid(ct->info));
917 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
918 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
919 }
920 J->base[0] = tr;
921 J->needsnap = 1;
922 return 1;
923 }
924 return 0;
925}
926
927/* Record ctype call metamethod. */
928static void crec_call_meta(jit_State *J, RecordFFData *rd, CTypeID id)
929{
930 CTState *cts = ctype_ctsG(J2G(J));
931 CType *ct = ctype_raw(cts, id);
932 cTValue *tv;
933 if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
934 tv = lj_ctype_meta(cts, id, MM_call);
935 if (tv && tvisfunc(tv)) {
936 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
937 rd->nres = -1; /* Pending tailcall. */
938 } else {
939 /* NYI: non-function metamethods. */
940 lj_trace_err(J, LJ_TRERR_BADTYPE);
941 }
942}
943
944void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd)
945{
946 GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]);
947 if (cd->typeid == CTID_CTYPEID)
948 crec_alloc(J, rd, crec_constructor(J, cd, J->base[0]));
949 else if (!crec_call(J, rd, cd))
950 crec_call_meta(J, rd, cd->typeid);
951}
952
953static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
954{
955 if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) {
956 IRType dt;
957 CTypeID id;
958 TRef tr;
959 MSize i;
960 lj_needsplit(J);
961 if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) ||
962 ((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) {
963 dt = IRT_U64; id = CTID_UINT64;
964 } else {
965 dt = IRT_I64; id = CTID_INT64;
966 }
967 for (i = 0; i < 2; i++) {
968 IRType st = tref_type(sp[i]);
969 if (st == IRT_NUM || st == IRT_FLOAT)
970 sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY);
971 else if (!(st == IRT_I64 || st == IRT_U64))
972 sp[i] = emitconv(sp[i], dt, IRT_INT,
973 ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
974 }
975 if (mm < MM_add) {
976 /* Assume true comparison. Fixup and emit pending guard later. */
977 IROp op;
978 if (mm == MM_eq) {
979 op = IR_EQ;
980 } else {
981 op = mm == MM_lt ? IR_LT : IR_LE;
982 if (dt == IRT_U64)
983 op += (IR_ULT-IR_LT);
984 }
985 lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]);
986 J->postproc = LJ_POST_FIXGUARD;
987 return TREF_TRUE;
988 } else {
989 tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]);
990 }
991 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
992 }
993 return 0;
994}
995
996static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
997{
998 CTState *cts = ctype_ctsG(J2G(J));
999 CType *ctp = s[0];
1000 if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) {
1001 if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) &&
1002 (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
1003 if (mm == MM_sub) { /* Pointer difference. */
1004 TRef tr;
1005 CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
1006 if (sz == 0 || (sz & (sz-1)) != 0)
1007 return 0; /* NYI: integer division. */
1008 tr = emitir(IRT(IR_SUB, IRT_PTR), sp[0], sp[1]);
1009 tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz)));
1010#if LJ_64
1011 tr = emitconv(tr, IRT_NUM, IRT_INTP, 0);
1012#endif
1013 return tr;
1014 } else { /* Pointer comparison (unsigned). */
1015 /* Assume true comparison. Fixup and emit pending guard later. */
1016 IROp op = mm == MM_eq ? IR_EQ : mm == MM_lt ? IR_ULT : IR_ULE;
1017 lj_ir_set(J, IRTG(op, IRT_PTR), sp[0], sp[1]);
1018 J->postproc = LJ_POST_FIXGUARD;
1019 return TREF_TRUE;
1020 }
1021 }
1022 if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(s[1]->info)))
1023 return 0;
1024 } else if (mm == MM_add && ctype_isnum(ctp->info) &&
1025 (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
1026 TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */
1027 ctp = s[1];
1028 } else {
1029 return 0;
1030 }
1031 {
1032 TRef tr = sp[1];
1033 IRType t = tref_type(tr);
1034 CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
1035 CTypeID id;
1036#if LJ_64
1037 if (t == IRT_NUM || t == IRT_FLOAT)
1038 tr = emitconv(tr, IRT_INTP, t, IRCONV_TRUNC|IRCONV_ANY);
1039 else if (!(t == IRT_I64 || t == IRT_U64))
1040 tr = emitconv(tr, IRT_INTP, IRT_INT,
1041 ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
1042#else
1043 if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) {
1044 tr = emitconv(tr, IRT_INTP, t,
1045 (t == IRT_NUM || t == IRT_FLOAT) ?
1046 IRCONV_TRUNC|IRCONV_ANY : 0);
1047 }
1048#endif
1049 tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz));
1050 tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, IRT_PTR), sp[0], tr);
1051 id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)),
1052 CTSIZE_PTR);
1053 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1054 }
1055}
1056
1057/* Record ctype arithmetic metamethods. */
1058static void crec_arith_meta(jit_State *J, CTState *cts, RecordFFData *rd)
1059{
1060 cTValue *tv = NULL;
1061 if (J->base[0]) {
1062 if (tviscdata(&rd->argv[0]))
1063 tv = lj_ctype_meta(cts, argv2cdata(J, J->base[0], &rd->argv[0])->typeid,
1064 (MMS)rd->data);
1065 if (!tv && J->base[1] && tviscdata(&rd->argv[1]))
1066 tv = lj_ctype_meta(cts, argv2cdata(J, J->base[1], &rd->argv[1])->typeid,
1067 (MMS)rd->data);
1068 }
1069 if (tv && tvisfunc(tv)) {
1070 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
1071 rd->nres = -1; /* Pending tailcall. */
1072 } else {
1073 /* NYI: non-function metamethods. */
1074 lj_trace_err(J, LJ_TRERR_BADTYPE);
1075 }
1076}
1077
1078void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
1079{
1080 CTState *cts = ctype_ctsG(J2G(J));
1081 TRef sp[2];
1082 CType *s[2];
1083 MSize i;
1084 for (i = 0; i < 2; i++) {
1085 TRef tr = J->base[i];
1086 CType *ct = ctype_get(cts, CTID_DOUBLE);
1087 if (!tr) {
1088 goto trymeta;
1089 } else if (tref_iscdata(tr)) {
1090 CTypeID id = argv2cdata(J, tr, &rd->argv[i])->typeid;
1091 ct = ctype_raw(cts, id);
1092 if (ctype_isptr(ct->info)) { /* Resolve pointer or reference. */
1093 IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
1094 if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
1095 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR);
1096 } else if (ctype_isinteger(ct->info) && ct->size == 8) {
1097 IRType t = (ct->info & CTF_UNSIGNED) ? IRT_U64 : IRT_I64;
1098 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64);
1099 lj_needsplit(J);
1100 goto ok;
1101 } else if (ctype_isfunc(ct->info)) {
1102 tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
1103 ct = ctype_get(cts,
1104 lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
1105 } else {
1106 tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
1107 }
1108 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1109 if (ctype_isnum(ct->info)) {
1110 IRType t = crec_ct2irt(ct);
1111 if (t == IRT_CDATA) goto trymeta;
1112 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1113 tr = emitir(IRT(IR_XLOAD, t), tr, 0);
1114 } else if (!(ctype_isptr(ct->info) || ctype_isrefarray(ct->info))) {
1115 goto trymeta;
1116 }
1117 } else if (tref_isnil(tr)) {
1118 tr = lj_ir_kptr(J, NULL);
1119 ct = ctype_get(cts, CTID_P_VOID);
1120 } else if (tref_isinteger(tr)) {
1121 ct = ctype_get(cts, CTID_INT32);
1122 } else if (!tref_isnum(tr)) {
1123 goto trymeta;
1124 }
1125 ok:
1126 s[i] = ct;
1127 sp[i] = tr;
1128 }
1129 {
1130 TRef tr;
1131 if ((tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) ||
1132 (tr = crec_arith_ptr(J, sp, s, (MMS)rd->data))) {
1133 J->base[0] = tr;
1134 /* Fixup cdata comparisons, too. Avoids some cdata escapes. */
1135 if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) &&
1136 !irt_isguard(J->guardemit)) {
1137 const BCIns *pc = frame_contpc(J->L->base-1) - 1;
1138 if (bc_op(*pc) <= BC_ISNEP) {
1139 setframe_pc(&J2G(J)->tmptv, pc);
1140 J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1);
1141 J->postproc = LJ_POST_FIXCOMP;
1142 }
1143 }
1144 } else {
1145 trymeta:
1146 crec_arith_meta(J, cts, rd);
1147 }
1148 }
1149}
1150
1151/* -- C library namespace metamethods ------------------------------------- */
1152
1153void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd)
1154{
1155 CTState *cts = ctype_ctsG(J2G(J));
1156 if (tref_isudata(J->base[0]) && tref_isstr(J->base[1]) &&
1157 udataV(&rd->argv[0])->udtype == UDTYPE_FFI_CLIB) {
1158 CLibrary *cl = (CLibrary *)uddata(udataV(&rd->argv[0]));
1159 GCstr *name = strV(&rd->argv[1]);
1160 CType *ct;
1161 CTypeID id = lj_ctype_getname(cts, &ct, name, CLNS_INDEX);
1162 cTValue *tv = lj_tab_getstr(cl->cache, name);
1163 rd->nres = rd->data;
1164 if (id && tv && !tvisnil(tv)) {
1165 /* Specialize to the symbol name and make the result a constant. */
1166 emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, name));
1167 if (ctype_isconstval(ct->info)) {
1168 if (ct->size >= 0x80000000u &&
1169 (ctype_child(cts, ct)->info & CTF_UNSIGNED))
1170 J->base[0] = lj_ir_knum(J, (lua_Number)(uint32_t)ct->size);
1171 else
1172 J->base[0] = lj_ir_kint(J, (int32_t)ct->size);
1173 } else if (ctype_isextern(ct->info)) {
1174 CTypeID sid = ctype_cid(ct->info);
1175 void *sp = *(void **)cdataptr(cdataV(tv));
1176 TRef ptr;
1177 ct = ctype_raw(cts, sid);
1178 if (rd->data && ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1179 if (LJ_64 && !checkptr32(sp))
1180 ptr = lj_ir_kintp(J, (uintptr_t)sp);
1181 else
1182 ptr = lj_ir_kptr(J, sp);
1183 if (rd->data) {
1184 J->base[0] = crec_tv_ct(J, ct, sid, ptr);
1185 } else {
1186 J->needsnap = 1;
1187 crec_ct_tv(J, ct, ptr, J->base[2], &rd->argv[2]);
1188 }
1189 } else {
1190 J->base[0] = lj_ir_kgc(J, obj2gco(cdataV(tv)), IRT_CDATA);
1191 }
1192 } else {
1193 lj_trace_err(J, LJ_TRERR_NOCACHE);
1194 }
1195 } /* else: interpreter will throw. */
1196}
1197
1198/* -- FFI library functions ----------------------------------------------- */
1199
1200static TRef crec_toint(jit_State *J, CTState *cts, TRef sp, TValue *sval)
1201{
1202 return crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, sp, sval);
1203}
1204
1205void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd)
1206{
1207 crec_alloc(J, rd, argv2ctype(J, J->base[0], &rd->argv[0]));
1208}
1209
1210void LJ_FASTCALL recff_ffi_errno(jit_State *J, RecordFFData *rd)
1211{
1212 UNUSED(rd);
1213 if (J->base[0])
1214 lj_trace_err(J, LJ_TRERR_NYICALL);
1215 J->base[0] = lj_ir_call(J, IRCALL_lj_vm_errno);
1216}
1217
1218void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd)
1219{
1220 CTState *cts = ctype_ctsG(J2G(J));
1221 TRef tr = J->base[0];
1222 if (tr) {
1223 TRef trlen = J->base[1];
1224 if (trlen) {
1225 trlen = crec_toint(J, cts, trlen, &rd->argv[1]);
1226 tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, tr, &rd->argv[0]);
1227 } else {
1228 tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CCHAR), 0, tr, &rd->argv[0]);
1229 trlen = lj_ir_call(J, IRCALL_strlen, tr);
1230 }
1231 J->base[0] = emitir(IRT(IR_XSNEW, IRT_STR), tr, trlen);
1232 } /* else: interpreter will throw. */
1233}
1234
1235void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd)
1236{
1237 CTState *cts = ctype_ctsG(J2G(J));
1238 TRef trdst = J->base[0], trsrc = J->base[1], trlen = J->base[2];
1239 if (trdst && trsrc && (trlen || tref_isstr(trsrc))) {
1240 trdst = crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, trdst, &rd->argv[0]);
1241 trsrc = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, trsrc, &rd->argv[1]);
1242 if (trlen) {
1243 trlen = crec_toint(J, cts, trlen, &rd->argv[2]);
1244 } else {
1245 trlen = emitir(IRTI(IR_FLOAD), J->base[1], IRFL_STR_LEN);
1246 trlen = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
1247 }
1248 lj_ir_call(J, IRCALL_memcpy, trdst, trsrc, trlen);
1249 emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
1250 rd->nres = 0;
1251 } /* else: interpreter will throw. */
1252}
1253
1254void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd)
1255{
1256 CTState *cts = ctype_ctsG(J2G(J));
1257 TRef tr = J->base[0], trlen = J->base[1], trfill = J->base[2];
1258 if (tr && trlen) {
1259 tr = crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, tr, &rd->argv[0]);
1260 trlen = crec_toint(J, cts, trlen, &rd->argv[1]);
1261 if (trfill)
1262 trfill = crec_toint(J, cts, trfill, &rd->argv[2]);
1263 else
1264 trfill = lj_ir_kint(J, 0);
1265 lj_ir_call(J, IRCALL_memset, tr, trfill, trlen);
1266 emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
1267 rd->nres = 0;
1268 } /* else: interpreter will throw. */
1269}
1270
1271void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd)
1272{
1273 argv2ctype(J, J->base[0], &rd->argv[0]);
1274 if (tref_iscdata(J->base[1])) {
1275 argv2ctype(J, J->base[1], &rd->argv[1]);
1276 J->postproc = LJ_POST_FIXBOOL;
1277 J->base[0] = TREF_TRUE;
1278 } else {
1279 J->base[0] = TREF_FALSE;
1280 }
1281}
1282
1283void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd)
1284{
1285 if (tref_isstr(J->base[0])) {
1286 /* Specialize to the ABI string to make the boolean result a constant. */
1287 emitir(IRTG(IR_EQ, IRT_STR), J->base[0], lj_ir_kstr(J, strV(&rd->argv[0])));
1288 J->postproc = LJ_POST_FIXBOOL;
1289 J->base[0] = TREF_TRUE;
1290 } /* else: interpreter will throw. */
1291}
1292
1293/* -- Miscellaneous library functions ------------------------------------- */
1294
1295void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
1296{
1297 CTState *cts = ctype_ctsG(J2G(J));
1298 CType *d, *ct = lj_ctype_rawref(cts, cdataV(&rd->argv[0])->typeid);
1299 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1300 if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
1301 if (ctype_isinteger_or_bool(ct->info) && ct->size <= 4 &&
1302 !(ct->size == 4 && (ct->info & CTF_UNSIGNED)))
1303 d = ctype_get(cts, CTID_INT32);
1304 else
1305 d = ctype_get(cts, CTID_DOUBLE);
1306 J->base[0] = crec_ct_tv(J, d, 0, J->base[0], &rd->argv[0]);
1307 } else {
1308 J->base[0] = TREF_NIL;
1309 }
1310}
1311
1312#undef IR
1313#undef emitir
1314#undef emitconv
1315
1316#endif
diff --git a/libraries/luajit-2.0/src/lj_crecord.h b/libraries/luajit-2.0/src/lj_crecord.h
new file mode 100644
index 0000000..fb042c5
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_crecord.h
@@ -0,0 +1,40 @@
1/*
2** Trace recorder for C data operations.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CRECORD_H
7#define _LJ_CRECORD_H
8
9#include "lj_obj.h"
10#include "lj_jit.h"
11#include "lj_ffrecord.h"
12
13#if LJ_HASJIT && LJ_HASFFI
14LJ_FUNC void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd);
15LJ_FUNC void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd);
16LJ_FUNC void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd);
17LJ_FUNC void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd);
18LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd);
19LJ_FUNC void LJ_FASTCALL recff_ffi_errno(jit_State *J, RecordFFData *rd);
20LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
21LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd);
22LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd);
23LJ_FUNC void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd);
24LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd);
25LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
26#else
27#define recff_cdata_index recff_nyi
28#define recff_cdata_call recff_nyi
29#define recff_cdata_arith recff_nyi
30#define recff_clib_index recff_nyi
31#define recff_ffi_new recff_nyi
32#define recff_ffi_errno recff_nyi
33#define recff_ffi_string recff_nyi
34#define recff_ffi_copy recff_nyi
35#define recff_ffi_fill recff_nyi
36#define recff_ffi_istype recff_nyi
37#define recff_ffi_abi recff_nyi
38#endif
39
40#endif
diff --git a/libraries/luajit-2.0/src/lj_ctype.c b/libraries/luajit-2.0/src/lj_ctype.c
new file mode 100644
index 0000000..7187d6f
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ctype.c
@@ -0,0 +1,607 @@
1/*
2** C type management.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include "lj_obj.h"
7
8#if LJ_HASFFI
9
10#include "lj_gc.h"
11#include "lj_err.h"
12#include "lj_str.h"
13#include "lj_tab.h"
14#include "lj_ctype.h"
15#include "lj_ccallback.h"
16
17/* -- C type definitions -------------------------------------------------- */
18
19/* Predefined typedefs. */
20#define CTTDDEF(_) \
21 /* Vararg handling. */ \
22 _("va_list", P_VOID) \
23 _("__builtin_va_list", P_VOID) \
24 _("__gnuc_va_list", P_VOID) \
25 /* From stddef.h. */ \
26 _("ptrdiff_t", INT_PSZ) \
27 _("size_t", UINT_PSZ) \
28 _("wchar_t", WCHAR) \
29 /* Subset of stdint.h. */ \
30 _("int8_t", INT8) \
31 _("int16_t", INT16) \
32 _("int32_t", INT32) \
33 _("int64_t", INT64) \
34 _("uint8_t", UINT8) \
35 _("uint16_t", UINT16) \
36 _("uint32_t", UINT32) \
37 _("uint64_t", UINT64) \
38 _("intptr_t", INT_PSZ) \
39 _("uintptr_t", UINT_PSZ) \
40 /* End of typedef list. */
41
42/* Keywords (only the ones we actually care for). */
43#define CTKWDEF(_) \
44 /* Type specifiers. */ \
45 _("void", -1, CTOK_VOID) \
46 _("_Bool", 1, CTOK_BOOL) \
47 _("bool", 1, CTOK_BOOL) \
48 _("char", 1, CTOK_CHAR) \
49 _("int", 4, CTOK_INT) \
50 _("__int8", 1, CTOK_INT) \
51 _("__int16", 2, CTOK_INT) \
52 _("__int32", 4, CTOK_INT) \
53 _("__int64", 8, CTOK_INT) \
54 _("float", 4, CTOK_FP) \
55 _("double", 8, CTOK_FP) \
56 _("long", 0, CTOK_LONG) \
57 _("short", 0, CTOK_SHORT) \
58 _("_Complex", 0, CTOK_COMPLEX) \
59 _("complex", 0, CTOK_COMPLEX) \
60 _("__complex", 0, CTOK_COMPLEX) \
61 _("__complex__", 0, CTOK_COMPLEX) \
62 _("signed", 0, CTOK_SIGNED) \
63 _("__signed", 0, CTOK_SIGNED) \
64 _("__signed__", 0, CTOK_SIGNED) \
65 _("unsigned", 0, CTOK_UNSIGNED) \
66 /* Type qualifiers. */ \
67 _("const", 0, CTOK_CONST) \
68 _("__const", 0, CTOK_CONST) \
69 _("__const__", 0, CTOK_CONST) \
70 _("volatile", 0, CTOK_VOLATILE) \
71 _("__volatile", 0, CTOK_VOLATILE) \
72 _("__volatile__", 0, CTOK_VOLATILE) \
73 _("restrict", 0, CTOK_RESTRICT) \
74 _("__restrict", 0, CTOK_RESTRICT) \
75 _("__restrict__", 0, CTOK_RESTRICT) \
76 _("inline", 0, CTOK_INLINE) \
77 _("__inline", 0, CTOK_INLINE) \
78 _("__inline__", 0, CTOK_INLINE) \
79 /* Storage class specifiers. */ \
80 _("typedef", 0, CTOK_TYPEDEF) \
81 _("extern", 0, CTOK_EXTERN) \
82 _("static", 0, CTOK_STATIC) \
83 _("auto", 0, CTOK_AUTO) \
84 _("register", 0, CTOK_REGISTER) \
85 /* GCC Attributes. */ \
86 _("__extension__", 0, CTOK_EXTENSION) \
87 _("__attribute", 0, CTOK_ATTRIBUTE) \
88 _("__attribute__", 0, CTOK_ATTRIBUTE) \
89 _("asm", 0, CTOK_ASM) \
90 _("__asm", 0, CTOK_ASM) \
91 _("__asm__", 0, CTOK_ASM) \
92 /* MSVC Attributes. */ \
93 _("__declspec", 0, CTOK_DECLSPEC) \
94 _("__cdecl", CTCC_CDECL, CTOK_CCDECL) \
95 _("__thiscall", CTCC_THISCALL, CTOK_CCDECL) \
96 _("__fastcall", CTCC_FASTCALL, CTOK_CCDECL) \
97 _("__stdcall", CTCC_STDCALL, CTOK_CCDECL) \
98 _("__ptr32", 4, CTOK_PTRSZ) \
99 _("__ptr64", 8, CTOK_PTRSZ) \
100 /* Other type specifiers. */ \
101 _("struct", 0, CTOK_STRUCT) \
102 _("union", 0, CTOK_UNION) \
103 _("enum", 0, CTOK_ENUM) \
104 /* Operators. */ \
105 _("sizeof", 0, CTOK_SIZEOF) \
106 _("__alignof", 0, CTOK_ALIGNOF) \
107 _("__alignof__", 0, CTOK_ALIGNOF) \
108 /* End of keyword list. */
109
110/* Type info for predefined types. Size merged in. */
111static CTInfo lj_ctype_typeinfo[] = {
112#define CTTYINFODEF(id, sz, ct, info) CTINFO((ct),(((sz)&0x3fu)<<10)+(info)),
113#define CTTDINFODEF(name, id) CTINFO(CT_TYPEDEF, CTID_##id),
114#define CTKWINFODEF(name, sz, kw) CTINFO(CT_KW,(((sz)&0x3fu)<<10)+(kw)),
115CTTYDEF(CTTYINFODEF)
116CTTDDEF(CTTDINFODEF)
117CTKWDEF(CTKWINFODEF)
118#undef CTTYINFODEF
119#undef CTTDINFODEF
120#undef CTKWINFODEF
121 0
122};
123
124/* Predefined type names collected in a single string. */
125static const char * const lj_ctype_typenames =
126#define CTTDNAMEDEF(name, id) name "\0"
127#define CTKWNAMEDEF(name, sz, cds) name "\0"
128CTTDDEF(CTTDNAMEDEF)
129CTKWDEF(CTKWNAMEDEF)
130#undef CTTDNAMEDEF
131#undef CTKWNAMEDEF
132;
133
134#define CTTYPEINFO_NUM (sizeof(lj_ctype_typeinfo)/sizeof(CTInfo)-1)
135#define CTTYPETAB_MIN 128
136
137/* -- C type interning ---------------------------------------------------- */
138
139#define ct_hashtype(info, size) (hashrot(info, size) & CTHASH_MASK)
140#define ct_hashname(name) \
141 (hashrot(u32ptr(name), u32ptr(name) + HASH_BIAS) & CTHASH_MASK)
142
143/* Create new type element. */
144CTypeID lj_ctype_new(CTState *cts, CType **ctp)
145{
146 CTypeID id = cts->top;
147 CType *ct;
148 lua_assert(cts->L);
149 if (LJ_UNLIKELY(id >= cts->sizetab)) {
150 if (id >= CTID_MAX) lj_err_msg(cts->L, LJ_ERR_TABOV);
151 lj_mem_growvec(cts->L, cts->tab, cts->sizetab, CTID_MAX, CType);
152 }
153 cts->top = id+1;
154 *ctp = ct = &cts->tab[id];
155 ct->info = 0;
156 ct->size = 0;
157 ct->sib = 0;
158 ct->next = 0;
159 setgcrefnull(ct->name);
160 return id;
161}
162
163/* Intern a type element. */
164CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size)
165{
166 uint32_t h = ct_hashtype(info, size);
167 CTypeID id = cts->hash[h];
168 lua_assert(cts->L);
169 while (id) {
170 CType *ct = ctype_get(cts, id);
171 if (ct->info == info && ct->size == size)
172 return id;
173 id = ct->next;
174 }
175 id = cts->top;
176 if (LJ_UNLIKELY(id >= cts->sizetab)) {
177 if (id >= CTID_MAX) lj_err_msg(cts->L, LJ_ERR_TABOV);
178 lj_mem_growvec(cts->L, cts->tab, cts->sizetab, CTID_MAX, CType);
179 }
180 cts->top = id+1;
181 cts->tab[id].info = info;
182 cts->tab[id].size = size;
183 cts->tab[id].sib = 0;
184 cts->tab[id].next = cts->hash[h];
185 setgcrefnull(cts->tab[id].name);
186 cts->hash[h] = (CTypeID1)id;
187 return id;
188}
189
190/* Add type element to hash table. */
191static void ctype_addtype(CTState *cts, CType *ct, CTypeID id)
192{
193 uint32_t h = ct_hashtype(ct->info, ct->size);
194 ct->next = cts->hash[h];
195 cts->hash[h] = (CTypeID1)id;
196}
197
198/* Add named element to hash table. */
199void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id)
200{
201 uint32_t h = ct_hashname(gcref(ct->name));
202 ct->next = cts->hash[h];
203 cts->hash[h] = (CTypeID1)id;
204}
205
206/* Get a C type by name, matching the type mask. */
207CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name, uint32_t tmask)
208{
209 CTypeID id = cts->hash[ct_hashname(name)];
210 while (id) {
211 CType *ct = ctype_get(cts, id);
212 if (gcref(ct->name) == obj2gco(name) &&
213 ((tmask >> ctype_type(ct->info)) & 1)) {
214 *ctp = ct;
215 return id;
216 }
217 id = ct->next;
218 }
219 *ctp = &cts->tab[0]; /* Simplify caller logic. ctype_get() would assert. */
220 return 0;
221}
222
223/* Get a struct/union/enum/function field by name. */
224CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name, CTSize *ofs)
225{
226 while (ct->sib) {
227 ct = ctype_get(cts, ct->sib);
228 if (gcref(ct->name) == obj2gco(name)) {
229 *ofs = ct->size;
230 return ct;
231 }
232 if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) {
233 CType *fct = lj_ctype_getfield(cts, ctype_child(cts, ct), name, ofs);
234 if (fct) {
235 *ofs += ct->size;
236 return fct;
237 }
238 }
239 }
240 return NULL; /* Not found. */
241}
242
243/* -- C type information -------------------------------------------------- */
244
245/* Follow references and get raw type for a C type ID. */
246CType *lj_ctype_rawref(CTState *cts, CTypeID id)
247{
248 CType *ct = ctype_get(cts, id);
249 while (ctype_isattrib(ct->info) || ctype_isref(ct->info))
250 ct = ctype_child(cts, ct);
251 return ct;
252}
253
254/* Get size for a C type ID. Does NOT support VLA/VLS. */
255CTSize lj_ctype_size(CTState *cts, CTypeID id)
256{
257 CType *ct = ctype_raw(cts, id);
258 return ctype_hassize(ct->info) ? ct->size : CTSIZE_INVALID;
259}
260
261/* Get size for a variable-length C type. Does NOT support other C types. */
262CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem)
263{
264 uint64_t xsz = 0;
265 if (ctype_isstruct(ct->info)) {
266 CTypeID arrid = 0, fid = ct->sib;
267 xsz = ct->size; /* Add the struct size. */
268 while (fid) {
269 CType *ctf = ctype_get(cts, fid);
270 if (ctype_type(ctf->info) == CT_FIELD)
271 arrid = ctype_cid(ctf->info); /* Remember last field of VLS. */
272 fid = ctf->sib;
273 }
274 ct = ctype_raw(cts, arrid);
275 }
276 lua_assert(ctype_isvlarray(ct->info)); /* Must be a VLA. */
277 ct = ctype_rawchild(cts, ct); /* Get array element. */
278 lua_assert(ctype_hassize(ct->info));
279 /* Calculate actual size of VLA and check for overflow. */
280 xsz += (uint64_t)ct->size * nelem;
281 return xsz < 0x80000000u ? (CTSize)xsz : CTSIZE_INVALID;
282}
283
284/* Get type, qualifiers, size and alignment for a C type ID. */
285CTInfo lj_ctype_info(CTState *cts, CTypeID id, CTSize *szp)
286{
287 CTInfo qual = 0;
288 CType *ct = ctype_get(cts, id);
289 for (;;) {
290 CTInfo info = ct->info;
291 if (ctype_isenum(info)) {
292 /* Follow child. Need to look at its attributes, too. */
293 } else if (ctype_isattrib(info)) {
294 if (ctype_isxattrib(info, CTA_QUAL))
295 qual |= ct->size;
296 else if (ctype_isxattrib(info, CTA_ALIGN) && !(qual & CTFP_ALIGNED))
297 qual |= CTFP_ALIGNED + CTALIGN(ct->size);
298 } else {
299 if (!(qual & CTFP_ALIGNED)) qual |= (info & CTF_ALIGN);
300 qual |= (info & ~(CTF_ALIGN|CTMASK_CID));
301 lua_assert(ctype_hassize(info) || ctype_isfunc(info));
302 *szp = ctype_isfunc(info) ? CTSIZE_INVALID : ct->size;
303 break;
304 }
305 ct = ctype_get(cts, ctype_cid(info));
306 }
307 return qual;
308}
309
310/* Get ctype metamethod. */
311cTValue *lj_ctype_meta(CTState *cts, CTypeID id, MMS mm)
312{
313 CType *ct = ctype_get(cts, id);
314 cTValue *tv;
315 while (ctype_isattrib(ct->info) || ctype_isref(ct->info)) {
316 id = ctype_cid(ct->info);
317 ct = ctype_get(cts, id);
318 }
319 if (ctype_isptr(ct->info) &&
320 ctype_isfunc(ctype_get(cts, ctype_cid(ct->info))->info))
321 tv = lj_tab_getstr(cts->miscmap, &cts->g->strempty);
322 else
323 tv = lj_tab_getinth(cts->miscmap, -(int32_t)id);
324 if (tv && tvistab(tv) &&
325 (tv = lj_tab_getstr(tabV(tv), mmname_str(cts->g, mm))) && !tvisnil(tv))
326 return tv;
327 return NULL;
328}
329
330/* -- C type representation ----------------------------------------------- */
331
332/* Fixed max. length of a C type representation. */
333#define CTREPR_MAX 512
334
335typedef struct CTRepr {
336 char *pb, *pe;
337 CTState *cts;
338 lua_State *L;
339 int needsp;
340 int ok;
341 char buf[CTREPR_MAX];
342} CTRepr;
343
344/* Prepend string. */
345static void ctype_prepstr(CTRepr *ctr, const char *str, MSize len)
346{
347 char *p = ctr->pb;
348 if (ctr->buf + len+1 > p) { ctr->ok = 0; return; }
349 if (ctr->needsp) *--p = ' ';
350 ctr->needsp = 1;
351 p -= len;
352 while (len-- > 0) p[len] = str[len];
353 ctr->pb = p;
354}
355
356#define ctype_preplit(ctr, str) ctype_prepstr((ctr), "" str, sizeof(str)-1)
357
358/* Prepend char. */
359static void ctype_prepc(CTRepr *ctr, int c)
360{
361 if (ctr->buf >= ctr->pb) { ctr->ok = 0; return; }
362 *--ctr->pb = c;
363}
364
365/* Prepend number. */
366static void ctype_prepnum(CTRepr *ctr, uint32_t n)
367{
368 char *p = ctr->pb;
369 if (ctr->buf + 10+1 > p) { ctr->ok = 0; return; }
370 do { *--p = (char)('0' + n % 10); } while (n /= 10);
371 ctr->pb = p;
372 ctr->needsp = 0;
373}
374
375/* Append char. */
376static void ctype_appc(CTRepr *ctr, int c)
377{
378 if (ctr->pe >= ctr->buf + CTREPR_MAX) { ctr->ok = 0; return; }
379 *ctr->pe++ = c;
380}
381
382/* Append number. */
383static void ctype_appnum(CTRepr *ctr, uint32_t n)
384{
385 char buf[10];
386 char *p = buf+sizeof(buf);
387 char *q = ctr->pe;
388 if (q > ctr->buf + CTREPR_MAX - 10) { ctr->ok = 0; return; }
389 do { *--p = (char)('0' + n % 10); } while (n /= 10);
390 do { *q++ = *p++; } while (p < buf+sizeof(buf));
391 ctr->pe = q;
392}
393
394/* Prepend qualifiers. */
395static void ctype_prepqual(CTRepr *ctr, CTInfo info)
396{
397 if ((info & CTF_VOLATILE)) ctype_preplit(ctr, "volatile");
398 if ((info & CTF_CONST)) ctype_preplit(ctr, "const");
399}
400
401/* Prepend named type. */
402static void ctype_preptype(CTRepr *ctr, CType *ct, CTInfo qual, const char *t)
403{
404 if (gcref(ct->name)) {
405 GCstr *str = gco2str(gcref(ct->name));
406 ctype_prepstr(ctr, strdata(str), str->len);
407 } else {
408 if (ctr->needsp) ctype_prepc(ctr, ' ');
409 ctype_prepnum(ctr, ctype_typeid(ctr->cts, ct));
410 ctr->needsp = 1;
411 }
412 ctype_prepstr(ctr, t, (MSize)strlen(t));
413 ctype_prepqual(ctr, qual);
414}
415
416static void ctype_repr(CTRepr *ctr, CTypeID id)
417{
418 CType *ct = ctype_get(ctr->cts, id);
419 CTInfo qual = 0;
420 int ptrto = 0;
421 for (;;) {
422 CTInfo info = ct->info;
423 CTSize size = ct->size;
424 switch (ctype_type(info)) {
425 case CT_NUM:
426 if ((info & CTF_BOOL)) {
427 ctype_preplit(ctr, "bool");
428 } else if ((info & CTF_FP)) {
429 if (size == sizeof(double)) ctype_preplit(ctr, "double");
430 else if (size == sizeof(float)) ctype_preplit(ctr, "float");
431 else ctype_preplit(ctr, "long double");
432 } else if (size == 1) {
433 if (!((info ^ CTF_UCHAR) & CTF_UNSIGNED)) ctype_preplit(ctr, "char");
434 else if (CTF_UCHAR) ctype_preplit(ctr, "signed char");
435 else ctype_preplit(ctr, "unsigned char");
436 } else if (size < 8) {
437 if (size == 4) ctype_preplit(ctr, "int");
438 else ctype_preplit(ctr, "short");
439 if ((info & CTF_UNSIGNED)) ctype_preplit(ctr, "unsigned");
440 } else {
441 ctype_preplit(ctr, "_t");
442 ctype_prepnum(ctr, size*8);
443 ctype_preplit(ctr, "int");
444 if ((info & CTF_UNSIGNED)) ctype_prepc(ctr, 'u');
445 }
446 ctype_prepqual(ctr, (qual|info));
447 return;
448 case CT_VOID:
449 ctype_preplit(ctr, "void");
450 ctype_prepqual(ctr, (qual|info));
451 return;
452 case CT_STRUCT:
453 ctype_preptype(ctr, ct, qual, (info & CTF_UNION) ? "union" : "struct");
454 return;
455 case CT_ENUM:
456 ctype_preptype(ctr, ct, qual, "enum");
457 return;
458 case CT_ATTRIB:
459 if (ctype_attrib(info) == CTA_QUAL) qual |= size;
460 break;
461 case CT_PTR:
462 if ((info & CTF_REF)) {
463 ctype_prepc(ctr, '&');
464 } else {
465 ctype_prepqual(ctr, (qual|info));
466 if (LJ_64 && size == 4) ctype_preplit(ctr, "__ptr32");
467 ctype_prepc(ctr, '*');
468 }
469 qual = 0;
470 ptrto = 1;
471 ctr->needsp = 1;
472 break;
473 case CT_ARRAY:
474 if (ctype_isrefarray(info)) {
475 ctr->needsp = 1;
476 if (ptrto) { ptrto = 0; ctype_prepc(ctr, '('); ctype_appc(ctr, ')'); }
477 ctype_appc(ctr, '[');
478 if (size != CTSIZE_INVALID) {
479 CTSize csize = ctype_child(ctr->cts, ct)->size;
480 ctype_appnum(ctr, csize ? size/csize : 0);
481 } else if ((info & CTF_VLA)) {
482 ctype_appc(ctr, '?');
483 }
484 ctype_appc(ctr, ']');
485 } else if ((info & CTF_COMPLEX)) {
486 if (size == 2*sizeof(float)) ctype_preplit(ctr, "float");
487 ctype_preplit(ctr, "complex");
488 return;
489 } else {
490 ctype_preplit(ctr, ")))");
491 ctype_prepnum(ctr, size);
492 ctype_preplit(ctr, "__attribute__((vector_size(");
493 }
494 break;
495 case CT_FUNC:
496 ctr->needsp = 1;
497 if (ptrto) { ptrto = 0; ctype_prepc(ctr, '('); ctype_appc(ctr, ')'); }
498 ctype_appc(ctr, '(');
499 ctype_appc(ctr, ')');
500 break;
501 default:
502 lua_assert(0);
503 break;
504 }
505 ct = ctype_get(ctr->cts, ctype_cid(info));
506 }
507}
508
509/* Return a printable representation of a C type. */
510GCstr *lj_ctype_repr(lua_State *L, CTypeID id, GCstr *name)
511{
512 global_State *g = G(L);
513 CTRepr ctr;
514 ctr.pb = ctr.pe = &ctr.buf[CTREPR_MAX/2];
515 ctr.cts = ctype_ctsG(g);
516 ctr.L = L;
517 ctr.ok = 1;
518 ctr.needsp = 0;
519 if (name) ctype_prepstr(&ctr, strdata(name), name->len);
520 ctype_repr(&ctr, id);
521 if (LJ_UNLIKELY(!ctr.ok)) return lj_str_newlit(L, "?");
522 return lj_str_new(L, ctr.pb, ctr.pe - ctr.pb);
523}
524
525/* Convert int64_t/uint64_t to string with 'LL' or 'ULL' suffix. */
526GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned)
527{
528 char buf[1+20+3];
529 char *p = buf+sizeof(buf);
530 int sign = 0;
531 *--p = 'L'; *--p = 'L';
532 if (isunsigned) {
533 *--p = 'U';
534 } else if ((int64_t)n < 0) {
535 n = (uint64_t)-(int64_t)n;
536 sign = 1;
537 }
538 do { *--p = (char)('0' + n % 10); } while (n /= 10);
539 if (sign) *--p = '-';
540 return lj_str_new(L, p, (size_t)(buf+sizeof(buf)-p));
541}
542
543/* Convert complex to string with 'i' or 'I' suffix. */
544GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size)
545{
546 char buf[2*LJ_STR_NUMBUF+2+1];
547 TValue re, im;
548 size_t len;
549 if (size == 2*sizeof(double)) {
550 re.n = *(double *)sp; im.n = ((double *)sp)[1];
551 } else {
552 re.n = (double)*(float *)sp; im.n = (double)((float *)sp)[1];
553 }
554 len = lj_str_bufnum(buf, &re);
555 if (!(im.u32.hi & 0x80000000u) || im.n != im.n) buf[len++] = '+';
556 len += lj_str_bufnum(buf+len, &im);
557 buf[len] = buf[len-1] >= 'a' ? 'I' : 'i';
558 return lj_str_new(L, buf, len+1);
559}
560
561/* -- C type state -------------------------------------------------------- */
562
563/* Initialize C type table and state. */
564CTState *lj_ctype_init(lua_State *L)
565{
566 CTState *cts = lj_mem_newt(L, sizeof(CTState), CTState);
567 CType *ct = lj_mem_newvec(L, CTTYPETAB_MIN, CType);
568 const char *name = lj_ctype_typenames;
569 CTypeID id;
570 memset(cts, 0, sizeof(CTState));
571 cts->tab = ct;
572 cts->sizetab = CTTYPETAB_MIN;
573 cts->top = CTTYPEINFO_NUM;
574 cts->L = NULL;
575 cts->g = G(L);
576 for (id = 0; id < CTTYPEINFO_NUM; id++, ct++) {
577 CTInfo info = lj_ctype_typeinfo[id];
578 ct->size = (CTSize)((int32_t)(info << 16) >> 26);
579 ct->info = info & 0xffff03ffu;
580 if (ctype_type(info) == CT_KW || ctype_istypedef(info)) {
581 size_t len = strlen(name);
582 GCstr *str = lj_str_new(L, name, len);
583 ctype_setname(ct, str);
584 name += len+1;
585 lj_ctype_addname(cts, ct, id);
586 } else {
587 setgcrefnull(ct->name);
588 if (!ctype_isenum(info)) ctype_addtype(cts, ct, id);
589 }
590 }
591 setmref(G(L)->ctype_state, cts);
592 return cts;
593}
594
595/* Free C type table and state. */
596void lj_ctype_freestate(global_State *g)
597{
598 CTState *cts = ctype_ctsG(g);
599 if (cts) {
600 lj_ccallback_mcode_free(cts);
601 lj_mem_freevec(g, cts->tab, cts->sizetab, CType);
602 lj_mem_freevec(g, cts->cb.cbid, cts->cb.sizeid, CTypeID1);
603 lj_mem_freet(g, cts);
604 }
605}
606
607#endif
diff --git a/libraries/luajit-2.0/src/lj_ctype.h b/libraries/luajit-2.0/src/lj_ctype.h
new file mode 100644
index 0000000..da31385
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ctype.h
@@ -0,0 +1,459 @@
1/*
2** C type management.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CTYPE_H
7#define _LJ_CTYPE_H
8
9#include "lj_obj.h"
10#include "lj_gc.h"
11
12#if LJ_HASFFI
13
14/* -- C type definitions -------------------------------------------------- */
15
16/* C type numbers. Highest 4 bits of C type info. ORDER CT. */
17enum {
18 /* Externally visible types. */
19 CT_NUM, /* Integer or floating-point numbers. */
20 CT_STRUCT, /* Struct or union. */
21 CT_PTR, /* Pointer or reference. */
22 CT_ARRAY, /* Array or complex type. */
23 CT_MAYCONVERT = CT_ARRAY,
24 CT_VOID, /* Void type. */
25 CT_ENUM, /* Enumeration. */
26 CT_HASSIZE = CT_ENUM, /* Last type where ct->size holds the actual size. */
27 CT_FUNC, /* Function. */
28 CT_TYPEDEF, /* Typedef. */
29 CT_ATTRIB, /* Miscellaneous attributes. */
30 /* Internal element types. */
31 CT_FIELD, /* Struct/union field or function parameter. */
32 CT_BITFIELD, /* Struct/union bitfield. */
33 CT_CONSTVAL, /* Constant value. */
34 CT_EXTERN, /* External reference. */
35 CT_KW /* Keyword. */
36};
37
38LJ_STATIC_ASSERT(((int)CT_PTR & (int)CT_ARRAY) == CT_PTR);
39LJ_STATIC_ASSERT(((int)CT_STRUCT & (int)CT_ARRAY) == CT_STRUCT);
40
41/*
42** ---------- info ------------
43** |type flags... A cid | size | sib | next | name |
44** +----------------------------+--------+-------+-------+-------+--
45** |NUM BFvcUL.. A | size | | type | |
46** |STRUCT ..vcU..V A | size | field | name? | name? |
47** |PTR ..vcR... A cid | size | | type | |
48** |ARRAY VCvc...V A cid | size | | type | |
49** |VOID ..vc.... A | size | | type | |
50** |ENUM A cid | size | const | name? | name? |
51** |FUNC ....VS.. cc cid | nargs | field | name? | name? |
52** |TYPEDEF cid | | | name | name |
53** |ATTRIB attrnum cid | attr | sib? | type? | |
54** |FIELD cid | offset | field | | name? |
55** |BITFIELD B.vcU csz bsz pos | offset | field | | name? |
56** |CONSTVAL c cid | value | const | name | name |
57** |EXTERN cid | | sib? | name | name |
58** |KW tok | size | | name | name |
59** +----------------------------+--------+-------+-------+-------+--
60** ^^ ^^--- bits used for C type conversion dispatch
61*/
62
63/* C type info flags. TFFArrrr */
64#define CTF_BOOL 0x08000000u /* Boolean: NUM, BITFIELD. */
65#define CTF_FP 0x04000000u /* Floating-point: NUM. */
66#define CTF_CONST 0x02000000u /* Const qualifier. */
67#define CTF_VOLATILE 0x01000000u /* Volatile qualifier. */
68#define CTF_UNSIGNED 0x00800000u /* Unsigned: NUM, BITFIELD. */
69#define CTF_LONG 0x00400000u /* Long: NUM. */
70#define CTF_VLA 0x00100000u /* Variable-length: ARRAY, STRUCT. */
71#define CTF_REF 0x00800000u /* Reference: PTR. */
72#define CTF_VECTOR 0x08000000u /* Vector: ARRAY. */
73#define CTF_COMPLEX 0x04000000u /* Complex: ARRAY. */
74#define CTF_UNION 0x00800000u /* Union: STRUCT. */
75#define CTF_VARARG 0x00800000u /* Vararg: FUNC. */
76#define CTF_SSEREGPARM 0x00400000u /* SSE register parameters: FUNC. */
77
78#define CTF_QUAL (CTF_CONST|CTF_VOLATILE)
79#define CTF_ALIGN (CTMASK_ALIGN<<CTSHIFT_ALIGN)
80#define CTF_UCHAR ((char)-1 > 0 ? CTF_UNSIGNED : 0)
81
82/* Flags used in parser. .F.Ammvf cp->attr */
83#define CTFP_ALIGNED 0x00000001u /* cp->attr + ALIGN */
84#define CTFP_PACKED 0x00000002u /* cp->attr */
85/* ...C...f cp->fattr */
86#define CTFP_CCONV 0x00000001u /* cp->fattr + CCONV/[SSE]REGPARM */
87
88/* C type info bitfields. */
89#define CTMASK_CID 0x0000ffffu /* Max. 65536 type IDs. */
90#define CTMASK_NUM 0xf0000000u /* Max. 16 type numbers. */
91#define CTSHIFT_NUM 28
92#define CTMASK_ALIGN 15 /* Max. alignment is 2^15. */
93#define CTSHIFT_ALIGN 16
94#define CTMASK_ATTRIB 255 /* Max. 256 attributes. */
95#define CTSHIFT_ATTRIB 16
96#define CTMASK_CCONV 3 /* Max. 4 calling conventions. */
97#define CTSHIFT_CCONV 16
98#define CTMASK_REGPARM 3 /* Max. 0-3 regparms. */
99#define CTSHIFT_REGPARM 18
100/* Bitfields only used in parser. */
101#define CTMASK_VSIZEP 15 /* Max. vector size is 2^15. */
102#define CTSHIFT_VSIZEP 4
103#define CTMASK_MSIZEP 255 /* Max. type size (via mode) is 128. */
104#define CTSHIFT_MSIZEP 8
105
106/* Info bits for BITFIELD. Max. size of bitfield is 64 bits. */
107#define CTBSZ_MAX 32 /* Max. size of bitfield is 32 bit. */
108#define CTBSZ_FIELD 127 /* Temp. marker for regular field. */
109#define CTMASK_BITPOS 127
110#define CTMASK_BITBSZ 127
111#define CTMASK_BITCSZ 127
112#define CTSHIFT_BITPOS 0
113#define CTSHIFT_BITBSZ 8
114#define CTSHIFT_BITCSZ 16
115
116#define CTF_INSERT(info, field, val) \
117 info = (info & ~(CTMASK_##field<<CTSHIFT_##field)) | \
118 (((CTSize)(val) & CTMASK_##field) << CTSHIFT_##field)
119
120/* Calling conventions. ORDER CC */
121enum { CTCC_CDECL, CTCC_THISCALL, CTCC_FASTCALL, CTCC_STDCALL };
122
123/* Attribute numbers. */
124enum {
125 CTA_NONE, /* Ignored attribute. Must be zero. */
126 CTA_QUAL, /* Unmerged qualifiers. */
127 CTA_ALIGN, /* Alignment override. */
128 CTA_SUBTYPE, /* Transparent sub-type. */
129 CTA_REDIR, /* Redirected symbol name. */
130 CTA_BAD, /* To catch bad IDs. */
131 CTA__MAX
132};
133
134/* Special sizes. */
135#define CTSIZE_INVALID 0xffffffffu
136
137typedef uint32_t CTInfo; /* Type info. */
138typedef uint32_t CTSize; /* Type size. */
139typedef uint32_t CTypeID; /* Type ID. */
140typedef uint16_t CTypeID1; /* Minimum-sized type ID. */
141
142/* C type table element. */
143typedef struct CType {
144 CTInfo info; /* Type info. */
145 CTSize size; /* Type size or other info. */
146 CTypeID1 sib; /* Sibling element. */
147 CTypeID1 next; /* Next element in hash chain. */
148 GCRef name; /* Element name (GCstr). */
149} CType;
150
151#define CTHASH_SIZE 128 /* Number of hash anchors. */
152#define CTHASH_MASK (CTHASH_SIZE-1)
153
154/* Simplify target-specific configuration. Checked in lj_ccall.h. */
155#define CCALL_MAX_GPR 8
156#define CCALL_MAX_FPR 8
157
158typedef LJ_ALIGN(8) union FPRCBArg { double d; float f; } FPRCBArg;
159
160/* C callback state. Defined here, to avoid dragging in lj_ccall.h. */
161
162typedef LJ_ALIGN(8) struct CCallback {
163 FPRCBArg fpr[CCALL_MAX_FPR]; /* Arguments/results in FPRs. */
164 intptr_t gpr[CCALL_MAX_GPR]; /* Arguments/results in GPRs. */
165 intptr_t *stack; /* Pointer to arguments on stack. */
166 void *mcode; /* Machine code for callback func. pointers. */
167 CTypeID1 *cbid; /* Callback type table. */
168 MSize sizeid; /* Size of callback type table. */
169 MSize topid; /* Highest unused callback type table slot. */
170 MSize slot; /* Current callback slot. */
171} CCallback;
172
173/* C type state. */
174typedef struct CTState {
175 CType *tab; /* C type table. */
176 CTypeID top; /* Current top of C type table. */
177 MSize sizetab; /* Size of C type table. */
178 lua_State *L; /* Lua state (needed for errors and allocations). */
179 global_State *g; /* Global state. */
180 GCtab *finalizer; /* Map of cdata to finalizer. */
181 GCtab *miscmap; /* Map of -CTypeID to metatable and cb slot to func. */
182 CCallback cb; /* Temporary callback state. */
183 CTypeID1 hash[CTHASH_SIZE]; /* Hash anchors for C type table. */
184} CTState;
185
186#define CTINFO(ct, flags) (((CTInfo)(ct) << CTSHIFT_NUM) + (flags))
187#define CTALIGN(al) ((CTSize)(al) << CTSHIFT_ALIGN)
188#define CTATTRIB(at) ((CTInfo)(at) << CTSHIFT_ATTRIB)
189
190#define ctype_type(info) ((info) >> CTSHIFT_NUM)
191#define ctype_cid(info) ((CTypeID)((info) & CTMASK_CID))
192#define ctype_align(info) (((info) >> CTSHIFT_ALIGN) & CTMASK_ALIGN)
193#define ctype_attrib(info) (((info) >> CTSHIFT_ATTRIB) & CTMASK_ATTRIB)
194#define ctype_bitpos(info) (((info) >> CTSHIFT_BITPOS) & CTMASK_BITPOS)
195#define ctype_bitbsz(info) (((info) >> CTSHIFT_BITBSZ) & CTMASK_BITBSZ)
196#define ctype_bitcsz(info) (((info) >> CTSHIFT_BITCSZ) & CTMASK_BITCSZ)
197#define ctype_vsizeP(info) (((info) >> CTSHIFT_VSIZEP) & CTMASK_VSIZEP)
198#define ctype_msizeP(info) (((info) >> CTSHIFT_MSIZEP) & CTMASK_MSIZEP)
199#define ctype_cconv(info) (((info) >> CTSHIFT_CCONV) & CTMASK_CCONV)
200
201/* Simple type checks. */
202#define ctype_isnum(info) (ctype_type((info)) == CT_NUM)
203#define ctype_isvoid(info) (ctype_type((info)) == CT_VOID)
204#define ctype_isptr(info) (ctype_type((info)) == CT_PTR)
205#define ctype_isarray(info) (ctype_type((info)) == CT_ARRAY)
206#define ctype_isstruct(info) (ctype_type((info)) == CT_STRUCT)
207#define ctype_isfunc(info) (ctype_type((info)) == CT_FUNC)
208#define ctype_isenum(info) (ctype_type((info)) == CT_ENUM)
209#define ctype_istypedef(info) (ctype_type((info)) == CT_TYPEDEF)
210#define ctype_isattrib(info) (ctype_type((info)) == CT_ATTRIB)
211#define ctype_isfield(info) (ctype_type((info)) == CT_FIELD)
212#define ctype_isbitfield(info) (ctype_type((info)) == CT_BITFIELD)
213#define ctype_isconstval(info) (ctype_type((info)) == CT_CONSTVAL)
214#define ctype_isextern(info) (ctype_type((info)) == CT_EXTERN)
215#define ctype_hassize(info) (ctype_type((info)) <= CT_HASSIZE)
216
217/* Combined type and flag checks. */
218#define ctype_isinteger(info) \
219 (((info) & (CTMASK_NUM|CTF_BOOL|CTF_FP)) == CTINFO(CT_NUM, 0))
220#define ctype_isinteger_or_bool(info) \
221 (((info) & (CTMASK_NUM|CTF_FP)) == CTINFO(CT_NUM, 0))
222#define ctype_isbool(info) \
223 (((info) & (CTMASK_NUM|CTF_BOOL)) == CTINFO(CT_NUM, CTF_BOOL))
224#define ctype_isfp(info) \
225 (((info) & (CTMASK_NUM|CTF_FP)) == CTINFO(CT_NUM, CTF_FP))
226
227#define ctype_ispointer(info) \
228 ((ctype_type(info) >> 1) == (CT_PTR >> 1)) /* Pointer or array. */
229#define ctype_isref(info) \
230 (((info) & (CTMASK_NUM|CTF_REF)) == CTINFO(CT_PTR, CTF_REF))
231
232#define ctype_isrefarray(info) \
233 (((info) & (CTMASK_NUM|CTF_VECTOR|CTF_COMPLEX)) == CTINFO(CT_ARRAY, 0))
234#define ctype_isvector(info) \
235 (((info) & (CTMASK_NUM|CTF_VECTOR)) == CTINFO(CT_ARRAY, CTF_VECTOR))
236#define ctype_iscomplex(info) \
237 (((info) & (CTMASK_NUM|CTF_COMPLEX)) == CTINFO(CT_ARRAY, CTF_COMPLEX))
238
239#define ctype_isvltype(info) \
240 (((info) & ((CTMASK_NUM|CTF_VLA) - (2u<<CTSHIFT_NUM))) == \
241 CTINFO(CT_STRUCT, CTF_VLA)) /* VL array or VL struct. */
242#define ctype_isvlarray(info) \
243 (((info) & (CTMASK_NUM|CTF_VLA)) == CTINFO(CT_ARRAY, CTF_VLA))
244
245#define ctype_isxattrib(info, at) \
246 (((info) & (CTMASK_NUM|CTATTRIB(CTMASK_ATTRIB))) == \
247 CTINFO(CT_ATTRIB, CTATTRIB(at)))
248
249/* Target-dependent sizes and alignments. */
250#if LJ_64
251#define CTSIZE_PTR 8
252#define CTALIGN_PTR CTALIGN(3)
253#else
254#define CTSIZE_PTR 4
255#define CTALIGN_PTR CTALIGN(2)
256#endif
257
258#define CTINFO_REF(ref) \
259 CTINFO(CT_PTR, (CTF_CONST|CTF_REF|CTALIGN_PTR) + (ref))
260
261#define CT_MEMALIGN 3 /* Alignment guaranteed by memory allocator. */
262
263/* -- Predefined types ---------------------------------------------------- */
264
265/* Target-dependent types. */
266#if LJ_TARGET_PPC || LJ_TARGET_PPCSPE
267#define CTTYDEFP(_) \
268 _(LINT32, 4, CT_NUM, CTF_LONG|CTALIGN(2))
269#else
270#define CTTYDEFP(_)
271#endif
272
273/* Common types. */
274#define CTTYDEF(_) \
275 _(NONE, 0, CT_ATTRIB, CTATTRIB(CTA_BAD)) \
276 _(VOID, -1, CT_VOID, CTALIGN(0)) \
277 _(CVOID, -1, CT_VOID, CTF_CONST|CTALIGN(0)) \
278 _(BOOL, 1, CT_NUM, CTF_BOOL|CTF_UNSIGNED|CTALIGN(0)) \
279 _(CCHAR, 1, CT_NUM, CTF_CONST|CTF_UCHAR|CTALIGN(0)) \
280 _(INT8, 1, CT_NUM, CTALIGN(0)) \
281 _(UINT8, 1, CT_NUM, CTF_UNSIGNED|CTALIGN(0)) \
282 _(INT16, 2, CT_NUM, CTALIGN(1)) \
283 _(UINT16, 2, CT_NUM, CTF_UNSIGNED|CTALIGN(1)) \
284 _(INT32, 4, CT_NUM, CTALIGN(2)) \
285 _(UINT32, 4, CT_NUM, CTF_UNSIGNED|CTALIGN(2)) \
286 _(INT64, 8, CT_NUM, CTF_LONG|CTALIGN(3)) \
287 _(UINT64, 8, CT_NUM, CTF_UNSIGNED|CTF_LONG|CTALIGN(3)) \
288 _(FLOAT, 4, CT_NUM, CTF_FP|CTALIGN(2)) \
289 _(DOUBLE, 8, CT_NUM, CTF_FP|CTALIGN(3)) \
290 _(COMPLEX_FLOAT, 8, CT_ARRAY, CTF_COMPLEX|CTALIGN(2)|CTID_FLOAT) \
291 _(COMPLEX_DOUBLE, 16, CT_ARRAY, CTF_COMPLEX|CTALIGN(3)|CTID_DOUBLE) \
292 _(P_VOID, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_VOID) \
293 _(P_CVOID, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_CVOID) \
294 _(P_CCHAR, CTSIZE_PTR, CT_PTR, CTALIGN_PTR|CTID_CCHAR) \
295 _(A_CCHAR, -1, CT_ARRAY, CTF_CONST|CTALIGN(0)|CTID_CCHAR) \
296 _(CTYPEID, 4, CT_ENUM, CTALIGN(2)|CTID_INT32) \
297 CTTYDEFP(_) \
298 /* End of type list. */
299
300/* Public predefined type IDs. */
301enum {
302#define CTTYIDDEF(id, sz, ct, info) CTID_##id,
303CTTYDEF(CTTYIDDEF)
304#undef CTTYIDDEF
305 /* Predefined typedefs and keywords follow. */
306 CTID_MAX = 65536
307};
308
309/* Target-dependent type IDs. */
310#if LJ_64
311#define CTID_INT_PSZ CTID_INT64
312#define CTID_UINT_PSZ CTID_UINT64
313#else
314#define CTID_INT_PSZ CTID_INT32
315#define CTID_UINT_PSZ CTID_UINT32
316#endif
317
318#if LJ_ABI_WIN
319#define CTID_WCHAR CTID_UINT16
320#elif LJ_TARGET_PPC
321#define CTID_WCHAR CTID_LINT32
322#else
323#define CTID_WCHAR CTID_INT32
324#endif
325
326/* -- C tokens and keywords ----------------------------------------------- */
327
328/* C lexer keywords. */
329#define CTOKDEF(_) \
330 _(IDENT, "<identifier>") _(STRING, "<string>") \
331 _(INTEGER, "<integer>") _(EOF, "<eof>") \
332 _(OROR, "||") _(ANDAND, "&&") _(EQ, "==") _(NE, "!=") \
333 _(LE, "<=") _(GE, ">=") _(SHL, "<<") _(SHR, ">>") _(DEREF, "->")
334
335/* Simple declaration specifiers. */
336#define CDSDEF(_) \
337 _(VOID) _(BOOL) _(CHAR) _(INT) _(FP) \
338 _(LONG) _(LONGLONG) _(SHORT) _(COMPLEX) _(SIGNED) _(UNSIGNED) \
339 _(CONST) _(VOLATILE) _(RESTRICT) _(INLINE) \
340 _(TYPEDEF) _(EXTERN) _(STATIC) _(AUTO) _(REGISTER)
341
342/* C keywords. */
343#define CKWDEF(_) \
344 CDSDEF(_) _(EXTENSION) _(ASM) _(ATTRIBUTE) \
345 _(DECLSPEC) _(CCDECL) _(PTRSZ) \
346 _(STRUCT) _(UNION) _(ENUM) \
347 _(SIZEOF) _(ALIGNOF)
348
349/* C token numbers. */
350enum {
351 CTOK_OFS = 255,
352#define CTOKNUM(name, sym) CTOK_##name,
353#define CKWNUM(name) CTOK_##name,
354CTOKDEF(CTOKNUM)
355CKWDEF(CKWNUM)
356#undef CTOKNUM
357#undef CKWNUM
358 CTOK_FIRSTDECL = CTOK_VOID,
359 CTOK_FIRSTSCL = CTOK_TYPEDEF,
360 CTOK_LASTDECLFLAG = CTOK_REGISTER,
361 CTOK_LASTDECL = CTOK_ENUM
362};
363
364/* Declaration specifier flags. */
365enum {
366#define CDSFLAG(name) CDF_##name = (1u << (CTOK_##name - CTOK_FIRSTDECL)),
367CDSDEF(CDSFLAG)
368#undef CDSFLAG
369 CDF__END
370};
371
372#define CDF_SCL (CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC|CDF_AUTO|CDF_REGISTER)
373
374/* -- C type management --------------------------------------------------- */
375
376#define ctype_ctsG(g) (mref((g)->ctype_state, CTState))
377
378/* Get C type state. */
379static LJ_AINLINE CTState *ctype_cts(lua_State *L)
380{
381 CTState *cts = ctype_ctsG(G(L));
382 cts->L = L; /* Save L for errors and allocations. */
383 return cts;
384}
385
386/* Save and restore state of C type table. */
387#define LJ_CTYPE_SAVE(cts) CTState savects_ = *(cts)
388#define LJ_CTYPE_RESTORE(cts) \
389 ((cts)->top = savects_.top, \
390 memcpy((cts)->hash, savects_.hash, sizeof(savects_.hash)))
391
392/* Check C type ID for validity when assertions are enabled. */
393static LJ_AINLINE CTypeID ctype_check(CTState *cts, CTypeID id)
394{
395 lua_assert(id > 0 && id < cts->top); UNUSED(cts);
396 return id;
397}
398
399/* Get C type for C type ID. */
400static LJ_AINLINE CType *ctype_get(CTState *cts, CTypeID id)
401{
402 return &cts->tab[ctype_check(cts, id)];
403}
404
405/* Get C type ID for a C type. */
406#define ctype_typeid(cts, ct) ((CTypeID)((ct) - (cts)->tab))
407
408/* Get child C type. */
409static LJ_AINLINE CType *ctype_child(CTState *cts, CType *ct)
410{
411 lua_assert(!(ctype_isvoid(ct->info) || ctype_isstruct(ct->info) ||
412 ctype_isbitfield(ct->info))); /* These don't have children. */
413 return ctype_get(cts, ctype_cid(ct->info));
414}
415
416/* Get raw type for a C type ID. */
417static LJ_AINLINE CType *ctype_raw(CTState *cts, CTypeID id)
418{
419 CType *ct = ctype_get(cts, id);
420 while (ctype_isattrib(ct->info)) ct = ctype_child(cts, ct);
421 return ct;
422}
423
424/* Get raw type of the child of a C type. */
425static LJ_AINLINE CType *ctype_rawchild(CTState *cts, CType *ct)
426{
427 do { ct = ctype_child(cts, ct); } while (ctype_isattrib(ct->info));
428 return ct;
429}
430
431/* Set the name of a C type table element. */
432static LJ_AINLINE void ctype_setname(CType *ct, GCstr *s)
433{
434 /* NOBARRIER: mark string as fixed -- the C type table is never collected. */
435 fixstring(s);
436 setgcref(ct->name, obj2gco(s));
437}
438
439LJ_FUNC CTypeID lj_ctype_new(CTState *cts, CType **ctp);
440LJ_FUNC CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size);
441LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id);
442LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name,
443 uint32_t tmask);
444LJ_FUNC CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name,
445 CTSize *ofs);
446LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id);
447LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id);
448LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem);
449LJ_FUNC CTInfo lj_ctype_info(CTState *cts, CTypeID id, CTSize *szp);
450LJ_FUNC cTValue *lj_ctype_meta(CTState *cts, CTypeID id, MMS mm);
451LJ_FUNC GCstr *lj_ctype_repr(lua_State *L, CTypeID id, GCstr *name);
452LJ_FUNC GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned);
453LJ_FUNC GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size);
454LJ_FUNC CTState *lj_ctype_init(lua_State *L);
455LJ_FUNC void lj_ctype_freestate(global_State *g);
456
457#endif
458
459#endif
diff --git a/libraries/luajit-2.0/src/lj_debug.c b/libraries/luajit-2.0/src/lj_debug.c
new file mode 100644
index 0000000..89434aa
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_debug.c
@@ -0,0 +1,502 @@
1/*
2** Debugging and introspection.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_debug_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#include "lj_err.h"
11#include "lj_debug.h"
12#include "lj_str.h"
13#include "lj_tab.h"
14#include "lj_state.h"
15#include "lj_frame.h"
16#include "lj_bc.h"
17#if LJ_HASJIT
18#include "lj_jit.h"
19#endif
20
21/* -- Frames -------------------------------------------------------------- */
22
23/* Get frame corresponding to a level. */
24cTValue *lj_debug_frame(lua_State *L, int level, int *size)
25{
26 cTValue *frame, *nextframe, *bot = tvref(L->stack);
27 /* Traverse frames backwards. */
28 for (nextframe = frame = L->base-1; frame > bot; ) {
29 if (frame_gc(frame) == obj2gco(L))
30 level++; /* Skip dummy frames. See lj_meta_call(). */
31 if (level-- == 0) {
32 *size = (int)(nextframe - frame);
33 return frame; /* Level found. */
34 }
35 nextframe = frame;
36 if (frame_islua(frame)) {
37 frame = frame_prevl(frame);
38 } else {
39 if (frame_isvarg(frame))
40 level++; /* Skip vararg pseudo-frame. */
41 frame = frame_prevd(frame);
42 }
43 }
44 *size = level;
45 return NULL; /* Level not found. */
46}
47
48/* Invalid bytecode position. */
49#define NO_BCPOS (~(BCPos)0)
50
51/* Return bytecode position for function/frame or NO_BCPOS. */
52static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
53{
54 const BCIns *ins;
55 GCproto *pt;
56 BCPos pos;
57 lua_assert(fn->c.gct == ~LJ_TFUNC || fn->c.gct == ~LJ_TTHREAD);
58 if (!isluafunc(fn)) { /* Cannot derive a PC for non-Lua functions. */
59 return NO_BCPOS;
60 } else if (nextframe == NULL) { /* Lua function on top. */
61 void *cf = cframe_raw(L->cframe);
62 if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf))
63 return NO_BCPOS;
64 ins = cframe_pc(cf); /* Only happens during error/hook handling. */
65 } else {
66 if (frame_islua(nextframe)) {
67 ins = frame_pc(nextframe);
68 } else if (frame_iscont(nextframe)) {
69 ins = frame_contpc(nextframe);
70 } else {
71 /* Lua function below errfunc/gc/hook: find cframe to get the PC. */
72 void *cf = cframe_raw(L->cframe);
73 TValue *f = L->base-1;
74 if (cf == NULL)
75 return NO_BCPOS;
76 while (f > nextframe) {
77 if (frame_islua(f)) {
78 f = frame_prevl(f);
79 } else {
80 if (frame_isc(f))
81 cf = cframe_raw(cframe_prev(cf));
82 f = frame_prevd(f);
83 }
84 }
85 if (cframe_prev(cf))
86 cf = cframe_raw(cframe_prev(cf));
87 ins = cframe_pc(cf);
88 }
89 }
90 pt = funcproto(fn);
91 pos = proto_bcpos(pt, ins) - 1;
92#if LJ_HASJIT
93 if (pos > pt->sizebc) { /* Undo the effects of lj_trace_exit for JLOOP. */
94 GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins));
95 lua_assert(bc_isret(bc_op(ins[-1])));
96 pos = proto_bcpos(pt, mref(T->startpc, const BCIns));
97 }
98#endif
99 return pos;
100}
101
102/* -- Line numbers -------------------------------------------------------- */
103
104/* Get line number for a bytecode position. */
105BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc)
106{
107 const void *lineinfo = proto_lineinfo(pt);
108 if (pc <= pt->sizebc && lineinfo) {
109 BCLine first = pt->firstline;
110 if (pc == pt->sizebc) return first + pt->numline;
111 if (pc-- == 0) return first;
112 if (pt->numline < 256)
113 return first + (BCLine)((const uint8_t *)lineinfo)[pc];
114 else if (pt->numline < 65536)
115 return first + (BCLine)((const uint16_t *)lineinfo)[pc];
116 else
117 return first + (BCLine)((const uint32_t *)lineinfo)[pc];
118 }
119 return 0;
120}
121
122/* Get line number for function/frame. */
123static BCLine debug_frameline(lua_State *L, GCfunc *fn, cTValue *nextframe)
124{
125 BCPos pc = debug_framepc(L, fn, nextframe);
126 if (pc != NO_BCPOS) {
127 GCproto *pt = funcproto(fn);
128 lua_assert(pc <= pt->sizebc);
129 return lj_debug_line(pt, pc);
130 }
131 return -1;
132}
133
134/* -- Variable names ------------------------------------------------------ */
135
136/* Read ULEB128 value. */
137static uint32_t debug_read_uleb128(const uint8_t **pp)
138{
139 const uint8_t *p = *pp;
140 uint32_t v = *p++;
141 if (LJ_UNLIKELY(v >= 0x80)) {
142 int sh = 0;
143 v &= 0x7f;
144 do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
145 }
146 *pp = p;
147 return v;
148}
149
150/* Get name of a local variable from slot number and PC. */
151static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot)
152{
153 const uint8_t *p = proto_varinfo(pt);
154 if (p) {
155 BCPos lastpc = 0;
156 for (;;) {
157 const char *name = (const char *)p;
158 uint32_t vn = *p++;
159 BCPos startpc, endpc;
160 if (vn < VARNAME__MAX) {
161 if (vn == VARNAME_END) break; /* End of varinfo. */
162 } else {
163 while (*p++) ; /* Skip over variable name string. */
164 }
165 lastpc = startpc = lastpc + debug_read_uleb128(&p);
166 if (startpc > pc) break;
167 endpc = startpc + debug_read_uleb128(&p);
168 if (pc < endpc && slot-- == 0) {
169 if (vn < VARNAME__MAX) {
170#define VARNAMESTR(name, str) str "\0"
171 name = VARNAMEDEF(VARNAMESTR);
172#undef VARNAMESTR
173 if (--vn) while (*name++ || --vn) ;
174 }
175 return name;
176 }
177 }
178 }
179 return NULL;
180}
181
182/* Get name of local variable from 1-based slot number and function/frame. */
183static TValue *debug_localname(lua_State *L, const lua_Debug *ar,
184 const char **name, BCReg slot1)
185{
186 uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
187 uint32_t size = (uint32_t)ar->i_ci >> 16;
188 TValue *frame = tvref(L->stack) + offset;
189 TValue *nextframe = size ? frame + size : NULL;
190 GCfunc *fn = frame_func(frame);
191 BCPos pc = debug_framepc(L, fn, nextframe);
192 if (pc != NO_BCPOS &&
193 (*name = debug_varname(funcproto(fn), pc, slot1-1)) != NULL)
194 ;
195 else if (slot1 > 0 && frame + slot1 < (nextframe ? nextframe : L->top))
196 *name = "(*temporary)";
197 else
198 *name = NULL;
199 return frame+slot1;
200}
201
202/* Get name of upvalue. */
203const char *lj_debug_uvname(GCproto *pt, uint32_t idx)
204{
205 const uint8_t *p = proto_uvinfo(pt);
206 lua_assert(idx < pt->sizeuv);
207 if (!p) return "";
208 if (idx) while (*p++ || --idx) ;
209 return (const char *)p;
210}
211
212/* Get name and value of upvalue. */
213const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp)
214{
215 if (tvisfunc(o)) {
216 GCfunc *fn = funcV(o);
217 if (isluafunc(fn)) {
218 GCproto *pt = funcproto(fn);
219 if (idx < pt->sizeuv) {
220 *tvp = uvval(&gcref(fn->l.uvptr[idx])->uv);
221 return lj_debug_uvname(pt, idx);
222 }
223 } else {
224 if (idx < fn->c.nupvalues) {
225 *tvp = &fn->c.upvalue[idx];
226 return "";
227 }
228 }
229 }
230 return NULL;
231}
232
233/* Deduce name of an object from slot number and PC. */
234const char *lj_debug_slotname(GCproto *pt, const BCIns *ip, BCReg slot,
235 const char **name)
236{
237 const char *lname;
238restart:
239 lname = debug_varname(pt, proto_bcpos(pt, ip), slot);
240 if (lname != NULL) { *name = lname; return "local"; }
241 while (--ip > proto_bc(pt)) {
242 BCIns ins = *ip;
243 BCOp op = bc_op(ins);
244 BCReg ra = bc_a(ins);
245 if (bcmode_a(op) == BCMbase) {
246 if (slot >= ra && (op != BC_KNIL || slot <= bc_d(ins)))
247 return NULL;
248 } else if (bcmode_a(op) == BCMdst && ra == slot) {
249 switch (bc_op(ins)) {
250 case BC_MOV:
251 if (ra == slot) { slot = bc_d(ins); goto restart; }
252 break;
253 case BC_GGET:
254 *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_d(ins))));
255 return "global";
256 case BC_TGETS:
257 *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
258 if (ip > proto_bc(pt)) {
259 BCIns insp = ip[-1];
260 if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1 &&
261 bc_d(insp) == bc_b(ins))
262 return "method";
263 }
264 return "field";
265 case BC_UGET:
266 *name = lj_debug_uvname(pt, bc_d(ins));
267 return "upvalue";
268 default:
269 return NULL;
270 }
271 }
272 }
273 return NULL;
274}
275
276/* Deduce function name from caller of a frame. */
277const char *lj_debug_funcname(lua_State *L, TValue *frame, const char **name)
278{
279 TValue *pframe;
280 GCfunc *fn;
281 BCPos pc;
282 if (frame_isvarg(frame))
283 frame = frame_prevd(frame);
284 pframe = frame_prev(frame);
285 fn = frame_func(pframe);
286 pc = debug_framepc(L, fn, frame);
287 if (pc != NO_BCPOS) {
288 GCproto *pt = funcproto(fn);
289 const BCIns *ip = &proto_bc(pt)[check_exp(pc < pt->sizebc, pc)];
290 MMS mm = bcmode_mm(bc_op(*ip));
291 if (mm == MM_call) {
292 BCReg slot = bc_a(*ip);
293 if (bc_op(*ip) == BC_ITERC) slot -= 3;
294 return lj_debug_slotname(pt, ip, slot, name);
295 } else if (mm != MM__MAX) {
296 *name = strdata(mmname_str(G(L), mm));
297 return "metamethod";
298 }
299 }
300 return NULL;
301}
302
303/* -- Source code locations ----------------------------------------------- */
304
305/* Generate shortened source name. */
306void lj_debug_shortname(char *out, GCstr *str)
307{
308 const char *src = strdata(str);
309 if (*src == '=') {
310 strncpy(out, src+1, LUA_IDSIZE); /* Remove first char. */
311 out[LUA_IDSIZE-1] = '\0'; /* Ensures null termination. */
312 } else if (*src == '@') { /* Output "source", or "...source". */
313 size_t len = str->len-1;
314 src++; /* Skip the `@' */
315 if (len >= LUA_IDSIZE) {
316 src += len-(LUA_IDSIZE-4); /* Get last part of file name. */
317 *out++ = '.'; *out++ = '.'; *out++ = '.';
318 }
319 strcpy(out, src);
320 } else { /* Output [string "string"]. */
321 size_t len; /* Length, up to first control char. */
322 for (len = 0; len < LUA_IDSIZE-12; len++)
323 if (((const unsigned char *)src)[len] < ' ') break;
324 strcpy(out, "[string \""); out += 9;
325 if (src[len] != '\0') { /* Must truncate? */
326 if (len > LUA_IDSIZE-15) len = LUA_IDSIZE-15;
327 strncpy(out, src, len); out += len;
328 strcpy(out, "..."); out += 3;
329 } else {
330 strcpy(out, src); out += len;
331 }
332 strcpy(out, "\"]");
333 }
334}
335
336/* Add current location of a frame to error message. */
337void lj_debug_addloc(lua_State *L, const char *msg,
338 cTValue *frame, cTValue *nextframe)
339{
340 if (frame) {
341 GCfunc *fn = frame_func(frame);
342 if (isluafunc(fn)) {
343 BCLine line = debug_frameline(L, fn, nextframe);
344 if (line >= 0) {
345 char buf[LUA_IDSIZE];
346 lj_debug_shortname(buf, proto_chunkname(funcproto(fn)));
347 lj_str_pushf(L, "%s:%d: %s", buf, line, msg);
348 return;
349 }
350 }
351 }
352 lj_str_pushf(L, "%s", msg);
353}
354
355/* Push location string for a bytecode position to Lua stack. */
356void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc)
357{
358 GCstr *name = proto_chunkname(pt);
359 const char *s = strdata(name);
360 MSize i, len = name->len;
361 BCLine line = lj_debug_line(pt, pc);
362 if (*s == '@') {
363 s++; len--;
364 for (i = len; i > 0; i--)
365 if (s[i] == '/' || s[i] == '\\') {
366 s += i+1;
367 break;
368 }
369 lj_str_pushf(L, "%s:%d", s, line);
370 } else if (len > 40) {
371 lj_str_pushf(L, "%p:%d", pt, line);
372 } else if (*s == '=') {
373 lj_str_pushf(L, "%s:%d", s+1, line);
374 } else {
375 lj_str_pushf(L, "\"%s\":%d", s, line);
376 }
377}
378
379/* -- Public debug API ---------------------------------------------------- */
380
381/* lua_getupvalue() and lua_setupvalue() are in lj_api.c. */
382
383LUA_API const char *lua_getlocal(lua_State *L, const lua_Debug *ar, int n)
384{
385 const char *name;
386 TValue *o = debug_localname(L, ar, &name, (BCReg)n);
387 if (name) {
388 copyTV(L, L->top, o);
389 incr_top(L);
390 }
391 return name;
392}
393
394LUA_API const char *lua_setlocal(lua_State *L, const lua_Debug *ar, int n)
395{
396 const char *name;
397 TValue *o = debug_localname(L, ar, &name, (BCReg)n);
398 if (name)
399 copyTV(L, o, L->top-1);
400 L->top--;
401 return name;
402}
403
404LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
405{
406 int status = 1;
407 TValue *frame = NULL;
408 TValue *nextframe = NULL;
409 GCfunc *fn;
410 if (*what == '>') {
411 TValue *func = L->top - 1;
412 api_check(L, tvisfunc(func));
413 fn = funcV(func);
414 L->top--;
415 what++;
416 } else {
417 uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
418 uint32_t size = (uint32_t)ar->i_ci >> 16;
419 lua_assert(offset != 0);
420 frame = tvref(L->stack) + offset;
421 if (size) nextframe = frame + size;
422 lua_assert(frame <= tvref(L->maxstack) &&
423 (!nextframe || nextframe <= tvref(L->maxstack)));
424 fn = frame_func(frame);
425 lua_assert(fn->c.gct == ~LJ_TFUNC);
426 }
427 for (; *what; what++) {
428 if (*what == 'S') {
429 if (isluafunc(fn)) {
430 GCproto *pt = funcproto(fn);
431 BCLine firstline = pt->firstline;
432 GCstr *name = proto_chunkname(pt);
433 ar->source = strdata(name);
434 lj_debug_shortname(ar->short_src, name);
435 ar->linedefined = (int)firstline;
436 ar->lastlinedefined = (int)(firstline + pt->numline);
437 ar->what = firstline ? "Lua" : "main";
438 } else {
439 ar->source = "=[C]";
440 ar->short_src[0] = '[';
441 ar->short_src[1] = 'C';
442 ar->short_src[2] = ']';
443 ar->short_src[3] = '\0';
444 ar->linedefined = -1;
445 ar->lastlinedefined = -1;
446 ar->what = "C";
447 }
448 } else if (*what == 'l') {
449 ar->currentline = frame ? debug_frameline(L, fn, nextframe) : -1;
450 } else if (*what == 'u') {
451 ar->nups = fn->c.nupvalues;
452 } else if (*what == 'n') {
453 ar->namewhat = frame ? lj_debug_funcname(L, frame, &ar->name) : NULL;
454 if (ar->namewhat == NULL) {
455 ar->namewhat = "";
456 ar->name = NULL;
457 }
458 } else if (*what == 'f') {
459 setfuncV(L, L->top, fn);
460 incr_top(L);
461 } else if (*what == 'L') {
462 if (isluafunc(fn)) {
463 GCtab *t = lj_tab_new(L, 0, 0);
464 GCproto *pt = funcproto(fn);
465 const void *lineinfo = proto_lineinfo(pt);
466 if (lineinfo) {
467 BCLine first = pt->firstline;
468 int sz = pt->numline < 256 ? 1 : pt->numline < 65536 ? 2 : 4;
469 MSize i, szl = pt->sizebc-1;
470 for (i = 0; i < szl; i++) {
471 BCLine line = first +
472 (sz == 1 ? (BCLine)((const uint8_t *)lineinfo)[i] :
473 sz == 2 ? (BCLine)((const uint16_t *)lineinfo)[i] :
474 (BCLine)((const uint32_t *)lineinfo)[i]);
475 setboolV(lj_tab_setint(L, t, line), 1);
476 }
477 }
478 settabV(L, L->top, t);
479 } else {
480 setnilV(L->top);
481 }
482 incr_top(L);
483 } else {
484 status = 0; /* Bad option. */
485 }
486 }
487 return status;
488}
489
490LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
491{
492 int size;
493 cTValue *frame = lj_debug_frame(L, level, &size);
494 if (frame) {
495 ar->i_ci = (size << 16) + (int)(frame - tvref(L->stack));
496 return 1;
497 } else {
498 ar->i_ci = level - size;
499 return 0;
500 }
501}
502
diff --git a/libraries/luajit-2.0/src/lj_debug.h b/libraries/luajit-2.0/src/lj_debug.h
new file mode 100644
index 0000000..f82fdfe
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_debug.h
@@ -0,0 +1,41 @@
1/*
2** Debugging and introspection.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_DEBUG_H
7#define _LJ_DEBUG_H
8
9#include "lj_obj.h"
10
11LJ_FUNC cTValue *lj_debug_frame(lua_State *L, int level, int *size);
12LJ_FUNC BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc);
13LJ_FUNC const char *lj_debug_uvname(GCproto *pt, uint32_t idx);
14LJ_FUNC const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp);
15LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc,
16 BCReg slot, const char **name);
17LJ_FUNC const char *lj_debug_funcname(lua_State *L, TValue *frame,
18 const char **name);
19LJ_FUNC void lj_debug_shortname(char *out, GCstr *str);
20LJ_FUNC void lj_debug_addloc(lua_State *L, const char *msg,
21 cTValue *frame, cTValue *nextframe);
22LJ_FUNC void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc);
23
24/* Fixed internal variable names. */
25#define VARNAMEDEF(_) \
26 _(FOR_IDX, "(for index)") \
27 _(FOR_STOP, "(for limit)") \
28 _(FOR_STEP, "(for step)") \
29 _(FOR_GEN, "(for generator)") \
30 _(FOR_STATE, "(for state)") \
31 _(FOR_CTL, "(for control)")
32
33enum {
34 VARNAME_END,
35#define VARNAMEENUM(name, str) VARNAME_##name,
36 VARNAMEDEF(VARNAMEENUM)
37#undef VARNAMEENUM
38 VARNAME__MAX
39};
40
41#endif
diff --git a/libraries/luajit-2.0/src/lj_def.h b/libraries/luajit-2.0/src/lj_def.h
new file mode 100644
index 0000000..5d21d58
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_def.h
@@ -0,0 +1,307 @@
1/*
2** LuaJIT common internal definitions.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_DEF_H
7#define _LJ_DEF_H
8
9#include "lua.h"
10
11#if defined(_MSC_VER)
12/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
13typedef __int8 int8_t;
14typedef __int16 int16_t;
15typedef __int32 int32_t;
16typedef __int64 int64_t;
17typedef unsigned __int8 uint8_t;
18typedef unsigned __int16 uint16_t;
19typedef unsigned __int32 uint32_t;
20typedef unsigned __int64 uint64_t;
21#ifdef _WIN64
22typedef __int64 intptr_t;
23typedef unsigned __int64 uintptr_t;
24#else
25typedef __int32 intptr_t;
26typedef unsigned __int32 uintptr_t;
27#endif
28#elif defined(__symbian__)
29/* Cough. */
30typedef signed char int8_t;
31typedef short int int16_t;
32typedef int int32_t;
33typedef long long int64_t;
34typedef unsigned char uint8_t;
35typedef unsigned short int uint16_t;
36typedef unsigned int uint32_t;
37typedef unsigned long long uint64_t;
38typedef int intptr_t;
39typedef unsigned int uintptr_t;
40#else
41#include <stdint.h>
42#endif
43
44/* Needed everywhere. */
45#include <string.h>
46#include <stdlib.h>
47
48/* Various VM limits. */
49#define LJ_MAX_MEM 0x7fffff00 /* Max. total memory allocation. */
50#define LJ_MAX_ALLOC LJ_MAX_MEM /* Max. individual allocation length. */
51#define LJ_MAX_STR LJ_MAX_MEM /* Max. string length. */
52#define LJ_MAX_UDATA LJ_MAX_MEM /* Max. userdata length. */
53
54#define LJ_MAX_STRTAB (1<<26) /* Max. string table size. */
55#define LJ_MAX_HBITS 26 /* Max. hash bits. */
56#define LJ_MAX_ABITS 28 /* Max. bits of array key. */
57#define LJ_MAX_ASIZE ((1<<(LJ_MAX_ABITS-1))+1) /* Max. array part size. */
58#define LJ_MAX_COLOSIZE 16 /* Max. elems for colocated array. */
59
60#define LJ_MAX_LINE LJ_MAX_MEM /* Max. source code line number. */
61#define LJ_MAX_XLEVEL 200 /* Max. syntactic nesting level. */
62#define LJ_MAX_BCINS (1<<26) /* Max. # of bytecode instructions. */
63#define LJ_MAX_SLOTS 250 /* Max. # of slots in a Lua func. */
64#define LJ_MAX_LOCVAR 200 /* Max. # of local variables. */
65#define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */
66
67#define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */
68#define LJ_STACK_EXTRA 5 /* Extra stack space (metamethods). */
69
70#define LJ_NUM_CBPAGE 1 /* Number of FFI callback pages. */
71
72/* Minimum table/buffer sizes. */
73#define LJ_MIN_GLOBAL 6 /* Min. global table size (hbits). */
74#define LJ_MIN_REGISTRY 2 /* Min. registry size (hbits). */
75#define LJ_MIN_STRTAB 256 /* Min. string table size (pow2). */
76#define LJ_MIN_SBUF 32 /* Min. string buffer length. */
77#define LJ_MIN_VECSZ 8 /* Min. size for growable vectors. */
78#define LJ_MIN_IRSZ 32 /* Min. size for growable IR. */
79#define LJ_MIN_K64SZ 16 /* Min. size for chained K64Array. */
80
81/* JIT compiler limits. */
82#define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */
83#define LJ_MAX_PHI 32 /* Max. # of PHIs for a loop. */
84#define LJ_MAX_EXITSTUBGR 16 /* Max. # of exit stub groups. */
85
86/* Various macros. */
87#ifndef UNUSED
88#define UNUSED(x) ((void)(x)) /* to avoid warnings */
89#endif
90
91#define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo)
92#define i32ptr(p) ((int32_t)(intptr_t)(void *)(p))
93#define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p))
94
95#define checki8(x) ((x) == (int32_t)(int8_t)(x))
96#define checku8(x) ((x) == (int32_t)(uint8_t)(x))
97#define checki16(x) ((x) == (int32_t)(int16_t)(x))
98#define checku16(x) ((x) == (int32_t)(uint16_t)(x))
99#define checki32(x) ((x) == (int32_t)(x))
100#define checku32(x) ((x) == (uint32_t)(x))
101#define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x))
102
103/* Every half-decent C compiler transforms this into a rotate instruction. */
104#define lj_rol(x, n) (((x)<<(n)) | ((x)>>(8*sizeof(x)-(n))))
105#define lj_ror(x, n) (((x)<<(8*sizeof(x)-(n))) | ((x)>>(n)))
106
107/* A really naive Bloom filter. But sufficient for our needs. */
108typedef uintptr_t BloomFilter;
109#define BLOOM_MASK (8*sizeof(BloomFilter) - 1)
110#define bloombit(x) ((uintptr_t)1 << ((x) & BLOOM_MASK))
111#define bloomset(b, x) ((b) |= bloombit((x)))
112#define bloomtest(b, x) ((b) & bloombit((x)))
113
114#if defined(__GNUC__)
115
116#define LJ_NORET __attribute__((noreturn))
117#define LJ_ALIGN(n) __attribute__((aligned(n)))
118#define LJ_INLINE inline
119#define LJ_AINLINE inline __attribute__((always_inline))
120#define LJ_NOINLINE __attribute__((noinline))
121
122#if defined(__ELF__) || defined(__MACH__)
123#if !((defined(__sun__) && defined(__svr4__)) || defined(__solaris__))
124#define LJ_NOAPI extern __attribute__((visibility("hidden")))
125#endif
126#endif
127
128/* Note: it's only beneficial to use fastcall on x86 and then only for up to
129** two non-FP args. The amalgamated compile covers all LJ_FUNC cases. Only
130** indirect calls and related tail-called C functions are marked as fastcall.
131*/
132#if defined(__i386__)
133#define LJ_FASTCALL __attribute__((fastcall))
134#endif
135
136#define LJ_LIKELY(x) __builtin_expect(!!(x), 1)
137#define LJ_UNLIKELY(x) __builtin_expect(!!(x), 0)
138
139#define lj_ffs(x) ((uint32_t)__builtin_ctz(x))
140/* Don't ask ... */
141#if defined(__INTEL_COMPILER) && (defined(__i386__) || defined(__x86_64__))
142static LJ_AINLINE uint32_t lj_fls(uint32_t x)
143{
144 uint32_t r; __asm__("bsrl %1, %0" : "=r" (r) : "rm" (x) : "cc"); return r;
145}
146#else
147#define lj_fls(x) ((uint32_t)(__builtin_clz(x)^31))
148#endif
149
150#if defined(__arm__)
151static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
152{
153 uint32_t r;
154#if __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6T2__ || __ARM_ARCH_6Z__ ||\
155 __ARM_ARCH_6ZK__ || __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__
156 __asm__("rev %0, %1" : "=r" (r) : "r" (x));
157 return r;
158#else
159#ifdef __thumb__
160 r = x ^ lj_ror(x, 16);
161#else
162 __asm__("eor %0, %1, %1, ror #16" : "=r" (r) : "r" (x));
163#endif
164 return ((r & 0xff00ffffu) >> 8) ^ lj_ror(x, 8);
165#endif
166}
167
168static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
169{
170 return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32));
171}
172#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
173static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
174{
175 return (uint32_t)__builtin_bswap32((int32_t)x);
176}
177
178static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
179{
180 return (uint64_t)__builtin_bswap64((int64_t)x);
181}
182#elif defined(__i386__) || defined(__x86_64__)
183static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
184{
185 uint32_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r;
186}
187
188#if defined(__i386__)
189static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
190{
191 return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32));
192}
193#else
194static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
195{
196 uint64_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r;
197}
198#endif
199#else
200#error "missing define for lj_bswap()"
201#endif
202
203typedef union __attribute__((packed)) Unaligned16 {
204 uint16_t u;
205 uint8_t b[2];
206} Unaligned16;
207
208typedef union __attribute__((packed)) Unaligned32 {
209 uint32_t u;
210 uint8_t b[4];
211} Unaligned32;
212
213/* Unaligned load of uint16_t. */
214static LJ_AINLINE uint16_t lj_getu16(const void *p)
215{
216 return ((const Unaligned16 *)p)->u;
217}
218
219/* Unaligned load of uint32_t. */
220static LJ_AINLINE uint32_t lj_getu32(const void *p)
221{
222 return ((const Unaligned32 *)p)->u;
223}
224
225#elif defined(_MSC_VER)
226
227#define LJ_NORET __declspec(noreturn)
228#define LJ_ALIGN(n) __declspec(align(n))
229#define LJ_INLINE __inline
230#define LJ_AINLINE __forceinline
231#define LJ_NOINLINE __declspec(noinline)
232#if defined(_M_IX86)
233#define LJ_FASTCALL __fastcall
234#endif
235
236static LJ_AINLINE uint32_t lj_ffs(uint32_t x)
237{
238 uint32_t r; _BitScanForward(&r, x); return r;
239}
240
241static LJ_AINLINE uint32_t lj_fls(uint32_t x)
242{
243 uint32_t r; _BitScanReverse(&r, x); return r;
244}
245
246#define lj_bswap(x) (_byteswap_ulong((x)))
247#define lj_bswap64(x) (_byteswap_uint64((x)))
248
249/* MSVC is only supported on x86/x64, where unaligned loads are always ok. */
250#define lj_getu16(p) (*(uint16_t *)(p))
251#define lj_getu32(p) (*(uint32_t *)(p))
252
253#else
254#error "missing defines for your compiler"
255#endif
256
257/* Optional defines. */
258#ifndef LJ_FASTCALL
259#define LJ_FASTCALL
260#endif
261#ifndef LJ_NORET
262#define LJ_NORET
263#endif
264#ifndef LJ_NOAPI
265#define LJ_NOAPI extern
266#endif
267#ifndef LJ_LIKELY
268#define LJ_LIKELY(x) (x)
269#define LJ_UNLIKELY(x) (x)
270#endif
271
272/* Attributes for internal functions. */
273#define LJ_DATA LJ_NOAPI
274#define LJ_DATADEF
275#define LJ_ASMF LJ_NOAPI
276#define LJ_FUNCA LJ_NOAPI
277#if defined(ljamalg_c)
278#define LJ_FUNC static
279#else
280#define LJ_FUNC LJ_NOAPI
281#endif
282#define LJ_FUNC_NORET LJ_FUNC LJ_NORET
283#define LJ_FUNCA_NORET LJ_FUNCA LJ_NORET
284#define LJ_ASMF_NORET LJ_ASMF LJ_NORET
285
286/* Runtime assertions. */
287#ifdef lua_assert
288#define check_exp(c, e) (lua_assert(c), (e))
289#define api_check(l, e) lua_assert(e)
290#else
291#define lua_assert(c) ((void)0)
292#define check_exp(c, e) (e)
293#define api_check luai_apicheck
294#endif
295
296/* Static assertions. */
297#define LJ_ASSERT_NAME2(name, line) name ## line
298#define LJ_ASSERT_NAME(line) LJ_ASSERT_NAME2(lj_assert_, line)
299#ifdef __COUNTER__
300#define LJ_STATIC_ASSERT(cond) \
301 extern void LJ_ASSERT_NAME(__COUNTER__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
302#else
303#define LJ_STATIC_ASSERT(cond) \
304 extern void LJ_ASSERT_NAME(__LINE__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
305#endif
306
307#endif
diff --git a/libraries/luajit-2.0/src/lj_dispatch.c b/libraries/luajit-2.0/src/lj_dispatch.c
new file mode 100644
index 0000000..38fd170
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_dispatch.c
@@ -0,0 +1,464 @@
1/*
2** Instruction dispatch handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_dispatch_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#include "lj_err.h"
11#include "lj_debug.h"
12#include "lj_state.h"
13#include "lj_frame.h"
14#include "lj_bc.h"
15#include "lj_ff.h"
16#if LJ_HASJIT
17#include "lj_jit.h"
18#endif
19#include "lj_trace.h"
20#include "lj_dispatch.h"
21#include "lj_vm.h"
22#include "luajit.h"
23
24/* Bump GG_NUM_ASMFF in lj_dispatch.h as needed. Ugly. */
25LJ_STATIC_ASSERT(GG_NUM_ASMFF == FF_NUM_ASMFUNC);
26
27/* -- Dispatch table management ------------------------------------------- */
28
29/* Initialize instruction dispatch table and hot counters. */
30void lj_dispatch_init(GG_State *GG)
31{
32 uint32_t i;
33 ASMFunction *disp = GG->dispatch;
34 for (i = 0; i < GG_LEN_SDISP; i++)
35 disp[GG_LEN_DDISP+i] = disp[i] = makeasmfunc(lj_bc_ofs[i]);
36 for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
37 disp[i] = makeasmfunc(lj_bc_ofs[i]);
38 /* The JIT engine is off by default. luaopen_jit() turns it on. */
39 disp[BC_FORL] = disp[BC_IFORL];
40 disp[BC_ITERL] = disp[BC_IITERL];
41 disp[BC_LOOP] = disp[BC_ILOOP];
42 disp[BC_FUNCF] = disp[BC_IFUNCF];
43 disp[BC_FUNCV] = disp[BC_IFUNCV];
44 GG->g.bc_cfunc_ext = GG->g.bc_cfunc_int = BCINS_AD(BC_FUNCC, LUA_MINSTACK, 0);
45 for (i = 0; i < GG_NUM_ASMFF; i++)
46 GG->bcff[i] = BCINS_AD(BC__MAX+i, 0, 0);
47}
48
49#if LJ_HASJIT
50/* Initialize hotcount table. */
51void lj_dispatch_init_hotcount(global_State *g)
52{
53 int32_t hotloop = G2J(g)->param[JIT_P_hotloop];
54 HotCount start = (HotCount)(hotloop*HOTCOUNT_LOOP - 1);
55 HotCount *hotcount = G2GG(g)->hotcount;
56 uint32_t i;
57 for (i = 0; i < HOTCOUNT_SIZE; i++)
58 hotcount[i] = start;
59}
60#endif
61
62/* Internal dispatch mode bits. */
63#define DISPMODE_JIT 0x01 /* JIT compiler on. */
64#define DISPMODE_REC 0x02 /* Recording active. */
65#define DISPMODE_INS 0x04 /* Override instruction dispatch. */
66#define DISPMODE_CALL 0x08 /* Override call dispatch. */
67#define DISPMODE_RET 0x08 /* Override return dispatch. */
68
69/* Update dispatch table depending on various flags. */
70void lj_dispatch_update(global_State *g)
71{
72 uint8_t oldmode = g->dispatchmode;
73 uint8_t mode = 0;
74#if LJ_HASJIT
75 mode |= (G2J(g)->flags & JIT_F_ON) ? DISPMODE_JIT : 0;
76 mode |= G2J(g)->state != LJ_TRACE_IDLE ?
77 (DISPMODE_REC|DISPMODE_INS|DISPMODE_CALL) : 0;
78#endif
79 mode |= (g->hookmask & (LUA_MASKLINE|LUA_MASKCOUNT)) ? DISPMODE_INS : 0;
80 mode |= (g->hookmask & LUA_MASKCALL) ? DISPMODE_CALL : 0;
81 mode |= (g->hookmask & LUA_MASKRET) ? DISPMODE_RET : 0;
82 if (oldmode != mode) { /* Mode changed? */
83 ASMFunction *disp = G2GG(g)->dispatch;
84 ASMFunction f_forl, f_iterl, f_loop, f_funcf, f_funcv;
85 g->dispatchmode = mode;
86
87 /* Hotcount if JIT is on, but not while recording. */
88 if ((mode & (DISPMODE_JIT|DISPMODE_REC)) == DISPMODE_JIT) {
89 f_forl = makeasmfunc(lj_bc_ofs[BC_FORL]);
90 f_iterl = makeasmfunc(lj_bc_ofs[BC_ITERL]);
91 f_loop = makeasmfunc(lj_bc_ofs[BC_LOOP]);
92 f_funcf = makeasmfunc(lj_bc_ofs[BC_FUNCF]);
93 f_funcv = makeasmfunc(lj_bc_ofs[BC_FUNCV]);
94 } else { /* Otherwise use the non-hotcounting instructions. */
95 f_forl = disp[GG_LEN_DDISP+BC_IFORL];
96 f_iterl = disp[GG_LEN_DDISP+BC_IITERL];
97 f_loop = disp[GG_LEN_DDISP+BC_ILOOP];
98 f_funcf = makeasmfunc(lj_bc_ofs[BC_IFUNCF]);
99 f_funcv = makeasmfunc(lj_bc_ofs[BC_IFUNCV]);
100 }
101 /* Init static counting instruction dispatch first (may be copied below). */
102 disp[GG_LEN_DDISP+BC_FORL] = f_forl;
103 disp[GG_LEN_DDISP+BC_ITERL] = f_iterl;
104 disp[GG_LEN_DDISP+BC_LOOP] = f_loop;
105
106 /* Set dynamic instruction dispatch. */
107 if ((oldmode ^ mode) & (DISPMODE_REC|DISPMODE_INS)) {
108 /* Need to update the whole table. */
109 if (!(mode & (DISPMODE_REC|DISPMODE_INS))) { /* No ins dispatch? */
110 /* Copy static dispatch table to dynamic dispatch table. */
111 memcpy(&disp[0], &disp[GG_LEN_DDISP], GG_LEN_SDISP*sizeof(ASMFunction));
112 /* Overwrite with dynamic return dispatch. */
113 if ((mode & DISPMODE_RET)) {
114 disp[BC_RETM] = lj_vm_rethook;
115 disp[BC_RET] = lj_vm_rethook;
116 disp[BC_RET0] = lj_vm_rethook;
117 disp[BC_RET1] = lj_vm_rethook;
118 }
119 } else {
120 /* The recording dispatch also checks for hooks. */
121 ASMFunction f = (mode & DISPMODE_REC) ? lj_vm_record : lj_vm_inshook;
122 uint32_t i;
123 for (i = 0; i < GG_LEN_SDISP; i++)
124 disp[i] = f;
125 }
126 } else if (!(mode & (DISPMODE_REC|DISPMODE_INS))) {
127 /* Otherwise set dynamic counting ins. */
128 disp[BC_FORL] = f_forl;
129 disp[BC_ITERL] = f_iterl;
130 disp[BC_LOOP] = f_loop;
131 /* Set dynamic return dispatch. */
132 if ((mode & DISPMODE_RET)) {
133 disp[BC_RETM] = lj_vm_rethook;
134 disp[BC_RET] = lj_vm_rethook;
135 disp[BC_RET0] = lj_vm_rethook;
136 disp[BC_RET1] = lj_vm_rethook;
137 } else {
138 disp[BC_RETM] = disp[GG_LEN_DDISP+BC_RETM];
139 disp[BC_RET] = disp[GG_LEN_DDISP+BC_RET];
140 disp[BC_RET0] = disp[GG_LEN_DDISP+BC_RET0];
141 disp[BC_RET1] = disp[GG_LEN_DDISP+BC_RET1];
142 }
143 }
144
145 /* Set dynamic call dispatch. */
146 if ((oldmode ^ mode) & DISPMODE_CALL) { /* Update the whole table? */
147 uint32_t i;
148 if ((mode & 8) == 0) { /* No call hooks? */
149 for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
150 disp[i] = makeasmfunc(lj_bc_ofs[i]);
151 } else {
152 for (i = GG_LEN_SDISP; i < GG_LEN_DDISP; i++)
153 disp[i] = lj_vm_callhook;
154 }
155 }
156 if (!(mode & DISPMODE_CALL)) { /* Overwrite dynamic counting ins. */
157 disp[BC_FUNCF] = f_funcf;
158 disp[BC_FUNCV] = f_funcv;
159 }
160
161#if LJ_HASJIT
162 /* Reset hotcounts for JIT off to on transition. */
163 if ((mode & DISPMODE_JIT) && !(oldmode & DISPMODE_JIT))
164 lj_dispatch_init_hotcount(g);
165#endif
166 }
167}
168
169/* -- JIT mode setting ---------------------------------------------------- */
170
171#if LJ_HASJIT
172/* Set JIT mode for a single prototype. */
173static void setptmode(global_State *g, GCproto *pt, int mode)
174{
175 if ((mode & LUAJIT_MODE_ON)) { /* (Re-)enable JIT compilation. */
176 pt->flags &= ~PROTO_NOJIT;
177 lj_trace_reenableproto(pt); /* Unpatch all ILOOP etc. bytecodes. */
178 } else { /* Flush and/or disable JIT compilation. */
179 if (!(mode & LUAJIT_MODE_FLUSH))
180 pt->flags |= PROTO_NOJIT;
181 lj_trace_flushproto(g, pt); /* Flush all traces of prototype. */
182 }
183}
184
185/* Recursively set the JIT mode for all children of a prototype. */
186static void setptmode_all(global_State *g, GCproto *pt, int mode)
187{
188 ptrdiff_t i;
189 if (!(pt->flags & PROTO_CHILD)) return;
190 for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) {
191 GCobj *o = proto_kgc(pt, i);
192 if (o->gch.gct == ~LJ_TPROTO) {
193 setptmode(g, gco2pt(o), mode);
194 setptmode_all(g, gco2pt(o), mode);
195 }
196 }
197}
198#endif
199
200/* Public API function: control the JIT engine. */
201int luaJIT_setmode(lua_State *L, int idx, int mode)
202{
203 global_State *g = G(L);
204 int mm = mode & LUAJIT_MODE_MASK;
205 lj_trace_abort(g); /* Abort recording on any state change. */
206 /* Avoid pulling the rug from under our own feet. */
207 if ((g->hookmask & HOOK_GC))
208 lj_err_caller(L, LJ_ERR_NOGCMM);
209 switch (mm) {
210#if LJ_HASJIT
211 case LUAJIT_MODE_ENGINE:
212 if ((mode & LUAJIT_MODE_FLUSH)) {
213 lj_trace_flushall(L);
214 } else {
215 if (!(mode & LUAJIT_MODE_ON))
216 G2J(g)->flags &= ~(uint32_t)JIT_F_ON;
217#if LJ_TARGET_X86ORX64
218 else if ((G2J(g)->flags & JIT_F_SSE2))
219 G2J(g)->flags |= (uint32_t)JIT_F_ON;
220 else
221 return 0; /* Don't turn on JIT compiler without SSE2 support. */
222#else
223 else
224 G2J(g)->flags |= (uint32_t)JIT_F_ON;
225#endif
226 lj_dispatch_update(g);
227 }
228 break;
229 case LUAJIT_MODE_FUNC:
230 case LUAJIT_MODE_ALLFUNC:
231 case LUAJIT_MODE_ALLSUBFUNC: {
232 cTValue *tv = idx == 0 ? frame_prev(L->base-1) :
233 idx > 0 ? L->base + (idx-1) : L->top + idx;
234 GCproto *pt;
235 if ((idx == 0 || tvisfunc(tv)) && isluafunc(&gcval(tv)->fn))
236 pt = funcproto(&gcval(tv)->fn); /* Cannot use funcV() for frame slot. */
237 else if (tvisproto(tv))
238 pt = protoV(tv);
239 else
240 return 0; /* Failed. */
241 if (mm != LUAJIT_MODE_ALLSUBFUNC)
242 setptmode(g, pt, mode);
243 if (mm != LUAJIT_MODE_FUNC)
244 setptmode_all(g, pt, mode);
245 break;
246 }
247 case LUAJIT_MODE_TRACE:
248 if (!(mode & LUAJIT_MODE_FLUSH))
249 return 0; /* Failed. */
250 lj_trace_flush(G2J(g), idx);
251 break;
252#else
253 case LUAJIT_MODE_ENGINE:
254 case LUAJIT_MODE_FUNC:
255 case LUAJIT_MODE_ALLFUNC:
256 case LUAJIT_MODE_ALLSUBFUNC:
257 UNUSED(idx);
258 if ((mode & LUAJIT_MODE_ON))
259 return 0; /* Failed. */
260 break;
261#endif
262 case LUAJIT_MODE_WRAPCFUNC:
263 if ((mode & LUAJIT_MODE_ON)) {
264 if (idx != 0) {
265 cTValue *tv = idx > 0 ? L->base + (idx-1) : L->top + idx;
266 if (tvislightud(tv))
267 g->wrapf = (lua_CFunction)lightudV(tv);
268 else
269 return 0; /* Failed. */
270 } else {
271 return 0; /* Failed. */
272 }
273 g->bc_cfunc_ext = BCINS_AD(BC_FUNCCW, 0, 0);
274 } else {
275 g->bc_cfunc_ext = BCINS_AD(BC_FUNCC, 0, 0);
276 }
277 break;
278 default:
279 return 0; /* Failed. */
280 }
281 return 1; /* OK. */
282}
283
284/* Enforce (dynamic) linker error for version mismatches. See luajit.c. */
285LUA_API void LUAJIT_VERSION_SYM(void)
286{
287}
288
289/* -- Hooks --------------------------------------------------------------- */
290
291/* This function can be called asynchronously (e.g. during a signal). */
292LUA_API int lua_sethook(lua_State *L, lua_Hook func, int mask, int count)
293{
294 global_State *g = G(L);
295 mask &= HOOK_EVENTMASK;
296 if (func == NULL || mask == 0) { mask = 0; func = NULL; } /* Consistency. */
297 g->hookf = func;
298 g->hookcount = g->hookcstart = (int32_t)count;
299 g->hookmask = (uint8_t)((g->hookmask & ~HOOK_EVENTMASK) | mask);
300 lj_trace_abort(g); /* Abort recording on any hook change. */
301 lj_dispatch_update(g);
302 return 1;
303}
304
305LUA_API lua_Hook lua_gethook(lua_State *L)
306{
307 return G(L)->hookf;
308}
309
310LUA_API int lua_gethookmask(lua_State *L)
311{
312 return G(L)->hookmask & HOOK_EVENTMASK;
313}
314
315LUA_API int lua_gethookcount(lua_State *L)
316{
317 return (int)G(L)->hookcstart;
318}
319
320/* Call a hook. */
321static void callhook(lua_State *L, int event, BCLine line)
322{
323 global_State *g = G(L);
324 lua_Hook hookf = g->hookf;
325 if (hookf && !hook_active(g)) {
326 lua_Debug ar;
327 lj_trace_abort(g); /* Abort recording on any hook call. */
328 ar.event = event;
329 ar.currentline = line;
330 /* Top frame, nextframe = NULL. */
331 ar.i_ci = (int)((L->base-1) - tvref(L->stack));
332 lj_state_checkstack(L, 1+LUA_MINSTACK);
333 hook_enter(g);
334 hookf(L, &ar);
335 lua_assert(hook_active(g));
336 hook_leave(g);
337 }
338}
339
340/* -- Dispatch callbacks -------------------------------------------------- */
341
342/* Calculate number of used stack slots in the current frame. */
343static BCReg cur_topslot(GCproto *pt, const BCIns *pc, uint32_t nres)
344{
345 BCIns ins = pc[-1];
346 if (bc_op(ins) == BC_UCLO)
347 ins = pc[bc_j(ins)];
348 switch (bc_op(ins)) {
349 case BC_CALLM: case BC_CALLMT: return bc_a(ins) + bc_c(ins) + nres-1+1;
350 case BC_RETM: return bc_a(ins) + bc_d(ins) + nres-1;
351 case BC_TSETM: return bc_a(ins) + nres-1;
352 default: return pt->framesize;
353 }
354}
355
356/* Instruction dispatch. Used by instr/line/return hooks or when recording. */
357void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
358{
359 ERRNO_SAVE
360 GCfunc *fn = curr_func(L);
361 GCproto *pt = funcproto(fn);
362 void *cf = cframe_raw(L->cframe);
363 const BCIns *oldpc = cframe_pc(cf);
364 global_State *g = G(L);
365 BCReg slots;
366 setcframe_pc(cf, pc);
367 slots = cur_topslot(pt, pc, cframe_multres_n(cf));
368 L->top = L->base + slots; /* Fix top. */
369#if LJ_HASJIT
370 {
371 jit_State *J = G2J(g);
372 if (J->state != LJ_TRACE_IDLE) {
373 J->L = L;
374 lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
375 }
376 }
377#endif
378 if ((g->hookmask & LUA_MASKCOUNT) && g->hookcount == 0) {
379 g->hookcount = g->hookcstart;
380 callhook(L, LUA_HOOKCOUNT, -1);
381 L->top = L->base + slots; /* Fix top again. */
382 }
383 if ((g->hookmask & LUA_MASKLINE)) {
384 BCPos npc = proto_bcpos(pt, pc) - 1;
385 BCPos opc = proto_bcpos(pt, oldpc) - 1;
386 BCLine line = lj_debug_line(pt, npc);
387 if (pc <= oldpc || opc >= pt->sizebc || line != lj_debug_line(pt, opc)) {
388 callhook(L, LUA_HOOKLINE, line);
389 L->top = L->base + slots; /* Fix top again. */
390 }
391 }
392 if ((g->hookmask & LUA_MASKRET) && bc_isret(bc_op(pc[-1])))
393 callhook(L, LUA_HOOKRET, -1);
394 ERRNO_RESTORE
395}
396
397/* Initialize call. Ensure stack space and return # of missing parameters. */
398static int call_init(lua_State *L, GCfunc *fn)
399{
400 if (isluafunc(fn)) {
401 GCproto *pt = funcproto(fn);
402 int numparams = pt->numparams;
403 int gotparams = (int)(L->top - L->base);
404 int need = pt->framesize;
405 if ((pt->flags & PROTO_VARARG)) need += 1+gotparams;
406 lj_state_checkstack(L, (MSize)need);
407 numparams -= gotparams;
408 return numparams >= 0 ? numparams : 0;
409 } else {
410 lj_state_checkstack(L, LUA_MINSTACK);
411 return 0;
412 }
413}
414
415/* Call dispatch. Used by call hooks, hot calls or when recording. */
416ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
417{
418 ERRNO_SAVE
419 GCfunc *fn = curr_func(L);
420 BCOp op;
421 global_State *g = G(L);
422#if LJ_HASJIT
423 jit_State *J = G2J(g);
424#endif
425 int missing = call_init(L, fn);
426#if LJ_HASJIT
427 J->L = L;
428 if ((uintptr_t)pc & 1) { /* Marker for hot call. */
429 pc = (const BCIns *)((uintptr_t)pc & ~(uintptr_t)1);
430 lj_trace_hot(J, pc);
431 goto out;
432 } else if (J->state != LJ_TRACE_IDLE &&
433 !(g->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
434#ifdef LUA_USE_ASSERT
435 ptrdiff_t delta = L->top - L->base;
436#endif
437 /* Record the FUNC* bytecodes, too. */
438 lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
439 lua_assert(L->top - L->base == delta);
440 }
441#endif
442 if ((g->hookmask & LUA_MASKCALL)) {
443 int i;
444 for (i = 0; i < missing; i++) /* Add missing parameters. */
445 setnilV(L->top++);
446 callhook(L, LUA_HOOKCALL, -1);
447 /* Preserve modifications of missing parameters by lua_setlocal(). */
448 while (missing-- > 0 && tvisnil(L->top - 1))
449 L->top--;
450 }
451#if LJ_HASJIT
452out:
453#endif
454 op = bc_op(pc[-1]); /* Get FUNC* op. */
455#if LJ_HASJIT
456 /* Use the non-hotcounting variants if JIT is off or while recording. */
457 if ((!(J->flags & JIT_F_ON) || J->state != LJ_TRACE_IDLE) &&
458 (op == BC_FUNCF || op == BC_FUNCV))
459 op = (BCOp)((int)op+(int)BC_IFUNCF-(int)BC_FUNCF);
460#endif
461 ERRNO_RESTORE
462 return makeasmfunc(lj_bc_ofs[op]); /* Return static dispatch target. */
463}
464
diff --git a/libraries/luajit-2.0/src/lj_dispatch.h b/libraries/luajit-2.0/src/lj_dispatch.h
new file mode 100644
index 0000000..c50d33a
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_dispatch.h
@@ -0,0 +1,93 @@
1/*
2** Instruction dispatch handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_DISPATCH_H
7#define _LJ_DISPATCH_H
8
9#include "lj_obj.h"
10#include "lj_bc.h"
11#if LJ_HASJIT
12#include "lj_jit.h"
13#endif
14
15/* Type of hot counter. Must match the code in the assembler VM. */
16/* 16 bits are sufficient. Only 0.0015% overhead with maximum slot penalty. */
17typedef uint16_t HotCount;
18
19/* Number of hot counter hash table entries (must be a power of two). */
20#define HOTCOUNT_SIZE 64
21#define HOTCOUNT_PCMASK ((HOTCOUNT_SIZE-1)*sizeof(HotCount))
22
23/* Hotcount decrements. */
24#define HOTCOUNT_LOOP 2
25#define HOTCOUNT_CALL 1
26
27/* This solves a circular dependency problem -- bump as needed. Sigh. */
28#define GG_NUM_ASMFF 62
29
30#define GG_LEN_DDISP (BC__MAX + GG_NUM_ASMFF)
31#define GG_LEN_SDISP BC_FUNCF
32#define GG_LEN_DISP (GG_LEN_DDISP + GG_LEN_SDISP)
33
34/* Global state, main thread and extra fields are allocated together. */
35typedef struct GG_State {
36 lua_State L; /* Main thread. */
37 global_State g; /* Global state. */
38#if LJ_HASJIT
39 jit_State J; /* JIT state. */
40 HotCount hotcount[HOTCOUNT_SIZE]; /* Hot counters. */
41#endif
42 ASMFunction dispatch[GG_LEN_DISP]; /* Instruction dispatch tables. */
43 BCIns bcff[GG_NUM_ASMFF]; /* Bytecode for ASM fast functions. */
44} GG_State;
45
46#define GG_OFS(field) ((int)offsetof(GG_State, field))
47#define G2GG(gl) ((GG_State *)((char *)(gl) - GG_OFS(g)))
48#define J2GG(j) ((GG_State *)((char *)(j) - GG_OFS(J)))
49#define L2GG(L) (G2GG(G(L)))
50#define J2G(J) (&J2GG(J)->g)
51#define G2J(gl) (&G2GG(gl)->J)
52#define L2J(L) (&L2GG(L)->J)
53#define GG_G2DISP (GG_OFS(dispatch) - GG_OFS(g))
54#define GG_DISP2G (GG_OFS(g) - GG_OFS(dispatch))
55#define GG_DISP2J (GG_OFS(J) - GG_OFS(dispatch))
56#define GG_DISP2HOT (GG_OFS(hotcount) - GG_OFS(dispatch))
57#define GG_DISP2STATIC (GG_LEN_DDISP*(int)sizeof(ASMFunction))
58
59#define hotcount_get(gg, pc) \
60 (gg)->hotcount[(u32ptr(pc)>>2) & (HOTCOUNT_SIZE-1)]
61#define hotcount_set(gg, pc, val) \
62 (hotcount_get((gg), (pc)) = (HotCount)(val))
63
64/* Dispatch table management. */
65LJ_FUNC void lj_dispatch_init(GG_State *GG);
66#if LJ_HASJIT
67LJ_FUNC void lj_dispatch_init_hotcount(global_State *g);
68#endif
69LJ_FUNC void lj_dispatch_update(global_State *g);
70
71/* Instruction dispatch callback for hooks or when recording. */
72LJ_FUNCA void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc);
73LJ_FUNCA ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns*pc);
74LJ_FUNCA void LJ_FASTCALL lj_dispatch_return(lua_State *L, const BCIns *pc);
75
76#if LJ_HASFFI && !defined(_BUILDVM_H)
77/* Save/restore errno and GetLastError() around hooks, exits and recording. */
78#include <errno.h>
79#if LJ_TARGET_WINDOWS
80#define WIN32_LEAN_AND_MEAN
81#include <windows.h>
82#define ERRNO_SAVE int olderr = errno; DWORD oldwerr = GetLastError();
83#define ERRNO_RESTORE errno = olderr; SetLastError(oldwerr);
84#else
85#define ERRNO_SAVE int olderr = errno;
86#define ERRNO_RESTORE errno = olderr;
87#endif
88#else
89#define ERRNO_SAVE
90#define ERRNO_RESTORE
91#endif
92
93#endif
diff --git a/libraries/luajit-2.0/src/lj_emit_arm.h b/libraries/luajit-2.0/src/lj_emit_arm.h
new file mode 100644
index 0000000..ea90852
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_emit_arm.h
@@ -0,0 +1,300 @@
1/*
2** ARM instruction emitter.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* -- Constant encoding --------------------------------------------------- */
7
8static uint8_t emit_invai[16] = {
9 /* AND */ (ARMI_AND^ARMI_BIC) >> 21,
10 /* EOR */ 0,
11 /* SUB */ (ARMI_SUB^ARMI_ADD) >> 21,
12 /* RSB */ 0,
13 /* ADD */ (ARMI_ADD^ARMI_SUB) >> 21,
14 /* ADC */ (ARMI_ADC^ARMI_SBC) >> 21,
15 /* SBC */ (ARMI_SBC^ARMI_ADC) >> 21,
16 /* RSC */ 0,
17 /* TST */ 0,
18 /* TEQ */ 0,
19 /* CMP */ (ARMI_CMP^ARMI_CMN) >> 21,
20 /* CMN */ (ARMI_CMN^ARMI_CMP) >> 21,
21 /* ORR */ 0,
22 /* MOV */ (ARMI_MOV^ARMI_MVN) >> 21,
23 /* BIC */ (ARMI_BIC^ARMI_AND) >> 21,
24 /* MVN */ (ARMI_MVN^ARMI_MOV) >> 21
25};
26
27/* Encode constant in K12 format for data processing instructions. */
28static uint32_t emit_isk12(ARMIns ai, int32_t n)
29{
30 uint32_t invai, i, m = (uint32_t)n;
31 /* K12: unsigned 8 bit value, rotated in steps of two bits. */
32 for (i = 0; i < 4096; i += 256, m = lj_rol(m, 2))
33 if (m <= 255) return ARMI_K12|m|i;
34 /* Otherwise try negation/complement with the inverse instruction. */
35 invai = emit_invai[((ai >> 21) & 15)];
36 if (!invai) return 0; /* Failed. No inverse instruction. */
37 m = ~(uint32_t)n;
38 if (invai == ((ARMI_SUB^ARMI_ADD) >> 21) ||
39 invai == (ARMI_CMP^ARMI_CMN) >> 21) m++;
40 for (i = 0; i < 4096; i += 256, m = lj_rol(m, 2))
41 if (m <= 255) return ARMI_K12|(invai<<21)|m|i;
42 return 0; /* Failed. */
43}
44
45/* -- Emit basic instructions --------------------------------------------- */
46
47static void emit_dnm(ASMState *as, ARMIns ai, Reg rd, Reg rn, Reg rm)
48{
49 *--as->mcp = ai | ARMF_D(rd) | ARMF_N(rn) | ARMF_M(rm);
50}
51
52static void emit_dm(ASMState *as, ARMIns ai, Reg rd, Reg rm)
53{
54 *--as->mcp = ai | ARMF_D(rd) | ARMF_M(rm);
55}
56
57static void emit_dn(ASMState *as, ARMIns ai, Reg rd, Reg rn)
58{
59 *--as->mcp = ai | ARMF_D(rd) | ARMF_N(rn);
60}
61
62static void emit_nm(ASMState *as, ARMIns ai, Reg rn, Reg rm)
63{
64 *--as->mcp = ai | ARMF_N(rn) | ARMF_M(rm);
65}
66
67static void emit_d(ASMState *as, ARMIns ai, Reg rd)
68{
69 *--as->mcp = ai | ARMF_D(rd);
70}
71
72static void emit_n(ASMState *as, ARMIns ai, Reg rn)
73{
74 *--as->mcp = ai | ARMF_N(rn);
75}
76
77static void emit_m(ASMState *as, ARMIns ai, Reg rm)
78{
79 *--as->mcp = ai | ARMF_M(rm);
80}
81
82static void emit_lsox(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
83{
84 lua_assert(ofs >= -255 && ofs <= 255);
85 if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
86 *--as->mcp = ai | ARMI_LS_P | ARMI_LSX_I | ARMF_D(rd) | ARMF_N(rn) |
87 ((ofs & 0xf0) << 4) | (ofs & 0x0f);
88}
89
90static void emit_lso(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
91{
92 lua_assert(ofs >= -4095 && ofs <= 4095);
93 /* Combine LDR/STR pairs to LDRD/STRD. */
94 if (*as->mcp == (ai|ARMI_LS_P|ARMI_LS_U|ARMF_D(rd^1)|ARMF_N(rn)|(ofs^4)) &&
95 (ai & ~(ARMI_LDR^ARMI_STR)) == ARMI_STR && rd != rn &&
96 (uint32_t)ofs <= 252 && !(ofs & 3) && !((rd ^ (ofs >>2)) & 1) &&
97 as->mcp != as->mcloop) {
98 as->mcp++;
99 emit_lsox(as, ai == ARMI_LDR ? ARMI_LDRD : ARMI_STRD, rd&~1, rn, ofs&~4);
100 return;
101 }
102 if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
103 *--as->mcp = ai | ARMI_LS_P | ARMF_D(rd) | ARMF_N(rn) | ofs;
104}
105
106/* -- Emit loads/stores --------------------------------------------------- */
107
108/* Prefer spills of BASE/L. */
109#define emit_canremat(ref) ((ref) < ASMREF_L)
110
111/* Try to find a one step delta relative to another constant. */
112static int emit_kdelta1(ASMState *as, Reg d, int32_t i)
113{
114 RegSet work = ~as->freeset & RSET_GPR;
115 while (work) {
116 Reg r = rset_picktop(work);
117 IRRef ref = regcost_ref(as->cost[r]);
118 lua_assert(r != d);
119 if (emit_canremat(ref)) {
120 int32_t delta = i - (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i);
121 uint32_t k = emit_isk12(ARMI_ADD, delta);
122 if (k) {
123 if (k == ARMI_K12)
124 emit_dm(as, ARMI_MOV, d, r);
125 else
126 emit_dn(as, ARMI_ADD^k, d, r);
127 return 1;
128 }
129 }
130 rset_clear(work, r);
131 }
132 return 0; /* Failed. */
133}
134
135/* Try to find a two step delta relative to another constant. */
136static int emit_kdelta2(ASMState *as, Reg d, int32_t i)
137{
138 RegSet work = ~as->freeset & RSET_GPR;
139 while (work) {
140 Reg r = rset_picktop(work);
141 IRRef ref = regcost_ref(as->cost[r]);
142 lua_assert(r != d);
143 if (emit_canremat(ref)) {
144 int32_t delta = i - (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i);
145 uint32_t sh, inv = 0, k2, k;
146 if (delta < 0) { delta = -delta; inv = ARMI_ADD^ARMI_SUB; }
147 sh = lj_ffs(delta) & ~1;
148 k2 = emit_isk12(0, delta & (255 << sh));
149 k = emit_isk12(0, delta & ~(255 << sh));
150 if (k) {
151 emit_dn(as, ARMI_ADD^k2^inv, d, d);
152 emit_dn(as, ARMI_ADD^k^inv, d, r);
153 return 1;
154 }
155 }
156 rset_clear(work, r);
157 }
158 return 0; /* Failed. */
159}
160
161/* Load a 32 bit constant into a GPR. */
162static void emit_loadi(ASMState *as, Reg r, int32_t i)
163{
164 uint32_t k = emit_isk12(ARMI_MOV, i);
165 lua_assert(rset_test(as->freeset, r) || r == RID_TMP);
166 if (k) {
167 /* Standard K12 constant. */
168 emit_d(as, ARMI_MOV^k, r);
169 } else if ((as->flags & JIT_F_ARMV6T2) && (uint32_t)i < 0x00010000u) {
170 /* 16 bit loword constant for ARMv6T2. */
171 emit_d(as, ARMI_MOVW|(i & 0x0fff)|((i & 0xf000)<<4), r);
172 } else if (emit_kdelta1(as, r, i)) {
173 /* One step delta relative to another constant. */
174 } else if ((as->flags & JIT_F_ARMV6T2)) {
175 /* 32 bit hiword/loword constant for ARMv6T2. */
176 emit_d(as, ARMI_MOVT|((i>>16) & 0x0fff)|(((i>>16) & 0xf000)<<4), r);
177 emit_d(as, ARMI_MOVW|(i & 0x0fff)|((i & 0xf000)<<4), r);
178 } else if (emit_kdelta2(as, r, i)) {
179 /* Two step delta relative to another constant. */
180 } else {
181 /* Otherwise construct the constant with up to 4 instructions. */
182 /* NYI: use mvn+bic, use pc-relative loads. */
183 for (;;) {
184 uint32_t sh = lj_ffs(i) & ~1;
185 int32_t m = i & (255 << sh);
186 i &= ~(255 << sh);
187 if (i == 0) {
188 emit_d(as, ARMI_MOV ^ emit_isk12(0, m), r);
189 break;
190 }
191 emit_dn(as, ARMI_ORR ^ emit_isk12(0, m), r, r);
192 }
193 }
194}
195
196#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
197
198static Reg ra_allock(ASMState *as, int32_t k, RegSet allow);
199
200/* Get/set from constant pointer. */
201static void emit_lsptr(ASMState *as, ARMIns ai, Reg r, void *p)
202{
203 int32_t i = i32ptr(p);
204 emit_lso(as, ai, r, ra_allock(as, (i & ~4095), rset_exclude(RSET_GPR, r)),
205 (i & 4095));
206}
207
208/* Get/set global_State fields. */
209#define emit_getgl(as, r, field) \
210 emit_lsptr(as, ARMI_LDR, (r), (void *)&J2G(as->J)->field)
211#define emit_setgl(as, r, field) \
212 emit_lsptr(as, ARMI_STR, (r), (void *)&J2G(as->J)->field)
213
214/* Trace number is determined from pc of exit instruction. */
215#define emit_setvmstate(as, i) UNUSED(i)
216
217/* -- Emit control-flow instructions -------------------------------------- */
218
219/* Label for internal jumps. */
220typedef MCode *MCLabel;
221
222/* Return label pointing to current PC. */
223#define emit_label(as) ((as)->mcp)
224
225static void emit_branch(ASMState *as, ARMIns ai, MCode *target)
226{
227 MCode *p = as->mcp;
228 ptrdiff_t delta = (target - p) - 1;
229 lua_assert(((delta + 0x00800000) >> 24) == 0);
230 *--p = ai | ((uint32_t)delta & 0x00ffffffu);
231 as->mcp = p;
232}
233
234static void emit_call(ASMState *as, void *target)
235{
236 MCode *p = --as->mcp;
237 ptrdiff_t delta = ((char *)target - (char *)p) - 8;
238 if ((((delta>>2) + 0x00800000) >> 24) == 0) {
239 if ((delta & 1))
240 *p = ARMI_BLX | ((uint32_t)(delta>>2) & 0x00ffffffu) | ((delta&2) << 27);
241 else
242 *p = ARMI_BL | ((uint32_t)(delta>>2) & 0x00ffffffu);
243 } else { /* Target out of range: need indirect call. But don't use R0-R3. */
244 Reg r = ra_allock(as, i32ptr(target), RSET_RANGE(RID_R4, RID_R12+1));
245 *p = ARMI_BLXr | ARMF_M(r);
246 }
247}
248
249/* -- Emit generic operations --------------------------------------------- */
250
251/* Generic move between two regs. */
252static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
253{
254 lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
255 if (as->mcp != as->mcloop) { /* Swap early registers for loads/stores. */
256 MCode ins = *as->mcp, swp = (src^dst);
257 if ((ins & 0x0c000000) == 0x04000000 && (ins & 0x02000010) != 0x02000010) {
258 if (!((ins ^ (dst << 16)) & 0x000f0000))
259 *as->mcp = ins ^ (swp << 16); /* Swap N in load/store. */
260 if (!(ins & 0x00100000) && !((ins ^ (dst << 12)) & 0x0000f000))
261 *as->mcp = ins ^ (swp << 12); /* Swap D in store. */
262 }
263 }
264 emit_dm(as, ARMI_MOV, dst, src);
265}
266
267/* Generic load of register from stack slot. */
268static void emit_spload(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
269{
270 lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
271 emit_lso(as, ARMI_LDR, r, RID_SP, ofs);
272}
273
274/* Generic store of register to stack slot. */
275static void emit_spstore(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
276{
277 lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
278 emit_lso(as, ARMI_STR, r, RID_SP, ofs);
279}
280
281/* Emit an arithmetic/logic operation with a constant operand. */
282static void emit_opk(ASMState *as, ARMIns ai, Reg dest, Reg src,
283 int32_t i, RegSet allow)
284{
285 uint32_t k = emit_isk12(ai, i);
286 if (k)
287 emit_dn(as, ai^k, dest, src);
288 else
289 emit_dnm(as, ai, dest, src, ra_allock(as, i, allow));
290}
291
292/* Add offset to pointer. */
293static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
294{
295 if (ofs)
296 emit_opk(as, ARMI_ADD, r, r, ofs, rset_exclude(RSET_GPR, r));
297}
298
299#define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs))
300
diff --git a/libraries/luajit-2.0/src/lj_emit_ppc.h b/libraries/luajit-2.0/src/lj_emit_ppc.h
new file mode 100644
index 0000000..e44221c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_emit_ppc.h
@@ -0,0 +1,232 @@
1/*
2** PPC instruction emitter.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* -- Emit basic instructions --------------------------------------------- */
7
8static void emit_tab(ASMState *as, PPCIns pi, Reg rt, Reg ra, Reg rb)
9{
10 *--as->mcp = pi | PPCF_T(rt) | PPCF_A(ra) | PPCF_B(rb);
11}
12
13#define emit_asb(as, pi, ra, rs, rb) emit_tab(as, (pi), (rs), (ra), (rb))
14#define emit_as(as, pi, ra, rs) emit_tab(as, (pi), (rs), (ra), 0)
15#define emit_ab(as, pi, ra, rb) emit_tab(as, (pi), 0, (ra), (rb))
16
17static void emit_tai(ASMState *as, PPCIns pi, Reg rt, Reg ra, int32_t i)
18{
19 *--as->mcp = pi | PPCF_T(rt) | PPCF_A(ra) | (i & 0xffff);
20}
21
22#define emit_ti(as, pi, rt, i) emit_tai(as, (pi), (rt), 0, (i))
23#define emit_ai(as, pi, ra, i) emit_tai(as, (pi), 0, (ra), (i))
24#define emit_asi(as, pi, ra, rs, i) emit_tai(as, (pi), (rs), (ra), (i))
25
26#define emit_fab(as, pi, rf, ra, rb) \
27 emit_tab(as, (pi), (rf)&31, (ra)&31, (rb)&31)
28#define emit_fb(as, pi, rf, rb) emit_tab(as, (pi), (rf)&31, 0, (rb)&31)
29#define emit_fac(as, pi, rf, ra, rc) \
30 emit_tab(as, (pi) | PPCF_C((rc) & 31), (rf)&31, (ra)&31, 0)
31#define emit_facb(as, pi, rf, ra, rc, rb) \
32 emit_tab(as, (pi) | PPCF_C((rc) & 31), (rf)&31, (ra)&31, (rb)&31)
33#define emit_fai(as, pi, rf, ra, i) emit_tai(as, (pi), (rf)&31, (ra), (i))
34
35static void emit_rot(ASMState *as, PPCIns pi, Reg ra, Reg rs,
36 int32_t n, int32_t b, int32_t e)
37{
38 *--as->mcp = pi | PPCF_T(rs) | PPCF_A(ra) | PPCF_B(n) |
39 PPCF_MB(b) | PPCF_ME(e);
40}
41
42static void emit_slwi(ASMState *as, Reg ra, Reg rs, int32_t n)
43{
44 lua_assert(n >= 0 && n < 32);
45 emit_rot(as, PPCI_RLWINM, ra, rs, n, 0, 31-n);
46}
47
48static void emit_rotlwi(ASMState *as, Reg ra, Reg rs, int32_t n)
49{
50 lua_assert(n >= 0 && n < 32);
51 emit_rot(as, PPCI_RLWINM, ra, rs, n, 0, 31);
52}
53
54/* -- Emit loads/stores --------------------------------------------------- */
55
56/* Prefer rematerialization of BASE/L from global_State over spills. */
57#define emit_canremat(ref) ((ref) <= REF_BASE)
58
59/* Try to find a one step delta relative to another constant. */
60static int emit_kdelta1(ASMState *as, Reg t, int32_t i)
61{
62 RegSet work = ~as->freeset & RSET_GPR;
63 while (work) {
64 Reg r = rset_picktop(work);
65 IRRef ref = regcost_ref(as->cost[r]);
66 lua_assert(r != t);
67 if (ref < ASMREF_L) {
68 int32_t delta = i - (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i);
69 if (checki16(delta)) {
70 emit_tai(as, PPCI_ADDI, t, r, delta);
71 return 1;
72 }
73 }
74 rset_clear(work, r);
75 }
76 return 0; /* Failed. */
77}
78
79/* Load a 32 bit constant into a GPR. */
80static void emit_loadi(ASMState *as, Reg r, int32_t i)
81{
82 if (checki16(i)) {
83 emit_ti(as, PPCI_LI, r, i);
84 } else {
85 if ((i & 0xffff)) {
86 int32_t jgl = i32ptr(J2G(as->J));
87 if ((uint32_t)(i-jgl) < 65536) {
88 emit_tai(as, PPCI_ADDI, r, RID_JGL, i-jgl-32768);
89 return;
90 } else if (emit_kdelta1(as, r, i)) {
91 return;
92 }
93 emit_asi(as, PPCI_ORI, r, r, i);
94 }
95 emit_ti(as, PPCI_LIS, r, (i >> 16));
96 }
97}
98
99#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
100
101static Reg ra_allock(ASMState *as, int32_t k, RegSet allow);
102
103/* Get/set from constant pointer. */
104static void emit_lsptr(ASMState *as, PPCIns pi, Reg r, void *p, RegSet allow)
105{
106 int32_t jgl = i32ptr(J2G(as->J));
107 int32_t i = i32ptr(p);
108 Reg base;
109 if ((uint32_t)(i-jgl) < 65536) {
110 i = i-jgl-32768;
111 base = RID_JGL;
112 } else {
113 base = ra_allock(as, i-(int16_t)i, allow);
114 }
115 emit_tai(as, pi, r, base, i);
116}
117
118#define emit_loadn(as, r, tv) \
119 emit_lsptr(as, PPCI_LFD, ((r) & 31), (void *)(tv), RSET_GPR)
120
121/* Get/set global_State fields. */
122static void emit_lsglptr(ASMState *as, PPCIns pi, Reg r, int32_t ofs)
123{
124 emit_tai(as, pi, r, RID_JGL, ofs-32768);
125}
126
127#define emit_getgl(as, r, field) \
128 emit_lsglptr(as, PPCI_LWZ, (r), (int32_t)offsetof(global_State, field))
129#define emit_setgl(as, r, field) \
130 emit_lsglptr(as, PPCI_STW, (r), (int32_t)offsetof(global_State, field))
131
132/* Trace number is determined from per-trace exit stubs. */
133#define emit_setvmstate(as, i) UNUSED(i)
134
135/* -- Emit control-flow instructions -------------------------------------- */
136
137/* Label for internal jumps. */
138typedef MCode *MCLabel;
139
140/* Return label pointing to current PC. */
141#define emit_label(as) ((as)->mcp)
142
143static void emit_condbranch(ASMState *as, PPCIns pi, PPCCC cc, MCode *target)
144{
145 MCode *p = as->mcp;
146 ptrdiff_t delta = ((char *)target - (char *)p) + 4;
147 lua_assert(((delta + 0x8000) >> 16) == 0);
148 pi ^= (delta & 0x8000) * (PPCF_Y/0x8000);
149 *--p = pi | PPCF_CC(cc) | ((uint32_t)delta & 0xffffu);
150 as->mcp = p;
151}
152
153static void emit_call(ASMState *as, void *target)
154{
155 MCode *p = --as->mcp;
156 ptrdiff_t delta = (char *)target - (char *)p;
157 if ((((delta>>2) + 0x00800000) >> 24) == 0) {
158 *p = PPCI_BL | (delta & 0x03fffffcu);
159 } else { /* Target out of range: need indirect call. Don't use arg reg. */
160 RegSet allow = RSET_GPR & ~RSET_RANGE(RID_R0, REGARG_LASTGPR+1);
161 Reg r = ra_allock(as, i32ptr(target), allow);
162 *p = PPCI_BCTRL;
163 p[-1] = PPCI_MTCTR | PPCF_T(r);
164 as->mcp = p-1;
165 }
166}
167
168/* -- Emit generic operations --------------------------------------------- */
169
170#define emit_mr(as, dst, src) \
171 emit_asb(as, PPCI_MR, (dst), (src), (src))
172
173/* Generic move between two regs. */
174static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
175{
176 UNUSED(ir);
177 if (dst < RID_MAX_GPR)
178 emit_mr(as, dst, src);
179 else
180 emit_fb(as, PPCI_FMR, dst, src);
181}
182
183/* Generic load of register from stack slot. */
184static void emit_spload(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
185{
186 if (r < RID_MAX_GPR)
187 emit_tai(as, PPCI_LWZ, r, RID_SP, ofs);
188 else
189 emit_fai(as, irt_isnum(ir->t) ? PPCI_LFD : PPCI_LFS, r, RID_SP, ofs);
190}
191
192/* Generic store of register to stack slot. */
193static void emit_spstore(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
194{
195 if (r < RID_MAX_GPR)
196 emit_tai(as, PPCI_STW, r, RID_SP, ofs);
197 else
198 emit_fai(as, irt_isnum(ir->t) ? PPCI_STFD : PPCI_STFS, r, RID_SP, ofs);
199}
200
201/* Emit a compare (for equality) with a constant operand. */
202static void emit_cmpi(ASMState *as, Reg r, int32_t k)
203{
204 if (checki16(k)) {
205 emit_ai(as, PPCI_CMPWI, r, k);
206 } else if (checku16(k)) {
207 emit_ai(as, PPCI_CMPLWI, r, k);
208 } else {
209 emit_ai(as, PPCI_CMPLWI, RID_TMP, k);
210 emit_asi(as, PPCI_XORIS, RID_TMP, r, (k >> 16));
211 }
212}
213
214/* Add offset to pointer. */
215static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
216{
217 if (ofs) {
218 emit_tai(as, PPCI_ADDI, r, r, ofs);
219 if (!checki16(ofs))
220 emit_tai(as, PPCI_ADDIS, r, r, (ofs + 32768) >> 16);
221 }
222}
223
224static void emit_spsub(ASMState *as, int32_t ofs)
225{
226 if (ofs) {
227 emit_tai(as, PPCI_STWU, RID_TMP, RID_SP, -ofs);
228 emit_tai(as, PPCI_ADDI, RID_TMP, RID_SP,
229 CFRAME_SIZE + (as->parent ? as->parent->spadjust : 0));
230 }
231}
232
diff --git a/libraries/luajit-2.0/src/lj_emit_x86.h b/libraries/luajit-2.0/src/lj_emit_x86.h
new file mode 100644
index 0000000..6c06184
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_emit_x86.h
@@ -0,0 +1,457 @@
1/*
2** x86/x64 instruction emitter.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* -- Emit basic instructions --------------------------------------------- */
7
8#define MODRM(mode, r1, r2) ((MCode)((mode)+(((r1)&7)<<3)+((r2)&7)))
9
10#if LJ_64
11#define REXRB(p, rr, rb) \
12 { MCode rex = 0x40 + (((rr)>>1)&4) + (((rb)>>3)&1); \
13 if (rex != 0x40) *--(p) = rex; }
14#define FORCE_REX 0x200
15#define REX_64 (FORCE_REX|0x080000)
16#else
17#define REXRB(p, rr, rb) ((void)0)
18#define FORCE_REX 0
19#define REX_64 0
20#endif
21
22#define emit_i8(as, i) (*--as->mcp = (MCode)(i))
23#define emit_i32(as, i) (*(int32_t *)(as->mcp-4) = (i), as->mcp -= 4)
24#define emit_u32(as, u) (*(uint32_t *)(as->mcp-4) = (u), as->mcp -= 4)
25
26#define emit_x87op(as, xo) \
27 (*(uint16_t *)(as->mcp-2) = (uint16_t)(xo), as->mcp -= 2)
28
29/* op */
30static LJ_AINLINE MCode *emit_op(x86Op xo, Reg rr, Reg rb, Reg rx,
31 MCode *p, int delta)
32{
33 int n = (int8_t)xo;
34#if defined(__GNUC__)
35 if (__builtin_constant_p(xo) && n == -2)
36 p[delta-2] = (MCode)(xo >> 24);
37 else if (__builtin_constant_p(xo) && n == -3)
38 *(uint16_t *)(p+delta-3) = (uint16_t)(xo >> 16);
39 else
40#endif
41 *(uint32_t *)(p+delta-5) = (uint32_t)xo;
42 p += n + delta;
43#if LJ_64
44 {
45 uint32_t rex = 0x40 + ((rr>>1)&(4+(FORCE_REX>>1)))+((rx>>2)&2)+((rb>>3)&1);
46 if (rex != 0x40) {
47 rex |= (rr >> 16);
48 if (n == -4) { *p = (MCode)rex; rex = (MCode)(xo >> 8); }
49 else if ((xo & 0xffffff) == 0x6600fd) { *p = (MCode)rex; rex = 0x66; }
50 *--p = (MCode)rex;
51 }
52 }
53#else
54 UNUSED(rr); UNUSED(rb); UNUSED(rx);
55#endif
56 return p;
57}
58
59/* op + modrm */
60#define emit_opm(xo, mode, rr, rb, p, delta) \
61 (p[(delta)-1] = MODRM((mode), (rr), (rb)), \
62 emit_op((xo), (rr), (rb), 0, (p), (delta)))
63
64/* op + modrm + sib */
65#define emit_opmx(xo, mode, scale, rr, rb, rx, p) \
66 (p[-1] = MODRM((scale), (rx), (rb)), \
67 p[-2] = MODRM((mode), (rr), RID_ESP), \
68 emit_op((xo), (rr), (rb), (rx), (p), -1))
69
70/* op r1, r2 */
71static void emit_rr(ASMState *as, x86Op xo, Reg r1, Reg r2)
72{
73 MCode *p = as->mcp;
74 as->mcp = emit_opm(xo, XM_REG, r1, r2, p, 0);
75}
76
77#if LJ_64 && defined(LUA_USE_ASSERT)
78/* [addr] is sign-extended in x64 and must be in lower 2G (not 4G). */
79static int32_t ptr2addr(const void *p)
80{
81 lua_assert((uintptr_t)p < (uintptr_t)0x80000000);
82 return i32ptr(p);
83}
84#else
85#define ptr2addr(p) (i32ptr((p)))
86#endif
87
88/* op r, [addr] */
89static void emit_rma(ASMState *as, x86Op xo, Reg rr, const void *addr)
90{
91 MCode *p = as->mcp;
92 *(int32_t *)(p-4) = ptr2addr(addr);
93#if LJ_64
94 p[-5] = MODRM(XM_SCALE1, RID_ESP, RID_EBP);
95 as->mcp = emit_opm(xo, XM_OFS0, rr, RID_ESP, p, -5);
96#else
97 as->mcp = emit_opm(xo, XM_OFS0, rr, RID_EBP, p, -4);
98#endif
99}
100
101/* op r, [base+ofs] */
102static void emit_rmro(ASMState *as, x86Op xo, Reg rr, Reg rb, int32_t ofs)
103{
104 MCode *p = as->mcp;
105 x86Mode mode;
106 if (ra_hasreg(rb)) {
107 if (ofs == 0 && (rb&7) != RID_EBP) {
108 mode = XM_OFS0;
109 } else if (checki8(ofs)) {
110 *--p = (MCode)ofs;
111 mode = XM_OFS8;
112 } else {
113 p -= 4;
114 *(int32_t *)p = ofs;
115 mode = XM_OFS32;
116 }
117 if ((rb&7) == RID_ESP)
118 *--p = MODRM(XM_SCALE1, RID_ESP, RID_ESP);
119 } else {
120 *(int32_t *)(p-4) = ofs;
121#if LJ_64
122 p[-5] = MODRM(XM_SCALE1, RID_ESP, RID_EBP);
123 p -= 5;
124 rb = RID_ESP;
125#else
126 p -= 4;
127 rb = RID_EBP;
128#endif
129 mode = XM_OFS0;
130 }
131 as->mcp = emit_opm(xo, mode, rr, rb, p, 0);
132}
133
134/* op r, [base+idx*scale+ofs] */
135static void emit_rmrxo(ASMState *as, x86Op xo, Reg rr, Reg rb, Reg rx,
136 x86Mode scale, int32_t ofs)
137{
138 MCode *p = as->mcp;
139 x86Mode mode;
140 if (ofs == 0 && (rb&7) != RID_EBP) {
141 mode = XM_OFS0;
142 } else if (checki8(ofs)) {
143 mode = XM_OFS8;
144 *--p = (MCode)ofs;
145 } else {
146 mode = XM_OFS32;
147 p -= 4;
148 *(int32_t *)p = ofs;
149 }
150 as->mcp = emit_opmx(xo, mode, scale, rr, rb, rx, p);
151}
152
153/* op r, i */
154static void emit_gri(ASMState *as, x86Group xg, Reg rb, int32_t i)
155{
156 MCode *p = as->mcp;
157 x86Op xo;
158 if (checki8(i)) {
159 *--p = (MCode)i;
160 xo = XG_TOXOi8(xg);
161 } else {
162 p -= 4;
163 *(int32_t *)p = i;
164 xo = XG_TOXOi(xg);
165 }
166 as->mcp = emit_opm(xo, XM_REG, (Reg)(xg & 7) | (rb & REX_64), rb, p, 0);
167}
168
169/* op [base+ofs], i */
170static void emit_gmroi(ASMState *as, x86Group xg, Reg rb, int32_t ofs,
171 int32_t i)
172{
173 x86Op xo;
174 if (checki8(i)) {
175 emit_i8(as, i);
176 xo = XG_TOXOi8(xg);
177 } else {
178 emit_i32(as, i);
179 xo = XG_TOXOi(xg);
180 }
181 emit_rmro(as, xo, (Reg)(xg & 7), rb, ofs);
182}
183
184#define emit_shifti(as, xg, r, i) \
185 (emit_i8(as, (i)), emit_rr(as, XO_SHIFTi, (Reg)(xg), (r)))
186
187/* op r, rm/mrm */
188static void emit_mrm(ASMState *as, x86Op xo, Reg rr, Reg rb)
189{
190 MCode *p = as->mcp;
191 x86Mode mode = XM_REG;
192 if (rb == RID_MRM) {
193 rb = as->mrm.base;
194 if (rb == RID_NONE) {
195 rb = RID_EBP;
196 mode = XM_OFS0;
197 p -= 4;
198 *(int32_t *)p = as->mrm.ofs;
199 if (as->mrm.idx != RID_NONE)
200 goto mrmidx;
201#if LJ_64
202 *--p = MODRM(XM_SCALE1, RID_ESP, RID_EBP);
203 rb = RID_ESP;
204#endif
205 } else {
206 if (as->mrm.ofs == 0 && (rb&7) != RID_EBP) {
207 mode = XM_OFS0;
208 } else if (checki8(as->mrm.ofs)) {
209 *--p = (MCode)as->mrm.ofs;
210 mode = XM_OFS8;
211 } else {
212 p -= 4;
213 *(int32_t *)p = as->mrm.ofs;
214 mode = XM_OFS32;
215 }
216 if (as->mrm.idx != RID_NONE) {
217 mrmidx:
218 as->mcp = emit_opmx(xo, mode, as->mrm.scale, rr, rb, as->mrm.idx, p);
219 return;
220 }
221 if ((rb&7) == RID_ESP)
222 *--p = MODRM(XM_SCALE1, RID_ESP, RID_ESP);
223 }
224 }
225 as->mcp = emit_opm(xo, mode, rr, rb, p, 0);
226}
227
228/* op rm/mrm, i */
229static void emit_gmrmi(ASMState *as, x86Group xg, Reg rb, int32_t i)
230{
231 x86Op xo;
232 if (checki8(i)) {
233 emit_i8(as, i);
234 xo = XG_TOXOi8(xg);
235 } else {
236 emit_i32(as, i);
237 xo = XG_TOXOi(xg);
238 }
239 emit_mrm(as, xo, (Reg)(xg & 7) | (rb & REX_64), (rb & ~REX_64));
240}
241
242/* -- Emit loads/stores --------------------------------------------------- */
243
244/* Instruction selection for XMM moves. */
245#define XMM_MOVRR(as) ((as->flags & JIT_F_SPLIT_XMM) ? XO_MOVSD : XO_MOVAPS)
246#define XMM_MOVRM(as) ((as->flags & JIT_F_SPLIT_XMM) ? XO_MOVLPD : XO_MOVSD)
247
248/* mov [base+ofs], i */
249static void emit_movmroi(ASMState *as, Reg base, int32_t ofs, int32_t i)
250{
251 emit_i32(as, i);
252 emit_rmro(as, XO_MOVmi, 0, base, ofs);
253}
254
255/* mov [base+ofs], r */
256#define emit_movtomro(as, r, base, ofs) \
257 emit_rmro(as, XO_MOVto, (r), (base), (ofs))
258
259/* Get/set global_State fields. */
260#define emit_opgl(as, xo, r, field) \
261 emit_rma(as, (xo), (r), (void *)&J2G(as->J)->field)
262#define emit_getgl(as, r, field) emit_opgl(as, XO_MOV, (r), field)
263#define emit_setgl(as, r, field) emit_opgl(as, XO_MOVto, (r), field)
264
265#define emit_setvmstate(as, i) \
266 (emit_i32(as, i), emit_opgl(as, XO_MOVmi, 0, vmstate))
267
268/* mov r, i / xor r, r */
269static void emit_loadi(ASMState *as, Reg r, int32_t i)
270{
271 /* XOR r,r is shorter, but modifies the flags. This is bad for HIOP. */
272 if (i == 0 && !(LJ_32 && (IR(as->curins)->o == IR_HIOP ||
273 (as->curins+1 < as->T->nins &&
274 IR(as->curins+1)->o == IR_HIOP)))) {
275 emit_rr(as, XO_ARITH(XOg_XOR), r, r);
276 } else {
277 MCode *p = as->mcp;
278 *(int32_t *)(p-4) = i;
279 p[-5] = (MCode)(XI_MOVri+(r&7));
280 p -= 5;
281 REXRB(p, 0, r);
282 as->mcp = p;
283 }
284}
285
286/* mov r, addr */
287#define emit_loada(as, r, addr) \
288 emit_loadi(as, (r), ptr2addr((addr)))
289
290#if LJ_64
291/* mov r, imm64 or shorter 32 bit extended load. */
292static void emit_loadu64(ASMState *as, Reg r, uint64_t u64)
293{
294 if (checku32(u64)) { /* 32 bit load clears upper 32 bits. */
295 emit_loadi(as, r, (int32_t)u64);
296 } else if (checki32((int64_t)u64)) { /* Sign-extended 32 bit load. */
297 MCode *p = as->mcp;
298 *(int32_t *)(p-4) = (int32_t)u64;
299 as->mcp = emit_opm(XO_MOVmi, XM_REG, REX_64, r, p, -4);
300 } else { /* Full-size 64 bit load. */
301 MCode *p = as->mcp;
302 *(uint64_t *)(p-8) = u64;
303 p[-9] = (MCode)(XI_MOVri+(r&7));
304 p[-10] = 0x48 + ((r>>3)&1);
305 p -= 10;
306 as->mcp = p;
307 }
308}
309#endif
310
311/* movsd r, [&tv->n] / xorps r, r */
312static void emit_loadn(ASMState *as, Reg r, cTValue *tv)
313{
314 if (tvispzero(tv)) /* Use xor only for +0. */
315 emit_rr(as, XO_XORPS, r, r);
316 else
317 emit_rma(as, XMM_MOVRM(as), r, &tv->n);
318}
319
320/* -- Emit control-flow instructions -------------------------------------- */
321
322/* Label for short jumps. */
323typedef MCode *MCLabel;
324
325#if LJ_32 && LJ_HASFFI
326/* jmp short target */
327static void emit_sjmp(ASMState *as, MCLabel target)
328{
329 MCode *p = as->mcp;
330 ptrdiff_t delta = target - p;
331 lua_assert(delta == (int8_t)delta);
332 p[-1] = (MCode)(int8_t)delta;
333 p[-2] = XI_JMPs;
334 as->mcp = p - 2;
335}
336#endif
337
338/* jcc short target */
339static void emit_sjcc(ASMState *as, int cc, MCLabel target)
340{
341 MCode *p = as->mcp;
342 ptrdiff_t delta = target - p;
343 lua_assert(delta == (int8_t)delta);
344 p[-1] = (MCode)(int8_t)delta;
345 p[-2] = (MCode)(XI_JCCs+(cc&15));
346 as->mcp = p - 2;
347}
348
349/* jcc short (pending target) */
350static MCLabel emit_sjcc_label(ASMState *as, int cc)
351{
352 MCode *p = as->mcp;
353 p[-1] = 0;
354 p[-2] = (MCode)(XI_JCCs+(cc&15));
355 as->mcp = p - 2;
356 return p;
357}
358
359/* Fixup jcc short target. */
360static void emit_sfixup(ASMState *as, MCLabel source)
361{
362 source[-1] = (MCode)(as->mcp-source);
363}
364
365/* Return label pointing to current PC. */
366#define emit_label(as) ((as)->mcp)
367
368/* Compute relative 32 bit offset for jump and call instructions. */
369static LJ_AINLINE int32_t jmprel(MCode *p, MCode *target)
370{
371 ptrdiff_t delta = target - p;
372 lua_assert(delta == (int32_t)delta);
373 return (int32_t)delta;
374}
375
376/* jcc target */
377static void emit_jcc(ASMState *as, int cc, MCode *target)
378{
379 MCode *p = as->mcp;
380 *(int32_t *)(p-4) = jmprel(p, target);
381 p[-5] = (MCode)(XI_JCCn+(cc&15));
382 p[-6] = 0x0f;
383 as->mcp = p - 6;
384}
385
386/* call target */
387static void emit_call_(ASMState *as, MCode *target)
388{
389 MCode *p = as->mcp;
390#if LJ_64
391 if (target-p != (int32_t)(target-p)) {
392 /* Assumes RID_RET is never an argument to calls and always clobbered. */
393 emit_rr(as, XO_GROUP5, XOg_CALL, RID_RET);
394 emit_loadu64(as, RID_RET, (uint64_t)target);
395 return;
396 }
397#endif
398 *(int32_t *)(p-4) = jmprel(p, target);
399 p[-5] = XI_CALL;
400 as->mcp = p - 5;
401}
402
403#define emit_call(as, f) emit_call_(as, (MCode *)(void *)(f))
404
405/* -- Emit generic operations --------------------------------------------- */
406
407/* Use 64 bit operations to handle 64 bit IR types. */
408#if LJ_64
409#define REX_64IR(ir, r) ((r) + (irt_is64((ir)->t) ? REX_64 : 0))
410#else
411#define REX_64IR(ir, r) (r)
412#endif
413
414/* Generic move between two regs. */
415static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
416{
417 UNUSED(ir);
418 if (dst < RID_MAX_GPR)
419 emit_rr(as, XO_MOV, REX_64IR(ir, dst), src);
420 else
421 emit_rr(as, XMM_MOVRR(as), dst, src);
422}
423
424/* Generic load of register from stack slot. */
425static void emit_spload(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
426{
427 if (r < RID_MAX_GPR)
428 emit_rmro(as, XO_MOV, REX_64IR(ir, r), RID_ESP, ofs);
429 else
430 emit_rmro(as, irt_isnum(ir->t) ? XMM_MOVRM(as) : XO_MOVSS, r, RID_ESP, ofs);
431}
432
433/* Generic store of register to stack slot. */
434static void emit_spstore(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
435{
436 if (r < RID_MAX_GPR)
437 emit_rmro(as, XO_MOVto, REX_64IR(ir, r), RID_ESP, ofs);
438 else
439 emit_rmro(as, irt_isnum(ir->t) ? XO_MOVSDto : XO_MOVSSto, r, RID_ESP, ofs);
440}
441
442/* Add offset to pointer. */
443static void emit_addptr(ASMState *as, Reg r, int32_t ofs)
444{
445 if (ofs) {
446 if ((as->flags & JIT_F_LEA_AGU))
447 emit_rmro(as, XO_LEA, r, r, ofs);
448 else
449 emit_gri(as, XG_ARITHi(XOg_ADD), r, ofs);
450 }
451}
452
453#define emit_spsub(as, ofs) emit_addptr(as, RID_ESP|REX_64, -(ofs))
454
455/* Prefer rematerialization of BASE/L from global_State over spills. */
456#define emit_canremat(ref) ((ref) <= REF_BASE)
457
diff --git a/libraries/luajit-2.0/src/lj_err.c b/libraries/luajit-2.0/src/lj_err.c
new file mode 100644
index 0000000..b0f3e5c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_err.c
@@ -0,0 +1,736 @@
1/*
2** Error handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_err_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#include "lj_err.h"
11#include "lj_debug.h"
12#include "lj_str.h"
13#include "lj_func.h"
14#include "lj_state.h"
15#include "lj_frame.h"
16#include "lj_ff.h"
17#include "lj_trace.h"
18#include "lj_vm.h"
19
20/*
21** LuaJIT can either use internal or external frame unwinding:
22**
23** - Internal frame unwinding (INT) is free-standing and doesn't require
24** any OS or library support.
25**
26** - External frame unwinding (EXT) uses the system-provided unwind handler.
27**
28** Pros and Cons:
29**
30** - EXT requires unwind tables for *all* functions on the C stack between
31** the pcall/catch and the error/throw. This is the default on x64,
32** but needs to be manually enabled on x86/PPC for non-C++ code.
33**
34** - INT is faster when actually throwing errors (but this happens rarely).
35** Setting up error handlers is zero-cost in any case.
36**
37** - EXT provides full interoperability with C++ exceptions. You can throw
38** Lua errors or C++ exceptions through a mix of Lua frames and C++ frames.
39** C++ destructors are called as needed. C++ exceptions caught by pcall
40** are converted to the string "C++ exception". Lua errors can be caught
41** with catch (...) in C++.
42**
43** - INT has only limited support for automatically catching C++ exceptions
44** on POSIX systems using DWARF2 stack unwinding. Other systems may use
45** the wrapper function feature. Lua errors thrown through C++ frames
46** cannot be caught by C++ code and C++ destructors are not run.
47**
48** EXT is the default on x64 systems, INT is the default on all other systems.
49**
50** EXT can be manually enabled on POSIX systems using GCC and DWARF2 stack
51** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled
52** with -funwind-tables (or -fexceptions). This includes LuaJIT itself (set
53** TARGET_CFLAGS), all of your C/Lua binding code, all loadable C modules
54** and all C libraries that have callbacks which may be used to call back
55** into Lua. C++ code must *not* be compiled with -fno-exceptions.
56**
57** EXT cannot be enabled on WIN32 since system exceptions use code-driven SEH.
58** EXT is mandatory on WIN64 since the calling convention has an abundance
59** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15).
60** EXT is mandatory on POSIX/x64 since the interpreter doesn't save r12/r13.
61*/
62
63#if defined(__GNUC__) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL))
64#define LJ_UNWIND_EXT 1
65#elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS
66#define LJ_UNWIND_EXT 1
67#endif
68
69/* -- Error messages ------------------------------------------------------ */
70
71/* Error message strings. */
72LJ_DATADEF const char *lj_err_allmsg =
73#define ERRDEF(name, msg) msg "\0"
74#include "lj_errmsg.h"
75;
76
77/* -- Internal frame unwinding -------------------------------------------- */
78
79/* Unwind Lua stack and move error message to new top. */
80LJ_NOINLINE static void unwindstack(lua_State *L, TValue *top)
81{
82 lj_func_closeuv(L, top);
83 if (top < L->top-1) {
84 copyTV(L, top, L->top-1);
85 L->top = top+1;
86 }
87 lj_state_relimitstack(L);
88}
89
90/* Unwind until stop frame. Optionally cleanup frames. */
91static void *err_unwind(lua_State *L, void *stopcf, int errcode)
92{
93 TValue *frame = L->base-1;
94 void *cf = L->cframe;
95 while (cf) {
96 int32_t nres = cframe_nres(cframe_raw(cf));
97 if (nres < 0) { /* C frame without Lua frame? */
98 TValue *top = restorestack(L, -nres);
99 if (frame < top) { /* Frame reached? */
100 if (errcode) {
101 L->cframe = cframe_prev(cf);
102 L->base = frame+1;
103 unwindstack(L, top);
104 }
105 return cf;
106 }
107 }
108 if (frame <= tvref(L->stack))
109 break;
110 switch (frame_typep(frame)) {
111 case FRAME_LUA: /* Lua frame. */
112 case FRAME_LUAP:
113 frame = frame_prevl(frame);
114 break;
115 case FRAME_C: /* C frame. */
116#if LJ_HASFFI
117 unwind_c:
118#endif
119#if LJ_UNWIND_EXT
120 if (errcode) {
121 L->cframe = cframe_prev(cf);
122 L->base = frame_prevd(frame) + 1;
123 unwindstack(L, frame);
124 } else if (cf != stopcf) {
125 cf = cframe_prev(cf);
126 frame = frame_prevd(frame);
127 break;
128 }
129 return NULL; /* Continue unwinding. */
130#else
131 UNUSED(stopcf);
132 cf = cframe_prev(cf);
133 frame = frame_prevd(frame);
134 break;
135#endif
136 case FRAME_CP: /* Protected C frame. */
137 if (cframe_canyield(cf)) { /* Resume? */
138 if (errcode) {
139 L->cframe = NULL;
140 L->status = (uint8_t)errcode;
141 }
142 return cf;
143 }
144 if (errcode) {
145 L->cframe = cframe_prev(cf);
146 L->base = frame_prevd(frame) + 1;
147 unwindstack(L, frame);
148 }
149 return cf;
150 case FRAME_CONT: /* Continuation frame. */
151#if LJ_HASFFI
152 if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK)
153 goto unwind_c;
154#endif
155 case FRAME_VARG: /* Vararg frame. */
156 frame = frame_prevd(frame);
157 break;
158 case FRAME_PCALL: /* FF pcall() frame. */
159 case FRAME_PCALLH: /* FF pcall() frame inside hook. */
160 if (errcode) {
161 if (errcode == LUA_YIELD) {
162 frame = frame_prevd(frame);
163 break;
164 }
165 if (frame_typep(frame) == FRAME_PCALL)
166 hook_leave(G(L));
167 L->cframe = cf;
168 L->base = frame_prevd(frame) + 1;
169 unwindstack(L, L->base);
170 }
171 return (void *)((intptr_t)cf | CFRAME_UNWIND_FF);
172 }
173 }
174 /* No C frame. */
175 if (errcode) {
176 L->cframe = NULL;
177 L->base = tvref(L->stack)+1;
178 unwindstack(L, L->base);
179 if (G(L)->panic)
180 G(L)->panic(L);
181 exit(EXIT_FAILURE);
182 }
183 return L; /* Anything non-NULL will do. */
184}
185
186/* -- External frame unwinding -------------------------------------------- */
187
188#if defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND)
189
190#ifdef __clang__
191/* http://llvm.org/bugs/show_bug.cgi?id=8703 */
192#define __unwind_word__ word
193#endif
194
195#include <unwind.h>
196
197#if !LJ_TARGET_ARM
198
199#define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */
200#define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c))
201#define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff)
202#define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff))
203
204/* DWARF2 personality handler referenced from interpreter .eh_frame. */
205LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions,
206 uint64_t uexclass, struct _Unwind_Exception *uex,
207 struct _Unwind_Context *ctx)
208{
209 void *cf;
210 lua_State *L;
211 if (version != 1)
212 return _URC_FATAL_PHASE1_ERROR;
213 UNUSED(uexclass);
214 cf = (void *)_Unwind_GetCFA(ctx);
215 L = cframe_L(cf);
216 if ((actions & _UA_SEARCH_PHASE)) {
217#if LJ_UNWIND_EXT
218 if (err_unwind(L, cf, 0) == NULL)
219 return _URC_CONTINUE_UNWIND;
220#endif
221 if (!LJ_UEXCLASS_CHECK(uexclass)) {
222 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP));
223 }
224 return _URC_HANDLER_FOUND;
225 }
226 if ((actions & _UA_CLEANUP_PHASE)) {
227 int errcode;
228 if (LJ_UEXCLASS_CHECK(uexclass)) {
229 errcode = LJ_UEXCLASS_ERRCODE(uexclass);
230 } else {
231 if ((actions & _UA_HANDLER_FRAME))
232 _Unwind_DeleteException(uex);
233 errcode = LUA_ERRRUN;
234 }
235#if LJ_UNWIND_EXT
236 cf = err_unwind(L, cf, errcode);
237 if ((actions & _UA_FORCE_UNWIND)) {
238 return _URC_CONTINUE_UNWIND;
239 } else if (cf) {
240 _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode);
241 _Unwind_SetIP(ctx, (uintptr_t)(cframe_unwind_ff(cf) ?
242 lj_vm_unwind_ff_eh :
243 lj_vm_unwind_c_eh));
244 return _URC_INSTALL_CONTEXT;
245 }
246#if LJ_TARGET_X86ORX64
247 else if ((actions & _UA_HANDLER_FRAME)) {
248 /* Workaround for ancient libgcc bug. Still present in RHEL 5.5. :-/
249 ** Real fix: http://gcc.gnu.org/viewcvs/trunk/gcc/unwind-dw2.c?r1=121165&r2=124837&pathrev=153877&diff_format=h
250 */
251 _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode);
252 _Unwind_SetIP(ctx, (uintptr_t)lj_vm_unwind_rethrow);
253 return _URC_INSTALL_CONTEXT;
254 }
255#endif
256#else
257 /* This is not the proper way to escape from the unwinder. We get away with
258 ** it on x86/PPC because the interpreter restores all callee-saved regs.
259 */
260 lj_err_throw(L, errcode);
261#endif
262 }
263 return _URC_CONTINUE_UNWIND;
264}
265
266#if LJ_UNWIND_EXT
267#if LJ_TARGET_OSX
268/* Sorry, no thread safety for OSX. Complain to Apple, not me. */
269static struct _Unwind_Exception static_uex;
270#else
271static __thread struct _Unwind_Exception static_uex;
272#endif
273
274/* Raise DWARF2 exception. */
275static void err_raise_ext(int errcode)
276{
277 static_uex.exception_class = LJ_UEXCLASS_MAKE(errcode);
278 static_uex.exception_cleanup = NULL;
279 _Unwind_RaiseException(&static_uex);
280}
281#endif
282
283#else
284
285/* ARM unwinder personality handler referenced from interpreter .ARM.extab. */
286LJ_FUNCA _Unwind_Reason_Code lj_err_unwind_arm(_Unwind_State state,
287 _Unwind_Control_Block *ucb,
288 _Unwind_Context *ctx)
289{
290 void *cf = (void *)_Unwind_GetGR(ctx, 13);
291 lua_State *L = cframe_L(cf);
292 if ((state & _US_ACTION_MASK) == _US_VIRTUAL_UNWIND_FRAME) {
293 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP));
294 return _URC_HANDLER_FOUND;
295 }
296 if ((state&(_US_ACTION_MASK|_US_FORCE_UNWIND)) == _US_UNWIND_FRAME_STARTING) {
297 _Unwind_DeleteException(ucb);
298 _Unwind_SetGR(ctx, 15, (_Unwind_Word)(void *)lj_err_throw);
299 _Unwind_SetGR(ctx, 0, (_Unwind_Word)L);
300 _Unwind_SetGR(ctx, 1, (_Unwind_Word)LUA_ERRRUN);
301 return _URC_INSTALL_CONTEXT;
302 }
303 if (__gnu_unwind_frame(ucb, ctx) != _URC_OK)
304 return _URC_FAILURE;
305 return _URC_CONTINUE_UNWIND;
306}
307
308#endif
309
310#elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS
311
312/*
313** Someone in Redmond owes me several days of my life. A lot of this is
314** undocumented or just plain wrong on MSDN. Some of it can be gathered
315** from 3rd party docs or must be found by trial-and-error. They really
316** don't want you to write your own language-specific exception handler
317** or to interact gracefully with MSVC. :-(
318**
319** Apparently MSVC doesn't call C++ destructors for foreign exceptions
320** unless you compile your C++ code with /EHa. Unfortunately this means
321** catch (...) also catches things like access violations. The use of
322** _set_se_translator doesn't really help, because it requires /EHa, too.
323*/
324
325#define WIN32_LEAN_AND_MEAN
326#include <windows.h>
327
328/* Taken from: http://www.nynaeve.net/?p=99 */
329typedef struct UndocumentedDispatcherContext {
330 ULONG64 ControlPc;
331 ULONG64 ImageBase;
332 PRUNTIME_FUNCTION FunctionEntry;
333 ULONG64 EstablisherFrame;
334 ULONG64 TargetIp;
335 PCONTEXT ContextRecord;
336 PEXCEPTION_ROUTINE LanguageHandler;
337 PVOID HandlerData;
338 PUNWIND_HISTORY_TABLE HistoryTable;
339 ULONG ScopeIndex;
340 ULONG Fill0;
341} UndocumentedDispatcherContext;
342
343#ifdef _MSC_VER
344/* Another wild guess. */
345extern __DestructExceptionObject(EXCEPTION_RECORD *rec, int nothrow);
346#endif
347
348#define LJ_MSVC_EXCODE ((DWORD)0xe06d7363)
349
350#define LJ_EXCODE ((DWORD)0xe24c4a00)
351#define LJ_EXCODE_MAKE(c) (LJ_EXCODE | (DWORD)(c))
352#define LJ_EXCODE_CHECK(cl) (((cl) ^ LJ_EXCODE) <= 0xff)
353#define LJ_EXCODE_ERRCODE(cl) ((int)((cl) & 0xff))
354
355/* Win64 exception handler for interpreter frame. */
356LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec,
357 void *cf, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch)
358{
359 lua_State *L = cframe_L(cf);
360 int errcode = LJ_EXCODE_CHECK(rec->ExceptionCode) ?
361 LJ_EXCODE_ERRCODE(rec->ExceptionCode) : LUA_ERRRUN;
362 if ((rec->ExceptionFlags & 6)) { /* EH_UNWINDING|EH_EXIT_UNWIND */
363 /* Unwind internal frames. */
364 err_unwind(L, cf, errcode);
365 } else {
366 void *cf2 = err_unwind(L, cf, 0);
367 if (cf2) { /* We catch it, so start unwinding the upper frames. */
368 if (rec->ExceptionCode == LJ_MSVC_EXCODE) {
369#ifdef _MSC_VER
370 __DestructExceptionObject(rec, 1);
371#endif
372 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP));
373 } else if (!LJ_EXCODE_CHECK(rec->ExceptionCode)) {
374 /* Don't catch access violations etc. */
375 return ExceptionContinueSearch;
376 }
377 /* Unwind the stack and call all handlers for all lower C frames
378 ** (including ourselves) again with EH_UNWINDING set. Then set
379 ** rsp = cf, rax = errcode and jump to the specified target.
380 */
381 RtlUnwindEx(cf, (void *)((cframe_unwind_ff(cf2) && errcode != LUA_YIELD) ?
382 lj_vm_unwind_ff_eh :
383 lj_vm_unwind_c_eh),
384 rec, (void *)errcode, ctx, dispatch->HistoryTable);
385 /* RtlUnwindEx should never return. */
386 }
387 }
388 return ExceptionContinueSearch;
389}
390
391/* Raise Windows exception. */
392static void err_raise_ext(int errcode)
393{
394 RaiseException(LJ_EXCODE_MAKE(errcode), 1 /* EH_NONCONTINUABLE */, 0, NULL);
395}
396
397#endif
398
399/* -- Error handling ------------------------------------------------------ */
400
401/* Throw error. Find catch frame, unwind stack and continue. */
402LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode)
403{
404 global_State *g = G(L);
405 lj_trace_abort(g);
406 setgcrefnull(g->jit_L);
407 L->status = 0;
408#if LJ_UNWIND_EXT
409 err_raise_ext(errcode);
410 /*
411 ** A return from this function signals a corrupt C stack that cannot be
412 ** unwound. We have no choice but to call the panic function and exit.
413 **
414 ** Usually this is caused by a C function without unwind information.
415 ** This should never happen on x64, but may happen if you've manually
416 ** enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every*
417 ** non-C++ file with -funwind-tables.
418 */
419 if (G(L)->panic)
420 G(L)->panic(L);
421#else
422 {
423 void *cf = err_unwind(L, NULL, errcode);
424 if (cframe_unwind_ff(cf))
425 lj_vm_unwind_ff(cframe_raw(cf));
426 else
427 lj_vm_unwind_c(cframe_raw(cf), errcode);
428 }
429#endif
430 exit(EXIT_FAILURE);
431}
432
433/* Return string object for error message. */
434LJ_NOINLINE GCstr *lj_err_str(lua_State *L, ErrMsg em)
435{
436 return lj_str_newz(L, err2msg(em));
437}
438
439/* Out-of-memory error. */
440LJ_NOINLINE void lj_err_mem(lua_State *L)
441{
442 if (L->status == LUA_ERRERR+1) /* Don't touch the stack during lua_open. */
443 lj_vm_unwind_c(L->cframe, LUA_ERRMEM);
444 L->top = L->base;
445 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM));
446 lj_err_throw(L, LUA_ERRMEM);
447}
448
449/* Find error function for runtime errors. Requires an extra stack traversal. */
450static ptrdiff_t finderrfunc(lua_State *L)
451{
452 cTValue *frame = L->base-1, *bot = tvref(L->stack);
453 void *cf = L->cframe;
454 while (frame > bot) {
455 lua_assert(cf != NULL);
456 while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */
457 if (frame >= restorestack(L, -cframe_nres(cf)))
458 break;
459 if (cframe_errfunc(cf) >= 0) /* Error handler not inherited (-1)? */
460 return cframe_errfunc(cf);
461 cf = cframe_prev(cf); /* Else unwind cframe and continue searching. */
462 if (cf == NULL)
463 return 0;
464 }
465 switch (frame_typep(frame)) {
466 case FRAME_LUA:
467 case FRAME_LUAP:
468 frame = frame_prevl(frame);
469 break;
470 case FRAME_C:
471 cf = cframe_prev(cf);
472 /* fallthrough */
473 case FRAME_CONT:
474#if LJ_HASFFI
475 if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK)
476 cf = cframe_prev(cf);
477#endif
478 case FRAME_VARG:
479 frame = frame_prevd(frame);
480 break;
481 case FRAME_CP:
482 if (cframe_canyield(cf)) return 0;
483 if (cframe_errfunc(cf) >= 0)
484 return cframe_errfunc(cf);
485 frame = frame_prevd(frame);
486 break;
487 case FRAME_PCALL:
488 case FRAME_PCALLH:
489 if (frame_ftsz(frame) >= (ptrdiff_t)(2*sizeof(TValue))) /* xpcall? */
490 return savestack(L, frame-1); /* Point to xpcall's errorfunc. */
491 return 0;
492 default:
493 lua_assert(0);
494 return 0;
495 }
496 }
497 return 0;
498}
499
500/* Runtime error. */
501LJ_NOINLINE void lj_err_run(lua_State *L)
502{
503 ptrdiff_t ef = finderrfunc(L);
504 if (ef) {
505 TValue *errfunc = restorestack(L, ef);
506 TValue *top = L->top;
507 lj_trace_abort(G(L));
508 if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) {
509 setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR));
510 lj_err_throw(L, LUA_ERRERR);
511 }
512 L->status = LUA_ERRERR;
513 copyTV(L, top, top-1);
514 copyTV(L, top-1, errfunc);
515 L->top = top+1;
516 lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */
517 }
518 lj_err_throw(L, LUA_ERRRUN);
519}
520
521/* Formatted runtime error message. */
522LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...)
523{
524 const char *msg;
525 va_list argp;
526 va_start(argp, em);
527 if (curr_funcisL(L)) L->top = curr_topL(L);
528 msg = lj_str_pushvf(L, err2msg(em), argp);
529 va_end(argp);
530 lj_debug_addloc(L, msg, L->base-1, NULL);
531 lj_err_run(L);
532}
533
534/* Non-vararg variant for better calling conventions. */
535LJ_NOINLINE void lj_err_msg(lua_State *L, ErrMsg em)
536{
537 err_msgv(L, em);
538}
539
540/* Lexer error. */
541LJ_NOINLINE void lj_err_lex(lua_State *L, GCstr *src, const char *tok,
542 BCLine line, ErrMsg em, va_list argp)
543{
544 char buff[LUA_IDSIZE];
545 const char *msg;
546 lj_debug_shortname(buff, src);
547 msg = lj_str_pushvf(L, err2msg(em), argp);
548 msg = lj_str_pushf(L, "%s:%d: %s", buff, line, msg);
549 if (tok)
550 lj_str_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tok);
551 lj_err_throw(L, LUA_ERRSYNTAX);
552}
553
554/* Typecheck error for operands. */
555LJ_NOINLINE void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm)
556{
557 const char *tname = typename(o);
558 const char *opname = err2msg(opm);
559 if (curr_funcisL(L)) {
560 GCproto *pt = curr_proto(L);
561 const BCIns *pc = cframe_Lpc(L) - 1;
562 const char *oname = NULL;
563 const char *kind = lj_debug_slotname(pt, pc, (BCReg)(o-L->base), &oname);
564 if (kind)
565 err_msgv(L, LJ_ERR_BADOPRT, opname, kind, oname, tname);
566 }
567 err_msgv(L, LJ_ERR_BADOPRV, opname, tname);
568}
569
570/* Typecheck error for ordered comparisons. */
571LJ_NOINLINE void lj_err_comp(lua_State *L, cTValue *o1, cTValue *o2)
572{
573 const char *t1 = typename(o1);
574 const char *t2 = typename(o2);
575 err_msgv(L, t1 == t2 ? LJ_ERR_BADCMPV : LJ_ERR_BADCMPT, t1, t2);
576 /* This assumes the two "boolean" entries are commoned by the C compiler. */
577}
578
579/* Typecheck error for __call. */
580LJ_NOINLINE void lj_err_optype_call(lua_State *L, TValue *o)
581{
582 /* Gross hack if lua_[p]call or pcall/xpcall fail for a non-callable object:
583 ** L->base still points to the caller. So add a dummy frame with L instead
584 ** of a function. See lua_getstack().
585 */
586 const BCIns *pc = cframe_Lpc(L);
587 if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) {
588 const char *tname = typename(o);
589 setframe_pc(o, pc);
590 setframe_gc(o, obj2gco(L));
591 L->top = L->base = o+1;
592 err_msgv(L, LJ_ERR_BADCALL, tname);
593 }
594 lj_err_optype(L, o, LJ_ERR_OPCALL);
595}
596
597/* Error in context of caller. */
598LJ_NOINLINE void lj_err_callermsg(lua_State *L, const char *msg)
599{
600 TValue *frame = L->base-1;
601 TValue *pframe = NULL;
602 if (frame_islua(frame)) {
603 pframe = frame_prevl(frame);
604 } else if (frame_iscont(frame)) {
605#if LJ_HASFFI
606 if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) {
607 pframe = frame;
608 frame = NULL;
609 } else
610#endif
611 {
612 pframe = frame_prevd(frame);
613#if LJ_HASFFI
614 /* Remove frame for FFI metamethods. */
615 if (frame_func(frame)->c.ffid >= FF_ffi_meta___index &&
616 frame_func(frame)->c.ffid <= FF_ffi_meta___tostring) {
617 L->base = pframe+1;
618 L->top = frame;
619 }
620#endif
621 }
622 }
623 lj_debug_addloc(L, msg, pframe, frame);
624 lj_err_run(L);
625}
626
627/* Formatted error in context of caller. */
628LJ_NOINLINE void lj_err_callerv(lua_State *L, ErrMsg em, ...)
629{
630 const char *msg;
631 va_list argp;
632 va_start(argp, em);
633 msg = lj_str_pushvf(L, err2msg(em), argp);
634 va_end(argp);
635 lj_err_callermsg(L, msg);
636}
637
638/* Error in context of caller. */
639LJ_NOINLINE void lj_err_caller(lua_State *L, ErrMsg em)
640{
641 lj_err_callermsg(L, err2msg(em));
642}
643
644/* Argument error message. */
645LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg,
646 const char *msg)
647{
648 const char *fname = "?";
649 const char *ftype = lj_debug_funcname(L, L->base - 1, &fname);
650 if (narg < 0 && narg > LUA_REGISTRYINDEX)
651 narg = (int)(L->top - L->base) + narg + 1;
652 if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */
653 msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg);
654 else
655 msg = lj_str_pushf(L, err2msg(LJ_ERR_BADARG), narg, fname, msg);
656 lj_err_callermsg(L, msg);
657}
658
659/* Formatted argument error. */
660LJ_NOINLINE void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...)
661{
662 const char *msg;
663 va_list argp;
664 va_start(argp, em);
665 msg = lj_str_pushvf(L, err2msg(em), argp);
666 va_end(argp);
667 err_argmsg(L, narg, msg);
668}
669
670/* Argument error. */
671LJ_NOINLINE void lj_err_arg(lua_State *L, int narg, ErrMsg em)
672{
673 err_argmsg(L, narg, err2msg(em));
674}
675
676/* Typecheck error for arguments. */
677LJ_NOINLINE void lj_err_argtype(lua_State *L, int narg, const char *xname)
678{
679 TValue *o = L->base + narg-1;
680 const char *tname = o < L->top ? typename(o) : lj_obj_typename[0];
681 const char *msg = lj_str_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname);
682 err_argmsg(L, narg, msg);
683}
684
685/* Typecheck error for arguments. */
686LJ_NOINLINE void lj_err_argt(lua_State *L, int narg, int tt)
687{
688 lj_err_argtype(L, narg, lj_obj_typename[tt+1]);
689}
690
691/* -- Public error handling API ------------------------------------------- */
692
693LUA_API lua_CFunction lua_atpanic(lua_State *L, lua_CFunction panicf)
694{
695 lua_CFunction old = G(L)->panic;
696 G(L)->panic = panicf;
697 return old;
698}
699
700/* Forwarders for the public API (C calling convention and no LJ_NORET). */
701LUA_API int lua_error(lua_State *L)
702{
703 lj_err_run(L);
704 return 0; /* unreachable */
705}
706
707LUALIB_API int luaL_argerror(lua_State *L, int narg, const char *msg)
708{
709 err_argmsg(L, narg, msg);
710 return 0; /* unreachable */
711}
712
713LUALIB_API int luaL_typerror(lua_State *L, int narg, const char *xname)
714{
715 lj_err_argtype(L, narg, xname);
716 return 0; /* unreachable */
717}
718
719LUALIB_API void luaL_where(lua_State *L, int level)
720{
721 int size;
722 cTValue *frame = lj_debug_frame(L, level, &size);
723 lj_debug_addloc(L, "", frame, size ? frame+size : NULL);
724}
725
726LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...)
727{
728 const char *msg;
729 va_list argp;
730 va_start(argp, fmt);
731 msg = lj_str_pushvf(L, fmt, argp);
732 va_end(argp);
733 lj_err_callermsg(L, msg);
734 return 0; /* unreachable */
735}
736
diff --git a/libraries/luajit-2.0/src/lj_err.h b/libraries/luajit-2.0/src/lj_err.h
new file mode 100644
index 0000000..c65f484
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_err.h
@@ -0,0 +1,41 @@
1/*
2** Error handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_ERR_H
7#define _LJ_ERR_H
8
9#include <stdarg.h>
10
11#include "lj_obj.h"
12
13typedef enum {
14#define ERRDEF(name, msg) \
15 LJ_ERR_##name, LJ_ERR_##name##_ = LJ_ERR_##name + sizeof(msg)-1,
16#include "lj_errmsg.h"
17 LJ_ERR__MAX
18} ErrMsg;
19
20LJ_DATA const char *lj_err_allmsg;
21#define err2msg(em) (lj_err_allmsg+(int)(em))
22
23LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em);
24LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode);
25LJ_FUNC_NORET void lj_err_mem(lua_State *L);
26LJ_FUNC_NORET void lj_err_run(lua_State *L);
27LJ_FUNC_NORET void lj_err_msg(lua_State *L, ErrMsg em);
28LJ_FUNC_NORET void lj_err_lex(lua_State *L, GCstr *src, const char *tok,
29 BCLine line, ErrMsg em, va_list argp);
30LJ_FUNC_NORET void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm);
31LJ_FUNC_NORET void lj_err_comp(lua_State *L, cTValue *o1, cTValue *o2);
32LJ_FUNC_NORET void lj_err_optype_call(lua_State *L, TValue *o);
33LJ_FUNC_NORET void lj_err_callermsg(lua_State *L, const char *msg);
34LJ_FUNC_NORET void lj_err_callerv(lua_State *L, ErrMsg em, ...);
35LJ_FUNC_NORET void lj_err_caller(lua_State *L, ErrMsg em);
36LJ_FUNC_NORET void lj_err_arg(lua_State *L, int narg, ErrMsg em);
37LJ_FUNC_NORET void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...);
38LJ_FUNC_NORET void lj_err_argtype(lua_State *L, int narg, const char *xname);
39LJ_FUNC_NORET void lj_err_argt(lua_State *L, int narg, int tt);
40
41#endif
diff --git a/libraries/luajit-2.0/src/lj_errmsg.h b/libraries/luajit-2.0/src/lj_errmsg.h
new file mode 100644
index 0000000..10c8395
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_errmsg.h
@@ -0,0 +1,173 @@
1/*
2** VM error messages.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* This file may be included multiple times with different ERRDEF macros. */
7
8/* Basic error handling. */
9ERRDEF(ERRMEM, "not enough memory")
10ERRDEF(ERRERR, "error in error handling")
11ERRDEF(ERRCPP, "C++ exception")
12
13/* Allocations. */
14ERRDEF(STROV, "string length overflow")
15ERRDEF(UDATAOV, "userdata length overflow")
16ERRDEF(STKOV, "stack overflow")
17ERRDEF(STKOVM, "stack overflow (%s)")
18ERRDEF(TABOV, "table overflow")
19
20/* Table indexing. */
21ERRDEF(NANIDX, "table index is NaN")
22ERRDEF(NILIDX, "table index is nil")
23ERRDEF(NEXTIDX, "invalid key to " LUA_QL("next"))
24
25/* Metamethod resolving. */
26ERRDEF(BADCALL, "attempt to call a %s value")
27ERRDEF(BADOPRT, "attempt to %s %s " LUA_QS " (a %s value)")
28ERRDEF(BADOPRV, "attempt to %s a %s value")
29ERRDEF(BADCMPT, "attempt to compare %s with %s")
30ERRDEF(BADCMPV, "attempt to compare two %s values")
31ERRDEF(GETLOOP, "loop in gettable")
32ERRDEF(SETLOOP, "loop in settable")
33ERRDEF(OPCALL, "call")
34ERRDEF(OPINDEX, "index")
35ERRDEF(OPARITH, "perform arithmetic on")
36ERRDEF(OPCAT, "concatenate")
37ERRDEF(OPLEN, "get length of")
38
39/* Type checks. */
40ERRDEF(BADSELF, "calling " LUA_QS " on bad self (%s)")
41ERRDEF(BADARG, "bad argument #%d to " LUA_QS " (%s)")
42ERRDEF(BADTYPE, "%s expected, got %s")
43ERRDEF(BADVAL, "invalid value")
44ERRDEF(NOVAL, "value expected")
45ERRDEF(NOCORO, "coroutine expected")
46ERRDEF(NOTABN, "nil or table expected")
47ERRDEF(NOFUNCL, "function or level expected")
48ERRDEF(NOSFT, "string/function/table expected")
49ERRDEF(NOPROXY, "boolean or proxy expected")
50ERRDEF(FORINIT, LUA_QL("for") " initial value must be a number")
51ERRDEF(FORLIM, LUA_QL("for") " limit must be a number")
52ERRDEF(FORSTEP, LUA_QL("for") " step must be a number")
53
54/* C API checks. */
55ERRDEF(NOENV, "no calling environment")
56ERRDEF(CYIELD, "attempt to yield across C-call boundary")
57ERRDEF(BADLU, "bad light userdata pointer")
58ERRDEF(NOGCMM, "bad action while in __gc metamethod")
59#if LJ_TARGET_WINDOWS
60ERRDEF(BADFPU, "bad FPU precision (use D3DCREATE_FPU_PRESERVE with DirectX)")
61#endif
62
63/* Standard library function errors. */
64ERRDEF(ASSERT, "assertion failed!")
65ERRDEF(PROTMT, "cannot change a protected metatable")
66ERRDEF(UNPACK, "too many results to unpack")
67ERRDEF(RDRSTR, "reader function must return a string")
68ERRDEF(PRTOSTR, LUA_QL("tostring") " must return a string to " LUA_QL("print"))
69ERRDEF(IDXRNG, "index out of range")
70ERRDEF(BASERNG, "base out of range")
71ERRDEF(LVLRNG, "level out of range")
72ERRDEF(INVLVL, "invalid level")
73ERRDEF(INVOPT, "invalid option")
74ERRDEF(INVOPTM, "invalid option " LUA_QS)
75ERRDEF(INVFMT, "invalid format")
76ERRDEF(SETFENV, LUA_QL("setfenv") " cannot change environment of given object")
77ERRDEF(CORUN, "cannot resume running coroutine")
78ERRDEF(CODEAD, "cannot resume dead coroutine")
79ERRDEF(COSUSP, "cannot resume non-suspended coroutine")
80ERRDEF(TABINS, "wrong number of arguments to " LUA_QL("insert"))
81ERRDEF(TABCAT, "invalid value (%s) at index %d in table for " LUA_QL("concat"))
82ERRDEF(TABSORT, "invalid order function for sorting")
83ERRDEF(IOCLFL, "attempt to use a closed file")
84ERRDEF(IOSTDCL, "standard file is closed")
85ERRDEF(OSUNIQF, "unable to generate a unique filename")
86ERRDEF(OSDATEF, "field " LUA_QS " missing in date table")
87ERRDEF(STRDUMP, "unable to dump given function")
88ERRDEF(STRSLC, "string slice too long")
89ERRDEF(STRPATB, "missing " LUA_QL("[") " after " LUA_QL("%f") " in pattern")
90ERRDEF(STRPATC, "invalid pattern capture")
91ERRDEF(STRPATE, "malformed pattern (ends with " LUA_QL("%") ")")
92ERRDEF(STRPATM, "malformed pattern (missing " LUA_QL("]") ")")
93ERRDEF(STRPATU, "unbalanced pattern")
94ERRDEF(STRCAPI, "invalid capture index")
95ERRDEF(STRCAPN, "too many captures")
96ERRDEF(STRCAPU, "unfinished capture")
97ERRDEF(STRFMTO, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"))
98ERRDEF(STRFMTR, "invalid format (repeated flags)")
99ERRDEF(STRFMTW, "invalid format (width or precision too long)")
100ERRDEF(STRGSRV, "invalid replacement value (a %s)")
101ERRDEF(BADMODN, "name conflict for module " LUA_QS)
102#if LJ_HASJIT
103ERRDEF(NOJIT, "JIT compiler disabled, CPU does not support SSE2")
104#elif defined(LJ_ARCH_NOJIT)
105ERRDEF(NOJIT, "no JIT compiler for this architecture (yet)")
106#else
107ERRDEF(NOJIT, "JIT compiler permanently disabled by build option")
108#endif
109ERRDEF(JITOPT, "unknown or malformed optimization flag " LUA_QS)
110
111/* Lexer/parser errors. */
112ERRDEF(XNEAR, "%s near " LUA_QS)
113ERRDEF(XELEM, "lexical element too long")
114ERRDEF(XLINES, "chunk has too many lines")
115ERRDEF(XLEVELS, "chunk has too many syntax levels")
116ERRDEF(XNUMBER, "malformed number")
117ERRDEF(XLSTR, "unfinished long string")
118ERRDEF(XLCOM, "unfinished long comment")
119ERRDEF(XSTR, "unfinished string")
120ERRDEF(XESC, "invalid escape sequence")
121ERRDEF(XLDELIM, "invalid long string delimiter")
122ERRDEF(XTOKEN, LUA_QS " expected")
123ERRDEF(XJUMP, "control structure too long")
124ERRDEF(XSLOTS, "function or expression too complex")
125ERRDEF(XLIMC, "chunk has more than %d local variables")
126ERRDEF(XLIMM, "main function has more than %d %s")
127ERRDEF(XLIMF, "function at line %d has more than %d %s")
128ERRDEF(XMATCH, LUA_QS " expected (to close " LUA_QS " at line %d)")
129ERRDEF(XFIXUP, "function too long for return fixup")
130ERRDEF(XPARAM, "<name> or " LUA_QL("...") " expected")
131ERRDEF(XAMBIG, "ambiguous syntax (function call x new statement)")
132ERRDEF(XFUNARG, "function arguments expected")
133ERRDEF(XSYMBOL, "unexpected symbol")
134ERRDEF(XDOTS, "cannot use " LUA_QL("...") " outside a vararg function")
135ERRDEF(XSYNTAX, "syntax error")
136ERRDEF(XBREAK, "no loop to break")
137ERRDEF(XFOR, LUA_QL("=") " or " LUA_QL("in") " expected")
138
139/* Bytecode reader errors. */
140ERRDEF(BCFMT, "cannot load incompatible bytecode")
141ERRDEF(BCBAD, "cannot load malformed bytecode")
142
143#if LJ_HASFFI
144/* FFI errors. */
145ERRDEF(FFI_INVTYPE, "invalid C type")
146ERRDEF(FFI_INVSIZE, "size of C type is unknown or too large")
147ERRDEF(FFI_BADSCL, "bad storage class")
148ERRDEF(FFI_DECLSPEC, "declaration specifier expected")
149ERRDEF(FFI_BADTAG, "undeclared or implicit tag " LUA_QS)
150ERRDEF(FFI_REDEF, "attempt to redefine " LUA_QS)
151ERRDEF(FFI_INITOV, "too many initializers for " LUA_QS)
152ERRDEF(FFI_BADCONV, "cannot convert " LUA_QS " to " LUA_QS)
153ERRDEF(FFI_BADLEN, "attempt to get length of " LUA_QS)
154ERRDEF(FFI_BADCONCAT, "attempt to concatenate " LUA_QS " and " LUA_QS)
155ERRDEF(FFI_BADARITH, "attempt to perform arithmetic on " LUA_QS " and " LUA_QS)
156ERRDEF(FFI_BADCOMP, "attempt to compare " LUA_QS " with " LUA_QS)
157ERRDEF(FFI_BADCALL, LUA_QS " is not callable")
158ERRDEF(FFI_NUMARG, "wrong number of arguments for function call")
159ERRDEF(FFI_BADMEMBER, LUA_QS " has no member named " LUA_QS)
160ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed")
161ERRDEF(FFI_WRCONST, "attempt to write to constant location")
162ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS)
163ERRDEF(FFI_BADCBACK, "bad callback")
164ERRDEF(FFI_CBACKOV, "too many callbacks")
165ERRDEF(FFI_NYIPACKBIT, "NYI: packed bit fields")
166ERRDEF(FFI_NYICALL, "NYI: cannot call this C function (yet)")
167#endif
168
169#undef ERRDEF
170
171/* Detecting unused error messages:
172 awk -F, '/^ERRDEF/ { gsub(/ERRDEF./, ""); printf "grep -q LJ_ERR_%s *.[ch] || echo %s\n", $1, $1}' lj_errmsg.h | sh
173*/
diff --git a/libraries/luajit-2.0/src/lj_ff.h b/libraries/luajit-2.0/src/lj_ff.h
new file mode 100644
index 0000000..0b01e16
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ff.h
@@ -0,0 +1,18 @@
1/*
2** Fast function IDs.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_FF_H
7#define _LJ_FF_H
8
9/* Fast function ID. */
10typedef enum {
11 FF_LUA_ = FF_LUA, /* Lua function (must be 0). */
12 FF_C_ = FF_C, /* Regular C function (must be 1). */
13#define FFDEF(name) FF_##name,
14#include "lj_ffdef.h"
15 FF__MAX
16} FastFunc;
17
18#endif
diff --git a/libraries/luajit-2.0/src/lj_ffrecord.c b/libraries/luajit-2.0/src/lj_ffrecord.c
new file mode 100644
index 0000000..6cdd79a
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ffrecord.c
@@ -0,0 +1,855 @@
1/*
2** Fast function call recorder.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_ffrecord_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12
13#include "lj_err.h"
14#include "lj_str.h"
15#include "lj_tab.h"
16#include "lj_frame.h"
17#include "lj_bc.h"
18#include "lj_ff.h"
19#include "lj_ir.h"
20#include "lj_jit.h"
21#include "lj_ircall.h"
22#include "lj_iropt.h"
23#include "lj_trace.h"
24#include "lj_record.h"
25#include "lj_ffrecord.h"
26#include "lj_crecord.h"
27#include "lj_dispatch.h"
28#include "lj_vm.h"
29
30/* Some local macros to save typing. Undef'd at the end. */
31#define IR(ref) (&J->cur.ir[(ref)])
32
33/* Pass IR on to next optimization in chain (FOLD). */
34#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
35
36/* -- Fast function recording handlers ------------------------------------ */
37
38/* Conventions for fast function call handlers:
39**
40** The argument slots start at J->base[0]. All of them are guaranteed to be
41** valid and type-specialized references. J->base[J->maxslot] is set to 0
42** as a sentinel. The runtime argument values start at rd->argv[0].
43**
44** In general fast functions should check for presence of all of their
45** arguments and for the correct argument types. Some simplifications
46** are allowed if the interpreter throws instead. But even if recording
47** is aborted, the generated IR must be consistent (no zero-refs).
48**
49** The number of results in rd->nres is set to 1. Handlers that return
50** a different number of results need to override it. A negative value
51** prevents return processing (e.g. for pending calls).
52**
53** Results need to be stored starting at J->base[0]. Return processing
54** moves them to the right slots later.
55**
56** The per-ffid auxiliary data is the value of the 2nd part of the
57** LJLIB_REC() annotation. This allows handling similar functionality
58** in a common handler.
59*/
60
61/* Type of handler to record a fast function. */
62typedef void (LJ_FASTCALL *RecordFunc)(jit_State *J, RecordFFData *rd);
63
64/* Get runtime value of int argument. */
65static int32_t argv2int(jit_State *J, TValue *o)
66{
67 if (!tvisnumber(o) && !(tvisstr(o) && lj_str_tonumber(strV(o), o)))
68 lj_trace_err(J, LJ_TRERR_BADTYPE);
69 return tvisint(o) ? intV(o) : lj_num2int(numV(o));
70}
71
72/* Get runtime value of string argument. */
73static GCstr *argv2str(jit_State *J, TValue *o)
74{
75 if (LJ_LIKELY(tvisstr(o))) {
76 return strV(o);
77 } else {
78 GCstr *s;
79 if (!tvisnumber(o))
80 lj_trace_err(J, LJ_TRERR_BADTYPE);
81 if (tvisint(o))
82 s = lj_str_fromint(J->L, intV(o));
83 else
84 s = lj_str_fromnum(J->L, &o->n);
85 setstrV(J->L, o, s);
86 return s;
87 }
88}
89
90/* Return number of results wanted by caller. */
91static ptrdiff_t results_wanted(jit_State *J)
92{
93 TValue *frame = J->L->base-1;
94 if (frame_islua(frame))
95 return (ptrdiff_t)bc_b(frame_pc(frame)[-1]) - 1;
96 else
97 return -1;
98}
99
100/* Throw error for unsupported variant of fast function. */
101LJ_NORET static void recff_nyiu(jit_State *J)
102{
103 setfuncV(J->L, &J->errinfo, J->fn);
104 lj_trace_err_info(J, LJ_TRERR_NYIFFU);
105}
106
107/* Fallback handler for all fast functions that are not recorded (yet). */
108static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd)
109{
110 setfuncV(J->L, &J->errinfo, J->fn);
111 lj_trace_err_info(J, LJ_TRERR_NYIFF);
112 UNUSED(rd);
113}
114
115/* C functions can have arbitrary side-effects and are not recorded (yet). */
116static void LJ_FASTCALL recff_c(jit_State *J, RecordFFData *rd)
117{
118 setfuncV(J->L, &J->errinfo, J->fn);
119 lj_trace_err_info(J, LJ_TRERR_NYICF);
120 UNUSED(rd);
121}
122
123/* -- Base library fast functions ----------------------------------------- */
124
125static void LJ_FASTCALL recff_assert(jit_State *J, RecordFFData *rd)
126{
127 /* Arguments already specialized. The interpreter throws for nil/false. */
128 rd->nres = J->maxslot; /* Pass through all arguments. */
129}
130
131static void LJ_FASTCALL recff_type(jit_State *J, RecordFFData *rd)
132{
133 /* Arguments already specialized. Result is a constant string. Neat, huh? */
134 uint32_t t;
135 if (tvisnumber(&rd->argv[0]))
136 t = ~LJ_TNUMX;
137 else if (LJ_64 && tvislightud(&rd->argv[0]))
138 t = ~LJ_TLIGHTUD;
139 else
140 t = ~itype(&rd->argv[0]);
141 J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[t]));
142 UNUSED(rd);
143}
144
145static void LJ_FASTCALL recff_getmetatable(jit_State *J, RecordFFData *rd)
146{
147 TRef tr = J->base[0];
148 if (tr) {
149 RecordIndex ix;
150 ix.tab = tr;
151 copyTV(J->L, &ix.tabv, &rd->argv[0]);
152 if (lj_record_mm_lookup(J, &ix, MM_metatable))
153 J->base[0] = ix.mobj;
154 else
155 J->base[0] = ix.mt;
156 } /* else: Interpreter will throw. */
157}
158
159static void LJ_FASTCALL recff_setmetatable(jit_State *J, RecordFFData *rd)
160{
161 TRef tr = J->base[0];
162 TRef mt = J->base[1];
163 if (tref_istab(tr) && (tref_istab(mt) || (mt && tref_isnil(mt)))) {
164 TRef fref, mtref;
165 RecordIndex ix;
166 ix.tab = tr;
167 copyTV(J->L, &ix.tabv, &rd->argv[0]);
168 lj_record_mm_lookup(J, &ix, MM_metatable); /* Guard for no __metatable. */
169 fref = emitir(IRT(IR_FREF, IRT_P32), tr, IRFL_TAB_META);
170 mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt;
171 emitir(IRT(IR_FSTORE, IRT_TAB), fref, mtref);
172 if (!tref_isnil(mt))
173 emitir(IRT(IR_TBAR, IRT_TAB), tr, 0);
174 J->base[0] = tr;
175 J->needsnap = 1;
176 } /* else: Interpreter will throw. */
177}
178
179static void LJ_FASTCALL recff_rawget(jit_State *J, RecordFFData *rd)
180{
181 RecordIndex ix;
182 ix.tab = J->base[0]; ix.key = J->base[1];
183 if (tref_istab(ix.tab) && ix.key) {
184 ix.val = 0; ix.idxchain = 0;
185 settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
186 copyTV(J->L, &ix.keyv, &rd->argv[1]);
187 J->base[0] = lj_record_idx(J, &ix);
188 } /* else: Interpreter will throw. */
189}
190
191static void LJ_FASTCALL recff_rawset(jit_State *J, RecordFFData *rd)
192{
193 RecordIndex ix;
194 ix.tab = J->base[0]; ix.key = J->base[1]; ix.val = J->base[2];
195 if (tref_istab(ix.tab) && ix.key && ix.val) {
196 ix.idxchain = 0;
197 settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
198 copyTV(J->L, &ix.keyv, &rd->argv[1]);
199 copyTV(J->L, &ix.valv, &rd->argv[2]);
200 lj_record_idx(J, &ix);
201 /* Pass through table at J->base[0] as result. */
202 } /* else: Interpreter will throw. */
203}
204
205static void LJ_FASTCALL recff_rawequal(jit_State *J, RecordFFData *rd)
206{
207 TRef tra = J->base[0];
208 TRef trb = J->base[1];
209 if (tra && trb) {
210 int diff = lj_record_objcmp(J, tra, trb, &rd->argv[0], &rd->argv[1]);
211 J->base[0] = diff ? TREF_FALSE : TREF_TRUE;
212 } /* else: Interpreter will throw. */
213}
214
215/* Determine mode of select() call. */
216int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv)
217{
218 if (tref_isstr(tr) && *strVdata(tv) == '#') { /* select('#', ...) */
219 if (strV(tv)->len == 1) {
220 emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, strV(tv)));
221 } else {
222 TRef trptr = emitir(IRT(IR_STRREF, IRT_P32), tr, lj_ir_kint(J, 0));
223 TRef trchar = emitir(IRT(IR_XLOAD, IRT_U8), trptr, IRXLOAD_READONLY);
224 emitir(IRTG(IR_EQ, IRT_INT), trchar, lj_ir_kint(J, '#'));
225 }
226 return 0;
227 } else { /* select(n, ...) */
228 int32_t start = argv2int(J, tv);
229 if (start == 0) lj_trace_err(J, LJ_TRERR_BADTYPE); /* A bit misleading. */
230 return start;
231 }
232}
233
234static void LJ_FASTCALL recff_select(jit_State *J, RecordFFData *rd)
235{
236 TRef tr = J->base[0];
237 if (tr) {
238 ptrdiff_t start = lj_ffrecord_select_mode(J, tr, &rd->argv[0]);
239 if (start == 0) { /* select('#', ...) */
240 J->base[0] = lj_ir_kint(J, J->maxslot - 1);
241 } else if (tref_isk(tr)) { /* select(k, ...) */
242 ptrdiff_t n = (ptrdiff_t)J->maxslot;
243 if (start < 0) start += n;
244 else if (start > n) start = n;
245 rd->nres = n - start;
246 if (start >= 1) {
247 ptrdiff_t i;
248 for (i = 0; i < n - start; i++)
249 J->base[i] = J->base[start+i];
250 } /* else: Interpreter will throw. */
251 } else {
252 recff_nyiu(J);
253 }
254 } /* else: Interpreter will throw. */
255}
256
257static void LJ_FASTCALL recff_tonumber(jit_State *J, RecordFFData *rd)
258{
259 TRef tr = J->base[0];
260 TRef base = J->base[1];
261 if (tr && base) {
262 base = lj_opt_narrow_toint(J, base);
263 if (!tref_isk(base) || IR(tref_ref(base))->i != 10)
264 recff_nyiu(J);
265 }
266 if (tref_isnumber_str(tr)) {
267 if (tref_isstr(tr)) {
268 TValue tmp;
269 if (!lj_str_tonum(strV(&rd->argv[0]), &tmp))
270 recff_nyiu(J); /* Would need an inverted STRTO for this case. */
271 tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
272 }
273#if LJ_HASFFI
274 } else if (tref_iscdata(tr)) {
275 lj_crecord_tonumber(J, rd);
276 return;
277#endif
278 } else {
279 tr = TREF_NIL;
280 }
281 J->base[0] = tr;
282 UNUSED(rd);
283}
284
285static TValue *recff_metacall_cp(lua_State *L, lua_CFunction dummy, void *ud)
286{
287 jit_State *J = (jit_State *)ud;
288 lj_record_tailcall(J, 0, 1);
289 UNUSED(L); UNUSED(dummy);
290 return NULL;
291}
292
293static int recff_metacall(jit_State *J, RecordFFData *rd, MMS mm)
294{
295 RecordIndex ix;
296 ix.tab = J->base[0];
297 copyTV(J->L, &ix.tabv, &rd->argv[0]);
298 if (lj_record_mm_lookup(J, &ix, mm)) { /* Has metamethod? */
299 int errcode;
300 TValue argv0;
301 /* Temporarily insert metamethod below object. */
302 J->base[1] = J->base[0];
303 J->base[0] = ix.mobj;
304 copyTV(J->L, &argv0, &rd->argv[0]);
305 copyTV(J->L, &rd->argv[1], &rd->argv[0]);
306 copyTV(J->L, &rd->argv[0], &ix.mobjv);
307 /* Need to protect lj_record_tailcall because it may throw. */
308 errcode = lj_vm_cpcall(J->L, NULL, J, recff_metacall_cp);
309 /* Always undo Lua stack changes to avoid confusing the interpreter. */
310 copyTV(J->L, &rd->argv[0], &argv0);
311 if (errcode)
312 lj_err_throw(J->L, errcode); /* Propagate errors. */
313 rd->nres = -1; /* Pending call. */
314 return 1; /* Tailcalled to metamethod. */
315 }
316 return 0;
317}
318
319static void LJ_FASTCALL recff_tostring(jit_State *J, RecordFFData *rd)
320{
321 TRef tr = J->base[0];
322 if (tref_isstr(tr)) {
323 /* Ignore __tostring in the string base metatable. */
324 /* Pass on result in J->base[0]. */
325 } else if (!recff_metacall(J, rd, MM_tostring)) {
326 if (tref_isnumber(tr)) {
327 J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0);
328 } else if (tref_ispri(tr)) {
329 J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)]));
330 } else {
331 recff_nyiu(J);
332 }
333 }
334}
335
336static void LJ_FASTCALL recff_ipairs_aux(jit_State *J, RecordFFData *rd)
337{
338 RecordIndex ix;
339 ix.tab = J->base[0];
340 if (tref_istab(ix.tab)) {
341 if (!tvisnumber(&rd->argv[1])) /* No support for string coercion. */
342 lj_trace_err(J, LJ_TRERR_BADTYPE);
343 setintV(&ix.keyv, numberVint(&rd->argv[1])+1);
344 settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
345 ix.val = 0; ix.idxchain = 0;
346 ix.key = lj_opt_narrow_toint(J, J->base[1]);
347 J->base[0] = ix.key = emitir(IRTI(IR_ADD), ix.key, lj_ir_kint(J, 1));
348 J->base[1] = lj_record_idx(J, &ix);
349 rd->nres = tref_isnil(J->base[1]) ? 0 : 2;
350 } /* else: Interpreter will throw. */
351}
352
353static void LJ_FASTCALL recff_ipairs(jit_State *J, RecordFFData *rd)
354{
355#ifdef LUAJIT_ENABLE_LUA52COMPAT
356 if (!recff_metacall(J, rd, MM_ipairs))
357#endif
358 {
359 TRef tab = J->base[0];
360 if (tref_istab(tab)) {
361 J->base[0] = lj_ir_kfunc(J, funcV(&J->fn->c.upvalue[0]));
362 J->base[1] = tab;
363 J->base[2] = lj_ir_kint(J, 0);
364 rd->nres = 3;
365 } /* else: Interpreter will throw. */
366 }
367}
368
369static void LJ_FASTCALL recff_pcall(jit_State *J, RecordFFData *rd)
370{
371 if (J->maxslot >= 1) {
372 lj_record_call(J, 0, J->maxslot - 1);
373 rd->nres = -1; /* Pending call. */
374 } /* else: Interpreter will throw. */
375}
376
377static TValue *recff_xpcall_cp(lua_State *L, lua_CFunction dummy, void *ud)
378{
379 jit_State *J = (jit_State *)ud;
380 lj_record_call(J, 1, J->maxslot - 2);
381 UNUSED(L); UNUSED(dummy);
382 return NULL;
383}
384
385static void LJ_FASTCALL recff_xpcall(jit_State *J, RecordFFData *rd)
386{
387 if (J->maxslot >= 2) {
388 TValue argv0, argv1;
389 TRef tmp;
390 int errcode;
391 /* Swap function and traceback. */
392 tmp = J->base[0]; J->base[0] = J->base[1]; J->base[1] = tmp;
393 copyTV(J->L, &argv0, &rd->argv[0]);
394 copyTV(J->L, &argv1, &rd->argv[1]);
395 copyTV(J->L, &rd->argv[0], &argv1);
396 copyTV(J->L, &rd->argv[1], &argv0);
397 /* Need to protect lj_record_call because it may throw. */
398 errcode = lj_vm_cpcall(J->L, NULL, J, recff_xpcall_cp);
399 /* Always undo Lua stack swap to avoid confusing the interpreter. */
400 copyTV(J->L, &rd->argv[0], &argv0);
401 copyTV(J->L, &rd->argv[1], &argv1);
402 if (errcode)
403 lj_err_throw(J->L, errcode); /* Propagate errors. */
404 rd->nres = -1; /* Pending call. */
405 } /* else: Interpreter will throw. */
406}
407
408/* -- Math library fast functions ----------------------------------------- */
409
410static void LJ_FASTCALL recff_math_abs(jit_State *J, RecordFFData *rd)
411{
412 TRef tr = lj_ir_tonum(J, J->base[0]);
413 J->base[0] = emitir(IRTN(IR_ABS), tr, lj_ir_knum_abs(J));
414 UNUSED(rd);
415}
416
417/* Record rounding functions math.floor and math.ceil. */
418static void LJ_FASTCALL recff_math_round(jit_State *J, RecordFFData *rd)
419{
420 TRef tr = J->base[0];
421 if (!tref_isinteger(tr)) { /* Pass through integers unmodified. */
422 tr = emitir(IRTN(IR_FPMATH), lj_ir_tonum(J, tr), rd->data);
423 /* Result is integral (or NaN/Inf), but may not fit an int32_t. */
424 if (LJ_DUALNUM) { /* Try to narrow using a guarded conversion to int. */
425 lua_Number n = lj_vm_foldfpm(numberVnum(&rd->argv[0]), rd->data);
426 if (n == (lua_Number)lj_num2int(n))
427 tr = emitir(IRTGI(IR_CONV), tr, IRCONV_INT_NUM|IRCONV_CHECK);
428 }
429 J->base[0] = tr;
430 }
431}
432
433/* Record unary math.* functions, mapped to IR_FPMATH opcode. */
434static void LJ_FASTCALL recff_math_unary(jit_State *J, RecordFFData *rd)
435{
436 J->base[0] = emitir(IRTN(IR_FPMATH), lj_ir_tonum(J, J->base[0]), rd->data);
437}
438
439/* Record math.atan2. */
440static void LJ_FASTCALL recff_math_atan2(jit_State *J, RecordFFData *rd)
441{
442 TRef tr = lj_ir_tonum(J, J->base[0]);
443 TRef tr2 = lj_ir_tonum(J, J->base[1]);
444 J->base[0] = emitir(IRTN(IR_ATAN2), tr, tr2);
445 UNUSED(rd);
446}
447
448/* Record math.ldexp. */
449static void LJ_FASTCALL recff_math_ldexp(jit_State *J, RecordFFData *rd)
450{
451 TRef tr = lj_ir_tonum(J, J->base[0]);
452#if LJ_TARGET_X86ORX64
453 TRef tr2 = lj_ir_tonum(J, J->base[1]);
454#else
455 TRef tr2 = lj_opt_narrow_toint(J, J->base[1]);
456#endif
457 J->base[0] = emitir(IRTN(IR_LDEXP), tr, tr2);
458 UNUSED(rd);
459}
460
461/* Record math.asin, math.acos, math.atan. */
462static void LJ_FASTCALL recff_math_atrig(jit_State *J, RecordFFData *rd)
463{
464 TRef y = lj_ir_tonum(J, J->base[0]);
465 TRef x = lj_ir_knum_one(J);
466 uint32_t ffid = rd->data;
467 if (ffid != FF_math_atan) {
468 TRef tmp = emitir(IRTN(IR_MUL), y, y);
469 tmp = emitir(IRTN(IR_SUB), x, tmp);
470 tmp = emitir(IRTN(IR_FPMATH), tmp, IRFPM_SQRT);
471 if (ffid == FF_math_asin) { x = tmp; } else { x = y; y = tmp; }
472 }
473 J->base[0] = emitir(IRTN(IR_ATAN2), y, x);
474}
475
476static void LJ_FASTCALL recff_math_htrig(jit_State *J, RecordFFData *rd)
477{
478 TRef tr = lj_ir_tonum(J, J->base[0]);
479 J->base[0] = lj_ir_call(J, rd->data, tr);
480}
481
482static void LJ_FASTCALL recff_math_modf(jit_State *J, RecordFFData *rd)
483{
484 TRef tr = J->base[0];
485 if (tref_isinteger(tr)) {
486 J->base[0] = tr;
487 J->base[1] = lj_ir_kint(J, 0);
488 } else {
489 TRef trt;
490 tr = lj_ir_tonum(J, tr);
491 trt = emitir(IRTN(IR_FPMATH), tr, IRFPM_TRUNC);
492 J->base[0] = trt;
493 J->base[1] = emitir(IRTN(IR_SUB), tr, trt);
494 }
495 rd->nres = 2;
496}
497
498static void LJ_FASTCALL recff_math_degrad(jit_State *J, RecordFFData *rd)
499{
500 TRef tr = lj_ir_tonum(J, J->base[0]);
501 TRef trm = lj_ir_knum(J, numV(&J->fn->c.upvalue[0]));
502 J->base[0] = emitir(IRTN(IR_MUL), tr, trm);
503 UNUSED(rd);
504}
505
506static void LJ_FASTCALL recff_math_pow(jit_State *J, RecordFFData *rd)
507{
508 TRef tr = lj_ir_tonum(J, J->base[0]);
509 if (!tref_isnumber_str(J->base[1]))
510 lj_trace_err(J, LJ_TRERR_BADTYPE);
511 J->base[0] = lj_opt_narrow_pow(J, tr, J->base[1], &rd->argv[1]);
512 UNUSED(rd);
513}
514
515static void LJ_FASTCALL recff_math_minmax(jit_State *J, RecordFFData *rd)
516{
517 TRef tr = lj_ir_tonumber(J, J->base[0]);
518 uint32_t op = rd->data;
519 BCReg i;
520 for (i = 1; J->base[i] != 0; i++) {
521 TRef tr2 = lj_ir_tonumber(J, J->base[i]);
522 IRType t = IRT_INT;
523 if (!(tref_isinteger(tr) && tref_isinteger(tr2))) {
524 if (tref_isinteger(tr)) tr = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
525 if (tref_isinteger(tr2)) tr2 = emitir(IRTN(IR_CONV), tr2, IRCONV_NUM_INT);
526 t = IRT_NUM;
527 }
528 tr = emitir(IRT(op, t), tr, tr2);
529 }
530 J->base[0] = tr;
531}
532
533static void LJ_FASTCALL recff_math_random(jit_State *J, RecordFFData *rd)
534{
535 GCudata *ud = udataV(&J->fn->c.upvalue[0]);
536 TRef tr, one;
537 lj_ir_kgc(J, obj2gco(ud), IRT_UDATA); /* Prevent collection. */
538 tr = lj_ir_call(J, IRCALL_lj_math_random_step, lj_ir_kptr(J, uddata(ud)));
539 one = lj_ir_knum_one(J);
540 tr = emitir(IRTN(IR_SUB), tr, one);
541 if (J->base[0]) {
542 TRef tr1 = lj_ir_tonum(J, J->base[0]);
543 if (J->base[1]) { /* d = floor(d*(r2-r1+1.0)) + r1 */
544 TRef tr2 = lj_ir_tonum(J, J->base[1]);
545 tr2 = emitir(IRTN(IR_SUB), tr2, tr1);
546 tr2 = emitir(IRTN(IR_ADD), tr2, one);
547 tr = emitir(IRTN(IR_MUL), tr, tr2);
548 tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_FLOOR);
549 tr = emitir(IRTN(IR_ADD), tr, tr1);
550 } else { /* d = floor(d*r1) + 1.0 */
551 tr = emitir(IRTN(IR_MUL), tr, tr1);
552 tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_FLOOR);
553 tr = emitir(IRTN(IR_ADD), tr, one);
554 }
555 }
556 J->base[0] = tr;
557 UNUSED(rd);
558}
559
560/* -- Bit library fast functions ------------------------------------------ */
561
562/* Record unary bit.tobit, bit.bnot, bit.bswap. */
563static void LJ_FASTCALL recff_bit_unary(jit_State *J, RecordFFData *rd)
564{
565 TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
566 J->base[0] = (rd->data == IR_TOBIT) ? tr : emitir(IRTI(rd->data), tr, 0);
567}
568
569/* Record N-ary bit.band, bit.bor, bit.bxor. */
570static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd)
571{
572 TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
573 uint32_t op = rd->data;
574 BCReg i;
575 for (i = 1; J->base[i] != 0; i++)
576 tr = emitir(IRTI(op), tr, lj_opt_narrow_tobit(J, J->base[i]));
577 J->base[0] = tr;
578}
579
580/* Record bit shifts. */
581static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd)
582{
583 TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
584 TRef tsh = lj_opt_narrow_tobit(J, J->base[1]);
585 IROp op = (IROp)rd->data;
586 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
587 !tref_isk(tsh))
588 tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 31));
589#ifdef LJ_TARGET_UNIFYROT
590 if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
591 op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
592 tsh = emitir(IRTI(IR_NEG), tsh, tsh);
593 }
594#endif
595 J->base[0] = emitir(IRTI(op), tr, tsh);
596}
597
598/* -- String library fast functions --------------------------------------- */
599
600static void LJ_FASTCALL recff_string_len(jit_State *J, RecordFFData *rd)
601{
602 J->base[0] = emitir(IRTI(IR_FLOAD), lj_ir_tostr(J, J->base[0]), IRFL_STR_LEN);
603 UNUSED(rd);
604}
605
606/* Handle string.byte (rd->data = 0) and string.sub (rd->data = 1). */
607static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd)
608{
609 TRef trstr = lj_ir_tostr(J, J->base[0]);
610 TRef trlen = emitir(IRTI(IR_FLOAD), trstr, IRFL_STR_LEN);
611 TRef tr0 = lj_ir_kint(J, 0);
612 TRef trstart, trend;
613 GCstr *str = argv2str(J, &rd->argv[0]);
614 int32_t start, end;
615 if (rd->data) { /* string.sub(str, start [,end]) */
616 start = argv2int(J, &rd->argv[1]);
617 trstart = lj_opt_narrow_toint(J, J->base[1]);
618 trend = J->base[2];
619 if (tref_isnil(trend)) {
620 trend = lj_ir_kint(J, -1);
621 end = -1;
622 } else {
623 trend = lj_opt_narrow_toint(J, trend);
624 end = argv2int(J, &rd->argv[2]);
625 }
626 } else { /* string.byte(str, [,start [,end]]) */
627 if (J->base[1]) {
628 start = argv2int(J, &rd->argv[1]);
629 trstart = lj_opt_narrow_toint(J, J->base[1]);
630 trend = J->base[2];
631 if (tref_isnil(trend)) {
632 trend = trstart;
633 end = start;
634 } else {
635 trend = lj_opt_narrow_toint(J, trend);
636 end = argv2int(J, &rd->argv[2]);
637 }
638 } else {
639 trend = trstart = lj_ir_kint(J, 1);
640 end = start = 1;
641 }
642 }
643 if (end < 0) {
644 emitir(IRTGI(IR_LT), trend, tr0);
645 trend = emitir(IRTI(IR_ADD), emitir(IRTI(IR_ADD), trlen, trend),
646 lj_ir_kint(J, 1));
647 end = end+(int32_t)str->len+1;
648 } else if ((MSize)end <= str->len) {
649 emitir(IRTGI(IR_ULE), trend, trlen);
650 } else {
651 emitir(IRTGI(IR_GT), trend, trlen);
652 end = (int32_t)str->len;
653 trend = trlen;
654 }
655 if (start < 0) {
656 emitir(IRTGI(IR_LT), trstart, tr0);
657 trstart = emitir(IRTI(IR_ADD), trlen, trstart);
658 start = start+(int32_t)str->len;
659 emitir(start < 0 ? IRTGI(IR_LT) : IRTGI(IR_GE), trstart, tr0);
660 if (start < 0) {
661 trstart = tr0;
662 start = 0;
663 }
664 } else {
665 if (start == 0) {
666 emitir(IRTGI(IR_EQ), trstart, tr0);
667 trstart = tr0;
668 } else {
669 trstart = emitir(IRTI(IR_ADD), trstart, lj_ir_kint(J, -1));
670 emitir(IRTGI(IR_GE), trstart, tr0);
671 start--;
672 }
673 }
674 if (rd->data) { /* Return string.sub result. */
675 if (end - start >= 0) {
676 /* Also handle empty range here, to avoid extra traces. */
677 TRef trptr, trslen = emitir(IRTI(IR_SUB), trend, trstart);
678 emitir(IRTGI(IR_GE), trslen, tr0);
679 trptr = emitir(IRT(IR_STRREF, IRT_P32), trstr, trstart);
680 J->base[0] = emitir(IRT(IR_SNEW, IRT_STR), trptr, trslen);
681 } else { /* Range underflow: return empty string. */
682 emitir(IRTGI(IR_LT), trend, trstart);
683 J->base[0] = lj_ir_kstr(J, lj_str_new(J->L, strdata(str), 0));
684 }
685 } else { /* Return string.byte result(s). */
686 ptrdiff_t i, len = end - start;
687 if (len > 0) {
688 TRef trslen = emitir(IRTI(IR_SUB), trend, trstart);
689 emitir(IRTGI(IR_EQ), trslen, lj_ir_kint(J, (int32_t)len));
690 if (J->baseslot + len > LJ_MAX_JSLOTS)
691 lj_trace_err_info(J, LJ_TRERR_STACKOV);
692 rd->nres = len;
693 for (i = 0; i < len; i++) {
694 TRef tmp = emitir(IRTI(IR_ADD), trstart, lj_ir_kint(J, (int32_t)i));
695 tmp = emitir(IRT(IR_STRREF, IRT_P32), trstr, tmp);
696 J->base[i] = emitir(IRT(IR_XLOAD, IRT_U8), tmp, IRXLOAD_READONLY);
697 }
698 } else { /* Empty range or range underflow: return no results. */
699 emitir(IRTGI(IR_LE), trend, trstart);
700 rd->nres = 0;
701 }
702 }
703}
704
705/* -- Table library fast functions ---------------------------------------- */
706
707static void LJ_FASTCALL recff_table_getn(jit_State *J, RecordFFData *rd)
708{
709 if (tref_istab(J->base[0]))
710 J->base[0] = lj_ir_call(J, IRCALL_lj_tab_len, J->base[0]);
711 /* else: Interpreter will throw. */
712 UNUSED(rd);
713}
714
715static void LJ_FASTCALL recff_table_remove(jit_State *J, RecordFFData *rd)
716{
717 TRef tab = J->base[0];
718 rd->nres = 0;
719 if (tref_istab(tab)) {
720 if (!J->base[1] || tref_isnil(J->base[1])) { /* Simple pop: t[#t] = nil */
721 TRef trlen = lj_ir_call(J, IRCALL_lj_tab_len, tab);
722 GCtab *t = tabV(&rd->argv[0]);
723 MSize len = lj_tab_len(t);
724 emitir(IRTGI(len ? IR_NE : IR_EQ), trlen, lj_ir_kint(J, 0));
725 if (len) {
726 RecordIndex ix;
727 ix.tab = tab;
728 ix.key = trlen;
729 settabV(J->L, &ix.tabv, t);
730 setintV(&ix.keyv, len);
731 ix.idxchain = 0;
732 if (results_wanted(J) != 0) { /* Specialize load only if needed. */
733 ix.val = 0;
734 J->base[0] = lj_record_idx(J, &ix); /* Load previous value. */
735 rd->nres = 1;
736 /* Assumes ix.key/ix.tab is not modified for raw lj_record_idx(). */
737 }
738 ix.val = TREF_NIL;
739 lj_record_idx(J, &ix); /* Remove value. */
740 }
741 } else { /* Complex case: remove in the middle. */
742 recff_nyiu(J);
743 }
744 } /* else: Interpreter will throw. */
745}
746
747static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd)
748{
749 RecordIndex ix;
750 ix.tab = J->base[0];
751 ix.val = J->base[1];
752 rd->nres = 0;
753 if (tref_istab(ix.tab) && ix.val) {
754 if (!J->base[2]) { /* Simple push: t[#t+1] = v */
755 TRef trlen = lj_ir_call(J, IRCALL_lj_tab_len, ix.tab);
756 GCtab *t = tabV(&rd->argv[0]);
757 ix.key = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
758 settabV(J->L, &ix.tabv, t);
759 setintV(&ix.keyv, lj_tab_len(t) + 1);
760 ix.idxchain = 0;
761 lj_record_idx(J, &ix); /* Set new value. */
762 } else { /* Complex case: insert in the middle. */
763 recff_nyiu(J);
764 }
765 } /* else: Interpreter will throw. */
766}
767
768/* -- I/O library fast functions ------------------------------------------ */
769
770/* Get FILE* for I/O function. Any I/O error aborts recording, so there's
771** no need to encode the alternate cases for any of the guards.
772*/
773static TRef recff_io_fp(jit_State *J, uint32_t id)
774{
775 TRef tr, ud, fp;
776 if (id) { /* io.func() */
777 tr = lj_ir_kptr(J, &J2G(J)->gcroot[id]);
778 ud = emitir(IRT(IR_XLOAD, IRT_UDATA), tr, 0);
779 } else { /* fp:method() */
780 ud = J->base[0];
781 if (!tref_isudata(ud))
782 lj_trace_err(J, LJ_TRERR_BADTYPE);
783 tr = emitir(IRT(IR_FLOAD, IRT_U8), ud, IRFL_UDATA_UDTYPE);
784 emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, UDTYPE_IO_FILE));
785 }
786 fp = emitir(IRT(IR_FLOAD, IRT_PTR), ud, IRFL_UDATA_FILE);
787 emitir(IRTG(IR_NE, IRT_PTR), fp, lj_ir_knull(J, IRT_PTR));
788 return fp;
789}
790
791static void LJ_FASTCALL recff_io_write(jit_State *J, RecordFFData *rd)
792{
793 TRef fp = recff_io_fp(J, rd->data);
794 TRef zero = lj_ir_kint(J, 0);
795 TRef one = lj_ir_kint(J, 1);
796 ptrdiff_t i = rd->data == 0 ? 1 : 0;
797 for (; J->base[i]; i++) {
798 TRef str = lj_ir_tostr(J, J->base[i]);
799 TRef buf = emitir(IRT(IR_STRREF, IRT_P32), str, zero);
800 TRef len = emitir(IRTI(IR_FLOAD), str, IRFL_STR_LEN);
801 if (tref_isk(len) && IR(tref_ref(len))->i == 1) {
802 TRef tr = emitir(IRT(IR_XLOAD, IRT_U8), buf, IRXLOAD_READONLY);
803 tr = lj_ir_call(J, IRCALL_fputc, tr, fp);
804 if (results_wanted(J) != 0) /* Check result only if not ignored. */
805 emitir(IRTGI(IR_NE), tr, lj_ir_kint(J, -1));
806 } else {
807 TRef tr = lj_ir_call(J, IRCALL_fwrite, buf, one, len, fp);
808 if (results_wanted(J) != 0) /* Check result only if not ignored. */
809 emitir(IRTGI(IR_EQ), tr, len);
810 }
811 }
812 J->base[0] = TREF_TRUE;
813}
814
815static void LJ_FASTCALL recff_io_flush(jit_State *J, RecordFFData *rd)
816{
817 TRef fp = recff_io_fp(J, rd->data);
818 TRef tr = lj_ir_call(J, IRCALL_fflush, fp);
819 if (results_wanted(J) != 0) /* Check result only if not ignored. */
820 emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, 0));
821 J->base[0] = TREF_TRUE;
822}
823
824/* -- Record calls to fast functions -------------------------------------- */
825
826#include "lj_recdef.h"
827
828static uint32_t recdef_lookup(GCfunc *fn)
829{
830 if (fn->c.ffid < sizeof(recff_idmap)/sizeof(recff_idmap[0]))
831 return recff_idmap[fn->c.ffid];
832 else
833 return 0;
834}
835
836/* Record entry to a fast function or C function. */
837void lj_ffrecord_func(jit_State *J)
838{
839 RecordFFData rd;
840 uint32_t m = recdef_lookup(J->fn);
841 rd.data = m & 0xff;
842 rd.nres = 1; /* Default is one result. */
843 rd.argv = J->L->base;
844 J->base[J->maxslot] = 0; /* Mark end of arguments. */
845 (recff_func[m >> 8])(J, &rd); /* Call recff_* handler. */
846 if (rd.nres >= 0) {
847 if (J->postproc == LJ_POST_NONE) J->postproc = LJ_POST_FFRETRY;
848 lj_record_ret(J, 0, rd.nres);
849 }
850}
851
852#undef IR
853#undef emitir
854
855#endif
diff --git a/libraries/luajit-2.0/src/lj_ffrecord.h b/libraries/luajit-2.0/src/lj_ffrecord.h
new file mode 100644
index 0000000..7ff270a
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ffrecord.h
@@ -0,0 +1,24 @@
1/*
2** Fast function call recorder.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_FFRECORD_H
7#define _LJ_FFRECORD_H
8
9#include "lj_obj.h"
10#include "lj_jit.h"
11
12#if LJ_HASJIT
13/* Data used by handlers to record a fast function. */
14typedef struct RecordFFData {
15 TValue *argv; /* Runtime argument values. */
16 ptrdiff_t nres; /* Number of returned results (defaults to 1). */
17 uint32_t data; /* Per-ffid auxiliary data (opcode, literal etc.). */
18} RecordFFData;
19
20LJ_FUNC int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv);
21LJ_FUNC void lj_ffrecord_func(jit_State *J);
22#endif
23
24#endif
diff --git a/libraries/luajit-2.0/src/lj_frame.h b/libraries/luajit-2.0/src/lj_frame.h
new file mode 100644
index 0000000..a69917e
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_frame.h
@@ -0,0 +1,160 @@
1/*
2** Stack frames.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_FRAME_H
7#define _LJ_FRAME_H
8
9#include "lj_obj.h"
10#include "lj_bc.h"
11
12/* -- Lua stack frame ----------------------------------------------------- */
13
14/* Frame type markers in callee function slot (callee base-1). */
15enum {
16 FRAME_LUA, FRAME_C, FRAME_CONT, FRAME_VARG,
17 FRAME_LUAP, FRAME_CP, FRAME_PCALL, FRAME_PCALLH
18};
19#define FRAME_TYPE 3
20#define FRAME_P 4
21#define FRAME_TYPEP (FRAME_TYPE|FRAME_P)
22
23/* Macros to access and modify Lua frames. */
24#define frame_gc(f) (gcref((f)->fr.func))
25#define frame_func(f) (&frame_gc(f)->fn)
26#define frame_ftsz(f) ((f)->fr.tp.ftsz)
27
28#define frame_type(f) (frame_ftsz(f) & FRAME_TYPE)
29#define frame_typep(f) (frame_ftsz(f) & FRAME_TYPEP)
30#define frame_islua(f) (frame_type(f) == FRAME_LUA)
31#define frame_isc(f) (frame_type(f) == FRAME_C)
32#define frame_iscont(f) (frame_typep(f) == FRAME_CONT)
33#define frame_isvarg(f) (frame_typep(f) == FRAME_VARG)
34#define frame_ispcall(f) ((frame_ftsz(f) & 6) == FRAME_PCALL)
35
36#define frame_pc(f) (mref((f)->fr.tp.pcr, const BCIns))
37#define frame_contpc(f) (frame_pc((f)-1))
38#if LJ_64
39#define frame_contf(f) \
40 ((ASMFunction)(void *)((intptr_t)lj_vm_asm_begin + \
41 (intptr_t)(int32_t)((f)-1)->u32.lo))
42#else
43#define frame_contf(f) ((ASMFunction)gcrefp(((f)-1)->gcr, void))
44#endif
45#define frame_delta(f) (frame_ftsz(f) >> 3)
46#define frame_sized(f) (frame_ftsz(f) & ~FRAME_TYPEP)
47
48#define frame_prevl(f) ((f) - (1+bc_a(frame_pc(f)[-1])))
49#define frame_prevd(f) ((TValue *)((char *)(f) - frame_sized(f)))
50#define frame_prev(f) (frame_islua(f)?frame_prevl(f):frame_prevd(f))
51/* Note: this macro does not skip over FRAME_VARG. */
52
53#define setframe_pc(f, pc) (setmref((f)->fr.tp.pcr, (pc)))
54#define setframe_ftsz(f, sz) ((f)->fr.tp.ftsz = (sz))
55#define setframe_gc(f, p) (setgcref((f)->fr.func, (p)))
56
57/* -- C stack frame ------------------------------------------------------- */
58
59/* Macros to access and modify the C stack frame chain. */
60
61/* These definitions must match with the arch-specific *.dasc files. */
62#if LJ_TARGET_X86
63#define CFRAME_OFS_ERRF (15*4)
64#define CFRAME_OFS_NRES (14*4)
65#define CFRAME_OFS_PREV (13*4)
66#define CFRAME_OFS_L (12*4)
67#define CFRAME_OFS_PC (6*4)
68#define CFRAME_OFS_MULTRES (5*4)
69#define CFRAME_SIZE (12*4)
70#define CFRAME_SHIFT_MULTRES 0
71#elif LJ_TARGET_X64
72#if LJ_ABI_WIN
73#define CFRAME_OFS_PREV (13*8)
74#define CFRAME_OFS_PC (25*4)
75#define CFRAME_OFS_L (24*4)
76#define CFRAME_OFS_ERRF (23*4)
77#define CFRAME_OFS_NRES (22*4)
78#define CFRAME_OFS_MULTRES (21*4)
79#define CFRAME_SIZE (10*8)
80#define CFRAME_SIZE_JIT (CFRAME_SIZE + 9*16 + 4*8)
81#define CFRAME_SHIFT_MULTRES 0
82#else
83#define CFRAME_OFS_PREV (4*8)
84#define CFRAME_OFS_PC (7*4)
85#define CFRAME_OFS_L (6*4)
86#define CFRAME_OFS_ERRF (5*4)
87#define CFRAME_OFS_NRES (4*4)
88#define CFRAME_OFS_MULTRES (1*4)
89#define CFRAME_SIZE (10*8)
90#define CFRAME_SIZE_JIT (CFRAME_SIZE + 16)
91#define CFRAME_SHIFT_MULTRES 0
92#endif
93#elif LJ_TARGET_ARM
94#define CFRAME_OFS_ERRF 24
95#define CFRAME_OFS_NRES 20
96#define CFRAME_OFS_PREV 16
97#define CFRAME_OFS_L 12
98#define CFRAME_OFS_PC 8
99#define CFRAME_OFS_MULTRES 4
100#define CFRAME_SIZE 64
101#define CFRAME_SHIFT_MULTRES 3
102#elif LJ_TARGET_PPC
103#define CFRAME_OFS_ERRF 48
104#define CFRAME_OFS_NRES 44
105#define CFRAME_OFS_PREV 40
106#define CFRAME_OFS_L 36
107#define CFRAME_OFS_PC 32
108#define CFRAME_OFS_MULTRES 28
109#define CFRAME_SIZE 272
110#define CFRAME_SHIFT_MULTRES 3
111#elif LJ_TARGET_PPCSPE
112#define CFRAME_OFS_ERRF 28
113#define CFRAME_OFS_NRES 24
114#define CFRAME_OFS_PREV 20
115#define CFRAME_OFS_L 16
116#define CFRAME_OFS_PC 12
117#define CFRAME_OFS_MULTRES 8
118#define CFRAME_SIZE 184
119#define CFRAME_SHIFT_MULTRES 3
120#elif LJ_TARGET_MIPS
121/* NYI: Dummy definitions for now. */
122#define CFRAME_OFS_ERRF 0
123#define CFRAME_OFS_NRES 0
124#define CFRAME_OFS_PREV 0
125#define CFRAME_OFS_L 0
126#define CFRAME_OFS_PC 0
127#define CFRAME_OFS_MULTRES 0
128#define CFRAME_SIZE 256
129#define CFRAME_SHIFT_MULTRES 3
130#else
131#error "Missing CFRAME_* definitions for this architecture"
132#endif
133
134#ifndef CFRAME_SIZE_JIT
135#define CFRAME_SIZE_JIT CFRAME_SIZE
136#endif
137
138#define CFRAME_RESUME 1
139#define CFRAME_UNWIND_FF 2 /* Only used in unwinder. */
140#define CFRAME_RAWMASK (~(intptr_t)(CFRAME_RESUME|CFRAME_UNWIND_FF))
141
142#define cframe_errfunc(cf) (*(int32_t *)(((char *)(cf))+CFRAME_OFS_ERRF))
143#define cframe_nres(cf) (*(int32_t *)(((char *)(cf))+CFRAME_OFS_NRES))
144#define cframe_prev(cf) (*(void **)(((char *)(cf))+CFRAME_OFS_PREV))
145#define cframe_multres(cf) (*(uint32_t *)(((char *)(cf))+CFRAME_OFS_MULTRES))
146#define cframe_multres_n(cf) (cframe_multres((cf)) >> CFRAME_SHIFT_MULTRES)
147#define cframe_L(cf) \
148 (&gcref(*(GCRef *)(((char *)(cf))+CFRAME_OFS_L))->th)
149#define cframe_pc(cf) \
150 (mref(*(MRef *)(((char *)(cf))+CFRAME_OFS_PC), const BCIns))
151#define setcframe_L(cf, L) \
152 (setmref(*(MRef *)(((char *)(cf))+CFRAME_OFS_L), (L)))
153#define setcframe_pc(cf, pc) \
154 (setmref(*(MRef *)(((char *)(cf))+CFRAME_OFS_PC), (pc)))
155#define cframe_canyield(cf) ((intptr_t)(cf) & CFRAME_RESUME)
156#define cframe_unwind_ff(cf) ((intptr_t)(cf) & CFRAME_UNWIND_FF)
157#define cframe_raw(cf) ((void *)((intptr_t)(cf) & CFRAME_RAWMASK))
158#define cframe_Lpc(L) cframe_pc(cframe_raw(L->cframe))
159
160#endif
diff --git a/libraries/luajit-2.0/src/lj_func.c b/libraries/luajit-2.0/src/lj_func.c
new file mode 100644
index 0000000..97be0a2
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_func.c
@@ -0,0 +1,184 @@
1/*
2** Function handling (prototypes, functions and upvalues).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lj_func_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13#include "lj_gc.h"
14#include "lj_func.h"
15#include "lj_trace.h"
16#include "lj_vm.h"
17
18/* -- Prototypes ---------------------------------------------------------- */
19
20void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt)
21{
22 lj_mem_free(g, pt, pt->sizept);
23}
24
25/* -- Upvalues ------------------------------------------------------------ */
26
27static void unlinkuv(GCupval *uv)
28{
29 lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv);
30 setgcrefr(uvnext(uv)->prev, uv->prev);
31 setgcrefr(uvprev(uv)->next, uv->next);
32}
33
34/* Find existing open upvalue for a stack slot or create a new one. */
35static GCupval *func_finduv(lua_State *L, TValue *slot)
36{
37 global_State *g = G(L);
38 GCRef *pp = &L->openupval;
39 GCupval *p;
40 GCupval *uv;
41 /* Search the sorted list of open upvalues. */
42 while (gcref(*pp) != NULL && uvval((p = gco2uv(gcref(*pp)))) >= slot) {
43 lua_assert(!p->closed && uvval(p) != &p->tv);
44 if (uvval(p) == slot) { /* Found open upvalue pointing to same slot? */
45 if (isdead(g, obj2gco(p))) /* Resurrect it, if it's dead. */
46 flipwhite(obj2gco(p));
47 return p;
48 }
49 pp = &p->nextgc;
50 }
51 /* No matching upvalue found. Create a new one. */
52 uv = lj_mem_newt(L, sizeof(GCupval), GCupval);
53 newwhite(g, uv);
54 uv->gct = ~LJ_TUPVAL;
55 uv->closed = 0; /* Still open. */
56 setmref(uv->v, slot); /* Pointing to the stack slot. */
57 /* NOBARRIER: The GCupval is new (marked white) and open. */
58 setgcrefr(uv->nextgc, *pp); /* Insert into sorted list of open upvalues. */
59 setgcref(*pp, obj2gco(uv));
60 setgcref(uv->prev, obj2gco(&g->uvhead)); /* Insert into GC list, too. */
61 setgcrefr(uv->next, g->uvhead.next);
62 setgcref(uvnext(uv)->prev, obj2gco(uv));
63 setgcref(g->uvhead.next, obj2gco(uv));
64 lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv);
65 return uv;
66}
67
68/* Create an empty and closed upvalue. */
69static GCupval *func_emptyuv(lua_State *L)
70{
71 GCupval *uv = (GCupval *)lj_mem_newgco(L, sizeof(GCupval));
72 uv->gct = ~LJ_TUPVAL;
73 uv->closed = 1;
74 setnilV(&uv->tv);
75 setmref(uv->v, &uv->tv);
76 return uv;
77}
78
79/* Close all open upvalues pointing to some stack level or above. */
80void LJ_FASTCALL lj_func_closeuv(lua_State *L, TValue *level)
81{
82 GCupval *uv;
83 global_State *g = G(L);
84 while (gcref(L->openupval) != NULL &&
85 uvval((uv = gco2uv(gcref(L->openupval)))) >= level) {
86 GCobj *o = obj2gco(uv);
87 lua_assert(!isblack(o) && !uv->closed && uvval(uv) != &uv->tv);
88 setgcrefr(L->openupval, uv->nextgc); /* No longer in open list. */
89 if (isdead(g, o)) {
90 lj_func_freeuv(g, uv);
91 } else {
92 unlinkuv(uv);
93 lj_gc_closeuv(g, uv);
94 }
95 }
96}
97
98void LJ_FASTCALL lj_func_freeuv(global_State *g, GCupval *uv)
99{
100 if (!uv->closed)
101 unlinkuv(uv);
102 lj_mem_freet(g, uv);
103}
104
105/* -- Functions (closures) ------------------------------------------------ */
106
107GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env)
108{
109 GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeCfunc(nelems));
110 fn->c.gct = ~LJ_TFUNC;
111 fn->c.ffid = FF_C;
112 fn->c.nupvalues = (uint8_t)nelems;
113 /* NOBARRIER: The GCfunc is new (marked white). */
114 setmref(fn->c.pc, &G(L)->bc_cfunc_ext);
115 setgcref(fn->c.env, obj2gco(env));
116 return fn;
117}
118
119static GCfunc *func_newL(lua_State *L, GCproto *pt, GCtab *env)
120{
121 uint32_t count;
122 GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv));
123 fn->l.gct = ~LJ_TFUNC;
124 fn->l.ffid = FF_LUA;
125 fn->l.nupvalues = 0; /* Set to zero until upvalues are initialized. */
126 /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */
127 setmref(fn->l.pc, proto_bc(pt));
128 setgcref(fn->l.env, obj2gco(env));
129 /* Saturating 3 bit counter (0..7) for created closures. */
130 count = (uint32_t)pt->flags + PROTO_CLCOUNT;
131 pt->flags = (uint8_t)(count - ((count >> PROTO_CLC_BITS) & PROTO_CLCOUNT));
132 return fn;
133}
134
135/* Create a new Lua function with empty upvalues. */
136GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env)
137{
138 GCfunc *fn = func_newL(L, pt, env);
139 MSize i, nuv = pt->sizeuv;
140 /* NOBARRIER: The GCfunc is new (marked white). */
141 for (i = 0; i < nuv; i++) {
142 GCupval *uv = func_emptyuv(L);
143 uv->dhash = (uint32_t)(uintptr_t)pt ^ ((uint32_t)proto_uv(pt)[i] << 24);
144 setgcref(fn->l.uvptr[i], obj2gco(uv));
145 }
146 fn->l.nupvalues = (uint8_t)nuv;
147 return fn;
148}
149
150/* Do a GC check and create a new Lua function with inherited upvalues. */
151GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent)
152{
153 GCfunc *fn;
154 GCRef *puv;
155 MSize i, nuv;
156 TValue *base;
157 lj_gc_check_fixtop(L);
158 fn = func_newL(L, pt, tabref(parent->env));
159 /* NOBARRIER: The GCfunc is new (marked white). */
160 puv = parent->uvptr;
161 nuv = pt->sizeuv;
162 base = L->base;
163 for (i = 0; i < nuv; i++) {
164 uint32_t v = proto_uv(pt)[i];
165 GCupval *uv;
166 if ((v & 0x8000)) {
167 uv = func_finduv(L, base + (v & 0xff));
168 uv->dhash = (uint32_t)(uintptr_t)mref(parent->pc, char) ^ (v << 24);
169 } else {
170 uv = &gcref(puv[v])->uv;
171 }
172 setgcref(fn->l.uvptr[i], obj2gco(uv));
173 }
174 fn->l.nupvalues = (uint8_t)nuv;
175 return fn;
176}
177
178void LJ_FASTCALL lj_func_free(global_State *g, GCfunc *fn)
179{
180 MSize size = isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) :
181 sizeCfunc((MSize)fn->c.nupvalues);
182 lj_mem_free(g, fn, size);
183}
184
diff --git a/libraries/luajit-2.0/src/lj_func.h b/libraries/luajit-2.0/src/lj_func.h
new file mode 100644
index 0000000..6ec4ab9
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_func.h
@@ -0,0 +1,24 @@
1/*
2** Function handling (prototypes, functions and upvalues).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_FUNC_H
7#define _LJ_FUNC_H
8
9#include "lj_obj.h"
10
11/* Prototypes. */
12LJ_FUNC void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt);
13
14/* Upvalues. */
15LJ_FUNCA void LJ_FASTCALL lj_func_closeuv(lua_State *L, TValue *level);
16LJ_FUNC void LJ_FASTCALL lj_func_freeuv(global_State *g, GCupval *uv);
17
18/* Functions (closures). */
19LJ_FUNC GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env);
20LJ_FUNC GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env);
21LJ_FUNCA GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent);
22LJ_FUNC void LJ_FASTCALL lj_func_free(global_State *g, GCfunc *c);
23
24#endif
diff --git a/libraries/luajit-2.0/src/lj_gc.c b/libraries/luajit-2.0/src/lj_gc.c
new file mode 100644
index 0000000..1985abc
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_gc.c
@@ -0,0 +1,838 @@
1/*
2** Garbage collector.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lj_gc_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_str.h"
16#include "lj_tab.h"
17#include "lj_func.h"
18#include "lj_udata.h"
19#include "lj_meta.h"
20#include "lj_state.h"
21#include "lj_frame.h"
22#if LJ_HASFFI
23#include "lj_ctype.h"
24#include "lj_cdata.h"
25#endif
26#include "lj_trace.h"
27#include "lj_vm.h"
28
29#define GCSTEPSIZE 1024u
30#define GCSWEEPMAX 40
31#define GCSWEEPCOST 10
32#define GCFINALIZECOST 100
33
34/* Macros to set GCobj colors and flags. */
35#define white2gray(x) ((x)->gch.marked &= (uint8_t)~LJ_GC_WHITES)
36#define gray2black(x) ((x)->gch.marked |= LJ_GC_BLACK)
37#define isfinalized(u) ((u)->marked & LJ_GC_FINALIZED)
38#define markfinalized(u) ((u)->marked |= LJ_GC_FINALIZED)
39
40/* -- Mark phase ---------------------------------------------------------- */
41
42/* Mark a TValue (if needed). */
43#define gc_marktv(g, tv) \
44 { lua_assert(!tvisgcv(tv) || (~itype(tv) == gcval(tv)->gch.gct)); \
45 if (tviswhite(tv)) gc_mark(g, gcV(tv)); }
46
47/* Mark a GCobj (if needed). */
48#define gc_markobj(g, o) \
49 { if (iswhite(obj2gco(o))) gc_mark(g, obj2gco(o)); }
50
51/* Mark a string object. */
52#define gc_mark_str(s) ((s)->marked &= (uint8_t)~LJ_GC_WHITES)
53
54/* Mark a white GCobj. */
55static void gc_mark(global_State *g, GCobj *o)
56{
57 lua_assert(iswhite(o) && !isdead(g, o));
58 white2gray(o);
59 if (LJ_UNLIKELY(o->gch.gct == ~LJ_TUDATA)) {
60 GCtab *mt = tabref(gco2ud(o)->metatable);
61 gray2black(o); /* Userdata are never gray. */
62 if (mt) gc_markobj(g, mt);
63 gc_markobj(g, tabref(gco2ud(o)->env));
64 } else if (LJ_UNLIKELY(o->gch.gct == ~LJ_TUPVAL)) {
65 GCupval *uv = gco2uv(o);
66 gc_marktv(g, uvval(uv));
67 if (uv->closed)
68 gray2black(o); /* Closed upvalues are never gray. */
69 } else if (o->gch.gct != ~LJ_TSTR && o->gch.gct != ~LJ_TCDATA) {
70 lua_assert(o->gch.gct == ~LJ_TFUNC || o->gch.gct == ~LJ_TTAB ||
71 o->gch.gct == ~LJ_TTHREAD || o->gch.gct == ~LJ_TPROTO);
72 setgcrefr(o->gch.gclist, g->gc.gray);
73 setgcref(g->gc.gray, o);
74 }
75}
76
77/* Mark GC roots. */
78static void gc_mark_gcroot(global_State *g)
79{
80 ptrdiff_t i;
81 for (i = 0; i < GCROOT_MAX; i++)
82 if (gcref(g->gcroot[i]) != NULL)
83 gc_markobj(g, gcref(g->gcroot[i]));
84}
85
86/* Start a GC cycle and mark the root set. */
87static void gc_mark_start(global_State *g)
88{
89 setgcrefnull(g->gc.gray);
90 setgcrefnull(g->gc.grayagain);
91 setgcrefnull(g->gc.weak);
92 gc_markobj(g, mainthread(g));
93 gc_markobj(g, tabref(mainthread(g)->env));
94 gc_marktv(g, &g->registrytv);
95 gc_mark_gcroot(g);
96 g->gc.state = GCSpropagate;
97}
98
99/* Mark open upvalues. */
100static void gc_mark_uv(global_State *g)
101{
102 GCupval *uv;
103 for (uv = uvnext(&g->uvhead); uv != &g->uvhead; uv = uvnext(uv)) {
104 lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv);
105 if (isgray(obj2gco(uv)))
106 gc_marktv(g, uvval(uv));
107 }
108}
109
110/* Mark userdata in mmudata list. */
111static void gc_mark_mmudata(global_State *g)
112{
113 GCobj *root = gcref(g->gc.mmudata);
114 GCobj *u = root;
115 if (u) {
116 do {
117 u = gcnext(u);
118 makewhite(g, u); /* Could be from previous GC. */
119 gc_mark(g, u);
120 } while (u != root);
121 }
122}
123
124/* Separate userdata which which needs finalization to mmudata list. */
125size_t lj_gc_separateudata(global_State *g, int all)
126{
127 size_t m = 0;
128 GCRef *p = &mainthread(g)->nextgc;
129 GCobj *o;
130 while ((o = gcref(*p)) != NULL) {
131 if (!(iswhite(o) || all) || isfinalized(gco2ud(o))) {
132 p = &o->gch.nextgc; /* Nothing to do. */
133 } else if (!lj_meta_fastg(g, tabref(gco2ud(o)->metatable), MM_gc)) {
134 markfinalized(gco2ud(o)); /* Done, as there's no __gc metamethod. */
135 p = &o->gch.nextgc;
136 } else { /* Otherwise move userdata to be finalized to mmudata list. */
137 m += sizeudata(gco2ud(o));
138 markfinalized(gco2ud(o));
139 *p = o->gch.nextgc;
140 if (gcref(g->gc.mmudata)) { /* Link to end of mmudata list. */
141 GCobj *root = gcref(g->gc.mmudata);
142 setgcrefr(o->gch.nextgc, root->gch.nextgc);
143 setgcref(root->gch.nextgc, o);
144 setgcref(g->gc.mmudata, o);
145 } else { /* Create circular list. */
146 setgcref(o->gch.nextgc, o);
147 setgcref(g->gc.mmudata, o);
148 }
149 }
150 }
151 return m;
152}
153
154/* -- Propagation phase --------------------------------------------------- */
155
156/* Traverse a table. */
157static int gc_traverse_tab(global_State *g, GCtab *t)
158{
159 int weak = 0;
160 cTValue *mode;
161 GCtab *mt = tabref(t->metatable);
162 if (mt)
163 gc_markobj(g, mt);
164 mode = lj_meta_fastg(g, mt, MM_mode);
165 if (mode && tvisstr(mode)) { /* Valid __mode field? */
166 const char *modestr = strVdata(mode);
167 int c;
168 while ((c = *modestr++)) {
169 if (c == 'k') weak |= LJ_GC_WEAKKEY;
170 else if (c == 'v') weak |= LJ_GC_WEAKVAL;
171 else if (c == 'K') weak = (int)(~0u & ~LJ_GC_WEAKVAL);
172 }
173 if (weak > 0) { /* Weak tables are cleared in the atomic phase. */
174 t->marked = (uint8_t)((t->marked & ~LJ_GC_WEAK) | weak);
175 setgcrefr(t->gclist, g->gc.weak);
176 setgcref(g->gc.weak, obj2gco(t));
177 }
178 }
179 if (weak == LJ_GC_WEAK) /* Nothing to mark if both keys/values are weak. */
180 return 1;
181 if (!(weak & LJ_GC_WEAKVAL)) { /* Mark array part. */
182 MSize i, asize = t->asize;
183 for (i = 0; i < asize; i++)
184 gc_marktv(g, arrayslot(t, i));
185 }
186 if (t->hmask > 0) { /* Mark hash part. */
187 Node *node = noderef(t->node);
188 MSize i, hmask = t->hmask;
189 for (i = 0; i <= hmask; i++) {
190 Node *n = &node[i];
191 if (!tvisnil(&n->val)) { /* Mark non-empty slot. */
192 lua_assert(!tvisnil(&n->key));
193 if (!(weak & LJ_GC_WEAKKEY)) gc_marktv(g, &n->key);
194 if (!(weak & LJ_GC_WEAKVAL)) gc_marktv(g, &n->val);
195 }
196 }
197 }
198 return weak;
199}
200
201/* Traverse a function. */
202static void gc_traverse_func(global_State *g, GCfunc *fn)
203{
204 gc_markobj(g, tabref(fn->c.env));
205 if (isluafunc(fn)) {
206 uint32_t i;
207 lua_assert(fn->l.nupvalues <= funcproto(fn)->sizeuv);
208 gc_markobj(g, funcproto(fn));
209 for (i = 0; i < fn->l.nupvalues; i++) /* Mark Lua function upvalues. */
210 gc_markobj(g, &gcref(fn->l.uvptr[i])->uv);
211 } else {
212 uint32_t i;
213 for (i = 0; i < fn->c.nupvalues; i++) /* Mark C function upvalues. */
214 gc_marktv(g, &fn->c.upvalue[i]);
215 }
216}
217
218#if LJ_HASJIT
219/* Mark a trace. */
220static void gc_marktrace(global_State *g, TraceNo traceno)
221{
222 GCobj *o = obj2gco(traceref(G2J(g), traceno));
223 lua_assert(traceno != G2J(g)->cur.traceno);
224 if (iswhite(o)) {
225 white2gray(o);
226 setgcrefr(o->gch.gclist, g->gc.gray);
227 setgcref(g->gc.gray, o);
228 }
229}
230
231/* Traverse a trace. */
232static void gc_traverse_trace(global_State *g, GCtrace *T)
233{
234 IRRef ref;
235 if (T->traceno == 0) return;
236 for (ref = T->nk; ref < REF_TRUE; ref++) {
237 IRIns *ir = &T->ir[ref];
238 if (ir->o == IR_KGC)
239 gc_markobj(g, ir_kgc(ir));
240 }
241 if (T->link) gc_marktrace(g, T->link);
242 if (T->nextroot) gc_marktrace(g, T->nextroot);
243 if (T->nextside) gc_marktrace(g, T->nextside);
244 gc_markobj(g, gcref(T->startpt));
245}
246
247/* The current trace is a GC root while not anchored in the prototype (yet). */
248#define gc_traverse_curtrace(g) gc_traverse_trace(g, &G2J(g)->cur)
249#else
250#define gc_traverse_curtrace(g) UNUSED(g)
251#endif
252
253/* Traverse a prototype. */
254static void gc_traverse_proto(global_State *g, GCproto *pt)
255{
256 ptrdiff_t i;
257 gc_mark_str(proto_chunkname(pt));
258 for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */
259 gc_markobj(g, proto_kgc(pt, i));
260#if LJ_HASJIT
261 if (pt->trace) gc_marktrace(g, pt->trace);
262#endif
263}
264
265/* Traverse the frame structure of a stack. */
266static MSize gc_traverse_frames(global_State *g, lua_State *th)
267{
268 TValue *frame, *top = th->top-1, *bot = tvref(th->stack);
269 /* Note: extra vararg frame not skipped, marks function twice (harmless). */
270 for (frame = th->base-1; frame > bot; frame = frame_prev(frame)) {
271 GCfunc *fn = frame_func(frame);
272 TValue *ftop = frame;
273 if (isluafunc(fn)) ftop += funcproto(fn)->framesize;
274 if (ftop > top) top = ftop;
275 gc_markobj(g, fn); /* Need to mark hidden function (or L). */
276 }
277 top++; /* Correct bias of -1 (frame == base-1). */
278 if (top > tvref(th->maxstack)) top = tvref(th->maxstack);
279 return (MSize)(top - bot); /* Return minimum needed stack size. */
280}
281
282/* Traverse a thread object. */
283static void gc_traverse_thread(global_State *g, lua_State *th)
284{
285 TValue *o, *top = th->top;
286 for (o = tvref(th->stack)+1; o < top; o++)
287 gc_marktv(g, o);
288 if (g->gc.state == GCSatomic) {
289 top = tvref(th->stack) + th->stacksize;
290 for (; o < top; o++) /* Clear unmarked slots. */
291 setnilV(o);
292 }
293 gc_markobj(g, tabref(th->env));
294 lj_state_shrinkstack(th, gc_traverse_frames(g, th));
295}
296
297/* Propagate one gray object. Traverse it and turn it black. */
298static size_t propagatemark(global_State *g)
299{
300 GCobj *o = gcref(g->gc.gray);
301 lua_assert(isgray(o));
302 gray2black(o);
303 setgcrefr(g->gc.gray, o->gch.gclist); /* Remove from gray list. */
304 if (LJ_LIKELY(o->gch.gct == ~LJ_TTAB)) {
305 GCtab *t = gco2tab(o);
306 if (gc_traverse_tab(g, t) > 0)
307 black2gray(o); /* Keep weak tables gray. */
308 return sizeof(GCtab) + sizeof(TValue) * t->asize +
309 sizeof(Node) * (t->hmask + 1);
310 } else if (LJ_LIKELY(o->gch.gct == ~LJ_TFUNC)) {
311 GCfunc *fn = gco2func(o);
312 gc_traverse_func(g, fn);
313 return isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) :
314 sizeCfunc((MSize)fn->c.nupvalues);
315 } else if (LJ_LIKELY(o->gch.gct == ~LJ_TPROTO)) {
316 GCproto *pt = gco2pt(o);
317 gc_traverse_proto(g, pt);
318 return pt->sizept;
319 } else if (LJ_LIKELY(o->gch.gct == ~LJ_TTHREAD)) {
320 lua_State *th = gco2th(o);
321 setgcrefr(th->gclist, g->gc.grayagain);
322 setgcref(g->gc.grayagain, o);
323 black2gray(o); /* Threads are never black. */
324 gc_traverse_thread(g, th);
325 return sizeof(lua_State) + sizeof(TValue) * th->stacksize;
326 } else {
327#if LJ_HASJIT
328 GCtrace *T = gco2trace(o);
329 gc_traverse_trace(g, T);
330 return ((sizeof(GCtrace)+7)&~7) + (T->nins-T->nk)*sizeof(IRIns) +
331 T->nsnap*sizeof(SnapShot) + T->nsnapmap*sizeof(SnapEntry);
332#else
333 lua_assert(0);
334 return 0;
335#endif
336 }
337}
338
339/* Propagate all gray objects. */
340static size_t gc_propagate_gray(global_State *g)
341{
342 size_t m = 0;
343 while (gcref(g->gc.gray) != NULL)
344 m += propagatemark(g);
345 return m;
346}
347
348/* -- Sweep phase --------------------------------------------------------- */
349
350/* Try to shrink some common data structures. */
351static void gc_shrink(global_State *g, lua_State *L)
352{
353 if (g->strnum <= (g->strmask >> 2) && g->strmask > LJ_MIN_STRTAB*2-1)
354 lj_str_resize(L, g->strmask >> 1); /* Shrink string table. */
355 if (g->tmpbuf.sz > LJ_MIN_SBUF*2)
356 lj_str_resizebuf(L, &g->tmpbuf, g->tmpbuf.sz >> 1); /* Shrink temp buf. */
357}
358
359/* Type of GC free functions. */
360typedef void (LJ_FASTCALL *GCFreeFunc)(global_State *g, GCobj *o);
361
362/* GC free functions for LJ_TSTR .. LJ_TUDATA. ORDER LJ_T */
363static const GCFreeFunc gc_freefunc[] = {
364 (GCFreeFunc)lj_str_free,
365 (GCFreeFunc)lj_func_freeuv,
366 (GCFreeFunc)lj_state_free,
367 (GCFreeFunc)lj_func_freeproto,
368 (GCFreeFunc)lj_func_free,
369#if LJ_HASJIT
370 (GCFreeFunc)lj_trace_free,
371#else
372 (GCFreeFunc)0,
373#endif
374#if LJ_HASFFI
375 (GCFreeFunc)lj_cdata_free,
376#else
377 (GCFreeFunc)0,
378#endif
379 (GCFreeFunc)lj_tab_free,
380 (GCFreeFunc)lj_udata_free
381};
382
383/* Full sweep of a GC list. */
384#define gc_fullsweep(g, p) gc_sweep(g, (p), LJ_MAX_MEM)
385
386/* Partial sweep of a GC list. */
387static GCRef *gc_sweep(global_State *g, GCRef *p, uint32_t lim)
388{
389 /* Mask with other white and LJ_GC_FIXED. Or LJ_GC_SFIXED on shutdown. */
390 int ow = otherwhite(g);
391 GCobj *o;
392 while ((o = gcref(*p)) != NULL && lim-- > 0) {
393 if (o->gch.gct == ~LJ_TTHREAD) /* Need to sweep open upvalues, too. */
394 gc_fullsweep(g, &gco2th(o)->openupval);
395 if (((o->gch.marked ^ LJ_GC_WHITES) & ow)) { /* Black or current white? */
396 lua_assert(!isdead(g, o) || (o->gch.marked & LJ_GC_FIXED));
397 makewhite(g, o); /* Value is alive, change to the current white. */
398 p = &o->gch.nextgc;
399 } else { /* Otherwise value is dead, free it. */
400 lua_assert(isdead(g, o) || ow == LJ_GC_SFIXED);
401 setgcrefr(*p, o->gch.nextgc);
402 if (o == gcref(g->gc.root))
403 setgcrefr(g->gc.root, o->gch.nextgc); /* Adjust list anchor. */
404 gc_freefunc[o->gch.gct - ~LJ_TSTR](g, o);
405 }
406 }
407 return p;
408}
409
410/* Check whether we can clear a key or a value slot from a table. */
411static int gc_mayclear(cTValue *o, int val)
412{
413 if (tvisgcv(o)) { /* Only collectable objects can be weak references. */
414 if (tvisstr(o)) { /* But strings cannot be used as weak references. */
415 gc_mark_str(strV(o)); /* And need to be marked. */
416 return 0;
417 }
418 if (iswhite(gcV(o)))
419 return 1; /* Object is about to be collected. */
420 if (tvisudata(o) && val && isfinalized(udataV(o)))
421 return 1; /* Finalized userdata is dropped only from values. */
422 }
423 return 0; /* Cannot clear. */
424}
425
426/* Clear collected entries from weak tables. */
427static void gc_clearweak(GCobj *o)
428{
429 while (o) {
430 GCtab *t = gco2tab(o);
431 lua_assert((t->marked & LJ_GC_WEAK));
432 if ((t->marked & LJ_GC_WEAKVAL)) {
433 MSize i, asize = t->asize;
434 for (i = 0; i < asize; i++) {
435 /* Clear array slot when value is about to be collected. */
436 TValue *tv = arrayslot(t, i);
437 if (gc_mayclear(tv, 1))
438 setnilV(tv);
439 }
440 }
441 if (t->hmask > 0) {
442 Node *node = noderef(t->node);
443 MSize i, hmask = t->hmask;
444 for (i = 0; i <= hmask; i++) {
445 Node *n = &node[i];
446 /* Clear hash slot when key or value is about to be collected. */
447 if (!tvisnil(&n->val) && (gc_mayclear(&n->key, 0) ||
448 gc_mayclear(&n->val, 1)))
449 setnilV(&n->val);
450 }
451 }
452 o = gcref(t->gclist);
453 }
454}
455
456/* Call a userdata or cdata finalizer. */
457static void gc_call_finalizer(global_State *g, lua_State *L,
458 cTValue *mo, GCobj *o)
459{
460 /* Save and restore lots of state around the __gc callback. */
461 uint8_t oldh = hook_save(g);
462 MSize oldt = g->gc.threshold;
463 int errcode;
464 TValue *top;
465 lj_trace_abort(g);
466 top = L->top;
467 L->top = top+2;
468 hook_entergc(g); /* Disable hooks and new traces during __gc. */
469 g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */
470 copyTV(L, top, mo);
471 setgcV(L, top+1, o, ~o->gch.gct);
472 errcode = lj_vm_pcall(L, top+1, 1+0, -1); /* Stack: |mo|o| -> | */
473 hook_restore(g, oldh);
474 g->gc.threshold = oldt; /* Restore GC threshold. */
475 if (errcode)
476 lj_err_throw(L, errcode); /* Propagate errors. */
477}
478
479/* Finalize one userdata or cdata object from the mmudata list. */
480static void gc_finalize(lua_State *L)
481{
482 global_State *g = G(L);
483 GCobj *o = gcnext(gcref(g->gc.mmudata));
484 cTValue *mo;
485 lua_assert(gcref(g->jit_L) == NULL); /* Must not be called on trace. */
486 /* Unchain from list of userdata to be finalized. */
487 if (o == gcref(g->gc.mmudata))
488 setgcrefnull(g->gc.mmudata);
489 else
490 setgcrefr(gcref(g->gc.mmudata)->gch.nextgc, o->gch.nextgc);
491#if LJ_HASFFI
492 if (o->gch.gct == ~LJ_TCDATA) {
493 TValue tmp, *tv;
494 /* Add cdata back to the GC list and make it white. */
495 setgcrefr(o->gch.nextgc, g->gc.root);
496 setgcref(g->gc.root, o);
497 makewhite(g, o);
498 o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
499 /* Resolve finalizer. */
500 setcdataV(L, &tmp, gco2cd(o));
501 tv = lj_tab_set(L, ctype_ctsG(g)->finalizer, &tmp);
502 if (!tvisnil(tv)) {
503 copyTV(L, &tmp, tv);
504 setnilV(tv); /* Clear entry in finalizer table. */
505 gc_call_finalizer(g, L, &tmp, o);
506 }
507 return;
508 }
509#endif
510 /* Add userdata back to the main userdata list and make it white. */
511 setgcrefr(o->gch.nextgc, mainthread(g)->nextgc);
512 setgcref(mainthread(g)->nextgc, o);
513 makewhite(g, o);
514 /* Resolve the __gc metamethod. */
515 mo = lj_meta_fastg(g, tabref(gco2ud(o)->metatable), MM_gc);
516 if (mo)
517 gc_call_finalizer(g, L, mo, o);
518}
519
520/* Finalize all userdata objects from mmudata list. */
521void lj_gc_finalize_udata(lua_State *L)
522{
523 while (gcref(G(L)->gc.mmudata) != NULL)
524 gc_finalize(L);
525}
526
527#if LJ_HASFFI
528/* Finalize all cdata objects from finalizer table. */
529void lj_gc_finalize_cdata(lua_State *L)
530{
531 global_State *g = G(L);
532 CTState *cts = ctype_ctsG(g);
533 if (cts) {
534 GCtab *t = cts->finalizer;
535 Node *node = noderef(t->node);
536 ptrdiff_t i;
537 setgcrefnull(t->metatable); /* Mark finalizer table as disabled. */
538 for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
539 if (!tvisnil(&node[i].val) && tviscdata(&node[i].key)) {
540 GCobj *o = gcV(&node[i].key);
541 TValue tmp;
542 makewhite(g, o);
543 o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
544 copyTV(L, &tmp, &node[i].val);
545 setnilV(&node[i].val);
546 gc_call_finalizer(g, L, &tmp, o);
547 }
548 }
549}
550#endif
551
552/* Free all remaining GC objects. */
553void lj_gc_freeall(global_State *g)
554{
555 MSize i, strmask;
556 /* Free everything, except super-fixed objects (the main thread). */
557 g->gc.currentwhite = LJ_GC_WHITES | LJ_GC_SFIXED;
558 gc_fullsweep(g, &g->gc.root);
559 strmask = g->strmask;
560 for (i = 0; i <= strmask; i++) /* Free all string hash chains. */
561 gc_fullsweep(g, &g->strhash[i]);
562}
563
564/* -- Collector ----------------------------------------------------------- */
565
566/* Atomic part of the GC cycle, transitioning from mark to sweep phase. */
567static void atomic(global_State *g, lua_State *L)
568{
569 size_t udsize;
570
571 gc_mark_uv(g); /* Need to remark open upvalues (the thread may be dead). */
572 gc_propagate_gray(g); /* Propagate any left-overs. */
573
574 setgcrefr(g->gc.gray, g->gc.weak); /* Empty the list of weak tables. */
575 setgcrefnull(g->gc.weak);
576 lua_assert(!iswhite(obj2gco(mainthread(g))));
577 gc_markobj(g, L); /* Mark running thread. */
578 gc_traverse_curtrace(g); /* Traverse current trace. */
579 gc_mark_gcroot(g); /* Mark GC roots (again). */
580 gc_propagate_gray(g); /* Propagate all of the above. */
581
582 setgcrefr(g->gc.gray, g->gc.grayagain); /* Empty the 2nd chance list. */
583 setgcrefnull(g->gc.grayagain);
584 gc_propagate_gray(g); /* Propagate it. */
585
586 udsize = lj_gc_separateudata(g, 0); /* Separate userdata to be finalized. */
587 gc_mark_mmudata(g); /* Mark them. */
588 udsize += gc_propagate_gray(g); /* And propagate the marks. */
589
590 /* All marking done, clear weak tables. */
591 gc_clearweak(gcref(g->gc.weak));
592
593 /* Prepare for sweep phase. */
594 g->gc.currentwhite = (uint8_t)otherwhite(g); /* Flip current white. */
595 g->strempty.marked = g->gc.currentwhite;
596 setmref(g->gc.sweep, &g->gc.root);
597 g->gc.estimate = g->gc.total - (MSize)udsize; /* Initial estimate. */
598}
599
600/* GC state machine. Returns a cost estimate for each step performed. */
601static size_t gc_onestep(lua_State *L)
602{
603 global_State *g = G(L);
604 switch (g->gc.state) {
605 case GCSpause:
606 gc_mark_start(g); /* Start a new GC cycle by marking all GC roots. */
607 return 0;
608 case GCSpropagate:
609 if (gcref(g->gc.gray) != NULL)
610 return propagatemark(g); /* Propagate one gray object. */
611 g->gc.state = GCSatomic; /* End of mark phase. */
612 return 0;
613 case GCSatomic:
614 if (gcref(g->jit_L)) /* Don't run atomic phase on trace. */
615 return LJ_MAX_MEM;
616 atomic(g, L);
617 g->gc.state = GCSsweepstring; /* Start of sweep phase. */
618 g->gc.sweepstr = 0;
619 return 0;
620 case GCSsweepstring: {
621 MSize old = g->gc.total;
622 gc_fullsweep(g, &g->strhash[g->gc.sweepstr++]); /* Sweep one chain. */
623 if (g->gc.sweepstr > g->strmask)
624 g->gc.state = GCSsweep; /* All string hash chains sweeped. */
625 lua_assert(old >= g->gc.total);
626 g->gc.estimate -= old - g->gc.total;
627 return GCSWEEPCOST;
628 }
629 case GCSsweep: {
630 MSize old = g->gc.total;
631 setmref(g->gc.sweep, gc_sweep(g, mref(g->gc.sweep, GCRef), GCSWEEPMAX));
632 if (gcref(*mref(g->gc.sweep, GCRef)) == NULL) {
633 gc_shrink(g, L);
634 if (gcref(g->gc.mmudata)) { /* Need any finalizations? */
635 g->gc.state = GCSfinalize;
636 } else { /* Otherwise skip this phase to help the JIT. */
637 g->gc.state = GCSpause; /* End of GC cycle. */
638 g->gc.debt = 0;
639 }
640 }
641 lua_assert(old >= g->gc.total);
642 g->gc.estimate -= old - g->gc.total;
643 return GCSWEEPMAX*GCSWEEPCOST;
644 }
645 case GCSfinalize:
646 if (gcref(g->gc.mmudata) != NULL) {
647 if (gcref(g->jit_L)) /* Don't call finalizers on trace. */
648 return LJ_MAX_MEM;
649 gc_finalize(L); /* Finalize one userdata object. */
650 if (g->gc.estimate > GCFINALIZECOST)
651 g->gc.estimate -= GCFINALIZECOST;
652 return GCFINALIZECOST;
653 }
654 g->gc.state = GCSpause; /* End of GC cycle. */
655 g->gc.debt = 0;
656 return 0;
657 default:
658 lua_assert(0);
659 return 0;
660 }
661}
662
663/* Perform a limited amount of incremental GC steps. */
664int LJ_FASTCALL lj_gc_step(lua_State *L)
665{
666 global_State *g = G(L);
667 MSize lim;
668 int32_t ostate = g->vmstate;
669 setvmstate(g, GC);
670 lim = (GCSTEPSIZE/100) * g->gc.stepmul;
671 if (lim == 0)
672 lim = LJ_MAX_MEM;
673 g->gc.debt += g->gc.total - g->gc.threshold;
674 do {
675 lim -= (MSize)gc_onestep(L);
676 if (g->gc.state == GCSpause) {
677 g->gc.threshold = (g->gc.estimate/100) * g->gc.pause;
678 g->vmstate = ostate;
679 return 1; /* Finished a GC cycle. */
680 }
681 } while ((int32_t)lim > 0);
682 if (g->gc.debt < GCSTEPSIZE) {
683 g->gc.threshold = g->gc.total + GCSTEPSIZE;
684 } else {
685 g->gc.debt -= GCSTEPSIZE;
686 g->gc.threshold = g->gc.total;
687 }
688 g->vmstate = ostate;
689 return 0;
690}
691
692/* Ditto, but fix the stack top first. */
693void LJ_FASTCALL lj_gc_step_fixtop(lua_State *L)
694{
695 if (curr_funcisL(L)) L->top = curr_topL(L);
696 lj_gc_step(L);
697}
698
699#if LJ_HASJIT
700/* Perform multiple GC steps. Called from JIT-compiled code. */
701int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps)
702{
703 lua_State *L = gco2th(gcref(g->jit_L));
704 L->base = mref(G(L)->jit_base, TValue);
705 L->top = curr_topL(L);
706 while (steps-- > 0 && lj_gc_step(L) == 0)
707 ;
708 /* Return 1 to force a trace exit. */
709 return (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize);
710}
711#endif
712
713/* Perform a full GC cycle. */
714void lj_gc_fullgc(lua_State *L)
715{
716 global_State *g = G(L);
717 int32_t ostate = g->vmstate;
718 setvmstate(g, GC);
719 if (g->gc.state <= GCSatomic) { /* Caught somewhere in the middle. */
720 setmref(g->gc.sweep, &g->gc.root); /* Sweep everything (preserving it). */
721 setgcrefnull(g->gc.gray); /* Reset lists from partial propagation. */
722 setgcrefnull(g->gc.grayagain);
723 setgcrefnull(g->gc.weak);
724 g->gc.state = GCSsweepstring; /* Fast forward to the sweep phase. */
725 g->gc.sweepstr = 0;
726 }
727 while (g->gc.state == GCSsweepstring || g->gc.state == GCSsweep)
728 gc_onestep(L); /* Finish sweep. */
729 lua_assert(g->gc.state == GCSfinalize || g->gc.state == GCSpause);
730 /* Now perform a full GC. */
731 g->gc.state = GCSpause;
732 do { gc_onestep(L); } while (g->gc.state != GCSpause);
733 g->gc.threshold = (g->gc.estimate/100) * g->gc.pause;
734 g->vmstate = ostate;
735}
736
737/* -- Write barriers ------------------------------------------------------ */
738
739/* Move the GC propagation frontier forward. */
740void lj_gc_barrierf(global_State *g, GCobj *o, GCobj *v)
741{
742 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
743 lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause);
744 lua_assert(o->gch.gct != ~LJ_TTAB);
745 /* Preserve invariant during propagation. Otherwise it doesn't matter. */
746 if (g->gc.state == GCSpropagate || g->gc.state == GCSatomic)
747 gc_mark(g, v); /* Move frontier forward. */
748 else
749 makewhite(g, o); /* Make it white to avoid the following barrier. */
750}
751
752/* Specialized barrier for closed upvalue. Pass &uv->tv. */
753void LJ_FASTCALL lj_gc_barrieruv(global_State *g, TValue *tv)
754{
755#define TV2MARKED(x) \
756 (*((uint8_t *)(x) - offsetof(GCupval, tv) + offsetof(GCupval, marked)))
757 if (g->gc.state == GCSpropagate || g->gc.state == GCSatomic)
758 gc_mark(g, gcV(tv));
759 else
760 TV2MARKED(tv) = (TV2MARKED(tv) & (uint8_t)~LJ_GC_COLORS) | curwhite(g);
761#undef TV2MARKED
762}
763
764/* Close upvalue. Also needs a write barrier. */
765void lj_gc_closeuv(global_State *g, GCupval *uv)
766{
767 GCobj *o = obj2gco(uv);
768 /* Copy stack slot to upvalue itself and point to the copy. */
769 copyTV(mainthread(g), &uv->tv, uvval(uv));
770 setmref(uv->v, &uv->tv);
771 uv->closed = 1;
772 setgcrefr(o->gch.nextgc, g->gc.root);
773 setgcref(g->gc.root, o);
774 if (isgray(o)) { /* A closed upvalue is never gray, so fix this. */
775 if (g->gc.state == GCSpropagate || g->gc.state == GCSatomic) {
776 gray2black(o); /* Make it black and preserve invariant. */
777 if (tviswhite(&uv->tv))
778 lj_gc_barrierf(g, o, gcV(&uv->tv));
779 } else {
780 makewhite(g, o); /* Make it white, i.e. sweep the upvalue. */
781 lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause);
782 }
783 }
784}
785
786#if LJ_HASJIT
787/* Mark a trace if it's saved during the propagation phase. */
788void lj_gc_barriertrace(global_State *g, uint32_t traceno)
789{
790 if (g->gc.state == GCSpropagate || g->gc.state == GCSatomic)
791 gc_marktrace(g, traceno);
792}
793#endif
794
795/* -- Allocator ----------------------------------------------------------- */
796
797/* Call pluggable memory allocator to allocate or resize a fragment. */
798void *lj_mem_realloc(lua_State *L, void *p, MSize osz, MSize nsz)
799{
800 global_State *g = G(L);
801 lua_assert((osz == 0) == (p == NULL));
802 p = g->allocf(g->allocd, p, osz, nsz);
803 if (p == NULL && nsz > 0)
804 lj_err_mem(L);
805 lua_assert((nsz == 0) == (p == NULL));
806 lua_assert(checkptr32(p));
807 g->gc.total = (g->gc.total - osz) + nsz;
808 return p;
809}
810
811/* Allocate new GC object and link it to the root set. */
812void * LJ_FASTCALL lj_mem_newgco(lua_State *L, MSize size)
813{
814 global_State *g = G(L);
815 GCobj *o = (GCobj *)g->allocf(g->allocd, NULL, 0, size);
816 if (o == NULL)
817 lj_err_mem(L);
818 lua_assert(checkptr32(o));
819 g->gc.total += size;
820 setgcrefr(o->gch.nextgc, g->gc.root);
821 setgcref(g->gc.root, o);
822 newwhite(g, o);
823 return o;
824}
825
826/* Resize growable vector. */
827void *lj_mem_grow(lua_State *L, void *p, MSize *szp, MSize lim, MSize esz)
828{
829 MSize sz = (*szp) << 1;
830 if (sz < LJ_MIN_VECSZ)
831 sz = LJ_MIN_VECSZ;
832 if (sz > lim)
833 sz = lim;
834 p = lj_mem_realloc(L, p, (*szp)*esz, sz*esz);
835 *szp = sz;
836 return p;
837}
838
diff --git a/libraries/luajit-2.0/src/lj_gc.h b/libraries/luajit-2.0/src/lj_gc.h
new file mode 100644
index 0000000..dd7f87b
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_gc.h
@@ -0,0 +1,133 @@
1/*
2** Garbage collector.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_GC_H
7#define _LJ_GC_H
8
9#include "lj_obj.h"
10
11/* Garbage collector states. Order matters. */
12enum {
13 GCSpause, GCSpropagate, GCSatomic, GCSsweepstring, GCSsweep, GCSfinalize
14};
15
16/* Bitmasks for marked field of GCobj. */
17#define LJ_GC_WHITE0 0x01
18#define LJ_GC_WHITE1 0x02
19#define LJ_GC_BLACK 0x04
20#define LJ_GC_FINALIZED 0x08
21#define LJ_GC_WEAKKEY 0x08
22#define LJ_GC_WEAKVAL 0x10
23#define LJ_GC_CDATA_FIN 0x10
24#define LJ_GC_FIXED 0x20
25#define LJ_GC_SFIXED 0x40
26
27#define LJ_GC_WHITES (LJ_GC_WHITE0 | LJ_GC_WHITE1)
28#define LJ_GC_COLORS (LJ_GC_WHITES | LJ_GC_BLACK)
29#define LJ_GC_WEAK (LJ_GC_WEAKKEY | LJ_GC_WEAKVAL)
30
31/* Macros to test and set GCobj colors. */
32#define iswhite(x) ((x)->gch.marked & LJ_GC_WHITES)
33#define isblack(x) ((x)->gch.marked & LJ_GC_BLACK)
34#define isgray(x) (!((x)->gch.marked & (LJ_GC_BLACK|LJ_GC_WHITES)))
35#define tviswhite(x) (tvisgcv(x) && iswhite(gcV(x)))
36#define otherwhite(g) (g->gc.currentwhite ^ LJ_GC_WHITES)
37#define isdead(g, v) ((v)->gch.marked & otherwhite(g) & LJ_GC_WHITES)
38
39#define curwhite(g) ((g)->gc.currentwhite & LJ_GC_WHITES)
40#define newwhite(g, x) (obj2gco(x)->gch.marked = (uint8_t)curwhite(g))
41#define makewhite(g, x) \
42 ((x)->gch.marked = ((x)->gch.marked & (uint8_t)~LJ_GC_COLORS) | curwhite(g))
43#define flipwhite(x) ((x)->gch.marked ^= LJ_GC_WHITES)
44#define black2gray(x) ((x)->gch.marked &= (uint8_t)~LJ_GC_BLACK)
45#define fixstring(s) ((s)->marked |= LJ_GC_FIXED)
46
47/* Collector. */
48LJ_FUNC size_t lj_gc_separateudata(global_State *g, int all);
49LJ_FUNC void lj_gc_finalize_udata(lua_State *L);
50#if LJ_HASFFI
51LJ_FUNC void lj_gc_finalize_cdata(lua_State *L);
52#else
53#define lj_gc_finalize_cdata(L) UNUSED(L)
54#endif
55LJ_FUNC void lj_gc_freeall(global_State *g);
56LJ_FUNCA int LJ_FASTCALL lj_gc_step(lua_State *L);
57LJ_FUNCA void LJ_FASTCALL lj_gc_step_fixtop(lua_State *L);
58#if LJ_HASJIT
59LJ_FUNC int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps);
60#endif
61LJ_FUNC void lj_gc_fullgc(lua_State *L);
62
63/* GC check: drive collector forward if the GC threshold has been reached. */
64#define lj_gc_check(L) \
65 { if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
66 lj_gc_step(L); }
67#define lj_gc_check_fixtop(L) \
68 { if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
69 lj_gc_step_fixtop(L); }
70
71/* Write barriers. */
72LJ_FUNC void lj_gc_barrierf(global_State *g, GCobj *o, GCobj *v);
73LJ_FUNCA void LJ_FASTCALL lj_gc_barrieruv(global_State *g, TValue *tv);
74LJ_FUNC void lj_gc_closeuv(global_State *g, GCupval *uv);
75#if LJ_HASJIT
76LJ_FUNC void lj_gc_barriertrace(global_State *g, uint32_t traceno);
77#endif
78
79/* Move the GC propagation frontier back for tables (make it gray again). */
80static LJ_AINLINE void lj_gc_barrierback(global_State *g, GCtab *t)
81{
82 GCobj *o = obj2gco(t);
83 lua_assert(isblack(o) && !isdead(g, o));
84 lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause);
85 black2gray(o);
86 setgcrefr(t->gclist, g->gc.grayagain);
87 setgcref(g->gc.grayagain, o);
88}
89
90/* Barrier for stores to table objects. TValue and GCobj variant. */
91#define lj_gc_anybarriert(L, t) \
92 { if (LJ_UNLIKELY(isblack(obj2gco(t)))) lj_gc_barrierback(G(L), (t)); }
93#define lj_gc_barriert(L, t, tv) \
94 { if (tviswhite(tv) && isblack(obj2gco(t))) \
95 lj_gc_barrierback(G(L), (t)); }
96#define lj_gc_objbarriert(L, t, o) \
97 { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) \
98 lj_gc_barrierback(G(L), (t)); }
99
100/* Barrier for stores to any other object. TValue and GCobj variant. */
101#define lj_gc_barrier(L, p, tv) \
102 { if (tviswhite(tv) && isblack(obj2gco(p))) \
103 lj_gc_barrierf(G(L), obj2gco(p), gcV(tv)); }
104#define lj_gc_objbarrier(L, p, o) \
105 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
106 lj_gc_barrierf(G(L), obj2gco(p), obj2gco(o)); }
107
108/* Allocator. */
109LJ_FUNC void *lj_mem_realloc(lua_State *L, void *p, MSize osz, MSize nsz);
110LJ_FUNC void * LJ_FASTCALL lj_mem_newgco(lua_State *L, MSize size);
111LJ_FUNC void *lj_mem_grow(lua_State *L, void *p,
112 MSize *szp, MSize lim, MSize esz);
113
114#define lj_mem_new(L, s) lj_mem_realloc(L, NULL, 0, (s))
115
116static LJ_AINLINE void lj_mem_free(global_State *g, void *p, size_t osize)
117{
118 g->gc.total -= (MSize)osize;
119 g->allocf(g->allocd, p, osize, 0);
120}
121
122#define lj_mem_newvec(L, n, t) ((t *)lj_mem_new(L, (MSize)((n)*sizeof(t))))
123#define lj_mem_reallocvec(L, p, on, n, t) \
124 ((p) = (t *)lj_mem_realloc(L, p, (on)*sizeof(t), (MSize)((n)*sizeof(t))))
125#define lj_mem_growvec(L, p, n, m, t) \
126 ((p) = (t *)lj_mem_grow(L, (p), &(n), (m), (MSize)sizeof(t)))
127#define lj_mem_freevec(g, p, n, t) lj_mem_free(g, (p), (n)*sizeof(t))
128
129#define lj_mem_newobj(L, t) ((t *)lj_mem_newgco(L, sizeof(t)))
130#define lj_mem_newt(L, s, t) ((t *)lj_mem_new(L, (s)))
131#define lj_mem_freet(g, p) lj_mem_free(g, (p), sizeof(*(p)))
132
133#endif
diff --git a/libraries/luajit-2.0/src/lj_gdbjit.c b/libraries/luajit-2.0/src/lj_gdbjit.c
new file mode 100644
index 0000000..130ab99
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_gdbjit.c
@@ -0,0 +1,783 @@
1/*
2** Client for the GDB JIT API.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_gdbjit_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_debug.h"
16#include "lj_frame.h"
17#include "lj_jit.h"
18#include "lj_dispatch.h"
19
20/* This is not compiled in by default.
21** Enable with -DLUAJIT_USE_GDBJIT in the Makefile and recompile everything.
22*/
23#ifdef LUAJIT_USE_GDBJIT
24
25/* The GDB JIT API allows JIT compilers to pass debug information about
26** JIT-compiled code back to GDB. You need at least GDB 7.0 or higher
27** to see it in action.
28**
29** This is a passive API, so it works even when not running under GDB
30** or when attaching to an already running process. Alas, this implies
31** enabling it always has a non-negligible overhead -- do not use in
32** release mode!
33**
34** The LuaJIT GDB JIT client is rather minimal at the moment. It gives
35** each trace a symbol name and adds a source location and frame unwind
36** information. Obviously LuaJIT itself and any embedding C application
37** should be compiled with debug symbols, too (see the Makefile).
38**
39** Traces are named TRACE_1, TRACE_2, ... these correspond to the trace
40** numbers from -jv or -jdump. Use "break TRACE_1" or "tbreak TRACE_1" etc.
41** to set breakpoints on specific traces (even ahead of their creation).
42**
43** The source location for each trace allows listing the corresponding
44** source lines with the GDB command "list" (but only if the Lua source
45** has been loaded from a file). Currently this is always set to the
46** location where the trace has been started.
47**
48** Frame unwind information can be inspected with the GDB command
49** "info frame". This also allows proper backtraces across JIT-compiled
50** code with the GDB command "bt".
51**
52** You probably want to add the following settings to a .gdbinit file
53** (or add them to ~/.gdbinit):
54** set disassembly-flavor intel
55** set breakpoint pending on
56**
57** Here's a sample GDB session:
58** ------------------------------------------------------------------------
59
60$ cat >x.lua
61for outer=1,100 do
62 for inner=1,100 do end
63end
64^D
65
66$ luajit -jv x.lua
67[TRACE 1 x.lua:2]
68[TRACE 2 (1/3) x.lua:1 -> 1]
69
70$ gdb --quiet --args luajit x.lua
71(gdb) tbreak TRACE_1
72Function "TRACE_1" not defined.
73Temporary breakpoint 1 (TRACE_1) pending.
74(gdb) run
75Starting program: luajit x.lua
76
77Temporary breakpoint 1, TRACE_1 () at x.lua:2
782 for inner=1,100 do end
79(gdb) list
801 for outer=1,100 do
812 for inner=1,100 do end
823 end
83(gdb) bt
84#0 TRACE_1 () at x.lua:2
85#1 0x08053690 in lua_pcall [...]
86[...]
87#7 0x0806ff90 in main [...]
88(gdb) disass TRACE_1
89Dump of assembler code for function TRACE_1:
900xf7fd9fba <TRACE_1+0>: mov DWORD PTR ds:0xf7e0e2a0,0x1
910xf7fd9fc4 <TRACE_1+10>: movsd xmm7,QWORD PTR [edx+0x20]
92[...]
930xf7fd9ff8 <TRACE_1+62>: jmp 0xf7fd2014
94End of assembler dump.
95(gdb) tbreak TRACE_2
96Function "TRACE_2" not defined.
97Temporary breakpoint 2 (TRACE_2) pending.
98(gdb) cont
99Continuing.
100
101Temporary breakpoint 2, TRACE_2 () at x.lua:1
1021 for outer=1,100 do
103(gdb) info frame
104Stack level 0, frame at 0xffffd7c0:
105 eip = 0xf7fd9f60 in TRACE_2 (x.lua:1); saved eip 0x8053690
106 called by frame at 0xffffd7e0
107 source language unknown.
108 Arglist at 0xffffd78c, args:
109 Locals at 0xffffd78c, Previous frame's sp is 0xffffd7c0
110 Saved registers:
111 ebx at 0xffffd7ac, ebp at 0xffffd7b8, esi at 0xffffd7b0, edi at 0xffffd7b4,
112 eip at 0xffffd7bc
113(gdb)
114
115** ------------------------------------------------------------------------
116*/
117
118/* -- GDB JIT API --------------------------------------------------------- */
119
120/* GDB JIT actions. */
121enum {
122 GDBJIT_NOACTION = 0,
123 GDBJIT_REGISTER,
124 GDBJIT_UNREGISTER
125};
126
127/* GDB JIT entry. */
128typedef struct GDBJITentry {
129 struct GDBJITentry *next_entry;
130 struct GDBJITentry *prev_entry;
131 const char *symfile_addr;
132 uint64_t symfile_size;
133} GDBJITentry;
134
135/* GDB JIT descriptor. */
136typedef struct GDBJITdesc {
137 uint32_t version;
138 uint32_t action_flag;
139 GDBJITentry *relevant_entry;
140 GDBJITentry *first_entry;
141} GDBJITdesc;
142
143GDBJITdesc __jit_debug_descriptor = {
144 1, GDBJIT_NOACTION, NULL, NULL
145};
146
147/* GDB sets a breakpoint at this function. */
148void LJ_NOINLINE __jit_debug_register_code()
149{
150 __asm__ __volatile__("");
151};
152
153/* -- In-memory ELF object definitions ------------------------------------ */
154
155/* ELF definitions. */
156typedef struct ELFheader {
157 uint8_t emagic[4];
158 uint8_t eclass;
159 uint8_t eendian;
160 uint8_t eversion;
161 uint8_t eosabi;
162 uint8_t eabiversion;
163 uint8_t epad[7];
164 uint16_t type;
165 uint16_t machine;
166 uint32_t version;
167 uintptr_t entry;
168 uintptr_t phofs;
169 uintptr_t shofs;
170 uint32_t flags;
171 uint16_t ehsize;
172 uint16_t phentsize;
173 uint16_t phnum;
174 uint16_t shentsize;
175 uint16_t shnum;
176 uint16_t shstridx;
177} ELFheader;
178
179typedef struct ELFsectheader {
180 uint32_t name;
181 uint32_t type;
182 uintptr_t flags;
183 uintptr_t addr;
184 uintptr_t ofs;
185 uintptr_t size;
186 uint32_t link;
187 uint32_t info;
188 uintptr_t align;
189 uintptr_t entsize;
190} ELFsectheader;
191
192#define ELFSECT_IDX_ABS 0xfff1
193
194enum {
195 ELFSECT_TYPE_PROGBITS = 1,
196 ELFSECT_TYPE_SYMTAB = 2,
197 ELFSECT_TYPE_STRTAB = 3,
198 ELFSECT_TYPE_NOBITS = 8
199};
200
201#define ELFSECT_FLAGS_WRITE 1
202#define ELFSECT_FLAGS_ALLOC 2
203#define ELFSECT_FLAGS_EXEC 4
204
205typedef struct ELFsymbol {
206#if LJ_64
207 uint32_t name;
208 uint8_t info;
209 uint8_t other;
210 uint16_t sectidx;
211 uintptr_t value;
212 uint64_t size;
213#else
214 uint32_t name;
215 uintptr_t value;
216 uint32_t size;
217 uint8_t info;
218 uint8_t other;
219 uint16_t sectidx;
220#endif
221} ELFsymbol;
222
223enum {
224 ELFSYM_TYPE_FUNC = 2,
225 ELFSYM_TYPE_FILE = 4,
226 ELFSYM_BIND_LOCAL = 0 << 4,
227 ELFSYM_BIND_GLOBAL = 1 << 4,
228};
229
230/* DWARF definitions. */
231#define DW_CIE_VERSION 1
232
233enum {
234 DW_CFA_nop = 0x0,
235 DW_CFA_offset_extended = 0x5,
236 DW_CFA_def_cfa = 0xc,
237 DW_CFA_def_cfa_offset = 0xe,
238 DW_CFA_offset_extended_sf = 0x11,
239 DW_CFA_advance_loc = 0x40,
240 DW_CFA_offset = 0x80
241};
242
243enum {
244 DW_EH_PE_udata4 = 3,
245 DW_EH_PE_textrel = 0x20
246};
247
248enum {
249 DW_TAG_compile_unit = 0x11
250};
251
252enum {
253 DW_children_no = 0,
254 DW_children_yes = 1
255};
256
257enum {
258 DW_AT_name = 0x03,
259 DW_AT_stmt_list = 0x10,
260 DW_AT_low_pc = 0x11,
261 DW_AT_high_pc = 0x12
262};
263
264enum {
265 DW_FORM_addr = 0x01,
266 DW_FORM_data4 = 0x06,
267 DW_FORM_string = 0x08
268};
269
270enum {
271 DW_LNS_extended_op = 0,
272 DW_LNS_copy = 1,
273 DW_LNS_advance_pc = 2,
274 DW_LNS_advance_line = 3
275};
276
277enum {
278 DW_LNE_end_sequence = 1,
279 DW_LNE_set_address = 2
280};
281
282enum {
283#if LJ_TARGET_X86
284 DW_REG_AX, DW_REG_CX, DW_REG_DX, DW_REG_BX,
285 DW_REG_SP, DW_REG_BP, DW_REG_SI, DW_REG_DI,
286 DW_REG_RA,
287#elif LJ_TARGET_X64
288 /* Yes, the order is strange, but correct. */
289 DW_REG_AX, DW_REG_DX, DW_REG_CX, DW_REG_BX,
290 DW_REG_SI, DW_REG_DI, DW_REG_BP, DW_REG_SP,
291 DW_REG_8, DW_REG_9, DW_REG_10, DW_REG_11,
292 DW_REG_12, DW_REG_13, DW_REG_14, DW_REG_15,
293 DW_REG_RA,
294#elif LJ_TARGET_ARM
295 DW_REG_SP = 13,
296 DW_REG_RA = 14,
297#elif LJ_TARGET_PPC
298 DW_REG_SP = 1,
299 DW_REG_RA = 65,
300 DW_REG_CR = 70,
301#else
302#error "Unsupported target architecture"
303#endif
304};
305
306/* Minimal list of sections for the in-memory ELF object. */
307enum {
308 GDBJIT_SECT_NULL,
309 GDBJIT_SECT_text,
310 GDBJIT_SECT_eh_frame,
311 GDBJIT_SECT_shstrtab,
312 GDBJIT_SECT_strtab,
313 GDBJIT_SECT_symtab,
314 GDBJIT_SECT_debug_info,
315 GDBJIT_SECT_debug_abbrev,
316 GDBJIT_SECT_debug_line,
317 GDBJIT_SECT__MAX
318};
319
320enum {
321 GDBJIT_SYM_UNDEF,
322 GDBJIT_SYM_FILE,
323 GDBJIT_SYM_FUNC,
324 GDBJIT_SYM__MAX
325};
326
327/* In-memory ELF object. */
328typedef struct GDBJITobj {
329 ELFheader hdr; /* ELF header. */
330 ELFsectheader sect[GDBJIT_SECT__MAX]; /* ELF sections. */
331 ELFsymbol sym[GDBJIT_SYM__MAX]; /* ELF symbol table. */
332 uint8_t space[4096]; /* Space for various section data. */
333} GDBJITobj;
334
335/* Combined structure for GDB JIT entry and ELF object. */
336typedef struct GDBJITentryobj {
337 GDBJITentry entry;
338 size_t sz;
339 GDBJITobj obj;
340} GDBJITentryobj;
341
342/* Template for in-memory ELF header. */
343static const ELFheader elfhdr_template = {
344 .emagic = { 0x7f, 'E', 'L', 'F' },
345 .eclass = LJ_64 ? 2 : 1,
346 .eendian = LJ_ENDIAN_SELECT(1, 2),
347 .eversion = 1,
348#if LJ_TARGET_LINUX
349 .eosabi = 0, /* Nope, it's not 3. */
350#elif defined(__FreeBSD__)
351 .eosabi = 9,
352#elif defined(__NetBSD__)
353 .eosabi = 2,
354#elif defined(__OpenBSD__)
355 .eosabi = 12,
356#elif (defined(__sun__) && defined(__svr4__)) || defined(__solaris__)
357 .eosabi = 6,
358#else
359 .eosabi = 0,
360#endif
361 .eabiversion = 0,
362 .epad = { 0, 0, 0, 0, 0, 0, 0 },
363 .type = 1,
364#if LJ_TARGET_X86
365 .machine = 3,
366#elif LJ_TARGET_X64
367 .machine = 62,
368#elif LJ_TARGET_ARM
369 .machine = 40,
370#elif LJ_TARGET_PPC
371 .machine = 20,
372#else
373#error "Unsupported target architecture"
374#endif
375 .version = 1,
376 .entry = 0,
377 .phofs = 0,
378 .shofs = offsetof(GDBJITobj, sect),
379 .flags = 0,
380 .ehsize = sizeof(ELFheader),
381 .phentsize = 0,
382 .phnum = 0,
383 .shentsize = sizeof(ELFsectheader),
384 .shnum = GDBJIT_SECT__MAX,
385 .shstridx = GDBJIT_SECT_shstrtab
386};
387
388/* -- In-memory ELF object generation ------------------------------------- */
389
390/* Context for generating the ELF object for the GDB JIT API. */
391typedef struct GDBJITctx {
392 uint8_t *p; /* Pointer to next address in obj.space. */
393 uint8_t *startp; /* Pointer to start address in obj.space. */
394 GCtrace *T; /* Generate symbols for this trace. */
395 uintptr_t mcaddr; /* Machine code address. */
396 MSize szmcode; /* Size of machine code. */
397 MSize spadjp; /* Stack adjustment for parent trace or interpreter. */
398 MSize spadj; /* Stack adjustment for trace itself. */
399 BCLine lineno; /* Starting line number. */
400 const char *filename; /* Starting file name. */
401 size_t objsize; /* Final size of ELF object. */
402 GDBJITobj obj; /* In-memory ELF object. */
403} GDBJITctx;
404
405/* Add a zero-terminated string. */
406static uint32_t gdbjit_strz(GDBJITctx *ctx, const char *str)
407{
408 uint8_t *p = ctx->p;
409 uint32_t ofs = (uint32_t)(p - ctx->startp);
410 do {
411 *p++ = (uint8_t)*str;
412 } while (*str++);
413 ctx->p = p;
414 return ofs;
415}
416
417/* Append a decimal number. */
418static void gdbjit_catnum(GDBJITctx *ctx, uint32_t n)
419{
420 if (n >= 10) { uint32_t m = n / 10; n = n % 10; gdbjit_catnum(ctx, m); }
421 *ctx->p++ = '0' + n;
422}
423
424/* Add a ULEB128 value. */
425static void gdbjit_uleb128(GDBJITctx *ctx, uint32_t v)
426{
427 uint8_t *p = ctx->p;
428 for (; v >= 0x80; v >>= 7)
429 *p++ = (uint8_t)((v & 0x7f) | 0x80);
430 *p++ = (uint8_t)v;
431 ctx->p = p;
432}
433
434/* Add a SLEB128 value. */
435static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v)
436{
437 uint8_t *p = ctx->p;
438 for (; (uint32_t)(v+0x40) >= 0x80; v >>= 7)
439 *p++ = (uint8_t)((v & 0x7f) | 0x80);
440 *p++ = (uint8_t)(v & 0x7f);
441 ctx->p = p;
442}
443
444/* Shortcuts to generate DWARF structures. */
445#define DB(x) (*p++ = (x))
446#define DI8(x) (*(int8_t *)p = (x), p++)
447#define DU16(x) (*(uint16_t *)p = (x), p += 2)
448#define DU32(x) (*(uint32_t *)p = (x), p += 4)
449#define DADDR(x) (*(uintptr_t *)p = (x), p += sizeof(uintptr_t))
450#define DUV(x) (ctx->p = p, gdbjit_uleb128(ctx, (x)), p = ctx->p)
451#define DSV(x) (ctx->p = p, gdbjit_sleb128(ctx, (x)), p = ctx->p)
452#define DSTR(str) (ctx->p = p, gdbjit_strz(ctx, (str)), p = ctx->p)
453#define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop
454#define DSECT(name, stmt) \
455 { uint32_t *szp_##name = (uint32_t *)p; p += 4; stmt \
456 *szp_##name = (uint32_t)((p-(uint8_t *)szp_##name)-4); } \
457
458/* Initialize ELF section headers. */
459static void LJ_FASTCALL gdbjit_secthdr(GDBJITctx *ctx)
460{
461 ELFsectheader *sect;
462
463 *ctx->p++ = '\0'; /* Empty string at start of string table. */
464
465#define SECTDEF(id, tp, al) \
466 sect = &ctx->obj.sect[GDBJIT_SECT_##id]; \
467 sect->name = gdbjit_strz(ctx, "." #id); \
468 sect->type = ELFSECT_TYPE_##tp; \
469 sect->align = (al)
470
471 SECTDEF(text, NOBITS, 16);
472 sect->flags = ELFSECT_FLAGS_ALLOC|ELFSECT_FLAGS_EXEC;
473 sect->addr = ctx->mcaddr;
474 sect->ofs = 0;
475 sect->size = ctx->szmcode;
476
477 SECTDEF(eh_frame, PROGBITS, sizeof(uintptr_t));
478 sect->flags = ELFSECT_FLAGS_ALLOC;
479
480 SECTDEF(shstrtab, STRTAB, 1);
481 SECTDEF(strtab, STRTAB, 1);
482
483 SECTDEF(symtab, SYMTAB, sizeof(uintptr_t));
484 sect->ofs = offsetof(GDBJITobj, sym);
485 sect->size = sizeof(ctx->obj.sym);
486 sect->link = GDBJIT_SECT_strtab;
487 sect->entsize = sizeof(ELFsymbol);
488 sect->info = GDBJIT_SYM_FUNC;
489
490 SECTDEF(debug_info, PROGBITS, 1);
491 SECTDEF(debug_abbrev, PROGBITS, 1);
492 SECTDEF(debug_line, PROGBITS, 1);
493
494#undef SECTDEF
495}
496
497/* Initialize symbol table. */
498static void LJ_FASTCALL gdbjit_symtab(GDBJITctx *ctx)
499{
500 ELFsymbol *sym;
501
502 *ctx->p++ = '\0'; /* Empty string at start of string table. */
503
504 sym = &ctx->obj.sym[GDBJIT_SYM_FILE];
505 sym->name = gdbjit_strz(ctx, "JIT mcode");
506 sym->sectidx = ELFSECT_IDX_ABS;
507 sym->info = ELFSYM_TYPE_FILE|ELFSYM_BIND_LOCAL;
508
509 sym = &ctx->obj.sym[GDBJIT_SYM_FUNC];
510 sym->name = gdbjit_strz(ctx, "TRACE_"); ctx->p--;
511 gdbjit_catnum(ctx, ctx->T->traceno); *ctx->p++ = '\0';
512 sym->sectidx = GDBJIT_SECT_text;
513 sym->value = 0;
514 sym->size = ctx->szmcode;
515 sym->info = ELFSYM_TYPE_FUNC|ELFSYM_BIND_GLOBAL;
516}
517
518/* Initialize .eh_frame section. */
519static void LJ_FASTCALL gdbjit_ehframe(GDBJITctx *ctx)
520{
521 uint8_t *p = ctx->p;
522 uint8_t *framep = p;
523
524 /* Emit DWARF EH CIE. */
525 DSECT(CIE,
526 DU32(0); /* Offset to CIE itself. */
527 DB(DW_CIE_VERSION);
528 DSTR("zR"); /* Augmentation. */
529 DUV(1); /* Code alignment factor. */
530 DSV(-(int32_t)sizeof(uintptr_t)); /* Data alignment factor. */
531 DB(DW_REG_RA); /* Return address register. */
532 DB(1); DB(DW_EH_PE_textrel|DW_EH_PE_udata4); /* Augmentation data. */
533 DB(DW_CFA_def_cfa); DUV(DW_REG_SP); DUV(sizeof(uintptr_t));
534#if LJ_TARGET_PPC
535 DB(DW_CFA_offset_extended_sf); DB(DW_REG_RA); DSV(-1);
536#else
537 DB(DW_CFA_offset|DW_REG_RA); DUV(1);
538#endif
539 DALIGNNOP(sizeof(uintptr_t));
540 )
541
542 /* Emit DWARF EH FDE. */
543 DSECT(FDE,
544 DU32((uint32_t)(p-framep)); /* Offset to CIE. */
545 DU32(0); /* Machine code offset relative to .text. */
546 DU32(ctx->szmcode); /* Machine code length. */
547 DB(0); /* Augmentation data. */
548 /* Registers saved in CFRAME. */
549#if LJ_TARGET_X86
550 DB(DW_CFA_offset|DW_REG_BP); DUV(2);
551 DB(DW_CFA_offset|DW_REG_DI); DUV(3);
552 DB(DW_CFA_offset|DW_REG_SI); DUV(4);
553 DB(DW_CFA_offset|DW_REG_BX); DUV(5);
554#elif LJ_TARGET_X64
555 DB(DW_CFA_offset|DW_REG_BP); DUV(2);
556 DB(DW_CFA_offset|DW_REG_BX); DUV(3);
557 DB(DW_CFA_offset|DW_REG_15); DUV(4);
558 DB(DW_CFA_offset|DW_REG_14); DUV(5);
559 /* Extra registers saved for JIT-compiled code. */
560 DB(DW_CFA_offset|DW_REG_13); DUV(9);
561 DB(DW_CFA_offset|DW_REG_12); DUV(10);
562#elif LJ_TARGET_ARM
563 {
564 int i;
565 DB(DW_CFA_offset_extended); DB(DW_REG_CR); DUV(55);
566 for (i = 11; i >= 4; i--) { /* R4-R11. */
567 DB(DW_CFA_offset|i); DUV(2+(11-i));
568 }
569 }
570#elif LJ_TARGET_PPC
571 {
572 int i;
573 for (i = 14; i <= 31; i++) {
574 DB(DW_CFA_offset|i); DUV(37+(31-i));
575 DB(DW_CFA_offset|32|i); DUV(2+2*(31-i));
576 }
577 }
578#else
579#error "Unsupported target architecture"
580#endif
581 if (ctx->spadjp != ctx->spadj) { /* Parent/interpreter stack frame size. */
582 DB(DW_CFA_def_cfa_offset); DUV(ctx->spadjp);
583 DB(DW_CFA_advance_loc|1); /* Only an approximation. */
584 }
585 DB(DW_CFA_def_cfa_offset); DUV(ctx->spadj); /* Trace stack frame size. */
586 DALIGNNOP(sizeof(uintptr_t));
587 )
588
589 ctx->p = p;
590}
591
592/* Initialize .debug_info section. */
593static void LJ_FASTCALL gdbjit_debuginfo(GDBJITctx *ctx)
594{
595 uint8_t *p = ctx->p;
596
597 DSECT(info,
598 DU16(2); /* DWARF version. */
599 DU32(0); /* Abbrev offset. */
600 DB(sizeof(uintptr_t)); /* Pointer size. */
601
602 DUV(1); /* Abbrev #1: DW_TAG_compile_unit. */
603 DSTR(ctx->filename); /* DW_AT_name. */
604 DADDR(ctx->mcaddr); /* DW_AT_low_pc. */
605 DADDR(ctx->mcaddr + ctx->szmcode); /* DW_AT_high_pc. */
606 DU32(0); /* DW_AT_stmt_list. */
607 )
608
609 ctx->p = p;
610}
611
612/* Initialize .debug_abbrev section. */
613static void LJ_FASTCALL gdbjit_debugabbrev(GDBJITctx *ctx)
614{
615 uint8_t *p = ctx->p;
616
617 /* Abbrev #1: DW_TAG_compile_unit. */
618 DUV(1); DUV(DW_TAG_compile_unit);
619 DB(DW_children_no);
620 DUV(DW_AT_name); DUV(DW_FORM_string);
621 DUV(DW_AT_low_pc); DUV(DW_FORM_addr);
622 DUV(DW_AT_high_pc); DUV(DW_FORM_addr);
623 DUV(DW_AT_stmt_list); DUV(DW_FORM_data4);
624 DB(0); DB(0);
625
626 ctx->p = p;
627}
628
629#define DLNE(op, s) (DB(DW_LNS_extended_op), DUV(1+(s)), DB((op)))
630
631/* Initialize .debug_line section. */
632static void LJ_FASTCALL gdbjit_debugline(GDBJITctx *ctx)
633{
634 uint8_t *p = ctx->p;
635
636 DSECT(line,
637 DU16(2); /* DWARF version. */
638 DSECT(header,
639 DB(1); /* Minimum instruction length. */
640 DB(1); /* is_stmt. */
641 DI8(0); /* Line base for special opcodes. */
642 DB(2); /* Line range for special opcodes. */
643 DB(3+1); /* Opcode base at DW_LNS_advance_line+1. */
644 DB(0); DB(1); DB(1); /* Standard opcode lengths. */
645 /* Directory table. */
646 DB(0);
647 /* File name table. */
648 DSTR(ctx->filename); DUV(0); DUV(0); DUV(0);
649 DB(0);
650 )
651
652 DLNE(DW_LNE_set_address, sizeof(uintptr_t)); DADDR(ctx->mcaddr);
653 if (ctx->lineno) {
654 DB(DW_LNS_advance_line); DSV(ctx->lineno-1);
655 }
656 DB(DW_LNS_copy);
657 DB(DW_LNS_advance_pc); DUV(ctx->szmcode);
658 DLNE(DW_LNE_end_sequence, 0);
659 )
660
661 ctx->p = p;
662}
663
664#undef DLNE
665
666/* Undef shortcuts. */
667#undef DB
668#undef DI8
669#undef DU16
670#undef DU32
671#undef DADDR
672#undef DUV
673#undef DSV
674#undef DSTR
675#undef DALIGNNOP
676#undef DSECT
677
678/* Type of a section initializer callback. */
679typedef void (LJ_FASTCALL *GDBJITinitf)(GDBJITctx *ctx);
680
681/* Call section initializer and set the section offset and size. */
682static void gdbjit_initsect(GDBJITctx *ctx, int sect, GDBJITinitf initf)
683{
684 ctx->startp = ctx->p;
685 ctx->obj.sect[sect].ofs = (uintptr_t)((char *)ctx->p - (char *)&ctx->obj);
686 initf(ctx);
687 ctx->obj.sect[sect].size = (uintptr_t)(ctx->p - ctx->startp);
688}
689
690#define SECTALIGN(p, a) \
691 ((p) = (uint8_t *)(((uintptr_t)(p) + ((a)-1)) & ~(uintptr_t)((a)-1)))
692
693/* Build in-memory ELF object. */
694static void gdbjit_buildobj(GDBJITctx *ctx)
695{
696 GDBJITobj *obj = &ctx->obj;
697 /* Fill in ELF header and clear structures. */
698 memcpy(&obj->hdr, &elfhdr_template, sizeof(ELFheader));
699 memset(&obj->sect, 0, sizeof(ELFsectheader)*GDBJIT_SECT__MAX);
700 memset(&obj->sym, 0, sizeof(ELFsymbol)*GDBJIT_SYM__MAX);
701 /* Initialize sections. */
702 ctx->p = obj->space;
703 gdbjit_initsect(ctx, GDBJIT_SECT_shstrtab, gdbjit_secthdr);
704 gdbjit_initsect(ctx, GDBJIT_SECT_strtab, gdbjit_symtab);
705 gdbjit_initsect(ctx, GDBJIT_SECT_debug_info, gdbjit_debuginfo);
706 gdbjit_initsect(ctx, GDBJIT_SECT_debug_abbrev, gdbjit_debugabbrev);
707 gdbjit_initsect(ctx, GDBJIT_SECT_debug_line, gdbjit_debugline);
708 SECTALIGN(ctx->p, sizeof(uintptr_t));
709 gdbjit_initsect(ctx, GDBJIT_SECT_eh_frame, gdbjit_ehframe);
710 ctx->objsize = (size_t)((char *)ctx->p - (char *)obj);
711 lua_assert(ctx->objsize < sizeof(GDBJITobj));
712}
713
714#undef SECTALIGN
715
716/* -- Interface to GDB JIT API -------------------------------------------- */
717
718/* Add new entry to GDB JIT symbol chain. */
719static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx)
720{
721 /* Allocate memory for GDB JIT entry and ELF object. */
722 MSize sz = (MSize)(sizeof(GDBJITentryobj) - sizeof(GDBJITobj) + ctx->objsize);
723 GDBJITentryobj *eo = lj_mem_newt(L, sz, GDBJITentryobj);
724 memcpy(&eo->obj, &ctx->obj, ctx->objsize); /* Copy ELF object. */
725 eo->sz = sz;
726 ctx->T->gdbjit_entry = (void *)eo;
727 /* Link new entry to chain and register it. */
728 eo->entry.prev_entry = NULL;
729 eo->entry.next_entry = __jit_debug_descriptor.first_entry;
730 if (eo->entry.next_entry)
731 eo->entry.next_entry->prev_entry = &eo->entry;
732 eo->entry.symfile_addr = (const char *)&eo->obj;
733 eo->entry.symfile_size = ctx->objsize;
734 __jit_debug_descriptor.first_entry = &eo->entry;
735 __jit_debug_descriptor.relevant_entry = &eo->entry;
736 __jit_debug_descriptor.action_flag = GDBJIT_REGISTER;
737 __jit_debug_register_code();
738}
739
740/* Add debug info for newly compiled trace and notify GDB. */
741void lj_gdbjit_addtrace(jit_State *J, GCtrace *T)
742{
743 GDBJITctx ctx;
744 GCproto *pt = &gcref(T->startpt)->pt;
745 TraceNo parent = T->ir[REF_BASE].op1;
746 const BCIns *startpc = mref(T->startpc, const BCIns);
747 ctx.T = T;
748 ctx.mcaddr = (uintptr_t)T->mcode;
749 ctx.szmcode = T->szmcode;
750 ctx.spadjp = CFRAME_SIZE_JIT +
751 (MSize)(parent ? traceref(J, parent)->spadjust : 0);
752 ctx.spadj = CFRAME_SIZE_JIT + T->spadjust;
753 lua_assert(startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc);
754 ctx.lineno = lj_debug_line(pt, proto_bcpos(pt, startpc));
755 ctx.filename = proto_chunknamestr(pt);
756 if (*ctx.filename == '@' || *ctx.filename == '=')
757 ctx.filename++;
758 else
759 ctx.filename = "(string)";
760 gdbjit_buildobj(&ctx);
761 gdbjit_newentry(J->L, &ctx);
762}
763
764/* Delete debug info for trace and notify GDB. */
765void lj_gdbjit_deltrace(jit_State *J, GCtrace *T)
766{
767 GDBJITentryobj *eo = (GDBJITentryobj *)T->gdbjit_entry;
768 if (eo) {
769 if (eo->entry.prev_entry)
770 eo->entry.prev_entry->next_entry = eo->entry.next_entry;
771 else
772 __jit_debug_descriptor.first_entry = eo->entry.next_entry;
773 if (eo->entry.next_entry)
774 eo->entry.next_entry->prev_entry = eo->entry.prev_entry;
775 __jit_debug_descriptor.relevant_entry = &eo->entry;
776 __jit_debug_descriptor.action_flag = GDBJIT_UNREGISTER;
777 __jit_debug_register_code();
778 lj_mem_free(J2G(J), eo, eo->sz);
779 }
780}
781
782#endif
783#endif
diff --git a/libraries/luajit-2.0/src/lj_gdbjit.h b/libraries/luajit-2.0/src/lj_gdbjit.h
new file mode 100644
index 0000000..5e42d3c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_gdbjit.h
@@ -0,0 +1,22 @@
1/*
2** Client for the GDB JIT API.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_GDBJIT_H
7#define _LJ_GDBJIT_H
8
9#include "lj_obj.h"
10#include "lj_jit.h"
11
12#if LJ_HASJIT && defined(LUAJIT_USE_GDBJIT)
13
14LJ_FUNC void lj_gdbjit_addtrace(jit_State *J, GCtrace *T);
15LJ_FUNC void lj_gdbjit_deltrace(jit_State *J, GCtrace *T);
16
17#else
18#define lj_gdbjit_addtrace(J, T) UNUSED(T)
19#define lj_gdbjit_deltrace(J, T) UNUSED(T)
20#endif
21
22#endif
diff --git a/libraries/luajit-2.0/src/lj_ir.c b/libraries/luajit-2.0/src/lj_ir.c
new file mode 100644
index 0000000..457d918
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ir.c
@@ -0,0 +1,492 @@
1/*
2** SSA IR (Intermediate Representation) emitter.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_ir_c
7#define LUA_CORE
8
9/* For pointers to libc/libm functions. */
10#include <stdio.h>
11#include <math.h>
12
13#include "lj_obj.h"
14
15#if LJ_HASJIT
16
17#include "lj_gc.h"
18#include "lj_str.h"
19#include "lj_tab.h"
20#include "lj_ir.h"
21#include "lj_jit.h"
22#include "lj_ircall.h"
23#include "lj_iropt.h"
24#include "lj_trace.h"
25#if LJ_HASFFI
26#include "lj_ctype.h"
27#include "lj_cdata.h"
28#include "lj_carith.h"
29#endif
30#include "lj_vm.h"
31#include "lj_lib.h"
32
33/* Some local macros to save typing. Undef'd at the end. */
34#define IR(ref) (&J->cur.ir[(ref)])
35#define fins (&J->fold.ins)
36
37/* Pass IR on to next optimization in chain (FOLD). */
38#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
39
40/* -- IR tables ----------------------------------------------------------- */
41
42/* IR instruction modes. */
43LJ_DATADEF const uint8_t lj_ir_mode[IR__MAX+1] = {
44IRDEF(IRMODE)
45 0
46};
47
48/* C call info for CALL* instructions. */
49LJ_DATADEF const CCallInfo lj_ir_callinfo[] = {
50#define IRCALLCI(cond, name, nargs, kind, type, flags) \
51 { (ASMFunction)IRCALLCOND_##cond(name), \
52 (nargs)|(CCI_CALL_##kind)|(IRT_##type<<CCI_OTSHIFT)|(flags) },
53IRCALLDEF(IRCALLCI)
54#undef IRCALLCI
55 { NULL, 0 }
56};
57
58/* -- IR emitter ---------------------------------------------------------- */
59
60/* Grow IR buffer at the top. */
61void LJ_FASTCALL lj_ir_growtop(jit_State *J)
62{
63 IRIns *baseir = J->irbuf + J->irbotlim;
64 MSize szins = J->irtoplim - J->irbotlim;
65 if (szins) {
66 baseir = (IRIns *)lj_mem_realloc(J->L, baseir, szins*sizeof(IRIns),
67 2*szins*sizeof(IRIns));
68 J->irtoplim = J->irbotlim + 2*szins;
69 } else {
70 baseir = (IRIns *)lj_mem_realloc(J->L, NULL, 0, LJ_MIN_IRSZ*sizeof(IRIns));
71 J->irbotlim = REF_BASE - LJ_MIN_IRSZ/4;
72 J->irtoplim = J->irbotlim + LJ_MIN_IRSZ;
73 }
74 J->cur.ir = J->irbuf = baseir - J->irbotlim;
75}
76
77/* Grow IR buffer at the bottom or shift it up. */
78static void lj_ir_growbot(jit_State *J)
79{
80 IRIns *baseir = J->irbuf + J->irbotlim;
81 MSize szins = J->irtoplim - J->irbotlim;
82 lua_assert(szins != 0);
83 lua_assert(J->cur.nk == J->irbotlim);
84 if (J->cur.nins + (szins >> 1) < J->irtoplim) {
85 /* More than half of the buffer is free on top: shift up by a quarter. */
86 MSize ofs = szins >> 2;
87 memmove(baseir + ofs, baseir, (J->cur.nins - J->irbotlim)*sizeof(IRIns));
88 J->irbotlim -= ofs;
89 J->irtoplim -= ofs;
90 J->cur.ir = J->irbuf = baseir - J->irbotlim;
91 } else {
92 /* Double the buffer size, but split the growth amongst top/bottom. */
93 IRIns *newbase = lj_mem_newt(J->L, 2*szins*sizeof(IRIns), IRIns);
94 MSize ofs = szins >= 256 ? 128 : (szins >> 1); /* Limit bottom growth. */
95 memcpy(newbase + ofs, baseir, (J->cur.nins - J->irbotlim)*sizeof(IRIns));
96 lj_mem_free(G(J->L), baseir, szins*sizeof(IRIns));
97 J->irbotlim -= ofs;
98 J->irtoplim = J->irbotlim + 2*szins;
99 J->cur.ir = J->irbuf = newbase - J->irbotlim;
100 }
101}
102
103/* Emit IR without any optimizations. */
104TRef LJ_FASTCALL lj_ir_emit(jit_State *J)
105{
106 IRRef ref = lj_ir_nextins(J);
107 IRIns *ir = IR(ref);
108 IROp op = fins->o;
109 ir->prev = J->chain[op];
110 J->chain[op] = (IRRef1)ref;
111 ir->o = op;
112 ir->op1 = fins->op1;
113 ir->op2 = fins->op2;
114 J->guardemit.irt |= fins->t.irt;
115 return TREF(ref, irt_t((ir->t = fins->t)));
116}
117
118/* Emit call to a C function. */
119TRef lj_ir_call(jit_State *J, IRCallID id, ...)
120{
121 const CCallInfo *ci = &lj_ir_callinfo[id];
122 uint32_t n = CCI_NARGS(ci);
123 TRef tr = TREF_NIL;
124 va_list argp;
125 va_start(argp, id);
126 if ((ci->flags & CCI_L)) n--;
127 if (n > 0)
128 tr = va_arg(argp, IRRef);
129 while (n-- > 1)
130 tr = emitir(IRT(IR_CARG, IRT_NIL), tr, va_arg(argp, IRRef));
131 va_end(argp);
132 if (CCI_OP(ci) == IR_CALLS)
133 J->needsnap = 1; /* Need snapshot after call with side effect. */
134 return emitir(CCI_OPTYPE(ci), tr, id);
135}
136
137/* -- Interning of constants ---------------------------------------------- */
138
139/*
140** IR instructions for constants are kept between J->cur.nk >= ref < REF_BIAS.
141** They are chained like all other instructions, but grow downwards.
142** The are interned (like strings in the VM) to facilitate reference
143** comparisons. The same constant must get the same reference.
144*/
145
146/* Get ref of next IR constant and optionally grow IR.
147** Note: this may invalidate all IRIns *!
148*/
149static LJ_AINLINE IRRef ir_nextk(jit_State *J)
150{
151 IRRef ref = J->cur.nk;
152 if (LJ_UNLIKELY(ref <= J->irbotlim)) lj_ir_growbot(J);
153 J->cur.nk = --ref;
154 return ref;
155}
156
157/* Intern int32_t constant. */
158TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k)
159{
160 IRIns *ir, *cir = J->cur.ir;
161 IRRef ref;
162 for (ref = J->chain[IR_KINT]; ref; ref = cir[ref].prev)
163 if (cir[ref].i == k)
164 goto found;
165 ref = ir_nextk(J);
166 ir = IR(ref);
167 ir->i = k;
168 ir->t.irt = IRT_INT;
169 ir->o = IR_KINT;
170 ir->prev = J->chain[IR_KINT];
171 J->chain[IR_KINT] = (IRRef1)ref;
172found:
173 return TREF(ref, IRT_INT);
174}
175
176/* The MRef inside the KNUM/KINT64 IR instructions holds the address of the
177** 64 bit constant. The constants themselves are stored in a chained array
178** and shared across traces.
179**
180** Rationale for choosing this data structure:
181** - The address of the constants is embedded in the generated machine code
182** and must never move. A resizable array or hash table wouldn't work.
183** - Most apps need very few non-32 bit integer constants (less than a dozen).
184** - Linear search is hard to beat in terms of speed and low complexity.
185*/
186typedef struct K64Array {
187 MRef next; /* Pointer to next list. */
188 MSize numk; /* Number of used elements in this array. */
189 TValue k[LJ_MIN_K64SZ]; /* Array of constants. */
190} K64Array;
191
192/* Free all chained arrays. */
193void lj_ir_k64_freeall(jit_State *J)
194{
195 K64Array *k;
196 for (k = mref(J->k64, K64Array); k; ) {
197 K64Array *next = mref(k->next, K64Array);
198 lj_mem_free(J2G(J), k, sizeof(K64Array));
199 k = next;
200 }
201}
202
203/* Find 64 bit constant in chained array or add it. */
204cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64)
205{
206 K64Array *k, *kp = NULL;
207 TValue *ntv;
208 MSize idx;
209 /* Search for the constant in the whole chain of arrays. */
210 for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) {
211 kp = k; /* Remember previous element in list. */
212 for (idx = 0; idx < k->numk; idx++) { /* Search one array. */
213 TValue *tv = &k->k[idx];
214 if (tv->u64 == u64) /* Needed for +-0/NaN/absmask. */
215 return tv;
216 }
217 }
218 /* Constant was not found, need to add it. */
219 if (!(kp && kp->numk < LJ_MIN_K64SZ)) { /* Allocate a new array. */
220 K64Array *kn = lj_mem_newt(J->L, sizeof(K64Array), K64Array);
221 setmref(kn->next, NULL);
222 kn->numk = 0;
223 if (kp)
224 setmref(kp->next, kn); /* Chain to the end of the list. */
225 else
226 setmref(J->k64, kn); /* Link first array. */
227 kp = kn;
228 }
229 ntv = &kp->k[kp->numk++]; /* Add to current array. */
230 ntv->u64 = u64;
231 return ntv;
232}
233
234/* Intern 64 bit constant, given by its address. */
235TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv)
236{
237 IRIns *ir, *cir = J->cur.ir;
238 IRRef ref;
239 IRType t = op == IR_KNUM ? IRT_NUM : IRT_I64;
240 for (ref = J->chain[op]; ref; ref = cir[ref].prev)
241 if (ir_k64(&cir[ref]) == tv)
242 goto found;
243 ref = ir_nextk(J);
244 ir = IR(ref);
245 lua_assert(checkptr32(tv));
246 setmref(ir->ptr, tv);
247 ir->t.irt = t;
248 ir->o = op;
249 ir->prev = J->chain[op];
250 J->chain[op] = (IRRef1)ref;
251found:
252 return TREF(ref, t);
253}
254
255/* Intern FP constant, given by its 64 bit pattern. */
256TRef lj_ir_knum_u64(jit_State *J, uint64_t u64)
257{
258 return lj_ir_k64(J, IR_KNUM, lj_ir_k64_find(J, u64));
259}
260
261/* Intern 64 bit integer constant. */
262TRef lj_ir_kint64(jit_State *J, uint64_t u64)
263{
264 return lj_ir_k64(J, IR_KINT64, lj_ir_k64_find(J, u64));
265}
266
267/* Check whether a number is int and return it. -0 is NOT considered an int. */
268static int numistrueint(lua_Number n, int32_t *kp)
269{
270 int32_t k = lj_num2int(n);
271 if (n == (lua_Number)k) {
272 if (kp) *kp = k;
273 if (k == 0) { /* Special check for -0. */
274 TValue tv;
275 setnumV(&tv, n);
276 if (tv.u32.hi != 0)
277 return 0;
278 }
279 return 1;
280 }
281 return 0;
282}
283
284/* Intern number as int32_t constant if possible, otherwise as FP constant. */
285TRef lj_ir_knumint(jit_State *J, lua_Number n)
286{
287 int32_t k;
288 if (numistrueint(n, &k))
289 return lj_ir_kint(J, k);
290 else
291 return lj_ir_knum(J, n);
292}
293
294/* Intern GC object "constant". */
295TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t)
296{
297 IRIns *ir, *cir = J->cur.ir;
298 IRRef ref;
299 lua_assert(!isdead(J2G(J), o));
300 for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev)
301 if (ir_kgc(&cir[ref]) == o)
302 goto found;
303 ref = ir_nextk(J);
304 ir = IR(ref);
305 /* NOBARRIER: Current trace is a GC root. */
306 setgcref(ir->gcr, o);
307 ir->t.irt = (uint8_t)t;
308 ir->o = IR_KGC;
309 ir->prev = J->chain[IR_KGC];
310 J->chain[IR_KGC] = (IRRef1)ref;
311found:
312 return TREF(ref, t);
313}
314
315/* Intern 32 bit pointer constant. */
316TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr)
317{
318 IRIns *ir, *cir = J->cur.ir;
319 IRRef ref;
320 lua_assert((void *)(intptr_t)i32ptr(ptr) == ptr);
321 for (ref = J->chain[op]; ref; ref = cir[ref].prev)
322 if (mref(cir[ref].ptr, void) == ptr)
323 goto found;
324 ref = ir_nextk(J);
325 ir = IR(ref);
326 setmref(ir->ptr, ptr);
327 ir->t.irt = IRT_P32;
328 ir->o = op;
329 ir->prev = J->chain[op];
330 J->chain[op] = (IRRef1)ref;
331found:
332 return TREF(ref, IRT_P32);
333}
334
335/* Intern typed NULL constant. */
336TRef lj_ir_knull(jit_State *J, IRType t)
337{
338 IRIns *ir, *cir = J->cur.ir;
339 IRRef ref;
340 for (ref = J->chain[IR_KNULL]; ref; ref = cir[ref].prev)
341 if (irt_t(cir[ref].t) == t)
342 goto found;
343 ref = ir_nextk(J);
344 ir = IR(ref);
345 ir->i = 0;
346 ir->t.irt = (uint8_t)t;
347 ir->o = IR_KNULL;
348 ir->prev = J->chain[IR_KNULL];
349 J->chain[IR_KNULL] = (IRRef1)ref;
350found:
351 return TREF(ref, t);
352}
353
354/* Intern key slot. */
355TRef lj_ir_kslot(jit_State *J, TRef key, IRRef slot)
356{
357 IRIns *ir, *cir = J->cur.ir;
358 IRRef2 op12 = IRREF2((IRRef1)key, (IRRef1)slot);
359 IRRef ref;
360 /* Const part is not touched by CSE/DCE, so 0-65535 is ok for IRMlit here. */
361 lua_assert(tref_isk(key) && slot == (IRRef)(IRRef1)slot);
362 for (ref = J->chain[IR_KSLOT]; ref; ref = cir[ref].prev)
363 if (cir[ref].op12 == op12)
364 goto found;
365 ref = ir_nextk(J);
366 ir = IR(ref);
367 ir->op12 = op12;
368 ir->t.irt = IRT_P32;
369 ir->o = IR_KSLOT;
370 ir->prev = J->chain[IR_KSLOT];
371 J->chain[IR_KSLOT] = (IRRef1)ref;
372found:
373 return TREF(ref, IRT_P32);
374}
375
376/* -- Access to IR constants ---------------------------------------------- */
377
378/* Copy value of IR constant. */
379void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir)
380{
381 UNUSED(L);
382 lua_assert(ir->o != IR_KSLOT); /* Common mistake. */
383 switch (ir->o) {
384 case IR_KPRI: setitype(tv, irt_toitype(ir->t)); break;
385 case IR_KINT: setintV(tv, ir->i); break;
386 case IR_KGC: setgcV(L, tv, ir_kgc(ir), irt_toitype(ir->t)); break;
387 case IR_KPTR: case IR_KKPTR: case IR_KNULL:
388 setlightudV(tv, mref(ir->ptr, void));
389 break;
390 case IR_KNUM: setnumV(tv, ir_knum(ir)->n); break;
391#if LJ_HASFFI
392 case IR_KINT64: {
393 GCcdata *cd = lj_cdata_new_(L, CTID_INT64, 8);
394 *(uint64_t *)cdataptr(cd) = ir_kint64(ir)->u64;
395 setcdataV(L, tv, cd);
396 break;
397 }
398#endif
399 default: lua_assert(0); break;
400 }
401}
402
403/* -- Convert IR operand types -------------------------------------------- */
404
405/* Convert from string to number. */
406TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr)
407{
408 if (!tref_isnumber(tr)) {
409 if (tref_isstr(tr))
410 tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
411 else
412 lj_trace_err(J, LJ_TRERR_BADTYPE);
413 }
414 return tr;
415}
416
417/* Convert from integer or string to number. */
418TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr)
419{
420 if (!tref_isnum(tr)) {
421 if (tref_isinteger(tr))
422 tr = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
423 else if (tref_isstr(tr))
424 tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
425 else
426 lj_trace_err(J, LJ_TRERR_BADTYPE);
427 }
428 return tr;
429}
430
431/* Convert from integer or number to string. */
432TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr)
433{
434 if (!tref_isstr(tr)) {
435 if (!tref_isnumber(tr))
436 lj_trace_err(J, LJ_TRERR_BADTYPE);
437 tr = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0);
438 }
439 return tr;
440}
441
442/* -- Miscellaneous IR ops ------------------------------------------------ */
443
444/* Evaluate numeric comparison. */
445int lj_ir_numcmp(lua_Number a, lua_Number b, IROp op)
446{
447 switch (op) {
448 case IR_EQ: return (a == b);
449 case IR_NE: return (a != b);
450 case IR_LT: return (a < b);
451 case IR_GE: return (a >= b);
452 case IR_LE: return (a <= b);
453 case IR_GT: return (a > b);
454 case IR_ULT: return !(a >= b);
455 case IR_UGE: return !(a < b);
456 case IR_ULE: return !(a > b);
457 case IR_UGT: return !(a <= b);
458 default: lua_assert(0); return 0;
459 }
460}
461
462/* Evaluate string comparison. */
463int lj_ir_strcmp(GCstr *a, GCstr *b, IROp op)
464{
465 int res = lj_str_cmp(a, b);
466 switch (op) {
467 case IR_LT: return (res < 0);
468 case IR_GE: return (res >= 0);
469 case IR_LE: return (res <= 0);
470 case IR_GT: return (res > 0);
471 default: lua_assert(0); return 0;
472 }
473}
474
475/* Rollback IR to previous state. */
476void lj_ir_rollback(jit_State *J, IRRef ref)
477{
478 IRRef nins = J->cur.nins;
479 while (nins > ref) {
480 IRIns *ir;
481 nins--;
482 ir = IR(nins);
483 J->chain[ir->o] = ir->prev;
484 }
485 J->cur.nins = nins;
486}
487
488#undef IR
489#undef fins
490#undef emitir
491
492#endif
diff --git a/libraries/luajit-2.0/src/lj_ir.h b/libraries/luajit-2.0/src/lj_ir.h
new file mode 100644
index 0000000..8cf8129
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ir.h
@@ -0,0 +1,540 @@
1/*
2** SSA IR (Intermediate Representation) format.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_IR_H
7#define _LJ_IR_H
8
9#include "lj_obj.h"
10
11/* -- IR instructions ----------------------------------------------------- */
12
13/* IR instruction definition. Order matters, see below. ORDER IR */
14#define IRDEF(_) \
15 /* Guarded assertions. */ \
16 /* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \
17 _(LT, N , ref, ref) \
18 _(GE, N , ref, ref) \
19 _(LE, N , ref, ref) \
20 _(GT, N , ref, ref) \
21 \
22 _(ULT, N , ref, ref) \
23 _(UGE, N , ref, ref) \
24 _(ULE, N , ref, ref) \
25 _(UGT, N , ref, ref) \
26 \
27 _(EQ, C , ref, ref) \
28 _(NE, C , ref, ref) \
29 \
30 _(ABC, N , ref, ref) \
31 _(RETF, S , ref, ref) \
32 \
33 /* Miscellaneous ops. */ \
34 _(NOP, N , ___, ___) \
35 _(BASE, N , lit, lit) \
36 _(HIOP, S , ref, ref) \
37 _(LOOP, S , ___, ___) \
38 _(USE, S , ref, ___) \
39 _(PHI, S , ref, ref) \
40 _(RENAME, S , ref, lit) \
41 \
42 /* Constants. */ \
43 _(KPRI, N , ___, ___) \
44 _(KINT, N , cst, ___) \
45 _(KGC, N , cst, ___) \
46 _(KPTR, N , cst, ___) \
47 _(KKPTR, N , cst, ___) \
48 _(KNULL, N , cst, ___) \
49 _(KNUM, N , cst, ___) \
50 _(KINT64, N , cst, ___) \
51 _(KSLOT, N , ref, lit) \
52 \
53 /* Bit ops. */ \
54 _(BNOT, N , ref, ___) \
55 _(BSWAP, N , ref, ___) \
56 _(BAND, C , ref, ref) \
57 _(BOR, C , ref, ref) \
58 _(BXOR, C , ref, ref) \
59 _(BSHL, N , ref, ref) \
60 _(BSHR, N , ref, ref) \
61 _(BSAR, N , ref, ref) \
62 _(BROL, N , ref, ref) \
63 _(BROR, N , ref, ref) \
64 \
65 /* Arithmetic ops. ORDER ARITH */ \
66 _(ADD, C , ref, ref) \
67 _(SUB, N , ref, ref) \
68 _(MUL, C , ref, ref) \
69 _(DIV, N , ref, ref) \
70 _(MOD, N , ref, ref) \
71 _(POW, N , ref, ref) \
72 _(NEG, N , ref, ref) \
73 \
74 _(ABS, N , ref, ref) \
75 _(ATAN2, N , ref, ref) \
76 _(LDEXP, N , ref, ref) \
77 _(MIN, C , ref, ref) \
78 _(MAX, C , ref, ref) \
79 _(FPMATH, N , ref, lit) \
80 \
81 /* Overflow-checking arithmetic ops. */ \
82 _(ADDOV, CW, ref, ref) \
83 _(SUBOV, NW, ref, ref) \
84 _(MULOV, CW, ref, ref) \
85 \
86 /* Memory ops. A = array, H = hash, U = upvalue, F = field, S = stack. */ \
87 \
88 /* Memory references. */ \
89 _(AREF, R , ref, ref) \
90 _(HREFK, R , ref, ref) \
91 _(HREF, L , ref, ref) \
92 _(NEWREF, S , ref, ref) \
93 _(UREFO, LW, ref, lit) \
94 _(UREFC, LW, ref, lit) \
95 _(FREF, R , ref, lit) \
96 _(STRREF, N , ref, ref) \
97 \
98 /* Loads and Stores. These must be in the same order. */ \
99 _(ALOAD, L , ref, ___) \
100 _(HLOAD, L , ref, ___) \
101 _(ULOAD, L , ref, ___) \
102 _(FLOAD, L , ref, lit) \
103 _(XLOAD, L , ref, lit) \
104 _(SLOAD, L , lit, lit) \
105 _(VLOAD, L , ref, ___) \
106 \
107 _(ASTORE, S , ref, ref) \
108 _(HSTORE, S , ref, ref) \
109 _(USTORE, S , ref, ref) \
110 _(FSTORE, S , ref, ref) \
111 _(XSTORE, S , ref, ref) \
112 \
113 /* Allocations. */ \
114 _(SNEW, N , ref, ref) /* CSE is ok, not marked as A. */ \
115 _(XSNEW, A , ref, ref) \
116 _(TNEW, AW, lit, lit) \
117 _(TDUP, AW, ref, ___) \
118 _(CNEW, AW, ref, ref) \
119 _(CNEWI, NW, ref, ref) /* CSE is ok, not marked as A. */ \
120 \
121 /* Barriers. */ \
122 _(TBAR, S , ref, ___) \
123 _(OBAR, S , ref, ref) \
124 _(XBAR, S , ___, ___) \
125 \
126 /* Type conversions. */ \
127 _(CONV, NW, ref, lit) \
128 _(TOBIT, N , ref, ref) \
129 _(TOSTR, N , ref, ___) \
130 _(STRTO, N , ref, ___) \
131 \
132 /* Calls. */ \
133 _(CALLN, N , ref, lit) \
134 _(CALLL, L , ref, lit) \
135 _(CALLS, S , ref, lit) \
136 _(CALLXS, S , ref, ref) \
137 _(CARG, N , ref, ref) \
138 \
139 /* End of list. */
140
141/* IR opcodes (max. 256). */
142typedef enum {
143#define IRENUM(name, m, m1, m2) IR_##name,
144IRDEF(IRENUM)
145#undef IRENUM
146 IR__MAX
147} IROp;
148
149/* Stored opcode. */
150typedef uint8_t IROp1;
151
152LJ_STATIC_ASSERT(((int)IR_EQ^1) == (int)IR_NE);
153LJ_STATIC_ASSERT(((int)IR_LT^1) == (int)IR_GE);
154LJ_STATIC_ASSERT(((int)IR_LE^1) == (int)IR_GT);
155LJ_STATIC_ASSERT(((int)IR_LT^3) == (int)IR_GT);
156LJ_STATIC_ASSERT(((int)IR_LT^4) == (int)IR_ULT);
157
158/* Delta between xLOAD and xSTORE. */
159#define IRDELTA_L2S ((int)IR_ASTORE - (int)IR_ALOAD)
160
161LJ_STATIC_ASSERT((int)IR_HLOAD + IRDELTA_L2S == (int)IR_HSTORE);
162LJ_STATIC_ASSERT((int)IR_ULOAD + IRDELTA_L2S == (int)IR_USTORE);
163LJ_STATIC_ASSERT((int)IR_FLOAD + IRDELTA_L2S == (int)IR_FSTORE);
164LJ_STATIC_ASSERT((int)IR_XLOAD + IRDELTA_L2S == (int)IR_XSTORE);
165
166/* -- Named IR literals --------------------------------------------------- */
167
168/* FPMATH sub-functions. ORDER FPM. */
169#define IRFPMDEF(_) \
170 _(FLOOR) _(CEIL) _(TRUNC) /* Must be first and in this order. */ \
171 _(SQRT) _(EXP) _(EXP2) _(LOG) _(LOG2) _(LOG10) \
172 _(SIN) _(COS) _(TAN) \
173 _(OTHER)
174
175typedef enum {
176#define FPMENUM(name) IRFPM_##name,
177IRFPMDEF(FPMENUM)
178#undef FPMENUM
179 IRFPM__MAX
180} IRFPMathOp;
181
182/* FLOAD fields. */
183#define IRFLDEF(_) \
184 _(STR_LEN, offsetof(GCstr, len)) \
185 _(FUNC_ENV, offsetof(GCfunc, l.env)) \
186 _(FUNC_PC, offsetof(GCfunc, l.pc)) \
187 _(TAB_META, offsetof(GCtab, metatable)) \
188 _(TAB_ARRAY, offsetof(GCtab, array)) \
189 _(TAB_NODE, offsetof(GCtab, node)) \
190 _(TAB_ASIZE, offsetof(GCtab, asize)) \
191 _(TAB_HMASK, offsetof(GCtab, hmask)) \
192 _(TAB_NOMM, offsetof(GCtab, nomm)) \
193 _(UDATA_META, offsetof(GCudata, metatable)) \
194 _(UDATA_UDTYPE, offsetof(GCudata, udtype)) \
195 _(UDATA_FILE, sizeof(GCudata)) \
196 _(CDATA_TYPEID, offsetof(GCcdata, typeid)) \
197 _(CDATA_PTR, sizeof(GCcdata)) \
198 _(CDATA_INT64, sizeof(GCcdata)) \
199 _(CDATA_INT64_4, sizeof(GCcdata) + 4)
200
201typedef enum {
202#define FLENUM(name, ofs) IRFL_##name,
203IRFLDEF(FLENUM)
204#undef FLENUM
205 IRFL__MAX
206} IRFieldID;
207
208/* SLOAD mode bits, stored in op2. */
209#define IRSLOAD_PARENT 0x01 /* Coalesce with parent trace. */
210#define IRSLOAD_FRAME 0x02 /* Load hiword of frame. */
211#define IRSLOAD_TYPECHECK 0x04 /* Needs type check. */
212#define IRSLOAD_CONVERT 0x08 /* Number to integer conversion. */
213#define IRSLOAD_READONLY 0x10 /* Read-only, omit slot store. */
214#define IRSLOAD_INHERIT 0x20 /* Inherited by exits/side traces. */
215
216/* XLOAD mode, stored in op2. */
217#define IRXLOAD_READONLY 1 /* Load from read-only data. */
218#define IRXLOAD_VOLATILE 2 /* Load from volatile data. */
219#define IRXLOAD_UNALIGNED 4 /* Unaligned load. */
220
221/* CONV mode, stored in op2. */
222#define IRCONV_SRCMASK 0x001f /* Source IRType. */
223#define IRCONV_DSTMASK 0x03e0 /* Dest. IRType (also in ir->t). */
224#define IRCONV_DSH 5
225#define IRCONV_NUM_INT ((IRT_NUM<<IRCONV_DSH)|IRT_INT)
226#define IRCONV_INT_NUM ((IRT_INT<<IRCONV_DSH)|IRT_NUM)
227#define IRCONV_TRUNC 0x0400 /* Truncate number to integer. */
228#define IRCONV_SEXT 0x0800 /* Sign-extend integer to integer. */
229#define IRCONV_MODEMASK 0x0fff
230#define IRCONV_CONVMASK 0xf000
231#define IRCONV_CSH 12
232/* Number to integer conversion mode. Ordered by strength of the checks. */
233#define IRCONV_TOBIT (0<<IRCONV_CSH) /* None. Cache only: TOBIT conv. */
234#define IRCONV_ANY (1<<IRCONV_CSH) /* Any FP number is ok. */
235#define IRCONV_INDEX (2<<IRCONV_CSH) /* Check + special backprop rules. */
236#define IRCONV_CHECK (3<<IRCONV_CSH) /* Number checked for integerness. */
237
238/* -- IR operands --------------------------------------------------------- */
239
240/* IR operand mode (2 bit). */
241typedef enum {
242 IRMref, /* IR reference. */
243 IRMlit, /* 16 bit unsigned literal. */
244 IRMcst, /* Constant literal: i, gcr or ptr. */
245 IRMnone /* Unused operand. */
246} IRMode;
247#define IRM___ IRMnone
248
249/* Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, Non-weak guard. */
250#define IRM_C 0x10
251
252#define IRM_N 0x00
253#define IRM_R IRM_N
254#define IRM_A 0x20
255#define IRM_L 0x40
256#define IRM_S 0x60
257
258#define IRM_W 0x80
259
260#define IRM_NW (IRM_N|IRM_W)
261#define IRM_CW (IRM_C|IRM_W)
262#define IRM_AW (IRM_A|IRM_W)
263#define IRM_LW (IRM_L|IRM_W)
264
265#define irm_op1(m) ((IRMode)((m)&3))
266#define irm_op2(m) ((IRMode)(((m)>>2)&3))
267#define irm_iscomm(m) ((m) & IRM_C)
268#define irm_kind(m) ((m) & IRM_S)
269
270#define IRMODE(name, m, m1, m2) (((IRM##m1)|((IRM##m2)<<2)|(IRM_##m))^IRM_W),
271
272LJ_DATA const uint8_t lj_ir_mode[IR__MAX+1];
273
274/* -- IR instruction types ------------------------------------------------ */
275
276/* Map of itypes to non-negative numbers. ORDER LJ_T.
277** LJ_TUPVAL/LJ_TTRACE never appear in a TValue. Use these itypes for
278** IRT_P32 and IRT_P64, which never escape the IR.
279** The various integers are only used in the IR and can only escape to
280** a TValue after implicit or explicit conversion. Their types must be
281** contiguous and next to IRT_NUM (see the typerange macros below).
282*/
283#define IRTDEF(_) \
284 _(NIL) _(FALSE) _(TRUE) _(LIGHTUD) _(STR) _(P32) _(THREAD) \
285 _(PROTO) _(FUNC) _(P64) _(CDATA) _(TAB) _(UDATA) \
286 _(FLOAT) _(NUM) _(I8) _(U8) _(I16) _(U16) _(INT) _(U32) _(I64) _(U64) \
287 _(SOFTFP) /* There is room for 9 more types. */
288
289/* IR result type and flags (8 bit). */
290typedef enum {
291#define IRTENUM(name) IRT_##name,
292IRTDEF(IRTENUM)
293#undef IRTENUM
294
295 /* Native pointer type and the corresponding integer type. */
296 IRT_PTR = LJ_64 ? IRT_P64 : IRT_P32,
297 IRT_INTP = LJ_64 ? IRT_I64 : IRT_INT,
298 IRT_UINTP = LJ_64 ? IRT_U64 : IRT_U32,
299
300 /* Additional flags. */
301 IRT_MARK = 0x20, /* Marker for misc. purposes. */
302 IRT_ISPHI = 0x40, /* Instruction is left or right PHI operand. */
303 IRT_GUARD = 0x80, /* Instruction is a guard. */
304
305 /* Masks. */
306 IRT_TYPE = 0x1f,
307 IRT_T = 0xff
308} IRType;
309
310#define irtype_ispri(irt) ((uint32_t)(irt) <= IRT_TRUE)
311
312/* Stored IRType. */
313typedef struct IRType1 { uint8_t irt; } IRType1;
314
315#define IRT(o, t) ((uint32_t)(((o)<<8) | (t)))
316#define IRTI(o) (IRT((o), IRT_INT))
317#define IRTN(o) (IRT((o), IRT_NUM))
318#define IRTG(o, t) (IRT((o), IRT_GUARD|(t)))
319#define IRTGI(o) (IRT((o), IRT_GUARD|IRT_INT))
320
321#define irt_t(t) ((IRType)(t).irt)
322#define irt_type(t) ((IRType)((t).irt & IRT_TYPE))
323#define irt_sametype(t1, t2) ((((t1).irt ^ (t2).irt) & IRT_TYPE) == 0)
324#define irt_typerange(t, first, last) \
325 ((uint32_t)((t).irt & IRT_TYPE) - (uint32_t)(first) <= (uint32_t)(last-first))
326
327#define irt_isnil(t) (irt_type(t) == IRT_NIL)
328#define irt_ispri(t) ((uint32_t)irt_type(t) <= IRT_TRUE)
329#define irt_islightud(t) (irt_type(t) == IRT_LIGHTUD)
330#define irt_isstr(t) (irt_type(t) == IRT_STR)
331#define irt_istab(t) (irt_type(t) == IRT_TAB)
332#define irt_isfloat(t) (irt_type(t) == IRT_FLOAT)
333#define irt_isnum(t) (irt_type(t) == IRT_NUM)
334#define irt_isint(t) (irt_type(t) == IRT_INT)
335#define irt_isi8(t) (irt_type(t) == IRT_I8)
336#define irt_isu8(t) (irt_type(t) == IRT_U8)
337#define irt_isi16(t) (irt_type(t) == IRT_I16)
338#define irt_isu16(t) (irt_type(t) == IRT_U16)
339#define irt_isu32(t) (irt_type(t) == IRT_U32)
340#define irt_isi64(t) (irt_type(t) == IRT_I64)
341#define irt_isu64(t) (irt_type(t) == IRT_U64)
342
343#define irt_isfp(t) (irt_isnum(t) || irt_isfloat(t))
344#define irt_isinteger(t) (irt_typerange((t), IRT_I8, IRT_INT))
345#define irt_isgcv(t) (irt_typerange((t), IRT_STR, IRT_UDATA))
346#define irt_isaddr(t) (irt_typerange((t), IRT_LIGHTUD, IRT_UDATA))
347#define irt_isint64(t) (irt_typerange((t), IRT_I64, IRT_U64))
348
349#if LJ_64
350#define IRT_IS64 \
351 ((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64)|(1u<<IRT_P64)|(1u<<IRT_LIGHTUD))
352#else
353#define IRT_IS64 \
354 ((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64))
355#endif
356
357#define irt_is64(t) ((IRT_IS64 >> irt_type(t)) & 1)
358#define irt_is64orfp(t) (((IRT_IS64|(1u<<IRT_FLOAT))>>irt_type(t)) & 1)
359
360static LJ_AINLINE IRType itype2irt(const TValue *tv)
361{
362 if (tvisint(tv))
363 return IRT_INT;
364 else if (tvisnum(tv))
365 return IRT_NUM;
366#if LJ_64
367 else if (tvislightud(tv))
368 return IRT_LIGHTUD;
369#endif
370 else
371 return (IRType)~itype(tv);
372}
373
374static LJ_AINLINE uint32_t irt_toitype_(IRType t)
375{
376 lua_assert(!LJ_64 || t != IRT_LIGHTUD);
377 if (LJ_DUALNUM && t > IRT_NUM) {
378 return LJ_TISNUM;
379 } else {
380 lua_assert(t <= IRT_NUM);
381 return ~(uint32_t)t;
382 }
383}
384
385#define irt_toitype(t) irt_toitype_(irt_type((t)))
386
387#define irt_isguard(t) ((t).irt & IRT_GUARD)
388#define irt_ismarked(t) ((t).irt & IRT_MARK)
389#define irt_setmark(t) ((t).irt |= IRT_MARK)
390#define irt_clearmark(t) ((t).irt &= ~IRT_MARK)
391#define irt_isphi(t) ((t).irt & IRT_ISPHI)
392#define irt_setphi(t) ((t).irt |= IRT_ISPHI)
393#define irt_clearphi(t) ((t).irt &= ~IRT_ISPHI)
394
395/* Stored combined IR opcode and type. */
396typedef uint16_t IROpT;
397
398/* -- IR references ------------------------------------------------------- */
399
400/* IR references. */
401typedef uint16_t IRRef1; /* One stored reference. */
402typedef uint32_t IRRef2; /* Two stored references. */
403typedef uint32_t IRRef; /* Used to pass around references. */
404
405/* Fixed references. */
406enum {
407 REF_BIAS = 0x8000,
408 REF_TRUE = REF_BIAS-3,
409 REF_FALSE = REF_BIAS-2,
410 REF_NIL = REF_BIAS-1, /* \--- Constants grow downwards. */
411 REF_BASE = REF_BIAS, /* /--- IR grows upwards. */
412 REF_FIRST = REF_BIAS+1,
413 REF_DROP = 0xffff
414};
415
416/* Note: IRMlit operands must be < REF_BIAS, too!
417** This allows for fast and uniform manipulation of all operands
418** without looking up the operand mode in lj_ir_mode:
419** - CSE calculates the maximum reference of two operands.
420** This must work with mixed reference/literal operands, too.
421** - DCE marking only checks for operand >= REF_BIAS.
422** - LOOP needs to substitute reference operands.
423** Constant references and literals must not be modified.
424*/
425
426#define IRREF2(lo, hi) ((IRRef2)(lo) | ((IRRef2)(hi) << 16))
427
428#define irref_isk(ref) ((ref) < REF_BIAS)
429
430/* Tagged IR references (32 bit).
431**
432** +-------+-------+---------------+
433** | irt | flags | ref |
434** +-------+-------+---------------+
435**
436** The tag holds a copy of the IRType and speeds up IR type checks.
437*/
438typedef uint32_t TRef;
439
440#define TREF_REFMASK 0x0000ffff
441#define TREF_FRAME 0x00010000
442#define TREF_CONT 0x00020000
443
444#define TREF(ref, t) ((TRef)((ref) + ((t)<<24)))
445
446#define tref_ref(tr) ((IRRef1)(tr))
447#define tref_t(tr) ((IRType)((tr)>>24))
448#define tref_type(tr) ((IRType)(((tr)>>24) & IRT_TYPE))
449#define tref_typerange(tr, first, last) \
450 ((((tr)>>24) & IRT_TYPE) - (TRef)(first) <= (TRef)(last-first))
451
452#define tref_istype(tr, t) (((tr) & (IRT_TYPE<<24)) == ((t)<<24))
453#define tref_isnil(tr) (tref_istype((tr), IRT_NIL))
454#define tref_isfalse(tr) (tref_istype((tr), IRT_FALSE))
455#define tref_istrue(tr) (tref_istype((tr), IRT_TRUE))
456#define tref_isstr(tr) (tref_istype((tr), IRT_STR))
457#define tref_isfunc(tr) (tref_istype((tr), IRT_FUNC))
458#define tref_iscdata(tr) (tref_istype((tr), IRT_CDATA))
459#define tref_istab(tr) (tref_istype((tr), IRT_TAB))
460#define tref_isudata(tr) (tref_istype((tr), IRT_UDATA))
461#define tref_isnum(tr) (tref_istype((tr), IRT_NUM))
462#define tref_isint(tr) (tref_istype((tr), IRT_INT))
463
464#define tref_isbool(tr) (tref_typerange((tr), IRT_FALSE, IRT_TRUE))
465#define tref_ispri(tr) (tref_typerange((tr), IRT_NIL, IRT_TRUE))
466#define tref_istruecond(tr) (!tref_typerange((tr), IRT_NIL, IRT_FALSE))
467#define tref_isinteger(tr) (tref_typerange((tr), IRT_I8, IRT_INT))
468#define tref_isnumber(tr) (tref_typerange((tr), IRT_NUM, IRT_INT))
469#define tref_isnumber_str(tr) (tref_isnumber((tr)) || tref_isstr((tr)))
470#define tref_isgcv(tr) (tref_typerange((tr), IRT_STR, IRT_UDATA))
471
472#define tref_isk(tr) (irref_isk(tref_ref((tr))))
473#define tref_isk2(tr1, tr2) (irref_isk(tref_ref((tr1) | (tr2))))
474
475#define TREF_PRI(t) (TREF(REF_NIL-(t), (t)))
476#define TREF_NIL (TREF_PRI(IRT_NIL))
477#define TREF_FALSE (TREF_PRI(IRT_FALSE))
478#define TREF_TRUE (TREF_PRI(IRT_TRUE))
479
480/* -- IR format ----------------------------------------------------------- */
481
482/* IR instruction format (64 bit).
483**
484** 16 16 8 8 8 8
485** +-------+-------+---+---+---+---+
486** | op1 | op2 | t | o | r | s |
487** +-------+-------+---+---+---+---+
488** | op12/i/gco | ot | prev | (alternative fields in union)
489** +---------------+-------+-------+
490** 32 16 16
491**
492** prev is only valid prior to register allocation and then reused for r + s.
493*/
494
495typedef union IRIns {
496 struct {
497 LJ_ENDIAN_LOHI(
498 IRRef1 op1; /* IR operand 1. */
499 , IRRef1 op2; /* IR operand 2. */
500 )
501 IROpT ot; /* IR opcode and type (overlaps t and o). */
502 IRRef1 prev; /* Previous ins in same chain (overlaps r and s). */
503 };
504 struct {
505 IRRef2 op12; /* IR operand 1 and 2 (overlaps op1 and op2). */
506 LJ_ENDIAN_LOHI(
507 IRType1 t; /* IR type. */
508 , IROp1 o; /* IR opcode. */
509 )
510 LJ_ENDIAN_LOHI(
511 uint8_t r; /* Register allocation (overlaps prev). */
512 , uint8_t s; /* Spill slot allocation (overlaps prev). */
513 )
514 };
515 int32_t i; /* 32 bit signed integer literal (overlaps op12). */
516 GCRef gcr; /* GCobj constant (overlaps op12). */
517 MRef ptr; /* Pointer constant (overlaps op12). */
518} IRIns;
519
520#define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)->gcr))
521#define ir_kstr(ir) (gco2str(ir_kgc((ir))))
522#define ir_ktab(ir) (gco2tab(ir_kgc((ir))))
523#define ir_kfunc(ir) (gco2func(ir_kgc((ir))))
524#define ir_kcdata(ir) (gco2cd(ir_kgc((ir))))
525#define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue))
526#define ir_kint64(ir) check_exp((ir)->o == IR_KINT64, mref((ir)->ptr,cTValue))
527#define ir_k64(ir) \
528 check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64, mref((ir)->ptr,cTValue))
529#define ir_kptr(ir) \
530 check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, mref((ir)->ptr, void))
531
532/* A store or any other op with a non-weak guard has a side-effect. */
533static LJ_AINLINE int ir_sideeff(IRIns *ir)
534{
535 return (((ir->t.irt | ~IRT_GUARD) & lj_ir_mode[ir->o]) >= IRM_S);
536}
537
538LJ_STATIC_ASSERT((int)IRT_GUARD == (int)IRM_W);
539
540#endif
diff --git a/libraries/luajit-2.0/src/lj_ircall.h b/libraries/luajit-2.0/src/lj_ircall.h
new file mode 100644
index 0000000..1a9599a
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_ircall.h
@@ -0,0 +1,271 @@
1/*
2** IR CALL* instruction definitions.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_IRCALL_H
7#define _LJ_IRCALL_H
8
9#include "lj_obj.h"
10#include "lj_ir.h"
11#include "lj_jit.h"
12
13/* C call info for CALL* instructions. */
14typedef struct CCallInfo {
15 ASMFunction func; /* Function pointer. */
16 uint32_t flags; /* Number of arguments and flags. */
17} CCallInfo;
18
19#define CCI_NARGS(ci) ((ci)->flags & 0xff) /* Extract # of args. */
20#define CCI_NARGS_MAX 32 /* Max. # of args. */
21
22#define CCI_OTSHIFT 16
23#define CCI_OPTYPE(ci) ((ci)->flags >> CCI_OTSHIFT) /* Get op/type. */
24#define CCI_OPSHIFT 24
25#define CCI_OP(ci) ((ci)->flags >> CCI_OPSHIFT) /* Get op. */
26
27#define CCI_CALL_N (IR_CALLN << CCI_OPSHIFT)
28#define CCI_CALL_L (IR_CALLL << CCI_OPSHIFT)
29#define CCI_CALL_S (IR_CALLS << CCI_OPSHIFT)
30#define CCI_CALL_FN (CCI_CALL_N|CCI_CC_FASTCALL)
31#define CCI_CALL_FL (CCI_CALL_L|CCI_CC_FASTCALL)
32#define CCI_CALL_FS (CCI_CALL_S|CCI_CC_FASTCALL)
33
34/* C call info flags. */
35#define CCI_L 0x0100 /* Implicit L arg. */
36#define CCI_CASTU64 0x0200 /* Cast u64 result to number. */
37#define CCI_NOFPRCLOBBER 0x0400 /* Does not clobber any FPRs. */
38#define CCI_VARARG 0x0800 /* Vararg function. */
39
40#define CCI_CC_MASK 0x3000 /* Calling convention mask. */
41#define CCI_CC_SHIFT 12
42/* ORDER CC */
43#define CCI_CC_CDECL 0x0000 /* Default cdecl calling convention. */
44#define CCI_CC_THISCALL 0x1000 /* Thiscall calling convention. */
45#define CCI_CC_FASTCALL 0x2000 /* Fastcall calling convention. */
46#define CCI_CC_STDCALL 0x3000 /* Stdcall calling convention. */
47
48/* Helpers for conditional function definitions. */
49#define IRCALLCOND_ANY(x) x
50
51#if LJ_TARGET_X86ORX64
52#define IRCALLCOND_FPMATH(x) NULL
53#else
54#define IRCALLCOND_FPMATH(x) x
55#endif
56
57#if LJ_SOFTFP
58#define IRCALLCOND_SOFTFP(x) x
59#if LJ_HASFFI
60#define IRCALLCOND_SOFTFP_FFI(x) x
61#else
62#define IRCALLCOND_SOFTFP_FFI(x) NULL
63#endif
64#else
65#define IRCALLCOND_SOFTFP(x) NULL
66#define IRCALLCOND_SOFTFP_FFI(x) NULL
67#endif
68
69#define LJ_NEED_FP64 LJ_TARGET_PPC
70
71#if LJ_HASFFI && (LJ_SOFTFP || LJ_NEED_FP64)
72#define IRCALLCOND_FP64_FFI(x) x
73#else
74#define IRCALLCOND_FP64_FFI(x) NULL
75#endif
76
77#if LJ_HASFFI
78#define IRCALLCOND_FFI(x) x
79#if LJ_32
80#define IRCALLCOND_FFI32(x) x
81#else
82#define IRCALLCOND_FFI32(x) NULL
83#endif
84#else
85#define IRCALLCOND_FFI(x) NULL
86#define IRCALLCOND_FFI32(x) NULL
87#endif
88
89#if LJ_SOFTFP
90#define ARG1_FP 2 /* Treat as 2 32 bit arguments. */
91#else
92#define ARG1_FP 1
93#endif
94
95#if LJ_32
96#define ARG2_64 4 /* Treat as 4 32 bit arguments. */
97#else
98#define ARG2_64 2
99#endif
100
101/* Function definitions for CALL* instructions. */
102#define IRCALLDEF(_) \
103 _(ANY, lj_str_cmp, 2, FN, INT, CCI_NOFPRCLOBBER) \
104 _(ANY, lj_str_new, 3, S, STR, CCI_L) \
105 _(ANY, lj_str_tonum, 2, FN, INT, 0) \
106 _(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \
107 _(ANY, lj_str_fromnum, 2, FN, STR, CCI_L) \
108 _(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \
109 _(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \
110 _(ANY, lj_tab_newkey, 3, S, P32, CCI_L) \
111 _(ANY, lj_tab_len, 1, FL, INT, 0) \
112 _(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \
113 _(ANY, lj_gc_barrieruv, 2, FS, NIL, 0) \
114 _(ANY, lj_mem_newgco, 2, FS, P32, CCI_L) \
115 _(ANY, lj_math_random_step, 1, FS, NUM, CCI_CASTU64|CCI_NOFPRCLOBBER) \
116 _(ANY, lj_vm_modi, 2, FN, INT, 0) \
117 _(ANY, sinh, 1, N, NUM, 0) \
118 _(ANY, cosh, 1, N, NUM, 0) \
119 _(ANY, tanh, 1, N, NUM, 0) \
120 _(ANY, fputc, 2, S, INT, 0) \
121 _(ANY, fwrite, 4, S, INT, 0) \
122 _(ANY, fflush, 1, S, INT, 0) \
123 /* ORDER FPM */ \
124 _(FPMATH, lj_vm_floor, ARG1_FP, N, NUM, 0) \
125 _(FPMATH, lj_vm_ceil, ARG1_FP, N, NUM, 0) \
126 _(FPMATH, lj_vm_trunc, ARG1_FP, N, NUM, 0) \
127 _(FPMATH, sqrt, ARG1_FP, N, NUM, 0) \
128 _(FPMATH, exp, ARG1_FP, N, NUM, 0) \
129 _(FPMATH, lj_vm_exp2, ARG1_FP, N, NUM, 0) \
130 _(FPMATH, log, ARG1_FP, N, NUM, 0) \
131 _(FPMATH, lj_vm_log2, ARG1_FP, N, NUM, 0) \
132 _(FPMATH, log10, ARG1_FP, N, NUM, 0) \
133 _(FPMATH, sin, ARG1_FP, N, NUM, 0) \
134 _(FPMATH, cos, ARG1_FP, N, NUM, 0) \
135 _(FPMATH, tan, ARG1_FP, N, NUM, 0) \
136 _(FPMATH, lj_vm_powi, ARG1_FP+1, N, NUM, 0) \
137 _(FPMATH, pow, ARG1_FP*2, N, NUM, 0) \
138 _(FPMATH, atan2, ARG1_FP*2, N, NUM, 0) \
139 _(FPMATH, ldexp, ARG1_FP+1, N, NUM, 0) \
140 _(SOFTFP, lj_vm_tobit, 2, N, INT, 0) \
141 _(SOFTFP, softfp_add, 4, N, NUM, 0) \
142 _(SOFTFP, softfp_sub, 4, N, NUM, 0) \
143 _(SOFTFP, softfp_mul, 4, N, NUM, 0) \
144 _(SOFTFP, softfp_div, 4, N, NUM, 0) \
145 _(SOFTFP, softfp_cmp, 4, N, NIL, 0) \
146 _(SOFTFP, softfp_i2d, 1, N, NUM, 0) \
147 _(SOFTFP, softfp_d2i, 2, N, INT, 0) \
148 _(SOFTFP_FFI, softfp_ui2d, 1, N, NUM, 0) \
149 _(SOFTFP_FFI, softfp_f2d, 1, N, NUM, 0) \
150 _(SOFTFP_FFI, softfp_d2ui, 2, N, INT, 0) \
151 _(SOFTFP_FFI, softfp_d2f, 2, N, FLOAT, 0) \
152 _(SOFTFP_FFI, softfp_i2f, 1, N, FLOAT, 0) \
153 _(SOFTFP_FFI, softfp_ui2f, 1, N, FLOAT, 0) \
154 _(SOFTFP_FFI, softfp_f2i, 1, N, INT, 0) \
155 _(SOFTFP_FFI, softfp_f2ui, 1, N, INT, 0) \
156 _(FP64_FFI, fp64_l2d, 2, N, NUM, 0) \
157 _(FP64_FFI, fp64_ul2d, 2, N, NUM, 0) \
158 _(FP64_FFI, fp64_l2f, 2, N, FLOAT, 0) \
159 _(FP64_FFI, fp64_ul2f, 2, N, FLOAT, 0) \
160 _(FP64_FFI, fp64_d2l, 2, N, I64, 0) \
161 _(FP64_FFI, fp64_d2ul, 2, N, U64, 0) \
162 _(FP64_FFI, fp64_f2l, 1, N, I64, 0) \
163 _(FP64_FFI, fp64_f2ul, 1, N, U64, 0) \
164 _(FFI, lj_carith_divi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \
165 _(FFI, lj_carith_divu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \
166 _(FFI, lj_carith_modi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \
167 _(FFI, lj_carith_modu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \
168 _(FFI, lj_carith_powi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \
169 _(FFI, lj_carith_powu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \
170 _(FFI, lj_cdata_setfin, 2, FN, P32, CCI_L) \
171 _(FFI, strlen, 1, L, INTP, 0) \
172 _(FFI, memcpy, 3, S, PTR, 0) \
173 _(FFI, memset, 3, S, PTR, 0) \
174 _(FFI, lj_vm_errno, 0, S, INT, CCI_NOFPRCLOBBER) \
175 _(FFI32, lj_carith_mul64, ARG2_64, N, I64, CCI_NOFPRCLOBBER)
176 \
177 /* End of list. */
178
179typedef enum {
180#define IRCALLENUM(cond, name, nargs, kind, type, flags) IRCALL_##name,
181IRCALLDEF(IRCALLENUM)
182#undef IRCALLENUM
183 IRCALL__MAX
184} IRCallID;
185
186LJ_FUNC TRef lj_ir_call(jit_State *J, IRCallID id, ...);
187
188LJ_DATA const CCallInfo lj_ir_callinfo[IRCALL__MAX+1];
189
190/* Soft-float declarations. */
191#if LJ_SOFTFP
192#if LJ_TARGET_ARM
193#define softfp_add __aeabi_dadd
194#define softfp_sub __aeabi_dsub
195#define softfp_mul __aeabi_dmul
196#define softfp_div __aeabi_ddiv
197#define softfp_cmp __aeabi_cdcmple
198#define softfp_i2d __aeabi_i2d
199#define softfp_d2i __aeabi_d2iz
200#define softfp_ui2d __aeabi_ui2d
201#define softfp_f2d __aeabi_f2d
202#define softfp_d2ui __aeabi_d2uiz
203#define softfp_d2f __aeabi_d2f
204#define softfp_i2f __aeabi_i2f
205#define softfp_ui2f __aeabi_ui2f
206#define softfp_f2i __aeabi_f2iz
207#define softfp_f2ui __aeabi_f2uiz
208#define fp64_l2d __aeabi_l2d
209#define fp64_ul2d __aeabi_ul2d
210#define fp64_l2f __aeabi_l2f
211#define fp64_ul2f __aeabi_ul2f
212#if LJ_TARGET_OSX
213#define fp64_d2l __fixdfdi
214#define fp64_d2ul __fixunsdfdi
215#define fp64_f2l __fixsfdi
216#define fp64_f2ul __fixunssfdi
217#else
218#define fp64_d2l __aeabi_d2lz
219#define fp64_d2ul __aeabi_d2ulz
220#define fp64_f2l __aeabi_f2lz
221#define fp64_f2ul __aeabi_f2ulz
222#endif
223#else
224#error "Missing soft-float definitions for target architecture"
225#endif
226extern double softfp_add(double a, double b);
227extern double softfp_sub(double a, double b);
228extern double softfp_mul(double a, double b);
229extern double softfp_div(double a, double b);
230extern void softfp_cmp(double a, double b);
231extern double softfp_i2d(int32_t a);
232extern int32_t softfp_d2i(double a);
233#if LJ_HASFFI
234extern double softfp_ui2d(uint32_t a);
235extern double softfp_f2d(float a);
236extern uint32_t softfp_d2ui(double a);
237extern float softfp_d2f(double a);
238extern float softfp_i2f(int32_t a);
239extern float softfp_ui2f(uint32_t a);
240extern int32_t softfp_f2i(float a);
241extern uint32_t softfp_f2ui(float a);
242#endif
243#endif
244
245#if LJ_HASFFI && LJ_NEED_FP64
246#ifdef __GNUC__
247#define fp64_l2d __floatdidf
248#define fp64_ul2d __floatundidf
249#define fp64_l2f __floatdisf
250#define fp64_ul2f __floatundisf
251#define fp64_d2l __fixdfdi
252#define fp64_d2ul __fixunsdfdi
253#define fp64_f2l __fixsfdi
254#define fp64_f2ul __fixunssfdi
255#else
256#error "Missing fp64 helper definitions for this compiler"
257#endif
258#endif
259
260#if LJ_HASFFI && (LJ_SOFTFP || LJ_NEED_FP64)
261extern double fp64_l2d(int64_t a);
262extern double fp64_ul2d(uint64_t a);
263extern float fp64_l2f(int64_t a);
264extern float fp64_ul2f(uint64_t a);
265extern int64_t fp64_d2l(double a);
266extern uint64_t fp64_d2ul(double a);
267extern int64_t fp64_f2l(float a);
268extern uint64_t fp64_f2ul(float a);
269#endif
270
271#endif
diff --git a/libraries/luajit-2.0/src/lj_iropt.h b/libraries/luajit-2.0/src/lj_iropt.h
new file mode 100644
index 0000000..3059fb9
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_iropt.h
@@ -0,0 +1,159 @@
1/*
2** Common header for IR emitter and optimizations.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_IROPT_H
7#define _LJ_IROPT_H
8
9#include <stdarg.h>
10
11#include "lj_obj.h"
12#include "lj_jit.h"
13
14#if LJ_HASJIT
15/* IR emitter. */
16LJ_FUNC void LJ_FASTCALL lj_ir_growtop(jit_State *J);
17LJ_FUNC TRef LJ_FASTCALL lj_ir_emit(jit_State *J);
18
19/* Save current IR in J->fold.ins, but do not emit it (yet). */
20static LJ_AINLINE void lj_ir_set_(jit_State *J, uint16_t ot, IRRef1 a, IRRef1 b)
21{
22 J->fold.ins.ot = ot; J->fold.ins.op1 = a; J->fold.ins.op2 = b;
23}
24
25#define lj_ir_set(J, ot, a, b) \
26 lj_ir_set_(J, (uint16_t)(ot), (IRRef1)(a), (IRRef1)(b))
27
28/* Get ref of next IR instruction and optionally grow IR.
29** Note: this may invalidate all IRIns*!
30*/
31static LJ_AINLINE IRRef lj_ir_nextins(jit_State *J)
32{
33 IRRef ref = J->cur.nins;
34 if (LJ_UNLIKELY(ref >= J->irtoplim)) lj_ir_growtop(J);
35 J->cur.nins = ref + 1;
36 return ref;
37}
38
39/* Interning of constants. */
40LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k);
41LJ_FUNC void lj_ir_k64_freeall(jit_State *J);
42LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv);
43LJ_FUNC cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64);
44LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64);
45LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n);
46LJ_FUNC TRef lj_ir_kint64(jit_State *J, uint64_t u64);
47LJ_FUNC TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t);
48LJ_FUNC TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr);
49LJ_FUNC TRef lj_ir_knull(jit_State *J, IRType t);
50LJ_FUNC TRef lj_ir_kslot(jit_State *J, TRef key, IRRef slot);
51
52#if LJ_64
53#define lj_ir_kintp(J, k) lj_ir_kint64(J, (uint64_t)(k))
54#else
55#define lj_ir_kintp(J, k) lj_ir_kint(J, (int32_t)(k))
56#endif
57
58static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n)
59{
60 TValue tv;
61 tv.n = n;
62 return lj_ir_knum_u64(J, tv.u64);
63}
64
65#define lj_ir_kstr(J, str) lj_ir_kgc(J, obj2gco((str)), IRT_STR)
66#define lj_ir_ktab(J, tab) lj_ir_kgc(J, obj2gco((tab)), IRT_TAB)
67#define lj_ir_kfunc(J, func) lj_ir_kgc(J, obj2gco((func)), IRT_FUNC)
68#define lj_ir_kptr(J, ptr) lj_ir_kptr_(J, IR_KPTR, (ptr))
69#define lj_ir_kkptr(J, ptr) lj_ir_kptr_(J, IR_KKPTR, (ptr))
70
71/* Special FP constants. */
72#define lj_ir_knum_zero(J) lj_ir_knum_u64(J, U64x(00000000,00000000))
73#define lj_ir_knum_one(J) lj_ir_knum_u64(J, U64x(3ff00000,00000000))
74#define lj_ir_knum_tobit(J) lj_ir_knum_u64(J, U64x(43380000,00000000))
75
76/* Special 128 bit SIMD constants. */
77#define lj_ir_knum_abs(J) lj_ir_k64(J, IR_KNUM, LJ_KSIMD(J, LJ_KSIMD_ABS))
78#define lj_ir_knum_neg(J) lj_ir_k64(J, IR_KNUM, LJ_KSIMD(J, LJ_KSIMD_NEG))
79
80/* Access to constants. */
81LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir);
82
83/* Convert IR operand types. */
84LJ_FUNC TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr);
85LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr);
86LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr);
87
88/* Miscellaneous IR ops. */
89LJ_FUNC int lj_ir_numcmp(lua_Number a, lua_Number b, IROp op);
90LJ_FUNC int lj_ir_strcmp(GCstr *a, GCstr *b, IROp op);
91LJ_FUNC void lj_ir_rollback(jit_State *J, IRRef ref);
92
93/* Emit IR instructions with on-the-fly optimizations. */
94LJ_FUNC TRef LJ_FASTCALL lj_opt_fold(jit_State *J);
95LJ_FUNC TRef LJ_FASTCALL lj_opt_cse(jit_State *J);
96LJ_FUNC TRef LJ_FASTCALL lj_opt_cselim(jit_State *J, IRRef lim);
97
98/* Special return values for the fold functions. */
99enum {
100 NEXTFOLD, /* Couldn't fold, pass on. */
101 RETRYFOLD, /* Retry fold with modified fins. */
102 KINTFOLD, /* Return ref for int constant in fins->i. */
103 FAILFOLD, /* Guard would always fail. */
104 DROPFOLD, /* Guard eliminated. */
105 MAX_FOLD
106};
107
108#define INTFOLD(k) ((J->fold.ins.i = (k)), (TRef)KINTFOLD)
109#define INT64FOLD(k) (lj_ir_kint64(J, (k)))
110#define CONDFOLD(cond) ((TRef)FAILFOLD + (TRef)(cond))
111#define LEFTFOLD (J->fold.ins.op1)
112#define RIGHTFOLD (J->fold.ins.op2)
113#define CSEFOLD (lj_opt_cse(J))
114#define EMITFOLD (lj_ir_emit(J))
115
116/* Load/store forwarding. */
117LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_aload(jit_State *J);
118LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_hload(jit_State *J);
119LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J);
120LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J);
121LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J);
122LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J);
123LJ_FUNC int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J);
124LJ_FUNC int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim);
125LJ_FUNC int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref);
126
127/* Dead-store elimination. */
128LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_ahstore(jit_State *J);
129LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_ustore(jit_State *J);
130LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_fstore(jit_State *J);
131LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_xstore(jit_State *J);
132
133/* Narrowing. */
134LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_convert(jit_State *J);
135LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_index(jit_State *J, TRef key);
136LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_toint(jit_State *J, TRef tr);
137LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_tobit(jit_State *J, TRef tr);
138#if LJ_HASFFI
139LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef key);
140#endif
141LJ_FUNC TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc,
142 TValue *vb, TValue *vc, IROp op);
143LJ_FUNC TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc);
144LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vc);
145LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc);
146LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase);
147
148/* Optimization passes. */
149LJ_FUNC void lj_opt_dce(jit_State *J);
150LJ_FUNC int lj_opt_loop(jit_State *J);
151#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
152LJ_FUNC void lj_opt_split(jit_State *J);
153#else
154#define lj_opt_split(J) UNUSED(J)
155#endif
156
157#endif
158
159#endif
diff --git a/libraries/luajit-2.0/src/lj_jit.h b/libraries/luajit-2.0/src/lj_jit.h
new file mode 100644
index 0000000..8a4c04c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_jit.h
@@ -0,0 +1,394 @@
1/*
2** Common definitions for the JIT compiler.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_JIT_H
7#define _LJ_JIT_H
8
9#include "lj_obj.h"
10#include "lj_ir.h"
11
12/* JIT engine flags. */
13#define JIT_F_ON 0x00000001
14
15/* CPU-specific JIT engine flags. */
16#if LJ_TARGET_X86ORX64
17#define JIT_F_CMOV 0x00000010
18#define JIT_F_SSE2 0x00000020
19#define JIT_F_SSE3 0x00000040
20#define JIT_F_SSE4_1 0x00000080
21#define JIT_F_P4 0x00000100
22#define JIT_F_PREFER_IMUL 0x00000200
23#define JIT_F_SPLIT_XMM 0x00000400
24#define JIT_F_LEA_AGU 0x00000800
25
26/* Names for the CPU-specific flags. Must match the order above. */
27#define JIT_F_CPU_FIRST JIT_F_CMOV
28#define JIT_F_CPUSTRING "\4CMOV\4SSE2\4SSE3\6SSE4.1\2P4\3AMD\2K8\4ATOM"
29#elif LJ_TARGET_ARM
30#define JIT_F_ARMV6 0x00000010
31#define JIT_F_ARMV6T2 0x00000020
32#define JIT_F_ARMV7 0x00000040
33
34/* Names for the CPU-specific flags. Must match the order above. */
35#define JIT_F_CPU_FIRST JIT_F_ARMV6
36#define JIT_F_CPUSTRING "\5ARMv6\7ARMv6T2\5ARMv7"
37#else
38#define JIT_F_CPU_FIRST 0
39#define JIT_F_CPUSTRING ""
40#endif
41
42/* Optimization flags. */
43#define JIT_F_OPT_MASK 0x0fff0000
44
45#define JIT_F_OPT_FOLD 0x00010000
46#define JIT_F_OPT_CSE 0x00020000
47#define JIT_F_OPT_DCE 0x00040000
48#define JIT_F_OPT_FWD 0x00080000
49#define JIT_F_OPT_DSE 0x00100000
50#define JIT_F_OPT_NARROW 0x00200000
51#define JIT_F_OPT_LOOP 0x00400000
52#define JIT_F_OPT_ABC 0x00800000
53#define JIT_F_OPT_FUSE 0x01000000
54
55/* Optimizations names for -O. Must match the order above. */
56#define JIT_F_OPT_FIRST JIT_F_OPT_FOLD
57#define JIT_F_OPTSTRING \
58 "\4fold\3cse\3dce\3fwd\3dse\6narrow\4loop\3abc\4fuse"
59
60/* Optimization levels set a fixed combination of flags. */
61#define JIT_F_OPT_0 0
62#define JIT_F_OPT_1 (JIT_F_OPT_FOLD|JIT_F_OPT_CSE|JIT_F_OPT_DCE)
63#define JIT_F_OPT_2 (JIT_F_OPT_1|JIT_F_OPT_NARROW|JIT_F_OPT_LOOP)
64#define JIT_F_OPT_3 \
65 (JIT_F_OPT_2|JIT_F_OPT_FWD|JIT_F_OPT_DSE|JIT_F_OPT_ABC|JIT_F_OPT_FUSE)
66#define JIT_F_OPT_DEFAULT JIT_F_OPT_3
67
68#if LJ_TARGET_WINDOWS || LJ_64
69/* See: http://blogs.msdn.com/oldnewthing/archive/2003/10/08/55239.aspx */
70#define JIT_P_sizemcode_DEFAULT 64
71#else
72/* Could go as low as 4K, but the mmap() overhead would be rather high. */
73#define JIT_P_sizemcode_DEFAULT 32
74#endif
75
76/* Optimization parameters and their defaults. Length is a char in octal! */
77#define JIT_PARAMDEF(_) \
78 _(\010, maxtrace, 1000) /* Max. # of traces in cache. */ \
79 _(\011, maxrecord, 4000) /* Max. # of recorded IR instructions. */ \
80 _(\012, maxirconst, 500) /* Max. # of IR constants of a trace. */ \
81 _(\007, maxside, 100) /* Max. # of side traces of a root trace. */ \
82 _(\007, maxsnap, 500) /* Max. # of snapshots for a trace. */ \
83 \
84 _(\007, hotloop, 56) /* # of iter. to detect a hot loop/call. */ \
85 _(\007, hotexit, 10) /* # of taken exits to start a side trace. */ \
86 _(\007, tryside, 4) /* # of attempts to compile a side trace. */ \
87 \
88 _(\012, instunroll, 4) /* Max. unroll for instable loops. */ \
89 _(\012, loopunroll, 15) /* Max. unroll for loop ops in side traces. */ \
90 _(\012, callunroll, 3) /* Max. unroll for recursive calls. */ \
91 _(\011, recunroll, 2) /* Min. unroll for true recursion. */ \
92 \
93 /* Size of each machine code area (in KBytes). */ \
94 _(\011, sizemcode, JIT_P_sizemcode_DEFAULT) \
95 /* Max. total size of all machine code areas (in KBytes). */ \
96 _(\010, maxmcode, 512) \
97 /* End of list. */
98
99enum {
100#define JIT_PARAMENUM(len, name, value) JIT_P_##name,
101JIT_PARAMDEF(JIT_PARAMENUM)
102#undef JIT_PARAMENUM
103 JIT_P__MAX
104};
105
106#define JIT_PARAMSTR(len, name, value) #len #name
107#define JIT_P_STRING JIT_PARAMDEF(JIT_PARAMSTR)
108
109/* Trace compiler state. */
110typedef enum {
111 LJ_TRACE_IDLE, /* Trace compiler idle. */
112 LJ_TRACE_ACTIVE = 0x10,
113 LJ_TRACE_RECORD, /* Bytecode recording active. */
114 LJ_TRACE_START, /* New trace started. */
115 LJ_TRACE_END, /* End of trace. */
116 LJ_TRACE_ASM, /* Assemble trace. */
117 LJ_TRACE_ERR /* Trace aborted with error. */
118} TraceState;
119
120/* Post-processing action. */
121typedef enum {
122 LJ_POST_NONE, /* No action. */
123 LJ_POST_FIXCOMP, /* Fixup comparison and emit pending guard. */
124 LJ_POST_FIXGUARD, /* Fixup and emit pending guard. */
125 LJ_POST_FIXGUARDSNAP, /* Fixup and emit pending guard and snapshot. */
126 LJ_POST_FIXBOOL, /* Fixup boolean result. */
127 LJ_POST_FFRETRY /* Suppress recording of retried fast functions. */
128} PostProc;
129
130/* Machine code type. */
131#if LJ_TARGET_X86ORX64
132typedef uint8_t MCode;
133#else
134typedef uint32_t MCode;
135#endif
136
137/* Stack snapshot header. */
138typedef struct SnapShot {
139 uint16_t mapofs; /* Offset into snapshot map. */
140 IRRef1 ref; /* First IR ref for this snapshot. */
141 uint8_t nslots; /* Number of valid slots. */
142 uint8_t topslot; /* Maximum frame extent. */
143 uint8_t nent; /* Number of compressed entries. */
144 uint8_t count; /* Count of taken exits for this snapshot. */
145} SnapShot;
146
147#define SNAPCOUNT_DONE 255 /* Already compiled and linked a side trace. */
148
149/* Compressed snapshot entry. */
150typedef uint32_t SnapEntry;
151
152#define SNAP_FRAME 0x010000 /* Frame slot. */
153#define SNAP_CONT 0x020000 /* Continuation slot. */
154#define SNAP_NORESTORE 0x040000 /* No need to restore slot. */
155#define SNAP_SOFTFPNUM 0x080000 /* Soft-float number. */
156LJ_STATIC_ASSERT(SNAP_FRAME == TREF_FRAME);
157LJ_STATIC_ASSERT(SNAP_CONT == TREF_CONT);
158
159#define SNAP(slot, flags, ref) (((SnapEntry)(slot) << 24) + (flags) + (ref))
160#define SNAP_TR(slot, tr) \
161 (((SnapEntry)(slot) << 24) + ((tr) & (TREF_CONT|TREF_FRAME|TREF_REFMASK)))
162#define SNAP_MKPC(pc) ((SnapEntry)u32ptr(pc))
163#define SNAP_MKFTSZ(ftsz) ((SnapEntry)(ftsz))
164#define snap_ref(sn) ((sn) & 0xffff)
165#define snap_slot(sn) ((BCReg)((sn) >> 24))
166#define snap_isframe(sn) ((sn) & SNAP_FRAME)
167#define snap_pc(sn) ((const BCIns *)(uintptr_t)(sn))
168#define snap_setref(sn, ref) (((sn) & (0xffff0000&~SNAP_NORESTORE)) | (ref))
169
170/* Snapshot and exit numbers. */
171typedef uint32_t SnapNo;
172typedef uint32_t ExitNo;
173
174/* Trace number. */
175typedef uint32_t TraceNo; /* Used to pass around trace numbers. */
176typedef uint16_t TraceNo1; /* Stored trace number. */
177
178/* Type of link. ORDER LJ_TRLINK */
179typedef enum {
180 LJ_TRLINK_NONE, /* Incomplete trace. No link, yet. */
181 LJ_TRLINK_ROOT, /* Link to other root trace. */
182 LJ_TRLINK_LOOP, /* Loop to same trace. */
183 LJ_TRLINK_TAILREC, /* Tail-recursion. */
184 LJ_TRLINK_UPREC, /* Up-recursion. */
185 LJ_TRLINK_DOWNREC, /* Down-recursion. */
186 LJ_TRLINK_INTERP, /* Fallback to interpreter. */
187 LJ_TRLINK_RETURN /* Return to interpreter. */
188} TraceLink;
189
190/* Trace object. */
191typedef struct GCtrace {
192 GCHeader;
193 uint8_t topslot; /* Top stack slot already checked to be allocated. */
194 uint8_t linktype; /* Type of link. */
195 IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */
196 GCRef gclist;
197 IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */
198 IRRef nk; /* Lowest IR constant. Biased with REF_BIAS. */
199 uint16_t nsnap; /* Number of snapshots. */
200 uint16_t nsnapmap; /* Number of snapshot map elements. */
201 SnapShot *snap; /* Snapshot array. */
202 SnapEntry *snapmap; /* Snapshot map. */
203 GCRef startpt; /* Starting prototype. */
204 MRef startpc; /* Bytecode PC of starting instruction. */
205 BCIns startins; /* Original bytecode of starting instruction. */
206 MSize szmcode; /* Size of machine code. */
207 MCode *mcode; /* Start of machine code. */
208 MSize mcloop; /* Offset of loop start in machine code. */
209 uint16_t nchild; /* Number of child traces (root trace only). */
210 uint16_t spadjust; /* Stack pointer adjustment (offset in bytes). */
211 TraceNo1 traceno; /* Trace number. */
212 TraceNo1 link; /* Linked trace (or self for loops). */
213 TraceNo1 root; /* Root trace of side trace (or 0 for root traces). */
214 TraceNo1 nextroot; /* Next root trace for same prototype. */
215 TraceNo1 nextside; /* Next side trace of same root trace. */
216 uint16_t unused2;
217#ifdef LUAJIT_USE_GDBJIT
218 void *gdbjit_entry; /* GDB JIT entry. */
219#endif
220} GCtrace;
221
222#define gco2trace(o) check_exp((o)->gch.gct == ~LJ_TTRACE, (GCtrace *)(o))
223#define traceref(J, n) \
224 check_exp((n)>0 && (MSize)(n)<J->sizetrace, (GCtrace *)gcref(J->trace[(n)]))
225
226LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCtrace, gclist));
227
228static LJ_AINLINE MSize snap_nextofs(GCtrace *T, SnapShot *snap)
229{
230 if (snap+1 == &T->snap[T->nsnap])
231 return T->nsnapmap;
232 else
233 return (snap+1)->mapofs;
234}
235
236/* Round-robin penalty cache for bytecodes leading to aborted traces. */
237typedef struct HotPenalty {
238 MRef pc; /* Starting bytecode PC. */
239 uint16_t val; /* Penalty value, i.e. hotcount start. */
240 uint16_t reason; /* Abort reason (really TraceErr). */
241} HotPenalty;
242
243#define PENALTY_SLOTS 64 /* Penalty cache slot. Must be a power of 2. */
244#define PENALTY_MIN (36*2) /* Minimum penalty value. */
245#define PENALTY_MAX 60000 /* Maximum penalty value. */
246#define PENALTY_RNDBITS 4 /* # of random bits to add to penalty value. */
247
248/* Round-robin backpropagation cache for narrowing conversions. */
249typedef struct BPropEntry {
250 IRRef1 key; /* Key: original reference. */
251 IRRef1 val; /* Value: reference after conversion. */
252 IRRef mode; /* Mode for this entry (currently IRCONV_*). */
253} BPropEntry;
254
255/* Number of slots for the backpropagation cache. Must be a power of 2. */
256#define BPROP_SLOTS 16
257
258/* Scalar evolution analysis cache. */
259typedef struct ScEvEntry {
260 IRRef1 idx; /* Index reference. */
261 IRRef1 start; /* Constant start reference. */
262 IRRef1 stop; /* Constant stop reference. */
263 IRRef1 step; /* Constant step reference. */
264 IRType1 t; /* Scalar type. */
265 uint8_t dir; /* Direction. 1: +, 0: -. */
266} ScEvEntry;
267
268/* 128 bit SIMD constants. */
269enum {
270 LJ_KSIMD_ABS,
271 LJ_KSIMD_NEG,
272 LJ_KSIMD__MAX
273};
274
275/* Get 16 byte aligned pointer to SIMD constant. */
276#define LJ_KSIMD(J, n) \
277 ((TValue *)(((intptr_t)&J->ksimd[2*(n)] + 15) & ~(intptr_t)15))
278
279/* Set/reset flag to activate the SPLIT pass for the current trace. */
280#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
281#define lj_needsplit(J) (J->needsplit = 1)
282#define lj_resetsplit(J) (J->needsplit = 0)
283#else
284#define lj_needsplit(J) UNUSED(J)
285#define lj_resetsplit(J) UNUSED(J)
286#endif
287
288/* Fold state is used to fold instructions on-the-fly. */
289typedef struct FoldState {
290 IRIns ins; /* Currently emitted instruction. */
291 IRIns left; /* Instruction referenced by left operand. */
292 IRIns right; /* Instruction referenced by right operand. */
293} FoldState;
294
295/* JIT compiler state. */
296typedef struct jit_State {
297 GCtrace cur; /* Current trace. */
298
299 lua_State *L; /* Current Lua state. */
300 const BCIns *pc; /* Current PC. */
301 GCfunc *fn; /* Current function. */
302 GCproto *pt; /* Current prototype. */
303 TRef *base; /* Current frame base, points into J->slots. */
304
305 uint32_t flags; /* JIT engine flags. */
306 BCReg maxslot; /* Relative to baseslot. */
307 BCReg baseslot; /* Current frame base, offset into J->slots. */
308
309 uint8_t mergesnap; /* Allowed to merge with next snapshot. */
310 uint8_t needsnap; /* Need snapshot before recording next bytecode. */
311 IRType1 guardemit; /* Accumulated IRT_GUARD for emitted instructions. */
312 uint8_t bcskip; /* Number of bytecode instructions to skip. */
313
314 FoldState fold; /* Fold state. */
315
316 const BCIns *bc_min; /* Start of allowed bytecode range for root trace. */
317 MSize bc_extent; /* Extent of the range. */
318
319 TraceState state; /* Trace compiler state. */
320
321 int32_t instunroll; /* Unroll counter for instable loops. */
322 int32_t loopunroll; /* Unroll counter for loop ops in side traces. */
323 int32_t tailcalled; /* Number of successive tailcalls. */
324 int32_t framedepth; /* Current frame depth. */
325 int32_t retdepth; /* Return frame depth (count of RETF). */
326
327 MRef k64; /* Pointer to chained array of 64 bit constants. */
328 TValue ksimd[LJ_KSIMD__MAX*2+1]; /* 16 byte aligned SIMD constants. */
329
330 IRIns *irbuf; /* Temp. IR instruction buffer. Biased with REF_BIAS. */
331 IRRef irtoplim; /* Upper limit of instuction buffer (biased). */
332 IRRef irbotlim; /* Lower limit of instuction buffer (biased). */
333 IRRef loopref; /* Last loop reference or ref of final LOOP (or 0). */
334
335 MSize sizesnap; /* Size of temp. snapshot buffer. */
336 SnapShot *snapbuf; /* Temp. snapshot buffer. */
337 SnapEntry *snapmapbuf; /* Temp. snapshot map buffer. */
338 MSize sizesnapmap; /* Size of temp. snapshot map buffer. */
339
340 PostProc postproc; /* Required post-processing after execution. */
341#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
342 int needsplit; /* Need SPLIT pass. */
343#endif
344
345 GCRef *trace; /* Array of traces. */
346 TraceNo freetrace; /* Start of scan for next free trace. */
347 MSize sizetrace; /* Size of trace array. */
348
349 IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */
350 TRef slot[LJ_MAX_JSLOTS+LJ_STACK_EXTRA]; /* Stack slot map. */
351
352 int32_t param[JIT_P__MAX]; /* JIT engine parameters. */
353
354 MCode *exitstubgroup[LJ_MAX_EXITSTUBGR]; /* Exit stub group addresses. */
355
356 HotPenalty penalty[PENALTY_SLOTS]; /* Penalty slots. */
357 uint32_t penaltyslot; /* Round-robin index into penalty slots. */
358 uint32_t prngstate; /* PRNG state. */
359
360 BPropEntry bpropcache[BPROP_SLOTS]; /* Backpropagation cache slots. */
361 uint32_t bpropslot; /* Round-robin index into bpropcache slots. */
362
363 ScEvEntry scev; /* Scalar evolution analysis cache slots. */
364
365 const BCIns *startpc; /* Bytecode PC of starting instruction. */
366 TraceNo parent; /* Parent of current side trace (0 for root traces). */
367 ExitNo exitno; /* Exit number in parent of current side trace. */
368
369 BCIns *patchpc; /* PC for pending re-patch. */
370 BCIns patchins; /* Instruction for pending re-patch. */
371
372 int mcprot; /* Protection of current mcode area. */
373 MCode *mcarea; /* Base of current mcode area. */
374 MCode *mctop; /* Top of current mcode area. */
375 MCode *mcbot; /* Bottom of current mcode area. */
376 size_t szmcarea; /* Size of current mcode area. */
377 size_t szallmcarea; /* Total size of all allocated mcode areas. */
378
379 TValue errinfo; /* Additional info element for trace errors. */
380}
381#if LJ_TARGET_ARM
382LJ_ALIGN(16) /* For DISPATCH-relative addresses in assembler part. */
383#endif
384jit_State;
385
386/* Trivial PRNG e.g. used for penalty randomization. */
387static LJ_AINLINE uint32_t LJ_PRNG_BITS(jit_State *J, int bits)
388{
389 /* Yes, this LCG is very weak, but that doesn't matter for our use case. */
390 J->prngstate = J->prngstate * 1103515245 + 12345;
391 return J->prngstate >> (32-bits);
392}
393
394#endif
diff --git a/libraries/luajit-2.0/src/lj_lex.c b/libraries/luajit-2.0/src/lj_lex.c
new file mode 100644
index 0000000..00daccd
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_lex.c
@@ -0,0 +1,505 @@
1/*
2** Lexical analyzer.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lj_lex_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_str.h"
16#if LJ_HASFFI
17#include "lj_tab.h"
18#include "lj_ctype.h"
19#include "lj_cdata.h"
20#include "lualib.h"
21#endif
22#include "lj_state.h"
23#include "lj_lex.h"
24#include "lj_parse.h"
25#include "lj_char.h"
26
27/* Lua lexer token names. */
28static const char *const tokennames[] = {
29#define TKSTR1(name) #name,
30#define TKSTR2(name, sym) #sym,
31TKDEF(TKSTR1, TKSTR2)
32#undef TKSTR1
33#undef TKSTR2
34 NULL
35};
36
37/* -- Buffer handling ----------------------------------------------------- */
38
39#define char2int(c) ((int)(uint8_t)(c))
40#define next(ls) \
41 (ls->current = (ls->n--) > 0 ? char2int(*ls->p++) : fillbuf(ls))
42#define save_and_next(ls) (save(ls, ls->current), next(ls))
43#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
44#define END_OF_STREAM (-1)
45
46static int fillbuf(LexState *ls)
47{
48 size_t sz;
49 const char *buf = ls->rfunc(ls->L, ls->rdata, &sz);
50 if (buf == NULL || sz == 0) return END_OF_STREAM;
51 ls->n = (MSize)sz - 1;
52 ls->p = buf;
53 return char2int(*(ls->p++));
54}
55
56static LJ_NOINLINE void save_grow(LexState *ls, int c)
57{
58 MSize newsize;
59 if (ls->sb.sz >= LJ_MAX_STR/2)
60 lj_lex_error(ls, 0, LJ_ERR_XELEM);
61 newsize = ls->sb.sz * 2;
62 lj_str_resizebuf(ls->L, &ls->sb, newsize);
63 ls->sb.buf[ls->sb.n++] = (char)c;
64}
65
66static LJ_AINLINE void save(LexState *ls, int c)
67{
68 if (LJ_UNLIKELY(ls->sb.n + 1 > ls->sb.sz))
69 save_grow(ls, c);
70 else
71 ls->sb.buf[ls->sb.n++] = (char)c;
72}
73
74static void inclinenumber(LexState *ls)
75{
76 int old = ls->current;
77 lua_assert(currIsNewline(ls));
78 next(ls); /* skip `\n' or `\r' */
79 if (currIsNewline(ls) && ls->current != old)
80 next(ls); /* skip `\n\r' or `\r\n' */
81 if (++ls->linenumber >= LJ_MAX_LINE)
82 lj_lex_error(ls, ls->token, LJ_ERR_XLINES);
83}
84
85/* -- Scanner for terminals ----------------------------------------------- */
86
87#if LJ_HASFFI
88/* Load FFI library on-demand. Needed if we create cdata objects. */
89static void lex_loadffi(lua_State *L)
90{
91 ptrdiff_t oldtop = savestack(L, L->top);
92 luaopen_ffi(L);
93 L->top = restorestack(L, oldtop);
94}
95
96/* Parse 64 bit integer. */
97static int lex_number64(LexState *ls, TValue *tv)
98{
99 uint64_t n = 0;
100 uint8_t *p = (uint8_t *)ls->sb.buf;
101 CTypeID id = CTID_INT64;
102 GCcdata *cd;
103 int numl = 0;
104 if (p[0] == '0' && (p[1] & ~0x20) == 'X') { /* Hexadecimal. */
105 p += 2;
106 if (!lj_char_isxdigit(*p)) return 0;
107 do {
108 n = n*16 + (*p & 15);
109 if (!lj_char_isdigit(*p)) n += 9;
110 p++;
111 } while (lj_char_isxdigit(*p));
112 } else { /* Decimal. */
113 if (!lj_char_isdigit(*p)) return 0;
114 do {
115 n = n*10 + (*p - '0');
116 p++;
117 } while (lj_char_isdigit(*p));
118 }
119 for (;;) { /* Parse suffixes. */
120 if ((*p & ~0x20) == 'U')
121 id = CTID_UINT64;
122 else if ((*p & ~0x20) == 'L')
123 numl++;
124 else
125 break;
126 p++;
127 }
128 if (numl != 2 || *p != '\0') return 0;
129 /* Return cdata holding a 64 bit integer. */
130 cd = lj_cdata_new_(ls->L, id, 8);
131 *(uint64_t *)cdataptr(cd) = n;
132 lj_parse_keepcdata(ls, tv, cd);
133 return 1; /* Ok. */
134}
135#endif
136
137/* Parse a number literal. */
138static void lex_number(LexState *ls, TValue *tv)
139{
140 int c;
141 lua_assert(lj_char_isdigit(ls->current));
142 do {
143 c = ls->current;
144 save_and_next(ls);
145 } while (lj_char_isident(ls->current) || ls->current == '.' ||
146 ((ls->current == '-' || ls->current == '+') &&
147 ((c & ~0x20) == 'E' || (c & ~0x20) == 'P')));
148#if LJ_HASFFI
149 c &= ~0x20;
150 if ((c == 'I' || c == 'L' || c == 'U') && !ctype_ctsG(G(ls->L)))
151 lex_loadffi(ls->L);
152 if (c == 'I') /* Parse imaginary part of complex number. */
153 ls->sb.n--;
154#endif
155 save(ls, '\0');
156#if LJ_HASFFI
157 if ((c == 'L' || c == 'U') && lex_number64(ls, tv)) { /* Parse 64 bit int. */
158 return;
159 } else
160#endif
161 if (lj_str_numconv(ls->sb.buf, tv)) {
162#if LJ_HASFFI
163 if (c == 'I') { /* Return cdata holding a complex number. */
164 GCcdata *cd = lj_cdata_new_(ls->L, CTID_COMPLEX_DOUBLE, 2*sizeof(double));
165 ((double *)cdataptr(cd))[0] = 0;
166 ((double *)cdataptr(cd))[1] = numberVnum(tv);
167 lj_parse_keepcdata(ls, tv, cd);
168 }
169#endif
170 if (LJ_DUALNUM && tvisnum(tv)) {
171 int32_t k = lj_num2int(numV(tv));
172 if ((lua_Number)k == numV(tv)) /* -0 cannot end up here. */
173 setintV(tv, k);
174 }
175 return;
176 }
177 lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER);
178}
179
180static int skip_sep(LexState *ls)
181{
182 int count = 0;
183 int s = ls->current;
184 lua_assert(s == '[' || s == ']');
185 save_and_next(ls);
186 while (ls->current == '=') {
187 save_and_next(ls);
188 count++;
189 }
190 return (ls->current == s) ? count : (-count) - 1;
191}
192
193static void read_long_string(LexState *ls, TValue *tv, int sep)
194{
195 save_and_next(ls); /* skip 2nd `[' */
196 if (currIsNewline(ls)) /* string starts with a newline? */
197 inclinenumber(ls); /* skip it */
198 for (;;) {
199 switch (ls->current) {
200 case END_OF_STREAM:
201 lj_lex_error(ls, TK_eof, tv ? LJ_ERR_XLSTR : LJ_ERR_XLCOM);
202 break;
203 case ']':
204 if (skip_sep(ls) == sep) {
205 save_and_next(ls); /* skip 2nd `]' */
206 goto endloop;
207 }
208 break;
209 case '\n':
210 case '\r':
211 save(ls, '\n');
212 inclinenumber(ls);
213 if (!tv) lj_str_resetbuf(&ls->sb); /* avoid wasting space */
214 break;
215 default:
216 if (tv) save_and_next(ls);
217 else next(ls);
218 break;
219 }
220 } endloop:
221 if (tv) {
222 GCstr *str = lj_parse_keepstr(ls, ls->sb.buf + (2 + (MSize)sep),
223 ls->sb.n - 2*(2 + (MSize)sep));
224 setstrV(ls->L, tv, str);
225 }
226}
227
228static void read_string(LexState *ls, int delim, TValue *tv)
229{
230 save_and_next(ls);
231 while (ls->current != delim) {
232 switch (ls->current) {
233 case END_OF_STREAM:
234 lj_lex_error(ls, TK_eof, LJ_ERR_XSTR);
235 continue;
236 case '\n':
237 case '\r':
238 lj_lex_error(ls, TK_string, LJ_ERR_XSTR);
239 continue;
240 case '\\': {
241 int c = next(ls); /* Skip the '\\'. */
242 switch (c) {
243 case 'a': c = '\a'; break;
244 case 'b': c = '\b'; break;
245 case 'f': c = '\f'; break;
246 case 'n': c = '\n'; break;
247 case 'r': c = '\r'; break;
248 case 't': c = '\t'; break;
249 case 'v': c = '\v'; break;
250 case 'x': /* Hexadecimal escape '\xXX'. */
251 c = (next(ls) & 15u) << 4;
252 if (!lj_char_isdigit(ls->current)) {
253 if (!lj_char_isxdigit(ls->current)) goto err_xesc;
254 c += 9 << 4;
255 }
256 c += (next(ls) & 15u);
257 if (!lj_char_isdigit(ls->current)) {
258 if (!lj_char_isxdigit(ls->current)) goto err_xesc;
259 c += 9;
260 }
261 break;
262 case 'z': /* Skip whitespace. */
263 next(ls);
264 while (lj_char_isspace(ls->current))
265 if (currIsNewline(ls)) inclinenumber(ls); else next(ls);
266 continue;
267 case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); continue;
268 case '\\': case '\"': case '\'': break;
269 case END_OF_STREAM: continue;
270 default:
271 if (!lj_char_isdigit(c))
272 goto err_xesc;
273 c -= '0'; /* Decimal escape '\ddd'. */
274 if (lj_char_isdigit(next(ls))) {
275 c = c*10 + (ls->current - '0');
276 if (lj_char_isdigit(next(ls))) {
277 c = c*10 + (ls->current - '0');
278 if (c > 255) {
279 err_xesc:
280 lj_lex_error(ls, TK_string, LJ_ERR_XESC);
281 }
282 next(ls);
283 }
284 }
285 save(ls, c);
286 continue;
287 }
288 save(ls, c);
289 next(ls);
290 continue;
291 }
292 default:
293 save_and_next(ls);
294 break;
295 }
296 }
297 save_and_next(ls); /* skip delimiter */
298 setstrV(ls->L, tv, lj_parse_keepstr(ls, ls->sb.buf + 1, ls->sb.n - 2));
299}
300
301/* -- Main lexical scanner ------------------------------------------------ */
302
303static int llex(LexState *ls, TValue *tv)
304{
305 lj_str_resetbuf(&ls->sb);
306 for (;;) {
307 if (lj_char_isident(ls->current)) {
308 GCstr *s;
309 if (lj_char_isdigit(ls->current)) { /* Numeric literal. */
310 lex_number(ls, tv);
311 return TK_number;
312 }
313 /* Identifier or reserved word. */
314 do {
315 save_and_next(ls);
316 } while (lj_char_isident(ls->current));
317 s = lj_parse_keepstr(ls, ls->sb.buf, ls->sb.n);
318 if (s->reserved > 0) /* Reserved word? */
319 return TK_OFS + s->reserved;
320 setstrV(ls->L, tv, s);
321 return TK_name;
322 }
323 switch (ls->current) {
324 case '\n':
325 case '\r':
326 inclinenumber(ls);
327 continue;
328 case ' ':
329 case '\t':
330 case '\v':
331 case '\f':
332 next(ls);
333 continue;
334 case '-':
335 next(ls);
336 if (ls->current != '-') return '-';
337 /* else is a comment */
338 next(ls);
339 if (ls->current == '[') {
340 int sep = skip_sep(ls);
341 lj_str_resetbuf(&ls->sb); /* `skip_sep' may dirty the buffer */
342 if (sep >= 0) {
343 read_long_string(ls, NULL, sep); /* long comment */
344 lj_str_resetbuf(&ls->sb);
345 continue;
346 }
347 }
348 /* else short comment */
349 while (!currIsNewline(ls) && ls->current != END_OF_STREAM)
350 next(ls);
351 continue;
352 case '[': {
353 int sep = skip_sep(ls);
354 if (sep >= 0) {
355 read_long_string(ls, tv, sep);
356 return TK_string;
357 } else if (sep == -1) {
358 return '[';
359 } else {
360 lj_lex_error(ls, TK_string, LJ_ERR_XLDELIM);
361 continue;
362 }
363 }
364 case '=':
365 next(ls);
366 if (ls->current != '=') return '='; else { next(ls); return TK_eq; }
367 case '<':
368 next(ls);
369 if (ls->current != '=') return '<'; else { next(ls); return TK_le; }
370 case '>':
371 next(ls);
372 if (ls->current != '=') return '>'; else { next(ls); return TK_ge; }
373 case '~':
374 next(ls);
375 if (ls->current != '=') return '~'; else { next(ls); return TK_ne; }
376 case '"':
377 case '\'':
378 read_string(ls, ls->current, tv);
379 return TK_string;
380 case '.':
381 save_and_next(ls);
382 if (ls->current == '.') {
383 next(ls);
384 if (ls->current == '.') {
385 next(ls);
386 return TK_dots; /* ... */
387 }
388 return TK_concat; /* .. */
389 } else if (!lj_char_isdigit(ls->current)) {
390 return '.';
391 } else {
392 lex_number(ls, tv);
393 return TK_number;
394 }
395 case END_OF_STREAM:
396 return TK_eof;
397 default: {
398 int c = ls->current;
399 next(ls);
400 return c; /* Single-char tokens (+ - / ...). */
401 }
402 }
403 }
404}
405
406/* -- Lexer API ----------------------------------------------------------- */
407
408/* Setup lexer state. */
409int lj_lex_setup(lua_State *L, LexState *ls)
410{
411 ls->L = L;
412 ls->fs = NULL;
413 ls->n = 0;
414 ls->p = NULL;
415 ls->vstack = NULL;
416 ls->sizevstack = 0;
417 ls->vtop = 0;
418 ls->bcstack = NULL;
419 ls->sizebcstack = 0;
420 ls->lookahead = TK_eof; /* No look-ahead token. */
421 ls->linenumber = 1;
422 ls->lastline = 1;
423 lj_str_resizebuf(ls->L, &ls->sb, LJ_MIN_SBUF);
424 next(ls); /* Read-ahead first char. */
425 if (ls->current == 0xef && ls->n >= 2 && char2int(ls->p[0]) == 0xbb &&
426 char2int(ls->p[1]) == 0xbf) { /* Skip UTF-8 BOM (if buffered). */
427 ls->n -= 2;
428 ls->p += 2;
429 next(ls);
430 }
431 if (ls->current == '#') { /* Skip POSIX #! header line. */
432 do {
433 next(ls);
434 if (ls->current == END_OF_STREAM) return 0;
435 } while (!currIsNewline(ls));
436 inclinenumber(ls);
437 }
438 return (ls->current == LUA_SIGNATURE[0]); /* Bytecode dump? */
439}
440
441/* Cleanup lexer state. */
442void lj_lex_cleanup(lua_State *L, LexState *ls)
443{
444 global_State *g = G(L);
445 lj_mem_freevec(g, ls->bcstack, ls->sizebcstack, BCInsLine);
446 lj_mem_freevec(g, ls->vstack, ls->sizevstack, VarInfo);
447 lj_str_freebuf(g, &ls->sb);
448}
449
450void lj_lex_next(LexState *ls)
451{
452 ls->lastline = ls->linenumber;
453 if (LJ_LIKELY(ls->lookahead == TK_eof)) { /* No lookahead token? */
454 ls->token = llex(ls, &ls->tokenval); /* Get next token. */
455 } else { /* Otherwise return lookahead token. */
456 ls->token = ls->lookahead;
457 ls->lookahead = TK_eof;
458 ls->tokenval = ls->lookaheadval;
459 }
460}
461
462LexToken lj_lex_lookahead(LexState *ls)
463{
464 lua_assert(ls->lookahead == TK_eof);
465 ls->lookahead = llex(ls, &ls->lookaheadval);
466 return ls->lookahead;
467}
468
469const char *lj_lex_token2str(LexState *ls, LexToken token)
470{
471 if (token > TK_OFS)
472 return tokennames[token-TK_OFS-1];
473 else if (!lj_char_iscntrl(token))
474 return lj_str_pushf(ls->L, "%c", token);
475 else
476 return lj_str_pushf(ls->L, "char(%d)", token);
477}
478
479void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...)
480{
481 const char *tok;
482 va_list argp;
483 if (token == 0) {
484 tok = NULL;
485 } else if (token == TK_name || token == TK_string || token == TK_number) {
486 save(ls, '\0');
487 tok = ls->sb.buf;
488 } else {
489 tok = lj_lex_token2str(ls, token);
490 }
491 va_start(argp, em);
492 lj_err_lex(ls->L, ls->chunkname, tok, ls->linenumber, em, argp);
493 va_end(argp);
494}
495
496void lj_lex_init(lua_State *L)
497{
498 uint32_t i;
499 for (i = 0; i < TK_RESERVED; i++) {
500 GCstr *s = lj_str_newz(L, tokennames[i]);
501 fixstring(s); /* Reserved words are never collected. */
502 s->reserved = (uint8_t)(i+1);
503 }
504}
505
diff --git a/libraries/luajit-2.0/src/lj_lex.h b/libraries/luajit-2.0/src/lj_lex.h
new file mode 100644
index 0000000..1ddf4b5
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_lex.h
@@ -0,0 +1,82 @@
1/*
2** Lexical analyzer.
3** Major parts taken verbatim from the Lua interpreter.
4** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
5*/
6
7#ifndef _LJ_LEX_H
8#define _LJ_LEX_H
9
10#include <stdarg.h>
11
12#include "lj_obj.h"
13#include "lj_err.h"
14
15/* Lua lexer tokens. */
16#define TKDEF(_, __) \
17 _(and) _(break) _(do) _(else) _(elseif) _(end) _(false) \
18 _(for) _(function) _(if) _(in) _(local) _(nil) _(not) _(or) \
19 _(repeat) _(return) _(then) _(true) _(until) _(while) \
20 __(concat, ..) __(dots, ...) __(eq, ==) __(ge, >=) __(le, <=) __(ne, ~=) \
21 __(number, <number>) __(name, <name>) __(string, <string>) __(eof, <eof>)
22
23enum {
24 TK_OFS = 256,
25#define TKENUM1(name) TK_##name,
26#define TKENUM2(name, sym) TK_##name,
27TKDEF(TKENUM1, TKENUM2)
28#undef TKENUM1
29#undef TKENUM2
30 TK_RESERVED = TK_while - TK_OFS
31};
32
33typedef int LexToken;
34
35/* Combined bytecode ins/line. Only used during bytecode generation. */
36typedef struct BCInsLine {
37 BCIns ins; /* Bytecode instruction. */
38 BCLine line; /* Line number for this bytecode. */
39} BCInsLine;
40
41/* Info for local variables. Only used during bytecode generation. */
42typedef struct VarInfo {
43 GCRef name; /* Local variable name. */
44 BCPos startpc; /* First point where the local variable is active. */
45 BCPos endpc; /* First point where the local variable is dead. */
46} VarInfo;
47
48/* Lua lexer state. */
49typedef struct LexState {
50 struct FuncState *fs; /* Current FuncState. Defined in lj_parse.c. */
51 struct lua_State *L; /* Lua state. */
52 TValue tokenval; /* Current token value. */
53 TValue lookaheadval; /* Lookahead token value. */
54 int current; /* Current character (charint). */
55 LexToken token; /* Current token. */
56 LexToken lookahead; /* Lookahead token. */
57 MSize n; /* Bytes left in input buffer. */
58 const char *p; /* Current position in input buffer. */
59 SBuf sb; /* String buffer for tokens. */
60 lua_Reader rfunc; /* Reader callback. */
61 void *rdata; /* Reader callback data. */
62 BCLine linenumber; /* Input line counter. */
63 BCLine lastline; /* Line of last token. */
64 GCstr *chunkname; /* Current chunk name (interned string). */
65 const char *chunkarg; /* Chunk name argument. */
66 VarInfo *vstack; /* Stack for names and extents of local variables. */
67 MSize sizevstack; /* Size of variable stack. */
68 MSize vtop; /* Top of variable stack. */
69 BCInsLine *bcstack; /* Stack for bytecode instructions/line numbers. */
70 MSize sizebcstack; /* Size of bytecode stack. */
71 uint32_t level; /* Syntactical nesting level. */
72} LexState;
73
74LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls);
75LJ_FUNC void lj_lex_cleanup(lua_State *L, LexState *ls);
76LJ_FUNC void lj_lex_next(LexState *ls);
77LJ_FUNC LexToken lj_lex_lookahead(LexState *ls);
78LJ_FUNC const char *lj_lex_token2str(LexState *ls, LexToken token);
79LJ_FUNC_NORET void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...);
80LJ_FUNC void lj_lex_init(lua_State *L);
81
82#endif
diff --git a/libraries/luajit-2.0/src/lj_lib.c b/libraries/luajit-2.0/src/lj_lib.c
new file mode 100644
index 0000000..655ad08
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_lib.c
@@ -0,0 +1,260 @@
1/*
2** Library function support.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_lib_c
7#define LUA_CORE
8
9#include "lauxlib.h"
10
11#include "lj_obj.h"
12#include "lj_gc.h"
13#include "lj_err.h"
14#include "lj_str.h"
15#include "lj_tab.h"
16#include "lj_func.h"
17#include "lj_bc.h"
18#include "lj_dispatch.h"
19#include "lj_vm.h"
20#include "lj_lib.h"
21
22/* -- Library initialization ---------------------------------------------- */
23
24static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize)
25{
26 if (libname) {
27 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
28 lua_getfield(L, -1, libname);
29 if (!tvistab(L->top-1)) {
30 L->top--;
31 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, hsize) != NULL)
32 lj_err_callerv(L, LJ_ERR_BADMODN, libname);
33 settabV(L, L->top, tabV(L->top-1));
34 L->top++;
35 lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
36 }
37 L->top--;
38 settabV(L, L->top-1, tabV(L->top));
39 } else {
40 lua_createtable(L, 0, hsize);
41 }
42 return tabV(L->top-1);
43}
44
45void lj_lib_register(lua_State *L, const char *libname,
46 const uint8_t *p, const lua_CFunction *cf)
47{
48 GCtab *env = tabref(L->env);
49 GCfunc *ofn = NULL;
50 int ffid = *p++;
51 BCIns *bcff = &L2GG(L)->bcff[*p++];
52 GCtab *tab = lib_create_table(L, libname, *p++);
53 ptrdiff_t tpos = L->top - L->base;
54
55 /* Avoid barriers further down. */
56 lj_gc_anybarriert(L, tab);
57 tab->nomm = 0;
58
59 for (;;) {
60 uint32_t tag = *p++;
61 MSize len = tag & LIBINIT_LENMASK;
62 tag &= LIBINIT_TAGMASK;
63 if (tag != LIBINIT_STRING) {
64 const char *name;
65 MSize nuv = (MSize)(L->top - L->base - tpos);
66 GCfunc *fn = lj_func_newC(L, nuv, env);
67 if (nuv) {
68 L->top = L->base + tpos;
69 memcpy(fn->c.upvalue, L->top, sizeof(TValue)*nuv);
70 }
71 fn->c.ffid = (uint8_t)(ffid++);
72 name = (const char *)p;
73 p += len;
74 if (tag == LIBINIT_CF)
75 setmref(fn->c.pc, &G(L)->bc_cfunc_int);
76 else
77 setmref(fn->c.pc, bcff++);
78 if (tag == LIBINIT_ASM_)
79 fn->c.f = ofn->c.f; /* Copy handler from previous function. */
80 else
81 fn->c.f = *cf++; /* Get cf or handler from C function table. */
82 if (len) {
83 /* NOBARRIER: See above for common barrier. */
84 setfuncV(L, lj_tab_setstr(L, tab, lj_str_new(L, name, len)), fn);
85 }
86 ofn = fn;
87 } else {
88 switch (tag | len) {
89 case LIBINIT_SET:
90 L->top -= 2;
91 if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
92 env = tabV(L->top);
93 else /* NOBARRIER: See above for common barrier. */
94 copyTV(L, lj_tab_set(L, tab, L->top+1), L->top);
95 break;
96 case LIBINIT_NUMBER:
97 memcpy(&L->top->n, p, sizeof(double));
98 L->top++;
99 p += sizeof(double);
100 break;
101 case LIBINIT_COPY:
102 copyTV(L, L->top, L->top - *p++);
103 L->top++;
104 break;
105 case LIBINIT_LASTCL:
106 setfuncV(L, L->top++, ofn);
107 break;
108 case LIBINIT_FFID:
109 ffid++;
110 break;
111 case LIBINIT_END:
112 return;
113 default:
114 setstrV(L, L->top++, lj_str_new(L, (const char *)p, len));
115 p += len;
116 break;
117 }
118 }
119 }
120}
121
122/* -- Type checks --------------------------------------------------------- */
123
124TValue *lj_lib_checkany(lua_State *L, int narg)
125{
126 TValue *o = L->base + narg-1;
127 if (o >= L->top)
128 lj_err_arg(L, narg, LJ_ERR_NOVAL);
129 return o;
130}
131
132GCstr *lj_lib_checkstr(lua_State *L, int narg)
133{
134 TValue *o = L->base + narg-1;
135 if (o < L->top) {
136 if (LJ_LIKELY(tvisstr(o))) {
137 return strV(o);
138 } else if (tvisnumber(o)) {
139 GCstr *s = lj_str_fromnumber(L, o);
140 setstrV(L, o, s);
141 return s;
142 }
143 }
144 lj_err_argt(L, narg, LUA_TSTRING);
145 return NULL; /* unreachable */
146}
147
148GCstr *lj_lib_optstr(lua_State *L, int narg)
149{
150 TValue *o = L->base + narg-1;
151 return (o < L->top && !tvisnil(o)) ? lj_lib_checkstr(L, narg) : NULL;
152}
153
154#if LJ_DUALNUM
155void lj_lib_checknumber(lua_State *L, int narg)
156{
157 TValue *o = L->base + narg-1;
158 if (!(o < L->top &&
159 (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
160 lj_err_argt(L, narg, LUA_TNUMBER);
161}
162#endif
163
164lua_Number lj_lib_checknum(lua_State *L, int narg)
165{
166 TValue *o = L->base + narg-1;
167 if (!(o < L->top &&
168 (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
169 lj_err_argt(L, narg, LUA_TNUMBER);
170 if (LJ_UNLIKELY(tvisint(o))) {
171 lua_Number n = (lua_Number)intV(o);
172 setnumV(o, n);
173 return n;
174 } else {
175 return numV(o);
176 }
177}
178
179int32_t lj_lib_checkint(lua_State *L, int narg)
180{
181 TValue *o = L->base + narg-1;
182 if (!(o < L->top &&
183 (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
184 lj_err_argt(L, narg, LUA_TNUMBER);
185 if (LJ_LIKELY(tvisint(o))) {
186 return intV(o);
187 } else {
188 int32_t i = lj_num2int(numV(o));
189 if (LJ_DUALNUM) setintV(o, i);
190 return i;
191 }
192}
193
194int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
195{
196 TValue *o = L->base + narg-1;
197 return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
198}
199
200int32_t lj_lib_checkbit(lua_State *L, int narg)
201{
202 TValue *o = L->base + narg-1;
203 if (!(o < L->top &&
204 (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
205 lj_err_argt(L, narg, LUA_TNUMBER);
206 if (LJ_LIKELY(tvisint(o))) {
207 return intV(o);
208 } else {
209 int32_t i = lj_num2bit(numV(o));
210 if (LJ_DUALNUM) setintV(o, i);
211 return i;
212 }
213}
214
215GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
216{
217 TValue *o = L->base + narg-1;
218 if (!(o < L->top && tvisfunc(o)))
219 lj_err_argt(L, narg, LUA_TFUNCTION);
220 return funcV(o);
221}
222
223GCtab *lj_lib_checktab(lua_State *L, int narg)
224{
225 TValue *o = L->base + narg-1;
226 if (!(o < L->top && tvistab(o)))
227 lj_err_argt(L, narg, LUA_TTABLE);
228 return tabV(o);
229}
230
231GCtab *lj_lib_checktabornil(lua_State *L, int narg)
232{
233 TValue *o = L->base + narg-1;
234 if (o < L->top) {
235 if (tvistab(o))
236 return tabV(o);
237 else if (tvisnil(o))
238 return NULL;
239 }
240 lj_err_arg(L, narg, LJ_ERR_NOTABN);
241 return NULL; /* unreachable */
242}
243
244int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst)
245{
246 GCstr *s = def >= 0 ? lj_lib_optstr(L, narg) : lj_lib_checkstr(L, narg);
247 if (s) {
248 const char *opt = strdata(s);
249 MSize len = s->len;
250 int i;
251 for (i = 0; *(const uint8_t *)lst; i++) {
252 if (*(const uint8_t *)lst == len && memcmp(opt, lst+1, len) == 0)
253 return i;
254 lst += 1+*(const uint8_t *)lst;
255 }
256 lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
257 }
258 return def;
259}
260
diff --git a/libraries/luajit-2.0/src/lj_lib.h b/libraries/luajit-2.0/src/lj_lib.h
new file mode 100644
index 0000000..2c30b68
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_lib.h
@@ -0,0 +1,112 @@
1/*
2** Library function support.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_LIB_H
7#define _LJ_LIB_H
8
9#include "lj_obj.h"
10
11/*
12** A fallback handler is called by the assembler VM if the fast path fails:
13**
14** - too few arguments: unrecoverable.
15** - wrong argument type: recoverable, if coercion succeeds.
16** - bad argument value: unrecoverable.
17** - stack overflow: recoverable, if stack reallocation succeeds.
18** - extra handling: recoverable.
19**
20** The unrecoverable cases throw an error with lj_err_arg(), lj_err_argtype(),
21** lj_err_caller() or lj_err_callermsg().
22** The recoverable cases return 0 or the number of results + 1.
23** The assembler VM retries the fast path only if 0 is returned.
24** This time the fallback must not be called again or it gets stuck in a loop.
25*/
26
27/* Return values from fallback handler. */
28#define FFH_RETRY 0
29#define FFH_UNREACHABLE FFH_RETRY
30#define FFH_RES(n) ((n)+1)
31#define FFH_TAILCALL (-1)
32
33LJ_FUNC TValue *lj_lib_checkany(lua_State *L, int narg);
34LJ_FUNC GCstr *lj_lib_checkstr(lua_State *L, int narg);
35LJ_FUNC GCstr *lj_lib_optstr(lua_State *L, int narg);
36#if LJ_DUALNUM
37LJ_FUNC void lj_lib_checknumber(lua_State *L, int narg);
38#else
39#define lj_lib_checknumber(L, narg) lj_lib_checknum((L), (narg))
40#endif
41LJ_FUNC lua_Number lj_lib_checknum(lua_State *L, int narg);
42LJ_FUNC int32_t lj_lib_checkint(lua_State *L, int narg);
43LJ_FUNC int32_t lj_lib_optint(lua_State *L, int narg, int32_t def);
44LJ_FUNC int32_t lj_lib_checkbit(lua_State *L, int narg);
45LJ_FUNC GCfunc *lj_lib_checkfunc(lua_State *L, int narg);
46LJ_FUNC GCtab *lj_lib_checktab(lua_State *L, int narg);
47LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg);
48LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst);
49
50/* Avoid including lj_frame.h. */
51#define lj_lib_upvalue(L, n) \
52 (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1])
53
54#if LJ_TARGET_WINDOWS
55#define lj_lib_checkfpu(L) \
56 do { setnumV(L->top++, (lua_Number)1437217655); \
57 if (lua_tointeger(L, -1) != 1437217655) lj_err_caller(L, LJ_ERR_BADFPU); \
58 L->top--; } while (0)
59#else
60#define lj_lib_checkfpu(L) UNUSED(L)
61#endif
62
63/* Push internal function on the stack. */
64static LJ_AINLINE void lj_lib_pushcc(lua_State *L, lua_CFunction f,
65 int id, int n)
66{
67 GCfunc *fn;
68 lua_pushcclosure(L, f, n);
69 fn = funcV(L->top-1);
70 fn->c.ffid = (uint8_t)id;
71 setmref(fn->c.pc, &G(L)->bc_cfunc_int);
72}
73
74#define lj_lib_pushcf(L, fn, id) (lj_lib_pushcc(L, (fn), (id), 0))
75
76/* Library function declarations. Scanned by buildvm. */
77#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
78#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)
79#define LJLIB_ASM_(name)
80#define LJLIB_SET(name)
81#define LJLIB_PUSH(arg)
82#define LJLIB_REC(handler)
83#define LJLIB_NOREGUV
84#define LJLIB_NOREG
85
86#define LJ_LIB_REG(L, regname, name) \
87 lj_lib_register(L, regname, lj_lib_init_##name, lj_lib_cf_##name)
88
89LJ_FUNC void lj_lib_register(lua_State *L, const char *libname,
90 const uint8_t *init, const lua_CFunction *cf);
91
92/* Library init data tags. */
93#define LIBINIT_LENMASK 0x3f
94#define LIBINIT_TAGMASK 0xc0
95#define LIBINIT_CF 0x00
96#define LIBINIT_ASM 0x40
97#define LIBINIT_ASM_ 0x80
98#define LIBINIT_STRING 0xc0
99#define LIBINIT_MAXSTR 0x39
100#define LIBINIT_SET 0xfa
101#define LIBINIT_NUMBER 0xfb
102#define LIBINIT_COPY 0xfc
103#define LIBINIT_LASTCL 0xfd
104#define LIBINIT_FFID 0xfe
105#define LIBINIT_END 0xff
106
107/* Exported library functions. */
108
109typedef struct RandomState RandomState;
110LJ_FUNC uint64_t LJ_FASTCALL lj_math_random_step(RandomState *rs);
111
112#endif
diff --git a/libraries/luajit-2.0/src/lj_mcode.c b/libraries/luajit-2.0/src/lj_mcode.c
new file mode 100644
index 0000000..90ac34f
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_mcode.c
@@ -0,0 +1,364 @@
1/*
2** Machine code management.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_mcode_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#if LJ_HASJIT
11#include "lj_gc.h"
12#include "lj_jit.h"
13#include "lj_mcode.h"
14#include "lj_trace.h"
15#include "lj_dispatch.h"
16#include "lj_vm.h"
17#endif
18
19/* -- OS-specific functions ----------------------------------------------- */
20
21#if LJ_HASJIT || LJ_HASFFI
22
23/* Define this if you want to run LuaJIT with Valgrind. */
24#ifdef LUAJIT_USE_VALGRIND
25#include <valgrind/valgrind.h>
26#endif
27
28#if !LJ_TARGET_X86ORX64 && LJ_TARGET_OSX
29void sys_icache_invalidate(void *start, size_t len);
30#endif
31
32#if LJ_TARGET_LINUX && LJ_TARGET_PPC
33#include <dlfcn.h>
34static void (*mcode_sync_ppc)(void *start, void *end);
35static void mcode_sync_dummy(void *start, void *end)
36{
37 UNUSED(start); UNUSED(end);
38}
39#endif
40
41/* Synchronize data/instruction cache. */
42void lj_mcode_sync(void *start, void *end)
43{
44#ifdef LUAJIT_USE_VALGRIND
45 VALGRIND_DISCARD_TRANSLATIONS(start, (char *)end-(char *)start);
46#endif
47#if LJ_TARGET_X86ORX64
48 UNUSED(start); UNUSED(end);
49#elif LJ_TARGET_OSX
50 sys_icache_invalidate(start, (char *)end-(char *)start);
51#elif LJ_TARGET_LINUX && LJ_TARGET_PPC
52 if (!mcode_sync_ppc) {
53 void *vdso = dlopen("linux-vdso32.so.1", RTLD_LAZY);
54 if (!vdso || !(mcode_sync_ppc = dlsym(vdso, "__kernel_sync_dicache")))
55 mcode_sync_ppc = mcode_sync_dummy;
56 }
57 mcode_sync_ppc(start, end);
58#elif defined(__GNUC__) && !LJ_TARGET_PPC
59 __clear_cache(start, end);
60#else
61#error "Missing builtin to flush instruction cache"
62#endif
63}
64
65#endif
66
67#if LJ_HASJIT
68
69#if LJ_TARGET_WINDOWS
70
71#define WIN32_LEAN_AND_MEAN
72#include <windows.h>
73
74#define MCPROT_RW PAGE_READWRITE
75#define MCPROT_RX PAGE_EXECUTE_READ
76#define MCPROT_RWX PAGE_EXECUTE_READWRITE
77
78static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, DWORD prot)
79{
80 void *p = VirtualAlloc((void *)hint, sz,
81 MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, prot);
82 if (!p && !hint)
83 lj_trace_err(J, LJ_TRERR_MCODEAL);
84 return p;
85}
86
87static void mcode_free(jit_State *J, void *p, size_t sz)
88{
89 UNUSED(J); UNUSED(sz);
90 VirtualFree(p, 0, MEM_RELEASE);
91}
92
93static void mcode_setprot(void *p, size_t sz, DWORD prot)
94{
95 DWORD oprot;
96 VirtualProtect(p, sz, prot, &oprot);
97}
98
99#elif LJ_TARGET_POSIX
100
101#include <sys/mman.h>
102
103#ifndef MAP_ANONYMOUS
104#define MAP_ANONYMOUS MAP_ANON
105#endif
106
107#define MCPROT_RW (PROT_READ|PROT_WRITE)
108#define MCPROT_RX (PROT_READ|PROT_EXEC)
109#define MCPROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC)
110
111static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot)
112{
113 void *p = mmap((void *)hint, sz, prot, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
114 if (p == MAP_FAILED && !hint)
115 lj_trace_err(J, LJ_TRERR_MCODEAL);
116 return p;
117}
118
119static void mcode_free(jit_State *J, void *p, size_t sz)
120{
121 UNUSED(J);
122 munmap(p, sz);
123}
124
125static void mcode_setprot(void *p, size_t sz, int prot)
126{
127 mprotect(p, sz, prot);
128}
129
130#elif LJ_64
131
132#error "Missing OS support for explicit placement of executable memory"
133
134#else
135
136/* Fallback allocator. This will fail if memory is not executable by default. */
137#define LUAJIT_UNPROTECT_MCODE
138#define MCPROT_RW 0
139#define MCPROT_RX 0
140#define MCPROT_RWX 0
141
142static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot)
143{
144 UNUSED(hint); UNUSED(prot);
145 return lj_mem_new(J->L, sz);
146}
147
148static void mcode_free(jit_State *J, void *p, size_t sz)
149{
150 lj_mem_free(J2G(J), p, sz);
151}
152
153#define mcode_setprot(p, sz, prot) UNUSED(p)
154
155#endif
156
157/* -- MCode area protection ----------------------------------------------- */
158
159/* Define this ONLY if the page protection twiddling becomes a bottleneck. */
160#ifdef LUAJIT_UNPROTECT_MCODE
161
162/* It's generally considered to be a potential security risk to have
163** pages with simultaneous write *and* execute access in a process.
164**
165** Do not even think about using this mode for server processes or
166** apps handling untrusted external data (such as a browser).
167**
168** The security risk is not in LuaJIT itself -- but if an adversary finds
169** any *other* flaw in your C application logic, then any RWX memory page
170** simplifies writing an exploit considerably.
171*/
172#define MCPROT_GEN MCPROT_RWX
173#define MCPROT_RUN MCPROT_RWX
174
175static void mcode_protect(jit_State *J, int prot)
176{
177 UNUSED(J); UNUSED(prot);
178}
179
180#else
181
182/* This is the default behaviour and much safer:
183**
184** Most of the time the memory pages holding machine code are executable,
185** but NONE of them is writable.
186**
187** The current memory area is marked read-write (but NOT executable) only
188** during the short time window while the assembler generates machine code.
189*/
190#define MCPROT_GEN MCPROT_RW
191#define MCPROT_RUN MCPROT_RX
192
193/* Change protection of MCode area. */
194static void mcode_protect(jit_State *J, int prot)
195{
196 if (J->mcprot != prot) {
197 mcode_setprot(J->mcarea, J->szmcarea, prot);
198 J->mcprot = prot;
199 }
200}
201
202#endif
203
204/* -- MCode area allocation ----------------------------------------------- */
205
206#if LJ_TARGET_X64
207#define mcode_validptr(p) ((p) && (uintptr_t)(p) < (uintptr_t)1<<47)
208#else
209#define mcode_validptr(p) ((p) && (uintptr_t)(p) < 0xffff0000)
210#endif
211
212#ifdef LJ_TARGET_JUMPRANGE
213
214/* Get memory within relative jump distance of our code in 64 bit mode. */
215static void *mcode_alloc(jit_State *J, size_t sz)
216{
217 /* Target an address in the static assembler code (64K aligned).
218 ** Try addresses within a distance of target-range/2+1MB..target+range/2-1MB.
219 */
220 uintptr_t target = (uintptr_t)(void *)lj_vm_exit_handler & ~(uintptr_t)0xffff;
221 const uintptr_t range = (1u << LJ_TARGET_JUMPRANGE) - (1u << 21);
222 /* First try a contiguous area below the last one. */
223 uintptr_t hint = J->mcarea ? (uintptr_t)J->mcarea - sz : 0;
224 int i;
225 for (i = 0; i < 32; i++) { /* 32 attempts ought to be enough ... */
226 if (mcode_validptr(hint)) {
227 void *p = mcode_alloc_at(J, hint, sz, MCPROT_GEN);
228
229 if (mcode_validptr(p)) {
230 if ((uintptr_t)p + sz - target < range || target - (uintptr_t)p < range)
231 return p;
232 mcode_free(J, p, sz); /* Free badly placed area. */
233 }
234 }
235 /* Next try probing pseudo-random addresses. */
236 do {
237 hint = (0x78fb ^ LJ_PRNG_BITS(J, 15)) << 16; /* 64K aligned. */
238 } while (!(hint + sz < range));
239 hint = target + hint - (range>>1);
240 }
241 lj_trace_err(J, LJ_TRERR_MCODEAL); /* Give up. OS probably ignores hints? */
242 return NULL;
243}
244
245#else
246
247/* All memory addresses are reachable by relative jumps. */
248#define mcode_alloc(J, sz) mcode_alloc_at((J), 0, (sz), MCPROT_GEN)
249
250#endif
251
252/* -- MCode area management ----------------------------------------------- */
253
254/* Linked list of MCode areas. */
255typedef struct MCLink {
256 MCode *next; /* Next area. */
257 size_t size; /* Size of current area. */
258} MCLink;
259
260/* Allocate a new MCode area. */
261static void mcode_allocarea(jit_State *J)
262{
263 MCode *oldarea = J->mcarea;
264 size_t sz = (size_t)J->param[JIT_P_sizemcode] << 10;
265 sz = (sz + LJ_PAGESIZE-1) & ~(size_t)(LJ_PAGESIZE - 1);
266 J->mcarea = (MCode *)mcode_alloc(J, sz);
267 J->szmcarea = sz;
268 J->mcprot = MCPROT_GEN;
269 J->mctop = (MCode *)((char *)J->mcarea + J->szmcarea);
270 J->mcbot = (MCode *)((char *)J->mcarea + sizeof(MCLink));
271 ((MCLink *)J->mcarea)->next = oldarea;
272 ((MCLink *)J->mcarea)->size = sz;
273 J->szallmcarea += sz;
274}
275
276/* Free all MCode areas. */
277void lj_mcode_free(jit_State *J)
278{
279 MCode *mc = J->mcarea;
280 J->mcarea = NULL;
281 J->szallmcarea = 0;
282 while (mc) {
283 MCode *next = ((MCLink *)mc)->next;
284 mcode_free(J, mc, ((MCLink *)mc)->size);
285 mc = next;
286 }
287}
288
289/* -- MCode transactions -------------------------------------------------- */
290
291/* Reserve the remainder of the current MCode area. */
292MCode *lj_mcode_reserve(jit_State *J, MCode **lim)
293{
294 if (!J->mcarea)
295 mcode_allocarea(J);
296 else
297 mcode_protect(J, MCPROT_GEN);
298 *lim = J->mcbot;
299 return J->mctop;
300}
301
302/* Commit the top part of the current MCode area. */
303void lj_mcode_commit(jit_State *J, MCode *top)
304{
305 J->mctop = top;
306 mcode_protect(J, MCPROT_RUN);
307}
308
309/* Abort the reservation. */
310void lj_mcode_abort(jit_State *J)
311{
312 mcode_protect(J, MCPROT_RUN);
313}
314
315/* Set/reset protection to allow patching of MCode areas. */
316MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish)
317{
318#ifdef LUAJIT_UNPROTECT_MCODE
319 UNUSED(J); UNUSED(ptr); UNUSED(finish);
320 return NULL;
321#else
322 if (finish) {
323 if (J->mcarea == ptr)
324 mcode_protect(J, MCPROT_RUN);
325 else
326 mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN);
327 return NULL;
328 } else {
329 MCode *mc = J->mcarea;
330 /* Try current area first to use the protection cache. */
331 if (ptr >= mc && ptr < (MCode *)((char *)mc + J->szmcarea)) {
332 mcode_protect(J, MCPROT_GEN);
333 return mc;
334 }
335 /* Otherwise search through the list of MCode areas. */
336 for (;;) {
337 mc = ((MCLink *)mc)->next;
338 lua_assert(mc != NULL);
339 if (ptr >= mc && ptr < (MCode *)((char *)mc + ((MCLink *)mc)->size)) {
340 mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN);
341 return mc;
342 }
343 }
344 }
345#endif
346}
347
348/* Limit of MCode reservation reached. */
349void lj_mcode_limiterr(jit_State *J, size_t need)
350{
351 size_t sizemcode, maxmcode;
352 lj_mcode_abort(J);
353 sizemcode = (size_t)J->param[JIT_P_sizemcode] << 10;
354 sizemcode = (sizemcode + LJ_PAGESIZE-1) & ~(size_t)(LJ_PAGESIZE - 1);
355 maxmcode = (size_t)J->param[JIT_P_maxmcode] << 10;
356 if ((size_t)need > sizemcode)
357 lj_trace_err(J, LJ_TRERR_MCODEOV); /* Too long for any area. */
358 if (J->szallmcarea + sizemcode > maxmcode)
359 lj_trace_err(J, LJ_TRERR_MCODEAL);
360 mcode_allocarea(J);
361 lj_trace_err(J, LJ_TRERR_MCODELM); /* Retry with new area. */
362}
363
364#endif
diff --git a/libraries/luajit-2.0/src/lj_mcode.h b/libraries/luajit-2.0/src/lj_mcode.h
new file mode 100644
index 0000000..d11b668
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_mcode.h
@@ -0,0 +1,30 @@
1/*
2** Machine code management.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_MCODE_H
7#define _LJ_MCODE_H
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT || LJ_HASFFI
12LJ_FUNC void lj_mcode_sync(void *start, void *end);
13#endif
14
15#if LJ_HASJIT
16
17#include "lj_jit.h"
18
19LJ_FUNC void lj_mcode_free(jit_State *J);
20LJ_FUNC MCode *lj_mcode_reserve(jit_State *J, MCode **lim);
21LJ_FUNC void lj_mcode_commit(jit_State *J, MCode *m);
22LJ_FUNC void lj_mcode_abort(jit_State *J);
23LJ_FUNC MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish);
24LJ_FUNC_NORET void lj_mcode_limiterr(jit_State *J, size_t need);
25
26#define lj_mcode_commitbot(J, m) (J->mcbot = (m))
27
28#endif
29
30#endif
diff --git a/libraries/luajit-2.0/src/lj_meta.c b/libraries/luajit-2.0/src/lj_meta.c
new file mode 100644
index 0000000..f258e3e
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_meta.c
@@ -0,0 +1,463 @@
1/*
2** Metamethod handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lj_meta_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_str.h"
16#include "lj_tab.h"
17#include "lj_meta.h"
18#include "lj_frame.h"
19#include "lj_bc.h"
20#include "lj_vm.h"
21
22/* -- Metamethod handling ------------------------------------------------- */
23
24/* String interning of metamethod names for fast indexing. */
25void lj_meta_init(lua_State *L)
26{
27#define MMNAME(name) "__" #name
28 const char *metanames = MMDEF(MMNAME);
29#undef MMNAME
30 global_State *g = G(L);
31 const char *p, *q;
32 uint32_t mm;
33 for (mm = 0, p = metanames; *p; mm++, p = q) {
34 GCstr *s;
35 for (q = p+2; *q && *q != '_'; q++) ;
36 s = lj_str_new(L, p, (size_t)(q-p));
37 /* NOBARRIER: g->gcroot[] is a GC root. */
38 setgcref(g->gcroot[GCROOT_MMNAME+mm], obj2gco(s));
39 }
40}
41
42/* Negative caching of a few fast metamethods. See the lj_meta_fast() macro. */
43cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name)
44{
45 cTValue *mo = lj_tab_getstr(mt, name);
46 lua_assert(mm <= MM_FAST);
47 if (!mo || tvisnil(mo)) { /* No metamethod? */
48 mt->nomm |= (uint8_t)(1u<<mm); /* Set negative cache flag. */
49 return NULL;
50 }
51 return mo;
52}
53
54/* Lookup metamethod for object. */
55cTValue *lj_meta_lookup(lua_State *L, cTValue *o, MMS mm)
56{
57 GCtab *mt;
58 if (tvistab(o))
59 mt = tabref(tabV(o)->metatable);
60 else if (tvisudata(o))
61 mt = tabref(udataV(o)->metatable);
62 else
63 mt = tabref(basemt_obj(G(L), o));
64 if (mt) {
65 cTValue *mo = lj_tab_getstr(mt, mmname_str(G(L), mm));
66 if (mo)
67 return mo;
68 }
69 return niltv(L);
70}
71
72#if LJ_HASFFI
73/* Tailcall from C function. */
74int lj_meta_tailcall(lua_State *L, cTValue *tv)
75{
76 TValue *base = L->base;
77 TValue *top = L->top;
78 const BCIns *pc = frame_pc(base-1); /* Preserve old PC from frame. */
79 copyTV(L, base-1, tv); /* Replace frame with new object. */
80 top->u32.lo = LJ_CONT_TAILCALL;
81 setframe_pc(top, pc);
82 setframe_gc(top+1, obj2gco(L)); /* Dummy frame object. */
83 setframe_ftsz(top+1, (int)((char *)(top+2) - (char *)base) + FRAME_CONT);
84 L->base = L->top = top+2;
85 /*
86 ** before: [old_mo|PC] [... ...]
87 ** ^base ^top
88 ** after: [new_mo|itype] [... ...] [NULL|PC] [dummy|delta]
89 ** ^base/top
90 ** tailcall: [new_mo|PC] [... ...]
91 ** ^base ^top
92 */
93 return 0;
94}
95#endif
96
97/* Setup call to metamethod to be run by Assembler VM. */
98static TValue *mmcall(lua_State *L, ASMFunction cont, cTValue *mo,
99 cTValue *a, cTValue *b)
100{
101 /*
102 ** |-- framesize -> top top+1 top+2 top+3
103 ** before: [func slots ...]
104 ** mm setup: [func slots ...] [cont|?] [mo|tmtype] [a] [b]
105 ** in asm: [func slots ...] [cont|PC] [mo|delta] [a] [b]
106 ** ^-- func base ^-- mm base
107 ** after mm: [func slots ...] [result]
108 ** ^-- copy to base[PC_RA] --/ for lj_cont_ra
109 ** istruecond + branch for lj_cont_cond*
110 ** ignore for lj_cont_nop
111 ** next PC: [func slots ...]
112 */
113 TValue *top = L->top;
114 if (curr_funcisL(L)) top = curr_topL(L);
115 setcont(top, cont); /* Assembler VM stores PC in upper word. */
116 copyTV(L, top+1, mo); /* Store metamethod and two arguments. */
117 copyTV(L, top+2, a);
118 copyTV(L, top+3, b);
119 return top+2; /* Return new base. */
120}
121
122/* -- C helpers for some instructions, called from assembler VM ----------- */
123
124/* Helper for TGET*. __index chain and metamethod. */
125cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k)
126{
127 int loop;
128 for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) {
129 cTValue *mo;
130 if (LJ_LIKELY(tvistab(o))) {
131 GCtab *t = tabV(o);
132 cTValue *tv = lj_tab_get(L, t, k);
133 if (!tvisnil(tv) ||
134 !(mo = lj_meta_fast(L, tabref(t->metatable), MM_index)))
135 return tv;
136 } else if (tvisnil(mo = lj_meta_lookup(L, o, MM_index))) {
137 lj_err_optype(L, o, LJ_ERR_OPINDEX);
138 return NULL; /* unreachable */
139 }
140 if (tvisfunc(mo)) {
141 L->top = mmcall(L, lj_cont_ra, mo, o, k);
142 return NULL; /* Trigger metamethod call. */
143 }
144 o = mo;
145 }
146 lj_err_msg(L, LJ_ERR_GETLOOP);
147 return NULL; /* unreachable */
148}
149
150/* Helper for TSET*. __newindex chain and metamethod. */
151TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k)
152{
153 TValue tmp;
154 int loop;
155 for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) {
156 cTValue *mo;
157 if (LJ_LIKELY(tvistab(o))) {
158 GCtab *t = tabV(o);
159 cTValue *tv = lj_tab_get(L, t, k);
160 if (LJ_LIKELY(!tvisnil(tv))) {
161 t->nomm = 0; /* Invalidate negative metamethod cache. */
162 lj_gc_anybarriert(L, t);
163 return (TValue *)tv;
164 } else if (!(mo = lj_meta_fast(L, tabref(t->metatable), MM_newindex))) {
165 t->nomm = 0; /* Invalidate negative metamethod cache. */
166 lj_gc_anybarriert(L, t);
167 if (tv != niltv(L))
168 return (TValue *)tv;
169 if (tvisnil(k)) lj_err_msg(L, LJ_ERR_NILIDX);
170 else if (tvisint(k)) { setnumV(&tmp, (lua_Number)intV(k)); k = &tmp; }
171 else if (tvisnum(k) && tvisnan(k)) lj_err_msg(L, LJ_ERR_NANIDX);
172 return lj_tab_newkey(L, t, k);
173 }
174 } else if (tvisnil(mo = lj_meta_lookup(L, o, MM_newindex))) {
175 lj_err_optype(L, o, LJ_ERR_OPINDEX);
176 return NULL; /* unreachable */
177 }
178 if (tvisfunc(mo)) {
179 L->top = mmcall(L, lj_cont_nop, mo, o, k);
180 /* L->top+2 = v filled in by caller. */
181 return NULL; /* Trigger metamethod call. */
182 }
183 copyTV(L, &tmp, mo);
184 o = &tmp;
185 }
186 lj_err_msg(L, LJ_ERR_SETLOOP);
187 return NULL; /* unreachable */
188}
189
190static cTValue *str2num(cTValue *o, TValue *n)
191{
192 if (tvisnum(o))
193 return o;
194 else if (tvisint(o))
195 return (setnumV(n, (lua_Number)intV(o)), n);
196 else if (tvisstr(o) && lj_str_tonum(strV(o), n))
197 return n;
198 else
199 return NULL;
200}
201
202/* Helper for arithmetic instructions. Coercion, metamethod. */
203TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc,
204 BCReg op)
205{
206 MMS mm = bcmode_mm(op);
207 TValue tempb, tempc;
208 cTValue *b, *c;
209 if ((b = str2num(rb, &tempb)) != NULL &&
210 (c = str2num(rc, &tempc)) != NULL) { /* Try coercion first. */
211 setnumV(ra, lj_vm_foldarith(numV(b), numV(c), (int)mm-MM_add));
212 return NULL;
213 } else {
214 cTValue *mo = lj_meta_lookup(L, rb, mm);
215 if (tvisnil(mo)) {
216 mo = lj_meta_lookup(L, rc, mm);
217 if (tvisnil(mo)) {
218 if (str2num(rb, &tempb) == NULL) rc = rb;
219 lj_err_optype(L, rc, LJ_ERR_OPARITH);
220 return NULL; /* unreachable */
221 }
222 }
223 return mmcall(L, lj_cont_ra, mo, rb, rc);
224 }
225}
226
227/* In-place coercion of a number to a string. */
228static LJ_AINLINE int tostring(lua_State *L, TValue *o)
229{
230 if (tvisstr(o)) {
231 return 1;
232 } else if (tvisnumber(o)) {
233 setstrV(L, o, lj_str_fromnumber(L, o));
234 return 1;
235 } else {
236 return 0;
237 }
238}
239
240/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */
241TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
242{
243 do {
244 int n = 1;
245 if (!(tvisstr(top-1) || tvisnumber(top-1)) || !tostring(L, top)) {
246 cTValue *mo = lj_meta_lookup(L, top-1, MM_concat);
247 if (tvisnil(mo)) {
248 mo = lj_meta_lookup(L, top, MM_concat);
249 if (tvisnil(mo)) {
250 if (tvisstr(top-1) || tvisnumber(top-1)) top++;
251 lj_err_optype(L, top-1, LJ_ERR_OPCAT);
252 return NULL; /* unreachable */
253 }
254 }
255 /* One of the top two elements is not a string, call __cat metamethod:
256 **
257 ** before: [...][CAT stack .........................]
258 ** top-1 top top+1 top+2
259 ** pick two: [...][CAT stack ...] [o1] [o2]
260 ** setup mm: [...][CAT stack ...] [cont|?] [mo|tmtype] [o1] [o2]
261 ** in asm: [...][CAT stack ...] [cont|PC] [mo|delta] [o1] [o2]
262 ** ^-- func base ^-- mm base
263 ** after mm: [...][CAT stack ...] <--push-- [result]
264 ** next step: [...][CAT stack .............]
265 */
266 copyTV(L, top+2, top); /* Careful with the order of stack copies! */
267 copyTV(L, top+1, top-1);
268 copyTV(L, top, mo);
269 setcont(top-1, lj_cont_cat);
270 return top+1; /* Trigger metamethod call. */
271 } else if (strV(top)->len == 0) { /* Shortcut. */
272 (void)tostring(L, top-1);
273 } else {
274 /* Pick as many strings as possible from the top and concatenate them:
275 **
276 ** before: [...][CAT stack ...........................]
277 ** pick str: [...][CAT stack ...] [...... strings ......]
278 ** concat: [...][CAT stack ...] [result]
279 ** next step: [...][CAT stack ............]
280 */
281 MSize tlen = strV(top)->len;
282 char *buffer;
283 int i;
284 for (n = 1; n <= left && tostring(L, top-n); n++) {
285 MSize len = strV(top-n)->len;
286 if (len >= LJ_MAX_STR - tlen)
287 lj_err_msg(L, LJ_ERR_STROV);
288 tlen += len;
289 }
290 buffer = lj_str_needbuf(L, &G(L)->tmpbuf, tlen);
291 n--;
292 tlen = 0;
293 for (i = n; i >= 0; i--) {
294 MSize len = strV(top-i)->len;
295 memcpy(buffer + tlen, strVdata(top-i), len);
296 tlen += len;
297 }
298 setstrV(L, top-n, lj_str_new(L, buffer, tlen));
299 }
300 left -= n;
301 top -= n;
302 } while (left >= 1);
303 lj_gc_check_fixtop(L);
304 return NULL;
305}
306
307/* Helper for LEN. __len metamethod. */
308TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o)
309{
310 cTValue *mo = lj_meta_lookup(L, o, MM_len);
311 if (tvisnil(mo)) {
312#ifdef LUAJIT_ENABLE_LUA52COMPAT
313 if (tvistab(o))
314 tabref(tabV(o)->metatable)->nomm |= (uint8_t)(1u<<MM_len);
315 else
316#endif
317 lj_err_optype(L, o, LJ_ERR_OPLEN);
318 return NULL;
319 }
320#ifdef LUAJIT_ENABLE_LUA52COMPAT
321 return mmcall(L, lj_cont_ra, mo, o, o);
322#else
323 return mmcall(L, lj_cont_ra, mo, o, niltv(L));
324#endif
325}
326
327/* Helper for equality comparisons. __eq metamethod. */
328TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne)
329{
330 /* Field metatable must be at same offset for GCtab and GCudata! */
331 cTValue *mo = lj_meta_fast(L, tabref(o1->gch.metatable), MM_eq);
332 if (mo) {
333 TValue *top;
334 uint32_t it;
335 if (tabref(o1->gch.metatable) != tabref(o2->gch.metatable)) {
336 cTValue *mo2 = lj_meta_fast(L, tabref(o2->gch.metatable), MM_eq);
337 if (mo2 == NULL || !lj_obj_equal(mo, mo2))
338 return (TValue *)(intptr_t)ne;
339 }
340 top = curr_top(L);
341 setcont(top, ne ? lj_cont_condf : lj_cont_condt);
342 copyTV(L, top+1, mo);
343 it = ~(uint32_t)o1->gch.gct;
344 setgcV(L, top+2, o1, it);
345 setgcV(L, top+3, o2, it);
346 return top+2; /* Trigger metamethod call. */
347 }
348 return (TValue *)(intptr_t)ne;
349}
350
351#if LJ_HASFFI
352TValue * LJ_FASTCALL lj_meta_equal_cd(lua_State *L, BCIns ins)
353{
354 ASMFunction cont = (bc_op(ins) & 1) ? lj_cont_condf : lj_cont_condt;
355 int op = (int)bc_op(ins) & ~1;
356 TValue tv;
357 cTValue *mo, *o2, *o1 = &L->base[bc_a(ins)];
358 cTValue *o1mm = o1;
359 if (op == BC_ISEQV) {
360 o2 = &L->base[bc_d(ins)];
361 if (!tviscdata(o1mm)) o1mm = o2;
362 } else if (op == BC_ISEQS) {
363 setstrV(L, &tv, gco2str(proto_kgc(curr_proto(L), ~(ptrdiff_t)bc_d(ins))));
364 o2 = &tv;
365 } else if (op == BC_ISEQN) {
366 o2 = &mref(curr_proto(L)->k, cTValue)[bc_d(ins)];
367 } else {
368 lua_assert(op == BC_ISEQP);
369 setitype(&tv, ~bc_d(ins));
370 o2 = &tv;
371 }
372 mo = lj_meta_lookup(L, o1mm, MM_eq);
373 if (LJ_LIKELY(!tvisnil(mo)))
374 return mmcall(L, cont, mo, o1, o2);
375 else
376 return (TValue *)(intptr_t)(bc_op(ins) & 1);
377}
378#endif
379
380/* Helper for ordered comparisons. String compare, __lt/__le metamethods. */
381TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op)
382{
383 if (LJ_HASFFI && (tviscdata(o1) || tviscdata(o2))) {
384 ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
385 MMS mm = (op & 2) ? MM_le : MM_lt;
386 cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm);
387 if (LJ_UNLIKELY(tvisnil(mo))) goto err;
388 return mmcall(L, cont, mo, o1, o2);
389 } else if (itype(o1) == itype(o2)) { /* Never called with two numbers. */
390 if (tvisstr(o1) && tvisstr(o2)) {
391 int32_t res = lj_str_cmp(strV(o1), strV(o2));
392 return (TValue *)(intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1));
393 } else {
394 trymt:
395 while (1) {
396 ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
397 MMS mm = (op & 2) ? MM_le : MM_lt;
398 cTValue *mo = lj_meta_lookup(L, o1, mm);
399 cTValue *mo2 = lj_meta_lookup(L, o2, mm);
400 if (tvisnil(mo) || !lj_obj_equal(mo, mo2)) {
401 if (op & 2) { /* MM_le not found: retry with MM_lt. */
402 cTValue *ot = o1; o1 = o2; o2 = ot; /* Swap operands. */
403 op ^= 3; /* Use LT and flip condition. */
404 continue;
405 }
406 goto err;
407 }
408 return mmcall(L, cont, mo, o1, o2);
409 }
410 }
411 } else if (tvisbool(o1) && tvisbool(o2)) {
412 goto trymt;
413 } else {
414 err:
415 lj_err_comp(L, o1, o2);
416 return NULL;
417 }
418}
419
420/* Helper for calls. __call metamethod. */
421void lj_meta_call(lua_State *L, TValue *func, TValue *top)
422{
423 cTValue *mo = lj_meta_lookup(L, func, MM_call);
424 TValue *p;
425 if (!tvisfunc(mo))
426 lj_err_optype_call(L, func);
427 for (p = top; p > func; p--) copyTV(L, p, p-1);
428 copyTV(L, func, mo);
429}
430
431/* Helper for FORI. Coercion. */
432void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o)
433{
434 if (!(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o))))
435 lj_err_msg(L, LJ_ERR_FORINIT);
436 if (!(tvisnumber(o+1) || (tvisstr(o+1) && lj_str_tonumber(strV(o+1), o+1))))
437 lj_err_msg(L, LJ_ERR_FORLIM);
438 if (!(tvisnumber(o+2) || (tvisstr(o+2) && lj_str_tonumber(strV(o+2), o+2))))
439 lj_err_msg(L, LJ_ERR_FORSTEP);
440 if (LJ_DUALNUM) {
441 /* Ensure all slots are integers or all slots are numbers. */
442 int32_t k[3];
443 int nint = 0;
444 ptrdiff_t i;
445 for (i = 0; i <= 2; i++) {
446 if (tvisint(o+i)) {
447 k[i] = intV(o+i); nint++;
448 } else {
449 k[i] = lj_num2int(numV(o+i)); nint += ((lua_Number)k[i] == numV(o+i));
450 }
451 }
452 if (nint == 3) { /* Narrow to integers. */
453 setintV(o, k[0]);
454 setintV(o+1, k[1]);
455 setintV(o+2, k[2]);
456 } else if (nint != 0) { /* Widen to numbers. */
457 if (tvisint(o)) setnumV(o, (lua_Number)intV(o));
458 if (tvisint(o+1)) setnumV(o+1, (lua_Number)intV(o+1));
459 if (tvisint(o+2)) setnumV(o+2, (lua_Number)intV(o+2));
460 }
461 }
462}
463
diff --git a/libraries/luajit-2.0/src/lj_meta.h b/libraries/luajit-2.0/src/lj_meta.h
new file mode 100644
index 0000000..3fec5b2
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_meta.h
@@ -0,0 +1,37 @@
1/*
2** Metamethod handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_META_H
7#define _LJ_META_H
8
9#include "lj_obj.h"
10
11/* Metamethod handling */
12LJ_FUNC void lj_meta_init(lua_State *L);
13LJ_FUNC cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name);
14LJ_FUNC cTValue *lj_meta_lookup(lua_State *L, cTValue *o, MMS mm);
15#if LJ_HASFFI
16LJ_FUNC int lj_meta_tailcall(lua_State *L, cTValue *tv);
17#endif
18
19#define lj_meta_fastg(g, mt, mm) \
20 ((mt) == NULL ? NULL : ((mt)->nomm & (1u<<(mm))) ? NULL : \
21 lj_meta_cache(mt, mm, mmname_str(g, mm)))
22#define lj_meta_fast(L, mt, mm) lj_meta_fastg(G(L), mt, mm)
23
24/* C helpers for some instructions, called from assembler VM. */
25LJ_FUNCA cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k);
26LJ_FUNCA TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k);
27LJ_FUNCA TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb,
28 cTValue *rc, BCReg op);
29LJ_FUNCA TValue *lj_meta_cat(lua_State *L, TValue *top, int left);
30LJ_FUNCA TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o);
31LJ_FUNCA TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne);
32LJ_FUNCA TValue * LJ_FASTCALL lj_meta_equal_cd(lua_State *L, BCIns ins);
33LJ_FUNCA TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op);
34LJ_FUNCA void lj_meta_call(lua_State *L, TValue *func, TValue *top);
35LJ_FUNCA void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o);
36
37#endif
diff --git a/libraries/luajit-2.0/src/lj_obj.c b/libraries/luajit-2.0/src/lj_obj.c
new file mode 100644
index 0000000..1476f0b
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_obj.c
@@ -0,0 +1,35 @@
1/*
2** Miscellaneous object handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_obj_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11/* Object type names. */
12LJ_DATADEF const char *const lj_obj_typename[] = { /* ORDER LUA_T */
13 "no value", "nil", "boolean", "userdata", "number", "string",
14 "table", "function", "userdata", "thread", "proto", "cdata"
15};
16
17LJ_DATADEF const char *const lj_obj_itypename[] = { /* ORDER LJ_T */
18 "nil", "boolean", "boolean", "userdata", "string", "upval", "thread",
19 "proto", "function", "trace", "cdata", "table", "userdata", "number"
20};
21
22/* Compare two objects without calling metamethods. */
23int lj_obj_equal(cTValue *o1, cTValue *o2)
24{
25 if (itype(o1) == itype(o2)) {
26 if (tvispri(o1))
27 return 1;
28 if (!tvisnum(o1))
29 return gcrefeq(o1->gcr, o2->gcr);
30 } else if (!tvisnumber(o1) || !tvisnumber(o2)) {
31 return 0;
32 }
33 return numberVnum(o1) == numberVnum(o2);
34}
35
diff --git a/libraries/luajit-2.0/src/lj_obj.h b/libraries/luajit-2.0/src/lj_obj.h
new file mode 100644
index 0000000..4a360df
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_obj.h
@@ -0,0 +1,844 @@
1/*
2** LuaJIT VM tags, values and objects.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#ifndef _LJ_OBJ_H
10#define _LJ_OBJ_H
11
12#include "lua.h"
13#include "lj_def.h"
14#include "lj_arch.h"
15
16/* -- Memory references (32 bit address space) ---------------------------- */
17
18/* Memory size. */
19typedef uint32_t MSize;
20
21/* Memory reference */
22typedef struct MRef {
23 uint32_t ptr32; /* Pseudo 32 bit pointer. */
24} MRef;
25
26#define mref(r, t) ((t *)(void *)(uintptr_t)(r).ptr32)
27
28#define setmref(r, p) ((r).ptr32 = (uint32_t)(uintptr_t)(void *)(p))
29#define setmrefr(r, v) ((r).ptr32 = (v).ptr32)
30
31/* -- GC object references (32 bit address space) ------------------------- */
32
33/* GCobj reference */
34typedef struct GCRef {
35 uint32_t gcptr32; /* Pseudo 32 bit pointer. */
36} GCRef;
37
38/* Common GC header for all collectable objects. */
39#define GCHeader GCRef nextgc; uint8_t marked; uint8_t gct
40/* This occupies 6 bytes, so use the next 2 bytes for non-32 bit fields. */
41
42#define gcref(r) ((GCobj *)(uintptr_t)(r).gcptr32)
43#define gcrefp(r, t) ((t *)(void *)(uintptr_t)(r).gcptr32)
44#define gcrefu(r) ((r).gcptr32)
45#define gcrefi(r) ((int32_t)(r).gcptr32)
46#define gcrefeq(r1, r2) ((r1).gcptr32 == (r2).gcptr32)
47#define gcnext(gc) (gcref((gc)->gch.nextgc))
48
49#define setgcref(r, gc) ((r).gcptr32 = (uint32_t)(uintptr_t)&(gc)->gch)
50#define setgcrefi(r, i) ((r).gcptr32 = (uint32_t)(i))
51#define setgcrefp(r, p) ((r).gcptr32 = (uint32_t)(uintptr_t)(p))
52#define setgcrefnull(r) ((r).gcptr32 = 0)
53#define setgcrefr(r, v) ((r).gcptr32 = (v).gcptr32)
54
55/* IMPORTANT NOTE:
56**
57** All uses of the setgcref* macros MUST be accompanied with a write barrier.
58**
59** This is to ensure the integrity of the incremental GC. The invariant
60** to preserve is that a black object never points to a white object.
61** I.e. never store a white object into a field of a black object.
62**
63** It's ok to LEAVE OUT the write barrier ONLY in the following cases:
64** - The source is not a GC object (NULL).
65** - The target is a GC root. I.e. everything in global_State.
66** - The target is a lua_State field (threads are never black).
67** - The target is a stack slot, see setgcV et al.
68** - The target is an open upvalue, i.e. pointing to a stack slot.
69** - The target is a newly created object (i.e. marked white). But make
70** sure nothing invokes the GC inbetween.
71** - The target and the source are the same object (self-reference).
72** - The target already contains the object (e.g. moving elements around).
73**
74** The most common case is a store to a stack slot. All other cases where
75** a barrier has been omitted are annotated with a NOBARRIER comment.
76**
77** The same logic applies for stores to table slots (array part or hash
78** part). ALL uses of lj_tab_set* require a barrier for the stored value
79** *and* the stored key, based on the above rules. In practice this means
80** a barrier is needed if *either* of the key or value are a GC object.
81**
82** It's ok to LEAVE OUT the write barrier in the following special cases:
83** - The stored value is nil. The key doesn't matter because it's either
84** not resurrected or lj_tab_newkey() will take care of the key barrier.
85** - The key doesn't matter if the *previously* stored value is guaranteed
86** to be non-nil (because the key is kept alive in the table).
87** - The key doesn't matter if it's guaranteed not to be part of the table,
88** since lj_tab_newkey() takes care of the key barrier. This applies
89** trivially to new tables, but watch out for resurrected keys. Storing
90** a nil value leaves the key in the table!
91**
92** In case of doubt use lj_gc_anybarriert() as it's rather cheap. It's used
93** by the interpreter for all table stores.
94**
95** Note: In contrast to Lua's GC, LuaJIT's GC does *not* specially mark
96** dead keys in tables. The reference is left in, but it's guaranteed to
97** be never dereferenced as long as the value is nil. It's ok if the key is
98** freed or if any object subsequently gets the same address.
99**
100** Not destroying dead keys helps to keep key hash slots stable. This avoids
101** specialization back-off for HREFK when a value flips between nil and
102** non-nil and the GC gets in the way. It also allows safely hoisting
103** HREF/HREFK across GC steps. Dead keys are only removed if a table is
104** resized (i.e. by NEWREF) and xREF must not be CSEd across a resize.
105**
106** The trade-off is that a write barrier for tables must take the key into
107** account, too. Implicitly resurrecting the key by storing a non-nil value
108** may invalidate the incremental GC invariant.
109*/
110
111/* -- Common type definitions --------------------------------------------- */
112
113/* Types for handling bytecodes. Need this here, details in lj_bc.h. */
114typedef uint32_t BCIns; /* Bytecode instruction. */
115typedef uint32_t BCPos; /* Bytecode position. */
116typedef uint32_t BCReg; /* Bytecode register. */
117typedef int32_t BCLine; /* Bytecode line number. */
118
119/* Internal assembler functions. Never call these directly from C. */
120typedef void (*ASMFunction)(void);
121
122/* Resizable string buffer. Need this here, details in lj_str.h. */
123typedef struct SBuf {
124 char *buf; /* String buffer base. */
125 MSize n; /* String buffer length. */
126 MSize sz; /* String buffer size. */
127} SBuf;
128
129/* -- Tags and values ----------------------------------------------------- */
130
131/* Frame link. */
132typedef union {
133 int32_t ftsz; /* Frame type and size of previous frame. */
134 MRef pcr; /* Overlaps PC for Lua frames. */
135} FrameLink;
136
137/* Tagged value. */
138typedef LJ_ALIGN(8) union TValue {
139 uint64_t u64; /* 64 bit pattern overlaps number. */
140 lua_Number n; /* Number object overlaps split tag/value object. */
141 struct {
142 LJ_ENDIAN_LOHI(
143 union {
144 GCRef gcr; /* GCobj reference (if any). */
145 int32_t i; /* Integer value. */
146 };
147 , uint32_t it; /* Internal object tag. Must overlap MSW of number. */
148 )
149 };
150 struct {
151 LJ_ENDIAN_LOHI(
152 GCRef func; /* Function for next frame (or dummy L). */
153 , FrameLink tp; /* Link to previous frame. */
154 )
155 } fr;
156 struct {
157 LJ_ENDIAN_LOHI(
158 uint32_t lo; /* Lower 32 bits of number. */
159 , uint32_t hi; /* Upper 32 bits of number. */
160 )
161 } u32;
162} TValue;
163
164typedef const TValue cTValue;
165
166#define tvref(r) (mref(r, TValue))
167
168/* More external and GCobj tags for internal objects. */
169#define LAST_TT LUA_TTHREAD
170#define LUA_TPROTO (LAST_TT+1)
171#define LUA_TCDATA (LAST_TT+2)
172
173/* Internal object tags.
174**
175** Internal tags overlap the MSW of a number object (must be a double).
176** Interpreted as a double these are special NaNs. The FPU only generates
177** one type of NaN (0xfff8_0000_0000_0000). So MSWs > 0xfff80000 are available
178** for use as internal tags. Small negative numbers are used to shorten the
179** encoding of type comparisons (reg/mem against sign-ext. 8 bit immediate).
180**
181** ---MSW---.---LSW---
182** primitive types | itype | |
183** lightuserdata | itype | void * | (32 bit platforms)
184** lightuserdata |ffff| void * | (64 bit platforms, 47 bit pointers)
185** GC objects | itype | GCRef |
186** int (LJ_DUALNUM)| itype | int |
187** number -------double------
188**
189** ORDER LJ_T
190** Primitive types nil/false/true must be first, lightuserdata next.
191** GC objects are at the end, table/userdata must be lowest.
192** Also check lj_ir.h for similar ordering constraints.
193*/
194#define LJ_TNIL (~0u)
195#define LJ_TFALSE (~1u)
196#define LJ_TTRUE (~2u)
197#define LJ_TLIGHTUD (~3u)
198#define LJ_TSTR (~4u)
199#define LJ_TUPVAL (~5u)
200#define LJ_TTHREAD (~6u)
201#define LJ_TPROTO (~7u)
202#define LJ_TFUNC (~8u)
203#define LJ_TTRACE (~9u)
204#define LJ_TCDATA (~10u)
205#define LJ_TTAB (~11u)
206#define LJ_TUDATA (~12u)
207/* This is just the canonical number type used in some places. */
208#define LJ_TNUMX (~13u)
209
210/* Integers have itype == LJ_TISNUM doubles have itype < LJ_TISNUM */
211#if LJ_64
212#define LJ_TISNUM 0xfffeffffu
213#else
214#define LJ_TISNUM LJ_TNUMX
215#endif
216#define LJ_TISTRUECOND LJ_TFALSE
217#define LJ_TISPRI LJ_TTRUE
218#define LJ_TISGCV (LJ_TSTR+1)
219#define LJ_TISTABUD LJ_TTAB
220
221/* -- String object ------------------------------------------------------- */
222
223/* String object header. String payload follows. */
224typedef struct GCstr {
225 GCHeader;
226 uint8_t reserved; /* Used by lexer for fast lookup of reserved words. */
227 uint8_t unused;
228 MSize hash; /* Hash of string. */
229 MSize len; /* Size of string. */
230} GCstr;
231
232#define strref(r) (&gcref((r))->str)
233#define strdata(s) ((const char *)((s)+1))
234#define strdatawr(s) ((char *)((s)+1))
235#define strVdata(o) strdata(strV(o))
236#define sizestring(s) (sizeof(struct GCstr)+(s)->len+1)
237
238/* -- Userdata object ----------------------------------------------------- */
239
240/* Userdata object. Payload follows. */
241typedef struct GCudata {
242 GCHeader;
243 uint8_t udtype; /* Userdata type. */
244 uint8_t unused2;
245 GCRef env; /* Should be at same offset in GCfunc. */
246 MSize len; /* Size of payload. */
247 GCRef metatable; /* Must be at same offset in GCtab. */
248 uint32_t align1; /* To force 8 byte alignment of the payload. */
249} GCudata;
250
251/* Userdata types. */
252enum {
253 UDTYPE_USERDATA, /* Regular userdata. */
254 UDTYPE_IO_FILE, /* I/O library FILE. */
255 UDTYPE_FFI_CLIB, /* FFI C library namespace. */
256 UDTYPE__MAX
257};
258
259#define uddata(u) ((void *)((u)+1))
260#define sizeudata(u) (sizeof(struct GCudata)+(u)->len)
261
262/* -- C data object ------------------------------------------------------- */
263
264/* C data object. Payload follows. */
265typedef struct GCcdata {
266 GCHeader;
267 uint16_t typeid; /* C type ID. */
268} GCcdata;
269
270/* Prepended to variable-sized or realigned C data objects. */
271typedef struct GCcdataVar {
272 uint16_t offset; /* Offset to allocated memory (relative to GCcdata). */
273 uint16_t extra; /* Extra space allocated (incl. GCcdata + GCcdatav). */
274 MSize len; /* Size of payload. */
275} GCcdataVar;
276
277#define cdataptr(cd) ((void *)((cd)+1))
278#define cdataisv(cd) ((cd)->marked & 0x80)
279#define cdatav(cd) ((GCcdataVar *)((char *)(cd) - sizeof(GCcdataVar)))
280#define cdatavlen(cd) check_exp(cdataisv(cd), cdatav(cd)->len)
281#define sizecdatav(cd) (cdatavlen(cd) + cdatav(cd)->extra)
282#define memcdatav(cd) ((void *)((char *)(cd) - cdatav(cd)->offset))
283
284/* -- Prototype object ---------------------------------------------------- */
285
286#define SCALE_NUM_GCO ((int32_t)sizeof(lua_Number)/sizeof(GCRef))
287#define round_nkgc(n) (((n) + SCALE_NUM_GCO-1) & ~(SCALE_NUM_GCO-1))
288
289typedef struct GCproto {
290 GCHeader;
291 uint8_t numparams; /* Number of parameters. */
292 uint8_t framesize; /* Fixed frame size. */
293 MSize sizebc; /* Number of bytecode instructions. */
294 GCRef gclist;
295 MRef k; /* Split constant array (points to the middle). */
296 MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */
297 MSize sizekgc; /* Number of collectable constants. */
298 MSize sizekn; /* Number of lua_Number constants. */
299 MSize sizept; /* Total size including colocated arrays. */
300 uint8_t sizeuv; /* Number of upvalues. */
301 uint8_t flags; /* Miscellaneous flags (see below). */
302 uint16_t trace; /* Anchor for chain of root traces. */
303 /* ------ The following fields are for debugging/tracebacks only ------ */
304 GCRef chunkname; /* Name of the chunk this function was defined in. */
305 BCLine firstline; /* First line of the function definition. */
306 BCLine numline; /* Number of lines for the function definition. */
307 MRef lineinfo; /* Compressed map from bytecode ins. to source line. */
308 MRef uvinfo; /* Upvalue names. */
309 MRef varinfo; /* Names and compressed extents of local variables. */
310} GCproto;
311
312/* Flags for prototype. */
313#define PROTO_CHILD 0x01 /* Has child prototypes. */
314#define PROTO_VARARG 0x02 /* Vararg function. */
315#define PROTO_FFI 0x04 /* Uses BC_KCDATA for FFI datatypes. */
316#define PROTO_NOJIT 0x08 /* JIT disabled for this function. */
317#define PROTO_ILOOP 0x10 /* Patched bytecode with ILOOP etc. */
318/* Only used during parsing. */
319#define PROTO_HAS_RETURN 0x20 /* Already emitted a return. */
320#define PROTO_FIXUP_RETURN 0x40 /* Need to fixup emitted returns. */
321/* Top bits used for counting created closures. */
322#define PROTO_CLCOUNT 0x20 /* Base of saturating 3 bit counter. */
323#define PROTO_CLC_BITS 3
324
325#define proto_kgc(pt, idx) \
326 check_exp((uintptr_t)(intptr_t)(idx) >= (uintptr_t)-(intptr_t)(pt)->sizekgc, \
327 gcref(mref((pt)->k, GCRef)[(idx)]))
328#define proto_knumtv(pt, idx) \
329 check_exp((uintptr_t)(idx) < (pt)->sizekn, &mref((pt)->k, TValue)[(idx)])
330#define proto_bc(pt) ((BCIns *)((char *)(pt) + sizeof(GCproto)))
331#define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt)))
332#define proto_uv(pt) (mref((pt)->uv, uint16_t))
333
334#define proto_chunkname(pt) (strref((pt)->chunkname))
335#define proto_chunknamestr(pt) (strdata(proto_chunkname((pt))))
336#define proto_lineinfo(pt) (mref((pt)->lineinfo, const void))
337#define proto_uvinfo(pt) (mref((pt)->uvinfo, const uint8_t))
338#define proto_varinfo(pt) (mref((pt)->varinfo, const uint8_t))
339
340/* -- Upvalue object ------------------------------------------------------ */
341
342typedef struct GCupval {
343 GCHeader;
344 uint8_t closed; /* Set if closed (i.e. uv->v == &uv->u.value). */
345 uint8_t unused;
346 union {
347 TValue tv; /* If closed: the value itself. */
348 struct { /* If open: double linked list, anchored at thread. */
349 GCRef prev;
350 GCRef next;
351 };
352 };
353 MRef v; /* Points to stack slot (open) or above (closed). */
354 uint32_t dhash; /* Disambiguation hash: dh1 != dh2 => cannot alias. */
355} GCupval;
356
357#define uvprev(uv_) (&gcref((uv_)->prev)->uv)
358#define uvnext(uv_) (&gcref((uv_)->next)->uv)
359#define uvval(uv_) (mref((uv_)->v, TValue))
360
361/* -- Function object (closures) ------------------------------------------ */
362
363/* Common header for functions. env should be at same offset in GCudata. */
364#define GCfuncHeader \
365 GCHeader; uint8_t ffid; uint8_t nupvalues; \
366 GCRef env; GCRef gclist; MRef pc
367
368typedef struct GCfuncC {
369 GCfuncHeader;
370 lua_CFunction f; /* C function to be called. */
371 TValue upvalue[1]; /* Array of upvalues (TValue). */
372} GCfuncC;
373
374typedef struct GCfuncL {
375 GCfuncHeader;
376 GCRef uvptr[1]; /* Array of _pointers_ to upvalue objects (GCupval). */
377} GCfuncL;
378
379typedef union GCfunc {
380 GCfuncC c;
381 GCfuncL l;
382} GCfunc;
383
384#define FF_LUA 0
385#define FF_C 1
386#define isluafunc(fn) ((fn)->c.ffid == FF_LUA)
387#define iscfunc(fn) ((fn)->c.ffid == FF_C)
388#define isffunc(fn) ((fn)->c.ffid > FF_C)
389#define funcproto(fn) \
390 check_exp(isluafunc(fn), (GCproto *)(mref((fn)->l.pc, char)-sizeof(GCproto)))
391#define sizeCfunc(n) (sizeof(GCfuncC)-sizeof(TValue)+sizeof(TValue)*(n))
392#define sizeLfunc(n) (sizeof(GCfuncL)-sizeof(GCRef)+sizeof(GCRef)*(n))
393
394/* -- Table object -------------------------------------------------------- */
395
396/* Hash node. */
397typedef struct Node {
398 TValue val; /* Value object. Must be first field. */
399 TValue key; /* Key object. */
400 MRef next; /* Hash chain. */
401 MRef freetop; /* Top of free elements (stored in t->node[0]). */
402} Node;
403
404LJ_STATIC_ASSERT(offsetof(Node, val) == 0);
405
406typedef struct GCtab {
407 GCHeader;
408 uint8_t nomm; /* Negative cache for fast metamethods. */
409 int8_t colo; /* Array colocation. */
410 MRef array; /* Array part. */
411 GCRef gclist;
412 GCRef metatable; /* Must be at same offset in GCudata. */
413 MRef node; /* Hash part. */
414 uint32_t asize; /* Size of array part (keys [0, asize-1]). */
415 uint32_t hmask; /* Hash part mask (size of hash part - 1). */
416} GCtab;
417
418#define sizetabcolo(n) ((n)*sizeof(TValue) + sizeof(GCtab))
419#define tabref(r) (&gcref((r))->tab)
420#define noderef(r) (mref((r), Node))
421#define nextnode(n) (mref((n)->next, Node))
422
423/* -- State objects ------------------------------------------------------- */
424
425/* VM states. */
426enum {
427 LJ_VMST_INTERP, /* Interpreter. */
428 LJ_VMST_C, /* C function. */
429 LJ_VMST_GC, /* Garbage collector. */
430 LJ_VMST_EXIT, /* Trace exit handler. */
431 LJ_VMST_RECORD, /* Trace recorder. */
432 LJ_VMST_OPT, /* Optimizer. */
433 LJ_VMST_ASM, /* Assembler. */
434 LJ_VMST__MAX
435};
436
437#define setvmstate(g, st) ((g)->vmstate = ~LJ_VMST_##st)
438
439/* Metamethods. ORDER MM */
440#ifdef LUAJIT_ENABLE_LUA52COMPAT
441#define MMDEF_52(_) _(pairs) _(ipairs)
442#else
443#define MMDEF_52(_)
444#endif
445
446#define MMDEF(_) \
447 _(index) _(newindex) _(gc) _(mode) _(eq) _(len) \
448 /* Only the above (fast) metamethods are negative cached (max. 8). */ \
449 _(lt) _(le) _(concat) _(call) \
450 /* The following must be in ORDER ARITH. */ \
451 _(add) _(sub) _(mul) _(div) _(mod) _(pow) _(unm) \
452 /* The following are used in the standard libraries. */ \
453 _(metatable) _(tostring) MMDEF_52(_)
454
455typedef enum {
456#define MMENUM(name) MM_##name,
457MMDEF(MMENUM)
458#undef MMENUM
459 MM__MAX,
460 MM____ = MM__MAX,
461 MM_FAST = MM_len
462} MMS;
463
464/* GC root IDs. */
465typedef enum {
466 GCROOT_MMNAME, /* Metamethod names. */
467 GCROOT_MMNAME_LAST = GCROOT_MMNAME + MM__MAX-1,
468 GCROOT_BASEMT, /* Metatables for base types. */
469 GCROOT_BASEMT_NUM = GCROOT_BASEMT + ~LJ_TNUMX,
470 GCROOT_IO_INPUT, /* Userdata for default I/O input file. */
471 GCROOT_IO_OUTPUT, /* Userdata for default I/O output file. */
472 GCROOT_MAX
473} GCRootID;
474
475#define basemt_it(g, it) ((g)->gcroot[GCROOT_BASEMT+~(it)])
476#define basemt_obj(g, o) ((g)->gcroot[GCROOT_BASEMT+itypemap(o)])
477#define mmname_str(g, mm) (strref((g)->gcroot[GCROOT_MMNAME+(mm)]))
478
479typedef struct GCState {
480 MSize total; /* Memory currently allocated. */
481 MSize threshold; /* Memory threshold. */
482 uint8_t currentwhite; /* Current white color. */
483 uint8_t state; /* GC state. */
484 uint8_t unused1;
485 uint8_t unused2;
486 MSize sweepstr; /* Sweep position in string table. */
487 GCRef root; /* List of all collectable objects. */
488 MRef sweep; /* Sweep position in root list. */
489 GCRef gray; /* List of gray objects. */
490 GCRef grayagain; /* List of objects for atomic traversal. */
491 GCRef weak; /* List of weak tables (to be cleared). */
492 GCRef mmudata; /* List of userdata (to be finalized). */
493 MSize stepmul; /* Incremental GC step granularity. */
494 MSize debt; /* Debt (how much GC is behind schedule). */
495 MSize estimate; /* Estimate of memory actually in use. */
496 MSize pause; /* Pause between successive GC cycles. */
497} GCState;
498
499/* Global state, shared by all threads of a Lua universe. */
500typedef struct global_State {
501 GCRef *strhash; /* String hash table (hash chain anchors). */
502 MSize strmask; /* String hash mask (size of hash table - 1). */
503 MSize strnum; /* Number of strings in hash table. */
504 lua_Alloc allocf; /* Memory allocator. */
505 void *allocd; /* Memory allocator data. */
506 GCState gc; /* Garbage collector. */
507 SBuf tmpbuf; /* Temporary buffer for string concatenation. */
508 Node nilnode; /* Fallback 1-element hash part (nil key and value). */
509 GCstr strempty; /* Empty string. */
510 uint8_t stremptyz; /* Zero terminator of empty string. */
511 uint8_t hookmask; /* Hook mask. */
512 uint8_t dispatchmode; /* Dispatch mode. */
513 uint8_t vmevmask; /* VM event mask. */
514 GCRef mainthref; /* Link to main thread. */
515 TValue registrytv; /* Anchor for registry. */
516 TValue tmptv, tmptv2; /* Temporary TValues. */
517 GCupval uvhead; /* Head of double-linked list of all open upvalues. */
518 int32_t hookcount; /* Instruction hook countdown. */
519 int32_t hookcstart; /* Start count for instruction hook counter. */
520 lua_Hook hookf; /* Hook function. */
521 lua_CFunction wrapf; /* Wrapper for C function calls. */
522 lua_CFunction panic; /* Called as a last resort for errors. */
523 volatile int32_t vmstate; /* VM state or current JIT code trace number. */
524 BCIns bc_cfunc_int; /* Bytecode for internal C function calls. */
525 BCIns bc_cfunc_ext; /* Bytecode for external C function calls. */
526 GCRef jit_L; /* Current JIT code lua_State or NULL. */
527 MRef jit_base; /* Current JIT code L->base. */
528 MRef ctype_state; /* Pointer to C type state. */
529 GCRef gcroot[GCROOT_MAX]; /* GC roots. */
530} global_State;
531
532#define mainthread(g) (&gcref(g->mainthref)->th)
533#define niltv(L) \
534 check_exp(tvisnil(&G(L)->nilnode.val), &G(L)->nilnode.val)
535#define niltvg(g) \
536 check_exp(tvisnil(&(g)->nilnode.val), &(g)->nilnode.val)
537
538/* Hook management. Hook event masks are defined in lua.h. */
539#define HOOK_EVENTMASK 0x0f
540#define HOOK_ACTIVE 0x10
541#define HOOK_ACTIVE_SHIFT 4
542#define HOOK_VMEVENT 0x20
543#define HOOK_GC 0x40
544#define hook_active(g) ((g)->hookmask & HOOK_ACTIVE)
545#define hook_enter(g) ((g)->hookmask |= HOOK_ACTIVE)
546#define hook_entergc(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_GC))
547#define hook_vmevent(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_VMEVENT))
548#define hook_leave(g) ((g)->hookmask &= ~HOOK_ACTIVE)
549#define hook_save(g) ((g)->hookmask & ~HOOK_EVENTMASK)
550#define hook_restore(g, h) \
551 ((g)->hookmask = ((g)->hookmask & HOOK_EVENTMASK) | (h))
552
553/* Per-thread state object. */
554struct lua_State {
555 GCHeader;
556 uint8_t dummy_ffid; /* Fake FF_C for curr_funcisL() on dummy frames. */
557 uint8_t status; /* Thread status. */
558 MRef glref; /* Link to global state. */
559 GCRef gclist; /* GC chain. */
560 TValue *base; /* Base of currently executing function. */
561 TValue *top; /* First free slot in the stack. */
562 MRef maxstack; /* Last free slot in the stack. */
563 MRef stack; /* Stack base. */
564 GCRef openupval; /* List of open upvalues in the stack. */
565 GCRef env; /* Thread environment (table of globals). */
566 void *cframe; /* End of C stack frame chain. */
567 MSize stacksize; /* True stack size (incl. LJ_STACK_EXTRA). */
568};
569
570#define G(L) (mref(L->glref, global_State))
571#define registry(L) (&G(L)->registrytv)
572
573/* Macros to access the currently executing (Lua) function. */
574#define curr_func(L) (&gcref((L->base-1)->fr.func)->fn)
575#define curr_funcisL(L) (isluafunc(curr_func(L)))
576#define curr_proto(L) (funcproto(curr_func(L)))
577#define curr_topL(L) (L->base + curr_proto(L)->framesize)
578#define curr_top(L) (curr_funcisL(L) ? curr_topL(L) : L->top)
579
580/* -- GC object definition and conversions -------------------------------- */
581
582/* GC header for generic access to common fields of GC objects. */
583typedef struct GChead {
584 GCHeader;
585 uint8_t unused1;
586 uint8_t unused2;
587 GCRef env;
588 GCRef gclist;
589 GCRef metatable;
590} GChead;
591
592/* The env field SHOULD be at the same offset for all GC objects. */
593LJ_STATIC_ASSERT(offsetof(GChead, env) == offsetof(GCfuncL, env));
594LJ_STATIC_ASSERT(offsetof(GChead, env) == offsetof(GCudata, env));
595
596/* The metatable field MUST be at the same offset for all GC objects. */
597LJ_STATIC_ASSERT(offsetof(GChead, metatable) == offsetof(GCtab, metatable));
598LJ_STATIC_ASSERT(offsetof(GChead, metatable) == offsetof(GCudata, metatable));
599
600/* The gclist field MUST be at the same offset for all GC objects. */
601LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(lua_State, gclist));
602LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCproto, gclist));
603LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCfuncL, gclist));
604LJ_STATIC_ASSERT(offsetof(GChead, gclist) == offsetof(GCtab, gclist));
605
606typedef union GCobj {
607 GChead gch;
608 GCstr str;
609 GCupval uv;
610 lua_State th;
611 GCproto pt;
612 GCfunc fn;
613 GCcdata cd;
614 GCtab tab;
615 GCudata ud;
616} GCobj;
617
618/* Macros to convert a GCobj pointer into a specific value. */
619#define gco2str(o) check_exp((o)->gch.gct == ~LJ_TSTR, &(o)->str)
620#define gco2uv(o) check_exp((o)->gch.gct == ~LJ_TUPVAL, &(o)->uv)
621#define gco2th(o) check_exp((o)->gch.gct == ~LJ_TTHREAD, &(o)->th)
622#define gco2pt(o) check_exp((o)->gch.gct == ~LJ_TPROTO, &(o)->pt)
623#define gco2func(o) check_exp((o)->gch.gct == ~LJ_TFUNC, &(o)->fn)
624#define gco2cd(o) check_exp((o)->gch.gct == ~LJ_TCDATA, &(o)->cd)
625#define gco2tab(o) check_exp((o)->gch.gct == ~LJ_TTAB, &(o)->tab)
626#define gco2ud(o) check_exp((o)->gch.gct == ~LJ_TUDATA, &(o)->ud)
627
628/* Macro to convert any collectable object into a GCobj pointer. */
629#define obj2gco(v) ((GCobj *)(v))
630
631/* -- TValue getters/setters ---------------------------------------------- */
632
633#ifdef LUA_USE_ASSERT
634#include "lj_gc.h"
635#endif
636
637/* Macros to test types. */
638#define itype(o) ((o)->it)
639#define tvisnil(o) (itype(o) == LJ_TNIL)
640#define tvisfalse(o) (itype(o) == LJ_TFALSE)
641#define tvistrue(o) (itype(o) == LJ_TTRUE)
642#define tvisbool(o) (tvisfalse(o) || tvistrue(o))
643#if LJ_64
644#define tvislightud(o) (((int32_t)itype(o) >> 15) == -2)
645#else
646#define tvislightud(o) (itype(o) == LJ_TLIGHTUD)
647#endif
648#define tvisstr(o) (itype(o) == LJ_TSTR)
649#define tvisfunc(o) (itype(o) == LJ_TFUNC)
650#define tvisthread(o) (itype(o) == LJ_TTHREAD)
651#define tvisproto(o) (itype(o) == LJ_TPROTO)
652#define tviscdata(o) (itype(o) == LJ_TCDATA)
653#define tvistab(o) (itype(o) == LJ_TTAB)
654#define tvisudata(o) (itype(o) == LJ_TUDATA)
655#define tvisnumber(o) (itype(o) <= LJ_TISNUM)
656#define tvisint(o) (LJ_DUALNUM && itype(o) == LJ_TISNUM)
657#define tvisnum(o) (itype(o) < LJ_TISNUM)
658
659#define tvistruecond(o) (itype(o) < LJ_TISTRUECOND)
660#define tvispri(o) (itype(o) >= LJ_TISPRI)
661#define tvistabud(o) (itype(o) <= LJ_TISTABUD) /* && !tvisnum() */
662#define tvisgcv(o) ((itype(o) - LJ_TISGCV) > (LJ_TNUMX - LJ_TISGCV))
663
664/* Special macros to test numbers for NaN, +0, -0, +1 and raw equality. */
665#define tvisnan(o) ((o)->n != (o)->n)
666#if LJ_64
667#define tviszero(o) (((o)->u64 << 1) == 0)
668#else
669#define tviszero(o) (((o)->u32.lo | ((o)->u32.hi << 1)) == 0)
670#endif
671#define tvispzero(o) ((o)->u64 == 0)
672#define tvismzero(o) ((o)->u64 == U64x(80000000,00000000))
673#define tvispone(o) ((o)->u64 == U64x(3ff00000,00000000))
674#define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64)
675
676/* Macros to convert type ids. */
677#if LJ_64
678#define itypemap(o) \
679 (tvisnumber(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o))
680#else
681#define itypemap(o) (tvisnumber(o) ? ~LJ_TNUMX : ~itype(o))
682#endif
683
684/* Macros to get tagged values. */
685#define gcval(o) (gcref((o)->gcr))
686#define boolV(o) check_exp(tvisbool(o), (LJ_TFALSE - (o)->it))
687#if LJ_64
688#define lightudV(o) \
689 check_exp(tvislightud(o), (void *)((o)->u64 & U64x(00007fff,ffffffff)))
690#else
691#define lightudV(o) check_exp(tvislightud(o), gcrefp((o)->gcr, void))
692#endif
693#define gcV(o) check_exp(tvisgcv(o), gcval(o))
694#define strV(o) check_exp(tvisstr(o), &gcval(o)->str)
695#define funcV(o) check_exp(tvisfunc(o), &gcval(o)->fn)
696#define threadV(o) check_exp(tvisthread(o), &gcval(o)->th)
697#define protoV(o) check_exp(tvisproto(o), &gcval(o)->pt)
698#define cdataV(o) check_exp(tviscdata(o), &gcval(o)->cd)
699#define tabV(o) check_exp(tvistab(o), &gcval(o)->tab)
700#define udataV(o) check_exp(tvisudata(o), &gcval(o)->ud)
701#define numV(o) check_exp(tvisnum(o), (o)->n)
702#define intV(o) check_exp(tvisint(o), (int32_t)(o)->i)
703
704/* Macros to set tagged values. */
705#define setitype(o, i) ((o)->it = (i))
706#define setnilV(o) ((o)->it = LJ_TNIL)
707#define setboolV(o, x) ((o)->it = LJ_TFALSE-(uint32_t)(x))
708
709static LJ_AINLINE void setlightudV(TValue *o, void *p)
710{
711#if LJ_64
712 o->u64 = (uint64_t)p | (((uint64_t)0xffff) << 48);
713#else
714 setgcrefp(o->gcr, p); setitype(o, LJ_TLIGHTUD);
715#endif
716}
717
718#if LJ_64
719#define checklightudptr(L, p) \
720 (((uint64_t)(p) >> 47) ? (lj_err_msg(L, LJ_ERR_BADLU), NULL) : (p))
721#define setcont(o, f) \
722 ((o)->u64 = (uint64_t)(void *)(f) - (uint64_t)lj_vm_asm_begin)
723#else
724#define checklightudptr(L, p) (p)
725#define setcont(o, f) setlightudV((o), (void *)(f))
726#endif
727
728#define tvchecklive(L, o) \
729 UNUSED(L), lua_assert(!tvisgcv(o) || \
730 ((~itype(o) == gcval(o)->gch.gct) && !isdead(G(L), gcval(o))))
731
732static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t itype)
733{
734 setgcref(o->gcr, v); setitype(o, itype); tvchecklive(L, o);
735}
736
737#define define_setV(name, type, tag) \
738static LJ_AINLINE void name(lua_State *L, TValue *o, type *v) \
739{ \
740 setgcV(L, o, obj2gco(v), tag); \
741}
742define_setV(setstrV, GCstr, LJ_TSTR)
743define_setV(setthreadV, lua_State, LJ_TTHREAD)
744define_setV(setprotoV, GCproto, LJ_TPROTO)
745define_setV(setfuncV, GCfunc, LJ_TFUNC)
746define_setV(setcdataV, GCcdata, LJ_TCDATA)
747define_setV(settabV, GCtab, LJ_TTAB)
748define_setV(setudataV, GCudata, LJ_TUDATA)
749
750#define setnumV(o, x) ((o)->n = (x))
751#define setnanV(o) ((o)->u64 = U64x(fff80000,00000000))
752#define setpinfV(o) ((o)->u64 = U64x(7ff00000,00000000))
753#define setminfV(o) ((o)->u64 = U64x(fff00000,00000000))
754
755static LJ_AINLINE void setintV(TValue *o, int32_t i)
756{
757#if LJ_DUALNUM
758 o->i = (uint32_t)i; setitype(o, LJ_TISNUM);
759#else
760 o->n = (lua_Number)i;
761#endif
762}
763
764static LJ_AINLINE void setint64V(TValue *o, int64_t i)
765{
766 if (LJ_DUALNUM && LJ_LIKELY(i == (int64_t)(int32_t)i))
767 setintV(o, (int32_t)i);
768 else
769 setnumV(o, (lua_Number)i);
770}
771
772#if LJ_64
773#define setintptrV(o, i) setint64V((o), (i))
774#else
775#define setintptrV(o, i) setintV((o), (i))
776#endif
777
778/* Copy tagged values. */
779static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2)
780{
781 *o1 = *o2; tvchecklive(L, o1);
782}
783
784/* -- Number to integer conversion ---------------------------------------- */
785
786#if LJ_SOFTFP
787LJ_ASMF int32_t lj_vm_tobit(double x);
788#endif
789
790static LJ_AINLINE int32_t lj_num2bit(lua_Number n)
791{
792#if LJ_SOFTFP
793 return lj_vm_tobit(n);
794#else
795 TValue o;
796 o.n = n + 6755399441055744.0; /* 2^52 + 2^51 */
797 return (int32_t)o.u32.lo;
798#endif
799}
800
801#if LJ_TARGET_X86 && !defined(__SSE2__)
802#define lj_num2int(n) lj_num2bit((n))
803#else
804#define lj_num2int(n) ((int32_t)(n))
805#endif
806
807static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)
808{
809#ifdef _MSC_VER
810 if (n >= 9223372036854775808.0) /* They think it's a feature. */
811 return (uint64_t)(int64_t)(n - 18446744073709551616.0);
812 else
813#endif
814 return (uint64_t)n;
815}
816
817static LJ_AINLINE int32_t numberVint(cTValue *o)
818{
819 if (LJ_LIKELY(tvisint(o)))
820 return intV(o);
821 else
822 return lj_num2int(numV(o));
823}
824
825static LJ_AINLINE lua_Number numberVnum(cTValue *o)
826{
827 if (LJ_UNLIKELY(tvisint(o)))
828 return (lua_Number)intV(o);
829 else
830 return numV(o);
831}
832
833/* -- Miscellaneous object handling --------------------------------------- */
834
835/* Names and maps for internal and external object tags. */
836LJ_DATA const char *const lj_obj_typename[1+LUA_TCDATA+1];
837LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1];
838
839#define typename(o) (lj_obj_itypename[itypemap(o)])
840
841/* Compare two objects without calling metamethods. */
842LJ_FUNC int lj_obj_equal(cTValue *o1, cTValue *o2);
843
844#endif
diff --git a/libraries/luajit-2.0/src/lj_opt_dce.c b/libraries/luajit-2.0/src/lj_opt_dce.c
new file mode 100644
index 0000000..0587262
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_opt_dce.c
@@ -0,0 +1,77 @@
1/*
2** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_opt_dce_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12
13#include "lj_ir.h"
14#include "lj_jit.h"
15#include "lj_iropt.h"
16
17/* Some local macros to save typing. Undef'd at the end. */
18#define IR(ref) (&J->cur.ir[(ref)])
19
20/* Scan through all snapshots and mark all referenced instructions. */
21static void dce_marksnap(jit_State *J)
22{
23 SnapNo i, nsnap = J->cur.nsnap;
24 for (i = 0; i < nsnap; i++) {
25 SnapShot *snap = &J->cur.snap[i];
26 SnapEntry *map = &J->cur.snapmap[snap->mapofs];
27 MSize n, nent = snap->nent;
28 for (n = 0; n < nent; n++) {
29 IRRef ref = snap_ref(map[n]);
30 if (ref >= REF_FIRST)
31 irt_setmark(IR(ref)->t);
32 }
33 }
34}
35
36/* Backwards propagate marks. Replace unused instructions with NOPs. */
37static void dce_propagate(jit_State *J)
38{
39 IRRef1 *pchain[IR__MAX];
40 IRRef ins;
41 uint32_t i;
42 for (i = 0; i < IR__MAX; i++) pchain[i] = &J->chain[i];
43 for (ins = J->cur.nins-1; ins >= REF_FIRST; ins--) {
44 IRIns *ir = IR(ins);
45 if (irt_ismarked(ir->t)) {
46 irt_clearmark(ir->t);
47 pchain[ir->o] = &ir->prev;
48 } else if (!ir_sideeff(ir)) {
49 *pchain[ir->o] = ir->prev; /* Reroute original instruction chain. */
50 ir->t.irt = IRT_NIL;
51 ir->o = IR_NOP; /* Replace instruction with NOP. */
52 ir->op1 = ir->op2 = 0;
53 ir->prev = 0;
54 continue;
55 }
56 if (ir->op1 >= REF_FIRST) irt_setmark(IR(ir->op1)->t);
57 if (ir->op2 >= REF_FIRST) irt_setmark(IR(ir->op2)->t);
58 }
59}
60
61/* Dead Code Elimination.
62**
63** First backpropagate marks for all used instructions. Then replace
64** the unused ones with a NOP. Note that compressing the IR to eliminate
65** the NOPs does not pay off.
66*/
67void lj_opt_dce(jit_State *J)
68{
69 if ((J->flags & JIT_F_OPT_DCE)) {
70 dce_marksnap(J);
71 dce_propagate(J);
72 }
73}
74
75#undef IR
76
77#endif
diff --git a/libraries/luajit-2.0/src/lj_opt_fold.c b/libraries/luajit-2.0/src/lj_opt_fold.c
new file mode 100644
index 0000000..e7d4f9c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_opt_fold.c
@@ -0,0 +1,2218 @@
1/*
2** FOLD: Constant Folding, Algebraic Simplifications and Reassociation.
3** ABCelim: Array Bounds Check Elimination.
4** CSE: Common-Subexpression Elimination.
5** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
6*/
7
8#define lj_opt_fold_c
9#define LUA_CORE
10
11#include <math.h>
12
13#include "lj_obj.h"
14
15#if LJ_HASJIT
16
17#include "lj_str.h"
18#include "lj_tab.h"
19#include "lj_ir.h"
20#include "lj_jit.h"
21#include "lj_iropt.h"
22#include "lj_trace.h"
23#include "lj_carith.h"
24#include "lj_vm.h"
25
26/* Here's a short description how the FOLD engine processes instructions:
27**
28** The FOLD engine receives a single instruction stored in fins (J->fold.ins).
29** The instruction and its operands are used to select matching fold rules.
30** These are applied iteratively until a fixed point is reached.
31**
32** The 8 bit opcode of the instruction itself plus the opcodes of the
33** two instructions referenced by its operands form a 24 bit key
34** 'ins left right' (unused operands -> 0, literals -> lowest 8 bits).
35**
36** This key is used for partial matching against the fold rules. The
37** left/right operand fields of the key are successively masked with
38** the 'any' wildcard, from most specific to least specific:
39**
40** ins left right
41** ins any right
42** ins left any
43** ins any any
44**
45** The masked key is used to lookup a matching fold rule in a semi-perfect
46** hash table. If a matching rule is found, the related fold function is run.
47** Multiple rules can share the same fold function. A fold rule may return
48** one of several special values:
49**
50** - NEXTFOLD means no folding was applied, because an additional test
51** inside the fold function failed. Matching continues against less
52** specific fold rules. Finally the instruction is passed on to CSE.
53**
54** - RETRYFOLD means the instruction was modified in-place. Folding is
55** retried as if this instruction had just been received.
56**
57** All other return values are terminal actions -- no further folding is
58** applied:
59**
60** - INTFOLD(i) returns a reference to the integer constant i.
61**
62** - LEFTFOLD and RIGHTFOLD return the left/right operand reference
63** without emitting an instruction.
64**
65** - CSEFOLD and EMITFOLD pass the instruction directly to CSE or emit
66** it without passing through any further optimizations.
67**
68** - FAILFOLD, DROPFOLD and CONDFOLD only apply to instructions which have
69** no result (e.g. guarded assertions): FAILFOLD means the guard would
70** always fail, i.e. the current trace is pointless. DROPFOLD means
71** the guard is always true and has been eliminated. CONDFOLD is a
72** shortcut for FAILFOLD + cond (i.e. drop if true, otherwise fail).
73**
74** - Any other return value is interpreted as an IRRef or TRef. This
75** can be a reference to an existing or a newly created instruction.
76** Only the least-significant 16 bits (IRRef1) are used to form a TRef
77** which is finally returned to the caller.
78**
79** The FOLD engine receives instructions both from the trace recorder and
80** substituted instructions from LOOP unrolling. This means all types
81** of instructions may end up here, even though the recorder bypasses
82** FOLD in some cases. Thus all loads, stores and allocations must have
83** an any/any rule to avoid being passed on to CSE.
84**
85** Carefully read the following requirements before adding or modifying
86** any fold rules:
87**
88** Requirement #1: All fold rules must preserve their destination type.
89**
90** Consistently use INTFOLD() (KINT result) or lj_ir_knum() (KNUM result).
91** Never use lj_ir_knumint() which can have either a KINT or KNUM result.
92**
93** Requirement #2: Fold rules should not create *new* instructions which
94** reference operands *across* PHIs.
95**
96** E.g. a RETRYFOLD with 'fins->op1 = fleft->op1' is invalid if the
97** left operand is a PHI. Then fleft->op1 would point across the PHI
98** frontier to an invariant instruction. Adding a PHI for this instruction
99** would be counterproductive. The solution is to add a barrier which
100** prevents folding across PHIs, i.e. 'PHIBARRIER(fleft)' in this case.
101** The only exception is for recurrences with high latencies like
102** repeated int->num->int conversions.
103**
104** One could relax this condition a bit if the referenced instruction is
105** a PHI, too. But this often leads to worse code due to excessive
106** register shuffling.
107**
108** Note: returning *existing* instructions (e.g. LEFTFOLD) is ok, though.
109** Even returning fleft->op1 would be ok, because a new PHI will added,
110** if needed. But again, this leads to excessive register shuffling and
111** should be avoided.
112**
113** Requirement #3: The set of all fold rules must be monotonic to guarantee
114** termination.
115**
116** The goal is optimization, so one primarily wants to add strength-reducing
117** rules. This means eliminating an instruction or replacing an instruction
118** with one or more simpler instructions. Don't add fold rules which point
119** into the other direction.
120**
121** Some rules (like commutativity) do not directly reduce the strength of
122** an instruction, but enable other fold rules (e.g. by moving constants
123** to the right operand). These rules must be made unidirectional to avoid
124** cycles.
125**
126** Rule of thumb: the trace recorder expands the IR and FOLD shrinks it.
127*/
128
129/* Some local macros to save typing. Undef'd at the end. */
130#define IR(ref) (&J->cur.ir[(ref)])
131#define fins (&J->fold.ins)
132#define fleft (&J->fold.left)
133#define fright (&J->fold.right)
134#define knumleft (ir_knum(fleft)->n)
135#define knumright (ir_knum(fright)->n)
136
137/* Pass IR on to next optimization in chain (FOLD). */
138#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
139
140/* Fold function type. Fastcall on x86 significantly reduces their size. */
141typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J);
142
143/* Macros for the fold specs, so buildvm can recognize them. */
144#define LJFOLD(x)
145#define LJFOLDX(x)
146#define LJFOLDF(name) static TRef LJ_FASTCALL fold_##name(jit_State *J)
147/* Note: They must be at the start of a line or buildvm ignores them! */
148
149/* Barrier to prevent using operands across PHIs. */
150#define PHIBARRIER(ir) if (irt_isphi((ir)->t)) return NEXTFOLD
151
152/* Barrier to prevent folding across a GC step.
153** GC steps can only happen at the head of a trace and at LOOP.
154** And the GC is only driven forward if there is at least one allocation.
155*/
156#define gcstep_barrier(J, ref) \
157 ((ref) < J->chain[IR_LOOP] && \
158 (J->chain[IR_SNEW] || J->chain[IR_XSNEW] || \
159 J->chain[IR_TNEW] || J->chain[IR_TDUP] || \
160 J->chain[IR_CNEW] || J->chain[IR_CNEWI] || J->chain[IR_TOSTR]))
161
162/* -- Constant folding for FP numbers ------------------------------------- */
163
164LJFOLD(ADD KNUM KNUM)
165LJFOLD(SUB KNUM KNUM)
166LJFOLD(MUL KNUM KNUM)
167LJFOLD(DIV KNUM KNUM)
168LJFOLD(NEG KNUM KNUM)
169LJFOLD(ABS KNUM KNUM)
170LJFOLD(ATAN2 KNUM KNUM)
171LJFOLD(LDEXP KNUM KNUM)
172LJFOLD(MIN KNUM KNUM)
173LJFOLD(MAX KNUM KNUM)
174LJFOLDF(kfold_numarith)
175{
176 lua_Number a = knumleft;
177 lua_Number b = knumright;
178 lua_Number y = lj_vm_foldarith(a, b, fins->o - IR_ADD);
179 return lj_ir_knum(J, y);
180}
181
182LJFOLD(LDEXP KNUM KINT)
183LJFOLDF(kfold_ldexp)
184{
185#if LJ_TARGET_X86ORX64
186 UNUSED(J);
187 return NEXTFOLD;
188#else
189 return lj_ir_knum(J, ldexp(knumleft, fright->i));
190#endif
191}
192
193LJFOLD(FPMATH KNUM any)
194LJFOLDF(kfold_fpmath)
195{
196 lua_Number a = knumleft;
197 lua_Number y = lj_vm_foldfpm(a, fins->op2);
198 return lj_ir_knum(J, y);
199}
200
201LJFOLD(POW KNUM KINT)
202LJFOLDF(kfold_numpow)
203{
204 lua_Number a = knumleft;
205 lua_Number b = (lua_Number)fright->i;
206 lua_Number y = lj_vm_foldarith(a, b, IR_POW - IR_ADD);
207 return lj_ir_knum(J, y);
208}
209
210/* Must not use kfold_kref for numbers (could be NaN). */
211LJFOLD(EQ KNUM KNUM)
212LJFOLD(NE KNUM KNUM)
213LJFOLD(LT KNUM KNUM)
214LJFOLD(GE KNUM KNUM)
215LJFOLD(LE KNUM KNUM)
216LJFOLD(GT KNUM KNUM)
217LJFOLD(ULT KNUM KNUM)
218LJFOLD(UGE KNUM KNUM)
219LJFOLD(ULE KNUM KNUM)
220LJFOLD(UGT KNUM KNUM)
221LJFOLDF(kfold_numcomp)
222{
223 return CONDFOLD(lj_ir_numcmp(knumleft, knumright, (IROp)fins->o));
224}
225
226/* -- Constant folding for 32 bit integers -------------------------------- */
227
228static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
229{
230 switch (op) {
231 case IR_ADD: k1 += k2; break;
232 case IR_SUB: k1 -= k2; break;
233 case IR_MUL: k1 *= k2; break;
234 case IR_MOD: k1 = lj_vm_modi(k1, k2); break;
235 case IR_NEG: k1 = -k1; break;
236 case IR_BAND: k1 &= k2; break;
237 case IR_BOR: k1 |= k2; break;
238 case IR_BXOR: k1 ^= k2; break;
239 case IR_BSHL: k1 <<= (k2 & 31); break;
240 case IR_BSHR: k1 = (int32_t)((uint32_t)k1 >> (k2 & 31)); break;
241 case IR_BSAR: k1 >>= (k2 & 31); break;
242 case IR_BROL: k1 = (int32_t)lj_rol((uint32_t)k1, (k2 & 31)); break;
243 case IR_BROR: k1 = (int32_t)lj_ror((uint32_t)k1, (k2 & 31)); break;
244 case IR_MIN: k1 = k1 < k2 ? k1 : k2; break;
245 case IR_MAX: k1 = k1 > k2 ? k1 : k2; break;
246 default: lua_assert(0); break;
247 }
248 return k1;
249}
250
251LJFOLD(ADD KINT KINT)
252LJFOLD(SUB KINT KINT)
253LJFOLD(MUL KINT KINT)
254LJFOLD(MOD KINT KINT)
255LJFOLD(NEG KINT KINT)
256LJFOLD(BAND KINT KINT)
257LJFOLD(BOR KINT KINT)
258LJFOLD(BXOR KINT KINT)
259LJFOLD(BSHL KINT KINT)
260LJFOLD(BSHR KINT KINT)
261LJFOLD(BSAR KINT KINT)
262LJFOLD(BROL KINT KINT)
263LJFOLD(BROR KINT KINT)
264LJFOLD(MIN KINT KINT)
265LJFOLD(MAX KINT KINT)
266LJFOLDF(kfold_intarith)
267{
268 return INTFOLD(kfold_intop(fleft->i, fright->i, (IROp)fins->o));
269}
270
271LJFOLD(ADDOV KINT KINT)
272LJFOLD(SUBOV KINT KINT)
273LJFOLD(MULOV KINT KINT)
274LJFOLDF(kfold_intovarith)
275{
276 lua_Number n = lj_vm_foldarith((lua_Number)fleft->i, (lua_Number)fright->i,
277 fins->o - IR_ADDOV);
278 int32_t k = lj_num2int(n);
279 if (n != (lua_Number)k)
280 return FAILFOLD;
281 return INTFOLD(k);
282}
283
284LJFOLD(BNOT KINT)
285LJFOLDF(kfold_bnot)
286{
287 return INTFOLD(~fleft->i);
288}
289
290LJFOLD(BSWAP KINT)
291LJFOLDF(kfold_bswap)
292{
293 return INTFOLD((int32_t)lj_bswap((uint32_t)fleft->i));
294}
295
296LJFOLD(LT KINT KINT)
297LJFOLD(GE KINT KINT)
298LJFOLD(LE KINT KINT)
299LJFOLD(GT KINT KINT)
300LJFOLD(ULT KINT KINT)
301LJFOLD(UGE KINT KINT)
302LJFOLD(ULE KINT KINT)
303LJFOLD(UGT KINT KINT)
304LJFOLD(ABC KINT KINT)
305LJFOLDF(kfold_intcomp)
306{
307 int32_t a = fleft->i, b = fright->i;
308 switch ((IROp)fins->o) {
309 case IR_LT: return CONDFOLD(a < b);
310 case IR_GE: return CONDFOLD(a >= b);
311 case IR_LE: return CONDFOLD(a <= b);
312 case IR_GT: return CONDFOLD(a > b);
313 case IR_ULT: return CONDFOLD((uint32_t)a < (uint32_t)b);
314 case IR_UGE: return CONDFOLD((uint32_t)a >= (uint32_t)b);
315 case IR_ULE: return CONDFOLD((uint32_t)a <= (uint32_t)b);
316 case IR_ABC:
317 case IR_UGT: return CONDFOLD((uint32_t)a > (uint32_t)b);
318 default: lua_assert(0); return FAILFOLD;
319 }
320}
321
322LJFOLD(UGE any KINT)
323LJFOLDF(kfold_intcomp0)
324{
325 if (fright->i == 0)
326 return DROPFOLD;
327 return NEXTFOLD;
328}
329
330/* -- Constant folding for 64 bit integers -------------------------------- */
331
332static uint64_t kfold_int64arith(uint64_t k1, uint64_t k2, IROp op)
333{
334 switch (op) {
335#if LJ_64 || LJ_HASFFI
336 case IR_ADD: k1 += k2; break;
337 case IR_SUB: k1 -= k2; break;
338#endif
339#if LJ_HASFFI
340 case IR_MUL: k1 *= k2; break;
341 case IR_BAND: k1 &= k2; break;
342 case IR_BOR: k1 |= k2; break;
343 case IR_BXOR: k1 ^= k2; break;
344#endif
345 default: UNUSED(k2); lua_assert(0); break;
346 }
347 return k1;
348}
349
350LJFOLD(ADD KINT64 KINT64)
351LJFOLD(SUB KINT64 KINT64)
352LJFOLD(MUL KINT64 KINT64)
353LJFOLD(BAND KINT64 KINT64)
354LJFOLD(BOR KINT64 KINT64)
355LJFOLD(BXOR KINT64 KINT64)
356LJFOLDF(kfold_int64arith)
357{
358 return INT64FOLD(kfold_int64arith(ir_k64(fleft)->u64,
359 ir_k64(fright)->u64, (IROp)fins->o));
360}
361
362LJFOLD(DIV KINT64 KINT64)
363LJFOLD(MOD KINT64 KINT64)
364LJFOLD(POW KINT64 KINT64)
365LJFOLDF(kfold_int64arith2)
366{
367#if LJ_HASFFI
368 uint64_t k1 = ir_k64(fleft)->u64, k2 = ir_k64(fright)->u64;
369 if (irt_isi64(fins->t)) {
370 k1 = fins->o == IR_DIV ? lj_carith_divi64((int64_t)k1, (int64_t)k2) :
371 fins->o == IR_MOD ? lj_carith_modi64((int64_t)k1, (int64_t)k2) :
372 lj_carith_powi64((int64_t)k1, (int64_t)k2);
373 } else {
374 k1 = fins->o == IR_DIV ? lj_carith_divu64(k1, k2) :
375 fins->o == IR_MOD ? lj_carith_modu64(k1, k2) :
376 lj_carith_powu64(k1, k2);
377 }
378 return INT64FOLD(k1);
379#else
380 UNUSED(J); lua_assert(0); return FAILFOLD;
381#endif
382}
383
384LJFOLD(BSHL KINT64 KINT)
385LJFOLD(BSHR KINT64 KINT)
386LJFOLD(BSAR KINT64 KINT)
387LJFOLD(BROL KINT64 KINT)
388LJFOLD(BROR KINT64 KINT)
389LJFOLDF(kfold_int64shift)
390{
391#if LJ_HASFFI || LJ_64
392 uint64_t k = ir_k64(fleft)->u64;
393 int32_t sh = (fright->i & 63);
394 switch ((IROp)fins->o) {
395 case IR_BSHL: k <<= sh; break;
396#if LJ_HASFFI
397 case IR_BSHR: k >>= sh; break;
398 case IR_BSAR: k = (uint64_t)((int64_t)k >> sh); break;
399 case IR_BROL: k = lj_rol(k, sh); break;
400 case IR_BROR: k = lj_ror(k, sh); break;
401#endif
402 default: lua_assert(0); break;
403 }
404 return INT64FOLD(k);
405#else
406 UNUSED(J); lua_assert(0); return FAILFOLD;
407#endif
408}
409
410LJFOLD(BNOT KINT64)
411LJFOLDF(kfold_bnot64)
412{
413#if LJ_HASFFI
414 return INT64FOLD(~ir_k64(fleft)->u64);
415#else
416 UNUSED(J); lua_assert(0); return FAILFOLD;
417#endif
418}
419
420LJFOLD(BSWAP KINT64)
421LJFOLDF(kfold_bswap64)
422{
423#if LJ_HASFFI
424 return INT64FOLD(lj_bswap64(ir_k64(fleft)->u64));
425#else
426 UNUSED(J); lua_assert(0); return FAILFOLD;
427#endif
428}
429
430LJFOLD(LT KINT64 KINT)
431LJFOLD(GE KINT64 KINT)
432LJFOLD(LE KINT64 KINT)
433LJFOLD(GT KINT64 KINT)
434LJFOLD(ULT KINT64 KINT)
435LJFOLD(UGE KINT64 KINT)
436LJFOLD(ULE KINT64 KINT)
437LJFOLD(UGT KINT64 KINT)
438LJFOLDF(kfold_int64comp)
439{
440#if LJ_HASFFI
441 uint64_t a = ir_k64(fleft)->u64, b = ir_k64(fright)->u64;
442 switch ((IROp)fins->o) {
443 case IR_LT: return CONDFOLD(a < b);
444 case IR_GE: return CONDFOLD(a >= b);
445 case IR_LE: return CONDFOLD(a <= b);
446 case IR_GT: return CONDFOLD(a > b);
447 case IR_ULT: return CONDFOLD((uint64_t)a < (uint64_t)b);
448 case IR_UGE: return CONDFOLD((uint64_t)a >= (uint64_t)b);
449 case IR_ULE: return CONDFOLD((uint64_t)a <= (uint64_t)b);
450 case IR_UGT: return CONDFOLD((uint64_t)a > (uint64_t)b);
451 default: lua_assert(0); return FAILFOLD;
452 }
453#else
454 UNUSED(J); lua_assert(0); return FAILFOLD;
455#endif
456}
457
458LJFOLD(UGE any KINT64)
459LJFOLDF(kfold_int64comp0)
460{
461#if LJ_HASFFI
462 if (ir_k64(fright)->u64 == 0)
463 return DROPFOLD;
464 return NEXTFOLD;
465#else
466 UNUSED(J); lua_assert(0); return FAILFOLD;
467#endif
468}
469
470/* -- Constant folding for strings ---------------------------------------- */
471
472LJFOLD(SNEW KKPTR KINT)
473LJFOLDF(kfold_snew_kptr)
474{
475 GCstr *s = lj_str_new(J->L, (const char *)ir_kptr(fleft), (size_t)fright->i);
476 return lj_ir_kstr(J, s);
477}
478
479LJFOLD(SNEW any KINT)
480LJFOLDF(kfold_snew_empty)
481{
482 if (fright->i == 0)
483 return lj_ir_kstr(J, &J2G(J)->strempty);
484 return NEXTFOLD;
485}
486
487LJFOLD(STRREF KGC KINT)
488LJFOLDF(kfold_strref)
489{
490 GCstr *str = ir_kstr(fleft);
491 lua_assert((MSize)fright->i < str->len);
492 return lj_ir_kkptr(J, (char *)strdata(str) + fright->i);
493}
494
495LJFOLD(STRREF SNEW any)
496LJFOLDF(kfold_strref_snew)
497{
498 PHIBARRIER(fleft);
499 if (irref_isk(fins->op2) && fright->i == 0) {
500 return fleft->op1; /* strref(snew(ptr, len), 0) ==> ptr */
501 } else {
502 /* Reassociate: strref(snew(strref(str, a), len), b) ==> strref(str, a+b) */
503 IRIns *ir = IR(fleft->op1);
504 IRRef1 str = ir->op1; /* IRIns * is not valid across emitir. */
505 lua_assert(ir->o == IR_STRREF);
506 PHIBARRIER(ir);
507 fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */
508 fins->op1 = str;
509 fins->ot = IRT(IR_STRREF, IRT_P32);
510 return RETRYFOLD;
511 }
512 return NEXTFOLD;
513}
514
515LJFOLD(CALLN CARG IRCALL_lj_str_cmp)
516LJFOLDF(kfold_strcmp)
517{
518 if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) {
519 GCstr *a = ir_kstr(IR(fleft->op1));
520 GCstr *b = ir_kstr(IR(fleft->op2));
521 return INTFOLD(lj_str_cmp(a, b));
522 }
523 return NEXTFOLD;
524}
525
526/* -- Constant folding of pointer arithmetic ------------------------------ */
527
528LJFOLD(ADD KGC KINT)
529LJFOLD(ADD KGC KINT64)
530LJFOLDF(kfold_add_kgc)
531{
532 GCobj *o = ir_kgc(fleft);
533#if LJ_64
534 ptrdiff_t ofs = (ptrdiff_t)ir_kint64(fright)->u64;
535#else
536 ptrdiff_t ofs = fright->i;
537#endif
538 return lj_ir_kkptr(J, (char *)o + ofs);
539}
540
541LJFOLD(ADD KPTR KINT)
542LJFOLD(ADD KPTR KINT64)
543LJFOLD(ADD KKPTR KINT)
544LJFOLD(ADD KKPTR KINT64)
545LJFOLDF(kfold_add_kptr)
546{
547 void *p = ir_kptr(fleft);
548#if LJ_64
549 ptrdiff_t ofs = (ptrdiff_t)ir_kint64(fright)->u64;
550#else
551 ptrdiff_t ofs = fright->i;
552#endif
553 return lj_ir_kptr_(J, fleft->o, (char *)p + ofs);
554}
555
556/* -- Constant folding of conversions ------------------------------------- */
557
558LJFOLD(TOBIT KNUM KNUM)
559LJFOLDF(kfold_tobit)
560{
561 return INTFOLD(lj_num2bit(knumleft));
562}
563
564LJFOLD(CONV KINT IRCONV_NUM_INT)
565LJFOLDF(kfold_conv_kint_num)
566{
567 return lj_ir_knum(J, (lua_Number)fleft->i);
568}
569
570LJFOLD(CONV KINT IRCONV_NUM_U32)
571LJFOLDF(kfold_conv_kintu32_num)
572{
573 return lj_ir_knum(J, (lua_Number)(uint32_t)fleft->i);
574}
575
576LJFOLD(CONV KINT IRCONV_I64_INT)
577LJFOLD(CONV KINT IRCONV_U64_INT)
578LJFOLDF(kfold_conv_kint_i64)
579{
580 if ((fins->op2 & IRCONV_SEXT))
581 return INT64FOLD((uint64_t)(int64_t)fleft->i);
582 else
583 return INT64FOLD((uint64_t)(int64_t)(uint32_t)fleft->i);
584}
585
586LJFOLD(CONV KINT64 IRCONV_NUM_I64)
587LJFOLDF(kfold_conv_kint64_num_i64)
588{
589 return lj_ir_knum(J, (lua_Number)(int64_t)ir_kint64(fleft)->u64);
590}
591
592LJFOLD(CONV KINT64 IRCONV_NUM_U64)
593LJFOLDF(kfold_conv_kint64_num_u64)
594{
595 return lj_ir_knum(J, (lua_Number)ir_kint64(fleft)->u64);
596}
597
598LJFOLD(CONV KINT64 IRCONV_INT_I64)
599LJFOLD(CONV KINT64 IRCONV_U32_I64)
600LJFOLDF(kfold_conv_kint64_int_i64)
601{
602 return INTFOLD((int32_t)ir_kint64(fleft)->u64);
603}
604
605LJFOLD(CONV KNUM IRCONV_INT_NUM)
606LJFOLDF(kfold_conv_knum_int_num)
607{
608 lua_Number n = knumleft;
609 if (!(fins->op2 & IRCONV_TRUNC)) {
610 int32_t k = lj_num2int(n);
611 if (irt_isguard(fins->t) && n != (lua_Number)k) {
612 /* We're about to create a guard which always fails, like CONV +1.5.
613 ** Some pathological loops cause this during LICM, e.g.:
614 ** local x,k,t = 0,1.5,{1,[1.5]=2}
615 ** for i=1,200 do x = x+ t[k]; k = k == 1 and 1.5 or 1 end
616 ** assert(x == 300)
617 */
618 return FAILFOLD;
619 }
620 return INTFOLD(k);
621 } else {
622 return INTFOLD((int32_t)n);
623 }
624}
625
626LJFOLD(CONV KNUM IRCONV_U32_NUM)
627LJFOLDF(kfold_conv_knum_u32_num)
628{
629 lua_assert((fins->op2 & IRCONV_TRUNC));
630 return INTFOLD((int32_t)(uint32_t)knumleft);
631}
632
633LJFOLD(CONV KNUM IRCONV_I64_NUM)
634LJFOLDF(kfold_conv_knum_i64_num)
635{
636 lua_assert((fins->op2 & IRCONV_TRUNC));
637 return INT64FOLD((uint64_t)(int64_t)knumleft);
638}
639
640LJFOLD(CONV KNUM IRCONV_U64_NUM)
641LJFOLDF(kfold_conv_knum_u64_num)
642{
643 lua_assert((fins->op2 & IRCONV_TRUNC));
644 return INT64FOLD(lj_num2u64(knumleft));
645}
646
647LJFOLD(TOSTR KNUM)
648LJFOLDF(kfold_tostr_knum)
649{
650 return lj_ir_kstr(J, lj_str_fromnum(J->L, &knumleft));
651}
652
653LJFOLD(TOSTR KINT)
654LJFOLDF(kfold_tostr_kint)
655{
656 return lj_ir_kstr(J, lj_str_fromint(J->L, fleft->i));
657}
658
659LJFOLD(STRTO KGC)
660LJFOLDF(kfold_strto)
661{
662 TValue n;
663 if (lj_str_tonum(ir_kstr(fleft), &n))
664 return lj_ir_knum(J, numV(&n));
665 return FAILFOLD;
666}
667
668/* -- Constant folding of equality checks --------------------------------- */
669
670/* Don't constant-fold away FLOAD checks against KNULL. */
671LJFOLD(EQ FLOAD KNULL)
672LJFOLD(NE FLOAD KNULL)
673LJFOLDX(lj_opt_cse)
674
675/* But fold all other KNULL compares, since only KNULL is equal to KNULL. */
676LJFOLD(EQ any KNULL)
677LJFOLD(NE any KNULL)
678LJFOLD(EQ KNULL any)
679LJFOLD(NE KNULL any)
680LJFOLD(EQ KINT KINT) /* Constants are unique, so same refs <==> same value. */
681LJFOLD(NE KINT KINT)
682LJFOLD(EQ KINT64 KINT64)
683LJFOLD(NE KINT64 KINT64)
684LJFOLD(EQ KGC KGC)
685LJFOLD(NE KGC KGC)
686LJFOLDF(kfold_kref)
687{
688 return CONDFOLD((fins->op1 == fins->op2) ^ (fins->o == IR_NE));
689}
690
691/* -- Algebraic shortcuts ------------------------------------------------- */
692
693LJFOLD(FPMATH FPMATH IRFPM_FLOOR)
694LJFOLD(FPMATH FPMATH IRFPM_CEIL)
695LJFOLD(FPMATH FPMATH IRFPM_TRUNC)
696LJFOLDF(shortcut_round)
697{
698 IRFPMathOp op = (IRFPMathOp)fleft->op2;
699 if (op == IRFPM_FLOOR || op == IRFPM_CEIL || op == IRFPM_TRUNC)
700 return LEFTFOLD; /* round(round_left(x)) = round_left(x) */
701 return NEXTFOLD;
702}
703
704LJFOLD(ABS ABS KNUM)
705LJFOLDF(shortcut_left)
706{
707 return LEFTFOLD; /* f(g(x)) ==> g(x) */
708}
709
710LJFOLD(ABS NEG KNUM)
711LJFOLDF(shortcut_dropleft)
712{
713 PHIBARRIER(fleft);
714 fins->op1 = fleft->op1; /* abs(neg(x)) ==> abs(x) */
715 return RETRYFOLD;
716}
717
718/* Note: no safe shortcuts with STRTO and TOSTR ("1e2" ==> +100 ==> "100"). */
719LJFOLD(NEG NEG any)
720LJFOLD(BNOT BNOT)
721LJFOLD(BSWAP BSWAP)
722LJFOLDF(shortcut_leftleft)
723{
724 PHIBARRIER(fleft); /* See above. Fold would be ok, but not beneficial. */
725 return fleft->op1; /* f(g(x)) ==> x */
726}
727
728/* -- FP algebraic simplifications ---------------------------------------- */
729
730/* FP arithmetic is tricky -- there's not much to simplify.
731** Please note the following common pitfalls before sending "improvements":
732** x+0 ==> x is INVALID for x=-0
733** 0-x ==> -x is INVALID for x=+0
734** x*0 ==> 0 is INVALID for x=-0, x=+-Inf or x=NaN
735*/
736
737LJFOLD(ADD NEG any)
738LJFOLDF(simplify_numadd_negx)
739{
740 PHIBARRIER(fleft);
741 fins->o = IR_SUB; /* (-a) + b ==> b - a */
742 fins->op1 = fins->op2;
743 fins->op2 = fleft->op1;
744 return RETRYFOLD;
745}
746
747LJFOLD(ADD any NEG)
748LJFOLDF(simplify_numadd_xneg)
749{
750 PHIBARRIER(fright);
751 fins->o = IR_SUB; /* a + (-b) ==> a - b */
752 fins->op2 = fright->op1;
753 return RETRYFOLD;
754}
755
756LJFOLD(SUB any KNUM)
757LJFOLDF(simplify_numsub_k)
758{
759 lua_Number n = knumright;
760 if (n == 0.0) /* x - (+-0) ==> x */
761 return LEFTFOLD;
762 return NEXTFOLD;
763}
764
765LJFOLD(SUB NEG KNUM)
766LJFOLDF(simplify_numsub_negk)
767{
768 PHIBARRIER(fleft);
769 fins->op2 = fleft->op1; /* (-x) - k ==> (-k) - x */
770 fins->op1 = (IRRef1)lj_ir_knum(J, -knumright);
771 return RETRYFOLD;
772}
773
774LJFOLD(SUB any NEG)
775LJFOLDF(simplify_numsub_xneg)
776{
777 PHIBARRIER(fright);
778 fins->o = IR_ADD; /* a - (-b) ==> a + b */
779 fins->op2 = fright->op1;
780 return RETRYFOLD;
781}
782
783LJFOLD(MUL any KNUM)
784LJFOLD(DIV any KNUM)
785LJFOLDF(simplify_nummuldiv_k)
786{
787 lua_Number n = knumright;
788 if (n == 1.0) { /* x o 1 ==> x */
789 return LEFTFOLD;
790 } else if (n == -1.0) { /* x o -1 ==> -x */
791 fins->o = IR_NEG;
792 fins->op2 = (IRRef1)lj_ir_knum_neg(J);
793 return RETRYFOLD;
794 } else if (fins->o == IR_MUL && n == 2.0) { /* x * 2 ==> x + x */
795 fins->o = IR_ADD;
796 fins->op2 = fins->op1;
797 return RETRYFOLD;
798 }
799 return NEXTFOLD;
800}
801
802LJFOLD(MUL NEG KNUM)
803LJFOLD(DIV NEG KNUM)
804LJFOLDF(simplify_nummuldiv_negk)
805{
806 PHIBARRIER(fleft);
807 fins->op1 = fleft->op1; /* (-a) o k ==> a o (-k) */
808 fins->op2 = (IRRef1)lj_ir_knum(J, -knumright);
809 return RETRYFOLD;
810}
811
812LJFOLD(MUL NEG NEG)
813LJFOLD(DIV NEG NEG)
814LJFOLDF(simplify_nummuldiv_negneg)
815{
816 PHIBARRIER(fleft);
817 PHIBARRIER(fright);
818 fins->op1 = fleft->op1; /* (-a) o (-b) ==> a o b */
819 fins->op2 = fright->op1;
820 return RETRYFOLD;
821}
822
823LJFOLD(POW any KINT)
824LJFOLDF(simplify_numpow_xk)
825{
826 int32_t k = fright->i;
827 TRef ref = fins->op1;
828 if (k == 0) /* x ^ 0 ==> 1 */
829 return lj_ir_knum_one(J); /* Result must be a number, not an int. */
830 if (k == 1) /* x ^ 1 ==> x */
831 return LEFTFOLD;
832 if ((uint32_t)(k+65536) > 2*65536u) /* Limit code explosion. */
833 return NEXTFOLD;
834 if (k < 0) { /* x ^ (-k) ==> (1/x) ^ k. */
835 ref = emitir(IRTN(IR_DIV), lj_ir_knum_one(J), ref);
836 k = -k;
837 }
838 /* Unroll x^k for 1 <= k <= 65536. */
839 for (; (k & 1) == 0; k >>= 1) /* Handle leading zeros. */
840 ref = emitir(IRTN(IR_MUL), ref, ref);
841 if ((k >>= 1) != 0) { /* Handle trailing bits. */
842 TRef tmp = emitir(IRTN(IR_MUL), ref, ref);
843 for (; k != 1; k >>= 1) {
844 if (k & 1)
845 ref = emitir(IRTN(IR_MUL), ref, tmp);
846 tmp = emitir(IRTN(IR_MUL), tmp, tmp);
847 }
848 ref = emitir(IRTN(IR_MUL), ref, tmp);
849 }
850 return ref;
851}
852
853LJFOLD(POW KNUM any)
854LJFOLDF(simplify_numpow_kx)
855{
856 lua_Number n = knumleft;
857 if (n == 2.0) { /* 2.0 ^ i ==> ldexp(1.0, tonum(i)) */
858 fins->o = IR_CONV;
859#if LJ_TARGET_X86ORX64
860 fins->op1 = fins->op2;
861 fins->op2 = IRCONV_NUM_INT;
862 fins->op2 = (IRRef1)lj_opt_fold(J);
863#endif
864 fins->op1 = (IRRef1)lj_ir_knum_one(J);
865 fins->o = IR_LDEXP;
866 return RETRYFOLD;
867 }
868 return NEXTFOLD;
869}
870
871/* -- Simplify conversions ------------------------------------------------ */
872
873LJFOLD(CONV CONV IRCONV_NUM_INT) /* _NUM */
874LJFOLDF(shortcut_conv_num_int)
875{
876 PHIBARRIER(fleft);
877 /* Only safe with a guarded conversion to int. */
878 if ((fleft->op2 & IRCONV_SRCMASK) == IRT_NUM && irt_isguard(fleft->t))
879 return fleft->op1; /* f(g(x)) ==> x */
880 return NEXTFOLD;
881}
882
883LJFOLD(CONV CONV IRCONV_INT_NUM) /* _INT */
884LJFOLDF(simplify_conv_int_num)
885{
886 /* Fold even across PHI to avoid expensive num->int conversions in loop. */
887 if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT)
888 return fleft->op1;
889 return NEXTFOLD;
890}
891
892LJFOLD(CONV CONV IRCONV_U32_NUM) /* _U32*/
893LJFOLDF(simplify_conv_u32_num)
894{
895 /* Fold even across PHI to avoid expensive num->int conversions in loop. */
896 if ((fleft->op2 & IRCONV_SRCMASK) == IRT_U32)
897 return fleft->op1;
898 return NEXTFOLD;
899}
900
901LJFOLD(CONV CONV IRCONV_I64_NUM) /* _INT or _U32*/
902LJFOLD(CONV CONV IRCONV_U64_NUM) /* _INT or _U32*/
903LJFOLDF(simplify_conv_i64_num)
904{
905 PHIBARRIER(fleft);
906 if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT) {
907 /* Reduce to a sign-extension. */
908 fins->op1 = fleft->op1;
909 fins->op2 = ((IRT_I64<<5)|IRT_INT|IRCONV_SEXT);
910 return RETRYFOLD;
911 } else if ((fleft->op2 & IRCONV_SRCMASK) == IRT_U32) {
912#if LJ_TARGET_X64
913 return fleft->op1;
914#else
915 /* Reduce to a zero-extension. */
916 fins->op1 = fleft->op1;
917 fins->op2 = (IRT_I64<<5)|IRT_U32;
918 return RETRYFOLD;
919#endif
920 }
921 return NEXTFOLD;
922}
923
924LJFOLD(CONV CONV IRCONV_INT_I64) /* _INT */
925LJFOLD(CONV CONV IRCONV_INT_U64) /* _INT */
926LJFOLDF(simplify_conv_int_i64)
927{
928 PHIBARRIER(fleft);
929 if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT)
930 return fleft->op1;
931 return NEXTFOLD;
932}
933
934LJFOLD(CONV CONV IRCONV_FLOAT_NUM) /* _FLOAT */
935LJFOLDF(simplify_conv_flt_num)
936{
937 PHIBARRIER(fleft);
938 if ((fleft->op2 & IRCONV_SRCMASK) == IRT_FLOAT)
939 return fleft->op1;
940 return NEXTFOLD;
941}
942
943/* Shortcut TOBIT + IRT_NUM <- IRT_INT/IRT_U32 conversion. */
944LJFOLD(TOBIT CONV KNUM)
945LJFOLDF(simplify_tobit_conv)
946{
947 if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT ||
948 (fleft->op2 & IRCONV_SRCMASK) == IRT_U32) {
949 /* Fold even across PHI to avoid expensive num->int conversions in loop. */
950 lua_assert(irt_isnum(fleft->t));
951 return fleft->op1;
952 }
953 return NEXTFOLD;
954}
955
956/* Shortcut floor/ceil/round + IRT_NUM <- IRT_INT/IRT_U32 conversion. */
957LJFOLD(FPMATH CONV IRFPM_FLOOR)
958LJFOLD(FPMATH CONV IRFPM_CEIL)
959LJFOLD(FPMATH CONV IRFPM_TRUNC)
960LJFOLDF(simplify_floor_conv)
961{
962 if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT ||
963 (fleft->op2 & IRCONV_SRCMASK) == IRT_U32)
964 return LEFTFOLD;
965 return NEXTFOLD;
966}
967
968/* Strength reduction of widening. */
969LJFOLD(CONV any IRCONV_I64_INT)
970LJFOLD(CONV any IRCONV_U64_INT)
971LJFOLDF(simplify_conv_sext)
972{
973 IRRef ref = fins->op1;
974 int64_t ofs = 0;
975 if (!(fins->op2 & IRCONV_SEXT))
976 return NEXTFOLD;
977 PHIBARRIER(fleft);
978 if (fleft->o == IR_XLOAD && (irt_isu8(fleft->t) || irt_isu16(fleft->t)))
979 goto ok_reduce;
980 if (fleft->o == IR_ADD && irref_isk(fleft->op2)) {
981 ofs = (int64_t)IR(fleft->op2)->i;
982 ref = fleft->op1;
983 }
984 /* Use scalar evolution analysis results to strength-reduce sign-extension. */
985 if (ref == J->scev.idx) {
986 IRRef lo = J->scev.dir ? J->scev.start : J->scev.stop;
987 lua_assert(irt_isint(J->scev.t));
988 if (lo && IR(lo)->i + ofs >= 0) {
989 ok_reduce:
990#if LJ_TARGET_X64
991 /* Eliminate widening. All 32 bit ops do an implicit zero-extension. */
992 return LEFTFOLD;
993#else
994 /* Reduce to a (cheaper) zero-extension. */
995 fins->op2 &= ~IRCONV_SEXT;
996 return RETRYFOLD;
997#endif
998 }
999 }
1000 return NEXTFOLD;
1001}
1002
1003/* Strength reduction of narrowing. */
1004LJFOLD(CONV ADD IRCONV_INT_I64)
1005LJFOLD(CONV SUB IRCONV_INT_I64)
1006LJFOLD(CONV MUL IRCONV_INT_I64)
1007LJFOLD(CONV ADD IRCONV_INT_U64)
1008LJFOLD(CONV SUB IRCONV_INT_U64)
1009LJFOLD(CONV MUL IRCONV_INT_U64)
1010LJFOLDF(simplify_conv_narrow)
1011{
1012 IROp op = (IROp)fleft->o;
1013 IRRef op1 = fleft->op1, op2 = fleft->op2, mode = fins->op2;
1014 PHIBARRIER(fleft);
1015 op1 = emitir(IRTI(IR_CONV), op1, mode);
1016 op2 = emitir(IRTI(IR_CONV), op2, mode);
1017 fins->ot = IRTI(op);
1018 fins->op1 = op1;
1019 fins->op2 = op2;
1020 return RETRYFOLD;
1021}
1022
1023/* Special CSE rule for CONV. */
1024LJFOLD(CONV any any)
1025LJFOLDF(cse_conv)
1026{
1027 if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) {
1028 IRRef op1 = fins->op1, op2 = (fins->op2 & IRCONV_MODEMASK);
1029 uint8_t guard = irt_isguard(fins->t);
1030 IRRef ref = J->chain[IR_CONV];
1031 while (ref > op1) {
1032 IRIns *ir = IR(ref);
1033 /* Commoning with stronger checks is ok. */
1034 if (ir->op1 == op1 && (ir->op2 & IRCONV_MODEMASK) == op2 &&
1035 irt_isguard(ir->t) >= guard)
1036 return ref;
1037 ref = ir->prev;
1038 }
1039 }
1040 return EMITFOLD; /* No fallthrough to regular CSE. */
1041}
1042
1043/* FP conversion narrowing. */
1044LJFOLD(TOBIT ADD KNUM)
1045LJFOLD(TOBIT SUB KNUM)
1046LJFOLD(CONV ADD IRCONV_INT_NUM)
1047LJFOLD(CONV SUB IRCONV_INT_NUM)
1048LJFOLD(CONV ADD IRCONV_I64_NUM)
1049LJFOLD(CONV SUB IRCONV_I64_NUM)
1050LJFOLDF(narrow_convert)
1051{
1052 PHIBARRIER(fleft);
1053 /* Narrowing ignores PHIs and repeating it inside the loop is not useful. */
1054 if (J->chain[IR_LOOP])
1055 return NEXTFOLD;
1056 lua_assert(fins->o != IR_CONV || (fins->op2&IRCONV_CONVMASK) != IRCONV_TOBIT);
1057 return lj_opt_narrow_convert(J);
1058}
1059
1060/* -- Integer algebraic simplifications ----------------------------------- */
1061
1062LJFOLD(ADD any KINT)
1063LJFOLD(ADDOV any KINT)
1064LJFOLD(SUBOV any KINT)
1065LJFOLDF(simplify_intadd_k)
1066{
1067 if (fright->i == 0) /* i o 0 ==> i */
1068 return LEFTFOLD;
1069 return NEXTFOLD;
1070}
1071
1072LJFOLD(MULOV any KINT)
1073LJFOLDF(simplify_intmul_k)
1074{
1075 if (fright->i == 0) /* i * 0 ==> 0 */
1076 return RIGHTFOLD;
1077 if (fright->i == 1) /* i * 1 ==> i */
1078 return LEFTFOLD;
1079 if (fright->i == 2) { /* i * 2 ==> i + i */
1080 fins->o = IR_ADDOV;
1081 fins->op2 = fins->op1;
1082 return RETRYFOLD;
1083 }
1084 return NEXTFOLD;
1085}
1086
1087LJFOLD(SUB any KINT)
1088LJFOLDF(simplify_intsub_k)
1089{
1090 if (fright->i == 0) /* i - 0 ==> i */
1091 return LEFTFOLD;
1092 fins->o = IR_ADD; /* i - k ==> i + (-k) */
1093 fins->op2 = (IRRef1)lj_ir_kint(J, -fright->i); /* Overflow for -2^31 ok. */
1094 return RETRYFOLD;
1095}
1096
1097LJFOLD(SUB KINT any)
1098LJFOLD(SUB KINT64 any)
1099LJFOLDF(simplify_intsub_kleft)
1100{
1101 if (fleft->o == IR_KINT ? (fleft->i == 0) : (ir_kint64(fleft)->u64 == 0)) {
1102 fins->o = IR_NEG; /* 0 - i ==> -i */
1103 fins->op1 = fins->op2;
1104 return RETRYFOLD;
1105 }
1106 return NEXTFOLD;
1107}
1108
1109LJFOLD(ADD any KINT64)
1110LJFOLDF(simplify_intadd_k64)
1111{
1112 if (ir_kint64(fright)->u64 == 0) /* i + 0 ==> i */
1113 return LEFTFOLD;
1114 return NEXTFOLD;
1115}
1116
1117LJFOLD(SUB any KINT64)
1118LJFOLDF(simplify_intsub_k64)
1119{
1120 uint64_t k = ir_kint64(fright)->u64;
1121 if (k == 0) /* i - 0 ==> i */
1122 return LEFTFOLD;
1123 fins->o = IR_ADD; /* i - k ==> i + (-k) */
1124 fins->op2 = (IRRef1)lj_ir_kint64(J, (uint64_t)-(int64_t)k);
1125 return RETRYFOLD;
1126}
1127
1128static TRef simplify_intmul_k(jit_State *J, int32_t k)
1129{
1130 /* Note: many more simplifications are possible, e.g. 2^k1 +- 2^k2.
1131 ** But this is mainly intended for simple address arithmetic.
1132 ** Also it's easier for the backend to optimize the original multiplies.
1133 */
1134 if (k == 1) { /* i * 1 ==> i */
1135 return LEFTFOLD;
1136 } else if ((k & (k-1)) == 0) { /* i * 2^k ==> i << k */
1137 fins->o = IR_BSHL;
1138 fins->op2 = lj_ir_kint(J, lj_fls((uint32_t)k));
1139 return RETRYFOLD;
1140 }
1141 return NEXTFOLD;
1142}
1143
1144LJFOLD(MUL any KINT)
1145LJFOLDF(simplify_intmul_k32)
1146{
1147 if (fright->i == 0) /* i * 0 ==> 0 */
1148 return INTFOLD(0);
1149 else if (fright->i > 0)
1150 return simplify_intmul_k(J, fright->i);
1151 return NEXTFOLD;
1152}
1153
1154LJFOLD(MUL any KINT64)
1155LJFOLDF(simplify_intmul_k64)
1156{
1157 if (ir_kint64(fright)->u64 == 0) /* i * 0 ==> 0 */
1158 return INT64FOLD(0);
1159#if LJ_64
1160 /* NYI: SPLIT for BSHL and 32 bit backend support. */
1161 else if (ir_kint64(fright)->u64 < 0x80000000u)
1162 return simplify_intmul_k(J, (int32_t)ir_kint64(fright)->u64);
1163#endif
1164 return NEXTFOLD;
1165}
1166
1167LJFOLD(MOD any KINT)
1168LJFOLDF(simplify_intmod_k)
1169{
1170 int32_t k = fright->i;
1171 lua_assert(k != 0);
1172 if (k > 0 && (k & (k-1)) == 0) { /* i % (2^k) ==> i & (2^k-1) */
1173 fins->o = IR_BAND;
1174 fins->op2 = lj_ir_kint(J, k-1);
1175 return RETRYFOLD;
1176 }
1177 return NEXTFOLD;
1178}
1179
1180LJFOLD(MOD KINT any)
1181LJFOLDF(simplify_intmod_kleft)
1182{
1183 if (fleft->i == 0)
1184 return INTFOLD(0);
1185 return NEXTFOLD;
1186}
1187
1188LJFOLD(SUB any any)
1189LJFOLD(SUBOV any any)
1190LJFOLDF(simplify_intsub)
1191{
1192 if (fins->op1 == fins->op2 && !irt_isnum(fins->t)) /* i - i ==> 0 */
1193 return irt_is64(fins->t) ? INT64FOLD(0) : INTFOLD(0);
1194 return NEXTFOLD;
1195}
1196
1197LJFOLD(SUB ADD any)
1198LJFOLDF(simplify_intsubadd_leftcancel)
1199{
1200 if (!irt_isnum(fins->t)) {
1201 PHIBARRIER(fleft);
1202 if (fins->op2 == fleft->op1) /* (i + j) - i ==> j */
1203 return fleft->op2;
1204 if (fins->op2 == fleft->op2) /* (i + j) - j ==> i */
1205 return fleft->op1;
1206 }
1207 return NEXTFOLD;
1208}
1209
1210LJFOLD(SUB SUB any)
1211LJFOLDF(simplify_intsubsub_leftcancel)
1212{
1213 if (!irt_isnum(fins->t)) {
1214 PHIBARRIER(fleft);
1215 if (fins->op1 == fleft->op1) { /* (i - j) - i ==> 0 - j */
1216 fins->op1 = (IRRef1)lj_ir_kint(J, 0);
1217 fins->op2 = fleft->op2;
1218 return RETRYFOLD;
1219 }
1220 }
1221 return NEXTFOLD;
1222}
1223
1224LJFOLD(SUB any SUB)
1225LJFOLDF(simplify_intsubsub_rightcancel)
1226{
1227 if (!irt_isnum(fins->t)) {
1228 PHIBARRIER(fright);
1229 if (fins->op1 == fright->op1) /* i - (i - j) ==> j */
1230 return fright->op2;
1231 }
1232 return NEXTFOLD;
1233}
1234
1235LJFOLD(SUB any ADD)
1236LJFOLDF(simplify_intsubadd_rightcancel)
1237{
1238 if (!irt_isnum(fins->t)) {
1239 PHIBARRIER(fright);
1240 if (fins->op1 == fright->op1) { /* i - (i + j) ==> 0 - j */
1241 fins->op2 = fright->op2;
1242 fins->op1 = (IRRef1)lj_ir_kint(J, 0);
1243 return RETRYFOLD;
1244 }
1245 if (fins->op1 == fright->op2) { /* i - (j + i) ==> 0 - j */
1246 fins->op2 = fright->op1;
1247 fins->op1 = (IRRef1)lj_ir_kint(J, 0);
1248 return RETRYFOLD;
1249 }
1250 }
1251 return NEXTFOLD;
1252}
1253
1254LJFOLD(SUB ADD ADD)
1255LJFOLDF(simplify_intsubaddadd_cancel)
1256{
1257 if (!irt_isnum(fins->t)) {
1258 PHIBARRIER(fleft);
1259 PHIBARRIER(fright);
1260 if (fleft->op1 == fright->op1) { /* (i + j1) - (i + j2) ==> j1 - j2 */
1261 fins->op1 = fleft->op2;
1262 fins->op2 = fright->op2;
1263 return RETRYFOLD;
1264 }
1265 if (fleft->op1 == fright->op2) { /* (i + j1) - (j2 + i) ==> j1 - j2 */
1266 fins->op1 = fleft->op2;
1267 fins->op2 = fright->op1;
1268 return RETRYFOLD;
1269 }
1270 if (fleft->op2 == fright->op1) { /* (j1 + i) - (i + j2) ==> j1 - j2 */
1271 fins->op1 = fleft->op1;
1272 fins->op2 = fright->op2;
1273 return RETRYFOLD;
1274 }
1275 if (fleft->op2 == fright->op2) { /* (j1 + i) - (j2 + i) ==> j1 - j2 */
1276 fins->op1 = fleft->op1;
1277 fins->op2 = fright->op1;
1278 return RETRYFOLD;
1279 }
1280 }
1281 return NEXTFOLD;
1282}
1283
1284LJFOLD(BAND any KINT)
1285LJFOLD(BAND any KINT64)
1286LJFOLDF(simplify_band_k)
1287{
1288 int64_t k = fright->o == IR_KINT ? (int64_t)fright->i :
1289 (int64_t)ir_k64(fright)->u64;
1290 if (k == 0) /* i & 0 ==> 0 */
1291 return RIGHTFOLD;
1292 if (k == -1) /* i & -1 ==> i */
1293 return LEFTFOLD;
1294 return NEXTFOLD;
1295}
1296
1297LJFOLD(BOR any KINT)
1298LJFOLD(BOR any KINT64)
1299LJFOLDF(simplify_bor_k)
1300{
1301 int64_t k = fright->o == IR_KINT ? (int64_t)fright->i :
1302 (int64_t)ir_k64(fright)->u64;
1303 if (k == 0) /* i | 0 ==> i */
1304 return LEFTFOLD;
1305 if (k == -1) /* i | -1 ==> -1 */
1306 return RIGHTFOLD;
1307 return NEXTFOLD;
1308}
1309
1310LJFOLD(BXOR any KINT)
1311LJFOLD(BXOR any KINT64)
1312LJFOLDF(simplify_bxor_k)
1313{
1314 int64_t k = fright->o == IR_KINT ? (int64_t)fright->i :
1315 (int64_t)ir_k64(fright)->u64;
1316 if (k == 0) /* i xor 0 ==> i */
1317 return LEFTFOLD;
1318 if (k == -1) { /* i xor -1 ==> ~i */
1319 fins->o = IR_BNOT;
1320 fins->op2 = 0;
1321 return RETRYFOLD;
1322 }
1323 return NEXTFOLD;
1324}
1325
1326LJFOLD(BSHL any KINT)
1327LJFOLD(BSHR any KINT)
1328LJFOLD(BSAR any KINT)
1329LJFOLD(BROL any KINT)
1330LJFOLD(BROR any KINT)
1331LJFOLDF(simplify_shift_ik)
1332{
1333 int32_t mask = irt_is64(fins->t) ? 63 : 31;
1334 int32_t k = (fright->i & mask);
1335 if (k == 0) /* i o 0 ==> i */
1336 return LEFTFOLD;
1337 if (k == 1 && fins->o == IR_BSHL) { /* i << 1 ==> i + i */
1338 fins->o = IR_ADD;
1339 fins->op2 = fins->op1;
1340 return RETRYFOLD;
1341 }
1342 if (k != fright->i) { /* i o k ==> i o (k & mask) */
1343 fins->op2 = (IRRef1)lj_ir_kint(J, k);
1344 return RETRYFOLD;
1345 }
1346#ifndef LJ_TARGET_UNIFYROT
1347 if (fins->o == IR_BROR) { /* bror(i, k) ==> brol(i, (-k)&mask) */
1348 fins->o = IR_BROL;
1349 fins->op2 = (IRRef1)lj_ir_kint(J, (-k)&mask);
1350 return RETRYFOLD;
1351 }
1352#endif
1353 return NEXTFOLD;
1354}
1355
1356LJFOLD(BSHL any BAND)
1357LJFOLD(BSHR any BAND)
1358LJFOLD(BSAR any BAND)
1359LJFOLD(BROL any BAND)
1360LJFOLD(BROR any BAND)
1361LJFOLDF(simplify_shift_andk)
1362{
1363 IRIns *irk = IR(fright->op2);
1364 PHIBARRIER(fright);
1365 if ((fins->o < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
1366 irk->o == IR_KINT) { /* i o (j & mask) ==> i o j */
1367 int32_t mask = irt_is64(fins->t) ? 63 : 31;
1368 int32_t k = irk->i & mask;
1369 if (k == mask) {
1370 fins->op2 = fright->op1;
1371 return RETRYFOLD;
1372 }
1373 }
1374 return NEXTFOLD;
1375}
1376
1377LJFOLD(BSHL KINT any)
1378LJFOLD(BSHR KINT any)
1379LJFOLD(BSHL KINT64 any)
1380LJFOLD(BSHR KINT64 any)
1381LJFOLDF(simplify_shift1_ki)
1382{
1383 int64_t k = fleft->o == IR_KINT ? (int64_t)fleft->i :
1384 (int64_t)ir_k64(fleft)->u64;
1385 if (k == 0) /* 0 o i ==> 0 */
1386 return LEFTFOLD;
1387 return NEXTFOLD;
1388}
1389
1390LJFOLD(BSAR KINT any)
1391LJFOLD(BROL KINT any)
1392LJFOLD(BROR KINT any)
1393LJFOLD(BSAR KINT64 any)
1394LJFOLD(BROL KINT64 any)
1395LJFOLD(BROR KINT64 any)
1396LJFOLDF(simplify_shift2_ki)
1397{
1398 int64_t k = fleft->o == IR_KINT ? (int64_t)fleft->i :
1399 (int64_t)ir_k64(fleft)->u64;
1400 if (k == 0 || k == -1) /* 0 o i ==> 0; -1 o i ==> -1 */
1401 return LEFTFOLD;
1402 return NEXTFOLD;
1403}
1404
1405LJFOLD(BSHL BAND KINT)
1406LJFOLD(BSHR BAND KINT)
1407LJFOLD(BROL BAND KINT)
1408LJFOLD(BROR BAND KINT)
1409LJFOLDF(simplify_shiftk_andk)
1410{
1411 IRIns *irk = IR(fleft->op2);
1412 PHIBARRIER(fleft);
1413 if (irk->o == IR_KINT) { /* (i & k1) o k2 ==> (i o k2) & (k1 o k2) */
1414 int32_t k = kfold_intop(irk->i, fright->i, (IROp)fins->o);
1415 fins->op1 = fleft->op1;
1416 fins->op1 = (IRRef1)lj_opt_fold(J);
1417 fins->op2 = (IRRef1)lj_ir_kint(J, k);
1418 fins->ot = IRTI(IR_BAND);
1419 return RETRYFOLD;
1420 }
1421 return NEXTFOLD;
1422}
1423
1424LJFOLD(BAND BSHL KINT)
1425LJFOLD(BAND BSHR KINT)
1426LJFOLDF(simplify_andk_shiftk)
1427{
1428 IRIns *irk = IR(fleft->op2);
1429 if (irk->o == IR_KINT &&
1430 kfold_intop(-1, irk->i, (IROp)fleft->o) == fright->i)
1431 return LEFTFOLD; /* (i o k1) & k2 ==> i, if (-1 o k1) == k2 */
1432 return NEXTFOLD;
1433}
1434
1435/* -- Reassociation ------------------------------------------------------- */
1436
1437LJFOLD(ADD ADD KINT)
1438LJFOLD(MUL MUL KINT)
1439LJFOLD(BAND BAND KINT)
1440LJFOLD(BOR BOR KINT)
1441LJFOLD(BXOR BXOR KINT)
1442LJFOLDF(reassoc_intarith_k)
1443{
1444 IRIns *irk = IR(fleft->op2);
1445 if (irk->o == IR_KINT) {
1446 int32_t k = kfold_intop(irk->i, fright->i, (IROp)fins->o);
1447 if (k == irk->i) /* (i o k1) o k2 ==> i o k1, if (k1 o k2) == k1. */
1448 return LEFTFOLD;
1449 PHIBARRIER(fleft);
1450 fins->op1 = fleft->op1;
1451 fins->op2 = (IRRef1)lj_ir_kint(J, k);
1452 return RETRYFOLD; /* (i o k1) o k2 ==> i o (k1 o k2) */
1453 }
1454 return NEXTFOLD;
1455}
1456
1457LJFOLD(ADD ADD KINT64)
1458LJFOLD(MUL MUL KINT64)
1459LJFOLD(BAND BAND KINT64)
1460LJFOLD(BOR BOR KINT64)
1461LJFOLD(BXOR BXOR KINT64)
1462LJFOLDF(reassoc_intarith_k64)
1463{
1464#if LJ_HASFFI || LJ_64
1465 IRIns *irk = IR(fleft->op2);
1466 if (irk->o == IR_KINT64) {
1467 uint64_t k = kfold_int64arith(ir_k64(irk)->u64,
1468 ir_k64(fright)->u64, (IROp)fins->o);
1469 PHIBARRIER(fleft);
1470 fins->op1 = fleft->op1;
1471 fins->op2 = (IRRef1)lj_ir_kint64(J, k);
1472 return RETRYFOLD; /* (i o k1) o k2 ==> i o (k1 o k2) */
1473 }
1474 return NEXTFOLD;
1475#else
1476 UNUSED(J); lua_assert(0); return FAILFOLD;
1477#endif
1478}
1479
1480LJFOLD(MIN MIN any)
1481LJFOLD(MAX MAX any)
1482LJFOLD(BAND BAND any)
1483LJFOLD(BOR BOR any)
1484LJFOLDF(reassoc_dup)
1485{
1486 if (fins->op2 == fleft->op1 || fins->op2 == fleft->op2)
1487 return LEFTFOLD; /* (a o b) o a ==> a o b; (a o b) o b ==> a o b */
1488 return NEXTFOLD;
1489}
1490
1491LJFOLD(BXOR BXOR any)
1492LJFOLDF(reassoc_bxor)
1493{
1494 PHIBARRIER(fleft);
1495 if (fins->op2 == fleft->op1) /* (a xor b) xor a ==> b */
1496 return fleft->op2;
1497 if (fins->op2 == fleft->op2) /* (a xor b) xor b ==> a */
1498 return fleft->op1;
1499 return NEXTFOLD;
1500}
1501
1502LJFOLD(BSHL BSHL KINT)
1503LJFOLD(BSHR BSHR KINT)
1504LJFOLD(BSAR BSAR KINT)
1505LJFOLD(BROL BROL KINT)
1506LJFOLD(BROR BROR KINT)
1507LJFOLDF(reassoc_shift)
1508{
1509 IRIns *irk = IR(fleft->op2);
1510 PHIBARRIER(fleft); /* The (shift any KINT) rule covers k2 == 0 and more. */
1511 if (irk->o == IR_KINT) { /* (i o k1) o k2 ==> i o (k1 + k2) */
1512 int32_t mask = irt_is64(fins->t) ? 63 : 31;
1513 int32_t k = (irk->i & mask) + (fright->i & mask);
1514 if (k > mask) { /* Combined shift too wide? */
1515 if (fins->o == IR_BSHL || fins->o == IR_BSHR)
1516 return mask == 31 ? INTFOLD(0) : INT64FOLD(0);
1517 else if (fins->o == IR_BSAR)
1518 k = mask;
1519 else
1520 k &= mask;
1521 }
1522 fins->op1 = fleft->op1;
1523 fins->op2 = (IRRef1)lj_ir_kint(J, k);
1524 return RETRYFOLD;
1525 }
1526 return NEXTFOLD;
1527}
1528
1529LJFOLD(MIN MIN KNUM)
1530LJFOLD(MAX MAX KNUM)
1531LJFOLD(MIN MIN KINT)
1532LJFOLD(MAX MAX KINT)
1533LJFOLDF(reassoc_minmax_k)
1534{
1535 IRIns *irk = IR(fleft->op2);
1536 if (irk->o == IR_KNUM) {
1537 lua_Number a = ir_knum(irk)->n;
1538 lua_Number y = lj_vm_foldarith(a, knumright, fins->o - IR_ADD);
1539 if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
1540 return LEFTFOLD;
1541 PHIBARRIER(fleft);
1542 fins->op1 = fleft->op1;
1543 fins->op2 = (IRRef1)lj_ir_knum(J, y);
1544 return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
1545 } else if (irk->o == IR_KINT) {
1546 int32_t a = irk->i;
1547 int32_t y = kfold_intop(a, fright->i, fins->o);
1548 if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
1549 return LEFTFOLD;
1550 PHIBARRIER(fleft);
1551 fins->op1 = fleft->op1;
1552 fins->op2 = (IRRef1)lj_ir_kint(J, y);
1553 return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
1554 }
1555 return NEXTFOLD;
1556}
1557
1558LJFOLD(MIN MAX any)
1559LJFOLD(MAX MIN any)
1560LJFOLDF(reassoc_minmax_left)
1561{
1562 if (fins->op2 == fleft->op1 || fins->op2 == fleft->op2)
1563 return RIGHTFOLD; /* (b o1 a) o2 b ==> b; (a o1 b) o2 b ==> b */
1564 return NEXTFOLD;
1565}
1566
1567LJFOLD(MIN any MAX)
1568LJFOLD(MAX any MIN)
1569LJFOLDF(reassoc_minmax_right)
1570{
1571 if (fins->op1 == fright->op1 || fins->op1 == fright->op2)
1572 return LEFTFOLD; /* a o2 (a o1 b) ==> a; a o2 (b o1 a) ==> a */
1573 return NEXTFOLD;
1574}
1575
1576/* -- Array bounds check elimination -------------------------------------- */
1577
1578/* Eliminate ABC across PHIs to handle t[i-1] forwarding case.
1579** ABC(asize, (i+k)+(-k)) ==> ABC(asize, i), but only if it already exists.
1580** Could be generalized to (i+k1)+k2 ==> i+(k1+k2), but needs better disambig.
1581*/
1582LJFOLD(ABC any ADD)
1583LJFOLDF(abc_fwd)
1584{
1585 if (LJ_LIKELY(J->flags & JIT_F_OPT_ABC)) {
1586 if (irref_isk(fright->op2)) {
1587 IRIns *add2 = IR(fright->op1);
1588 if (add2->o == IR_ADD && irref_isk(add2->op2) &&
1589 IR(fright->op2)->i == -IR(add2->op2)->i) {
1590 IRRef ref = J->chain[IR_ABC];
1591 IRRef lim = add2->op1;
1592 if (fins->op1 > lim) lim = fins->op1;
1593 while (ref > lim) {
1594 IRIns *ir = IR(ref);
1595 if (ir->op1 == fins->op1 && ir->op2 == add2->op1)
1596 return DROPFOLD;
1597 ref = ir->prev;
1598 }
1599 }
1600 }
1601 }
1602 return NEXTFOLD;
1603}
1604
1605/* Eliminate ABC for constants.
1606** ABC(asize, k1), ABC(asize k2) ==> ABC(asize, max(k1, k2))
1607** Drop second ABC if k2 is lower. Otherwise patch first ABC with k2.
1608*/
1609LJFOLD(ABC any KINT)
1610LJFOLDF(abc_k)
1611{
1612 if (LJ_LIKELY(J->flags & JIT_F_OPT_ABC)) {
1613 IRRef ref = J->chain[IR_ABC];
1614 IRRef asize = fins->op1;
1615 while (ref > asize) {
1616 IRIns *ir = IR(ref);
1617 if (ir->op1 == asize && irref_isk(ir->op2)) {
1618 int32_t k = IR(ir->op2)->i;
1619 if (fright->i > k)
1620 ir->op2 = fins->op2;
1621 return DROPFOLD;
1622 }
1623 ref = ir->prev;
1624 }
1625 return EMITFOLD; /* Already performed CSE. */
1626 }
1627 return NEXTFOLD;
1628}
1629
1630/* Eliminate invariant ABC inside loop. */
1631LJFOLD(ABC any any)
1632LJFOLDF(abc_invar)
1633{
1634 if (!irt_isint(fins->t) && J->chain[IR_LOOP]) /* Currently marked as PTR. */
1635 return DROPFOLD;
1636 return NEXTFOLD;
1637}
1638
1639/* -- Commutativity ------------------------------------------------------- */
1640
1641/* The refs of commutative ops are canonicalized. Lower refs go to the right.
1642** Rationale behind this:
1643** - It (also) moves constants to the right.
1644** - It reduces the number of FOLD rules (e.g. (BOR any KINT) suffices).
1645** - It helps CSE to find more matches.
1646** - The assembler generates better code with constants at the right.
1647*/
1648
1649LJFOLD(ADD any any)
1650LJFOLD(MUL any any)
1651LJFOLD(ADDOV any any)
1652LJFOLD(MULOV any any)
1653LJFOLDF(comm_swap)
1654{
1655 if (fins->op1 < fins->op2) { /* Move lower ref to the right. */
1656 IRRef1 tmp = fins->op1;
1657 fins->op1 = fins->op2;
1658 fins->op2 = tmp;
1659 return RETRYFOLD;
1660 }
1661 return NEXTFOLD;
1662}
1663
1664LJFOLD(EQ any any)
1665LJFOLD(NE any any)
1666LJFOLDF(comm_equal)
1667{
1668 /* For non-numbers only: x == x ==> drop; x ~= x ==> fail */
1669 if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
1670 return CONDFOLD(fins->o == IR_EQ);
1671 return fold_comm_swap(J);
1672}
1673
1674LJFOLD(LT any any)
1675LJFOLD(GE any any)
1676LJFOLD(LE any any)
1677LJFOLD(GT any any)
1678LJFOLD(ULT any any)
1679LJFOLD(UGE any any)
1680LJFOLD(ULE any any)
1681LJFOLD(UGT any any)
1682LJFOLDF(comm_comp)
1683{
1684 /* For non-numbers only: x <=> x ==> drop; x <> x ==> fail */
1685 if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
1686 return CONDFOLD((fins->o ^ (fins->o >> 1)) & 1);
1687 if (fins->op1 < fins->op2) { /* Move lower ref to the right. */
1688 IRRef1 tmp = fins->op1;
1689 fins->op1 = fins->op2;
1690 fins->op2 = tmp;
1691 fins->o ^= 3; /* GT <-> LT, GE <-> LE, does not affect U */
1692 return RETRYFOLD;
1693 }
1694 return NEXTFOLD;
1695}
1696
1697LJFOLD(BAND any any)
1698LJFOLD(BOR any any)
1699LJFOLD(MIN any any)
1700LJFOLD(MAX any any)
1701LJFOLDF(comm_dup)
1702{
1703 if (fins->op1 == fins->op2) /* x o x ==> x */
1704 return LEFTFOLD;
1705 return fold_comm_swap(J);
1706}
1707
1708LJFOLD(BXOR any any)
1709LJFOLDF(comm_bxor)
1710{
1711 if (fins->op1 == fins->op2) /* i xor i ==> 0 */
1712 return irt_is64(fins->t) ? INT64FOLD(0) : INTFOLD(0);
1713 return fold_comm_swap(J);
1714}
1715
1716/* -- Simplification of compound expressions ------------------------------ */
1717
1718static TRef kfold_xload(jit_State *J, IRIns *ir, const void *p)
1719{
1720 int32_t k;
1721 switch (irt_type(ir->t)) {
1722 case IRT_NUM: return lj_ir_knum_u64(J, *(uint64_t *)p);
1723 case IRT_I8: k = (int32_t)*(int8_t *)p; break;
1724 case IRT_U8: k = (int32_t)*(uint8_t *)p; break;
1725 case IRT_I16: k = (int32_t)(int16_t)lj_getu16(p); break;
1726 case IRT_U16: k = (int32_t)(uint16_t)lj_getu16(p); break;
1727 case IRT_INT: case IRT_U32: k = (int32_t)lj_getu32(p); break;
1728 case IRT_I64: case IRT_U64: return lj_ir_kint64(J, *(uint64_t *)p);
1729 default: return 0;
1730 }
1731 return lj_ir_kint(J, k);
1732}
1733
1734/* Turn: string.sub(str, a, b) == kstr
1735** into: string.byte(str, a) == string.byte(kstr, 1) etc.
1736** Note: this creates unaligned XLOADs on x86/x64.
1737*/
1738LJFOLD(EQ SNEW KGC)
1739LJFOLD(NE SNEW KGC)
1740LJFOLDF(merge_eqne_snew_kgc)
1741{
1742 GCstr *kstr = ir_kstr(fright);
1743 int32_t len = (int32_t)kstr->len;
1744 lua_assert(irt_isstr(fins->t));
1745
1746#if LJ_TARGET_X86ORX64
1747#define FOLD_SNEW_MAX_LEN 4 /* Handle string lengths 0, 1, 2, 3, 4. */
1748#define FOLD_SNEW_TYPE8 IRT_I8 /* Creates shorter immediates. */
1749#else
1750#define FOLD_SNEW_MAX_LEN 1 /* Handle string lengths 0 or 1. */
1751#define FOLD_SNEW_TYPE8 IRT_U8 /* Prefer unsigned loads. */
1752#endif
1753
1754 if (len <= FOLD_SNEW_MAX_LEN) {
1755 IROp op = (IROp)fins->o;
1756 IRRef strref = fleft->op1;
1757 lua_assert(IR(strref)->o == IR_STRREF);
1758 if (op == IR_EQ) {
1759 emitir(IRTGI(IR_EQ), fleft->op2, lj_ir_kint(J, len));
1760 /* Caveat: fins/fleft/fright is no longer valid after emitir. */
1761 } else {
1762 /* NE is not expanded since this would need an OR of two conds. */
1763 if (!irref_isk(fleft->op2)) /* Only handle the constant length case. */
1764 return NEXTFOLD;
1765 if (IR(fleft->op2)->i != len)
1766 return DROPFOLD;
1767 }
1768 if (len > 0) {
1769 /* A 4 byte load for length 3 is ok -- all strings have an extra NUL. */
1770 uint16_t ot = (uint16_t)(len == 1 ? IRT(IR_XLOAD, FOLD_SNEW_TYPE8) :
1771 len == 2 ? IRT(IR_XLOAD, IRT_U16) :
1772 IRTI(IR_XLOAD));
1773 TRef tmp = emitir(ot, strref,
1774 IRXLOAD_READONLY | (len > 1 ? IRXLOAD_UNALIGNED : 0));
1775 TRef val = kfold_xload(J, IR(tref_ref(tmp)), strdata(kstr));
1776 if (len == 3)
1777 tmp = emitir(IRTI(IR_BAND), tmp,
1778 lj_ir_kint(J, LJ_ENDIAN_SELECT(0x00ffffff, 0xffffff00)));
1779 fins->op1 = (IRRef1)tmp;
1780 fins->op2 = (IRRef1)val;
1781 fins->ot = (IROpT)IRTGI(op);
1782 return RETRYFOLD;
1783 } else {
1784 return DROPFOLD;
1785 }
1786 }
1787 return NEXTFOLD;
1788}
1789
1790/* -- Loads --------------------------------------------------------------- */
1791
1792/* Loads cannot be folded or passed on to CSE in general.
1793** Alias analysis is needed to check for forwarding opportunities.
1794**
1795** Caveat: *all* loads must be listed here or they end up at CSE!
1796*/
1797
1798LJFOLD(ALOAD any)
1799LJFOLDX(lj_opt_fwd_aload)
1800
1801/* From HREF fwd (see below). Must eliminate, not supported by fwd/backend. */
1802LJFOLD(HLOAD KKPTR)
1803LJFOLDF(kfold_hload_kkptr)
1804{
1805 UNUSED(J);
1806 lua_assert(ir_kptr(fleft) == niltvg(J2G(J)));
1807 return TREF_NIL;
1808}
1809
1810LJFOLD(HLOAD any)
1811LJFOLDX(lj_opt_fwd_hload)
1812
1813LJFOLD(ULOAD any)
1814LJFOLDX(lj_opt_fwd_uload)
1815
1816LJFOLD(CALLL any IRCALL_lj_tab_len)
1817LJFOLDX(lj_opt_fwd_tab_len)
1818
1819/* Upvalue refs are really loads, but there are no corresponding stores.
1820** So CSE is ok for them, except for UREFO across a GC step (see below).
1821** If the referenced function is const, its upvalue addresses are const, too.
1822** This can be used to improve CSE by looking for the same address,
1823** even if the upvalues originate from a different function.
1824*/
1825LJFOLD(UREFO KGC any)
1826LJFOLD(UREFC KGC any)
1827LJFOLDF(cse_uref)
1828{
1829 if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) {
1830 IRRef ref = J->chain[fins->o];
1831 GCfunc *fn = ir_kfunc(fleft);
1832 GCupval *uv = gco2uv(gcref(fn->l.uvptr[(fins->op2 >> 8)]));
1833 while (ref > 0) {
1834 IRIns *ir = IR(ref);
1835 if (irref_isk(ir->op1)) {
1836 GCfunc *fn2 = ir_kfunc(IR(ir->op1));
1837 if (gco2uv(gcref(fn2->l.uvptr[(ir->op2 >> 8)])) == uv) {
1838 if (fins->o == IR_UREFO && gcstep_barrier(J, ref))
1839 break;
1840 return ref;
1841 }
1842 }
1843 ref = ir->prev;
1844 }
1845 }
1846 return EMITFOLD;
1847}
1848
1849LJFOLD(HREF TNEW any)
1850LJFOLDF(fwd_href_tnew)
1851{
1852 if (lj_opt_fwd_href_nokey(J))
1853 return lj_ir_kkptr(J, niltvg(J2G(J)));
1854 return NEXTFOLD;
1855}
1856
1857LJFOLD(HREF TDUP KPRI)
1858LJFOLD(HREF TDUP KGC)
1859LJFOLD(HREF TDUP KNUM)
1860LJFOLDF(fwd_href_tdup)
1861{
1862 TValue keyv;
1863 lj_ir_kvalue(J->L, &keyv, fright);
1864 if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) &&
1865 lj_opt_fwd_href_nokey(J))
1866 return lj_ir_kkptr(J, niltvg(J2G(J)));
1867 return NEXTFOLD;
1868}
1869
1870/* We can safely FOLD/CSE array/hash refs and field loads, since there
1871** are no corresponding stores. But we need to check for any NEWREF with
1872** an aliased table, as it may invalidate all of the pointers and fields.
1873** Only HREF needs the NEWREF check -- AREF and HREFK already depend on
1874** FLOADs. And NEWREF itself is treated like a store (see below).
1875*/
1876LJFOLD(FLOAD TNEW IRFL_TAB_ASIZE)
1877LJFOLDF(fload_tab_tnew_asize)
1878{
1879 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && lj_opt_fwd_tptr(J, fins->op1))
1880 return INTFOLD(fleft->op1);
1881 return NEXTFOLD;
1882}
1883
1884LJFOLD(FLOAD TNEW IRFL_TAB_HMASK)
1885LJFOLDF(fload_tab_tnew_hmask)
1886{
1887 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && lj_opt_fwd_tptr(J, fins->op1))
1888 return INTFOLD((1 << fleft->op2)-1);
1889 return NEXTFOLD;
1890}
1891
1892LJFOLD(FLOAD TDUP IRFL_TAB_ASIZE)
1893LJFOLDF(fload_tab_tdup_asize)
1894{
1895 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && lj_opt_fwd_tptr(J, fins->op1))
1896 return INTFOLD((int32_t)ir_ktab(IR(fleft->op1))->asize);
1897 return NEXTFOLD;
1898}
1899
1900LJFOLD(FLOAD TDUP IRFL_TAB_HMASK)
1901LJFOLDF(fload_tab_tdup_hmask)
1902{
1903 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && lj_opt_fwd_tptr(J, fins->op1))
1904 return INTFOLD((int32_t)ir_ktab(IR(fleft->op1))->hmask);
1905 return NEXTFOLD;
1906}
1907
1908LJFOLD(HREF any any)
1909LJFOLD(FLOAD any IRFL_TAB_ARRAY)
1910LJFOLD(FLOAD any IRFL_TAB_NODE)
1911LJFOLD(FLOAD any IRFL_TAB_ASIZE)
1912LJFOLD(FLOAD any IRFL_TAB_HMASK)
1913LJFOLDF(fload_tab_ah)
1914{
1915 TRef tr = lj_opt_cse(J);
1916 return lj_opt_fwd_tptr(J, tref_ref(tr)) ? tr : EMITFOLD;
1917}
1918
1919/* Strings are immutable, so we can safely FOLD/CSE the related FLOAD. */
1920LJFOLD(FLOAD KGC IRFL_STR_LEN)
1921LJFOLDF(fload_str_len_kgc)
1922{
1923 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
1924 return INTFOLD((int32_t)ir_kstr(fleft)->len);
1925 return NEXTFOLD;
1926}
1927
1928LJFOLD(FLOAD SNEW IRFL_STR_LEN)
1929LJFOLDF(fload_str_len_snew)
1930{
1931 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) {
1932 PHIBARRIER(fleft);
1933 return fleft->op2;
1934 }
1935 return NEXTFOLD;
1936}
1937
1938/* The C type ID of cdata objects is immutable. */
1939LJFOLD(FLOAD KGC IRFL_CDATA_TYPEID)
1940LJFOLDF(fload_cdata_typeid_kgc)
1941{
1942 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
1943 return INTFOLD((int32_t)ir_kcdata(fleft)->typeid);
1944 return NEXTFOLD;
1945}
1946
1947/* Get the contents of immutable cdata objects. */
1948LJFOLD(FLOAD KGC IRFL_CDATA_PTR)
1949LJFOLD(FLOAD KGC IRFL_CDATA_INT64)
1950LJFOLDF(fload_cdata_int64_kgc)
1951{
1952 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) {
1953 void *p = cdataptr(ir_kcdata(fleft));
1954 if (irt_is64(fins->t))
1955 return INT64FOLD(*(uint64_t *)p);
1956 else
1957 return INTFOLD(*(int32_t *)p);
1958 }
1959 return NEXTFOLD;
1960}
1961
1962LJFOLD(FLOAD CNEW IRFL_CDATA_TYPEID)
1963LJFOLD(FLOAD CNEWI IRFL_CDATA_TYPEID)
1964LJFOLDF(fload_cdata_typeid_cnew)
1965{
1966 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
1967 return fleft->op1; /* No PHI barrier needed. CNEW/CNEWI op1 is const. */
1968 return NEXTFOLD;
1969}
1970
1971/* Pointer and int64 cdata objects are immutable. */
1972LJFOLD(FLOAD CNEWI IRFL_CDATA_PTR)
1973LJFOLD(FLOAD CNEWI IRFL_CDATA_INT64)
1974LJFOLDF(fload_cdata_ptr_int64_cnew)
1975{
1976 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
1977 return fleft->op2; /* Fold even across PHI to avoid allocations. */
1978 return NEXTFOLD;
1979}
1980
1981LJFOLD(FLOAD any IRFL_STR_LEN)
1982LJFOLD(FLOAD any IRFL_CDATA_TYPEID)
1983LJFOLD(FLOAD any IRFL_CDATA_PTR)
1984LJFOLD(FLOAD any IRFL_CDATA_INT64)
1985LJFOLD(VLOAD any any) /* Vararg loads have no corresponding stores. */
1986LJFOLDX(lj_opt_cse)
1987
1988/* All other field loads need alias analysis. */
1989LJFOLD(FLOAD any any)
1990LJFOLDX(lj_opt_fwd_fload)
1991
1992/* This is for LOOP only. Recording handles SLOADs internally. */
1993LJFOLD(SLOAD any any)
1994LJFOLDF(fwd_sload)
1995{
1996 if ((fins->op2 & IRSLOAD_FRAME)) {
1997 TRef tr = lj_opt_cse(J);
1998 return tref_ref(tr) < J->chain[IR_RETF] ? EMITFOLD : tr;
1999 } else {
2000 lua_assert(J->slot[fins->op1] != 0);
2001 return J->slot[fins->op1];
2002 }
2003}
2004
2005/* Only fold for KKPTR. The pointer _and_ the contents must be const. */
2006LJFOLD(XLOAD KKPTR any)
2007LJFOLDF(xload_kptr)
2008{
2009 TRef tr = kfold_xload(J, fins, ir_kptr(fleft));
2010 return tr ? tr : NEXTFOLD;
2011}
2012
2013LJFOLD(XLOAD any any)
2014LJFOLDX(lj_opt_fwd_xload)
2015
2016/* -- Write barriers ------------------------------------------------------ */
2017
2018/* Write barriers are amenable to CSE, but not across any incremental
2019** GC steps.
2020**
2021** The same logic applies to open upvalue references, because a stack
2022** may be resized during a GC step (not the current stack, but maybe that
2023** of a coroutine).
2024*/
2025LJFOLD(TBAR any)
2026LJFOLD(OBAR any any)
2027LJFOLD(UREFO any any)
2028LJFOLDF(barrier_tab)
2029{
2030 TRef tr = lj_opt_cse(J);
2031 if (gcstep_barrier(J, tref_ref(tr))) /* CSE across GC step? */
2032 return EMITFOLD; /* Raw emit. Assumes fins is left intact by CSE. */
2033 return tr;
2034}
2035
2036LJFOLD(TBAR TNEW)
2037LJFOLD(TBAR TDUP)
2038LJFOLDF(barrier_tnew_tdup)
2039{
2040 /* New tables are always white and never need a barrier. */
2041 if (fins->op1 < J->chain[IR_LOOP]) /* Except across a GC step. */
2042 return NEXTFOLD;
2043 return DROPFOLD;
2044}
2045
2046/* -- Stores and allocations ---------------------------------------------- */
2047
2048/* Stores and allocations cannot be folded or passed on to CSE in general.
2049** But some stores can be eliminated with dead-store elimination (DSE).
2050**
2051** Caveat: *all* stores and allocs must be listed here or they end up at CSE!
2052*/
2053
2054LJFOLD(ASTORE any any)
2055LJFOLD(HSTORE any any)
2056LJFOLDX(lj_opt_dse_ahstore)
2057
2058LJFOLD(USTORE any any)
2059LJFOLDX(lj_opt_dse_ustore)
2060
2061LJFOLD(FSTORE any any)
2062LJFOLDX(lj_opt_dse_fstore)
2063
2064LJFOLD(XSTORE any any)
2065LJFOLDX(lj_opt_dse_xstore)
2066
2067LJFOLD(NEWREF any any) /* Treated like a store. */
2068LJFOLD(CALLS any any)
2069LJFOLD(CALLL any any) /* Safeguard fallback. */
2070LJFOLD(CALLXS any any)
2071LJFOLD(XBAR)
2072LJFOLD(RETF any any) /* Modifies BASE. */
2073LJFOLD(TNEW any any)
2074LJFOLD(TDUP any)
2075LJFOLD(CNEW any any)
2076LJFOLD(XSNEW any any)
2077LJFOLDX(lj_ir_emit)
2078
2079/* ------------------------------------------------------------------------ */
2080
2081/* Every entry in the generated hash table is a 32 bit pattern:
2082**
2083** xxxxxxxx iiiiiii lllllll rrrrrrrrrr
2084**
2085** xxxxxxxx = 8 bit index into fold function table
2086** iiiiiii = 7 bit folded instruction opcode
2087** lllllll = 7 bit left instruction opcode
2088** rrrrrrrrrr = 8 bit right instruction opcode or 10 bits from literal field
2089*/
2090
2091#include "lj_folddef.h"
2092
2093/* ------------------------------------------------------------------------ */
2094
2095/* Fold IR instruction. */
2096TRef LJ_FASTCALL lj_opt_fold(jit_State *J)
2097{
2098 uint32_t key, any;
2099 IRRef ref;
2100
2101 if (LJ_UNLIKELY((J->flags & JIT_F_OPT_MASK) != JIT_F_OPT_DEFAULT)) {
2102 lua_assert(((JIT_F_OPT_FOLD|JIT_F_OPT_FWD|JIT_F_OPT_CSE|JIT_F_OPT_DSE) |
2103 JIT_F_OPT_DEFAULT) == JIT_F_OPT_DEFAULT);
2104 /* Folding disabled? Chain to CSE, but not for loads/stores/allocs. */
2105 if (!(J->flags & JIT_F_OPT_FOLD) && irm_kind(lj_ir_mode[fins->o]) == IRM_N)
2106 return lj_opt_cse(J);
2107
2108 /* Forwarding or CSE disabled? Emit raw IR for loads, except for SLOAD. */
2109 if ((J->flags & (JIT_F_OPT_FWD|JIT_F_OPT_CSE)) !=
2110 (JIT_F_OPT_FWD|JIT_F_OPT_CSE) &&
2111 irm_kind(lj_ir_mode[fins->o]) == IRM_L && fins->o != IR_SLOAD)
2112 return lj_ir_emit(J);
2113
2114 /* DSE disabled? Emit raw IR for stores. */
2115 if (!(J->flags & JIT_F_OPT_DSE) && irm_kind(lj_ir_mode[fins->o]) == IRM_S)
2116 return lj_ir_emit(J);
2117 }
2118
2119 /* Fold engine start/retry point. */
2120retry:
2121 /* Construct key from opcode and operand opcodes (unless literal/none). */
2122 key = ((uint32_t)fins->o << 17);
2123 if (fins->op1 >= J->cur.nk) {
2124 key += (uint32_t)IR(fins->op1)->o << 10;
2125 *fleft = *IR(fins->op1);
2126 }
2127 if (fins->op2 >= J->cur.nk) {
2128 key += (uint32_t)IR(fins->op2)->o;
2129 *fright = *IR(fins->op2);
2130 } else {
2131 key += (fins->op2 & 0x3ffu); /* Literal mask. Must include IRCONV_*MASK. */
2132 }
2133
2134 /* Check for a match in order from most specific to least specific. */
2135 any = 0;
2136 for (;;) {
2137 uint32_t k = key | (any & 0x1ffff);
2138 uint32_t h = fold_hashkey(k);
2139 uint32_t fh = fold_hash[h]; /* Lookup key in semi-perfect hash table. */
2140 if ((fh & 0xffffff) == k || (fh = fold_hash[h+1], (fh & 0xffffff) == k)) {
2141 ref = (IRRef)tref_ref(fold_func[fh >> 24](J));
2142 if (ref != NEXTFOLD)
2143 break;
2144 }
2145 if (any == 0xfffff) /* Exhausted folding. Pass on to CSE. */
2146 return lj_opt_cse(J);
2147 any = (any | (any >> 10)) ^ 0xffc00;
2148 }
2149
2150 /* Return value processing, ordered by frequency. */
2151 if (LJ_LIKELY(ref >= MAX_FOLD))
2152 return TREF(ref, irt_t(IR(ref)->t));
2153 if (ref == RETRYFOLD)
2154 goto retry;
2155 if (ref == KINTFOLD)
2156 return lj_ir_kint(J, fins->i);
2157 if (ref == FAILFOLD)
2158 lj_trace_err(J, LJ_TRERR_GFAIL);
2159 lua_assert(ref == DROPFOLD);
2160 return REF_DROP;
2161}
2162
2163/* -- Common-Subexpression Elimination ------------------------------------ */
2164
2165/* CSE an IR instruction. This is very fast due to the skip-list chains. */
2166TRef LJ_FASTCALL lj_opt_cse(jit_State *J)
2167{
2168 /* Avoid narrow to wide store-to-load forwarding stall */
2169 IRRef2 op12 = (IRRef2)fins->op1 + ((IRRef2)fins->op2 << 16);
2170 IROp op = fins->o;
2171 if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) {
2172 /* Limited search for same operands in per-opcode chain. */
2173 IRRef ref = J->chain[op];
2174 IRRef lim = fins->op1;
2175 if (fins->op2 > lim) lim = fins->op2; /* Relies on lit < REF_BIAS. */
2176 while (ref > lim) {
2177 if (IR(ref)->op12 == op12)
2178 return TREF(ref, irt_t(IR(ref)->t)); /* Common subexpression found. */
2179 ref = IR(ref)->prev;
2180 }
2181 }
2182 /* Otherwise emit IR (inlined for speed). */
2183 {
2184 IRRef ref = lj_ir_nextins(J);
2185 IRIns *ir = IR(ref);
2186 ir->prev = J->chain[op];
2187 ir->op12 = op12;
2188 J->chain[op] = (IRRef1)ref;
2189 ir->o = fins->o;
2190 J->guardemit.irt |= fins->t.irt;
2191 return TREF(ref, irt_t((ir->t = fins->t)));
2192 }
2193}
2194
2195/* CSE with explicit search limit. */
2196TRef LJ_FASTCALL lj_opt_cselim(jit_State *J, IRRef lim)
2197{
2198 IRRef ref = J->chain[fins->o];
2199 IRRef2 op12 = (IRRef2)fins->op1 + ((IRRef2)fins->op2 << 16);
2200 while (ref > lim) {
2201 if (IR(ref)->op12 == op12)
2202 return ref;
2203 ref = IR(ref)->prev;
2204 }
2205 return lj_ir_emit(J);
2206}
2207
2208/* ------------------------------------------------------------------------ */
2209
2210#undef IR
2211#undef fins
2212#undef fleft
2213#undef fright
2214#undef knumleft
2215#undef knumright
2216#undef emitir
2217
2218#endif
diff --git a/libraries/luajit-2.0/src/lj_opt_loop.c b/libraries/luajit-2.0/src/lj_opt_loop.c
new file mode 100644
index 0000000..460297b
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_opt_loop.c
@@ -0,0 +1,429 @@
1/*
2** LOOP: Loop Optimizations.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_opt_loop_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12
13#include "lj_err.h"
14#include "lj_str.h"
15#include "lj_ir.h"
16#include "lj_jit.h"
17#include "lj_iropt.h"
18#include "lj_trace.h"
19#include "lj_snap.h"
20#include "lj_vm.h"
21
22/* Loop optimization:
23**
24** Traditional Loop-Invariant Code Motion (LICM) splits the instructions
25** of a loop into invariant and variant instructions. The invariant
26** instructions are hoisted out of the loop and only the variant
27** instructions remain inside the loop body.
28**
29** Unfortunately LICM is mostly useless for compiling dynamic languages.
30** The IR has many guards and most of the subsequent instructions are
31** control-dependent on them. The first non-hoistable guard would
32** effectively prevent hoisting of all subsequent instructions.
33**
34** That's why we use a special form of unrolling using copy-substitution,
35** combined with redundancy elimination:
36**
37** The recorded instruction stream is re-emitted to the compiler pipeline
38** with substituted operands. The substitution table is filled with the
39** refs returned by re-emitting each instruction. This can be done
40** on-the-fly, because the IR is in strict SSA form, where every ref is
41** defined before its use.
42**
43** This aproach generates two code sections, separated by the LOOP
44** instruction:
45**
46** 1. The recorded instructions form a kind of pre-roll for the loop. It
47** contains a mix of invariant and variant instructions and performs
48** exactly one loop iteration (but not necessarily the 1st iteration).
49**
50** 2. The loop body contains only the variant instructions and performs
51** all remaining loop iterations.
52**
53** On first sight that looks like a waste of space, because the variant
54** instructions are present twice. But the key insight is that the
55** pre-roll honors the control-dependencies for *both* the pre-roll itself
56** *and* the loop body!
57**
58** It also means one doesn't have to explicitly model control-dependencies
59** (which, BTW, wouldn't help LICM much). And it's much easier to
60** integrate sparse snapshotting with this approach.
61**
62** One of the nicest aspects of this approach is that all of the
63** optimizations of the compiler pipeline (FOLD, CSE, FWD, etc.) can be
64** reused with only minor restrictions (e.g. one should not fold
65** instructions across loop-carried dependencies).
66**
67** But in general all optimizations can be applied which only need to look
68** backwards into the generated instruction stream. At any point in time
69** during the copy-substitution process this contains both a static loop
70** iteration (the pre-roll) and a dynamic one (from the to-be-copied
71** instruction up to the end of the partial loop body).
72**
73** Since control-dependencies are implicitly kept, CSE also applies to all
74** kinds of guards. The major advantage is that all invariant guards can
75** be hoisted, too.
76**
77** Load/store forwarding works across loop iterations, too. This is
78** important if loop-carried dependencies are kept in upvalues or tables.
79** E.g. 'self.idx = self.idx + 1' deep down in some OO-style method may
80** become a forwarded loop-recurrence after inlining.
81**
82** Since the IR is in SSA form, loop-carried dependencies have to be
83** modeled with PHI instructions. The potential candidates for PHIs are
84** collected on-the-fly during copy-substitution. After eliminating the
85** redundant ones, PHI instructions are emitted *below* the loop body.
86**
87** Note that this departure from traditional SSA form doesn't change the
88** semantics of the PHI instructions themselves. But it greatly simplifies
89** on-the-fly generation of the IR and the machine code.
90*/
91
92/* Some local macros to save typing. Undef'd at the end. */
93#define IR(ref) (&J->cur.ir[(ref)])
94
95/* Pass IR on to next optimization in chain (FOLD). */
96#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
97
98/* Emit raw IR without passing through optimizations. */
99#define emitir_raw(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_ir_emit(J))
100
101/* -- PHI elimination ----------------------------------------------------- */
102
103/* Emit or eliminate collected PHIs. */
104static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi,
105 SnapNo onsnap)
106{
107 int passx = 0;
108 IRRef i, nslots;
109 IRRef invar = J->chain[IR_LOOP];
110 /* Pass #1: mark redundant and potentially redundant PHIs. */
111 for (i = 0; i < nphi; i++) {
112 IRRef lref = phi[i];
113 IRRef rref = subst[lref];
114 if (lref == rref || rref == REF_DROP) { /* Invariants are redundant. */
115 irt_setmark(IR(lref)->t);
116 } else if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) {
117 /* Quick check for simple recurrences failed, need pass2. */
118 irt_setmark(IR(lref)->t);
119 passx = 1;
120 }
121 }
122 /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */
123 if (passx) {
124 SnapNo s;
125 for (i = J->cur.nins-1; i > invar; i--) {
126 IRIns *ir = IR(i);
127 if (!irref_isk(ir->op2)) irt_clearmark(IR(ir->op2)->t);
128 if (!irref_isk(ir->op1)) {
129 irt_clearmark(IR(ir->op1)->t);
130 if (ir->op1 < invar &&
131 ir->o >= IR_CALLN && ir->o <= IR_CARG) { /* ORDER IR */
132 ir = IR(ir->op1);
133 while (ir->o == IR_CARG) {
134 if (!irref_isk(ir->op2)) irt_clearmark(IR(ir->op2)->t);
135 if (irref_isk(ir->op1)) break;
136 ir = IR(ir->op1);
137 irt_clearmark(ir->t);
138 }
139 }
140 }
141 }
142 for (s = J->cur.nsnap-1; s >= onsnap; s--) {
143 SnapShot *snap = &J->cur.snap[s];
144 SnapEntry *map = &J->cur.snapmap[snap->mapofs];
145 MSize n, nent = snap->nent;
146 for (n = 0; n < nent; n++) {
147 IRRef ref = snap_ref(map[n]);
148 if (!irref_isk(ref)) irt_clearmark(IR(ref)->t);
149 }
150 }
151 }
152 /* Pass #3: add PHIs for variant slots without a corresponding SLOAD. */
153 nslots = J->baseslot+J->maxslot;
154 for (i = 1; i < nslots; i++) {
155 IRRef ref = tref_ref(J->slot[i]);
156 while (!irref_isk(ref) && ref != subst[ref]) {
157 IRIns *ir = IR(ref);
158 irt_clearmark(ir->t); /* Unmark potential uses, too. */
159 if (irt_isphi(ir->t) || irt_ispri(ir->t))
160 break;
161 irt_setphi(ir->t);
162 if (nphi >= LJ_MAX_PHI)
163 lj_trace_err(J, LJ_TRERR_PHIOV);
164 phi[nphi++] = (IRRef1)ref;
165 ref = subst[ref];
166 if (ref > invar)
167 break;
168 }
169 }
170 /* Pass #4: propagate non-redundant PHIs. */
171 while (passx) {
172 passx = 0;
173 for (i = 0; i < nphi; i++) {
174 IRRef lref = phi[i];
175 IRIns *ir = IR(lref);
176 if (!irt_ismarked(ir->t)) { /* Propagate only from unmarked PHIs. */
177 IRRef rref = subst[lref];
178 if (lref == rref) { /* Mark redundant PHI. */
179 irt_setmark(ir->t);
180 } else {
181 IRIns *irr = IR(rref);
182 if (irt_ismarked(irr->t)) { /* Right ref points to other PHI? */
183 irt_clearmark(irr->t); /* Mark that PHI as non-redundant. */
184 passx = 1; /* Retry. */
185 }
186 }
187 }
188 }
189 }
190 /* Pass #5: emit PHI instructions or eliminate PHIs. */
191 for (i = 0; i < nphi; i++) {
192 IRRef lref = phi[i];
193 IRIns *ir = IR(lref);
194 if (!irt_ismarked(ir->t)) { /* Emit PHI if not marked. */
195 IRRef rref = subst[lref];
196 if (rref > invar)
197 irt_setphi(IR(rref)->t);
198 emitir_raw(IRT(IR_PHI, irt_type(ir->t)), lref, rref);
199 } else { /* Otherwise eliminate PHI. */
200 irt_clearmark(ir->t);
201 irt_clearphi(ir->t);
202 }
203 }
204}
205
206/* -- Loop unrolling using copy-substitution ------------------------------ */
207
208/* Copy-substitute snapshot. */
209static void loop_subst_snap(jit_State *J, SnapShot *osnap,
210 SnapEntry *loopmap, IRRef1 *subst)
211{
212 SnapEntry *nmap, *omap = &J->cur.snapmap[osnap->mapofs];
213 SnapEntry *nextmap = &J->cur.snapmap[snap_nextofs(&J->cur, osnap)];
214 MSize nmapofs;
215 MSize on, ln, nn, onent = osnap->nent;
216 BCReg nslots = osnap->nslots;
217 SnapShot *snap = &J->cur.snap[J->cur.nsnap];
218 if (irt_isguard(J->guardemit)) { /* Guard inbetween? */
219 nmapofs = J->cur.nsnapmap;
220 J->cur.nsnap++; /* Add new snapshot. */
221 } else { /* Otherwise overwrite previous snapshot. */
222 snap--;
223 nmapofs = snap->mapofs;
224 }
225 J->guardemit.irt = 0;
226 /* Setup new snapshot. */
227 snap->mapofs = (uint16_t)nmapofs;
228 snap->ref = (IRRef1)J->cur.nins;
229 snap->nslots = nslots;
230 snap->topslot = osnap->topslot;
231 snap->count = 0;
232 nmap = &J->cur.snapmap[nmapofs];
233 /* Substitute snapshot slots. */
234 on = ln = nn = 0;
235 while (on < onent) {
236 SnapEntry osn = omap[on], lsn = loopmap[ln];
237 if (snap_slot(lsn) < snap_slot(osn)) { /* Copy slot from loop map. */
238 nmap[nn++] = lsn;
239 ln++;
240 } else { /* Copy substituted slot from snapshot map. */
241 if (snap_slot(lsn) == snap_slot(osn)) ln++; /* Shadowed loop slot. */
242 if (!irref_isk(snap_ref(osn)))
243 osn = snap_setref(osn, subst[snap_ref(osn)]);
244 nmap[nn++] = osn;
245 on++;
246 }
247 }
248 while (snap_slot(loopmap[ln]) < nslots) /* Copy remaining loop slots. */
249 nmap[nn++] = loopmap[ln++];
250 snap->nent = (uint8_t)nn;
251 omap += onent;
252 nmap += nn;
253 while (omap < nextmap) /* Copy PC + frame links. */
254 *nmap++ = *omap++;
255 J->cur.nsnapmap = (uint16_t)(nmap - J->cur.snapmap);
256}
257
258/* Unroll loop. */
259static void loop_unroll(jit_State *J)
260{
261 IRRef1 phi[LJ_MAX_PHI];
262 uint32_t nphi = 0;
263 IRRef1 *subst;
264 SnapNo onsnap;
265 SnapShot *osnap, *loopsnap;
266 SnapEntry *loopmap, *psentinel;
267 IRRef ins, invar;
268
269 /* Use temp buffer for substitution table.
270 ** Only non-constant refs in [REF_BIAS,invar) are valid indexes.
271 ** Caveat: don't call into the VM or run the GC or the buffer may be gone.
272 */
273 invar = J->cur.nins;
274 subst = (IRRef1 *)lj_str_needbuf(J->L, &G(J->L)->tmpbuf,
275 (invar-REF_BIAS)*sizeof(IRRef1)) - REF_BIAS;
276 subst[REF_BASE] = REF_BASE;
277
278 /* LOOP separates the pre-roll from the loop body. */
279 emitir_raw(IRTG(IR_LOOP, IRT_NIL), 0, 0);
280
281 /* Grow snapshot buffer and map for copy-substituted snapshots.
282 ** Need up to twice the number of snapshots minus #0 and loop snapshot.
283 ** Need up to twice the number of entries plus fallback substitutions
284 ** from the loop snapshot entries for each new snapshot.
285 ** Caveat: both calls may reallocate J->cur.snap and J->cur.snapmap!
286 */
287 onsnap = J->cur.nsnap;
288 lj_snap_grow_buf(J, 2*onsnap-2);
289 lj_snap_grow_map(J, J->cur.nsnapmap*2+(onsnap-2)*J->cur.snap[onsnap-1].nent);
290
291 /* The loop snapshot is used for fallback substitutions. */
292 loopsnap = &J->cur.snap[onsnap-1];
293 loopmap = &J->cur.snapmap[loopsnap->mapofs];
294 /* The PC of snapshot #0 and the loop snapshot must match. */
295 psentinel = &loopmap[loopsnap->nent];
296 lua_assert(*psentinel == J->cur.snapmap[J->cur.snap[0].nent]);
297 *psentinel = SNAP(255, 0, 0); /* Replace PC with temporary sentinel. */
298
299 /* Start substitution with snapshot #1 (#0 is empty for root traces). */
300 osnap = &J->cur.snap[1];
301
302 /* Copy and substitute all recorded instructions and snapshots. */
303 for (ins = REF_FIRST; ins < invar; ins++) {
304 IRIns *ir;
305 IRRef op1, op2;
306
307 if (ins >= osnap->ref) /* Instruction belongs to next snapshot? */
308 loop_subst_snap(J, osnap++, loopmap, subst); /* Copy-substitute it. */
309
310 /* Substitute instruction operands. */
311 ir = IR(ins);
312 op1 = ir->op1;
313 if (!irref_isk(op1)) op1 = subst[op1];
314 op2 = ir->op2;
315 if (!irref_isk(op2)) op2 = subst[op2];
316 if (irm_kind(lj_ir_mode[ir->o]) == IRM_N &&
317 op1 == ir->op1 && op2 == ir->op2) { /* Regular invariant ins? */
318 subst[ins] = (IRRef1)ins; /* Shortcut. */
319 } else {
320 /* Re-emit substituted instruction to the FOLD/CSE/etc. pipeline. */
321 IRType1 t = ir->t; /* Get this first, since emitir may invalidate ir. */
322 IRRef ref = tref_ref(emitir(ir->ot & ~IRT_ISPHI, op1, op2));
323 subst[ins] = (IRRef1)ref;
324 if (ref != ins && ref < invar) { /* Loop-carried dependency? */
325 IRIns *irr = IR(ref);
326 /* Potential PHI? */
327 if (!irref_isk(ref) && !irt_isphi(irr->t) && !irt_ispri(irr->t)) {
328 irt_setphi(irr->t);
329 if (nphi >= LJ_MAX_PHI)
330 lj_trace_err(J, LJ_TRERR_PHIOV);
331 phi[nphi++] = (IRRef1)ref;
332 }
333 /* Check all loop-carried dependencies for type instability. */
334 if (!irt_sametype(t, irr->t)) {
335 if (irt_isinteger(t) && irt_isinteger(irr->t))
336 continue;
337 else if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num. */
338 ref = tref_ref(emitir(IRTN(IR_CONV), ref, IRCONV_NUM_INT));
339 else if (irt_isnum(irr->t) && irt_isinteger(t)) /* Fix num->int. */
340 ref = tref_ref(emitir(IRTGI(IR_CONV), ref,
341 IRCONV_INT_NUM|IRCONV_CHECK));
342 else
343 lj_trace_err(J, LJ_TRERR_TYPEINS);
344 subst[ins] = (IRRef1)ref;
345 /* May need a PHI for the CONV, too. */
346 irr = IR(ref);
347 if (ref < invar && !irref_isk(ref) && !irt_isphi(irr->t)) {
348 irt_setphi(irr->t);
349 if (nphi >= LJ_MAX_PHI)
350 lj_trace_err(J, LJ_TRERR_PHIOV);
351 phi[nphi++] = (IRRef1)ref;
352 }
353 }
354 }
355 }
356 }
357 if (!irt_isguard(J->guardemit)) /* Drop redundant snapshot. */
358 J->cur.nsnapmap = (uint16_t)J->cur.snap[--J->cur.nsnap].mapofs;
359 lua_assert(J->cur.nsnapmap <= J->sizesnapmap);
360 *psentinel = J->cur.snapmap[J->cur.snap[0].nent]; /* Restore PC. */
361
362 loop_emit_phi(J, subst, phi, nphi, onsnap);
363}
364
365/* Undo any partial changes made by the loop optimization. */
366static void loop_undo(jit_State *J, IRRef ins, SnapNo nsnap, MSize nsnapmap)
367{
368 ptrdiff_t i;
369 SnapShot *snap = &J->cur.snap[nsnap-1];
370 SnapEntry *map = J->cur.snapmap;
371 map[snap->mapofs + snap->nent] = map[J->cur.snap[0].nent]; /* Restore PC. */
372 J->cur.nsnapmap = (uint16_t)nsnapmap;
373 J->cur.nsnap = nsnap;
374 J->guardemit.irt = 0;
375 lj_ir_rollback(J, ins);
376 for (i = 0; i < BPROP_SLOTS; i++) { /* Remove backprop. cache entries. */
377 BPropEntry *bp = &J->bpropcache[i];
378 if (bp->val >= ins)
379 bp->key = 0;
380 }
381 for (ins--; ins >= REF_FIRST; ins--) { /* Remove flags. */
382 IRIns *ir = IR(ins);
383 irt_clearphi(ir->t);
384 irt_clearmark(ir->t);
385 }
386}
387
388/* Protected callback for loop optimization. */
389static TValue *cploop_opt(lua_State *L, lua_CFunction dummy, void *ud)
390{
391 UNUSED(L); UNUSED(dummy);
392 loop_unroll((jit_State *)ud);
393 return NULL;
394}
395
396/* Loop optimization. */
397int lj_opt_loop(jit_State *J)
398{
399 IRRef nins = J->cur.nins;
400 SnapNo nsnap = J->cur.nsnap;
401 MSize nsnapmap = J->cur.nsnapmap;
402 int errcode = lj_vm_cpcall(J->L, NULL, J, cploop_opt);
403 if (LJ_UNLIKELY(errcode)) {
404 lua_State *L = J->L;
405 if (errcode == LUA_ERRRUN && tvisnumber(L->top-1)) { /* Trace error? */
406 int32_t e = numberVint(L->top-1);
407 switch ((TraceError)e) {
408 case LJ_TRERR_TYPEINS: /* Type instability. */
409 case LJ_TRERR_GFAIL: /* Guard would always fail. */
410 /* Unrolling via recording fixes many cases, e.g. a flipped boolean. */
411 if (--J->instunroll < 0) /* But do not unroll forever. */
412 break;
413 L->top--; /* Remove error object. */
414 loop_undo(J, nins, nsnap, nsnapmap);
415 return 1; /* Loop optimization failed, continue recording. */
416 default:
417 break;
418 }
419 }
420 lj_err_throw(L, errcode); /* Propagate all other errors. */
421 }
422 return 0; /* Loop optimization is ok. */
423}
424
425#undef IR
426#undef emitir
427#undef emitir_raw
428
429#endif
diff --git a/libraries/luajit-2.0/src/lj_opt_mem.c b/libraries/luajit-2.0/src/lj_opt_mem.c
new file mode 100644
index 0000000..a90d097
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_opt_mem.c
@@ -0,0 +1,861 @@
1/*
2** Memory access optimizations.
3** AA: Alias Analysis using high-level semantic disambiguation.
4** FWD: Load Forwarding (L2L) + Store Forwarding (S2L).
5** DSE: Dead-Store Elimination.
6** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
7*/
8
9#define lj_opt_mem_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13
14#if LJ_HASJIT
15
16#include "lj_tab.h"
17#include "lj_ir.h"
18#include "lj_jit.h"
19#include "lj_iropt.h"
20
21/* Some local macros to save typing. Undef'd at the end. */
22#define IR(ref) (&J->cur.ir[(ref)])
23#define fins (&J->fold.ins)
24#define fright (&J->fold.right)
25
26/*
27** Caveat #1: return value is not always a TRef -- only use with tref_ref().
28** Caveat #2: FWD relies on active CSE for xREF operands -- see lj_opt_fold().
29*/
30
31/* Return values from alias analysis. */
32typedef enum {
33 ALIAS_NO, /* The two refs CANNOT alias (exact). */
34 ALIAS_MAY, /* The two refs MAY alias (inexact). */
35 ALIAS_MUST /* The two refs MUST alias (exact). */
36} AliasRet;
37
38/* -- ALOAD/HLOAD forwarding and ASTORE/HSTORE elimination ---------------- */
39
40/* Simplified escape analysis: check for intervening stores. */
41static AliasRet aa_escape(jit_State *J, IRIns *ir, IRIns *stop)
42{
43 IRRef ref = (IRRef)(ir - J->cur.ir); /* The ref that might be stored. */
44 for (ir++; ir < stop; ir++)
45 if (ir->op2 == ref &&
46 (ir->o == IR_ASTORE || ir->o == IR_HSTORE ||
47 ir->o == IR_USTORE || ir->o == IR_FSTORE))
48 return ALIAS_MAY; /* Reference was stored and might alias. */
49 return ALIAS_NO; /* Reference was not stored. */
50}
51
52/* Alias analysis for two different table references. */
53static AliasRet aa_table(jit_State *J, IRRef ta, IRRef tb)
54{
55 IRIns *taba = IR(ta), *tabb = IR(tb);
56 int newa, newb;
57 lua_assert(ta != tb);
58 lua_assert(irt_istab(taba->t) && irt_istab(tabb->t));
59 /* Disambiguate new allocations. */
60 newa = (taba->o == IR_TNEW || taba->o == IR_TDUP);
61 newb = (tabb->o == IR_TNEW || tabb->o == IR_TDUP);
62 if (newa && newb)
63 return ALIAS_NO; /* Two different allocations never alias. */
64 if (newb) { /* At least one allocation? */
65 IRIns *tmp = taba; taba = tabb; tabb = tmp;
66 } else if (!newa) {
67 return ALIAS_MAY; /* Anything else: we just don't know. */
68 }
69 return aa_escape(J, taba, tabb);
70}
71
72/* Alias analysis for array and hash access using key-based disambiguation. */
73static AliasRet aa_ahref(jit_State *J, IRIns *refa, IRIns *refb)
74{
75 IRRef ka = refa->op2;
76 IRRef kb = refb->op2;
77 IRIns *keya, *keyb;
78 IRRef ta, tb;
79 if (refa == refb)
80 return ALIAS_MUST; /* Shortcut for same refs. */
81 keya = IR(ka);
82 if (keya->o == IR_KSLOT) { ka = keya->op1; keya = IR(ka); }
83 keyb = IR(kb);
84 if (keyb->o == IR_KSLOT) { kb = keyb->op1; keyb = IR(kb); }
85 ta = (refa->o==IR_HREFK || refa->o==IR_AREF) ? IR(refa->op1)->op1 : refa->op1;
86 tb = (refb->o==IR_HREFK || refb->o==IR_AREF) ? IR(refb->op1)->op1 : refb->op1;
87 if (ka == kb) {
88 /* Same key. Check for same table with different ref (NEWREF vs. HREF). */
89 if (ta == tb)
90 return ALIAS_MUST; /* Same key, same table. */
91 else
92 return aa_table(J, ta, tb); /* Same key, possibly different table. */
93 }
94 if (irref_isk(ka) && irref_isk(kb))
95 return ALIAS_NO; /* Different constant keys. */
96 if (refa->o == IR_AREF) {
97 /* Disambiguate array references based on index arithmetic. */
98 int32_t ofsa = 0, ofsb = 0;
99 IRRef basea = ka, baseb = kb;
100 lua_assert(refb->o == IR_AREF);
101 /* Gather base and offset from t[base] or t[base+-ofs]. */
102 if (keya->o == IR_ADD && irref_isk(keya->op2)) {
103 basea = keya->op1;
104 ofsa = IR(keya->op2)->i;
105 if (basea == kb && ofsa != 0)
106 return ALIAS_NO; /* t[base+-ofs] vs. t[base]. */
107 }
108 if (keyb->o == IR_ADD && irref_isk(keyb->op2)) {
109 baseb = keyb->op1;
110 ofsb = IR(keyb->op2)->i;
111 if (ka == baseb && ofsb != 0)
112 return ALIAS_NO; /* t[base] vs. t[base+-ofs]. */
113 }
114 if (basea == baseb && ofsa != ofsb)
115 return ALIAS_NO; /* t[base+-o1] vs. t[base+-o2] and o1 != o2. */
116 } else {
117 /* Disambiguate hash references based on the type of their keys. */
118 lua_assert((refa->o==IR_HREF || refa->o==IR_HREFK || refa->o==IR_NEWREF) &&
119 (refb->o==IR_HREF || refb->o==IR_HREFK || refb->o==IR_NEWREF));
120 if (!irt_sametype(keya->t, keyb->t))
121 return ALIAS_NO; /* Different key types. */
122 }
123 if (ta == tb)
124 return ALIAS_MAY; /* Same table, cannot disambiguate keys. */
125 else
126 return aa_table(J, ta, tb); /* Try to disambiguate tables. */
127}
128
129/* Array and hash load forwarding. */
130static TRef fwd_ahload(jit_State *J, IRRef xref)
131{
132 IRIns *xr = IR(xref);
133 IRRef lim = xref; /* Search limit. */
134 IRRef ref;
135
136 /* Search for conflicting stores. */
137 ref = J->chain[fins->o+IRDELTA_L2S];
138 while (ref > xref) {
139 IRIns *store = IR(ref);
140 switch (aa_ahref(J, xr, IR(store->op1))) {
141 case ALIAS_NO: break; /* Continue searching. */
142 case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */
143 case ALIAS_MUST: return store->op2; /* Store forwarding. */
144 }
145 ref = store->prev;
146 }
147
148 /* No conflicting store (yet): const-fold loads from allocations. */
149 {
150 IRIns *ir = (xr->o == IR_HREFK || xr->o == IR_AREF) ? IR(xr->op1) : xr;
151 IRRef tab = ir->op1;
152 ir = IR(tab);
153 if (ir->o == IR_TNEW || (ir->o == IR_TDUP && irref_isk(xr->op2))) {
154 /* A NEWREF with a number key may end up pointing to the array part.
155 ** But it's referenced from HSTORE and not found in the ASTORE chain.
156 ** For now simply consider this a conflict without forwarding anything.
157 */
158 if (xr->o == IR_AREF) {
159 IRRef ref2 = J->chain[IR_NEWREF];
160 while (ref2 > tab) {
161 IRIns *newref = IR(ref2);
162 if (irt_isnum(IR(newref->op2)->t))
163 goto cselim;
164 ref2 = newref->prev;
165 }
166 }
167 /* NEWREF inhibits CSE for HREF, and dependent FLOADs from HREFK/AREF.
168 ** But the above search for conflicting stores was limited by xref.
169 ** So continue searching, limited by the TNEW/TDUP. Store forwarding
170 ** is ok, too. A conflict does NOT limit the search for a matching load.
171 */
172 while (ref > tab) {
173 IRIns *store = IR(ref);
174 switch (aa_ahref(J, xr, IR(store->op1))) {
175 case ALIAS_NO: break; /* Continue searching. */
176 case ALIAS_MAY: goto cselim; /* Conflicting store. */
177 case ALIAS_MUST: return store->op2; /* Store forwarding. */
178 }
179 ref = store->prev;
180 }
181 lua_assert(ir->o != IR_TNEW || irt_isnil(fins->t));
182 if (irt_ispri(fins->t)) {
183 return TREF_PRI(irt_type(fins->t));
184 } else if (irt_isnum(fins->t) || irt_isstr(fins->t)) {
185 TValue keyv;
186 cTValue *tv;
187 IRIns *key = IR(xr->op2);
188 if (key->o == IR_KSLOT) key = IR(key->op1);
189 lj_ir_kvalue(J->L, &keyv, key);
190 tv = lj_tab_get(J->L, ir_ktab(IR(ir->op1)), &keyv);
191 lua_assert(itype2irt(tv) == irt_type(fins->t));
192 if (irt_isnum(fins->t))
193 return lj_ir_knum_u64(J, tv->u64);
194 else
195 return lj_ir_kstr(J, strV(tv));
196 }
197 /* Othwerwise: don't intern as a constant. */
198 }
199 }
200
201cselim:
202 /* Try to find a matching load. Below the conflicting store, if any. */
203 ref = J->chain[fins->o];
204 while (ref > lim) {
205 IRIns *load = IR(ref);
206 if (load->op1 == xref)
207 return ref; /* Load forwarding. */
208 ref = load->prev;
209 }
210 return 0; /* Conflict or no match. */
211}
212
213/* Reassociate ALOAD across PHIs to handle t[i-1] forwarding case. */
214static TRef fwd_aload_reassoc(jit_State *J)
215{
216 IRIns *irx = IR(fins->op1);
217 IRIns *key = IR(irx->op2);
218 if (key->o == IR_ADD && irref_isk(key->op2)) {
219 IRIns *add2 = IR(key->op1);
220 if (add2->o == IR_ADD && irref_isk(add2->op2) &&
221 IR(key->op2)->i == -IR(add2->op2)->i) {
222 IRRef ref = J->chain[IR_AREF];
223 IRRef lim = add2->op1;
224 if (irx->op1 > lim) lim = irx->op1;
225 while (ref > lim) {
226 IRIns *ir = IR(ref);
227 if (ir->op1 == irx->op1 && ir->op2 == add2->op1)
228 return fwd_ahload(J, ref);
229 ref = ir->prev;
230 }
231 }
232 }
233 return 0;
234}
235
236/* ALOAD forwarding. */
237TRef LJ_FASTCALL lj_opt_fwd_aload(jit_State *J)
238{
239 IRRef ref;
240 if ((ref = fwd_ahload(J, fins->op1)) ||
241 (ref = fwd_aload_reassoc(J)))
242 return ref;
243 return EMITFOLD;
244}
245
246/* HLOAD forwarding. */
247TRef LJ_FASTCALL lj_opt_fwd_hload(jit_State *J)
248{
249 IRRef ref = fwd_ahload(J, fins->op1);
250 if (ref)
251 return ref;
252 return EMITFOLD;
253}
254
255/* Check whether HREF of TNEW/TDUP can be folded to niltv. */
256int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J)
257{
258 IRRef lim = fins->op1; /* Search limit. */
259 IRRef ref;
260
261 /* The key for an ASTORE may end up in the hash part after a NEWREF. */
262 if (irt_isnum(fright->t) && J->chain[IR_NEWREF] > lim) {
263 ref = J->chain[IR_ASTORE];
264 while (ref > lim) {
265 if (ref < J->chain[IR_NEWREF])
266 return 0; /* Conflict. */
267 ref = IR(ref)->prev;
268 }
269 }
270
271 /* Search for conflicting stores. */
272 ref = J->chain[IR_HSTORE];
273 while (ref > lim) {
274 IRIns *store = IR(ref);
275 if (aa_ahref(J, fins, IR(store->op1)) != ALIAS_NO)
276 return 0; /* Conflict. */
277 ref = store->prev;
278 }
279
280 return 1; /* No conflict. Can fold to niltv. */
281}
282
283/* Check whether there's no aliasing NEWREF for the left operand. */
284int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim)
285{
286 IRRef ta = fins->op1;
287 IRRef ref = J->chain[IR_NEWREF];
288 while (ref > lim) {
289 IRIns *newref = IR(ref);
290 if (ta == newref->op1 || aa_table(J, ta, newref->op1) != ALIAS_NO)
291 return 0; /* Conflict. */
292 ref = newref->prev;
293 }
294 return 1; /* No conflict. Can safely FOLD/CSE. */
295}
296
297/* ASTORE/HSTORE elimination. */
298TRef LJ_FASTCALL lj_opt_dse_ahstore(jit_State *J)
299{
300 IRRef xref = fins->op1; /* xREF reference. */
301 IRRef val = fins->op2; /* Stored value reference. */
302 IRIns *xr = IR(xref);
303 IRRef1 *refp = &J->chain[fins->o];
304 IRRef ref = *refp;
305 while (ref > xref) { /* Search for redundant or conflicting stores. */
306 IRIns *store = IR(ref);
307 switch (aa_ahref(J, xr, IR(store->op1))) {
308 case ALIAS_NO:
309 break; /* Continue searching. */
310 case ALIAS_MAY: /* Store to MAYBE the same location. */
311 if (store->op2 != val) /* Conflict if the value is different. */
312 goto doemit;
313 break; /* Otherwise continue searching. */
314 case ALIAS_MUST: /* Store to the same location. */
315 if (store->op2 == val) /* Same value: drop the new store. */
316 return DROPFOLD;
317 /* Different value: try to eliminate the redundant store. */
318 if (ref > J->chain[IR_LOOP]) { /* Quick check to avoid crossing LOOP. */
319 IRIns *ir;
320 /* Check for any intervening guards (includes conflicting loads). */
321 for (ir = IR(J->cur.nins-1); ir > store; ir--)
322 if (irt_isguard(ir->t))
323 goto doemit; /* No elimination possible. */
324 /* Remove redundant store from chain and replace with NOP. */
325 *refp = store->prev;
326 store->o = IR_NOP;
327 store->t.irt = IRT_NIL;
328 store->op1 = store->op2 = 0;
329 store->prev = 0;
330 /* Now emit the new store instead. */
331 }
332 goto doemit;
333 }
334 ref = *(refp = &store->prev);
335 }
336doemit:
337 return EMITFOLD; /* Otherwise we have a conflict or simply no match. */
338}
339
340/* -- ULOAD forwarding ---------------------------------------------------- */
341
342/* The current alias analysis for upvalues is very simplistic. It only
343** disambiguates between the unique upvalues of the same function.
344** This is good enough for now, since most upvalues are read-only.
345**
346** A more precise analysis would be feasible with the help of the parser:
347** generate a unique key for every upvalue, even across all prototypes.
348** Lacking a realistic use-case, it's unclear whether this is beneficial.
349*/
350static AliasRet aa_uref(IRIns *refa, IRIns *refb)
351{
352 if (refa->o != refb->o)
353 return ALIAS_NO; /* Different UREFx type. */
354 if (refa->op1 == refb->op1) { /* Same function. */
355 if (refa->op2 == refb->op2)
356 return ALIAS_MUST; /* Same function, same upvalue idx. */
357 else
358 return ALIAS_NO; /* Same function, different upvalue idx. */
359 } else { /* Different functions, check disambiguation hash values. */
360 if (((refa->op2 ^ refb->op2) & 0xff))
361 return ALIAS_NO; /* Upvalues with different hash values cannot alias. */
362 else
363 return ALIAS_MAY; /* No conclusion can be drawn for same hash value. */
364 }
365}
366
367/* ULOAD forwarding. */
368TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J)
369{
370 IRRef uref = fins->op1;
371 IRRef lim = uref; /* Search limit. */
372 IRIns *xr = IR(uref);
373 IRRef ref;
374
375 /* Search for conflicting stores. */
376 ref = J->chain[IR_USTORE];
377 while (ref > uref) {
378 IRIns *store = IR(ref);
379 switch (aa_uref(xr, IR(store->op1))) {
380 case ALIAS_NO: break; /* Continue searching. */
381 case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */
382 case ALIAS_MUST: return store->op2; /* Store forwarding. */
383 }
384 ref = store->prev;
385 }
386
387cselim:
388 /* Try to find a matching load. Below the conflicting store, if any. */
389 return lj_opt_cselim(J, lim);
390}
391
392/* USTORE elimination. */
393TRef LJ_FASTCALL lj_opt_dse_ustore(jit_State *J)
394{
395 IRRef xref = fins->op1; /* xREF reference. */
396 IRRef val = fins->op2; /* Stored value reference. */
397 IRIns *xr = IR(xref);
398 IRRef1 *refp = &J->chain[IR_USTORE];
399 IRRef ref = *refp;
400 while (ref > xref) { /* Search for redundant or conflicting stores. */
401 IRIns *store = IR(ref);
402 switch (aa_uref(xr, IR(store->op1))) {
403 case ALIAS_NO:
404 break; /* Continue searching. */
405 case ALIAS_MAY: /* Store to MAYBE the same location. */
406 if (store->op2 != val) /* Conflict if the value is different. */
407 goto doemit;
408 break; /* Otherwise continue searching. */
409 case ALIAS_MUST: /* Store to the same location. */
410 if (store->op2 == val) /* Same value: drop the new store. */
411 return DROPFOLD;
412 /* Different value: try to eliminate the redundant store. */
413 if (ref > J->chain[IR_LOOP]) { /* Quick check to avoid crossing LOOP. */
414 IRIns *ir;
415 /* Check for any intervening guards (includes conflicting loads). */
416 for (ir = IR(J->cur.nins-1); ir > store; ir--)
417 if (irt_isguard(ir->t))
418 goto doemit; /* No elimination possible. */
419 /* Remove redundant store from chain and replace with NOP. */
420 *refp = store->prev;
421 store->o = IR_NOP;
422 store->t.irt = IRT_NIL;
423 store->op1 = store->op2 = 0;
424 store->prev = 0;
425 /* Now emit the new store instead. */
426 }
427 goto doemit;
428 }
429 ref = *(refp = &store->prev);
430 }
431doemit:
432 return EMITFOLD; /* Otherwise we have a conflict or simply no match. */
433}
434
435/* -- FLOAD forwarding and FSTORE elimination ----------------------------- */
436
437/* Alias analysis for field access.
438** Field loads are cheap and field stores are rare.
439** Simple disambiguation based on field types is good enough.
440*/
441static AliasRet aa_fref(jit_State *J, IRIns *refa, IRIns *refb)
442{
443 if (refa->op2 != refb->op2)
444 return ALIAS_NO; /* Different fields. */
445 if (refa->op1 == refb->op1)
446 return ALIAS_MUST; /* Same field, same object. */
447 else if (refa->op2 >= IRFL_TAB_META && refa->op2 <= IRFL_TAB_NOMM)
448 return aa_table(J, refa->op1, refb->op1); /* Disambiguate tables. */
449 else
450 return ALIAS_MAY; /* Same field, possibly different object. */
451}
452
453/* Only the loads for mutable fields end up here (see FOLD). */
454TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J)
455{
456 IRRef oref = fins->op1; /* Object reference. */
457 IRRef fid = fins->op2; /* Field ID. */
458 IRRef lim = oref; /* Search limit. */
459 IRRef ref;
460
461 /* Search for conflicting stores. */
462 ref = J->chain[IR_FSTORE];
463 while (ref > oref) {
464 IRIns *store = IR(ref);
465 switch (aa_fref(J, fins, IR(store->op1))) {
466 case ALIAS_NO: break; /* Continue searching. */
467 case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */
468 case ALIAS_MUST: return store->op2; /* Store forwarding. */
469 }
470 ref = store->prev;
471 }
472
473 /* No conflicting store: const-fold field loads from allocations. */
474 if (fid == IRFL_TAB_META) {
475 IRIns *ir = IR(oref);
476 if (ir->o == IR_TNEW || ir->o == IR_TDUP)
477 return lj_ir_knull(J, IRT_TAB);
478 }
479
480cselim:
481 /* Try to find a matching load. Below the conflicting store, if any. */
482 return lj_opt_cselim(J, lim);
483}
484
485/* FSTORE elimination. */
486TRef LJ_FASTCALL lj_opt_dse_fstore(jit_State *J)
487{
488 IRRef fref = fins->op1; /* FREF reference. */
489 IRRef val = fins->op2; /* Stored value reference. */
490 IRIns *xr = IR(fref);
491 IRRef1 *refp = &J->chain[IR_FSTORE];
492 IRRef ref = *refp;
493 while (ref > fref) { /* Search for redundant or conflicting stores. */
494 IRIns *store = IR(ref);
495 switch (aa_fref(J, xr, IR(store->op1))) {
496 case ALIAS_NO:
497 break; /* Continue searching. */
498 case ALIAS_MAY:
499 if (store->op2 != val) /* Conflict if the value is different. */
500 goto doemit;
501 break; /* Otherwise continue searching. */
502 case ALIAS_MUST:
503 if (store->op2 == val) /* Same value: drop the new store. */
504 return DROPFOLD;
505 /* Different value: try to eliminate the redundant store. */
506 if (ref > J->chain[IR_LOOP]) { /* Quick check to avoid crossing LOOP. */
507 IRIns *ir;
508 /* Check for any intervening guards or conflicting loads. */
509 for (ir = IR(J->cur.nins-1); ir > store; ir--)
510 if (irt_isguard(ir->t) || (ir->o == IR_FLOAD && ir->op2 == xr->op2))
511 goto doemit; /* No elimination possible. */
512 /* Remove redundant store from chain and replace with NOP. */
513 *refp = store->prev;
514 store->o = IR_NOP;
515 store->t.irt = IRT_NIL;
516 store->op1 = store->op2 = 0;
517 store->prev = 0;
518 /* Now emit the new store instead. */
519 }
520 goto doemit;
521 }
522 ref = *(refp = &store->prev);
523 }
524doemit:
525 return EMITFOLD; /* Otherwise we have a conflict or simply no match. */
526}
527
528/* -- XLOAD forwarding and XSTORE elimination ----------------------------- */
529
530/* Find cdata allocation for a reference (if any). */
531static IRIns *aa_findcnew(jit_State *J, IRIns *ir)
532{
533 while (ir->o == IR_ADD) {
534 if (!irref_isk(ir->op1)) {
535 IRIns *ir1 = aa_findcnew(J, IR(ir->op1)); /* Left-recursion. */
536 if (ir1) return ir1;
537 }
538 if (irref_isk(ir->op2)) return NULL;
539 ir = IR(ir->op2); /* Flatten right-recursion. */
540 }
541 return ir->o == IR_CNEW ? ir : NULL;
542}
543
544/* Alias analysis for two cdata allocations. */
545static AliasRet aa_cnew(jit_State *J, IRIns *refa, IRIns *refb)
546{
547 IRIns *cnewa = aa_findcnew(J, refa);
548 IRIns *cnewb = aa_findcnew(J, refb);
549 if (cnewa == cnewb)
550 return ALIAS_MAY; /* Same allocation or neither is an allocation. */
551 if (cnewa && cnewb)
552 return ALIAS_NO; /* Two different allocations never alias. */
553 if (cnewb) { cnewa = cnewb; refb = refa; }
554 return aa_escape(J, cnewa, refb);
555}
556
557/* Alias analysis for XLOAD/XSTORE. */
558static AliasRet aa_xref(jit_State *J, IRIns *refa, IRIns *xa, IRIns *xb)
559{
560 ptrdiff_t ofsa = 0, ofsb = 0;
561 IRIns *refb = IR(xb->op1);
562 IRIns *basea = refa, *baseb = refb;
563 /* This implements (very) strict aliasing rules.
564 ** Different types do NOT alias, except for differences in signedness.
565 ** NYI: this also prevents type punning through unions.
566 */
567 if (irt_sametype(xa->t, xb->t)) {
568 if (refa == refb)
569 return ALIAS_MUST; /* Shortcut for same refs with identical type. */
570 } else if (!(irt_typerange(xa->t, IRT_I8, IRT_U64) &&
571 ((xa->t.irt - IRT_I8) ^ (xb->t.irt - IRT_I8)) == 1)) {
572 return ALIAS_NO;
573 }
574 /* Offset-based disambiguation. */
575 if (refa->o == IR_ADD && irref_isk(refa->op2)) {
576 IRIns *irk = IR(refa->op2);
577 basea = IR(refa->op1);
578 ofsa = (LJ_64 && irk->o == IR_KINT64) ? (ptrdiff_t)ir_k64(irk)->u64 :
579 (ptrdiff_t)irk->i;
580 if (basea == refb && ofsa != 0)
581 return ALIAS_NO; /* base+-ofs vs. base. */
582 }
583 if (refb->o == IR_ADD && irref_isk(refb->op2)) {
584 IRIns *irk = IR(refb->op2);
585 baseb = IR(refb->op1);
586 ofsb = (LJ_64 && irk->o == IR_KINT64) ? (ptrdiff_t)ir_k64(irk)->u64 :
587 (ptrdiff_t)irk->i;
588 if (refa == baseb && ofsb != 0)
589 return ALIAS_NO; /* base vs. base+-ofs. */
590 }
591 if (basea == baseb) {
592 /* This assumes strictly-typed, non-overlapping accesses. */
593 if (ofsa != ofsb)
594 return ALIAS_NO; /* base+-o1 vs. base+-o2 and o1 != o2. */
595 return ALIAS_MUST; /* Unsigned vs. signed access to the same address. */
596 }
597 /* NYI: structural disambiguation. */
598 return aa_cnew(J, basea, baseb); /* Try to disambiguate allocations. */
599}
600
601/* Return CSEd reference or 0. Caveat: swaps lower ref to the right! */
602static IRRef reassoc_trycse(jit_State *J, IROp op, IRRef op1, IRRef op2)
603{
604 IRRef ref = J->chain[op];
605 IRRef lim = op1;
606 if (op2 > lim) { lim = op2; op2 = op1; op1 = lim; }
607 while (ref > lim) {
608 IRIns *ir = IR(ref);
609 if (ir->op1 == op1 && ir->op2 == op2)
610 return ref;
611 ref = ir->prev;
612 }
613 return 0;
614}
615
616/* Reassociate index references. */
617static IRRef reassoc_xref(jit_State *J, IRIns *ir)
618{
619 ptrdiff_t ofs = 0;
620 if (ir->o == IR_ADD && irref_isk(ir->op2)) { /* Get constant offset. */
621 IRIns *irk = IR(ir->op2);
622 ofs = (LJ_64 && irk->o == IR_KINT64) ? (ptrdiff_t)ir_k64(irk)->u64 :
623 (ptrdiff_t)irk->i;
624 ir = IR(ir->op1);
625 }
626 if (ir->o == IR_ADD) { /* Add of base + index. */
627 /* Index ref > base ref for loop-carried dependences. Only check op1. */
628 IRIns *ir2, *ir1 = IR(ir->op1);
629 int32_t shift = 0;
630 IRRef idxref;
631 /* Determine index shifts. Don't bother with IR_MUL here. */
632 if (ir1->o == IR_BSHL && irref_isk(ir1->op2))
633 shift = IR(ir1->op2)->i;
634 else if (ir1->o == IR_ADD && ir1->op1 == ir1->op2)
635 shift = 1;
636 else
637 ir1 = ir;
638 ir2 = IR(ir1->op1);
639 /* A non-reassociated add. Must be a loop-carried dependence. */
640 if (ir2->o == IR_ADD && irt_isint(ir2->t) && irref_isk(ir2->op2))
641 ofs += (ptrdiff_t)IR(ir2->op2)->i << shift;
642 else
643 return 0;
644 idxref = ir2->op1;
645 /* Try to CSE the reassociated chain. Give up if not found. */
646 if (ir1 != ir &&
647 !(idxref = reassoc_trycse(J, ir1->o, idxref,
648 ir1->o == IR_BSHL ? ir1->op2 : idxref)))
649 return 0;
650 if (!(idxref = reassoc_trycse(J, IR_ADD, idxref, ir->op2)))
651 return 0;
652 if (ofs != 0) {
653 IRRef refk = tref_ref(lj_ir_kintp(J, ofs));
654 if (!(idxref = reassoc_trycse(J, IR_ADD, idxref, refk)))
655 return 0;
656 }
657 return idxref; /* Success, found a reassociated index reference. Phew. */
658 }
659 return 0; /* Failure. */
660}
661
662/* XLOAD forwarding. */
663TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J)
664{
665 IRRef xref = fins->op1;
666 IRIns *xr = IR(xref);
667 IRRef lim = xref; /* Search limit. */
668 IRRef ref;
669
670 if ((fins->op2 & IRXLOAD_READONLY))
671 goto cselim;
672 if ((fins->op2 & IRXLOAD_VOLATILE))
673 goto doemit;
674
675 /* Search for conflicting stores. */
676 ref = J->chain[IR_XSTORE];
677retry:
678 if (J->chain[IR_CALLXS] > lim) lim = J->chain[IR_CALLXS];
679 if (J->chain[IR_XBAR] > lim) lim = J->chain[IR_XBAR];
680 while (ref > lim) {
681 IRIns *store = IR(ref);
682 switch (aa_xref(J, xr, fins, store)) {
683 case ALIAS_NO: break; /* Continue searching. */
684 case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */
685 case ALIAS_MUST:
686 /* Emit conversion if the loaded type doesn't match the forwarded type. */
687 if (!irt_sametype(fins->t, IR(store->op2)->t)) {
688 IRType st = irt_type(fins->t);
689 if (st == IRT_I8 || st == IRT_I16) { /* Trunc + sign-extend. */
690 st |= IRCONV_SEXT;
691 } else if (st == IRT_U8 || st == IRT_U16) { /* Trunc + zero-extend. */
692 } else if (st == IRT_INT && !irt_isint(IR(store->op2)->t)) {
693 st = irt_type(IR(store->op2)->t); /* Needs dummy CONV.int.*. */
694 } else { /* I64/U64 are boxed, U32 is hidden behind a CONV.num.u32. */
695 goto store_fwd;
696 }
697 fins->ot = IRTI(IR_CONV);
698 fins->op1 = store->op2;
699 fins->op2 = (IRT_INT<<5)|st;
700 return RETRYFOLD;
701 }
702 store_fwd:
703 return store->op2; /* Store forwarding. */
704 }
705 ref = store->prev;
706 }
707
708cselim:
709 /* Try to find a matching load. Below the conflicting store, if any. */
710 ref = J->chain[IR_XLOAD];
711 while (ref > lim) {
712 /* CSE for XLOAD depends on the type, but not on the IRXLOAD_* flags. */
713 if (IR(ref)->op1 == xref && irt_sametype(IR(ref)->t, fins->t))
714 return ref;
715 ref = IR(ref)->prev;
716 }
717
718 /* Reassociate XLOAD across PHIs to handle a[i-1] forwarding case. */
719 if (!(fins->op2 & IRXLOAD_READONLY) && J->chain[IR_LOOP] &&
720 xref == fins->op1 && (xref = reassoc_xref(J, xr)) != 0) {
721 ref = J->chain[IR_XSTORE];
722 while (ref > lim) /* Skip stores that have already been checked. */
723 ref = IR(ref)->prev;
724 lim = xref;
725 xr = IR(xref);
726 goto retry; /* Retry with the reassociated reference. */
727 }
728doemit:
729 return EMITFOLD;
730}
731
732/* XSTORE elimination. */
733TRef LJ_FASTCALL lj_opt_dse_xstore(jit_State *J)
734{
735 IRRef xref = fins->op1;
736 IRIns *xr = IR(xref);
737 IRRef lim = xref; /* Search limit. */
738 IRRef val = fins->op2; /* Stored value reference. */
739 IRRef1 *refp = &J->chain[IR_XSTORE];
740 IRRef ref = *refp;
741 if (J->chain[IR_CALLXS] > lim) lim = J->chain[IR_CALLXS];
742 if (J->chain[IR_XBAR] > lim) lim = J->chain[IR_XBAR];
743 while (ref > lim) { /* Search for redundant or conflicting stores. */
744 IRIns *store = IR(ref);
745 switch (aa_xref(J, xr, fins, store)) {
746 case ALIAS_NO:
747 break; /* Continue searching. */
748 case ALIAS_MAY:
749 if (store->op2 != val) /* Conflict if the value is different. */
750 goto doemit;
751 break; /* Otherwise continue searching. */
752 case ALIAS_MUST:
753 if (store->op2 == val) /* Same value: drop the new store. */
754 return DROPFOLD;
755 /* Different value: try to eliminate the redundant store. */
756 if (ref > J->chain[IR_LOOP]) { /* Quick check to avoid crossing LOOP. */
757 IRIns *ir;
758 /* Check for any intervening guards or any XLOADs (no AA performed). */
759 for (ir = IR(J->cur.nins-1); ir > store; ir--)
760 if (irt_isguard(ir->t) || ir->o == IR_XLOAD)
761 goto doemit; /* No elimination possible. */
762 /* Remove redundant store from chain and replace with NOP. */
763 *refp = store->prev;
764 store->o = IR_NOP;
765 store->t.irt = IRT_NIL;
766 store->op1 = store->op2 = 0;
767 store->prev = 0;
768 /* Now emit the new store instead. */
769 }
770 goto doemit;
771 }
772 ref = *(refp = &store->prev);
773 }
774doemit:
775 return EMITFOLD; /* Otherwise we have a conflict or simply no match. */
776}
777
778/* -- Forwarding of lj_tab_len -------------------------------------------- */
779
780/* This is rather simplistic right now, but better than nothing. */
781TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J)
782{
783 IRRef tab = fins->op1; /* Table reference. */
784 IRRef lim = tab; /* Search limit. */
785 IRRef ref;
786
787 /* Any ASTORE is a conflict and limits the search. */
788 if (J->chain[IR_ASTORE] > lim) lim = J->chain[IR_ASTORE];
789
790 /* Search for conflicting HSTORE with numeric key. */
791 ref = J->chain[IR_HSTORE];
792 while (ref > lim) {
793 IRIns *store = IR(ref);
794 IRIns *href = IR(store->op1);
795 IRIns *key = IR(href->op2);
796 if (irt_isnum(key->o == IR_KSLOT ? IR(key->op1)->t : key->t)) {
797 lim = ref; /* Conflicting store found, limits search for TLEN. */
798 break;
799 }
800 ref = store->prev;
801 }
802
803 /* Try to find a matching load. Below the conflicting store, if any. */
804 return lj_opt_cselim(J, lim);
805}
806
807/* -- ASTORE/HSTORE previous type analysis -------------------------------- */
808
809/* Check whether the previous value for a table store is non-nil.
810** This can be derived either from a previous store or from a previous
811** load (because all loads from tables perform a type check).
812**
813** The result of the analysis can be used to avoid the metatable check
814** and the guard against HREF returning niltv. Both of these are cheap,
815** so let's not spend too much effort on the analysis.
816**
817** A result of 1 is exact: previous value CANNOT be nil.
818** A result of 0 is inexact: previous value MAY be nil.
819*/
820int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref)
821{
822 /* First check stores. */
823 IRRef ref = J->chain[loadop+IRDELTA_L2S];
824 while (ref > xref) {
825 IRIns *store = IR(ref);
826 if (store->op1 == xref) { /* Same xREF. */
827 /* A nil store MAY alias, but a non-nil store MUST alias. */
828 return !irt_isnil(store->t);
829 } else if (irt_isnil(store->t)) { /* Must check any nil store. */
830 IRRef skref = IR(store->op1)->op2;
831 IRRef xkref = IR(xref)->op2;
832 /* Same key type MAY alias. Need ALOAD check due to multiple int types. */
833 if (loadop == IR_ALOAD || irt_sametype(IR(skref)->t, IR(xkref)->t)) {
834 if (skref == xkref || !irref_isk(skref) || !irref_isk(xkref))
835 return 0; /* A nil store with same const key or var key MAY alias. */
836 /* Different const keys CANNOT alias. */
837 } /* Different key types CANNOT alias. */
838 } /* Other non-nil stores MAY alias. */
839 ref = store->prev;
840 }
841
842 /* Check loads since nothing could be derived from stores. */
843 ref = J->chain[loadop];
844 while (ref > xref) {
845 IRIns *load = IR(ref);
846 if (load->op1 == xref) { /* Same xREF. */
847 /* A nil load MAY alias, but a non-nil load MUST alias. */
848 return !irt_isnil(load->t);
849 } /* Other non-nil loads MAY alias. */
850 ref = load->prev;
851 }
852 return 0; /* Nothing derived at all, previous value MAY be nil. */
853}
854
855/* ------------------------------------------------------------------------ */
856
857#undef IR
858#undef fins
859#undef fright
860
861#endif
diff --git a/libraries/luajit-2.0/src/lj_opt_narrow.c b/libraries/luajit-2.0/src/lj_opt_narrow.c
new file mode 100644
index 0000000..d9d1e2b
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_opt_narrow.c
@@ -0,0 +1,648 @@
1/*
2** NARROW: Narrowing of numbers to integers (double to int32_t).
3** STRIPOV: Stripping of overflow checks.
4** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
5*/
6
7#define lj_opt_narrow_c
8#define LUA_CORE
9
10#include "lj_obj.h"
11
12#if LJ_HASJIT
13
14#include "lj_str.h"
15#include "lj_bc.h"
16#include "lj_ir.h"
17#include "lj_jit.h"
18#include "lj_iropt.h"
19#include "lj_trace.h"
20#include "lj_vm.h"
21
22/* Rationale for narrowing optimizations:
23**
24** Lua has only a single number type and this is a FP double by default.
25** Narrowing doubles to integers does not pay off for the interpreter on a
26** current-generation x86/x64 machine. Most FP operations need the same
27** amount of execution resources as their integer counterparts, except
28** with slightly longer latencies. Longer latencies are a non-issue for
29** the interpreter, since they are usually hidden by other overhead.
30**
31** The total CPU execution bandwidth is the sum of the bandwidth of the FP
32** and the integer units, because they execute in parallel. The FP units
33** have an equal or higher bandwidth than the integer units. Not using
34** them means losing execution bandwidth. Moving work away from them to
35** the already quite busy integer units is a losing proposition.
36**
37** The situation for JIT-compiled code is a bit different: the higher code
38** density makes the extra latencies much more visible. Tight loops expose
39** the latencies for updating the induction variables. Array indexing
40** requires narrowing conversions with high latencies and additional
41** guards (to check that the index is really an integer). And many common
42** optimizations only work on integers.
43**
44** One solution would be speculative, eager narrowing of all number loads.
45** This causes many problems, like losing -0 or the need to resolve type
46** mismatches between traces. It also effectively forces the integer type
47** to have overflow-checking semantics. This impedes many basic
48** optimizations and requires adding overflow checks to all integer
49** arithmetic operations (whereas FP arithmetics can do without).
50**
51** Always replacing an FP op with an integer op plus an overflow check is
52** counter-productive on a current-generation super-scalar CPU. Although
53** the overflow check branches are highly predictable, they will clog the
54** execution port for the branch unit and tie up reorder buffers. This is
55** turning a pure data-flow dependency into a different data-flow
56** dependency (with slightly lower latency) *plus* a control dependency.
57** In general, you don't want to do this since latencies due to data-flow
58** dependencies can be well hidden by out-of-order execution.
59**
60** A better solution is to keep all numbers as FP values and only narrow
61** when it's beneficial to do so. LuaJIT uses predictive narrowing for
62** induction variables and demand-driven narrowing for index expressions,
63** integer arguments and bit operations. Additionally it can eliminate or
64** hoist most of the resulting overflow checks. Regular arithmetic
65** computations are never narrowed to integers.
66**
67** The integer type in the IR has convenient wrap-around semantics and
68** ignores overflow. Extra operations have been added for
69** overflow-checking arithmetic (ADDOV/SUBOV) instead of an extra type.
70** Apart from reducing overall complexity of the compiler, this also
71** nicely solves the problem where you want to apply algebraic
72** simplifications to ADD, but not to ADDOV. And the x86/x64 assembler can
73** use lea instead of an add for integer ADD, but not for ADDOV (lea does
74** not affect the flags, but it helps to avoid register moves).
75**
76**
77** All of the above has to be reconsidered for architectures with slow FP
78** operations or without a hardware FPU. The dual-number mode of LuaJIT
79** addresses this issue. Arithmetic operations are performed on integers
80** as far as possible and overflow checks are added as needed.
81**
82** This implies that narrowing for integer arguments and bit operations
83** should also strip overflow checks, e.g. replace ADDOV with ADD. The
84** original overflow guards are weak and can be eliminated by DCE, if
85** there's no other use.
86**
87** A slight twist is that it's usually beneficial to use overflow-checked
88** integer arithmetics if all inputs are already integers. This is the only
89** change that affects the single-number mode, too.
90*/
91
92/* Some local macros to save typing. Undef'd at the end. */
93#define IR(ref) (&J->cur.ir[(ref)])
94#define fins (&J->fold.ins)
95
96/* Pass IR on to next optimization in chain (FOLD). */
97#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
98
99#define emitir_raw(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_ir_emit(J))
100
101/* -- Elimination of narrowing type conversions --------------------------- */
102
103/* Narrowing of index expressions and bit operations is demand-driven. The
104** trace recorder emits a narrowing type conversion (CONV.int.num or TOBIT)
105** in all of these cases (e.g. array indexing or string indexing). FOLD
106** already takes care of eliminating simple redundant conversions like
107** CONV.int.num(CONV.num.int(x)) ==> x.
108**
109** But the surrounding code is FP-heavy and arithmetic operations are
110** performed on FP numbers (for the single-number mode). Consider a common
111** example such as 'x=t[i+1]', with 'i' already an integer (due to induction
112** variable narrowing). The index expression would be recorded as
113** CONV.int.num(ADD(CONV.num.int(i), 1))
114** which is clearly suboptimal.
115**
116** One can do better by recursively backpropagating the narrowing type
117** conversion across FP arithmetic operations. This turns FP ops into
118** their corresponding integer counterparts. Depending on the semantics of
119** the conversion they also need to check for overflow. Currently only ADD
120** and SUB are supported.
121**
122** The above example can be rewritten as
123** ADDOV(CONV.int.num(CONV.num.int(i)), 1)
124** and then into ADDOV(i, 1) after folding of the conversions. The original
125** FP ops remain in the IR and are eliminated by DCE since all references to
126** them are gone.
127**
128** [In dual-number mode the trace recorder already emits ADDOV etc., but
129** this can be further reduced. See below.]
130**
131** Special care has to be taken to avoid narrowing across an operation
132** which is potentially operating on non-integral operands. One obvious
133** case is when an expression contains a non-integral constant, but ends
134** up as an integer index at runtime (like t[x+1.5] with x=0.5).
135**
136** Operations with two non-constant operands illustrate a similar problem
137** (like t[a+b] with a=1.5 and b=2.5). Backpropagation has to stop there,
138** unless it can be proven that either operand is integral (e.g. by CSEing
139** a previous conversion). As a not-so-obvious corollary this logic also
140** applies for a whole expression tree (e.g. t[(a+1)+(b+1)]).
141**
142** Correctness of the transformation is guaranteed by avoiding to expand
143** the tree by adding more conversions than the one we would need to emit
144** if not backpropagating. TOBIT employs a more optimistic rule, because
145** the conversion has special semantics, designed to make the life of the
146** compiler writer easier. ;-)
147**
148** Using on-the-fly backpropagation of an expression tree doesn't work
149** because it's unknown whether the transform is correct until the end.
150** This either requires IR rollback and cache invalidation for every
151** subtree or a two-pass algorithm. The former didn't work out too well,
152** so the code now combines a recursive collector with a stack-based
153** emitter.
154**
155** [A recursive backpropagation algorithm with backtracking, employing
156** skip-list lookup and round-robin caching, emitting stack operations
157** on-the-fly for a stack-based interpreter -- and all of that in a meager
158** kilobyte? Yep, compilers are a great treasure chest. Throw away your
159** textbooks and read the codebase of a compiler today!]
160**
161** There's another optimization opportunity for array indexing: it's
162** always accompanied by an array bounds-check. The outermost overflow
163** check may be delegated to the ABC operation. This works because ABC is
164** an unsigned comparison and wrap-around due to overflow creates negative
165** numbers.
166**
167** But this optimization is only valid for constants that cannot overflow
168** an int32_t into the range of valid array indexes [0..2^27+1). A check
169** for +-2^30 is safe since -2^31 - 2^30 wraps to 2^30 and 2^31-1 + 2^30
170** wraps to -2^30-1.
171**
172** It's also good enough in practice, since e.g. t[i+1] or t[i-10] are
173** quite common. So the above example finally ends up as ADD(i, 1)!
174**
175** Later on, the assembler is able to fuse the whole array reference and
176** the ADD into the memory operands of loads and other instructions. This
177** is why LuaJIT is able to generate very pretty (and fast) machine code
178** for array indexing. And that, my dear, concludes another story about
179** one of the hidden secrets of LuaJIT ...
180*/
181
182/* Maximum backpropagation depth and maximum stack size. */
183#define NARROW_MAX_BACKPROP 100
184#define NARROW_MAX_STACK 256
185
186/* The stack machine has a 32 bit instruction format: [IROpT | IRRef1]
187** The lower 16 bits hold a reference (or 0). The upper 16 bits hold
188** the IR opcode + type or one of the following special opcodes:
189*/
190enum {
191 NARROW_REF, /* Push ref. */
192 NARROW_CONV, /* Push conversion of ref. */
193 NARROW_SEXT, /* Push sign-extension of ref. */
194 NARROW_INT /* Push KINT ref. The next code holds an int32_t. */
195};
196
197typedef uint32_t NarrowIns;
198
199#define NARROWINS(op, ref) (((op) << 16) + (ref))
200#define narrow_op(ins) ((IROpT)((ins) >> 16))
201#define narrow_ref(ins) ((IRRef1)(ins))
202
203/* Context used for narrowing of type conversions. */
204typedef struct NarrowConv {
205 jit_State *J; /* JIT compiler state. */
206 NarrowIns *sp; /* Current stack pointer. */
207 NarrowIns *maxsp; /* Maximum stack pointer minus redzone. */
208 int lim; /* Limit on the number of emitted conversions. */
209 IRRef mode; /* Conversion mode (IRCONV_*). */
210 IRType t; /* Destination type: IRT_INT or IRT_I64. */
211 NarrowIns stack[NARROW_MAX_STACK]; /* Stack holding stack-machine code. */
212} NarrowConv;
213
214/* Lookup a reference in the backpropagation cache. */
215static BPropEntry *narrow_bpc_get(jit_State *J, IRRef1 key, IRRef mode)
216{
217 ptrdiff_t i;
218 for (i = 0; i < BPROP_SLOTS; i++) {
219 BPropEntry *bp = &J->bpropcache[i];
220 /* Stronger checks are ok, too. */
221 if (bp->key == key && bp->mode >= mode &&
222 ((bp->mode ^ mode) & IRCONV_MODEMASK) == 0)
223 return bp;
224 }
225 return NULL;
226}
227
228/* Add an entry to the backpropagation cache. */
229static void narrow_bpc_set(jit_State *J, IRRef1 key, IRRef1 val, IRRef mode)
230{
231 uint32_t slot = J->bpropslot;
232 BPropEntry *bp = &J->bpropcache[slot];
233 J->bpropslot = (slot + 1) & (BPROP_SLOTS-1);
234 bp->key = key;
235 bp->val = val;
236 bp->mode = mode;
237}
238
239/* Backpropagate overflow stripping. */
240static void narrow_stripov_backprop(NarrowConv *nc, IRRef ref, int depth)
241{
242 jit_State *J = nc->J;
243 IRIns *ir = IR(ref);
244 if (ir->o == IR_ADDOV || ir->o == IR_SUBOV ||
245 (ir->o == IR_MULOV && (nc->mode & IRCONV_CONVMASK) == IRCONV_ANY)) {
246 BPropEntry *bp = narrow_bpc_get(nc->J, ref, IRCONV_TOBIT);
247 if (bp) {
248 ref = bp->val;
249 } else if (++depth < NARROW_MAX_BACKPROP && nc->sp < nc->maxsp) {
250 narrow_stripov_backprop(nc, ir->op1, depth);
251 narrow_stripov_backprop(nc, ir->op2, depth);
252 *nc->sp++ = NARROWINS(IRT(ir->o - IR_ADDOV + IR_ADD, IRT_INT), ref);
253 return;
254 }
255 }
256 *nc->sp++ = NARROWINS(NARROW_REF, ref);
257}
258
259/* Backpropagate narrowing conversion. Return number of needed conversions. */
260static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth)
261{
262 jit_State *J = nc->J;
263 IRIns *ir = IR(ref);
264 IRRef cref;
265
266 /* Check the easy cases first. */
267 if (ir->o == IR_CONV && (ir->op2 & IRCONV_SRCMASK) == IRT_INT) {
268 if ((nc->mode & IRCONV_CONVMASK) <= IRCONV_ANY)
269 narrow_stripov_backprop(nc, ir->op1, depth+1);
270 else
271 *nc->sp++ = NARROWINS(NARROW_REF, ir->op1); /* Undo conversion. */
272 if (nc->t == IRT_I64)
273 *nc->sp++ = NARROWINS(NARROW_SEXT, 0); /* Sign-extend integer. */
274 return 0;
275 } else if (ir->o == IR_KNUM) { /* Narrow FP constant. */
276 lua_Number n = ir_knum(ir)->n;
277 if ((nc->mode & IRCONV_CONVMASK) == IRCONV_TOBIT) {
278 /* Allows a wider range of constants. */
279 int64_t k64 = (int64_t)n;
280 if (n == (lua_Number)k64) { /* Only if const doesn't lose precision. */
281 *nc->sp++ = NARROWINS(NARROW_INT, 0);
282 *nc->sp++ = (NarrowIns)k64; /* But always truncate to 32 bits. */
283 return 0;
284 }
285 } else {
286 int32_t k = lj_num2int(n);
287 /* Only if constant is a small integer. */
288 if (checki16(k) && n == (lua_Number)k) {
289 *nc->sp++ = NARROWINS(NARROW_INT, 0);
290 *nc->sp++ = (NarrowIns)k;
291 return 0;
292 }
293 }
294 return 10; /* Never narrow other FP constants (this is rare). */
295 }
296
297 /* Try to CSE the conversion. Stronger checks are ok, too. */
298 cref = J->chain[fins->o];
299 while (cref > ref) {
300 IRIns *cr = IR(cref);
301 if (cr->op1 == ref &&
302 (fins->o == IR_TOBIT ||
303 ((cr->op2 & IRCONV_MODEMASK) == (nc->mode & IRCONV_MODEMASK) &&
304 irt_isguard(cr->t) >= irt_isguard(fins->t)))) {
305 *nc->sp++ = NARROWINS(NARROW_REF, cref);
306 return 0; /* Already there, no additional conversion needed. */
307 }
308 cref = cr->prev;
309 }
310
311 /* Backpropagate across ADD/SUB. */
312 if (ir->o == IR_ADD || ir->o == IR_SUB) {
313 /* Try cache lookup first. */
314 IRRef mode = nc->mode;
315 BPropEntry *bp;
316 /* Inner conversions need a stronger check. */
317 if ((mode & IRCONV_CONVMASK) == IRCONV_INDEX && depth > 0)
318 mode += IRCONV_CHECK-IRCONV_INDEX;
319 bp = narrow_bpc_get(nc->J, (IRRef1)ref, mode);
320 if (bp) {
321 *nc->sp++ = NARROWINS(NARROW_REF, bp->val);
322 return 0;
323 } else if (nc->t == IRT_I64) {
324 /* Try sign-extending from an existing (checked) conversion to int. */
325 mode = (IRT_INT<<5)|IRT_NUM|IRCONV_INDEX;
326 bp = narrow_bpc_get(nc->J, (IRRef1)ref, mode);
327 if (bp) {
328 *nc->sp++ = NARROWINS(NARROW_REF, bp->val);
329 *nc->sp++ = NARROWINS(NARROW_SEXT, 0);
330 return 0;
331 }
332 }
333 if (++depth < NARROW_MAX_BACKPROP && nc->sp < nc->maxsp) {
334 NarrowIns *savesp = nc->sp;
335 int count = narrow_conv_backprop(nc, ir->op1, depth);
336 count += narrow_conv_backprop(nc, ir->op2, depth);
337 if (count <= nc->lim) { /* Limit total number of conversions. */
338 *nc->sp++ = NARROWINS(IRT(ir->o, nc->t), ref);
339 return count;
340 }
341 nc->sp = savesp; /* Too many conversions, need to backtrack. */
342 }
343 }
344
345 /* Otherwise add a conversion. */
346 *nc->sp++ = NARROWINS(NARROW_CONV, ref);
347 return 1;
348}
349
350/* Emit the conversions collected during backpropagation. */
351static IRRef narrow_conv_emit(jit_State *J, NarrowConv *nc)
352{
353 /* The fins fields must be saved now -- emitir() overwrites them. */
354 IROpT guardot = irt_isguard(fins->t) ? IRTG(IR_ADDOV-IR_ADD, 0) : 0;
355 IROpT convot = fins->ot;
356 IRRef1 convop2 = fins->op2;
357 NarrowIns *next = nc->stack; /* List of instructions from backpropagation. */
358 NarrowIns *last = nc->sp;
359 NarrowIns *sp = nc->stack; /* Recycle the stack to store operands. */
360 while (next < last) { /* Simple stack machine to process the ins. list. */
361 NarrowIns ref = *next++;
362 IROpT op = narrow_op(ref);
363 if (op == NARROW_REF) {
364 *sp++ = ref;
365 } else if (op == NARROW_CONV) {
366 *sp++ = emitir_raw(convot, ref, convop2); /* Raw emit avoids a loop. */
367 } else if (op == NARROW_SEXT) {
368 lua_assert(sp >= nc->stack+1);
369 sp[-1] = emitir(IRT(IR_CONV, IRT_I64), sp[-1],
370 (IRT_I64<<5)|IRT_INT|IRCONV_SEXT);
371 } else if (op == NARROW_INT) {
372 lua_assert(next < last);
373 *sp++ = nc->t == IRT_I64 ?
374 lj_ir_kint64(J, (int64_t)(int32_t)*next++) :
375 lj_ir_kint(J, *next++);
376 } else { /* Regular IROpT. Pops two operands and pushes one result. */
377 IRRef mode = nc->mode;
378 lua_assert(sp >= nc->stack+2);
379 sp--;
380 /* Omit some overflow checks for array indexing. See comments above. */
381 if ((mode & IRCONV_CONVMASK) == IRCONV_INDEX) {
382 if (next == last && irref_isk(narrow_ref(sp[0])) &&
383 (uint32_t)IR(narrow_ref(sp[0]))->i + 0x40000000u < 0x80000000u)
384 guardot = 0;
385 else /* Otherwise cache a stronger check. */
386 mode += IRCONV_CHECK-IRCONV_INDEX;
387 }
388 sp[-1] = emitir(op+guardot, sp[-1], sp[0]);
389 /* Add to cache. */
390 if (narrow_ref(ref))
391 narrow_bpc_set(J, narrow_ref(ref), narrow_ref(sp[-1]), mode);
392 }
393 }
394 lua_assert(sp == nc->stack+1);
395 return nc->stack[0];
396}
397
398/* Narrow a type conversion of an arithmetic operation. */
399TRef LJ_FASTCALL lj_opt_narrow_convert(jit_State *J)
400{
401 if ((J->flags & JIT_F_OPT_NARROW)) {
402 NarrowConv nc;
403 nc.J = J;
404 nc.sp = nc.stack;
405 nc.maxsp = &nc.stack[NARROW_MAX_STACK-4];
406 nc.t = irt_type(fins->t);
407 if (fins->o == IR_TOBIT) {
408 nc.mode = IRCONV_TOBIT; /* Used only in the backpropagation cache. */
409 nc.lim = 2; /* TOBIT can use a more optimistic rule. */
410 } else {
411 nc.mode = fins->op2;
412 nc.lim = 1;
413 }
414 if (narrow_conv_backprop(&nc, fins->op1, 0) <= nc.lim)
415 return narrow_conv_emit(J, &nc);
416 }
417 return NEXTFOLD;
418}
419
420/* -- Narrowing of implicit conversions ----------------------------------- */
421
422/* Recursively strip overflow checks. */
423static TRef narrow_stripov(jit_State *J, TRef tr, int lastop, IRRef mode)
424{
425 IRRef ref = tref_ref(tr);
426 IRIns *ir = IR(ref);
427 int op = ir->o;
428 if (op >= IR_ADDOV && op <= lastop) {
429 BPropEntry *bp = narrow_bpc_get(J, ref, mode);
430 if (bp) {
431 return TREF(bp->val, irt_t(IR(bp->val)->t));
432 } else {
433 IRRef op1 = ir->op1, op2 = ir->op2; /* The IR may be reallocated. */
434 op1 = narrow_stripov(J, op1, lastop, mode);
435 op2 = narrow_stripov(J, op2, lastop, mode);
436 tr = emitir(IRT(op - IR_ADDOV + IR_ADD,
437 ((mode & IRCONV_DSTMASK) >> IRCONV_DSH)), op1, op2);
438 narrow_bpc_set(J, ref, tref_ref(tr), mode);
439 }
440 } else if (LJ_64 && (mode & IRCONV_SEXT) && !irt_is64(ir->t)) {
441 tr = emitir(IRT(IR_CONV, IRT_INTP), tr, mode);
442 }
443 return tr;
444}
445
446/* Narrow array index. */
447TRef LJ_FASTCALL lj_opt_narrow_index(jit_State *J, TRef tr)
448{
449 IRIns *ir;
450 lua_assert(tref_isnumber(tr));
451 if (tref_isnum(tr)) /* Conversion may be narrowed, too. See above. */
452 return emitir(IRTGI(IR_CONV), tr, IRCONV_INT_NUM|IRCONV_INDEX);
453 /* Omit some overflow checks for array indexing. See comments above. */
454 ir = IR(tref_ref(tr));
455 if ((ir->o == IR_ADDOV || ir->o == IR_SUBOV) && irref_isk(ir->op2) &&
456 (uint32_t)IR(ir->op2)->i + 0x40000000u < 0x80000000u)
457 return emitir(IRTI(ir->o - IR_ADDOV + IR_ADD), ir->op1, ir->op2);
458 return tr;
459}
460
461/* Narrow conversion to integer operand (overflow undefined). */
462TRef LJ_FASTCALL lj_opt_narrow_toint(jit_State *J, TRef tr)
463{
464 if (tref_isstr(tr))
465 tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
466 if (tref_isnum(tr)) /* Conversion may be narrowed, too. See above. */
467 return emitir(IRTI(IR_CONV), tr, IRCONV_INT_NUM|IRCONV_ANY);
468 if (!tref_isinteger(tr))
469 lj_trace_err(J, LJ_TRERR_BADTYPE);
470 /*
471 ** Undefined overflow semantics allow stripping of ADDOV, SUBOV and MULOV.
472 ** Use IRCONV_TOBIT for the cache entries, since the semantics are the same.
473 */
474 return narrow_stripov(J, tr, IR_MULOV, (IRT_INT<<5)|IRT_INT|IRCONV_TOBIT);
475}
476
477/* Narrow conversion to bitop operand (overflow wrapped). */
478TRef LJ_FASTCALL lj_opt_narrow_tobit(jit_State *J, TRef tr)
479{
480 if (tref_isstr(tr))
481 tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
482 if (tref_isnum(tr)) /* Conversion may be narrowed, too. See above. */
483 return emitir(IRTI(IR_TOBIT), tr, lj_ir_knum_tobit(J));
484 if (!tref_isinteger(tr))
485 lj_trace_err(J, LJ_TRERR_BADTYPE);
486 /*
487 ** Wrapped overflow semantics allow stripping of ADDOV and SUBOV.
488 ** MULOV cannot be stripped due to precision widening.
489 */
490 return narrow_stripov(J, tr, IR_SUBOV, (IRT_INT<<5)|IRT_INT|IRCONV_TOBIT);
491}
492
493#if LJ_HASFFI
494/* Narrow C array index (overflow undefined). */
495TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef tr)
496{
497 lua_assert(tref_isnumber(tr));
498 if (tref_isnum(tr))
499 return emitir(IRT(IR_CONV, IRT_INTP), tr,
500 (IRT_INTP<<5)|IRT_NUM|IRCONV_TRUNC|IRCONV_ANY);
501 /* Undefined overflow semantics allow stripping of ADDOV, SUBOV and MULOV. */
502 return narrow_stripov(J, tr, IR_MULOV,
503 LJ_64 ? ((IRT_INTP<<5)|IRT_INT|IRCONV_SEXT) :
504 ((IRT_INTP<<5)|IRT_INT|IRCONV_TOBIT));
505}
506#endif
507
508/* -- Narrowing of arithmetic operators ----------------------------------- */
509
510/* Check whether a number fits into an int32_t (-0 is ok, too). */
511static int numisint(lua_Number n)
512{
513 return (n == (lua_Number)lj_num2int(n));
514}
515
516/* Narrowing of arithmetic operations. */
517TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc,
518 TValue *vb, TValue *vc, IROp op)
519{
520 if (tref_isstr(rb)) {
521 rb = emitir(IRTG(IR_STRTO, IRT_NUM), rb, 0);
522 lj_str_tonum(strV(vb), vb);
523 }
524 if (tref_isstr(rc)) {
525 rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0);
526 lj_str_tonum(strV(vc), vc);
527 }
528 /* Must not narrow MUL in non-DUALNUM variant, because it loses -0. */
529 if ((op >= IR_ADD && op <= (LJ_DUALNUM ? IR_MUL : IR_SUB)) &&
530 tref_isinteger(rb) && tref_isinteger(rc) &&
531 numisint(lj_vm_foldarith(numberVnum(vb), numberVnum(vc),
532 (int)op - (int)IR_ADD)))
533 return emitir(IRTGI((int)op - (int)IR_ADD + (int)IR_ADDOV), rb, rc);
534 if (!tref_isnum(rb)) rb = emitir(IRTN(IR_CONV), rb, IRCONV_NUM_INT);
535 if (!tref_isnum(rc)) rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
536 return emitir(IRTN(op), rb, rc);
537}
538
539/* Narrowing of unary minus operator. */
540TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc)
541{
542 if (tref_isstr(rc)) {
543 rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0);
544 lj_str_tonum(strV(vc), vc);
545 }
546 if (tref_isinteger(rc)) {
547 if ((uint32_t)numberVint(vc) != 0x80000000u)
548 return emitir(IRTGI(IR_SUBOV), lj_ir_kint(J, 0), rc);
549 rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
550 }
551 return emitir(IRTN(IR_NEG), rc, lj_ir_knum_neg(J));
552}
553
554/* Narrowing of modulo operator. */
555TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vc)
556{
557 TRef tmp;
558 if (tvisstr(vc) && !lj_str_tonum(strV(vc), vc))
559 lj_trace_err(J, LJ_TRERR_BADTYPE);
560 if ((LJ_DUALNUM || (J->flags & JIT_F_OPT_NARROW)) &&
561 tref_isinteger(rb) && tref_isinteger(rc) &&
562 (tvisint(vc) ? intV(vc) != 0 : !tviszero(vc))) {
563 emitir(IRTGI(IR_NE), rc, lj_ir_kint(J, 0));
564 return emitir(IRTI(IR_MOD), rb, rc);
565 }
566 /* b % c ==> b - floor(b/c)*c */
567 rb = lj_ir_tonum(J, rb);
568 rc = lj_ir_tonum(J, rc);
569 tmp = emitir(IRTN(IR_DIV), rb, rc);
570 tmp = emitir(IRTN(IR_FPMATH), tmp, IRFPM_FLOOR);
571 tmp = emitir(IRTN(IR_MUL), tmp, rc);
572 return emitir(IRTN(IR_SUB), rb, tmp);
573}
574
575/* Narrowing of power operator or math.pow. */
576TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc)
577{
578 if (tvisstr(vc) && !lj_str_tonum(strV(vc), vc))
579 lj_trace_err(J, LJ_TRERR_BADTYPE);
580 /* Narrowing must be unconditional to preserve (-x)^i semantics. */
581 if (tvisint(vc) || numisint(numV(vc))) {
582 int checkrange = 0;
583 /* Split pow is faster for bigger exponents. But do this only for (+k)^i. */
584 if (tref_isk(rb) && (int32_t)ir_knum(IR(tref_ref(rb)))->u32.hi >= 0) {
585 int32_t k = numberVint(vc);
586 if (!(k >= -65536 && k <= 65536)) goto split_pow;
587 checkrange = 1;
588 }
589 if (!tref_isinteger(rc)) {
590 if (tref_isstr(rc))
591 rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0);
592 /* Guarded conversion to integer! */
593 rc = emitir(IRTGI(IR_CONV), rc, IRCONV_INT_NUM|IRCONV_CHECK);
594 }
595 if (checkrange && !tref_isk(rc)) { /* Range guard: -65536 <= i <= 65536 */
596 TRef tmp = emitir(IRTI(IR_ADD), rc, lj_ir_kint(J, 65536));
597 emitir(IRTGI(IR_ULE), tmp, lj_ir_kint(J, 2*65536));
598 }
599 return emitir(IRTN(IR_POW), rb, rc);
600 }
601split_pow:
602 /* FOLD covers most cases, but some are easier to do here. */
603 if (tref_isk(rb) && tvispone(ir_knum(IR(tref_ref(rb)))))
604 return rb; /* 1 ^ x ==> 1 */
605 rc = lj_ir_tonum(J, rc);
606 if (tref_isk(rc) && ir_knum(IR(tref_ref(rc)))->n == 0.5)
607 return emitir(IRTN(IR_FPMATH), rb, IRFPM_SQRT); /* x ^ 0.5 ==> sqrt(x) */
608 /* Split up b^c into exp2(c*log2(b)). Assembler may rejoin later. */
609 rb = emitir(IRTN(IR_FPMATH), rb, IRFPM_LOG2);
610 rc = emitir(IRTN(IR_MUL), rb, rc);
611 return emitir(IRTN(IR_FPMATH), rc, IRFPM_EXP2);
612}
613
614/* -- Predictive narrowing of induction variables ------------------------- */
615
616/* Narrow a single runtime value. */
617static int narrow_forl(jit_State *J, cTValue *o)
618{
619 if (tvisint(o)) return 1;
620 if (LJ_DUALNUM || (J->flags & JIT_F_OPT_NARROW)) return numisint(numV(o));
621 return 0;
622}
623
624/* Narrow the FORL index type by looking at the runtime values. */
625IRType lj_opt_narrow_forl(jit_State *J, cTValue *tv)
626{
627 lua_assert(tvisnumber(&tv[FORL_IDX]) &&
628 tvisnumber(&tv[FORL_STOP]) &&
629 tvisnumber(&tv[FORL_STEP]));
630 /* Narrow only if the runtime values of start/stop/step are all integers. */
631 if (narrow_forl(J, &tv[FORL_IDX]) &&
632 narrow_forl(J, &tv[FORL_STOP]) &&
633 narrow_forl(J, &tv[FORL_STEP])) {
634 /* And if the loop index can't possibly overflow. */
635 lua_Number step = numberVnum(&tv[FORL_STEP]);
636 lua_Number sum = numberVnum(&tv[FORL_STOP]) + step;
637 if (0 <= step ? (sum <= 2147483647.0) : (sum >= -2147483648.0))
638 return IRT_INT;
639 }
640 return IRT_NUM;
641}
642
643#undef IR
644#undef fins
645#undef emitir
646#undef emitir_raw
647
648#endif
diff --git a/libraries/luajit-2.0/src/lj_opt_split.c b/libraries/luajit-2.0/src/lj_opt_split.c
new file mode 100644
index 0000000..913a7a0
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_opt_split.c
@@ -0,0 +1,723 @@
1/*
2** SPLIT: Split 64 bit IR instructions into 32 bit IR instructions.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_opt_split_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT && (LJ_SOFTFP || (LJ_32 && LJ_HASFFI))
12
13#include "lj_err.h"
14#include "lj_str.h"
15#include "lj_ir.h"
16#include "lj_jit.h"
17#include "lj_ircall.h"
18#include "lj_iropt.h"
19#include "lj_vm.h"
20
21/* SPLIT pass:
22**
23** This pass splits up 64 bit IR instructions into multiple 32 bit IR
24** instructions. It's only active for soft-float targets or for 32 bit CPUs
25** which lack native 64 bit integer operations (the FFI is currently the
26** only emitter for 64 bit integer instructions).
27**
28** Splitting the IR in a separate pass keeps each 32 bit IR assembler
29** backend simple. Only a small amount of extra functionality needs to be
30** implemented. This is much easier than adding support for allocating
31** register pairs to each backend (believe me, I tried). A few simple, but
32** important optimizations can be performed by the SPLIT pass, which would
33** be tedious to do in the backend.
34**
35** The basic idea is to replace each 64 bit IR instruction with its 32 bit
36** equivalent plus an extra HIOP instruction. The splitted IR is not passed
37** through FOLD or any other optimizations, so each HIOP is guaranteed to
38** immediately follow it's counterpart. The actual functionality of HIOP is
39** inferred from the previous instruction.
40**
41** The operands of HIOP hold the hiword input references. The output of HIOP
42** is the hiword output reference, which is also used to hold the hiword
43** register or spill slot information. The register allocator treats this
44** instruction independently of any other instruction, which improves code
45** quality compared to using fixed register pairs.
46**
47** It's easier to split up some instructions into two regular 32 bit
48** instructions. E.g. XLOAD is split up into two XLOADs with two different
49** addresses. Obviously 64 bit constants need to be split up into two 32 bit
50** constants, too. Some hiword instructions can be entirely omitted, e.g.
51** when zero-extending a 32 bit value to 64 bits. 64 bit arguments for calls
52** are split up into two 32 bit arguments each.
53**
54** On soft-float targets, floating-point instructions are directly converted
55** to soft-float calls by the SPLIT pass (except for comparisons and MIN/MAX).
56** HIOP for number results has the type IRT_SOFTFP ("sfp" in -jdump).
57**
58** Here's the IR and x64 machine code for 'x.b = x.a + 1' for a struct with
59** two int64_t fields:
60**
61** 0100 p32 ADD base +8
62** 0101 i64 XLOAD 0100
63** 0102 i64 ADD 0101 +1
64** 0103 p32 ADD base +16
65** 0104 i64 XSTORE 0103 0102
66**
67** mov rax, [esi+0x8]
68** add rax, +0x01
69** mov [esi+0x10], rax
70**
71** Here's the transformed IR and the x86 machine code after the SPLIT pass:
72**
73** 0100 p32 ADD base +8
74** 0101 int XLOAD 0100
75** 0102 p32 ADD base +12
76** 0103 int XLOAD 0102
77** 0104 int ADD 0101 +1
78** 0105 int HIOP 0103 +0
79** 0106 p32 ADD base +16
80** 0107 int XSTORE 0106 0104
81** 0108 p32 ADD base +20
82** 0109 int XSTORE 0108 0105
83**
84** mov eax, [esi+0x8]
85** mov ecx, [esi+0xc]
86** add eax, +0x01
87** adc ecx, +0x00
88** mov [esi+0x10], eax
89** mov [esi+0x14], ecx
90**
91** You may notice the reassociated hiword address computation, which is
92** later fused into the mov operands by the assembler.
93*/
94
95/* Some local macros to save typing. Undef'd at the end. */
96#define IR(ref) (&J->cur.ir[(ref)])
97
98/* Directly emit the transformed IR without updating chains etc. */
99static IRRef split_emit(jit_State *J, uint16_t ot, IRRef1 op1, IRRef1 op2)
100{
101 IRRef nref = lj_ir_nextins(J);
102 IRIns *ir = IR(nref);
103 ir->ot = ot;
104 ir->op1 = op1;
105 ir->op2 = op2;
106 return nref;
107}
108
109#if LJ_SOFTFP
110/* Emit a (checked) number to integer conversion. */
111static IRRef split_num2int(jit_State *J, IRRef lo, IRRef hi, int check)
112{
113 IRRef tmp, res;
114#if LJ_LE
115 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), lo, hi);
116#else
117 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hi, lo);
118#endif
119 res = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_softfp_d2i);
120 if (check) {
121 tmp = split_emit(J, IRTI(IR_CALLN), res, IRCALL_softfp_i2d);
122 split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
123 split_emit(J, IRTGI(IR_EQ), tmp, lo);
124 split_emit(J, IRTG(IR_HIOP, IRT_SOFTFP), tmp+1, hi);
125 }
126 return res;
127}
128
129/* Emit a CALLN with one split 64 bit argument. */
130static IRRef split_call_l(jit_State *J, IRRef1 *hisubst, IRIns *oir,
131 IRIns *ir, IRCallID id)
132{
133 IRRef tmp, op1 = ir->op1;
134 J->cur.nins--;
135#if LJ_LE
136 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]);
137#else
138 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
139#endif
140 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id);
141 return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
142}
143
144/* Emit a CALLN with one split 64 bit argument and a 32 bit argument. */
145static IRRef split_call_li(jit_State *J, IRRef1 *hisubst, IRIns *oir,
146 IRIns *ir, IRCallID id)
147{
148 IRRef tmp, op1 = ir->op1, op2 = ir->op2;
149 J->cur.nins--;
150#if LJ_LE
151 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]);
152#else
153 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
154#endif
155 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev);
156 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id);
157 return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
158}
159#endif
160
161/* Emit a CALLN with two split 64 bit arguments. */
162static IRRef split_call_ll(jit_State *J, IRRef1 *hisubst, IRIns *oir,
163 IRIns *ir, IRCallID id)
164{
165 IRRef tmp, op1 = ir->op1, op2 = ir->op2;
166 J->cur.nins--;
167#if LJ_LE
168 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]);
169 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev);
170 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, hisubst[op2]);
171#else
172 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
173 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, hisubst[op2]);
174 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev);
175#endif
176 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id);
177 return split_emit(J,
178 IRT(IR_HIOP, (LJ_SOFTFP && irt_isnum(ir->t)) ? IRT_SOFTFP : IRT_INT),
179 tmp, tmp);
180}
181
182/* Get a pointer to the other 32 bit word (LE: hiword, BE: loword). */
183static IRRef split_ptr(jit_State *J, IRIns *oir, IRRef ref)
184{
185 IRRef nref = oir[ref].prev;
186 IRIns *ir = IR(nref);
187 int32_t ofs = 4;
188 if (ir->o == IR_ADD && irref_isk(ir->op2) && !irt_isphi(oir[ref].t)) {
189 /* Reassociate address. */
190 ofs += IR(ir->op2)->i;
191 nref = ir->op1;
192 if (ofs == 0) return nref;
193 }
194 return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs));
195}
196
197/* Transform the old IR to the new IR. */
198static void split_ir(jit_State *J)
199{
200 IRRef nins = J->cur.nins, nk = J->cur.nk;
201 MSize irlen = nins - nk;
202 MSize need = (irlen+1)*(sizeof(IRIns) + sizeof(IRRef1));
203 IRIns *oir = (IRIns *)lj_str_needbuf(J->L, &G(J->L)->tmpbuf, need);
204 IRRef1 *hisubst;
205 IRRef ref;
206
207 /* Copy old IR to buffer. */
208 memcpy(oir, IR(nk), irlen*sizeof(IRIns));
209 /* Bias hiword substitution table and old IR. Loword kept in field prev. */
210 hisubst = (IRRef1 *)&oir[irlen] - nk;
211 oir -= nk;
212
213 /* Remove all IR instructions, but retain IR constants. */
214 J->cur.nins = REF_FIRST;
215 J->loopref = 0;
216
217 /* Process constants and fixed references. */
218 for (ref = nk; ref <= REF_BASE; ref++) {
219 IRIns *ir = &oir[ref];
220 if ((LJ_SOFTFP && ir->o == IR_KNUM) || ir->o == IR_KINT64) {
221 /* Split up 64 bit constant. */
222 TValue tv = *ir_k64(ir);
223 ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo);
224 hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi);
225 } else {
226 ir->prev = ref; /* Identity substitution for loword. */
227 hisubst[ref] = 0;
228 }
229 }
230
231 /* Process old IR instructions. */
232 for (ref = REF_FIRST; ref < nins; ref++) {
233 IRIns *ir = &oir[ref];
234 IRRef nref = lj_ir_nextins(J);
235 IRIns *nir = IR(nref);
236 IRRef hi = 0;
237
238 /* Copy-substitute old instruction to new instruction. */
239 nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev;
240 nir->op2 = ir->op2 < nk ? ir->op2 : oir[ir->op2].prev;
241 ir->prev = nref; /* Loword substitution. */
242 nir->o = ir->o;
243 nir->t.irt = ir->t.irt & ~(IRT_MARK|IRT_ISPHI);
244 hisubst[ref] = 0;
245
246 /* Split 64 bit instructions. */
247#if LJ_SOFTFP
248 if (irt_isnum(ir->t)) {
249 nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */
250 /* Note: hi ref = lo ref + 1! Required for SNAP_SOFTFPNUM logic. */
251 switch (ir->o) {
252 case IR_ADD:
253 hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_add);
254 break;
255 case IR_SUB:
256 hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_sub);
257 break;
258 case IR_MUL:
259 hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_mul);
260 break;
261 case IR_DIV:
262 hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_div);
263 break;
264 case IR_POW:
265 hi = split_call_li(J, hisubst, oir, ir, IRCALL_lj_vm_powi);
266 break;
267 case IR_FPMATH:
268 /* Try to rejoin pow from EXP2, MUL and LOG2. */
269 if (nir->op2 == IRFPM_EXP2 && nir->op1 > J->loopref) {
270 IRIns *irp = IR(nir->op1);
271 if (irp->o == IR_CALLN && irp->op2 == IRCALL_softfp_mul) {
272 IRIns *irm4 = IR(irp->op1);
273 IRIns *irm3 = IR(irm4->op1);
274 IRIns *irm12 = IR(irm3->op1);
275 IRIns *irl1 = IR(irm12->op1);
276 if (irm12->op1 > J->loopref && irl1->o == IR_CALLN &&
277 irl1->op2 == IRCALL_lj_vm_log2) {
278 IRRef tmp = irl1->op1; /* Recycle first two args from LOG2. */
279 IRRef arg3 = irm3->op2, arg4 = irm4->op2;
280 J->cur.nins--;
281 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, arg3);
282 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, arg4);
283 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_pow);
284 hi = split_emit(J, IRT(IR_HIOP, LJ_SOFTFP), tmp, tmp);
285 break;
286 }
287 }
288 }
289 hi = split_call_l(J, hisubst, oir, ir, IRCALL_lj_vm_floor + ir->op2);
290 break;
291 case IR_ATAN2:
292 hi = split_call_ll(J, hisubst, oir, ir, IRCALL_atan2);
293 break;
294 case IR_LDEXP:
295 hi = split_call_li(J, hisubst, oir, ir, IRCALL_ldexp);
296 break;
297 case IR_NEG: case IR_ABS:
298 nir->o = IR_CONV; /* Pass through loword. */
299 nir->op2 = (IRT_INT << 5) | IRT_INT;
300 hi = split_emit(J, IRT(ir->o == IR_NEG ? IR_BXOR : IR_BAND, IRT_SOFTFP),
301 hisubst[ir->op1], hisubst[ir->op2]);
302 break;
303 case IR_SLOAD:
304 if ((nir->op2 & IRSLOAD_CONVERT)) { /* Convert from int to number. */
305 nir->op2 &= ~IRSLOAD_CONVERT;
306 ir->prev = nref = split_emit(J, IRTI(IR_CALLN), nref,
307 IRCALL_softfp_i2d);
308 hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
309 break;
310 }
311 /* fallthrough */
312 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
313 case IR_STRTO:
314 hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
315 break;
316 case IR_XLOAD: {
317 IRIns inslo = *nir; /* Save/undo the emit of the lo XLOAD. */
318 J->cur.nins--;
319 hi = split_ptr(J, oir, ir->op1); /* Insert the hiref ADD. */
320 nref = lj_ir_nextins(J);
321 nir = IR(nref);
322 *nir = inslo; /* Re-emit lo XLOAD immediately before hi XLOAD. */
323 hi = split_emit(J, IRT(IR_XLOAD, IRT_SOFTFP), hi, ir->op2);
324#if LJ_LE
325 ir->prev = nref;
326#else
327 ir->prev = hi; hi = nref;
328#endif
329 break;
330 }
331 case IR_ASTORE: case IR_HSTORE: case IR_USTORE:
332 split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nir->op1, hisubst[ir->op2]);
333 break;
334 case IR_XSTORE: {
335#if LJ_LE
336 IRRef hiref = hisubst[ir->op2];
337#else
338 IRRef hiref = nir->op2; nir->op2 = hisubst[ir->op2];
339#endif
340 split_emit(J, IRT(IR_XSTORE, IRT_SOFTFP),
341 split_ptr(J, oir, ir->op1), hiref);
342 break;
343 }
344 case IR_CONV: { /* Conversion to number. Others handled below. */
345 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
346 UNUSED(st);
347#if LJ_32 && LJ_HASFFI
348 if (st == IRT_I64 || st == IRT_U64) {
349 hi = split_call_l(J, hisubst, oir, ir,
350 st == IRT_I64 ? IRCALL_fp64_l2d : IRCALL_fp64_ul2d);
351 break;
352 }
353#endif
354 lua_assert(st == IRT_INT ||
355 (LJ_32 && LJ_HASFFI && (st == IRT_U32 || st == IRT_FLOAT)));
356 nir->o = IR_CALLN;
357#if LJ_32 && LJ_HASFFI
358 nir->op2 = st == IRT_INT ? IRCALL_softfp_i2d :
359 st == IRT_FLOAT ? IRCALL_softfp_f2d :
360 IRCALL_softfp_ui2d;
361#else
362 nir->op2 = IRCALL_softfp_i2d;
363#endif
364 hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
365 break;
366 }
367 case IR_CALLS:
368 case IR_CALLXS:
369 goto split_call;
370 case IR_PHI:
371 if (nir->op1 == nir->op2)
372 J->cur.nins--; /* Drop useless PHIs. */
373 if (hisubst[ir->op1] != hisubst[ir->op2])
374 split_emit(J, IRT(IR_PHI, IRT_SOFTFP),
375 hisubst[ir->op1], hisubst[ir->op2]);
376 break;
377 default:
378 lua_assert(ir->o <= IR_NE || ir->o == IR_MIN || ir->o == IR_MAX);
379 hi = split_emit(J, IRTG(IR_HIOP, IRT_SOFTFP),
380 hisubst[ir->op1], hisubst[ir->op2]);
381 break;
382 }
383 } else
384#endif
385#if LJ_32 && LJ_HASFFI
386 if (irt_isint64(ir->t)) {
387 IRRef hiref = hisubst[ir->op1];
388 nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */
389 switch (ir->o) {
390 case IR_ADD:
391 case IR_SUB:
392 /* Use plain op for hiword if loword cannot produce a carry/borrow. */
393 if (irref_isk(nir->op2) && IR(nir->op2)->i == 0) {
394 ir->prev = nir->op1; /* Pass through loword. */
395 nir->op1 = hiref; nir->op2 = hisubst[ir->op2];
396 hi = nref;
397 break;
398 }
399 /* fallthrough */
400 case IR_NEG:
401 hi = split_emit(J, IRTI(IR_HIOP), hiref, hisubst[ir->op2]);
402 break;
403 case IR_MUL:
404 hi = split_call_ll(J, hisubst, oir, ir, IRCALL_lj_carith_mul64);
405 break;
406 case IR_DIV:
407 hi = split_call_ll(J, hisubst, oir, ir,
408 irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 :
409 IRCALL_lj_carith_divu64);
410 break;
411 case IR_MOD:
412 hi = split_call_ll(J, hisubst, oir, ir,
413 irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 :
414 IRCALL_lj_carith_modu64);
415 break;
416 case IR_POW:
417 hi = split_call_ll(J, hisubst, oir, ir,
418 irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
419 IRCALL_lj_carith_powu64);
420 break;
421 case IR_FLOAD:
422 lua_assert(ir->op2 == IRFL_CDATA_INT64);
423 hi = split_emit(J, IRTI(IR_FLOAD), nir->op1, IRFL_CDATA_INT64_4);
424#if LJ_BE
425 ir->prev = hi; hi = nref;
426#endif
427 break;
428 case IR_XLOAD:
429 hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, oir, ir->op1), ir->op2);
430#if LJ_BE
431 ir->prev = hi; hi = nref;
432#endif
433 break;
434 case IR_XSTORE:
435#if LJ_LE
436 hiref = hisubst[ir->op2];
437#else
438 hiref = nir->op2; nir->op2 = hisubst[ir->op2];
439#endif
440 split_emit(J, IRTI(IR_XSTORE), split_ptr(J, oir, ir->op1), hiref);
441 break;
442 case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */
443 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
444#if LJ_SOFTFP
445 if (st == IRT_NUM) { /* NUM to 64 bit int conv. */
446 hi = split_call_l(J, hisubst, oir, ir,
447 irt_isi64(ir->t) ? IRCALL_fp64_d2l : IRCALL_fp64_d2ul);
448 } else if (st == IRT_FLOAT) { /* FLOAT to 64 bit int conv. */
449 nir->o = IR_CALLN;
450 nir->op2 = irt_isi64(ir->t) ? IRCALL_fp64_f2l : IRCALL_fp64_f2ul;
451 hi = split_emit(J, IRTI(IR_HIOP), nref, nref);
452 }
453#else
454 if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */
455 hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref);
456 }
457#endif
458 else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */
459 /* Drop cast, since assembler doesn't care. */
460 goto fwdlo;
461 } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */
462 IRRef k31 = lj_ir_kint(J, 31);
463 nir = IR(nref); /* May have been reallocated. */
464 ir->prev = nir->op1; /* Pass through loword. */
465 nir->o = IR_BSAR; /* hi = bsar(lo, 31). */
466 nir->op2 = k31;
467 hi = nref;
468 } else { /* Zero-extend to 64 bit. */
469 hi = lj_ir_kint(J, 0);
470 goto fwdlo;
471 }
472 break;
473 }
474 case IR_CALLXS:
475 goto split_call;
476 case IR_PHI: {
477 IRRef hiref2;
478 if ((irref_isk(nir->op1) && irref_isk(nir->op2)) ||
479 nir->op1 == nir->op2)
480 J->cur.nins--; /* Drop useless PHIs. */
481 hiref2 = hisubst[ir->op2];
482 if (!((irref_isk(hiref) && irref_isk(hiref2)) || hiref == hiref2))
483 split_emit(J, IRTI(IR_PHI), hiref, hiref2);
484 break;
485 }
486 default:
487 lua_assert(ir->o <= IR_NE); /* Comparisons. */
488 split_emit(J, IRTGI(IR_HIOP), hiref, hisubst[ir->op2]);
489 break;
490 }
491 } else
492#endif
493#if LJ_SOFTFP
494 if (ir->o == IR_SLOAD) {
495 if ((nir->op2 & IRSLOAD_CONVERT)) { /* Convert from number to int. */
496 nir->op2 &= ~IRSLOAD_CONVERT;
497 if (!(nir->op2 & IRSLOAD_TYPECHECK))
498 nir->t.irt = IRT_INT; /* Drop guard. */
499 split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
500 ir->prev = split_num2int(J, nref, nref+1, irt_isguard(ir->t));
501 }
502 } else if (ir->o == IR_TOBIT) {
503 IRRef tmp, op1 = ir->op1;
504 J->cur.nins--;
505#if LJ_LE
506 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]);
507#else
508 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
509#endif
510 ir->prev = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_lj_vm_tobit);
511 } else if (ir->o == IR_TOSTR) {
512 if (hisubst[ir->op1]) {
513 if (irref_isk(ir->op1))
514 nir->op1 = ir->op1;
515 else
516 split_emit(J, IRT(IR_HIOP, IRT_NIL), hisubst[ir->op1], nref);
517 }
518 } else if (ir->o == IR_HREF || ir->o == IR_NEWREF) {
519 if (irref_isk(ir->op2) && hisubst[ir->op2])
520 nir->op2 = ir->op2;
521 } else
522#endif
523 if (ir->o == IR_CONV) { /* See above, too. */
524 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
525#if LJ_32 && LJ_HASFFI
526 if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */
527#if LJ_SOFTFP
528 if (irt_isfloat(ir->t)) {
529 split_call_l(J, hisubst, oir, ir,
530 st == IRT_I64 ? IRCALL_fp64_l2f : IRCALL_fp64_ul2f);
531 J->cur.nins--; /* Drop unused HIOP. */
532 }
533#else
534 if (irt_isfp(ir->t)) { /* 64 bit integer to FP conversion. */
535 ir->prev = split_emit(J, IRT(IR_HIOP, irt_type(ir->t)),
536 hisubst[ir->op1], nref);
537 }
538#endif
539 else { /* Truncate to lower 32 bits. */
540 fwdlo:
541 ir->prev = nir->op1; /* Forward loword. */
542 /* Replace with NOP to avoid messing up the snapshot logic. */
543 nir->ot = IRT(IR_NOP, IRT_NIL);
544 nir->op1 = nir->op2 = 0;
545 }
546 }
547#endif
548#if LJ_SOFTFP && LJ_32 && LJ_HASFFI
549 else if (irt_isfloat(ir->t)) {
550 if (st == IRT_NUM) {
551 split_call_l(J, hisubst, oir, ir, IRCALL_softfp_d2f);
552 J->cur.nins--; /* Drop unused HIOP. */
553 } else {
554 nir->o = IR_CALLN;
555 nir->op2 = st == IRT_INT ? IRCALL_softfp_i2f : IRCALL_softfp_ui2f;
556 }
557 } else if (st == IRT_FLOAT) {
558 nir->o = IR_CALLN;
559 nir->op2 = irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui;
560 } else
561#endif
562#if LJ_SOFTFP
563 if (st == IRT_NUM || (LJ_32 && LJ_HASFFI && st == IRT_FLOAT)) {
564 if (irt_isguard(ir->t)) {
565 lua_assert(st == IRT_NUM && irt_isint(ir->t));
566 J->cur.nins--;
567 ir->prev = split_num2int(J, nir->op1, hisubst[ir->op1], 1);
568 } else {
569 split_call_l(J, hisubst, oir, ir,
570#if LJ_32 && LJ_HASFFI
571 st == IRT_NUM ?
572 (irt_isint(ir->t) ? IRCALL_softfp_d2i : IRCALL_softfp_d2ui) :
573 (irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui)
574#else
575 IRCALL_softfp_d2i
576#endif
577 );
578 J->cur.nins--; /* Drop unused HIOP. */
579 }
580 }
581#endif
582 } else if (ir->o == IR_CALLXS) {
583 IRRef hiref;
584 split_call:
585 hiref = hisubst[ir->op1];
586 if (hiref) {
587 IROpT ot = nir->ot;
588 IRRef op2 = nir->op2;
589 nir->ot = IRT(IR_CARG, IRT_NIL);
590#if LJ_LE
591 nir->op2 = hiref;
592#else
593 nir->op2 = nir->op1; nir->op1 = hiref;
594#endif
595 ir->prev = nref = split_emit(J, ot, nref, op2);
596 }
597 if (LJ_SOFTFP ? irt_is64(ir->t) : irt_isint64(ir->t))
598 hi = split_emit(J,
599 IRT(IR_HIOP, (LJ_SOFTFP && irt_isnum(ir->t)) ? IRT_SOFTFP : IRT_INT),
600 nref, nref);
601 } else if (ir->o == IR_CARG) {
602 IRRef hiref = hisubst[ir->op1];
603 if (hiref) {
604 IRRef op2 = nir->op2;
605#if LJ_LE
606 nir->op2 = hiref;
607#else
608 nir->op2 = nir->op1; nir->op1 = hiref;
609#endif
610 ir->prev = nref = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, op2);
611 nir = IR(nref);
612 }
613 hiref = hisubst[ir->op2];
614 if (hiref) {
615#if !LJ_TARGET_X86
616 int carg = 0;
617 IRIns *cir;
618 for (cir = IR(nir->op1); cir->o == IR_CARG; cir = IR(cir->op1))
619 carg++;
620 if ((carg & 1) == 0) { /* Align 64 bit arguments. */
621 IRRef op2 = nir->op2;
622 nir->op2 = REF_NIL;
623 nref = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, op2);
624 nir = IR(nref);
625 }
626#endif
627#if LJ_BE
628 { IRRef tmp = nir->op2; nir->op2 = hiref; hiref = tmp; }
629#endif
630 ir->prev = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, hiref);
631 }
632 } else if (ir->o == IR_CNEWI) {
633 if (hisubst[ir->op2])
634 split_emit(J, IRT(IR_HIOP, IRT_NIL), nref, hisubst[ir->op2]);
635 } else if (ir->o == IR_LOOP) {
636 J->loopref = nref; /* Needed by assembler. */
637 }
638 hisubst[ref] = hi; /* Store hiword substitution. */
639 }
640
641 /* Add PHI marks. */
642 for (ref = J->cur.nins-1; ref >= REF_FIRST; ref--) {
643 IRIns *ir = IR(ref);
644 if (ir->o != IR_PHI) break;
645 if (!irref_isk(ir->op1)) irt_setphi(IR(ir->op1)->t);
646 if (ir->op2 > J->loopref) irt_setphi(IR(ir->op2)->t);
647 }
648
649 /* Substitute snapshot maps. */
650 oir[nins].prev = J->cur.nins; /* Substitution for last snapshot. */
651 {
652 SnapNo i, nsnap = J->cur.nsnap;
653 for (i = 0; i < nsnap; i++) {
654 SnapShot *snap = &J->cur.snap[i];
655 SnapEntry *map = &J->cur.snapmap[snap->mapofs];
656 MSize n, nent = snap->nent;
657 snap->ref = snap->ref == REF_FIRST ? REF_FIRST : oir[snap->ref].prev;
658 for (n = 0; n < nent; n++) {
659 SnapEntry sn = map[n];
660 IRIns *ir = &oir[snap_ref(sn)];
661 if (!(LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))))
662 map[n] = ((sn & 0xffff0000) | ir->prev);
663 }
664 }
665 }
666}
667
668/* Protected callback for split pass. */
669static TValue *cpsplit(lua_State *L, lua_CFunction dummy, void *ud)
670{
671 jit_State *J = (jit_State *)ud;
672 split_ir(J);
673 UNUSED(L); UNUSED(dummy);
674 return NULL;
675}
676
677#if defined(LUA_USE_ASSERT) || LJ_SOFTFP
678/* Slow, but sure way to check whether a SPLIT pass is needed. */
679static int split_needsplit(jit_State *J)
680{
681 IRIns *ir, *irend;
682 IRRef ref;
683 for (ir = IR(REF_FIRST), irend = IR(J->cur.nins); ir < irend; ir++)
684 if (LJ_SOFTFP ? irt_is64orfp(ir->t) : irt_isint64(ir->t))
685 return 1;
686 if (LJ_SOFTFP) {
687 for (ref = J->chain[IR_SLOAD]; ref; ref = IR(ref)->prev)
688 if ((IR(ref)->op2 & IRSLOAD_CONVERT))
689 return 1;
690 }
691 for (ref = J->chain[IR_CONV]; ref; ref = IR(ref)->prev) {
692 IRType st = (IR(ref)->op2 & IRCONV_SRCMASK);
693 if ((LJ_SOFTFP && (st == IRT_NUM || st == IRT_FLOAT)) ||
694 st == IRT_I64 || st == IRT_U64)
695 return 1;
696 }
697 return 0; /* Nope. */
698}
699#endif
700
701/* SPLIT pass. */
702void lj_opt_split(jit_State *J)
703{
704#if LJ_SOFTFP
705 if (!J->needsplit)
706 J->needsplit = split_needsplit(J);
707#else
708 lua_assert(J->needsplit >= split_needsplit(J)); /* Verify flag. */
709#endif
710 if (J->needsplit) {
711 int errcode = lj_vm_cpcall(J->L, NULL, J, cpsplit);
712 if (errcode) {
713 /* Completely reset the trace to avoid inconsistent dump on abort. */
714 J->cur.nins = J->cur.nk = REF_BASE;
715 J->cur.nsnap = 0;
716 lj_err_throw(J->L, errcode); /* Propagate errors. */
717 }
718 }
719}
720
721#undef IR
722
723#endif
diff --git a/libraries/luajit-2.0/src/lj_parse.c b/libraries/luajit-2.0/src/lj_parse.c
new file mode 100644
index 0000000..4b8a8e6
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_parse.c
@@ -0,0 +1,2511 @@
1/*
2** Lua parser (source code -> bytecode).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lj_parse_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_debug.h"
16#include "lj_str.h"
17#include "lj_tab.h"
18#include "lj_func.h"
19#include "lj_state.h"
20#include "lj_bc.h"
21#if LJ_HASFFI
22#include "lj_ctype.h"
23#endif
24#include "lj_lex.h"
25#include "lj_parse.h"
26#include "lj_vm.h"
27#include "lj_vmevent.h"
28
29/* -- Parser structures and definitions ----------------------------------- */
30
31/* Expression kinds. */
32typedef enum {
33 /* Constant expressions must be first and in this order: */
34 VKNIL,
35 VKFALSE,
36 VKTRUE,
37 VKSTR, /* sval = string value */
38 VKNUM, /* nval = number value */
39 VKLAST = VKNUM,
40 VKCDATA, /* nval = cdata value, not treated as a constant expression */
41 /* Non-constant expressions follow: */
42 VLOCAL, /* info = local register */
43 VUPVAL, /* info = upvalue index */
44 VGLOBAL, /* sval = string value */
45 VINDEXED, /* info = table register, aux = index reg/byte/string const */
46 VJMP, /* info = instruction PC */
47 VRELOCABLE, /* info = instruction PC */
48 VNONRELOC, /* info = result register */
49 VCALL, /* info = instruction PC, aux = base */
50 VVOID
51} ExpKind;
52
53/* Expression descriptor. */
54typedef struct ExpDesc {
55 union {
56 struct {
57 uint32_t info; /* Primary info. */
58 uint32_t aux; /* Secondary info. */
59 } s;
60 TValue nval; /* Number value. */
61 GCstr *sval; /* String value. */
62 } u;
63 ExpKind k;
64 BCPos t; /* True condition jump list. */
65 BCPos f; /* False condition jump list. */
66} ExpDesc;
67
68/* Macros for expressions. */
69#define expr_hasjump(e) ((e)->t != (e)->f)
70
71#define expr_isk(e) ((e)->k <= VKLAST)
72#define expr_isk_nojump(e) (expr_isk(e) && !expr_hasjump(e))
73#define expr_isnumk(e) ((e)->k == VKNUM)
74#define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e))
75#define expr_isstrk(e) ((e)->k == VKSTR)
76
77#define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval)
78#define expr_numberV(e) numberVnum(expr_numtv((e)))
79
80/* Initialize expression. */
81static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info)
82{
83 e->k = k;
84 e->u.s.info = info;
85 e->f = e->t = NO_JMP;
86}
87
88/* Check number constant for +-0. */
89static int expr_numiszero(ExpDesc *e)
90{
91 TValue *o = expr_numtv(e);
92 return tvisint(o) ? (intV(o) == 0) : tviszero(o);
93}
94
95/* Per-function linked list of scope blocks. */
96typedef struct FuncScope {
97 struct FuncScope *prev; /* Link to outer scope. */
98 BCPos breaklist; /* Jump list for loop breaks. */
99 uint8_t nactvar; /* Number of active vars outside the scope. */
100 uint8_t upval; /* Some variable in the scope is an upvalue. */
101 uint8_t isbreakable; /* Scope is a loop and allows a break. */
102} FuncScope;
103
104/* Index into variable stack. */
105typedef uint16_t VarIndex;
106#define LJ_MAX_VSTACK 65536
107
108/* Upvalue map. */
109typedef struct UVMap {
110 VarIndex vidx; /* Varinfo index. */
111 uint16_t slot; /* Slot or parent upvalue index. */
112} UVMap;
113
114/* Per-function state. */
115typedef struct FuncState {
116 GCtab *kt; /* Hash table for constants. */
117 LexState *ls; /* Lexer state. */
118 lua_State *L; /* Lua state. */
119 FuncScope *bl; /* Current scope. */
120 struct FuncState *prev; /* Enclosing function. */
121 BCPos pc; /* Next bytecode position. */
122 BCPos lasttarget; /* Bytecode position of last jump target. */
123 BCPos jpc; /* Pending jump list to next bytecode. */
124 BCReg freereg; /* First free register. */
125 BCReg nactvar; /* Number of active local variables. */
126 BCReg nkn, nkgc; /* Number of lua_Number/GCobj constants */
127 BCLine linedefined; /* First line of the function definition. */
128 BCInsLine *bcbase; /* Base of bytecode stack. */
129 BCPos bclim; /* Limit of bytecode stack. */
130 MSize vbase; /* Base of variable stack for this function. */
131 uint8_t flags; /* Prototype flags. */
132 uint8_t numparams; /* Number of parameters. */
133 uint8_t framesize; /* Fixed frame size. */
134 uint8_t nuv; /* Number of upvalues */
135 VarIndex varmap[LJ_MAX_LOCVAR]; /* Map from register to variable idx. */
136 UVMap uvloc[LJ_MAX_UPVAL]; /* Map from upvalue to variable idx and slot. */
137} FuncState;
138
139/* Binary and unary operators. ORDER OPR */
140typedef enum BinOpr {
141 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, /* ORDER ARITH */
142 OPR_CONCAT,
143 OPR_NE, OPR_EQ,
144 OPR_LT, OPR_GE, OPR_LE, OPR_GT,
145 OPR_AND, OPR_OR,
146 OPR_NOBINOPR
147} BinOpr;
148
149LJ_STATIC_ASSERT((int)BC_ISGE-(int)BC_ISLT == (int)OPR_GE-(int)OPR_LT);
150LJ_STATIC_ASSERT((int)BC_ISLE-(int)BC_ISLT == (int)OPR_LE-(int)OPR_LT);
151LJ_STATIC_ASSERT((int)BC_ISGT-(int)BC_ISLT == (int)OPR_GT-(int)OPR_LT);
152LJ_STATIC_ASSERT((int)BC_SUBVV-(int)BC_ADDVV == (int)OPR_SUB-(int)OPR_ADD);
153LJ_STATIC_ASSERT((int)BC_MULVV-(int)BC_ADDVV == (int)OPR_MUL-(int)OPR_ADD);
154LJ_STATIC_ASSERT((int)BC_DIVVV-(int)BC_ADDVV == (int)OPR_DIV-(int)OPR_ADD);
155LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD);
156
157/* -- Error handling ------------------------------------------------------ */
158
159LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em)
160{
161 lj_lex_error(ls, ls->token, em);
162}
163
164LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken token)
165{
166 lj_lex_error(ls, ls->token, LJ_ERR_XTOKEN, lj_lex_token2str(ls, token));
167}
168
169LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what)
170{
171 if (fs->linedefined == 0)
172 lj_lex_error(fs->ls, 0, LJ_ERR_XLIMM, limit, what);
173 else
174 lj_lex_error(fs->ls, 0, LJ_ERR_XLIMF, fs->linedefined, limit, what);
175}
176
177#define checklimit(fs, v, l, m) if ((v) >= (l)) err_limit(fs, l, m)
178#define checklimitgt(fs, v, l, m) if ((v) > (l)) err_limit(fs, l, m)
179#define checkcond(ls, c, em) { if (!(c)) err_syntax(ls, em); }
180
181/* -- Management of constants --------------------------------------------- */
182
183/* Return bytecode encoding for primitive constant. */
184#define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k)
185
186#define tvhaskslot(o) ((o)->u32.hi == 0)
187#define tvkslot(o) ((o)->u32.lo)
188
189/* Add a number constant. */
190static BCReg const_num(FuncState *fs, ExpDesc *e)
191{
192 lua_State *L = fs->L;
193 TValue *o;
194 lua_assert(expr_isnumk(e));
195 o = lj_tab_set(L, fs->kt, &e->u.nval);
196 if (tvhaskslot(o))
197 return tvkslot(o);
198 o->u64 = fs->nkn;
199 return fs->nkn++;
200}
201
202/* Add a GC object constant. */
203static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype)
204{
205 lua_State *L = fs->L;
206 TValue key, *o;
207 setgcV(L, &key, gc, itype);
208 /* NOBARRIER: the key is new or kept alive. */
209 o = lj_tab_set(L, fs->kt, &key);
210 if (tvhaskslot(o))
211 return tvkslot(o);
212 o->u64 = fs->nkgc;
213 return fs->nkgc++;
214}
215
216/* Add a string constant. */
217static BCReg const_str(FuncState *fs, ExpDesc *e)
218{
219 lua_assert(expr_isstrk(e) || e->k == VGLOBAL);
220 return const_gc(fs, obj2gco(e->u.sval), LJ_TSTR);
221}
222
223/* Anchor string constant to avoid GC. */
224GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len)
225{
226 /* NOBARRIER: the key is new or kept alive. */
227 lua_State *L = ls->L;
228 GCstr *s = lj_str_new(L, str, len);
229 TValue *tv = lj_tab_setstr(L, ls->fs->kt, s);
230 if (tvisnil(tv)) setboolV(tv, 1);
231 lj_gc_check(L);
232 return s;
233}
234
235#if LJ_HASFFI
236/* Anchor cdata to avoid GC. */
237void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd)
238{
239 /* NOBARRIER: the key is new or kept alive. */
240 lua_State *L = ls->L;
241 setcdataV(L, tv, cd);
242 setboolV(lj_tab_set(L, ls->fs->kt, tv), 1);
243}
244#endif
245
246/* -- Jump list handling -------------------------------------------------- */
247
248/* Get next element in jump list. */
249static BCPos jmp_next(FuncState *fs, BCPos pc)
250{
251 ptrdiff_t delta = bc_j(fs->bcbase[pc].ins);
252 if ((BCPos)delta == NO_JMP)
253 return NO_JMP;
254 else
255 return (BCPos)(((ptrdiff_t)pc+1)+delta);
256}
257
258/* Check if any of the instructions on the jump list produce no value. */
259static int jmp_novalue(FuncState *fs, BCPos list)
260{
261 for (; list != NO_JMP; list = jmp_next(fs, list)) {
262 BCIns p = fs->bcbase[list >= 1 ? list-1 : list].ins;
263 if (!(bc_op(p) == BC_ISTC || bc_op(p) == BC_ISFC || bc_a(p) == NO_REG))
264 return 1;
265 }
266 return 0;
267}
268
269/* Patch register of test instructions. */
270static int jmp_patchtestreg(FuncState *fs, BCPos pc, BCReg reg)
271{
272 BCIns *ip = &fs->bcbase[pc >= 1 ? pc-1 : pc].ins;
273 BCOp op = bc_op(*ip);
274 if (op == BC_ISTC || op == BC_ISFC) {
275 if (reg != NO_REG && reg != bc_d(*ip)) {
276 setbc_a(ip, reg);
277 } else { /* Nothing to store or already in the right register. */
278 setbc_op(ip, op+(BC_IST-BC_ISTC));
279 setbc_a(ip, 0);
280 }
281 } else if (bc_a(*ip) == NO_REG) {
282 if (reg == NO_REG)
283 *ip = BCINS_AJ(BC_JMP, bc_a(fs->bcbase[pc].ins), 0);
284 else
285 setbc_a(ip, reg);
286 } else {
287 return 0; /* Cannot patch other instructions. */
288 }
289 return 1;
290}
291
292/* Drop values for all instructions on jump list. */
293static void jmp_dropval(FuncState *fs, BCPos list)
294{
295 for (; list != NO_JMP; list = jmp_next(fs, list))
296 jmp_patchtestreg(fs, list, NO_REG);
297}
298
299/* Patch jump instruction to target. */
300static void jmp_patchins(FuncState *fs, BCPos pc, BCPos dest)
301{
302 BCIns *jmp = &fs->bcbase[pc].ins;
303 BCPos offset = dest-(pc+1)+BCBIAS_J;
304 lua_assert(dest != NO_JMP);
305 if (offset > BCMAX_D)
306 err_syntax(fs->ls, LJ_ERR_XJUMP);
307 setbc_d(jmp, offset);
308}
309
310/* Append to jump list. */
311static void jmp_append(FuncState *fs, BCPos *l1, BCPos l2)
312{
313 if (l2 == NO_JMP) {
314 return;
315 } else if (*l1 == NO_JMP) {
316 *l1 = l2;
317 } else {
318 BCPos list = *l1;
319 BCPos next;
320 while ((next = jmp_next(fs, list)) != NO_JMP) /* Find last element. */
321 list = next;
322 jmp_patchins(fs, list, l2);
323 }
324}
325
326/* Patch jump list and preserve produced values. */
327static void jmp_patchval(FuncState *fs, BCPos list, BCPos vtarget,
328 BCReg reg, BCPos dtarget)
329{
330 while (list != NO_JMP) {
331 BCPos next = jmp_next(fs, list);
332 if (jmp_patchtestreg(fs, list, reg))
333 jmp_patchins(fs, list, vtarget); /* Jump to target with value. */
334 else
335 jmp_patchins(fs, list, dtarget); /* Jump to default target. */
336 list = next;
337 }
338}
339
340/* Jump to following instruction. Append to list of pending jumps. */
341static void jmp_tohere(FuncState *fs, BCPos list)
342{
343 fs->lasttarget = fs->pc;
344 jmp_append(fs, &fs->jpc, list);
345}
346
347/* Patch jump list to target. */
348static void jmp_patch(FuncState *fs, BCPos list, BCPos target)
349{
350 if (target == fs->pc) {
351 jmp_tohere(fs, list);
352 } else {
353 lua_assert(target < fs->pc);
354 jmp_patchval(fs, list, target, NO_REG, target);
355 }
356}
357
358/* -- Bytecode register allocator ----------------------------------------- */
359
360/* Bump frame size. */
361static void bcreg_bump(FuncState *fs, BCReg n)
362{
363 BCReg sz = fs->freereg + n;
364 if (sz > fs->framesize) {
365 if (sz >= LJ_MAX_SLOTS)
366 err_syntax(fs->ls, LJ_ERR_XSLOTS);
367 fs->framesize = (uint8_t)sz;
368 }
369}
370
371/* Reserve registers. */
372static void bcreg_reserve(FuncState *fs, BCReg n)
373{
374 bcreg_bump(fs, n);
375 fs->freereg += n;
376}
377
378/* Free register. */
379static void bcreg_free(FuncState *fs, BCReg reg)
380{
381 if (reg >= fs->nactvar) {
382 fs->freereg--;
383 lua_assert(reg == fs->freereg);
384 }
385}
386
387/* Free register for expression. */
388static void expr_free(FuncState *fs, ExpDesc *e)
389{
390 if (e->k == VNONRELOC)
391 bcreg_free(fs, e->u.s.info);
392}
393
394/* -- Bytecode emitter ---------------------------------------------------- */
395
396/* Emit bytecode instruction. */
397static BCPos bcemit_INS(FuncState *fs, BCIns ins)
398{
399 BCPos pc = fs->pc;
400 LexState *ls = fs->ls;
401 jmp_patchval(fs, fs->jpc, pc, NO_REG, pc);
402 fs->jpc = NO_JMP;
403 if (LJ_UNLIKELY(pc >= fs->bclim)) {
404 ptrdiff_t base = fs->bcbase - ls->bcstack;
405 checklimit(fs, ls->sizebcstack, LJ_MAX_BCINS, "bytecode instructions");
406 lj_mem_growvec(fs->L, ls->bcstack, ls->sizebcstack, LJ_MAX_BCINS,BCInsLine);
407 fs->bclim = (BCPos)(ls->sizebcstack - base);
408 fs->bcbase = ls->bcstack + base;
409 }
410 fs->bcbase[pc].ins = ins;
411 fs->bcbase[pc].line = ls->lastline;
412 fs->pc = pc+1;
413 return pc;
414}
415
416#define bcemit_ABC(fs, o, a, b, c) bcemit_INS(fs, BCINS_ABC(o, a, b, c))
417#define bcemit_AD(fs, o, a, d) bcemit_INS(fs, BCINS_AD(o, a, d))
418#define bcemit_AJ(fs, o, a, j) bcemit_INS(fs, BCINS_AJ(o, a, j))
419
420#define bcptr(fs, e) (&(fs)->bcbase[(e)->u.s.info].ins)
421
422/* -- Bytecode emitter for expressions ------------------------------------ */
423
424/* Discharge non-constant expression to any register. */
425static void expr_discharge(FuncState *fs, ExpDesc *e)
426{
427 BCIns ins;
428 if (e->k == VUPVAL) {
429 ins = BCINS_AD(BC_UGET, 0, e->u.s.info);
430 } else if (e->k == VGLOBAL) {
431 ins = BCINS_AD(BC_GGET, 0, const_str(fs, e));
432 } else if (e->k == VINDEXED) {
433 BCReg rc = e->u.s.aux;
434 if ((int32_t)rc < 0) {
435 ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc);
436 } else if (rc > BCMAX_C) {
437 ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1));
438 } else {
439 bcreg_free(fs, rc);
440 ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc);
441 }
442 bcreg_free(fs, e->u.s.info);
443 } else if (e->k == VCALL) {
444 e->u.s.info = e->u.s.aux;
445 e->k = VNONRELOC;
446 return;
447 } else if (e->k == VLOCAL) {
448 e->k = VNONRELOC;
449 return;
450 } else {
451 return;
452 }
453 e->u.s.info = bcemit_INS(fs, ins);
454 e->k = VRELOCABLE;
455}
456
457/* Emit bytecode to set a range of registers to nil. */
458static void bcemit_nil(FuncState *fs, BCReg from, BCReg n)
459{
460 if (fs->pc > fs->lasttarget) { /* No jumps to current position? */
461 BCIns *ip = &fs->bcbase[fs->pc-1].ins;
462 BCReg pto, pfrom = bc_a(*ip);
463 switch (bc_op(*ip)) { /* Try to merge with the previous instruction. */
464 case BC_KPRI:
465 if (bc_d(*ip) != ~LJ_TNIL) break;
466 if (from == pfrom) {
467 if (n == 1) return;
468 } else if (from == pfrom+1) {
469 from = pfrom;
470 n++;
471 } else {
472 break;
473 }
474 fs->pc--; /* Drop KPRI. */
475 break;
476 case BC_KNIL:
477 pto = bc_d(*ip);
478 if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */
479 if (from+n-1 > pto)
480 setbc_d(ip, from+n-1); /* Patch previous instruction range. */
481 return;
482 }
483 break;
484 default:
485 break;
486 }
487 }
488 /* Emit new instruction or replace old instruction. */
489 bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) :
490 BCINS_AD(BC_KNIL, from, from+n-1));
491}
492
493/* Discharge an expression to a specific register. Ignore branches. */
494static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
495{
496 BCIns ins;
497 expr_discharge(fs, e);
498 if (e->k == VKSTR) {
499 ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e));
500 } else if (e->k == VKNUM) {
501#if LJ_DUALNUM
502 cTValue *tv = expr_numtv(e);
503 if (tvisint(tv) && checki16(intV(tv)))
504 ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv));
505 else
506#else
507 lua_Number n = expr_numberV(e);
508 int32_t k = lj_num2int(n);
509 if (checki16(k) && n == (lua_Number)k)
510 ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k);
511 else
512#endif
513 ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e));
514#if LJ_HASFFI
515 } else if (e->k == VKCDATA) {
516 fs->flags |= PROTO_FFI;
517 ins = BCINS_AD(BC_KCDATA, reg,
518 const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA));
519#endif
520 } else if (e->k == VRELOCABLE) {
521 setbc_a(bcptr(fs, e), reg);
522 goto noins;
523 } else if (e->k == VNONRELOC) {
524 if (reg == e->u.s.info)
525 goto noins;
526 ins = BCINS_AD(BC_MOV, reg, e->u.s.info);
527 } else if (e->k == VKNIL) {
528 bcemit_nil(fs, reg, 1);
529 goto noins;
530 } else if (e->k <= VKTRUE) {
531 ins = BCINS_AD(BC_KPRI, reg, const_pri(e));
532 } else {
533 lua_assert(e->k == VVOID || e->k == VJMP);
534 return;
535 }
536 bcemit_INS(fs, ins);
537noins:
538 e->u.s.info = reg;
539 e->k = VNONRELOC;
540}
541
542/* Forward declaration. */
543static BCPos bcemit_jmp(FuncState *fs);
544
545/* Discharge an expression to a specific register. */
546static void expr_toreg(FuncState *fs, ExpDesc *e, BCReg reg)
547{
548 expr_toreg_nobranch(fs, e, reg);
549 if (e->k == VJMP)
550 jmp_append(fs, &e->t, e->u.s.info); /* Add it to the true jump list. */
551 if (expr_hasjump(e)) { /* Discharge expression with branches. */
552 BCPos jend, jfalse = NO_JMP, jtrue = NO_JMP;
553 if (jmp_novalue(fs, e->t) || jmp_novalue(fs, e->f)) {
554 BCPos jval = (e->k == VJMP) ? NO_JMP : bcemit_jmp(fs);
555 jfalse = bcemit_AD(fs, BC_KPRI, reg, VKFALSE);
556 bcemit_AJ(fs, BC_JMP, fs->freereg, 1);
557 jtrue = bcemit_AD(fs, BC_KPRI, reg, VKTRUE);
558 jmp_tohere(fs, jval);
559 }
560 jend = fs->pc;
561 fs->lasttarget = jend;
562 jmp_patchval(fs, e->f, jend, reg, jfalse);
563 jmp_patchval(fs, e->t, jend, reg, jtrue);
564 }
565 e->f = e->t = NO_JMP;
566 e->u.s.info = reg;
567 e->k = VNONRELOC;
568}
569
570/* Discharge an expression to the next free register. */
571static void expr_tonextreg(FuncState *fs, ExpDesc *e)
572{
573 expr_discharge(fs, e);
574 expr_free(fs, e);
575 bcreg_reserve(fs, 1);
576 expr_toreg(fs, e, fs->freereg - 1);
577}
578
579/* Discharge an expression to any register. */
580static BCReg expr_toanyreg(FuncState *fs, ExpDesc *e)
581{
582 expr_discharge(fs, e);
583 if (e->k == VNONRELOC) {
584 if (!expr_hasjump(e)) return e->u.s.info; /* Already in a register. */
585 if (e->u.s.info >= fs->nactvar) {
586 expr_toreg(fs, e, e->u.s.info); /* Discharge to temp. register. */
587 return e->u.s.info;
588 }
589 }
590 expr_tonextreg(fs, e); /* Discharge to next register. */
591 return e->u.s.info;
592}
593
594/* Partially discharge expression to a value. */
595static void expr_toval(FuncState *fs, ExpDesc *e)
596{
597 if (expr_hasjump(e))
598 expr_toanyreg(fs, e);
599 else
600 expr_discharge(fs, e);
601}
602
603/* Emit store for LHS expression. */
604static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e)
605{
606 BCIns ins;
607 if (var->k == VLOCAL) {
608 expr_free(fs, e);
609 expr_toreg(fs, e, var->u.s.info);
610 return;
611 } else if (var->k == VUPVAL) {
612 expr_toval(fs, e);
613 if (e->k <= VKTRUE)
614 ins = BCINS_AD(BC_USETP, var->u.s.info, const_pri(e));
615 else if (e->k == VKSTR)
616 ins = BCINS_AD(BC_USETS, var->u.s.info, const_str(fs, e));
617 else if (e->k == VKNUM)
618 ins = BCINS_AD(BC_USETN, var->u.s.info, const_num(fs, e));
619 else
620 ins = BCINS_AD(BC_USETV, var->u.s.info, expr_toanyreg(fs, e));
621 } else if (var->k == VGLOBAL) {
622 BCReg ra = expr_toanyreg(fs, e);
623 ins = BCINS_AD(BC_GSET, ra, const_str(fs, var));
624 } else {
625 BCReg ra, rc;
626 lua_assert(var->k == VINDEXED);
627 ra = expr_toanyreg(fs, e);
628 rc = var->u.s.aux;
629 if ((int32_t)rc < 0) {
630 ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc);
631 } else if (rc > BCMAX_C) {
632 ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1));
633 } else {
634 /* Free late alloced key reg to avoid assert on free of value reg. */
635 /* This can only happen when called from expr_table(). */
636 lua_assert(e->k != VNONRELOC || ra < fs->nactvar ||
637 rc < ra || (bcreg_free(fs, rc),1));
638 ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc);
639 }
640 }
641 bcemit_INS(fs, ins);
642 expr_free(fs, e);
643}
644
645/* Emit method lookup expression. */
646static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key)
647{
648 BCReg idx, func, obj = expr_toanyreg(fs, e);
649 expr_free(fs, e);
650 func = fs->freereg;
651 bcemit_AD(fs, BC_MOV, func+1, obj); /* Copy object to first argument. */
652 lua_assert(expr_isstrk(key));
653 idx = const_str(fs, key);
654 if (idx <= BCMAX_C) {
655 bcreg_reserve(fs, 2);
656 bcemit_ABC(fs, BC_TGETS, func, obj, idx);
657 } else {
658 bcreg_reserve(fs, 3);
659 bcemit_AD(fs, BC_KSTR, func+2, idx);
660 bcemit_ABC(fs, BC_TGETV, func, obj, func+2);
661 fs->freereg--;
662 }
663 e->u.s.info = func;
664 e->k = VNONRELOC;
665}
666
667/* -- Bytecode emitter for branches --------------------------------------- */
668
669/* Emit unconditional branch. */
670static BCPos bcemit_jmp(FuncState *fs)
671{
672 BCPos jpc = fs->jpc;
673 BCPos j = fs->pc - 1;
674 BCIns *ip = &fs->bcbase[j].ins;
675 fs->jpc = NO_JMP;
676 if ((int32_t)j >= (int32_t)fs->lasttarget &&
677 bc_op(*ip) == BC_UCLO)
678 setbc_j(ip, NO_JMP);
679 else
680 j = bcemit_AJ(fs, BC_JMP, fs->freereg, NO_JMP);
681 jmp_append(fs, &j, jpc);
682 return j;
683}
684
685/* Invert branch condition of bytecode instruction. */
686static void invertcond(FuncState *fs, ExpDesc *e)
687{
688 BCIns *ip = &fs->bcbase[e->u.s.info - 1].ins;
689 setbc_op(ip, bc_op(*ip)^1);
690}
691
692/* Emit conditional branch. */
693static BCPos bcemit_branch(FuncState *fs, ExpDesc *e, int cond)
694{
695 BCPos pc;
696 if (e->k == VRELOCABLE) {
697 BCIns *ip = bcptr(fs, e);
698 if (bc_op(*ip) == BC_NOT) {
699 *ip = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*ip));
700 return bcemit_jmp(fs);
701 }
702 }
703 if (e->k != VNONRELOC) {
704 bcreg_reserve(fs, 1);
705 expr_toreg_nobranch(fs, e, fs->freereg-1);
706 }
707 bcemit_AD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info);
708 pc = bcemit_jmp(fs);
709 expr_free(fs, e);
710 return pc;
711}
712
713/* Emit branch on true condition. */
714static void bcemit_branch_t(FuncState *fs, ExpDesc *e)
715{
716 BCPos pc;
717 expr_discharge(fs, e);
718 if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
719 pc = NO_JMP; /* Never jump. */
720 else if (e->k == VJMP)
721 invertcond(fs, e), pc = e->u.s.info;
722 else if (e->k == VKFALSE || e->k == VKNIL)
723 expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
724 else
725 pc = bcemit_branch(fs, e, 0);
726 jmp_append(fs, &e->f, pc);
727 jmp_tohere(fs, e->t);
728 e->t = NO_JMP;
729}
730
731/* Emit branch on false condition. */
732static void bcemit_branch_f(FuncState *fs, ExpDesc *e)
733{
734 BCPos pc;
735 expr_discharge(fs, e);
736 if (e->k == VKNIL || e->k == VKFALSE)
737 pc = NO_JMP; /* Never jump. */
738 else if (e->k == VJMP)
739 pc = e->u.s.info;
740 else if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
741 expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
742 else
743 pc = bcemit_branch(fs, e, 1);
744 jmp_append(fs, &e->t, pc);
745 jmp_tohere(fs, e->f);
746 e->f = NO_JMP;
747}
748
749/* -- Bytecode emitter for operators -------------------------------------- */
750
751/* Try constant-folding of arithmetic operators. */
752static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2)
753{
754 TValue o;
755 lua_Number n;
756 if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0;
757 n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD);
758 setnumV(&o, n);
759 if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */
760 if (LJ_DUALNUM) {
761 int32_t k = lj_num2int(n);
762 if ((lua_Number)k == n) {
763 setintV(&e1->u.nval, k);
764 return 1;
765 }
766 }
767 setnumV(&e1->u.nval, n);
768 return 1;
769}
770
771/* Emit arithmetic operator. */
772static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
773{
774 BCReg rb, rc, t;
775 uint32_t op;
776 if (foldarith(opr, e1, e2))
777 return;
778 if (opr == OPR_POW) {
779 op = BC_POW;
780 rc = expr_toanyreg(fs, e2);
781 rb = expr_toanyreg(fs, e1);
782 } else {
783 op = opr-OPR_ADD+BC_ADDVV;
784 /* Must discharge 2nd operand first since VINDEXED might free regs. */
785 expr_toval(fs, e2);
786 if (expr_isnumk(e2) && (rc = const_num(fs, e2)) <= BCMAX_C)
787 op -= BC_ADDVV-BC_ADDVN;
788 else
789 rc = expr_toanyreg(fs, e2);
790 /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */
791 lua_assert(expr_isnumk(e1) || e1->k == VNONRELOC);
792 expr_toval(fs, e1);
793 /* Avoid two consts to satisfy bytecode constraints. */
794 if (expr_isnumk(e1) && !expr_isnumk(e2) &&
795 (t = const_num(fs, e1)) <= BCMAX_B) {
796 rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV;
797 } else {
798 rb = expr_toanyreg(fs, e1);
799 }
800 }
801 /* Using expr_free might cause asserts if the order is wrong. */
802 if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--;
803 if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
804 e1->u.s.info = bcemit_ABC(fs, op, 0, rb, rc);
805 e1->k = VRELOCABLE;
806}
807
808/* Emit comparison operator. */
809static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
810{
811 ExpDesc *eret = e1;
812 BCIns ins;
813 expr_toval(fs, e1);
814 if (opr == OPR_EQ || opr == OPR_NE) {
815 BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV;
816 BCReg ra;
817 if (expr_isk(e1)) { e1 = e2; e2 = eret; } /* Need constant in 2nd arg. */
818 ra = expr_toanyreg(fs, e1); /* First arg must be in a reg. */
819 expr_toval(fs, e2);
820 switch (e2->k) {
821 case VKNIL: case VKFALSE: case VKTRUE:
822 ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, const_pri(e2));
823 break;
824 case VKSTR:
825 ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, const_str(fs, e2));
826 break;
827 case VKNUM:
828 ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, const_num(fs, e2));
829 break;
830 default:
831 ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2));
832 break;
833 }
834 } else {
835 uint32_t op = opr-OPR_LT+BC_ISLT;
836 BCReg ra;
837 if ((op-BC_ISLT) & 1) { /* GT -> LT, GE -> LE */
838 e1 = e2; e2 = eret; /* Swap operands. */
839 op = ((op-BC_ISLT)^3)+BC_ISLT;
840 }
841 ra = expr_toanyreg(fs, e1);
842 ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2));
843 }
844 /* Using expr_free might cause asserts if the order is wrong. */
845 if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--;
846 if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
847 bcemit_INS(fs, ins);
848 eret->u.s.info = bcemit_jmp(fs);
849 eret->k = VJMP;
850}
851
852/* Fixup left side of binary operator. */
853static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e)
854{
855 if (op == OPR_AND) {
856 bcemit_branch_t(fs, e);
857 } else if (op == OPR_OR) {
858 bcemit_branch_f(fs, e);
859 } else if (op == OPR_CONCAT) {
860 expr_tonextreg(fs, e);
861 } else if (op == OPR_EQ || op == OPR_NE) {
862 if (!expr_isk_nojump(e)) expr_toanyreg(fs, e);
863 } else {
864 if (!expr_isnumk_nojump(e)) expr_toanyreg(fs, e);
865 }
866}
867
868/* Emit binary operator. */
869static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2)
870{
871 if (op <= OPR_POW) {
872 bcemit_arith(fs, op, e1, e2);
873 } else if (op == OPR_AND) {
874 lua_assert(e1->t == NO_JMP); /* List must be closed. */
875 expr_discharge(fs, e2);
876 jmp_append(fs, &e2->f, e1->f);
877 *e1 = *e2;
878 } else if (op == OPR_OR) {
879 lua_assert(e1->f == NO_JMP); /* List must be closed. */
880 expr_discharge(fs, e2);
881 jmp_append(fs, &e2->t, e1->t);
882 *e1 = *e2;
883 } else if (op == OPR_CONCAT) {
884 expr_toval(fs, e2);
885 if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) {
886 lua_assert(e1->u.s.info == bc_b(*bcptr(fs, e2))-1);
887 expr_free(fs, e1);
888 setbc_b(bcptr(fs, e2), e1->u.s.info);
889 e1->u.s.info = e2->u.s.info;
890 } else {
891 expr_tonextreg(fs, e2);
892 expr_free(fs, e2);
893 expr_free(fs, e1);
894 e1->u.s.info = bcemit_ABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info);
895 }
896 e1->k = VRELOCABLE;
897 } else {
898 lua_assert(op == OPR_NE || op == OPR_EQ ||
899 op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT);
900 bcemit_comp(fs, op, e1, e2);
901 }
902}
903
904/* Emit unary operator. */
905static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
906{
907 if (op == BC_NOT) {
908 /* Swap true and false lists. */
909 { BCPos temp = e->f; e->f = e->t; e->t = temp; }
910 jmp_dropval(fs, e->f);
911 jmp_dropval(fs, e->t);
912 expr_discharge(fs, e);
913 if (e->k == VKNIL || e->k == VKFALSE) {
914 e->k = VKTRUE;
915 return;
916 } else if (expr_isk(e) || (LJ_HASFFI && e->k == VKCDATA)) {
917 e->k = VKFALSE;
918 return;
919 } else if (e->k == VJMP) {
920 invertcond(fs, e);
921 return;
922 } else if (e->k == VRELOCABLE) {
923 bcreg_reserve(fs, 1);
924 setbc_a(bcptr(fs, e), fs->freereg-1);
925 e->u.s.info = fs->freereg-1;
926 e->k = VNONRELOC;
927 } else {
928 lua_assert(e->k == VNONRELOC);
929 }
930 } else {
931 lua_assert(op == BC_UNM || op == BC_LEN);
932 if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */
933#if LJ_HASFFI
934 if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */
935 GCcdata *cd = cdataV(&e->u.nval);
936 int64_t *p = (int64_t *)cdataptr(cd);
937 if (cd->typeid == CTID_COMPLEX_DOUBLE)
938 p[1] ^= (int64_t)U64x(80000000,00000000);
939 else
940 *p = -*p;
941 return;
942 } else
943#endif
944 if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */
945 TValue *o = expr_numtv(e);
946 if (tvisint(o)) {
947 int32_t k = intV(o);
948 if (k == -k)
949 setnumV(o, -(lua_Number)k);
950 else
951 setintV(o, -k);
952 return;
953 } else {
954 o->u64 ^= U64x(80000000,00000000);
955 return;
956 }
957 }
958 }
959 expr_toanyreg(fs, e);
960 }
961 expr_free(fs, e);
962 e->u.s.info = bcemit_AD(fs, op, 0, e->u.s.info);
963 e->k = VRELOCABLE;
964}
965
966/* -- Lexer support ------------------------------------------------------- */
967
968/* Check and consume optional token. */
969static int lex_opt(LexState *ls, LexToken tok)
970{
971 if (ls->token == tok) {
972 lj_lex_next(ls);
973 return 1;
974 }
975 return 0;
976}
977
978/* Check and consume token. */
979static void lex_check(LexState *ls, LexToken tok)
980{
981 if (ls->token != tok)
982 err_token(ls, tok);
983 lj_lex_next(ls);
984}
985
986/* Check for matching token. */
987static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line)
988{
989 if (!lex_opt(ls, what)) {
990 if (line == ls->linenumber) {
991 err_token(ls, what);
992 } else {
993 const char *swhat = lj_lex_token2str(ls, what);
994 const char *swho = lj_lex_token2str(ls, who);
995 lj_lex_error(ls, ls->token, LJ_ERR_XMATCH, swhat, swho, line);
996 }
997 }
998}
999
1000/* Check for string token. */
1001static GCstr *lex_str(LexState *ls)
1002{
1003 GCstr *s;
1004 if (ls->token != TK_name)
1005 err_token(ls, TK_name);
1006 s = strV(&ls->tokenval);
1007 lj_lex_next(ls);
1008 return s;
1009}
1010
1011/* -- Variable handling --------------------------------------------------- */
1012
1013#define var_get(ls, fs, i) ((ls)->vstack[(fs)->varmap[(i)]])
1014
1015/* Define a new local variable. */
1016static void var_new(LexState *ls, BCReg n, GCstr *name)
1017{
1018 FuncState *fs = ls->fs;
1019 MSize vtop = ls->vtop;
1020 checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables");
1021 if (LJ_UNLIKELY(vtop >= ls->sizevstack)) {
1022 if (ls->sizevstack >= LJ_MAX_VSTACK)
1023 lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK);
1024 lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo);
1025 }
1026 lua_assert((uintptr_t)name < VARNAME__MAX ||
1027 lj_tab_getstr(fs->kt, name) != NULL);
1028 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */
1029 setgcref(ls->vstack[vtop].name, obj2gco(name));
1030 fs->varmap[fs->nactvar+n] = (uint16_t)vtop;
1031 ls->vtop = vtop+1;
1032}
1033
1034#define var_new_lit(ls, n, v) \
1035 var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1))
1036
1037#define var_new_fixed(ls, n, vn) \
1038 var_new(ls, (n), (GCstr *)(uintptr_t)(vn))
1039
1040/* Add local variables. */
1041static void var_add(LexState *ls, BCReg nvars)
1042{
1043 FuncState *fs = ls->fs;
1044 fs->nactvar = (uint8_t)(fs->nactvar + nvars);
1045 for (; nvars; nvars--)
1046 var_get(ls, fs, fs->nactvar - nvars).startpc = fs->pc;
1047}
1048
1049/* Remove local variables. */
1050static void var_remove(LexState *ls, BCReg tolevel)
1051{
1052 FuncState *fs = ls->fs;
1053 while (fs->nactvar > tolevel)
1054 var_get(ls, fs, --fs->nactvar).endpc = fs->pc;
1055}
1056
1057/* Lookup local variable name. */
1058static BCReg var_lookup_local(FuncState *fs, GCstr *n)
1059{
1060 int i;
1061 for (i = fs->nactvar-1; i >= 0; i--) {
1062 if (n == strref(var_get(fs->ls, fs, i).name))
1063 return (BCReg)i;
1064 }
1065 return (BCReg)-1; /* Not found. */
1066}
1067
1068/* Lookup or add upvalue index. */
1069static MSize var_lookup_uv(FuncState *fs, MSize vidx, ExpDesc *e)
1070{
1071 MSize i, n = fs->nuv;
1072 for (i = 0; i < n; i++)
1073 if (fs->uvloc[i].vidx == vidx)
1074 return i; /* Already exists. */
1075 /* Otherwise create a new one. */
1076 checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues");
1077 lua_assert(e->k == VLOCAL || e->k == VUPVAL);
1078 fs->uvloc[n].vidx = (uint16_t)vidx;
1079 fs->uvloc[n].slot = (uint16_t)(e->u.s.info | (e->k == VLOCAL ? 0x8000 : 0));
1080 fs->nuv = n+1;
1081 return n;
1082}
1083
1084/* Forward declaration. */
1085static void scope_uvmark(FuncState *fs, BCReg level);
1086
1087/* Recursively lookup variables in enclosing functions. */
1088static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first)
1089{
1090 if (fs) {
1091 BCReg reg = var_lookup_local(fs, name);
1092 if ((int32_t)reg >= 0) { /* Local in this function? */
1093 expr_init(e, VLOCAL, reg);
1094 if (!first)
1095 scope_uvmark(fs, reg); /* Scope now has an upvalue. */
1096 return (MSize)fs->varmap[reg];
1097 } else {
1098 MSize vidx = var_lookup_(fs->prev, name, e, 0); /* Var in outer func? */
1099 if ((int32_t)vidx >= 0) { /* Yes, make it an upvalue here. */
1100 e->u.s.info = (uint8_t)var_lookup_uv(fs, vidx, e);
1101 e->k = VUPVAL;
1102 return vidx;
1103 }
1104 }
1105 } else { /* Not found in any function, must be a global. */
1106 expr_init(e, VGLOBAL, 0);
1107 e->u.sval = name;
1108 }
1109 return (MSize)-1; /* Global. */
1110}
1111
1112/* Lookup variable name. */
1113#define var_lookup(ls, e) \
1114 var_lookup_((ls)->fs, lex_str(ls), (e), 1)
1115
1116/* -- Function state management ------------------------------------------- */
1117
1118/* Fixup bytecode for prototype. */
1119static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n)
1120{
1121 BCInsLine *base = fs->bcbase;
1122 MSize i;
1123 pt->sizebc = n;
1124 bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
1125 fs->framesize, 0);
1126 for (i = 1; i < n; i++)
1127 bc[i] = base[i].ins;
1128}
1129
1130/* Fixup constants for prototype. */
1131static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr)
1132{
1133 GCtab *kt;
1134 TValue *array;
1135 Node *node;
1136 MSize i, hmask;
1137 checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants");
1138 checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants");
1139 setmref(pt->k, kptr);
1140 pt->sizekn = fs->nkn;
1141 pt->sizekgc = fs->nkgc;
1142 kt = fs->kt;
1143 array = tvref(kt->array);
1144 for (i = 0; i < kt->asize; i++)
1145 if (tvhaskslot(&array[i])) {
1146 TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])];
1147 if (LJ_DUALNUM)
1148 setintV(tv, (int32_t)i);
1149 else
1150 setnumV(tv, (lua_Number)i);
1151 }
1152 node = noderef(kt->node);
1153 hmask = kt->hmask;
1154 for (i = 0; i <= hmask; i++) {
1155 Node *n = &node[i];
1156 if (tvhaskslot(&n->val)) {
1157 ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val);
1158 lua_assert(!tvisint(&n->key));
1159 if (tvisnum(&n->key)) {
1160 TValue *tv = &((TValue *)kptr)[kidx];
1161 if (LJ_DUALNUM) {
1162 lua_Number nn = numV(&n->key);
1163 int32_t k = lj_num2int(nn);
1164 lua_assert(!tvismzero(&n->key));
1165 if ((lua_Number)k == nn)
1166 setintV(tv, k);
1167 else
1168 *tv = n->key;
1169 } else {
1170 *tv = n->key;
1171 }
1172 } else {
1173 GCobj *o = gcV(&n->key);
1174 setgcref(((GCRef *)kptr)[~kidx], o);
1175 lj_gc_objbarrier(fs->L, pt, o);
1176 }
1177 }
1178 }
1179}
1180
1181/* Fixup upvalues for prototype. */
1182static void fs_fixup_uv(FuncState *fs, GCproto *pt, uint16_t *uv)
1183{
1184 MSize i, n = fs->nuv;
1185 setmref(pt->uv, uv);
1186 pt->sizeuv = n;
1187 for (i = 0; i < n; i++)
1188 uv[i] = fs->uvloc[i].slot;
1189}
1190
1191#ifndef LUAJIT_DISABLE_DEBUGINFO
1192/* Prepare lineinfo for prototype. */
1193static size_t fs_prep_line(FuncState *fs, BCLine numline)
1194{
1195 return (fs->pc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2);
1196}
1197
1198/* Fixup lineinfo for prototype. */
1199static void fs_fixup_line(FuncState *fs, GCproto *pt,
1200 void *lineinfo, BCLine numline)
1201{
1202 BCInsLine *base = fs->bcbase + 1;
1203 BCLine first = fs->linedefined;
1204 MSize i = 0, n = fs->pc-1;
1205 pt->firstline = fs->linedefined;
1206 pt->numline = numline;
1207 setmref(pt->lineinfo, lineinfo);
1208 if (LJ_LIKELY(numline < 256)) {
1209 uint8_t *li = (uint8_t *)lineinfo;
1210 do {
1211 BCLine delta = base[i].line - first;
1212 lua_assert(delta >= 0 && delta < 256);
1213 li[i] = (uint8_t)delta;
1214 } while (++i < n);
1215 } else if (LJ_LIKELY(numline < 65536)) {
1216 uint16_t *li = (uint16_t *)lineinfo;
1217 do {
1218 BCLine delta = base[i].line - first;
1219 lua_assert(delta >= 0 && delta < 65536);
1220 li[i] = (uint16_t)delta;
1221 } while (++i < n);
1222 } else {
1223 uint32_t *li = (uint32_t *)lineinfo;
1224 do {
1225 BCLine delta = base[i].line - first;
1226 lua_assert(delta >= 0);
1227 li[i] = (uint32_t)delta;
1228 } while (++i < n);
1229 }
1230}
1231
1232/* Resize buffer if needed. */
1233static LJ_NOINLINE void fs_buf_resize(LexState *ls, MSize len)
1234{
1235 MSize sz = ls->sb.sz * 2;
1236 while (ls->sb.n + len > sz) sz = sz * 2;
1237 lj_str_resizebuf(ls->L, &ls->sb, sz);
1238}
1239
1240static LJ_AINLINE void fs_buf_need(LexState *ls, MSize len)
1241{
1242 if (LJ_UNLIKELY(ls->sb.n + len > ls->sb.sz))
1243 fs_buf_resize(ls, len);
1244}
1245
1246/* Add string to buffer. */
1247static void fs_buf_str(LexState *ls, const char *str, MSize len)
1248{
1249 char *p = ls->sb.buf + ls->sb.n;
1250 MSize i;
1251 ls->sb.n += len;
1252 for (i = 0; i < len; i++) p[i] = str[i];
1253}
1254
1255/* Add ULEB128 value to buffer. */
1256static void fs_buf_uleb128(LexState *ls, uint32_t v)
1257{
1258 MSize n = ls->sb.n;
1259 uint8_t *p = (uint8_t *)ls->sb.buf;
1260 for (; v >= 0x80; v >>= 7)
1261 p[n++] = (uint8_t)((v & 0x7f) | 0x80);
1262 p[n++] = (uint8_t)v;
1263 ls->sb.n = n;
1264}
1265
1266/* Prepare variable info for prototype. */
1267static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1268{
1269 VarInfo *vstack = fs->ls->vstack;
1270 MSize i, n;
1271 BCPos lastpc;
1272 lj_str_resetbuf(&ls->sb); /* Copy to temp. string buffer. */
1273 /* Store upvalue names. */
1274 for (i = 0, n = fs->nuv; i < n; i++) {
1275 GCstr *s = strref(vstack[fs->uvloc[i].vidx].name);
1276 MSize len = s->len+1;
1277 fs_buf_need(ls, len);
1278 fs_buf_str(ls, strdata(s), len);
1279 }
1280 *ofsvar = ls->sb.n;
1281 vstack += fs->vbase;
1282 lastpc = 0;
1283 /* Store local variable names and compressed ranges. */
1284 for (i = 0, n = ls->vtop - fs->vbase; i < n; i++) {
1285 GCstr *s = strref(vstack[i].name);
1286 BCPos startpc = vstack[i].startpc, endpc = vstack[i].endpc;
1287 if ((uintptr_t)s < VARNAME__MAX) {
1288 fs_buf_need(ls, 1 + 2*5);
1289 ls->sb.buf[ls->sb.n++] = (uint8_t)(uintptr_t)s;
1290 } else {
1291 MSize len = s->len+1;
1292 fs_buf_need(ls, len + 2*5);
1293 fs_buf_str(ls, strdata(s), len);
1294 }
1295 fs_buf_uleb128(ls, startpc-lastpc);
1296 fs_buf_uleb128(ls, endpc-startpc);
1297 lastpc = startpc;
1298 }
1299 fs_buf_need(ls, 1);
1300 ls->sb.buf[ls->sb.n++] = '\0'; /* Terminator for varinfo. */
1301 return ls->sb.n;
1302}
1303
1304/* Fixup variable info for prototype. */
1305static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
1306{
1307 setmref(pt->uvinfo, p);
1308 setmref(pt->varinfo, (char *)p + ofsvar);
1309 memcpy(p, ls->sb.buf, ls->sb.n); /* Copy from temp. string buffer. */
1310}
1311#else
1312
1313/* Initialize with empty debug info, if disabled. */
1314#define fs_prep_line(fs, numline) (UNUSED(numline), 0)
1315#define fs_fixup_line(fs, pt, li, numline) \
1316 pt->firstline = pt->numline = 0, setmref((pt)->lineinfo, NULL)
1317#define fs_prep_var(ls, fs, ofsvar) (UNUSED(ofsvar), 0)
1318#define fs_fixup_var(ls, pt, p, ofsvar) \
1319 setmref((pt)->uvinfo, NULL), setmref((pt)->varinfo, NULL)
1320
1321#endif
1322
1323/* Check if bytecode op returns. */
1324static int bcopisret(BCOp op)
1325{
1326 switch (op) {
1327 case BC_CALLMT: case BC_CALLT:
1328 case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1329 return 1;
1330 default:
1331 return 0;
1332 }
1333}
1334
1335/* Fixup return instruction for prototype. */
1336static void fs_fixup_ret(FuncState *fs)
1337{
1338 BCPos lastpc = fs->pc;
1339 if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) {
1340 if (fs->flags & PROTO_CHILD)
1341 bcemit_AJ(fs, BC_UCLO, 0, 0);
1342 bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */
1343 }
1344 /* May need to fixup returns encoded before first function was created. */
1345 if (fs->flags & PROTO_FIXUP_RETURN) {
1346 BCPos pc;
1347 for (pc = 0; pc < lastpc; pc++) {
1348 BCIns ins = fs->bcbase[pc].ins;
1349 BCPos offset;
1350 switch (bc_op(ins)) {
1351 case BC_CALLMT: case BC_CALLT:
1352 case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1353 offset = bcemit_INS(fs, ins)-(pc+1)+BCBIAS_J; /* Copy return ins. */
1354 if (offset > BCMAX_D)
1355 err_syntax(fs->ls, LJ_ERR_XFIXUP);
1356 /* Replace with UCLO plus branch. */
1357 fs->bcbase[pc].ins = BCINS_AD(BC_UCLO, 0, offset);
1358 break;
1359 case BC_UCLO:
1360 return; /* We're done. */
1361 default:
1362 break;
1363 }
1364 }
1365 }
1366}
1367
1368/* Finish a FuncState and return the new prototype. */
1369static GCproto *fs_finish(LexState *ls, BCLine line)
1370{
1371 lua_State *L = ls->L;
1372 FuncState *fs = ls->fs;
1373 BCLine numline = line - fs->linedefined;
1374 size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar;
1375 GCproto *pt;
1376
1377 /* Apply final fixups. */
1378 lua_assert(fs->bl == NULL);
1379 fs_fixup_ret(fs);
1380 var_remove(ls, 0);
1381
1382 /* Calculate total size of prototype including all colocated arrays. */
1383 sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef);
1384 sizept = (sizept + sizeof(TValue)-1) & ~(sizeof(TValue)-1);
1385 ofsk = sizept; sizept += fs->nkn*sizeof(TValue);
1386 ofsuv = sizept; sizept += ((fs->nuv+1)&~1)*2;
1387 ofsli = sizept; sizept += fs_prep_line(fs, numline);
1388 ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar);
1389
1390 /* Allocate prototype and initialize its fields. */
1391 pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept);
1392 pt->gct = ~LJ_TPROTO;
1393 pt->sizept = (MSize)sizept;
1394 pt->trace = 0;
1395 pt->flags = (uint8_t)(fs->flags & ~(PROTO_HAS_RETURN|PROTO_FIXUP_RETURN));
1396 pt->numparams = fs->numparams;
1397 pt->framesize = fs->framesize;
1398 setgcref(pt->chunkname, obj2gco(ls->chunkname));
1399
1400 /* Close potentially uninitialized gap between bc and kgc. */
1401 *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(fs->nkgc+1)) = 0;
1402 fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), fs->pc);
1403 fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk));
1404 fs_fixup_uv(fs, pt, (uint16_t *)((char *)pt + ofsuv));
1405 fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline);
1406 fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar);
1407
1408 lj_vmevent_send(L, BC,
1409 setprotoV(L, L->top++, pt);
1410 );
1411
1412 L->top--; /* Pop table of constants. */
1413 ls->vtop = fs->vbase; /* Reset variable stack. */
1414 ls->fs = fs->prev;
1415 lua_assert(ls->fs != NULL || ls->token == TK_eof);
1416 return pt;
1417}
1418
1419/* Initialize a new FuncState. */
1420static void fs_init(LexState *ls, FuncState *fs)
1421{
1422 lua_State *L = ls->L;
1423 fs->prev = ls->fs; ls->fs = fs; /* Append to list. */
1424 fs->ls = ls;
1425 fs->vbase = ls->vtop;
1426 fs->L = L;
1427 fs->pc = 0;
1428 fs->lasttarget = 0;
1429 fs->jpc = NO_JMP;
1430 fs->freereg = 0;
1431 fs->nkgc = 0;
1432 fs->nkn = 0;
1433 fs->nactvar = 0;
1434 fs->nuv = 0;
1435 fs->bl = NULL;
1436 fs->flags = 0;
1437 fs->framesize = 1; /* Minimum frame size. */
1438 fs->kt = lj_tab_new(L, 0, 0);
1439 /* Anchor table of constants in stack to avoid being collected. */
1440 settabV(L, L->top, fs->kt);
1441 incr_top(L);
1442}
1443
1444/* -- Expressions --------------------------------------------------------- */
1445
1446/* Forward declaration. */
1447static void expr(LexState *ls, ExpDesc *v);
1448
1449/* Return string expression. */
1450static void expr_str(LexState *ls, ExpDesc *e)
1451{
1452 expr_init(e, VKSTR, 0);
1453 e->u.sval = lex_str(ls);
1454}
1455
1456/* Return index expression. */
1457static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e)
1458{
1459 /* Already called: expr_toval(fs, e). */
1460 t->k = VINDEXED;
1461 if (expr_isnumk(e)) {
1462#if LJ_DUALNUM
1463 if (tvisint(expr_numtv(e))) {
1464 int32_t k = intV(expr_numtv(e));
1465 if (checku8(k)) {
1466 t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */
1467 return;
1468 }
1469 }
1470#else
1471 lua_Number n = expr_numberV(e);
1472 int32_t k = lj_num2int(n);
1473 if (checku8(k) && n == (lua_Number)k) {
1474 t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */
1475 return;
1476 }
1477#endif
1478 } else if (expr_isstrk(e)) {
1479 BCReg idx = const_str(fs, e);
1480 if (idx <= BCMAX_C) {
1481 t->u.s.aux = ~idx; /* -256..-1: const string key */
1482 return;
1483 }
1484 }
1485 t->u.s.aux = expr_toanyreg(fs, e); /* 0..255: register */
1486}
1487
1488/* Parse index expression with named field. */
1489static void expr_field(LexState *ls, ExpDesc *v)
1490{
1491 FuncState *fs = ls->fs;
1492 ExpDesc key;
1493 expr_toanyreg(fs, v);
1494 lj_lex_next(ls); /* Skip dot or colon. */
1495 expr_str(ls, &key);
1496 expr_index(fs, v, &key);
1497}
1498
1499/* Parse index expression with brackets. */
1500static void expr_bracket(LexState *ls, ExpDesc *v)
1501{
1502 lj_lex_next(ls); /* Skip '['. */
1503 expr(ls, v);
1504 expr_toval(ls->fs, v);
1505 lex_check(ls, ']');
1506}
1507
1508/* Get value of constant expression. */
1509static void expr_kvalue(TValue *v, ExpDesc *e)
1510{
1511 if (e->k <= VKTRUE) {
1512 setitype(v, ~(uint32_t)e->k);
1513 } else if (e->k == VKSTR) {
1514 setgcref(v->gcr, obj2gco(e->u.sval));
1515 setitype(v, LJ_TSTR);
1516 } else {
1517 lua_assert(tvisnumber(expr_numtv(e)));
1518 *v = *expr_numtv(e);
1519 }
1520}
1521
1522/* Parse table constructor expression. */
1523static void expr_table(LexState *ls, ExpDesc *e)
1524{
1525 FuncState *fs = ls->fs;
1526 BCLine line = ls->linenumber;
1527 GCtab *t = NULL;
1528 int vcall = 0, needarr = 0;
1529 int32_t narr = 1; /* First array index. */
1530 uint32_t nhash = 0; /* Number of hash entries. */
1531 BCReg freg = fs->freereg;
1532 BCPos pc = bcemit_AD(fs, BC_TNEW, freg, 0);
1533 expr_init(e, VNONRELOC, freg);
1534 bcreg_reserve(fs, 1);
1535 freg++;
1536 lex_check(ls, '{');
1537 while (ls->token != '}') {
1538 ExpDesc key, val;
1539 vcall = 0;
1540 if (ls->token == '[') {
1541 expr_bracket(ls, &key); /* Already calls expr_toval. */
1542 if (!expr_isk(&key)) expr_index(fs, e, &key);
1543 if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++;
1544 lex_check(ls, '=');
1545 } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') {
1546 expr_str(ls, &key);
1547 lex_check(ls, '=');
1548 nhash++;
1549 } else {
1550 expr_init(&key, VKNUM, 0);
1551 setintV(&key.u.nval, narr);
1552 narr++;
1553 needarr = vcall = 1;
1554 }
1555 expr(ls, &val);
1556 if (expr_isk_nojump(&val) && expr_isk(&key) && key.k != VKNIL) {
1557 TValue k;
1558 if (!t) { /* Create template table on demand. */
1559 BCReg kidx;
1560 t = lj_tab_new(fs->L, 0, 0);
1561 kidx = const_gc(fs, obj2gco(t), LJ_TTAB);
1562 fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx);
1563 }
1564 vcall = 0;
1565 expr_kvalue(&k, &key);
1566 expr_kvalue(lj_tab_set(fs->L, t, &k), &val);
1567 lj_gc_anybarriert(fs->L, t);
1568 } else {
1569 if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; }
1570 if (expr_isk(&key)) expr_index(fs, e, &key);
1571 bcemit_store(fs, e, &val);
1572 }
1573 fs->freereg = freg;
1574 if (!lex_opt(ls, ',') && !lex_opt(ls, ';')) break;
1575 }
1576 lex_match(ls, '}', '{', line);
1577 if (vcall) {
1578 BCInsLine *ilp = &fs->bcbase[fs->pc-1];
1579 ExpDesc en;
1580 lua_assert(bc_a(ilp->ins) == freg &&
1581 bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB));
1582 expr_init(&en, VKNUM, 0);
1583 en.u.nval.u32.lo = narr-1;
1584 en.u.nval.u32.hi = 0x43300000; /* Biased integer to avoid denormals. */
1585 if (narr > 256) { fs->pc--; ilp--; }
1586 ilp->ins = BCINS_AD(BC_TSETM, freg, const_num(fs, &en));
1587 setbc_b(&ilp[-1].ins, 0);
1588 }
1589 if (pc == fs->pc-1) { /* Make expr relocable if possible. */
1590 e->u.s.info = pc;
1591 fs->freereg--;
1592 e->k = VRELOCABLE;
1593 } else {
1594 e->k = VNONRELOC; /* May have been changed by expr_index. */
1595 }
1596 if (!t) { /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */
1597 BCIns *ip = &fs->bcbase[pc].ins;
1598 if (!needarr) narr = 0;
1599 else if (narr < 3) narr = 3;
1600 else if (narr > 0x7ff) narr = 0x7ff;
1601 setbc_d(ip, (uint32_t)narr|(hsize2hbits(nhash)<<11));
1602 }
1603}
1604
1605/* Parse function parameters. */
1606static BCReg parse_params(LexState *ls, int needself)
1607{
1608 FuncState *fs = ls->fs;
1609 BCReg nparams = 0;
1610 lex_check(ls, '(');
1611 if (needself)
1612 var_new_lit(ls, nparams++, "self");
1613 if (ls->token != ')') {
1614 do {
1615 if (ls->token == TK_name) {
1616 var_new(ls, nparams++, lex_str(ls));
1617 } else if (ls->token == TK_dots) {
1618 lj_lex_next(ls);
1619 fs->flags |= PROTO_VARARG;
1620 break;
1621 } else {
1622 err_syntax(ls, LJ_ERR_XPARAM);
1623 }
1624 } while (lex_opt(ls, ','));
1625 }
1626 var_add(ls, nparams);
1627 lua_assert(fs->nactvar == nparams);
1628 bcreg_reserve(fs, nparams);
1629 lex_check(ls, ')');
1630 return nparams;
1631}
1632
1633/* Forward declaration. */
1634static void parse_chunk(LexState *ls);
1635
1636/* Parse body of a function. */
1637static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
1638{
1639 FuncState fs, *pfs = ls->fs;
1640 GCproto *pt;
1641 ptrdiff_t oldbase = pfs->bcbase - ls->bcstack;
1642 fs_init(ls, &fs);
1643 fs.linedefined = line;
1644 fs.numparams = (uint8_t)parse_params(ls, needself);
1645 fs.bcbase = pfs->bcbase + pfs->pc;
1646 fs.bclim = pfs->bclim - pfs->pc;
1647 bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */
1648 parse_chunk(ls);
1649 if (ls->token != TK_end) lex_match(ls, TK_end, TK_function, line);
1650 pt = fs_finish(ls, (ls->lastline = ls->linenumber));
1651 pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */
1652 pfs->bclim = (BCPos)(ls->sizebcstack - oldbase);
1653 /* Store new prototype in the constant array of the parent. */
1654 expr_init(e, VRELOCABLE,
1655 bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO)));
1656#if LJ_HASFFI
1657 pfs->flags |= (fs.flags & PROTO_FFI);
1658#endif
1659 if (!(pfs->flags & PROTO_CHILD)) {
1660 if (pfs->flags & PROTO_HAS_RETURN)
1661 pfs->flags |= PROTO_FIXUP_RETURN;
1662 pfs->flags |= PROTO_CHILD;
1663 }
1664 lj_lex_next(ls);
1665}
1666
1667/* Parse expression list. Last expression is left open. */
1668static BCReg expr_list(LexState *ls, ExpDesc *v)
1669{
1670 BCReg n = 1;
1671 expr(ls, v);
1672 while (lex_opt(ls, ',')) {
1673 expr_tonextreg(ls->fs, v);
1674 expr(ls, v);
1675 n++;
1676 }
1677 return n;
1678}
1679
1680/* Parse function argument list. */
1681static void parse_args(LexState *ls, ExpDesc *e)
1682{
1683 FuncState *fs = ls->fs;
1684 ExpDesc args;
1685 BCIns ins;
1686 BCReg base;
1687 BCLine line = ls->linenumber;
1688 if (ls->token == '(') {
1689 if (line != ls->lastline)
1690 err_syntax(ls, LJ_ERR_XAMBIG);
1691 lj_lex_next(ls);
1692 if (ls->token == ')') { /* f(). */
1693 args.k = VVOID;
1694 } else {
1695 expr_list(ls, &args);
1696 if (args.k == VCALL) /* f(a, b, g()) or f(a, b, ...). */
1697 setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */
1698 }
1699 lex_match(ls, ')', '(', line);
1700 } else if (ls->token == '{') {
1701 expr_table(ls, &args);
1702 } else if (ls->token == TK_string) {
1703 expr_init(&args, VKSTR, 0);
1704 args.u.sval = strV(&ls->tokenval);
1705 lj_lex_next(ls);
1706 } else {
1707 err_syntax(ls, LJ_ERR_XFUNARG);
1708 return; /* Silence compiler. */
1709 }
1710 lua_assert(e->k == VNONRELOC);
1711 base = e->u.s.info; /* Base register for call. */
1712 if (args.k == VCALL) {
1713 ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1);
1714 } else {
1715 if (args.k != VVOID)
1716 expr_tonextreg(fs, &args);
1717 ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base);
1718 }
1719 expr_init(e, VCALL, bcemit_INS(fs, ins));
1720 e->u.s.aux = base;
1721 fs->bcbase[fs->pc - 1].line = line;
1722 fs->freereg = base+1; /* Leave one result by default. */
1723}
1724
1725/* Parse primary expression. */
1726static void expr_primary(LexState *ls, ExpDesc *v)
1727{
1728 FuncState *fs = ls->fs;
1729 /* Parse prefix expression. */
1730 if (ls->token == '(') {
1731 BCLine line = ls->linenumber;
1732 lj_lex_next(ls);
1733 expr(ls, v);
1734 lex_match(ls, ')', '(', line);
1735 expr_discharge(ls->fs, v);
1736 } else if (ls->token == TK_name) {
1737 var_lookup(ls, v);
1738 } else {
1739 err_syntax(ls, LJ_ERR_XSYMBOL);
1740 }
1741 for (;;) { /* Parse multiple expression suffixes. */
1742 if (ls->token == '.') {
1743 expr_field(ls, v);
1744 } else if (ls->token == '[') {
1745 ExpDesc key;
1746 expr_toanyreg(fs, v);
1747 expr_bracket(ls, &key);
1748 expr_index(fs, v, &key);
1749 } else if (ls->token == ':') {
1750 ExpDesc key;
1751 lj_lex_next(ls);
1752 expr_str(ls, &key);
1753 bcemit_method(fs, v, &key);
1754 parse_args(ls, v);
1755 } else if (ls->token == '(' || ls->token == TK_string || ls->token == '{') {
1756 expr_tonextreg(fs, v);
1757 parse_args(ls, v);
1758 } else {
1759 break;
1760 }
1761 }
1762}
1763
1764/* Parse simple expression. */
1765static void expr_simple(LexState *ls, ExpDesc *v)
1766{
1767 switch (ls->token) {
1768 case TK_number:
1769 expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokenval)) ? VKCDATA : VKNUM, 0);
1770 copyTV(ls->L, &v->u.nval, &ls->tokenval);
1771 break;
1772 case TK_string:
1773 expr_init(v, VKSTR, 0);
1774 v->u.sval = strV(&ls->tokenval);
1775 break;
1776 case TK_nil:
1777 expr_init(v, VKNIL, 0);
1778 break;
1779 case TK_true:
1780 expr_init(v, VKTRUE, 0);
1781 break;
1782 case TK_false:
1783 expr_init(v, VKFALSE, 0);
1784 break;
1785 case TK_dots: { /* Vararg. */
1786 FuncState *fs = ls->fs;
1787 BCReg base;
1788 checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS);
1789 bcreg_reserve(fs, 1);
1790 base = fs->freereg-1;
1791 expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams));
1792 v->u.s.aux = base;
1793 break;
1794 }
1795 case '{': /* Table constructor. */
1796 expr_table(ls, v);
1797 return;
1798 case TK_function:
1799 lj_lex_next(ls);
1800 parse_body(ls, v, 0, ls->linenumber);
1801 return;
1802 default:
1803 expr_primary(ls, v);
1804 return;
1805 }
1806 lj_lex_next(ls);
1807}
1808
1809/* Manage syntactic levels to avoid blowing up the stack. */
1810static void synlevel_begin(LexState *ls)
1811{
1812 if (++ls->level >= LJ_MAX_XLEVEL)
1813 lj_lex_error(ls, 0, LJ_ERR_XLEVELS);
1814}
1815
1816#define synlevel_end(ls) ((ls)->level--)
1817
1818/* Convert token to binary operator. */
1819static BinOpr token2binop(LexToken tok)
1820{
1821 switch (tok) {
1822 case '+': return OPR_ADD;
1823 case '-': return OPR_SUB;
1824 case '*': return OPR_MUL;
1825 case '/': return OPR_DIV;
1826 case '%': return OPR_MOD;
1827 case '^': return OPR_POW;
1828 case TK_concat: return OPR_CONCAT;
1829 case TK_ne: return OPR_NE;
1830 case TK_eq: return OPR_EQ;
1831 case '<': return OPR_LT;
1832 case TK_le: return OPR_LE;
1833 case '>': return OPR_GT;
1834 case TK_ge: return OPR_GE;
1835 case TK_and: return OPR_AND;
1836 case TK_or: return OPR_OR;
1837 default: return OPR_NOBINOPR;
1838 }
1839}
1840
1841/* Priorities for each binary operator. ORDER OPR. */
1842static const struct {
1843 uint8_t left; /* Left priority. */
1844 uint8_t right; /* Right priority. */
1845} priority[] = {
1846 {6,6}, {6,6}, {7,7}, {7,7}, {7,7}, /* ADD SUB MUL DIV MOD */
1847 {10,9}, {5,4}, /* POW CONCAT (right associative) */
1848 {3,3}, {3,3}, /* EQ NE */
1849 {3,3}, {3,3}, {3,3}, {3,3}, /* LT GE GT LE */
1850 {2,2}, {1,1} /* AND OR */
1851};
1852
1853#define UNARY_PRIORITY 8 /* Priority for unary operators. */
1854
1855/* Forward declaration. */
1856static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit);
1857
1858/* Parse unary expression. */
1859static void expr_unop(LexState *ls, ExpDesc *v)
1860{
1861 BCOp op;
1862 if (ls->token == TK_not) {
1863 op = BC_NOT;
1864 } else if (ls->token == '-') {
1865 op = BC_UNM;
1866 } else if (ls->token == '#') {
1867 op = BC_LEN;
1868 } else {
1869 expr_simple(ls, v);
1870 return;
1871 }
1872 lj_lex_next(ls);
1873 expr_binop(ls, v, UNARY_PRIORITY);
1874 bcemit_unop(ls->fs, op, v);
1875}
1876
1877/* Parse binary expressions with priority higher than the limit. */
1878static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit)
1879{
1880 BinOpr op;
1881 synlevel_begin(ls);
1882 expr_unop(ls, v);
1883 op = token2binop(ls->token);
1884 while (op != OPR_NOBINOPR && priority[op].left > limit) {
1885 ExpDesc v2;
1886 BinOpr nextop;
1887 lj_lex_next(ls);
1888 bcemit_binop_left(ls->fs, op, v);
1889 /* Parse binary expression with higher priority. */
1890 nextop = expr_binop(ls, &v2, priority[op].right);
1891 bcemit_binop(ls->fs, op, v, &v2);
1892 op = nextop;
1893 }
1894 synlevel_end(ls);
1895 return op; /* Return unconsumed binary operator (if any). */
1896}
1897
1898/* Parse expression. */
1899static void expr(LexState *ls, ExpDesc *v)
1900{
1901 expr_binop(ls, v, 0); /* Priority 0: parse whole expression. */
1902}
1903
1904/* Assign expression to the next register. */
1905static void expr_next(LexState *ls)
1906{
1907 ExpDesc e;
1908 expr(ls, &e);
1909 expr_tonextreg(ls->fs, &e);
1910}
1911
1912/* Parse conditional expression. */
1913static BCPos expr_cond(LexState *ls)
1914{
1915 ExpDesc v;
1916 expr(ls, &v);
1917 if (v.k == VKNIL) v.k = VKFALSE;
1918 bcemit_branch_t(ls->fs, &v);
1919 return v.f;
1920}
1921
1922/* -- Scope handling ------------------------------------------------------ */
1923
1924/* Begin a scope. */
1925static void scope_begin(FuncState *fs, FuncScope *bl, int isbreakable)
1926{
1927 bl->breaklist = NO_JMP;
1928 bl->isbreakable = (uint8_t)isbreakable;
1929 bl->nactvar = (uint8_t)fs->nactvar;
1930 bl->upval = 0;
1931 bl->prev = fs->bl;
1932 fs->bl = bl;
1933 lua_assert(fs->freereg == fs->nactvar);
1934}
1935
1936/* End a scope. */
1937static void scope_end(FuncState *fs)
1938{
1939 FuncScope *bl = fs->bl;
1940 fs->bl = bl->prev;
1941 var_remove(fs->ls, bl->nactvar);
1942 fs->freereg = fs->nactvar;
1943 lua_assert(bl->nactvar == fs->nactvar);
1944 /* A scope is either breakable or has upvalues. */
1945 lua_assert(!bl->isbreakable || !bl->upval);
1946 if (bl->upval)
1947 bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0);
1948 else /* Avoid in upval case, it clears lasttarget and kills UCLO+JMP join. */
1949 jmp_tohere(fs, bl->breaklist);
1950}
1951
1952/* Mark scope as having an upvalue. */
1953static void scope_uvmark(FuncState *fs, BCReg level)
1954{
1955 FuncScope *bl;
1956 for (bl = fs->bl; bl && bl->nactvar > level; bl = bl->prev)
1957 ;
1958 if (bl)
1959 bl->upval = 1;
1960}
1961
1962/* Parse 'break' statement. */
1963static void parse_break(LexState *ls)
1964{
1965 FuncState *fs = ls->fs;
1966 FuncScope *bl;
1967 BCReg savefr;
1968 int upval = 0;
1969 for (bl = fs->bl; bl && !bl->isbreakable; bl = bl->prev)
1970 upval |= bl->upval; /* Collect upvalues in intervening scopes. */
1971 if (!bl) /* Error if no breakable scope found. */
1972 err_syntax(ls, LJ_ERR_XBREAK);
1973 savefr = fs->freereg;
1974 fs->freereg = bl->nactvar; /* Shrink slots to help data-flow analysis. */
1975 if (upval)
1976 bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); /* Close upvalues. */
1977 jmp_append(fs, &bl->breaklist, bcemit_jmp(fs));
1978 fs->freereg = savefr;
1979}
1980
1981/* Check for end of block. */
1982static int endofblock(LexToken token)
1983{
1984 switch (token) {
1985 case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof:
1986 return 1;
1987 default:
1988 return 0;
1989 }
1990}
1991
1992/* Parse 'return' statement. */
1993static void parse_return(LexState *ls)
1994{
1995 BCIns ins;
1996 FuncState *fs = ls->fs;
1997 lj_lex_next(ls); /* Skip 'return'. */
1998 fs->flags |= PROTO_HAS_RETURN;
1999 if (endofblock(ls->token) || ls->token == ';') { /* Bare return. */
2000 ins = BCINS_AD(BC_RET0, 0, 1);
2001 } else { /* Return with one or more values. */
2002 ExpDesc e; /* Receives the _last_ expression in the list. */
2003 BCReg nret = expr_list(ls, &e);
2004 if (nret == 1) { /* Return one result. */
2005 if (e.k == VCALL) { /* Check for tail call. */
2006 BCIns *ip = bcptr(fs, &e);
2007 /* It doesn't pay off to add BC_VARGT just for 'return ...'. */
2008 if (bc_op(*ip) == BC_VARG) goto notailcall;
2009 fs->pc--;
2010 ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip));
2011 } else { /* Can return the result from any register. */
2012 ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
2013 }
2014 } else {
2015 if (e.k == VCALL) { /* Append all results from a call. */
2016 notailcall:
2017 setbc_b(bcptr(fs, &e), 0);
2018 ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar);
2019 } else {
2020 expr_tonextreg(fs, &e); /* Force contiguous registers. */
2021 ins = BCINS_AD(BC_RET, fs->nactvar, nret+1);
2022 }
2023 }
2024 }
2025 if (fs->flags & PROTO_CHILD)
2026 bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */
2027 bcemit_INS(fs, ins);
2028}
2029
2030/* Parse a block. */
2031static void parse_block(LexState *ls)
2032{
2033 FuncState *fs = ls->fs;
2034 FuncScope bl;
2035 scope_begin(fs, &bl, 0);
2036 parse_chunk(ls);
2037 lua_assert(bl.breaklist == NO_JMP);
2038 scope_end(fs);
2039}
2040
2041/* -- Assignments --------------------------------------------------------- */
2042
2043/* List of LHS variables. */
2044typedef struct LHSVarList {
2045 ExpDesc v; /* LHS variable. */
2046 struct LHSVarList *prev; /* Link to previous LHS variable. */
2047} LHSVarList;
2048
2049/* Eliminate write-after-read hazards for local variable assignment. */
2050static void assign_hazard(LexState *ls, LHSVarList *lh, const ExpDesc *v)
2051{
2052 FuncState *fs = ls->fs;
2053 BCReg reg = v->u.s.info; /* Check against this variable. */
2054 BCReg tmp = fs->freereg; /* Rename to this temp. register (if needed). */
2055 int hazard = 0;
2056 for (; lh; lh = lh->prev) {
2057 if (lh->v.k == VINDEXED) {
2058 if (lh->v.u.s.info == reg) { /* t[i], t = 1, 2 */
2059 hazard = 1;
2060 lh->v.u.s.info = tmp;
2061 }
2062 if (lh->v.u.s.aux == reg) { /* t[i], i = 1, 2 */
2063 hazard = 1;
2064 lh->v.u.s.aux = tmp;
2065 }
2066 }
2067 }
2068 if (hazard) {
2069 bcemit_AD(fs, BC_MOV, tmp, reg); /* Rename conflicting variable. */
2070 bcreg_reserve(fs, 1);
2071 }
2072}
2073
2074/* Adjust LHS/RHS of an assignment. */
2075static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e)
2076{
2077 FuncState *fs = ls->fs;
2078 int32_t extra = (int32_t)nvars - (int32_t)nexps;
2079 if (e->k == VCALL) {
2080 extra++; /* Compensate for the VCALL itself. */
2081 if (extra < 0) extra = 0;
2082 setbc_b(bcptr(fs, e), extra+1); /* Fixup call results. */
2083 if (extra > 1) bcreg_reserve(fs, (BCReg)extra-1);
2084 } else {
2085 if (e->k != VVOID)
2086 expr_tonextreg(fs, e); /* Close last expression. */
2087 if (extra > 0) { /* Leftover LHS are set to nil. */
2088 BCReg reg = fs->freereg;
2089 bcreg_reserve(fs, (BCReg)extra);
2090 bcemit_nil(fs, reg, (BCReg)extra);
2091 }
2092 }
2093}
2094
2095/* Recursively parse assignment statement. */
2096static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars)
2097{
2098 ExpDesc e;
2099 checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX);
2100 if (lex_opt(ls, ',')) { /* Collect LHS list and recurse upwards. */
2101 LHSVarList vl;
2102 vl.prev = lh;
2103 expr_primary(ls, &vl.v);
2104 if (vl.v.k == VLOCAL)
2105 assign_hazard(ls, lh, &vl.v);
2106 checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names");
2107 parse_assignment(ls, &vl, nvars+1);
2108 } else { /* Parse RHS. */
2109 BCReg nexps;
2110 lex_check(ls, '=');
2111 nexps = expr_list(ls, &e);
2112 if (nexps == nvars) {
2113 if (e.k == VCALL) {
2114 if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) { /* Vararg assignment. */
2115 ls->fs->freereg--;
2116 e.k = VRELOCABLE;
2117 } else { /* Multiple call results. */
2118 e.u.s.info = e.u.s.aux; /* Base of call is not relocatable. */
2119 e.k = VNONRELOC;
2120 }
2121 }
2122 bcemit_store(ls->fs, &lh->v, &e);
2123 return;
2124 }
2125 assign_adjust(ls, nvars, nexps, &e);
2126 if (nexps > nvars)
2127 ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */
2128 }
2129 /* Assign RHS to LHS and recurse downwards. */
2130 expr_init(&e, VNONRELOC, ls->fs->freereg-1);
2131 bcemit_store(ls->fs, &lh->v, &e);
2132}
2133
2134/* Parse call statement or assignment. */
2135static void parse_call_assign(LexState *ls)
2136{
2137 FuncState *fs = ls->fs;
2138 LHSVarList vl;
2139 expr_primary(ls, &vl.v);
2140 if (vl.v.k == VCALL) { /* Function call statement. */
2141 setbc_b(bcptr(fs, &vl.v), 1); /* No results. */
2142 } else { /* Start of an assignment. */
2143 vl.prev = NULL;
2144 parse_assignment(ls, &vl, 1);
2145 }
2146}
2147
2148/* Parse 'local' statement. */
2149static void parse_local(LexState *ls)
2150{
2151 if (lex_opt(ls, TK_function)) { /* Local function declaration. */
2152 ExpDesc v, b;
2153 FuncState *fs = ls->fs;
2154 var_new(ls, 0, lex_str(ls));
2155 expr_init(&v, VLOCAL, fs->freereg);
2156 bcreg_reserve(fs, 1);
2157 var_add(ls, 1);
2158 parse_body(ls, &b, 0, ls->linenumber);
2159 bcemit_store(fs, &v, &b);
2160 /* The upvalue is in scope, but the local is only valid after the store. */
2161 var_get(ls, fs, fs->nactvar - 1).startpc = fs->pc;
2162 } else { /* Local variable declaration. */
2163 ExpDesc e;
2164 BCReg nexps, nvars = 0;
2165 do { /* Collect LHS. */
2166 var_new(ls, nvars++, lex_str(ls));
2167 } while (lex_opt(ls, ','));
2168 if (lex_opt(ls, '=')) { /* Optional RHS. */
2169 nexps = expr_list(ls, &e);
2170 } else { /* Or implicitly set to nil. */
2171 e.k = VVOID;
2172 nexps = 0;
2173 }
2174 assign_adjust(ls, nvars, nexps, &e);
2175 var_add(ls, nvars);
2176 }
2177}
2178
2179/* Parse 'function' statement. */
2180static void parse_func(LexState *ls, BCLine line)
2181{
2182 FuncState *fs;
2183 ExpDesc v, b;
2184 int needself = 0;
2185 lj_lex_next(ls); /* Skip 'function'. */
2186 /* Parse function name. */
2187 var_lookup(ls, &v);
2188 while (ls->token == '.') /* Multiple dot-separated fields. */
2189 expr_field(ls, &v);
2190 if (ls->token == ':') { /* Optional colon to signify method call. */
2191 needself = 1;
2192 expr_field(ls, &v);
2193 }
2194 parse_body(ls, &b, needself, line);
2195 fs = ls->fs;
2196 bcemit_store(fs, &v, &b);
2197 fs->bcbase[fs->pc - 1].line = line; /* Set line for the store. */
2198}
2199
2200/* -- Loop and conditional statements ------------------------------------- */
2201
2202/* Parse 'while' statement. */
2203static void parse_while(LexState *ls, BCLine line)
2204{
2205 FuncState *fs = ls->fs;
2206 BCPos start, loop, condexit;
2207 FuncScope bl;
2208 lj_lex_next(ls); /* Skip 'while'. */
2209 start = fs->lasttarget = fs->pc;
2210 condexit = expr_cond(ls);
2211 scope_begin(fs, &bl, 1);
2212 lex_check(ls, TK_do);
2213 loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
2214 parse_block(ls);
2215 jmp_patch(fs, bcemit_jmp(fs), start);
2216 lex_match(ls, TK_end, TK_while, line);
2217 scope_end(fs);
2218 jmp_tohere(fs, condexit);
2219 jmp_patchins(fs, loop, fs->pc);
2220}
2221
2222/* Parse 'repeat' statement. */
2223static void parse_repeat(LexState *ls, BCLine line)
2224{
2225 FuncState *fs = ls->fs;
2226 BCPos loop = fs->lasttarget = fs->pc;
2227 BCPos condexit;
2228 FuncScope bl1, bl2;
2229 scope_begin(fs, &bl1, 1); /* Breakable loop scope. */
2230 scope_begin(fs, &bl2, 0); /* Inner scope. */
2231 lj_lex_next(ls); /* Skip 'repeat'. */
2232 bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
2233 parse_chunk(ls);
2234 lex_match(ls, TK_until, TK_repeat, line);
2235 condexit = expr_cond(ls); /* Parse condition (still inside inner scope). */
2236 if (!bl2.upval) { /* No upvalues? Just end inner scope. */
2237 scope_end(fs);
2238 } else { /* Otherwise generate: cond: UCLO+JMP out, !cond: UCLO+JMP loop. */
2239 parse_break(ls); /* Break from loop and close upvalues. */
2240 jmp_tohere(fs, condexit);
2241 scope_end(fs); /* End inner scope and close upvalues. */
2242 condexit = bcemit_jmp(fs);
2243 }
2244 jmp_patch(fs, condexit, loop); /* Jump backwards if !cond. */
2245 jmp_patchins(fs, loop, fs->pc);
2246 scope_end(fs); /* End loop scope. */
2247}
2248
2249/* Parse numeric 'for'. */
2250static void parse_for_num(LexState *ls, GCstr *varname, BCLine line)
2251{
2252 FuncState *fs = ls->fs;
2253 BCReg base = fs->freereg;
2254 FuncScope bl;
2255 BCPos loop, loopend;
2256 /* Hidden control variables. */
2257 var_new_fixed(ls, FORL_IDX, VARNAME_FOR_IDX);
2258 var_new_fixed(ls, FORL_STOP, VARNAME_FOR_STOP);
2259 var_new_fixed(ls, FORL_STEP, VARNAME_FOR_STEP);
2260 /* Visible copy of index variable. */
2261 var_new(ls, FORL_EXT, varname);
2262 lex_check(ls, '=');
2263 expr_next(ls);
2264 lex_check(ls, ',');
2265 expr_next(ls);
2266 if (lex_opt(ls, ',')) {
2267 expr_next(ls);
2268 } else {
2269 bcemit_AD(fs, BC_KSHORT, fs->freereg, 1); /* Default step is 1. */
2270 bcreg_reserve(fs, 1);
2271 }
2272 var_add(ls, 3); /* Hidden control variables. */
2273 lex_check(ls, TK_do);
2274 loop = bcemit_AJ(fs, BC_FORI, base, NO_JMP);
2275 scope_begin(fs, &bl, 0); /* Scope for visible variables. */
2276 var_add(ls, 1);
2277 bcreg_reserve(fs, 1);
2278 parse_block(ls);
2279 scope_end(fs);
2280 /* Perform loop inversion. Loop control instructions are at the end. */
2281 loopend = bcemit_AJ(fs, BC_FORL, base, NO_JMP);
2282 fs->bcbase[loopend].line = line; /* Fix line for control ins. */
2283 jmp_patchins(fs, loopend, loop+1);
2284 jmp_patchins(fs, loop, fs->pc);
2285}
2286
2287/* Try to predict whether the iterator is next() and specialize the bytecode.
2288** Detecting next() and pairs() by name is simplistic, but quite effective.
2289** The interpreter backs off if the check for the closure fails at runtime.
2290*/
2291static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
2292{
2293 BCIns ins = fs->bcbase[pc].ins;
2294 GCstr *name;
2295 cTValue *o;
2296 switch (bc_op(ins)) {
2297 case BC_MOV:
2298 name = gco2str(gcref(var_get(ls, fs, bc_d(ins)).name));
2299 break;
2300 case BC_UGET:
2301 name = gco2str(gcref(ls->vstack[fs->uvloc[bc_d(ins)].vidx].name));
2302 break;
2303 case BC_GGET:
2304 /* There's no inverse index (yet), so lookup the strings. */
2305 o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs"));
2306 if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins))
2307 return 1;
2308 o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next"));
2309 if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins))
2310 return 1;
2311 return 0;
2312 default:
2313 return 0;
2314 }
2315 return (name->len == 5 && !strcmp(strdata(name), "pairs")) ||
2316 (name->len == 4 && !strcmp(strdata(name), "next"));
2317}
2318
2319/* Parse 'for' iterator. */
2320static void parse_for_iter(LexState *ls, GCstr *indexname)
2321{
2322 FuncState *fs = ls->fs;
2323 ExpDesc e;
2324 BCReg nvars = 0;
2325 BCLine line;
2326 BCReg base = fs->freereg + 3;
2327 BCPos loop, loopend, exprpc = fs->pc;
2328 FuncScope bl;
2329 int isnext;
2330 /* Hidden control variables. */
2331 var_new_fixed(ls, nvars++, VARNAME_FOR_GEN);
2332 var_new_fixed(ls, nvars++, VARNAME_FOR_STATE);
2333 var_new_fixed(ls, nvars++, VARNAME_FOR_CTL);
2334 /* Visible variables returned from iterator. */
2335 var_new(ls, nvars++, indexname);
2336 while (lex_opt(ls, ','))
2337 var_new(ls, nvars++, lex_str(ls));
2338 lex_check(ls, TK_in);
2339 line = ls->linenumber;
2340 assign_adjust(ls, 3, expr_list(ls, &e), &e);
2341 bcreg_bump(fs, 3); /* The iterator needs another 3 slots (func + 2 args). */
2342 isnext = (nvars <= 5 && predict_next(ls, fs, exprpc));
2343 var_add(ls, 3); /* Hidden control variables. */
2344 lex_check(ls, TK_do);
2345 loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP);
2346 scope_begin(fs, &bl, 0); /* Scope for visible variables. */
2347 var_add(ls, nvars-3);
2348 bcreg_reserve(fs, nvars-3);
2349 parse_block(ls);
2350 scope_end(fs);
2351 /* Perform loop inversion. Loop control instructions are at the end. */
2352 jmp_patchins(fs, loop, fs->pc);
2353 bcemit_ABC(fs, isnext ? BC_ITERN : BC_ITERC, base, nvars-3+1, 2+1);
2354 loopend = bcemit_AJ(fs, BC_ITERL, base, NO_JMP);
2355 fs->bcbase[loopend-1].line = line; /* Fix line for control ins. */
2356 fs->bcbase[loopend].line = line;
2357 jmp_patchins(fs, loopend, loop+1);
2358}
2359
2360/* Parse 'for' statement. */
2361static void parse_for(LexState *ls, BCLine line)
2362{
2363 FuncState *fs = ls->fs;
2364 GCstr *varname;
2365 FuncScope bl;
2366 scope_begin(fs, &bl, 1); /* Breakable loop scope. */
2367 lj_lex_next(ls); /* Skip 'for'. */
2368 varname = lex_str(ls); /* Get first variable name. */
2369 if (ls->token == '=')
2370 parse_for_num(ls, varname, line);
2371 else if (ls->token == ',' || ls->token == TK_in)
2372 parse_for_iter(ls, varname);
2373 else
2374 err_syntax(ls, LJ_ERR_XFOR);
2375 lex_match(ls, TK_end, TK_for, line);
2376 scope_end(fs); /* Resolve break list. */
2377}
2378
2379/* Parse condition and 'then' block. */
2380static BCPos parse_then(LexState *ls)
2381{
2382 BCPos condexit;
2383 lj_lex_next(ls); /* Skip 'if' or 'elseif'. */
2384 condexit = expr_cond(ls);
2385 lex_check(ls, TK_then);
2386 parse_block(ls);
2387 return condexit;
2388}
2389
2390/* Parse 'if' statement. */
2391static void parse_if(LexState *ls, BCLine line)
2392{
2393 FuncState *fs = ls->fs;
2394 BCPos flist;
2395 BCPos escapelist = NO_JMP;
2396 flist = parse_then(ls);
2397 while (ls->token == TK_elseif) { /* Parse multiple 'elseif' blocks. */
2398 jmp_append(fs, &escapelist, bcemit_jmp(fs));
2399 jmp_tohere(fs, flist);
2400 flist = parse_then(ls);
2401 }
2402 if (ls->token == TK_else) { /* Parse optional 'else' block. */
2403 jmp_append(fs, &escapelist, bcemit_jmp(fs));
2404 jmp_tohere(fs, flist);
2405 lj_lex_next(ls); /* Skip 'else'. */
2406 parse_block(ls);
2407 } else {
2408 jmp_append(fs, &escapelist, flist);
2409 }
2410 jmp_tohere(fs, escapelist);
2411 lex_match(ls, TK_end, TK_if, line);
2412}
2413
2414/* -- Parse statements ---------------------------------------------------- */
2415
2416/* Parse a statement. Returns 1 if it must be the last one in a chunk. */
2417static int parse_stmt(LexState *ls)
2418{
2419 BCLine line = ls->linenumber;
2420 switch (ls->token) {
2421 case TK_if:
2422 parse_if(ls, line);
2423 break;
2424 case TK_while:
2425 parse_while(ls, line);
2426 break;
2427 case TK_do:
2428 lj_lex_next(ls);
2429 parse_block(ls);
2430 lex_match(ls, TK_end, TK_do, line);
2431 break;
2432 case TK_for:
2433 parse_for(ls, line);
2434 break;
2435 case TK_repeat:
2436 parse_repeat(ls, line);
2437 break;
2438 case TK_function:
2439 parse_func(ls, line);
2440 break;
2441 case TK_local:
2442 lj_lex_next(ls);
2443 parse_local(ls);
2444 break;
2445 case TK_return:
2446 parse_return(ls);
2447 return 1; /* Must be last. */
2448 case TK_break:
2449 lj_lex_next(ls);
2450 parse_break(ls);
2451 return 1; /* Must be last. */
2452#ifdef LUAJIT_ENABLE_LUA52COMPAT
2453 case ';':
2454 lj_lex_next(ls);
2455 break;
2456#endif
2457 default:
2458 parse_call_assign(ls);
2459 break;
2460 }
2461 return 0;
2462}
2463
2464/* A chunk is a list of statements optionally separated by semicolons. */
2465static void parse_chunk(LexState *ls)
2466{
2467 int islast = 0;
2468 synlevel_begin(ls);
2469 while (!islast && !endofblock(ls->token)) {
2470 islast = parse_stmt(ls);
2471 lex_opt(ls, ';');
2472 lua_assert(ls->fs->framesize >= ls->fs->freereg &&
2473 ls->fs->freereg >= ls->fs->nactvar);
2474 ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */
2475 }
2476 synlevel_end(ls);
2477}
2478
2479/* Entry point of bytecode parser. */
2480GCproto *lj_parse(LexState *ls)
2481{
2482 FuncState fs;
2483 GCproto *pt;
2484 lua_State *L = ls->L;
2485#ifdef LUAJIT_DISABLE_DEBUGINFO
2486 ls->chunkname = lj_str_newlit(L, "=");
2487#else
2488 ls->chunkname = lj_str_newz(L, ls->chunkarg);
2489#endif
2490 setstrV(L, L->top, ls->chunkname); /* Anchor chunkname string. */
2491 incr_top(L);
2492 ls->level = 0;
2493 fs_init(ls, &fs);
2494 fs.linedefined = 0;
2495 fs.numparams = 0;
2496 fs.bcbase = NULL;
2497 fs.bclim = 0;
2498 fs.flags |= PROTO_VARARG; /* Main chunk is always a vararg func. */
2499 bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */
2500 lj_lex_next(ls); /* Read-ahead first token. */
2501 parse_chunk(ls);
2502 if (ls->token != TK_eof)
2503 err_token(ls, TK_eof);
2504 pt = fs_finish(ls, ls->linenumber);
2505 L->top--; /* Drop chunkname. */
2506 lua_assert(fs.prev == NULL);
2507 lua_assert(ls->fs == NULL);
2508 lua_assert(pt->sizeuv == 0);
2509 return pt;
2510}
2511
diff --git a/libraries/luajit-2.0/src/lj_parse.h b/libraries/luajit-2.0/src/lj_parse.h
new file mode 100644
index 0000000..0916535
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_parse.h
@@ -0,0 +1,18 @@
1/*
2** Lua parser (source code -> bytecode).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_PARSE_H
7#define _LJ_PARSE_H
8
9#include "lj_obj.h"
10#include "lj_lex.h"
11
12LJ_FUNC GCproto *lj_parse(LexState *ls);
13LJ_FUNC GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t l);
14#if LJ_HASFFI
15LJ_FUNC void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd);
16#endif
17
18#endif
diff --git a/libraries/luajit-2.0/src/lj_record.c b/libraries/luajit-2.0/src/lj_record.c
new file mode 100644
index 0000000..2c27a71
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_record.c
@@ -0,0 +1,2228 @@
1/*
2** Trace recorder (bytecode -> SSA IR).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_record_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12
13#include "lj_err.h"
14#include "lj_str.h"
15#include "lj_tab.h"
16#include "lj_meta.h"
17#include "lj_frame.h"
18#include "lj_bc.h"
19#include "lj_ff.h"
20#include "lj_ir.h"
21#include "lj_jit.h"
22#include "lj_ircall.h"
23#include "lj_iropt.h"
24#include "lj_trace.h"
25#include "lj_record.h"
26#include "lj_ffrecord.h"
27#include "lj_snap.h"
28#include "lj_dispatch.h"
29#include "lj_vm.h"
30
31/* Some local macros to save typing. Undef'd at the end. */
32#define IR(ref) (&J->cur.ir[(ref)])
33
34/* Pass IR on to next optimization in chain (FOLD). */
35#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
36
37/* Emit raw IR without passing through optimizations. */
38#define emitir_raw(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_ir_emit(J))
39
40/* -- Sanity checks ------------------------------------------------------- */
41
42#ifdef LUA_USE_ASSERT
43/* Sanity check the whole IR -- sloooow. */
44static void rec_check_ir(jit_State *J)
45{
46 IRRef i, nins = J->cur.nins, nk = J->cur.nk;
47 lua_assert(nk <= REF_BIAS && nins >= REF_BIAS && nins < 65536);
48 for (i = nins-1; i >= nk; i--) {
49 IRIns *ir = IR(i);
50 uint32_t mode = lj_ir_mode[ir->o];
51 IRRef op1 = ir->op1;
52 IRRef op2 = ir->op2;
53 switch (irm_op1(mode)) {
54 case IRMnone: lua_assert(op1 == 0); break;
55 case IRMref: lua_assert(op1 >= nk);
56 lua_assert(i >= REF_BIAS ? op1 < i : op1 > i); break;
57 case IRMlit: break;
58 case IRMcst: lua_assert(i < REF_BIAS); continue;
59 }
60 switch (irm_op2(mode)) {
61 case IRMnone: lua_assert(op2 == 0); break;
62 case IRMref: lua_assert(op2 >= nk);
63 lua_assert(i >= REF_BIAS ? op2 < i : op2 > i); break;
64 case IRMlit: break;
65 case IRMcst: lua_assert(0); break;
66 }
67 if (ir->prev) {
68 lua_assert(ir->prev >= nk);
69 lua_assert(i >= REF_BIAS ? ir->prev < i : ir->prev > i);
70 lua_assert(ir->o == IR_NOP || IR(ir->prev)->o == ir->o);
71 }
72 }
73}
74
75/* Compare stack slots and frames of the recorder and the VM. */
76static void rec_check_slots(jit_State *J)
77{
78 BCReg s, nslots = J->baseslot + J->maxslot;
79 int32_t depth = 0;
80 cTValue *base = J->L->base - J->baseslot;
81 lua_assert(J->baseslot >= 1 && J->baseslot < LJ_MAX_JSLOTS);
82 lua_assert(J->baseslot == 1 || (J->slot[J->baseslot-1] & TREF_FRAME));
83 lua_assert(nslots < LJ_MAX_JSLOTS);
84 for (s = 0; s < nslots; s++) {
85 TRef tr = J->slot[s];
86 if (tr) {
87 cTValue *tv = &base[s];
88 IRRef ref = tref_ref(tr);
89 IRIns *ir;
90 lua_assert(ref >= J->cur.nk && ref < J->cur.nins);
91 ir = IR(ref);
92 lua_assert(irt_t(ir->t) == tref_t(tr));
93 if (s == 0) {
94 lua_assert(tref_isfunc(tr));
95 } else if ((tr & TREF_FRAME)) {
96 GCfunc *fn = gco2func(frame_gc(tv));
97 BCReg delta = (BCReg)(tv - frame_prev(tv));
98 lua_assert(tref_isfunc(tr));
99 if (tref_isk(tr)) lua_assert(fn == ir_kfunc(ir));
100 lua_assert(s > delta ? (J->slot[s-delta] & TREF_FRAME) : (s == delta));
101 depth++;
102 } else if ((tr & TREF_CONT)) {
103 lua_assert(ir_kptr(ir) == gcrefp(tv->gcr, void));
104 lua_assert((J->slot[s+1] & TREF_FRAME));
105 depth++;
106 } else {
107 if (tvisnumber(tv))
108 lua_assert(tref_isnumber(tr)); /* Could be IRT_INT etc., too. */
109 else
110 lua_assert(itype2irt(tv) == tref_type(tr));
111 if (tref_isk(tr)) { /* Compare constants. */
112 TValue tvk;
113 lj_ir_kvalue(J->L, &tvk, ir);
114 if (!(tvisnum(&tvk) && tvisnan(&tvk)))
115 lua_assert(lj_obj_equal(tv, &tvk));
116 else
117 lua_assert(tvisnum(tv) && tvisnan(tv));
118 }
119 }
120 }
121 }
122 lua_assert(J->framedepth == depth);
123}
124#endif
125
126/* -- Type handling and specialization ------------------------------------ */
127
128/* Note: these functions return tagged references (TRef). */
129
130/* Specialize a slot to a specific type. Note: slot can be negative! */
131static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
132{
133 /* Caller may set IRT_GUARD in t. */
134 TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
135 J->base[slot] = ref;
136 return ref;
137}
138
139/* Specialize a slot to the runtime type. Note: slot can be negative! */
140static TRef sload(jit_State *J, int32_t slot)
141{
142 IRType t = itype2irt(&J->L->base[slot]);
143 TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
144 IRSLOAD_TYPECHECK);
145 if (irtype_ispri(t)) ref = TREF_PRI(t); /* Canonicalize primitive refs. */
146 J->base[slot] = ref;
147 return ref;
148}
149
150/* Get TRef from slot. Load slot and specialize if not done already. */
151#define getslot(J, s) (J->base[(s)] ? J->base[(s)] : sload(J, (int32_t)(s)))
152
153/* Get TRef for current function. */
154static TRef getcurrf(jit_State *J)
155{
156 if (J->base[-1])
157 return J->base[-1];
158 lua_assert(J->baseslot == 1);
159 return sloadt(J, -1, IRT_FUNC, IRSLOAD_READONLY);
160}
161
162/* Compare for raw object equality.
163** Returns 0 if the objects are the same.
164** Returns 1 if they are different, but the same type.
165** Returns 2 for two different types.
166** Comparisons between primitives always return 1 -- no caller cares about it.
167*/
168int lj_record_objcmp(jit_State *J, TRef a, TRef b, cTValue *av, cTValue *bv)
169{
170 int diff = !lj_obj_equal(av, bv);
171 if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */
172 IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
173 IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
174 if (ta != tb) {
175 /* Widen mixed number/int comparisons to number/number comparison. */
176 if (ta == IRT_INT && tb == IRT_NUM) {
177 a = emitir(IRTN(IR_CONV), a, IRCONV_NUM_INT);
178 ta = IRT_NUM;
179 } else if (ta == IRT_NUM && tb == IRT_INT) {
180 b = emitir(IRTN(IR_CONV), b, IRCONV_NUM_INT);
181 } else {
182 return 2; /* Two different types are never equal. */
183 }
184 }
185 emitir(IRTG(diff ? IR_NE : IR_EQ, ta), a, b);
186 }
187 return diff;
188}
189
190/* -- Record loop ops ----------------------------------------------------- */
191
192/* Loop event. */
193typedef enum {
194 LOOPEV_LEAVE, /* Loop is left or not entered. */
195 LOOPEV_ENTERLO, /* Loop is entered with a low iteration count left. */
196 LOOPEV_ENTER /* Loop is entered. */
197} LoopEvent;
198
199/* Canonicalize slots: convert integers to numbers. */
200static void canonicalize_slots(jit_State *J)
201{
202 BCReg s;
203 if (LJ_DUALNUM) return;
204 for (s = J->baseslot+J->maxslot-1; s >= 1; s--) {
205 TRef tr = J->slot[s];
206 if (tref_isinteger(tr)) {
207 IRIns *ir = IR(tref_ref(tr));
208 if (!(ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_READONLY)))
209 J->slot[s] = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
210 }
211 }
212}
213
214/* Stop recording. */
215static void rec_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
216{
217 lj_trace_end(J);
218 J->cur.linktype = (uint8_t)linktype;
219 J->cur.link = (uint16_t)lnk;
220 /* Looping back at the same stack level? */
221 if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
222 if ((J->flags & JIT_F_OPT_LOOP)) /* Shall we try to create a loop? */
223 goto nocanon; /* Do not canonicalize or we lose the narrowing. */
224 if (J->cur.root) /* Otherwise ensure we always link to the root trace. */
225 J->cur.link = J->cur.root;
226 }
227 canonicalize_slots(J);
228nocanon:
229 /* Note: all loop ops must set J->pc to the following instruction! */
230 lj_snap_add(J); /* Add loop snapshot. */
231 J->needsnap = 0;
232 J->mergesnap = 1; /* In case recording continues. */
233}
234
235/* Search bytecode backwards for a int/num constant slot initializer. */
236static TRef find_kinit(jit_State *J, const BCIns *endpc, BCReg slot, IRType t)
237{
238 /* This algorithm is rather simplistic and assumes quite a bit about
239 ** how the bytecode is generated. It works fine for FORI initializers,
240 ** but it won't necessarily work in other cases (e.g. iterator arguments).
241 ** It doesn't do anything fancy, either (like backpropagating MOVs).
242 */
243 const BCIns *pc, *startpc = proto_bc(J->pt);
244 for (pc = endpc-1; pc > startpc; pc--) {
245 BCIns ins = *pc;
246 BCOp op = bc_op(ins);
247 /* First try to find the last instruction that stores to this slot. */
248 if (bcmode_a(op) == BCMbase && bc_a(ins) <= slot) {
249 return 0; /* Multiple results, e.g. from a CALL or KNIL. */
250 } else if (bcmode_a(op) == BCMdst && bc_a(ins) == slot) {
251 if (op == BC_KSHORT || op == BC_KNUM) { /* Found const. initializer. */
252 /* Now try to verify there's no forward jump across it. */
253 const BCIns *kpc = pc;
254 for (; pc > startpc; pc--)
255 if (bc_op(*pc) == BC_JMP) {
256 const BCIns *target = pc+bc_j(*pc)+1;
257 if (target > kpc && target <= endpc)
258 return 0; /* Conditional assignment. */
259 }
260 if (op == BC_KSHORT) {
261 int32_t k = (int32_t)(int16_t)bc_d(ins);
262 return t == IRT_INT ? lj_ir_kint(J, k) : lj_ir_knum(J, (lua_Number)k);
263 } else {
264 cTValue *tv = proto_knumtv(J->pt, bc_d(ins));
265 if (t == IRT_INT) {
266 int32_t k = numberVint(tv);
267 if (tvisint(tv) || numV(tv) == (lua_Number)k) /* -0 is ok here. */
268 return lj_ir_kint(J, k);
269 return 0; /* Type mismatch. */
270 } else {
271 return lj_ir_knum(J, numberVnum(tv));
272 }
273 }
274 }
275 return 0; /* Non-constant initializer. */
276 }
277 }
278 return 0; /* No assignment to this slot found? */
279}
280
281/* Load and optionally convert a FORI argument from a slot. */
282static TRef fori_load(jit_State *J, BCReg slot, IRType t, int mode)
283{
284 int conv = (tvisint(&J->L->base[slot]) != (t==IRT_INT)) ? IRSLOAD_CONVERT : 0;
285 return sloadt(J, (int32_t)slot,
286 t + (((mode & IRSLOAD_TYPECHECK) ||
287 (conv && t == IRT_INT && !(mode >> 16))) ?
288 IRT_GUARD : 0),
289 mode + conv);
290}
291
292/* Peek before FORI to find a const initializer. Otherwise load from slot. */
293static TRef fori_arg(jit_State *J, const BCIns *fori, BCReg slot,
294 IRType t, int mode)
295{
296 TRef tr = J->base[slot];
297 if (!tr) {
298 tr = find_kinit(J, fori, slot, t);
299 if (!tr)
300 tr = fori_load(J, slot, t, mode);
301 }
302 return tr;
303}
304
305/* Return the direction of the FOR loop iterator.
306** It's important to exactly reproduce the semantics of the interpreter.
307*/
308static int rec_for_direction(cTValue *o)
309{
310 return (tvisint(o) ? intV(o) : (int32_t)o->u32.hi) >= 0;
311}
312
313/* Simulate the runtime behavior of the FOR loop iterator. */
314static LoopEvent rec_for_iter(IROp *op, cTValue *o, int isforl)
315{
316 lua_Number stopv = numberVnum(&o[FORL_STOP]);
317 lua_Number idxv = numberVnum(&o[FORL_IDX]);
318 lua_Number stepv = numberVnum(&o[FORL_STEP]);
319 if (isforl)
320 idxv += stepv;
321 if (rec_for_direction(&o[FORL_STEP])) {
322 if (idxv <= stopv) {
323 *op = IR_LE;
324 return idxv + 2*stepv > stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
325 }
326 *op = IR_GT; return LOOPEV_LEAVE;
327 } else {
328 if (stopv <= idxv) {
329 *op = IR_GE;
330 return idxv + 2*stepv < stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
331 }
332 *op = IR_LT; return LOOPEV_LEAVE;
333 }
334}
335
336/* Record checks for FOR loop overflow and step direction. */
337static void rec_for_check(jit_State *J, IRType t, int dir,
338 TRef stop, TRef step, int init)
339{
340 if (!tref_isk(step)) {
341 /* Non-constant step: need a guard for the direction. */
342 TRef zero = (t == IRT_INT) ? lj_ir_kint(J, 0) : lj_ir_knum_zero(J);
343 emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero);
344 /* Add hoistable overflow checks for a narrowed FORL index. */
345 if (init && t == IRT_INT) {
346 if (tref_isk(stop)) {
347 /* Constant stop: optimize check away or to a range check for step. */
348 int32_t k = IR(tref_ref(stop))->i;
349 if (dir) {
350 if (k > 0)
351 emitir(IRTGI(IR_LE), step, lj_ir_kint(J, (int32_t)0x7fffffff-k));
352 } else {
353 if (k < 0)
354 emitir(IRTGI(IR_GE), step, lj_ir_kint(J, (int32_t)0x80000000-k));
355 }
356 } else {
357 /* Stop+step variable: need full overflow check. */
358 TRef tr = emitir(IRTGI(IR_ADDOV), step, stop);
359 emitir(IRTI(IR_USE), tr, 0); /* ADDOV is weak. Avoid dead result. */
360 }
361 }
362 } else if (init && t == IRT_INT && !tref_isk(stop)) {
363 /* Constant step: optimize overflow check to a range check for stop. */
364 int32_t k = IR(tref_ref(step))->i;
365 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
366 emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
367 }
368}
369
370/* Record a FORL instruction. */
371static void rec_for_loop(jit_State *J, const BCIns *fori, ScEvEntry *scev,
372 int init)
373{
374 BCReg ra = bc_a(*fori);
375 cTValue *tv = &J->L->base[ra];
376 TRef idx = J->base[ra+FORL_IDX];
377 IRType t = idx ? tref_type(idx) :
378 (init || LJ_DUALNUM) ? lj_opt_narrow_forl(J, tv) : IRT_NUM;
379 int mode = IRSLOAD_INHERIT +
380 ((!LJ_DUALNUM || tvisint(tv) == (t == IRT_INT)) ? IRSLOAD_READONLY : 0);
381 TRef stop = fori_arg(J, fori, ra+FORL_STOP, t, mode);
382 TRef step = fori_arg(J, fori, ra+FORL_STEP, t, mode);
383 int tc, dir = rec_for_direction(&tv[FORL_STEP]);
384 lua_assert(bc_op(*fori) == BC_FORI || bc_op(*fori) == BC_JFORI);
385 scev->t.irt = t;
386 scev->dir = dir;
387 scev->stop = tref_ref(stop);
388 scev->step = tref_ref(step);
389 rec_for_check(J, t, dir, stop, step, init);
390 scev->start = tref_ref(find_kinit(J, fori, ra+FORL_IDX, IRT_INT));
391 tc = (LJ_DUALNUM &&
392 !(scev->start && irref_isk(scev->stop) && irref_isk(scev->step) &&
393 tvisint(&tv[FORL_IDX]) == (t == IRT_INT))) ?
394 IRSLOAD_TYPECHECK : 0;
395 if (tc) {
396 J->base[ra+FORL_STOP] = stop;
397 J->base[ra+FORL_STEP] = step;
398 }
399 if (!idx)
400 idx = fori_load(J, ra+FORL_IDX, t,
401 IRSLOAD_INHERIT + tc + (J->scev.start << 16));
402 if (!init)
403 J->base[ra+FORL_IDX] = idx = emitir(IRT(IR_ADD, t), idx, step);
404 J->base[ra+FORL_EXT] = idx;
405 scev->idx = tref_ref(idx);
406 J->maxslot = ra+FORL_EXT+1;
407}
408
409/* Record FORL/JFORL or FORI/JFORI. */
410static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl)
411{
412 BCReg ra = bc_a(*fori);
413 TValue *tv = &J->L->base[ra];
414 TRef *tr = &J->base[ra];
415 IROp op;
416 LoopEvent ev;
417 TRef stop;
418 IRType t;
419 if (isforl) { /* Handle FORL/JFORL opcodes. */
420 TRef idx = tr[FORL_IDX];
421 if (tref_ref(idx) == J->scev.idx) {
422 t = J->scev.t.irt;
423 stop = J->scev.stop;
424 idx = emitir(IRT(IR_ADD, t), idx, J->scev.step);
425 tr[FORL_EXT] = tr[FORL_IDX] = idx;
426 } else {
427 ScEvEntry scev;
428 rec_for_loop(J, fori, &scev, 0);
429 t = scev.t.irt;
430 stop = scev.stop;
431 }
432 } else { /* Handle FORI/JFORI opcodes. */
433 BCReg i;
434 lj_meta_for(J->L, tv);
435 t = (LJ_DUALNUM || tref_isint(tr[FORL_IDX])) ? lj_opt_narrow_forl(J, tv) :
436 IRT_NUM;
437 for (i = FORL_IDX; i <= FORL_STEP; i++) {
438 if (!tr[i]) sload(J, ra+i);
439 lua_assert(tref_isnumber_str(tr[i]));
440 if (tref_isstr(tr[i]))
441 tr[i] = emitir(IRTG(IR_STRTO, IRT_NUM), tr[i], 0);
442 if (t == IRT_INT) {
443 if (!tref_isinteger(tr[i]))
444 tr[i] = emitir(IRTGI(IR_CONV), tr[i], IRCONV_INT_NUM|IRCONV_CHECK);
445 } else {
446 if (!tref_isnum(tr[i]))
447 tr[i] = emitir(IRTN(IR_CONV), tr[i], IRCONV_NUM_INT);
448 }
449 }
450 tr[FORL_EXT] = tr[FORL_IDX];
451 stop = tr[FORL_STOP];
452 rec_for_check(J, t, rec_for_direction(&tv[FORL_STEP]),
453 stop, tr[FORL_STEP], 1);
454 }
455
456 ev = rec_for_iter(&op, tv, isforl);
457 if (ev == LOOPEV_LEAVE) {
458 J->maxslot = ra+FORL_EXT+1;
459 J->pc = fori+1;
460 } else {
461 J->maxslot = ra;
462 J->pc = fori+bc_j(*fori)+1;
463 }
464 lj_snap_add(J);
465
466 emitir(IRTG(op, t), tr[FORL_IDX], stop);
467
468 if (ev == LOOPEV_LEAVE) {
469 J->maxslot = ra;
470 J->pc = fori+bc_j(*fori)+1;
471 } else {
472 J->maxslot = ra+FORL_EXT+1;
473 J->pc = fori+1;
474 }
475 J->needsnap = 1;
476 return ev;
477}
478
479/* Record ITERL/JITERL. */
480static LoopEvent rec_iterl(jit_State *J, const BCIns iterins)
481{
482 BCReg ra = bc_a(iterins);
483 lua_assert(J->base[ra] != 0);
484 if (!tref_isnil(J->base[ra])) { /* Looping back? */
485 J->base[ra-1] = J->base[ra]; /* Copy result of ITERC to control var. */
486 J->maxslot = ra-1+bc_b(J->pc[-1]);
487 J->pc += bc_j(iterins)+1;
488 return LOOPEV_ENTER;
489 } else {
490 J->maxslot = ra-3;
491 J->pc++;
492 return LOOPEV_LEAVE;
493 }
494}
495
496/* Record LOOP/JLOOP. Now, that was easy. */
497static LoopEvent rec_loop(jit_State *J, BCReg ra)
498{
499 if (ra < J->maxslot) J->maxslot = ra;
500 J->pc++;
501 return LOOPEV_ENTER;
502}
503
504/* Check if a loop repeatedly failed to trace because it didn't loop back. */
505static int innerloopleft(jit_State *J, const BCIns *pc)
506{
507 ptrdiff_t i;
508 for (i = 0; i < PENALTY_SLOTS; i++)
509 if (mref(J->penalty[i].pc, const BCIns) == pc) {
510 if ((J->penalty[i].reason == LJ_TRERR_LLEAVE ||
511 J->penalty[i].reason == LJ_TRERR_LINNER) &&
512 J->penalty[i].val >= 2*PENALTY_MIN)
513 return 1;
514 break;
515 }
516 return 0;
517}
518
519/* Handle the case when an interpreted loop op is hit. */
520static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev)
521{
522 if (J->parent == 0) {
523 if (pc == J->startpc && J->framedepth + J->retdepth == 0) {
524 /* Same loop? */
525 if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */
526 lj_trace_err(J, LJ_TRERR_LLEAVE);
527 rec_stop(J, LJ_TRLINK_LOOP, J->cur.traceno); /* Looping root trace. */
528 } else if (ev != LOOPEV_LEAVE) { /* Entering inner loop? */
529 /* It's usually better to abort here and wait until the inner loop
530 ** is traced. But if the inner loop repeatedly didn't loop back,
531 ** this indicates a low trip count. In this case try unrolling
532 ** an inner loop even in a root trace. But it's better to be a bit
533 ** more conservative here and only do it for very short loops.
534 */
535 if (!innerloopleft(J, pc))
536 lj_trace_err(J, LJ_TRERR_LINNER); /* Root trace hit an inner loop. */
537 if ((ev != LOOPEV_ENTERLO &&
538 J->loopref && J->cur.nins - J->loopref > 24) || --J->loopunroll < 0)
539 lj_trace_err(J, LJ_TRERR_LUNROLL); /* Limit loop unrolling. */
540 J->loopref = J->cur.nins;
541 }
542 } else if (ev != LOOPEV_LEAVE) { /* Side trace enters an inner loop. */
543 J->loopref = J->cur.nins;
544 if (--J->loopunroll < 0)
545 lj_trace_err(J, LJ_TRERR_LUNROLL); /* Limit loop unrolling. */
546 } /* Side trace continues across a loop that's left or not entered. */
547}
548
549/* Handle the case when an already compiled loop op is hit. */
550static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev)
551{
552 if (J->parent == 0) { /* Root trace hit an inner loop. */
553 /* Better let the inner loop spawn a side trace back here. */
554 lj_trace_err(J, LJ_TRERR_LINNER);
555 } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */
556 J->instunroll = 0; /* Cannot continue across a compiled loop op. */
557 if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
558 rec_stop(J, LJ_TRLINK_LOOP, J->cur.traceno); /* Form an extra loop. */
559 else
560 rec_stop(J, LJ_TRLINK_ROOT, lnk); /* Link to the loop. */
561 } /* Side trace continues across a loop that's left or not entered. */
562}
563
564/* -- Record calls and returns -------------------------------------------- */
565
566/* Specialize to the runtime value of the called function or its prototype. */
567static TRef rec_call_specialize(jit_State *J, GCfunc *fn, TRef tr)
568{
569 TRef kfunc;
570 if (isluafunc(fn)) {
571 GCproto *pt = funcproto(fn);
572 /* 3 or more closures created? Probably not a monomorphic function. */
573 if (pt->flags >= 3*PROTO_CLCOUNT) { /* Specialize to prototype instead. */
574 TRef trpt = emitir(IRT(IR_FLOAD, IRT_P32), tr, IRFL_FUNC_PC);
575 emitir(IRTG(IR_EQ, IRT_P32), trpt, lj_ir_kptr(J, proto_bc(pt)));
576 (void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); /* Prevent GC of proto. */
577 return tr;
578 }
579 }
580 /* Otherwise specialize to the function (closure) value itself. */
581 kfunc = lj_ir_kfunc(J, fn);
582 emitir(IRTG(IR_EQ, IRT_FUNC), tr, kfunc);
583 return kfunc;
584}
585
586/* Record call setup. */
587static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
588{
589 RecordIndex ix;
590 TValue *functv = &J->L->base[func];
591 TRef *fbase = &J->base[func];
592 ptrdiff_t i;
593 for (i = 0; i <= nargs; i++)
594 (void)getslot(J, func+i); /* Ensure func and all args have a reference. */
595 if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */
596 ix.tab = fbase[0];
597 copyTV(J->L, &ix.tabv, functv);
598 if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj))
599 lj_trace_err(J, LJ_TRERR_NOMM);
600 for (i = ++nargs; i > 0; i--) /* Shift arguments up. */
601 fbase[i] = fbase[i-1];
602 fbase[0] = ix.mobj; /* Replace function. */
603 functv = &ix.mobjv;
604 }
605 fbase[0] = TREF_FRAME | rec_call_specialize(J, funcV(functv), fbase[0]);
606 J->maxslot = (BCReg)nargs;
607}
608
609/* Record call. */
610void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs)
611{
612 rec_call_setup(J, func, nargs);
613 /* Bump frame. */
614 J->framedepth++;
615 J->base += func+1;
616 J->baseslot += func+1;
617}
618
619/* Record tail call. */
620void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs)
621{
622 rec_call_setup(J, func, nargs);
623 if (frame_isvarg(J->L->base - 1)) {
624 BCReg cbase = (BCReg)frame_delta(J->L->base - 1);
625 if (--J->framedepth < 0)
626 lj_trace_err(J, LJ_TRERR_NYIRETL);
627 J->baseslot -= (BCReg)cbase;
628 J->base -= cbase;
629 func += cbase;
630 }
631 /* Move func + args down. */
632 memmove(&J->base[-1], &J->base[func], sizeof(TRef)*(J->maxslot+1));
633 /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */
634 /* Tailcalls can form a loop, so count towards the loop unroll limit. */
635 if (++J->tailcalled > J->loopunroll)
636 lj_trace_err(J, LJ_TRERR_LUNROLL);
637}
638
639/* Check unroll limits for down-recursion. */
640static int check_downrec_unroll(jit_State *J, GCproto *pt)
641{
642 IRRef ptref;
643 for (ptref = J->chain[IR_KGC]; ptref; ptref = IR(ptref)->prev)
644 if (ir_kgc(IR(ptref)) == obj2gco(pt)) {
645 int count = 0;
646 IRRef ref;
647 for (ref = J->chain[IR_RETF]; ref; ref = IR(ref)->prev)
648 if (IR(ref)->op1 == ptref)
649 count++;
650 if (count) {
651 if (J->pc == J->startpc) {
652 if (count + J->tailcalled > J->param[JIT_P_recunroll])
653 return 1;
654 } else {
655 lj_trace_err(J, LJ_TRERR_DOWNREC);
656 }
657 }
658 }
659 return 0;
660}
661
662/* Record return. */
663void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
664{
665 TValue *frame = J->L->base - 1;
666 ptrdiff_t i;
667 for (i = 0; i < gotresults; i++)
668 (void)getslot(J, rbase+i); /* Ensure all results have a reference. */
669 while (frame_ispcall(frame)) { /* Immediately resolve pcall() returns. */
670 BCReg cbase = (BCReg)frame_delta(frame);
671 if (--J->framedepth < 0)
672 lj_trace_err(J, LJ_TRERR_NYIRETL);
673 lua_assert(J->baseslot > 1);
674 gotresults++;
675 rbase += cbase;
676 J->baseslot -= (BCReg)cbase;
677 J->base -= cbase;
678 J->base[--rbase] = TREF_TRUE; /* Prepend true to results. */
679 frame = frame_prevd(frame);
680 }
681 /* Return to lower frame via interpreter for unhandled cases. */
682 if (J->framedepth == 0 && J->pt && bc_isret(bc_op(*J->pc)) &&
683 (!frame_islua(frame) ||
684 (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))))) {
685 /* NYI: specialize to frame type and return directly, not via RET*. */
686 for (i = -1; i < (ptrdiff_t)rbase; i++)
687 J->base[i] = 0; /* Purge dead slots. */
688 J->maxslot = rbase + (BCReg)gotresults;
689 rec_stop(J, LJ_TRLINK_RETURN, 0); /* Return to interpreter. */
690 return;
691 }
692 if (frame_isvarg(frame)) {
693 BCReg cbase = (BCReg)frame_delta(frame);
694 if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */
695 lj_trace_err(J, LJ_TRERR_NYIRETL);
696 lua_assert(J->baseslot > 1);
697 rbase += cbase;
698 J->baseslot -= (BCReg)cbase;
699 J->base -= cbase;
700 frame = frame_prevd(frame);
701 }
702 if (frame_islua(frame)) { /* Return to Lua frame. */
703 BCIns callins = *(frame_pc(frame)-1);
704 ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults;
705 BCReg cbase = bc_a(callins);
706 GCproto *pt = funcproto(frame_func(frame - (cbase+1)));
707 if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) {
708 if (check_downrec_unroll(J, pt)) {
709 J->maxslot = (BCReg)(rbase + gotresults);
710 lj_snap_purge(J);
711 rec_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno); /* Down-recursion. */
712 return;
713 }
714 lj_snap_add(J);
715 }
716 for (i = 0; i < nresults; i++) /* Adjust results. */
717 J->base[i-1] = i < gotresults ? J->base[rbase+i] : TREF_NIL;
718 J->maxslot = cbase+(BCReg)nresults;
719 if (J->framedepth > 0) { /* Return to a frame that is part of the trace. */
720 J->framedepth--;
721 lua_assert(J->baseslot > cbase+1);
722 J->baseslot -= cbase+1;
723 J->base -= cbase+1;
724 } else if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) {
725 /* Return to lower frame would leave the loop in a root trace. */
726 lj_trace_err(J, LJ_TRERR_LLEAVE);
727 } else { /* Return to lower frame. Guard for the target we return to. */
728 TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
729 TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame));
730 emitir(IRTG(IR_RETF, IRT_P32), trpt, trpc);
731 J->retdepth++;
732 J->needsnap = 1;
733 lua_assert(J->baseslot == 1);
734 /* Shift result slots up and clear the slots of the new frame below. */
735 memmove(J->base + cbase, J->base-1, sizeof(TRef)*nresults);
736 memset(J->base-1, 0, sizeof(TRef)*(cbase+1));
737 }
738 } else if (frame_iscont(frame)) { /* Return to continuation frame. */
739 ASMFunction cont = frame_contf(frame);
740 BCReg cbase = (BCReg)frame_delta(frame);
741 if ((J->framedepth -= 2) < 0)
742 lj_trace_err(J, LJ_TRERR_NYIRETL);
743 J->baseslot -= (BCReg)cbase;
744 J->base -= cbase;
745 J->maxslot = cbase-2;
746 if (cont == lj_cont_ra) {
747 /* Copy result to destination slot. */
748 BCReg dst = bc_a(*(frame_contpc(frame)-1));
749 J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL;
750 if (dst >= J->maxslot) J->maxslot = dst+1;
751 } else if (cont == lj_cont_nop) {
752 /* Nothing to do here. */
753 } else if (cont == lj_cont_cat) {
754 lua_assert(0);
755 } else {
756 /* Result type already specialized. */
757 lua_assert(cont == lj_cont_condf || cont == lj_cont_condt);
758 }
759 } else {
760 lj_trace_err(J, LJ_TRERR_NYIRETL); /* NYI: handle return to C frame. */
761 }
762 lua_assert(J->baseslot >= 1);
763}
764
765/* -- Metamethod handling ------------------------------------------------- */
766
767/* Prepare to record call to metamethod. */
768static BCReg rec_mm_prep(jit_State *J, ASMFunction cont)
769{
770 BCReg s, top = curr_proto(J->L)->framesize;
771 TRef trcont;
772 setcont(&J->L->base[top], cont);
773#if LJ_64
774 trcont = lj_ir_kptr(J, (void *)((int64_t)cont - (int64_t)lj_vm_asm_begin));
775#else
776 trcont = lj_ir_kptr(J, (void *)cont);
777#endif
778 J->base[top] = trcont | TREF_CONT;
779 J->framedepth++;
780 for (s = J->maxslot; s < top; s++)
781 J->base[s] = 0; /* Clear frame gap to avoid resurrecting previous refs. */
782 return top+1;
783}
784
785/* Record metamethod lookup. */
786int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
787{
788 RecordIndex mix;
789 GCtab *mt;
790 if (tref_istab(ix->tab)) {
791 mt = tabref(tabV(&ix->tabv)->metatable);
792 mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
793 } else if (tref_isudata(ix->tab)) {
794 int udtype = udataV(&ix->tabv)->udtype;
795 mt = tabref(udataV(&ix->tabv)->metatable);
796 /* The metatables of special userdata objects are treated as immutable. */
797 if (udtype != UDTYPE_USERDATA) {
798 cTValue *mo;
799 if (LJ_HASFFI && udtype == UDTYPE_FFI_CLIB) {
800 /* Specialize to the C library namespace object. */
801 emitir(IRTG(IR_EQ, IRT_P32), ix->tab, lj_ir_kptr(J, udataV(&ix->tabv)));
802 } else {
803 /* Specialize to the type of userdata. */
804 TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), ix->tab, IRFL_UDATA_UDTYPE);
805 emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, udtype));
806 }
807 immutable_mt:
808 mo = lj_tab_getstr(mt, mmname_str(J2G(J), mm));
809 if (!mo || tvisnil(mo))
810 return 0; /* No metamethod. */
811 /* Treat metamethod or index table as immutable, too. */
812 if (!(tvisfunc(mo) || tvistab(mo)))
813 lj_trace_err(J, LJ_TRERR_BADTYPE);
814 copyTV(J->L, &ix->mobjv, mo);
815 ix->mobj = lj_ir_kgc(J, gcV(mo), tvisfunc(mo) ? IRT_FUNC : IRT_TAB);
816 ix->mtv = mt;
817 ix->mt = TREF_NIL; /* Dummy value for comparison semantics. */
818 return 1; /* Got metamethod or index table. */
819 }
820 mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_UDATA_META);
821 } else {
822 /* Specialize to base metatable. Must flush mcode in lua_setmetatable(). */
823 mt = tabref(basemt_obj(J2G(J), &ix->tabv));
824 if (mt == NULL) {
825 ix->mt = TREF_NIL;
826 return 0; /* No metamethod. */
827 }
828 /* The cdata metatable is treated as immutable. */
829 if (LJ_HASFFI && tref_iscdata(ix->tab)) goto immutable_mt;
830 ix->mt = mix.tab = lj_ir_ktab(J, mt);
831 goto nocheck;
832 }
833 ix->mt = mt ? mix.tab : TREF_NIL;
834 emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
835nocheck:
836 if (mt) {
837 GCstr *mmstr = mmname_str(J2G(J), mm);
838 cTValue *mo = lj_tab_getstr(mt, mmstr);
839 if (mo && !tvisnil(mo))
840 copyTV(J->L, &ix->mobjv, mo);
841 ix->mtv = mt;
842 settabV(J->L, &mix.tabv, mt);
843 setstrV(J->L, &mix.keyv, mmstr);
844 mix.key = lj_ir_kstr(J, mmstr);
845 mix.val = 0;
846 mix.idxchain = 0;
847 ix->mobj = lj_record_idx(J, &mix);
848 return !tref_isnil(ix->mobj); /* 1 if metamethod found, 0 if not. */
849 }
850 return 0; /* No metamethod. */
851}
852
853/* Record call to arithmetic metamethod. */
854static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm)
855{
856 /* Set up metamethod call first to save ix->tab and ix->tabv. */
857 BCReg func = rec_mm_prep(J, lj_cont_ra);
858 TRef *base = J->base + func;
859 TValue *basev = J->L->base + func;
860 base[1] = ix->tab; base[2] = ix->key;
861 copyTV(J->L, basev+1, &ix->tabv);
862 copyTV(J->L, basev+2, &ix->keyv);
863 if (!lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */
864 if (mm != MM_unm) {
865 ix->tab = ix->key;
866 copyTV(J->L, &ix->tabv, &ix->keyv);
867 if (lj_record_mm_lookup(J, ix, mm)) /* Lookup mm on 2nd operand. */
868 goto ok;
869 }
870 lj_trace_err(J, LJ_TRERR_NOMM);
871 }
872ok:
873 base[0] = ix->mobj;
874 copyTV(J->L, basev+0, &ix->mobjv);
875 lj_record_call(J, func, 2);
876 return 0; /* No result yet. */
877}
878
879/* Record call to __len metamethod. */
880static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv)
881{
882 RecordIndex ix;
883 ix.tab = tr;
884 copyTV(J->L, &ix.tabv, tv);
885 if (lj_record_mm_lookup(J, &ix, MM_len)) {
886 BCReg func = rec_mm_prep(J, lj_cont_ra);
887 TRef *base = J->base + func;
888 TValue *basev = J->L->base + func;
889 base[0] = ix.mobj; copyTV(J->L, basev+0, &ix.mobjv);
890 base[1] = tr; copyTV(J->L, basev+1, tv);
891#ifdef LUAJIT_ENABLE_LUA52COMPAT
892 base[2] = tr; copyTV(J->L, basev+2, tv);
893#else
894 base[2] = TREF_NIL; setnilV(basev+2);
895#endif
896 lj_record_call(J, func, 2);
897 } else {
898#ifdef LUAJIT_ENABLE_LUA52COMPAT
899 if (tref_istab(tr))
900 return lj_ir_call(J, IRCALL_lj_tab_len, tr);
901#endif
902 lj_trace_err(J, LJ_TRERR_NOMM);
903 }
904 return 0; /* No result yet. */
905}
906
907/* Call a comparison metamethod. */
908static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op)
909{
910 BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt);
911 TRef *base = J->base + func;
912 TValue *tv = J->L->base + func;
913 base[0] = ix->mobj; base[1] = ix->val; base[2] = ix->key;
914 copyTV(J->L, tv+0, &ix->mobjv);
915 copyTV(J->L, tv+1, &ix->valv);
916 copyTV(J->L, tv+2, &ix->keyv);
917 lj_record_call(J, func, 2);
918}
919
920/* Record call to equality comparison metamethod (for tab and udata only). */
921static void rec_mm_equal(jit_State *J, RecordIndex *ix, int op)
922{
923 ix->tab = ix->val;
924 copyTV(J->L, &ix->tabv, &ix->valv);
925 if (lj_record_mm_lookup(J, ix, MM_eq)) { /* Lookup mm on 1st operand. */
926 cTValue *bv;
927 TRef mo1 = ix->mobj;
928 TValue mo1v;
929 copyTV(J->L, &mo1v, &ix->mobjv);
930 /* Avoid the 2nd lookup and the objcmp if the metatables are equal. */
931 bv = &ix->keyv;
932 if (tvistab(bv) && tabref(tabV(bv)->metatable) == ix->mtv) {
933 TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_TAB_META);
934 emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
935 } else if (tvisudata(bv) && tabref(udataV(bv)->metatable) == ix->mtv) {
936 TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_UDATA_META);
937 emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
938 } else { /* Lookup metamethod on 2nd operand and compare both. */
939 ix->tab = ix->key;
940 copyTV(J->L, &ix->tabv, bv);
941 if (!lj_record_mm_lookup(J, ix, MM_eq) ||
942 lj_record_objcmp(J, mo1, ix->mobj, &mo1v, &ix->mobjv))
943 return;
944 }
945 rec_mm_callcomp(J, ix, op);
946 }
947}
948
949/* Record call to ordered comparison metamethods (for arbitrary objects). */
950static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
951{
952 ix->tab = ix->val;
953 copyTV(J->L, &ix->tabv, &ix->valv);
954 while (1) {
955 MMS mm = (op & 2) ? MM_le : MM_lt; /* Try __le + __lt or only __lt. */
956 if (lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */
957 cTValue *bv;
958 TRef mo1 = ix->mobj;
959 TValue mo1v;
960 copyTV(J->L, &mo1v, &ix->mobjv);
961 /* Avoid the 2nd lookup and the objcmp if the metatables are equal. */
962 bv = &ix->keyv;
963 if (tvistab(bv) && tabref(tabV(bv)->metatable) == ix->mtv) {
964 TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_TAB_META);
965 emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
966 } else if (tvisudata(bv) && tabref(udataV(bv)->metatable) == ix->mtv) {
967 TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_UDATA_META);
968 emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
969 } else { /* Lookup metamethod on 2nd operand and compare both. */
970 ix->tab = ix->key;
971 copyTV(J->L, &ix->tabv, bv);
972 if (!lj_record_mm_lookup(J, ix, mm) ||
973 lj_record_objcmp(J, mo1, ix->mobj, &mo1v, &ix->mobjv))
974 goto nomatch;
975 }
976 rec_mm_callcomp(J, ix, op);
977 return;
978 }
979 nomatch:
980 /* First lookup failed. Retry with __lt and swapped operands. */
981 if (!(op & 2)) break; /* Already at __lt. Interpreter will throw. */
982 ix->tab = ix->key; ix->key = ix->val; ix->val = ix->tab;
983 copyTV(J->L, &ix->tabv, &ix->keyv);
984 copyTV(J->L, &ix->keyv, &ix->valv);
985 copyTV(J->L, &ix->valv, &ix->tabv);
986 op ^= 3;
987 }
988}
989
990#if LJ_HASFFI
991/* Setup call to cdata comparison metamethod. */
992static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm)
993{
994 lj_snap_add(J);
995 if (tref_iscdata(ix->val)) {
996 ix->tab = ix->val;
997 copyTV(J->L, &ix->tabv, &ix->valv);
998 } else {
999 lua_assert(tref_iscdata(ix->key));
1000 ix->tab = ix->key;
1001 copyTV(J->L, &ix->tabv, &ix->keyv);
1002 }
1003 lj_record_mm_lookup(J, ix, mm);
1004 rec_mm_callcomp(J, ix, op);
1005}
1006#endif
1007
1008/* -- Indexed access ------------------------------------------------------ */
1009
1010/* Record bounds-check. */
1011static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
1012{
1013 /* Try to emit invariant bounds checks. */
1014 if ((J->flags & (JIT_F_OPT_LOOP|JIT_F_OPT_ABC)) ==
1015 (JIT_F_OPT_LOOP|JIT_F_OPT_ABC)) {
1016 IRRef ref = tref_ref(ikey);
1017 IRIns *ir = IR(ref);
1018 int32_t ofs = 0;
1019 IRRef ofsref = 0;
1020 /* Handle constant offsets. */
1021 if (ir->o == IR_ADD && irref_isk(ir->op2)) {
1022 ofsref = ir->op2;
1023 ofs = IR(ofsref)->i;
1024 ref = ir->op1;
1025 ir = IR(ref);
1026 }
1027 /* Got scalar evolution analysis results for this reference? */
1028 if (ref == J->scev.idx) {
1029 int32_t stop;
1030 lua_assert(irt_isint(J->scev.t) && ir->o == IR_SLOAD);
1031 stop = numberVint(&(J->L->base - J->baseslot)[ir->op1 + FORL_STOP]);
1032 /* Runtime value for stop of loop is within bounds? */
1033 if ((int64_t)stop + ofs < (int64_t)asize) {
1034 /* Emit invariant bounds check for stop. */
1035 emitir(IRTG(IR_ABC, IRT_P32), asizeref, ofs == 0 ? J->scev.stop :
1036 emitir(IRTI(IR_ADD), J->scev.stop, ofsref));
1037 /* Emit invariant bounds check for start, if not const or negative. */
1038 if (!(J->scev.dir && J->scev.start &&
1039 (int64_t)IR(J->scev.start)->i + ofs >= 0))
1040 emitir(IRTG(IR_ABC, IRT_P32), asizeref, ikey);
1041 return;
1042 }
1043 }
1044 }
1045 emitir(IRTGI(IR_ABC), asizeref, ikey); /* Emit regular bounds check. */
1046}
1047
1048/* Record indexed key lookup. */
1049static TRef rec_idx_key(jit_State *J, RecordIndex *ix)
1050{
1051 TRef key;
1052 GCtab *t = tabV(&ix->tabv);
1053 ix->oldv = lj_tab_get(J->L, t, &ix->keyv); /* Lookup previous value. */
1054
1055 /* Integer keys are looked up in the array part first. */
1056 key = ix->key;
1057 if (tref_isnumber(key)) {
1058 int32_t k = numberVint(&ix->keyv);
1059 if (!tvisint(&ix->keyv) && numV(&ix->keyv) != (lua_Number)k)
1060 k = LJ_MAX_ASIZE;
1061 if ((MSize)k < LJ_MAX_ASIZE) { /* Potential array key? */
1062 TRef ikey = lj_opt_narrow_index(J, key);
1063 TRef asizeref = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
1064 if ((MSize)k < t->asize) { /* Currently an array key? */
1065 TRef arrayref;
1066 rec_idx_abc(J, asizeref, ikey, t->asize);
1067 arrayref = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_ARRAY);
1068 return emitir(IRT(IR_AREF, IRT_P32), arrayref, ikey);
1069 } else { /* Currently not in array (may be an array extension)? */
1070 emitir(IRTGI(IR_ULE), asizeref, ikey); /* Inv. bounds check. */
1071 if (k == 0 && tref_isk(key))
1072 key = lj_ir_knum_zero(J); /* Canonicalize 0 or +-0.0 to +0.0. */
1073 /* And continue with the hash lookup. */
1074 }
1075 } else if (!tref_isk(key)) {
1076 /* We can rule out const numbers which failed the integerness test
1077 ** above. But all other numbers are potential array keys.
1078 */
1079 if (t->asize == 0) { /* True sparse tables have an empty array part. */
1080 /* Guard that the array part stays empty. */
1081 TRef tmp = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
1082 emitir(IRTGI(IR_EQ), tmp, lj_ir_kint(J, 0));
1083 } else {
1084 lj_trace_err(J, LJ_TRERR_NYITMIX);
1085 }
1086 }
1087 }
1088
1089 /* Otherwise the key is located in the hash part. */
1090 if (t->hmask == 0) { /* Shortcut for empty hash part. */
1091 /* Guard that the hash part stays empty. */
1092 TRef tmp = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
1093 emitir(IRTGI(IR_EQ), tmp, lj_ir_kint(J, 0));
1094 return lj_ir_kkptr(J, niltvg(J2G(J)));
1095 }
1096 if (tref_isinteger(key)) /* Hash keys are based on numbers, not ints. */
1097 ix->key = key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
1098 if (tref_isk(key)) {
1099 /* Optimize lookup of constant hash keys. */
1100 MSize hslot = (MSize)((char *)ix->oldv - (char *)&noderef(t->node)[0].val);
1101 if (t->hmask > 0 && hslot <= t->hmask*(MSize)sizeof(Node) &&
1102 hslot <= 65535*(MSize)sizeof(Node)) {
1103 TRef node, kslot;
1104 TRef hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
1105 emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask));
1106 node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE);
1107 kslot = lj_ir_kslot(J, key, hslot / sizeof(Node));
1108 return emitir(IRTG(IR_HREFK, IRT_P32), node, kslot);
1109 }
1110 }
1111 /* Fall back to a regular hash lookup. */
1112 return emitir(IRT(IR_HREF, IRT_P32), ix->tab, key);
1113}
1114
1115/* Determine whether a key is NOT one of the fast metamethod names. */
1116static int nommstr(jit_State *J, TRef key)
1117{
1118 if (tref_isstr(key)) {
1119 if (tref_isk(key)) {
1120 GCstr *str = ir_kstr(IR(tref_ref(key)));
1121 uint32_t mm;
1122 for (mm = 0; mm <= MM_FAST; mm++)
1123 if (mmname_str(J2G(J), mm) == str)
1124 return 0; /* MUST be one the fast metamethod names. */
1125 } else {
1126 return 0; /* Variable string key MAY be a metamethod name. */
1127 }
1128 }
1129 return 1; /* CANNOT be a metamethod name. */
1130}
1131
1132/* Record indexed load/store. */
1133TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1134{
1135 TRef xref;
1136 IROp xrefop, loadop;
1137 cTValue *oldv;
1138
1139 while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */
1140 /* Never call raw lj_record_idx() on non-table. */
1141 lua_assert(ix->idxchain != 0);
1142 if (!lj_record_mm_lookup(J, ix, ix->val ? MM_newindex : MM_index))
1143 lj_trace_err(J, LJ_TRERR_NOMM);
1144 handlemm:
1145 if (tref_isfunc(ix->mobj)) { /* Handle metamethod call. */
1146 BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra);
1147 TRef *base = J->base + func;
1148 TValue *tv = J->L->base + func;
1149 base[0] = ix->mobj; base[1] = ix->tab; base[2] = ix->key;
1150 setfuncV(J->L, tv+0, funcV(&ix->mobjv));
1151 copyTV(J->L, tv+1, &ix->tabv);
1152 copyTV(J->L, tv+2, &ix->keyv);
1153 if (ix->val) {
1154 base[3] = ix->val;
1155 copyTV(J->L, tv+3, &ix->valv);
1156 lj_record_call(J, func, 3); /* mobj(tab, key, val) */
1157 return 0;
1158 } else {
1159 lj_record_call(J, func, 2); /* res = mobj(tab, key) */
1160 return 0; /* No result yet. */
1161 }
1162 }
1163 /* Otherwise retry lookup with metaobject. */
1164 ix->tab = ix->mobj;
1165 copyTV(J->L, &ix->tabv, &ix->mobjv);
1166 if (--ix->idxchain == 0)
1167 lj_trace_err(J, LJ_TRERR_IDXLOOP);
1168 }
1169
1170 /* First catch nil and NaN keys for tables. */
1171 if (tvisnil(&ix->keyv) || (tvisnum(&ix->keyv) && tvisnan(&ix->keyv))) {
1172 if (ix->val) /* Better fail early. */
1173 lj_trace_err(J, LJ_TRERR_STORENN);
1174 if (tref_isk(ix->key)) {
1175 if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
1176 goto handlemm;
1177 return TREF_NIL;
1178 }
1179 }
1180
1181 /* Record the key lookup. */
1182 xref = rec_idx_key(J, ix);
1183 xrefop = IR(tref_ref(xref))->o;
1184 loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD;
1185 /* The lj_meta_tset() inconsistency is gone, but better play safe. */
1186 oldv = xrefop == IR_KKPTR ? (cTValue *)ir_kptr(IR(tref_ref(xref))) : ix->oldv;
1187
1188 if (ix->val == 0) { /* Indexed load */
1189 IRType t = itype2irt(oldv);
1190 TRef res;
1191 if (oldv == niltvg(J2G(J))) {
1192 emitir(IRTG(IR_EQ, IRT_P32), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1193 res = TREF_NIL;
1194 } else {
1195 res = emitir(IRTG(loadop, t), xref, 0);
1196 }
1197 if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
1198 goto handlemm;
1199 if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitives. */
1200 return res;
1201 } else { /* Indexed store. */
1202 GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
1203 int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
1204 if (tvisnil(oldv)) { /* Previous value was nil? */
1205 /* Need to duplicate the hasmm check for the early guards. */
1206 int hasmm = 0;
1207 if (ix->idxchain && mt) {
1208 cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), MM_newindex));
1209 hasmm = mo && !tvisnil(mo);
1210 }
1211 if (hasmm)
1212 emitir(IRTG(loadop, IRT_NIL), xref, 0); /* Guard for nil value. */
1213 else if (xrefop == IR_HREF)
1214 emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_P32),
1215 xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1216 if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) {
1217 lua_assert(hasmm);
1218 goto handlemm;
1219 }
1220 lua_assert(!hasmm);
1221 if (oldv == niltvg(J2G(J))) { /* Need to insert a new key. */
1222 TRef key = ix->key;
1223 if (tref_isinteger(key)) /* NEWREF needs a TValue as a key. */
1224 key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
1225 xref = emitir(IRT(IR_NEWREF, IRT_P32), ix->tab, key);
1226 keybarrier = 0; /* NEWREF already takes care of the key barrier. */
1227 }
1228 } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
1229 /* Cannot derive that the previous value was non-nil, must do checks. */
1230 if (xrefop == IR_HREF) /* Guard against store to niltv. */
1231 emitir(IRTG(IR_NE, IRT_P32), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1232 if (ix->idxchain) { /* Metamethod lookup required? */
1233 /* A check for NULL metatable is cheaper (hoistable) than a load. */
1234 if (!mt) {
1235 TRef mtref = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
1236 emitir(IRTG(IR_EQ, IRT_TAB), mtref, lj_ir_knull(J, IRT_TAB));
1237 } else {
1238 IRType t = itype2irt(oldv);
1239 emitir(IRTG(loadop, t), xref, 0); /* Guard for non-nil value. */
1240 }
1241 }
1242 } else {
1243 keybarrier = 0; /* Previous non-nil value kept the key alive. */
1244 }
1245 /* Convert int to number before storing. */
1246 if (!LJ_DUALNUM && tref_isinteger(ix->val))
1247 ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT);
1248 emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val);
1249 if (keybarrier || tref_isgcv(ix->val))
1250 emitir(IRT(IR_TBAR, IRT_NIL), ix->tab, 0);
1251 /* Invalidate neg. metamethod cache for stores with certain string keys. */
1252 if (!nommstr(J, ix->key)) {
1253 TRef fref = emitir(IRT(IR_FREF, IRT_P32), ix->tab, IRFL_TAB_NOMM);
1254 emitir(IRT(IR_FSTORE, IRT_U8), fref, lj_ir_kint(J, 0));
1255 }
1256 J->needsnap = 1;
1257 return 0;
1258 }
1259}
1260
1261/* -- Upvalue access ------------------------------------------------------ */
1262
1263/* Record upvalue load/store. */
1264static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
1265{
1266 GCupval *uvp = &gcref(J->fn->l.uvptr[uv])->uv;
1267 TRef fn = getcurrf(J);
1268 IRRef uref;
1269 int needbarrier = 0;
1270 /* Note: this effectively limits LJ_MAX_UPVAL to 127. */
1271 uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
1272 if (!uvp->closed) {
1273 /* In current stack? */
1274 if (uvval(uvp) >= tvref(J->L->stack) &&
1275 uvval(uvp) < tvref(J->L->maxstack)) {
1276 int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot));
1277 if (slot >= 0) { /* Aliases an SSA slot? */
1278 slot -= (int32_t)J->baseslot; /* Note: slot number may be negative! */
1279 /* NYI: add IR to guard that it's still aliasing the same slot. */
1280 if (val == 0) {
1281 return getslot(J, slot);
1282 } else {
1283 J->base[slot] = val;
1284 if (slot >= (int32_t)J->maxslot) J->maxslot = (BCReg)(slot+1);
1285 return 0;
1286 }
1287 }
1288 }
1289 uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv));
1290 } else {
1291 needbarrier = 1;
1292 uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_P32), fn, uv));
1293 }
1294 if (val == 0) { /* Upvalue load */
1295 IRType t = itype2irt(uvval(uvp));
1296 TRef res = emitir(IRTG(IR_ULOAD, t), uref, 0);
1297 if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitive refs. */
1298 return res;
1299 } else { /* Upvalue store. */
1300 /* Convert int to number before storing. */
1301 if (!LJ_DUALNUM && tref_isinteger(val))
1302 val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT);
1303 emitir(IRT(IR_USTORE, tref_type(val)), uref, val);
1304 if (needbarrier && tref_isgcv(val))
1305 emitir(IRT(IR_OBAR, IRT_NIL), uref, val);
1306 J->needsnap = 1;
1307 return 0;
1308 }
1309}
1310
1311/* -- Record calls to Lua functions --------------------------------------- */
1312
1313/* Check unroll limits for calls. */
1314static void check_call_unroll(jit_State *J, TraceNo lnk)
1315{
1316 cTValue *frame = J->L->base - 1;
1317 void *pc = mref(frame_func(frame)->l.pc, void);
1318 int32_t depth = J->framedepth;
1319 int32_t count = 0;
1320 if ((J->pt->flags & PROTO_VARARG)) depth--; /* Vararg frame still missing. */
1321 for (; depth > 0; depth--) { /* Count frames with same prototype. */
1322 frame = frame_prev(frame);
1323 if (mref(frame_func(frame)->l.pc, void) == pc)
1324 count++;
1325 }
1326 if (J->pc == J->startpc) {
1327 if (count + J->tailcalled > J->param[JIT_P_recunroll]) {
1328 J->pc++;
1329 if (J->framedepth + J->retdepth == 0)
1330 rec_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno); /* Tail-recursion. */
1331 else
1332 rec_stop(J, LJ_TRLINK_UPREC, J->cur.traceno); /* Up-recursion. */
1333 }
1334 } else {
1335 if (count > J->param[JIT_P_callunroll]) {
1336 if (lnk) { /* Possible tail- or up-recursion. */
1337 lj_trace_flush(J, lnk); /* Flush trace that only returns. */
1338 /* Set a small, pseudo-random hotcount for a quick retry of JFUNC*. */
1339 hotcount_set(J2GG(J), J->pc+1, LJ_PRNG_BITS(J, 4));
1340 }
1341 lj_trace_err(J, LJ_TRERR_CUNROLL);
1342 }
1343 }
1344}
1345
1346/* Record Lua function setup. */
1347static void rec_func_setup(jit_State *J)
1348{
1349 GCproto *pt = J->pt;
1350 BCReg s, numparams = pt->numparams;
1351 if ((pt->flags & PROTO_NOJIT))
1352 lj_trace_err(J, LJ_TRERR_CJITOFF);
1353 if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS)
1354 lj_trace_err(J, LJ_TRERR_STACKOV);
1355 /* Fill up missing parameters with nil. */
1356 for (s = J->maxslot; s < numparams; s++)
1357 J->base[s] = TREF_NIL;
1358 /* The remaining slots should never be read before they are written. */
1359 J->maxslot = numparams;
1360}
1361
1362/* Record Lua vararg function setup. */
1363static void rec_func_vararg(jit_State *J)
1364{
1365 GCproto *pt = J->pt;
1366 BCReg s, fixargs, vframe = J->maxslot+1;
1367 lua_assert((pt->flags & PROTO_VARARG));
1368 if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS)
1369 lj_trace_err(J, LJ_TRERR_STACKOV);
1370 J->base[vframe-1] = J->base[-1]; /* Copy function up. */
1371 /* Copy fixarg slots up and set their original slots to nil. */
1372 fixargs = pt->numparams < J->maxslot ? pt->numparams : J->maxslot;
1373 for (s = 0; s < fixargs; s++) {
1374 J->base[vframe+s] = J->base[s];
1375 J->base[s] = TREF_NIL;
1376 }
1377 J->maxslot = fixargs;
1378 J->framedepth++;
1379 J->base += vframe;
1380 J->baseslot += vframe;
1381}
1382
1383/* Record entry to a Lua function. */
1384static void rec_func_lua(jit_State *J)
1385{
1386 rec_func_setup(J);
1387 check_call_unroll(J, 0);
1388}
1389
1390/* Record entry to an already compiled function. */
1391static void rec_func_jit(jit_State *J, TraceNo lnk)
1392{
1393 GCtrace *T;
1394 rec_func_setup(J);
1395 T = traceref(J, lnk);
1396 if (T->linktype == LJ_TRLINK_RETURN) { /* Trace returns to interpreter? */
1397 check_call_unroll(J, lnk);
1398 /* Temporarily unpatch JFUNC* to continue recording across function. */
1399 J->patchins = *J->pc;
1400 J->patchpc = (BCIns *)J->pc;
1401 *J->patchpc = T->startins;
1402 return;
1403 }
1404 J->instunroll = 0; /* Cannot continue across a compiled function. */
1405 if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
1406 rec_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno); /* Extra tail-recursion. */
1407 else
1408 rec_stop(J, LJ_TRLINK_ROOT, lnk); /* Link to the function. */
1409}
1410
1411/* -- Vararg handling ----------------------------------------------------- */
1412
1413/* Detect y = select(x, ...) idiom. */
1414static int select_detect(jit_State *J)
1415{
1416 BCIns ins = J->pc[1];
1417 if (bc_op(ins) == BC_CALLM && bc_b(ins) == 2 && bc_c(ins) == 1) {
1418 cTValue *func = &J->L->base[bc_a(ins)];
1419 if (tvisfunc(func) && funcV(func)->c.ffid == FF_select)
1420 return 1;
1421 }
1422 return 0;
1423}
1424
1425/* Record vararg instruction. */
1426static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
1427{
1428 int32_t numparams = J->pt->numparams;
1429 ptrdiff_t nvararg = frame_delta(J->L->base-1) - numparams - 1;
1430 lua_assert(frame_isvarg(J->L->base-1));
1431 if (J->framedepth > 0) { /* Simple case: varargs defined on-trace. */
1432 ptrdiff_t i;
1433 if (nvararg < 0) nvararg = 0;
1434 if (nresults == -1) {
1435 nresults = nvararg;
1436 J->maxslot = dst + (BCReg)nvararg;
1437 } else if (dst + nresults > J->maxslot) {
1438 J->maxslot = dst + (BCReg)nresults;
1439 }
1440 for (i = 0; i < nresults; i++) {
1441 J->base[dst+i] = i < nvararg ? J->base[i - nvararg - 1] : TREF_NIL;
1442 lua_assert(J->base[dst+i] != 0);
1443 }
1444 } else { /* Unknown number of varargs passed to trace. */
1445 TRef fr = emitir(IRTI(IR_SLOAD), 0, IRSLOAD_READONLY|IRSLOAD_FRAME);
1446 int32_t frofs = 8*(1+numparams)+FRAME_VARG;
1447 if (nresults >= 0) { /* Known fixed number of results. */
1448 ptrdiff_t i;
1449 if (nvararg > 0) {
1450 ptrdiff_t nload = nvararg >= nresults ? nresults : nvararg;
1451 TRef vbase;
1452 if (nvararg >= nresults)
1453 emitir(IRTGI(IR_GE), fr, lj_ir_kint(J, frofs+8*(int32_t)nresults));
1454 else
1455 emitir(IRTGI(IR_EQ), fr, lj_ir_kint(J, frame_ftsz(J->L->base-1)));
1456 vbase = emitir(IRTI(IR_SUB), REF_BASE, fr);
1457 vbase = emitir(IRT(IR_ADD, IRT_P32), vbase, lj_ir_kint(J, frofs-8));
1458 for (i = 0; i < nload; i++) {
1459 IRType t = itype2irt(&J->L->base[i-1-nvararg]);
1460 TRef aref = emitir(IRT(IR_AREF, IRT_P32),
1461 vbase, lj_ir_kint(J, (int32_t)i));
1462 TRef tr = emitir(IRTG(IR_VLOAD, t), aref, 0);
1463 if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */
1464 J->base[dst+i] = tr;
1465 }
1466 } else {
1467 emitir(IRTGI(IR_LE), fr, lj_ir_kint(J, frofs));
1468 nvararg = 0;
1469 }
1470 for (i = nvararg; i < nresults; i++)
1471 J->base[dst+i] = TREF_NIL;
1472 if (dst + (BCReg)nresults > J->maxslot)
1473 J->maxslot = dst + (BCReg)nresults;
1474 } else if (select_detect(J)) { /* y = select(x, ...) */
1475 TRef tridx = J->base[dst-1];
1476 TRef tr = TREF_NIL;
1477 ptrdiff_t idx = lj_ffrecord_select_mode(J, tridx, &J->L->base[dst-1]);
1478 if (idx < 0) goto nyivarg;
1479 if (idx != 0 && !tref_isinteger(tridx))
1480 tridx = emitir(IRTGI(IR_CONV), tridx, IRCONV_INT_NUM|IRCONV_INDEX);
1481 if (idx != 0 && tref_isk(tridx)) {
1482 emitir(IRTGI(idx <= nvararg ? IR_GE : IR_LT),
1483 fr, lj_ir_kint(J, frofs+8*(int32_t)idx));
1484 frofs -= 8; /* Bias for 1-based index. */
1485 } else if (idx <= nvararg) { /* Compute size. */
1486 TRef tmp = emitir(IRTI(IR_ADD), fr, lj_ir_kint(J, -frofs));
1487 if (numparams)
1488 emitir(IRTGI(IR_GE), tmp, lj_ir_kint(J, 0));
1489 tr = emitir(IRTI(IR_BSHR), tmp, lj_ir_kint(J, 3));
1490 if (idx != 0) {
1491 tridx = emitir(IRTI(IR_ADD), tridx, lj_ir_kint(J, -1));
1492 rec_idx_abc(J, tr, tridx, (uint32_t)nvararg);
1493 }
1494 } else {
1495 TRef tmp = lj_ir_kint(J, frofs);
1496 if (idx != 0) {
1497 TRef tmp2 = emitir(IRTI(IR_BSHL), tridx, lj_ir_kint(J, 3));
1498 tmp = emitir(IRTI(IR_ADD), tmp2, tmp);
1499 } else {
1500 tr = lj_ir_kint(J, 0);
1501 }
1502 emitir(IRTGI(IR_LT), fr, tmp);
1503 }
1504 if (idx != 0 && idx <= nvararg) {
1505 IRType t;
1506 TRef aref, vbase = emitir(IRTI(IR_SUB), REF_BASE, fr);
1507 vbase = emitir(IRT(IR_ADD, IRT_P32), vbase, lj_ir_kint(J, frofs-8));
1508 t = itype2irt(&J->L->base[idx-2-nvararg]);
1509 aref = emitir(IRT(IR_AREF, IRT_P32), vbase, tridx);
1510 tr = emitir(IRTG(IR_VLOAD, t), aref, 0);
1511 if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */
1512 }
1513 J->base[dst-2] = tr;
1514 J->maxslot = dst-1;
1515 J->bcskip = 2; /* Skip CALLM + select. */
1516 } else {
1517 nyivarg:
1518 setintV(&J->errinfo, BC_VARG);
1519 lj_trace_err_info(J, LJ_TRERR_NYIBC);
1520 }
1521 }
1522}
1523
1524/* -- Record allocations -------------------------------------------------- */
1525
1526static TRef rec_tnew(jit_State *J, uint32_t ah)
1527{
1528 uint32_t asize = ah & 0x7ff;
1529 uint32_t hbits = ah >> 11;
1530 if (asize == 0x7ff) asize = 0x801;
1531 return emitir(IRTG(IR_TNEW, IRT_TAB), asize, hbits);
1532}
1533
1534/* -- Record bytecode ops ------------------------------------------------- */
1535
1536/* Prepare for comparison. */
1537static void rec_comp_prep(jit_State *J)
1538{
1539 /* Prevent merging with snapshot #0 (GC exit) since we fixup the PC. */
1540 if (J->cur.nsnap == 1 && J->cur.snap[0].ref == J->cur.nins)
1541 emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0);
1542 lj_snap_add(J);
1543}
1544
1545/* Fixup comparison. */
1546static void rec_comp_fixup(jit_State *J, const BCIns *pc, int cond)
1547{
1548 BCIns jmpins = pc[1];
1549 const BCIns *npc = pc + 2 + (cond ? bc_j(jmpins) : 0);
1550 SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
1551 /* Set PC to opposite target to avoid re-recording the comp. in side trace. */
1552 J->cur.snapmap[snap->mapofs + snap->nent] = SNAP_MKPC(npc);
1553 J->needsnap = 1;
1554 if (bc_a(jmpins) < J->maxslot) J->maxslot = bc_a(jmpins);
1555 lj_snap_shrink(J); /* Shrink last snapshot if possible. */
1556}
1557
1558/* Record the next bytecode instruction (_before_ it's executed). */
1559void lj_record_ins(jit_State *J)
1560{
1561 cTValue *lbase;
1562 RecordIndex ix;
1563 const BCIns *pc;
1564 BCIns ins;
1565 BCOp op;
1566 TRef ra, rb, rc;
1567
1568 /* Perform post-processing action before recording the next instruction. */
1569 if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) {
1570 switch (J->postproc) {
1571 case LJ_POST_FIXCOMP: /* Fixup comparison. */
1572 pc = frame_pc(&J2G(J)->tmptv);
1573 rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1)));
1574 /* fallthrough */
1575 case LJ_POST_FIXGUARD: /* Fixup and emit pending guard. */
1576 case LJ_POST_FIXGUARDSNAP: /* Fixup and emit pending guard and snapshot. */
1577 if (!tvistruecond(&J2G(J)->tmptv2)) {
1578 J->fold.ins.o ^= 1; /* Flip guard to opposite. */
1579 if (J->postproc == LJ_POST_FIXGUARDSNAP) {
1580 SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
1581 J->cur.snapmap[snap->mapofs+snap->nent-1]--; /* False -> true. */
1582 }
1583 }
1584 lj_opt_fold(J); /* Emit pending guard. */
1585 /* fallthrough */
1586 case LJ_POST_FIXBOOL:
1587 if (!tvistruecond(&J2G(J)->tmptv2)) {
1588 BCReg s;
1589 for (s = 0; s < J->maxslot; s++) /* Fixup stack slot (if any). */
1590 if (J->base[s] == TREF_TRUE && tvisfalse(&J->L->base[s])) {
1591 J->base[s] = TREF_FALSE;
1592 break;
1593 }
1594 }
1595 break;
1596 case LJ_POST_FFRETRY: /* Suppress recording of retried fast function. */
1597 if (bc_op(*J->pc) >= BC__MAX)
1598 return;
1599 break;
1600 default: lua_assert(0); break;
1601 }
1602 J->postproc = LJ_POST_NONE;
1603 }
1604
1605 /* Need snapshot before recording next bytecode (e.g. after a store). */
1606 if (J->needsnap) {
1607 J->needsnap = 0;
1608 lj_snap_purge(J);
1609 lj_snap_add(J);
1610 J->mergesnap = 1;
1611 }
1612
1613 /* Skip some bytecodes. */
1614 if (LJ_UNLIKELY(J->bcskip > 0)) {
1615 J->bcskip--;
1616 return;
1617 }
1618
1619 /* Record only closed loops for root traces. */
1620 pc = J->pc;
1621 if (J->framedepth == 0 &&
1622 (MSize)((char *)pc - (char *)J->bc_min) >= J->bc_extent)
1623 lj_trace_err(J, LJ_TRERR_LLEAVE);
1624
1625#ifdef LUA_USE_ASSERT
1626 rec_check_slots(J);
1627 rec_check_ir(J);
1628#endif
1629
1630 /* Keep a copy of the runtime values of var/num/str operands. */
1631#define rav (&ix.valv)
1632#define rbv (&ix.tabv)
1633#define rcv (&ix.keyv)
1634
1635 lbase = J->L->base;
1636 ins = *pc;
1637 op = bc_op(ins);
1638 ra = bc_a(ins);
1639 ix.val = 0;
1640 switch (bcmode_a(op)) {
1641 case BCMvar:
1642 copyTV(J->L, rav, &lbase[ra]); ix.val = ra = getslot(J, ra); break;
1643 default: break; /* Handled later. */
1644 }
1645 rb = bc_b(ins);
1646 rc = bc_c(ins);
1647 switch (bcmode_b(op)) {
1648 case BCMnone: rb = 0; rc = bc_d(ins); break; /* Upgrade rc to 'rd'. */
1649 case BCMvar:
1650 copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
1651 default: break; /* Handled later. */
1652 }
1653 switch (bcmode_c(op)) {
1654 case BCMvar:
1655 copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
1656 case BCMpri: setitype(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break;
1657 case BCMnum: { cTValue *tv = proto_knumtv(J->pt, rc);
1658 copyTV(J->L, rcv, tv); ix.key = rc = tvisint(tv) ? lj_ir_kint(J, intV(tv)) :
1659 lj_ir_knumint(J, numV(tv)); } break;
1660 case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
1661 setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
1662 default: break; /* Handled later. */
1663 }
1664
1665 switch (op) {
1666
1667 /* -- Comparison ops ---------------------------------------------------- */
1668
1669 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
1670#if LJ_HASFFI
1671 if (tref_iscdata(ra) || tref_iscdata(rc)) {
1672 rec_mm_comp_cdata(J, &ix, op, ((int)op & 2) ? MM_le : MM_lt);
1673 break;
1674 }
1675#endif
1676 /* Emit nothing for two numeric or string consts. */
1677 if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
1678 IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
1679 IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
1680 int irop;
1681 if (ta != tc) {
1682 /* Widen mixed number/int comparisons to number/number comparison. */
1683 if (ta == IRT_INT && tc == IRT_NUM) {
1684 ra = emitir(IRTN(IR_CONV), ra, IRCONV_NUM_INT);
1685 ta = IRT_NUM;
1686 } else if (ta == IRT_NUM && tc == IRT_INT) {
1687 rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
1688 } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
1689 (tc == IRT_FALSE || tc == IRT_TRUE))) {
1690 break; /* Interpreter will throw for two different types. */
1691 }
1692 }
1693 rec_comp_prep(J);
1694 irop = (int)op - (int)BC_ISLT + (int)IR_LT;
1695 if (ta == IRT_NUM) {
1696 if ((irop & 1)) irop ^= 4; /* ISGE/ISGT are unordered. */
1697 if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
1698 irop ^= 5;
1699 } else if (ta == IRT_INT) {
1700 if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
1701 irop ^= 1;
1702 } else if (ta == IRT_STR) {
1703 if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1;
1704 ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc);
1705 rc = lj_ir_kint(J, 0);
1706 ta = IRT_INT;
1707 } else {
1708 rec_mm_comp(J, &ix, (int)op);
1709 break;
1710 }
1711 emitir(IRTG(irop, ta), ra, rc);
1712 rec_comp_fixup(J, J->pc, ((int)op ^ irop) & 1);
1713 }
1714 break;
1715
1716 case BC_ISEQV: case BC_ISNEV:
1717 case BC_ISEQS: case BC_ISNES:
1718 case BC_ISEQN: case BC_ISNEN:
1719 case BC_ISEQP: case BC_ISNEP:
1720#if LJ_HASFFI
1721 if (tref_iscdata(ra) || tref_iscdata(rc)) {
1722 rec_mm_comp_cdata(J, &ix, op, MM_eq);
1723 break;
1724 }
1725#endif
1726 /* Emit nothing for two non-table, non-udata consts. */
1727 if (!(tref_isk2(ra, rc) && !(tref_istab(ra) || tref_isudata(ra)))) {
1728 int diff;
1729 rec_comp_prep(J);
1730 diff = lj_record_objcmp(J, ra, rc, rav, rcv);
1731 if (diff == 1 && (tref_istab(ra) || tref_isudata(ra))) {
1732 /* Only check __eq if different, but the same type (table or udata). */
1733 rec_mm_equal(J, &ix, (int)op);
1734 break;
1735 }
1736 rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
1737 }
1738 break;
1739
1740 /* -- Unary test and copy ops ------------------------------------------- */
1741
1742 case BC_ISTC: case BC_ISFC:
1743 if ((op & 1) == tref_istruecond(rc))
1744 rc = 0; /* Don't store if condition is not true. */
1745 /* fallthrough */
1746 case BC_IST: case BC_ISF: /* Type specialization suffices. */
1747 if (bc_a(pc[1]) < J->maxslot)
1748 J->maxslot = bc_a(pc[1]); /* Shrink used slots. */
1749 break;
1750
1751 /* -- Unary ops --------------------------------------------------------- */
1752
1753 case BC_NOT:
1754 /* Type specialization already forces const result. */
1755 rc = tref_istruecond(rc) ? TREF_FALSE : TREF_TRUE;
1756 break;
1757
1758 case BC_LEN:
1759 if (tref_isstr(rc))
1760 rc = emitir(IRTI(IR_FLOAD), rc, IRFL_STR_LEN);
1761#ifndef LUAJIT_ENABLE_LUA52COMPAT
1762 else if (tref_istab(rc))
1763 rc = lj_ir_call(J, IRCALL_lj_tab_len, rc);
1764#endif
1765 else
1766 rc = rec_mm_len(J, rc, rcv);
1767 break;
1768
1769 /* -- Arithmetic ops ---------------------------------------------------- */
1770
1771 case BC_UNM:
1772 if (tref_isnumber_str(rc)) {
1773 rc = lj_opt_narrow_unm(J, rc, rcv);
1774 } else {
1775 ix.tab = rc;
1776 copyTV(J->L, &ix.tabv, rcv);
1777 rc = rec_mm_arith(J, &ix, MM_unm);
1778 }
1779 break;
1780
1781 case BC_ADDNV: case BC_SUBNV: case BC_MULNV: case BC_DIVNV: case BC_MODNV:
1782 /* Swap rb/rc and rbv/rcv. rav is temp. */
1783 ix.tab = rc; ix.key = rc = rb; rb = ix.tab;
1784 copyTV(J->L, rav, rbv);
1785 copyTV(J->L, rbv, rcv);
1786 copyTV(J->L, rcv, rav);
1787 if (op == BC_MODNV)
1788 goto recmod;
1789 /* fallthrough */
1790 case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
1791 case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
1792 MMS mm = bcmode_mm(op);
1793 if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
1794 rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
1795 (int)mm - (int)MM_add + (int)IR_ADD);
1796 else
1797 rc = rec_mm_arith(J, &ix, mm);
1798 break;
1799 }
1800
1801 case BC_MODVN: case BC_MODVV:
1802 recmod:
1803 if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
1804 rc = lj_opt_narrow_mod(J, rb, rc, rcv);
1805 else
1806 rc = rec_mm_arith(J, &ix, MM_mod);
1807 break;
1808
1809 case BC_POW:
1810 if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
1811 rc = lj_opt_narrow_pow(J, lj_ir_tonum(J, rb), rc, rcv);
1812 else
1813 rc = rec_mm_arith(J, &ix, MM_pow);
1814 break;
1815
1816 /* -- Constant and move ops --------------------------------------------- */
1817
1818 case BC_MOV:
1819 /* Clear gap of method call to avoid resurrecting previous refs. */
1820 if (ra > J->maxslot) J->base[ra-1] = 0;
1821 break;
1822 case BC_KSTR: case BC_KNUM: case BC_KPRI:
1823 break;
1824 case BC_KSHORT:
1825 rc = lj_ir_kint(J, (int32_t)(int16_t)rc);
1826 break;
1827 case BC_KNIL:
1828 while (ra <= rc)
1829 J->base[ra++] = TREF_NIL;
1830 if (rc >= J->maxslot) J->maxslot = rc+1;
1831 break;
1832#if LJ_HASFFI
1833 case BC_KCDATA:
1834 rc = lj_ir_kgc(J, proto_kgc(J->pt, ~(ptrdiff_t)rc), IRT_CDATA);
1835 break;
1836#endif
1837
1838 /* -- Upvalue and function ops ------------------------------------------ */
1839
1840 case BC_UGET:
1841 rc = rec_upvalue(J, rc, 0);
1842 break;
1843 case BC_USETV: case BC_USETS: case BC_USETN: case BC_USETP:
1844 rec_upvalue(J, ra, rc);
1845 break;
1846
1847 /* -- Table ops --------------------------------------------------------- */
1848
1849 case BC_GGET: case BC_GSET:
1850 settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
1851 ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
1852 ix.idxchain = LJ_MAX_IDXCHAIN;
1853 rc = lj_record_idx(J, &ix);
1854 break;
1855
1856 case BC_TGETB: case BC_TSETB:
1857 setintV(&ix.keyv, (int32_t)rc);
1858 ix.key = lj_ir_kint(J, (int32_t)rc);
1859 /* fallthrough */
1860 case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
1861 ix.idxchain = LJ_MAX_IDXCHAIN;
1862 rc = lj_record_idx(J, &ix);
1863 break;
1864
1865 case BC_TNEW:
1866 rc = rec_tnew(J, rc);
1867 break;
1868 case BC_TDUP:
1869 rc = emitir(IRTG(IR_TDUP, IRT_TAB),
1870 lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0);
1871 break;
1872
1873 /* -- Calls and vararg handling ----------------------------------------- */
1874
1875 case BC_ITERC:
1876 J->base[ra] = getslot(J, ra-3);
1877 J->base[ra+1] = getslot(J, ra-2);
1878 J->base[ra+2] = getslot(J, ra-1);
1879 { /* Do the actual copy now because lj_record_call needs the values. */
1880 TValue *b = &J->L->base[ra];
1881 copyTV(J->L, b, b-3);
1882 copyTV(J->L, b+1, b-2);
1883 copyTV(J->L, b+2, b-1);
1884 }
1885 lj_record_call(J, ra, (ptrdiff_t)rc-1);
1886 break;
1887
1888 /* L->top is set to L->base+ra+rc+NARGS-1+1. See lj_dispatch_ins(). */
1889 case BC_CALLM:
1890 rc = (BCReg)(J->L->top - J->L->base) - ra;
1891 /* fallthrough */
1892 case BC_CALL:
1893 lj_record_call(J, ra, (ptrdiff_t)rc-1);
1894 break;
1895
1896 case BC_CALLMT:
1897 rc = (BCReg)(J->L->top - J->L->base) - ra;
1898 /* fallthrough */
1899 case BC_CALLT:
1900 lj_record_tailcall(J, ra, (ptrdiff_t)rc-1);
1901 break;
1902
1903 case BC_VARG:
1904 rec_varg(J, ra, (ptrdiff_t)rb-1);
1905 break;
1906
1907 /* -- Returns ----------------------------------------------------------- */
1908
1909 case BC_RETM:
1910 /* L->top is set to L->base+ra+rc+NRESULTS-1, see lj_dispatch_ins(). */
1911 rc = (BCReg)(J->L->top - J->L->base) - ra + 1;
1912 /* fallthrough */
1913 case BC_RET: case BC_RET0: case BC_RET1:
1914 lj_record_ret(J, ra, (ptrdiff_t)rc-1);
1915 break;
1916
1917 /* -- Loops and branches ------------------------------------------------ */
1918
1919 case BC_FORI:
1920 if (rec_for(J, pc, 0) != LOOPEV_LEAVE)
1921 J->loopref = J->cur.nins;
1922 break;
1923 case BC_JFORI:
1924 lua_assert(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL);
1925 if (rec_for(J, pc, 0) != LOOPEV_LEAVE) /* Link to existing loop. */
1926 rec_stop(J, LJ_TRLINK_ROOT, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
1927 /* Continue tracing if the loop is not entered. */
1928 break;
1929
1930 case BC_FORL:
1931 rec_loop_interp(J, pc, rec_for(J, pc+((ptrdiff_t)rc-BCBIAS_J), 1));
1932 break;
1933 case BC_ITERL:
1934 rec_loop_interp(J, pc, rec_iterl(J, *pc));
1935 break;
1936 case BC_LOOP:
1937 rec_loop_interp(J, pc, rec_loop(J, ra));
1938 break;
1939
1940 case BC_JFORL:
1941 rec_loop_jit(J, rc, rec_for(J, pc+bc_j(traceref(J, rc)->startins), 1));
1942 break;
1943 case BC_JITERL:
1944 rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
1945 break;
1946 case BC_JLOOP:
1947 rec_loop_jit(J, rc, rec_loop(J, ra));
1948 break;
1949
1950 case BC_IFORL:
1951 case BC_IITERL:
1952 case BC_ILOOP:
1953 case BC_IFUNCF:
1954 case BC_IFUNCV:
1955 lj_trace_err(J, LJ_TRERR_BLACKL);
1956 break;
1957
1958 case BC_JMP:
1959 if (ra < J->maxslot)
1960 J->maxslot = ra; /* Shrink used slots. */
1961 break;
1962
1963 /* -- Function headers -------------------------------------------------- */
1964
1965 case BC_FUNCF:
1966 rec_func_lua(J);
1967 break;
1968 case BC_JFUNCF:
1969 rec_func_jit(J, rc);
1970 break;
1971
1972 case BC_FUNCV:
1973 rec_func_vararg(J);
1974 rec_func_lua(J);
1975 break;
1976 case BC_JFUNCV:
1977 lua_assert(0); /* Cannot happen. No hotcall counting for varag funcs. */
1978 break;
1979
1980 case BC_FUNCC:
1981 case BC_FUNCCW:
1982 lj_ffrecord_func(J);
1983 break;
1984
1985 default:
1986 if (op >= BC__MAX) {
1987 lj_ffrecord_func(J);
1988 break;
1989 }
1990 /* fallthrough */
1991 case BC_ITERN:
1992 case BC_ISNEXT:
1993 case BC_CAT:
1994 case BC_UCLO:
1995 case BC_FNEW:
1996 case BC_TSETM:
1997 setintV(&J->errinfo, (int32_t)op);
1998 lj_trace_err_info(J, LJ_TRERR_NYIBC);
1999 break;
2000 }
2001
2002 /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */
2003 if (bcmode_a(op) == BCMdst && rc) {
2004 J->base[ra] = rc;
2005 if (ra >= J->maxslot) J->maxslot = ra+1;
2006 }
2007
2008#undef rav
2009#undef rbv
2010#undef rcv
2011
2012 /* Limit the number of recorded IR instructions. */
2013 if (J->cur.nins > REF_FIRST+(IRRef)J->param[JIT_P_maxrecord])
2014 lj_trace_err(J, LJ_TRERR_TRACEOV);
2015}
2016
2017/* -- Recording setup ----------------------------------------------------- */
2018
2019/* Setup recording for a root trace started by a hot loop. */
2020static const BCIns *rec_setup_root(jit_State *J)
2021{
2022 /* Determine the next PC and the bytecode range for the loop. */
2023 const BCIns *pcj, *pc = J->pc;
2024 BCIns ins = *pc;
2025 BCReg ra = bc_a(ins);
2026 switch (bc_op(ins)) {
2027 case BC_FORL:
2028 J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
2029 pc += 1+bc_j(ins);
2030 J->bc_min = pc;
2031 break;
2032 case BC_ITERL:
2033 lua_assert(bc_op(pc[-1]) == BC_ITERC);
2034 J->maxslot = ra + bc_b(pc[-1]) - 1;
2035 J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
2036 pc += 1+bc_j(ins);
2037 lua_assert(bc_op(pc[-1]) == BC_JMP);
2038 J->bc_min = pc;
2039 break;
2040 case BC_LOOP:
2041 /* Only check BC range for real loops, but not for "repeat until true". */
2042 pcj = pc + bc_j(ins);
2043 ins = *pcj;
2044 if (bc_op(ins) == BC_JMP && bc_j(ins) < 0) {
2045 J->bc_min = pcj+1 + bc_j(ins);
2046 J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
2047 }
2048 J->maxslot = ra;
2049 pc++;
2050 break;
2051 case BC_RET:
2052 case BC_RET0:
2053 case BC_RET1:
2054 /* No bytecode range check for down-recursive root traces. */
2055 J->maxslot = ra + bc_d(ins);
2056 break;
2057 case BC_FUNCF:
2058 /* No bytecode range check for root traces started by a hot call. */
2059 J->maxslot = J->pt->numparams;
2060 pc++;
2061 break;
2062 default:
2063 lua_assert(0);
2064 break;
2065 }
2066 return pc;
2067}
2068
2069/* Setup recording for a side trace. */
2070static void rec_setup_side(jit_State *J, GCtrace *T)
2071{
2072 SnapShot *snap = &T->snap[J->exitno];
2073 SnapEntry *map = &T->snapmap[snap->mapofs];
2074 MSize n, nent = snap->nent;
2075 BloomFilter seen = 0;
2076 J->framedepth = 0;
2077 /* Emit IR for slots inherited from parent snapshot. */
2078 for (n = 0; n < nent; n++) {
2079 SnapEntry sn = map[n];
2080 IRRef ref = snap_ref(sn);
2081 BCReg s = snap_slot(sn);
2082 IRIns *ir = &T->ir[ref];
2083 IRType t = irt_type(ir->t);
2084 TRef tr;
2085 /* The bloom filter avoids O(nent^2) overhead for de-duping slots. */
2086 if (bloomtest(seen, ref)) {
2087 MSize j;
2088 for (j = 0; j < n; j++)
2089 if (snap_ref(map[j]) == ref) {
2090 tr = J->slot[snap_slot(map[j])];
2091 goto setslot;
2092 }
2093 }
2094 bloomset(seen, ref);
2095 switch ((IROp)ir->o) {
2096 /* Only have to deal with constants that can occur in stack slots. */
2097 case IR_KPRI: tr = TREF_PRI(t); break;
2098 case IR_KINT: tr = lj_ir_kint(J, ir->i); break;
2099 case IR_KGC: tr = lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); break;
2100 case IR_KNUM: tr = lj_ir_k64(J, IR_KNUM, ir_knum(ir)); break;
2101 case IR_KINT64: tr = lj_ir_k64(J, IR_KINT64, ir_kint64(ir)); break;
2102 case IR_KPTR: tr = lj_ir_kptr(J, ir_kptr(ir)); break; /* Continuation. */
2103 /* Inherited SLOADs don't need a guard or type check. */
2104 case IR_SLOAD:
2105 if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM;
2106 tr = emitir_raw(IRT(IR_SLOAD, t), s,
2107 (ir->op2&IRSLOAD_READONLY) | IRSLOAD_INHERIT|IRSLOAD_PARENT);
2108 break;
2109 /* Parent refs are already typed and don't need a guard. */
2110 default:
2111 if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM;
2112 tr = emitir_raw(IRT(IR_SLOAD, t), s, IRSLOAD_INHERIT|IRSLOAD_PARENT);
2113 break;
2114 }
2115 setslot:
2116 J->slot[s] = tr | (sn&(SNAP_CONT|SNAP_FRAME)); /* Same as TREF_* flags. */
2117 J->framedepth += ((sn & (SNAP_CONT|SNAP_FRAME)) && s);
2118 if ((sn & SNAP_FRAME))
2119 J->baseslot = s+1;
2120 }
2121 J->base = J->slot + J->baseslot;
2122 J->maxslot = snap->nslots - J->baseslot;
2123 lj_snap_add(J);
2124}
2125
2126/* Setup for recording a new trace. */
2127void lj_record_setup(jit_State *J)
2128{
2129 uint32_t i;
2130
2131 /* Initialize state related to current trace. */
2132 memset(J->slot, 0, sizeof(J->slot));
2133 memset(J->chain, 0, sizeof(J->chain));
2134 memset(J->bpropcache, 0, sizeof(J->bpropcache));
2135 J->scev.idx = REF_NIL;
2136
2137 J->baseslot = 1; /* Invoking function is at base[-1]. */
2138 J->base = J->slot + J->baseslot;
2139 J->maxslot = 0;
2140 J->framedepth = 0;
2141 J->retdepth = 0;
2142
2143 J->instunroll = J->param[JIT_P_instunroll];
2144 J->loopunroll = J->param[JIT_P_loopunroll];
2145 J->tailcalled = 0;
2146 J->loopref = 0;
2147
2148 J->bc_min = NULL; /* Means no limit. */
2149 J->bc_extent = ~(MSize)0;
2150
2151 /* Emit instructions for fixed references. Also triggers initial IR alloc. */
2152 emitir_raw(IRT(IR_BASE, IRT_P32), J->parent, J->exitno);
2153 for (i = 0; i <= 2; i++) {
2154 IRIns *ir = IR(REF_NIL-i);
2155 ir->i = 0;
2156 ir->t.irt = (uint8_t)(IRT_NIL+i);
2157 ir->o = IR_KPRI;
2158 ir->prev = 0;
2159 }
2160 J->cur.nk = REF_TRUE;
2161
2162 J->startpc = J->pc;
2163 setmref(J->cur.startpc, J->pc);
2164 if (J->parent) { /* Side trace. */
2165 GCtrace *T = traceref(J, J->parent);
2166 TraceNo root = T->root ? T->root : J->parent;
2167 J->cur.root = (uint16_t)root;
2168 J->cur.startins = BCINS_AD(BC_JMP, 0, 0);
2169 /* Check whether we could at least potentially form an extra loop. */
2170 if (J->exitno == 0 && T->snap[0].nent == 0) {
2171 /* We can narrow a FORL for some side traces, too. */
2172 if (J->pc > proto_bc(J->pt) && bc_op(J->pc[-1]) == BC_JFORI &&
2173 bc_d(J->pc[bc_j(J->pc[-1])-1]) == root) {
2174 lj_snap_add(J);
2175 rec_for_loop(J, J->pc-1, &J->scev, 1);
2176 goto sidecheck;
2177 }
2178 } else {
2179 J->startpc = NULL; /* Prevent forming an extra loop. */
2180 }
2181 rec_setup_side(J, T);
2182 sidecheck:
2183 if (traceref(J, J->cur.root)->nchild >= J->param[JIT_P_maxside] ||
2184 T->snap[J->exitno].count >= J->param[JIT_P_hotexit] +
2185 J->param[JIT_P_tryside]) {
2186 rec_stop(J, LJ_TRLINK_INTERP, 0);
2187 }
2188 } else { /* Root trace. */
2189 J->cur.root = 0;
2190 J->cur.startins = *J->pc;
2191 J->pc = rec_setup_root(J);
2192 /* Note: the loop instruction itself is recorded at the end and not
2193 ** at the start! So snapshot #0 needs to point to the *next* instruction.
2194 */
2195 lj_snap_add(J);
2196 if (bc_op(J->cur.startins) == BC_FORL)
2197 rec_for_loop(J, J->pc-1, &J->scev, 1);
2198 if (1 + J->pt->framesize >= LJ_MAX_JSLOTS)
2199 lj_trace_err(J, LJ_TRERR_STACKOV);
2200 }
2201#ifdef LUAJIT_ENABLE_CHECKHOOK
2202 /* Regularly check for instruction/line hooks from compiled code and
2203 ** exit to the interpreter if the hooks are set.
2204 **
2205 ** This is a compile-time option and disabled by default, since the
2206 ** hook checks may be quite expensive in tight loops.
2207 **
2208 ** Note this is only useful if hooks are *not* set most of the time.
2209 ** Use this only if you want to *asynchronously* interrupt the execution.
2210 **
2211 ** You can set the instruction hook via lua_sethook() with a count of 1
2212 ** from a signal handler or another native thread. Please have a look
2213 ** at the first few functions in luajit.c for an example (Ctrl-C handler).
2214 */
2215 {
2216 TRef tr = emitir(IRT(IR_XLOAD, IRT_U8),
2217 lj_ir_kptr(J, &J2G(J)->hookmask), IRXLOAD_VOLATILE);
2218 tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (LUA_MASKLINE|LUA_MASKCOUNT)));
2219 emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, 0));
2220 }
2221#endif
2222}
2223
2224#undef IR
2225#undef emitir_raw
2226#undef emitir
2227
2228#endif
diff --git a/libraries/luajit-2.0/src/lj_record.h b/libraries/luajit-2.0/src/lj_record.h
new file mode 100644
index 0000000..186a25f
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_record.h
@@ -0,0 +1,43 @@
1/*
2** Trace recorder (bytecode -> SSA IR).
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_RECORD_H
7#define _LJ_RECORD_H
8
9#include "lj_obj.h"
10#include "lj_jit.h"
11
12#if LJ_HASJIT
13/* Context for recording an indexed load/store. */
14typedef struct RecordIndex {
15 TValue tabv; /* Runtime value of table (or indexed object). */
16 TValue keyv; /* Runtime value of key. */
17 TValue valv; /* Runtime value of stored value. */
18 TValue mobjv; /* Runtime value of metamethod object. */
19 GCtab *mtv; /* Runtime value of metatable object. */
20 cTValue *oldv; /* Runtime value of previously stored value. */
21 TRef tab; /* Table (or indexed object) reference. */
22 TRef key; /* Key reference. */
23 TRef val; /* Value reference for a store or 0 for a load. */
24 TRef mt; /* Metatable reference. */
25 TRef mobj; /* Metamethod object reference. */
26 int idxchain; /* Index indirections left or 0 for raw lookup. */
27} RecordIndex;
28
29LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b,
30 cTValue *av, cTValue *bv);
31
32LJ_FUNC void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs);
33LJ_FUNC void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs);
34LJ_FUNC void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults);
35
36LJ_FUNC int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm);
37LJ_FUNC TRef lj_record_idx(jit_State *J, RecordIndex *ix);
38
39LJ_FUNC void lj_record_ins(jit_State *J);
40LJ_FUNC void lj_record_setup(jit_State *J);
41#endif
42
43#endif
diff --git a/libraries/luajit-2.0/src/lj_snap.c b/libraries/luajit-2.0/src/lj_snap.c
new file mode 100644
index 0000000..10fd6af
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_snap.c
@@ -0,0 +1,446 @@
1/*
2** Snapshot handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_snap_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12
13#include "lj_gc.h"
14#include "lj_state.h"
15#include "lj_frame.h"
16#include "lj_bc.h"
17#include "lj_ir.h"
18#include "lj_jit.h"
19#include "lj_iropt.h"
20#include "lj_trace.h"
21#include "lj_snap.h"
22#include "lj_target.h"
23
24/* Some local macros to save typing. Undef'd at the end. */
25#define IR(ref) (&J->cur.ir[(ref)])
26
27/* -- Snapshot buffer allocation ------------------------------------------ */
28
29/* Grow snapshot buffer. */
30void lj_snap_grow_buf_(jit_State *J, MSize need)
31{
32 MSize maxsnap = (MSize)J->param[JIT_P_maxsnap];
33 if (need > maxsnap)
34 lj_trace_err(J, LJ_TRERR_SNAPOV);
35 lj_mem_growvec(J->L, J->snapbuf, J->sizesnap, maxsnap, SnapShot);
36 J->cur.snap = J->snapbuf;
37}
38
39/* Grow snapshot map buffer. */
40void lj_snap_grow_map_(jit_State *J, MSize need)
41{
42 if (need < 2*J->sizesnapmap)
43 need = 2*J->sizesnapmap;
44 else if (need < 64)
45 need = 64;
46 J->snapmapbuf = (SnapEntry *)lj_mem_realloc(J->L, J->snapmapbuf,
47 J->sizesnapmap*sizeof(SnapEntry), need*sizeof(SnapEntry));
48 J->cur.snapmap = J->snapmapbuf;
49 J->sizesnapmap = need;
50}
51
52/* -- Snapshot generation ------------------------------------------------- */
53
54/* Add all modified slots to the snapshot. */
55static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots)
56{
57 IRRef retf = J->chain[IR_RETF]; /* Limits SLOAD restore elimination. */
58 BCReg s;
59 MSize n = 0;
60 for (s = 0; s < nslots; s++) {
61 TRef tr = J->slot[s];
62 IRRef ref = tref_ref(tr);
63 if (ref) {
64 SnapEntry sn = SNAP_TR(s, tr);
65 IRIns *ir = IR(ref);
66 if (!(sn & (SNAP_CONT|SNAP_FRAME)) &&
67 ir->o == IR_SLOAD && ir->op1 == s && ref > retf) {
68 /* No need to snapshot unmodified non-inherited slots. */
69 if (!(ir->op2 & IRSLOAD_INHERIT))
70 continue;
71 /* No need to restore readonly slots and unmodified non-parent slots. */
72 if (!(LJ_DUALNUM && (ir->op2 & IRSLOAD_CONVERT)) &&
73 (ir->op2 & (IRSLOAD_READONLY|IRSLOAD_PARENT)) != IRSLOAD_PARENT)
74 sn |= SNAP_NORESTORE;
75 }
76 if (LJ_SOFTFP && irt_isnum(ir->t))
77 sn |= SNAP_SOFTFPNUM;
78 map[n++] = sn;
79 }
80 }
81 return n;
82}
83
84/* Add frame links at the end of the snapshot. */
85static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map)
86{
87 cTValue *frame = J->L->base - 1;
88 cTValue *lim = J->L->base - J->baseslot;
89 cTValue *ftop = frame + funcproto(frame_func(frame))->framesize;
90 MSize f = 0;
91 map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */
92 while (frame > lim) { /* Backwards traversal of all frames above base. */
93 if (frame_islua(frame)) {
94 map[f++] = SNAP_MKPC(frame_pc(frame));
95 frame = frame_prevl(frame);
96 if (frame + funcproto(frame_func(frame))->framesize > ftop)
97 ftop = frame + funcproto(frame_func(frame))->framesize;
98 } else if (frame_iscont(frame)) {
99 map[f++] = SNAP_MKFTSZ(frame_ftsz(frame));
100 map[f++] = SNAP_MKPC(frame_contpc(frame));
101 frame = frame_prevd(frame);
102 } else {
103 lua_assert(!frame_isc(frame));
104 map[f++] = SNAP_MKFTSZ(frame_ftsz(frame));
105 frame = frame_prevd(frame);
106 }
107 }
108 lua_assert(f == (MSize)(1 + J->framedepth));
109 return (BCReg)(ftop - lim);
110}
111
112/* Take a snapshot of the current stack. */
113static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap)
114{
115 BCReg nslots = J->baseslot + J->maxslot;
116 MSize nent;
117 SnapEntry *p;
118 /* Conservative estimate. */
119 lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1);
120 p = &J->cur.snapmap[nsnapmap];
121 nent = snapshot_slots(J, p, nslots);
122 snap->topslot = (uint8_t)snapshot_framelinks(J, p + nent);
123 snap->mapofs = (uint16_t)nsnapmap;
124 snap->ref = (IRRef1)J->cur.nins;
125 snap->nent = (uint8_t)nent;
126 snap->nslots = (uint8_t)nslots;
127 snap->count = 0;
128 J->cur.nsnapmap = (uint16_t)(nsnapmap + nent + 1 + J->framedepth);
129}
130
131/* Add or merge a snapshot. */
132void lj_snap_add(jit_State *J)
133{
134 MSize nsnap = J->cur.nsnap;
135 MSize nsnapmap = J->cur.nsnapmap;
136 /* Merge if no ins. inbetween or if requested and no guard inbetween. */
137 if (J->mergesnap ? !irt_isguard(J->guardemit) :
138 (nsnap > 0 && J->cur.snap[nsnap-1].ref == J->cur.nins)) {
139 nsnapmap = J->cur.snap[--nsnap].mapofs;
140 } else {
141 lj_snap_grow_buf(J, nsnap+1);
142 J->cur.nsnap = (uint16_t)(nsnap+1);
143 }
144 J->mergesnap = 0;
145 J->guardemit.irt = 0;
146 snapshot_stack(J, &J->cur.snap[nsnap], nsnapmap);
147}
148
149/* -- Snapshot modification ----------------------------------------------- */
150
151#define SNAP_USEDEF_SLOTS (LJ_MAX_JSLOTS+LJ_STACK_EXTRA)
152
153/* Find unused slots with reaching-definitions bytecode data-flow analysis. */
154static BCReg snap_usedef(jit_State *J, uint8_t *udf,
155 const BCIns *pc, BCReg maxslot)
156{
157 BCReg s;
158 GCobj *o;
159
160 if (maxslot == 0) return 0;
161#ifdef LUAJIT_USE_VALGRIND
162 /* Avoid errors for harmless reads beyond maxslot. */
163 memset(udf, 1, SNAP_USEDEF_SLOTS);
164#else
165 memset(udf, 1, maxslot);
166#endif
167
168 /* Treat open upvalues as used. */
169 o = gcref(J->L->openupval);
170 while (o) {
171 if (uvval(gco2uv(o)) < J->L->base) break;
172 udf[uvval(gco2uv(o)) - J->L->base] = 0;
173 o = gcref(o->gch.nextgc);
174 }
175
176#define USE_SLOT(s) udf[(s)] &= ~1
177#define DEF_SLOT(s) udf[(s)] *= 3
178
179 /* Scan through following bytecode and check for uses/defs. */
180 lua_assert(pc >= proto_bc(J->pt) && pc < proto_bc(J->pt) + J->pt->sizebc);
181 for (;;) {
182 BCIns ins = *pc++;
183 BCOp op = bc_op(ins);
184 switch (bcmode_b(op)) {
185 case BCMvar: USE_SLOT(bc_b(ins)); break;
186 default: break;
187 }
188 switch (bcmode_c(op)) {
189 case BCMvar: USE_SLOT(bc_c(ins)); break;
190 case BCMrbase:
191 lua_assert(op == BC_CAT);
192 for (s = bc_b(ins); s <= bc_c(ins); s++) USE_SLOT(s);
193 for (; s < maxslot; s++) DEF_SLOT(s);
194 break;
195 case BCMjump:
196 handle_jump: {
197 BCReg minslot = bc_a(ins);
198 if (op >= BC_FORI && op <= BC_JFORL) minslot += FORL_EXT;
199 else if (op >= BC_ITERL && op <= BC_JITERL) minslot += bc_b(pc[-2])-1;
200 else if (op == BC_UCLO) { pc += bc_j(ins); break; }
201 for (s = minslot; s < maxslot; s++) DEF_SLOT(s);
202 return minslot < maxslot ? minslot : maxslot;
203 }
204 case BCMlit:
205 if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) {
206 goto handle_jump;
207 } else if (bc_isret(op)) {
208 BCReg top = op == BC_RETM ? maxslot : (bc_a(ins) + bc_d(ins)-1);
209 for (s = 0; s < bc_a(ins); s++) DEF_SLOT(s);
210 for (; s < top; s++) USE_SLOT(s);
211 for (; s < maxslot; s++) DEF_SLOT(s);
212 return 0;
213 }
214 break;
215 case BCMfunc: return maxslot; /* NYI: will abort, anyway. */
216 default: break;
217 }
218 switch (bcmode_a(op)) {
219 case BCMvar: USE_SLOT(bc_a(ins)); break;
220 case BCMdst:
221 if (!(op == BC_ISTC || op == BC_ISFC)) DEF_SLOT(bc_a(ins));
222 break;
223 case BCMbase:
224 if (op >= BC_CALLM && op <= BC_VARG) {
225 BCReg top = (op == BC_CALLM || op == BC_CALLMT || bc_c(ins) == 0) ?
226 maxslot : (bc_a(ins) + bc_c(ins));
227 s = bc_a(ins) - ((op == BC_ITERC || op == BC_ITERN) ? 3 : 0);
228 for (; s < top; s++) USE_SLOT(s);
229 for (; s < maxslot; s++) DEF_SLOT(s);
230 if (op == BC_CALLT || op == BC_CALLMT) {
231 for (s = 0; s < bc_a(ins); s++) DEF_SLOT(s);
232 return 0;
233 }
234 } else if (op == BC_KNIL) {
235 for (s = bc_a(ins); s <= bc_d(ins); s++) DEF_SLOT(s);
236 } else if (op == BC_TSETM) {
237 for (s = bc_a(ins)-1; s < maxslot; s++) USE_SLOT(s);
238 }
239 break;
240 default: break;
241 }
242 lua_assert(pc >= proto_bc(J->pt) && pc < proto_bc(J->pt) + J->pt->sizebc);
243 }
244
245#undef USE_SLOT
246#undef DEF_SLOT
247
248 return 0; /* unreachable */
249}
250
251/* Purge dead slots before the next snapshot. */
252void lj_snap_purge(jit_State *J)
253{
254 uint8_t udf[SNAP_USEDEF_SLOTS];
255 BCReg maxslot = J->maxslot;
256 BCReg s = snap_usedef(J, udf, J->pc, maxslot);
257 for (; s < maxslot; s++)
258 if (udf[s] != 0)
259 J->base[s] = 0; /* Purge dead slots. */
260}
261
262/* Shrink last snapshot. */
263void lj_snap_shrink(jit_State *J)
264{
265 SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
266 SnapEntry *map = &J->cur.snapmap[snap->mapofs];
267 MSize n, m, nlim, nent = snap->nent;
268 uint8_t udf[SNAP_USEDEF_SLOTS];
269 BCReg maxslot = J->maxslot;
270 BCReg minslot = snap_usedef(J, udf, snap_pc(map[nent]), maxslot);
271 BCReg baseslot = J->baseslot;
272 maxslot += baseslot;
273 minslot += baseslot;
274 snap->nslots = (uint8_t)maxslot;
275 for (n = m = 0; n < nent; n++) { /* Remove unused slots from snapshot. */
276 BCReg s = snap_slot(map[n]);
277 if (s < minslot || (s < maxslot && udf[s-baseslot] == 0))
278 map[m++] = map[n]; /* Only copy used slots. */
279 }
280 snap->nent = (uint8_t)m;
281 nlim = J->cur.nsnapmap - snap->mapofs - 1;
282 while (n <= nlim) map[m++] = map[n++]; /* Move PC + frame links down. */
283 J->cur.nsnapmap = (uint16_t)(snap->mapofs + m); /* Free up space in map. */
284}
285
286/* -- Snapshot access ----------------------------------------------------- */
287
288/* Initialize a Bloom Filter with all renamed refs.
289** There are very few renames (often none), so the filter has
290** very few bits set. This makes it suitable for negative filtering.
291*/
292static BloomFilter snap_renamefilter(GCtrace *T, SnapNo lim)
293{
294 BloomFilter rfilt = 0;
295 IRIns *ir;
296 for (ir = &T->ir[T->nins-1]; ir->o == IR_RENAME; ir--)
297 if (ir->op2 <= lim)
298 bloomset(rfilt, ir->op1);
299 return rfilt;
300}
301
302/* Process matching renames to find the original RegSP. */
303static RegSP snap_renameref(GCtrace *T, SnapNo lim, IRRef ref, RegSP rs)
304{
305 IRIns *ir;
306 for (ir = &T->ir[T->nins-1]; ir->o == IR_RENAME; ir--)
307 if (ir->op1 == ref && ir->op2 <= lim)
308 rs = ir->prev;
309 return rs;
310}
311
312/* Convert a snapshot into a linear slot -> RegSP map.
313** Note: unused slots are not initialized!
314*/
315void lj_snap_regspmap(uint16_t *rsmap, GCtrace *T, SnapNo snapno, int hi)
316{
317 SnapShot *snap = &T->snap[snapno];
318 MSize n, nent = snap->nent;
319 SnapEntry *map = &T->snapmap[snap->mapofs];
320 BloomFilter rfilt = snap_renamefilter(T, snapno);
321 for (n = 0; n < nent; n++) {
322 SnapEntry sn = map[n];
323 IRRef ref = snap_ref(sn);
324 if (!irref_isk(ref) &&
325 ((LJ_SOFTFP && hi) ? (ref++, (sn & SNAP_SOFTFPNUM)) : 1)) {
326 IRIns *ir = &T->ir[ref];
327 uint32_t rs = ir->prev;
328 if (bloomtest(rfilt, ref))
329 rs = snap_renameref(T, snapno, ref, rs);
330 rsmap[snap_slot(sn)] = (uint16_t)rs;
331 }
332 }
333}
334
335/* Restore interpreter state from exit state with the help of a snapshot. */
336const BCIns *lj_snap_restore(jit_State *J, void *exptr)
337{
338 ExitState *ex = (ExitState *)exptr;
339 SnapNo snapno = J->exitno; /* For now, snapno == exitno. */
340 GCtrace *T = traceref(J, J->parent);
341 SnapShot *snap = &T->snap[snapno];
342 MSize n, nent = snap->nent;
343 SnapEntry *map = &T->snapmap[snap->mapofs];
344 SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1];
345 int32_t ftsz0;
346 TValue *frame;
347 BloomFilter rfilt = snap_renamefilter(T, snapno);
348 const BCIns *pc = snap_pc(map[nent]);
349 lua_State *L = J->L;
350
351 /* Set interpreter PC to the next PC to get correct error messages. */
352 setcframe_pc(cframe_raw(L->cframe), pc+1);
353
354 /* Make sure the stack is big enough for the slots from the snapshot. */
355 if (LJ_UNLIKELY(L->base + snap->topslot >= tvref(L->maxstack))) {
356 L->top = curr_topL(L);
357 lj_state_growstack(L, snap->topslot - curr_proto(L)->framesize);
358 }
359
360 /* Fill stack slots with data from the registers and spill slots. */
361 frame = L->base-1;
362 ftsz0 = frame_ftsz(frame); /* Preserve link to previous frame in slot #0. */
363 for (n = 0; n < nent; n++) {
364 SnapEntry sn = map[n];
365 IRRef ref = snap_ref(sn);
366 BCReg s = snap_slot(sn);
367 TValue *o = &frame[s]; /* Stack slots are relative to start frame. */
368 IRIns *ir = &T->ir[ref];
369 if (irref_isk(ref)) { /* Restore constant slot. */
370 lj_ir_kvalue(L, o, ir);
371 } else if (!(sn & SNAP_NORESTORE)) {
372 IRType1 t = ir->t;
373 RegSP rs = ir->prev;
374 if (LJ_UNLIKELY(bloomtest(rfilt, ref)))
375 rs = snap_renameref(T, snapno, ref, rs);
376 if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */
377 int32_t *sps = &ex->spill[regsp_spill(rs)];
378 if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) {
379 o->u32.lo = (uint32_t)*sps;
380 } else if (irt_isinteger(t)) {
381 setintV(o, *sps);
382#if !LJ_SOFTFP
383 } else if (irt_isnum(t)) {
384 o->u64 = *(uint64_t *)sps;
385#endif
386#if LJ_64
387 } else if (irt_islightud(t)) {
388 /* 64 bit lightuserdata which may escape already has the tag bits. */
389 o->u64 = *(uint64_t *)sps;
390#endif
391 } else {
392 lua_assert(!irt_ispri(t)); /* PRI refs never have a spill slot. */
393 setgcrefi(o->gcr, *sps);
394 setitype(o, irt_toitype(t));
395 }
396 } else { /* Restore from register. */
397 Reg r = regsp_reg(rs);
398 lua_assert(ra_hasreg(r));
399 if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) {
400 o->u32.lo = (uint32_t)ex->gpr[r-RID_MIN_GPR];
401 } else if (irt_isinteger(t)) {
402 setintV(o, (int32_t)ex->gpr[r-RID_MIN_GPR]);
403#if !LJ_SOFTFP
404 } else if (irt_isnum(t)) {
405 setnumV(o, ex->fpr[r-RID_MIN_FPR]);
406#endif
407#if LJ_64
408 } else if (irt_islightud(t)) {
409 /* 64 bit lightuserdata which may escape already has the tag bits. */
410 o->u64 = ex->gpr[r-RID_MIN_GPR];
411#endif
412 } else {
413 if (!irt_ispri(t))
414 setgcrefi(o->gcr, ex->gpr[r-RID_MIN_GPR]);
415 setitype(o, irt_toitype(t));
416 }
417 }
418 if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) {
419 rs = (ir+1)->prev;
420 if (LJ_UNLIKELY(bloomtest(rfilt, ref+1)))
421 rs = snap_renameref(T, snapno, ref+1, rs);
422 o->u32.hi = (ra_hasspill(regsp_spill(rs))) ?
423 (uint32_t)*&ex->spill[regsp_spill(rs)] :
424 (uint32_t)ex->gpr[regsp_reg(rs)-RID_MIN_GPR];
425 }
426 }
427 if ((sn & (SNAP_CONT|SNAP_FRAME))) { /* Overwrite tag with frame link. */
428 o->fr.tp.ftsz = s != 0 ? (int32_t)*flinks-- : ftsz0;
429 L->base = o+1;
430 }
431 }
432 switch (bc_op(*pc)) {
433 case BC_CALLM: case BC_CALLMT: case BC_RETM: case BC_TSETM:
434 L->top = frame + snap->nslots;
435 break;
436 default:
437 L->top = curr_topL(L);
438 break;
439 }
440 lua_assert(map + nent == flinks);
441 return pc;
442}
443
444#undef IR
445
446#endif
diff --git a/libraries/luajit-2.0/src/lj_snap.h b/libraries/luajit-2.0/src/lj_snap.h
new file mode 100644
index 0000000..da9813b
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_snap.h
@@ -0,0 +1,34 @@
1/*
2** Snapshot handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_SNAP_H
7#define _LJ_SNAP_H
8
9#include "lj_obj.h"
10#include "lj_jit.h"
11
12#if LJ_HASJIT
13LJ_FUNC void lj_snap_add(jit_State *J);
14LJ_FUNC void lj_snap_purge(jit_State *J);
15LJ_FUNC void lj_snap_shrink(jit_State *J);
16LJ_FUNC void lj_snap_regspmap(uint16_t *rsmap, GCtrace *T, SnapNo snapno,
17 int hi);
18LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr);
19LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need);
20LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need);
21
22static LJ_AINLINE void lj_snap_grow_buf(jit_State *J, MSize need)
23{
24 if (LJ_UNLIKELY(need > J->sizesnap)) lj_snap_grow_buf_(J, need);
25}
26
27static LJ_AINLINE void lj_snap_grow_map(jit_State *J, MSize need)
28{
29 if (LJ_UNLIKELY(need > J->sizesnapmap)) lj_snap_grow_map_(J, need);
30}
31
32#endif
33
34#endif
diff --git a/libraries/luajit-2.0/src/lj_state.c b/libraries/luajit-2.0/src/lj_state.c
new file mode 100644
index 0000000..49f2d6b
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_state.c
@@ -0,0 +1,280 @@
1/*
2** State and stack handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lj_state_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_str.h"
16#include "lj_tab.h"
17#include "lj_func.h"
18#include "lj_meta.h"
19#include "lj_state.h"
20#include "lj_frame.h"
21#if LJ_HASFFI
22#include "lj_ctype.h"
23#endif
24#include "lj_trace.h"
25#include "lj_dispatch.h"
26#include "lj_vm.h"
27#include "lj_lex.h"
28#include "lj_alloc.h"
29
30/* -- Stack handling ------------------------------------------------------ */
31
32/* Stack sizes. */
33#define LJ_STACK_MIN LUA_MINSTACK /* Min. stack size. */
34#define LJ_STACK_MAX LUAI_MAXSTACK /* Max. stack size. */
35#define LJ_STACK_START (2*LJ_STACK_MIN) /* Starting stack size. */
36#define LJ_STACK_MAXEX (LJ_STACK_MAX + 1 + LJ_STACK_EXTRA)
37
38/* Explanation of LJ_STACK_EXTRA:
39**
40** Calls to metamethods store their arguments beyond the current top
41** without checking for the stack limit. This avoids stack resizes which
42** would invalidate passed TValue pointers. The stack check is performed
43** later by the function header. This can safely resize the stack or raise
44** an error. Thus we need some extra slots beyond the current stack limit.
45**
46** Most metamethods need 4 slots above top (cont, mobj, arg1, arg2) plus
47** one extra slot if mobj is not a function. Only lj_meta_tset needs 5
48** slots above top, but then mobj is always a function. So we can get by
49** with 5 extra slots.
50*/
51
52/* Resize stack slots and adjust pointers in state. */
53static void resizestack(lua_State *L, MSize n)
54{
55 TValue *st, *oldst = tvref(L->stack);
56 ptrdiff_t delta;
57 MSize oldsize = L->stacksize;
58 MSize realsize = n + 1 + LJ_STACK_EXTRA;
59 GCobj *up;
60 lua_assert((MSize)(tvref(L->maxstack)-oldst)==L->stacksize-LJ_STACK_EXTRA-1);
61 st = (TValue *)lj_mem_realloc(L, tvref(L->stack),
62 (MSize)(L->stacksize*sizeof(TValue)),
63 (MSize)(realsize*sizeof(TValue)));
64 setmref(L->stack, st);
65 delta = (char *)st - (char *)oldst;
66 setmref(L->maxstack, st + n);
67 while (oldsize < realsize) /* Clear new slots. */
68 setnilV(st + oldsize++);
69 L->stacksize = realsize;
70 L->base = (TValue *)((char *)L->base + delta);
71 L->top = (TValue *)((char *)L->top + delta);
72 for (up = gcref(L->openupval); up != NULL; up = gcnext(up))
73 setmref(gco2uv(up)->v, (TValue *)((char *)uvval(gco2uv(up)) + delta));
74 if (obj2gco(L) == gcref(G(L)->jit_L))
75 setmref(G(L)->jit_base, mref(G(L)->jit_base, char) + delta);
76}
77
78/* Relimit stack after error, in case the limit was overdrawn. */
79void lj_state_relimitstack(lua_State *L)
80{
81 if (L->stacksize > LJ_STACK_MAXEX && L->top-tvref(L->stack) < LJ_STACK_MAX-1)
82 resizestack(L, LJ_STACK_MAX);
83}
84
85/* Try to shrink the stack (called from GC). */
86void lj_state_shrinkstack(lua_State *L, MSize used)
87{
88 if (L->stacksize > LJ_STACK_MAXEX)
89 return; /* Avoid stack shrinking while handling stack overflow. */
90 if (4*used < L->stacksize &&
91 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize &&
92 obj2gco(L) != gcref(G(L)->jit_L)) /* Don't shrink stack of live trace. */
93 resizestack(L, L->stacksize >> 1);
94}
95
96/* Try to grow stack. */
97void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need)
98{
99 MSize n;
100 if (L->stacksize > LJ_STACK_MAXEX) /* Overflow while handling overflow? */
101 lj_err_throw(L, LUA_ERRERR);
102 n = L->stacksize + need;
103 if (n > LJ_STACK_MAX) {
104 n += 2*LUA_MINSTACK;
105 } else if (n < 2*L->stacksize) {
106 n = 2*L->stacksize;
107 if (n >= LJ_STACK_MAX)
108 n = LJ_STACK_MAX;
109 }
110 resizestack(L, n);
111 if (L->stacksize > LJ_STACK_MAXEX)
112 lj_err_msg(L, LJ_ERR_STKOV);
113}
114
115void LJ_FASTCALL lj_state_growstack1(lua_State *L)
116{
117 lj_state_growstack(L, 1);
118}
119
120/* Allocate basic stack for new state. */
121static void stack_init(lua_State *L1, lua_State *L)
122{
123 TValue *stend, *st = lj_mem_newvec(L, LJ_STACK_START+LJ_STACK_EXTRA, TValue);
124 setmref(L1->stack, st);
125 L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA;
126 stend = st + L1->stacksize;
127 setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1);
128 L1->base = L1->top = st+1;
129 setthreadV(L1, st, L1); /* Needed for curr_funcisL() on empty stack. */
130 while (st < stend) /* Clear new slots. */
131 setnilV(st++);
132}
133
134/* -- State handling ------------------------------------------------------ */
135
136/* Open parts that may cause memory-allocation errors. */
137static TValue *cpluaopen(lua_State *L, lua_CFunction dummy, void *ud)
138{
139 global_State *g = G(L);
140 UNUSED(dummy);
141 UNUSED(ud);
142 stack_init(L, L);
143 /* NOBARRIER: State initialization, all objects are white. */
144 setgcref(L->env, obj2gco(lj_tab_new(L, 0, LJ_MIN_GLOBAL)));
145 settabV(L, registry(L), lj_tab_new(L, 0, LJ_MIN_REGISTRY));
146 lj_str_resize(L, LJ_MIN_STRTAB-1);
147 lj_meta_init(L);
148 lj_lex_init(L);
149 fixstring(lj_err_str(L, LJ_ERR_ERRMEM)); /* Preallocate memory error msg. */
150 g->gc.threshold = 4*g->gc.total;
151 lj_trace_initstate(g);
152 return NULL;
153}
154
155static void close_state(lua_State *L)
156{
157 global_State *g = G(L);
158 lj_func_closeuv(L, tvref(L->stack));
159 lj_gc_freeall(g);
160 lua_assert(gcref(g->gc.root) == obj2gco(L));
161 lua_assert(g->strnum == 0);
162 lj_trace_freestate(g);
163#if LJ_HASFFI
164 lj_ctype_freestate(g);
165#endif
166 lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef);
167 lj_str_freebuf(g, &g->tmpbuf);
168 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue);
169 lua_assert(g->gc.total == sizeof(GG_State));
170#ifndef LUAJIT_USE_SYSMALLOC
171 if (g->allocf == lj_alloc_f)
172 lj_alloc_destroy(g->allocd);
173 else
174#endif
175 g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0);
176}
177
178#if LJ_64
179lua_State *lj_state_newstate(lua_Alloc f, void *ud)
180#else
181LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
182#endif
183{
184 GG_State *GG = (GG_State *)f(ud, NULL, 0, sizeof(GG_State));
185 lua_State *L = &GG->L;
186 global_State *g = &GG->g;
187 if (GG == NULL || !checkptr32(GG)) return NULL;
188 memset(GG, 0, sizeof(GG_State));
189 L->gct = ~LJ_TTHREAD;
190 L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */
191 L->dummy_ffid = FF_C;
192 setmref(L->glref, g);
193 g->gc.currentwhite = LJ_GC_WHITE0 | LJ_GC_FIXED;
194 g->strempty.marked = LJ_GC_WHITE0;
195 g->strempty.gct = ~LJ_TSTR;
196 g->allocf = f;
197 g->allocd = ud;
198 setgcref(g->mainthref, obj2gco(L));
199 setgcref(g->uvhead.prev, obj2gco(&g->uvhead));
200 setgcref(g->uvhead.next, obj2gco(&g->uvhead));
201 g->strmask = ~(MSize)0;
202 setnilV(registry(L));
203 setnilV(&g->nilnode.val);
204 setnilV(&g->nilnode.key);
205 setmref(g->nilnode.freetop, &g->nilnode);
206 lj_str_initbuf(&g->tmpbuf);
207 g->gc.state = GCSpause;
208 setgcref(g->gc.root, obj2gco(L));
209 setmref(g->gc.sweep, &g->gc.root);
210 g->gc.total = sizeof(GG_State);
211 g->gc.pause = LUAI_GCPAUSE;
212 g->gc.stepmul = LUAI_GCMUL;
213 lj_dispatch_init((GG_State *)L);
214 L->status = LUA_ERRERR+1; /* Avoid touching the stack upon memory error. */
215 if (lj_vm_cpcall(L, NULL, NULL, cpluaopen) != 0) {
216 /* Memory allocation error: free partial state. */
217 close_state(L);
218 return NULL;
219 }
220 L->status = 0;
221 return L;
222}
223
224static TValue *cpfinalize(lua_State *L, lua_CFunction dummy, void *ud)
225{
226 UNUSED(dummy);
227 UNUSED(ud);
228 lj_gc_finalize_udata(L);
229 lj_gc_finalize_cdata(L);
230 /* Frame pop omitted. */
231 return NULL;
232}
233
234LUA_API void lua_close(lua_State *L)
235{
236 global_State *g = G(L);
237 L = mainthread(g); /* Only the main thread can be closed. */
238 lj_func_closeuv(L, tvref(L->stack));
239 lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */
240#if LJ_HASJIT
241 G2J(g)->flags &= ~JIT_F_ON;
242 G2J(g)->state = LJ_TRACE_IDLE;
243 lj_dispatch_update(g);
244#endif
245 do {
246 hook_enter(g);
247 L->status = 0;
248 L->cframe = NULL;
249 L->base = L->top = tvref(L->stack) + 1;
250 } while (lj_vm_cpcall(L, NULL, NULL, cpfinalize) != 0);
251 close_state(L);
252}
253
254lua_State *lj_state_new(lua_State *L)
255{
256 lua_State *L1 = lj_mem_newobj(L, lua_State);
257 L1->gct = ~LJ_TTHREAD;
258 L1->dummy_ffid = FF_C;
259 L1->status = 0;
260 L1->stacksize = 0;
261 setmref(L1->stack, NULL);
262 L1->cframe = NULL;
263 /* NOBARRIER: The lua_State is new (marked white). */
264 setgcrefnull(L1->openupval);
265 setmrefr(L1->glref, L->glref);
266 setgcrefr(L1->env, L->env);
267 stack_init(L1, L); /* init stack */
268 lua_assert(iswhite(obj2gco(L1)));
269 return L1;
270}
271
272void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L)
273{
274 lua_assert(L != mainthread(g));
275 lj_func_closeuv(L, tvref(L->stack));
276 lua_assert(gcref(L->openupval) == NULL);
277 lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue);
278 lj_mem_freet(g, L);
279}
280
diff --git a/libraries/luajit-2.0/src/lj_state.h b/libraries/luajit-2.0/src/lj_state.h
new file mode 100644
index 0000000..75b8dc8
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_state.h
@@ -0,0 +1,35 @@
1/*
2** State and stack handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_STATE_H
7#define _LJ_STATE_H
8
9#include "lj_obj.h"
10
11#define incr_top(L) \
12 (++L->top >= tvref(L->maxstack) && (lj_state_growstack1(L), 0))
13
14#define savestack(L, p) ((char *)(p) - mref(L->stack, char))
15#define restorestack(L, n) ((TValue *)(mref(L->stack, char) + (n)))
16
17LJ_FUNC void lj_state_relimitstack(lua_State *L);
18LJ_FUNC void lj_state_shrinkstack(lua_State *L, MSize used);
19LJ_FUNCA void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need);
20LJ_FUNC void LJ_FASTCALL lj_state_growstack1(lua_State *L);
21
22static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need)
23{
24 if ((mref(L->maxstack, char) - (char *)L->top) <=
25 (ptrdiff_t)need*(ptrdiff_t)sizeof(TValue))
26 lj_state_growstack(L, need);
27}
28
29LJ_FUNC lua_State *lj_state_new(lua_State *L);
30LJ_FUNC void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L);
31#if LJ_64
32LJ_FUNC lua_State *lj_state_newstate(lua_Alloc f, void *ud);
33#endif
34
35#endif
diff --git a/libraries/luajit-2.0/src/lj_str.c b/libraries/luajit-2.0/src/lj_str.c
new file mode 100644
index 0000000..cd3a8b6
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_str.c
@@ -0,0 +1,415 @@
1/*
2** String handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#include <stdio.h>
10
11#define lj_str_c
12#define LUA_CORE
13
14#include "lj_obj.h"
15#include "lj_gc.h"
16#include "lj_err.h"
17#include "lj_str.h"
18#include "lj_state.h"
19#include "lj_char.h"
20
21/* -- String interning ---------------------------------------------------- */
22
23/* Ordered compare of strings. Assumes string data is 4-byte aligned. */
24int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b)
25{
26 MSize i, n = a->len > b->len ? b->len : a->len;
27 for (i = 0; i < n; i += 4) {
28 /* Note: innocuous access up to end of string + 3. */
29 uint32_t va = *(const uint32_t *)(strdata(a)+i);
30 uint32_t vb = *(const uint32_t *)(strdata(b)+i);
31 if (va != vb) {
32#if LJ_LE
33 va = lj_bswap(va); vb = lj_bswap(vb);
34#endif
35 i -= n;
36 if ((int32_t)i >= -3) {
37 va >>= 32+(i<<3); vb >>= 32+(i<<3);
38 if (va == vb) break;
39 }
40 return va < vb ? -1 : 1;
41 }
42 }
43 return (int32_t)(a->len - b->len);
44}
45
46/* Fast string data comparison. Caveat: unaligned access to 1st string! */
47static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
48{
49 MSize i = 0;
50 lua_assert(len > 0);
51 lua_assert((((uintptr_t)a + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4);
52 do { /* Note: innocuous access up to end of string + 3. */
53 uint32_t v = lj_getu32(a+i) ^ *(const uint32_t *)(b+i);
54 if (v) {
55 i -= len;
56#if LJ_LE
57 return (int32_t)i >= -3 ? (v << (32+(i<<3))) : 1;
58#else
59 return (int32_t)i >= -3 ? (v >> (32+(i<<3))) : 1;
60#endif
61 }
62 i += 4;
63 } while (i < len);
64 return 0;
65}
66
67/* Resize the string hash table (grow and shrink). */
68void lj_str_resize(lua_State *L, MSize newmask)
69{
70 global_State *g = G(L);
71 GCRef *newhash;
72 MSize i;
73 if (g->gc.state == GCSsweepstring || newmask >= LJ_MAX_STRTAB-1)
74 return; /* No resizing during GC traversal or if already too big. */
75 newhash = lj_mem_newvec(L, newmask+1, GCRef);
76 memset(newhash, 0, (newmask+1)*sizeof(GCRef));
77 for (i = g->strmask; i != ~(MSize)0; i--) { /* Rehash old table. */
78 GCobj *p = gcref(g->strhash[i]);
79 while (p) { /* Follow each hash chain and reinsert all strings. */
80 MSize h = gco2str(p)->hash & newmask;
81 GCobj *next = gcnext(p);
82 /* NOBARRIER: The string table is a GC root. */
83 setgcrefr(p->gch.nextgc, newhash[h]);
84 setgcref(newhash[h], p);
85 p = next;
86 }
87 }
88 lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef);
89 g->strmask = newmask;
90 g->strhash = newhash;
91}
92
93/* Intern a string and return string object. */
94GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
95{
96 global_State *g;
97 GCstr *s;
98 GCobj *o;
99 MSize len = (MSize)lenx;
100 MSize a, b, h = len;
101 if (lenx >= LJ_MAX_STR)
102 lj_err_msg(L, LJ_ERR_STROV);
103 g = G(L);
104 /* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
105 if (len >= 4) { /* Caveat: unaligned access! */
106 a = lj_getu32(str);
107 h ^= lj_getu32(str+len-4);
108 b = lj_getu32(str+(len>>1)-2);
109 h ^= b; h -= lj_rol(b, 14);
110 b += lj_getu32(str+(len>>2)-1);
111 } else if (len > 0) {
112 a = *(const uint8_t *)str;
113 h ^= *(const uint8_t *)(str+len-1);
114 b = *(const uint8_t *)(str+(len>>1));
115 h ^= b; h -= lj_rol(b, 14);
116 } else {
117 return &g->strempty;
118 }
119 a ^= h; a -= lj_rol(h, 11);
120 b ^= a; b -= lj_rol(a, 25);
121 h ^= b; h -= lj_rol(b, 16);
122 /* Check if the string has already been interned. */
123 o = gcref(g->strhash[h & g->strmask]);
124 if (LJ_LIKELY((((uintptr_t)str + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {
125 while (o != NULL) {
126 GCstr *sx = gco2str(o);
127 if (sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) {
128 /* Resurrect if dead. Can only happen with fixstring() (keywords). */
129 if (isdead(g, o)) flipwhite(o);
130 return sx; /* Return existing string. */
131 }
132 o = gcnext(o);
133 }
134 } else { /* Slow path: end of string is too close to a page boundary. */
135 while (o != NULL) {
136 GCstr *sx = gco2str(o);
137 if (sx->len == len && memcmp(str, strdata(sx), len) == 0) {
138 /* Resurrect if dead. Can only happen with fixstring() (keywords). */
139 if (isdead(g, o)) flipwhite(o);
140 return sx; /* Return existing string. */
141 }
142 o = gcnext(o);
143 }
144 }
145 /* Nope, create a new string. */
146 s = lj_mem_newt(L, sizeof(GCstr)+len+1, GCstr);
147 newwhite(g, s);
148 s->gct = ~LJ_TSTR;
149 s->len = len;
150 s->hash = h;
151 s->reserved = 0;
152 memcpy(strdatawr(s), str, len);
153 strdatawr(s)[len] = '\0'; /* Zero-terminate string. */
154 /* Add it to string hash table. */
155 h &= g->strmask;
156 s->nextgc = g->strhash[h];
157 /* NOBARRIER: The string table is a GC root. */
158 setgcref(g->strhash[h], obj2gco(s));
159 if (g->strnum++ > g->strmask) /* Allow a 100% load factor. */
160 lj_str_resize(L, (g->strmask<<1)+1); /* Grow string table. */
161 return s; /* Return newly interned string. */
162}
163
164void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s)
165{
166 g->strnum--;
167 lj_mem_free(g, s, sizestring(s));
168}
169
170/* -- Type conversions ---------------------------------------------------- */
171
172/* Convert string object to number. */
173int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n)
174{
175 int ok = lj_str_numconv(strdata(str), n);
176 if (ok && tvisint(n))
177 setnumV(n, (lua_Number)intV(n));
178 return ok;
179}
180
181int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n)
182{
183 return lj_str_numconv(strdata(str), n);
184}
185
186/* Convert string to number. */
187int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
188{
189#if LJ_DUALNUM
190 int sign = 1;
191#else
192 lua_Number sign = 1;
193#endif
194 const uint8_t *p = (const uint8_t *)s;
195 while (lj_char_isspace(*p)) p++;
196 if (*p == '-') { p++; sign = -1; } else if (*p == '+') { p++; }
197 if ((uint32_t)(*p - '0') < 10) {
198 uint32_t k = (uint32_t)(*p++ - '0');
199 if (k == 0 && ((*p & ~0x20) == 'X')) {
200 p++;
201 if (!lj_char_isxdigit(*p))
202 return 0; /* Don't accept '0x' without hex digits. */
203 do {
204 if (k >= 0x10000000u) goto parsedbl;
205 k = (k << 4) + (*p & 15u);
206 if (!lj_char_isdigit(*p)) k += 9;
207 p++;
208 } while (lj_char_isxdigit(*p));
209 } else {
210 while ((uint32_t)(*p - '0') < 10) {
211 if (LJ_UNLIKELY(k >= 429496729) && (k != 429496729 || *p > '5'))
212 goto parsedbl;
213 k = k * 10u + (uint32_t)(*p++ - '0');
214 }
215 }
216 while (LJ_UNLIKELY(lj_char_isspace(*p))) p++;
217 if (LJ_LIKELY(*p == '\0')) {
218#if LJ_DUALNUM
219 if (sign == 1) {
220 if (k < 0x80000000u) {
221 setintV(n, (int32_t)k);
222 return 1;
223 }
224 } else if (k <= 0x80000000u) {
225 setintV(n, -(int32_t)k);
226 return 1;
227 }
228#endif
229 setnumV(n, sign * (lua_Number)k);
230 return 1;
231 }
232 }
233parsedbl:
234 {
235 TValue tv;
236 char *endptr;
237 setnumV(&tv, lua_str2number(s, &endptr));
238 if (endptr == s) return 0; /* Conversion failed. */
239 if (LJ_UNLIKELY(*endptr != '\0')) {
240 while (lj_char_isspace((uint8_t)*endptr)) endptr++;
241 if (*endptr != '\0') return 0; /* Invalid trailing characters? */
242 }
243 if (LJ_LIKELY(!tvisnan(&tv)))
244 setnumV(n, numV(&tv));
245 else
246 setnanV(n); /* Canonicalize injected NaNs. */
247 return 1;
248 }
249}
250
251/* Print number to buffer. Canonicalizes non-finite values. */
252size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o)
253{
254 if (LJ_LIKELY((o->u32.hi << 1) < 0xffe00000)) { /* Finite? */
255 lua_Number n = o->n;
256 return (size_t)lua_number2str(s, n);
257 } else if (((o->u32.hi & 0x000fffff) | o->u32.lo) != 0) {
258 s[0] = 'n'; s[1] = 'a'; s[2] = 'n'; return 3;
259 } else if ((o->u32.hi & 0x80000000) == 0) {
260 s[0] = 'i'; s[1] = 'n'; s[2] = 'f'; return 3;
261 } else {
262 s[0] = '-'; s[1] = 'i'; s[2] = 'n'; s[3] = 'f'; return 4;
263 }
264}
265
266/* Print integer to buffer. Returns pointer to start. */
267char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k)
268{
269 uint32_t u = (uint32_t)(k < 0 ? -k : k);
270 p += 1+10;
271 do { *--p = (char)('0' + u % 10); } while (u /= 10);
272 if (k < 0) *--p = '-';
273 return p;
274}
275
276/* Convert number to string. */
277GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
278{
279 char buf[LJ_STR_NUMBUF];
280 size_t len = lj_str_bufnum(buf, (TValue *)np);
281 return lj_str_new(L, buf, len);
282}
283
284/* Convert integer to string. */
285GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k)
286{
287 char s[1+10];
288 char *p = lj_str_bufint(s, k);
289 return lj_str_new(L, p, (size_t)(s+sizeof(s)-p));
290}
291
292GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
293{
294 return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n);
295}
296
297/* -- String formatting --------------------------------------------------- */
298
299static void addstr(lua_State *L, SBuf *sb, const char *str, MSize len)
300{
301 char *p;
302 MSize i;
303 if (sb->n + len > sb->sz) {
304 MSize sz = sb->sz * 2;
305 while (sb->n + len > sz) sz = sz * 2;
306 lj_str_resizebuf(L, sb, sz);
307 }
308 p = sb->buf + sb->n;
309 sb->n += len;
310 for (i = 0; i < len; i++) p[i] = str[i];
311}
312
313static void addchar(lua_State *L, SBuf *sb, int c)
314{
315 if (sb->n + 1 > sb->sz) {
316 MSize sz = sb->sz * 2;
317 lj_str_resizebuf(L, sb, sz);
318 }
319 sb->buf[sb->n++] = (char)c;
320}
321
322/* Push formatted message as a string object to Lua stack. va_list variant. */
323const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
324{
325 SBuf *sb = &G(L)->tmpbuf;
326 lj_str_needbuf(L, sb, (MSize)strlen(fmt));
327 lj_str_resetbuf(sb);
328 for (;;) {
329 const char *e = strchr(fmt, '%');
330 if (e == NULL) break;
331 addstr(L, sb, fmt, (MSize)(e-fmt));
332 /* This function only handles %s, %c, %d, %f and %p formats. */
333 switch (e[1]) {
334 case 's': {
335 const char *s = va_arg(argp, char *);
336 if (s == NULL) s = "(null)";
337 addstr(L, sb, s, (MSize)strlen(s));
338 break;
339 }
340 case 'c':
341 addchar(L, sb, va_arg(argp, int));
342 break;
343 case 'd': {
344 char buf[LJ_STR_INTBUF];
345 char *p = lj_str_bufint(buf, va_arg(argp, int32_t));
346 addstr(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p));
347 break;
348 }
349 case 'f': {
350 char buf[LJ_STR_NUMBUF];
351 TValue tv;
352 MSize len;
353 tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
354 len = (MSize)lj_str_bufnum(buf, &tv);
355 addstr(L, sb, buf, len);
356 break;
357 }
358 case 'p': {
359#define FMTP_CHARS (2*sizeof(ptrdiff_t))
360 char buf[2+FMTP_CHARS];
361 ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *));
362 ptrdiff_t i, lasti = 2+FMTP_CHARS;
363 if (p == 0) {
364 addstr(L, sb, "NULL", 4);
365 break;
366 }
367#if LJ_64
368 /* Shorten output for 64 bit pointers. */
369 lasti = 2+2*4+((p >> 32) ? 2+2*(lj_fls((uint32_t)(p >> 32))>>3) : 0);
370#endif
371 buf[0] = '0';
372 buf[1] = 'x';
373 for (i = lasti-1; i >= 2; i--, p >>= 4)
374 buf[i] = "0123456789abcdef"[(p & 15)];
375 addstr(L, sb, buf, (MSize)lasti);
376 break;
377 }
378 case '%':
379 addchar(L, sb, '%');
380 break;
381 default:
382 addchar(L, sb, '%');
383 addchar(L, sb, e[1]);
384 break;
385 }
386 fmt = e+2;
387 }
388 addstr(L, sb, fmt, (MSize)strlen(fmt));
389 setstrV(L, L->top, lj_str_new(L, sb->buf, sb->n));
390 incr_top(L);
391 return strVdata(L->top - 1);
392}
393
394/* Push formatted message as a string object to Lua stack. Vararg variant. */
395const char *lj_str_pushf(lua_State *L, const char *fmt, ...)
396{
397 const char *msg;
398 va_list argp;
399 va_start(argp, fmt);
400 msg = lj_str_pushvf(L, fmt, argp);
401 va_end(argp);
402 return msg;
403}
404
405/* -- Buffer handling ----------------------------------------------------- */
406
407char *lj_str_needbuf(lua_State *L, SBuf *sb, MSize sz)
408{
409 if (sz > sb->sz) {
410 if (sz < LJ_MIN_SBUF) sz = LJ_MIN_SBUF;
411 lj_str_resizebuf(L, sb, sz);
412 }
413 return sb->buf;
414}
415
diff --git a/libraries/luajit-2.0/src/lj_str.h b/libraries/luajit-2.0/src/lj_str.h
new file mode 100644
index 0000000..fbd927c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_str.h
@@ -0,0 +1,53 @@
1/*
2** String handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_STR_H
7#define _LJ_STR_H
8
9#include <stdarg.h>
10
11#include "lj_obj.h"
12
13/* String interning. */
14LJ_FUNC int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b);
15LJ_FUNC void lj_str_resize(lua_State *L, MSize newmask);
16LJ_FUNCA GCstr *lj_str_new(lua_State *L, const char *str, size_t len);
17LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s);
18
19#define lj_str_newz(L, s) (lj_str_new(L, s, strlen(s)))
20#define lj_str_newlit(L, s) (lj_str_new(L, "" s, sizeof(s)-1))
21
22/* Type conversions. */
23LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n);
24LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n);
25LJ_FUNC int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n);
26LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o);
27LJ_FUNC char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k);
28LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
29LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
30LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o);
31
32#define LJ_STR_INTBUF (1+10)
33#define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR
34
35/* String formatting. */
36LJ_FUNC const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp);
37LJ_FUNC const char *lj_str_pushf(lua_State *L, const char *fmt, ...)
38#if defined(__GNUC__)
39 __attribute__ ((format (printf, 2, 3)))
40#endif
41 ;
42
43/* Resizable string buffers. Struct definition in lj_obj.h. */
44LJ_FUNC char *lj_str_needbuf(lua_State *L, SBuf *sb, MSize sz);
45
46#define lj_str_initbuf(sb) ((sb)->buf = NULL, (sb)->sz = 0)
47#define lj_str_resetbuf(sb) ((sb)->n = 0)
48#define lj_str_resizebuf(L, sb, size) \
49 ((sb)->buf = (char *)lj_mem_realloc(L, (sb)->buf, (sb)->sz, (size)), \
50 (sb)->sz = (size))
51#define lj_str_freebuf(g, sb) lj_mem_free(g, (void *)(sb)->buf, (sb)->sz)
52
53#endif
diff --git a/libraries/luajit-2.0/src/lj_tab.c b/libraries/luajit-2.0/src/lj_tab.c
new file mode 100644
index 0000000..cd200f0
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_tab.c
@@ -0,0 +1,622 @@
1/*
2** Table handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#define lj_tab_c
10#define LUA_CORE
11
12#include "lj_obj.h"
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_tab.h"
16
17/* -- Object hashing ------------------------------------------------------ */
18
19/* Hash values are masked with the table hash mask and used as an index. */
20static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash)
21{
22 Node *n = noderef(t->node);
23 return &n[hash & t->hmask];
24}
25
26/* String hashes are precomputed when they are interned. */
27#define hashstr(t, s) hashmask(t, (s)->hash)
28
29#define hashlohi(t, lo, hi) hashmask((t), hashrot((lo), (hi)))
30#define hashnum(t, o) hashlohi((t), (o)->u32.lo, ((o)->u32.hi << 1))
31#define hashptr(t, p) hashlohi((t), u32ptr(p), u32ptr(p) + HASH_BIAS)
32#define hashgcref(t, r) hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS)
33
34/* Hash an arbitrary key and return its anchor position in the hash table. */
35static Node *hashkey(const GCtab *t, cTValue *key)
36{
37 lua_assert(!tvisint(key));
38 if (tvisstr(key))
39 return hashstr(t, strV(key));
40 else if (tvisnum(key))
41 return hashnum(t, key);
42 else if (tvisbool(key))
43 return hashmask(t, boolV(key));
44 else
45 return hashgcref(t, key->gcr);
46 /* Only hash 32 bits of lightuserdata on a 64 bit CPU. Good enough? */
47}
48
49/* -- Table creation and destruction -------------------------------------- */
50
51/* Create new hash part for table. */
52static LJ_AINLINE void newhpart(lua_State *L, GCtab *t, uint32_t hbits)
53{
54 uint32_t hsize;
55 Node *node;
56 lua_assert(hbits != 0);
57 if (hbits > LJ_MAX_HBITS)
58 lj_err_msg(L, LJ_ERR_TABOV);
59 hsize = 1u << hbits;
60 node = lj_mem_newvec(L, hsize, Node);
61 setmref(node->freetop, &node[hsize]);
62 setmref(t->node, node);
63 t->hmask = hsize-1;
64}
65
66/*
67** Q: Why all of these copies of t->hmask, t->node etc. to local variables?
68** A: Because alias analysis for C is _really_ tough.
69** Even state-of-the-art C compilers won't produce good code without this.
70*/
71
72/* Clear hash part of table. */
73static LJ_AINLINE void clearhpart(GCtab *t)
74{
75 uint32_t i, hmask = t->hmask;
76 Node *node = noderef(t->node);
77 lua_assert(t->hmask != 0);
78 for (i = 0; i <= hmask; i++) {
79 Node *n = &node[i];
80 setmref(n->next, NULL);
81 setnilV(&n->key);
82 setnilV(&n->val);
83 }
84}
85
86/* Clear array part of table. */
87static LJ_AINLINE void clearapart(GCtab *t)
88{
89 uint32_t i, asize = t->asize;
90 TValue *array = tvref(t->array);
91 for (i = 0; i < asize; i++)
92 setnilV(&array[i]);
93}
94
95/* Create a new table. Note: the slots are not initialized (yet). */
96static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
97{
98 GCtab *t;
99 /* First try to colocate the array part. */
100 if (LJ_MAX_COLOSIZE != 0 && asize > 0 && asize <= LJ_MAX_COLOSIZE) {
101 lua_assert((sizeof(GCtab) & 7) == 0);
102 t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize));
103 t->gct = ~LJ_TTAB;
104 t->nomm = (uint8_t)~0;
105 t->colo = (int8_t)asize;
106 setmref(t->array, (TValue *)((char *)t + sizeof(GCtab)));
107 setgcrefnull(t->metatable);
108 t->asize = asize;
109 t->hmask = 0;
110 setmref(t->node, &G(L)->nilnode);
111 } else { /* Otherwise separately allocate the array part. */
112 t = lj_mem_newobj(L, GCtab);
113 t->gct = ~LJ_TTAB;
114 t->nomm = (uint8_t)~0;
115 t->colo = 0;
116 setmref(t->array, NULL);
117 setgcrefnull(t->metatable);
118 t->asize = 0; /* In case the array allocation fails. */
119 t->hmask = 0;
120 setmref(t->node, &G(L)->nilnode);
121 if (asize > 0) {
122 if (asize > LJ_MAX_ASIZE)
123 lj_err_msg(L, LJ_ERR_TABOV);
124 setmref(t->array, lj_mem_newvec(L, asize, TValue));
125 t->asize = asize;
126 }
127 }
128 if (hbits)
129 newhpart(L, t, hbits);
130 return t;
131}
132
133/* Create a new table.
134**
135** IMPORTANT NOTE: The API differs from lua_createtable()!
136**
137** The array size is non-inclusive. E.g. asize=128 creates array slots
138** for 0..127, but not for 128. If you need slots 1..128, pass asize=129
139** (slot 0 is wasted in this case).
140**
141** The hash size is given in hash bits. hbits=0 means no hash part.
142** hbits=1 creates 2 hash slots, hbits=2 creates 4 hash slots and so on.
143*/
144GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits)
145{
146 GCtab *t = newtab(L, asize, hbits);
147 clearapart(t);
148 if (t->hmask > 0) clearhpart(t);
149 return t;
150}
151
152#if LJ_HASJIT
153GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize)
154{
155 GCtab *t = newtab(L, ahsize & 0xffffff, ahsize >> 24);
156 clearapart(t);
157 if (t->hmask > 0) clearhpart(t);
158 return t;
159}
160#endif
161
162/* Duplicate a table. */
163GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
164{
165 GCtab *t;
166 uint32_t asize, hmask;
167 t = newtab(L, kt->asize, kt->hmask > 0 ? lj_fls(kt->hmask)+1 : 0);
168 lua_assert(kt->asize == t->asize && kt->hmask == t->hmask);
169 t->nomm = 0; /* Keys with metamethod names may be present. */
170 asize = kt->asize;
171 if (asize > 0) {
172 TValue *array = tvref(t->array);
173 TValue *karray = tvref(kt->array);
174 if (asize < 64) { /* An inlined loop beats memcpy for < 512 bytes. */
175 uint32_t i;
176 for (i = 0; i < asize; i++)
177 copyTV(L, &array[i], &karray[i]);
178 } else {
179 memcpy(array, karray, asize*sizeof(TValue));
180 }
181 }
182 hmask = kt->hmask;
183 if (hmask > 0) {
184 uint32_t i;
185 Node *node = noderef(t->node);
186 Node *knode = noderef(kt->node);
187 ptrdiff_t d = (char *)node - (char *)knode;
188 setmref(node->freetop, (Node *)((char *)noderef(knode->freetop) + d));
189 for (i = 0; i <= hmask; i++) {
190 Node *kn = &knode[i];
191 Node *n = &node[i];
192 Node *next = nextnode(kn);
193 /* Don't use copyTV here, since it asserts on a copy of a dead key. */
194 n->val = kn->val; n->key = kn->key;
195 setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
196 }
197 }
198 return t;
199}
200
201/* Free a table. */
202void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t)
203{
204 if (t->hmask > 0)
205 lj_mem_freevec(g, noderef(t->node), t->hmask+1, Node);
206 if (t->asize > 0 && LJ_MAX_COLOSIZE != 0 && t->colo <= 0)
207 lj_mem_freevec(g, tvref(t->array), t->asize, TValue);
208 if (LJ_MAX_COLOSIZE != 0 && t->colo)
209 lj_mem_free(g, t, sizetabcolo((uint32_t)t->colo & 0x7f));
210 else
211 lj_mem_freet(g, t);
212}
213
214/* -- Table resizing ------------------------------------------------------ */
215
216/* Resize a table to fit the new array/hash part sizes. */
217static void resizetab(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits)
218{
219 Node *oldnode = noderef(t->node);
220 uint32_t oldasize = t->asize;
221 uint32_t oldhmask = t->hmask;
222 if (asize > oldasize) { /* Array part grows? */
223 TValue *array;
224 uint32_t i;
225 if (asize > LJ_MAX_ASIZE)
226 lj_err_msg(L, LJ_ERR_TABOV);
227 if (LJ_MAX_COLOSIZE != 0 && t->colo > 0) {
228 /* A colocated array must be separated and copied. */
229 TValue *oarray = tvref(t->array);
230 array = lj_mem_newvec(L, asize, TValue);
231 t->colo = (int8_t)(t->colo | 0x80); /* Mark as separated (colo < 0). */
232 for (i = 0; i < oldasize; i++)
233 copyTV(L, &array[i], &oarray[i]);
234 } else {
235 array = (TValue *)lj_mem_realloc(L, tvref(t->array),
236 oldasize*sizeof(TValue), asize*sizeof(TValue));
237 }
238 setmref(t->array, array);
239 t->asize = asize;
240 for (i = oldasize; i < asize; i++) /* Clear newly allocated slots. */
241 setnilV(&array[i]);
242 }
243 /* Create new (empty) hash part. */
244 if (hbits) {
245 newhpart(L, t, hbits);
246 clearhpart(t);
247 } else {
248 global_State *g = G(L);
249 setmref(t->node, &g->nilnode);
250 t->hmask = 0;
251 }
252 if (asize < oldasize) { /* Array part shrinks? */
253 TValue *array = tvref(t->array);
254 uint32_t i;
255 t->asize = asize; /* Note: This 'shrinks' even colocated arrays. */
256 for (i = asize; i < oldasize; i++) /* Reinsert old array values. */
257 if (!tvisnil(&array[i]))
258 copyTV(L, lj_tab_setinth(L, t, (int32_t)i), &array[i]);
259 /* Physically shrink only separated arrays. */
260 if (LJ_MAX_COLOSIZE != 0 && t->colo <= 0)
261 setmref(t->array, lj_mem_realloc(L, array,
262 oldasize*sizeof(TValue), asize*sizeof(TValue)));
263 }
264 if (oldhmask > 0) { /* Reinsert pairs from old hash part. */
265 global_State *g;
266 uint32_t i;
267 for (i = 0; i <= oldhmask; i++) {
268 Node *n = &oldnode[i];
269 if (!tvisnil(&n->val))
270 copyTV(L, lj_tab_set(L, t, &n->key), &n->val);
271 }
272 g = G(L);
273 lj_mem_freevec(g, oldnode, oldhmask+1, Node);
274 }
275}
276
277static uint32_t countint(cTValue *key, uint32_t *bins)
278{
279 lua_assert(!tvisint(key));
280 if (tvisnum(key)) {
281 lua_Number nk = numV(key);
282 int32_t k = lj_num2int(nk);
283 if ((uint32_t)k < LJ_MAX_ASIZE && nk == (lua_Number)k) {
284 bins[(k > 2 ? lj_fls((uint32_t)(k-1)) : 0)]++;
285 return 1;
286 }
287 }
288 return 0;
289}
290
291static uint32_t countarray(const GCtab *t, uint32_t *bins)
292{
293 uint32_t na, b, i;
294 if (t->asize == 0) return 0;
295 for (na = i = b = 0; b < LJ_MAX_ABITS; b++) {
296 uint32_t n, top = 2u << b;
297 TValue *array;
298 if (top >= t->asize) {
299 top = t->asize-1;
300 if (i > top)
301 break;
302 }
303 array = tvref(t->array);
304 for (n = 0; i <= top; i++)
305 if (!tvisnil(&array[i]))
306 n++;
307 bins[b] += n;
308 na += n;
309 }
310 return na;
311}
312
313static uint32_t counthash(const GCtab *t, uint32_t *bins, uint32_t *narray)
314{
315 uint32_t total, na, i, hmask = t->hmask;
316 Node *node = noderef(t->node);
317 for (total = na = 0, i = 0; i <= hmask; i++) {
318 Node *n = &node[i];
319 if (!tvisnil(&n->val)) {
320 na += countint(&n->key, bins);
321 total++;
322 }
323 }
324 *narray += na;
325 return total;
326}
327
328static uint32_t bestasize(uint32_t bins[], uint32_t *narray)
329{
330 uint32_t b, sum, na = 0, sz = 0, nn = *narray;
331 for (b = 0, sum = 0; 2*nn > (1u<<b) && sum != nn; b++)
332 if (bins[b] > 0 && 2*(sum += bins[b]) > (1u<<b)) {
333 sz = (2u<<b)+1;
334 na = sum;
335 }
336 *narray = sz;
337 return na;
338}
339
340static void rehashtab(lua_State *L, GCtab *t, cTValue *ek)
341{
342 uint32_t bins[LJ_MAX_ABITS];
343 uint32_t total, asize, na, i;
344 for (i = 0; i < LJ_MAX_ABITS; i++) bins[i] = 0;
345 asize = countarray(t, bins);
346 total = 1 + asize;
347 total += counthash(t, bins, &asize);
348 asize += countint(ek, bins);
349 na = bestasize(bins, &asize);
350 total -= na;
351 resizetab(L, t, asize, hsize2hbits(total));
352}
353
354void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize)
355{
356 resizetab(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0);
357}
358
359/* -- Table getters ------------------------------------------------------- */
360
361cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key)
362{
363 TValue k;
364 Node *n;
365 k.n = (lua_Number)key;
366 n = hashnum(t, &k);
367 do {
368 if (tvisnum(&n->key) && n->key.n == k.n)
369 return &n->val;
370 } while ((n = nextnode(n)));
371 return NULL;
372}
373
374cTValue *lj_tab_getstr(GCtab *t, GCstr *key)
375{
376 Node *n = hashstr(t, key);
377 do {
378 if (tvisstr(&n->key) && strV(&n->key) == key)
379 return &n->val;
380 } while ((n = nextnode(n)));
381 return NULL;
382}
383
384cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key)
385{
386 if (tvisstr(key)) {
387 cTValue *tv = lj_tab_getstr(t, strV(key));
388 if (tv)
389 return tv;
390 } else if (tvisint(key)) {
391 cTValue *tv = lj_tab_getint(t, intV(key));
392 if (tv)
393 return tv;
394 } else if (tvisnum(key)) {
395 lua_Number nk = numV(key);
396 int32_t k = lj_num2int(nk);
397 if (nk == (lua_Number)k) {
398 cTValue *tv = lj_tab_getint(t, k);
399 if (tv)
400 return tv;
401 } else {
402 goto genlookup; /* Else use the generic lookup. */
403 }
404 } else if (!tvisnil(key)) {
405 Node *n;
406 genlookup:
407 n = hashkey(t, key);
408 do {
409 if (lj_obj_equal(&n->key, key))
410 return &n->val;
411 } while ((n = nextnode(n)));
412 }
413 return niltv(L);
414}
415
416/* -- Table setters ------------------------------------------------------- */
417
418/* Insert new key. Use Brent's variation to optimize the chain length. */
419TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)
420{
421 Node *n = hashkey(t, key);
422 if (!tvisnil(&n->val) || t->hmask == 0) {
423 Node *nodebase = noderef(t->node);
424 Node *collide, *freenode = noderef(nodebase->freetop);
425 lua_assert(freenode >= nodebase && freenode <= nodebase+t->hmask+1);
426 do {
427 if (freenode == nodebase) { /* No free node found? */
428 rehashtab(L, t, key); /* Rehash table. */
429 return lj_tab_set(L, t, key); /* Retry key insertion. */
430 }
431 } while (!tvisnil(&(--freenode)->key));
432 setmref(nodebase->freetop, freenode);
433 lua_assert(freenode != &G(L)->nilnode);
434 collide = hashkey(t, &n->key);
435 if (collide != n) { /* Colliding node not the main node? */
436 while (noderef(collide->next) != n) /* Find predecessor. */
437 collide = nextnode(collide);
438 setmref(collide->next, freenode); /* Relink chain. */
439 /* Copy colliding node into free node and free main node. */
440 freenode->val = n->val;
441 freenode->key = n->key;
442 freenode->next = n->next;
443 setmref(n->next, NULL);
444 setnilV(&n->val);
445 /* Rechain pseudo-resurrected string keys with colliding hashes. */
446 while (nextnode(freenode)) {
447 Node *nn = nextnode(freenode);
448 if (tvisstr(&nn->key) && !tvisnil(&nn->val) &&
449 hashstr(t, strV(&nn->key)) == n) {
450 freenode->next = nn->next;
451 nn->next = n->next;
452 setmref(n->next, nn);
453 } else {
454 freenode = nn;
455 }
456 }
457 } else { /* Otherwise use free node. */
458 setmrefr(freenode->next, n->next); /* Insert into chain. */
459 setmref(n->next, freenode);
460 n = freenode;
461 }
462 }
463 n->key.u64 = key->u64;
464 if (LJ_UNLIKELY(tvismzero(&n->key)))
465 n->key.u64 = 0;
466 lj_gc_anybarriert(L, t);
467 lua_assert(tvisnil(&n->val));
468 return &n->val;
469}
470
471TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key)
472{
473 TValue k;
474 Node *n;
475 k.n = (lua_Number)key;
476 n = hashnum(t, &k);
477 do {
478 if (tvisnum(&n->key) && n->key.n == k.n)
479 return &n->val;
480 } while ((n = nextnode(n)));
481 return lj_tab_newkey(L, t, &k);
482}
483
484TValue *lj_tab_setstr(lua_State *L, GCtab *t, GCstr *key)
485{
486 TValue k;
487 Node *n = hashstr(t, key);
488 do {
489 if (tvisstr(&n->key) && strV(&n->key) == key)
490 return &n->val;
491 } while ((n = nextnode(n)));
492 setstrV(L, &k, key);
493 return lj_tab_newkey(L, t, &k);
494}
495
496TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key)
497{
498 Node *n;
499 t->nomm = 0; /* Invalidate negative metamethod cache. */
500 if (tvisstr(key)) {
501 return lj_tab_setstr(L, t, strV(key));
502 } else if (tvisint(key)) {
503 return lj_tab_setint(L, t, intV(key));
504 } else if (tvisnum(key)) {
505 lua_Number nk = numV(key);
506 int32_t k = lj_num2int(nk);
507 if (nk == (lua_Number)k)
508 return lj_tab_setint(L, t, k);
509 if (tvisnan(key))
510 lj_err_msg(L, LJ_ERR_NANIDX);
511 /* Else use the generic lookup. */
512 } else if (tvisnil(key)) {
513 lj_err_msg(L, LJ_ERR_NILIDX);
514 }
515 n = hashkey(t, key);
516 do {
517 if (lj_obj_equal(&n->key, key))
518 return &n->val;
519 } while ((n = nextnode(n)));
520 return lj_tab_newkey(L, t, key);
521}
522
523/* -- Table traversal ----------------------------------------------------- */
524
525/* Get the traversal index of a key. */
526static uint32_t keyindex(lua_State *L, GCtab *t, cTValue *key)
527{
528 TValue tmp;
529 if (tvisint(key)) {
530 int32_t k = intV(key);
531 if ((uint32_t)k < t->asize)
532 return (uint32_t)k; /* Array key indexes: [0..t->asize-1] */
533 setnumV(&tmp, (lua_Number)k);
534 key = &tmp;
535 } else if (tvisnum(key)) {
536 lua_Number nk = numV(key);
537 int32_t k = lj_num2int(nk);
538 if ((uint32_t)k < t->asize && nk == (lua_Number)k)
539 return (uint32_t)k; /* Array key indexes: [0..t->asize-1] */
540 }
541 if (!tvisnil(key)) {
542 Node *n = hashkey(t, key);
543 do {
544 if (lj_obj_equal(&n->key, key))
545 return t->asize + (uint32_t)(n - noderef(t->node));
546 /* Hash key indexes: [t->asize..t->asize+t->nmask] */
547 } while ((n = nextnode(n)));
548 lj_err_msg(L, LJ_ERR_NEXTIDX);
549 return 0; /* unreachable */
550 }
551 return ~0u; /* A nil key starts the traversal. */
552}
553
554/* Advance to the next step in a table traversal. */
555int lj_tab_next(lua_State *L, GCtab *t, TValue *key)
556{
557 uint32_t i = keyindex(L, t, key); /* Find predecessor key index. */
558 for (i++; i < t->asize; i++) /* First traverse the array keys. */
559 if (!tvisnil(arrayslot(t, i))) {
560 setintV(key, i);
561 copyTV(L, key+1, arrayslot(t, i));
562 return 1;
563 }
564 for (i -= t->asize; i <= t->hmask; i++) { /* Then traverse the hash keys. */
565 Node *n = &noderef(t->node)[i];
566 if (!tvisnil(&n->val)) {
567 copyTV(L, key, &n->key);
568 copyTV(L, key+1, &n->val);
569 return 1;
570 }
571 }
572 return 0; /* End of traversal. */
573}
574
575/* -- Table length calculation -------------------------------------------- */
576
577static MSize unbound_search(GCtab *t, MSize j)
578{
579 cTValue *tv;
580 MSize i = j; /* i is zero or a present index */
581 j++;
582 /* find `i' and `j' such that i is present and j is not */
583 while ((tv = lj_tab_getint(t, (int32_t)j)) && !tvisnil(tv)) {
584 i = j;
585 j *= 2;
586 if (j > (MSize)(INT_MAX-2)) { /* overflow? */
587 /* table was built with bad purposes: resort to linear search */
588 i = 1;
589 while ((tv = lj_tab_getint(t, (int32_t)i)) && !tvisnil(tv)) i++;
590 return i - 1;
591 }
592 }
593 /* now do a binary search between them */
594 while (j - i > 1) {
595 MSize m = (i+j)/2;
596 cTValue *tvb = lj_tab_getint(t, (int32_t)m);
597 if (tvb && !tvisnil(tvb)) i = m; else j = m;
598 }
599 return i;
600}
601
602/*
603** Try to find a boundary in table `t'. A `boundary' is an integer index
604** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
605*/
606MSize LJ_FASTCALL lj_tab_len(GCtab *t)
607{
608 MSize j = (MSize)t->asize;
609 if (j > 1 && tvisnil(arrayslot(t, j-1))) {
610 MSize i = 1;
611 while (j - i > 1) {
612 MSize m = (i+j)/2;
613 if (tvisnil(arrayslot(t, m-1))) j = m; else i = m;
614 }
615 return i-1;
616 }
617 if (j) j--;
618 if (t->hmask <= 0)
619 return j;
620 return unbound_search(t, j);
621}
622
diff --git a/libraries/luajit-2.0/src/lj_tab.h b/libraries/luajit-2.0/src/lj_tab.h
new file mode 100644
index 0000000..76e96f1
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_tab.h
@@ -0,0 +1,67 @@
1/*
2** Table handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_TAB_H
7#define _LJ_TAB_H
8
9#include "lj_obj.h"
10
11/* Hash constants. Tuned using a brute force search. */
12#define HASH_BIAS (-0x04c11db7)
13#define HASH_ROT1 14
14#define HASH_ROT2 5
15#define HASH_ROT3 13
16
17/* Scramble the bits of numbers and pointers. */
18static LJ_AINLINE uint32_t hashrot(uint32_t lo, uint32_t hi)
19{
20#if LJ_TARGET_X86ORX64
21 /* Prefer variant that compiles well for a 2-operand CPU. */
22 lo ^= hi; hi = lj_rol(hi, HASH_ROT1);
23 lo -= hi; hi = lj_rol(hi, HASH_ROT2);
24 hi ^= lo; hi -= lj_rol(lo, HASH_ROT3);
25#else
26 lo ^= hi;
27 lo = lo - lj_rol(hi, HASH_ROT1);
28 hi = lo ^ lj_rol(hi, HASH_ROT1 + HASH_ROT2);
29 hi = hi - lj_rol(lo, HASH_ROT3);
30#endif
31 return hi;
32}
33
34#define hsize2hbits(s) ((s) ? ((s)==1 ? 1 : 1+lj_fls((uint32_t)((s)-1))) : 0)
35
36LJ_FUNCA GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits);
37#if LJ_HASJIT
38LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize);
39#endif
40LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt);
41LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t);
42LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize);
43
44/* Caveat: all getters except lj_tab_get() can return NULL! */
45
46LJ_FUNCA cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key);
47LJ_FUNC cTValue *lj_tab_getstr(GCtab *t, GCstr *key);
48LJ_FUNCA cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key);
49
50/* Caveat: all setters require a write barrier for the stored value. */
51
52LJ_FUNCA TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key);
53LJ_FUNC TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key);
54LJ_FUNC TValue *lj_tab_setstr(lua_State *L, GCtab *t, GCstr *key);
55LJ_FUNC TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key);
56
57#define inarray(t, key) ((MSize)(key) < (MSize)(t)->asize)
58#define arrayslot(t, i) (&tvref((t)->array)[(i)])
59#define lj_tab_getint(t, key) \
60 (inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_getinth((t), (key)))
61#define lj_tab_setint(L, t, key) \
62 (inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_setinth(L, (t), (key)))
63
64LJ_FUNCA int lj_tab_next(lua_State *L, GCtab *t, TValue *key);
65LJ_FUNCA MSize LJ_FASTCALL lj_tab_len(GCtab *t);
66
67#endif
diff --git a/libraries/luajit-2.0/src/lj_target.h b/libraries/luajit-2.0/src/lj_target.h
new file mode 100644
index 0000000..c302d30
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_target.h
@@ -0,0 +1,158 @@
1/*
2** Definitions for target CPU.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_TARGET_H
7#define _LJ_TARGET_H
8
9#include "lj_def.h"
10#include "lj_arch.h"
11
12/* -- Registers and spill slots ------------------------------------------- */
13
14/* Register type (uint8_t in ir->r). */
15typedef uint32_t Reg;
16
17/* The hi-bit is NOT set for an allocated register. This means the value
18** can be directly used without masking. The hi-bit is set for a register
19** allocation hint or for RID_INIT.
20*/
21#define RID_NONE 0x80
22#define RID_MASK 0x7f
23#define RID_INIT (RID_NONE|RID_MASK)
24
25#define ra_noreg(r) ((r) & RID_NONE)
26#define ra_hasreg(r) (!((r) & RID_NONE))
27
28/* The ra_hashint() macro assumes a previous test for ra_noreg(). */
29#define ra_hashint(r) ((r) != RID_INIT)
30#define ra_gethint(r) ((Reg)((r) & RID_MASK))
31#define ra_sethint(rr, r) rr = (uint8_t)((r)|RID_NONE)
32#define ra_samehint(r1, r2) (ra_gethint((r1)^(r2)) == 0)
33
34/* Spill slot 0 means no spill slot has been allocated. */
35#define SPS_NONE 0
36
37#define ra_hasspill(s) ((s) != SPS_NONE)
38
39/* Combined register and spill slot (uint16_t in ir->prev). */
40typedef uint32_t RegSP;
41
42#define REGSP(r, s) ((r) + ((s) << 8))
43#define REGSP_HINT(r) ((r)|RID_NONE)
44#define REGSP_INIT REGSP(RID_INIT, 0)
45
46#define regsp_reg(rs) ((rs) & 255)
47#define regsp_spill(rs) ((rs) >> 8)
48#define regsp_used(rs) \
49 (((rs) & ~REGSP(RID_MASK, 0)) != REGSP(RID_NONE, 0))
50
51/* -- Register sets ------------------------------------------------------- */
52
53/* Bitset for registers. 32 registers suffice for most architectures.
54** Note that one set holds bits for both GPRs and FPRs.
55*/
56#if LJ_TARGET_PPC
57typedef uint64_t RegSet;
58#else
59typedef uint32_t RegSet;
60#endif
61
62#define RID2RSET(r) (((RegSet)1) << (r))
63#define RSET_EMPTY ((RegSet)0)
64#define RSET_RANGE(lo, hi) ((RID2RSET((hi)-(lo))-1) << (lo))
65
66#define rset_test(rs, r) (((rs) >> (r)) & 1)
67#define rset_set(rs, r) (rs |= RID2RSET(r))
68#define rset_clear(rs, r) (rs &= ~RID2RSET(r))
69#define rset_exclude(rs, r) (rs & ~RID2RSET(r))
70#if LJ_TARGET_PPC
71#define rset_picktop(rs) ((Reg)(__builtin_clzll(rs)^63))
72#define rset_pickbot(rs) ((Reg)__builtin_ctzll(rs))
73#else
74#define rset_picktop(rs) ((Reg)lj_fls(rs))
75#define rset_pickbot(rs) ((Reg)lj_ffs(rs))
76#endif
77
78/* -- Register allocation cost -------------------------------------------- */
79
80/* The register allocation heuristic keeps track of the cost for allocating
81** a specific register:
82**
83** A free register (obviously) has a cost of 0 and a 1-bit in the free mask.
84**
85** An already allocated register has the (non-zero) IR reference in the lowest
86** bits and the result of a blended cost-model in the higher bits.
87**
88** The allocator first checks the free mask for a hit. Otherwise an (unrolled)
89** linear search for the minimum cost is used. The search doesn't need to
90** keep track of the position of the minimum, which makes it very fast.
91** The lowest bits of the minimum cost show the desired IR reference whose
92** register is the one to evict.
93**
94** Without the cost-model this degenerates to the standard heuristics for
95** (reverse) linear-scan register allocation. Since code generation is done
96** in reverse, a live interval extends from the last use to the first def.
97** For an SSA IR the IR reference is the first (and only) def and thus
98** trivially marks the end of the interval. The LSRA heuristics says to pick
99** the register whose live interval has the furthest extent, i.e. the lowest
100** IR reference in our case.
101**
102** A cost-model should take into account other factors, like spill-cost and
103** restore- or rematerialization-cost, which depend on the kind of instruction.
104** E.g. constants have zero spill costs, variant instructions have higher
105** costs than invariants and PHIs should preferably never be spilled.
106**
107** Here's a first cut at simple, but effective blended cost-model for R-LSRA:
108** - Due to careful design of the IR, constants already have lower IR
109** references than invariants and invariants have lower IR references
110** than variants.
111** - The cost in the upper 16 bits is the sum of the IR reference and a
112** weighted score. The score currently only takes into account whether
113** the IRT_ISPHI bit is set in the instruction type.
114** - The PHI weight is the minimum distance (in IR instructions) a PHI
115** reference has to be further apart from a non-PHI reference to be spilled.
116** - It should be a power of two (for speed) and must be between 2 and 32768.
117** Good values for the PHI weight seem to be between 40 and 150.
118** - Further study is required.
119*/
120#define REGCOST_PHI_WEIGHT 64
121
122/* Cost for allocating a specific register. */
123typedef uint32_t RegCost;
124
125/* Note: assumes 16 bit IRRef1. */
126#define REGCOST(cost, ref) ((RegCost)(ref) + ((RegCost)(cost) << 16))
127#define regcost_ref(rc) ((IRRef1)(rc))
128
129#define REGCOST_T(t) \
130 ((RegCost)((t)&IRT_ISPHI) * (((RegCost)(REGCOST_PHI_WEIGHT)<<16)/IRT_ISPHI))
131#define REGCOST_REF_T(ref, t) (REGCOST((ref), (ref)) + REGCOST_T((t)))
132
133/* -- Target-specific definitions ----------------------------------------- */
134
135#if LJ_TARGET_X86ORX64
136#include "lj_target_x86.h"
137#elif LJ_TARGET_ARM
138#include "lj_target_arm.h"
139#elif LJ_TARGET_PPC
140#include "lj_target_ppc.h"
141#else
142#error "Missing include for target CPU"
143#endif
144
145#ifdef EXITSTUBS_PER_GROUP
146/* Return the address of an exit stub. */
147static LJ_AINLINE char *exitstub_addr_(char **group, uint32_t exitno)
148{
149 lua_assert(group[exitno / EXITSTUBS_PER_GROUP] != NULL);
150 return (char *)group[exitno / EXITSTUBS_PER_GROUP] +
151 EXITSTUB_SPACING*(exitno % EXITSTUBS_PER_GROUP);
152}
153/* Avoid dependence on lj_jit.h if only including lj_target.h. */
154#define exitstub_addr(J, exitno) \
155 ((MCode *)exitstub_addr_((char **)((J)->exitstubgroup), (exitno)))
156#endif
157
158#endif
diff --git a/libraries/luajit-2.0/src/lj_target_arm.h b/libraries/luajit-2.0/src/lj_target_arm.h
new file mode 100644
index 0000000..b4b26d4
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_target_arm.h
@@ -0,0 +1,210 @@
1/*
2** Definitions for ARM CPUs.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_TARGET_ARM_H
7#define _LJ_TARGET_ARM_H
8
9/* -- Registers IDs ------------------------------------------------------- */
10
11#define GPRDEF(_) \
12 _(R0) _(R1) _(R2) _(R3) _(R4) _(R5) _(R6) _(R7) \
13 _(R8) _(R9) _(R10) _(R11) _(R12) _(SP) _(LR) _(PC)
14#if LJ_SOFTFP
15#define FPRDEF(_)
16#else
17#error "NYI: hard-float support for ARM"
18#endif
19#define VRIDDEF(_)
20
21#define RIDENUM(name) RID_##name,
22
23enum {
24 GPRDEF(RIDENUM) /* General-purpose registers (GPRs). */
25 FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */
26 RID_MAX,
27 RID_TMP = RID_LR,
28
29 /* Calling conventions. */
30 RID_RET = RID_R0,
31 RID_RETLO = RID_R0,
32 RID_RETHI = RID_R1,
33 RID_FPRET = RID_R0,
34
35 /* These definitions must match with the *.dasc file(s): */
36 RID_BASE = RID_R9, /* Interpreter BASE. */
37 RID_LPC = RID_R6, /* Interpreter PC. */
38 RID_DISPATCH = RID_R7, /* Interpreter DISPATCH table. */
39 RID_LREG = RID_R8, /* Interpreter L. */
40
41 /* Register ranges [min, max) and number of registers. */
42 RID_MIN_GPR = RID_R0,
43 RID_MAX_GPR = RID_PC+1,
44 RID_MIN_FPR = RID_MAX_GPR,
45#if LJ_SOFTFP
46 RID_MAX_FPR = RID_MIN_FPR,
47#else
48#error "NYI: VFP support for ARM"
49#endif
50 RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
51 RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR
52};
53
54#define RID_NUM_KREF RID_NUM_GPR
55#define RID_MIN_KREF RID_R0
56
57/* -- Register sets ------------------------------------------------------- */
58
59/* Make use of all registers, except sp, lr and pc. */
60#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_R12+1))
61#define RSET_GPREVEN \
62 (RID2RSET(RID_R0)|RID2RSET(RID_R2)|RID2RSET(RID_R4)|RID2RSET(RID_R6)| \
63 RID2RSET(RID_R8)|RID2RSET(RID_R10))
64#define RSET_GPRODD \
65 (RID2RSET(RID_R1)|RID2RSET(RID_R3)|RID2RSET(RID_R5)|RID2RSET(RID_R7)| \
66 RID2RSET(RID_R9)|RID2RSET(RID_R11))
67#if LJ_SOFTFP
68#define RSET_FPR 0
69#define RSET_ALL RSET_GPR
70#else
71#error "NYI: VFP support for ARM"
72#endif
73#define RSET_INIT RSET_ALL
74
75/* ABI-specific register sets. lr is an implicit scratch register. */
76#define RSET_SCRATCH_GPR_ (RSET_RANGE(RID_R0, RID_R3+1)|RID2RSET(RID_R12))
77#ifdef __APPLE__
78#define RSET_SCRATCH_GPR (RSET_SCRATCH_GPR_|RID2RSET(RID_R9))
79#else
80#define RSET_SCRATCH_GPR RSET_SCRATCH_GPR_
81#endif
82#if LJ_SOFTFP
83#define RSET_SCRATCH_FPR 0
84#else
85#error "NYI: VFP support for ARM"
86#endif
87#define RSET_SCRATCH (RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
88#define REGARG_FIRSTGPR RID_R0
89#define REGARG_LASTGPR RID_R3
90#define REGARG_NUMGPR 4
91
92/* -- Spill slots --------------------------------------------------------- */
93
94/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
95**
96** SPS_FIXED: Available fixed spill slots in interpreter frame.
97** This definition must match with the *.dasc file(s).
98**
99** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
100*/
101#define SPS_FIXED 2
102#define SPS_FIRST 2
103
104#define sps_scale(slot) (4 * (int32_t)(slot))
105#define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
106
107/* -- Exit state ---------------------------------------------------------- */
108
109/* This definition must match with the *.dasc file(s). */
110typedef struct {
111#if !LJ_SOFTFP
112 lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */
113#endif
114 int32_t gpr[RID_NUM_GPR]; /* General-purpose registers. */
115 int32_t spill[256]; /* Spill slots. */
116} ExitState;
117
118/* PC after instruction that caused an exit. Used to find the trace number. */
119#define EXITSTATE_PCREG RID_PC
120/* Highest exit + 1 indicates stack check. */
121#define EXITSTATE_CHECKEXIT 1
122
123#define EXITSTUB_SPACING 4
124#define EXITSTUBS_PER_GROUP 32
125
126/* -- Instructions -------------------------------------------------------- */
127
128/* Instruction fields. */
129#define ARMF_CC(ai, cc) (((ai) ^ ARMI_CCAL) | ((cc) << 28))
130#define ARMF_N(r) ((r) << 16)
131#define ARMF_D(r) ((r) << 12)
132#define ARMF_S(r) ((r) << 8)
133#define ARMF_M(r) (r)
134#define ARMF_SH(sh, n) (((sh) << 5) | ((n) << 7))
135#define ARMF_RSH(sh, r) (0x10 | ((sh) << 5) | ARMF_S(r))
136
137typedef enum ARMIns {
138 ARMI_CCAL = 0xe0000000,
139 ARMI_S = 0x000100000,
140 ARMI_K12 = 0x02000000,
141 ARMI_KNEG = 0x00200000,
142 ARMI_LS_W = 0x00200000,
143 ARMI_LS_U = 0x00800000,
144 ARMI_LS_P = 0x01000000,
145 ARMI_LS_R = 0x02000000,
146 ARMI_LSX_I = 0x00400000,
147
148 ARMI_AND = 0xe0000000,
149 ARMI_EOR = 0xe0200000,
150 ARMI_SUB = 0xe0400000,
151 ARMI_RSB = 0xe0600000,
152 ARMI_ADD = 0xe0800000,
153 ARMI_ADC = 0xe0a00000,
154 ARMI_SBC = 0xe0c00000,
155 ARMI_RSC = 0xe0e00000,
156 ARMI_TST = 0xe1100000,
157 ARMI_TEQ = 0xe1300000,
158 ARMI_CMP = 0xe1500000,
159 ARMI_CMN = 0xe1700000,
160 ARMI_ORR = 0xe1800000,
161 ARMI_MOV = 0xe1a00000,
162 ARMI_BIC = 0xe1c00000,
163 ARMI_MVN = 0xe1e00000,
164
165 ARMI_NOP = 0xe1a00000,
166
167 ARMI_MUL = 0xe0000090,
168 ARMI_SMULL = 0xe0c00090,
169
170 ARMI_LDR = 0xe4100000,
171 ARMI_LDRB = 0xe4500000,
172 ARMI_LDRH = 0xe01000b0,
173 ARMI_LDRSB = 0xe01000d0,
174 ARMI_LDRSH = 0xe01000f0,
175 ARMI_LDRD = 0xe00000d0,
176 ARMI_STR = 0xe4000000,
177 ARMI_STRB = 0xe4400000,
178 ARMI_STRH = 0xe00000b0,
179 ARMI_STRD = 0xe00000f0,
180 ARMI_PUSH = 0xe92d0000,
181
182 ARMI_B = 0xea000000,
183 ARMI_BL = 0xeb000000,
184 ARMI_BLX = 0xfa000000,
185 ARMI_BLXr = 0xe12fff30,
186
187 /* ARMv6 */
188 ARMI_REV = 0xe6bf0f30,
189 ARMI_SXTB = 0xe6af0070,
190 ARMI_SXTH = 0xe6bf0070,
191 ARMI_UXTB = 0xe6ef0070,
192 ARMI_UXTH = 0xe6ff0070,
193
194 /* ARMv6T2 */
195 ARMI_MOVW = 0xe3000000,
196 ARMI_MOVT = 0xe3400000,
197} ARMIns;
198
199typedef enum ARMShift {
200 ARMSH_LSL, ARMSH_LSR, ARMSH_ASR, ARMSH_ROR
201} ARMShift;
202
203/* ARM condition codes. */
204typedef enum ARMCC {
205 CC_EQ, CC_NE, CC_CS, CC_CC, CC_MI, CC_PL, CC_VS, CC_VC,
206 CC_HI, CC_LS, CC_GE, CC_LT, CC_GT, CC_LE, CC_AL,
207 CC_HS = CC_CS, CC_LO = CC_CC
208} ARMCC;
209
210#endif
diff --git a/libraries/luajit-2.0/src/lj_target_ppc.h b/libraries/luajit-2.0/src/lj_target_ppc.h
new file mode 100644
index 0000000..d8fbea6
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_target_ppc.h
@@ -0,0 +1,279 @@
1/*
2** Definitions for PPC CPUs.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_TARGET_PPC_H
7#define _LJ_TARGET_PPC_H
8
9/* -- Registers IDs ------------------------------------------------------- */
10
11#define GPRDEF(_) \
12 _(R0) _(SP) _(SYS1) _(R3) _(R4) _(R5) _(R6) _(R7) \
13 _(R8) _(R9) _(R10) _(R11) _(R12) _(SYS2) _(R14) _(R15) \
14 _(R16) _(R17) _(R18) _(R19) _(R20) _(R21) _(R22) _(R23) \
15 _(R24) _(R25) _(R26) _(R27) _(R28) _(R29) _(R30) _(R31)
16#define FPRDEF(_) \
17 _(F0) _(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) \
18 _(F8) _(F9) _(F10) _(F11) _(F12) _(F13) _(F14) _(F15) \
19 _(F16) _(F17) _(F18) _(F19) _(F20) _(F21) _(F22) _(F23) \
20 _(F24) _(F25) _(F26) _(F27) _(F28) _(F29) _(F30) _(F31)
21#define VRIDDEF(_)
22
23#define RIDENUM(name) RID_##name,
24
25enum {
26 GPRDEF(RIDENUM) /* General-purpose registers (GPRs). */
27 FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */
28 RID_MAX,
29 RID_TMP = RID_R0,
30
31 /* Calling conventions. */
32 RID_RET = RID_R3,
33 RID_RETHI = RID_R3,
34 RID_RETLO = RID_R4,
35 RID_FPRET = RID_F1,
36
37 /* These definitions must match with the *.dasc file(s): */
38 RID_BASE = RID_R14, /* Interpreter BASE. */
39 RID_LPC = RID_R16, /* Interpreter PC. */
40 RID_DISPATCH = RID_R17, /* Interpreter DISPATCH table. */
41 RID_LREG = RID_R18, /* Interpreter L. */
42 RID_JGL = RID_R31, /* On-trace: global_State + 32768. */
43
44 /* Register ranges [min, max) and number of registers. */
45 RID_MIN_GPR = RID_R0,
46 RID_MAX_GPR = RID_R31+1,
47 RID_MIN_FPR = RID_F0,
48 RID_MAX_FPR = RID_F31+1,
49 RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
50 RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR
51};
52
53#define RID_NUM_KREF RID_NUM_GPR
54#define RID_MIN_KREF RID_R0
55
56/* -- Register sets ------------------------------------------------------- */
57
58/* Make use of all registers, except TMP, SP, SYS1, SYS2 and JGL. */
59#define RSET_FIXED \
60 (RID2RSET(RID_TMP)|RID2RSET(RID_SP)|RID2RSET(RID_SYS1)|\
61 RID2RSET(RID_SYS2)|RID2RSET(RID_JGL))
62#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED)
63#define RSET_FPR RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR)
64#define RSET_ALL (RSET_GPR|RSET_FPR)
65#define RSET_INIT RSET_ALL
66
67#define RSET_SCRATCH_GPR (RSET_RANGE(RID_R3, RID_R12+1))
68#define RSET_SCRATCH_FPR (RSET_RANGE(RID_F0, RID_F13+1))
69#define RSET_SCRATCH (RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
70#define REGARG_FIRSTGPR RID_R3
71#define REGARG_LASTGPR RID_R10
72#define REGARG_NUMGPR 8
73#define REGARG_FIRSTFPR RID_F1
74#define REGARG_LASTFPR RID_F8
75#define REGARG_NUMFPR 8
76
77/* -- Spill slots --------------------------------------------------------- */
78
79/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
80**
81** SPS_FIXED: Available fixed spill slots in interpreter frame.
82** This definition must match with the *.dasc file(s).
83**
84** SPS_FIRST: First spill slot for general use.
85** [sp+12] tmplo word \
86** [sp+ 8] tmphi word / tmp dword, parameter area for callee
87** [sp+ 4] tmpw, LR of callee
88** [sp+ 0] stack chain
89*/
90#define SPS_FIXED 7
91#define SPS_FIRST 4
92
93/* Stack offsets for temporary slots. Used for FP<->int conversions etc. */
94#define SPOFS_TMPW 4
95#define SPOFS_TMP 8
96#define SPOFS_TMPHI 8
97#define SPOFS_TMPLO 12
98
99#define sps_scale(slot) (4 * (int32_t)(slot))
100#define sps_align(slot) (((slot) - SPS_FIXED + 3) & ~3)
101
102/* -- Exit state ---------------------------------------------------------- */
103
104/* This definition must match with the *.dasc file(s). */
105typedef struct {
106 lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */
107 int32_t gpr[RID_NUM_GPR]; /* General-purpose registers. */
108 int32_t spill[256]; /* Spill slots. */
109} ExitState;
110
111/* Highest exit + 1 indicates stack check. */
112#define EXITSTATE_CHECKEXIT 1
113
114/* Return the address of a per-trace exit stub. */
115static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p, uint32_t exitno)
116{
117 while (*p == 0x60000000) p++; /* Skip PPCI_NOP. */
118 return p + 3 + exitno;
119}
120/* Avoid dependence on lj_jit.h if only including lj_target.h. */
121#define exitstub_trace_addr(T, exitno) \
122 exitstub_trace_addr_((MCode *)((char *)(T)->mcode + (T)->szmcode), (exitno))
123
124/* -- Instructions -------------------------------------------------------- */
125
126/* Instruction fields. */
127#define PPCF_CC(cc) ((((cc) & 3) << 16) | (((cc) & 4) << 22))
128#define PPCF_T(r) ((r) << 21)
129#define PPCF_A(r) ((r) << 16)
130#define PPCF_B(r) ((r) << 11)
131#define PPCF_C(r) ((r) << 6)
132#define PPCF_MB(n) ((n) << 6)
133#define PPCF_ME(n) ((n) << 1)
134#define PPCF_Y 0x00200000
135#define PPCF_DOT 0x00000001
136
137typedef enum PPCIns {
138 /* Integer instructions. */
139 PPCI_MR = 0x7c000378,
140 PPCI_NOP = 0x60000000,
141
142 PPCI_LI = 0x38000000,
143 PPCI_LIS = 0x3c000000,
144
145 PPCI_ADD = 0x7c000214,
146 PPCI_ADDC = 0x7c000014,
147 PPCI_ADDO = 0x7c000614,
148 PPCI_ADDE = 0x7c000114,
149 PPCI_ADDZE = 0x7c000194,
150 PPCI_ADDME = 0x7c0001d4,
151 PPCI_ADDI = 0x38000000,
152 PPCI_ADDIS = 0x3c000000,
153 PPCI_ADDIC = 0x30000000,
154 PPCI_ADDICDOT = 0x34000000,
155
156 PPCI_SUBF = 0x7c000050,
157 PPCI_SUBFC = 0x7c000010,
158 PPCI_SUBFO = 0x7c000450,
159 PPCI_SUBFE = 0x7c000110,
160 PPCI_SUBFZE = 0x7c000190,
161 PPCI_SUBFME = 0x7c0001d0,
162 PPCI_SUBFIC = 0x20000000,
163
164 PPCI_NEG = 0x7c0000d0,
165
166 PPCI_AND = 0x7c000038,
167 PPCI_ANDC = 0x7c000078,
168 PPCI_NAND = 0x7c0003b8,
169 PPCI_ANDIDOT = 0x70000000,
170 PPCI_ANDISDOT = 0x74000000,
171
172 PPCI_OR = 0x7c000378,
173 PPCI_NOR = 0x7c0000f8,
174 PPCI_ORI = 0x60000000,
175 PPCI_ORIS = 0x64000000,
176
177 PPCI_XOR = 0x7c000278,
178 PPCI_EQV = 0x7c000238,
179 PPCI_XORI = 0x68000000,
180 PPCI_XORIS = 0x6c000000,
181
182 PPCI_CMPW = 0x7c000000,
183 PPCI_CMPLW = 0x7c000040,
184 PPCI_CMPWI = 0x2c000000,
185 PPCI_CMPLWI = 0x28000000,
186
187 PPCI_MULLW = 0x7c0001d6,
188 PPCI_MULLI = 0x1c000000,
189 PPCI_MULLWO = 0x7c0005d6,
190
191 PPCI_EXTSB = 0x7c000774,
192 PPCI_EXTSH = 0x7c000734,
193
194 PPCI_SLW = 0x7c000030,
195 PPCI_SRW = 0x7c000430,
196 PPCI_SRAW = 0x7c000630,
197 PPCI_SRAWI = 0x7c000670,
198
199 PPCI_RLWNM = 0x5c000000,
200 PPCI_RLWINM = 0x54000000,
201 PPCI_RLWIMI = 0x50000000,
202
203 PPCI_B = 0x48000000,
204 PPCI_BL = 0x48000001,
205 PPCI_BC = 0x40800000,
206 PPCI_BCL = 0x40800001,
207 PPCI_BCTR = 0x4e800420,
208 PPCI_BCTRL = 0x4e800421,
209
210 PPCI_CRANDC = 0x4c000102,
211 PPCI_CRXOR = 0x4c000182,
212 PPCI_CRAND = 0x4c000202,
213 PPCI_CREQV = 0x4c000242,
214 PPCI_CRORC = 0x4c000342,
215 PPCI_CROR = 0x4c000382,
216
217 PPCI_MFLR = 0x7c0802a6,
218 PPCI_MTCTR = 0x7c0903a6,
219
220 PPCI_MCRXR = 0x7c000400,
221
222 /* Load/store instructions. */
223 PPCI_LWZ = 0x80000000,
224 PPCI_LBZ = 0x88000000,
225 PPCI_STW = 0x90000000,
226 PPCI_STB = 0x98000000,
227 PPCI_LHZ = 0xa0000000,
228 PPCI_LHA = 0xa8000000,
229 PPCI_STH = 0xb0000000,
230
231 PPCI_STWU = 0x94000000,
232
233 PPCI_LFS = 0xc0000000,
234 PPCI_LFD = 0xc8000000,
235 PPCI_STFS = 0xd0000000,
236 PPCI_STFD = 0xd8000000,
237
238 PPCI_LWZX = 0x7c00002e,
239 PPCI_LBZX = 0x7c0000ae,
240 PPCI_STWX = 0x7c00012e,
241 PPCI_STBX = 0x7c0001ae,
242 PPCI_LHZX = 0x7c00022e,
243 PPCI_LHAX = 0x7c0002ae,
244 PPCI_STHX = 0x7c00032e,
245
246 PPCI_LWBRX = 0x7c00042c,
247 PPCI_STWBRX = 0x7c00052c,
248
249 PPCI_LFSX = 0x7c00042e,
250 PPCI_LFDX = 0x7c0004ae,
251 PPCI_STFSX = 0x7c00052e,
252 PPCI_STFDX = 0x7c0005ae,
253
254 /* FP instructions. */
255 PPCI_FMR = 0xfc000090,
256 PPCI_FNEG = 0xfc000050,
257 PPCI_FABS = 0xfc000210,
258
259 PPCI_FRSP = 0xfc000018,
260 PPCI_FCTIWZ = 0xfc00001e,
261
262 PPCI_FADD = 0xfc00002a,
263 PPCI_FSUB = 0xfc000028,
264 PPCI_FMUL = 0xfc000032,
265 PPCI_FDIV = 0xfc000024,
266
267 PPCI_FMADD = 0xfc00003a,
268 PPCI_FMSUB = 0xfc000038,
269 PPCI_FNMSUB = 0xfc00003c,
270
271 PPCI_FCMPU = 0xfc000000,
272 PPCI_FSEL = 0xfc00002e,
273} PPCIns;
274
275typedef enum PPCCC {
276 CC_GE, CC_LE, CC_NE, CC_NS, CC_LT, CC_GT, CC_EQ, CC_SO
277} PPCCC;
278
279#endif
diff --git a/libraries/luajit-2.0/src/lj_target_x86.h b/libraries/luajit-2.0/src/lj_target_x86.h
new file mode 100644
index 0000000..593e7b0
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_target_x86.h
@@ -0,0 +1,337 @@
1/*
2** Definitions for x86 and x64 CPUs.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_TARGET_X86_H
7#define _LJ_TARGET_X86_H
8
9/* -- Registers IDs ------------------------------------------------------- */
10
11#if LJ_64
12#define GPRDEF(_) \
13 _(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI) \
14 _(R8D) _(R9D) _(R10D) _(R11D) _(R12D) _(R13D) _(R14D) _(R15D)
15#define FPRDEF(_) \
16 _(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7) \
17 _(XMM8) _(XMM9) _(XMM10) _(XMM11) _(XMM12) _(XMM13) _(XMM14) _(XMM15)
18#else
19#define GPRDEF(_) \
20 _(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI)
21#define FPRDEF(_) \
22 _(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7)
23#endif
24#define VRIDDEF(_) \
25 _(MRM)
26
27#define RIDENUM(name) RID_##name,
28
29enum {
30 GPRDEF(RIDENUM) /* General-purpose registers (GPRs). */
31 FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */
32 RID_MAX,
33 RID_MRM = RID_MAX, /* Pseudo-id for ModRM operand. */
34
35 /* Calling conventions. */
36 RID_RET = RID_EAX,
37#if LJ_64
38 RID_FPRET = RID_XMM0,
39#else
40 RID_RETLO = RID_EAX,
41 RID_RETHI = RID_EDX,
42#endif
43
44 /* These definitions must match with the *.dasc file(s): */
45 RID_BASE = RID_EDX, /* Interpreter BASE. */
46#if LJ_64 && !LJ_ABI_WIN
47 RID_LPC = RID_EBX, /* Interpreter PC. */
48 RID_DISPATCH = RID_R14D, /* Interpreter DISPATCH table. */
49#else
50 RID_LPC = RID_ESI, /* Interpreter PC. */
51 RID_DISPATCH = RID_EBX, /* Interpreter DISPATCH table. */
52#endif
53
54 /* Register ranges [min, max) and number of registers. */
55 RID_MIN_GPR = RID_EAX,
56 RID_MIN_FPR = RID_XMM0,
57 RID_MAX_GPR = RID_MIN_FPR,
58 RID_MAX_FPR = RID_MAX,
59 RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
60 RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR,
61};
62
63/* -- Register sets ------------------------------------------------------- */
64
65/* Make use of all registers, except the stack pointer. */
66#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR)-RID2RSET(RID_ESP))
67#define RSET_FPR (RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR))
68#define RSET_ALL (RSET_GPR|RSET_FPR)
69#define RSET_INIT RSET_ALL
70
71#if LJ_64
72/* Note: this requires the use of FORCE_REX! */
73#define RSET_GPR8 RSET_GPR
74#else
75#define RSET_GPR8 (RSET_RANGE(RID_EAX, RID_EBX+1))
76#endif
77
78/* ABI-specific register sets. */
79#define RSET_ACD (RID2RSET(RID_EAX)|RID2RSET(RID_ECX)|RID2RSET(RID_EDX))
80#if LJ_64
81#if LJ_ABI_WIN
82/* Windows x64 ABI. */
83#define RSET_SCRATCH \
84 (RSET_ACD|RSET_RANGE(RID_R8D, RID_R11D+1)|RSET_RANGE(RID_XMM0, RID_XMM5+1))
85#define REGARG_GPRS \
86 (RID_ECX|((RID_EDX|((RID_R8D|(RID_R9D<<5))<<5))<<5))
87#define REGARG_NUMGPR 4
88#define REGARG_NUMFPR 4
89#define REGARG_FIRSTFPR RID_XMM0
90#define REGARG_LASTFPR RID_XMM3
91#define STACKARG_OFS (4*8)
92#else
93/* The rest of the civilized x64 world has a common ABI. */
94#define RSET_SCRATCH \
95 (RSET_ACD|RSET_RANGE(RID_ESI, RID_R11D+1)|RSET_FPR)
96#define REGARG_GPRS \
97 (RID_EDI|((RID_ESI|((RID_EDX|((RID_ECX|((RID_R8D|(RID_R9D \
98 <<5))<<5))<<5))<<5))<<5))
99#define REGARG_NUMGPR 6
100#define REGARG_NUMFPR 8
101#define REGARG_FIRSTFPR RID_XMM0
102#define REGARG_LASTFPR RID_XMM7
103#define STACKARG_OFS 0
104#endif
105#else
106/* Common x86 ABI. */
107#define RSET_SCRATCH (RSET_ACD|RSET_FPR)
108#define REGARG_GPRS (RID_ECX|(RID_EDX<<5)) /* Fastcall only. */
109#define REGARG_NUMGPR 2 /* Fastcall only. */
110#define REGARG_NUMFPR 0
111#define STACKARG_OFS 0
112#endif
113
114#if LJ_64
115/* Prefer the low 8 regs of each type to reduce REX prefixes. */
116#undef rset_picktop
117#define rset_picktop(rs) (lj_fls(lj_bswap(rs)) ^ 0x18)
118#endif
119
120/* -- Spill slots --------------------------------------------------------- */
121
122/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
123**
124** SPS_FIXED: Available fixed spill slots in interpreter frame.
125** This definition must match with the *.dasc file(s).
126**
127** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
128*/
129#if LJ_64
130#if LJ_ABI_WIN
131#define SPS_FIXED (4*2)
132#define SPS_FIRST (4*2) /* Don't use callee register save area. */
133#else
134#define SPS_FIXED 4
135#define SPS_FIRST 2
136#endif
137#else
138#define SPS_FIXED 6
139#define SPS_FIRST 2
140#endif
141
142#define sps_scale(slot) (4 * (int32_t)(slot))
143#define sps_align(slot) (((slot) - SPS_FIXED + 3) & ~3)
144
145/* -- Exit state ---------------------------------------------------------- */
146
147/* This definition must match with the *.dasc file(s). */
148typedef struct {
149 lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */
150 intptr_t gpr[RID_NUM_GPR]; /* General-purpose registers. */
151 int32_t spill[256]; /* Spill slots. */
152} ExitState;
153
154/* Limited by the range of a short fwd jump (127): (2+2)*(32-1)-2 = 122. */
155#define EXITSTUB_SPACING (2+2)
156#define EXITSTUBS_PER_GROUP 32
157
158/* -- x86 ModRM operand encoding ------------------------------------------ */
159
160typedef enum {
161 XM_OFS0 = 0x00, XM_OFS8 = 0x40, XM_OFS32 = 0x80, XM_REG = 0xc0,
162 XM_SCALE1 = 0x00, XM_SCALE2 = 0x40, XM_SCALE4 = 0x80, XM_SCALE8 = 0xc0,
163 XM_MASK = 0xc0
164} x86Mode;
165
166/* Structure to hold variable ModRM operand. */
167typedef struct {
168 int32_t ofs; /* Offset. */
169 uint8_t base; /* Base register or RID_NONE. */
170 uint8_t idx; /* Index register or RID_NONE. */
171 uint8_t scale; /* Index scale (XM_SCALE1 .. XM_SCALE8). */
172} x86ModRM;
173
174/* -- Opcodes ------------------------------------------------------------- */
175
176/* Macros to construct variable-length x86 opcodes. -(len+1) is in LSB. */
177#define XO_(o) ((uint32_t)(0x0000fe + (0x##o<<24)))
178#define XO_FPU(a,b) ((uint32_t)(0x00fd + (0x##a<<16)+(0x##b<<24)))
179#define XO_0f(o) ((uint32_t)(0x0f00fd + (0x##o<<24)))
180#define XO_66(o) ((uint32_t)(0x6600fd + (0x##o<<24)))
181#define XO_660f(o) ((uint32_t)(0x0f66fc + (0x##o<<24)))
182#define XO_f20f(o) ((uint32_t)(0x0ff2fc + (0x##o<<24)))
183#define XO_f30f(o) ((uint32_t)(0x0ff3fc + (0x##o<<24)))
184
185/* This list of x86 opcodes is not intended to be complete. Opcodes are only
186** included when needed. Take a look at DynASM or jit.dis_x86 to see the
187** whole mess.
188*/
189typedef enum {
190 /* Fixed length opcodes. XI_* prefix. */
191 XI_NOP = 0x90,
192 XI_CALL = 0xe8,
193 XI_JMP = 0xe9,
194 XI_JMPs = 0xeb,
195 XI_PUSH = 0x50, /* Really 50+r. */
196 XI_JCCs = 0x70, /* Really 7x. */
197 XI_JCCn = 0x80, /* Really 0f8x. */
198 XI_LEA = 0x8d,
199 XI_MOVrib = 0xb0, /* Really b0+r. */
200 XI_MOVri = 0xb8, /* Really b8+r. */
201 XI_ARITHib = 0x80,
202 XI_ARITHi = 0x81,
203 XI_ARITHi8 = 0x83,
204 XI_PUSHi8 = 0x6a,
205 XI_TEST = 0x85,
206 XI_MOVmi = 0xc7,
207 XI_GROUP5 = 0xff,
208
209 /* Note: little-endian byte-order! */
210 XI_FLDZ = 0xeed9,
211 XI_FLD1 = 0xe8d9,
212 XI_FLDLG2 = 0xecd9,
213 XI_FLDLN2 = 0xedd9,
214 XI_FDUP = 0xc0d9, /* Really fld st0. */
215 XI_FPOP = 0xd8dd, /* Really fstp st0. */
216 XI_FPOP1 = 0xd9dd, /* Really fstp st1. */
217 XI_FRNDINT = 0xfcd9,
218 XI_FSIN = 0xfed9,
219 XI_FCOS = 0xffd9,
220 XI_FPTAN = 0xf2d9,
221 XI_FPATAN = 0xf3d9,
222 XI_FSCALE = 0xfdd9,
223 XI_FYL2X = 0xf1d9,
224
225 /* Variable-length opcodes. XO_* prefix. */
226 XO_MOV = XO_(8b),
227 XO_MOVto = XO_(89),
228 XO_MOVtow = XO_66(89),
229 XO_MOVtob = XO_(88),
230 XO_MOVmi = XO_(c7),
231 XO_MOVmib = XO_(c6),
232 XO_LEA = XO_(8d),
233 XO_ARITHib = XO_(80),
234 XO_ARITHi = XO_(81),
235 XO_ARITHi8 = XO_(83),
236 XO_ARITHiw8 = XO_66(83),
237 XO_SHIFTi = XO_(c1),
238 XO_SHIFT1 = XO_(d1),
239 XO_SHIFTcl = XO_(d3),
240 XO_IMUL = XO_0f(af),
241 XO_IMULi = XO_(69),
242 XO_IMULi8 = XO_(6b),
243 XO_CMP = XO_(3b),
244 XO_TEST = XO_(85),
245 XO_GROUP3b = XO_(f6),
246 XO_GROUP3 = XO_(f7),
247 XO_GROUP5b = XO_(fe),
248 XO_GROUP5 = XO_(ff),
249 XO_MOVZXb = XO_0f(b6),
250 XO_MOVZXw = XO_0f(b7),
251 XO_MOVSXb = XO_0f(be),
252 XO_MOVSXw = XO_0f(bf),
253 XO_MOVSXd = XO_(63),
254 XO_BSWAP = XO_0f(c8),
255 XO_CMOV = XO_0f(40),
256
257 XO_MOVSD = XO_f20f(10),
258 XO_MOVSDto = XO_f20f(11),
259 XO_MOVSS = XO_f30f(10),
260 XO_MOVSSto = XO_f30f(11),
261 XO_MOVLPD = XO_660f(12),
262 XO_MOVAPS = XO_0f(28),
263 XO_XORPS = XO_0f(57),
264 XO_ANDPS = XO_0f(54),
265 XO_ADDSD = XO_f20f(58),
266 XO_SUBSD = XO_f20f(5c),
267 XO_MULSD = XO_f20f(59),
268 XO_DIVSD = XO_f20f(5e),
269 XO_SQRTSD = XO_f20f(51),
270 XO_MINSD = XO_f20f(5d),
271 XO_MAXSD = XO_f20f(5f),
272 XO_ROUNDSD = 0x0b3a0ffc, /* Really 66 0f 3a 0b. See asm_fpmath. */
273 XO_UCOMISD = XO_660f(2e),
274 XO_CVTSI2SD = XO_f20f(2a),
275 XO_CVTSD2SI = XO_f20f(2d),
276 XO_CVTTSD2SI= XO_f20f(2c),
277 XO_CVTSI2SS = XO_f30f(2a),
278 XO_CVTSS2SI = XO_f30f(2d),
279 XO_CVTTSS2SI= XO_f30f(2c),
280 XO_CVTSS2SD = XO_f30f(5a),
281 XO_CVTSD2SS = XO_f20f(5a),
282 XO_ADDSS = XO_f30f(58),
283 XO_MOVD = XO_660f(6e),
284 XO_MOVDto = XO_660f(7e),
285
286 XO_FLDd = XO_(d9), XOg_FLDd = 0,
287 XO_FLDq = XO_(dd), XOg_FLDq = 0,
288 XO_FILDd = XO_(db), XOg_FILDd = 0,
289 XO_FILDq = XO_(df), XOg_FILDq = 5,
290 XO_FSTPd = XO_(d9), XOg_FSTPd = 3,
291 XO_FSTPq = XO_(dd), XOg_FSTPq = 3,
292 XO_FISTPq = XO_(df), XOg_FISTPq = 7,
293 XO_FISTTPq = XO_(dd), XOg_FISTTPq = 1,
294 XO_FADDq = XO_(dc), XOg_FADDq = 0,
295 XO_FLDCW = XO_(d9), XOg_FLDCW = 5,
296 XO_FNSTCW = XO_(d9), XOg_FNSTCW = 7
297} x86Op;
298
299/* x86 opcode groups. */
300typedef uint32_t x86Group;
301
302#define XG_(i8, i, g) ((x86Group)(((i8) << 16) + ((i) << 8) + (g)))
303#define XG_ARITHi(g) XG_(XI_ARITHi8, XI_ARITHi, g)
304#define XG_TOXOi(xg) ((x86Op)(0x000000fe + (((xg)<<16) & 0xff000000)))
305#define XG_TOXOi8(xg) ((x86Op)(0x000000fe + (((xg)<<8) & 0xff000000)))
306
307#define XO_ARITH(a) ((x86Op)(0x030000fe + ((a)<<27)))
308#define XO_ARITHw(a) ((x86Op)(0x036600fd + ((a)<<27)))
309
310typedef enum {
311 XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP,
312 XOg_X_IMUL
313} x86Arith;
314
315typedef enum {
316 XOg_ROL, XOg_ROR, XOg_RCL, XOg_RCR, XOg_SHL, XOg_SHR, XOg_SAL, XOg_SAR
317} x86Shift;
318
319typedef enum {
320 XOg_TEST, XOg_TEST_, XOg_NOT, XOg_NEG, XOg_MUL, XOg_IMUL, XOg_DIV, XOg_IDIV
321} x86Group3;
322
323typedef enum {
324 XOg_INC, XOg_DEC, XOg_CALL, XOg_CALLfar, XOg_JMP, XOg_JMPfar, XOg_PUSH
325} x86Group5;
326
327/* x86 condition codes. */
328typedef enum {
329 CC_O, CC_NO, CC_B, CC_NB, CC_E, CC_NE, CC_BE, CC_NBE,
330 CC_S, CC_NS, CC_P, CC_NP, CC_L, CC_NL, CC_LE, CC_NLE,
331 CC_C = CC_B, CC_NAE = CC_C, CC_NC = CC_NB, CC_AE = CC_NB,
332 CC_Z = CC_E, CC_NZ = CC_NE, CC_NA = CC_BE, CC_A = CC_NBE,
333 CC_PE = CC_P, CC_PO = CC_NP, CC_NGE = CC_L, CC_GE = CC_NL,
334 CC_NG = CC_LE, CC_G = CC_NLE
335} x86CC;
336
337#endif
diff --git a/libraries/luajit-2.0/src/lj_trace.c b/libraries/luajit-2.0/src/lj_trace.c
new file mode 100644
index 0000000..9645ecb
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_trace.c
@@ -0,0 +1,812 @@
1/*
2** Trace management.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_trace_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12
13#include "lj_gc.h"
14#include "lj_err.h"
15#include "lj_debug.h"
16#include "lj_str.h"
17#include "lj_frame.h"
18#include "lj_state.h"
19#include "lj_bc.h"
20#include "lj_ir.h"
21#include "lj_jit.h"
22#include "lj_iropt.h"
23#include "lj_mcode.h"
24#include "lj_trace.h"
25#include "lj_snap.h"
26#include "lj_gdbjit.h"
27#include "lj_record.h"
28#include "lj_asm.h"
29#include "lj_dispatch.h"
30#include "lj_vm.h"
31#include "lj_vmevent.h"
32#include "lj_target.h"
33
34/* -- Error handling ------------------------------------------------------ */
35
36/* Synchronous abort with error message. */
37void lj_trace_err(jit_State *J, TraceError e)
38{
39 setnilV(&J->errinfo); /* No error info. */
40 setintV(J->L->top++, (int32_t)e);
41 lj_err_throw(J->L, LUA_ERRRUN);
42}
43
44/* Synchronous abort with error message and error info. */
45void lj_trace_err_info(jit_State *J, TraceError e)
46{
47 setintV(J->L->top++, (int32_t)e);
48 lj_err_throw(J->L, LUA_ERRRUN);
49}
50
51/* -- Trace management ---------------------------------------------------- */
52
53/* The current trace is first assembled in J->cur. The variable length
54** arrays point to shared, growable buffers (J->irbuf etc.). When trace
55** recording ends successfully, the current trace and its data structures
56** are copied to a new (compact) GCtrace object.
57*/
58
59/* Find a free trace number. */
60static TraceNo trace_findfree(jit_State *J)
61{
62 MSize osz, lim;
63 if (J->freetrace == 0)
64 J->freetrace = 1;
65 for (; J->freetrace < J->sizetrace; J->freetrace++)
66 if (traceref(J, J->freetrace) == NULL)
67 return J->freetrace++;
68 /* Need to grow trace array. */
69 lim = (MSize)J->param[JIT_P_maxtrace] + 1;
70 if (lim < 2) lim = 2; else if (lim > 65535) lim = 65535;
71 osz = J->sizetrace;
72 if (osz >= lim)
73 return 0; /* Too many traces. */
74 lj_mem_growvec(J->L, J->trace, J->sizetrace, lim, GCRef);
75 for (; osz < J->sizetrace; osz++)
76 setgcrefnull(J->trace[osz]);
77 return J->freetrace;
78}
79
80#define TRACE_APPENDVEC(field, szfield, tp) \
81 T->field = (tp *)p; \
82 memcpy(p, J->cur.field, J->cur.szfield*sizeof(tp)); \
83 p += J->cur.szfield*sizeof(tp);
84
85#ifdef LUAJIT_USE_PERFTOOLS
86/*
87** Create symbol table of JIT-compiled code. For use with Linux perf tools.
88** Example usage:
89** perf record -f -e cycles luajit test.lua
90** perf report -s symbol
91** rm perf.data /tmp/perf-*.map
92*/
93#include <stdio.h>
94#include <unistd.h>
95
96static void perftools_addtrace(GCtrace *T)
97{
98 static FILE *fp;
99 GCproto *pt = &gcref(T->startpt)->pt;
100 const BCIns *startpc = mref(T->startpc, const BCIns);
101 const char *name = proto_chunknamestr(pt);
102 BCLine lineno;
103 if (name[0] == '@' || name[0] == '=')
104 name++;
105 else
106 name = "(string)";
107 lua_assert(startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc);
108 lineno = lj_debug_line(pt, proto_bcpos(pt, startpc));
109 if (!fp) {
110 char fname[40];
111 sprintf(fname, "/tmp/perf-%d.map", getpid());
112 if (!(fp = fopen(fname, "w"))) return;
113 setlinebuf(fp);
114 }
115 fprintf(fp, "%lx %x TRACE_%d::%s:%u\n",
116 (long)T->mcode, T->szmcode, T->traceno, name, lineno);
117}
118#endif
119
120/* Save current trace by copying and compacting it. */
121static void trace_save(jit_State *J)
122{
123 size_t sztr = ((sizeof(GCtrace)+7)&~7);
124 size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
125 size_t sz = sztr + szins +
126 J->cur.nsnap*sizeof(SnapShot) +
127 J->cur.nsnapmap*sizeof(SnapEntry);
128 GCtrace *T = lj_mem_newt(J->L, (MSize)sz, GCtrace);
129 char *p = (char *)T + sztr;
130 memcpy(T, &J->cur, sizeof(GCtrace));
131 setgcrefr(T->nextgc, J2G(J)->gc.root);
132 setgcrefp(J2G(J)->gc.root, T);
133 newwhite(J2G(J), T);
134 T->gct = ~LJ_TTRACE;
135 T->ir = (IRIns *)p - J->cur.nk;
136 memcpy(p, J->cur.ir+J->cur.nk, szins);
137 p += szins;
138 TRACE_APPENDVEC(snap, nsnap, SnapShot)
139 TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
140 J->cur.traceno = 0;
141 setgcrefp(J->trace[T->traceno], T);
142 lj_gc_barriertrace(J2G(J), T->traceno);
143 lj_gdbjit_addtrace(J, T);
144#ifdef LUAJIT_USE_PERFTOOLS
145 perftools_addtrace(T);
146#endif
147}
148
149void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T)
150{
151 jit_State *J = G2J(g);
152 if (T->traceno) {
153 lj_gdbjit_deltrace(J, T);
154 if (T->traceno < J->freetrace)
155 J->freetrace = T->traceno;
156 setgcrefnull(J->trace[T->traceno]);
157 }
158 lj_mem_free(g, T,
159 ((sizeof(GCtrace)+7)&~7) + (T->nins-T->nk)*sizeof(IRIns) +
160 T->nsnap*sizeof(SnapShot) + T->nsnapmap*sizeof(SnapEntry));
161}
162
163/* Re-enable compiling a prototype by unpatching any modified bytecode. */
164void lj_trace_reenableproto(GCproto *pt)
165{
166 if ((pt->flags & PROTO_ILOOP)) {
167 BCIns *bc = proto_bc(pt);
168 BCPos i, sizebc = pt->sizebc;;
169 pt->flags &= ~PROTO_ILOOP;
170 if (bc_op(bc[0]) == BC_IFUNCF)
171 setbc_op(&bc[0], BC_FUNCF);
172 for (i = 1; i < sizebc; i++) {
173 BCOp op = bc_op(bc[i]);
174 if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP)
175 setbc_op(&bc[i], (int)op+(int)BC_LOOP-(int)BC_ILOOP);
176 }
177 }
178}
179
180/* Unpatch the bytecode modified by a root trace. */
181static void trace_unpatch(jit_State *J, GCtrace *T)
182{
183 BCOp op = bc_op(T->startins);
184 BCIns *pc = mref(T->startpc, BCIns);
185 UNUSED(J);
186 if (op == BC_JMP)
187 return; /* No need to unpatch branches in parent traces (yet). */
188 switch (bc_op(*pc)) {
189 case BC_JFORL:
190 lua_assert(traceref(J, bc_d(*pc)) == T);
191 *pc = T->startins;
192 pc += bc_j(T->startins);
193 lua_assert(bc_op(*pc) == BC_JFORI);
194 setbc_op(pc, BC_FORI);
195 break;
196 case BC_JITERL:
197 case BC_JLOOP:
198 lua_assert(op == BC_ITERL || op == BC_LOOP || bc_isret(op));
199 *pc = T->startins;
200 break;
201 case BC_JMP:
202 lua_assert(op == BC_ITERL);
203 pc += bc_j(*pc)+2;
204 if (bc_op(*pc) == BC_JITERL) {
205 lua_assert(traceref(J, bc_d(*pc)) == T);
206 *pc = T->startins;
207 }
208 break;
209 case BC_JFUNCF:
210 lua_assert(op == BC_FUNCF);
211 *pc = T->startins;
212 break;
213 default: /* Already unpatched. */
214 break;
215 }
216}
217
218/* Flush a root trace. */
219static void trace_flushroot(jit_State *J, GCtrace *T)
220{
221 GCproto *pt = &gcref(T->startpt)->pt;
222 lua_assert(T->root == 0 && pt != NULL);
223 /* First unpatch any modified bytecode. */
224 trace_unpatch(J, T);
225 /* Unlink root trace from chain anchored in prototype. */
226 if (pt->trace == T->traceno) { /* Trace is first in chain. Easy. */
227 pt->trace = T->nextroot;
228 } else if (pt->trace) { /* Otherwise search in chain of root traces. */
229 GCtrace *T2 = traceref(J, pt->trace);
230 if (T2) {
231 for (; T2->nextroot; T2 = traceref(J, T2->nextroot))
232 if (T2->nextroot == T->traceno) {
233 T2->nextroot = T->nextroot; /* Unlink from chain. */
234 break;
235 }
236 }
237 }
238}
239
240/* Flush a trace. Only root traces are considered. */
241void lj_trace_flush(jit_State *J, TraceNo traceno)
242{
243 if (traceno > 0 && traceno < J->sizetrace) {
244 GCtrace *T = traceref(J, traceno);
245 if (T && T->root == 0)
246 trace_flushroot(J, T);
247 }
248}
249
250/* Flush all traces associated with a prototype. */
251void lj_trace_flushproto(global_State *g, GCproto *pt)
252{
253 while (pt->trace != 0)
254 trace_flushroot(G2J(g), traceref(G2J(g), pt->trace));
255}
256
257/* Flush all traces. */
258int lj_trace_flushall(lua_State *L)
259{
260 jit_State *J = L2J(L);
261 ptrdiff_t i;
262 if ((J2G(J)->hookmask & HOOK_GC))
263 return 1;
264 for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
265 GCtrace *T = traceref(J, i);
266 if (T) {
267 if (T->root == 0)
268 trace_flushroot(J, T);
269 lj_gdbjit_deltrace(J, T);
270 T->traceno = 0;
271 setgcrefnull(J->trace[i]);
272 }
273 }
274 J->cur.traceno = 0;
275 J->freetrace = 0;
276 /* Clear penalty cache. */
277 memset(J->penalty, 0, sizeof(J->penalty));
278 /* Free the whole machine code and invalidate all exit stub groups. */
279 lj_mcode_free(J);
280 memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup));
281 lj_vmevent_send(L, TRACE,
282 setstrV(L, L->top++, lj_str_newlit(L, "flush"));
283 );
284 return 0;
285}
286
287/* Initialize JIT compiler state. */
288void lj_trace_initstate(global_State *g)
289{
290 jit_State *J = G2J(g);
291 TValue *tv;
292 /* Initialize SIMD constants. */
293 tv = LJ_KSIMD(J, LJ_KSIMD_ABS);
294 tv[0].u64 = U64x(7fffffff,ffffffff);
295 tv[1].u64 = U64x(7fffffff,ffffffff);
296 tv = LJ_KSIMD(J, LJ_KSIMD_NEG);
297 tv[0].u64 = U64x(80000000,00000000);
298 tv[1].u64 = U64x(80000000,00000000);
299}
300
301/* Free everything associated with the JIT compiler state. */
302void lj_trace_freestate(global_State *g)
303{
304 jit_State *J = G2J(g);
305#ifdef LUA_USE_ASSERT
306 { /* This assumes all traces have already been freed. */
307 ptrdiff_t i;
308 for (i = 1; i < (ptrdiff_t)J->sizetrace; i++)
309 lua_assert(i == (ptrdiff_t)J->cur.traceno || traceref(J, i) == NULL);
310 }
311#endif
312 lj_mcode_free(J);
313 lj_ir_k64_freeall(J);
314 lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry);
315 lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot);
316 lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns);
317 lj_mem_freevec(g, J->trace, J->sizetrace, GCRef);
318}
319
320/* -- Penalties and blacklisting ------------------------------------------ */
321
322/* Blacklist a bytecode instruction. */
323static void blacklist_pc(GCproto *pt, BCIns *pc)
324{
325 setbc_op(pc, (int)bc_op(*pc)+(int)BC_ILOOP-(int)BC_LOOP);
326 pt->flags |= PROTO_ILOOP;
327}
328
329/* Penalize a bytecode instruction. */
330static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e)
331{
332 uint32_t i, val = PENALTY_MIN;
333 for (i = 0; i < PENALTY_SLOTS; i++)
334 if (mref(J->penalty[i].pc, const BCIns) == pc) { /* Cache slot found? */
335 /* First try to bump its hotcount several times. */
336 val = ((uint32_t)J->penalty[i].val << 1) +
337 LJ_PRNG_BITS(J, PENALTY_RNDBITS);
338 if (val > PENALTY_MAX) {
339 blacklist_pc(pt, pc); /* Blacklist it, if that didn't help. */
340 return;
341 }
342 goto setpenalty;
343 }
344 /* Assign a new penalty cache slot. */
345 i = J->penaltyslot;
346 J->penaltyslot = (J->penaltyslot + 1) & (PENALTY_SLOTS-1);
347 setmref(J->penalty[i].pc, pc);
348setpenalty:
349 J->penalty[i].val = (uint16_t)val;
350 J->penalty[i].reason = e;
351 hotcount_set(J2GG(J), pc+1, val);
352}
353
354/* -- Trace compiler state machine ---------------------------------------- */
355
356/* Start tracing. */
357static void trace_start(jit_State *J)
358{
359 lua_State *L;
360 TraceNo traceno;
361
362 if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
363 if (J->parent == 0) {
364 /* Lazy bytecode patching to disable hotcount events. */
365 lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL ||
366 bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF);
367 setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP);
368 J->pt->flags |= PROTO_ILOOP;
369 }
370 J->state = LJ_TRACE_IDLE; /* Silently ignored. */
371 return;
372 }
373
374 /* Get a new trace number. */
375 traceno = trace_findfree(J);
376 if (LJ_UNLIKELY(traceno == 0)) { /* No free trace? */
377 lua_assert((J2G(J)->hookmask & HOOK_GC) == 0);
378 lj_trace_flushall(J->L);
379 J->state = LJ_TRACE_IDLE; /* Silently ignored. */
380 return;
381 }
382 setgcrefp(J->trace[traceno], &J->cur);
383
384 /* Setup enough of the current trace to be able to send the vmevent. */
385 memset(&J->cur, 0, sizeof(GCtrace));
386 J->cur.traceno = traceno;
387 J->cur.nins = J->cur.nk = REF_BASE;
388 J->cur.ir = J->irbuf;
389 J->cur.snap = J->snapbuf;
390 J->cur.snapmap = J->snapmapbuf;
391 J->mergesnap = 0;
392 J->needsnap = 0;
393 J->bcskip = 0;
394 J->guardemit.irt = 0;
395 J->postproc = LJ_POST_NONE;
396 lj_resetsplit(J);
397 setgcref(J->cur.startpt, obj2gco(J->pt));
398
399 L = J->L;
400 lj_vmevent_send(L, TRACE,
401 setstrV(L, L->top++, lj_str_newlit(L, "start"));
402 setintV(L->top++, traceno);
403 setfuncV(L, L->top++, J->fn);
404 setintV(L->top++, proto_bcpos(J->pt, J->pc));
405 if (J->parent) {
406 setintV(L->top++, J->parent);
407 setintV(L->top++, J->exitno);
408 }
409 );
410 lj_record_setup(J);
411}
412
413/* Stop tracing. */
414static void trace_stop(jit_State *J)
415{
416 BCIns *pc = mref(J->cur.startpc, BCIns);
417 BCOp op = bc_op(J->cur.startins);
418 GCproto *pt = &gcref(J->cur.startpt)->pt;
419 TraceNo traceno = J->cur.traceno;
420 lua_State *L;
421
422 switch (op) {
423 case BC_FORL:
424 setbc_op(pc+bc_j(J->cur.startins), BC_JFORI); /* Patch FORI, too. */
425 /* fallthrough */
426 case BC_LOOP:
427 case BC_ITERL:
428 case BC_FUNCF:
429 /* Patch bytecode of starting instruction in root trace. */
430 setbc_op(pc, (int)op+(int)BC_JLOOP-(int)BC_LOOP);
431 setbc_d(pc, traceno);
432 addroot:
433 /* Add to root trace chain in prototype. */
434 J->cur.nextroot = pt->trace;
435 pt->trace = (TraceNo1)traceno;
436 break;
437 case BC_RET:
438 case BC_RET0:
439 case BC_RET1:
440 *pc = BCINS_AD(BC_JLOOP, J->cur.snap[0].nslots, traceno);
441 goto addroot;
442 case BC_JMP:
443 /* Patch exit branch in parent to side trace entry. */
444 lua_assert(J->parent != 0 && J->cur.root != 0);
445 lj_asm_patchexit(J, traceref(J, J->parent), J->exitno, J->cur.mcode);
446 /* Avoid compiling a side trace twice (stack resizing uses parent exit). */
447 traceref(J, J->parent)->snap[J->exitno].count = SNAPCOUNT_DONE;
448 /* Add to side trace chain in root trace. */
449 {
450 GCtrace *root = traceref(J, J->cur.root);
451 root->nchild++;
452 J->cur.nextside = root->nextside;
453 root->nextside = (TraceNo1)traceno;
454 }
455 break;
456 default:
457 lua_assert(0);
458 break;
459 }
460
461 /* Commit new mcode only after all patching is done. */
462 lj_mcode_commit(J, J->cur.mcode);
463 J->postproc = LJ_POST_NONE;
464 trace_save(J);
465
466 L = J->L;
467 lj_vmevent_send(L, TRACE,
468 setstrV(L, L->top++, lj_str_newlit(L, "stop"));
469 setintV(L->top++, traceno);
470 );
471}
472
473/* Start a new root trace for down-recursion. */
474static int trace_downrec(jit_State *J)
475{
476 /* Restart recording at the return instruction. */
477 lua_assert(J->pt != NULL);
478 lua_assert(bc_isret(bc_op(*J->pc)));
479 if (bc_op(*J->pc) == BC_RETM)
480 return 0; /* NYI: down-recursion with RETM. */
481 J->parent = 0;
482 J->exitno = 0;
483 J->state = LJ_TRACE_RECORD;
484 trace_start(J);
485 return 1;
486}
487
488/* Abort tracing. */
489static int trace_abort(jit_State *J)
490{
491 lua_State *L = J->L;
492 TraceError e = LJ_TRERR_RECERR;
493 TraceNo traceno;
494
495 J->postproc = LJ_POST_NONE;
496 lj_mcode_abort(J);
497 if (tvisnumber(L->top-1))
498 e = (TraceError)numberVint(L->top-1);
499 if (e == LJ_TRERR_MCODELM) {
500 L->top--; /* Remove error object */
501 J->state = LJ_TRACE_ASM;
502 return 1; /* Retry ASM with new MCode area. */
503 }
504 /* Penalize or blacklist starting bytecode instruction. */
505 if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins)))
506 penalty_pc(J, &gcref(J->cur.startpt)->pt, mref(J->cur.startpc, BCIns), e);
507
508 /* Is there anything to abort? */
509 traceno = J->cur.traceno;
510 if (traceno) {
511 ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
512 J->cur.link = 0;
513 J->cur.linktype = LJ_TRLINK_NONE;
514 lj_vmevent_send(L, TRACE,
515 TValue *frame;
516 const BCIns *pc;
517 GCfunc *fn;
518 setstrV(L, L->top++, lj_str_newlit(L, "abort"));
519 setintV(L->top++, traceno);
520 /* Find original Lua function call to generate a better error message. */
521 frame = J->L->base-1;
522 pc = J->pc;
523 while (!isluafunc(frame_func(frame))) {
524 pc = (frame_iscont(frame) ? frame_contpc(frame) : frame_pc(frame)) - 1;
525 frame = frame_prev(frame);
526 }
527 fn = frame_func(frame);
528 setfuncV(L, L->top++, fn);
529 setintV(L->top++, proto_bcpos(funcproto(fn), pc));
530 copyTV(L, L->top++, restorestack(L, errobj));
531 copyTV(L, L->top++, &J->errinfo);
532 );
533 /* Drop aborted trace after the vmevent (which may still access it). */
534 setgcrefnull(J->trace[traceno]);
535 if (traceno < J->freetrace)
536 J->freetrace = traceno;
537 J->cur.traceno = 0;
538 }
539 L->top--; /* Remove error object */
540 if (e == LJ_TRERR_DOWNREC)
541 return trace_downrec(J);
542 else if (e == LJ_TRERR_MCODEAL)
543 lj_trace_flushall(L);
544 return 0;
545}
546
547/* Perform pending re-patch of a bytecode instruction. */
548static LJ_AINLINE void trace_pendpatch(jit_State *J, int force)
549{
550 if (LJ_UNLIKELY(J->patchpc)) {
551 if (force || J->bcskip == 0) {
552 *J->patchpc = J->patchins;
553 J->patchpc = NULL;
554 } else {
555 J->bcskip = 0;
556 }
557 }
558}
559
560/* State machine for the trace compiler. Protected callback. */
561static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
562{
563 jit_State *J = (jit_State *)ud;
564 UNUSED(dummy);
565 do {
566 retry:
567 switch (J->state) {
568 case LJ_TRACE_START:
569 J->state = LJ_TRACE_RECORD; /* trace_start() may change state. */
570 trace_start(J);
571 lj_dispatch_update(J2G(J));
572 break;
573
574 case LJ_TRACE_RECORD:
575 trace_pendpatch(J, 0);
576 setvmstate(J2G(J), RECORD);
577 lj_vmevent_send_(L, RECORD,
578 /* Save/restore tmptv state for trace recorder. */
579 TValue savetv = J2G(J)->tmptv;
580 TValue savetv2 = J2G(J)->tmptv2;
581 setintV(L->top++, J->cur.traceno);
582 setfuncV(L, L->top++, J->fn);
583 setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1);
584 setintV(L->top++, J->framedepth);
585 ,
586 J2G(J)->tmptv = savetv;
587 J2G(J)->tmptv2 = savetv2;
588 );
589 lj_record_ins(J);
590 break;
591
592 case LJ_TRACE_END:
593 trace_pendpatch(J, 1);
594 J->loopref = 0;
595 if ((J->flags & JIT_F_OPT_LOOP) &&
596 J->cur.link == J->cur.traceno && J->framedepth + J->retdepth == 0) {
597 setvmstate(J2G(J), OPT);
598 lj_opt_dce(J);
599 if (lj_opt_loop(J)) { /* Loop optimization failed? */
600 J->cur.link = 0;
601 J->cur.linktype = LJ_TRLINK_NONE;
602 J->loopref = J->cur.nins;
603 J->state = LJ_TRACE_RECORD; /* Try to continue recording. */
604 break;
605 }
606 J->loopref = J->chain[IR_LOOP]; /* Needed by assembler. */
607 }
608 lj_opt_split(J);
609 J->state = LJ_TRACE_ASM;
610 break;
611
612 case LJ_TRACE_ASM:
613 setvmstate(J2G(J), ASM);
614 lj_asm_trace(J, &J->cur);
615 trace_stop(J);
616 setvmstate(J2G(J), INTERP);
617 J->state = LJ_TRACE_IDLE;
618 lj_dispatch_update(J2G(J));
619 return NULL;
620
621 default: /* Trace aborted asynchronously. */
622 setintV(L->top++, (int32_t)LJ_TRERR_RECERR);
623 /* fallthrough */
624 case LJ_TRACE_ERR:
625 trace_pendpatch(J, 1);
626 if (trace_abort(J))
627 goto retry;
628 setvmstate(J2G(J), INTERP);
629 J->state = LJ_TRACE_IDLE;
630 lj_dispatch_update(J2G(J));
631 return NULL;
632 }
633 } while (J->state > LJ_TRACE_RECORD);
634 return NULL;
635}
636
637/* -- Event handling ------------------------------------------------------ */
638
639/* A bytecode instruction is about to be executed. Record it. */
640void lj_trace_ins(jit_State *J, const BCIns *pc)
641{
642 /* Note: J->L must already be set. pc is the true bytecode PC here. */
643 J->pc = pc;
644 J->fn = curr_func(J->L);
645 J->pt = isluafunc(J->fn) ? funcproto(J->fn) : NULL;
646 while (lj_vm_cpcall(J->L, NULL, (void *)J, trace_state) != 0)
647 J->state = LJ_TRACE_ERR;
648}
649
650/* A hotcount triggered. Start recording a root trace. */
651void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc)
652{
653 /* Note: pc is the interpreter bytecode PC here. It's offset by 1. */
654 ERRNO_SAVE
655 /* Reset hotcount. */
656 hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]*HOTCOUNT_LOOP);
657 /* Only start a new trace if not recording or inside __gc call or vmevent. */
658 if (J->state == LJ_TRACE_IDLE &&
659 !(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
660 J->parent = 0; /* Root trace. */
661 J->exitno = 0;
662 J->state = LJ_TRACE_START;
663 lj_trace_ins(J, pc-1);
664 }
665 ERRNO_RESTORE
666}
667
668/* Check for a hot side exit. If yes, start recording a side trace. */
669static void trace_hotside(jit_State *J, const BCIns *pc)
670{
671 SnapShot *snap = &traceref(J, J->parent)->snap[J->exitno];
672 if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) &&
673 snap->count != SNAPCOUNT_DONE &&
674 ++snap->count >= J->param[JIT_P_hotexit]) {
675 lua_assert(J->state == LJ_TRACE_IDLE);
676 /* J->parent is non-zero for a side trace. */
677 J->state = LJ_TRACE_START;
678 lj_trace_ins(J, pc);
679 }
680}
681
682/* Tiny struct to pass data to protected call. */
683typedef struct ExitDataCP {
684 jit_State *J;
685 void *exptr; /* Pointer to exit state. */
686 const BCIns *pc; /* Restart interpreter at this PC. */
687} ExitDataCP;
688
689/* Need to protect lj_snap_restore because it may throw. */
690static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud)
691{
692 ExitDataCP *exd = (ExitDataCP *)ud;
693 cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
694 exd->pc = lj_snap_restore(exd->J, exd->exptr);
695 UNUSED(dummy);
696 return NULL;
697}
698
699#ifndef LUAJIT_DISABLE_VMEVENT
700/* Push all registers from exit state. */
701static void trace_exit_regs(lua_State *L, ExitState *ex)
702{
703 int32_t i;
704 setintV(L->top++, RID_NUM_GPR);
705 setintV(L->top++, RID_NUM_FPR);
706 for (i = 0; i < RID_NUM_GPR; i++) {
707 if (sizeof(ex->gpr[i]) == sizeof(int32_t))
708 setintV(L->top++, (int32_t)ex->gpr[i]);
709 else
710 setnumV(L->top++, (lua_Number)ex->gpr[i]);
711 }
712#if !LJ_SOFTFP
713 for (i = 0; i < RID_NUM_FPR; i++) {
714 setnumV(L->top, ex->fpr[i]);
715 if (LJ_UNLIKELY(tvisnan(L->top)))
716 setnanV(L->top);
717 L->top++;
718 }
719#endif
720}
721#endif
722
723#ifdef EXITSTATE_PCREG
724/* Determine trace number from pc of exit instruction. */
725static TraceNo trace_exit_find(jit_State *J, MCode *pc)
726{
727 TraceNo traceno;
728 for (traceno = 1; traceno < J->sizetrace; traceno++) {
729 GCtrace *T = traceref(J, traceno);
730 if (T && pc >= T->mcode && pc < (MCode *)((char *)T->mcode + T->szmcode))
731 return traceno;
732 }
733 lua_assert(0);
734 return 0;
735}
736#endif
737
738/* A trace exited. Restore interpreter state. */
739int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
740{
741 ERRNO_SAVE
742 lua_State *L = J->L;
743 ExitState *ex = (ExitState *)exptr;
744 ExitDataCP exd;
745 int errcode;
746 const BCIns *pc;
747 void *cf;
748 GCtrace *T;
749#ifdef EXITSTATE_PCREG
750 J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
751#endif
752 T = traceref(J, J->parent); UNUSED(T);
753#ifdef EXITSTATE_CHECKEXIT
754 if (J->exitno == T->nsnap) { /* Treat stack check like a parent exit. */
755 lua_assert(T->root != 0);
756 J->exitno = T->ir[REF_BASE].op2;
757 J->parent = T->ir[REF_BASE].op1;
758 T = traceref(J, J->parent);
759 }
760#endif
761 lua_assert(T != NULL && J->exitno < T->nsnap);
762 exd.J = J;
763 exd.exptr = exptr;
764 errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
765 if (errcode)
766 return -errcode; /* Return negated error code. */
767
768 lj_vmevent_send(L, TEXIT,
769 lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
770 setintV(L->top++, J->parent);
771 setintV(L->top++, J->exitno);
772 trace_exit_regs(L, ex);
773 );
774
775 pc = exd.pc;
776 cf = cframe_raw(L->cframe);
777 setcframe_pc(cf, pc);
778 if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize)
779 lj_gc_step(L); /* Exited because of GC: drive GC forward. */
780 else
781 trace_hotside(J, pc);
782 if (bc_op(*pc) == BC_JLOOP) {
783 BCIns *retpc = &traceref(J, bc_d(*pc))->startins;
784 if (bc_isret(bc_op(*retpc))) {
785 if (J->state == LJ_TRACE_RECORD) {
786 J->patchins = *pc;
787 J->patchpc = (BCIns *)pc;
788 *J->patchpc = *retpc;
789 J->bcskip = 1;
790 } else {
791 pc = retpc;
792 setcframe_pc(cf, pc);
793 }
794 }
795 }
796 /* Return MULTRES or 0. */
797 ERRNO_RESTORE
798 switch (bc_op(*pc)) {
799 case BC_CALLM: case BC_CALLMT:
800 return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc));
801 case BC_RETM:
802 return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc));
803 case BC_TSETM:
804 return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
805 default:
806 if (bc_op(*pc) >= BC_FUNCF)
807 return (int)((BCReg)(L->top - L->base) + 1);
808 return 0;
809 }
810}
811
812#endif
diff --git a/libraries/luajit-2.0/src/lj_trace.h b/libraries/luajit-2.0/src/lj_trace.h
new file mode 100644
index 0000000..25a456d
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_trace.h
@@ -0,0 +1,53 @@
1/*
2** Trace management.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_TRACE_H
7#define _LJ_TRACE_H
8
9#include "lj_obj.h"
10
11#if LJ_HASJIT
12#include "lj_jit.h"
13#include "lj_dispatch.h"
14
15/* Trace errors. */
16typedef enum {
17#define TREDEF(name, msg) LJ_TRERR_##name,
18#include "lj_traceerr.h"
19 LJ_TRERR__MAX
20} TraceError;
21
22LJ_FUNC_NORET void lj_trace_err(jit_State *J, TraceError e);
23LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e);
24
25/* Trace management. */
26LJ_FUNC void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T);
27LJ_FUNC void lj_trace_reenableproto(GCproto *pt);
28LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt);
29LJ_FUNC void lj_trace_flush(jit_State *J, TraceNo traceno);
30LJ_FUNC int lj_trace_flushall(lua_State *L);
31LJ_FUNC void lj_trace_initstate(global_State *g);
32LJ_FUNC void lj_trace_freestate(global_State *g);
33
34/* Event handling. */
35LJ_FUNC void lj_trace_ins(jit_State *J, const BCIns *pc);
36LJ_FUNCA void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc);
37LJ_FUNCA int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr);
38
39/* Signal asynchronous abort of trace or end of trace. */
40#define lj_trace_abort(g) (G2J(g)->state &= ~LJ_TRACE_ACTIVE)
41#define lj_trace_end(J) (J->state = LJ_TRACE_END)
42
43#else
44
45#define lj_trace_flushall(L) (UNUSED(L), 0)
46#define lj_trace_initstate(g) UNUSED(g)
47#define lj_trace_freestate(g) UNUSED(g)
48#define lj_trace_abort(g) UNUSED(g)
49#define lj_trace_end(J) UNUSED(J)
50
51#endif
52
53#endif
diff --git a/libraries/luajit-2.0/src/lj_traceerr.h b/libraries/luajit-2.0/src/lj_traceerr.h
new file mode 100644
index 0000000..756330e
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_traceerr.h
@@ -0,0 +1,61 @@
1/*
2** Trace compiler error messages.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/* This file may be included multiple times with different TREDEF macros. */
7
8/* Recording. */
9TREDEF(RECERR, "error thrown or hook called during recording")
10TREDEF(TRACEOV, "trace too long")
11TREDEF(STACKOV, "trace too deep")
12TREDEF(SNAPOV, "too many snapshots")
13TREDEF(BLACKL, "blacklisted")
14TREDEF(NYIBC, "NYI: bytecode %d")
15
16/* Recording loop ops. */
17TREDEF(LLEAVE, "leaving loop in root trace")
18TREDEF(LINNER, "inner loop in root trace")
19TREDEF(LUNROLL, "loop unroll limit reached")
20
21/* Recording calls/returns. */
22TREDEF(BADTYPE, "bad argument type")
23TREDEF(CJITOFF, "call to JIT-disabled function")
24TREDEF(CUNROLL, "call unroll limit reached")
25TREDEF(DOWNREC, "down-recursion, restarting")
26TREDEF(NYICF, "NYI: C function %p")
27TREDEF(NYIFF, "NYI: FastFunc %s")
28TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s")
29TREDEF(NYIRETL, "NYI: return to lower frame")
30
31/* Recording indexed load/store. */
32TREDEF(STORENN, "store with nil or NaN key")
33TREDEF(NOMM, "missing metamethod")
34TREDEF(IDXLOOP, "looping index lookup")
35TREDEF(NYITMIX, "NYI: mixed sparse/dense table")
36
37/* Recording C data operations. */
38TREDEF(NOCACHE, "symbol not in cache")
39TREDEF(NYICONV, "NYI: unsupported C type conversion")
40TREDEF(NYICALL, "NYI: unsupported C function type")
41
42/* Optimizations. */
43TREDEF(GFAIL, "guard would always fail")
44TREDEF(PHIOV, "too many PHIs")
45TREDEF(TYPEINS, "persistent type instability")
46
47/* Assembler. */
48TREDEF(MCODEAL, "failed to allocate mcode memory")
49TREDEF(MCODEOV, "machine code too long")
50TREDEF(MCODELM, "hit mcode limit (retrying)")
51TREDEF(SPILLOV, "too many spill slots")
52TREDEF(BADRA, "inconsistent register allocation")
53TREDEF(NYIIR, "NYI: cannot assemble IR instruction %d")
54TREDEF(NYIPHI, "NYI: PHI shuffling too complex")
55TREDEF(NYICOAL, "NYI: register coalescing too complex")
56
57#undef TREDEF
58
59/* Detecting unused error messages:
60 awk -F, '/^TREDEF/ { gsub(/TREDEF./, ""); printf "grep -q LJ_TRERR_%s *.[ch] || echo %s\n", $1, $1}' lj_traceerr.h | sh
61*/
diff --git a/libraries/luajit-2.0/src/lj_udata.c b/libraries/luajit-2.0/src/lj_udata.c
new file mode 100644
index 0000000..869f31f
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_udata.c
@@ -0,0 +1,34 @@
1/*
2** Userdata handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_udata_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#include "lj_gc.h"
11#include "lj_udata.h"
12
13GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env)
14{
15 GCudata *ud = lj_mem_newt(L, sizeof(GCudata) + sz, GCudata);
16 global_State *g = G(L);
17 newwhite(g, ud); /* Not finalized. */
18 ud->gct = ~LJ_TUDATA;
19 ud->udtype = UDTYPE_USERDATA;
20 ud->len = sz;
21 /* NOBARRIER: The GCudata is new (marked white). */
22 setgcrefnull(ud->metatable);
23 setgcref(ud->env, obj2gco(env));
24 /* Chain to userdata list (after main thread). */
25 setgcrefr(ud->nextgc, mainthread(g)->nextgc);
26 setgcref(mainthread(g)->nextgc, obj2gco(ud));
27 return ud;
28}
29
30void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud)
31{
32 lj_mem_free(g, ud, sizeudata(ud));
33}
34
diff --git a/libraries/luajit-2.0/src/lj_udata.h b/libraries/luajit-2.0/src/lj_udata.h
new file mode 100644
index 0000000..952c748
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_udata.h
@@ -0,0 +1,14 @@
1/*
2** Userdata handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_UDATA_H
7#define _LJ_UDATA_H
8
9#include "lj_obj.h"
10
11LJ_FUNC GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env);
12LJ_FUNC void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud);
13
14#endif
diff --git a/libraries/luajit-2.0/src/lj_vm.h b/libraries/luajit-2.0/src/lj_vm.h
new file mode 100644
index 0000000..da940b9
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_vm.h
@@ -0,0 +1,102 @@
1/*
2** Assembler VM interface definitions.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_VM_H
7#define _LJ_VM_H
8
9#include "lj_obj.h"
10
11/* Entry points for ASM parts of VM. */
12LJ_ASMF void lj_vm_call(lua_State *L, TValue *base, int nres1);
13LJ_ASMF int lj_vm_pcall(lua_State *L, TValue *base, int nres1, ptrdiff_t ef);
14typedef TValue *(*lua_CPFunction)(lua_State *L, lua_CFunction func, void *ud);
15LJ_ASMF int lj_vm_cpcall(lua_State *L, lua_CFunction func, void *ud,
16 lua_CPFunction cp);
17LJ_ASMF int lj_vm_resume(lua_State *L, TValue *base, int nres1, ptrdiff_t ef);
18LJ_ASMF_NORET void LJ_FASTCALL lj_vm_unwind_c(void *cframe, int errcode);
19LJ_ASMF_NORET void LJ_FASTCALL lj_vm_unwind_ff(void *cframe);
20LJ_ASMF void lj_vm_unwind_c_eh(void);
21LJ_ASMF void lj_vm_unwind_ff_eh(void);
22#if LJ_TARGET_X86ORX64
23LJ_ASMF void lj_vm_unwind_rethrow(void);
24#endif
25
26/* Miscellaneous functions. */
27#if LJ_TARGET_X86ORX64
28LJ_ASMF int lj_vm_cpuid(uint32_t f, uint32_t res[4]);
29#endif
30LJ_ASMF double lj_vm_foldarith(double x, double y, int op);
31#if LJ_HASJIT
32LJ_ASMF double lj_vm_foldfpm(double x, int op);
33#endif
34#if !LJ_ARCH_HASFPU
35/* Declared in lj_obj.h: LJ_ASMF int32_t lj_vm_tobit(double x); */
36#endif
37
38/* Dispatch targets for recording and hooks. */
39LJ_ASMF void lj_vm_record(void);
40LJ_ASMF void lj_vm_inshook(void);
41LJ_ASMF void lj_vm_rethook(void);
42LJ_ASMF void lj_vm_callhook(void);
43
44/* Trace exit handling. */
45LJ_ASMF void lj_vm_exit_handler(void);
46LJ_ASMF void lj_vm_exit_interp(void);
47
48/* Internal math helper functions. */
49#if LJ_TARGET_X86ORX64
50#define lj_vm_floor(x) floor(x)
51#define lj_vm_ceil(x) ceil(x)
52#else
53LJ_ASMF double lj_vm_floor(double);
54LJ_ASMF double lj_vm_ceil(double);
55#endif
56
57#if LJ_HASJIT
58#if LJ_TARGET_X86ORX64
59LJ_ASMF void lj_vm_floor_sse(void);
60LJ_ASMF void lj_vm_ceil_sse(void);
61LJ_ASMF void lj_vm_trunc_sse(void);
62LJ_ASMF void lj_vm_exp_x87(void);
63LJ_ASMF void lj_vm_exp2_x87(void);
64LJ_ASMF void lj_vm_pow_sse(void);
65LJ_ASMF void lj_vm_powi_sse(void);
66#else
67LJ_ASMF double lj_vm_trunc(double);
68LJ_ASMF double lj_vm_powi(double, int32_t);
69#ifdef LUAJIT_NO_LOG2
70LJ_ASMF double lj_vm_log2(double);
71#else
72#define lj_vm_log2 log2
73#endif
74#ifdef LUAJIT_NO_EXP2
75LJ_ASMF double lj_vm_exp2(double);
76#else
77#define lj_vm_exp2 exp2
78#endif
79#endif
80LJ_ASMF int32_t LJ_FASTCALL lj_vm_modi(int32_t, int32_t);
81#if LJ_HASFFI
82LJ_ASMF int lj_vm_errno(void);
83#endif
84#endif
85
86/* Continuations for metamethods. */
87LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */
88LJ_ASMF void lj_cont_ra(void); /* Store result in RA from instruction. */
89LJ_ASMF void lj_cont_nop(void); /* Do nothing, just continue execution. */
90LJ_ASMF void lj_cont_condt(void); /* Branch if result is true. */
91LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */
92LJ_ASMF void lj_cont_hook(void); /* Continue from hook yield. */
93
94enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */
95
96/* Start of the ASM code. */
97LJ_ASMF char lj_vm_asm_begin[];
98
99/* Bytecode offsets are relative to lj_vm_asm_begin. */
100#define makeasmfunc(ofs) ((ASMFunction)(lj_vm_asm_begin + (ofs)))
101
102#endif
diff --git a/libraries/luajit-2.0/src/lj_vmevent.c b/libraries/luajit-2.0/src/lj_vmevent.c
new file mode 100644
index 0000000..67cc6dc
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_vmevent.c
@@ -0,0 +1,56 @@
1/*
2** VM event handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include <stdio.h>
7
8#define lj_vmevent_c
9#define LUA_CORE
10
11#include "lj_obj.h"
12#include "lj_str.h"
13#include "lj_tab.h"
14#include "lj_state.h"
15#include "lj_dispatch.h"
16#include "lj_vm.h"
17#include "lj_vmevent.h"
18
19ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev)
20{
21 global_State *g = G(L);
22 GCstr *s = lj_str_newlit(L, LJ_VMEVENTS_REGKEY);
23 cTValue *tv = lj_tab_getstr(tabV(registry(L)), s);
24 if (tvistab(tv)) {
25 int hash = VMEVENT_HASH(ev);
26 tv = lj_tab_getint(tabV(tv), hash);
27 if (tv && tvisfunc(tv)) {
28 lj_state_checkstack(L, LUA_MINSTACK);
29 setfuncV(L, L->top++, funcV(tv));
30 return savestack(L, L->top);
31 }
32 }
33 g->vmevmask &= ~VMEVENT_MASK(ev); /* No handler: cache this fact. */
34 return 0;
35}
36
37void lj_vmevent_call(lua_State *L, ptrdiff_t argbase)
38{
39 global_State *g = G(L);
40 uint8_t oldmask = g->vmevmask;
41 uint8_t oldh = hook_save(g);
42 int status;
43 g->vmevmask = 0; /* Disable all events. */
44 hook_vmevent(g);
45 status = lj_vm_pcall(L, restorestack(L, argbase), 0+1, 0);
46 if (LJ_UNLIKELY(status)) {
47 /* Really shouldn't use stderr here, but where else to complain? */
48 L->top--;
49 fprintf(stderr, "VM handler failed: %s\n",
50 tvisstr(L->top) ? strVdata(L->top) : "?");
51 }
52 hook_restore(g, oldh);
53 if (g->vmevmask != VMEVENT_NOCACHE)
54 g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */
55}
56
diff --git a/libraries/luajit-2.0/src/lj_vmevent.h b/libraries/luajit-2.0/src/lj_vmevent.h
new file mode 100644
index 0000000..8a0822f
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_vmevent.h
@@ -0,0 +1,59 @@
1/*
2** VM event handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_VMEVENT_H
7#define _LJ_VMEVENT_H
8
9#include "lj_obj.h"
10
11/* Registry key for VM event handler table. */
12#define LJ_VMEVENTS_REGKEY "_VMEVENTS"
13#define LJ_VMEVENTS_HSIZE 4
14
15#define VMEVENT_MASK(ev) ((uint8_t)1 << ((int)(ev) & 7))
16#define VMEVENT_HASH(ev) ((int)(ev) & ~7)
17#define VMEVENT_HASHIDX(h) ((int)(h) << 3)
18#define VMEVENT_NOCACHE 255
19
20#define VMEVENT_DEF(name, hash) \
21 LJ_VMEVENT_##name##_, \
22 LJ_VMEVENT_##name = ((LJ_VMEVENT_##name##_) & 7)|((hash) << 3)
23
24/* VM event IDs. */
25typedef enum {
26 VMEVENT_DEF(BC, 0x00003883),
27 VMEVENT_DEF(TRACE, 0xb2d91467),
28 VMEVENT_DEF(RECORD, 0x9284bf4f),
29 VMEVENT_DEF(TEXIT, 0xb29df2b0),
30 LJ_VMEVENT__MAX
31} VMEvent;
32
33#ifdef LUAJIT_DISABLE_VMEVENT
34#define lj_vmevent_send(L, ev, args) UNUSED(L)
35#define lj_vmevent_send_(L, ev, args, post) UNUSED(L)
36#else
37#define lj_vmevent_send(L, ev, args) \
38 if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \
39 ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \
40 if (argbase) { \
41 args \
42 lj_vmevent_call(L, argbase); \
43 } \
44 }
45#define lj_vmevent_send_(L, ev, args, post) \
46 if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \
47 ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \
48 if (argbase) { \
49 args \
50 lj_vmevent_call(L, argbase); \
51 post \
52 } \
53 }
54
55LJ_FUNC ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev);
56LJ_FUNC void lj_vmevent_call(lua_State *L, ptrdiff_t argbase);
57#endif
58
59#endif
diff --git a/libraries/luajit-2.0/src/lj_vmmath.c b/libraries/luajit-2.0/src/lj_vmmath.c
new file mode 100644
index 0000000..8b17720
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_vmmath.c
@@ -0,0 +1,119 @@
1/*
2** Math helper functions for assembler VM.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_vmmath_c
7#define LUA_CORE
8
9#include <errno.h>
10#include <math.h>
11
12#include "lj_obj.h"
13#if LJ_HASJIT
14#include "lj_ir.h"
15#endif
16#include "lj_vm.h"
17
18/* -- Helper functions for generated machine code ------------------------- */
19
20#if LJ_TARGET_X86ORX64
21/* Wrapper functions to avoid linker issues on OSX. */
22LJ_FUNCA double lj_vm_sinh(double x) { return sinh(x); }
23LJ_FUNCA double lj_vm_cosh(double x) { return cosh(x); }
24LJ_FUNCA double lj_vm_tanh(double x) { return tanh(x); }
25#endif
26
27#if LJ_HASJIT
28
29#ifdef LUAJIT_NO_LOG2
30double lj_vm_log2(double a)
31{
32 return log(a) * 1.4426950408889634074;
33}
34#endif
35
36#ifdef LUAJIT_NO_EXP2
37double lj_vm_exp2(double a)
38{
39 return exp(a * 0.6931471805599453);
40}
41#endif
42
43#if !(LJ_TARGET_ARM || LJ_TARGET_PPC)
44int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b)
45{
46 uint32_t y, ua, ub;
47 lua_assert(b != 0); /* This must be checked before using this function. */
48 ua = a < 0 ? (uint32_t)-a : (uint32_t)a;
49 ub = b < 0 ? (uint32_t)-b : (uint32_t)b;
50 y = ua % ub;
51 if (y != 0 && (a^b) < 0) y = y - ub;
52 if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y;
53 return (int32_t)y;
54}
55#endif
56
57#if !LJ_TARGET_X86ORX64
58/* Unsigned x^k. */
59static double lj_vm_powui(double x, uint32_t k)
60{
61 double y;
62 lua_assert(k != 0);
63 for (; (k & 1) == 0; k >>= 1) x *= x;
64 y = x;
65 if ((k >>= 1) != 0) {
66 for (;;) {
67 x *= x;
68 if (k == 1) break;
69 if (k & 1) y *= x;
70 k >>= 1;
71 }
72 y *= x;
73 }
74 return y;
75}
76
77/* Signed x^k. */
78double lj_vm_powi(double x, int32_t k)
79{
80 if (k > 1)
81 return lj_vm_powui(x, (uint32_t)k);
82 else if (k == 1)
83 return x;
84 else if (k == 0)
85 return 1.0;
86 else
87 return 1.0 / lj_vm_powui(x, (uint32_t)-k);
88}
89
90/* Computes fpm(x) for extended math functions. */
91double lj_vm_foldfpm(double x, int fpm)
92{
93 switch (fpm) {
94 case IRFPM_FLOOR: return lj_vm_floor(x);
95 case IRFPM_CEIL: return lj_vm_ceil(x);
96 case IRFPM_TRUNC: return lj_vm_trunc(x);
97 case IRFPM_SQRT: return sqrt(x);
98 case IRFPM_EXP: return exp(x);
99 case IRFPM_EXP2: return lj_vm_exp2(x);
100 case IRFPM_LOG: return log(x);
101 case IRFPM_LOG2: return lj_vm_log2(x);
102 case IRFPM_LOG10: return log10(x);
103 case IRFPM_SIN: return sin(x);
104 case IRFPM_COS: return cos(x);
105 case IRFPM_TAN: return tan(x);
106 default: lua_assert(0);
107 }
108 return 0;
109}
110#endif
111
112#if LJ_HASFFI
113int lj_vm_errno(void)
114{
115 return errno;
116}
117#endif
118
119#endif
diff --git a/libraries/luajit-2.0/src/ljamalg.c b/libraries/luajit-2.0/src/ljamalg.c
new file mode 100644
index 0000000..17c4b65
--- /dev/null
+++ b/libraries/luajit-2.0/src/ljamalg.c
@@ -0,0 +1,90 @@
1/*
2** LuaJIT core and libraries amalgamation.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6/*
7+--------------------------------------------------------------------------+
8| WARNING: Compiling the amalgamation needs a lot of virtual memory |
9| (around 200 MB with GCC 4.x)! If you don't have enough physical memory |
10| your machine will start swapping to disk and the compile will not finish |
11| within a reasonable amount of time. |
12| So either compile on a bigger machine or use the non-amalgamated build. |
13+--------------------------------------------------------------------------+
14*/
15
16#define ljamalg_c
17#define LUA_CORE
18
19/* To get the mremap prototype. Must be defined before any system includes. */
20#if defined(__linux__) && !defined(_GNU_SOURCE)
21#define _GNU_SOURCE
22#endif
23
24#ifndef WINVER
25#define WINVER 0x0500
26#endif
27
28#include "lua.h"
29#include "lauxlib.h"
30
31#include "lj_gc.c"
32#include "lj_err.c"
33#include "lj_char.c"
34#include "lj_bc.c"
35#include "lj_obj.c"
36#include "lj_str.c"
37#include "lj_tab.c"
38#include "lj_func.c"
39#include "lj_udata.c"
40#include "lj_meta.c"
41#include "lj_debug.c"
42#include "lj_state.c"
43#include "lj_dispatch.c"
44#include "lj_vmevent.c"
45#include "lj_vmmath.c"
46#include "lj_api.c"
47#include "lj_lex.c"
48#include "lj_parse.c"
49#include "lj_bcread.c"
50#include "lj_bcwrite.c"
51#include "lj_ctype.c"
52#include "lj_cdata.c"
53#include "lj_cconv.c"
54#include "lj_ccall.c"
55#include "lj_ccallback.c"
56#include "lj_carith.c"
57#include "lj_clib.c"
58#include "lj_cparse.c"
59#include "lj_lib.c"
60#include "lj_ir.c"
61#include "lj_opt_mem.c"
62#include "lj_opt_fold.c"
63#include "lj_opt_narrow.c"
64#include "lj_opt_dce.c"
65#include "lj_opt_loop.c"
66#include "lj_opt_split.c"
67#include "lj_mcode.c"
68#include "lj_snap.c"
69#include "lj_record.c"
70#include "lj_crecord.c"
71#include "lj_ffrecord.c"
72#include "lj_asm.c"
73#include "lj_trace.c"
74#include "lj_gdbjit.c"
75#include "lj_alloc.c"
76
77#include "lib_aux.c"
78#include "lib_base.c"
79#include "lib_math.c"
80#include "lib_string.c"
81#include "lib_table.c"
82#include "lib_io.c"
83#include "lib_os.c"
84#include "lib_package.c"
85#include "lib_debug.c"
86#include "lib_bit.c"
87#include "lib_jit.c"
88#include "lib_ffi.c"
89#include "lib_init.c"
90
diff --git a/libraries/luajit-2.0/src/lua.h b/libraries/luajit-2.0/src/lua.h
new file mode 100644
index 0000000..0e98b37
--- /dev/null
+++ b/libraries/luajit-2.0/src/lua.h
@@ -0,0 +1,388 @@
1/*
2** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
3** Lua - An Extensible Extension Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file
6*/
7
8
9#ifndef lua_h
10#define lua_h
11
12#include <stdarg.h>
13#include <stddef.h>
14
15
16#include "luaconf.h"
17
18
19#define LUA_VERSION "Lua 5.1"
20#define LUA_RELEASE "Lua 5.1.4"
21#define LUA_VERSION_NUM 501
22#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
23#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
24
25
26/* mark for precompiled code (`<esc>Lua') */
27#define LUA_SIGNATURE "\033Lua"
28
29/* option for multiple returns in `lua_pcall' and `lua_call' */
30#define LUA_MULTRET (-1)
31
32
33/*
34** pseudo-indices
35*/
36#define LUA_REGISTRYINDEX (-10000)
37#define LUA_ENVIRONINDEX (-10001)
38#define LUA_GLOBALSINDEX (-10002)
39#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
40
41
42/* thread status; 0 is OK */
43#define LUA_YIELD 1
44#define LUA_ERRRUN 2
45#define LUA_ERRSYNTAX 3
46#define LUA_ERRMEM 4
47#define LUA_ERRERR 5
48
49
50typedef struct lua_State lua_State;
51
52typedef int (*lua_CFunction) (lua_State *L);
53
54
55/*
56** functions that read/write blocks when loading/dumping Lua chunks
57*/
58typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
59
60typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
61
62
63/*
64** prototype for memory-allocation functions
65*/
66typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
67
68
69/*
70** basic types
71*/
72#define LUA_TNONE (-1)
73
74#define LUA_TNIL 0
75#define LUA_TBOOLEAN 1
76#define LUA_TLIGHTUSERDATA 2
77#define LUA_TNUMBER 3
78#define LUA_TSTRING 4
79#define LUA_TTABLE 5
80#define LUA_TFUNCTION 6
81#define LUA_TUSERDATA 7
82#define LUA_TTHREAD 8
83
84
85
86/* minimum Lua stack available to a C function */
87#define LUA_MINSTACK 20
88
89
90/*
91** generic extra include file
92*/
93#if defined(LUA_USER_H)
94#include LUA_USER_H
95#endif
96
97
98/* type of numbers in Lua */
99typedef LUA_NUMBER lua_Number;
100
101
102/* type for integer functions */
103typedef LUA_INTEGER lua_Integer;
104
105
106
107/*
108** state manipulation
109*/
110LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
111LUA_API void (lua_close) (lua_State *L);
112LUA_API lua_State *(lua_newthread) (lua_State *L);
113
114LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
115
116
117/*
118** basic stack manipulation
119*/
120LUA_API int (lua_gettop) (lua_State *L);
121LUA_API void (lua_settop) (lua_State *L, int idx);
122LUA_API void (lua_pushvalue) (lua_State *L, int idx);
123LUA_API void (lua_remove) (lua_State *L, int idx);
124LUA_API void (lua_insert) (lua_State *L, int idx);
125LUA_API void (lua_replace) (lua_State *L, int idx);
126LUA_API int (lua_checkstack) (lua_State *L, int sz);
127
128LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
129
130
131/*
132** access functions (stack -> C)
133*/
134
135LUA_API int (lua_isnumber) (lua_State *L, int idx);
136LUA_API int (lua_isstring) (lua_State *L, int idx);
137LUA_API int (lua_iscfunction) (lua_State *L, int idx);
138LUA_API int (lua_isuserdata) (lua_State *L, int idx);
139LUA_API int (lua_type) (lua_State *L, int idx);
140LUA_API const char *(lua_typename) (lua_State *L, int tp);
141
142LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
143LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
144LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
145
146LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
147LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
148LUA_API int (lua_toboolean) (lua_State *L, int idx);
149LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
150LUA_API size_t (lua_objlen) (lua_State *L, int idx);
151LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
152LUA_API void *(lua_touserdata) (lua_State *L, int idx);
153LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
154LUA_API const void *(lua_topointer) (lua_State *L, int idx);
155
156
157/*
158** push functions (C -> stack)
159*/
160LUA_API void (lua_pushnil) (lua_State *L);
161LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
162LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
163LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
164LUA_API void (lua_pushstring) (lua_State *L, const char *s);
165LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
166 va_list argp);
167LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
168LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
169LUA_API void (lua_pushboolean) (lua_State *L, int b);
170LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
171LUA_API int (lua_pushthread) (lua_State *L);
172
173
174/*
175** get functions (Lua -> stack)
176*/
177LUA_API void (lua_gettable) (lua_State *L, int idx);
178LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
179LUA_API void (lua_rawget) (lua_State *L, int idx);
180LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
181LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
182LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
183LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
184LUA_API void (lua_getfenv) (lua_State *L, int idx);
185
186
187/*
188** set functions (stack -> Lua)
189*/
190LUA_API void (lua_settable) (lua_State *L, int idx);
191LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
192LUA_API void (lua_rawset) (lua_State *L, int idx);
193LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
194LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
195LUA_API int (lua_setfenv) (lua_State *L, int idx);
196
197
198/*
199** `load' and `call' functions (load and run Lua code)
200*/
201LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
202LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
203LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
204LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
205 const char *chunkname);
206
207LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
208
209
210/*
211** coroutine functions
212*/
213LUA_API int (lua_yield) (lua_State *L, int nresults);
214LUA_API int (lua_resume) (lua_State *L, int narg);
215LUA_API int (lua_status) (lua_State *L);
216
217/*
218** garbage-collection function and options
219*/
220
221#define LUA_GCSTOP 0
222#define LUA_GCRESTART 1
223#define LUA_GCCOLLECT 2
224#define LUA_GCCOUNT 3
225#define LUA_GCCOUNTB 4
226#define LUA_GCSTEP 5
227#define LUA_GCSETPAUSE 6
228#define LUA_GCSETSTEPMUL 7
229
230LUA_API int (lua_gc) (lua_State *L, int what, int data);
231
232
233/*
234** miscellaneous functions
235*/
236
237LUA_API int (lua_error) (lua_State *L);
238
239LUA_API int (lua_next) (lua_State *L, int idx);
240
241LUA_API void (lua_concat) (lua_State *L, int n);
242
243LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
244LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
245
246
247
248/*
249** ===============================================================
250** some useful macros
251** ===============================================================
252*/
253
254#define lua_pop(L,n) lua_settop(L, -(n)-1)
255
256#define lua_newtable(L) lua_createtable(L, 0, 0)
257
258#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
259
260#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
261
262#define lua_strlen(L,i) lua_objlen(L, (i))
263
264#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
265#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
266#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
267#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
268#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
269#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
270#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
271#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
272
273#define lua_pushliteral(L, s) \
274 lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
275
276#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
277#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
278
279#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
280
281
282
283/*
284** compatibility macros and functions
285*/
286
287#define lua_open() luaL_newstate()
288
289#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
290
291#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
292
293#define lua_Chunkreader lua_Reader
294#define lua_Chunkwriter lua_Writer
295
296
297/* hack */
298LUA_API void lua_setlevel (lua_State *from, lua_State *to);
299
300
301/*
302** {======================================================================
303** Debug API
304** =======================================================================
305*/
306
307
308/*
309** Event codes
310*/
311#define LUA_HOOKCALL 0
312#define LUA_HOOKRET 1
313#define LUA_HOOKLINE 2
314#define LUA_HOOKCOUNT 3
315#define LUA_HOOKTAILRET 4
316
317
318/*
319** Event masks
320*/
321#define LUA_MASKCALL (1 << LUA_HOOKCALL)
322#define LUA_MASKRET (1 << LUA_HOOKRET)
323#define LUA_MASKLINE (1 << LUA_HOOKLINE)
324#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
325
326typedef struct lua_Debug lua_Debug; /* activation record */
327
328
329/* Functions to be called by the debuger in specific events */
330typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
331
332
333LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
334LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
335LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
336LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
337LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
338LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
339
340LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
341LUA_API lua_Hook lua_gethook (lua_State *L);
342LUA_API int lua_gethookmask (lua_State *L);
343LUA_API int lua_gethookcount (lua_State *L);
344
345
346struct lua_Debug {
347 int event;
348 const char *name; /* (n) */
349 const char *namewhat; /* (n) `global', `local', `field', `method' */
350 const char *what; /* (S) `Lua', `C', `main', `tail' */
351 const char *source; /* (S) */
352 int currentline; /* (l) */
353 int nups; /* (u) number of upvalues */
354 int linedefined; /* (S) */
355 int lastlinedefined; /* (S) */
356 char short_src[LUA_IDSIZE]; /* (S) */
357 /* private part */
358 int i_ci; /* active function */
359};
360
361/* }====================================================================== */
362
363
364/******************************************************************************
365* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
366*
367* Permission is hereby granted, free of charge, to any person obtaining
368* a copy of this software and associated documentation files (the
369* "Software"), to deal in the Software without restriction, including
370* without limitation the rights to use, copy, modify, merge, publish,
371* distribute, sublicense, and/or sell copies of the Software, and to
372* permit persons to whom the Software is furnished to do so, subject to
373* the following conditions:
374*
375* The above copyright notice and this permission notice shall be
376* included in all copies or substantial portions of the Software.
377*
378* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
379* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
380* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
381* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
382* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
383* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
384* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
385******************************************************************************/
386
387
388#endif
diff --git a/libraries/luajit-2.0/src/lua.hpp b/libraries/luajit-2.0/src/lua.hpp
new file mode 100644
index 0000000..07e9002
--- /dev/null
+++ b/libraries/luajit-2.0/src/lua.hpp
@@ -0,0 +1,9 @@
1// C++ wrapper for LuaJIT header files.
2
3extern "C" {
4#include "lua.h"
5#include "lauxlib.h"
6#include "lualib.h"
7#include "luajit.h"
8}
9
diff --git a/libraries/luajit-2.0/src/luaconf.h b/libraries/luajit-2.0/src/luaconf.h
new file mode 100644
index 0000000..5b04ad4
--- /dev/null
+++ b/libraries/luajit-2.0/src/luaconf.h
@@ -0,0 +1,131 @@
1/*
2** Configuration header.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef luaconf_h
7#define luaconf_h
8
9#include <limits.h>
10#include <stddef.h>
11
12/* Default path for loading Lua and C modules with require(). */
13#if defined(_WIN32)
14/*
15** In Windows, any exclamation mark ('!') in the path is replaced by the
16** path of the directory of the executable file of the current process.
17*/
18#define LUA_LDIR "!\\lua\\"
19#define LUA_CDIR "!\\"
20#define LUA_PATH_DEFAULT \
21 ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;"
22#define LUA_CPATH_DEFAULT \
23 ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
24#else
25#define LUA_ROOT "/usr/local/"
26#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
27#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
28#ifdef LUA_XROOT
29#define LUA_JDIR LUA_XROOT "share/luajit-2.0.0-beta9/"
30#define LUA_XPATH \
31 ";" LUA_XROOT "share/lua/5.1/?.lua;" LUA_XROOT "share/lua/5.1/?/init.lua"
32#define LUA_XCPATH LUA_XROOT "lib/lua/5.1/?.so;"
33#else
34#define LUA_JDIR LUA_ROOT "share/luajit-2.0.0-beta9/"
35#define LUA_XPATH
36#define LUA_XCPATH
37#endif
38#define LUA_PATH_DEFAULT \
39 "./?.lua;" LUA_JDIR"?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua" LUA_XPATH
40#define LUA_CPATH_DEFAULT \
41 "./?.so;" LUA_CDIR"?.so;" LUA_XCPATH LUA_CDIR"loadall.so"
42#endif
43
44/* Environment variable names for path overrides and initialization code. */
45#define LUA_PATH "LUA_PATH"
46#define LUA_CPATH "LUA_CPATH"
47#define LUA_INIT "LUA_INIT"
48
49/* Special file system characters. */
50#if defined(_WIN32)
51#define LUA_DIRSEP "\\"
52#else
53#define LUA_DIRSEP "/"
54#endif
55#define LUA_PATHSEP ";"
56#define LUA_PATH_MARK "?"
57#define LUA_EXECDIR "!"
58#define LUA_IGMARK "-"
59#define LUA_PATH_CONFIG \
60 LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \
61 LUA_EXECDIR "\n" LUA_IGMARK
62
63/* Quoting in error messages. */
64#define LUA_QL(x) "'" x "'"
65#define LUA_QS LUA_QL("%s")
66
67/* Various tunables. */
68#define LUAI_MAXSTACK 65500 /* Max. # of stack slots for a thread (<64K). */
69#define LUAI_MAXCSTACK 8000 /* Max. # of stack slots for a C func (<10K). */
70#define LUAI_GCPAUSE 200 /* Pause GC until memory is at 200%. */
71#define LUAI_GCMUL 200 /* Run GC at 200% of allocation speed. */
72#define LUA_MAXCAPTURES 32 /* Max. pattern captures. */
73
74/* Compatibility with older library function names. */
75#define LUA_COMPAT_MOD /* OLD: math.mod, NEW: math.fmod */
76#define LUA_COMPAT_GFIND /* OLD: string.gfind, NEW: string.gmatch */
77
78/* Configuration for the frontend (the luajit executable). */
79#if defined(luajit_c)
80#define LUA_PROGNAME "luajit" /* Fallback frontend name. */
81#define LUA_PROMPT "> " /* Interactive prompt. */
82#define LUA_PROMPT2 ">> " /* Continuation prompt. */
83#define LUA_MAXINPUT 512 /* Max. input line length. */
84#endif
85
86/* Note: changing the following defines breaks the Lua 5.1 ABI. */
87#define LUA_INTEGER ptrdiff_t
88#define LUA_IDSIZE 60 /* Size of lua_Debug.short_src. */
89#define LUAL_BUFFERSIZE BUFSIZ /* Size of lauxlib and io.* buffers. */
90
91/* The following defines are here only for compatibility with luaconf.h
92** from the standard Lua distribution. They must not be changed for LuaJIT.
93*/
94#define LUA_NUMBER_DOUBLE
95#define LUA_NUMBER double
96#define LUAI_UACNUMBER double
97#define LUA_NUMBER_SCAN "%lf"
98#define LUA_NUMBER_FMT "%.14g"
99#define lua_number2str(s, n) sprintf((s), LUA_NUMBER_FMT, (n))
100#define LUAI_MAXNUMBER2STR 32
101#define lua_str2number(s, p) strtod((s), (p))
102#define LUA_INTFRMLEN "l"
103#define LUA_INTFRM_T long
104
105/* Linkage of public API functions. */
106#if defined(LUA_BUILD_AS_DLL)
107#if defined(LUA_CORE) || defined(LUA_LIB)
108#define LUA_API __declspec(dllexport)
109#else
110#define LUA_API __declspec(dllimport)
111#endif
112#else
113#define LUA_API extern
114#endif
115
116#define LUALIB_API LUA_API
117
118/* Support for internal assertions. */
119#if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK)
120#include <assert.h>
121#endif
122#ifdef LUA_USE_ASSERT
123#define lua_assert(x) assert(x)
124#endif
125#ifdef LUA_USE_APICHECK
126#define luai_apicheck(L, o) { (void)L; assert(o); }
127#else
128#define luai_apicheck(L, o) { (void)L; }
129#endif
130
131#endif
diff --git a/libraries/luajit-2.0/src/luajit.c b/libraries/luajit-2.0/src/luajit.c
new file mode 100644
index 0000000..17d3b5f
--- /dev/null
+++ b/libraries/luajit-2.0/src/luajit.c
@@ -0,0 +1,553 @@
1/*
2** LuaJIT frontend. Runs commands, scripts, read-eval-print (REPL) etc.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Major portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/
8
9#include <signal.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define luajit_c
15
16#include "lua.h"
17#include "lauxlib.h"
18#include "lualib.h"
19#include "luajit.h"
20
21#include "lj_arch.h"
22
23#if LJ_TARGET_POSIX
24#include <unistd.h>
25#define lua_stdin_is_tty() isatty(0)
26#elif LJ_TARGET_WINDOWS
27#include <io.h>
28#ifdef __BORLANDC__
29#define lua_stdin_is_tty() isatty(_fileno(stdin))
30#else
31#define lua_stdin_is_tty() _isatty(_fileno(stdin))
32#endif
33#else
34#define lua_stdin_is_tty() 1
35#endif
36
37static lua_State *globalL = NULL;
38static const char *progname = LUA_PROGNAME;
39
40static void lstop(lua_State *L, lua_Debug *ar)
41{
42 (void)ar; /* unused arg. */
43 lua_sethook(L, NULL, 0, 0);
44 /* Avoid luaL_error -- a C hook doesn't add an extra frame. */
45 luaL_where(L, 0);
46 lua_pushfstring(L, "%sinterrupted!", lua_tostring(L, -1));
47 lua_error(L);
48}
49
50static void laction(int i)
51{
52 signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
53 terminate process (default action) */
54 lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
55}
56
57static void print_usage(void)
58{
59 fprintf(stderr,
60 "usage: %s [options]... [script [args]...].\n"
61 "Available options are:\n"
62 " -e chunk Execute string " LUA_QL("chunk") ".\n"
63 " -l name Require library " LUA_QL("name") ".\n"
64 " -b ... Save or list bytecode.\n"
65 " -j cmd Perform LuaJIT control command.\n"
66 " -O[opt] Control LuaJIT optimizations.\n"
67 " -i Enter interactive mode after executing " LUA_QL("script") ".\n"
68 " -v Show version information.\n"
69 " -- Stop handling options.\n"
70 " - Execute stdin and stop handling options.\n"
71 ,
72 progname);
73 fflush(stderr);
74}
75
76static void l_message(const char *pname, const char *msg)
77{
78 if (pname) fprintf(stderr, "%s: ", pname);
79 fprintf(stderr, "%s\n", msg);
80 fflush(stderr);
81}
82
83static int report(lua_State *L, int status)
84{
85 if (status && !lua_isnil(L, -1)) {
86 const char *msg = lua_tostring(L, -1);
87 if (msg == NULL) msg = "(error object is not a string)";
88 l_message(progname, msg);
89 lua_pop(L, 1);
90 }
91 return status;
92}
93
94static int traceback(lua_State *L)
95{
96 if (!lua_isstring(L, 1)) /* 'message' not a string? */
97 return 1; /* keep it intact */
98 lua_getfield(L, LUA_GLOBALSINDEX, "debug");
99 if (!lua_istable(L, -1)) {
100 lua_pop(L, 1);
101 return 1;
102 }
103 lua_getfield(L, -1, "traceback");
104 if (!lua_isfunction(L, -1)) {
105 lua_pop(L, 2);
106 return 1;
107 }
108 lua_pushvalue(L, 1); /* pass error message */
109 lua_pushinteger(L, 2); /* skip this function and traceback */
110 lua_call(L, 2, 1); /* call debug.traceback */
111 return 1;
112}
113
114static int docall(lua_State *L, int narg, int clear)
115{
116 int status;
117 int base = lua_gettop(L) - narg; /* function index */
118 lua_pushcfunction(L, traceback); /* push traceback function */
119 lua_insert(L, base); /* put it under chunk and args */
120 signal(SIGINT, laction);
121 status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
122 signal(SIGINT, SIG_DFL);
123 lua_remove(L, base); /* remove traceback function */
124 /* force a complete garbage collection in case of errors */
125 if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
126 return status;
127}
128
129static void print_version(void)
130{
131 fprintf(stderr,
132 LUAJIT_VERSION " -- " LUAJIT_COPYRIGHT ". " LUAJIT_URL "\n");
133}
134
135static void print_jit_status(lua_State *L)
136{
137 int n;
138 const char *s;
139 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
140 lua_getfield(L, -1, "jit"); /* Get jit.* module table. */
141 lua_remove(L, -2);
142 lua_getfield(L, -1, "status");
143 lua_remove(L, -2);
144 n = lua_gettop(L);
145 lua_call(L, 0, LUA_MULTRET);
146 fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stderr);
147 for (n++; (s = lua_tostring(L, n)); n++)
148 fprintf(stderr, " %s", s);
149 fputs("\n", stderr);
150}
151
152static int getargs(lua_State *L, char **argv, int n)
153{
154 int narg;
155 int i;
156 int argc = 0;
157 while (argv[argc]) argc++; /* count total number of arguments */
158 narg = argc - (n + 1); /* number of arguments to the script */
159 luaL_checkstack(L, narg + 3, "too many arguments to script");
160 for (i = n+1; i < argc; i++)
161 lua_pushstring(L, argv[i]);
162 lua_createtable(L, narg, n + 1);
163 for (i = 0; i < argc; i++) {
164 lua_pushstring(L, argv[i]);
165 lua_rawseti(L, -2, i - n);
166 }
167 return narg;
168}
169
170static int dofile(lua_State *L, const char *name)
171{
172 int status = luaL_loadfile(L, name) || docall(L, 0, 1);
173 return report(L, status);
174}
175
176static int dostring(lua_State *L, const char *s, const char *name)
177{
178 int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
179 return report(L, status);
180}
181
182static int dolibrary(lua_State *L, const char *name)
183{
184 lua_getglobal(L, "require");
185 lua_pushstring(L, name);
186 return report(L, docall(L, 1, 1));
187}
188
189static void write_prompt(lua_State *L, int firstline)
190{
191 const char *p;
192 lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
193 p = lua_tostring(L, -1);
194 if (p == NULL) p = firstline ? LUA_PROMPT : LUA_PROMPT2;
195 fputs(p, stdout);
196 fflush(stdout);
197 lua_pop(L, 1); /* remove global */
198}
199
200static int incomplete(lua_State *L, int status)
201{
202 if (status == LUA_ERRSYNTAX) {
203 size_t lmsg;
204 const char *msg = lua_tolstring(L, -1, &lmsg);
205 const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
206 if (strstr(msg, LUA_QL("<eof>")) == tp) {
207 lua_pop(L, 1);
208 return 1;
209 }
210 }
211 return 0; /* else... */
212}
213
214static int pushline(lua_State *L, int firstline)
215{
216 char buf[LUA_MAXINPUT];
217 write_prompt(L, firstline);
218 if (fgets(buf, LUA_MAXINPUT, stdin)) {
219 size_t len = strlen(buf);
220 if (len > 0 && buf[len-1] == '\n')
221 buf[len-1] = '\0';
222 if (firstline && buf[0] == '=')
223 lua_pushfstring(L, "return %s", buf+1);
224 else
225 lua_pushstring(L, buf);
226 return 1;
227 }
228 return 0;
229}
230
231static int loadline(lua_State *L)
232{
233 int status;
234 lua_settop(L, 0);
235 if (!pushline(L, 1))
236 return -1; /* no input */
237 for (;;) { /* repeat until gets a complete line */
238 status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
239 if (!incomplete(L, status)) break; /* cannot try to add lines? */
240 if (!pushline(L, 0)) /* no more input? */
241 return -1;
242 lua_pushliteral(L, "\n"); /* add a new line... */
243 lua_insert(L, -2); /* ...between the two lines */
244 lua_concat(L, 3); /* join them */
245 }
246 lua_remove(L, 1); /* remove line */
247 return status;
248}
249
250static void dotty(lua_State *L)
251{
252 int status;
253 const char *oldprogname = progname;
254 progname = NULL;
255 while ((status = loadline(L)) != -1) {
256 if (status == 0) status = docall(L, 0, 0);
257 report(L, status);
258 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
259 lua_getglobal(L, "print");
260 lua_insert(L, 1);
261 if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
262 l_message(progname,
263 lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)",
264 lua_tostring(L, -1)));
265 }
266 }
267 lua_settop(L, 0); /* clear stack */
268 fputs("\n", stdout);
269 fflush(stdout);
270 progname = oldprogname;
271}
272
273static int handle_script(lua_State *L, char **argv, int n)
274{
275 int status;
276 const char *fname;
277 int narg = getargs(L, argv, n); /* collect arguments */
278 lua_setglobal(L, "arg");
279 fname = argv[n];
280 if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
281 fname = NULL; /* stdin */
282 status = luaL_loadfile(L, fname);
283 lua_insert(L, -(narg+1));
284 if (status == 0)
285 status = docall(L, narg, 0);
286 else
287 lua_pop(L, narg);
288 return report(L, status);
289}
290
291/* Load add-on module. */
292static int loadjitmodule(lua_State *L)
293{
294 lua_getglobal(L, "require");
295 lua_pushliteral(L, "jit.");
296 lua_pushvalue(L, -3);
297 lua_concat(L, 2);
298 if (lua_pcall(L, 1, 1, 0)) {
299 const char *msg = lua_tostring(L, -1);
300 if (msg && !strncmp(msg, "module ", 7)) {
301 err:
302 l_message(progname,
303 "unknown luaJIT command or jit.* modules not installed");
304 return 1;
305 } else {
306 return report(L, 1);
307 }
308 }
309 lua_getfield(L, -1, "start");
310 if (lua_isnil(L, -1)) goto err;
311 lua_remove(L, -2); /* Drop module table. */
312 return 0;
313}
314
315/* Run command with options. */
316static int runcmdopt(lua_State *L, const char *opt)
317{
318 int narg = 0;
319 if (opt && *opt) {
320 for (;;) { /* Split arguments. */
321 const char *p = strchr(opt, ',');
322 narg++;
323 if (!p) break;
324 if (p == opt)
325 lua_pushnil(L);
326 else
327 lua_pushlstring(L, opt, (size_t)(p - opt));
328 opt = p + 1;
329 }
330 if (*opt)
331 lua_pushstring(L, opt);
332 else
333 lua_pushnil(L);
334 }
335 return report(L, lua_pcall(L, narg, 0, 0));
336}
337
338/* JIT engine control command: try jit library first or load add-on module. */
339static int dojitcmd(lua_State *L, const char *cmd)
340{
341 const char *opt = strchr(cmd, '=');
342 lua_pushlstring(L, cmd, opt ? (size_t)(opt - cmd) : strlen(cmd));
343 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
344 lua_getfield(L, -1, "jit"); /* Get jit.* module table. */
345 lua_remove(L, -2);
346 lua_pushvalue(L, -2);
347 lua_gettable(L, -2); /* Lookup library function. */
348 if (!lua_isfunction(L, -1)) {
349 lua_pop(L, 2); /* Drop non-function and jit.* table, keep module name. */
350 if (loadjitmodule(L))
351 return 1;
352 } else {
353 lua_remove(L, -2); /* Drop jit.* table. */
354 }
355 lua_remove(L, -2); /* Drop module name. */
356 return runcmdopt(L, opt ? opt+1 : opt);
357}
358
359/* Optimization flags. */
360static int dojitopt(lua_State *L, const char *opt)
361{
362 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
363 lua_getfield(L, -1, "jit.opt"); /* Get jit.opt.* module table. */
364 lua_remove(L, -2);
365 lua_getfield(L, -1, "start");
366 lua_remove(L, -2);
367 return runcmdopt(L, opt);
368}
369
370/* Save or list bytecode. */
371static int dobytecode(lua_State *L, char **argv)
372{
373 int narg = 0;
374 lua_pushliteral(L, "bcsave");
375 if (loadjitmodule(L))
376 return 1;
377 if (argv[0][2]) {
378 narg++;
379 argv[0][1] = '-';
380 lua_pushstring(L, argv[0]+1);
381 }
382 for (argv++; *argv != NULL; narg++, argv++)
383 lua_pushstring(L, *argv);
384 return report(L, lua_pcall(L, narg, 0, 0));
385}
386
387/* check that argument has no extra characters at the end */
388#define notail(x) {if ((x)[2] != '\0') return -1;}
389
390#define FLAGS_INTERACTIVE 1
391#define FLAGS_VERSION 2
392#define FLAGS_EXEC 4
393#define FLAGS_OPTION 8
394
395static int collectargs(char **argv, int *flags)
396{
397 int i;
398 for (i = 1; argv[i] != NULL; i++) {
399 if (argv[i][0] != '-') /* Not an option? */
400 return i;
401 switch (argv[i][1]) { /* Check option. */
402 case '-':
403 notail(argv[i]);
404 return (argv[i+1] != NULL ? i+1 : 0);
405 case '\0':
406 return i;
407 case 'i':
408 notail(argv[i]);
409 *flags |= FLAGS_INTERACTIVE;
410 /* fallthrough */
411 case 'v':
412 notail(argv[i]);
413 *flags |= FLAGS_VERSION;
414 break;
415 case 'e':
416 *flags |= FLAGS_EXEC;
417 case 'j': /* LuaJIT extension */
418 case 'l':
419 *flags |= FLAGS_OPTION;
420 if (argv[i][2] == '\0') {
421 i++;
422 if (argv[i] == NULL) return -1;
423 }
424 break;
425 case 'O': break; /* LuaJIT extension */
426 case 'b': /* LuaJIT extension */
427 if (*flags) return -1;
428 *flags |= FLAGS_EXEC;
429 return 0;
430 default: return -1; /* invalid option */
431 }
432 }
433 return 0;
434}
435
436static int runargs(lua_State *L, char **argv, int n)
437{
438 int i;
439 for (i = 1; i < n; i++) {
440 if (argv[i] == NULL) continue;
441 lua_assert(argv[i][0] == '-');
442 switch (argv[i][1]) { /* option */
443 case 'e': {
444 const char *chunk = argv[i] + 2;
445 if (*chunk == '\0') chunk = argv[++i];
446 lua_assert(chunk != NULL);
447 if (dostring(L, chunk, "=(command line)") != 0)
448 return 1;
449 break;
450 }
451 case 'l': {
452 const char *filename = argv[i] + 2;
453 if (*filename == '\0') filename = argv[++i];
454 lua_assert(filename != NULL);
455 if (dolibrary(L, filename))
456 return 1; /* stop if file fails */
457 break;
458 }
459 case 'j': { /* LuaJIT extension */
460 const char *cmd = argv[i] + 2;
461 if (*cmd == '\0') cmd = argv[++i];
462 lua_assert(cmd != NULL);
463 if (dojitcmd(L, cmd))
464 return 1;
465 break;
466 }
467 case 'O': /* LuaJIT extension */
468 if (dojitopt(L, argv[i] + 2))
469 return 1;
470 break;
471 case 'b': /* LuaJIT extension */
472 return dobytecode(L, argv+i);
473 default: break;
474 }
475 }
476 return 0;
477}
478
479static int handle_luainit(lua_State *L)
480{
481 const char *init = getenv(LUA_INIT);
482 if (init == NULL)
483 return 0; /* status OK */
484 else if (init[0] == '@')
485 return dofile(L, init+1);
486 else
487 return dostring(L, init, "=" LUA_INIT);
488}
489
490struct Smain {
491 char **argv;
492 int argc;
493 int status;
494};
495
496static int pmain(lua_State *L)
497{
498 struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
499 char **argv = s->argv;
500 int script;
501 int flags = 0;
502 globalL = L;
503 if (argv[0] && argv[0][0]) progname = argv[0];
504 LUAJIT_VERSION_SYM(); /* linker-enforced version check */
505 lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
506 luaL_openlibs(L); /* open libraries */
507 lua_gc(L, LUA_GCRESTART, -1);
508 s->status = handle_luainit(L);
509 if (s->status != 0) return 0;
510 script = collectargs(argv, &flags);
511 if (script < 0) { /* invalid args? */
512 print_usage();
513 s->status = 1;
514 return 0;
515 }
516 if ((flags & FLAGS_VERSION)) print_version();
517 s->status = runargs(L, argv, (script > 0) ? script : s->argc);
518 if (s->status != 0) return 0;
519 if (script)
520 s->status = handle_script(L, argv, script);
521 if (s->status != 0) return 0;
522 if ((flags & FLAGS_INTERACTIVE)) {
523 print_jit_status(L);
524 dotty(L);
525 } else if (script == 0 && !(flags & (FLAGS_EXEC|FLAGS_VERSION))) {
526 if (lua_stdin_is_tty()) {
527 print_version();
528 print_jit_status(L);
529 dotty(L);
530 } else {
531 dofile(L, NULL); /* executes stdin as a file */
532 }
533 }
534 return 0;
535}
536
537int main(int argc, char **argv)
538{
539 int status;
540 struct Smain s;
541 lua_State *L = lua_open(); /* create state */
542 if (L == NULL) {
543 l_message(argv[0], "cannot create state: not enough memory");
544 return EXIT_FAILURE;
545 }
546 s.argc = argc;
547 s.argv = argv;
548 status = lua_cpcall(L, pmain, &s);
549 report(L, status);
550 lua_close(L);
551 return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
552}
553
diff --git a/libraries/luajit-2.0/src/luajit.h b/libraries/luajit-2.0/src/luajit.h
new file mode 100644
index 0000000..2421502
--- /dev/null
+++ b/libraries/luajit-2.0/src/luajit.h
@@ -0,0 +1,70 @@
1/*
2** LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
3**
4** Copyright (C) 2005-2011 Mike Pall. All rights reserved.
5**
6** Permission is hereby granted, free of charge, to any person obtaining
7** a copy of this software and associated documentation files (the
8** "Software"), to deal in the Software without restriction, including
9** without limitation the rights to use, copy, modify, merge, publish,
10** distribute, sublicense, and/or sell copies of the Software, and to
11** permit persons to whom the Software is furnished to do so, subject to
12** the following conditions:
13**
14** The above copyright notice and this permission notice shall be
15** included in all copies or substantial portions of the Software.
16**
17** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24**
25** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
26*/
27
28#ifndef _LUAJIT_H
29#define _LUAJIT_H
30
31#include "lua.h"
32
33#define LUAJIT_VERSION "LuaJIT 2.0.0-beta9"
34#define LUAJIT_VERSION_NUM 20000 /* Version 2.0.0 = 02.00.00. */
35#define LUAJIT_VERSION_SYM luaJIT_version_2_0_0_beta9
36#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2011 Mike Pall"
37#define LUAJIT_URL "http://luajit.org/"
38
39/* Modes for luaJIT_setmode. */
40#define LUAJIT_MODE_MASK 0x00ff
41
42enum {
43 LUAJIT_MODE_ENGINE, /* Set mode for whole JIT engine. */
44 LUAJIT_MODE_DEBUG, /* Set debug mode (idx = level). */
45
46 LUAJIT_MODE_FUNC, /* Change mode for a function. */
47 LUAJIT_MODE_ALLFUNC, /* Recurse into subroutine protos. */
48 LUAJIT_MODE_ALLSUBFUNC, /* Change only the subroutines. */
49
50 LUAJIT_MODE_TRACE, /* Flush a compiled trace. */
51
52 LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */
53
54 LUAJIT_MODE_MAX
55};
56
57/* Flags or'ed in to the mode. */
58#define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */
59#define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */
60#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */
61
62/* LuaJIT public C API. */
63
64/* Control the JIT engine. */
65LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
66
67/* Enforce (dynamic) linker error for version mismatches. Call from main. */
68LUA_API void LUAJIT_VERSION_SYM(void);
69
70#endif
diff --git a/libraries/luajit-2.0/src/lualib.h b/libraries/luajit-2.0/src/lualib.h
new file mode 100644
index 0000000..35fb698
--- /dev/null
+++ b/libraries/luajit-2.0/src/lualib.h
@@ -0,0 +1,43 @@
1/*
2** Standard library header.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LUALIB_H
7#define _LUALIB_H
8
9#include "lua.h"
10
11#define LUA_FILEHANDLE "FILE*"
12
13#define LUA_COLIBNAME "coroutine"
14#define LUA_MATHLIBNAME "math"
15#define LUA_STRLIBNAME "string"
16#define LUA_TABLIBNAME "table"
17#define LUA_IOLIBNAME "io"
18#define LUA_OSLIBNAME "os"
19#define LUA_LOADLIBNAME "package"
20#define LUA_DBLIBNAME "debug"
21#define LUA_BITLIBNAME "bit"
22#define LUA_JITLIBNAME "jit"
23#define LUA_FFILIBNAME "ffi"
24
25LUALIB_API int luaopen_base(lua_State *L);
26LUALIB_API int luaopen_math(lua_State *L);
27LUALIB_API int luaopen_string(lua_State *L);
28LUALIB_API int luaopen_table(lua_State *L);
29LUALIB_API int luaopen_io(lua_State *L);
30LUALIB_API int luaopen_os(lua_State *L);
31LUALIB_API int luaopen_package(lua_State *L);
32LUALIB_API int luaopen_debug(lua_State *L);
33LUALIB_API int luaopen_bit(lua_State *L);
34LUALIB_API int luaopen_jit(lua_State *L);
35LUALIB_API int luaopen_ffi(lua_State *L);
36
37LUALIB_API void luaL_openlibs(lua_State *L);
38
39#ifndef lua_assert
40#define lua_assert(x) ((void)0)
41#endif
42
43#endif
diff --git a/libraries/luajit-2.0/src/msvcbuild.bat b/libraries/luajit-2.0/src/msvcbuild.bat
new file mode 100644
index 0000000..422d165
--- /dev/null
+++ b/libraries/luajit-2.0/src/msvcbuild.bat
@@ -0,0 +1,101 @@
1@rem Script to build LuaJIT with MSVC.
2@rem Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
3@rem
4@rem Either open a "Visual Studio .NET Command Prompt"
5@rem (Note that the Express Edition does not contain an x64 compiler)
6@rem -or-
7@rem Open a "Windows SDK Command Shell" and set the compiler environment:
8@rem setenv /release /x86
9@rem -or-
10@rem setenv /release /x64
11@rem
12@rem Then cd to this directory and run this script.
13
14@if not defined INCLUDE goto :FAIL
15
16@setlocal
17@set LJCOMPILE=cl /nologo /c /MD /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE
18@set LJLINK=link /nologo
19@set LJMT=mt /nologo
20@set LJLIB=lib /nologo
21@set DASMDIR=..\dynasm
22@set DASM=lua %DASMDIR%\dynasm.lua
23@set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
24
25if not exist buildvm_x86.h^
26 %DASM% -LN -o buildvm_x86.h buildvm_x86.dasc
27@if errorlevel 1 goto :BAD
28if not exist buildvm_x64win.h^
29 %DASM% -LN -D X64 -D X64WIN -o buildvm_x64win.h buildvm_x86.dasc
30@if errorlevel 1 goto :BAD
31
32%LJCOMPILE% /I "." /I %DASMDIR% buildvm*.c
33@if errorlevel 1 goto :BAD
34%LJLINK% /out:buildvm.exe buildvm*.obj
35@if errorlevel 1 goto :BAD
36if exist buildvm.exe.manifest^
37 %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe
38
39buildvm -m peobj -o lj_vm.obj
40@if errorlevel 1 goto :BAD
41buildvm -m bcdef -o lj_bcdef.h %ALL_LIB%
42@if errorlevel 1 goto :BAD
43buildvm -m ffdef -o lj_ffdef.h %ALL_LIB%
44@if errorlevel 1 goto :BAD
45buildvm -m libdef -o lj_libdef.h %ALL_LIB%
46@if errorlevel 1 goto :BAD
47buildvm -m recdef -o lj_recdef.h %ALL_LIB%
48@if errorlevel 1 goto :BAD
49buildvm -m vmdef -o ..\lib\vmdef.lua %ALL_LIB%
50@if errorlevel 1 goto :BAD
51buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
52@if errorlevel 1 goto :BAD
53
54@if "%1" neq "debug" goto :NODEBUG
55@shift
56@set LJCOMPILE=%LJCOMPILE% /Zi
57@set LJLINK=%LJLINK% /debug
58:NODEBUG
59@if "%1"=="amalg" goto :AMALGDLL
60@if "%1"=="static" goto :STATIC
61%LJCOMPILE% /DLUA_BUILD_AS_DLL lj_*.c lib_*.c
62@if errorlevel 1 goto :BAD
63%LJLINK% /DLL /out:lua51.dll lj_*.obj lib_*.obj
64@if errorlevel 1 goto :BAD
65@goto :MTDLL
66:STATIC
67%LJCOMPILE% /DLUA_BUILD_AS_DLL lj_*.c lib_*.c
68@if errorlevel 1 goto :BAD
69%LJLIB% /OUT:lua51.lib lj_*.obj lib_*.obj
70@if errorlevel 1 goto :BAD
71@goto :MTDLL
72:AMALGDLL
73%LJCOMPILE% /DLUA_BUILD_AS_DLL ljamalg.c
74@if errorlevel 1 goto :BAD
75%LJLINK% /DLL /out:lua51.dll ljamalg.obj lj_vm.obj
76@if errorlevel 1 goto :BAD
77:MTDLL
78if exist lua51.dll.manifest^
79 %LJMT% -manifest lua51.dll.manifest -outputresource:lua51.dll;2
80
81%LJCOMPILE% luajit.c
82@if errorlevel 1 goto :BAD
83%LJLINK% /out:luajit.exe luajit.obj lua51.lib
84@if errorlevel 1 goto :BAD
85if exist luajit.exe.manifest^
86 %LJMT% -manifest luajit.exe.manifest -outputresource:luajit.exe
87
88@del *.obj *.manifest buildvm.exe
89@echo.
90@echo === Successfully built LuaJIT ===
91
92@goto :END
93:BAD
94@echo.
95@echo *******************************************************
96@echo *** Build FAILED -- Please check the error messages ***
97@echo *******************************************************
98@goto :END
99:FAIL
100@echo You must open a "Visual Studio .NET Command Prompt" to run this script
101:END
diff --git a/libraries/luaproc/COPYRIGHT b/libraries/luaproc/COPYRIGHT
new file mode 100644
index 0000000..5f3c3ab
--- /dev/null
+++ b/libraries/luaproc/COPYRIGHT
@@ -0,0 +1,32 @@
1luaproc License
2---------------
3
4luaproc is licensed under the terms of the MIT license reproduced below.
5This means that luaproc is free software and can be used for both academic
6and commercial purposes at absolutely no cost.
7
8===============================================================================
9
10Copyright (C) 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in
20all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28THE SOFTWARE.
29
30===============================================================================
31
32(end of COPYRIGHT)
diff --git a/libraries/luaproc/Lua_multithreading_ry08-05.pdf b/libraries/luaproc/Lua_multithreading_ry08-05.pdf
new file mode 100644
index 0000000..5caf694
--- /dev/null
+++ b/libraries/luaproc/Lua_multithreading_ry08-05.pdf
Binary files differ
diff --git a/libraries/luaproc/Makefile b/libraries/luaproc/Makefile
new file mode 100644
index 0000000..1efc2d5
--- /dev/null
+++ b/libraries/luaproc/Makefile
@@ -0,0 +1,64 @@
1####################################################
2#
3# Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy
6# of this software and associated documentation files (the "Software"), to deal
7# in the Software without restriction, including without limitation the rights
8# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9# copies of the Software, and to permit persons to whom the Software is
10# furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in
13# all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21# THE SOFTWARE.
22#
23######################################################
24#
25# [Makefile]
26#
27######################################################
28
29# path to lua header files
30LUA_INC_PATH=/usr/include/lua5.1
31# path to lua library
32LUA_LIB_PATH=/usr/lib/lua5.1
33
34# standard makefile variables
35CC=gcc
36CFLAGS=-c -Wall -fPIC -I${LUA_INC_PATH}
37LDFLAGS=-shared -L${LUA_LIB_PATH} -lpthread
38SOURCES=sched.c list.c luaproc.c channel.c
39OBJECTS=${SOURCES:.c=.o}
40LIB=luaproc.so
41
42all: ${SOURCES} ${LIB}
43
44${LIB}: ${OBJECTS}
45 ${CC} ${OBJECTS} -o $@ ${LDFLAGS}
46
47sched.o: sched.c sched.h list.h luaproc.h channel.h
48 ${CC} ${CFLAGS} sched.c
49
50list.o: list.c list.h
51 ${CC} ${CFLAGS} list.c
52
53luaproc.o: luaproc.c luaproc.h list.h sched.h channel.h
54 ${CC} ${CFLAGS} luaproc.c
55
56channel.o: channel.c channel.h list.h
57 ${CC} ${CFLAGS} channel.c
58
59clean:
60 rm -f ${OBJECTS} ${LIB}
61
62test:
63 lua test.lua
64
diff --git a/libraries/luaproc/README b/libraries/luaproc/README
new file mode 100644
index 0000000..bc37dfe
--- /dev/null
+++ b/libraries/luaproc/README
@@ -0,0 +1,97 @@
1***************************************************
2*
3* Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4*
5* Permission is hereby granted, free of charge, to any person obtaining a copy
6* of this software and associated documentation files (the "Software"), to deal
7* in the Software without restriction, including without limitation the rights
8* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9* copies of the Software, and to permit persons to whom the Software is
10* furnished to do so, subject to the following conditions:
11*
12* The above copyright notice and this permission notice shall be included in
13* all copies or substantial portions of the Software.
14*
15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21* THE SOFTWARE.
22*
23*****************************************************
24*
25* [README]
26*
27****************************************************
28
29
30**************
31* PARENT API *
32**************
33
34-- Create a new lua process
35-- Returns true if sucessful or nil, error_message if failed
36luaproc.newproc( <string lua_code> )
37
38-- Create a new worker (pthread)
39-- Returns true if sucessful or nil, error_message if failed
40luaproc.createworker( <void> )
41
42-- Destroy a worker (pthread)
43-- Returns true if sucessful or nil, error_message if failed
44luaproc.destroyworker( <void> )
45
46-- Synchronize workers (pthreads) and exit after all lua processes have ended
47-- No return, finishes execution.
48luaproc.exit( <void> )
49
50-- Set maximum lua processes that should be recycled (default = 0)
51-- Returns true if sucessful or nil, error_message if failed
52luaproc.recycle( <int maxrecycle> )
53
54************************************************************
55* CHILD API *
56* Available only to processes spawned *
57* with luaproc.newproc *
58************************************************************
59
60-- Create a new lua process
61-- Returns true if sucessful or nil, error_message if failed
62luaproc.newproc( <string lua_code> )
63
64-- Create a new worker (pthread)
65-- Returns true if sucessful or nil, error_message if failed
66luaproc.createworker( <void> )
67
68-- Destroy a worker (pthread)
69-- Returns true if sucessful or nil, error_message if failed
70luaproc.destroyworker( <void> )
71
72-- Send a message on a channel
73-- Returns true if sucessful or nil, error_message if failed
74-- Results in blocking if there is no matching receive
75luaproc.send( <string channel_name>, <string msg1>,
76 [string msg2], [string msg3], ... )
77
78-- Receive a message on a channel
79-- Returns message string(s) if sucessful or nil, error_message if failed
80-- Results in blocking if there is no matching send
81-- and the asynchronous flag is not set (nil) or set to false
82luaproc.receive( <string channel_name>, [boolean asynchronous] )
83
84-- Create a new channel
85-- Returns true if sucessful or nil, error_message if failed
86luaproc.newchannel( <string channel_name> )
87
88-- Destroy a channel
89-- Returns true if sucessful or nil, error_message if failed
90luaproc.delchannel( <string channel_name> )
91
92-- Set maximum lua processes that should be recycled (default = 0)
93-- Returns true if sucessful or nil, error_message if failed
94luaproc.recycle( <int maxrecycle> )
95
96<> = mandatory arguments
97[] = optional arguments
diff --git a/libraries/luaproc/channel.c b/libraries/luaproc/channel.c
new file mode 100644
index 0000000..ef4ab4b
--- /dev/null
+++ b/libraries/luaproc/channel.c
@@ -0,0 +1,151 @@
1/***************************************************
2
3Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*****************************************************
24
25[channel.c]
26
27****************************************************/
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <lua.h>
33#include <lauxlib.h>
34#include <lualib.h>
35
36#include "channel.h"
37#include "list.h"
38
39/* global channel lua_State mutex */
40pthread_mutex_t mutex_channel_lstate = PTHREAD_MUTEX_INITIALIZER;
41
42/* global lua_State where channel hash table will be stored */
43lua_State *chanls = NULL;
44
45/* message channel */
46struct stchannel {
47 list send;
48 list recv;
49 pthread_mutex_t *mutex;
50 pthread_cond_t *in_use;
51};
52
53/* initialize channel table */
54void channel_init( void ) {
55 chanls = luaL_newstate();
56 lua_newtable( chanls );
57 lua_setglobal( chanls, "channeltb" );
58}
59
60/* create new channel */
61channel channel_create( const char *cname ) {
62
63 channel chan;
64
65 /* get exclusive access to the channel table */
66 pthread_mutex_lock( &mutex_channel_lstate );
67
68 /* create a new channel */
69 lua_getglobal( chanls, "channeltb");
70 lua_pushstring( chanls, cname );
71 chan = (channel )lua_newuserdata( chanls, sizeof( struct stchannel ));
72 chan->send = list_new();
73 chan->recv = list_new();
74 chan->mutex = (pthread_mutex_t *)malloc( sizeof( pthread_mutex_t ));
75 pthread_mutex_init( chan->mutex, NULL );
76 chan->in_use = (pthread_cond_t *)malloc( sizeof( pthread_cond_t ));
77 pthread_cond_init( chan->in_use, NULL );
78 lua_settable( chanls, -3 );
79 lua_pop( chanls, 1 );
80
81 /* let others access the channel table */
82 pthread_mutex_unlock( &mutex_channel_lstate );
83
84 return chan;
85}
86
87/* destroy a channel */
88int channel_destroy( channel chan, const char *chname ) {
89
90 /* get exclusive access to the channel table */
91 pthread_mutex_lock( &mutex_channel_lstate );
92
93 list_destroy( chan->send );
94 list_destroy( chan->recv );
95
96 lua_getglobal( chanls, "channeltb");
97 lua_pushstring( chanls, chname );
98 lua_pushnil( chanls );
99 lua_settable( chanls, -3 );
100 lua_pop( chanls, 1 );
101
102 /* let others access the channel table */
103 pthread_mutex_unlock( &mutex_channel_lstate );
104
105 return CHANNEL_DESTROYED;
106}
107
108/* search for and return a channel with a given name */
109channel channel_search( const char *cname ) {
110
111 channel chan;
112
113 /* get exclusive access to the channel table */
114 pthread_mutex_lock( &mutex_channel_lstate );
115
116 /* search for channel */
117 lua_getglobal( chanls, "channeltb");
118 lua_getfield( chanls, -1, cname );
119 if (( lua_type( chanls, -1 )) == LUA_TUSERDATA ) {
120 chan = (channel )lua_touserdata( chanls, -1 );
121 } else {
122 chan = NULL;
123 }
124 lua_pop( chanls, 2 );
125
126 /* let others access channel table */
127 pthread_mutex_unlock( &mutex_channel_lstate );
128
129 return chan;
130}
131
132/* return a channel's send queue */
133list channel_get_sendq( channel chan ) {
134 return chan->send;
135}
136
137/* return a channel's receive queue */
138list channel_get_recvq( channel chan ) {
139 return chan->recv;
140}
141
142/* return a channel's mutex */
143pthread_mutex_t *channel_get_mutex( channel chan ) {
144 return chan->mutex;
145}
146
147/* return a channel's conditional variable */
148pthread_cond_t *channel_get_cond( channel chan ) {
149 return chan->in_use;
150}
151
diff --git a/libraries/luaproc/channel.h b/libraries/luaproc/channel.h
new file mode 100644
index 0000000..1cced9e
--- /dev/null
+++ b/libraries/luaproc/channel.h
@@ -0,0 +1,67 @@
1/***************************************************
2
3Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*****************************************************
24
25[channel.h]
26
27****************************************************/
28
29#ifndef _CHANNEL_H_
30#define _CHANNEL_H_
31
32#include <pthread.h>
33
34#include "list.h"
35
36#define CHANNEL_MAX_NAME_LENGTH 255
37
38#define CHANNEL_DESTROYED 0
39
40/* message channel pointer type */
41typedef struct stchannel *channel;
42
43/* initialize channels */
44void channel_init( void );
45
46/* create new channel */
47channel channel_create( const char *cname );
48
49/* destroy a channel */
50int channel_destroy( channel chan, const char *chname );
51
52/* search for and return a channel with a given name */
53channel channel_search( const char *cname );
54
55/* return a channel's send queue */
56list channel_get_sendq( channel chan );
57
58/* return a channel's receive queue */
59list channel_get_recvq( channel chan );
60
61/* return a channel's mutex */
62pthread_mutex_t *channel_get_mutex( channel chan );
63
64/* return a channel's conditional variable */
65pthread_cond_t *channel_get_cond( channel chan );
66
67#endif
diff --git a/libraries/luaproc/list.c b/libraries/luaproc/list.c
new file mode 100644
index 0000000..0088695
--- /dev/null
+++ b/libraries/luaproc/list.c
@@ -0,0 +1,241 @@
1/***************************************************
2
3Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*****************************************************
24
25[list.c]
26
27****************************************************/
28#include <stdio.h>
29#include <stdlib.h>
30
31#include "list.h"
32
33/* linked list node */
34struct stnode {
35 void *data;
36 struct stnode *next;
37 struct stnode *prev;
38};
39
40/* linked list */
41struct stlist {
42 node head;
43 node tail;
44 int nodes;
45};
46
47/* create new (empty) list */
48list list_new( void ) {
49 list lst;
50 lst = (list )malloc( sizeof( struct stlist ));
51 if ( lst == NULL ) {
52 return lst;
53 }
54 lst->head = NULL;
55 lst->tail = NULL;
56 lst->nodes = 0;
57 return lst;
58}
59
60/* create new node */
61node list_new_node( void *data ) {
62 node n;
63 n = (node )malloc( sizeof( struct stnode ));
64 if ( n == NULL ) {
65 return n;
66 }
67 n->data = data;
68 n->next = NULL;
69 n->prev = NULL;
70 return n;
71}
72
73/* add node to list */
74node list_add( list lst, node n ) {
75
76 /* void list or node */
77 if (( lst == NULL ) || ( n == NULL )) {
78 return NULL;
79 }
80
81 /* list is empty */
82 if ( lst->head == NULL ) {
83 lst->head = n;
84 lst->tail = n;
85 }
86
87 /* list is _not_ empty */
88 else {
89 lst->tail->next = n;
90 n->prev = lst->tail;
91 lst->tail = n;
92 }
93
94 lst->nodes++;
95 return n;
96}
97
98/* search for a node */
99node list_search( list lst, void *data ) {
100
101 node nitr;
102
103 /* check if list is null or empty */
104 if (( lst == NULL ) || ( lst->head == NULL )) {
105 return NULL;
106 }
107
108 /* look for node between first and last nodes (first and last are included) */
109 for ( nitr = lst->head; nitr != NULL; nitr = nitr->next ) {
110 if ( nitr->data == data ) {
111 /* node found, return it */
112 return nitr;
113 }
114 }
115
116 /* node not found */
117 return NULL;
118}
119
120/* remove node from list */
121void list_remove( list lst, node n ) {
122
123 node nitr;
124
125 /* check if list or node are null and if list is empty */
126 if (( lst == NULL ) || ( n == NULL ) || ( lst->head == NULL )) {
127 return;
128 }
129
130 /* check if node is list's head */
131 if ( lst->head == n ) {
132 lst->head = n->next;
133 /* if so, also check if it's the only node in the list */
134 if ( lst->tail == n ) {
135 lst->tail = n->next;
136 }
137 else {
138 lst->head->prev = NULL;
139 }
140 free( n );
141 lst->nodes--;
142 return;
143 }
144
145 /* look for node between first and last nodes (first and last are excluded) */
146 for ( nitr = lst->head->next; nitr != lst->tail; nitr = nitr->next ) {
147 if ( nitr == n ) {
148 n->prev->next = n->next;
149 n->next->prev = n->prev;
150 free( n );
151 lst->nodes--;
152 return;
153 }
154 }
155
156 /* check if node is list's tail */
157 if ( lst->tail == n ) {
158 lst->tail = n->prev;
159 n->prev->next = n->next;
160 free( n );
161 lst->nodes--;
162 return;
163 }
164
165 return;
166}
167
168/* list_destroy */
169void list_destroy( list lst ) {
170
171 /* empty list */
172 if ( lst == NULL ) {
173 return;
174 }
175
176 /* non-empty list */
177 while ( lst->head != NULL ) {
178 list_remove( lst, lst->head );
179 }
180
181 free( lst );
182}
183
184/* return list's first node */
185node list_head( list lst ) {
186 if ( lst != NULL ) {
187 return lst->head;
188 }
189 return NULL;
190}
191
192/* return node's next node */
193node list_next( node n ) {
194 if ( n != NULL ) {
195 return n->next;
196 }
197 return NULL;
198}
199
200/* return a node's data */
201void *list_data( node n ) {
202 if ( n != NULL ) {
203 return n->data;
204 }
205 return NULL;
206}
207
208/* pop the head node from the list */
209node list_pop_head( list lst ) {
210 node ntmp;
211 if (( lst == NULL ) || ( lst->head == NULL )) {
212 return NULL;
213 }
214
215 ntmp = lst->head;
216 if ( lst->head == lst->tail ) {
217 lst->head = NULL;
218 lst->tail = NULL;
219 } else {
220 lst->head = ntmp->next;
221 ntmp->next->prev = NULL;
222 }
223 ntmp->next = NULL;
224 ntmp->prev = NULL;
225 lst->nodes--;
226 return ntmp;
227}
228
229/* destroy a node */
230void list_destroy_node( node n ) {
231 free( n );
232}
233
234/* return a list's node count */
235int list_node_count( list lst ) {
236 if ( lst != NULL ) {
237 return lst->nodes;
238 }
239 return LIST_COUNT_ERROR;
240}
241
diff --git a/libraries/luaproc/list.h b/libraries/luaproc/list.h
new file mode 100644
index 0000000..6aa21c0
--- /dev/null
+++ b/libraries/luaproc/list.h
@@ -0,0 +1,76 @@
1/***************************************************
2
3Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*****************************************************
24
25[list.h]
26
27****************************************************/
28
29#ifndef _LIST_H_
30#define _LIST_H_
31
32#define LIST_COUNT_ERROR -1
33
34/* node pointer type */
35typedef struct stnode *node;
36
37/* list pointer type */
38typedef struct stlist *list;
39
40/* create new (empty) list */
41list list_new( void );
42
43/* create new node */
44node list_new_node( void *data );
45
46/* add node to list */
47node list_add( list lst, node n );
48
49/* search for a node */
50node list_search( list lst, void *data );
51
52/* remove node from list */
53void list_remove( list lst, node n );
54
55/* destroy list */
56void list_destroy( list lst );
57
58/* return list's first node */
59node list_head( list lst );
60
61/* return node's next node */
62node list_next( node n );
63
64/* return a node's data */
65void *list_data( node n );
66
67/* pop the head node from the list */
68node list_pop_head( list lst );
69
70/* destroy a node */
71void list_destroy_node( node n );
72
73/* return a list's node count */
74int list_node_count( list lst );
75
76#endif
diff --git a/libraries/luaproc/luaproc.c b/libraries/luaproc/luaproc.c
new file mode 100644
index 0000000..2ec5b31
--- /dev/null
+++ b/libraries/luaproc/luaproc.c
@@ -0,0 +1,837 @@
1/***************************************************
2
3Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*****************************************************
24
25[luaproc.c]
26
27****************************************************/
28
29#include <netdb.h>
30#include <pthread.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
35#include <lua.h>
36#include <lauxlib.h>
37#include <lualib.h>
38
39#include "luaproc.h"
40#include "list.h"
41#include "sched.h"
42#include "channel.h"
43
44#define FALSE 0
45#define TRUE 1
46
47/*********
48* globals
49*********/
50
51/* channel operations mutex */
52pthread_mutex_t mutex_channel = PTHREAD_MUTEX_INITIALIZER;
53
54/* recycle list mutex */
55pthread_mutex_t mutex_recycle_list = PTHREAD_MUTEX_INITIALIZER;
56
57/* recycled lua process list */
58list recyclelp = NULL;
59
60/* maximum lua processes to recycle */
61int recyclemax = 0;
62
63/* lua process */
64struct stluaproc {
65 lua_State *lstate;
66 int stat;
67 int args;
68 channel chan;
69 int destroyworker;
70};
71
72/******************************
73* library functions prototypes
74******************************/
75/* create a new lua process */
76static int luaproc_create_newproc( lua_State *L );
77/* send a message to a lua process */
78static int luaproc_send( lua_State *L );
79/* receive a message from a lua process */
80static int luaproc_receive( lua_State *L );
81/* create a new channel */
82static int luaproc_create_channel( lua_State *L );
83/* destroy a channel */
84static int luaproc_destroy_channel( lua_State *L );
85/* wait until all luaprocs have finished and exit */
86static int luaproc_exit( lua_State *L );
87/* create a new worker */
88static int luaproc_create_worker( lua_State *L );
89/* destroy a worker */
90static int luaproc_destroy_worker( lua_State *L );
91/* set amount of lua processes that should be recycled (ie, reused) */
92static int luaproc_recycle_set( lua_State *L );
93
94/* luaproc function registration array - main (parent) functions */
95static const struct luaL_reg luaproc_funcs_parent[] = {
96 { "newproc", luaproc_create_newproc },
97 { "exit", luaproc_exit },
98 { "createworker", luaproc_create_worker },
99 { "destroyworker", luaproc_destroy_worker },
100 { "recycle", luaproc_recycle_set },
101 { NULL, NULL }
102};
103
104/* luaproc function registration array - newproc (child) functions */
105static const struct luaL_reg luaproc_funcs_child[] = {
106 { "newproc", luaproc_create_newproc },
107 { "send", luaproc_send },
108 { "receive", luaproc_receive },
109 { "newchannel", luaproc_create_channel },
110 { "delchannel", luaproc_destroy_channel },
111 { "createworker", luaproc_create_worker },
112 { "destroyworker", luaproc_destroy_worker },
113 { "recycle", luaproc_recycle_set },
114 { NULL, NULL }
115};
116
117static void registerlib( lua_State *L, const char *name, lua_CFunction f ) {
118 lua_getglobal( L, "package" );
119 lua_getfield( L, -1, "preload" );
120 lua_pushcfunction( L, f );
121 lua_setfield( L, -2, name );
122 lua_pop( L, 2 );
123}
124
125static void openlibs( lua_State *L ) {
126 lua_cpcall( L, luaopen_base, NULL );
127 lua_cpcall( L, luaopen_package, NULL );
128 registerlib( L, "io", luaopen_io );
129 registerlib( L, "os", luaopen_os );
130 registerlib( L, "table", luaopen_table );
131 registerlib( L, "string", luaopen_string );
132 registerlib( L, "math", luaopen_math );
133 registerlib( L, "debug", luaopen_debug );
134}
135
136/* return status (boolean) indicating if lua process should be recycled */
137luaproc luaproc_recycle_pop( void ) {
138
139 luaproc lp;
140 node n;
141
142 /* get exclusive access to operate on recycle list */
143 pthread_mutex_lock( &mutex_recycle_list );
144
145 /* check if there are any lua processes on recycle list */
146 if ( list_node_count( recyclelp ) > 0 ) {
147 /* pop list head */
148 n = list_pop_head( recyclelp );
149 /* free access to operate on recycle list */
150 pthread_mutex_unlock( &mutex_recycle_list );
151 /* find associated luaproc */
152 lp = (luaproc )list_data( n );
153 /* destroy node (but not associated luaproc) */
154 list_destroy_node( n );
155 /* return associated luaproc */
156 return lp;
157 }
158
159 /* free access to operate on recycle list */
160 pthread_mutex_unlock( &mutex_recycle_list );
161
162 /* if no lua processes are available simply return null */
163 return NULL;
164}
165
166/* check if lua process should be recycled and, in case so, add it to the recycle list */
167int luaproc_recycle_push( luaproc lp ) {
168
169 node n;
170
171 /* get exclusive access to operate on recycle list */
172 pthread_mutex_lock( &mutex_recycle_list );
173
174 /* check if amount of lua processes currently on recycle list is greater than
175 or equal to the maximum amount of lua processes that should be recycled */
176 if ( list_node_count( recyclelp ) >= recyclemax ) {
177 /* free access to operate on recycle list */
178 pthread_mutex_unlock( &mutex_recycle_list );
179 /* if so, lua process should NOT be recycled and should be destroyed */
180 return FALSE;
181 }
182 /* otherwise, lua process should be added to recycle list */
183 n = list_new_node( lp );
184 if ( n == NULL ) {
185 /* free access to operate on recycle list */
186 pthread_mutex_unlock( &mutex_recycle_list );
187 /* in case of errors, lua process should be destroyed */
188 return FALSE;
189 }
190 list_add( recyclelp, n );
191 /* free access to operate on recycle list */
192 pthread_mutex_unlock( &mutex_recycle_list );
193 /* since lua process will be recycled, it should not be destroyed */
194 return TRUE;
195}
196
197/* create new luaproc */
198luaproc luaproc_new( const char *code, int destroyflag ) {
199
200 luaproc lp;
201 int ret;
202 /* create new lua state */
203 lua_State *lpst = luaL_newstate( );
204 /* store the luaproc struct in its own lua state */
205 lp = (luaproc )lua_newuserdata( lpst, sizeof( struct stluaproc ));
206 lua_setfield( lpst, LUA_REGISTRYINDEX, "_SELF" );
207
208 lp->lstate = lpst;
209 lp->stat = LUAPROC_STAT_IDLE;
210 lp->args = 0;
211 lp->chan = NULL;
212 lp->destroyworker = destroyflag;
213
214 /* load standard libraries */
215 openlibs( lpst );
216
217 /* register luaproc's own functions */
218 luaL_register( lpst, "luaproc", luaproc_funcs_child );
219
220 /* load process' code */
221 ret = luaL_loadstring( lpst, code );
222 /* in case of errors, destroy recently created lua process */
223 if ( ret != 0 ) {
224 lua_close( lpst );
225 return NULL;
226 }
227
228 /* return recently created lua process */
229 return lp;
230}
231
232/* synchronize worker threads and exit */
233static int luaproc_exit( lua_State *L ) {
234 sched_join_workerthreads( );
235 return 0;
236}
237
238/* create a new worker pthread */
239static int luaproc_create_worker( lua_State *L ) {
240
241 if ( sched_create_worker( ) != LUAPROC_SCHED_OK ) {
242 lua_pushnil( L );
243 lua_pushstring( L, "error creating worker" );
244 return 2;
245 }
246
247 lua_pushboolean( L, TRUE );
248 return 1;
249}
250
251/* set amount of lua processes that should be recycled (ie, reused) */
252static int luaproc_recycle_set( lua_State *L ) {
253
254 node n;
255 luaproc lp;
256 int max = luaL_checkint( L, 1 );
257
258 /* check if function argument represents a reasonable value */
259 if ( max < 0 ) {
260 /* in case of errors return nil + error msg */
261 lua_pushnil( L );
262 lua_pushstring( L, "error setting recycle limit to negative value" );
263 return 2;
264 }
265
266 /* get exclusive access to operate on recycle list */
267 pthread_mutex_lock( &mutex_recycle_list );
268
269 /* set maximum lua processes that should be recycled */
270 recyclemax = max;
271
272 /* destroy recycle list excessive nodes (and corresponding lua processes) */
273 while ( list_node_count( recyclelp ) > max ) {
274 /* get first node from recycle list */
275 n = list_pop_head( recyclelp );
276 /* find associated luaproc */
277 lp = (luaproc )list_data( n );
278 /* destroy node */
279 list_destroy_node( n );
280 /* close associated lua_State */
281 lua_close( lp->lstate );
282 }
283
284 /* free access to operate on recycle list */
285 pthread_mutex_unlock( &mutex_recycle_list );
286
287 lua_pushboolean( L, TRUE );
288 return 1;
289}
290
291
292/* destroy a worker pthread */
293static int luaproc_destroy_worker( lua_State *L ) {
294
295 /* new lua process pointer */
296 luaproc lp;
297
298 /* create new lua process with empty code and destroy worker flag set to true
299 (ie, conclusion of lua process WILL result in worker thread destruction */
300 lp = luaproc_new( "", TRUE );
301
302 /* ensure process creation was successfull */
303 if ( lp == NULL ) {
304 /* in case of errors return nil + error msg */
305 lua_pushnil( L );
306 lua_pushstring( L, "error destroying worker" );
307 return 2;
308 }
309
310 /* increase active luaproc count */
311 sched_lpcount_inc();
312
313 /* schedule luaproc */
314 if ( sched_queue_proc( lp ) != LUAPROC_SCHED_QUEUE_PROC_OK ) {
315 printf( "[luaproc] error queueing Lua process\n" );
316 /* decrease active luaproc count */
317 sched_lpcount_dec();
318 /* close lua_State */
319 lua_close( lp->lstate );
320 /* return nil + error msg */
321 lua_pushnil( L );
322 lua_pushstring( L, "error destroying worker" );
323 return 2;
324 }
325
326 lua_pushboolean( L, TRUE );
327 return 1;
328}
329
330/* recycle a lua process */
331luaproc luaproc_recycle( luaproc lp, const char *code ) {
332
333 int ret;
334
335 /* reset struct members */
336 lp->stat = LUAPROC_STAT_IDLE;
337 lp->args = 0;
338 lp->chan = NULL;
339 lp->destroyworker = FALSE;
340
341 /* load process' code */
342 ret = luaL_loadstring( lp->lstate, code );
343
344 /* in case of errors, destroy lua process */
345 if ( ret != 0 ) {
346 lua_close( lp->lstate );
347 return NULL;
348 }
349
350 /* return recycled lua process */
351 return lp;
352}
353
354/* create and schedule a new lua process (luaproc.newproc) */
355static int luaproc_create_newproc( lua_State *L ) {
356
357 /* check if first argument is a string (lua code) */
358 const char *code = luaL_checkstring( L, 1 );
359
360 /* new lua process pointer */
361 luaproc lp;
362
363 /* check if existing lua process should be recycled to avoid new creation */
364 lp = luaproc_recycle_pop( );
365
366 /* if there is a lua process available on the recycle queue, recycle it */
367 if ( lp != NULL ) {
368 lp = luaproc_recycle( lp, code );
369 }
370 /* otherwise create a new one from scratch */
371 else {
372 /* create new lua process with destroy worker flag set to false
373 (ie, conclusion of lua process will NOT result in worker thread destruction */
374 lp = luaproc_new( code, FALSE );
375 }
376
377 /* ensure process creation was successfull */
378 if ( lp == NULL ) {
379 /* in case of errors return nil + error msg */
380 lua_pushnil( L );
381 lua_pushstring( L, "error loading code string" );
382 return 2;
383 }
384
385 /* increase active luaproc count */
386 sched_lpcount_inc();
387
388 /* schedule luaproc */
389 if ( sched_queue_proc( lp ) != LUAPROC_SCHED_QUEUE_PROC_OK ) {
390 printf( "[luaproc] error queueing Lua process\n" );
391 /* decrease active luaproc count */
392 sched_lpcount_dec();
393 /* close lua_State */
394 lua_close( lp->lstate );
395 /* return nil + error msg */
396 lua_pushnil( L );
397 lua_pushstring( L, "error queuing process" );
398 return 2;
399 }
400
401 lua_pushboolean( L, TRUE );
402 return 1;
403}
404
405/* queue a lua process sending a message without a matching receiver */
406void luaproc_queue_sender( luaproc lp ) {
407 /* add the sending process to this process' send queue */
408 list_add( channel_get_sendq( lp->chan ), list_new_node( lp ));
409}
410
411/* dequeue a lua process sending a message with a receiver match */
412luaproc luaproc_dequeue_sender( channel chan ) {
413
414 node n;
415 luaproc lp;
416
417 if ( list_node_count( channel_get_sendq( chan )) > 0 ) {
418 /* get first node from channel's send queue */
419 n = list_pop_head( channel_get_sendq( chan ));
420 /* find associated luaproc */
421 lp = (luaproc )list_data( n );
422 /* destroy node (but not associated luaproc) */
423 list_destroy_node( n );
424 /* return associated luaproc */
425 return lp;
426 }
427
428 return NULL;
429}
430
431/* queue a luc process receiving a message without a matching sender */
432void luaproc_queue_receiver( luaproc lp ) {
433 /* add the receiving process to this process' receive queue */
434 list_add( channel_get_recvq( lp->chan ), list_new_node( lp ));
435}
436
437/* dequeue a lua process receiving a message with a sender match */
438luaproc luaproc_dequeue_receiver( channel chan ) {
439
440 node n;
441 luaproc lp;
442
443 if ( list_node_count( channel_get_recvq( chan )) > 0 ) {
444 /* get first node from channel's recv queue */
445 n = list_pop_head( channel_get_recvq( chan ));
446 /* find associated luaproc */
447 lp = (luaproc )list_data( n );
448 /* destroy node (but not associated luaproc) */
449 list_destroy_node( n );
450 /* return associated luaproc */
451 return lp;
452 }
453
454 return NULL;
455}
456
457/* moves values between lua states' stacks */
458void luaproc_movevalues( lua_State *Lfrom, lua_State *Lto ) {
459
460 int i;
461 int n = lua_gettop( Lfrom );
462
463 /* move values between lua states' stacks */
464 for ( i = 2; i <= n; i++ ) {
465 lua_pushstring( Lto, lua_tostring( Lfrom, i ));
466 }
467}
468
469/* return the lua process associated with a given lua state */
470luaproc luaproc_getself( lua_State *L ) {
471 luaproc lp;
472 lua_getfield( L, LUA_REGISTRYINDEX, "_SELF" );
473 lp = (luaproc )lua_touserdata( L, -1 );
474 lua_pop( L, 1 );
475 return lp;
476}
477
478/* send a message to a lua process */
479static int luaproc_send( lua_State *L ) {
480
481 channel chan;
482 luaproc dstlp, self;
483 const char *chname = luaL_checkstring( L, 1 );
484
485 /* get exclusive access to operate on channels */
486 pthread_mutex_lock( &mutex_channel );
487
488 /* wait until channel is not in use */
489 while((( chan = channel_search( chname )) != NULL ) && ( pthread_mutex_trylock( channel_get_mutex( chan )) != 0 )) {
490 pthread_cond_wait( channel_get_cond( chan ), &mutex_channel );
491 }
492
493 /* free access to operate on channels */
494 pthread_mutex_unlock( &mutex_channel );
495
496 /* if channel is not found, return an error to Lua */
497 if ( chan == NULL ) {
498 lua_pushnil( L );
499 lua_pushstring( L, "non-existent channel" );
500 return 2;
501 }
502
503 /* try to find a matching receiver */
504 dstlp = luaproc_dequeue_receiver( chan );
505
506 /* if a match is found, move values to it and (queue) wake it */
507 if ( dstlp != NULL ) {
508
509 /* move values between Lua states' stacks */
510 luaproc_movevalues( L, dstlp->lstate );
511
512 dstlp->args = lua_gettop( dstlp->lstate ) - 1;
513
514 if ( sched_queue_proc( dstlp ) != LUAPROC_SCHED_QUEUE_PROC_OK ) {
515
516 /* unlock channel access */
517 luaproc_unlock_channel( chan );
518
519 /* decrease active luaproc count */
520 sched_lpcount_dec();
521
522 /* close lua_State */
523 lua_close( dstlp->lstate );
524 lua_pushnil( L );
525 lua_pushstring( L, "error scheduling process" );
526 return 2;
527 }
528
529 /* unlock channel access */
530 luaproc_unlock_channel( chan );
531 }
532
533 /* otherwise queue (block) the sending process */
534 else {
535
536 self = luaproc_getself( L );
537
538 if ( self != NULL ) {
539 self->stat = LUAPROC_STAT_BLOCKED_SEND;
540 self->chan = chan;
541 }
542
543 /* just yield the lua process, channel unlocking will be done by the scheduler */
544 return lua_yield( L, lua_gettop( L ));
545 }
546
547 lua_pushboolean( L, TRUE );
548 return 1;
549}
550
551/* receive a message from a lua process */
552static int luaproc_receive( lua_State *L ) {
553
554 channel chan;
555 luaproc srclp, self;
556 const char *chname = luaL_checkstring( L, 1 );
557
558 /* get exclusive access to operate on channels */
559 pthread_mutex_lock( &mutex_channel );
560
561 /* wait until channel is not in use */
562 while((( chan = channel_search( chname )) != NULL ) && ( pthread_mutex_trylock( channel_get_mutex( chan )) != 0 )) {
563 pthread_cond_wait( channel_get_cond( chan ), &mutex_channel );
564 }
565
566 /* free access to operate on channels */
567 pthread_mutex_unlock( &mutex_channel );
568
569 /* if channel is not found, free access to operate on channels and return an error to Lua */
570 if ( chan == NULL ) {
571 lua_pushnil( L );
572 lua_pushstring( L, "non-existent channel" );
573 return 2;
574 }
575
576 /* try to find a matching sender */
577 srclp = luaproc_dequeue_sender( chan );
578
579 /* if a match is found, get values from it and (queue) wake it */
580 if ( srclp != NULL ) {
581
582 /* move values between Lua states' stacks */
583 luaproc_movevalues( srclp->lstate, L );
584
585 /* return to sender indicanting message was sent */
586 lua_pushboolean( srclp->lstate, TRUE );
587 srclp->args = 1;
588
589 if ( sched_queue_proc( srclp ) != LUAPROC_SCHED_QUEUE_PROC_OK ) {
590
591 /* unlock channel access */
592 luaproc_unlock_channel( chan );
593
594 /* decrease active luaproc count */
595 sched_lpcount_dec();
596
597 /* close lua_State */
598 lua_close( srclp->lstate );
599 lua_pushnil( L );
600 lua_pushstring( L, "error scheduling process" );
601 return 2;
602 }
603
604 /* unlock channel access */
605 luaproc_unlock_channel( chan );
606
607 return lua_gettop( L ) - 1;
608 }
609
610 /* otherwise queue (block) the receiving process (sync) or return immediatly (async) */
611 else {
612
613 /* if trying an asynchronous receive, unlock channel access and return an error */
614 if ( lua_toboolean( L, 2 )) {
615 /* unlock channel access */
616 luaproc_unlock_channel( chan );
617 /* return an error */
618 lua_pushnil( L );
619 lua_pushfstring( L, "no senders waiting on channel %s", chname );
620 return 2;
621 }
622
623 /* otherwise (synchronous receive) simply block process */
624 else {
625 self = luaproc_getself( L );
626
627 if ( self != NULL ) {
628 self->stat = LUAPROC_STAT_BLOCKED_RECV;
629 self->chan = chan;
630 }
631
632 /* just yield the lua process, channel unlocking will be done by the scheduler */
633 return lua_yield( L, lua_gettop( L ));
634 }
635 }
636}
637
638LUALIB_API int luaopen_luaproc( lua_State *L ) {
639
640 /* register luaproc functions */
641 luaL_register( L, "luaproc", luaproc_funcs_parent );
642
643 /* initialize recycle list */
644 recyclelp = list_new();
645
646 /* initialize local scheduler */
647 sched_init_local( LUAPROC_SCHED_DEFAULT_WORKER_THREADS );
648
649 return 0;
650}
651
652/* return a process' status */
653int luaproc_get_status( luaproc lp ) {
654 return lp->stat;
655}
656
657/* set a process' status */
658void luaproc_set_status( luaproc lp, int status ) {
659 lp->stat = status;
660}
661
662/* return a process' state */
663lua_State *luaproc_get_state( luaproc lp ) {
664 return lp->lstate;
665}
666
667/* return the number of arguments expected by a given process */
668int luaproc_get_args( luaproc lp ) {
669 return lp->args;
670}
671
672/* set the number of arguments expected by a given process */
673void luaproc_set_args( luaproc lp, int n ) {
674 lp->args = n;
675}
676
677/* create a new channel */
678static int luaproc_create_channel( lua_State *L ) {
679
680 const char *chname = luaL_checkstring( L, 1 );
681
682 /* get exclusive access to operate on channels */
683 pthread_mutex_lock( &mutex_channel );
684
685 /* check if channel exists */
686 if ( channel_search( chname ) != NULL ) {
687 /* free access to operate on channels */
688 pthread_mutex_unlock( &mutex_channel );
689 /* return an error to lua */
690 lua_pushnil( L );
691 lua_pushstring( L, "channel already exists" );
692 return 2;
693 }
694
695 channel_create( chname );
696
697 /* free access to operate on channels */
698 pthread_mutex_unlock( &mutex_channel );
699
700 lua_pushboolean( L, TRUE );
701
702 return 1;
703
704}
705
706/* destroy a channel */
707static int luaproc_destroy_channel( lua_State *L ) {
708
709 channel chan;
710 luaproc lp;
711 node nitr;
712 pthread_mutex_t *chmutex;
713 pthread_cond_t *chcond;
714 const char *chname = luaL_checkstring( L, 1 );
715
716
717 /* get exclusive access to operate on channels */
718 pthread_mutex_lock( &mutex_channel );
719
720 /* wait until channel is not in use */
721 while((( chan = channel_search( chname )) != NULL ) && ( pthread_mutex_trylock( channel_get_mutex( chan )) != 0 )) {
722 pthread_cond_wait( channel_get_cond( chan ), &mutex_channel );
723 }
724
725 /* free access to operate on channels */
726 pthread_mutex_unlock( &mutex_channel );
727
728 /* if channel is not found, return an error to Lua */
729 if ( chan == NULL ) {
730 lua_pushnil( L );
731 lua_pushstring( L, "non-existent channel" );
732 return 2;
733 }
734
735 /* get channel's mutex and conditional pointers */
736 chmutex = channel_get_mutex( chan );
737 chcond = channel_get_cond( chan );
738
739 /* search for processes waiting to send a message on this channel */
740 while (( nitr = list_pop_head( channel_get_sendq( chan ))) != NULL ) {
741
742 lp = (luaproc )list_data( nitr );
743
744 /* destroy node (but not associated luaproc) */
745 list_destroy_node( nitr );
746
747 /* return an error so the processe knows the channel was destroyed before the message was sent */
748 lua_settop( lp->lstate, 0 );
749 lua_pushnil( lp->lstate );
750 lua_pushstring( lp->lstate, "channel destroyed while waiting for receiver" );
751 lp->args = 2;
752
753 /* schedule the process for execution */
754 if ( sched_queue_proc( lp ) != LUAPROC_SCHED_QUEUE_PROC_OK ) {
755
756 /* decrease active luaproc count */
757 sched_lpcount_dec();
758
759 /* close lua_State */
760 lua_close( lp->lstate );
761 }
762 }
763
764 /* search for processes waiting to receive a message on this channel */
765 while (( nitr = list_pop_head( channel_get_recvq( chan ))) != NULL ) {
766
767 lp = (luaproc )list_data( nitr );
768
769 /* destroy node (but not associated luaproc) */
770 list_destroy_node( nitr );
771
772 /* return an error so the processe knows the channel was destroyed before the message was received */
773 lua_settop( lp->lstate, 0 );
774 lua_pushnil( lp->lstate );
775 lua_pushstring( lp->lstate, "channel destroyed while waiting for sender" );
776 lp->args = 2;
777
778 /* schedule the process for execution */
779 if ( sched_queue_proc( lp ) != LUAPROC_SCHED_QUEUE_PROC_OK ) {
780
781 /* decrease active luaproc count */
782 sched_lpcount_dec();
783
784 /* close lua_State */
785 lua_close( lp->lstate );
786 }
787 }
788
789 /* get exclusive access to operate on channels */
790 pthread_mutex_lock( &mutex_channel );
791 /* destroy channel */
792 channel_destroy( chan, chname );
793 /* broadcast channel not in use */
794 pthread_cond_broadcast( chcond );
795 /* unlock channel access */
796 pthread_mutex_unlock( chmutex );
797 /* destroy channel mutex and conditional */
798 pthread_mutex_destroy( chmutex );
799 pthread_cond_destroy( chcond );
800 /* free memory used by channel mutex and conditional */
801 free( chmutex );
802 free( chcond );
803 /* free access to operate on channels */
804 pthread_mutex_unlock( &mutex_channel );
805
806 lua_pushboolean( L, TRUE );
807
808 return 1;
809}
810
811/* register luaproc's functions in a lua_State */
812void luaproc_register_funcs( lua_State *L ) {
813 luaL_register( L, "luaproc", luaproc_funcs_child );
814}
815
816/* return the channel where the corresponding luaproc is blocked at */
817channel luaproc_get_channel( luaproc lp ) {
818 return lp->chan;
819}
820
821/* unlock access to a channel */
822void luaproc_unlock_channel( channel chan ) {
823 /* get exclusive access to operate on channels */
824 pthread_mutex_lock( &mutex_channel );
825 /* unlock channel access */
826 pthread_mutex_unlock( channel_get_mutex( chan ));
827 /* signal channel not in use */
828 pthread_cond_signal( channel_get_cond( chan ));
829 /* free access to operate on channels */
830 pthread_mutex_unlock( &mutex_channel );
831}
832
833/* return status (boolean) indicating if worker thread should be destroyed after luaproc execution */
834int luaproc_get_destroyworker( luaproc lp ) {
835 return lp->destroyworker;
836}
837
diff --git a/libraries/luaproc/luaproc.h b/libraries/luaproc/luaproc.h
new file mode 100644
index 0000000..86617a9
--- /dev/null
+++ b/libraries/luaproc/luaproc.h
@@ -0,0 +1,92 @@
1/***************************************************
2
3Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*****************************************************
24
25[luaproc.h]
26
27****************************************************/
28#ifndef _LUAPROC_H_
29#define _LUAPROC_H_
30
31#include "channel.h"
32
33/* process is idle */
34#define LUAPROC_STAT_IDLE 0
35/* process is ready to run */
36#define LUAPROC_STAT_READY 1
37/* process is blocked on send */
38#define LUAPROC_STAT_BLOCKED_SEND 2
39/* process is blocked on receive */
40#define LUAPROC_STAT_BLOCKED_RECV 3
41/* process is finished */
42#define LUAPROC_STAT_FINISHED 4
43
44/* lua process pointer type */
45typedef struct stluaproc *luaproc;
46
47/* return a process' status */
48int luaproc_get_status( luaproc lp );
49
50/* set a process' status */
51void luaproc_set_status( luaproc lp, int status );
52
53/* return a process' state */
54lua_State *luaproc_get_state( luaproc lp );
55
56/* return the number of arguments expected by a given a process */
57int luaproc_get_args( luaproc lp );
58
59/* set the number of arguments expected by a given process */
60void luaproc_set_args( luaproc lp, int n );
61
62/* create luaproc (from scheduler) */
63luaproc luaproc_create_sched( char *code );
64
65/* register luaproc's functions in a lua_State */
66void luaproc_register_funcs( lua_State *L );
67
68/* allow registering of luaproc's functions in c main prog */
69void luaproc_register_lib( lua_State *L );
70
71/* queue a luaproc that tried to send a message */
72void luaproc_queue_sender( luaproc lp );
73
74/* queue a luaproc that tried to receive a message */
75void luaproc_queue_receiver( luaproc lp );
76
77/* unlock a channel's access */
78void luaproc_unlock_channel( channel chan );
79
80/* return a luaproc's channel */
81channel luaproc_get_channel( luaproc lp );
82
83/* return status (boolean) indicating if worker thread should be destroyed after luaproc execution */
84int luaproc_get_destroyworker( luaproc lp );
85
86/* return status (boolean) indicating if lua process should be recycled */
87luaproc luaproc_recycle_pop( void );
88
89/* add a lua process to the recycle list */
90int luaproc_recycle_push( luaproc lp );
91
92#endif
diff --git a/libraries/luaproc/luaproc.lua b/libraries/luaproc/luaproc.lua
new file mode 100644
index 0000000..a1a73e4
--- /dev/null
+++ b/libraries/luaproc/luaproc.lua
@@ -0,0 +1,34 @@
1----------------------------------------------------
2--
3-- Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4--
5-- Permission is hereby granted, free of charge, to any person obtaining a copy
6-- of this software and associated documentation files (the "Software"), to deal
7-- in the Software without restriction, including without limitation the rights
8-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9-- copies of the Software, and to permit persons to whom the Software is
10-- furnished to do so, subject to the following conditions:
11--
12-- The above copyright notice and this permission notice shall be included in
13-- all copies or substantial portions of the Software.
14--
15-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21-- THE SOFTWARE.
22--
23-----------------------------------------------------
24--
25-- luaproc.lua
26--
27-----------------------------------------------------
28
29local function so( objname )
30 local SOPATH = os.getenv( "LUA_SOPATH" ) or "./"
31 assert( package.loadlib( SOPATH .. objname .. ".so" , "luaopen_" .. objname ))( )
32end
33
34so( "luaproc" )
diff --git a/libraries/luaproc/sched.c b/libraries/luaproc/sched.c
new file mode 100644
index 0000000..f19beeb
--- /dev/null
+++ b/libraries/luaproc/sched.c
@@ -0,0 +1,314 @@
1/***************************************************
2
3Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*****************************************************
24
25[sched.c]
26
27****************************************************/
28
29#include <pthread.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34#include <arpa/inet.h>
35#include <sys/select.h>
36#include <sys/socket.h>
37#include <sys/stat.h>
38#include <lua.h>
39#include <lauxlib.h>
40#include <lualib.h>
41
42#include "list.h"
43#include "sched.h"
44#include "luaproc.h"
45#include "channel.h"
46
47#define TRUE 1
48#define FALSE 0
49
50/*********
51* globals
52*********/
53
54/* ready process list */
55list lpready = NULL;
56
57/* ready process queue access mutex */
58pthread_mutex_t mutex_queue_access = PTHREAD_MUTEX_INITIALIZER;
59
60/* wake worker up conditional variable */
61pthread_cond_t cond_wakeup_worker = PTHREAD_COND_INITIALIZER;
62
63/* active luaproc count access mutex */
64pthread_mutex_t mutex_lp_count = PTHREAD_MUTEX_INITIALIZER;
65
66/* no active luaproc conditional variable */
67pthread_cond_t cond_no_active_lp = PTHREAD_COND_INITIALIZER;
68
69/* number of active luaprocs */
70int lpcount = 0;
71
72/* no more lua processes flag */
73int no_more_processes = FALSE;
74
75/* worker thread main function */
76void *workermain( void *args ) {
77
78 node n;
79 luaproc lp;
80 int procstat;
81 int destroyworker;
82
83 /* detach thread so resources are freed as soon as thread exits (no further joining) */
84 pthread_detach( pthread_self( ));
85
86 /* main worker loop */
87 while ( 1 ) {
88
89 /* get exclusive access to the ready process queue */
90 pthread_mutex_lock( &mutex_queue_access );
91
92 /* wait until instructed to wake up (because there's work to do or because its time to finish) */
93 while (( list_node_count( lpready ) == 0 ) && ( no_more_processes == FALSE )) {
94 pthread_cond_wait( &cond_wakeup_worker, &mutex_queue_access );
95 }
96
97 /* pop the first node from the ready process queue */
98 n = list_pop_head( lpready );
99
100 /* ensure list pop succeeded before proceeding */
101 if ( n != NULL ) {
102 /* get the popped node's data content (ie, the lua process struct) */
103 lp = (luaproc )list_data( n );
104 }
105 else {
106 /* free access to the process ready queue */
107 pthread_mutex_unlock( &mutex_queue_access );
108 /* finished thread */
109 pthread_exit( NULL );
110 }
111
112 /* free access to the process ready queue */
113 pthread_mutex_unlock( &mutex_queue_access );
114
115 /* execute the lua code specified in the lua process struct */
116 procstat = lua_resume( luaproc_get_state( lp ), luaproc_get_args( lp ));
117
118 /* reset the process argument count */
119 luaproc_set_args( lp, 0 );
120
121 /* check if process finished its whole execution */
122 if ( procstat == 0 ) {
123
124 /* destroy the corresponding list node */
125 list_destroy_node( n );
126
127 /* check if worker thread should be destroyed */
128 destroyworker = luaproc_get_destroyworker( lp );
129
130 /* set process status to finished */
131 luaproc_set_status( lp, LUAPROC_STAT_FINISHED );
132
133 /* check if lua process should be recycled and, if not, destroy it */
134 if ( luaproc_recycle_push( lp ) == FALSE ) {
135 lua_close( luaproc_get_state( lp ));
136 }
137
138 /* decrease active lua process count */
139 sched_lpcount_dec();
140
141 /* check if thread should be finished after lua process conclusion */
142 if ( destroyworker ) {
143 /* if so, finish thread */
144 pthread_exit( NULL );
145 }
146 }
147
148 /* check if process yielded */
149 else if ( procstat == LUA_YIELD ) {
150
151 /* if so, further check if yield originated from an unmatched send/recv operation */
152 if ( luaproc_get_status( lp ) == LUAPROC_STAT_BLOCKED_SEND ) {
153 /* queue blocked lua process on corresponding channel */
154 luaproc_queue_sender( lp );
155 /* unlock channel access */
156 luaproc_unlock_channel( luaproc_get_channel( lp ));
157 /* destroy node (but not the associated Lua process) */
158 list_destroy_node( n );
159 }
160
161 else if ( luaproc_get_status( lp ) == LUAPROC_STAT_BLOCKED_RECV ) {
162 /* queue blocked lua process on corresponding channel */
163 luaproc_queue_receiver( lp );
164 /* unlock channel access */
165 luaproc_unlock_channel( luaproc_get_channel( lp ));
166 /* destroy node (but not the associated Lua process) */
167 list_destroy_node( n );
168 }
169
170 /* or if yield resulted from an explicit call to coroutine.yield in the lua code being executed */
171 else {
172 /* get exclusive access to the ready process queue */
173 pthread_mutex_lock( &mutex_queue_access );
174 /* re-insert the job at the end of the ready process queue */
175 list_add( lpready, n );
176 /* free access to the process ready queue */
177 pthread_mutex_unlock( &mutex_queue_access );
178 }
179 }
180
181 /* check if there was any execution error (LUA_ERRRUN, LUA_ERRSYNTAX, LUA_ERRMEM or LUA_ERRERR) */
182 else {
183 /* destroy the corresponding node */
184 list_destroy_node( n );
185 /* print error message */
186 fprintf( stderr, "close lua_State (error: %s)\n", luaL_checkstring( luaproc_get_state( lp ), -1 ));
187 /* close lua state */
188 lua_close( luaproc_get_state( lp ));
189 /* decrease active lua process count */
190 sched_lpcount_dec();
191 }
192 }
193}
194
195/* local scheduler initialization */
196int sched_init_local( int numworkers ) {
197
198 int tid;
199 int workercount = 0;
200 pthread_t worker;
201
202 /* initialize ready process list */
203 lpready = list_new();
204
205 /* initialize channels */
206 channel_init();
207
208 /* create initial worker threads */
209 for ( tid = 0; tid < numworkers; tid++ ) {
210 if ( pthread_create( &worker, NULL, workermain, NULL ) == 0 ) {
211 workercount++;
212 }
213 }
214
215 if ( workercount != numworkers ) {
216 return LUAPROC_SCHED_INIT_ERROR;
217 }
218
219 return LUAPROC_SCHED_OK;
220}
221
222/* exit scheduler */
223void sched_exit( void ) {
224
225 /* get exclusive access to the ready process queue */
226 pthread_mutex_lock( &mutex_queue_access );
227 /* destroy the ready process list */
228 list_destroy( lpready );
229 /* free access to the process ready queue */
230 pthread_mutex_unlock( &mutex_queue_access );
231}
232
233/* move process to ready queue (ie, schedule process) */
234int sched_queue_proc( luaproc lp ) {
235
236 /* get exclusive access to the ready process queue */
237 pthread_mutex_lock( &mutex_queue_access );
238
239 /* add process to ready queue */
240 if ( list_add( lpready, list_new_node( lp )) != NULL ) {
241
242 /* set process status to ready */
243 luaproc_set_status( lp, LUAPROC_STAT_READY );
244
245 /* wake worker up */
246 pthread_cond_signal( &cond_wakeup_worker );
247 /* free access to the process ready queue */
248 pthread_mutex_unlock( &mutex_queue_access );
249
250 return LUAPROC_SCHED_QUEUE_PROC_OK;
251 }
252 else {
253 /* free access to the process ready queue */
254 pthread_mutex_unlock( &mutex_queue_access );
255
256 return LUAPROC_SCHED_QUEUE_PROC_ERR;
257 }
258}
259
260/* synchronize worker threads */
261void sched_join_workerthreads( void ) {
262
263 pthread_mutex_lock( &mutex_lp_count );
264
265 /* wait until there is no more active lua processes */
266 while( lpcount != 0 ) {
267 pthread_cond_wait( &cond_no_active_lp, &mutex_lp_count );
268 }
269 /* get exclusive access to the ready process queue */
270 pthread_mutex_lock( &mutex_queue_access );
271 /* set the no more active lua processes flag to true */
272 no_more_processes = TRUE;
273 /* wake ALL workers up */
274 pthread_cond_broadcast( &cond_wakeup_worker );
275 /* free access to the process ready queue */
276 pthread_mutex_unlock( &mutex_queue_access );
277 /* wait for (join) worker threads */
278 pthread_exit( NULL );
279
280 pthread_mutex_unlock( &mutex_lp_count );
281
282}
283
284/* increase active lua process count */
285void sched_lpcount_inc( void ) {
286 pthread_mutex_lock( &mutex_lp_count );
287 lpcount++;
288 pthread_mutex_unlock( &mutex_lp_count );
289}
290
291/* decrease active lua process count */
292void sched_lpcount_dec( void ) {
293 pthread_mutex_lock( &mutex_lp_count );
294 lpcount--;
295 /* if count reaches zero, signal there are no more active processes */
296 if ( lpcount == 0 ) {
297 pthread_cond_signal( &cond_no_active_lp );
298 }
299 pthread_mutex_unlock( &mutex_lp_count );
300}
301
302/* create a new worker pthread */
303int sched_create_worker( void ) {
304
305 pthread_t worker;
306
307 /* create a new pthread */
308 if ( pthread_create( &worker, NULL, workermain, NULL ) != 0 ) {
309 return LUAPROC_SCHED_PTHREAD_ERROR;
310 }
311
312 return LUAPROC_SCHED_OK;
313}
314
diff --git a/libraries/luaproc/sched.h b/libraries/luaproc/sched.h
new file mode 100644
index 0000000..c03e6ea
--- /dev/null
+++ b/libraries/luaproc/sched.h
@@ -0,0 +1,78 @@
1/***************************************************
2
3Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
23*****************************************************
24
25[sched.h]
26
27****************************************************/
28#ifndef _SCHED_H_
29#define _SCHED_H_
30
31#include "luaproc.h"
32
33/* scheduler function return constants */
34#define LUAPROC_SCHED_OK 0
35#define LUAPROC_SCHED_SOCKET_ERROR -1
36#define LUAPROC_SCHED_SETSOCKOPT_ERROR -2
37#define LUAPROC_SCHED_BIND_ERROR -3
38#define LUAPROC_SCHED_LISTEN_ERROR -4
39#define LUAPROC_SCHED_FORK_ERROR -5
40#define LUAPROC_SCHED_PTHREAD_ERROR -6
41#define LUAPROC_SCHED_INIT_ERROR -7
42
43/* ready process queue insertion status */
44#define LUAPROC_SCHED_QUEUE_PROC_OK 0
45#define LUAPROC_SCHED_QUEUE_PROC_ERR -1
46
47/* scheduler listener service default hostname and port */
48#define LUAPROC_SCHED_DEFAULT_HOST "127.0.0.1"
49#define LUAPROC_SCHED_DEFAULT_PORT 3133
50
51/* scheduler default number of worker threads */
52#define LUAPROC_SCHED_DEFAULT_WORKER_THREADS 1
53
54/* initialize local scheduler */
55int sched_init_local( int numworkers );
56
57/* initialize socket enabled scheduler */
58int sched_init_socket( int numworkers, const char *host, int port );
59
60/* exit scheduler */
61void sched_exit( void );
62
63/* move process to ready queue (ie, schedule process) */
64int sched_queue_proc( luaproc lp );
65
66/* join all worker threads and exit */
67void sched_join_workerthreads( void );
68
69/* increase active luaproc count */
70void sched_lpcount_inc( void );
71
72/* decrease active luaproc count */
73void sched_lpcount_dec( void );
74
75/* create a new worker pthread */
76int sched_create_worker( void );
77
78#endif
diff --git a/libraries/luaproc/test.lua b/libraries/luaproc/test.lua
new file mode 100644
index 0000000..5868d6f
--- /dev/null
+++ b/libraries/luaproc/test.lua
@@ -0,0 +1,39 @@
1----------------------------------------------------
2--
3-- Copyright 2008 Alexandre Skyrme, Noemi Rodriguez, Roberto Ierusalimschy
4--
5-- Permission is hereby granted, free of charge, to any person obtaining a copy
6-- of this software and associated documentation files (the "Software"), to deal
7-- in the Software without restriction, including without limitation the rights
8-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9-- copies of the Software, and to permit persons to whom the Software is
10-- furnished to do so, subject to the following conditions:
11--
12-- The above copyright notice and this permission notice shall be included in
13-- all copies or substantial portions of the Software.
14--
15-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21-- THE SOFTWARE.
22--
23-----------------------------------------------------
24--
25-- test.lua
26--
27-----------------------------------------------------
28
29require "luaproc"
30
31luaproc.createworker()
32
33luaproc.newproc( [=[
34 luaproc.newchannel( "testchannel" )
35 luaproc.newproc( "luaproc.send( 'testchannel', 'luaproc is working fine!' )" )
36 luaproc.newproc( "print( luaproc.receive( 'testchannel' ))" )
37]=] )
38
39luaproc.exit()