Skip to content

Commit 447496c

Browse files
committed
vm: give opcode its own type
1 parent 0838829 commit 447496c

File tree

7 files changed

+291
-287
lines changed

7 files changed

+291
-287
lines changed

compile/compile.go

+14-14
Original file line numberDiff line numberDiff line change
@@ -351,23 +351,23 @@ func (c *compiler) Name(Id ast.Identifier) uint32 {
351351
}
352352

353353
// Adds this opcode with mangled name as an argument
354-
func (c *compiler) OpName(opcode byte, name ast.Identifier) {
354+
func (c *compiler) OpName(opcode vm.OpCode, name ast.Identifier) {
355355
// FIXME mangled := _Py_Mangle(c->u->u_private, o);
356356
mangled := name
357357
c.OpArg(opcode, c.Name(mangled))
358358
}
359359

360360
// Compiles an instruction with an argument
361-
func (c *compiler) OpArg(Op byte, Arg uint32) {
362-
if !vm.HAS_ARG(Op) {
361+
func (c *compiler) OpArg(Op vm.OpCode, Arg uint32) {
362+
if !Op.HAS_ARG() {
363363
panic("OpArg called with an instruction which doesn't take an Arg")
364364
}
365365
c.OpCodes.Add(&OpArg{Op: Op, Arg: Arg})
366366
}
367367

368368
// Compiles an instruction without an argument
369-
func (c *compiler) Op(op byte) {
370-
if vm.HAS_ARG(op) {
369+
func (c *compiler) Op(op vm.OpCode) {
370+
if op.HAS_ARG() {
371371
panic("Op called with an instruction which takes an Arg")
372372
}
373373
c.OpCodes.Add(&Op{Op: op})
@@ -386,7 +386,7 @@ func (c *compiler) NewLabel() *Label {
386386
}
387387

388388
// Compiles a jump instruction
389-
func (c *compiler) Jump(Op byte, Dest *Label) {
389+
func (c *compiler) Jump(Op vm.OpCode, Dest *Label) {
390390
switch Op {
391391
case vm.JUMP_IF_FALSE_OR_POP, vm.JUMP_IF_TRUE_OR_POP, vm.JUMP_ABSOLUTE, vm.POP_JUMP_IF_FALSE, vm.POP_JUMP_IF_TRUE, vm.CONTINUE_LOOP: // Absolute
392392
c.OpCodes.Add(&JumpAbs{OpArg: OpArg{Op: Op}, Dest: Dest})
@@ -1001,7 +1001,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
10011001
setctx.SetCtx(ast.AugLoad)
10021002
c.Expr(node.Target)
10031003
c.Expr(node.Value)
1004-
var op byte
1004+
var op vm.OpCode
10051005
switch node.Op {
10061006
case ast.Add:
10071007
op = vm.INPLACE_ADD
@@ -1218,7 +1218,7 @@ func (c *compiler) NameOp(name string, ctx ast.ExprContext) {
12181218
panic("NameOp: Can't compile None, True or False")
12191219
}
12201220

1221-
op := byte(0)
1221+
op := vm.OpCode(0)
12221222
optype := OP_NAME
12231223
scope := c.SymTable.GetScope(mangled)
12241224
switch scope {
@@ -1325,7 +1325,7 @@ func (c *compiler) callHelper(n int, Args []ast.Expr, Keywords []*ast.Keyword, S
13251325
c.LoadConst(py.String(kw.Arg))
13261326
c.Expr(kw.Value)
13271327
}
1328-
op := byte(vm.CALL_FUNCTION)
1328+
op := vm.CALL_FUNCTION
13291329
if Starargs != nil {
13301330
c.Expr(Starargs)
13311331
if Kwargs != nil {
@@ -1425,7 +1425,7 @@ func (c *compiler) comprehension(expr ast.Expr, generators []ast.Comprehension)
14251425
}
14261426

14271427
// Compile a tuple or a list
1428-
func (c *compiler) tupleOrList(op byte, ctx ast.ExprContext, elts []ast.Expr) {
1428+
func (c *compiler) tupleOrList(op vm.OpCode, ctx ast.ExprContext, elts []ast.Expr) {
14291429
const INT_MAX = 0x7FFFFFFF
14301430
n := len(elts)
14311431
if ctx == ast.Store {
@@ -1553,7 +1553,7 @@ func (c *compiler) Expr(expr ast.Expr) {
15531553
case *ast.BoolOp:
15541554
// Op BoolOpNumber
15551555
// Values []Expr
1556-
var op byte
1556+
var op vm.OpCode
15571557
switch node.Op {
15581558
case ast.And:
15591559
op = vm.JUMP_IF_FALSE_OR_POP
@@ -1576,7 +1576,7 @@ func (c *compiler) Expr(expr ast.Expr) {
15761576
// Right Expr
15771577
c.Expr(node.Left)
15781578
c.Expr(node.Right)
1579-
var op byte
1579+
var op vm.OpCode
15801580
switch node.Op {
15811581
case ast.Add:
15821582
op = vm.BINARY_ADD
@@ -1610,7 +1610,7 @@ func (c *compiler) Expr(expr ast.Expr) {
16101610
// Op UnaryOpNumber
16111611
// Operand Expr
16121612
c.Expr(node.Operand)
1613-
var op byte
1613+
var op vm.OpCode
16141614
switch node.Op {
16151615
case ast.Invert:
16161616
op = vm.UNARY_INVERT
@@ -1783,7 +1783,7 @@ func (c *compiler) Expr(expr ast.Expr) {
17831783
if node.Ctx != ast.AugStore {
17841784
c.Expr(node.Value)
17851785
}
1786-
var op byte
1786+
var op vm.OpCode
17871787
switch node.Ctx {
17881788
case ast.AugLoad:
17891789
c.Op(vm.DUP_TOP)

compile/instructions.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func nArgs(o uint32) int {
7373
}
7474

7575
// Effect the opcode has on the stack
76-
func opcodeStackEffect(opcode byte, oparg uint32) int {
76+
func opcodeStackEffect(opcode vm.OpCode, oparg uint32) int {
7777
switch opcode {
7878
case vm.POP_TOP:
7979
return -1
@@ -337,7 +337,7 @@ func (p *pos) SetPos(number int, newPos uint32) bool {
337337
// A plain opcode
338338
type Op struct {
339339
pos
340-
Op byte
340+
Op vm.OpCode
341341
}
342342

343343
// Uses 1 byte in the output stream
@@ -358,7 +358,7 @@ func (o *Op) StackEffect() int {
358358
// An opcode with argument
359359
type OpArg struct {
360360
pos
361-
Op byte
361+
Op vm.OpCode
362362
Arg uint32
363363
}
364364

@@ -373,9 +373,9 @@ func (o *OpArg) Size() uint32 {
373373

374374
// Output
375375
func (o *OpArg) Output() []byte {
376-
out := []byte{o.Op, byte(o.Arg), byte(o.Arg >> 8)}
376+
out := []byte{byte(o.Op), byte(o.Arg), byte(o.Arg >> 8)}
377377
if o.Arg > 0xFFFF {
378-
out = append([]byte{vm.EXTENDED_ARG, byte(o.Arg >> 16), byte(o.Arg >> 24)}, out...)
378+
out = append([]byte{byte(vm.EXTENDED_ARG), byte(o.Arg >> 16), byte(o.Arg >> 24)}, out...)
379379
}
380380
return out
381381
}

py/frame.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,21 @@
22

33
package py
44

5+
// What kind of block this is
6+
type TryBlockType byte
7+
8+
const (
9+
TryBlockSetupLoop TryBlockType = iota
10+
TryBlockSetupExcept
11+
TryBlockSetupFinally
12+
TryBlockExceptHandler
13+
)
14+
515
// Store information about try blocks
616
type TryBlock struct {
7-
Type byte // what kind of block this is (the opcode)
8-
Handler int32 // where to jump to find handler
9-
Level int // value stack level to pop to
17+
Type TryBlockType // what kind of block this is
18+
Handler int32 // where to jump to find handler
19+
Level int // value stack level to pop to
1020
}
1121

1222
// A python Frame object
@@ -123,7 +133,7 @@ func (f *Frame) Lookup(name string) (obj Object, ok bool) {
123133
}
124134

125135
// Make a new Block (try/for/while)
126-
func (f *Frame) PushBlock(Type byte, Handler int32, Level int) {
136+
func (f *Frame) PushBlock(Type TryBlockType, Handler int32, Level int) {
127137
f.Blockstack = append(f.Blockstack, TryBlock{
128138
Type: Type,
129139
Handler: Handler,

vm/eval.go

+17-19
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Evaluate opcodes
22
package vm
33

4-
// FIXME make opcode its own type so can stringer
5-
64
// FIXME use LocalVars instead of storing everything in the Locals dict
75
// see frameobject.c dict_to_map and LocalsToFast
86

@@ -680,7 +678,7 @@ func do_POP_EXCEPT(vm *Vm, arg int32) {
680678
frame := vm.frame
681679
b := vm.frame.Block
682680
frame.PopBlock()
683-
if b.Type != EXCEPT_HANDLER {
681+
if b.Type != py.TryBlockExceptHandler {
684682
vm.SetException(py.ExceptionNewf(py.SystemError, "popped block is not an except handler"))
685683
} else {
686684
vm.UnwindExceptHandler(frame, b)
@@ -715,7 +713,7 @@ func do_END_FINALLY(vm *Vm, arg int32) {
715713
frame := vm.frame
716714
b := vm.frame.Block
717715
frame.PopBlock()
718-
if b.Type != EXCEPT_HANDLER {
716+
if b.Type != py.TryBlockExceptHandler {
719717
panic("Expecting EXCEPT_HANDLER in END_FINALLY")
720718
}
721719
vm.UnwindExceptHandler(frame, b)
@@ -1093,21 +1091,21 @@ func do_LOAD_GLOBAL(vm *Vm, namei int32) {
10931091
// from the current instruction with a size of delta bytes.
10941092
func do_SETUP_LOOP(vm *Vm, delta int32) {
10951093
defer vm.CheckException()
1096-
vm.frame.PushBlock(SETUP_LOOP, vm.frame.Lasti+delta, len(vm.frame.Stack))
1094+
vm.frame.PushBlock(py.TryBlockSetupLoop, vm.frame.Lasti+delta, len(vm.frame.Stack))
10971095
}
10981096

10991097
// Pushes a try block from a try-except clause onto the block
11001098
// stack. delta points to the first except block.
11011099
func do_SETUP_EXCEPT(vm *Vm, delta int32) {
11021100
defer vm.CheckException()
1103-
vm.frame.PushBlock(SETUP_EXCEPT, vm.frame.Lasti+delta, len(vm.frame.Stack))
1101+
vm.frame.PushBlock(py.TryBlockSetupExcept, vm.frame.Lasti+delta, len(vm.frame.Stack))
11041102
}
11051103

11061104
// Pushes a try block from a try-except clause onto the block
11071105
// stack. delta points to the finally block.
11081106
func do_SETUP_FINALLY(vm *Vm, delta int32) {
11091107
defer vm.CheckException()
1110-
vm.frame.PushBlock(SETUP_FINALLY, vm.frame.Lasti+delta, len(vm.frame.Stack))
1108+
vm.frame.PushBlock(py.TryBlockSetupFinally, vm.frame.Lasti+delta, len(vm.frame.Stack))
11111109
}
11121110

11131111
// Store a key and value pair in a dictionary. Pops the key and value
@@ -1308,7 +1306,7 @@ func do_CALL_FUNCTION(vm *Vm, argc int32) {
13081306
}
13091307

13101308
// Implementation for MAKE_FUNCTION and MAKE_CLOSURE
1311-
func _make_function(vm *Vm, argc int32, opcode byte) {
1309+
func _make_function(vm *Vm, argc int32, opcode OpCode) {
13121310
posdefaults := argc & 0xff
13131311
kwdefaults := (argc >> 8) & 0xff
13141312
num_annotations := (argc >> 16) & 0x7fff
@@ -1512,25 +1510,25 @@ func RunFrame(frame *py.Frame) (res py.Object, err error) {
15121510
// }
15131511
// }()
15141512

1515-
var opcode byte
1513+
var opcode OpCode
15161514
var arg int32
15171515
for vm.why == whyNot {
15181516
frame := vm.frame
15191517
debugf("* %4d:", frame.Lasti)
15201518
opcodes := frame.Code.Code
1521-
opcode = opcodes[frame.Lasti]
1519+
opcode = OpCode(opcodes[frame.Lasti])
15221520
frame.Lasti++
1523-
if HAS_ARG(opcode) {
1521+
if opcode.HAS_ARG() {
15241522
arg = int32(opcodes[frame.Lasti])
15251523
frame.Lasti++
15261524
arg += int32(opcodes[frame.Lasti]) << 8
15271525
frame.Lasti++
15281526
if vm.extended {
15291527
arg += vm.ext << 16
15301528
}
1531-
debugf(" %s(%d)\n", OpCodeToName[opcode], arg)
1529+
debugf(" %v(%d)\n", opcode, arg)
15321530
} else {
1533-
debugf(" %s\n", OpCodeToName[opcode])
1531+
debugf(" %v\n", opcode)
15341532
}
15351533
vm.extended = false
15361534
jumpTable[opcode](vm, arg)
@@ -1554,7 +1552,7 @@ func RunFrame(frame *py.Frame) (res py.Object, err error) {
15541552
b := frame.Block
15551553
debugf("*** Unwinding %#v vm %#v\n", b, vm)
15561554

1557-
if b.Type == SETUP_LOOP && vm.why == whyContinue {
1555+
if b.Type == py.TryBlockSetupLoop && vm.why == whyContinue {
15581556
vm.why = whyNot
15591557
dest := vm.retval.(py.Int)
15601558
frame.Lasti = int32(dest)
@@ -1564,23 +1562,23 @@ func RunFrame(frame *py.Frame) (res py.Object, err error) {
15641562
// Now we have to pop the block.
15651563
frame.PopBlock()
15661564

1567-
if b.Type == EXCEPT_HANDLER {
1565+
if b.Type == py.TryBlockExceptHandler {
15681566
debugf("*** EXCEPT_HANDLER\n")
15691567
vm.UnwindExceptHandler(frame, b)
15701568
continue
15711569
}
15721570
vm.UnwindBlock(frame, b)
1573-
if b.Type == SETUP_LOOP && vm.why == whyBreak {
1571+
if b.Type == py.TryBlockSetupLoop && vm.why == whyBreak {
15741572
debugf("*** Loop\n")
15751573
vm.why = whyNot
15761574
frame.Lasti = b.Handler
15771575
break
15781576
}
1579-
if vm.why == whyException && (b.Type == SETUP_EXCEPT || b.Type == SETUP_FINALLY) {
1577+
if vm.why == whyException && (b.Type == py.TryBlockSetupExcept || b.Type == py.TryBlockSetupFinally) {
15801578
debugf("*** Exception\n")
15811579
handler := b.Handler
15821580
// This invalidates b
1583-
frame.PushBlock(EXCEPT_HANDLER, -1, vm.STACK_LEVEL())
1581+
frame.PushBlock(py.TryBlockExceptHandler, -1, vm.STACK_LEVEL())
15841582
vm.PUSH(vm.exc.Traceback)
15851583
vm.PUSH(vm.exc.Value)
15861584
if vm.exc.Type == nil {
@@ -1615,7 +1613,7 @@ func RunFrame(frame *py.Frame) (res py.Object, err error) {
16151613
frame.Lasti = handler
16161614
break
16171615
}
1618-
if b.Type == SETUP_FINALLY {
1616+
if b.Type == py.TryBlockSetupFinally {
16191617
if vm.why == whyReturn || vm.why == whyContinue {
16201618
vm.PUSH(vm.retval)
16211619
}

0 commit comments

Comments
 (0)