@scriptc/compiler 0.0.33 → 0.0.34
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/dist/backend/cc-cache.test.js +122 -0
- package/dist/backend/cc-cache.test.js.map +1 -1
- package/dist/backend/cc.d.ts +19 -0
- package/dist/backend/cc.js +111 -20
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-exprs.js +26 -1
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-shapes.js +37 -4
- package/dist/backend/emission/emit-shapes.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +11 -2
- package/dist/backend/emission/emitter.js +11 -5
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/library-identity.d.ts +22 -0
- package/dist/backend/library-identity.js +103 -0
- package/dist/backend/library-identity.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +3 -0
- package/dist/backend/llvm/emitter.js +35 -5
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +1 -0
- package/dist/backend/llvm/shapes.js +25 -1
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/mangle.d.ts +1 -0
- package/dist/backend/mangle.js +3 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/object-localize.d.ts +5 -5
- package/dist/backend/object-localize.js +19 -16
- package/dist/backend/object-localize.js.map +1 -1
- package/dist/backend/object-localize.test.js +37 -13
- package/dist/backend/object-localize.test.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +82 -0
- package/dist/frontend/input-tracker.js +380 -0
- package/dist/frontend/input-tracker.js.map +1 -0
- package/dist/frontend/input-tracker.test.d.ts +1 -0
- package/dist/frontend/input-tracker.test.js +137 -0
- package/dist/frontend/input-tracker.test.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.js +2 -8
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +155 -140
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +3 -0
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.js +48 -9
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +67 -1
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +45 -26
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +1 -1
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +48 -3
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +67 -29
- package/dist/frontend/lowering/lowerer.js +410 -87
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/npm-static-rewrite.js +25 -26
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static.js +29 -30
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.d.ts +1 -0
- package/dist/frontend/npm-static.test.js +15 -0
- package/dist/frontend/npm-static.test.js.map +1 -0
- package/dist/frontend/npm.js +5 -17
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.js +2 -6
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.js +8 -29
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/ts7/program.js +17 -18
- package/dist/frontend/ts7/program.js.map +1 -1
- package/dist/frontend/types.d.ts +33 -0
- package/dist/frontend/types.js +114 -3
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +241 -42
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +21 -4
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/validate.js +31 -1
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/early-cache.d.ts +65 -0
- package/dist/library/early-cache.js +380 -0
- package/dist/library/early-cache.js.map +1 -0
- package/dist/library/early-cache.test.d.ts +1 -0
- package/dist/library/early-cache.test.js +528 -0
- package/dist/library/early-cache.test.js.map +1 -0
- package/dist/library/int-infer.js +14 -0
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +21 -4
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/semantic-source.d.ts +13 -0
- package/dist/library/semantic-source.js +257 -0
- package/dist/library/semantic-source.js.map +1 -0
- package/dist/library/semantic-source.test.d.ts +1 -0
- package/dist/library/semantic-source.test.js +113 -0
- package/dist/library/semantic-source.test.js.map +1 -0
- package/dist/library/sidecar.d.ts +6 -0
- package/dist/library/sidecar.js +11 -0
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type LibraryEmission = "c" | "llvm";
|
|
2
|
+
export declare const C_LIBRARY_IDENTITY_BEGIN = "/* scriptc-library-identity: begin */";
|
|
3
|
+
export declare const C_LIBRARY_IDENTITY_END = "/* scriptc-library-identity: end */";
|
|
4
|
+
export declare const LLVM_LIBRARY_IDENTITY_BEGIN = "; scriptc-library-identity: begin";
|
|
5
|
+
export declare const LLVM_LIBRARY_IDENTITY_END = "; scriptc-library-identity: end";
|
|
6
|
+
export interface LibraryIdentityValues {
|
|
7
|
+
buildIdSymbol: string;
|
|
8
|
+
abiVersionSymbol: string;
|
|
9
|
+
buildId: string;
|
|
10
|
+
abiVersion: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function emitLibraryIdentityLines(emission: LibraryEmission, identity: LibraryIdentityValues, llvmFunctionAttrs?: string): string[];
|
|
13
|
+
/** Refresh only the volatile identity block in a cached public TU. */
|
|
14
|
+
export declare function replaceLibraryIdentity(source: string, emission: LibraryEmission, identity: LibraryIdentityValues): string;
|
|
15
|
+
/** Refresh the source-line annotations retained in a caller-visible C TU. */
|
|
16
|
+
export declare function rebaseLibrarySourceComments(source: string, sourceFile: string, rebaseLine: (line: number) => number): string;
|
|
17
|
+
/** Remove C-only debugging annotations from the private native-cache input. */
|
|
18
|
+
export declare function stripLibrarySourceComments(source: string, sourceFile: string): string;
|
|
19
|
+
/** Remove the generated identity region from a complete caller-visible
|
|
20
|
+
* library TU. Archive assembly compiles this stable projection beside the
|
|
21
|
+
* small volatile identity C object, while the public TU remains complete. */
|
|
22
|
+
export declare function stripLibraryIdentity(source: string, emission: LibraryEmission): string;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export const C_LIBRARY_IDENTITY_BEGIN = "/* scriptc-library-identity: begin */";
|
|
2
|
+
export const C_LIBRARY_IDENTITY_END = "/* scriptc-library-identity: end */";
|
|
3
|
+
export const LLVM_LIBRARY_IDENTITY_BEGIN = "; scriptc-library-identity: begin";
|
|
4
|
+
export const LLVM_LIBRARY_IDENTITY_END = "; scriptc-library-identity: end";
|
|
5
|
+
function identityMarkers(emission) {
|
|
6
|
+
return emission === "c"
|
|
7
|
+
? { begin: C_LIBRARY_IDENTITY_BEGIN, end: C_LIBRARY_IDENTITY_END }
|
|
8
|
+
: { begin: LLVM_LIBRARY_IDENTITY_BEGIN, end: LLVM_LIBRARY_IDENTITY_END };
|
|
9
|
+
}
|
|
10
|
+
export function emitLibraryIdentityLines(emission, identity, llvmFunctionAttrs = "#0") {
|
|
11
|
+
if (!/^[0-9a-f]{16}$/.test(identity.buildId)) {
|
|
12
|
+
throw new Error("library build id must be exactly 16 lowercase hex digits");
|
|
13
|
+
}
|
|
14
|
+
if (emission === "c") {
|
|
15
|
+
return [
|
|
16
|
+
C_LIBRARY_IDENTITY_BEGIN,
|
|
17
|
+
`uint64_t ${identity.buildIdSymbol}(void) {`,
|
|
18
|
+
` return UINT64_C(0x${identity.buildId});`,
|
|
19
|
+
`}`,
|
|
20
|
+
``,
|
|
21
|
+
`uint32_t ${identity.abiVersionSymbol}(void) {`,
|
|
22
|
+
` return ${identity.abiVersion}u;`,
|
|
23
|
+
`}`,
|
|
24
|
+
``,
|
|
25
|
+
C_LIBRARY_IDENTITY_END,
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
const signedBuildId = BigInt.asIntN(64, BigInt(`0x${identity.buildId}`)).toString();
|
|
29
|
+
return [
|
|
30
|
+
LLVM_LIBRARY_IDENTITY_BEGIN,
|
|
31
|
+
`define i64 @${identity.buildIdSymbol}() ${llvmFunctionAttrs} { ; identity getter build_id 0x${identity.buildId}`,
|
|
32
|
+
`entry:`,
|
|
33
|
+
` ret i64 ${signedBuildId}`,
|
|
34
|
+
`}`,
|
|
35
|
+
``,
|
|
36
|
+
`define i32 @${identity.abiVersionSymbol}() ${llvmFunctionAttrs} { ; identity getter abi_version`,
|
|
37
|
+
`entry:`,
|
|
38
|
+
` ret i32 ${identity.abiVersion}`,
|
|
39
|
+
`}`,
|
|
40
|
+
``,
|
|
41
|
+
LLVM_LIBRARY_IDENTITY_END,
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
function identityOffsets(source, emission) {
|
|
45
|
+
const { begin, end } = identityMarkers(emission);
|
|
46
|
+
const start = source.indexOf(`${begin}\n`);
|
|
47
|
+
if (start < 0)
|
|
48
|
+
return null;
|
|
49
|
+
if (source.indexOf(begin, start + begin.length) >= 0) {
|
|
50
|
+
throw new Error("generated library TU contains multiple identity regions");
|
|
51
|
+
}
|
|
52
|
+
const endStart = source.indexOf(end, start + begin.length);
|
|
53
|
+
if (endStart < 0)
|
|
54
|
+
throw new Error("generated library TU has an unterminated identity region");
|
|
55
|
+
return { start, end: endStart + end.length };
|
|
56
|
+
}
|
|
57
|
+
/** Refresh only the volatile identity block in a cached public TU. */
|
|
58
|
+
export function replaceLibraryIdentity(source, emission, identity) {
|
|
59
|
+
const offsets = identityOffsets(source, emission);
|
|
60
|
+
if (offsets === null)
|
|
61
|
+
throw new Error("generated public library TU has no identity region");
|
|
62
|
+
const replacement = emitLibraryIdentityLines(emission, identity).join("\n");
|
|
63
|
+
return source.slice(0, offsets.start) + replacement + source.slice(offsets.end);
|
|
64
|
+
}
|
|
65
|
+
function escapedRegExp(text) {
|
|
66
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
67
|
+
}
|
|
68
|
+
function sourceCommentPattern(sourceFile) {
|
|
69
|
+
// Emission appends these comments at physical line ends. Requiring that
|
|
70
|
+
// boundary prevents source-looking text inside a generated C string from
|
|
71
|
+
// being mistaken for an annotation and changing program semantics. An
|
|
72
|
+
// uninitialized reference declaration appends its own `/* let ... */`
|
|
73
|
+
// explanation after the location, so admit that one generated suffix too.
|
|
74
|
+
return new RegExp(` /\\* ${escapedRegExp(sourceFile)}:(\\d+) \\*/` +
|
|
75
|
+
`(?= /\\* let [^\\r\\n]*; \\*/(?=\\r?\\n|$)|\\r?\\n|$)`, "g");
|
|
76
|
+
}
|
|
77
|
+
/** Refresh the source-line annotations retained in a caller-visible C TU. */
|
|
78
|
+
export function rebaseLibrarySourceComments(source, sourceFile, rebaseLine) {
|
|
79
|
+
return source.replace(sourceCommentPattern(sourceFile), (_match, line) => ` /* ${sourceFile}:${rebaseLine(Number(line))} */`);
|
|
80
|
+
}
|
|
81
|
+
/** Remove C-only debugging annotations from the private native-cache input. */
|
|
82
|
+
export function stripLibrarySourceComments(source, sourceFile) {
|
|
83
|
+
return source.replace(sourceCommentPattern(sourceFile), "");
|
|
84
|
+
}
|
|
85
|
+
/** Remove the generated identity region from a complete caller-visible
|
|
86
|
+
* library TU. Archive assembly compiles this stable projection beside the
|
|
87
|
+
* small volatile identity C object, while the public TU remains complete. */
|
|
88
|
+
export function stripLibraryIdentity(source, emission) {
|
|
89
|
+
const offsets = identityOffsets(source, emission);
|
|
90
|
+
if (offsets === null)
|
|
91
|
+
return source;
|
|
92
|
+
const endOffset = offsets.end;
|
|
93
|
+
const suffix = source[endOffset] === "\n" ? endOffset + 1 : endOffset;
|
|
94
|
+
let prefix = source.slice(0, offsets.start);
|
|
95
|
+
// An omitted final region leaves the emitter's preceding empty array entry
|
|
96
|
+
// as one trailing newline; a marked final region has material after that
|
|
97
|
+
// entry and therefore renders it as two. Restore the omitted form exactly.
|
|
98
|
+
if (suffix === source.length && prefix.endsWith("\n\n")) {
|
|
99
|
+
prefix = prefix.slice(0, -1);
|
|
100
|
+
}
|
|
101
|
+
return prefix + source.slice(suffix);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=library-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-identity.js","sourceRoot":"","sources":["../../src/backend/library-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,8 @@ export interface LlvmTargetOptions {
|
|
|
5
5
|
pointerBits?: 32 | 64;
|
|
6
6
|
/** Select the WASI libc entry-point convention. */
|
|
7
7
|
wasi?: boolean;
|
|
8
|
+
/** Library archive assembly may move the volatile identity getters into a
|
|
9
|
+
* separate translation unit. Public/direct emission keeps them by default. */
|
|
10
|
+
emitLibraryIdentity?: boolean;
|
|
8
11
|
}
|
|
9
12
|
export declare function emitLlvmModule(mod: IrModule, options?: LlvmTargetOptions): string;
|
|
@@ -61,11 +61,12 @@
|
|
|
61
61
|
* lazy-inflate representation as the C debugging backend.
|
|
62
62
|
*/
|
|
63
63
|
import { deflateRawSync } from "node:zlib";
|
|
64
|
+
import { emitLibraryIdentityLines } from "../library-identity.js";
|
|
64
65
|
import { canMarshalFuncIntoIsland, CAUGHT, DYN, F64, ffiCallbackType, islandCallbackRet, islandPromisePayloadTag, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, moduleEmbedsBuiltin, moduleEmbedsCompressedNpm, moduleUsesDynInvoke, moduleUsesFetch, moduleUsesFsWatch, moduleUsesHttpServer, moduleUsesNet, moduleUsesNodeTest, moduleUsesProcessEvents, moduleUsesStream, moduleUsesTls, moduleUsesTlsCa, NPM_COMPRESS_MIN, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, typeEquals, typeKey, VOID } from "../../ir/nodes.js";
|
|
65
66
|
import { matchIntegerBytesForLoop } from "../../ir/integer-loops.js";
|
|
66
67
|
import { allocateFfiCallbackAdapters, collectFfiRetainedOps, hasForeignFfiCallback, hasRetainedFfiCallback, parseFfiCallbackKey } from "../ffi-callbacks.js";
|
|
67
68
|
import { computeMayThrow } from "../emission/may-throw.js";
|
|
68
|
-
import { mangleArgPack, mangleAsyncSpawn, mangleClassNew, mangleClassObj, mangleClassRetain, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenResThunk, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordNew, mangleRecordStruct, mangleResolveThunk, mangleTrampoline, mangleVtStruct, mangleWrapper } from "../mangle.js";
|
|
69
|
+
import { mangleArgPack, mangleAsyncSpawn, mangleClassNew, mangleClassObj, mangleClassRetain, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenResThunk, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordClone, mangleRecordNew, mangleRecordStruct, mangleResolveThunk, mangleTrampoline, mangleVtStruct, mangleWrapper } from "../mangle.js";
|
|
69
70
|
import { BlockBuilder } from "./blocks.js";
|
|
70
71
|
import { buildClassGraph, classFieldIndex, classStructSym, emitClassObjDefs, emitClassShapes, } from "./classes.js";
|
|
71
72
|
import { DK, LlDyn } from "./dyn.js";
|
|
@@ -876,6 +877,7 @@ class LlEmitter {
|
|
|
876
877
|
sizeType;
|
|
877
878
|
cycleColorOffset;
|
|
878
879
|
wasi;
|
|
880
|
+
emitLibraryIdentity;
|
|
879
881
|
/** Interned string literals: UTF-8 text → { symbol, byte length } —
|
|
880
882
|
* first-use order, the C emitter's determinism discipline. */
|
|
881
883
|
literals = new Map();
|
|
@@ -951,6 +953,7 @@ class LlEmitter {
|
|
|
951
953
|
dynPromiseAdapters = new Map();
|
|
952
954
|
unionsById = new Map();
|
|
953
955
|
recordsById = new Map();
|
|
956
|
+
recordCloneShapes = new Set();
|
|
954
957
|
tracedShapes;
|
|
955
958
|
tracedUnions;
|
|
956
959
|
/** The class graph (buildClassGraph): preorder numbering, hierarchy
|
|
@@ -1022,6 +1025,7 @@ class LlEmitter {
|
|
|
1022
1025
|
this.mod = mod;
|
|
1023
1026
|
this.sizeType = options.pointerBits === 32 ? "i32" : "i64";
|
|
1024
1027
|
this.wasi = options.wasi === true;
|
|
1028
|
+
this.emitLibraryIdentity = options.emitLibraryIdentity !== false;
|
|
1025
1029
|
// ScrCycHdr is { ptr trace; ptr free; i32 color; i16 buffered;
|
|
1026
1030
|
// i16 gen; size_t buf_index }. The object follows it, so color is 12
|
|
1027
1031
|
// bytes behind a wasm32 object and 16 bytes behind a 64-bit object.
|
|
@@ -1403,6 +1407,7 @@ class LlEmitter {
|
|
|
1403
1407
|
const wrappers = this.emitFnValueDefs();
|
|
1404
1408
|
const asyncDefs = this.emitAsyncScaffolding();
|
|
1405
1409
|
const ffiCallbacks = this.emitFfiCallbackDefs();
|
|
1410
|
+
const hasNoInlineRecordClone = [...this.recordCloneShapes].some((shapeId) => (this.recordsById.get(shapeId)?.fields.length ?? 0) >= 16);
|
|
1406
1411
|
const embedded = this.mod.embedded;
|
|
1407
1412
|
const usesIsland = embedded !== undefined && embedded.modules.length > 0;
|
|
1408
1413
|
const storeNpmText = (text) => {
|
|
@@ -1870,6 +1875,8 @@ class LlEmitter {
|
|
|
1870
1875
|
out.push(`attributes #0 = { sanitize_address }`);
|
|
1871
1876
|
if (this.wasi)
|
|
1872
1877
|
out.push(`attributes #1 = { sanitize_address presplitcoroutine }`);
|
|
1878
|
+
if (hasNoInlineRecordClone)
|
|
1879
|
+
out.push(`attributes #2 = { noinline sanitize_address }`);
|
|
1873
1880
|
out.push(``);
|
|
1874
1881
|
return out.join("\n");
|
|
1875
1882
|
}
|
|
@@ -1972,7 +1979,7 @@ class LlEmitter {
|
|
|
1972
1979
|
// sanitize_address is inert under the plain pipeline; the sanitized
|
|
1973
1980
|
// lane's -fsanitize=address link activates instrumentation over the
|
|
1974
1981
|
// emitted functions too (the runtime TUs get theirs from clang).
|
|
1975
|
-
`attributes #0 = { sanitize_address }`, ...(this.wasi ? [`attributes #1 = { sanitize_address presplitcoroutine }`] : []), ``);
|
|
1982
|
+
`attributes #0 = { sanitize_address }`, ...(this.wasi ? [`attributes #1 = { sanitize_address presplitcoroutine }`] : []), ...(hasNoInlineRecordClone ? [`attributes #2 = { noinline sanitize_address }`] : []), ``);
|
|
1976
1983
|
return out.join("\n");
|
|
1977
1984
|
}
|
|
1978
1985
|
/** LIBRARY mode: the profile-declared external definitions — the
|
|
@@ -2053,14 +2060,13 @@ class LlEmitter {
|
|
|
2053
2060
|
});
|
|
2054
2061
|
out.push(`miss:`, ` ret i32 -1`, `}`, ``);
|
|
2055
2062
|
}
|
|
2056
|
-
if (lib.identity !== undefined) {
|
|
2063
|
+
if (lib.identity !== undefined && this.emitLibraryIdentity) {
|
|
2057
2064
|
// Profile-declared identity getters (the ask-2 sidecar's boot-time
|
|
2058
2065
|
// pairing fence): pure data returns with NO entry prologue — exempt
|
|
2059
2066
|
// from the poisoned guard and every runtime touch (ratified), so a
|
|
2060
2067
|
// host can read them before init and after a trap. The u64 rides
|
|
2061
2068
|
// i64 two's-complement (LLVM integer constants are signed).
|
|
2062
|
-
|
|
2063
|
-
out.push(`define i64 @${lib.identity.buildIdSymbol}() ${FN_ATTRS} { ; identity getter build_id 0x${lib.identity.buildId}`, `entry:`, ` ret i64 ${buildId}`, `}`, ``, `define i32 @${lib.identity.abiVersionSymbol}() ${FN_ATTRS} { ; identity getter abi_version`, `entry:`, ` ret i32 ${lib.identity.abiVersion}`, `}`, ``);
|
|
2069
|
+
out.push(...emitLibraryIdentityLines("llvm", lib.identity, FN_ATTRS));
|
|
2064
2070
|
}
|
|
2065
2071
|
if (lib.resultResetSymbol !== null) {
|
|
2066
2072
|
out.push(`define void @${lib.resultResetSymbol}() ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext false, ptr ${symConst(lib.resultResetSymbol)})`, ` call void @scr_library_arena_reset()`, ` ret void`, `}`, ``);
|
|
@@ -4891,6 +4897,30 @@ class LlEmitter {
|
|
|
4891
4897
|
}
|
|
4892
4898
|
return out;
|
|
4893
4899
|
}
|
|
4900
|
+
case "recordClone": {
|
|
4901
|
+
if (e.type.kind !== "record")
|
|
4902
|
+
throw new Error("llvm emitter bug: recordClone of non-record type");
|
|
4903
|
+
this.recordCloneShapes.add(e.type.shapeId);
|
|
4904
|
+
const source = this.emitExpr(e.source);
|
|
4905
|
+
const rec = B.tmp();
|
|
4906
|
+
B.line(`${rec} = call ptr @${mangleRecordClone(e.type.shapeId)}(ptr ${source.name})`);
|
|
4907
|
+
const out = this.own({ name: rec, type: e.type });
|
|
4908
|
+
for (const f of e.overrides) {
|
|
4909
|
+
const v = this.emitExpr(f.value);
|
|
4910
|
+
const { ptr, type } = this.recordFieldPtr(rec, e.type.shapeId, f.name);
|
|
4911
|
+
if (isRefCounted(type)) {
|
|
4912
|
+
this.moveTemp(v);
|
|
4913
|
+
const old = B.tmp();
|
|
4914
|
+
B.line(`${old} = load ptr, ptr ${ptr}`);
|
|
4915
|
+
this.storeField(ptr, type, v.name);
|
|
4916
|
+
this.releaseValue(old, type);
|
|
4917
|
+
}
|
|
4918
|
+
else {
|
|
4919
|
+
this.storeField(ptr, type, v.name);
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
return out;
|
|
4923
|
+
}
|
|
4894
4924
|
case "recordGet": {
|
|
4895
4925
|
const obj = this.emitExpr(e.obj);
|
|
4896
4926
|
const { ptr, type } = this.recordFieldPtr(obj.name, e.shapeId, e.field);
|