@@ -5,22 +5,58 @@ import (
55 "strings"
66)
77
8- // Blocks is a slice of blocks
9- type Blocks []* Block
8+ /* Byte code could be described as a tree where functions and contracts are on the top level and
9+ nesting goes further according to nesting of bracketed. Tree nodes are structures of
10+ 'CodeBlock' type. For instance,
11+ func a {
12+ if b {
13+ while d {
14+
15+ }
16+ }
17+ if c {
18+ }
19+ }
20+ will be compiled into CodeBlock(a) which will have two child blocks CodeBlock (b) and CodeBlock (c) that
21+ are responsible for executing bytecode inside if. CodeBlock (b) will have a child CodeBlock (d) with
22+ a cycle.
23+ */
24+
25+ // CodeBlock contains all information about compiled block {...} and its children
26+ type CodeBlock struct {
27+ Objects map [string ]* ObjInfo
28+ Type ObjectType
29+ Owner * OwnerInfo
30+ Info interface {}
31+ Parent * CodeBlock
32+ Vars []reflect.Type
33+ Code ByteCodes
34+ Children CodeBlocks
35+ }
1036
11- func (bs * Blocks ) push (x interface {}) {
12- * bs = append (* bs , x .(* Block ))
37+ // ByteCode stores a command and an additional parameter.
38+ type ByteCode struct {
39+ Cmd uint16
40+ Line uint16
41+ Value interface {}
42+ }
43+
44+ // CodeBlocks is a slice of blocks
45+ type CodeBlocks []* CodeBlock
46+
47+ func (bs * CodeBlocks ) push (x interface {}) {
48+ * bs = append (* bs , x .(* CodeBlock ))
1349}
1450
15- func (bs * Blocks ) peek () * Block {
51+ func (bs * CodeBlocks ) peek () * CodeBlock {
1652 bsLen := len (* bs )
1753 if bsLen == 0 {
1854 return nil
1955 }
2056 return (* bs )[bsLen - 1 ]
2157}
2258
23- func (bs * Blocks ) get (idx int ) * Block {
59+ func (bs * CodeBlocks ) get (idx int ) * CodeBlock {
2460 if idx >= 0 && len (* bs ) > 0 && len (* bs ) > idx {
2561 return (* bs )[idx ]
2662 }
@@ -42,25 +78,6 @@ func (bs *ByteCodes) peek() *ByteCode {
4278 return (* bs )[bsLen - 1 ]
4379}
4480
45- // Block contains all information about compiled block {...} and its children
46- type Block struct {
47- Objects map [string ]* ObjInfo
48- Type ObjectType
49- Owner * OwnerInfo
50- Info interface {}
51- Parent * Block
52- Vars []reflect.Type
53- Code ByteCodes
54- Children Blocks
55- }
56-
57- // ByteCode stores a command and an additional parameter.
58- type ByteCode struct {
59- Cmd uint16
60- Line uint16
61- Value interface {}
62- }
63-
6481func newByteCode (cmd uint16 , line uint16 , value interface {}) * ByteCode {
6582 return & ByteCode {Cmd : cmd , Line : line , Value : value }
6683}
@@ -80,18 +97,18 @@ type ObjInfo struct {
8097 Value interface {}
8198}
8299
83- func NewBlock () * Block {
84- b := & Block {
100+ func NewCodeBlock () * CodeBlock {
101+ b := & CodeBlock {
85102 Objects : make (map [string ]* ObjInfo ),
86103 // Reserved 256 indexes for system purposes
87- Children : make (Blocks , 256 , 1024 ),
104+ Children : make (CodeBlocks , 256 , 1024 ),
88105 }
89106 b .Extend (NewExtendData ())
90107 return b
91108}
92109
93110// Extend sets the extended variables and functions
94- func (b * Block ) Extend (ext * ExtendData ) {
111+ func (b * CodeBlock ) Extend (ext * ExtendData ) {
95112 for key , item := range ext .Objects {
96113 fobj := reflect .ValueOf (item ).Type ()
97114 switch fobj .Kind () {
@@ -119,15 +136,15 @@ func (b *Block) Extend(ext *ExtendData) {
119136 }
120137}
121138
122- func (b * Block ) getObjByNameExt (name string , state uint32 ) (ret * ObjInfo ) {
139+ func (b * CodeBlock ) getObjByNameExt (name string , state uint32 ) (ret * ObjInfo ) {
123140 sname := StateName (state , name )
124141 if ret = b .getObjByName (name ); ret == nil && len (sname ) > 0 {
125142 ret = b .getObjByName (sname )
126143 }
127144 return
128145}
129146
130- func (block * Block ) getObjByName (name string ) (ret * ObjInfo ) {
147+ func (block * CodeBlock ) getObjByName (name string ) (ret * ObjInfo ) {
131148 var ok bool
132149 names := strings .Split (name , `.` )
133150 for i , name := range names {
@@ -141,11 +158,11 @@ func (block *Block) getObjByName(name string) (ret *ObjInfo) {
141158 if ret .Type != ObjectType_Contract && ret .Type != ObjectType_Func {
142159 return nil
143160 }
144- block = ret .Value .(* Block )
161+ block = ret .Value .(* CodeBlock )
145162 }
146163 return
147164}
148- func (block * Block ) parentContractCost () int64 {
165+ func (block * CodeBlock ) parentContractCost () int64 {
149166 var cost int64
150167 if parent , ok := block .Parent .Info .(* ContractInfo ); ok {
151168 cost += int64 (len (block .Parent .Objects ) * CostCall )
@@ -157,16 +174,27 @@ func (block *Block) parentContractCost() int64 {
157174 return cost
158175}
159176
160- func (block * Block ) isParentContract () bool {
177+ func (block * CodeBlock ) isParentContract () bool {
161178 if block .Parent != nil && block .Parent .Type == ObjectType_Contract {
162179 return true
163180 }
164181 return false
165182}
166183
184+ func setWritable (block * CodeBlocks ) {
185+ for i := len (* block ) - 1 ; i >= 0 ; i -- {
186+ blockItem := (* block )[i ]
187+ if blockItem .Type == ObjectType_Func {
188+ blockItem .Info .(* FuncInfo ).CanWrite = true
189+ }
190+ if blockItem .Type == ObjectType_Contract {
191+ blockItem .Info .(* ContractInfo ).CanWrite = true
192+ }
193+ }
194+ }
167195func (ret * ObjInfo ) getInParams () int {
168196 if ret .Type == ObjectType_ExtFunc {
169197 return len (ret .Value .(ExtFuncInfo ).Params )
170198 }
171- return len (ret .Value .(* Block ).Info .(* FuncInfo ).Params )
199+ return len (ret .Value .(* CodeBlock ).Info .(* FuncInfo ).Params )
172200}
0 commit comments