SlideShare une entreprise Scribd logo
1  sur  88
Télécharger pour lire hors ligne
Running JS via Wasm Faster
with JIT
Dmitry Bezhetskov
Wasm I/O 2024
JS is getting popular
The State of WebAssembly 2021 - 2023
How to run JS inside Wasm?
● Mozilla SpiderMonkey
● QuickJS
SpiderMonkey
- Size 5Mb
- Support only interpreter mode
+ Good support of JS standard and actively developed
credit: @b_atchison98
QuickJS
+ Size 800Kb
- Support only interpreter mode
- Less support of JS standard
+ Fast interpreter and preprocessing support
credit: @sanghoon71
JavaScript Interpreter
● Slow math
● Overhead on dispatch
● No specialization
● No optimizations
Wishful thinking
+ Better than interpreter throughput
+ Industrial support of new features of JS
+ Reasonable size
+ Preprocessing and/or AOT support
JIT support for JS with
Wasm
The plan
The plan
X64
ARM64
Loongson
Risc-V
The plan
X64
ARM64
Loongson
Risc-V
Wasm
credit: @franku84
SpiderMonkey + Wasm backend
+ Industrial support of JS
+ Interpreter for cold code
+ JIT for hot code
- Size 5mb
+ … more in the last section
How can we add Wasm as a
backend?
SpiderMonkey interface for backend
Bytecode
SpiderMonkey interface for backend
Bytecode
C++
Interpreter
SpiderMonkey interface for backend
Bytecode
C++
Interpreter
BaselineInterpreter
BaselineJIT
Ion
Warp
SpiderMonkey interface for backend
Bytecode
C++
Interpreter
BaselineInterpreter
BaselineJIT
Ion
Warp
Masm
Masm Wasm
Registers
Masm
Locals & Globals
Wasm
Registers
Masm
Locals & Globals
Wasm
Direct stack
access
Own restricted
stack
Registers
Masm
Locals & Globals
Wasm
Direct stack
access
Own restricted
stack
Add32, Mul32, … Add32, Mul32, …
Registers
Masm
Locals & Globals
Wasm
Direct stack
access
Own restricted
stack
Add32, Mul32, … Add32, Mul32, …
Jumps addr &
Labels
Structured control
flow & blocks
Control flow
Control flow
Control flow
…
load script into scratch
compare scratch against 0
fail push 0
…
load script into scratch
compare scratch against 0
fail
push 0
…
load script into scratch
compare scratch against 0
fail
push 0
Control flow resume
1. Control flow obtained from Masm is structured
2. Using classic compilers algorithms for layouting CFG with loops
Registers
function foo() {...}
JS
Registers
masm.push(rcx);
masm.push(rax);
masm.push(rdx);
…
MASM
function foo() {...}
JS
Registers
masm.push(rcx);
masm.push(rax);
masm.push(rdx);
…
MASM (func (param $rcx i64)
(param $rax i64)
(param $rdx i64)
local.get 0
local.get 1
local.get 2
…
)
WAT
function foo() {...}
JS
Stack
Local “foo”
Saved FP
Return Address
Arg0
Native stack
Stack
Local “foo”
Saved FP
Return Address
Arg0
Native stack
local 0
I32.const offset
I32.const 4
…
Wasm Stack
Stack
__stack_pointer Local “foo”
Saved FP
Return Address
Arg0
Native stack
local 0
I32.const offset
I32.const 4
…
Wasm Stack
Resume of compilation
1. Recreate CFG from Masm
2. Use the structured property of SpiderMonkey to layout blocks
3. Represent registers as parameters
4. Import __stack_pointer to maintain the same stack structure
Code installation
Code installation
How to use freshly compiled wasm code?
Code installation
How to use freshly compiled wasm code?
Solution:
● wasmtime is able to compile and instantiate new modules at runtime
● we will patch SpiderMonkey memory to “install” code
SpiderMonkey.wasm
source.js
WebAssembly.Memory
SpiderMonkey.wasm
WebAssembly.Table
source.js
WebAssembly.Memory
SpiderMonkey.wasm
WebAssembly.Table
source.js
Do we have compiled
code for source.js?
WebAssembly.Memory
SpiderMonkey.wasm
WebAssembly.Table
source.js
Do we have compiled
code for source.js?
Execute in
Interpreter
N
o
WebAssembly.Memory
SpiderMonkey.wasm
WebAssembly.Table
source.js
Do we have compiled
code for source.js?
Y
e
s
load index $idx
call_indirect $idx
Execute in
Interpreter
N
o
WebAssembly.Memory
SpiderMonkey.wasm
WebAssembly.Table
source.js
Do we have compiled
code for source.js?
Y
e
s
load index $idx
call_indirect $idx
Execute in
Interpreter
N
o
jitcode.wasm
WebAssembly.Memory
SpiderMonkey.wasm
WebAssembly.Table
source.js
Do we have compiled
code for source.js?
Y
e
s
load index $idx
call_indirect $idx
Execute in
Interpreter
N
o
jitcode.wasm
WebAssembly.Memory
SpiderMonkey.wasm
WebAssembly.Table
source.js
Do we have compiled
code for source.js?
Y
e
s
load index $idx
call_indirect $idx
Execute in
Interpreter
N
o
jitcode.wasm
f1
WebAssembly.Memory
SpiderMonkey.wasm
WebAssembly.Table
source.js
Do we have compiled
code for source.js?
Y
e
s
load index $idx
call_indirect $idx
Execute in
Interpreter
N
o
jitcode.wasm
f1
SpiderMonkey.wasm
WebAssembly.Table
source.js
Do we have compiled
code for source.js?
Y
e
s
load index $idx
call_indirect $idx
Execute in
Interpreter
N
o
jitcode.wasm
f1
WebAssembly.Memory
When to call the
compilation?
wasmtime
driver
SpiderMonkey
wasmtime
driver
SpiderMonkey
execute source.js
wasmtime
driver
SpiderMonkey
execute source.js
return result
wasmtime
driver
SpiderMonkey
execute source.js
return result
...
wasmtime
driver
SpiderMonkey
execute source.js
return result
...
compile source.js
wasmtime
driver
SpiderMonkey
execute source.js
return result
...
compile source.js
postpone
compilation
wasmtime
driver
SpiderMonkey
execute source.js
return result
...
compile source.js
postpone
compilation
run all pending compilations
wasmtime
driver
SpiderMonkey
execute source.js
return result
...
compile source.js
postpone
compilation
run all pending compilations
instantiate
bytes
wasmtime
driver
SpiderMonkey
execute source.js
return result
...
compile source.js
postpone
compilation
run all pending compilations
execute source.js
instantiate
bytes
wasmtime
driver
SpiderMonkey
execute source.js
return result
...
compile source.js
postpone
compilation
run all pending compilations
execute source.js
execute jit
version
instantiate
bytes
Results
Performance preliminary: BaselineJIT
Performance preliminary: BaselineJIT
Why we are fast?
● CacheIR support from SpiderMonkey
● Inlining for known targets
Readiness
● Don’t support whole JS, but we pass 83% (9867 out of 11340) of jit-tests
● Working on upstream, see bug 1863986 at bugzilla
How to use all of this?
Three modes of execution
1. Full specialization
2. Sharing scheme
3. Call compilation each time
Full specialization
Full specialization
source.js
Full specialization
source.js test data
Full specialization
source.js test data
specialized
Full specialization
+ No runtime codegen if needed
+ Full power of JIT with Baseline and ICs
+ Full isolation
- Big size ~5Mb
Sharing scheme
Sharing scheme
source.js
Sharing scheme
source.js test data
Sharing scheme
source.js test data
jit_module
wasmtime
driver
wasmtime
driver
execute source.js
wasmtime
driver
execute source.js
instantiate shared
SM
wasmtime
driver
execute source.js
instantiate shared
SM
install
jit_module.wasm
wasmtime
driver
execute source.js
instantiate shared
SM
install
jit_module.wasm
wasmtime
driver
execute source.js
instantiate shared
SM
install
jit_module.wasm
execute source.js
with JIT
Sharing scheme
● SpiderMonkey code is shared
● One instance per client
● jit_module is used to install previously compiled code
Call compilation each time
● Emulation native SpiderMonkey
● Slow, because we don’t batch compilation calls and run compilation at runtime
● Used for tests
Resume
● Implemented new Wasm backend for SpiderMonkey
● Supported ICs and provided promising perf results - from 2x to 11x
● Passed most of the 83% of jit-tests
● Provided interesting modes of execution for embedding or cloud
● Unblocked higher JIT tiers like Warp or Ion
Thanks
● Thanks to all people from Shopify involved for sponsoring this work
○ Special thanks to Mike Shaver and Saúl Cabrera who patiently provides us
feedback for our work
● Thanks to SpiderMonkey team for reviewing our patches
Happy to hear your opinion

Contenu connexe

Similaire à Running JS via WASM faster with JIT

Grabbing the PostgreSQL Elephant by the Trunk
Grabbing the PostgreSQL Elephant by the TrunkGrabbing the PostgreSQL Elephant by the Trunk
Grabbing the PostgreSQL Elephant by the Trunk
Harold Giménez
 
"JIT compiler overview" @ JEEConf 2013, Kiev, Ukraine
"JIT compiler overview" @ JEEConf 2013, Kiev, Ukraine"JIT compiler overview" @ JEEConf 2013, Kiev, Ukraine
"JIT compiler overview" @ JEEConf 2013, Kiev, Ukraine
Vladimir Ivanov
 
Plny12 galera-cluster-best-practices
Plny12 galera-cluster-best-practicesPlny12 galera-cluster-best-practices
Plny12 galera-cluster-best-practices
Dimas Prasetyo
 

Similaire à Running JS via WASM faster with JIT (20)

Browser exploitation SEC-T 2019 stockholm
Browser exploitation SEC-T 2019 stockholmBrowser exploitation SEC-T 2019 stockholm
Browser exploitation SEC-T 2019 stockholm
 
Investigation report on 64 bit support in Android Open Source Project
Investigation report on 64 bit support in Android Open Source ProjectInvestigation report on 64 bit support in Android Open Source Project
Investigation report on 64 bit support in Android Open Source Project
 
Jvm Performance Tunning
Jvm Performance TunningJvm Performance Tunning
Jvm Performance Tunning
 
Jvm Performance Tunning
Jvm Performance TunningJvm Performance Tunning
Jvm Performance Tunning
 
Grabbing the PostgreSQL Elephant by the Trunk
Grabbing the PostgreSQL Elephant by the TrunkGrabbing the PostgreSQL Elephant by the Trunk
Grabbing the PostgreSQL Elephant by the Trunk
 
Advantages of running OpenShift on Power/OpenPOWER systems
Advantages of running OpenShift on Power/OpenPOWER systemsAdvantages of running OpenShift on Power/OpenPOWER systems
Advantages of running OpenShift on Power/OpenPOWER systems
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 
"JIT compiler overview" @ JEEConf 2013, Kiev, Ukraine
"JIT compiler overview" @ JEEConf 2013, Kiev, Ukraine"JIT compiler overview" @ JEEConf 2013, Kiev, Ukraine
"JIT compiler overview" @ JEEConf 2013, Kiev, Ukraine
 
7 jvm-arguments-Confoo
7 jvm-arguments-Confoo7 jvm-arguments-Confoo
7 jvm-arguments-Confoo
 
Persistent Memory Programming with Java*
Persistent Memory Programming with Java*Persistent Memory Programming with Java*
Persistent Memory Programming with Java*
 
How the HotSpot and Graal JVMs execute Java Code
How the HotSpot and Graal JVMs execute Java CodeHow the HotSpot and Graal JVMs execute Java Code
How the HotSpot and Graal JVMs execute Java Code
 
Using GPUs to handle Big Data with Java by Adam Roberts.
Using GPUs to handle Big Data with Java by Adam Roberts.Using GPUs to handle Big Data with Java by Adam Roberts.
Using GPUs to handle Big Data with Java by Adam Roberts.
 
Lonestar php scalingmagento
Lonestar php scalingmagentoLonestar php scalingmagento
Lonestar php scalingmagento
 
Goroutine stack and local variable allocation in Go
Goroutine stack and local variable allocation in GoGoroutine stack and local variable allocation in Go
Goroutine stack and local variable allocation in Go
 
Plny12 galera-cluster-best-practices
Plny12 galera-cluster-best-practicesPlny12 galera-cluster-best-practices
Plny12 galera-cluster-best-practices
 
Dataswft Intel benchmark 2013
Dataswft Intel benchmark 2013Dataswft Intel benchmark 2013
Dataswft Intel benchmark 2013
 
Large Scale Log collection using LogStash & mongoDB
Large Scale Log collection using LogStash & mongoDB Large Scale Log collection using LogStash & mongoDB
Large Scale Log collection using LogStash & mongoDB
 
JerryScript: An ultra-lighteweight JavaScript Engine for the Internet of Things
JerryScript: An ultra-lighteweight JavaScript Engine for the Internet of ThingsJerryScript: An ultra-lighteweight JavaScript Engine for the Internet of Things
JerryScript: An ultra-lighteweight JavaScript Engine for the Internet of Things
 
Enabling Java: Windows on Arm64 - A Success Story!
Enabling Java: Windows on Arm64 - A Success Story!Enabling Java: Windows on Arm64 - A Success Story!
Enabling Java: Windows on Arm64 - A Success Story!
 
Tuning and development with SIP Servlets on Mobicents
Tuning and development with SIP Servlets on MobicentsTuning and development with SIP Servlets on Mobicents
Tuning and development with SIP Servlets on Mobicents
 

Plus de Igalia

Building End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPEBuilding End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPE
Igalia
 
Automated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded DevicesAutomated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded Devices
Igalia
 
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por IgaliaIntroducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Igalia
 

Plus de Igalia (20)

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Building End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPEBuilding End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPE
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Automated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded DevicesAutomated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded Devices
 
Embedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to MaintenanceEmbedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to Maintenance
 
Optimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdfOptimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdf
 
To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!
 
Implementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamerImplementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamer
 
8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in Mesa8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in Mesa
 
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por IgaliaIntroducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
 
2023 in Chimera Linux
2023 in Chimera                    Linux2023 in Chimera                    Linux
2023 in Chimera Linux
 
Building a Linux distro with LLVM
Building a Linux distro        with LLVMBuilding a Linux distro        with LLVM
Building a Linux distro with LLVM
 
turnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUsturnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUs
 
Graphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devicesGraphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devices
 
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOSDelegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
 
MessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the webMessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the web
 
Replacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shadersReplacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shaders
 
I'm not an AMD expert, but...
I'm not an AMD expert, but...I'm not an AMD expert, but...
I'm not an AMD expert, but...
 
Status of Vulkan on Raspberry
Status of Vulkan on RaspberryStatus of Vulkan on Raspberry
Status of Vulkan on Raspberry
 
Enable hardware acceleration for GL applications without glamor on Xorg modes...
Enable hardware acceleration for GL applications without glamor on Xorg modes...Enable hardware acceleration for GL applications without glamor on Xorg modes...
Enable hardware acceleration for GL applications without glamor on Xorg modes...
 

Dernier

Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
FIDO Alliance
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
FIDO Alliance
 

Dernier (20)

WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
 
Using IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandUsing IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & Ireland
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
Your enemies use GenAI too - staying ahead of fraud with Neo4j
Your enemies use GenAI too - staying ahead of fraud with Neo4jYour enemies use GenAI too - staying ahead of fraud with Neo4j
Your enemies use GenAI too - staying ahead of fraud with Neo4j
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - Questionnaire
 
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties ReimaginedEasier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
 

Running JS via WASM faster with JIT