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