...

Source file src/github.com/dop251/goja/runtime.go

Documentation: github.com/dop251/goja

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

View as plain text