Skip to content

Commit

Permalink
Allow disabling intrinsic language features (like #116) (#136)
Browse files Browse the repository at this point in the history
* define c interface for adding intrinsics

* define enum in js for adding intrinsics

* start passing intrinsics list

* fix oopsies

* treat enum type as number

* switch from array to options object

* regen

* improve docs for Intrinsics, actually export it

* BaseObjects intrinsic was busted

* iterate on tests
  • Loading branch information
justjake authored Jan 1, 2024
1 parent 8016b52 commit df301ef
Show file tree
Hide file tree
Showing 95 changed files with 1,905 additions and 1,045 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## v0.26.0

- [#136](https://github.com/justjake/quickjs-emscripten/pull/136), [#116](https://github.com/justjake/quickjs-emscripten/pull/116) (thanks to @GrantMatejka) Expose ability to configure Context's intrinsic objects.
- [#135](https://github.com/justjake/quickjs-emscripten/pull/135) (thanks to @saghul) Add `quickjs-ng` variants. quickjs-ng is a fork of quickjs under active development. It implements more EcmaScript standards and removes some of quickjs's custom language features like BigFloat.
- [#134](https://github.com/justjake/quickjs-emscripten/pull/134) Support using statement for Disposable. If you `using value = vm.unwrapResult(vm.evalCode("1+1"))`, the value will be automatically disposed when the scope exits.
- [#133](https://github.com/justjake/quickjs-emscripten/pull/133) WebAssembly loading options & Cloudflare Worker support. Added an example of using quickjs-emscripten in a Cloudflare Worker.

## v0.25.1

- [#130](https://github.com/justjake/quickjs-emscripten/pull/129) Fix some README and docs quibbles.
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ main()
- [Packaging](#packaging)
- [Reducing package size](#reducing-package-size)
- [WebAssembly loading](#webassembly-loading)
- [quickjs-ng](#quickjs-ng)
- [Using in the browser without a build step](#using-in-the-browser-without-a-build-step)
- [Debugging](#debugging)
- [Supported Platforms](#supported-platforms)
Expand Down Expand Up @@ -643,6 +644,12 @@ const cloudflareVariant = newVariant(baseVariant, {

[newVariant]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/quickjs-emscripten/interfaces/CustomizeVariantOptions.md

#### quickjs-ng

[quickjs-ng/quickjs](https://github.com/quickjs-ng/quickjs) (aka quickjs-ng) is a fork of the original [bellard/quickjs](https://github.com/quickjs-ng/quickjs) under active development. It implements more EcmaScript standards and removes some of quickjs's custom language features like BigFloat.

There are several variants of quickjs-ng available, and quickjs-emscripten may switch to using quickjs-ng by default in the future. See [the list of variants][core].

#### Using in the browser without a build step

You can use quickjs-emscripten directly from an HTML file in two ways:
Expand Down
86 changes: 84 additions & 2 deletions c/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
#define JSVoid void

#define EvalFlags int
#define IntrinsicsFlags enum QTS_Intrinsic
#define EvalDetectModule int

void qts_log(char *msg) {
Expand Down Expand Up @@ -275,8 +276,89 @@ void QTS_FreeRuntime(JSRuntime *rt) {
JS_FreeRuntime(rt);
}

JSContext *QTS_NewContext(JSRuntime *rt) {
return JS_NewContext(rt);
enum QTS_Intrinsic {
QTS_Intrinsic_BaseObjects = 1 << 0,
QTS_Intrinsic_Date = 1 << 1,
QTS_Intrinsic_Eval = 1 << 2,
QTS_Intrinsic_StringNormalize = 1 << 3,
QTS_Intrinsic_RegExp = 1 << 4,
QTS_Intrinsic_RegExpCompiler = 1 << 5,
QTS_Intrinsic_JSON = 1 << 6,
QTS_Intrinsic_Proxy = 1 << 7,
QTS_Intrinsic_MapSet = 1 << 8,
QTS_Intrinsic_TypedArrays = 1 << 9,
QTS_Intrinsic_Promise = 1 << 10,
QTS_Intrinsic_BigInt = 1 << 11,
QTS_Intrinsic_BigFloat = 1 << 12,
QTS_Intrinsic_BigDecimal = 1 << 13,
QTS_Intrinsic_OperatorOverloading = 1 << 14,
QTS_Intrinsic_BignumExt = 1 << 15,
};

JSContext *QTS_NewContext(JSRuntime *rt, IntrinsicsFlags intrinsics) {
if (intrinsics == 0) {
return JS_NewContext(rt);
}

JSContext *ctx = JS_NewContextRaw(rt);
if (ctx == NULL) {
return NULL;
}

if (intrinsics & QTS_Intrinsic_BaseObjects) {
JS_AddIntrinsicBaseObjects(ctx);
}
if (intrinsics & QTS_Intrinsic_Date) {
JS_AddIntrinsicDate(ctx);
}
if (intrinsics & QTS_Intrinsic_Eval) {
JS_AddIntrinsicEval(ctx);
}
#ifndef QTS_USE_QUICKJS_NG
if (intrinsics & QTS_Intrinsic_StringNormalize) {
JS_AddIntrinsicStringNormalize(ctx);
}
#endif
if (intrinsics & QTS_Intrinsic_RegExp) {
JS_AddIntrinsicRegExp(ctx);
}
if (intrinsics & QTS_Intrinsic_RegExpCompiler) {
JS_AddIntrinsicRegExpCompiler(ctx);
}
if (intrinsics & QTS_Intrinsic_JSON) {
JS_AddIntrinsicJSON(ctx);
}
if (intrinsics & QTS_Intrinsic_Proxy) {
JS_AddIntrinsicProxy(ctx);
}
if (intrinsics & QTS_Intrinsic_MapSet) {
JS_AddIntrinsicMapSet(ctx);
}
if (intrinsics & QTS_Intrinsic_TypedArrays) {
JS_AddIntrinsicTypedArrays(ctx);
}
if (intrinsics & QTS_Intrinsic_Promise) {
JS_AddIntrinsicPromise(ctx);
}
if (intrinsics & QTS_Intrinsic_BigInt) {
JS_AddIntrinsicBigInt(ctx);
}
#ifdef CONFIG_BIGNUM
if (intrinsics & QTS_Intrinsic_BigFloat) {
JS_AddIntrinsicBigFloat(ctx);
}
if (intrinsics & QTS_Intrinsic_BigDecimal) {
JS_AddIntrinsicBigDecimal(ctx);
}
if (intrinsics & QTS_Intrinsic_BignumExt) {
JS_EnableBignumExt(ctx, TRUE);
}
if (intrinsics & QTS_Intrinsic_OperatorOverloading) {
JS_AddIntrinsicOperators(ctx);
}
#endif

return ctx;
}

void QTS_FreeContext(JSContext *ctx) {
Expand Down
99 changes: 89 additions & 10 deletions doc/@jitl/quickjs-ffi-types/exports.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- [QuickJSVariant](exports.md#quickjsvariant)
- [Variables](exports.md#variables)
- [EvalFlags](exports.md#evalflags)
- [IntrinsicsFlags](exports.md#intrinsicsflags)
- [Functions](exports.md#functions)
- [assertSync()](exports.md#assertsync)

Expand Down Expand Up @@ -273,62 +274,140 @@ Bitfield options for JS_Eval() C function.

##### JS\_EVAL\_FLAG\_BACKTRACE\_BARRIER

> **JS\_EVAL\_FLAG\_BACKTRACE\_BARRIER**: `number`
> **`readonly`** **JS\_EVAL\_FLAG\_BACKTRACE\_BARRIER**: `number`
don't include the stack frames before this eval in the Error() backtraces

##### JS\_EVAL\_FLAG\_COMPILE\_ONLY

> **JS\_EVAL\_FLAG\_COMPILE\_ONLY**: `number`
> **`readonly`** **JS\_EVAL\_FLAG\_COMPILE\_ONLY**: `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\_STRICT

> **JS\_EVAL\_FLAG\_STRICT**: `number`
> **`readonly`** **JS\_EVAL\_FLAG\_STRICT**: `number`
force 'strict' mode

##### JS\_EVAL\_FLAG\_STRIP

> **JS\_EVAL\_FLAG\_STRIP**: `number`
> **`readonly`** **JS\_EVAL\_FLAG\_STRIP**: `number`
force 'strip' mode

##### JS\_EVAL\_TYPE\_DIRECT

> **JS\_EVAL\_TYPE\_DIRECT**: `number`
> **`readonly`** **JS\_EVAL\_TYPE\_DIRECT**: `number`
direct call (internal use)

##### JS\_EVAL\_TYPE\_GLOBAL

> **JS\_EVAL\_TYPE\_GLOBAL**: `number`
> **`readonly`** **JS\_EVAL\_TYPE\_GLOBAL**: `number`
global code (default)

##### JS\_EVAL\_TYPE\_INDIRECT

> **JS\_EVAL\_TYPE\_INDIRECT**: `number`
> **`readonly`** **JS\_EVAL\_TYPE\_INDIRECT**: `number`
indirect call (internal use)

##### JS\_EVAL\_TYPE\_MASK

> **JS\_EVAL\_TYPE\_MASK**: `number`
> **`readonly`** **JS\_EVAL\_TYPE\_MASK**: `number`
##### JS\_EVAL\_TYPE\_MODULE

> **JS\_EVAL\_TYPE\_MODULE**: `number`
> **`readonly`** **JS\_EVAL\_TYPE\_MODULE**: `number`
module code

#### Source

[packages/quickjs-ffi-types/src/ffi-types.ts:99](https://github.com/justjake/quickjs-emscripten/blob/main/packages/quickjs-ffi-types/src/ffi-types.ts#L99)

***

### IntrinsicsFlags

> **IntrinsicsFlags**: `Object`
Bitfield options for QTS_NewContext intrinsices

#### Type declaration

##### BaseObjects

> **`readonly`** **BaseObjects**: `number`
##### BigDecimal

> **`readonly`** **BigDecimal**: `number`
##### BigFloat

> **`readonly`** **BigFloat**: `number`
##### BigInt

> **`readonly`** **BigInt**: `number`
##### BignumExt

> **`readonly`** **BignumExt**: `number`
##### Date

> **`readonly`** **Date**: `number`
##### Eval

> **`readonly`** **Eval**: `number`
##### JSON

> **`readonly`** **JSON**: `number`
##### MapSet

> **`readonly`** **MapSet**: `number`
##### OperatorOverloading

> **`readonly`** **OperatorOverloading**: `number`
##### Promise

> **`readonly`** **Promise**: `number`
##### Proxy

> **`readonly`** **Proxy**: `number`
##### RegExp

> **`readonly`** **RegExp**: `number`
##### RegExpCompiler

> **`readonly`** **RegExpCompiler**: `number`
##### StringNormalize

> **`readonly`** **StringNormalize**: `number`
##### TypedArrays

> **`readonly`** **TypedArrays**: `number`
#### Source

[packages/quickjs-ffi-types/src/ffi-types.ts:104](https://github.com/justjake/quickjs-emscripten/blob/main/packages/quickjs-ffi-types/src/ffi-types.ts#L104)

## Functions

### assertSync()
Expand Down Expand Up @@ -360,7 +439,7 @@ module code
#### Source

[packages/quickjs-ffi-types/src/ffi-types.ts:106](https://github.com/justjake/quickjs-emscripten/blob/main/packages/quickjs-ffi-types/src/ffi-types.ts#L106)
[packages/quickjs-ffi-types/src/ffi-types.ts:111](https://github.com/justjake/quickjs-emscripten/blob/main/packages/quickjs-ffi-types/src/ffi-types.ts#L111)

***

Expand Down
Loading

0 comments on commit df301ef

Please sign in to comment.