diff --git a/.github/openclaw/qualify-sync.sh b/.github/openclaw/qualify-sync.sh index c1bbf0e0ba743..bdbcf2fc5b7e5 100644 --- a/.github/openclaw/qualify-sync.sh +++ b/.github/openclaw/qualify-sync.sh @@ -17,6 +17,31 @@ cd "$repo" results="$QUALIFICATION_DIR/sync" mkdir -p "$results/home" "$results/tmp" "$results/bin" chmod 700 "$results/home" "$results/tmp" +# Test the real Bun host table without changing the frozen consumer's compiled inputs. +evaluator_fixtures="$results/aot-evaluators" +mkdir -p "$evaluator_fixtures" +for fixture in evaluated-text-does-not-call-private-host-evaluators a-private-host-evaluator-that-is-called-still-evaluates-text; do + curl -fSL --retry 5 "https://raw.githubusercontent.com/openclaw/bun/02526c26fb9cbf76c9748e9ed3ae67020d99dd77/test/aot/engine-tests/valueflow/modules/$fixture.ir" -o "$evaluator_fixtures/$fixture.ir" +done +printf '%s\n' \ + '063440e834e83e69d1ee7a5fa2107964569546f727bdee55e3ac5a8de6392003 evaluated-text-does-not-call-private-host-evaluators.ir' \ + 'd5586fed571bd4bf796d00b1f53295d0604e7a0bff664a38505b75904a3213f8 a-private-host-evaluator-that-is-called-still-evaluates-text.ir' \ + | (cd "$evaluator_fixtures" && sha256sum -c -) +engine_digest=$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["engine"]["archive"]["sha256"])' "$CANDIDATE_RECEIPT") +engine_aot="$QUALIFICATION_DIR/cache-candidate/webkit-sha256-$engine_digest/Source/JavaScriptCore/aot" +export TESTAOT="$repo/build/qualify-candidate/testaot" JSC="$repo/build/qualify-candidate/jsc" +export AOT_SCHEMA="$engine_aot/ir/AOTSchema.def" AOT_BUILTINS_GENERATED="$engine_aot/builtins/generated" +export AOT_ENGINE_DIRECTORY="$engine_aot" AOT_ENGINE_TESTS="$engine_aot/tests" +ninja=$("$INSPECTOR_RUNTIME" -e 'import {detectHost} from "./scripts/build/config.ts"; import {ninjaIfPresent} from "./scripts/build/ninja-release.ts"; console.log=console.error; process.stdout.write(ninjaIfPresent({host:detectHost(),cacheDir:process.argv[1]}));' "$QUALIFICATION_DIR/cache-candidate") +BUN_BUILD_CACHE_DIR="$QUALIFICATION_DIR/cache-candidate" BUN_BUILD_PREFETCH_DIR="$QUALIFICATION_DIR/candidate-input/prefetch" \ + "$ninja" -C "$repo/build/qualify-candidate" engine-test-programs > "$results/aot-host-tools-build.log" 2>&1 +test -x "$TESTAOT" && test -x "$JSC" && test -s "$AOT_SCHEMA" +timeout 120 "$TESTAOT" run "$evaluator_fixtures" --show-output > "$results/aot-evaluators.log" 2>&1 +grep -Fx '2 passed, 0 failed, 0 todo' "$results/aot-evaluators.log" +timeout 300 "$TESTAOT" native --single-process closed-world/evaluation/program-that-evaluates-text-keeps-every-evaluator \ + > "$results/aot-language-evaluators.log" 2>&1 +grep -Fx 'closed-world/evaluation/program-that-evaluates-text-keeps-every-evaluator' "$results/aot-language-evaluators.log" +grep -Fx '1 passed, 0 failed, 0 todo' "$results/aot-language-evaluators.log" "$candidate" --revision > "$results/revision.log" "$candidate" -e 'const server=Bun.serve({port:0,fetch(){return new Response("ready")}});try{if(await(await fetch(server.url)).text()!=="ready")throw Error("startup");console.log("build/startup/http passed")}finally{await server.stop(true)}' > "$results/startup.log" 2>&1 ln -s "$candidate" "$results/bin/bun" diff --git a/.github/openclaw/release-notes.md b/.github/openclaw/release-notes.md index 67cbce450a311..1303a4328ceb2 100644 --- a/.github/openclaw/release-notes.md +++ b/.github/openclaw/release-notes.md @@ -1,3 +1,5 @@ +AOT value-flow no longer treats every host text evaluator as called merely because a program may run unseen code. Language evaluators and reachable host evaluator calls keep their existing behavior. Qualification covers a real Bun-host negative/positive regression pair and the existing native control for all five language evaluators. + Qualification now pins Bun `ae14f84a8f978f069ce8deadb4c5582b3331f139`, including repaired socket reconnect teardown and aliased/computed customization-hook coverage. Its runtime transpiler-cache gate expects format 53; the historical baseline remains format 36. Frozen harness adapters and the four AOT platform cases remain unchanged; final-source platform qualification is still required. AOT valueflow preserves arbitrary module answers when the program registers customization hooks, including calls through aliases. Bun must declare the registration builtin and retain its host loader calls; consumers need a joint rebuild with the matching engine headers and libraries. diff --git a/Source/JavaScriptCore/aot/valueflow/AOTValueFlowRulesHost.cpp b/Source/JavaScriptCore/aot/valueflow/AOTValueFlowRulesHost.cpp index caa3e36f59959..1c0418a8fe7c3 100644 --- a/Source/JavaScriptCore/aot/valueflow/AOTValueFlowRulesHost.cpp +++ b/Source/JavaScriptCore/aot/valueflow/AOTValueFlowRulesHost.cpp @@ -1506,7 +1506,9 @@ void runUnseenCode(const ValueFlowStatement&, ValueFlowRuleContext& context) handLoadableModulesToText(context, filesOfProgramAreLoadedByName || context.refusedCode().hostRunsFilesOutsideImage); for (uint32_t index = 0; index < builtins.builtinCount(); ++index) { - if (builtins.at(BuiltinID(index)).flags.contains(BuiltinFlag::EvaluatesText)) + // Unseen code can name the language's evaluators. Private host entry points still need a reachable caller. + const Builtin& entry = builtins.at(BuiltinID(index)); + if (entry.origin == BuiltinOrigin::Engine && entry.flags.contains(BuiltinFlag::EvaluatesText)) context.use(BuiltinID(index), { BuiltinUse::Escaped, BuiltinUse::Called }); } letHostChooseOperands(context);