mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
shader: Forbid assigning to special variables
This commit is contained in:
parent
5e15ebf580
commit
a5af597594
@ -45,7 +45,7 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
return nil, false
|
||||
}
|
||||
|
||||
ss, ok := cs.assign(block, stmt.Pos(), stmt.Lhs, stmt.Rhs, true)
|
||||
ss, ok := cs.assign(block, fname, stmt.Pos(), stmt.Lhs, stmt.Rhs, inParams, true)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
@ -55,7 +55,7 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
cs.addError(stmt.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
|
||||
return nil, false
|
||||
}
|
||||
ss, ok := cs.assign(block, stmt.Pos(), stmt.Lhs, stmt.Rhs, false)
|
||||
ss, ok := cs.assign(block, fname, stmt.Pos(), stmt.Lhs, stmt.Rhs, inParams, false)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
@ -486,7 +486,7 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
return stmts, true
|
||||
}
|
||||
|
||||
func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr, define bool) ([]shaderir.Stmt, bool) {
|
||||
func (cs *compileState) assign(block *block, fname string, pos token.Pos, lhs, rhs []ast.Expr, inParams []variable, define bool) ([]shaderir.Stmt, bool) {
|
||||
var stmts []shaderir.Stmt
|
||||
var rhsExprs []shaderir.Expr
|
||||
var rhsTypes []shaderir.Type
|
||||
@ -543,6 +543,28 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr,
|
||||
if l[0].Type == shaderir.Blank {
|
||||
continue
|
||||
}
|
||||
|
||||
var isAssignmentForbidden func(e *shaderir.Expr) bool
|
||||
isAssignmentForbidden = func(e *shaderir.Expr) bool {
|
||||
switch e.Type {
|
||||
case shaderir.UniformVariable:
|
||||
return true
|
||||
case shaderir.LocalVariable:
|
||||
if fname == cs.vertexEntry || fname == cs.fragmentEntry {
|
||||
return e.Index < len(inParams)
|
||||
}
|
||||
case shaderir.FieldSelector:
|
||||
return isAssignmentForbidden(&e.Exprs[0])
|
||||
case shaderir.Index:
|
||||
return isAssignmentForbidden(&e.Exprs[0])
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if isAssignmentForbidden(&l[0]) {
|
||||
cs.addError(pos, fmt.Sprintf("a uniform variable cannot be assigned"))
|
||||
return nil, false
|
||||
}
|
||||
allblank = false
|
||||
|
||||
if r[0].Type == shaderir.NumberExpr {
|
||||
|
@ -448,3 +448,61 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestShaderForbidAssigningSpecialVariables(t *testing.T) {
|
||||
if _, err := NewShader([]byte(`package main
|
||||
|
||||
var U vec4
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
U = vec4(0)
|
||||
return vec4(0)
|
||||
}
|
||||
`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
|
||||
if _, err := NewShader([]byte(`package main
|
||||
|
||||
var U vec4
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
U.x = 0
|
||||
return vec4(0)
|
||||
}
|
||||
`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
|
||||
if _, err := NewShader([]byte(`package main
|
||||
|
||||
var U [2]vec4
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
U[0] = vec4(0)
|
||||
return vec4(0)
|
||||
}
|
||||
`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
|
||||
if _, err := NewShader([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
texCoord = vec2(0)
|
||||
return vec4(0)
|
||||
}
|
||||
`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
|
||||
if _, err := NewShader([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
texCoord.x = 0
|
||||
return vec4(0)
|
||||
}
|
||||
`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user