lightpanda-io / zig-js-runtime Goto Github PK
View Code? Open in Web Editor NEWAdd a JS runtime in your Zig project
Home Page: https://lightpanda.io
License: Apache License 2.0
Add a JS runtime in your Zig project
Home Page: https://lightpanda.io
License: Apache License 2.0
Generate native APIs as Javascript objects and functions available in the context globals.
The default Javascript engine is v8 (Chromium). It's:
But it's also fat (16 Mo added to the binary, at least) and complex.
Supporting other Javascript engine could allow integration in constrained environment (WASM, IoT, embed). And we could also make some performance vs consumption tests with v8.
Candidates are:
Let's say a JS function must accept a variadic arguments of Node
as input, ...nodes
.
We have 2 solutions to handle this on the native API:
[]Node
VariadicNodes
generated through a provided helper function Variadic(comptime T: type) type
The slice solution is easier to use as you don't have to generate the Variadic<Type>
. But it's also less explicit and can lead to some misunderstanding:
[]Node
will be forbidden, which is less obvious than forbid to return a VariadicNode
JS -> Native
Native -> JS
Some complex types:
There is 2 types of JS Array:
Array
which is just an object list of heterogeneous types with some additional methodsTypedArray
subclasses for numerical values (Int<x>Array
, Uint<x>Array
, Float<x>Array
, BigInt<x>Array
and BigUint<x>Array
)It's not easy to translate those to zig native types (eg. slice, tuple) as:
Array
TypedArray
but not all native types have a corresponding JS typed array, eg. we will have to forbid []bool
or []<UserType>
as they don't have a TypedArray
counterpartAs they are JS native types, Array
and TypedArray
exists in the JS engine native API (eg. v8.Array), with all their public properties and methods like Length()
.
So maybe the more logical solution is just to expose those types, ie. define a jsruntime.Array
type that will use underneath v8.Array
(or quickjs.Array
).
Main advantages:
It does not support ECMA402 (Internationalisation APIs).
The idea is to use QuickJS as the default JS engine, at least for the open source version.
We store right now on the reflect structures some fields which are comptime anyway and therefore could be either replace by the builtin function or simple methods, making reflect structures lighter without performance cost.
As tigerbeetle IO loop does not use zig async primitives (no suspend/resume or async/await) we sould be able to use the default self-hosted compiler (stage2).
We "just" need to adapt the lib.
iterable
read-only
etc...
see Object.getOwnPropertyDescriptors(obj)
JS -> Native
Native -> JS
The idea for primitive types to be as natural as possible, ie. translating native primitive types to JS primitive types.
JS primitive types:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#primitive_values
Problem
When returning a user-defined object, a new JS object is always instantiated to hold the corresponding native object.
see. https://github.com/Browsercore/jsruntime-lib/blob/main/src/engines/v8/generate.zig#L291
How to reproduce
Add the following tests in types_native_test.zig
:
car.brand === car.brand
car.brandPtr === car.brandPtr
Actual result
Both tests are false.
Expected result
In my opinion car.brand === car.brand
could be false, as the getter returns a value and not a pointer. I'm open on this.
But car.brandPtr === car.brandPtr
, who returns a pointer, should be true.
We need to handle JS functions prototype, knowing that Zig does not support inheritance and neither embedding struct.
The main goal of Browsercore is too build a small and efficient headless browser.
But, as the project develop, we can see we could built other stuff with it:
To do that we need at least the following:
browsercore-engine
to a dedicated librarySome Web APIs says “This parameter is not optional, but can be set to null”.
jsruntime does not support this for now:
?<Type>
) is translated as an optional parameter<Type>
) a null
value is not allowedThe easiest way to handle that would be to keep ?<Type>
for optional parameter and create custom type for mandatory nullable parameter <NullableType>
, eg. NullableNumber
or NullableNode
.
It’s a bit verbose but we can use a comptime function generator to help with that.
Maybe another solution is possible.
Source : Blog de Mitchell Hashimoto
The main goal of Browsercore is too build a small and efficient headless browser.
But, as the project develop, we can see we could built other stuff with it:
To do that we need at least the following:
https://github.com/mitchellh/libxev
libxev supporte WASI
Since zig-0.11 merge it seems we have a regression on re-allocations
zig-0.10 tag (2023-09-01_23-33_fba2064_main.txt)
+--------------------------------------------------------------------------------------------+
| Benchmark jsengine 🚀 (~= 100 iters) |
+--------------------------------------------------------------------------------------------+
| FUNCTION | DURATION (per iter) | ALLOCATIONS (nb) | RE-ALLOCATIONS (nb) | HEAP SIZE |
+--------------------------------------------------------------------------------------------+
| With Isolate | 619us | 3 | 2 | 72kb |
+--------------------------------------------------------------------------------------------+
| Without Isolate | 259us | 2 | 1 | 24kb |
+--------------------------------------------------------------------------------------------+
zig-0.11 tag
+--------------------------------------------------------------------------------------------+
| Benchmark jsengine 🚀 (~= 100 iters) |
+--------------------------------------------------------------------------------------------+
| FUNCTION | DURATION (per iter) | ALLOCATIONS (nb) | RE-ALLOCATIONS (nb) | HEAP SIZE |
+--------------------------------------------------------------------------------------------+
| With Isolate | 624us | 3 | 1039 | 72kb |
+--------------------------------------------------------------------------------------------+
| Without Isolate | 262us | 2 | 932 | 24kb |
+--------------------------------------------------------------------------------------------+
The default Javascript engine is v8 (Chromium). It's:
But it's also fat (16 Mo added to the binary, at least) and complex.
Supporting other Javascript engine could allow integration in constrained environment (WASM, IoT, embed). And we could also make some performance vs consumption tests with v8.
Candidates are:
jsruntime-lib uses C lib : https://github.com/antirez/linenoise
which can be replaced by the zig port https://github.com/joachimschmidt557/linenoize
Only in public functions/structs
Relates to #56
Should we include i18n support (icu dependancy) ?
Investigate if we can reuse the JS lib for completions from QuickJS
For example in document.createElement()
we can return either any type of HTMLElement
+ HTMLUnknownElement
.
Throw exceptions when the user input is invalid.
For now I close this ticket and create one to investigate custom exceptions types and wrong parameters types.
https://trello.com/c/gE6iL2hz
We can see custom exception types that are not part of v8 API (eg. Uncaught DOMException
: instead of Uncaught xError
).
How can we set thoses?
Right now I can not find any example of generic exception for wrong type arguments (TypeError
?).
For example document.createElement(1)
throws a custom DOMException
with function implementation detail error.
Maybe there is no generic exception for wrong type arguments?
Il faut :
Questions :
La 1ère étape est de s'assurer lors du reflect (comptime) que les types natifs en retour de fonction ont bien été eux-mêmes générés.
Puis à runtime il faut lors de nativeToJS récupérer le template associé au type généré pour pouvoir instancier l'objet en JS.
Il faut notamment vérifier les dépendances:
2 cas à vérifier :
Pour v8 il faut regarder le handle Permanent et son callback optionel SetWeak.
For example Uncaught DOMException
:
Example: window.setTimeout
S’inspirer de ce qui est fait entre C et C++.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.