@@ -4,6 +4,8 @@ package vm
44// FIXME use LocalVars instead of storing everything in the Locals dict
55// see frameobject.c dict_to_map and LocalsToFast
66
7+ // FIXME *_FAST aren't using the fast path
8+
79/* FIXME
810
911cpython has one stack per frame, not one stack in total
@@ -32,7 +34,6 @@ objects so they can be GCed
3234*/
3335
3436import (
35- // "fmt"
3637 "runtime/debug"
3738
3839 "github.com/ncw/gpython/py"
@@ -749,7 +750,12 @@ func do_STORE_NAME(vm *Vm, namei int32) {
749750// attribute of the code object.
750751func do_DELETE_NAME (vm * Vm , namei int32 ) {
751752 defer vm .CheckException ()
752- vm .NotImplemented ("DELETE_NAME" , namei )
753+ name := vm .frame .Code .Names [namei ]
754+ if _ , ok := vm .frame .Locals [name ]; ! ok {
755+ vm .SetException (py .ExceptionNewf (py .NameError , nameErrorMsg , name ))
756+ } else {
757+ delete (vm .frame .Locals , name )
758+ }
753759}
754760
755761// Unpacks TOS into count individual values, which are put onto the
@@ -798,7 +804,12 @@ func do_STORE_GLOBAL(vm *Vm, namei int32) {
798804// Works as DELETE_NAME, but deletes a global name.
799805func do_DELETE_GLOBAL (vm * Vm , namei int32 ) {
800806 defer vm .CheckException ()
801- vm .NotImplemented ("DELETE_GLOBAL" , namei )
807+ name := vm .frame .Code .Names [namei ]
808+ if _ , ok := vm .frame .Globals [name ]; ! ok {
809+ vm .SetException (py .ExceptionNewf (py .NameError , nameErrorMsg , name ))
810+ } else {
811+ delete (vm .frame .Globals , name )
812+ }
802813}
803814
804815// Pushes co_consts[consti] onto the stack.
@@ -811,8 +822,14 @@ func do_LOAD_CONST(vm *Vm, consti int32) {
811822// Pushes the value associated with co_names[namei] onto the stack.
812823func do_LOAD_NAME (vm * Vm , namei int32 ) {
813824 defer vm .CheckException ()
814- debugf ("LOAD_NAME %v\n " , vm .frame .Code .Names [namei ])
815- vm .PUSH (vm .frame .Lookup (vm .frame .Code .Names [namei ]))
825+ name := vm .frame .Code .Names [namei ]
826+ debugf ("LOAD_NAME %v\n " , name )
827+ obj , ok := vm .frame .Lookup (name )
828+ if ! ok {
829+ vm .SetException (py .ExceptionNewf (py .NameError , nameErrorMsg , name ))
830+ } else {
831+ vm .PUSH (obj )
832+ }
816833}
817834
818835// Creates a tuple consuming count items from the stack, and pushes
@@ -1023,9 +1040,14 @@ func do_FOR_ITER(vm *Vm, delta int32) {
10231040// Loads the global named co_names[namei] onto the stack.
10241041func do_LOAD_GLOBAL (vm * Vm , namei int32 ) {
10251042 defer vm .CheckException ()
1026- // FIXME this is looking in local scope too - is that correct?
1027- debugf ("LOAD_GLOBAL %v\n " , vm .frame .Code .Names [namei ])
1028- vm .PUSH (vm .frame .Lookup (vm .frame .Code .Names [namei ]))
1043+ name := vm .frame .Code .Names [namei ]
1044+ debugf ("LOAD_GLOBAL %v\n " , name )
1045+ obj , ok := vm .frame .LookupGlobal (name )
1046+ if ! ok {
1047+ vm .SetException (py .ExceptionNewf (py .NameError , nameErrorMsg , name ))
1048+ } else {
1049+ vm .PUSH (obj )
1050+ }
10291051}
10301052
10311053// Pushes a block for a loop onto the block stack. The block spans
@@ -1069,7 +1091,9 @@ func do_LOAD_FAST(vm *Vm, var_num int32) {
10691091 if value , ok := vm .frame .Locals [varname ]; ok {
10701092 vm .PUSH (value )
10711093 } else {
1072- vm .SetException (py .ExceptionNewf (py .UnboundLocalError , unboundLocalErrorMsg , varname ))
1094+ vm .SetException (py .ExceptionNewf (py .NameError , nameErrorMsg , varname ))
1095+ // FIXME ceval.c says this, but it python3.4 returns the above
1096+ // vm.SetException(py.ExceptionNewf(py.UnboundLocalError, unboundLocalErrorMsg, varname))
10731097 }
10741098}
10751099
@@ -1086,7 +1110,8 @@ func do_DELETE_FAST(vm *Vm, var_num int32) {
10861110 if _ , ok := vm .frame .Locals [varname ]; ok {
10871111 delete (vm .frame .Locals , varname )
10881112 } else {
1089- vm .SetException (py .ExceptionNewf (py .UnboundLocalError , unboundLocalErrorMsg , varname ))
1113+ vm .SetException (py .ExceptionNewf (py .NameError , nameErrorMsg , varname ))
1114+ // FIXME ceval.c says this vm.SetException(py.ExceptionNewf(py.UnboundLocalError, unboundLocalErrorMsg, varname))
10901115 }
10911116}
10921117
@@ -1111,19 +1136,24 @@ func do_LOAD_CLOSURE(vm *Vm, i int32) {
11111136 vm .PUSH (vm .frame .CellAndFreeVars [i ])
11121137}
11131138
1139+ // writes the correct errors for an unbound deref
1140+ func unboundDeref (vm * Vm , i int32 ) {
1141+ varname , free := _var_name (vm , i )
1142+ if free {
1143+ vm .SetException (py .ExceptionNewf (py .NameError , unboundFreeErrorMsg , varname ))
1144+ } else {
1145+ vm .SetException (py .ExceptionNewf (py .UnboundLocalError , unboundLocalErrorMsg , varname ))
1146+ }
1147+ }
1148+
11141149// Loads the cell contained in slot i of the cell and free variable
11151150// storage. Pushes a reference to the object the cell contains on the
11161151// stack.
11171152func do_LOAD_DEREF (vm * Vm , i int32 ) {
11181153 defer vm .CheckException ()
11191154 res := vm .frame .CellAndFreeVars [i ].(* py.Cell ).Get ()
11201155 if res == nil {
1121- varname , free := _var_name (vm , i )
1122- if free {
1123- vm .SetException (py .ExceptionNewf (py .UnboundLocalError , unboundFreeErrorMsg , varname ))
1124- } else {
1125- vm .SetException (py .ExceptionNewf (py .UnboundLocalError , unboundLocalErrorMsg , varname ))
1126- }
1156+ unboundDeref (vm , i )
11271157 }
11281158 vm .PUSH (res )
11291159}
@@ -1140,14 +1170,19 @@ func do_LOAD_CLASSDEREF(vm *Vm, i int32) {
11401170// variable storage.
11411171func do_STORE_DEREF (vm * Vm , i int32 ) {
11421172 defer vm .CheckException ()
1143- vm .NotImplemented ("STORE_DEREF" , i )
1173+ cell := vm .frame .CellAndFreeVars [i ].(* py.Cell )
1174+ cell .Set (vm .POP ())
11441175}
11451176
11461177// Empties the cell contained in slot i of the cell and free variable
11471178// storage. Used by the del statement.
11481179func do_DELETE_DEREF (vm * Vm , i int32 ) {
11491180 defer vm .CheckException ()
1150- vm .NotImplemented ("DELETE_DEREF" , i )
1181+ cell := vm .frame .CellAndFreeVars [i ].(* py.Cell )
1182+ if cell .Get () == nil {
1183+ unboundDeref (vm , i )
1184+ }
1185+ cell .Delete ()
11511186}
11521187
11531188// Logic for the raise statement
0 commit comments