space-data-module-sdk 0.8.18 → 0.8.19
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/package.json +1 -1
- package/src/flow/flowCompiler.js +34 -23
package/package.json
CHANGED
package/src/flow/flowCompiler.js
CHANGED
|
@@ -52,6 +52,8 @@ import { runWithEmceptionLock } from "../compiler/emceptionNode.js";
|
|
|
52
52
|
import {
|
|
53
53
|
assertPthreadArtifact,
|
|
54
54
|
assertPthreadFlagsPresent,
|
|
55
|
+
assertSequentialArtifact,
|
|
56
|
+
assertSequentialFlagsAbsent,
|
|
55
57
|
PTHREAD_FINAL_LINK_FLAGS,
|
|
56
58
|
} from "../compiler/pthreadArtifactGuard.js";
|
|
57
59
|
import { resolveWasiThreadsToolchain } from "../compiler/wasiThreadsToolchain.js";
|
|
@@ -96,12 +98,11 @@ const execFileAsync = promisify(execFile);
|
|
|
96
98
|
const FLOW_THREAD_MODEL = Object.freeze({
|
|
97
99
|
SINGLE_THREAD: "single-thread",
|
|
98
100
|
WASI_THREADS: "wasi-threads",
|
|
101
|
+
WASI_SEQUENTIAL: "wasi-sequential",
|
|
99
102
|
});
|
|
100
103
|
const HISTORICAL_PTHREAD_THREAD_MODEL = "emscripten-pthreads";
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
// object format, same ABI — so it unions with wasi-threads rather than
|
|
104
|
-
// conflicting with it. See normalizeGuestThreadModel.
|
|
104
|
+
// Sequential and threaded WASI objects can link together. Preserve the
|
|
105
|
+
// distinction until composition: an all-sequential flow must own its memory and not claim thread spawning.
|
|
105
106
|
const WASI_SEQUENTIAL_THREAD_MODEL = "wasi-sequential";
|
|
106
107
|
|
|
107
108
|
const RUNTIME_ABI_EXPORTS = [
|
|
@@ -762,18 +763,12 @@ function normalizeGuestThreadModel(value) {
|
|
|
762
763
|
if (normalized === FLOW_THREAD_MODEL.SINGLE_THREAD) {
|
|
763
764
|
return FLOW_THREAD_MODEL.SINGLE_THREAD;
|
|
764
765
|
}
|
|
766
|
+
if (normalized === WASI_SEQUENTIAL_THREAD_MODEL) {
|
|
767
|
+
return FLOW_THREAD_MODEL.WASI_SEQUENTIAL;
|
|
768
|
+
}
|
|
765
769
|
if (
|
|
766
770
|
normalized === FLOW_THREAD_MODEL.WASI_THREADS ||
|
|
767
|
-
normalized === HISTORICAL_PTHREAD_THREAD_MODEL
|
|
768
|
-
// wasi-sequential collapses to wasi-threads HERE, at the linking layer,
|
|
769
|
-
// and only here. The distinction is a property of a guest (may it spawn?),
|
|
770
|
-
// not of the object format: both are clang wasm32-wasip1-threads objects
|
|
771
|
-
// and link together cleanly. Keeping them separate at this layer would
|
|
772
|
-
// make a flow of one sequential node fall through to the emception branch
|
|
773
|
-
// and be linked by emcc — exactly the toolchain drift this model exists to
|
|
774
|
-
// prevent. The per-guest guarantee is enforced where it belongs: on each
|
|
775
|
-
// MODULE artifact, by assertSequentialArtifact.
|
|
776
|
-
normalized === WASI_SEQUENTIAL_THREAD_MODEL
|
|
771
|
+
normalized === HISTORICAL_PTHREAD_THREAD_MODEL
|
|
777
772
|
) {
|
|
778
773
|
return FLOW_THREAD_MODEL.WASI_THREADS;
|
|
779
774
|
}
|
|
@@ -1941,6 +1936,9 @@ export function checkFlowProgram({ flow, dependencies = new Map() } = {}) {
|
|
|
1941
1936
|
}
|
|
1942
1937
|
}
|
|
1943
1938
|
|
|
1939
|
+
if (threadModels.has(FLOW_THREAD_MODEL.WASI_THREADS)) {
|
|
1940
|
+
threadModels.delete(FLOW_THREAD_MODEL.WASI_SEQUENTIAL);
|
|
1941
|
+
}
|
|
1944
1942
|
let threadModel =
|
|
1945
1943
|
threadModels.size === 1
|
|
1946
1944
|
? [...threadModels][0]
|
|
@@ -2245,6 +2243,12 @@ export function buildFlowModuleManifest({ flow, check, dependencies }) {
|
|
|
2245
2243
|
name: flow.name ?? flow.programId,
|
|
2246
2244
|
version: flow.version ?? "0.0.0",
|
|
2247
2245
|
pluginFamily: "flow",
|
|
2246
|
+
...(check.threadModel === FLOW_THREAD_MODEL.WASI_SEQUENTIAL
|
|
2247
|
+
? { sequentialJustification: {
|
|
2248
|
+
kind: "caller-level-parallelism",
|
|
2249
|
+
detail: "Every linked guest is wasi-sequential; the flow dispatches them serially and delegates external concurrency to its host.",
|
|
2250
|
+
} }
|
|
2251
|
+
: {}),
|
|
2248
2252
|
description:
|
|
2249
2253
|
flow.description ??
|
|
2250
2254
|
`Compiled SDN flow "${flow.programId}" (linked-direct monolithic artifact).`,
|
|
@@ -2941,6 +2945,7 @@ async function linkFlowArtifactWithWasiThreads({
|
|
|
2941
2945
|
programSource,
|
|
2942
2946
|
dependencyObjects,
|
|
2943
2947
|
engineLinked = false,
|
|
2948
|
+
sequential = false,
|
|
2944
2949
|
}) {
|
|
2945
2950
|
const toolchain = resolveWasiThreadsToolchain();
|
|
2946
2951
|
const workDir = await mkdtemp(
|
|
@@ -2975,9 +2980,8 @@ async function linkFlowArtifactWithWasiThreads({
|
|
|
2975
2980
|
"-std=c++17",
|
|
2976
2981
|
`-I${workDir}`,
|
|
2977
2982
|
"-O3",
|
|
2978
|
-
"-matomics",
|
|
2983
|
+
...(sequential ? [] : ["-matomics", "-pthread"]),
|
|
2979
2984
|
"-mbulk-memory",
|
|
2980
|
-
"-pthread",
|
|
2981
2985
|
"-fno-exceptions",
|
|
2982
2986
|
"-DNDEBUG",
|
|
2983
2987
|
];
|
|
@@ -3010,16 +3014,20 @@ async function linkFlowArtifactWithWasiThreads({
|
|
|
3010
3014
|
...dependencyObjectPaths,
|
|
3011
3015
|
"-O3",
|
|
3012
3016
|
"-mexec-model=reactor",
|
|
3013
|
-
...
|
|
3017
|
+
...(sequential
|
|
3018
|
+
? ["-mbulk-memory", "-Wl,--initial-memory=16777216", "-Wl,--max-memory=2147483648"]
|
|
3019
|
+
: PTHREAD_FINAL_LINK_FLAGS),
|
|
3014
3020
|
"-Wl,--export-memory",
|
|
3015
3021
|
"-Wl,--allow-undefined",
|
|
3016
3022
|
...exportSymbols.map((symbol) => `-Wl,--export=${symbol}`),
|
|
3017
3023
|
"-o",
|
|
3018
3024
|
outputPath,
|
|
3019
3025
|
];
|
|
3020
|
-
|
|
3021
|
-
threadModel:
|
|
3022
|
-
}
|
|
3026
|
+
if (sequential) {
|
|
3027
|
+
assertSequentialFlagsAbsent(linkArgs, { threadModel: WASI_SEQUENTIAL_THREAD_MODEL });
|
|
3028
|
+
} else {
|
|
3029
|
+
assertPthreadFlagsPresent(linkArgs, { threadModel: HISTORICAL_PTHREAD_THREAD_MODEL });
|
|
3030
|
+
}
|
|
3023
3031
|
await runWasiThreadsCompiler(toolchain.clangxx, linkArgs, workDir);
|
|
3024
3032
|
return new Uint8Array(await readFile(outputPath));
|
|
3025
3033
|
} finally {
|
|
@@ -3118,7 +3126,7 @@ export async function compileFlowProgram({
|
|
|
3118
3126
|
});
|
|
3119
3127
|
|
|
3120
3128
|
const linkFlowArtifact =
|
|
3121
|
-
check.threadModel
|
|
3129
|
+
check.threadModel !== FLOW_THREAD_MODEL.SINGLE_THREAD
|
|
3122
3130
|
? linkFlowArtifactWithWasiThreads
|
|
3123
3131
|
: linkFlowArtifactWithEmception;
|
|
3124
3132
|
let wasmBytes = await linkFlowArtifact({
|
|
@@ -3129,6 +3137,7 @@ export async function compileFlowProgram({
|
|
|
3129
3137
|
programSource,
|
|
3130
3138
|
dependencyObjects: linkedDependencies.map((dependency) => dependency.guestLink.objectBytes),
|
|
3131
3139
|
engineLinked: Boolean(check.engineLinkage),
|
|
3140
|
+
sequential: check.threadModel === FLOW_THREAD_MODEL.WASI_SEQUENTIAL,
|
|
3132
3141
|
});
|
|
3133
3142
|
wasmBytes = appendWasmCustomSection(
|
|
3134
3143
|
wasmBytes,
|
|
@@ -3137,6 +3146,8 @@ export async function compileFlowProgram({
|
|
|
3137
3146
|
);
|
|
3138
3147
|
if (check.threadModel === FLOW_THREAD_MODEL.WASI_THREADS) {
|
|
3139
3148
|
assertPthreadArtifact(wasmBytes, { source: sourceName });
|
|
3149
|
+
} else if (check.threadModel === FLOW_THREAD_MODEL.WASI_SEQUENTIAL) {
|
|
3150
|
+
assertSequentialArtifact(wasmBytes, { source: sourceName });
|
|
3140
3151
|
}
|
|
3141
3152
|
|
|
3142
3153
|
const report = await validateArtifactWithStandards({
|
|
@@ -3193,8 +3204,8 @@ export async function compileFlowProgram({
|
|
|
3193
3204
|
name: flow.name ?? null,
|
|
3194
3205
|
version: flow.version ?? null,
|
|
3195
3206
|
compiler:
|
|
3196
|
-
check.threadModel
|
|
3197
|
-
?
|
|
3207
|
+
check.threadModel !== FLOW_THREAD_MODEL.SINGLE_THREAD
|
|
3208
|
+
? `space-data-module flow compile (isomorphic, ${check.threadModel})`
|
|
3198
3209
|
: "space-data-module flow compile (isomorphic, emception)",
|
|
3199
3210
|
threadModel: check.threadModel,
|
|
3200
3211
|
nodes: (flow.nodes ?? []).length,
|