|
1 | 1 | // Evaluate opcodes
|
2 | 2 | package vm
|
3 | 3 |
|
| 4 | +// FIXME use LocalVars instead of storing everything in the Locals dict |
| 5 | +// see frameobject.c dict_to_map and LocalsToFast |
| 6 | + |
4 | 7 | /* FIXME
|
5 | 8 |
|
6 | 9 | cpython has one stack per frame, not one stack in total
|
@@ -1055,18 +1058,15 @@ func _var_name(vm *Vm, i int32) (string, bool) {
|
1055 | 1058 | // co_freevars[i - len(co_cellvars)].
|
1056 | 1059 | func do_LOAD_CLOSURE(vm *Vm, i int32) {
|
1057 | 1060 | defer vm.CheckException()
|
1058 |
| - varname, _ := _var_name(vm, i) |
1059 |
| - // FIXME this is making a new cell each time rather than |
1060 |
| - // returning a reference to an old one |
1061 |
| - vm.PUSH(py.NewCell(vm.frame.Locals[varname])) |
| 1061 | + vm.PUSH(vm.frame.CellAndFreeVars[i]) |
1062 | 1062 | }
|
1063 | 1063 |
|
1064 | 1064 | // Loads the cell contained in slot i of the cell and free variable
|
1065 | 1065 | // storage. Pushes a reference to the object the cell contains on the
|
1066 | 1066 | // stack.
|
1067 | 1067 | func do_LOAD_DEREF(vm *Vm, i int32) {
|
1068 | 1068 | defer vm.CheckException()
|
1069 |
| - res := vm.frame.Closure[i].(*py.Cell).Get() |
| 1069 | + res := vm.frame.CellAndFreeVars[i].(*py.Cell).Get() |
1070 | 1070 | if res == nil {
|
1071 | 1071 | varname, free := _var_name(vm, i)
|
1072 | 1072 | if free {
|
@@ -1470,6 +1470,32 @@ func RunFrame(frame *py.Frame) (res py.Object, err error) {
|
1470 | 1470 | func Run(globals, locals py.StringDict, code *py.Code, closure py.Tuple) (res py.Object, err error) {
|
1471 | 1471 | frame := py.NewFrame(globals, locals, code, closure)
|
1472 | 1472 |
|
| 1473 | + // Allocate and initialize storage for cell vars, and copy free |
| 1474 | + // vars into frame. |
| 1475 | + for i := range code.Cellvars { |
| 1476 | + var c py.Object |
| 1477 | + // Possibly account for the cell variable being an argument. |
| 1478 | + if code.Cell2arg != nil && code.Cell2arg[i] != py.CO_CELL_NOT_AN_ARG { |
| 1479 | + arg := code.Cell2arg[i] |
| 1480 | + // FIXME if use localvars need to change this |
| 1481 | + // c = NewCell(GETLOCAL(arg)) |
| 1482 | + // // Clear the local copy. |
| 1483 | + // SETLOCAL(arg, nil) |
| 1484 | + varname := code.Varnames[arg] |
| 1485 | + c = py.NewCell(locals[varname]) |
| 1486 | + } else { |
| 1487 | + c = py.NewCell(nil) |
| 1488 | + } |
| 1489 | + //SETLOCAL(code.nlocals+i, c) |
| 1490 | + frame.CellAndFreeVars[i] = c |
| 1491 | + } |
| 1492 | + ncells := len(code.Cellvars) |
| 1493 | + for i := range code.Freevars { |
| 1494 | + //PyObject * o = PyTuple_GET_ITEM(closure, i) |
| 1495 | + //freevars[PyTuple_GET_SIZE(code.cellvars)+i] = o |
| 1496 | + frame.CellAndFreeVars[i+ncells] = closure[i] |
| 1497 | + } |
| 1498 | + |
1473 | 1499 | // If this is a generator then make a generator object from
|
1474 | 1500 | // the frame and return that instead
|
1475 | 1501 | if code.Flags&py.CO_GENERATOR != 0 {
|
|
0 commit comments