Repository navigation
Compile the hot-shots StatsD client over UDP - #1568
Merged
Merged
Conversation
hot-shots, a StatsD client compiled from its JavaScript, failed when a program constructed a client. Each gap on its UDP path is closed generically: - Sloppy-mode functions with named parameters may read `arguments` where the aliasing of their parameters cannot show: only `arguments.length`, or element reads without parameter or element writes. - An `any` slot admits any boxable function value, including functions with optional parameters (`C.prototype.m = function (...)` through an untyped receiver). - In a JavaScript file TypeScript does not check, a prototype method takes its documented parameters as checked-dynamic values, as constructors already did. - JavaScript dgram sends run completion callbacks, buffer lists, connected sends and the six-argument offset/length form. - A dgram socket crosses into the checked-dynamic tree as a handle (SCR_DYNH_DGRAM_SOCKET) whose methods are function values, with untyped listeners that survive 'close'. The handle lives in its own runtime unit (scr_dgram_dyn.c, the dgramDyn feature), linked only when a program converts a socket to or from an untyped value. - `String.prototype.concat` on strings, and `parseInt` over a possibly missing or untyped value in JavaScript. Corpus programs 6590-6596 and the hot-shots-udp npm case (hot-shots 8.5.0 vendored) match Node in both lanes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…n runs concat, substr and the other typed String and Number extra methods convert their arguments after evaluating all of them. When an argument's conversion can run program code (an object's toString or valueOf), a variable read of the receiver or another argument is now kept in a local as well, so a conversion that assigns the variable leaves the already-evaluated argument unchanged, as in Node.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The hot-shots package is a StatsD client that scriptc compiles from its JavaScript. Constructing a client failed. This change closes each gap on the package's UDP path generically. It adds the package as an npm test case whose program sends metrics to a local dgram server.
Gaps and fixes
arguments. The client's constructor and itsincrementanddecrementmethods readarguments.lengthin functions that have named parameters and are not in an ES module. Such a function may now readargumentswherever the aliasing of its parameters cannot show: it reads onlyarguments.length, or it reads elements and never writes a parameter or an element (argumentsAliasingUnobservableinarguments-usage.ts).anyslot.Client.prototype.timer = function (...)through an untypedClientwas refused, because the function has optional parameters. Ananyslot boxes the function: the box fills omitted arguments withundefinedand checks the others, so the slot now admits any signature that can be boxed.C.prototype.m = function (...) {}) now takes its documented parameters as checked-dynamic values, as constructors already did. hot-shots documentssendStat(..., sampleRate {Number}, tags {Array}), then passesundefinedand objects to those parameters.socket.send()now runs the offset/length form with a sixth argument, completion callbacks, buffer lists (sent as one datagram), and sends on a connected socket. A callback receives(null, bytes), or the send failure instead of an'error'event. The ladder takes six untyped slots and no longer needs a fence.socket.emit.bind(socket)and the socket's other listener methods as values. A socket can now cross into the checked-dynamic tree as a handle (SCR_DYNH_DGRAM_SOCKET). The handle wraps an entry that holds the socket's untyped listeners, and its methods are function values that dispatch on their receiver. The handle supportson,once,removeListener,emit,send,close,bind,connect,address,refandunref. Untyped listeners survive the socket's'close', as Node keeps them, so the send-after-close error that hot-shots emits still reaches the listener itsclose()installed. JavaScript listeners with untyped parameters register through the same handle. The code is a runtime unit of its own (scr_dgram_dyn.c, thedgramDynfeature), which links only when a program converts a socket to or from an untyped value.Function.prototype.bind/call/applyon such a method value run at run time.String.prototype.concaton strings, which builds theDD_ENTITY_IDtag.parseIntover a possibly missing or untyped value in JavaScript, as inparseInt(process.env.DD_DOGSTATSD_PORT, 10) || 8125.Some paths stay explicit refusals where they run: the TCP transport (
socket.emiton anet.Socket), the telegraf message rewrite, and the buffered mode'sTimeouthandle. The Unix-socket mode reports the missingunix-dgramaddon as Node does.Evidence
arguments, function values in ananyslot, dgram send callbacks, bound socket methods, JSDoc on prototype methods,String.prototype.concat, andparseIntover a missing value.tests/fixtures/npm/cases/hot-shots-udpvendors hot-shots 8.5.0. The case compares stdout, stderr and exit status with Node in both lanes. It covers tags, explicit sample rates, the send callback, child clients, the error handler, close, a send after close, mock mode, and the Unix-socket refusal.--corpus=all, 3450 programs): 3449 byte-identical, including every benchmark and the self-hosted compiler. One program,2597-dgram-send-ladders.cjs, differs by intent: it is the JavaScript send-ladder program, and its calls now go to the six-slot callback-capable ladder (binary −0.03%). Benchmark time is within tolerance (geomean +0.02%). That run also showed the self-hosted compiler compiling 3.5 times slower: thedgramDyndetection walked every class's fields for each dynamic conversion. After the detection became a once-per-module fixpoint, the self set compiles to identical artifacts at +0.68% compile time (3 pairs, 95% CI −0.36% to +1.94%).Overlap
#1324 (sloppy
arguments) covers the first gap with its own implementation. Whichever of the two lands first, the other should drop its copy. A program that closes the client withpromisify(client.close.bind(client))(), where the package's types resolve toany, also needs #1502 (untypedutil.promisify).🤖 Generated with Claude Code