vm.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  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 += 4
  207. v.sp--
  208. if v.stack[v.sp].IsFalsy() {
  209. pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 | int(v.curInsts[v.ip-2])<<16 | int(v.curInsts[v.ip-3])<<24
  210. v.ip = pos - 1
  211. }
  212. case parser.OpAndJump:
  213. v.ip += 4
  214. if v.stack[v.sp-1].IsFalsy() {
  215. pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 | int(v.curInsts[v.ip-2])<<16 | int(v.curInsts[v.ip-3])<<24
  216. v.ip = pos - 1
  217. } else {
  218. v.sp--
  219. }
  220. case parser.OpOrJump:
  221. v.ip += 4
  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 | int(v.curInsts[v.ip-2])<<16 | int(v.curInsts[v.ip-3])<<24
  226. v.ip = pos - 1
  227. }
  228. case parser.OpJump:
  229. pos := int(v.curInsts[v.ip+4]) | int(v.curInsts[v.ip+3])<<8 | int(v.curInsts[v.ip+2])<<16 | int(v.curInsts[v.ip+1])<<24
  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. var elements []Object
  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 lowInt, ok := low.(*Int); ok {
  358. lowIdx = lowInt.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 highInt, ok := high.(*Int); ok {
  372. highIdx = highInt.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 highInt, ok := high.(*Int); ok {
  409. highIdx = highInt.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 highInt, ok := high.(*Int); ok {
  446. highIdx = highInt.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 highInt, ok := high.(*Int); ok {
  483. highIdx = highInt.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. default:
  515. v.err = fmt.Errorf("not indexable: %s", left.TypeName())
  516. return
  517. }
  518. case parser.OpCall:
  519. numArgs := int(v.curInsts[v.ip+1])
  520. spread := int(v.curInsts[v.ip+2])
  521. v.ip += 2
  522. value := v.stack[v.sp-1-numArgs]
  523. if !value.CanCall() {
  524. v.err = fmt.Errorf("not callable: %s", value.TypeName())
  525. return
  526. }
  527. if spread == 1 {
  528. v.sp--
  529. switch arr := v.stack[v.sp].(type) {
  530. case *Array:
  531. for _, item := range arr.Value {
  532. v.stack[v.sp] = item
  533. v.sp++
  534. }
  535. numArgs += len(arr.Value) - 1
  536. case *ImmutableArray:
  537. for _, item := range arr.Value {
  538. v.stack[v.sp] = item
  539. v.sp++
  540. }
  541. numArgs += len(arr.Value) - 1
  542. default:
  543. v.err = fmt.Errorf("not an array: %s", arr.TypeName())
  544. return
  545. }
  546. }
  547. if callee, ok := value.(*CompiledFunction); ok {
  548. if callee.VarArgs {
  549. // if the closure is variadic,
  550. // roll up all variadic parameters into an array
  551. realArgs := callee.NumParameters - 1
  552. varArgs := numArgs - realArgs
  553. if varArgs >= 0 {
  554. numArgs = realArgs + 1
  555. args := make([]Object, varArgs)
  556. spStart := v.sp - varArgs
  557. for i := spStart; i < v.sp; i++ {
  558. args[i-spStart] = v.stack[i]
  559. }
  560. v.stack[spStart] = &Array{Value: args}
  561. v.sp = spStart + 1
  562. }
  563. }
  564. if numArgs != callee.NumParameters {
  565. if callee.VarArgs {
  566. v.err = fmt.Errorf(
  567. "wrong number of arguments: want>=%d, got=%d",
  568. callee.NumParameters-1, numArgs)
  569. } else {
  570. v.err = fmt.Errorf(
  571. "wrong number of arguments: want=%d, got=%d",
  572. callee.NumParameters, numArgs)
  573. }
  574. return
  575. }
  576. // test if it's tail-call
  577. if callee == v.curFrame.fn { // recursion
  578. nextOp := v.curInsts[v.ip+1]
  579. if nextOp == parser.OpReturn ||
  580. (nextOp == parser.OpPop &&
  581. parser.OpReturn == v.curInsts[v.ip+2]) {
  582. for p := 0; p < numArgs; p++ {
  583. v.stack[v.curFrame.basePointer+p] =
  584. v.stack[v.sp-numArgs+p]
  585. }
  586. v.sp -= numArgs + 1
  587. v.ip = -1 // reset IP to beginning of the frame
  588. continue
  589. }
  590. }
  591. if v.framesIndex >= MaxFrames {
  592. v.err = ErrStackOverflow
  593. return
  594. }
  595. // update call frame
  596. v.curFrame.ip = v.ip // store current ip before call
  597. v.curFrame = &(v.frames[v.framesIndex])
  598. v.curFrame.fn = callee
  599. v.curFrame.freeVars = callee.Free
  600. v.curFrame.basePointer = v.sp - numArgs
  601. v.curInsts = callee.Instructions
  602. v.ip = -1
  603. v.framesIndex++
  604. v.sp = v.sp - numArgs + callee.NumLocals
  605. } else {
  606. var args []Object
  607. args = append(args, v.stack[v.sp-numArgs:v.sp]...)
  608. ret, e := value.Call(args...)
  609. v.sp -= numArgs + 1
  610. // runtime error
  611. if e != nil {
  612. if e == ErrWrongNumArguments {
  613. v.err = fmt.Errorf(
  614. "wrong number of arguments in call to '%s'",
  615. value.TypeName())
  616. return
  617. }
  618. if e, ok := e.(ErrInvalidArgumentType); ok {
  619. v.err = fmt.Errorf(
  620. "invalid type for argument '%s' in call to '%s': "+
  621. "expected %s, found %s",
  622. e.Name, value.TypeName(), e.Expected, e.Found)
  623. return
  624. }
  625. v.err = e
  626. return
  627. }
  628. // nil return -> undefined
  629. if ret == nil {
  630. ret = UndefinedValue
  631. }
  632. v.allocs--
  633. if v.allocs == 0 {
  634. v.err = ErrObjectAllocLimit
  635. return
  636. }
  637. v.stack[v.sp] = ret
  638. v.sp++
  639. }
  640. case parser.OpReturn:
  641. v.ip++
  642. var retVal Object
  643. if int(v.curInsts[v.ip]) == 1 {
  644. retVal = v.stack[v.sp-1]
  645. } else {
  646. retVal = UndefinedValue
  647. }
  648. //v.sp--
  649. v.framesIndex--
  650. v.curFrame = &v.frames[v.framesIndex-1]
  651. v.curInsts = v.curFrame.fn.Instructions
  652. v.ip = v.curFrame.ip
  653. //v.sp = lastFrame.basePointer - 1
  654. v.sp = v.frames[v.framesIndex].basePointer
  655. // skip stack overflow check because (newSP) <= (oldSP)
  656. v.stack[v.sp-1] = retVal
  657. //v.sp++
  658. case parser.OpDefineLocal:
  659. v.ip++
  660. localIndex := int(v.curInsts[v.ip])
  661. sp := v.curFrame.basePointer + localIndex
  662. // local variables can be mutated by other actions
  663. // so always store the copy of popped value
  664. val := v.stack[v.sp-1]
  665. v.sp--
  666. v.stack[sp] = val
  667. case parser.OpSetLocal:
  668. localIndex := int(v.curInsts[v.ip+1])
  669. v.ip++
  670. sp := v.curFrame.basePointer + localIndex
  671. // update pointee of v.stack[sp] instead of replacing the pointer
  672. // itself. this is needed because there can be free variables
  673. // referencing the same local variables.
  674. val := v.stack[v.sp-1]
  675. v.sp--
  676. if obj, ok := v.stack[sp].(*ObjectPtr); ok {
  677. *obj.Value = val
  678. val = obj
  679. }
  680. v.stack[sp] = val // also use a copy of popped value
  681. case parser.OpSetSelLocal:
  682. localIndex := int(v.curInsts[v.ip+1])
  683. numSelectors := int(v.curInsts[v.ip+2])
  684. v.ip += 2
  685. // selectors and RHS value
  686. selectors := make([]Object, numSelectors)
  687. for i := 0; i < numSelectors; i++ {
  688. selectors[i] = v.stack[v.sp-numSelectors+i]
  689. }
  690. val := v.stack[v.sp-numSelectors-1]
  691. v.sp -= numSelectors + 1
  692. dst := v.stack[v.curFrame.basePointer+localIndex]
  693. if obj, ok := dst.(*ObjectPtr); ok {
  694. dst = *obj.Value
  695. }
  696. if e := indexAssign(dst, val, selectors); e != nil {
  697. v.err = e
  698. return
  699. }
  700. case parser.OpGetLocal:
  701. v.ip++
  702. localIndex := int(v.curInsts[v.ip])
  703. val := v.stack[v.curFrame.basePointer+localIndex]
  704. if obj, ok := val.(*ObjectPtr); ok {
  705. val = *obj.Value
  706. }
  707. v.stack[v.sp] = val
  708. v.sp++
  709. case parser.OpGetBuiltin:
  710. v.ip++
  711. builtinIndex := int(v.curInsts[v.ip])
  712. v.stack[v.sp] = builtinFuncs[builtinIndex]
  713. v.sp++
  714. case parser.OpClosure:
  715. v.ip += 3
  716. constIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8
  717. numFree := int(v.curInsts[v.ip])
  718. fn, ok := v.constants[constIndex].(*CompiledFunction)
  719. if !ok {
  720. v.err = fmt.Errorf("not function: %s", fn.TypeName())
  721. return
  722. }
  723. free := make([]*ObjectPtr, numFree)
  724. for i := 0; i < numFree; i++ {
  725. switch freeVar := (v.stack[v.sp-numFree+i]).(type) {
  726. case *ObjectPtr:
  727. free[i] = freeVar
  728. default:
  729. free[i] = &ObjectPtr{
  730. Value: &v.stack[v.sp-numFree+i],
  731. }
  732. }
  733. }
  734. v.sp -= numFree
  735. cl := &CompiledFunction{
  736. Instructions: fn.Instructions,
  737. NumLocals: fn.NumLocals,
  738. NumParameters: fn.NumParameters,
  739. VarArgs: fn.VarArgs,
  740. SourceMap: fn.SourceMap,
  741. Free: free,
  742. }
  743. v.allocs--
  744. if v.allocs == 0 {
  745. v.err = ErrObjectAllocLimit
  746. return
  747. }
  748. v.stack[v.sp] = cl
  749. v.sp++
  750. case parser.OpGetFreePtr:
  751. v.ip++
  752. freeIndex := int(v.curInsts[v.ip])
  753. val := v.curFrame.freeVars[freeIndex]
  754. v.stack[v.sp] = val
  755. v.sp++
  756. case parser.OpGetFree:
  757. v.ip++
  758. freeIndex := int(v.curInsts[v.ip])
  759. val := *v.curFrame.freeVars[freeIndex].Value
  760. v.stack[v.sp] = val
  761. v.sp++
  762. case parser.OpSetFree:
  763. v.ip++
  764. freeIndex := int(v.curInsts[v.ip])
  765. *v.curFrame.freeVars[freeIndex].Value = v.stack[v.sp-1]
  766. v.sp--
  767. case parser.OpGetLocalPtr:
  768. v.ip++
  769. localIndex := int(v.curInsts[v.ip])
  770. sp := v.curFrame.basePointer + localIndex
  771. val := v.stack[sp]
  772. var freeVar *ObjectPtr
  773. if obj, ok := val.(*ObjectPtr); ok {
  774. freeVar = obj
  775. } else {
  776. freeVar = &ObjectPtr{Value: &val}
  777. v.stack[sp] = freeVar
  778. }
  779. v.stack[v.sp] = freeVar
  780. v.sp++
  781. case parser.OpSetSelFree:
  782. v.ip += 2
  783. freeIndex := int(v.curInsts[v.ip-1])
  784. numSelectors := int(v.curInsts[v.ip])
  785. // selectors and RHS value
  786. selectors := make([]Object, numSelectors)
  787. for i := 0; i < numSelectors; i++ {
  788. selectors[i] = v.stack[v.sp-numSelectors+i]
  789. }
  790. val := v.stack[v.sp-numSelectors-1]
  791. v.sp -= numSelectors + 1
  792. e := indexAssign(*v.curFrame.freeVars[freeIndex].Value,
  793. val, selectors)
  794. if e != nil {
  795. v.err = e
  796. return
  797. }
  798. case parser.OpIteratorInit:
  799. var iterator Object
  800. dst := v.stack[v.sp-1]
  801. v.sp--
  802. if !dst.CanIterate() {
  803. v.err = fmt.Errorf("not iterable: %s", dst.TypeName())
  804. return
  805. }
  806. iterator = dst.Iterate()
  807. v.allocs--
  808. if v.allocs == 0 {
  809. v.err = ErrObjectAllocLimit
  810. return
  811. }
  812. v.stack[v.sp] = iterator
  813. v.sp++
  814. case parser.OpIteratorNext:
  815. iterator := v.stack[v.sp-1]
  816. v.sp--
  817. hasMore := iterator.(Iterator).Next()
  818. if hasMore {
  819. v.stack[v.sp] = TrueValue
  820. } else {
  821. v.stack[v.sp] = FalseValue
  822. }
  823. v.sp++
  824. case parser.OpIteratorKey:
  825. iterator := v.stack[v.sp-1]
  826. v.sp--
  827. val := iterator.(Iterator).Key()
  828. v.stack[v.sp] = val
  829. v.sp++
  830. case parser.OpIteratorValue:
  831. iterator := v.stack[v.sp-1]
  832. v.sp--
  833. val := iterator.(Iterator).Value()
  834. v.stack[v.sp] = val
  835. v.sp++
  836. case parser.OpSuspend:
  837. return
  838. default:
  839. v.err = fmt.Errorf("unknown opcode: %d", v.curInsts[v.ip])
  840. return
  841. }
  842. }
  843. }
  844. // IsStackEmpty tests if the stack is empty or not.
  845. func (v *VM) IsStackEmpty() bool {
  846. return v.sp == 0
  847. }
  848. func indexAssign(dst, src Object, selectors []Object) error {
  849. numSel := len(selectors)
  850. for sidx := numSel - 1; sidx > 0; sidx-- {
  851. next, err := dst.IndexGet(selectors[sidx])
  852. if err != nil {
  853. if err == ErrNotIndexable {
  854. return fmt.Errorf("not indexable: %s", dst.TypeName())
  855. }
  856. if err == ErrInvalidIndexType {
  857. return fmt.Errorf("invalid index type: %s",
  858. selectors[sidx].TypeName())
  859. }
  860. return err
  861. }
  862. dst = next
  863. }
  864. if err := dst.IndexSet(selectors[0], src); err != nil {
  865. if err == ErrNotIndexAssignable {
  866. return fmt.Errorf("not index-assignable: %s", dst.TypeName())
  867. }
  868. if err == ErrInvalidIndexValueType {
  869. return fmt.Errorf("invaid index value type: %s", src.TypeName())
  870. }
  871. return err
  872. }
  873. return nil
  874. }