Skip to content

Commit 5ad0278

Browse files
authored
Merge pull request #34 from gahaas/funcref
Make anyfunc an alias of funcref
2 parents 93de45b + eb42622 commit 5ad0278

File tree

8 files changed

+431
-15
lines changed

8 files changed

+431
-15
lines changed

document/js-api/index.bs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,7 @@ The <dfn method for="Memory">type()</dfn> method steps are:
795795
enum TableKind {
796796
"externref",
797797
"anyfunc",
798+
"funcref",
798799
// Note: More values may be added in future iterations,
799800
// e.g., typed function references, typed GC references
800801
};
@@ -848,7 +849,7 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address
848849

849850
The algorithm <dfn abstract-op>ToTableKind</dfn>(|t|) performs the following steps:
850851

851-
1. If |t| equals [=funcref=], return "{{TableKind/anyfunc}}".
852+
1. If |t| equals [=funcref=], return "{{TableKind/funcref}}".
852853
1. If |t| equals [=externref=], return "{{TableKind/externref}}".
853854
1. Assert: This step is not reached.
854855

@@ -950,6 +951,7 @@ enum ValueType {
950951
"f32",
951952
"f64",
952953
"externref",
954+
"funcref",
953955
"anyfunc",
954956
};
955957
</pre>
@@ -1002,6 +1004,7 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
10021004
1. If |s| equals "i64", return [=i64=].
10031005
1. If |s| equals "f32", return [=f32=].
10041006
1. If |s| equals "f64", return [=f64=].
1007+
1. If |s| equals "funcref", return [=funcref=].
10051008
1. If |s| equals "anyfunc", return [=funcref=].
10061009
1. If |s| equals "externref", return [=externref=].
10071010
1. Assert: This step is not reached.
@@ -1015,7 +1018,7 @@ The algorithm <dfn abstract-op>FromValueType</dfn>(|s|) performs the following s
10151018
1. If |s| equals [=i64=], return "{{ValueType/i64}}".
10161019
1. If |s| equals [=f32=], return "{{ValueType/f32}}".
10171020
1. If |s| equals [=f64=], return "{{ValueType/f64}}".
1018-
1. If |s| equals [=funcref=], return "{{ValueType/anyfunc}}".
1021+
1. If |s| equals [=funcref=], return "{{ValueType/funcref}}".
10191022
1. If |s| equals [=externref=], return "{{ValueType/externref}}".
10201023
1. Assert: This step is not reached.
10211024

proposals/js-types/Overview.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ All Wasm types can be defined by a simple grammar. This grammar could be mapped
3232

3333
```TypeScript
3434
type ValueType = "i32" | "i64" | "f32" | "f64"
35-
type ElemType = "anyfunc"
35+
type ElemType = "funcref"
3636
type GlobalType = {value: ValueType, mutable: boolean}
3737
type MemoryType = {limits: Limits}
3838
type TableType = {limits: Limits, element: ElemType}
@@ -200,7 +200,7 @@ function print(...args) {
200200
for (let x of args) console.log(x + "\n")
201201
}
202202

203-
let table = new Table({element: "anyfunc", minimum: 10});
203+
let table = new Table({element: "funcref", minimum: 10});
204204

205205
let print_i32 = new WebAssembly.Function({parameters: ["i32"], results: []}, print);
206206
table.set(0, print_i32);

test/js-api/global/constructor.any.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,15 @@ test(() => {
164164
const global = new WebAssembly.Global(argument, 0, {});
165165
assert_Global(global, 0);
166166
}, "Stray argument");
167+
168+
test(() => {
169+
const argument = { "value": "anyfunc" };
170+
const global = new WebAssembly.Global(argument);
171+
assert_Global(global, null);
172+
}, "funcref with default");
173+
174+
test(() => {
175+
const argument = { "value": "funcref" };
176+
const global = new WebAssembly.Global(argument);
177+
assert_Global(global, null);
178+
}, "funcref with default");

test/js-api/global/type.any.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// META: global=window,dedicatedworker,jsshell
2+
// META: script=/wasm/jsapi/assertions.js
3+
4+
function assert_type(argument) {
5+
const myglobal = new WebAssembly.Global(argument);
6+
const globaltype = myglobal.type();
7+
8+
assert_equals(globaltype.value, argument.value);
9+
assert_equals(globaltype.mutable, argument.mutable);
10+
}
11+
12+
test(() => {
13+
assert_type({ "value": "i32", "mutable": true});
14+
}, "i32, mutable");
15+
16+
test(() => {
17+
assert_type({ "value": "i32", "mutable": false});
18+
}, "i32, immutable");
19+
20+
test(() => {
21+
assert_type({ "value": "i64", "mutable": true});
22+
}, "i64, mutable");
23+
24+
test(() => {
25+
assert_type({ "value": "i64", "mutable": false});
26+
}, "i64, immutable");
27+
28+
test(() => {
29+
assert_type({ "value": "f32", "mutable": true});
30+
}, "f32, mutable");
31+
32+
test(() => {
33+
assert_type({ "value": "f32", "mutable": false});
34+
}, "f32, immutable");
35+
36+
test(() => {
37+
assert_type({ "value": "f64", "mutable": true});
38+
}, "f64, mutable");
39+
40+
test(() => {
41+
assert_type({ "value": "f64", "mutable": false});
42+
}, "f64, immutable");
43+
44+
test(() => {
45+
assert_type({"value": "externref", "mutable": true})
46+
}, "externref, mutable")
47+
48+
test(() => {
49+
assert_type({"value": "externref", "mutable": false})
50+
}, "externref, immutable")
51+
52+
test(() => {
53+
const argument = {"value": "anyfunc", "mutable": true};
54+
const myglobal = new WebAssembly.Global(argument);
55+
const globaltype = myglobal.type();
56+
57+
assert_equals(globaltype.value, "funcref");
58+
assert_equals(globaltype.mutable, argument.mutable);
59+
}, "anyfunc, mutable")
60+
61+
test(() => {
62+
const argument = {"value": "anyfunc", "mutable": false};
63+
const myglobal = new WebAssembly.Global(argument);
64+
const globaltype = myglobal.type();
65+
66+
assert_equals(globaltype.value, "funcref");
67+
assert_equals(globaltype.mutable, argument.mutable);
68+
}, "anyfunc, immutable")
69+
70+
test(() => {
71+
assert_type({"value": "funcref", "mutable": true})
72+
}, "funcref, mutable")
73+
74+
test(() => {
75+
assert_type({"value": "funcref", "mutable": false})
76+
}, "funcref, immutable")
77+
78+
test(() => {
79+
const myglobal = new WebAssembly.Global({"value": "i32", "mutable": true});
80+
const propertyNames = Object.getOwnPropertyNames(myglobal.type());
81+
assert_equals(propertyNames[0], "mutable");
82+
assert_equals(propertyNames[1], "value");
83+
}, "key ordering");

test/js-api/module/exports.any.js

Lines changed: 137 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,35 @@ function assert_ModuleExportDescriptor(export_, expected) {
2121
assert_true(kind.enumerable, "kind: enumerable");
2222
assert_true(kind.configurable, "kind: configurable");
2323
assert_equals(kind.value, expected.kind);
24+
25+
if (expected.type) {
26+
const type = Object.getOwnPropertyDescriptor(export_, 'type');
27+
assert_true(type.writable, 'type: writable');
28+
assert_true(type.enumerable, 'type: enumerable');
29+
assert_true(type.configurable, 'type: configurable');
30+
31+
if (expected.type.parameters !== undefined) {
32+
assert_array_equals(type.value.parameters, expected.type.parameters);
33+
}
34+
if (expected.type.results !== undefined) {
35+
assert_array_equals(type.value.results, expected.type.results);
36+
}
37+
if (expected.type.value !== undefined) {
38+
assert_equals(type.value.value, expected.type.value);
39+
}
40+
if (expected.type.mutable !== undefined) {
41+
assert_equals(type.value.mutable, expected.type.mutable);
42+
}
43+
if (expected.type.mimimum !== undefined) {
44+
assert_equals(type.value.mimimum, expected.type.mimimum);
45+
}
46+
if (expected.type.maximum !== undefined) {
47+
assert_equals(type.value.maximum, expected.type.maximum);
48+
}
49+
if (expected.type.element !== undefined) {
50+
assert_equals(type.value.element, expected.type.element);
51+
}
52+
}
2453
}
2554

2655
function assert_exports(exports, expected) {
@@ -75,6 +104,12 @@ test(() => {
75104
}
76105
}, "Branding");
77106

107+
test(() => {
108+
const module = new WebAssembly.Module(emptyModuleBinary);
109+
const exports = WebAssembly.Module.exports(module);
110+
assert_true(Array.isArray(exports));
111+
}, "Return type");
112+
78113
test(() => {
79114
const module = new WebAssembly.Module(emptyModuleBinary);
80115
const exports = WebAssembly.Module.exports(module);
@@ -83,7 +118,8 @@ test(() => {
83118

84119
test(() => {
85120
const module = new WebAssembly.Module(emptyModuleBinary);
86-
assert_not_equals(WebAssembly.Module.exports(module), WebAssembly.Module.exports(module));
121+
assert_not_equals(
122+
WebAssembly.Module.exports(module), WebAssembly.Module.exports(module));
87123
}, "Empty module: array caching");
88124

89125
test(() => {
@@ -114,18 +150,112 @@ test(() => {
114150
const module = new WebAssembly.Module(buffer);
115151
const exports = WebAssembly.Module.exports(module);
116152
const expected = [
117-
{ "kind": "function", "name": "fn" },
118-
{ "kind": "function", "name": "fn2" },
119-
{ "kind": "table", "name": "table" },
120-
{ "kind": "global", "name": "global" },
121-
{ "kind": "global", "name": "global2" },
122-
{ "kind": "memory", "name": "memory" },
153+
{
154+
'kind': 'function',
155+
'name': 'fn',
156+
'type': {'parameters': [], 'results': []}
157+
},
158+
{
159+
'kind': 'function',
160+
'name': 'fn2',
161+
'type': {'parameters': [], 'results': []}
162+
},
163+
{'kind': 'table', 'name': 'table'},
164+
{'kind': 'global', 'name': 'global'},
165+
{'kind': 'global', 'name': 'global2'},
166+
{'kind': 'memory', 'name': 'memory'},
123167
];
124168
assert_exports(exports, expected);
125169
}, "exports");
126170

171+
test(() => {
172+
const builder = new WasmModuleBuilder();
173+
174+
builder
175+
.addFunction("", kSig_v_v)
176+
.addBody([])
177+
.exportFunc();
178+
179+
const buffer = builder.toBuffer()
180+
const module = new WebAssembly.Module(buffer);
181+
const exports = WebAssembly.Module.exports(module);
182+
const expected = [
183+
{'kind': 'function', 'name': '', 'type': {'parameters': [], 'results': []}},
184+
];
185+
assert_exports(exports, expected);
186+
}, "exports with empty name: function");
187+
188+
test(() => {
189+
const builder = new WasmModuleBuilder();
190+
191+
builder.setTableBounds(1);
192+
builder.addExportOfKind("", kExternalTable, 0);
193+
194+
const buffer = builder.toBuffer()
195+
const module = new WebAssembly.Module(buffer);
196+
const exports = WebAssembly.Module.exports(module);
197+
const expected = [
198+
{ "kind": "table", "name": "" },
199+
];
200+
assert_exports(exports, expected);
201+
}, "exports with empty name: table");
202+
203+
test(() => {
204+
const builder = new WasmModuleBuilder();
205+
206+
builder.addGlobal(kWasmI32, true)
207+
.exportAs("")
208+
.init = 7;
209+
210+
const buffer = builder.toBuffer()
211+
const module = new WebAssembly.Module(buffer);
212+
const exports = WebAssembly.Module.exports(module);
213+
const expected = [
214+
{ "kind": "global", "name": "" },
215+
];
216+
assert_exports(exports, expected);
217+
}, "exports with empty name: global");
218+
127219
test(() => {
128220
const module = new WebAssembly.Module(emptyModuleBinary);
129221
const exports = WebAssembly.Module.exports(module, {});
130222
assert_exports(exports, []);
131223
}, "Stray argument");
224+
225+
test(() => {
226+
const builder = new WasmModuleBuilder();
227+
228+
builder
229+
.addFunction("fn", kSig_a_a)
230+
.addBody([kExprLocalGet, 0])
231+
.exportFunc();
232+
233+
builder.addTable(kWasmAnyFunc, 10, 100);
234+
builder.addExportOfKind("table", kExternalTable, 0);
235+
236+
builder.addGlobal(kWasmAnyFunc, true)
237+
.exportAs("global").function_index = 0;
238+
239+
const buffer = builder.toBuffer();
240+
const module = new WebAssembly.Module(buffer);
241+
const exports = WebAssembly.Module.exports(module);
242+
const expected = [
243+
{
244+
'kind': 'function',
245+
'name': 'fn',
246+
'type': {'parameters': ['funcref'], 'results': ['funcref']}
247+
},
248+
{
249+
'kind': 'table',
250+
'name': 'table',
251+
'type': {'minimum': 10, 'maximum': 100, 'element': 'funcref'}
252+
},
253+
{
254+
'kind': 'global',
255+
'name': 'global',
256+
'type': {'value': 'funcref', 'mutable': true}
257+
},
258+
];
259+
assert_exports(exports, expected);
260+
}, "exports with type funcref");
261+

0 commit comments

Comments
 (0)