@scriptc/compiler 0.0.35 → 0.1.1
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.
- package/ambient/scriptc-node-fallback.d.ts +14 -11
- package/ambient/scriptc-overrides.d.ts +0 -7
- package/ambient/scriptc.d.ts +1 -1
- package/dist/backend/build-cache.d.ts +44 -0
- package/dist/backend/build-cache.js +241 -0
- package/dist/backend/build-cache.js.map +1 -0
- package/dist/backend/{emission/emit-async.d.ts → c/async.d.ts} +21 -30
- package/dist/backend/{emission/emit-async.js → c/async.js} +270 -286
- package/dist/backend/c/async.js.map +1 -0
- package/dist/backend/{emission/emitter.d.ts → c/c-emitter.d.ts} +6 -23
- package/dist/backend/{emission/emitter.js → c/c-emitter.js} +53 -107
- package/dist/backend/c/c-emitter.js.map +1 -0
- package/dist/backend/c/exprs.d.ts +8 -0
- package/dist/backend/c/exprs.js +7937 -0
- package/dist/backend/c/exprs.js.map +1 -0
- package/dist/backend/{emission/emit-island.d.ts → c/island.d.ts} +5 -5
- package/dist/backend/{emission/emit-island.js → c/island.js} +24 -22
- package/dist/backend/c/island.js.map +1 -0
- package/dist/backend/{emission → c}/may-throw.d.ts +1 -1
- package/dist/backend/{emission → c}/may-throw.js +4 -1
- package/dist/backend/c/may-throw.js.map +1 -0
- package/dist/backend/{emission/emit-shapes.d.ts → c/shapes.d.ts} +19 -19
- package/dist/backend/{emission/emit-shapes.js → c/shapes.js} +78 -87
- package/dist/backend/c/shapes.js.map +1 -0
- package/dist/backend/{emission/emit-stmts.d.ts → c/stmts.d.ts} +12 -12
- package/dist/backend/{emission/emit-stmts.js → c/stmts.js} +395 -343
- package/dist/backend/c/stmts.js.map +1 -0
- package/dist/backend/{emission/emit-types.d.ts → c/types.d.ts} +1 -1
- package/dist/backend/{emission/emit-types.js → c/types.js} +42 -286
- package/dist/backend/c/types.js.map +1 -0
- package/dist/backend/c/types.test.js +25 -0
- package/dist/backend/c/types.test.js.map +1 -0
- package/dist/backend/{emission/emit-walkers.d.ts → c/walkers.d.ts} +19 -41
- package/dist/backend/{emission/emit-walkers.js → c/walkers.js} +242 -304
- package/dist/backend/c/walkers.js.map +1 -0
- package/dist/backend/external-c.d.ts +33 -0
- package/dist/backend/external-c.js +51 -0
- package/dist/backend/external-c.js.map +1 -0
- package/dist/backend/ffi-callbacks.d.ts +1 -1
- package/dist/backend/ffi-callbacks.js +4 -3
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/{library-identity.d.ts → library-identity-markers.d.ts} +0 -4
- package/dist/backend/{library-identity.js → library-identity-markers.js} +10 -9
- package/dist/backend/library-identity-markers.js.map +1 -0
- package/dist/backend/link-plan.d.ts +37 -0
- package/dist/backend/link-plan.js +26 -0
- package/dist/backend/link-plan.js.map +1 -0
- package/dist/backend/linker.d.ts +22 -0
- package/dist/backend/linker.js +236 -0
- package/dist/backend/linker.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +4 -0
- package/dist/backend/llvm/blocks.js +29 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +2 -19
- package/dist/backend/llvm/classes.js +20 -52
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +4 -0
- package/dist/backend/llvm/common.js +27 -0
- package/dist/backend/llvm/common.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +3 -8
- package/dist/backend/llvm/dyn.js +159 -224
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +4 -1
- package/dist/backend/llvm/emitter.js +548 -9988
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-async.d.ts +4 -0
- package/dist/backend/llvm/expr-async.js +726 -0
- package/dist/backend/llvm/expr-async.js.map +1 -0
- package/dist/backend/llvm/expr-bytes.d.ts +13 -0
- package/dist/backend/llvm/expr-bytes.js +456 -0
- package/dist/backend/llvm/expr-bytes.js.map +1 -0
- package/dist/backend/llvm/expr-callbacks.d.ts +22 -0
- package/dist/backend/llvm/expr-callbacks.js +520 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -0
- package/dist/backend/llvm/expr-calls.d.ts +2 -0
- package/dist/backend/llvm/expr-calls.js +618 -0
- package/dist/backend/llvm/expr-calls.js.map +1 -0
- package/dist/backend/llvm/expr-containers.d.ts +25 -0
- package/dist/backend/llvm/expr-containers.js +637 -0
- package/dist/backend/llvm/expr-containers.js.map +1 -0
- package/dist/backend/llvm/expr-context.d.ts +255 -0
- package/dist/backend/llvm/expr-context.js +2 -0
- package/dist/backend/llvm/expr-context.js.map +1 -0
- package/dist/backend/llvm/expr-control.d.ts +2 -0
- package/dist/backend/llvm/expr-control.js +473 -0
- package/dist/backend/llvm/expr-control.js.map +1 -0
- package/dist/backend/llvm/expr-dispatch.d.ts +4 -0
- package/dist/backend/llvm/expr-dispatch.js +153 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -0
- package/dist/backend/llvm/expr-dynamic.d.ts +2 -0
- package/dist/backend/llvm/expr-dynamic.js +810 -0
- package/dist/backend/llvm/expr-dynamic.js.map +1 -0
- package/dist/backend/llvm/expr-island.d.ts +15 -0
- package/dist/backend/llvm/expr-island.js +690 -0
- package/dist/backend/llvm/expr-island.js.map +1 -0
- package/dist/backend/llvm/expr-primitives.d.ts +6 -0
- package/dist/backend/llvm/expr-primitives.js +642 -0
- package/dist/backend/llvm/expr-primitives.js.map +1 -0
- package/dist/backend/llvm/expr-records.d.ts +9 -0
- package/dist/backend/llvm/expr-records.js +299 -0
- package/dist/backend/llvm/expr-records.js.map +1 -0
- package/dist/backend/llvm/expr-stream-bridges.d.ts +13 -0
- package/dist/backend/llvm/expr-stream-bridges.js +420 -0
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +12 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +360 -0
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -0
- package/dist/backend/llvm/lib-dispatch.d.ts +5 -0
- package/dist/backend/llvm/lib-dispatch.js +267 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -0
- package/dist/backend/llvm/lib-filesystem.d.ts +6 -0
- package/dist/backend/llvm/lib-filesystem.js +594 -0
- package/dist/backend/llvm/lib-filesystem.js.map +1 -0
- package/dist/backend/llvm/lib-network.d.ts +2 -0
- package/dist/backend/llvm/lib-network.js +429 -0
- package/dist/backend/llvm/lib-network.js.map +1 -0
- package/dist/backend/llvm/lib-process.d.ts +5 -0
- package/dist/backend/llvm/lib-process.js +585 -0
- package/dist/backend/llvm/lib-process.js.map +1 -0
- package/dist/backend/llvm/lib-shared.d.ts +6 -0
- package/dist/backend/llvm/lib-shared.js +687 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -0
- package/dist/backend/llvm/lib-stream.d.ts +2 -0
- package/dist/backend/llvm/lib-stream.js +470 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +12 -2
- package/dist/backend/llvm/shapes.js +66 -307
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +52 -0
- package/dist/backend/llvm/shapes.test.js.map +1 -0
- package/dist/backend/llvm/unsupported.d.ts +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -3
- package/dist/backend/llvm/walkers.js +195 -222
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +45 -0
- package/dist/backend/native-codegen.js +275 -0
- package/dist/backend/native-codegen.js.map +1 -0
- package/dist/backend/native-codegen.test.js +226 -0
- package/dist/backend/native-codegen.test.js.map +1 -0
- package/dist/backend/native-link-info.d.ts +96 -0
- package/dist/backend/native-link-info.js +243 -0
- package/dist/backend/native-link-info.js.map +1 -0
- package/dist/backend/native-link-info.test.d.ts +1 -0
- package/dist/backend/native-link-info.test.js +134 -0
- package/dist/backend/native-link-info.test.js.map +1 -0
- package/dist/backend/{cc.d.ts → native-toolchain.d.ts} +54 -34
- package/dist/backend/{cc.js → native-toolchain.js} +231 -810
- package/dist/backend/native-toolchain.js.map +1 -0
- package/dist/backend/native-toolchain.test.d.ts +1 -0
- package/dist/backend/{cc-cache.test.js → native-toolchain.test.js} +219 -7
- package/dist/backend/native-toolchain.test.js.map +1 -0
- package/dist/backend/object-localize.js +1 -1
- package/dist/backend/runtime-abi.d.ts +10 -0
- package/dist/backend/runtime-abi.js +11 -0
- package/dist/backend/runtime-abi.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.d.ts +1 -0
- package/dist/backend/runtime-pack-targets.test.js +54 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -0
- package/dist/backend/runtime-pack.d.ts +112 -0
- package/dist/backend/runtime-pack.js +305 -0
- package/dist/backend/runtime-pack.js.map +1 -0
- package/dist/backend/runtime-pack.test.d.ts +1 -0
- package/dist/backend/runtime-pack.test.js +473 -0
- package/dist/backend/runtime-pack.test.js.map +1 -0
- package/dist/backend/targets.d.ts +76 -0
- package/dist/backend/targets.js +262 -0
- package/dist/backend/targets.js.map +1 -0
- package/dist/backend/targets.test.d.ts +1 -0
- package/dist/backend/targets.test.js +41 -0
- package/dist/backend/targets.test.js.map +1 -0
- package/dist/backend/vendor-archives.d.ts +41 -0
- package/dist/backend/vendor-archives.js +462 -0
- package/dist/backend/vendor-archives.js.map +1 -0
- package/dist/compat/fetch-profile.d.ts +0 -1
- package/dist/compat/fetch-profile.js +0 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/coverage/report.js +3 -3
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +35 -33
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +11 -12
- package/dist/diagnostics/diagnostic.js +19 -17
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/render.d.ts +1 -1
- package/dist/diagnostics/render.js +1 -1
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/executable/{early-cache.d.ts → executable-cache.d.ts} +2 -2
- package/dist/executable/{early-cache.js → executable-cache.js} +36 -98
- package/dist/executable/executable-cache.js.map +1 -0
- package/dist/executable/executable-cache.test.d.ts +1 -0
- package/dist/executable/{early-cache.test.js → executable-cache.test.js} +3 -3
- package/dist/executable/executable-cache.test.js.map +1 -0
- package/dist/ffi/{profile.js → ffi-manifest.js} +1 -1
- package/dist/ffi/ffi-manifest.js.map +1 -0
- package/dist/frontend/builtin-modules.d.ts +21 -0
- package/dist/frontend/builtin-modules.js +82 -0
- package/dist/frontend/builtin-modules.js.map +1 -0
- package/dist/frontend/cjs-lexer.d.ts +7 -0
- package/dist/frontend/cjs-lexer.js +15 -17
- package/dist/frontend/cjs-lexer.js.map +1 -1
- package/dist/frontend/dts-paths.d.ts +26 -0
- package/dist/frontend/dts-paths.js +41 -0
- package/dist/frontend/dts-paths.js.map +1 -0
- package/dist/frontend/input-tracker.d.ts +0 -2
- package/dist/frontend/input-tracker.js +1 -4
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.d.ts +1 -5
- package/dist/frontend/lib-contract.js +1 -1
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.d.ts +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -0
- package/dist/frontend/lowering/array-values.js +60 -0
- package/dist/frontend/lowering/array-values.js.map +1 -0
- package/dist/frontend/lowering/call-position.d.ts +4 -0
- package/dist/frontend/lowering/call-position.js +7 -0
- package/dist/frontend/lowering/call-position.js.map +1 -0
- package/dist/frontend/lowering/callback-arg.d.ts +20 -0
- package/dist/frontend/lowering/callback-arg.js +44 -0
- package/dist/frontend/lowering/callback-arg.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.d.ts +1 -1
- package/dist/frontend/lowering/lib-boundary.js +34 -34
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.d.ts +22 -0
- package/dist/frontend/lowering/lower-array-sort.js +619 -0
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.d.ts +3 -3
- package/dist/frontend/lowering/lower-assert.js +214 -241
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +74 -146
- package/dist/frontend/lowering/lower-builtins.js +1285 -1233
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +59 -192
- package/dist/frontend/lowering/lower-calls.js +1644 -1506
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +62 -125
- package/dist/frontend/lowering/lower-classes.js +832 -866
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +5 -12
- package/dist/frontend/lowering/lower-comptime.js +32 -31
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +35 -135
- package/dist/frontend/lowering/lower-containers.js +1984 -2227
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +3 -7
- package/dist/frontend/lowering/lower-dgram.js +97 -111
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.d.ts +4 -4
- package/dist/frontend/lowering/lower-enums.js +30 -30
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/{lower-emitter.d.ts → lower-event-emitter.d.ts} +7 -18
- package/dist/frontend/lowering/{lower-emitter.js → lower-event-emitter.js} +172 -174
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -0
- package/dist/frontend/lowering/lower-expando.d.ts +5 -5
- package/dist/frontend/lowering/lower-expando.js +40 -40
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +60 -264
- package/dist/frontend/lowering/lower-exprs.js +2361 -1765
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -6
- package/dist/frontend/lowering/lower-generators.js +73 -72
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +5 -17
- package/dist/frontend/lowering/lower-inspect.js +273 -261
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +39 -49
- package/dist/frontend/lowering/lower-island.js +447 -513
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.d.ts +7 -10
- package/dist/frontend/lowering/lower-mixins.js +85 -85
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +12 -18
- package/dist/frontend/lowering/lower-modules.js +284 -283
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +23 -49
- package/dist/frontend/lowering/lower-namespaces.js +123 -115
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +18 -25
- package/dist/frontend/lowering/lower-server.js +909 -899
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +30 -149
- package/dist/frontend/lowering/lower-stmts.js +1463 -1285
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +12 -12
- package/dist/frontend/lowering/lower-stream.js +300 -301
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +5 -5
- package/dist/frontend/lowering/lower-test.js +82 -82
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +134 -22
- package/dist/frontend/lowering/lowerer.js +1277 -126
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.d.ts +11 -0
- package/dist/frontend/lowering/pairs-snapshot.js +85 -0
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -0
- package/dist/frontend/lowering/static-this.d.ts +6 -0
- package/dist/frontend/lowering/static-this.js +24 -0
- package/dist/frontend/lowering/static-this.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +24 -35
- package/dist/frontend/lowering/surfaces.js +78 -66
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-rewrite.js +6 -28
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +0 -10
- package/dist/frontend/npm-static.js +4 -7
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +0 -24
- package/dist/frontend/npm.js +11 -85
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.d.ts +3 -1
- package/dist/frontend/program.js +9 -4
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance-registry.d.ts +0 -2
- package/dist/frontend/provenance-registry.js +0 -10
- package/dist/frontend/provenance-registry.js.map +1 -1
- package/dist/frontend/provenance.js +4 -7
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/resolve.d.ts +7 -2
- package/dist/frontend/resolve.js +12 -17
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.d.ts +1 -0
- package/dist/frontend/resolve.test.js +29 -0
- package/dist/frontend/resolve.test.js.map +1 -0
- package/dist/frontend/ts7/adapter.d.ts +2 -2
- package/dist/frontend/ts7/adapter.js +1 -1
- package/dist/frontend/ts7/adapter.js.map +1 -1
- package/dist/frontend/ts7/checker.js +2 -36
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/enums.js +2 -1
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/{program.js → program-adapter.js} +7 -6
- package/dist/frontend/ts7/program-adapter.js.map +1 -0
- package/dist/frontend/ts7/world-check.d.ts +1 -3
- package/dist/frontend/ts7/world-check.js +3 -1
- package/dist/frontend/ts7/world-check.js.map +1 -1
- package/dist/frontend/tsc-codes.d.ts +8 -0
- package/dist/frontend/tsc-codes.js +109 -0
- package/dist/frontend/tsc-codes.js.map +1 -0
- package/dist/frontend/{types.d.ts → type-mapper.d.ts} +2 -25
- package/dist/frontend/{types.js → type-mapper.js} +12 -11
- package/dist/frontend/type-mapper.js.map +1 -0
- package/dist/frontend/workspace-registry.d.ts +26 -0
- package/dist/frontend/workspace-registry.js +71 -0
- package/dist/frontend/workspace-registry.js.map +1 -0
- package/dist/index.d.ts +113 -31
- package/dist/index.js +536 -128
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +37 -0
- package/dist/ir/analysis.js +118 -0
- package/dist/ir/analysis.js.map +1 -0
- package/dist/ir/analysis.test.d.ts +1 -0
- package/dist/ir/analysis.test.js +21 -0
- package/dist/ir/analysis.test.js.map +1 -0
- package/dist/ir/build.d.ts +9 -0
- package/dist/ir/build.js +33 -0
- package/dist/ir/build.js.map +1 -0
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/{nodes.d.ts → ir.d.ts} +119 -37
- package/dist/ir/{nodes.js → ir.js} +170 -166
- package/dist/ir/ir.js.map +1 -0
- package/dist/ir/ir.test.d.ts +1 -0
- package/dist/ir/ir.test.js +17 -0
- package/dist/ir/ir.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +2 -2
- package/dist/ir/serialize.js +3 -2
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.d.ts +1 -1
- package/dist/ir/validate.js +93 -41
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/cache-primitives.d.ts +24 -0
- package/dist/library/cache-primitives.js +83 -0
- package/dist/library/cache-primitives.js.map +1 -0
- package/dist/library/cache-reset.test.d.ts +1 -0
- package/dist/library/cache-reset.test.js +47 -0
- package/dist/library/cache-reset.test.js.map +1 -0
- package/dist/library/{implementation-identity.js → compiler-self-identity.js} +1 -1
- package/dist/library/compiler-self-identity.js.map +1 -0
- package/dist/library/fence-eval.d.ts +3 -1
- package/dist/library/fence-eval.js +8 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.d.ts +1 -36
- package/dist/library/int-infer.js +29 -18
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/{early-cache.d.ts → library-cache.d.ts} +1 -1
- package/dist/library/{early-cache.js → library-cache.js} +34 -89
- package/dist/library/library-cache.js.map +1 -0
- package/dist/library/library-cache.test.d.ts +1 -0
- package/dist/library/{early-cache.test.js → library-cache.test.js} +7 -7
- package/dist/library/library-cache.test.js.map +1 -0
- package/dist/library/{profile.d.ts → library-profile.d.ts} +4 -7
- package/dist/library/{profile.js → library-profile.js} +18 -11
- package/dist/library/library-profile.js.map +1 -0
- package/dist/library/semantic-source.js +2 -1
- package/dist/library/semantic-source.js.map +1 -1
- package/dist/library/sidecar.d.ts +5 -2
- package/dist/library/sidecar.js +11 -5
- package/dist/library/sidecar.js.map +1 -1
- package/dist/startup-cache.d.ts +11 -3
- package/dist/startup-cache.js +17 -2
- package/dist/startup-cache.js.map +1 -1
- package/package.json +19 -2
- package/surface-manifest.json +5 -5
- package/dist/backend/cc-cache.test.js.map +0 -1
- package/dist/backend/cc.js.map +0 -1
- package/dist/backend/emission/emit-async.js.map +0 -1
- package/dist/backend/emission/emit-exprs.d.ts +0 -13
- package/dist/backend/emission/emit-exprs.js +0 -7407
- package/dist/backend/emission/emit-exprs.js.map +0 -1
- package/dist/backend/emission/emit-island.js.map +0 -1
- package/dist/backend/emission/emit-shapes.js.map +0 -1
- package/dist/backend/emission/emit-stmts.js.map +0 -1
- package/dist/backend/emission/emit-types.js.map +0 -1
- package/dist/backend/emission/emit-walkers.js.map +0 -1
- package/dist/backend/emission/emitter.js.map +0 -1
- package/dist/backend/emission/may-throw.js.map +0 -1
- package/dist/backend/library-identity.js.map +0 -1
- package/dist/executable/early-cache.js.map +0 -1
- package/dist/executable/early-cache.test.js.map +0 -1
- package/dist/ffi/profile.js.map +0 -1
- package/dist/frontend/lowering/lower-emitter.js.map +0 -1
- package/dist/frontend/shared.d.ts +0 -82
- package/dist/frontend/shared.js +0 -308
- package/dist/frontend/shared.js.map +0 -1
- package/dist/frontend/ts7/program.js.map +0 -1
- package/dist/frontend/types.js.map +0 -1
- package/dist/ir/nodes.js.map +0 -1
- package/dist/library/early-cache.js.map +0 -1
- package/dist/library/early-cache.test.js.map +0 -1
- package/dist/library/implementation-identity.js.map +0 -1
- package/dist/library/profile.js.map +0 -1
- /package/dist/backend/{cc-cache.test.d.ts → c/types.test.d.ts} +0 -0
- /package/dist/{executable/early-cache.test.d.ts → backend/llvm/shapes.test.d.ts} +0 -0
- /package/dist/{library/early-cache.test.d.ts → backend/native-codegen.test.d.ts} +0 -0
- /package/dist/ffi/{profile.d.ts → ffi-manifest.d.ts} +0 -0
- /package/dist/frontend/ts7/{program.d.ts → program-adapter.d.ts} +0 -0
- /package/dist/library/{implementation-identity.d.ts → compiler-self-identity.d.ts} +0 -0
|
@@ -0,0 +1,810 @@
|
|
|
1
|
+
/* Focused LLVM expression emission extracted from emitter.ts. */
|
|
2
|
+
import { InternalCompilerError } from "../../errors.js";
|
|
3
|
+
import { streamTypedRefEligible } from "../../ir/analysis.js";
|
|
4
|
+
import { DYN, isRefCounted, isUnitType, typeEquals, typeKey } from "../../ir/ir.js";
|
|
5
|
+
import { DYN_KIND } from "./dyn.js";
|
|
6
|
+
import { elemAccess, vAdapters } from "./shapes.js";
|
|
7
|
+
import { LlvmUnsupportedError } from "./unsupported.js";
|
|
8
|
+
export function emitDynamicExpr(host, e) {
|
|
9
|
+
const B = host.B;
|
|
10
|
+
switch (e.kind) {
|
|
11
|
+
case "dynFrom": {
|
|
12
|
+
// Static value → fresh dyn tree (+1) through the interned per-type
|
|
13
|
+
// converter; the operand stays borrowed (frame-released as usual).
|
|
14
|
+
// Bare unit literals (an `undefined`/`null` stored under an
|
|
15
|
+
// `unknown` index signature) are the dyn unit values directly.
|
|
16
|
+
if (e.value.kind === "unitLit") {
|
|
17
|
+
const t = B.tmp();
|
|
18
|
+
if (e.value.unit === "undefined") {
|
|
19
|
+
host.declare(`declare ptr @scr_dyn_undefined()`);
|
|
20
|
+
host.declare(`declare ptr @scr_dyn_retain_v(ptr)`);
|
|
21
|
+
const u = B.tmp();
|
|
22
|
+
B.line(`${u} = call ptr @scr_dyn_undefined()`);
|
|
23
|
+
B.line(`${t} = call ptr @scr_dyn_retain_v(ptr ${u})`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
host.declare(`declare ptr @scr_dyn_new_null()`);
|
|
27
|
+
B.line(`${t} = call ptr @scr_dyn_new_null()`);
|
|
28
|
+
}
|
|
29
|
+
return host.own({ name: t, type: e.type });
|
|
30
|
+
}
|
|
31
|
+
const v = host.emitExpr(e.value);
|
|
32
|
+
if (e.liveRef) {
|
|
33
|
+
if (v.type.kind === "union") {
|
|
34
|
+
const adapter = host.liveDynUnionRefAdapter(v.type);
|
|
35
|
+
const boxed = B.tmp();
|
|
36
|
+
B.line(`${boxed} = call ptr @${adapter}(ptr ${v.name})`);
|
|
37
|
+
return host.own({ name: boxed, type: e.type });
|
|
38
|
+
}
|
|
39
|
+
if (!streamTypedRefEligible(v.type)) {
|
|
40
|
+
throw new InternalCompilerError(`llvm emitter bug: live dyn ref of ${typeKey(v.type)}`);
|
|
41
|
+
}
|
|
42
|
+
const key = typeKey(v.type);
|
|
43
|
+
let adapter = host.liveDynRefAdapters.get(key);
|
|
44
|
+
if (!adapter) {
|
|
45
|
+
const prefix = `sc_ldr_${host.liveDynRefAdapters.size}`;
|
|
46
|
+
adapter = host.streamTypedRefMaterializeAdapter(v.type, { prefix, adapters: new Map() }, `${prefix}_materialize`);
|
|
47
|
+
host.liveDynRefAdapters.set(key, adapter);
|
|
48
|
+
}
|
|
49
|
+
const rc = vAdapters(host, v.type);
|
|
50
|
+
host.declare(`declare ptr @scr_dyn_new_typed_ref(ptr, ptr, ptr, ptr, ${host.sizeType}, ptr, ptr)`);
|
|
51
|
+
const boxed = B.tmp();
|
|
52
|
+
B.line(`${boxed} = call ptr @scr_dyn_new_typed_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${host.cstr(key)}, ${host.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr @${adapter.snapshot}, ptr ${adapter.commit})`);
|
|
53
|
+
return host.own({ name: boxed, type: e.type });
|
|
54
|
+
}
|
|
55
|
+
if (v.type.kind === "func") {
|
|
56
|
+
// A closure boxes as the checked-dynamic tree's function kind: retained closure +
|
|
57
|
+
// the per-signature call thunk + the interned signature key. The
|
|
58
|
+
// best-effort name rides along (null when the lowering had none).
|
|
59
|
+
const name = e.fnName !== undefined && e.fnName !== "" ? host.cstr(e.fnName) : "null";
|
|
60
|
+
const box = host.dyn.dynFuncBoxHelper(v.type);
|
|
61
|
+
const t = B.tmp();
|
|
62
|
+
B.line(`${t} = call ptr @${box}(ptr ${v.name}, ptr ${name})`);
|
|
63
|
+
return host.own({ name: t, type: e.type });
|
|
64
|
+
}
|
|
65
|
+
const conv = host.dyn.toDynHelper(v.type);
|
|
66
|
+
const valTy = v.type.kind === "f64" ? "double" : v.type.kind === "bool" ? "i1" : "ptr";
|
|
67
|
+
const t = B.tmp();
|
|
68
|
+
B.line(`${t} = call ptr @${conv}(${valTy} ${v.name})`);
|
|
69
|
+
return host.own({ name: t, type: e.type });
|
|
70
|
+
}
|
|
71
|
+
case "dynFromJsval": {
|
|
72
|
+
// Island value → dyn: the by-reference wrap (scr_dyn_from_jsval
|
|
73
|
+
// retains the cell in; engine scalars normalize to native dyn
|
|
74
|
+
// kinds at wrap time). Operand borrowed, result +1, never throws.
|
|
75
|
+
const v = host.emitExpr(e.value);
|
|
76
|
+
host.declare(`declare ptr @scr_dyn_from_jsval(ptr)`);
|
|
77
|
+
const t = B.tmp();
|
|
78
|
+
B.line(`${t} = call ptr @scr_dyn_from_jsval(ptr ${v.name})`);
|
|
79
|
+
return host.own({ name: t, type: e.type });
|
|
80
|
+
}
|
|
81
|
+
case "dynCall": {
|
|
82
|
+
// Calling a dyn value: args are already dyn (the lowering boxed or
|
|
83
|
+
// converted them); everything is BORROWED by scr_dyn_call — the
|
|
84
|
+
// boxed thunk builds its own typed copies. The callee's source
|
|
85
|
+
// spelling rides along for Node's "<name> is not a function".
|
|
86
|
+
const callee = host.emitExpr(e.callee);
|
|
87
|
+
if (e.spreads !== undefined && e.spreads.length > 0) {
|
|
88
|
+
// The RUNTIME-ARITY form (`f(...args)`): one fresh dyn array
|
|
89
|
+
// collects the arguments left-to-right — plain args move in
|
|
90
|
+
// (push takes ownership), spread args FLATTEN (push_spread
|
|
91
|
+
// retains elements in and throws V8's spread-call TypeError for
|
|
92
|
+
// non-iterable dyn kinds, checked per spread — JS's
|
|
93
|
+
// ArgumentListEvaluation order) — then apply calls through the
|
|
94
|
+
// array's elements (borrowed, exactly scr_dyn_call).
|
|
95
|
+
host.declare(`declare ptr @scr_dyn_new_arr()`);
|
|
96
|
+
host.declare(`declare void @scr_dyn_arr_push(ptr, ptr)`);
|
|
97
|
+
host.declare(`declare void @scr_dyn_arr_push_spread(ptr, ptr, ptr)`);
|
|
98
|
+
host.declare(`declare ptr @scr_dyn_apply(ptr, ptr, ptr)`);
|
|
99
|
+
const spreadAt = new Map(e.spreads.map((s) => [s.arg, s.what]));
|
|
100
|
+
const pack = B.tmp();
|
|
101
|
+
B.line(`${pack} = call ptr @scr_dyn_new_arr()`);
|
|
102
|
+
host.own({ name: pack, type: DYN });
|
|
103
|
+
e.args.forEach((a, i) => {
|
|
104
|
+
const v = host.emitExpr(a);
|
|
105
|
+
const spreadWhat = spreadAt.get(i);
|
|
106
|
+
if (spreadWhat !== undefined) {
|
|
107
|
+
B.line(`call void @scr_dyn_arr_push_spread(ptr ${pack}, ptr ${v.name}, ptr ${host.cstr(spreadWhat)})`);
|
|
108
|
+
host.emitPendingCheck();
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
host.moveTemp(v);
|
|
112
|
+
B.line(`call void @scr_dyn_arr_push(ptr ${pack}, ptr ${v.name})`);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
const t = B.tmp();
|
|
116
|
+
B.line(`${t} = call ptr @scr_dyn_apply(ptr ${callee.name}, ptr ${pack}, ptr ${host.cstr(e.calleeName)})`);
|
|
117
|
+
const out = host.own({ name: t, type: e.type });
|
|
118
|
+
host.emitPendingCheck();
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
const args = e.args.map((a) => host.emitExpr(a));
|
|
122
|
+
let argsPtr = "null";
|
|
123
|
+
if (args.length > 0) {
|
|
124
|
+
const arr = B.slot();
|
|
125
|
+
B.entryAllocas.push(`${arr} = alloca [${args.length} x ptr]`);
|
|
126
|
+
args.forEach((a, i) => {
|
|
127
|
+
const p = B.tmp();
|
|
128
|
+
B.line(`${p} = getelementptr inbounds [${args.length} x ptr], ptr ${arr}, i64 0, ${host.sizeType} ${i}`);
|
|
129
|
+
B.line(`store ptr ${a.name}, ptr ${p}`);
|
|
130
|
+
});
|
|
131
|
+
argsPtr = arr;
|
|
132
|
+
}
|
|
133
|
+
host.declare(`declare ptr @scr_dyn_call(ptr, ptr, ${host.sizeType}, ptr)`);
|
|
134
|
+
const t = B.tmp();
|
|
135
|
+
B.line(`${t} = call ptr @scr_dyn_call(ptr ${callee.name}, ptr ${argsPtr}, ${host.sizeType} ${args.length}, ptr ${host.cstr(e.calleeName)})`);
|
|
136
|
+
const out = host.own({ name: t, type: e.type });
|
|
137
|
+
host.emitPendingCheck();
|
|
138
|
+
return out;
|
|
139
|
+
}
|
|
140
|
+
case "dynInvoke": {
|
|
141
|
+
// Prototype-method dispatch on a dyn receiver: everything is
|
|
142
|
+
// BORROWED by scr_dyn_invoke; the result is owned and may ride a
|
|
143
|
+
// pending exception.
|
|
144
|
+
const recv = host.emitExpr(e.recv);
|
|
145
|
+
const args = e.args.map((a) => host.emitExpr(a));
|
|
146
|
+
let argsPtr = "null";
|
|
147
|
+
if (args.length > 0) {
|
|
148
|
+
const arr = B.slot();
|
|
149
|
+
B.entryAllocas.push(`${arr} = alloca [${args.length} x ptr]`);
|
|
150
|
+
args.forEach((a, i) => {
|
|
151
|
+
const p = B.tmp();
|
|
152
|
+
B.line(`${p} = getelementptr inbounds [${args.length} x ptr], ptr ${arr}, i64 0, ${host.sizeType} ${i}`);
|
|
153
|
+
B.line(`store ptr ${a.name}, ptr ${p}`);
|
|
154
|
+
});
|
|
155
|
+
argsPtr = arr;
|
|
156
|
+
}
|
|
157
|
+
host.declare(`declare ptr @scr_dyn_invoke(ptr, ptr, ptr, ${host.sizeType}, ptr)`);
|
|
158
|
+
const t = B.tmp();
|
|
159
|
+
B.line(`${t} = call ptr @scr_dyn_invoke(ptr ${recv.name}, ptr ${host.cstr(e.method)}, ptr ${argsPtr}, ${host.sizeType} ${args.length}, ptr ${host.cstr(e.calleeName)})`);
|
|
160
|
+
const out = host.own({ name: t, type: e.type });
|
|
161
|
+
host.emitPendingCheck();
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
case "dynArrLit": {
|
|
165
|
+
// A dyn array built element-by-element: ownership of each dyn
|
|
166
|
+
// element MOVES into the array (scr_dyn_arr_push's contract).
|
|
167
|
+
host.declare(`declare ptr @scr_dyn_new_arr()`);
|
|
168
|
+
host.declare(`declare void @scr_dyn_arr_push(ptr, ptr)`);
|
|
169
|
+
const arr = B.tmp();
|
|
170
|
+
B.line(`${arr} = call ptr @scr_dyn_new_arr()`);
|
|
171
|
+
const out = host.own({ name: arr, type: e.type });
|
|
172
|
+
for (const el of e.elems) {
|
|
173
|
+
const v = host.emitExpr(el);
|
|
174
|
+
host.moveTemp(v);
|
|
175
|
+
B.line(`call void @scr_dyn_arr_push(ptr ${arr}, ptr ${v.name})`);
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
case "dynObjLit": {
|
|
180
|
+
// A dyn object built member-by-member: key then value, source
|
|
181
|
+
// order. scr_dyn_key_set BORROWS all three (the member retains the
|
|
182
|
+
// value in); the receiver is a fresh OBJ, so the non-object throw
|
|
183
|
+
// paths are unreachable here.
|
|
184
|
+
host.declare(`declare ptr @scr_dyn_new_obj()`);
|
|
185
|
+
host.declare(`declare void @scr_dyn_key_set(ptr, ptr, ptr)`);
|
|
186
|
+
const obj = B.tmp();
|
|
187
|
+
B.line(`${obj} = call ptr @scr_dyn_new_obj()`);
|
|
188
|
+
const out = host.own({ name: obj, type: e.type });
|
|
189
|
+
for (const f of e.fields ?? []) {
|
|
190
|
+
const k = host.emitExpr(f.key);
|
|
191
|
+
const v = host.emitExpr(f.value);
|
|
192
|
+
B.line(`call void @scr_dyn_key_set(ptr ${obj}, ptr ${k.name}, ptr ${v.name})`);
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
case "unionWrap": {
|
|
197
|
+
// Construct a fresh immutable tagged box. Ownership of a refcounted
|
|
198
|
+
// payload MOVES into the union; scalars ride the slot. Unit arms
|
|
199
|
+
// carry NO payload: every wrap yields THE interned immortal
|
|
200
|
+
// instance for this (union, tag) — no allocation, and the frame's
|
|
201
|
+
// release is a no-op (rc == SIZE_MAX).
|
|
202
|
+
const arm = e.value.type;
|
|
203
|
+
if (isUnitType(arm)) {
|
|
204
|
+
return host.own({ name: host.unitInstanceRef(e.unionId, e.tag), type: e.type });
|
|
205
|
+
}
|
|
206
|
+
// A VOID payload (a void call wrapping into an undefined arm):
|
|
207
|
+
// evaluate for effects, produce the interned unit instance.
|
|
208
|
+
if (arm.kind === "void") {
|
|
209
|
+
host.emitExpr(e.value);
|
|
210
|
+
return host.own({ name: host.unitInstanceRef(e.unionId, e.tag), type: e.type });
|
|
211
|
+
}
|
|
212
|
+
const v = host.emitExpr(e.value);
|
|
213
|
+
if (isRefCounted(arm))
|
|
214
|
+
host.moveTemp(v);
|
|
215
|
+
return host.own({ name: host.unionNewOwned(e.tag, v), type: e.type });
|
|
216
|
+
}
|
|
217
|
+
case "unionNarrow": {
|
|
218
|
+
// Tag-UNCHECKED payload extraction: the frontend emits this only
|
|
219
|
+
// where tsc's control-flow narrowing proved the tag. Ref payloads
|
|
220
|
+
// come out +1; the union temp itself releases with this
|
|
221
|
+
// statement's frame as usual.
|
|
222
|
+
const u = host.emitExpr(e.value);
|
|
223
|
+
const arm = e.type;
|
|
224
|
+
if (isUnitType(arm))
|
|
225
|
+
throw new InternalCompilerError(`llvm emitter bug: unionNarrow to unit arm ${arm.kind}`);
|
|
226
|
+
const v = host.unionExtract(u.name, arm);
|
|
227
|
+
return host.own({ name: v, type: arm });
|
|
228
|
+
}
|
|
229
|
+
case "unionDisc": {
|
|
230
|
+
// Shared-field read `r.kind`: switch on the runtime tag and read
|
|
231
|
+
// the (same-typed) field from the concretely-typed payload.
|
|
232
|
+
// Ref-counted results come out retained (+1), owned by this frame.
|
|
233
|
+
const u = host.emitExpr(e.value);
|
|
234
|
+
const def = host.unionsById.get(e.unionId);
|
|
235
|
+
if (!def)
|
|
236
|
+
throw new InternalCompilerError(`llvm emitter bug: unionDisc of unknown union ${e.unionId}`);
|
|
237
|
+
const ty = host.llType(e.type);
|
|
238
|
+
const slot = B.slot();
|
|
239
|
+
B.entryAllocas.push(`${slot} = alloca ${ty}`);
|
|
240
|
+
const join = B.newLabel("ud.j");
|
|
241
|
+
host.unionTagSwitch(u.name, def, (arm) => {
|
|
242
|
+
if (arm.kind !== "record" && arm.kind !== "object") {
|
|
243
|
+
throw new LlvmUnsupportedError(`unionDisc:${arm.kind}`, e.loc);
|
|
244
|
+
}
|
|
245
|
+
const payload = host.unionPeek(u.name);
|
|
246
|
+
const { ptr, type } = arm.kind === "object"
|
|
247
|
+
? host.classFieldPtr(payload, arm.className, e.field)
|
|
248
|
+
: host.recordFieldPtr(payload, arm.shapeId, e.field);
|
|
249
|
+
const v = host.loadField(ptr, type);
|
|
250
|
+
const value = isRefCounted(e.type) ? host.retainValue(v, e.type) : v;
|
|
251
|
+
B.line(`store ${ty} ${value}, ptr ${slot}`);
|
|
252
|
+
B.br(join);
|
|
253
|
+
});
|
|
254
|
+
B.startBlock(join);
|
|
255
|
+
const t = B.tmp();
|
|
256
|
+
B.line(`${t} = load ${ty}, ptr ${slot}`);
|
|
257
|
+
return host.own({ name: t, type: e.type });
|
|
258
|
+
}
|
|
259
|
+
case "unionKeyGet": {
|
|
260
|
+
// The unionDisc generalization: switch on the runtime tag; each
|
|
261
|
+
// arm answers at the JOIN type — a declared field reads its slot
|
|
262
|
+
// (wrapping an arm-typed answer into the join), an index-signature
|
|
263
|
+
// arm rides the shared keyed-read chain (owned result, missing-key
|
|
264
|
+
// policy included), and a unit arm answers the interned undefined
|
|
265
|
+
// arm (the optional-chain tail's short-circuit value).
|
|
266
|
+
const u = host.emitExpr(e.value);
|
|
267
|
+
const k = host.emitExpr(e.key);
|
|
268
|
+
const def = host.unionsById.get(e.unionId);
|
|
269
|
+
if (!def)
|
|
270
|
+
throw new InternalCompilerError(`llvm emitter bug: unionKeyGet of unknown union ${e.unionId}`);
|
|
271
|
+
const resultDef = e.type.kind === "union" ? host.unionsById.get(e.type.unionId) : undefined;
|
|
272
|
+
const literal = e.key.kind === "strLit" ? e.key.value : null;
|
|
273
|
+
const ty = host.llType(e.type);
|
|
274
|
+
const slot = B.slot();
|
|
275
|
+
B.entryAllocas.push(`${slot} = alloca ${ty}`);
|
|
276
|
+
const join = B.newLabel("ukg.j");
|
|
277
|
+
host.unionTagSwitch(u.name, def, (arm) => {
|
|
278
|
+
if (isUnitType(arm)) {
|
|
279
|
+
if (e.type.kind === "dyn") {
|
|
280
|
+
// A dyn-typed chain: the unit path is the undefined dyn
|
|
281
|
+
// value — dyn represents undefined directly.
|
|
282
|
+
host.declare(`declare ptr @scr_dyn_undefined()`);
|
|
283
|
+
host.declare(`declare ptr @scr_dyn_retain_v(ptr)`);
|
|
284
|
+
const un = B.tmp();
|
|
285
|
+
const r = B.tmp();
|
|
286
|
+
B.line(`${un} = call ptr @scr_dyn_undefined()`);
|
|
287
|
+
B.line(`${r} = call ptr @scr_dyn_retain_v(ptr ${un})`);
|
|
288
|
+
B.line(`store ptr ${r}, ptr ${slot}`);
|
|
289
|
+
B.br(join);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const tag = resultDef?.arms.findIndex((a) => a.kind === "undefinedT") ?? -1;
|
|
293
|
+
if (tag < 0 || e.type.kind !== "union") {
|
|
294
|
+
throw new InternalCompilerError("llvm emitter bug: unionKeyGet unit arm without an undefined result arm");
|
|
295
|
+
}
|
|
296
|
+
B.line(`store ptr ${host.unitInstanceRef(e.type.unionId, tag)}, ptr ${slot}`);
|
|
297
|
+
B.br(join);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (arm.kind === "array") {
|
|
301
|
+
// A NUMBER-keyed element read (the chain-tail form): the
|
|
302
|
+
// runtime getter answers owned (+1 for ref elements); invalid
|
|
303
|
+
// indices trap. The result wraps into the join when unit arms
|
|
304
|
+
// widened it.
|
|
305
|
+
const payload = host.unionPeek(u.name);
|
|
306
|
+
const acc = elemAccess(arm.elem);
|
|
307
|
+
const accTy = acc === "f64" ? "double" : acc === "bool" ? "i1" : "ptr";
|
|
308
|
+
host.declare(`declare ${acc === "bool" ? "zeroext i1" : accTy} @scr_arr_get_${acc}(ptr, double)`);
|
|
309
|
+
const v = B.tmp();
|
|
310
|
+
B.line(`${v} = call ${accTy} @scr_arr_get_${acc}(ptr ${payload}, double ${k.name})`);
|
|
311
|
+
if (typeEquals(arm.elem, e.type)) {
|
|
312
|
+
B.line(`store ${ty} ${v}, ptr ${slot}`);
|
|
313
|
+
B.br(join);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const tag = resultDef?.arms.findIndex((a) => typeEquals(a, arm.elem)) ?? -1;
|
|
317
|
+
if (tag < 0 || e.type.kind !== "union" || isUnitType(arm.elem)) {
|
|
318
|
+
throw new InternalCompilerError(`llvm emitter bug: unionKeyGet element ${arm.elem.kind} outside the join`);
|
|
319
|
+
}
|
|
320
|
+
// The element read is already owned (+1) — ownership MOVES
|
|
321
|
+
// into the union box, no extra retain.
|
|
322
|
+
B.line(`store ptr ${host.unionNewOwned(tag, { name: v, type: arm.elem })}, ptr ${slot}`);
|
|
323
|
+
B.br(join);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (arm.kind !== "record")
|
|
327
|
+
throw new LlvmUnsupportedError(`unionKeyGet:${arm.kind}`, e.loc);
|
|
328
|
+
const shape = host.recordShape(arm.shapeId);
|
|
329
|
+
const payload = host.unionPeek(u.name);
|
|
330
|
+
const declared = literal !== null ? shape.fields.find((f) => f.name === literal) : undefined;
|
|
331
|
+
if (declared) {
|
|
332
|
+
const { ptr, type: ft } = host.recordFieldPtr(payload, arm.shapeId, declared.name);
|
|
333
|
+
const v = host.loadField(ptr, ft);
|
|
334
|
+
if (typeEquals(ft, e.type)) {
|
|
335
|
+
B.line(`store ${ty} ${isRefCounted(ft) ? host.retainValue(v, ft) : v}, ptr ${slot}`);
|
|
336
|
+
B.br(join);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const tag = resultDef?.arms.findIndex((a) => typeEquals(a, ft)) ?? -1;
|
|
340
|
+
if (tag < 0 || e.type.kind !== "union" || isUnitType(ft)) {
|
|
341
|
+
throw new InternalCompilerError(`llvm emitter bug: unionKeyGet arm answer ${ft.kind} outside the join`);
|
|
342
|
+
}
|
|
343
|
+
const wrapped = ft.kind === "f64" || ft.kind === "bool"
|
|
344
|
+
? host.unionNewOwned(tag, { name: v, type: ft })
|
|
345
|
+
: host.unionNewOwned(tag, { name: host.retainValue(v, ft), type: ft });
|
|
346
|
+
B.line(`store ptr ${wrapped}, ptr ${slot}`);
|
|
347
|
+
B.br(join);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
// Index-signature arm (or declared-only shape under a runtime
|
|
351
|
+
// key): the shared keyed-read chain — a literal key naming no
|
|
352
|
+
// declared field touches only the overflow map.
|
|
353
|
+
host.keyedRecordReadInto(slot, join, payload, k.name, arm.shapeId, e.type, literal !== null && !!shape.indexValue, e.loc);
|
|
354
|
+
});
|
|
355
|
+
B.startBlock(join);
|
|
356
|
+
const t = B.tmp();
|
|
357
|
+
B.line(`${t} = load ${ty}, ptr ${slot}`);
|
|
358
|
+
return host.own({ name: t, type: e.type });
|
|
359
|
+
}
|
|
360
|
+
case "unionIsTag": {
|
|
361
|
+
// A pure tag compare — the box is borrowed, no payload is touched.
|
|
362
|
+
const u = host.emitExpr(e.value);
|
|
363
|
+
const tag = host.unionTag(u.name);
|
|
364
|
+
const t = B.tmp();
|
|
365
|
+
B.line(`${t} = icmp ${e.negated ? "ne" : "eq"} i32 ${tag}, ${e.tag}`);
|
|
366
|
+
return { name: t, type: e.type };
|
|
367
|
+
}
|
|
368
|
+
case "dynKeyGet": {
|
|
369
|
+
// Keyed read on the checked-dynamic tree through the one interned helper — the
|
|
370
|
+
// non-optional form throws JS's TypeError on an undefined/null
|
|
371
|
+
// receiver, and HANDLE receivers can throw the loud unmodeled-
|
|
372
|
+
// property ladder on EITHER form; the result is owned (+1).
|
|
373
|
+
const d = host.emitExpr(e.value);
|
|
374
|
+
const k = host.emitExpr(e.key);
|
|
375
|
+
const helper = host.dyn.dynKeyGetHelper();
|
|
376
|
+
const t = B.tmp();
|
|
377
|
+
B.line(`${t} = call ptr @${helper}(ptr ${d.name}, ptr ${k.name}, i1 ${e.optional ? "true" : "false"})`);
|
|
378
|
+
const out = host.own({ name: t, type: e.type });
|
|
379
|
+
host.emitPendingCheck();
|
|
380
|
+
return out;
|
|
381
|
+
}
|
|
382
|
+
case "dynHasKey": {
|
|
383
|
+
// `"k" in pkg`: a kind-guarded presence answer, computed against
|
|
384
|
+
// the literal key at compile time — no allocation, borrowed box.
|
|
385
|
+
const d = host.emitExpr(e.value);
|
|
386
|
+
const kd = host.dynKind(d.name);
|
|
387
|
+
const slot = B.slot();
|
|
388
|
+
B.entryAllocas.push(`${slot} = alloca i1`);
|
|
389
|
+
B.line(`store i1 false, ptr ${slot}`);
|
|
390
|
+
const lObj = B.newLabel("dhk.o");
|
|
391
|
+
const lArr = B.newLabel("dhk.a");
|
|
392
|
+
const lNotObj = B.newLabel("dhk.no");
|
|
393
|
+
const lj = B.newLabel("dhk.j");
|
|
394
|
+
const isObj = B.tmp();
|
|
395
|
+
B.line(`${isObj} = icmp eq i32 ${kd}, ${DYN_KIND.OBJ}`);
|
|
396
|
+
B.condBr(isObj, lObj, lNotObj);
|
|
397
|
+
B.startBlock(lObj);
|
|
398
|
+
host.declare(`declare ptr @scr_dyn_obj_get(ptr, ptr, ${host.sizeType})`);
|
|
399
|
+
const keyBytes = Buffer.byteLength(e.key, "utf8");
|
|
400
|
+
const m = B.tmp();
|
|
401
|
+
const has = B.tmp();
|
|
402
|
+
B.line(`${m} = call ptr @scr_dyn_obj_get(ptr ${d.name}, ptr ${host.cstr(e.key)}, ${host.sizeType} ${keyBytes})`);
|
|
403
|
+
B.line(`${has} = icmp ne ptr ${m}, null`);
|
|
404
|
+
B.line(`store i1 ${has}, ptr ${slot}`);
|
|
405
|
+
B.br(lj);
|
|
406
|
+
B.startBlock(lNotObj);
|
|
407
|
+
const isArr = B.tmp();
|
|
408
|
+
B.line(`${isArr} = icmp eq i32 ${kd}, ${DYN_KIND.ARR}`);
|
|
409
|
+
const lNotArr = B.newLabel("dhk.na");
|
|
410
|
+
B.condBr(isArr, lArr, lNotArr);
|
|
411
|
+
B.startBlock(lArr);
|
|
412
|
+
if (e.key === "length") {
|
|
413
|
+
B.line(`store i1 true, ptr ${slot}`);
|
|
414
|
+
}
|
|
415
|
+
else if (/^(0|[1-9][0-9]*)$/.test(e.key) && Number(e.key) <= Number.MAX_SAFE_INTEGER) {
|
|
416
|
+
const lenp = B.tmp();
|
|
417
|
+
const len = B.tmp();
|
|
418
|
+
const inR = B.tmp();
|
|
419
|
+
B.line(`${lenp} = getelementptr inbounds i8, ptr ${d.name}, i64 16 ; ->v.arr.len`);
|
|
420
|
+
B.line(`${len} = load ${host.sizeType}, ptr ${lenp}`);
|
|
421
|
+
B.line(`${inR} = icmp ugt ${host.sizeType} ${len}, ${e.key}`);
|
|
422
|
+
B.line(`store i1 ${inR}, ptr ${slot}`);
|
|
423
|
+
}
|
|
424
|
+
B.br(lj);
|
|
425
|
+
// An ISLAND-held receiver fences loudly (Node asks the real
|
|
426
|
+
// engine object — `false` would be a silent wrong answer); the
|
|
427
|
+
// helper answers false for every other kind, so this arm is a
|
|
428
|
+
// plain unconditional call.
|
|
429
|
+
B.startBlock(lNotArr);
|
|
430
|
+
host.declare(`declare zeroext i1 @scr_dyn_isl_fence(ptr, ptr)`);
|
|
431
|
+
const fenced = B.tmp();
|
|
432
|
+
B.line(`${fenced} = call zeroext i1 @scr_dyn_isl_fence(ptr ${d.name}, ptr ${host.cstr("'in'")})`);
|
|
433
|
+
B.line(`store i1 ${fenced}, ptr ${slot}`);
|
|
434
|
+
B.br(lj);
|
|
435
|
+
B.startBlock(lj);
|
|
436
|
+
const raw = B.tmp();
|
|
437
|
+
B.line(`${raw} = load i1, ptr ${slot}`);
|
|
438
|
+
host.emitPendingCheck();
|
|
439
|
+
if (!e.negated)
|
|
440
|
+
return { name: raw, type: e.type };
|
|
441
|
+
const neg = B.tmp();
|
|
442
|
+
B.line(`${neg} = xor i1 ${raw}, true`);
|
|
443
|
+
return { name: neg, type: e.type };
|
|
444
|
+
}
|
|
445
|
+
case "dynScalarEq": {
|
|
446
|
+
// dyn vs scalar strict equality: kind test + payload compare.
|
|
447
|
+
// Operands emit in SOURCE order; the dyn side is found by type.
|
|
448
|
+
// Both borrowed, no allocation.
|
|
449
|
+
const l = host.emitExpr(e.left);
|
|
450
|
+
const r = host.emitExpr(e.right);
|
|
451
|
+
const [d, s, st] = e.left.type.kind === "dyn" ? [l, r, e.right.type] : [r, l, e.left.type];
|
|
452
|
+
let test;
|
|
453
|
+
if (st.kind === "dyn") {
|
|
454
|
+
// dyn vs dyn: whole-dyn strict equality.
|
|
455
|
+
host.declare(`declare zeroext i1 @scr_dyn_strict_eq(ptr, ptr)`);
|
|
456
|
+
test = B.tmp();
|
|
457
|
+
B.line(`${test} = call zeroext i1 @scr_dyn_strict_eq(ptr ${l.name}, ptr ${r.name})`);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
const kd = host.dynKind(d.name);
|
|
461
|
+
const kindOk = B.tmp();
|
|
462
|
+
const wantKind = st.kind === "string" ? DYN_KIND.STR : st.kind === "f64" ? DYN_KIND.NUM : DYN_KIND.BOOL;
|
|
463
|
+
B.line(`${kindOk} = icmp eq i32 ${kd}, ${wantKind}`);
|
|
464
|
+
const slot = B.slot();
|
|
465
|
+
B.entryAllocas.push(`${slot} = alloca i1`);
|
|
466
|
+
B.line(`store i1 false, ptr ${slot}`);
|
|
467
|
+
const lCmp = B.newLabel("dse.c");
|
|
468
|
+
const lj = B.newLabel("dse.j");
|
|
469
|
+
B.condBr(kindOk, lCmp, lj);
|
|
470
|
+
B.startBlock(lCmp);
|
|
471
|
+
const pv = B.tmp();
|
|
472
|
+
const eq = B.tmp();
|
|
473
|
+
if (st.kind === "string") {
|
|
474
|
+
host.declare(`declare zeroext i1 @scr_str_eq(ptr, ptr)`);
|
|
475
|
+
B.line(`${pv} = getelementptr inbounds i8, ptr ${d.name}, i64 16 ; ->v.str`);
|
|
476
|
+
const sv = B.tmp();
|
|
477
|
+
B.line(`${sv} = load ptr, ptr ${pv}`);
|
|
478
|
+
B.line(`${eq} = call zeroext i1 @scr_str_eq(ptr ${sv}, ptr ${s.name})`);
|
|
479
|
+
}
|
|
480
|
+
else if (st.kind === "f64") {
|
|
481
|
+
B.line(`${pv} = getelementptr inbounds i8, ptr ${d.name}, i64 16 ; ->v.num`);
|
|
482
|
+
const nv = B.tmp();
|
|
483
|
+
B.line(`${nv} = load double, ptr ${pv}`);
|
|
484
|
+
B.line(`${eq} = fcmp oeq double ${nv}, ${s.name}`);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
B.line(`${pv} = getelementptr inbounds i8, ptr ${d.name}, i64 16 ; ->v.b`);
|
|
488
|
+
const raw = B.tmp();
|
|
489
|
+
const bv = B.tmp();
|
|
490
|
+
B.line(`${raw} = load i8, ptr ${pv}`);
|
|
491
|
+
B.line(`${bv} = trunc i8 ${raw} to i1`);
|
|
492
|
+
B.line(`${eq} = icmp eq i1 ${bv}, ${s.name}`);
|
|
493
|
+
}
|
|
494
|
+
B.line(`store i1 ${eq}, ptr ${slot}`);
|
|
495
|
+
B.br(lj);
|
|
496
|
+
B.startBlock(lj);
|
|
497
|
+
test = B.tmp();
|
|
498
|
+
B.line(`${test} = load i1, ptr ${slot}`);
|
|
499
|
+
}
|
|
500
|
+
if (!e.negated)
|
|
501
|
+
return { name: test, type: e.type };
|
|
502
|
+
const neg = B.tmp();
|
|
503
|
+
B.line(`${neg} = xor i1 ${test}, true`);
|
|
504
|
+
return { name: neg, type: e.type };
|
|
505
|
+
}
|
|
506
|
+
case "dynTest": {
|
|
507
|
+
// A pure kind compare on the dyn node — borrowed; only the truthy
|
|
508
|
+
// form also reads a scalar payload (the runtime's ToBoolean).
|
|
509
|
+
const d = host.emitExpr(e.value);
|
|
510
|
+
let test;
|
|
511
|
+
if (e.test === "truthy") {
|
|
512
|
+
host.declare(`declare zeroext i1 @scr_dyn_truthy(ptr)`);
|
|
513
|
+
test = B.tmp();
|
|
514
|
+
B.line(`${test} = call zeroext i1 @scr_dyn_truthy(ptr ${d.name})`);
|
|
515
|
+
}
|
|
516
|
+
else if (e.test === "error") {
|
|
517
|
+
// `u instanceof Error`: the checked-dynamic tree's error encoding — an object
|
|
518
|
+
// carrying the reserved "%error" marker key — or a real engine
|
|
519
|
+
// Error held by reference (the isl helper answers false for
|
|
520
|
+
// every non-JSVAL kind, so the call is unconditional).
|
|
521
|
+
const kd = host.dynKind(d.name);
|
|
522
|
+
const isObj = B.tmp();
|
|
523
|
+
B.line(`${isObj} = icmp eq i32 ${kd}, ${DYN_KIND.OBJ}`);
|
|
524
|
+
const slot = B.slot();
|
|
525
|
+
B.entryAllocas.push(`${slot} = alloca i1`);
|
|
526
|
+
host.declare(`declare zeroext i1 @scr_dyn_isl_is_error(ptr)`);
|
|
527
|
+
const isl = B.tmp();
|
|
528
|
+
B.line(`${isl} = call zeroext i1 @scr_dyn_isl_is_error(ptr ${d.name})`);
|
|
529
|
+
B.line(`store i1 ${isl}, ptr ${slot}`);
|
|
530
|
+
const lObj = B.newLabel("dts.o");
|
|
531
|
+
const lj = B.newLabel("dts.j");
|
|
532
|
+
B.condBr(isObj, lObj, lj);
|
|
533
|
+
B.startBlock(lObj);
|
|
534
|
+
host.declare(`declare ptr @scr_dyn_obj_get(ptr, ptr, ${host.sizeType})`);
|
|
535
|
+
const m = B.tmp();
|
|
536
|
+
const has = B.tmp();
|
|
537
|
+
B.line(`${m} = call ptr @scr_dyn_obj_get(ptr ${d.name}, ptr ${host.cstr("%error")}, ${host.sizeType} 6)`);
|
|
538
|
+
B.line(`${has} = icmp ne ptr ${m}, null`);
|
|
539
|
+
B.line(`store i1 ${has}, ptr ${slot}`);
|
|
540
|
+
B.br(lj);
|
|
541
|
+
B.startBlock(lj);
|
|
542
|
+
test = B.tmp();
|
|
543
|
+
B.line(`${test} = load i1, ptr ${slot}`);
|
|
544
|
+
}
|
|
545
|
+
else {
|
|
546
|
+
const kd = host.dynKind(d.name);
|
|
547
|
+
const oneOf = (kinds) => {
|
|
548
|
+
let acc = "";
|
|
549
|
+
for (const k of kinds) {
|
|
550
|
+
const c = B.tmp();
|
|
551
|
+
B.line(`${c} = icmp eq i32 ${kd}, ${k}`);
|
|
552
|
+
if (acc === "") {
|
|
553
|
+
acc = c;
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
const o = B.tmp();
|
|
557
|
+
B.line(`${o} = or i1 ${acc}, ${c}`);
|
|
558
|
+
acc = o;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return acc;
|
|
562
|
+
};
|
|
563
|
+
// ISLAND-held nodes route the tests that depend on the engine's
|
|
564
|
+
// answer through the scr_dyn_isl_* helpers (false on every
|
|
565
|
+
// other kind — the calls stay unconditional and branch-free).
|
|
566
|
+
const orIsl = (acc, helper, arg) => {
|
|
567
|
+
host.declare(`declare zeroext i1 @${helper}(ptr${arg !== undefined ? ", ptr" : ""})`);
|
|
568
|
+
const c = B.tmp();
|
|
569
|
+
B.line(`${c} = call zeroext i1 @${helper}(ptr ${d.name}${arg !== undefined ? `, ptr ${arg}` : ""})`);
|
|
570
|
+
const o = B.tmp();
|
|
571
|
+
B.line(`${o} = or i1 ${acc}, ${c}`);
|
|
572
|
+
return o;
|
|
573
|
+
};
|
|
574
|
+
if (e.test === "nullish") {
|
|
575
|
+
test = oneOf([DYN_KIND.UNDEF, DYN_KIND.NULL]);
|
|
576
|
+
}
|
|
577
|
+
else if (e.test === "object") {
|
|
578
|
+
// `typeof v === "object"`: objects, arrays, bytes, native
|
|
579
|
+
// handles, promises, AND null — engine-held objects by the
|
|
580
|
+
// engine's own typeof.
|
|
581
|
+
test = orIsl(oneOf([DYN_KIND.OBJ, DYN_KIND.ARR, DYN_KIND.BYTES, DYN_KIND.HANDLE, DYN_KIND.PROMISE, DYN_KIND.NULL]), "scr_dyn_isl_typeof_is", host.cstr("object"));
|
|
582
|
+
}
|
|
583
|
+
else if (e.test === "array") {
|
|
584
|
+
// Array.isArray: the checked-dynamic tree's array kind, or the engine's own
|
|
585
|
+
// answer for an engine-held value.
|
|
586
|
+
test = orIsl(oneOf([DYN_KIND.ARR]), "scr_dyn_isl_is_array");
|
|
587
|
+
}
|
|
588
|
+
else if (e.test === "function") {
|
|
589
|
+
test = orIsl(oneOf([DYN_KIND.FUNC]), "scr_dyn_isl_typeof_is", host.cstr("function"));
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
const kindOf = {
|
|
593
|
+
string: DYN_KIND.STR,
|
|
594
|
+
number: DYN_KIND.NUM,
|
|
595
|
+
boolean: DYN_KIND.BOOL,
|
|
596
|
+
undefined: DYN_KIND.UNDEF,
|
|
597
|
+
null: DYN_KIND.NULL,
|
|
598
|
+
bytes: DYN_KIND.BYTES,
|
|
599
|
+
};
|
|
600
|
+
test = oneOf([kindOf[e.test]]);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (!e.negated)
|
|
604
|
+
return { name: test, type: e.type };
|
|
605
|
+
const neg = B.tmp();
|
|
606
|
+
B.line(`${neg} = xor i1 ${test}, true`);
|
|
607
|
+
return { name: neg, type: e.type };
|
|
608
|
+
}
|
|
609
|
+
case "unionEq": {
|
|
610
|
+
// Strict equality of the ARM values (tag compare + per-arm payload
|
|
611
|
+
// compare — the C per-union helper, inlined). Both boxes borrowed.
|
|
612
|
+
const l = host.emitExpr(e.left);
|
|
613
|
+
const r = host.emitExpr(e.right);
|
|
614
|
+
const def = host.unionsById.get(e.unionId);
|
|
615
|
+
if (!def)
|
|
616
|
+
throw new InternalCompilerError(`llvm emitter bug: equality of unknown union ${e.unionId}`);
|
|
617
|
+
const slot = B.slot();
|
|
618
|
+
B.entryAllocas.push(`${slot} = alloca i1`);
|
|
619
|
+
const join = B.newLabel("ue.j");
|
|
620
|
+
const same = B.newLabel("ue.s");
|
|
621
|
+
const ltag = host.unionTag(l.name);
|
|
622
|
+
const rtag = host.unionTag(r.name);
|
|
623
|
+
const tagEq = B.tmp();
|
|
624
|
+
B.line(`${tagEq} = icmp eq i32 ${ltag}, ${rtag}`);
|
|
625
|
+
B.line(`store i1 false, ptr ${slot}`);
|
|
626
|
+
B.condBr(tagEq, same, join);
|
|
627
|
+
B.startBlock(same);
|
|
628
|
+
host.unionTagSwitch(l.name, def, (arm) => {
|
|
629
|
+
switch (arm.kind) {
|
|
630
|
+
case "undefinedT":
|
|
631
|
+
case "nullT":
|
|
632
|
+
B.line(`store i1 true, ptr ${slot}`);
|
|
633
|
+
break;
|
|
634
|
+
case "f64": {
|
|
635
|
+
host.declare(`declare double @scr_union_get_f64(ptr)`);
|
|
636
|
+
const a = B.tmp();
|
|
637
|
+
const b = B.tmp();
|
|
638
|
+
const t = B.tmp();
|
|
639
|
+
B.line(`${a} = call double @scr_union_get_f64(ptr ${l.name})`);
|
|
640
|
+
B.line(`${b} = call double @scr_union_get_f64(ptr ${r.name})`);
|
|
641
|
+
if (e.sameValue) {
|
|
642
|
+
// Object.is's f64 compare: NaN equals NaN, +0 differs
|
|
643
|
+
// from -0 — the runtime SameValue.
|
|
644
|
+
host.declare(`declare zeroext i1 @scr_num_same_value(double, double)`);
|
|
645
|
+
B.line(`${t} = call zeroext i1 @scr_num_same_value(double ${a}, double ${b})`);
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
B.line(`${t} = fcmp oeq double ${a}, ${b}`);
|
|
649
|
+
}
|
|
650
|
+
B.line(`store i1 ${t}, ptr ${slot}`);
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
case "bool": {
|
|
654
|
+
host.declare(`declare zeroext i1 @scr_union_get_bool(ptr)`);
|
|
655
|
+
const a = B.tmp();
|
|
656
|
+
const b = B.tmp();
|
|
657
|
+
const t = B.tmp();
|
|
658
|
+
B.line(`${a} = call zeroext i1 @scr_union_get_bool(ptr ${l.name})`);
|
|
659
|
+
B.line(`${b} = call zeroext i1 @scr_union_get_bool(ptr ${r.name})`);
|
|
660
|
+
B.line(`${t} = icmp eq i1 ${a}, ${b}`);
|
|
661
|
+
B.line(`store i1 ${t}, ptr ${slot}`);
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
664
|
+
case "string": {
|
|
665
|
+
host.declare(`declare zeroext i1 @scr_str_eq(ptr, ptr)`);
|
|
666
|
+
const a = host.unionPeek(l.name);
|
|
667
|
+
const b = host.unionPeek(r.name);
|
|
668
|
+
const t = B.tmp();
|
|
669
|
+
B.line(`${t} = call zeroext i1 @scr_str_eq(ptr ${a}, ptr ${b})`);
|
|
670
|
+
B.line(`store i1 ${t}, ptr ${slot}`);
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
default: {
|
|
674
|
+
// Ref arms: pointer identity, exactly JS object equality.
|
|
675
|
+
const a = host.unionPeek(l.name);
|
|
676
|
+
const b = host.unionPeek(r.name);
|
|
677
|
+
const t = B.tmp();
|
|
678
|
+
B.line(`${t} = icmp eq ptr ${a}, ${b} ; ${arm.kind}`);
|
|
679
|
+
B.line(`store i1 ${t}, ptr ${slot}`);
|
|
680
|
+
break;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
B.br(join);
|
|
684
|
+
});
|
|
685
|
+
B.startBlock(join);
|
|
686
|
+
const eq = B.tmp();
|
|
687
|
+
B.line(`${eq} = load i1, ptr ${slot}`);
|
|
688
|
+
if (!e.negated)
|
|
689
|
+
return { name: eq, type: e.type };
|
|
690
|
+
const t = B.tmp();
|
|
691
|
+
B.line(`${t} = xor i1 ${eq}, true`);
|
|
692
|
+
return { name: t, type: e.type };
|
|
693
|
+
}
|
|
694
|
+
case "unionFuncEq": {
|
|
695
|
+
const u = host.emitExpr(e.union);
|
|
696
|
+
const f = host.emitExpr(e.func);
|
|
697
|
+
const tag = host.unionTag(u.name);
|
|
698
|
+
const tagMatch = B.tmp();
|
|
699
|
+
B.line(`${tagMatch} = icmp eq i32 ${tag}, ${e.tag}`);
|
|
700
|
+
const payload = host.unionPeek(u.name);
|
|
701
|
+
const ptrMatch = B.tmp();
|
|
702
|
+
B.line(`${ptrMatch} = icmp eq ptr ${payload}, ${f.name}`);
|
|
703
|
+
const result = B.tmp();
|
|
704
|
+
B.line(`${result} = and i1 ${tagMatch}, ${ptrMatch}`);
|
|
705
|
+
if (!e.negated)
|
|
706
|
+
return host.own({ name: result, type: e.type });
|
|
707
|
+
const negated = B.tmp();
|
|
708
|
+
B.line(`${negated} = xor i1 ${result}, true`);
|
|
709
|
+
return host.own({ name: negated, type: e.type });
|
|
710
|
+
}
|
|
711
|
+
case "caughtTest": {
|
|
712
|
+
// Kind-tag tests read the snapshot directly; instanceof compares
|
|
713
|
+
// an OBJ payload's vtable preorder against the class's compile-
|
|
714
|
+
// time interval (false for every other payload kind). Box
|
|
715
|
+
// borrowed. SCR_EXC_STR = 3, SCR_EXC_F64 = 1, SCR_EXC_BOOL = 2.
|
|
716
|
+
const c = host.emitExpr(e.value);
|
|
717
|
+
if (e.test === "instanceof") {
|
|
718
|
+
const target = host.classMetaOf(e.className);
|
|
719
|
+
host.declare(`declare zeroext i1 @scr_caught_instanceof(ptr, ${host.sizeType}, ${host.sizeType})`);
|
|
720
|
+
const t = B.tmp();
|
|
721
|
+
B.line(`${t} = call zeroext i1 @scr_caught_instanceof(ptr ${c.name}, ${host.sizeType} ${target.pre}, ${host.sizeType} ${target.post})`);
|
|
722
|
+
if (e.negated !== true)
|
|
723
|
+
return { name: t, type: e.type };
|
|
724
|
+
const n = B.tmp();
|
|
725
|
+
B.line(`${n} = xor i1 ${t}, true`);
|
|
726
|
+
return { name: n, type: e.type };
|
|
727
|
+
}
|
|
728
|
+
const tag = { string: 3, number: 1, boolean: 2 }[e.test];
|
|
729
|
+
const kp = B.tmp();
|
|
730
|
+
const k = B.tmp();
|
|
731
|
+
const t = B.tmp();
|
|
732
|
+
B.line(`${kp} = getelementptr inbounds %ScrCaught, ptr ${c.name}, i64 0, i32 1`);
|
|
733
|
+
B.line(`${k} = load i32, ptr ${kp}`);
|
|
734
|
+
B.line(`${t} = icmp ${e.negated === true ? "ne" : "eq"} i32 ${k}, ${tag} ; typeof e === "${e.test}"`);
|
|
735
|
+
return { name: t, type: e.type };
|
|
736
|
+
}
|
|
737
|
+
case "caughtCheck": {
|
|
738
|
+
// Checked payload extraction (`e as C`): instanceof match extracts
|
|
739
|
+
// +1, anything else throws the catchable TypeError — the result
|
|
740
|
+
// joins the frame BEFORE the pending check so an unwind releases
|
|
741
|
+
// the NULL dummy harmlessly. Box borrowed.
|
|
742
|
+
const c = host.emitExpr(e.value);
|
|
743
|
+
const target = host.classMetaOf(e.className);
|
|
744
|
+
const display = e.className.startsWith("%") ? e.className.slice(1) : e.className;
|
|
745
|
+
host.declare(`declare ptr @scr_caught_check_obj(ptr, ${host.sizeType}, ${host.sizeType}, ptr)`);
|
|
746
|
+
const t = B.tmp();
|
|
747
|
+
B.line(`${t} = call ptr @scr_caught_check_obj(ptr ${c.name}, ${host.sizeType} ${target.pre}, ${host.sizeType} ${target.post}, ptr ${host.cstr(display)})`);
|
|
748
|
+
const out = host.own({ name: t, type: e.type });
|
|
749
|
+
host.emitPendingCheck();
|
|
750
|
+
return out;
|
|
751
|
+
}
|
|
752
|
+
case "caughtNarrow": {
|
|
753
|
+
// Checker-trusted extraction (the matching caughtTest was proven
|
|
754
|
+
// by tsc's narrowing): scalars read the snapshot's slots,
|
|
755
|
+
// refcounted payloads come out retained (+1). Box borrowed.
|
|
756
|
+
const c = host.emitExpr(e.value);
|
|
757
|
+
if (e.type.kind === "f64") {
|
|
758
|
+
const p = B.tmp();
|
|
759
|
+
const v = B.tmp();
|
|
760
|
+
B.line(`${p} = getelementptr inbounds %ScrCaught, ptr ${c.name}, i64 0, i32 2`);
|
|
761
|
+
B.line(`${v} = load double, ptr ${p}`);
|
|
762
|
+
return { name: v, type: e.type };
|
|
763
|
+
}
|
|
764
|
+
if (e.type.kind === "bool") {
|
|
765
|
+
const p = B.tmp();
|
|
766
|
+
const raw = B.tmp();
|
|
767
|
+
const v = B.tmp();
|
|
768
|
+
B.line(`${p} = getelementptr inbounds %ScrCaught, ptr ${c.name}, i64 0, i32 3`);
|
|
769
|
+
B.line(`${raw} = load i8, ptr ${p}`);
|
|
770
|
+
B.line(`${v} = trunc i8 ${raw} to i1`);
|
|
771
|
+
return { name: v, type: e.type };
|
|
772
|
+
}
|
|
773
|
+
const pp = B.tmp();
|
|
774
|
+
const payload = B.tmp();
|
|
775
|
+
B.line(`${pp} = getelementptr inbounds %ScrCaught, ptr ${c.name}, i64 0, i32 4`);
|
|
776
|
+
B.line(`${payload} = load ptr, ptr ${pp}`);
|
|
777
|
+
if (e.type.kind === "string") {
|
|
778
|
+
return host.own({ name: host.retainValue(payload, e.type), type: e.type });
|
|
779
|
+
}
|
|
780
|
+
if (e.type.kind === "object") {
|
|
781
|
+
// Retain through the snapshot's own entry point (the payload's
|
|
782
|
+
// dynamic class is opaque here — exactly the C's retain_fn call).
|
|
783
|
+
const rp = B.tmp();
|
|
784
|
+
const rf = B.tmp();
|
|
785
|
+
const v = B.tmp();
|
|
786
|
+
B.line(`${rp} = getelementptr inbounds %ScrCaught, ptr ${c.name}, i64 0, i32 5`);
|
|
787
|
+
B.line(`${rf} = load ptr, ptr ${rp}`);
|
|
788
|
+
B.line(`${v} = call ptr ${rf}(ptr ${payload})`);
|
|
789
|
+
return host.own({ name: v, type: e.type });
|
|
790
|
+
}
|
|
791
|
+
throw new LlvmUnsupportedError(`caughtNarrow:${e.type.kind}`, e.loc);
|
|
792
|
+
}
|
|
793
|
+
case "caughtToDyn": {
|
|
794
|
+
// A catch binding flowing into an `unknown` slot: the snapshot's
|
|
795
|
+
// runtime kind converts through the interned helper (+1 fresh
|
|
796
|
+
// tree; never throws). Box borrowed.
|
|
797
|
+
const c = host.emitExpr(e.value);
|
|
798
|
+
const helper = host.dyn.caughtToDynHelper();
|
|
799
|
+
const t = B.tmp();
|
|
800
|
+
B.line(`${t} = call ptr @${helper}(ptr ${c.name})`);
|
|
801
|
+
return host.own({ name: t, type: e.type });
|
|
802
|
+
}
|
|
803
|
+
default: {
|
|
804
|
+
const _exhaustive = e;
|
|
805
|
+
void _exhaustive;
|
|
806
|
+
throw new InternalCompilerError("unreachable");
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
//# sourceMappingURL=expr-dynamic.js.map
|