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

     1  package goja
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"reflect"
     7  	"sort"
     8  
     9  	"github.com/nuvolaris/goja/unistring"
    10  )
    11  
    12  const (
    13  	classObject        = "Object"
    14  	classArray         = "Array"
    15  	classWeakSet       = "WeakSet"
    16  	classWeakMap       = "WeakMap"
    17  	classMap           = "Map"
    18  	classMath          = "Math"
    19  	classSet           = "Set"
    20  	classFunction      = "Function"
    21  	classAsyncFunction = "AsyncFunction"
    22  	classNumber        = "Number"
    23  	classString        = "String"
    24  	classBoolean       = "Boolean"
    25  	classError         = "Error"
    26  	classRegExp        = "RegExp"
    27  	classDate          = "Date"
    28  	classJSON          = "JSON"
    29  	classGlobal        = "global"
    30  	classPromise       = "Promise"
    31  
    32  	classArrayIterator        = "Array Iterator"
    33  	classMapIterator          = "Map Iterator"
    34  	classSetIterator          = "Set Iterator"
    35  	classStringIterator       = "String Iterator"
    36  	classRegExpStringIterator = "RegExp String Iterator"
    37  
    38  	classGenerator         = "Generator"
    39  	classGeneratorFunction = "GeneratorFunction"
    40  )
    41  
    42  var (
    43  	hintDefault Value = asciiString("default")
    44  	hintNumber  Value = asciiString("number")
    45  	hintString  Value = asciiString("string")
    46  )
    47  
    48  type Object struct {
    49  	id      uint64
    50  	runtime *Runtime
    51  	self    objectImpl
    52  
    53  	weakRefs map[weakMap]Value
    54  }
    55  
    56  type iterNextFunc func() (propIterItem, iterNextFunc)
    57  
    58  type PropertyDescriptor struct {
    59  	jsDescriptor *Object
    60  
    61  	Value Value
    62  
    63  	Writable, Configurable, Enumerable Flag
    64  
    65  	Getter, Setter Value
    66  }
    67  
    68  func (p *PropertyDescriptor) Empty() bool {
    69  	var empty PropertyDescriptor
    70  	return *p == empty
    71  }
    72  
    73  func (p *PropertyDescriptor) IsAccessor() bool {
    74  	return p.Setter != nil || p.Getter != nil
    75  }
    76  
    77  func (p *PropertyDescriptor) IsData() bool {
    78  	return p.Value != nil || p.Writable != FLAG_NOT_SET
    79  }
    80  
    81  func (p *PropertyDescriptor) IsGeneric() bool {
    82  	return !p.IsAccessor() && !p.IsData()
    83  }
    84  
    85  func (p *PropertyDescriptor) toValue(r *Runtime) Value {
    86  	if p.jsDescriptor != nil {
    87  		return p.jsDescriptor
    88  	}
    89  	if p.Empty() {
    90  		return _undefined
    91  	}
    92  	o := r.NewObject()
    93  	s := o.self
    94  
    95  	if p.Value != nil {
    96  		s._putProp("value", p.Value, true, true, true)
    97  	}
    98  
    99  	if p.Writable != FLAG_NOT_SET {
   100  		s._putProp("writable", valueBool(p.Writable.Bool()), true, true, true)
   101  	}
   102  
   103  	if p.Enumerable != FLAG_NOT_SET {
   104  		s._putProp("enumerable", valueBool(p.Enumerable.Bool()), true, true, true)
   105  	}
   106  
   107  	if p.Configurable != FLAG_NOT_SET {
   108  		s._putProp("configurable", valueBool(p.Configurable.Bool()), true, true, true)
   109  	}
   110  
   111  	if p.Getter != nil {
   112  		s._putProp("get", p.Getter, true, true, true)
   113  	}
   114  	if p.Setter != nil {
   115  		s._putProp("set", p.Setter, true, true, true)
   116  	}
   117  
   118  	return o
   119  }
   120  
   121  func (p *PropertyDescriptor) complete() {
   122  	if p.Getter == nil && p.Setter == nil {
   123  		if p.Value == nil {
   124  			p.Value = _undefined
   125  		}
   126  		if p.Writable == FLAG_NOT_SET {
   127  			p.Writable = FLAG_FALSE
   128  		}
   129  	} else {
   130  		if p.Getter == nil {
   131  			p.Getter = _undefined
   132  		}
   133  		if p.Setter == nil {
   134  			p.Setter = _undefined
   135  		}
   136  	}
   137  	if p.Enumerable == FLAG_NOT_SET {
   138  		p.Enumerable = FLAG_FALSE
   139  	}
   140  	if p.Configurable == FLAG_NOT_SET {
   141  		p.Configurable = FLAG_FALSE
   142  	}
   143  }
   144  
   145  type objectExportCacheItem map[reflect.Type]interface{}
   146  
   147  type objectExportCtx struct {
   148  	cache map[*Object]interface{}
   149  }
   150  
   151  type objectImpl interface {
   152  	sortable
   153  	className() string
   154  	typeOf() String
   155  	getStr(p unistring.String, receiver Value) Value
   156  	getIdx(p valueInt, receiver Value) Value
   157  	getSym(p *Symbol, receiver Value) Value
   158  
   159  	getOwnPropStr(unistring.String) Value
   160  	getOwnPropIdx(valueInt) Value
   161  	getOwnPropSym(*Symbol) Value
   162  
   163  	setOwnStr(p unistring.String, v Value, throw bool) bool
   164  	setOwnIdx(p valueInt, v Value, throw bool) bool
   165  	setOwnSym(p *Symbol, v Value, throw bool) bool
   166  
   167  	setForeignStr(p unistring.String, v, receiver Value, throw bool) (res bool, handled bool)
   168  	setForeignIdx(p valueInt, v, receiver Value, throw bool) (res bool, handled bool)
   169  	setForeignSym(p *Symbol, v, receiver Value, throw bool) (res bool, handled bool)
   170  
   171  	hasPropertyStr(unistring.String) bool
   172  	hasPropertyIdx(idx valueInt) bool
   173  	hasPropertySym(s *Symbol) bool
   174  
   175  	hasOwnPropertyStr(unistring.String) bool
   176  	hasOwnPropertyIdx(valueInt) bool
   177  	hasOwnPropertySym(s *Symbol) bool
   178  
   179  	defineOwnPropertyStr(name unistring.String, desc PropertyDescriptor, throw bool) bool
   180  	defineOwnPropertyIdx(name valueInt, desc PropertyDescriptor, throw bool) bool
   181  	defineOwnPropertySym(name *Symbol, desc PropertyDescriptor, throw bool) bool
   182  
   183  	deleteStr(name unistring.String, throw bool) bool
   184  	deleteIdx(idx valueInt, throw bool) bool
   185  	deleteSym(s *Symbol, throw bool) bool
   186  
   187  	assertCallable() (call func(FunctionCall) Value, ok bool)
   188  	vmCall(vm *vm, n int)
   189  	assertConstructor() func(args []Value, newTarget *Object) *Object
   190  	proto() *Object
   191  	setProto(proto *Object, throw bool) bool
   192  	hasInstance(v Value) bool
   193  	isExtensible() bool
   194  	preventExtensions(throw bool) bool
   195  
   196  	export(ctx *objectExportCtx) interface{}
   197  	exportType() reflect.Type
   198  	exportToMap(m reflect.Value, typ reflect.Type, ctx *objectExportCtx) error
   199  	exportToArrayOrSlice(s reflect.Value, typ reflect.Type, ctx *objectExportCtx) error
   200  	equal(objectImpl) bool
   201  
   202  	iterateStringKeys() iterNextFunc
   203  	iterateSymbols() iterNextFunc
   204  	iterateKeys() iterNextFunc
   205  
   206  	stringKeys(all bool, accum []Value) []Value
   207  	symbols(all bool, accum []Value) []Value
   208  	keys(all bool, accum []Value) []Value
   209  
   210  	_putProp(name unistring.String, value Value, writable, enumerable, configurable bool) Value
   211  	_putSym(s *Symbol, prop Value)
   212  	getPrivateEnv(typ *privateEnvType, create bool) *privateElements
   213  }
   214  
   215  type baseObject struct {
   216  	class      string
   217  	val        *Object
   218  	prototype  *Object
   219  	extensible bool
   220  
   221  	values    map[unistring.String]Value
   222  	propNames []unistring.String
   223  
   224  	lastSortedPropLen, idxPropCount int
   225  
   226  	symValues *orderedMap
   227  
   228  	privateElements map[*privateEnvType]*privateElements
   229  }
   230  
   231  type guardedObject struct {
   232  	baseObject
   233  	guardedProps map[unistring.String]struct{}
   234  }
   235  
   236  type primitiveValueObject struct {
   237  	baseObject
   238  	pValue Value
   239  }
   240  
   241  func (o *primitiveValueObject) export(*objectExportCtx) interface{} {
   242  	return o.pValue.Export()
   243  }
   244  
   245  func (o *primitiveValueObject) exportType() reflect.Type {
   246  	return o.pValue.ExportType()
   247  }
   248  
   249  type FunctionCall struct {
   250  	This      Value
   251  	Arguments []Value
   252  }
   253  
   254  type ConstructorCall struct {
   255  	This      *Object
   256  	Arguments []Value
   257  	NewTarget *Object
   258  }
   259  
   260  func (f FunctionCall) Argument(idx int) Value {
   261  	if idx < len(f.Arguments) {
   262  		return f.Arguments[idx]
   263  	}
   264  	return _undefined
   265  }
   266  
   267  func (f ConstructorCall) Argument(idx int) Value {
   268  	if idx < len(f.Arguments) {
   269  		return f.Arguments[idx]
   270  	}
   271  	return _undefined
   272  }
   273  
   274  func (o *baseObject) init() {
   275  	o.values = make(map[unistring.String]Value)
   276  }
   277  
   278  func (o *baseObject) className() string {
   279  	return o.class
   280  }
   281  
   282  func (o *baseObject) typeOf() String {
   283  	return stringObjectC
   284  }
   285  
   286  func (o *baseObject) hasPropertyStr(name unistring.String) bool {
   287  	if o.val.self.hasOwnPropertyStr(name) {
   288  		return true
   289  	}
   290  	if o.prototype != nil {
   291  		return o.prototype.self.hasPropertyStr(name)
   292  	}
   293  	return false
   294  }
   295  
   296  func (o *baseObject) hasPropertyIdx(idx valueInt) bool {
   297  	return o.val.self.hasPropertyStr(idx.string())
   298  }
   299  
   300  func (o *baseObject) hasPropertySym(s *Symbol) bool {
   301  	if o.hasOwnPropertySym(s) {
   302  		return true
   303  	}
   304  	if o.prototype != nil {
   305  		return o.prototype.self.hasPropertySym(s)
   306  	}
   307  	return false
   308  }
   309  
   310  func (o *baseObject) getWithOwnProp(prop, p, receiver Value) Value {
   311  	if prop == nil && o.prototype != nil {
   312  		if receiver == nil {
   313  			return o.prototype.get(p, o.val)
   314  		}
   315  		return o.prototype.get(p, receiver)
   316  	}
   317  	if prop, ok := prop.(*valueProperty); ok {
   318  		if receiver == nil {
   319  			return prop.get(o.val)
   320  		}
   321  		return prop.get(receiver)
   322  	}
   323  	return prop
   324  }
   325  
   326  func (o *baseObject) getStrWithOwnProp(prop Value, name unistring.String, receiver Value) Value {
   327  	if prop == nil && o.prototype != nil {
   328  		if receiver == nil {
   329  			return o.prototype.self.getStr(name, o.val)
   330  		}
   331  		return o.prototype.self.getStr(name, receiver)
   332  	}
   333  	if prop, ok := prop.(*valueProperty); ok {
   334  		if receiver == nil {
   335  			return prop.get(o.val)
   336  		}
   337  		return prop.get(receiver)
   338  	}
   339  	return prop
   340  }
   341  
   342  func (o *baseObject) getIdx(idx valueInt, receiver Value) Value {
   343  	return o.val.self.getStr(idx.string(), receiver)
   344  }
   345  
   346  func (o *baseObject) getSym(s *Symbol, receiver Value) Value {
   347  	return o.getWithOwnProp(o.getOwnPropSym(s), s, receiver)
   348  }
   349  
   350  func (o *baseObject) getStr(name unistring.String, receiver Value) Value {
   351  	prop := o.values[name]
   352  	if prop == nil {
   353  		if o.prototype != nil {
   354  			if receiver == nil {
   355  				return o.prototype.self.getStr(name, o.val)
   356  			}
   357  			return o.prototype.self.getStr(name, receiver)
   358  		}
   359  	}
   360  	if prop, ok := prop.(*valueProperty); ok {
   361  		if receiver == nil {
   362  			return prop.get(o.val)
   363  		}
   364  		return prop.get(receiver)
   365  	}
   366  	return prop
   367  }
   368  
   369  func (o *baseObject) getOwnPropIdx(idx valueInt) Value {
   370  	return o.val.self.getOwnPropStr(idx.string())
   371  }
   372  
   373  func (o *baseObject) getOwnPropSym(s *Symbol) Value {
   374  	if o.symValues != nil {
   375  		return o.symValues.get(s)
   376  	}
   377  	return nil
   378  }
   379  
   380  func (o *baseObject) getOwnPropStr(name unistring.String) Value {
   381  	return o.values[name]
   382  }
   383  
   384  func (o *baseObject) checkDeleteProp(name unistring.String, prop *valueProperty, throw bool) bool {
   385  	if !prop.configurable {
   386  		if throw {
   387  			r := o.val.runtime
   388  			panic(r.NewTypeError("Cannot delete property '%s' of %s", name, r.objectproto_toString(FunctionCall{This: o.val})))
   389  		}
   390  		return false
   391  	}
   392  	return true
   393  }
   394  
   395  func (o *baseObject) checkDelete(name unistring.String, val Value, throw bool) bool {
   396  	if val, ok := val.(*valueProperty); ok {
   397  		return o.checkDeleteProp(name, val, throw)
   398  	}
   399  	return true
   400  }
   401  
   402  func (o *baseObject) _delete(name unistring.String) {
   403  	delete(o.values, name)
   404  	for i, n := range o.propNames {
   405  		if n == name {
   406  			names := o.propNames
   407  			if namesMarkedForCopy(names) {
   408  				newNames := make([]unistring.String, len(names)-1, shrinkCap(len(names), cap(names)))
   409  				copy(newNames, names[:i])
   410  				copy(newNames[i:], names[i+1:])
   411  				o.propNames = newNames
   412  			} else {
   413  				copy(names[i:], names[i+1:])
   414  				names[len(names)-1] = ""
   415  				o.propNames = names[:len(names)-1]
   416  			}
   417  			if i < o.lastSortedPropLen {
   418  				o.lastSortedPropLen--
   419  				if i < o.idxPropCount {
   420  					o.idxPropCount--
   421  				}
   422  			}
   423  			break
   424  		}
   425  	}
   426  }
   427  
   428  func (o *baseObject) deleteIdx(idx valueInt, throw bool) bool {
   429  	return o.val.self.deleteStr(idx.string(), throw)
   430  }
   431  
   432  func (o *baseObject) deleteSym(s *Symbol, throw bool) bool {
   433  	if o.symValues != nil {
   434  		if val := o.symValues.get(s); val != nil {
   435  			if !o.checkDelete(s.descriptiveString().string(), val, throw) {
   436  				return false
   437  			}
   438  			o.symValues.remove(s)
   439  		}
   440  	}
   441  	return true
   442  }
   443  
   444  func (o *baseObject) deleteStr(name unistring.String, throw bool) bool {
   445  	if val, exists := o.values[name]; exists {
   446  		if !o.checkDelete(name, val, throw) {
   447  			return false
   448  		}
   449  		o._delete(name)
   450  	}
   451  	return true
   452  }
   453  
   454  func (o *baseObject) setProto(proto *Object, throw bool) bool {
   455  	current := o.prototype
   456  	if current.SameAs(proto) {
   457  		return true
   458  	}
   459  	if !o.extensible {
   460  		o.val.runtime.typeErrorResult(throw, "%s is not extensible", o.val)
   461  		return false
   462  	}
   463  	for p := proto; p != nil; p = p.self.proto() {
   464  		if p.SameAs(o.val) {
   465  			o.val.runtime.typeErrorResult(throw, "Cyclic __proto__ value")
   466  			return false
   467  		}
   468  		if _, ok := p.self.(*proxyObject); ok {
   469  			break
   470  		}
   471  	}
   472  	o.prototype = proto
   473  	return true
   474  }
   475  
   476  func (o *baseObject) setOwnStr(name unistring.String, val Value, throw bool) bool {
   477  	ownDesc := o.values[name]
   478  	if ownDesc == nil {
   479  		if proto := o.prototype; proto != nil {
   480  			// we know it's foreign because prototype loops are not allowed
   481  			if res, handled := proto.self.setForeignStr(name, val, o.val, throw); handled {
   482  				return res
   483  			}
   484  		}
   485  		// new property
   486  		if !o.extensible {
   487  			o.val.runtime.typeErrorResult(throw, "Cannot add property %s, object is not extensible", name)
   488  			return false
   489  		} else {
   490  			o.values[name] = val
   491  			names := copyNamesIfNeeded(o.propNames, 1)
   492  			o.propNames = append(names, name)
   493  		}
   494  		return true
   495  	}
   496  	if prop, ok := ownDesc.(*valueProperty); ok {
   497  		if !prop.isWritable() {
   498  			o.val.runtime.typeErrorResult(throw, "Cannot assign to read only property '%s'", name)
   499  			return false
   500  		} else {
   501  			prop.set(o.val, val)
   502  		}
   503  	} else {
   504  		o.values[name] = val
   505  	}
   506  	return true
   507  }
   508  
   509  func (o *baseObject) setOwnIdx(idx valueInt, val Value, throw bool) bool {
   510  	return o.val.self.setOwnStr(idx.string(), val, throw)
   511  }
   512  
   513  func (o *baseObject) setOwnSym(name *Symbol, val Value, throw bool) bool {
   514  	var ownDesc Value
   515  	if o.symValues != nil {
   516  		ownDesc = o.symValues.get(name)
   517  	}
   518  	if ownDesc == nil {
   519  		if proto := o.prototype; proto != nil {
   520  			// we know it's foreign because prototype loops are not allowed
   521  			if res, handled := proto.self.setForeignSym(name, val, o.val, throw); handled {
   522  				return res
   523  			}
   524  		}
   525  		// new property
   526  		if !o.extensible {
   527  			o.val.runtime.typeErrorResult(throw, "Cannot add property %s, object is not extensible", name)
   528  			return false
   529  		} else {
   530  			if o.symValues == nil {
   531  				o.symValues = newOrderedMap(nil)
   532  			}
   533  			o.symValues.set(name, val)
   534  		}
   535  		return true
   536  	}
   537  	if prop, ok := ownDesc.(*valueProperty); ok {
   538  		if !prop.isWritable() {
   539  			o.val.runtime.typeErrorResult(throw, "Cannot assign to read only property '%s'", name)
   540  			return false
   541  		} else {
   542  			prop.set(o.val, val)
   543  		}
   544  	} else {
   545  		o.symValues.set(name, val)
   546  	}
   547  	return true
   548  }
   549  
   550  func (o *baseObject) _setForeignStr(name unistring.String, prop, val, receiver Value, throw bool) (bool, bool) {
   551  	if prop != nil {
   552  		if prop, ok := prop.(*valueProperty); ok {
   553  			if !prop.isWritable() {
   554  				o.val.runtime.typeErrorResult(throw, "Cannot assign to read only property '%s'", name)
   555  				return false, true
   556  			}
   557  			if prop.setterFunc != nil {
   558  				prop.set(receiver, val)
   559  				return true, true
   560  			}
   561  		}
   562  	} else {
   563  		if proto := o.prototype; proto != nil {
   564  			if receiver != proto {
   565  				return proto.self.setForeignStr(name, val, receiver, throw)
   566  			}
   567  			return proto.self.setOwnStr(name, val, throw), true
   568  		}
   569  	}
   570  	return false, false
   571  }
   572  
   573  func (o *baseObject) _setForeignIdx(idx valueInt, prop, val, receiver Value, throw bool) (bool, bool) {
   574  	if prop != nil {
   575  		if prop, ok := prop.(*valueProperty); ok {
   576  			if !prop.isWritable() {
   577  				o.val.runtime.typeErrorResult(throw, "Cannot assign to read only property '%d'", idx)
   578  				return false, true
   579  			}
   580  			if prop.setterFunc != nil {
   581  				prop.set(receiver, val)
   582  				return true, true
   583  			}
   584  		}
   585  	} else {
   586  		if proto := o.prototype; proto != nil {
   587  			if receiver != proto {
   588  				return proto.self.setForeignIdx(idx, val, receiver, throw)
   589  			}
   590  			return proto.self.setOwnIdx(idx, val, throw), true
   591  		}
   592  	}
   593  	return false, false
   594  }
   595  
   596  func (o *baseObject) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) {
   597  	return o._setForeignStr(name, o.values[name], val, receiver, throw)
   598  }
   599  
   600  func (o *baseObject) setForeignIdx(name valueInt, val, receiver Value, throw bool) (bool, bool) {
   601  	if idx := toIdx(name); idx != math.MaxUint32 {
   602  		o.ensurePropOrder()
   603  		if o.idxPropCount == 0 {
   604  			return o._setForeignIdx(name, name, nil, receiver, throw)
   605  		}
   606  	}
   607  	return o.setForeignStr(name.string(), val, receiver, throw)
   608  }
   609  
   610  func (o *baseObject) setForeignSym(name *Symbol, val, receiver Value, throw bool) (bool, bool) {
   611  	var prop Value
   612  	if o.symValues != nil {
   613  		prop = o.symValues.get(name)
   614  	}
   615  	if prop != nil {
   616  		if prop, ok := prop.(*valueProperty); ok {
   617  			if !prop.isWritable() {
   618  				o.val.runtime.typeErrorResult(throw, "Cannot assign to read only property '%s'", name)
   619  				return false, true
   620  			}
   621  			if prop.setterFunc != nil {
   622  				prop.set(receiver, val)
   623  				return true, true
   624  			}
   625  		}
   626  	} else {
   627  		if proto := o.prototype; proto != nil {
   628  			if receiver != o.val {
   629  				return proto.self.setForeignSym(name, val, receiver, throw)
   630  			}
   631  			return proto.self.setOwnSym(name, val, throw), true
   632  		}
   633  	}
   634  	return false, false
   635  }
   636  
   637  func (o *baseObject) hasOwnPropertySym(s *Symbol) bool {
   638  	if o.symValues != nil {
   639  		return o.symValues.has(s)
   640  	}
   641  	return false
   642  }
   643  
   644  func (o *baseObject) hasOwnPropertyStr(name unistring.String) bool {
   645  	_, exists := o.values[name]
   646  	return exists
   647  }
   648  
   649  func (o *baseObject) hasOwnPropertyIdx(idx valueInt) bool {
   650  	return o.val.self.hasOwnPropertyStr(idx.string())
   651  }
   652  
   653  func (o *baseObject) _defineOwnProperty(name unistring.String, existingValue Value, descr PropertyDescriptor, throw bool) (val Value, ok bool) {
   654  
   655  	getterObj, _ := descr.Getter.(*Object)
   656  	setterObj, _ := descr.Setter.(*Object)
   657  
   658  	var existing *valueProperty
   659  
   660  	if existingValue == nil {
   661  		if !o.extensible {
   662  			o.val.runtime.typeErrorResult(throw, "Cannot define property %s, object is not extensible", name)
   663  			return nil, false
   664  		}
   665  		existing = &valueProperty{}
   666  	} else {
   667  		if existing, ok = existingValue.(*valueProperty); !ok {
   668  			existing = &valueProperty{
   669  				writable:     true,
   670  				enumerable:   true,
   671  				configurable: true,
   672  				value:        existingValue,
   673  			}
   674  		}
   675  
   676  		if !existing.configurable {
   677  			if descr.Configurable == FLAG_TRUE {
   678  				goto Reject
   679  			}
   680  			if descr.Enumerable != FLAG_NOT_SET && descr.Enumerable.Bool() != existing.enumerable {
   681  				goto Reject
   682  			}
   683  		}
   684  		if existing.accessor && descr.Value != nil || !existing.accessor && (getterObj != nil || setterObj != nil) {
   685  			if !existing.configurable {
   686  				goto Reject
   687  			}
   688  		} else if !existing.accessor {
   689  			if !existing.configurable {
   690  				if !existing.writable {
   691  					if descr.Writable == FLAG_TRUE {
   692  						goto Reject
   693  					}
   694  					if descr.Value != nil && !descr.Value.SameAs(existing.value) {
   695  						goto Reject
   696  					}
   697  				}
   698  			}
   699  		} else {
   700  			if !existing.configurable {
   701  				if descr.Getter != nil && existing.getterFunc != getterObj || descr.Setter != nil && existing.setterFunc != setterObj {
   702  					goto Reject
   703  				}
   704  			}
   705  		}
   706  	}
   707  
   708  	if descr.Writable == FLAG_TRUE && descr.Enumerable == FLAG_TRUE && descr.Configurable == FLAG_TRUE && descr.Value != nil {
   709  		return descr.Value, true
   710  	}
   711  
   712  	if descr.Writable != FLAG_NOT_SET {
   713  		existing.writable = descr.Writable.Bool()
   714  	}
   715  	if descr.Enumerable != FLAG_NOT_SET {
   716  		existing.enumerable = descr.Enumerable.Bool()
   717  	}
   718  	if descr.Configurable != FLAG_NOT_SET {
   719  		existing.configurable = descr.Configurable.Bool()
   720  	}
   721  
   722  	if descr.Value != nil {
   723  		existing.value = descr.Value
   724  		existing.getterFunc = nil
   725  		existing.setterFunc = nil
   726  	}
   727  
   728  	if descr.Value != nil || descr.Writable != FLAG_NOT_SET {
   729  		existing.accessor = false
   730  	}
   731  
   732  	if descr.Getter != nil {
   733  		existing.getterFunc = propGetter(o.val, descr.Getter, o.val.runtime)
   734  		existing.value = nil
   735  		existing.accessor = true
   736  	}
   737  
   738  	if descr.Setter != nil {
   739  		existing.setterFunc = propSetter(o.val, descr.Setter, o.val.runtime)
   740  		existing.value = nil
   741  		existing.accessor = true
   742  	}
   743  
   744  	if !existing.accessor && existing.value == nil {
   745  		existing.value = _undefined
   746  	}
   747  
   748  	return existing, true
   749  
   750  Reject:
   751  	o.val.runtime.typeErrorResult(throw, "Cannot redefine property: %s", name)
   752  	return nil, false
   753  
   754  }
   755  
   756  func (o *baseObject) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool {
   757  	existingVal := o.values[name]
   758  	if v, ok := o._defineOwnProperty(name, existingVal, descr, throw); ok {
   759  		o.values[name] = v
   760  		if existingVal == nil {
   761  			names := copyNamesIfNeeded(o.propNames, 1)
   762  			o.propNames = append(names, name)
   763  		}
   764  		return true
   765  	}
   766  	return false
   767  }
   768  
   769  func (o *baseObject) defineOwnPropertyIdx(idx valueInt, desc PropertyDescriptor, throw bool) bool {
   770  	return o.val.self.defineOwnPropertyStr(idx.string(), desc, throw)
   771  }
   772  
   773  func (o *baseObject) defineOwnPropertySym(s *Symbol, descr PropertyDescriptor, throw bool) bool {
   774  	var existingVal Value
   775  	if o.symValues != nil {
   776  		existingVal = o.symValues.get(s)
   777  	}
   778  	if v, ok := o._defineOwnProperty(s.descriptiveString().string(), existingVal, descr, throw); ok {
   779  		if o.symValues == nil {
   780  			o.symValues = newOrderedMap(nil)
   781  		}
   782  		o.symValues.set(s, v)
   783  		return true
   784  	}
   785  	return false
   786  }
   787  
   788  func (o *baseObject) _put(name unistring.String, v Value) {
   789  	if _, exists := o.values[name]; !exists {
   790  		names := copyNamesIfNeeded(o.propNames, 1)
   791  		o.propNames = append(names, name)
   792  	}
   793  
   794  	o.values[name] = v
   795  }
   796  
   797  func valueProp(value Value, writable, enumerable, configurable bool) Value {
   798  	if writable && enumerable && configurable {
   799  		return value
   800  	}
   801  	return &valueProperty{
   802  		value:        value,
   803  		writable:     writable,
   804  		enumerable:   enumerable,
   805  		configurable: configurable,
   806  	}
   807  }
   808  
   809  func (o *baseObject) _putProp(name unistring.String, value Value, writable, enumerable, configurable bool) Value {
   810  	prop := valueProp(value, writable, enumerable, configurable)
   811  	o._put(name, prop)
   812  	return prop
   813  }
   814  
   815  func (o *baseObject) _putSym(s *Symbol, prop Value) {
   816  	if o.symValues == nil {
   817  		o.symValues = newOrderedMap(nil)
   818  	}
   819  	o.symValues.set(s, prop)
   820  }
   821  
   822  func (o *baseObject) getPrivateEnv(typ *privateEnvType, create bool) *privateElements {
   823  	env := o.privateElements[typ]
   824  	if env != nil && create {
   825  		panic(o.val.runtime.NewTypeError("Private fields for the class have already been set"))
   826  	}
   827  	if env == nil && create {
   828  		env = &privateElements{
   829  			fields: make([]Value, typ.numFields),
   830  		}
   831  		if o.privateElements == nil {
   832  			o.privateElements = make(map[*privateEnvType]*privateElements)
   833  		}
   834  		o.privateElements[typ] = env
   835  	}
   836  	return env
   837  }
   838  
   839  func (o *Object) tryPrimitive(methodName unistring.String) Value {
   840  	if method, ok := o.self.getStr(methodName, nil).(*Object); ok {
   841  		if call, ok := method.self.assertCallable(); ok {
   842  			v := call(FunctionCall{
   843  				This: o,
   844  			})
   845  			if _, fail := v.(*Object); !fail {
   846  				return v
   847  			}
   848  		}
   849  	}
   850  	return nil
   851  }
   852  
   853  func (o *Object) ordinaryToPrimitiveNumber() Value {
   854  	if v := o.tryPrimitive("valueOf"); v != nil {
   855  		return v
   856  	}
   857  
   858  	if v := o.tryPrimitive("toString"); v != nil {
   859  		return v
   860  	}
   861  
   862  	panic(o.runtime.NewTypeError("Could not convert %v to primitive", o.self))
   863  }
   864  
   865  func (o *Object) ordinaryToPrimitiveString() Value {
   866  	if v := o.tryPrimitive("toString"); v != nil {
   867  		return v
   868  	}
   869  
   870  	if v := o.tryPrimitive("valueOf"); v != nil {
   871  		return v
   872  	}
   873  
   874  	panic(o.runtime.NewTypeError("Could not convert %v to primitive", o.self))
   875  }
   876  
   877  func (o *Object) tryExoticToPrimitive(hint Value) Value {
   878  	exoticToPrimitive := toMethod(o.self.getSym(SymToPrimitive, nil))
   879  	if exoticToPrimitive != nil {
   880  		ret := exoticToPrimitive(FunctionCall{
   881  			This:      o,
   882  			Arguments: []Value{hint},
   883  		})
   884  		if _, fail := ret.(*Object); !fail {
   885  			return ret
   886  		}
   887  		panic(o.runtime.NewTypeError("Cannot convert object to primitive value"))
   888  	}
   889  	return nil
   890  }
   891  
   892  func (o *Object) toPrimitiveNumber() Value {
   893  	if v := o.tryExoticToPrimitive(hintNumber); v != nil {
   894  		return v
   895  	}
   896  
   897  	return o.ordinaryToPrimitiveNumber()
   898  }
   899  
   900  func (o *Object) toPrimitiveString() Value {
   901  	if v := o.tryExoticToPrimitive(hintString); v != nil {
   902  		return v
   903  	}
   904  
   905  	return o.ordinaryToPrimitiveString()
   906  }
   907  
   908  func (o *Object) toPrimitive() Value {
   909  	if v := o.tryExoticToPrimitive(hintDefault); v != nil {
   910  		return v
   911  	}
   912  	return o.ordinaryToPrimitiveNumber()
   913  }
   914  
   915  func (o *baseObject) assertCallable() (func(FunctionCall) Value, bool) {
   916  	return nil, false
   917  }
   918  
   919  func (o *baseObject) vmCall(vm *vm, n int) {
   920  	vm.r.typeErrorResult(true, "Not a function: %s", o.val.toString())
   921  }
   922  
   923  func (o *baseObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
   924  	return nil
   925  }
   926  
   927  func (o *baseObject) proto() *Object {
   928  	return o.prototype
   929  }
   930  
   931  func (o *baseObject) isExtensible() bool {
   932  	return o.extensible
   933  }
   934  
   935  func (o *baseObject) preventExtensions(bool) bool {
   936  	o.extensible = false
   937  	return true
   938  }
   939  
   940  func (o *baseObject) sortLen() int {
   941  	return toIntStrict(toLength(o.val.self.getStr("length", nil)))
   942  }
   943  
   944  func (o *baseObject) sortGet(i int) Value {
   945  	return o.val.self.getIdx(valueInt(i), nil)
   946  }
   947  
   948  func (o *baseObject) swap(i int, j int) {
   949  	ii := valueInt(i)
   950  	jj := valueInt(j)
   951  
   952  	x := o.val.self.getIdx(ii, nil)
   953  	y := o.val.self.getIdx(jj, nil)
   954  
   955  	o.val.self.setOwnIdx(ii, y, false)
   956  	o.val.self.setOwnIdx(jj, x, false)
   957  }
   958  
   959  func (o *baseObject) export(ctx *objectExportCtx) interface{} {
   960  	if v, exists := ctx.get(o.val); exists {
   961  		return v
   962  	}
   963  	keys := o.stringKeys(false, nil)
   964  	m := make(map[string]interface{}, len(keys))
   965  	ctx.put(o.val, m)
   966  	for _, itemName := range keys {
   967  		itemNameStr := itemName.String()
   968  		v := o.val.self.getStr(itemName.string(), nil)
   969  		if v != nil {
   970  			m[itemNameStr] = exportValue(v, ctx)
   971  		} else {
   972  			m[itemNameStr] = nil
   973  		}
   974  	}
   975  
   976  	return m
   977  }
   978  
   979  func (o *baseObject) exportType() reflect.Type {
   980  	return reflectTypeMap
   981  }
   982  
   983  func genericExportToMap(o *Object, dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
   984  	dst.Set(reflect.MakeMap(typ))
   985  	ctx.putTyped(o, typ, dst.Interface())
   986  	keyTyp := typ.Key()
   987  	elemTyp := typ.Elem()
   988  	needConvertKeys := !reflectTypeString.AssignableTo(keyTyp)
   989  	iter := &enumerableIter{
   990  		o:       o,
   991  		wrapped: o.self.iterateStringKeys(),
   992  	}
   993  	r := o.runtime
   994  	for item, next := iter.next(); next != nil; item, next = next() {
   995  		var kv reflect.Value
   996  		var err error
   997  		if needConvertKeys {
   998  			kv = reflect.New(keyTyp).Elem()
   999  			err = r.toReflectValue(item.name, kv, ctx)
  1000  			if err != nil {
  1001  				return fmt.Errorf("could not convert map key %s to %v: %w", item.name.String(), typ, err)
  1002  			}
  1003  		} else {
  1004  			kv = reflect.ValueOf(item.name.String())
  1005  		}
  1006  
  1007  		ival := o.self.getStr(item.name.string(), nil)
  1008  		if ival != nil {
  1009  			vv := reflect.New(elemTyp).Elem()
  1010  			err = r.toReflectValue(ival, vv, ctx)
  1011  			if err != nil {
  1012  				return fmt.Errorf("could not convert map value %v to %v at key %s: %w", ival, typ, item.name.String(), err)
  1013  			}
  1014  			dst.SetMapIndex(kv, vv)
  1015  		} else {
  1016  			dst.SetMapIndex(kv, reflect.Zero(elemTyp))
  1017  		}
  1018  	}
  1019  
  1020  	return nil
  1021  }
  1022  
  1023  func (o *baseObject) exportToMap(m reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
  1024  	return genericExportToMap(o.val, m, typ, ctx)
  1025  }
  1026  
  1027  func genericExportToArrayOrSlice(o *Object, dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) (err error) {
  1028  	r := o.runtime
  1029  
  1030  	if method := toMethod(r.getV(o, SymIterator)); method != nil {
  1031  		// iterable
  1032  
  1033  		var values []Value
  1034  		// cannot change (append to) the slice once it's been put into the cache, so we need to know its length beforehand
  1035  		ex := r.try(func() {
  1036  			values = r.iterableToList(o, method)
  1037  		})
  1038  		if ex != nil {
  1039  			return ex
  1040  		}
  1041  		if typ.Kind() == reflect.Array {
  1042  			if dst.Len() != len(values) {
  1043  				return fmt.Errorf("cannot convert an iterable into an array, lengths mismatch (have %d, need %d)", len(values), dst.Len())
  1044  			}
  1045  		} else {
  1046  			dst.Set(reflect.MakeSlice(typ, len(values), len(values)))
  1047  		}
  1048  		ctx.putTyped(o, typ, dst.Interface())
  1049  		for i, val := range values {
  1050  			err = r.toReflectValue(val, dst.Index(i), ctx)
  1051  			if err != nil {
  1052  				return
  1053  			}
  1054  		}
  1055  	} else {
  1056  		// array-like
  1057  		var lp Value
  1058  		if _, ok := o.self.assertCallable(); !ok {
  1059  			lp = o.self.getStr("length", nil)
  1060  		}
  1061  		if lp == nil {
  1062  			return fmt.Errorf("cannot convert %v to %v: not an array or iterable", o, typ)
  1063  		}
  1064  		l := toIntStrict(toLength(lp))
  1065  		if dst.Len() != l {
  1066  			if typ.Kind() == reflect.Array {
  1067  				return fmt.Errorf("cannot convert an array-like object into an array, lengths mismatch (have %d, need %d)", l, dst.Len())
  1068  			} else {
  1069  				dst.Set(reflect.MakeSlice(typ, l, l))
  1070  			}
  1071  		}
  1072  		ctx.putTyped(o, typ, dst.Interface())
  1073  		for i := 0; i < l; i++ {
  1074  			val := nilSafe(o.self.getIdx(valueInt(i), nil))
  1075  			err = r.toReflectValue(val, dst.Index(i), ctx)
  1076  			if err != nil {
  1077  				return
  1078  			}
  1079  		}
  1080  	}
  1081  
  1082  	return
  1083  }
  1084  
  1085  func (o *baseObject) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
  1086  	return genericExportToArrayOrSlice(o.val, dst, typ, ctx)
  1087  }
  1088  
  1089  type enumerableFlag int
  1090  
  1091  const (
  1092  	_ENUM_UNKNOWN enumerableFlag = iota
  1093  	_ENUM_FALSE
  1094  	_ENUM_TRUE
  1095  )
  1096  
  1097  type propIterItem struct {
  1098  	name       Value
  1099  	value      Value
  1100  	enumerable enumerableFlag
  1101  }
  1102  
  1103  type objectPropIter struct {
  1104  	o         *baseObject
  1105  	propNames []unistring.String
  1106  	idx       int
  1107  }
  1108  
  1109  type recursivePropIter struct {
  1110  	o    objectImpl
  1111  	cur  iterNextFunc
  1112  	seen map[unistring.String]struct{}
  1113  }
  1114  
  1115  type enumerableIter struct {
  1116  	o       *Object
  1117  	wrapped iterNextFunc
  1118  }
  1119  
  1120  func (i *enumerableIter) next() (propIterItem, iterNextFunc) {
  1121  	for {
  1122  		var item propIterItem
  1123  		item, i.wrapped = i.wrapped()
  1124  		if i.wrapped == nil {
  1125  			return item, nil
  1126  		}
  1127  		if item.enumerable == _ENUM_FALSE {
  1128  			continue
  1129  		}
  1130  		if item.enumerable == _ENUM_UNKNOWN {
  1131  			var prop Value
  1132  			if item.value == nil {
  1133  				prop = i.o.getOwnProp(item.name)
  1134  			} else {
  1135  				prop = item.value
  1136  			}
  1137  			if prop == nil {
  1138  				continue
  1139  			}
  1140  			if prop, ok := prop.(*valueProperty); ok {
  1141  				if !prop.enumerable {
  1142  					continue
  1143  				}
  1144  			}
  1145  		}
  1146  		return item, i.next
  1147  	}
  1148  }
  1149  
  1150  func (i *recursivePropIter) next() (propIterItem, iterNextFunc) {
  1151  	for {
  1152  		var item propIterItem
  1153  		item, i.cur = i.cur()
  1154  		if i.cur == nil {
  1155  			if proto := i.o.proto(); proto != nil {
  1156  				i.cur = proto.self.iterateStringKeys()
  1157  				i.o = proto.self
  1158  				continue
  1159  			}
  1160  			return propIterItem{}, nil
  1161  		}
  1162  		name := item.name.string()
  1163  		if _, exists := i.seen[name]; !exists {
  1164  			i.seen[name] = struct{}{}
  1165  			return item, i.next
  1166  		}
  1167  	}
  1168  }
  1169  
  1170  func enumerateRecursive(o *Object) iterNextFunc {
  1171  	return (&enumerableIter{
  1172  		o: o,
  1173  		wrapped: (&recursivePropIter{
  1174  			o:    o.self,
  1175  			cur:  o.self.iterateStringKeys(),
  1176  			seen: make(map[unistring.String]struct{}),
  1177  		}).next,
  1178  	}).next
  1179  }
  1180  
  1181  func (i *objectPropIter) next() (propIterItem, iterNextFunc) {
  1182  	for i.idx < len(i.propNames) {
  1183  		name := i.propNames[i.idx]
  1184  		i.idx++
  1185  		prop := i.o.values[name]
  1186  		if prop != nil {
  1187  			return propIterItem{name: stringValueFromRaw(name), value: prop}, i.next
  1188  		}
  1189  	}
  1190  	clearNamesCopyMarker(i.propNames)
  1191  	return propIterItem{}, nil
  1192  }
  1193  
  1194  var copyMarker = unistring.String(" ")
  1195  
  1196  // Set a copy-on-write flag so that any subsequent modifications of anything below the current length
  1197  // trigger a copy.
  1198  // The marker is a special value put at the index position of cap-1. Capacity is set so that the marker is
  1199  // beyond the current length (therefore invisible to normal slice operations).
  1200  // This function is called before an iteration begins to avoid copying of the names array if
  1201  // there are no modifications within the iteration.
  1202  // Note that the copying also occurs in two cases: nested iterations (on the same object) and
  1203  // iterations after a previously abandoned iteration (because there is currently no mechanism to close an
  1204  // iterator). It is still better than copying every time.
  1205  func prepareNamesForCopy(names []unistring.String) []unistring.String {
  1206  	if len(names) == 0 {
  1207  		return names
  1208  	}
  1209  	if namesMarkedForCopy(names) || cap(names) == len(names) {
  1210  		var newcap int
  1211  		if cap(names) == len(names) {
  1212  			newcap = growCap(len(names)+1, len(names), cap(names))
  1213  		} else {
  1214  			newcap = cap(names)
  1215  		}
  1216  		newNames := make([]unistring.String, len(names), newcap)
  1217  		copy(newNames, names)
  1218  		names = newNames
  1219  	}
  1220  	names[cap(names)-1 : cap(names)][0] = copyMarker
  1221  	return names
  1222  }
  1223  
  1224  func namesMarkedForCopy(names []unistring.String) bool {
  1225  	return cap(names) > len(names) && names[cap(names)-1 : cap(names)][0] == copyMarker
  1226  }
  1227  
  1228  func clearNamesCopyMarker(names []unistring.String) {
  1229  	if cap(names) > len(names) {
  1230  		names[cap(names)-1 : cap(names)][0] = ""
  1231  	}
  1232  }
  1233  
  1234  func copyNamesIfNeeded(names []unistring.String, extraCap int) []unistring.String {
  1235  	if namesMarkedForCopy(names) && len(names)+extraCap >= cap(names) {
  1236  		var newcap int
  1237  		newsize := len(names) + extraCap + 1
  1238  		if newsize > cap(names) {
  1239  			newcap = growCap(newsize, len(names), cap(names))
  1240  		} else {
  1241  			newcap = cap(names)
  1242  		}
  1243  		newNames := make([]unistring.String, len(names), newcap)
  1244  		copy(newNames, names)
  1245  		return newNames
  1246  	}
  1247  	return names
  1248  }
  1249  
  1250  func (o *baseObject) iterateStringKeys() iterNextFunc {
  1251  	o.ensurePropOrder()
  1252  	propNames := prepareNamesForCopy(o.propNames)
  1253  	o.propNames = propNames
  1254  	return (&objectPropIter{
  1255  		o:         o,
  1256  		propNames: propNames,
  1257  	}).next
  1258  }
  1259  
  1260  type objectSymbolIter struct {
  1261  	iter *orderedMapIter
  1262  }
  1263  
  1264  func (i *objectSymbolIter) next() (propIterItem, iterNextFunc) {
  1265  	entry := i.iter.next()
  1266  	if entry != nil {
  1267  		return propIterItem{
  1268  			name:  entry.key,
  1269  			value: entry.value,
  1270  		}, i.next
  1271  	}
  1272  	return propIterItem{}, nil
  1273  }
  1274  
  1275  func (o *baseObject) iterateSymbols() iterNextFunc {
  1276  	if o.symValues != nil {
  1277  		return (&objectSymbolIter{
  1278  			iter: o.symValues.newIter(),
  1279  		}).next
  1280  	}
  1281  	return func() (propIterItem, iterNextFunc) {
  1282  		return propIterItem{}, nil
  1283  	}
  1284  }
  1285  
  1286  type objectAllPropIter struct {
  1287  	o      *Object
  1288  	curStr iterNextFunc
  1289  }
  1290  
  1291  func (i *objectAllPropIter) next() (propIterItem, iterNextFunc) {
  1292  	item, next := i.curStr()
  1293  	if next != nil {
  1294  		i.curStr = next
  1295  		return item, i.next
  1296  	}
  1297  	return i.o.self.iterateSymbols()()
  1298  }
  1299  
  1300  func (o *baseObject) iterateKeys() iterNextFunc {
  1301  	return (&objectAllPropIter{
  1302  		o:      o.val,
  1303  		curStr: o.val.self.iterateStringKeys(),
  1304  	}).next
  1305  }
  1306  
  1307  func (o *baseObject) equal(objectImpl) bool {
  1308  	// Rely on parent reference comparison
  1309  	return false
  1310  }
  1311  
  1312  // hopefully this gets inlined
  1313  func (o *baseObject) ensurePropOrder() {
  1314  	if o.lastSortedPropLen < len(o.propNames) {
  1315  		o.fixPropOrder()
  1316  	}
  1317  }
  1318  
  1319  // Reorder property names so that any integer properties are shifted to the beginning of the list
  1320  // in ascending order. This is to conform to https://262.ecma-international.org/#sec-ordinaryownpropertykeys.
  1321  // Personally I think this requirement is strange. I can sort of understand where they are coming from,
  1322  // this way arrays can be specified just as objects with a 'magic' length property. However, I think
  1323  // it's safe to assume most devs don't use Objects to store integer properties. Therefore, performing
  1324  // property type checks when adding (and potentially looking up) properties would be unreasonable.
  1325  // Instead, we keep insertion order and only change it when (if) the properties get enumerated.
  1326  func (o *baseObject) fixPropOrder() {
  1327  	names := o.propNames
  1328  	for i := o.lastSortedPropLen; i < len(names); i++ {
  1329  		name := names[i]
  1330  		if idx := strToArrayIdx(name); idx != math.MaxUint32 {
  1331  			k := sort.Search(o.idxPropCount, func(j int) bool {
  1332  				return strToArrayIdx(names[j]) >= idx
  1333  			})
  1334  			if k < i {
  1335  				if namesMarkedForCopy(names) {
  1336  					newNames := make([]unistring.String, len(names), cap(names))
  1337  					copy(newNames[:k], names)
  1338  					copy(newNames[k+1:i+1], names[k:i])
  1339  					copy(newNames[i+1:], names[i+1:])
  1340  					names = newNames
  1341  					o.propNames = names
  1342  				} else {
  1343  					copy(names[k+1:i+1], names[k:i])
  1344  				}
  1345  				names[k] = name
  1346  			}
  1347  			o.idxPropCount++
  1348  		}
  1349  	}
  1350  	o.lastSortedPropLen = len(names)
  1351  }
  1352  
  1353  func (o *baseObject) stringKeys(all bool, keys []Value) []Value {
  1354  	o.ensurePropOrder()
  1355  	if all {
  1356  		for _, k := range o.propNames {
  1357  			keys = append(keys, stringValueFromRaw(k))
  1358  		}
  1359  	} else {
  1360  		for _, k := range o.propNames {
  1361  			prop := o.values[k]
  1362  			if prop, ok := prop.(*valueProperty); ok && !prop.enumerable {
  1363  				continue
  1364  			}
  1365  			keys = append(keys, stringValueFromRaw(k))
  1366  		}
  1367  	}
  1368  	return keys
  1369  }
  1370  
  1371  func (o *baseObject) symbols(all bool, accum []Value) []Value {
  1372  	if o.symValues != nil {
  1373  		iter := o.symValues.newIter()
  1374  		if all {
  1375  			for {
  1376  				entry := iter.next()
  1377  				if entry == nil {
  1378  					break
  1379  				}
  1380  				accum = append(accum, entry.key)
  1381  			}
  1382  		} else {
  1383  			for {
  1384  				entry := iter.next()
  1385  				if entry == nil {
  1386  					break
  1387  				}
  1388  				if prop, ok := entry.value.(*valueProperty); ok {
  1389  					if !prop.enumerable {
  1390  						continue
  1391  					}
  1392  				}
  1393  				accum = append(accum, entry.key)
  1394  			}
  1395  		}
  1396  	}
  1397  
  1398  	return accum
  1399  }
  1400  
  1401  func (o *baseObject) keys(all bool, accum []Value) []Value {
  1402  	return o.symbols(all, o.val.self.stringKeys(all, accum))
  1403  }
  1404  
  1405  func (o *baseObject) hasInstance(Value) bool {
  1406  	panic(o.val.runtime.NewTypeError("Expecting a function in instanceof check, but got %s", o.val.toString()))
  1407  }
  1408  
  1409  func toMethod(v Value) func(FunctionCall) Value {
  1410  	if v == nil || IsUndefined(v) || IsNull(v) {
  1411  		return nil
  1412  	}
  1413  	if obj, ok := v.(*Object); ok {
  1414  		if call, ok := obj.self.assertCallable(); ok {
  1415  			return call
  1416  		}
  1417  	}
  1418  	panic(newTypeError("%s is not a method", v.String()))
  1419  }
  1420  
  1421  func instanceOfOperator(o Value, c *Object) bool {
  1422  	if instOfHandler := toMethod(c.self.getSym(SymHasInstance, c)); instOfHandler != nil {
  1423  		return instOfHandler(FunctionCall{
  1424  			This:      c,
  1425  			Arguments: []Value{o},
  1426  		}).ToBoolean()
  1427  	}
  1428  
  1429  	return c.self.hasInstance(o)
  1430  }
  1431  
  1432  func (o *Object) get(p Value, receiver Value) Value {
  1433  	switch p := p.(type) {
  1434  	case valueInt:
  1435  		return o.self.getIdx(p, receiver)
  1436  	case *Symbol:
  1437  		return o.self.getSym(p, receiver)
  1438  	default:
  1439  		return o.self.getStr(p.string(), receiver)
  1440  	}
  1441  }
  1442  
  1443  func (o *Object) getOwnProp(p Value) Value {
  1444  	switch p := p.(type) {
  1445  	case valueInt:
  1446  		return o.self.getOwnPropIdx(p)
  1447  	case *Symbol:
  1448  		return o.self.getOwnPropSym(p)
  1449  	default:
  1450  		return o.self.getOwnPropStr(p.string())
  1451  	}
  1452  }
  1453  
  1454  func (o *Object) hasOwnProperty(p Value) bool {
  1455  	switch p := p.(type) {
  1456  	case valueInt:
  1457  		return o.self.hasOwnPropertyIdx(p)
  1458  	case *Symbol:
  1459  		return o.self.hasOwnPropertySym(p)
  1460  	default:
  1461  		return o.self.hasOwnPropertyStr(p.string())
  1462  	}
  1463  }
  1464  
  1465  func (o *Object) hasProperty(p Value) bool {
  1466  	switch p := p.(type) {
  1467  	case valueInt:
  1468  		return o.self.hasPropertyIdx(p)
  1469  	case *Symbol:
  1470  		return o.self.hasPropertySym(p)
  1471  	default:
  1472  		return o.self.hasPropertyStr(p.string())
  1473  	}
  1474  }
  1475  
  1476  func (o *Object) setStr(name unistring.String, val, receiver Value, throw bool) bool {
  1477  	if receiver == o {
  1478  		return o.self.setOwnStr(name, val, throw)
  1479  	} else {
  1480  		if res, ok := o.self.setForeignStr(name, val, receiver, throw); !ok {
  1481  			if robj, ok := receiver.(*Object); ok {
  1482  				if prop := robj.self.getOwnPropStr(name); prop != nil {
  1483  					if desc, ok := prop.(*valueProperty); ok {
  1484  						if desc.accessor {
  1485  							o.runtime.typeErrorResult(throw, "Receiver property %s is an accessor", name)
  1486  							return false
  1487  						}
  1488  						if !desc.writable {
  1489  							o.runtime.typeErrorResult(throw, "Cannot assign to read only property '%s'", name)
  1490  							return false
  1491  						}
  1492  					}
  1493  					return robj.self.defineOwnPropertyStr(name, PropertyDescriptor{Value: val}, throw)
  1494  				} else {
  1495  					return robj.self.defineOwnPropertyStr(name, PropertyDescriptor{
  1496  						Value:        val,
  1497  						Writable:     FLAG_TRUE,
  1498  						Configurable: FLAG_TRUE,
  1499  						Enumerable:   FLAG_TRUE,
  1500  					}, throw)
  1501  				}
  1502  			} else {
  1503  				o.runtime.typeErrorResult(throw, "Receiver is not an object: %v", receiver)
  1504  				return false
  1505  			}
  1506  		} else {
  1507  			return res
  1508  		}
  1509  	}
  1510  }
  1511  
  1512  func (o *Object) set(name Value, val, receiver Value, throw bool) bool {
  1513  	switch name := name.(type) {
  1514  	case valueInt:
  1515  		return o.setIdx(name, val, receiver, throw)
  1516  	case *Symbol:
  1517  		return o.setSym(name, val, receiver, throw)
  1518  	default:
  1519  		return o.setStr(name.string(), val, receiver, throw)
  1520  	}
  1521  }
  1522  
  1523  func (o *Object) setOwn(name Value, val Value, throw bool) bool {
  1524  	switch name := name.(type) {
  1525  	case valueInt:
  1526  		return o.self.setOwnIdx(name, val, throw)
  1527  	case *Symbol:
  1528  		return o.self.setOwnSym(name, val, throw)
  1529  	default:
  1530  		return o.self.setOwnStr(name.string(), val, throw)
  1531  	}
  1532  }
  1533  
  1534  func (o *Object) setIdx(name valueInt, val, receiver Value, throw bool) bool {
  1535  	if receiver == o {
  1536  		return o.self.setOwnIdx(name, val, throw)
  1537  	} else {
  1538  		if res, ok := o.self.setForeignIdx(name, val, receiver, throw); !ok {
  1539  			if robj, ok := receiver.(*Object); ok {
  1540  				if prop := robj.self.getOwnPropIdx(name); prop != nil {
  1541  					if desc, ok := prop.(*valueProperty); ok {
  1542  						if desc.accessor {
  1543  							o.runtime.typeErrorResult(throw, "Receiver property %s is an accessor", name)
  1544  							return false
  1545  						}
  1546  						if !desc.writable {
  1547  							o.runtime.typeErrorResult(throw, "Cannot assign to read only property '%s'", name)
  1548  							return false
  1549  						}
  1550  					}
  1551  					robj.self.defineOwnPropertyIdx(name, PropertyDescriptor{Value: val}, throw)
  1552  				} else {
  1553  					robj.self.defineOwnPropertyIdx(name, PropertyDescriptor{
  1554  						Value:        val,
  1555  						Writable:     FLAG_TRUE,
  1556  						Configurable: FLAG_TRUE,
  1557  						Enumerable:   FLAG_TRUE,
  1558  					}, throw)
  1559  				}
  1560  			} else {
  1561  				o.runtime.typeErrorResult(throw, "Receiver is not an object: %v", receiver)
  1562  				return false
  1563  			}
  1564  		} else {
  1565  			return res
  1566  		}
  1567  	}
  1568  	return true
  1569  }
  1570  
  1571  func (o *Object) setSym(name *Symbol, val, receiver Value, throw bool) bool {
  1572  	if receiver == o {
  1573  		return o.self.setOwnSym(name, val, throw)
  1574  	} else {
  1575  		if res, ok := o.self.setForeignSym(name, val, receiver, throw); !ok {
  1576  			if robj, ok := receiver.(*Object); ok {
  1577  				if prop := robj.self.getOwnPropSym(name); prop != nil {
  1578  					if desc, ok := prop.(*valueProperty); ok {
  1579  						if desc.accessor {
  1580  							o.runtime.typeErrorResult(throw, "Receiver property %s is an accessor", name)
  1581  							return false
  1582  						}
  1583  						if !desc.writable {
  1584  							o.runtime.typeErrorResult(throw, "Cannot assign to read only property '%s'", name)
  1585  							return false
  1586  						}
  1587  					}
  1588  					robj.self.defineOwnPropertySym(name, PropertyDescriptor{Value: val}, throw)
  1589  				} else {
  1590  					robj.self.defineOwnPropertySym(name, PropertyDescriptor{
  1591  						Value:        val,
  1592  						Writable:     FLAG_TRUE,
  1593  						Configurable: FLAG_TRUE,
  1594  						Enumerable:   FLAG_TRUE,
  1595  					}, throw)
  1596  				}
  1597  			} else {
  1598  				o.runtime.typeErrorResult(throw, "Receiver is not an object: %v", receiver)
  1599  				return false
  1600  			}
  1601  		} else {
  1602  			return res
  1603  		}
  1604  	}
  1605  	return true
  1606  }
  1607  
  1608  func (o *Object) delete(n Value, throw bool) bool {
  1609  	switch n := n.(type) {
  1610  	case valueInt:
  1611  		return o.self.deleteIdx(n, throw)
  1612  	case *Symbol:
  1613  		return o.self.deleteSym(n, throw)
  1614  	default:
  1615  		return o.self.deleteStr(n.string(), throw)
  1616  	}
  1617  }
  1618  
  1619  func (o *Object) defineOwnProperty(n Value, desc PropertyDescriptor, throw bool) bool {
  1620  	switch n := n.(type) {
  1621  	case valueInt:
  1622  		return o.self.defineOwnPropertyIdx(n, desc, throw)
  1623  	case *Symbol:
  1624  		return o.self.defineOwnPropertySym(n, desc, throw)
  1625  	default:
  1626  		return o.self.defineOwnPropertyStr(n.string(), desc, throw)
  1627  	}
  1628  }
  1629  
  1630  func (o *Object) getWeakRefs() map[weakMap]Value {
  1631  	refs := o.weakRefs
  1632  	if refs == nil {
  1633  		refs = make(map[weakMap]Value)
  1634  		o.weakRefs = refs
  1635  	}
  1636  	return refs
  1637  }
  1638  
  1639  func (o *Object) getId() uint64 {
  1640  	id := o.id
  1641  	if id == 0 {
  1642  		id = o.runtime.genId()
  1643  		o.id = id
  1644  	}
  1645  	return id
  1646  }
  1647  
  1648  func (o *guardedObject) guard(props ...unistring.String) {
  1649  	if o.guardedProps == nil {
  1650  		o.guardedProps = make(map[unistring.String]struct{})
  1651  	}
  1652  	for _, p := range props {
  1653  		o.guardedProps[p] = struct{}{}
  1654  	}
  1655  }
  1656  
  1657  func (o *guardedObject) check(p unistring.String) {
  1658  	if _, exists := o.guardedProps[p]; exists {
  1659  		o.val.self = &o.baseObject
  1660  	}
  1661  }
  1662  
  1663  func (o *guardedObject) setOwnStr(p unistring.String, v Value, throw bool) bool {
  1664  	res := o.baseObject.setOwnStr(p, v, throw)
  1665  	if res {
  1666  		o.check(p)
  1667  	}
  1668  	return res
  1669  }
  1670  
  1671  func (o *guardedObject) defineOwnPropertyStr(name unistring.String, desc PropertyDescriptor, throw bool) bool {
  1672  	res := o.baseObject.defineOwnPropertyStr(name, desc, throw)
  1673  	if res {
  1674  		o.check(name)
  1675  	}
  1676  	return res
  1677  }
  1678  
  1679  func (o *guardedObject) deleteStr(name unistring.String, throw bool) bool {
  1680  	res := o.baseObject.deleteStr(name, throw)
  1681  	if res {
  1682  		o.check(name)
  1683  	}
  1684  	return res
  1685  }
  1686  
  1687  func (ctx *objectExportCtx) get(key *Object) (interface{}, bool) {
  1688  	if v, exists := ctx.cache[key]; exists {
  1689  		if item, ok := v.(objectExportCacheItem); ok {
  1690  			r, exists := item[key.self.exportType()]
  1691  			return r, exists
  1692  		} else {
  1693  			return v, true
  1694  		}
  1695  	}
  1696  	return nil, false
  1697  }
  1698  
  1699  func (ctx *objectExportCtx) getTyped(key *Object, typ reflect.Type) (interface{}, bool) {
  1700  	if v, exists := ctx.cache[key]; exists {
  1701  		if item, ok := v.(objectExportCacheItem); ok {
  1702  			r, exists := item[typ]
  1703  			return r, exists
  1704  		} else {
  1705  			if reflect.TypeOf(v) == typ {
  1706  				return v, true
  1707  			}
  1708  		}
  1709  	}
  1710  	return nil, false
  1711  }
  1712  
  1713  func (ctx *objectExportCtx) put(key *Object, value interface{}) {
  1714  	if ctx.cache == nil {
  1715  		ctx.cache = make(map[*Object]interface{})
  1716  	}
  1717  	if item, ok := ctx.cache[key].(objectExportCacheItem); ok {
  1718  		item[key.self.exportType()] = value
  1719  	} else {
  1720  		ctx.cache[key] = value
  1721  	}
  1722  }
  1723  
  1724  func (ctx *objectExportCtx) putTyped(key *Object, typ reflect.Type, value interface{}) {
  1725  	if ctx.cache == nil {
  1726  		ctx.cache = make(map[*Object]interface{})
  1727  	}
  1728  	v, exists := ctx.cache[key]
  1729  	if exists {
  1730  		if item, ok := ctx.cache[key].(objectExportCacheItem); ok {
  1731  			item[typ] = value
  1732  		} else {
  1733  			m := make(objectExportCacheItem, 2)
  1734  			m[key.self.exportType()] = v
  1735  			m[typ] = value
  1736  			ctx.cache[key] = m
  1737  		}
  1738  	} else {
  1739  		m := make(objectExportCacheItem)
  1740  		m[typ] = value
  1741  		ctx.cache[key] = m
  1742  	}
  1743  }
  1744  
  1745  type enumPropertiesIter struct {
  1746  	o       *Object
  1747  	wrapped iterNextFunc
  1748  }
  1749  
  1750  func (i *enumPropertiesIter) next() (propIterItem, iterNextFunc) {
  1751  	for i.wrapped != nil {
  1752  		item, next := i.wrapped()
  1753  		i.wrapped = next
  1754  		if next == nil {
  1755  			break
  1756  		}
  1757  		if item.value == nil {
  1758  			item.value = i.o.get(item.name, nil)
  1759  			if item.value == nil {
  1760  				continue
  1761  			}
  1762  		} else {
  1763  			if prop, ok := item.value.(*valueProperty); ok {
  1764  				item.value = prop.get(i.o)
  1765  			}
  1766  		}
  1767  		return item, i.next
  1768  	}
  1769  	return propIterItem{}, nil
  1770  }
  1771  
  1772  func iterateEnumerableProperties(o *Object) iterNextFunc {
  1773  	return (&enumPropertiesIter{
  1774  		o: o,
  1775  		wrapped: (&enumerableIter{
  1776  			o:       o,
  1777  			wrapped: o.self.iterateKeys(),
  1778  		}).next,
  1779  	}).next
  1780  }
  1781  
  1782  func iterateEnumerableStringProperties(o *Object) iterNextFunc {
  1783  	return (&enumPropertiesIter{
  1784  		o: o,
  1785  		wrapped: (&enumerableIter{
  1786  			o:       o,
  1787  			wrapped: o.self.iterateStringKeys(),
  1788  		}).next,
  1789  	}).next
  1790  }
  1791  
  1792  type privateId struct {
  1793  	typ      *privateEnvType
  1794  	name     unistring.String
  1795  	idx      uint32
  1796  	isMethod bool
  1797  }
  1798  
  1799  type privateEnvType struct {
  1800  	numFields, numMethods uint32
  1801  }
  1802  
  1803  type privateNames map[unistring.String]*privateId
  1804  
  1805  type privateEnv struct {
  1806  	instanceType, staticType *privateEnvType
  1807  
  1808  	names privateNames
  1809  
  1810  	outer *privateEnv
  1811  }
  1812  
  1813  type privateElements struct {
  1814  	methods []Value
  1815  	fields  []Value
  1816  }
  1817  
  1818  func (i *privateId) String() string {
  1819  	return "#" + i.name.String()
  1820  }
  1821  
  1822  func (i *privateId) string() unistring.String {
  1823  	return privateIdString(i.name)
  1824  }