fix: revert scalar return optimization that breaks named types
reflect.ValueOf(uintptr(x)) creates a value of type uintptr, not the declared return type (e.g., types.GType). reflect.MakeFunc requires exact type match. Revert to reflect.New(outType).Elem() + Set* which preserves named type semantics.
- commit
- 91aa177a27043b8d15daac3cb32849fd9916104e
- author
- brice · · 2026-03-23 09:59 UTC
- parent
- a02394b
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +6 -27
M func.go +6 -27
| @@ -392,35 +392,14 @@ func callAndReturn(ty reflect.Type, is32bit bool, cfn uintptr, sysargs *[maxArgs | |||
| 392 | 392 | return nil | |
| 393 | 393 | } | |
| 394 | 394 | outType := ty.Out(0) | |
| 395 | - | // Task 5: For simple scalar return types, construct the reflect.Value directly | |
| 396 | - | // instead of allocating via reflect.New(outType).Elem(). | |
| 397 | - | // reflect.ValueOf for scalar types avoids the heap allocation that reflect.New incurs. | |
| 398 | - | var v reflect.Value | |
| 395 | + | v := reflect.New(outType).Elem() | |
| 399 | 396 | switch outType.Kind() { | |
| 400 | - | case reflect.Uintptr: | |
| 401 | - | v = reflect.ValueOf(uintptr(syscall.a1)) | |
| 402 | - | case reflect.Uint: | |
| 403 | - | v = reflect.ValueOf(uint(syscall.a1)) | |
| 404 | - | case reflect.Uint8: | |
| 405 | - | v = reflect.ValueOf(uint8(syscall.a1)) | |
| 406 | - | case reflect.Uint16: | |
| 407 | - | v = reflect.ValueOf(uint16(syscall.a1)) | |
| 408 | - | case reflect.Uint32: | |
| 409 | - | v = reflect.ValueOf(uint32(syscall.a1)) | |
| 410 | - | case reflect.Uint64: | |
| 411 | - | v = reflect.ValueOf(uint64(syscall.a1)) | |
| 412 | - | case reflect.Int: | |
| 413 | - | v = reflect.ValueOf(int(syscall.a1)) | |
| 414 | - | case reflect.Int8: | |
| 415 | - | v = reflect.ValueOf(int8(syscall.a1)) | |
| 416 | - | case reflect.Int16: | |
| 417 | - | v = reflect.ValueOf(int16(syscall.a1)) | |
| 418 | - | case reflect.Int32: | |
| 419 | - | v = reflect.ValueOf(int32(syscall.a1)) | |
| 420 | - | case reflect.Int64: | |
| 421 | - | v = reflect.ValueOf(int64(syscall.a1)) | |
| 397 | + | case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | |
| 398 | + | v.SetUint(uint64(syscall.a1)) | |
| 399 | + | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | |
| 400 | + | v.SetInt(int64(syscall.a1)) | |
| 422 | 401 | case reflect.Bool: | |
| 423 | - | v = reflect.ValueOf(byte(syscall.a1) != 0) | |
| 402 | + | v.SetBool(byte(syscall.a1) != 0) | |
| 424 | 403 | case reflect.UnsafePointer: | |
| 425 | 404 | // We take the address and then dereference it to trick go vet from creating a possible miss-use of unsafe.Pointer | |
| 426 | 405 | v = reflect.New(outType).Elem() | |
| @@ -392,35 +392,14 @@ func callAndReturn(ty reflect.Type, is32bit bool, cfn uintptr, sysargs *[maxArgs | |||||
| 392 | return nil | 392 | return nil | ||
| 393 | } | 393 | } | ||
| 394 | outType := ty.Out(0) | 394 | outType := ty.Out(0) | ||
| 395 | - | // Task 5: For simple scalar return types, construct the reflect.Value directly | 395 | + | v := reflect.New(outType).Elem() |
| 396 | - | // instead of allocating via reflect.New(outType).Elem(). | |||
| 397 | - | // reflect.ValueOf for scalar types avoids the heap allocation that reflect.New incurs. | |||
| 398 | - | var v reflect.Value | |||
| 399 | switch outType.Kind() { | 396 | switch outType.Kind() { | ||
| 400 | - | case reflect.Uintptr: | 397 | + | case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: |
| 401 | - | v = reflect.ValueOf(uintptr(syscall.a1)) | 398 | + | v.SetUint(uint64(syscall.a1)) |
| 402 | - | case reflect.Uint: | 399 | + | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
| 403 | - | v = reflect.ValueOf(uint(syscall.a1)) | 400 | + | v.SetInt(int64(syscall.a1)) |
| 404 | - | case reflect.Uint8: | |||
| 405 | - | v = reflect.ValueOf(uint8(syscall.a1)) | |||
| 406 | - | case reflect.Uint16: | |||
| 407 | - | v = reflect.ValueOf(uint16(syscall.a1)) | |||
| 408 | - | case reflect.Uint32: | |||
| 409 | - | v = reflect.ValueOf(uint32(syscall.a1)) | |||
| 410 | - | case reflect.Uint64: | |||
| 411 | - | v = reflect.ValueOf(uint64(syscall.a1)) | |||
| 412 | - | case reflect.Int: | |||
| 413 | - | v = reflect.ValueOf(int(syscall.a1)) | |||
| 414 | - | case reflect.Int8: | |||
| 415 | - | v = reflect.ValueOf(int8(syscall.a1)) | |||
| 416 | - | case reflect.Int16: | |||
| 417 | - | v = reflect.ValueOf(int16(syscall.a1)) | |||
| 418 | - | case reflect.Int32: | |||
| 419 | - | v = reflect.ValueOf(int32(syscall.a1)) | |||
| 420 | - | case reflect.Int64: | |||
| 421 | - | v = reflect.ValueOf(int64(syscall.a1)) | |||
| 422 | case reflect.Bool: | 401 | case reflect.Bool: | ||
| 423 | - | v = reflect.ValueOf(byte(syscall.a1) != 0) | 402 | + | v.SetBool(byte(syscall.a1) != 0) |
| 424 | case reflect.UnsafePointer: | 403 | case reflect.UnsafePointer: | ||
| 425 | // We take the address and then dereference it to trick go vet from creating a possible miss-use of unsafe.Pointer | 404 | // We take the address and then dereference it to trick go vet from creating a possible miss-use of unsafe.Pointer | ||
| 426 | v = reflect.New(outType).Elem() | 405 | v = reflect.New(outType).Elem() | ||