Skip to content

Commit 2ec37d4

Browse files
committed
[GR-63376] Implement new Wasm Polyglot API.
PullRequest: graal/20572
2 parents 75b5b6e + b632e46 commit 2ec37d4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1656
-566
lines changed

vm/src/org.graalvm.polybench/src/org/graalvm/polybench/PolyBenchLauncher.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -591,7 +591,7 @@ public void run() {
591591
// language-specific lookup
592592
switch (languageId) {
593593
case "wasm":
594-
result = evalSourceValue.getMember(memberName);
594+
result = evalSourceValue.newInstance().getMember("exports").getMember(memberName);
595595
break;
596596
case "java":
597597
// Espresso doesn't provide methods as executable values.

wasm/CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@ This changelog summarizes major changes to the WebAssembly engine implemented in
44

55
## Version 25.0.0
66

7+
* BREAKING: Changed Context.eval of _wasm_ sources to return a compiled, but not yet instantiated, module object instead of the module instance.
8+
To instantiate the module, you have to call `newInstance()` on the module object now, e.g.:
9+
```java
10+
Context c = Context.create();
11+
Source wasmSource = Source.newBuilder...;
12+
Value module = c.eval(wasmSource);
13+
Value instance = module.newInstance(); // < 25.0: c.eval(wasmSource)
14+
```
15+
This change enables modules to be instantiated multiple times—and run independently—within the same context. Previously, each module could only be instantiated once per context.
16+
`newInstance()` optionally also accepts an import object, similar to the JS WebAssembly API, as well as other modules to be linked together with the module.
17+
The previous behavior can still be restored with the experimental option `--wasm.EvalReturnsInstance=true`.
18+
Note: Modules instantiated using `module.newInstance()` are not accessible via `context.getBindings("wasm")`, unlike modules instantiated using `context.eval` when using `--wasm.EvalReturnsInstance=true`.
19+
* BREAKING: Exports are no longer exposed as direct members of the module instance.
20+
Use the `exports` member of the module instance to access its exports, e.g:.
21+
```java
22+
Value mainFunction = instance.getMember("exports").getMember("main"); // < 25.0: instance.getMember("main")
23+
```
24+
This aligns with the JS WebAssembly API and allows other members to be introduced on the module instance without potential name clashes.
25+
More information about these API changes and examples can be found in the [GraalWasm Polyglot API Migration Guide](docs/user/GraalWasmAPIMigration.md) and the [Readme](docs/user/README.md).
726
* Implemented support for editing primitive values during debugging. Fixed several debugger-related issues.
827

928
## Version 24.2.0

wasm/docs/site/Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
source "https://rubygems.org"
22

3-
gem "jekyll", "~> 4.3.4"
3+
gem "jekyll", "~> 4.4.0"
44

55
gem "graal-languages-jekyll-theme"
66

wasm/docs/site/Gemfile.lock

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ GEM
1111
io-event (~> 1.9)
1212
metrics (~> 0.12)
1313
traces (~> 0.15)
14+
base64 (0.3.0)
1415
bigdecimal (3.1.8)
1516
coderay (1.1.3)
1617
colorator (1.1.0)
17-
concurrent-ruby (1.3.4)
18+
concurrent-ruby (1.3.5)
1819
console (1.29.3)
1920
fiber-annotation
2021
fiber-local (~> 1.1)
@@ -26,17 +27,16 @@ GEM
2627
ethon (0.16.0)
2728
ffi (>= 1.15.0)
2829
eventmachine (1.2.7)
29-
ffi (1.17.0-arm64-darwin)
30-
ffi (1.17.0-x86_64-linux-gnu)
30+
ffi (1.17.0)
3131
fiber-annotation (0.2.0)
3232
fiber-local (1.1.0)
3333
fiber-storage
3434
fiber-storage (1.0.0)
3535
forwardable-extended (2.6.0)
36-
google-protobuf (4.28.3-arm64-darwin)
36+
google-protobuf (4.31.1-arm64-darwin)
3737
bigdecimal
3838
rake (>= 13)
39-
google-protobuf (4.28.3-x86_64-linux)
39+
google-protobuf (4.31.1-x86_64-linux-gnu)
4040
bigdecimal
4141
rake (>= 13)
4242
graal-languages-jekyll-theme (0.1.0)
@@ -56,36 +56,39 @@ GEM
5656
csv
5757
mini_mime (>= 1.0.0)
5858
multi_xml (>= 0.5.2)
59-
i18n (1.14.6)
59+
i18n (1.14.7)
6060
concurrent-ruby (~> 1.0)
6161
io-event (1.9.0)
62-
jekyll (4.3.4)
62+
jekyll (4.4.1)
6363
addressable (~> 2.4)
64+
base64 (~> 0.2)
6465
colorator (~> 1.0)
66+
csv (~> 3.0)
6567
em-websocket (~> 0.5)
6668
i18n (~> 1.0)
6769
jekyll-sass-converter (>= 2.0, < 4.0)
6870
jekyll-watch (~> 2.0)
71+
json (~> 2.6)
6972
kramdown (~> 2.3, >= 2.3.1)
7073
kramdown-parser-gfm (~> 1.0)
7174
liquid (~> 4.0)
72-
mercenary (>= 0.3.6, < 0.5)
75+
mercenary (~> 0.3, >= 0.3.6)
7376
pathutil (~> 0.9)
7477
rouge (>= 3.0, < 5.0)
7578
safe_yaml (~> 1.0)
7679
terminal-table (>= 1.8, < 4.0)
7780
webrick (~> 1.7)
7881
jekyll-relative-links (0.7.0)
7982
jekyll (>= 3.3, < 5.0)
80-
jekyll-sass-converter (3.0.0)
81-
sass-embedded (~> 1.54)
83+
jekyll-sass-converter (3.1.0)
84+
sass-embedded (~> 1.75)
8285
jekyll-seo-tag (2.8.0)
8386
jekyll (>= 3.8, < 5.0)
8487
jekyll-watch (2.2.1)
8588
listen (~> 3.0)
8689
json (2.10.1)
87-
kramdown (2.4.0)
88-
rexml
90+
kramdown (2.5.1)
91+
rexml (>= 3.3.9)
8992
kramdown-parser-gfm (1.1.0)
9093
kramdown (~> 2.0)
9194
liquid (4.0.4)
@@ -117,18 +120,18 @@ GEM
117120
racc (1.8.1)
118121
rack (3.1.8)
119122
rainbow (3.1.1)
120-
rake (13.2.1)
123+
rake (13.3.0)
121124
rb-fsevent (0.11.2)
122125
rb-inotify (0.11.1)
123126
ffi (~> 1.0)
124-
rexml (3.3.9)
125-
rouge (4.5.1)
127+
rexml (3.4.1)
128+
rouge (4.5.2)
126129
ruby-rc4 (0.1.5)
127130
safe_yaml (1.0.5)
128-
sass-embedded (1.81.0-arm64-darwin)
129-
google-protobuf (~> 4.28)
130-
sass-embedded (1.81.0-x86_64-linux-gnu)
131-
google-protobuf (~> 4.28)
131+
sass-embedded (1.89.1-arm64-darwin)
132+
google-protobuf (~> 4.31)
133+
sass-embedded (1.89.1-x86_64-linux-gnu)
134+
google-protobuf (~> 4.31)
132135
siteleaf (2.3.0)
133136
httparty (>= 0.16.0)
134137
jekyll (>= 1.4.1)
@@ -141,7 +144,7 @@ GEM
141144
typhoeus (1.4.1)
142145
ethon (>= 0.9.0)
143146
unicode-display_width (2.6.0)
144-
webrick (1.9.0)
147+
webrick (1.9.1)
145148
yell (2.2.2)
146149
zeitwerk (2.7.2)
147150

@@ -153,7 +156,7 @@ DEPENDENCIES
153156
graal-languages-jekyll-theme
154157
html-proofer
155158
http_parser.rb (~> 0.6.0)
156-
jekyll (~> 4.3.4)
159+
jekyll (~> 4.4.0)
157160
jekyll-relative-links
158161
jekyll-seo-tag
159162
pry

wasm/docs/site/_plugins/wat_lexer.rb

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2+
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
3+
4+
require 'rouge'
5+
6+
# overly simplistic wat lexer
7+
module Rouge
8+
module Lexers
9+
class Wat < RegexLexer
10+
tag 'wat'
11+
filenames '*.wat'
12+
title "wat"
13+
desc "WebAssembly Text Format"
14+
15+
state :root do
16+
rule %r/;;.*$/, Comment::Single
17+
rule %r/\(;.*?;\)/m, Comment::Multiline
18+
19+
# literals
20+
rule %r/"([^\\"]|\\.)*?"/, Str
21+
rule %r/[-+]?(?:\d+|0x[0-9a-fA-F]+)/, Num::Integer
22+
rule %r/[-+]?\d+\.\d+(?:[eE][-+]?\d+)?/, Num::Float
23+
24+
# keywords
25+
rule %r/\b(
26+
module|func|type|param|result|local|global|memory|data|table|elem|start|import|export|mut
27+
)(?!\.)\b/x, Keyword
28+
29+
# types
30+
rule %r/\b(
31+
i32|i64|f32|f64|v128|funcref|externref
32+
)(?!\.)\b/x, Keyword::Type
33+
34+
# instructions
35+
rule %r/\b(
36+
local\.(?:get|set|tee)|
37+
global\.(?:get|set)|
38+
(?:i32|i64|f32|f64|v128|i8x16|i16x8|i32x4|i64x2|f32x4|f64x2)\.[a-z0-9_]+|
39+
nop|unreachable|
40+
block|loop|if|else|end|
41+
br|br_if|br_table|
42+
return|
43+
call|call_indirect|
44+
drop|select|
45+
table\.(?:get|set|size|grow|fill|copy|init)|
46+
elem\.drop|
47+
memory\.(?:size|grow|fill|copy|init)
48+
data\.drop|
49+
ref\.(?:null|is_null|func)
50+
)(?!\.)\b/x, Name::Attribute
51+
52+
# names
53+
rule %r/\$[a-zA-Z0-9._-]*/, Name::Builtin
54+
55+
# attributes
56+
rule %r/(?:offset|align)=/, Name::Property
57+
58+
rule %r/[()]/, Punctuation
59+
60+
rule %r/\s+/, Text
61+
end
62+
end
63+
end
64+
end

wasm/docs/site/index.md

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,15 @@ implementation("org.graalvm.polyglot:wasm:{{ site.language_version }}")
150150
<div class="language__example-subtitle">
151151
<h4>2. Create a WebAssembly module, for example with <a href="https://webassembly.github.io/wabt/demo/wat2wasm/" target="_blank">wat2wasm</a></h4>
152152
</div>
153-
{%- highlight javascript -%}
154-
(module
155-
(func (export "addTwo") (param i32 i32) (result i32)
156-
local.get 0
157-
local.get 1
158-
i32.add))
153+
{%- highlight wat -%}
154+
;; wat2wasm add-two.wat -o add-two.wasm
155+
(module
156+
(func (export "addTwo") (param i32 i32) (result i32)
157+
local.get 0
158+
local.get 1
159+
i32.add
160+
)
161+
)
159162
{%- endhighlight -%}
160163
</div>
161164
<div class="example-logo-box">
@@ -167,10 +170,34 @@ implementation("org.graalvm.polyglot:wasm:{{ site.language_version }}")
167170
</div>
168171
<div class="languages__example-box">
169172
<div class="languages__snippet">
170-
<div class="language__example-subtitle">
171-
<h4>3. Embed the Wasm module in Java</h4>
172-
</div>
173-
{%- highlight java -%}
173+
<div class="language__example-subtitle">
174+
<h4>3. Embed the Wasm module in Java</h4>
175+
</div>
176+
<div class="tabs-container">
177+
<ul class="nav nav-tabs">
178+
<li><a href="#" data-bs-toggle="tab" data-bs-target="#version25" class="nav-link active">≥ 25.0</a></li>
179+
<li><a href="#" data-bs-toggle="tab" data-bs-target="#version24" class="nav-link">≤ 24.2</a></li>
180+
</ul>
181+
<div class="tab-content">
182+
<div id="version25" class="tab-pane fade show active">
183+
{% highlight java %}
184+
import java.net.URL;
185+
186+
import org.graalvm.polyglot.Context;
187+
import org.graalvm.polyglot.Source;
188+
import org.graalvm.polyglot.Value;
189+
190+
try (Context context = Context.create()) {
191+
URL wasmFile = Main.class.getResource("add-two.wasm");
192+
Value mainModule = context.eval(Source.newBuilder("wasm", wasmFile).build());
193+
Value mainInstance = mainModule.newInstance();
194+
Value addTwo = mainInstance.getMember("exports").getMember("addTwo");
195+
System.out.println("addTwo(40, 2) = " + addTwo.execute(40, 2));
196+
}
197+
{% endhighlight %}
198+
</div>
199+
<div id="version24" class="tab-pane fade">
200+
{% highlight java %}
174201
import java.net.URL;
175202

176203
import org.graalvm.polyglot.Context;
@@ -184,8 +211,11 @@ try (Context context = Context.create()) {
184211
Value addTwo = context.getBindings("wasm").getMember(moduleName).getMember("addTwo");
185212
System.out.println("addTwo(40, 2) = " + addTwo.execute(40, 2));
186213
}
187-
{%- endhighlight -%}
188-
</div>
214+
{% endhighlight %}
215+
</div>
216+
</div>
217+
</div>
218+
</div><!-- languages__snippet -->
189219
<div class="example-logo-box">
190220
<img alt="Java icon" src='{{ "/assets/img/logos/java-logo.svg" | relative_url }}' class="languages__example-logo">
191221
</div>

0 commit comments

Comments
 (0)