jaelis-node 1.10.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +146 -445
  2. package/bin/jaelis-node.js +79 -504
  3. package/lib/index.js +31 -2840
  4. package/lib/node.js +271 -0
  5. package/lib/rpc.js +315 -0
  6. package/lib/storage.js +198 -0
  7. package/lib/sync.js +366 -0
  8. package/package.json +19 -53
  9. package/config/default.json +0 -74
  10. package/config/mainnet.json +0 -30
  11. package/config/testnet.json +0 -26
  12. package/lib/JAELIS-VM/lib/adapters/evm-adapter.js +0 -454
  13. package/lib/JAELIS-VM/lib/adapters/index.js +0 -411
  14. package/lib/JAELIS-VM/lib/adapters/svm-adapter.js +0 -457
  15. package/lib/JAELIS-VM/lib/compiler/jir-compiler.js +0 -1097
  16. package/lib/JAELIS-VM/lib/execution/engine.js +0 -1183
  17. package/lib/JAELIS-VM/lib/index.js +0 -440
  18. package/lib/JAELIS-VM/lib/integration/jaelis-integration.js +0 -543
  19. package/lib/JAELIS-VM/lib/serialization/serializer.js +0 -819
  20. package/lib/JAELIS-VM/lib/state/state-manager.js +0 -1116
  21. package/lib/JAELIS-VM/lib/translator/bytecode-translator.js +0 -1222
  22. package/lib/JAELIS-VM/lib/unified/cross-chain-deploy.js +0 -1678
  23. package/lib/JAELIS-VM/lib/unified/cross-chain-state.js +0 -836
  24. package/lib/JAELIS-VM/lib/unified/dynamic-contracts.js +0 -1127
  25. package/lib/JAELIS-VM/lib/unified/index.js +0 -456
  26. package/lib/JAELIS-VM/lib/unified/jaelis-abi.js +0 -1150
  27. package/lib/JAELIS-VM/lib/unified/unified-compiler.js +0 -1350
  28. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds +0 -12
  29. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.cmd +0 -17
  30. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.ps1 +0 -28
  31. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds +0 -12
  32. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.cmd +0 -17
  33. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.ps1 +0 -28
  34. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages +0 -12
  35. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional +0 -12
  36. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +0 -17
  37. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +0 -28
  38. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test +0 -12
  39. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +0 -17
  40. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +0 -28
  41. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.cmd +0 -17
  42. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.ps1 +0 -28
  43. package/lib/JAELIS-VM/node_modules/.package-lock.json +0 -127
  44. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/README.md +0 -1
  45. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/index.js +0 -0
  46. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.abi115.node +0 -0
  47. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.napi.node +0 -0
  48. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/package.json +0 -17
  49. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/README.md +0 -1
  50. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/index.js +0 -0
  51. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.abi115.node +0 -0
  52. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.napi.node +0 -0
  53. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/package.json +0 -17
  54. package/lib/JAELIS-VM/node_modules/cbor-extract/LICENSE +0 -21
  55. package/lib/JAELIS-VM/node_modules/cbor-extract/README.md +0 -5
  56. package/lib/JAELIS-VM/node_modules/cbor-extract/bin/download-prebuilds.js +0 -11
  57. package/lib/JAELIS-VM/node_modules/cbor-extract/binding.gyp +0 -60
  58. package/lib/JAELIS-VM/node_modules/cbor-extract/index.js +0 -1
  59. package/lib/JAELIS-VM/node_modules/cbor-extract/package.json +0 -50
  60. package/lib/JAELIS-VM/node_modules/cbor-extract/src/extract.cpp +0 -198
  61. package/lib/JAELIS-VM/node_modules/cbor-x/LICENSE +0 -21
  62. package/lib/JAELIS-VM/node_modules/cbor-x/README.md +0 -380
  63. package/lib/JAELIS-VM/node_modules/cbor-x/SECURITY.md +0 -11
  64. package/lib/JAELIS-VM/node_modules/cbor-x/benchmark.md +0 -73
  65. package/lib/JAELIS-VM/node_modules/cbor-x/browser.js +0 -11
  66. package/lib/JAELIS-VM/node_modules/cbor-x/decode.d.ts +0 -2
  67. package/lib/JAELIS-VM/node_modules/cbor-x/decode.js +0 -1300
  68. package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs +0 -1244
  69. package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs.map +0 -1
  70. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs +0 -2509
  71. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs.map +0 -1
  72. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js +0 -2
  73. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js.map +0 -1
  74. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js +0 -2508
  75. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js.map +0 -1
  76. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js +0 -2
  77. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js.map +0 -1
  78. package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs +0 -2629
  79. package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs.map +0 -1
  80. package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js +0 -3343
  81. package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js.map +0 -1
  82. package/lib/JAELIS-VM/node_modules/cbor-x/encode.d.ts +0 -1
  83. package/lib/JAELIS-VM/node_modules/cbor-x/encode.js +0 -1231
  84. package/lib/JAELIS-VM/node_modules/cbor-x/index.d.ts +0 -79
  85. package/lib/JAELIS-VM/node_modules/cbor-x/index.js +0 -3
  86. package/lib/JAELIS-VM/node_modules/cbor-x/iterators.js +0 -85
  87. package/lib/JAELIS-VM/node_modules/cbor-x/node-index.js +0 -24
  88. package/lib/JAELIS-VM/node_modules/cbor-x/package.json +0 -94
  89. package/lib/JAELIS-VM/node_modules/cbor-x/rollup.config.js +0 -88
  90. package/lib/JAELIS-VM/node_modules/cbor-x/stream.js +0 -61
  91. package/lib/JAELIS-VM/node_modules/cbor-x/webpack.config.js +0 -19
  92. package/lib/JAELIS-VM/node_modules/detect-libc/LICENSE +0 -201
  93. package/lib/JAELIS-VM/node_modules/detect-libc/README.md +0 -163
  94. package/lib/JAELIS-VM/node_modules/detect-libc/index.d.ts +0 -14
  95. package/lib/JAELIS-VM/node_modules/detect-libc/lib/detect-libc.js +0 -313
  96. package/lib/JAELIS-VM/node_modules/detect-libc/lib/elf.js +0 -39
  97. package/lib/JAELIS-VM/node_modules/detect-libc/lib/filesystem.js +0 -51
  98. package/lib/JAELIS-VM/node_modules/detect-libc/lib/process.js +0 -24
  99. package/lib/JAELIS-VM/node_modules/detect-libc/package.json +0 -44
  100. package/lib/JAELIS-VM/node_modules/msgpackr/LICENSE +0 -21
  101. package/lib/JAELIS-VM/node_modules/msgpackr/README.md +0 -372
  102. package/lib/JAELIS-VM/node_modules/msgpackr/SECURITY.md +0 -11
  103. package/lib/JAELIS-VM/node_modules/msgpackr/benchmark.md +0 -67
  104. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs +0 -2407
  105. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs.map +0 -1
  106. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js +0 -2
  107. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js.map +0 -1
  108. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js +0 -2406
  109. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js.map +0 -1
  110. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js +0 -2
  111. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js.map +0 -1
  112. package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs +0 -3320
  113. package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs.map +0 -1
  114. package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js +0 -4540
  115. package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js.map +0 -1
  116. package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs +0 -1250
  117. package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs.map +0 -1
  118. package/lib/JAELIS-VM/node_modules/msgpackr/index.d.cts +0 -91
  119. package/lib/JAELIS-VM/node_modules/msgpackr/index.d.ts +0 -91
  120. package/lib/JAELIS-VM/node_modules/msgpackr/index.js +0 -5
  121. package/lib/JAELIS-VM/node_modules/msgpackr/iterators.js +0 -87
  122. package/lib/JAELIS-VM/node_modules/msgpackr/node-index.js +0 -25
  123. package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.cts +0 -1
  124. package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.ts +0 -1
  125. package/lib/JAELIS-VM/node_modules/msgpackr/pack.js +0 -1141
  126. package/lib/JAELIS-VM/node_modules/msgpackr/package.json +0 -104
  127. package/lib/JAELIS-VM/node_modules/msgpackr/rollup.config.js +0 -88
  128. package/lib/JAELIS-VM/node_modules/msgpackr/stream.js +0 -57
  129. package/lib/JAELIS-VM/node_modules/msgpackr/struct.js +0 -815
  130. package/lib/JAELIS-VM/node_modules/msgpackr/test-worker.js +0 -3
  131. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.cts +0 -2
  132. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.ts +0 -2
  133. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.js +0 -1221
  134. package/lib/JAELIS-VM/node_modules/msgpackr-extract/LICENSE +0 -21
  135. package/lib/JAELIS-VM/node_modules/msgpackr-extract/README.md +0 -5
  136. package/lib/JAELIS-VM/node_modules/msgpackr-extract/bin/download-prebuilds.js +0 -13
  137. package/lib/JAELIS-VM/node_modules/msgpackr-extract/binding.gyp +0 -63
  138. package/lib/JAELIS-VM/node_modules/msgpackr-extract/index.js +0 -1
  139. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages +0 -12
  140. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional +0 -12
  141. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +0 -17
  142. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +0 -28
  143. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test +0 -12
  144. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +0 -17
  145. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +0 -28
  146. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.cmd +0 -17
  147. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.ps1 +0 -28
  148. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/LICENSE +0 -21
  149. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/README.md +0 -58
  150. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/bin.js +0 -82
  151. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/build-test.js +0 -19
  152. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/index.js +0 -6
  153. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/node-gyp-build.js +0 -236
  154. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/optional.js +0 -7
  155. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/package.json +0 -32
  156. package/lib/JAELIS-VM/node_modules/msgpackr-extract/package.json +0 -50
  157. package/lib/JAELIS-VM/node_modules/msgpackr-extract/src/extract.cpp +0 -274
  158. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/LICENSE +0 -21
  159. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/README.md +0 -58
  160. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/bin.js +0 -77
  161. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/build-test.js +0 -19
  162. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/index.js +0 -224
  163. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/optional.js +0 -7
  164. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/package.json +0 -32
  165. package/lib/JAELIS-VM/package-lock.json +0 -284
  166. package/lib/JAELIS-VM/package.json +0 -38
  167. package/lib/JAELIS-VM/test/comprehensive.test.js +0 -267
  168. package/lib/JAELIS-VM/test/cross-chain-test.js +0 -470
  169. package/lib/JAELIS-VM/test/unified-vm-test.js +0 -459
  170. package/lib/JAELIS-VM/test/unified.test.js +0 -166
  171. package/lib/JAELIS-VM/test/vm.test.js +0 -599
  172. package/lib/settlement-server.js +0 -999
  173. package/lib/vm/index.js +0 -397
@@ -1,1183 +0,0 @@
1
- /**
2
- * JAELIS EXECUTION ENGINE
3
- *
4
- * Executes JIR bytecode using multiple execution strategies:
5
- * - Interpreter: Development/debugging (baseline)
6
- * - AOT Compiler: Production (10x faster)
7
- * - JIT Compiler: Hot path optimization
8
- *
9
- * Features:
10
- * - WASM 3.0 compatible (64-bit, GC, threads)
11
- * - Deterministic execution
12
- * - Gas/Lode metering
13
- * - Cross-VM state access
14
- *
15
- * @version 0.1.0
16
- * @author Mario Papaleo - JAELIS Foundation
17
- */
18
-
19
- const EventEmitter = require('events');
20
- const crypto = require('crypto');
21
-
22
- // Import opcodes from compiler
23
- const JIR_OPCODES = {
24
- NOP: 0x00, BLOCK: 0x01, LOOP: 0x02, IF: 0x03, ELSE: 0x04, END: 0x05,
25
- BR: 0x06, BR_IF: 0x07, RETURN: 0x08, CALL: 0x09, CALL_INDIRECT: 0x0A,
26
- DROP: 0x10, SELECT: 0x11, LOCAL_GET: 0x12, LOCAL_SET: 0x13, LOCAL_TEE: 0x14,
27
- GLOBAL_GET: 0x15, GLOBAL_SET: 0x16,
28
- I32_LOAD: 0x20, I64_LOAD: 0x21, F32_LOAD: 0x22, F64_LOAD: 0x23,
29
- I32_STORE: 0x24, I64_STORE: 0x25, F32_STORE: 0x26, F64_STORE: 0x27,
30
- MEMORY_SIZE: 0x28, MEMORY_GROW: 0x29, MEMORY_COPY: 0x2A, MEMORY_FILL: 0x2B,
31
- I32_CONST: 0x30, I64_CONST: 0x31, F32_CONST: 0x32, F64_CONST: 0x33,
32
- I32_ADD: 0x34, I32_SUB: 0x35, I32_MUL: 0x36, I32_DIV_S: 0x37, I32_DIV_U: 0x38,
33
- I64_ADD: 0x39, I64_SUB: 0x3A, I64_MUL: 0x3B, I64_DIV_S: 0x3C, I64_DIV_U: 0x3D,
34
- I32_EQ: 0x40, I32_NE: 0x41, I32_LT_S: 0x42, I32_LT_U: 0x43,
35
- I32_GT_S: 0x44, I32_GT_U: 0x45, I32_LE_S: 0x46, I32_LE_U: 0x47,
36
- I32_GE_S: 0x48, I32_GE_U: 0x49, I64_EQ: 0x4A, I64_NE: 0x4B,
37
- I32_AND: 0x50, I32_OR: 0x51, I32_XOR: 0x52, I32_SHL: 0x53,
38
- I32_SHR_S: 0x54, I32_SHR_U: 0x55, I64_AND: 0x56, I64_OR: 0x57, I64_XOR: 0x58,
39
- REF_NULL: 0x60, REF_IS_NULL: 0x61, REF_FUNC: 0x62,
40
- STRUCT_NEW: 0x63, STRUCT_GET: 0x64, STRUCT_SET: 0x65,
41
- ARRAY_NEW: 0x66, ARRAY_GET: 0x67, ARRAY_SET: 0x68, ARRAY_LEN: 0x69,
42
- ATOMIC_LOAD: 0x70, ATOMIC_STORE: 0x71, ATOMIC_ADD: 0x72, ATOMIC_SUB: 0x73,
43
- ATOMIC_AND: 0x74, ATOMIC_OR: 0x75, ATOMIC_XOR: 0x76, ATOMIC_CMPXCHG: 0x77,
44
- ATOMIC_WAIT: 0x78, ATOMIC_NOTIFY: 0x79,
45
- SLOAD: 0x80, SSTORE: 0x81, SLOAD_EXT: 0x82, SSTORE_EXT: 0x83,
46
- BALANCE: 0x84, TRANSFER: 0x85, TRANSFER_TOKEN: 0x86,
47
- CONTRACT_CALL: 0x87, DELEGATE_CALL: 0x88, STATIC_CALL: 0x89,
48
- CREATE: 0x8A, CREATE2: 0x8B, SELFDESTRUCT: 0x8C,
49
- CALLER: 0x90, ORIGIN: 0x91, CALLVALUE: 0x92, CALLDATA: 0x93,
50
- CALLDATASIZE: 0x94, RETURNDATASIZE: 0x95, RETURNDATACOPY: 0x96,
51
- BLOCKHASH: 0xA0, COINBASE: 0xA1, TIMESTAMP: 0xA2, BLOCKNUMBER: 0xA3,
52
- DIFFICULTY: 0xA4, GASLIMIT: 0xA5, CHAINID: 0xA6, SELFBALANCE: 0xA7, BASEFEE: 0xA8,
53
- SHA256: 0xB0, KECCAK256: 0xB1, BLAKE2B: 0xB2, BLAKE3: 0xB3,
54
- POSEIDON: 0xB4, ECRECOVER: 0xB5, ECADD: 0xB6, ECMUL: 0xB7,
55
- ECPAIRING: 0xB8, ED25519_VERIFY: 0xB9,
56
- LOG0: 0xC0, LOG1: 0xC1, LOG2: 0xC2, LOG3: 0xC3, LOG4: 0xC4,
57
- CROSS_VM_CALL: 0xD0, CROSS_VM_TRANSFER: 0xD1, CROSS_VM_STATE: 0xD2,
58
- BRIDGE_LOCK: 0xD3, BRIDGE_UNLOCK: 0xD4, BRIDGE_MINT: 0xD5, BRIDGE_BURN: 0xD6,
59
- GAS: 0xE0, LODE_SIGNAL: 0xE1, METER_START: 0xE2, METER_END: 0xE3,
60
- DEBUG_PRINT: 0xF0, DEBUG_BREAK: 0xF1, DEBUG_TRACE: 0xF2,
61
- REVERT: 0xFE, HALT: 0xFF
62
- };
63
-
64
- // Gas costs for each opcode (for metering)
65
- const GAS_COSTS = {
66
- [JIR_OPCODES.NOP]: 1,
67
- [JIR_OPCODES.I32_ADD]: 3,
68
- [JIR_OPCODES.I32_SUB]: 3,
69
- [JIR_OPCODES.I32_MUL]: 5,
70
- [JIR_OPCODES.I32_DIV_S]: 8,
71
- [JIR_OPCODES.I64_ADD]: 3,
72
- [JIR_OPCODES.I64_SUB]: 3,
73
- [JIR_OPCODES.I64_MUL]: 5,
74
- [JIR_OPCODES.I64_DIV_S]: 8,
75
- [JIR_OPCODES.SLOAD]: 100,
76
- [JIR_OPCODES.SSTORE]: 20000,
77
- [JIR_OPCODES.CONTRACT_CALL]: 700,
78
- [JIR_OPCODES.CREATE]: 32000,
79
- [JIR_OPCODES.CREATE2]: 32000,
80
- [JIR_OPCODES.KECCAK256]: 30,
81
- [JIR_OPCODES.SHA256]: 60,
82
- [JIR_OPCODES.TRANSFER]: 2100,
83
- [JIR_OPCODES.LOG0]: 375,
84
- [JIR_OPCODES.LOG1]: 750,
85
- [JIR_OPCODES.LOG2]: 1125,
86
- [JIR_OPCODES.CROSS_VM_CALL]: 5000,
87
- default: 3
88
- };
89
-
90
- /**
91
- * Stack Frame for execution
92
- */
93
- class StackFrame {
94
- constructor(functionIndex, returnPC, locals = []) {
95
- this.functionIndex = functionIndex;
96
- this.returnPC = returnPC;
97
- this.locals = locals;
98
- this.operandStack = [];
99
- this.blockStack = []; // For structured control flow
100
- }
101
-
102
- push(value) {
103
- this.operandStack.push(value);
104
- }
105
-
106
- pop() {
107
- if (this.operandStack.length === 0) {
108
- throw new Error('Stack underflow');
109
- }
110
- return this.operandStack.pop();
111
- }
112
-
113
- peek() {
114
- return this.operandStack[this.operandStack.length - 1];
115
- }
116
-
117
- getLocal(index) {
118
- return this.locals[index];
119
- }
120
-
121
- setLocal(index, value) {
122
- this.locals[index] = value;
123
- }
124
- }
125
-
126
- /**
127
- * JAELIS Execution Engine
128
- *
129
- * Supports three execution modes:
130
- * 1. Interpreter - Step-by-step execution (good for debugging)
131
- * 2. AOT - Ahead-of-time compilation (fastest for production)
132
- * 3. JIT - Just-in-time compilation (optimizes hot paths)
133
- */
134
- class ExecutionEngine extends EventEmitter {
135
- constructor(config = {}) {
136
- super();
137
-
138
- this.config = {
139
- executionMode: config.executionMode || 'interpreter',
140
- maxMemory: config.maxMemory || 1024 * 1024 * 1024, // 1GB
141
- maxStack: config.maxStack || 1024 * 1024 * 64, // 64MB
142
- maxHeap: config.maxHeap || 1024 * 1024 * 512, // 512MB
143
- maxInstructions: config.maxInstructions || 100000000, // 100M
144
- meteringEnabled: config.meteringEnabled !== false,
145
- debug: config.debug || false,
146
- trace: config.trace || false,
147
- ...config
148
- };
149
-
150
- // Memory (64-bit addressable!)
151
- this.memory = null;
152
- this.memorySize = 0;
153
-
154
- // Heap for GC-managed objects
155
- this.heap = new Map();
156
- this.heapNextId = 1;
157
-
158
- // Globals
159
- this.globals = new Map();
160
-
161
- // Tables (function references)
162
- this.tables = [];
163
-
164
- // Call stack
165
- this.callStack = [];
166
-
167
- // Execution state
168
- this.pc = 0; // Program counter
169
- this.running = false;
170
- this.halted = false;
171
-
172
- // Metering
173
- this.instructionsExecuted = 0;
174
- this.gasUsed = 0;
175
- this.gasLimit = 0;
176
-
177
- // Execution context (blockchain-specific)
178
- this.context = null;
179
-
180
- // State changes for rollback
181
- this.stateChanges = [];
182
- this.logs = [];
183
-
184
- // AOT compiled functions cache
185
- this.aotCache = new Map();
186
-
187
- // JIT hot path detection
188
- this.jitStats = new Map();
189
- this.jitThreshold = 100; // Compile after 100 calls
190
-
191
- // Host functions (blockchain operations)
192
- this.hostFunctions = new Map();
193
- this._registerHostFunctions();
194
-
195
- console.log(`[Engine] Initialized in ${this.config.executionMode.toUpperCase()} mode`);
196
- }
197
-
198
- /**
199
- * Execute a JIR module
200
- *
201
- * @param {object} jir - Compiled JIR module
202
- * @param {string} functionName - Function to execute
203
- * @param {Buffer} args - Serialized arguments
204
- * @param {object} context - Execution context
205
- * @returns {object} Execution result
206
- */
207
- async execute(jir, functionName, args, context = {}) {
208
- const startTime = Date.now();
209
-
210
- // Reset state
211
- this._reset();
212
-
213
- // Setup context
214
- this.context = {
215
- caller: context.caller || '0x0000000000000000000000000000000000000000',
216
- origin: context.origin || context.caller || '0x0000000000000000000000000000000000000000',
217
- value: BigInt(context.value || 0),
218
- gasLimit: context.gasLimit || this.config.maxInstructions,
219
- blockNumber: context.blockNumber || 0,
220
- timestamp: context.timestamp || Math.floor(Date.now() / 1000),
221
- chainId: context.chainId || 4545,
222
- address: context.address || '0x0000000000000000000000000000000000000000',
223
- ...context
224
- };
225
-
226
- this.gasLimit = this.context.gasLimit;
227
-
228
- // Initialize memory
229
- this._initMemory(jir.memory);
230
-
231
- // Load globals
232
- this._loadGlobals(jir.globals);
233
-
234
- // Load data sections
235
- this._loadData(jir.data);
236
-
237
- // Find function
238
- const funcIndex = jir.exports.findIndex(e => e.name === functionName && e.kind === 'function');
239
- if (funcIndex === -1) {
240
- throw new Error(`Function not found: ${functionName}`);
241
- }
242
-
243
- const func = jir.functions[jir.exports[funcIndex].index];
244
- if (!func) {
245
- throw new Error(`Function index out of bounds: ${jir.exports[funcIndex].index}`);
246
- }
247
-
248
- // Prepare arguments
249
- const parsedArgs = this._parseArguments(args, func.params);
250
-
251
- // Execute based on mode
252
- let result;
253
- switch (this.config.executionMode) {
254
- case 'aot':
255
- result = await this._executeAOT(jir, func, parsedArgs);
256
- break;
257
- case 'jit':
258
- result = await this._executeJIT(jir, func, parsedArgs);
259
- break;
260
- case 'interpreter':
261
- default:
262
- result = await this._executeInterpreter(jir, func, parsedArgs);
263
- break;
264
- }
265
-
266
- const executionTime = Date.now() - startTime;
267
-
268
- return {
269
- success: !this.halted || result.success !== false,
270
- returnData: result.returnData || Buffer.alloc(0),
271
- instructionsUsed: this.instructionsExecuted,
272
- gasUsed: this.gasUsed,
273
- executionTime,
274
- logs: this.logs,
275
- stateChanges: this.stateChanges
276
- };
277
- }
278
-
279
- // ═══════════════════════════════════════════════════════════════
280
- // INTERPRETER MODE
281
- // ═══════════════════════════════════════════════════════════════
282
-
283
- async _executeInterpreter(jir, func, args) {
284
- if (this.config.debug) {
285
- console.log(`[Engine] Interpreting function: ${func.name}`);
286
- }
287
-
288
- // Create initial stack frame
289
- const frame = new StackFrame(0, -1, [...args]);
290
- this.callStack.push(frame);
291
-
292
- // Get bytecode
293
- const bytecode = jir.bytecode;
294
- this.pc = this._findFunctionOffset(jir, func);
295
-
296
- this.running = true;
297
-
298
- while (this.running && !this.halted) {
299
- // Check limits
300
- if (this.config.meteringEnabled && this.instructionsExecuted >= this.gasLimit) {
301
- throw new Error('Out of gas');
302
- }
303
-
304
- if (this.pc >= bytecode.length) {
305
- break;
306
- }
307
-
308
- const opcode = bytecode[this.pc];
309
-
310
- // Trace execution
311
- if (this.config.trace) {
312
- console.log(`[Trace] PC=${this.pc} OP=0x${opcode.toString(16)} Stack=${frame.operandStack.length}`);
313
- }
314
-
315
- // Execute opcode
316
- await this._executeOpcode(opcode, bytecode, jir);
317
-
318
- // Update metrics
319
- this.instructionsExecuted++;
320
- this.gasUsed += GAS_COSTS[opcode] || GAS_COSTS.default;
321
- }
322
-
323
- // Get return value
324
- const returnValue = frame.operandStack.length > 0 ? frame.pop() : null;
325
-
326
- return {
327
- success: !this.halted,
328
- returnData: this._serializeReturn(returnValue)
329
- };
330
- }
331
-
332
- async _executeOpcode(opcode, bytecode, jir) {
333
- const frame = this.callStack[this.callStack.length - 1];
334
-
335
- switch (opcode) {
336
- // ═══════════════════════════════════════════════════════════════
337
- // CONTROL FLOW
338
- // ═══════════════════════════════════════════════════════════════
339
-
340
- case JIR_OPCODES.NOP:
341
- this.pc++;
342
- break;
343
-
344
- case JIR_OPCODES.BLOCK:
345
- frame.blockStack.push({ type: 'block', pc: this.pc });
346
- this.pc++;
347
- break;
348
-
349
- case JIR_OPCODES.LOOP:
350
- frame.blockStack.push({ type: 'loop', pc: this.pc });
351
- this.pc++;
352
- break;
353
-
354
- case JIR_OPCODES.IF:
355
- const condition = frame.pop();
356
- if (condition) {
357
- frame.blockStack.push({ type: 'if', pc: this.pc });
358
- this.pc++;
359
- } else {
360
- // Jump to else or end
361
- this.pc = this._findElseOrEnd(bytecode, this.pc);
362
- }
363
- break;
364
-
365
- case JIR_OPCODES.ELSE:
366
- // Skip to end
367
- this.pc = this._findEnd(bytecode, this.pc);
368
- break;
369
-
370
- case JIR_OPCODES.END:
371
- if (frame.blockStack.length > 0) {
372
- frame.blockStack.pop();
373
- }
374
- this.pc++;
375
- break;
376
-
377
- case JIR_OPCODES.BR:
378
- const depth1 = bytecode[++this.pc];
379
- this._branch(depth1, frame);
380
- break;
381
-
382
- case JIR_OPCODES.BR_IF:
383
- const depth2 = bytecode[++this.pc];
384
- if (frame.pop()) {
385
- this._branch(depth2, frame);
386
- } else {
387
- this.pc++;
388
- }
389
- break;
390
-
391
- case JIR_OPCODES.RETURN:
392
- if (this.callStack.length <= 1) {
393
- this.running = false;
394
- } else {
395
- const returnValue = frame.operandStack.length > 0 ? frame.pop() : null;
396
- this.callStack.pop();
397
- const parentFrame = this.callStack[this.callStack.length - 1];
398
- if (returnValue !== null) {
399
- parentFrame.push(returnValue);
400
- }
401
- this.pc = frame.returnPC;
402
- }
403
- break;
404
-
405
- case JIR_OPCODES.CALL:
406
- const funcIdx = bytecode[++this.pc];
407
- await this._call(funcIdx, jir);
408
- break;
409
-
410
- case JIR_OPCODES.CALL_INDIRECT:
411
- const tableIdx = bytecode[++this.pc];
412
- const funcTypeIdx = bytecode[++this.pc];
413
- const funcRef = frame.pop();
414
- await this._callIndirect(tableIdx, funcTypeIdx, funcRef, jir);
415
- break;
416
-
417
- // ═══════════════════════════════════════════════════════════════
418
- // STACK OPERATIONS
419
- // ═══════════════════════════════════════════════════════════════
420
-
421
- case JIR_OPCODES.DROP:
422
- frame.pop();
423
- this.pc++;
424
- break;
425
-
426
- case JIR_OPCODES.SELECT:
427
- const cond = frame.pop();
428
- const val2 = frame.pop();
429
- const val1 = frame.pop();
430
- frame.push(cond ? val1 : val2);
431
- this.pc++;
432
- break;
433
-
434
- case JIR_OPCODES.LOCAL_GET:
435
- const localIdx1 = bytecode[++this.pc];
436
- frame.push(frame.getLocal(localIdx1));
437
- this.pc++;
438
- break;
439
-
440
- case JIR_OPCODES.LOCAL_SET:
441
- const localIdx2 = bytecode[++this.pc];
442
- frame.setLocal(localIdx2, frame.pop());
443
- this.pc++;
444
- break;
445
-
446
- case JIR_OPCODES.LOCAL_TEE:
447
- const localIdx3 = bytecode[++this.pc];
448
- frame.setLocal(localIdx3, frame.peek());
449
- this.pc++;
450
- break;
451
-
452
- case JIR_OPCODES.GLOBAL_GET:
453
- const globalIdx1 = bytecode[++this.pc];
454
- frame.push(this.globals.get(globalIdx1) || 0);
455
- this.pc++;
456
- break;
457
-
458
- case JIR_OPCODES.GLOBAL_SET:
459
- const globalIdx2 = bytecode[++this.pc];
460
- this.globals.set(globalIdx2, frame.pop());
461
- this.pc++;
462
- break;
463
-
464
- // ═══════════════════════════════════════════════════════════════
465
- // MEMORY OPERATIONS (64-bit addressing)
466
- // ═══════════════════════════════════════════════════════════════
467
-
468
- case JIR_OPCODES.I32_LOAD:
469
- const addr1 = Number(frame.pop());
470
- frame.push(this.memory.readInt32LE(addr1));
471
- this.pc++;
472
- break;
473
-
474
- case JIR_OPCODES.I64_LOAD:
475
- const addr2 = Number(frame.pop());
476
- frame.push(this.memory.readBigInt64LE(addr2));
477
- this.pc++;
478
- break;
479
-
480
- case JIR_OPCODES.I32_STORE:
481
- const val_store1 = frame.pop();
482
- const addr_store1 = Number(frame.pop());
483
- this.memory.writeInt32LE(val_store1, addr_store1);
484
- this.pc++;
485
- break;
486
-
487
- case JIR_OPCODES.I64_STORE:
488
- const val_store2 = frame.pop();
489
- const addr_store2 = Number(frame.pop());
490
- this.memory.writeBigInt64LE(BigInt(val_store2), addr_store2);
491
- this.pc++;
492
- break;
493
-
494
- case JIR_OPCODES.MEMORY_SIZE:
495
- frame.push(Math.floor(this.memorySize / 65536)); // Return in pages
496
- this.pc++;
497
- break;
498
-
499
- case JIR_OPCODES.MEMORY_GROW:
500
- const pages = frame.pop();
501
- const oldSize = Math.floor(this.memorySize / 65536);
502
- const newSize = this.memorySize + (pages * 65536);
503
- if (newSize <= this.config.maxMemory) {
504
- const newMemory = Buffer.alloc(newSize);
505
- this.memory.copy(newMemory);
506
- this.memory = newMemory;
507
- this.memorySize = newSize;
508
- frame.push(oldSize);
509
- } else {
510
- frame.push(-1); // Failed
511
- }
512
- this.pc++;
513
- break;
514
-
515
- // ═══════════════════════════════════════════════════════════════
516
- // NUMERIC OPERATIONS
517
- // ═══════════════════════════════════════════════════════════════
518
-
519
- case JIR_OPCODES.I32_CONST:
520
- const i32val = bytecode.readInt32LE(++this.pc);
521
- frame.push(i32val);
522
- this.pc += 4;
523
- break;
524
-
525
- case JIR_OPCODES.I64_CONST:
526
- const i64val = bytecode.readBigInt64LE(++this.pc);
527
- frame.push(i64val);
528
- this.pc += 8;
529
- break;
530
-
531
- case JIR_OPCODES.I32_ADD:
532
- frame.push((frame.pop() + frame.pop()) | 0);
533
- this.pc++;
534
- break;
535
-
536
- case JIR_OPCODES.I32_SUB:
537
- const sub2 = frame.pop();
538
- const sub1 = frame.pop();
539
- frame.push((sub1 - sub2) | 0);
540
- this.pc++;
541
- break;
542
-
543
- case JIR_OPCODES.I32_MUL:
544
- frame.push(Math.imul(frame.pop(), frame.pop()));
545
- this.pc++;
546
- break;
547
-
548
- case JIR_OPCODES.I32_DIV_S:
549
- const div2 = frame.pop();
550
- const div1 = frame.pop();
551
- if (div2 === 0) throw new Error('Division by zero');
552
- frame.push((div1 / div2) | 0);
553
- this.pc++;
554
- break;
555
-
556
- case JIR_OPCODES.I64_ADD:
557
- frame.push(BigInt(frame.pop()) + BigInt(frame.pop()));
558
- this.pc++;
559
- break;
560
-
561
- case JIR_OPCODES.I64_SUB:
562
- const lsub2 = BigInt(frame.pop());
563
- const lsub1 = BigInt(frame.pop());
564
- frame.push(lsub1 - lsub2);
565
- this.pc++;
566
- break;
567
-
568
- case JIR_OPCODES.I64_MUL:
569
- frame.push(BigInt(frame.pop()) * BigInt(frame.pop()));
570
- this.pc++;
571
- break;
572
-
573
- // ═══════════════════════════════════════════════════════════════
574
- // COMPARISON OPERATIONS
575
- // ═══════════════════════════════════════════════════════════════
576
-
577
- case JIR_OPCODES.I32_EQ:
578
- frame.push(frame.pop() === frame.pop() ? 1 : 0);
579
- this.pc++;
580
- break;
581
-
582
- case JIR_OPCODES.I32_NE:
583
- frame.push(frame.pop() !== frame.pop() ? 1 : 0);
584
- this.pc++;
585
- break;
586
-
587
- case JIR_OPCODES.I32_LT_S:
588
- const lt2 = frame.pop();
589
- const lt1 = frame.pop();
590
- frame.push(lt1 < lt2 ? 1 : 0);
591
- this.pc++;
592
- break;
593
-
594
- case JIR_OPCODES.I32_GT_S:
595
- const gt2 = frame.pop();
596
- const gt1 = frame.pop();
597
- frame.push(gt1 > gt2 ? 1 : 0);
598
- this.pc++;
599
- break;
600
-
601
- // ═══════════════════════════════════════════════════════════════
602
- // BITWISE OPERATIONS
603
- // ═══════════════════════════════════════════════════════════════
604
-
605
- case JIR_OPCODES.I32_AND:
606
- frame.push(frame.pop() & frame.pop());
607
- this.pc++;
608
- break;
609
-
610
- case JIR_OPCODES.I32_OR:
611
- frame.push(frame.pop() | frame.pop());
612
- this.pc++;
613
- break;
614
-
615
- case JIR_OPCODES.I32_XOR:
616
- frame.push(frame.pop() ^ frame.pop());
617
- this.pc++;
618
- break;
619
-
620
- case JIR_OPCODES.I32_SHL:
621
- const shl2 = frame.pop();
622
- const shl1 = frame.pop();
623
- frame.push(shl1 << shl2);
624
- this.pc++;
625
- break;
626
-
627
- case JIR_OPCODES.I32_SHR_S:
628
- const shr2 = frame.pop();
629
- const shr1 = frame.pop();
630
- frame.push(shr1 >> shr2);
631
- this.pc++;
632
- break;
633
-
634
- case JIR_OPCODES.I32_SHR_U:
635
- const shru2 = frame.pop();
636
- const shru1 = frame.pop();
637
- frame.push(shru1 >>> shru2);
638
- this.pc++;
639
- break;
640
-
641
- // ═══════════════════════════════════════════════════════════════
642
- // BLOCKCHAIN OPERATIONS
643
- // ═══════════════════════════════════════════════════════════════
644
-
645
- case JIR_OPCODES.SLOAD:
646
- const slot = frame.pop();
647
- const stored = await this._sload(slot);
648
- frame.push(stored);
649
- this.pc++;
650
- break;
651
-
652
- case JIR_OPCODES.SSTORE:
653
- const value = frame.pop();
654
- const key = frame.pop();
655
- await this._sstore(key, value);
656
- this.pc++;
657
- break;
658
-
659
- case JIR_OPCODES.BALANCE:
660
- const balAddr = frame.pop();
661
- const balance = await this._getBalance(balAddr);
662
- frame.push(balance);
663
- this.pc++;
664
- break;
665
-
666
- case JIR_OPCODES.TRANSFER:
667
- const amount = frame.pop();
668
- const toAddr = frame.pop();
669
- await this._transfer(toAddr, amount);
670
- this.pc++;
671
- break;
672
-
673
- case JIR_OPCODES.CONTRACT_CALL:
674
- const callGas = frame.pop();
675
- const callValue = frame.pop();
676
- const callTarget = frame.pop();
677
- const callData = this._popBytes(frame);
678
- const callResult = await this._contractCall(callTarget, callValue, callData, callGas);
679
- frame.push(callResult.success ? 1 : 0);
680
- this._pushBytes(frame, callResult.returnData);
681
- this.pc++;
682
- break;
683
-
684
- case JIR_OPCODES.CALLER:
685
- frame.push(this._addressToNum(this.context.caller));
686
- this.pc++;
687
- break;
688
-
689
- case JIR_OPCODES.ORIGIN:
690
- frame.push(this._addressToNum(this.context.origin));
691
- this.pc++;
692
- break;
693
-
694
- case JIR_OPCODES.CALLVALUE:
695
- frame.push(this.context.value);
696
- this.pc++;
697
- break;
698
-
699
- case JIR_OPCODES.TIMESTAMP:
700
- frame.push(this.context.timestamp);
701
- this.pc++;
702
- break;
703
-
704
- case JIR_OPCODES.BLOCKNUMBER:
705
- frame.push(this.context.blockNumber);
706
- this.pc++;
707
- break;
708
-
709
- case JIR_OPCODES.CHAINID:
710
- frame.push(this.context.chainId);
711
- this.pc++;
712
- break;
713
-
714
- // ═══════════════════════════════════════════════════════════════
715
- // CRYPTO OPERATIONS
716
- // ═══════════════════════════════════════════════════════════════
717
-
718
- case JIR_OPCODES.SHA256:
719
- const sha256Data = this._popBytes(frame);
720
- const sha256Hash = crypto.createHash('sha256').update(sha256Data).digest();
721
- this._pushBytes(frame, sha256Hash);
722
- this.pc++;
723
- break;
724
-
725
- case JIR_OPCODES.KECCAK256:
726
- const keccakData = this._popBytes(frame);
727
- // Using sha3-256 as a placeholder (proper keccak would need external lib)
728
- const keccakHash = crypto.createHash('sha3-256').update(keccakData).digest();
729
- this._pushBytes(frame, keccakHash);
730
- this.pc++;
731
- break;
732
-
733
- // ═══════════════════════════════════════════════════════════════
734
- // LOGGING
735
- // ═══════════════════════════════════════════════════════════════
736
-
737
- case JIR_OPCODES.LOG0:
738
- case JIR_OPCODES.LOG1:
739
- case JIR_OPCODES.LOG2:
740
- case JIR_OPCODES.LOG3:
741
- case JIR_OPCODES.LOG4:
742
- const numTopics = opcode - JIR_OPCODES.LOG0;
743
- const logData = this._popBytes(frame);
744
- const topics = [];
745
- for (let i = 0; i < numTopics; i++) {
746
- topics.push(frame.pop());
747
- }
748
- this.logs.push({
749
- address: this.context.address,
750
- topics,
751
- data: logData
752
- });
753
- this.pc++;
754
- break;
755
-
756
- // ═══════════════════════════════════════════════════════════════
757
- // CROSS-VM OPERATIONS (JAELIS SPECIFIC!)
758
- // ═══════════════════════════════════════════════════════════════
759
-
760
- case JIR_OPCODES.CROSS_VM_CALL:
761
- const targetVM = frame.pop(); // Target VM type
762
- const targetAddr = frame.pop(); // Target address
763
- const crossCallData = this._popBytes(frame);
764
- const crossResult = await this._crossVMCall(targetVM, targetAddr, crossCallData);
765
- frame.push(crossResult.success ? 1 : 0);
766
- this._pushBytes(frame, crossResult.returnData);
767
- this.pc++;
768
- break;
769
-
770
- case JIR_OPCODES.CROSS_VM_STATE:
771
- const stateVM = frame.pop();
772
- const stateAddr = frame.pop();
773
- const stateSlot = frame.pop();
774
- const stateValue = await this._crossVMState(stateVM, stateAddr, stateSlot);
775
- frame.push(stateValue);
776
- this.pc++;
777
- break;
778
-
779
- // ═══════════════════════════════════════════════════════════════
780
- // METERING
781
- // ═══════════════════════════════════════════════════════════════
782
-
783
- case JIR_OPCODES.GAS:
784
- frame.push(this.gasLimit - this.gasUsed);
785
- this.pc++;
786
- break;
787
-
788
- case JIR_OPCODES.LODE_SIGNAL:
789
- frame.push(0); // JAELIS is zero-fee!
790
- this.pc++;
791
- break;
792
-
793
- // ═══════════════════════════════════════════════════════════════
794
- // DEBUG
795
- // ═══════════════════════════════════════════════════════════════
796
-
797
- case JIR_OPCODES.DEBUG_PRINT:
798
- if (this.config.debug) {
799
- const printVal = frame.pop();
800
- console.log(`[DEBUG] ${printVal}`);
801
- }
802
- this.pc++;
803
- break;
804
-
805
- // ═══════════════════════════════════════════════════════════════
806
- // HALT
807
- // ═══════════════════════════════════════════════════════════════
808
-
809
- case JIR_OPCODES.REVERT:
810
- this.halted = true;
811
- this.running = false;
812
- break;
813
-
814
- case JIR_OPCODES.HALT:
815
- this.running = false;
816
- break;
817
-
818
- default:
819
- if (this.config.debug) {
820
- console.log(`[Engine] Unknown opcode: 0x${opcode.toString(16)}`);
821
- }
822
- this.pc++;
823
- break;
824
- }
825
- }
826
-
827
- // ═══════════════════════════════════════════════════════════════
828
- // AOT MODE (Ahead-of-Time Compilation)
829
- // ═══════════════════════════════════════════════════════════════
830
-
831
- async _executeAOT(jir, func, args) {
832
- const cacheKey = `${jir.metadata.sourceHash}:${func.name}`;
833
-
834
- // Check cache
835
- if (!this.aotCache.has(cacheKey)) {
836
- // Compile to native JavaScript
837
- const compiled = this._compileToJS(jir, func);
838
- this.aotCache.set(cacheKey, compiled);
839
- }
840
-
841
- const compiledFunc = this.aotCache.get(cacheKey);
842
-
843
- // Execute compiled function
844
- const result = await compiledFunc.call(this, args, this.context);
845
-
846
- return {
847
- success: true,
848
- returnData: this._serializeReturn(result)
849
- };
850
- }
851
-
852
- _compileToJS(jir, func) {
853
- // Generate JavaScript code from JIR
854
- // This is a simplified version - real AOT would be much more sophisticated
855
-
856
- const jsCode = `
857
- return async function(args, context) {
858
- // Compiled function: ${func.name}
859
- const locals = [...args];
860
- let result = 0;
861
-
862
- // Function body would be generated here
863
- // based on the JIR bytecode
864
-
865
- return result;
866
- }
867
- `;
868
-
869
- return new Function(jsCode)();
870
- }
871
-
872
- // ═══════════════════════════════════════════════════════════════
873
- // JIT MODE (Just-in-Time Compilation)
874
- // ═══════════════════════════════════════════════════════════════
875
-
876
- async _executeJIT(jir, func, args) {
877
- const cacheKey = `${jir.metadata.sourceHash}:${func.name}`;
878
-
879
- // Track execution counts
880
- const stats = this.jitStats.get(cacheKey) || { count: 0, compiled: false };
881
- stats.count++;
882
- this.jitStats.set(cacheKey, stats);
883
-
884
- // If hot, compile
885
- if (stats.count >= this.jitThreshold && !stats.compiled) {
886
- console.log(`[JIT] Compiling hot function: ${func.name}`);
887
- const compiled = this._compileToJS(jir, func);
888
- this.aotCache.set(cacheKey, compiled);
889
- stats.compiled = true;
890
- }
891
-
892
- // Execute (compiled if available, otherwise interpreted)
893
- if (stats.compiled) {
894
- return this._executeAOT(jir, func, args);
895
- } else {
896
- return this._executeInterpreter(jir, func, args);
897
- }
898
- }
899
-
900
- // ═══════════════════════════════════════════════════════════════
901
- // HELPER METHODS
902
- // ═══════════════════════════════════════════════════════════════
903
-
904
- _reset() {
905
- this.memory = null;
906
- this.memorySize = 0;
907
- this.heap.clear();
908
- this.heapNextId = 1;
909
- this.globals.clear();
910
- this.callStack = [];
911
- this.pc = 0;
912
- this.running = false;
913
- this.halted = false;
914
- this.instructionsExecuted = 0;
915
- this.gasUsed = 0;
916
- this.stateChanges = [];
917
- this.logs = [];
918
- }
919
-
920
- _initMemory(memConfig) {
921
- const initialPages = memConfig?.initial || 1;
922
- this.memorySize = initialPages * 65536; // 64KB per page
923
- this.memory = Buffer.alloc(this.memorySize);
924
- }
925
-
926
- _loadGlobals(globals) {
927
- if (!globals) return;
928
- globals.forEach((g, i) => {
929
- this.globals.set(i, g.init || 0);
930
- });
931
- }
932
-
933
- _loadData(data) {
934
- if (!data) return;
935
- for (const segment of data) {
936
- if (segment.data && segment.offset !== undefined) {
937
- segment.data.copy(this.memory, segment.offset);
938
- }
939
- }
940
- }
941
-
942
- _findFunctionOffset(jir, func) {
943
- // Find the bytecode offset for the function
944
- // This is a simplified version
945
- return 4; // Skip magic number
946
- }
947
-
948
- _parseArguments(args, params) {
949
- // Parse serialized arguments based on function parameter types
950
- if (!args || args.length === 0) return [];
951
-
952
- // Simple parsing - would be more sophisticated with proper type handling
953
- try {
954
- if (Buffer.isBuffer(args)) {
955
- // Try to parse as CBOR or MessagePack
956
- return JSON.parse(args.toString());
957
- }
958
- return Array.isArray(args) ? args : [args];
959
- } catch (e) {
960
- return [];
961
- }
962
- }
963
-
964
- _serializeReturn(value) {
965
- if (value === null || value === undefined) {
966
- return Buffer.alloc(0);
967
- }
968
-
969
- if (Buffer.isBuffer(value)) {
970
- return value;
971
- }
972
-
973
- if (typeof value === 'bigint') {
974
- const buf = Buffer.alloc(32);
975
- let v = value;
976
- for (let i = 31; i >= 0 && v > 0n; i--) {
977
- buf[i] = Number(v & 0xffn);
978
- v >>= 8n;
979
- }
980
- return buf;
981
- }
982
-
983
- if (typeof value === 'number') {
984
- const buf = Buffer.alloc(8);
985
- buf.writeBigInt64LE(BigInt(value));
986
- return buf;
987
- }
988
-
989
- return Buffer.from(JSON.stringify(value));
990
- }
991
-
992
- _findElseOrEnd(bytecode, pc) {
993
- let depth = 1;
994
- let i = pc + 1;
995
- while (depth > 0 && i < bytecode.length) {
996
- if (bytecode[i] === JIR_OPCODES.IF || bytecode[i] === JIR_OPCODES.BLOCK || bytecode[i] === JIR_OPCODES.LOOP) {
997
- depth++;
998
- } else if (bytecode[i] === JIR_OPCODES.END) {
999
- depth--;
1000
- } else if (depth === 1 && bytecode[i] === JIR_OPCODES.ELSE) {
1001
- return i + 1;
1002
- }
1003
- i++;
1004
- }
1005
- return i;
1006
- }
1007
-
1008
- _findEnd(bytecode, pc) {
1009
- let depth = 1;
1010
- let i = pc + 1;
1011
- while (depth > 0 && i < bytecode.length) {
1012
- if (bytecode[i] === JIR_OPCODES.IF || bytecode[i] === JIR_OPCODES.BLOCK || bytecode[i] === JIR_OPCODES.LOOP) {
1013
- depth++;
1014
- } else if (bytecode[i] === JIR_OPCODES.END) {
1015
- depth--;
1016
- }
1017
- i++;
1018
- }
1019
- return i;
1020
- }
1021
-
1022
- _branch(depth, frame) {
1023
- // Branch to outer block
1024
- for (let i = 0; i < depth && frame.blockStack.length > 0; i++) {
1025
- frame.blockStack.pop();
1026
- }
1027
-
1028
- if (frame.blockStack.length > 0) {
1029
- const block = frame.blockStack[frame.blockStack.length - 1];
1030
- if (block.type === 'loop') {
1031
- this.pc = block.pc + 1; // Jump to loop start
1032
- } else {
1033
- // Jump to end of block
1034
- this.pc = this._findEnd(this.memory, block.pc);
1035
- }
1036
- } else {
1037
- this.running = false;
1038
- }
1039
- }
1040
-
1041
- async _call(funcIdx, jir) {
1042
- // Call another function
1043
- if (funcIdx < jir.functions.length) {
1044
- const func = jir.functions[funcIdx];
1045
- const frame = this.callStack[this.callStack.length - 1];
1046
-
1047
- // Pop arguments from caller's stack
1048
- const args = [];
1049
- for (let i = 0; i < (func.params?.length || 0); i++) {
1050
- args.unshift(frame.pop());
1051
- }
1052
-
1053
- // Create new frame
1054
- const newFrame = new StackFrame(funcIdx, this.pc + 1, args);
1055
- this.callStack.push(newFrame);
1056
-
1057
- // Jump to function
1058
- this.pc = this._findFunctionOffset(jir, func);
1059
- }
1060
- }
1061
-
1062
- async _callIndirect(tableIdx, typeIdx, funcRef, jir) {
1063
- // Indirect call through table
1064
- if (this.tables[tableIdx] && this.tables[tableIdx][funcRef]) {
1065
- await this._call(this.tables[tableIdx][funcRef], jir);
1066
- } else {
1067
- throw new Error('Invalid indirect call');
1068
- }
1069
- }
1070
-
1071
- _popBytes(frame) {
1072
- const size = Number(frame.pop());
1073
- const offset = Number(frame.pop());
1074
- return this.memory.slice(offset, offset + size);
1075
- }
1076
-
1077
- _pushBytes(frame, data) {
1078
- // Write to memory and push offset/size
1079
- const offset = this._allocateMemory(data.length);
1080
- data.copy(this.memory, offset);
1081
- frame.push(offset);
1082
- frame.push(data.length);
1083
- }
1084
-
1085
- _allocateMemory(size) {
1086
- // Simple bump allocator
1087
- const offset = this.heapNextId;
1088
- this.heapNextId += size;
1089
- if (this.heapNextId > this.memorySize) {
1090
- // Grow memory
1091
- const newSize = Math.min(this.memorySize * 2, this.config.maxMemory);
1092
- const newMemory = Buffer.alloc(newSize);
1093
- this.memory.copy(newMemory);
1094
- this.memory = newMemory;
1095
- this.memorySize = newSize;
1096
- }
1097
- return offset;
1098
- }
1099
-
1100
- _addressToNum(addr) {
1101
- // Convert address string to BigInt
1102
- if (typeof addr === 'string') {
1103
- return BigInt(addr);
1104
- }
1105
- return BigInt(addr);
1106
- }
1107
-
1108
- // ═══════════════════════════════════════════════════════════════
1109
- // BLOCKCHAIN HOST FUNCTIONS
1110
- // ═══════════════════════════════════════════════════════════════
1111
-
1112
- _registerHostFunctions() {
1113
- // Register blockchain operations as host functions
1114
- this.hostFunctions.set('sload', this._sload.bind(this));
1115
- this.hostFunctions.set('sstore', this._sstore.bind(this));
1116
- this.hostFunctions.set('balance', this._getBalance.bind(this));
1117
- this.hostFunctions.set('transfer', this._transfer.bind(this));
1118
- this.hostFunctions.set('call', this._contractCall.bind(this));
1119
- this.hostFunctions.set('crossVMCall', this._crossVMCall.bind(this));
1120
- }
1121
-
1122
- async _sload(slot) {
1123
- // Load from contract storage
1124
- // This would interface with StateManager
1125
- this.emit('sload', { address: this.context.address, slot });
1126
- return 0n; // Placeholder
1127
- }
1128
-
1129
- async _sstore(key, value) {
1130
- // Store to contract storage
1131
- this.stateChanges.push({
1132
- type: 'storage',
1133
- address: this.context.address,
1134
- key,
1135
- value
1136
- });
1137
- this.emit('sstore', { address: this.context.address, key, value });
1138
- }
1139
-
1140
- async _getBalance(address) {
1141
- // Get balance of address
1142
- this.emit('balance', { address });
1143
- return 0n; // Placeholder
1144
- }
1145
-
1146
- async _transfer(to, amount) {
1147
- // Transfer native token
1148
- this.stateChanges.push({
1149
- type: 'transfer',
1150
- from: this.context.caller,
1151
- to,
1152
- amount
1153
- });
1154
- this.emit('transfer', { from: this.context.caller, to, amount });
1155
- }
1156
-
1157
- async _contractCall(target, value, data, gas) {
1158
- // Call another contract
1159
- this.emit('call', { target, value, data, gas });
1160
- return {
1161
- success: true,
1162
- returnData: Buffer.alloc(0)
1163
- };
1164
- }
1165
-
1166
- async _crossVMCall(targetVM, targetAddr, data) {
1167
- // Cross-VM call (JAELIS specific!)
1168
- console.log(`[Engine] Cross-VM call to VM=${targetVM} addr=${targetAddr}`);
1169
- this.emit('crossVMCall', { targetVM, targetAddr, data });
1170
- return {
1171
- success: true,
1172
- returnData: Buffer.alloc(0)
1173
- };
1174
- }
1175
-
1176
- async _crossVMState(vm, addr, slot) {
1177
- // Read state from another VM's contract
1178
- this.emit('crossVMState', { vm, addr, slot });
1179
- return 0n; // Placeholder
1180
- }
1181
- }
1182
-
1183
- module.exports = ExecutionEngine;