This commit fixes a crash when trying to compile the following (invalid)
code:
package main
import "unsafe"
func main() {
}
type Foo struct {
x DoesNotExist
}
const foo = unsafe.Sizeof(Foo{})
This commit fixes this situation. The result is a regular error message,
indicating that DoesNotExist is not defined.
Instead of putting the magic in the AST, generate regular accessor
methods. This avoids a number of special cases in the compiler, and
avoids missing any of them.
The resulting union accesses are somewhat clunkier to use, but the
compiler implementation has far less coupling between the CGo
implementation and the IR generator.
Instead of storing the value to send/receive in the coroutine promise,
store only a pointer in the promise. This simplifies the code a lot and
allows larger value sizes to be sent across a channel.
Unfortunately, this new system has a code size impact. For example,
compiling testdata/channel.go for the BBC micro:bit, there is an
increase in code size from 4776 bytes to 4856 bytes. However, the
improved flexibility and simplicity of the code should be worth it. If
this becomes an issue, we can always refactor the code at a later time.
Unions are somewhat hard to implement in Go because they are not a
native type. But it is actually possible with some compiler magic.
This commit inserts a special "C union" field at the start of a struct
to indicate that it is a union. As such a field cannot be written
directly in Go, this is a useful to distinguish structs and unions.