github.com/dop251/goja@v0.0.0-20240220182346-e401ed450204/builtin_object.go (about) 1 package goja 2 3 import ( 4 "fmt" 5 "sync" 6 ) 7 8 func (r *Runtime) builtin_Object(args []Value, newTarget *Object) *Object { 9 if newTarget != nil && newTarget != r.getObject() { 10 proto := r.getPrototypeFromCtor(newTarget, nil, r.global.ObjectPrototype) 11 return r.newBaseObject(proto, classObject).val 12 } 13 if len(args) > 0 { 14 arg := args[0] 15 if arg != _undefined && arg != _null { 16 return arg.ToObject(r) 17 } 18 } 19 return r.NewObject() 20 } 21 22 func (r *Runtime) object_getPrototypeOf(call FunctionCall) Value { 23 o := call.Argument(0).ToObject(r) 24 p := o.self.proto() 25 if p == nil { 26 return _null 27 } 28 return p 29 } 30 31 func (r *Runtime) valuePropToDescriptorObject(desc Value) Value { 32 if desc == nil { 33 return _undefined 34 } 35 var writable, configurable, enumerable, accessor bool 36 var get, set *Object 37 var value Value 38 if v, ok := desc.(*valueProperty); ok { 39 writable = v.writable 40 configurable = v.configurable 41 enumerable = v.enumerable 42 accessor = v.accessor 43 value = v.value 44 get = v.getterFunc 45 set = v.setterFunc 46 } else { 47 writable = true 48 configurable = true 49 enumerable = true 50 value = desc 51 } 52 53 ret := r.NewObject() 54 obj := ret.self 55 if !accessor { 56 obj.setOwnStr("value", value, false) 57 obj.setOwnStr("writable", r.toBoolean(writable), false) 58 } else { 59 if get != nil { 60 obj.setOwnStr("get", get, false) 61 } else { 62 obj.setOwnStr("get", _undefined, false) 63 } 64 if set != nil { 65 obj.setOwnStr("set", set, false) 66 } else { 67 obj.setOwnStr("set", _undefined, false) 68 } 69 } 70 obj.setOwnStr("enumerable", r.toBoolean(enumerable), false) 71 obj.setOwnStr("configurable", r.toBoolean(configurable), false) 72 73 return ret 74 } 75 76 func (r *Runtime) object_getOwnPropertyDescriptor(call FunctionCall) Value { 77 o := call.Argument(0).ToObject(r) 78 propName := toPropertyKey(call.Argument(1)) 79 return r.valuePropToDescriptorObject(o.getOwnProp(propName)) 80 } 81 82 func (r *Runtime) object_getOwnPropertyDescriptors(call FunctionCall) Value { 83 o := call.Argument(0).ToObject(r) 84 result := r.newBaseObject(r.global.ObjectPrototype, classObject).val 85 for item, next := o.self.iterateKeys()(); next != nil; item, next = next() { 86 var prop Value 87 if item.value == nil { 88 prop = o.getOwnProp(item.name) 89 if prop == nil { 90 continue 91 } 92 } else { 93 prop = item.value 94 } 95 descriptor := r.valuePropToDescriptorObject(prop) 96 if descriptor != _undefined { 97 createDataPropertyOrThrow(result, item.name, descriptor) 98 } 99 } 100 return result 101 } 102 103 func (r *Runtime) object_getOwnPropertyNames(call FunctionCall) Value { 104 obj := call.Argument(0).ToObject(r) 105 106 return r.newArrayValues(obj.self.stringKeys(true, nil)) 107 } 108 109 func (r *Runtime) object_getOwnPropertySymbols(call FunctionCall) Value { 110 obj := call.Argument(0).ToObject(r) 111 return r.newArrayValues(obj.self.symbols(true, nil)) 112 } 113 114 func (r *Runtime) toValueProp(v Value) *valueProperty { 115 if v == nil || v == _undefined { 116 return nil 117 } 118 obj := r.toObject(v) 119 getter := obj.self.getStr("get", nil) 120 setter := obj.self.getStr("set", nil) 121 writable := obj.self.getStr("writable", nil) 122 value := obj.self.getStr("value", nil) 123 if (getter != nil || setter != nil) && (value != nil || writable != nil) { 124 r.typeErrorResult(true, "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute") 125 } 126 127 ret := &valueProperty{} 128 if writable != nil && writable.ToBoolean() { 129 ret.writable = true 130 } 131 if e := obj.self.getStr("enumerable", nil); e != nil && e.ToBoolean() { 132 ret.enumerable = true 133 } 134 if c := obj.self.getStr("configurable", nil); c != nil && c.ToBoolean() { 135 ret.configurable = true 136 } 137 ret.value = value 138 139 if getter != nil && getter != _undefined { 140 o := r.toObject(getter) 141 if _, ok := o.self.assertCallable(); !ok { 142 r.typeErrorResult(true, "getter must be a function") 143 } 144 ret.getterFunc = o 145 } 146 147 if setter != nil && setter != _undefined { 148 o := r.toObject(setter) 149 if _, ok := o.self.assertCallable(); !ok { 150 r.typeErrorResult(true, "setter must be a function") 151 } 152 ret.setterFunc = o 153 } 154 155 if ret.getterFunc != nil || ret.setterFunc != nil { 156 ret.accessor = true 157 } 158 159 return ret 160 } 161 162 func (r *Runtime) toPropertyDescriptor(v Value) (ret PropertyDescriptor) { 163 if o, ok := v.(*Object); ok { 164 descr := o.self 165 166 // Save the original descriptor for reference 167 ret.jsDescriptor = o 168 169 ret.Value = descr.getStr("value", nil) 170 171 if p := descr.getStr("writable", nil); p != nil { 172 ret.Writable = ToFlag(p.ToBoolean()) 173 } 174 if p := descr.getStr("enumerable", nil); p != nil { 175 ret.Enumerable = ToFlag(p.ToBoolean()) 176 } 177 if p := descr.getStr("configurable", nil); p != nil { 178 ret.Configurable = ToFlag(p.ToBoolean()) 179 } 180 181 ret.Getter = descr.getStr("get", nil) 182 ret.Setter = descr.getStr("set", nil) 183 184 if ret.Getter != nil && ret.Getter != _undefined { 185 if _, ok := r.toObject(ret.Getter).self.assertCallable(); !ok { 186 r.typeErrorResult(true, "getter must be a function") 187 } 188 } 189 190 if ret.Setter != nil && ret.Setter != _undefined { 191 if _, ok := r.toObject(ret.Setter).self.assertCallable(); !ok { 192 r.typeErrorResult(true, "setter must be a function") 193 } 194 } 195 196 if (ret.Getter != nil || ret.Setter != nil) && (ret.Value != nil || ret.Writable != FLAG_NOT_SET) { 197 r.typeErrorResult(true, "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute") 198 } 199 } else { 200 r.typeErrorResult(true, "Property description must be an object: %s", v.String()) 201 } 202 203 return 204 } 205 206 func (r *Runtime) _defineProperties(o *Object, p Value) { 207 type propItem struct { 208 name Value 209 prop PropertyDescriptor 210 } 211 props := p.ToObject(r) 212 var list []propItem 213 for item, next := iterateEnumerableProperties(props)(); next != nil; item, next = next() { 214 list = append(list, propItem{ 215 name: item.name, 216 prop: r.toPropertyDescriptor(item.value), 217 }) 218 } 219 for _, prop := range list { 220 o.defineOwnProperty(prop.name, prop.prop, true) 221 } 222 } 223 224 func (r *Runtime) object_create(call FunctionCall) Value { 225 var proto *Object 226 if arg := call.Argument(0); arg != _null { 227 if o, ok := arg.(*Object); ok { 228 proto = o 229 } else { 230 r.typeErrorResult(true, "Object prototype may only be an Object or null: %s", arg.String()) 231 } 232 } 233 o := r.newBaseObject(proto, classObject).val 234 235 if props := call.Argument(1); props != _undefined { 236 r._defineProperties(o, props) 237 } 238 239 return o 240 } 241 242 func (r *Runtime) object_defineProperty(call FunctionCall) (ret Value) { 243 if obj, ok := call.Argument(0).(*Object); ok { 244 descr := r.toPropertyDescriptor(call.Argument(2)) 245 obj.defineOwnProperty(toPropertyKey(call.Argument(1)), descr, true) 246 ret = call.Argument(0) 247 } else { 248 r.typeErrorResult(true, "Object.defineProperty called on non-object") 249 } 250 return 251 } 252 253 func (r *Runtime) object_defineProperties(call FunctionCall) Value { 254 obj := r.toObject(call.Argument(0)) 255 r._defineProperties(obj, call.Argument(1)) 256 return obj 257 } 258 259 func (r *Runtime) object_seal(call FunctionCall) Value { 260 // ES6 261 arg := call.Argument(0) 262 if obj, ok := arg.(*Object); ok { 263 obj.self.preventExtensions(true) 264 descr := PropertyDescriptor{ 265 Configurable: FLAG_FALSE, 266 } 267 268 for item, next := obj.self.iterateKeys()(); next != nil; item, next = next() { 269 if prop, ok := item.value.(*valueProperty); ok { 270 prop.configurable = false 271 } else { 272 obj.defineOwnProperty(item.name, descr, true) 273 } 274 } 275 276 return obj 277 } 278 return arg 279 } 280 281 func (r *Runtime) object_freeze(call FunctionCall) Value { 282 arg := call.Argument(0) 283 if obj, ok := arg.(*Object); ok { 284 obj.self.preventExtensions(true) 285 286 for item, next := obj.self.iterateKeys()(); next != nil; item, next = next() { 287 if prop, ok := item.value.(*valueProperty); ok { 288 prop.configurable = false 289 if !prop.accessor { 290 prop.writable = false 291 } 292 } else { 293 prop := obj.getOwnProp(item.name) 294 descr := PropertyDescriptor{ 295 Configurable: FLAG_FALSE, 296 } 297 if prop, ok := prop.(*valueProperty); ok && prop.accessor { 298 // no-op 299 } else { 300 descr.Writable = FLAG_FALSE 301 } 302 obj.defineOwnProperty(item.name, descr, true) 303 } 304 } 305 return obj 306 } else { 307 // ES6 behavior 308 return arg 309 } 310 } 311 312 func (r *Runtime) object_preventExtensions(call FunctionCall) (ret Value) { 313 arg := call.Argument(0) 314 if obj, ok := arg.(*Object); ok { 315 obj.self.preventExtensions(true) 316 } 317 return arg 318 } 319 320 func (r *Runtime) object_isSealed(call FunctionCall) Value { 321 if obj, ok := call.Argument(0).(*Object); ok { 322 if obj.self.isExtensible() { 323 return valueFalse 324 } 325 for item, next := obj.self.iterateKeys()(); next != nil; item, next = next() { 326 var prop Value 327 if item.value == nil { 328 prop = obj.getOwnProp(item.name) 329 if prop == nil { 330 continue 331 } 332 } else { 333 prop = item.value 334 } 335 if prop, ok := prop.(*valueProperty); ok { 336 if prop.configurable { 337 return valueFalse 338 } 339 } else { 340 return valueFalse 341 } 342 } 343 } 344 return valueTrue 345 } 346 347 func (r *Runtime) object_isFrozen(call FunctionCall) Value { 348 if obj, ok := call.Argument(0).(*Object); ok { 349 if obj.self.isExtensible() { 350 return valueFalse 351 } 352 for item, next := obj.self.iterateKeys()(); next != nil; item, next = next() { 353 var prop Value 354 if item.value == nil { 355 prop = obj.getOwnProp(item.name) 356 if prop == nil { 357 continue 358 } 359 } else { 360 prop = item.value 361 } 362 if prop, ok := prop.(*valueProperty); ok { 363 if prop.configurable || prop.value != nil && prop.writable { 364 return valueFalse 365 } 366 } else { 367 return valueFalse 368 } 369 } 370 } 371 return valueTrue 372 } 373 374 func (r *Runtime) object_isExtensible(call FunctionCall) Value { 375 if obj, ok := call.Argument(0).(*Object); ok { 376 if obj.self.isExtensible() { 377 return valueTrue 378 } 379 return valueFalse 380 } else { 381 // ES6 382 //r.typeErrorResult(true, "Object.isExtensible called on non-object") 383 return valueFalse 384 } 385 } 386 387 func (r *Runtime) object_keys(call FunctionCall) Value { 388 obj := call.Argument(0).ToObject(r) 389 390 return r.newArrayValues(obj.self.stringKeys(false, nil)) 391 } 392 393 func (r *Runtime) object_entries(call FunctionCall) Value { 394 obj := call.Argument(0).ToObject(r) 395 396 var values []Value 397 398 for item, next := iterateEnumerableStringProperties(obj)(); next != nil; item, next = next() { 399 values = append(values, r.newArrayValues([]Value{item.name, item.value})) 400 } 401 402 return r.newArrayValues(values) 403 } 404 405 func (r *Runtime) object_values(call FunctionCall) Value { 406 obj := call.Argument(0).ToObject(r) 407 408 var values []Value 409 410 for item, next := iterateEnumerableStringProperties(obj)(); next != nil; item, next = next() { 411 values = append(values, item.value) 412 } 413 414 return r.newArrayValues(values) 415 } 416 417 func (r *Runtime) objectproto_hasOwnProperty(call FunctionCall) Value { 418 p := toPropertyKey(call.Argument(0)) 419 o := call.This.ToObject(r) 420 if o.hasOwnProperty(p) { 421 return valueTrue 422 } else { 423 return valueFalse 424 } 425 } 426 427 func (r *Runtime) objectproto_isPrototypeOf(call FunctionCall) Value { 428 if v, ok := call.Argument(0).(*Object); ok { 429 o := call.This.ToObject(r) 430 for { 431 v = v.self.proto() 432 if v == nil { 433 break 434 } 435 if v == o { 436 return valueTrue 437 } 438 } 439 } 440 return valueFalse 441 } 442 443 func (r *Runtime) objectproto_propertyIsEnumerable(call FunctionCall) Value { 444 p := toPropertyKey(call.Argument(0)) 445 o := call.This.ToObject(r) 446 pv := o.getOwnProp(p) 447 if pv == nil { 448 return valueFalse 449 } 450 if prop, ok := pv.(*valueProperty); ok { 451 if !prop.enumerable { 452 return valueFalse 453 } 454 } 455 return valueTrue 456 } 457 458 func (r *Runtime) objectproto_toString(call FunctionCall) Value { 459 switch o := call.This.(type) { 460 case valueNull: 461 return stringObjectNull 462 case valueUndefined: 463 return stringObjectUndefined 464 default: 465 obj := o.ToObject(r) 466 if o, ok := obj.self.(*objectGoReflect); ok { 467 if toString := o.toString; toString != nil { 468 return toString() 469 } 470 } 471 var clsName string 472 if isArray(obj) { 473 clsName = classArray 474 } else { 475 clsName = obj.self.className() 476 } 477 if tag := obj.self.getSym(SymToStringTag, nil); tag != nil { 478 if str, ok := tag.(String); ok { 479 clsName = str.String() 480 } 481 } 482 return newStringValue(fmt.Sprintf("[object %s]", clsName)) 483 } 484 } 485 486 func (r *Runtime) objectproto_toLocaleString(call FunctionCall) Value { 487 toString := toMethod(r.getVStr(call.This, "toString")) 488 return toString(FunctionCall{This: call.This}) 489 } 490 491 func (r *Runtime) objectproto_getProto(call FunctionCall) Value { 492 proto := call.This.ToObject(r).self.proto() 493 if proto != nil { 494 return proto 495 } 496 return _null 497 } 498 499 func (r *Runtime) setObjectProto(o, arg Value) { 500 r.checkObjectCoercible(o) 501 var proto *Object 502 if arg != _null { 503 if obj, ok := arg.(*Object); ok { 504 proto = obj 505 } else { 506 return 507 } 508 } 509 if o, ok := o.(*Object); ok { 510 o.self.setProto(proto, true) 511 } 512 } 513 514 func (r *Runtime) objectproto_setProto(call FunctionCall) Value { 515 r.setObjectProto(call.This, call.Argument(0)) 516 return _undefined 517 } 518 519 func (r *Runtime) objectproto_valueOf(call FunctionCall) Value { 520 return call.This.ToObject(r) 521 } 522 523 func (r *Runtime) object_assign(call FunctionCall) Value { 524 to := call.Argument(0).ToObject(r) 525 if len(call.Arguments) > 1 { 526 for _, arg := range call.Arguments[1:] { 527 if arg != _undefined && arg != _null { 528 source := arg.ToObject(r) 529 for item, next := iterateEnumerableProperties(source)(); next != nil; item, next = next() { 530 to.setOwn(item.name, item.value, true) 531 } 532 } 533 } 534 } 535 536 return to 537 } 538 539 func (r *Runtime) object_is(call FunctionCall) Value { 540 return r.toBoolean(call.Argument(0).SameAs(call.Argument(1))) 541 } 542 543 func (r *Runtime) toProto(proto Value) *Object { 544 if proto != _null { 545 if obj, ok := proto.(*Object); ok { 546 return obj 547 } else { 548 panic(r.NewTypeError("Object prototype may only be an Object or null: %s", proto)) 549 } 550 } 551 return nil 552 } 553 554 func (r *Runtime) object_setPrototypeOf(call FunctionCall) Value { 555 o := call.Argument(0) 556 r.checkObjectCoercible(o) 557 proto := r.toProto(call.Argument(1)) 558 if o, ok := o.(*Object); ok { 559 o.self.setProto(proto, true) 560 } 561 562 return o 563 } 564 565 func (r *Runtime) object_fromEntries(call FunctionCall) Value { 566 o := call.Argument(0) 567 r.checkObjectCoercible(o) 568 569 result := r.newBaseObject(r.global.ObjectPrototype, classObject).val 570 571 iter := r.getIterator(o, nil) 572 iter.iterate(func(nextValue Value) { 573 i0 := valueInt(0) 574 i1 := valueInt(1) 575 576 itemObj := r.toObject(nextValue) 577 k := itemObj.self.getIdx(i0, nil) 578 v := itemObj.self.getIdx(i1, nil) 579 key := toPropertyKey(k) 580 581 createDataPropertyOrThrow(result, key, v) 582 }) 583 584 return result 585 } 586 587 func (r *Runtime) object_hasOwn(call FunctionCall) Value { 588 o := call.Argument(0) 589 obj := o.ToObject(r) 590 p := toPropertyKey(call.Argument(1)) 591 592 if obj.hasOwnProperty(p) { 593 return valueTrue 594 } else { 595 return valueFalse 596 } 597 } 598 599 func createObjectTemplate() *objectTemplate { 600 t := newObjectTemplate() 601 t.protoFactory = func(r *Runtime) *Object { 602 return r.getFunctionPrototype() 603 } 604 605 t.putStr("length", func(r *Runtime) Value { return valueProp(intToValue(1), false, false, true) }) 606 t.putStr("name", func(r *Runtime) Value { return valueProp(asciiString("Object"), false, false, true) }) 607 608 t.putStr("prototype", func(r *Runtime) Value { return valueProp(r.global.ObjectPrototype, false, false, false) }) 609 610 t.putStr("assign", func(r *Runtime) Value { return r.methodProp(r.object_assign, "assign", 2) }) 611 t.putStr("defineProperty", func(r *Runtime) Value { return r.methodProp(r.object_defineProperty, "defineProperty", 3) }) 612 t.putStr("defineProperties", func(r *Runtime) Value { return r.methodProp(r.object_defineProperties, "defineProperties", 2) }) 613 t.putStr("entries", func(r *Runtime) Value { return r.methodProp(r.object_entries, "entries", 1) }) 614 t.putStr("getOwnPropertyDescriptor", func(r *Runtime) Value { 615 return r.methodProp(r.object_getOwnPropertyDescriptor, "getOwnPropertyDescriptor", 2) 616 }) 617 t.putStr("getOwnPropertyDescriptors", func(r *Runtime) Value { 618 return r.methodProp(r.object_getOwnPropertyDescriptors, "getOwnPropertyDescriptors", 1) 619 }) 620 t.putStr("getPrototypeOf", func(r *Runtime) Value { return r.methodProp(r.object_getPrototypeOf, "getPrototypeOf", 1) }) 621 t.putStr("is", func(r *Runtime) Value { return r.methodProp(r.object_is, "is", 2) }) 622 t.putStr("getOwnPropertyNames", func(r *Runtime) Value { return r.methodProp(r.object_getOwnPropertyNames, "getOwnPropertyNames", 1) }) 623 t.putStr("getOwnPropertySymbols", func(r *Runtime) Value { 624 return r.methodProp(r.object_getOwnPropertySymbols, "getOwnPropertySymbols", 1) 625 }) 626 t.putStr("create", func(r *Runtime) Value { return r.methodProp(r.object_create, "create", 2) }) 627 t.putStr("seal", func(r *Runtime) Value { return r.methodProp(r.object_seal, "seal", 1) }) 628 t.putStr("freeze", func(r *Runtime) Value { return r.methodProp(r.object_freeze, "freeze", 1) }) 629 t.putStr("preventExtensions", func(r *Runtime) Value { return r.methodProp(r.object_preventExtensions, "preventExtensions", 1) }) 630 t.putStr("isSealed", func(r *Runtime) Value { return r.methodProp(r.object_isSealed, "isSealed", 1) }) 631 t.putStr("isFrozen", func(r *Runtime) Value { return r.methodProp(r.object_isFrozen, "isFrozen", 1) }) 632 t.putStr("isExtensible", func(r *Runtime) Value { return r.methodProp(r.object_isExtensible, "isExtensible", 1) }) 633 t.putStr("keys", func(r *Runtime) Value { return r.methodProp(r.object_keys, "keys", 1) }) 634 t.putStr("setPrototypeOf", func(r *Runtime) Value { return r.methodProp(r.object_setPrototypeOf, "setPrototypeOf", 2) }) 635 t.putStr("values", func(r *Runtime) Value { return r.methodProp(r.object_values, "values", 1) }) 636 t.putStr("fromEntries", func(r *Runtime) Value { return r.methodProp(r.object_fromEntries, "fromEntries", 1) }) 637 t.putStr("hasOwn", func(r *Runtime) Value { return r.methodProp(r.object_hasOwn, "hasOwn", 2) }) 638 639 return t 640 } 641 642 var _objectTemplate *objectTemplate 643 var objectTemplateOnce sync.Once 644 645 func getObjectTemplate() *objectTemplate { 646 objectTemplateOnce.Do(func() { 647 _objectTemplate = createObjectTemplate() 648 }) 649 return _objectTemplate 650 } 651 652 func (r *Runtime) getObject() *Object { 653 ret := r.global.Object 654 if ret == nil { 655 ret = &Object{runtime: r} 656 r.global.Object = ret 657 r.newTemplatedFuncObject(getObjectTemplate(), ret, func(call FunctionCall) Value { 658 return r.builtin_Object(call.Arguments, nil) 659 }, r.builtin_Object) 660 } 661 return ret 662 } 663 664 /* 665 func (r *Runtime) getObjectPrototype() *Object { 666 ret := r.global.ObjectPrototype 667 if ret == nil { 668 ret = &Object{runtime: r} 669 r.global.ObjectPrototype = ret 670 r.newTemplatedObject(getObjectProtoTemplate(), ret) 671 } 672 return ret 673 } 674 */ 675 676 var objectProtoTemplate *objectTemplate 677 var objectProtoTemplateOnce sync.Once 678 679 func getObjectProtoTemplate() *objectTemplate { 680 objectProtoTemplateOnce.Do(func() { 681 objectProtoTemplate = createObjectProtoTemplate() 682 }) 683 return objectProtoTemplate 684 } 685 686 func createObjectProtoTemplate() *objectTemplate { 687 t := newObjectTemplate() 688 689 // null prototype 690 691 t.putStr("constructor", func(r *Runtime) Value { return valueProp(r.getObject(), true, false, true) }) 692 693 t.putStr("toString", func(r *Runtime) Value { return r.methodProp(r.objectproto_toString, "toString", 0) }) 694 t.putStr("toLocaleString", func(r *Runtime) Value { return r.methodProp(r.objectproto_toLocaleString, "toLocaleString", 0) }) 695 t.putStr("valueOf", func(r *Runtime) Value { return r.methodProp(r.objectproto_valueOf, "valueOf", 0) }) 696 t.putStr("hasOwnProperty", func(r *Runtime) Value { return r.methodProp(r.objectproto_hasOwnProperty, "hasOwnProperty", 1) }) 697 t.putStr("isPrototypeOf", func(r *Runtime) Value { return r.methodProp(r.objectproto_isPrototypeOf, "isPrototypeOf", 1) }) 698 t.putStr("propertyIsEnumerable", func(r *Runtime) Value { 699 return r.methodProp(r.objectproto_propertyIsEnumerable, "propertyIsEnumerable", 1) 700 }) 701 t.putStr(__proto__, func(r *Runtime) Value { 702 return &valueProperty{ 703 accessor: true, 704 getterFunc: r.newNativeFunc(r.objectproto_getProto, "get __proto__", 0), 705 setterFunc: r.newNativeFunc(r.objectproto_setProto, "set __proto__", 1), 706 configurable: true, 707 } 708 }) 709 710 return t 711 }