aboutsummaryrefslogtreecommitdiff
path: root/starlark/interp.go
diff options
context:
space:
mode:
Diffstat (limited to 'starlark/interp.go')
-rw-r--r--starlark/interp.go30
1 files changed, 21 insertions, 9 deletions
diff --git a/starlark/interp.go b/starlark/interp.go
index f00382c..642d8f5 100644
--- a/starlark/interp.go
+++ b/starlark/interp.go
@@ -547,11 +547,9 @@ loop:
locals[arg] = stack[sp-1]
sp--
- case compile.SETCELL:
- x := stack[sp-2]
- y := stack[sp-1]
- sp -= 2
- y.(*cell).v = x
+ case compile.SETLOCALCELL:
+ locals[arg].(*cell).v = stack[sp-1]
+ sp--
case compile.SETGLOBAL:
fn.module.globals[arg] = stack[sp-1]
@@ -570,9 +568,23 @@ loop:
stack[sp] = fn.freevars[arg]
sp++
- case compile.CELL:
- x := stack[sp-1]
- stack[sp-1] = x.(*cell).v
+ case compile.LOCALCELL:
+ v := locals[arg].(*cell).v
+ if v == nil {
+ err = fmt.Errorf("local variable %s referenced before assignment", f.Locals[arg].Name)
+ break loop
+ }
+ stack[sp] = v
+ sp++
+
+ case compile.FREECELL:
+ v := fn.freevars[arg].(*cell).v
+ if v == nil {
+ err = fmt.Errorf("local variable %s referenced before assignment", f.Freevars[arg].Name)
+ break loop
+ }
+ stack[sp] = v
+ sp++
case compile.GLOBAL:
x := fn.module.globals[arg]
@@ -641,7 +653,7 @@ func (mandatory) Hash() (uint32, error) { return 0, nil }
// A cell is a box containing a Value.
// Local variables marked as cells hold their value indirectly
// so that they may be shared by outer and inner nested functions.
-// Cells are always accessed using indirect CELL/SETCELL instructions.
+// Cells are always accessed using indirect {FREE,LOCAL,SETLOCAL}CELL instructions.
// The FreeVars tuple contains only cells.
// The FREE instruction always yields a cell.
type cell struct{ v Value }