vm.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  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. 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. }
  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. var args []Object
  604. args = append(args, v.stack[v.sp-numArgs:v.sp]...)
  605. ret, e := value.Call(args...)
  606. v.sp -= numArgs + 1
  607. // runtime error
  608. if e != nil {
  609. if e == ErrWrongNumArguments {
  610. v.err = fmt.Errorf(
  611. "wrong number of arguments in call to '%s'",
  612. value.TypeName())
  613. return
  614. }
  615. if e, ok := e.(ErrInvalidArgumentType); ok {
  616. v.err = fmt.Errorf(
  617. "invalid type for argument '%s' in call to '%s': "+
  618. "expected %s, found %s",
  619. e.Name, value.TypeName(), e.Expected, e.Found)
  620. return
  621. }
  622. v.err = e
  623. return
  624. }
  625. // nil return -> undefined
  626. if ret == nil {
  627. ret = UndefinedValue
  628. }
  629. v.allocs--
  630. if v.allocs == 0 {
  631. v.err = ErrObjectAllocLimit
  632. return
  633. }
  634. v.stack[v.sp] = ret
  635. v.sp++
  636. }
  637. case parser.OpReturn:
  638. v.ip++
  639. var retVal Object
  640. if int(v.curInsts[v.ip]) == 1 {
  641. retVal = v.stack[v.sp-1]
  642. } else {
  643. retVal = UndefinedValue
  644. }
  645. //v.sp--
  646. v.framesIndex--
  647. v.curFrame = &v.frames[v.framesIndex-1]
  648. v.curInsts = v.curFrame.fn.Instructions
  649. v.ip = v.curFrame.ip
  650. //v.sp = lastFrame.basePointer - 1
  651. v.sp = v.frames[v.framesIndex].basePointer
  652. // skip stack overflow check because (newSP) <= (oldSP)
  653. v.stack[v.sp-1] = retVal
  654. //v.sp++
  655. case parser.OpDefineLocal:
  656. v.ip++
  657. localIndex := int(v.curInsts[v.ip])
  658. sp := v.curFrame.basePointer + localIndex
  659. // local variables can be mutated by other actions
  660. // so always store the copy of popped value
  661. val := v.stack[v.sp-1]
  662. v.sp--
  663. v.stack[sp] = val
  664. case parser.OpSetLocal:
  665. localIndex := int(v.curInsts[v.ip+1])
  666. v.ip++
  667. sp := v.curFrame.basePointer + localIndex
  668. // update pointee of v.stack[sp] instead of replacing the pointer
  669. // itself. this is needed because there can be free variables
  670. // referencing the same local variables.
  671. val := v.stack[v.sp-1]
  672. v.sp--
  673. if obj, ok := v.stack[sp].(*ObjectPtr); ok {
  674. *obj.Value = val
  675. val = obj
  676. }
  677. v.stack[sp] = val // also use a copy of popped value
  678. case parser.OpSetSelLocal:
  679. localIndex := int(v.curInsts[v.ip+1])
  680. numSelectors := int(v.curInsts[v.ip+2])
  681. v.ip += 2
  682. // selectors and RHS value
  683. selectors := make([]Object, numSelectors)
  684. for i := 0; i < numSelectors; i++ {
  685. selectors[i] = v.stack[v.sp-numSelectors+i]
  686. }
  687. val := v.stack[v.sp-numSelectors-1]
  688. v.sp -= numSelectors + 1
  689. dst := v.stack[v.curFrame.basePointer+localIndex]
  690. if obj, ok := dst.(*ObjectPtr); ok {
  691. dst = *obj.Value
  692. }
  693. if e := indexAssign(dst, val, selectors); e != nil {
  694. v.err = e
  695. return
  696. }
  697. case parser.OpGetLocal:
  698. v.ip++
  699. localIndex := int(v.curInsts[v.ip])
  700. val := v.stack[v.curFrame.basePointer+localIndex]
  701. if obj, ok := val.(*ObjectPtr); ok {
  702. val = *obj.Value
  703. }
  704. v.stack[v.sp] = val
  705. v.sp++
  706. case parser.OpGetBuiltin:
  707. v.ip++
  708. builtinIndex := int(v.curInsts[v.ip])
  709. v.stack[v.sp] = builtinFuncs[builtinIndex]
  710. v.sp++
  711. case parser.OpClosure:
  712. v.ip += 3
  713. constIndex := int(v.curInsts[v.ip-1]) | int(v.curInsts[v.ip-2])<<8
  714. numFree := int(v.curInsts[v.ip])
  715. fn, ok := v.constants[constIndex].(*CompiledFunction)
  716. if !ok {
  717. v.err = fmt.Errorf("not function: %s", fn.TypeName())
  718. return
  719. }
  720. free := make([]*ObjectPtr, numFree)
  721. for i := 0; i < numFree; i++ {
  722. switch freeVar := (v.stack[v.sp-numFree+i]).(type) {
  723. case *ObjectPtr:
  724. free[i] = freeVar
  725. default:
  726. free[i] = &ObjectPtr{
  727. Value: &v.stack[v.sp-numFree+i],
  728. }
  729. }
  730. }
  731. v.sp -= numFree
  732. cl := &CompiledFunction{
  733. Instructions: fn.Instructions,
  734. NumLocals: fn.NumLocals,
  735. NumParameters: fn.NumParameters,
  736. VarArgs: fn.VarArgs,
  737. SourceMap: fn.SourceMap,
  738. Free: free,
  739. }
  740. v.allocs--
  741. if v.allocs == 0 {
  742. v.err = ErrObjectAllocLimit
  743. return
  744. }
  745. v.stack[v.sp] = cl
  746. v.sp++
  747. case parser.OpGetFreePtr:
  748. v.ip++
  749. freeIndex := int(v.curInsts[v.ip])
  750. val := v.curFrame.freeVars[freeIndex]
  751. v.stack[v.sp] = val
  752. v.sp++
  753. case parser.OpGetFree:
  754. v.ip++
  755. freeIndex := int(v.curInsts[v.ip])
  756. val := *v.curFrame.freeVars[freeIndex].Value
  757. v.stack[v.sp] = val
  758. v.sp++
  759. case parser.OpSetFree:
  760. v.ip++
  761. freeIndex := int(v.curInsts[v.ip])
  762. *v.curFrame.freeVars[freeIndex].Value = v.stack[v.sp-1]
  763. v.sp--
  764. case parser.OpGetLocalPtr:
  765. v.ip++
  766. localIndex := int(v.curInsts[v.ip])
  767. sp := v.curFrame.basePointer + localIndex
  768. val := v.stack[sp]
  769. var freeVar *ObjectPtr
  770. if obj, ok := val.(*ObjectPtr); ok {
  771. freeVar = obj
  772. } else {
  773. freeVar = &ObjectPtr{Value: &val}
  774. v.stack[sp] = freeVar
  775. }
  776. v.stack[v.sp] = freeVar
  777. v.sp++
  778. case parser.OpSetSelFree:
  779. v.ip += 2
  780. freeIndex := int(v.curInsts[v.ip-1])
  781. numSelectors := int(v.curInsts[v.ip])
  782. // selectors and RHS value
  783. selectors := make([]Object, numSelectors)
  784. for i := 0; i < numSelectors; i++ {
  785. selectors[i] = v.stack[v.sp-numSelectors+i]
  786. }
  787. val := v.stack[v.sp-numSelectors-1]
  788. v.sp -= numSelectors + 1
  789. e := indexAssign(*v.curFrame.freeVars[freeIndex].Value,
  790. val, selectors)
  791. if e != nil {
  792. v.err = e
  793. return
  794. }
  795. case parser.OpIteratorInit:
  796. var iterator Object
  797. dst := v.stack[v.sp-1]
  798. v.sp--
  799. if !dst.CanIterate() {
  800. v.err = fmt.Errorf("not iterable: %s", dst.TypeName())
  801. return
  802. }
  803. iterator = dst.Iterate()
  804. v.allocs--
  805. if v.allocs == 0 {
  806. v.err = ErrObjectAllocLimit
  807. return
  808. }
  809. v.stack[v.sp] = iterator
  810. v.sp++
  811. case parser.OpIteratorNext:
  812. iterator := v.stack[v.sp-1]
  813. v.sp--
  814. hasMore := iterator.(Iterator).Next()
  815. if hasMore {
  816. v.stack[v.sp] = TrueValue
  817. } else {
  818. v.stack[v.sp] = FalseValue
  819. }
  820. v.sp++
  821. case parser.OpIteratorKey:
  822. iterator := v.stack[v.sp-1]
  823. v.sp--
  824. val := iterator.(Iterator).Key()
  825. v.stack[v.sp] = val
  826. v.sp++
  827. case parser.OpIteratorValue:
  828. iterator := v.stack[v.sp-1]
  829. v.sp--
  830. val := iterator.(Iterator).Value()
  831. v.stack[v.sp] = val
  832. v.sp++
  833. case parser.OpSuspend:
  834. return
  835. default:
  836. v.err = fmt.Errorf("unknown opcode: %d", v.curInsts[v.ip])
  837. return
  838. }
  839. }
  840. }
  841. // IsStackEmpty tests if the stack is empty or not.
  842. func (v *VM) IsStackEmpty() bool {
  843. return v.sp == 0
  844. }
  845. func indexAssign(dst, src Object, selectors []Object) error {
  846. numSel := len(selectors)
  847. for sidx := numSel - 1; sidx > 0; sidx-- {
  848. next, err := dst.IndexGet(selectors[sidx])
  849. if err != nil {
  850. if err == ErrNotIndexable {
  851. return fmt.Errorf("not indexable: %s", dst.TypeName())
  852. }
  853. if err == ErrInvalidIndexType {
  854. return fmt.Errorf("invalid index type: %s",
  855. selectors[sidx].TypeName())
  856. }
  857. return err
  858. }
  859. dst = next
  860. }
  861. if err := dst.IndexSet(selectors[0], src); err != nil {
  862. if err == ErrNotIndexAssignable {
  863. return fmt.Errorf("not index-assignable: %s", dst.TypeName())
  864. }
  865. if err == ErrInvalidIndexValueType {
  866. return fmt.Errorf("invaid index value type: %s", src.TypeName())
  867. }
  868. return err
  869. }
  870. return nil
  871. }