Bug 231114 - [WebAssembly][modules] Importing globals into Wasm from JS doesn't work
Summary: [WebAssembly][modules] Importing globals into Wasm from JS doesn't work
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebAssembly (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-10-01 17:22 PDT by Asumu Takikawa
Modified: 2021-10-22 11:35 PDT (History)
9 users (show)

See Also:


Attachments
Patch (33.48 KB, patch)
2021-10-19 14:05 PDT, Asumu Takikawa
no flags Details | Formatted Diff | Diff
Patch (33.65 KB, patch)
2021-10-21 16:58 PDT, Asumu Takikawa
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Asumu Takikawa 2021-10-01 17:22:51 PDT
Wasm/ES module integration should allow globals and other values to be imported in the JS->Wasm direction, such as in the example below. This is based on this example from the proposal explainer: https://github.com/WebAssembly/esm-integration/blob/main/proposals/esm-integration/EXAMPLES.md#value-imports

Entry script (global.js):

```
import * as assert from '../assert.js';
import {incrementCount} from "./global.wasm";
import {count} from "./global.mjs";

incrementCount();
assert.eq(count.valueOf(), 43);
```

global.mjs:
```
export const count = new WebAssembly.Global({
  value: 'i32',
  mutable: true,
}, 42);

```

global.wat:
```
;; global.wat --> global.wasm
(module
  ;; this import should work normally
  (import "./global.mjs" "count" (global (mut i32)))
  (func (export "incrementCount")
    (global.set 0
      (i32.add
        (global.get 0)
        (i32.const 1))))
)
```

Currently, this doesn't work in JSC and produces a `LinkError` like the following:

```
$ ~/WebKit/WebKitBuild/GTK/Release/bin/jsc -m global.js
Exception: LinkError: imported global ./global.mjs:count must be a WebAssembly.Global object since it is mutable
moduleDeclarationInstantiation@[native code]
link@[native code]
link@[native code]
linkAndEvaluateModule@[native code]
@[native code]
asyncFunctionResume@[native code]
@[native code]
promiseReactionJobWithoutPromise@[native code]
promiseReactionJob@[native code]
```

The issue appears to be that Wasm is fetching the value from JS too early, when it's still `undefined`. JSC's Wasm module records look at the imports in the `link` step of module execution, rather than in the `evaluate` step (as the Wasm/ESM proposal spec says: https://webassembly.github.io/esm-integration/js-api/index.html#module-execution).

I'm working on a draft patch that would move the work in the `link` step into the `evaluate` step. This appears to pass almost all of the current Wasm modules tests (except in one case where I think the test might be wrong). I'll share the patch after writing more tests to check various edge cases. Even with this change, more work is probably needed for `WebAssembly.Memory` to work (because of https://bugs.webkit.org/show_bug.cgi?id=184745).
Comment 1 Radar WebKit Bug Importer 2021-10-08 17:23:21 PDT
<rdar://problem/84050206>
Comment 2 Asumu Takikawa 2021-10-19 14:05:00 PDT
Created attachment 441794 [details]
Patch
Comment 3 Yusuke Suzuki 2021-10-21 09:01:03 PDT
Comment on attachment 441794 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=441794&action=review

r=me

> Source/JavaScriptCore/runtime/AbstractModuleRecord.cpp:840
>          return jsModuleRecord->evaluate(globalObject, sentValue, resumeMode);

Replace it with

RELEASE_AND_RETURN(scope, jsModuleRecord->evaluate(globalObject, sentValue, resumeMode));

since scope is defined now.

> Source/JavaScriptCore/runtime/AbstractModuleRecord.cpp:848
>          return wasmModuleRecord->evaluate(globalObject);

Replace it with

RELEASE_AND_RETURN(scope, wasmModuleRecord->evaluate(globalObject));
Comment 4 Asumu Takikawa 2021-10-21 16:58:24 PDT
Created attachment 442089 [details]
Patch
Comment 5 EWS 2021-10-22 11:35:48 PDT
Committed r284702 (243419@main): <https://commits.webkit.org/243419@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 442089 [details].