Built-in Objects
<!-- doc-length-limit: 900 -->
For contributors adding or modifying built-in objects, and for script authors looking up available APIs.
Executive Summary#
- Core vs runtime registration —
TGocciaEnginealways registers core language built-ins (Math, Object, Array, String, Number, RegExp, JSON, Symbol, Set, Map, Promise, Temporal, ArrayBuffer, TypedArrays, Proxy, Reflect, Iterator, DisposableStack, etc.);Goccia.Runtimeprovides optional host/runtime globals (Console, JSON5, JSONL, TOML, YAML, CSV, TSV, Performance, TextEncoder/TextDecoder, URL, fetch, Headers, Response, SemVer) - Runtime opt-ins —
rgTestAssertions,rgBenchmark, andrgFFIare special-purpose runtime globals that are off by default - Adding new built-ins — See Adding Built-in Types for the step-by-step recipe
- Always-present globals —
globalThisandGoccianamespace are registered after all built-ins
GocciaScript provides a set of built-in global objects that mirror JavaScript's standard library. Core language built-ins are implemented as Pascal units and registered by the engine. Host/runtime globals live behind runtime extensions so binaries can import only the surface they need. Test assertions, benchmarks, and FFI are runtime-level opt-ins.
Registration System#
Core language built-ins (Math, Object, Array, Number, JSON, Symbol, Set, Map, WeakSet, WeakMap, Promise, Temporal, ArrayBuffer, Proxy, Reflect, etc.) are always registered unconditionally by the engine.
Runtime globals (Console, JSON5, JSONL, TOML, YAML, CSV, TSV, Performance, TextEncoder/TextDecoder, URL, fetch, Headers, Response, SemVer) are registered by TGocciaRuntime. Frontends such as GocciaScriptLoader, GocciaTestRunner, GocciaBenchmarkRunner, and GocciaREPL attach that runtime; GocciaScriptLoaderBare does not, and exposes only a CLI-local print(...args) helper.
Only three runtime globals are special-purpose opt-ins in TGocciaRuntimeGlobal:
TGocciaRuntimeGlobal = (
rgTestAssertions, // describe, test, expect (testing only)
rgBenchmark, // suite, bench, runBenchmarks (benchmarking only)
rgFFI // Foreign Function Interface
);The GocciaTestRunner adds rgTestAssertions, the GocciaBenchmarkRunner adds rgBenchmark, and FFI (rgFFI) requires the --unsafe-ffi CLI flag.
Adding a New Built-in#
See Adding a New Built-in Type for the complete step-by-step guide with code templates, GC considerations, and a checklist.
Available Built-ins#
Console (Goccia.Builtins.Console.pas)#
Implements the WHATWG Console Standard. Not implemented: console.dirxml, console.groupCollapsed, console.profile, console.profileEnd, console.timeStamp.
| Method | Description |
|---|---|
console.log(...args) | Output to stdout with space-separated values |
console.warn(...args) | Output with "Warning:" prefix |
console.error(...args) | Output with "Error:" prefix |
console.info(...args) | Output with "Info:" prefix |
console.debug(...args) | Output with "Debug:" prefix |
console.dir(obj) | Display object properties |
console.assert(condition, ...args) | Print if assertion fails |
console.count(label?) | Increment and print named counter |
console.countReset(label?) | Reset named counter |
console.time(label?) | Start a named timer |
console.timeEnd(label?) | Stop timer and print elapsed time |
console.timeLog(label?) | Print elapsed time without stopping timer |
console.clear() | No-op (placeholder for terminal clearing) |
console.group(label?) | Increase indentation level |
console.groupEnd() | Decrease indentation level |
console.trace(...args) | Print with "Trace:" prefix |
console.table(data) | Display data (formatted output) |
Output capture: The console supports an OutputCallback hook for capturing output programmatically (see Embedding — Console Output Capture).
Separately, the TGocciaCLIApplication-based frontends use LogCallback for --log=<file>, which writes every console call to the specified file in [method] line format while preserving normal stdout output.
Math (Goccia.Builtins.Math.pas)#
Implements the ECMAScript Math object. See MDN Math reference for the full API.
Full standard compliance — all standard constants and methods are available.
Extras:
| Method | Description |
|---|---|
Math.clamp(x, min, max) | Clamp to range (Stage 2 proposal-math-clamp) |
Math.f16round(x) | Nearest 16-bit float |
Math.sumPrecise(iterable) | Precise sum via Kahan-Babuska-Neumaier compensated summation. Throws TypeError for non-iterable or non-number elements. Empty iterable returns -0. Mixed ±Infinity returns NaN. |
Data Formats (JSON, JSON5, YAML, JSONL, CSV, TSV, TOML)#
See Data Format Built-ins for the complete JSON, JSON5, YAML, JSONL, CSV, TSV, and TOML API reference.
Object (Goccia.Builtins.GlobalObject.pas)#
Implements the ECMAScript Object. See MDN Object reference for the full API.
Full standard compliance — all standard static methods and prototype methods are available.
GocciaScript-specific behavior: Object.hasOwn supports class values and checks static properties (not private fields).
Array (Goccia.Builtins.GlobalArray.pas)#
Implements the ECMAScript Array. Not implemented: Array.prototype.reduceRight, Array.prototype.toLocaleString.
Static methods:
| Method | Description |
|---|---|
Array.isArray(value) | Check if value is an array |
Array.from(iterable, mapFn?) | Create array from iterable (array or string) with optional map |
Array.fromAsync(asyncItems [, mapfn [, thisArg]]) | Returns a Promise that resolves to an Array. Tries [Symbol.asyncIterator] first, falls back to [Symbol.iterator], then array-like. Each value is awaited (Promise-aware via synchronous microtask drain). |
Array.of(...items) | Create array from arguments |
Prototype methods (implemented directly on TGocciaArrayValue):
| Method | Description |
|---|---|
map(callback) | Transform each element |
filter(callback) | Filter elements by predicate |
reduce(callback, initial?) | Reduce to single value |
forEach(callback) | Execute callback for each element |
some(callback) | Test if any element passes |
every(callback) | Test if all elements pass |
flat(depth?) | Flatten nested arrays |
flatMap(callback) | Map then flatten one level |
find(callback) | Find first matching element |
findIndex(callback) | Find index of first match |
findLast(callback) | Find last matching element |
findLastIndex(callback) | Find index of last match |
indexOf(value, fromIndex?) | Find index of value |
lastIndexOf(value, fromIndex?) | Find last index of value |
includes(value, fromIndex?) | Check if array contains value |
join(separator?) | Join elements into string |
toString() | Returns comma-separated string (delegates to join()) |
concat(...arrays) | Concatenate arrays |
slice(start?, end?) | Extract a section |
push(...items) | Add to end (mutating) |
pop() | Remove from end (mutating) |
shift() | Remove from start (mutating) |
unshift(...items) | Add to start (mutating) |
sort(compareFn?) | Sort in place (mutating) |
splice(start, deleteCount?, ...items) | Add/remove elements (mutating) |
reverse() | Reverse in place (mutating) |
fill(value, start?, end?) | Fill with value (mutating) |
at(index) | Access element (supports negative index) |
toReversed() | Non-mutating reverse |
toSorted(compareFn?) | Non-mutating sort |
with(index, value) | Non-mutating element replacement |
copyWithin(target, start, end?) | Copy within array (mutating) |
toSpliced(start, deleteCount?, ...items) | Non-mutating splice |
values() | Returns an iterator over values |
keys() | Returns an iterator over indices |
entries() | Returns an iterator over [index, value] pairs |
[Symbol.iterator]() | Returns a values iterator (same as values()) |
Number (Goccia.Builtins.GlobalNumber.pas)#
Implements the ECMAScript Number. See MDN Number reference for the full API.
Full standard compliance — all standard static methods, constants, and prototype methods are available.
GocciaScript difference: parseInt, parseFloat, isNaN, and isFinite are only available as Number.* static methods — not as global functions. See language.md for the rationale.
BigInt (Goccia.Builtins.GlobalBigInt.pas)#
Implements ECMAScript BigInt (ES2020). See MDN BigInt reference for the full API.
Related: BigInt64Array and BigUint64Array are implemented — see Binary Data Built-ins.
String (Goccia.Builtins.GlobalString.pas)#
Implements the ECMAScript String.
String constructor available as String().
Static methods:
| Method | Description |
|---|---|
String.fromCharCode(...codes) | Create string from UTF-16 code units |
String.fromCodePoint(...codePoints) | Create string from Unicode code points |
String.raw(template, ...substitutions) | Create string from raw template strings (escape sequences not processed) |
String prototype methods are implemented on string values:
charAt, charCodeAt, codePointAt, indexOf, lastIndexOf, includes, startsWith, endsWith, slice, substring, toLowerCase, toUpperCase, toLocaleLowerCase, toLocaleUpperCase, trim, trimStart, trimEnd, repeat, replace, replaceAll, split, match, matchAll, search, padStart, padEnd, concat, at, localeCompare, normalize, isWellFormed, toWellFormed, [Symbol.iterator]
replace, replaceAll, split, match, matchAll, and search also honor custom objects implementing the corresponding Symbol.replace, Symbol.split, Symbol.match, Symbol.matchAll, or Symbol.search hooks.
[Symbol.iterator]() returns an iterator that yields individual characters.
RegExp (Goccia.Builtins.GlobalRegExp.pas)#
Implements the ECMAScript RegExp including modifiers, duplicate named groups, and RegExp.escape.
RegExp is available as both RegExp() and new RegExp(). Regex literals (/pattern/flags) are also supported in both interpreted and bytecode execution modes. Calling RegExp(existingRegExp) without new and without an explicit flags argument returns the original regex object; new RegExp(existingRegExp) clones it.
Supported flags: d, g, i, m, s, u, v, y
Constructor properties:
| Property | Description |
|---|---|
source | Normalized pattern source |
flags | Canonicalized flags string (sorted: dgimsuvy) |
lastIndex | Current match position for g/y regexes |
global | true when the g flag is present |
ignoreCase | true when the i flag is present |
multiline | true when the m flag is present |
dotAll | true when the s flag is present |
unicode | true when the u flag is present |
sticky | true when the y flag is present |
unicodeSets | true when the v flag is present |
hasIndices | true when the d flag is present |
Static methods:
| Method | Description |
|---|---|
escape(string) | Returns a string with all regex-significant characters escaped so the result can be safely interpolated into a pattern. Implements RegExp.escape. Syntax characters are backslash-escaped; ClassSet-reserved punctuators, whitespace, and line terminators are hex-encoded (\xHH / \uHHHH). A leading digit or ASCII letter is also hex-encoded to prevent ambiguity with backreferences. |
RegExp[Symbol.species] | Accessor returning the receiver constructor (this) for subclass-aware species lookup |
Prototype methods:
| Method | Description |
|---|---|
exec(string) | Returns a match array with capture groups, index, input, and groups, or null |
test(string) | Returns true if the regex matches |
toString() | Returns /pattern/flags |
[Symbol.match](string) | Matching hook used by String.prototype.match() |
[Symbol.matchAll](string) | Match-all hook used by String.prototype.matchAll() |
[Symbol.replace](string, replaceValue) | Replacement hook used by String.prototype.replace() and replaceAll() |
[Symbol.search](string) | Search hook used by String.prototype.search() |
[Symbol.split](string, limit?) | Split hook used by String.prototype.split() |
Behavior notes:
- Inline modifier groups (
(?ims-ims:...)) are supported per the RegExp Modifiers specification. Onlyi(ignoreCase),m(multiline), ands(dotAll) are valid modifier flags. The colon form is required — bare(?ims)without:is aSyntaxError. Duplicate flags and flags appearing in both enable and disable sections are rejected. Modifiers are scoped to the group body; outer flags are unaffected. - Named capture groups (
(?<name>...)) are supported. Match results include agroupsproperty (an object withnullprototype) mapping group names to matched strings. Non-participating named groups areundefined. When no named groups exist,groupsisundefined. - Duplicate named capture groups: the same group name may appear in different alternatives of a disjunction (
|). For example,/(?<year>\d{4})-\d{2}|\d{2}-(?<year>\d{4})/. Thegroupsproperty on the match result returns the value from whichever alternative participated; non-participating duplicates areundefined. Using the same name in the same alternative (where both groups could participate) is aSyntaxError. - Named backreferences (
\k<name>) reference a previously captured named group within the same pattern. With duplicate named capture groups,\k<name>resolves to the group with that name in the same alternative branch. - Replacement strings in
replace()andreplaceAll()support$$,$&, the pre-match token$followed by a backtick,$', numeric captures such as$1, and named group references$<name>for regex matches with named groups. An unmatched$<name>produces an empty string when named groups exist;$<without a closing>is literal. - When the replacer is a function and named groups are present, the
groupsobject is passed as the last argument afterinput. String.prototype.match,matchAll,replace,replaceAll,search, andsplitdispatch through the corresponding well-known symbol hooks, so custom protocol objects work as expected.matchAll()returns a lazy iterator that advances matches on demand per the specification.- The
uflag enables Unicode-aware pattern matching. Unicode property escapes (\p{Letter},\P{ASCII}, etc.) are expanded to equivalent character classes. Unicode code point escapes (\u{41},\u{1F600}) are converted to UTF-8 byte sequences. Supported properties:L/Letter,Lu/Uppercase_Letter,Ll/Lowercase_Letter,N/Number,Nd/Decimal_Number,P/Punctuation,S/Symbol,Z/Separator,Cc/Control,ASCII,ASCII_Hex_Digit,White_Space. Unsupported properties throwSyntaxError. Theuflag also disables TRegExpr's Russian charset extensions and enables correctAdvanceStringIndexfor multi-byte UTF-8 sequences. - The
vflag (Unicode sets) is accepted and exposed through.flagsand.unicodeSets. Theuandvflags are mutually exclusive. Full Unicode set notation and properties of strings in character classes are not yet implemented beyond basicuflag behavior. - The
dflag (indices) is accepted and exposed through.flagsand.hasIndices. Match indices are not yet populated.
Global Constants, Functions, and Error Constructors (Goccia.Builtins.Globals.pas)#
These core constants, functions, and error constructors are always registered (not flag-gated). Runtime extensions can add more globals or namespace properties.
Constants: undefined, NaN, Infinity, globalThis
globalThis is a const binding that holds a plain object populated with global scope bindings. It includes a self-referential globalThis property (globalThis.globalThis === globalThis). Runtime extensions and global-injection helpers call TGocciaEngine.RefreshGlobalThis after adding globals so enumeration and property access reflect the new bindings; the public refresh method delegates to the engine's internal global-object registration routine.
`Goccia` object:
A const global providing engine metadata and Goccia-owned utility APIs:
| Property | Type | Description |
|---|---|---|
version | string | Semver version from the latest git tag (e.g., "0.2.0"), or tag + -dev suffix if there are commits after the tag (e.g., "0.2.0-dev") |
commit | string | Short git commit hash (e.g., "a1b2c3d") |
build | object | Compile-time platform information (see below) |
semver | object | Runtime-provided SemVer 2.0.0 API namespace (see below) |
spec | object | ES specification features implemented by GocciaScript, keyed by year (e.g., "2015", "2025"). Each year maps to an array of { name, link } entries. |
proposal | object | TC39 proposals implemented by GocciaScript, keyed by stage (e.g., "stage-3", "stage-1"). Each stage maps to an array of { name, link } entries. |
shims | string[] | Names of registered shims (currently empty, infrastructure for future shim support) |
gc | function | Trigger manual garbage collection. Returns undefined. Also exposes read-only gc.bytesAllocated (approximate GC heap size in bytes) and gc.maxBytes (active ceiling; defaults to half of physical memory capped at 8 GB on 64-bit or 700 MB on 32-bit, overridable via --max-memory). Allocations exceeding the ceiling throw a RangeError. |
`Goccia.build`
Goccia.build exposes compile-time platform information, mirroring Deno.build:
| Property | Type | Description |
|---|---|---|
os | string | Operating system: "darwin", "linux", "windows", "freebsd", "netbsd", "openbsd", "android", "aix", "solaris", or "unknown" |
arch | string | Processor architecture: "x86_64", "aarch64", "x86", "arm", "powerpc64", "powerpc", or "unknown" |
date | string | Build date in YYYY-MM-DD format (e.g., "2026-04-20") |
`Goccia.semver`
Goccia.semver is provided by TGocciaRuntime; it is not part of the bare engine namespace. GocciaScriptLoaderBare exposes Goccia but does not expose Goccia.semver.
Goccia.semver exposes a SemVer 2.0.0 API modeled after the main node-semver export plus its documented module-group aliases:
| Property | Type | Description |
|---|---|---|
SEMVER_SPEC_VERSION | string | Always "2.0.0" |
RELEASE_TYPES | string[] | ["major", "premajor", "minor", "preminor", "patch", "prepatch", "prerelease"] |
SemVer | function | Constructor for parsed semantic versions |
Comparator | function | Constructor for comparator objects |
Range | function | Constructor for range objects |
classes | object | Aliases for SemVer, Comparator, and Range matching the documented node-semver class module groups |
functions | object | Aliases for the documented function-level exports (valid, clean, compare, inc, etc.) |
ranges | object | Aliases for the documented range helpers (gtr, ltr, maxSatisfying, valid, etc.) |
Top-level methods follow node-semver naming and nullability conventions. The currently exposed main-export surface is:
valid, clean, parse, inc, prerelease, major, minor, patch, intersects, gt, gte, lt, lte, eq, neq, cmp, compare, rcompare, compareBuild, compareLoose, diff, sort, rsort, validRange, satisfies, maxSatisfying, minSatisfying, minVersion, gtr, ltr, outside, simplifyRange, subset, toComparators, coerce.
The constructor-backed objects mirror the node-semver public fields and core instance methods:
| Constructor | Instance fields | Instance methods |
|---|---|---|
new Goccia.semver.SemVer(version, options?) | raw, version, major, minor, patch, prerelease, build, options, loose, includePrerelease | format(), toString(), compare(other), compareMain(other), comparePre(other), compareBuild(other), inc(releaseType, identifier?) |
new Goccia.semver.Comparator(comparator, options?) | operator, semver, value, options, loose | toString(), test(version), intersects(other, options?) |
new Goccia.semver.Range(range, options?) | raw, range, set, options, loose, includePrerelease | format(), toString(), test(version), intersects(other, options?) |
Global functions:
| Function | Description |
|---|---|
queueMicrotask(callback) | Enqueue a callback to run as a microtask. Throws TypeError if the argument is not callable. |
structuredClone(value) | Deep-clone a value using the structured clone algorithm. Handles objects, arrays, Map, Set, and circular references. Throws DOMException with name "DataCloneError" (code 25) for non-cloneable types (functions, symbols, WeakMap, WeakSet). |
btoa(data) | Encode a binary string (each character code ≤ U+00FF) to base64. Throws DOMException with name "InvalidCharacterError" (code 5) if any character code exceeds U+00FF. |
atob(data) | Decode a base64 string to a binary string. Uses WHATWG forgiving-base64-decode: strips ASCII whitespace, tolerates missing = padding. Throws DOMException with name "InvalidCharacterError" (code 5) for invalid base64 input. |
encodeURI(uriString) | Encode a complete URI, preserving reserved characters (;/?:@&=+$,#) and unreserved characters. Multi-byte characters are UTF-8 encoded. Throws URIError for lone surrogates. |
decodeURI(encodedURI) | Decode a percent-encoded URI. Does not decode reserved characters (%3B, %2F, etc.). Throws URIError for malformed percent sequences or invalid UTF-8. |
encodeURIComponent(uriComponent) | Encode a URI component. Only unreserved characters (A-Z a-z 0-9 - _ . ! ~ * ' ( )) are preserved. Throws URIError for lone surrogates. |
decodeURIComponent(encodedURIComponent) | Decode a percent-encoded URI component. Decodes all percent sequences including reserved characters. Throws URIError for malformed percent sequences or invalid UTF-8. |
queueMicrotask shares the same microtask queue used by Promise reactions. Callbacks run after the current synchronous code completes but before the engine returns control. If a callback throws, the error is silently discarded and remaining microtasks still execute.
structuredClone creates a deep copy following the HTML spec's structured clone algorithm. Primitives are returned as-is. Objects, arrays, Maps, and Sets are recursively cloned. Circular references and shared references within the object graph are preserved (the same cloned object is reused). Non-serializable values (functions, symbols, WeakMaps, WeakSets) throw a DOMException with name: "DataCloneError" and code: 25, matching browser and Node.js behavior. Accessor properties (getters/setters) are read via the getter and the resulting value is cloned as a data property on the clone.
btoa encodes a string to base64 following the WHATWG HTML spec §8.3. Each character in the input must have a code point ≤ U+00FF (Latin-1 range); characters outside this range throw a DOMException with name "InvalidCharacterError" and legacy code 5. The input is interpreted as a byte sequence where each code point maps 1:1 to a byte value.
atob decodes a base64 string following the WHATWG forgiving-base64-decode algorithm. ASCII whitespace (U+0009, U+000A, U+000C, U+000D, U+0020) is stripped before decoding. Missing = padding is tolerated. Invalid characters or an invalid length (length mod 4 = 1 after cleanup) throw a DOMException with name "InvalidCharacterError" and legacy code 5. The decoded bytes are returned as a string where each byte becomes a character (Latin-1 interpretation).
encodeURI / decodeURI / encodeURIComponent / decodeURIComponent follow the ECMA-262 URI handling specification. The shared encoding/decoding logic lives in Goccia.URI.pas and is also used by import.meta.url for file-path percent-encoding. Multi-byte Unicode characters are encoded as UTF-8 octets, each percent-encoded individually (e.g., encodeURIComponent("中") → %E4%B8%AD). Lone surrogates (U+D800–U+DFFF) throw URIError. Decoding validates UTF-8 well-formedness: overlong encodings, truncated sequences, and code points above U+10FFFF all throw URIError. decodeURI re-emits reserved characters as uppercase percent-encoded sequences even when the input uses lowercase hex digits (e.g., %2f → %2F).
Error constructors: Error, TypeError, ReferenceError, RangeError, SyntaxError, URIError, AggregateError, DOMException
Prototype chain: All error types follow the standard prototype hierarchy. TypeError.prototype, RangeError.prototype, etc. inherit from Error.prototype. This means new TypeError("msg") instanceof TypeError is true AND new TypeError("msg") instanceof Error is true. Cross-type checks return false (e.g., new TypeError("msg") instanceof RangeError is false).
Runtime errors: Errors thrown internally by the engine (e.g., TypeError from accessing a property on null/undefined, or RangeError from invalid ArrayBuffer length) have the same prototype chain as user-constructed errors. This means instanceof checks work correctly in catch blocks:
try { null.x; } catch (e) {
e instanceof TypeError; // true
e instanceof Error; // true
}Static methods:
| Method | Description |
|---|---|
Error.isError(arg) | Returns true if arg is an Error instance (has [[ErrorData]] internal slot), false otherwise |
All error constructors accept an optional second argument options with a cause property. AggregateError takes (errors, message, options?) where errors is an array of error objects. DOMException takes (message?, name?) where name defaults to "Error" — the code property is automatically set from the legacy error code mapping (e.g., "DataCloneError" → 25).
Each creates an error object with name, message, and stack properties. The stack property is a formatted string with the following structure:
ErrorName: message
at functionName (filePath:line:col)
at outerFunction (filePath:line:col)Iterator (Goccia.Values.IteratorValue.pas, Iterator.Concrete.pas, Iterator.Lazy.pas, Iterator.Concat.pas, Iterator.Generic.pas)#
Implements the ECMAScript Iterator Helpers, Iterator Sequencing (Iterator.concat), and the Stage 3 Joint Iteration proposal (Iterator.zip).
All built-in iterators (Array, String, Map, Set) share a common Iterator.prototype with helper methods per the ECMAScript Iterator Helpers proposal:
| Method | Description |
|---|---|
iter.next() | Returns {value, done} — advances the iterator |
iter[Symbol.iterator]() | Returns iter itself (iterators are iterable) |
iter.map(callback) | Returns a new iterator with mapped values |
iter.filter(callback) | Returns a new iterator with filtered values |
iter.take(n) | Returns a new iterator with the first n values |
iter.drop(n) | Returns a new iterator skipping the first n values |
iter.flatMap(callback) | Map and flatten one level |
iter.forEach(callback) | Execute callback for each value |
iter.reduce(callback, initial?) | Reduce to single value |
iter.toArray() | Collect remaining values into an array |
iter.some(callback) | Test if any value matches |
iter.every(callback) | Test if all values match |
iter.find(callback) | Find first matching value |
Lazy helpers: map, filter, take, drop, and flatMap return new lazy iterators that advance the source on-demand — they do not eagerly consume the underlying iterator. Consuming methods (forEach, reduce, toArray, some, every, find) do consume the iterator.
Iterators are consumed once — calling next() past the end returns {value: undefined, done: true} forever. Spread ([...iter]), destructuring, and Array.from() all consume iterators via the [Symbol.iterator] protocol.
User-defined iterables: Objects with a [Symbol.iterator]() method that returns a plain {next()} object are fully supported. They work with spread, destructuring, Array.from(), and Iterator.from().
Static methods:
| Method | Description |
|---|---|
Iterator.from(value) | Wrap an iterable, iterator, or {next()} object as a proper Iterator with helper methods |
Iterator.concat(...items) | Concatenate multiple iterables into a single lazy iterator (TC39 Iterator Sequencing). All arguments are validated upfront as iterables; iterators are opened lazily as each iterable is consumed. |
Iterator.zip(iterables, options?) | Combine multiple iterables into an iterator of arrays (TC39 Joint Iteration). iterables is an iterable of iterables. options.mode can be "shortest" (default), "longest", or "strict". In "longest" mode, options.padding (an iterable) provides fill values for exhausted iterables. |
Iterator.zipKeyed(iterables, options?) | Combine keyed iterables into an iterator of objects (TC39 Joint Iteration). iterables is an object whose values are iterables. Each yielded object has the same keys as the input. Same mode/padding options as zip, but padding is an object with matching keys. |
Iterator.prototype | The shared iterator prototype (accessible for inspection) |
Symbol (Goccia.Builtins.GlobalSymbol.pas)#
Implements ECMAScript Symbol. Symbols are unique, immutable primitive values used as property keys. Also includes Symbol.metadata (TC39 decorator metadata), Symbol.dispose, Symbol.asyncDispose (TC39 explicit resource management), and Symbol.customMatcher (Stage 1 TC39 pattern matching) beyond the base standard.
| Method/Property | Description |
|---|---|
Symbol(description?) | Create a new unique symbol |
Symbol.for(key) | Get/create a symbol in the global registry |
Symbol.keyFor(symbol) | Get the key for a global registry symbol (throws TypeError for non-symbol arguments) |
Symbol.iterator | Well-known symbol for iteration protocol |
Symbol.asyncIterator | Well-known symbol for async iteration protocol. Returns the singleton symbol. Used by for await...of and Array.fromAsync. Objects with a [Symbol.asyncIterator]() method are async iterables. |
Symbol.match | Well-known symbol for String.prototype.match() dispatch |
Symbol.matchAll | Well-known symbol for String.prototype.matchAll() dispatch |
Symbol.replace | Well-known symbol for String.prototype.replace() and replaceAll() dispatch |
Symbol.search | Well-known symbol for String.prototype.search() dispatch |
Symbol.split | Well-known symbol for String.prototype.split() dispatch |
Symbol.species | Well-known symbol for constructor species (behavioral: Array/Map/Promise/RegExp/Set constructors have default [Symbol.species] getter returning this; Array prototype methods use ArraySpeciesCreate for subclass-aware result construction) |
Symbol.hasInstance | Well-known symbol for instanceof behavior |
Symbol.toPrimitive | Well-known symbol for type conversion |
Symbol.toStringTag | Well-known symbol for Object.prototype.toString |
Symbol.isConcatSpreadable | Well-known symbol for Array.prototype.concat |
Symbol.metadata | Well-known symbol for decorator metadata (TC39 proposal-decorator-metadata) |
Symbol.customMatcher | Well-known symbol for Stage 1 pattern matching. Objects can define [Symbol.customMatcher](subject, hint) and return a truthy/falsy value for value-pattern matching. |
symbol.toString() | Returns "Symbol(description)" |
symbol.description | The description string, or undefined |
Symbols can be used as computed property keys:
const sym = Symbol("myKey");
const obj = { [sym]: "value" };
obj[sym]; // "value"Object.defineProperty and Object.getOwnPropertySymbols also support symbol keys. The in operator checks for symbol-keyed properties, including global registry symbols created via Symbol.for().
Prototype: Symbol.prototype is an object containing toString() and a description getter, matching ECMAScript semantics. All symbol instances share this prototype.
Coercion semantics: Implicit conversion of a symbol to string or number throws TypeError. Use String(symbol) or symbol.toString() for explicit string conversion. See value-system.md for details.
Set (Goccia.Builtins.GlobalSet.pas)#
Implements the ECMAScript Set including Set methods (union, intersection, difference, symmetricDifference, isSubsetOf, isSupersetOf, isDisjointFrom).
A collection of unique values with insertion-order iteration. Set operation methods accept either another Set or a set-like object with size, has(value), and keys().
| Method/Property | Description |
|---|---|
new Set(iterable?) | Create a new Set, optionally from an array |
set.add(value) | Add a value (returns the Set for chaining) |
set.has(value) | Check if value exists |
set.delete(value) | Remove a value (returns boolean) |
set.clear() | Remove all values |
set.size | Number of values |
set.forEach(callback) | Iterate over values |
set.values() | Returns an iterator over values |
set.keys() | Returns an iterator over values (same as values() for Set) |
set.entries() | Returns an iterator of [value, value] pairs (matches Map.entries() shape) |
set[Symbol.iterator]() | Returns a values iterator (same as values()) |
set.union(other) | Returns new Set with elements from both |
set.intersection(other) | Returns new Set with common elements |
set.difference(other) | Returns new Set with elements in this but not other |
set.symmetricDifference(other) | Returns new Set with elements in either but not both |
set.isSubsetOf(other) | Check if all elements are in other |
set.isSupersetOf(other) | Check if contains all elements of other |
set.isDisjointFrom(other) | Check if no common elements |
Sets are iterable: [...mySet] spreads the set's values into an array.
WeakSet (Goccia.Builtins.GlobalWeakSet.pas)#
Implements the ECMAScript WeakSet.
A weak collection of object and non-registered symbol values. Entries do not keep their values alive; they are removed by GC after the value becomes unreachable elsewhere.
| Method/Property | Description |
|---|---|
new WeakSet(iterable?) | Create a new WeakSet, optionally from an iterable of weakly held values |
weakSet.add(value) | Add an object or non-registered symbol value (returns the WeakSet for chaining) |
weakSet.has(value) | Check if value exists; returns false for invalid weak values |
weakSet.delete(value) | Remove a value; returns false for invalid weak values |
WeakSets intentionally do not expose size, clear, forEach, iteration, keys, values, or entries. Values must satisfy ECMAScript CanBeHeldWeakly: objects and non-registered symbols are accepted; primitives and Symbol.for() registry symbols throw from add() and construction.
Map (Goccia.Builtins.GlobalMap.pas)#
Implements the ECMAScript Map including Map.prototype.getOrInsert/getOrInsertComputed.
A collection of key-value pairs with insertion-order iteration. Any value (including objects) can be a key.
| Method/Property | Description |
|---|---|
new Map(entries?) | Create a new Map, optionally from [[key, value], ...] |
map.get(key) | Get value for key |
map.set(key, value) | Set a key-value pair (returns the Map for chaining) |
map.has(key) | Check if key exists |
map.delete(key) | Remove a key (returns boolean) |
map.clear() | Remove all entries |
map.size | Number of entries |
map.forEach(callback) | Iterate over entries |
map.keys() | Returns an iterator over keys |
map.values() | Returns an iterator over values |
map.entries() | Returns an iterator over [key, value] pairs |
map[Symbol.iterator]() | Returns an entries iterator (same as entries()) |
map.getOrInsert(key, default) | Return value for key if present; otherwise insert default and return it |
map.getOrInsertComputed(key, cb) | Return value for key if present; otherwise call cb(key), insert result, and return it |
Static methods:
| Method | Description |
|---|---|
Map.groupBy(iterable, callback) | Group elements into a Map by callback return value |
Maps are iterable: [...myMap] spreads the map into an array of [key, value] pairs.
WeakMap (Goccia.Builtins.GlobalWeakMap.pas)#
Implements the ECMAScript WeakMap including ES2026 WeakMap.prototype.getOrInsert and WeakMap.prototype.getOrInsertComputed.
A weak key-value collection where keys are objects or non-registered symbols. WeakMap entries do not keep keys alive. Values are traced only while their key is reachable from outside the WeakMap.
| Method/Property | Description |
|---|---|
new WeakMap(entries?) | Create a new WeakMap, optionally from an iterable of [key, value] pairs |
weakMap.get(key) | Get value for key; returns undefined for invalid weak keys |
weakMap.set(key, value) | Set an object or non-registered symbol key (returns the WeakMap for chaining) |
weakMap.has(key) | Check if key exists; returns false for invalid weak keys |
weakMap.delete(key) | Remove a key; returns false for invalid weak keys |
weakMap.getOrInsert(key, default) | Return value for key if present; otherwise insert default and return it |
weakMap.getOrInsertComputed(key, cb) | Return value for key if present; otherwise call cb(key), insert result, and return it |
WeakMaps intentionally do not expose size, clear, forEach, iteration, keys, values, or entries. Keys must satisfy ECMAScript CanBeHeldWeakly: objects and non-registered symbols are accepted; primitives and Symbol.for() registry symbols throw from set(), upsert methods, and construction.
Promise (Goccia.Builtins.GlobalPromise.pas, Goccia.Values.PromiseValue.pas)#
Implements the ECMAScript Promise including Promise.withResolvers() and Promise.try(). See MDN Promise reference for the standard API.
An implementation of ECMAScript Promises with a synchronous microtask queue. .then() callbacks are always deferred (never synchronous), matching spec behavior.
Constructor:
const p = new Promise((resolve, reject) => {
// executor runs synchronously
resolve(42);
});Prototype methods:
| Method | Description |
|---|---|
promise.then(onFulfilled?, onRejected?) | Attach fulfillment/rejection handlers. Returns a new Promise. |
promise.catch(onRejected) | Sugar for .then(undefined, onRejected) |
promise.finally(onFinally) | Runs callback regardless of outcome, preserves settlement value |
Static methods:
| Method | Description |
|---|---|
Promise.resolve(value) | Create a fulfilled Promise (returns value if already a Promise) |
Promise.reject(reason) | Create a rejected Promise |
Promise.all(iterable) | Resolve when all resolve; reject on first rejection |
Promise.allSettled(iterable) | Wait for all to settle; returns {status, value/reason} objects |
Promise.race(iterable) | Settle with first settled value |
Promise.any(iterable) | Resolve with first fulfillment; reject with AggregateError if all reject |
Promise.withResolvers() | Returns object with promise, resolve, reject |
Promise.try(callback) | Execute callback, wrap result or error in Promise |
Promise[Symbol.species] | Accessor returning the receiver constructor (this) for subclass-aware species lookup |
Microtask queue: .then() callbacks are enqueued as microtasks and drained automatically after script execution completes — the script is one macrotask, and microtasks drain after it finishes, matching ECMAScript specification behavior. Thenable adoption (resolving a Promise with another Promise) is deferred via a microtask per the spec's PromiseResolveThenableJob, ensuring correct ordering relative to other microtasks. If the script throws an exception, pending microtasks are discarded via ClearQueue in a finally block, preventing stale callbacks from leaking into subsequent executions. The test framework also drains microtasks after each test callback, so tests can return a Promise and place assertions inside .then() handlers. The benchmark runner drains after each measurement round.
Async test pattern:
test("async test", () => {
return Promise.resolve(42).then((v) => {
expect(v).toBe(42);
});
});If a test returns a rejected Promise, the test framework automatically fails the test with the rejection reason.
Thenable adoption: Resolving a Promise with another Promise causes it to adopt the inner Promise's state. Resolving a Promise with itself throws a TypeError ("Chaining cycle detected for promise"), matching ECMAScript spec behavior.
Error validation: Static combinator methods (Promise.all, Promise.allSettled, Promise.race, Promise.any) accept any iterable argument (arrays, strings, Sets, Maps). Non-iterable arguments (numbers, booleans, null, undefined, plain objects) cause the returned Promise to reject with a TypeError, matching ECMAScript spec behavior where the rejection is asynchronous rather than a synchronous throw.
Chaining and error recovery:
Promise.resolve(1)
.then((v) => v + 1) // 2
.then((v) => { throw "err"; })
.catch((e) => "recovered") // "recovered"
.then((v) => v); // "recovered"Performance (Goccia.Builtins.Performance.pas)#
performance is exposed as a global Performance instance, not as a plain namespace object. The global Performance interface object is also exposed, with Performance.prototype === Object.getPrototypeOf(performance). now(), toJSON(), timeOrigin, and Symbol.toStringTag live on the shared prototype.
Core High Resolution Time API:
| Member | Description |
|---|---|
performance.now() | Monotonic elapsed time in milliseconds since the engine's time origin |
performance.timeOrigin | Unix epoch timestamp in milliseconds for the engine's time origin |
performance.toJSON() | Returns { timeOrigin } |
performance[Symbol.toStringTag] | "Performance" |
performance.now() uses TimingUtils.GetNanoseconds, so wall-clock changes do not affect it. performance.timeOrigin is captured once from TimingUtils.GetEpochNanoseconds when the built-in is created.
Performance() and new Performance() both throw TypeError ("Illegal constructor"), matching the web platform's non-constructible interface object behavior.
Temporal#
See Temporal Built-ins for the complete Temporal API reference (PlainDate, PlainTime, PlainDateTime, Duration, Instant, ZonedDateTime, and more).
Binary Data (ArrayBuffer, SharedArrayBuffer, TypedArrays)#
See Binary Data Built-ins for the complete ArrayBuffer, SharedArrayBuffer, and TypedArray API reference.
FFI (Goccia.Builtins.GlobalFFI.pas)#
Foreign Function Interface for calling native shared libraries. Only available when rgFFI is enabled in the runtime (not registered by default).
FFI global object:
| Method/Property | Description |
|---|---|
FFI.open(path) | Open a dynamic library, returns an FFILibrary |
FFI.nullptr | Singleton null pointer value |
FFI.suffix | Platform library suffix (.dylib, .so, .dll) |
FFILibrary methods:
| Method/Property | Description |
|---|---|
library.bind(funcName, signature) | Bind a native function. signature is { args: ['i32', ...], returns: 'i32' }. Returns a callable function. |
library.symbol(name) | Get raw pointer to a named symbol |
library.close() | Unload the library |
library.path | Full path to the loaded library |
library.closed | Whether the library has been closed |
FFIPointer properties:
| Property | Description |
|---|---|
ptr.address | Numeric address |
ptr.isNull | Whether pointer is null |
Supported FFI types: i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, pointer, cstring, bool, void (return only). i64/u64 are not available on i386. Max 8 arguments per function. Pointer arguments accept FFIPointer, ArrayBuffer, SharedArrayBuffer, TypedArray, or null.
Test Assertions (Goccia.Builtins.TestingLibrary.pas)#
Only available when rgTestAssertions is enabled in the runtime.
Test structure:
describe("group name", () => {
test("test name", () => {
expect(value).toBe(expected);
});
});Functions: describe, describe.skip, describe.skipIf, describe.runIf, describe.only, describe.each, test, it (alias for test), test.skip, test.skipIf, test.runIf, test.only, it.only, test.each, test.todo, beforeAll, beforeEach, afterEach, afterAll
Vitest-style structure helpers:
beforeAll(fn)/afterAll(fn)run once per suite around that suite's testsbeforeEach(fn)/afterEach(fn)are suite-scoped and inherited by nested suitestest.each(table)(name, fn)expands one test per table row and passes row values as callback argumentsdescribe.each(table)(name, fn)expands one suite per table row and passes row values as callback argumentstest.only(...),it.only(...), anddescribe.only(...)focus execution to the selected tests/suitestest.todo(name)registers a placeholder test that is reported as skipped but never executed
Matchers:
| Matcher | Description |
|---|---|
.toBe(expected) | Strict equality (===) |
.toEqual(expected) | Deep equality |
.toStrictEqual(expected) | Deep equality alias for Vitest compatibility |
.toBeNull() | Is null |
.toBeNaN() | Is NaN |
.toBeUndefined() | Is undefined |
.toBeDefined() | Is not undefined |
.toBeTruthy() | Truthy value |
.toBeFalsy() | Falsy value |
.toBeGreaterThan(n) | Greater than |
.toBeLessThan(n) | Less than |
.toContain(item) | Array/Set element or string substring |
.toContainEqual(item) | Deep-equal array element |
.toMatch(stringOrRegExp) | String substring or regular expression match |
.toMatchObject(obj) | Partial recursive object/subset match |
.toBeInstanceOf(class) | instanceof check |
.toHaveLength(n) | Length check |
.toHaveProperty(name) | Property exists on an object. Non-object values always fail; negated (not.toHaveProperty) on non-objects passes. |
.toThrow(ErrorType?) | Throws an error (optionally checks error constructor) |
.toBeCloseTo(n, digits?) | Approximate equality |
All matchers support .not negation: expect(value).not.toBe(wrong).
.toMatch() accepts either a string substring or a RegExp object. Regex matches ignore the regex's current lastIndex, matching Jest/Vitest-style assertion ergonomics.
Benchmark (Goccia.Builtins.Benchmark.pas)#
Only available when rgBenchmark is enabled in the runtime (used by the GocciaBenchmarkRunner). See benchmarks.md for usage, output formats, and CI integration.
Benchmark structure:
suite("group name", () => {
bench("benchmark name", () => {
// Code to benchmark — called many times during measurement
someOperation();
});
});Functions:
| Function | Description |
|---|---|
suite(name, fn) | Group benchmarks. Executes fn immediately to register bench entries. |
bench(name, fn) | Register a benchmark function. Called repeatedly during calibration and measurement. |
runBenchmarks() | Execute all registered benchmarks and return results. GocciaBenchmarkRunner calls this automatically after benchmark files register suites. |
Result object (returned by runBenchmarks()):
Each benchmark result includes: name, suite, opsPerSec, meanMs, iterations, totalMs, variancePercentage, and optionally error.
Proxy (Goccia.Builtins.GlobalProxy.pas, Goccia.Values.ProxyValue.pas)#
Implements the ECMAScript Proxy. See MDN Proxy reference for the full API.
GocciaScript differences: None -- all 13 handler traps are supported with full invariant enforcement. Both string and symbol property keys work. Proxy.revocable() is supported.
Reflect (Goccia.Builtins.GlobalReflect.pas)#
Implements the ECMAScript Reflect. See MDN Reflect reference for the full API.
GocciaScript differences: None -- all 13 Reflect methods are supported with both string and symbol property keys.
TextEncoder (Goccia.Builtins.GlobalTextEncoder.pas)#
Implements the Encoding Standard TextEncoder. See MDN TextEncoder reference for the full API.
GocciaScript differences: None -- full standard compliance (UTF-8 only, with encode and encodeInto).
TextDecoder (Goccia.Builtins.GlobalTextDecoder.pas)#
Implements the Encoding Standard TextDecoder. See MDN TextDecoder reference for the full API.
GocciaScript differences: Only "utf-8" encoding is supported. The fatal and ignoreBOM options are accepted.
URL (Goccia.Builtins.GlobalURL.pas)#
Implements the WHATWG URL Standard. See MDN URL reference for the full API.
GocciaScript differences: None -- full standard compliance.
URLSearchParams (Goccia.Values.URLSearchParamsValue.pas)#
Implements the WHATWG URLSearchParams. See MDN URLSearchParams reference for the full API.
GocciaScript differences: None -- full standard compliance.
fetch (Goccia.Builtins.GlobalFetch.pas)#
Implements a subset of the WHATWG Fetch Standard. Only GET and HEAD methods are supported; other methods throw TypeError.
| Function / Property | Description |
|---|---|
fetch(url, options?) | Perform an HTTP request, returns Promise<Response> |
The options object supports method ("GET" or "HEAD") and headers (plain object or Headers instance). Redirects (301/302/303/307/308) are followed automatically up to 20 hops. HTTPS uses the platform TLS backend: SecureTransport on macOS, SChannel on Windows, and OpenSSL on Linux. macOS and Windows builds do not require OpenSSL libraries for HTTPS; Linux supports OpenSSL 3 runtime-only installs as well as compatible older OpenSSL library names.
Allowed hosts — fetch requires an explicit allowlist of hostnames. Without --allowed-host or an "allowed-hosts" entry in goccia.json, any call to fetch throws TypeError. Add one or more allowed hosts via CLI or config:
./build/GocciaScriptLoader example.js --allowed-host=api.example.com --allowed-host=cdn.example.com{ "allowed-hosts": ["api.example.com", "cdn.example.com"] }Host matching is case-insensitive and ignores port, path, and userinfo. Only the hostname portion of the URL is checked.
GocciaScript differences: GocciaScript implements a focused subset of fetch:
- HTTP methods: only
GETandHEADare supported. - Absent features: no
Requestobject,AbortSignal, streaming body, or CORS. - Runtime behavior: requests run on fetch-specific background workers and settle their Promise on the owning runtime thread.
await fetch(...)still synchronously waits by pumping fetch completions. - Concurrency cap: each runtime caps active fetch workers at 16; additional calls reject their returned Promise with
TypeErroruntil a worker finishes. - Configuration: requires
--allowed-hostor an"allowed-hosts"entry ingoccia.json.
Headers (Goccia.Values.HeadersValue.pas)#
Implements the WHATWG Fetch Headers interface.
| Method / Property | Description |
|---|---|
new Headers() | Create empty headers |
new Headers(object) | Create from plain object or another Headers |
headers.get(name) | Get header value (case-insensitive), or null |
headers.has(name) | Check if header exists (case-insensitive) |
headers.forEach(callback) | Iterate entries as callback(value, name, headers) |
headers.entries() | Iterator of [name, value] pairs |
headers.keys() | Iterator of header names |
headers.values() | Iterator of header values |
headers[Symbol.iterator]() | Same as entries() |
GocciaScript differences: Read-only on Response headers. No append, set, or delete mutations.
Response (Goccia.Values.ResponseValue.pas)#
Implements the WHATWG Fetch Response interface.
| Method / Property | Description |
|---|---|
response.status | HTTP status code (e.g. 200) |
response.statusText | HTTP status text (e.g. "OK") |
response.ok | true if status is 200–299 |
response.url | Final URL after redirects |
response.headers | Headers object |
response.type | Always "basic" |
response.redirected | true if any redirect was followed |
response.bodyUsed | true after a body method is called |
response.text() | Returns Promise<string> (UTF-8 decoded body) |
response.json() | Returns Promise<any> (parsed JSON body) |
response.arrayBuffer() | Returns Promise<ArrayBuffer> (raw bytes) |
GocciaScript differences: No Response.body (ReadableStream), blob(), formData(), or clone(). Body is fully buffered. Each body method can only be called once.
DisposableStack / AsyncDisposableStack (Goccia.Builtins.DisposableStack.pas)#
Implements Explicit Resource Management. See MDN DisposableStack reference for the full API.
GocciaScript differences: None -- full proposal compliance. Both DisposableStack (sync) and AsyncDisposableStack (async) are supported. SuppressedError is thrown when both the block body and a disposer throw, with error (body error) and suppressed (dispose error) properties.