1 package goja
2
3 import (
4 "fmt"
5 "math"
6 "reflect"
7 "sort"
8
9 "github.com/dop251/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
481 if res, handled := proto.self.setForeignStr(name, val, o.val, throw); handled {
482 return res
483 }
484 }
485
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
521 if res, handled := proto.self.setForeignSym(name, val, o.val, throw); handled {
522 return res
523 }
524 }
525
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 (%T) to primitive", o.self, 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, _ int) {
920 panic(vm.r.NewTypeError("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
1032
1033 var values []Value
1034
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
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
1197
1198
1199
1200
1201
1202
1203
1204
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
1309 return false
1310 }
1311
1312
1313 func (o *baseObject) ensurePropOrder() {
1314 if o.lastSortedPropLen < len(o.propNames) {
1315 o.fixPropOrder()
1316 }
1317 }
1318
1319
1320
1321
1322
1323
1324
1325
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 }
1825
View as plain text