...
1 package goja
2
3 import (
4 "math"
5 "math/bits"
6 "reflect"
7
8 "github.com/dop251/goja/unistring"
9 )
10
11 type objectGoSliceReflect struct {
12 objectGoArrayReflect
13 }
14
15 func (o *objectGoSliceReflect) init() {
16 o.objectGoArrayReflect._init()
17 o.lengthProp.writable = true
18 o.putIdx = o._putIdx
19 }
20
21 func (o *objectGoSliceReflect) _putIdx(idx int, v Value, throw bool) bool {
22 if idx >= o.fieldsValue.Len() {
23 o.grow(idx + 1)
24 }
25 return o.objectGoArrayReflect._putIdx(idx, v, throw)
26 }
27
28 func (o *objectGoSliceReflect) grow(size int) {
29 oldcap := o.fieldsValue.Cap()
30 if oldcap < size {
31 n := reflect.MakeSlice(o.fieldsValue.Type(), size, growCap(size, o.fieldsValue.Len(), oldcap))
32 reflect.Copy(n, o.fieldsValue)
33 o.fieldsValue.Set(n)
34 l := len(o.valueCache)
35 if l > size {
36 l = size
37 }
38 for i, w := range o.valueCache[:l] {
39 if w != nil {
40 w.setReflectValue(o.fieldsValue.Index(i))
41 }
42 }
43 } else {
44 tail := o.fieldsValue.Slice(o.fieldsValue.Len(), size)
45 zero := reflect.Zero(o.fieldsValue.Type().Elem())
46 for i := 0; i < tail.Len(); i++ {
47 tail.Index(i).Set(zero)
48 }
49 o.fieldsValue.SetLen(size)
50 }
51 }
52
53 func (o *objectGoSliceReflect) shrink(size int) {
54 o.valueCache.shrink(size)
55 tail := o.fieldsValue.Slice(size, o.fieldsValue.Len())
56 zero := reflect.Zero(o.fieldsValue.Type().Elem())
57 for i := 0; i < tail.Len(); i++ {
58 tail.Index(i).Set(zero)
59 }
60 o.fieldsValue.SetLen(size)
61 }
62
63 func (o *objectGoSliceReflect) putLength(v uint32, throw bool) bool {
64 if bits.UintSize == 32 && v > math.MaxInt32 {
65 panic(rangeError("Integer value overflows 32-bit int"))
66 }
67 newLen := int(v)
68 curLen := o.fieldsValue.Len()
69 if newLen > curLen {
70 o.grow(newLen)
71 } else if newLen < curLen {
72 o.shrink(newLen)
73 }
74 return true
75 }
76
77 func (o *objectGoSliceReflect) setOwnStr(name unistring.String, val Value, throw bool) bool {
78 if name == "length" {
79 return o.putLength(o.val.runtime.toLengthUint32(val), throw)
80 }
81 return o.objectGoArrayReflect.setOwnStr(name, val, throw)
82 }
83
84 func (o *objectGoSliceReflect) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool {
85 if name == "length" {
86 return o.val.runtime.defineArrayLength(&o.lengthProp, descr, o.putLength, throw)
87 }
88 return o.objectGoArrayReflect.defineOwnPropertyStr(name, descr, throw)
89 }
90
View as plain text