Tons of Solutions Engineering work done today for the rest of the CS team! Headway, Howard Hanna, Engels, Brighton, etc. Also completed Datasnippers auth flow and worked on Anthology's script. Cloned Anthology's courses (900..) and will clone Full Story on Monday.
This commit is contained in:
21
Scripts/node_modules/@tootallnate/quickjs-emscripten/LICENSE
generated
vendored
Normal file
21
Scripts/node_modules/@tootallnate/quickjs-emscripten/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
quickjs-emscripten copyright (c) 2019 Jake Teton-Landis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
597
Scripts/node_modules/@tootallnate/quickjs-emscripten/README.md
generated
vendored
Normal file
597
Scripts/node_modules/@tootallnate/quickjs-emscripten/README.md
generated
vendored
Normal file
@ -0,0 +1,597 @@
|
||||
# quickjs-emscripten
|
||||
|
||||
Javascript/Typescript bindings for QuickJS, a modern Javascript interpreter,
|
||||
compiled to WebAssembly.
|
||||
|
||||
- Safely evaluate untrusted Javascript (up to ES2020).
|
||||
- Create and manipulate values inside the QuickJS runtime ([more][values]).
|
||||
- Expose host functions to the QuickJS runtime ([more][functions]).
|
||||
- Execute synchronous code that uses asynchronous functions, with [asyncify][asyncify].
|
||||
|
||||
[Github] | [NPM] | [API Documentation][api] | [Examples][tests]
|
||||
|
||||
```typescript
|
||||
import { getQuickJS } from "quickjs-emscripten"
|
||||
|
||||
async function main() {
|
||||
const QuickJS = await getQuickJS()
|
||||
const vm = QuickJS.newContext()
|
||||
|
||||
const world = vm.newString("world")
|
||||
vm.setProp(vm.global, "NAME", world)
|
||||
world.dispose()
|
||||
|
||||
const result = vm.evalCode(`"Hello " + NAME + "!"`)
|
||||
if (result.error) {
|
||||
console.log("Execution failed:", vm.dump(result.error))
|
||||
result.error.dispose()
|
||||
} else {
|
||||
console.log("Success:", vm.dump(result.value))
|
||||
result.value.dispose()
|
||||
}
|
||||
|
||||
vm.dispose()
|
||||
}
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
[github]: https://github.com/justjake/quickjs-emscripten
|
||||
[npm]: https://www.npmjs.com/package/quickjs-emscripten
|
||||
[api]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md
|
||||
[tests]: https://github.com/justjake/quickjs-emscripten/blob/main/ts/quickjs.test.ts
|
||||
[values]: #interfacing-with-the-interpreter
|
||||
[asyncify]: #asyncify
|
||||
[functions]: #exposing-apis
|
||||
|
||||
## Usage
|
||||
|
||||
Install from `npm`: `npm install --save quickjs-emscripten` or `yarn add quickjs-emscripten`.
|
||||
|
||||
The root entrypoint of this library is the `getQuickJS` function, which returns
|
||||
a promise that resolves to a [QuickJS singleton](./doc/classes/quickjs.md) when
|
||||
the QuickJS WASM module is ready.
|
||||
|
||||
Once `getQuickJS` has been awaited at least once, you also can use the `getQuickJSSync`
|
||||
function to directly access the singleton engine in your synchronous code.
|
||||
|
||||
### Safely evaluate Javascript code
|
||||
|
||||
See [QuickJS.evalCode](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/quickjs.md#evalcode)
|
||||
|
||||
```typescript
|
||||
import { getQuickJS, shouldInterruptAfterDeadline } from "quickjs-emscripten"
|
||||
|
||||
getQuickJS().then((QuickJS) => {
|
||||
const result = QuickJS.evalCode("1 + 1", {
|
||||
shouldInterrupt: shouldInterruptAfterDeadline(Date.now() + 1000),
|
||||
memoryLimitBytes: 1024 * 1024,
|
||||
})
|
||||
console.log(result)
|
||||
})
|
||||
```
|
||||
|
||||
### Interfacing with the interpreter
|
||||
|
||||
You can use [QuickJSContext](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/QuickJSContext.md)
|
||||
to build a scripting environment by modifying globals and exposing functions
|
||||
into the QuickJS interpreter.
|
||||
|
||||
Each `QuickJSContext` instance has its own environment -- globals, built-in
|
||||
classes -- and actions from one context won't leak into other contexts or
|
||||
runtimes (with one exception, see [Asyncify][asyncify]).
|
||||
|
||||
Every context is created inside a
|
||||
[QuickJSRuntime](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/QuickJSRuntime.md).
|
||||
A runtime represents a Javascript heap, and you can even share values between
|
||||
contexts in the same runtime.
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
let state = 0
|
||||
|
||||
const fnHandle = vm.newFunction("nextId", () => {
|
||||
return vm.newNumber(++state)
|
||||
})
|
||||
|
||||
vm.setProp(vm.global, "nextId", fnHandle)
|
||||
fnHandle.dispose()
|
||||
|
||||
const nextId = vm.unwrapResult(vm.evalCode(`nextId(); nextId(); nextId()`))
|
||||
console.log("vm result:", vm.getNumber(nextId), "native state:", state)
|
||||
|
||||
nextId.dispose()
|
||||
vm.dispose()
|
||||
```
|
||||
|
||||
When you create a context from a top-level API like in the example above,
|
||||
instead of by calling `runtime.newContext()`, a runtime is automatically created
|
||||
for the lifetime of the context, and disposed of when you dispose the context.
|
||||
|
||||
#### Runtime
|
||||
|
||||
The runtime has APIs for CPU and memory limits that apply to all contexts within
|
||||
the runtime in aggregate. You can also use the runtime to configure EcmaScript
|
||||
module loading.
|
||||
|
||||
```typescript
|
||||
const runtime = QuickJS.newRuntime()
|
||||
// "Should be enough for everyone" -- attributed to B. Gates
|
||||
runtime.setMemoryLimit(1024 * 640)
|
||||
// Limit stack size
|
||||
runtime.setMaxStackSize(1024 * 320)
|
||||
// Interrupt computation after 1024 calls to the interrupt handler
|
||||
let interruptCycles = 0
|
||||
runtime.setInterruptHandler(() => ++interruptCycles > 1024)
|
||||
// Toy module system that always returns the module name
|
||||
// as the default export
|
||||
runtime.setModuleLoader((moduleName) => `export default '${moduleName}'`)
|
||||
const context = runtime.newContext()
|
||||
const ok = context.evalCode(`
|
||||
import fooName from './foo.js'
|
||||
globalThis.result = fooName
|
||||
`)
|
||||
context.unwrapResult(ok).dispose()
|
||||
// logs "foo.js"
|
||||
console.log(context.getProp(context.global, "result").consume(context.dump))
|
||||
context.dispose()
|
||||
runtime.dispose()
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
|
||||
Many methods in this library return handles to memory allocated inside the
|
||||
WebAssembly heap. These types cannot be garbage-collected as usual in
|
||||
Javascript. Instead, you must manually manage their memory by calling a
|
||||
`.dispose()` method to free the underlying resources. Once a handle has been
|
||||
disposed, it cannot be used anymore. Note that in the example above, we call
|
||||
`.dispose()` on each handle once it is no longer needed.
|
||||
|
||||
Calling `QuickJSContext.dispose()` will throw a RuntimeError if you've forgotten to
|
||||
dispose any handles associated with that VM, so it's good practice to create a
|
||||
new VM instance for each of your tests, and to call `vm.dispose()` at the end
|
||||
of every test.
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
const numberHandle = vm.newNumber(42)
|
||||
// Note: numberHandle not disposed, so it leaks memory.
|
||||
vm.dispose()
|
||||
// throws RuntimeError: abort(Assertion failed: list_empty(&rt->gc_obj_list), at: quickjs/quickjs.c,1963,JS_FreeRuntime)
|
||||
```
|
||||
|
||||
Here are some strategies to reduce the toil of calling `.dispose()` on each
|
||||
handle you create:
|
||||
|
||||
#### Scope
|
||||
|
||||
A
|
||||
[`Scope`](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/scope.md#class-scope)
|
||||
instance manages a set of disposables and calls their `.dispose()`
|
||||
method in the reverse order in which they're added to the scope. Here's the
|
||||
"Interfacing with the interpreter" example re-written using `Scope`:
|
||||
|
||||
```typescript
|
||||
Scope.withScope((scope) => {
|
||||
const vm = scope.manage(QuickJS.newContext())
|
||||
let state = 0
|
||||
|
||||
const fnHandle = scope.manage(
|
||||
vm.newFunction("nextId", () => {
|
||||
return vm.newNumber(++state)
|
||||
})
|
||||
)
|
||||
|
||||
vm.setProp(vm.global, "nextId", fnHandle)
|
||||
|
||||
const nextId = scope.manage(vm.unwrapResult(vm.evalCode(`nextId(); nextId(); nextId()`)))
|
||||
console.log("vm result:", vm.getNumber(nextId), "native state:", state)
|
||||
|
||||
// When the withScope block exits, it calls scope.dispose(), which in turn calls
|
||||
// the .dispose() methods of all the disposables managed by the scope.
|
||||
})
|
||||
```
|
||||
|
||||
You can also create `Scope` instances with `new Scope()` if you want to manage
|
||||
calling `scope.dispose()` yourself.
|
||||
|
||||
#### `Lifetime.consume(fn)`
|
||||
|
||||
[`Lifetime.consume`](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/lifetime.md#consume)
|
||||
is sugar for the common pattern of using a handle and then
|
||||
immediately disposing of it. `Lifetime.consume` takes a `map` function that
|
||||
produces a result of any type. The `map` fuction is called with the handle,
|
||||
then the handle is disposed, then the result is returned.
|
||||
|
||||
Here's the "Interfacing with interpreter" example re-written using `.consume()`:
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
let state = 0
|
||||
|
||||
vm.newFunction("nextId", () => {
|
||||
return vm.newNumber(++state)
|
||||
}).consume((fnHandle) => vm.setProp(vm.global, "nextId", fnHandle))
|
||||
|
||||
vm.unwrapResult(vm.evalCode(`nextId(); nextId(); nextId()`)).consume((nextId) =>
|
||||
console.log("vm result:", vm.getNumber(nextId), "native state:", state)
|
||||
)
|
||||
|
||||
vm.dispose()
|
||||
```
|
||||
|
||||
Generally working with `Scope` leads to more straight-forward code, but
|
||||
`Lifetime.consume` can be handy sugar as part of a method call chain.
|
||||
|
||||
### Exposing APIs
|
||||
|
||||
To add APIs inside the QuickJS environment, you'll need to create objects to
|
||||
define the shape of your API, and add properties and functions to those objects
|
||||
to allow code inside QuickJS to call code on the host.
|
||||
|
||||
By default, no host functionality is exposed to code running inside QuickJS.
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
// `console.log`
|
||||
const logHandle = vm.newFunction("log", (...args) => {
|
||||
const nativeArgs = args.map(vm.dump)
|
||||
console.log("QuickJS:", ...nativeArgs)
|
||||
})
|
||||
// Partially implement `console` object
|
||||
const consoleHandle = vm.newObject()
|
||||
vm.setProp(consoleHandle, "log", logHandle)
|
||||
vm.setProp(vm.global, "console", consoleHandle)
|
||||
consoleHandle.dispose()
|
||||
logHandle.dispose()
|
||||
|
||||
vm.unwrapResult(vm.evalCode(`console.log("Hello from QuickJS!")`)).dispose()
|
||||
```
|
||||
|
||||
#### Promises
|
||||
|
||||
To expose an asynchronous function that _returns a promise_ to callers within
|
||||
QuickJS, your function can return the handle of a `QuickJSDeferredPromise`
|
||||
created via `context.newPromise()`.
|
||||
|
||||
When you resolve a `QuickJSDeferredPromise` -- and generally whenever async
|
||||
behavior completes for the VM -- pending listeners inside QuickJS may not
|
||||
execute immediately. Your code needs to explicitly call
|
||||
`runtime.executePendingJobs()` to resume execution inside QuickJS. This API
|
||||
gives your code maximum control to _schedule_ when QuickJS will block the host's
|
||||
event loop by resuming execution.
|
||||
|
||||
To work with QuickJS handles that contain a promise inside the environment, you
|
||||
can convert the QuickJSHandle into a native promise using
|
||||
`context.resolvePromise()`. Take care with this API to avoid 'deadlocks' where
|
||||
the host awaits a guest promise, but the guest cannot make progress until the
|
||||
host calls `runtime.executePendingJobs()`. The simplest way to avoid this kind
|
||||
of deadlock is to always schedule `executePendingJobs` after any promise is
|
||||
settled.
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
const fakeFileSystem = new Map([["example.txt", "Example file content"]])
|
||||
|
||||
// Function that simulates reading data asynchronously
|
||||
const readFileHandle = vm.newFunction("readFile", (pathHandle) => {
|
||||
const path = vm.getString(pathHandle)
|
||||
const promise = vm.newPromise()
|
||||
setTimeout(() => {
|
||||
const content = fakeFileSystem.get(path)
|
||||
promise.resolve(vm.newString(content || ""))
|
||||
}, 100)
|
||||
// IMPORTANT: Once you resolve an async action inside QuickJS,
|
||||
// call runtime.executePendingJobs() to run any code that was
|
||||
// waiting on the promise or callback.
|
||||
promise.settled.then(vm.runtime.executePendingJobs)
|
||||
return promise.handle
|
||||
})
|
||||
readFileHandle.consume((handle) => vm.setProp(vm.global, "readFile", handle))
|
||||
|
||||
// Evaluate code that uses `readFile`, which returns a promise
|
||||
const result = vm.evalCode(`(async () => {
|
||||
const content = await readFile('example.txt')
|
||||
return content.toUpperCase()
|
||||
})()`)
|
||||
const promiseHandle = vm.unwrapResult(result)
|
||||
|
||||
// Convert the promise handle into a native promise and await it.
|
||||
// If code like this deadlocks, make sure you are calling
|
||||
// runtime.executePendingJobs appropriately.
|
||||
const resolvedResult = await vm.resolvePromise(promiseHandle)
|
||||
promiseHandle.dispose()
|
||||
const resolvedHandle = vm.unwrapResult(resolvedResult)
|
||||
console.log("Result:", vm.getString(resolvedHandle))
|
||||
resolvedHandle.dispose()
|
||||
```
|
||||
|
||||
#### Asyncify
|
||||
|
||||
Sometimes, we want to create a function that's synchronous from the perspective
|
||||
of QuickJS, but prefer to implement that function _asynchronously_ in your host
|
||||
code. The most obvious use-case is for EcmaScript module loading. The underlying
|
||||
QuickJS C library expects the module loader function to return synchronously,
|
||||
but loading data synchronously in the browser or server is somewhere between "a
|
||||
bad idea" and "impossible". QuickJS also doesn't expose an API to "pause" the
|
||||
execution of a runtime, and adding such an API is tricky due to the VM's
|
||||
implementation.
|
||||
|
||||
As a work-around, we provide an alternate build of QuickJS processed by
|
||||
Emscripten/Binaryen's [ASYNCIFY](https://emscripten.org/docs/porting/asyncify.html)
|
||||
compiler transform. Here's how Emscripten's documentation describes Asyncify:
|
||||
|
||||
> Asyncify lets synchronous C or C++ code interact with asynchronous \[host] JavaScript. This allows things like:
|
||||
>
|
||||
> - A synchronous call in C that yields to the event loop, which allows browser events to be handled.
|
||||
>
|
||||
> - A synchronous call in C that waits for an asynchronous operation in \[host] JS to complete.
|
||||
>
|
||||
> Asyncify automatically transforms ... code into a form that can be paused and
|
||||
> resumed ..., so that it is asynchronous (hence the name “Asyncify”) even though
|
||||
> \[it is written] in a normal synchronous way.
|
||||
|
||||
This means we can suspend an _entire WebAssembly module_ (which could contain
|
||||
multiple runtimes and contexts) while our host Javascript loads data
|
||||
asynchronously, and then resume execution once the data load completes. This is
|
||||
a very handy superpower, but it comes with a couple of major limitations:
|
||||
|
||||
1. _An asyncified WebAssembly module can only suspend to wait for a single
|
||||
asynchronous call at a time_. You may call back into a suspended WebAssembly
|
||||
module eg. to create a QuickJS value to return a result, but the system will
|
||||
crash if this call tries to suspend again. Take a look at Emscripten's documentation
|
||||
on [reentrancy](https://emscripten.org/docs/porting/asyncify.html#reentrancy).
|
||||
|
||||
2. _Asyncified code is bigger and runs slower_. The asyncified build of
|
||||
Quickjs-emscripten library is 1M, 2x larger than the 500K of the default
|
||||
version. There may be room for further
|
||||
[optimization](https://emscripten.org/docs/porting/asyncify.html#optimizing)
|
||||
Of our build in the future.
|
||||
|
||||
To use asyncify features, use the following functions:
|
||||
|
||||
- [newAsyncRuntime][]: create a runtime inside a new WebAssembly module.
|
||||
- [newAsyncContext][]: create runtime and context together inside a new
|
||||
WebAssembly module.
|
||||
- [newQuickJSAsyncWASMModule][]: create an empty WebAssembly module.
|
||||
|
||||
[newasyncruntime]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md#newasyncruntime
|
||||
[newasynccontext]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md#newasynccontext
|
||||
[newquickjsasyncwasmmodule]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md#newquickjsasyncwasmmodule
|
||||
|
||||
These functions are asynchronous because they always create a new underlying
|
||||
WebAssembly module so that each instance can suspend and resume independently,
|
||||
and instantiating a WebAssembly module is an async operation. This also adds
|
||||
substantial overhead compared to creating a runtime or context inside an
|
||||
existing module; if you only need to wait for a single async action at a time,
|
||||
you can create a single top-level module and create runtimes or contexts inside
|
||||
of it.
|
||||
|
||||
##### Async module loader
|
||||
|
||||
Here's an example of valuating a script that loads React asynchronously as an ES
|
||||
module. In our example, we're loading from the filesystem for reproducibility,
|
||||
but you can use this technique to load using `fetch`.
|
||||
|
||||
```typescript
|
||||
const module = await newQuickJSAsyncWASMModule()
|
||||
const runtime = module.newRuntime()
|
||||
const path = await import("path")
|
||||
const { promises: fs } = await import("fs")
|
||||
|
||||
const importsPath = path.join(__dirname, "../examples/imports") + "/"
|
||||
// Module loaders can return promises.
|
||||
// Execution will suspend until the promise resolves.
|
||||
runtime.setModuleLoader((moduleName) => {
|
||||
const modulePath = path.join(importsPath, moduleName)
|
||||
if (!modulePath.startsWith(importsPath)) {
|
||||
throw new Error("out of bounds")
|
||||
}
|
||||
console.log("loading", moduleName, "from", modulePath)
|
||||
return fs.readFile(modulePath, "utf-8")
|
||||
})
|
||||
|
||||
// evalCodeAsync is required when execution may suspend.
|
||||
const context = runtime.newContext()
|
||||
const result = await context.evalCodeAsync(`
|
||||
import * as React from 'esm.sh/react@17'
|
||||
import * as ReactDOMServer from 'esm.sh/react-dom@17/server'
|
||||
const e = React.createElement
|
||||
globalThis.html = ReactDOMServer.renderToStaticMarkup(
|
||||
e('div', null, e('strong', null, 'Hello world!'))
|
||||
)
|
||||
`)
|
||||
context.unwrapResult(result).dispose()
|
||||
const html = context.getProp(context.global, "html").consume(context.getString)
|
||||
console.log(html) // <div><strong>Hello world!</strong></div>
|
||||
```
|
||||
|
||||
##### Async on host, sync in QuickJS
|
||||
|
||||
Here's an example of turning an async function into a sync function inside the
|
||||
VM.
|
||||
|
||||
```typescript
|
||||
const context = await newAsyncContext()
|
||||
const path = await import("path")
|
||||
const { promises: fs } = await import("fs")
|
||||
|
||||
const importsPath = path.join(__dirname, "../examples/imports") + "/"
|
||||
const readFileHandle = context.newAsyncifiedFunction("readFile", async (pathHandle) => {
|
||||
const pathString = path.join(importsPath, context.getString(pathHandle))
|
||||
if (!pathString.startsWith(importsPath)) {
|
||||
throw new Error("out of bounds")
|
||||
}
|
||||
const data = await fs.readFile(pathString, "utf-8")
|
||||
return context.newString(data)
|
||||
})
|
||||
readFileHandle.consume((fn) => context.setProp(context.global, "readFile", fn))
|
||||
|
||||
// evalCodeAsync is required when execution may suspend.
|
||||
const result = await context.evalCodeAsync(`
|
||||
// Not a promise! Sync! vvvvvvvvvvvvvvvvvvvv
|
||||
const data = JSON.parse(readFile('data.json'))
|
||||
data.map(x => x.toUpperCase()).join(' ')
|
||||
`)
|
||||
const upperCaseData = context.unwrapResult(result).consume(context.getString)
|
||||
console.log(upperCaseData) // 'VERY USEFUL DATA'
|
||||
```
|
||||
|
||||
### Testing your code
|
||||
|
||||
This library is complicated to use, so please consider automated testing your
|
||||
implementation. We highly writing your test suite to run with both the "release"
|
||||
build variant of quickjs-emscripten, and also the [DEBUG_SYNC] build variant.
|
||||
The debug sync build variant has extra instrumentation code for detecting memory
|
||||
leaks.
|
||||
|
||||
The class [TestQuickJSWASMModule] exposes the memory leak detection API, although
|
||||
this API is only accurate when using `DEBUG_SYNC` variant.
|
||||
|
||||
```typescript
|
||||
// Define your test suite in a function, so that you can test against
|
||||
// different module loaders.
|
||||
function myTests(moduleLoader: () => Promise<QuickJSWASMModule>) {
|
||||
let QuickJS: TestQuickJSWASMModule
|
||||
beforeEach(async () => {
|
||||
// Get a unique TestQuickJSWASMModule instance for each test.
|
||||
const wasmModule = await moduleLoader()
|
||||
QuickJS = new TestQuickJSWASMModule(wasmModule)
|
||||
})
|
||||
afterEach(() => {
|
||||
// Assert that the test disposed all handles. The DEBUG_SYNC build
|
||||
// variant will show detailed traces for each leak.
|
||||
QuickJS.assertNoMemoryAllocated()
|
||||
})
|
||||
|
||||
it("works well", () => {
|
||||
// TODO: write a test using QuickJS
|
||||
const context = QuickJS.newContext()
|
||||
context.unwrapResult(context.evalCode("1 + 1")).dispose()
|
||||
context.dispose()
|
||||
})
|
||||
}
|
||||
|
||||
// Run the test suite against a matrix of module loaders.
|
||||
describe("Check for memory leaks with QuickJS DEBUG build", () => {
|
||||
const moduleLoader = memoizePromiseFactory(() => newQuickJSWASMModule(DEBUG_SYNC))
|
||||
myTests(moduleLoader)
|
||||
})
|
||||
|
||||
describe("Realistic test with QuickJS RELEASE build", () => {
|
||||
myTests(getQuickJS)
|
||||
})
|
||||
```
|
||||
|
||||
For more testing examples, please explore the typescript source of [quickjs-emscripten][ts] repository.
|
||||
|
||||
[ts]: https://github.com/justjake/quickjs-emscripten/blob/main/ts
|
||||
[debug_sync]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md#debug_sync
|
||||
[testquickjswasmmodule]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/TestQuickJSWASMModule.md
|
||||
|
||||
### Debugging
|
||||
|
||||
- Switch to a DEBUG build variant of the WebAssembly module to see debug log messages from the C part of this library.
|
||||
- Set `process.env.QTS_DEBUG` to see debug log messages from the Javascript part of this library.
|
||||
|
||||
### More Documentation
|
||||
|
||||
[Github] | [NPM] | [API Documentation][api] | [Examples][tests]
|
||||
|
||||
## Background
|
||||
|
||||
This was inspired by seeing https://github.com/maple3142/duktape-eval
|
||||
[on Hacker News](https://news.ycombinator.com/item?id=21946565) and Figma's
|
||||
blogposts about using building a Javascript plugin runtime:
|
||||
|
||||
- [How Figma built the Figma plugin system](https://www.figma.com/blog/how-we-built-the-figma-plugin-system/): Describes the LowLevelJavascriptVm interface.
|
||||
- [An update on plugin security](https://www.figma.com/blog/an-update-on-plugin-security/): Figma switches to QuickJS.
|
||||
|
||||
## Status & Roadmap
|
||||
|
||||
**Stability**: Because the version number of this project is below `1.0.0`,
|
||||
\*expect occasional breaking API changes.
|
||||
|
||||
**Security**: This project makes every effort to be secure, but has not been
|
||||
audited. Please use with care in production settings.
|
||||
|
||||
**Roadmap**: I work on this project in my free time, for fun. Here's I'm
|
||||
thinking comes next. Last updated 2022-03-18.
|
||||
|
||||
1. Further work on module loading APIs:
|
||||
|
||||
- Create modules via Javascript, instead of source text.
|
||||
- Scan source text for imports, for ahead of time or concurrent loading.
|
||||
(This is possible with third-party tools, so lower priority.)
|
||||
|
||||
2. Higher-level tools for reading QuickJS values:
|
||||
|
||||
- Type guard functions: `context.isArray(handle)`, `context.isPromise(handle)`, etc.
|
||||
- Iteration utilities: `context.getIterable(handle)`, `context.iterateObjectEntries(handle)`.
|
||||
This better supports user-level code to deserialize complex handle objects.
|
||||
|
||||
3. Higher-level tools for creating QuickJS values:
|
||||
|
||||
- Devise a way to avoid needing to mess around with handles when setting up
|
||||
the environment.
|
||||
- Consider integrating
|
||||
[quickjs-emscripten-sync](https://github.com/reearth/quickjs-emscripten-sync)
|
||||
for automatic translation.
|
||||
- Consider class-based or interface-type-based marshalling.
|
||||
|
||||
4. EcmaScript Modules / WebAssembly files / Deno support. This requires me to
|
||||
learn a lot of new things, but should be interesting for modern browser usage.
|
||||
|
||||
5. SQLite integration.
|
||||
|
||||
## Related
|
||||
|
||||
- Duktape wrapped in Wasm: https://github.com/maple3142/duktape-eval/blob/main/src/Makefile
|
||||
- QuickJS wrapped in C++: https://github.com/ftk/quickjspp
|
||||
|
||||
## Developing
|
||||
|
||||
This library is implemented in two languages: C (compiled to WASM with
|
||||
Emscripten), and Typescript.
|
||||
|
||||
### The C parts
|
||||
|
||||
The ./c directory contains C code that wraps the QuickJS C library (in ./quickjs).
|
||||
Public functions (those starting with `QTS_`) in ./c/interface.c are
|
||||
automatically exported to native code (via a generated header) and to
|
||||
Typescript (via a generated FFI class). See ./generate.ts for how this works.
|
||||
|
||||
The C code builds as both with `emscripten` (using `emcc`), to produce WASM (or
|
||||
ASM.js) and with `clang`. Build outputs are checked in, so you can iterate on
|
||||
the Javascript parts of the library without setting up the Emscripten toolchain.
|
||||
|
||||
Intermediate object files from QuickJS end up in ./build/quickjs/.
|
||||
|
||||
This project uses `emscripten 3.1.32`.
|
||||
|
||||
- On ARM64, you should install `emscripten` on your machine. For example on macOS, `brew install emscripten`.
|
||||
- If _the correct version of emcc_ is not in your PATH, compilation falls back to using Docker.
|
||||
On ARM64, this is 10-50x slower than native compilation, but it's just fine on x64.
|
||||
|
||||
Related NPM scripts:
|
||||
|
||||
- `yarn update-quickjs` will sync the ./quickjs folder with a
|
||||
github repo tracking the upstream QuickJS.
|
||||
- `yarn make-debug` will rebuild C outputs into ./build/wrapper
|
||||
- `yarn make-release` will rebuild C outputs in release mode, which is the mode
|
||||
that should be checked into the repo.
|
||||
|
||||
### The Typescript parts
|
||||
|
||||
The ./ts directory contains Typescript types and wraps the generated Emscripten
|
||||
FFI in a more usable interface.
|
||||
|
||||
You'll need `node` and `yarn`. Install dependencies with `yarn install`.
|
||||
|
||||
- `yarn build` produces ./dist.
|
||||
- `yarn test` runs the tests.
|
||||
- `yarn test --watch` watches for changes and re-runs the tests.
|
||||
|
||||
### Yarn updates
|
||||
|
||||
Just run `yarn set version from sources` to upgrade the Yarn release.
|
||||
819
Scripts/node_modules/@tootallnate/quickjs-emscripten/c/interface.c
generated
vendored
Normal file
819
Scripts/node_modules/@tootallnate/quickjs-emscripten/c/interface.c
generated
vendored
Normal file
@ -0,0 +1,819 @@
|
||||
/**
|
||||
* interface.c
|
||||
*
|
||||
* We primarily use JSValue* (pointer to JSValue) when communicating with the
|
||||
* host javascript environment, because pointers are trivial to use for calls
|
||||
* into emscripten because they're just a number!
|
||||
*
|
||||
* As with the quickjs.h API, a JSValueConst* value is "borrowed" and should
|
||||
* not be freed. A JSValue* is "owned" and should be freed by the owner.
|
||||
*
|
||||
* Functions starting with "QTS_" are exported by generate.ts to:
|
||||
* - interface.h for native C code.
|
||||
* - ffi.ts for emscripten.
|
||||
*
|
||||
* We support building the following build outputs:
|
||||
*
|
||||
* ## 1. Native machine code
|
||||
* For internal development testing purposes.
|
||||
*
|
||||
* ## 2. WASM via Emscripten
|
||||
* For general production use.
|
||||
*
|
||||
* ## 3. Experimental: Asyncified WASM via Emscripten with -s ASYNCIFY=1.
|
||||
* This variant supports treating async host Javascript calls as synchronous
|
||||
* from the perspective of the WASM c code.
|
||||
*
|
||||
* The way this works is described here:
|
||||
* https://emscripten.org/docs/porting/asyncify.html
|
||||
*
|
||||
* In this variant, any call into our C code could return a promise if it ended
|
||||
* up suspended. We mark the methods we suspect might suspend due to users' code
|
||||
* as returning MaybeAsync(T). This information is ignored for the regular
|
||||
* build.
|
||||
*/
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#include <math.h> // For NAN
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef QTS_SANITIZE_LEAK
|
||||
#include <sanitizer/lsan_interface.h>
|
||||
#endif
|
||||
|
||||
#include "../quickjs/cutils.h"
|
||||
#include "../quickjs/quickjs-libc.h"
|
||||
#include "../quickjs/quickjs.h"
|
||||
|
||||
#define PKG "quickjs-emscripten: "
|
||||
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
#define QTS_DEBUG(msg) qts_log(msg);
|
||||
#define QTS_DUMP(value) qts_dump(ctx, value);
|
||||
#else
|
||||
#define QTS_DEBUG(msg) ;
|
||||
#define QTS_DUMP(value) ;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Signal to our FFI code generator that this string argument should be passed as a pointer
|
||||
* allocated by the caller on the heap, not a JS string on the stack.
|
||||
* https://github.com/emscripten-core/emscripten/issues/6860#issuecomment-405818401
|
||||
*/
|
||||
#define BorrowedHeapChar const char
|
||||
#define OwnedHeapChar char
|
||||
#define JSBorrowedChar const char
|
||||
|
||||
/**
|
||||
* Signal to our FFI code generator that this function should be called
|
||||
* asynchronously when compiled with ASYNCIFY.
|
||||
*/
|
||||
#define MaybeAsync(T) T
|
||||
|
||||
/**
|
||||
* Signal to our FFI code generator that this function is only available in
|
||||
* ASYNCIFY builds.
|
||||
*/
|
||||
#define AsyncifyOnly(T) T
|
||||
|
||||
#define JSVoid void
|
||||
|
||||
#define EvalFlags int
|
||||
#define EvalDetectModule int
|
||||
|
||||
void qts_log(char *msg) {
|
||||
fputs(PKG, stderr);
|
||||
fputs(msg, stderr);
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
|
||||
void qts_dump(JSContext *ctx, JSValueConst value) {
|
||||
const char *str = JS_ToCString(ctx, value);
|
||||
if (!str) {
|
||||
QTS_DEBUG("QTS_DUMP: can't dump");
|
||||
return;
|
||||
}
|
||||
fputs(str, stderr);
|
||||
JS_FreeCString(ctx, str);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void copy_prop_if_needed(JSContext *ctx, JSValueConst dest, JSValueConst src, const char *prop_name) {
|
||||
JSAtom prop_atom = JS_NewAtom(ctx, prop_name);
|
||||
JSValue dest_prop = JS_GetProperty(ctx, dest, prop_atom);
|
||||
if (JS_IsUndefined(dest_prop)) {
|
||||
JSValue src_prop = JS_GetProperty(ctx, src, prop_atom);
|
||||
if (!JS_IsUndefined(src_prop) && !JS_IsException(src_prop)) {
|
||||
JS_SetProperty(ctx, dest, prop_atom, src_prop);
|
||||
}
|
||||
} else {
|
||||
JS_FreeValue(ctx, dest_prop);
|
||||
}
|
||||
JS_FreeAtom(ctx, prop_atom);
|
||||
}
|
||||
|
||||
JSValue *jsvalue_to_heap(JSValueConst value) {
|
||||
JSValue *result = malloc(sizeof(JSValue));
|
||||
if (result) {
|
||||
// Could be better optimized, but at -0z / -ftlo, it
|
||||
// appears to produce the same binary code as a memcpy.
|
||||
*result = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
JSValue *QTS_Throw(JSContext *ctx, JSValueConst *error) {
|
||||
JSValue copy = JS_DupValue(ctx, *error);
|
||||
return jsvalue_to_heap(JS_Throw(ctx, copy));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewError(JSContext *ctx) {
|
||||
return jsvalue_to_heap(JS_NewError(ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Memory limit. Set to -1 to disable.
|
||||
*/
|
||||
void QTS_RuntimeSetMemoryLimit(JSRuntime *rt, size_t limit) {
|
||||
JS_SetMemoryLimit(rt, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Memory diagnostics
|
||||
*/
|
||||
|
||||
JSValue *QTS_RuntimeComputeMemoryUsage(JSRuntime *rt, JSContext *ctx) {
|
||||
JSMemoryUsage s;
|
||||
JS_ComputeMemoryUsage(rt, &s);
|
||||
|
||||
// Note that we're going to allocate more memory just to report the memory usage.
|
||||
// A more sound approach would be to bind JSMemoryUsage struct directly - but that's
|
||||
// a lot of work. This should be okay in the mean time.
|
||||
JSValue result = JS_NewObject(ctx);
|
||||
|
||||
// Manually generated via editor-fu from JSMemoryUsage struct definition in quickjs.h
|
||||
JS_SetPropertyStr(ctx, result, "malloc_limit", JS_NewInt64(ctx, s.malloc_limit));
|
||||
JS_SetPropertyStr(ctx, result, "memory_used_size", JS_NewInt64(ctx, s.memory_used_size));
|
||||
JS_SetPropertyStr(ctx, result, "malloc_count", JS_NewInt64(ctx, s.malloc_count));
|
||||
JS_SetPropertyStr(ctx, result, "memory_used_count", JS_NewInt64(ctx, s.memory_used_count));
|
||||
JS_SetPropertyStr(ctx, result, "atom_count", JS_NewInt64(ctx, s.atom_count));
|
||||
JS_SetPropertyStr(ctx, result, "atom_size", JS_NewInt64(ctx, s.atom_size));
|
||||
JS_SetPropertyStr(ctx, result, "str_count", JS_NewInt64(ctx, s.str_count));
|
||||
JS_SetPropertyStr(ctx, result, "str_size", JS_NewInt64(ctx, s.str_size));
|
||||
JS_SetPropertyStr(ctx, result, "obj_count", JS_NewInt64(ctx, s.obj_count));
|
||||
JS_SetPropertyStr(ctx, result, "obj_size", JS_NewInt64(ctx, s.obj_size));
|
||||
JS_SetPropertyStr(ctx, result, "prop_count", JS_NewInt64(ctx, s.prop_count));
|
||||
JS_SetPropertyStr(ctx, result, "prop_size", JS_NewInt64(ctx, s.prop_size));
|
||||
JS_SetPropertyStr(ctx, result, "shape_count", JS_NewInt64(ctx, s.shape_count));
|
||||
JS_SetPropertyStr(ctx, result, "shape_size", JS_NewInt64(ctx, s.shape_size));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_count", JS_NewInt64(ctx, s.js_func_count));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_size", JS_NewInt64(ctx, s.js_func_size));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_code_size", JS_NewInt64(ctx, s.js_func_code_size));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_pc2line_count", JS_NewInt64(ctx, s.js_func_pc2line_count));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_pc2line_size", JS_NewInt64(ctx, s.js_func_pc2line_size));
|
||||
JS_SetPropertyStr(ctx, result, "c_func_count", JS_NewInt64(ctx, s.c_func_count));
|
||||
JS_SetPropertyStr(ctx, result, "array_count", JS_NewInt64(ctx, s.array_count));
|
||||
JS_SetPropertyStr(ctx, result, "fast_array_count", JS_NewInt64(ctx, s.fast_array_count));
|
||||
JS_SetPropertyStr(ctx, result, "fast_array_elements", JS_NewInt64(ctx, s.fast_array_elements));
|
||||
JS_SetPropertyStr(ctx, result, "binary_object_count", JS_NewInt64(ctx, s.binary_object_count));
|
||||
JS_SetPropertyStr(ctx, result, "binary_object_size", JS_NewInt64(ctx, s.binary_object_size));
|
||||
|
||||
return jsvalue_to_heap(result);
|
||||
}
|
||||
|
||||
OwnedHeapChar *QTS_RuntimeDumpMemoryUsage(JSRuntime *rt) {
|
||||
char *result = malloc(sizeof(char) * 1024);
|
||||
FILE *memfile = fmemopen(result, 1024, "w");
|
||||
JSMemoryUsage s;
|
||||
JS_ComputeMemoryUsage(rt, &s);
|
||||
JS_DumpMemoryUsage(memfile, &s, rt);
|
||||
fclose(memfile);
|
||||
return result;
|
||||
}
|
||||
|
||||
int QTS_RecoverableLeakCheck() {
|
||||
#ifdef QTS_SANITIZE_LEAK
|
||||
return __lsan_do_recoverable_leak_check();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int QTS_BuildIsSanitizeLeak() {
|
||||
#ifdef QTS_SANITIZE_LEAK
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef QTS_ASYNCIFY
|
||||
EM_JS(void, set_asyncify_stack_size, (size_t size), {
|
||||
Asyncify.StackSize = size || 81920;
|
||||
});
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the stack size limit, in bytes. Set to 0 to disable.
|
||||
*/
|
||||
void QTS_RuntimeSetMaxStackSize(JSRuntime *rt, size_t stack_size) {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
set_asyncify_stack_size(stack_size);
|
||||
#endif
|
||||
JS_SetMaxStackSize(rt, stack_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant pointers. Because we always use JSValue* from the host Javascript environment,
|
||||
* we need helper fuctions to return pointers to these constants.
|
||||
*/
|
||||
|
||||
JSValueConst QTS_Undefined = JS_UNDEFINED;
|
||||
JSValueConst *QTS_GetUndefined() {
|
||||
return &QTS_Undefined;
|
||||
}
|
||||
|
||||
JSValueConst QTS_Null = JS_NULL;
|
||||
JSValueConst *QTS_GetNull() {
|
||||
return &QTS_Null;
|
||||
}
|
||||
|
||||
JSValueConst QTS_False = JS_FALSE;
|
||||
JSValueConst *QTS_GetFalse() {
|
||||
return &QTS_False;
|
||||
}
|
||||
|
||||
JSValueConst QTS_True = JS_TRUE;
|
||||
JSValueConst *QTS_GetTrue() {
|
||||
return &QTS_True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard FFI functions
|
||||
*/
|
||||
|
||||
JSRuntime *QTS_NewRuntime() {
|
||||
return JS_NewRuntime();
|
||||
}
|
||||
|
||||
void QTS_FreeRuntime(JSRuntime *rt) {
|
||||
JS_FreeRuntime(rt);
|
||||
}
|
||||
|
||||
JSContext *QTS_NewContext(JSRuntime *rt) {
|
||||
return JS_NewContext(rt);
|
||||
}
|
||||
|
||||
void QTS_FreeContext(JSContext *ctx) {
|
||||
JS_FreeContext(ctx);
|
||||
}
|
||||
|
||||
void QTS_FreeValuePointer(JSContext *ctx, JSValue *value) {
|
||||
JS_FreeValue(ctx, *value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
void QTS_FreeValuePointerRuntime(JSRuntime *rt, JSValue *value) {
|
||||
JS_FreeValueRT(rt, *value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
void QTS_FreeVoidPointer(JSContext *ctx, JSVoid *ptr) {
|
||||
js_free(ctx, ptr);
|
||||
}
|
||||
|
||||
void QTS_FreeCString(JSContext *ctx, JSBorrowedChar *str) {
|
||||
JS_FreeCString(ctx, str);
|
||||
}
|
||||
|
||||
JSValue *QTS_DupValuePointer(JSContext *ctx, JSValueConst *val) {
|
||||
return jsvalue_to_heap(JS_DupValue(ctx, *val));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewObject(JSContext *ctx) {
|
||||
return jsvalue_to_heap(JS_NewObject(ctx));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewObjectProto(JSContext *ctx, JSValueConst *proto) {
|
||||
return jsvalue_to_heap(JS_NewObjectProto(ctx, *proto));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewArray(JSContext *ctx) {
|
||||
return jsvalue_to_heap(JS_NewArray(ctx));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewFloat64(JSContext *ctx, double num) {
|
||||
return jsvalue_to_heap(JS_NewFloat64(ctx, num));
|
||||
}
|
||||
|
||||
double QTS_GetFloat64(JSContext *ctx, JSValueConst *value) {
|
||||
double result = NAN;
|
||||
JS_ToFloat64(ctx, &result, *value);
|
||||
return result;
|
||||
}
|
||||
|
||||
JSValue *QTS_NewString(JSContext *ctx, BorrowedHeapChar *string) {
|
||||
return jsvalue_to_heap(JS_NewString(ctx, string));
|
||||
}
|
||||
|
||||
JSBorrowedChar *QTS_GetString(JSContext *ctx, JSValueConst *value) {
|
||||
return JS_ToCString(ctx, *value);
|
||||
}
|
||||
|
||||
JSValue qts_get_symbol_key(JSContext *ctx, JSValueConst *value) {
|
||||
JSValue global = JS_GetGlobalObject(ctx);
|
||||
JSValue Symbol = JS_GetPropertyStr(ctx, global, "Symbol");
|
||||
JS_FreeValue(ctx, global);
|
||||
|
||||
JSValue Symbol_keyFor = JS_GetPropertyStr(ctx, Symbol, "keyFor");
|
||||
JSValue key = JS_Call(ctx, Symbol_keyFor, Symbol, 1, value);
|
||||
JS_FreeValue(ctx, Symbol_keyFor);
|
||||
JS_FreeValue(ctx, Symbol);
|
||||
return key;
|
||||
}
|
||||
|
||||
JSValue *QTS_NewSymbol(JSContext *ctx, BorrowedHeapChar *description, int isGlobal) {
|
||||
JSValue global = JS_GetGlobalObject(ctx);
|
||||
JSValue Symbol = JS_GetPropertyStr(ctx, global, "Symbol");
|
||||
JS_FreeValue(ctx, global);
|
||||
JSValue descriptionValue = JS_NewString(ctx, description);
|
||||
JSValue symbol;
|
||||
|
||||
if (isGlobal != 0) {
|
||||
JSValue Symbol_for = JS_GetPropertyStr(ctx, Symbol, "for");
|
||||
symbol = JS_Call(ctx, Symbol_for, Symbol, 1, &descriptionValue);
|
||||
JS_FreeValue(ctx, descriptionValue);
|
||||
JS_FreeValue(ctx, Symbol_for);
|
||||
JS_FreeValue(ctx, Symbol);
|
||||
return jsvalue_to_heap(symbol);
|
||||
}
|
||||
|
||||
symbol = JS_Call(ctx, Symbol, JS_UNDEFINED, 1, &descriptionValue);
|
||||
JS_FreeValue(ctx, descriptionValue);
|
||||
JS_FreeValue(ctx, Symbol);
|
||||
|
||||
return jsvalue_to_heap(symbol);
|
||||
}
|
||||
|
||||
MaybeAsync(JSBorrowedChar *) QTS_GetSymbolDescriptionOrKey(JSContext *ctx, JSValueConst *value) {
|
||||
JSBorrowedChar *result;
|
||||
|
||||
JSValue key = qts_get_symbol_key(ctx, value);
|
||||
if (!JS_IsUndefined(key)) {
|
||||
result = JS_ToCString(ctx, key);
|
||||
JS_FreeValue(ctx, key);
|
||||
return result;
|
||||
}
|
||||
|
||||
JSValue description = JS_GetPropertyStr(ctx, *value, "description");
|
||||
result = JS_ToCString(ctx, description);
|
||||
JS_FreeValue(ctx, description);
|
||||
return result;
|
||||
}
|
||||
|
||||
int QTS_IsGlobalSymbol(JSContext *ctx, JSValueConst *value) {
|
||||
JSValue key = qts_get_symbol_key(ctx, value);
|
||||
int undefined = JS_IsUndefined(key);
|
||||
JS_FreeValue(ctx, key);
|
||||
|
||||
if (undefined) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int QTS_IsJobPending(JSRuntime *rt) {
|
||||
return JS_IsJobPending(rt);
|
||||
}
|
||||
|
||||
/*
|
||||
runs pending jobs (Promises/async functions) until it encounters
|
||||
an exception or it executed the passed maxJobsToExecute jobs.
|
||||
|
||||
Passing a negative value will run the loop until there are no more
|
||||
pending jobs or an exception happened
|
||||
|
||||
Returns the executed number of jobs or the exception encountered
|
||||
*/
|
||||
MaybeAsync(JSValue *) QTS_ExecutePendingJob(JSRuntime *rt, int maxJobsToExecute, JSContext **lastJobContext) {
|
||||
JSContext *pctx;
|
||||
int status = 1;
|
||||
int executed = 0;
|
||||
while (executed != maxJobsToExecute && status == 1) {
|
||||
status = JS_ExecutePendingJob(rt, &pctx);
|
||||
if (status == -1) {
|
||||
*lastJobContext = pctx;
|
||||
return jsvalue_to_heap(JS_GetException(pctx));
|
||||
} else if (status == 1) {
|
||||
*lastJobContext = pctx;
|
||||
executed++;
|
||||
}
|
||||
}
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "QTS_ExecutePendingJob(executed: %d, pctx: %p, lastJobExecuted: %p)", executed, pctx, *lastJobContext);
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
return jsvalue_to_heap(JS_NewFloat64(pctx, executed));
|
||||
}
|
||||
|
||||
MaybeAsync(JSValue *) QTS_GetProp(JSContext *ctx, JSValueConst *this_val, JSValueConst *prop_name) {
|
||||
JSAtom prop_atom = JS_ValueToAtom(ctx, *prop_name);
|
||||
JSValue prop_val = JS_GetProperty(ctx, *this_val, prop_atom);
|
||||
JS_FreeAtom(ctx, prop_atom);
|
||||
return jsvalue_to_heap(prop_val);
|
||||
}
|
||||
|
||||
MaybeAsync(void) QTS_SetProp(JSContext *ctx, JSValueConst *this_val, JSValueConst *prop_name, JSValueConst *prop_value) {
|
||||
JSAtom prop_atom = JS_ValueToAtom(ctx, *prop_name);
|
||||
JSValue extra_prop_value = JS_DupValue(ctx, *prop_value);
|
||||
// TODO: should we use DefineProperty internally if this object doesn't have the property yet?
|
||||
JS_SetProperty(ctx, *this_val, prop_atom, extra_prop_value); // consumes extra_prop_value
|
||||
JS_FreeAtom(ctx, prop_atom);
|
||||
}
|
||||
|
||||
void QTS_DefineProp(JSContext *ctx, JSValueConst *this_val, JSValueConst *prop_name, JSValueConst *prop_value, JSValueConst *get, JSValueConst *set, bool configurable, bool enumerable, bool has_value) {
|
||||
JSAtom prop_atom = JS_ValueToAtom(ctx, *prop_name);
|
||||
|
||||
int flags = 0;
|
||||
if (configurable) {
|
||||
flags = flags | JS_PROP_CONFIGURABLE;
|
||||
if (has_value) {
|
||||
flags = flags | JS_PROP_HAS_CONFIGURABLE;
|
||||
}
|
||||
}
|
||||
if (enumerable) {
|
||||
flags = flags | JS_PROP_ENUMERABLE;
|
||||
if (has_value) {
|
||||
flags = flags | JS_PROP_HAS_ENUMERABLE;
|
||||
}
|
||||
}
|
||||
if (!JS_IsUndefined(*get)) {
|
||||
flags = flags | JS_PROP_HAS_GET;
|
||||
}
|
||||
if (!JS_IsUndefined(*set)) {
|
||||
flags = flags | JS_PROP_HAS_SET;
|
||||
}
|
||||
if (has_value) {
|
||||
flags = flags | JS_PROP_HAS_VALUE;
|
||||
}
|
||||
|
||||
JS_DefineProperty(ctx, *this_val, prop_atom, *prop_value, *get, *set, flags);
|
||||
JS_FreeAtom(ctx, prop_atom);
|
||||
}
|
||||
|
||||
MaybeAsync(JSValue *) QTS_Call(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj, int argc, JSValueConst **argv_ptrs) {
|
||||
// convert array of pointers to array of values
|
||||
JSValueConst argv[argc];
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv[i] = *(argv_ptrs[i]);
|
||||
}
|
||||
|
||||
return jsvalue_to_heap(JS_Call(ctx, *func_obj, *this_obj, argc, argv));
|
||||
}
|
||||
|
||||
/**
|
||||
* If maybe_exception is an exception, get the error.
|
||||
* Otherwise, return NULL.
|
||||
*/
|
||||
JSValue *QTS_ResolveException(JSContext *ctx, JSValue *maybe_exception) {
|
||||
if (JS_IsException(*maybe_exception)) {
|
||||
return jsvalue_to_heap(JS_GetException(ctx));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MaybeAsync(JSBorrowedChar *) QTS_Dump(JSContext *ctx, JSValueConst *obj) {
|
||||
JSValue obj_json_value = JS_JSONStringify(ctx, *obj, JS_UNDEFINED, JS_UNDEFINED);
|
||||
if (!JS_IsException(obj_json_value)) {
|
||||
const char *obj_json_chars = JS_ToCString(ctx, obj_json_value);
|
||||
JS_FreeValue(ctx, obj_json_value);
|
||||
if (obj_json_chars != NULL) {
|
||||
JSValue enumerable_props = JS_ParseJSON(ctx, obj_json_chars, strlen(obj_json_chars), "<dump>");
|
||||
JS_FreeCString(ctx, obj_json_chars);
|
||||
if (!JS_IsException(enumerable_props)) {
|
||||
// Copy common non-enumerable props for different object types.
|
||||
// Errors:
|
||||
copy_prop_if_needed(ctx, enumerable_props, *obj, "name");
|
||||
copy_prop_if_needed(ctx, enumerable_props, *obj, "message");
|
||||
copy_prop_if_needed(ctx, enumerable_props, *obj, "stack");
|
||||
|
||||
// Serialize again.
|
||||
JSValue enumerable_json = JS_JSONStringify(ctx, enumerable_props, JS_UNDEFINED, JS_UNDEFINED);
|
||||
JS_FreeValue(ctx, enumerable_props);
|
||||
|
||||
JSBorrowedChar *result = QTS_GetString(ctx, &enumerable_json);
|
||||
JS_FreeValue(ctx, enumerable_json);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
qts_log("Error dumping JSON:");
|
||||
js_std_dump_error(ctx);
|
||||
#endif
|
||||
|
||||
// Fallback: convert to string
|
||||
return QTS_GetString(ctx, obj);
|
||||
}
|
||||
|
||||
MaybeAsync(JSValue *) QTS_Eval(JSContext *ctx, BorrowedHeapChar *js_code, const char *filename, EvalDetectModule detectModule, EvalFlags evalFlags) {
|
||||
size_t js_code_len = strlen(js_code);
|
||||
|
||||
if (detectModule) {
|
||||
if (JS_DetectModule((const char *)js_code, js_code_len)) {
|
||||
QTS_DEBUG("QTS_Eval: Detected module = true");
|
||||
evalFlags |= JS_EVAL_TYPE_MODULE;
|
||||
} else {
|
||||
QTS_DEBUG("QTS_Eval: Detected module = false");
|
||||
}
|
||||
} else {
|
||||
QTS_DEBUG("QTS_Eval: do not detect module");
|
||||
}
|
||||
|
||||
return jsvalue_to_heap(JS_Eval(ctx, js_code, strlen(js_code), filename, evalFlags));
|
||||
}
|
||||
|
||||
OwnedHeapChar *QTS_Typeof(JSContext *ctx, JSValueConst *value) {
|
||||
const char *result = "unknown";
|
||||
uint32_t tag = JS_VALUE_GET_TAG(*value);
|
||||
|
||||
if (JS_IsNumber(*value)) {
|
||||
result = "number";
|
||||
} else if (JS_IsBigInt(ctx, *value)) {
|
||||
result = "bigint";
|
||||
} else if (JS_IsBigFloat(*value)) {
|
||||
result = "bigfloat";
|
||||
} else if (JS_IsBigDecimal(*value)) {
|
||||
result = "bigdecimal";
|
||||
} else if (JS_IsFunction(ctx, *value)) {
|
||||
result = "function";
|
||||
} else if (JS_IsBool(*value)) {
|
||||
result = "boolean";
|
||||
} else if (JS_IsNull(*value)) {
|
||||
result = "object";
|
||||
} else if (JS_IsUndefined(*value)) {
|
||||
result = "undefined";
|
||||
} else if (JS_IsUninitialized(*value)) {
|
||||
result = "undefined";
|
||||
} else if (JS_IsString(*value)) {
|
||||
result = "string";
|
||||
} else if (JS_IsSymbol(*value)) {
|
||||
result = "symbol";
|
||||
} else if (JS_IsObject(*value)) {
|
||||
result = "object";
|
||||
}
|
||||
|
||||
char *out = strdup(result);
|
||||
return out;
|
||||
}
|
||||
|
||||
JSValue *QTS_GetGlobalObject(JSContext *ctx) {
|
||||
return jsvalue_to_heap(JS_GetGlobalObject(ctx));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewPromiseCapability(JSContext *ctx, JSValue **resolve_funcs_out) {
|
||||
JSValue resolve_funcs[2];
|
||||
JSValue promise = JS_NewPromiseCapability(ctx, resolve_funcs);
|
||||
resolve_funcs_out[0] = jsvalue_to_heap(resolve_funcs[0]);
|
||||
resolve_funcs_out[1] = jsvalue_to_heap(resolve_funcs[1]);
|
||||
return jsvalue_to_heap(promise);
|
||||
}
|
||||
|
||||
void QTS_TestStringArg(const char *string) {
|
||||
// pass
|
||||
}
|
||||
|
||||
int QTS_BuildIsDebug() {
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int QTS_BuildIsAsyncify() {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Module loading helpers
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// C -> Host Callbacks
|
||||
// Note: inside EM_JS, we need to use ['...'] subscript syntax for accessing JS
|
||||
// objects, because in optimized builds, Closure compiler will mangle all the
|
||||
// names.
|
||||
|
||||
// -------------------
|
||||
// function: C -> Host
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(MaybeAsync(JSValue *), qts_host_call_function, (JSContext * ctx, JSValueConst *this_ptr, int argc, JSValueConst *argv, uint32_t magic_func_id), {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
const asyncify = {['handleSleep'] : Asyncify.handleSleep};
|
||||
#else
|
||||
const asyncify = undefined;
|
||||
#endif
|
||||
return Module['callbacks']['callFunction'](asyncify, ctx, this_ptr, argc, argv, magic_func_id);
|
||||
});
|
||||
#endif
|
||||
|
||||
// Function: QuickJS -> C
|
||||
JSValue qts_call_function(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) {
|
||||
JSValue *result_ptr = qts_host_call_function(ctx, &this_val, argc, argv, magic);
|
||||
if (result_ptr == NULL) {
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
JSValue result = *result_ptr;
|
||||
free(result_ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Function: Host -> QuickJS
|
||||
JSValue *QTS_NewFunction(JSContext *ctx, uint32_t func_id, const char *name) {
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "new_function(name: %s, magic: %d)", name, func_id);
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
JSValue func_obj = JS_NewCFunctionMagic(
|
||||
/* context */ ctx,
|
||||
/* JSCFunctionMagic* */ &qts_call_function,
|
||||
/* name */ name,
|
||||
/* min argc */ 0,
|
||||
/* function type */ JS_CFUNC_generic_magic,
|
||||
/* magic: fn id */ func_id);
|
||||
return jsvalue_to_heap(func_obj);
|
||||
}
|
||||
|
||||
JSValueConst *QTS_ArgvGetJSValueConstPointer(JSValueConst *argv, int index) {
|
||||
return &argv[index];
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// interrupt: C -> Host
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(int, qts_host_interrupt_handler, (JSRuntime * rt), {
|
||||
// Async not supported here.
|
||||
// #ifdef QTS_ASYNCIFY
|
||||
// const asyncify = Asyncify;
|
||||
// #else
|
||||
const asyncify = undefined;
|
||||
// #endif
|
||||
return Module['callbacks']['shouldInterrupt'](asyncify, rt);
|
||||
});
|
||||
#endif
|
||||
|
||||
// interrupt: QuickJS -> C
|
||||
int qts_interrupt_handler(JSRuntime *rt, void *_unused) {
|
||||
return qts_host_interrupt_handler(rt);
|
||||
}
|
||||
|
||||
// interrupt: Host -> QuickJS
|
||||
void QTS_RuntimeEnableInterruptHandler(JSRuntime *rt) {
|
||||
JS_SetInterruptHandler(rt, &qts_interrupt_handler, NULL);
|
||||
}
|
||||
|
||||
void QTS_RuntimeDisableInterruptHandler(JSRuntime *rt) {
|
||||
JS_SetInterruptHandler(rt, NULL, NULL);
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// load module: C -> Host
|
||||
// TODO: a future version can support host returning JSModuleDef* directly;
|
||||
// for now we only support loading module source code.
|
||||
|
||||
/*
|
||||
The module loading model under ASYNCIFY is convoluted. We need to make sure we
|
||||
never have an async request running concurrently for loading modules.
|
||||
|
||||
The first implemenation looked like this:
|
||||
|
||||
C HOST SUSPENDED
|
||||
qts_host_load_module(name) ------> false
|
||||
call rt.loadModule(name) false
|
||||
Start async load module false
|
||||
Suspend C true
|
||||
Async load complete true
|
||||
< --------------- QTS_CompileModule(source) true
|
||||
QTS_Eval(source, COMPILE_ONLY) true
|
||||
Loaded module has import true
|
||||
qts_host_load_module(dep) -------> true
|
||||
call rt.loadModule(dep) true
|
||||
Start async load module true
|
||||
ALREADY SUSPENDED, CRASH
|
||||
|
||||
We can solve this in two different ways:
|
||||
|
||||
1. Return to C as soon as we async load the module source.
|
||||
That way, we unsuspend before calling QTS_CompileModule.
|
||||
2. Once we load the module, use a new API to detect and async
|
||||
load the module's downstream dependencies. This way
|
||||
they're loaded synchronously so we don't need to suspend "again".
|
||||
|
||||
Probably we could optimize (2) to make it more performant, eg with parallel
|
||||
loading, but (1) seems much easier to implement in the sort run.
|
||||
*/
|
||||
|
||||
JSModuleDef *qts_compile_module(JSContext *ctx, const char *module_name, BorrowedHeapChar *module_body) {
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "QTS_CompileModule(ctx: %p, name: %s, bodyLength: %lu)", ctx, module_name, strlen(module_body));
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
JSValue func_val = JS_Eval(ctx, module_body, strlen(module_body), module_name, JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
|
||||
if (JS_IsException(func_val)) {
|
||||
return NULL;
|
||||
}
|
||||
// TODO: Is exception ok?
|
||||
// TODO: set import.meta?
|
||||
JSModuleDef *module = JS_VALUE_GET_PTR(func_val);
|
||||
JS_FreeValue(ctx, func_val);
|
||||
return module;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(MaybeAsync(char *), qts_host_load_module_source, (JSRuntime * rt, JSContext *ctx, const char *module_name), {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
const asyncify = {['handleSleep'] : Asyncify.handleSleep};
|
||||
#else
|
||||
const asyncify = undefined;
|
||||
#endif
|
||||
// https://emscripten.org/docs/api_reference/preamble.js.html#UTF8ToString
|
||||
const moduleNameString = UTF8ToString(module_name);
|
||||
return Module['callbacks']['loadModuleSource'](asyncify, rt, ctx, moduleNameString);
|
||||
});
|
||||
|
||||
EM_JS(MaybeAsync(char *), qts_host_normalize_module, (JSRuntime * rt, JSContext *ctx, const char *module_base_name, const char *module_name), {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
const asyncify = {['handleSleep'] : Asyncify.handleSleep};
|
||||
#else
|
||||
const asyncify = undefined;
|
||||
#endif
|
||||
// https://emscripten.org/docs/api_reference/preamble.js.html#UTF8ToString
|
||||
const moduleBaseNameString = UTF8ToString(module_base_name);
|
||||
const moduleNameString = UTF8ToString(module_name);
|
||||
return Module['callbacks']['normalizeModule'](asyncify, rt, ctx, moduleBaseNameString, moduleNameString);
|
||||
});
|
||||
#endif
|
||||
|
||||
// load module: QuickJS -> C
|
||||
// See js_module_loader in quickjs/quickjs-libc.c:567
|
||||
JSModuleDef *qts_load_module(JSContext *ctx, const char *module_name, void *_unused) {
|
||||
JSRuntime *rt = JS_GetRuntime(ctx);
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "qts_load_module(rt: %p, ctx: %p, name: %s)", rt, ctx, module_name);
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
char *module_source = qts_host_load_module_source(rt, ctx, module_name);
|
||||
if (module_source == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSModuleDef *module = qts_compile_module(ctx, module_name, module_source);
|
||||
free(module_source);
|
||||
return module;
|
||||
}
|
||||
|
||||
char *qts_normalize_module(JSContext *ctx, const char *module_base_name, const char *module_name, void *_unused) {
|
||||
JSRuntime *rt = JS_GetRuntime(ctx);
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "qts_normalize_module(rt: %p, ctx: %p, base_name: %s, name: %s)", rt, ctx, module_base_name, module_name);
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
char *em_module_name = qts_host_normalize_module(rt, ctx, module_base_name, module_name);
|
||||
char *js_module_name = js_strdup(ctx, em_module_name);
|
||||
free(em_module_name);
|
||||
return js_module_name;
|
||||
}
|
||||
|
||||
// Load module: Host -> QuickJS
|
||||
void QTS_RuntimeEnableModuleLoader(JSRuntime *rt, int use_custom_normalize) {
|
||||
JSModuleNormalizeFunc *module_normalize = NULL; /* use default name normalizer */
|
||||
if (use_custom_normalize) {
|
||||
module_normalize = &qts_normalize_module;
|
||||
}
|
||||
JS_SetModuleLoaderFunc(rt, module_normalize, &qts_load_module, NULL);
|
||||
}
|
||||
|
||||
void QTS_RuntimeDisableModuleLoader(JSRuntime *rt) {
|
||||
JS_SetModuleLoaderFunc(rt, NULL, NULL, NULL);
|
||||
}
|
||||
24
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.d.ts
generated
vendored
Normal file
24
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.d.ts
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
declare function awaitYield<T>(value: T | Promise<T>): Generator<T | Promise<T>, T, T>;
|
||||
declare function awaitYieldOf<T, Yielded>(generator: Generator<Yielded | Promise<Yielded>, T, Yielded>): Generator<T | Promise<T>, T, T>;
|
||||
export type AwaitYield = typeof awaitYield & {
|
||||
of: typeof awaitYieldOf;
|
||||
};
|
||||
/**
|
||||
* Create a function that may or may not be async, using a generator
|
||||
*
|
||||
* Within the generator, call `yield* awaited(maybePromise)` to await a value
|
||||
* that may or may not be a promise.
|
||||
*
|
||||
* If the inner function never yields a promise, it will return synchronously.
|
||||
*/
|
||||
export declare function maybeAsyncFn<
|
||||
/** Function arguments */
|
||||
Args extends any[], This,
|
||||
/** Function return type */
|
||||
Return,
|
||||
/** Yields to unwrap */
|
||||
Yielded>(that: This, fn: (this: This, awaited: AwaitYield, ...args: Args) => Generator<Yielded | Promise<Yielded>, Return, Yielded>): (...args: Args) => Return | Promise<Return>;
|
||||
export type MaybeAsyncBlock<Return, This, Yielded, Args extends any[] = []> = (this: This, awaited: AwaitYield, ...args: Args) => Generator<Yielded | Promise<Yielded>, Return, Yielded>;
|
||||
export declare function maybeAsync<Return, This, Yielded>(that: This, startGenerator: (this: This, await: AwaitYield) => Generator<Yielded | Promise<Yielded>, Return, Yielded>): Return | Promise<Return>;
|
||||
export declare function awaitEachYieldedPromise<Yielded, Returned>(gen: Generator<Yielded | Promise<Yielded>, Returned, Yielded>): Returned | Promise<Returned>;
|
||||
export {};
|
||||
53
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js
generated
vendored
Normal file
53
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.awaitEachYieldedPromise = exports.maybeAsync = exports.maybeAsyncFn = void 0;
|
||||
function* awaitYield(value) {
|
||||
return (yield value);
|
||||
}
|
||||
function awaitYieldOf(generator) {
|
||||
return awaitYield(awaitEachYieldedPromise(generator));
|
||||
}
|
||||
const AwaitYield = awaitYield;
|
||||
AwaitYield.of = awaitYieldOf;
|
||||
/**
|
||||
* Create a function that may or may not be async, using a generator
|
||||
*
|
||||
* Within the generator, call `yield* awaited(maybePromise)` to await a value
|
||||
* that may or may not be a promise.
|
||||
*
|
||||
* If the inner function never yields a promise, it will return synchronously.
|
||||
*/
|
||||
function maybeAsyncFn(that, fn) {
|
||||
return (...args) => {
|
||||
const generator = fn.call(that, AwaitYield, ...args);
|
||||
return awaitEachYieldedPromise(generator);
|
||||
};
|
||||
}
|
||||
exports.maybeAsyncFn = maybeAsyncFn;
|
||||
class Example {
|
||||
constructor() {
|
||||
this.maybeAsyncMethod = maybeAsyncFn(this, function* (awaited, a) {
|
||||
yield* awaited(new Promise((resolve) => setTimeout(resolve, a)));
|
||||
return 5;
|
||||
});
|
||||
}
|
||||
}
|
||||
function maybeAsync(that, startGenerator) {
|
||||
const generator = startGenerator.call(that, AwaitYield);
|
||||
return awaitEachYieldedPromise(generator);
|
||||
}
|
||||
exports.maybeAsync = maybeAsync;
|
||||
function awaitEachYieldedPromise(gen) {
|
||||
function handleNextStep(step) {
|
||||
if (step.done) {
|
||||
return step.value;
|
||||
}
|
||||
if (step.value instanceof Promise) {
|
||||
return step.value.then((value) => handleNextStep(gen.next(value)), (error) => handleNextStep(gen.throw(error)));
|
||||
}
|
||||
return handleNextStep(gen.next(step.value));
|
||||
}
|
||||
return handleNextStep(gen.next());
|
||||
}
|
||||
exports.awaitEachYieldedPromise = awaitEachYieldedPromise;
|
||||
//# sourceMappingURL=asyncify-helpers.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"asyncify-helpers.js","sourceRoot":"","sources":["../ts/asyncify-helpers.ts"],"names":[],"mappings":";;;AAAA,QAAQ,CAAC,CAAC,UAAU,CAAI,KAAqB;IAC3C,OAAO,CAAC,MAAM,KAAK,CAAM,CAAA;AAC3B,CAAC;AAED,SAAS,YAAY,CACnB,SAA4D;IAE5D,OAAO,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAA;AACvD,CAAC;AAMD,MAAM,UAAU,GAAe,UAAwB,CAAA;AACvD,UAAU,CAAC,EAAE,GAAG,YAAY,CAAA;AAE5B;;;;;;;GAOG;AACH,SAAgB,YAAY,CAS1B,IAAU,EACV,EAI2D;IAE3D,OAAO,CAAC,GAAG,IAAU,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,CAAA;QACpD,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAA;IAC3C,CAAC,CAAA;AACH,CAAC;AApBD,oCAoBC;AAED,MAAM,OAAO;IAAb;QACU,qBAAgB,GAAG,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAS;YACzE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;YAChE,OAAO,CAAC,CAAA;QACV,CAAC,CAAC,CAAA;IACJ,CAAC;CAAA;AAQD,SAAgB,UAAU,CACxB,IAAU,EACV,cAG2D;IAE3D,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACvD,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAA;AAC3C,CAAC;AATD,gCASC;AAED,SAAgB,uBAAuB,CACrC,GAA6D;IAI7D,SAAS,cAAc,CAAC,IAAgB;QACtC,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,OAAO,IAAI,CAAC,KAAK,CAAA;SAClB;QAED,IAAI,IAAI,CAAC,KAAK,YAAY,OAAO,EAAE;YACjC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CACpB,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC1C,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAC5C,CAAA;SACF;QAED,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;AACnC,CAAC;AArBD,0DAqBC","sourcesContent":["function* awaitYield<T>(value: T | Promise<T>) {\n return (yield value) as T\n}\n\nfunction awaitYieldOf<T, Yielded>(\n generator: Generator<Yielded | Promise<Yielded>, T, Yielded>\n): Generator<T | Promise<T>, T, T> {\n return awaitYield(awaitEachYieldedPromise(generator))\n}\n\nexport type AwaitYield = typeof awaitYield & {\n of: typeof awaitYieldOf\n}\n\nconst AwaitYield: AwaitYield = awaitYield as AwaitYield\nAwaitYield.of = awaitYieldOf\n\n/**\n * Create a function that may or may not be async, using a generator\n *\n * Within the generator, call `yield* awaited(maybePromise)` to await a value\n * that may or may not be a promise.\n *\n * If the inner function never yields a promise, it will return synchronously.\n */\nexport function maybeAsyncFn<\n /** Function arguments */\n Args extends any[],\n This,\n /** Function return type */\n Return,\n /** Yields to unwrap */\n Yielded\n>(\n that: This,\n fn: (\n this: This,\n awaited: AwaitYield,\n ...args: Args\n ) => Generator<Yielded | Promise<Yielded>, Return, Yielded>\n): (...args: Args) => Return | Promise<Return> {\n return (...args: Args) => {\n const generator = fn.call(that, AwaitYield, ...args)\n return awaitEachYieldedPromise(generator)\n }\n}\n\nclass Example {\n private maybeAsyncMethod = maybeAsyncFn(this, function* (awaited, a: number) {\n yield* awaited(new Promise((resolve) => setTimeout(resolve, a)))\n return 5\n })\n}\n\nexport type MaybeAsyncBlock<Return, This, Yielded, Args extends any[] = []> = (\n this: This,\n awaited: AwaitYield,\n ...args: Args\n) => Generator<Yielded | Promise<Yielded>, Return, Yielded>\n\nexport function maybeAsync<Return, This, Yielded>(\n that: This,\n startGenerator: (\n this: This,\n await: AwaitYield\n ) => Generator<Yielded | Promise<Yielded>, Return, Yielded>\n): Return | Promise<Return> {\n const generator = startGenerator.call(that, AwaitYield)\n return awaitEachYieldedPromise(generator)\n}\n\nexport function awaitEachYieldedPromise<Yielded, Returned>(\n gen: Generator<Yielded | Promise<Yielded>, Returned, Yielded>\n): Returned | Promise<Returned> {\n type NextResult = ReturnType<typeof gen.next>\n\n function handleNextStep(step: NextResult): Returned | Promise<Returned> {\n if (step.done) {\n return step.value\n }\n\n if (step.value instanceof Promise) {\n return step.value.then(\n (value) => handleNextStep(gen.next(value)),\n (error) => handleNextStep(gen.throw(error))\n )\n }\n\n return handleNextStep(gen.next(step.value))\n }\n\n return handleNextStep(gen.next())\n}\n"]}
|
||||
48
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.d.ts
generated
vendored
Normal file
48
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.d.ts
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import { QuickJSContext } from "./context";
|
||||
import { QuickJSAsyncEmscriptenModule } from "./emscripten-types";
|
||||
import { QuickJSAsyncFFI } from "./variants";
|
||||
import { JSRuntimePointer } from "./types-ffi";
|
||||
import { Lifetime } from "./lifetime";
|
||||
import { QuickJSModuleCallbacks } from "./module";
|
||||
import { QuickJSAsyncRuntime } from "./runtime-asyncify";
|
||||
import { ContextEvalOptions, QuickJSHandle } from "./types";
|
||||
import { VmCallResult } from "./vm-interface";
|
||||
export type AsyncFunctionImplementation = (this: QuickJSHandle, ...args: QuickJSHandle[]) => Promise<QuickJSHandle | VmCallResult<QuickJSHandle> | void>;
|
||||
/**
|
||||
* Asyncified version of [[QuickJSContext]].
|
||||
*
|
||||
* *Asyncify* allows normally synchronous code to wait for asynchronous Promises
|
||||
* or callbacks. The asyncified version of QuickJSContext can wait for async
|
||||
* host functions as though they were synchronous.
|
||||
*/
|
||||
export declare class QuickJSAsyncContext extends QuickJSContext {
|
||||
runtime: QuickJSAsyncRuntime;
|
||||
/** @private */
|
||||
protected module: QuickJSAsyncEmscriptenModule;
|
||||
/** @private */
|
||||
protected ffi: QuickJSAsyncFFI;
|
||||
/** @private */
|
||||
protected rt: Lifetime<JSRuntimePointer>;
|
||||
/** @private */
|
||||
protected callbacks: QuickJSModuleCallbacks;
|
||||
/**
|
||||
* Asyncified version of [[evalCode]].
|
||||
*/
|
||||
evalCodeAsync(code: string, filename?: string,
|
||||
/** See [[EvalFlags]] for number semantics */
|
||||
options?: number | ContextEvalOptions): Promise<VmCallResult<QuickJSHandle>>;
|
||||
/**
|
||||
* Similar to [[newFunction]].
|
||||
* Convert an async host Javascript function into a synchronous QuickJS function value.
|
||||
*
|
||||
* Whenever QuickJS calls this function, the VM's stack will be unwound while
|
||||
* waiting the async function to complete, and then restored when the returned
|
||||
* promise resolves.
|
||||
*
|
||||
* Asyncified functions must never call other asyncified functions or
|
||||
* `import`, even indirectly, because the stack cannot be unwound twice.
|
||||
*
|
||||
* See [Emscripten's docs on Asyncify](https://emscripten.org/docs/porting/asyncify.html).
|
||||
*/
|
||||
newAsyncifiedFunction(name: string, fn: AsyncFunctionImplementation): QuickJSHandle;
|
||||
}
|
||||
58
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js
generated
vendored
Normal file
58
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSAsyncContext = void 0;
|
||||
const context_1 = require("./context");
|
||||
const debug_1 = require("./debug");
|
||||
const types_1 = require("./types");
|
||||
/**
|
||||
* Asyncified version of [[QuickJSContext]].
|
||||
*
|
||||
* *Asyncify* allows normally synchronous code to wait for asynchronous Promises
|
||||
* or callbacks. The asyncified version of QuickJSContext can wait for async
|
||||
* host functions as though they were synchronous.
|
||||
*/
|
||||
class QuickJSAsyncContext extends context_1.QuickJSContext {
|
||||
/**
|
||||
* Asyncified version of [[evalCode]].
|
||||
*/
|
||||
async evalCodeAsync(code, filename = "eval.js",
|
||||
/** See [[EvalFlags]] for number semantics */
|
||||
options) {
|
||||
const detectModule = (options === undefined ? 1 : 0);
|
||||
const flags = (0, types_1.evalOptionsToFlags)(options);
|
||||
let resultPtr = 0;
|
||||
try {
|
||||
resultPtr = await this.memory
|
||||
.newHeapCharPointer(code)
|
||||
.consume((charHandle) => this.ffi.QTS_Eval_MaybeAsync(this.ctx.value, charHandle.value, filename, detectModule, flags));
|
||||
}
|
||||
catch (error) {
|
||||
(0, debug_1.debugLog)("QTS_Eval_MaybeAsync threw", error);
|
||||
throw error;
|
||||
}
|
||||
const errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr);
|
||||
if (errorPtr) {
|
||||
this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr);
|
||||
return { error: this.memory.heapValueHandle(errorPtr) };
|
||||
}
|
||||
return { value: this.memory.heapValueHandle(resultPtr) };
|
||||
}
|
||||
/**
|
||||
* Similar to [[newFunction]].
|
||||
* Convert an async host Javascript function into a synchronous QuickJS function value.
|
||||
*
|
||||
* Whenever QuickJS calls this function, the VM's stack will be unwound while
|
||||
* waiting the async function to complete, and then restored when the returned
|
||||
* promise resolves.
|
||||
*
|
||||
* Asyncified functions must never call other asyncified functions or
|
||||
* `import`, even indirectly, because the stack cannot be unwound twice.
|
||||
*
|
||||
* See [Emscripten's docs on Asyncify](https://emscripten.org/docs/porting/asyncify.html).
|
||||
*/
|
||||
newAsyncifiedFunction(name, fn) {
|
||||
return this.newFunction(name, fn);
|
||||
}
|
||||
}
|
||||
exports.QuickJSAsyncContext = QuickJSAsyncContext;
|
||||
//# sourceMappingURL=context-asyncify.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"context-asyncify.js","sourceRoot":"","sources":["../ts/context-asyncify.ts"],"names":[],"mappings":";;;AAAA,uCAA0C;AAC1C,mCAAkC;AAOlC,mCAA+E;AAQ/E;;;;;;GAMG;AACH,MAAa,mBAAoB,SAAQ,wBAAc;IAWrD;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,IAAY,EACZ,WAAmB,SAAS;IAC5B,6CAA6C;IAC7C,OAAqC;QAErC,MAAM,YAAY,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAqB,CAAA;QACxE,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,OAAO,CAAc,CAAA;QACtD,IAAI,SAAS,GAAG,CAAmB,CAAA;QACnC,IAAI;YACF,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM;iBAC1B,kBAAkB,CAAC,IAAI,CAAC;iBACxB,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CACtB,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAC1B,IAAI,CAAC,GAAG,CAAC,KAAK,EACd,UAAU,CAAC,KAAK,EAChB,QAAQ,EACR,YAAY,EACZ,KAAK,CACN,CACF,CAAA;SACJ;QAAC,OAAO,KAAK,EAAE;YACd,IAAA,gBAAQ,EAAC,2BAA2B,EAAE,KAAK,CAAC,CAAA;YAC5C,MAAM,KAAK,CAAA;SACZ;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QACzE,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;YACxD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAA;SACxD;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAA;IAC1D,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,qBAAqB,CAAC,IAAY,EAAE,EAA+B;QACjE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAS,CAAC,CAAA;IAC1C,CAAC;CACF;AA/DD,kDA+DC","sourcesContent":["import { QuickJSContext } from \"./context\"\nimport { debugLog } from \"./debug\"\nimport { QuickJSAsyncEmscriptenModule } from \"./emscripten-types\"\nimport { QuickJSAsyncFFI } from \"./variants\"\nimport { EvalDetectModule, EvalFlags, JSRuntimePointer, JSValuePointer } from \"./types-ffi\"\nimport { Lifetime } from \"./lifetime\"\nimport { QuickJSModuleCallbacks } from \"./module\"\nimport { QuickJSAsyncRuntime } from \"./runtime-asyncify\"\nimport { ContextEvalOptions, evalOptionsToFlags, QuickJSHandle } from \"./types\"\nimport { VmCallResult } from \"./vm-interface\"\n\nexport type AsyncFunctionImplementation = (\n this: QuickJSHandle,\n ...args: QuickJSHandle[]\n) => Promise<QuickJSHandle | VmCallResult<QuickJSHandle> | void>\n\n/**\n * Asyncified version of [[QuickJSContext]].\n *\n * *Asyncify* allows normally synchronous code to wait for asynchronous Promises\n * or callbacks. The asyncified version of QuickJSContext can wait for async\n * host functions as though they were synchronous.\n */\nexport class QuickJSAsyncContext extends QuickJSContext {\n public declare runtime: QuickJSAsyncRuntime\n /** @private */\n protected declare module: QuickJSAsyncEmscriptenModule\n /** @private */\n protected declare ffi: QuickJSAsyncFFI\n /** @private */\n protected declare rt: Lifetime<JSRuntimePointer>\n /** @private */\n protected declare callbacks: QuickJSModuleCallbacks\n\n /**\n * Asyncified version of [[evalCode]].\n */\n async evalCodeAsync(\n code: string,\n filename: string = \"eval.js\",\n /** See [[EvalFlags]] for number semantics */\n options?: number | ContextEvalOptions\n ): Promise<VmCallResult<QuickJSHandle>> {\n const detectModule = (options === undefined ? 1 : 0) as EvalDetectModule\n const flags = evalOptionsToFlags(options) as EvalFlags\n let resultPtr = 0 as JSValuePointer\n try {\n resultPtr = await this.memory\n .newHeapCharPointer(code)\n .consume((charHandle) =>\n this.ffi.QTS_Eval_MaybeAsync(\n this.ctx.value,\n charHandle.value,\n filename,\n detectModule,\n flags\n )\n )\n } catch (error) {\n debugLog(\"QTS_Eval_MaybeAsync threw\", error)\n throw error\n }\n const errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr)\n if (errorPtr) {\n this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr)\n return { error: this.memory.heapValueHandle(errorPtr) }\n }\n return { value: this.memory.heapValueHandle(resultPtr) }\n }\n\n /**\n * Similar to [[newFunction]].\n * Convert an async host Javascript function into a synchronous QuickJS function value.\n *\n * Whenever QuickJS calls this function, the VM's stack will be unwound while\n * waiting the async function to complete, and then restored when the returned\n * promise resolves.\n *\n * Asyncified functions must never call other asyncified functions or\n * `import`, even indirectly, because the stack cannot be unwound twice.\n *\n * See [Emscripten's docs on Asyncify](https://emscripten.org/docs/porting/asyncify.html).\n */\n newAsyncifiedFunction(name: string, fn: AsyncFunctionImplementation): QuickJSHandle {\n return this.newFunction(name, fn as any)\n }\n}\n"]}
|
||||
371
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.d.ts
generated
vendored
Normal file
371
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.d.ts
generated
vendored
Normal file
@ -0,0 +1,371 @@
|
||||
import { QuickJSDeferredPromise } from "./deferred-promise";
|
||||
import type { EitherModule } from "./emscripten-types";
|
||||
import { JSBorrowedCharPointer, JSContextPointer, JSRuntimePointer, JSValueConstPointer, JSValuePointer } from "./types-ffi";
|
||||
import { Disposable, Lifetime, Scope } from "./lifetime";
|
||||
import { ModuleMemory } from "./memory";
|
||||
import { QuickJSModuleCallbacks } from "./module";
|
||||
import { QuickJSRuntime } from "./runtime";
|
||||
import { ContextEvalOptions, EitherFFI, JSValue, PromiseExecutor, QuickJSHandle } from "./types";
|
||||
import { LowLevelJavascriptVm, SuccessOrFail, VmCallResult, VmFunctionImplementation, VmPropertyDescriptor } from "./vm-interface";
|
||||
/**
|
||||
* Property key for getting or setting a property on a handle with
|
||||
* [[QuickJSContext.getProp]], [[QuickJSContext.setProp]], or [[QuickJSContext.defineProp]].
|
||||
*/
|
||||
export type QuickJSPropertyKey = number | string | QuickJSHandle;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
declare class ContextMemory extends ModuleMemory implements Disposable {
|
||||
readonly owner: QuickJSRuntime;
|
||||
readonly ctx: Lifetime<JSContextPointer>;
|
||||
readonly rt: Lifetime<JSRuntimePointer>;
|
||||
readonly module: EitherModule;
|
||||
readonly ffi: EitherFFI;
|
||||
readonly scope: Scope;
|
||||
/** @private */
|
||||
constructor(args: {
|
||||
owner: QuickJSRuntime;
|
||||
module: EitherModule;
|
||||
ffi: EitherFFI;
|
||||
ctx: Lifetime<JSContextPointer>;
|
||||
rt: Lifetime<JSRuntimePointer>;
|
||||
ownedLifetimes?: Disposable[];
|
||||
});
|
||||
get alive(): boolean;
|
||||
dispose(): void;
|
||||
/**
|
||||
* Track `lifetime` so that it is disposed when this scope is disposed.
|
||||
*/
|
||||
manage<T extends Disposable>(lifetime: T): T;
|
||||
copyJSValue: (ptr: JSValuePointer | JSValueConstPointer) => any;
|
||||
freeJSValue: (ptr: JSValuePointer) => void;
|
||||
consumeJSCharPointer(ptr: JSBorrowedCharPointer): string;
|
||||
heapValueHandle(ptr: JSValuePointer): JSValue;
|
||||
}
|
||||
/**
|
||||
* 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 {@link runtime} references the context's runtime.
|
||||
*
|
||||
* This class's methods return {@link 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 {@link QuickJSRuntime.newContext} or {@link 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 [[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 {@link QuickJSRuntime} for more information.
|
||||
*
|
||||
*/
|
||||
export declare class QuickJSContext implements LowLevelJavascriptVm<QuickJSHandle>, Disposable {
|
||||
/**
|
||||
* The runtime that created this context.
|
||||
*/
|
||||
readonly runtime: QuickJSRuntime;
|
||||
/** @private */
|
||||
protected readonly ctx: Lifetime<JSContextPointer>;
|
||||
/** @private */
|
||||
protected readonly rt: Lifetime<JSRuntimePointer>;
|
||||
/** @private */
|
||||
protected readonly module: EitherModule;
|
||||
/** @private */
|
||||
protected readonly ffi: EitherFFI;
|
||||
/** @private */
|
||||
protected memory: ContextMemory;
|
||||
/** @private */
|
||||
protected _undefined: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _null: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _false: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _true: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _global: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _BigInt: QuickJSHandle | undefined;
|
||||
/**
|
||||
* Use {@link QuickJS.createVm} to create a QuickJSContext instance.
|
||||
*/
|
||||
constructor(args: {
|
||||
module: EitherModule;
|
||||
ffi: EitherFFI;
|
||||
ctx: Lifetime<JSContextPointer>;
|
||||
rt: Lifetime<JSRuntimePointer>;
|
||||
runtime: QuickJSRuntime;
|
||||
ownedLifetimes?: Disposable[];
|
||||
callbacks: QuickJSModuleCallbacks;
|
||||
});
|
||||
get alive(): boolean;
|
||||
/**
|
||||
* Dispose of this VM's underlying resources.
|
||||
*
|
||||
* @throws Calling this method without disposing of all created handles
|
||||
* will result in an error.
|
||||
*/
|
||||
dispose(): void;
|
||||
/**
|
||||
* [`undefined`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined).
|
||||
*/
|
||||
get undefined(): QuickJSHandle;
|
||||
/**
|
||||
* [`null`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null).
|
||||
*/
|
||||
get null(): QuickJSHandle;
|
||||
/**
|
||||
* [`true`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/true).
|
||||
*/
|
||||
get true(): QuickJSHandle;
|
||||
/**
|
||||
* [`false`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/false).
|
||||
*/
|
||||
get false(): QuickJSHandle;
|
||||
/**
|
||||
* [`global`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects).
|
||||
* A handle to the global object inside the interpreter.
|
||||
* You can set properties to create global variables.
|
||||
*/
|
||||
get global(): QuickJSHandle;
|
||||
/**
|
||||
* Converts a Javascript number into a QuickJS value.
|
||||
*/
|
||||
newNumber(num: number): QuickJSHandle;
|
||||
/**
|
||||
* Create a QuickJS [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) value.
|
||||
*/
|
||||
newString(str: string): QuickJSHandle;
|
||||
/**
|
||||
* Create a QuickJS [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) value.
|
||||
* No two symbols created with this function will be the same value.
|
||||
*/
|
||||
newUniqueSymbol(description: string | symbol): QuickJSHandle;
|
||||
/**
|
||||
* Get a symbol from the [global registry](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#shared_symbols_in_the_global_symbol_registry) for the given key.
|
||||
* All symbols created with the same key will be the same value.
|
||||
*/
|
||||
newSymbolFor(key: string | symbol): QuickJSHandle;
|
||||
/**
|
||||
* Create a QuickJS [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) value.
|
||||
*/
|
||||
newBigInt(num: bigint): QuickJSHandle;
|
||||
/**
|
||||
* `{}`.
|
||||
* Create a new QuickJS [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer).
|
||||
*
|
||||
* @param prototype - Like [`Object.create`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create).
|
||||
*/
|
||||
newObject(prototype?: QuickJSHandle): QuickJSHandle;
|
||||
/**
|
||||
* `[]`.
|
||||
* Create a new QuickJS [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).
|
||||
*/
|
||||
newArray(): QuickJSHandle;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
newPromise(): 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.
|
||||
*/
|
||||
newPromise(promise: Promise<QuickJSHandle>): 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.
|
||||
*/
|
||||
newPromise(newPromiseFn: PromiseExecutor<QuickJSHandle, Error | QuickJSHandle>): QuickJSDeferredPromise;
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* ```
|
||||
*/
|
||||
newFunction(name: string, fn: VmFunctionImplementation<QuickJSHandle>): QuickJSHandle;
|
||||
newError(error: {
|
||||
name: string;
|
||||
message: string;
|
||||
}): QuickJSHandle;
|
||||
newError(message: string): QuickJSHandle;
|
||||
newError(): QuickJSHandle;
|
||||
/**
|
||||
* `typeof` operator. **Not** [standards compliant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof).
|
||||
*
|
||||
* @remarks
|
||||
* Does not support BigInt values correctly.
|
||||
*/
|
||||
typeof(handle: QuickJSHandle): string;
|
||||
/**
|
||||
* Converts `handle` into a Javascript number.
|
||||
* @returns `NaN` on error, otherwise a `number`.
|
||||
*/
|
||||
getNumber(handle: QuickJSHandle): number;
|
||||
/**
|
||||
* Converts `handle` to a Javascript string.
|
||||
*/
|
||||
getString(handle: QuickJSHandle): string;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
getSymbol(handle: QuickJSHandle): symbol;
|
||||
/**
|
||||
* Converts `handle` to a Javascript bigint.
|
||||
*/
|
||||
getBigInt(handle: QuickJSHandle): bigint;
|
||||
/**
|
||||
* `Promise.resolve(value)`.
|
||||
* Convert a handle containing a Promise-like value inside the VM into an
|
||||
* actual promise on the host.
|
||||
*
|
||||
* @remarks
|
||||
* You may need to call [[executePendingJobs]] to ensure that the promise is resolved.
|
||||
*
|
||||
* @param promiseLikeHandle - A handle to a Promise-like value with a `.then(onSuccess, onError)` method.
|
||||
*/
|
||||
resolvePromise(promiseLikeHandle: QuickJSHandle): Promise<VmCallResult<QuickJSHandle>>;
|
||||
/**
|
||||
* `handle[key]`.
|
||||
* Get a property from a JSValue.
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string (which will be converted automatically).
|
||||
*/
|
||||
getProp(handle: QuickJSHandle, key: QuickJSPropertyKey): QuickJSHandle;
|
||||
/**
|
||||
* `handle[key] = value`.
|
||||
* Set a property on a JSValue.
|
||||
*
|
||||
* @remarks
|
||||
* Note that the QuickJS authors recommend using [[defineProp]] to define new
|
||||
* properties.
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string or number (which will be converted automatically to a JSValue).
|
||||
*/
|
||||
setProp(handle: QuickJSHandle, key: QuickJSPropertyKey, value: QuickJSHandle): void;
|
||||
/**
|
||||
* [`Object.defineProperty(handle, key, descriptor)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string or number (which will be converted automatically to a JSValue).
|
||||
*/
|
||||
defineProp(handle: QuickJSHandle, key: QuickJSPropertyKey, descriptor: VmPropertyDescriptor<QuickJSHandle>): void;
|
||||
/**
|
||||
* [`func.call(thisVal, ...args)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call).
|
||||
* 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
|
||||
* [[executePendingJobs]] to finish evaluating the promise.
|
||||
*
|
||||
* @returns 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.
|
||||
*/
|
||||
callFunction(func: QuickJSHandle, thisVal: QuickJSHandle, ...args: QuickJSHandle[]): VmCallResult<QuickJSHandle>;
|
||||
/**
|
||||
* Like [`eval(code)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Description).
|
||||
* Evaluates the Javascript source `code` in the global scope of this VM.
|
||||
* When working with async code, you many need to call [[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
|
||||
* [[executePendingJobs]] to finish evaluating the promise.
|
||||
*
|
||||
* *Note*: to protect against infinite loops, provide an interrupt handler to
|
||||
* [[setInterruptHandler]]. You can use [[shouldInterruptAfterDeadline]] to
|
||||
* create a time-based deadline.
|
||||
*
|
||||
* @returns 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`.
|
||||
*/
|
||||
evalCode(code: string, filename?: string,
|
||||
/**
|
||||
* If no options are passed, a heuristic will be used to detect if `code` is
|
||||
* an ES module.
|
||||
*
|
||||
* See [[EvalFlags]] for number semantics.
|
||||
*/
|
||||
options?: number | ContextEvalOptions): VmCallResult<QuickJSHandle>;
|
||||
/**
|
||||
* Throw an error in the VM, interrupted whatever current execution is in progress when execution resumes.
|
||||
* @experimental
|
||||
*/
|
||||
throw(error: Error | QuickJSHandle): any;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
protected borrowPropertyKey(key: QuickJSPropertyKey): QuickJSHandle;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
getMemory(rt: JSRuntimePointer): ContextMemory;
|
||||
/**
|
||||
* Dump a JSValue to Javascript in a best-effort fashion.
|
||||
* Returns `handle.toString()` if it cannot be serialized to JSON.
|
||||
*/
|
||||
dump(handle: QuickJSHandle): any;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
unwrapResult<T>(result: SuccessOrFail<T, QuickJSHandle>): T;
|
||||
/** @private */
|
||||
protected fnNextId: number;
|
||||
/** @private */
|
||||
protected fnMaps: Map<number, Map<number, VmFunctionImplementation<QuickJSHandle>>>;
|
||||
/** @private */
|
||||
protected getFunction(fn_id: number): VmFunctionImplementation<QuickJSHandle> | undefined;
|
||||
/** @private */
|
||||
protected setFunction(fn_id: number, handle: VmFunctionImplementation<QuickJSHandle>): Map<number, VmFunctionImplementation<QuickJSHandle>>;
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
private cToHostCallbacks;
|
||||
private errorToHandle;
|
||||
}
|
||||
export {};
|
||||
691
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.js
generated
vendored
Normal file
691
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.js
generated
vendored
Normal file
@ -0,0 +1,691 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSContext = void 0;
|
||||
const debug_1 = require("./debug");
|
||||
const deferred_promise_1 = require("./deferred-promise");
|
||||
const errors_1 = require("./errors");
|
||||
const lifetime_1 = require("./lifetime");
|
||||
const memory_1 = require("./memory");
|
||||
const types_1 = require("./types");
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
class ContextMemory extends memory_1.ModuleMemory {
|
||||
/** @private */
|
||||
constructor(args) {
|
||||
super(args.module);
|
||||
this.scope = new lifetime_1.Scope();
|
||||
this.copyJSValue = (ptr) => {
|
||||
return this.ffi.QTS_DupValuePointer(this.ctx.value, ptr);
|
||||
};
|
||||
this.freeJSValue = (ptr) => {
|
||||
this.ffi.QTS_FreeValuePointer(this.ctx.value, ptr);
|
||||
};
|
||||
args.ownedLifetimes?.forEach((lifetime) => this.scope.manage(lifetime));
|
||||
this.owner = args.owner;
|
||||
this.module = args.module;
|
||||
this.ffi = args.ffi;
|
||||
this.rt = args.rt;
|
||||
this.ctx = this.scope.manage(args.ctx);
|
||||
}
|
||||
get alive() {
|
||||
return this.scope.alive;
|
||||
}
|
||||
dispose() {
|
||||
return this.scope.dispose();
|
||||
}
|
||||
/**
|
||||
* Track `lifetime` so that it is disposed when this scope is disposed.
|
||||
*/
|
||||
manage(lifetime) {
|
||||
return this.scope.manage(lifetime);
|
||||
}
|
||||
consumeJSCharPointer(ptr) {
|
||||
const str = this.module.UTF8ToString(ptr);
|
||||
this.ffi.QTS_FreeCString(this.ctx.value, ptr);
|
||||
return str;
|
||||
}
|
||||
heapValueHandle(ptr) {
|
||||
return new lifetime_1.Lifetime(ptr, this.copyJSValue, this.freeJSValue, this.owner);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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 {@link runtime} references the context's runtime.
|
||||
*
|
||||
* This class's methods return {@link 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 {@link QuickJSRuntime.newContext} or {@link 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 [[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 {@link QuickJSRuntime} for more information.
|
||||
*
|
||||
*/
|
||||
// TODO: Manage own callback registration
|
||||
class QuickJSContext {
|
||||
/**
|
||||
* Use {@link QuickJS.createVm} to create a QuickJSContext instance.
|
||||
*/
|
||||
constructor(args) {
|
||||
/** @private */
|
||||
this._undefined = undefined;
|
||||
/** @private */
|
||||
this._null = undefined;
|
||||
/** @private */
|
||||
this._false = undefined;
|
||||
/** @private */
|
||||
this._true = undefined;
|
||||
/** @private */
|
||||
this._global = undefined;
|
||||
/** @private */
|
||||
this._BigInt = undefined;
|
||||
/** @private */
|
||||
this.fnNextId = -32768; // min value of signed 16bit int used by Quickjs
|
||||
/** @private */
|
||||
this.fnMaps = new Map();
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
this.cToHostCallbacks = {
|
||||
callFunction: (ctx, this_ptr, argc, argv, fn_id) => {
|
||||
if (ctx !== this.ctx.value) {
|
||||
throw new Error("QuickJSContext instance received C -> JS call with mismatched ctx");
|
||||
}
|
||||
const fn = this.getFunction(fn_id);
|
||||
if (!fn) {
|
||||
// this "throw" is not catch-able from the TS side. could we somehow handle this higher up?
|
||||
throw new Error(`QuickJSContext had no callback with id ${fn_id}`);
|
||||
}
|
||||
return lifetime_1.Scope.withScopeMaybeAsync(this, function* (awaited, scope) {
|
||||
const thisHandle = scope.manage(new lifetime_1.WeakLifetime(this_ptr, this.memory.copyJSValue, this.memory.freeJSValue, this.runtime));
|
||||
const argHandles = new Array(argc);
|
||||
for (let i = 0; i < argc; i++) {
|
||||
const ptr = this.ffi.QTS_ArgvGetJSValueConstPointer(argv, i);
|
||||
argHandles[i] = scope.manage(new lifetime_1.WeakLifetime(ptr, this.memory.copyJSValue, this.memory.freeJSValue, this.runtime));
|
||||
}
|
||||
try {
|
||||
const result = yield* awaited(fn.apply(thisHandle, argHandles));
|
||||
if (result) {
|
||||
if ("error" in result && result.error) {
|
||||
(0, debug_1.debugLog)("throw error", result.error);
|
||||
throw result.error;
|
||||
}
|
||||
const handle = scope.manage(result instanceof lifetime_1.Lifetime ? result : result.value);
|
||||
return this.ffi.QTS_DupValuePointer(this.ctx.value, handle.value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch (error) {
|
||||
return this.errorToHandle(error).consume((errorHandle) => this.ffi.QTS_Throw(this.ctx.value, errorHandle.value));
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
this.runtime = args.runtime;
|
||||
this.module = args.module;
|
||||
this.ffi = args.ffi;
|
||||
this.rt = args.rt;
|
||||
this.ctx = args.ctx;
|
||||
this.memory = new ContextMemory({
|
||||
...args,
|
||||
owner: this.runtime,
|
||||
});
|
||||
args.callbacks.setContextCallbacks(this.ctx.value, this.cToHostCallbacks);
|
||||
this.dump = this.dump.bind(this);
|
||||
this.getString = this.getString.bind(this);
|
||||
this.getNumber = this.getNumber.bind(this);
|
||||
this.resolvePromise = this.resolvePromise.bind(this);
|
||||
}
|
||||
// @implement Disposable ----------------------------------------------------
|
||||
get alive() {
|
||||
return this.memory.alive;
|
||||
}
|
||||
/**
|
||||
* Dispose of this VM's underlying resources.
|
||||
*
|
||||
* @throws Calling this method without disposing of all created handles
|
||||
* will result in an error.
|
||||
*/
|
||||
dispose() {
|
||||
this.memory.dispose();
|
||||
}
|
||||
// Globals ------------------------------------------------------------------
|
||||
/**
|
||||
* [`undefined`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined).
|
||||
*/
|
||||
get undefined() {
|
||||
if (this._undefined) {
|
||||
return this._undefined;
|
||||
}
|
||||
// Undefined is a constant, immutable value in QuickJS.
|
||||
const ptr = this.ffi.QTS_GetUndefined();
|
||||
return (this._undefined = new lifetime_1.StaticLifetime(ptr));
|
||||
}
|
||||
/**
|
||||
* [`null`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null).
|
||||
*/
|
||||
get null() {
|
||||
if (this._null) {
|
||||
return this._null;
|
||||
}
|
||||
// Null is a constant, immutable value in QuickJS.
|
||||
const ptr = this.ffi.QTS_GetNull();
|
||||
return (this._null = new lifetime_1.StaticLifetime(ptr));
|
||||
}
|
||||
/**
|
||||
* [`true`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/true).
|
||||
*/
|
||||
get true() {
|
||||
if (this._true) {
|
||||
return this._true;
|
||||
}
|
||||
// True is a constant, immutable value in QuickJS.
|
||||
const ptr = this.ffi.QTS_GetTrue();
|
||||
return (this._true = new lifetime_1.StaticLifetime(ptr));
|
||||
}
|
||||
/**
|
||||
* [`false`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/false).
|
||||
*/
|
||||
get false() {
|
||||
if (this._false) {
|
||||
return this._false;
|
||||
}
|
||||
// False is a constant, immutable value in QuickJS.
|
||||
const ptr = this.ffi.QTS_GetFalse();
|
||||
return (this._false = new lifetime_1.StaticLifetime(ptr));
|
||||
}
|
||||
/**
|
||||
* [`global`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects).
|
||||
* A handle to the global object inside the interpreter.
|
||||
* You can set properties to create global variables.
|
||||
*/
|
||||
get global() {
|
||||
if (this._global) {
|
||||
return this._global;
|
||||
}
|
||||
// The global is a JSValue, but since it's lifetime is as long as the VM's,
|
||||
// we should manage it.
|
||||
const ptr = this.ffi.QTS_GetGlobalObject(this.ctx.value);
|
||||
// Automatically clean up this reference when we dispose
|
||||
this.memory.manage(this.memory.heapValueHandle(ptr));
|
||||
// This isn't technically a static lifetime, but since it has the same
|
||||
// lifetime as the VM, it's okay to fake one since when the VM is
|
||||
// disposed, no other functions will accept the value.
|
||||
this._global = new lifetime_1.StaticLifetime(ptr, this.runtime);
|
||||
return this._global;
|
||||
}
|
||||
// New values ---------------------------------------------------------------
|
||||
/**
|
||||
* Converts a Javascript number into a QuickJS value.
|
||||
*/
|
||||
newNumber(num) {
|
||||
return this.memory.heapValueHandle(this.ffi.QTS_NewFloat64(this.ctx.value, num));
|
||||
}
|
||||
/**
|
||||
* Create a QuickJS [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) value.
|
||||
*/
|
||||
newString(str) {
|
||||
const ptr = this.memory
|
||||
.newHeapCharPointer(str)
|
||||
.consume((charHandle) => this.ffi.QTS_NewString(this.ctx.value, charHandle.value));
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
/**
|
||||
* Create a QuickJS [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) value.
|
||||
* No two symbols created with this function will be the same value.
|
||||
*/
|
||||
newUniqueSymbol(description) {
|
||||
const key = (typeof description === "symbol" ? description.description : description) ?? "";
|
||||
const ptr = this.memory
|
||||
.newHeapCharPointer(key)
|
||||
.consume((charHandle) => this.ffi.QTS_NewSymbol(this.ctx.value, charHandle.value, 0));
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
/**
|
||||
* Get a symbol from the [global registry](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#shared_symbols_in_the_global_symbol_registry) for the given key.
|
||||
* All symbols created with the same key will be the same value.
|
||||
*/
|
||||
newSymbolFor(key) {
|
||||
const description = (typeof key === "symbol" ? key.description : key) ?? "";
|
||||
const ptr = this.memory
|
||||
.newHeapCharPointer(description)
|
||||
.consume((charHandle) => this.ffi.QTS_NewSymbol(this.ctx.value, charHandle.value, 1));
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
/**
|
||||
* Create a QuickJS [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) value.
|
||||
*/
|
||||
newBigInt(num) {
|
||||
if (!this._BigInt) {
|
||||
const bigIntHandle = this.getProp(this.global, "BigInt");
|
||||
this.memory.manage(bigIntHandle);
|
||||
this._BigInt = new lifetime_1.StaticLifetime(bigIntHandle.value, this.runtime);
|
||||
}
|
||||
const bigIntHandle = this._BigInt;
|
||||
const asString = String(num);
|
||||
return this.newString(asString).consume((handle) => this.unwrapResult(this.callFunction(bigIntHandle, this.undefined, handle)));
|
||||
}
|
||||
/**
|
||||
* `{}`.
|
||||
* Create a new QuickJS [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer).
|
||||
*
|
||||
* @param prototype - Like [`Object.create`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create).
|
||||
*/
|
||||
newObject(prototype) {
|
||||
if (prototype) {
|
||||
this.runtime.assertOwned(prototype);
|
||||
}
|
||||
const ptr = prototype
|
||||
? this.ffi.QTS_NewObjectProto(this.ctx.value, prototype.value)
|
||||
: this.ffi.QTS_NewObject(this.ctx.value);
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
/**
|
||||
* `[]`.
|
||||
* Create a new QuickJS [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).
|
||||
*/
|
||||
newArray() {
|
||||
const ptr = this.ffi.QTS_NewArray(this.ctx.value);
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
newPromise(value) {
|
||||
const deferredPromise = lifetime_1.Scope.withScope((scope) => {
|
||||
const mutablePointerArray = scope.manage(this.memory.newMutablePointerArray(2));
|
||||
const promisePtr = this.ffi.QTS_NewPromiseCapability(this.ctx.value, mutablePointerArray.value.ptr);
|
||||
const promiseHandle = this.memory.heapValueHandle(promisePtr);
|
||||
const [resolveHandle, rejectHandle] = Array.from(mutablePointerArray.value.typedArray).map((jsvaluePtr) => this.memory.heapValueHandle(jsvaluePtr));
|
||||
return new deferred_promise_1.QuickJSDeferredPromise({
|
||||
context: this,
|
||||
promiseHandle,
|
||||
resolveHandle,
|
||||
rejectHandle,
|
||||
});
|
||||
});
|
||||
if (value && typeof value === "function") {
|
||||
value = new Promise(value);
|
||||
}
|
||||
if (value) {
|
||||
Promise.resolve(value).then(deferredPromise.resolve, (error) => error instanceof lifetime_1.Lifetime
|
||||
? deferredPromise.reject(error)
|
||||
: this.newError(error).consume(deferredPromise.reject));
|
||||
}
|
||||
return deferredPromise;
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* ```
|
||||
*/
|
||||
newFunction(name, fn) {
|
||||
const fnId = ++this.fnNextId;
|
||||
this.setFunction(fnId, fn);
|
||||
return this.memory.heapValueHandle(this.ffi.QTS_NewFunction(this.ctx.value, fnId, name));
|
||||
}
|
||||
newError(error) {
|
||||
const errorHandle = this.memory.heapValueHandle(this.ffi.QTS_NewError(this.ctx.value));
|
||||
if (error && typeof error === "object") {
|
||||
if (error.name !== undefined) {
|
||||
this.newString(error.name).consume((handle) => this.setProp(errorHandle, "name", handle));
|
||||
}
|
||||
if (error.message !== undefined) {
|
||||
this.newString(error.message).consume((handle) => this.setProp(errorHandle, "message", handle));
|
||||
}
|
||||
}
|
||||
else if (typeof error === "string") {
|
||||
this.newString(error).consume((handle) => this.setProp(errorHandle, "message", handle));
|
||||
}
|
||||
else if (error !== undefined) {
|
||||
// This isn't supported in the type signature but maybe it will make life easier.
|
||||
this.newString(String(error)).consume((handle) => this.setProp(errorHandle, "message", handle));
|
||||
}
|
||||
return errorHandle;
|
||||
}
|
||||
// Read values --------------------------------------------------------------
|
||||
/**
|
||||
* `typeof` operator. **Not** [standards compliant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof).
|
||||
*
|
||||
* @remarks
|
||||
* Does not support BigInt values correctly.
|
||||
*/
|
||||
typeof(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
return this.memory.consumeHeapCharPointer(this.ffi.QTS_Typeof(this.ctx.value, handle.value));
|
||||
}
|
||||
/**
|
||||
* Converts `handle` into a Javascript number.
|
||||
* @returns `NaN` on error, otherwise a `number`.
|
||||
*/
|
||||
getNumber(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
return this.ffi.QTS_GetFloat64(this.ctx.value, handle.value);
|
||||
}
|
||||
/**
|
||||
* Converts `handle` to a Javascript string.
|
||||
*/
|
||||
getString(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
return this.memory.consumeJSCharPointer(this.ffi.QTS_GetString(this.ctx.value, handle.value));
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
getSymbol(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
const key = this.memory.consumeJSCharPointer(this.ffi.QTS_GetSymbolDescriptionOrKey(this.ctx.value, handle.value));
|
||||
const isGlobal = this.ffi.QTS_IsGlobalSymbol(this.ctx.value, handle.value);
|
||||
return isGlobal ? Symbol.for(key) : Symbol(key);
|
||||
}
|
||||
/**
|
||||
* Converts `handle` to a Javascript bigint.
|
||||
*/
|
||||
getBigInt(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
const asString = this.getString(handle);
|
||||
return BigInt(asString);
|
||||
}
|
||||
/**
|
||||
* `Promise.resolve(value)`.
|
||||
* Convert a handle containing a Promise-like value inside the VM into an
|
||||
* actual promise on the host.
|
||||
*
|
||||
* @remarks
|
||||
* You may need to call [[executePendingJobs]] to ensure that the promise is resolved.
|
||||
*
|
||||
* @param promiseLikeHandle - A handle to a Promise-like value with a `.then(onSuccess, onError)` method.
|
||||
*/
|
||||
resolvePromise(promiseLikeHandle) {
|
||||
this.runtime.assertOwned(promiseLikeHandle);
|
||||
const vmResolveResult = lifetime_1.Scope.withScope((scope) => {
|
||||
const vmPromise = scope.manage(this.getProp(this.global, "Promise"));
|
||||
const vmPromiseResolve = scope.manage(this.getProp(vmPromise, "resolve"));
|
||||
return this.callFunction(vmPromiseResolve, vmPromise, promiseLikeHandle);
|
||||
});
|
||||
if (vmResolveResult.error) {
|
||||
return Promise.resolve(vmResolveResult);
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
lifetime_1.Scope.withScope((scope) => {
|
||||
const resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
|
||||
resolve({ value: value && value.dup() });
|
||||
}));
|
||||
const rejectHandle = scope.manage(this.newFunction("reject", (error) => {
|
||||
resolve({ error: error && error.dup() });
|
||||
}));
|
||||
const promiseHandle = scope.manage(vmResolveResult.value);
|
||||
const promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
|
||||
this.unwrapResult(this.callFunction(promiseThenHandle, promiseHandle, resolveHandle, rejectHandle)).dispose();
|
||||
});
|
||||
});
|
||||
}
|
||||
// Properties ---------------------------------------------------------------
|
||||
/**
|
||||
* `handle[key]`.
|
||||
* Get a property from a JSValue.
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string (which will be converted automatically).
|
||||
*/
|
||||
getProp(handle, key) {
|
||||
this.runtime.assertOwned(handle);
|
||||
const ptr = this.borrowPropertyKey(key).consume((quickJSKey) => this.ffi.QTS_GetProp(this.ctx.value, handle.value, quickJSKey.value));
|
||||
const result = this.memory.heapValueHandle(ptr);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* `handle[key] = value`.
|
||||
* Set a property on a JSValue.
|
||||
*
|
||||
* @remarks
|
||||
* Note that the QuickJS authors recommend using [[defineProp]] to define new
|
||||
* properties.
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string or number (which will be converted automatically to a JSValue).
|
||||
*/
|
||||
setProp(handle, key, value) {
|
||||
this.runtime.assertOwned(handle);
|
||||
// free newly allocated value if key was a string or number. No-op if string was already
|
||||
// a QuickJS handle.
|
||||
this.borrowPropertyKey(key).consume((quickJSKey) => this.ffi.QTS_SetProp(this.ctx.value, handle.value, quickJSKey.value, value.value));
|
||||
}
|
||||
/**
|
||||
* [`Object.defineProperty(handle, key, descriptor)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string or number (which will be converted automatically to a JSValue).
|
||||
*/
|
||||
defineProp(handle, key, descriptor) {
|
||||
this.runtime.assertOwned(handle);
|
||||
lifetime_1.Scope.withScope((scope) => {
|
||||
const quickJSKey = scope.manage(this.borrowPropertyKey(key));
|
||||
const value = descriptor.value || this.undefined;
|
||||
const configurable = Boolean(descriptor.configurable);
|
||||
const enumerable = Boolean(descriptor.enumerable);
|
||||
const hasValue = Boolean(descriptor.value);
|
||||
const get = descriptor.get
|
||||
? scope.manage(this.newFunction(descriptor.get.name, descriptor.get))
|
||||
: this.undefined;
|
||||
const set = descriptor.set
|
||||
? scope.manage(this.newFunction(descriptor.set.name, descriptor.set))
|
||||
: this.undefined;
|
||||
this.ffi.QTS_DefineProp(this.ctx.value, handle.value, quickJSKey.value, value.value, get.value, set.value, configurable, enumerable, hasValue);
|
||||
});
|
||||
}
|
||||
// Evaluation ---------------------------------------------------------------
|
||||
/**
|
||||
* [`func.call(thisVal, ...args)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call).
|
||||
* 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
|
||||
* [[executePendingJobs]] to finish evaluating the promise.
|
||||
*
|
||||
* @returns 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.
|
||||
*/
|
||||
callFunction(func, thisVal, ...args) {
|
||||
this.runtime.assertOwned(func);
|
||||
const resultPtr = this.memory
|
||||
.toPointerArray(args)
|
||||
.consume((argsArrayPtr) => this.ffi.QTS_Call(this.ctx.value, func.value, thisVal.value, args.length, argsArrayPtr.value));
|
||||
const errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr);
|
||||
if (errorPtr) {
|
||||
this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr);
|
||||
return { error: this.memory.heapValueHandle(errorPtr) };
|
||||
}
|
||||
return { value: this.memory.heapValueHandle(resultPtr) };
|
||||
}
|
||||
/**
|
||||
* Like [`eval(code)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Description).
|
||||
* Evaluates the Javascript source `code` in the global scope of this VM.
|
||||
* When working with async code, you many need to call [[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
|
||||
* [[executePendingJobs]] to finish evaluating the promise.
|
||||
*
|
||||
* *Note*: to protect against infinite loops, provide an interrupt handler to
|
||||
* [[setInterruptHandler]]. You can use [[shouldInterruptAfterDeadline]] to
|
||||
* create a time-based deadline.
|
||||
*
|
||||
* @returns 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`.
|
||||
*/
|
||||
evalCode(code, filename = "eval.js",
|
||||
/**
|
||||
* If no options are passed, a heuristic will be used to detect if `code` is
|
||||
* an ES module.
|
||||
*
|
||||
* See [[EvalFlags]] for number semantics.
|
||||
*/
|
||||
options) {
|
||||
const detectModule = (options === undefined ? 1 : 0);
|
||||
const flags = (0, types_1.evalOptionsToFlags)(options);
|
||||
const resultPtr = this.memory
|
||||
.newHeapCharPointer(code)
|
||||
.consume((charHandle) => this.ffi.QTS_Eval(this.ctx.value, charHandle.value, filename, detectModule, flags));
|
||||
const errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr);
|
||||
if (errorPtr) {
|
||||
this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr);
|
||||
return { error: this.memory.heapValueHandle(errorPtr) };
|
||||
}
|
||||
return { value: this.memory.heapValueHandle(resultPtr) };
|
||||
}
|
||||
/**
|
||||
* Throw an error in the VM, interrupted whatever current execution is in progress when execution resumes.
|
||||
* @experimental
|
||||
*/
|
||||
throw(error) {
|
||||
return this.errorToHandle(error).consume((handle) => this.ffi.QTS_Throw(this.ctx.value, handle.value));
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
borrowPropertyKey(key) {
|
||||
if (typeof key === "number") {
|
||||
return this.newNumber(key);
|
||||
}
|
||||
if (typeof key === "string") {
|
||||
return this.newString(key);
|
||||
}
|
||||
// key is already a JSValue, but we're borrowing it. Return a static handle
|
||||
// for internal use only.
|
||||
return new lifetime_1.StaticLifetime(key.value, this.runtime);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
getMemory(rt) {
|
||||
if (rt === this.rt.value) {
|
||||
return this.memory;
|
||||
}
|
||||
else {
|
||||
throw new Error("Private API. Cannot get memory from a different runtime");
|
||||
}
|
||||
}
|
||||
// Utilities ----------------------------------------------------------------
|
||||
/**
|
||||
* Dump a JSValue to Javascript in a best-effort fashion.
|
||||
* Returns `handle.toString()` if it cannot be serialized to JSON.
|
||||
*/
|
||||
dump(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
const type = this.typeof(handle);
|
||||
if (type === "string") {
|
||||
return this.getString(handle);
|
||||
}
|
||||
else if (type === "number") {
|
||||
return this.getNumber(handle);
|
||||
}
|
||||
else if (type === "bigint") {
|
||||
return this.getBigInt(handle);
|
||||
}
|
||||
else if (type === "undefined") {
|
||||
return undefined;
|
||||
}
|
||||
else if (type === "symbol") {
|
||||
return this.getSymbol(handle);
|
||||
}
|
||||
const str = this.memory.consumeJSCharPointer(this.ffi.QTS_Dump(this.ctx.value, handle.value));
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
}
|
||||
catch (err) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
unwrapResult(result) {
|
||||
if (result.error) {
|
||||
const context = "context" in result.error ? result.error.context : this;
|
||||
const cause = result.error.consume((error) => this.dump(error));
|
||||
if (cause && typeof cause === "object" && typeof cause.message === "string") {
|
||||
const { message, name, stack } = cause;
|
||||
const exception = new errors_1.QuickJSUnwrapError("");
|
||||
const hostStack = exception.stack;
|
||||
if (typeof name === "string") {
|
||||
exception.name = cause.name;
|
||||
}
|
||||
if (typeof stack === "string") {
|
||||
exception.stack = `${name}: ${message}\n${cause.stack}Host: ${hostStack}`;
|
||||
}
|
||||
Object.assign(exception, { cause, context, message });
|
||||
throw exception;
|
||||
}
|
||||
throw new errors_1.QuickJSUnwrapError(cause, context);
|
||||
}
|
||||
return result.value;
|
||||
}
|
||||
/** @private */
|
||||
getFunction(fn_id) {
|
||||
const map_id = fn_id >> 8;
|
||||
const fnMap = this.fnMaps.get(map_id);
|
||||
if (!fnMap) {
|
||||
return undefined;
|
||||
}
|
||||
return fnMap.get(fn_id);
|
||||
}
|
||||
/** @private */
|
||||
setFunction(fn_id, handle) {
|
||||
const map_id = fn_id >> 8;
|
||||
let fnMap = this.fnMaps.get(map_id);
|
||||
if (!fnMap) {
|
||||
fnMap = new Map();
|
||||
this.fnMaps.set(map_id, fnMap);
|
||||
}
|
||||
return fnMap.set(fn_id, handle);
|
||||
}
|
||||
errorToHandle(error) {
|
||||
if (error instanceof lifetime_1.Lifetime) {
|
||||
return error;
|
||||
}
|
||||
return this.newError(error);
|
||||
}
|
||||
}
|
||||
exports.QuickJSContext = QuickJSContext;
|
||||
//# sourceMappingURL=context.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
5
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.d.ts
generated
vendored
Normal file
5
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.d.ts
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export declare const QTS_DEBUG: boolean;
|
||||
export declare let debugLog: {
|
||||
(...data: any[]): void;
|
||||
(message?: any, ...optionalParams: any[]): void;
|
||||
};
|
||||
6
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js
generated
vendored
Normal file
6
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.debugLog = exports.QTS_DEBUG = void 0;
|
||||
exports.QTS_DEBUG = false || Boolean(typeof process === "object" && process.env.QTS_DEBUG);
|
||||
exports.debugLog = exports.QTS_DEBUG ? console.log.bind(console) : () => { };
|
||||
//# sourceMappingURL=debug.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../ts/debug.ts"],"names":[],"mappings":";;;AAAa,QAAA,SAAS,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;AACpF,QAAA,QAAQ,GAAG,iBAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAA","sourcesContent":["export const QTS_DEBUG = false || Boolean(typeof process === \"object\" && process.env.QTS_DEBUG)\nexport let debugLog = QTS_DEBUG ? console.log.bind(console) : () => {}\n"]}
|
||||
75
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.d.ts
generated
vendored
Normal file
75
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.d.ts
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
import type { Disposable } from "./lifetime";
|
||||
import type { QuickJSHandle } from "./types";
|
||||
import type { QuickJSRuntime } from "./runtime";
|
||||
import type { QuickJSContext } from "./context";
|
||||
export type { PromiseExecutor } from "./types";
|
||||
/**
|
||||
* QuickJSDeferredPromise wraps a QuickJS promise [[handle]] and allows
|
||||
* [[resolve]]ing or [[reject]]ing that promise. Use it to bridge asynchronous
|
||||
* code on the host to APIs inside a QuickJSContext.
|
||||
*
|
||||
* Managing the lifetime of promises is tricky. There are three
|
||||
* [[QuickJSHandle]]s inside of each deferred promise object: (1) the promise
|
||||
* itself, (2) the `resolve` callback, and (3) the `reject` callback.
|
||||
*
|
||||
* - If the promise will be fulfilled before the end of it's [[owner]]'s lifetime,
|
||||
* the only cleanup necessary is `deferred.handle.dispose()`, because
|
||||
* calling [[resolve]] or [[reject]] will dispose of both callbacks automatically.
|
||||
*
|
||||
* - As the return value of a [[VmFunctionImplementation]], return [[handle]],
|
||||
* and ensure that either [[resolve]] or [[reject]] will be called. No other
|
||||
* clean-up is necessary.
|
||||
*
|
||||
* - In other cases, call [[dispose]], which will dispose [[handle]] as well as the
|
||||
* QuickJS handles that back [[resolve]] and [[reject]]. For this object,
|
||||
* [[dispose]] is idempotent.
|
||||
*/
|
||||
export declare class QuickJSDeferredPromise implements Disposable {
|
||||
owner: QuickJSRuntime;
|
||||
context: QuickJSContext;
|
||||
/**
|
||||
* A handle of the Promise instance inside the QuickJSContext.
|
||||
* You must dispose [[handle]] or the entire QuickJSDeferredPromise once you
|
||||
* are finished with it.
|
||||
*/
|
||||
handle: QuickJSHandle;
|
||||
/**
|
||||
* A native promise that will resolve once this deferred is settled.
|
||||
*/
|
||||
settled: Promise<void>;
|
||||
private resolveHandle;
|
||||
private rejectHandle;
|
||||
private onSettled;
|
||||
/**
|
||||
* Use [[QuickJSContext.newPromise]] to create a new promise instead of calling
|
||||
* this constructor directly.
|
||||
* @unstable
|
||||
*/
|
||||
constructor(args: {
|
||||
context: QuickJSContext;
|
||||
promiseHandle: QuickJSHandle;
|
||||
resolveHandle: QuickJSHandle;
|
||||
rejectHandle: QuickJSHandle;
|
||||
});
|
||||
/**
|
||||
* Resolve [[handle]] with the given value, if any.
|
||||
* Calling this method after calling [[dispose]] is a no-op.
|
||||
*
|
||||
* Note that after resolving a promise, you may need to call
|
||||
* [[QuickJSContext.executePendingJobs]] to propagate the result to the promise's
|
||||
* callbacks.
|
||||
*/
|
||||
resolve: (value?: QuickJSHandle) => void;
|
||||
/**
|
||||
* Reject [[handle]] with the given value, if any.
|
||||
* Calling this method after calling [[dispose]] is a no-op.
|
||||
*
|
||||
* Note that after rejecting a promise, you may need to call
|
||||
* [[QuickJSContext.executePendingJobs]] to propagate the result to the promise's
|
||||
* callbacks.
|
||||
*/
|
||||
reject: (value?: QuickJSHandle) => void;
|
||||
get alive(): boolean;
|
||||
dispose: () => void;
|
||||
private disposeResolvers;
|
||||
}
|
||||
96
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js
generated
vendored
Normal file
96
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSDeferredPromise = void 0;
|
||||
/**
|
||||
* QuickJSDeferredPromise wraps a QuickJS promise [[handle]] and allows
|
||||
* [[resolve]]ing or [[reject]]ing that promise. Use it to bridge asynchronous
|
||||
* code on the host to APIs inside a QuickJSContext.
|
||||
*
|
||||
* Managing the lifetime of promises is tricky. There are three
|
||||
* [[QuickJSHandle]]s inside of each deferred promise object: (1) the promise
|
||||
* itself, (2) the `resolve` callback, and (3) the `reject` callback.
|
||||
*
|
||||
* - If the promise will be fulfilled before the end of it's [[owner]]'s lifetime,
|
||||
* the only cleanup necessary is `deferred.handle.dispose()`, because
|
||||
* calling [[resolve]] or [[reject]] will dispose of both callbacks automatically.
|
||||
*
|
||||
* - As the return value of a [[VmFunctionImplementation]], return [[handle]],
|
||||
* and ensure that either [[resolve]] or [[reject]] will be called. No other
|
||||
* clean-up is necessary.
|
||||
*
|
||||
* - In other cases, call [[dispose]], which will dispose [[handle]] as well as the
|
||||
* QuickJS handles that back [[resolve]] and [[reject]]. For this object,
|
||||
* [[dispose]] is idempotent.
|
||||
*/
|
||||
class QuickJSDeferredPromise {
|
||||
/**
|
||||
* Use [[QuickJSContext.newPromise]] to create a new promise instead of calling
|
||||
* this constructor directly.
|
||||
* @unstable
|
||||
*/
|
||||
constructor(args) {
|
||||
/**
|
||||
* Resolve [[handle]] with the given value, if any.
|
||||
* Calling this method after calling [[dispose]] is a no-op.
|
||||
*
|
||||
* Note that after resolving a promise, you may need to call
|
||||
* [[QuickJSContext.executePendingJobs]] to propagate the result to the promise's
|
||||
* callbacks.
|
||||
*/
|
||||
this.resolve = (value) => {
|
||||
if (!this.resolveHandle.alive) {
|
||||
return;
|
||||
}
|
||||
this.context
|
||||
.unwrapResult(this.context.callFunction(this.resolveHandle, this.context.undefined, value || this.context.undefined))
|
||||
.dispose();
|
||||
this.disposeResolvers();
|
||||
this.onSettled();
|
||||
};
|
||||
/**
|
||||
* Reject [[handle]] with the given value, if any.
|
||||
* Calling this method after calling [[dispose]] is a no-op.
|
||||
*
|
||||
* Note that after rejecting a promise, you may need to call
|
||||
* [[QuickJSContext.executePendingJobs]] to propagate the result to the promise's
|
||||
* callbacks.
|
||||
*/
|
||||
this.reject = (value) => {
|
||||
if (!this.rejectHandle.alive) {
|
||||
return;
|
||||
}
|
||||
this.context
|
||||
.unwrapResult(this.context.callFunction(this.rejectHandle, this.context.undefined, value || this.context.undefined))
|
||||
.dispose();
|
||||
this.disposeResolvers();
|
||||
this.onSettled();
|
||||
};
|
||||
this.dispose = () => {
|
||||
if (this.handle.alive) {
|
||||
this.handle.dispose();
|
||||
}
|
||||
this.disposeResolvers();
|
||||
};
|
||||
this.context = args.context;
|
||||
this.owner = args.context.runtime;
|
||||
this.handle = args.promiseHandle;
|
||||
this.settled = new Promise((resolve) => {
|
||||
this.onSettled = resolve;
|
||||
});
|
||||
this.resolveHandle = args.resolveHandle;
|
||||
this.rejectHandle = args.rejectHandle;
|
||||
}
|
||||
get alive() {
|
||||
return this.handle.alive || this.resolveHandle.alive || this.rejectHandle.alive;
|
||||
}
|
||||
disposeResolvers() {
|
||||
if (this.resolveHandle.alive) {
|
||||
this.resolveHandle.dispose();
|
||||
}
|
||||
if (this.rejectHandle.alive) {
|
||||
this.rejectHandle.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.QuickJSDeferredPromise = QuickJSDeferredPromise;
|
||||
//# sourceMappingURL=deferred-promise.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
97
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.d.ts
generated
vendored
Normal file
97
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.d.ts
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
import { BorrowedHeapCharPointer, JSContextPointer, JSRuntimePointer, JSValueConstPointer, JSValuePointer, OwnedHeapCharPointer } from "./types-ffi";
|
||||
declare namespace Emscripten {
|
||||
interface FileSystemType {
|
||||
}
|
||||
type EnvironmentType = "WEB" | "NODE" | "SHELL" | "WORKER";
|
||||
type ValueType = "number" | "string" | "array" | "boolean";
|
||||
type TypeCompatibleWithC = number | string | any[] | boolean;
|
||||
type WebAssemblyImports = Array<{
|
||||
name: string;
|
||||
kind: string;
|
||||
}>;
|
||||
type WebAssemblyExports = Array<{
|
||||
module: string;
|
||||
name: string;
|
||||
kind: string;
|
||||
}>;
|
||||
interface CCallOpts {
|
||||
async?: boolean;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Typings for the features we use to interface with our Emscripten build of
|
||||
* QuickJS.
|
||||
*/
|
||||
interface EmscriptenModule {
|
||||
/**
|
||||
* Write JS `str` to HeapChar pointer.
|
||||
* https://emscripten.org/docs/api_reference/preamble.js.html#stringToUTF8
|
||||
*/
|
||||
stringToUTF8(str: string, outPtr: OwnedHeapCharPointer, maxBytesToRead?: number): void;
|
||||
/**
|
||||
* HeapChar to JS string.
|
||||
* https://emscripten.org/docs/api_reference/preamble.js.html#UTF8ToString
|
||||
*/
|
||||
UTF8ToString(ptr: BorrowedHeapCharPointer, maxBytesToRead?: number): string;
|
||||
lengthBytesUTF8(str: string): number;
|
||||
_malloc(size: number): number;
|
||||
_free(ptr: number): void;
|
||||
cwrap(ident: string, returnType: Emscripten.ValueType | null, argTypes: Emscripten.ValueType[], opts?: Emscripten.CCallOpts): (...args: any[]) => any;
|
||||
HEAP8: Int8Array;
|
||||
HEAP16: Int16Array;
|
||||
HEAP32: Int32Array;
|
||||
HEAPU8: Uint8Array;
|
||||
HEAPU16: Uint16Array;
|
||||
HEAPU32: Uint32Array;
|
||||
HEAPF32: Float32Array;
|
||||
HEAPF64: Float64Array;
|
||||
TOTAL_STACK: number;
|
||||
TOTAL_MEMORY: number;
|
||||
FAST_MEMORY: number;
|
||||
}
|
||||
declare const AsyncifySleepReturnValue: unique symbol;
|
||||
/** @private */
|
||||
export type AsyncifySleepResult<T> = T & typeof AsyncifySleepReturnValue;
|
||||
/**
|
||||
* Allows us to optionally suspend the Emscripten runtime to wait for a promise.
|
||||
* https://emscripten.org/docs/porting/asyncify.html#ways-to-use-async-apis-in-older-engines
|
||||
* ```
|
||||
* EM_JS(int, do_fetch, (), {
|
||||
* return Asyncify.handleSleep(function (wakeUp) {
|
||||
* out("waiting for a fetch");
|
||||
* fetch("a.html").then(function (response) {
|
||||
* out("got the fetch response");
|
||||
* // (normally you would do something with the fetch here)
|
||||
* wakeUp(42);
|
||||
* });
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
* @private
|
||||
*/
|
||||
export interface Asyncify {
|
||||
handleSleep<T>(maybeAsyncFn: (wakeUp: (result: T) => void) => void): AsyncifySleepResult<T>;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export interface EmscriptenModuleCallbacks {
|
||||
callFunction: (asyncify: Asyncify | undefined, ctx: JSContextPointer, this_ptr: JSValueConstPointer, argc: number, argv: JSValueConstPointer, fn_id: number) => JSValuePointer | AsyncifySleepResult<JSValuePointer>;
|
||||
loadModuleSource: (asyncify: Asyncify | undefined, rt: JSRuntimePointer, ctx: JSContextPointer, module_name: string) => BorrowedHeapCharPointer | AsyncifySleepResult<BorrowedHeapCharPointer>;
|
||||
normalizeModule: (asyncify: Asyncify | undefined, rt: JSRuntimePointer, ctx: JSContextPointer, module_base_name: string, module_name: string) => BorrowedHeapCharPointer | AsyncifySleepResult<BorrowedHeapCharPointer>;
|
||||
shouldInterrupt: (asyncify: Asyncify | undefined, rt: JSRuntimePointer) => 0 | 1 | AsyncifySleepResult<0 | 1>;
|
||||
}
|
||||
export interface QuickJSEmscriptenModule extends EmscriptenModule {
|
||||
type: "sync";
|
||||
callbacks: EmscriptenModuleCallbacks;
|
||||
}
|
||||
export interface QuickJSAsyncEmscriptenModule extends EmscriptenModule {
|
||||
/** @todo Implement this field */
|
||||
type: "async";
|
||||
callbacks: EmscriptenModuleCallbacks;
|
||||
}
|
||||
export type EitherModule = QuickJSEmscriptenModule | QuickJSAsyncEmscriptenModule;
|
||||
export interface EmscriptenModuleLoader<T extends EmscriptenModule> {
|
||||
(): Promise<T>;
|
||||
}
|
||||
export {};
|
||||
15
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.js
generated
vendored
Normal file
15
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
// This is a subset of the Emscripten type definitions from @types/emscripten
|
||||
// Project: http://kripken.github.io/emscripten-site/index.html
|
||||
// Definitions by: Kensuke Matsuzaki <https://github.com/zakki>
|
||||
// Periklis Tsirakidis <https://github.com/periklis>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
//
|
||||
// quickjs-emscripten doesn't use the full EmscriptenModule type from @types/emscripten because:
|
||||
//
|
||||
// - the upstream types define many properties that don't exist on our module due
|
||||
// to our build settings
|
||||
// - some upstream types reference web-only ambient types like WebGL stuff, which
|
||||
// we don't use.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=emscripten-types.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
28
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.d.ts
generated
vendored
Normal file
28
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.d.ts
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
import type { QuickJSContext } from "./context";
|
||||
/**
|
||||
* Error thrown if [[QuickJSContext.unwrapResult]] unwraps an error value that isn't an object.
|
||||
*/
|
||||
export declare class QuickJSUnwrapError extends Error {
|
||||
cause: unknown;
|
||||
context?: QuickJSContext | undefined;
|
||||
name: string;
|
||||
constructor(cause: unknown, context?: QuickJSContext | undefined);
|
||||
}
|
||||
export declare class QuickJSWrongOwner extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSUseAfterFree extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSNotImplemented extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSAsyncifyError extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSAsyncifySuspended extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSMemoryLeakDetected extends Error {
|
||||
name: string;
|
||||
}
|
||||
58
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js
generated
vendored
Normal file
58
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSMemoryLeakDetected = exports.QuickJSAsyncifySuspended = exports.QuickJSAsyncifyError = exports.QuickJSNotImplemented = exports.QuickJSUseAfterFree = exports.QuickJSWrongOwner = exports.QuickJSUnwrapError = void 0;
|
||||
/**
|
||||
* Error thrown if [[QuickJSContext.unwrapResult]] unwraps an error value that isn't an object.
|
||||
*/
|
||||
class QuickJSUnwrapError extends Error {
|
||||
constructor(cause, context) {
|
||||
super(String(cause));
|
||||
this.cause = cause;
|
||||
this.context = context;
|
||||
this.name = "QuickJSUnwrapError";
|
||||
}
|
||||
}
|
||||
exports.QuickJSUnwrapError = QuickJSUnwrapError;
|
||||
class QuickJSWrongOwner extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSWrongOwner";
|
||||
}
|
||||
}
|
||||
exports.QuickJSWrongOwner = QuickJSWrongOwner;
|
||||
class QuickJSUseAfterFree extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSUseAfterFree";
|
||||
}
|
||||
}
|
||||
exports.QuickJSUseAfterFree = QuickJSUseAfterFree;
|
||||
class QuickJSNotImplemented extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSNotImplemented";
|
||||
}
|
||||
}
|
||||
exports.QuickJSNotImplemented = QuickJSNotImplemented;
|
||||
class QuickJSAsyncifyError extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSAsyncifyError";
|
||||
}
|
||||
}
|
||||
exports.QuickJSAsyncifyError = QuickJSAsyncifyError;
|
||||
class QuickJSAsyncifySuspended extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSAsyncifySuspended";
|
||||
}
|
||||
}
|
||||
exports.QuickJSAsyncifySuspended = QuickJSAsyncifySuspended;
|
||||
class QuickJSMemoryLeakDetected extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSMemoryLeakDetected";
|
||||
}
|
||||
}
|
||||
exports.QuickJSMemoryLeakDetected = QuickJSMemoryLeakDetected;
|
||||
//# sourceMappingURL=errors.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../ts/errors.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,MAAa,kBAAmB,SAAQ,KAAK;IAE3C,YAAmB,KAAc,EAAS,OAAwB;QAChE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QADH,UAAK,GAAL,KAAK,CAAS;QAAS,YAAO,GAAP,OAAO,CAAiB;QADlE,SAAI,GAAG,oBAAoB,CAAA;IAG3B,CAAC;CACF;AALD,gDAKC;AAED,MAAa,iBAAkB,SAAQ,KAAK;IAA5C;;QACE,SAAI,GAAG,mBAAmB,CAAA;IAC5B,CAAC;CAAA;AAFD,8CAEC;AAED,MAAa,mBAAoB,SAAQ,KAAK;IAA9C;;QACE,SAAI,GAAG,qBAAqB,CAAA;IAC9B,CAAC;CAAA;AAFD,kDAEC;AAED,MAAa,qBAAsB,SAAQ,KAAK;IAAhD;;QACE,SAAI,GAAG,uBAAuB,CAAA;IAChC,CAAC;CAAA;AAFD,sDAEC;AAED,MAAa,oBAAqB,SAAQ,KAAK;IAA/C;;QACE,SAAI,GAAG,sBAAsB,CAAA;IAC/B,CAAC;CAAA;AAFD,oDAEC;AAED,MAAa,wBAAyB,SAAQ,KAAK;IAAnD;;QACE,SAAI,GAAG,0BAA0B,CAAA;IACnC,CAAC;CAAA;AAFD,4DAEC;AAED,MAAa,yBAA0B,SAAQ,KAAK;IAApD;;QACE,SAAI,GAAG,2BAA2B,CAAA;IACpC,CAAC;CAAA;AAFD,8DAEC","sourcesContent":["import type { QuickJSContext } from \"./context\"\n\n/**\n * Error thrown if [[QuickJSContext.unwrapResult]] unwraps an error value that isn't an object.\n */\nexport class QuickJSUnwrapError extends Error {\n name = \"QuickJSUnwrapError\"\n constructor(public cause: unknown, public context?: QuickJSContext) {\n super(String(cause))\n }\n}\n\nexport class QuickJSWrongOwner extends Error {\n name = \"QuickJSWrongOwner\"\n}\n\nexport class QuickJSUseAfterFree extends Error {\n name = \"QuickJSUseAfterFree\"\n}\n\nexport class QuickJSNotImplemented extends Error {\n name = \"QuickJSNotImplemented\"\n}\n\nexport class QuickJSAsyncifyError extends Error {\n name = \"QuickJSAsyncifyError\"\n}\n\nexport class QuickJSAsyncifySuspended extends Error {\n name = \"QuickJSAsyncifySuspended\"\n}\n\nexport class QuickJSMemoryLeakDetected extends Error {\n name = \"QuickJSMemoryLeakDetected\"\n}\n"]}
|
||||
9
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.d.ts
generated
vendored
Normal file
9
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.d.ts
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/** Typescript thinks import('...js/.d.ts') needs mod.default.default */
|
||||
declare function fakeUnwrapDefault<T>(mod: {
|
||||
default: T;
|
||||
}): T;
|
||||
/** Typescript thinks import('...ts') doesn't need mod.default.default, but does */
|
||||
declare function actualUnwrapDefault<T>(mod: T): T;
|
||||
export declare const unwrapTypescript: typeof actualUnwrapDefault;
|
||||
export declare const unwrapJavascript: typeof fakeUnwrapDefault;
|
||||
export {};
|
||||
19
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js
generated
vendored
Normal file
19
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.unwrapJavascript = exports.unwrapTypescript = void 0;
|
||||
/** Typescript thinks import('...js/.d.ts') needs mod.default.default */
|
||||
function fakeUnwrapDefault(mod) {
|
||||
// console.log("fakeUnwrapDefault", mod)
|
||||
return mod.default;
|
||||
}
|
||||
/** Typescript thinks import('...ts') doesn't need mod.default.default, but does */
|
||||
function actualUnwrapDefault(mod) {
|
||||
// console.log("actualUnwrapDefault", mod)
|
||||
const maybeUnwrap = mod.default;
|
||||
return maybeUnwrap ?? mod;
|
||||
}
|
||||
// I'm not sure if this behavior is needed in all runtimes,
|
||||
// or just for mocha + ts-node.
|
||||
exports.unwrapTypescript = actualUnwrapDefault;
|
||||
exports.unwrapJavascript = fakeUnwrapDefault;
|
||||
//# sourceMappingURL=esmHelpers.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"esmHelpers.js","sourceRoot":"","sources":["../ts/esmHelpers.ts"],"names":[],"mappings":";;;AAAA,wEAAwE;AACxE,SAAS,iBAAiB,CAAI,GAAmB;IAC/C,wCAAwC;IACxC,OAAO,GAAG,CAAC,OAAY,CAAA;AACzB,CAAC;AAED,mFAAmF;AACnF,SAAS,mBAAmB,CAAI,GAAM;IACpC,0CAA0C;IAC1C,MAAM,WAAW,GAAI,GAAW,CAAC,OAAO,CAAA;IACxC,OAAO,WAAW,IAAI,GAAG,CAAA;AAC3B,CAAC;AAED,2DAA2D;AAC3D,+BAA+B;AAClB,QAAA,gBAAgB,GAAG,mBAAmB,CAAA;AACtC,QAAA,gBAAgB,GAAG,iBAAiB,CAAA","sourcesContent":["/** Typescript thinks import('...js/.d.ts') needs mod.default.default */\nfunction fakeUnwrapDefault<T>(mod: { default: T }): T {\n // console.log(\"fakeUnwrapDefault\", mod)\n return mod.default as T\n}\n\n/** Typescript thinks import('...ts') doesn't need mod.default.default, but does */\nfunction actualUnwrapDefault<T>(mod: T): T {\n // console.log(\"actualUnwrapDefault\", mod)\n const maybeUnwrap = (mod as any).default\n return maybeUnwrap ?? mod\n}\n\n// I'm not sure if this behavior is needed in all runtimes,\n// or just for mocha + ts-node.\nexport const unwrapTypescript = actualUnwrapDefault\nexport const unwrapJavascript = fakeUnwrapDefault\n"]}
|
||||
5
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.d.ts
generated
vendored
Normal file
5
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.d.ts
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export = QuickJSRaw;
|
||||
declare function QuickJSRaw(QuickJSRaw?: {}): any;
|
||||
declare namespace QuickJSRaw {
|
||||
export { QuickJSRaw };
|
||||
}
|
||||
387
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js
generated
vendored
Normal file
387
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
67
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.d.ts
generated
vendored
Normal file
67
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.d.ts
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
import { QuickJSEmscriptenModule } from "../emscripten-types";
|
||||
import { JSRuntimePointer, JSContextPointer, JSContextPointerPointer, JSValuePointer, JSValueConstPointer, JSValuePointerPointer, JSValueConstPointerPointer, BorrowedHeapCharPointer, OwnedHeapCharPointer, JSBorrowedCharPointer, JSVoidPointer, EvalFlags, EvalDetectModule } from "../types-ffi";
|
||||
/**
|
||||
* Low-level FFI bindings to QuickJS's Emscripten module.
|
||||
* See instead [[QuickJSContext]], the public Javascript interface exposed by this
|
||||
* library.
|
||||
*
|
||||
* @unstable The FFI interface is considered private and may change.
|
||||
*/
|
||||
export declare class QuickJSFFI {
|
||||
private module;
|
||||
constructor(module: QuickJSEmscriptenModule);
|
||||
/** Set at compile time. */
|
||||
readonly DEBUG = false;
|
||||
QTS_Throw: (ctx: JSContextPointer, error: JSValuePointer | JSValueConstPointer) => JSValuePointer;
|
||||
QTS_NewError: (ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_RuntimeSetMemoryLimit: (rt: JSRuntimePointer, limit: number) => void;
|
||||
QTS_RuntimeComputeMemoryUsage: (rt: JSRuntimePointer, ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_RuntimeDumpMemoryUsage: (rt: JSRuntimePointer) => OwnedHeapCharPointer;
|
||||
QTS_RecoverableLeakCheck: () => number;
|
||||
QTS_BuildIsSanitizeLeak: () => number;
|
||||
QTS_RuntimeSetMaxStackSize: (rt: JSRuntimePointer, stack_size: number) => void;
|
||||
QTS_GetUndefined: () => JSValueConstPointer;
|
||||
QTS_GetNull: () => JSValueConstPointer;
|
||||
QTS_GetFalse: () => JSValueConstPointer;
|
||||
QTS_GetTrue: () => JSValueConstPointer;
|
||||
QTS_NewRuntime: () => JSRuntimePointer;
|
||||
QTS_FreeRuntime: (rt: JSRuntimePointer) => void;
|
||||
QTS_NewContext: (rt: JSRuntimePointer) => JSContextPointer;
|
||||
QTS_FreeContext: (ctx: JSContextPointer) => void;
|
||||
QTS_FreeValuePointer: (ctx: JSContextPointer, value: JSValuePointer) => void;
|
||||
QTS_FreeValuePointerRuntime: (rt: JSRuntimePointer, value: JSValuePointer) => void;
|
||||
QTS_FreeVoidPointer: (ctx: JSContextPointer, ptr: JSVoidPointer) => void;
|
||||
QTS_FreeCString: (ctx: JSContextPointer, str: JSBorrowedCharPointer) => void;
|
||||
QTS_DupValuePointer: (ctx: JSContextPointer, val: JSValuePointer | JSValueConstPointer) => JSValuePointer;
|
||||
QTS_NewObject: (ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_NewObjectProto: (ctx: JSContextPointer, proto: JSValuePointer | JSValueConstPointer) => JSValuePointer;
|
||||
QTS_NewArray: (ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_NewFloat64: (ctx: JSContextPointer, num: number) => JSValuePointer;
|
||||
QTS_GetFloat64: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => number;
|
||||
QTS_NewString: (ctx: JSContextPointer, string: BorrowedHeapCharPointer) => JSValuePointer;
|
||||
QTS_GetString: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => JSBorrowedCharPointer;
|
||||
QTS_NewSymbol: (ctx: JSContextPointer, description: BorrowedHeapCharPointer, isGlobal: number) => JSValuePointer;
|
||||
QTS_GetSymbolDescriptionOrKey: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => JSBorrowedCharPointer;
|
||||
QTS_IsGlobalSymbol: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => number;
|
||||
QTS_IsJobPending: (rt: JSRuntimePointer) => number;
|
||||
QTS_ExecutePendingJob: (rt: JSRuntimePointer, maxJobsToExecute: number, lastJobContext: JSContextPointerPointer) => JSValuePointer;
|
||||
QTS_GetProp: (ctx: JSContextPointer, this_val: JSValuePointer | JSValueConstPointer, prop_name: JSValuePointer | JSValueConstPointer) => JSValuePointer;
|
||||
QTS_SetProp: (ctx: JSContextPointer, this_val: JSValuePointer | JSValueConstPointer, prop_name: JSValuePointer | JSValueConstPointer, prop_value: JSValuePointer | JSValueConstPointer) => void;
|
||||
QTS_DefineProp: (ctx: JSContextPointer, this_val: JSValuePointer | JSValueConstPointer, prop_name: JSValuePointer | JSValueConstPointer, prop_value: JSValuePointer | JSValueConstPointer, get: JSValuePointer | JSValueConstPointer, set: JSValuePointer | JSValueConstPointer, configurable: boolean, enumerable: boolean, has_value: boolean) => void;
|
||||
QTS_Call: (ctx: JSContextPointer, func_obj: JSValuePointer | JSValueConstPointer, this_obj: JSValuePointer | JSValueConstPointer, argc: number, argv_ptrs: JSValueConstPointerPointer) => JSValuePointer;
|
||||
QTS_ResolveException: (ctx: JSContextPointer, maybe_exception: JSValuePointer) => JSValuePointer;
|
||||
QTS_Dump: (ctx: JSContextPointer, obj: JSValuePointer | JSValueConstPointer) => JSBorrowedCharPointer;
|
||||
QTS_Eval: (ctx: JSContextPointer, js_code: BorrowedHeapCharPointer, filename: string, detectModule: EvalDetectModule, evalFlags: EvalFlags) => JSValuePointer;
|
||||
QTS_Typeof: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => OwnedHeapCharPointer;
|
||||
QTS_GetGlobalObject: (ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_NewPromiseCapability: (ctx: JSContextPointer, resolve_funcs_out: JSValuePointerPointer) => JSValuePointer;
|
||||
QTS_TestStringArg: (string: string) => void;
|
||||
QTS_BuildIsDebug: () => number;
|
||||
QTS_BuildIsAsyncify: () => number;
|
||||
QTS_NewFunction: (ctx: JSContextPointer, func_id: number, name: string) => JSValuePointer;
|
||||
QTS_ArgvGetJSValueConstPointer: (argv: JSValuePointer | JSValueConstPointer, index: number) => JSValueConstPointer;
|
||||
QTS_RuntimeEnableInterruptHandler: (rt: JSRuntimePointer) => void;
|
||||
QTS_RuntimeDisableInterruptHandler: (rt: JSRuntimePointer) => void;
|
||||
QTS_RuntimeEnableModuleLoader: (rt: JSRuntimePointer, use_custom_normalize: number) => void;
|
||||
QTS_RuntimeDisableModuleLoader: (rt: JSRuntimePointer) => void;
|
||||
}
|
||||
71
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js
generated
vendored
Normal file
71
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSFFI = void 0;
|
||||
/**
|
||||
* Low-level FFI bindings to QuickJS's Emscripten module.
|
||||
* See instead [[QuickJSContext]], the public Javascript interface exposed by this
|
||||
* library.
|
||||
*
|
||||
* @unstable The FFI interface is considered private and may change.
|
||||
*/
|
||||
class QuickJSFFI {
|
||||
constructor(module) {
|
||||
this.module = module;
|
||||
/** Set at compile time. */
|
||||
this.DEBUG = false;
|
||||
this.QTS_Throw = this.module.cwrap("QTS_Throw", "number", ["number", "number"]);
|
||||
this.QTS_NewError = this.module.cwrap("QTS_NewError", "number", ["number"]);
|
||||
this.QTS_RuntimeSetMemoryLimit = this.module.cwrap("QTS_RuntimeSetMemoryLimit", null, ["number", "number"]);
|
||||
this.QTS_RuntimeComputeMemoryUsage = this.module.cwrap("QTS_RuntimeComputeMemoryUsage", "number", ["number", "number"]);
|
||||
this.QTS_RuntimeDumpMemoryUsage = this.module.cwrap("QTS_RuntimeDumpMemoryUsage", "number", ["number"]);
|
||||
this.QTS_RecoverableLeakCheck = this.module.cwrap("QTS_RecoverableLeakCheck", "number", []);
|
||||
this.QTS_BuildIsSanitizeLeak = this.module.cwrap("QTS_BuildIsSanitizeLeak", "number", []);
|
||||
this.QTS_RuntimeSetMaxStackSize = this.module.cwrap("QTS_RuntimeSetMaxStackSize", null, ["number", "number"]);
|
||||
this.QTS_GetUndefined = this.module.cwrap("QTS_GetUndefined", "number", []);
|
||||
this.QTS_GetNull = this.module.cwrap("QTS_GetNull", "number", []);
|
||||
this.QTS_GetFalse = this.module.cwrap("QTS_GetFalse", "number", []);
|
||||
this.QTS_GetTrue = this.module.cwrap("QTS_GetTrue", "number", []);
|
||||
this.QTS_NewRuntime = this.module.cwrap("QTS_NewRuntime", "number", []);
|
||||
this.QTS_FreeRuntime = this.module.cwrap("QTS_FreeRuntime", null, ["number"]);
|
||||
this.QTS_NewContext = this.module.cwrap("QTS_NewContext", "number", ["number"]);
|
||||
this.QTS_FreeContext = this.module.cwrap("QTS_FreeContext", null, ["number"]);
|
||||
this.QTS_FreeValuePointer = this.module.cwrap("QTS_FreeValuePointer", null, ["number", "number"]);
|
||||
this.QTS_FreeValuePointerRuntime = this.module.cwrap("QTS_FreeValuePointerRuntime", null, ["number", "number"]);
|
||||
this.QTS_FreeVoidPointer = this.module.cwrap("QTS_FreeVoidPointer", null, ["number", "number"]);
|
||||
this.QTS_FreeCString = this.module.cwrap("QTS_FreeCString", null, ["number", "number"]);
|
||||
this.QTS_DupValuePointer = this.module.cwrap("QTS_DupValuePointer", "number", ["number", "number"]);
|
||||
this.QTS_NewObject = this.module.cwrap("QTS_NewObject", "number", ["number"]);
|
||||
this.QTS_NewObjectProto = this.module.cwrap("QTS_NewObjectProto", "number", ["number", "number"]);
|
||||
this.QTS_NewArray = this.module.cwrap("QTS_NewArray", "number", ["number"]);
|
||||
this.QTS_NewFloat64 = this.module.cwrap("QTS_NewFloat64", "number", ["number", "number"]);
|
||||
this.QTS_GetFloat64 = this.module.cwrap("QTS_GetFloat64", "number", ["number", "number"]);
|
||||
this.QTS_NewString = this.module.cwrap("QTS_NewString", "number", ["number", "number"]);
|
||||
this.QTS_GetString = this.module.cwrap("QTS_GetString", "number", ["number", "number"]);
|
||||
this.QTS_NewSymbol = this.module.cwrap("QTS_NewSymbol", "number", ["number", "number", "number"]);
|
||||
this.QTS_GetSymbolDescriptionOrKey = this.module.cwrap("QTS_GetSymbolDescriptionOrKey", "number", ["number", "number"]);
|
||||
this.QTS_IsGlobalSymbol = this.module.cwrap("QTS_IsGlobalSymbol", "number", ["number", "number"]);
|
||||
this.QTS_IsJobPending = this.module.cwrap("QTS_IsJobPending", "number", ["number"]);
|
||||
this.QTS_ExecutePendingJob = this.module.cwrap("QTS_ExecutePendingJob", "number", ["number", "number", "number"]);
|
||||
this.QTS_GetProp = this.module.cwrap("QTS_GetProp", "number", ["number", "number", "number"]);
|
||||
this.QTS_SetProp = this.module.cwrap("QTS_SetProp", null, ["number", "number", "number", "number"]);
|
||||
this.QTS_DefineProp = this.module.cwrap("QTS_DefineProp", null, ["number", "number", "number", "number", "number", "number", "boolean", "boolean", "boolean"]);
|
||||
this.QTS_Call = this.module.cwrap("QTS_Call", "number", ["number", "number", "number", "number", "number"]);
|
||||
this.QTS_ResolveException = this.module.cwrap("QTS_ResolveException", "number", ["number", "number"]);
|
||||
this.QTS_Dump = this.module.cwrap("QTS_Dump", "number", ["number", "number"]);
|
||||
this.QTS_Eval = this.module.cwrap("QTS_Eval", "number", ["number", "number", "string", "number", "number"]);
|
||||
this.QTS_Typeof = this.module.cwrap("QTS_Typeof", "number", ["number", "number"]);
|
||||
this.QTS_GetGlobalObject = this.module.cwrap("QTS_GetGlobalObject", "number", ["number"]);
|
||||
this.QTS_NewPromiseCapability = this.module.cwrap("QTS_NewPromiseCapability", "number", ["number", "number"]);
|
||||
this.QTS_TestStringArg = this.module.cwrap("QTS_TestStringArg", null, ["string"]);
|
||||
this.QTS_BuildIsDebug = this.module.cwrap("QTS_BuildIsDebug", "number", []);
|
||||
this.QTS_BuildIsAsyncify = this.module.cwrap("QTS_BuildIsAsyncify", "number", []);
|
||||
this.QTS_NewFunction = this.module.cwrap("QTS_NewFunction", "number", ["number", "number", "string"]);
|
||||
this.QTS_ArgvGetJSValueConstPointer = this.module.cwrap("QTS_ArgvGetJSValueConstPointer", "number", ["number", "number"]);
|
||||
this.QTS_RuntimeEnableInterruptHandler = this.module.cwrap("QTS_RuntimeEnableInterruptHandler", null, ["number"]);
|
||||
this.QTS_RuntimeDisableInterruptHandler = this.module.cwrap("QTS_RuntimeDisableInterruptHandler", null, ["number"]);
|
||||
this.QTS_RuntimeEnableModuleLoader = this.module.cwrap("QTS_RuntimeEnableModuleLoader", null, ["number", "number"]);
|
||||
this.QTS_RuntimeDisableModuleLoader = this.module.cwrap("QTS_RuntimeDisableModuleLoader", null, ["number"]);
|
||||
}
|
||||
}
|
||||
exports.QuickJSFFI = QuickJSFFI;
|
||||
//# sourceMappingURL=ffi.WASM_RELEASE_SYNC.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
75
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.d.ts
generated
vendored
Normal file
75
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
import type { QuickJSWASMModule } from "./module";
|
||||
import type { QuickJSRuntime, InterruptHandler } from "./runtime";
|
||||
import type { QuickJSContext } from "./context";
|
||||
export type { QuickJSWASMModule, QuickJSContext, QuickJSRuntime };
|
||||
import type { QuickJSAsyncWASMModule } from "./module-asyncify";
|
||||
import type { QuickJSAsyncRuntime } from "./runtime-asyncify";
|
||||
import type { QuickJSAsyncContext, AsyncFunctionImplementation } from "./context-asyncify";
|
||||
import { AsyncRuntimeOptions, ContextOptions } from "./types";
|
||||
export type { QuickJSAsyncContext, QuickJSAsyncRuntime, QuickJSAsyncWASMModule, AsyncFunctionImplementation, };
|
||||
import { newQuickJSWASMModule, newQuickJSAsyncWASMModule, DEBUG_ASYNC, DEBUG_SYNC, RELEASE_ASYNC, RELEASE_SYNC, SyncBuildVariant, AsyncBuildVariant } from "./variants";
|
||||
export { newQuickJSWASMModule, newQuickJSAsyncWASMModule, DEBUG_ASYNC, DEBUG_SYNC, RELEASE_ASYNC, RELEASE_SYNC, SyncBuildVariant, AsyncBuildVariant, };
|
||||
export * from "./vm-interface";
|
||||
export * from "./lifetime";
|
||||
/** Collects the informative errors this library may throw. */
|
||||
export * as errors from "./errors";
|
||||
export * from "./deferred-promise";
|
||||
export * from "./module-test";
|
||||
export type { StaticJSValue, JSValueConst, JSValue, QuickJSHandle, ContextOptions, ContextEvalOptions, RuntimeOptions, AsyncRuntimeOptions, RuntimeOptionsBase, JSModuleLoader, JSModuleLoadResult, JSModuleLoaderAsync, JSModuleLoadSuccess, JSModuleLoadFailure, JSModuleNormalizer, JSModuleNormalizerAsync, JSModuleNormalizeResult, JSModuleNormalizeFailure, JSModuleNormalizeSuccess, } from "./types";
|
||||
export type { ModuleEvalOptions } from "./module";
|
||||
export type { InterruptHandler, ExecutePendingJobsResult } from "./runtime";
|
||||
export type { QuickJSPropertyKey } from "./context";
|
||||
/**
|
||||
* Get a shared singleton {@link QuickJSWASMModule}. Use this to evaluate code
|
||||
* or create Javascript environments.
|
||||
*
|
||||
* This is the top-level entrypoint for the quickjs-emscripten library.
|
||||
*
|
||||
* If you need strictest possible isolation guarantees, you may create a
|
||||
* separate {@link QuickJSWASMModule} via {@link newQuickJSWASMModule}.
|
||||
*
|
||||
* To work with the asyncified version of this library, see these functions:
|
||||
*
|
||||
* - {@link newAsyncRuntime}.
|
||||
* - {@link newAsyncContext}.
|
||||
* - {@link newQuickJSAsyncWASMModule}.
|
||||
*/
|
||||
export declare function getQuickJS(): Promise<QuickJSWASMModule>;
|
||||
/**
|
||||
* Provides synchronous access to the shared {@link QuickJSWASMModule} instance returned by {@link getQuickJS}, as long as
|
||||
* least once.
|
||||
* @throws If called before `getQuickJS` resolves.
|
||||
*/
|
||||
export declare function getQuickJSSync(): QuickJSWASMModule;
|
||||
/**
|
||||
* Create a new [[QuickJSAsyncRuntime]] in a separate WebAssembly module.
|
||||
*
|
||||
* Each runtime is isolated in a separate WebAssembly module, so that errors in
|
||||
* one runtime cannot contaminate another runtime, and each runtime can execute
|
||||
* an asynchronous action without conflicts.
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
export declare function newAsyncRuntime(options?: AsyncRuntimeOptions): Promise<QuickJSAsyncRuntime>;
|
||||
/**
|
||||
* Create a new [[QuickJSAsyncContext]] (with an associated runtime) in an
|
||||
* separate WebAssembly module.
|
||||
*
|
||||
* Each context is isolated in a separate WebAssembly module, so that errors in
|
||||
* one runtime cannot contaminate another runtime, and each runtime can execute
|
||||
* an asynchronous action without conflicts.
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
export declare function newAsyncContext(options?: ContextOptions): Promise<QuickJSAsyncContext>;
|
||||
/**
|
||||
* Returns an interrupt handler that interrupts Javascript execution after a deadline time.
|
||||
*
|
||||
* @param deadline - Interrupt execution if it's still running after this time.
|
||||
* Number values are compared against `Date.now()`
|
||||
*/
|
||||
export declare function shouldInterruptAfterDeadline(deadline: Date | number): InterruptHandler;
|
||||
128
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.js
generated
vendored
Normal file
128
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.js
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.shouldInterruptAfterDeadline = exports.newAsyncContext = exports.newAsyncRuntime = exports.getQuickJSSync = exports.getQuickJS = exports.errors = exports.RELEASE_SYNC = exports.RELEASE_ASYNC = exports.DEBUG_SYNC = exports.DEBUG_ASYNC = exports.newQuickJSAsyncWASMModule = exports.newQuickJSWASMModule = void 0;
|
||||
// Build variants
|
||||
const variants_1 = require("./variants");
|
||||
Object.defineProperty(exports, "newQuickJSWASMModule", { enumerable: true, get: function () { return variants_1.newQuickJSWASMModule; } });
|
||||
Object.defineProperty(exports, "newQuickJSAsyncWASMModule", { enumerable: true, get: function () { return variants_1.newQuickJSAsyncWASMModule; } });
|
||||
Object.defineProperty(exports, "DEBUG_ASYNC", { enumerable: true, get: function () { return variants_1.DEBUG_ASYNC; } });
|
||||
Object.defineProperty(exports, "DEBUG_SYNC", { enumerable: true, get: function () { return variants_1.DEBUG_SYNC; } });
|
||||
Object.defineProperty(exports, "RELEASE_ASYNC", { enumerable: true, get: function () { return variants_1.RELEASE_ASYNC; } });
|
||||
Object.defineProperty(exports, "RELEASE_SYNC", { enumerable: true, get: function () { return variants_1.RELEASE_SYNC; } });
|
||||
// Export helpers
|
||||
__exportStar(require("./vm-interface"), exports);
|
||||
__exportStar(require("./lifetime"), exports);
|
||||
/** Collects the informative errors this library may throw. */
|
||||
exports.errors = __importStar(require("./errors"));
|
||||
__exportStar(require("./deferred-promise"), exports);
|
||||
__exportStar(require("./module-test"), exports);
|
||||
let singleton = undefined;
|
||||
let singletonPromise = undefined;
|
||||
/**
|
||||
* Get a shared singleton {@link QuickJSWASMModule}. Use this to evaluate code
|
||||
* or create Javascript environments.
|
||||
*
|
||||
* This is the top-level entrypoint for the quickjs-emscripten library.
|
||||
*
|
||||
* If you need strictest possible isolation guarantees, you may create a
|
||||
* separate {@link QuickJSWASMModule} via {@link newQuickJSWASMModule}.
|
||||
*
|
||||
* To work with the asyncified version of this library, see these functions:
|
||||
*
|
||||
* - {@link newAsyncRuntime}.
|
||||
* - {@link newAsyncContext}.
|
||||
* - {@link newQuickJSAsyncWASMModule}.
|
||||
*/
|
||||
async function getQuickJS() {
|
||||
singletonPromise ?? (singletonPromise = (0, variants_1.newQuickJSWASMModule)().then((instance) => {
|
||||
singleton = instance;
|
||||
return instance;
|
||||
}));
|
||||
return await singletonPromise;
|
||||
}
|
||||
exports.getQuickJS = getQuickJS;
|
||||
/**
|
||||
* Provides synchronous access to the shared {@link QuickJSWASMModule} instance returned by {@link getQuickJS}, as long as
|
||||
* least once.
|
||||
* @throws If called before `getQuickJS` resolves.
|
||||
*/
|
||||
function getQuickJSSync() {
|
||||
if (!singleton) {
|
||||
throw new Error("QuickJS not initialized. Await getQuickJS() at least once.");
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
exports.getQuickJSSync = getQuickJSSync;
|
||||
/**
|
||||
* Create a new [[QuickJSAsyncRuntime]] in a separate WebAssembly module.
|
||||
*
|
||||
* Each runtime is isolated in a separate WebAssembly module, so that errors in
|
||||
* one runtime cannot contaminate another runtime, and each runtime can execute
|
||||
* an asynchronous action without conflicts.
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
async function newAsyncRuntime(options) {
|
||||
const module = await (0, variants_1.newQuickJSAsyncWASMModule)();
|
||||
return module.newRuntime(options);
|
||||
}
|
||||
exports.newAsyncRuntime = newAsyncRuntime;
|
||||
/**
|
||||
* Create a new [[QuickJSAsyncContext]] (with an associated runtime) in an
|
||||
* separate WebAssembly module.
|
||||
*
|
||||
* Each context is isolated in a separate WebAssembly module, so that errors in
|
||||
* one runtime cannot contaminate another runtime, and each runtime can execute
|
||||
* an asynchronous action without conflicts.
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
async function newAsyncContext(options) {
|
||||
const module = await (0, variants_1.newQuickJSAsyncWASMModule)();
|
||||
return module.newContext(options);
|
||||
}
|
||||
exports.newAsyncContext = newAsyncContext;
|
||||
/**
|
||||
* Returns an interrupt handler that interrupts Javascript execution after a deadline time.
|
||||
*
|
||||
* @param deadline - Interrupt execution if it's still running after this time.
|
||||
* Number values are compared against `Date.now()`
|
||||
*/
|
||||
function shouldInterruptAfterDeadline(deadline) {
|
||||
const deadlineAsNumber = typeof deadline === "number" ? deadline : deadline.getTime();
|
||||
return function () {
|
||||
return Date.now() > deadlineAsNumber;
|
||||
};
|
||||
}
|
||||
exports.shouldInterruptAfterDeadline = shouldInterruptAfterDeadline;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
115
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.d.ts
generated
vendored
Normal file
115
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.d.ts
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
import { MaybeAsyncBlock } from "./asyncify-helpers";
|
||||
import type { QuickJSHandle } from "./types";
|
||||
/**
|
||||
* An object that can be disposed.
|
||||
* [[Lifetime]] is the canonical implementation of Disposable.
|
||||
* Use [[Scope]] to manage cleaning up multiple disposables.
|
||||
*/
|
||||
export interface Disposable {
|
||||
/**
|
||||
* Dispose of the underlying resources used by this object.
|
||||
*/
|
||||
dispose(): void;
|
||||
/**
|
||||
* @returns true if the object is alive
|
||||
* @returns false after the object has been [[dispose]]d
|
||||
*/
|
||||
alive: boolean;
|
||||
}
|
||||
/**
|
||||
* A lifetime prevents access to a value after the lifetime has been
|
||||
* [[dispose]]ed.
|
||||
*
|
||||
* Typically, quickjs-emscripten uses Lifetimes to protect C memory pointers.
|
||||
*/
|
||||
export declare class Lifetime<T, TCopy = never, Owner = never> implements Disposable {
|
||||
protected readonly _value: T;
|
||||
protected readonly copier?: ((value: T | TCopy) => TCopy) | undefined;
|
||||
protected readonly disposer?: ((value: T | TCopy) => void) | undefined;
|
||||
protected readonly _owner?: Owner | undefined;
|
||||
protected _alive: boolean;
|
||||
protected _constructorStack: string | undefined;
|
||||
/**
|
||||
* When the Lifetime is disposed, it will call `disposer(_value)`. Use the
|
||||
* disposer function to implement whatever cleanup needs to happen at the end
|
||||
* of `value`'s lifetime.
|
||||
*
|
||||
* `_owner` is not used or controlled by the lifetime. It's just metadata for
|
||||
* the creator.
|
||||
*/
|
||||
constructor(_value: T, copier?: ((value: T | TCopy) => TCopy) | undefined, disposer?: ((value: T | TCopy) => void) | undefined, _owner?: Owner | undefined);
|
||||
get alive(): boolean;
|
||||
/**
|
||||
* The value this Lifetime protects. You must never retain the value - it
|
||||
* may become invalid, leading to memory errors.
|
||||
*
|
||||
* @throws If the lifetime has been [[dispose]]d already.
|
||||
*/
|
||||
get value(): T;
|
||||
get owner(): Owner | undefined;
|
||||
get dupable(): boolean;
|
||||
/**
|
||||
* Create a new handle pointing to the same [[value]].
|
||||
*/
|
||||
dup(): Lifetime<TCopy, TCopy, Owner>;
|
||||
/**
|
||||
* Call `map` with this lifetime, then dispose the lifetime.
|
||||
* @return the result of `map(this)`.
|
||||
*/
|
||||
consume<O>(map: (lifetime: this) => O): O;
|
||||
consume<O>(map: (lifetime: QuickJSHandle) => O): O;
|
||||
/**
|
||||
* Dispose of [[value]] and perform cleanup.
|
||||
*/
|
||||
dispose(): void;
|
||||
private assertAlive;
|
||||
}
|
||||
/**
|
||||
* A Lifetime that lives forever. Used for constants.
|
||||
*/
|
||||
export declare class StaticLifetime<T, Owner = never> extends Lifetime<T, T, Owner> {
|
||||
constructor(value: T, owner?: Owner);
|
||||
get dupable(): boolean;
|
||||
dup(): this;
|
||||
dispose(): void;
|
||||
}
|
||||
/**
|
||||
* A Lifetime that does not own its `value`. A WeakLifetime never calls its
|
||||
* `disposer` function, but can be `dup`ed to produce regular lifetimes that
|
||||
* do.
|
||||
*
|
||||
* Used for function arguments.
|
||||
*/
|
||||
export declare class WeakLifetime<T, TCopy = never, Owner = never> extends Lifetime<T, TCopy, Owner> {
|
||||
constructor(value: T, copier?: (value: T | TCopy) => TCopy, disposer?: (value: TCopy) => void, owner?: Owner);
|
||||
dispose(): void;
|
||||
}
|
||||
/**
|
||||
* Scope helps reduce the burden of manually tracking and disposing of
|
||||
* Lifetimes. See [[withScope]]. and [[withScopeAsync]].
|
||||
*/
|
||||
export declare class Scope implements Disposable {
|
||||
/**
|
||||
* Run `block` with a new Scope instance that will be disposed after the block returns.
|
||||
* Inside `block`, call `scope.manage` on each lifetime you create to have the lifetime
|
||||
* automatically disposed after the block returns.
|
||||
*
|
||||
* @warning Do not use with async functions. Instead, use [[withScopeAsync]].
|
||||
*/
|
||||
static withScope<R>(block: (scope: Scope) => R): R;
|
||||
static withScopeMaybeAsync<Return, This, Yielded>(_this: This, block: MaybeAsyncBlock<Return, This, Yielded, [Scope]>): Return | Promise<Return>;
|
||||
/**
|
||||
* Run `block` with a new Scope instance that will be disposed after the
|
||||
* block's returned promise settles. Inside `block`, call `scope.manage` on each
|
||||
* lifetime you create to have the lifetime automatically disposed after the
|
||||
* block returns.
|
||||
*/
|
||||
static withScopeAsync<R>(block: (scope: Scope) => Promise<R>): Promise<R>;
|
||||
private _disposables;
|
||||
/**
|
||||
* Track `lifetime` so that it is disposed when this scope is disposed.
|
||||
*/
|
||||
manage<T extends Disposable>(lifetime: T): T;
|
||||
get alive(): boolean;
|
||||
dispose(): void;
|
||||
}
|
||||
227
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js
generated
vendored
Normal file
227
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js
generated
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Scope = exports.WeakLifetime = exports.StaticLifetime = exports.Lifetime = void 0;
|
||||
const asyncify_helpers_1 = require("./asyncify-helpers");
|
||||
const debug_1 = require("./debug");
|
||||
const errors_1 = require("./errors");
|
||||
/**
|
||||
* A lifetime prevents access to a value after the lifetime has been
|
||||
* [[dispose]]ed.
|
||||
*
|
||||
* Typically, quickjs-emscripten uses Lifetimes to protect C memory pointers.
|
||||
*/
|
||||
class Lifetime {
|
||||
/**
|
||||
* When the Lifetime is disposed, it will call `disposer(_value)`. Use the
|
||||
* disposer function to implement whatever cleanup needs to happen at the end
|
||||
* of `value`'s lifetime.
|
||||
*
|
||||
* `_owner` is not used or controlled by the lifetime. It's just metadata for
|
||||
* the creator.
|
||||
*/
|
||||
constructor(_value, copier, disposer, _owner) {
|
||||
this._value = _value;
|
||||
this.copier = copier;
|
||||
this.disposer = disposer;
|
||||
this._owner = _owner;
|
||||
this._alive = true;
|
||||
this._constructorStack = debug_1.QTS_DEBUG ? new Error("Lifetime constructed").stack : undefined;
|
||||
}
|
||||
get alive() {
|
||||
return this._alive;
|
||||
}
|
||||
/**
|
||||
* The value this Lifetime protects. You must never retain the value - it
|
||||
* may become invalid, leading to memory errors.
|
||||
*
|
||||
* @throws If the lifetime has been [[dispose]]d already.
|
||||
*/
|
||||
get value() {
|
||||
this.assertAlive();
|
||||
return this._value;
|
||||
}
|
||||
get owner() {
|
||||
return this._owner;
|
||||
}
|
||||
get dupable() {
|
||||
return !!this.copier;
|
||||
}
|
||||
/**
|
||||
* Create a new handle pointing to the same [[value]].
|
||||
*/
|
||||
dup() {
|
||||
this.assertAlive();
|
||||
if (!this.copier) {
|
||||
throw new Error("Non-dupable lifetime");
|
||||
}
|
||||
return new Lifetime(this.copier(this._value), this.copier, this.disposer, this._owner);
|
||||
}
|
||||
consume(map) {
|
||||
this.assertAlive();
|
||||
const result = map(this);
|
||||
this.dispose();
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Dispose of [[value]] and perform cleanup.
|
||||
*/
|
||||
dispose() {
|
||||
this.assertAlive();
|
||||
if (this.disposer) {
|
||||
this.disposer(this._value);
|
||||
}
|
||||
this._alive = false;
|
||||
}
|
||||
assertAlive() {
|
||||
if (!this.alive) {
|
||||
if (this._constructorStack) {
|
||||
throw new errors_1.QuickJSUseAfterFree(`Lifetime not alive\n${this._constructorStack}\nLifetime used`);
|
||||
}
|
||||
throw new errors_1.QuickJSUseAfterFree("Lifetime not alive");
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Lifetime = Lifetime;
|
||||
/**
|
||||
* A Lifetime that lives forever. Used for constants.
|
||||
*/
|
||||
class StaticLifetime extends Lifetime {
|
||||
constructor(value, owner) {
|
||||
super(value, undefined, undefined, owner);
|
||||
}
|
||||
// Static lifetime doesn't need a copier to be copiable
|
||||
get dupable() {
|
||||
return true;
|
||||
}
|
||||
// Copy returns the same instance.
|
||||
dup() {
|
||||
return this;
|
||||
}
|
||||
// Dispose does nothing.
|
||||
dispose() { }
|
||||
}
|
||||
exports.StaticLifetime = StaticLifetime;
|
||||
/**
|
||||
* A Lifetime that does not own its `value`. A WeakLifetime never calls its
|
||||
* `disposer` function, but can be `dup`ed to produce regular lifetimes that
|
||||
* do.
|
||||
*
|
||||
* Used for function arguments.
|
||||
*/
|
||||
class WeakLifetime extends Lifetime {
|
||||
constructor(value, copier, disposer, owner) {
|
||||
// We don't care if the disposer doesn't support freeing T
|
||||
super(value, copier, disposer, owner);
|
||||
}
|
||||
dispose() {
|
||||
this._alive = false;
|
||||
}
|
||||
}
|
||||
exports.WeakLifetime = WeakLifetime;
|
||||
function scopeFinally(scope, blockError) {
|
||||
// console.log('scopeFinally', scope, blockError)
|
||||
let disposeError;
|
||||
try {
|
||||
scope.dispose();
|
||||
}
|
||||
catch (error) {
|
||||
disposeError = error;
|
||||
}
|
||||
if (blockError && disposeError) {
|
||||
Object.assign(blockError, {
|
||||
message: `${blockError.message}\n Then, failed to dispose scope: ${disposeError.message}`,
|
||||
disposeError,
|
||||
});
|
||||
throw blockError;
|
||||
}
|
||||
if (blockError || disposeError) {
|
||||
throw blockError || disposeError;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Scope helps reduce the burden of manually tracking and disposing of
|
||||
* Lifetimes. See [[withScope]]. and [[withScopeAsync]].
|
||||
*/
|
||||
class Scope {
|
||||
constructor() {
|
||||
this._disposables = new Lifetime(new Set());
|
||||
}
|
||||
/**
|
||||
* Run `block` with a new Scope instance that will be disposed after the block returns.
|
||||
* Inside `block`, call `scope.manage` on each lifetime you create to have the lifetime
|
||||
* automatically disposed after the block returns.
|
||||
*
|
||||
* @warning Do not use with async functions. Instead, use [[withScopeAsync]].
|
||||
*/
|
||||
static withScope(block) {
|
||||
const scope = new Scope();
|
||||
let blockError;
|
||||
try {
|
||||
return block(scope);
|
||||
}
|
||||
catch (error) {
|
||||
blockError = error;
|
||||
throw error;
|
||||
}
|
||||
finally {
|
||||
scopeFinally(scope, blockError);
|
||||
}
|
||||
}
|
||||
static withScopeMaybeAsync(_this, block) {
|
||||
return (0, asyncify_helpers_1.maybeAsync)(undefined, function* (awaited) {
|
||||
const scope = new Scope();
|
||||
let blockError;
|
||||
try {
|
||||
return yield* awaited.of(block.call(_this, awaited, scope));
|
||||
}
|
||||
catch (error) {
|
||||
blockError = error;
|
||||
throw error;
|
||||
}
|
||||
finally {
|
||||
scopeFinally(scope, blockError);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Run `block` with a new Scope instance that will be disposed after the
|
||||
* block's returned promise settles. Inside `block`, call `scope.manage` on each
|
||||
* lifetime you create to have the lifetime automatically disposed after the
|
||||
* block returns.
|
||||
*/
|
||||
static async withScopeAsync(block) {
|
||||
const scope = new Scope();
|
||||
let blockError;
|
||||
try {
|
||||
return await block(scope);
|
||||
}
|
||||
catch (error) {
|
||||
blockError = error;
|
||||
throw error;
|
||||
}
|
||||
finally {
|
||||
scopeFinally(scope, blockError);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Track `lifetime` so that it is disposed when this scope is disposed.
|
||||
*/
|
||||
manage(lifetime) {
|
||||
this._disposables.value.add(lifetime);
|
||||
return lifetime;
|
||||
}
|
||||
get alive() {
|
||||
return this._disposables.alive;
|
||||
}
|
||||
dispose() {
|
||||
const lifetimes = Array.from(this._disposables.value.values()).reverse();
|
||||
for (const lifetime of lifetimes) {
|
||||
if (lifetime.alive) {
|
||||
lifetime.dispose();
|
||||
}
|
||||
}
|
||||
this._disposables.dispose();
|
||||
}
|
||||
}
|
||||
exports.Scope = Scope;
|
||||
//# sourceMappingURL=lifetime.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
18
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.d.ts
generated
vendored
Normal file
18
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.d.ts
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import { EitherModule } from "./emscripten-types";
|
||||
import { OwnedHeapCharPointer, JSContextPointerPointer, JSValueConstPointerPointer, JSValuePointerPointer } from "./types-ffi";
|
||||
import { Lifetime } from "./lifetime";
|
||||
import { QuickJSHandle } from "./types";
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export declare class ModuleMemory {
|
||||
module: EitherModule;
|
||||
constructor(module: EitherModule);
|
||||
toPointerArray(handleArray: QuickJSHandle[]): Lifetime<JSValueConstPointerPointer>;
|
||||
newMutablePointerArray<T extends JSContextPointerPointer | JSValuePointerPointer>(length: number): Lifetime<{
|
||||
typedArray: Int32Array;
|
||||
ptr: T;
|
||||
}>;
|
||||
newHeapCharPointer(string: string): Lifetime<OwnedHeapCharPointer>;
|
||||
consumeHeapCharPointer(ptr: OwnedHeapCharPointer): string;
|
||||
}
|
||||
41
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js
generated
vendored
Normal file
41
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ModuleMemory = void 0;
|
||||
const lifetime_1 = require("./lifetime");
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
class ModuleMemory {
|
||||
constructor(module) {
|
||||
this.module = module;
|
||||
}
|
||||
toPointerArray(handleArray) {
|
||||
const typedArray = new Int32Array(handleArray.map((handle) => handle.value));
|
||||
const numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT;
|
||||
const ptr = this.module._malloc(numBytes);
|
||||
var heapBytes = new Uint8Array(this.module.HEAPU8.buffer, ptr, numBytes);
|
||||
heapBytes.set(new Uint8Array(typedArray.buffer));
|
||||
return new lifetime_1.Lifetime(ptr, undefined, (ptr) => this.module._free(ptr));
|
||||
}
|
||||
newMutablePointerArray(length) {
|
||||
const zeros = new Int32Array(new Array(length).fill(0));
|
||||
const numBytes = zeros.length * zeros.BYTES_PER_ELEMENT;
|
||||
const ptr = this.module._malloc(numBytes);
|
||||
const typedArray = new Int32Array(this.module.HEAPU8.buffer, ptr, length);
|
||||
typedArray.set(zeros);
|
||||
return new lifetime_1.Lifetime({ typedArray, ptr }, undefined, (value) => this.module._free(value.ptr));
|
||||
}
|
||||
newHeapCharPointer(string) {
|
||||
const numBytes = this.module.lengthBytesUTF8(string) + 1;
|
||||
const ptr = this.module._malloc(numBytes);
|
||||
this.module.stringToUTF8(string, ptr, numBytes);
|
||||
return new lifetime_1.Lifetime(ptr, undefined, (value) => this.module._free(value));
|
||||
}
|
||||
consumeHeapCharPointer(ptr) {
|
||||
const str = this.module.UTF8ToString(ptr);
|
||||
this.module._free(ptr);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
exports.ModuleMemory = ModuleMemory;
|
||||
//# sourceMappingURL=memory.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../ts/memory.ts"],"names":[],"mappings":";;;AAOA,yCAAqC;AAGrC;;GAEG;AACH,MAAa,YAAY;IACvB,YAAmB,MAAoB;QAApB,WAAM,GAAN,MAAM,CAAc;IAAG,CAAC;IAE3C,cAAc,CAAC,WAA4B;QACzC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5E,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,iBAAiB,CAAA;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAA+B,CAAA;QACvE,IAAI,SAAS,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;QACxE,SAAS,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAA;QAChD,OAAO,IAAI,mBAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IACtE,CAAC;IAED,sBAAsB,CACpB,MAAc;QAEd,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QACvD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAA;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAM,CAAA;QAC9C,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QACzE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACrB,OAAO,IAAI,mBAAQ,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IAC9F,CAAC;IAED,kBAAkB,CAAC,MAAc;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACxD,MAAM,GAAG,GAAyB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAyB,CAAA;QACvF,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;QAC/C,OAAO,IAAI,mBAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1E,CAAC;IAED,sBAAsB,CAAC,GAAyB;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACtB,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;AAnCD,oCAmCC","sourcesContent":["import { EitherModule } from \"./emscripten-types\"\nimport {\n OwnedHeapCharPointer,\n JSContextPointerPointer,\n JSValueConstPointerPointer,\n JSValuePointerPointer,\n} from \"./types-ffi\"\nimport { Lifetime } from \"./lifetime\"\nimport { EitherFFI, QuickJSHandle } from \"./types\"\n\n/**\n * @private\n */\nexport class ModuleMemory {\n constructor(public module: EitherModule) {}\n\n toPointerArray(handleArray: QuickJSHandle[]): Lifetime<JSValueConstPointerPointer> {\n const typedArray = new Int32Array(handleArray.map((handle) => handle.value))\n const numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT\n const ptr = this.module._malloc(numBytes) as JSValueConstPointerPointer\n var heapBytes = new Uint8Array(this.module.HEAPU8.buffer, ptr, numBytes)\n heapBytes.set(new Uint8Array(typedArray.buffer))\n return new Lifetime(ptr, undefined, (ptr) => this.module._free(ptr))\n }\n\n newMutablePointerArray<T extends JSContextPointerPointer | JSValuePointerPointer>(\n length: number\n ): Lifetime<{ typedArray: Int32Array; ptr: T }> {\n const zeros = new Int32Array(new Array(length).fill(0))\n const numBytes = zeros.length * zeros.BYTES_PER_ELEMENT\n const ptr = this.module._malloc(numBytes) as T\n const typedArray = new Int32Array(this.module.HEAPU8.buffer, ptr, length)\n typedArray.set(zeros)\n return new Lifetime({ typedArray, ptr }, undefined, (value) => this.module._free(value.ptr))\n }\n\n newHeapCharPointer(string: string): Lifetime<OwnedHeapCharPointer> {\n const numBytes = this.module.lengthBytesUTF8(string) + 1\n const ptr: OwnedHeapCharPointer = this.module._malloc(numBytes) as OwnedHeapCharPointer\n this.module.stringToUTF8(string, ptr, numBytes)\n return new Lifetime(ptr, undefined, (value) => this.module._free(value))\n }\n\n consumeHeapCharPointer(ptr: OwnedHeapCharPointer): string {\n const str = this.module.UTF8ToString(ptr)\n this.module._free(ptr)\n return str\n }\n}\n"]}
|
||||
53
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-asyncify.d.ts
generated
vendored
Normal file
53
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-asyncify.d.ts
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
import { QuickJSAsyncContext } from "./context-asyncify";
|
||||
import { QuickJSAsyncEmscriptenModule } from "./emscripten-types";
|
||||
import { QuickJSAsyncFFI } from "./variants";
|
||||
import { ModuleEvalOptions, QuickJSWASMModule } from "./module";
|
||||
import { QuickJSAsyncRuntime } from "./runtime-asyncify";
|
||||
import { AsyncRuntimeOptions, ContextOptions } from "./types";
|
||||
/**
|
||||
* Asyncified version of [[QuickJSWASMModule]].
|
||||
*
|
||||
* Due to limitations of Emscripten's ASYNCIFY process, only a single async
|
||||
* function call can happen at a time across the entire WebAssembly module.
|
||||
*
|
||||
* That means that all runtimes, contexts, functions, etc created inside this
|
||||
* WebAssembly are limited to a single concurrent async action.
|
||||
* **Multiple concurrent async actions is an error.**
|
||||
*
|
||||
* To allow for multiple concurrent async actions, you must create multiple WebAssembly
|
||||
* modules.
|
||||
*/
|
||||
export declare class QuickJSAsyncWASMModule extends QuickJSWASMModule {
|
||||
/** @private */
|
||||
protected ffi: QuickJSAsyncFFI;
|
||||
/** @private */
|
||||
protected module: QuickJSAsyncEmscriptenModule;
|
||||
/** @private */
|
||||
constructor(module: QuickJSAsyncEmscriptenModule, ffi: QuickJSAsyncFFI);
|
||||
/**
|
||||
* Create a new async runtime inside this WebAssembly module. All runtimes inside a
|
||||
* module are limited to a single async call at a time. For multiple
|
||||
* concurrent async actions, create multiple WebAssembly modules.
|
||||
*/
|
||||
newRuntime(options?: AsyncRuntimeOptions): QuickJSAsyncRuntime;
|
||||
/**
|
||||
* A simplified API to create a new [[QuickJSRuntime]] and a
|
||||
* [[QuickJSContext]] inside that runtime at the same time. The runtime will
|
||||
* be disposed when the context is disposed.
|
||||
*/
|
||||
newContext(options?: ContextOptions): QuickJSAsyncContext;
|
||||
/** Synchronous evalCode is not supported. */
|
||||
evalCode(): never;
|
||||
/**
|
||||
* One-off evaluate code without needing to create a [[QuickJSRuntimeAsync]] or
|
||||
* [[QuickJSContextSync]] explicitly.
|
||||
*
|
||||
* This version allows for asynchronous Ecmascript module loading.
|
||||
*
|
||||
* Note that only a single async action can occur at a time inside the entire WebAssembly module.
|
||||
* **Multiple concurrent async actions is an error.**
|
||||
*
|
||||
* See the documentation for [[QuickJSWASMModule.evalCode]] for more details.
|
||||
*/
|
||||
evalCodeAsync(code: string, options: ModuleEvalOptions): Promise<unknown>;
|
||||
}
|
||||
97
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-asyncify.js
generated
vendored
Normal file
97
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-asyncify.js
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSAsyncWASMModule = void 0;
|
||||
const errors_1 = require("./errors");
|
||||
const lifetime_1 = require("./lifetime");
|
||||
const module_1 = require("./module");
|
||||
const runtime_asyncify_1 = require("./runtime-asyncify");
|
||||
/**
|
||||
* Asyncified version of [[QuickJSWASMModule]].
|
||||
*
|
||||
* Due to limitations of Emscripten's ASYNCIFY process, only a single async
|
||||
* function call can happen at a time across the entire WebAssembly module.
|
||||
*
|
||||
* That means that all runtimes, contexts, functions, etc created inside this
|
||||
* WebAssembly are limited to a single concurrent async action.
|
||||
* **Multiple concurrent async actions is an error.**
|
||||
*
|
||||
* To allow for multiple concurrent async actions, you must create multiple WebAssembly
|
||||
* modules.
|
||||
*/
|
||||
class QuickJSAsyncWASMModule extends module_1.QuickJSWASMModule {
|
||||
/** @private */
|
||||
constructor(module, ffi) {
|
||||
super(module, ffi);
|
||||
this.ffi = ffi;
|
||||
this.module = module;
|
||||
}
|
||||
/**
|
||||
* Create a new async runtime inside this WebAssembly module. All runtimes inside a
|
||||
* module are limited to a single async call at a time. For multiple
|
||||
* concurrent async actions, create multiple WebAssembly modules.
|
||||
*/
|
||||
newRuntime(options = {}) {
|
||||
const rt = new lifetime_1.Lifetime(this.ffi.QTS_NewRuntime(), undefined, (rt_ptr) => {
|
||||
this.callbacks.deleteRuntime(rt_ptr);
|
||||
this.ffi.QTS_FreeRuntime(rt_ptr);
|
||||
});
|
||||
const runtime = new runtime_asyncify_1.QuickJSAsyncRuntime({
|
||||
module: this.module,
|
||||
ffi: this.ffi,
|
||||
rt,
|
||||
callbacks: this.callbacks,
|
||||
});
|
||||
(0, module_1.applyBaseRuntimeOptions)(runtime, options);
|
||||
if (options.moduleLoader) {
|
||||
runtime.setModuleLoader(options.moduleLoader);
|
||||
}
|
||||
return runtime;
|
||||
}
|
||||
/**
|
||||
* A simplified API to create a new [[QuickJSRuntime]] and a
|
||||
* [[QuickJSContext]] inside that runtime at the same time. The runtime will
|
||||
* be disposed when the context is disposed.
|
||||
*/
|
||||
newContext(options = {}) {
|
||||
const runtime = this.newRuntime();
|
||||
const lifetimes = options.ownedLifetimes ? options.ownedLifetimes.concat([runtime]) : [runtime];
|
||||
const context = runtime.newContext({ ...options, ownedLifetimes: lifetimes });
|
||||
runtime.context = context;
|
||||
return context;
|
||||
}
|
||||
/** Synchronous evalCode is not supported. */
|
||||
evalCode() {
|
||||
throw new errors_1.QuickJSNotImplemented("QuickJSWASMModuleAsyncify.evalCode: use evalCodeAsync instead");
|
||||
}
|
||||
/**
|
||||
* One-off evaluate code without needing to create a [[QuickJSRuntimeAsync]] or
|
||||
* [[QuickJSContextSync]] explicitly.
|
||||
*
|
||||
* This version allows for asynchronous Ecmascript module loading.
|
||||
*
|
||||
* Note that only a single async action can occur at a time inside the entire WebAssembly module.
|
||||
* **Multiple concurrent async actions is an error.**
|
||||
*
|
||||
* See the documentation for [[QuickJSWASMModule.evalCode]] for more details.
|
||||
*/
|
||||
evalCodeAsync(code, options) {
|
||||
// TODO: we should really figure out generator for the Promise monad...
|
||||
return lifetime_1.Scope.withScopeAsync(async (scope) => {
|
||||
const vm = scope.manage(this.newContext());
|
||||
(0, module_1.applyModuleEvalRuntimeOptions)(vm.runtime, options);
|
||||
const result = await vm.evalCodeAsync(code, "eval.js");
|
||||
if (options.memoryLimitBytes !== undefined) {
|
||||
// Remove memory limit so we can dump the result without exceeding it.
|
||||
vm.runtime.setMemoryLimit(-1);
|
||||
}
|
||||
if (result.error) {
|
||||
const error = vm.dump(scope.manage(result.error));
|
||||
throw error;
|
||||
}
|
||||
const value = vm.dump(scope.manage(result.value));
|
||||
return value;
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.QuickJSAsyncWASMModule = QuickJSAsyncWASMModule;
|
||||
//# sourceMappingURL=module-asyncify.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-asyncify.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-asyncify.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
27
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-test.d.ts
generated
vendored
Normal file
27
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-test.d.ts
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import type { QuickJSContext } from "./context";
|
||||
import type { ModuleEvalOptions, QuickJSWASMModule } from "./module";
|
||||
import type { QuickJSRuntime } from "./runtime";
|
||||
import type { ContextOptions, RuntimeOptions } from "./types";
|
||||
/**
|
||||
* A test wrapper of [[QuickJSWASMModule]] that keeps a reference to each
|
||||
* context or runtime created.
|
||||
*
|
||||
* Call [[disposeAll]] to reset these sets and calls `dispose` on any left alive
|
||||
* (which may throw an error).
|
||||
*
|
||||
* Call [[assertNoMemoryAllocated]] at the end of a test, when you expect that you've
|
||||
* freed all the memory you've ever allocated.
|
||||
*/
|
||||
export declare class TestQuickJSWASMModule implements Pick<QuickJSWASMModule, keyof QuickJSWASMModule> {
|
||||
private parent;
|
||||
contexts: Set<QuickJSContext>;
|
||||
runtimes: Set<QuickJSRuntime>;
|
||||
constructor(parent: QuickJSWASMModule);
|
||||
newRuntime(options?: RuntimeOptions): QuickJSRuntime;
|
||||
newContext(options?: ContextOptions): QuickJSContext;
|
||||
evalCode(code: string, options?: ModuleEvalOptions): unknown;
|
||||
disposeAll(): void;
|
||||
assertNoMemoryAllocated(): void;
|
||||
/** @private */
|
||||
getFFI(): any;
|
||||
}
|
||||
77
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-test.js
generated
vendored
Normal file
77
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-test.js
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TestQuickJSWASMModule = void 0;
|
||||
const errors_1 = require("./errors");
|
||||
const lifetime_1 = require("./lifetime");
|
||||
/**
|
||||
* A test wrapper of [[QuickJSWASMModule]] that keeps a reference to each
|
||||
* context or runtime created.
|
||||
*
|
||||
* Call [[disposeAll]] to reset these sets and calls `dispose` on any left alive
|
||||
* (which may throw an error).
|
||||
*
|
||||
* Call [[assertNoMemoryAllocated]] at the end of a test, when you expect that you've
|
||||
* freed all the memory you've ever allocated.
|
||||
*/
|
||||
class TestQuickJSWASMModule {
|
||||
constructor(parent) {
|
||||
this.parent = parent;
|
||||
this.contexts = new Set();
|
||||
this.runtimes = new Set();
|
||||
}
|
||||
newRuntime(options) {
|
||||
const runtime = this.parent.newRuntime({
|
||||
...options,
|
||||
ownedLifetimes: [
|
||||
new lifetime_1.Lifetime(undefined, undefined, () => this.runtimes.delete(runtime)),
|
||||
...(options?.ownedLifetimes ?? []),
|
||||
],
|
||||
});
|
||||
this.runtimes.add(runtime);
|
||||
return runtime;
|
||||
}
|
||||
newContext(options) {
|
||||
const context = this.parent.newContext({
|
||||
...options,
|
||||
ownedLifetimes: [
|
||||
new lifetime_1.Lifetime(undefined, undefined, () => this.contexts.delete(context)),
|
||||
...(options?.ownedLifetimes ?? []),
|
||||
],
|
||||
});
|
||||
this.contexts.add(context);
|
||||
return context;
|
||||
}
|
||||
evalCode(code, options) {
|
||||
return this.parent.evalCode(code, options);
|
||||
}
|
||||
disposeAll() {
|
||||
const allDisposables = [...this.contexts, ...this.runtimes];
|
||||
this.runtimes.clear();
|
||||
this.contexts.clear();
|
||||
allDisposables.forEach((d) => {
|
||||
if (d.alive) {
|
||||
d.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
assertNoMemoryAllocated() {
|
||||
const leaksDetected = this.getFFI().QTS_RecoverableLeakCheck();
|
||||
if (leaksDetected) {
|
||||
// Note: this is currently only available when building from source
|
||||
// with debug builds.
|
||||
throw new errors_1.QuickJSMemoryLeakDetected("Leak sanitizer detected un-freed memory");
|
||||
}
|
||||
if (this.contexts.size > 0) {
|
||||
throw new errors_1.QuickJSMemoryLeakDetected(`${this.contexts.size} contexts leaked`);
|
||||
}
|
||||
if (this.runtimes.size > 0) {
|
||||
throw new errors_1.QuickJSMemoryLeakDetected(`${this.runtimes.size} runtimes leaked`);
|
||||
}
|
||||
}
|
||||
/** @private */
|
||||
getFFI() {
|
||||
return this.parent.getFFI();
|
||||
}
|
||||
}
|
||||
exports.TestQuickJSWASMModule = TestQuickJSWASMModule;
|
||||
//# sourceMappingURL=module-test.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-test.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module-test.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"module-test.js","sourceRoot":"","sources":["../ts/module-test.ts"],"names":[],"mappings":";;;AAIA,qCAAoD;AACpD,yCAAqC;AAErC;;;;;;;;;GASG;AACH,MAAa,qBAAqB;IAGhC,YAAoB,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;QAF7C,aAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;QACpC,aAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;IACY,CAAC;IAEjD,UAAU,CAAC,OAAwB;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YACrC,GAAG,OAAO;YACV,cAAc,EAAE;gBACd,IAAI,mBAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACvE,GAAG,CAAC,OAAO,EAAE,cAAc,IAAI,EAAE,CAAC;aACnC;SACF,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC1B,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,UAAU,CAAC,OAAwB;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YACrC,GAAG,OAAO;YACV,cAAc,EAAE;gBACd,IAAI,mBAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACvE,GAAG,CAAC,OAAO,EAAE,cAAc,IAAI,EAAE,CAAC;aACnC;SACF,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC1B,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,QAAQ,CAAC,IAAY,EAAE,OAA2B;QAChD,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IAED,UAAU;QACR,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC3D,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;QACrB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;QACrB,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YAC3B,IAAI,CAAC,CAAC,KAAK,EAAE;gBACX,CAAC,CAAC,OAAO,EAAE,CAAA;aACZ;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,uBAAuB;QACrB,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,wBAAwB,EAAE,CAAA;QAC9D,IAAI,aAAa,EAAE;YACjB,mEAAmE;YACnE,qBAAqB;YACrB,MAAM,IAAI,kCAAyB,CAAC,yCAAyC,CAAC,CAAA;SAC/E;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE;YAC1B,MAAM,IAAI,kCAAyB,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,CAAA;SAC7E;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE;YAC1B,MAAM,IAAI,kCAAyB,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,CAAA;SAC7E;IACH,CAAC;IAED,eAAe;IACf,MAAM;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAA;IAC7B,CAAC;CACF;AAjED,sDAiEC","sourcesContent":["import type { QuickJSContext } from \"./context\"\nimport type { ModuleEvalOptions, QuickJSWASMModule } from \"./module\"\nimport type { QuickJSRuntime } from \"./runtime\"\nimport type { ContextOptions, RuntimeOptions } from \"./types\"\nimport { QuickJSMemoryLeakDetected } from \"./errors\"\nimport { Lifetime } from \"./lifetime\"\n\n/**\n * A test wrapper of [[QuickJSWASMModule]] that keeps a reference to each\n * context or runtime created.\n *\n * Call [[disposeAll]] to reset these sets and calls `dispose` on any left alive\n * (which may throw an error).\n *\n * Call [[assertNoMemoryAllocated]] at the end of a test, when you expect that you've\n * freed all the memory you've ever allocated.\n */\nexport class TestQuickJSWASMModule implements Pick<QuickJSWASMModule, keyof QuickJSWASMModule> {\n contexts = new Set<QuickJSContext>()\n runtimes = new Set<QuickJSRuntime>()\n constructor(private parent: QuickJSWASMModule) {}\n\n newRuntime(options?: RuntimeOptions): QuickJSRuntime {\n const runtime = this.parent.newRuntime({\n ...options,\n ownedLifetimes: [\n new Lifetime(undefined, undefined, () => this.runtimes.delete(runtime)),\n ...(options?.ownedLifetimes ?? []),\n ],\n })\n this.runtimes.add(runtime)\n return runtime\n }\n\n newContext(options?: ContextOptions): QuickJSContext {\n const context = this.parent.newContext({\n ...options,\n ownedLifetimes: [\n new Lifetime(undefined, undefined, () => this.contexts.delete(context)),\n ...(options?.ownedLifetimes ?? []),\n ],\n })\n this.contexts.add(context)\n return context\n }\n\n evalCode(code: string, options?: ModuleEvalOptions): unknown {\n return this.parent.evalCode(code, options)\n }\n\n disposeAll() {\n const allDisposables = [...this.contexts, ...this.runtimes]\n this.runtimes.clear()\n this.contexts.clear()\n allDisposables.forEach((d) => {\n if (d.alive) {\n d.dispose()\n }\n })\n }\n\n assertNoMemoryAllocated() {\n const leaksDetected = this.getFFI().QTS_RecoverableLeakCheck()\n if (leaksDetected) {\n // Note: this is currently only available when building from source\n // with debug builds.\n throw new QuickJSMemoryLeakDetected(\"Leak sanitizer detected un-freed memory\")\n }\n\n if (this.contexts.size > 0) {\n throw new QuickJSMemoryLeakDetected(`${this.contexts.size} contexts leaked`)\n }\n\n if (this.runtimes.size > 0) {\n throw new QuickJSMemoryLeakDetected(`${this.runtimes.size} runtimes leaked`)\n }\n }\n\n /** @private */\n getFFI() {\n return this.parent.getFFI()\n }\n}\n"]}
|
||||
152
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module.d.ts
generated
vendored
Normal file
152
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module.d.ts
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
import { QuickJSContext } from "./context";
|
||||
import { Asyncify, AsyncifySleepResult, EitherModule, EmscriptenModuleCallbacks } from "./emscripten-types";
|
||||
import { JSContextPointer, JSRuntimePointer } from "./types-ffi";
|
||||
import { InterruptHandler, QuickJSRuntime } from "./runtime";
|
||||
import { ContextOptions, EitherFFI, JSModuleLoader, RuntimeOptions, RuntimeOptionsBase } from "./types";
|
||||
type EmscriptenCallback<BaseArgs extends any[], Result> = (...args: [Asyncify | undefined, ...BaseArgs]) => Result | AsyncifySleepResult<Result>;
|
||||
type MaybeAsyncEmscriptenCallback<T extends EmscriptenCallback<any, any>> = T extends EmscriptenCallback<infer Args, infer Result> ? (...args: Args) => Result | Promise<Result> : never;
|
||||
type MaybeAsyncEmscriptenCallbacks = {
|
||||
[K in keyof EmscriptenModuleCallbacks]: MaybeAsyncEmscriptenCallback<EmscriptenModuleCallbacks[K]>;
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export interface ContextCallbacks {
|
||||
callFunction: MaybeAsyncEmscriptenCallbacks["callFunction"];
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export interface RuntimeCallbacks {
|
||||
shouldInterrupt: MaybeAsyncEmscriptenCallbacks["shouldInterrupt"];
|
||||
loadModuleSource: MaybeAsyncEmscriptenCallbacks["loadModuleSource"];
|
||||
normalizeModule: MaybeAsyncEmscriptenCallbacks["normalizeModule"];
|
||||
}
|
||||
/**
|
||||
* Options for [[QuickJSWASMModule.evalCode]].
|
||||
*/
|
||||
export interface ModuleEvalOptions {
|
||||
/**
|
||||
* Interrupt evaluation if `shouldInterrupt` returns `true`.
|
||||
* See [[shouldInterruptAfterDeadline]].
|
||||
*/
|
||||
shouldInterrupt?: InterruptHandler;
|
||||
/**
|
||||
* Memory limit, in bytes, of WebAssembly heap memory used by the QuickJS VM.
|
||||
*/
|
||||
memoryLimitBytes?: number;
|
||||
/**
|
||||
* Stack size limit for this vm, in bytes
|
||||
* To remove the limit, set to `0`.
|
||||
*/
|
||||
maxStackSizeBytes?: number;
|
||||
/**
|
||||
* Module loader for any `import` statements or expressions.
|
||||
*/
|
||||
moduleLoader?: JSModuleLoader;
|
||||
}
|
||||
/**
|
||||
* We use static functions per module to dispatch runtime or context calls from
|
||||
* C to the host. This class manages the indirection from a specific runtime or
|
||||
* context pointer to the appropriate callback handler.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
export declare class QuickJSModuleCallbacks {
|
||||
private module;
|
||||
private contextCallbacks;
|
||||
private runtimeCallbacks;
|
||||
constructor(module: EitherModule);
|
||||
setRuntimeCallbacks(rt: JSRuntimePointer, callbacks: RuntimeCallbacks): void;
|
||||
deleteRuntime(rt: JSRuntimePointer): void;
|
||||
setContextCallbacks(ctx: JSContextPointer, callbacks: ContextCallbacks): void;
|
||||
deleteContext(ctx: JSContextPointer): void;
|
||||
private suspendedCount;
|
||||
private suspended;
|
||||
private handleAsyncify;
|
||||
private cToHostCallbacks;
|
||||
}
|
||||
/**
|
||||
* Process RuntimeOptions and apply them to a QuickJSRuntime.
|
||||
* @private
|
||||
*/
|
||||
export declare function applyBaseRuntimeOptions(runtime: QuickJSRuntime, options: RuntimeOptionsBase): void;
|
||||
/**
|
||||
* Process ModuleEvalOptions and apply them to a QuickJSRuntime.
|
||||
* @private
|
||||
*/
|
||||
export declare function applyModuleEvalRuntimeOptions<T extends QuickJSRuntime>(runtime: T, options: ModuleEvalOptions): void;
|
||||
/**
|
||||
* This class presents a Javascript interface to QuickJS, a Javascript interpreter
|
||||
* that supports EcmaScript 2020 (ES2020).
|
||||
*
|
||||
* It wraps a single WebAssembly module containing the QuickJS library and
|
||||
* associated helper C code. WebAssembly modules are completely isolated from
|
||||
* each other by the host's WebAssembly runtime. Separate WebAssembly modules
|
||||
* have the most isolation guarantees possible with this library.
|
||||
*
|
||||
* The simplest way to start running code is {@link evalCode}. This shortcut
|
||||
* method will evaluate Javascript safely and return the result as a native
|
||||
* Javascript value.
|
||||
*
|
||||
* For more control over the execution environment, or to interact with values
|
||||
* inside QuickJS, create a context with {@link newContext} or a runtime with
|
||||
* {@link newRuntime}.
|
||||
*/
|
||||
export declare class QuickJSWASMModule {
|
||||
/** @private */
|
||||
protected ffi: EitherFFI;
|
||||
/** @private */
|
||||
protected callbacks: QuickJSModuleCallbacks;
|
||||
/** @private */
|
||||
protected module: EitherModule;
|
||||
/** @private */
|
||||
constructor(module: EitherModule, ffi: EitherFFI);
|
||||
/**
|
||||
* Create a runtime.
|
||||
* Use the runtime to set limits on CPU and memory usage and configure module
|
||||
* loading for one or more [[QuickJSContext]]s inside the runtime.
|
||||
*/
|
||||
newRuntime(options?: RuntimeOptions): QuickJSRuntime;
|
||||
/**
|
||||
* A simplified API to create a new [[QuickJSRuntime]] and a
|
||||
* [[QuickJSContext]] inside that runtime at the same time. The runtime will
|
||||
* be disposed when the context is disposed.
|
||||
*/
|
||||
newContext(options?: ContextOptions): QuickJSContext;
|
||||
/**
|
||||
* One-off evaluate code without needing to create a [[QuickJSRuntime]] or
|
||||
* [[QuickJSContext]] explicitly.
|
||||
*
|
||||
* To protect against infinite loops, use the `shouldInterrupt` option. The
|
||||
* [[shouldInterruptAfterDeadline]] function will create a time-based deadline.
|
||||
*
|
||||
* If you need more control over how the code executes, create a
|
||||
* [[QuickJSRuntime]] (with [[newRuntime]]) or a [[QuickJSContext]] (with
|
||||
* [[newContext]] or [[QuickJSRuntime.newContext]]), and use its
|
||||
* [[QuickJSContext.evalCode]] method.
|
||||
*
|
||||
* Asynchronous callbacks may not run during the first call to `evalCode`. If
|
||||
* you need to work with async code inside QuickJS, create a runtime and use
|
||||
* [[QuickJSRuntime.executePendingJobs]].
|
||||
*
|
||||
* @returns The result is coerced to a native Javascript value using JSON
|
||||
* serialization, so properties and values unsupported by JSON will be dropped.
|
||||
*
|
||||
* @throws If `code` throws during evaluation, the exception will be
|
||||
* converted into a native Javascript value and thrown.
|
||||
*
|
||||
* @throws if `options.shouldInterrupt` interrupted execution, will throw a Error
|
||||
* with name `"InternalError"` and message `"interrupted"`.
|
||||
*/
|
||||
evalCode(code: string, options?: ModuleEvalOptions): unknown;
|
||||
/**
|
||||
* Get a low-level interface to the QuickJS functions in this WebAssembly
|
||||
* module.
|
||||
* @experimental
|
||||
* @unstable No warranty is provided with this API. It could change at any time.
|
||||
* @private
|
||||
*/
|
||||
getFFI(): EitherFFI;
|
||||
}
|
||||
export {};
|
||||
302
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module.js
generated
vendored
Normal file
302
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module.js
generated
vendored
Normal file
@ -0,0 +1,302 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSWASMModule = exports.applyModuleEvalRuntimeOptions = exports.applyBaseRuntimeOptions = exports.QuickJSModuleCallbacks = void 0;
|
||||
const debug_1 = require("./debug");
|
||||
const errors_1 = require("./errors");
|
||||
const lifetime_1 = require("./lifetime");
|
||||
const runtime_1 = require("./runtime");
|
||||
const types_1 = require("./types");
|
||||
class QuickJSEmscriptenModuleCallbacks {
|
||||
constructor(args) {
|
||||
this.callFunction = args.callFunction;
|
||||
this.shouldInterrupt = args.shouldInterrupt;
|
||||
this.loadModuleSource = args.loadModuleSource;
|
||||
this.normalizeModule = args.normalizeModule;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* We use static functions per module to dispatch runtime or context calls from
|
||||
* C to the host. This class manages the indirection from a specific runtime or
|
||||
* context pointer to the appropriate callback handler.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
class QuickJSModuleCallbacks {
|
||||
constructor(module) {
|
||||
this.contextCallbacks = new Map();
|
||||
this.runtimeCallbacks = new Map();
|
||||
this.suspendedCount = 0;
|
||||
this.cToHostCallbacks = new QuickJSEmscriptenModuleCallbacks({
|
||||
callFunction: (asyncify, ctx, this_ptr, argc, argv, fn_id) => this.handleAsyncify(asyncify, () => {
|
||||
try {
|
||||
const vm = this.contextCallbacks.get(ctx);
|
||||
if (!vm) {
|
||||
throw new Error(`QuickJSContext(ctx = ${ctx}) not found for C function call "${fn_id}"`);
|
||||
}
|
||||
return vm.callFunction(ctx, this_ptr, argc, argv, fn_id);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("[C to host error: returning null]", error);
|
||||
return 0;
|
||||
}
|
||||
}),
|
||||
shouldInterrupt: (asyncify, rt) => this.handleAsyncify(asyncify, () => {
|
||||
try {
|
||||
const vm = this.runtimeCallbacks.get(rt);
|
||||
if (!vm) {
|
||||
throw new Error(`QuickJSRuntime(rt = ${rt}) not found for C interrupt`);
|
||||
}
|
||||
return vm.shouldInterrupt(rt);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("[C to host interrupt: returning error]", error);
|
||||
return 1;
|
||||
}
|
||||
}),
|
||||
loadModuleSource: (asyncify, rt, ctx, moduleName) => this.handleAsyncify(asyncify, () => {
|
||||
try {
|
||||
const runtimeCallbacks = this.runtimeCallbacks.get(rt);
|
||||
if (!runtimeCallbacks) {
|
||||
throw new Error(`QuickJSRuntime(rt = ${rt}) not found for C module loader`);
|
||||
}
|
||||
const loadModule = runtimeCallbacks.loadModuleSource;
|
||||
if (!loadModule) {
|
||||
throw new Error(`QuickJSRuntime(rt = ${rt}) does not support module loading`);
|
||||
}
|
||||
return loadModule(rt, ctx, moduleName);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("[C to host module loader error: returning null]", error);
|
||||
return 0;
|
||||
}
|
||||
}),
|
||||
normalizeModule: (asyncify, rt, ctx, moduleBaseName, moduleName) => this.handleAsyncify(asyncify, () => {
|
||||
try {
|
||||
const runtimeCallbacks = this.runtimeCallbacks.get(rt);
|
||||
if (!runtimeCallbacks) {
|
||||
throw new Error(`QuickJSRuntime(rt = ${rt}) not found for C module loader`);
|
||||
}
|
||||
const normalizeModule = runtimeCallbacks.normalizeModule;
|
||||
if (!normalizeModule) {
|
||||
throw new Error(`QuickJSRuntime(rt = ${rt}) does not support module loading`);
|
||||
}
|
||||
return normalizeModule(rt, ctx, moduleBaseName, moduleName);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("[C to host module loader error: returning null]", error);
|
||||
return 0;
|
||||
}
|
||||
}),
|
||||
});
|
||||
this.module = module;
|
||||
this.module.callbacks = this.cToHostCallbacks;
|
||||
}
|
||||
setRuntimeCallbacks(rt, callbacks) {
|
||||
this.runtimeCallbacks.set(rt, callbacks);
|
||||
}
|
||||
deleteRuntime(rt) {
|
||||
this.runtimeCallbacks.delete(rt);
|
||||
}
|
||||
setContextCallbacks(ctx, callbacks) {
|
||||
this.contextCallbacks.set(ctx, callbacks);
|
||||
}
|
||||
deleteContext(ctx) {
|
||||
this.contextCallbacks.delete(ctx);
|
||||
}
|
||||
handleAsyncify(asyncify, fn) {
|
||||
if (asyncify) {
|
||||
// We must always call asyncify.handleSync around our function.
|
||||
// This allows asyncify to resume suspended execution on the second call.
|
||||
// Asyncify internally can detect sync behavior, and avoid suspending.
|
||||
return asyncify.handleSleep((done) => {
|
||||
try {
|
||||
const result = fn();
|
||||
if (!(result instanceof Promise)) {
|
||||
(0, debug_1.debugLog)("asyncify.handleSleep: not suspending:", result);
|
||||
done(result);
|
||||
return;
|
||||
}
|
||||
// Is promise, we intend to suspend.
|
||||
if (this.suspended) {
|
||||
throw new errors_1.QuickJSAsyncifyError(`Already suspended at: ${this.suspended.stack}\nAttempted to suspend at:`);
|
||||
}
|
||||
else {
|
||||
this.suspended = new errors_1.QuickJSAsyncifySuspended(`(${this.suspendedCount++})`);
|
||||
(0, debug_1.debugLog)("asyncify.handleSleep: suspending:", this.suspended);
|
||||
}
|
||||
result.then((resolvedResult) => {
|
||||
this.suspended = undefined;
|
||||
(0, debug_1.debugLog)("asyncify.handleSleep: resolved:", resolvedResult);
|
||||
done(resolvedResult);
|
||||
}, (error) => {
|
||||
(0, debug_1.debugLog)("asyncify.handleSleep: rejected:", error);
|
||||
console.error("QuickJS: cannot handle error in suspended function", error);
|
||||
this.suspended = undefined;
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
(0, debug_1.debugLog)("asyncify.handleSleep: error:", error);
|
||||
this.suspended = undefined;
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
// No asyncify - we should never return a promise.
|
||||
const value = fn();
|
||||
if (value instanceof Promise) {
|
||||
throw new Error("Promise return value not supported in non-asyncify context.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
exports.QuickJSModuleCallbacks = QuickJSModuleCallbacks;
|
||||
/**
|
||||
* Process RuntimeOptions and apply them to a QuickJSRuntime.
|
||||
* @private
|
||||
*/
|
||||
function applyBaseRuntimeOptions(runtime, options) {
|
||||
if (options.interruptHandler) {
|
||||
runtime.setInterruptHandler(options.interruptHandler);
|
||||
}
|
||||
if (options.maxStackSizeBytes !== undefined) {
|
||||
runtime.setMaxStackSize(options.maxStackSizeBytes);
|
||||
}
|
||||
if (options.memoryLimitBytes !== undefined) {
|
||||
runtime.setMemoryLimit(options.memoryLimitBytes);
|
||||
}
|
||||
}
|
||||
exports.applyBaseRuntimeOptions = applyBaseRuntimeOptions;
|
||||
/**
|
||||
* Process ModuleEvalOptions and apply them to a QuickJSRuntime.
|
||||
* @private
|
||||
*/
|
||||
function applyModuleEvalRuntimeOptions(runtime, options) {
|
||||
if (options.moduleLoader) {
|
||||
runtime.setModuleLoader(options.moduleLoader);
|
||||
}
|
||||
if (options.shouldInterrupt) {
|
||||
runtime.setInterruptHandler(options.shouldInterrupt);
|
||||
}
|
||||
if (options.memoryLimitBytes !== undefined) {
|
||||
runtime.setMemoryLimit(options.memoryLimitBytes);
|
||||
}
|
||||
if (options.maxStackSizeBytes !== undefined) {
|
||||
runtime.setMaxStackSize(options.maxStackSizeBytes);
|
||||
}
|
||||
}
|
||||
exports.applyModuleEvalRuntimeOptions = applyModuleEvalRuntimeOptions;
|
||||
/**
|
||||
* This class presents a Javascript interface to QuickJS, a Javascript interpreter
|
||||
* that supports EcmaScript 2020 (ES2020).
|
||||
*
|
||||
* It wraps a single WebAssembly module containing the QuickJS library and
|
||||
* associated helper C code. WebAssembly modules are completely isolated from
|
||||
* each other by the host's WebAssembly runtime. Separate WebAssembly modules
|
||||
* have the most isolation guarantees possible with this library.
|
||||
*
|
||||
* The simplest way to start running code is {@link evalCode}. This shortcut
|
||||
* method will evaluate Javascript safely and return the result as a native
|
||||
* Javascript value.
|
||||
*
|
||||
* For more control over the execution environment, or to interact with values
|
||||
* inside QuickJS, create a context with {@link newContext} or a runtime with
|
||||
* {@link newRuntime}.
|
||||
*/
|
||||
class QuickJSWASMModule {
|
||||
/** @private */
|
||||
constructor(module, ffi) {
|
||||
this.module = module;
|
||||
this.ffi = ffi;
|
||||
this.callbacks = new QuickJSModuleCallbacks(module);
|
||||
}
|
||||
/**
|
||||
* Create a runtime.
|
||||
* Use the runtime to set limits on CPU and memory usage and configure module
|
||||
* loading for one or more [[QuickJSContext]]s inside the runtime.
|
||||
*/
|
||||
newRuntime(options = {}) {
|
||||
const rt = new lifetime_1.Lifetime(this.ffi.QTS_NewRuntime(), undefined, (rt_ptr) => {
|
||||
this.callbacks.deleteRuntime(rt_ptr);
|
||||
this.ffi.QTS_FreeRuntime(rt_ptr);
|
||||
});
|
||||
const runtime = new runtime_1.QuickJSRuntime({
|
||||
module: this.module,
|
||||
callbacks: this.callbacks,
|
||||
ffi: this.ffi,
|
||||
rt,
|
||||
});
|
||||
applyBaseRuntimeOptions(runtime, options);
|
||||
if (options.moduleLoader) {
|
||||
runtime.setModuleLoader(options.moduleLoader);
|
||||
}
|
||||
return runtime;
|
||||
}
|
||||
/**
|
||||
* A simplified API to create a new [[QuickJSRuntime]] and a
|
||||
* [[QuickJSContext]] inside that runtime at the same time. The runtime will
|
||||
* be disposed when the context is disposed.
|
||||
*/
|
||||
newContext(options = {}) {
|
||||
const runtime = this.newRuntime();
|
||||
const context = runtime.newContext({
|
||||
...options,
|
||||
ownedLifetimes: (0, types_1.concat)(runtime, options.ownedLifetimes),
|
||||
});
|
||||
runtime.context = context;
|
||||
return context;
|
||||
}
|
||||
/**
|
||||
* One-off evaluate code without needing to create a [[QuickJSRuntime]] or
|
||||
* [[QuickJSContext]] explicitly.
|
||||
*
|
||||
* To protect against infinite loops, use the `shouldInterrupt` option. The
|
||||
* [[shouldInterruptAfterDeadline]] function will create a time-based deadline.
|
||||
*
|
||||
* If you need more control over how the code executes, create a
|
||||
* [[QuickJSRuntime]] (with [[newRuntime]]) or a [[QuickJSContext]] (with
|
||||
* [[newContext]] or [[QuickJSRuntime.newContext]]), and use its
|
||||
* [[QuickJSContext.evalCode]] method.
|
||||
*
|
||||
* Asynchronous callbacks may not run during the first call to `evalCode`. If
|
||||
* you need to work with async code inside QuickJS, create a runtime and use
|
||||
* [[QuickJSRuntime.executePendingJobs]].
|
||||
*
|
||||
* @returns The result is coerced to a native Javascript value using JSON
|
||||
* serialization, so properties and values unsupported by JSON will be dropped.
|
||||
*
|
||||
* @throws If `code` throws during evaluation, the exception will be
|
||||
* converted into a native Javascript value and thrown.
|
||||
*
|
||||
* @throws if `options.shouldInterrupt` interrupted execution, will throw a Error
|
||||
* with name `"InternalError"` and message `"interrupted"`.
|
||||
*/
|
||||
evalCode(code, options = {}) {
|
||||
return lifetime_1.Scope.withScope((scope) => {
|
||||
const vm = scope.manage(this.newContext());
|
||||
applyModuleEvalRuntimeOptions(vm.runtime, options);
|
||||
const result = vm.evalCode(code, "eval.js");
|
||||
if (options.memoryLimitBytes !== undefined) {
|
||||
// Remove memory limit so we can dump the result without exceeding it.
|
||||
vm.runtime.setMemoryLimit(-1);
|
||||
}
|
||||
if (result.error) {
|
||||
const error = vm.dump(scope.manage(result.error));
|
||||
throw error;
|
||||
}
|
||||
const value = vm.dump(scope.manage(result.value));
|
||||
return value;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get a low-level interface to the QuickJS functions in this WebAssembly
|
||||
* module.
|
||||
* @experimental
|
||||
* @unstable No warranty is provided with this API. It could change at any time.
|
||||
* @private
|
||||
*/
|
||||
getFFI() {
|
||||
return this.ffi;
|
||||
}
|
||||
}
|
||||
exports.QuickJSWASMModule = QuickJSWASMModule;
|
||||
//# sourceMappingURL=module.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/module.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
38
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime-asyncify.d.ts
generated
vendored
Normal file
38
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime-asyncify.d.ts
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
import { Lifetime } from ".";
|
||||
import { QuickJSAsyncContext } from "./context-asyncify";
|
||||
import { QuickJSAsyncEmscriptenModule } from "./emscripten-types";
|
||||
import { QuickJSAsyncFFI } from "./variants";
|
||||
import { JSContextPointer, JSRuntimePointer } from "./types-ffi";
|
||||
import { QuickJSModuleCallbacks } from "./module";
|
||||
import { QuickJSRuntime } from "./runtime";
|
||||
import { ContextOptions, JSModuleLoaderAsync, JSModuleNormalizerAsync } from "./types";
|
||||
export declare class QuickJSAsyncRuntime extends QuickJSRuntime {
|
||||
context: QuickJSAsyncContext | undefined;
|
||||
/** @private */
|
||||
protected module: QuickJSAsyncEmscriptenModule;
|
||||
/** @private */
|
||||
protected ffi: QuickJSAsyncFFI;
|
||||
/** @private */
|
||||
protected rt: Lifetime<JSRuntimePointer>;
|
||||
/** @private */
|
||||
protected callbacks: QuickJSModuleCallbacks;
|
||||
/** @private */
|
||||
protected contextMap: Map<JSContextPointer, QuickJSAsyncContext>;
|
||||
/** @private */
|
||||
constructor(args: {
|
||||
module: QuickJSAsyncEmscriptenModule;
|
||||
ffi: QuickJSAsyncFFI;
|
||||
rt: Lifetime<JSRuntimePointer>;
|
||||
callbacks: QuickJSModuleCallbacks;
|
||||
});
|
||||
newContext(options?: ContextOptions): QuickJSAsyncContext;
|
||||
setModuleLoader(moduleLoader: JSModuleLoaderAsync, moduleNormalizer?: JSModuleNormalizerAsync): void;
|
||||
/**
|
||||
* Set the max stack size for this runtime in bytes.
|
||||
* To remove the limit, set to `0`.
|
||||
*
|
||||
* Setting this limit also adjusts the global `ASYNCIFY_STACK_SIZE` for the entire {@link QuickJSAsyncWASMModule}.
|
||||
* See the [pull request](https://github.com/justjake/quickjs-emscripten/pull/114) for more details.
|
||||
*/
|
||||
setMaxStackSize(stackSize: number): void;
|
||||
}
|
||||
49
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime-asyncify.js
generated
vendored
Normal file
49
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime-asyncify.js
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSAsyncRuntime = void 0;
|
||||
const _1 = require(".");
|
||||
const context_asyncify_1 = require("./context-asyncify");
|
||||
const runtime_1 = require("./runtime");
|
||||
const types_1 = require("./types");
|
||||
class QuickJSAsyncRuntime extends runtime_1.QuickJSRuntime {
|
||||
/** @private */
|
||||
constructor(args) {
|
||||
super(args);
|
||||
}
|
||||
newContext(options = {}) {
|
||||
if (options.intrinsics && options.intrinsics !== types_1.DefaultIntrinsics) {
|
||||
throw new Error("TODO: Custom intrinsics are not supported yet");
|
||||
}
|
||||
const ctx = new _1.Lifetime(this.ffi.QTS_NewContext(this.rt.value), undefined, (ctx_ptr) => {
|
||||
this.contextMap.delete(ctx_ptr);
|
||||
this.callbacks.deleteContext(ctx_ptr);
|
||||
this.ffi.QTS_FreeContext(ctx_ptr);
|
||||
});
|
||||
const context = new context_asyncify_1.QuickJSAsyncContext({
|
||||
module: this.module,
|
||||
ctx,
|
||||
ffi: this.ffi,
|
||||
rt: this.rt,
|
||||
ownedLifetimes: [],
|
||||
runtime: this,
|
||||
callbacks: this.callbacks,
|
||||
});
|
||||
this.contextMap.set(ctx.value, context);
|
||||
return context;
|
||||
}
|
||||
setModuleLoader(moduleLoader, moduleNormalizer) {
|
||||
super.setModuleLoader(moduleLoader, moduleNormalizer);
|
||||
}
|
||||
/**
|
||||
* Set the max stack size for this runtime in bytes.
|
||||
* To remove the limit, set to `0`.
|
||||
*
|
||||
* Setting this limit also adjusts the global `ASYNCIFY_STACK_SIZE` for the entire {@link QuickJSAsyncWASMModule}.
|
||||
* See the [pull request](https://github.com/justjake/quickjs-emscripten/pull/114) for more details.
|
||||
*/
|
||||
setMaxStackSize(stackSize) {
|
||||
return super.setMaxStackSize(stackSize);
|
||||
}
|
||||
}
|
||||
exports.QuickJSAsyncRuntime = QuickJSAsyncRuntime;
|
||||
//# sourceMappingURL=runtime-asyncify.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime-asyncify.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime-asyncify.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"runtime-asyncify.js","sourceRoot":"","sources":["../ts/runtime-asyncify.ts"],"names":[],"mappings":";;;AACA,wBAA4B;AAC5B,yDAAwD;AAKxD,uCAA0C;AAC1C,mCAOgB;AAEhB,MAAa,mBAAoB,SAAQ,wBAAc;IAcrD,eAAe;IACf,YAAY,IAKX;QACC,KAAK,CAAC,IAAI,CAAC,CAAA;IACb,CAAC;IAEQ,UAAU,CAAC,UAA0B,EAAE;QAC9C,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,KAAK,yBAAiB,EAAE;YAClE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;SACjE;QAED,MAAM,GAAG,GAAG,IAAI,WAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;YACtF,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAC/B,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;YACrC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;QACnC,CAAC,CAAC,CAAA;QAEF,MAAM,OAAO,GAAG,IAAI,sCAAmB,CAAC;YACtC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG;YACH,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,cAAc,EAAE,EAAE;YAClB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAA;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAEvC,OAAO,OAAO,CAAA;IAChB,CAAC;IAEe,eAAe,CAC7B,YAAiC,EACjC,gBAA0C;QAE1C,KAAK,CAAC,eAAe,CACnB,YAA8B,EAC9B,gBAAkD,CACnD,CAAA;IACH,CAAC;IAED;;;;;;OAMG;IACa,eAAe,CAAC,SAAiB;QAC/C,OAAO,KAAK,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;IACzC,CAAC;CACF;AArED,kDAqEC","sourcesContent":["import type { QuickJSAsyncWASMModule } from \"./module-asyncify\"\nimport { Lifetime } from \".\"\nimport { QuickJSAsyncContext } from \"./context-asyncify\"\nimport { QuickJSAsyncEmscriptenModule } from \"./emscripten-types\"\nimport { QuickJSAsyncFFI } from \"./variants\"\nimport { JSContextPointer, JSRuntimePointer } from \"./types-ffi\"\nimport { QuickJSModuleCallbacks } from \"./module\"\nimport { QuickJSRuntime } from \"./runtime\"\nimport {\n ContextOptions,\n DefaultIntrinsics,\n JSModuleLoader,\n JSModuleLoaderAsync,\n JSModuleNormalizer,\n JSModuleNormalizerAsync,\n} from \"./types\"\n\nexport class QuickJSAsyncRuntime extends QuickJSRuntime {\n public context: QuickJSAsyncContext | undefined\n\n /** @private */\n protected declare module: QuickJSAsyncEmscriptenModule\n /** @private */\n protected declare ffi: QuickJSAsyncFFI\n /** @private */\n protected declare rt: Lifetime<JSRuntimePointer>\n /** @private */\n protected declare callbacks: QuickJSModuleCallbacks\n /** @private */\n protected declare contextMap: Map<JSContextPointer, QuickJSAsyncContext>\n\n /** @private */\n constructor(args: {\n module: QuickJSAsyncEmscriptenModule\n ffi: QuickJSAsyncFFI\n rt: Lifetime<JSRuntimePointer>\n callbacks: QuickJSModuleCallbacks\n }) {\n super(args)\n }\n\n override newContext(options: ContextOptions = {}): QuickJSAsyncContext {\n if (options.intrinsics && options.intrinsics !== DefaultIntrinsics) {\n throw new Error(\"TODO: Custom intrinsics are not supported yet\")\n }\n\n const ctx = new Lifetime(this.ffi.QTS_NewContext(this.rt.value), undefined, (ctx_ptr) => {\n this.contextMap.delete(ctx_ptr)\n this.callbacks.deleteContext(ctx_ptr)\n this.ffi.QTS_FreeContext(ctx_ptr)\n })\n\n const context = new QuickJSAsyncContext({\n module: this.module,\n ctx,\n ffi: this.ffi,\n rt: this.rt,\n ownedLifetimes: [],\n runtime: this,\n callbacks: this.callbacks,\n })\n this.contextMap.set(ctx.value, context)\n\n return context\n }\n\n public override setModuleLoader(\n moduleLoader: JSModuleLoaderAsync,\n moduleNormalizer?: JSModuleNormalizerAsync\n ): void {\n super.setModuleLoader(\n moduleLoader as JSModuleLoader,\n moduleNormalizer as JSModuleNormalizer | undefined\n )\n }\n\n /**\n * Set the max stack size for this runtime in bytes.\n * To remove the limit, set to `0`.\n *\n * Setting this limit also adjusts the global `ASYNCIFY_STACK_SIZE` for the entire {@link QuickJSAsyncWASMModule}.\n * See the [pull request](https://github.com/justjake/quickjs-emscripten/pull/114) for more details.\n */\n public override setMaxStackSize(stackSize: number): void {\n return super.setMaxStackSize(stackSize)\n }\n}\n"]}
|
||||
174
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime.d.ts
generated
vendored
Normal file
174
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime.d.ts
generated
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
import { QuickJSContext } from "./context";
|
||||
import { EitherModule } from "./emscripten-types";
|
||||
import { JSContextPointer, JSRuntimePointer } from "./types-ffi";
|
||||
import { Disposable, Lifetime, Scope } from "./lifetime";
|
||||
import { ModuleMemory } from "./memory";
|
||||
import { QuickJSModuleCallbacks } from "./module";
|
||||
import { ContextOptions, EitherFFI, JSModuleLoader, JSModuleNormalizer, QuickJSHandle } from "./types";
|
||||
import { SuccessOrFail } from "./vm-interface";
|
||||
/**
|
||||
* Callback called regularly while the VM executes code.
|
||||
* Determines if a VM's execution should be interrupted.
|
||||
*
|
||||
* @returns `true` to interrupt JS execution inside the VM.
|
||||
* @returns `false` or `undefined` to continue JS execution inside the VM.
|
||||
*/
|
||||
export type InterruptHandler = (runtime: QuickJSRuntime) => boolean | undefined;
|
||||
/**
|
||||
* Used as an optional for the results of executing pendingJobs.
|
||||
* On success, `value` contains the number of async jobs executed
|
||||
* by the runtime.
|
||||
* @source
|
||||
*/
|
||||
export type ExecutePendingJobsResult = SuccessOrFail<
|
||||
/** Number of jobs successfully executed. */
|
||||
number,
|
||||
/** The error that occurred. */
|
||||
QuickJSHandle & {
|
||||
/** The context where the error occurred. */
|
||||
context: QuickJSContext;
|
||||
}>;
|
||||
/**
|
||||
* A runtime represents a Javascript runtime corresponding to an object heap.
|
||||
* Several runtimes can exist at the same time but they cannot exchange objects.
|
||||
* Inside a given runtime, no multi-threading is supported.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Create a runtime via {@link QuickJSWASMModule.newRuntime}.
|
||||
*
|
||||
* You should create separate runtime instances for untrusted code from
|
||||
* different sources for isolation. However, stronger isolation is also
|
||||
* available (at the cost of memory usage), by creating separate WebAssembly
|
||||
* modules to further isolate untrusted code.
|
||||
* See {@link newQuickJSWASMModule}.
|
||||
*
|
||||
* Implement memory and CPU constraints with [[setInterruptHandler]]
|
||||
* (called regularly while the interpreter runs), [[setMemoryLimit]], and
|
||||
* [[setMaxStackSize]].
|
||||
* Use [[computeMemoryUsage]] or [[dumpMemoryUsage]] to guide memory limit
|
||||
* tuning.
|
||||
*
|
||||
* Configure ES module loading with [[setModuleLoader]].
|
||||
*/
|
||||
export declare class QuickJSRuntime implements Disposable {
|
||||
/**
|
||||
* If this runtime was created as as part of a context, points to the context
|
||||
* associated with the runtime.
|
||||
*
|
||||
* If this runtime was created stand-alone, this may or may not contain a context.
|
||||
* A context here may be allocated if one is needed by the runtime, eg for [[computeMemoryUsage]].
|
||||
*/
|
||||
context: QuickJSContext | undefined;
|
||||
/** @private */
|
||||
protected module: EitherModule;
|
||||
/** @private */
|
||||
protected memory: ModuleMemory;
|
||||
/** @private */
|
||||
protected ffi: EitherFFI;
|
||||
/** @private */
|
||||
protected rt: Lifetime<JSRuntimePointer>;
|
||||
/** @private */
|
||||
protected callbacks: QuickJSModuleCallbacks;
|
||||
/** @private */
|
||||
protected scope: Scope;
|
||||
/** @private */
|
||||
protected contextMap: Map<JSContextPointer, QuickJSContext>;
|
||||
/** @private */
|
||||
protected moduleLoader: JSModuleLoader | undefined;
|
||||
/** @private */
|
||||
protected moduleNormalizer: JSModuleNormalizer | undefined;
|
||||
/** @private */
|
||||
constructor(args: {
|
||||
module: EitherModule;
|
||||
ffi: EitherFFI;
|
||||
rt: Lifetime<JSRuntimePointer>;
|
||||
callbacks: QuickJSModuleCallbacks;
|
||||
ownedLifetimes?: Disposable[];
|
||||
});
|
||||
get alive(): boolean;
|
||||
dispose(): void;
|
||||
newContext(options?: ContextOptions): QuickJSContext;
|
||||
/**
|
||||
* Set the loader for EcmaScript modules requested by any context in this
|
||||
* runtime.
|
||||
*
|
||||
* The loader can be removed with [[removeModuleLoader]].
|
||||
*/
|
||||
setModuleLoader(moduleLoader: JSModuleLoader, moduleNormalizer?: JSModuleNormalizer): void;
|
||||
/**
|
||||
* Remove the the loader set by [[setModuleLoader]]. This disables module loading.
|
||||
*/
|
||||
removeModuleLoader(): void;
|
||||
/**
|
||||
* In QuickJS, promises and async functions create pendingJobs. These do not execute
|
||||
* immediately and need to be run by calling [[executePendingJobs]].
|
||||
*
|
||||
* @return true if there is at least one pendingJob queued up.
|
||||
*/
|
||||
hasPendingJob(): boolean;
|
||||
private interruptHandler;
|
||||
/**
|
||||
* Set a callback which is regularly called by the QuickJS engine when it is
|
||||
* executing code. This callback can be used to implement an execution
|
||||
* timeout.
|
||||
*
|
||||
* The interrupt handler can be removed with [[removeInterruptHandler]].
|
||||
*/
|
||||
setInterruptHandler(cb: InterruptHandler): void;
|
||||
/**
|
||||
* Remove the interrupt handler, if any.
|
||||
* See [[setInterruptHandler]].
|
||||
*/
|
||||
removeInterruptHandler(): void;
|
||||
/**
|
||||
* Execute pendingJobs on the runtime until `maxJobsToExecute` jobs are
|
||||
* executed (default all pendingJobs), the queue is exhausted, or the runtime
|
||||
* encounters an exception.
|
||||
*
|
||||
* In QuickJS, promises and async functions *inside the runtime* create
|
||||
* pendingJobs. These do not execute immediately and need to triggered to run.
|
||||
*
|
||||
* @param maxJobsToExecute - When negative, run all pending jobs. Otherwise execute
|
||||
* at most `maxJobsToExecute` before returning.
|
||||
*
|
||||
* @return On success, the number of executed jobs. On error, the exception
|
||||
* that stopped execution, and the context it occurred in. Note that
|
||||
* executePendingJobs will not normally return errors thrown inside async
|
||||
* functions or rejected promises. Those errors are available by calling
|
||||
* [[resolvePromise]] on the promise handle returned by the async function.
|
||||
*/
|
||||
executePendingJobs(maxJobsToExecute?: number | void): ExecutePendingJobsResult;
|
||||
/**
|
||||
* Set the max memory this runtime can allocate.
|
||||
* To remove the limit, set to `-1`.
|
||||
*/
|
||||
setMemoryLimit(limitBytes: number): void;
|
||||
/**
|
||||
* Compute memory usage for this runtime. Returns the result as a handle to a
|
||||
* JSValue object. Use [[QuickJSContext.dump]] to convert to a native object.
|
||||
* Calling this method will allocate more memory inside the runtime. The information
|
||||
* is accurate as of just before the call to `computeMemoryUsage`.
|
||||
* For a human-digestible representation, see [[dumpMemoryUsage]].
|
||||
*/
|
||||
computeMemoryUsage(): QuickJSHandle;
|
||||
/**
|
||||
* @returns a human-readable description of memory usage in this runtime.
|
||||
* For programmatic access to this information, see [[computeMemoryUsage]].
|
||||
*/
|
||||
dumpMemoryUsage(): string;
|
||||
/**
|
||||
* Set the max stack size for this runtime, in bytes.
|
||||
* To remove the limit, set to `0`.
|
||||
*/
|
||||
setMaxStackSize(stackSize: number): void;
|
||||
/**
|
||||
* Assert that `handle` is owned by this runtime.
|
||||
* @throws QuickJSWrongOwner if owned by a different runtime.
|
||||
*/
|
||||
assertOwned(handle: QuickJSHandle): void;
|
||||
private getSystemContext;
|
||||
private cToHostCallbacks;
|
||||
}
|
||||
300
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime.js
generated
vendored
Normal file
300
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime.js
generated
vendored
Normal file
@ -0,0 +1,300 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSRuntime = void 0;
|
||||
const asyncify_helpers_1 = require("./asyncify-helpers");
|
||||
const context_1 = require("./context");
|
||||
const debug_1 = require("./debug");
|
||||
const errors_1 = require("./errors");
|
||||
const lifetime_1 = require("./lifetime");
|
||||
const memory_1 = require("./memory");
|
||||
const types_1 = require("./types");
|
||||
/**
|
||||
* A runtime represents a Javascript runtime corresponding to an object heap.
|
||||
* Several runtimes can exist at the same time but they cannot exchange objects.
|
||||
* Inside a given runtime, no multi-threading is supported.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Create a runtime via {@link QuickJSWASMModule.newRuntime}.
|
||||
*
|
||||
* You should create separate runtime instances for untrusted code from
|
||||
* different sources for isolation. However, stronger isolation is also
|
||||
* available (at the cost of memory usage), by creating separate WebAssembly
|
||||
* modules to further isolate untrusted code.
|
||||
* See {@link newQuickJSWASMModule}.
|
||||
*
|
||||
* Implement memory and CPU constraints with [[setInterruptHandler]]
|
||||
* (called regularly while the interpreter runs), [[setMemoryLimit]], and
|
||||
* [[setMaxStackSize]].
|
||||
* Use [[computeMemoryUsage]] or [[dumpMemoryUsage]] to guide memory limit
|
||||
* tuning.
|
||||
*
|
||||
* Configure ES module loading with [[setModuleLoader]].
|
||||
*/
|
||||
class QuickJSRuntime {
|
||||
/** @private */
|
||||
constructor(args) {
|
||||
/** @private */
|
||||
this.scope = new lifetime_1.Scope();
|
||||
/** @private */
|
||||
this.contextMap = new Map();
|
||||
this.cToHostCallbacks = {
|
||||
shouldInterrupt: (rt) => {
|
||||
if (rt !== this.rt.value) {
|
||||
throw new Error("QuickJSContext instance received C -> JS interrupt with mismatched rt");
|
||||
}
|
||||
const fn = this.interruptHandler;
|
||||
if (!fn) {
|
||||
throw new Error("QuickJSContext had no interrupt handler");
|
||||
}
|
||||
return fn(this) ? 1 : 0;
|
||||
},
|
||||
loadModuleSource: (0, asyncify_helpers_1.maybeAsyncFn)(this, function* (awaited, rt, ctx, moduleName) {
|
||||
const moduleLoader = this.moduleLoader;
|
||||
if (!moduleLoader) {
|
||||
throw new Error("Runtime has no module loader");
|
||||
}
|
||||
if (rt !== this.rt.value) {
|
||||
throw new Error("Runtime pointer mismatch");
|
||||
}
|
||||
const context = this.contextMap.get(ctx) ??
|
||||
this.newContext({
|
||||
contextPointer: ctx,
|
||||
});
|
||||
try {
|
||||
const result = yield* awaited(moduleLoader(moduleName, context));
|
||||
if (typeof result === "object" && "error" in result && result.error) {
|
||||
(0, debug_1.debugLog)("cToHostLoadModule: loader returned error", result.error);
|
||||
throw result.error;
|
||||
}
|
||||
const moduleSource = typeof result === "string" ? result : "value" in result ? result.value : result;
|
||||
return this.memory.newHeapCharPointer(moduleSource).value;
|
||||
}
|
||||
catch (error) {
|
||||
(0, debug_1.debugLog)("cToHostLoadModule: caught error", error);
|
||||
context.throw(error);
|
||||
return 0;
|
||||
}
|
||||
}),
|
||||
normalizeModule: (0, asyncify_helpers_1.maybeAsyncFn)(this, function* (awaited, rt, ctx, baseModuleName, moduleNameRequest) {
|
||||
const moduleNormalizer = this.moduleNormalizer;
|
||||
if (!moduleNormalizer) {
|
||||
throw new Error("Runtime has no module normalizer");
|
||||
}
|
||||
if (rt !== this.rt.value) {
|
||||
throw new Error("Runtime pointer mismatch");
|
||||
}
|
||||
const context = this.contextMap.get(ctx) ??
|
||||
this.newContext({
|
||||
/* TODO: Does this happen? Are we responsible for disposing? I don't think so */
|
||||
contextPointer: ctx,
|
||||
});
|
||||
try {
|
||||
const result = yield* awaited(moduleNormalizer(baseModuleName, moduleNameRequest, context));
|
||||
if (typeof result === "object" && "error" in result && result.error) {
|
||||
(0, debug_1.debugLog)("cToHostNormalizeModule: normalizer returned error", result.error);
|
||||
throw result.error;
|
||||
}
|
||||
const name = typeof result === "string" ? result : result.value;
|
||||
return context.getMemory(this.rt.value).newHeapCharPointer(name).value;
|
||||
}
|
||||
catch (error) {
|
||||
(0, debug_1.debugLog)("normalizeModule: caught error", error);
|
||||
context.throw(error);
|
||||
return 0;
|
||||
}
|
||||
}),
|
||||
};
|
||||
args.ownedLifetimes?.forEach((lifetime) => this.scope.manage(lifetime));
|
||||
this.module = args.module;
|
||||
this.memory = new memory_1.ModuleMemory(this.module);
|
||||
this.ffi = args.ffi;
|
||||
this.rt = args.rt;
|
||||
this.callbacks = args.callbacks;
|
||||
this.scope.manage(this.rt);
|
||||
this.callbacks.setRuntimeCallbacks(this.rt.value, this.cToHostCallbacks);
|
||||
this.executePendingJobs = this.executePendingJobs.bind(this);
|
||||
}
|
||||
get alive() {
|
||||
return this.scope.alive;
|
||||
}
|
||||
dispose() {
|
||||
return this.scope.dispose();
|
||||
}
|
||||
newContext(options = {}) {
|
||||
if (options.intrinsics && options.intrinsics !== types_1.DefaultIntrinsics) {
|
||||
throw new Error("TODO: Custom intrinsics are not supported yet");
|
||||
}
|
||||
const ctx = new lifetime_1.Lifetime(options.contextPointer || this.ffi.QTS_NewContext(this.rt.value), undefined, (ctx_ptr) => {
|
||||
this.contextMap.delete(ctx_ptr);
|
||||
this.callbacks.deleteContext(ctx_ptr);
|
||||
this.ffi.QTS_FreeContext(ctx_ptr);
|
||||
});
|
||||
const context = new context_1.QuickJSContext({
|
||||
module: this.module,
|
||||
ctx,
|
||||
ffi: this.ffi,
|
||||
rt: this.rt,
|
||||
ownedLifetimes: options.ownedLifetimes,
|
||||
runtime: this,
|
||||
callbacks: this.callbacks,
|
||||
});
|
||||
this.contextMap.set(ctx.value, context);
|
||||
return context;
|
||||
}
|
||||
/**
|
||||
* Set the loader for EcmaScript modules requested by any context in this
|
||||
* runtime.
|
||||
*
|
||||
* The loader can be removed with [[removeModuleLoader]].
|
||||
*/
|
||||
setModuleLoader(moduleLoader, moduleNormalizer) {
|
||||
this.moduleLoader = moduleLoader;
|
||||
this.moduleNormalizer = moduleNormalizer;
|
||||
this.ffi.QTS_RuntimeEnableModuleLoader(this.rt.value, this.moduleNormalizer ? 1 : 0);
|
||||
}
|
||||
/**
|
||||
* Remove the the loader set by [[setModuleLoader]]. This disables module loading.
|
||||
*/
|
||||
removeModuleLoader() {
|
||||
this.moduleLoader = undefined;
|
||||
this.ffi.QTS_RuntimeDisableModuleLoader(this.rt.value);
|
||||
}
|
||||
// Runtime management -------------------------------------------------------
|
||||
/**
|
||||
* In QuickJS, promises and async functions create pendingJobs. These do not execute
|
||||
* immediately and need to be run by calling [[executePendingJobs]].
|
||||
*
|
||||
* @return true if there is at least one pendingJob queued up.
|
||||
*/
|
||||
hasPendingJob() {
|
||||
return Boolean(this.ffi.QTS_IsJobPending(this.rt.value));
|
||||
}
|
||||
/**
|
||||
* Set a callback which is regularly called by the QuickJS engine when it is
|
||||
* executing code. This callback can be used to implement an execution
|
||||
* timeout.
|
||||
*
|
||||
* The interrupt handler can be removed with [[removeInterruptHandler]].
|
||||
*/
|
||||
setInterruptHandler(cb) {
|
||||
const prevInterruptHandler = this.interruptHandler;
|
||||
this.interruptHandler = cb;
|
||||
if (!prevInterruptHandler) {
|
||||
this.ffi.QTS_RuntimeEnableInterruptHandler(this.rt.value);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Remove the interrupt handler, if any.
|
||||
* See [[setInterruptHandler]].
|
||||
*/
|
||||
removeInterruptHandler() {
|
||||
if (this.interruptHandler) {
|
||||
this.ffi.QTS_RuntimeDisableInterruptHandler(this.rt.value);
|
||||
this.interruptHandler = undefined;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Execute pendingJobs on the runtime until `maxJobsToExecute` jobs are
|
||||
* executed (default all pendingJobs), the queue is exhausted, or the runtime
|
||||
* encounters an exception.
|
||||
*
|
||||
* In QuickJS, promises and async functions *inside the runtime* create
|
||||
* pendingJobs. These do not execute immediately and need to triggered to run.
|
||||
*
|
||||
* @param maxJobsToExecute - When negative, run all pending jobs. Otherwise execute
|
||||
* at most `maxJobsToExecute` before returning.
|
||||
*
|
||||
* @return On success, the number of executed jobs. On error, the exception
|
||||
* that stopped execution, and the context it occurred in. Note that
|
||||
* executePendingJobs will not normally return errors thrown inside async
|
||||
* functions or rejected promises. Those errors are available by calling
|
||||
* [[resolvePromise]] on the promise handle returned by the async function.
|
||||
*/
|
||||
executePendingJobs(maxJobsToExecute = -1) {
|
||||
const ctxPtrOut = this.memory.newMutablePointerArray(1);
|
||||
const valuePtr = this.ffi.QTS_ExecutePendingJob(this.rt.value, maxJobsToExecute ?? -1, ctxPtrOut.value.ptr);
|
||||
const ctxPtr = ctxPtrOut.value.typedArray[0];
|
||||
ctxPtrOut.dispose();
|
||||
if (ctxPtr === 0) {
|
||||
// No jobs executed.
|
||||
this.ffi.QTS_FreeValuePointerRuntime(this.rt.value, valuePtr);
|
||||
return { value: 0 };
|
||||
}
|
||||
const context = this.contextMap.get(ctxPtr) ??
|
||||
this.newContext({
|
||||
contextPointer: ctxPtr,
|
||||
});
|
||||
const resultValue = context.getMemory(this.rt.value).heapValueHandle(valuePtr);
|
||||
const typeOfRet = context.typeof(resultValue);
|
||||
if (typeOfRet === "number") {
|
||||
const executedJobs = context.getNumber(resultValue);
|
||||
resultValue.dispose();
|
||||
return { value: executedJobs };
|
||||
}
|
||||
else {
|
||||
const error = Object.assign(resultValue, { context });
|
||||
return {
|
||||
error,
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set the max memory this runtime can allocate.
|
||||
* To remove the limit, set to `-1`.
|
||||
*/
|
||||
setMemoryLimit(limitBytes) {
|
||||
if (limitBytes < 0 && limitBytes !== -1) {
|
||||
throw new Error("Cannot set memory limit to negative number. To unset, pass -1");
|
||||
}
|
||||
this.ffi.QTS_RuntimeSetMemoryLimit(this.rt.value, limitBytes);
|
||||
}
|
||||
/**
|
||||
* Compute memory usage for this runtime. Returns the result as a handle to a
|
||||
* JSValue object. Use [[QuickJSContext.dump]] to convert to a native object.
|
||||
* Calling this method will allocate more memory inside the runtime. The information
|
||||
* is accurate as of just before the call to `computeMemoryUsage`.
|
||||
* For a human-digestible representation, see [[dumpMemoryUsage]].
|
||||
*/
|
||||
computeMemoryUsage() {
|
||||
const serviceContextMemory = this.getSystemContext().getMemory(this.rt.value);
|
||||
return serviceContextMemory.heapValueHandle(this.ffi.QTS_RuntimeComputeMemoryUsage(this.rt.value, serviceContextMemory.ctx.value));
|
||||
}
|
||||
/**
|
||||
* @returns a human-readable description of memory usage in this runtime.
|
||||
* For programmatic access to this information, see [[computeMemoryUsage]].
|
||||
*/
|
||||
dumpMemoryUsage() {
|
||||
return this.memory.consumeHeapCharPointer(this.ffi.QTS_RuntimeDumpMemoryUsage(this.rt.value));
|
||||
}
|
||||
/**
|
||||
* Set the max stack size for this runtime, in bytes.
|
||||
* To remove the limit, set to `0`.
|
||||
*/
|
||||
setMaxStackSize(stackSize) {
|
||||
if (stackSize < 0) {
|
||||
throw new Error("Cannot set memory limit to negative number. To unset, pass 0.");
|
||||
}
|
||||
this.ffi.QTS_RuntimeSetMaxStackSize(this.rt.value, stackSize);
|
||||
}
|
||||
/**
|
||||
* Assert that `handle` is owned by this runtime.
|
||||
* @throws QuickJSWrongOwner if owned by a different runtime.
|
||||
*/
|
||||
assertOwned(handle) {
|
||||
if (handle.owner && handle.owner.rt !== this.rt) {
|
||||
throw new errors_1.QuickJSWrongOwner(`Handle is not owned by this runtime: ${handle.owner.rt.value} != ${this.rt.value}`);
|
||||
}
|
||||
}
|
||||
getSystemContext() {
|
||||
if (!this.context) {
|
||||
// We own this context and should dispose of it.
|
||||
this.context = this.scope.manage(this.newContext());
|
||||
}
|
||||
return this.context;
|
||||
}
|
||||
}
|
||||
exports.QuickJSRuntime = QuickJSRuntime;
|
||||
//# sourceMappingURL=runtime.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/runtime.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
114
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types-ffi.d.ts
generated
vendored
Normal file
114
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types-ffi.d.ts
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* C pointer to type `CType`. Pointer types are used internally for FFI, but
|
||||
* are not intended for external use.
|
||||
*
|
||||
* @unstable This type is considered private and may change.
|
||||
*/
|
||||
type Pointer<CType extends string> = number & {
|
||||
ctype: CType;
|
||||
};
|
||||
type Brand<T, B> = T & {
|
||||
brand: B;
|
||||
};
|
||||
/**
|
||||
* `JSRuntime*`.
|
||||
*/
|
||||
export type JSRuntimePointer = Pointer<"JSRuntime">;
|
||||
/**
|
||||
* `JSContext*`.
|
||||
*/
|
||||
export type JSContextPointer = Pointer<"JSContext">;
|
||||
/**
|
||||
* `JSContext**`. Used internally for execute pending jobs.
|
||||
*/
|
||||
export type JSContextPointerPointer = Pointer<"JSContext">;
|
||||
/**
|
||||
* `JSModuleDef*`.
|
||||
*/
|
||||
export type JSModuleDefPointer = Pointer<"JSModuleDef">;
|
||||
/**
|
||||
* `JSValue*`.
|
||||
* See [[JSValue]].
|
||||
*/
|
||||
export type JSValuePointer = Pointer<"JSValue">;
|
||||
/**
|
||||
* `JSValueConst*
|
||||
* See [[JSValueConst]] and [[StaticJSValue]].
|
||||
*/
|
||||
export type JSValueConstPointer = Pointer<"JSValueConst">;
|
||||
/**
|
||||
* Used internally for Javascript-to-C function calls.
|
||||
*/
|
||||
export type JSValuePointerPointer = Pointer<"JSValue[]">;
|
||||
/**
|
||||
* Used internally for Javascript-to-C function calls.
|
||||
*/
|
||||
export type JSValueConstPointerPointer = Pointer<"JSValueConst[]">;
|
||||
/**
|
||||
* Used internally for C-to-Javascript function calls.
|
||||
*/
|
||||
/**
|
||||
* Used internally for C-to-Javascript function calls.
|
||||
*/
|
||||
export type QTS_C_To_HostCallbackFuncPointer = Pointer<"C_To_HostCallbackFunc">;
|
||||
/**
|
||||
* Used internally for C-to-Javascript interrupt handlers.
|
||||
*/
|
||||
export type QTS_C_To_HostInterruptFuncPointer = Pointer<"C_To_HostInterruptFunc">;
|
||||
/**
|
||||
* Used internally for C-to-Javascript module loading.
|
||||
*/
|
||||
export type QTS_C_To_HostLoadModuleFuncPointer = Pointer<"C_To_HostLoadModuleFunc">;
|
||||
/**
|
||||
* Used internally for Javascript-to-C calls that may contain strings too large
|
||||
* for the Emscripten stack.
|
||||
*/
|
||||
export type BorrowedHeapCharPointer = Pointer<"const char" | "char" | "js const char">;
|
||||
/**
|
||||
* Used internally for Javascript-to-C calls that may contain strings too large
|
||||
* for the Emscripten stack.
|
||||
*/
|
||||
export type OwnedHeapCharPointer = Pointer<"char">;
|
||||
/**
|
||||
* Used internally for Javascript-to-C calls that may contain strings too large
|
||||
* for the Emscripten stack.
|
||||
*/
|
||||
export type JSBorrowedCharPointer = Pointer<"js const char">;
|
||||
/**
|
||||
* Opaque pointer that was allocated by js_malloc.
|
||||
*/
|
||||
export type JSVoidPointer = Pointer<any>;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export type EvalFlags = Brand<number, "EvalFlags">;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export type EvalDetectModule = Brand<number, "EvalDetectModule">;
|
||||
export declare function assertSync<Args extends any[], R>(fn: (...args: Args) => R): (...args: Args) => R;
|
||||
/** Bitfield options for JS_Eval() C function. */
|
||||
export declare const EvalFlags: {
|
||||
/** global code (default) */
|
||||
JS_EVAL_TYPE_GLOBAL: number;
|
||||
/** module code */
|
||||
JS_EVAL_TYPE_MODULE: number;
|
||||
/** direct call (internal use) */
|
||||
JS_EVAL_TYPE_DIRECT: number;
|
||||
/** indirect call (internal use) */
|
||||
JS_EVAL_TYPE_INDIRECT: number;
|
||||
JS_EVAL_TYPE_MASK: number;
|
||||
/** force 'strict' mode */
|
||||
JS_EVAL_FLAG_STRICT: number;
|
||||
/** force 'strip' mode */
|
||||
JS_EVAL_FLAG_STRIP: number;
|
||||
/**
|
||||
* compile but do not run. The result is an object with a
|
||||
* JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
|
||||
* with JS_EvalFunction().
|
||||
*/
|
||||
JS_EVAL_FLAG_COMPILE_ONLY: number;
|
||||
/** don't include the stack frames before this eval in the Error() backtraces */
|
||||
JS_EVAL_FLAG_BACKTRACE_BARRIER: number;
|
||||
};
|
||||
export {};
|
||||
38
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types-ffi.js
generated
vendored
Normal file
38
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types-ffi.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EvalFlags = exports.assertSync = void 0;
|
||||
function assertSync(fn) {
|
||||
return function mustBeSync(...args) {
|
||||
const result = fn(...args);
|
||||
if (result && typeof result === "object" && result instanceof Promise) {
|
||||
throw new Error("Function unexpectedly returned a Promise");
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
exports.assertSync = assertSync;
|
||||
/** Bitfield options for JS_Eval() C function. */
|
||||
exports.EvalFlags = {
|
||||
/** global code (default) */
|
||||
JS_EVAL_TYPE_GLOBAL: 0 << 0,
|
||||
/** module code */
|
||||
JS_EVAL_TYPE_MODULE: 1 << 0,
|
||||
/** direct call (internal use) */
|
||||
JS_EVAL_TYPE_DIRECT: 2 << 0,
|
||||
/** indirect call (internal use) */
|
||||
JS_EVAL_TYPE_INDIRECT: 3 << 0,
|
||||
JS_EVAL_TYPE_MASK: 3 << 0,
|
||||
/** force 'strict' mode */
|
||||
JS_EVAL_FLAG_STRICT: 1 << 3,
|
||||
/** force 'strip' mode */
|
||||
JS_EVAL_FLAG_STRIP: 1 << 4,
|
||||
/**
|
||||
* compile but do not run. The result is an object with a
|
||||
* JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
|
||||
* with JS_EvalFunction().
|
||||
*/
|
||||
JS_EVAL_FLAG_COMPILE_ONLY: 1 << 5,
|
||||
/** don't include the stack frames before this eval in the Error() backtraces */
|
||||
JS_EVAL_FLAG_BACKTRACE_BARRIER: 1 << 6,
|
||||
};
|
||||
//# sourceMappingURL=types-ffi.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types-ffi.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types-ffi.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"types-ffi.js","sourceRoot":"","sources":["../ts/types-ffi.ts"],"names":[],"mappings":";;;AAyGA,SAAgB,UAAU,CAAwB,EAAwB;IACxE,OAAO,SAAS,UAAU,CAAC,GAAG,IAAU;QACtC,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QAC1B,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,YAAY,OAAO,EAAE;YACrE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;SAC5D;QACD,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;AACH,CAAC;AARD,gCAQC;AAED,iDAAiD;AACpC,QAAA,SAAS,GAAG;IACvB,4BAA4B;IAC5B,mBAAmB,EAAE,CAAC,IAAI,CAAC;IAC3B,kBAAkB;IAClB,mBAAmB,EAAE,CAAC,IAAI,CAAC;IAC3B,iCAAiC;IACjC,mBAAmB,EAAE,CAAC,IAAI,CAAC;IAC3B,mCAAmC;IACnC,qBAAqB,EAAE,CAAC,IAAI,CAAC;IAC7B,iBAAiB,EAAE,CAAC,IAAI,CAAC;IACzB,0BAA0B;IAC1B,mBAAmB,EAAE,CAAC,IAAI,CAAC;IAC3B,yBAAyB;IACzB,kBAAkB,EAAE,CAAC,IAAI,CAAC;IAC1B;;;;OAIG;IACH,yBAAyB,EAAE,CAAC,IAAI,CAAC;IACjC,gFAAgF;IAChF,8BAA8B,EAAE,CAAC,IAAI,CAAC;CACvC,CAAA","sourcesContent":["/**\n * C pointer to type `CType`. Pointer types are used internally for FFI, but\n * are not intended for external use.\n *\n * @unstable This type is considered private and may change.\n */\ntype Pointer<CType extends string> = number & { ctype: CType }\n\ntype Brand<T, B> = T & { brand: B }\n\n/**\n * `JSRuntime*`.\n */\nexport type JSRuntimePointer = Pointer<\"JSRuntime\">\n\n/**\n * `JSContext*`.\n */\nexport type JSContextPointer = Pointer<\"JSContext\">\n\n/**\n * `JSContext**`. Used internally for execute pending jobs.\n */\nexport type JSContextPointerPointer = Pointer<\"JSContext\">\n\n/**\n * `JSModuleDef*`.\n */\nexport type JSModuleDefPointer = Pointer<\"JSModuleDef\">\n\n/**\n * `JSValue*`.\n * See [[JSValue]].\n */\nexport type JSValuePointer = Pointer<\"JSValue\">\n\n/**\n * `JSValueConst*\n * See [[JSValueConst]] and [[StaticJSValue]].\n */\nexport type JSValueConstPointer = Pointer<\"JSValueConst\">\n\n/**\n * Used internally for Javascript-to-C function calls.\n */\nexport type JSValuePointerPointer = Pointer<\"JSValue[]\">\n\n/**\n * Used internally for Javascript-to-C function calls.\n */\nexport type JSValueConstPointerPointer = Pointer<\"JSValueConst[]\">\n\n/**\n * Used internally for C-to-Javascript function calls.\n */\n// type JSCFunctionPointer = Pointer<'JSCFunction'>\n\n/**\n * Used internally for C-to-Javascript function calls.\n */\nexport type QTS_C_To_HostCallbackFuncPointer = Pointer<\"C_To_HostCallbackFunc\">\n\n/**\n * Used internally for C-to-Javascript interrupt handlers.\n */\nexport type QTS_C_To_HostInterruptFuncPointer = Pointer<\"C_To_HostInterruptFunc\">\n\n/**\n * Used internally for C-to-Javascript module loading.\n */\nexport type QTS_C_To_HostLoadModuleFuncPointer = Pointer<\"C_To_HostLoadModuleFunc\">\n\n/**\n * Used internally for Javascript-to-C calls that may contain strings too large\n * for the Emscripten stack.\n */\nexport type BorrowedHeapCharPointer = Pointer<\"const char\" | \"char\" | \"js const char\">\n\n/**\n * Used internally for Javascript-to-C calls that may contain strings too large\n * for the Emscripten stack.\n */\nexport type OwnedHeapCharPointer = Pointer<\"char\">\n\n/**\n * Used internally for Javascript-to-C calls that may contain strings too large\n * for the Emscripten stack.\n */\nexport type JSBorrowedCharPointer = Pointer<\"js const char\">\n\n/**\n * Opaque pointer that was allocated by js_malloc.\n */\nexport type JSVoidPointer = Pointer<any>\n\n/**\n * @private\n */\nexport type EvalFlags = Brand<number, \"EvalFlags\">\n\n/**\n * @private\n */\nexport type EvalDetectModule = Brand<number, \"EvalDetectModule\">\n\nexport function assertSync<Args extends any[], R>(fn: (...args: Args) => R): (...args: Args) => R {\n return function mustBeSync(...args: Args): R {\n const result = fn(...args)\n if (result && typeof result === \"object\" && result instanceof Promise) {\n throw new Error(\"Function unexpectedly returned a Promise\")\n }\n return result\n }\n}\n\n/** Bitfield options for JS_Eval() C function. */\nexport const EvalFlags = {\n /** global code (default) */\n JS_EVAL_TYPE_GLOBAL: 0 << 0,\n /** module code */\n JS_EVAL_TYPE_MODULE: 1 << 0,\n /** direct call (internal use) */\n JS_EVAL_TYPE_DIRECT: 2 << 0,\n /** indirect call (internal use) */\n JS_EVAL_TYPE_INDIRECT: 3 << 0,\n JS_EVAL_TYPE_MASK: 3 << 0,\n /** force 'strict' mode */\n JS_EVAL_FLAG_STRICT: 1 << 3,\n /** force 'strip' mode */\n JS_EVAL_FLAG_STRIP: 1 << 4,\n /**\n * compile but do not run. The result is an object with a\n * JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed\n * with JS_EvalFunction().\n */\n JS_EVAL_FLAG_COMPILE_ONLY: 1 << 5,\n /** don't include the stack frames before this eval in the Error() backtraces */\n JS_EVAL_FLAG_BACKTRACE_BARRIER: 1 << 6,\n}\n"]}
|
||||
158
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types.d.ts
generated
vendored
Normal file
158
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types.d.ts
generated
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
import type { QuickJSFFI, QuickJSAsyncFFI } from "./variants";
|
||||
import type { QuickJSContext } from "./context";
|
||||
import type { SuccessOrFail, VmFunctionImplementation } from "./vm-interface";
|
||||
import type { Disposable, Lifetime } from "./lifetime";
|
||||
import type { QuickJSAsyncContext } from "./context-asyncify";
|
||||
import type { InterruptHandler, QuickJSRuntime } from "./runtime";
|
||||
import { JSContextPointer, JSValueConstPointer, JSValuePointer } from "./types-ffi";
|
||||
export type EitherFFI = QuickJSFFI | QuickJSAsyncFFI;
|
||||
/**
|
||||
* A QuickJSHandle to a constant that will never change, and does not need to
|
||||
* be disposed.
|
||||
*/
|
||||
export type StaticJSValue = Lifetime<JSValueConstPointer, JSValueConstPointer, QuickJSRuntime>;
|
||||
/**
|
||||
* A QuickJSHandle to a borrowed value that does not need to be disposed.
|
||||
*
|
||||
* In QuickJS, a JSValueConst is a "borrowed" reference that isn't owned by the
|
||||
* current scope. That means that the current scope should not `JS_FreeValue`
|
||||
* it, or retain a reference to it after the scope exits, because it may be
|
||||
* freed by its owner.
|
||||
*
|
||||
* quickjs-emscripten takes care of disposing JSValueConst references.
|
||||
*/
|
||||
export type JSValueConst = Lifetime<JSValueConstPointer, JSValuePointer, QuickJSRuntime>;
|
||||
/**
|
||||
* A owned QuickJSHandle that should be disposed or returned.
|
||||
*
|
||||
* The QuickJS interpreter passes Javascript values between functions as
|
||||
* `JSValue` structs that references some internal data. Because passing
|
||||
* structs cross the Empscripten FFI interfaces is bothersome, we use pointers
|
||||
* to these structs instead.
|
||||
*
|
||||
* A JSValue reference is "owned" in its scope. before exiting the scope, it
|
||||
* should be freed, by calling `JS_FreeValue(ctx, js_value)`) or returned from
|
||||
* the scope. We extend that contract - a JSValuePointer (`JSValue*`) must also
|
||||
* be `free`d.
|
||||
*
|
||||
* You can do so from Javascript by calling the .dispose() method.
|
||||
*/
|
||||
export type JSValue = Lifetime<JSValuePointer, JSValuePointer, QuickJSRuntime>;
|
||||
/**
|
||||
* Wraps a C pointer to a QuickJS JSValue, which represents a Javascript value inside
|
||||
* a QuickJS virtual machine.
|
||||
*
|
||||
* Values must not be shared between QuickJSContext instances.
|
||||
* You must dispose of any handles you create by calling the `.dispose()` method.
|
||||
*/
|
||||
export type QuickJSHandle = StaticJSValue | JSValue | JSValueConst;
|
||||
export type JSModuleExport = {
|
||||
type: "function";
|
||||
name: string;
|
||||
implementation: (vm: QuickJSContext) => VmFunctionImplementation<QuickJSHandle>;
|
||||
} | {
|
||||
type: "value";
|
||||
name: string;
|
||||
value: (vm: QuickJSContext) => QuickJSHandle;
|
||||
};
|
||||
export interface JSModuleDefinition {
|
||||
name: string;
|
||||
exports: JSModuleExport[];
|
||||
}
|
||||
export type JSModuleLoadSuccess = string;
|
||||
export type JSModuleLoadFailure = Error | QuickJSHandle;
|
||||
export type JSModuleLoadResult = JSModuleLoadSuccess | SuccessOrFail<JSModuleLoadSuccess, JSModuleLoadFailure>;
|
||||
export interface JSModuleLoaderAsync {
|
||||
/** Load module (async) */
|
||||
(moduleName: string, context: QuickJSAsyncContext): JSModuleLoadResult | Promise<JSModuleLoadResult>;
|
||||
}
|
||||
export interface JSModuleLoader {
|
||||
/** Load module (sync) */
|
||||
(moduleName: string, context: QuickJSContext): JSModuleLoadResult;
|
||||
}
|
||||
export type JSModuleNormalizeSuccess = string;
|
||||
export type JSModuleNormalizeFailure = Error | QuickJSHandle;
|
||||
export type JSModuleNormalizeResult = JSModuleNormalizeSuccess | SuccessOrFail<JSModuleNormalizeSuccess, JSModuleNormalizeFailure>;
|
||||
export interface JSModuleNormalizerAsync {
|
||||
(baseModuleName: string, requestedName: string, vm: QuickJSAsyncContext): JSModuleNormalizeResult | Promise<JSModuleNormalizeResult>;
|
||||
}
|
||||
export interface JSModuleNormalizer extends JSModuleNormalizerAsync {
|
||||
(baseModuleName: string, requestedName: string, vm: QuickJSContext): JSModuleNormalizeResult;
|
||||
}
|
||||
type TODO<hint extends string = "?", typeHint = unknown> = never;
|
||||
declare const UnstableSymbol: unique symbol;
|
||||
export type PartiallyImplemented<T> = never & T & {
|
||||
[UnstableSymbol]: "This feature may unimplemented, broken, throw errors, etc.";
|
||||
};
|
||||
export interface RuntimeOptionsBase {
|
||||
interruptHandler?: InterruptHandler;
|
||||
maxStackSizeBytes?: number;
|
||||
memoryLimitBytes?: number;
|
||||
promiseRejectionHandler?: TODO<"JSHostPromiseRejectionTracker">;
|
||||
runtimeInfo?: TODO<"JS_SetRuntimeInfo", string>;
|
||||
gcThreshold?: TODO<"JS_SetGCThreshold", number>;
|
||||
sharedArrayBufferFunctions?: TODO<"JS_SetJSSharedArrayBufferFunctions", {
|
||||
sab_alloc: TODO;
|
||||
sab_free: TODO;
|
||||
sab_dup: TODO;
|
||||
sab_opaque: TODO;
|
||||
}>;
|
||||
/**
|
||||
* Extra lifetimes the runtime should dispose of after it is destroyed.
|
||||
* @private
|
||||
*/
|
||||
ownedLifetimes?: Disposable[];
|
||||
}
|
||||
export interface RuntimeOptions extends RuntimeOptionsBase {
|
||||
moduleLoader?: JSModuleLoader;
|
||||
}
|
||||
export interface AsyncRuntimeOptions extends RuntimeOptionsBase {
|
||||
moduleLoader?: JSModuleLoaderAsync | JSModuleLoader;
|
||||
}
|
||||
/**
|
||||
* Work in progress.
|
||||
*/
|
||||
export type Intrinsic = "BaseObjects" | "Date" | "Eval" | "StringNormalize" | "RegExp" | "RegExpCompiler" | "JSON" | "Proxy" | "MapSet" | "TypedArrays" | "Promise" | "BigInt" | "BigFloat" | "BigDecimal" | "OperatorOverloading" | "BignumExt";
|
||||
/**
|
||||
* Work in progress.
|
||||
*/
|
||||
export declare const DefaultIntrinsics: unique symbol;
|
||||
export interface ContextOptions {
|
||||
/**
|
||||
* What built-in objects and language features to enable?
|
||||
* If unset, the default intrinsics will be used.
|
||||
* To omit all intrinsics, pass an empty array.
|
||||
*/
|
||||
intrinsics?: PartiallyImplemented<Intrinsic[]> | typeof DefaultIntrinsics;
|
||||
/**
|
||||
* Wrap the provided context instead of constructing a new one.
|
||||
* @private
|
||||
*/
|
||||
contextPointer?: JSContextPointer;
|
||||
/**
|
||||
* Extra lifetimes the context should dispose of after it is destroyed.
|
||||
* @private
|
||||
*/
|
||||
ownedLifetimes?: Disposable[];
|
||||
}
|
||||
export interface ContextEvalOptions {
|
||||
/** Global code (default) */
|
||||
type?: "global" | "module";
|
||||
/** Force "strict" mode */
|
||||
strict?: boolean;
|
||||
/** Force "strip" mode */
|
||||
strip?: boolean;
|
||||
/**
|
||||
* compile but do not run. The result is an object with a
|
||||
* JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
|
||||
* with JS_EvalFunction().
|
||||
*/
|
||||
compileOnly?: boolean;
|
||||
/** don't include the stack frames before this eval in the Error() backtraces */
|
||||
backtraceBarrier?: boolean;
|
||||
}
|
||||
/** Convert [[ContextEvalOptions]] to a bitfield flags */
|
||||
export declare function evalOptionsToFlags(evalOptions: ContextEvalOptions | number | undefined): number;
|
||||
export type PromiseExecutor<ResolveT, RejectT> = (resolve: (value: ResolveT | PromiseLike<ResolveT>) => void, reject: (reason: RejectT) => void) => void;
|
||||
export declare function concat<T>(...values: Array<T[] | T | undefined>): T[];
|
||||
export {};
|
||||
58
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types.js
generated
vendored
Normal file
58
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types.js
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.concat = exports.evalOptionsToFlags = exports.DefaultIntrinsics = void 0;
|
||||
const types_ffi_1 = require("./types-ffi");
|
||||
const UnstableSymbol = Symbol("Unstable");
|
||||
// For informational purposes
|
||||
const DefaultIntrinsicsList = [
|
||||
"BaseObjects",
|
||||
"Date",
|
||||
"Eval",
|
||||
"StringNormalize",
|
||||
"RegExp",
|
||||
"JSON",
|
||||
"Proxy",
|
||||
"MapSet",
|
||||
"TypedArrays",
|
||||
"Promise",
|
||||
];
|
||||
/**
|
||||
* Work in progress.
|
||||
*/
|
||||
exports.DefaultIntrinsics = Symbol("DefaultIntrinsics");
|
||||
/** Convert [[ContextEvalOptions]] to a bitfield flags */
|
||||
function evalOptionsToFlags(evalOptions) {
|
||||
if (typeof evalOptions === "number") {
|
||||
return evalOptions;
|
||||
}
|
||||
if (evalOptions === undefined) {
|
||||
return 0;
|
||||
}
|
||||
const { type, strict, strip, compileOnly, backtraceBarrier } = evalOptions;
|
||||
let flags = 0;
|
||||
if (type === "global")
|
||||
flags |= types_ffi_1.EvalFlags.JS_EVAL_TYPE_GLOBAL;
|
||||
if (type === "module")
|
||||
flags |= types_ffi_1.EvalFlags.JS_EVAL_TYPE_MODULE;
|
||||
if (strict)
|
||||
flags |= types_ffi_1.EvalFlags.JS_EVAL_FLAG_STRICT;
|
||||
if (strip)
|
||||
flags |= types_ffi_1.EvalFlags.JS_EVAL_FLAG_STRIP;
|
||||
if (compileOnly)
|
||||
flags |= types_ffi_1.EvalFlags.JS_EVAL_FLAG_COMPILE_ONLY;
|
||||
if (backtraceBarrier)
|
||||
flags |= types_ffi_1.EvalFlags.JS_EVAL_FLAG_BACKTRACE_BARRIER;
|
||||
return flags;
|
||||
}
|
||||
exports.evalOptionsToFlags = evalOptionsToFlags;
|
||||
function concat(...values) {
|
||||
let result = [];
|
||||
for (const value of values) {
|
||||
if (value !== undefined) {
|
||||
result = result.concat(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.concat = concat;
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/types.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
113
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/variants.d.ts
generated
vendored
Normal file
113
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/variants.d.ts
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
import type { QuickJSFFI as ReleaseSyncFFI } from "./generated/ffi.WASM_RELEASE_SYNC";
|
||||
import type { EmscriptenModuleLoader, QuickJSEmscriptenModule, QuickJSAsyncEmscriptenModule } from "./emscripten-types";
|
||||
import type { QuickJSWASMModule } from "./module";
|
||||
import type { QuickJSAsyncWASMModule } from "./module-asyncify";
|
||||
/** @private */
|
||||
export type QuickJSFFI = ReleaseSyncFFI;
|
||||
/** @private */
|
||||
export type QuickJSFFIConstructor = typeof ReleaseSyncFFI;
|
||||
/** @private */
|
||||
export type QuickJSAsyncFFI = any;
|
||||
/** @private */
|
||||
export type QuickJSAsyncFFIConstructor = any;
|
||||
/**
|
||||
* quickjs-emscripten provides multiple build variants of the core WebAssembly
|
||||
* module. These variants are each intended for a different use case.
|
||||
*
|
||||
* To create an instance of the library using a specific build variant, pass the
|
||||
* build variant to {@link newQuickJSWASMModule} or {@link newQuickJSAsyncWASMModule}.
|
||||
*
|
||||
* Synchronous build variants:
|
||||
*
|
||||
* - {@link RELEASE_SYNC} - This is the default synchronous variant, for general purpose use.
|
||||
* - {@link DEBUG_SYNC} - Synchronous build variant for debugging memory leaks.
|
||||
*/
|
||||
export interface SyncBuildVariant {
|
||||
type: "sync";
|
||||
importFFI: () => Promise<QuickJSFFIConstructor>;
|
||||
importModuleLoader: () => Promise<EmscriptenModuleLoader<QuickJSEmscriptenModule>>;
|
||||
}
|
||||
/**
|
||||
* quickjs-emscripten provides multiple build variants of the core WebAssembly
|
||||
* module. These variants are each intended for a different use case.
|
||||
*
|
||||
* To create an instance of the library using a specific build variant, pass the
|
||||
* build variant to {@link newQuickJSWASMModule} or {@link newQuickJSAsyncWASMModule}.
|
||||
*
|
||||
* Asyncified build variants:
|
||||
*
|
||||
* - {@link RELEASE_ASYNC} - This is the default asyncified build variant, for general purpose use.
|
||||
* - {@link DEBUG_ASYNC} - Asyncified build variant with debug logging.
|
||||
*/
|
||||
export interface AsyncBuildVariant {
|
||||
type: "async";
|
||||
importFFI: () => Promise<QuickJSAsyncFFIConstructor>;
|
||||
importModuleLoader: () => Promise<EmscriptenModuleLoader<QuickJSAsyncEmscriptenModule>>;
|
||||
}
|
||||
/**
|
||||
* Create a new, completely isolated WebAssembly module containing the QuickJS library.
|
||||
* See the documentation on [[QuickJSWASMModule]].
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
export declare function newQuickJSWASMModule(
|
||||
/**
|
||||
* Optionally, pass a {@link SyncBuildVariant} to construct a different WebAssembly module.
|
||||
*/
|
||||
variant?: SyncBuildVariant): Promise<QuickJSWASMModule>;
|
||||
/**
|
||||
* Create a new, completely isolated WebAssembly module containing a version of the QuickJS library
|
||||
* compiled with Emscripten's [ASYNCIFY](https://emscripten.org/docs/porting/asyncify.html) transform.
|
||||
*
|
||||
* This version of the library offers features that enable synchronous code
|
||||
* inside the VM to interact with asynchronous code in the host environment.
|
||||
* See the documentation on [[QuickJSAsyncWASMModule]], [[QuickJSAsyncRuntime]],
|
||||
* and [[QuickJSAsyncContext]].
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
export declare function newQuickJSAsyncWASMModule(
|
||||
/**
|
||||
* Optionally, pass a {@link AsyncBuildVariant} to construct a different WebAssembly module.
|
||||
*/
|
||||
variant?: AsyncBuildVariant): Promise<QuickJSAsyncWASMModule>;
|
||||
/**
|
||||
* Helper intended to memoize the creation of a WebAssembly module.
|
||||
* ```typescript
|
||||
* const getDebugModule = memoizePromiseFactory(() => newQuickJSWASMModule(DEBUG_SYNC))
|
||||
* ```
|
||||
*/
|
||||
export declare function memoizePromiseFactory<T>(fn: () => Promise<T>): () => Promise<T>;
|
||||
/**
|
||||
* This build variant is compiled with `-fsanitize=leak`. It instruments all
|
||||
* memory allocations and when combined with sourcemaps, can present stack trace
|
||||
* locations where memory leaks occur.
|
||||
*
|
||||
* See [[TestQuickJSWASMModule]] which provides access to the leak sanitizer via
|
||||
* {@link TestQuickJSWASMModule.assertNoMemoryAllocated}.
|
||||
*
|
||||
* The downside is that it's 100-1000x slower than the other variants.
|
||||
* Suggested use case: automated testing, regression testing, and interactive
|
||||
* debugging.
|
||||
*/
|
||||
export declare const DEBUG_SYNC: SyncBuildVariant;
|
||||
/**
|
||||
* This is the default (synchronous) build variant.
|
||||
* {@link getQuickJS} returns a memoized instance of this build variant.
|
||||
*/
|
||||
export declare const RELEASE_SYNC: SyncBuildVariant;
|
||||
/**
|
||||
* The async debug build variant may or may not have the sanitizer enabled.
|
||||
* It does print a lot of debug logs.
|
||||
*
|
||||
* Suggested use case: interactive debugging only.
|
||||
*/
|
||||
export declare const DEBUG_ASYNC: AsyncBuildVariant;
|
||||
/**
|
||||
* This is the default asyncified build variant.
|
||||
*/
|
||||
export declare const RELEASE_ASYNC: AsyncBuildVariant;
|
||||
169
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/variants.js
generated
vendored
Normal file
169
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/variants.js
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RELEASE_ASYNC = exports.DEBUG_ASYNC = exports.RELEASE_SYNC = exports.DEBUG_SYNC = exports.memoizePromiseFactory = exports.newQuickJSAsyncWASMModule = exports.newQuickJSWASMModule = void 0;
|
||||
const esmHelpers_1 = require("./esmHelpers");
|
||||
/**
|
||||
* Create a new, completely isolated WebAssembly module containing the QuickJS library.
|
||||
* See the documentation on [[QuickJSWASMModule]].
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
async function newQuickJSWASMModule(
|
||||
/**
|
||||
* Optionally, pass a {@link SyncBuildVariant} to construct a different WebAssembly module.
|
||||
*/
|
||||
variant = exports.RELEASE_SYNC) {
|
||||
const [wasmModuleLoader, QuickJSFFI, { QuickJSWASMModule }] = await Promise.all([
|
||||
variant.importModuleLoader(),
|
||||
variant.importFFI(),
|
||||
Promise.resolve().then(() => __importStar(require("./module.js"))).then(esmHelpers_1.unwrapTypescript),
|
||||
]);
|
||||
const wasmModule = await wasmModuleLoader();
|
||||
wasmModule.type = "sync";
|
||||
const ffi = new QuickJSFFI(wasmModule);
|
||||
return new QuickJSWASMModule(wasmModule, ffi);
|
||||
}
|
||||
exports.newQuickJSWASMModule = newQuickJSWASMModule;
|
||||
/**
|
||||
* Create a new, completely isolated WebAssembly module containing a version of the QuickJS library
|
||||
* compiled with Emscripten's [ASYNCIFY](https://emscripten.org/docs/porting/asyncify.html) transform.
|
||||
*
|
||||
* This version of the library offers features that enable synchronous code
|
||||
* inside the VM to interact with asynchronous code in the host environment.
|
||||
* See the documentation on [[QuickJSAsyncWASMModule]], [[QuickJSAsyncRuntime]],
|
||||
* and [[QuickJSAsyncContext]].
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
async function newQuickJSAsyncWASMModule(
|
||||
/**
|
||||
* Optionally, pass a {@link AsyncBuildVariant} to construct a different WebAssembly module.
|
||||
*/
|
||||
variant = exports.RELEASE_ASYNC) {
|
||||
const [wasmModuleLoader, QuickJSAsyncFFI, { QuickJSAsyncWASMModule }] = await Promise.all([
|
||||
variant.importModuleLoader(),
|
||||
variant.importFFI(),
|
||||
Promise.resolve().then(() => __importStar(require("./module-asyncify.js"))).then(esmHelpers_1.unwrapTypescript),
|
||||
]);
|
||||
const wasmModule = await wasmModuleLoader();
|
||||
wasmModule.type = "async";
|
||||
const ffi = new QuickJSAsyncFFI(wasmModule);
|
||||
return new QuickJSAsyncWASMModule(wasmModule, ffi);
|
||||
}
|
||||
exports.newQuickJSAsyncWASMModule = newQuickJSAsyncWASMModule;
|
||||
/**
|
||||
* Helper intended to memoize the creation of a WebAssembly module.
|
||||
* ```typescript
|
||||
* const getDebugModule = memoizePromiseFactory(() => newQuickJSWASMModule(DEBUG_SYNC))
|
||||
* ```
|
||||
*/
|
||||
function memoizePromiseFactory(fn) {
|
||||
let promise;
|
||||
return () => {
|
||||
return (promise ?? (promise = fn()));
|
||||
};
|
||||
}
|
||||
exports.memoizePromiseFactory = memoizePromiseFactory;
|
||||
/**
|
||||
* This build variant is compiled with `-fsanitize=leak`. It instruments all
|
||||
* memory allocations and when combined with sourcemaps, can present stack trace
|
||||
* locations where memory leaks occur.
|
||||
*
|
||||
* See [[TestQuickJSWASMModule]] which provides access to the leak sanitizer via
|
||||
* {@link TestQuickJSWASMModule.assertNoMemoryAllocated}.
|
||||
*
|
||||
* The downside is that it's 100-1000x slower than the other variants.
|
||||
* Suggested use case: automated testing, regression testing, and interactive
|
||||
* debugging.
|
||||
*/
|
||||
exports.DEBUG_SYNC = {
|
||||
type: "sync",
|
||||
async importFFI() {
|
||||
throw new Error("not implemented");
|
||||
// const mod = await import("./generated/ffi.WASM_DEBUG_SYNC.js")
|
||||
// return unwrapTypescript(mod).QuickJSFFI
|
||||
},
|
||||
async importModuleLoader() {
|
||||
throw new Error("not implemented");
|
||||
// const mod = await import("./generated/emscripten-module.WASM_DEBUG_SYNC.js")
|
||||
// return unwrapJavascript(mod).default
|
||||
},
|
||||
};
|
||||
/**
|
||||
* This is the default (synchronous) build variant.
|
||||
* {@link getQuickJS} returns a memoized instance of this build variant.
|
||||
*/
|
||||
exports.RELEASE_SYNC = {
|
||||
type: "sync",
|
||||
async importFFI() {
|
||||
const mod = await Promise.resolve().then(() => __importStar(require("./generated/ffi.WASM_RELEASE_SYNC.js")));
|
||||
return (0, esmHelpers_1.unwrapTypescript)(mod).QuickJSFFI;
|
||||
},
|
||||
async importModuleLoader() {
|
||||
const mod = await Promise.resolve().then(() => __importStar(require("./generated/emscripten-module.WASM_RELEASE_SYNC.js")));
|
||||
return (0, esmHelpers_1.unwrapJavascript)(mod);
|
||||
},
|
||||
};
|
||||
/**
|
||||
* The async debug build variant may or may not have the sanitizer enabled.
|
||||
* It does print a lot of debug logs.
|
||||
*
|
||||
* Suggested use case: interactive debugging only.
|
||||
*/
|
||||
exports.DEBUG_ASYNC = {
|
||||
type: "async",
|
||||
async importFFI() {
|
||||
throw new Error("not implemented");
|
||||
// const mod = await import("./generated/ffi.WASM_DEBUG_ASYNCIFY.js")
|
||||
// return unwrapTypescript(mod).QuickJSAsyncFFI
|
||||
},
|
||||
async importModuleLoader() {
|
||||
throw new Error("not implemented");
|
||||
// const mod = await import("./generated/emscripten-module.WASM_DEBUG_ASYNCIFY.js")
|
||||
// return unwrapJavascript(mod).default
|
||||
},
|
||||
};
|
||||
/**
|
||||
* This is the default asyncified build variant.
|
||||
*/
|
||||
exports.RELEASE_ASYNC = {
|
||||
type: "async",
|
||||
async importFFI() {
|
||||
throw new Error("not implemented");
|
||||
// const mod = await import("./generated/ffi.WASM_RELEASE_ASYNCIFY.js")
|
||||
// return unwrapTypescript(mod).QuickJSAsyncFFI
|
||||
},
|
||||
async importModuleLoader() {
|
||||
throw new Error("not implemented");
|
||||
// const mod = await import("./generated/emscripten-module.WASM_RELEASE_ASYNCIFY.js")
|
||||
// return unwrapJavascript(mod).default
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=variants.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/variants.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/variants.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
68
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/vm-interface.d.ts
generated
vendored
Normal file
68
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/vm-interface.d.ts
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Used as an optional.
|
||||
* `{ value: S } | { error: E }`.
|
||||
*/
|
||||
export type SuccessOrFail<S, F> = {
|
||||
value: S;
|
||||
error?: undefined;
|
||||
} | {
|
||||
error: F;
|
||||
};
|
||||
export declare function isSuccess<S, F>(successOrFail: SuccessOrFail<S, F>): successOrFail is {
|
||||
value: S;
|
||||
};
|
||||
export declare function isFail<S, F>(successOrFail: SuccessOrFail<S, F>): successOrFail is {
|
||||
error: F;
|
||||
};
|
||||
/**
|
||||
* Used as an optional for results of a Vm call.
|
||||
* `{ value: VmHandle } | { error: VmHandle }`.
|
||||
*/
|
||||
export type VmCallResult<VmHandle> = SuccessOrFail<VmHandle, VmHandle>;
|
||||
/**
|
||||
* A VmFunctionImplementation takes handles as arguments.
|
||||
* It should return a handle, or be void.
|
||||
*
|
||||
* To indicate an exception, a VMs can throw either a handle (transferred
|
||||
* directly) or any other Javascript value (only the poperties `name` and
|
||||
* `message` will be transferred). Or, the VmFunctionImplementation may return
|
||||
* a VmCallResult's `{ error: handle }` error variant.
|
||||
*
|
||||
* VmFunctionImplementation should not free its arguments or its return value.
|
||||
* It should not retain a reference to its return value or thrown error.
|
||||
*/
|
||||
export type VmFunctionImplementation<VmHandle> = (this: VmHandle, ...args: VmHandle[]) => VmHandle | VmCallResult<VmHandle> | void;
|
||||
/**
|
||||
* A minimal interface to a Javascript execution environment.
|
||||
*
|
||||
* Higher-level tools should build over the LowLevelJavascriptVm interface to
|
||||
* share as much as possible between executors.
|
||||
*
|
||||
* From https://www.figma.com/blog/how-we-built-the-figma-plugin-system/
|
||||
*/
|
||||
export interface LowLevelJavascriptVm<VmHandle> {
|
||||
global: VmHandle;
|
||||
undefined: VmHandle;
|
||||
typeof(handle: VmHandle): string;
|
||||
getNumber(handle: VmHandle): number;
|
||||
getString(handle: VmHandle): string;
|
||||
newNumber(value: number): VmHandle;
|
||||
newString(value: string): VmHandle;
|
||||
newObject(prototype?: VmHandle): VmHandle;
|
||||
newFunction(name: string, value: VmFunctionImplementation<VmHandle>): VmHandle;
|
||||
getProp(handle: VmHandle, key: string | VmHandle): VmHandle;
|
||||
setProp(handle: VmHandle, key: string | VmHandle, value: VmHandle): void;
|
||||
defineProp(handle: VmHandle, key: string | VmHandle, descriptor: VmPropertyDescriptor<VmHandle>): void;
|
||||
callFunction(func: VmHandle, thisVal: VmHandle, ...args: VmHandle[]): VmCallResult<VmHandle>;
|
||||
evalCode(code: string, filename?: string): VmCallResult<VmHandle>;
|
||||
}
|
||||
/**
|
||||
* From https://www.figma.com/blog/how-we-built-the-figma-plugin-system/
|
||||
*/
|
||||
export interface VmPropertyDescriptor<VmHandle> {
|
||||
value?: VmHandle;
|
||||
configurable?: boolean;
|
||||
enumerable?: boolean;
|
||||
get?: (this: VmHandle) => VmHandle;
|
||||
set?: (this: VmHandle, value: VmHandle) => void;
|
||||
}
|
||||
12
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/vm-interface.js
generated
vendored
Normal file
12
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/vm-interface.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isFail = exports.isSuccess = void 0;
|
||||
function isSuccess(successOrFail) {
|
||||
return "error" in successOrFail === false;
|
||||
}
|
||||
exports.isSuccess = isSuccess;
|
||||
function isFail(successOrFail) {
|
||||
return "error" in successOrFail === true;
|
||||
}
|
||||
exports.isFail = isFail;
|
||||
//# sourceMappingURL=vm-interface.js.map
|
||||
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/vm-interface.js.map
generated
vendored
Normal file
1
Scripts/node_modules/@tootallnate/quickjs-emscripten/dist/vm-interface.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"vm-interface.js","sourceRoot":"","sources":["../ts/vm-interface.ts"],"names":[],"mappings":";;;AAaA,SAAgB,SAAS,CAAO,aAAkC;IAChE,OAAO,OAAO,IAAI,aAAa,KAAK,KAAK,CAAA;AAC3C,CAAC;AAFD,8BAEC;AAED,SAAgB,MAAM,CAAO,aAAkC;IAC7D,OAAO,OAAO,IAAI,aAAa,KAAK,IAAI,CAAA;AAC1C,CAAC;AAFD,wBAEC","sourcesContent":["/**\n * Used as an optional.\n * `{ value: S } | { error: E }`.\n */\nexport type SuccessOrFail<S, F> =\n | {\n value: S\n error?: undefined\n }\n | {\n error: F\n }\n\nexport function isSuccess<S, F>(successOrFail: SuccessOrFail<S, F>): successOrFail is { value: S } {\n return \"error\" in successOrFail === false\n}\n\nexport function isFail<S, F>(successOrFail: SuccessOrFail<S, F>): successOrFail is { error: F } {\n return \"error\" in successOrFail === true\n}\n\n/**\n * Used as an optional for results of a Vm call.\n * `{ value: VmHandle } | { error: VmHandle }`.\n */\nexport type VmCallResult<VmHandle> = SuccessOrFail<VmHandle, VmHandle>\n\n/**\n * A VmFunctionImplementation takes handles as arguments.\n * It should return a handle, or be void.\n *\n * To indicate an exception, a VMs can throw either a handle (transferred\n * directly) or any other Javascript value (only the poperties `name` and\n * `message` will be transferred). Or, the VmFunctionImplementation may return\n * a VmCallResult's `{ error: handle }` error variant.\n *\n * VmFunctionImplementation should not free its arguments or its return value.\n * It should not retain a reference to its return value or thrown error.\n */\nexport type VmFunctionImplementation<VmHandle> = (\n this: VmHandle,\n ...args: VmHandle[]\n) => VmHandle | VmCallResult<VmHandle> | void\n\n/**\n * A minimal interface to a Javascript execution environment.\n *\n * Higher-level tools should build over the LowLevelJavascriptVm interface to\n * share as much as possible between executors.\n *\n * From https://www.figma.com/blog/how-we-built-the-figma-plugin-system/\n */\nexport interface LowLevelJavascriptVm<VmHandle> {\n global: VmHandle\n undefined: VmHandle\n\n typeof(handle: VmHandle): string\n\n getNumber(handle: VmHandle): number\n getString(handle: VmHandle): string\n\n newNumber(value: number): VmHandle\n newString(value: string): VmHandle\n newObject(prototype?: VmHandle): VmHandle\n newFunction(name: string, value: VmFunctionImplementation<VmHandle>): VmHandle\n\n // For accessing properties of objects\n getProp(handle: VmHandle, key: string | VmHandle): VmHandle\n setProp(handle: VmHandle, key: string | VmHandle, value: VmHandle): void\n defineProp(\n handle: VmHandle,\n key: string | VmHandle,\n descriptor: VmPropertyDescriptor<VmHandle>\n ): void\n\n callFunction(func: VmHandle, thisVal: VmHandle, ...args: VmHandle[]): VmCallResult<VmHandle>\n evalCode(code: string, filename?: string): VmCallResult<VmHandle>\n}\n\n/**\n * From https://www.figma.com/blog/how-we-built-the-figma-plugin-system/\n */\nexport interface VmPropertyDescriptor<VmHandle> {\n value?: VmHandle\n configurable?: boolean\n enumerable?: boolean\n get?: (this: VmHandle) => VmHandle\n set?: (this: VmHandle, value: VmHandle) => void\n}\n"]}
|
||||
60
Scripts/node_modules/@tootallnate/quickjs-emscripten/package.json
generated
vendored
Normal file
60
Scripts/node_modules/@tootallnate/quickjs-emscripten/package.json
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "@tootallnate/quickjs-emscripten",
|
||||
"version": "0.23.0",
|
||||
"main": "dist/index.js",
|
||||
"sideEffects": false,
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"eval",
|
||||
"quickjs",
|
||||
"vm",
|
||||
"interpreter",
|
||||
"runtime",
|
||||
"safe",
|
||||
"emscripten",
|
||||
"wasm"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/justjake/quickjs-emscripten"
|
||||
},
|
||||
"files": [
|
||||
"c/interface.c",
|
||||
"dist/**/*",
|
||||
"!dist/*.test.js",
|
||||
"!dist/*.tsbuildinfo"
|
||||
],
|
||||
"scripts": {
|
||||
"tarball": "make build/quickjs-emscripten.tgz",
|
||||
"clean": "make clean",
|
||||
"tsc": "node_modules/.bin/tsc",
|
||||
"build": "make dist",
|
||||
"doc": "typedoc",
|
||||
"test": "TS_NODE_TRANSPILE_ONLY=true mocha 'ts/**/*.test.ts'",
|
||||
"test-dist": "cd dist && TS_NODE_TRANSPILE_ONLY=true mocha --require source-map-support/register *.test.js",
|
||||
"test-fast": "TEST_NO_ASYNC=true yarn test 'ts/**/*.test.ts'",
|
||||
"test-all": "TEST_LEAK=1 yarn test && TEST_LEAK=1 yarn test-dist",
|
||||
"prettier": "prettier --write .",
|
||||
"prettier-check": "prettier --check .",
|
||||
"update-quickjs": "git subtree pull --prefix=quickjs --squash git@github.com:bellard/quickjs.git master",
|
||||
"smoketest-node": "yarn tarball && ./scripts/smoketest-node.sh",
|
||||
"smoketest-cra": "yarn tarball && ./scripts/smoketest-website.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/emscripten": "^1.38.0",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^13.1.4",
|
||||
"fs-extra": "^10.0.1",
|
||||
"markserv": "^1.17.4",
|
||||
"mocha": "7.2.0",
|
||||
"node-fetch-commonjs": "^3.1.1",
|
||||
"prettier": "2.8.4",
|
||||
"source-map-support": "^0.5.21",
|
||||
"ts-node": "^10.9.1",
|
||||
"typedoc": "^0.22.0",
|
||||
"typedoc-plugin-inline-sources": "^1.0.1",
|
||||
"typedoc-plugin-markdown": "^3.11.12",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user