func.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101
  1. package goja
  2. import (
  3. "fmt"
  4. "reflect"
  5. "github.com/dop251/goja/unistring"
  6. )
  7. type resultType uint8
  8. const (
  9. resultNormal resultType = iota
  10. resultYield
  11. resultYieldRes // a yield that expects a value in return
  12. resultYieldDelegate // yield*
  13. resultYieldDelegateRes
  14. resultAwait
  15. )
  16. // used both as an instruction and as a Value
  17. type yieldMarker struct {
  18. valueNull
  19. resultType resultType
  20. }
  21. var (
  22. await = &yieldMarker{resultType: resultAwait}
  23. yield = &yieldMarker{resultType: resultYield}
  24. yieldRes = &yieldMarker{resultType: resultYieldRes}
  25. yieldDelegate = &yieldMarker{resultType: resultYieldDelegate}
  26. yieldDelegateRes = &yieldMarker{resultType: resultYieldDelegateRes}
  27. yieldEmpty = &yieldMarker{resultType: resultYield}
  28. )
  29. // AsyncContextTracker is a handler that allows to track an async execution context to ensure it remains
  30. // consistent across all callback invocations.
  31. // Whenever a Promise reaction job is scheduled the Grab method is called. It is supposed to return the
  32. // current context. The same context will be supplied to the Resumed method before the reaction job is
  33. // executed. The Exited method is called after the reaction job is finished.
  34. // This means that for each invocation of the Grab method there will be exactly one subsequent invocation
  35. // of Resumed and then Exited methods (assuming the Promise is fulfilled or rejected). Also, the Resumed/Exited
  36. // calls cannot be nested, so Exited can simply clear the current context instead of popping from a stack.
  37. // Note, this works for both async functions and regular Promise.then()/Promise.catch() callbacks.
  38. // See TestAsyncContextTracker for more insight.
  39. //
  40. // To register it call Runtime.SetAsyncContextTracker().
  41. type AsyncContextTracker interface {
  42. Grab() (trackingObject interface{})
  43. Resumed(trackingObject interface{})
  44. Exited()
  45. }
  46. type funcObjectImpl interface {
  47. source() valueString
  48. }
  49. type baseFuncObject struct {
  50. baseObject
  51. lenProp valueProperty
  52. }
  53. type baseJsFuncObject struct {
  54. baseFuncObject
  55. stash *stash
  56. privEnv *privateEnv
  57. prg *Program
  58. src string
  59. strict bool
  60. }
  61. type funcObject struct {
  62. baseJsFuncObject
  63. }
  64. type generatorFuncObject struct {
  65. baseJsFuncObject
  66. }
  67. type asyncFuncObject struct {
  68. baseJsFuncObject
  69. }
  70. type classFuncObject struct {
  71. baseJsFuncObject
  72. initFields *Program
  73. computedKeys []Value
  74. privateEnvType *privateEnvType
  75. privateMethods []Value
  76. derived bool
  77. }
  78. type methodFuncObject struct {
  79. baseJsFuncObject
  80. homeObject *Object
  81. }
  82. type generatorMethodFuncObject struct {
  83. methodFuncObject
  84. }
  85. type asyncMethodFuncObject struct {
  86. methodFuncObject
  87. }
  88. type arrowFuncObject struct {
  89. baseJsFuncObject
  90. funcObj *Object
  91. newTarget Value
  92. }
  93. type asyncArrowFuncObject struct {
  94. arrowFuncObject
  95. }
  96. type nativeFuncObject struct {
  97. baseFuncObject
  98. f func(FunctionCall) Value
  99. construct func(args []Value, newTarget *Object) *Object
  100. }
  101. type wrappedFuncObject struct {
  102. nativeFuncObject
  103. wrapped reflect.Value
  104. }
  105. type boundFuncObject struct {
  106. nativeFuncObject
  107. wrapped *Object
  108. }
  109. type generatorState uint8
  110. const (
  111. genStateUndefined generatorState = iota
  112. genStateSuspendedStart
  113. genStateExecuting
  114. genStateSuspendedYield
  115. genStateSuspendedYieldRes
  116. genStateCompleted
  117. )
  118. type generatorObject struct {
  119. baseObject
  120. gen generator
  121. delegated *iteratorRecord
  122. state generatorState
  123. }
  124. func (f *nativeFuncObject) source() valueString {
  125. return newStringValue(fmt.Sprintf("function %s() { [native code] }", nilSafe(f.getStr("name", nil)).toString()))
  126. }
  127. func (f *nativeFuncObject) export(*objectExportCtx) interface{} {
  128. return f.f
  129. }
  130. func (f *wrappedFuncObject) exportType() reflect.Type {
  131. return f.wrapped.Type()
  132. }
  133. func (f *wrappedFuncObject) export(*objectExportCtx) interface{} {
  134. return f.wrapped.Interface()
  135. }
  136. func (f *funcObject) _addProto(n unistring.String) Value {
  137. if n == "prototype" {
  138. if _, exists := f.values[n]; !exists {
  139. return f.addPrototype()
  140. }
  141. }
  142. return nil
  143. }
  144. func (f *funcObject) getStr(p unistring.String, receiver Value) Value {
  145. return f.getStrWithOwnProp(f.getOwnPropStr(p), p, receiver)
  146. }
  147. func (f *funcObject) getOwnPropStr(name unistring.String) Value {
  148. if v := f._addProto(name); v != nil {
  149. return v
  150. }
  151. return f.baseObject.getOwnPropStr(name)
  152. }
  153. func (f *funcObject) setOwnStr(name unistring.String, val Value, throw bool) bool {
  154. f._addProto(name)
  155. return f.baseObject.setOwnStr(name, val, throw)
  156. }
  157. func (f *funcObject) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) {
  158. return f._setForeignStr(name, f.getOwnPropStr(name), val, receiver, throw)
  159. }
  160. func (f *funcObject) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool {
  161. f._addProto(name)
  162. return f.baseObject.defineOwnPropertyStr(name, descr, throw)
  163. }
  164. func (f *funcObject) deleteStr(name unistring.String, throw bool) bool {
  165. f._addProto(name)
  166. return f.baseObject.deleteStr(name, throw)
  167. }
  168. func (f *funcObject) addPrototype() Value {
  169. proto := f.val.runtime.NewObject()
  170. proto.self._putProp("constructor", f.val, true, false, true)
  171. return f._putProp("prototype", proto, true, false, false)
  172. }
  173. func (f *funcObject) hasOwnPropertyStr(name unistring.String) bool {
  174. if f.baseObject.hasOwnPropertyStr(name) {
  175. return true
  176. }
  177. if name == "prototype" {
  178. return true
  179. }
  180. return false
  181. }
  182. func (f *funcObject) stringKeys(all bool, accum []Value) []Value {
  183. if all {
  184. if _, exists := f.values["prototype"]; !exists {
  185. accum = append(accum, asciiString("prototype"))
  186. }
  187. }
  188. return f.baseFuncObject.stringKeys(all, accum)
  189. }
  190. func (f *funcObject) iterateStringKeys() iterNextFunc {
  191. if _, exists := f.values["prototype"]; !exists {
  192. f.addPrototype()
  193. }
  194. return f.baseFuncObject.iterateStringKeys()
  195. }
  196. func (f *baseFuncObject) createInstance(newTarget *Object) *Object {
  197. r := f.val.runtime
  198. if newTarget == nil {
  199. newTarget = f.val
  200. }
  201. proto := r.getPrototypeFromCtor(newTarget, nil, r.global.ObjectPrototype)
  202. return f.val.runtime.newBaseObject(proto, classObject).val
  203. }
  204. func (f *baseJsFuncObject) source() valueString {
  205. return newStringValue(f.src)
  206. }
  207. func (f *baseJsFuncObject) construct(args []Value, newTarget *Object) *Object {
  208. if newTarget == nil {
  209. newTarget = f.val
  210. }
  211. proto := newTarget.self.getStr("prototype", nil)
  212. var protoObj *Object
  213. if p, ok := proto.(*Object); ok {
  214. protoObj = p
  215. } else {
  216. protoObj = f.val.runtime.global.ObjectPrototype
  217. }
  218. obj := f.val.runtime.newBaseObject(protoObj, classObject).val
  219. ret := f.call(FunctionCall{
  220. This: obj,
  221. Arguments: args,
  222. }, newTarget)
  223. if ret, ok := ret.(*Object); ok {
  224. return ret
  225. }
  226. return obj
  227. }
  228. func (f *classFuncObject) Call(FunctionCall) Value {
  229. panic(f.val.runtime.NewTypeError("Class constructor cannot be invoked without 'new'"))
  230. }
  231. func (f *classFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  232. return f.Call, true
  233. }
  234. func (f *classFuncObject) vmCall(vm *vm, n int) {
  235. f.Call(FunctionCall{})
  236. }
  237. func (f *classFuncObject) export(*objectExportCtx) interface{} {
  238. return f.Call
  239. }
  240. func (f *classFuncObject) createInstance(args []Value, newTarget *Object) (instance *Object) {
  241. if f.derived {
  242. if ctor := f.prototype.self.assertConstructor(); ctor != nil {
  243. instance = ctor(args, newTarget)
  244. } else {
  245. panic(f.val.runtime.NewTypeError("Super constructor is not a constructor"))
  246. }
  247. } else {
  248. instance = f.baseFuncObject.createInstance(newTarget)
  249. }
  250. return
  251. }
  252. func (f *classFuncObject) _initFields(instance *Object) {
  253. if f.privateEnvType != nil {
  254. penv := instance.self.getPrivateEnv(f.privateEnvType, true)
  255. penv.methods = f.privateMethods
  256. }
  257. if f.initFields != nil {
  258. vm := f.val.runtime.vm
  259. vm.pushCtx()
  260. vm.prg = f.initFields
  261. vm.stash = f.stash
  262. vm.privEnv = f.privEnv
  263. vm.newTarget = nil
  264. // so that 'super' base could be correctly resolved (including from direct eval())
  265. vm.push(f.val)
  266. vm.sb = vm.sp
  267. vm.push(instance)
  268. vm.pc = 0
  269. ex := vm.runTry()
  270. vm.popCtx()
  271. if ex != nil {
  272. panic(ex)
  273. }
  274. vm.sp -= 2
  275. }
  276. }
  277. func (f *classFuncObject) construct(args []Value, newTarget *Object) *Object {
  278. if newTarget == nil {
  279. newTarget = f.val
  280. }
  281. if f.prg == nil {
  282. instance := f.createInstance(args, newTarget)
  283. f._initFields(instance)
  284. return instance
  285. } else {
  286. var instance *Object
  287. var thisVal Value
  288. if !f.derived {
  289. instance = f.createInstance(args, newTarget)
  290. f._initFields(instance)
  291. thisVal = instance
  292. }
  293. ret := f._call(args, newTarget, thisVal)
  294. if ret, ok := ret.(*Object); ok {
  295. return ret
  296. }
  297. if f.derived {
  298. r := f.val.runtime
  299. if ret != _undefined {
  300. panic(r.NewTypeError("Derived constructors may only return object or undefined"))
  301. }
  302. if v := r.vm.stack[r.vm.sp+1]; v != nil { // using residual 'this' value (a bit hacky)
  303. instance = r.toObject(v)
  304. } else {
  305. panic(r.newError(r.global.ReferenceError, "Must call super constructor in derived class before returning from derived constructor"))
  306. }
  307. }
  308. return instance
  309. }
  310. }
  311. func (f *classFuncObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
  312. return f.construct
  313. }
  314. func (f *baseJsFuncObject) Call(call FunctionCall) Value {
  315. return f.call(call, nil)
  316. }
  317. func (f *arrowFuncObject) Call(call FunctionCall) Value {
  318. return f._call(call.Arguments, f.newTarget, nil)
  319. }
  320. func (f *baseJsFuncObject) __call(args []Value, newTarget, this Value) (Value, *Exception) {
  321. vm := f.val.runtime.vm
  322. vm.stack.expand(vm.sp + len(args) + 1)
  323. vm.stack[vm.sp] = f.val
  324. vm.sp++
  325. vm.stack[vm.sp] = this
  326. vm.sp++
  327. for _, arg := range args {
  328. if arg != nil {
  329. vm.stack[vm.sp] = arg
  330. } else {
  331. vm.stack[vm.sp] = _undefined
  332. }
  333. vm.sp++
  334. }
  335. vm.pushTryFrame(tryPanicMarker, -1)
  336. defer vm.popTryFrame()
  337. var needPop bool
  338. if vm.prg != nil {
  339. vm.pushCtx()
  340. vm.callStack = append(vm.callStack, context{pc: -2}) // extra frame so that run() halts after ret
  341. needPop = true
  342. } else {
  343. vm.pc = -2
  344. vm.pushCtx()
  345. }
  346. vm.args = len(args)
  347. vm.prg = f.prg
  348. vm.stash = f.stash
  349. vm.privEnv = f.privEnv
  350. vm.newTarget = newTarget
  351. vm.pc = 0
  352. for {
  353. ex := vm.runTryInner()
  354. if ex != nil {
  355. return nil, ex
  356. }
  357. if vm.halted() {
  358. break
  359. }
  360. }
  361. if needPop {
  362. vm.popCtx()
  363. }
  364. return vm.pop(), nil
  365. }
  366. func (f *baseJsFuncObject) _call(args []Value, newTarget, this Value) Value {
  367. res, ex := f.__call(args, newTarget, this)
  368. if ex != nil {
  369. panic(ex)
  370. }
  371. return res
  372. }
  373. func (f *baseJsFuncObject) call(call FunctionCall, newTarget Value) Value {
  374. return f._call(call.Arguments, newTarget, nilSafe(call.This))
  375. }
  376. func (f *baseJsFuncObject) export(*objectExportCtx) interface{} {
  377. return f.Call
  378. }
  379. func (f *baseFuncObject) exportType() reflect.Type {
  380. return reflectTypeFunc
  381. }
  382. func (f *baseFuncObject) typeOf() valueString {
  383. return stringFunction
  384. }
  385. func (f *baseJsFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  386. return f.Call, true
  387. }
  388. func (f *funcObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
  389. return f.construct
  390. }
  391. func (f *baseJsFuncObject) vmCall(vm *vm, n int) {
  392. vm.pushCtx()
  393. vm.args = n
  394. vm.prg = f.prg
  395. vm.stash = f.stash
  396. vm.privEnv = f.privEnv
  397. vm.pc = 0
  398. vm.stack[vm.sp-n-1], vm.stack[vm.sp-n-2] = vm.stack[vm.sp-n-2], vm.stack[vm.sp-n-1]
  399. }
  400. func (f *arrowFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  401. return f.Call, true
  402. }
  403. func (f *arrowFuncObject) vmCall(vm *vm, n int) {
  404. vm.pushCtx()
  405. vm.args = n
  406. vm.prg = f.prg
  407. vm.stash = f.stash
  408. vm.privEnv = f.privEnv
  409. vm.pc = 0
  410. vm.stack[vm.sp-n-1], vm.stack[vm.sp-n-2] = nil, vm.stack[vm.sp-n-1]
  411. vm.newTarget = f.newTarget
  412. }
  413. func (f *arrowFuncObject) export(*objectExportCtx) interface{} {
  414. return f.Call
  415. }
  416. func (f *baseFuncObject) init(name unistring.String, length Value) {
  417. f.baseObject.init()
  418. f.lenProp.configurable = true
  419. f.lenProp.value = length
  420. f._put("length", &f.lenProp)
  421. f._putProp("name", stringValueFromRaw(name), false, false, true)
  422. }
  423. func (f *baseFuncObject) hasInstance(v Value) bool {
  424. if v, ok := v.(*Object); ok {
  425. o := f.val.self.getStr("prototype", nil)
  426. if o1, ok := o.(*Object); ok {
  427. for {
  428. v = v.self.proto()
  429. if v == nil {
  430. return false
  431. }
  432. if o1 == v {
  433. return true
  434. }
  435. }
  436. } else {
  437. f.val.runtime.typeErrorResult(true, "prototype is not an object")
  438. }
  439. }
  440. return false
  441. }
  442. func (f *nativeFuncObject) defaultConstruct(ccall func(ConstructorCall) *Object, args []Value, newTarget *Object) *Object {
  443. obj := f.createInstance(newTarget)
  444. ret := ccall(ConstructorCall{
  445. This: obj,
  446. Arguments: args,
  447. NewTarget: newTarget,
  448. })
  449. if ret != nil {
  450. return ret
  451. }
  452. return obj
  453. }
  454. func (f *nativeFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  455. if f.f != nil {
  456. return f.f, true
  457. }
  458. return nil, false
  459. }
  460. func (f *nativeFuncObject) vmCall(vm *vm, n int) {
  461. if f.f != nil {
  462. vm.pushCtx()
  463. vm.prg = nil
  464. vm.sb = vm.sp - n // so that [sb-1] points to the callee
  465. ret := f.f(FunctionCall{
  466. Arguments: vm.stack[vm.sp-n : vm.sp],
  467. This: vm.stack[vm.sp-n-2],
  468. })
  469. if ret == nil {
  470. ret = _undefined
  471. }
  472. vm.stack[vm.sp-n-2] = ret
  473. vm.popCtx()
  474. } else {
  475. vm.stack[vm.sp-n-2] = _undefined
  476. }
  477. vm.sp -= n + 1
  478. vm.pc++
  479. }
  480. func (f *nativeFuncObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
  481. return f.construct
  482. }
  483. func (f *boundFuncObject) hasInstance(v Value) bool {
  484. return instanceOfOperator(v, f.wrapped)
  485. }
  486. func (f *baseJsFuncObject) prepareForVmCall(call FunctionCall) {
  487. vm := f.val.runtime.vm
  488. args := call.Arguments
  489. vm.stack.expand(vm.sp + len(args) + 1)
  490. vm.stack[vm.sp] = call.This
  491. vm.sp++
  492. vm.stack[vm.sp] = f.val
  493. vm.sp++
  494. for _, arg := range args {
  495. if arg != nil {
  496. vm.stack[vm.sp] = arg
  497. } else {
  498. vm.stack[vm.sp] = _undefined
  499. }
  500. vm.sp++
  501. }
  502. }
  503. func (f *baseJsFuncObject) asyncCall(call FunctionCall, vmCall func(*vm, int)) Value {
  504. f.prepareForVmCall(call)
  505. ar := &asyncRunner{
  506. f: f.val,
  507. vmCall: vmCall,
  508. }
  509. ar.start(len(call.Arguments))
  510. return ar.promiseCap.promise
  511. }
  512. func (f *asyncFuncObject) Call(call FunctionCall) Value {
  513. return f.asyncCall(call, f.baseJsFuncObject.vmCall)
  514. }
  515. func (f *asyncFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  516. return f.Call, true
  517. }
  518. func (f *asyncFuncObject) export(*objectExportCtx) interface{} {
  519. return f.Call
  520. }
  521. func (f *asyncArrowFuncObject) Call(call FunctionCall) Value {
  522. return f.asyncCall(call, f.arrowFuncObject.vmCall)
  523. }
  524. func (f *asyncArrowFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  525. return f.Call, true
  526. }
  527. func (f *asyncArrowFuncObject) export(*objectExportCtx) interface{} {
  528. return f.Call
  529. }
  530. func (f *asyncArrowFuncObject) vmCall(vm *vm, n int) {
  531. f.asyncVmCall(vm, n, f.arrowFuncObject.vmCall)
  532. }
  533. func (f *asyncMethodFuncObject) Call(call FunctionCall) Value {
  534. return f.asyncCall(call, f.methodFuncObject.vmCall)
  535. }
  536. func (f *asyncMethodFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  537. return f.Call, true
  538. }
  539. func (f *asyncMethodFuncObject) export(ctx *objectExportCtx) interface{} {
  540. return f.Call
  541. }
  542. func (f *asyncMethodFuncObject) vmCall(vm *vm, n int) {
  543. f.asyncVmCall(vm, n, f.methodFuncObject.vmCall)
  544. }
  545. func (f *baseJsFuncObject) asyncVmCall(vm *vm, n int, vmCall func(*vm, int)) {
  546. ar := &asyncRunner{
  547. f: f.val,
  548. vmCall: vmCall,
  549. }
  550. ar.start(n)
  551. vm.push(ar.promiseCap.promise)
  552. vm.pc++
  553. }
  554. func (f *asyncFuncObject) vmCall(vm *vm, n int) {
  555. f.asyncVmCall(vm, n, f.baseJsFuncObject.vmCall)
  556. }
  557. type asyncRunner struct {
  558. gen generator
  559. promiseCap *promiseCapability
  560. f *Object
  561. vmCall func(*vm, int)
  562. }
  563. func (ar *asyncRunner) onFulfilled(call FunctionCall) Value {
  564. ar.gen.vm.curAsyncRunner = ar
  565. defer func() {
  566. ar.gen.vm.curAsyncRunner = nil
  567. }()
  568. arg := call.Argument(0)
  569. res, resType, ex := ar.gen.next(arg)
  570. ar.step(res, resType == resultNormal, ex)
  571. return _undefined
  572. }
  573. func (ar *asyncRunner) onRejected(call FunctionCall) Value {
  574. ar.gen.vm.curAsyncRunner = ar
  575. defer func() {
  576. ar.gen.vm.curAsyncRunner = nil
  577. }()
  578. reason := call.Argument(0)
  579. res, resType, ex := ar.gen.nextThrow(reason)
  580. ar.step(res, resType == resultNormal, ex)
  581. return _undefined
  582. }
  583. func (ar *asyncRunner) step(res Value, done bool, ex *Exception) {
  584. r := ar.f.runtime
  585. if done || ex != nil {
  586. if ex == nil {
  587. ar.promiseCap.resolve(res)
  588. } else {
  589. ar.promiseCap.reject(ex.val)
  590. }
  591. return
  592. }
  593. // await
  594. promise := r.promiseResolve(r.global.Promise, res)
  595. promise.self.(*Promise).addReactions(&promiseReaction{
  596. typ: promiseReactionFulfill,
  597. handler: &jobCallback{callback: ar.onFulfilled},
  598. asyncRunner: ar,
  599. }, &promiseReaction{
  600. typ: promiseReactionReject,
  601. handler: &jobCallback{callback: ar.onRejected},
  602. asyncRunner: ar,
  603. })
  604. }
  605. func (ar *asyncRunner) start(nArgs int) {
  606. r := ar.f.runtime
  607. ar.gen.vm = r.vm
  608. ar.promiseCap = r.newPromiseCapability(r.global.Promise)
  609. sp := r.vm.sp
  610. ar.gen.enter()
  611. ar.vmCall(r.vm, nArgs)
  612. res, resType, ex := ar.gen.step()
  613. ar.step(res, resType == resultNormal, ex)
  614. if ex != nil {
  615. r.vm.sp = sp - nArgs - 2
  616. }
  617. r.vm.popTryFrame()
  618. r.vm.popCtx()
  619. }
  620. type generator struct {
  621. ctx execCtx
  622. vm *vm
  623. tryStackLen, iterStackLen, refStackLen uint32
  624. }
  625. func (g *generator) storeLengths() {
  626. g.tryStackLen, g.iterStackLen, g.refStackLen = uint32(len(g.vm.tryStack)), uint32(len(g.vm.iterStack)), uint32(len(g.vm.refStack))
  627. }
  628. func (g *generator) enter() {
  629. g.vm.pushCtx()
  630. g.vm.pushTryFrame(tryPanicMarker, -1)
  631. g.vm.prg, g.vm.sb, g.vm.pc = nil, -1, -2 // so that vm.run() halts after ret
  632. g.storeLengths()
  633. }
  634. func (g *generator) step() (res Value, resultType resultType, ex *Exception) {
  635. for {
  636. ex = g.vm.runTryInner()
  637. if ex != nil {
  638. return
  639. }
  640. if g.vm.halted() {
  641. break
  642. }
  643. }
  644. res = g.vm.pop()
  645. if ym, ok := res.(*yieldMarker); ok {
  646. resultType = ym.resultType
  647. g.ctx = execCtx{}
  648. g.vm.pc = -g.vm.pc + 1
  649. if res != yieldEmpty {
  650. res = g.vm.pop()
  651. } else {
  652. res = nil
  653. }
  654. g.vm.suspend(&g.ctx, g.tryStackLen, g.iterStackLen, g.refStackLen)
  655. g.vm.sp = g.vm.sb - 1
  656. g.vm.callStack = g.vm.callStack[:len(g.vm.callStack)-1] // remove the frame with pc == -2, as ret would do
  657. }
  658. return
  659. }
  660. func (g *generator) enterNext() {
  661. g.vm.pushCtx()
  662. g.vm.pushTryFrame(tryPanicMarker, -1)
  663. g.vm.callStack = append(g.vm.callStack, context{pc: -2}) // extra frame so that vm.run() halts after ret
  664. g.storeLengths()
  665. g.vm.resume(&g.ctx)
  666. }
  667. func (g *generator) next(v Value) (Value, resultType, *Exception) {
  668. g.enterNext()
  669. if v != nil {
  670. g.vm.push(v)
  671. }
  672. res, done, ex := g.step()
  673. g.vm.popTryFrame()
  674. g.vm.popCtx()
  675. return res, done, ex
  676. }
  677. func (g *generator) nextThrow(v interface{}) (Value, resultType, *Exception) {
  678. g.enterNext()
  679. ex := g.vm.handleThrow(v)
  680. if ex != nil {
  681. g.vm.popTryFrame()
  682. g.vm.popCtx()
  683. return nil, resultNormal, ex
  684. }
  685. res, resType, ex := g.step()
  686. g.vm.popTryFrame()
  687. g.vm.popCtx()
  688. return res, resType, ex
  689. }
  690. func (g *generatorObject) init(vmCall func(*vm, int), nArgs int) {
  691. g.baseObject.init()
  692. vm := g.val.runtime.vm
  693. g.gen.vm = vm
  694. g.gen.enter()
  695. vmCall(vm, nArgs)
  696. _, _, ex := g.gen.step()
  697. vm.popTryFrame()
  698. if ex != nil {
  699. panic(ex)
  700. }
  701. g.state = genStateSuspendedStart
  702. vm.popCtx()
  703. }
  704. func (g *generatorObject) validate() {
  705. if g.state == genStateExecuting {
  706. panic(g.val.runtime.NewTypeError("Illegal generator state"))
  707. }
  708. }
  709. func (g *generatorObject) step(res Value, resType resultType, ex *Exception) Value {
  710. if ex != nil {
  711. g.delegated = nil
  712. g.state = genStateCompleted
  713. panic(ex)
  714. }
  715. switch resType {
  716. case resultYield:
  717. g.state = genStateSuspendedYield
  718. return g.val.runtime.createIterResultObject(res, false)
  719. case resultYieldDelegate:
  720. g.state = genStateSuspendedYield
  721. return g.delegate(res)
  722. case resultYieldRes:
  723. g.state = genStateSuspendedYieldRes
  724. return g.val.runtime.createIterResultObject(res, false)
  725. case resultYieldDelegateRes:
  726. g.state = genStateSuspendedYieldRes
  727. return g.delegate(res)
  728. case resultNormal:
  729. g.state = genStateCompleted
  730. return g.val.runtime.createIterResultObject(res, true)
  731. default:
  732. panic(g.val.runtime.NewTypeError("Runtime bug: unexpected result type: %v", resType))
  733. }
  734. }
  735. func (g *generatorObject) delegate(v Value) Value {
  736. ex := g.val.runtime.try(func() {
  737. g.delegated = g.val.runtime.getIterator(v, nil)
  738. })
  739. if ex != nil {
  740. g.delegated = nil
  741. g.state = genStateCompleted
  742. return g.step(g.gen.nextThrow(ex))
  743. }
  744. return g.next(_undefined)
  745. }
  746. func (g *generatorObject) tryCallDelegated(fn func() (Value, bool)) (ret Value, done bool) {
  747. ex := g.val.runtime.try(func() {
  748. ret, done = fn()
  749. })
  750. if ex != nil {
  751. g.delegated = nil
  752. g.state = genStateExecuting
  753. return g.step(g.gen.nextThrow(ex)), false
  754. }
  755. return
  756. }
  757. func (g *generatorObject) callDelegated(method func(FunctionCall) Value, v Value) (Value, bool) {
  758. res := g.val.runtime.toObject(method(FunctionCall{This: g.delegated.iterator, Arguments: []Value{v}}))
  759. if iteratorComplete(res) {
  760. g.delegated = nil
  761. return iteratorValue(res), true
  762. }
  763. return res, false
  764. }
  765. func (g *generatorObject) next(v Value) Value {
  766. g.validate()
  767. if g.state == genStateCompleted {
  768. return g.val.runtime.createIterResultObject(_undefined, true)
  769. }
  770. if g.delegated != nil {
  771. res, done := g.tryCallDelegated(func() (Value, bool) {
  772. return g.callDelegated(g.delegated.next, v)
  773. })
  774. if !done {
  775. return res
  776. } else {
  777. v = res
  778. }
  779. }
  780. if g.state != genStateSuspendedYieldRes {
  781. v = nil
  782. }
  783. g.state = genStateExecuting
  784. return g.step(g.gen.next(v))
  785. }
  786. func (g *generatorObject) throw(v Value) Value {
  787. g.validate()
  788. if g.state == genStateSuspendedStart {
  789. g.state = genStateCompleted
  790. }
  791. if g.state == genStateCompleted {
  792. panic(v)
  793. }
  794. if d := g.delegated; d != nil {
  795. res, done := g.tryCallDelegated(func() (Value, bool) {
  796. method := toMethod(g.delegated.iterator.self.getStr("throw", nil))
  797. if method != nil {
  798. return g.callDelegated(method, v)
  799. }
  800. g.delegated = nil
  801. d.returnIter()
  802. panic(g.val.runtime.NewTypeError("The iterator does not provide a 'throw' method"))
  803. })
  804. if !done {
  805. return res
  806. }
  807. if g.state != genStateSuspendedYieldRes {
  808. res = nil
  809. }
  810. g.state = genStateExecuting
  811. return g.step(g.gen.next(res))
  812. }
  813. g.state = genStateExecuting
  814. return g.step(g.gen.nextThrow(v))
  815. }
  816. func (g *generatorObject) _return(v Value) Value {
  817. g.validate()
  818. if g.state == genStateSuspendedStart {
  819. g.state = genStateCompleted
  820. }
  821. if g.state == genStateCompleted {
  822. return g.val.runtime.createIterResultObject(v, true)
  823. }
  824. if d := g.delegated; d != nil {
  825. res, done := g.tryCallDelegated(func() (Value, bool) {
  826. method := toMethod(g.delegated.iterator.self.getStr("return", nil))
  827. if method != nil {
  828. return g.callDelegated(method, v)
  829. }
  830. g.delegated = nil
  831. return v, true
  832. })
  833. if !done {
  834. return res
  835. } else {
  836. v = res
  837. }
  838. }
  839. g.state = genStateExecuting
  840. g.gen.enterNext()
  841. vm := g.gen.vm
  842. var ex *Exception
  843. for len(vm.tryStack) > 0 {
  844. tf := &vm.tryStack[len(vm.tryStack)-1]
  845. if int(tf.callStackLen) != len(vm.callStack) {
  846. break
  847. }
  848. if tf.finallyPos >= 0 {
  849. vm.sp = int(tf.sp)
  850. vm.stash = tf.stash
  851. vm.privEnv = tf.privEnv
  852. ex1 := vm.restoreStacks(tf.iterLen, tf.refLen)
  853. if ex1 != nil {
  854. ex = ex1
  855. vm.popTryFrame()
  856. continue
  857. }
  858. vm.pc = int(tf.finallyPos)
  859. tf.catchPos = tryPanicMarker
  860. tf.finallyPos = -1
  861. tf.finallyRet = -2 // -1 would cause it to continue after leaveFinally
  862. for {
  863. ex1 := vm.runTryInner()
  864. if ex1 != nil {
  865. ex = ex1
  866. vm.popTryFrame()
  867. break
  868. }
  869. if vm.halted() {
  870. break
  871. }
  872. }
  873. } else {
  874. vm.popTryFrame()
  875. }
  876. }
  877. g.state = genStateCompleted
  878. vm.popTryFrame()
  879. if ex == nil {
  880. ex = vm.restoreStacks(g.gen.iterStackLen, g.gen.refStackLen)
  881. }
  882. if ex != nil {
  883. panic(ex)
  884. }
  885. vm.callStack = vm.callStack[:len(vm.callStack)-1]
  886. vm.sp = vm.sb - 1
  887. vm.popCtx()
  888. return g.val.runtime.createIterResultObject(v, true)
  889. }
  890. func (f *baseJsFuncObject) generatorCall(vmCall func(*vm, int), nArgs int) Value {
  891. o := &Object{runtime: f.val.runtime}
  892. genObj := &generatorObject{
  893. baseObject: baseObject{
  894. class: classObject,
  895. val: o,
  896. extensible: true,
  897. },
  898. }
  899. o.self = genObj
  900. genObj.init(vmCall, nArgs)
  901. genObj.prototype = o.runtime.getPrototypeFromCtor(f.val, nil, o.runtime.getGeneratorPrototype())
  902. return o
  903. }
  904. func (f *baseJsFuncObject) generatorVmCall(vmCall func(*vm, int), nArgs int) {
  905. vm := f.val.runtime.vm
  906. vm.push(f.generatorCall(vmCall, nArgs))
  907. vm.pc++
  908. }
  909. func (f *generatorFuncObject) vmCall(_ *vm, nArgs int) {
  910. f.generatorVmCall(f.baseJsFuncObject.vmCall, nArgs)
  911. }
  912. func (f *generatorFuncObject) Call(call FunctionCall) Value {
  913. f.prepareForVmCall(call)
  914. return f.generatorCall(f.baseJsFuncObject.vmCall, len(call.Arguments))
  915. }
  916. func (f *generatorFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  917. return f.Call, true
  918. }
  919. func (f *generatorFuncObject) export(*objectExportCtx) interface{} {
  920. return f.Call
  921. }
  922. func (f *generatorFuncObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
  923. return nil
  924. }
  925. func (f *generatorMethodFuncObject) vmCall(_ *vm, nArgs int) {
  926. f.generatorVmCall(f.methodFuncObject.vmCall, nArgs)
  927. }
  928. func (f *generatorMethodFuncObject) Call(call FunctionCall) Value {
  929. f.prepareForVmCall(call)
  930. return f.generatorCall(f.methodFuncObject.vmCall, len(call.Arguments))
  931. }
  932. func (f *generatorMethodFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  933. return f.Call, true
  934. }
  935. func (f *generatorMethodFuncObject) export(*objectExportCtx) interface{} {
  936. return f.Call
  937. }