1package goja
2
3import (
4	"bytes"
5	"errors"
6	"fmt"
7	"github.com/dop251/goja/file"
8	"go/ast"
9	"hash/maphash"
10	"math"
11	"math/bits"
12	"math/rand"
13	"reflect"
14	"runtime"
15	"strconv"
16	"time"
17
18	"golang.org/x/text/collate"
19
20	js_ast "github.com/dop251/goja/ast"
21	"github.com/dop251/goja/parser"
22	"github.com/dop251/goja/unistring"
23)
24
25const (
26	sqrt1_2 float64 = math.Sqrt2 / 2
27
28	deoptimiseRegexp = false
29)
30
31var (
32	typeCallable = reflect.TypeOf(Callable(nil))
33	typeValue    = reflect.TypeOf((*Value)(nil)).Elem()
34	typeObject   = reflect.TypeOf((*Object)(nil))
35	typeTime     = reflect.TypeOf(time.Time{})
36	typeBytes    = reflect.TypeOf(([]byte)(nil))
37)
38
39type iterationKind int
40
41const (
42	iterationKindKey iterationKind = iota
43	iterationKindValue
44	iterationKindKeyValue
45)
46
47type global struct {
48	stash    stash
49	varNames map[unistring.String]struct{}
50
51	Object   *Object
52	Array    *Object
53	Function *Object
54	String   *Object
55	Number   *Object
56	Boolean  *Object
57	RegExp   *Object
58	Date     *Object
59	Symbol   *Object
60	Proxy    *Object
61
62	ArrayBuffer       *Object
63	DataView          *Object
64	TypedArray        *Object
65	Uint8Array        *Object
66	Uint8ClampedArray *Object
67	Int8Array         *Object
68	Uint16Array       *Object
69	Int16Array        *Object
70	Uint32Array       *Object
71	Int32Array        *Object
72	Float32Array      *Object
73	Float64Array      *Object
74
75	WeakSet *Object
76	WeakMap *Object
77	Map     *Object
78	Set     *Object
79
80	Error          *Object
81	TypeError      *Object
82	ReferenceError *Object
83	SyntaxError    *Object
84	RangeError     *Object
85	EvalError      *Object
86	URIError       *Object
87
88	GoError *Object
89
90	ObjectPrototype   *Object
91	ArrayPrototype    *Object
92	NumberPrototype   *Object
93	StringPrototype   *Object
94	BooleanPrototype  *Object
95	FunctionPrototype *Object
96	RegExpPrototype   *Object
97	DatePrototype     *Object
98	SymbolPrototype   *Object
99
100	ArrayBufferPrototype *Object
101	DataViewPrototype    *Object
102	TypedArrayPrototype  *Object
103	WeakSetPrototype     *Object
104	WeakMapPrototype     *Object
105	MapPrototype         *Object
106	SetPrototype         *Object
107
108	IteratorPrototype             *Object
109	ArrayIteratorPrototype        *Object
110	MapIteratorPrototype          *Object
111	SetIteratorPrototype          *Object
112	StringIteratorPrototype       *Object
113	RegExpStringIteratorPrototype *Object
114
115	ErrorPrototype          *Object
116	TypeErrorPrototype      *Object
117	SyntaxErrorPrototype    *Object
118	RangeErrorPrototype     *Object
119	ReferenceErrorPrototype *Object
120	EvalErrorPrototype      *Object
121	URIErrorPrototype       *Object
122
123	GoErrorPrototype *Object
124
125	Eval *Object
126
127	thrower         *Object
128	throwerProperty Value
129
130	stdRegexpProto *guardedObject
131
132	weakSetAdder  *Object
133	weakMapAdder  *Object
134	mapAdder      *Object
135	setAdder      *Object
136	arrayValues   *Object
137	arrayToString *Object
138}
139
140type Flag int
141
142const (
143	FLAG_NOT_SET Flag = iota
144	FLAG_FALSE
145	FLAG_TRUE
146)
147
148func (f Flag) Bool() bool {
149	return f == FLAG_TRUE
150}
151
152func ToFlag(b bool) Flag {
153	if b {
154		return FLAG_TRUE
155	}
156	return FLAG_FALSE
157}
158
159type RandSource func() float64
160
161type Now func() time.Time
162
163type Runtime struct {
164	global          global
165	globalObject    *Object
166	stringSingleton *stringObject
167	rand            RandSource
168	now             Now
169	_collator       *collate.Collator
170	parserOptions   []parser.Option
171
172	symbolRegistry map[unistring.String]*Symbol
173
174	typeInfoCache   map[reflect.Type]*reflectTypeInfo
175	fieldNameMapper FieldNameMapper
176
177	vm    *vm
178	hash  *maphash.Hash
179	idSeq uint64
180}
181
182type StackFrame struct {
183	prg      *Program
184	funcName unistring.String
185	pc       int
186}
187
188func (f *StackFrame) SrcName() string {
189	if f.prg == nil {
190		return "<native>"
191	}
192	return f.prg.src.Name()
193}
194
195func (f *StackFrame) FuncName() string {
196	if f.funcName == "" && f.prg == nil {
197		return "<native>"
198	}
199	if f.funcName == "" {
200		return "<anonymous>"
201	}
202	return f.funcName.String()
203}
204
205func (f *StackFrame) Position() file.Position {
206	if f.prg == nil || f.prg.src == nil {
207		return file.Position{}
208	}
209	return f.prg.src.Position(f.prg.sourceOffset(f.pc))
210}
211
212func (f *StackFrame) Write(b *bytes.Buffer) {
213	if f.prg != nil {
214		if n := f.prg.funcName; n != "" {
215			b.WriteString(n.String())
216			b.WriteString(" (")
217		}
218		p := f.Position()
219		if p.Filename != "" {
220			b.WriteString(p.Filename)
221		} else {
222			b.WriteString("<eval>")
223		}
224		b.WriteByte(':')
225		b.WriteString(strconv.Itoa(p.Line))
226		b.WriteByte(':')
227		b.WriteString(strconv.Itoa(p.Column))
228		b.WriteByte('(')
229		b.WriteString(strconv.Itoa(f.pc))
230		b.WriteByte(')')
231		if f.prg.funcName != "" {
232			b.WriteByte(')')
233		}
234	} else {
235		if f.funcName != "" {
236			b.WriteString(f.funcName.String())
237			b.WriteString(" (")
238		}
239		b.WriteString("native")
240		if f.funcName != "" {
241			b.WriteByte(')')
242		}
243	}
244}
245
246type Exception struct {
247	val   Value
248	stack []StackFrame
249}
250
251type uncatchableException struct {
252	stack *[]StackFrame
253	err   error
254}
255
256type InterruptedError struct {
257	Exception
258	iface interface{}
259}
260
261type StackOverflowError struct {
262	Exception
263}
264
265func (e *InterruptedError) Value() interface{} {
266	return e.iface
267}
268
269func (e *InterruptedError) String() string {
270	if e == nil {
271		return "<nil>"
272	}
273	var b bytes.Buffer
274	if e.iface != nil {
275		b.WriteString(fmt.Sprint(e.iface))
276		b.WriteByte('\n')
277	}
278	e.writeFullStack(&b)
279	return b.String()
280}
281
282func (e *InterruptedError) Error() string {
283	if e == nil || e.iface == nil {
284		return "<nil>"
285	}
286	var b bytes.Buffer
287	b.WriteString(fmt.Sprint(e.iface))
288	e.writeShortStack(&b)
289	return b.String()
290}
291
292func (e *Exception) writeFullStack(b *bytes.Buffer) {
293	for _, frame := range e.stack {
294		b.WriteString("\tat ")
295		frame.Write(b)
296		b.WriteByte('\n')
297	}
298}
299
300func (e *Exception) writeShortStack(b *bytes.Buffer) {
301	if len(e.stack) > 0 && (e.stack[0].prg != nil || e.stack[0].funcName != "") {
302		b.WriteString(" at ")
303		e.stack[0].Write(b)
304	}
305}
306
307func (e *Exception) String() string {
308	if e == nil {
309		return "<nil>"
310	}
311	var b bytes.Buffer
312	if e.val != nil {
313		b.WriteString(e.val.String())
314		b.WriteByte('\n')
315	}
316	e.writeFullStack(&b)
317	return b.String()
318}
319
320func (e *Exception) Error() string {
321	if e == nil || e.val == nil {
322		return "<nil>"
323	}
324	var b bytes.Buffer
325	b.WriteString(e.val.String())
326	e.writeShortStack(&b)
327	return b.String()
328}
329
330func (e *Exception) Value() Value {
331	return e.val
332}
333
334func (r *Runtime) addToGlobal(name string, value Value) {
335	r.globalObject.self._putProp(unistring.String(name), value, true, false, true)
336}
337
338func (r *Runtime) createIterProto(val *Object) objectImpl {
339	o := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
340
341	o._putSym(SymIterator, valueProp(r.newNativeFunc(r.returnThis, nil, "[Symbol.iterator]", nil, 0), true, false, true))
342	return o
343}
344
345func (r *Runtime) init() {
346	r.rand = rand.Float64
347	r.now = time.Now
348	r.global.ObjectPrototype = r.newBaseObject(nil, classObject).val
349	r.globalObject = r.NewObject()
350
351	r.vm = &vm{
352		r: r,
353	}
354	r.vm.init()
355
356	funcProto := r.newNativeFunc(func(FunctionCall) Value {
357		return _undefined
358	}, nil, " ", nil, 0)
359	r.global.FunctionPrototype = funcProto
360	funcProtoObj := funcProto.self.(*nativeFuncObject)
361
362	r.global.IteratorPrototype = r.newLazyObject(r.createIterProto)
363
364	r.initObject()
365	r.initFunction()
366	r.initArray()
367	r.initString()
368	r.initGlobalObject()
369	r.initNumber()
370	r.initRegExp()
371	r.initDate()
372	r.initBoolean()
373	r.initProxy()
374	r.initReflect()
375
376	r.initErrors()
377
378	r.global.Eval = r.newNativeFunc(r.builtin_eval, nil, "eval", nil, 1)
379	r.addToGlobal("eval", r.global.Eval)
380
381	r.initMath()
382	r.initJSON()
383
384	r.initTypedArrays()
385	r.initSymbol()
386	r.initWeakSet()
387	r.initWeakMap()
388	r.initMap()
389	r.initSet()
390
391	r.global.thrower = r.newNativeFunc(r.builtin_thrower, nil, "thrower", nil, 0)
392	r.global.throwerProperty = &valueProperty{
393		getterFunc: r.global.thrower,
394		setterFunc: r.global.thrower,
395		accessor:   true,
396	}
397
398	funcProtoObj._put("caller", r.global.throwerProperty)
399	funcProtoObj._put("arguments", r.global.throwerProperty)
400}
401
402func (r *Runtime) typeErrorResult(throw bool, args ...interface{}) {
403	if throw {
404		panic(r.NewTypeError(args...))
405	}
406}
407
408func (r *Runtime) newError(typ *Object, format string, args ...interface{}) Value {
409	msg := fmt.Sprintf(format, args...)
410	return r.builtin_new(typ, []Value{newStringValue(msg)})
411}
412
413func (r *Runtime) throwReferenceError(name unistring.String) {
414	panic(r.newError(r.global.ReferenceError, "%s is not defined", name))
415}
416
417func (r *Runtime) newSyntaxError(msg string, offset int) Value {
418	return r.builtin_new(r.global.SyntaxError, []Value{newStringValue(msg)})
419}
420
421func newBaseObjectObj(obj, proto *Object, class string) *baseObject {
422	o := &baseObject{
423		class:      class,
424		val:        obj,
425		extensible: true,
426		prototype:  proto,
427	}
428	obj.self = o
429	o.init()
430	return o
431}
432
433func newGuardedObj(proto *Object, class string) *guardedObject {
434	return &guardedObject{
435		baseObject: baseObject{
436			class:      class,
437			extensible: true,
438			prototype:  proto,
439		},
440	}
441}
442
443func (r *Runtime) newBaseObject(proto *Object, class string) (o *baseObject) {
444	v := &Object{runtime: r}
445	return newBaseObjectObj(v, proto, class)
446}
447
448func (r *Runtime) newGuardedObject(proto *Object, class string) (o *guardedObject) {
449	v := &Object{runtime: r}
450	o = newGuardedObj(proto, class)
451	v.self = o
452	o.val = v
453	o.init()
454	return
455}
456
457func (r *Runtime) NewObject() (v *Object) {
458	return r.newBaseObject(r.global.ObjectPrototype, classObject).val
459}
460
461// CreateObject creates an object with given prototype. Equivalent of Object.create(proto).
462func (r *Runtime) CreateObject(proto *Object) *Object {
463	return r.newBaseObject(proto, classObject).val
464}
465
466func (r *Runtime) NewArray(items ...interface{}) *Object {
467	values := make([]Value, len(items))
468	for i, item := range items {
469		values[i] = r.ToValue(item)
470	}
471	return r.newArrayValues(values)
472}
473
474func (r *Runtime) NewTypeError(args ...interface{}) *Object {
475	msg := ""
476	if len(args) > 0 {
477		f, _ := args[0].(string)
478		msg = fmt.Sprintf(f, args[1:]...)
479	}
480	return r.builtin_new(r.global.TypeError, []Value{newStringValue(msg)})
481}
482
483func (r *Runtime) NewGoError(err error) *Object {
484	e := r.newError(r.global.GoError, err.Error()).(*Object)
485	e.Set("value", err)
486	return e
487}
488
489func (r *Runtime) newFunc(name unistring.String, len int, strict bool) (f *funcObject) {
490	v := &Object{runtime: r}
491
492	f = &funcObject{}
493	f.class = classFunction
494	f.val = v
495	f.extensible = true
496	f.strict = strict
497	v.self = f
498	f.prototype = r.global.FunctionPrototype
499	f.init(name, len)
500	return
501}
502
503func (r *Runtime) newArrowFunc(name unistring.String, len int, strict bool) (f *arrowFuncObject) {
504	v := &Object{runtime: r}
505
506	f = &arrowFuncObject{}
507	f.class = classFunction
508	f.val = v
509	f.extensible = true
510	f.strict = strict
511
512	vm := r.vm
513	var this Value
514	if vm.sb >= 0 {
515		this = vm.stack[vm.sb]
516	} else {
517		this = vm.r.globalObject
518	}
519
520	f.this = this
521	f.newTarget = vm.newTarget
522	v.self = f
523	f.prototype = r.global.FunctionPrototype
524	f.init(name, len)
525	return
526}
527
528func (r *Runtime) newNativeFuncObj(v *Object, call func(FunctionCall) Value, construct func(args []Value, proto *Object) *Object, name unistring.String, proto *Object, length int) *nativeFuncObject {
529	f := &nativeFuncObject{
530		baseFuncObject: baseFuncObject{
531			baseObject: baseObject{
532				class:      classFunction,
533				val:        v,
534				extensible: true,
535				prototype:  r.global.FunctionPrototype,
536			},
537		},
538		f:         call,
539		construct: r.wrapNativeConstruct(construct, proto),
540	}
541	v.self = f
542	f.init(name, length)
543	if proto != nil {
544		f._putProp("prototype", proto, false, false, false)
545	}
546	return f
547}
548
549func (r *Runtime) newNativeConstructor(call func(ConstructorCall) *Object, name unistring.String, length int) *Object {
550	v := &Object{runtime: r}
551
552	f := &nativeFuncObject{
553		baseFuncObject: baseFuncObject{
554			baseObject: baseObject{
555				class:      classFunction,
556				val:        v,
557				extensible: true,
558				prototype:  r.global.FunctionPrototype,
559			},
560		},
561	}
562
563	f.f = func(c FunctionCall) Value {
564		thisObj, _ := c.This.(*Object)
565		if thisObj != nil {
566			res := call(ConstructorCall{
567				This:      thisObj,
568				Arguments: c.Arguments,
569			})
570			if res == nil {
571				return _undefined
572			}
573			return res
574		}
575		return f.defaultConstruct(call, c.Arguments, nil)
576	}
577
578	f.construct = func(args []Value, newTarget *Object) *Object {
579		return f.defaultConstruct(call, args, newTarget)
580	}
581
582	v.self = f
583	f.init(name, length)
584
585	proto := r.NewObject()
586	proto.self._putProp("constructor", v, true, false, true)
587	f._putProp("prototype", proto, true, false, false)
588
589	return v
590}
591
592func (r *Runtime) newNativeConstructOnly(v *Object, ctor func(args []Value, newTarget *Object) *Object, defaultProto *Object, name unistring.String, length int) *nativeFuncObject {
593	if v == nil {
594		v = &Object{runtime: r}
595	}
596
597	f := &nativeFuncObject{
598		baseFuncObject: baseFuncObject{
599			baseObject: baseObject{
600				class:      classFunction,
601				val:        v,
602				extensible: true,
603				prototype:  r.global.FunctionPrototype,
604			},
605		},
606		f: func(call FunctionCall) Value {
607			return ctor(call.Arguments, nil)
608		},
609		construct: func(args []Value, newTarget *Object) *Object {
610			if newTarget == nil {
611				newTarget = v
612			}
613			return ctor(args, newTarget)
614		},
615	}
616	v.self = f
617	f.init(name, length)
618	if defaultProto != nil {
619		f._putProp("prototype", defaultProto, false, false, false)
620	}
621
622	return f
623}
624
625func (r *Runtime) newNativeFunc(call func(FunctionCall) Value, construct func(args []Value, proto *Object) *Object, name unistring.String, proto *Object, length int) *Object {
626	v := &Object{runtime: r}
627
628	f := &nativeFuncObject{
629		baseFuncObject: baseFuncObject{
630			baseObject: baseObject{
631				class:      classFunction,
632				val:        v,
633				extensible: true,
634				prototype:  r.global.FunctionPrototype,
635			},
636		},
637		f:         call,
638		construct: r.wrapNativeConstruct(construct, proto),
639	}
640	v.self = f
641	f.init(name, length)
642	if proto != nil {
643		f._putProp("prototype", proto, false, false, false)
644		proto.self._putProp("constructor", v, true, false, true)
645	}
646	return v
647}
648
649func (r *Runtime) newNativeFuncConstructObj(v *Object, construct func(args []Value, proto *Object) *Object, name unistring.String, proto *Object, length int) *nativeFuncObject {
650	f := &nativeFuncObject{
651		baseFuncObject: baseFuncObject{
652			baseObject: baseObject{
653				class:      classFunction,
654				val:        v,
655				extensible: true,
656				prototype:  r.global.FunctionPrototype,
657			},
658		},
659		f:         r.constructToCall(construct, proto),
660		construct: r.wrapNativeConstruct(construct, proto),
661	}
662
663	f.init(name, length)
664	if proto != nil {
665		f._putProp("prototype", proto, false, false, false)
666	}
667	return f
668}
669
670func (r *Runtime) newNativeFuncConstruct(construct func(args []Value, proto *Object) *Object, name unistring.String, prototype *Object, length int) *Object {
671	return r.newNativeFuncConstructProto(construct, name, prototype, r.global.FunctionPrototype, length)
672}
673
674func (r *Runtime) newNativeFuncConstructProto(construct func(args []Value, proto *Object) *Object, name unistring.String, prototype, proto *Object, length int) *Object {
675	v := &Object{runtime: r}
676
677	f := &nativeFuncObject{}
678	f.class = classFunction
679	f.val = v
680	f.extensible = true
681	v.self = f
682	f.prototype = proto
683	f.f = r.constructToCall(construct, prototype)
684	f.construct = r.wrapNativeConstruct(construct, prototype)
685	f.init(name, length)
686	if prototype != nil {
687		f._putProp("prototype", prototype, false, false, false)
688		prototype.self._putProp("constructor", v, true, false, true)
689	}
690	return v
691}
692
693func (r *Runtime) newPrimitiveObject(value Value, proto *Object, class string) *Object {
694	v := &Object{runtime: r}
695
696	o := &primitiveValueObject{}
697	o.class = class
698	o.val = v
699	o.extensible = true
700	v.self = o
701	o.prototype = proto
702	o.pValue = value
703	o.init()
704	return v
705}
706
707func (r *Runtime) builtin_Number(call FunctionCall) Value {
708	if len(call.Arguments) > 0 {
709		return call.Arguments[0].ToNumber()
710	} else {
711		return valueInt(0)
712	}
713}
714
715func (r *Runtime) builtin_newNumber(args []Value, proto *Object) *Object {
716	var v Value
717	if len(args) > 0 {
718		v = args[0].ToNumber()
719	} else {
720		v = intToValue(0)
721	}
722	return r.newPrimitiveObject(v, proto, classNumber)
723}
724
725func (r *Runtime) builtin_Boolean(call FunctionCall) Value {
726	if len(call.Arguments) > 0 {
727		if call.Arguments[0].ToBoolean() {
728			return valueTrue
729		} else {
730			return valueFalse
731		}
732	} else {
733		return valueFalse
734	}
735}
736
737func (r *Runtime) builtin_newBoolean(args []Value, proto *Object) *Object {
738	var v Value
739	if len(args) > 0 {
740		if args[0].ToBoolean() {
741			v = valueTrue
742		} else {
743			v = valueFalse
744		}
745	} else {
746		v = valueFalse
747	}
748	return r.newPrimitiveObject(v, proto, classBoolean)
749}
750
751func (r *Runtime) error_toString(call FunctionCall) Value {
752	var nameStr, msgStr valueString
753	obj := call.This.ToObject(r).self
754	name := obj.getStr("name", nil)
755	if name == nil || name == _undefined {
756		nameStr = asciiString("Error")
757	} else {
758		nameStr = name.toString()
759	}
760	msg := obj.getStr("message", nil)
761	if msg == nil || msg == _undefined {
762		msgStr = stringEmpty
763	} else {
764		msgStr = msg.toString()
765	}
766	if nameStr.length() == 0 {
767		return msgStr
768	}
769	if msgStr.length() == 0 {
770		return nameStr
771	}
772	var sb valueStringBuilder
773	sb.WriteString(nameStr)
774	sb.WriteString(asciiString(": "))
775	sb.WriteString(msgStr)
776	return sb.String()
777}
778
779func (r *Runtime) builtin_Error(args []Value, proto *Object) *Object {
780	obj := r.newBaseObject(proto, classError)
781	if len(args) > 0 && args[0] != _undefined {
782		obj._putProp("message", args[0], true, false, true)
783	}
784	return obj.val
785}
786
787func (r *Runtime) builtin_new(construct *Object, args []Value) *Object {
788	return r.toConstructor(construct)(args, nil)
789}
790
791func (r *Runtime) throw(e Value) {
792	panic(e)
793}
794
795func (r *Runtime) builtin_thrower(call FunctionCall) Value {
796	obj := r.toObject(call.This)
797	strict := true
798	switch fn := obj.self.(type) {
799	case *funcObject:
800		strict = fn.strict
801	}
802	r.typeErrorResult(strict, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them")
803	return nil
804}
805
806func (r *Runtime) eval(srcVal valueString, direct, strict bool, this Value) Value {
807	src := escapeInvalidUtf16(srcVal)
808	vm := r.vm
809	inGlobal := true
810	if direct {
811		for s := vm.stash; s != nil; s = s.outer {
812			if s.variable {
813				inGlobal = false
814				break
815			}
816		}
817	}
818	p, err := r.compile("<eval>", src, strict, true, inGlobal)
819	if err != nil {
820		panic(err)
821	}
822
823	vm.pushCtx()
824	vm.prg = p
825	vm.pc = 0
826	vm.args = 0
827	vm.result = _undefined
828	if !direct {
829		vm.stash = &r.global.stash
830	}
831	vm.sb = vm.sp
832	vm.push(this)
833	vm.run()
834	retval := vm.result
835	vm.popCtx()
836	vm.halt = false
837	vm.sp -= 1
838	return retval
839}
840
841func (r *Runtime) builtin_eval(call FunctionCall) Value {
842	if len(call.Arguments) == 0 {
843		return _undefined
844	}
845	if str, ok := call.Arguments[0].(valueString); ok {
846		return r.eval(str, false, false, r.globalObject)
847	}
848	return call.Arguments[0]
849}
850
851func (r *Runtime) constructToCall(construct func(args []Value, proto *Object) *Object, proto *Object) func(call FunctionCall) Value {
852	return func(call FunctionCall) Value {
853		return construct(call.Arguments, proto)
854	}
855}
856
857func (r *Runtime) wrapNativeConstruct(c func(args []Value, proto *Object) *Object, proto *Object) func(args []Value, newTarget *Object) *Object {
858	if c == nil {
859		return nil
860	}
861	return func(args []Value, newTarget *Object) *Object {
862		var p *Object
863		if newTarget != nil {
864			if pp, ok := newTarget.self.getStr("prototype", nil).(*Object); ok {
865				p = pp
866			}
867		}
868		if p == nil {
869			p = proto
870		}
871		return c(args, p)
872	}
873}
874
875func (r *Runtime) toCallable(v Value) func(FunctionCall) Value {
876	if call, ok := r.toObject(v).self.assertCallable(); ok {
877		return call
878	}
879	r.typeErrorResult(true, "Value is not callable: %s", v.toString())
880	return nil
881}
882
883func (r *Runtime) checkObjectCoercible(v Value) {
884	switch v.(type) {
885	case valueUndefined, valueNull:
886		r.typeErrorResult(true, "Value is not object coercible")
887	}
888}
889
890func toInt8(v Value) int8 {
891	v = v.ToNumber()
892	if i, ok := v.(valueInt); ok {
893		return int8(i)
894	}
895
896	if f, ok := v.(valueFloat); ok {
897		f := float64(f)
898		if !math.IsNaN(f) && !math.IsInf(f, 0) {
899			return int8(int64(f))
900		}
901	}
902	return 0
903}
904
905func toUint8(v Value) uint8 {
906	v = v.ToNumber()
907	if i, ok := v.(valueInt); ok {
908		return uint8(i)
909	}
910
911	if f, ok := v.(valueFloat); ok {
912		f := float64(f)
913		if !math.IsNaN(f) && !math.IsInf(f, 0) {
914			return uint8(int64(f))
915		}
916	}
917	return 0
918}
919
920func toUint8Clamp(v Value) uint8 {
921	v = v.ToNumber()
922	if i, ok := v.(valueInt); ok {
923		if i < 0 {
924			return 0
925		}
926		if i <= 255 {
927			return uint8(i)
928		}
929		return 255
930	}
931
932	if num, ok := v.(valueFloat); ok {
933		num := float64(num)
934		if !math.IsNaN(num) {
935			if num < 0 {
936				return 0
937			}
938			if num > 255 {
939				return 255
940			}
941			f := math.Floor(num)
942			f1 := f + 0.5
943			if f1 < num {
944				return uint8(f + 1)
945			}
946			if f1 > num {
947				return uint8(f)
948			}
949			r := uint8(f)
950			if r&1 != 0 {
951				return r + 1
952			}
953			return r
954		}
955	}
956	return 0
957}
958
959func toInt16(v Value) int16 {
960	v = v.ToNumber()
961	if i, ok := v.(valueInt); ok {
962		return int16(i)
963	}
964
965	if f, ok := v.(valueFloat); ok {
966		f := float64(f)
967		if !math.IsNaN(f) && !math.IsInf(f, 0) {
968			return int16(int64(f))
969		}
970	}
971	return 0
972}
973
974func toUint16(v Value) uint16 {
975	v = v.ToNumber()
976	if i, ok := v.(valueInt); ok {
977		return uint16(i)
978	}
979
980	if f, ok := v.(valueFloat); ok {
981		f := float64(f)
982		if !math.IsNaN(f) && !math.IsInf(f, 0) {
983			return uint16(int64(f))
984		}
985	}
986	return 0
987}
988
989func toInt32(v Value) int32 {
990	v = v.ToNumber()
991	if i, ok := v.(valueInt); ok {
992		return int32(i)
993	}
994
995	if f, ok := v.(valueFloat); ok {
996		f := float64(f)
997		if !math.IsNaN(f) && !math.IsInf(f, 0) {
998			return int32(int64(f))
999		}
1000	}
1001	return 0
1002}
1003
1004func toUint32(v Value) uint32 {
1005	v = v.ToNumber()
1006	if i, ok := v.(valueInt); ok {
1007		return uint32(i)
1008	}
1009
1010	if f, ok := v.(valueFloat); ok {
1011		f := float64(f)
1012		if !math.IsNaN(f) && !math.IsInf(f, 0) {
1013			return uint32(int64(f))
1014		}
1015	}
1016	return 0
1017}
1018
1019func toInt64(v Value) int64 {
1020	v = v.ToNumber()
1021	if i, ok := v.(valueInt); ok {
1022		return int64(i)
1023	}
1024
1025	if f, ok := v.(valueFloat); ok {
1026		f := float64(f)
1027		if !math.IsNaN(f) && !math.IsInf(f, 0) {
1028			return int64(f)
1029		}
1030	}
1031	return 0
1032}
1033
1034func toUint64(v Value) uint64 {
1035	v = v.ToNumber()
1036	if i, ok := v.(valueInt); ok {
1037		return uint64(i)
1038	}
1039
1040	if f, ok := v.(valueFloat); ok {
1041		f := float64(f)
1042		if !math.IsNaN(f) && !math.IsInf(f, 0) {
1043			return uint64(int64(f))
1044		}
1045	}
1046	return 0
1047}
1048
1049func toInt(v Value) int {
1050	v = v.ToNumber()
1051	if i, ok := v.(valueInt); ok {
1052		return int(i)
1053	}
1054
1055	if f, ok := v.(valueFloat); ok {
1056		f := float64(f)
1057		if !math.IsNaN(f) && !math.IsInf(f, 0) {
1058			return int(f)
1059		}
1060	}
1061	return 0
1062}
1063
1064func toUint(v Value) uint {
1065	v = v.ToNumber()
1066	if i, ok := v.(valueInt); ok {
1067		return uint(i)
1068	}
1069
1070	if f, ok := v.(valueFloat); ok {
1071		f := float64(f)
1072		if !math.IsNaN(f) && !math.IsInf(f, 0) {
1073			return uint(int64(f))
1074		}
1075	}
1076	return 0
1077}
1078
1079func toFloat32(v Value) float32 {
1080	return float32(v.ToFloat())
1081}
1082
1083func toLength(v Value) int64 {
1084	if v == nil {
1085		return 0
1086	}
1087	i := v.ToInteger()
1088	if i < 0 {
1089		return 0
1090	}
1091	if i >= maxInt {
1092		return maxInt - 1
1093	}
1094	return i
1095}
1096
1097func toIntStrict(i int64) int {
1098	if bits.UintSize == 32 {
1099		if i > math.MaxInt32 || i < math.MinInt32 {
1100			panic(rangeError("Integer value overflows 32-bit int"))
1101		}
1102	}
1103	return int(i)
1104}
1105
1106func toIntClamp(i int64) int {
1107	if bits.UintSize == 32 {
1108		if i > math.MaxInt32 {
1109			return math.MaxInt32
1110		}
1111		if i < math.MinInt32 {
1112			return math.MinInt32
1113		}
1114	}
1115	return int(i)
1116}
1117
1118func (r *Runtime) toIndex(v Value) int {
1119	intIdx := v.ToInteger()
1120	if intIdx >= 0 && intIdx < maxInt {
1121		if bits.UintSize == 32 && intIdx >= math.MaxInt32 {
1122			panic(r.newError(r.global.RangeError, "Index %s overflows int", v.String()))
1123		}
1124		return int(intIdx)
1125	}
1126	panic(r.newError(r.global.RangeError, "Invalid index %s", v.String()))
1127}
1128
1129func (r *Runtime) toBoolean(b bool) Value {
1130	if b {
1131		return valueTrue
1132	} else {
1133		return valueFalse
1134	}
1135}
1136
1137// New creates an instance of a Javascript runtime that can be used to run code. Multiple instances may be created and
1138// used simultaneously, however it is not possible to pass JS values across runtimes.
1139func New() *Runtime {
1140	r := &Runtime{}
1141	r.init()
1142	return r
1143}
1144
1145// Compile creates an internal representation of the JavaScript code that can be later run using the Runtime.RunProgram()
1146// method. This representation is not linked to a runtime in any way and can be run in multiple runtimes (possibly
1147// at the same time).
1148func Compile(name, src string, strict bool) (*Program, error) {
1149	return compile(name, src, strict, false, true)
1150}
1151
1152// CompileAST creates an internal representation of the JavaScript code that can be later run using the Runtime.RunProgram()
1153// method. This representation is not linked to a runtime in any way and can be run in multiple runtimes (possibly
1154// at the same time).
1155func CompileAST(prg *js_ast.Program, strict bool) (*Program, error) {
1156	return compileAST(prg, strict, false, true)
1157}
1158
1159// MustCompile is like Compile but panics if the code cannot be compiled.
1160// It simplifies safe initialization of global variables holding compiled JavaScript code.
1161func MustCompile(name, src string, strict bool) *Program {
1162	prg, err := Compile(name, src, strict)
1163	if err != nil {
1164		panic(err)
1165	}
1166
1167	return prg
1168}
1169
1170// Parse takes a source string and produces a parsed AST. Use this function if you want to pass options
1171// to the parser, e.g.:
1172//
1173//  p, err := Parse("test.js", "var a = true", parser.WithDisableSourceMaps)
1174//  if err != nil { /* ... */ }
1175//  prg, err := CompileAST(p, true)
1176//  // ...
1177//
1178// Otherwise use Compile which combines both steps.
1179func Parse(name, src string, options ...parser.Option) (prg *js_ast.Program, err error) {
1180	prg, err1 := parser.ParseFile(nil, name, src, 0, options...)
1181	if err1 != nil {
1182		// FIXME offset
1183		err = &CompilerSyntaxError{
1184			CompilerError: CompilerError{
1185				Message: err1.Error(),
1186			},
1187		}
1188	}
1189	return
1190}
1191
1192func compile(name, src string, strict, eval, inGlobal bool, parserOptions ...parser.Option) (p *Program, err error) {
1193	prg, err := Parse(name, src, parserOptions...)
1194	if err != nil {
1195		return
1196	}
1197
1198	return compileAST(prg, strict, eval, inGlobal)
1199}
1200
1201func compileAST(prg *js_ast.Program, strict, eval, inGlobal bool) (p *Program, err error) {
1202	c := newCompiler()
1203
1204	defer func() {
1205		if x := recover(); x != nil {
1206			p = nil
1207			switch x1 := x.(type) {
1208			case *CompilerSyntaxError:
1209				err = x1
1210			default:
1211				panic(x)
1212			}
1213		}
1214	}()
1215
1216	c.compile(prg, strict, eval, inGlobal)
1217	p = c.p
1218	return
1219}
1220
1221func (r *Runtime) compile(name, src string, strict, eval, inGlobal bool) (p *Program, err error) {
1222	p, err = compile(name, src, strict, eval, inGlobal, r.parserOptions...)
1223	if err != nil {
1224		switch x1 := err.(type) {
1225		case *CompilerSyntaxError:
1226			err = &Exception{
1227				val: r.builtin_new(r.global.SyntaxError, []Value{newStringValue(x1.Error())}),
1228			}
1229		case *CompilerReferenceError:
1230			err = &Exception{
1231				val: r.newError(r.global.ReferenceError, x1.Message),
1232			} // TODO proper message
1233		}
1234	}
1235	return
1236}
1237
1238// RunString executes the given string in the global context.
1239func (r *Runtime) RunString(str string) (Value, error) {
1240	return r.RunScript("", str)
1241}
1242
1243// RunScript executes the given string in the global context.
1244func (r *Runtime) RunScript(name, src string) (Value, error) {
1245	p, err := r.compile(name, src, false, false, true)
1246
1247	if err != nil {
1248		return nil, err
1249	}
1250
1251	return r.RunProgram(p)
1252}
1253
1254// RunProgram executes a pre-compiled (see Compile()) code in the global context.
1255func (r *Runtime) RunProgram(p *Program) (result Value, err error) {
1256	defer func() {
1257		if x := recover(); x != nil {
1258			if ex, ok := x.(*uncatchableException); ok {
1259				err = ex.err
1260			} else {
1261				panic(x)
1262			}
1263		}
1264	}()
1265	vm := r.vm
1266	recursive := false
1267	if len(vm.callStack) > 0 {
1268		recursive = true
1269		vm.pushCtx()
1270		vm.stash = &r.global.stash
1271		vm.sb = vm.sp - 1
1272	}
1273	vm.prg = p
1274	vm.pc = 0
1275	vm.result = _undefined
1276	ex := vm.runTry()
1277	if ex == nil {
1278		result = r.vm.result
1279	} else {
1280		err = ex
1281	}
1282	if recursive {
1283		vm.popCtx()
1284		vm.halt = false
1285		vm.clearStack()
1286	} else {
1287		vm.stack = nil
1288		vm.prg = nil
1289		r.leave()
1290	}
1291	return
1292}
1293
1294// CaptureCallStack appends the current call stack frames to the stack slice (which may be nil) up to the specified depth.
1295// The most recent frame will be the first one.
1296// If depth <= 0 or more than the number of available frames, returns the entire stack.
1297// This method is not safe for concurrent use and should only be called by a Go function that is
1298// called from a running script.
1299func (r *Runtime) CaptureCallStack(depth int, stack []StackFrame) []StackFrame {
1300	l := len(r.vm.callStack)
1301	var offset int
1302	if depth > 0 {
1303		offset = l - depth + 1
1304		if offset < 0 {
1305			offset = 0
1306		}
1307	}
1308	if stack == nil {
1309		stack = make([]StackFrame, 0, l-offset+1)
1310	}
1311	return r.vm.captureStack(stack, offset)
1312}
1313
1314// Interrupt a running JavaScript. The corresponding Go call will return an *InterruptedError containing v.
1315// Note, it only works while in JavaScript code, it does not interrupt native Go functions (which includes all built-ins).
1316// If the runtime is currently not running, it will be immediately interrupted on the next Run*() call.
1317// To avoid that use ClearInterrupt()
1318func (r *Runtime) Interrupt(v interface{}) {
1319	r.vm.Interrupt(v)
1320}
1321
1322// ClearInterrupt resets the interrupt flag. Typically this needs to be called before the runtime
1323// is made available for re-use if there is a chance it could have been interrupted with Interrupt().
1324// Otherwise if Interrupt() was called when runtime was not running (e.g. if it had already finished)
1325// so that Interrupt() didn't actually trigger, an attempt to use the runtime will immediately cause
1326// an interruption. It is up to the user to ensure proper synchronisation so that ClearInterrupt() is
1327// only called when the runtime has finished and there is no chance of a concurrent Interrupt() call.
1328func (r *Runtime) ClearInterrupt() {
1329	r.vm.ClearInterrupt()
1330}
1331
1332/*
1333ToValue converts a Go value into a JavaScript value of a most appropriate type. Structural types (such as structs, maps
1334and slices) are wrapped so that changes are reflected on the original value which can be retrieved using Value.Export().
1335
1336WARNING! There are two very important caveats to bear in mind when modifying wrapped Go structs, maps and
1337slices.
1338
13391. If a slice is passed by value (not as a pointer), resizing the slice does not reflect on the original
1340value. Moreover, extending the slice may result in the underlying array being re-allocated and copied.
1341For example:
1342
1343 a := []interface{}{1}
1344 vm.Set("a", a)
1345 vm.RunString(`a.push(2); a[0] = 0;`)
1346 fmt.Println(a[0]) // prints "1"
1347
13482. If a regular JavaScript Object is assigned as an element of a wrapped Go struct, map or array, it is
1349Export()'ed and therefore copied. This may result in an unexpected behaviour in JavaScript:
1350
1351 m := map[string]interface{}{}
1352 vm.Set("m", m)
1353 vm.RunString(`
1354 var obj = {test: false};
1355 m.obj = obj; // obj gets Export()'ed, i.e. copied to a new map[string]interface{} and then this map is set as m["obj"]
1356 obj.test = true; // note, m.obj.test is still false
1357 `)
1358 fmt.Println(m["obj"].(map[string]interface{})["test"]) // prints "false"
1359
1360Notes on individual types:
1361
1362Primitive types
1363
1364Primitive types (numbers, string, bool) are converted to the corresponding JavaScript primitives.
1365
1366Strings
1367
1368Because of the difference in internal string representation between ECMAScript (which uses UTF-16) and Go (which uses
1369UTF-8) conversion from JS to Go may be lossy. In particular, code points that can be part of UTF-16 surrogate pairs
1370(0xD800-0xDFFF) cannot be represented in UTF-8 unless they form a valid surrogate pair and are replaced with
1371utf8.RuneError.
1372
1373Nil
1374
1375Nil is converted to null.
1376
1377Functions
1378
1379func(FunctionCall) Value is treated as a native JavaScript function. This increases performance because there are no
1380automatic argument and return value type conversions (which involves reflect). Attempting to use
1381the function as a constructor will result in a TypeError.
1382
1383func(FunctionCall, *Runtime) Value is treated as above, except the *Runtime is also passed as a parameter.
1384
1385func(ConstructorCall) *Object is treated as a native constructor, allowing to use it with the new
1386operator:
1387
1388 func MyObject(call goja.ConstructorCall) *goja.Object {
1389    // call.This contains the newly created object as per http://www.ecma-international.org/ecma-262/5.1/index.html#sec-13.2.2
1390    // call.Arguments contain arguments passed to the function
1391
1392    call.This.Set("method", method)
1393
1394    //...
1395
1396    // If return value is a non-nil *Object, it will be used instead of call.This
1397    // This way it is possible to return a Go struct or a map converted
1398    // into goja.Value using ToValue(), however in this case
1399    // instanceof will not work as expected.
1400    return nil
1401 }
1402
1403 runtime.Set("MyObject", MyObject)
1404
1405Then it can be used in JS as follows:
1406
1407 var o = new MyObject(arg);
1408 var o1 = MyObject(arg); // same thing
1409 o instanceof MyObject && o1 instanceof MyObject; // true
1410
1411When a native constructor is called directly (without the new operator) its behavior depends on
1412this value: if it's an Object, it is passed through, otherwise a new one is created exactly as
1413if it was called with the new operator. In either case call.NewTarget will be nil.
1414
1415func(ConstructorCall, *Runtime) *Object is treated as above, except the *Runtime is also passed as a parameter.
1416
1417Any other Go function is wrapped so that the arguments are automatically converted into the required Go types and the
1418return value is converted to a JavaScript value (using this method).  If conversion is not possible, a TypeError is
1419thrown.
1420
1421Functions with multiple return values return an Array. If the last return value is an `error` it is not returned but
1422converted into a JS exception. If the error is *Exception, it is thrown as is, otherwise it's wrapped in a GoEerror.
1423Note that if there are exactly two return values and the last is an `error`, the function returns the first value as is,
1424not an Array.
1425
1426Structs
1427
1428Structs are converted to Object-like values. Fields and methods are available as properties, their values are
1429results of this method (ToValue()) applied to the corresponding Go value.
1430
1431Field properties are writable (if the struct is addressable) and non-configurable.
1432Method properties are non-writable and non-configurable.
1433
1434Attempt to define a new property or delete an existing property will fail (throw in strict mode) unless it's a Symbol
1435property. Symbol properties only exist in the wrapper and do not affect the underlying Go value.
1436Note that because a wrapper is created every time a property is accessed it may lead to unexpected results such as this:
1437
1438 type Field struct{
1439 }
1440 type S struct {
1441	Field *Field
1442 }
1443 var s = S{
1444	Field: &Field{},
1445 }
1446 vm := New()
1447 vm.Set("s", &s)
1448 res, err := vm.RunString(`
1449 var sym = Symbol(66);
1450 var field1 = s.Field;
1451 field1[sym] = true;
1452 var field2 = s.Field;
1453 field1 === field2; // true, because the equality operation compares the wrapped values, not the wrappers
1454 field1[sym] === true; // true
1455 field2[sym] === undefined; // also true
1456 `)
1457
1458The same applies to values from maps and slices as well.
1459
1460Handling of time.Time
1461
1462time.Time does not get special treatment and therefore is converted just like any other `struct` providing access to
1463all its methods. This is done deliberately instead of converting it to a `Date` because these two types are not fully
1464compatible: `time.Time` includes zone, whereas JS `Date` doesn't. Doing the conversion implicitly therefore would
1465result in a loss of information.
1466
1467If you need to convert it to a `Date`, it can be done either in JS:
1468
1469 var d = new Date(goval.UnixNano()/1e6);
1470
1471... or in Go:
1472
1473 now := time.Now()
1474 vm := New()
1475 val, err := vm.New(vm.Get("Date").ToObject(vm), vm.ToValue(now.UnixNano()/1e6))
1476 if err != nil {
1477	...
1478 }
1479 vm.Set("d", val)
1480
1481Note that Value.Export() for a `Date` value returns time.Time in local timezone.
1482
1483Maps
1484
1485Maps with string or integer key type are converted into host objects that largely behave like a JavaScript Object.
1486
1487Maps with methods
1488
1489If a map type has at least one method defined, the properties of the resulting Object represent methods, not map keys.
1490This is because in JavaScript there is no distinction between 'object.key` and `object[key]`, unlike Go.
1491If access to the map values is required, it can be achieved by defining another method or, if it's not possible, by
1492defining an external getter function.
1493
1494Slices
1495
1496Slices are converted into host objects that behave largely like JavaScript Array. It has the appropriate
1497prototype and all the usual methods should work. There is, however, a caveat: converted Arrays may not contain holes
1498(because Go slices cannot). This means that hasOwnProperty(n) always returns `true` if n < length. Deleting an item with
1499an index < length will set it to a zero value (but the property will remain). Nil slice elements are be converted to
1500`null`. Accessing an element beyond `length` returns `undefined`. Also see the warning above about passing slices as
1501values (as opposed to pointers).
1502
1503Any other type is converted to a generic reflect based host object. Depending on the underlying type it behaves similar
1504to a Number, String, Boolean or Object.
1505
1506Note that the underlying type is not lost, calling Export() returns the original Go value. This applies to all
1507reflect based types.
1508*/
1509func (r *Runtime) ToValue(i interface{}) Value {
1510	switch i := i.(type) {
1511	case nil:
1512		return _null
1513	case *Object:
1514		if i == nil || i.runtime == nil {
1515			return _null
1516		}
1517		if i.runtime != r {
1518			panic(r.NewTypeError("Illegal runtime transition of an Object"))
1519		}
1520		return i
1521	case valueContainer:
1522		return i.toValue(r)
1523	case Value:
1524		return i
1525	case string:
1526		return newStringValue(i)
1527	case bool:
1528		if i {
1529			return valueTrue
1530		} else {
1531			return valueFalse
1532		}
1533	case func(FunctionCall) Value:
1534		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
1535		return r.newNativeFunc(i, nil, name, nil, 0)
1536	case func(FunctionCall, *Runtime) Value:
1537		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
1538		return r.newNativeFunc(func(call FunctionCall) Value {
1539			return i(call, r)
1540		}, nil, name, nil, 0)
1541	case func(ConstructorCall) *Object:
1542		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
1543		return r.newNativeConstructor(i, name, 0)
1544	case func(ConstructorCall, *Runtime) *Object:
1545		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
1546		return r.newNativeConstructor(func(call ConstructorCall) *Object {
1547			return i(call, r)
1548		}, name, 0)
1549	case int:
1550		return intToValue(int64(i))
1551	case int8:
1552		return intToValue(int64(i))
1553	case int16:
1554		return intToValue(int64(i))
1555	case int32:
1556		return intToValue(int64(i))
1557	case int64:
1558		return intToValue(i)
1559	case uint:
1560		if uint64(i) <= math.MaxInt64 {
1561			return intToValue(int64(i))
1562		} else {
1563			return floatToValue(float64(i))
1564		}
1565	case uint8:
1566		return intToValue(int64(i))
1567	case uint16:
1568		return intToValue(int64(i))
1569	case uint32:
1570		return intToValue(int64(i))
1571	case uint64:
1572		if i <= math.MaxInt64 {
1573			return intToValue(int64(i))
1574		}
1575		return floatToValue(float64(i))
1576	case float32:
1577		return floatToValue(float64(i))
1578	case float64:
1579		return floatToValue(i)
1580	case map[string]interface{}:
1581		if i == nil {
1582			return _null
1583		}
1584		obj := &Object{runtime: r}
1585		m := &objectGoMapSimple{
1586			baseObject: baseObject{
1587				val:        obj,
1588				extensible: true,
1589			},
1590			data: i,
1591		}
1592		obj.self = m
1593		m.init()
1594		return obj
1595	case []interface{}:
1596		if i == nil {
1597			return _null
1598		}
1599		obj := &Object{runtime: r}
1600		a := &objectGoSlice{
1601			baseObject: baseObject{
1602				val: obj,
1603			},
1604			data: &i,
1605		}
1606		obj.self = a
1607		a.init()
1608		return obj
1609	case *[]interface{}:
1610		if i == nil {
1611			return _null
1612		}
1613		obj := &Object{runtime: r}
1614		a := &objectGoSlice{
1615			baseObject: baseObject{
1616				val: obj,
1617			},
1618			data: i,
1619		}
1620		obj.self = a
1621		a.init()
1622		return obj
1623	}
1624
1625	origValue := reflect.ValueOf(i)
1626	value := origValue
1627	for value.Kind() == reflect.Ptr {
1628		value = reflect.Indirect(value)
1629	}
1630
1631	if !value.IsValid() {
1632		return _null
1633	}
1634
1635	switch value.Kind() {
1636	case reflect.Map:
1637		if value.Type().NumMethod() == 0 {
1638			switch value.Type().Key().Kind() {
1639			case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
1640				reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
1641				reflect.Float64, reflect.Float32:
1642
1643				obj := &Object{runtime: r}
1644				m := &objectGoMapReflect{
1645					objectGoReflect: objectGoReflect{
1646						baseObject: baseObject{
1647							val:        obj,
1648							extensible: true,
1649						},
1650						origValue: origValue,
1651						value:     value,
1652					},
1653				}
1654				m.init()
1655				obj.self = m
1656				return obj
1657			}
1658		}
1659	case reflect.Slice:
1660		obj := &Object{runtime: r}
1661		a := &objectGoSliceReflect{
1662			objectGoReflect: objectGoReflect{
1663				baseObject: baseObject{
1664					val: obj,
1665				},
1666				origValue: origValue,
1667				value:     value,
1668			},
1669		}
1670		a.init()
1671		obj.self = a
1672		return obj
1673	case reflect.Func:
1674		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
1675		return r.newNativeFunc(r.wrapReflectFunc(value), nil, name, nil, value.Type().NumIn())
1676	}
1677
1678	obj := &Object{runtime: r}
1679	o := &objectGoReflect{
1680		baseObject: baseObject{
1681			val: obj,
1682		},
1683		origValue: origValue,
1684		value:     value,
1685	}
1686	obj.self = o
1687	o.init()
1688	return obj
1689}
1690
1691func (r *Runtime) wrapReflectFunc(value reflect.Value) func(FunctionCall) Value {
1692	return func(call FunctionCall) Value {
1693		typ := value.Type()
1694		nargs := typ.NumIn()
1695		var in []reflect.Value
1696
1697		if l := len(call.Arguments); l < nargs {
1698			// fill missing arguments with zero values
1699			n := nargs
1700			if typ.IsVariadic() {
1701				n--
1702			}
1703			in = make([]reflect.Value, n)
1704			for i := l; i < n; i++ {
1705				in[i] = reflect.Zero(typ.In(i))
1706			}
1707		} else {
1708			if l > nargs && !typ.IsVariadic() {
1709				l = nargs
1710			}
1711			in = make([]reflect.Value, l)
1712		}
1713
1714		callSlice := false
1715		for i, a := range call.Arguments {
1716			var t reflect.Type
1717
1718			n := i
1719			if n >= nargs-1 && typ.IsVariadic() {
1720				if n > nargs-1 {
1721					n = nargs - 1
1722				}
1723
1724				t = typ.In(n).Elem()
1725			} else if n > nargs-1 { // ignore extra arguments
1726				break
1727			} else {
1728				t = typ.In(n)
1729			}
1730
1731			// if this is a variadic Go function, and the caller has supplied
1732			// exactly the number of JavaScript arguments required, and this
1733			// is the last JavaScript argument, try treating the it as the
1734			// actual set of variadic Go arguments. if that succeeds, break
1735			// out of the loop.
1736			if typ.IsVariadic() && len(call.Arguments) == nargs && i == nargs-1 {
1737				v := reflect.New(typ.In(n)).Elem()
1738				if err := r.toReflectValue(a, v, &objectExportCtx{}); err == nil {
1739					in[i] = v
1740					callSlice = true
1741					break
1742				}
1743			}
1744			v := reflect.New(t).Elem()
1745			err := r.toReflectValue(a, v, &objectExportCtx{})
1746			if err != nil {
1747				panic(r.newError(r.global.TypeError, "could not convert function call parameter %v to %v", a, t))
1748			}
1749			in[i] = v
1750		}
1751
1752		var out []reflect.Value
1753		if callSlice {
1754			out = value.CallSlice(in)
1755		} else {
1756			out = value.Call(in)
1757		}
1758
1759		if len(out) == 0 {
1760			return _undefined
1761		}
1762
1763		if last := out[len(out)-1]; last.Type().Name() == "error" {
1764			if !last.IsNil() {
1765				err := last.Interface()
1766				if _, ok := err.(*Exception); ok {
1767					panic(err)
1768				}
1769				panic(r.NewGoError(last.Interface().(error)))
1770			}
1771			out = out[:len(out)-1]
1772		}
1773
1774		switch len(out) {
1775		case 0:
1776			return _undefined
1777		case 1:
1778			return r.ToValue(out[0].Interface())
1779		default:
1780			s := make([]interface{}, len(out))
1781			for i, v := range out {
1782				s[i] = v.Interface()
1783			}
1784
1785			return r.ToValue(s)
1786		}
1787	}
1788}
1789
1790func (r *Runtime) toReflectValue(v Value, dst reflect.Value, ctx *objectExportCtx) error {
1791	typ := dst.Type()
1792
1793	if typ == typeValue {
1794		dst.Set(reflect.ValueOf(v))
1795		return nil
1796	}
1797
1798	if typ == typeObject {
1799		if obj, ok := v.(*Object); ok {
1800			dst.Set(reflect.ValueOf(obj))
1801			return nil
1802		}
1803	}
1804
1805	if typ == typeCallable {
1806		if fn, ok := AssertFunction(v); ok {
1807			dst.Set(reflect.ValueOf(fn))
1808			return nil
1809		}
1810	}
1811
1812	et := v.ExportType()
1813	if et == nil || et == reflectTypeNil {
1814		dst.Set(reflect.Zero(typ))
1815		return nil
1816	}
1817
1818	kind := typ.Kind()
1819	for i := 0; ; i++ {
1820		if et.AssignableTo(typ) {
1821			ev := reflect.ValueOf(exportValue(v, ctx))
1822			for ; i > 0; i-- {
1823				ev = ev.Elem()
1824			}
1825			dst.Set(ev)
1826			return nil
1827		}
1828		expKind := et.Kind()
1829		if expKind == kind && et.ConvertibleTo(typ) || expKind == reflect.String && typ == typeBytes {
1830			ev := reflect.ValueOf(exportValue(v, ctx))
1831			for ; i > 0; i-- {
1832				ev = ev.Elem()
1833			}
1834			dst.Set(ev.Convert(typ))
1835			return nil
1836		}
1837		if expKind == reflect.Ptr {
1838			et = et.Elem()
1839		} else {
1840			break
1841		}
1842	}
1843
1844	if typ == typeTime {
1845		if obj, ok := v.(*Object); ok {
1846			if d, ok := obj.self.(*dateObject); ok {
1847				dst.Set(reflect.ValueOf(d.time()))
1848				return nil
1849			}
1850		}
1851		if et.Kind() == reflect.String {
1852			tme, ok := dateParse(v.String())
1853			if !ok {
1854				return fmt.Errorf("could not convert string %v to %v", v, typ)
1855			}
1856			dst.Set(reflect.ValueOf(tme))
1857			return nil
1858		}
1859	}
1860
1861	switch kind {
1862	case reflect.String:
1863		dst.Set(reflect.ValueOf(v.String()).Convert(typ))
1864		return nil
1865	case reflect.Bool:
1866		dst.Set(reflect.ValueOf(v.ToBoolean()).Convert(typ))
1867		return nil
1868	case reflect.Int:
1869		dst.Set(reflect.ValueOf(toInt(v)).Convert(typ))
1870		return nil
1871	case reflect.Int64:
1872		dst.Set(reflect.ValueOf(toInt64(v)).Convert(typ))
1873		return nil
1874	case reflect.Int32:
1875		dst.Set(reflect.ValueOf(toInt32(v)).Convert(typ))
1876		return nil
1877	case reflect.Int16:
1878		dst.Set(reflect.ValueOf(toInt16(v)).Convert(typ))
1879		return nil
1880	case reflect.Int8:
1881		dst.Set(reflect.ValueOf(toInt8(v)).Convert(typ))
1882		return nil
1883	case reflect.Uint:
1884		dst.Set(reflect.ValueOf(toUint(v)).Convert(typ))
1885		return nil
1886	case reflect.Uint64:
1887		dst.Set(reflect.ValueOf(toUint64(v)).Convert(typ))
1888		return nil
1889	case reflect.Uint32:
1890		dst.Set(reflect.ValueOf(toUint32(v)).Convert(typ))
1891		return nil
1892	case reflect.Uint16:
1893		dst.Set(reflect.ValueOf(toUint16(v)).Convert(typ))
1894		return nil
1895	case reflect.Uint8:
1896		dst.Set(reflect.ValueOf(toUint8(v)).Convert(typ))
1897		return nil
1898	case reflect.Float64:
1899		dst.Set(reflect.ValueOf(v.ToFloat()).Convert(typ))
1900		return nil
1901	case reflect.Float32:
1902		dst.Set(reflect.ValueOf(toFloat32(v)).Convert(typ))
1903		return nil
1904	case reflect.Slice:
1905		if o, ok := v.(*Object); ok {
1906			if o.self.className() == classArray {
1907				if v, exists := ctx.getTyped(o.self, typ); exists {
1908					dst.Set(reflect.ValueOf(v))
1909					return nil
1910				}
1911				l := int(toLength(o.self.getStr("length", nil)))
1912				if dst.IsNil() || dst.Len() != l {
1913					dst.Set(reflect.MakeSlice(typ, l, l))
1914				}
1915				s := dst
1916				ctx.putTyped(o.self, typ, s.Interface())
1917				for i := 0; i < l; i++ {
1918					item := o.self.getIdx(valueInt(int64(i)), nil)
1919					err := r.toReflectValue(item, s.Index(i), ctx)
1920					if err != nil {
1921						return fmt.Errorf("could not convert array element %v to %v at %d: %w", v, typ, i, err)
1922					}
1923				}
1924				return nil
1925			}
1926		}
1927	case reflect.Map:
1928		if o, ok := v.(*Object); ok {
1929			if v, exists := ctx.getTyped(o.self, typ); exists {
1930				dst.Set(reflect.ValueOf(v))
1931				return nil
1932			}
1933			if dst.IsNil() {
1934				dst.Set(reflect.MakeMap(typ))
1935			}
1936			m := dst
1937			ctx.putTyped(o.self, typ, m.Interface())
1938			keyTyp := typ.Key()
1939			elemTyp := typ.Elem()
1940			needConvertKeys := !reflect.ValueOf("").Type().AssignableTo(keyTyp)
1941			iter := &enumerableIter{
1942				wrapped: o.self.enumerateOwnKeys(),
1943			}
1944			for item, next := iter.next(); next != nil; item, next = next() {
1945				var kv reflect.Value
1946				var err error
1947				if needConvertKeys {
1948					kv = reflect.New(keyTyp).Elem()
1949					err = r.toReflectValue(stringValueFromRaw(item.name), kv, ctx)
1950					if err != nil {
1951						return fmt.Errorf("could not convert map key %s to %v", item.name.String(), typ)
1952					}
1953				} else {
1954					kv = reflect.ValueOf(item.name.String())
1955				}
1956
1957				ival := o.self.getStr(item.name, nil)
1958				if ival != nil {
1959					vv := reflect.New(elemTyp).Elem()
1960					err := r.toReflectValue(ival, vv, ctx)
1961					if err != nil {
1962						return fmt.Errorf("could not convert map value %v to %v at key %s", ival, typ, item.name.String())
1963					}
1964					m.SetMapIndex(kv, vv)
1965				} else {
1966					m.SetMapIndex(kv, reflect.Zero(elemTyp))
1967				}
1968			}
1969
1970			return nil
1971		}
1972	case reflect.Struct:
1973		if o, ok := v.(*Object); ok {
1974			t := reflect.PtrTo(typ)
1975			if v, exists := ctx.getTyped(o.self, t); exists {
1976				dst.Set(reflect.ValueOf(v).Elem())
1977				return nil
1978			}
1979			s := dst
1980			ctx.putTyped(o.self, t, s.Addr().Interface())
1981			for i := 0; i < typ.NumField(); i++ {
1982				field := typ.Field(i)
1983				if ast.IsExported(field.Name) {
1984					name := field.Name
1985					if r.fieldNameMapper != nil {
1986						name = r.fieldNameMapper.FieldName(typ, field)
1987					}
1988					var v Value
1989					if field.Anonymous {
1990						v = o
1991					} else {
1992						v = o.self.getStr(unistring.NewFromString(name), nil)
1993					}
1994
1995					if v != nil {
1996						err := r.toReflectValue(v, s.Field(i), ctx)
1997						if err != nil {
1998							return fmt.Errorf("could not convert struct value %v to %v for field %s: %w", v, field.Type, field.Name, err)
1999						}
2000					}
2001				}
2002			}
2003			return nil
2004		}
2005	case reflect.Func:
2006		if fn, ok := AssertFunction(v); ok {
2007			dst.Set(reflect.MakeFunc(typ, r.wrapJSFunc(fn, typ)))
2008			return nil
2009		}
2010	case reflect.Ptr:
2011		if o, ok := v.(*Object); ok {
2012			if v, exists := ctx.getTyped(o.self, typ); exists {
2013				dst.Set(reflect.ValueOf(v))
2014				return nil
2015			}
2016		}
2017		if dst.IsNil() {
2018			dst.Set(reflect.New(typ.Elem()))
2019		}
2020		return r.toReflectValue(v, dst.Elem(), ctx)
2021	}
2022
2023	return fmt.Errorf("could not convert %v to %v", v, typ)
2024}
2025
2026func (r *Runtime) wrapJSFunc(fn Callable, typ reflect.Type) func(args []reflect.Value) (results []reflect.Value) {
2027	return func(args []reflect.Value) (results []reflect.Value) {
2028		jsArgs := make([]Value, len(args))
2029		for i, arg := range args {
2030			jsArgs[i] = r.ToValue(arg.Interface())
2031		}
2032
2033		results = make([]reflect.Value, typ.NumOut())
2034		res, err := fn(_undefined, jsArgs...)
2035		if err == nil {
2036			if typ.NumOut() > 0 {
2037				v := reflect.New(typ.Out(0)).Elem()
2038				err = r.toReflectValue(res, v, &objectExportCtx{})
2039				if err == nil {
2040					results[0] = v
2041				}
2042			}
2043		}
2044
2045		if err != nil {
2046			if typ.NumOut() == 2 && typ.Out(1).Name() == "error" {
2047				results[1] = reflect.ValueOf(err).Convert(typ.Out(1))
2048			} else {
2049				panic(err)
2050			}
2051		}
2052
2053		for i, v := range results {
2054			if !v.IsValid() {
2055				results[i] = reflect.Zero(typ.Out(i))
2056			}
2057		}
2058
2059		return
2060	}
2061}
2062
2063// ExportTo converts a JavaScript value into the specified Go value. The second parameter must be a non-nil pointer.
2064// Exporting to an interface{} results in a value of the same type as Export() would produce.
2065// Exporting to numeric types uses the standard ECMAScript conversion operations, same as used when assigning
2066// values to non-clamped typed array items, e.g. https://262.ecma-international.org/#sec-toint32
2067// Returns error if conversion is not possible.
2068func (r *Runtime) ExportTo(v Value, target interface{}) error {
2069	tval := reflect.ValueOf(target)
2070	if tval.Kind() != reflect.Ptr || tval.IsNil() {
2071		return errors.New("target must be a non-nil pointer")
2072	}
2073	return r.toReflectValue(v, tval.Elem(), &objectExportCtx{})
2074}
2075
2076// GlobalObject returns the global object.
2077func (r *Runtime) GlobalObject() *Object {
2078	return r.globalObject
2079}
2080
2081// Set the specified variable in the global context.
2082// Equivalent to running "name = value" in non-strict mode.
2083// The value is first converted using ToValue().
2084// Note, this is not the same as GlobalObject().Set(name, value),
2085// because if a global lexical binding (let or const) exists, it is set instead.
2086func (r *Runtime) Set(name string, value interface{}) error {
2087	return r.try(func() {
2088		name := unistring.NewFromString(name)
2089		v := r.ToValue(value)
2090		if ref := r.global.stash.getRefByName(name, false); ref != nil {
2091			ref.set(v)
2092		} else {
2093			r.globalObject.self.setOwnStr(name, v, true)
2094		}
2095	})
2096}
2097
2098// Get the specified variable in the global context.
2099// Equivalent to dereferencing a variable by name in non-strict mode. If variable is not defined returns nil.
2100// Note, this is not the same as GlobalObject().Get(name),
2101// because if a global lexical binding (let or const) exists, it is used instead.
2102// This method will panic with an *Exception if a JavaScript exception is thrown in the process.
2103func (r *Runtime) Get(name string) (ret Value) {
2104	r.tryPanic(func() {
2105		n := unistring.NewFromString(name)
2106		if v, exists := r.global.stash.getByName(n); exists {
2107			ret = v
2108		} else {
2109			ret = r.globalObject.self.getStr(n, nil)
2110		}
2111	})
2112	return
2113}
2114
2115// SetRandSource sets random source for this Runtime. If not called, the default math/rand is used.
2116func (r *Runtime) SetRandSource(source RandSource) {
2117	r.rand = source
2118}
2119
2120// SetTimeSource sets the current time source for this Runtime.
2121// If not called, the default time.Now() is used.
2122func (r *Runtime) SetTimeSource(now Now) {
2123	r.now = now
2124}
2125
2126// SetParserOptions sets parser options to be used by RunString, RunScript and eval() within the code.
2127func (r *Runtime) SetParserOptions(opts ...parser.Option) {
2128	r.parserOptions = opts
2129}
2130
2131// SetMaxCallStackSize sets the maximum function call depth. When exceeded, a *StackOverflowError is thrown and
2132// returned by RunProgram or by a Callable call. This is useful to prevent memory exhaustion caused by an
2133// infinite recursion. The default value is math.MaxInt32.
2134// This method (as the rest of the Set* methods) is not safe for concurrent use and may only be called
2135// from the vm goroutine or when the vm is not running.
2136func (r *Runtime) SetMaxCallStackSize(size int) {
2137	r.vm.maxCallStackSize = size
2138}
2139
2140// New is an equivalent of the 'new' operator allowing to call it directly from Go.
2141func (r *Runtime) New(construct Value, args ...Value) (o *Object, err error) {
2142	err = r.try(func() {
2143		o = r.builtin_new(r.toObject(construct), args)
2144	})
2145	return
2146}
2147
2148// Callable represents a JavaScript function that can be called from Go.
2149type Callable func(this Value, args ...Value) (Value, error)
2150
2151// AssertFunction checks if the Value is a function and returns a Callable.
2152func AssertFunction(v Value) (Callable, bool) {
2153	if obj, ok := v.(*Object); ok {
2154		if f, ok := obj.self.assertCallable(); ok {
2155			return func(this Value, args ...Value) (ret Value, err error) {
2156				defer func() {
2157					if x := recover(); x != nil {
2158						if ex, ok := x.(*uncatchableException); ok {
2159							err = ex.err
2160						} else {
2161							panic(x)
2162						}
2163					}
2164				}()
2165				ex := obj.runtime.vm.try(func() {
2166					ret = f(FunctionCall{
2167						This:      this,
2168						Arguments: args,
2169					})
2170				})
2171				if ex != nil {
2172					err = ex
2173				}
2174				vm := obj.runtime.vm
2175				vm.clearStack()
2176				if len(vm.callStack) == 0 {
2177					obj.runtime.leave()
2178				}
2179				return
2180			}, true
2181		}
2182	}
2183	return nil, false
2184}
2185
2186// IsUndefined returns true if the supplied Value is undefined. Note, it checks against the real undefined, not
2187// against the global object's 'undefined' property.
2188func IsUndefined(v Value) bool {
2189	return v == _undefined
2190}
2191
2192// IsNull returns true if the supplied Value is null.
2193func IsNull(v Value) bool {
2194	return v == _null
2195}
2196
2197// IsNaN returns true if the supplied value is NaN.
2198func IsNaN(v Value) bool {
2199	f, ok := v.(valueFloat)
2200	return ok && math.IsNaN(float64(f))
2201}
2202
2203// IsInfinity returns true if the supplied is (+/-)Infinity
2204func IsInfinity(v Value) bool {
2205	return v == _positiveInf || v == _negativeInf
2206}
2207
2208// Undefined returns JS undefined value. Note if global 'undefined' property is changed this still returns the original value.
2209func Undefined() Value {
2210	return _undefined
2211}
2212
2213// Null returns JS null value.
2214func Null() Value {
2215	return _null
2216}
2217
2218// NaN returns a JS NaN value.
2219func NaN() Value {
2220	return _NaN
2221}
2222
2223// PositiveInf returns a JS +Inf value.
2224func PositiveInf() Value {
2225	return _positiveInf
2226}
2227
2228// NegativeInf returns a JS -Inf value.
2229func NegativeInf() Value {
2230	return _negativeInf
2231}
2232
2233func tryFunc(f func()) (ret interface{}) {
2234	defer func() {
2235		ret = recover()
2236	}()
2237
2238	f()
2239	return
2240}
2241
2242func (r *Runtime) try(f func()) error {
2243	if ex := r.vm.try(f); ex != nil {
2244		return ex
2245	}
2246	return nil
2247}
2248
2249func (r *Runtime) tryPanic(f func()) {
2250	if ex := r.vm.try(f); ex != nil {
2251		panic(ex)
2252	}
2253}
2254
2255func (r *Runtime) toObject(v Value, args ...interface{}) *Object {
2256	if obj, ok := v.(*Object); ok {
2257		return obj
2258	}
2259	if len(args) > 0 {
2260		panic(r.NewTypeError(args...))
2261	} else {
2262		var s string
2263		if v == nil {
2264			s = "undefined"
2265		} else {
2266			s = v.String()
2267		}
2268		panic(r.NewTypeError("Value is not an object: %s", s))
2269	}
2270}
2271
2272func (r *Runtime) toNumber(v Value) Value {
2273	switch o := v.(type) {
2274	case valueInt, valueFloat:
2275		return v
2276	case *Object:
2277		if pvo, ok := o.self.(*primitiveValueObject); ok {
2278			return r.toNumber(pvo.pValue)
2279		}
2280	}
2281	panic(r.NewTypeError("Value is not a number: %s", v))
2282}
2283
2284func (r *Runtime) speciesConstructor(o, defaultConstructor *Object) func(args []Value, newTarget *Object) *Object {
2285	c := o.self.getStr("constructor", nil)
2286	if c != nil && c != _undefined {
2287		c = r.toObject(c).self.getSym(SymSpecies, nil)
2288	}
2289	if c == nil || c == _undefined || c == _null {
2290		c = defaultConstructor
2291	}
2292	return r.toConstructor(c)
2293}
2294
2295func (r *Runtime) speciesConstructorObj(o, defaultConstructor *Object) *Object {
2296	c := o.self.getStr("constructor", nil)
2297	if c != nil && c != _undefined {
2298		c = r.toObject(c).self.getSym(SymSpecies, nil)
2299	}
2300	if c == nil || c == _undefined || c == _null {
2301		return defaultConstructor
2302	}
2303	return r.toObject(c)
2304}
2305
2306func (r *Runtime) returnThis(call FunctionCall) Value {
2307	return call.This
2308}
2309
2310func createDataPropertyOrThrow(o *Object, p Value, v Value) {
2311	o.defineOwnProperty(p, PropertyDescriptor{
2312		Writable:     FLAG_TRUE,
2313		Enumerable:   FLAG_TRUE,
2314		Configurable: FLAG_TRUE,
2315		Value:        v,
2316	}, true)
2317}
2318
2319func toPropertyKey(key Value) Value {
2320	return key.ToString()
2321}
2322
2323func (r *Runtime) getVStr(v Value, p unistring.String) Value {
2324	o := v.ToObject(r)
2325	return o.self.getStr(p, v)
2326}
2327
2328func (r *Runtime) getV(v Value, p Value) Value {
2329	o := v.ToObject(r)
2330	return o.get(p, v)
2331}
2332
2333func (r *Runtime) getIterator(obj Value, method func(FunctionCall) Value) *Object {
2334	if method == nil {
2335		method = toMethod(r.getV(obj, SymIterator))
2336		if method == nil {
2337			panic(r.NewTypeError("object is not iterable"))
2338		}
2339	}
2340
2341	return r.toObject(method(FunctionCall{
2342		This: obj,
2343	}))
2344}
2345
2346func returnIter(iter *Object) {
2347	retMethod := toMethod(iter.self.getStr("return", nil))
2348	if retMethod != nil {
2349		iter.runtime.toObject(retMethod(FunctionCall{This: iter}))
2350	}
2351}
2352
2353func (r *Runtime) iterate(iter *Object, step func(Value)) {
2354	for {
2355		res := r.toObject(toMethod(iter.self.getStr("next", nil))(FunctionCall{This: iter}))
2356		if nilSafe(res.self.getStr("done", nil)).ToBoolean() {
2357			break
2358		}
2359		value := nilSafe(res.self.getStr("value", nil))
2360		ret := tryFunc(func() {
2361			step(value)
2362		})
2363		if ret != nil {
2364			_ = tryFunc(func() {
2365				returnIter(iter)
2366			})
2367			panic(ret)
2368		}
2369	}
2370}
2371
2372func (r *Runtime) createIterResultObject(value Value, done bool) Value {
2373	o := r.NewObject()
2374	o.self.setOwnStr("value", value, false)
2375	o.self.setOwnStr("done", r.toBoolean(done), false)
2376	return o
2377}
2378
2379func (r *Runtime) newLazyObject(create func(*Object) objectImpl) *Object {
2380	val := &Object{runtime: r}
2381	o := &lazyObject{
2382		val:    val,
2383		create: create,
2384	}
2385	val.self = o
2386	return val
2387}
2388
2389func (r *Runtime) getHash() *maphash.Hash {
2390	if r.hash == nil {
2391		r.hash = &maphash.Hash{}
2392	}
2393	return r.hash
2394}
2395
2396// called when the top level function returns (i.e. control is passed outside the Runtime).
2397func (r *Runtime) leave() {
2398	// run jobs, etc...
2399}
2400
2401func nilSafe(v Value) Value {
2402	if v != nil {
2403		return v
2404	}
2405	return _undefined
2406}
2407
2408func isArray(object *Object) bool {
2409	self := object.self
2410	if proxy, ok := self.(*proxyObject); ok {
2411		if proxy.target == nil {
2412			panic(typeError("Cannot perform 'IsArray' on a proxy that has been revoked"))
2413		}
2414		return isArray(proxy.target)
2415	}
2416	switch self.className() {
2417	case classArray:
2418		return true
2419	default:
2420		return false
2421	}
2422}
2423
2424func isRegexp(v Value) bool {
2425	if o, ok := v.(*Object); ok {
2426		matcher := o.self.getSym(SymMatch, nil)
2427		if matcher != nil && matcher != _undefined {
2428			return matcher.ToBoolean()
2429		}
2430		_, reg := o.self.(*regexpObject)
2431		return reg
2432	}
2433	return false
2434}
2435
2436func limitCallArgs(call FunctionCall, n int) FunctionCall {
2437	if len(call.Arguments) > n {
2438		return FunctionCall{This: call.This, Arguments: call.Arguments[:n]}
2439	} else {
2440		return call
2441	}
2442}
2443
2444func shrinkCap(newSize, oldCap int) int {
2445	if oldCap > 8 {
2446		if cap := oldCap / 2; cap >= newSize {
2447			return cap
2448		}
2449	}
2450	return oldCap
2451}
2452
2453func growCap(newSize, oldSize, oldCap int) int {
2454	// Use the same algorithm as in runtime.growSlice
2455	doublecap := oldCap + oldCap
2456	if newSize > doublecap {
2457		return newSize
2458	} else {
2459		if oldSize < 1024 {
2460			return doublecap
2461		} else {
2462			cap := oldCap
2463			// Check 0 < cap to detect overflow
2464			// and prevent an infinite loop.
2465			for 0 < cap && cap < newSize {
2466				cap += cap / 4
2467			}
2468			// Return the requested cap when
2469			// the calculation overflowed.
2470			if cap <= 0 {
2471				return newSize
2472			}
2473			return cap
2474		}
2475	}
2476}
2477
2478func (r *Runtime) genId() (ret uint64) {
2479	if r.hash == nil {
2480		h := r.getHash()
2481		r.idSeq = h.Sum64()
2482	}
2483	if r.idSeq == 0 {
2484		r.idSeq = 1
2485	}
2486	ret = r.idSeq
2487	r.idSeq++
2488	return
2489}
2490
2491func (r *Runtime) setGlobal(name unistring.String, v Value, strict bool) {
2492	if ref := r.global.stash.getRefByName(name, strict); ref != nil {
2493		ref.set(v)
2494	} else {
2495		o := r.globalObject.self
2496		if strict {
2497			if o.hasOwnPropertyStr(name) {
2498				o.setOwnStr(name, v, true)
2499			} else {
2500				r.throwReferenceError(name)
2501			}
2502		} else {
2503			o.setOwnStr(name, v, false)
2504		}
2505	}
2506}
2507
2508func strToArrayIdx(s unistring.String) uint32 {
2509	if s == "" {
2510		return math.MaxUint32
2511	}
2512	l := len(s)
2513	if s[0] == '0' {
2514		if l == 1 {
2515			return 0
2516		}
2517		return math.MaxUint32
2518	}
2519	var n uint32
2520	if l < 10 {
2521		// guaranteed not to overflow
2522		for i := 0; i < len(s); i++ {
2523			c := s[i]
2524			if c < '0' || c > '9' {
2525				return math.MaxUint32
2526			}
2527			n = n*10 + uint32(c-'0')
2528		}
2529		return n
2530	}
2531	if l > 10 {
2532		// guaranteed to overflow
2533		return math.MaxUint32
2534	}
2535	c9 := s[9]
2536	if c9 < '0' || c9 > '9' {
2537		return math.MaxUint32
2538	}
2539	for i := 0; i < 9; i++ {
2540		c := s[i]
2541		if c < '0' || c > '9' {
2542			return math.MaxUint32
2543		}
2544		n = n*10 + uint32(c-'0')
2545	}
2546	if n >= math.MaxUint32/10+1 {
2547		return math.MaxUint32
2548	}
2549	n *= 10
2550	n1 := n + uint32(c9-'0')
2551	if n1 < n {
2552		return math.MaxUint32
2553	}
2554
2555	return n1
2556}
2557
2558func strToInt32(s unistring.String) (int32, bool) {
2559	if s == "" {
2560		return -1, false
2561	}
2562	neg := s[0] == '-'
2563	if neg {
2564		s = s[1:]
2565	}
2566	l := len(s)
2567	if s[0] == '0' {
2568		if l == 1 {
2569			return 0, !neg
2570		}
2571		return -1, false
2572	}
2573	var n uint32
2574	if l < 10 {
2575		// guaranteed not to overflow
2576		for i := 0; i < len(s); i++ {
2577			c := s[i]
2578			if c < '0' || c > '9' {
2579				return -1, false
2580			}
2581			n = n*10 + uint32(c-'0')
2582		}
2583	} else if l > 10 {
2584		// guaranteed to overflow
2585		return -1, false
2586	} else {
2587		c9 := s[9]
2588		if c9 >= '0' {
2589			if !neg && c9 > '7' || c9 > '8' {
2590				// guaranteed to overflow
2591				return -1, false
2592			}
2593			for i := 0; i < 9; i++ {
2594				c := s[i]
2595				if c < '0' || c > '9' {
2596					return -1, false
2597				}
2598				n = n*10 + uint32(c-'0')
2599			}
2600			if n >= math.MaxInt32/10+1 {
2601				// valid number, but it overflows integer
2602				return 0, false
2603			}
2604			n = n*10 + uint32(c9-'0')
2605		} else {
2606			return -1, false
2607		}
2608	}
2609	if neg {
2610		return int32(-n), true
2611	}
2612	return int32(n), true
2613}
2614
2615func strToInt64(s unistring.String) (int64, bool) {
2616	if s == "" {
2617		return -1, false
2618	}
2619	neg := s[0] == '-'
2620	if neg {
2621		s = s[1:]
2622	}
2623	l := len(s)
2624	if s[0] == '0' {
2625		if l == 1 {
2626			return 0, !neg
2627		}
2628		return -1, false
2629	}
2630	var n uint64
2631	if l < 19 {
2632		// guaranteed not to overflow
2633		for i := 0; i < len(s); i++ {
2634			c := s[i]
2635			if c < '0' || c > '9' {
2636				return -1, false
2637			}
2638			n = n*10 + uint64(c-'0')
2639		}
2640	} else if l > 19 {
2641		// guaranteed to overflow
2642		return -1, false
2643	} else {
2644		c18 := s[18]
2645		if c18 >= '0' {
2646			if !neg && c18 > '7' || c18 > '8' {
2647				// guaranteed to overflow
2648				return -1, false
2649			}
2650			for i := 0; i < 18; i++ {
2651				c := s[i]
2652				if c < '0' || c > '9' {
2653					return -1, false
2654				}
2655				n = n*10 + uint64(c-'0')
2656			}
2657			if n >= math.MaxInt64/10+1 {
2658				// valid number, but it overflows integer
2659				return 0, false
2660			}
2661			n = n*10 + uint64(c18-'0')
2662		} else {
2663			return -1, false
2664		}
2665	}
2666	if neg {
2667		return int64(-n), true
2668	}
2669	return int64(n), true
2670}
2671
2672func strToInt(s unistring.String) (int, bool) {
2673	if bits.UintSize == 32 {
2674		n, ok := strToInt32(s)
2675		return int(n), ok
2676	}
2677	n, ok := strToInt64(s)
2678	return int(n), ok
2679}
2680
2681// Attempts to convert a string into a canonical integer.
2682// On success returns (number, true).
2683// If it was a canonical number, but not an integer returns (0, false). This includes -0 and overflows.
2684// In all other cases returns (-1, false).
2685// See https://262.ecma-international.org/#sec-canonicalnumericindexstring
2686func strToIntNum(s unistring.String) (int, bool) {
2687	n, ok := strToInt64(s)
2688	if n == 0 {
2689		return 0, ok
2690	}
2691	if ok && n >= -maxInt && n <= maxInt {
2692		if bits.UintSize == 32 {
2693			if n > math.MaxInt32 || n < math.MinInt32 {
2694				return 0, false
2695			}
2696		}
2697		return int(n), true
2698	}
2699	str := stringValueFromRaw(s)
2700	if str.ToNumber().toString().SameAs(str) {
2701		return 0, false
2702	}
2703	return -1, false
2704}
2705
2706func strToGoIdx(s unistring.String) int {
2707	if n, ok := strToInt(s); ok {
2708		return n
2709	}
2710	return -1
2711}
2712
2713func strToIdx64(s unistring.String) int64 {
2714	if n, ok := strToInt64(s); ok {
2715		return n
2716	}
2717	return -1
2718}
2719