aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-12-08 19:03:09 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-12-08 19:08:08 +0100
commitc7918378631992d874c99736272ed342d5d77b2c (patch)
tree5e67097471fda876d532c270dc4b7f3db0e850c5 /pkg/compiler
parent33508266251f6db13ef34741e36b1dce2c9e1b49 (diff)
executor: fix handling of big-endian bitfields
Currently we apply big-endian-ness and bitfield-ness in the wrong order in copyin. This leads to totally bogus result. Fix this.
Diffstat (limited to 'pkg/compiler')
-rw-r--r--pkg/compiler/check.go3
-rw-r--r--pkg/compiler/testdata/errors.txt1
-rw-r--r--pkg/compiler/types.go18
3 files changed, 17 insertions, 5 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index 6ec2fa9e2..cc0535449 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -751,7 +751,8 @@ func (comp *compiler) checkTypeBasic(t *ast.Type, desc *typeDesc, flags checkFla
comp.error(t.Pos, "%v can't be type alias target", t.Ident)
return
}
- if flags&checkIsResourceBase != 0 && !desc.ResourceBase {
+ if flags&checkIsResourceBase != 0 &&
+ (desc.CanBeResourceBase == nil || !desc.CanBeResourceBase(comp, t)) {
comp.error(t.Pos, "%v can't be resource base (int types can)", t.Ident)
return
}
diff --git a/pkg/compiler/testdata/errors.txt b/pkg/compiler/testdata/errors.txt
index fed520e6e..55ec40901 100644
--- a/pkg/compiler/testdata/errors.txt
+++ b/pkg/compiler/testdata/errors.txt
@@ -65,6 +65,7 @@ resource r2[r0]: 2
resource r3[int32:1] ### unexpected ':', only struct fields can be bitfields
resource r4[int32[opt]] ### resource base can't be marked as opt
resource r5[non_existent] ### unknown type non_existent
+resource r6[int64be] ### int64be can't be resource base (int types can)
resource r9["foo"] ### unexpected string "foo", expect type
foo$7(a r0, a1 r2[opt])
diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go
index 98edc9d74..30ff8884a 100644
--- a/pkg/compiler/types.go
+++ b/pkg/compiler/types.go
@@ -18,11 +18,12 @@ type typeDesc struct {
CantBeOpt bool // can't be marked as opt?
NeedBase bool // needs base type when used as field?
AllowColon bool // allow colon (int8:2) on fields?
- ResourceBase bool // can be resource base type?
OptArgs int // number of optional arguments in Args array
Args []namedArg // type arguments
// CanBeArgRet returns if this type can be syscall argument/return (false if nil).
CanBeArgRet func(comp *compiler, t *ast.Type) (bool, bool)
+ // CanBeResourceBase returns if this type can be a resource base type (false if nil.
+ CanBeResourceBase func(comp *compiler, t *ast.Type) bool
// Check does custom verification of the type (optional, consts are not patched yet).
Check func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon)
// CheckConsts does custom verification of the type (optional, consts are patched).
@@ -67,9 +68,16 @@ var typeInt = &typeDesc{
CanBeArgRet: canBeArg,
CanBeTypedef: true,
AllowColon: true,
- ResourceBase: true,
OptArgs: 1,
Args: []namedArg{{Name: "range", Type: typeArgIntRange}},
+ CanBeResourceBase: func(comp *compiler, t *ast.Type) bool {
+ // Big-endian resources can always be converted to non-big-endian,
+ // since we will always revert bytes during copyout and during copyin,
+ // so the result is the same as not reverting at all.
+ // Big-endian resources are also not implemented and don't have tests.
+ _, be := comp.parseIntType(t.Ident)
+ return !be
+ },
Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) {
typeArgBase.Type.Check(comp, t)
},
@@ -653,8 +661,10 @@ var typeArgType = &typeArg{}
var typeResource = &typeDesc{
// No Names, but getTypeDesc knows how to match it.
- CanBeArgRet: canBeArgRet,
- ResourceBase: true,
+ CanBeArgRet: canBeArgRet,
+ CanBeResourceBase: func(comp *compiler, t *ast.Type) bool {
+ return true
+ },
// Gen is assigned below to avoid initialization loop.
}