quickjs-emscripten • quickjs-emscripten-core • Readme | Exports
quickjs-emscripten / quickjs-emscripten-core / QuickJSContext
QuickJSContext wraps a QuickJS Javascript context (JSContext*) within a runtime. The contexts within the same runtime may exchange objects freely. You can think of separate runtimes like different domains in a browser, and the contexts within a runtime like the different windows open to the same domain. The runtime references the context's runtime.
This class's methods return QuickJSHandle, which wrap C pointers (JSValue*).
It's the caller's responsibility to call .dispose()
on any
handles you create to free memory once you're done with the handle.
Use QuickJSRuntime#newContext or QuickJSWASMModule#newContext to create a new QuickJSContext.
Create QuickJS values inside the interpreter with methods like newNumber, newString, newArray, newObject, newFunction, and newPromise.
Call setProp or defineProp to customize objects. Use those methods with global to expose the values you create to the interior of the interpreter, so they can be used in evalCode.
Use evalCode or callFunction to execute Javascript inside the VM. If you're using asynchronous code inside the QuickJSContext, you may need to also call QuickJSRuntime#executePendingJobs. Executing code inside the runtime returns a result object representing successful execution or an error. You must dispose of any such results to avoid leaking memory inside the VM.
Implement memory and CPU constraints at the runtime level, using runtime. See QuickJSRuntime for more information.
- Extends
- Implements
- Constructors
- Properties
- Accessors
- Methods
[dispose]
()- callFunction()
- callMethod()
- decodeBinaryJSON()
- defineProp()
- dispose()
- dump()
- encodeBinaryJSON()
- eq()
- evalCode()
- fail()
- getArrayBuffer()
- getBigInt()
- getIterator()
- getLength()
- getNumber()
- getOwnPropertyNames()
- getPromiseState()
- getProp()
- getString()
- getSymbol()
- getWellKnownSymbol()
- newArray()
- newArrayBuffer()
- newBigInt()
- newError()
- newFunction()
- newNumber()
- newObject()
- newPromise()
- newString()
- newSymbolFor()
- newUniqueSymbol()
- resolvePromise()
- sameValue()
- sameValueZero()
- setProp()
- success()
- throw()
- typeof()
- unwrapResult()
new QuickJSContext(
args
):QuickJSContext
Use QuickJSRuntime#newContext or QuickJSWASMModule#newContext to create a new QuickJSContext.
• args: Object
• args.callbacks: QuickJSModuleCallbacks
• args.ctx: Lifetime
<JSContextPointer
, never
, never
>
• args.ffi: EitherFFI
• args.module: EitherModule
• args.ownedLifetimes?: Disposable
[]
• args.rt: Lifetime
<JSRuntimePointer
, never
, never
>
• args.runtime: QuickJSRuntime
quickjs-emscripten-core.UsingDisposable.constructor
packages/quickjs-emscripten-core/src/context.ts:224
readonly
runtime:QuickJSRuntime
The runtime that created this context.
packages/quickjs-emscripten-core/src/context.ts:186
get
alive():boolean
boolean
true if the object is alive
false after the object has been disposed
packages/quickjs-emscripten-core/src/context.ts:255
get
false():QuickJSHandle
packages/quickjs-emscripten-core/src/context.ts:313
get
global():QuickJSHandle
global
.
A handle to the global object inside the interpreter.
You can set properties to create global variables.
packages/quickjs-emscripten-core/src/context.ts:328
get
null():QuickJSHandle
null
.
packages/quickjs-emscripten-core/src/context.ts:287
get
true():QuickJSHandle
true
.
packages/quickjs-emscripten-core/src/context.ts:300
get
undefined():QuickJSHandle
packages/quickjs-emscripten-core/src/context.ts:274
[dispose]():
void
Just calls the standard .dispose() method of this class.
void
quickjs-emscripten-core.Disposable.[dispose]
quickjs-emscripten-core.UsingDisposable.[dispose]
packages/quickjs-emscripten-core/src/lifetime.ts:47
callFunction(
func
,thisVal
,args
?):QuickJSContextResult
<QuickJSHandle
>
func.call(thisVal, ...args)
or
func.apply(thisVal, args)
.
Call a JSValue as a function.
See unwrapResult, which will throw if the function returned an error, or return the result handle directly. If evaluation returned a handle containing a promise, use resolvePromise to convert it to a native promise and runtime.QuickJSRuntime#executePendingJobs to finish evaluating the promise.
• func: QuickJSHandle
• thisVal: QuickJSHandle
• args?: QuickJSHandle
[]
QuickJSContextResult
<QuickJSHandle
>
A result. If the function threw synchronously, result.error
be a
handle to the exception. Otherwise result.value
will be a handle to the
value.
Example:
using parseIntHandle = context.getProp(global, "parseInt")
using stringHandle = context.newString("42")
using resultHandle = context.callFunction(parseIntHandle, context.undefined, stringHandle).unwrap()
console.log(context.dump(resultHandle)) // 42
quickjs-emscripten-core.LowLevelJavascriptVm.callFunction
packages/quickjs-emscripten-core/src/context.ts:1059
callFunction(
func
,thisVal
, ...args
):QuickJSContextResult
<QuickJSHandle
>
• func: QuickJSHandle
• thisVal: QuickJSHandle
• ...args: QuickJSHandle
[]
QuickJSContextResult
<QuickJSHandle
>
LowLevelJavascriptVm.callFunction
packages/quickjs-emscripten-core/src/context.ts:1064
callMethod(
thisHandle
,key
,args
):QuickJSContextResult
<QuickJSHandle
>
handle[key](...args)
Call a method on a JSValue. This is a convenience method that calls getProp and callFunction.
• thisHandle: QuickJSHandle
• key: QuickJSPropertyKey
• args: QuickJSHandle
[]= []
QuickJSContextResult
<QuickJSHandle
>
A result. If the function threw synchronously, result.error
be a
handle to the exception. Otherwise result.value
will be a handle to the
value.
packages/quickjs-emscripten-core/src/context.ts:1113
decodeBinaryJSON(
handle
):QuickJSHandle
Outputs Handle of the given QuickJS Object in binary form
// imagine receiving data from another via IPC
socket.on("data", chunk => {
context.newArrayBuffer(chunk)
?.consume(handle => context.decodeBinaryJSON(handle))
?.consume(handle => console.log(context.dump(handle)))
})
• handle: QuickJSHandle
packages/quickjs-emscripten-core/src/context.ts:1431
defineProp(
handle
,key
,descriptor
):void
Object.defineProperty(handle, key, descriptor)
.
• handle: QuickJSHandle
• key: QuickJSPropertyKey
The property may be specified as a JSValue handle, or as a Javascript string or number (which will be converted automatically to a JSValue).
• descriptor: VmPropertyDescriptor
<QuickJSHandle
>
void
quickjs-emscripten-core.LowLevelJavascriptVm.defineProp
packages/quickjs-emscripten-core/src/context.ts:1000
dispose():
void
Dispose of this VM's underlying resources.
void
quickjs-emscripten-core.Disposable.dispose
quickjs-emscripten-core.UsingDisposable.dispose
Calling this method without disposing of all created handles will result in an error.
packages/quickjs-emscripten-core/src/context.ts:265
dump(
handle
):any
Dump a JSValue to Javascript in a best-effort fashion.
If the value is a promise, dumps the promise's state.
Returns handle.toString()
if it cannot be serialized to JSON.
• handle: QuickJSHandle
any
packages/quickjs-emscripten-core/src/context.ts:1234
encodeBinaryJSON(
handle
):QuickJSHandle
Outputs QuickJS Objects in binary form
WARNING: QuickJS's binary JSON doesn't have a standard so expect it to change between version
// imagine sending data to another via IPC
let dataLifetime = context.newString("This is an example")
?.consume(handle => context.encodeBinaryJSON(handle))
?.consume(handle => context.getArrayBuffer(handle))
socket.write(dataLifetime?.value)
• handle: QuickJSHandle
packages/quickjs-emscripten-core/src/context.ts:1414
eq(
handle
,other
):boolean
handle === other
- IsStrictlyEqual.
See Equality comparisons and sameness.
• handle: QuickJSHandle
• other: QuickJSHandle
boolean
packages/quickjs-emscripten-core/src/context.ts:811
evalCode(
code
,filename
,options
?):QuickJSContextResult
<QuickJSHandle
>
Like eval(code)
.
Evaluates code
, as though it's in a file named filename
, with options options
.
- When
options.type
is"global"
, the code is evaluated in the global scope of the QuickJSContext, and the return value is the result of the last expression. - When
options.type
is"module"
, the code is evaluated is a module scope. It may useimport
andexport
if runtime.QuickJSRuntime#setModuleLoader was called. It may use top-level await if supported by the underlying QuickJS library. The return value is the module's exports, or a promise for the module's exports. - When
options.type
is unset, the code is evaluated as a module if it contains animport
orexport
statement, otherwise it is evaluated in the global scope.
When working with async code, you many need to call runtime.QuickJSRuntime#executePendingJobs to execute callbacks pending after synchronous evaluation returns.
See unwrapResult, which will throw if the function returned an error, or return the result handle directly. If evaluation returned a handle containing a promise, use resolvePromise to convert it to a native promise and QuickJSRuntime#executePendingJobs to finish evaluating the promise.
Note: to protect against infinite loops, provide an interrupt handler to QuickJSRuntime#setInterruptHandler. You can use shouldInterruptAfterDeadline to create a time-based deadline.
• code: string
• filename: string
= "eval.js"
• options?: number
| ContextEvalOptions
If no options are passed, a heuristic will be used to detect if code
is
an ES module.
See EvalFlags for number semantics.
QuickJSContextResult
<QuickJSHandle
>
The last statement's value. If the code threw synchronously,
result.error
will be a handle to the exception. If execution was
interrupted, the error will have name InternalError
and message
interrupted
.
quickjs-emscripten-core.LowLevelJavascriptVm.evalCode
packages/quickjs-emscripten-core/src/context.ts:1156
protected
fail(error
):DisposableFail
<QuickJSHandle
>
• error: QuickJSHandle
packages/quickjs-emscripten-core/src/context.ts:1440
getArrayBuffer(
handle
):Lifetime
<Uint8Array
,never
,never
>
Coverts handle
to a JavaScript ArrayBuffer
• handle: QuickJSHandle
Lifetime
<Uint8Array
, never
, never
>
packages/quickjs-emscripten-core/src/context.ts:690
getBigInt(
handle
):bigint
Converts handle
to a Javascript bigint.
• handle: QuickJSHandle
bigint
packages/quickjs-emscripten-core/src/context.ts:681
getIterator(
iterableHandle
):QuickJSContextResult
<QuickJSIterator
>
handle[Symbol.iterator]()
. See [QuickJSIterator]([object Object]).
Returns a host iterator that wraps and proxies calls to a guest iterator handle.
Each step of the iteration returns a result, either an error or a handle to the next value.
Once the iterator is done, the handle is automatically disposed, and the iterator
is considered done if the handle is disposed.
for (using entriesHandle of context.getIterator(mapHandle).unwrap()) {
using keyHandle = context.getProp(entriesHandle, 0)
using valueHandle = context.getProp(entriesHandle, 1)
console.log(context.dump(keyHandle), '->', context.dump(valueHandle))
}
• iterableHandle: QuickJSHandle
QuickJSContextResult
<QuickJSIterator
>
packages/quickjs-emscripten-core/src/context.ts:960
getLength(
handle
):undefined
|number
handle.length
as a host number.
Example use:
const length = context.getLength(arrayHandle) ?? 0
for (let i = 0; i < length; i++) {
using value = context.getProp(arrayHandle, i)
console.log(`array[${i}] =`, context.dump(value))
}
• handle: QuickJSHandle
undefined
| number
a number if the handle has a numeric length property, otherwise undefined
.
packages/quickjs-emscripten-core/src/context.ts:870
getNumber(
handle
):number
Converts handle
into a Javascript number.
• handle: QuickJSHandle
number
NaN
on error, otherwise a number
.
quickjs-emscripten-core.LowLevelJavascriptVm.getNumber
packages/quickjs-emscripten-core/src/context.ts:652
getOwnPropertyNames(
handle
,options
):QuickJSContextResult
<DisposableArray
<QuickJSHandle
>>
Object.getOwnPropertyNames(handle)
.
Similar to the standard semantics,
but with extra, non-standard options for:
- fetching array indexes as numbers (
numbers: true
) - including symbols (
symbols: true
) - only iterating over enumerable properties (
onlyEnumerable: true
)
The default behavior is to emulate the standard:
context.getOwnPropertyNames(handle, { strings: true, numbersAsStrings: true })
Note when passing an explicit options object, you must set at least one
option, and strings
are not included unless specified.
Example use:
for (using prop of context.getOwnPropertyNames(objectHandle).unwrap()) {
using value = context.getProp(handle, prop)
console.log(context.dump(prop), '->', context.dump(value))
}
• handle: QuickJSHandle
• options: GetOwnPropertyNamesOptions
= undefined
QuickJSContextResult
<DisposableArray
<QuickJSHandle
>>
an an array of handles of the property names. The array itself is disposable for your convenience.
QuickJSEmptyGetOwnPropertyNames if no options are set.
packages/quickjs-emscripten-core/src/context.ts:907
getPromiseState(
handle
):JSPromiseState
Get the current state of a QuickJS promise, see JSPromiseState for the possible states. This can be used to expect a promise to be fulfilled when combined with unwrapResult:
const promiseHandle = context.evalCode(`Promise.resolve(42)`);
const resultHandle = context.unwrapResult(
context.getPromiseState(promiseHandle)
);
context.getNumber(resultHandle) === 42; // true
resultHandle.dispose();
• handle: QuickJSHandle
packages/quickjs-emscripten-core/src/context.ts:715
getProp(
handle
,key
):QuickJSHandle
handle[key]
.
Get a property from a JSValue.
• handle: QuickJSHandle
• key: QuickJSPropertyKey
The property may be specified as a JSValue handle, or as a Javascript string (which will be converted automatically).
quickjs-emscripten-core.LowLevelJavascriptVm.getProp
packages/quickjs-emscripten-core/src/context.ts:840
getString(
handle
):string
Converts handle
to a Javascript string.
• handle: QuickJSHandle
string
quickjs-emscripten-core.LowLevelJavascriptVm.getString
packages/quickjs-emscripten-core/src/context.ts:660
getSymbol(
handle
):symbol
Converts handle
into a Javascript symbol. If the symbol is in the global
registry in the guest, it will be created with Symbol.for on the host.
• handle: QuickJSHandle
symbol
packages/quickjs-emscripten-core/src/context.ts:669
getWellKnownSymbol(
name
):QuickJSHandle
Access a well-known symbol that is a property of the global Symbol object, like Symbol.iterator
.
• name: string
packages/quickjs-emscripten-core/src/context.ts:388
newArray():
QuickJSHandle
[]
.
Create a new QuickJS array.
packages/quickjs-emscripten-core/src/context.ts:430
newArrayBuffer(
buffer
):QuickJSHandle
Create a new QuickJS ArrayBuffer.
• buffer: ArrayBufferLike
packages/quickjs-emscripten-core/src/context.ts:438
newBigInt(
num
):QuickJSHandle
Create a QuickJS bigint value.
• num: bigint
packages/quickjs-emscripten-core/src/context.ts:396
newError(
error
):QuickJSHandle
• error: Object
• error.message: string
• error.name: string
packages/quickjs-emscripten-core/src/context.ts:607
newError(
message
):QuickJSHandle
• message: string
packages/quickjs-emscripten-core/src/context.ts:608
newError():
QuickJSHandle
packages/quickjs-emscripten-core/src/context.ts:609
newFunction(
name
,fn
):QuickJSHandle
Convert a Javascript function into a QuickJS function value. See VmFunctionImplementation for more details.
A VmFunctionImplementation should not free its arguments or its return value. A VmFunctionImplementation should also not retain any references to its return value.
The function argument handles are automatically disposed when the function
returns. If you want to retain a handle beyond the end of the function, you
can call Lifetime#dup to create a copy of the handle that you own
and must dispose manually. For example, you need to use this API and do some
extra book keeping to implement setInterval
:
// This won't work because `callbackHandle` expires when the function returns,
// so when the interval fires, the callback handle is already disposed.
const WRONG_setIntervalHandle = context.newFunction("setInterval", (callbackHandle, delayHandle) => {
const delayMs = context.getNumber(delayHandle)
const intervalId = globalThis.setInterval(() => {
// ERROR: callbackHandle is already disposed here.
context.callFunction(callbackHandle)
}, intervalId)
return context.newNumber(intervalId)
})
// This works since we dup the callbackHandle.
// We just need to make sure we clean it up manually when the interval is cleared --
// so we need to keep track of those interval IDs, and make sure we clean all
// of them up when we dispose the owning context.
const setIntervalHandle = context.newFunction("setInterval", (callbackHandle, delayHandle) => {
// Ensure the guest can't overload us by scheduling too many intervals.
if (QuickJSInterval.INTERVALS.size > 100) {
throw new Error(`Too many intervals scheduled already`)
}
const delayMs = context.getNumber(delayHandle)
const longLivedCallbackHandle = callbackHandle.dup()
const intervalId = globalThis.setInterval(() => {
context.callFunction(longLivedCallbackHandle)
}, intervalId)
const disposable = new QuickJSInterval(longLivedCallbackHandle, context, intervalId)
QuickJSInterval.INTERVALS.set(intervalId, disposable)
return context.newNumber(intervalId)
})
const clearIntervalHandle = context.newFunction("clearInterval", (intervalIdHandle) => {
const intervalId = context.getNumber(intervalIdHandle)
const disposable = QuickJSInterval.INTERVALS.get(intervalId)
disposable?.dispose()
})
class QuickJSInterval extends UsingDisposable {
static INTERVALS = new Map<number, QuickJSInterval>()
static disposeContext(context: QuickJSContext) {
for (const interval of QuickJSInterval.INTERVALS.values()) {
if (interval.context === context) {
interval.dispose()
}
}
}
constructor(
public fnHandle: QuickJSHandle,
public context: QuickJSContext,
public intervalId: number,
) {
super()
}
dispose() {
globalThis.clearInterval(this.intervalId)
this.fnHandle.dispose()
QuickJSInterval.INTERVALS.delete(this.fnHandle.value)
}
get alive() {
return this.fnHandle.alive
}
}
To implement an async function, create a promise with newPromise, then
return the deferred promise handle from deferred.handle
from your
function implementation:
const deferred = vm.newPromise()
someNativeAsyncFunction().then(deferred.resolve)
return deferred.handle
• name: string
• fn: VmFunctionImplementation
<QuickJSHandle
>
quickjs-emscripten-core.LowLevelJavascriptVm.newFunction
packages/quickjs-emscripten-core/src/context.ts:601
newNumber(
num
):QuickJSHandle
Converts a Javascript number into a QuickJS value.
• num: number
quickjs-emscripten-core.LowLevelJavascriptVm.newNumber
packages/quickjs-emscripten-core/src/context.ts:347
newObject(
prototype
?):QuickJSHandle
{}
.
Create a new QuickJS object.
• prototype?: QuickJSHandle
Like Object.create
.
quickjs-emscripten-core.LowLevelJavascriptVm.newObject
packages/quickjs-emscripten-core/src/context.ts:416
newPromise():
QuickJSDeferredPromise
Create a new QuickJSDeferredPromise. Use deferred.resolve(handle)
and
deferred.reject(handle)
to fulfill the promise handle available at deferred.handle
.
Note that you are responsible for calling deferred.dispose()
to free the underlying
resources; see the documentation on QuickJSDeferredPromise for details.
packages/quickjs-emscripten-core/src/context.ts:451
newPromise(
promise
):QuickJSDeferredPromise
Create a new QuickJSDeferredPromise that resolves when the
given native Promise<QuickJSHandle>
resolves. Rejections will be coerced
to a QuickJS error.
You can still resolve/reject the created promise "early" using its methods.
• promise: Promise
<QuickJSHandle
>
packages/quickjs-emscripten-core/src/context.ts:459
newPromise(
newPromiseFn
):QuickJSDeferredPromise
Construct a new native Promise<QuickJSHandle>
, and then convert it into a
QuickJSDeferredPromise.
You can still resolve/reject the created promise "early" using its methods.
• newPromiseFn: PromiseExecutor
<QuickJSHandle
, Error
| QuickJSHandle
>
packages/quickjs-emscripten-core/src/context.ts:466
newString(
str
):QuickJSHandle
Create a QuickJS string value.
• str: string
quickjs-emscripten-core.LowLevelJavascriptVm.newString
packages/quickjs-emscripten-core/src/context.ts:354
newSymbolFor(
key
):QuickJSHandle
Get a symbol from the global registry for the given key. All symbols created with the same key will be the same value.
• key: string
| symbol
packages/quickjs-emscripten-core/src/context.ts:377
newUniqueSymbol(
description
):QuickJSHandle
Create a QuickJS symbol value. No two symbols created with this function will be the same value.
• description: string
| symbol
packages/quickjs-emscripten-core/src/context.ts:365
resolvePromise(
promiseLikeHandle
):Promise
<QuickJSContextResult
<QuickJSHandle
>>
Promise.resolve(value)
.
Convert a handle containing a Promise-like value inside the VM into an
actual promise on the host.
• promiseLikeHandle: QuickJSHandle
A handle to a Promise-like value with a .then(onSuccess, onError)
method.
Promise
<QuickJSContextResult
<QuickJSHandle
>>
You may need to call runtime.QuickJSRuntime#executePendingJobs to ensure that the promise is resolved.
packages/quickjs-emscripten-core/src/context.ts:754
sameValue(
handle
,other
):boolean
Object.is(a, b)
See Equality comparisons and sameness.
• handle: QuickJSHandle
• other: QuickJSHandle
boolean
packages/quickjs-emscripten-core/src/context.ts:819
sameValueZero(
handle
,other
):boolean
SameValueZero comparison. See Equality comparisons and sameness.
• handle: QuickJSHandle
• other: QuickJSHandle
boolean
packages/quickjs-emscripten-core/src/context.ts:827
setProp(
handle
,key
,value
):void
handle[key] = value
.
Set a property on a JSValue.
• handle: QuickJSHandle
• key: QuickJSPropertyKey
The property may be specified as a JSValue handle, or as a Javascript string or number (which will be converted automatically to a JSValue).
• value: QuickJSHandle
void
quickjs-emscripten-core.LowLevelJavascriptVm.setProp
Note that the QuickJS authors recommend using defineProp to define new properties.
packages/quickjs-emscripten-core/src/context.ts:985
protected
success<S
>(value
):DisposableSuccess
<S
>
• S
• value: S
packages/quickjs-emscripten-core/src/context.ts:1436
throw(
error
):JSValuePointer
Throw an error in the VM, interrupted whatever current execution is in progress when execution resumes.
• error: Error
| QuickJSHandle
packages/quickjs-emscripten-core/src/context.ts:1193
typeof(
handle
):string
typeof
operator. Not standards compliant.
• handle: QuickJSHandle
string
quickjs-emscripten-core.LowLevelJavascriptVm.typeof
Does not support BigInt values correctly.
packages/quickjs-emscripten-core/src/context.ts:643
unwrapResult<
T
>(result
):T
Unwrap a SuccessOrFail result such as a VmCallResult or a ExecutePendingJobsResult, where the fail branch contains a handle to a QuickJS error value. If the result is a success, returns the value. If the result is an error, converts the error to a native object and throws the error.
• T
• result: SuccessOrFail
<T
, QuickJSHandle
>
T
packages/quickjs-emscripten-core/src/context.ts:1277
Generated using typedoc-plugin-markdown and TypeDoc