|
@@ -144,8 +144,8 @@ func (r *Runtime) arrayproto_pop(call FunctionCall) Value {
|
|
obj := call.This.ToObject(r)
|
|
obj := call.This.ToObject(r)
|
|
if a, ok := obj.self.(*arrayObject); ok {
|
|
if a, ok := obj.self.(*arrayObject); ok {
|
|
l := a.length
|
|
l := a.length
|
|
|
|
+ var val Value
|
|
if l > 0 {
|
|
if l > 0 {
|
|
- var val Value
|
|
|
|
l--
|
|
l--
|
|
if l < uint32(len(a.values)) {
|
|
if l < uint32(len(a.values)) {
|
|
val = a.values[l]
|
|
val = a.values[l]
|
|
@@ -161,10 +161,15 @@ func (r *Runtime) arrayproto_pop(call FunctionCall) Value {
|
|
//a._setLengthInt(l, false)
|
|
//a._setLengthInt(l, false)
|
|
a.values[l] = nil
|
|
a.values[l] = nil
|
|
a.values = a.values[:l]
|
|
a.values = a.values[:l]
|
|
|
|
+ } else {
|
|
|
|
+ val = _undefined
|
|
|
|
+ }
|
|
|
|
+ if a.lengthProp.writable {
|
|
a.length = l
|
|
a.length = l
|
|
- return val
|
|
|
|
|
|
+ } else {
|
|
|
|
+ a.setLength(0, true) // will throw
|
|
}
|
|
}
|
|
- return _undefined
|
|
|
|
|
|
+ return val
|
|
} else {
|
|
} else {
|
|
return r.arrayproto_pop_generic(obj)
|
|
return r.arrayproto_pop_generic(obj)
|
|
}
|
|
}
|
|
@@ -313,7 +318,7 @@ func (r *Runtime) arrayproto_slice(call FunctionCall) Value {
|
|
|
|
|
|
a := arraySpeciesCreate(o, count)
|
|
a := arraySpeciesCreate(o, count)
|
|
if src := r.checkStdArrayObj(o); src != nil {
|
|
if src := r.checkStdArrayObj(o); src != nil {
|
|
- if dst, ok := a.self.(*arrayObject); ok {
|
|
|
|
|
|
+ if dst := r.checkStdArrayObjWithProto(a); dst != nil {
|
|
values := make([]Value, count)
|
|
values := make([]Value, count)
|
|
copy(values, src.values[start:])
|
|
copy(values, src.values[start:])
|
|
setArrayValues(dst, values)
|
|
setArrayValues(dst, values)
|
|
@@ -396,7 +401,7 @@ func (r *Runtime) arrayproto_splice(call FunctionCall) Value {
|
|
itemCount := max(int64(len(call.Arguments)-2), 0)
|
|
itemCount := max(int64(len(call.Arguments)-2), 0)
|
|
newLength := length - actualDeleteCount + itemCount
|
|
newLength := length - actualDeleteCount + itemCount
|
|
if src := r.checkStdArrayObj(o); src != nil {
|
|
if src := r.checkStdArrayObj(o); src != nil {
|
|
- if dst, ok := a.self.(*arrayObject); ok {
|
|
|
|
|
|
+ if dst := r.checkStdArrayObjWithProto(a); dst != nil {
|
|
values := make([]Value, actualDeleteCount)
|
|
values := make([]Value, actualDeleteCount)
|
|
copy(values, src.values[actualStart:])
|
|
copy(values, src.values[actualStart:])
|
|
setArrayValues(dst, values)
|
|
setArrayValues(dst, values)
|
|
@@ -484,7 +489,7 @@ func (r *Runtime) arrayproto_unshift(call FunctionCall) Value {
|
|
argCount := int64(len(call.Arguments))
|
|
argCount := int64(len(call.Arguments))
|
|
newLen := intToValue(length + argCount)
|
|
newLen := intToValue(length + argCount)
|
|
newSize := length + argCount
|
|
newSize := length + argCount
|
|
- if arr := r.checkStdArrayObj(o); arr != nil && newSize < math.MaxUint32 {
|
|
|
|
|
|
+ if arr := r.checkStdArrayObjWithProto(o); arr != nil && newSize < math.MaxUint32 {
|
|
if int64(cap(arr.values)) >= newSize {
|
|
if int64(cap(arr.values)) >= newSize {
|
|
arr.values = arr.values[:newSize]
|
|
arr.values = arr.values[:newSize]
|
|
copy(arr.values[argCount:], arr.values[:length])
|
|
copy(arr.values[argCount:], arr.values[:length])
|
|
@@ -917,8 +922,11 @@ func (r *Runtime) arrayproto_reverse(call FunctionCall) Value {
|
|
|
|
|
|
func (r *Runtime) arrayproto_shift(call FunctionCall) Value {
|
|
func (r *Runtime) arrayproto_shift(call FunctionCall) Value {
|
|
o := call.This.ToObject(r)
|
|
o := call.This.ToObject(r)
|
|
- if a := r.checkStdArrayObj(o); a != nil {
|
|
|
|
|
|
+ if a := r.checkStdArrayObjWithProto(o); a != nil {
|
|
if len(a.values) == 0 {
|
|
if len(a.values) == 0 {
|
|
|
|
+ if !a.lengthProp.writable {
|
|
|
|
+ a.setLength(0, true) // will throw
|
|
|
|
+ }
|
|
return _undefined
|
|
return _undefined
|
|
}
|
|
}
|
|
first := a.values[0]
|
|
first := a.values[0]
|
|
@@ -1138,6 +1146,20 @@ func (r *Runtime) checkStdArrayObj(obj *Object) *arrayObject {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (r *Runtime) checkStdArrayObjWithProto(obj *Object) *arrayObject {
|
|
|
|
+ if arr := r.checkStdArrayObj(obj); arr != nil {
|
|
|
|
+ if p1, ok := arr.prototype.self.(*arrayObject); ok && p1.propValueCount == 0 {
|
|
|
|
+ if p2, ok := p1.prototype.self.(*baseObject); ok && p2.prototype == nil {
|
|
|
|
+ p2.ensurePropOrder()
|
|
|
|
+ if p2.idxPropCount == 0 {
|
|
|
|
+ return arr
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
func (r *Runtime) checkStdArray(v Value) *arrayObject {
|
|
func (r *Runtime) checkStdArray(v Value) *arrayObject {
|
|
if obj, ok := v.(*Object); ok {
|
|
if obj, ok := v.(*Object); ok {
|
|
return r.checkStdArrayObj(obj)
|
|
return r.checkStdArrayObj(obj)
|
|
@@ -1195,7 +1217,7 @@ func (r *Runtime) array_from(call FunctionCall) Value {
|
|
}
|
|
}
|
|
iter := r.getIterator(items, usingIterator)
|
|
iter := r.getIterator(items, usingIterator)
|
|
if mapFn == nil {
|
|
if mapFn == nil {
|
|
- if a := r.checkStdArrayObj(arr); a != nil {
|
|
|
|
|
|
+ if a := r.checkStdArrayObjWithProto(arr); a != nil {
|
|
var values []Value
|
|
var values []Value
|
|
iter.iterate(func(val Value) {
|
|
iter.iterate(func(val Value) {
|
|
values = append(values, val)
|
|
values = append(values, val)
|
|
@@ -1222,7 +1244,7 @@ func (r *Runtime) array_from(call FunctionCall) Value {
|
|
arr = r.newArrayValues(nil)
|
|
arr = r.newArrayValues(nil)
|
|
}
|
|
}
|
|
if mapFn == nil {
|
|
if mapFn == nil {
|
|
- if a := r.checkStdArrayObj(arr); a != nil {
|
|
|
|
|
|
+ if a := r.checkStdArrayObjWithProto(arr); a != nil {
|
|
values := make([]Value, l)
|
|
values := make([]Value, l)
|
|
for k := int64(0); k < l; k++ {
|
|
for k := int64(0); k < l; k++ {
|
|
values[k] = nilSafe(arrayLike.self.getIdx(valueInt(k), nil))
|
|
values[k] = nilSafe(arrayLike.self.getIdx(valueInt(k), nil))
|
|
@@ -1344,6 +1366,8 @@ func (r *Runtime) createArrayProto(val *Object) objectImpl {
|
|
bl.setOwnStr("includes", valueTrue, true)
|
|
bl.setOwnStr("includes", valueTrue, true)
|
|
bl.setOwnStr("keys", valueTrue, true)
|
|
bl.setOwnStr("keys", valueTrue, true)
|
|
bl.setOwnStr("values", valueTrue, true)
|
|
bl.setOwnStr("values", valueTrue, true)
|
|
|
|
+ bl.setOwnStr("groupBy", valueTrue, true)
|
|
|
|
+ bl.setOwnStr("groupByToMap", valueTrue, true)
|
|
o._putSym(SymUnscopables, valueProp(bl.val, false, false, true))
|
|
o._putSym(SymUnscopables, valueProp(bl.val, false, false, true))
|
|
|
|
|
|
return o
|
|
return o
|