diff --git a/packages/compiler/test/speculative-hoisted-functions.test.ts b/packages/compiler/test/speculative-hoisted-functions.test.ts index a58310b2a..79a56dcde 100644 --- a/packages/compiler/test/speculative-hoisted-functions.test.ts +++ b/packages/compiler/test/speculative-hoisted-functions.test.ts @@ -9,7 +9,9 @@ import type { IrModule } from "../src/ir/ir.js"; // list above the constructor. The initializer lowers speculatively first, // which hoists the constructor and the helper it calls. Those bodies are // kept, so their failing statements must keep runtime fences; dropping -// them left `isNum` without its return (an SC9002 trap at load). +// them left `isNum` without its return (an SC9002 trap at load). isNum's +// return reads the prototype through Reflect.getPrototypeOf, which has no +// lowering, so it fences. const source = ` function clone(config) { var P = (Num.prototype = { constructor: Num, toString: null }), @@ -20,7 +22,7 @@ function clone(config) { x.v = isNum(v) ? 0 : v * unit; } function isNum(v) { - return v instanceof Num || (!!v && v._isNum === true); + return Reflect.getPrototypeOf(v) === P || (!!v && v._isNum === true); } P._isNum = true; return Num; @@ -59,6 +61,6 @@ test("speculatively hoisted JavaScript functions keep their statement fences", a const mod = await lower(); const isNum = mod.functions.find((fn) => fn.name.endsWith("_isNum")); expect(isNum).toBeDefined(); - expect(fenceCodes(isNum!.body)).toEqual(["SC1090"]); + expect(fenceCodes(isNum!.body)).toEqual(["SC2020"]); expect(mod.functions.flatMap((fn) => fenceCodes(fn.body))).not.toContain("SC9002"); }); diff --git a/packages/runtime/src/scr_stream.h b/packages/runtime/src/scr_stream.h index 69da3dc0e..5587b58d7 100644 --- a/packages/runtime/src/scr_stream.h +++ b/packages/runtime/src/scr_stream.h @@ -136,6 +136,13 @@ ScrStream *scr_stream_pipe_general(ScrStream *src, ScrStream *dst, bool end); /* A boxed native stream out of a checked-dynamic pipeline stage (+1), or * NULL with `message` thrown as the not-supported Error. */ ScrStream *scr_stream_unbox_dyn(const struct ScrDyn *value, const ScrStr *message); +/* Checked-dynamic stream slots (scr_stream_dyn.c): the native stream a + * value boxes with the requested side (1 readable, 2 writable; +1, or + * NULL), and readable.pipe()/unpipe() for a destination that is not a + * native stream. */ +ScrStream *scr_stream_dyn_native(const struct ScrDyn *value, double side); +void scr_stream_pipe_dyn(ScrStream *src, struct ScrDyn *src_box, struct ScrDyn *dest, bool end); +void scr_stream_unpipe_dyn(ScrStream *src, struct ScrDyn *dest); ScrStream *scr_stream_new_duplex_dyn(struct ScrDyn *opts); ScrStream *scr_stream_new_transform_dyn(struct ScrDyn *opts); ScrStream *scr_stream_new_passthrough_dyn(struct ScrDyn *opts); diff --git a/packages/runtime/src/scr_wasm.c b/packages/runtime/src/scr_wasm.c index 8f9244c28..92d556272 100644 --- a/packages/runtime/src/scr_wasm.c +++ b/packages/runtime/src/scr_wasm.c @@ -90,25 +90,6 @@ #define SCR_WASM_ASAN 1 #endif -ScrPromise *scr_wasm_compile(ScrDyn *bytes); -bool scr_wasm_validate(ScrDyn *bytes); -ScrPromise *scr_wasm_instantiate(ScrDyn *source, ScrDyn *imports); -ScrDyn *scr_wasm_module_new(ScrDyn *bytes); -ScrDyn *scr_wasm_instance_new(ScrDyn *module, ScrDyn *imports); -bool scr_wasm_is(const ScrDyn *value, double kind); -ScrDyn *scr_wasm_error_new(double kind, ScrDyn *message, ScrDyn *options); -ScrDyn *scr_wasm_function(double kind); -ScrDyn *scr_wasm_namespace(void); -ScrDyn *scr_wasm_global_view(void); -ScrDyn *scr_wasm_memory_construct(ScrDyn *descriptor); -ScrDyn *scr_wasm_table_construct(ScrDyn *descriptor, ScrDyn *value); -ScrDyn *scr_wasm_global_construct(ScrDyn *descriptor, ScrDyn *value); -ScrDyn *scr_wasm_construct_without_new(double kind, ScrDyn *arg0, ScrDyn *arg1); -ScrDyn *scr_wasm_module_imports(ScrDyn *module); -ScrDyn *scr_wasm_module_exports(ScrDyn *module); -ScrDyn *scr_wasm_module_custom_sections(ScrDyn *module, ScrDyn *name); -ScrDyn *scr_wasm_value_of(ScrDyn *value); - /* Entry points of translated code. */ /* Sanitized builds do not declare it noreturn: AddressSanitizer would * call __asan_handle_no_return before every call, which warns on the diff --git a/packages/runtime/src/scr_wasm.h b/packages/runtime/src/scr_wasm.h index 7b0a29689..f7a791a26 100644 --- a/packages/runtime/src/scr_wasm.h +++ b/packages/runtime/src/scr_wasm.h @@ -19,5 +19,13 @@ ScrDyn *scr_wasm_error_new(double kind, ScrDyn *message, ScrDyn *options); ScrDyn *scr_wasm_function(double kind); ScrDyn *scr_wasm_namespace(void); ScrDyn *scr_wasm_global_view(void); +ScrDyn *scr_wasm_memory_construct(ScrDyn *descriptor); +ScrDyn *scr_wasm_table_construct(ScrDyn *descriptor, ScrDyn *value); +ScrDyn *scr_wasm_global_construct(ScrDyn *descriptor, ScrDyn *value); +ScrDyn *scr_wasm_construct_without_new(double kind, ScrDyn *arg0, ScrDyn *arg1); +ScrDyn *scr_wasm_module_imports(ScrDyn *module); +ScrDyn *scr_wasm_module_exports(ScrDyn *module); +ScrDyn *scr_wasm_module_custom_sections(ScrDyn *module, ScrDyn *name); +ScrDyn *scr_wasm_value_of(ScrDyn *value); #endif /* SCR_WASM_H */