value

package
v0.0.0-...-f725ab5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 34 Imported by: 0

Documentation

Overview

Package value is bento's shared value model: the Go types that represent JavaScript values on both the compiled (typed) and interpreted (dynamic) sides, so a value computed by lowered Go and a value computed by the engine are the same object. It implements 10_value_model.md.

This file owns the string type. JavaScript strings are sequences of UTF-16 code units, and Go strings are UTF-8 byte sequences, so the two do not line up: a JavaScript string can hold a lone surrogate that is not valid Unicode and cannot round-trip through UTF-8. So a lowered `string` is not a Go string; it is a BStr, a UTF-16 string with a UTF-8 fast path for the common case where the text is valid UTF-8 that never needs the code-unit view (05_type_lowering section 5, 10_value_model section 5.4).

Index

Constants

View Source
const (
	MathE      = 2.718281828459045  // Math.E, Euler's number
	MathLN10   = 2.302585092994046  // Math.LN10, the natural log of 10
	MathLN2    = 0.6931471805599453 // Math.LN2, the natural log of 2
	MathLOG10E = 0.4342944819032518 // Math.LOG10E, the base-10 log of e
	MathLOG2E  = 1.4426950408889634 // Math.LOG2E, the base-2 log of e
	MathPI     = 3.141592653589793  // Math.PI
	MathSQRT12 = 0.7071067811865476 // Math.SQRT1_2, the square root of one half
	MathSQRT2  = 1.4142135623730951 // Math.SQRT2, the square root of two
)

The Math constants. Go's math package has most of these, but the derived ones (Log2E as 1/Ln2, for instance) are defined by a constant expression rather than a literal, so pinning the exact ECMAScript double here keeps them independent of how Go chose to spell its own.

View Source
const (
	NumberEpsilon        float64 = 2.220446049250313e-16  // Number.EPSILON, 2^-52, the gap above 1
	NumberMaxSafeInteger float64 = 9007199254740991       // Number.MAX_SAFE_INTEGER, 2^53 - 1
	NumberMinSafeInteger float64 = -9007199254740991      // Number.MIN_SAFE_INTEGER
	NumberMaxValue       float64 = 1.7976931348623157e308 // Number.MAX_VALUE, the largest finite double
	NumberMinValue       float64 = 5e-324                 // Number.MIN_VALUE, the smallest positive subnormal
)

The finite Number constants. Every one is a JavaScript Number, an IEEE-754 double, so each is typed float64 explicitly. MAX_SAFE_INTEGER and MIN_SAFE_INTEGER are whole numbers, and an untyped integer constant defaults to int when it lands in a `:=`, so `const n = Number.MAX_SAFE_INTEGER` would otherwise bind an int-typed Go var and refuse to flow into a float64 parameter (value.Some[float64], NewDuration). Typing them float64 keeps the JS model, that all five are the same kind of number.

Variables

View Source
var (
	Undefined = Value{/* contains filtered or unexported fields */}
	Null      = Value{/* contains filtered or unexported fields */}
	True      = Value{/* contains filtered or unexported fields */}
	False     = Value{/* contains filtered or unexported fields */}
)

The singletons. undefined, null, and the two booleans carry no reference, so they are cheap to return and to compare.

Functions

func AsyncGenAwait

func AsyncGenAwait[Y, X any](co *AsyncGenCo[Y], p *Promise[X]) X

AsyncGenAwait suspends an async generator body at an await until p settles, then returns its fulfilled value or raises its rejection into the body. It parks the body with an await frame carrying p's type-erased subscriber, so the driver keeps the current pull pending and resumes the body once p settles. The settled value rides the resume as a boxed any and is asserted back to the promise's element type X, which the lowerer knows at the await site.

func AsyncGenAwaitValue

func AsyncGenAwaitValue[X, Y any](co *AsyncGenCo[Y], v X) X

AsyncGenAwaitValue awaits a plain, non-promise value inside an async generator body. JavaScript awaiting a non-thenable wraps it in a resolved promise and suspends for one microtask turn, so this resolves v and awaits that, taking the same park-and-resume path and one-turn delay a real await imposes. The awaited element type X leads the type parameter list so the lowerer can pin it explicitly while the coroutine's yield type Y is inferred from co, the same explicit-element crossing plain AwaitValue takes.

func AtomicAdd

func AtomicAdd(a AtomicView, index float64, value float64) float64

AtomicAdd adds value to the element and returns the previous element, the lowering of Atomics.add. The read, the add, and the write are one indivisible step in the spec; with one agent a plain read-modify-write is that step. The sum is stored through the element's coercion, so it wraps into the element's range exactly as a plain store would, and the returned previous value is the widened element from before the add.

func AtomicAnd

func AtomicAnd(a AtomicView, index float64, value float64) float64

AtomicAnd stores the bitwise AND of the element and value and returns the previous element, the lowering of Atomics.and. The operands are integer elements, so the bit op runs on their int64 forms, which hold every covered element width exactly, and the result stores through the element's coercion back into range.

func AtomicCompareExchange

func AtomicCompareExchange(a AtomicView, index float64, expected float64, replacement float64) float64

AtomicCompareExchange stores replacement only if the element equals expected and returns the previous element either way, the lowering of Atomics.compareExchange. The comparison is against the element representation, so expected is coerced to the element's store form before the compare, matching the spec's byte-equal check; the returned value is the element from before any store.

func AtomicExchange

func AtomicExchange(a AtomicView, index float64, value float64) float64

AtomicExchange stores value and returns the previous element, the lowering of Atomics.exchange: an unconditional swap whose returned value is the element from before the store.

func AtomicIsLockFree

func AtomicIsLockFree(size float64) bool

AtomicIsLockFree reports whether an atomic operation on an element of the given byte size is lock-free, the lowering of Atomics.isLockFree. A size of 1, 2, 4, or 8 bytes is lock-free on the platforms bento targets, matching what a modern engine reports; any other size is not.

func AtomicLoad

func AtomicLoad(a AtomicView, index float64) float64

AtomicLoad reads the element at the index, the lowering of Atomics.load. In a single agent the read is already indivisible, so it is the same widened element At reads, after the bounds check the spec runs first.

func AtomicNotify

func AtomicNotify(a AtomicView, index float64, count ...float64) float64

AtomicNotify wakes up to count agents waiting on the index and returns the number woken, the lowering of Atomics.notify. In a single agent there is never a waiter to wake, since the one agent that could wait is the one calling notify, so it always wakes zero. The index is bounds-checked the same way the read-modify-write path checks it.

func AtomicOr

func AtomicOr(a AtomicView, index float64, value float64) float64

AtomicOr stores the bitwise OR of the element and value and returns the previous element, the lowering of Atomics.or, the same integer read-modify-write as AtomicAnd.

func AtomicPause

func AtomicPause(iterations ...float64)

AtomicPause is a hint to the processor that the agent is in a spin-wait loop, the lowering of Atomics.pause. It has no observable effect on program state and returns undefined; with one agent there is no contention to back off from, so it is a no-op.

func AtomicStore

func AtomicStore(a AtomicView, index float64, value float64) float64

AtomicStore writes value at the index and returns it, the lowering of Atomics.store. The value runs through ToIntegerOrInfinity first, so a -0 normalizes to +0 and a fractional value truncates before it is both stored and returned, matching Object.is on the result. The spec returns that integer, not the wrapped element the store keeps, so a value outside the element's range reads back here as the integer given while the stored element wraps; the covered subset passes an in-range integer, for which the two agree.

func AtomicSub

func AtomicSub(a AtomicView, index float64, value float64) float64

AtomicSub subtracts value from the element and returns the previous element, the lowering of Atomics.sub, the same read-modify-write shape as AtomicAdd.

func AtomicXor

func AtomicXor(a AtomicView, index float64, value float64) float64

AtomicXor stores the bitwise XOR of the element and value and returns the previous element, the lowering of Atomics.xor, the same integer read-modify-write as AtomicAnd.

func Await

func Await[X any](co *AsyncCo, p *Promise[X]) X

Await suspends the async body at an await expression until p settles, then returns its fulfilled value or raises its rejection into the body. It registers a reaction on p that, when p settles, resumes the body one step; then it parks, handing control back to the driver. Because the reaction is scheduled as a microtask even when p has already settled, the code after an await always runs in a later turn, the ordering JavaScript fixes for await. The awaited value rides the resume as a boxed any and is asserted back to the promise's element type X, which the lowerer knows at the await site.

func AwaitValue

func AwaitValue[X any](co *AsyncCo, v X) X

AwaitValue awaits a plain, non-promise value. JavaScript awaiting a non-thenable wraps it in a resolved promise and suspends for one microtask turn before yielding it back, so AwaitValue resolves v into a promise and awaits that, taking the same suspend-and-resume path and the same one-turn delay a real await imposes.

func BigIntAsIntN

func BigIntAsIntN(bits float64, x *big.Int) *big.Int

BigIntAsIntN wraps a bigint to the signed two's-complement integer of the given bit width, the lowering of BigInt.asIntN(bits, x). It reads the unsigned wrap first, then folds the top half of the range down by one modulus so the result lands in [-2^(bits-1), 2^(bits-1)); asIntN(8, 255n) is -1n. A width of zero wraps everything to 0n.

func BigIntAsUintN

func BigIntAsUintN(bits float64, x *big.Int) *big.Int

BigIntAsUintN wraps a bigint to the unsigned integer of the given bit width, the lowering of BigInt.asUintN(bits, x). The result is x modulo 2^bits, taken as the Euclidean remainder so it lands in [0, 2^bits) whatever the sign of x. A width of zero wraps everything to 0n, and a non-negative x that already fits the width passes through without building the modulus.

func BigIntDiv

func BigIntDiv(x, y *big.Int) *big.Int

BigIntDiv computes x / y on bigints, the quotient truncated toward zero that BigInt division takes. A zero divisor throws the RangeError JavaScript raises rather than letting big.Int.Quo panic, so the error is catchable in a try the way the language means it: 1n / 0n throws, it does not crash the program.

func BigIntLsh

func BigIntLsh(x, n *big.Int) *big.Int

BigIntLsh computes x << n on bigints. A negative count shifts the other way, the JavaScript rule that makes x << -1n mean x >> 1n, and a shift that would build a result past the size cap throws the size RangeError.

func BigIntMustParse

func BigIntMustParse(s string) *big.Int

BigIntMustParse parses the decimal digits of a wide bigint literal, the form the lowering emits as a package-level var so a literal past int64 is parsed once at init and reused (05_type_lowering section 4). The digits come from the compiler, which already normalized radix prefixes and separators away, so a parse failure is a lowering bug and panics rather than throwing.

func BigIntPow

func BigIntPow(x, y *big.Int) *big.Int

BigIntPow computes x ** y on bigints. A negative exponent throws the RangeError JavaScript raises, since a bigint cannot hold a fraction, and an exponent that would build a result past the size cap throws the size RangeError rather than exhaust memory. The |x| <= 1 bases are exempt from the cap because their powers never grow.

func BigIntRem

func BigIntRem(x, y *big.Int) *big.Int

BigIntRem computes x % y on bigints, the remainder that keeps the sign of the dividend. A zero divisor throws the same RangeError division does, since the remainder is undefined there and big.Int.Rem would otherwise panic.

func BigIntRsh

func BigIntRsh(x, n *big.Int) *big.Int

BigIntRsh computes x >> n on bigints, the arithmetic (floor) shift JavaScript defines, so -7n >> 1n is -4n. A negative count shifts the other way.

func BigIntToBool

func BigIntToBool(b *big.Int) bool

BigIntToBool is the truthiness of a bigint, the lowering of Boolean(b) and a bigint in condition position: only 0n is false.

func BigIntToNumber

func BigIntToNumber(b *big.Int) float64

BigIntToNumber converts a bigint to a number, the lowering of Number(b). The conversion rounds to the nearest float64 the way JavaScript does, so a bigint past 2^53 loses its low bits and a bigint past the float64 range becomes an infinity; big.Float's round-to-nearest-even is exactly that rounding.

func BoolToBigInt

func BoolToBigInt(b bool) *big.Int

BoolToBigInt converts a boolean to a bigint, the lowering of BigInt(b): true is 1n and false is 0n.

func BoolToNumber

func BoolToNumber(b bool) float64

BoolToNumber returns the JavaScript Number(b) of a boolean, 1 for true and 0 for false, the ECMAScript ToNumber applied to a Boolean.

func ClearTimer

func ClearTimer(handle Value)

ClearTimer cancels the callback a timer id stands for, the runtime behind clearTimeout, clearInterval, and clearImmediate. One function backs all three because the recorded timer already knows which kind it is, so the three differ only in the handle they are documented to take. An id that names no live timer, whether because it was already cleared, already fired, or never was a timer id, is ignored rather than treated as an error, since clearing a finished timeout is normal in Node.

func Clz32

func Clz32(x float64) float64

Clz32 counts the leading zero bits of a number read as a 32-bit unsigned integer, the ECMAScript Math.clz32. The argument is coerced with ToUint32 first, so NaN, the infinities, and a fraction reduce the same way the bitwise operators reduce them, and then the count runs on the 32-bit value: zero has no set bit, so it counts the full 32, which bits.LeadingZeros32 returns directly.

func Clz32U

func Clz32U(u uint32) int32

Clz32U counts the leading zero bits of a value already held as a 32-bit unsigned integer, the integer-typed core of Clz32. Clz32 exists for the float64 value model, where its argument is a number that must run through ToUint32 first; Clz32U is what the lowerer emits once a local is specialized to int32 and the coercion is already done, so the leading-zero count is a single machine instruction with no float round trip. The two agree by construction: Clz32(x) is Clz32U(ToUint32(x)).

func ConsoleAssert

func ConsoleAssert(cond Value, args ...Value)

ConsoleAssert is console.assert, which is quiet when the condition holds and writes "Assertion failed" to standard error when it does not. It never throws, which is the whole difference between it and assert(): a failed console.assert reports and the program carries on. The condition arrives as a value and is read for its truthiness, since console.assert takes whatever it is given.

The message is built the way Node builds it, which takes three cases and not one. With nothing else passed the line is the bare prefix. With a string first, the prefix is glued onto it with a colon, so the string keeps its place as the format the arguments after it fill: console.assert(false, '%d x', 1) prints "Assertion failed: 1 x" rather than leaving the specifier standing. With anything else first, the prefix goes in front as its own argument, so the value is inspected the way a logged value is: console.assert(false, {a: 1}) prints "Assertion failed { a: 1 }", with no colon, since there is no message to introduce.

func ConsoleClear

func ConsoleClear()

ConsoleClear is console.clear. On a terminal it moves the cursor home and clears the screen below it, the two escape sequences Node writes; on anything else, a pipe or a file, it does nothing at all, because there is no screen to clear and Node writes nothing.

func ConsoleCount

func ConsoleCount(label Value)

ConsoleCount is console.count. It counts the calls made under a label and prints the label and the running total, which is how a program counts times through a path without writing the counter itself. An omitted label counts under "default", and any other value is counted under its string form, so console.count(null) and console.count('null') share a tally the way Node's do.

func ConsoleCountReset

func ConsoleCountReset(label Value)

ConsoleCountReset is console.countReset, which drops one label's tally so the next count under it starts at one again. A label that was never counted draws the warning Node prints, since resetting a counter that does not exist is almost always a typo in the label.

func ConsoleDir

func ConsoleDir(v Value)

ConsoleDir is console.dir, which writes one value's inspected form. It differs from console.log on a string, which log prints raw and dir prints quoted, so it is its own helper rather than log with one argument.

func ConsoleError

func ConsoleError(parts ...BStr)

ConsoleError is the standard-error companion of ConsoleLog, the lowering of console.error and console.warn, which Node writes to standard error with the same space-joined, newline-terminated shape.

func ConsoleGroup

func ConsoleGroup(parts ...BStr)

ConsoleGroup is console.group, which prints its arguments if it was given any and indents everything written after it by two spaces, until the matching groupEnd. Node's groupCollapsed is the same function, since a terminal has no way to collapse anything.

func ConsoleGroupEnd

func ConsoleGroupEnd()

ConsoleGroupEnd is console.groupEnd, which takes one level of indentation back off. At the outermost level it does nothing, rather than indent negatively.

func ConsoleLog

func ConsoleLog(parts ...BStr)

ConsoleLog writes one console.log line to standard output: the parts joined by a single space and terminated with a newline, the shape Node's console.log prints for a list of already-stringified arguments. The compiler stringifies each argument at lower time (a number through NumberToString, a boolean through BoolToString, a string as itself), so this only has to join and terminate, which keeps the byte path identical to what a hand-written Go program would do.

func ConsoleNoop

func ConsoleNoop(args ...Value)

ConsoleNoop is console.timeStamp, console.profile, and console.profileEnd, the three members that report to an attached inspector and write nothing on their own. A compiled program has no inspector to report to, so there is nothing for them to do, and Node's own output for a program that calls them is the same nothing. The arguments are taken rather than dropped at the call site so a call still evaluates what it was passed.

func ConsoleTime

func ConsoleTime(label Value)

ConsoleTime is console.time, which starts a timer under a label. A label already timing is left alone and draws a warning, the way Node refuses to restart a running timer rather than silently losing the first start.

func ConsoleTimeEnd

func ConsoleTimeEnd(label Value)

ConsoleTimeEnd is console.timeEnd, which prints how long the label's timer ran and stops it. A label with no timer draws a warning and prints nothing.

func ConsoleTimeLog

func ConsoleTimeLog(label Value, data ...Value)

ConsoleTimeLog is console.timeLog, which prints how long the label's timer has run so far and leaves it running, so a program can mark several points inside one span. Anything else passed is printed after the duration.

Node writes the line as log('%s: %s', label, duration, ...data), so the extra arguments go through the same format pass every console line does: the first of them can carry specifiers the ones after it fill. Handing the whole list to the formatter is what keeps that, rather than stringifying each on its own.

func DateNow

func DateNow() float64

DateNow is the current time value as a Number, the lowering of Date.now(). It is the same clock new Date() reads, handed back as the number rather than wrapped, since that is what the static gives.

func DateUTC

func DateUTC(args ...float64) float64

DateUTC is the time value a UTC calendar reading names, the lowering of Date.UTC. It is the same construction as the component constructor with the zone left out, and like Date.now it gives a Number rather than a Date.

func DeepEqual

func DeepEqual(a, b Value) bool

DeepEqual reports whether two values are deeply loosely equal, the comparison behind assert.deepEqual. Loosely means a primitive compares with ==, so 1 and "1" are equal, a null element matches an undefined one, and neither the prototype nor a symbol-keyed property is looked at.

func DeepStrictEqual

func DeepStrictEqual(a, b Value) bool

DeepStrictEqual reports whether two values are deeply strictly equal, the comparison behind util.isDeepStrictEqual and assert.deepStrictEqual. Strictly means every primitive compares with ===, with NaN equal to itself and 0 not equal to -0, and two objects must carry the same prototype as well as the same properties.

func DeepStrictEqualSkipPrototype

func DeepStrictEqualSkipPrototype(a, b Value) bool

DeepStrictEqualSkipPrototype is the strict comparison with the constructor check dropped, node's kStrictWithoutPrototypes. A program reaches it through assert's skipPrototype option, and assert itself uses it to compare two errors it built, so an error it raised from one place matches one raised from another. Everything else is the strict comparison: a primitive still compares with ===, and a symbol-keyed property still counts.

func Dispose

func Dispose(release func())

Dispose runs a using declaration's release at scope exit and threads the explicit-resource-management error semantics through Go's panic unwinding. It is deferred, so an error unwinding the scope (a throw from the block body or an earlier resource's release) is in flight when it runs. It recovers that pending throw, runs the release, and re-raises the result the protocol requires: a throw from the release wraps the pending throw in a SuppressedError, a clean release re-raises the pending throw unchanged, and with no pending throw a release throw propagates on its own. A pending panic that is not a JavaScript throw is a Go runtime fault, which propagates unchanged rather than fold into an error chain.

func DurationCompare

func DurationCompare(a, b *Duration, rel *PlainDate) float64

DurationCompare implements Temporal.Duration.compare. rel is the PlainDate the calendar units resolve against, or nil when no relativeTo was given. Without a reference neither operand may carry years, months, or weeks, else a RangeError, and each folds to a signed nanosecond count over a fixed 24-hour day; with a reference each resolves against the calendar to an endpoint. The result is the sign of the first span minus the second, -1, 0, or 1.

func EmitProcessEvent

func EmitProcessEvent(event string, args ...Value) bool

EmitProcessEvent runs every listener registered for an event, in registration order, and reports whether there was one. The listeners are copied first so a listener that registers another does not extend the batch in progress, which matches Node, where emit takes the listener array at the point of the emit.

func FinalizationRegister

func FinalizationRegister[Target any, T any](r *FinalizationRegistry[T], target *Target, held T, token any)

FinalizationRegister registers target with the registry, the lowering of registry.register(target, held, token). It is a free function rather than a method because it is generic over the target's own type: the registry is generic only over the held-value type T, while a target may be any object, so the target type arrives at the call site the lowerer emits. It wires target to runtime.AddCleanup with held as the argument and the registry's callback as the cleanup, then records the returned handle under token so unregister can stop it. A nil token records a registration no unregister can target, which matches passing no unregister token.

func Fround

func Fround(x float64) float64

Fround rounds a number to the nearest single-precision float and back, the ECMAScript Math.fround. A round trip through float32 is exactly that: the value is rounded to the nearest representable float32 with ties to even, then widened back to a double. NaN stays NaN, the infinities and the signed zeros pass through unchanged, and a magnitude past the float32 range becomes the matching infinity, all of which the float32 conversion already does.

func Greater

func Greater(a, b Value) bool

Greater implements a > b, which is b < a with the operands swapped.

func GreaterEqual

func GreaterEqual(a, b Value) bool

GreaterEqual implements a >= b, which holds exactly when a < b is false and not undefined, the mirror of LessEqual.

func HasProcessListener

func HasProcessListener(event string) bool

HasProcessListener reports whether any listener is registered for an event. The uncaught-error and unhandled-rejection reporters ask before printing, since a program that registered a handler for either has said it wants to deal with the condition itself rather than crash on it.

func HostedGlobalNames

func HostedGlobalNames() []string

HostedGlobalNames returns the hosted names sorted, for the global object to install and for a test to walk. Sorted rather than in map order because the install order is the order the names sit on the global object, and a program reading them back through getOwnPropertyNames should see the same list on every run of the same binary.

func HostsGlobal

func HostsGlobal(name string) bool

HostsGlobal reports whether bento has a value form for an ambient global. The lowerer asks before it emits GlobalValue, so the set of names the compiler will hand a program and the set the runtime can answer for are one list rather than two that drift.

func HypotN

func HypotN(nums ...float64) float64

HypotN returns the square root of the sum of squares of its arguments, Math.hypot, which takes any number of arguments rather than exactly two. The identity is +0, so Math.hypot() with no arguments is +0, and folding with math.Hypot carries the JavaScript rules for free: math.Hypot(0, x) is |x|, so Math.hypot(x) is the magnitude of x; a ±Infinity argument makes the result +Infinity even when another argument is NaN, matching the specification order that infinity wins over NaN; and the pairwise fold avoids the overflow a naive sum of squares would hit, since math.Hypot scales each step.

func Imul

func Imul(a, b float64) float64

Imul multiplies two numbers as 32-bit signed integers, the ECMAScript Math.imul, the one multiply that keeps only the low 32 bits rather than the full double product. Each operand is coerced with ToInt32, the product of two int32 values wraps modulo 2^32 in Go exactly as two's-complement multiplication requires, and the wrapped int32 widens back to a number.

func InOperator

func InOperator(key, obj Value) bool

InOperator implements the general in operator, key in obj, the property-existence check distinct from the discriminated-union tag test the lowerer folds a narrowing in to. The right operand must be an object: a string primitive carries length and index properties HasProperty would answer, but the language treats it as a non-object and throws, so only KindObject, KindArray, and KindFunc (a proxy is backed by one of these) pass. The key is coerced through ToPropertyKey: a symbol key is probed by identity along the prototype chain, and every other key by its property-key string, so a numeric key like 1 reads the "1" slot and a dynamic key reaches the same check a string key does. The existence probe climbs the prototype chain and sees a non-enumerable property, since HasProperty and hasSymChained both walk every own key.

func InstanceOf

func InstanceOf(v, ctor Value) bool

InstanceOf reports whether v was built by ctor, the runtime behind `v instanceof ctor`. It is the ordinary [[HasInstance]]: the constructor's current .prototype is looked up and v's prototype chain walked for it, so an object built before a prototype was replaced answers against the object it actually links to, which is what the language does.

A right-hand side that is not callable, and one whose .prototype is not an object, each throw a TypeError the way the spec rejects them. A Symbol.hasInstance method overriding the test is a later slice; nothing in the runtime installs one.

func InstantCompare

func InstantCompare(a, b *Instant) float64

InstantCompare implements Temporal.Instant.compare: -1, 0, or 1 as the first instant is earlier than, equal to, or later than the second, the sign of the big.Int comparison.

func IsArray

func IsArray(v Value) bool

IsArray reports whether v is a real array, the runtime brand check Array.isArray makes. It asks the tag, so it says true only for an array value and false for an array-like object, a typed array box, a string, or any other value, matching the exotic-array brand the spec tests rather than a duck-typed length probe. A Proxy is an array when its target is: the spec's IsArray reads through the [[ProxyTarget]] slot rather than the proxy's own kind, so a proxy over an array, or a proxy over such a proxy, brands as an array. A revoked proxy has no target to read and throws a TypeError, the way IsArray rejects it.

func IsBuiltinModule

func IsBuiltinModule(specifier string) bool

IsBuiltinModule reports whether a require specifier names a Node built-in the registry resolves, in either the bare or the node: form. The lowerer calls it to decide whether a require('<literal>') lowers to a registry lookup rather than to the throwing runtime require, so the built-in name set has one home, here.

func IsConstructor

func IsConstructor(v Value) bool

IsConstructor reports whether v is a value `new` can be applied to, which here means a function value built by NewCtor. A plain boxed callable is not one: it has a body but no [Construct], the same distinction JavaScript draws between an arrow function and a function declaration.

func IsSignalEvent

func IsSignalEvent(event string) bool

IsSignalEvent reports whether an event name is a signal. A signal name is upper case and starts with SIG, which is how Node's own emitter tells one from an ordinary event; whether the host actually has a signal by that name is a separate question, and one signals.go answers, since a program may name a signal this platform does not define and Node treats that as an ordinary event.

func IterEvery

func IterEvery(next func() IterResult, fn Value) bool

IterEvery drives the source until fn(value, index) is falsy, the terminal every. It returns false as soon as a value fails, pulling no further, and true only once the source is exhausted with all passing, so an empty source is true.

func IterSome

func IterSome(next func() IterResult, fn Value) bool

IterSome drives the source until fn(value, index) is truthy, the terminal some. It returns true as soon as a value passes, pulling no further, and false only once the source is exhausted with none passing, so an empty source is false.

func JSONGapNum

func JSONGapNum(space float64) string

JSONGapNum computes the indentation gap for a numeric space: that many spaces, floored through ToInteger and clamped to ten, and the empty gap for a space below one, matching the gap the specification's SerializeJSONProperty derives.

func JSONGapStr

func JSONGapStr(space BStr) string

JSONGapStr computes the indentation gap for a string space: the first ten code units of the string, and the empty gap for an empty string.

func Less

func Less(a, b Value) bool

Less implements a < b over two dynamic values.

func LessEqual

func LessEqual(a, b Value) bool

LessEqual implements a <= b, which holds exactly when b < a is false and not undefined: an operand that makes b < a undefined also makes a <= b false.

func LooseEquals

func LooseEquals(a, b Value) bool

LooseEquals implements a == b over two dynamic values.

func MathRandom

func MathRandom() float64

MathRandom is Math.random(): a float64 uniformly distributed in [0, 1). It draws from the math/rand/v2 top-level generator, which is seeded from the operating system at startup and is safe to call from any goroutine, so a lowered program needs no generator plumbing of its own. The [0, 1) range is exactly the range rand.Float64 and Math.random share, so no rescaling is needed.

func MaxN

func MaxN(nums ...float64) float64

MaxN returns the largest of its arguments, Math.max, the mirror of MinN. Its identity is -Infinity, so Math.max() with no arguments is -Infinity, and math.Max carries the same NaN propagation and signed-zero order, so Math.max(-0, +0) is +0.

func MinN

func MinN(nums ...float64) float64

MinN returns the smallest of its arguments, Math.min, which takes any number of arguments rather than exactly two. The identity is +Infinity, so Math.min() with no arguments is +Infinity, and folding with math.Min carries the JavaScript rules for free: math.Min propagates NaN (any NaN argument makes the result NaN) and orders the signed zeros so Math.min(-0, +0) is -0.

func NodeIsDeepStrictEqual

func NodeIsDeepStrictEqual(args ...Value) bool

NodeIsDeepStrictEqual is util.isDeepStrictEqual called with its own argument list. It is variadic for the reason the other util entry points are: the lowerer emits one boxed argument per source argument, and a call with a missing argument compares against undefined rather than failing to compile.

func NumberIsFinite

func NumberIsFinite(n float64) bool

NumberIsFinite reports whether n is a finite number, Number.isFinite: neither an infinity nor NaN. Again no coercion, since the argument is a number.

func NumberIsInteger

func NumberIsInteger(n float64) bool

NumberIsInteger reports whether n is an integer value, Number.isInteger: finite and equal to its own truncation. NaN and the infinities are not integers, which the finiteness test rules out before the truncation compare.

func NumberIsNaN

func NumberIsNaN(n float64) bool

NumberIsNaN reports whether n is the NaN value, Number.isNaN. Unlike the global isNaN it does no coercion, but the argument is already a number here, so it is just the NaN test. It is not the same as `n != n` written in Go source only in that it names the intent; the semantics are identical.

func NumberIsSafeInteger

func NumberIsSafeInteger(n float64) bool

NumberIsSafeInteger reports whether n is a safe integer, Number.isSafeInteger: an integer whose magnitude is at most 2^53 - 1, so it is the only double with its value and integer arithmetic on it is exact.

func NumberNaN

func NumberNaN() float64

NumberNaN is Number.NaN.

func NumberNegativeInfinity

func NumberNegativeInfinity() float64

NumberNegativeInfinity is Number.NEGATIVE_INFINITY.

func NumberPositiveInfinity

func NumberPositiveInfinity() float64

NumberPositiveInfinity is Number.POSITIVE_INFINITY.

func NumberSameValue

func NumberSameValue(a, b float64) bool

NumberSameValue reports whether two numbers are the same value under the SameValue algorithm, the number case of Object.is. It differs from the strict equality Go == gives at exactly the two points JavaScript's === also differs: two NaNs are the same value, where == calls them unequal, and +0 and -0 are distinct values, where == calls them equal. The sign-bit compare only decides the zero case, since for any two equal non-zero numbers the sign bits already agree, so a == b with matching sign bits is the same value, and two NaNs are caught first.

func NumberToBigInt

func NumberToBigInt(f float64) *big.Int

NumberToBigInt converts a number to a bigint, the lowering of BigInt(n). Only a finite integral number converts; a fractional value, NaN, or an infinity throws the RangeError JavaScript raises, because a bigint has no way to hold it. The conversion goes through big.Float so an integral number past int64 (1e21) still converts exactly.

func NumberToBool

func NumberToBool(x float64) bool

NumberToBool returns the JavaScript Boolean(x) of a number, the ECMAScript ToBoolean applied to a Number: false for +0, -0, and NaN, and true for every other value. The NaN guard is what a bare x != 0 would miss, since NaN compares unequal to zero.

func OSAvailableParallelism

func OSAvailableParallelism() float64

OSAvailableParallelism is os.availableParallelism(), the count of cores this process may run on, which is what a program sizes a worker pool by.

func OSFreemem

func OSFreemem() float64

OSFreemem is os.freemem(), the memory not currently in use, in bytes. It is measured on each call, since it is the one of these that moves while a program runs.

func OSTotalmem

func OSTotalmem() float64

OSTotalmem is os.totalmem(), the machine's physical memory in bytes.

func OSUptime

func OSUptime() float64

OSUptime is os.uptime(), the seconds since the machine booted.

func OnExit

func OnExit(fn Value)

OnExit registers a process 'exit' listener, the runtime behind process.on('exit', fn). It is the same registry every other process event uses (processevents.go), so a listener registered through the lowerer's static path and one registered through the process object itself run in the one registration order.

func OnProcessEvent

func OnProcessEvent(event string, fn Value)

OnProcessEvent registers a process listener, the runtime behind process.on(event, fn) for an event the lowerer read as a string literal. The listener is held as a value so a closure that captured its module's state runs with that state when the event fires.

func ParseDate

func ParseDate(s BStr) float64

ParseDate is the time value a string names, or NaN when the string names no date. It is the whole of Date.parse and the string half of the Date constructor.

func ParseFloat

func ParseFloat(s BStr) float64

ParseFloat returns the JavaScript parseFloat(s) of a string: the Number value of the longest leading substring that is a decimal literal, or NaN when no such prefix exists.

func ParseInt

func ParseInt(s BStr, radix float64) float64

ParseInt returns the JavaScript parseInt(s, radix) of a string. A radix of 0 stands for an omitted argument, which the specification treats identically to a radix of 0, so the compiler passes 0 when parseInt is called with one argument.

func PathIsAbsolute

func PathIsAbsolute(p BStr) bool

PathIsAbsolute is path.isAbsolute.

func PerformanceNow

func PerformanceNow() float64

PerformanceNow returns the number of milliseconds since the time origin, the lowering of performance.now(). It is a float64 with sub-millisecond resolution, matching the DOMHighResTimeStamp performance.now() returns in a browser and in Node, where the value is a fractional count of milliseconds rather than a whole number. Only differences between two readings are meaningful, so the absolute origin is an implementation detail; what matters is that every reading measures from the same monotonic start.

func PlainDateCompare

func PlainDateCompare(a, b *PlainDate) float64

PlainDateCompare implements Temporal.PlainDate.compare, the static comparator: -1 if a precedes b, 1 if a follows b, 0 if they fall on the same day.

func PlainDateTimeCompare

func PlainDateTimeCompare(a, b *PlainDateTime) float64

PlainDateTimeCompare implements Temporal.PlainDateTime.compare, the static comparator: -1 if a precedes b, 1 if a follows b, 0 if they are the same instant on the wall clock. It compares the dates first and falls to the times only when the dates are equal.

func PlainTimeCompare

func PlainTimeCompare(a, b *PlainTime) float64

PlainTimeCompare implements Temporal.PlainTime.compare, the static comparator: -1 if a precedes b, 1 if a follows b, 0 if they are the same time. It compares the fields from the most significant down, stopping at the first that differs.

func PlainYearMonthCompare

func PlainYearMonthCompare(a, b *PlainYearMonth) float64

PlainYearMonthCompare implements Temporal.PlainYearMonth.compare, the static comparator: -1 if a precedes b, 1 if a follows b, 0 if they are the same year-month.

func Pow

func Pow(base, exp float64) float64

Pow raises base to exponent, the ** operator and Math.pow. It is not math.Pow: ECMAScript's Number::exponentiate returns NaN in two cases where Go's math.Pow keeps the IEEE result of one. A NaN exponent is always NaN in JavaScript, but math.Pow(1, NaN) is 1 because math.Pow special-cases a base of one for every exponent. A base whose magnitude is one raised to an infinite exponent is NaN in JavaScript, where math.Pow(-1, +Inf) and math.Pow(1, -Inf) are both 1. Every other input agrees between the two, so those cases are handled here and the rest defers to math.Pow.

func ProcessListenerCount

func ProcessListenerCount(event Value) float64

ProcessListenerCount answers how many listeners an event has, the runtime behind process.listenerCount.

func QueueMicrotask

func QueueMicrotask(fn Value)

QueueMicrotask schedules fn on the microtask queue, the runtime behind the global queueMicrotask(fn). The callback is held as a value and invoked with no arguments when the queue drains, so a queueMicrotask callback and a promise then callback interleave in enqueue order, the ordering the language gives two microtasks. The compiled main drains the queue as part of its end-of-run checkpoint whenever the program used queueMicrotask or a promise.

func Reduce

func Reduce[T, A any](a *Array[T], f func(A, T) A, init A) A

Reduce folds the array left to right into a single accumulator, the lowering of Array.prototype.reduce called with an initial value. It is a free function rather than a method because the accumulator type A may differ from the element type T (numbers.reduce((acc, n) => acc + String(n), "") is a string over a number array), and a Go method cannot introduce the new type parameter A the way this function's second type argument does. The callback takes the accumulator and the element, the two-parameter shape reduce needs; the index and array arguments JavaScript also passes are a later slice. Starting from init, each element updates the accumulator in order, and an empty array returns init unchanged, matching JavaScript's reduce with an initial value.

func ReduceIndex

func ReduceIndex[T, A any](a *Array[T], f func(A, T, float64) A, init A) A

ReduceIndex is Reduce for a callback that also reads the element index, the (accumulator, element, index) shape JavaScript passes. It mirrors Reduce, handing the position as a float64 third argument, the Number the index parameter lowers to.

func ReduceRight

func ReduceRight[T, A any](a *Array[T], f func(A, T) A, init A) A

ReduceRight folds the array right to left into a single accumulator, the lowering of Array.prototype.reduceRight called with an initial value. Like Reduce it is a free function so the accumulator type A can differ from the element type T, which a method could not introduce. Starting from init, each element from the last to the first updates the accumulator, and an empty array returns init unchanged.

func ReduceRightIndex

func ReduceRightIndex[T, A any](a *Array[T], f func(A, T, float64) A, init A) A

ReduceRightIndex is ReduceRight for an (accumulator, element, index) callback, walking from the last element to the first and passing each element's own descending index as a float64.

func ReduceRightTypedArray

func ReduceRightTypedArray[T typedElem, A any](a *TypedArray[T], f func(A, float64) A, init A) A

ReduceRightTypedArray folds the view right to left into a single accumulator, the lowering of TypedArray.prototype.reduceRight called with an initial value. Like ReduceTypedArray it is a free function so the accumulator type A can differ from the element Number. Starting from init, each element from the last to the first updates the accumulator, and an empty view returns init unchanged.

func ReduceTypedArray

func ReduceTypedArray[T typedElem, A any](a *TypedArray[T], f func(A, float64) A, init A) A

ReduceTypedArray folds the view left to right into a single accumulator, the lowering of TypedArray.prototype.reduce called with an initial value. It is a free function rather than a method because the accumulator type A may differ from the Number the elements widen to, and a Go method cannot introduce the new type parameter A. Starting from init, each element updates the accumulator in order, and an empty view returns init unchanged.

func ReflectDefineProperty

func ReflectDefineProperty(target, key, descObj Value) bool

ReflectDefineProperty implements Reflect.defineProperty(target, key, descriptor): the [[DefineOwnProperty]] Object.defineProperty performs, returning whether the define succeeded instead of throwing on a define the invariants forbid. It reads the descriptor object, validates the change against the target's extensibility and the existing property's configurability, and applies it, reporting false for the same rejection Object.defineProperty turns into a TypeError.

func ReflectDeleteProperty

func ReflectDeleteProperty(target, key Value) bool

ReflectDeleteProperty implements Reflect.deleteProperty(target, key): the [[Delete]] the delete operator performs, returning whether the removal succeeded. A configurable or absent property removes and reports true; a non-configurable property survives and reports false.

func ReflectHas

func ReflectHas(target, key Value) bool

ReflectHas implements Reflect.has(target, key): the [[HasProperty]] the in operator performs, climbing the prototype chain so an inherited property reports true. A symbol key is probed by identity, a string or other key by its property-key string, matching how the target stores each.

func ReflectIsExtensible

func ReflectIsExtensible(target Value) bool

ReflectIsExtensible implements Reflect.isExtensible(target): the [[IsExtensible]] Object.isExtensible performs, reporting whether new own properties may be added. It throws the TypeError every Reflect method raises on a non-object target rather than coercing a primitive the way the Object form does.

func ReflectPreventExtensions

func ReflectPreventExtensions(target Value) bool

ReflectPreventExtensions implements Reflect.preventExtensions(target): the [[PreventExtensions]] Object.preventExtensions performs, marking the target closed to new own properties and reporting success, which for an ordinary object is always true. It throws the TypeError every Reflect method raises on a non-object target.

func ReflectSet

func ReflectSet(target, key, val Value) bool

ReflectSet implements Reflect.set(target, key, value): the ordinary [Set] with the receiver defaulting to the target, returning whether the write succeeded instead of throwing on a refused write the way a strict assignment would. The four-argument receiver form is a later slice, gated at lowering.

func ReflectSetPrototypeOf

func ReflectSetPrototypeOf(target, proto Value) bool

ReflectSetPrototypeOf implements Reflect.setPrototypeOf(target, proto): the [[SetPrototypeOf]] Object.setPrototypeOf performs, returning whether the write succeeded instead of throwing on a refused change. A non-object, non-null prototype throws a TypeError, as does a non-object target. Setting the prototype a non-extensible object already holds succeeds, while changing it to a different one is refused and reports false.

func RegExpSourceHasAnchor

func RegExpSourceHasAnchor(pattern string) bool

RegExpSourceHasAnchor reports whether a pattern uses a ^ or $ anchor or a \b or \B word boundary, the position assertions whose meaning depends on surrounding text. The lowerer consults it to keep String.prototype.split off a separator RE2 cannot host faithfully: split matches the separator anchored at each offset the way a sticky clone does, and slicing the subject at that offset would sever the left context such an assertion reads.

func RegisterClass

func RegisterClass(name string, sample any) bool

RegisterClass records that instances of the generated struct sample points at are instances of the JavaScript class called name, and returns true so the registration can ride a package-level var declaration rather than an init function. The lowerer emits one of these per class it renders.

The prototype is built here rather than on the first boxing so every instance of one class shares one prototype object however it is reached. That identity is what the strict deep comparison reads: two instances of P carry the same prototype pointer and compare as having the same constructor, while an instance of Q and a plain object, which carries no prototype at all, do not.

func RegisterClassCoercion

func RegisterClassCoercion(sample any, name string, fn func(any) Value) bool

RegisterClassCoercion records that instances of the struct sample points at answer the named coercion by calling fn, and returns true so the registration can ride a package-level var the way RegisterClass does. The lowerer emits one of these per class that writes a toString or a valueOf, with fn closing over the typed call and the boxing of what it returns, so nothing here has to know the class's Go signature.

A name that is neither is ignored rather than stored, which keeps the read path a two-way switch instead of a map lookup on every property miss.

func ReportUncaught

func ReportUncaught()

ReportUncaught is deferred at the program root to surface a throw that escaped every catch. It recovers the panic, and if the payload is a thrown JavaScript value it prints an uncaught-error line to standard error and exits non-zero, the way a runtime reports an unhandled exception. A payload that is not a thrown value is a Go runtime panic, a bug in the runtime rather than a program throw, so it is re-panicked to keep its original stack. A run that did not panic recovers nothing and returns, leaving a clean exit untouched.

A program that registered an uncaughtException listener has said it wants to deal with the escape itself, so the listeners run with the thrown value and the program leaves cleanly instead of crashing, which is what Node does. The exit listeners run after them, because the panic skipped the end of main where they would have run.

func ReportUnhandledRejections

func ReportUnhandledRejections()

ReportUnhandledRejections surfaces every promise that settled rejected and was never subscribed to, the unhandled-rejection path JavaScript runs after the microtask checkpoint. It prints each one to stderr in the shape Node uses and, if any exist, exits non-zero, so a test that asserts a rejection observes the crash rather than a false pass. The assembled main calls it once, right after the final microtask drain, so every reaction that could still consume a rejection has already run.

func RmSync

func RmSync(pathArg BStr, recursive, force bool)

RmSync removes the file or directory at path, the lowering of fs.rmSync with its recursive and force options. recursive removes a directory and everything under it, the RemoveAll semantics; without it only a single file or empty directory is removed, the Remove semantics, matching Node, which errors on a non-empty directory unless recursive is set. force suppresses the error a missing path would raise, exactly Node's force flag, so a cleanup that runs twice does not throw the second time; without force a missing path panics as a thrown error would. The compiler reads both flags from the options object at lower time, so they arrive here as plain booleans.

func Round

func Round(x float64) float64

Round rounds a number to the nearest integer, Math.round. It is not math.Round: JavaScript breaks a tie by rounding toward +Infinity (Math.round(2.5) is 3 and Math.round(-2.5) is -2), where Go's math.Round rounds a tie away from zero (math.Round(-2.5) is -3). Rounding down and then bumping when the fraction reaches one half gives the +Infinity tie-break directly, and it avoids the floor(x+0.5) trap where a value just under one half like 0.49999999999999994 adds up to 1.0 and rounds the wrong way. NaN and the infinities pass through. A result of zero keeps the sign of x, so Math.round(-0.4) stays -0 like the specification requires.

func RunBeforeExit

func RunBeforeExit()

RunBeforeExit fires the beforeExit event, the point Node reaches when the loop has drained and the process is about to leave but has not left yet. A listener may schedule more work, which is the whole reason the event exists, so the loop turns again after the listeners run and the event fires once more when that work is done. A program that scheduled nothing new leaves after one pass.

It is not called from process.exit, matching Node, which skips beforeExit entirely when the program asked to leave rather than ran out of things to do.

func RunEventLoop

func RunEventLoop()

RunEventLoop runs scheduled callbacks until nothing is left scheduled, the loop the assembled main enters after the synchronous body when the program used a timer. It opens with a microtask drain so a promise reaction the body queued runs before the first macrotask, the ordering the language gives, then turns the loop: due timers, then immediates, sleeping until the next deadline when neither has anything ready.

Running out of scheduled work is what ends the loop, which is when Node's process exits on its own. A program with a live interval it never clears therefore runs forever here exactly as it does under Node, rather than exiting early and losing the callbacks it asked for.

A signal that arrived is delivered at the top of a turn, ahead of the timers due in that same turn, which is where Node delivers one. A signal does not keep the loop turning on its own, again matching Node: a program whose only reason to stay is a listener for SIGINT has already left by the time the signal could arrive.

func RunExitCallbacks

func RunExitCallbacks()

RunExitCallbacks runs every registered 'exit' listener once, in registration order, the drain the compiled main appends as its final statement when the program registered any listener. It is what lets common.mustCall, which asserts on exit that a wrapped function ran the expected number of times, observe the run. The exit status is 0 here, the status a program that ran off the end of main leaves with; process.exit passes its own.

func RunExitCallbacksWithCode

func RunExitCallbacksWithCode(code int)

RunExitCallbacksWithCode runs the 'exit' listeners with the status the process is leaving with, which Node passes each listener as its one argument. A listener that declares no parameter ignores it, so the argument costs nothing where it is not wanted and is there for the common `process.on('exit', (code) => ...)` that asserts the program left cleanly.

func RunMicrotasks

func RunMicrotasks()

RunMicrotasks drains the microtask queue to completion, running each callback in the order it was enqueued. A callback may enqueue more (a then inside a then), so the loop re-reads the length each pass and runs until the queue is empty, the run-to-completion semantics of the microtask checkpoint. The assembled main calls it once at its end when the program minted any promise.

func SameValueZero

func SameValueZero(a, b Value) bool

SameValueZero implements the SameValueZero comparison, the key and member identity a Map and a Set use. It is Strict Equality with one difference: NaN is the same value as NaN, so a collection holds one NaN key however many times it is offered. The zeroes stay a single value under both, which float64 == already gives. Every other kind compares exactly as === does.

func SetImmediate

func SetImmediate(fn Value, args ...Value) float64

SetImmediate schedules fn to run in the next turn's check phase, the runtime behind the global setImmediate. It is not a zero-delay timeout: an immediate runs before any timer the same turn re-arms, and an immediate scheduled from inside an immediate waits for the following turn rather than running in the current batch, which is what keeps a self-rescheduling immediate from starving the timers.

func SetInterval

func SetInterval(fn Value, delay Value, args ...Value) float64

SetInterval schedules fn to run every delay milliseconds until it is cancelled, the runtime behind the global setInterval. It returns an id the same way setTimeout does; the difference is that the timer re-arms after each run, so a program that never clears it keeps the loop alive forever, as it does under Node.

func SetTimeout

func SetTimeout(fn Value, delay Value, args ...Value) float64

SetTimeout schedules fn to run once after delay milliseconds, the runtime behind the global setTimeout. Extra arguments are held and passed to the callback when it runs, the way Node forwards them. It returns the timer's id, the handle a program passes to clearTimeout to cancel the callback before it fires.

func Sign

func Sign(x float64) float64

Sign returns the sign of a number, Math.sign: 1 for a positive number, -1 for a negative one, and the argument itself for zero or NaN. Go has no math.Sign, and returning x for the zero and NaN cases is what keeps the signed zeros and NaN flowing through unchanged the way the specification asks.

func StaticBool

func StaticBool[T any](_ T, result bool) bool

StaticBool returns result and ignores operand, the lowering of a call whose answer the checker already knows at compile time but whose operand must still be evaluated and referenced. Array.isArray(x) on a statically typed x folds to true or false, yet dropping x would discard its side effects (Array.isArray(f()) must still call f) and leave a Go binding that x was the only use of unreferenced, so the emit passes x through here to keep it live while yielding the known result.

func StrictEquals

func StrictEquals(a, b Value) bool

StrictEquals implements the === operator over two dynamic values, the Strict Equality Comparison: different types are never equal, numbers compare as doubles (so NaN equals nothing and +0 equals -0, which Go's float64 == already does), strings compare by code unit, bigints by mathematical value, and the reference kinds by identity. undefined equals undefined and null equals null, each only itself.

func StringToBigInt

func StringToBigInt(s BStr) *big.Int

StringToBigInt converts a string to a bigint, the lowering of BigInt(s). It implements the ECMAScript StringToBigInt grammar: whitespace trims away, the empty remainder is 0n, a decimal form may carry one sign, and the 0x, 0o, and 0b radix prefixes are read unsigned. Anything else, a trailing character, a digit separator, or a sign on a prefixed form, throws the SyntaxError JavaScript raises, since unlike Number(s) there is no NaN to fall back to.

func StringToBool

func StringToBool(s BStr) bool

StringToBool returns the JavaScript Boolean(s) of a string, the ECMAScript ToBoolean applied to a String: true for any non-empty string and false only for the empty one. The content does not matter, so "0" and "false" are both true.

func StringToNumber

func StringToNumber(s BStr) float64

StringToNumber returns the JavaScript Number(s) of a string. It trims the ECMAScript whitespace, maps the empty result to +0, recognizes the radix-prefixed integer forms and the signed decimal (including Infinity), and returns NaN for anything that does not match the grammar.

func Throw

func Throw(e Thrown)

Throw raises a thrown value so an enclosing catch recovers it or the top-level reporter surfaces it. The payload is anything carrying the Thrown surface: the runtime's own *Error, or a program class whose thrown instances gained ErrorName and ErrorMessage in emission. It is a named entry point so every throw lowers to one call shape rather than an inline panic, which keeps the generated code readable and gives the runtime one place to evolve the throw path.

func TimerHasRef

func TimerHasRef(handle Value) bool

TimerHasRef reports whether a timer is refed, the runtime behind timeout.hasRef(). It reads the ref flag and nothing else, which is what Node's Timeout does: a timeout that has already fired or been cleared still answers true, because clearing a timer does not unref it. A timer this runtime has forgotten therefore answers true as well, and forgetting only ever happens to a refed one; see retireTimer.

func TimerRef

func TimerRef(handle Value) float64

TimerRef puts a timer back into the count that keeps the process alive, the runtime behind timeout.ref() and the undo of TimerUnref. A timer is refed when it is scheduled, so this only matters after an unref.

func TimerRefresh

func TimerRefresh(handle Value) float64

TimerRefresh re-arms a timeout for its original delay counted from now, the runtime behind timeout.refresh(). It is what a program with an idle timeout calls on every bit of activity, so the timeout only fires after a real gap rather than a fixed time after it was created.

The call a program most often makes is from inside the timeout's own callback, which is how an idle timeout keeps itself alive; a timer is retired only after its callback returns, so the handle is still live when that call arrives and the refresh re-arms it rather than dropping. An id naming a timer that has been cleared, or one this process never handed out, is ignored. An immediate has no deadline to move, so it is ignored too, which is what Node's Immediate does by not carrying the method at all.

func TimerUnref

func TimerUnref(handle Value) float64

TimerUnref takes a timer out of the count that keeps the process alive, the runtime behind timeout.unref(). The callback is not cancelled: an unrefed timer still fires if the loop is turning for some other reason, which is the difference between unref and clearTimeout and the whole reason a program reaches for it. A program whose only remaining work is unrefed exits instead of waiting, which is what setTimeout(mustNotCall(), 1000).unref() is asserting.

It returns the handle so a call can be chained, the way Node's returns the Timeout. An id naming no live timer is ignored, since unrefing a timer that already fired is as normal as clearing one.

func ToBoolean

func ToBoolean(v Value) bool

ToBoolean implements the ToBoolean abstract operation, JavaScript truthiness: undefined, null, false, +0, -0, NaN, and the empty string are falsy, and every object, every nonempty string, and every other number is truthy.

func ToInt32

func ToInt32(n float64) int32

ToInt32 coerces a number to a signed 32-bit integer, the ECMAScript ToInt32 operation. It shares every step with ToUint32 and differs only in the final interpretation: a value at or above 2^31 wraps to its negative two's-complement form. Reinterpreting the uint32 bits as int32 is exactly that wrap, so ToInt32 is ToUint32 reread as signed.

func ToNumber

func ToNumber(v Value) float64

ToNumber implements the ToNumber abstract operation, the coercion arithmetic on a maybe-non-number reaches for. It follows the spec cases: undefined is NaN, null and false are 0, true is 1, a number is itself, and a string parses through the same StringToNumber the Number(s) coercion uses. An object coerces through its primitive first, so [1] becomes 1 and [] becomes 0, matching the engine.

func ToUint16

func ToUint16(n float64) uint16

ToUint16 coerces a number to an unsigned 16-bit integer, the ECMAScript ToUint16 operation. It mirrors ToUint32 step for step and differs only in the modulus: NaN and the infinities become 0, and every other value is truncated toward zero then reduced modulo 2^16 into [0, 2^16). String.fromCharCode is the caller, which maps each argument through this before taking the result as a UTF-16 code unit. The fast path is ToUint32's, the low 16 bits of the int64 conversion, which skips the math.Mod for every argument short of 2^63; NaN and the infinities fail the range test and fall to the slow path that returns 0.

func ToUint32

func ToUint32(n float64) uint32

ToUint32 coerces a number to an unsigned 32-bit integer, the ECMAScript ToUint32 operation. NaN and the infinities become 0, every other value is truncated toward zero and then reduced modulo 2^32 into [0, 2^32). Every bitwise operand a normal program produces comes from integer arithmetic that stays far inside 2^63, so the fast path takes the low 32 bits of the int64 conversion (which is that truncate-then-reduce, since Go conversion truncates toward zero and a uint32 cast keeps the low 32 bits as two's complement) and pays a couple of casts where the modulo path pays a math.Mod. NaN and the infinities fail the range test and fall through to the slow path, which returns 0, so the fast path needs no separate check for them.

func TranslateRegExpSource

func TranslateRegExpSource(pattern, flags string) (re2 string, ok bool, reason string)

TranslateRegExpSource is the string-in, string-out gate the lowerer calls at compile time to decide whether a pattern and flag pair lowers. It parses the flag text and runs the same translation the runtime constructor runs, so a pattern lowers exactly when NewRegExpLiteral would build it. It reports the translated RE2 source on success and ok=false with a reason otherwise, including an invalid flag set, which the lowerer surfaces as its handback reason.

func URLCanParse

func URLCanParse(input BStr, base ...BStr) bool

URLCanParse reports whether new URL would succeed, the lowering of the static URL.canParse(input, base). It is the same parse without the throw, which is why the specification added it: asking the question should not cost an exception.

func WriteFileSync

func WriteFileSync(pathArg, data BStr)

WriteFileSync writes data to the file at the given path, creating it or truncating an existing file, the lowering of fs.writeFileSync(path, data) in its string-data form. The string is transcoded to its UTF-8 view, the byte sink Node uses when the data argument is a string with the default encoding. The 0o666 mode before umask matches Node's default for a newly created file. A write failure is a thrown error in Node, surfaced here as a panic.

func WriteStderr

func WriteStderr(s BStr) bool

WriteStderr is the standard-error companion of WriteStdout, the lowering of process.stderr.write(chunk).

func WriteStdout

func WriteStdout(s BStr) bool

WriteStdout writes a string to standard output, the lowering of process.stdout.write(chunk). The string is transcoded to its UTF-8 view, the byte sink a stream write expects, which maps a lone surrogate to U+FFFD the same way Node does when a string is written to a byte stream.

func ZonedDateTimeCompare

func ZonedDateTimeCompare(a, b *ZonedDateTime) float64

ZonedDateTimeCompare implements Temporal.ZonedDateTime.compare: -1, 0, or 1 as the first instant is before, at, or after the second. The comparison is on the exact time only; the zone and calendar do not enter it.

Types

type Array

type Array[T any] struct {
	// contains filtered or unexported fields
}

Array is bento's runtime representation of a JavaScript array whose element type the compiler proved, the *Array[T] header that 05_type_lowering.md section 11 names. It wraps a Go backing slice and adds the JavaScript array semantics a bare []T lacks.

This slice implements the dense core the lowerer needs first: construction from an array literal, the .length as a Number, and in-order iteration for for...of. The sparse edges (a length that outruns the backing store, holes, and index writes past the end) and the mutating and higher-order methods (push, pop, map, filter, slice) land in later slices. The type is introduced now so those can grow it without changing how an array is spelled in generated code: an array is always a *Array[T], today and after the methods arrive.

func ArrayFrom

func ArrayFrom[T any](elems []T) *Array[T]

ArrayFrom builds an array that takes ownership of an existing backing slice, the lowering target of an array literal that splices in a spread element. The spread lowering builds the backing slice with append, starting from a fresh []T so the result aliases none of the spread sources, then hands that slice here rather than re-copying it through NewArray's variadic. The array owns the slice from this point, which is sound because the caller built it for this one array and keeps no other reference to it.

func EntryPairs

func EntryPairs[T any](v Value, pair func(BStr, Value) T) *Array[T]

EntryPairs is Entries for a caller that has a Go type for the pair. The lowerer reaches for it when the checker gave Object.entries a typed pair array, which is what it gives for a receiver whose type it knows, and hands the pair constructor for the tuple struct it interned for that type. The walk is the one Entries makes, so the two agree on which properties an object contributes and in what order; only the shape of what comes back differs, a typed array rather than a boxed one.

func Flat

func Flat[T any](a *Array[*Array[T]]) *Array[T]

Flat concatenates the elements of an array of arrays into one flat array, the lowering of Array.prototype.flat at its default depth of one over an array whose element type is itself an array. It is a free function rather than a method because it needs the inner element type T as a type argument, which the receiver's *Array[*Array[T]] shape names but a method on *Array[*Array[T]] could not introduce. The result is a fresh array that aliases none of the inner arrays, matching flat, which copies elements into a new array. Deeper depths and a mixed array of arrays and values are later slices.

func FlatMap

func FlatMap[T, U any](a *Array[T], f func(T) *Array[U]) *Array[U]

FlatMap maps each element to an array and concatenates the results one level deep, the lowering of Array.prototype.flatMap over a callback that returns an array. It is a free function because the callback maps the element type T to an array of a possibly different element type U, the two type arguments the shape names, which a method could not introduce. It is the map-then-flat pair fused into one pass, so no intermediate array of arrays is built. The result is a fresh array; a callback returning a bare value rather than an array is a later slice.

func MapArray

func MapArray[T, U any](a *Array[T], f func(T) U) *Array[U]

MapArray is the type-changing form of Map: it builds a fresh Array[U] by applying f to each element of a, the lowering of Array.prototype.map when the callback returns a different type than the element (number[].map(n => n.toString()) is string[]). Map cannot express this because a Go method may not introduce a new type parameter, so the lowerer emits this free function with both type arguments spelled out whenever the callback's result type does not match the element type. As with Map the callback takes only the element, and the receiver is unchanged since the result is a new array.

func MapArrayIndex

func MapArrayIndex[T, U any](a *Array[T], f func(T, float64) U) *Array[U]

MapArrayIndex is the type-changing form of MapIndex: the (element, index) callback returns a different type than the element, the same reason MapArray is a free function with both type arguments spelled out.

func MapCallString

func MapCallString(arrayLike Value) *Array[Value]

MapCallString implements the borrowed idiom Array.prototype.map.call(arrayLike, String): it reads the array-like's length, coerces each element through the same abstract ToString the String built-in applies, and returns a new array of those strings. The test262 assert prelude formats a failed comparison exactly this way, compareArray.format, so lowering the borrow is what lets the prelude reach the interpreter's build path rather than hand back. The length coerces the way ToLength does, a NaN or negative length yielding a zero count, and each element reads positionally through the dynamic index so a dense array maps element for element.

func NewArray

func NewArray[T any](elems ...T) *Array[T]

NewArray builds an array from its elements, the lowering of an array literal [e0, e1, ...]. The elements are copied into a fresh backing slice so the header owns its storage and a later push through one array cannot alias a caller's variadic argument array or a slice the literal was built from.

func NewArrayLen

func NewArrayLen[T any](n float64) *Array[T]

NewArrayLen builds an array of n elements, the lowering of new Array<T>(n). JavaScript gives that call n holes, which read back as undefined; here the elements are T's zero value, because the declared element type says what a read of one is allowed to be and T has no undefined unless the type spelled it. Under a nullable element type the zero value is nil, which is the same empty slot the source is reaching for when it preallocates. The length is a float64 because that is how a JavaScript number arrives; a negative or fractional one is not a length, so it truncates toward zero and clamps at empty rather than panic in make.

func ReflectOwnKeys

func ReflectOwnKeys(target Value) *Array[Value]

ReflectOwnKeys implements Reflect.ownKeys(target): every own property key, string and symbol alike, in the spec's [[OwnPropertyKeys]] order. Integer-index keys come first in ascending numeric order, then the remaining string keys in insertion order, then the symbol keys in insertion order. An array contributes its element indices and then its length as a string key, ahead of any other string key.

func (*Array[T]) At

func (a *Array[T]) At(i float64) T

At reads the element a JavaScript index expression a[i] selects. The index is a Number, so it is a float64 here to match the type the checker gives the argument expression and to take the result of the bitwise and arithmetic path with no conversion at the call site. JavaScript truncates the index toward zero, and an index outside the array reads as the absent element. The element type is not optional, because the checker types a[i] as T under its default index signature rather than T | undefined, so an out-of-range read yields the zero value of T. That is a faithful lowering of the covered subset, where the programs that index an array do so within its bounds; the noUncheckedIndexed -Access shape, which types the read as T | undefined and needs an Opt result, is a later slice.

func (*Array[T]) AtI

func (a *Array[T]) AtI(i int) T

AtI reads the element at a Go int index, the integer-index form of At the lowerer emits when the checker proved the index expression is an integer. The float truncation and NaN fold At runs are then dead work, so this form takes the index already narrowed. The bounds check and the zero-value out-of-range result are the same as At, so the two reads agree on every index; only the index type differs.

func (*Array[T]) AtOpt

func (a *Array[T]) AtOpt(i float64) Opt[T]

AtOpt reads the element Array.prototype.at selects, the relative-index read that counts from the end when the index is negative. It is the sibling of At: At lowers the index expression a[i], whose default index signature types the read as T, so At returns a bare T with the zero value out of range; at is a method whose declared type is T | undefined, so AtOpt returns an Opt[T], a present optional in range and the undefined optional outside it. JavaScript truncates the index toward zero and adds the length once to a negative index, so at(-1) is the last element; an index still out of range after that, or a NaN that truncates to zero on an empty array, yields undefined. The receiver is unchanged, since at only reads.

func (*Array[T]) Concat

func (a *Array[T]) Concat(others ...*Array[T]) *Array[T]

Concat returns a new array formed by appending the elements of each argument array to a copy of the receiver, the lowering of Array.prototype.concat. In JavaScript concat spreads array arguments one level and appends non-array arguments as single elements. The lowering wraps a non-array argument in a one-element array at the call site, so by the time control reaches here every argument is an *Array[T] whose elements splice in. The result is a fresh array that aliases none of its sources, matching concat, which never mutates the arrays it reads.

func (*Array[T]) CopyWithin

func (a *Array[T]) CopyWithin(bounds ...float64) *Array[T]

CopyWithin copies a block of the array to another position within the same array in place and returns the array, the lowering of Array.prototype.copyWithin. It takes a target and up to two bounds, all Numbers, matching the source call: copyWithin(target) copies the whole array onto itself starting at target, copyWithin(target, start) copies from start to the end, and copyWithin(target, start, end) copies the half-open source range. Each index is read through relativeIndex, the same step slice and fill use, so a negative index counts from the end and an out-of-range one clamps rather than panicking. The number of elements copied is capped so it neither runs past the source range nor writes past the end of the array, matching copyWithin, which never changes the length. The copy uses Go's builtin copy, whose memmove semantics reproduce copyWithin's overlap behavior of reading the source range as if to a temporary before writing, so an overlapping copy is correct. It is a pointer method returning the receiver, so the write is visible through every reference, matching JavaScript where copyWithin mutates in place and returns this.

func (*Array[T]) Elems

func (a *Array[T]) Elems() []T

Elems returns the backing slice for in-order iteration, the lowering target of for...of. It is the live backing store, not a copy, which matches the array iterator visiting the elements in place. A push during iteration is visible through the same slice header the range captured at loop entry, which matches the array iterator reading up to the current length; the sparse grow-and-shrink edges are still a later slice.

func (*Array[T]) Every

func (a *Array[T]) Every(f func(T) bool) bool

Every reports whether all elements satisfy the predicate, the lowering of Array.prototype.every. It short-circuits on the first element the callback rejects, matching JavaScript, and an empty array is true because no element fails, the vacuous case JavaScript also returns true for. The callback takes only the element; the index and array arguments are a later slice.

func (*Array[T]) EveryIndex

func (a *Array[T]) EveryIndex(f func(T, float64) bool) bool

EveryIndex is Every for an (element, index) callback, threading the position as a float64. Short-circuiting on the first rejection and the vacuous empty true are unchanged.

func (*Array[T]) Fill

func (a *Array[T]) Fill(v T, bounds ...float64) *Array[T]

Fill overwrites a range of the array with a single value in place and returns the array, the lowering of Array.prototype.fill. It takes the fill value and zero, one, or two Number bounds, matching the source call, since fill's start and end are both optional: fill(v) fills the whole array, fill(v, start) runs to the end, and fill(v, start, end) is the half-open range. The bounds are read through relativeIndex, the same step slice uses, so a negative bound counts from the end and an out-of-range or crossed pair fills nothing rather than panicking. It is a pointer method returning the receiver, so the write is visible through every reference and a.fill(0) can be read on as the same array, matching JavaScript where fill mutates in place and returns this.

func (*Array[T]) Filter

func (a *Array[T]) Filter(f func(T) bool) *Array[T]

Filter returns a new array of the elements for which f returns true, in order, the lowering of Array.prototype.filter. As with Map, the callback takes only the element for now. The result is a fresh array, so the receiver is unchanged.

func (*Array[T]) FilterIndex

func (a *Array[T]) FilterIndex(f func(T, float64) bool) *Array[T]

FilterIndex is Filter for a predicate that also reads the element index, the lowering of Array.prototype.filter whose callback takes (element, index). The index is the float64 position, so the emitted predicate is func(T, float64) bool.

func (*Array[T]) Find

func (a *Array[T]) Find(f func(T) bool) Opt[T]

Find returns the first element the callback accepts, the lowering of Array.prototype.find. Its declared type is T | undefined, so it returns an Opt[T]: a present optional holding that element, or the undefined optional when no element passes, where JavaScript find returns undefined. It short-circuits on the first match, matching JavaScript. The callback takes only the element; the index and array arguments are a later slice.

func (*Array[T]) FindIndex

func (a *Array[T]) FindIndex(f func(T) bool) float64

FindIndex returns the index of the first element the callback accepts, or -1 when none does, the lowering of Array.prototype.findIndex. The result is a Number, so it is a float64, and -1 is the not-found sentinel JavaScript uses, so no optional is needed the way find's element result needs one. It short-circuits on the first match. The callback takes only the element; the index and array arguments are a later slice.

func (*Array[T]) FindIndexIndex

func (a *Array[T]) FindIndexIndex(f func(T, float64) bool) float64

FindIndexIndex is FindIndex for an (element, index) callback, returning the position of the first match or -1. The predicate receives the position as a float64.

func (*Array[T]) FindIndexed

func (a *Array[T]) FindIndexed(f func(T, float64) bool) Opt[T]

FindIndexed is Find for an (element, index) callback, returning the first element the predicate accepts as an Opt[T]. The name avoids colliding with FindIndex, which returns the position rather than the element. The position is passed as a float64.

func (*Array[T]) FindLast

func (a *Array[T]) FindLast(f func(T) bool) Opt[T]

FindLast returns the last element the callback accepts, the lowering of Array.prototype.findLast. Like find its declared type is T | undefined, so it returns an Opt[T], present with the matching element or the undefined optional when none passes. It walks from the end and short-circuits on the first match, matching JavaScript, which visits indices in descending order. The callback takes only the element; the index and array arguments are a later slice.

func (*Array[T]) FindLastIndex

func (a *Array[T]) FindLastIndex(f func(T) bool) float64

FindLastIndex returns the index of the last element the callback accepts, or -1 when none does, the lowering of Array.prototype.findLastIndex. Like findIndex the result is a Number, so it is a float64 with -1 as the not-found sentinel, and no optional is needed. It walks from the end and short-circuits on the first match, matching JavaScript's descending visit order. The callback takes only the element; the index and array arguments are a later slice.

func (*Array[T]) FindLastIndexIndex

func (a *Array[T]) FindLastIndexIndex(f func(T, float64) bool) float64

FindLastIndexIndex is FindLastIndex for an (element, index) callback, returning the position of the last match or -1. The predicate receives the position as a float64, walking from the end.

func (*Array[T]) FindLastIndexed

func (a *Array[T]) FindLastIndexed(f func(T, float64) bool) Opt[T]

FindLastIndexed is FindLast for an (element, index) callback, walking from the end and returning the last match as an Opt[T]. The position is passed as a float64, matching JavaScript's descending visit order.

func (*Array[T]) ForEach

func (a *Array[T]) ForEach(f func(T))

ForEach runs the callback for each element in order for its side effect, the lowering of Array.prototype.forEach. It returns nothing, matching the method's undefined result, so a call stands in the statement position. The callback takes only the element; the index and array arguments are a later slice, and forEach cannot be stopped early, matching JavaScript.

func (*Array[T]) ForEachIndex

func (a *Array[T]) ForEachIndex(f func(T, float64))

ForEachIndex is ForEach for an (element, index) callback, running it for effect with the position as a float64. It returns nothing, matching forEach's undefined result.

func (*Array[T]) Includes

func (a *Array[T]) Includes(target T, eq func(T, T) bool) bool

Includes reports whether any element equals target, the lowering of Array.prototype.includes. It is IndexOf against the same target, so it shares the linear scan; the difference between the two methods is entirely in the eq the lowerer passes. includes uses SameValueZero, which unlike strict equality treats NaN as equal to NaN, so the lowerer passes a NaN-aware eq for a number element here while it passes strict equality for IndexOf. That is why a NaN is found by includes but not by indexOf, matching JavaScript.

func (*Array[T]) IndexOf

func (a *Array[T]) IndexOf(target T, eq func(T, T) bool) float64

IndexOf returns the index of the first element equal to target, or -1 if none is, the lowering of Array.prototype.indexOf. Equality is supplied by the caller through eq rather than fixed here, because a Go method cannot compare two values of the type parameter T (it is any, not comparable) and because the exact equality JavaScript uses is element-type-specific: the lowerer passes strict equality for indexOf, which for a number is Go ==, so a NaN target is never found, matching indexOf's use of the strict equality operator. The result is a Number, so it is a float64. The optional fromIndex argument is a later slice; this is the whole-array scan.

func (*Array[T]) Join

func (a *Array[T]) Join(sep BStr, str func(T) BStr) BStr

Join concatenates the elements into a string separated by sep, the lowering of Array.prototype.join. Each element becomes a string through str, supplied by the caller for the same reason the search methods take an equality: a Go method cannot run the element-type-specific ToString on its type parameter, so the lowerer, which knows the element type, passes NumberToString, BoolToString, or the identity for a string. An empty array joins to the empty string, and a single element to itself with no separator, matching JavaScript.

func (*Array[T]) LastIndexOf

func (a *Array[T]) LastIndexOf(target T, eq func(T, T) bool) float64

LastIndexOf returns the index of the last element equal to target, or -1 if none is, the lowering of Array.prototype.lastIndexOf. It is IndexOf scanning from the end instead of the front, and it takes the same caller-supplied equality for the same reason: a Go method cannot compare two values of its type parameter, and the equality is element-type-specific. lastIndexOf uses strict equality like indexOf, so the lowerer passes the same closure it passes for indexOf, and a NaN target is never found. The result is a Number, so it is a float64. The optional fromIndex argument is a later slice; this is the whole-array scan.

func (*Array[T]) Len

func (a *Array[T]) Len() float64

Len is the array's length. JavaScript's .length is a Number, so it is a float64 here to match the type the checker gives the property and to compose with the rest of the numeric path with no conversion at the use site. It is the element count while arrays stay dense; the sparse case, where length can exceed the backing store, is a later slice.

func (*Array[T]) Map

func (a *Array[T]) Map(f func(T) T) *Array[T]

Map returns a new array holding f applied to each element in order, the lowering of Array.prototype.map. This is the same-element-type form, where the callback returns the element type; a map that changes the element type needs a free generic function, a later slice, because a Go method cannot introduce a new type parameter for the result. The callback here takes only the element, which is the common shape; the index and array parameters JavaScript also passes are a later slice. The result is a fresh array, so the receiver is unchanged.

func (*Array[T]) MapIndex

func (a *Array[T]) MapIndex(f func(T, float64) T) *Array[T]

MapIndex is Map for a callback that also reads the element index, the lowering of Array.prototype.map whose callback takes (element, index) and returns the element type. The index is the float64 position, matching JavaScript's number index, so the emitted callback is func(T, float64) T.

func (*Array[T]) Pop

func (a *Array[T]) Pop() Opt[T]

Pop removes the last element and returns it, the lowering of Array.prototype.pop. Its declared type is T | undefined, so it returns an Opt[T]: a present optional holding the removed element on a non-empty array, and the undefined optional on an empty array, where JavaScript pop returns undefined and leaves the array empty. It is a pointer method because the removal must be visible through every reference to the array, the same reason Push is. The backing slice is reshortened by one, so the popped slot is no longer part of the array.

func (*Array[T]) Push

func (a *Array[T]) Push(xs ...T) float64

Push appends its arguments to the end of the array and returns the new length as a Number, matching JavaScript's Array.prototype.push. It is a pointer method so the append is visible through every reference to the array, which is what a mutation on a shared array must be; a const binding in the source is no obstacle, because const freezes the binding, not the array's contents.

func (*Array[T]) ReduceNoInit

func (a *Array[T]) ReduceNoInit(f func(T, T) T) T

ReduceNoInit folds the array left to right with no initial value, the lowering of Array.prototype.reduce called with only a callback. With no init the accumulator seeds from the first element and the fold runs from the second, so the accumulator type is the element type T and the callback is func(T, T) T, unlike the initial-value form whose accumulator may be a different type A. That same difference is why this is a method: the accumulator type does not vary from the element type here, so no second type parameter is needed. An empty array has no seed, so it throws a TypeError the way JavaScript does rather than inventing one.

func (*Array[T]) ReduceNoInitIndex

func (a *Array[T]) ReduceNoInitIndex(f func(T, T, float64) T) T

ReduceNoInitIndex is ReduceNoInit for an (accumulator, element, index) callback. The accumulator seeds from the first element and the fold runs from the second, so the first callback index is 1, matching JavaScript. An empty array throws.

func (*Array[T]) ReduceRightNoInit

func (a *Array[T]) ReduceRightNoInit(f func(T, T) T) T

ReduceRightNoInit folds the array right to left with no initial value, the lowering of Array.prototype.reduceRight called with only a callback. The accumulator seeds from the last element and the fold runs toward the first, so the accumulator type is the element type T and no second type parameter is needed, which is why this is a method. An empty array has no seed, so it throws a TypeError the way JavaScript does.

func (*Array[T]) ReduceRightNoInitIndex

func (a *Array[T]) ReduceRightNoInitIndex(f func(T, T, float64) T) T

ReduceRightNoInitIndex is ReduceRightNoInit for an (accumulator, element, index) callback. The accumulator seeds from the last element and the fold runs toward the first, so the first callback index is len-2, matching JavaScript's descending visit order. An empty array throws.

func (*Array[T]) Reverse

func (a *Array[T]) Reverse() *Array[T]

Reverse reverses the elements in place and returns the same array, the lowering of Array.prototype.reverse. It is a pointer method because the reversal mutates the receiver, and it returns the receiver rather than a copy so that a.reverse() === a holds, matching JavaScript, where reverse returns a reference to the same array it reordered. An empty or single-element array is unchanged.

func (*Array[T]) Set

func (a *Array[T]) Set(i float64, v T) T

Set writes the element a JavaScript index assignment a[i] = v selects and returns the assigned value, which is what an assignment expression evaluates to. It is the store half of the At read: the index truncates toward zero the same way, and the two share the non-negative in-bounds convention that At's documentation describes. A write inside the array overwrites in place; a write at the current length extends the array by one; a write past the length grows the array and fills the gap with the zero value of T, which is the absent element At reads back out of range. That gap fill is where this lowering meets its covered subset: JavaScript leaves those slots as holes that read undefined, and the zero value stands in for them just as At returns the zero value rather than undefined for an in-type read past the end. A negative index in JavaScript creates a string-keyed property rather than an element and leaves the length alone, which is outside the covered subset, so it writes nothing and only yields the value; At is silent on the same negative index for the same reason. It is a pointer method so the write is visible through every reference to the array, the same way Push and the other in-place mutations are.

func (*Array[T]) Shift

func (a *Array[T]) Shift() Opt[T]

Shift removes the first element and returns it, the lowering of Array.prototype.shift. It is the front-of-array sibling of Pop: like pop its declared type is T | undefined, so it returns an Opt[T], a present optional holding the removed element on a non-empty array and the undefined optional on an empty array, where JavaScript shift returns undefined and leaves the array empty. It is a pointer method because the removal must be visible through every reference to the array, the same reason Push and Pop are. The backing slice is advanced by one, so every remaining element's index drops by one, which is the downward shift JavaScript names the method for.

func (*Array[T]) Slice

func (a *Array[T]) Slice(bounds ...float64) *Array[T]

Slice returns a shallow copy of a portion of the array into a new array, the lowering of Array.prototype.slice. It takes zero, one, or two Number bounds, matching the source call, since JavaScript's slice has both arguments optional: slice() copies the whole array, slice(start) runs to the end, and slice(start, end) is the half-open range. A bound is read exactly as JavaScript specifies, through relativeIndex: it truncates toward zero, a negative bound counts from the end, and the result is clamped into range, so an out-of-range or crossed pair yields an empty array rather than a panic. The result is a fresh array, so the receiver is unchanged.

func (*Array[T]) Some

func (a *Array[T]) Some(f func(T) bool) bool

Some reports whether at least one element satisfies the predicate, the lowering of Array.prototype.some. It short-circuits on the first element the callback accepts, matching JavaScript, and an empty array is false because no element passes. The callback here takes only the element, the common shape; the index and array arguments JavaScript also passes are a later slice.

func (*Array[T]) SomeIndex

func (a *Array[T]) SomeIndex(f func(T, float64) bool) bool

SomeIndex is Some for a callback that also reads the element index, the (element, index) shape JavaScript passes. It mirrors Some, handing the position as a float64 second argument, the Number the index parameter lowers to. Short-circuiting and the empty-array false are unchanged.

func (*Array[T]) Sort

func (a *Array[T]) Sort(cmp func(T, T) float64) *Array[T]

Sort orders the array in place by a comparator and returns the array, the lowering of Array.prototype.sort called with a compare function. The comparator returns a Number that is negative when its first argument should sort before its second, zero when their order is left as is, and positive otherwise, so an element sorts before another exactly when cmp returns a negative value. The sort is stable, matching the guarantee modern JavaScript engines give, so two elements the comparator calls equal keep their relative order. It is a pointer method returning the receiver, the same shape reverse takes, so the ordering is visible through every reference and the returned array is the same array, not a copy, matching JavaScript where sort mutates in place and returns this. A comparator that returns NaN, which JavaScript treats as zero, reads here as not-before through the NaN < 0 being false, so those elements keep their order too.

func (*Array[T]) Splice

func (a *Array[T]) Splice(start, deleteCount float64, items ...T) *Array[T]

Splice removes deleteCount elements starting at start, inserts items in their place, and returns the removed elements as a new array, the lowering of Array.prototype.splice called with a delete count. The start goes through relativeIndex, so a negative one counts from the end, and the count is clamped into [0, len-start] so it never runs past the end nor goes negative. The array is rebuilt into a fresh backing slice of the head, the inserted items, and the tail, so the result and the receiver share no storage with each other or with the items. It is a pointer method that replaces the receiver's backing slice, so the change is visible through every reference, matching JavaScript where splice mutates in place and returns the removed elements.

func (*Array[T]) SpliceToEnd

func (a *Array[T]) SpliceToEnd(start float64) *Array[T]

SpliceToEnd removes every element from start to the end and returns them as a new array, the lowering of the one-argument splice(start) form where the delete count is omitted and defaults to the rest of the array. The start goes through relativeIndex the same way Splice reads it. The removed elements are copied out before the receiver is truncated, so the result aliases none of the receiver's storage. It is a pointer method that shrinks the receiver in place, matching JavaScript where splice mutates the array and returns what it removed.

func (*Array[T]) ToReversed

func (a *Array[T]) ToReversed() *Array[T]

ToReversed returns a new array with the elements in reverse order, the lowering of Array.prototype.toReversed. It is the copying sibling of reverse: where reverse reorders in place and returns the same array, toReversed leaves the receiver untouched and returns a fresh array, so a.toReversed() !== a and the original order is still readable through the receiver. It writes the elements back to front into a new slice in one pass rather than copying then reversing. An empty or single-element array yields an equal fresh copy.

func (*Array[T]) ToSorted

func (a *Array[T]) ToSorted(cmp func(T, T) float64) *Array[T]

ToSorted returns a new array sorted by the comparator, the lowering of Array.prototype.toSorted called with a compare function. It is the copying sibling of sort: it orders a fresh copy of the elements and leaves the receiver in its original order, where sort reorders in place and returns the same array. The comparator has the same meaning it has for sort, negative to place its first argument before its second, and the sort is stable for the same reason, so equal elements keep their relative order. The result aliases none of the receiver's storage, so a.toSorted(cmp) !== a and the original order is still readable through the receiver.

func (*Array[T]) ToSpliced

func (a *Array[T]) ToSpliced(start, deleteCount float64, items ...T) *Array[T]

ToSpliced returns a new array with deleteCount elements removed at start and items inserted in their place, the lowering of Array.prototype.toSpliced called with a delete count. It is the copying sibling of splice: where splice mutates the receiver and returns what it removed, toSpliced leaves the receiver alone and returns the array that results from the edit. The start and count are read exactly as Splice reads them, so a negative start counts from the end and the count is clamped into [0, len-start]. The result is built into a fresh backing slice of the head, the inserted items, and the tail, so it aliases neither the receiver nor the items.

func (*Array[T]) ToSplicedToEnd

func (a *Array[T]) ToSplicedToEnd(start float64) *Array[T]

ToSplicedToEnd returns a new array with every element from start to the end removed, the lowering of the one-argument toSpliced(start) form where the delete count defaults to the rest of the array. It is the copying sibling of SpliceToEnd: the head up to start is copied into a fresh slice and the receiver is left untouched.

func (*Array[T]) ToValue

func (a *Array[T]) ToValue() Value

ToValue is ArrayValueOf with the element box left to the runtime's own dispatch, the no-argument form a container holding an array needs: a boxed Map<string, number[]> reaches each value with nothing but its Go type in hand, so it cannot be handed a boxer the way an emitted call site can. It copies the way ArrayValueOf does, so an array nested in a boxed collection reads through and a write made through the box does not reach the typed array.

func (*Array[T]) Unshift

func (a *Array[T]) Unshift(xs ...T) float64

Unshift prepends its arguments to the front of the array in order and returns the new length as a Number, the lowering of Array.prototype.unshift. It is the front-of-array sibling of Push, and like Push it is a pointer method so the insertion is visible through every reference. The arguments keep their order, so unshift(1, 2) on [3] yields [1, 2, 3]. A fresh backing slice is built with the arguments ahead of the existing elements rather than prepending in place, so the caller's variadic argument array is never aliased or mutated, the same ownership NewArray keeps.

func (*Array[T]) With

func (a *Array[T]) With(index float64, value T) *Array[T]

With returns a new array with the element at index replaced by value, the lowering of Array.prototype.with. It is the copying single-index write: where a[i] = v mutates in place, with leaves the receiver alone and returns a fresh array, so it reads back through every reference unchanged. The index is read as JavaScript reads it, truncated toward zero with NaN becoming zero, and a negative index counts from the end. An index that lands outside the array after that throws a RangeError rather than clamping or growing, matching with, which reports the original argument in the message even when it was fractional. The result aliases none of the receiver's storage.

type ArrayBuffer

type ArrayBuffer struct {
	// contains filtered or unexported fields
}

ArrayBuffer is bento's runtime representation of a JavaScript ArrayBuffer, the raw byte backing store a typed array or a DataView views (25 §6.2 and §25.1). It owns a flat run of bytes and nothing else: a typed array is a separate view that records this buffer, a byte offset, and an element length, so many views can share one buffer and observe each other's writes. Splitting the storage out of the view this way is what lets `new Int32Array(buf)` and `new Uint8Array(buf)` over the same buffer alias the same bytes, which is the model the test262 buffer tests exercise.

The bytes are allocated eight-byte aligned (allocBytes) so a view of any element width up to eight bytes, placed at the byte offset the spec requires to be a multiple of that width, lands on a naturally aligned address. A view then reads and writes its elements straight through an aliasing slice over these bytes with no per-element packing, and the platform's little-endian layout is the byte order the buffer exposes, which is the order the tests assume. A resizable buffer carries the maximum byte length it may grow to and a flag that marks it resizable, the pair new ArrayBuffer(n, { maxByteLength }) sets (25 §25.1.3). A fixed-length buffer leaves both zero, so resizable reads false and the max-length getter falls back to the current length the way the spec's getter does. resize reallocates the backing run to the requested length, within the max, and every view recomputes its span over the new run on its next access, so a shrink turns an out-of-range view zero-length and a grow restores it.

func NewArrayBuffer

func NewArrayBuffer(byteLength float64) *ArrayBuffer

NewArrayBuffer builds a zeroed buffer of the given byte length, the lowering of `new ArrayBuffer(n)`. The length runs through ToIndex, so a negative length, a non-integer past 2^53-1, or an infinity throws a RangeError before any allocation, and CreateByteDataBlock's allocation limit throws a RangeError for a length too large to back, matching the throws Node raises rather than clamping or panicking.

func NewResizableArrayBuffer

func NewResizableArrayBuffer(byteLength float64, maxByteLength float64) *ArrayBuffer

NewResizableArrayBuffer builds a resizable buffer of the given byte length that may later grow to maxByteLength, the lowering of new ArrayBuffer(n, { maxByteLength }). Both arguments are Numbers truncated toward zero like ToIndex. A max below the initial length is a RangeError, the same throw the spec raises for an initial length past the maximum; the covered subset otherwise clamps a negative to zero. The backing run is sized to the initial length, not the maximum, and resize reallocates it, so an unused max costs no storage.

func (*ArrayBuffer) ByteLength

func (b *ArrayBuffer) ByteLength() float64

ByteLength is the buffer's size in bytes, a Number to match the type the checker gives the .byteLength property and to compose with the numeric path with no conversion at the use site.

func (*ArrayBuffer) Bytes

func (b *ArrayBuffer) Bytes() []byte

Bytes returns the buffer's backing slice, the storage every view over it shares. A view builds its aliasing element slice over this run, and the Go boundary hands these bytes to a Go function taking []byte. The slice header aliases the buffer's own storage, so a write through any view or through the returned slice shows through every other view of the buffer.

func (*ArrayBuffer) Detach

func (b *ArrayBuffer) Detach()

Detach empties the buffer and marks it detached, the state a transfer or an explicit detach leaves it in. The bytes are dropped so ByteLength reads zero and, once the view path consults the buffer's live state, every view over it reads as zero-length with its indexed access a no-op.

func (*ArrayBuffer) Detached

func (b *ArrayBuffer) Detached() bool

Detached reports whether the buffer has been detached, the ArrayBuffer.prototype .detached accessor and the state the $DETACHBUFFER harness hook leaves behind.

func (*ArrayBuffer) MaxByteLength

func (b *ArrayBuffer) MaxByteLength() float64

MaxByteLength is the largest byte length the buffer may hold, the .maxByteLength accessor. A resizable buffer reports the maximum it was built with; a fixed-length one reports its current length, the value the spec's getter returns when the buffer is not resizable. A detached buffer reports zero.

func (*ArrayBuffer) Resizable

func (b *ArrayBuffer) Resizable() bool

Resizable reports whether the buffer may be resized, the .resizable accessor, true only for a buffer built with a maxByteLength.

func (*ArrayBuffer) Resize

func (b *ArrayBuffer) Resize(newLength float64)

Resize grows or shrinks the backing run to newLength, the lowering of ArrayBuffer.prototype.resize (25 §25.1.6). Resizing a detached buffer or one that is not resizable is a TypeError, and a length past the maximum is a RangeError, the throws the spec raises. The run is reallocated to the new length, the retained bytes copied, and any growth left zeroed, so a view over the buffer sees the new size and, where a shrink drops its range, reads zero-length until a later grow restores it.

func (*ArrayBuffer) Slice

func (b *ArrayBuffer) Slice(bounds ...float64) *ArrayBuffer

Slice copies the bytes in [start, end) into a fresh fixed-length buffer, the lowering of ArrayBuffer.prototype.slice (25 §25.1.6). start and end are optional Numbers; a negative index counts from the end and an omitted end runs to the current byte length, the same relative-index rule Array.prototype.slice takes, and an end before the start yields an empty buffer rather than a negative length. The result owns its bytes and does not alias the receiver, so a later write through either shows only in that one, and it is never resizable even when the receiver is, which is what the spec's species-free allocation does. Slicing a detached buffer is a TypeError, since there are no bytes left to copy.

func (*ArrayBuffer) ToValue

func (b *ArrayBuffer) ToValue() Value

ToValue boxes a buffer into a dynamic value. The box is built once and kept on the buffer, so every crossing of the same buffer hands back the same object: two boxes would compare unequal under === and print as two values even though the program has one run of bytes.

func (*ArrayBuffer) Transfer

func (b *ArrayBuffer) Transfer(newLength ...float64) *ArrayBuffer

Transfer moves the buffer's bytes to a fresh buffer of the given byte length and detaches the receiver, the lowering of ArrayBuffer.prototype.transfer (25 §25.1.6). The new buffer keeps the first min(old, new) bytes and zero-fills any growth, and the old buffer is detached so every view over it reads as zero-length from here on. The new length defaults to the receiver's current byte length when the call gives none. Transferring an already-detached buffer is a TypeError, the same throw the spec raises. The resizable distinction transferToFixedLength carries has no effect until the resizable buffer lands, so the two share this body today.

func (*ArrayBuffer) TransferToFixedLength

func (b *ArrayBuffer) TransferToFixedLength(newLength ...float64) *ArrayBuffer

TransferToFixedLength moves the bytes to a fresh fixed-length buffer and detaches the receiver, the lowering of ArrayBuffer.prototype.transferToFixedLength. It differs from Transfer only in that its result is never resizable; with the resizable buffer still a later slice every buffer is already fixed-length, so it shares Transfer's body and the distinction is a no-op until then.

type ArrayIter

type ArrayIter struct {
	// contains filtered or unexported fields
}

ArrayIter is a running walk over an array's indices. src is the array as a boxed value, so length and each index read through the same dynamic accessors a generic-receiver method uses; i is the next index to visit; kind picks the projection. It holds no goroutine, unlike a generator, since an array walk needs no suspended body: each Next reads the next index directly.

func ArrayIterFromSlice

func ArrayIterFromSlice[T any](elems []T, kind ArrayIterKind, box func(T) Value) *ArrayIter

ArrayIterFromSlice mints an array iterator over a snapshot slice of typed elements, the form a manual drive of a Map or Set iterator takes: the runtime's Keys, Values, or Members accessor hands back an insertion-ordered snapshot slice, and this boxes it once into a dynamic array the ArrayIter walks. The box closure lifts each typed element into a value.Value, the same constructor a static-to- dynamic crossing uses, since the iterator yields boxed values whatever the element type. The snapshot is taken when the iterator is minted, matching the moment map.values() is called; the mutation-after-mint case the caller proves absent.

func ArrayIterFromTyped

func ArrayIterFromTyped[T any](a *Array[T], kind ArrayIterKind, box func(T) Value) *ArrayIter

ArrayIterFromTyped mints an array iterator over a statically typed array by boxing its elements into a dynamic array once, the form the runtime takes when the source is a *Array[T] the lowerer holds. The box closure lifts each typed element into a value.Value, the same constructor a static-to-dynamic crossing uses, since the iterator yields boxed values whatever the element type. Boxing eagerly snapshots the elements, so an iterator over a typed array reflects the elements present when it was created.

func NewArrayIter

func NewArrayIter(src Value, kind ArrayIterKind) *ArrayIter

NewArrayIter mints an array iterator over a boxed array, the form the runtime takes when the source is already a value.Value, a dynamic array or an array-like.

func (*ArrayIter) Next

func (it *ArrayIter) Next() IterResult

Next advances the iterator one step and packs the { value, done } result. Once the index reaches the current length it reports done with undefined; otherwise it yields the projection its kind selects and steps the index. It reads length live, so an array that grew is walked to its new end and one that shrank stops early.

type ArrayIterKind

type ArrayIterKind int

ArrayIterKind selects which projection an array iterator yields: the element, the index, or the [index, element] pair, the three kinds values, keys, and entries produce.

const (
	// ArrayIterKeys yields each index as a number, the projection arr.keys() takes.
	ArrayIterKeys ArrayIterKind = iota
	// ArrayIterValues yields each element, the projection arr.values() takes and the
	// one for...of and spread over an array walk.
	ArrayIterValues
	// ArrayIterEntries yields each [index, element] pair as a two-element array, the
	// projection arr.entries() takes.
	ArrayIterEntries
)

type AsyncCo

type AsyncCo struct {
	// contains filtered or unexported fields
}

AsyncCo is the handle a suspending async body holds. The body parks by sending on parked and waits for the next step on resume; the driver advances it by sending the settled await result on resume and waiting for the body to park or complete on parked. It carries no element type: the awaited value rides asyncResume as a boxed any, since a single body awaits promises of many element types.

type AsyncGen

type AsyncGen[Y any] struct {
	// contains filtered or unexported fields
}

AsyncGen is a running async generator of yield type Y. The body runs in a goroutine that parks on out; the driver advances it through Next and settles each pull's promise with the { value, done } result. started gates the goroutine launch to the first pull, so an async generator that is never pulled never runs its body, and done latches once the body completes so a later pull resolves to a done result without resuming.

func NewAsyncGen

func NewAsyncGen[Y any](body func(*AsyncGenCo[Y]) Value) *AsyncGen[Y]

NewAsyncGen mints an async generator whose body is the goroutine func the lowerer builds from an async generator function's source. The body takes the coroutine handle it yields and awaits through and returns the value the generator completes with, undefined for one that runs off its end with no return value.

func (*AsyncGen[Y]) Next

func (g *AsyncGen[Y]) Next(sent Value, box func(Y) Value) *Promise[IterResult]

Next pulls the next value and returns the promise for the { value, done } result. It resumes the body with sig, then reads why the body parked: a yield fulfills the promise with the yielded value, a completion fulfills it with a done result, and a throw rejects it. An await keeps the promise pending: the body registers its resume on the awaited promise, and when that settles the driver resumes the body and reads the next park, so the pull settles only once the body reaches its next yield or its completion. The box closure lifts the typed yield into a value.Value, since the driver is generic over Y.

type AsyncGenCo

type AsyncGenCo[Y any] struct {
	// contains filtered or unexported fields
}

AsyncGenCo is the handle the body holds. It yields and awaits through the same channel pair the AsyncGen drives, so a yield sends a yield frame and blocks for the resume and an await sends an await frame and blocks for the settled value. It is passed to the body func the lowerer builds from the async generator source.

func (*AsyncGenCo[Y]) Yield

func (co *AsyncGenCo[Y]) Yield(v Y) Value

Yield sends v to the driver and blocks until the driver pulls again, then returns the value the consumer passed back through next(v). A return signal unwinds the body as a genAbort so its finally blocks run, and a throw signal raises the injected value at the yield the way a plain generator's yield does.

func (*AsyncGenCo[Y]) YieldBoxed

func (co *AsyncGenCo[Y]) YieldBoxed(v Value) Value

YieldBoxed sends an already-boxed value to the driver rather than a typed Y, then blocks for the resume the way Yield does. A yield* over an async delegate pulls each value through the delegate's own Next, which returns it boxed in an IterResult, so re-yielding it through Yield would box it a second time; YieldBoxed carries the boxed value straight to the driver, which fulfills the outer pull with it. The resume handling matches Yield: a return unwinds the body, a throw raises at the yield, and a next resumes with its value.

func (*AsyncGenCo[Y]) YieldFrom

func (co *AsyncGenCo[Y]) YieldFrom(sub *AsyncGen[Y], box func(Y) Value) Value

YieldFrom delegates a yield* to another async generator: it pulls sub one value at a time, awaiting each pull, and re-yields every value the delegate produces until the delegate completes, then returns the delegate's completion value as the value of the yield* expression. Awaiting each sub.Next parks the outer body the same await path a plain await takes, so the outer generator's own driver stays suspended while the delegate runs, and the delegate's yields flow through the outer pull one at a time in order. The box closure lifts the delegate's yield type into a value.Value for its own pulls; the re-yield uses YieldBoxed since that pull already boxed the value.

type AtomicView

type AtomicView interface {
	// Len is the view's element count, the bound an access index is checked against.
	Len() float64
	// At reads the element at an index, widened to a Number.
	At(i float64) float64
	// SetAt writes an element at an index, coercing the value with the element's store
	// rule, the same write a plain indexed assignment makes.
	SetAt(i float64, v float64)
	// contains filtered or unexported methods
}

AtomicView is the integer typed array an Atomics operation runs over: the numeric family value.TypedArray[T] and the byte-backed value.Uint8Array both satisfy it, so one set of Atomics functions covers every integer element width. It exposes the element read and write the operations share and the element coercion compareExchange needs to compare a stored element against a coerced operand.

type BStr

type BStr struct {
	// contains filtered or unexported fields
}

BStr is a JavaScript string: a sequence of UTF-16 code units. It keeps two coherent views. Most strings are valid UTF-8 (they came from source, JSON, or the network), so the common case stores the UTF-8 bytes and never allocates the code-unit slice; utf16 is populated only when the string holds a lone surrogate that UTF-8 cannot represent, or when an operation forces the code-unit view. lengthU16 is always the UTF-16 code-unit count, which is what String.prototype.length reports, so .length is O(1) whichever view is live.

A BStr is immutable, like a JavaScript string, so it is passed and shared by value with no defensive copy and no locking.

func Atob

func Atob(s BStr) BStr

Atob is atob(s): it decodes base64 back to a string whose code units are the decoded bytes, following the WHATWG forgiving-base64 rules. It strips ASCII whitespace, drops the trailing padding, and rejects input of the wrong length or with a character outside the alphabet with an InvalidCharacterError. The final group's spare bits are discarded rather than required to be zero, which is the "forgiving" part and what parts atob from a strict base64 decoder.

func AtomicWait

func AtomicWait(a AtomicView, index float64, value float64, timeout ...float64) BStr

AtomicWait blocks until the element at the index changes from value or a notify arrives, the lowering of Atomics.wait, and returns "ok", "not-equal", or "timed-out". In a single agent there is no other agent to change the element or send a notify, so a wait that would block cannot make progress: it returns "not-equal" when the element already differs from value, and "timed-out" otherwise, since a wait with no possible notifier is a wait that has already timed out. The "ok" result, which only a real notify from a second agent produces, never occurs single-agent.

func BigIntToConsole

func BigIntToConsole(b *big.Int) BStr

BigIntToConsole renders a *big.Int the way console.log inspects a bigint: the decimal digits with a trailing "n", so console.log(10n) prints "10n" while String(10n) and `${10n}` stay "10". Only the console inspector adds the suffix, which is why it is its own helper and not BigIntToString.

func BigIntToString

func BigIntToString(b *big.Int) BStr

BigIntToString renders a *big.Int the typed side holds as its decimal digits, the value String(b) and a `${b}` template produce. It is the typed-side companion of the boxed ToString: a bigint's string form is just its digits, with no suffix.

func BigIntToStringRadix

func BigIntToStringRadix(b *big.Int, radix float64) BStr

BigIntToStringRadix renders a bigint in the given base, the lowering of b.toString(radix). The radix runs through ToIntegerOrInfinity and must land in [2, 36], else it throws the RangeError JavaScript raises. big.Int.Text uses the same 0-9a-z digits JavaScript does for those bases, and it keeps the leading minus, so (-255n).toString(16) is "-ff" the same as V8.

func BoolToString

func BoolToString(b bool) BStr

BoolToString returns the JavaScript String(b) of a boolean, "true" or "false", the ECMAScript Boolean::toString.

func Btoa

func Btoa(s BStr) BStr

Btoa is btoa(s): it reads each code unit as a byte and returns the base64 encoding of that byte sequence. A code unit above 0xFF is not a byte, so it cannot be a binary-string character, and btoa raises an InvalidCharacterError rather than truncate it.

func ClassTag

func ClassTag(v Value) BStr

ClassTag implements Object.prototype.toString.call(v), the idiom test262 and much library code reaches for to read a value's internal class as a string of the form "[object Type]". The mapping is the spec's Object.prototype.toString: undefined and null carry their own tags, an array is "[object Array]", a callable is "[object Function]", and every primitive and plain object reports the tag for its type. It is called only where the AOT path proved the borrow is Object.prototype.toString.call, so the receiver kind alone decides the tag.

An object whose Symbol.toStringTag property is a string reports "[object <tag>]" with that string, the hook a library uses to name its own instances, and it is read first because the specification has it override the internal class. A boxed Date, Error or RegExp reports its own name next: bento brands those on the object's storage rather than in the spec's internal slot, so the brand is what the tag is read from. A plain object with neither reaches the object case and reports "[object Object]".

func CoerceThisToString

func CoerceThisToString(v Value) BStr

CoerceThisToString runs the two opening steps every String.prototype method shares before it touches its receiver: RequireObjectCoercible(this value) then ToString(O) (for example 22.1.3.3 steps 1-2). A null or undefined this throws a TypeError before any coercion, so String.prototype.codePointAt.call(null) raises the way Node does rather than stringifying the receiver to "null"/"undefined" and running the method on that text. A non-nullish receiver coerces through the ordinary ToString, so a number, boolean, or object this stringifies exactly as a direct string-method call would.

func Concat

func Concat(a, b BStr) BStr

Concat returns the concatenation of a and b, the lowering of `a + b` when both are strings. It picks the backing form once: if both sides are on the UTF-8 fast path the result stays UTF-8 with a single byte copy, and otherwise the result materializes the code-unit view of each side and appends, so a lone surrogate on either side survives. Go's own `+` is never used on the BStr struct, and Go string concat is never used as the lowering, because that would be UTF-8 semantics on a UTF-16 string (05_type_lowering section 5).

func ConsoleFormat

func ConsoleFormat(args ...Value) BStr

ConsoleFormat renders one console.log or console.error call's arguments, the single string that goes to the stream. console.log is util.format with color options when it writes to a terminal and without them otherwise, and bento does not color, so this is util.format.

func ConsoleValue

func ConsoleValue(v Value) BStr

ConsoleValue renders a dynamic value the way console.log renders one argument. A string prints as itself, with no quotes: console.log("hi") is hi, which is why the string is not sent through the inspector. Everything else is inspected, the way Node's console does, so an object reads as its properties rather than as "[object Object]" and a symbol renders instead of throwing the way a string coercion would.

func DecodeURI

func DecodeURI(s BStr) BStr

DecodeURI is decodeURI(s): it reverses encodeURI, but leaves an escape that decodes to a reserved delimiter as the literal %XX it found, so a decoded URI keeps the escaped punctuation that a re-encode would have to restore anyway. This preserve rule is the only way decodeURI parts from decodeURIComponent.

func DecodeURIComponent

func DecodeURIComponent(s BStr) BStr

DecodeURIComponent is decodeURIComponent(s): it turns each %XX escape back into the byte it names, decodes each UTF-8 sequence to its code point, and passes every other code unit through, the reverse of encodeURIComponent.

func EncodeURI

func EncodeURI(s BStr) BStr

EncodeURI is encodeURI(s): it keeps the unreserved characters and the reserved delimiters and percent-encodes every other code point, the encoder for a whole URI that must keep its structure.

func EncodeURIComponent

func EncodeURIComponent(s BStr) BStr

EncodeURIComponent is encodeURIComponent(s): it keeps the unreserved characters and percent-encodes the UTF-8 bytes of every other code point, the encoder for a single URI component.

func ErrorMessageString

func ErrorMessageString(v Value) BStr

ErrorMessageString coerces a dynamic value to the message string the Error constructor stores. The constructor (20 §20.5.1.1) sets the message only when the argument is not undefined, leaving the empty string otherwise, and coerces a present argument with ToString: new Error(undefined).message is "", but new Error(0).message is "0". It backs an Error subclass whose super() argument is not statically a string, where the lowered argument is a value.Value the inherited message field cannot take raw.

func FromCharCode

func FromCharCode(codes ...float64) BStr

FromCharCode builds a string from UTF-16 code units, String.fromCharCode. Each argument is coerced to a 16-bit unsigned integer by ToUint16, the same truncation the specification applies, so a number outside [0, 2^16) wraps rather than being rejected and a fraction is dropped. The units are taken verbatim, which means a lone surrogate is preserved rather than replaced, so the result keeps the code-unit view rather than the UTF-8 fast path. It is a free function, not a method, because fromCharCode is a static on the String constructor with no string receiver.

The units slice is allocated and filled here and never handed back to the caller, so it backs the result directly, the way padTo does, without the defensive copy FromUTF16 makes for a slice it does not own. That is the one allocation the call costs; routing through FromUTF16 would double it.

func FromCharCodeValues

func FromCharCodeValues(args ...Value) BStr

FromCharCodeValues is String.fromCharCode over already-boxed arguments, the shape String.fromCharCode.apply reaches when the spread array's element type is dynamic: apply coerces each element with ToNumber before the code unit is taken, so a numeric string or a boolean joins a plain number, and the coerced numbers delegate to the variadic FromCharCode that owns the ToUint16 truncation.

func FromCodePoint

func FromCodePoint(codePoints ...float64) BStr

FromCodePoint builds a string from Unicode code points, String.fromCodePoint. Unlike fromCharCode, each argument is a full code point, not a code unit, so an astral point above U+FFFF is encoded as the surrogate pair that spells it in UTF-16 and adds two code units, not one. Each argument must be an integer in [0, 0x10FFFF]; a negative number, a fraction, or a value past the last code point is not a valid code point, so it throws a RangeError the way the specification requires rather than wrapping the way fromCharCode does. The units are taken verbatim into the code-unit view, so a lone surrogate passed directly is preserved. It is a free function for the same reason fromCharCode is: fromCodePoint is a static on the String constructor with no receiver.

func FromCodePointValues

func FromCodePointValues(args ...Value) BStr

FromCodePointValues is the code-point sibling of FromCharCodeValues: apply coerces each boxed element with ToNumber, then FromCodePoint validates and encodes it as a full code point, so String.fromCodePoint.apply over a dynamic array throws the same RangeError on a non-integer or out-of-range element a direct call would.

func FromGoString

func FromGoString(s string) BStr

FromGoString builds a BStr from a Go string. A Go string is UTF-8, which is always representable as UTF-16, so the result keeps the UTF-8 fast path and only counts code units; no surrogate array is allocated. Invalid UTF-8 bytes in the input are counted as the U+FFFD replacement each rune decode yields, so the length matches what materializing the string would produce. This is the transcode a Go value takes when it crosses into the JavaScript world (05_type_lowering section 5, bento.FromGoString).

func FromUTF16

func FromUTF16(units []uint16) BStr

FromUTF16 builds a BStr from raw UTF-16 code units, the constructor for a value that may contain a lone surrogate. If the units happen to be a valid UTF-8-representable string this still keeps the code-unit view, because the caller reached for this path precisely when the UTF-8 fast path would not be safe; callers with UTF-8 in hand use FromGoString. The units are copied so a later mutation of the caller's slice cannot change an immutable string.

func Inspect

func Inspect(v Value) BStr

Inspect renders a dynamic value the way the interpreter's prelude inspector does, the compact object-and-array spelling util.inspect and the assert message formatter reach for through the __bento_inspect host callee. It is not Node's full util.inspect (the interpreter's own inspector is not either); it is the same compact form both bento paths share so an AOT program and the interpreter agree on what an object logs as. The top-level value renders unquoted when it is a string, so console.log(util.inspect("hi")) reads "hi", while a string nested in a container is quoted the way JSON renders it.

func JSONStringify

func JSONStringify(v any) BStr

JSONStringify serializes a value to the text JSON.stringify produces, with no indentation and keys in insertion order, matching V8 exactly. It is the top of the reflection walk: the argument arrives boxed as any because the call site is the one dynamic edge in an otherwise statically typed program, and the walk dispatches on the concrete type from there.

func JSONStringifyIndentNum

func JSONStringifyIndentNum(v any, space float64) BStr

JSONStringifyIndentNum is JSON.stringify(v, null, space) with a numeric space: the gap is that many spaces, clamped to ten and floored through ToInteger, and a space below one produces the compact form with no indentation, exactly as the specification's SerializeJSONProperty computes the gap.

func JSONStringifyIndentStr

func JSONStringifyIndentStr(v any, space BStr) BStr

JSONStringifyIndentStr is JSON.stringify(v, null, space) with a string space: the gap is the first ten code units of the string, and an empty string produces the compact form, matching how the specification truncates a string gap.

func JSONStringifyReplacerArray

func JSONStringifyReplacerArray(v any, keys []BStr, gap string) BStr

JSONStringifyReplacerArray is JSON.stringify(v, keys, space) with an array replacer: only the keys the array lists are serialized, in the array's order, and a listed key an object does not have is skipped. The value is lifted to a Value tree and serialized with the given gap.

func JSONStringifyReplacerFunc

func JSONStringifyReplacerFunc(v any, replacer func(BStr, Value) Value, gap string) BStr

JSONStringifyReplacerFunc is JSON.stringify(v, replacer, space) with a function replacer. The value is lifted to a Value tree, the replacer is applied to the root and then to every key and value top-down, and the result is serialized with the given gap, an empty gap meaning the compact form.

func JoinString

func JoinString(v Value) BStr

JoinString converts one element the way Array.prototype.join does: undefined and null contribute the empty string rather than their names, so [1, null, 3].join() is "1,,3", and every other value goes through the abstract ToString. The lowerer passes this as the per-element string closure when the array's element type is dynamic and it cannot pick a fixed element ToString (NumberToString, BoolToString, or the identity for a string).

func Mkdtemp

func Mkdtemp(prefix BStr) BStr

Mkdtemp creates a new temporary directory whose name starts with prefix and returns its path, the lowering of fs.mkdtempSync. Node treats the prefix as a literal path fragment and appends six random characters to it, which is exactly os.MkdirTemp's contract when the prefix's directory is split from its base, so the two agree on the created path shape. A creation failure (a missing parent, a permission denial) is a thrown error in Node, surfaced here as a panic.

func NamedClassTag

func NamedClassTag(_ any, name string) BStr

NamedClassTag returns the "[object <Name>]" tag Object.prototype.toString.call reads off a receiver whose class name the compiler knows statically but whose Go representation does not box into a Value the runtime ClassTag could read: a typed array, a Map, or a Set. The receiver is taken and discarded so the borrowed toString evaluates its argument the way the language does and the caller's binding reads as a use, while the tag comes from the compiler-known name.

func NodeFormat

func NodeFormat(args ...Value) BStr

NodeFormat is util.format: the format string's specifiers filled from the arguments that follow, with the leftovers appended. It is also what console.log does with its arguments, because console's no-color options are the defaults.

func NodeFormatWithOptions

func NodeFormatWithOptions(opts Value, args ...Value) BStr

NodeFormatWithOptions is util.formatWithOptions: the same formatting with the inspect options the caller chose, which reach the %s, %o and %O specifiers and every leftover argument. The options argument is validated rather than ignored, because Node throws ERR_INVALID_ARG_TYPE on a non-object and a program that passes its format string there by mistake should learn so from the same error.

func NodeInspect

func NodeInspect(v Value) BStr

NodeInspect renders a value the way Node's util.inspect does with its default options, which is what console.log prints for every argument that is not already a string. It is the console's renderer rather than a string coercion: an object reads as its properties instead of "[object Object]", a string nested in a container is quoted, and a bigint carries its "n".

func NodeInspectArgs

func NodeInspectArgs(args ...Value) BStr

NodeInspectArgs is util.inspect called with its own argument list, so the module entry point and this port read the options in one place. Node still accepts the positional form inspect(value, showHidden, depth, colors) it started with, and reads it before the options object, so both are handled here in that order. It is variadic because the lowerer emits a call to it for an imported node:util inspect, one boxed argument per source argument, and a variadic signature is what an emitted call can name without building a slice literal.

func NowTimeZoneId

func NowTimeZoneId() BStr

NowTimeZoneId implements Temporal.Now.timeZoneId, the host's default time-zone identifier.

func NumberToConsole

func NumberToConsole(f float64) BStr

NumberToConsole renders a float64 the way console.log inspects a number, which is NumberToString everywhere but at negative zero: console.log(-0) prints "-0" while String(-0) and `${-0}` are "0". The sign is the only thing telling the two zeros apart, and a program logging one is usually logging it to find out which it got, so the console keeps the sign the string coercion drops.

func NumberToExponential

func NumberToExponential(x float64, digits int) BStr

NumberToExponential returns the JavaScript n.toExponential(digits) of a number, formatting it with one integer digit, exactly digits fraction digits, and a signed decimal exponent. digits must be in 0..100, which the caller guarantees by only lowering a literal in range; the non-finite cases match Number::toString.

func NumberToExponentialDynamic

func NumberToExponentialDynamic(x, digits float64) BStr

NumberToExponentialDynamic is n.toExponential(digits) with a runtime digit count: it range-checks the count against 0..100 and formats through NumberToExponential.

func NumberToFixed

func NumberToFixed(x float64, digits int) BStr

NumberToFixed returns the JavaScript n.toFixed(digits) of a number, formatting it with exactly digits fraction digits. digits must be in 0..100, which the caller guarantees by only lowering a literal in range; a value at or past 1e21 falls back to Number::toString the way the specification requires, and the non-finite cases match it too.

func NumberToFixedDynamic

func NumberToFixedDynamic(x, digits float64) BStr

NumberToFixedDynamic is n.toFixed(digits) with a runtime digit count: it range-checks the count against 0..100 and formats through NumberToFixed.

func NumberToPrecision

func NumberToPrecision(x float64, precision int) BStr

NumberToPrecision returns the JavaScript n.toPrecision(precision) of a number, formatting it with exactly precision significant digits. precision must be in 1..100, which the caller guarantees by only lowering a literal in range; the non-finite cases match Number::toString.

func NumberToPrecisionDynamic

func NumberToPrecisionDynamic(x, precision float64) BStr

NumberToPrecisionDynamic is n.toPrecision(precision) with a runtime precision: it range-checks the precision against 1..100 (zero significant digits is not a valid precision) and formats through NumberToPrecision.

func NumberToString

func NumberToString(x float64) BStr

NumberToString returns the JavaScript String(x) of a number, the decimal Number::toString. It handles the non-finite and zero cases directly and then formats a finite nonzero value from its shortest round-tripping digits.

func NumberToStringRadix

func NumberToStringRadix(x float64, radix int) BStr

NumberToStringRadix returns the JavaScript n.toString(radix) of a number in the given radix. The radix must be in 2..36, which the caller guarantees by only lowering a literal radix in range; a radix of 10 is delegated to NumberToString so the decimal path stays the single source of the base-ten form. The non-finite and zero cases match Number::toString, and a finite nonzero value is converted through the shared dtoa-in-base algorithm.

func NumberToStringRadixDynamic

func NumberToStringRadixDynamic(x, radix float64) BStr

NumberToStringRadixDynamic is n.toString(radix) with a runtime radix: it applies ToInteger to the radix, range-checks it against 2..36, throwing the RangeError JavaScript raises otherwise, and renders through NumberToStringRadix.

func OSArch

func OSArch() BStr

OSArch is os.arch(), Node's name for the processor architecture this binary was built for: x64, arm64, ia32.

func OSDevNull

func OSDevNull() BStr

OSDevNull is os.devNull, the path of the null device. Windows spells it as a device namespace path rather than as a file, which is the spelling Node reports there, so a program that opens it gets the device on both platforms.

func OSEOL

func OSEOL() BStr

OSEOL is os.EOL, the line ending the host platform writes: a carriage return and a line feed on Windows, a line feed everywhere else. It is a function rather than a Go const because the compiled program is built for its target, so the platform is a build-time fact of that binary and not of the compiler.

func OSEndianness

func OSEndianness() BStr

OSEndianness is os.endianness(), the byte order of this processor: LE or BE.

func OSHomedir

func OSHomedir() BStr

OSHomedir is os.homedir(), the current user's home directory.

func OSHostname

func OSHostname() BStr

OSHostname is os.hostname(), the name this machine answers to.

func OSMachine

func OSMachine() BStr

OSMachine is os.machine(), the hardware name uname reports, which is not os.arch(): uname says x86_64 where arch says x64.

func OSPlatform

func OSPlatform() BStr

OSPlatform is os.platform(), the operating system name Node uses: darwin, linux, win32.

func OSRelease

func OSRelease() BStr

OSRelease is os.release(), the kernel release string.

func OSType

func OSType() BStr

OSType is os.type(), the operating system name uname reports rather than the one Node coined: Linux, Darwin, Windows_NT.

func OSVersion

func OSVersion() BStr

OSVersion is os.version(), the kernel version string, which is the product name on Windows because there is no kernel version string there.

func PathBasename

func PathBasename(p BStr) BStr

PathBasename is path.basename with one argument.

func PathBasenameSuffix

func PathBasenameSuffix(p, suffix BStr) BStr

PathBasenameSuffix is path.basename with the optional suffix, which is stripped only when it is not the whole name.

func PathDelimiter

func PathDelimiter() BStr

PathDelimiter is path.delimiter, the character that separates entries in a PATH-style list on this platform.

func PathDirname

func PathDirname(p BStr) BStr

PathDirname is path.dirname.

func PathExtname

func PathExtname(p BStr) BStr

PathExtname is path.extname.

func PathJoin

func PathJoin(parts ...BStr) BStr

PathJoin is path.join: the parts are joined with the platform separator and the result normalized. With no parts, or only empty ones, it is ".".

func PathNormalize

func PathNormalize(p BStr) BStr

PathNormalize is path.normalize.

func PathRelative

func PathRelative(from, to BStr) BStr

PathRelative is path.relative, the path that walks from one to the other.

func PathResolve

func PathResolve(parts ...BStr) BStr

PathResolve is path.resolve, which walks its arguments from the right until it has an absolute path, falling back to the working directory.

func PathSep

func PathSep() BStr

PathSep is path.sep, the character that separates segments on this platform.

func PathToNamespacedPath

func PathToNamespacedPath(p BStr) BStr

PathToNamespacedPath is path.toNamespacedPath, which is the identity everywhere except Windows.

func PlusToString

func PlusToString(v Value) BStr

PlusToString coerces an operand of the + operator's string-concatenation branch: ToPrimitive with the default hint (the hint + passes, per the AdditionOperator spec) and then ToString on the resulting primitive. It differs from ToString on exactly one kind, an object whose valueOf, toString, or Symbol.toPrimitive reads the hint: + must ask for "default", where a plain ToString asks for "string", so { valueOf: () => 42, toString: () => "s" } concatenates as "42", not "s". Every primitive is already primitive, so ToPrimitive returns it unchanged and this matches ToString for a number, string, boolean, bigint, null, or undefined; a symbol still throws in the trailing ToString the way "" + Symbol() does.

func ReadFileSyncUTF8

func ReadFileSyncUTF8(pathArg BStr) BStr

ReadFileSyncUTF8 reads the whole file at path and returns its contents as a string, the lowering of fs.readFileSync(path, "utf8"). The bytes are decoded as UTF-8 into a BStr, which keeps the UTF-8 fast path, matching the encoding argument the ambient declaration fixes. A read failure (a missing file, a permission denial) is a thrown error in Node, surfaced here as a panic.

func StringCoerce

func StringCoerce(v Value) BStr

StringCoerce implements the String built-in called as a function, String(v), which differs from abstract ToString on exactly one kind: a symbol renders as its descriptive string "Symbol(desc)" (SymbolDescriptiveString) rather than throwing, the special case the String constructor makes for a symbol argument. Every other value coerces through the ordinary ToString, so a template substitution or a bare concatenation (which take ToString directly) still throws on a symbol while String(sym) reports its description.

func StringRaw

func StringRaw(strings Value, subs ...Value) BStr

StringRaw is String.raw, the built-in tag that answers the template's raw text with the substitutions spliced in, so the escapes the cooked strings resolved stay as they were written. It reads the raw array off whatever object it is given rather than off a template object specifically, which is what lets String.raw({ raw: parts }, ...) work on a hand-built object, the spelling a tag reaches for when it wants the built-in to do the splicing.

The walk is the spec's: one raw segment, then one substitution, until the last segment, which is not followed by one. A substitution the caller did not pass contributes nothing, so a call with fewer substitutions than gaps runs the segments together rather than write undefined between them.

The result is a BStr rather than a boxed value because String.raw's return type is string whatever it is given, so the emitted expression sits in a static string slot and boxes only where the surrounding lowering decides it should.

func StringRawArgs

func StringRawArgs(strings, subs Value) BStr

StringRawArgs is String.raw with its substitutions gathered in one array-like value rather than spelled out one by one, which is the shape String.raw(o, ...vals) takes when vals is a rest parameter: the count is a run-time fact, so there is no fixed argument list for the call to write. It reads the substitutions off the array the same way the spread would have supplied them and hands them to StringRaw, so the two spellings answer the same string.

func Tmpdir

func Tmpdir() BStr

Tmpdir returns the operating system's default directory for temporary files, the lowering of os.tmpdir. It reads the same environment the platform uses (TMPDIR and its kin), so a compiled program lands its temp tree where a Node program would.

func ToString

func ToString(v Value) BStr

ToString implements the ToString abstract operation. undefined and null spell their names, a boolean and a number go through the same stringify String(x) uses so the two agree, a string is itself, and an object stringifies through its primitive: an array joins its elements with commas and a plain object is "[object Object]", which is what the engine prints.

func TypedArrayClassTag

func TypedArrayClassTag(recv any, name string) BStr

TypedArrayClassTag returns the "[object <Name>]" tag Object.prototype.toString.call reads off a typed array, built from the concrete constructor name the compiler knows statically. The view is taken and discarded so the borrowed toString evaluates its argument the way the language does and the caller's binding reads as a use; the name comes from the compiler rather than the Go element type, since a single element width does not name one JS constructor (a uint8 element backs both Uint8Array and Uint8ClampedArray).

func (BStr) AtOpt

func (s BStr) AtOpt(i float64) Opt[BStr]

AtOpt returns the one-code-unit string at the relative index i, matching String.prototype.at. Its declared type is string | undefined, so it returns an Opt[BStr]: a present optional holding the single-code-unit string when the resolved index falls in range, and the undefined optional otherwise. The index is coerced to an integer the same way CharAt coerces it, then a negative index counts back from the end. An index still outside [0, length) reads as the undefined optional rather than the empty string CharAt yields, matching at's out-of-range result. The single unit may be a lone surrogate, so it is rebuilt through FromUTF16, which preserves a surrogate FromGoString could not.

func (BStr) CharAt

func (s BStr) CharAt(i float64) BStr

CharAt returns the one-code-unit string at index i, matching String.prototype.charAt. The index is coerced to an integer the same way CharCodeAt coerces it, and an index outside [0, length) yields the empty string rather than a panic. The single code unit may be a lone surrogate (half of an astral character), so the result is built from the raw unit through FromUTF16, which preserves a surrogate that FromGoString could not, keeping charAt(0) of an astral character the exact high surrogate JavaScript returns.

func (BStr) CharAtI

func (s BStr) CharAtI(i int) BStr

CharAtI reads the one-code-unit string at a Go int index, the integer-index form of CharAt the lowerer emits when the checker proved the index expression is an integer. The float truncation and NaN fold CharAt runs are then dead work, so this form takes the index already narrowed. The bounds check and the empty-string out-of-range result are the same as CharAt, so the two reads agree on every index; only the index type differs.

func (BStr) CharCodeAt

func (s BStr) CharCodeAt(i float64) float64

CharCodeAt returns the UTF-16 code unit at index i as a number, matching String.prototype.charCodeAt. The index is coerced to an integer the way JavaScript does (NaN becomes 0, a fraction truncates toward zero), and an index outside [0, length) yields NaN, not a zero or a panic. The result is a float64 because the code unit is a JavaScript number and JavaScript has no character type. The range test is done on the float before the int conversion so a huge index cannot overflow int on the way in.

func (BStr) CodePointAtOpt

func (s BStr) CodePointAtOpt(i float64) Opt[float64]

CodePointAtOpt returns the Unicode code point that begins at code-unit index i as a number, matching String.prototype.codePointAt. Its declared type is number | undefined, so it returns an Opt[float64]: the undefined optional when the index is outside [0, length), and the present optional otherwise. When the unit at i is a high surrogate and the next unit is a low surrogate, the two combine into the single astral code point they encode, which is the difference from charCodeAt; a high surrogate with no following low half, a lone low surrogate, or any BMP unit reads as that unit's own value. The index is coerced to an integer the same way charCodeAt coerces it, and the range test is on the float before the int conversion so a huge index cannot overflow int on the way in.

func (BStr) CodePoints

func (s BStr) CodePoints() []BStr

CodePoints returns the string's Unicode code points in order, each as its own one- or two-code-unit string. This is what a for...of loop over a string iterates: JavaScript steps a string by code point, so a surrogate pair (an astral character) yields as a single two-unit element and every other unit, including a lone surrogate, yields as its own one-unit element. It is the string counterpart of an array's Elems, the slice a ranged Go loop walks. A pair is rebuilt through FromUTF16 so a lone surrogate that UTF-8 cannot represent is preserved rather than replaced.

func (BStr) Compare

func (a BStr) Compare(b BStr) int

Compare returns -1, 0, or 1 as a orders before, equal to, or after b, comparing code unit by code unit, which is how JavaScript's relational operators (<, <=, >, >=) order two strings (the Abstract Relational Comparison over the UTF-16 views). The comparison is on code units, not code points or runes, so it matches JavaScript even where a Go string < would differ: an astral character sits above U+E000..U+FFFF in code-point order but its leading surrogate (U+D800..U+DBFF) orders below them, and JavaScript compares the surrogate. The shorter string orders first when it is a prefix of the longer.

func (BStr) ConcatN

func (s BStr) ConcatN(rest ...BStr) BStr

ConcatN returns the receiver followed by every argument in order, the lowering of str.concat(a, b, ...). It stays on the UTF-8 fast path while the receiver and every argument seen so far are UTF-8, appending bytes; the first argument that carries a raw code-unit backing switches the whole result to the code-unit form so a lone surrogate survives, matching how Concat picks a backing. With no arguments it returns the receiver unchanged, which is what concat() with no arguments does.

func (BStr) EndsWith

func (s BStr) EndsWith(suffix BStr, endPosition ...float64) bool

EndsWith reports whether s has suffix ending at an optional end position, matching String.prototype.endsWith. Where startsWith takes the index the match begins at, endsWith takes the index it ends at, which defaults to the length; the suffix is matched in the window that ends there. The end position is clamped into [0, length], and a suffix longer than that window is not a match. It compares code units so it agrees with JavaScript on astral text.

func (BStr) Equal

func (a BStr) Equal(b BStr) bool

Equal reports whether a and b are the same string, code unit for code unit, which is JavaScript string === and == on two strings. When both are on the UTF-8 fast path the bytes compare directly, since equal UTF-8 means equal code units; otherwise the code-unit views compare, so two strings that differ only in how they are backed still compare equal.

func (BStr) Includes

func (s BStr) Includes(search BStr, position ...float64) bool

Includes reports whether search occurs at or after an optional start position, matching String.prototype.includes. It is defined in terms of IndexOf, so it shares the code-unit search, the optional position, and the empty-string rule (an empty search is found at the clamped position, so Includes returns true).

func (BStr) IndexOf

func (s BStr) IndexOf(search BStr, position ...float64) float64

IndexOf returns the code-unit index of the first occurrence of search at or after an optional start position, or -1 if it does not occur, matching String.prototype.indexOf. The position is optional, so the method is variadic: the lowered call passes exactly the arguments the source did. A position is run through the substring clamp (ToInteger, then into [0, length], with NaN going to 0), and the scan begins there. The search is code-unit-wise over the UTF-16 view so it agrees with JavaScript on astral text and lone surrogates, and an empty search string matches at the clamped position the way JavaScript defines it. The result is a float64 because it is a JavaScript number.

func (BStr) IsWellFormed

func (s BStr) IsWellFormed() bool

IsWellFormed reports whether the string contains no lone surrogate code unit, matching String.prototype.isWellFormed. In a well-formed string every high surrogate (D800..DBFF) is immediately followed by a low surrogate (DC00..DFFF) and every low surrogate follows a high one; a surrogate that breaks that pairing is lone and makes the string ill-formed. A string on the UTF-8 fast path cannot hold a lone surrogate, because UTF-8 cannot encode one, so it answers true with no scan; only a string with a raw code-unit backing is walked.

func (BStr) LastIndexOf

func (s BStr) LastIndexOf(search BStr, position ...float64) float64

LastIndexOf returns the code-unit index of the last occurrence of search that begins at or before an optional position, or -1 if it does not occur, matching String.prototype.lastIndexOf. It scans backward, so it reports the greatest matching index rather than the least. The position defaults to the end and, unlike indexOf, a NaN position also means the end (the specification coerces a missing or NaN position to +Infinity here), so only a real number narrows the window. An empty search string matches at the clamped position. The search is code-unit-wise so it agrees with JavaScript on astral text and lone surrogates.

func (BStr) Length

func (s BStr) Length() float64

Length returns the number of UTF-16 code units, String.prototype.length. It is a JavaScript number, so it is returned as a float64 to match the lowered type of a number without a conversion at the use site.

func (BStr) Normalize

func (s BStr) Normalize(form ...BStr) BStr

Normalize returns the string in the requested Unicode normalization form, matching String.prototype.normalize. The form defaults to NFC when the argument is omitted, and a form that is not one of NFC, NFD, NFKC, or NFKD is a RangeError, the same throw the method raises in the engine.

A well-formed string crosses to UTF-8, normalizes, and crosses back in one step. A string that holds a lone surrogate cannot round-trip through UTF-8, since the crossing would replace the surrogate with U+FFFD, so it takes a slower path that normalizes each maximal well-formed run and keeps every lone surrogate between the runs untouched. That is faithful because a lone surrogate is a starter with combining class zero, so it always sits on a normalization boundary and never combines with the text around it.

func (BStr) PadEnd

func (s BStr) PadEnd(targetLength float64, pad ...BStr) BStr

PadEnd pads the end of s with pad until the result is targetLength code units long, matching String.prototype.padEnd. It shares every rule with PadStart and differs only in appending the filler after s rather than before it.

func (BStr) PadStart

func (s BStr) PadStart(targetLength float64, pad ...BStr) BStr

PadStart pads the front of s with pad until the result is targetLength code units long, matching String.prototype.padStart. targetLength is coerced to an integer JavaScript-style (NaN becomes 0, a fraction truncates), and if it is not longer than s the receiver is returned unchanged, which also covers a negative target. The pad string is optional and defaults to a single space; an explicitly empty pad string produces no filler, so the receiver comes back unchanged. The filler is the pad repeated and then truncated to the exact fill length on the code-unit view, so truncating in the middle of an astral pad can emit a lone surrogate, exactly as JavaScript does.

func (BStr) Repeat

func (s BStr) Repeat(count float64) BStr

Repeat returns s concatenated count times, String.prototype.repeat. count is coerced to an integer the way JavaScript does (a fraction truncates toward zero, NaN becomes 0), and a count that is negative or not finite throws the RangeError JavaScript raises, "Invalid count value: <count>", the same Throw(NewRangeError(...)) every other range-checked runtime method uses so a try/catch or assert.throws catches it. A count of zero, or an empty receiver, yields the empty string, and a count of one returns the receiver unchanged. The UTF-8 fast path is kept when the receiver is on it, since repeating valid UTF-8 stays valid UTF-8.

func (BStr) Replace

func (s BStr) Replace(search, replacement BStr) BStr

Replace returns s with the first occurrence of search replaced by the expansion of replacement, matching String.prototype.replace called with two strings. (The regexp pattern and the replacer-function forms are a later slice.) The search is code-unit-wise, so it agrees with JavaScript on astral text and lone surrogates, and when search does not occur the receiver is returned unchanged with no allocation. An empty search matches at the front, so the replacement is inserted there. The replacement string carries the ECMAScript substitution patterns: see appendSubstitution.

func (BStr) ReplaceAll

func (s BStr) ReplaceAll(search, replacement BStr) BStr

ReplaceAll returns s with every non-overlapping occurrence of search replaced by the expansion of replacement, matching String.prototype.replaceAll called with two strings. It shares Replace's code-unit search and substitution rules. An empty search matches at every position including both ends, so the replacement is woven between every code unit, matching how JavaScript expands "abc".replaceAll("", "-") to "-a-b-c-". When search does not occur the receiver is returned unchanged.

func (BStr) Slice

func (s BStr) Slice(args ...float64) BStr

Slice returns the substring between two code-unit indices, matching String.prototype.slice. Both arguments are optional (start defaults to 0, end to the length), which is why the method is variadic: the lowered call passes exactly the arguments the source did, and the count selects the defaults. A negative index counts from the end, an index past the end clamps to the end, and a start at or after the end yields the empty string. Working on the code-unit view means a slice can land between the halves of an astral character and return a lone surrogate, exactly as JavaScript does.

func (BStr) Split

func (s BStr) Split(sep BStr, limit ...float64) *Array[BStr]

Split divides the string on each occurrence of a string separator and returns the pieces, String.prototype.split(separator, limit) in its string-separator form (the regexp form hands back in the compiler). The pieces are cut on code-unit boundaries, so a separator that occurs at the start or end yields an empty leading or trailing piece and a separator that does not occur yields the whole string as the one piece, exactly as JavaScript does. An empty separator splits into single code units, and the empty string split by an empty separator is the empty array, the two edges the specification calls out.

The optional limit is variadic so one Go signature covers split(sep) and split(sep, n): it is coerced through ToUint32 the way the specification's split caps the result, a limit of zero yields the empty array, and a limit shorter than the piece count truncates the result to that many leading pieces (the rest are not rejoined). An absent limit leaves the split unbounded.

func (BStr) StartsWith

func (s BStr) StartsWith(prefix BStr, position ...float64) bool

StartsWith reports whether s has prefix starting at an optional position, matching String.prototype.startsWith. The position is optional, so the method is variadic; it is clamped into [0, length] and the prefix is matched there. It compares code units so it agrees with JavaScript on astral text, and a prefix that would run past the end is not a match.

func (BStr) StringIndexValue

func (s BStr) StringIndexValue(i float64) Value

StringIndexValue reads s[i] with the String exotic object's own-property semantics (10.4.3.1 [[GetOwnProperty]]): a canonical in-range integer index yields the one-code-unit string at that position, and every other numeric index — a negative, a fractional, a NaN or an infinity, or one at or past the length — is not an own property of the string and reads as undefined, not the empty string CharAt yields for the typed slot. It backs the boxed form of a bracket read s[i], where the result flows into a dynamic sink that can tell undefined from "" (an assert.sameValue against undefined, a console.log), so the read matches Node rather than the string slot's zero value. The single unit may be a lone surrogate, so it is rebuilt through FromUTF16.

func (BStr) Substr

func (s BStr) Substr(args ...float64) BStr

Substr returns a run of code units of a given length starting at an index, matching the legacy String.prototype.substr. It differs from Slice and Substring in taking a start and a count rather than two bounds: a negative start counts from the end and clamps at 0, an omitted length runs to the end of the string, and a negative or zero length yields the empty string. It is variadic so one signature covers the one- and two-argument forms, and it works on the code-unit view so a cut can land inside an astral pair and return a lone surrogate the way JavaScript does.

func (BStr) Substring

func (s BStr) Substring(args ...float64) BStr

Substring returns the substring between two code-unit indices, matching String.prototype.substring. It differs from Slice in its edge handling: a negative or NaN argument becomes 0 rather than counting from the end, and if start is greater than end the two are swapped rather than yielding the empty string. It is variadic for the same reason Slice is.

func (BStr) ToGoString

func (s BStr) ToGoString() string

ToGoString returns the UTF-8 view of the string, the transcode a lowered string takes when it is handed to a Go library or node: API that wants a Go string (05_type_lowering section 5, bento.ToGoString). A string that holds a lone surrogate cannot be represented in UTF-8, so each unpaired surrogate becomes the U+FFFD replacement, the same lossy mapping the platform makes when such a string is written to a byte sink.

func (BStr) ToLowerCase

func (s BStr) ToLowerCase() BStr

ToLowerCase returns the string with every character replaced by its full lowercase mapping, including the Final_Sigma context (String.prototype.toLowerCase).

func (BStr) ToUpperCase

func (s BStr) ToUpperCase() BStr

ToUpperCase returns the string with every character replaced by its full uppercase mapping (String.prototype.toUpperCase).

func (BStr) ToWellFormed

func (s BStr) ToWellFormed() BStr

ToWellFormed returns the string with every lone surrogate replaced by U+FFFD, matching String.prototype.toWellFormed. A well-formed string is returned unchanged, so it keeps its backing and costs no allocation; only a string that holds a lone surrogate is rebuilt, with each unpaired surrogate swapped for the replacement character and every valid pair copied through untouched.

func (BStr) Trim

func (s BStr) Trim() BStr

Trim removes leading and trailing whitespace, matching String.prototype.trim. The whitespace set is the exact ECMAScript one (WhiteSpace plus LineTerminator, isStringWhiteSpace below), not Go's unicode.IsSpace, which disagrees at the edges (Go counts U+0085 as space and not U+FEFF, JavaScript does the reverse). When nothing is trimmed the receiver is returned unchanged so a string with no surrounding whitespace keeps its backing and allocates nothing.

func (BStr) TrimEnd

func (s BStr) TrimEnd() BStr

TrimEnd removes trailing whitespace only, matching String.prototype.trimEnd, over the same whitespace set as Trim.

func (BStr) TrimStart

func (s BStr) TrimStart() BStr

TrimStart removes leading whitespace only, matching String.prototype.trimStart, over the same whitespace set as Trim.

type BigInt

type BigInt struct {
	// contains filtered or unexported fields
}

BigInt is a JavaScript bigint. It is its own type, not a bare big.Int, so the value model owns bigint identity and a later small-int fast path can slot in without changing any caller: the first cut is just big.Int for correctness.

func (*BigInt) Int

func (b *BigInt) Int() *big.Int

Int is the arbitrary-precision value, for a caller that needs the underlying math/big.Int, such as the bridge marshaling a bigint back to a Go integer.

func (*BigInt) IsZero

func (b *BigInt) IsZero() bool

IsZero reports whether the bigint is 0n, the falsy bigint.

func (*BigInt) String

func (b *BigInt) String() string

String renders a bigint as its decimal digits with no suffix, the value String(b) and a `${b}` template produce: a bigint's ToString is just its digits, the "n" suffix belongs only to how console.log inspects a value, not to string coercion.

type BigIntArray

type BigIntArray[T bigArrayElem] struct {
	// contains filtered or unexported fields
}

BigIntArray is bento's runtime representation of a BigInt64Array or a BigUint64Array, the two typed arrays whose element is a bigint rather than a Number (16 §6.3). Each element is a fixed 64-bit two's-complement integer, so the storage is a Go []int64 or []uint64, and a read widens the element to the arbitrary-precision *big.Int a JavaScript bigint is while a write truncates the bigint to 64 bits the way BigInt.asIntN(64) and asUintN(64) do. It is the bigint sibling of the numeric TypedArray: the numeric family reads and writes through float64, which a bigint cannot ride, so the bigint pair takes its own header that reads and writes through *big.Int.

Like every other family member a BigIntArray is a view, not the storage: it records the ArrayBuffer it reads, the byte offset it starts at, and its element length. It does not cache an element slice; live forms one with unsafe.Slice over the buffer's current bytes on each access, so two views over one buffer observe each other's writes, and because both bigint elements are eight bytes wide a bigint view aliases a Float64Array view of the same buffer byte for byte. The length is consulted against the buffer's live state through liveLen, the same clamp the numeric family takes, so a view over a detached buffer reads as zero-length. The store and load functions carry the per-kind truncation and widening so the generic core stays one type.

func BigInt64ArrayOf

func BigInt64ArrayOf(elems ...*big.Int) *BigIntArray[int64]

func BigInt64ArrayView

func BigInt64ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *BigIntArray[int64]

func BigUint64ArrayOf

func BigUint64ArrayOf(elems ...*big.Int) *BigIntArray[uint64]

func BigUint64ArrayView

func BigUint64ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *BigIntArray[uint64]

func NewBigInt64Array

func NewBigInt64Array(length float64) *BigIntArray[int64]

func NewBigUint64Array

func NewBigUint64Array(length float64) *BigIntArray[uint64]

func (*BigIntArray[T]) At

func (a *BigIntArray[T]) At(i float64) *big.Int

At reads the element a JavaScript index expression a[i] selects, widened to the *big.Int a bigint read hands out. Only a canonical integer index inside the array names an element; an out-of-range or non-canonical index reads as 0n here rather than the undefined the spec gives, the covered subset for the bigint read path, since At's result is a *big.Int. A read that flows into a dynamic slot takes GetIndex instead, which does answer undefined for those indices.

func (*BigIntArray[T]) Buffer

func (a *BigIntArray[T]) Buffer() *ArrayBuffer

Buffer is the ArrayBuffer the view aliases, the .buffer getter, the same backing store every other view of the buffer holds.

func (*BigIntArray[T]) ByteLength

func (a *BigIntArray[T]) ByteLength() float64

ByteLength is the view's span in bytes, the .byteLength getter: the element count times eight, the run of buffer bytes the view aliases.

func (*BigIntArray[T]) ByteOffset

func (a *BigIntArray[T]) ByteOffset() float64

ByteOffset is the byte the view starts at within its buffer, the .byteOffset getter, a Number to match the property's type.

func (*BigIntArray[T]) BytesPerElement

func (a *BigIntArray[T]) BytesPerElement() float64

BytesPerElement is the element width in bytes, the instance BYTES_PER_ELEMENT property, eight for a bigint element. It is a method so a read keeps the receiver referenced rather than folding to a literal that would orphan the binding.

func (*BigIntArray[T]) GetIndex

func (a *BigIntArray[T]) GetIndex(i float64) Value

GetIndex reads the element a JavaScript index selects as a boxed Value, the form a bigint read takes when it flows into a dynamic slot. It answers the element as a boxed bigint for a canonical in-range index and the undefined singleton for an out-of-range or non-canonical one, so a[100] and a[1.5] read as undefined the way the spec requires, which the *big.Int At cannot express.

func (*BigIntArray[T]) Len

func (a *BigIntArray[T]) Len() float64

Len is the array's length in elements, a Number to match the type the checker gives .length and to compose with the numeric path with no conversion.

func (*BigIntArray[T]) SetAt

func (a *BigIntArray[T]) SetAt(i float64, v *big.Int)

SetAt writes the element a JavaScript assignment a[i] = v stores, truncating the bigint to the element's 64-bit width the way asIntN(64) and asUintN(64) do, so a value outside the element's range wraps exactly as JavaScript does. Only a canonical integer index inside the array names an element; a write to an out-of-range or non-canonical index is dropped, the no-op the spec requires.

func (*BigIntArray[T]) ToValue

func (a *BigIntArray[T]) ToValue() Value

ToValue is the bigint half of the same crossing.

type Combinable

type Combinable interface {
	// contains filtered or unexported methods
}

Combinable is the face a promise shows a combinator that watches promises of more than one element type at once. All takes an array, so every input shares one T; a Promise.all over a tuple does not, and `Promise.all([fetchUser(), fetchPosts()])` combines a Promise<User> with a Promise<Post[]> in one call. A Go slice cannot hold both, and a type parameter list cannot vary in length, so the inputs cross as this element-type-erased interface instead and the fulfilled values are read back through the caller's own closure, which is the one place that still knows each T.

The methods are unexported, so only a value.Promise can be one and no foreign type can claim to be a promise by shape.

type DataView

type DataView struct {
	// contains filtered or unexported fields
}

DataView is bento's runtime representation of a JavaScript DataView, the view that reads and writes an ArrayBuffer at arbitrary byte offsets with an explicit endianness, independent of any element alignment (25 §25.3). Unlike a typed array, which pins one element width and reads through a naturally aligned slice, a DataView carries no element type: every get and set names its own width and byte order at the call, so one view over a buffer can read a big-endian int32 at byte 1 and a little-endian float64 at byte 5 over the same bytes a typed array would see.

Like every other view it is not the storage: it records the ArrayBuffer it reads, the byte offset it starts at, and its byte length, so it aliases the buffer's bytes and observes writes made through the buffer or any other view of it. The byte length is consulted against the buffer's live state through liveByteLength rather than frozen at construction, because the buffer can be detached or resized while the view points at it: a detached buffer, or a shrink that puts the view's range past the buffer's new end, turns the view out of bounds, which every access reports as the TypeError the spec throws.

func NewDataView

func NewDataView(buffer *ArrayBuffer, byteOffset float64, byteLength ...float64) *DataView

NewDataView builds a DataView over an existing ArrayBuffer, the lowering of new DataView(buffer, byteOffset, byteLength) and its shorter forms (25 §25.3.2). The byte offset defaults to zero when the call omits it and the byte length runs from the offset to the end of the buffer when omitted. The offset is a ToIndex value, so a negative or too-large offset is a RangeError; a detached buffer is a TypeError; and an offset or an explicit length that runs past the buffer is a RangeError, the throws the spec raises at construction.

func (*DataView) Buffer

func (d *DataView) Buffer() *ArrayBuffer

Buffer is the ArrayBuffer the view aliases, the .buffer getter, the same backing store every other view of the buffer holds, so a comparison of two views' buffers by identity holds.

func (*DataView) ByteLength

func (d *DataView) ByteLength() float64

ByteLength is the view's span in bytes, the .byteLength getter, a Number. The getter (25 §25.3.4.1) throws a TypeError when the view is out of bounds, the same witness check ByteOffset makes; a length-tracking view that still fits reports its live span over the buffer's current size.

func (*DataView) ByteOffset

func (d *DataView) ByteOffset() float64

ByteOffset is the byte the view starts at within its buffer, the .byteOffset getter, a Number to match the property's type. The getter (25 §25.3.4.2) reads the view's witness record and throws a TypeError when IsViewOutOfBounds is true, so a detached buffer or a shrink that has dropped the view's range is a TypeError here rather than a zero.

func (*DataView) GetBigInt64

func (d *DataView) GetBigInt64(byteOffset float64, littleEndian ...bool) *big.Int

GetBigInt64 reads the signed 64-bit integer at the offset with the given endianness as a bigint, DataView.prototype.getBigInt64 (25 §25.3.4). A bigint lowers to a *big.Int, so the read widens the stored two's-complement value into one rather than the Number the numeric getters return, since a 64-bit integer does not fit a Number without loss.

func (*DataView) GetBigUint64

func (d *DataView) GetBigUint64(byteOffset float64, littleEndian ...bool) *big.Int

GetBigUint64 reads the unsigned 64-bit integer at the offset with the given endianness as a bigint, DataView.prototype.getBigUint64, the unsigned sibling of GetBigInt64 that keeps the full 64-bit magnitude a signed value could not.

func (*DataView) GetFloat16

func (d *DataView) GetFloat16(byteOffset float64, littleEndian ...bool) float64

GetFloat16 reads the half-precision float at the offset with the given endianness, DataView.prototype.getFloat16 (25 §25.3.4), decoding the two stored bytes to the Number the read hands out.

func (*DataView) GetFloat32

func (d *DataView) GetFloat32(byteOffset float64, littleEndian ...bool) float64

GetFloat32 reads the single-precision float at the offset with the given endianness, DataView.prototype.getFloat32, widening the stored float32 to a Number.

func (*DataView) GetFloat64

func (d *DataView) GetFloat64(byteOffset float64, littleEndian ...bool) float64

GetFloat64 reads the double-precision float at the offset with the given endianness, DataView.prototype.getFloat64. A Number is a float64, so the read is the stored value with no widening.

func (*DataView) GetInt8

func (d *DataView) GetInt8(byteOffset float64) float64

GetInt8 reads the signed byte at the offset, DataView.prototype.getInt8. It is a single byte, so it carries no endianness, and it widens the stored int8 to the Number the read hands out.

func (*DataView) GetInt16

func (d *DataView) GetInt16(byteOffset float64, littleEndian ...bool) float64

GetInt16 reads the signed 16-bit integer at the offset with the given endianness, DataView.prototype.getInt16, widening the result to a Number.

func (*DataView) GetInt32

func (d *DataView) GetInt32(byteOffset float64, littleEndian ...bool) float64

GetInt32 reads the signed 32-bit integer at the offset with the given endianness, DataView.prototype.getInt32, widening the result to a Number.

func (*DataView) GetUint8

func (d *DataView) GetUint8(byteOffset float64) float64

GetUint8 reads the unsigned byte at the offset, DataView.prototype.getUint8, the unsigned sibling of GetInt8.

func (*DataView) GetUint16

func (d *DataView) GetUint16(byteOffset float64, littleEndian ...bool) float64

GetUint16 reads the unsigned 16-bit integer at the offset with the given endianness, DataView.prototype.getUint16.

func (*DataView) GetUint32

func (d *DataView) GetUint32(byteOffset float64, littleEndian ...bool) float64

GetUint32 reads the unsigned 32-bit integer at the offset with the given endianness, DataView.prototype.getUint32.

func (*DataView) SetBigInt64

func (d *DataView) SetBigInt64(byteOffset float64, v *big.Int, littleEndian ...bool)

SetBigInt64 writes v as a signed 64-bit integer at the offset with the given endianness, DataView.prototype.setBigInt64 (25 §25.3.4). The value is a bigint, which lowers to a *big.Int; the store reduces it modulo 2^64 and lays down the low 64 bits, the same bytes a setBigUint64 of the congruent unsigned value would.

func (*DataView) SetBigUint64

func (d *DataView) SetBigUint64(byteOffset float64, v *big.Int, littleEndian ...bool)

SetBigUint64 writes v as an unsigned 64-bit integer at the offset with the given endianness, DataView.prototype.setBigUint64, the unsigned sibling of SetBigInt64. The stored bytes are the low 64 bits of the value, so it and SetBigInt64 write the same bytes for congruent inputs.

func (*DataView) SetFloat16

func (d *DataView) SetFloat16(byteOffset float64, v float64, littleEndian ...bool)

SetFloat16 writes v as a half-precision float at the offset with the given endianness, DataView.prototype.setFloat16 (25 §25.3.4), encoding the Number to the two stored bytes.

func (*DataView) SetFloat32

func (d *DataView) SetFloat32(byteOffset float64, v float64, littleEndian ...bool)

SetFloat32 writes v as a single-precision float at the offset with the given endianness, DataView.prototype.setFloat32, narrowing the Number to a float32 before it stores the four bytes.

func (*DataView) SetFloat64

func (d *DataView) SetFloat64(byteOffset float64, v float64, littleEndian ...bool)

SetFloat64 writes v as a double-precision float at the offset with the given endianness, DataView.prototype.setFloat64. A Number is a float64, so the store lays down the value's bits with no narrowing.

func (*DataView) SetInt8

func (d *DataView) SetInt8(byteOffset float64, v float64)

SetInt8 writes v as a signed byte at the offset, DataView.prototype.setInt8. The value is a Number the store reduces with ECMAScript ToInt8, the same modulo wrap a write into an Int8Array element applies, so 256 stores 0 and -1 stores -1. One byte carries no endianness.

func (*DataView) SetInt16

func (d *DataView) SetInt16(byteOffset float64, v float64, littleEndian ...bool)

SetInt16 writes v as a signed 16-bit integer at the offset with the given endianness, DataView.prototype.setInt16, reducing the Number with ToInt16 before it lays the two bytes down in the chosen byte order.

func (*DataView) SetInt32

func (d *DataView) SetInt32(byteOffset float64, v float64, littleEndian ...bool)

SetInt32 writes v as a signed 32-bit integer at the offset with the given endianness, DataView.prototype.setInt32, reducing the Number with ToInt32.

func (*DataView) SetUint8

func (d *DataView) SetUint8(byteOffset float64, v float64)

SetUint8 writes v as an unsigned byte at the offset, DataView.prototype.setUint8, reducing the Number with ToUint8, the unsigned sibling of SetInt8.

func (*DataView) SetUint16

func (d *DataView) SetUint16(byteOffset float64, v float64, littleEndian ...bool)

SetUint16 writes v as an unsigned 16-bit integer at the offset with the given endianness, DataView.prototype.setUint16, reducing the Number with ToUint16.

func (*DataView) SetUint32

func (d *DataView) SetUint32(byteOffset float64, v float64, littleEndian ...bool)

SetUint32 writes v as an unsigned 32-bit integer at the offset with the given endianness, DataView.prototype.setUint32, reducing the Number with ToUint32.

func (*DataView) ToValue

func (d *DataView) ToValue() Value

ToValue boxes a data view. A view is a window onto a buffer rather than storage of its own, so the box carries the view and reaches the bytes through it, which is what makes a write through the box show up in every other view of the same buffer.

type Date

type Date struct {
	// contains filtered or unexported fields
}

Date is bento's runtime representation of a JavaScript Date. It holds the time value, the milliseconds since the epoch, and nothing else: every read a Date answers is derived from that one number. A NaN time value is the Invalid Date, the state a construction from an out-of-range or unparsable input lands in.

func NewDate

func NewDate() *Date

NewDate builds a Date for the current moment, the lowering of new Date(). It reads the same wall clock the rest of the runtime does and truncates to whole milliseconds, the resolution a time value has.

func NewDateFromComponents

func NewDateFromComponents(args ...float64) *Date

NewDateFromComponents builds a Date from a local calendar reading, the lowering of new Date(year, month, day, ...). The reading is local time, not UTC, which is the one thing about this constructor that surprises people: new Date(2023, 0, 1) is midnight where the program runs, and its ISO string is a different day west of Greenwich.

func NewDateFromMillis

func NewDateFromMillis(ms float64) *Date

NewDateFromMillis builds a Date for a time value, the lowering of new Date(ms). The value is clipped the way the specification's TimeClip does: a non-finite or out-of-range number, and a fraction, each land where they must, which is the Invalid Date for the first two and the truncated integer for the third.

func NewDateFromString

func NewDateFromString(s BStr) *Date

NewDateFromString builds a Date from a string, the lowering of new Date(s). A string that names no date gives the Invalid Date rather than throwing, which is what makes a bad date something a program has to check for with isNaN rather than catch.

func (*Date) GetDate

func (d *Date) GetDate() float64

func (*Date) GetDay

func (d *Date) GetDay() float64

func (*Date) GetFullYear

func (d *Date) GetFullYear() float64

The local calendar getters. Each reports the component the local zone sees, and each gives NaN for the Invalid Date, which is what makes every read of an invalid date propagate rather than quietly reporting 1970.

func (*Date) GetHours

func (d *Date) GetHours() float64

func (*Date) GetMilliseconds

func (d *Date) GetMilliseconds() float64

func (*Date) GetMinutes

func (d *Date) GetMinutes() float64

func (*Date) GetMonth

func (d *Date) GetMonth() float64

func (*Date) GetSeconds

func (d *Date) GetSeconds() float64

func (*Date) GetTime

func (d *Date) GetTime() float64

GetTime is the time value, the lowering of date.getTime(). It is NaN for the Invalid Date, which is what makes an invalid date compare false against everything including itself.

func (*Date) GetTimezoneOffset

func (d *Date) GetTimezoneOffset() float64

GetTimezoneOffset is the difference between local time and UTC in minutes, the lowering of date.getTimezoneOffset(). The sign is the specification's, not the one a zone name suggests: a zone ahead of UTC reports a negative number, because the value is what you add to local time to get UTC.

func (*Date) GetUTCDate

func (d *Date) GetUTCDate() float64

func (*Date) GetUTCDay

func (d *Date) GetUTCDay() float64

func (*Date) GetUTCFullYear

func (d *Date) GetUTCFullYear() float64

The UTC calendar getters. They read the same components without the zone shift, so a program that wants a stable answer across machines reaches for these.

func (*Date) GetUTCHours

func (d *Date) GetUTCHours() float64

func (*Date) GetUTCMilliseconds

func (d *Date) GetUTCMilliseconds() float64

func (*Date) GetUTCMinutes

func (d *Date) GetUTCMinutes() float64

func (*Date) GetUTCMonth

func (d *Date) GetUTCMonth() float64

func (*Date) GetUTCSeconds

func (d *Date) GetUTCSeconds() float64

func (*Date) SetDate

func (d *Date) SetDate(args ...float64) float64

func (*Date) SetFullYear

func (d *Date) SetFullYear(args ...float64) float64

The local setters. Each takes its own field and, optionally, the fields below it, so setHours(9, 30) moves the hour and the minute in one call. Each gives back the new time value, which is what makes d.setDate(1) usable as an expression.

func (*Date) SetHours

func (d *Date) SetHours(args ...float64) float64

func (*Date) SetMilliseconds

func (d *Date) SetMilliseconds(args ...float64) float64

func (*Date) SetMinutes

func (d *Date) SetMinutes(args ...float64) float64

func (*Date) SetMonth

func (d *Date) SetMonth(args ...float64) float64

func (*Date) SetSeconds

func (d *Date) SetSeconds(args ...float64) float64

func (*Date) SetTime

func (d *Date) SetTime(ms float64) float64

SetTime replaces the whole time value, the lowering of date.setTime(ms). It is the one setter that takes an instant rather than a calendar field, so it does not go through the component rebuild at all.

func (*Date) SetUTCDate

func (d *Date) SetUTCDate(args ...float64) float64

func (*Date) SetUTCFullYear

func (d *Date) SetUTCFullYear(args ...float64) float64

The UTC setters, the same writes against the UTC reading of the date.

func (*Date) SetUTCHours

func (d *Date) SetUTCHours(args ...float64) float64

func (*Date) SetUTCMilliseconds

func (d *Date) SetUTCMilliseconds(args ...float64) float64

func (*Date) SetUTCMinutes

func (d *Date) SetUTCMinutes(args ...float64) float64

func (*Date) SetUTCMonth

func (d *Date) SetUTCMonth(args ...float64) float64

func (*Date) SetUTCSeconds

func (d *Date) SetUTCSeconds(args ...float64) float64

func (*Date) ToDateString

func (d *Date) ToDateString() BStr

ToDateString is the calendar half of the local reading, the lowering of date.toDateString(): "Sun Jan 15 2023", with no clock and no zone.

func (*Date) ToISOString

func (d *Date) ToISOString() BStr

ToISOString is the date as the ISO 8601 string in UTC, the lowering of date.toISOString(). The format is fixed: a four-digit year, or the expanded six-digit form with a sign for a year outside 0 through 9999, then the date, the time to milliseconds with all three fraction digits always present, and the Z designator. The Invalid Date has no ISO spelling, so it throws a RangeError, which is what the specification requires and what makes an invalid date impossible to serialize by accident.

func (*Date) ToJSON

func (d *Date) ToJSON() Value

ToJSON is what JSON.stringify serializes a date as, the lowering of date.toJSON(). It is toISOString for a representable date and the value null for the Invalid Date, which is the whole reason it exists as its own method: toISOString throws there, and a program serializing a record that happens to hold an unparsable date gets null in the output rather than an exception out of JSON.stringify.

It answers a Value rather than a BStr because null is one of the two answers. The checker types the method as returning a string, which is a lie the standard library tells; the lowering marks the call dynamic so the truthful value flows into a dynamic sink and a string slot hands the build back rather than taking null as "".

func (*Date) ToString

func (d *Date) ToString() BStr

ToString is the whole human-readable reading in local time, the lowering of date.toString() and the text a date coerces to in a string context. It is the one format a program gets without asking, since a Date coerces to its string form rather than to its number in ordinary concatenation.

func (*Date) ToTimeString

func (d *Date) ToTimeString() BStr

ToTimeString is the clock half, the lowering of date.toTimeString(). It carries the zone with it, since a time of day with no zone names no instant.

func (*Date) ToUTCString

func (d *Date) ToUTCString() BStr

ToUTCString is the date in UTC in the format HTTP headers use, the lowering of date.toUTCString(): "Sun, 15 Jan 2023 03:04:05 GMT". The comma after the weekday and the day before the month are what separate it from the human family, and they are the reason it is written out here rather than composed from the same pieces.

func (*Date) ToValue

func (d *Date) ToValue() Value

ToValue boxes a date into a dynamic value. The box is built once and kept on the date, so every crossing of the same date hands back the same object: a JavaScript Date is a reference, and two boxes would compare unequal under === and print as two values under console.log even though the program has one date.

func (*Date) ValueOf

func (d *Date) ValueOf() float64

ValueOf is the time value, the lowering of date.valueOf() and the number a Date coerces to in arithmetic. It is the same number getTime gives.

type Duration

type Duration struct {
	// contains filtered or unexported fields
}

Duration is bento's runtime representation of a Temporal.Duration (Temporal §7): a span of time as ten independent components, from years down to nanoseconds, with no anchor to a point on the timeline. It carries no calendar and no zone; it is a bag of signed integer counts that all share one sign. The fields are stored as the float64s ToIntegerIfIntegral validated, which is exactly what the JS getters return, and every rendering recomputes from them.

This slice hosts the shape of a Duration and the arithmetic that needs no reference point: construction with the sign and range rules, the ten field getters, sign and blank, negated and abs, toString and toJSON, and from over a Duration. The methods that balance or round across units (round, total, add, subtract, with, compare over mixed calendar units, and from over a string or a property bag) each need a relativeTo reference and the calendar model, so they hand back at lowering and are a later slice.

func DurationFrom

func DurationFrom(d *Duration) *Duration

DurationFrom implements Temporal.Duration.from for a Duration argument: it returns a fresh Duration with the same fields, the copy the specification makes so the result is a distinct object equal to its source. from over a string or a property bag hands back at lowering, so this is only reached with a Duration in hand.

func DurationFromFields

func DurationFromFields(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds Opt[float64]) *Duration

DurationFromFields implements Temporal.Duration.from over a property bag: it reads the ten optional unit fields, each absent field defaulting to zero. At least one field must be present, matching ToTemporalDurationRecord, or a TypeError is thrown; NewDuration then runs ToIntegerIfIntegral and RejectDuration over the ten, so a fractional or mixed-sign field throws a RangeError. A duration carries no calendar, so the bag needs no calendar gate.

func DurationFromString

func DurationFromString(s string) *Duration

DurationFromString implements Temporal.Duration.from over a string. It parses the ISO 8601 duration grammar, PnYnMnWnDTnHnMnS with an optional leading sign, where only the smallest present time component may carry a fraction that cascades into the finer fields down to nanoseconds. A grammar the parser rejects, an empty duration with no component, or a field out of the valid Duration range each throws a RangeError.

func NewDuration

func NewDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds float64) *Duration

NewDuration builds a Duration from the constructor's ten optional number arguments, every one defaulting to zero. It runs ToIntegerIfIntegral on each, so a fractional, NaN, or non-finite component throws a RangeError (unlike PlainDate and PlainTime, a Duration does not truncate a fractional argument, it rejects it), then RejectDuration, so a mixed-sign set or an out-of-range magnitude throws a RangeError, the order new Temporal.Duration(...) follows in the specification. The lowerer pads the missing trailing components with zero before the call, so this constructor always sees ten numbers.

func (*Duration) Abs

func (d *Duration) Abs() *Duration

Abs implements Temporal.Duration.prototype.abs: a Duration with every field made non-negative.

func (*Duration) Add

func (d *Duration) Add(other *Duration) *Duration

Add implements Temporal.Duration.prototype.add, and Subtract implements subtract, which is add over a negated operand. The reduced Temporal profile drops the relativeTo option from both, so neither can balance calendar units: if the receiver or the operand carries years, months, or weeks, a RangeError is thrown. Otherwise the two durations fold to one signed nanosecond count over a fixed 24-hour day and re-balance to the coarser of their two default largest units, days when either counts whole days and the largest time unit present otherwise.

func (*Duration) Blank

func (d *Duration) Blank() bool

Blank reports whether the Duration is all zeros, the case where sign is 0.

func (*Duration) Days

func (d *Duration) Days() float64

Days returns the days field.

func (*Duration) Hours

func (d *Duration) Hours() float64

Hours returns the hours field.

func (*Duration) Microseconds

func (d *Duration) Microseconds() float64

Microseconds returns the microseconds field.

func (*Duration) Milliseconds

func (d *Duration) Milliseconds() float64

Milliseconds returns the milliseconds field.

func (*Duration) Minutes

func (d *Duration) Minutes() float64

Minutes returns the minutes field.

func (*Duration) Months

func (d *Duration) Months() float64

Months returns the months field.

func (*Duration) Nanoseconds

func (d *Duration) Nanoseconds() float64

Nanoseconds returns the nanoseconds field.

func (*Duration) Negated

func (d *Duration) Negated() *Duration

Negated implements Temporal.Duration.prototype.negated: a Duration with every field's sign flipped. A zero field stays a positive zero.

func (*Duration) Round

func (d *Duration) Round(smallestUnit, largestUnit string, increment float64, mode string, rel *PlainDate) *Duration

Round implements Temporal.Duration.prototype.round. smallestUnit and largestUnit are the singular unit names, either empty when the option was absent; smallestUnit then defaults to nanosecond and largestUnit to the coarser of the duration's default largest unit and the smallestUnit. rel is the PlainDate the calendar units resolve against, or nil when no relativeTo was given. Without a reference the duration may carry no years, months, or weeks and both units must be day or finer, since week, month, and year each need a calendar, else a RangeError; the duration then rounds over a fixed 24-hour day and balances to largestUnit. With a reference every field resolves against the calendar to an endpoint, the endpoint rounds at smallestUnit, and the rounded date rebalances to largestUnit. An irregular smallestUnit, month or year, rounds by bracketing the endpoint between two unit boundaries; a fixed one rounds the nanosecond span and splits it back into whole days and a remainder.

func (*Duration) Seconds

func (d *Duration) Seconds() float64

Seconds returns the seconds field.

func (*Duration) Sign

func (d *Duration) Sign() float64

Sign returns the sign of the whole Duration, 1, -1, or 0.

func (*Duration) Subtract

func (d *Duration) Subtract(other *Duration) *Duration

Subtract implements Temporal.Duration.prototype.subtract as add over a negated operand.

func (*Duration) ToJSON

func (d *Duration) ToJSON() BStr

ToJSON implements Temporal.Duration.prototype.toJSON, the same ISO string toString produces under default options.

func (*Duration) ToString

func (d *Duration) ToString() BStr

ToString implements Temporal.Duration.prototype.toString for the default options: the ISO 8601 duration form, an optional leading minus for a negative Duration, then P, the non-zero date components (years, months, weeks, days), then T and the non-zero time components (hours, minutes, and a combined seconds field). The seconds field folds the seconds, milliseconds, microseconds, and nanoseconds into one decimal with the fraction trimmed of trailing zeros. An all-zero Duration renders as "PT0S".

func (*Duration) Total

func (d *Duration) Total(unit string, rel *PlainDate) float64

Total implements Temporal.Duration.prototype.total. unit names the output unit, already normalized to its singular form, and rel is the PlainDate the calendar units resolve against, or nil when no relativeTo was given. Without a reference the duration may carry no years, months, or weeks and unit must be day or finer, since week, month, and year each need a calendar, else a RangeError; a day then counts as a fixed 24 hours. With a reference every field resolves against the calendar: the date part lands on an end date, the sub-day time adds over a fixed 24-hour day, and the signed nanosecond span from rel to that endpoint converts to unit. Days and weeks are fixed lengths that divide directly; months and years vary, so the fraction interpolates between the two unit boundaries that bracket the endpoint.

func (*Duration) Weeks

func (d *Duration) Weeks() float64

Weeks returns the weeks field.

func (*Duration) With

func (d *Duration) With(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds Opt[float64]) *Duration

With implements Temporal.Duration.prototype.with: it overlays the present fields of a partial-duration bag onto the receiver, each absent field keeping the receiver's value. At least one field must be present, matching ToTemporalPartialDurationRecord, or a TypeError is thrown; NewDuration then runs ToIntegerIfIntegral and RejectDuration over the merged ten, so a fractional or mixed-sign field throws a RangeError. with does no balancing, it only reshapes, so it needs no relativeTo reference.

func (*Duration) Years

func (d *Duration) Years() float64

Years returns the years field.

type Error

type Error struct {
	// contains filtered or unexported fields
}

Error is a thrown JavaScript error in the typed world: a constructor name and a message, the two properties every built-in error carries. Both are held as bento strings, so a catch that reads err.name or err.message gets the JavaScript string with no re-transcoding on the read path. It is a pointer type so a caught error compares by identity the way a JavaScript object does, and it implements the Go error interface so it round-trips through panic and recover and reads cleanly if it ever reaches Go-level logging.

func Caught

func Caught(r any) *Error

Caught converts a recovered panic payload into the *Error a catch binds. A thrown *Error binds unchanged, so identity is preserved; a boundary Thrown (a go: failure, a range check) binds as an Error carrying its name and message, so a catch handles it like any other error. A payload that is not a thrown value is a Go runtime panic, a bug in the runtime rather than a program throw, so it is re-panicked to keep its original stack rather than be caught as a JavaScript error.

func NewAggregateError

func NewAggregateError(errors []Value, message BStr) *Error

NewAggregateError constructs an AggregateError, the error Promise.any rejects with when every input rejects. It carries the rejection reasons as its errors array and a summary message, and marks itself an aggregate through a non-nil errors slice so the boxed object exposes the errors property alongside name and message.

func NewAssertionError

func NewAssertionError(actual, expected Value, operator string, message Value, hasMessage bool) *Error

NewAssertionError builds the error an assert method throws. The message follows from the operator and the two values the way node's does, and the properties a caller reads off a caught assertion are all here: the code it branches on, the two values and the operator, and whether the message was generated or its own.

A caught AssertionError does not print the way node's does. Node marks name and message non-enumerable, so console.log of one shows the diff and the four assertion properties; bento's boxed error carries name and message as ordinary properties, so they show too. That is the error box's own divergence rather than assert's, and it is one place rather than eleven.

func NewError

func NewError(message BStr) *Error

NewError constructs a plain Error, the lowering of new Error(message).

func NewInvalidCharacterError

func NewInvalidCharacterError() *Error

NewInvalidCharacterError constructs an InvalidCharacterError, the DOMException the base64 globals raise: a btoa over a code unit above the Latin1 range, or an atob over base64 that is the wrong length or holds a character outside the alphabet. It is a DOMException rather than an ECMAScript error, but the runtime models every thrown error as a name and a message, so a catch reads err.name as "InvalidCharacterError" the way it would in Node.

func NewNodeError

func NewNodeError(name, code string, message BStr) *Error

NewNodeError constructs the error a Node built-in raises: an ordinary error of the given constructor name carrying the code that identifies it. Node builds these from one internal factory so that every built-in reports a failure the same way, and this is that factory. The name is the constructor a program tests with instanceof (TypeError for a bad argument type, RangeError for a bad value, Error for everything else), and the code is what it branches on.

func NewRangeError

func NewRangeError(message BStr) *Error

NewRangeError constructs a RangeError, the lowering of new RangeError(message) and the error a numeric range check raises.

func NewSuppressedError

func NewSuppressedError(suppressor, suppressed Thrown) *Error

NewSuppressedError constructs the SuppressedError the explicit-resource-management protocol raises when a using declaration's disposal throws while an error is already propagating: suppressor is the disposal's throw, the error property, and suppressed is the error it interrupted, the suppressed property. Both are kept as boxed values so a catch reads err.error and err.suppressed as the JavaScript errors they were, and either can itself be a SuppressedError when a chain of disposals each throw.

func NewSyntaxError

func NewSyntaxError(message BStr) *Error

NewSyntaxError constructs a SyntaxError, the error a runtime parse raises: a BigInt(s) whose string is not an integer literal, or a JSON.parse on malformed input once its throw path lands.

func NewTypeError

func NewTypeError(message BStr) *Error

NewTypeError constructs a TypeError, the lowering of new TypeError(message) and the error a failed type guard raises.

func NewURIError

func NewURIError(message BStr) *Error

NewURIError constructs a URIError, the error the URI codec globals raise: an encodeURIComponent over a lone surrogate, or a decodeURIComponent over a malformed percent-escape.

func (*Error) As

func (e *Error) As(target any) bool

As unwraps the caught error's Go error into target, the lowering of err.as(...) (section 7.7). It defers to errors.As, so target is a pointer to the concrete Go error type the chain is searched for, and it reports whether a match was assigned; an error the program threw itself has no Go error to unwrap and never matches.

func (*Error) Cause

func (e *Error) Cause() error

Cause reports the original Go error behind a caught boundary failure, or nil for an error the program threw itself. It is the value.Value-side handle behind a caught error's goError property (section 7.7): the underlying Go value that errors.Is and errors.As walk, kept alive by the caught error that holds it.

func (*Error) Code

func (e *Error) Code() (BStr, bool)

Code reports the error's Node code as a bento string and whether it has one, the read behind err.code on an error a built-in raised.

func (*Error) CodeValue

func (e *Error) CodeValue() Value

CodeValue is err.code as a program reads it: the string a Node built-in put there, or undefined for an error with no code, which is what a property that was never set answers in JavaScript. It is the boxed form because a catch binding is typed unknown, so every property read off it is dynamic.

func (*Error) Constructor

func (e *Error) Constructor() Value

Constructor reports the caught error's constructor as a value, the lowering of a caught error's .constructor. The runtime models the error family by name, so the constructor is the interned value for that name: a caught TypeError answers the same TypeError value the program compares it against, which is what makes thrown.constructor === TypeError hold.

func (*Error) Error

func (e *Error) Error() string

Error formats the error the way JavaScript's Error.prototype.toString does: the name, then ": " and the message when the message is non-empty, or just the name when it is empty.

func (*Error) ErrorMessage

func (e *Error) ErrorMessage() string

ErrorMessage reports the error's message as a Go string, the form the Thrown marker and the top-level reporter read.

func (*Error) ErrorName

func (e *Error) ErrorName() string

ErrorName reports the error's constructor name as a Go string, the form the Thrown marker and the top-level reporter read.

func (*Error) Is

func (e *Error) Is(target error) bool

Is reports whether the caught error matches a Go sentinel, the lowering of err.is(target) where target is an error imported from a go: package (io.EOF is the canonical one, section 7.7). It defers to errors.Is against the original Go error, so a wrapped sentinel matches exactly as it would in Go; an error the program threw itself has no Go error behind it and matches nothing.

func (*Error) IsA

func (e *Error) IsA(name string) bool

IsA reports whether the error is an instance of the named built-in error constructor, the lowering of e instanceof Error and its TypeError and RangeError siblings on a caught error. Every built-in error is an Error, so the base name always matches; a specific name matches only the error the matching constructor built, which is how instanceof narrows a caught error to the subclass a catch handles. The runtime models the error family as one type with a name field rather than distinct Go types, so the test is a name comparison rather than a type assertion.

func (*Error) IsGoError

func (e *Error) IsGoError() bool

IsGoError reports whether the caught error came from Go, the lowering of e instanceof GoError on a catch binding (section 7.7). A boundary failure that wrapped a Go error carries a cause, so it is a GoError; an error the program threw itself has no Go error behind it and is not. This is what narrows a catch binding to the GoError surface before err.is or err.as reads it.

func (*Error) Message

func (e *Error) Message() BStr

Message reports the error's message as a bento string, the lowering of JavaScript's err.message.

func (*Error) Name

func (e *Error) Name() BStr

Name reports the error's constructor name as a bento string, the lowering of JavaScript's err.name.

func (*Error) PropertyValue

func (e *Error) PropertyValue(name string) Value

PropertyValue is the read that answers err.actual, err.operator and the other properties a built-in put on the error with SetProperty, the counterpart of that write. An error that carries no such property answers undefined, which is what a property that was never set answers in JavaScript: a plain Error has no operator, and a program that reads one there gets the same undefined Node gives it.

func (*Error) SetProperty

func (e *Error) SetProperty(name string, v Value)

SetProperty adds an own property to the error, the write a built-in makes when the error it raises carries more than a name, a message and a code: an AssertionError's actual, expected and operator, or a filesystem error's path. The property is enumerable and writable the way an assigned one is in Node, since that is what the built-in does there too.

The boxed form is updated as well when it already exists, so a property set after the error crossed into the dynamic world is visible through the box a program is already holding rather than lost.

func (*Error) ToBStr

func (e *Error) ToBStr() BStr

ToBStr returns the error's JavaScript string form as a bento string, the result Error.prototype.toString produces: the name, then ": " and the message when the message is non-empty, or the name alone when it is empty. It is the coercion a caught error takes in a template, a concatenation, or String(err), the bento string form of the Go-string Error method above so the coercion needs no re-transcoding.

func (*Error) ToValue

func (e *Error) ToValue() Value

ToValue boxes the error as a dynamic object value, the form a caught error takes when it flows into the dynamic world rather than through a typed read: it is passed to a helper that takes any, compared for identity, or tested for truthiness. The object carries the two own properties every error exposes, name and message, so a dynamic read of either resolves through the boxed object's Get the way JavaScript's own property lookup does. The object is built once and kept on the error, so two boxings return the same pointer and identity holds: a caught error stashed and compared to itself is === true, matching an object's reference equality. A dynamic .constructor read on the boxed form is a later slice; the direct thrown.constructor read stays on its own typed path.

type FinalizationRegistry

type FinalizationRegistry[T any] struct {
	// contains filtered or unexported fields
}

FinalizationRegistry is bento's runtime representation of a JavaScript FinalizationRegistry<T>. It holds the cleanup callback and the live registrations, each pairing an unregister token with the Cleanup handle AddCleanup returned, so a later unregister can find and stop the pending cleanup by its token.

func NewFinalizationRegistry

func NewFinalizationRegistry[T any](cleanup func(T)) *FinalizationRegistry[T]

NewFinalizationRegistry builds a registry with the given cleanup callback, the lowering of new FinalizationRegistry(cb). The callback is called with a registration's held value after that registration's target is collected.

func (*FinalizationRegistry[T]) ToValue

func (r *FinalizationRegistry[T]) ToValue() Value

ToValue boxes a FinalizationRegistry into a dynamic value.

func (*FinalizationRegistry[T]) Unregister

func (r *FinalizationRegistry[T]) Unregister(token any) bool

Unregister removes every registration made under token, stopping its pending cleanup, and reports whether it removed any, the lowering of registry.unregister(token). Tokens are objects, so they compare by reference identity through ==.

type Gen

type Gen[Y any] struct {
	// contains filtered or unexported fields
}

Gen is a running generator of yield type Y. The body runs in a goroutine that suspends on out; the consumer drives it through Next, Return, and Throw. started gates the goroutine launch to the first pull, so a generator that is never pulled never runs its body, matching the JavaScript rule that calling a generator function only creates the object. done latches once the body completes, and result holds the value the completion carried, the value a { value, done: true } result reports.

func NewGen

func NewGen[Y any](body func(*GenCo[Y]) Value) *Gen[Y]

NewGen mints a generator whose body is the goroutine func the lowerer builds from a generator function's source. The body takes the coroutine handle it yields through and returns the value the generator completes with, undefined for a generator with no return value.

func (*Gen[Y]) Done

func (g *Gen[Y]) Done() bool

Done reports whether the generator has completed, the state a manual driver reads off the result's done between pulls.

func (*Gen[Y]) Next

func (g *Gen[Y]) Next(sent Value) (Y, bool)

Next pulls the next value, resuming the suspended yield with sent, the value next(v) passes back into the body. It returns the yielded value and whether the generator is done; a done pull reports the yield type's zero value, which the consumer ignores because done is true.

func (*Gen[Y]) Result

func (g *Gen[Y]) Result() Value

Result is the value the generator completed with, valid once done. It is the value a { value, done: true } result carries, undefined for a generator that ran off the end with no return value.

func (*Gen[Y]) Return

func (g *Gen[Y]) Return(ret Value) (Y, bool)

Return closes the generator early with a return value, the way for...of closes an iterable it leaves mid-iteration: the suspended body unwinds through its finally blocks and completes carrying ret. A generator that has not started or is already done simply latches done, since there is no suspended body to unwind.

func (*Gen[Y]) Stop

func (g *Gen[Y]) Stop()

Stop closes an abandoned generator, the drain a for...of runs when it leaves the loop early through a break. It resumes the suspended body with a return signal so the body unwinds through its finally blocks and the goroutine exits, rather than parking forever on its next yield and leaking. It is Return with the completion value discarded, the close a consumer that breaks out of iteration does not name a value for; a generator already run to done is left as is.

func (*Gen[Y]) Throw

func (g *Gen[Y]) Throw(e Thrown) (Y, bool)

Throw injects a thrown value at the suspended yield, the way a hand driver raises an error inside the generator with throw(e). A suspended body resumes with e raised at its yield, so a try/catch there catches it and the generator may yield again or complete; an uncaught throw unwinds the body and escapes to the caller. A generator that has not started or is already done has no yield to raise at, so e propagates to the caller and the generator latches done, matching the JavaScript rule that throw on a newborn or completed generator throws straight back.

type GenCo

type GenCo[Y any] struct {
	// contains filtered or unexported fields
}

GenCo is the handle the body holds: it yields through the same channel pair the Gen drives, so a yield inside the body sends on out and blocks for the resume on in. It is passed to the body func the lowerer builds from the generator source.

func (*GenCo[Y]) Yield

func (co *GenCo[Y]) Yield(v Y) Value

Yield sends v to the consumer and blocks until the consumer pulls again, then returns the value the consumer passed back through next(v). A return signal unwinds the body as a genAbort so its finally blocks run before the generator completes.

func (*GenCo[Y]) YieldFrom

func (co *GenCo[Y]) YieldFrom(sub *Gen[Y]) Value

YieldFrom drives a delegate generator on this coroutine's behalf, the runtime of a yield* delegation. It pulls each value the delegate yields and re-yields it to this generator's consumer, threading the value the consumer sends back through next(v) into the delegate's own next, so a value sent through the outer generator reaches the delegate. The first pull resumes the delegate with undefined, the argument yield* passes on its opening next(). It returns once the delegate completes, evaluating to the value the delegate finished with, the value the yield* expression takes on.

type Instant

type Instant struct {
	// contains filtered or unexported fields
}

Instant is bento's runtime representation of a Temporal.Instant (Temporal §8): an exact point on the UTC time line, counted as a whole number of nanoseconds since the epoch 1970-01-01T00:00:00Z. It carries no calendar and no zone, only the count, so a single arbitrary-precision integer captures it; the nanosecond total runs to ±8.64e21, past a float64's exact-integer range, so it is a big.Int rather than a double.

The stored count is validated against the representable range at construction, so an Instant that reached a getter or a comparison is always in range. The value is copied in and copied out, so a caller cannot mutate the shared big.Int and reach through to the Instant's field.

func InstantFrom

func InstantFrom(inst *Instant) *Instant

InstantFrom implements Temporal.Instant.from for an Instant argument: it returns a fresh Instant with the same count, the copy the specification makes. from over a string routes to InstantFromString instead, so this is reached only with an Instant in hand.

func InstantFromEpochMilliseconds

func InstantFromEpochMilliseconds(epochMilliseconds float64) *Instant

InstantFromEpochMilliseconds implements Temporal.Instant.fromEpochMilliseconds: the number of milliseconds must be an integer, so a NaN, non-finite, or fractional value throws a RangeError (the NumberToBigInt step the specification runs), then the count is scaled to nanoseconds and validated against the Instant range. A whole millisecond count up to the range bound stays inside a float64's exact-integer range, so the int64 narrowing is lossless.

func InstantFromEpochNanoseconds

func InstantFromEpochNanoseconds(epochNanoseconds *big.Int) *Instant

InstantFromEpochNanoseconds implements Temporal.Instant.fromEpochNanoseconds: it is the constructor under another name, a bigint nanosecond count validated and stored.

func InstantFromString

func InstantFromString(s string) *Instant

InstantFromString implements Temporal.Instant.from over a string. An Instant is an exact point on the UTC time line, so the string must fix the offset from UTC: a Z designator or a numeric offset is required, and a date-only or offset-less date-time string throws a RangeError. The wall-clock reading the date and time name is taken as UTC and the offset is subtracted to reach the epoch count, which newInstant range-checks. A calendar annotation is accepted and ignored whatever it names, since an Instant carries no calendar; the shared parser still rejects a malformed annotation or a critical non-calendar one.

func NewInstant

func NewInstant(epochNanoseconds *big.Int) *Instant

NewInstant builds an Instant from the constructor's single bigint argument, the nanoseconds since the epoch, running IsValidEpochNanoseconds so an out-of-range count throws a RangeError the way new Temporal.Instant(ns) does.

func NowInstant

func NowInstant() *Instant

NowInstant implements Temporal.Now.instant, the current instant as an exact point on the time line with no zone.

func (*Instant) AddDuration

func (i *Instant) AddDuration(dur *Duration) *Instant

AddDuration implements Temporal.Instant.prototype.add: it folds the duration's time part into the epoch nanosecond count. An Instant has no calendar and no wall clock, so a nonzero years, months, weeks, or days field is meaningless and throws a RangeError, matching the specification's rejection of the calendar units. The fold runs in big.Int, so an hour field near the safe-integer ceiling does not overflow, and newInstant re-validates the range so a result past the Instant bounds throws. subtract reuses this over a negated duration.

func (*Instant) EpochMilliseconds

func (i *Instant) EpochMilliseconds() float64

EpochMilliseconds returns the whole milliseconds since the epoch, floor(ns / 10^6). The floor runs through big.Int Euclidean division, so a negative instant rounds toward minus infinity the way the specification's mathematical floor does; the result is within a float64's exact-integer range across the whole Instant range.

func (*Instant) EpochNanoseconds

func (i *Instant) EpochNanoseconds() *big.Int

EpochNanoseconds returns the nanoseconds since the epoch as a fresh big.Int, so the caller holds a bigint independent of the Instant's field.

func (*Instant) Equals

func (i *Instant) Equals(other *Instant) bool

Equals implements Temporal.Instant.prototype.equals for an Instant argument: two instants are equal exactly when their nanosecond counts match.

func (*Instant) Round

func (i *Instant) Round(smallestUnit string, increment float64, roundingMode string) *Instant

Round implements Temporal.Instant.prototype.round: it rounds the epoch nanosecond count to a multiple of roundingIncrement of smallestUnit under one of the nine rounding modes. Unlike PlainTime.round, whose increment divides the next larger unit, an Instant rounds against the whole day, so the increment must divide the number of the unit in a 24-hour day, hour into 24, minute into 1440, second into 86400, and each sub-second unit correspondingly. An increment that is not a positive integer at or below that count and dividing it throws a RangeError. The quantum divides a day evenly, so the rounding aligns to the day boundary. The receiver is unchanged.

func (*Instant) Since

func (i *Instant) Since(other *Instant, largestUnit, smallestUnit string, increment float64, roundingMode string) *Duration

Since returns the signed exact-time difference from other to the receiver, the reverse of Until. Both round the signed difference so the mode acts on the true sign, matching the specification's rule of negating the mode and the result for since.

func (*Instant) ToJSON

func (i *Instant) ToJSON() BStr

ToJSON implements Temporal.Instant.prototype.toJSON, the same UTC ISO string toString produces under default options.

func (*Instant) ToString

func (i *Instant) ToString() BStr

ToString implements Temporal.Instant.prototype.toString under the default options: the ISO 8601 date-time in UTC with a Z designator, a fractional-second part appended only when a sub-second field is set. The count is split into a day index and a within-day nanosecond remainder by Euclidean division, so a negative instant lands on the correct earlier day with a positive time of day, then the day index becomes an ISO date and the remainder the wall-clock time.

func (*Instant) ToZonedDateTimeISO

func (i *Instant) ToZonedDateTimeISO(timeZone string) *ZonedDateTime

ToZonedDateTimeISO implements Temporal.Instant.prototype.toZonedDateTimeISO: it pairs the exact instant with a time zone under the ISO 8601 calendar, giving the count a wall-clock reading. The epoch nanosecond count is already in range, so newZonedDateTime only resolves the zone, throwing a RangeError on an unrecognized identifier, and stores a copy under the empty ISO calendar.

func (*Instant) Until

func (i *Instant) Until(other *Instant, largestUnit, smallestUnit string, increment float64, roundingMode string) *Duration

Until returns the signed exact-time difference from the receiver to other as a Duration, balanced from largestUnit down and rounded at smallestUnit under roundingMode. An Instant carries no calendar, so the units run hour down to nanosecond only; a day or larger unit is rejected at the boundary before this method by the caller's unit set.

type IterHelper

type IterHelper struct {
	// contains filtered or unexported fields
}

The iterator helpers are the lazy iterator methods ES2024 hangs off Iterator.prototype: map, filter, take, drop, and flatMap return a new iterator that pulls from the source on demand, and reduce, toArray, forEach, some, every, and find drive the source to exhaustion and return a value (10_advanced group 5).

IterHelper is the one runtime iterator every helper produces and consumes. It holds a next closure that yields the same value.IterResult a generator or an array iterator hands back, so a helper reads .Value and .Done off a step the same way a for...of or a manual next() does, and a chain of helpers is a chain of next closures each wrapping the one below it. The helpers are free functions taking a next closure rather than methods, so an array iterator's Next and an IterHelper's Next feed them the same way, which is how arr.values().map(...) and Iterator.from(...).map(...) share one path.

func IterDrop

func IterDrop(next func() IterResult, limit Value) *IterHelper

IterDrop skips the first limit values from the source and then yields the rest, the lazy drop. It pulls and discards up to the count on the first advance, stopping early if the source runs out inside the skip, and yields every value after, so dropping more than the source holds yields nothing. A limit of positive infinity skips the whole source.

func IterFilter

func IterFilter(next func() IterResult, fn Value) *IterHelper

IterFilter keeps each value for which fn(value, index) is truthy, the lazy filter. It pulls from the source until a value passes the predicate or the source is done, so a filtered iterator skips the rejected values without materializing them. The index counts every value the predicate sees, kept or dropped.

func IterFlatMap

func IterFlatMap(next func() IterResult, fn Value) *IterHelper

IterFlatMap maps each value through fn and flattens the results, the lazy flatMap. It drives the outer source one value at a time and, for each, drives the iterable fn returns to exhaustion before pulling the next outer value, so the yields interleave in the order the spec lays out. The mapped value flattens under reject-primitives handling: an array flattens over its elements and anything else, a string or any other primitive included, throws a TypeError, matching flatMap's GetIteratorFlattenable(reject-primitives). The index passed to fn counts the outer values seen.

func IterFrom

func IterFrom(src Value) *IterHelper

IterFrom wraps an iterable value as an IterHelper, the runtime behind Iterator.from. It drives an array over its indices and a string over its code points, the iterate-string-primitives handling Iterator.from asks for. A value that is neither is not an iterable this path drives, so it throws a TypeError the way the spec does for a non-iterable argument.

func IterMap

func IterMap(next func() IterResult, fn Value) *IterHelper

IterMap lifts each yielded value through fn(value, index), the lazy map. It calls fn only as the result is pulled, and the index counts the values actually seen, so a value the source never reaches is never mapped. A done step passes straight through without calling fn.

func IterTake

func IterTake(next func() IterResult, limit Value) *IterHelper

IterTake yields at most limit values from the source and then reports done, the lazy take. It counts down as values are pulled, so a source shorter than the limit is yielded whole and a source longer is cut off once the count runs out, without pulling the values past the cut. A limit of positive infinity never runs out, so the whole source is yielded.

func Iterate

func Iterate(v Value, src string) *IterHelper

Iterate is the runtime side of a for...of, a spread, or an array destructuring whose source is a boxed value rather than a shape the checker recognized. The lowerer emits it when it cannot tell statically what it is about to walk, which is every value that came back from a built-in: `require('os').cpus()` is a value.Value of KindArray, and the checker knows only that it is dynamic.

It answers an *IterHelper because that is the one puller the runtime already has. A generator, an array iterator and an iterator-helper chain all hand back an IterResult from Next, so a caller drives whatever this returns the same way it drives those, and the lowerer needs no second loop shape.

The source text is passed in because the message is worth getting right. Node says "os.cpus is not iterable", naming the expression the program wrote, and the runtime cannot recover that from the value. The lowerer has it, so it hands it over.

func IterateSpreadCall

func IterateSpreadCall(v Value) *IterHelper

IterateSpreadCall is Iterate for the one site JavaScript words differently. A spread in a call's argument list that finds no iterator says the syntax requires one and names no expression, where an array literal's spread, an array destructuring, and a for...of all say "x is not iterable". Everything about the walk is the same, so the two share the decision below rather than each carrying their own copy of it.

func NewIterHelper

func NewIterHelper(next func() IterResult) *IterHelper

NewIterHelper wraps a next closure as an IterHelper, the constructor the lowerer emits when it needs to lift an array iterator's Next into the helper the chain consumes. A nil closure yields a done result forever, so a helper built over an exhausted or empty source is safe to pull.

func (*IterHelper) Next

func (h *IterHelper) Next() IterResult

Next advances the iterator one step, the drive a for...of over a helper result and a manual it.next() both take. It reports done once the underlying closure is exhausted and keeps reporting done after, so a caller that pulls past the end reads { undefined, true } rather than panicking on a nil closure.

type IterResult

type IterResult struct {
	Value Value
	Done  bool
}

IterResult is the { value, done } object a generator hands back from a manual next, return, or throw, the IteratorResult a hand-rolled driver reads .value and .done off. Value carries the yielded value while Done is false and the completion value once Done is true, so a manual loop reads Done to stop and Value for each step. It is a plain struct passed by value: it packages, as the object the language gives a manual caller, the same pair for...of already reads straight off the Gen.

func GenNext

func GenNext[Y any](g *Gen[Y], sent Value, box func(Y) Value) IterResult

GenNext drives one step of a generator for a manual next(v) and packs the { value, done } result. The box closure lifts the generator's typed yield into a value.Value; the lowerer supplies it because it alone knows the element type Y. On completion the result carries the generator's return value, which is already a value.Value, and Done is true.

func GenReturn

func GenReturn[Y any](g *Gen[Y], ret Value, box func(Y) Value) IterResult

GenReturn drives a manual return(v) and packs the { value, done } result, the runtime of it.return(v). It closes the generator early through Gen.Return, so the suspended body unwinds its finally blocks and completes carrying ret; the result is { value: ret, done: true } unless a finally yields, in which case the box lifts that yield the way GenNext does.

func GenThrow

func GenThrow[Y any](g *Gen[Y], e Thrown, box func(Y) Value) IterResult

GenThrow drives a manual throw(e) and packs the { value, done } result, the runtime of it.throw(e). It raises e at the suspended yield through Gen.Throw: a try/catch in the body catches it and the generator yields again (the box lifts that value) or completes, and an uncaught throw propagates out of this call the way it does in JavaScript.

type Kind

type Kind uint8

Kind is the runtime tag of a boxed Value, one case per JavaScript type plus the flat array and function cases the spec splits out so their fast paths do not go through the generic object case.

const (
	KindUndefined Kind = iota
	KindNull
	KindBool
	KindNumber
	KindBigInt
	KindString
	KindSymbol
	KindObject
	KindArray
	KindFunc
	// KindHole is the internal tag of an array hole, an index below length that
	// carries no own property. It fills a gap in an array's dense element storage so
	// a hole is distinct from a stored undefined: a read sees undefined either way,
	// but the in operator, hasOwnProperty, and enumeration treat a hole as absent. It
	// never escapes to user code, so typeof and the coercions never see it.
	KindHole
)

type Map

type Map[K any, V any] struct {
	// contains filtered or unexported fields
}

Map is bento's runtime representation of a JavaScript Map<K, V>. It holds its entries as parallel key and value slices in insertion order, the order for...of, forEach, and the go: crossing all observe, and an eq function that decides key identity so number, string, and boolean keys each compare the way JavaScript's SameValueZero does for that kind. The type is monomorphized: the compiler proved K and V, so there is no boxing on the entries themselves.

func NewBoolMap

func NewBoolMap[V any]() *Map[bool, V]

NewBoolMap builds an empty Map with boolean keys, the lowering of new Map<boolean, V>(). There are only two keys, so plain == is the whole of SameValueZero here.

func NewDynMap

func NewDynMap[V any]() *Map[Value, V]

NewDynMap builds an empty Map whose keys are dynamic values, the lowering of a `new Map()` written with no key type. That is the ordinary spelling in JavaScript, where nothing narrows the key to a single kind, so one map holds a number, a string, and an object key side by side. Keys compare by SameValueZero over the boxed value, which is the one comparison that covers every kind at once: a number key matches by value with NaN matching itself, a string by code unit, and an object by identity, exactly as the kind-specific constructors above do for the keys they each admit.

func NewNumberMap

func NewNumberMap[V any]() *Map[float64, V]

NewNumberMap builds an empty Map with number keys, the lowering of new Map<number, V>(). Keys compare by SameValueZero: NaN is a single key (every NaN matches) and +0 and -0 are the same key, which is exactly what a plain == misses for NaN and gets right for the zeroes, so the equality folds the NaN case in by hand.

func NewRefMap

func NewRefMap[K comparable, V any]() *Map[K, V]

NewRefMap builds an empty Map whose keys are objects compared by reference identity, the lowering of new Map<K, V>() for an object key type K. A JavaScript object key matches under SameValueZero, which for objects is reference identity: two object keys are the same key exactly when they are the same object. Objects lower to Go struct pointers, so Go's == on those pointers is that identity, and there is no NaN case to fold in the way a number key has. K is constrained to comparable because only a comparable key can back the == the equality uses; the lowerer only reaches this constructor for a key type that renders to a pointer.

func NewStringMap

func NewStringMap[V any]() *Map[BStr, V]

NewStringMap builds an empty Map with string keys, the lowering of new Map<string, V>(). Keys compare by the string's UTF-16 code units through BStr.Equal, so two strings that print the same are the same key however each was built.

func (*Map[K, V]) Clear

func (m *Map[K, V]) Clear()

Clear removes every entry, the lowering of map.clear(). The slices are truncated to length zero but keep their backing storage, so a map that is refilled after a clear does not reallocate from empty.

func (*Map[K, V]) Delete

func (m *Map[K, V]) Delete(k K) bool

Delete removes the entry for k and reports whether it was present, the lowering of map.delete(k). The remaining entries keep their relative order, matching JavaScript, so a later iteration still visits them in insertion order.

func (*Map[K, V]) ForEach

func (m *Map[K, V]) ForEach(fn func(V, K))

ForEach visits each entry in insertion order, passing the value then the key, the order Map.prototype.forEach hands its callback (value, key, map). It is the two- argument shape a forEach callback that reads both takes; a callback that reads only the value lowers to ForEachValue instead. The entries are passed by value, so a callback cannot alias the map's storage.

func (*Map[K, V]) ForEachValue

func (m *Map[K, V]) ForEachValue(fn func(V))

ForEachValue visits each entry's value in insertion order, the shape a forEach callback that reads only its first parameter takes, so the common (value) => ... form needs no unused key binding.

func (*Map[K, V]) Get

func (m *Map[K, V]) Get(k K) Opt[V]

Get returns the value for k as an optional, undefined when the key is absent, the lowering of map.get(k) whose declared type is V | undefined. It hands back an Opt[V] so the value composes with the same narrowing and nullish paths any other optional takes.

func (*Map[K, V]) Has

func (m *Map[K, V]) Has(k K) bool

Has reports whether the map holds an entry for k, the lowering of map.has(k).

func (*Map[K, V]) KeySet

func (m *Map[K, V]) KeySet() *Set[K]

KeySet returns a Set of the map's keys, the set-like view a Map presents when it is passed as the argument to a Set-algebra method (union, intersection, and the rest). A JavaScript Map is a set-like: it has a size, a has, and a keys iterator over its keys, which is exactly the protocol those methods read, so a Map argument projects to the Set of its keys. The keys are already unique and carry the map's key equality, so the members copy needs no dedup and the new Set shares the same eq, giving it the same SameValueZero identity the map keys had.

func (*Map[K, V]) Keys

func (m *Map[K, V]) Keys() []K

Keys returns the map's keys in insertion order, the traversal map.keys() and a for...of over the keys read. It copies the backing slice so a mutation to the map during the loop does not disturb the range in progress; the live-view an iterator has of concurrent mutation is a later slice.

func (*Map[K, V]) Range

func (m *Map[K, V]) Range(fn func(K, V))

Range visits each entry in insertion order, the iteration the go: crossing reads to marshal a bento map to a Go map. It passes the key and value by value, so a callback cannot alias the map's storage.

func (*Map[K, V]) Set

func (m *Map[K, V]) Set(k K, v V) *Map[K, V]

Set inserts or updates the entry for k and returns the map, the lowering of map.set(k, v). A new key appends in insertion order; an existing key keeps its position and takes the new value, matching JavaScript, and the map itself is the result so a chained set lowers with no temporary.

func (*Map[K, V]) Size

func (m *Map[K, V]) Size() float64

Size is the entry count as a Number, the lowering of the map.size accessor. It is a float64 to match the type the checker gives the property and to compose with the numeric path with no conversion at the use site.

func (*Map[K, V]) ToValue

func (m *Map[K, V]) ToValue() Value

ToValue boxes a typed map into a dynamic value. The box is built once and kept on the map, so every crossing of the same map hands back the same object: a JavaScript Map is a reference, and two boxes would compare unequal under === and print as two values under console.log even though the program has one map.

func (*Map[K, V]) Values

func (m *Map[K, V]) Values() []V

Values returns the map's values in insertion order, the traversal map.values() and a for...of over the values read. It copies the backing slice for the same reason Keys does, so the two snapshots a for-of over entries pairs are consistent and stable across a body that mutates the map.

type ModuleSlot

type ModuleSlot struct {
	// contains filtered or unexported fields
}

ModuleSlot is the per-module cache the compiled CommonJS loader guards its body with, so a module required more than once runs its body once and every require returns the one exports value. Each required module emits one package-level slot and one loader function; the loader consults the slot before running the body, which is what makes require idempotent the way Node's module cache is.

func NewModuleSlot

func NewModuleSlot() *ModuleSlot

NewModuleSlot returns an empty cache slot, the zero state a module holds before its loader first runs.

func (*ModuleSlot) Exports

func (s *ModuleSlot) Exports() Value

Exports returns the module's current exports, the value a repeated or re-entrant require resolves to. During the body it is the initial exports object, so a circular require observes the exports built so far; after the body it is whatever module.exports finally names. This is exactly Node's rule that a cyclic require yields the partially populated exports rather than looping.

func (*ModuleSlot) Finish

func (s *ModuleSlot) Finish(module Value) Value

Finish caches the module's final exports, read back off the module object so a body that reassigned module.exports wholesale returns the new value rather than the initial object, and returns it as the loader's result. A body that only mutated exports leaves module.exports naming the initial object, so the cached value is unchanged from Init.

func (*ModuleSlot) Init

func (s *ModuleSlot) Init() Value

Init marks the slot loaded and builds the module object with a fresh exports object, caching that exports object before the body runs so a circular require re-entering the loader returns the partial exports. It returns the module object the loader binds its module local to; the exports local reads module.exports off it.

func (*ModuleSlot) Loaded

func (s *ModuleSlot) Loaded() bool

Loaded reports whether the module's body has already started running, so the loader can return the cached exports instead of running the body again. It is true from the moment Init runs, before the body finishes, so a circular require that re-enters the loader mid-body sees a loaded slot and takes the cached path.

type Object

type Object struct {
	// contains filtered or unexported fields
}

Object is the storage behind a KindObject or KindArray value. A plain object keeps its properties in insertion order as parallel key and value slices, the order JavaScript enumerates and serializes in. An array keeps its elements in a dense slice, separate from named properties, because indices are hot and must not go through the property map. One struct backs both so an array can still carry a named property without changing representation.

type Opt

type Opt[T any] struct {
	// contains filtered or unexported fields
}

Opt is bento's runtime representation of the type T | undefined, the exact monomorphized optional 05_type_lowering.md reaches for when a value is a concrete type or the one missing value undefined. A method whose declared return is T | undefined (Array.prototype.pop, at, find) lowers to a function returning Opt[T], and a binding of that type is a Go variable of type Opt[T].

It is deliberately not the fully boxed dynamic Value: when the only alternative to T is undefined, a present flag beside a T slot captures the whole type with no interface boxing and no allocation, so the optional path stays as cheap as the value it wraps. A genuine union of unlike types (the tagged sum) is a different representation and a later slice.

The zero Opt[T] is the undefined case, which makes None[T]() a plain zero value and means a freshly declared optional reads as undefined before assignment, matching a JavaScript binding that has not been given a defined value.

func None

func None[T any]() Opt[T]

None is the undefined optional. It is the zero Opt[T], written as a function so the lowerer has a spelling for undefined at a known element type; the result is identical to the zero value a declared-but-unassigned optional already holds.

func OptMap

func OptMap[T, U any](o Opt[T], f func(T) U) Opt[U]

OptMap reads a member of the wrapped value when present and returns it as a new optional, the lowering of a single link of an optional chain a?.b: when a holds a value f reads the member off it, and when a is undefined the whole chain short-circuits to undefined and f never runs, so the member read is never reached on a missing receiver. It is a free function rather than a method because a method cannot introduce the second type parameter the mapped element needs. Longer chains compose by nesting: a?.b?.c lowers to OptMap over the OptMap that produced a?.b, each link mapping only when the one before it was present.

func Some

func Some[T any](v T) Opt[T]

Some wraps a present value, the Opt an expression of type T flows into when the context wants T | undefined, and what a producer returns when it has a value.

func SymbolKeyFor

func SymbolKeyFor(v Value) Opt[BStr]

SymbolKeyFor returns the registry key a symbol was interned under, present when the symbol was created with Symbol.for and absent otherwise, the read Symbol.keyFor(sym) makes. It is only valid on a KindSymbol value, the shape the lowerer guarantees at the call site. The Opt[BStr] result matches how the checker types Symbol.keyFor as string|undefined: a typed slot takes the Opt directly and a boxed use flows it through value.OptToValue(_, value.StringValue).

func ToOptBoolean

func ToOptBoolean(v Value) Opt[bool]

ToOptBoolean coerces a dynamic Value into an optional boolean, undefined to the empty optional and any other value through ToBoolean. See ToOptNumber.

func ToOptNumber

func ToOptNumber(v Value) Opt[float64]

ToOptNumber coerces a dynamic Value into an optional number, the unboxing a value.Value flowing into a number | undefined slot needs: undefined stays the empty optional, and any other value coerces through ToNumber the way a bare number slot does. It is the dynamic-to-optional mirror of ToNumber, used when a boxed member read off a { } value narrowed by a type guard returns into an optional primitive slot.

func ToOptString

func ToOptString(v Value) Opt[BStr]

ToOptString coerces a dynamic Value into an optional string, undefined to the empty optional and any other value through ToString. See ToOptNumber.

func (Opt[T]) Get

func (o Opt[T]) Get() T

Get returns the wrapped value, the lowering of a use of an optional binding at a point where control-flow narrowing has already proved it is present (past an x !== undefined guard). On an undefined optional it returns the zero T, so a use the checker has not narrowed does not panic; that path is unreachable in code the checker accepted, since it would be a use of a possibly-undefined value where T is required.

func (Opt[T]) IsUndefined

func (o Opt[T]) IsUndefined() bool

IsUndefined reports whether the optional holds no value, the lowering of an x === undefined test (its negation lowers an x !== undefined test). It is the only way the generated code inspects an optional without first narrowing it, so a comparison against undefined never has to touch the wrapped slot.

func (Opt[T]) Or

func (o Opt[T]) Or(fallback T) T

Or returns the wrapped value when present, otherwise the fallback, the lowering of a ?? b where a is T | undefined and b is T. For an optional the one nullish value is undefined, so present is exactly the "not nullish" test ?? runs. The fallback is passed by value, so the lowerer only emits this form when b is side-effect free; a pure b evaluated eagerly cannot be observed to run early, which keeps the short-circuit ?? gives observationally intact.

func (Opt[T]) OrOpt

func (o Opt[T]) OrOpt(fallback Opt[T]) Opt[T]

OrOpt returns the optional itself when present, otherwise the fallback optional, the lowering of a ?? b where both a and b are T | undefined, so the result is still optional. The same eager-evaluation rule as Or applies to the fallback.

type PlainDate

type PlainDate struct {
	// contains filtered or unexported fields
}

PlainDate is bento's runtime representation of a Temporal.PlainDate (Temporal §3): a calendar date with no time and no zone, held as an ISO year, month, and day paired with a calendar that interprets them. Every PlainDate stores its date over the proleptic Gregorian (ISO 8601) calendar the way Temporal does internally; the cal field names the calendar the getters report under, "" reading as iso8601. This slice hosts the ISO 8601 calendar and the proleptic Gregorian calendar, whose date arithmetic is the ISO one with an era; a calendar bento does not host yet hands back at lowering, so cal is always "" or "gregory".

The three date fields are the proleptic Gregorian year, the month in 1..12, and the day in 1..(days in that month). They are stored as the integers RejectISODate validated, so every derived accessor (the weekday, the day of the year, the leap flag) recomputes from them rather than caching a second copy. The calendar-dependent getters the checker types as an optional read as the value the calendar gives them: era and eraYear are undefined under ISO but read the gregory era under gregory, and weekOfYear and yearOfWeek are the ISO 8601 week date computed from the ordinal day and the weekday, which the gregory calendar shares.

func NewPlainDate

func NewPlainDate(isoYear, isoMonth, isoDay float64) *PlainDate

NewPlainDate builds a PlainDate from the constructor's three number arguments, running ToIntegerWithTruncation on each and then RejectISODate, so a fractional argument truncates toward zero, a non-finite one throws a RangeError, and an out-of-range or out-of-limits date throws a RangeError, the same order new Temporal.PlainDate(y, m, d) follows in the specification. A fourth calendar argument is not accepted here; a non-ISO calendar hands back at lowering, so this constructor is only ever reached for the ISO calendar.

func NewPlainDateCal

func NewPlainDateCal(isoYear, isoMonth, isoDay float64, calendar string) *PlainDate

NewPlainDateCal builds a PlainDate under a named calendar, the four-argument constructor new Temporal.PlainDate(y, m, d, calendar). It follows the specification order: ToIntegerWithTruncation on each component first, so a non-finite one throws a RangeError, then CanonicalizeCalendar, so an unhosted or invalid id throws a RangeError, then RejectISODate, so an out-of-range date throws. The date fields are the ISO date the components spell; the calendar only changes how the getters label them.

func NowPlainDateISO

func NowPlainDateISO() *PlainDate

NowPlainDateISO implements Temporal.Now.plainDateISO, the calendar date the host default zone reads at the current instant.

func NowPlainDateISOIn

func NowPlainDateISOIn(timeZone BStr) *PlainDate

NowPlainDateISOIn is Temporal.Now.plainDateISO(timeZone), the calendar date in the named zone.

func PlainDateFrom

func PlainDateFrom(pd *PlainDate) *PlainDate

PlainDateFrom implements Temporal.PlainDate.from for a PlainDate argument: it returns a fresh PlainDate with the same fields, the copy the specification makes so the result is a distinct object that compares equal to its source. from over a string or a property bag hands back at lowering, so this is only reached with a PlainDate in hand.

func PlainDateFromFields

func PlainDateFromFields(year, month, day float64, calendar, overflow string) *PlainDate

PlainDateFromFields implements Temporal.PlainDate.from over a property bag: it builds a PlainDate from the required year, month, and day fields under the given calendar, regulating the result with the overflow option. The year is read in the calendar's own reckoning, so a roc bag year maps back to the ISO year by adding 1911 while the other hosted calendars count the ISO year directly. Under constrain the month clamps to 1..12 and the day to that month's length; under reject an out-of-range field throws a RangeError. The calendar is canonicalized and validated, so an unhosted id throws, though the lowerer only routes a hosted one here.

func PlainDateFromString

func PlainDateFromString(s string) *PlainDate

PlainDateFromString implements Temporal.PlainDate.from over a string: it parses the ISO date, applies the calendar annotation, and builds the PlainDate. A string the grammar rejects, a date outside the representable range, a Z designator (a Plain type has no zone to resolve it against), or a calendar bento does not host each throws a RangeError, matching the specification. The time, offset, and time-zone annotation a full date-time string may carry are parsed for validation and then dropped, since a PlainDate keeps only the date.

func PlainDateWithCalendar

func PlainDateWithCalendar(pd *PlainDate, calendar string) *PlainDate

PlainDateWithCalendar implements Temporal.PlainDate.prototype.withCalendar: it reinterprets the same ISO date under another calendar, returning a fresh PlainDate with the given calendar id. The id is canonicalized and validated, so an unhosted or invalid one throws a RangeError.

func (*PlainDate) AddDate

func (pd *PlainDate) AddDate(dur *Duration, overflow string) *PlainDate

AddDate implements Temporal.PlainDate.prototype.add and, over a negated Duration, subtract. A PlainDate has no clock, so the duration's time components fold into a whole-day carry truncated toward zero and the sub-day remainder is dropped; that carry joins the duration's days, and the years, months, weeks, and days add through addISODate under the overflow rule. The result keeps the receiver's calendar, whose year and era re-derive from the moved ISO date, and an out-of-range result throws a RangeError.

func (*PlainDate) CalendarId

func (pd *PlainDate) CalendarId() BStr

CalendarId returns the calendar identifier, "iso8601", "gregory", "roc", or "japanese".

func (*PlainDate) Day

func (pd *PlainDate) Day() float64

Day returns the ISO day of the month.

func (*PlainDate) DayOfWeek

func (pd *PlainDate) DayOfWeek() float64

DayOfWeek returns the ISO day of the week, Monday=1 through Sunday=7. The epoch day 1970-01-01 is a Thursday (ISO 4), which fixes the offset.

func (*PlainDate) DayOfYear

func (pd *PlainDate) DayOfYear() float64

DayOfYear returns the 1-based ordinal day within the year.

func (*PlainDate) DaysInMonth

func (pd *PlainDate) DaysInMonth() float64

DaysInMonth returns the number of days in this date's month.

func (*PlainDate) DaysInWeek

func (pd *PlainDate) DaysInWeek() float64

DaysInWeek is always 7 in the ISO calendar.

func (*PlainDate) DaysInYear

func (pd *PlainDate) DaysInYear() float64

DaysInYear returns 366 in a leap year and 365 otherwise.

func (*PlainDate) Equals

func (pd *PlainDate) Equals(other *PlainDate) bool

Equals implements Temporal.PlainDate.prototype.equals: two dates are equal when their year, month, and day match and they carry the same calendar, so the same ISO day under iso8601 and under gregory does not compare equal.

func (*PlainDate) Era

func (pd *PlainDate) Era() Opt[BStr]

Era implements Temporal.PlainDate.prototype.era. The ISO 8601 calendar has no era, so the getter the checker types string | undefined is undefined under ISO. gregory and roc split their timeline at their own year 1: a display year of 1 or above is the base era and 0 or below the "-inverse" era, gregory at ISO year 1 and roc at ISO year 1912. japanese resolves its era from the whole date against the nengo table.

func (*PlainDate) EraYear

func (pd *PlainDate) EraYear() Opt[float64]

EraYear implements Temporal.PlainDate.prototype.eraYear, the year counted within the era. It is undefined under ISO; under gregory or roc it is the display year itself in the base era and 1 minus the display year in the "-inverse" era, so under gregory ISO year 0 is eraYear 1 and under roc ISO year 1911 (roc year 0) is eraYear 1 in the "roc-inverse" era. japanese counts within the nengo the date falls in.

func (*PlainDate) InLeapYear

func (pd *PlainDate) InLeapYear() bool

InLeapYear reports whether this date's year is an ISO leap year.

func (*PlainDate) Month

func (pd *PlainDate) Month() float64

Month returns the ISO month, 1..12.

func (*PlainDate) MonthCode

func (pd *PlainDate) MonthCode() BStr

MonthCode returns the ISO month code, "M" followed by the two-digit month. The ISO calendar has no leap months, so the code never carries the trailing "L".

func (*PlainDate) MonthsInYear

func (pd *PlainDate) MonthsInYear() float64

MonthsInYear is always 12 in the ISO calendar.

func (*PlainDate) Since

func (pd *PlainDate) Since(other *PlainDate, largestUnit string) *Duration

Since returns the calendar difference from other to the receiver, the negation of Until, so the month anchoring stays on the receiver.

func (*PlainDate) ToJSON

func (pd *PlainDate) ToJSON() BStr

ToJSON implements Temporal.PlainDate.prototype.toJSON, the same ISO string toString produces under default options.

func (*PlainDate) ToPlainDateTime

func (pd *PlainDate) ToPlainDateTime(time *PlainTime) *PlainDateTime

ToPlainDateTime implements Temporal.PlainDate.prototype.toPlainDateTime: it pairs the date with a wall-clock time to make a PlainDateTime, defaulting to midnight when no time is given. The result keeps this date's calendar, so a non-ISO date stays under its calendar. The receiver is copied, so the new PlainDateTime shares no state with it.

func (*PlainDate) ToPlainMonthDay

func (pd *PlainDate) ToPlainMonthDay() *PlainMonthDay

ToPlainMonthDay implements Temporal.PlainDate.prototype.toPlainMonthDay: it narrows the date to its month and day, dropping the year, under the date's own calendar. The result keeps that calendar, so a non-ISO month-day carries the leap reference year 1972 and the annotation in its toString. The four hosted calendars share the ISO month structure, so the month and day pass through unchanged.

func (*PlainDate) ToPlainYearMonth

func (pd *PlainDate) ToPlainYearMonth() *PlainYearMonth

ToPlainYearMonth implements Temporal.PlainDate.prototype.toPlainYearMonth: it narrows the date to its year and month, dropping the day, under the date's own calendar. The result keeps that calendar, so its year getter and toString read in the calendar's reckoning and a non-ISO year-month carries the reference day the first of the month.

func (*PlainDate) ToString

func (pd *PlainDate) ToString() BStr

ToString implements Temporal.PlainDate.prototype.toString for the default options: the ISO 8601 date, YYYY-MM-DD, with the year expanded to a signed six-digit form outside 0..9999.

func (*PlainDate) ToZonedDateTime

func (pd *PlainDate) ToZonedDateTime(timeZone string, plainTime *PlainTime) *ZonedDateTime

ToZonedDateTime implements Temporal.PlainDate.prototype.toZonedDateTime: it pins the date, at a wall-clock time defaulting to midnight, to a time zone, resolving the exact instant under the default compatible disambiguation, which takes the earlier reading in a fall-back overlap and shifts forward across a spring-forward gap. The result keeps this date's calendar, so a non-ISO date stays under its calendar.

func (*PlainDate) Until

func (pd *PlainDate) Until(other *PlainDate, largestUnit string) *Duration

Until returns the calendar difference from the receiver to other as a Duration, balanced from largestUnit down to days.

func (*PlainDate) WeekOfYear

func (pd *PlainDate) WeekOfYear() Opt[float64]

WeekOfYear implements Temporal.PlainDate.prototype.weekOfYear, the ISO 8601 week number 1..53. The ISO calendar always defines it, so the optional the checker types number | undefined is always present; a calendar without weeks would read undefined, which is why the field is optional at all.

func (*PlainDate) WithFields

func (pd *PlainDate) WithFields(year, month, day Opt[float64], overflow string) *PlainDate

WithFields implements Temporal.PlainDate.prototype.with: it lays the bag's present year, month, and day over the receiver's own fields and regulates the result with the overflow option, so an omitted field keeps its current value. The year is read in the receiver's calendar reckoning, so under roc a bag year maps back to the ISO year the date stores by adding 1911; the other hosted calendars count the ISO year directly. Under constrain the month clamps to 1..12 and the day to that month's length, so with month 2 over January 31 lands on the last day of February; under reject an out-of-range field throws a RangeError. A literal monthCode the lowerer resolves to its numeric month before the call, the same month the getter reports since the hosted calendars have no leap month; the era fields the lowerer hands back. The receiver is unchanged.

func (*PlainDate) Year

func (pd *PlainDate) Year() float64

Year returns the year the calendar counts: the ISO year under iso8601 and gregory, and the ISO year minus 1911 under roc.

func (*PlainDate) YearOfWeek

func (pd *PlainDate) YearOfWeek() Opt[float64]

YearOfWeek implements Temporal.PlainDate.prototype.yearOfWeek, the ISO 8601 week-numbering year that pairs with weekOfYear. It differs from the calendar year at a January or December boundary, where a week belongs to the neighbouring year.

type PlainDateTime

type PlainDateTime struct {
	// contains filtered or unexported fields
}

PlainDateTime is bento's runtime representation of a Temporal.PlainDateTime (Temporal §5): a calendar date paired with a wall-clock time, no zone. It is exactly a PlainDate and a PlainTime carried together, so it holds one of each and delegates every field, every string rendering, and both comparisons to them rather than restating the calendar and the time math. It carries whatever calendar its date does, iso8601 or gregory in this slice, so era and eraYear and the [u-ca=...] annotation follow from the date half.

func NewPlainDateTime

func NewPlainDateTime(isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond float64) *PlainDateTime

NewPlainDateTime builds a PlainDateTime from the constructor's three date arguments and up to six time arguments (isoYear, isoMonth, isoDay, then hour, minute, second, millisecond, microsecond, nanosecond). It runs ToIntegerWithTruncation on every argument first, so a NaN or non-finite component throws a RangeError before any range check, then RejectISODate and RejectTime, so an out-of-range date or time throws a RangeError, the order new Temporal.PlainDateTime(...) follows in the specification. Every time argument defaults to zero; the lowerer pads the missing trailing components before the call, so this constructor always sees nine numbers.

func NewPlainDateTimeCal

func NewPlainDateTimeCal(isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond float64, calendar string) *PlainDateTime

NewPlainDateTimeCal builds a PlainDateTime under a named calendar, the ten-argument constructor new Temporal.PlainDateTime(y, mo, d, h, mi, s, ms, us, ns, calendar). It mirrors NewPlainDateTime with the specification's calendar step folded in: the components truncate first, then the calendar is canonicalized, so an unhosted id throws a RangeError, then the date and time are rejected.

func NowPlainDateTimeISO

func NowPlainDateTimeISO() *PlainDateTime

NowPlainDateTimeISO implements Temporal.Now.plainDateTimeISO, the wall-clock date and time the host default zone reads at the current instant.

func NowPlainDateTimeISOIn

func NowPlainDateTimeISOIn(timeZone BStr) *PlainDateTime

NowPlainDateTimeISOIn is Temporal.Now.plainDateTimeISO(timeZone), the wall-clock reading in the named zone.

func PlainDateTimeFrom

func PlainDateTimeFrom(pdt *PlainDateTime) *PlainDateTime

PlainDateTimeFrom implements Temporal.PlainDateTime.from for a PlainDateTime argument: it returns a fresh PlainDateTime with the same date and time, the copy the specification makes so the result is a distinct object that compares equal to its source. from over a string or a property bag hands back at lowering, so this is only reached with a PlainDateTime in hand.

func PlainDateTimeFromFields

func PlainDateTimeFromFields(year, month, day float64, hour, minute, second, millisecond, microsecond, nanosecond Opt[float64], calendar, overflow string) *PlainDateTime

PlainDateTimeFromFields implements Temporal.PlainDateTime.from over a property bag: it builds a PlainDateTime from the required year, month, and day fields plus the optional time fields under the given calendar, regulating each half with the overflow option. The date half reuses PlainDateFromFields, so the year is read in the calendar's own reckoning and the day clamps to the resulting month under constrain; the time half lays the present fields over an all-zero base so an omitted time field defaults to the zero midnight carries, then clamps to its ISO maxima. Under reject an out-of-range field in either half throws a RangeError. The result keeps the calendar, so a roc bag stays under roc.

func PlainDateTimeFromString

func PlainDateTimeFromString(s string) *PlainDateTime

PlainDateTimeFromString implements Temporal.PlainDateTime.from over a string. It reads a date, optionally followed by a time it keeps, so a date-only string like "2024-06-30" is accepted with the time defaulting to midnight while a full date-time string keeps its time. A grammar the parser rejects, a date outside the representable range, a Z designator (a Plain type has no zone to resolve it against), or a calendar bento does not host each throws a RangeError. A time-only string with no date is rejected, since the grammar this method accepts always begins with a date. The offset and time-zone annotation a string may carry are parsed for validation and then dropped.

func PlainDateTimeWithCalendar

func PlainDateTimeWithCalendar(pdt *PlainDateTime, calendar string) *PlainDateTime

PlainDateTimeWithCalendar implements Temporal.PlainDateTime.prototype.withCalendar: it reinterprets the same ISO date and time under another calendar, returning a fresh PlainDateTime. The id is canonicalized and validated, so an unhosted or invalid one throws a RangeError.

func (*PlainDateTime) AddDateTime

func (pdt *PlainDateTime) AddDateTime(dur *Duration, overflow string) *PlainDateTime

AddDateTime implements Temporal.PlainDateTime.prototype.add and, over a negated Duration, subtract. Unlike a PlainDate, which drops the duration's sub-day time part, a PlainDateTime carries a wall clock, so the time part folds into the clock first: the duration's six time components add to the receiver's time, and the total splits into a time of day in [0, one day) and a whole-day carry, floored so a net-negative time lands on the previous day's clock. That carry joins the duration's days, and the years, months, weeks, and days add to the date through addISODate under the overflow rule. The result keeps the receiver's calendar, and an out-of-range date throws a RangeError.

func (*PlainDateTime) CalendarId

func (pdt *PlainDateTime) CalendarId() BStr

CalendarId returns the calendar identifier the date half carries.

func (*PlainDateTime) Day

func (pdt *PlainDateTime) Day() float64

Day returns the ISO day of the month.

func (*PlainDateTime) DayOfWeek

func (pdt *PlainDateTime) DayOfWeek() float64

DayOfWeek returns the ISO day of the week, Monday=1 through Sunday=7.

func (*PlainDateTime) DayOfYear

func (pdt *PlainDateTime) DayOfYear() float64

DayOfYear returns the 1-based ordinal day within the year.

func (*PlainDateTime) DaysInMonth

func (pdt *PlainDateTime) DaysInMonth() float64

DaysInMonth returns the number of days in this date's month.

func (*PlainDateTime) DaysInWeek

func (pdt *PlainDateTime) DaysInWeek() float64

DaysInWeek is always 7 in the ISO calendar.

func (*PlainDateTime) DaysInYear

func (pdt *PlainDateTime) DaysInYear() float64

DaysInYear returns 366 in a leap year and 365 otherwise.

func (*PlainDateTime) Equals

func (pdt *PlainDateTime) Equals(other *PlainDateTime) bool

Equals implements Temporal.PlainDateTime.prototype.equals: two date-times are equal when their dates and their times are each equal under the same (ISO) calendar.

func (*PlainDateTime) Era

func (pdt *PlainDateTime) Era() Opt[BStr]

Era, EraYear, WeekOfYear, and YearOfWeek read the calendar-dependent fields off the date half, so a date-time answers them the same as the date it carries: era and eraYear undefined under ISO and the gregory era under gregory, weekOfYear and yearOfWeek the ISO 8601 week date.

func (*PlainDateTime) EraYear

func (pdt *PlainDateTime) EraYear() Opt[float64]

func (*PlainDateTime) Hour

func (pdt *PlainDateTime) Hour() float64

Hour returns the hour, 0..23.

func (*PlainDateTime) InLeapYear

func (pdt *PlainDateTime) InLeapYear() bool

InLeapYear reports whether this date's year is an ISO leap year.

func (*PlainDateTime) Microsecond

func (pdt *PlainDateTime) Microsecond() float64

Microsecond returns the microsecond, 0..999.

func (*PlainDateTime) Millisecond

func (pdt *PlainDateTime) Millisecond() float64

Millisecond returns the millisecond, 0..999.

func (*PlainDateTime) Minute

func (pdt *PlainDateTime) Minute() float64

Minute returns the minute, 0..59.

func (*PlainDateTime) Month

func (pdt *PlainDateTime) Month() float64

Month returns the ISO month, 1..12.

func (*PlainDateTime) MonthCode

func (pdt *PlainDateTime) MonthCode() BStr

MonthCode returns the ISO month code, "M" followed by the two-digit month.

func (*PlainDateTime) MonthsInYear

func (pdt *PlainDateTime) MonthsInYear() float64

MonthsInYear is always 12 in the ISO calendar.

func (*PlainDateTime) Nanosecond

func (pdt *PlainDateTime) Nanosecond() float64

Nanosecond returns the nanosecond, 0..999.

func (*PlainDateTime) Round

func (pdt *PlainDateTime) Round(smallestUnit string, increment float64, roundingMode string) *PlainDateTime

Round implements Temporal.PlainDateTime.prototype.round: it rounds the wall clock to a multiple of roundingIncrement of smallestUnit under one of the nine rounding modes, carrying a whole day into the date when the clock rounds up past midnight. The day unit rounds the whole date-time to the nearest midnight, so its increment must be exactly one; the time units fix their quantum and the divisor the increment must divide the same way PlainTime.round does. An increment out of range throws a RangeError, and an out-of-range carried date does too. The receiver is unchanged.

func (*PlainDateTime) Second

func (pdt *PlainDateTime) Second() float64

Second returns the second, 0..59.

func (*PlainDateTime) Since

func (pdt *PlainDateTime) Since(other *PlainDateTime, largestUnit string) *Duration

Since returns the negation of the receiver-to-other difference.

func (*PlainDateTime) ToJSON

func (pdt *PlainDateTime) ToJSON() BStr

ToJSON implements Temporal.PlainDateTime.prototype.toJSON, the same ISO string toString produces under default options.

func (*PlainDateTime) ToPlainDate

func (pdt *PlainDateTime) ToPlainDate() *PlainDate

ToPlainDate implements Temporal.PlainDateTime.prototype.toPlainDate: the calendar date half of the date-time, carrying the same calendar, with the clock dropped.

func (*PlainDateTime) ToPlainTime

func (pdt *PlainDateTime) ToPlainTime() *PlainTime

ToPlainTime implements Temporal.PlainDateTime.prototype.toPlainTime: the wall-clock half of the date-time, with the calendar date dropped.

func (*PlainDateTime) ToString

func (pdt *PlainDateTime) ToString() BStr

ToString implements Temporal.PlainDateTime.prototype.toString for the default options: the ISO 8601 date and time joined by "T", each rendered as its own type renders it, so the fractional-second part appears only when a sub-second field is set.

func (*PlainDateTime) ToZonedDateTime

func (pdt *PlainDateTime) ToZonedDateTime(timeZone, disambiguation string) *ZonedDateTime

ToZonedDateTime implements Temporal.PlainDateTime.prototype.toZonedDateTime: it pins the date-time's wall clock to a time zone, resolving the exact instant under the given disambiguation. compatible (the default) takes the earlier reading in a fall-back overlap and shifts forward across a spring-forward gap; earlier and later pick the two overlap readings and the two sides of a gap; reject throws on an ambiguous or gapped reading. The result keeps the date-time's calendar, so a non-ISO date-time stays under its calendar.

func (*PlainDateTime) Until

func (pdt *PlainDateTime) Until(other *PlainDateTime, largestUnit string) *Duration

Until returns the difference from the receiver to other as a Duration balanced from largestUnit down. Since returns the difference from other to the receiver, the negation of Until, so the month anchoring stays on the receiver the way the specification requires.

func (*PlainDateTime) WeekOfYear

func (pdt *PlainDateTime) WeekOfYear() Opt[float64]

func (*PlainDateTime) WithFields

func (pdt *PlainDateTime) WithFields(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond Opt[float64], overflow string) *PlainDateTime

WithFields implements Temporal.PlainDateTime.prototype.with: it lays the bag's present date and time fields over the receiver's own and regulates each half with the overflow option, so an omitted field keeps its current value. The date half regulates exactly as PlainDate.with, so the year is read in the receiver's calendar reckoning and the day clamps to the resulting month's length under constrain; the time half clamps to its ISO maxima under constrain. Under reject an out-of-range field in either half throws a RangeError. A literal monthCode the lowerer resolves to its numeric month before the call; the era fields the lowerer hands back. The receiver is unchanged and its calendar carries through.

func (*PlainDateTime) WithPlainTime

func (pdt *PlainDateTime) WithPlainTime(time *PlainTime) *PlainDateTime

WithPlainTime implements Temporal.PlainDateTime.prototype.withPlainTime: it keeps the calendar date and replaces the wall clock, defaulting to midnight when no time is given. The result keeps this date-time's calendar, so a non-ISO date-time stays under its calendar. The receiver's date is copied, so the new PlainDateTime shares no state with it.

func (*PlainDateTime) Year

func (pdt *PlainDateTime) Year() float64

Year returns the ISO year.

func (*PlainDateTime) YearOfWeek

func (pdt *PlainDateTime) YearOfWeek() Opt[float64]

type PlainMonthDay

type PlainMonthDay struct {
	// contains filtered or unexported fields
}

PlainMonthDay is bento's runtime representation of a Temporal.PlainMonthDay (Temporal §10): a calendar month and day with no year, no time, and no zone, the way a birthday or a holiday recurs every year. Like PlainDate it hosts only the ISO 8601 calendar; a non-ISO calendar hands back at lowering. The specification anchors a month-day to a reference ISO year so a calendar can resolve which day the pair falls on; the ISO calendar needs it only to admit February 29, so this type stores the month and day and validates against the fixed leap reference year without keeping it.

func NewPlainMonthDay

func NewPlainMonthDay(isoMonth, isoDay float64) *PlainMonthDay

NewPlainMonthDay builds a PlainMonthDay from the constructor's two number arguments, the month first and the day second, running ToIntegerWithTruncation on each and then RejectISOMonthDay, so a fractional argument truncates toward zero, a non-finite one throws a RangeError, and a month outside 1..12 or a day out of range for that month throws a RangeError. A third calendar argument and a fourth reference-year argument are not accepted here; both hand back at lowering, so this constructor is only ever reached for the ISO calendar with the default reference year.

func PlainMonthDayFrom

func PlainMonthDayFrom(md *PlainMonthDay) *PlainMonthDay

PlainMonthDayFrom implements Temporal.PlainMonthDay.from for a PlainMonthDay argument: it returns a fresh PlainMonthDay with the same fields, the copy the specification makes. from over a string or a property bag hands back at lowering.

func PlainMonthDayFromFields

func PlainMonthDayFromFields(month, day float64, year Opt[float64], overflow string) *PlainMonthDay

PlainMonthDayFromFields implements Temporal.PlainMonthDay.from over a property bag for the ISO calendar. The month and day are required, so the lowerer only reaches here with concrete values; a monthCode is resolved to its numeric month at lowering. A year is optional: when present it sets the year the day is validated against, so February 29 with a common year constrains to the 28th, and when absent the leap reference year 1972 admits February 29. Under reject an out-of-range month or day throws; under the default constrain each clamps into range.

func PlainMonthDayFromString

func PlainMonthDayFromString(s string) *PlainMonthDay

PlainMonthDayFromString implements Temporal.PlainMonthDay.from over a string. It reads a bare month-day string like "10-01" or "--10-01", whose year the type does not carry, or a full date or date-time string like "1976-10-01", whose month and day it keeps and whose year and time it drops. A grammar the parser rejects, an out-of-range month-day, an out-of-range day on a full-date string, a Z designator, or a non-ISO calendar each throws a RangeError. The full-date form validates the day against its real year, so "2024-06-31" throws, while the yearless form has no year and admits any day in 1..31, so "06-31" parses, matching the specification.

func (*PlainMonthDay) CalendarId

func (md *PlainMonthDay) CalendarId() BStr

CalendarId returns the calendar identifier, "iso8601", "gregory", "roc", or "japanese".

func (*PlainMonthDay) Day

func (md *PlainMonthDay) Day() float64

Day returns the ISO day of the month.

func (*PlainMonthDay) Equals

func (md *PlainMonthDay) Equals(other *PlainMonthDay) bool

Equals implements Temporal.PlainMonthDay.prototype.equals: two month-days are equal when their month and day match under the same calendar.

func (*PlainMonthDay) MonthCode

func (md *PlainMonthDay) MonthCode() BStr

MonthCode returns the ISO month code, "M" followed by the two-digit month. The ISO calendar has no leap months, so the code never carries the trailing "L". A month-day exposes its month only through this code, not through a numeric month getter.

func (*PlainMonthDay) ToJSON

func (md *PlainMonthDay) ToJSON() BStr

ToJSON implements Temporal.PlainMonthDay.prototype.toJSON, the same ISO string toString produces under default options.

func (*PlainMonthDay) ToPlainDate

func (md *PlainMonthDay) ToPlainDate(year float64) *PlainDate

ToPlainDate implements Temporal.PlainMonthDay.prototype.toPlainDate: it combines the month-day with the year from the argument bag into a PlainDate in the receiver's calendar. The year is read in the calendar's own reckoning, so a roc bag year maps back to the ISO year by adding 1911 while the other hosted calendars count the ISO year directly. The specification gives toPlainDate no overflow option, so the day always constrains to that year's month length, dropping February 29 to the 28th in a common year. An out-of-range result throws a RangeError.

func (*PlainMonthDay) ToString

func (md *PlainMonthDay) ToString() BStr

ToString implements Temporal.PlainMonthDay.prototype.toString for the default options. The ISO calendar prints MM-DD, hiding the reference year. A non-ISO calendar prints the full ISO reference date, the leap reference year 1972 followed by the month and day, then its "[u-ca=<id>]" annotation, so the calendar can resolve which day the pair falls on.

func (*PlainMonthDay) WithFields

func (md *PlainMonthDay) WithFields(month, day Opt[float64], overflow string) *PlainMonthDay

WithFields implements Temporal.PlainMonthDay.prototype.with: it lays the bag's present month and day over the receiver's own fields and regulates the result with the overflow option, so an omitted field keeps its current value. The day is validated against the leap reference year 1972, so February 29 is admitted. Under constrain the month clamps to 1..12 and the day to that month's length; under reject an out-of-range field throws a RangeError. A month code lowers to a numeric month at compile time, and a bag carrying a year hands back there, so only month and day reach here. The receiver is unchanged.

type PlainTime

type PlainTime struct {
	// contains filtered or unexported fields
}

PlainTime is bento's runtime representation of a Temporal.PlainTime (Temporal §4): a wall-clock time with no date and no zone, the hour, the minute, the second, and the three sub-second fields. It carries no calendar and no zone, so unlike PlainDate it needs no calendar model at all. The six fields are stored as the integers RejectTime validated, so every accessor reads a field directly and toString recomputes the fractional-second rendering from the sub-second three.

func NewPlainTime

func NewPlainTime(hour, minute, second, millisecond, microsecond, nanosecond float64) *PlainTime

NewPlainTime builds a PlainTime from the constructor's up to six number arguments, running ToIntegerWithTruncation on each and then RejectTime, so a fractional argument truncates toward zero, a NaN or non-finite one throws a RangeError, and an out-of-range field throws a RangeError, the order new Temporal.PlainTime(...) follows in the specification. Every argument defaults to zero; the lowerer pads the missing trailing components before the call, so this constructor always sees six numbers.

func NowPlainTimeISO

func NowPlainTimeISO() *PlainTime

NowPlainTimeISO implements Temporal.Now.plainTimeISO, the wall-clock time the host default zone reads at the current instant.

func NowPlainTimeISOIn

func NowPlainTimeISOIn(timeZone BStr) *PlainTime

NowPlainTimeISOIn is Temporal.Now.plainTimeISO(timeZone), the wall-clock time in the named zone.

func PlainTimeFrom

func PlainTimeFrom(pt *PlainTime) *PlainTime

PlainTimeFrom implements Temporal.PlainTime.from for a PlainTime argument: it returns a fresh PlainTime with the same fields, the copy the specification makes so the result is a distinct object that compares equal to its source. from over a string or a property bag hands back at lowering, so this is only reached with a PlainTime in hand.

func PlainTimeFromFields

func PlainTimeFromFields(hour, minute, second, millisecond, microsecond, nanosecond Opt[float64], overflow string) *PlainTime

PlainTimeFromFields implements Temporal.PlainTime.from over a property bag: it lays the bag's present fields over an all-zero base, so an omitted field defaults to the zero midnight carries, and regulates with the overflow option. The lowerer reads the bag at compile time, requires at least one time field, and passes each as a present or absent optional.

func PlainTimeFromString

func PlainTimeFromString(s string) *PlainTime

PlainTimeFromString implements Temporal.PlainTime.from over a string. It reads either a full date-time string, whose date it validates and whose time it keeps, or a time-only string; a date-only string with no time, a Z designator (a wall-clock time has no zone to resolve it against), or a syntax the grammar rejects each throws a RangeError. A calendar annotation is accepted and ignored whatever it names, since a PlainTime carries no calendar, so an unhosted or unknown identifier is not an error the way it is for a PlainDate.

func (*PlainTime) AddDuration

func (pt *PlainTime) AddDuration(dur *Duration) *PlainTime

AddDuration implements Temporal.PlainTime.prototype.add: it folds the duration's time units into the receiver's wall clock. Only the six time units count, since days, weeks, months, and years do not move the time of day, and the total wraps mod 24 hours, so adding past midnight lands on the following day's clock and a net-negative offset lands on the previous day's. The receiver is unchanged. subtract is add over a negated duration, so no separate SubtractDuration is needed. The fold runs in big.Int because an hour field can be up to 2^53 and hours-to-nanoseconds overflows int64.

func (*PlainTime) Equals

func (pt *PlainTime) Equals(other *PlainTime) bool

Equals implements Temporal.PlainTime.prototype.equals: two times are equal when all six fields match.

func (*PlainTime) Hour

func (pt *PlainTime) Hour() float64

Hour returns the hour, 0..23.

func (*PlainTime) Microsecond

func (pt *PlainTime) Microsecond() float64

Microsecond returns the microsecond, 0..999.

func (*PlainTime) Millisecond

func (pt *PlainTime) Millisecond() float64

Millisecond returns the millisecond, 0..999.

func (*PlainTime) Minute

func (pt *PlainTime) Minute() float64

Minute returns the minute, 0..59.

func (*PlainTime) Nanosecond

func (pt *PlainTime) Nanosecond() float64

Nanosecond returns the nanosecond, 0..999.

func (*PlainTime) Round

func (pt *PlainTime) Round(smallestUnit string, increment float64, roundingMode string) *PlainTime

Round implements Temporal.PlainTime.prototype.round: it rounds the wall clock to a multiple of roundingIncrement of smallestUnit under one of the nine rounding modes. The smallestUnit fixes the quantum in nanoseconds and the divisor the increment must divide, hour into 24, minute and second into 60, and each sub-second unit into 1000; an increment that is not a positive integer below the divisor and dividing it throws a RangeError. The rounded count wraps mod 24 hours, so rounding up from late in the day lands on the next day's clock. The receiver is unchanged.

func (*PlainTime) Second

func (pt *PlainTime) Second() float64

Second returns the second, 0..59.

func (*PlainTime) Since

func (pt *PlainTime) Since(other *PlainTime, largestUnit, smallestUnit string, increment float64, roundingMode string) *Duration

Since returns the signed wall-clock difference from other to the receiver, the reverse of Until. Both round the signed difference so the mode acts on the true sign, which matches the specification's rule of negating the mode and the result for since.

func (*PlainTime) ToJSON

func (pt *PlainTime) ToJSON() BStr

ToJSON implements Temporal.PlainTime.prototype.toJSON, the same ISO string toString produces under default options.

func (*PlainTime) ToString

func (pt *PlainTime) ToString() BStr

ToString implements Temporal.PlainTime.prototype.toString for the default options: HH:MM:SS, with a fractional-second part appended only when a sub-second field is set, rendered to the fewest digits (the nine-digit nanosecond total with trailing zeros trimmed). A time on the whole second renders without a fractional part at all.

func (*PlainTime) Until

func (pt *PlainTime) Until(other *PlainTime, largestUnit, smallestUnit string, increment float64, roundingMode string) *Duration

Until returns the signed wall-clock difference from the receiver to other as a Duration, balanced from largestUnit down and rounded at smallestUnit under roundingMode. The two times sit within one day, so the difference is under 24 hours before balancing.

func (*PlainTime) With

func (pt *PlainTime) With(hour, minute, second, millisecond, microsecond, nanosecond Opt[float64], overflow string) *PlainTime

With implements Temporal.PlainTime.prototype.with: it lays the bag's present fields over the receiver's current fields, so an omitted field keeps its existing value, and regulates with the overflow option. The result is a fresh PlainTime and the receiver is unchanged.

type PlainYearMonth

type PlainYearMonth struct {
	// contains filtered or unexported fields
}

PlainYearMonth is bento's runtime representation of a Temporal.PlainYearMonth (Temporal §9): a calendar year and month with no day, no time, and no zone, the way a credit card carries an expiry. Like PlainDate it hosts only the ISO 8601 calendar; a non-ISO calendar hands back at lowering. The specification anchors a year-month to a reference ISO day so a calendar can resolve calendar-dependent fields, but the ISO calendar needs no reference, so this type stores only the year and the month and derives every getter from them.

func NewPlainYearMonth

func NewPlainYearMonth(isoYear, isoMonth float64) *PlainYearMonth

NewPlainYearMonth builds a PlainYearMonth from the constructor's two number arguments, running ToIntegerWithTruncation on each and then RejectISOYearMonth, so a fractional argument truncates toward zero, a non-finite one throws a RangeError, and a month outside 1..12 or a year-month outside the representable range throws a RangeError. A third calendar argument and a fourth reference-day argument are not accepted here; both hand back at lowering, so this constructor is only ever reached for the ISO calendar with the default reference day.

func PlainYearMonthFrom

func PlainYearMonthFrom(ym *PlainYearMonth) *PlainYearMonth

PlainYearMonthFrom implements Temporal.PlainYearMonth.from for a PlainYearMonth argument: it returns a fresh PlainYearMonth with the same fields, the copy the specification makes. from over a string or a property bag hands back at lowering.

func PlainYearMonthFromFields

func PlainYearMonthFromFields(year, month float64, overflow string) *PlainYearMonth

PlainYearMonthFromFields implements Temporal.PlainYearMonth.from over a property bag for the ISO calendar. The year and month the bag supplies are both required, so the lowerer only reaches here with concrete values; a monthCode is resolved to its numeric month at lowering. Under the default constrain a month outside 1..12 clamps into range; under reject it is a RangeError. Either way a year-month outside the representable range throws.

func PlainYearMonthFromString

func PlainYearMonthFromString(s string) *PlainYearMonth

PlainYearMonthFromString implements Temporal.PlainYearMonth.from over a string. It reads a bare year-month string like "2024-06", whose day the type does not carry, or a full date or date-time string like "2024-06-30", whose year and month it keeps and whose day and time it drops. A grammar the parser rejects, an out-of-range year-month, an out-of-range day on a full-date string, a Z designator, or a non-ISO calendar each throws a RangeError. The year-month-only form carries no time, so a "T" designator or a space after the month sends the string to the full parser, which needs a day, and both failing throws.

func (*PlainYearMonth) AddDuration

func (ym *PlainYearMonth) AddDuration(dur *Duration, overflow string) *PlainYearMonth

AddDuration implements Temporal.PlainYearMonth.prototype.add and, over a negated duration, subtract. A year-month has no day, so the specification anchors the arithmetic to a reference day: the first of the month when the duration runs forward, the last of the month when it runs backward, so a month step that would only survive by clamping a large day is never counted. The reference-day date carries the full duration through PlainDate.AddDate, which folds the time part into whole days, and the moved date narrows back to a year-month. The result keeps the receiver's calendar, and an out-of-range step or, under reject, a clamped day throws a RangeError.

func (*PlainYearMonth) CalendarId

func (ym *PlainYearMonth) CalendarId() BStr

CalendarId returns the calendar identifier, "iso8601", "gregory", "roc", or "japanese".

func (*PlainYearMonth) DaysInMonth

func (ym *PlainYearMonth) DaysInMonth() float64

DaysInMonth returns the number of days in this year-month's month.

func (*PlainYearMonth) DaysInYear

func (ym *PlainYearMonth) DaysInYear() float64

DaysInYear returns 366 in a leap year and 365 otherwise.

func (*PlainYearMonth) Equals

func (ym *PlainYearMonth) Equals(other *PlainYearMonth) bool

Equals implements Temporal.PlainYearMonth.prototype.equals: two year-months are equal when their year and month match under the same (ISO) calendar.

func (*PlainYearMonth) Era

func (ym *PlainYearMonth) Era() Opt[BStr]

Era implements Temporal.PlainYearMonth.prototype.era by resolving the era at the first of the year-month's month, so a year-month reports the same era the date it came from does. It is undefined under the ISO calendar.

func (*PlainYearMonth) EraYear

func (ym *PlainYearMonth) EraYear() Opt[float64]

EraYear implements Temporal.PlainYearMonth.prototype.eraYear, the year counted within the era at the first of the month. It is undefined under the ISO calendar.

func (*PlainYearMonth) InLeapYear

func (ym *PlainYearMonth) InLeapYear() bool

InLeapYear reports whether this year-month's year is an ISO leap year.

func (*PlainYearMonth) Month

func (ym *PlainYearMonth) Month() float64

Month returns the ISO month, 1..12.

func (*PlainYearMonth) MonthCode

func (ym *PlainYearMonth) MonthCode() BStr

MonthCode returns the ISO month code, "M" followed by the two-digit month. The ISO calendar has no leap months, so the code never carries the trailing "L".

func (*PlainYearMonth) MonthsInYear

func (ym *PlainYearMonth) MonthsInYear() float64

MonthsInYear is always 12 in the ISO calendar.

func (*PlainYearMonth) Since

func (ym *PlainYearMonth) Since(other *PlainYearMonth, largestUnit string) *Duration

Since implements Temporal.PlainYearMonth.prototype.since as the negation of Until, so a.since(b) is the span from b to a.

func (*PlainYearMonth) SubtractDuration

func (ym *PlainYearMonth) SubtractDuration(dur *Duration, overflow string) *PlainYearMonth

SubtractDuration implements Temporal.PlainYearMonth.prototype.subtract as AddDuration over the negated duration, so the reference day is chosen from the negated sign.

func (*PlainYearMonth) ToJSON

func (ym *PlainYearMonth) ToJSON() BStr

ToJSON implements Temporal.PlainYearMonth.prototype.toJSON, the same ISO string toString produces under default options.

func (*PlainYearMonth) ToPlainDate

func (ym *PlainYearMonth) ToPlainDate(day float64) *PlainDate

ToPlainDate implements Temporal.PlainYearMonth.prototype.toPlainDate: it combines the year-month with the day from the argument bag into a PlainDate in the receiver's calendar. The specification gives toPlainDate no overflow option, so the day always constrains to the month's length. An out-of-range result throws a RangeError.

func (*PlainYearMonth) ToString

func (ym *PlainYearMonth) ToString() BStr

ToString implements Temporal.PlainYearMonth.prototype.toString for the default options. The ISO calendar prints YYYY-MM, the year expanded to a signed six-digit form outside 0..9999 and the reference day hidden. A non-ISO calendar prints the full ISO reference date YYYY-MM-DD followed by its "[u-ca=<id>]" annotation; the four hosted calendars align their months with ISO months, so the reference day is the first of the month.

func (*PlainYearMonth) Until

func (ym *PlainYearMonth) Until(other *PlainYearMonth, largestUnit string) *Duration

Until implements Temporal.PlainYearMonth.prototype.until, the span from the receiver to the argument as a years-and-months Duration. Since implements the mirror by negating it.

func (*PlainYearMonth) WithFields

func (ym *PlainYearMonth) WithFields(year, month Opt[float64], overflow string) *PlainYearMonth

WithFields implements Temporal.PlainYearMonth.prototype.with: it lays the bag's present year and month over the receiver's own fields and regulates the result with the overflow option, so an omitted field keeps its current value. The year is read in the receiver's calendar reckoning, so under roc a bag year maps back to the ISO year by adding 1911; the other hosted calendars count the ISO year directly. Under constrain the month clamps to 1..12; under reject an out-of-range month throws a RangeError. A month code lowers to a numeric month at compile time, and a bag carrying the era fields or a day hands back there, so only year and month reach here. The receiver is unchanged.

func (*PlainYearMonth) Year

func (ym *PlainYearMonth) Year() float64

Year returns the year the calendar counts: the ISO year under iso8601, gregory, and japanese, and the ISO year minus 1911 under roc.

type Promise

type Promise[T any] struct {
	// contains filtered or unexported fields
}

Promise is a JavaScript promise of element type T. It holds its state and, once settled, either a fulfilled value or the thrown value a rejection carries. While pending it holds the reactions a Then, a Catch, or an await registered, which fire as microtasks when it settles. It is a pointer type so a promise has reference identity the way a JavaScript promise object does.

func All

func All[T any](ps *Array[*Promise[T]]) *Promise[*Array[T]]

All combines an array of promises into one promise of the array of their fulfilled values, the value.Promise side of Promise.all. It fulfills with the values in input order once every input has fulfilled, and rejects with the reason of the first input to reject, ignoring later settlements the way the first rejection wins. An empty input fulfills immediately with an empty array. Each input is subscribed, so a reaction runs at the microtask checkpoint when the input settles; the combined promise stays pending until its count reaches zero, then fulfills and flushes its own reactions.

func AllTuple

func AllTuple[T any](build func() T, ps ...Combinable) *Promise[T]

AllTuple combines promises of differing element types into one promise of the tuple of their fulfilled values, the value.Promise side of a Promise.all whose argument the checker typed as a tuple rather than an array. It settles by the same rule All does: it fulfills once every input has fulfilled, and rejects with the reason of the first input to reject, ignoring later settlements.

The difference is where the values come from. All can gather them itself because they share one type; here they do not, so build is the caller's closure over the very promises passed in, reading each one's Fulfilled at its own static type and packing them into the tuple struct. AllTuple calls it exactly once, at the moment the last input fulfills, so every read it makes is of a settled promise. An empty input fulfills immediately, the way Promise.all([]) does.

func Any

func Any[T any](ps *Array[*Promise[T]]) *Promise[T]

Any combines an array of promises into one promise that fulfills with the first input to fulfill, the value.Promise side of Promise.any: a rejection does not decide the race, so the result stays pending while rejections accumulate, and only when every input has rejected does it reject with an AggregateError whose errors array carries the rejection reasons in input order. An empty input has no promise that can fulfill, so it rejects at once with an AggregateError over no errors, matching Promise.any([]).

func Async

func Async[T any](body func() T) (p *Promise[T])

Async runs an await-free async body now and turns its completion into a settled promise: a normal return fulfills, and a thrown value (a Go panic carrying a Thrown, the payload every bento throw raises) rejects. This mirrors the JavaScript rule that a synchronous throw inside an async body becomes a rejected promise rather than propagating. A Go runtime panic (not a Thrown) is a runtime bug, not a program throw, so it is re-panicked to keep its original stack.

func AsyncVoid

func AsyncVoid(body func()) (p *Promise[Unit])

AsyncVoid is Async for an async body with no value, a Promise<void>. It runs the body and settles a unit promise: fulfilled on a normal return, rejected on a thrown value. The element type is Unit, the value model's no-value placeholder, so a void async method has a concrete Go result type like any other.

func NewPromise

func NewPromise[T any](executor func(resolve func(T), reject func(Value))) (p *Promise[T])

NewPromise mints a pending promise and runs executor now, passing it the resolve and reject callbacks that settle the promise. resolve fulfills with a value of the element type; reject settles as rejected, carrying the value it was handed through rejectionValue. An executor that throws (a Go panic carrying a Thrown, the payload every bento throw raises) rejects the promise with that thrown value, matching the rule that a synchronous throw inside the executor rejects rather than propagates. A Go runtime panic that is not a Thrown is a real bug and keeps its stack.

func Race

func Race[T any](ps *Array[*Promise[T]]) *Promise[T]

Race combines an array of promises into one promise that settles the way the first input to settle does, the value.Promise side of Promise.race: it fulfills with that input's value if it fulfilled, or rejects with its reason if it rejected, and later settlements are ignored once the race is decided. An empty input never settles, the forever-pending promise Promise.race([]) returns, so the loop simply subscribes nothing and the result stays pending.

func Rejected

func Rejected[T any](reason Thrown) *Promise[T]

Rejected mints a promise already rejected with reason, the promise an async body returns when it throws. The reason is the thrown value a catch would recover.

func Resolved

func Resolved[T any](v T) *Promise[T]

Resolved mints a promise already fulfilled with v, the promise an await-free async body returns when it runs to a normal completion.

func RunAsync

func RunAsync[T any](body func(*AsyncCo) T) *Promise[T]

RunAsync runs an async body that awaits and returns the promise it settles. The body runs in a goroutine up to its first await (or its completion if it never parks) and hands control back through parked, so RunAsync returns a pending promise the moment the body first suspends. A normal completion fulfills the promise with the body's value; a thrown value the body did not catch (a Go panic carrying a Thrown, the payload every bento throw raises) rejects it, matching the rule that a throw inside an async body becomes a rejection. A Go runtime panic that is not a Thrown is a real bug and keeps its stack.

func RunAsyncVoid

func RunAsyncVoid(body func(*AsyncCo)) *Promise[Unit]

RunAsyncVoid is RunAsync for an async body with no value, a Promise<void>. It runs the body and settles a unit promise: fulfilled on a normal completion, rejected on a thrown value the body did not catch.

func ThenFlat

func ThenFlat[T, U any](p *Promise[T], onFulfilled func(T) *Promise[U]) *Promise[U]

ThenFlat is Then for a callback that returns a promise, the adoption form p.then((v) => fetch(v)): the returned promise adopts the state of the promise the callback returns, fulfilling or rejecting the way that inner promise settles, so the chain flattens rather than nesting a promise of a promise. Like ThenMap a rejection of the receiver passes through and a callback that throws rejects the returned promise. The inner promise's value type is the returned promise's element type, so a following then reads the inner value directly.

func ThenMap

func ThenMap[T, U any](p *Promise[T], onFulfilled func(T) U) *Promise[U]

ThenMap is Then for a callback that returns a plain value, the chaining form p.then((v) => v + 1): the returned promise fulfills with the callback's result once the receiver fulfills, so a following then reads the mapped value. A rejection of the receiver passes straight through to the returned promise, since a then with no rejection handler forwards the rejection down the chain, and a callback that throws (a Go panic carrying a Thrown) rejects the returned promise rather than propagating. The receiver's and result's element types are inferred from the receiver and the callback, so a chain of thens carries each stage's value type without annotation.

func (*Promise[T]) Catch

func (p *Promise[T]) Catch(onRejected func(Value)) *Promise[Unit]

Catch schedules onRejected to run with the rejection reason at the next microtask checkpoint. A fulfilled promise does not run onRejected; its fulfillment passes through, so the returned promise fulfills and a following then still runs. The reason is handed over as a dynamic value: a caught rejection is typed any in JavaScript, so the callback reads it through the value model the way a catch binding boxed into the dynamic world does. Like Then it returns a fresh promise that settles only once the reaction has run, so a chained then or finally runs one turn later, and a callback that throws rejects the returned promise rather than swallowing the error.

func (*Promise[T]) Finally

func (p *Promise[T]) Finally(onFinally func()) *Promise[Unit]

Finally schedules onFinally to run when the promise settles, fulfilled or rejected alike, with no argument: the cleanup reaction .finally registers to run whichever way the promise ends. Like Then and Catch the callback is deferred to the microtask checkpoint, never inlined, so it runs after the synchronous code and in settle order among the reactions the promise gathered. It returns a fresh promise that settles only once the callback has run, so a chained reaction runs a turn later. A finally does not consume a rejection: the returned promise re-raises the receiver's rejection after the callback, and a callback that throws overrides it, the rules .finally follows.

func (*Promise[T]) Fulfilled

func (p *Promise[T]) Fulfilled() T

Fulfilled reads the value a settled promise fulfilled with. It is the accessor the build closure AllTuple calls uses to assemble its tuple, and it is only meaningful once the promise has fulfilled, which is the only moment AllTuple calls that closure.

func (*Promise[T]) Then

func (p *Promise[T]) Then(onFulfilled func(T)) *Promise[Unit]

Then schedules onFulfilled to run with the fulfilled value at the next microtask checkpoint. The callback is always deferred, never inlined, so synchronous code after the then runs first. It returns the promise then produces in JavaScript: a fresh promise that fulfills with unit only once the callback has run, so a chained then runs one turn later than this one, the ordering a following then observes. A rejection of the receiver passes straight through to the returned promise, since a then with no rejection handler forwards the rejection down the chain, and a callback that throws (a Go panic carrying a Thrown) rejects the returned promise. The callback covered here returns nothing, so the returned promise carries only unit.

type RegExp

type RegExp struct {
	// contains filtered or unexported fields
}

RegExp is bento's runtime representation of a JavaScript RegExp (22 §22.2). A regexp pairs a pattern with a flag set and matches it against a string; bento hosts the match on Go's regexp package (RE2) rather than a from-scratch backtracking engine, so a pattern lowers only when its ECMAScript semantics coincide with what RE2 computes. The lowerer proves that coincidence at compile time through TranslateRegExp, the same function this constructor runs, so a literal or a constant-pattern constructor that reached here is known to compile; a pattern RE2 cannot host faithfully never becomes a RegExp, it hands back at lowering instead.

The object carries the original source and the flag set for the source and flags accessors, the compiled RE2 program for exec and test, and the lastIndex the global and sticky flags advance across successive matches. Source and flags are the ECMAScript text the program wrote, not the translated RE2 text, since that is what .source and .flags must report.

func NewRegExpLiteral

func NewRegExpLiteral(pattern, flags string) *RegExp

NewRegExpLiteral builds the RegExp a regexp literal or a constant-pattern constructor lowers to. The pattern and flags are the ECMAScript text the program wrote; the lowerer already ran TranslateRegExp over them and lowered only on success, so the translate-and-compile here cannot fail on a well-formed input. It still reports a SyntaxError through Throw on the impossible failure rather than panicking, so a bug in the compile-time gate surfaces as a language error and never a Go crash.

func (*RegExp) DotAll

func (re *RegExp) DotAll() bool

func (*RegExp) Exec

func (re *RegExp) Exec(s BStr) Value

Exec runs RegExp.prototype.exec (22 §22.2.7.2): it matches the pattern against s and returns the match result array on success or null on failure. Under the global or sticky flag it starts from lastIndex and advances lastIndex past the match, and resets lastIndex to zero on a failed match; a plain regexp ignores lastIndex, never writes it, and always searches from the start. The result is a value.Value because exec returns an array or null, the RegExpExecArray | null union the checker gives it.

func (*RegExp) Flags

func (re *RegExp) Flags() BStr

Flags returns the flag string .flags reports: the flags the regexp carries in the canonical order the specification fixes, d g i m s u v y, so two regexps with the same flags always report the same string regardless of how they were written.

func (*RegExp) Global

func (re *RegExp) Global() bool

The single-flag accessors report each flag as a boolean, the reads .global, .ignoreCase, and the rest make. They mirror the flags string Flags builds, one getter per flag, so a program can test one flag without parsing the string.

func (*RegExp) HasIndices

func (re *RegExp) HasIndices() bool

func (*RegExp) IgnoreCase

func (re *RegExp) IgnoreCase() bool

func (*RegExp) LastIndex

func (re *RegExp) LastIndex() float64

LastIndex reports the lastIndex property, the offset a global or sticky match resumes from. It is a Number read back exactly as it was last written or last advanced, so a program that sets it and reads it sees its own value.

func (*RegExp) MatchStr

func (re *RegExp) MatchStr(s BStr) Value

MatchStr runs String.prototype.match (22 §22.1.3.14). A non-global regexp returns exec's result, the match array or null. A global regexp resets lastIndex to zero, walks every match, and returns an array of the matched substrings (element zero of each match), or null when there is no match; an empty match advances one code unit so the walk terminates, the AdvanceStringIndex the specification applies.

func (*RegExp) Multiline

func (re *RegExp) Multiline() bool

func (*RegExp) ReplaceAllCallStr

func (re *RegExp) ReplaceAllCallStr(s BStr, fn Value) BStr

ReplaceAllCallStr runs String.prototype.replaceAll with a replacer function called through the value model, requiring a global regexp and throwing the same TypeError ReplaceAllStr does without one.

func (*RegExp) ReplaceAllFuncStr

func (re *RegExp) ReplaceAllFuncStr(s BStr, fn func(BStr) BStr) BStr

ReplaceAllFuncStr runs String.prototype.replaceAll with a function replacement, requiring a global regexp and throwing a TypeError otherwise the way ReplaceAllStr does; with the global flag present it replaces every match as a global replace does.

func (*RegExp) ReplaceAllStr

func (re *RegExp) ReplaceAllStr(s, repl BStr) BStr

ReplaceAllStr runs String.prototype.replaceAll (22 §22.1.3.20) with a string replacement. replaceAll requires a global regexp and throws a TypeError otherwise, the one check that separates it from replace; with the global flag present it replaces every match exactly as a global replace does.

func (*RegExp) ReplaceCallStr

func (re *RegExp) ReplaceCallStr(s BStr, fn Value) BStr

ReplaceCallStr runs String.prototype.replace with a replacer function called through the value model, the form a dynamic receiver takes: `s.replace(re, (m, p1) => ...)` where neither the string nor the function has a static type. It differs from ReplaceFuncStr only in what the replacer is handed. ReplaceFuncStr serves the lowered path, where the callback's declared signature is one BStr parameter, so it passes the matched text alone; here the callback is a boxed value with no declared arity, so it gets the whole argument list the specification defines: the matched text, then one argument per capture group (undefined for a group that did not participate), then the match's code-unit offset, then the subject.

The match walk is the one ReplaceFuncStr makes. A non-global regexp replaces the first match and leaves lastIndex alone; a global one resets lastIndex, replaces every match, and advances one code unit past an empty match so the walk terminates.

func (*RegExp) ReplaceFuncStr

func (re *RegExp) ReplaceFuncStr(s BStr, fn func(BStr) BStr) BStr

ReplaceFuncStr runs String.prototype.replace with a function replacement (22 §22.1.3.19), calling fn with each match's text and substituting the string fn returns. It covers the single-argument replacer the lowerer admits: fn receives the matched substring, not the capture groups, offset, or subject the full replacer signature also passes. A non-global regexp replaces the first match; a global one resets lastIndex and replaces every match, advancing one code unit past an empty match so the walk terminates, the same iteration ReplaceStr runs.

func (*RegExp) ReplaceStr

func (re *RegExp) ReplaceStr(s, repl BStr) BStr

ReplaceStr runs String.prototype.replace and replaceAll with a string replacement (22 §22.1.3.19). A non-global regexp replaces the first match; a global regexp resets lastIndex and replaces every match, advancing one code unit past an empty match so the walk terminates. The replacement template expands the ECMAScript substitution patterns $$, $&, $`, $', and $n, so a captured group flows into the result the same way the engine substitutes it.

func (*RegExp) Search

func (re *RegExp) Search(s BStr) float64

Search runs RegExp.prototype[Symbol.search] (22 §22.2.7.9): it reports the UTF-16 index of the first match or -1, and neither reads nor writes lastIndex, so a global or sticky regexp searches from the start the same as a plain one. A sticky regexp still matches only at position zero, the search-from-zero the specification fixes, so a later match does not count.

func (*RegExp) SetLastIndex

func (re *RegExp) SetLastIndex(v float64)

SetLastIndex writes the lastIndex property, the re.lastIndex = n assignment. The value is stored as given and only coerced with ToLength when a match reads it, so the property read reports the raw assignment the way the specification's data property does.

func (*RegExp) Source

func (re *RegExp) Source() BStr

Source returns the pattern text .source reports, the ECMAScript source the program wrote (or "(?:)" for the empty pattern), not the RE2 text the match runs on. It is a BStr so it flows into the string world unchanged.

func (*RegExp) SplitStr

func (re *RegExp) SplitStr(s BStr, limited bool, limit float64) Value

SplitStr runs String.prototype.split with a regexp separator (22 §22.2.7.11). It walks the subject, matching the separator anchored at each position the way the specification's sticky splitter clone does, cutting the text between matches into the result and appending each capture group of the separator after each cut. The limit caps the result length, an undefined limit meaning no cap; a zero limit yields the empty array, and the empty subject yields [""] unless the separator matches there. The anchored match reads no severed left context because the lowerer admits split only for a separator with no anchor or word boundary.

func (*RegExp) Sticky

func (re *RegExp) Sticky() bool

func (*RegExp) Test

func (re *RegExp) Test(s BStr) bool

Test runs RegExp.prototype.test (22 §22.2.7.10), reporting whether the pattern matches s. It shares exec's stateful search, so the global and sticky flags advance and reset lastIndex the same way; only the return differs, a boolean rather than the match array, and no result object is built.

func (*RegExp) ToStringBStr

func (re *RegExp) ToStringBStr() BStr

ToStringBStr renders the regexp the way RegExp.prototype.toString does, "/" + source + "/" + flags, so String(re), `${re}`, "" + re, and re.toString() all read the literal form the program wrote. The source is the .source getter's text, already "(?:)" for the empty pattern, and the flags are the canonical run Flags builds, so /a/gi stringifies to "/a/gi" and // to "/(?:)/".

func (*RegExp) Unicode

func (re *RegExp) Unicode() bool

func (*RegExp) UnicodeSets

func (re *RegExp) UnicodeSets() bool

type Set

type Set[T any] struct {
	// contains filtered or unexported fields
}

Set is bento's runtime representation of a JavaScript Set<T>. It holds its members as a single slice in insertion order, the order for...of and forEach observe, and an eq function that decides member identity so number, string, and boolean members each compare the way JavaScript's SameValueZero does for that kind. The type is monomorphized: the compiler proved T, so there is no boxing on the members themselves. It is deliberately the members-only shape of Map, which keeps the two collections' semantics in one mental model.

func NewBoolSet

func NewBoolSet() *Set[bool]

NewBoolSet builds an empty Set with boolean members, the lowering of new Set<boolean>(). There are only two members, so plain == is the whole of SameValueZero here.

func NewDynSet

func NewDynSet() *Set[Value]

NewDynSet builds an empty Set whose members are dynamic values, the lowering of a `new Set()` written with no member type, the ordinary spelling in JavaScript. Members compare by SameValueZero over the boxed value, the one comparison that covers every kind at once, exactly as NewDynMap does for its keys.

func NewNumberSet

func NewNumberSet() *Set[float64]

NewNumberSet builds an empty Set with number members, the lowering of new Set<number>(). Members compare by SameValueZero: NaN is a single member (every NaN matches) and +0 and -0 are the same member, which is exactly what a plain == misses for NaN and gets right for the zeroes, so the equality folds the NaN case in by hand, the same way NewNumberMap does for its keys.

func NewRefSet

func NewRefSet[T comparable]() *Set[T]

NewRefSet builds an empty Set whose members are objects compared by reference identity, the lowering of new Set<T>() for an object member type T. As with NewRefMap, an object member matches under SameValueZero by reference identity, which is Go's == on the struct pointers objects lower to, so two members are the same member exactly when they are the same object. T is constrained to comparable because only a comparable member can back that ==; the lowerer only reaches this constructor for a member type that renders to a pointer.

func NewStringSet

func NewStringSet() *Set[BStr]

NewStringSet builds an empty Set with string members, the lowering of new Set<string>(). Members compare by the string's UTF-16 code units through BStr.Equal, so two strings that print the same are the same member however each was built.

func (*Set[T]) Add

func (s *Set[T]) Add(v T) *Set[T]

Add inserts v if it is not already present and returns the set, the lowering of set.add(v). A new member appends in insertion order; a member already present leaves the set unchanged and keeps its position, matching JavaScript, and the set itself is the result so a chained add lowers with no temporary.

func (*Set[T]) Clear

func (s *Set[T]) Clear()

Clear removes every member, the lowering of set.clear(). The slice is truncated to length zero but keeps its backing storage, so a set that is refilled after a clear does not reallocate from empty.

func (*Set[T]) Delete

func (s *Set[T]) Delete(v T) bool

Delete removes v and reports whether it was present, the lowering of set.delete(v). The remaining members keep their relative order, matching JavaScript, so a later iteration still visits them in insertion order.

func (*Set[T]) Difference

func (s *Set[T]) Difference(other *Set[T]) *Set[T]

Difference returns a new set of the members in this set but not the other, the lowering of set.difference(other) (ES2025). It keeps this set's members that the other lacks, in this set's order.

func (*Set[T]) ForEach

func (s *Set[T]) ForEach(fn func(T))

ForEach visits each member in insertion order, the shape Set.prototype.forEach hands its callback. The specification passes the member twice and then the set (value, value, set); a callback that reads only the first parameter, the common form, takes this one-argument shape. The member is passed by value, so a callback cannot alias the set's storage.

func (*Set[T]) Has

func (s *Set[T]) Has(v T) bool

Has reports whether the set holds v, the lowering of set.has(v).

func (*Set[T]) Intersection

func (s *Set[T]) Intersection(other *Set[T]) *Set[T]

Intersection returns a new set of the members in both sets, the lowering of set.intersection(other) (ES2025). The specification walks the smaller set and keeps the members the larger one also holds, so the result order follows whichever operand is smaller: this set's order when it is the smaller, the other's order otherwise. Both operands are deduped already, so each kept member is appended directly.

func (*Set[T]) IsDisjointFrom

func (s *Set[T]) IsDisjointFrom(other *Set[T]) bool

IsDisjointFrom reports whether the two sets share no member, the lowering of set.isDisjointFrom(other) (ES2025). It scans the smaller set against the larger, the work the specification does, and a single shared member settles it as false.

func (*Set[T]) IsSubsetOf

func (s *Set[T]) IsSubsetOf(other *Set[T]) bool

IsSubsetOf reports whether every member of this set is in the other, the lowering of set.isSubsetOf(other) (ES2025). A set larger than the other cannot be a subset, so the size check settles that case before the membership scan.

func (*Set[T]) IsSupersetOf

func (s *Set[T]) IsSupersetOf(other *Set[T]) bool

IsSupersetOf reports whether every member of the other set is in this one, the lowering of set.isSupersetOf(other) (ES2025). A set smaller than the other cannot be a superset, so the size check settles that case before the scan.

func (*Set[T]) Members

func (s *Set[T]) Members() []T

Members returns the set's members in insertion order, the traversal set.values(), set.keys(), and a for...of over the set read (a Set's keys and values are its members, so all three project to this). It copies the backing slice so a mutation to the set during the loop does not disturb the range in progress; the live-view an iterator has of concurrent mutation is a later slice.

func (*Set[T]) Range

func (s *Set[T]) Range(fn func(T))

Range visits each member in insertion order, the shape a later for...of over a set reads. It passes the member by value, so a callback cannot alias the set's storage.

func (*Set[T]) Size

func (s *Set[T]) Size() float64

Size is the member count as a Number, the lowering of the set.size accessor. It is a float64 to match the type the checker gives the property and to compose with the numeric path with no conversion at the use site.

func (*Set[T]) SymmetricDifference

func (s *Set[T]) SymmetricDifference(other *Set[T]) *Set[T]

SymmetricDifference returns a new set of the members in exactly one of the two sets, the lowering of set.symmetricDifference(other) (ES2025). It lists this set's members the other lacks, in this set's order, then the other's members this set lacks, in the other's order, which is the order the specification builds by seeding with the receiver and toggling each of the argument's members.

func (*Set[T]) ToValue

func (s *Set[T]) ToValue() Value

ToValue boxes a typed set into a dynamic value, building the box once and keeping it on the set so two crossings of one set hand back one object.

func (*Set[T]) Union

func (s *Set[T]) Union(other *Set[T]) *Set[T]

Union returns a new set of the members in this set or the other, the lowering of set.union(other) (ES2025). The result lists this set's members in their order first, then the other set's members not already present, which is the order the specification builds by seeding the result with the receiver and appending the argument's new members.

type SharedArrayBuffer

type SharedArrayBuffer struct {
	// contains filtered or unexported fields
}

SharedArrayBuffer is bento's runtime representation of a JavaScript SharedArrayBuffer, the backing store Atomics operates over and a typed array or a DataView views the same as it views an ArrayBuffer (25 §25.2). In a browser or a worker host a SharedArrayBuffer is the one buffer kind whose bytes are visible to a second agent, which is the whole reason Atomics exists: it coordinates two agents racing on those bytes.

Ceiling: bento's AOT output is a single Go process with one agent, so there is no second agent to share bytes with. A SharedArrayBuffer here is therefore an ordinary shared backing store that behaves exactly as the spec requires within one agent: its bytes alias into every view over it, it cannot be detached, and when growable it only grows. The cross-agent visibility a real second agent would observe, and the wait and notify that block on it, are the multi-agent slice this group states as a handback rather than emits. Every single-agent SharedArrayBuffer program, which is what the built-in tests exercise, runs with full fidelity.

The bytes live in an ArrayBuffer so a view over a SharedArrayBuffer aliases the same run the ArrayBuffer path already aliases, with no second storage model: a typed array or DataView constructed over one takes the underlying buffer and shares its bytes. A SharedArrayBuffer differs from an ArrayBuffer only in the surface it carries, so the distinctions the spec draws (grow rather than resize, growable rather than resizable, no detach or transfer) live in this wrapper's methods rather than in the shared storage.

func NewGrowableSharedArrayBuffer

func NewGrowableSharedArrayBuffer(byteLength float64, maxByteLength float64) *SharedArrayBuffer

NewGrowableSharedArrayBuffer builds a growable shared buffer of the given byte length that may later grow to maxByteLength, the lowering of new SharedArrayBuffer(n, { maxByteLength }). Both arguments are Numbers truncated toward zero like ToIndex. A max below the initial length is a RangeError, the throw the spec raises. The backing run is sized to the initial length and grow reallocates it, so an unused max costs no storage.

func NewSharedArrayBuffer

func NewSharedArrayBuffer(byteLength float64) *SharedArrayBuffer

NewSharedArrayBuffer builds a zeroed fixed-length shared buffer of the given byte length, the lowering of new SharedArrayBuffer(n). The length is a Number truncated toward zero like ToIndex, and a negative or not-a-number length clamps to zero, the same covered subset the ArrayBuffer constructor takes.

func (*SharedArrayBuffer) Buffer

func (s *SharedArrayBuffer) Buffer() *ArrayBuffer

Buffer is the ArrayBuffer holding the shared bytes, the storage every view over the SharedArrayBuffer aliases. The view path takes an *ArrayBuffer, so a typed array or DataView over a SharedArrayBuffer binds this buffer and observes writes made through any other view of the same shared bytes.

func (*SharedArrayBuffer) ByteLength

func (s *SharedArrayBuffer) ByteLength() float64

ByteLength is the shared buffer's size in bytes, the .byteLength accessor, a Number to match the type the checker gives the property.

func (*SharedArrayBuffer) Grow

func (s *SharedArrayBuffer) Grow(newLength float64)

Grow enlarges the shared buffer to newLength, the lowering of SharedArrayBuffer.prototype.grow (25 §25.2.4.4). A grow on a non-growable buffer, a length past the maximum, or a length below the current byte length is a RangeError, the throws the spec raises: unlike an ArrayBuffer resize, a shared buffer only grows, so a shorter length is rejected rather than shrinking the run. The retained bytes are kept and the growth zeroed, so every view over the buffer sees the new size on its next access.

func (*SharedArrayBuffer) Growable

func (s *SharedArrayBuffer) Growable() bool

Growable reports whether the shared buffer may grow, the .growable accessor, true only for a buffer built with a maxByteLength. It is the SharedArrayBuffer spelling of the resizable flag an ArrayBuffer carries.

func (*SharedArrayBuffer) MaxByteLength

func (s *SharedArrayBuffer) MaxByteLength() float64

MaxByteLength is the largest byte length the shared buffer may hold, the .maxByteLength accessor. A growable buffer reports the maximum it was built with; a fixed-length one reports its current length, matching the spec's getter.

func (*SharedArrayBuffer) Slice

func (s *SharedArrayBuffer) Slice(bounds ...float64) *SharedArrayBuffer

Slice copies the bytes in [start, end) into a fresh fixed-length shared buffer, the lowering of SharedArrayBuffer.prototype.slice (25 §25.2.4.3). start and end are optional Numbers; a negative index counts from the end and an omitted end runs to the current byte length, the same relative-index rule Array.prototype.slice takes. The result is a new SharedArrayBuffer that owns its bytes and does not alias the receiver, so a later write through either shows only in that one.

func (*SharedArrayBuffer) ToValue

func (s *SharedArrayBuffer) ToValue() Value

ToValue is the SharedArrayBuffer half of the same crossing.

type StrBuilder

type StrBuilder struct {
	// contains filtered or unexported fields
}

StrBuilder is a reusable builder for a string the compiler assembles from a template literal or a chain of + whose parts include a coerced number or boolean. The lowerer hoists one builder per such site above the loop that runs it and reuses it every iteration, so the scratch buffer is allocated once and grows to its steady-state size, and each build costs only the one allocation of its result. That is the win over the straightforward lowering, which coerces each interpolated number to its own String(x) BStr before joining: those intermediate strings are gone because a number or boolean part formats straight into the builder's buffer.

The result is an independent copy, so the builder is safe wherever the value goes: it can be stored, returned, or compared, and the builder is free to reuse its buffer on the next iteration with no aliasing to reason about. Each template site gets its own builder, so a template nested inside another never resets the buffer the outer build is still filling.

The common build stays on a UTF-8 byte buffer, the fast path that keeps a whole template a plain byte append and lets a later .charCodeAt read a byte directly. A build only leaves that path when a part carries a lone surrogate the UTF-8 view cannot hold, at which point the builder transcodes what it has to code units and finishes on the UTF-16 view, so the result is correct for every string while paying the wider representation only when the input needs it.

func (*StrBuilder) Bool

func (a *StrBuilder) Bool(b bool) *StrBuilder

Bool appends "true" or "false", String(b) of a boolean.

func (*StrBuilder) Done

func (a *StrBuilder) Done() BStr

Done returns the built string as an independent BStr, copied out of the builder's buffer so the builder can safely reuse that buffer on the next build. A build that never went wide returns the UTF-8 view, so a later .charCodeAt on an all-ASCII result reads a byte with no code-unit materialization; a wide build returns the code-unit view through FromUTF16, which makes the owning copy.

func (*StrBuilder) Lit

func (a *StrBuilder) Lit(s string, units int) *StrBuilder

Lit appends a compile-time literal part, the head or a between-part of a template or a string-literal operand, with its precomputed UTF-16 length. A literal part that carries a lone surrogate is passed through Units instead, so the byte append here is always valid UTF-8; if an earlier runtime part already went wide the bytes are widened to code units.

func (*StrBuilder) Num

func (a *StrBuilder) Num(x float64) *StrBuilder

Num appends String(x) of a number, formatted through the same Number::toString the value model uses into a stack scratch. The decimal is ASCII, so it is a straight byte append (or a widen once wide).

func (*StrBuilder) Reset

func (a *StrBuilder) Reset() *StrBuilder

Reset clears the builder for a fresh build and returns it so the caller can chain the appends and the terminal Done in one expression. It keeps both buffers' capacity, which is the point: after the first few iterations neither append reallocates and the build allocates nothing but its result.

func (*StrBuilder) Str

func (a *StrBuilder) Str(s BStr) *StrBuilder

Str appends a runtime string's code units. A string on the UTF-8 fast path is appended as bytes, or transcoded rune by rune when the build has already gone wide; a string that holds a lone surrogate forces the wide switch and copies its code units verbatim so the surrogate survives.

func (*StrBuilder) Units

func (a *StrBuilder) Units(u []uint16) *StrBuilder

Units appends a compile-time literal part that carries a lone surrogate, the rare template or string part the UTF-8 view cannot hold. It forces the wide switch so the surrogate survives and copies the units verbatim. The lowerer routes a literal here only when it holds an unpaired surrogate; every other literal takes the cheaper byte path through Lit.

type Symbol

type Symbol struct {
	// contains filtered or unexported fields
}

Symbol is the storage behind a KindSymbol value. It carries only the description a Symbol(desc) call recorded, used by toString and the description getter; identity lives in the pointer itself, so the box's ref distinguishes one symbol from another and StrictEquals compares symbols by that pointer the way the language compares them by reference. The hasDesc flag keeps Symbol() apart from Symbol(""): the former's description is undefined while the latter's is the empty string, a difference the empty BStr alone cannot record.

type TextDecoder

type TextDecoder struct {
	// contains filtered or unexported fields
}

TextDecoder is the bytes-to-string half of the codec, the lowering of new TextDecoder(label). It carries the encoding it was built with and the two flags the constructor's options set, each readable back through its getter.

func NewTextDecoder

func NewTextDecoder(label ...BStr) *TextDecoder

NewTextDecoder builds a TextDecoder for a label, the lowering of new TextDecoder() and new TextDecoder(label). An absent label is utf-8, the default the specification gives. The label is matched case-insensitively against the aliases the registry lists for each encoding, and a label naming an encoding this runtime does not host throws a RangeError, the specification's answer for an unsupported label. Silently decoding as utf-8 instead would hand the program bytes read as the wrong text, which is the kind of quiet wrong answer a compiler must not give.

func NewTextDecoderWithOptions

func NewTextDecoderWithOptions(label BStr, fatal, ignoreBOM bool) *TextDecoder

NewTextDecoderWithOptions builds a TextDecoder for a label and the fatal and ignoreBOM flags an options dictionary carries, the lowering of new TextDecoder(label, { fatal, ignoreBOM }). The flags arrive already coerced to booleans, since the caller read them off the dictionary at the call site.

func (*TextDecoder) Decode

func (d *TextDecoder) Decode(a *Uint8Array) BStr

Decode transcodes bytes to a string, the lowering of decoder.decode(input). A leading byte order mark is stripped unless ignoreBOM was set, and a malformed sequence becomes the U+FFFD replacement, or throws a TypeError when the decoder is fatal. Decoding an absent input gives the empty string, the answer decode() with no argument has.

func (*TextDecoder) Encoding

func (d *TextDecoder) Encoding() BStr

Encoding is the label the decoder was built with, the lowering of the encoding getter. It is the canonical name, not the alias the constructor was given, matching what the specification reports.

func (*TextDecoder) Fatal

func (d *TextDecoder) Fatal() bool

Fatal reports whether a malformed sequence throws rather than becoming U+FFFD, the lowering of the fatal getter.

func (*TextDecoder) IgnoreBOM

func (d *TextDecoder) IgnoreBOM() bool

IgnoreBOM reports whether a leading byte order mark is kept as a character rather than stripped, the lowering of the ignoreBOM getter.

type TextEncoder

type TextEncoder struct{}

TextEncoder is the string-to-UTF-8 half of the codec, the lowering of new TextEncoder(). It carries no state: the specification fixes its encoding at utf-8, so every encoder is the same encoder and the type is an empty struct held by pointer for the reference identity a JavaScript object has.

func NewTextEncoder

func NewTextEncoder() *TextEncoder

NewTextEncoder builds a TextEncoder. It takes no argument, matching the one constructor the specification gives: an encoder is always utf-8.

func (*TextEncoder) Encode

func (e *TextEncoder) Encode(s BStr) *Uint8Array

Encode transcodes a string to its UTF-8 bytes, the lowering of encoder.encode(input). A string that holds a lone surrogate has no UTF-8 spelling, so each unpaired surrogate becomes the U+FFFD replacement, which is what ToGoString already does and what the specification requires of the encoder.

func (*TextEncoder) Encoding

func (e *TextEncoder) Encoding() BStr

Encoding is the encoder's fixed label, the lowering of the encoding getter. It is always "utf-8".

type Thrown

type Thrown interface {
	ErrorName() string
	ErrorMessage() string
}

Thrown marks a Go panic payload that carries a thrown JavaScript value. A deliberate throw (an Error the program raised, a boundary range check, a failed go: call) implements it; a Go runtime panic (a nil dereference, an out-of-range index in the runtime) does not, so the top-level handler reports the first and re-panics the second. The two methods are the surface a catch and the reporter read: the error's constructor name and its message.

func NewRejection

func NewRejection(reason Value) Thrown

NewRejection wraps an arbitrary value into the Thrown a rejected promise carries, so Promise.reject and a manual Rejected can settle with any JavaScript value, not only a runtime Error. A catch handler or a rejected await reads the value back through the Thrown's ToValue.

type ThrownString

type ThrownString BStr

ThrownString is a thrown primitive string, the `throw "reason"` JavaScript allows beside thrown errors. It carries the Thrown surface with the string as the name and no message, so the uncaught reporter prints the string the way node reports a thrown primitive. A catch that recovers one binds an *Error that stashes the string, so a dynamic read of the binding boxes back to the string primitive: `e === "reason"` and typeof e === "string" hold the way a JavaScript catch binds the primitive itself.

func (ThrownString) ErrorMessage

func (t ThrownString) ErrorMessage() string

ErrorMessage reports an empty message; a thrown primitive has none.

func (ThrownString) ErrorName

func (t ThrownString) ErrorName() string

ErrorName reports the thrown string itself, the text the reporter prints.

type ThrownValue

type ThrownValue struct {
	// contains filtered or unexported fields
}

ThrownValue is a thrown JavaScript value that is neither a built-in error nor a primitive string: a number, a boolean, null, undefined, or an object the program raised with `throw <expr>`. JavaScript allows any value to be thrown, so the runtime models the general case with one carrier that boxes the raised value and carries the Thrown surface with the value's String coercion as the name and no message, so the uncaught reporter prints it the way the engine spells a thrown value: `throw 7` reports "Uncaught 7" and `throw {}` reports "Uncaught [object Object]". A catch that recovers one binds the value itself, so a dynamic read of the binding sees the original value: throwing 42 and catching it holds `e === 42` and `typeof e === "number"` the way a JavaScript catch binds the value.

func NewThrownValue

func NewThrownValue(v Value) ThrownValue

NewThrownValue wraps a raised value in the Thrown carrier, the payload a `throw <expr>` over a non-error, non-string value lowers to.

func (ThrownValue) ErrorMessage

func (t ThrownValue) ErrorMessage() string

ErrorMessage reports an empty message; a thrown value carries none.

func (ThrownValue) ErrorName

func (t ThrownValue) ErrorName() string

ErrorName reports the value's String coercion, the text the reporter prints after "Uncaught ": a number spells its digits, an object its "[object Object]" tag, null and undefined their literal words.

func (ThrownValue) Value

func (t ThrownValue) Value() Value

Value reports the wrapped value, the primitive or object a catch binds so the binding reads back as the value the program threw.

type TypedArray

type TypedArray[T typedElem] struct {
	// contains filtered or unexported fields
}

TypedArray is bento's runtime representation of a JavaScript numeric typed array whose element width the compiler proved: Int8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, and Float64Array (16 §6.3). It wraps a Go slice of the element's fixed-width type, the same storage the platform gives that array kind, so a read is a slice index and a write is a slice store, with none of the per-element boxing a JavaScript engine keeps. It is spelled *TypedArray[T] in generated code the same way a dense array is spelled *Array[T], so the two read alike at the use site.

Uint8Array is the one family member kept separate (bytes.go): it stores a Go []byte so it can hand its backing slice to a Go function taking []byte across the go: boundary with no copy (16 §7.3). The bigint-element arrays (BigInt64Array, BigUint64Array) store a *big.Int element and are a later slice.

The store coercion is the one per-element behavior that differs across the family: a write into an Int8Array wraps modulo 256 into signed range, a write into a Uint8ClampedArray clamps to 0 to 255, a write into a Float32Array rounds to single precision, and so on. The header carries that coercion as a function so the generic core stays one type; a read always widens the stored element back to a Number, which every member does the same way.

A typed array is a view, not the storage: it records the ArrayBuffer it reads, the byte offset it starts at, and its element length (section 6.2 and §6.3). It does not cache an element slice; live forms one with unsafe.Slice over the buffer's current bytes on each access, so an element read and write go straight through it with no per-element packing, and two views over one buffer, even of different element widths, observe each other's writes because they alias the same run of bytes. The buffer allocates eight-byte aligned and the byte offset the spec requires to be a multiple of the element width keeps every element on a naturally aligned address, and the platform's little-endian layout is the byte order the buffer exposes.

The length is consulted against the buffer's live state rather than frozen at construction, because the buffer can go away or change size while the view points at it: a detached buffer turns every view over it into a zero-length view whose indexed access is a no-op, and a shrink that puts the view's range out of bounds does the same (25 §10.4.5). liveLen is the one place that clamp lives, so every element-access method below reaches storage through it and reacts to a detach with no per-method check.

func Float32ArrayOf

func Float32ArrayOf(elems ...float64) *TypedArray[float32]

func Float32ArrayView

func Float32ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *TypedArray[float32]

func Float64ArrayOf

func Float64ArrayOf(elems ...float64) *TypedArray[float64]

func Float64ArrayView

func Float64ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *TypedArray[float64]

func Int8ArrayOf

func Int8ArrayOf(elems ...float64) *TypedArray[int8]

func Int8ArrayView

func Int8ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *TypedArray[int8]

func Int16ArrayOf

func Int16ArrayOf(elems ...float64) *TypedArray[int16]

func Int16ArrayView

func Int16ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *TypedArray[int16]

func Int32ArrayOf

func Int32ArrayOf(elems ...float64) *TypedArray[int32]

func Int32ArrayView

func Int32ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *TypedArray[int32]

func NewFloat32Array

func NewFloat32Array(length float64) *TypedArray[float32]

func NewFloat64Array

func NewFloat64Array(length float64) *TypedArray[float64]

func NewInt8Array

func NewInt8Array(length float64) *TypedArray[int8]

func NewInt16Array

func NewInt16Array(length float64) *TypedArray[int16]

func NewInt32Array

func NewInt32Array(length float64) *TypedArray[int32]

func NewUint8ClampedArray

func NewUint8ClampedArray(length float64) *TypedArray[uint8]

func NewUint16Array

func NewUint16Array(length float64) *TypedArray[uint16]

func NewUint32Array

func NewUint32Array(length float64) *TypedArray[uint32]

func Uint8ClampedArrayOf

func Uint8ClampedArrayOf(elems ...float64) *TypedArray[uint8]

func Uint8ClampedArrayView

func Uint8ClampedArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *TypedArray[uint8]

func Uint16ArrayOf

func Uint16ArrayOf(elems ...float64) *TypedArray[uint16]

func Uint16ArrayView

func Uint16ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *TypedArray[uint16]

func Uint32ArrayOf

func Uint32ArrayOf(elems ...float64) *TypedArray[uint32]

func Uint32ArrayView

func Uint32ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *TypedArray[uint32]

func (*TypedArray[T]) At

func (a *TypedArray[T]) At(i float64) float64

At reads the element a JavaScript index expression a[i] selects, widened to the Number a typed-array read hands out. Only a canonical integer index inside the array names an element; an out-of-range or non-canonical index (a fractional value, a negative, or NaN) reads as 0 here rather than the undefined the spec gives, the covered subset for the numeric read path, since At's result type is a Number. A read that flows into a dynamic slot takes GetIndex instead, which does answer undefined for those indices.

func (*TypedArray[T]) AtI

func (a *TypedArray[T]) AtI(i int) float64

AtI reads the element at a Go int index, the integer-index form of At the lowerer emits when the checker proved the index expression is an integer. The float truncation At runs on its Number index is then dead work, so this form takes the index already narrowed. The bounds check and the out-of-range 0 are the same as At, so the two reads agree on every index; only the index type differs, which is what keeps a proven-integer index a native slice index rather than a float that round trips through the canonical-index check on every access.

func (*TypedArray[T]) AtOpt

func (a *TypedArray[T]) AtOpt(i float64) Opt[float64]

AtOpt reads the element TypedArray.prototype.at selects, the relative-index read that counts from the end when the index is negative, the lowering of TypedArray.prototype.at. Its declared type is Number | undefined, so it returns an Opt[float64], a present optional in range and the undefined optional outside it. The index truncates toward zero with NaN becoming zero, and a negative index adds the length once, so at(-1) is the last element; an index still out of range after that yields undefined.

func (*TypedArray[T]) Buffer

func (a *TypedArray[T]) Buffer() *ArrayBuffer

Buffer is the ArrayBuffer the view aliases, the .buffer getter. It hands back the same backing store every other view of the buffer holds, so a comparison of two views' buffers by identity holds and a read of view.buffer.byteLength answers the whole buffer's span, not the view's.

func (*TypedArray[T]) ByteLength

func (a *TypedArray[T]) ByteLength() float64

ByteLength is the view's span in bytes, the .byteLength getter: the element count times the element width, which is the run of buffer bytes the view aliases. It is a Number, and it differs from Len, the element count, by the element width.

func (*TypedArray[T]) ByteOffset

func (a *TypedArray[T]) ByteOffset() float64

ByteOffset is the byte the view starts at within its buffer, the .byteOffset getter, a Number to match the type the checker gives the property.

func (*TypedArray[T]) BytesPerElement

func (a *TypedArray[T]) BytesPerElement() float64

BytesPerElement is the element width in bytes, the instance BYTES_PER_ELEMENT property, a constant of the element kind. It is a method rather than a folded literal at the use site so a read keeps the receiver referenced, and it reads the width from the Go element type so it agrees with the buffer arithmetic.

func (*TypedArray[T]) CopyWithin

func (a *TypedArray[T]) CopyWithin(bounds ...float64) *TypedArray[T]

CopyWithin copies a block of the view to another position within the same view in place and returns the receiver, the lowering of TypedArray.prototype.copyWithin. The target and the optional start and end bounds go through relativeIndex, and the count is capped so the copy neither runs past the source range nor writes past the end of the view, matching copyWithin, which never changes the length. The copy uses Go's builtin copy, whose memmove semantics reproduce copyWithin's overlap behavior of reading the source range as if to a temporary before writing, so an overlapping copy is correct. The elements are already stored, so no coercion runs, unlike fill.

func (*TypedArray[T]) Data

func (a *TypedArray[T]) Data() []T

Data returns the backing slice, the storage a read and a write share. The lowerer indexes it directly, bData[i], at an access it proved stays inside the array, so the read skips the At bounds branch and the Number round trip and an integer store skips the coerce function pointer: a proven-integer value goes straight into the element through a Go conversion that wraps to the element width exactly as the store coercion does. The slice header aliases the array's own storage, so a write through the returned slice shows through the array and through any other reference to it, the same as a write through SetAt. A typed array's length never grows, so a loop that reads Data once and indexes it holds a valid header for the length of that loop; the caller only takes this path when it proved the index in range, so the Go slice bounds check it still carries never trips. The header is formed from the buffer's live bytes at the call, so a detach before the call yields an empty slice and the proven-in-range loop runs zero iterations rather than reading freed storage.

func (*TypedArray[T]) Every

func (a *TypedArray[T]) Every(f func(float64) bool) bool

Every reports whether all elements satisfy the predicate, the lowering of TypedArray.prototype.every. It short-circuits on the first rejected element, and an empty view is true, the vacuous case JavaScript also returns true for.

func (*TypedArray[T]) Fill

func (a *TypedArray[T]) Fill(v float64, bounds ...float64) *TypedArray[T]

Fill overwrites a range of the view with a single coerced value in place and returns the receiver, the lowering of TypedArray.prototype.fill. The value is run through the element kind's store coercion exactly as an indexed write would be, so a value outside the element's range wraps or clamps. The optional start and end bounds go through relativeIndex, so fill(v) fills the whole view, fill(v, start) runs to the end, and fill(v, start, end) is the half-open range.

func (*TypedArray[T]) Filter

func (a *TypedArray[T]) Filter(f func(float64) bool) *TypedArray[T]

Filter returns a fresh typed array of the elements for which the callback returns true, in order, the lowering of TypedArray.prototype.filter. The kept elements are gathered as widened Numbers and rebuilt into a new array through the element's store coercion, so the result owns its storage and the receiver is unchanged.

func (*TypedArray[T]) Find

func (a *TypedArray[T]) Find(f func(float64) bool) Opt[float64]

Find returns the first element the callback accepts, the lowering of TypedArray.prototype.find. Its declared type is Number | undefined, so it returns an Opt[float64], present with the matching element or the undefined optional when none passes. It short-circuits on the first match.

func (*TypedArray[T]) FindIndex

func (a *TypedArray[T]) FindIndex(f func(float64) bool) float64

FindIndex returns the index of the first element the callback accepts, or -1 when none does, the lowering of TypedArray.prototype.findIndex. The result is a Number, so -1 is the not-found sentinel and no optional is needed.

func (*TypedArray[T]) FindLast

func (a *TypedArray[T]) FindLast(f func(float64) bool) Opt[float64]

FindLast returns the last element the callback accepts, the lowering of TypedArray.prototype.findLast. Like find it returns an Opt[float64], and it walks from the end, short-circuiting on the first match in descending index order.

func (*TypedArray[T]) FindLastIndex

func (a *TypedArray[T]) FindLastIndex(f func(float64) bool) float64

FindLastIndex returns the index of the last element the callback accepts, or -1 when none does, the lowering of TypedArray.prototype.findLastIndex. Like findIndex the result is a Number with -1 as the not-found sentinel, and it walks from the end in descending index order.

func (*TypedArray[T]) Floats

func (a *TypedArray[T]) Floats() []float64

Floats widens every element to the Number a typed-array read hands out, the source a fresh typed array copies when it is constructed from another typed array. It allocates a new slice, so the copy the constructor makes reads the source once and does not alias it: the two arrays own separate storage after the copy, which is what the from-a-typed-array constructor requires.

func (*TypedArray[T]) ForEach

func (a *TypedArray[T]) ForEach(f func(float64))

ForEach runs the callback for each element in order for its side effect, the lowering of TypedArray.prototype.forEach. It returns nothing, matching the method's undefined result, and cannot be stopped early, matching JavaScript.

func (*TypedArray[T]) GetIndex

func (a *TypedArray[T]) GetIndex(i float64) Value

GetIndex reads the element a JavaScript index selects as a boxed Value, the form a typed-array read takes when it flows into a dynamic slot. It answers the element as a Number for a canonical in-range index and the undefined singleton for an out-of-range or non-canonical one, so ta[100] and ta[1.5] read as undefined the way the spec requires, which the numeric At cannot express because its result is a Number.

func (*TypedArray[T]) Includes

func (a *TypedArray[T]) Includes(target float64) bool

Includes reports whether any element equals target under SameValueZero, the lowering of TypedArray.prototype.includes. It differs from indexOf only in that SameValueZero treats NaN as equal to NaN, so a Float32Array or Float64Array holding a NaN reports true for a NaN target where indexOf would not. The +0 and -0 pair is equal under both, which Go == already gives.

func (*TypedArray[T]) IndexOf

func (a *TypedArray[T]) IndexOf(target float64) float64

IndexOf returns the index of the first element strictly equal to target, or -1 if none is, the lowering of TypedArray.prototype.indexOf. Every element is widened to a Number and compared with Go ==, which is the strict equality indexOf uses, so a NaN target is never found and a +0 target matches a stored -0. The result is a Number, so it is a float64. The optional fromIndex argument is a later slice; this is the whole-view scan.

func (*TypedArray[T]) Join

func (a *TypedArray[T]) Join(sep BStr) BStr

Join concatenates the elements into a string separated by sep, the lowering of TypedArray.prototype.join. Each element becomes a string through NumberToString, the ToString a Number takes, so unlike the Array Join no per-element stringify closure is threaded in: a typed array's element is always a Number. An empty view joins to the empty string, and a single element to itself with no separator, matching JavaScript. The UTF-8 fast path stays on bytes through a strings.Builder while the separator is valid UTF-8, which every NumberToString piece always is; a separator that carries a raw code-unit backing falls to the code-unit builder so a lone surrogate in it survives.

func (*TypedArray[T]) LastIndexOf

func (a *TypedArray[T]) LastIndexOf(target float64) float64

LastIndexOf returns the index of the last element strictly equal to target, or -1 if none is, the lowering of TypedArray.prototype.lastIndexOf. It is IndexOf scanning from the end, and like indexOf it uses strict equality, so a NaN target is never found. The result is a Number. The optional fromIndex argument is a later slice; this is the whole-view scan.

func (*TypedArray[T]) Len

func (a *TypedArray[T]) Len() float64

Len is the array's length in elements, a Number to match the type the checker gives the .length property and to compose with the numeric path with no conversion at the use site.

func (*TypedArray[T]) Map

func (a *TypedArray[T]) Map(f func(float64) float64) *TypedArray[T]

Map returns a fresh typed array of the same element kind holding the callback's result for each element, the lowering of TypedArray.prototype.map. A typed array's map always yields the same element type, so unlike the Array map there is no type-changing free-function form: the callback returns a Number, which the new array stores through its element's store coercion exactly as an indexed write would. The receiver is unchanged.

func (*TypedArray[T]) ReduceNoInit

func (a *TypedArray[T]) ReduceNoInit(f func(float64, float64) float64) float64

ReduceNoInit folds the view left to right with no initial value, the lowering of TypedArray.prototype.reduce called with only a callback. With no init the accumulator seeds from the first element, so the accumulator is a Number and the callback is func(float64, float64) float64, which is why this is a method rather than the free function the initial-value form needs for a differing accumulator type. An empty view has no seed, so it throws a TypeError the way JavaScript does.

func (*TypedArray[T]) ReduceRightNoInit

func (a *TypedArray[T]) ReduceRightNoInit(f func(float64, float64) float64) float64

ReduceRightNoInit folds the view right to left with no initial value, the lowering of TypedArray.prototype.reduceRight called with only a callback. The accumulator seeds from the last element and the fold runs toward the first. An empty view throws a TypeError.

func (*TypedArray[T]) Reverse

func (a *TypedArray[T]) Reverse() *TypedArray[T]

Reverse reverses the view in place and returns the receiver, the lowering of TypedArray.prototype.reverse. It swaps from both ends toward the middle, so the new order is visible through every view of the same buffer, and the returned value is the same array rather than a copy.

func (*TypedArray[T]) Set

func (a *TypedArray[T]) Set(src []float64, offset float64)

Set copies the elements of a source list into the view starting at offset, coercing each with the element kind's store rule, the lowering of TypedArray.prototype.set. The source arrives as a []float64 snapshot: the lowerer reads a typed-array source through Floats and an array source through its elements, so by the time control reaches here the source is a plain slice that aliases neither the receiver's buffer nor the caller's array. Reading the whole source before the first write is what makes an overlapping set from another view of the same buffer correct, since the source values are captured before any of them is overwritten. A negative offset or a source that would run past the end of the view throws a RangeError, matching set, which validates the bounds before it writes any element.

func (*TypedArray[T]) SetAt

func (a *TypedArray[T]) SetAt(i float64, v float64)

SetAt writes the element a JavaScript assignment a[i] = v stores, coercing the value with the element kind's store rule so a number outside the element's range wraps or clamps exactly as JavaScript does. Only a canonical integer index inside the array names an element; a write to an out-of-range or non-canonical index is dropped, the no-op the spec requires rather than growing the array or writing a truncated neighbor.

func (*TypedArray[T]) SetAtI

func (a *TypedArray[T]) SetAtI(i int, v float64)

SetAtI writes v at a Go int index, the integer-index form of SetAt. It coerces the value with the element kind's store rule and drops an out-of-range write exactly as SetAt does, so the only difference is that the index arrives already narrowed to an int rather than truncated from a Number here.

func (*TypedArray[T]) Slice

func (a *TypedArray[T]) Slice(bounds ...float64) *TypedArray[T]

Slice returns a fresh typed array holding a copy of a range of the view, the lowering of TypedArray.prototype.slice. Unlike subarray, which makes a new view over the same buffer, slice allocates a new buffer and copies the elements into it, so the result owns its storage and a later write to either array does not show through the other. The bounds go through relativeIndex, so slice() copies the whole view, slice(start) runs to the end, and a crossed pair yields an empty array. The copy is a plain slice copy, since both arrays hold the same element type.

func (*TypedArray[T]) Some

func (a *TypedArray[T]) Some(f func(float64) bool) bool

Some reports whether at least one element satisfies the predicate, the lowering of TypedArray.prototype.some. It short-circuits on the first accepted element, and an empty view is false.

func (*TypedArray[T]) Sort

func (a *TypedArray[T]) Sort() *TypedArray[T]

Sort orders the view in place by ascending numeric value and returns the receiver, the lowering of TypedArray.prototype.sort called with no comparator. The order is the numeric default typed arrays use rather than the string order the Array default uses, so it needs no element-to-string step. The sort is stable, so equal elements keep their relative order, and the new order shows through every view of the same buffer.

func (*TypedArray[T]) SortFunc

func (a *TypedArray[T]) SortFunc(cmp func(float64, float64) float64) *TypedArray[T]

SortFunc orders the view in place by the comparator and returns the receiver, the lowering of TypedArray.prototype.sort called with a compare function. The comparator takes the two elements widened to Numbers and returns a Number that is negative to place its first argument first, matching the Array sort comparator. A comparator that returns NaN, which JavaScript treats as zero, reads as not-before here, so those elements keep their order. The sort is stable and the new order shows through every view of the same buffer.

func (*TypedArray[T]) Subarray

func (a *TypedArray[T]) Subarray(bounds ...float64) *TypedArray[T]

Subarray returns a new typed array that views the same buffer over a range of the receiver, the lowering of TypedArray.prototype.subarray. It shares the bytes: a write through the subarray shows through the receiver and every other view of the buffer, which is the difference from slice, whose result owns a fresh copy. The byte offset of the new view is the receiver's offset advanced by the start element, so the two views alias the same run of bytes. The bounds go through relativeIndex, so subarray() views the whole range, subarray(start) runs to the end, and a crossed pair yields an empty view.

func (*TypedArray[T]) ToReversed

func (a *TypedArray[T]) ToReversed() *TypedArray[T]

ToReversed returns a fresh typed array with the elements in reverse order, the lowering of TypedArray.prototype.toReversed. It is the copying sibling of reverse: the receiver keeps its order and the result owns its storage, so a.toReversed() is a different array over a different buffer.

func (*TypedArray[T]) ToSorted

func (a *TypedArray[T]) ToSorted() *TypedArray[T]

ToSorted returns a fresh typed array sorted by ascending numeric value, the lowering of TypedArray.prototype.toSorted called with no comparator. It is the copying sibling of Sort: it orders a snapshot of the elements and leaves the receiver in its original order, and the result owns its storage.

func (*TypedArray[T]) ToSortedFunc

func (a *TypedArray[T]) ToSortedFunc(cmp func(float64, float64) float64) *TypedArray[T]

ToSortedFunc returns a fresh typed array sorted by the comparator, the lowering of TypedArray.prototype.toSorted called with a compare function. It is the copying sibling of SortFunc: the comparator has the same meaning, the sort is stable, and the receiver keeps its original order while the result owns its storage.

func (*TypedArray[T]) ToValue

func (a *TypedArray[T]) ToValue() Value

ToValue boxes a numeric typed array into a dynamic value. The box is built once and kept on the array, so every crossing hands back the same object: a typed array is a view over a buffer, and two boxes of one view would compare unequal under === while writing into the same bytes.

func (*TypedArray[T]) With

func (a *TypedArray[T]) With(index float64, v float64) *TypedArray[T]

With returns a fresh typed array equal to the receiver with one element replaced, the lowering of TypedArray.prototype.with. The index counts from the end when negative and truncates toward zero, and an index outside the view throws a RangeError the way JavaScript does. The replacement value is coerced into the element kind through the same store rule an indexed write uses, and the receiver is unchanged since the result is built over a fresh snapshot.

type URL

type URL struct {
	// contains filtered or unexported fields
}

URL is a parsed absolute URL, the lowering of new URL(input, base). It holds the components the specification exposes as getters, plus the searchParams view built with it. The view holds a back-pointer here, so a mutation through it re-serializes search and href: a program that appends a parameter and then reads url.href sees the parameter, which is the whole point of the live view.

func NewURL

func NewURL(input BStr, base ...BStr) *URL

NewURL parses input, optionally against a base, the lowering of new URL(input) and new URL(input, base). An input that is not a valid absolute URL throws a TypeError, which is what the specification requires: an invalid URL is a hard error, not a null result. Only the first base is read; the variadic is how the optional second argument reaches a Go signature.

func (*URL) Hash

func (u *URL) Hash() BStr

Hash is the fragment with its leading "#", empty when there is none, the lowering of url.hash.

func (*URL) Host

func (u *URL) Host() BStr

Host is the hostname with the port when one is given, the lowering of url.host.

func (*URL) Hostname

func (u *URL) Hostname() BStr

Hostname is the host without the port, the lowering of url.hostname.

func (*URL) Href

func (u *URL) Href() BStr

Href is the serialized URL, the lowering of url.href.

func (*URL) Origin

func (u *URL) Origin() BStr

Origin is the scheme, host and port triple for a special scheme and the string "null" for any other, the lowering of url.origin. It is "null" and not the null value because the specification serializes an opaque origin that way.

func (*URL) Password

func (u *URL) Password() BStr

Password is the userinfo password, empty when there is none, the lowering of url.password.

func (*URL) Pathname

func (u *URL) Pathname() BStr

Pathname is the path, "/" for an absolute URL with no path, the lowering of url.pathname.

func (*URL) Port

func (u *URL) Port() BStr

Port is the port, empty when the URL uses its scheme's default, the lowering of url.port.

func (*URL) Protocol

func (u *URL) Protocol() BStr

Protocol is the scheme with its trailing colon, "https:", the lowering of url.protocol.

func (*URL) Search

func (u *URL) Search() BStr

Search is the query with its leading "?", empty when there is no query, the lowering of url.search. It reflects any mutation made through searchParams.

func (*URL) SearchParams

func (u *URL) SearchParams() *URLSearchParams

SearchParams is the live view over the query, the lowering of url.searchParams. It is the same object every read, as the specification requires, so a caller can hold it and keep mutating through it.

func (*URL) ToJSON

func (u *URL) ToJSON() BStr

ToJSON is the lowering of url.toJSON(), the serialized URL.

func (*URL) ToString

func (u *URL) ToString() BStr

ToString is the serialized URL, the lowering of url.toString(). ToJSON is the same string, which is what the specification defines for url.toJSON(), so JSON.stringify of a URL gives its href.

func (*URL) Username

func (u *URL) Username() BStr

Username is the userinfo name, empty when there is none, the lowering of url.username.

type URLSearchParams

type URLSearchParams struct {
	// contains filtered or unexported fields
}

URLSearchParams is an ordered list of query parameters, the lowering of new URLSearchParams(init). It is a multimap, not a map: a query can repeat a name, and getAll exists precisely to read the repeats, so the storage is a list and not a Go map.

url is set when this view belongs to a URL and nil for a standalone one. Every mutating method calls sync, so an owned view writes its serialization back through the owner.

func NewURLSearchParams

func NewURLSearchParams(query ...BStr) *URLSearchParams

NewURLSearchParams builds a view from an optional query string, the lowering of new URLSearchParams() and new URLSearchParams(query). A leading "?" is stripped, as the specification requires, so both "a=1" and "?a=1" parse the same.

func NewURLSearchParamsFrom

func NewURLSearchParamsFrom(other *URLSearchParams) *URLSearchParams

NewURLSearchParamsFrom copies another view's pairs, the lowering of new URLSearchParams(other). The copy is independent and unowned: mutating it never touches the source or the source's URL.

func (*URLSearchParams) Append

func (p *URLSearchParams) Append(name, value BStr)

Append adds a pair without disturbing an existing one of the same name, the lowering of params.append(name, value).

func (*URLSearchParams) Delete

func (p *URLSearchParams) Delete(name BStr)

Delete removes every pair with the given name, the lowering of params.delete(name).

func (*URLSearchParams) ForEach

func (p *URLSearchParams) ForEach(fn func(value, name BStr))

ForEach walks the pairs in order passing the value and then the name, the argument order the specification's callback takes, the lowering of a two-parameter params.forEach(cb).

func (*URLSearchParams) ForEachValue

func (p *URLSearchParams) ForEachValue(fn func(value BStr))

ForEachValue walks the pairs passing only the value, the lowering of a one-parameter params.forEach(cb). It is the common shape, so it gets a callback with no unused parameter, the same split map.forEach takes.

func (*URLSearchParams) Get

func (p *URLSearchParams) Get(name BStr) Value

Get is the first value for a name, the lowering of params.get(name). It returns a boxed Value rather than a BStr because the specification's answer for an absent name is null, not undefined or the empty string, and null is a value of its own: there is no BStr that means "no such parameter". So the result carries the string or Null, and the caller reads it on the dynamic path, the same shape re.exec's array-or-null takes.

func (*URLSearchParams) GetAll

func (p *URLSearchParams) GetAll(name BStr) *Array[BStr]

GetAll is every value for a name in insertion order, the lowering of params.getAll(name). An absent name gives an empty array, not null: this is the method that reads the repeats a query is allowed to carry.

func (*URLSearchParams) Has

func (p *URLSearchParams) Has(name BStr) bool

Has reports whether any pair carries the name, the lowering of params.has(name).

func (*URLSearchParams) Set

func (p *URLSearchParams) Set(name, value BStr)

Set replaces the first pair with the name and drops the rest, appending when the name is absent, the lowering of params.set(name, value). Keeping the first pair's position rather than moving it to the end is what the specification requires, and it is what makes set idempotent on the serialization.

func (*URLSearchParams) Size

func (p *URLSearchParams) Size() float64

Size is the pair count, the lowering of the params.size accessor. It counts pairs and not distinct names, so a query that repeats a name counts it each time.

func (*URLSearchParams) Sort

func (p *URLSearchParams) Sort()

Sort orders the pairs by name, the lowering of params.sort(). The sort is stable, so pairs that repeat a name keep their relative order, which the specification requires. Names compare by UTF-16 code unit, the ordering JavaScript's own relational operator gives, not by Go's byte ordering, which differs for the surrogate range.

func (*URLSearchParams) ToString

func (p *URLSearchParams) ToString() BStr

ToString is the form-urlencoded serialization, the lowering of params.toString().

type Uint8Array

type Uint8Array struct {
	// contains filtered or unexported fields
}

Uint8Array is bento's runtime representation of a JavaScript Uint8Array, the byte-buffer type a Go []byte projects to across the go: boundary (16 §6.3 and §7.3). It wraps a Go []byte, the exact storage a Go []byte already uses, so a crossing into a Go function taking []byte hands the bytes over with at most one copy and the value model's own collector owns the buffer (10 §6 and §7). A Uint8Array is spelled as a *Uint8Array in generated code the same way a typed array is spelled *Array[T], so the methods below can grow without changing how the value is named.

This slice implements the dense core the boundary needs: construction from a length, from a JavaScript number list, and from a Go slice, the .length as a Number, indexed reads and writes with JavaScript's byte coercion, and the backing slice the bridge passes to Go. Like the numeric family, a Uint8Array is a view: it records the ArrayBuffer it reads, the byte offset it starts at, and its byte length. It does not cache the subslice; live forms one over the buffer's current storage on each access, so a Uint8Array over a shared ArrayBuffer aliases the same bytes as any other view of it and reacts to a detach or a resize of the buffer. A byte is the buffer's own element, so the subslice aliases directly with no unsafe step. The length is consulted against the buffer's live state through liveLen, so a view over a detached buffer reads as zero-length. The remaining view methods (subarray, DataView) and the copying methods (set, slice, fill) land in later slices; the type carries the buffer now so those grow it in place.

func NewNodeBuffer

func NewNodeBuffer(n int) *Uint8Array

NewNodeBuffer builds a zero-filled Buffer of n bytes over its own storage, the Go-side constructor the runtime and the statics both build through.

func NewUint8Array

func NewUint8Array(length float64) *Uint8Array

NewUint8Array builds a zeroed buffer of the given length, the lowering of `new Uint8Array(n)`. It allocates a fresh ArrayBuffer sized to the length and views the whole of it, so the array owns its storage but exposes a buffer like every other typed array. The length is a Number in JavaScript, so it arrives as a float64 and is truncated toward zero the way ToIndex does. A negative or not-a-number length clamps to zero here rather than throwing; the RangeError JavaScript raises for a negative length is a later slice, and the covered subset passes a valid length.

func NodeBufferFromGo

func NodeBufferFromGo(b []byte) *Uint8Array

NodeBufferFromGo wraps a Go byte slice as a Buffer, adopting the slice rather than copying it, the same bargain Uint8ArrayFromGo makes: the caller has already decided whether the bytes are bento's to own.

func Uint8ArrayFromGo

func Uint8ArrayFromGo(b []byte) *Uint8Array

Uint8ArrayFromGo wraps a Go []byte as a Uint8Array, the Go-to-bento crossing of a []byte return (16 §7.3). It adopts the slice rather than copying, because the bridge has already decided on the copy-versus-share question by the time it calls this: when Go may keep or mutate the bytes after return the bridge passes a copy and this adopts that copy, and when the return is bento's to own the bridge passes the slice itself. Either way the buffer is bento's after the call. The adopted slice is wrapped in an ArrayBuffer so the array exposes a buffer like every other typed array.

func Uint8ArrayOf

func Uint8ArrayOf(elems ...float64) *Uint8Array

Uint8ArrayOf builds a buffer from a list of JavaScript numbers, the lowering of `new Uint8Array([a, b, c])`. Each element is coerced to a byte with ToUint8, so a value outside 0 to 255 wraps modulo 256 exactly as an assignment into a Uint8Array element does. It allocates a fresh buffer of the right size and fills it, so the array owns its storage.

func Uint8ArrayView

func Uint8ArrayView(buf *ArrayBuffer, byteOffset float64, length ...float64) *Uint8Array

Uint8ArrayView builds a Uint8Array that views an existing ArrayBuffer, the lowering of new Uint8Array(buffer, byteOffset, length). The byte offset defaults to zero and the length, when omitted, runs from the offset to the end of the buffer. The bytes slice is a subslice of the buffer's storage, so the view observes writes made through the buffer or through any other view of it. A byte offset or length past the buffer clamps to what it holds, the covered subset the RangeError is a later slice of.

func (*Uint8Array) At

func (a *Uint8Array) At(i float64) float64

At reads the byte a JavaScript index expression a[i] selects, as a Number in the range 0 to 255. Only a canonical integer index inside the buffer names a byte; an out-of-range or non-canonical index reads as 0 here rather than the undefined the spec gives, the covered subset for the numeric read path, since At's result is a Number. A read that flows into a dynamic slot takes GetIndex, which answers undefined for those indices.

func (*Uint8Array) Buffer

func (a *Uint8Array) Buffer() *ArrayBuffer

Buffer is the ArrayBuffer the view aliases, the .buffer getter, the same backing store every other view of the buffer holds so an identity comparison of two views' buffers holds.

func (*Uint8Array) ByteLength

func (a *Uint8Array) ByteLength() float64

ByteLength is the view's span in bytes, the .byteLength getter. A byte is the element, so the span equals the element count and Len reports the same Number, but both getters exist because the numeric family separates the two.

func (*Uint8Array) ByteOffset

func (a *Uint8Array) ByteOffset() float64

ByteOffset is the byte the view starts at within its buffer, the .byteOffset getter, a Number to match the property's type.

func (*Uint8Array) Bytes

func (a *Uint8Array) Bytes() []byte

Bytes returns the live backing slice, the storage the bridge passes to a Go function taking []byte (16 §7.3). It is not a copy: while a Go call runs it may read these bytes, and the caller in the bridge decides whether a copy is needed before handing them over, so a Go API that retains the slice never aliases bento's buffer by surprise.

func (*Uint8Array) BytesPerElement

func (a *Uint8Array) BytesPerElement() float64

BytesPerElement is the element width in bytes, the instance BYTES_PER_ELEMENT property, one for a byte array. It is a method so a read keeps the receiver referenced rather than folding to a literal that would orphan the binding.

func (*Uint8Array) Floats

func (a *Uint8Array) Floats() []float64

Floats widens every byte to the Number a read hands out, the source a fresh typed array copies when it is constructed from a Uint8Array. It allocates a new slice so the copy does not alias the source, matching the from-a-typed-array constructor's fresh-buffer rule.

func (*Uint8Array) GetIndex

func (a *Uint8Array) GetIndex(i float64) Value

GetIndex reads the byte a JavaScript index selects as a boxed Value, the form a Uint8Array read takes when it flows into a dynamic slot. It answers the byte as a Number for a canonical in-range index and the undefined singleton for an out-of-range or non-canonical one, so a[100] and a[1.5] read as undefined the way the spec requires, which the numeric At cannot express.

func (*Uint8Array) Len

func (a *Uint8Array) Len() float64

Len is the buffer's length in bytes. JavaScript's .length is a Number, so it is a float64 here to match the type the checker gives the property and to compose with the numeric path with no conversion at the use site.

func (*Uint8Array) SetAt

func (a *Uint8Array) SetAt(i float64, v float64)

SetAt writes the byte a JavaScript assignment a[i] = v stores. The value is coerced to a byte with ToUint8, so a number outside 0 to 255 wraps modulo 256 exactly as JavaScript does for a Uint8Array element. Only a canonical integer index inside the buffer names a byte; a write to an out-of-range or non-canonical index is dropped, the no-op the spec requires rather than growing the buffer.

func (*Uint8Array) ToValue

func (a *Uint8Array) ToValue() Value

ToValue is the Uint8Array half of the same crossing. A Node Buffer gets one thing a plain Uint8Array does not: its box is linked to Buffer.prototype, so `b instanceof Buffer` walks the chain and answers true. The link changes no read, because every member lookup consults the typed-array surface before it climbs the chain.

type Unit

type Unit struct{}

Unit is the no-value placeholder a void promise carries as its element type, so a Promise<void> lowers to a concrete *Promise[Unit] rather than needing a special element-less promise. It holds nothing: a fulfilled unit promise records only that the void async body completed.

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value is the boxed, self-describing dynamic value. It is three machine words: the tag, a scalar for immediates (a bool in the low bit or a number's raw float64 bits), and a pointer the collector scans for the reference kinds. It is passed by value, so a Value in a local or a slice lives inline with no separate allocation; only the reference kinds put anything on the heap.

func Add

func Add(a, b Value) Value

Add implements the JavaScript + operator over two dynamic values, the one operator whose result kind depends on its operands: if either side becomes a string after ToPrimitive, the result is the concatenation, and otherwise both coerce to numbers and add. This is the operator the dynamic path hits when an any-typed expression is added to anything.

func And

func And(a, b Value) Value

And implements the value-returning a && b over dynamic values: the left operand when it is falsy, the right otherwise. The same eager-argument caveat as Or applies, so the lowering gates on an effect-free right operand.

func Arg

func Arg(args []Value, i int) Value

Arg returns the ith boxed argument, or undefined when the call passed fewer, the value JavaScript binds to a parameter the caller omitted. A boxed callable reads its arguments through this helper so its body never indexes past the slice a short call hands it.

func ArgOr

func ArgOr(args []Value, i int, def Value) Value

ArgOr is Arg with the parameter's own default standing in for a missing argument, what a boxed callable needs when its parameter's Go slot is a static type with no undefined to test. The default is taken for an argument the call omitted and for one passed explicitly as undefined, which is the same rule JavaScript applies: a default is initialized whenever the argument is undefined, not only when it is absent.

func ArgumentsValue

func ArgumentsValue(a *Array[Value]) Value

ArgumentsValue boxes the arguments snapshot store into a dynamic value, sharing the store's backing so an index read off the box sees the same slot the element path reads and the box reports the same .length. The box is an ordinary array value, so spread, indexing, .length, and Array.prototype.slice.call over it all read the same elements.

The box is an array, so Array.isArray(arguments) and `arguments instanceof Array` report true where the real arguments exotic object reports false, and a property of the arguments object other than an index or length (callee, caller) is not modeled here; the lowerer hands those back rather than route them through this box. Closing that array-like-not-Array distinction is a later slice.

func ArrayFromArrayLike

func ArrayFromArrayLike(src, mapFn Value) Value

ArrayFromArrayLike builds an array from an array-like source, the general form Array.from takes when the source is a plain object carrying a length and integer keys rather than an iterable. It reads length the spec's ToLength way, then reads each index in order, a missing index reading undefined, so the result is dense with an undefined wherever the source had no key. When mapFn is not undefined it is called with each element and its index and the result becomes the element, matching Array.from's optional map callback.

func ArrayValueOf

func ArrayValueOf[T any](a *Array[T], box func(T) Value) Value

ArrayValueOf boxes a typed array into a live array Value, one element at a time through the element's own box constructor, so a *Array[float64] or *Array[BStr] can flow into a dynamic slot the way an array literal boxed straight to a Value does. It is the array sibling of ObjectFromStruct, and it copies for the same reason: the box holds its own elements, so a write through the box does not reach the typed array it was built from. That is why it is reached from the dynamic boundary, where the box is what the program works with from then on, rather than being how an array is represented.

func BigIntFromBig

func BigIntFromBig(b *big.Int) Value

BigIntFromBig boxes a *big.Int the typed side holds into a bigint value, the crossing a statically typed bigint takes into a dynamic slot: a bigint binding, a bigint literal, and a bigint operator result all lower to *big.Int, and this wraps one into the boxed BigInt the dynamic world reads. It copies the integer into a fresh BigInt rather than aliasing the source pointer, so the box owns its own value independent of the source's later reuse and of the *big.Int and *BigInt layouts staying identical; a JavaScript bigint is immutable, so the copy is the honest shape.

func BigIntFromInt64

func BigIntFromInt64(n int64) Value

BigIntFromInt64 boxes a Go int64 as a bigint. It is the crossing a Go int64 projected as bigint uses and the base BigInt(n) lowers to for a number that fits an int64.

func BigIntFromString

func BigIntFromString(s string) (Value, bool)

BigIntFromString boxes the arbitrary-precision integer a decimal digit string denotes, the path a bigint literal like 123n lowers through when the value does not fit an int64. It reports false for a string that is not a canonical base-10 integer, which the caller reports as a SyntaxError at lower time.

func BigIntValue

func BigIntValue(b *BigInt) Value

BigIntValue boxes an existing *BigInt without copying, the crossing that hands a bigint the typed side already lowered to *big.Int straight into the dynamic world. The pointer is shared because a bigint is immutable.

func BitAnd

func BitAnd(a, b Value) Value

BitAnd implements the & operator over two dynamic values. The bigint arm computes on big.Int's infinite two's complement, which is the bit model a negative JavaScript bigint means, while the number arm narrows each side to a signed 32-bit integer first, which is the bit model a number means.

func BitOr

func BitOr(a, b Value) Value

BitOr implements the | operator over two dynamic values.

func BitXor

func BitXor(a, b Value) Value

BitXor implements the ^ operator over two dynamic values.

func Bool

func Bool(b bool) Value

Bool boxes a Go bool as one of the two singletons.

func BufferConstructor

func BufferConstructor() Value

BufferConstructor returns the Buffer global: the callable Node exposes as a constructor plus the statics hanging off it. The lowerer emits a call to this for a program that names Buffer, and globalThis carries the same value, so the identity globalThis.Buffer === Buffer holds the way it does for process.

func CallMethod

func CallMethod(obj Value, key BStr, args ...Value) Value

CallMethod runs obj[key](args), the receiver-preserving form of a method call on a dynamic value. It is one operation rather than a read followed by a call so the object the property came off can be bound as the callee's `this`, which is what the language does and what a plain `obj.Get(key).Call(args)` throws away.

A callee that has no receiver slot, every boxed function that is not a method or a constructor, ignores the receiver and runs exactly as it did.

func CallWithThis

func CallWithThis(fn, this Value, args ...Value) Value

CallWithThis invokes a function value with an explicit receiver, the runtime behind F.call(obj, ...). It is the constructor-chaining idiom, where a derived constructor runs the base constructor's body over the object it is building:

function ArrayStream() { Stream.call(this); }

A constructor value and a method value each honor the receiver, since both bodies take one. Any other callable does not have a receiver slot to fill, so the argument would set a `this` the body could never read; the lowering refuses that case rather than reach here, and a value that arrives anyway runs with the receiver dropped, which is the same undefined its body would have read.

func ClassToValue

func ClassToValue[T any](x T) Value

ClassToValue boxes one class instance, the generic form an element boxer has to have. ObjectFromStruct takes an any, which is the right shape for a boxing site that names the value directly, but ArrayValueOf wants a func(T) Value it can apply down a typed slice, and a func(any) Value does not fit that however compatible the call would be. This is that function with the type parameter spelled, so an array of instances boxes with the element boxer inferred from the slice and no closure emitted per class.

func Coalesce

func Coalesce(a, b Value) Value

Coalesce implements the value-returning a ?? b over dynamic values: the left operand when it is neither null nor undefined and the right otherwise. Unlike Or it tests presence, not truthiness, so a zero or an empty string on the left is kept. The same eager-argument caveat as Or applies, so the lowering gates on an effect-free right operand.

func ConsoleObject

func ConsoleObject() Value

ConsoleObject returns the console global as an object, building it on first read and caching it, so console === console holds and a property a program sets on it is still there on the next read.

The members are the ones the lowerer also emits direct calls for, wrapped so a dynamic call reaches the same helper. They are ordinary enumerable properties, unlike the entries on globalThis: Node's console carries its methods as own enumerable properties, which is what makes Object.keys(console) list them.

func Construct

func Construct(fn Value, args ...Value) Value

Construct runs [Construct] over a constructor value, the runtime behind `new F(args)`. It makes a fresh object whose [[Prototype]] is the constructor's current .prototype, runs the body with that object as its receiver, and answers the object unless the body returned an object of its own, which overrides it the way `function F() { return other; }` does.

The prototype is read at construction time rather than captured when the constructor was made, because a program is free to replace it first, and the whole point of `B.prototype = new A()` is that instances built after the assignment link to the new object. A .prototype that is not an object leaves the instance on the default chain, which is what the spec's OrdinaryCreateFromConstructor falls back to.

func CryptoValue

func CryptoValue() Value

CryptoValue returns the crypto global as an object, building it on first read. The members are own properties on the object, where Node carries them on Crypto.prototype; that is the same shape the other host classes here take (abort.go, event.go), and it changes a read of one only under Object.getOwnPropertyNames.

func DateToJSON

func DateToJSON(d *Date) Value

DateToJSON is ToJSON reached as a function, the shape the lowerer emits so the call site does not have to name a method on a value whose Go type it is boxing away.

func Dec

func Dec(v Value) Value

Dec implements the -- update, the numeric decrement sibling of Inc: the operand's ToNumeric minus one, a bigint staying a bigint.

func Div

func Div(a, b Value) Value

Div implements the / operator over two dynamic values. Dividing numbers by zero gives an infinity, while dividing bigints by 0n throws, so the two arms differ in more than their result kind.

func EmitProcessEventNamed

func EmitProcessEventNamed(event Value, args ...Value) Value

EmitProcessEventNamed is EmitProcessEvent for an event named by a value, the runtime behind process.emit. It answers the boolean emit answers: whether anything was listening.

func ErrorConstructor

func ErrorConstructor(name string) Value

ErrorConstructor returns the constructor value for a built-in error name, the lowering of naming TypeError or one of its siblings as a value. A known name returns the interned singleton, so repeated references share identity the way a single global constructor does. An unknown name (a custom error class, which the class slice will own) returns a fresh constructor carrying that name, so .name still reads correctly; the identity of a fresh value is per call, a deviation the class slice removes once it interns user constructors.

func Exponentiate

func Exponentiate(a, b Value) Value

Exponentiate implements the ** operator over two dynamic values.

func FromEntries

func FromEntries(iterable Value) Value

FromEntries builds a fresh object from an iterable of key-value pairs, the runtime behind Object.fromEntries(iterable). Each entry is read for its first two elements, the key and the value, and the key is set on the new object through the ordinary property-key coercion, so a later entry with the same key overwrites an earlier one. An array is read straight off its dense elements, since that is the common source and a hole there contributes no entry; every other iterable, a Map above all, is drained through the iteration protocol the same way a for...of would drain it.

func GenericAt

func GenericAt(recv, index Value) Value

GenericAt runs Array.prototype.at on a generic receiver: a non-negative index reads that element and a negative one counts back from the end, with an index outside the range reading undefined rather than clamping.

func GenericConcat

func GenericConcat(recv Value, items ...Value) Value

GenericConcat runs Array.prototype.concat on a generic receiver, returning a new array of the receiver's elements followed by each argument's. A spreadable argument, an array, contributes its elements one by one; any other argument is appended whole, the way concat folds a non-array into a single slot. A hole in the receiver or in a spreadable argument stays a hole in the result, so concat carries holes across rather than filling them with undefined.

func GenericCopyWithin

func GenericCopyWithin(recv Value, bounds ...Value) Value

GenericCopyWithin runs Array.prototype.copyWithin on a generic receiver, copying the block of elements starting at from into the positions starting at to, both relative indices that count from the end when negative, and returning the receiver. The copy runs backward when the ranges overlap so a source is read before it is overwritten. A hole in the source stays a hole: rather than writing undefined, the target index is deleted, matching the spec's DeletePropertyOrThrow on a missing source.

func GenericEntries

func GenericEntries(recv Value) Value

func GenericEvery

func GenericEvery(recv, cb Value, thisArg ...Value) Value

GenericEvery runs Array.prototype.every on a generic receiver, reporting whether the callback's result is truthy for every element, stopping at the first that is not.

func GenericFill

func GenericFill(recv, value Value, bounds ...Value) Value

GenericFill runs Array.prototype.fill on a generic receiver, writing value into each index in the half-open range [start, end) and returning the receiver. start and end are relative indices: a negative bound counts from the end and clamps at 0, a positive bound clamps at the length, and an omitted start is 0 and an omitted end is the length. The receiver is returned so the borrowed call reads as the in-place fill the array method evaluates to.

func GenericFilter

func GenericFilter(recv, cb Value, thisArg ...Value) Value

GenericFilter runs Array.prototype.filter on a generic receiver, returning a new array of the elements for which the callback's result is truthy, in order.

func GenericFind

func GenericFind(recv, cb Value, thisArg ...Value) Value

GenericFind runs Array.prototype.find on a generic receiver, returning the first element for which the callback's result is truthy, or undefined when none is. Unlike the hole-skipping methods, find visits a hole as undefined, so the callback is called for every index in range.

func GenericFindIndex

func GenericFindIndex(recv, cb Value, thisArg ...Value) Value

GenericFindIndex runs Array.prototype.findIndex on a generic receiver, returning the index of the first element for which the callback's result is truthy, or -1.

func GenericFindLast

func GenericFindLast(recv, cb Value, thisArg ...Value) Value

GenericFindLast runs Array.prototype.findLast, the backward twin of find: it walks from the end and answers the first element the predicate accepts, or undefined. It visits every index rather than skipping holes, which is what the find family does and what separates it from forEach.

func GenericFindLastIndex

func GenericFindLastIndex(recv, cb Value, thisArg ...Value) Value

GenericFindLastIndex is findLast's index form, answering the index the predicate accepted or -1.

func GenericFlat

func GenericFlat(recv Value, depth ...Value) Value

GenericFlat runs Array.prototype.flat, concatenating nested arrays into the result down to the given depth, one level by default and every level for Infinity.

func GenericFlatMap

func GenericFlatMap(recv, cb Value, thisArg ...Value) Value

GenericFlatMap runs Array.prototype.flatMap, which maps then flattens one level. It is not map followed by flat: the callback's result is spread only when it is an array, and only ever one level deep, whatever the callback returns.

func GenericForEach

func GenericForEach(recv, cb Value, thisArg ...Value) Value

GenericForEach runs Array.prototype.forEach on a generic receiver, calling the callback with each element, its index, and the receiver, and returning undefined.

func GenericIncludes

func GenericIncludes(recv, target Value, from ...Value) Value

GenericIncludes runs Array.prototype.includes on a generic receiver, reporting whether any element at or after fromIndex is SameValueZero-equal to target, so a stored NaN is found where indexOf would miss it. The result boxes to a boolean.

func GenericIndexOf

func GenericIndexOf(recv, target Value, from ...Value) Value

GenericIndexOf runs Array.prototype.indexOf on a generic receiver, returning the index of the first element strictly equal to target at or after fromIndex, or -1. A negative fromIndex counts from the end, the way the array method does. The result boxes to a number so a borrowed call yields a value whatever the receiver.

func GenericJoin

func GenericJoin(recv Value, sep ...Value) Value

GenericJoin runs Array.prototype.join on a generic receiver, concatenating the string form of each element with a separator between them. The separator defaults to a comma and an explicit undefined takes that default too, any other separator coercing through ToString. A hole reads as undefined and undefined and null each contribute the empty string, so join treats a hole as undefined the way the spec does. The result boxes to a string.

func GenericKeys

func GenericKeys(recv Value) Value

GenericKeys, GenericValues and GenericEntries hand back the three array iterators, each as the object a manual next() drives and a for...of pulls.

func GenericLastIndexOf

func GenericLastIndexOf(recv, target Value, from ...Value) Value

GenericLastIndexOf runs Array.prototype.lastIndexOf on a generic receiver, returning the index of the last element strictly equal to target at or before fromIndex, or -1. fromIndex defaults to the last index and a negative value counts from the end.

func GenericMap

func GenericMap(recv, cb Value, thisArg ...Value) Value

GenericMap runs Array.prototype.map on a generic receiver, returning a new array whose element k is the callback's result on element k. The result is a real array whatever the receiver's kind, so a borrowed map on an array-like still yields an array.

func GenericPop

func GenericPop(recv Value) Value

GenericPop runs Array.prototype.pop on a generic receiver, removing and returning the last element. An empty receiver still has its length written back as 0, the way the spec does, and answers undefined.

func GenericPush

func GenericPush(recv Value, items ...Value) Value

GenericPush runs Array.prototype.push on a generic receiver, appending each item at the current length in order and returning the new length. It writes length back explicitly, so an array-like object that carries a plain length property ends up with the right one rather than only the new keys.

func GenericReduce

func GenericReduce(recv, cb Value, initial ...Value) Value

GenericReduce runs Array.prototype.reduce on a generic receiver, folding the present elements left to right into a single accumulator. With an initial value the fold seeds from it and runs over every present index; with no initial value it seeds from the first present element and runs from the next, so an all-hole or empty receiver with no initial value throws a TypeError the way the array method does. A hole is skipped, never visited, matching the spec's kPresent guard. The callback takes the four arguments the spec passes, the accumulator, the element, its index as a number, and the receiver.

func GenericReduceRight

func GenericReduceRight(recv, cb Value, initial ...Value) Value

GenericReduceRight runs Array.prototype.reduceRight on a generic receiver, folding the present elements right to left into a single accumulator. It mirrors GenericReduce: with an initial value the fold seeds from it, otherwise it seeds from the last present element and an all-hole or empty receiver with no initial value throws a TypeError. A hole is skipped, and the callback takes the accumulator, the element, its index, and the receiver.

func GenericReverse

func GenericReverse(recv Value) Value

GenericReverse runs Array.prototype.reverse on a generic receiver, swapping the element at each index with its mirror across the middle and returning the receiver. Each swap reads both elements as properties named by their indices and writes them back, so a real array and an array-like object both reverse in place.

func GenericShift

func GenericShift(recv Value) Value

GenericShift runs Array.prototype.shift on a generic receiver, removing and returning the first element and moving every later element down one index. A hole moves as a hole, which is why the loop deletes rather than writes undefined when the source index is absent.

func GenericSlice

func GenericSlice(recv Value, bounds ...Value) Value

GenericSlice runs Array.prototype.slice on a generic receiver, returning a new array of the elements in the half-open range [start, end), read as the properties named by their indices. start and end are relative indices: a negative bound counts from the end and clamps at 0, a positive bound clamps at the length, an omitted start is 0 and an omitted end is the length. The result is a real array whatever the receiver's kind, so a borrowed slice on an array-like still yields an array. A hole in the range stays a hole in the result rather than materializing as a stored undefined, matching the spec's HasProperty guard on each copied index.

func GenericSome

func GenericSome(recv, cb Value, thisArg ...Value) Value

GenericSome runs Array.prototype.some on a generic receiver, reporting whether the callback's result is truthy for any element, stopping at the first that is.

func GenericSort

func GenericSort(recv Value, cmp ...Value) Value

GenericSort runs Array.prototype.sort on a generic receiver, ordering it in place and returning it. A comparator that is neither undefined nor callable throws before anything is read, the way the spec checks it first.

func GenericSplice

func GenericSplice(recv Value, args ...Value) Value

GenericSplice runs Array.prototype.splice on a generic receiver: it removes count elements at start, inserts the items in their place, and returns what it removed. The shift that closes or opens the gap runs in whichever direction keeps a move from overwriting an element it has not read.

func GenericToLocaleString

func GenericToLocaleString(recv Value) Value

GenericToLocaleString runs Array.prototype.toLocaleString, which joins with a comma like toString but renders each element by calling its own toLocaleString rather than its toString. A nullish element renders empty, the way join treats one.

func GenericToReversed

func GenericToReversed(recv Value) Value

GenericToReversed runs Array.prototype.toReversed, the copying form of reverse.

func GenericToSorted

func GenericToSorted(recv Value, cmp ...Value) Value

GenericToSorted runs Array.prototype.toSorted, the copying form of sort: it builds a new dense array in order and leaves the receiver alone. Being dense, a hole in the source becomes an undefined at the end rather than staying a hole.

func GenericToSpliced

func GenericToSpliced(recv Value, args ...Value) Value

GenericToSpliced runs Array.prototype.toSpliced, the copying form of splice: it builds a new dense array with count elements replaced by the items and leaves the receiver alone. A hole in the source reads as undefined here, since the result is dense the way the copying methods all are.

func GenericToString

func GenericToString(recv Value) Value

GenericToString runs Array.prototype.toString, which is join with a comma and is what String(arr) and a template interpolation of an array both reach.

func GenericUnshift

func GenericUnshift(recv Value, items ...Value) Value

GenericUnshift runs Array.prototype.unshift on a generic receiver, inserting the items at the front and returning the new length. The existing elements move up by the number of items, walked from the top down so a move never overwrites an element it has not read yet.

func GenericValues

func GenericValues(recv Value) Value

func GenericWith

func GenericWith(recv, index, val Value) Value

GenericWith runs Array.prototype.with: a copy of the receiver with one index replaced. A negative index counts from the end, and an index outside the range throws a RangeError rather than growing the result, which is what separates it from a plain write.

func GlobalThisValue

func GlobalThisValue() Value

GlobalThisValue returns the globalThis global, building it on first read.

func GlobalValue

func GlobalValue(name string) Value

GlobalValue returns the value form of an ambient global, the lowering of naming one rather than calling it. The name is one the lowerer only emits after asking HostsGlobal, so an unknown name here is a bug in that pairing rather than something a program can reach; it answers undefined rather than panicking, since a compiled program crashing inside its own prelude is the worse of the two.

func Identity

func Identity(v Value) Value

Identity is the element boxer for an element that is already a box, the value.Value an any[] or an array written with no element type at all holds. ArrayValueOf applies a boxer to every element and has no way to skip one, so the array of boxes needs a boxer that hands its argument straight back rather than a special case in the loop. It is spelled here rather than as a closure at each site so an emitted box of a dynamic array reads as the one call the other element types get.

func Inc

func Inc(v Value) Value

Inc implements the ++ update over a dynamic value: the operand's ToNumeric plus one. Every kind but bigint coerces to a number, so "5"++ is 6 and true++ is 2, and a bigint stays a bigint so 9n++ is 10n, the ToNumeric contract the update operators keep. It differs from Add over one, which would concatenate a string operand rather than coerce it, so the update stays numeric on every kind.

func IterFind

func IterFind(next func() IterResult, fn Value) Value

IterFind drives the source until fn(value, index) is truthy and returns that value, the terminal find. It returns the first passing value, pulling no further, and undefined once the source is exhausted with none passing, so an empty source is undefined.

func IterForEach

func IterForEach(next func() IterResult, fn Value) Value

IterForEach drives the source to exhaustion and calls fn(value, index) for each, the terminal forEach. It returns undefined the way the method does, running fn only for its side effect and passing the zero-based index of every value it visits.

func IterReduce

func IterReduce(next func() IterResult, fn Value, hasInit bool, init Value) Value

IterReduce drives the source to exhaustion and folds it with fn, the terminal reduce. With an initial value the fold seeds from it and the index counts from zero; without one the first value seeds the accumulator, the index counts from one, and an empty source throws a TypeError the way the spec does for a reduce with no seed. fn receives the running accumulator, the value, and the index.

func IterToArray

func IterToArray(next func() IterResult) Value

IterToArray drives the source to exhaustion and collects its values into a new array, the terminal toArray. The values ride into the array as the boxed values the source yields, so the result is a dense array a caller can index or spread.

func IterateToSlice

func IterateToSlice(v Value, src string) []Value

IterateToSlice drains an iterable into a Go slice, the eager form a spread and an array destructuring need where a loop will not stand: `[...it]` and `const [a, b] = it` both want every element at once. It is Iterate driven to exhaustion, so the two agree on what is iterable and on what each element is.

func JSONParse

func JSONParse(s BStr) Value

JSONParse reads a JSON document from s and returns the boxed value it denotes, the value model's JSON.parse. It parses the one top-level value and requires only whitespace after it; a value that does not parse, or any non-whitespace content after it, throws the SyntaxError JavaScript raises on malformed JSON.

func JSONParseReviver

func JSONParseReviver(s BStr, reviver func(BStr, Value) Value) Value

JSONParseReviver is JSON.parse(text, reviver): it parses the text into a boxed Value tree and then walks the tree bottom-up, calling the reviver for every key and value. A reviver result of undefined deletes the property; any other result replaces it. The root is held under the empty key of a wrapper object, the way the specification seeds the walk, so the reviver runs once more on the whole document under the "" key and can replace it outright.

func JSONStringifyOpt

func JSONStringifyOpt(v any) Value

JSONStringifyOpt is JSON.stringify of a top-level optional, the T | undefined shape a keyed read of a collection answers. Its result is a Value rather than a BStr for the same reason JSONStringifyUndefined's is: an absent optional is undefined, and JSON.stringify of undefined is the value undefined, not a string.

A present one serializes the arm it holds. Without this the walk would reach the value.Opt struct itself, whose two fields are unexported, and write it as an empty object; the field walk already unwraps an optional this way, and this is the same unwrapping at the top of the walk, where there is no field to hang it off.

func JSONStringifyUndefined

func JSONStringifyUndefined(v any) Value

JSONStringifyUndefined is JSON.stringify of a top-level value whose JSON form is undefined: a function, a symbol, or undefined itself. SerializeJSONProperty returns the value undefined for these, not a string, so the lowering emits this in place of JSONStringify when the argument's static type is one of those shapes. The argument is still passed (and so evaluated for its side effects, matching the spec order that evaluates the argument before the call) but does not affect the undefined result.

func MissingProperty

func MissingProperty(recv any) Value

MissingProperty is the value of a property read whose receiver's fixed shape does not declare the property. A shape interns to a Go struct that carries exactly its declared fields, so such a read is a provable miss and the language answers undefined. The receiver is passed and dropped rather than ignored at the call site so its evaluation still happens, keeping any effect a receiver expression like getObj().foo carries, and so the read references the receiver the Go compiler would otherwise flag as unused. It takes any because the receiver is a static Go value of the shape's struct type, not a boxed value.

func Mul

func Mul(a, b Value) Value

Mul implements the * operator over two dynamic values.

func NewAbortController

func NewAbortController() Value

NewAbortController builds an AbortController, the object that owns one signal and can trip it. signal is the AbortSignal a consumer passes to a cancelable operation and abort(reason) trips that signal with the given reason or the default AbortError. The controller is the only holder of the trip, which is the whole point of the pair: the consumer sees a read-only signal while the producer keeps the ability to cancel.

func NewAbortSignal

func NewAbortSignal() Value

NewAbortSignal builds an AbortSignal, an EventTarget carrying the aborted flag it starts false, the reason it starts undefined, and an onabort handler slot a program may set to a function. throwIfAborted throws the reason when the signal is aborted and is a no-op otherwise, the guard a consumer runs before starting work. The signal is returned as a value the caller holds as an any, the same shape an EventTarget takes.

func NewAbortSignalAborted

func NewAbortSignalAborted(reason Value) Value

NewAbortSignalAborted builds a signal that is already aborted with the given reason, the value AbortSignal.abort(reason) returns. It is the static factory's counterpart to a controller: no controller trips it, it starts tripped, so a consumer that reads it sees aborted true and the reason from the first read. An undefined reason becomes the default AbortError, matching a controller's abort with no argument.

func NewArrayValue

func NewArrayValue(elems []Value) Value

NewArrayValue returns an array value holding the given elements, the target JSON.parse builds as it reads an array literal. The elements are taken as given, in order, so the array's indices match the source order.

func NewCtor

func NewCtor(name string, arity int, fn ctorFn) Value

NewCtor boxes a Go closure as an ES5 constructor function value, the pair a `function F(...) {...}` declaration creates when a program treats it as a constructor: F is callable and constructible, F.prototype is a fresh object, and F.prototype.constructor points back at F.

The three own properties are defined rather than assigned, with the attributes the spec gives them, so none of them shows up in Object.keys(F) or in a logged rendering of it. prototype is writable and non-configurable, which is what lets `B.prototype = new A()` replace the object wholesale; name and length are the non-enumerable, configurable pair every function carries.

arity is the declared parameter count the function reports as .length, which is the count before the first default or rest parameter, the same number the lowerer reads off the declared signature.

func NewEvent

func NewEvent(typeVal Value, init Value) Value

NewEvent builds an Event value of the given type, the object dispatchEvent hands each listener. It carries the read-only type and the bubbles and cancelable flags the init dictionary sets, and preventDefault marks it canceled only when it is cancelable, the spec's rule that a non-cancelable event ignores preventDefault. target and currentTarget start null and dispatch fills them, so a listener reading event.target sees the target it dispatched on. init is the optional second argument, read for its bubbles and cancelable members when it is an object.

func NewEventTarget

func NewEventTarget() Value

NewEventTarget builds an EventTarget value, the object addEventListener registers on and dispatchEvent fires. The registry maps an event type to its listeners in registration order, closed over by the three methods so they share one instance's state without a Go struct backing the value. Dispatch is single-target: with no node tree under a bare EventTarget there is no bubbling or capture to run, so a capture flag on a registration is accepted and has no effect, and the listeners for the dispatched type run in registration order.

func NewFunc

func NewFunc(fn callFn) Value

NewFunc boxes a Go closure as a callable function value, the box a static function takes when it flows into a dynamic slot so a dynamic call site can invoke it. A function is an object too (it can carry properties like name and length), so it rides the same Object storage as a plain object with the call body set; the kind stays KindFunc so typeof reports "function" and a property read still finds the object's own keys.

func NewMethod

func NewMethod(fn ctorFn) Value

NewMethod boxes a Go closure as a function value that reads its receiver, the box a function expression takes when it is written onto an object and then called back off it:

A.prototype.who = function () { return "A:" + this.tag; };
new A("x").who();

A plain NewFunc box has no receiver slot, so a body like that one would read undefined for `this` and answer "A:undefined", which is a wrong answer rather than a refusal. A method value carries the body as a ctorFn instead, and the method-call path hands it the object the call selected it from.

The value is otherwise an ordinary callable: WithName still names it, a property read still finds its own keys, and calling it with no receiver, the way a plain callback is invoked, binds the undefined a receiver-free call leaves.

func NewObject

func NewObject() Value

NewObject returns an empty plain object value, the target JSON.parse builds a key at a time as it reads an object literal.

func NewProxy

func NewProxy(target, handler Value) Value

NewProxy builds a Proxy over target with handler, the runtime behind new Proxy(target, handler). Both must be objects, so a primitive for either throws a TypeError the way the constructor's first steps reject it. The proxy takes its kind from the target: a callable target yields a callable proxy so typeof reports "function" and a call reaches the apply path, and any other object target yields an object proxy. The proxy's own property bag stays empty; every read, write, and probe routes through the handler and the target instead.

func NewSymbol

func NewSymbol(desc BStr) Value

NewSymbol boxes a fresh symbol with the given description, the value a Symbol(desc) call produces. Each call allocates a new Symbol, so two calls with the same description are still distinct references and never compare equal, the uniqueness the language guarantees.

func NewSymbolNoDesc

func NewSymbolNoDesc() Value

NewSymbolNoDesc boxes a fresh symbol created without a description, the value a bare Symbol() call produces, whose description reads back as undefined.

func Number

func Number(f float64) Value

Number boxes a float64. The raw bits are stored, so a NaN payload and a negative zero round-trip unchanged, which the number-to-string and equality paths rely on.

func ObjectCoerce

func ObjectCoerce(v Value) Value

ObjectCoerce is Object(x): the coercion that answers the object form of a value. An object is already one and comes back unchanged, which is what makes Object(process.config) === process.config hold, and null or undefined answer a fresh empty object.

A primitive has no answer here. The object form of one is a wrapper object, a Number or a String holding a primitive inside it, and bento does not model those: there is no value in this package a program could get back that would behave like one. Throwing names that gap rather than handing back something that is not what was asked for.

func ObjectCreate

func ObjectCreate(proto Value) Value

ObjectCreate returns a new plain object whose [[Prototype]] is proto, the runtime behind Object.create(proto). An object prototype is stored in the new object's slot so a later read climbs into it, and a null prototype leaves the slot nil so the object is prototype-less and a read never climbs past its own bag. The result is a fresh, extensible object with no own properties, the target Object.create hands back before an optional descriptor map is applied. A prototype that is neither an object nor null throws a TypeError the way the spec rejects it.

func ObjectFromStruct

func ObjectFromStruct(v any) Value

ObjectFromStruct boxes a generated fixed-shape object struct into a live plain object Value, one property per exported field named by its json tag, so a value whose Go representation is a concrete struct can flow into a dynamic slot (an index-signature dictionary, an any, a JS object parameter) the same way an object literal boxed straight to a Value does. An absent optional field is dropped and an embedded struct flattens its fields in, matching how the JSON walk reads the shape. It reuses the same reflection the JSON replacer already uses to turn a struct into a Value object, so the two never disagree on which fields a shape contributes.

func OnProcessEventNamed

func OnProcessEventNamed(event, fn Value) Value

OnProcessEventNamed registers a listener for an event named by a value rather than by a literal, the runtime behind process.on(name, fn) where the name is computed or is a symbol. The listener is checked here rather than at compile time, since a value the checker could not see a call signature on may still be a function at run time, and a value that is not one is Node's ERR_INVALID_ARG_TYPE.

func OnceProcessEvent

func OnceProcessEvent(event, fn Value) Value

OnceProcessEvent registers a listener that runs at most once, the runtime behind process.once. The registration is dropped as the listener is called rather than after it returns, so a listener that emits the same event again does not re-enter itself.

func OptToValue

func OptToValue[T any](o Opt[T], box func(T) Value) Value

OptToValue boxes an optional into the dynamic Value the language sees when a T | undefined result flows into an any slot, the lowering of an optional passed where a boxed value is wanted (console.log of an array's at or pop, a member read the checker types number | undefined). A present value boxes through the element's own box constructor, which the caller supplies because the element type T is not itself a Value and only the call site knows how to wrap it; an undefined optional is the undefined singleton, the box the language already uses for a missing value.

func OptValue

func OptValue(o Opt[Value]) Value

OptValue unwraps an Opt[Value] into a plain Value: the present element when it holds one, otherwise the undefined singleton. It is the identity-element case of OptToValue, the box a method whose declared return is T | undefined needs when T is any: the checker collapses any | undefined back to any, so downstream every use of the result wants a Value, yet the runtime method still returns Opt[Value]. Threading it through OptValue keeps the static any contract and the runtime representation in agreement without a per-call closure.

func OptionalElem

func OptionalElem(v Value, key Value) Value

OptionalElem is a?.[k] on a boxed receiver whose key is itself a box or a symbol: undefined when the receiver is null or undefined, and the ordinary computed read otherwise. The key is coerced the way GetElem coerces it, a symbol looked up by identity and anything else taken through ToString, so an optional read resolves the same key its non-optional spelling would.

func OptionalIndex

func OptionalIndex(v Value, i float64) Value

OptionalIndex is a?.[i] on a boxed receiver with a number index: undefined when the receiver is null or undefined, and the ordinary indexed read otherwise. It is the numeric spelling of OptionalMember, and it exists rather than the caller boxing the index and going through OptionalElem so a number index costs the same here as it does on the plain a[i] read.

func OptionalMember

func OptionalMember(v Value, key BStr) Value

OptionalMember is a?.b on a boxed receiver: undefined when the receiver is null or undefined, and the ordinary property read otherwise. The short circuit is the whole point of the optional chain, and a box is the one receiver that can carry either answer without the lowerer having to prove which, so the question is asked here at run time. A longer chain composes by feeding this call's result back in as the next receiver, which is what makes a?.b?.c stop at the first nullish link.

func Or

func Or(a, b Value) Value

Or implements the value-returning a || b over dynamic values: the left operand when it is truthy, the right otherwise. Both arguments arrive evaluated, so the lowering only takes this form when the right operand has no side effect to short-circuit away; a right operand with an effect keeps its hand-back until the lazy form lands.

func PrependOnceProcessListener

func PrependOnceProcessListener(event, fn Value) Value

PrependOnceProcessListener is prependListener and once at the same time, the runtime behind process.prependOnceListener.

func PrependProcessListener

func PrependProcessListener(event, fn Value) Value

PrependProcessListener puts a listener at the front of an event's list, the runtime behind process.prependListener. A program uses it to see an event before a listener something else installed, which is the whole reason the method exists.

func ProcessEventNames

func ProcessEventNames() Value

ProcessEventNames answers the events with at least one listener, in the order their first listener arrived, the runtime behind process.eventNames. A symbol-named event answers as the symbol itself, since that is the only value that can be handed back to on or emit and reach the same list.

func ProcessKill

func ProcessKill(args []Value) Value

ProcessKill sends a signal to a process, the runtime behind process.kill(pid, sig). The signal defaults to SIGTERM and may be named or numbered; signal 0 sends nothing and reports whether the process exists, which is what a liveness check uses. A program most often sends to itself, which is how a test drives its own handler.

func ProcessListeners

func ProcessListeners(event Value) Value

ProcessListeners answers the listeners registered for an event, the runtime behind process.listeners. Node answers a copy, which is what lets the caller in Node's own test suite save a list, remove everything, and put the saved listeners back.

func ProcessValue

func ProcessValue() Value

ProcessValue returns the process global, building it on first read. The lowerer emits one package-level call to it per program, so the compiled binary pays for the environment and argument snapshots only when the program actually names process.

func ProxyRevocable

func ProxyRevocable(target, handler Value) Value

ProxyRevocable is the runtime behind Proxy.revocable(target, handler): it builds a proxy the same way new Proxy does and pairs it with a revoke function, returned as a { proxy, revoke } object. Calling revoke flips the proxy's revoked flag and drops its target and handler, so every later operation throws through checkRevoked and the target is no longer reachable through the dead proxy.

func ReflectApply

func ReflectApply(target, thisArg, argsList Value) Value

ReflectApply implements Reflect.apply(target, thisArgument, argumentsList): the [[Call]] Function.prototype.apply performs, reading the array-like argumentsList into a positional argument list the spec's CreateListFromArrayLike way and calling the target with it. bento's callables never read this, so a body that would consult thisArgument hands back at its declaration and the argument is threaded no further here. A non-callable target throws the TypeError the spec raises.

func ReflectGet

func ReflectGet(target, key Value) Value

ReflectGet implements Reflect.get(target, key): the ordinary [[Get]] with the receiver defaulting to the target, so it reads the same value target[key] would, climbing the prototype chain and running an inherited getter with the target as its this. The three-argument receiver form is a later slice, gated at lowering.

func ReflectGetOwnPropertyDescriptor

func ReflectGetOwnPropertyDescriptor(target, key Value) Value

ReflectGetOwnPropertyDescriptor implements Reflect.getOwnPropertyDescriptor(target, key): the [[GetOwnProperty]] Object.getOwnPropertyDescriptor performs, returning the descriptor object for an own property or undefined when the key is absent. Unlike the Object form, which coerces a primitive target to an object, it throws the TypeError every Reflect method raises on a non-object target.

func ReflectGetPrototypeOf

func ReflectGetPrototypeOf(target Value) Value

ReflectGetPrototypeOf implements Reflect.getPrototypeOf(target): the [[GetPrototypeOf]] Object.getPrototypeOf performs, reporting the target's prototype object or null. Unlike the Object form it throws the TypeError every Reflect method raises on a non-object target rather than coercing it.

func RegExpValue

func RegExpValue(re *RegExp) Value

RegExpValue boxes a *RegExp into a dynamic value. The box is a KindObject value, so it is an object everywhere the value model asks its kind, and it keeps the live regexp reachable through the object's regexp field, so a read off the box sees the same lastIndex a concrete read would and String(box) renders the literal form.

func Rem

func Rem(a, b Value) Value

Rem implements the % operator over two dynamic values. The number arm is math.Mod, which keeps the sign of the dividend the way JavaScript's remainder does rather than the sign of the divisor a modulo would take.

func RemoveAllProcessListeners

func RemoveAllProcessListeners(args ...Value) Value

RemoveAllProcessListeners drops every listener for an event, or every listener for every event when it is called with no argument, the runtime behind process.removeAllListeners. A program calls it on a signal to hand the signal back to its default disposition, which is why the disarm matters as much as the drop: after this, a SIGINT terminates the process again.

func RemoveProcessListener

func RemoveProcessListener(event, fn Value) Value

RemoveProcessListener drops one registration for an event, the runtime behind process.removeListener and its alias off. Node removes the most recently added match, and a once wrapper is found by the function the program passed rather than by the wrapper, which is why the listener a registration holds is the original.

func RequireBuiltin

func RequireBuiltin(specifier string) Value

RequireBuiltin returns the registered built-in module for a specifier, the value require('assert') or require('node:assert') evaluates to. The result is cached by canonical name, so the two specifier forms share one identity and a repeated require returns the same value. A name outside the registry never reaches here, since the lowerer gates the call on IsBuiltinModule; a specifier that slips through resolves as a fresh stub rather than panicking, keeping the runtime total.

func RequireFunc

func RequireFunc() Value

RequireFunc returns the CommonJS require function as a callable value, the box a module's require binding takes. A require of a specifier the compiler resolved to a sibling module lowers to a direct call on that module's loader, not through this value; this value is what a bare require reference, a typeof require, or a require of a specifier the compiler could not resolve statically evaluates to. Such a call throws the error Node raises for a specifier it cannot resolve, so a program that probes require works (typeof require is "function", and require can be passed around and stored) while a dynamic or missing require fails honestly rather than resolving to a silent wrong value. The specifier is coerced to a string the way Node coerces its argument, and the message matches Node's exactly so a test that asserts on err.message compares equal.

func SharedFunc

func SharedFunc(key string, box Value) Value

SharedFunc answers the one box for key, taking the wrapper it was handed as that box the first time it is asked. The wrapper is built by the caller either way, which costs one closure allocation at the sites that lose the race; making it lazy would mean a thunk per site, which allocates the same closure to avoid allocating a closure.

func ShiftLeft

func ShiftLeft(a, b Value) Value

ShiftLeft implements the << operator over two dynamic values. A bigint shifts by the whole count, since a bigint has no width to overflow; a number masks the count to five bits, since it is shifting a 32-bit integer.

func ShiftRight

func ShiftRight(a, b Value) Value

ShiftRight implements the >> operator over two dynamic values, the arithmetic shift that keeps the sign in both arms.

func SpreadCallArgs

func SpreadCallArgs(v Value) []Value

SpreadCallArgs drains a spread operand in a call's argument list into the boxed arguments the callee reads, which is IterateToSlice under the message that site words differently.

func StringValue

func StringValue(s BStr) Value

StringValue boxes a BStr. The string is a value type, so it is copied to the heap and the box holds a pointer to that copy, which the collector scans as the reference payload.

func StructToValue

func StructToValue[T any](x T) Value

StructToValue boxes one generated struct, the generic form an element boxer has to have. It is ObjectFromStruct with the type parameter spelled, for the same reason ClassToValue is: ObjectFromStruct takes an any, which fits a boxing site that names the value directly, and ArrayValueOf wants a func(T) Value it can apply down a typed slice. The two names say what the emitter proved about the element, a plain fixed shape here and a registered class instance there; the walk underneath is one walk, which is what keeps a class named wherever it is reached.

func StructuredClone

func StructuredClone(v Value) Value

StructuredClone deep-copies a value the way the WHATWG global structuredClone does, for the subset bento's value model represents. A primitive is returned unchanged. A plain object or array is copied one own enumerable string key at a time, and shared or cyclic references are preserved: an object reached twice through the input graph is the same object twice in the clone, and a cycle clones to a cycle rather than looping forever. A value the structured-clone algorithm rejects, a function or a symbol, throws rather than returning a lossy copy, and so does a Proxy, whose traps bento cannot faithfully reproduce in a copy. The runtime never sees a Date, RegExp, Map, or Set here, since none of those box into a value object in the dynamic model; a program that reaches this path holds a primitive, a plain object, an array, a function, or a proxy.

func Sub

func Sub(a, b Value) Value

Sub implements the - operator over two dynamic values.

func SymbolAsyncIterator

func SymbolAsyncIterator() Value

func SymbolFor

func SymbolFor(key BStr) Value

SymbolFor returns the registered symbol for key, creating and interning one when the key is new, the value Symbol.for(key) produces. A registered symbol's description is its key, matching the specification, and every call with an equal key returns the same reference so Symbol.for("k") === Symbol.for("k").

func SymbolHasInstance

func SymbolHasInstance() Value

func SymbolIsConcatSpreadable

func SymbolIsConcatSpreadable() Value

func SymbolIterator

func SymbolIterator() Value

SymbolIterator and the accessors beside it return the one interned well-known symbol each names, the value Symbol.iterator and its siblings read. Every call returns the same reference, so a program comparing two reads of the same well-known symbol sees identity, and a symbol used as a property key lands in the same slot each time it is read.

func SymbolMatch

func SymbolMatch() Value

func SymbolMatchAll

func SymbolMatchAll() Value

func SymbolReplace

func SymbolReplace() Value

func SymbolSearch

func SymbolSearch() Value

func SymbolSpecies

func SymbolSpecies() Value

func SymbolSplit

func SymbolSplit() Value

func SymbolToPrimitive

func SymbolToPrimitive() Value

func SymbolToStringTag

func SymbolToStringTag() Value

func SymbolUnscopables

func SymbolUnscopables() Value

func TemplateObject

func TemplateObject(cooked, raw []Value) Value

TemplateObject builds the template strings object a tagged template passes as its first argument: an array of the template's cooked literal parts carrying a raw property that holds the same parts undecoded. Both arrays are frozen and so is the object, which is what the language specifies, so a tag that writes to either drops the write rather than change what the next call sees.

The identity of this object belongs to the call site rather than to the call: the spec keys its template registry on the parse node, so every evaluation of one tagged template hands the tag the same object, and two sites that spell the same text hand out two different ones. The compiler gets that for free by emitting one package-level var per site and initializing it here at init.

func TupleToValue

func TupleToValue[T any](t T) Value

TupleToValue boxes a tuple into the array value a tuple is in JavaScript, the box the lowering emits wherever a tuple crosses into a dynamic slot: console.log of one, String of one, an element of an array being boxed. It is generic so it can be passed as the func(T) Value that ArrayValueOf applies down a slice, and it defers to the same walk every other boxing goes through, so a position holding a date, a class instance, or another tuple boxes the way it would anywhere else.

func UnsignedShiftRight

func UnsignedShiftRight(a, b Value) Value

UnsignedShiftRight implements the >>> operator over two dynamic values. There is no bigint arm: >>> reads the operand as an unsigned integer of a fixed width, and a bigint has no width, so the language throws rather than pick one.

func WithName

func WithName(f Value, name string) Value

WithName records name as a function value's own name property and returns the value, the effect named evaluation has when an anonymous function is assigned to an identifier: value = function() {} binds the function's name to "value". The name rides the function's own "name" property, so a later read of f.name returns it the way Function.prototype.name does. A non-function value is returned untouched, since only a function carries a name.

func (Value) AsBool

func (v Value) AsBool() bool

AsBool returns the bool a boolean box holds.

func (Value) AsNumber

func (v Value) AsNumber() float64

AsNumber returns the double a number box holds, decoding the raw bits. It is only valid on a KindNumber value; the caller checks the kind first, or reaches for ToNumber when the kind is not known.

func (Value) AsString

func (v Value) AsString() BStr

AsString returns the BStr a string box holds. Like AsNumber it is only valid on a KindString value: lowered code calls it where the checker proved the kind, past a typeof guard, and reaches for ToString when the kind is open.

func (Value) Assign

func (v Value) Assign(sources ...Value) Value

Assign copies the own enumerable properties of each source onto the receiver, the target, through the ordinary get and set path, the runtime behind Object.assign(target, ...sources). A source's string keys copy in the spec's enumeration order, integer indices ascending then the remaining keys in insertion order, followed by its own enumerable symbol keys in insertion order. A null or undefined source contributes nothing, matching the spec's skip, and a string source contributes its index characters, the own enumerable properties its wrapper exposes. Each property lands through the target's Set, so the target's own writability and extensibility govern whether it takes. The target is returned so the call reads as the assignment expression Object.assign evaluates to.

func (Value) Call

func (v Value) Call(args ...Value) Value

Call invokes a callable function value with the given boxed arguments, the lowering of fn(args) when the callee's type is dynamic so its shape is known only at runtime. A callable runs its boxed body; any other value throws a TypeError the way JavaScript does when a call target turns out not to be a function.

func (Value) DefineProperties

func (v Value) DefineProperties(props Value) Value

DefineProperties applies a map of descriptor objects to the receiver and returns it, the runtime behind Object.defineProperties(o, props). It walks props's own enumerable properties, string keys in enumeration order then symbol keys in insertion order, and defines each onto the receiver through the same path Object.defineProperty takes, so the batched form and the single form share one definition. A non-object receiver or a nullish props throws a TypeError the way the spec rejects them.

func (Value) DefineProperty

func (v Value) DefineProperty(key, descObj Value) Value

DefineProperty applies a descriptor object to a key on the receiver and returns the receiver, the runtime behind Object.defineProperty(o, key, desc). A symbol key defines onto the symbol bag; any other key takes its property-key string and defines onto the named bag. The define is validated against the object's extensibility and the existing property's configurability first, and a change the spec forbids throws a TypeError rather than mutating the bag. A non-object receiver throws a TypeError the way the spec rejects a primitive target.

func (Value) Delete

func (v Value) Delete(key BStr) bool

Delete removes v[key] by the receiver's kind, the runtime behind the delete operator, and reports the boolean delete yields. An array clears a numeric key to a hole rather than shifting the later elements, the way delete a[i] leaves a gap without changing length, and a non-numeric key falls to the named property map an array can still carry. An object and a function drop the own key through deleteOwn. A primitive receiver has no own property this path stores, so there is nothing to remove and the result is true, the value delete gives for a property that is absent. A non-configurable property, whether from a descriptor or from Object.seal, refuses removal and reports false, the value delete gives when the property survives.

func (Value) DeleteElem

func (v Value) DeleteElem(key Value) bool

DeleteElem removes v[key] for a dynamic index whose own type is not known to be a number, the mirror of GetElem. The key is coerced to a property key the way JavaScript does, a string used as is and any other value taken through ToString, then the removal dispatches through the same kind-aware Delete, so a numeric string key round-trips to the same array element DeleteIndex would.

func (Value) DeleteElemStrict

func (v Value) DeleteElemStrict(key Value) bool

DeleteElemStrict is the strict-mode form of DeleteElem: a symbol key refused by a non-configurable property throws, and every other key routes through DeleteStrict so a refused string or coerced key throws too. A successful removal returns true unchanged, so an ordinary strict delete matches the sloppy one.

func (Value) DeleteIndex

func (v Value) DeleteIndex(i float64) bool

DeleteIndex removes v[i] for a numeric index, the delete a[i] takes when the receiver is a dynamic value and the index is a number. It mirrors GetIndex: the index becomes a property key its canonical string, then the removal dispatches by the receiver's kind through Delete, so an array element clears to a hole and an object numeric property drops from the map the way delete a[3] does.

func (Value) DeleteIndexStrict

func (v Value) DeleteIndexStrict(i float64) bool

DeleteIndexStrict is the strict-mode form of DeleteIndex: a refused element removal (a sealed array slot or a non-configurable numeric property) throws rather than reporting false, routed through DeleteStrict like the named path.

func (Value) DeleteStrict

func (v Value) DeleteStrict(key BStr) bool

DeleteStrict is the strict-mode form of Delete. A delete in a strict function whose removal is refused is a TypeError rather than a false result: where Delete reports false for a non-configurable property or a sealed array element, DeleteStrict throws. A nullish receiver already throws through Delete, and every removal that succeeds returns true unchanged, so an ordinary strict delete is identical to the sloppy one. The lowerer emits this in place of Delete for a member delete when the program is strict, so only a genuinely refused removal turns into a throw; a configurable delete cannot regress.

func (Value) Entries

func (v Value) Entries() Value

Entries returns the receiver's own enumerable string-keyed properties as a boxed array of [key, value] pairs in the spec's enumeration order, the value Object.entries builds for a dynamic receiver. Each pair is a two-element array whose first element is the key string and whose second is the value the same read Object.values makes resolves. The result is a boxed value rather than a typed array because its elements are themselves arrays, so a member read off a pair, entries[i][0], dispatches through the dynamic Get the way the source's own reads do. A receiver with no object storage yields an empty array.

func (Value) ForInKeys

func (v Value) ForInKeys() *Array[BStr]

ForInKeys returns the property names a for...in loop visits over the receiver: its own enumerable string keys followed by those it inherits, walking the prototype chain and yielding each name once. A key seen at a lower level shadows the same name higher up whether or not it was enumerable there, so a non-enumerable own property hides an inherited enumerable one and the name does not appear. Symbol keys are never visited, which matches the string-side model, and a receiver with no object storage (a primitive) yields an empty array. The user prototype chain is the one o.proto threads, so built-in prototypes and their non-enumerable methods never enter the enumeration.

func (Value) Freeze

func (v Value) Freeze() Value

Freeze seals the object and additionally marks every own data property non-writable, so no property can be added, removed, redefined, or reassigned, the runtime behind Object.freeze(o). An accessor property has no value to lock, so its getter and setter are left in place; only its configurability is cleared, by the seal. An array's elements are marked non-writable through the elemsFrozen flag, so an element write drops. A non-object receiver has nothing to freeze and is returned unchanged.

func (Value) Get

func (v Value) Get(key BStr) Value

Get implements a dynamic property read, o[key], for the kinds the AOT path produces. A string reports its length and indexes to a one-character string; an array reports its length and indexes into its elements; an object looks the key up in its property map. A read that finds nothing is undefined, the JavaScript result for a missing property, so the caller never faults. The other kinds have no own properties the dynamic path reads yet and return undefined too.

func (Value) GetElem

func (v Value) GetElem(key Value) Value

GetElem reads v[key] for a dynamic index whose own type is not known to be a number, the bracket read a[k] takes when both the receiver and the key are dynamic values. The key is coerced to a property key the way JavaScript does, a string used as is and any other value taken through ToString, then the read dispatches through Get. A number key round-trips to its canonical string, so a dynamic index reads the same element GetIndex would.

func (Value) GetIndex

func (v Value) GetIndex(i float64) Value

GetIndex reads v[i] for a numeric index, the bracket read a[i] takes when the receiver is a dynamic value and the index is a number. The index becomes a property key its canonical string the way JavaScript's a[3] reads the "3" property, then the read dispatches by the receiver's kind through Get, so an array element, a string code unit, and an object numeric property all resolve the same way a static read would.

func (Value) GetOwnPropertyDescriptor

func (v Value) GetOwnPropertyDescriptor(key Value) Value

GetOwnPropertyDescriptor returns the descriptor object for an own property of the receiver, or undefined when the property is absent, the runtime behind Object.getOwnPropertyDescriptor(o, key). A symbol key reads the symbol bag; any other key takes its property-key string. An array answers for its length as a non-enumerable, non-configurable writable data property and for each in-range element index as a fully writable, enumerable, configurable data property, since those live outside the named bag. A non-object receiver reports undefined for every key, the value the spec gives once it coerces the target to an object with no own properties of interest.

func (Value) GetOwnPropertyDescriptors

func (v Value) GetOwnPropertyDescriptors() Value

GetOwnPropertyDescriptors returns an object mapping every own property key of the receiver to its descriptor object, the runtime behind Object.getOwnPropertyDescriptors(o). It walks the own string keys in the spec's enumeration order, including the non-enumerable ones, then the symbol keys in insertion order, and stores each key's descriptor object under the same key on a fresh object, so the result carries a string entry for every string key and a symbol entry for every symbol key. An array contributes its element indices and its length. A non-object receiver yields an empty object, the descriptors of nothing.

func (Value) GetPrototype

func (v Value) GetPrototype() Value

GetPrototype returns the receiver's [[Prototype]] as a value, the runtime behind Object.getPrototypeOf(o). A slot holding an object reports that object; a slot left nil, whether never set or set to null through Object.create(null), reports null. A non-object receiver has no slot this model tracks, so it reports null too.

func (Value) HasOwnElem

func (v Value) HasOwnElem(key Value) bool

HasOwnElem reports whether the receiver carries key as an own property, the value Object.hasOwn returns for a dynamic receiver. A symbol key is looked up by identity in the symbol bag; any other key is taken to its property-key string, so o.hasOwn(s) and o.hasOwn("k") each probe the slot the matching read would reach. An array answers for its length and its in-range element indices as well as any named property, and a receiver with no object storage has nothing to own.

func (Value) HasProperty

func (v Value) HasProperty(key BStr) bool

HasProperty implements the in operator, key in v: whether v carries the named property, own or built in, for the kinds the AOT path produces. A string has a length and its in-range character indices; an array has a length and its in-range element indices as well as any own named property; an object or a function probes its own keys. JavaScript throws a TypeError when the right operand of in is not an object, so a primitive receiver raises rather than answering false.

func (Value) IndexRest

func (v Value) IndexRest(from float64) Value

IndexRest gathers the receiver's elements from index from to the end into a fresh boxed array, the tail an array destructuring rest binds: `const [a, ...rest] = xs` fills rest with everything past the fixed slots. It reads the length through the dynamic length property coerced the way ToLength does, a NaN or negative length yielding a zero count, and reads each position through the dynamic index, so a boxed array yields its dense tail and an array-like yields its indexed tail. A from at or past the end yields an empty array, matching JavaScript's rest of a short source. The result is boxed because the source is dynamic and the rest target is typed any[].

func (Value) IsExtensible

func (v Value) IsExtensible() bool

IsExtensible reports whether new properties may still be added to the receiver, the runtime behind Object.isExtensible(o). A non-object is never extensible, the answer the spec gives for a primitive, which has no properties to add.

func (Value) IsFrozen

func (v Value) IsFrozen() bool

IsFrozen reports whether the receiver is frozen, the runtime behind Object.isFrozen(o). A non-object is treated as frozen, the answer the spec gives for a primitive, which has no property to write.

func (Value) IsNull

func (v Value) IsNull() bool

func (Value) IsNullish

func (v Value) IsNullish() bool

func (Value) IsSealed

func (v Value) IsSealed() bool

IsSealed reports whether the receiver is sealed, the runtime behind Object.isSealed(o). A non-object is treated as sealed, the answer the spec gives for a primitive, which has no property to configure.

func (Value) IsUndefined

func (v Value) IsUndefined() bool

IsUndefined and the other predicates ask the tag directly, the cheap check the dynamic path makes before it commits to a kind-specific operation.

func (Value) Kind

func (v Value) Kind() Kind

Kind reports the value's runtime tag.

func (Value) ObjectRest

func (v Value) ObjectRest(omit ...BStr) Value

ObjectRest returns a new plain object holding the receiver's own enumerable properties except those named in omit, the value an object rest element binds: { a, ...rest } gathers every own property but a. The properties copy in the spec's own-property order, integer indices ascending then the remaining string keys in insertion order, so the rest object enumerates the way the source does. A receiver with no object storage yields an empty object, the rest of nothing.

func (Value) OwnEnumerableKeys

func (v Value) OwnEnumerableKeys() *Array[BStr]

OwnEnumerableKeys returns the receiver's own enumerable string-keyed property names in the spec's enumeration order, the value Object.keys builds for a dynamic receiver. It differs from OwnKeys only in that a property defined non-enumerable through Object.defineProperty is left out. A receiver with no object storage yields an empty array.

func (Value) OwnKeys

func (v Value) OwnKeys() *Array[BStr]

OwnKeys returns the receiver's own string-keyed property names as a string array in the spec's enumeration order, including the non-enumerable ones, the value Object.getOwnPropertyNames builds for a dynamic receiver whose keys are known only at runtime. Symbol keys never appear, which matches the string-side static. A receiver with no object storage yields an empty array.

func (Value) OwnSymbols

func (v Value) OwnSymbols() *Array[Value]

OwnSymbols returns the receiver's own symbol-keyed property keys as a value array in insertion order, the value Object.getOwnPropertySymbols builds for a dynamic receiver. Both enumerable and non-enumerable symbol keys appear, since the spec does not filter symbols by enumerability the way the string-keyed statics filter named keys. A receiver with no object storage yields an empty array.

func (Value) OwnValues

func (v Value) OwnValues() *Array[Value]

OwnValues returns the receiver's own enumerable property values as a value array in the same order OwnEnumerableKeys walks the names, the value Object.values builds for a dynamic receiver. A non-enumerable property contributes no value, matching Object.keys. A receiver with no object storage yields an empty array.

func (Value) PreventExtensions

func (v Value) PreventExtensions() Value

PreventExtensions clears the receiver's extensible flag so no new property can be added, the runtime behind Object.preventExtensions(o). The object's existing properties are untouched; only the addition of a new key is blocked, which the Set and element-write paths honor. A non-object receiver has no flag to clear and is returned unchanged, the no-op Object.preventExtensions performs on a primitive.

func (Value) ProtoRead

func (v Value) ProtoRead() Value

ProtoRead is the read of the legacy `obj.__proto__` member. The name __proto__ is an accessor inherited from Object.prototype, so an own property of that name shadows it: JSON.parse and CreateDataProperty install an own "__proto__" data property that a later obj.__proto__ read must return in place of the prototype (see JSON/parse/duplicate-proto). Only when the receiver carries no own __proto__ does the read fall through to the accessor's [[Prototype]] result.

func (Value) Seal

func (v Value) Seal() Value

Seal prevents extensions and marks every own property non-configurable, so no property can be added, removed, or redefined, the runtime behind Object.seal(o). A sealed property keeps its value and writability, so a data property can still be assigned; only its configurability is cleared. An array's elements are marked non-configurable through the elemsSealed flag, since they carry no per-element descriptor. A non-object receiver has nothing to seal and is returned unchanged.

func (Value) Set

func (v Value) Set(key BStr, val Value) Value

func (Value) SetElem

func (v Value) SetElem(key, val Value) Value

SetElem writes v[key] = val for a dynamic index whose own type is not known to be a number, the mirror of GetElem. The key is coerced to a property key the way JavaScript does, a string used as is and any other value taken through ToString, then the write dispatches through the same kind-aware path SetIndex uses, so a numeric string key round-trips to the same array element GetIndex would read.

func (Value) SetElemStrict

func (v Value) SetElemStrict(key, val Value) Value

SetElemStrict is the strict-mode form of SetElem, the dynamic bracket write o[key] = val the lowerer emits in place of SetElem under a "use strict" program. A symbol key routes through the throwing symbol store, a string key through the throwing named store, and any other key is coerced to a property key the same way before the throwing named store, so a strict computed write drops nothing silently the way its sloppy counterpart would.

func (Value) SetIndex

func (v Value) SetIndex(i float64, val Value) Value

SetIndex writes v[i] = val for a numeric index, the bracket write a[i] = val takes when the receiver is a dynamic value and the index is a number. It mirrors GetIndex: the index becomes a property key its canonical string, then the write dispatches by the receiver's kind, so an array element lands in dense storage and an object numeric property lands in the property map the way a[3] = x does. It returns the assigned value so the write reads the same as JavaScript's assignment expression, which evaluates to its right-hand side.

func (Value) SetIndexStrict

func (v Value) SetIndexStrict(i float64, val Value) Value

SetIndexStrict is the strict-mode form of SetIndex, the numeric bracket write a[i] = val the lowerer emits under a "use strict" program. It routes through the throwing string store so a write blocked by a frozen or non-extensible receiver raises the TypeError a strict element assignment raises instead of dropping.

func (Value) SetKey

func (v Value) SetKey(key BStr, val Value) Value

SetKey writes v[key] = val by the receiver's kind, the store mirror of the kind-aware Get read. An array claims a numeric key into its dense element storage, growing the slice with undefined holes so a[5] = x on a shorter array leaves the gap the way JavaScript does, and a non-numeric key lands in the named property map an array can still carry. An object and a function store the key as a named property through Set. It returns val so a bracket write can sit in an expression, the way JavaScript's assignment evaluates to its right-hand side. A kind with no writable storage drops the write and returns val, the value the language still hands back.

func (Value) SetKeyStrict

func (v Value) SetKeyStrict(key BStr, val Value) Value

SetKeyStrict is the strict-mode form of SetKey, the string-keyed bracket write o[k] = val the lowerer emits under a "use strict" program. An array's numeric key still lands in dense storage, but a write blocked by a frozen or non-extensible array now throws the TypeError a strict element assignment raises instead of dropping, and an object or function key routes through the throwing SetStrict, so a strict computed string write fails the same way its named counterpart does.

func (Value) SetKeyed

func (v Value) SetKeyed(key, val Value) Value

SetKeyed writes a property whose key is a boxed value, resolving it to a symbol, string, or numeric-string property the way SetElem does, and returns the receiver so a boxed object literal can chain a computed member `{ [k]: v }` in one expression the way Set chains a named one. It differs from SetElem, whose assignment semantics return the assigned value, because literal construction needs the object back to keep building.

func (Value) SetProtoAssign

func (v Value) SetProtoAssign(proto Value) Value

SetProtoAssign applies the legacy __proto__ assignment, the runtime shared by the object literal __proto__: member and the o.__proto__ = v accessor. An object or null becomes the prototype through the same slot write Object.setPrototypeOf takes, so a non-extensible object still rejects a real change with a TypeError; any other value is ignored without error, the way both __proto__ forms leave a primitive prototype alone rather than storing an own property of that name. It returns the receiver so the object-literal builder keeps chaining Set calls.

func (Value) SetPrototype

func (v Value) SetPrototype(proto Value) Value

SetPrototype writes the receiver's [[Prototype]] slot and returns the receiver, the runtime behind Object.setPrototypeOf(o, proto). An object becomes the new prototype and null clears the slot; a prototype that is neither an object nor null throws a TypeError the way the spec rejects it. Changing the prototype of a non-extensible object to a different one throws a TypeError, while setting it to the value it already holds is allowed and leaves the object untouched. A non-object receiver has no slot to write, so it is returned unchanged.

func (Value) SetStrict

func (v Value) SetStrict(key BStr, val Value) Value

SetStrict is the strict-mode form of Set. Where Set silently drops a write that a sloppy assignment also drops, SetStrict throws the TypeError a strict assignment raises: a write to a non-writable data property, a write through an accessor with no setter, and a new key on a non-extensible object each throw, with V8's exact message so a catch reads the text Node reports. Every write that would succeed behaves identically to Set, so a strict program's ordinary property writes are unchanged. The lowerer emits this in place of Set for a member store under a "use strict" program.

func (Value) SymbolDescription

func (v Value) SymbolDescription() Value

SymbolDescription returns the symbol's description as a string value, or undefined when it was created without one, the read Symbol.prototype.description makes. It is only valid on a KindSymbol value.

func (Value) SymbolDescriptiveString

func (v Value) SymbolDescriptiveString() BStr

SymbolDescriptiveString renders a symbol as "Symbol(desc)", the SymbolDescriptiveString abstract operation Symbol.prototype.toString returns. A symbol with no description reads as "Symbol()", since a missing description contributes the empty string between the parentheses. It is only valid on a KindSymbol value.

func (Value) ToStringMethod

func (v Value) ToStringMethod() Value

ToStringMethod implements a dynamic x.toString() call, the method each prototype installs rather than the abstract ToString the operators use. A number spells its digits, a boolean spells true or false, a string is itself, a bigint spells its digits, an array joins its elements, and any other object reports the "[object Object]" tag. undefined and null carry no prototype, so reading toString off them throws a TypeError the way JavaScript does. The result is boxed because the receiver is dynamic and the call site is typed any.

func (Value) TypeOf

func (v Value) TypeOf() BStr

TypeOf returns the JavaScript typeof string for the boxed value, the lowering of typeof x when the operand is dynamic and its kind is only known at runtime. The mapping is the language's, not Go's: null reports "object" (the historical wart), an array is an "object" like any other, and only a callable is "function". A static operand never reaches here; the lowerer folds typeof to a string constant when the checker already knows the kind, and emits this call only when the operand is any or unknown.

func (Value) ValueOfMethod

func (v Value) ValueOfMethod() Value

ValueOfMethod implements a dynamic x.valueOf() call, the method each prototype installs. Object.prototype.valueOf returns the receiver itself, and the primitive wrappers return the primitive they box, so for every kind that carries a prototype the answer is the receiver value unchanged: a number, string, boolean, bigint, or symbol is its own primitive value, and an object, array, or function is returned by identity. undefined and null carry no prototype, so reading valueOf off them throws a TypeError the way JavaScript does. The result is boxed because the receiver is dynamic and the call site is typed any.

A boxed class instance is the one object that does not answer by identity: a class writing its own valueOf shadows Object.prototype's, so the call runs the class's code and answers the primitive it returns. An own field of that name shadows the method again, the way it does on a live instance, so the read is checked first.

type WeakMap

type WeakMap[T any, V any] struct {
	// contains filtered or unexported fields
}

WeakMap is bento's runtime representation of a JavaScript WeakMap<*T, V>. It holds its entries as parallel weak-key and value slices: a key is a weak.Pointer[T] that does not keep the object alive, and the value rides alongside it. There is no insertion order to preserve because a WeakMap exposes no iteration, so the slices are only a store the linear scan searches, the same first-cut shape Map takes.

func NewWeakMap

func NewWeakMap[T any, V any]() *WeakMap[T, V]

NewWeakMap builds an empty WeakMap keyed by *T, the lowering of new WeakMap<K, V>() for an object key type K whose render is *T. There is no key-kind switch the way a Map has, because a WeakMap key is always an object compared by reference identity, which Go's == on the strong pointer gives once the weak pointer is resolved.

func (*WeakMap[T, V]) Delete

func (m *WeakMap[T, V]) Delete(k *T) bool

Delete removes the entry for k and reports whether it was present, the lowering of weakMap.delete(k).

func (*WeakMap[T, V]) Get

func (m *WeakMap[T, V]) Get(k *T) Opt[V]

Get returns the value for k as an optional, undefined when the key is absent or has been collected, the lowering of weakMap.get(k) whose declared type is V | undefined.

func (*WeakMap[T, V]) Has

func (m *WeakMap[T, V]) Has(k *T) bool

Has reports whether the map holds a live entry for k, the lowering of weakMap.has(k).

func (*WeakMap[T, V]) Set

func (m *WeakMap[T, V]) Set(k *T, v V) *WeakMap[T, V]

Set inserts or updates the entry for k and returns the map, the lowering of weakMap.set(k, v). A new key appends; an existing key takes the new value. The key is wrapped weakly so the map does not extend its lifetime, and the map itself is the result so a chained set lowers with no temporary.

func (*WeakMap[T, V]) ToValue

func (m *WeakMap[T, V]) ToValue() Value

ToValue boxes a typed WeakMap into a dynamic value, building the box once and keeping it on the map so two crossings of one map hand back one object.

type WeakRef

type WeakRef[T any] struct {
	// contains filtered or unexported fields
}

WeakRef is bento's runtime representation of a JavaScript WeakRef<*T>. It holds a single weak.Pointer[T] to the target, which does not extend the target's lifetime.

func NewWeakRef

func NewWeakRef[T any](target *T) *WeakRef[T]

NewWeakRef builds a WeakRef to target, the lowering of new WeakRef(target). The target is wrapped weakly, so the reference alone does not keep it alive.

func (*WeakRef[T]) Deref

func (w *WeakRef[T]) Deref() Opt[*T]

Deref returns the target as an optional, the object while it lives and undefined once it has been collected, the lowering of weakRef.deref() whose declared type is T | undefined.

func (*WeakRef[T]) ToValue

func (w *WeakRef[T]) ToValue() Value

ToValue boxes a WeakRef into a dynamic value. A WeakRef holds no items, so its box is not opaque and prints as empty braces, which is what Node prints for one.

type WeakSet

type WeakSet[T any] struct {
	// contains filtered or unexported fields
}

WeakSet is bento's runtime representation of a JavaScript WeakSet<*T>. It holds its members as a slice of weak.Pointer[T] that do not keep the objects alive. There is no order to preserve because a WeakSet exposes no iteration, so the slice is only a store the linear scan searches, the same first-cut shape Set takes.

func NewWeakSet

func NewWeakSet[T any]() *WeakSet[T]

NewWeakSet builds an empty WeakSet over *T, the lowering of new WeakSet<E>() for an object member type E whose render is *T. There is no member-kind switch the way a Set has, because a WeakSet member is always an object compared by reference identity, which Go's == on the strong pointer gives once the weak pointer resolves.

func (*WeakSet[T]) Add

func (s *WeakSet[T]) Add(k *T) *WeakSet[T]

Add inserts k if absent and returns the set, the lowering of weakSet.add(k). The member is wrapped weakly so the set does not extend its lifetime, and the set itself is the result so a chained add lowers with no temporary.

func (*WeakSet[T]) Delete

func (s *WeakSet[T]) Delete(k *T) bool

Delete removes k and reports whether it was present, the lowering of weakSet.delete(k).

func (*WeakSet[T]) Has

func (s *WeakSet[T]) Has(k *T) bool

Has reports whether the set holds a live member equal to k, the lowering of weakSet.has(k).

func (*WeakSet[T]) ToValue

func (s *WeakSet[T]) ToValue() Value

ToValue boxes a typed WeakSet into a dynamic value, the WeakMap case with a member rather than a pair.

type ZonedDateTime

type ZonedDateTime struct {
	// contains filtered or unexported fields
}

ZonedDateTime is bento's runtime representation of a Temporal.ZonedDateTime (Temporal §7): an exact point on the time line, the same nanosecond count an Instant holds, paired with a time zone that gives the count a wall-clock reading and a calendar. Like the plain types this slice hosts only the ISO 8601 calendar; a non-ISO calendar hands back at lowering, so calendarId always reports iso8601.

The three fields are the epoch-nanosecond count, the resolved standard-library location the offset lookup runs against, and the canonical time-zone identifier the getters and toString report. The wall-clock getters do not cache a second copy of the date and time: each derives the local reading by adding the zone's offset at this instant to the count and splitting the result, so a getter always reflects the offset in force at its own instant, which is what makes a reading across a daylight-saving transition come out right.

func NewZonedDateTime

func NewZonedDateTime(epochNanoseconds *big.Int, timeZone BStr) *ZonedDateTime

NewZonedDateTime builds a ZonedDateTime from the constructor's bigint epoch count and time-zone identifier, running IsValidEpochNanoseconds and then ToTemporalTimeZoneIdentifier the way new Temporal.ZonedDateTime(ns, tz) does. The optional calendar argument is not accepted here; a non-ISO calendar hands back at lowering.

func NowZonedDateTimeISO

func NowZonedDateTimeISO() *ZonedDateTime

NowZonedDateTimeISO implements Temporal.Now.zonedDateTimeISO, the current instant paired with a zone under the ISO calendar. With no argument the zone is the host default; an explicit identifier names another zone, which resolveTimeZone validates.

func NowZonedDateTimeISOIn

func NowZonedDateTimeISOIn(timeZone BStr) *ZonedDateTime

NowZonedDateTimeISOIn is Temporal.Now.zonedDateTimeISO(timeZone), the current instant in the named zone.

func ZonedDateTimeFrom

func ZonedDateTimeFrom(z *ZonedDateTime) *ZonedDateTime

ZonedDateTimeFrom implements Temporal.ZonedDateTime.from for a ZonedDateTime argument: it returns a fresh ZonedDateTime with the same count, zone, and calendar, the copy the specification makes. from over a string or a property bag needs the parser and the option handling and hands back at lowering, so this body is only reached with a ZonedDateTime.

func ZonedDateTimeFromFields

func ZonedDateTimeFromFields(year, month, day float64, hour, minute, second, millisecond, microsecond, nanosecond Opt[float64], timeZone string, offset Opt[string], overflow, disambiguation, offsetOption string) *ZonedDateTime

ZonedDateTimeFromFields implements Temporal.ZonedDateTime.from over a property bag. The date and time fields build a wall-clock reading through PlainDateTimeFromFields under the overflow option, the timeZone field names the zone, and the reading folds to an exact instant one of two ways. A bag with no offset field resolves through the zone under the disambiguation option, exactly as a bare string does. A bag that carries an offset field weighs it under the offset option: use takes the offset at face value and reads the instant as the wall clock less that offset; ignore drops the offset and resolves through disambiguation; prefer keeps a zone instant whose offset matches and otherwise falls to disambiguation; reject demands a zone instant whose offset matches and throws when none does. bento's ZonedDateTime hosts only the ISO calendar, so the lowerer hands back a bag naming another before this is reached.

func ZonedDateTimeFromString

func ZonedDateTimeFromString(s string) *ZonedDateTime

ZonedDateTimeFromString implements Temporal.ZonedDateTime.from over a string. The string must carry a time-zone annotation in brackets, the identifier the wall-clock reading is resolved against; a string with none throws a RangeError the way the specification does, since a zoned date-time has no zone without it. The wall-clock date and time are read through the shared parser, then folded to an exact instant one of three ways: a Z designator names the instant exactly, so the wall clock is read as UTC; a bare string with no offset resolves through the zone with the default compatible disambiguation, which takes the earlier reading in a fall-back overlap and shifts forward across a spring-forward gap; a string with a numeric offset must match one of the zone's offsets for that wall clock under the default reject option, and a mismatch throws. bento's ZonedDateTime hosts only the ISO calendar, so a non-ISO calendar annotation throws, and the lowerer hands back any literal naming one before this is reached.

func (*ZonedDateTime) AddDuration

func (z *ZonedDateTime) AddDuration(dur *Duration, overflow string) *ZonedDateTime

AddDuration implements Temporal.ZonedDateTime.prototype.add and, over a negated Duration, subtract. Following the specification's AddZonedDateTime, the calendar part and the exact-time part move separately. When the duration carries no years, months, weeks, or days the addition is pure exact time: the time fields fold to nanoseconds and add straight onto the count, so an hour added stays an hour on the time line even across a daylight-saving change. Otherwise the calendar part first adds to the wall-clock reading in the calendar under the overflow rule, the moved wall clock re-resolves to an instant through the zone under the default compatible disambiguation, and the exact-time part then folds onto that instant as plain nanoseconds. That order is what makes a day added across a transition land on the same wall-clock time a day later while the offset it reports updates. The zone and calendar carry through and the result is range-checked.

func (*ZonedDateTime) CalendarId

func (z *ZonedDateTime) CalendarId() BStr

CalendarId reports the calendar the wall-clock fields read under, iso8601 by default.

func (*ZonedDateTime) Day

func (z *ZonedDateTime) Day() float64

func (*ZonedDateTime) DayOfWeek

func (z *ZonedDateTime) DayOfWeek() float64

func (*ZonedDateTime) DayOfYear

func (z *ZonedDateTime) DayOfYear() float64

func (*ZonedDateTime) DaysInMonth

func (z *ZonedDateTime) DaysInMonth() float64

func (*ZonedDateTime) DaysInWeek

func (z *ZonedDateTime) DaysInWeek() float64

func (*ZonedDateTime) DaysInYear

func (z *ZonedDateTime) DaysInYear() float64

func (*ZonedDateTime) EpochMilliseconds

func (z *ZonedDateTime) EpochMilliseconds() float64

EpochMilliseconds returns the count floored to whole milliseconds, the same Euclidean division Instant uses.

func (*ZonedDateTime) EpochNanoseconds

func (z *ZonedDateTime) EpochNanoseconds() *big.Int

EpochNanoseconds returns a fresh copy of the count, so a caller holds a bigint independent of the ZonedDateTime's field.

func (*ZonedDateTime) Equals

func (z *ZonedDateTime) Equals(other *ZonedDateTime) bool

Equals implements Temporal.ZonedDateTime.prototype.equals for a ZonedDateTime argument: two zoned date-times are equal when they name the same instant in the same zone under the same calendar, so the check is the count, the canonical zone identifier, and the calendar.

func (*ZonedDateTime) Era

func (z *ZonedDateTime) Era() Opt[BStr]

func (*ZonedDateTime) EraYear

func (z *ZonedDateTime) EraYear() Opt[float64]

func (*ZonedDateTime) Hour

func (z *ZonedDateTime) Hour() float64

func (*ZonedDateTime) HoursInDay

func (z *ZonedDateTime) HoursInDay() float64

HoursInDay implements Temporal.ZonedDateTime.prototype.hoursInDay. It reads the length of the receiver's local calendar day as the exact hours between this day's start and the next day's start, so an ordinary day is twenty-four, a spring-forward day twenty-three, and a fall-back day twenty-five. The gap divides in floating point so a zone whose transition is off the hour keeps its fractional part.

func (*ZonedDateTime) InLeapYear

func (z *ZonedDateTime) InLeapYear() bool

func (*ZonedDateTime) Microsecond

func (z *ZonedDateTime) Microsecond() float64

func (*ZonedDateTime) Millisecond

func (z *ZonedDateTime) Millisecond() float64

func (*ZonedDateTime) Minute

func (z *ZonedDateTime) Minute() float64

func (*ZonedDateTime) Month

func (z *ZonedDateTime) Month() float64

func (*ZonedDateTime) MonthCode

func (z *ZonedDateTime) MonthCode() BStr

func (*ZonedDateTime) MonthsInYear

func (z *ZonedDateTime) MonthsInYear() float64

func (*ZonedDateTime) Nanosecond

func (z *ZonedDateTime) Nanosecond() float64

func (*ZonedDateTime) Offset

func (z *ZonedDateTime) Offset() BStr

Offset reports the zone's UTC offset at this instant in the ±HH:MM[:SS] spelling.

func (*ZonedDateTime) OffsetNanoseconds

func (z *ZonedDateTime) OffsetNanoseconds() float64

OffsetNanoseconds reports the zone's UTC offset at this instant in nanoseconds. The offset stays within ±14 hours, so the nanosecond product is exact in a float64.

func (*ZonedDateTime) Round

func (z *ZonedDateTime) Round(smallestUnit string, increment float64, roundingMode string) *ZonedDateTime

Round implements Temporal.ZonedDateTime.prototype.round. A day smallestUnit rounds the instant within the zoned day, whose length the daylight-saving transitions stretch or shrink: the day progress from the day's start is rounded to the whole day length, twenty-three or twenty-five hours on a transition day rather than a flat twenty-four, and lands on this midnight or the next. A time smallestUnit rounds the wall clock the way a PlainDateTime does, carrying past midnight when it must, and the rounded wall clock re-resolves to an instant preferring the original offset, so a value rounded inside a fall-back overlap keeps the branch it was on. Only increment one is allowed for the day unit; a time increment must divide its next larger unit.

func (*ZonedDateTime) Second

func (z *ZonedDateTime) Second() float64

func (*ZonedDateTime) Since

func (z *ZonedDateTime) Since(other *ZonedDateTime, largestUnit string) *Duration

Since returns the negation of the receiver-to-other difference.

func (*ZonedDateTime) StartOfDay

func (z *ZonedDateTime) StartOfDay() *ZonedDateTime

StartOfDay implements Temporal.ZonedDateTime.prototype.startOfDay. It returns the first instant of the receiver's local calendar day in its zone, wall-clock midnight resolved through the compatible rule, so an ordinary day starts at 00:00 and a rare spring-forward at midnight lands just past the gap. The zone and calendar carry over unchanged.

func (*ZonedDateTime) TimeZoneId

func (z *ZonedDateTime) TimeZoneId() BStr

TimeZoneId reports the canonical time-zone identifier.

func (*ZonedDateTime) ToInstant

func (z *ZonedDateTime) ToInstant() *Instant

ToInstant implements Temporal.ZonedDateTime.prototype.toInstant: the exact time with the zone dropped, the same nanosecond count as an Instant.

func (*ZonedDateTime) ToJSON

func (z *ZonedDateTime) ToJSON() BStr

ToJSON implements Temporal.ZonedDateTime.prototype.toJSON, the same string toString produces under default options.

func (*ZonedDateTime) ToPlainDate

func (z *ZonedDateTime) ToPlainDate() *PlainDate

ToPlainDate implements Temporal.ZonedDateTime.prototype.toPlainDate: the calendar date of the wall-clock reading.

func (*ZonedDateTime) ToPlainDateTime

func (z *ZonedDateTime) ToPlainDateTime() *PlainDateTime

ToPlainDateTime implements Temporal.ZonedDateTime.prototype.toPlainDateTime: the wall-clock reading with the zone dropped.

func (*ZonedDateTime) ToPlainTime

func (z *ZonedDateTime) ToPlainTime() *PlainTime

ToPlainTime implements Temporal.ZonedDateTime.prototype.toPlainTime: the time of day of the wall-clock reading.

func (*ZonedDateTime) ToString

func (z *ZonedDateTime) ToString() BStr

ToString implements Temporal.ZonedDateTime.prototype.toString under the default options: the local ISO 8601 date-time, the UTC offset at this instant, the time-zone identifier in brackets, and, for a non-ISO calendar, the calendar annotation after it, the round-trippable form.

func (*ZonedDateTime) Until

func (z *ZonedDateTime) Until(other *ZonedDateTime, largestUnit string) *Duration

Until returns the difference from the receiver to other as a Duration balanced from largestUnit down. Since returns the difference from other to the receiver, the negation of Until, so the calendar anchoring stays on the receiver the way the specification requires.

func (*ZonedDateTime) WeekOfYear

func (z *ZonedDateTime) WeekOfYear() Opt[float64]

func (*ZonedDateTime) WithCalendar

func (z *ZonedDateTime) WithCalendar(calendar string) *ZonedDateTime

WithCalendar implements Temporal.ZonedDateTime.prototype.withCalendar: it keeps the instant and the zone and reinterprets the wall-clock fields under another calendar, returning a copy that reads its year, era, and eraYear through the new calendar. The id is canonicalized and validated, so an unhosted or invalid one throws a RangeError; the lowerer only routes a hosted one here.

func (*ZonedDateTime) WithFields

func (z *ZonedDateTime) WithFields(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond Opt[float64], overflow string) *ZonedDateTime

WithFields implements Temporal.ZonedDateTime.prototype.with. It overlays the bag's present date and time fields onto the wall-clock reading under the overflow rule, reusing the PlainDateTime field overlay, then re-resolves the reshaped wall clock to an instant preferring the original offset, the default offset option with is: a field changed inside a fall-back overlap keeps the branch the value was on, and a field that lands the wall clock in a spring-forward gap shifts forward under the compatible fallback. The zone and the calendar carry through.

func (*ZonedDateTime) WithPlainTime

func (z *ZonedDateTime) WithPlainTime(time *PlainTime) *ZonedDateTime

WithPlainTime implements Temporal.ZonedDateTime.prototype.withPlainTime. It keeps the wall-clock date, replaces the time of day, defaulting to midnight when none is given, and re-resolves through the compatible disambiguation rather than preferring the old offset, so a new time inside a fall-back overlap takes the earlier branch the way the specification's withPlainTime does.

func (*ZonedDateTime) WithTimeZone

func (z *ZonedDateTime) WithTimeZone(timeZone string) *ZonedDateTime

WithTimeZone implements Temporal.ZonedDateTime.prototype.withTimeZone. It keeps the exact instant and re-homes it in another zone, so the wall clock and the offset re-read there while the instant is unchanged. An unrecognized identifier throws a RangeError through the shared resolver.

func (*ZonedDateTime) Year

func (z *ZonedDateTime) Year() float64

func (*ZonedDateTime) YearOfWeek

func (z *ZonedDateTime) YearOfWeek() Opt[float64]

Source Files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL