Class: Dommy::Js::Wasmtime::Engines::Quickjs
- Inherits:
-
Object
- Object
- Dommy::Js::Wasmtime::Engines::Quickjs
- Defined in:
- lib/dommy/js/wasmtime/engines/quickjs.rb
Overview
Real-JS engine backing the wasmtime host’s ‘js.*` bridge.
mruby-in-wasm reaches the host through ~25 ‘js_*` imports that operate on opaque JS handles (js_eval / js_global / js_get / js_set / js_call / js_new / js_make_callback / …). In the browser those go to V8; here they go to a QuickJS VM bound to a Dommy DOM (dommy-js-quickjs’s WasmBridge), so the mruby inner loop runs the same JavaScript a browser would.
One global JS world: QuickJS owns globalThis, Dommy’s window/document are installed into it, and the guest’s ‘JS.global` IS quickjs globalThis — so a fetch stub installed with `engine.eval(“globalThis.fetch = …”)` and the fetch Fetchy calls are the same function (no split brain).
Every JS value crosses as a JsRef implementing the bridge ABI (js_get/js_set/js_call/js_new), so the VM’s duck-typed dispatch drives it unchanged.
Extracted from lilac’s reference host (test/ruby_spec/quickjs_bridge.rb).
Defined Under Namespace
Classes: JsRef
Constant Summary collapse
Instance Attribute Summary collapse
-
#global ⇒ Object
readonly
Returns the value of attribute global.
-
#wb ⇒ Object
readonly
Returns the value of attribute wb.
-
#window ⇒ Object
readonly
Returns the value of attribute window.
Instance Method Summary collapse
- #document ⇒ Object
-
#eval(src) ⇒ Object
Evaluate real JS source (the JS.eval_javascript escape hatch + the bridge’s js_eval import).
-
#initialize(invoke:, window: Dommy.new_window) ⇒ Quickjs
constructor
A new instance of Quickjs.
- #instanceof(value, ctor) ⇒ Object
-
#make_callback(callback_id) ⇒ Object
A JS function that calls back into the guest’s callback table by id.
- #on_log ⇒ Object
-
#run_until_idle ⇒ Object
Drive the event loop to quiescence (WHATWG-ordered): drain microtasks, advance Dommy’s deterministic scheduler to its next timer, repeat.
- #strict_equal(a, b) ⇒ Object
- #to_string(value) ⇒ Object
- #typeof(value) ⇒ Object
-
#unwrap_arg(value) ⇒ Object
Handle value (primitive | JsRef | Array | Hash) -> WasmBridge arg.
-
#wrap_result(value) ⇒ Object
WasmBridge value (primitive | JSValue) -> handle value (primitive | JsRef).
Constructor Details
#initialize(invoke:, window: Dommy.new_window) ⇒ Quickjs
Returns a new instance of Quickjs.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 65 def initialize(invoke:, window: Dommy.new_window) @window = window @runtime = Dommy::Js::Quickjs::Runtime.new @runtime.install_window(@window) @runtime.install_browser_globals @runtime.define_host_object("document", @window.document) @wb = @runtime.wasm_bridge @wb.on_invoke do |callback_id, packed_args| ruby_args = packed_args.map { |pa| wrap_result(@wb.unpack(pa)) } result = invoke.call(callback_id, ruby_args) @wb.pack(unwrap_arg(result)) end @global = wrap_result(@wb.global_ref) end |
Instance Attribute Details
#global ⇒ Object (readonly)
Returns the value of attribute global.
59 60 61 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 59 def global @global end |
#wb ⇒ Object (readonly)
Returns the value of attribute wb.
59 60 61 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 59 def wb @wb end |
#window ⇒ Object (readonly)
Returns the value of attribute window.
59 60 61 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 59 def window @window end |
Instance Method Details
#document ⇒ Object
80 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 80 def document = @window.document |
#eval(src) ⇒ Object
Evaluate real JS source (the JS.eval_javascript escape hatch + the bridge’s js_eval import).
84 85 86 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 84 def eval(src) wrap_result(@wb.eval_js(src)) end |
#instanceof(value, ctor) ⇒ Object
125 126 127 128 129 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 125 def instanceof(value, ctor) return false unless value.is_a?(JsRef) && ctor.is_a?(JsRef) @wb.instance_of?(value.jsvalue, ctor.jsvalue) end |
#make_callback(callback_id) ⇒ Object
A JS function that calls back into the guest’s callback table by id.
89 90 91 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 89 def make_callback(callback_id) wrap_result(@wb.make_callback(callback_id)) end |
#on_log ⇒ Object
99 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 99 def on_log(&) = @runtime.on_log(&) |
#run_until_idle ⇒ Object
Drive the event loop to quiescence (WHATWG-ordered): drain microtasks, advance Dommy’s deterministic scheduler to its next timer, repeat.
95 96 97 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 95 def run_until_idle @runtime.run_until_idle end |
#strict_equal(a, b) ⇒ Object
119 120 121 122 123 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 119 def strict_equal(a, b) return @wb.strict_equal(a.jsvalue, b.jsvalue) if a.is_a?(JsRef) && b.is_a?(JsRef) a == b end |
#to_string(value) ⇒ Object
113 114 115 116 117 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 113 def to_string(value) return @wb.to_string(value.jsvalue) if value.is_a?(JsRef) value.to_s end |
#typeof(value) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 101 def typeof(value) return @wb.typeof(value.jsvalue) if value.is_a?(JsRef) case value when nil then "object" # typeof null === "object" when Integer, Float then "number" when String then "string" when true, false then "boolean" else "object" end end |
#unwrap_arg(value) ⇒ Object
Handle value (primitive | JsRef | Array | Hash) -> WasmBridge arg.
137 138 139 140 141 142 143 144 |
# File 'lib/dommy/js/wasmtime/engines/quickjs.rb', line 137 def unwrap_arg(value) case value when JsRef then value.jsvalue when Array then value.map { |e| unwrap_arg(e) } when Hash then value.transform_values { |e| unwrap_arg(e) } else value end end |