js: lists, buffers and text natives under Node (slice 4A of #63) #708
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Step 5 of epic #63 (JavaScript back end), slice 4, part A of
docs/design/JAVASCRIPT-BACKEND.mdsection 6 row 4 ("The kernel, part 1"). Slices 1 to 3 (#678, #684, #701) are onmain:compiler/src/backend/javascript/{emit,body,type,natives,witness,count,writer}.trb,runtime/javascript/{core,int64}.mjs,tools/conformance.sh --js,tests/conformance/js.allow, CI jobconformance-js. The integer, comparison, conversion and text intrinsics (K1, K2, K4, K7,TextConcat,TextEqual,TextByteLength) are already emitted byemitIntrinsic; what stops every program that holds a list is the runtime natives (NativeTarget.Runtime,nativeNameOfinnatives.trbknows only the fivetorb_show_*/torb_process_exitsymbols) andInstruction.ContainerNew(kind: ListStorage)(body.trbreports it as unsupported).Slice 4 of the record is too big for one PR (kernel natives,
ListStorage, the manifest walk, BigInt property tests,isSame). Decided by the loop: it is split in two. This issue is 4A, the storage and the natives the standard library's list code stands on. 4B (filed when 4A lands): the walk ofnativeEntries()that fails for an entry without JavaScript (with the explicit deferred list for slices 5 and 7),isSame, theIntrinsicsweep over every width, and the property tests againstBigIntintools/.Source
docs/design/JAVASCRIPT-BACKEND.mdsection 3 (K5 row), section 4 ("Collections":ListStorageis a growingArrayor typed array with a count) and section 6 row 4.docs/design/NATIVES.md"Buffer", "String" and the list entries (listEntriesincompiler/src/backend/c/natives.trb:length,get,append,set,insert,removeAt,replaceBetween,reverse,clear,compact,sliceBetween,withCapacity) and theStringkernel rowssliceBytes,byteAt.runtime/(torb_list_*), andcompiler/src/backend/c/body.trbforContainerNewand for howNativeResult.Optional,ownedParametersandaddressedParametersshape a call.Goal
Programs that build, index, append to, slice and print lists run under Node:
ListStorage.ContainerNew(ListStorage)creates a list object (a growingArray; a plainArrayfor every element type in this slice, typed arrays are an optimisation for a later change). Every symbollistEntriesnames is a function ofruntime/javascript/with the C symbol's name and meaning: bounds errors panic with the same message and location astorb_list_*(torb_locationis theplacestringemitIntrinsicalready passes); anOptionalresult (get,removeAt) returns the value orundefinedaccording to howemitCallshapes anOptiontoday (read the existingOptionconstruct inbody.trb, do not invent a second form).clone()when it is read out (get), stored in (append,set,insert) or moved into a slice; a list ofshared typeobjects shares the objects and retains them, andReleaseof a list closes heldCloseobjects in the order the Ctorb_list_*drop does (slice 3'srelease$Textended by a list case, only whenClosing.holdingsays the list can hold one).String.sliceBytesandString.byteAt(K5), over the representation of section 2.5 as slices 1 and 2 left it;String.addis already+.natives.trbgains the symbols above; a symbol the back end still lacks stays a finding naming the symbol, as today.javascript_first.trbandjs-witnesses-close.trb).Decided by the loop
runtime/javascript/list.mjs, which the driver reads and writes in front of the program only when the emitted program reaches aListStoragesymbol (one whole-program flag fromemit.trb, likercin slice 3);core.mjsis unchanged except for a shared helper if two files need it. Reason:core.mjsis in every program, and the record's rule is that unused machinery is absent.MapStorageorSetStoragehere. Section 4 waits for epic #55 (collection storage onBuffer) for maps and sets; programs that need aHashMap,HashSetorTrie*stay offjs.allow.withCapacitydrops its hint as the C runtime does (first version), so no preallocation.torb_panicpath with theatlocation; exit code and stderr match the C leg.Files
compiler/src/backend/javascript/body.trb(ContainerNew, theRuntimecall shapes forOptional/ owned / addressed parameters),natives.trb(symbols),type.trb(list case of the drop /release$T,clone()of a list element),emit.trb(the list flag, readinglist.mjs).runtime/javascript/list.mjs(new).tests/conformance/js-lists.trb(new) with.expectedand.exit, and a second programjs-lists-panic.trbwith.expected,.stderr,.exitfor an out-of-rangeset/insert(check an existing panic program oftests/conformancefor the exact file set before writing it);tests/conformance/js.allow.docs/design/JAVASCRIPT-BACKEND.md: row 4 split into 4A (done) and 4B, and a "What slice 4A left out" paragraph; docs regenerated astorb docsrequires.Tests
js-lists.trb, text and integers only: build a list byappendand a literal, index withget/[],set,insert,removeAt,replaceBetween,reverse,clear,sliceBetween(and the slice keeps its own copy), a list of records (aggregate copy: mutating the original afterappenddoes not change the stored one), a list ofshared typeobjects withclose()(closed in the C drop order when the list is released), iteration withfor,printof a list throughShow,sliceBytes/byteAton ASCII and multi-byte text. Same.expectedand.exiton the C, VM and JavaScript legs..expected,.stderrand.exitfiles joinjs.allow. Candidates (list-using programs that need no map, set, float, task, file or time):array-pattern-binding,bankers-queue,buffer-list,buffer-holds-close,buffer-field-derived,collect-through-wrappers,cons-stack-persists,declared-list-shape,destructor-fields-and-lists,destructor-patterns-and-temporaries,destructor-slice-concrete,destructor-slice,heap-order,interpolation,joined,list-bounds-proven, plus the trait programs slice 3 left off (bound-methods,plain-bound,generic-trait-members,trait-constants,source-trait-value,trait-typed-literals,entry-cell-trait,shared-top-level-const,destructor-early-exits,slice-close-generic). A program that still fails for a construct of a later slice (a map or set, a float, a task, a native of 4B) stays off; the PR body lists each with the finding or output line that names the later slice. Programs with.allocationsfiles: the counts are a C-leg check; the printedclose()lines must match.js.allowis removed; the existing JS programs still pass.Acceptance criteria
js-lists.trbandjs-lists-panic.trbpass on the C, VM and JavaScript legs with identical expected filesjs.allowgrows by every program of the candidate list that passes, at leastbuffer-list,heap-orderand one ofdestructor-fields-and-lists/destructor-slice; each program left off is listed in the PR with its reasonlist.mjsin front of it): pinned by an unchanged output ofjavascript_first.trbtorb format --checkandtorb docs checkgreentools/check-commits.shclean;sh tools/gates.sh aand theconformance-jsjob green in forge CI (CI only, no local bootstrap or gates)Seed
Compiler and runtime only: no syntax change, no new native, no std name the compiler looks up, no change of the manifest (
nativeEntries()is read, not edited), noArchitecturecase.seed/is untouched. One PR; one Conventional Commit per logical change (feat(js): ...,test(js): ...), expect two or three. If the list-drop order work grows past one review, landListStorageand the natives first and move theclose()case into a follow-up commit of the same PR (not a second issue).Out of scope
4B (manifest walk,
isSame,Intrinsicsweep,BigIntproperty tests),MapStorage/SetStorage(epic #55), floats andlibm(5), structured control flow (6), tasks (7),.nojsmarkers andtorb test(8), typed arrays for lists, a minifier, source maps.Dependencies
#701 (slice 3, landed as PR #703).
Part of #63 (epic; do not close it).