Skip to content

Commit ed90add

Browse files
authored
Merge pull request #108 from WebAssembly/param-name
Remove unnamed function parameter case
2 parents 3ee3b98 + 9bea0ad commit ed90add

File tree

6 files changed

+66
-61
lines changed

6 files changed

+66
-61
lines changed

design/mvp/Binary.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,10 @@ casetype ::= 0x00 =>
183183
| 0x01 t:<valtype> => t
184184
valtype ::= i:<typeidx> => i
185185
| pvt:<primvaltype> => pvt
186-
functype ::= 0x40 p*:<funcvec> r*:<funcvec> => (func (param p)* (result r)*)
187-
funcvec ::= 0x00 t:<valtype> => [t]
188-
| 0x01 nt*:vec(<namedvaltype>) => nt*
186+
functype ::= 0x40 ps:<paramlist> rs:<resultlist> => (func ps rs)
187+
paramlist ::= nt*:vec(<namedvaltype>) => (param nt)*
188+
resultlist ::= 0x00 t:<valtype> => (result t)
189+
| 0x01 nt*:vec(<namedvaltype>) => (result nt)*
189190
componenttype ::= 0x41 cd*:vec(<componentdecl>) => (component cd*)
190191
instancetype ::= 0x42 id*:vec(<instancedecl>) => (instance id*)
191192
componentdecl ::= 0x03 id:<importdecl> => id

design/mvp/CanonicalABI.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,27 +1461,28 @@ the Canonical ABI.
14611461

14621462
#### Function type mangling
14631463

1464-
Function types are mangled into
1465-
[`wit`](WIT.md)-compatible syntax:
1464+
Function types are mangled into [`wit`](WIT.md)-compatible syntax:
14661465
```python
14671466
def mangle_funcname(name, ft):
1468-
return '{name}: func{params} -> {results}'.format(
1469-
name = name,
1470-
params = mangle_funcvec(ft.params, pre_space = False),
1471-
results = mangle_funcvec(ft.results, pre_space = True))
1472-
1473-
def mangle_funcvec(es, pre_space):
1474-
if len(es) == 1 and isinstance(es[0], ValType):
1475-
return (' ' if not pre_space else '') + mangle_valtype(es[0])
1476-
assert(all(type(e) == tuple and len(e) == 2 for e in es))
1477-
mangled_elems = (e[0] + ': ' + mangle_valtype(e[1]) for e in es)
1467+
params = mangle_named_types(ft.params)
1468+
if len(ft.results) == 1 and isinstance(ft.results[0], ValType):
1469+
results = mangle_valtype(ft.results[0])
1470+
else:
1471+
results = mangle_named_types(ft.results)
1472+
return f'{name}: func{params} -> {results}'
1473+
1474+
def mangle_named_types(nts):
1475+
assert(all(type(nt) == tuple and len(nt) == 2 for nt in nts))
1476+
mangled_elems = (nt[0] + ': ' + mangle_valtype(nt[1]) for nt in nts)
14781477
return '(' + ', '.join(mangled_elems) + ')'
1478+
```
14791479

14801480
#### Value type mangling
14811481

14821482
Value types are similarly mangled into [`wit`](WIT.md)-compatible syntax,
14831483
recursively:
14841484

1485+
```
14851486
def mangle_valtype(t):
14861487
match t:
14871488
case Bool() : return 'bool'
@@ -1548,7 +1549,7 @@ As an example, given a component type:
15481549
(export "bar" (func (param "x" u32) (param "y" u32) (result u32)))
15491550
))
15501551
(import "v1" (value string))
1551-
(export "baz" (func (param string) (result string)))
1552+
(export "baz" (func (param "s" string) (result string)))
15521553
(export "v2" (value list<list<string>>))
15531554
)
15541555
```
@@ -1560,7 +1561,7 @@ the `canonical_module_type` would be:
15601561
(export "cabi_memory" (memory 0))
15611562
(export "cabi_realloc" (func (param i32 i32 i32 i32) (result i32)))
15621563
(export "cabi_start{cabi=0.1}: func(v1: string) -> (v2: list<list<string>>)" (func (param i32 i32) (result i32)))
1563-
(export "baz: func string -> string" (func (param i32 i32) (result i32)))
1564+
(export "baz: func(s: string) -> string" (func (param i32 i32) (result i32)))
15641565
(export "cabi_post_baz" (func (param i32)))
15651566
)
15661567
```

design/mvp/Explainer.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,6 @@ valtype ::= <typeidx>
456456
| <defvaltype>
457457
functype ::= (func <paramlist> <resultlist>)
458458
paramlist ::= (param <name> <valtype>)*
459-
| (param <valtype>)
460459
resultlist ::= (result <name> <valtype>)*
461460
| (result <valtype>)
462461
componenttype ::= (component <componentdecl>*)
@@ -533,11 +532,11 @@ shared-nothing functions, components and component instances:
533532
The `func` type constructor describes a component-level function definition
534533
that takes and returns a list of `valtype`. In contrast to [`core:functype`],
535534
the parameters and results of `functype` can have associated names which
536-
validation requires to be unique. If a name is not present, the name is taken
537-
to be a special "empty" name and uniqueness still requires there to only be one
538-
unnamed parameter/result. To avoid unnecessary complexity for language binding
539-
generators, parameter and result lists are not allowed to contain both named
540-
and unnamed parameters.
535+
validation requires to be unique. To improve the ergonomics and performance of
536+
the common case of single-value-returning functions, function types may
537+
additionally have a single unnamed return type. For this special case, bindings
538+
generators are naturally encouraged to return the single value directly without
539+
wrapping it in any containing record/object/struct.
541540

542541
The `instance` type constructor describes a list of named, typed definitions
543542
that can be imported or exported by a component. Informally, instance types

design/mvp/WIT.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,17 @@ fibonacci: func(n: u32) -> u32
345345
Specifically functions have the structure:
346346

347347
```wit
348-
func-item ::= id ':' 'func' func-vec '->' func-vec
348+
func-item ::= id ':' 'func' param-list '->' result-list
349349
350-
func-vec ::= ty
351-
| '(' func-named-type-list ')'
350+
param-list ::= '(' named-type-list ')'
352351
353-
func-named-type-list ::= nil
354-
| func-named-type ( ',' func-named-type )*
352+
result-list ::= ty
353+
| '(' named-type-list ')
355354
356-
func-named-type ::= id ':' ty
355+
named-type-list ::= nil
356+
| named-type ( ',' named-type )*
357+
358+
named-type ::= id ':' ty
357359
```
358360

359361
## Item: `resource`

design/mvp/canonical-abi/definitions.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,18 +1106,20 @@ def mangle_instances(xs, path = ''):
11061106
#
11071107

11081108
def mangle_funcname(name, ft):
1109-
return '{name}: func{params} -> {results}'.format(
1110-
name = name,
1111-
params = mangle_funcvec(ft.params, pre_space = False),
1112-
results = mangle_funcvec(ft.results, pre_space = True))
1113-
1114-
def mangle_funcvec(es, pre_space):
1115-
if len(es) == 1 and isinstance(es[0], ValType):
1116-
return (' ' if not pre_space else '') + mangle_valtype(es[0])
1117-
assert(all(type(e) == tuple and len(e) == 2 for e in es))
1118-
mangled_elems = (e[0] + ': ' + mangle_valtype(e[1]) for e in es)
1109+
params = mangle_named_types(ft.params)
1110+
if len(ft.results) == 1 and isinstance(ft.results[0], ValType):
1111+
results = mangle_valtype(ft.results[0])
1112+
else:
1113+
results = mangle_named_types(ft.results)
1114+
return f'{name}: func{params} -> {results}'
1115+
1116+
def mangle_named_types(nts):
1117+
assert(all(type(nt) == tuple and len(nt) == 2 for nt in nts))
1118+
mangled_elems = (nt[0] + ': ' + mangle_valtype(nt[1]) for nt in nts)
11191119
return '(' + ', '.join(mangled_elems) + ')'
11201120

1121+
#
1122+
11211123
def mangle_valtype(t):
11221124
match t:
11231125
case Bool() : return 'bool'

design/mvp/canonical-abi/run_tests.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -381,25 +381,25 @@ def test_mangle_functype(params, results, expect):
381381
if got != expect:
382382
fail("test_mangle_func() got:\n {}\nexpected:\n {}".format(got, expect))
383383

384-
test_mangle_functype([U8()], [U8()], 'func u8 -> u8')
385-
test_mangle_functype([U8()], [], 'func u8 -> ()')
384+
test_mangle_functype([('x',U8())], [U8()], 'func(x: u8) -> u8')
385+
test_mangle_functype([('x',U8())], [], 'func(x: u8) -> ()')
386386
test_mangle_functype([], [U8()], 'func() -> u8')
387387
test_mangle_functype([('x',U8())], [('y',U8())], 'func(x: u8) -> (y: u8)')
388388
test_mangle_functype([('a',Bool()),('b',U8()),('c',S16()),('d',U32()),('e',S64())],
389389
[('a',S8()),('b',U16()),('c',S32()),('d',U64())],
390390
'func(a: bool, b: u8, c: s16, d: u32, e: s64) -> (a: s8, b: u16, c: s32, d: u64)')
391-
test_mangle_functype([List(List(String()))], [],
392-
'func list<list<string>> -> ()')
393-
test_mangle_functype([Record([Field('x',Record([Field('y',String())])),Field('z',U32())])], [],
394-
'func record { x: record { y: string }, z: u32 } -> ()')
395-
test_mangle_functype([Tuple([U8()])], [Tuple([U8(),U8()])],
396-
'func tuple<u8> -> tuple<u8, u8>')
397-
test_mangle_functype([Flags(['a','b'])], [Enum(['a','b'])],
398-
'func flags { a, b } -> enum { a, b }')
399-
test_mangle_functype([Variant([Case('a',None),Case('b',U8())])], [Union([U8(),List(String())])],
400-
'func variant { a, b(u8) } -> union { u8, list<string> }')
401-
test_mangle_functype([Option(Bool())],[Option(List(U8()))],
402-
'func option<bool> -> option<list<u8>>')
391+
test_mangle_functype([('l',List(List(String())))], [],
392+
'func(l: list<list<string>>) -> ()')
393+
test_mangle_functype([('r',Record([Field('x',Record([Field('y',String())])),Field('z',U32())]))], [],
394+
'func(r: record { x: record { y: string }, z: u32 }) -> ()')
395+
test_mangle_functype([('t',Tuple([U8()]))], [Tuple([U8(),U8()])],
396+
'func(t: tuple<u8>) -> tuple<u8, u8>')
397+
test_mangle_functype([('f',Flags(['a','b']))], [Enum(['a','b'])],
398+
'func(f: flags { a, b }) -> enum { a, b }')
399+
test_mangle_functype([('v',Variant([Case('a',None),Case('b',U8())]))], [Union([U8(),List(String())])],
400+
'func(v: variant { a, b(u8) }) -> union { u8, list<string> }')
401+
test_mangle_functype([('o',Option(Bool()))],[Option(List(U8()))],
402+
'func(o: option<bool>) -> option<list<u8>>')
403403
test_mangle_functype([], [('a',Result(None,None)),('b',Result(U8(),None)),('c',Result(None,U8()))],
404404
'func() -> (a: result, b: result<u8>, c: result<_, u8>)')
405405

@@ -410,24 +410,24 @@ def test_cabi(ct, expect):
410410

411411
test_cabi(
412412
ComponentType(
413-
[ExternDecl('a', FuncType([U8()],[U8()])),
413+
[ExternDecl('a', FuncType([('x',U8())],[U8()])),
414414
ExternDecl('b', ValueType(String()))],
415-
[ExternDecl('c', FuncType([S8()],[S8()])),
415+
[ExternDecl('c', FuncType([('x',S8())],[S8()])),
416416
ExternDecl('d', ValueType(List(U8())))]
417417
),
418418
ModuleType(
419-
[CoreImportDecl('','a: func u8 -> u8', CoreFuncType(['i32'],['i32']))],
419+
[CoreImportDecl('','a: func(x: u8) -> u8', CoreFuncType(['i32'],['i32']))],
420420
[CoreExportDecl('cabi_memory', CoreMemoryType(0, None)),
421421
CoreExportDecl('cabi_realloc', CoreFuncType(['i32','i32','i32','i32'],['i32'])),
422422
CoreExportDecl('cabi_start{cabi=0.1}: func(b: string) -> (d: list<u8>)',
423423
CoreFuncType(['i32','i32'],['i32'])),
424-
CoreExportDecl('c: func s8 -> s8', CoreFuncType(['i32'],['i32']))]
424+
CoreExportDecl('c: func(x: s8) -> s8', CoreFuncType(['i32'],['i32']))]
425425
)
426426
)
427427
test_cabi(
428428
ComponentType(
429429
[ExternDecl('a', InstanceType([
430-
ExternDecl('b', FuncType([U8()],[U8()])),
430+
ExternDecl('b', FuncType([('x',U8())],[U8()])),
431431
ExternDecl('c', ValueType(Float32()))
432432
]))],
433433
[ExternDecl('d', InstanceType([
@@ -436,7 +436,7 @@ def test_cabi(ct, expect):
436436
]))]
437437
),
438438
ModuleType(
439-
[CoreImportDecl('','a.b: func u8 -> u8', CoreFuncType(['i32'],['i32']))],
439+
[CoreImportDecl('','a.b: func(x: u8) -> u8', CoreFuncType(['i32'],['i32']))],
440440
[CoreExportDecl('cabi_memory', CoreMemoryType(0, None)),
441441
CoreExportDecl('cabi_realloc', CoreFuncType(['i32','i32','i32','i32'],['i32'])),
442442
CoreExportDecl('cabi_start{cabi=0.1}: func(a.c: float32) -> (d.f: float64)',
@@ -452,7 +452,7 @@ def test_cabi(ct, expect):
452452
ExternDecl('bar', FuncType([('x', U32()),('y', U32())],[U32()]))
453453
])),
454454
ExternDecl('v1', ValueType(String()))],
455-
[ExternDecl('baz', FuncType([String()], [String()])),
455+
[ExternDecl('baz', FuncType([('s',String())], [String()])),
456456
ExternDecl('v2', ValueType(List(List(String()))))]
457457
),
458458
ModuleType(
@@ -462,7 +462,7 @@ def test_cabi(ct, expect):
462462
CoreExportDecl('cabi_realloc', CoreFuncType(['i32','i32','i32','i32'],['i32'])),
463463
CoreExportDecl('cabi_start{cabi=0.1}: func(v1: string) -> (v2: list<list<string>>)',
464464
CoreFuncType(['i32','i32'],['i32'])),
465-
CoreExportDecl('baz: func string -> string', CoreFuncType(['i32','i32'],['i32'])),
465+
CoreExportDecl('baz: func(s: string) -> string', CoreFuncType(['i32','i32'],['i32'])),
466466
CoreExportDecl('cabi_post_baz', CoreFuncType(['i32'],[]))]
467467
)
468468
)

0 commit comments

Comments
 (0)