Skip to content

Commit 71b9c99

Browse files
committed
change code block interface to struct
1 parent 6cc27b8 commit 71b9c99

File tree

16 files changed

+150
-133
lines changed

16 files changed

+150
-133
lines changed

packages/api/login.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"github.com/IBAX-io/go-ibax/packages/consts"
2121
"github.com/IBAX-io/go-ibax/packages/converter"
2222
"github.com/IBAX-io/go-ibax/packages/publisher"
23-
"github.com/IBAX-io/go-ibax/packages/script"
2423
"github.com/IBAX-io/go-ibax/packages/smart"
2524
"github.com/IBAX-io/go-ibax/packages/storage/sqldb"
2625
"github.com/IBAX-io/go-ibax/packages/transaction"
@@ -170,7 +169,7 @@ func (m Mode) loginHandler(w http.ResponseWriter, r *http.Request) {
170169
contract := smart.GetContract("NewUser", 1)
171170
sc := types.SmartContract{
172171
Header: &types.Header{
173-
ID: int(contract.Block.Info.(*script.ContractInfo).ID),
172+
ID: int(contract.Info().ID),
174173
Time: time.Now().Unix(),
175174
EcosystemID: 1,
176175
KeyID: conf.Config.KeyID,

packages/script/code_block.go

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,24 @@ type CodeBlock struct {
2727
Objects map[string]*ObjInfo
2828
Type ObjectType
2929
Owner *OwnerInfo
30-
Info interface{}
30+
Info *codeBlockInfo
3131
Parent *CodeBlock
3232
Vars []reflect.Type
3333
Code ByteCodes
3434
Children CodeBlocks
3535
}
3636

37+
type codeBlockInfo struct{ i interface{} }
38+
39+
func newCodeBlockInfo(i interface{}) *codeBlockInfo { return &codeBlockInfo{i: i} }
40+
func (i *codeBlockInfo) FuncInfo() *FuncInfo { return i.i.(*FuncInfo) }
41+
func (i *codeBlockInfo) Uint32() uint32 { return i.i.(uint32) }
42+
func (i *codeBlockInfo) ContractInfo() *ContractInfo { return i.i.(*ContractInfo) }
43+
func (i *codeBlockInfo) IsContractInfo() (*ContractInfo, bool) {
44+
v, ok := i.i.(*ContractInfo)
45+
return v, ok
46+
}
47+
3748
// ByteCode stores a command and an additional parameter.
3849
type ByteCode struct {
3950
Cmd uint16
@@ -94,9 +105,17 @@ type OwnerInfo struct {
94105
// ObjInfo is the common object type
95106
type ObjInfo struct {
96107
Type ObjectType
97-
Value interface{}
108+
Value *objInfoValue
98109
}
99110

111+
type objInfoValue struct{ v interface{} }
112+
113+
func newObjInfoValue(v interface{}) *objInfoValue { return &objInfoValue{v: v} }
114+
func (i *objInfoValue) CodeBlock() *CodeBlock { return i.v.(*CodeBlock) }
115+
func (i *objInfoValue) ExtFuncInfo() *ExtFuncInfo { return i.v.(*ExtFuncInfo) }
116+
func (i *objInfoValue) Int() int { return i.v.(int) }
117+
func (i *objInfoValue) String() string { return i.v.(string) }
118+
100119
func NewCodeBlock() *CodeBlock {
101120
b := &CodeBlock{
102121
Objects: make(map[string]*ObjInfo),
@@ -114,7 +133,7 @@ func (b *CodeBlock) Extend(ext *ExtendData) {
114133
switch fobj.Kind() {
115134
case reflect.Func:
116135
_, canWrite := ext.WriteFuncs[key]
117-
data := ExtFuncInfo{
136+
data := &ExtFuncInfo{
118137
Name: key,
119138
Params: make([]reflect.Type, fobj.NumIn()),
120139
Results: make([]reflect.Type, fobj.NumOut()),
@@ -131,7 +150,7 @@ func (b *CodeBlock) Extend(ext *ExtendData) {
131150
for i := 0; i < fobj.NumOut(); i++ {
132151
data.Results[i] = fobj.Out(i)
133152
}
134-
b.Objects[key] = &ObjInfo{Type: ObjectType_ExtFunc, Value: data}
153+
b.Objects[key] = &ObjInfo{Type: ObjectType_ExtFunc, Value: newObjInfoValue(data)}
135154
}
136155
}
137156
}
@@ -158,13 +177,14 @@ func (block *CodeBlock) getObjByName(name string) (ret *ObjInfo) {
158177
if ret.Type != ObjectType_Contract && ret.Type != ObjectType_Func {
159178
return nil
160179
}
161-
block = ret.Value.(*CodeBlock)
180+
block = ret.Value.CodeBlock()
162181
}
163182
return
164183
}
184+
165185
func (block *CodeBlock) parentContractCost() int64 {
166186
var cost int64
167-
if parent, ok := block.Parent.Info.(*ContractInfo); ok {
187+
if parent, ok := block.Parent.Info.IsContractInfo(); ok {
168188
cost += int64(len(block.Parent.Objects) * CostCall)
169189
cost += int64(len(parent.Settings) * CostCall)
170190
if parent.Tx != nil {
@@ -185,16 +205,16 @@ func setWritable(block *CodeBlocks) {
185205
for i := len(*block) - 1; i >= 0; i-- {
186206
blockItem := (*block)[i]
187207
if blockItem.Type == ObjectType_Func {
188-
blockItem.Info.(*FuncInfo).CanWrite = true
208+
blockItem.Info.FuncInfo().CanWrite = true
189209
}
190210
if blockItem.Type == ObjectType_Contract {
191-
blockItem.Info.(*ContractInfo).CanWrite = true
211+
blockItem.Info.ContractInfo().CanWrite = true
192212
}
193213
}
194214
}
195215
func (ret *ObjInfo) getInParams() int {
196216
if ret.Type == ObjectType_ExtFunc {
197-
return len(ret.Value.(ExtFuncInfo).Params)
217+
return len(ret.Value.ExtFuncInfo().Params)
198218
}
199-
return len(ret.Value.(*CodeBlock).Info.(*FuncInfo).Params)
219+
return len(ret.Value.CodeBlock().Info.FuncInfo().Params)
200220
}

packages/script/compile.go

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func StateName(state uint32, name string) string {
9898

9999
// CompileBlock compile the source code into the CodeBlock structure with a byte-code
100100
func (vm *VM) CompileBlock(input []rune, owner *OwnerInfo) (*CodeBlock, error) {
101-
root := &CodeBlock{Info: owner.StateID, Owner: owner}
101+
root := &CodeBlock{Info: newCodeBlockInfo(owner.StateID), Owner: owner}
102102
lexems, err := lexParser(input)
103103
if err != nil {
104104
return nil, err
@@ -195,8 +195,8 @@ func (vm *VM) CompileBlock(input []rune, owner *OwnerInfo) (*CodeBlock, error) {
195195
}
196196
for _, item := range root.Objects {
197197
if item.Type == ObjectType_Contract {
198-
if cond, ok := item.Value.(*CodeBlock).Objects[`conditions`]; ok {
199-
if cond.Type == ObjectType_Func && cond.Value.(*CodeBlock).Info.(*FuncInfo).CanWrite {
198+
if cond, ok := item.Value.CodeBlock().Objects[`conditions`]; ok {
199+
if cond.Type == ObjectType_Func && cond.Value.CodeBlock().Info.FuncInfo().CanWrite {
200200
return nil, errCondWrite
201201
}
202202
}
@@ -212,9 +212,9 @@ func (vm *VM) FlushBlock(root *CodeBlock) {
212212
if cur, ok := vm.Objects[key]; ok {
213213
switch item.Type {
214214
case ObjectType_Contract:
215-
root.Objects[key].Value.(*CodeBlock).Info.(*ContractInfo).ID = cur.Value.(*CodeBlock).Info.(*ContractInfo).ID + flushMark
215+
root.Objects[key].Value.CodeBlock().Info.ContractInfo().ID = cur.Value.CodeBlock().Info.ContractInfo().ID + flushMark
216216
case ObjectType_Func:
217-
root.Objects[key].Value.(*CodeBlock).Info.(*FuncInfo).ID = cur.Value.(*CodeBlock).Info.(*FuncInfo).ID + flushMark
217+
root.Objects[key].Value.CodeBlock().Info.FuncInfo().ID = cur.Value.CodeBlock().Info.FuncInfo().ID + flushMark
218218
vm.Objects[key].Value = root.Objects[key].Value
219219
}
220220
}
@@ -223,23 +223,23 @@ func (vm *VM) FlushBlock(root *CodeBlock) {
223223
for _, item := range root.Children {
224224
switch item.Type {
225225
case ObjectType_Contract:
226-
if item.Info.(*ContractInfo).ID > flushMark {
227-
item.Info.(*ContractInfo).ID -= flushMark
228-
vm.Children[item.Info.(*ContractInfo).ID] = item
226+
if item.Info.ContractInfo().ID > flushMark {
227+
item.Info.ContractInfo().ID -= flushMark
228+
vm.Children[item.Info.ContractInfo().ID] = item
229229
shift--
230230
continue
231231
}
232232
item.Parent = vm.CodeBlock
233-
item.Info.(*ContractInfo).ID += uint32(shift)
233+
item.Info.ContractInfo().ID += uint32(shift)
234234
case ObjectType_Func:
235-
if item.Info.(*FuncInfo).ID > flushMark {
236-
item.Info.(*FuncInfo).ID -= flushMark
237-
vm.Children[item.Info.(*FuncInfo).ID] = item
235+
if item.Info.FuncInfo().ID > flushMark {
236+
item.Info.FuncInfo().ID -= flushMark
237+
vm.Children[item.Info.FuncInfo().ID] = item
238238
shift--
239239
continue
240240
}
241241
item.Parent = vm.CodeBlock
242-
item.Info.(*FuncInfo).ID += uint32(shift)
242+
item.Info.FuncInfo().ID += uint32(shift)
243243
}
244244
vm.Children = append(vm.Children, item)
245245
}
@@ -273,7 +273,7 @@ func findVar(name string, block *CodeBlocks) (ret *ObjInfo, owner *CodeBlock) {
273273
}
274274

275275
func (vm *VM) findObj(name string, block *CodeBlocks) (ret *ObjInfo, owner *CodeBlock) {
276-
sname := StateName((*block)[0].Info.(uint32), name)
276+
sname := StateName((*block)[0].Info.Uint32(), name)
277277
ret, owner = findVar(name, block)
278278
if ret != nil {
279279
return
@@ -545,11 +545,11 @@ main:
545545
var tail *ByteCode
546546
if prev := buffer[len(buffer)-1]; prev.Cmd == cmdCall || prev.Cmd == cmdCallVari {
547547
objInfo := prev.Value.(*ObjInfo)
548-
if (objInfo.Type == ObjectType_Func && objInfo.Value.(*CodeBlock).Info.(*FuncInfo).CanWrite) ||
549-
(objInfo.Type == ObjectType_ExtFunc && objInfo.Value.(ExtFuncInfo).CanWrite) {
548+
if (objInfo.Type == ObjectType_Func && objInfo.Value.CodeBlock().Info.FuncInfo().CanWrite) ||
549+
(objInfo.Type == ObjectType_ExtFunc && objInfo.Value.ExtFuncInfo().CanWrite) {
550550
setWritable(block)
551551
}
552-
if objInfo.Type == ObjectType_Func && objInfo.Value.(*CodeBlock).Info.(*FuncInfo).Names != nil {
552+
if objInfo.Type == ObjectType_Func && objInfo.Value.CodeBlock().Info.FuncInfo().Names != nil {
553553
if len(bytecode) == 0 || bytecode[len(bytecode)-1].Cmd != cmdFuncName {
554554
bytecode.push(newByteCode(cmdPush, lexem.Line, nil))
555555
}
@@ -558,7 +558,7 @@ main:
558558
log.WithFields(log.Fields{"type": consts.ParseError}).Error("must be the name of the tail")
559559
return fmt.Errorf(`must be the name of the tail`)
560560
}
561-
names := prev.Value.(*ObjInfo).Value.(*CodeBlock).Info.(*FuncInfo).Names
561+
names := prev.Value.(*ObjInfo).Value.CodeBlock().Info.FuncInfo().Names
562562
if _, ok := (*names)[(*lexems)[i+2].Value.(string)]; !ok {
563563

564564
if i < len(*lexems)-5 && (*lexems)[i+3].Type == isLPar {
@@ -588,7 +588,7 @@ main:
588588
parcount = parcount[:len(parcount)-1]
589589
if prev.Value.(*ObjInfo).Type == ObjectType_ExtFunc {
590590
var errtext string
591-
extinfo := prev.Value.(*ObjInfo).Value.(ExtFuncInfo)
591+
extinfo := prev.Value.(*ObjInfo).Value.ExtFuncInfo()
592592
wantlen := len(extinfo.Params)
593593
for _, v := range extinfo.Auto {
594594
if len(v) > 0 {
@@ -732,14 +732,14 @@ main:
732732
}
733733
if objInfo.Type == ObjectType_Contract {
734734
if objInfo.Value != nil {
735-
objContract = objInfo.Value.(*CodeBlock)
735+
objContract = objInfo.Value.CodeBlock()
736736
}
737737
objInfo, tobj = vm.findObj(`ExecContract`, block)
738738
isContract = true
739739
}
740740
cmdCall := uint16(cmdCall)
741-
if (objInfo.Type == ObjectType_ExtFunc && objInfo.Value.(ExtFuncInfo).Variadic) ||
742-
(objInfo.Type == ObjectType_Func && objInfo.Value.(*CodeBlock).Info.(*FuncInfo).Variadic) {
741+
if (objInfo.Type == ObjectType_ExtFunc && objInfo.Value.ExtFuncInfo().Variadic) ||
742+
(objInfo.Type == ObjectType_Func && objInfo.Value.CodeBlock().Info.FuncInfo().Variadic) {
743743
cmdCall = cmdCallVari
744744
}
745745
count := 0
@@ -748,20 +748,20 @@ main:
748748
}
749749
buffer.push(newByteCode(cmdCall, lexem.Line, objInfo))
750750
if isContract {
751-
name := StateName((*block)[0].Info.(uint32), lexem.Value.(string))
751+
name := StateName((*block)[0].Info.Uint32(), lexem.Value.(string))
752752
for j := len(*block) - 1; j >= 0; j-- {
753753
topblock := (*block)[j]
754754
if topblock.Type == ObjectType_Contract {
755-
if name == topblock.Info.(*ContractInfo).Name {
755+
if name == topblock.Info.ContractInfo().Name {
756756
return errRecursion
757757
}
758-
if topblock.Info.(*ContractInfo).Used == nil {
759-
topblock.Info.(*ContractInfo).Used = make(map[string]bool)
758+
if topblock.Info.ContractInfo().Used == nil {
759+
topblock.Info.ContractInfo().Used = make(map[string]bool)
760760
}
761-
topblock.Info.(*ContractInfo).Used[name] = true
761+
topblock.Info.ContractInfo().Used[name] = true
762762
}
763763
}
764-
if objContract != nil && objContract.Info.(*ContractInfo).CanWrite {
764+
if objContract != nil && objContract.Info.ContractInfo().CanWrite {
765765
setWritable(block)
766766
}
767767
bytecode.push(newByteCode(cmdPush, lexem.Line, name))
@@ -774,7 +774,7 @@ main:
774774
}
775775
if lexem.Value.(string) == `CallContract` {
776776
count++
777-
bytecode.push(newByteCode(cmdPush, lexem.Line, (*block)[0].Info.(uint32)))
777+
bytecode.push(newByteCode(cmdPush, lexem.Line, (*block)[0].Info.Uint32()))
778778
}
779779
parcount = append(parcount, count)
780780
call = true
@@ -784,7 +784,7 @@ main:
784784
logger.WithFields(log.Fields{"lex_value": lexem.Value.(string), "type": consts.ParseError}).Error("unknown variable")
785785
return fmt.Errorf(`unknown variable %s`, lexem.Value.(string))
786786
}
787-
buffer.push(newByteCode(cmdIndex, lexem.Line, &IndexInfo{VarOffset: objInfo.Value.(int), Owner: tobj}))
787+
buffer.push(newByteCode(cmdIndex, lexem.Line, &IndexInfo{VarOffset: objInfo.Value.Int(), Owner: tobj}))
788788
}
789789
}
790790
if !call {

packages/script/func.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func ExecContract(rt *RunTime, name, txs string, params ...interface{}) (interfa
4242
return nil, fmt.Errorf(eUnknownContract, name)
4343
}
4444
logger := log.WithFields(log.Fields{"contract_name": name, "type": consts.ContractError})
45-
cblock := contract.Value.(*CodeBlock)
45+
cblock := contract.Value.CodeBlock()
4646
parnames := make(map[string]bool)
4747
pars := strings.Split(txs, `,`)
4848
if len(pars) != len(params) {
@@ -69,8 +69,8 @@ func ExecContract(rt *RunTime, name, txs string, params ...interface{}) (interfa
6969
}
7070

7171
var isSignature bool
72-
if cblock.Info.(*ContractInfo).Tx != nil {
73-
for _, tx := range *cblock.Info.(*ContractInfo).Tx {
72+
if cblock.Info.ContractInfo().Tx != nil {
73+
for _, tx := range *cblock.Info.ContractInfo().Tx {
7474
if !parnames[tx.Name] {
7575
if !strings.Contains(tx.Tags, TagOptional) {
7676
logger.WithFields(log.Fields{"transaction_name": tx.Name, "type": consts.ContractError}).Error("transaction not defined")
@@ -95,7 +95,7 @@ func ExecContract(rt *RunTime, name, txs string, params ...interface{}) (interfa
9595
for i := len(rt.blocks) - 1; i >= 0; i-- {
9696
if rt.blocks[i].Block.Type == ObjectType_Func && rt.blocks[i].Block.Parent != nil &&
9797
rt.blocks[i].Block.Parent.Type == ObjectType_Contract {
98-
parent = rt.blocks[i].Block.Parent.Info.(*ContractInfo).Name
98+
parent = rt.blocks[i].Block.Parent.Info.ContractInfo().Name
9999
fid, fname := converter.ParseName(parent)
100100
cid, _ := converter.ParseName(name)
101101
if len(fname) > 0 {
@@ -130,7 +130,7 @@ func ExecContract(rt *RunTime, name, txs string, params ...interface{}) (interfa
130130
}
131131
if (*rt.extend)[`sc`] != nil && isSignature {
132132
obj := rt.vm.Objects[`check_signature`]
133-
finfo := obj.Value.(ExtFuncInfo)
133+
finfo := obj.Value.ExtFuncInfo()
134134
if err := finfo.Func.(func(*map[string]interface{}, string) error)(rt.extend, name); err != nil {
135135
logger.WithFields(log.Fields{"error": err, "func_name": finfo.Name, "type": consts.ContractError}).Error("executing exended function")
136136
return nil, err
@@ -140,7 +140,7 @@ func ExecContract(rt *RunTime, name, txs string, params ...interface{}) (interfa
140140
if block, ok := (*cblock).Objects[method]; ok && block.Type == ObjectType_Func {
141141
rtemp := NewRunTime(rt.vm, rt.cost)
142142
(*rt.extend)[`parent`] = parent
143-
_, err = rtemp.Run(block.Value.(*CodeBlock), nil, rt.extend)
143+
_, err = rtemp.Run(block.Value.CodeBlock(), nil, rt.extend)
144144
rt.cost = rtemp.cost
145145
if err != nil {
146146
logger.WithFields(log.Fields{"error": err, "method_name": method, "type": consts.ContractError}).Error("executing contract method")
@@ -187,9 +187,9 @@ func ExContract(rt *RunTime, state uint32, name string, params *types.Map) (inte
187187
logger := log.WithFields(log.Fields{"contract_name": name, "type": consts.ContractError})
188188
names := make([]string, 0)
189189
vals := make([]interface{}, 0)
190-
cblock := contract.Value.(*CodeBlock)
191-
if cblock.Info.(*ContractInfo).Tx != nil {
192-
for _, tx := range *cblock.Info.(*ContractInfo).Tx {
190+
cblock := contract.Value.CodeBlock()
191+
if cblock.Info.ContractInfo().Tx != nil {
192+
for _, tx := range *cblock.Info.ContractInfo().Tx {
193193
val, ok := params.Get(tx.Name)
194194
if !ok {
195195
if !strings.Contains(tx.Tags, TagOptional) {
@@ -215,9 +215,9 @@ func GetSettings(rt *RunTime, cntname, name string) (interface{}, error) {
215215
log.WithFields(log.Fields{"contract_name": name, "type": consts.ContractError}).Error("unknown contract")
216216
return nil, fmt.Errorf(`unknown contract %s`, cntname)
217217
}
218-
cblock := contract.Value.(*CodeBlock)
219-
if cblock.Info.(*ContractInfo).Settings != nil {
220-
if val, ok := cblock.Info.(*ContractInfo).Settings[name]; ok {
218+
cblock := contract.Value.CodeBlock()
219+
if cblock.Info.ContractInfo().Settings != nil {
220+
if val, ok := cblock.Info.ContractInfo().Settings[name]; ok {
221221
return val, nil
222222
}
223223
}

0 commit comments

Comments
 (0)