vm.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. package tengo
  2. import (
  3. "fmt"
  4. "sync/atomic"
  5. "github.com/d5/tengo/v2/parser"
  6. "github.com/d5/tengo/v2/token"
  7. )
  8. // frame represents a function call frame.
  9. type frame struct {
  10. fn *CompiledFunction
  11. freeVars []*ObjectPtr
  12. ip int
  13. basePointer int
  14. }
  15. // VM is a virtual machine that executes the bytecode compiled by Compiler.
  16. type VM struct {
  17. constants []Object
  18. stack [StackSize]Object
  19. sp int
  20. globals []Object
  21. fileSet *parser.SourceFileSet
  22. frames [MaxFrames]frame
  23. framesIndex int
  24. curFrame *frame
  25. curInsts []byte
  26. ip int
  27. aborting int64
  28. maxAllocs int64
  29. allocs int64
  30. err error
  31. }
  32. // NewVM creates a VM.
  33. func NewVM(
  34. bytecode *Bytecode,
  35. globals []Object,
  36. maxAllocs int64,
  37. ) *VM {
  38. if globals == nil {
  39. globals = make([]Object, GlobalsSize)
  40. }
  41. v := &VM{
  42. constants: bytecode.Constants,
  43. sp: 0,
  44. globals: globals,
  45. fileSet: bytecode.FileSet,
  46. framesIndex: 1,
  47. ip: -1,
  48. maxAllocs: maxAllocs,
  49. }
  50. v.frames[0].fn = bytecode.MainFunction
  51. v.frames[0].ip = -1
  52. v.curFrame = &v.frames[0]
  53. v.curInsts = v.curFrame.fn.Instructions
  54. return v
  55. }
  56. // Abort aborts the execution.
  57. func (v *VM) Abort() {
  58. atomic.StoreInt64(&v.aborting, 1)
  59. }
  60. // Run starts the execution.
  61. func (v *VM) Run() (err error) {
  62. // reset VM states
  63. v.sp = 0
  64. v.curFrame = &(v.frames[0])
  65. v.curInsts = v.curFrame.fn.Instructions
  66. v.framesIndex = 1
  67. v.ip = -1
  68. v.allocs = v.maxAllocs + 1
  69. v.run()
  70. atomic.StoreInt64(&v.aborting, 0)
  71. err = v.err
  72. if err != nil {
  73. filePos := v.fileSet.Position(
  74. v.curFrame.fn.SourcePos(v.ip - 1))
  75. err = fmt.Errorf("Runtime Error: %w\n\tat %s",
  76. err, filePos)
  77. for v.framesIndex > 1 {
  78. v.framesIndex--
  79. v.curFrame = &v.frames[v.framesIndex-1]
  80. filePos = v.fileSet.Position(
  81. v.curFrame.fn.SourcePos(v.curFrame.ip - 1))
  82. err = fmt.Errorf("%w\n\tat %s", err, filePos)
  83. }
  84. return err
  85. }
  86. return nil
  87. }
  88. func (v *VM) run() {
  89. for atomic.LoadInt64(&v.aborting) == 0 {
  90. v.ip++
  91. switch v.curInsts[v.ip] {
  92. case parser.OpConstant:
  93. v.ip += 2
  94. cidx := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
  95. v.stack[v.sp] = v.constants[cidx]
  96. v.sp++
  97. case parser.OpNull:
  98. v.stack[v.sp] = UndefinedValue
  99. v.sp++
  100. case parser.OpBinaryOp:
  101. v.ip++
  102. right := v.stack[v.sp-1]
  103. left := v.stack[v.sp-2]
  104. tok := token.Token(v.curInsts[v.ip])
  105. res, e := left.BinaryOp(tok, right)
  106. if e != nil {
  107. v.sp -= 2
  108. if e == ErrInvalidOperator {
  109. v.err = fmt.Errorf("invalid operation: %s %s %s",
  110. left.TypeName(), tok.String(), right.TypeName())
  111. return
  112. }
  113. v.err = e
  114. return
  115. }
  116. v.allocs--
  117. if v.allocs == 0 {
  118. v.err = ErrObjectAllocLimit
  119. return
  120. }
  121. v.stack[v.sp-2] = res
  122. v.sp--
  123. case parser.OpEqual:
  124. right := v.stack[v.sp-1]
  125. left := v.stack[v.sp-2]
  126. v.sp -= 2
  127. if left.Equals(right) {
  128. v.stack[v.sp] = TrueValue
  129. } else {
  130. v.stack[v.sp] = FalseValue
  131. }
  132. v.sp++
  133. case parser.OpNotEqual:
  134. right := v.stack[v.sp-1]
  135. left := v.stack[v.sp-2]
  136. v.sp -= 2
  137. if left.Equals(right) {
  138. v.stack[v.sp] = FalseValue
  139. } else {
  140. v.stack[v.sp] = TrueValue
  141. }
  142. v.sp++
  143. case parser.OpPop:
  144. v.sp--
  145. case parser.OpTrue:
  146. v.stack[v.sp] = TrueValue
  147. v.sp++
  148. case parser.OpFalse:
  149. v.stack[v.sp] = FalseValue
  150. v.sp++
  151. case parser.OpLNot:
  152. operand := v.stack[v.sp-1]
  153. v.sp--
  154. if operand.IsFalsy() {
  155. v.stack[v.sp] = TrueValue
  156. } else {
  157. v.stack[v.sp] = FalseValue
  158. }
  159. v.sp++
  160. case parser.OpBComplement:
  161. operand := v.stack[v.sp-1]
  162. v.sp--
  163. switch x := operand.(type) {
  164. case Int:
  165. var res Object = Int{Value: ^x.Value}
  166. v.allocs--
  167. if v.allocs == 0 {
  168. v.err = ErrObjectAllocLimit
  169. return
  170. }
  171. v.stack[v.sp] = res
  172. v.sp++
  173. default:
  174. v.err = fmt.Errorf("invalid operation: ^%s",
  175. operand.TypeName())
  176. return
  177. }
  178. case parser.OpMinus:
  179. operand := v.stack[v.sp-1]
  180. v.sp--
  181. switch x := operand.(type) {
  182. case Int:
  183. var res Object = Int{Value: -x.Value}
  184. v.allocs--
  185. if v.allocs == 0 {
  186. v.err = ErrObjectAllocLimit
  187. return
  188. }
  189. v.stack[v.sp] = res
  190. v.sp++
  191. case Float:
  192. var res Object = Float{Value: -x.Value}
  193. v.allocs--
  194. if v.allocs == 0 {
  195. v.err = ErrObjectAllocLimit
  196. return
  197. }
  198. v.stack[v.sp] = res
  199. v.sp++
  200. default:
  201. v.err = fmt.Errorf("invalid operation: -%s",
  202. operand.TypeName())
  203. return
  204. }
  205. case parser.OpJumpFalsy:
  206. v.ip += 2
  207. v.sp--
  208. if v.stack[v.sp].IsFalsy() {
  209. pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
  210. v.ip = pos - 1
  211. }
  212. case parser.OpAndJump:
  213. v.ip += 2
  214. if v.stack[v.sp-1].IsFalsy() {
  215. pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
  216. v.ip = pos - 1
  217. } else {
  218. v.sp--
  219. }
  220. case parser.OpOrJump:
  221. v.ip += 2
  222. if v.stack[v.sp-1].IsFalsy() {
  223. v.sp--
  224. } else {
  225. pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
  226. v.ip = pos - 1
  227. }
  228. case parser.OpJump:
  229. pos := int(v.curInsts[v.ip+2]) | int(v.curInsts[v.ip+1])<<8
  230. v.ip = pos - 1
  231. case parser.OpSetGlobal:
  232. v.ip += 2
  233. v.sp--
  234. globalIndex := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
  235. v.globals[globalIndex] = v.stack[v.sp]
  236. case parser.OpSetSelGlobal:
  237. v.ip += 3
  238. globalIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8
  239. numSelectors := int(v.curInsts[v.ip])
  240. // selectors and RHS value
  241. selectors := make([]Object, numSelectors)
  242. for i := 0; i < numSelectors; i++ {
  243. selectors[i] = v.stack[v.sp-numSelectors+i]
  244. }
  245. val := v.stack[v.sp-numSelectors-1]
  246. v.sp -= numSelectors + 1
  247. e := indexAssign(v.globals[globalIndex], val, selectors)
  248. if e != nil {
  249. v.err = e
  250. return
  251. }
  252. case parser.OpGetGlobal:
  253. v.ip += 2
  254. globalIndex := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
  255. val := v.globals[globalIndex]
  256. v.stack[v.sp] = val
  257. v.sp++
  258. case parser.OpArray:
  259. v.ip += 2
  260. numElements := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
  261. elements := make([]Object, 0, numElements)
  262. for i := v.sp - numElements; i < v.sp; i++ {
  263. elements = append(elements, v.stack[i])
  264. }
  265. v.sp -= numElements
  266. var arr Object = &Array{Value: elements}
  267. v.allocs--
  268. if v.allocs == 0 {
  269. v.err = ErrObjectAllocLimit
  270. return
  271. }
  272. v.stack[v.sp] = arr
  273. v.sp++
  274. case parser.OpMap:
  275. v.ip += 2
  276. numElements := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
  277. kv := make(map[string]Object, numElements)
  278. for i := v.sp - numElements; i < v.sp; i += 2 {
  279. key := v.stack[i]
  280. value := v.stack[i+1]
  281. kv[key.(*String).Value] = value
  282. }
  283. v.sp -= numElements
  284. var m Object = &Map{Value: kv}
  285. v.allocs--
  286. if v.allocs == 0 {
  287. v.err = ErrObjectAllocLimit
  288. return
  289. }
  290. v.stack[v.sp] = m
  291. v.sp++
  292. case parser.OpError:
  293. value := v.stack[v.sp-1]
  294. var e Object = &Error{
  295. Value: value,
  296. }
  297. v.allocs--
  298. if v.allocs == 0 {
  299. v.err = ErrObjectAllocLimit
  300. return
  301. }
  302. v.stack[v.sp-1] = e
  303. case parser.OpImmutable:
  304. value := v.stack[v.sp-1]
  305. switch value := value.(type) {
  306. case *Array:
  307. var immutableArray Object = &ImmutableArray{
  308. Value: value.Value,
  309. }
  310. v.allocs--
  311. if v.allocs == 0 {
  312. v.err = ErrObjectAllocLimit
  313. return
  314. }
  315. v.stack[v.sp-1] = immutableArray
  316. case *Map:
  317. var immutableMap Object = &ImmutableMap{
  318. Value: value.Value,
  319. }
  320. v.allocs--
  321. if v.allocs == 0 {
  322. v.err = ErrObjectAllocLimit
  323. return
  324. }
  325. v.stack[v.sp-1] = immutableMap
  326. }
  327. case parser.OpIndex:
  328. index := v.stack[v.sp-1]
  329. left := v.stack[v.sp-2]
  330. v.sp -= 2
  331. val, err := left.IndexGet(index)
  332. if err != nil {
  333. if err == ErrNotIndexable {
  334. v.err = fmt.Errorf("not indexable: %s", index.TypeName())
  335. return
  336. }
  337. if err == ErrInvalidIndexType {
  338. v.err = fmt.Errorf("invalid index type: %s",
  339. index.TypeName())
  340. return
  341. }
  342. v.err = err
  343. return
  344. }
  345. if val == nil {
  346. val = UndefinedValue
  347. }
  348. v.stack[v.sp] = val
  349. v.sp++
  350. case parser.OpSliceIndex:
  351. high := v.stack[v.sp-1]
  352. low := v.stack[v.sp-2]
  353. left := v.stack[v.sp-3]
  354. v.sp -= 3
  355. var lowIdx int64
  356. if low != UndefinedValue {
  357. if low, ok := low.(Int); ok {
  358. lowIdx = low.Value
  359. } else {
  360. v.err = fmt.Errorf("invalid slice index type: %s",
  361. low.TypeName())
  362. return
  363. }
  364. }
  365. switch left := left.(type) {
  366. case *Array:
  367. numElements := int64(len(left.Value))
  368. var highIdx int64
  369. if high == UndefinedValue {
  370. highIdx = numElements
  371. } else if high, ok := high.(Int); ok {
  372. highIdx = high.Value
  373. } else {
  374. v.err = fmt.Errorf("invalid slice index type: %s",
  375. high.TypeName())
  376. return
  377. }
  378. if lowIdx > highIdx {
  379. v.err = fmt.Errorf("invalid slice index: %d > %d",
  380. lowIdx, highIdx)
  381. return
  382. }
  383. if lowIdx < 0 {
  384. lowIdx = 0
  385. } else if lowIdx > numElements {
  386. lowIdx = numElements
  387. }
  388. if highIdx < 0 {
  389. highIdx = 0
  390. } else if highIdx > numElements {
  391. highIdx = numElements
  392. }
  393. var val Object = &Array{
  394. Value: left.Value[lowIdx:highIdx],
  395. }
  396. v.allocs--
  397. if v.allocs == 0 {
  398. v.err = ErrObjectAllocLimit
  399. return
  400. }
  401. v.stack[v.sp] = val
  402. v.sp++
  403. case *ImmutableArray:
  404. numElements := int64(len(left.Value))
  405. var highIdx int64
  406. if high == UndefinedValue {
  407. highIdx = numElements
  408. } else if high, ok := high.(Int); ok {
  409. highIdx = high.Value
  410. } else {
  411. v.err = fmt.Errorf("invalid slice index type: %s",
  412. high.TypeName())
  413. return
  414. }
  415. if lowIdx > highIdx {
  416. v.err = fmt.Errorf("invalid slice index: %d > %d",
  417. lowIdx, highIdx)
  418. return
  419. }
  420. if lowIdx < 0 {
  421. lowIdx = 0
  422. } else if lowIdx > numElements {
  423. lowIdx = numElements
  424. }
  425. if highIdx < 0 {
  426. highIdx = 0
  427. } else if highIdx > numElements {
  428. highIdx = numElements
  429. }
  430. var val Object = &Array{
  431. Value: left.Value[lowIdx:highIdx],
  432. }
  433. v.allocs--
  434. if v.allocs == 0 {
  435. v.err = ErrObjectAllocLimit
  436. return
  437. }
  438. v.stack[v.sp] = val
  439. v.sp++
  440. case *String:
  441. numElements := int64(len(left.Value))
  442. var highIdx int64
  443. if high == UndefinedValue {
  444. highIdx = numElements
  445. } else if high, ok := high.(Int); ok {
  446. highIdx = high.Value
  447. } else {
  448. v.err = fmt.Errorf("invalid slice index type: %s",
  449. high.TypeName())
  450. return
  451. }
  452. if lowIdx > highIdx {
  453. v.err = fmt.Errorf("invalid slice index: %d > %d",
  454. lowIdx, highIdx)
  455. return
  456. }
  457. if lowIdx < 0 {
  458. lowIdx = 0
  459. } else if lowIdx > numElements {
  460. lowIdx = numElements
  461. }
  462. if highIdx < 0 {
  463. highIdx = 0
  464. } else if highIdx > numElements {
  465. highIdx = numElements
  466. }
  467. var val Object = &String{
  468. Value: left.Value[lowIdx:highIdx],
  469. }
  470. v.allocs--
  471. if v.allocs == 0 {
  472. v.err = ErrObjectAllocLimit
  473. return
  474. }
  475. v.stack[v.sp] = val
  476. v.sp++
  477. case *Bytes:
  478. numElements := int64(len(left.Value))
  479. var highIdx int64
  480. if high == UndefinedValue {
  481. highIdx = numElements
  482. } else if high, ok := high.(Int); ok {
  483. highIdx = high.Value
  484. } else {
  485. v.err = fmt.Errorf("invalid slice index type: %s",
  486. high.TypeName())
  487. return
  488. }
  489. if lowIdx > highIdx {
  490. v.err = fmt.Errorf("invalid slice index: %d > %d",
  491. lowIdx, highIdx)
  492. return
  493. }
  494. if lowIdx < 0 {
  495. lowIdx = 0
  496. } else if lowIdx > numElements {
  497. lowIdx = numElements
  498. }
  499. if highIdx < 0 {
  500. highIdx = 0
  501. } else if highIdx > numElements {
  502. highIdx = numElements
  503. }
  504. var val Object = &Bytes{
  505. Value: left.Value[lowIdx:highIdx],
  506. }
  507. v.allocs--
  508. if v.allocs == 0 {
  509. v.err = ErrObjectAllocLimit
  510. return
  511. }
  512. v.stack[v.sp] = val
  513. v.sp++
  514. }
  515. case parser.OpCall:
  516. numArgs := int(v.curInsts[v.ip+1])
  517. spread := int(v.curInsts[v.ip+2])
  518. v.ip += 2
  519. value := v.stack[v.sp-1-numArgs]
  520. if !value.CanCall() {
  521. v.err = fmt.Errorf("not callable: %s", value.TypeName())
  522. return
  523. }
  524. if spread == 1 {
  525. v.sp--
  526. switch arr := v.stack[v.sp].(type) {
  527. case *Array:
  528. for _, item := range arr.Value {
  529. v.stack[v.sp] = item
  530. v.sp++
  531. }
  532. numArgs += len(arr.Value) - 1
  533. case *ImmutableArray:
  534. for _, item := range arr.Value {
  535. v.stack[v.sp] = item
  536. v.sp++
  537. }
  538. numArgs += len(arr.Value) - 1
  539. default:
  540. v.err = fmt.Errorf("not an array: %s", arr.TypeName())
  541. return
  542. }
  543. }
  544. if callee, ok := value.(*CompiledFunction); ok {
  545. if callee.VarArgs {
  546. // if the closure is variadic,
  547. // roll up all variadic parameters into an array
  548. realArgs := callee.NumParameters - 1
  549. varArgs := numArgs - realArgs
  550. if varArgs >= 0 {
  551. numArgs = realArgs + 1
  552. args := make([]Object, varArgs)
  553. spStart := v.sp - varArgs
  554. for i := spStart; i < v.sp; i++ {
  555. args[i-spStart] = v.stack[i]
  556. }
  557. v.stack[spStart] = &Array{Value: args}
  558. v.sp = spStart + 1
  559. }
  560. }
  561. if numArgs != callee.NumParameters {
  562. if callee.VarArgs {
  563. v.err = fmt.Errorf(
  564. "wrong number of arguments: want>=%d, got=%d",
  565. callee.NumParameters-1, numArgs)
  566. } else {
  567. v.err = fmt.Errorf(
  568. "wrong number of arguments: want=%d, got=%d",
  569. callee.NumParameters, numArgs)
  570. }
  571. return
  572. }
  573. // test if it's tail-call
  574. if callee == v.curFrame.fn { // recursion
  575. nextOp := v.curInsts[v.ip+1]
  576. if nextOp == parser.OpReturn ||
  577. (nextOp == parser.OpPop &&
  578. parser.OpReturn == v.curInsts[v.ip+2]) {
  579. for p := 0; p < numArgs; p++ {
  580. v.stack[v.curFrame.basePointer+p] =
  581. v.stack[v.sp-numArgs+p]
  582. }
  583. v.sp -= numArgs + 1
  584. v.ip = -1 // reset IP to beginning of the frame
  585. continue
  586. }
  587. }
  588. if v.framesIndex >= MaxFrames {
  589. v.err = ErrStackOverflow
  590. return
  591. }
  592. // update call frame
  593. v.curFrame.ip = v.ip // store current ip before call
  594. v.curFrame = &(v.frames[v.framesIndex])
  595. v.curFrame.fn = callee
  596. v.curFrame.freeVars = callee.Free
  597. v.curFrame.basePointer = v.sp - numArgs
  598. v.curInsts = callee.Instructions
  599. v.ip = -1
  600. v.framesIndex++
  601. v.sp = v.sp - numArgs + callee.NumLocals
  602. } else {
  603. args := v.stack[v.sp-numArgs : v.sp]
  604. ret, e := value.Call(args...)
  605. v.sp -= numArgs + 1
  606. // runtime error
  607. if e != nil {
  608. if e == ErrWrongNumArguments {
  609. v.err = fmt.Errorf(
  610. "wrong number of arguments in call to '%s'",
  611. value.TypeName())
  612. return
  613. }
  614. if e, ok := e.(ErrInvalidArgumentType); ok {
  615. v.err = fmt.Errorf(
  616. "invalid type for argument '%s' in call to '%s': "+
  617. "expected %s, found %s",
  618. e.Name, value.TypeName(), e.Expected, e.Found)
  619. return
  620. }
  621. v.err = e
  622. return
  623. }
  624. // nil return -> undefined
  625. if ret == nil {
  626. ret = UndefinedValue
  627. }
  628. v.allocs--
  629. if v.allocs == 0 {
  630. v.err = ErrObjectAllocLimit
  631. return
  632. }
  633. v.stack[v.sp] = ret
  634. v.sp++
  635. }
  636. case parser.OpReturn:
  637. v.ip++
  638. var retVal Object
  639. if int(v.curInsts[v.ip]) == 1 {
  640. retVal = v.stack[v.sp-1]
  641. } else {
  642. retVal = UndefinedValue
  643. }
  644. //v.sp--
  645. v.framesIndex--
  646. v.curFrame = &v.frames[v.framesIndex-1]
  647. v.curInsts = v.curFrame.fn.Instructions
  648. v.ip = v.curFrame.ip
  649. //v.sp = lastFrame.basePointer - 1
  650. v.sp = v.frames[v.framesIndex].basePointer
  651. // skip stack overflow check because (newSP) <= (oldSP)
  652. v.stack[v.sp-1] = retVal
  653. //v.sp++
  654. case parser.OpDefineLocal:
  655. v.ip++
  656. localIndex := int(v.curInsts[v.ip])
  657. sp := v.curFrame.basePointer + localIndex
  658. // local variables can be mutated by other actions
  659. // so always store the copy of popped value
  660. val := v.stack[v.sp-1]
  661. v.sp--
  662. v.stack[sp] = val
  663. case parser.OpSetLocal:
  664. localIndex := int(v.curInsts[v.ip+1])
  665. v.ip++
  666. sp := v.curFrame.basePointer + localIndex
  667. // update pointee of v.stack[sp] instead of replacing the pointer
  668. // itself. this is needed because there can be free variables
  669. // referencing the same local variables.
  670. val := v.stack[v.sp-1]
  671. v.sp--
  672. if obj, ok := v.stack[sp].(*ObjectPtr); ok {
  673. *obj.Value = val
  674. val = obj
  675. }
  676. v.stack[sp] = val // also use a copy of popped value
  677. case parser.OpSetSelLocal:
  678. localIndex := int(v.curInsts[v.ip+1])
  679. numSelectors := int(v.curInsts[v.ip+2])
  680. v.ip += 2
  681. // selectors and RHS value
  682. selectors := make([]Object, numSelectors)
  683. for i := 0; i < numSelectors; i++ {
  684. selectors[i] = v.stack[v.sp-numSelectors+i]
  685. }
  686. val := v.stack[v.sp-numSelectors-1]
  687. v.sp -= numSelectors + 1
  688. dst := v.stack[v.curFrame.basePointer+localIndex]
  689. if obj, ok := dst.(*ObjectPtr); ok {
  690. dst = *obj.Value
  691. }
  692. if e := indexAssign(dst, val, selectors); e != nil {
  693. v.err = e
  694. return
  695. }
  696. case parser.OpGetLocal:
  697. v.ip++
  698. localIndex := int(v.curInsts[v.ip])
  699. val := v.stack[v.curFrame.basePointer+localIndex]
  700. if obj, ok := val.(*ObjectPtr); ok {
  701. val = *obj.Value
  702. }
  703. v.stack[v.sp] = val
  704. v.sp++
  705. case parser.OpGetBuiltin:
  706. v.ip++
  707. builtinIndex := int(v.curInsts[v.ip])
  708. v.stack[v.sp] = builtinFuncs[builtinIndex]
  709. v.sp++
  710. case parser.OpClosure:
  711. v.ip += 3
  712. constIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8
  713. numFree := int(v.curInsts[v.ip])
  714. fn, ok := v.constants[constIndex].(*CompiledFunction)
  715. if !ok {
  716. v.err = fmt.Errorf("not function: %s", fn.TypeName())
  717. return
  718. }
  719. free := make([]*ObjectPtr, numFree)
  720. for i := 0; i < numFree; i++ {
  721. switch freeVar := (v.stack[v.sp-numFree+i]).(type) {
  722. case *ObjectPtr:
  723. free[i] = freeVar
  724. default:
  725. free[i] = &ObjectPtr{
  726. Value: &v.stack[v.sp-numFree+i],
  727. }
  728. }
  729. }
  730. v.sp -= numFree
  731. cl := &CompiledFunction{
  732. Instructions: fn.Instructions,
  733. NumLocals: fn.NumLocals,
  734. NumParameters: fn.NumParameters,
  735. VarArgs: fn.VarArgs,
  736. Free: free,
  737. }
  738. v.allocs--
  739. if v.allocs == 0 {
  740. v.err = ErrObjectAllocLimit
  741. return
  742. }
  743. v.stack[v.sp] = cl
  744. v.sp++
  745. case parser.OpGetFreePtr:
  746. v.ip++
  747. freeIndex := int(v.curInsts[v.ip])
  748. val := v.curFrame.freeVars[freeIndex]
  749. v.stack[v.sp] = val
  750. v.sp++
  751. case parser.OpGetFree:
  752. v.ip++
  753. freeIndex := int(v.curInsts[v.ip])
  754. val := *v.curFrame.freeVars[freeIndex].Value
  755. v.stack[v.sp] = val
  756. v.sp++
  757. case parser.OpSetFree:
  758. v.ip++
  759. freeIndex := int(v.curInsts[v.ip])
  760. *v.curFrame.freeVars[freeIndex].Value = v.stack[v.sp-1]
  761. v.sp--
  762. case parser.OpGetLocalPtr:
  763. v.ip++
  764. localIndex := int(v.curInsts[v.ip])
  765. sp := v.curFrame.basePointer + localIndex
  766. val := v.stack[sp]
  767. var freeVar *ObjectPtr
  768. if obj, ok := val.(*ObjectPtr); ok {
  769. freeVar = obj
  770. } else {
  771. freeVar = &ObjectPtr{Value: &val}
  772. v.stack[sp] = freeVar
  773. }
  774. v.stack[v.sp] = freeVar
  775. v.sp++
  776. case parser.OpSetSelFree:
  777. v.ip += 2
  778. freeIndex := int(v.curInsts[v.ip-1])
  779. numSelectors := int(v.curInsts[v.ip])
  780. // selectors and RHS value
  781. selectors := make([]Object, numSelectors)
  782. for i := 0; i < numSelectors; i++ {
  783. selectors[i] = v.stack[v.sp-numSelectors+i]
  784. }
  785. val := v.stack[v.sp-numSelectors-1]
  786. v.sp -= numSelectors + 1
  787. e := indexAssign(*v.curFrame.freeVars[freeIndex].Value,
  788. val, selectors)
  789. if e != nil {
  790. v.err = e
  791. return
  792. }
  793. case parser.OpIteratorInit:
  794. var iterator Object
  795. dst := v.stack[v.sp-1]
  796. v.sp--
  797. if !dst.CanIterate() {
  798. v.err = fmt.Errorf("not iterable: %s", dst.TypeName())
  799. return
  800. }
  801. iterator = dst.Iterate()
  802. v.allocs--
  803. if v.allocs == 0 {
  804. v.err = ErrObjectAllocLimit
  805. return
  806. }
  807. v.stack[v.sp] = iterator
  808. v.sp++
  809. case parser.OpIteratorNext:
  810. iterator := v.stack[v.sp-1]
  811. v.sp--
  812. hasMore := iterator.(Iterator).Next()
  813. if hasMore {
  814. v.stack[v.sp] = TrueValue
  815. } else {
  816. v.stack[v.sp] = FalseValue
  817. }
  818. v.sp++
  819. case parser.OpIteratorKey:
  820. iterator := v.stack[v.sp-1]
  821. v.sp--
  822. val := iterator.(Iterator).Key()
  823. v.stack[v.sp] = val
  824. v.sp++
  825. case parser.OpIteratorValue:
  826. iterator := v.stack[v.sp-1]
  827. v.sp--
  828. val := iterator.(Iterator).Value()
  829. v.stack[v.sp] = val
  830. v.sp++
  831. case parser.OpSuspend:
  832. return
  833. default:
  834. v.err = fmt.Errorf("unknown opcode: %d", v.curInsts[v.ip])
  835. return
  836. }
  837. }
  838. }
  839. // IsStackEmpty tests if the stack is empty or not.
  840. func (v *VM) IsStackEmpty() bool {
  841. return v.sp == 0
  842. }
  843. func indexAssign(dst, src Object, selectors []Object) error {
  844. numSel := len(selectors)
  845. for sidx := numSel - 1; sidx > 0; sidx-- {
  846. next, err := dst.IndexGet(selectors[sidx])
  847. if err != nil {
  848. if err == ErrNotIndexable {
  849. return fmt.Errorf("not indexable: %s", dst.TypeName())
  850. }
  851. if err == ErrInvalidIndexType {
  852. return fmt.Errorf("invalid index type: %s",
  853. selectors[sidx].TypeName())
  854. }
  855. return err
  856. }
  857. dst = next
  858. }
  859. if err := dst.IndexSet(selectors[0], src); err != nil {
  860. if err == ErrNotIndexAssignable {
  861. return fmt.Errorf("not index-assignable: %s", dst.TypeName())
  862. }
  863. if err == ErrInvalidIndexValueType {
  864. return fmt.Errorf("invaid index value type: %s", src.TypeName())
  865. }
  866. return err
  867. }
  868. return nil
  869. }