@@ -4,6 +4,8 @@ package vm
4
4
// FIXME use LocalVars instead of storing everything in the Locals dict
5
5
// see frameobject.c dict_to_map and LocalsToFast
6
6
7
+ // FIXME *_FAST aren't using the fast path
8
+
7
9
/* FIXME
8
10
9
11
cpython has one stack per frame, not one stack in total
@@ -32,7 +34,6 @@ objects so they can be GCed
32
34
*/
33
35
34
36
import (
35
- // "fmt"
36
37
"runtime/debug"
37
38
38
39
"github.com/ncw/gpython/py"
@@ -749,7 +750,12 @@ func do_STORE_NAME(vm *Vm, namei int32) {
749
750
// attribute of the code object.
750
751
func do_DELETE_NAME (vm * Vm , namei int32 ) {
751
752
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
+ }
753
759
}
754
760
755
761
// Unpacks TOS into count individual values, which are put onto the
@@ -798,7 +804,12 @@ func do_STORE_GLOBAL(vm *Vm, namei int32) {
798
804
// Works as DELETE_NAME, but deletes a global name.
799
805
func do_DELETE_GLOBAL (vm * Vm , namei int32 ) {
800
806
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
+ }
802
813
}
803
814
804
815
// Pushes co_consts[consti] onto the stack.
@@ -811,8 +822,14 @@ func do_LOAD_CONST(vm *Vm, consti int32) {
811
822
// Pushes the value associated with co_names[namei] onto the stack.
812
823
func do_LOAD_NAME (vm * Vm , namei int32 ) {
813
824
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
+ }
816
833
}
817
834
818
835
// Creates a tuple consuming count items from the stack, and pushes
@@ -1023,9 +1040,14 @@ func do_FOR_ITER(vm *Vm, delta int32) {
1023
1040
// Loads the global named co_names[namei] onto the stack.
1024
1041
func do_LOAD_GLOBAL (vm * Vm , namei int32 ) {
1025
1042
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
+ }
1029
1051
}
1030
1052
1031
1053
// 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) {
1069
1091
if value , ok := vm .frame .Locals [varname ]; ok {
1070
1092
vm .PUSH (value )
1071
1093
} 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))
1073
1097
}
1074
1098
}
1075
1099
@@ -1086,7 +1110,8 @@ func do_DELETE_FAST(vm *Vm, var_num int32) {
1086
1110
if _ , ok := vm .frame .Locals [varname ]; ok {
1087
1111
delete (vm .frame .Locals , varname )
1088
1112
} 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))
1090
1115
}
1091
1116
}
1092
1117
@@ -1111,19 +1136,24 @@ func do_LOAD_CLOSURE(vm *Vm, i int32) {
1111
1136
vm .PUSH (vm .frame .CellAndFreeVars [i ])
1112
1137
}
1113
1138
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
+
1114
1149
// Loads the cell contained in slot i of the cell and free variable
1115
1150
// storage. Pushes a reference to the object the cell contains on the
1116
1151
// stack.
1117
1152
func do_LOAD_DEREF (vm * Vm , i int32 ) {
1118
1153
defer vm .CheckException ()
1119
1154
res := vm .frame .CellAndFreeVars [i ].(* py.Cell ).Get ()
1120
1155
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 )
1127
1157
}
1128
1158
vm .PUSH (res )
1129
1159
}
@@ -1140,14 +1170,19 @@ func do_LOAD_CLASSDEREF(vm *Vm, i int32) {
1140
1170
// variable storage.
1141
1171
func do_STORE_DEREF (vm * Vm , i int32 ) {
1142
1172
defer vm .CheckException ()
1143
- vm .NotImplemented ("STORE_DEREF" , i )
1173
+ cell := vm .frame .CellAndFreeVars [i ].(* py.Cell )
1174
+ cell .Set (vm .POP ())
1144
1175
}
1145
1176
1146
1177
// Empties the cell contained in slot i of the cell and free variable
1147
1178
// storage. Used by the del statement.
1148
1179
func do_DELETE_DEREF (vm * Vm , i int32 ) {
1149
1180
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 ()
1151
1186
}
1152
1187
1153
1188
// Logic for the raise statement
0 commit comments