quickjs-emscripten
Advanced tools
Comparing version 0.1.0-a to 0.1.0-b
{ | ||
"name": "quickjs-emscripten", | ||
"version": "0.1.0a", | ||
"main": "build/js/ts/quickjs.js", | ||
"version": "0.1.0b", | ||
"main": "dist/quickjs.js", | ||
"license": "MIT", | ||
@@ -11,17 +11,16 @@ "repository": { | ||
"files": [ | ||
"./build/js/build/**/*", | ||
"./build/js/ts/**/*", | ||
"./build/wrapper/wasm/*.js" | ||
"./dist/*.js", | ||
"./dist/*.ts", | ||
"./dist/*.map" | ||
], | ||
"scripts": { | ||
"prepare": "yarn make-release && yarn build && mocha ./build/js/ts/quickjs.test.js", | ||
"prepare": "yarn make-release && yarn build && mocha ./dist/quickjs.test.js", | ||
"update-quickjs": "git subtree pull --prefix=quickjs --squash git@github.com:ldarren/QuickJS.git mod", | ||
"make-debug": "make DEBUG=1 -j 8", | ||
"make-release": "make clean && make -j 8", | ||
"make-release": "which emcc && make clean && make -j 8", | ||
"clean": "make clean", | ||
"build": "tsc", | ||
"test": "mocha", | ||
"watch": "tsc --watch", | ||
"prettier": "prettier --write ./package.json ./**/*.ts", | ||
"run-ts": "yarn make-debug && ts-node -T ./ts/examples/hello.ts", | ||
"doc": "typedoc --plugin typedoc-plugin-markdown ts", | ||
"test": "yarn make-debug && mocha", | ||
"prettier": "prettier --write ./*.json ./**/*.ts ./*.js ./*.md", | ||
"run-n": "yarn make-debug && ./build/wrapper/native/test.exe" | ||
@@ -37,4 +36,6 @@ }, | ||
"ts-node": "^8.5.4", | ||
"typedoc": "^0.15.8", | ||
"typedoc-plugin-markdown": "^2.2.16", | ||
"typescript": "^3.7.4" | ||
} | ||
} |
102
README.md
@@ -14,3 +14,7 @@ # quickjs-emscripten | ||
const result = vm.evalCode(`"Hello " + "world!"`) | ||
const world = vm.createString('world') | ||
vm.setProp(vm.global, 'NAME', world) | ||
world.dispose() | ||
const result = vm.evalCode(`"Hello " + NAME + "!"`) | ||
if (result.error) { | ||
@@ -30,2 +34,47 @@ console.log('Execution failed:', vm.dump(result.error)) | ||
[API Documentation](https://github.com/justjake/quickjs-emscripten/blob/master/doc/globals.md) | [Examples](https://github.com/justjake/quickjs-emscripten/blob/master/ts/quickjs.test.ts) | ||
## 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 Emscripten WASM module is ready. | ||
### Safely evaluate Javascript code | ||
See [QuickJS.evalCode](https://github.com/justjake/quickjs-emscripten/blob/master/doc/classes/quickjs.md#evalcode) | ||
```typescript | ||
import { getQuickJS } from 'quickjs-emscripten' | ||
getQuickJS.then(QuickJS => { | ||
console.log(QuickJS.evalCode('1 + 1')) | ||
}) | ||
``` | ||
_Note: this will not protect you from infinite loops._ | ||
### Interfacing with the interpreter | ||
You can use [QuickJSVm](https://github.com/justjake/quickjs-emscripten/blob/master/doc/classes/quickjsvm.md) | ||
to build a scripting environment by modifying globals and exposing functions | ||
into the QuickJS interpreter. | ||
```typescript | ||
const vm = QuickJS.createVm() | ||
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) | ||
``` | ||
## Background | ||
@@ -37,32 +86,35 @@ | ||
* [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. | ||
- [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 | ||
**Appears to work**, but lacks rigorous tests. Some functionality is excersized | ||
in ts/examples/hello.ts. | ||
**Beta**. There [are tests](https://github.com/justjake/quickjs-emscripten/blob/master/ts/quickjs.test.ts), but I haven't built anything | ||
on top of this. | ||
Open problems: | ||
Ideas for future work: | ||
* Think more about C -> JS function calls. Right now there is a fixed-size | ||
array for these pointers. Maybe we need to manage our own resizable array | ||
inside C code? | ||
* Simplify memory management. Currently the user must call `handle.dispose()` on all handles they | ||
- Simplify memory management. Currently the user must call `handle.dispose()` on all handles they | ||
create to avoid leaking memory in C. | ||
* We chould use a Pool abstraction and do a Pool.freeAll() to free all handles and pointers | ||
- We chould use a Pool abstraction and do a Pool.freeAll() to free all handles and pointers | ||
in the pool. | ||
- Pools, etc, should not pollute QuickJSVm interface. Composition! | ||
- Expose QuickJS interpreter execution hooks to protect against infinite loops. | ||
- Higher-level abstractions for translating values into (and out of) QuickJS. | ||
These should be implemented in a way that works for any `LowLevelJavascriptVm` | ||
implementation. | ||
- Removing the singleton limitations. Each QuickJS class instance could create | ||
its own copy of the emscripten module, although we'd need to make all public | ||
methods async - so they wait for the module instance to be ready. | ||
* Pools, etc, should not pollute QuickJSVm interface. Composition! | ||
## Related | ||
* Duktape wrapped in Wasm: https://github.com/maple3142/duktape-eval/blob/master/src/Makefile | ||
* QuickJS wrapped in C++: https://github.com/ftk/quickjspp | ||
- Duktape wrapped in Wasm: https://github.com/maple3142/duktape-eval/blob/master/src/Makefile | ||
- QuickJS wrapped in C++: https://github.com/ftk/quickjspp | ||
## Developing | ||
This library is implemented in two languages: C and Typescript. | ||
This library is implemented in two languages: C (compiled to WASM with | ||
Emscripten), and Typescript. Emscripten outputs are checked in, so you will | ||
only need the C compiler if you need to modify C code. | ||
@@ -77,3 +129,3 @@ ### The C parts | ||
The C code builds as both with `emscripten` (using `emcc`), to produce WASM (or | ||
ASM.js) and with `clang`. Build outputs end up in ./build/wrapper/{wasm,native}. | ||
ASM.js) and with `clang`. Build outputs are checked in, so | ||
Intermediate object files from QuickJS end up in ./build/quickjs/{wasm,native}. | ||
@@ -86,6 +138,6 @@ | ||
* `yarn update-quickjs` will sync the ./quickjs folder with a | ||
- `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 run-n` builds and runs ./c/test.c | ||
- `yarn make-debug` will rebuild C outputs into ./build/wrapper | ||
- `yarn run-n` builds and runs ./c/test.c | ||
@@ -100,4 +152,4 @@ ### The Typescript parts | ||
* `yarn run-ts` runs an example file | ||
* `yarn build` produces ./build/js | ||
* `yarn watch` will watch ./ts for changes and build into ./build/js | ||
- `yarn build` produces ./dist. | ||
- `yarn test` runs the tests. | ||
- `yarn test --watch` watches for changes and re-runs the tests. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
2
150
0
2
32851
10
3
645