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