@@ -360,7 +360,7 @@ func (c *compilerContext) checkWasmImport(f *ssa.Function, pragma string) {
360
360
c .addError (f .Signature .Results ().At (1 ).Pos (), fmt .Sprintf ("%s: too many return values" , pragma ))
361
361
} else if f .Signature .Results ().Len () == 1 {
362
362
result := f .Signature .Results ().At (0 )
363
- if ! isValidWasmType (result .Type (), true ) {
363
+ if ! isValidWasmType (result .Type (), false ) {
364
364
c .addError (result .Pos (), fmt .Sprintf ("%s: unsupported result type %s" , pragma , result .Type ().String ()))
365
365
}
366
366
}
@@ -373,30 +373,42 @@ func (c *compilerContext) checkWasmImport(f *ssa.Function, pragma string) {
373
373
}
374
374
}
375
375
376
- // Check whether the type maps directly to a WebAssembly type, according to:
377
- // https://github.com/golang/go/issues/59149
376
+ // Check whether the type maps directly to a WebAssembly type.
378
377
//
379
- // Update: this reflects the relaxed type restrictions proposed here:
378
+ // This reflects the relaxed type restrictions proposed here (except for structs.HostLayout) :
380
379
// https://github.com/golang/go/issues/66984
381
- func isValidWasmType (typ types.Type , isReturn bool ) bool {
380
+ //
381
+ // This previously reflected the additional restrictions documented here:
382
+ // https://github.com/golang/go/issues/59149
383
+ func isValidWasmType (typ types.Type , isPointerOrField bool ) bool {
382
384
switch typ := typ .Underlying ().(type ) {
383
385
case * types.Basic :
384
386
switch typ .Kind () {
385
387
case types .Bool :
386
388
return true
387
- case types .Int8 , types .Uint8 , types .Int16 , types .Uint16 , types .Int32 , types .Uint32 , types .Int64 , types .Uint64 :
389
+ case types .Int , types . Uint , types . Int8 , types .Uint8 , types .Int16 , types .Uint16 , types .Int32 , types .Uint32 , types .Int64 , types .Uint64 :
388
390
return true
389
391
case types .Float32 , types .Float64 :
390
392
return true
391
393
case types .Uintptr , types .UnsafePointer :
392
394
return true
393
395
case types .String :
394
- return true
396
+ return isPointerOrField
395
397
}
398
+ case * types.Array :
399
+ return isPointerOrField && isValidWasmType (typ .Elem (), true )
396
400
case * types.Struct :
401
+ if ! isPointerOrField {
402
+ return false
403
+ }
404
+ for i := 0 ; i < typ .NumFields (); i ++ {
405
+ if ! isValidWasmType (typ .Field (i ).Type (), true ) {
406
+ return false
407
+ }
408
+ }
397
409
return true
398
410
case * types.Pointer :
399
- return isValidWasmType (typ .Elem (), isReturn )
411
+ return isValidWasmType (typ .Elem (), true )
400
412
}
401
413
return false
402
414
}
0 commit comments