github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/runtime.go (about)

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