@divmain/jdm-asm 0.2.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 (397) hide show
  1. package/.github/workflows/ci.yml +53 -0
  2. package/.oxfmtrc.json +16 -0
  3. package/.oxlintrc.json +183 -0
  4. package/AGENTS.md +81 -0
  5. package/README.md +769 -0
  6. package/asconfig.json +23 -0
  7. package/benchmarks/fixtures.ts +111 -0
  8. package/benchmarks/input-fixtures.ts +80 -0
  9. package/benchmarks/run.ts +913 -0
  10. package/benchmarks/worker-pool.ts +223 -0
  11. package/benchmarks/worker.ts +374 -0
  12. package/dist/index.d.ts +996 -0
  13. package/dist/index.js +12239 -0
  14. package/dist/index.js.map +1 -0
  15. package/package.json +49 -0
  16. package/scripts/run-all-tests.ts +220 -0
  17. package/src/compiler/EXPRESSION_SUBSETS.md +228 -0
  18. package/src/compiler/asc-compiler.ts +315 -0
  19. package/src/compiler/ast-types.ts +215 -0
  20. package/src/compiler/build.ts +56 -0
  21. package/src/compiler/cache.ts +414 -0
  22. package/src/compiler/code-generators.ts +211 -0
  23. package/src/compiler/codegen/index.ts +15 -0
  24. package/src/compiler/codegen/js-marshal.ts +999 -0
  25. package/src/compiler/codegen/js-validation.ts +243 -0
  26. package/src/compiler/codegen.ts +19 -0
  27. package/src/compiler/compile-time-validation.ts +507 -0
  28. package/src/compiler/cst-visitor.ts +434 -0
  29. package/src/compiler/errors.ts +227 -0
  30. package/src/compiler/expression-parser.ts +536 -0
  31. package/src/compiler/graph.ts +197 -0
  32. package/src/compiler/index.ts +199 -0
  33. package/src/compiler/input-validation.ts +33 -0
  34. package/src/compiler/marshal-gen.ts +21 -0
  35. package/src/compiler/nodes/context-resolvers.ts +197 -0
  36. package/src/compiler/nodes/decision-table.ts +507 -0
  37. package/src/compiler/nodes/decision.ts +292 -0
  38. package/src/compiler/nodes/expression-compiler.ts +526 -0
  39. package/src/compiler/nodes/expression.ts +425 -0
  40. package/src/compiler/nodes/function.ts +316 -0
  41. package/src/compiler/nodes/input.ts +60 -0
  42. package/src/compiler/nodes/switch.ts +547 -0
  43. package/src/compiler/optimizer.ts +948 -0
  44. package/src/compiler/orchestrator.ts +352 -0
  45. package/src/compiler/parser.ts +115 -0
  46. package/src/compiler/result-selection.ts +161 -0
  47. package/src/compiler/runtime/index.ts +26 -0
  48. package/src/compiler/runtime-codegen.ts +211 -0
  49. package/src/compiler/runtime-validation-codegen.ts +294 -0
  50. package/src/compiler/runtime.ts +452 -0
  51. package/src/compiler/schema.ts +245 -0
  52. package/src/compiler/switch-branch-detection.ts +92 -0
  53. package/src/compiler/types.ts +136 -0
  54. package/src/compiler/unary-ast-transforms.ts +148 -0
  55. package/src/compiler/unary-parser.ts +301 -0
  56. package/src/compiler/unary-transform.ts +161 -0
  57. package/src/compiler/utils.ts +27 -0
  58. package/src/compiler/virtual-fs.ts +90 -0
  59. package/src/compiler/wasm-instantiate.ts +127 -0
  60. package/src/index.ts +1 -0
  61. package/src/runtime/arrays.ts +579 -0
  62. package/src/runtime/context.ts +189 -0
  63. package/src/runtime/expressions.ts +1811 -0
  64. package/src/runtime/index.ts +8 -0
  65. package/src/runtime/memory.ts +607 -0
  66. package/src/runtime/strings.ts +260 -0
  67. package/src/runtime/tables.ts +96 -0
  68. package/src/runtime/tsconfig.json +4 -0
  69. package/src/runtime/values.ts +209 -0
  70. package/test-data/README.md +83 -0
  71. package/test-data/decision-tables/basic/8k.json +87992 -0
  72. package/test-data/decision-tables/basic/affiliate-commission-calculator.json +228 -0
  73. package/test-data/decision-tables/basic/airline-loyalty-points-calculations.json +285 -0
  74. package/test-data/decision-tables/basic/airline-upgrade-eligibility.json +466 -0
  75. package/test-data/decision-tables/basic/auto-insurance-premium-calculator.json +412 -0
  76. package/test-data/decision-tables/basic/booking-personalization-system.json +553 -0
  77. package/test-data/decision-tables/basic/care-team-assignment-system.json +585 -0
  78. package/test-data/decision-tables/basic/claim-validation-system.json +307 -0
  79. package/test-data/decision-tables/basic/clinical-lab-result-interpreter.json +433 -0
  80. package/test-data/decision-tables/basic/clinical-treatment-protocol.json +474 -0
  81. package/test-data/decision-tables/basic/credit-limit-adjustment.json +479 -0
  82. package/test-data/decision-tables/basic/customer-eligibility-engine.json +551 -0
  83. package/test-data/decision-tables/basic/customer-lifetime-value.json +200 -0
  84. package/test-data/decision-tables/basic/customer-onboarding-kyc-verification.json +611 -0
  85. package/test-data/decision-tables/basic/customer-service-escalation.json +191 -0
  86. package/test-data/decision-tables/basic/decision-table-discounts.json +168 -0
  87. package/test-data/decision-tables/basic/decision-table-shipping.json +398 -0
  88. package/test-data/decision-tables/basic/delivery-route-optimizer.json +271 -0
  89. package/test-data/decision-tables/basic/device-compatibility-checker.json +303 -0
  90. package/test-data/decision-tables/basic/disaster-relief-fund-allocation.json +296 -0
  91. package/test-data/decision-tables/basic/dynamic-fx-rate-pricing-system.json +237 -0
  92. package/test-data/decision-tables/basic/dynamic-marketplace-comission-calculator.json +242 -0
  93. package/test-data/decision-tables/basic/dynamic-shipping-cost-calculator.json +378 -0
  94. package/test-data/decision-tables/basic/dynamic-tarrif-engine.json +289 -0
  95. package/test-data/decision-tables/basic/dynamic-ticket-pricing.json +325 -0
  96. package/test-data/decision-tables/basic/empty-column-with-space.json +100 -0
  97. package/test-data/decision-tables/basic/empty-column-without-space.json +100 -0
  98. package/test-data/decision-tables/basic/environment-compliance-assessment.json +386 -0
  99. package/test-data/decision-tables/basic/expression-table-map.json +313 -0
  100. package/test-data/decision-tables/basic/flash-sale-eligibility.json +366 -0
  101. package/test-data/decision-tables/basic/flight-dispatch-decision-system.json +455 -0
  102. package/test-data/decision-tables/basic/flight-rebooking-fee-calculator.json +406 -0
  103. package/test-data/decision-tables/basic/government-assistance.json +299 -0
  104. package/test-data/decision-tables/basic/grant-funding-distribution.json +307 -0
  105. package/test-data/decision-tables/basic/hazardous-materials-management-system.json +414 -0
  106. package/test-data/decision-tables/basic/immigration-eligibility-evaluator.json +765 -0
  107. package/test-data/decision-tables/basic/import-duties-calculator.json +318 -0
  108. package/test-data/decision-tables/basic/insurance-agent-commission.json +228 -0
  109. package/test-data/decision-tables/basic/insurance-coverage-calculator.json +362 -0
  110. package/test-data/decision-tables/basic/insurance-underwriting-risk.json +321 -0
  111. package/test-data/decision-tables/basic/international-roaming-policy-manager.json +199 -0
  112. package/test-data/decision-tables/basic/legacy-plan-management.json +434 -0
  113. package/test-data/decision-tables/basic/marketplace-listing-verification-system.json +334 -0
  114. package/test-data/decision-tables/basic/medication-dosage-calculator.json +318 -0
  115. package/test-data/decision-tables/basic/merch-bags.json +171 -0
  116. package/test-data/decision-tables/basic/municipal-permit-evaluation-system.json +364 -0
  117. package/test-data/decision-tables/basic/mvno-partner-enablement.json +313 -0
  118. package/test-data/decision-tables/basic/partner-revenue-sharing.json +244 -0
  119. package/test-data/decision-tables/basic/payment-routing-and-fee-calculator.json +475 -0
  120. package/test-data/decision-tables/basic/policy-discount-calculator.json +307 -0
  121. package/test-data/decision-tables/basic/policy-eligibility-analyzer.json +299 -0
  122. package/test-data/decision-tables/basic/product-listing-scoring.json +358 -0
  123. package/test-data/decision-tables/basic/realtime-fraud-detection.json +235 -0
  124. package/test-data/decision-tables/basic/regional-compliance-manager.json +278 -0
  125. package/test-data/decision-tables/basic/returns-and-refund-policy.json +366 -0
  126. package/test-data/decision-tables/basic/returns-processing-system.json +448 -0
  127. package/test-data/decision-tables/basic/school-district-resource-allocation.json +282 -0
  128. package/test-data/decision-tables/basic/seat-map-optimization.json +325 -0
  129. package/test-data/decision-tables/basic/seller-fee-calculator.json +307 -0
  130. package/test-data/decision-tables/basic/service-level-agreement-enforcement.json +575 -0
  131. package/test-data/decision-tables/basic/smart-financial-product-matcher.json +249 -0
  132. package/test-data/decision-tables/basic/supply-chain-risk.json +316 -0
  133. package/test-data/decision-tables/basic/table-loop.json +93 -0
  134. package/test-data/decision-tables/basic/table.json +76 -0
  135. package/test-data/decision-tables/basic/traffic-violation-penalty-calculator.json +436 -0
  136. package/test-data/decision-tables/basic/transaction-compliance-classifier.json +525 -0
  137. package/test-data/decision-tables/basic/vehicle-claims-resolution.json +310 -0
  138. package/test-data/decision-tables/basic/warehouse-storage-location.json +345 -0
  139. package/test-data/decision-tables/hit-policy-collect/collect-multiple-matches.json +127 -0
  140. package/test-data/decision-tables/hit-policy-collect/collect-no-match.json +95 -0
  141. package/test-data/decision-tables/hit-policy-first/first-match.json +103 -0
  142. package/test-data/decision-tables/hit-policy-first/no-match.json +95 -0
  143. package/test-data/decision-tables/hit-policy-output-order/output-order-respected.json +94 -0
  144. package/test-data/decision-tables/hit-policy-output-order/string-output-order.json +94 -0
  145. package/test-data/decision-tables/hit-policy-priority/priority-respected.json +86 -0
  146. package/test-data/decision-tables/hit-policy-rule-order/rule-order-respected.json +94 -0
  147. package/test-data/decision-tables/hit-policy-unique/all-match-error.json +89 -0
  148. package/test-data/decision-tables/hit-policy-unique/multiple-match-error.json +89 -0
  149. package/test-data/decision-tables/hit-policy-unique/no-match.json +88 -0
  150. package/test-data/decision-tables/hit-policy-unique/unique-match.json +99 -0
  151. package/test-data/expressions/arithmetic/error-cyclic.json +114 -0
  152. package/test-data/expressions/arithmetic/error-missing-input.json +54 -0
  153. package/test-data/expressions/arithmetic/error-missing-output.json +54 -0
  154. package/test-data/expressions/arithmetic/expression-default.json +93 -0
  155. package/test-data/expressions/arithmetic/expression-fields.json +94 -0
  156. package/test-data/expressions/arithmetic/expression-loop.json +94 -0
  157. package/test-data/expressions/arithmetic/expression-passthrough.json +108 -0
  158. package/test-data/expressions/arithmetic/expression.json +69 -0
  159. package/test-data/expressions/arithmetic/nested-request.json +125 -0
  160. package/test-data/expressions/arithmetic/number-function.json +58 -0
  161. package/test-data/expressions/arithmetic/test-number-functions.json +68 -0
  162. package/test-data/expressions/functions/all.json +149 -0
  163. package/test-data/expressions/functions/avg.json +89 -0
  164. package/test-data/expressions/functions/filter.json +109 -0
  165. package/test-data/expressions/functions/flat.json +167 -0
  166. package/test-data/expressions/functions/map-strings.json +65 -0
  167. package/test-data/expressions/functions/map.json +73 -0
  168. package/test-data/expressions/functions/reduce.json +49 -0
  169. package/test-data/expressions/functions/some.json +175 -0
  170. package/test-data/expressions/functions/sort-strings.json +97 -0
  171. package/test-data/expressions/functions/sort.json +97 -0
  172. package/test-data/expressions/logical/logical-and.json +116 -0
  173. package/test-data/expressions/logical/logical-complex.json +260 -0
  174. package/test-data/expressions/logical/logical-not.json +111 -0
  175. package/test-data/expressions/logical/logical-or.json +123 -0
  176. package/test-data/expressions/string/string-comparison.json +128 -0
  177. package/test-data/expressions/string/string-concat.json +106 -0
  178. package/test-data/expressions/string/string-contains.json +125 -0
  179. package/test-data/expressions/string/string-endsWith.json +113 -0
  180. package/test-data/expressions/string/string-indexOf.json +131 -0
  181. package/test-data/expressions/string/string-join.json +92 -0
  182. package/test-data/expressions/string/string-lower.json +94 -0
  183. package/test-data/expressions/string/string-replace.json +130 -0
  184. package/test-data/expressions/string/string-split.json +101 -0
  185. package/test-data/expressions/string/string-startsWith.json +113 -0
  186. package/test-data/expressions/string/string-substring.json +138 -0
  187. package/test-data/expressions/string/string-trim.json +100 -0
  188. package/test-data/expressions/string/string-upper.json +94 -0
  189. package/test-data/other/custom.json +51 -0
  190. package/test-data/other/customer-input-schema.json +34 -0
  191. package/test-data/other/customer-output-schema.json +34 -0
  192. package/test-data/other/passthrough.json +31 -0
  193. package/test-data/sub-decisions/basic/$nodes-child.json +31 -0
  194. package/test-data/sub-decisions/basic/$nodes-parent.json +49 -0
  195. package/test-data/sub-decisions/basic/recursive-table1.json +49 -0
  196. package/test-data/sub-decisions/basic/recursive-table2.json +49 -0
  197. package/test-data/sub-decisions/complex-multi/approval-decision.json +31 -0
  198. package/test-data/sub-decisions/complex-multi/complex-dag.json +175 -0
  199. package/test-data/sub-decisions/complex-multi/credit-check.json +31 -0
  200. package/test-data/sub-decisions/complex-multi/customer-segmentation.json +31 -0
  201. package/test-data/sub-decisions/complex-multi/discount-eligibility.json +31 -0
  202. package/test-data/sub-decisions/complex-multi/eligibility-check.json +31 -0
  203. package/test-data/sub-decisions/complex-multi/final-offer.json +31 -0
  204. package/test-data/sub-decisions/complex-multi/income-verification.json +31 -0
  205. package/test-data/sub-decisions/complex-multi/linear-chain.json +121 -0
  206. package/test-data/sub-decisions/complex-multi/pricing-calculation.json +31 -0
  207. package/test-data/sub-decisions/complex-multi/product-eligibility.json +31 -0
  208. package/test-data/sub-decisions/complex-multi/risk-assessment.json +31 -0
  209. package/test-data/sub-decisions/complex-multi/shared-validation.json +31 -0
  210. package/test-data/sub-decisions/complex-multi/validation.json +31 -0
  211. package/test-data/sub-decisions/diamond/decision-a.json +31 -0
  212. package/test-data/sub-decisions/diamond/decision-b.json +31 -0
  213. package/test-data/sub-decisions/diamond/decision-c.json +31 -0
  214. package/test-data/sub-decisions/diamond/decision-shared.json +31 -0
  215. package/test-data/sub-decisions/diamond/diamond-pattern.json +109 -0
  216. package/test-data/sub-decisions/error-propagation/parent-calls-error.json +44 -0
  217. package/test-data/sub-decisions/error-propagation/sub-decision-with-error.json +60 -0
  218. package/test-data/switch-nodes/basic/account-dormancy-management.json +245 -0
  219. package/test-data/switch-nodes/basic/application-risk-assessment.json +474 -0
  220. package/test-data/switch-nodes/basic/cellular-data-rollover-system.json +281 -0
  221. package/test-data/switch-nodes/basic/clinical-pathway-selection.json +454 -0
  222. package/test-data/switch-nodes/basic/insurance-prior-authorization.json +467 -0
  223. package/test-data/switch-nodes/basic/last-mile-delivery-assignment.json +373 -0
  224. package/test-data/switch-nodes/basic/loan-approval.json +469 -0
  225. package/test-data/switch-nodes/basic/multi-switch.json +498 -0
  226. package/test-data/switch-nodes/basic/online-checkin-eligibility.json +285 -0
  227. package/test-data/switch-nodes/basic/order-consolidation-system.json +493 -0
  228. package/test-data/switch-nodes/basic/seller-approval-workflow.json +383 -0
  229. package/test-data/switch-nodes/basic/set-fee.json +243 -0
  230. package/test-data/switch-nodes/basic/shipping-carrier-selector.json +379 -0
  231. package/test-data/switch-nodes/basic/switch-node.json +167 -0
  232. package/test-data/switch-nodes/basic/switch-performance-2.json +1307 -0
  233. package/test-data/switch-nodes/basic/switch-performance.json +691 -0
  234. package/test-data/switch-nodes/basic/tax-exemption.json +295 -0
  235. package/test-data/switch-nodes/basic/warehouse-cross-docking.json +313 -0
  236. package/test-data/switch-nodes/default-cases/switch-with-default.json +134 -0
  237. package/test-data/zen-reference/$nodes-child.json +69 -0
  238. package/test-data/zen-reference/$nodes-parent.json +34 -0
  239. package/test-data/zen-reference/8k.json +87992 -0
  240. package/test-data/zen-reference/credit-analysis.json +324 -0
  241. package/test-data/zen-reference/custom.json +51 -0
  242. package/test-data/zen-reference/customer-input-schema.json +34 -0
  243. package/test-data/zen-reference/customer-output-schema.json +34 -0
  244. package/test-data/zen-reference/error-cyclic.json +114 -0
  245. package/test-data/zen-reference/error-missing-input.json +54 -0
  246. package/test-data/zen-reference/error-missing-output.json +54 -0
  247. package/test-data/zen-reference/expression.json +69 -0
  248. package/test-data/zen-reference/function-v2.json +48 -0
  249. package/test-data/zen-reference/function.json +46 -0
  250. package/test-data/zen-reference/graphs/account-dormancy-management.json +245 -0
  251. package/test-data/zen-reference/graphs/affiliate-commission-calculator.json +228 -0
  252. package/test-data/zen-reference/graphs/airline-loyalty-points-calculations.json +285 -0
  253. package/test-data/zen-reference/graphs/airline-upgrade-eligibility.json +466 -0
  254. package/test-data/zen-reference/graphs/aml.json +537 -0
  255. package/test-data/zen-reference/graphs/application-risk-assessment.json +474 -0
  256. package/test-data/zen-reference/graphs/auto-insurance-premium-calculator.json +412 -0
  257. package/test-data/zen-reference/graphs/booking-personalization-system.json +553 -0
  258. package/test-data/zen-reference/graphs/care-team-assignment-system.json +585 -0
  259. package/test-data/zen-reference/graphs/cellular-data-rollover-system.json +281 -0
  260. package/test-data/zen-reference/graphs/claim-validation-system.json +307 -0
  261. package/test-data/zen-reference/graphs/clinical-lab-result-interpreter.json +433 -0
  262. package/test-data/zen-reference/graphs/clinical-pathway-selection.json +454 -0
  263. package/test-data/zen-reference/graphs/clinical-treatment-protocol.json +474 -0
  264. package/test-data/zen-reference/graphs/company-analysis.json +390 -0
  265. package/test-data/zen-reference/graphs/credit-limit-adjustment.json +479 -0
  266. package/test-data/zen-reference/graphs/customer-eligibility-engine.json +551 -0
  267. package/test-data/zen-reference/graphs/customer-lifetime-value.json +200 -0
  268. package/test-data/zen-reference/graphs/customer-onboarding-kyc-verification.json +611 -0
  269. package/test-data/zen-reference/graphs/customer-service-escalation.json +191 -0
  270. package/test-data/zen-reference/graphs/decision-table-discounts.json +168 -0
  271. package/test-data/zen-reference/graphs/decision-table-shipping.json +398 -0
  272. package/test-data/zen-reference/graphs/delivery-route-optimizer.json +271 -0
  273. package/test-data/zen-reference/graphs/device-compatibility-checker.json +303 -0
  274. package/test-data/zen-reference/graphs/disaster-relief-fund-allocation.json +296 -0
  275. package/test-data/zen-reference/graphs/dynamic-fx-rate-pricing-system.json +237 -0
  276. package/test-data/zen-reference/graphs/dynamic-marketplace-comission-calculator.json +242 -0
  277. package/test-data/zen-reference/graphs/dynamic-shipping-cost-calculator.json +378 -0
  278. package/test-data/zen-reference/graphs/dynamic-tarrif-engine.json +289 -0
  279. package/test-data/zen-reference/graphs/dynamic-ticket-pricing.json +325 -0
  280. package/test-data/zen-reference/graphs/empty-column-with-space.json +100 -0
  281. package/test-data/zen-reference/graphs/empty-column-without-space.json +100 -0
  282. package/test-data/zen-reference/graphs/environment-compliance-assessment.json +386 -0
  283. package/test-data/zen-reference/graphs/expression-default.json +93 -0
  284. package/test-data/zen-reference/graphs/expression-fields.json +94 -0
  285. package/test-data/zen-reference/graphs/expression-loop.json +94 -0
  286. package/test-data/zen-reference/graphs/expression-passthrough.json +108 -0
  287. package/test-data/zen-reference/graphs/expression-table-map.json +313 -0
  288. package/test-data/zen-reference/graphs/flash-sale-eligibility.json +366 -0
  289. package/test-data/zen-reference/graphs/flight-dispatch-decision-system.json +455 -0
  290. package/test-data/zen-reference/graphs/flight-rebooking-fee-calculator.json +406 -0
  291. package/test-data/zen-reference/graphs/government-assistance.json +299 -0
  292. package/test-data/zen-reference/graphs/grant-funding-distribution.json +307 -0
  293. package/test-data/zen-reference/graphs/hazardous-materials-management-system.json +414 -0
  294. package/test-data/zen-reference/graphs/immigration-eligibility-evaluator.json +765 -0
  295. package/test-data/zen-reference/graphs/import-duties-calculator.json +318 -0
  296. package/test-data/zen-reference/graphs/insurance-agent-commission.json +228 -0
  297. package/test-data/zen-reference/graphs/insurance-breakdown.json +421 -0
  298. package/test-data/zen-reference/graphs/insurance-coverage-calculator.json +362 -0
  299. package/test-data/zen-reference/graphs/insurance-prior-authorization.json +467 -0
  300. package/test-data/zen-reference/graphs/insurance-underwriting-risk.json +321 -0
  301. package/test-data/zen-reference/graphs/international-roaming-policy-manager.json +199 -0
  302. package/test-data/zen-reference/graphs/last-mile-delivery-assignment.json +373 -0
  303. package/test-data/zen-reference/graphs/legacy-plan-management.json +434 -0
  304. package/test-data/zen-reference/graphs/loan-approval.json +469 -0
  305. package/test-data/zen-reference/graphs/marketplace-listing-verification-system.json +334 -0
  306. package/test-data/zen-reference/graphs/medication-dosage-calculator.json +318 -0
  307. package/test-data/zen-reference/graphs/merch-bags.json +171 -0
  308. package/test-data/zen-reference/graphs/multi-switch.json +498 -0
  309. package/test-data/zen-reference/graphs/municipal-permit-evaluation-system.json +364 -0
  310. package/test-data/zen-reference/graphs/mvno-partner-enablement.json +313 -0
  311. package/test-data/zen-reference/graphs/nested-request.json +125 -0
  312. package/test-data/zen-reference/graphs/online-checkin-eligibility.json +285 -0
  313. package/test-data/zen-reference/graphs/order-consolidation-system.json +493 -0
  314. package/test-data/zen-reference/graphs/partner-revenue-sharing.json +244 -0
  315. package/test-data/zen-reference/graphs/payment-routing-and-fee-calculator.json +475 -0
  316. package/test-data/zen-reference/graphs/policy-discount-calculator.json +307 -0
  317. package/test-data/zen-reference/graphs/policy-eligibility-analyzer.json +299 -0
  318. package/test-data/zen-reference/graphs/product-listing-scoring.json +358 -0
  319. package/test-data/zen-reference/graphs/realtime-fraud-detection.json +235 -0
  320. package/test-data/zen-reference/graphs/regional-compliance-manager.json +278 -0
  321. package/test-data/zen-reference/graphs/returns-and-refund-policy.json +366 -0
  322. package/test-data/zen-reference/graphs/returns-processing-system.json +448 -0
  323. package/test-data/zen-reference/graphs/school-district-resource-allocation.json +282 -0
  324. package/test-data/zen-reference/graphs/seat-map-optimization.json +325 -0
  325. package/test-data/zen-reference/graphs/seller-approval-workflow.json +383 -0
  326. package/test-data/zen-reference/graphs/seller-fee-calculator.json +307 -0
  327. package/test-data/zen-reference/graphs/service-level-agreement-enforcement.json +575 -0
  328. package/test-data/zen-reference/graphs/set-fee.json +243 -0
  329. package/test-data/zen-reference/graphs/shipping-carrier-selector.json +379 -0
  330. package/test-data/zen-reference/graphs/smart-financial-product-matcher.json +249 -0
  331. package/test-data/zen-reference/graphs/supply-chain-risk.json +316 -0
  332. package/test-data/zen-reference/graphs/table-loop.json +93 -0
  333. package/test-data/zen-reference/graphs/tax-exemption.json +295 -0
  334. package/test-data/zen-reference/graphs/traffic-violation-penalty-calculator.json +436 -0
  335. package/test-data/zen-reference/graphs/transaction-compliance-classifier.json +525 -0
  336. package/test-data/zen-reference/graphs/vehicle-claims-resolution.json +310 -0
  337. package/test-data/zen-reference/graphs/warehouse-cross-docking.json +313 -0
  338. package/test-data/zen-reference/graphs/warehouse-storage-location.json +345 -0
  339. package/test-data/zen-reference/http-function.json +34 -0
  340. package/test-data/zen-reference/infinite-function.json +46 -0
  341. package/test-data/zen-reference/js/imports.js +25 -0
  342. package/test-data/zen-reference/passthrough.json +31 -0
  343. package/test-data/zen-reference/recursive-table1.json +49 -0
  344. package/test-data/zen-reference/recursive-table2.json +49 -0
  345. package/test-data/zen-reference/sleep-function.json +34 -0
  346. package/test-data/zen-reference/switch-node.json +167 -0
  347. package/test-data/zen-reference/switch-performance-2.json +1307 -0
  348. package/test-data/zen-reference/switch-performance.json +691 -0
  349. package/test-data/zen-reference/table.json +76 -0
  350. package/tests/helpers/index.ts +73 -0
  351. package/tests/helpers/mock-context.ts +231 -0
  352. package/tests/helpers/round-trip.ts +398 -0
  353. package/tests/helpers/test-harness-comparison.ts +325 -0
  354. package/tests/helpers/test-harness-wasm.ts +710 -0
  355. package/tests/helpers/test-harness.ts +28 -0
  356. package/tests/helpers/wasm-test.ts +659 -0
  357. package/tests/integration/compilation-errors.test.ts +864 -0
  358. package/tests/integration/decision-tables.test.ts +531 -0
  359. package/tests/integration/edge-cases.test.ts +787 -0
  360. package/tests/integration/expressions.test.ts +513 -0
  361. package/tests/integration/function-node-integration.test.ts +182 -0
  362. package/tests/integration/sub-decisions.test.ts +108 -0
  363. package/tests/integration/switch-nodes.test.ts +399 -0
  364. package/tests/integration/unary-or-matching.test.ts +53 -0
  365. package/tests/integration/wasm-data-types.test.ts +398 -0
  366. package/tests/integration/wasm-errors.test.ts +199 -0
  367. package/tests/integration/wasm-execution.test.ts +348 -0
  368. package/tests/integration/wasm-memory.test.ts +228 -0
  369. package/tests/scripts/analyze-coverage.ts +166 -0
  370. package/tests/scripts/categorize-tests.ts +396 -0
  371. package/tests/scripts/coverage-analysis.ts +836 -0
  372. package/tests/unit/compiler/cache.test.ts +238 -0
  373. package/tests/unit/compiler/errors.test.ts +316 -0
  374. package/tests/unit/compiler/graph-scalability.test.ts +510 -0
  375. package/tests/unit/compiler/graph.test.ts +878 -0
  376. package/tests/unit/compiler/input-validation.test.ts +447 -0
  377. package/tests/unit/compiler/logical-and-parser.test.ts +143 -0
  378. package/tests/unit/compiler/logical-not-parser.test.ts +107 -0
  379. package/tests/unit/compiler/logical-or-parser.test.ts +236 -0
  380. package/tests/unit/compiler/marshal-gen/marshal-gen.test.ts +97 -0
  381. package/tests/unit/compiler/nodes/decision-table.test.ts +103 -0
  382. package/tests/unit/compiler/nodes/decision.test.ts +182 -0
  383. package/tests/unit/compiler/nodes/function-compile.test.ts +204 -0
  384. package/tests/unit/compiler/nodes/function.test.ts +176 -0
  385. package/tests/unit/compiler/nodes/input.test.ts +30 -0
  386. package/tests/unit/compiler/nodes/switch.test.ts +127 -0
  387. package/tests/unit/compiler/optimizer-cache.test.ts +327 -0
  388. package/tests/unit/compiler/optimizer-implementation.test.ts +625 -0
  389. package/tests/unit/compiler/parser.test.ts +508 -0
  390. package/tests/unit/compiler/runtime-error-cleanup.test.ts +426 -0
  391. package/tests/unit/compiler/runtime-validation.test.ts +303 -0
  392. package/tests/unit/compiler/runtime.test.ts +221 -0
  393. package/tests/unit/compiler/schema/schema.test.ts +248 -0
  394. package/tests/unit/compiler/unary-ast-transforms.test.ts +245 -0
  395. package/tsconfig.json +27 -0
  396. package/tsup.config.ts +11 -0
  397. package/vitest.config.ts +12 -0
@@ -0,0 +1,579 @@
1
+ // assembly/runtime/arrays.ts (AssemblyScript)
2
+ // Array handling for WASM linear memory
3
+
4
+ import { heapAlloc } from './memory';
5
+ import { writeString, readString } from './strings';
6
+ import {
7
+ Value,
8
+ TYPE_NULL,
9
+ TYPE_BOOL,
10
+ TYPE_INT,
11
+ TYPE_FLOAT,
12
+ TYPE_STRING,
13
+ TYPE_ARRAY,
14
+ TYPE_OBJECT,
15
+ } from './values';
16
+
17
+ // ============================================================================
18
+ // Array Constants
19
+ // ============================================================================
20
+
21
+ /**
22
+ * Size of the length field header in bytes for arrays.
23
+ */
24
+ export const ARRAY_LENGTH_SIZE: usize = 4;
25
+
26
+ /**
27
+ * Size of each F64 element in bytes.
28
+ */
29
+ export const F64_ELEMENT_SIZE: usize = 8;
30
+
31
+ /**
32
+ * Size of each element pointer (usize) in bytes for generic arrays.
33
+ */
34
+ export const ELEMENT_PTR_SIZE: usize = 4;
35
+
36
+ /**
37
+ * Size of the type tag field in bytes for serialized Values.
38
+ */
39
+ export const VALUE_TYPE_SIZE: usize = 4;
40
+
41
+ /**
42
+ * Size of the bool field in bytes for serialized Values.
43
+ */
44
+ export const VALUE_BOOL_SIZE: usize = 1;
45
+
46
+ /**
47
+ * Size of the int field in bytes for serialized Values.
48
+ */
49
+ export const VALUE_INT_SIZE: usize = 8;
50
+
51
+ /**
52
+ * Size of the float field in bytes for serialized Values.
53
+ */
54
+ export const VALUE_FLOAT_SIZE: usize = 8;
55
+
56
+ /**
57
+ * Size of the pointer field in bytes for serialized Values (string, array, object).
58
+ */
59
+ export const VALUE_PTR_SIZE: usize = 4;
60
+
61
+ // ============================================================================
62
+ // F64 Array Handling
63
+ // ============================================================================
64
+
65
+ /**
66
+ * Write a numeric array (Array<f64>) to memory.
67
+ *
68
+ * The array is stored in the format: [length: u32][f64 elements...]
69
+ *
70
+ * Memory is allocated from the runtime heap using heapAlloc().
71
+ * The memory is aligned to 8 bytes for efficient access.
72
+ *
73
+ * @param arr - The array to write to memory
74
+ * @returns Pointer to the allocated array data, or 0 if allocation failed
75
+ */
76
+ export function writeF64Array(arr: Array<f64>): usize {
77
+ const len = <u32>arr.length;
78
+
79
+ // Calculate total size: length field (4 bytes) + f64 elements (8 bytes each)
80
+ const totalSize = ARRAY_LENGTH_SIZE + <usize>len * F64_ELEMENT_SIZE;
81
+
82
+ // Allocate memory from heap
83
+ const ptr = heapAlloc(totalSize);
84
+
85
+ // Return 0 if allocation failed
86
+ if (ptr == 0) {
87
+ return 0;
88
+ }
89
+
90
+ // Write length
91
+ store<u32>(ptr, len);
92
+
93
+ // Write each f64 element
94
+ for (let i: u32 = 0; i < len; i++) {
95
+ store<f64>(ptr + ARRAY_LENGTH_SIZE + <usize>i * F64_ELEMENT_SIZE, arr[i]);
96
+ }
97
+
98
+ return ptr;
99
+ }
100
+
101
+ /**
102
+ * Read a numeric array (Array<f64>) from memory.
103
+ *
104
+ * The array must be stored in the format: [length: u32][f64 elements...]
105
+ *
106
+ * @param ptr - Pointer to the array data in memory
107
+ * @returns The read array, or empty array if pointer is null
108
+ */
109
+ export function readF64Array(ptr: usize): Array<f64> {
110
+ // Return empty array for null pointer
111
+ if (ptr == 0) {
112
+ return new Array<f64>();
113
+ }
114
+
115
+ // Read length
116
+ const len = load<u32>(ptr);
117
+
118
+ // Create array and populate it
119
+ const result = new Array<f64>(len);
120
+ for (let i: u32 = 0; i < len; i++) {
121
+ result[i] = load<f64>(ptr + ARRAY_LENGTH_SIZE + <usize>i * F64_ELEMENT_SIZE);
122
+ }
123
+
124
+ return result;
125
+ }
126
+
127
+ /**
128
+ * Calculate the size in bytes needed to store an F64 array in memory.
129
+ *
130
+ * @param len - The length of the array
131
+ * @returns The total size in bytes including the length header
132
+ */
133
+ export function getF64ArraySize(len: usize): usize {
134
+ return ARRAY_LENGTH_SIZE + len * F64_ELEMENT_SIZE;
135
+ }
136
+
137
+ // ============================================================================
138
+ // Value Serialization
139
+ // ============================================================================
140
+
141
+ /**
142
+ * Write a Value to memory and return its pointer.
143
+ *
144
+ * For complex types (string/array/object), storing the actual data inline would make
145
+ * Value structs variable-sized and unpredictable. Storing pointers provides fixed-size
146
+ * Values (predictable offsets) while allowing arbitrary complex data on the heap.
147
+ *
148
+ * The Value is stored in the format: [type: u32][value_data...]
149
+ *
150
+ * For primitive types (bool, int, float), value_data is the actual value.
151
+ * For complex types (string, array, object), value_data is a pointer to the data.
152
+ *
153
+ * Memory is allocated from the runtime heap using heapAlloc().
154
+ *
155
+ * @param v - The Value to write to memory
156
+ * @returns Pointer to the allocated Value data, or 0 if allocation failed
157
+ */
158
+ export function writeValue(v: Value): usize {
159
+ const type = v.type;
160
+
161
+ if (type == TYPE_NULL) {
162
+ // For null, just write the type tag
163
+ const ptr = heapAlloc(VALUE_TYPE_SIZE);
164
+ if (ptr == 0) return 0;
165
+ store<u32>(ptr, type);
166
+ return ptr;
167
+ } else if (type == TYPE_BOOL) {
168
+ // Format: [type: u32][bool: u8]
169
+ const ptr = heapAlloc(VALUE_TYPE_SIZE + VALUE_BOOL_SIZE);
170
+ if (ptr == 0) return 0;
171
+ store<u32>(ptr, type);
172
+ store<u8>(ptr + VALUE_TYPE_SIZE, v.boolVal ? 1 : 0);
173
+ return ptr;
174
+ } else if (type == TYPE_INT) {
175
+ // Format: [type: u32][int: i64]
176
+ const ptr = heapAlloc(VALUE_TYPE_SIZE + VALUE_INT_SIZE);
177
+ if (ptr == 0) return 0;
178
+ store<u32>(ptr, type);
179
+ store<i64>(ptr + VALUE_TYPE_SIZE, v.intVal);
180
+ return ptr;
181
+ } else if (type == TYPE_FLOAT) {
182
+ // Format: [type: u32][float: f64]
183
+ const ptr = heapAlloc(VALUE_TYPE_SIZE + VALUE_FLOAT_SIZE);
184
+ if (ptr == 0) return 0;
185
+ store<u32>(ptr, type);
186
+ store<f64>(ptr + VALUE_TYPE_SIZE, v.floatVal);
187
+ return ptr;
188
+ } else if (type == TYPE_STRING) {
189
+ // Format: [type: u32][stringPtr: u32]
190
+ const ptr = heapAlloc(VALUE_TYPE_SIZE + VALUE_PTR_SIZE);
191
+ if (ptr == 0) return 0;
192
+ store<u32>(ptr, type);
193
+ const stringVal = v.stringVal != null ? v.stringVal! : '';
194
+ const stringPtr = writeString(stringVal);
195
+ store<u32>(ptr + VALUE_TYPE_SIZE, stringPtr);
196
+ return ptr;
197
+ } else if (type == TYPE_ARRAY) {
198
+ // Format: [type: u32][arrayPtr: u32]
199
+ const ptr = heapAlloc(VALUE_TYPE_SIZE + VALUE_PTR_SIZE);
200
+ if (ptr == 0) return 0;
201
+ store<u32>(ptr, type);
202
+ const arrayVal = v.arrayVal != null ? v.arrayVal! : new Array<Value>();
203
+ const arrayPtr = writeValueArray(arrayVal);
204
+ store<u32>(ptr + VALUE_TYPE_SIZE, arrayPtr);
205
+ return ptr;
206
+ } else if (type == TYPE_OBJECT) {
207
+ // Format: [type: u32][objectPtr: u32]
208
+ const ptr = heapAlloc(VALUE_TYPE_SIZE + VALUE_PTR_SIZE);
209
+ if (ptr == 0) return 0;
210
+ store<u32>(ptr, type);
211
+ const objectVal = v.objectVal != null ? v.objectVal! : new Map<string, Value>();
212
+ const objectPtr = writeValueMap(objectVal);
213
+ store<u32>(ptr + VALUE_TYPE_SIZE, objectPtr);
214
+ return ptr;
215
+ }
216
+
217
+ return 0; // Unknown type
218
+ }
219
+
220
+ /**
221
+ * Read a Value from memory.
222
+ *
223
+ * The Value must be stored in the format: [type: u32][value_data...]
224
+ *
225
+ * @param ptr - Pointer to the Value data in memory
226
+ * @returns The read Value, or null if pointer is invalid
227
+ */
228
+ export function readValue(ptr: usize): Value {
229
+ // Return null for null pointer
230
+ if (ptr == 0) {
231
+ return Value.Null();
232
+ }
233
+
234
+ // Read type
235
+ const type = load<u32>(ptr);
236
+
237
+ if (type == TYPE_NULL) {
238
+ return Value.Null();
239
+ } else if (type == TYPE_BOOL) {
240
+ const boolVal = load<u8>(ptr + VALUE_TYPE_SIZE) != 0;
241
+ return Value.Bool(boolVal);
242
+ } else if (type == TYPE_INT) {
243
+ const intVal = load<i64>(ptr + VALUE_TYPE_SIZE);
244
+ return Value.Int(intVal);
245
+ } else if (type == TYPE_FLOAT) {
246
+ const floatVal = load<f64>(ptr + VALUE_TYPE_SIZE);
247
+ return Value.Float(floatVal);
248
+ } else if (type == TYPE_STRING) {
249
+ const stringPtr = load<u32>(ptr + VALUE_TYPE_SIZE);
250
+ const stringVal = readString(stringPtr);
251
+ return Value.String(stringVal);
252
+ } else if (type == TYPE_ARRAY) {
253
+ const arrayPtr = load<u32>(ptr + VALUE_TYPE_SIZE);
254
+ const arrayVal = readValueArray(arrayPtr);
255
+ return Value.Array(arrayVal);
256
+ } else if (type == TYPE_OBJECT) {
257
+ const objectPtr = load<u32>(ptr + VALUE_TYPE_SIZE);
258
+ const objectVal = readValueMap(objectPtr);
259
+ return Value.Object(objectVal);
260
+ }
261
+
262
+ return Value.Null(); // Unknown type
263
+ }
264
+
265
+ // ============================================================================
266
+ // Value Array Handling
267
+ // ============================================================================
268
+
269
+ // Format marker for flat numeric arrays (high bit set in length field)
270
+ const FLAT_ARRAY_MARKER: u32 = 0x80000000;
271
+
272
+ /**
273
+ * Detect if an array contains only floats/ints (homogeneous numeric array).
274
+ *
275
+ * @param arr - The array to check
276
+ * @returns true if all elements are TYPE_FLOAT or TYPE_INT, false otherwise
277
+ */
278
+ function isHomogeneousNumericArray(arr: Array<Value>): bool {
279
+ const len = arr.length;
280
+ if (len == 0) return false;
281
+
282
+ for (let i = 0; i < len; i++) {
283
+ const type = arr[i].type;
284
+ if (type != TYPE_FLOAT && type != TYPE_INT) {
285
+ return false;
286
+ }
287
+ }
288
+ return true;
289
+ }
290
+
291
+ /**
292
+ * Write a homogeneous numeric array in flat format.
293
+ *
294
+ * Format: [length | FLAT_ARRAY_MARKER: u32][f64 elements...]
295
+ *
296
+ * The high bit of the length field is set to indicate flat format.
297
+ * This specialized format avoids individual Value allocations and type tags,
298
+ * reducing memory overhead and fragmentation significantly.
299
+ *
300
+ * @param arr - The array to write (must be homogeneous numeric)
301
+ * @returns Pointer to the allocated array data, or 0 if allocation failed
302
+ */
303
+ function writeHomogeneousNumericArray(arr: Array<Value>): usize {
304
+ const len = <u32>arr.length;
305
+
306
+ // Calculate total size: length with marker (4) + f64 elements (8 each)
307
+ const totalSize = ARRAY_LENGTH_SIZE + <usize>len * F64_ELEMENT_SIZE;
308
+
309
+ // Single allocation for entire array
310
+ const ptr = heapAlloc(totalSize);
311
+ if (ptr == 0) return 0;
312
+
313
+ // Write length with high bit set to indicate flat format
314
+ store<u32>(ptr, len | FLAT_ARRAY_MARKER);
315
+
316
+ // Write all numeric values as f64 directly (no Value wrapping)
317
+ for (let i: u32 = 0; i < len; i++) {
318
+ const val = arr[i];
319
+ const numVal = val.type == TYPE_FLOAT ? val.floatVal : <f64>val.intVal;
320
+ store<f64>(ptr + ARRAY_LENGTH_SIZE + <usize>i * F64_ELEMENT_SIZE, numVal);
321
+ }
322
+
323
+ return ptr;
324
+ }
325
+
326
+ /**
327
+ * Read a homogeneous numeric array from flat format.
328
+ *
329
+ * Format: [length | FLAT_ARRAY_MARKER: u32][f64 elements...]
330
+ *
331
+ * @param ptr - Pointer to the array data in memory
332
+ * @param len - The actual length (without the marker bit)
333
+ * @returns The read array of Value objects
334
+ */
335
+ function readHomogeneousNumericArray(ptr: usize, len: u32): Array<Value> {
336
+ const result = new Array<Value>(len);
337
+
338
+ // Read all f64 values and wrap them as Value.Float
339
+ for (let i: u32 = 0; i < len; i++) {
340
+ const numVal = load<f64>(ptr + ARRAY_LENGTH_SIZE + <usize>i * F64_ELEMENT_SIZE);
341
+ result[i] = Value.Float(numVal);
342
+ }
343
+
344
+ return result;
345
+ }
346
+
347
+ /**
348
+ * Write a Value array to memory.
349
+ *
350
+ * The array is stored in one of two formats:
351
+ *
352
+ * 1. Flat numeric format (for homogeneous numeric arrays):
353
+ * [length | FLAT_ARRAY_MARKER: u32][f64 elements...]
354
+ *
355
+ * 2. Generic format (for mixed-type arrays):
356
+ * [length: u32][Value pointers...]
357
+ *
358
+ * Homogeneous numeric arrays are detected and serialized using a flat format
359
+ * that eliminates per-element allocations and type tags, significantly reducing
360
+ * memory overhead (from ~16+ bytes per element to 8 bytes) and fragmentation.
361
+ * The flat format is indicated by setting the high bit of the length field.
362
+ *
363
+ * Memory is allocated from the runtime heap using heapAlloc().
364
+ *
365
+ * @param arr - The array to write to memory
366
+ * @returns Pointer to the allocated array data, or 0 if allocation failed
367
+ */
368
+ export function writeValueArray(arr: Array<Value>): usize {
369
+ const len = <u32>arr.length;
370
+
371
+ // Empty array (generic format)
372
+ if (len == 0) {
373
+ const ptr = heapAlloc(ARRAY_LENGTH_SIZE);
374
+ if (ptr == 0) return 0;
375
+ store<u32>(ptr, 0);
376
+ return ptr;
377
+ }
378
+
379
+ // Optimization: detect homogeneous numeric arrays and use flat format
380
+ if (isHomogeneousNumericArray(arr)) {
381
+ return writeHomogeneousNumericArray(arr);
382
+ }
383
+
384
+ // Generic path: mixed-type array
385
+ // Format: [length: u32][Value pointers...]
386
+ const totalSize = ARRAY_LENGTH_SIZE + <usize>len * ELEMENT_PTR_SIZE;
387
+
388
+ const ptr = heapAlloc(totalSize);
389
+ if (ptr == 0) return 0;
390
+
391
+ store<u32>(ptr, len);
392
+
393
+ // Write each Value pointer
394
+ for (let i: u32 = 0; i < len; i++) {
395
+ const valuePtr = writeValue(arr[i]);
396
+ store<u32>(ptr + ARRAY_LENGTH_SIZE + <usize>i * ELEMENT_PTR_SIZE, valuePtr);
397
+ }
398
+
399
+ return ptr;
400
+ }
401
+
402
+ /**
403
+ * Read a Value array from memory.
404
+ *
405
+ * Handles both flat numeric format and generic format:
406
+ *
407
+ * 1. Flat numeric format: [length | FLAT_ARRAY_MARKER: u32][f64 elements...]
408
+ * 2. Generic format: [length: u32][Value pointers...]
409
+ *
410
+ * The format is detected by checking if the high bit of the length is set.
411
+ *
412
+ * @param ptr - Pointer to the array data in memory
413
+ * @returns The read array, or empty array if pointer is null
414
+ */
415
+ export function readValueArray(ptr: usize): Array<Value> {
416
+ // Return empty array for null pointer
417
+ if (ptr == 0) {
418
+ return new Array<Value>();
419
+ }
420
+
421
+ // Read length (with potential marker bit)
422
+ const lengthField = load<u32>(ptr);
423
+
424
+ // Check if this is a flat numeric array (high bit set)
425
+ if ((lengthField & FLAT_ARRAY_MARKER) != 0) {
426
+ // Flat numeric format - extract actual length
427
+ const len = lengthField & ~FLAT_ARRAY_MARKER;
428
+ return readHomogeneousNumericArray(ptr, len);
429
+ }
430
+
431
+ // Generic format - length is used as-is
432
+ const len = lengthField;
433
+
434
+ // Empty array
435
+ if (len == 0) {
436
+ return new Array<Value>();
437
+ }
438
+
439
+ // Read array of Value pointers
440
+ const result = new Array<Value>(len);
441
+ for (let i: u32 = 0; i < len; i++) {
442
+ const valuePtr = load<u32>(ptr + ARRAY_LENGTH_SIZE + <usize>i * ELEMENT_PTR_SIZE);
443
+ result[i] = readValue(valuePtr);
444
+ }
445
+
446
+ return result;
447
+ }
448
+
449
+ /**
450
+ * Calculate the size in bytes needed to store a Value array in memory.
451
+ *
452
+ * Note: This calculates the size for the generic format.
453
+ * For flat numeric arrays, the actual size may be different.
454
+ *
455
+ * @param len - The length of the array
456
+ * @returns The total size in bytes including the length header (but not the individual Values)
457
+ */
458
+ export function getValueArraySize(len: usize): usize {
459
+ return ARRAY_LENGTH_SIZE + len * ELEMENT_PTR_SIZE;
460
+ }
461
+
462
+ // ============================================================================
463
+ // Value Map (Object) Handling
464
+ // ============================================================================
465
+
466
+ /**
467
+ * Write a Value map to memory.
468
+ *
469
+ * The map is stored in the format: [length: u32][keyPtr1: u32][valuePtr1: u32][keyPtr2: u32][valuePtr2: u32]...
470
+ *
471
+ * Keys are always strings and written to memory separately using writeString().
472
+ * Values are serialized using writeValue() separately.
473
+ *
474
+ * Memory is allocated from the runtime heap using heapAlloc().
475
+ *
476
+ * JavaScript object property order is insertion-ordered (ES2015+), so we must preserve
477
+ * order when serializing to match JS semantics and ensure deterministic output.
478
+ *
479
+ * @param map - The map to write to memory
480
+ * @returns Pointer to the allocated map data, or 0 if allocation failed
481
+ */
482
+ export function writeValueMap(map: Map<string, Value>): usize {
483
+ const len = <u32>map.size;
484
+
485
+ // Calculate total size: length field (4 bytes) + key/value pairs (8 bytes each)
486
+ const totalSize = ARRAY_LENGTH_SIZE + <usize>len * 2 * ELEMENT_PTR_SIZE;
487
+
488
+ // Allocate memory from heap
489
+ const ptr = heapAlloc(totalSize);
490
+
491
+ // Return 0 if allocation failed
492
+ if (ptr == 0) {
493
+ return 0;
494
+ }
495
+
496
+ // Write length
497
+ store<u32>(ptr, len);
498
+
499
+ // Get keys and write each key/value pair
500
+ const keys = map.keys();
501
+ for (let i: u32 = 0; i < <u32>keys.length; i++) {
502
+ const key = keys[i];
503
+ const offset = ptr + ARRAY_LENGTH_SIZE + <usize>i * 2 * ELEMENT_PTR_SIZE;
504
+
505
+ // Write key pointer
506
+ const keyPtr = writeString(key);
507
+ store<u32>(offset, keyPtr);
508
+
509
+ // Write value pointer
510
+ const valuePtr = writeValue(map.get(key));
511
+ store<u32>(offset + ELEMENT_PTR_SIZE, valuePtr);
512
+ }
513
+
514
+ return ptr;
515
+ }
516
+
517
+ /**
518
+ * Read a Value map from memory.
519
+ *
520
+ * The map must be stored in the format: [length: u32][keyPtr1: u32][valuePtr1: u32][keyPtr2: u32][valuePtr2: u32]...
521
+ *
522
+ * @param ptr - Pointer to the map data in memory
523
+ * @returns The read map, or empty map if pointer is null
524
+ */
525
+ export function readValueMap(ptr: usize): Map<string, Value> {
526
+ // Return empty map for null pointer
527
+ if (ptr == 0) {
528
+ return new Map<string, Value>();
529
+ }
530
+
531
+ // Read length
532
+ const len = load<u32>(ptr);
533
+
534
+ // Create map and populate it
535
+ const result = new Map<string, Value>();
536
+ for (let i: u32 = 0; i < len; i++) {
537
+ const keyPtr = load<u32>(ptr + ARRAY_LENGTH_SIZE + <usize>i * 2 * ELEMENT_PTR_SIZE);
538
+ const valuePtr = load<u32>(
539
+ ptr + ARRAY_LENGTH_SIZE + <usize>i * 2 * ELEMENT_PTR_SIZE + ELEMENT_PTR_SIZE,
540
+ );
541
+
542
+ const key = readString(keyPtr);
543
+ const value = readValue(valuePtr);
544
+
545
+ result.set(key, value);
546
+ }
547
+
548
+ return result;
549
+ }
550
+
551
+ // ============================================================================
552
+ // Array Utility Functions
553
+ // ============================================================================
554
+
555
+ /**
556
+ * Calculate the length of an array from its pointer in memory.
557
+ *
558
+ * @param ptr - Pointer to the array data in memory
559
+ * @returns The length of the array, or 0 if null
560
+ */
561
+ export function getArrayLength(ptr: usize): usize {
562
+ if (ptr == 0) {
563
+ return 0;
564
+ }
565
+ return load<u32>(ptr);
566
+ }
567
+
568
+ /**
569
+ * Check if an array pointer points to an empty array.
570
+ *
571
+ * @param ptr - Pointer to the array data in memory
572
+ * @returns true if the array is empty or pointer is null, false otherwise
573
+ */
574
+ export function isArrayEmpty(ptr: usize): bool {
575
+ if (ptr == 0) {
576
+ return true;
577
+ }
578
+ return load<u32>(ptr) == 0;
579
+ }