mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
Merge main
This commit is contained in:
@@ -219,6 +219,12 @@ jobs:
|
||||
Move-Item "$expanded\clang+llvm-22.1.8-x86_64-pc-windows-msvc" $llvm
|
||||
echo "LLVM_DIR=$llvm\lib\cmake\llvm" >> $env:GITHUB_ENV
|
||||
echo "$llvm\bin" >> $env:GITHUB_PATH
|
||||
# A musl CLI ships tsc-ts's musl executable, and these jobs run on glibc
|
||||
# runners, where pnpm installs only the glibc platform packages.
|
||||
- name: Let pnpm install musl platform packages
|
||||
if: endsWith(matrix.cli_target, '-musl')
|
||||
run: |
|
||||
printf 'supportedArchitectures:\n libc: [current, musl]\n' >> pnpm-workspace.yaml
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- name: Build native packages (POSIX)
|
||||
if: matrix.platform != 'windows-x64'
|
||||
|
||||
+67
-2
@@ -6,6 +6,73 @@ All notable changes to scriptc will be documented in this file.
|
||||
|
||||
<!-- release:start -->
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- **tsc-ts is the default TypeScript 7 checker** on Linux and macOS. scriptc installs it with the compiler (`tsc-ts` 0.0.5 and its platform package for the host). Programs get the same diagnostics and generated code as with tsgo, and compiling takes less checker memory. `SCRIPTC_CHECKER=tsgo` selects tsgo, which stays the default on Windows. A build cache entry made with one checker isn't reused with the other.
|
||||
- **`--npm-static=auto`, the default, compiles more packages:** packages typed by their DefinitelyTyped twin (`@types/<name>`), and untyped dependencies that another package's JavaScript imports. A program whose dependencies were refused before can now compile them, and a twin whose declarations disagree with the package's JavaScript fails the build at the use. Use `--npm-static <pkg,…>` to name the packages to compile.
|
||||
- **Program type errors are reported as type errors** instead of as refusals of the npm package that contains them.
|
||||
|
||||
### Highlights
|
||||
|
||||
- **WebAssembly:** builds translate every WebAssembly module whose bytes they can see into native code, and `WebAssembly.compile`, `instantiate`, `validate`, `new WebAssembly.Module` and `new WebAssembly.Instance` run them. There is no interpreter. `WebAssembly.Memory`, `Table` and `Global`, `Module.imports`, `Module.exports` and `Module.customSections`, and function references from tables are supported, and modules can be sent to workers. `scriptc coverage` lists the modules a program loads, with `--wasm <file.wasm>` for modules loaded from paths the sources don't spell out.
|
||||
- **Async functions that suspend only at their `await`s run as stackless coroutines** instead of on fibers with their own stack, so a suspended call keeps only the values live across its awaits.
|
||||
- **Discriminated unions of records are the record pointer itself,** with no box around each value.
|
||||
- **The dynamic tier computes with NaN-boxed values:** numbers, booleans, `undefined` and `null` between operators no longer allocate. `scriptc coverage --explain-dynamic` lists the functions that run in the dynamic tier and why, and `--tier=static-only` keeps a program fully static.
|
||||
- **npm packages:** esbuild's bundled CommonJS chunks, CommonJS cycles and lazily initialized ES modules compile statically, as do classic CommonJS packages (late and JSON `require`s, require cycles), class hierarchies across a package's modules, and the packages unblocked by type-only imports, `@types` packages, `punycode` and `constants`. chalk 5 and the jose root entry compile.
|
||||
|
||||
### Features
|
||||
|
||||
- **`@scriptc/experimental` adds `ThreadSlots`,** one value per key and thread on shared objects, read without a lock.
|
||||
- **`node:test` adds `mock.timers`, `getTestContext`, `t.assert.snapshot` and `t.assert.fileSnapshot`,** the `TestContext` values `filePath`, `attempt`, `passed`, `workerId` and `tags`, module-level `before` and `after` hooks, the `SuiteContext` and hook contexts, and unnamed `test` and `describe` calls. A timed-out test cancels its running subtests.
|
||||
- **`node:worker_threads` adds `BroadcastChannel`,** `setEnvironmentData`/`getEnvironmentData`, `receiveMessageOnPort`, `markAsUntransferable`, `markAsUncloneable`, `threadName`, `resourceLimits.stackSizeMb`, the `stdout`/`stderr`/`stdin` options and streams, and `worker[Symbol.asyncDispose]`.
|
||||
- **`node:net` adds `SocketAddress` and `BlockList`,** and `net.connect` resolves host names.
|
||||
- **`node:http` pools keep-alive sockets in `Agent`s,** uses `globalAgent` for default requests, reads `http.request` options at run time, and speaks HTTP over Unix domain sockets. `fetch` tunnels through `HTTP_PROXY`/`HTTPS_PROXY` with `CONNECT`.
|
||||
- **`DisposableStack`, `Float16Array`, `Error.isError`, `Promise.try` and the regular expression `v` flag** are supported.
|
||||
- **Iterator helpers** run on generators, `Map` and `Set` iterators, string and typed array iterators, `Iterator.from` and untyped iterators.
|
||||
- **`Object.groupBy` and `Map.groupBy`** group Sets, Maps and generators.
|
||||
- **`v8`, `stream/web`, `dns/promises`, `EvalError` and `graceful-fs`** are available, and `Temporal` is reported as absent, as in Node 24.
|
||||
- **`util.promisify`** works over the crypto callback functions, dns lookups, `child_process.exec`'s callback forms and callback-style functions.
|
||||
- **`events.once`** takes an `AbortSignal` and works over streams.
|
||||
- **`AsyncLocalStorage` stores** carry into timer, immediate, `process.nextTick` and microtask callbacks.
|
||||
- **JavaScript classes compile like TypeScript classes** when their layout or JSDoc types allow it.
|
||||
- **Classes that extend `EventEmitter` or a stream class can be used as values,** and so can `EventEmitter`, the stream classes and the error classes themselves. Constructor functions can inherit from them.
|
||||
- **Class instances can be frozen and their fields redefined.**
|
||||
- **Method overrides may differ from the method they override** in parameter and result types, as long as each value converts.
|
||||
- **Library profiles add the `cstring` class.**
|
||||
- **An experimental young-object nursery** for compiled classes and records is available at compile time with `SCRIPTC_YOUNG_NURSERY=1`.
|
||||
|
||||
### Performance
|
||||
|
||||
- **Dense arrays have head room,** so `shift`, `splice(0, n)` and `unshift` runs cost amortized O(1), and `pop` of a packed array is inline.
|
||||
- **Index loops over arrays and typed arrays are versioned on one bounds guard,** with stable lengths proven and typed-array memory tagged for alias analysis.
|
||||
- **Retain and release pairs are removed** through private-array precision and last-use moves, borrowed string slices go into stack buffers, and records, tuples and spread updates stay in frame storage.
|
||||
- **SHA-384 and SHA-512 use AVX2, AVX-512VL or the arm64 SHA-512 instructions,** and MD5's block function is unrolled.
|
||||
- **String character tests, optional-string `switch`es, `String.fromCharCode` and long-string `length` are faster,** and `Buffer.write` widens ASCII to UTF-16 sixteen bytes per step.
|
||||
- **The cycle collector walks dead cycles once,** frees large dead cycle sets in address order and no longer creates self-capture cycles on the release fast path.
|
||||
- **Workers return their memory** while the event loop waits and when they finish, and default-region memory is committed as it is used.
|
||||
- **Lifetime regions carry across `await`,** and freed region chunks are reused.
|
||||
- **Large closure environments compile in linear time,** and two frontend scans no longer repeat.
|
||||
- **Programs keep stack frames only when they can read `stack`.** Before, a computed-key read on a dynamic value kept frames in every function; tsc-ts's own check is back to 0.3.6's speed.
|
||||
- **The child-process runtime unit links only into programs that spawn.**
|
||||
|
||||
### Fixes
|
||||
|
||||
- **Node 24 parity:** `util.format`, `util.types` and `util.inspect`, `URLSearchParams`, `querystring` (null-prototype results), `string_decoder`, `os`, `events` and `timers/promises` match Node 24. Class instances, iterators, iterator helper objects and holes in arrays print as Node prints them, and `%d`/`%i` format dynamic arguments as Node does.
|
||||
- **Silent wrong output is fixed** for object identity, `Object.prototype` values, `Date.parse` (V8's date grammar), stored builtins, constructor returns, `arr && arr[0]`, ES5 class names, builtin function values, uninitialized `let` writes, module-export `this` and `1 ** Infinity`.
|
||||
- **Strings compare in UTF-16 code-unit order.**
|
||||
- **Dates format with Node's local time zone names,** convert to local time once for their local getters, and follow `TZ` changes. `Date.prototype.toJSON` gives `null` for invalid dates.
|
||||
- **Errors:** thrown Maps, Sets, typed arrays, functions and arrays keep their identity. Errors list their own name where they were created, errors held as `any` have their own `stack` accessor and convert with `Error.prototype.toString`, and errors that cross into dynamic code carry Node's error properties.
|
||||
- **`matchAll` rows and `exec` results have `index`, `input` and `groups`,** and named groups keep their null prototype through optional chains.
|
||||
- **Unhandled rejections are reported after each timer and immediate callback,** and async generator completions settle on Node's microtask turns.
|
||||
- **Missing `Record` and index-signature keys read as `undefined`,** and generic functions that read a missing element return `undefined`.
|
||||
- **Sockets:** `'data'` listeners get strings after `setEncoding`, socket and stream chunks are Buffers, and an idle pooled http socket that receives data is destroyed.
|
||||
- **Diagnostic code frames window long source lines.**
|
||||
- **npm crashes, internal errors and false TDZ errors** found while compiling popular packages are fixed.
|
||||
|
||||
<!-- release:end -->
|
||||
|
||||
## 0.3.6
|
||||
|
||||
### Features
|
||||
@@ -38,8 +105,6 @@ All notable changes to scriptc will be documented in this file.
|
||||
- **`Object.setPrototypeOf` returns primitive receivers,** and `createHmac` without a key throws Node's error.
|
||||
- **Boxed records that hold an async function link the dynamic promise unit.**
|
||||
|
||||
<!-- release:end -->
|
||||
|
||||
## 0.3.5
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/cli-darwin-arm64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Native scriptc compiler for darwin-arm64",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/cli-darwin-x64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Native scriptc compiler for darwin-x64",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/cli-linux-arm64-gnu",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Native scriptc compiler for linux-arm64-gnu",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/cli-linux-arm64-musl",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Native scriptc compiler for linux-arm64-musl",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/cli-linux-x64-gnu",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Native scriptc compiler for linux-x64-gnu",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/cli-linux-x64-musl",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Native scriptc compiler for linux-x64-musl",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/cli-win32-x64-msvc",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Native scriptc compiler for win32-x64-msvc",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "scriptc",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Compile ordinary TypeScript and JavaScript to small, fast native executables and WebAssembly modules that run without Node.js",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/compiler",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "The scriptc compiler — TypeScript/JavaScript frontend, typed IR, LLVM backend",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -36,7 +36,7 @@ export function emitStreamLibCall(host: LlvmEmitterContext, e: LibCallExpr): LlV
|
||||
host.emitPendingCheck();
|
||||
return out;
|
||||
}
|
||||
if (e.fn === "stream.dynNative") {
|
||||
if (e.fn === "stream.dynNative" || e.fn === "stream.dynNativePipe") {
|
||||
// Checked-dynamic stream slots: the boxed native stream (+1) or NULL.
|
||||
if (e.type.kind !== "union")
|
||||
throw new InternalCompilerError(`llvm emitter bug: ${e.fn} result is not a union`);
|
||||
@@ -47,11 +47,16 @@ export function emitStreamLibCall(host: LlvmEmitterContext, e: LibCallExpr): LlV
|
||||
throw new InternalCompilerError(`llvm emitter bug: ${e.fn} union lacks its arms`);
|
||||
const value = host.emitExpr(e.args[0]!);
|
||||
const side = host.emitExpr(e.args[1]!);
|
||||
host.declare(`declare ptr @scr_stream_dyn_native(ptr, double)`);
|
||||
// A pipe or unpipe destination in programs with constructor-function
|
||||
// streams can be one of those streams too (scr_dyn_builtin_stream.c),
|
||||
// as stream.unboxDyn does there.
|
||||
const fn =
|
||||
e.fn === "stream.dynNativePipe" && host.usesDynBuiltinStream
|
||||
? "scr_dyn_builtin_stream_dyn_native"
|
||||
: "scr_stream_dyn_native";
|
||||
host.declare(`declare ptr @${fn}(ptr, double)`);
|
||||
const raw = B.tmp();
|
||||
B.line(
|
||||
`${raw} = call ptr @scr_stream_dyn_native(ptr ${value.name}, double ${side.name}) ; +1 or NULL`,
|
||||
);
|
||||
B.line(`${raw} = call ptr @${fn}(ptr ${value.name}, double ${side.name}) ; +1 or NULL`);
|
||||
return host.wrapNullable(raw, raw, def!.arms[streamTag]!, streamTag, e.type, nullTag);
|
||||
}
|
||||
if (e.fn === "stream.onData") {
|
||||
|
||||
@@ -58,11 +58,16 @@ export function nativeStreamClass(side: "r" | "w"): IrType {
|
||||
/** The native stream of a checked-dynamic value (+1, typed as the side's
|
||||
* class) or null: the stream.dynNative libCall, which tests the value's
|
||||
* typed capsule without throwing. */
|
||||
function dynNativeStream(lowerer: Lowerer, value: IrExpr, side: "r" | "w"): IrExpr {
|
||||
function dynNativeStream(
|
||||
lowerer: Lowerer,
|
||||
value: IrExpr,
|
||||
side: "r" | "w",
|
||||
fn: "stream.dynNative" | "stream.dynNativePipe" = "stream.dynNative",
|
||||
): IrExpr {
|
||||
const native = nativeStreamClass(side);
|
||||
return {
|
||||
kind: "libCall",
|
||||
fn: "stream.dynNative",
|
||||
fn,
|
||||
args: [value, numLit(side === "r" ? 1 : 2, value.loc)],
|
||||
type: { kind: "union", unionId: lowerer.unions.intern([native, { kind: "nullT" }]) },
|
||||
loc: value.loc,
|
||||
@@ -268,8 +273,11 @@ export function lowerForAwaitDynStream(
|
||||
}
|
||||
|
||||
/** A statement that runs `onNative` with the native stream a
|
||||
* checked-dynamic value boxes (typed as the side's class), or `otherwise`
|
||||
* for any other value. */
|
||||
* checked-dynamic pipe or unpipe destination stands for (typed as the
|
||||
* side's class), or `otherwise` for any other value. The destination's
|
||||
* stream is a boxed native one or a constructor-function stream's
|
||||
* (stream.dynNativePipe): only the runtime's pipe reads it, while member
|
||||
* calls on a slot keep a constructor-function stream's own methods. */
|
||||
export function dynNativeBranch(
|
||||
lowerer: Lowerer,
|
||||
value: IrExpr,
|
||||
@@ -279,7 +287,7 @@ export function dynNativeBranch(
|
||||
): IrStmt {
|
||||
const loc = value.loc;
|
||||
const nativeType = nativeStreamClass(side);
|
||||
const nullable = dynNativeStream(lowerer, value, side);
|
||||
const nullable = dynNativeStream(lowerer, value, side, "stream.dynNativePipe");
|
||||
const nativeOrNull = lowerer.declareHiddenLocal("%streamNative", nullable.type);
|
||||
const unionId = nullable.type.kind === "union" ? nullable.type.unionId : "";
|
||||
const tag = lowerer.armTag(unionId, nativeType);
|
||||
|
||||
@@ -7228,7 +7228,7 @@ function wideningAddedProperties(
|
||||
if ((prop.flags & ts.SymbolFlags.Optional) === 0 || prop.declarations.length === 0) continue;
|
||||
if (prop.declarations.some((d) => d.parent === literal)) continue;
|
||||
if ((ctx.checker.getTypeOfSymbol(prop).flags & ts.TypeFlags.Undefined) === 0) continue;
|
||||
added.add(prop.name);
|
||||
added.add(ts.symbolName(prop));
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
@@ -2689,6 +2689,10 @@ export const LIB_FN_SIGS = defineLibFnSignatures({
|
||||
* (1) or writable (2) side — or null for any other value. Never throws;
|
||||
* the result union is `%Readable | null` or `%Writable | null`. */
|
||||
"stream.dynNative": { argTypes: [DYN, F64], result: VOID },
|
||||
/** stream.dynNative for a pipe or unpipe destination: also a
|
||||
* constructor-function stream's runtime stream, in programs that link
|
||||
* that unit, unless it overrides write() or end(). */
|
||||
"stream.dynNativePipe": { argTypes: [DYN, F64], result: VOID },
|
||||
/** readable.pipe(destination, end) into a checked-dynamic destination
|
||||
* that is not a native stream: [source, the source boxed, destination,
|
||||
* end]. Node's pipe listener protocol over the destination's members
|
||||
|
||||
@@ -170,6 +170,7 @@ const STREAM_LIB_FNS: ReadonlySet<IrLibFn> = new Set([
|
||||
"stream.errored",
|
||||
"stream.prop",
|
||||
"stream.dynNative",
|
||||
"stream.dynNativePipe",
|
||||
"stream.pipeDyn",
|
||||
"stream.unpipeDyn",
|
||||
"stream.stdioWritable",
|
||||
@@ -209,6 +210,7 @@ const READABLE_DYN_ASYNC_PREFIXES: readonly string[] = ["readable.fromGen", "rea
|
||||
/** Entry points that link the dyn-invoke unit. */
|
||||
const DYN_INVOKE_LIB_FNS: ReadonlySet<IrLibFn> = new Set([
|
||||
"stream.dynNative",
|
||||
"stream.dynNativePipe",
|
||||
"stream.pipeDyn",
|
||||
"stream.unpipeDyn",
|
||||
"dyn.arrayProtoCall",
|
||||
@@ -568,7 +570,9 @@ const RUNTIME_FEATURE_RULES = {
|
||||
dynTier: rule({ prefixes: ["js."] }),
|
||||
/** Checked-dynamic stream slots test values and pipe into JavaScript
|
||||
* stream objects (scr_stream_dyn.c). */
|
||||
streamDyn: rule({ fns: ["stream.dynNative", "stream.pipeDyn", "stream.unpipeDyn"] }),
|
||||
streamDyn: rule({
|
||||
fns: ["stream.dynNative", "stream.dynNativePipe", "stream.pipeDyn", "stream.unpipeDyn"],
|
||||
}),
|
||||
/** The stream unit emits through the emitter unit, also when the
|
||||
* program constructs no stream (a pipeline of functions). */
|
||||
emitter: rule({
|
||||
|
||||
@@ -5233,7 +5233,7 @@ function validateFunction(
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (e.fn === "stream.dynNative") {
|
||||
if (e.fn === "stream.dynNative" || e.fn === "stream.dynNativePipe") {
|
||||
const def = e.type.kind === "union" ? unions.get(e.type.unionId) : undefined;
|
||||
const side = e.args[1];
|
||||
const className =
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"compilerVersion": "0.3.6",
|
||||
"compilerVersion": "0.4.0",
|
||||
"coverage": [
|
||||
"Entries are projected mechanically from the compiler's own decision tables: the diagnostics registry, the unsupported-syntax dispatch tables, the stdlib and node-builtin lowering tables, and the supported-builtin-module list. Nothing is hand-maintained; the manifest regenerates byte-identically from the source tree at this version.",
|
||||
"Absence from this manifest means 'not projected', never 'unsupported'. Surfaces lowered through dedicated code paths rather than tables are not yet projected: console, JSON, Promise/async and the timer surface, the net/http/tls/https/dgram/dns/assert/test/stream/readline module member surfaces, template literals, the regex slice, global functions (parseInt, parseFloat, isNaN, isFinite), and the process surface outside its ambient slice.",
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/5820-node-stream-dyn-constructor-overrides/sources.js",
|
||||
"<repo>/tests/corpus/5820-node-stream-dyn-constructor-overrides/main.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/experimental",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Experimental scriptc APIs, with Node.js implementations: lifetime regions for ProgramLifetime objects, intern tables shared between threads, and per-thread slots on shared objects",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/llvm-darwin-arm64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Pinned LLVM code-generation helper for scriptc on macOS arm64",
|
||||
"license": "Apache-2.0 WITH LLVM-exception",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/llvm-darwin-x64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Pinned LLVM code-generation helper for scriptc on macOS x64",
|
||||
"license": "Apache-2.0 WITH LLVM-exception",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/llvm-linux-arm64-gnu",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Pinned LLVM code-generation helper for scriptc on Linux arm64",
|
||||
"license": "Apache-2.0 WITH LLVM-exception",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/llvm-linux-arm64-musl",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Statically linked LLVM code-generation helper for scriptc on Linux arm64 musl",
|
||||
"license": "Apache-2.0 WITH LLVM-exception",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/llvm-linux-x64-gnu",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Pinned LLVM code-generation helper for scriptc on Linux x64",
|
||||
"license": "Apache-2.0 WITH LLVM-exception",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/llvm-linux-x64-musl",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Statically linked LLVM code-generation helper for scriptc on Linux x64 musl",
|
||||
"license": "Apache-2.0 WITH LLVM-exception",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/llvm-win32-x64-msvc",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Pinned LLVM code-generation helper for scriptc on Windows x64",
|
||||
"license": "Apache-2.0 WITH LLVM-exception",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-android-arm64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc library runtime pack for Android arm64",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-darwin-arm64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc runtime pack for macOS arm64",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-darwin-x64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc runtime pack for macOS x64",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-ios-arm64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc library runtime pack for iOS arm64",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-ios-simulator-arm64",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc library runtime pack for iOS simulator arm64",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-linux-arm64-gnu",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc runtime pack for Linux arm64 glibc",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-linux-arm64-musl",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc runtime pack for Linux arm64 musl",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-linux-x64-gnu",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc runtime pack for Linux x64 glibc",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-linux-x64-musl",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc runtime pack for Linux x64 musl",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-wasm32-wasi",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc runtime pack for WASI Preview 1",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime-win32-x64-msvc",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Precompiled scriptc runtime pack for Windows x64 MSVC",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/runtime",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "scriptc native runtime sources and vendored dependencies",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1192,6 +1192,10 @@ ScrDyn *scr_dyn_builtin_stream_object(struct ScrStream *s);
|
||||
ScrDyn *scr_dyn_builtin_stream_view(struct ScrStream *s);
|
||||
struct ScrStream *scr_dyn_builtin_stream_check(const ScrDyn *value, double kind);
|
||||
struct ScrStream *scr_dyn_builtin_stream_unbox(const ScrDyn *value, const ScrStr *message);
|
||||
/* stream.dynNative in those programs: scr_stream_dyn_native's contract,
|
||||
* also taking constructor-function streams that keep the runtime's write
|
||||
* and end (+1 or NULL). */
|
||||
struct ScrStream *scr_dyn_builtin_stream_dyn_native(const ScrDyn *value, double side);
|
||||
bool scr_dyn_class_is_key(const ScrDyn *value, const ScrStr *type_key);
|
||||
bool scr_dyn_class_is(const ScrDyn *value, const char *type_key);
|
||||
/* Calls a dyn value: a non-function kind throws the catchable TypeError
|
||||
|
||||
@@ -1673,6 +1673,31 @@ ScrStream *scr_dyn_builtin_stream_check(const ScrDyn *value, double kind) {
|
||||
return ok ? scr_stream_retain(s) : NULL;
|
||||
}
|
||||
|
||||
/* stream.dynNative (checked-dynamic stream slots, scr_stream_dyn.c) in
|
||||
* programs that link this unit: a constructor-function stream with the
|
||||
* requested side (1 readable, 2 writable) answers its runtime stream (+1),
|
||||
* so a pipe into it, and an unpipe of it, are the runtime's own, unless it
|
||||
* overrides write() or end(), which the runtime's pipe would bypass: that
|
||||
* one is NULL and pipes through its JavaScript members. Other values take
|
||||
* scr_stream_dyn_native. Never throws. */
|
||||
ScrStream *scr_dyn_builtin_stream_dyn_native(const ScrDyn *value, double side) {
|
||||
ScrStream *s = value->kind == SCR_DYN_OBJ ? bcs_of(value) : NULL;
|
||||
if (s) {
|
||||
const ScrVt *vt = s->vt;
|
||||
bool readable = vt->pre >= scr_readable_vt.pre && vt->pre <= scr_readable_vt.post;
|
||||
bool writable = vt->pre >= scr_writable_vt.pre && vt->pre <= scr_writable_vt.post;
|
||||
bool duplex = vt->pre >= scr_duplex_vt.pre && vt->pre <= scr_duplex_vt.post;
|
||||
if (!(duplex || (side == 1 ? readable : writable))) return NULL;
|
||||
ScrDyn *object = (ScrDyn *)value;
|
||||
if (side == 2 && (bcs_overrides(object, "write") || bcs_overrides(object, "end"))) {
|
||||
if (scr_exc_pending()) scr_exc_clear();
|
||||
return NULL;
|
||||
}
|
||||
return scr_stream_retain(s);
|
||||
}
|
||||
return scr_stream_dyn_native(value, side);
|
||||
}
|
||||
|
||||
/* stream.unboxDyn (an untyped pipe destination or pipeline stage) in
|
||||
* programs that link this unit: a constructor-function stream answers its
|
||||
* runtime stream (+1), unless it overrides write() or end(), which the
|
||||
|
||||
@@ -306,9 +306,50 @@ static void scr_wasm_throw_trap(int code) {
|
||||
|
||||
/* AddressSanitizer intercepts siglongjmp and warns when it cannot tell the
|
||||
* extent of the running stack, as on the runtime's async fibers. Sanitized
|
||||
* builds therefore jump with the compiler's builtin pair, which no runtime
|
||||
* intercepts, and unpoison the abandoned frames themselves. */
|
||||
#ifdef SCR_WASM_ASAN
|
||||
* builds therefore jump with a pair no runtime intercepts and unpoison the
|
||||
* abandoned frames themselves: the compiler's builtin pair, or on AArch64,
|
||||
* where the compiler has no builtin setjmp lowering, the pair below. */
|
||||
#if defined(SCR_WASM_ASAN) && defined(__aarch64__)
|
||||
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
||||
/* x19-x28, the frame and link registers, sp and d8-d15: the registers the
|
||||
* AArch64 procedure call standard has a callee preserve. */
|
||||
typedef uint64_t ScrWasmJmp[21];
|
||||
__attribute__((naked, noinline, returns_twice)) static int scr_wasm_setjmp(ScrWasmJmp buf) {
|
||||
__asm__ volatile("stp x19, x20, [x0, #0]\n"
|
||||
"stp x21, x22, [x0, #16]\n"
|
||||
"stp x23, x24, [x0, #32]\n"
|
||||
"stp x25, x26, [x0, #48]\n"
|
||||
"stp x27, x28, [x0, #64]\n"
|
||||
"stp x29, x30, [x0, #80]\n"
|
||||
"mov x16, sp\n"
|
||||
"str x16, [x0, #96]\n"
|
||||
"stp d8, d9, [x0, #104]\n"
|
||||
"stp d10, d11, [x0, #120]\n"
|
||||
"stp d12, d13, [x0, #136]\n"
|
||||
"stp d14, d15, [x0, #152]\n"
|
||||
"mov w0, #0\n"
|
||||
"ret\n");
|
||||
}
|
||||
/* Returns 1 from the scr_wasm_setjmp call that filled buf. */
|
||||
__attribute__((naked, noinline, noreturn)) static void scr_wasm_longjmp(ScrWasmJmp buf) {
|
||||
__asm__ volatile("ldp x19, x20, [x0, #0]\n"
|
||||
"ldp x21, x22, [x0, #16]\n"
|
||||
"ldp x23, x24, [x0, #32]\n"
|
||||
"ldp x25, x26, [x0, #48]\n"
|
||||
"ldp x27, x28, [x0, #64]\n"
|
||||
"ldp x29, x30, [x0, #80]\n"
|
||||
"ldr x16, [x0, #96]\n"
|
||||
"mov sp, x16\n"
|
||||
"ldp d8, d9, [x0, #104]\n"
|
||||
"ldp d10, d11, [x0, #120]\n"
|
||||
"ldp d12, d13, [x0, #136]\n"
|
||||
"ldp d14, d15, [x0, #152]\n"
|
||||
"mov w0, #1\n"
|
||||
"ret\n");
|
||||
}
|
||||
#define SCR_WASM_SETJMP(buf) scr_wasm_setjmp(buf)
|
||||
#define SCR_WASM_LONGJMP(buf) scr_wasm_longjmp(buf)
|
||||
#elif defined(SCR_WASM_ASAN)
|
||||
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
||||
typedef void *ScrWasmJmp[5];
|
||||
#define SCR_WASM_SETJMP(buf) __builtin_setjmp(buf)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/threads",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Zero-copy publication of immutable object graphs to worker threads (scriptc), with a deep-freezing Node.js implementation",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scriptc/types",
|
||||
"version": "0.3.6",
|
||||
"version": "0.4.0",
|
||||
"description": "Contract types for scriptc: type-only annotations (Int32, NoThrow, Immutable) that scriptc checks and optimizes, with no runtime semantics",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://scriptc.dev",
|
||||
|
||||
Generated
+9
@@ -1374,6 +1374,11 @@ packages:
|
||||
'@ts-morph/common@0.11.1':
|
||||
resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==}
|
||||
|
||||
'@tsc-ts/darwin-arm64@0.0.5':
|
||||
resolution: {integrity: sha512-yP64b2VpAKWG92KepBqxs1P89wpwiheYwNMk4EmmhSl6aw/ImIBrdHYNjvao3sg6FHZCXTc+PB6Vukh6hyQiJQ==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@tsc-ts/darwin-x64@0.0.5':
|
||||
resolution: {integrity: sha512-CEeHOFfpx5H9V3WSq+V7XGU8tfc06nRN818auiRVwuwPHvpti9gHq0HYkvf/43PH1pIGcgf68sQYdIxJhrQDKQ==}
|
||||
cpu: [x64]
|
||||
@@ -3442,6 +3447,9 @@ snapshots:
|
||||
mkdirp: 1.0.4
|
||||
path-browserify: 1.0.1
|
||||
|
||||
'@tsc-ts/darwin-arm64@0.0.5':
|
||||
optional: true
|
||||
|
||||
'@tsc-ts/darwin-x64@0.0.5':
|
||||
optional: true
|
||||
|
||||
@@ -4800,6 +4808,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@scriptc/threads': 0.3.6
|
||||
optionalDependencies:
|
||||
'@tsc-ts/darwin-arm64': 0.0.5
|
||||
'@tsc-ts/darwin-x64': 0.0.5
|
||||
'@tsc-ts/linux-arm64-gnu': 0.0.5
|
||||
'@tsc-ts/linux-arm64-musl': 0.0.5
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Constructor-function streams in NodeJS.ReadableStream / WritableStream
|
||||
// slots: member calls run the stream's own pause, resume and on, and a pipe
|
||||
// into one, and an unpipe of it, are the runtime's.
|
||||
import { Readable } from "node:stream";
|
||||
import { collector, recordingSource } from "./sources.js";
|
||||
|
||||
function control(stream: NodeJS.ReadableStream): void {
|
||||
stream.pause();
|
||||
stream.resume();
|
||||
stream.on("end", () => {});
|
||||
}
|
||||
|
||||
function attach(src: Readable, dst: NodeJS.WritableStream): void {
|
||||
src.pipe(dst);
|
||||
}
|
||||
|
||||
function detach(src: Readable, dst: NodeJS.WritableStream): void {
|
||||
src.unpipe(dst);
|
||||
}
|
||||
|
||||
const recording = recordingSource();
|
||||
control(recording);
|
||||
console.log("recorded", recording.calls.join(","));
|
||||
|
||||
const sink = collector();
|
||||
sink.on("pipe", () => console.log("pipe event"));
|
||||
sink.on("unpipe", () => console.log("unpipe event"));
|
||||
const source = new Readable({ read() {} });
|
||||
attach(source, sink);
|
||||
source.push("a");
|
||||
setImmediate(() => {
|
||||
detach(source, sink);
|
||||
source.push("b");
|
||||
setImmediate(() => console.log("collected", sink.chunks.join(","), source.isPaused()));
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
// Constructor-function streams that override stream methods, and a plain
|
||||
// JavaScript sink.
|
||||
import { Readable, Writable } from "node:stream";
|
||||
import util from "node:util";
|
||||
|
||||
/** A Readable whose pause, resume and on record their calls before
|
||||
* running Readable's own. */
|
||||
function Recording() {
|
||||
Readable.call(this, { read() {} });
|
||||
this.calls = [];
|
||||
}
|
||||
util.inherits(Recording, Readable);
|
||||
for (const name of ["pause", "resume", "on"]) {
|
||||
Recording.prototype[name] = function (...args) {
|
||||
this.calls.push(name);
|
||||
return Readable.prototype[name].apply(this, args);
|
||||
};
|
||||
}
|
||||
|
||||
/** @returns {any} */
|
||||
export function recordingSource() {
|
||||
return new Recording();
|
||||
}
|
||||
|
||||
/** A Writable without overrides, piped into natively. */
|
||||
function Collector() {
|
||||
Writable.call(this);
|
||||
this.chunks = [];
|
||||
}
|
||||
util.inherits(Collector, Writable);
|
||||
Collector.prototype._write = function (chunk, _encoding, done) {
|
||||
this.chunks.push(String(chunk));
|
||||
done();
|
||||
};
|
||||
|
||||
/** @returns {any} */
|
||||
export function collector() {
|
||||
return new Collector();
|
||||
}
|
||||
@@ -32,9 +32,12 @@ fs.writeFileSync(file, "file contents\n");
|
||||
const stream = fs.createReadStream(file);
|
||||
const release = (): void => console.log("released");
|
||||
stream.on("data", (chunk: Buffer | string) => describe("file", chunk));
|
||||
stream.on("close", release);
|
||||
stream.on("error", release);
|
||||
stream.on("end", () => {
|
||||
// The second read starts once the first stream has closed its file, so the
|
||||
// order of its 'close' and the second stream's data does not depend on
|
||||
// which file operation finishes first.
|
||||
stream.on("close", () => {
|
||||
release();
|
||||
const encoded = fs.createReadStream(file, { encoding: "utf8" });
|
||||
encoded.on("data", (chunk: Buffer | string) => describe("file utf8", chunk));
|
||||
encoded.on("close", () => {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{ "plain": 3490, "san": 8050 }
|
||||
Reference in New Issue
Block a user