|
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 | funcdo_LOAD_CLOSURE(vm*Vm, iint32){ |
1057 | 1060 | defervm.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 | funcdo_LOAD_DEREF(vm*Vm, iint32){ |
1068 | 1068 | defervm.CheckException() |
1069 | | -res:=vm.frame.Closure[i].(*py.Cell).Get() |
| 1069 | +res:=vm.frame.CellAndFreeVars[i].(*py.Cell).Get() |
1070 | 1070 | ifres==nil{ |
1071 | 1071 | varname, free:=_var_name(vm, i) |
1072 | 1072 | iffree{ |
@@ -1470,6 +1470,32 @@ func RunFrame(frame *py.Frame) (res py.Object, err error){ |
1470 | 1470 | funcRun(globals, locals py.StringDict, code*py.Code, closure py.Tuple) (res py.Object, errerror){ |
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 | +fori:=rangecode.Cellvars{ |
| 1476 | +varc py.Object |
| 1477 | +// Possibly account for the cell variable being an argument. |
| 1478 | +ifcode.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 | +fori:=rangecode.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 | ifcode.Flags&py.CO_GENERATOR!=0{ |
|
0 commit comments