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