46 KiB
CodeMode Interpreter Support
This is the checkable support matrix for CodeMode's confined JavaScript interpreter. It tracks the language and standard-library surface that programs can use today, plus concrete gaps that may be implemented later.
[x]means the feature is implemented at the scope described here.[ ]means a concrete compatibility gap remains.- Checked items do not promise complete ECMAScript edge-case parity; known differences are stated explicitly.
- Intentional boundaries are not listed as compatibility work.
When behavior changes, update this file and the tests in the same change. The implementation and tests remain the
ultimate source of truth. Upstream test262 files run verbatim from test/test262; a failing file is listed in
test/test262/skipped.txt and its gap is an unchecked item here (see test/test262/README.md).
Source and execution model
- JavaScript parsed with the latest syntax accepted by Acorn, then restricted by the interpreter allowlist. TypeScript-only syntax is rejected rather than stripped before execution.
- Top-level
awaitandreturnthrough the program's implicit async-function scope. - Explicit
return, final top-level expression as a REPL-style result, andnullwhen no value is produced. - The host boundary is
JSON.stringifyplus a short table. The program result and tool arguments cross as whatJSON.stringifywould serialize:toJSONis honored, functions andundefinedproperties vanish,undefinedarray elements and non-finite numbers becomenull, a cyclic value throws the sameTypeError, and Map, RegExp, and generators serialize as{}. A bareundefinedresult isnull. Tool results come back the wayJSON.parse(JSON.stringify(result))would. The table, where a value cannot be JSON but what the program meant is clear: a promise is awaited (a rejection fails the program), a Set crosses as an array, a URLSearchParams as its query string, an Error as{ name, message, ...own enumerable }, a Uint8Array is rejected with a hint to encode as text, and own__proto__keys are dropped so merging tool inputs or results cannot replace a prototype. In-programJSON.stringifykeeps JS behavior except for the Error form and a promise, which is aTypeErrorwith an await hint rather than a silent{}. - Live Date, RegExp, Map, Set, URL, URLSearchParams, Headers, and Uint8Array values inside CodeMode.
- Tool calls through the host-provided
toolstree only. - The global
search(...)built-in: synchronous tool discovery that counts as an admitted tool call and is shadowable by program declarations like other globals. - Cooperative timeout, an optional total tool-call limit, output bounding, and unrestricted tool-call concurrency.
- The timeout fires between interpreter steps, so one built-in is bounded in what it may build: strings up to
2^24 characters (
repeat,pad*,concat,join,+, template literals,JSON.stringify), arrays up to 10,000,000 elements (Array(n),length =,Array.from,split,matchAll,concat,flat; below the JS maximum of 2^32 - 1), and 10,000 pending promises at once. Exceeding one throws aRangeError. A single regular expression match can still run long on a pathological pattern; the host regex engine has no interrupt hook. - A trailing comma after a rest parameter is a syntax error, with or without
"use strict". - A program that begins with
"use strict"rejectsyieldas an identifier and duplicate parameter names at parse time. Without it,yieldis an ordinary binding. - Duplicate parameter names in non-strict code bind the last parameter, as in JS (
function f(a, a)called with(1, 2)seesa === 2).
Values and literals
null,undefined, booleans, finite and non-finite numbers, and strings.- Array literals, including holes and spread from arrays, strings, Maps, Sets, URLSearchParams, Headers, custom synchronous iterators, and synchronous generators.
- Object literals with shorthand, computed string/number keys, and spread following ToObject: data objects and arrays copy own enumerable keys, strings copy index keys, and other values contribute nothing.
- Template literals with interpolation.
- Tagged templates: a tag applied to a template literal is called as
tag(strings, ...values), with the tag read like a callee so a member tag keeps its receiver.stringsis an array of the cooked text with a read-onlyrawarray of the source text; an invalid escape such as\unicodecooks toundefined. One template object per site, as in JS, but it is not frozen:strings[0] = "x"succeeds here where JS throws. - Regular-expression literals.
NaNandInfinityglobals.- BigInt literals and in-interpreter BigInt arithmetic; BigInt remains invalid at JSON-like host boundaries.
- Arbitrary Symbol primitive values and symbol-keyed properties. The confined
Symbol.iteratorandSymbol.asyncIteratorkeys are available only for the iterator protocols. - Getter and setter definitions in object literals.
Bindings and destructuring
const,let, andvardeclarations.- Object and array destructuring in declarations, parameters, assignment expressions, and
for...ofbindings. - Nested patterns, defaults, elisions, and rest elements.
- Assignment to identifiers, plain-object fields, non-negative integer array indexes, and writable URL fields.
- Direct function declarations are hoisted in program and block statement lists.
- Parameter defaults observe a temporal dead zone for later parameters.
varis function-scoped and hoisted: names declared anywhere in a function or program body, including loop heads, blocks,switchcases, andtry/catch, read asundefinedbefore their statement runs; redeclaration assigns the one binding; a same-named parameter keeps its argument; closures in parameter defaults see outer names rather than bodyvars.- Predeclare
letandconstbindings in every lexical scope, including program/block bodies, switch bodies, and loop headers, so reads before initialization and self- or cross-referential initializers observe the JavaScript temporal dead zone. - Function declarations are hoisted across all cases of a
switch, like any other statement list. - Computed object destructuring keys such as
const { [field]: value } = record. - Object destructuring from arrays, such as
const { length } = values. - Array binding and assignment destructuring from strings, Maps, Sets, URLSearchParams, custom synchronous
iterators, and synchronous generators, including stepwise elisions/rest and
IteratorCloseon early completion or binding/default failure. - Object destructuring from primitives follows ToObject (
const { length } = "abc",const {} = 1); non-object sources are rejected. - Destructuring reads through the prototype chain like member access:
const { constructor } = errorandconst { slice } = valuesfind the inherited built-in. - Any assignment target as a
for...inhead, likefor...of:for (x.y in obj),for (a[i++] in obj), and destructuring patterns.
Statements and control flow
- Blocks and empty statements.
if/elseand conditional expressions.switch, including default clauses and fallthrough.for,while, anddo...while.for...ofover arrays, strings, Maps, Sets, URLSearchParams, Headers, Uint8Arrays, built-in iterators, custom synchronous iterators, and confined synchronous generators. Abrupt completion invokes the iterator's optionalreturn().for...inover own keys of plain objects, arrays, strings, and tool references.null,undefined, and other non-objects iterate nothing. An un-awaited promise throws rather than iterating.- Unlabeled
breakandcontinue. try,catch, optional catch bindings, andfinally.throwwith arbitrary values.- Labeled statements, labeled
break, and labeledcontinue. for await...ofover the supported synchronous collections and custom iterator objects usingSymbol.asyncIteratoror theSymbol.iteratorfallback. Each iterator step is sequential, yielded promises and plain values from synchronous collections and sync iterators are awaited before binding, and abrupt loop completion invokes the iterator's optionalreturn(). Custom async iterators control their yielded values, as in JavaScript; only theirnext()results are awaited. Confined sync and async generators are iterable here.
Functions and callbacks
- Function declarations, function expressions, and arrow functions.
- Synchronous and
asyncfunctions. A line break betweenfunctionand the name is allowed, as in JavaScript; a line break betweenasyncandfunctionis not an async function. - Closures, recursion, default parameters, rest parameters, and destructured parameters.
- A call depth limit of 10000: deeper nesting throws a catchable
RangeError: Maximum call stack size exceededat the overflowing call instead of running until the timeout. Callbacks invoked by built-ins count below the call that invoked the built-in, and a resumedawaitstarts from depth 0 as in JS, so long async chains such as recursive pagination are unaffected. - Expression and block function bodies.
- User callbacks for the supported Array, Map, Set, URLSearchParams, sort, string-replacement, and
Array.frommapper APIs, with one shared acceptance rule everywhere including promise reactions. Boolean,Number,String,parseInt,parseFloat,isFinite,isNaN, and URI helpers as callbacks.- Built-in method references as callbacks, such as
values.map(Math.abs),records.map(JSON.stringify),items.forEach(console.log), andPromise.resolve(-1).then(Math.abs). Extra callback arguments a built-in does not consume are ignored, like JS, and consumed arguments coerce, like JS ("3.7".replace(/\d\.\d/, Math.floor)is"3"). A detached method loses its receiver, as in JS:values.filter("abc".includes)is aTypeErrorbecauseincludesis called without a stringthis. - Constructors work as callbacks with JS call semantics:
Errortypes construct (messages.map(Error)), and new-requiring constructors (Map,Set,URL,URLSearchParams,Headers,Promise) throw aTypeError, like JS. - Tool references and detached
Promisestatics are rejected as callbacks with a hint to wrap them in an arrow function. - Promise-returning string replacers are coerced synchronously to
"[object Promise]", like JavaScript; they are not automatically awaited. - The optional
thisArgof iteration methods is accepted and ignored: CodeMode functions have nothis, so ignoring it matches JS arrow-function semantics exactly. thisin non-arrow CodeMode functions and callbacks.- User-defined constructor calls.
Function.prototype.call,apply, andbindfor CodeMode functions.- Classes and private fields.
- Functions are objects: they hold own properties (
fn.count = 1), enumerate them, and expose read-onlynameandlength. Names follow JavaScript's NamedEvaluation: declarations, named expressions, bindings, assignments, object literal keys, and destructuring or parameter defaults. - Built-in functions are objects too, with
nameandlength(Math.max.length === 2,Array.prototype.push.name === "push"). - A named function expression's name is bound read-only inside its own body; assigning to it throws a
TypeError, as in strict mode. - Redeclaring a function in the same scope, or alongside a
var, is allowed: the last declaration wins. - Generator functions have their own
prototype(inheriting the shared generator prototype), sog() instanceof gholds. Plain functions have none, since they cannot construct. - Generator and async generator functions bind parameters (defaults, destructuring) at the call and defer only the
body to the first
next(), so a bad argument throws synchronously from the call site, as in JS. - Synchronous and async generator declarations/expressions,
yield, andyield*, including lazy bodies,next(value),return(value),throw(value), exhaustion, promise adoption, async request ordering,try/catch/finally, and sync/async iterator symbols. Asyncyield*awaits values while adapting a sync iterator but preserves values supplied by a manually implemented async iterator. Generator values are opaque runtime references. - Synchronous generators and custom synchronous iterators are consumed stepwise by array/argument spread, array
destructuring,
Array.from, Map/Set/URLSearchParams construction,Object.fromEntries, Object/MapgroupBy, Promise combinators,AggregateError, andMath.sumPrecise. Mapper/grouping callbacks interleave with iterator steps; synchronous consumers preserve yielded promise objects rather than awaiting them. Async generators are rejected by every synchronous consumer. - Synchronous iterator acquisition and result validation follow
IteratorCloseboundaries: consumer errors and intentional early stops invokereturn(), acquisition/next()failures do not, and an original consumer error wins over a cleanup failure. A generator'sreturn()is an intentional stop, so areturn()that throws or yields a non-object surfaces from it as aTypeError. Async iterator consumption remains limited tofor await...ofand asyncyield*. - Portable generator protocol coverage is adapted from pinned Test262 cases for suspended-start, suspended-yield,
and completed states; sync and async
next/return/throw; finally yields and completion overrides; rejected yielded promises; mixed async request queues; sync and asyncyield*forwarding; malformed methods/results; and declaration, expression, and object-method forms with closure and parameter behavior. The adapted suite deliberately skips Test262 variants whose observation mechanism requires unsupported getter definitions, proxies, prototype inspection or mutation, non-arrowthis, classes, or arbitrary symbols. It also skips tests asserting exact promise reaction-turn counts beyond the observable ordering guarantee documented below. These are interpreter-surface boundaries, not claims that the corresponding full Test262 families pass unchanged.
Expressions and operators
- Property access with dot or computed bracket syntax.
- Optional property access and optional calls.
- Function/tool calls and spread arguments.
- Sequence expressions (the comma operator).
awaitfor CodeMode promises and callable thenables; a plain value passes through unchanged, though everyawaitstill defers its continuation one reaction turn.newfor Array, Object, Error types, Date, RegExp, Map, Set, URL, URLSearchParams, Headers, and Promise.newon any other value throws a catchableTypeErrornaming the callee: other built-in functions such asNumbersaynewis unsupported and point at the plain call, user-defined functions report the constructor gap below, and non-callable values are not constructors. Error constructors take the ES2022 options object, sonew Error(message, { cause })installs a non-enumerablecausewhen the option is present.Error.isErroris true for every Error value.- Arithmetic operators:
+,-,*,/,%, and**. - Equality and ordering:
==,!=,===,!==,<,<=,>, and>=. - Bitwise operators:
&,|,^,~,<<,>>, and>>>. - Logical operators:
&&,||,??, and!, with short-circuiting. - Unary
+, unary-,void,typeof,instanceof(through the constructor'sprototype, so[] instanceof Objectholds), andinacross the prototype chain. - Prefix and postfix
++and--. - Plain, arithmetic, bitwise, and logical assignment operators.
- Property deletion on plain data objects and arrays, including computed and optional forms; deleting an array index
creates a hole without changing its length. Deleting a non-configurable property (
length) or assigning a read-only one (Math.PI,fn.name) throws aTypeError, as in strict mode.deleteof a non-reference (delete 0,delete f()) evaluates the operand and istrue;delete xon a variable throws. - Coercion helpers and template interpolation accept functions and namespaces:
String(fn)and${fn}give"[object Function]"rather than the source text,isNaN(fn)istrue. - Operators other than
===/!==,switchdiscriminants and cases, andObject.isapplied to a function, promise, generator, tool reference, or any object holding one anywhere inside; JavaScript compares by identity or coerces (fn == nullisfalse,fn + ""is its source text), the interpreter throwsTypeError: Binary operators require data values.The check walks both operands' whole object graphs, sorows == nullon a large array is slow whererows === nullis not. - ToPrimitive on program objects: operators,
Number/String,Error(message),parseIntradix, multi-argumentDateconstruction andDate.UTC, and numeric built-in arguments (Math.max,at,indexOfstart) should call the object's ownvalueOf/toStringin spec order and surface their throws. Today they use the built-in form (NaN,"[object Object]") and ignore own methods. Date setters and one-argumentDateconstruction already follow ToPrimitive. - Property keys follow ToPropertyKey:
x[null],x[true], and objects (via their built-in string form) become string keys.
Promises and tools
- Tool calls start eagerly and return supervised, run-once CodeMode promises.
- Direct
await, repeated awaits, and recursive thenable assimilation when a promise or thenable is returned from a function/program. Promise.resolveandPromise.reject.Promise.all,Promise.allSettled,Promise.race, andPromise.anyover finite collections, custom synchronous iterators, and synchronous generators containing promises and plain values.Promise.allpreserves result order and rejects on the first observed failure without cancelling siblings.Promise.allSettledreturns plain fulfilled/rejected outcome records.Promise.racesettles from the first result without cancelling losers at settlement time.- Real promise values from
Promise.all,Promise.allSettled, andPromise.race; separately constructed combinator batches overlap as in normal JavaScript. - Promise chaining with
.then,.catch, and.finally: handlers run deferred in attach order, returned promises are adopted, handler throws reject the derived promise,.finallypreserves the original settlement unless its cleanup fails, and direct self-resolution rejects with aTypeError. - Every
await(including of plain values and already-settled promises) defers its continuation one reaction turn, so concurrent async functions interleave at await points as in JavaScript. - Combinators settle one reaction turn after their deciding member (V8-observable ordering): reactions already
attached to members run first, and an aggregate cannot beat a plain value settling in the same turn into a
Promise.race. Exact microtask-count parity beyond this observable ordering is not a documented guarantee. - All still-pending work (race losers, fail-fast
Promise.allstragglers, and un-awaited calls alike) is interrupted when the program returns; rejections that settled un-awaited becomeSuccess.warningsdiagnostics. A combinator abandoned inside its final settlement turn counts as pending and is interrupted without a warning. try/catchcan handle awaited tool and promise failures.Promise.any: first fulfillment wins; all-rejected rejects with anAggregateErrorwhoseerrorsarray holds the catch-normalized reasons in input order, and empty input rejects with an emptyAggregateError.new Promise((resolve, reject) => ...): the executor runs synchronously and receives first-class resolve/reject callables that settle the promise exactly once (they may escape the executor and settle later); an executor throw rejects unless the promise already settled, resolving with a promise or callable thenable adopts it, and resolving with the promise itself rejects with aTypeError. Resolver callables work anywhere callbacks are accepted, including.then/.catchhandlers and collection callbacks, and vanish at the data boundary like any function.Promise.withResolvers(): the same promise and resolver callables as the constructor, as a{ promise, resolve, reject }object.Promise.try(fn, ...args): callsfnsynchronously; a throw rejects, a return fulfils, and a returned promise or thenable is adopted.- Recursive assimilation of objects with an own callable
thenfield acrossPromise.resolve, combinators, constructors, reactions,finally,await, and async returns. Thenable methods run deferred, receive first-call-wins resolve/reject functions, and ignore throws after settlement. Inherited/accessorthenfields and a JavaScriptthisreceiver remain outside the supported object/function model. - Dotted tool names are canonicalized into namespace paths; a path can be both callable and a namespace, and the last tool supplied for a canonical path wins.
- Tool path segments may be named
constructor,prototype, or__proto__because paths use inert Map keys. - Outbound tool arguments are what
JSON.stringifywould serialize (see the boundary rule above). Tools never receiveundefinedinside their input object, though a baretools.t(undefined)argument still reaches schema decoding asundefined. - Tokenize and case-fold non-ASCII tool paths, descriptions, and queries for tool search.
Objects and properties
- Own-field reads and writes on plain data objects.
newdispatches on the evaluated constructor value, so aliases (const D = Date; new D()), constructors held in objects, and constructors passed as arguments work, while a shadowed name (const Date = 5; new Date()) does not construct.Object()andnew Object()return{}for nullish arguments and pass objects through unchanged; primitive wrapper objects (Object(1)) are rejected explicitly.- Computed property names and object spread. Any value works as a key (ToPropertyKey): strings, numbers, and the
two confined symbols as themselves, everything else as its string form (
o[null]iso["null"],o[{}]iso["[object Object]"]), in reads, writes, literals,in, and destructuring. Object.keys,Object.values,Object.entries,Object.hasOwn,Object.assign, andObject.fromEntries, with synchronous iterator support forfromEntries. Sources follow ToObject: strings enumerate by index, other primitives and wrappers contribute nothing, andnull/undefinedthrow.Object.assignaccepts array targets for index keys only; a primitive target is aTypeErrorrather than a boxed object.Object.keysover arrays and tool references.- Object identity is preserved by in-CodeMode Object helpers.
- Every value has a real prototype chain built fresh for each run:
Object.prototype,Array.prototype,String.prototype,Error.prototype→TypeError.prototype, and so on hold the built-in methods as non-enumerable properties, and each constructor'sprototypepoints at it ([].constructor === Array,Object.getPrototypeOfis not exposed). Programs may read and even overwrite these prototypes; the change is confined to that run.__proto__is an ordinary own data key, soo.__proto__ = xnever changes the chain, andObject.groupByresults have no prototype at all, as in JS. - Circular references are rejected when created (
o.self = o,array.push(array)), not at serialization as in JS. Object.isfor supported data values.Object.groupByover finite collections and custom synchronous iterators/generators, with string-key coercion and plain-object results.Object.prototypemethods on values:toString("[object Array]","[object Map]","[object Promise]", and so on for every built-in kind, as JS reports throughSymbol.toStringTag),toLocaleString(calls the value'stoString, as in JS),valueOf,hasOwnProperty,isPrototypeOf, andpropertyIsEnumerable.
Arrays
- The
Arrayconstructor with or withoutnew:Array(a, b)collects arguments andArray(n)creates a sparse array of that length; invalid lengths throwRangeError. Iteration, spread, join, and JSON handle holes like JavaScript, and host results normalize holes tonull. - Static methods:
Array.isArray,Array.of, andArray.from, including theArray.frommapper form with(value, index)arguments and stepwise synchronous iterator consumption. - Iteration/transformation:
map,filter,flatMap, andforEach. - Searching/tests:
find,findIndex,findLast,findLastIndex,some,every,includes,indexOf, andlastIndexOf. - Aggregation:
reduceandreduceRight. - Ordering:
sort,toSorted,reverse, andtoReversed. - Access/copying:
at,slice,concat,flat,with,join, andtoLocaleString(each element'stoLocaleString, holes and nullish elements as empty strings). - Mutation:
push,pop,shift,unshift,splice,fill, andcopyWithin. keys,values,entries, and[Symbol.iterator](the same function asvalues) return live iterator objects withnext()and[Symbol.iterator], as in JS. Iterator objects are opaque references: they print as[opaque reference], serialize to{}, and cannot be passed to extensions. Every built-in collection iterator shares one prototype. JavaScript gives each collection its own; the difference is not observable here becauseObject.getPrototypeOfis not exposed.length, numeric indexing, index assignment, spread, andfor...of.- The
thisArgargument ofArray.fromis accepted and ignored, like JS arrows. Array.prototype.toSpliced.- Canonical array/string index parsing: keys such as
"01"are ordinary properties rather than aliases of index1. Array.prototype.sortpreserves trailing holes, whiletoSorteddensifies holes intoundefinedelements, like JavaScript.- Assigning
lengthto truncate or extend an array; invalid lengths throwRangeError. - Non-index own properties on arrays (
arr.foo = 1,arr.constructor = null). They are excluded from the JSON form, likeJSON.stringify. - Numeric arguments coerce as in JS (ToIntegerOrInfinity):
indexOf(x, "1"),slice("1", "3"),at(null),flat(1.9),with(1.5, v),Math.max("3", "2"),parseInt("11", "2"),(1.5).toFixed("2"),String.fromCharCode("65"), and the Uint8Array equivalents.join(sep)andJSON.parse(text)apply ToString (join(null)is"1null2",JSON.parse(123)is123).Array.from({ length: "2" })applies ToLength; a promise source still throws with anawaithint rather than JS's silent[]. A program object's ownvalueOf/toStringis not consulted yet (see ToPrimitive above).
Strings
- Case/normalization:
toLowerCase,toUpperCase,normalize, and thetoLocaleLowerCase/toLocaleUpperCasealiases, which ignore their locale argument and apply the default Unicode casing. - Trimming:
trim,trimStart, andtrimEnd, plus the Annex BtrimLeftandtrimRightaliases. - Searching/tests:
includes,startsWith,endsWith,indexOf,lastIndexOf, andsearch. - Slicing/access:
slice,substring, Annex Bsubstr,at,charAt,charCodeAt, andcodePointAt. - Construction/transformation:
split,concat,repeat,padStart,padEnd,replace, andreplaceAll. - Regular-expression integration:
match, materializedmatchAll,replace,replaceAll,split, andsearch. localeCompare; locale and options arguments are currently ignored.isWellFormedandtoWellFormed.toString,length, numeric indexing, spread,for...of, and[Symbol.iterator]by Unicode code point.- Static
String.fromCharCodeandString.fromCodePoint. - Native argument coercion for supported String methods; for example,
includes(1)andslice("1")coerce like native JS,split(undefined)returns the whole string, andincludes/startsWith/endsWithreject regular expressions with a native-styleTypeError. Opaque runtime references still reject as data errors, andrepeatstill requires a finite non-negative count. - Native no-argument parity for
match(),matchAll(), andsearch(); all behave as an empty pattern. String.raw, on a template object or any{ raw }object; raw strings and substitutions coerce through their owntoString.match,matchAll,search, andsplitread any non-RegExp argument as a pattern string, asnew RegExp(arg)would:"a1b".match(1)matches/1/,search(null)looks for"null", andundefinedis the empty pattern. Objects use their built-in string form until ToPrimitive lands.
Numbers and Math
- Coercion functions:
Number,parseInt, andparseFloat. - Number predicates/parsers:
Number.isInteger,Number.isFinite,Number.isNaN,Number.isSafeInteger,Number.parseInt, andNumber.parseFloat. - Number formatting:
toFixed,toPrecision,toExponential,toString,valueOf, andtoLocaleString, which always formats asen-US("1,234.5") so output does not depend on the host. - Number constants:
MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,MAX_VALUE,MIN_VALUE,EPSILON,NaN,POSITIVE_INFINITY, andNEGATIVE_INFINITY. - Math constants:
PI,E,LN2,LN10,LOG2E,LOG10E,SQRT2, andSQRT1_2. - Math methods:
random,max,min,abs,acos,acosh,asin,asinh,atan,atan2,atanh,floor,ceil,round,trunc,sign,sqrt,cbrt,pow,hypot,cos,cosh,sin,sinh,tan,tanh,log,log2,log10,log1p,exp,expm1,f16round,fround,clz32, andimul. - Native zero-argument behavior for
Number()andString(): they produce0and"", whileNumber(undefined)staysNaNandString(undefined)stays"undefined". ++and--use CodeMode numeric coercion (numeric strings increment, plain data objects becomeNaN, Dates use their epoch time) and reject opaque runtime references as data errors.- Unknown static members on global namespaces and on
Number/String/the coercion functions read asundefinedfor feature detection. Calling any undefined value reports a native-styleTypeErrornaming the callee, for exampleMath.sum is not a function.orsearch(...).catch is not a function.UnknownPromisestatics keep their descriptive error. Math.sumPreciseover finite collections and custom synchronous iterators/generators, rejecting non-number elements without coercion.- Global coercing
isFiniteandisNaN; opaque runtime references reject as data errors, likeNumber(...).
JSON and console
JSON.parseandJSON.stringifyfor supported data objects.- Numeric/string indentation for
JSON.stringify. JSON.parsereviver callbacks, including postorder traversal, deletion throughundefined, and root replacement. Revivers receive(key, value)but nothisholder because CodeMode functions intentionally have nothis.JSON.stringifyfunction and array replacers. Function replacers receive(key, value)in preorder, including the root, but nothisholder. Array replacers preserve requested property order, deduplicate names, coerce number primitives, and ignore non-string/non-number entries. Primitive wrapper entries remain unsupported.- Captured
console.log,console.info,console.debug,console.warn, andconsole.error. An Error prints asError.prototype.toStringwould show it (Error: boom), wherever it appears in the logged value. - Captured
console.dirandconsole.table.
Date
Date.now,Date.parse, andDate.UTC.new Date()from the current time, epoch milliseconds, a date string, another Date, or local components.Date()withoutnewreturns the current time as a string, like JS, but in deterministic ISO format rather than the host's locale/timezone string.getTime,valueOf,toISOString,toJSON, and deterministic ISOtoString.- Local getters:
getFullYear,getMonth,getDate,getDay,getHours,getMinutes,getSeconds, andgetMilliseconds. - UTC getters:
getUTCFullYear,getUTCMonth,getUTCDate,getUTCDay,getUTCHours,getUTCMinutes,getUTCSeconds, andgetUTCMilliseconds. getTimezoneOffset, arithmetic, relational comparison, andinstanceof Date.- Date values serialize to ISO strings; invalid dates serialize to
null. - Local and UTC Date setters, including native argument coercion, mutation, rollover, invalid-Date recovery, and
TimeClipbehavior. Date.prototype.toUTCStringand itstoGMTStringalias.toDateStringandtoTimeStringin the host's local timezone.toLocaleString,toLocaleDateString, andtoLocaleTimeStringalways format asen-USin UTC ("1/1/1970, 12:00:00 AM") so output does not depend on the host.- Native one-argument Date coercion for supported values, including booleans, null, arrays, and plain objects.
- Date setters and one-argument construction coerce object arguments through their own
valueOf/toStringand surface their throws. - Multi-argument construction and
Date.UTCcoerce object arguments the same way (see ToPrimitive above). - Native Date loose-equality and default primitive-coercion semantics, using CodeMode's deterministic ISO string representation for the string primitive.
- Native
RangeErrorbranding for invalidtoISOString()calls.
Regular expressions
- Literal and
RegExp(pattern, flags)construction, with or withoutnew. test,exec, andtoString.- Readable
source,flags,lastIndex,hasIndices,global,ignoreCase,multiline,sticky,unicode,unicodeSets, anddotAll. - Captures, named groups, match
.indexand.input, and stateful global matching. - Integration with supported String methods, including function replacers.
- Writable
lastIndex, shared byexec,test, and the String methods. It is a prototype accessor that stores a number, sore.lastIndex = "12"reads back12,deleteis a no-op, andhasOwnProperty("lastIndex")isfalse. - Match
indicesmetadata for thedflag, including named groups onexec,match, andmatchAllresults. RegExp.escape.
Iterator
Iterator.prototype.map,filter,take,drop, andflatMapon any iterator or generator: lazy, one source step per result, closing the source when a callback throws, on earlyreturn(), or whenfor...ofor destructuring finishes with it early. Once done or closed a helper stays done, and a callback that re-enters its own helper is aTypeError.take/dropcoerce their count and rejectNaNor negative counts with aRangeError;flatMapcallbacks must return an iterable or iterator, not a string.Iterator.prototype.reduce,toArray,forEach,some,every, andfind, closing the source on early exit.Iterator.from(value)returns iterators and generators as they are, and wraps strings, iterables, and objects with anextmethod.Iteratoritself is abstract: calling or constructing it is aTypeError.- Helpers and
Iterator.fromwrappers havereturn(); collection iterators (array.values()) do not, as in JS, so an early exit from them leaves them where they were. Iterator.concat,Iterator.zip, andIterator.zipKeyed(stage 3 proposals).
Map and Set
- Static
Map.groupByover finite collections and custom synchronous iterators/generators, preserving key identity. new Map()from synchronous iterables of entries.- Map
get,set,has,delete,clear,size,forEach,getOrInsert, andgetOrInsertComputed.forEachis live: entries deleted during the walk are skipped and entries added are visited, as in JS. new Set()from synchronous iterables.- Set
add,has,delete,clear,size, andforEach. - Live
keys,values,entries, and[Symbol.iterator]iterators for Map and Set; a Set-like operand'skeys()may return any iterator or an array. - Spread,
for...of,Array.from, andObject.fromEntriesintegration. - Map and Set values serialize to
{}at host/JSON boundaries. - Set composition and relation methods:
union,intersection,difference,symmetricDifference,isSubsetOf,isSupersetOf, andisDisjointFrom, including supported Set-like operands.
URL and URI helpers
encodeURI,encodeURIComponent,decodeURI, anddecodeURIComponent.new URL(input, base),URL.canParse, andURL.parse.- URL
toString,toJSON, and linkedsearchParams. - Readable URL fields:
href,origin,protocol,username,password,host,hostname,port,pathname,search, andhash. - Writable URL fields except
origin. new URLSearchParams()from query strings, data objects, synchronous iterables of pairs, and URLSearchParams.- URLSearchParams
append,delete,get,getAll,has,set,sort,forEach,keys,values,entries,[Symbol.iterator],toString, andsize. - URL values are their href in
JSON.stringifyand at the host boundary. URLSearchParams are{}inJSON.stringifyand their query string at the host boundary.
Uint8Array
The only binary type. Bytes stay inside the program or cross to extensions as copies; the tool boundary rejects them
with a hint to encode as text first (TextDecoder, toBase64, toHex).
new Uint8Array(length | array | iterable | Uint8Array),Uint8Array.from,Uint8Array.of,fromBase64, andfromHex. Lengths are capped like arrays.- Index reads and writes with JS byte semantics: values wrap modulo 256, out-of-range writes are ignored, indexes
cannot be deleted.
lengthis a prototype accessor, soObject.keyslists only indexes. at,slice,subarray(a view on the same bytes),set,fill,reverse,indexOf,lastIndexOf,includes,join,toString,toBase64,toHex, and livekeys,values,entries, and[Symbol.iterator]iterators.- Spread, destructuring,
for...of,yield*,Array.from, andnew Set(bytes).Array.isArrayis false. - String coercion joins with commas;
JSON.stringifygives{"0":1,...};console.logprintsUint8Array(n) [...]. - Callback methods (
forEach,map,filter,find,reduce, ...); useArray.from(bytes, fn)meanwhile. ArrayBuffer,DataView, and other typed arrays.
Web platform helpers
atobandbtoawith forgiving-base64 decoding and WebIDL string conversion; invalid input throws aTypeError, since there is noDOMException.crypto.randomUUID()andcrypto.getRandomValues(uint8Array).TextEncoderandTextDecoderfor UTF-8 only: any other label is aRangeError.TextDecoderaccepts thefatalandignoreBOMoptions;decodetakes a Uint8Array or nothing.new Headers()from records, synchronous iterables of pairs, and Headers, wrapping the host'sHeaders: names fold to lowercase, values are normalized and combined, and invalid names or values throw aTypeError.- Headers
append,delete,get,getSetCookie,has,set,forEach,keys,values,entries, and[Symbol.iterator]; iteration is live and sorted by name, withset-cookievalues kept apart. - Headers serialize to a
{ name: value }object in JSON, in results, and in tool arguments. Request,Response, andBlob.crypto.subtleandTextDecoderstreaming or non-UTF-8 encodings.
Extensions
Host functions a host opts in through Extension.make({ name, globals }) and CodeMode.make({ extensions }).
Nothing is exposed unless a host provides it; extension calls are not tool calls.
- Each global is a function, callable but not constructible, run with
thisundefined. A global that shadows a built-in or another extension throws atmake. - Every value crossing in either direction is converted, never shared: plain objects and arrays are copied,
Date,RegExp,URL,URLSearchParams,Headers,Map,Set, andUint8Arraybecome fresh copies with their contents converted (a hostArrayBuffercomes in as aUint8Array; other typed arrays cannot come out), errors cross as errors with their name, message,cause, and own enumerable data, and a__proto__key is dropped. Functions, generators, un-awaited promises, and symbols cannot be passed in; a class instance, a symbol, or a BigInt cannot come out. - A host function inside a result becomes a program function whose calls cross the same way, so a result can
carry methods (
res.json()) whose host closures keep the host state. Diagnostics name it by its path (fetch.json). Like any program function it vanishes at the data boundary. - Each call to an extension global runs inside the host's
extension.before/extension.afterhooks as{ extension, name, args }, with the host's own error on failure; calls to functions inside results do not. - A host
Promisebecomes a program promise. Whatever host code returns, resolves, throws, or rejects with crosses the same way, socatch (e)receives a copy of the thrown value (anErrorof the matching type, or plain data). - An Error crosses, in either direction, as its name, message,
cause, and own enumerable data, so Node'scode,errno,syscall, andpathreach the program anderr.code === "ENOENT"works.stackstays on its own side, no field may shadow an Error method, and a field that cannot cross (a class instance, a function) is left behind rather than replacing the error. - Program functions as arguments to extension code (callbacks such as
forEach). - Host classes. Stateful host objects are expressed as closures; a declared method table would be the next
step if
new X()in a program is ever needed.
Errors and diagnostics
Error,TypeError,RangeError,SyntaxError,ReferenceError,EvalError, andURIError, callable with or withoutnew.AggregateErrorwith the(errors, message?)signature and an ownerrorsarray, constructed directly or by an all-rejectedPromise.any; direct construction accepts custom synchronous iterators and generators.- Error
name/message, error inheritance throughinstanceof, and plain-data serialization.messageis an own non-enumerable property andnameis inherited, as in JS, soObject.keys(err)is[]for a plain error. The result boundary still emits{ name, message, ...own enumerable }, so a field such ascodecrosses.causeis non-enumerable: an extension Error carries it, and this JSON form does not. Errors have nostack; the diagnostic carries a 1-based line and column in the submitted source instead. instanceofagainst any constructor with aprototype, including every built-in andFunction.- Catchable user throws, runtime failures raised during interpreted evaluation, awaited tool failures, and awaited
tool-call-limit failures; parse/compile failures, cooperative timeout, and output bounding remain outside program
catch. - Source locations on unsupported-syntax diagnostics. The diagnostic names the rejected node type and attaches a short orientation to the supported subset; this matrix is the full reference.
- Model-visible host failure messages and underlying causes, including output-validation errors.
- Caught errors do not distinguish user throws, interpreter failures, and tool failures; a program sees one
Error-shaped value in
catch, rejection handlers, andPromise.allSettledreasons. It always hasnameandmessage, pluscauseand own data when the failure carried them. This is deliberate: the program should handle a failure the same way regardless of where it originated. - Failures raised by the interpreter are
TypeErrors unless JavaScript names them otherwise (RangeError,ReferenceError,SyntaxError,URIError), soe instanceof TypeErrorande.constructor === TypeErrorhold. Unsupported syntax reached at runtime is aSyntaxError; awaited tool failures stay plainError. Host errors escaping a built-in ((1).toFixed(200)) become the same-named program error at the call. A failure raised inside a promise a built-in created (Promise.all(1),Promise.race([]), a resolution cycle) is located at the call that created the promise. - One failure is one error object: every
catch, rejection handler, andallSettledreason for the same failure sees the identical value, soa === bholds after awaiting the same rejected promise twice. - Rethrowing an interpreter failure keeps its diagnostic:
catch (e) { throw e }still reports the original kind and source location. Uncaught errors report asname: messagewhoever raised them, asError.prototype.toStringwould (TypeError: Cannot read properties of null (reading 'foo').,TypeError: bad input); other thrown values report asUncaught: <value>.