From 41690ac8530095f5ed693ccdd8f8e683010eeac6 Mon Sep 17 00:00:00 2001 From: shiroyk Date: Tue, 6 Aug 2024 21:46:34 +0800 Subject: [PATCH] Fix Array.prototype.toSpliced --- builtin_array.go | 21 +++++++++------------ builtin_arrray_test.go | 24 +++++++++++++++++++++++- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/builtin_array.go b/builtin_array.go index 0993a16..0ebcdff 100644 --- a/builtin_array.go +++ b/builtin_array.go @@ -1338,11 +1338,9 @@ func (r *Runtime) arrayproto_toSpliced(call FunctionCall) Value { length := toLength(o.self.getStr("length", nil)) actualStart := relToIdx(call.Argument(0).ToInteger(), length) var actualSkipCount int64 - switch len(call.Arguments) { - case 0: - case 1: + if len(call.Arguments) == 1 { actualSkipCount = length - actualStart - default: + } else if len(call.Arguments) > 1 { actualSkipCount = min(max(call.Argument(1).ToInteger(), 0), length-actualStart) } itemCount := max(int64(len(call.Arguments)-2), 0) @@ -1354,24 +1352,23 @@ func (r *Runtime) arrayproto_toSpliced(call FunctionCall) Value { if src := r.checkStdArrayObj(o); src != nil { var values []Value if itemCount < actualSkipCount { - values = src.values + values = make([]Value, len(src.values)) + copy(values, src.values) copy(values[actualStart+itemCount:], values[actualStart+actualSkipCount:]) - tail := values[newLength:] - for k := range tail { - tail[k] = nil - } values = values[:newLength] } else if itemCount > actualSkipCount { if int64(cap(src.values)) >= newLength { - values = src.values[:newLength] - copy(values[actualStart+itemCount:], values[actualStart+actualSkipCount:length]) + values = make([]Value, newLength) + copy(values, src.values[:actualStart]) + copy(values[actualStart+itemCount:], src.values[actualStart+actualSkipCount:]) } else { values = make([]Value, newLength) copy(values, src.values[:actualStart]) copy(values[actualStart+itemCount:], src.values[actualStart+actualSkipCount:]) } } else { - values = src.values + values = make([]Value, len(src.values)) + copy(values, src.values) } if itemCount > 0 { copy(values[actualStart:], call.Arguments[2:]) diff --git a/builtin_arrray_test.go b/builtin_arrray_test.go index 8418a95..3600347 100644 --- a/builtin_arrray_test.go +++ b/builtin_arrray_test.go @@ -1,6 +1,8 @@ package sobek -import "testing" +import ( + "testing" +) func TestArrayProtoProp(t *testing.T) { const SCRIPT = ` @@ -339,3 +341,23 @@ func TestArrayProto(t *testing.T) { ` testScriptWithTestLib(SCRIPT, _undefined, t) } + +func TestArrayToSpliced(t *testing.T) { + const SCRIPT = ` + const a = [1, 2, 3]; + a.push(4) + assert(compareArray(a, [1, 2, 3, 4])); + const b = a.toSpliced(2) + assert(compareArray(a, [1, 2, 3, 4])); + assert(compareArray(b, [1, 2])); + a.push(5) + const c = a.toSpliced(1, 2); + assert(compareArray(a, [1, 2, 3, 4, 5])); + assert(compareArray(c, [1, 4, 5])); + assert(compareArray(a.toSpliced(4, 2, 'a', 'b'), [1, 2, 3, 4, 'a', 'b'])); + assert(compareArray(a.toSpliced(-2, 2), [1, 2, 3])); + assert(compareArray(a.toSpliced(2, 10), [1, 2])); + assert(compareArray(a.toSpliced(1, 0, 'a'), [1, 'a', 2, 3, 4, 5])); + ` + testScriptWithTestLib(SCRIPT, _undefined, t) +}