Skip to content

Commit

Permalink
fix runtime
Browse files Browse the repository at this point in the history
* fix object type func
* rename Extend to ExtVar
  • Loading branch information
scottafk committed Mar 28, 2022
1 parent aaff519 commit 48e791e
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 98 deletions.
4 changes: 2 additions & 2 deletions packages/pb/vm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ enum ObjectType{
ExtFunc = 3;
// ObjectType_Var is a variable. myvar
Var = 4;
// ObjectType_Extend is an extended variable. $myvar
Extend = 5;
// ObjectType_ExtVar is an extended build in variable. $myvar
ExtVar = 5;
}
5 changes: 3 additions & 2 deletions packages/script/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package script

import (
"fmt"
"reflect"

"github.com/IBAX-io/go-ibax/packages/consts"
log "github.com/sirupsen/logrus"
"reflect"
)

type compileFunc func(*CodeBlocks, stateTypes, *Lexem) error
Expand Down Expand Up @@ -286,7 +287,7 @@ func fAssignVar(buf *CodeBlocks, state stateTypes, lexem *Lexem) error {
lexem.GetLogger().WithFields(log.Fields{"type": consts.ParseError, "lex_value": lexem.Value.(string)}).Error("modifying system variable")
return fmt.Errorf(eSysVar, lexem.Value.(string))
}
ivar = VarInfo{Obj: &ObjInfo{Type: ObjectType_Extend, Value: newObjInfoValue(lexem.Value.(string))}, Owner: nil}
ivar = VarInfo{Obj: &ObjInfo{Type: ObjectType_ExtVar, Value: newObjInfoValue(lexem.Value.(string))}, Owner: nil}
} else {
objInfo, tobj := findVar(lexem.Value.(string), buf)
if objInfo == nil || objInfo.Type != ObjectType_Var {
Expand Down
155 changes: 82 additions & 73 deletions packages/script/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,16 @@ func (rt *RunTime) callFunc(cmd uint16, obj *ObjInfo) (err error) {
return errWrongCountPars
}
for i, v := range finfo.Params {
switch v.String() {
case `string`, `int64`:
switch v.Kind() {
case reflect.String, reflect.Int64:
if v.Kind() == reflect.Int64 {
rv := reflect.ValueOf(rt.stack[len(rt.stack)-in+i])
switch rv.Kind() {
case reflect.Float64:
val, _ := converter.ValueToInt(rt.stack[len(rt.stack)-in+i])
rt.stack[len(rt.stack)-in+i] = val
}
}
if reflect.TypeOf(rt.stack[len(rt.stack)-in+i]) != v {
log.WithFields(log.Fields{"type": consts.VMError}).Error(eTypeParam)
return fmt.Errorf(eTypeParam, i+1)
Expand All @@ -196,85 +204,86 @@ func (rt *RunTime) callFunc(cmd uint16, obj *ObjInfo) (err error) {
rt.stack = append(rt.stack, imap)
}
_, err = rt.RunCode(obj.Value.CodeBlock())
} else {
finfo := obj.Value.ExtFuncInfo()
foo := reflect.ValueOf(finfo.Func)
var result []reflect.Value
pars := make([]reflect.Value, in)
limit := 0
var (
stack Stacker
ok bool
)
if stack, ok = rt.extend["sc"].(Stacker); ok {
if err := stack.AppendStack(finfo.Name); err != nil {
return err
}
}
rt.extend[`rt`] = rt
auto := 0
for k := 0; k < in; k++ {
if len(finfo.Auto[k]) > 0 {
auto++
}
}
shift := size - count + auto
if finfo.Variadic {
shift = size - count
count += auto
limit = count - in + 1
}
i := count
for ; i > limit; i-- {
if len(finfo.Auto[count-i]) > 0 {
pars[count-i] = reflect.ValueOf(rt.extend[finfo.Auto[count-i]])
auto--
} else {
pars[count-i] = reflect.ValueOf(rt.stack[size-i+auto])
}
if !pars[count-i].IsValid() {
pars[count-i] = reflect.Zero(reflect.TypeOf(string(``)))
}
}
if i > 0 {
pars[in-1] = reflect.ValueOf(rt.stack[size-i : size])
return
}

var (
stack Stacker
ok bool
result []reflect.Value
limit = 0
finfo = obj.Value.ExtFuncInfo()
foo = reflect.ValueOf(finfo.Func)
pars = make([]reflect.Value, in)
)
if stack, ok = rt.extend["sc"].(Stacker); ok {
if err := stack.AppendStack(finfo.Name); err != nil {
return err
}
if finfo.Name == `ExecContract` && (pars[2].Type().String() != `string` || !pars[3].IsValid()) {
return fmt.Errorf(`unknown function %v`, pars[1])
}
rt.extend[`rt`] = rt
auto := 0
for k := 0; k < in; k++ {
if len(finfo.Auto[k]) > 0 {
auto++
}
if finfo.Variadic {
result = foo.CallSlice(pars)
}
shift := size - count + auto
if finfo.Variadic {
shift = size - count
count += auto
limit = count - in + 1
}
i := count
for ; i > limit; i-- {
if len(finfo.Auto[count-i]) > 0 {
pars[count-i] = reflect.ValueOf(rt.extend[finfo.Auto[count-i]])
auto--
} else {
result = foo.Call(pars)
pars[count-i] = reflect.ValueOf(rt.stack[size-i+auto])
}
rt.stack = rt.stack[:shift]
if stack != nil {
stack.PopStack(finfo.Name)
if !pars[count-i].IsValid() {
pars[count-i] = reflect.Zero(reflect.TypeOf(``))
}
}
if i > 0 {
pars[in-1] = reflect.ValueOf(rt.stack[size-i : size])
}
if finfo.Name == `ExecContract` && (pars[2].Kind() != reflect.String || !pars[3].IsValid()) {
return fmt.Errorf(`unknown function %v`, pars[1])
}
if finfo.Variadic {
result = foo.CallSlice(pars)
} else {
result = foo.Call(pars)
}
rt.stack = rt.stack[:shift]
if stack != nil {
stack.PopStack(finfo.Name)
}

for i, iret := range result {
// first return value of every extend function that makes queries to DB is cost
if i == 0 && rt.vm.FuncCallsDB != nil {
if _, ok := rt.vm.FuncCallsDB[finfo.Name]; ok {
cost := iret.Int()
if cost > rt.cost {
rt.cost = 0
rt.vm.logger.WithFields(log.Fields{"type": consts.VMError}).Error("paid CPU resource is over")
return fmt.Errorf("paid CPU resource is over")
}

rt.cost -= cost
continue
for i, iret := range result {
// first return value of every extend function that makes queries to DB is cost
if i == 0 && rt.vm.FuncCallsDB != nil {
if _, ok := rt.vm.FuncCallsDB[finfo.Name]; ok {
cost := iret.Int()
if cost > rt.cost {
rt.cost = 0
rt.vm.logger.WithFields(log.Fields{"type": consts.VMError}).Error("paid CPU resource is over")
return fmt.Errorf("paid CPU resource is over")
}

rt.cost -= cost
continue
}
if finfo.Results[i].String() == `error` {
if iret.Interface() != nil {
rt.errInfo = ErrInfo{Name: finfo.Name}
return iret.Interface().(error)
}
} else {
rt.stack = append(rt.stack, iret.Interface())
}
if finfo.Results[i].String() == `error` {
if iret.Interface() != nil {
rt.errInfo = ErrInfo{Name: finfo.Name}
return iret.Interface().(error)
}
} else {
rt.stack = append(rt.stack, iret.Interface())
}
}
return
Expand Down Expand Up @@ -711,7 +720,7 @@ main:
count := len(assign)
for ivar, item := range assign {
if item.Owner == nil {
if (*item).Obj.Type == ObjectType_Extend {
if (*item).Obj.Type == ObjectType_ExtVar {
if isSysVar((*item).Obj.Value.String()) {
err = fmt.Errorf(eSysVar, (*item).Obj.Value.String())
rt.vm.logger.WithFields(log.Fields{"type": consts.VMError, "error": err}).Error("modifying system variable")
Expand Down
42 changes: 21 additions & 21 deletions packages/script/vm.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 48e791e

Please sign in to comment.