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 }