Skip to content

Commit c2ee698

Browse files
[skip ci] Document the reason of dirty workaround
1 parent d5eb64f commit c2ee698

File tree

1 file changed

+23
-3
lines changed
  • packages/npm-packages/ruby-wasm-wasi/src

1 file changed

+23
-3
lines changed

packages/npm-packages/ruby-wasm-wasi/src/index.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export class RubyVM {
9797
return value.toString();
9898
},
9999
takeJsValue: (value) => {
100+
// See `JsValueExporter` for the reason why we need to do this
100101
this.exporter.takeJsValue(value);
101102
},
102103
instanceOf: (value, klass) => {
@@ -175,12 +176,32 @@ export class RubyVM {
175176
}
176177
}
177178

179+
/**
180+
* Export a JS value held by the Ruby VM to the JS environment.
181+
* This is implemented in a dirty way since wit cannot reference resources
182+
* defined in other interfaces.
183+
* In our case, we can't express `function(v: rb-abi-value) -> js-abi-value`
184+
* because `rb-js-abi-host.wit`, that defines `js-abi-value`, is implemented
185+
* by embedder side (JS) but `rb-abi-guest.wit`, that defines `rb-abi-value`
186+
* is implemented by guest side (Wasm).
187+
*
188+
* This class is a helper to export by:
189+
* 1. Call `function __export_to_js(v: rb-abi-value)` defined in guest from embedder side.
190+
* 2. Call `function takeJsValue(v: js-abi-value)` defined in embedder from guest side with
191+
* underlying JS value of given `rb-abi-value`.
192+
* 3. Then `takeJsValue` implementation escapes the given JS value to the `_takenJsValues`
193+
* stored in embedder side.
194+
* 4. Finally, embedder side can take `_takenJsValues`.
195+
*
196+
* Note that `exportJsValue` is not reentrant.
197+
*/
178198
class JsValueExporter {
179199
private _takenJsValues: JsAbiValue = null;
180200
takeJsValue(value: JsAbiValue) {
181201
this._takenJsValues = value;
182202
}
183-
exportJsValue(): JsAbiValue {
203+
exportJsValue(value: RbValue): JsAbiValue {
204+
value.call("__export_to_js");
184205
return this._takenJsValues;
185206
}
186207
}
@@ -254,8 +275,7 @@ export class RbValue {
254275
if (jsValue.call("nil?").toString() === "true") {
255276
return null;
256277
}
257-
jsValue.call("__export_to_js");
258-
return this.privateObject.exporter.exportJsValue();
278+
return this.privateObject.exporter.exportJsValue(jsValue);
259279
}
260280
}
261281

0 commit comments

Comments
 (0)