From 747cde816142cc737b0a7c0ce4fd45504611fcce Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 2 Sep 2009 12:03:20 -0700 Subject: [PATCH] s/vm/Thread/ change eval functions from taking *Frame to *Thread R=austin DELTA=500 (7 added, 4 deleted, 489 changed) OCL=34256 CL=34260 --- usr/austin/eval/abort.go | 24 +-- usr/austin/eval/bridge.go | 4 +- usr/austin/eval/eval_test.go | 14 +- usr/austin/eval/expr.go | 155 +++++++------- usr/austin/eval/expr1.go | 380 +++++++++++++++++------------------ usr/austin/eval/func.go | 15 +- usr/austin/eval/gen.go | 48 ++--- usr/austin/eval/stmt.go | 93 +++++---- usr/austin/eval/value.go | 2 +- 9 files changed, 369 insertions(+), 366 deletions(-) diff --git a/usr/austin/eval/abort.go b/usr/austin/eval/abort.go index 0b8022e963..521e51652b 100644 --- a/usr/austin/eval/abort.go +++ b/usr/austin/eval/abort.go @@ -39,49 +39,49 @@ func Try(f func()) os.Error { return res; } -type DivByZero struct {} +type DivByZeroError struct {} -func (DivByZero) String() string { +func (DivByZeroError) String() string { return "divide by zero"; } -type NilPointer struct {} +type NilPointerError struct {} -func (NilPointer) String() string { +func (NilPointerError) String() string { return "nil pointer dereference"; } -type IndexOutOfBounds struct { +type IndexError struct { Idx, Len int64; } -func (e IndexOutOfBounds) String() string { +func (e IndexError) String() string { if e.Idx < 0 { return fmt.Sprintf("negative index: %d", e.Idx); } return fmt.Sprintf("index %d exceeds length %d", e.Idx, e.Len); } -type KeyNotFound struct { +type KeyError struct { Key interface {}; } -func (e KeyNotFound) String() string { +func (e KeyError) String() string { return fmt.Sprintf("key '%v' not found in map", e.Key); } -type NegativeLength struct { +type NegativeLengthError struct { Len int64; } -func (e NegativeLength) String() string { +func (e NegativeLengthError) String() string { return fmt.Sprintf("negative length: %d", e.Len); } -type NegativeCapacity struct { +type NegativeCapacityError struct { Len int64; } -func (e NegativeCapacity) String() string { +func (e NegativeCapacityError) String() string { return fmt.Sprintf("negative capacity: %d", e.Len); } diff --git a/usr/austin/eval/bridge.go b/usr/austin/eval/bridge.go index f349135a05..41674860e2 100644 --- a/usr/austin/eval/bridge.go +++ b/usr/austin/eval/bridge.go @@ -146,8 +146,8 @@ func (f *nativeFunc) NewFrame() *Frame { return &Frame{nil, vars}; } -func (f *nativeFunc) Call(fr *Frame) { - f.fn(fr.Vars[0:f.in], fr.Vars[f.in:f.in+f.out]); +func (f *nativeFunc) Call(t *Thread) { + f.fn(t.f.Vars[0:f.in], t.f.Vars[f.in:f.in+f.out]); } // FuncFromNative creates an interpreter function from a native diff --git a/usr/austin/eval/eval_test.go b/usr/austin/eval/eval_test.go index e8619e137b..847a6f2fa7 100644 --- a/usr/austin/eval/eval_test.go +++ b/usr/austin/eval/eval_test.go @@ -277,12 +277,12 @@ func (*testFunc) NewFrame() *Frame { return &Frame{nil, &[2]Value {}}; } -func (*testFunc) Call(fr *Frame) { - n := fr.Vars[0].(IntValue).Get(); +func (*testFunc) Call(t *Thread) { + n := t.f.Vars[0].(IntValue).Get(); res := n + 1; - fr.Vars[1].(IntValue).Set(res); + t.f.Vars[1].(IntValue).Set(res); } type oneTwoFunc struct {}; @@ -291,9 +291,9 @@ func (*oneTwoFunc) NewFrame() *Frame { return &Frame{nil, &[2]Value {}}; } -func (*oneTwoFunc) Call(fr *Frame) { - fr.Vars[0].(IntValue).Set(1); - fr.Vars[1].(IntValue).Set(2); +func (*oneTwoFunc) Call(t *Thread) { + t.f.Vars[0].(IntValue).Set(1); + t.f.Vars[1].(IntValue).Set(2); } type voidFunc struct {}; @@ -302,7 +302,7 @@ func (*voidFunc) NewFrame() *Frame { return &Frame{nil, []Value {}}; } -func (*voidFunc) Call(fr *Frame) { +func (*voidFunc) Call(t *Thread) { } func newTestScope() *Scope { diff --git a/usr/austin/eval/expr.go b/usr/austin/eval/expr.go index 7f959d93d7..4415c84ed2 100644 --- a/usr/austin/eval/expr.go +++ b/usr/austin/eval/expr.go @@ -26,16 +26,16 @@ type expr struct { // Map index expressions permit special forms of assignment, // for which we need to know the Map and key. - evalMapValue func(f *Frame) (Map, interface{}); + evalMapValue func(t *Thread) (Map, interface{}); // Evaluate to the "address of" this value; that is, the // settable Value object. nil for expressions whose address // cannot be taken. - evalAddr func(f *Frame) Value; + evalAddr func(t *Thread) Value; // Execute this expression as a statement. Only expressions // that are valid expression statements should set this. - exec func(f *Frame); + exec func(t *Thread); // If this expression is a type, this is its compiled type. // This is only permitted in the function position of a call @@ -126,12 +126,12 @@ func (a *expr) convertTo(t Type) *expr { n, d := rat.Value(); f := n.Quo(bignum.MakeInt(false, d)); v := f.Abs().Value(); - res.eval = func(*Frame) uint64 { return v }; + res.eval = func(*Thread) uint64 { return v }; case *intType: n, d := rat.Value(); f := n.Quo(bignum.MakeInt(false, d)); v := f.Value(); - res.eval = func(*Frame) int64 { return v }; + res.eval = func(*Thread) int64 { return v }; case *idealIntType: n, d := rat.Value(); f := n.Quo(bignum.MakeInt(false, d)); @@ -139,7 +139,7 @@ func (a *expr) convertTo(t Type) *expr { case *floatType: n, d := rat.Value(); v := float64(n.Value())/float64(d.Value()); - res.eval = func(*Frame) float64 { return v }; + res.eval = func(*Thread) float64 { return v }; case *idealFloatType: res.eval = func() *bignum.Rational { return rat }; default: @@ -172,8 +172,8 @@ func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr { // Convert to int na := a.newExpr(IntType, a.desc); af := a.asUint(); - na.eval = func(f *Frame) int64 { - return int64(af(f)); + na.eval = func(t *Thread) int64 { + return int64(af(t)); }; return na; @@ -302,7 +302,7 @@ func (a *assignCompiler) allowMapForms(nls int) { // a function that expects an l-value and the frame in which to // evaluate the RHS expressions. The l-value must have exactly the // type given by lt. Returns nil if type checking fails. -func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) { +func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) { lmt, isMT := lt.(*MultiType); rmt, isUnpack := a.rmt, a.isUnpack; @@ -333,7 +333,7 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) { // multi-value and replace the RHS with expressions to pull // out values from the temporary. Technically, this is only // necessary when we need to perform assignment conversions. - var effect func(f *Frame); + var effect func(*Thread); if isUnpack { // This leaks a slot, but is definitely safe. temp := b.DefineSlot(a.rmt); @@ -341,20 +341,20 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) { if a.isMapUnpack { rf := a.rs[0].evalMapValue; vt := a.rmt.Elems[0]; - effect = func(f *Frame) { - m, k := rf(f); + effect = func(t *Thread) { + m, k := rf(t); v := m.Elem(k); found := boolV(true); if v == nil { found = boolV(false); v = vt.Zero(); } - f.Vars[tempIdx] = multiV([]Value {v, &found}); + t.f.Vars[tempIdx] = multiV([]Value {v, &found}); }; } else { rf := a.rs[0].asMulti(); - effect = func(f *Frame) { - f.Vars[tempIdx] = multiV(rf(f)); + effect = func(t *Thread) { + t.f.Vars[tempIdx] = multiV(rf(t)); }; } orig := a.rs[0]; @@ -365,7 +365,7 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) { } a.rs[i] = orig.newExpr(t, orig.desc); index := i; - a.rs[i].genValue(func(f *Frame) Value { return f.Vars[tempIdx].(multiV)[index] }); + a.rs[i].genValue(func(t *Thread) Value { return t.f.Vars[tempIdx].(multiV)[index] }); } } // Now len(a.rs) == len(a.rmt) and we've reduced any unpacking @@ -400,8 +400,8 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) { rf := a.rs[i].asPtr(); a.rs[i] = a.rs[i].newExpr(lt, a.rs[i].desc); len := at.Len; - a.rs[i].eval = func(f *Frame) Slice { - return Slice{rf(f).(ArrayValue), len, len}; + a.rs[i].eval = func(t *Thread) Slice { + return Slice{rf(t).(ArrayValue), len, len}; }; rt = a.rs[i].t; } @@ -428,17 +428,17 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) { return genAssign(lt, a.rs[0]); } // Case 2 or 3 - as := make([]func(lv Value, f *Frame), len(a.rs)); + as := make([]func(lv Value, t *Thread), len(a.rs)); for i, r := range a.rs { as[i] = genAssign(lmt.Elems[i], r); } - return func(lv Value, f *Frame) { + return func(lv Value, t *Thread) { if effect != nil { - effect(f); + effect(t); } lmv := lv.(multiV); for i, a := range as { - a(lmv[i], f); + a(lmv[i], t); } }; } @@ -446,7 +446,7 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) { // compileAssign compiles an assignment operation without the full // generality of an assignCompiler. See assignCompiler for a // description of the arguments. -func (a *compiler) compileAssign(pos token.Position, b *block, lt Type, rs []*expr, errOp, errPosName string) (func(lv Value, f *Frame)) { +func (a *compiler) compileAssign(pos token.Position, b *block, lt Type, rs []*expr, errOp, errPosName string) (func(Value, *Thread)) { ac, ok := a.checkAssign(pos, rs, errOp, errPosName); if !ok { return nil; @@ -758,7 +758,7 @@ func (a *exprInfo) compileString(s string) *expr { // TODO(austin) Use unnamed string type. expr := a.newExpr(StringType, "string literal"); - expr.eval = func(*Frame) string { return s }; + expr.eval = func(*Thread) string { return s }; return expr; } @@ -779,7 +779,7 @@ func (a *exprInfo) compileStringList(list []*expr) *expr { return a.compileString(strings.Join(ss, "")); } -func (a *exprInfo) compileFuncLit(decl *FuncDecl, fn func(f *Frame) Func) *expr { +func (a *exprInfo) compileFuncLit(decl *FuncDecl, fn func(*Thread) Func) *expr { expr := a.newExpr(decl.Type, "function literal"); expr.eval = fn; return expr; @@ -880,8 +880,8 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr { } expr := a.newExpr(ft, "selector expression"); pf := parent.asStruct(); - evalAddr := func(f *Frame) Value { - return pf(f).Field(index); + evalAddr := func(t *Thread) Value { + return pf(t).Field(index); }; expr.genValue(evalAddr); return sub(expr); @@ -964,10 +964,10 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr { lf := l.asArray(); rf := r.asInt(); bound := lt.Len; - expr.genValue(func(f *Frame) Value { - l, r := lf(f), rf(f); + expr.genValue(func(t *Thread) Value { + l, r := lf(t), rf(t); if r < 0 || r >= bound { - Abort(IndexOutOfBounds{r, bound}); + Abort(IndexError{r, bound}); } return l.Elem(r); }); @@ -975,13 +975,13 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr { case *SliceType: lf := l.asSlice(); rf := r.asInt(); - expr.genValue(func(f *Frame) Value { - l, r := lf(f), rf(f); + expr.genValue(func(t *Thread) Value { + l, r := lf(t), rf(t); if l.Base == nil { - Abort(NilPointer{}); + Abort(NilPointerError{}); } if r < 0 || r >= l.Len { - Abort(IndexOutOfBounds{r, l.Len}); + Abort(IndexError{r, l.Len}); } return l.Base.Elem(r); }); @@ -991,10 +991,10 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr { rf := r.asInt(); // TODO(austin) This pulls over the whole string in a // remote setting, instead of just the one character. - expr.eval = func(f *Frame) uint64 { - l, r := lf(f), rf(f); + expr.eval = func(t *Thread) uint64 { + l, r := lf(t), rf(t); if r < 0 || r >= int64(len(l)) { - Abort(IndexOutOfBounds{r, int64(len(l))}); + Abort(IndexError{r, int64(len(l))}); } return uint64(l[r]); } @@ -1002,24 +1002,24 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr { case *MapType: lf := l.asMap(); rf := r.asInterface(); - expr.genValue(func(f *Frame) Value { - m := lf(f); - k := rf(f); + expr.genValue(func(t *Thread) Value { + m := lf(t); + k := rf(t); if m == nil { - Abort(NilPointer{}); + Abort(NilPointerError{}); } e := m.Elem(k); if e == nil { - Abort(KeyNotFound{k}); + Abort(KeyError{k}); } return e; }); // genValue makes things addressable, but map values // aren't addressable. expr.evalAddr = nil; - expr.evalMapValue = func(f *Frame) (Map, interface{}) { + expr.evalMapValue = func(t *Thread) (Map, interface{}) { // TODO(austin) Key check? nil check? - return lf(f), rf(f); + return lf(t), rf(t); }; default: @@ -1080,14 +1080,17 @@ func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr { // Compile lf := l.asFunc(); - call := func(f *Frame) []Value { - fun := lf(f); + call := func(t *Thread) []Value { + fun := lf(t); fr := fun.NewFrame(); for i, t := range vts { fr.Vars[i] = t.Zero(); } - assign(multiV(fr.Vars[0:nin]), f); - fun.Call(fr); + assign(multiV(fr.Vars[0:nin]), t); + oldf := t.f; + t.f = fr; + fun.Call(t); + t.f = oldf; return fr.Vars[nin:nin+nout]; }; expr.genFuncCall(call); @@ -1119,14 +1122,14 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e // TODO(austin) It would be nice if this could // be a constant int. v := t.Len; - expr.eval = func(f *Frame) int64 { + expr.eval = func(t *Thread) int64 { return v; }; case *SliceType: vf := arg.asSlice(); - expr.eval = func(f *Frame) int64 { - return vf(f).Cap; + expr.eval = func(t *Thread) int64 { + return vf(t).Cap; }; //case *ChanType: @@ -1146,30 +1149,30 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e switch t := arg.t.lit().(type) { case *stringType: vf := arg.asString(); - expr.eval = func(f *Frame) int64 { - return int64(len(vf(f))); + expr.eval = func(t *Thread) int64 { + return int64(len(vf(t))); }; case *ArrayType: // TODO(austin) It would be nice if this could // be a constant int. v := t.Len; - expr.eval = func(f *Frame) int64 { + expr.eval = func(t *Thread) int64 { return v; }; case *SliceType: vf := arg.asSlice(); - expr.eval = func(f *Frame) int64 { - return vf(f).Len; + expr.eval = func(t *Thread) int64 { + return vf(t).Len; }; case *MapType: vf := arg.asMap(); - expr.eval = func(f *Frame) int64 { + expr.eval = func(t *Thread) int64 { // XXX(Spec) What's the len of an // uninitialized map? - m := vf(f); + m := vf(t); if m == nil { return 0; } @@ -1192,7 +1195,7 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e // arguments? Do they have to be ints? 6g // accepts any integral type. var lenexpr, capexpr *expr; - var lenf, capf func(f *Frame) int64; + var lenf, capf func(*Thread) int64; if len(as) > 1 { lenexpr = as[1].convertToInt(-1, "length", "make function"); if lenexpr == nil { @@ -1220,18 +1223,18 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e } et := t.Elem; expr := a.newExpr(t, "function call"); - expr.eval = func(f *Frame) Slice { - l := lenf(f); + expr.eval = func(t *Thread) Slice { + l := lenf(t); // XXX(Spec) What if len or cap is // negative? The runtime panics. if l < 0 { - Abort(NegativeLength{l}); + Abort(NegativeLengthError{l}); } c := l; if capf != nil { - c = capf(f); + c = capf(t); if c < 0 { - Abort(NegativeCapacity{c}); + Abort(NegativeCapacityError{c}); } // XXX(Spec) What happens if // len > cap? The runtime @@ -1257,11 +1260,11 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e return nil; } expr := a.newExpr(t, "function call"); - expr.eval = func(f *Frame) Map { + expr.eval = func(t *Thread) Map { if lenf == nil { return make(evalMap); } - l := lenf(f); + l := lenf(t); return make(evalMap, l); }; return expr; @@ -1287,10 +1290,10 @@ func (a *exprInfo) compileStarExpr(v *expr) *expr { case *PtrType: expr := a.newExpr(vt.Elem, "indirect expression"); vf := v.asPtr(); - expr.genValue(func(f *Frame) Value { - v := vf(f); + expr.genValue(func(t *Thread) Value { + v := vf(t); if v == nil { - Abort(NilPointer{}); + Abort(NilPointerError{}); } return v; }); @@ -1376,7 +1379,7 @@ func (a *exprInfo) compileUnaryExpr(op token.Token, v *expr) *expr { case token.AND: vf := v.evalAddr; - expr.eval = func(f *Frame) Value { return vf(f) }; + expr.eval = func(t *Thread) Value { return vf(t) }; default: log.Crashf("Compilation of unary op %v not implemented", op); @@ -1781,7 +1784,7 @@ func (a *compiler) compileExpr(b *block, constant bool, expr ast.Expr) *expr { // temporary variable, the caller should create a temporary block for // the compilation of this expression and the evaluation of the // results. -func (a *expr) extractEffect(b *block, errOp string) (func(f *Frame), *expr) { +func (a *expr) extractEffect(b *block, errOp string) (func(*Thread), *expr) { // Create "&a" if a is addressable rhs := a; if a.evalAddr != nil { @@ -1818,10 +1821,10 @@ func (a *expr) extractEffect(b *block, errOp string) (func(f *Frame), *expr) { log.Crashf("compileAssign type check failed"); } - effect := func(f *Frame) { + effect := func(t *Thread) { tempVal := tempType.Zero(); - f.Vars[tempIdx] = tempVal; - assign(tempVal, f); + t.f.Vars[tempIdx] = tempVal; + assign(tempVal, t); }; // Generate "temp" or "*temp" @@ -1850,6 +1853,8 @@ func (expr *Expr) Type() Type { } func (expr *Expr) Eval(f *Frame) (Value, os.Error) { + t := new(Thread); + t.f = f; switch _ := expr.e.t.(type) { case *idealIntType: return &idealIntV{expr.e.asIdealInt()()}, nil; @@ -1858,7 +1863,7 @@ func (expr *Expr) Eval(f *Frame) (Value, os.Error) { } v := expr.e.t.Zero(); eval := genAssign(expr.e.t, expr.e); - err := Try(func() {eval(v, f)}); + err := Try(func() {eval(v, t)}); return v, err; } diff --git a/usr/austin/eval/expr1.go b/usr/austin/eval/expr1.go index 1bbe87242c..dce004f40f 100644 --- a/usr/austin/eval/expr1.go +++ b/usr/austin/eval/expr1.go @@ -1,6 +1,6 @@ // This file is machine generated by gen.go. -// 6g gen.go && 6l gen.6 && 6.out >expr1.go +// 6g gen.go && 6l gen.6 && ./6.out >expr1.go package eval @@ -13,77 +13,77 @@ import ( * "As" functions. These retrieve evaluator functions from an * expr, panicking if the requested evaluator has the wrong type. */ -func (a *expr) asBool() (func(*Frame) bool) { - return a.eval.(func(*Frame)(bool)) +func (a *expr) asBool() (func(*Thread) bool) { + return a.eval.(func(*Thread)(bool)) } -func (a *expr) asUint() (func(*Frame) uint64) { - return a.eval.(func(*Frame)(uint64)) +func (a *expr) asUint() (func(*Thread) uint64) { + return a.eval.(func(*Thread)(uint64)) } -func (a *expr) asInt() (func(*Frame) int64) { - return a.eval.(func(*Frame)(int64)) +func (a *expr) asInt() (func(*Thread) int64) { + return a.eval.(func(*Thread)(int64)) } func (a *expr) asIdealInt() (func() *bignum.Integer) { return a.eval.(func()(*bignum.Integer)) } -func (a *expr) asFloat() (func(*Frame) float64) { - return a.eval.(func(*Frame)(float64)) +func (a *expr) asFloat() (func(*Thread) float64) { + return a.eval.(func(*Thread)(float64)) } func (a *expr) asIdealFloat() (func() *bignum.Rational) { return a.eval.(func()(*bignum.Rational)) } -func (a *expr) asString() (func(*Frame) string) { - return a.eval.(func(*Frame)(string)) +func (a *expr) asString() (func(*Thread) string) { + return a.eval.(func(*Thread)(string)) } -func (a *expr) asArray() (func(*Frame) ArrayValue) { - return a.eval.(func(*Frame)(ArrayValue)) +func (a *expr) asArray() (func(*Thread) ArrayValue) { + return a.eval.(func(*Thread)(ArrayValue)) } -func (a *expr) asStruct() (func(*Frame) StructValue) { - return a.eval.(func(*Frame)(StructValue)) +func (a *expr) asStruct() (func(*Thread) StructValue) { + return a.eval.(func(*Thread)(StructValue)) } -func (a *expr) asPtr() (func(*Frame) Value) { - return a.eval.(func(*Frame)(Value)) +func (a *expr) asPtr() (func(*Thread) Value) { + return a.eval.(func(*Thread)(Value)) } -func (a *expr) asFunc() (func(*Frame) Func) { - return a.eval.(func(*Frame)(Func)) +func (a *expr) asFunc() (func(*Thread) Func) { + return a.eval.(func(*Thread)(Func)) } -func (a *expr) asSlice() (func(*Frame) Slice) { - return a.eval.(func(*Frame)(Slice)) +func (a *expr) asSlice() (func(*Thread) Slice) { + return a.eval.(func(*Thread)(Slice)) } -func (a *expr) asMap() (func(*Frame) Map) { - return a.eval.(func(*Frame)(Map)) +func (a *expr) asMap() (func(*Thread) Map) { + return a.eval.(func(*Thread)(Map)) } -func (a *expr) asMulti() (func(*Frame) []Value) { - return a.eval.(func(*Frame)[]Value) +func (a *expr) asMulti() (func(*Thread) []Value) { + return a.eval.(func(*Thread)[]Value) } -func (a *expr) asInterface() (func(*Frame) interface{}) { +func (a *expr) asInterface() (func(*Thread) interface{}) { switch sf := a.eval.(type) { - case func(*Frame)bool: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)uint64: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)int64: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)*bignum.Integer: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)float64: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)*bignum.Rational: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)string: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)ArrayValue: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)StructValue: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)Value: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)Func: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)Slice: - return func(f *Frame) interface{} { return sf(f) } - case func(*Frame)Map: - return func(f *Frame) interface{} { return sf(f) } + case func(*Thread)bool: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)uint64: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)int64: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)*bignum.Integer: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)float64: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)*bignum.Rational: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)string: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)ArrayValue: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)StructValue: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)Value: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)Func: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)Slice: + return func(t *Thread) interface{} { return sf(t) } + case func(*Thread)Map: + return func(t *Thread) interface{} { return sf(t) } default: log.Crashf("unexpected expression node type %T at %v", a.eval, a.pos); } @@ -98,135 +98,135 @@ func (a *expr) genConstant(v Value) { switch _ := a.t.lit().(type) { case *boolType: val := v.(BoolValue).Get(); - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *uintType: val := v.(UintValue).Get(); - a.eval = func(f *Frame) uint64 { return val } + a.eval = func(t *Thread) uint64 { return val } case *intType: val := v.(IntValue).Get(); - a.eval = func(f *Frame) int64 { return val } + a.eval = func(t *Thread) int64 { return val } case *idealIntType: val := v.(IdealIntValue).Get(); a.eval = func() *bignum.Integer { return val } case *floatType: val := v.(FloatValue).Get(); - a.eval = func(f *Frame) float64 { return val } + a.eval = func(t *Thread) float64 { return val } case *idealFloatType: val := v.(IdealFloatValue).Get(); a.eval = func() *bignum.Rational { return val } case *stringType: val := v.(StringValue).Get(); - a.eval = func(f *Frame) string { return val } + a.eval = func(t *Thread) string { return val } case *ArrayType: val := v.(ArrayValue).Get(); - a.eval = func(f *Frame) ArrayValue { return val } + a.eval = func(t *Thread) ArrayValue { return val } case *StructType: val := v.(StructValue).Get(); - a.eval = func(f *Frame) StructValue { return val } + a.eval = func(t *Thread) StructValue { return val } case *PtrType: val := v.(PtrValue).Get(); - a.eval = func(f *Frame) Value { return val } + a.eval = func(t *Thread) Value { return val } case *FuncType: val := v.(FuncValue).Get(); - a.eval = func(f *Frame) Func { return val } + a.eval = func(t *Thread) Func { return val } case *SliceType: val := v.(SliceValue).Get(); - a.eval = func(f *Frame) Slice { return val } + a.eval = func(t *Thread) Slice { return val } case *MapType: val := v.(MapValue).Get(); - a.eval = func(f *Frame) Map { return val } + a.eval = func(t *Thread) Map { return val } default: log.Crashf("unexpected constant type %v at %v", a.t, a.pos); } } func (a *expr) genIdentOp(level, index int) { - a.evalAddr = func(f *Frame) Value { return f.Get(level, index) }; + a.evalAddr = func(t *Thread) Value { return t.f.Get(level, index) }; switch _ := a.t.lit().(type) { case *boolType: - a.eval = func(f *Frame) bool { return f.Get(level, index).(BoolValue).Get() } + a.eval = func(t *Thread) bool { return t.f.Get(level, index).(BoolValue).Get() } case *uintType: - a.eval = func(f *Frame) uint64 { return f.Get(level, index).(UintValue).Get() } + a.eval = func(t *Thread) uint64 { return t.f.Get(level, index).(UintValue).Get() } case *intType: - a.eval = func(f *Frame) int64 { return f.Get(level, index).(IntValue).Get() } + a.eval = func(t *Thread) int64 { return t.f.Get(level, index).(IntValue).Get() } case *floatType: - a.eval = func(f *Frame) float64 { return f.Get(level, index).(FloatValue).Get() } + a.eval = func(t *Thread) float64 { return t.f.Get(level, index).(FloatValue).Get() } case *stringType: - a.eval = func(f *Frame) string { return f.Get(level, index).(StringValue).Get() } + a.eval = func(t *Thread) string { return t.f.Get(level, index).(StringValue).Get() } case *ArrayType: - a.eval = func(f *Frame) ArrayValue { return f.Get(level, index).(ArrayValue).Get() } + a.eval = func(t *Thread) ArrayValue { return t.f.Get(level, index).(ArrayValue).Get() } case *StructType: - a.eval = func(f *Frame) StructValue { return f.Get(level, index).(StructValue).Get() } + a.eval = func(t *Thread) StructValue { return t.f.Get(level, index).(StructValue).Get() } case *PtrType: - a.eval = func(f *Frame) Value { return f.Get(level, index).(PtrValue).Get() } + a.eval = func(t *Thread) Value { return t.f.Get(level, index).(PtrValue).Get() } case *FuncType: - a.eval = func(f *Frame) Func { return f.Get(level, index).(FuncValue).Get() } + a.eval = func(t *Thread) Func { return t.f.Get(level, index).(FuncValue).Get() } case *SliceType: - a.eval = func(f *Frame) Slice { return f.Get(level, index).(SliceValue).Get() } + a.eval = func(t *Thread) Slice { return t.f.Get(level, index).(SliceValue).Get() } case *MapType: - a.eval = func(f *Frame) Map { return f.Get(level, index).(MapValue).Get() } + a.eval = func(t *Thread) Map { return t.f.Get(level, index).(MapValue).Get() } default: log.Crashf("unexpected identifier type %v at %v", a.t, a.pos); } } -func (a *expr) genFuncCall(call func(f *Frame) []Value) { - a.exec = func(f *Frame) { call(f)}; +func (a *expr) genFuncCall(call func(t *Thread) []Value) { + a.exec = func(t *Thread) { call(t)}; switch _ := a.t.lit().(type) { case *boolType: - a.eval = func(f *Frame) bool { return call(f)[0].(BoolValue).Get() } + a.eval = func(t *Thread) bool { return call(t)[0].(BoolValue).Get() } case *uintType: - a.eval = func(f *Frame) uint64 { return call(f)[0].(UintValue).Get() } + a.eval = func(t *Thread) uint64 { return call(t)[0].(UintValue).Get() } case *intType: - a.eval = func(f *Frame) int64 { return call(f)[0].(IntValue).Get() } + a.eval = func(t *Thread) int64 { return call(t)[0].(IntValue).Get() } case *floatType: - a.eval = func(f *Frame) float64 { return call(f)[0].(FloatValue).Get() } + a.eval = func(t *Thread) float64 { return call(t)[0].(FloatValue).Get() } case *stringType: - a.eval = func(f *Frame) string { return call(f)[0].(StringValue).Get() } + a.eval = func(t *Thread) string { return call(t)[0].(StringValue).Get() } case *ArrayType: - a.eval = func(f *Frame) ArrayValue { return call(f)[0].(ArrayValue).Get() } + a.eval = func(t *Thread) ArrayValue { return call(t)[0].(ArrayValue).Get() } case *StructType: - a.eval = func(f *Frame) StructValue { return call(f)[0].(StructValue).Get() } + a.eval = func(t *Thread) StructValue { return call(t)[0].(StructValue).Get() } case *PtrType: - a.eval = func(f *Frame) Value { return call(f)[0].(PtrValue).Get() } + a.eval = func(t *Thread) Value { return call(t)[0].(PtrValue).Get() } case *FuncType: - a.eval = func(f *Frame) Func { return call(f)[0].(FuncValue).Get() } + a.eval = func(t *Thread) Func { return call(t)[0].(FuncValue).Get() } case *SliceType: - a.eval = func(f *Frame) Slice { return call(f)[0].(SliceValue).Get() } + a.eval = func(t *Thread) Slice { return call(t)[0].(SliceValue).Get() } case *MapType: - a.eval = func(f *Frame) Map { return call(f)[0].(MapValue).Get() } + a.eval = func(t *Thread) Map { return call(t)[0].(MapValue).Get() } case *MultiType: - a.eval = func(f *Frame) []Value { return call(f) } + a.eval = func(t *Thread) []Value { return call(t) } default: log.Crashf("unexpected result type %v at %v", a.t, a.pos); } } -func (a *expr) genValue(vf func(*Frame) Value) { +func (a *expr) genValue(vf func(*Thread) Value) { a.evalAddr = vf; switch _ := a.t.lit().(type) { case *boolType: - a.eval = func(f *Frame) bool { return vf(f).(BoolValue).Get() } + a.eval = func(t *Thread) bool { return vf(t).(BoolValue).Get() } case *uintType: - a.eval = func(f *Frame) uint64 { return vf(f).(UintValue).Get() } + a.eval = func(t *Thread) uint64 { return vf(t).(UintValue).Get() } case *intType: - a.eval = func(f *Frame) int64 { return vf(f).(IntValue).Get() } + a.eval = func(t *Thread) int64 { return vf(t).(IntValue).Get() } case *floatType: - a.eval = func(f *Frame) float64 { return vf(f).(FloatValue).Get() } + a.eval = func(t *Thread) float64 { return vf(t).(FloatValue).Get() } case *stringType: - a.eval = func(f *Frame) string { return vf(f).(StringValue).Get() } + a.eval = func(t *Thread) string { return vf(t).(StringValue).Get() } case *ArrayType: - a.eval = func(f *Frame) ArrayValue { return vf(f).(ArrayValue).Get() } + a.eval = func(t *Thread) ArrayValue { return vf(t).(ArrayValue).Get() } case *StructType: - a.eval = func(f *Frame) StructValue { return vf(f).(StructValue).Get() } + a.eval = func(t *Thread) StructValue { return vf(t).(StructValue).Get() } case *PtrType: - a.eval = func(f *Frame) Value { return vf(f).(PtrValue).Get() } + a.eval = func(t *Thread) Value { return vf(t).(PtrValue).Get() } case *FuncType: - a.eval = func(f *Frame) Func { return vf(f).(FuncValue).Get() } + a.eval = func(t *Thread) Func { return vf(t).(FuncValue).Get() } case *SliceType: - a.eval = func(f *Frame) Slice { return vf(f).(SliceValue).Get() } + a.eval = func(t *Thread) Slice { return vf(t).(SliceValue).Get() } case *MapType: - a.eval = func(f *Frame) Map { return vf(f).(MapValue).Get() } + a.eval = func(t *Thread) Map { return vf(t).(MapValue).Get() } default: log.Crashf("unexpected result type %v at %v", a.t, a.pos); } @@ -236,17 +236,17 @@ func (a *expr) genUnaryOpNeg(v *expr) { switch _ := a.t.lit().(type) { case *uintType: vf := v.asUint(); - a.eval = func(f *Frame) uint64 { v := vf(f); return -v } + a.eval = func(t *Thread) uint64 { v := vf(t); return -v } case *intType: vf := v.asInt(); - a.eval = func(f *Frame) int64 { v := vf(f); return -v } + a.eval = func(t *Thread) int64 { v := vf(t); return -v } case *idealIntType: v := v.asIdealInt()(); val := v.Neg(); a.eval = func() *bignum.Integer { return val } case *floatType: vf := v.asFloat(); - a.eval = func(f *Frame) float64 { v := vf(f); return -v } + a.eval = func(t *Thread) float64 { v := vf(t); return -v } case *idealFloatType: v := v.asIdealFloat()(); val := v.Neg(); @@ -260,7 +260,7 @@ func (a *expr) genUnaryOpNot(v *expr) { switch _ := a.t.lit().(type) { case *boolType: vf := v.asBool(); - a.eval = func(f *Frame) bool { v := vf(f); return !v } + a.eval = func(t *Thread) bool { v := vf(t); return !v } default: log.Crashf("unexpected type %v at %v", a.t, a.pos); } @@ -270,10 +270,10 @@ func (a *expr) genUnaryOpXor(v *expr) { switch _ := a.t.lit().(type) { case *uintType: vf := v.asUint(); - a.eval = func(f *Frame) uint64 { v := vf(f); return ^v } + a.eval = func(t *Thread) uint64 { v := vf(t); return ^v } case *intType: vf := v.asInt(); - a.eval = func(f *Frame) int64 { v := vf(f); return ^v } + a.eval = func(t *Thread) int64 { v := vf(t); return ^v } case *idealIntType: v := v.asIdealInt()(); val := v.Neg().Sub(bignum.Int(1)); @@ -288,11 +288,11 @@ func (a *expr) genBinOpAdd(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l + r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l + r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l + r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l + r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -301,7 +301,7 @@ func (a *expr) genBinOpAdd(l, r *expr) { case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l + r } + a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); return l + r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); @@ -310,7 +310,7 @@ func (a *expr) genBinOpAdd(l, r *expr) { case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) string { l, r := lf(f), rf(f); return l + r } + a.eval = func(t *Thread) string { l, r := lf(t), rf(t); return l + r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } @@ -321,11 +321,11 @@ func (a *expr) genBinOpSub(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l - r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l - r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l - r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l - r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -334,7 +334,7 @@ func (a *expr) genBinOpSub(l, r *expr) { case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l - r } + a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); return l - r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); @@ -350,11 +350,11 @@ func (a *expr) genBinOpMul(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l * r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l * r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l * r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l * r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -363,7 +363,7 @@ func (a *expr) genBinOpMul(l, r *expr) { case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l * r } + a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); return l * r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); @@ -379,11 +379,11 @@ func (a *expr) genBinOpQuo(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l / r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l / r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l / r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l / r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -392,7 +392,7 @@ func (a *expr) genBinOpQuo(l, r *expr) { case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l / r } + a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l / r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); @@ -408,11 +408,11 @@ func (a *expr) genBinOpRem(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l % r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l % r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l % r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l % r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -428,11 +428,11 @@ func (a *expr) genBinOpAnd(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l & r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l & r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l & r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l & r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -448,11 +448,11 @@ func (a *expr) genBinOpOr(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l | r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l | r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l | r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l | r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -468,11 +468,11 @@ func (a *expr) genBinOpXor(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l ^ r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l ^ r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l ^ r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l ^ r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -488,11 +488,11 @@ func (a *expr) genBinOpAndNot(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l &^ r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l &^ r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l &^ r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l &^ r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); @@ -508,11 +508,11 @@ func (a *expr) genBinOpShl(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l << r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l << r } case *intType: lf := l.asInt(); rf := r.asUint(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l << r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l << r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } @@ -523,11 +523,11 @@ func (a *expr) genBinOpShr(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l >> r } + a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l >> r } case *intType: lf := l.asInt(); rf := r.asUint(); - a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l >> r } + a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l >> r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } @@ -538,29 +538,29 @@ func (a *expr) genBinOpLss(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) < 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) < 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } @@ -571,29 +571,29 @@ func (a *expr) genBinOpGtr(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) > 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) > 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } @@ -604,29 +604,29 @@ func (a *expr) genBinOpLeq(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) <= 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) <= 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } @@ -637,29 +637,29 @@ func (a *expr) genBinOpGeq(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) >= 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) >= 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } @@ -670,45 +670,45 @@ func (a *expr) genBinOpEql(l, r *expr) { case *boolType: lf := l.asBool(); rf := r.asBool(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r } case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) == 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) == 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r } case *PtrType: lf := l.asPtr(); rf := r.asPtr(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r } case *FuncType: lf := l.asFunc(); rf := r.asFunc(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r } case *MapType: lf := l.asMap(); rf := r.asMap(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } @@ -719,85 +719,85 @@ func (a *expr) genBinOpNeq(l, r *expr) { case *boolType: lf := l.asBool(); rf := r.asBool(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r } case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) != 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) != 0; - a.eval = func(f *Frame) bool { return val } + a.eval = func(t *Thread) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r } case *PtrType: lf := l.asPtr(); rf := r.asPtr(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r } case *FuncType: lf := l.asFunc(); rf := r.asFunc(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r } case *MapType: lf := l.asMap(); rf := r.asMap(); - a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } + a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r } default: log.Crashf("unexpected type %v at %v", l.t, a.pos); } } -func genAssign(lt Type, r *expr) (func(lv Value, f *Frame)) { +func genAssign(lt Type, r *expr) (func(lv Value, t *Thread)) { switch _ := lt.lit().(type) { case *boolType: rf := r.asBool(); - return func(lv Value, f *Frame) { lv.(BoolValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(BoolValue).Set(rf(t)) } case *uintType: rf := r.asUint(); - return func(lv Value, f *Frame) { lv.(UintValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(UintValue).Set(rf(t)) } case *intType: rf := r.asInt(); - return func(lv Value, f *Frame) { lv.(IntValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(IntValue).Set(rf(t)) } case *floatType: rf := r.asFloat(); - return func(lv Value, f *Frame) { lv.(FloatValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(FloatValue).Set(rf(t)) } case *stringType: rf := r.asString(); - return func(lv Value, f *Frame) { lv.(StringValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(StringValue).Set(rf(t)) } case *ArrayType: rf := r.asArray(); - return func(lv Value, f *Frame) { lv.Assign(rf(f)) } + return func(lv Value, t *Thread) { lv.Assign(rf(t)) } case *StructType: rf := r.asStruct(); - return func(lv Value, f *Frame) { lv.Assign(rf(f)) } + return func(lv Value, t *Thread) { lv.Assign(rf(t)) } case *PtrType: rf := r.asPtr(); - return func(lv Value, f *Frame) { lv.(PtrValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(PtrValue).Set(rf(t)) } case *FuncType: rf := r.asFunc(); - return func(lv Value, f *Frame) { lv.(FuncValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(FuncValue).Set(rf(t)) } case *SliceType: rf := r.asSlice(); - return func(lv Value, f *Frame) { lv.(SliceValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(SliceValue).Set(rf(t)) } case *MapType: rf := r.asMap(); - return func(lv Value, f *Frame) { lv.(MapValue).Set(rf(f)) } + return func(lv Value, t *Thread) { lv.(MapValue).Set(rf(t)) } default: log.Crashf("unexpected left operand type %v at %v", lt, r.pos); } diff --git a/usr/austin/eval/func.go b/usr/austin/eval/func.go index 2281b644d4..d13fbbed40 100644 --- a/usr/austin/eval/func.go +++ b/usr/austin/eval/func.go @@ -8,18 +8,17 @@ package eval * Virtual machine */ -type vm struct { +type Thread struct { pc uint; // The execution frame of this function. This remains the // same throughout a function invocation. f *Frame; } -type code []func(*vm) - -func (i code) exec(fr *Frame) { - v := vm{0, fr}; +type code []func(*Thread) +func (i code) exec(t *Thread) { + v := Thread{0, t.f}; // TODO: reuse t l := uint(len(i)); for v.pc < l { pc := v.pc; @@ -40,7 +39,7 @@ func newCodeBuf() *codeBuf { return &codeBuf{make(code, 0, 16)}; } -func (b *codeBuf) push(instr func(*vm)) { +func (b *codeBuf) push(instr func(*Thread)) { n := len(b.instrs); if n >= cap(b.instrs) { a := make(code, n, n*2); @@ -80,6 +79,6 @@ func (f *evalFunc) NewFrame() *Frame { return f.outer.child(f.frameSize); } -func (f *evalFunc) Call(fr *Frame) { - f.code.exec(fr); +func (f *evalFunc) Call(t *Thread) { + f.code.exec(t); } diff --git a/usr/austin/eval/gen.go b/usr/austin/eval/gen.go index c9b5ab6e3b..a9d088db8c 100644 --- a/usr/austin/eval/gen.go +++ b/usr/austin/eval/gen.go @@ -91,12 +91,12 @@ var binOps = []Op{ Op{ Name: "Sub", Expr: "l - r", ConstExpr: "l.Sub(r)", Types: numbers }, Op{ Name: "Mul", Expr: "l * r", ConstExpr: "l.Mul(r)", Types: numbers }, Op{ Name: "Quo", - Body: "if r == 0 { Abort(DivByZero{}) } return l / r", + Body: "if r == 0 { Abort(DivByZeroError{}) } return l / r", ConstExpr: "l.Quo(r)", Types: numbers, }, Op{ Name: "Rem", - Body: "if r == 0 { Abort(DivByZero{}) } return l % r", + Body: "if r == 0 { Abort(DivByZeroError{}) } return l % r", ConstExpr: "l.Rem(r)", Types: integers, }, @@ -151,23 +151,23 @@ func (a *expr) «As»() (func() «Native») { return a.eval.(func()(«Native»)) } «.or» -func (a *expr) «As»() (func(*Frame) «Native») { - return a.eval.(func(*Frame)(«Native»)) +func (a *expr) «As»() (func(*Thread) «Native») { + return a.eval.(func(*Thread)(«Native»)) } «.end» «.end» -func (a *expr) asMulti() (func(*Frame) []Value) { - return a.eval.(func(*Frame)[]Value) +func (a *expr) asMulti() (func(*Thread) []Value) { + return a.eval.(func(*Thread)[]Value) } -func (a *expr) asInterface() (func(*Frame) interface{}) { +func (a *expr) asInterface() (func(*Thread) interface{}) { switch sf := a.eval.(type) { «.repeated section Types» - case func(*Frame)«Native»: + case func(*Thread)«Native»: «.section IsIdeal» - return func(f *Frame) interface{} { return sf(f) } + return func(t *Thread) interface{} { return sf(t) } «.or» - return func(f *Frame) interface{} { return sf(f) } + return func(t *Thread) interface{} { return sf(t) } «.end» «.end» default: @@ -188,7 +188,7 @@ func (a *expr) genConstant(v Value) { «.section IsIdeal» a.eval = func() «Native» { return val } «.or» - a.eval = func(f *Frame) «Native» { return val } + a.eval = func(t *Thread) «Native» { return val } «.end» «.end» default: @@ -197,13 +197,13 @@ func (a *expr) genConstant(v Value) { } func (a *expr) genIdentOp(level, index int) { - a.evalAddr = func(f *Frame) Value { return f.Get(level, index) }; + a.evalAddr = func(t *Thread) Value { return t.f.Get(level, index) }; switch _ := a.t.lit().(type) { «.repeated section Types» «.section IsIdeal» «.or» case «Repr»: - a.eval = func(f *Frame) «Native» { return f.Get(level, index).(«Value»).Get() } + a.eval = func(t *Thread) «Native» { return t.f.Get(level, index).(«Value»).Get() } «.end» «.end» default: @@ -211,31 +211,31 @@ func (a *expr) genIdentOp(level, index int) { } } -func (a *expr) genFuncCall(call func(f *Frame) []Value) { - a.exec = func(f *Frame) { call(f)}; +func (a *expr) genFuncCall(call func(t *Thread) []Value) { + a.exec = func(t *Thread) { call(t)}; switch _ := a.t.lit().(type) { «.repeated section Types» «.section IsIdeal» «.or» case «Repr»: - a.eval = func(f *Frame) «Native» { return call(f)[0].(«Value»).Get() } + a.eval = func(t *Thread) «Native» { return call(t)[0].(«Value»).Get() } «.end» «.end» case *MultiType: - a.eval = func(f *Frame) []Value { return call(f) } + a.eval = func(t *Thread) []Value { return call(t) } default: log.Crashf("unexpected result type %v at %v", a.t, a.pos); } } -func (a *expr) genValue(vf func(*Frame) Value) { +func (a *expr) genValue(vf func(*Thread) Value) { a.evalAddr = vf; switch _ := a.t.lit().(type) { «.repeated section Types» «.section IsIdeal» «.or» case «Repr»: - a.eval = func(f *Frame) «Native» { return vf(f).(«Value»).Get() } + a.eval = func(t *Thread) «Native» { return vf(t).(«Value»).Get() } «.end» «.end» default: @@ -254,7 +254,7 @@ func (a *expr) genUnaryOp«Name»(v *expr) { a.eval = func() «Native» { return val } «.or» vf := v.«As»(); - a.eval = func(f *Frame) «Native» { v := vf(f); return «Expr» } + a.eval = func(t *Thread) «Native» { v := vf(t); return «Expr» } «.end» «.end» default: @@ -273,14 +273,14 @@ func (a *expr) genBinOp«Name»(l, r *expr) { r := r.«As»()(); val := «ConstExpr»; «.section ReturnType» - a.eval = func(f *Frame) «ReturnType» { return val } + a.eval = func(t *Thread) «ReturnType» { return val } «.or» a.eval = func() «Native» { return val } «.end» «.or» lf := l.«As»(); rf := r.«.section AsRightName»«@»«.or»«As»«.end»(); - a.eval = func(f *Frame) «.section ReturnType»«@»«.or»«Native»«.end» { l, r := lf(f), rf(f); «.section Body»«Body»«.or»return «Expr»«.end» } + a.eval = func(t *Thread) «.section ReturnType»«@»«.or»«Native»«.end» { l, r := lf(t), rf(t); «.section Body»«Body»«.or»return «Expr»«.end» } «.end» «.end» default: @@ -289,14 +289,14 @@ func (a *expr) genBinOp«Name»(l, r *expr) { } «.end» -func genAssign(lt Type, r *expr) (func(lv Value, f *Frame)) { +func genAssign(lt Type, r *expr) (func(lv Value, t *Thread)) { switch _ := lt.lit().(type) { «.repeated section Types» «.section IsIdeal» «.or» case «Repr»: rf := r.«As»(); - return func(lv Value, f *Frame) { «.section HasAssign»lv.Assign(rf(f))«.or»lv.(«Value»).Set(rf(f))«.end» } + return func(lv Value, t *Thread) { «.section HasAssign»lv.Assign(rf(t))«.or»lv.(«Value»).Set(rf(t))«.end» } «.end» «.end» default: diff --git a/usr/austin/eval/stmt.go b/usr/austin/eval/stmt.go index 9002b980f5..50a776e35e 100644 --- a/usr/austin/eval/stmt.go +++ b/usr/austin/eval/stmt.go @@ -230,7 +230,7 @@ func (a *stmtCompiler) defineVar(ident *ast.Ident, t Type) *Variable { // Initialize the variable index := v.Index; - a.push(func(v *vm) { + a.push(func(v *Thread) { v.f.Vars[index] = t.Zero(); }); return v; @@ -416,10 +416,7 @@ func (a *stmtCompiler) compileExprStmt(s *ast.ExprStmt) { return; } - exec := e.exec; - a.push(func(v *vm) { - exec(v.f); - }); + a.push(e.exec); } func (a *stmtCompiler) compileIncDecStmt(s *ast.IncDecStmt) { @@ -471,9 +468,9 @@ func (a *stmtCompiler) compileIncDecStmt(s *ast.IncDecStmt) { } lf := l.evalAddr; - a.push(func(v *vm) { - effect(v.f); - assign(lf(v.f), v.f); + a.push(func(v *Thread) { + effect(v); + assign(lf(v), v); }); } @@ -605,8 +602,8 @@ func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token, ls[i].evalMapValue = sub.evalMapValue; mvf := sub.evalMapValue; et := sub.t; - ls[i].evalAddr = func(f *Frame) Value { - m, k := mvf(f); + ls[i].evalAddr = func(t *Thread) Value { + m, k := mvf(t); e := m.Elem(k); if e == nil { e = et.Zero(); @@ -666,35 +663,35 @@ func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token, if n == 1 { // Don't need temporaries and can avoid []Value. lf := ls[0].evalAddr; - a.push(func(v *vm) { assign(lf(v.f), v.f) }); + a.push(func(t *Thread) { assign(lf(t), t) }); } else if tok == token.VAR || (tok == token.DEFINE && nDefs == n) { // Don't need temporaries - lfs := make([]func(*Frame) Value, n); + lfs := make([]func(*Thread) Value, n); for i, l := range ls { lfs[i] = l.evalAddr; } - a.push(func(v *vm) { + a.push(func(t *Thread) { dest := make([]Value, n); for i, lf := range lfs { - dest[i] = lf(v.f); + dest[i] = lf(t); } - assign(multiV(dest), v.f); + assign(multiV(dest), t); }); } else { // Need temporaries lmt := lt.(*MultiType); - lfs := make([]func(*Frame) Value, n); + lfs := make([]func(*Thread) Value, n); for i, l := range ls { lfs[i] = l.evalAddr; } - a.push(func(v *vm) { + a.push(func(t *Thread) { temp := lmt.Zero().(multiV); - assign(temp, v.f); + assign(temp, t); // Copy to destination for i := 0; i < n; i ++ { // TODO(austin) Need to evaluate LHS // before RHS - lfs[i](v.f).Assign(temp[i]); + lfs[i](t).Assign(temp[i]); } }); } @@ -749,9 +746,9 @@ func (a *stmtCompiler) doAssignOp(s *ast.AssignStmt) { } lf := l.evalAddr; - a.push(func(v *vm) { - effect(v.f); - assign(lf(v.f), v.f); + a.push(func(t *Thread) { + effect(t); + assign(lf(t), t); }); } @@ -774,7 +771,7 @@ func (a *stmtCompiler) compileReturnStmt(s *ast.ReturnStmt) { if len(s.Results) == 0 && (len(a.fnType.Out) == 0 || a.outVarsNamed) { // Simple case. Simply exit from the function. a.flow.putTerm(); - a.push(func(v *vm) { v.pc = returnPC }); + a.push(func(v *Thread) { v.pc = returnPC }); return; } @@ -810,9 +807,9 @@ func (a *stmtCompiler) compileReturnStmt(s *ast.ReturnStmt) { start := len(a.fnType.In); nout := len(a.fnType.Out); a.flow.putTerm(); - a.push(func(v *vm) { - assign(multiV(v.f.Vars[start:start+nout]), v.f); - v.pc = returnPC; + a.push(func(t *Thread) { + assign(multiV(t.f.Vars[start:start+nout]), t); + t.pc = returnPC; }); } @@ -880,7 +877,7 @@ func (a *stmtCompiler) compileBranchStmt(s *ast.BranchStmt) { } a.flow.put1(false, pc); - a.push(func(v *vm) { v.pc = *pc }); + a.push(func(v *Thread) { v.pc = *pc }); } func (a *stmtCompiler) compileBlockStmt(s *ast.BlockStmt) { @@ -923,9 +920,9 @@ func (a *stmtCompiler) compileIfStmt(s *ast.IfStmt) { default: eval := e.asBool(); a.flow.put1(true, &elsePC); - a.push(func(v *vm) { - if !eval(v.f) { - v.pc = elsePC; + a.push(func(t *Thread) { + if !eval(t) { + t.pc = elsePC; } }); } @@ -940,7 +937,7 @@ func (a *stmtCompiler) compileIfStmt(s *ast.IfStmt) { if s.Else != nil { // Skip over else if we executed the body a.flow.put1(false, &endPC); - a.push(func(v *vm) { + a.push(func(v *Thread) { v.pc = endPC; }); elsePC = a.nextPC(); @@ -967,9 +964,9 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) { if s.Tag != nil { e := condbc.compileExpr(condbc.block, false, s.Tag); if e != nil { - var effect func(f *Frame); + var effect func(*Thread); effect, cond = e.extractEffect(condbc.block, "switch"); - a.push(func(v *vm) { effect(v.f) }); + a.push(effect); } } @@ -993,7 +990,7 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) { } // Compile case expressions - cases := make([]func(f *Frame) bool, ncases); + cases := make([]func(*Thread) bool, ncases); i := 0; for _, c := range s.Body.List { clause, ok := c.(*ast.CaseClause); @@ -1026,14 +1023,14 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) { endPC := badPC; a.flow.put(false, false, casePCs); - a.push(func(v *vm) { + a.push(func(t *Thread) { for i, c := range cases { - if c(v.f) { - v.pc = *casePCs[i]; + if c(t) { + t.pc = *casePCs[i]; return; } } - v.pc = *casePCs[ncases]; + t.pc = *casePCs[ncases]; }); condbc.exit(); @@ -1083,7 +1080,7 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) { // Jump out of switch, unless there was a fallthrough if !fall { a.flow.put1(false, &endPC); - a.push(func(v *vm) { v.pc = endPC }); + a.push(func(v *Thread) { v.pc = endPC }); } } @@ -1112,7 +1109,7 @@ func (a *stmtCompiler) compileForStmt(s *ast.ForStmt) { // Jump to condition check. We generate slightly less code by // placing the condition check after the body. a.flow.put1(false, &checkPC); - a.push(func(v *vm) { v.pc = checkPC }); + a.push(func(v *Thread) { v.pc = checkPC }); // Compile body bodyPC = a.nextPC(); @@ -1141,7 +1138,7 @@ func (a *stmtCompiler) compileForStmt(s *ast.ForStmt) { if s.Cond == nil { // If the condition is absent, it is equivalent to true. a.flow.put1(false, &bodyPC); - a.push(func(v *vm) { v.pc = bodyPC }); + a.push(func(v *Thread) { v.pc = bodyPC }); } else { e := bc.compileExpr(bc.block, false, s.Cond); switch { @@ -1152,9 +1149,9 @@ func (a *stmtCompiler) compileForStmt(s *ast.ForStmt) { default: eval := e.asBool(); a.flow.put1(true, &bodyPC); - a.push(func(v *vm) { - if eval(v.f) { - v.pc = bodyPC; + a.push(func(t *Thread) { + if eval(t) { + t.pc = bodyPC; } }); } @@ -1195,7 +1192,7 @@ func (a *blockCompiler) exit() { * Function compiler */ -func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (func (f *Frame) Func) { +func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (func (*Thread) Func) { // Create body scope // // The scope of a parameter or result is the body of the @@ -1250,7 +1247,7 @@ func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (f code := fc.get(); maxVars := bodyScope.maxVars; - return func(f *Frame) Func { return &evalFunc{f, maxVars, code} }; + return func(t *Thread) Func { return &evalFunc{t.f, maxVars, code} }; } // Checks that labels were resolved and that all jumps obey scoping @@ -1282,7 +1279,9 @@ type Stmt struct { } func (s *Stmt) Exec(f *Frame) os.Error { - return Try(func() {s.code.exec(f)}); + t := new(Thread); + t.f = f; + return Try(func() {s.code.exec(t)}); } func CompileStmts(scope *Scope, stmts []ast.Stmt) (*Stmt, os.Error) { diff --git a/usr/austin/eval/value.go b/usr/austin/eval/value.go index b40d1aac92..abb2ab0d5e 100644 --- a/usr/austin/eval/value.go +++ b/usr/austin/eval/value.go @@ -87,7 +87,7 @@ type PtrValue interface { type Func interface { NewFrame() *Frame; - Call(*Frame); + Call(*Thread); } type FuncValue interface { -- 2.48.1