@@ -67,7 +67,7 @@ func (vm *VM) Run(program *Program, env interface{}) interface{} {
6767 switch op {
6868
6969 case OpPush :
70- vm .push (vm .constants [ vm . arg ()] )
70+ vm .push (vm .constant () )
7171
7272 case OpPop :
7373 vm .pop ()
@@ -79,10 +79,10 @@ func (vm *VM) Run(program *Program, env interface{}) interface{} {
7979 vm .push (a )
8080
8181 case OpFetch :
82- vm .push (fetch (env , vm .constants [ vm . arg ()] ))
82+ vm .push (fetch (env , vm .constant () ))
8383
8484 case OpFetchMap :
85- vm .push (env .(map [string ]interface {})[vm .constants [ vm . arg ()] .(string )])
85+ vm .push (env .(map [string ]interface {})[vm .constant () .(string )])
8686
8787 case OpTrue :
8888 vm .push (true )
@@ -208,7 +208,7 @@ func (vm *VM) Run(program *Program, env interface{}) interface{} {
208208
209209 case OpMatchesConst :
210210 a := vm .pop ()
211- r := vm .constants [ vm . arg ()] .(* regexp.Regexp )
211+ r := vm .constant () .(* regexp.Regexp )
212212 vm .push (r .MatchString (a .(string )))
213213
214214 case OpContains :
@@ -239,31 +239,34 @@ func (vm *VM) Run(program *Program, env interface{}) interface{} {
239239
240240 case OpProperty :
241241 a := vm .pop ()
242- b := vm .constants [ vm . arg ()]
242+ b := vm .constant ()
243243 vm .push (fetch (a , b ))
244244
245245 case OpCall :
246- call := vm .constants [vm .arg ()].(Call )
247-
246+ call := vm .constant ().(Call )
248247 in := make ([]reflect.Value , call .Size )
249248 for i := call .Size - 1 ; i >= 0 ; i -- {
250249 in [i ] = reflect .ValueOf (vm .pop ())
251250 }
252-
253251 out := fetchFn (env , call .Name ).Call (in )
254252 vm .push (out [0 ].Interface ())
255253
254+ case OpCallFast :
255+ call := vm .constant ().(Call )
256+ in := make ([]interface {}, call .Size )
257+ for i := call .Size - 1 ; i >= 0 ; i -- {
258+ in [i ] = vm .pop ()
259+ }
260+ fn := fetchFn (env , call .Name ).Interface ()
261+ vm .push (fn .(func (... interface {}) interface {})(in ... ))
262+
256263 case OpMethod :
257264 call := vm .constants [vm .arg ()].(Call )
258-
259265 in := make ([]reflect.Value , call .Size )
260266 for i := call .Size - 1 ; i >= 0 ; i -- {
261267 in [i ] = reflect .ValueOf (vm .pop ())
262268 }
263-
264- obj := vm .pop ()
265-
266- out := fetchFn (obj , call .Name ).Call (in )
269+ out := fetchFn (vm .pop (), call .Name ).Call (in )
267270 vm .push (out [0 ].Interface ())
268271
269272 case OpArray :
@@ -298,18 +301,18 @@ func (vm *VM) Run(program *Program, env interface{}) interface{} {
298301
299302 case OpStore :
300303 scope := vm .Scope ()
301- key := vm .constants [ vm . arg ()] .(string )
304+ key := vm .constant () .(string )
302305 value := vm .pop ()
303306 scope [key ] = value
304307
305308 case OpLoad :
306309 scope := vm .Scope ()
307- key := vm .constants [ vm . arg ()] .(string )
310+ key := vm .constant () .(string )
308311 vm .push (scope [key ])
309312
310313 case OpInc :
311314 scope := vm .Scope ()
312- key := vm .constants [ vm . arg ()] .(string )
315+ key := vm .constant () .(string )
313316 i := scope [key ].(int )
314317 i ++
315318 scope [key ] = i
@@ -362,6 +365,10 @@ func (vm *VM) arg() uint16 {
362365 return uint16 (b0 ) | uint16 (b1 )<< 8
363366}
364367
368+ func (vm * VM ) constant () interface {} {
369+ return vm .constants [vm .arg ()]
370+ }
371+
365372func (vm * VM ) Stack () []interface {} {
366373 return vm .stack
367374}
0 commit comments