Skip to content

Commit

Permalink
Array.prototype.filter() and find()
Browse files Browse the repository at this point in the history
  • Loading branch information
dop251 committed Mar 9, 2020
1 parent 5a4756e commit 3274eaa
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 38 deletions.
77 changes: 60 additions & 17 deletions builtin_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,24 +261,28 @@ func (r *Runtime) arrayproto_concat_append(a *Object, item Value) {
a.self.putStr("length", intToValue(aLength), true)
}

func arraySpeciesCreate(obj *Object, size int) *Object {
func arraySpeciesCreate(obj *Object, size int64) *Object {
if isArray(obj) {
v := obj.self.getStr("constructor")
if constructObj, ok := v.(*Object); ok {
species := constructObj.self.get(symSpecies)
if species != nil && !IsUndefined(species) && !IsNull(species) {
constructObj, _ = species.(*Object)
if constructObj != nil {
constructor := getConstructor(constructObj)
if constructor != nil {
return constructor([]Value{intToValue(int64(size))})
}
v = constructObj.self.get(symSpecies)
if v == _null {
v = nil
}
}

if v != nil && v != _undefined {
constructObj, _ := v.(*Object)
if constructObj != nil {
constructor := getConstructor(constructObj)
if constructor != nil {
return constructor([]Value{intToValue(size)})
}
panic(obj.runtime.NewTypeError())
}
panic(obj.runtime.NewTypeError("Species is not a constructor"))
}
}
return obj.runtime.newArrayValues(nil)
return obj.runtime.newArrayLength(size)
}

func (r *Runtime) arrayproto_concat(call FunctionCall) Value {
Expand Down Expand Up @@ -624,24 +628,42 @@ func (r *Runtime) arrayproto_filter(call FunctionCall) Value {
length := toLength(o.self.getStr("length"))
callbackFn := call.Argument(0).ToObject(r)
if callbackFn, ok := callbackFn.self.assertCallable(); ok {
a := r.newArrayObject()
a := arraySpeciesCreate(o, 0)
fc := FunctionCall{
This: call.Argument(1),
Arguments: []Value{nil, nil, o},
}
if _, stdSrc := o.self.(*arrayObject); stdSrc {
if arr := r.checkStdArrayObj(a); arr != nil {
var values []Value
for k := int64(0); k < length; k++ {
idx := intToValue(k)
if val := o.self.get(idx); val != nil {
fc.Arguments[0] = val
fc.Arguments[1] = idx
if callbackFn(fc).ToBoolean() {
values = append(values, val)
}
}
}
setArrayValues(arr, values)
return a
}
}

to := int64(0)
for k := int64(0); k < length; k++ {
idx := intToValue(k)
if val := o.self.get(idx); val != nil {
fc.Arguments[0] = val
fc.Arguments[1] = idx
if callbackFn(fc).ToBoolean() {
a.values = append(a.values, val)
defineDataPropertyOrThrow(a, intToValue(to), val)
to++
}
}
}
a.length = int64(len(a.values))
a.objCount = a.length
return a.val
return a
} else {
r.typeErrorResult(true, "%s is not a function", call.Argument(0))
}
Expand Down Expand Up @@ -896,6 +918,26 @@ func (r *Runtime) arrayproto_fill(call FunctionCall) Value {
return o
}

func (r *Runtime) arrayproto_find(call FunctionCall) Value {
o := call.This.ToObject(r)
l := toLength(o.self.getStr("length"))
predicate := r.toCallable(call.Argument(0))
fc := FunctionCall{
This: call.Argument(1),
Arguments: []Value{nil, nil, o},
}
for k := int64(0); k < l; k++ {
idx := intToValue(k)
kValue := o.self.get(idx)
fc.Arguments[0], fc.Arguments[1] = kValue, idx
if predicate(fc).ToBoolean() {
return kValue
}
}

return _undefined
}

func (r *Runtime) checkStdArrayObj(obj *Object) *arrayObject {
if arr, ok := obj.self.(*arrayObject); ok &&
arr.propValueCount == 0 &&
Expand Down Expand Up @@ -1072,6 +1114,8 @@ func (r *Runtime) createArrayProto(val *Object) objectImpl {
o._putProp("copyWithin", r.newNativeFunc(r.arrayproto_copyWithin, nil, "copyWithin", nil, 2), true, false, true)
o._putProp("entries", r.newNativeFunc(r.arrayproto_entries, nil, "entries", nil, 0), true, false, true)
o._putProp("fill", r.newNativeFunc(r.arrayproto_fill, nil, "fill", nil, 1), true, false, true)
o._putProp("filter", r.newNativeFunc(r.arrayproto_filter, nil, "filter", nil, 1), true, false, true)
o._putProp("find", r.newNativeFunc(r.arrayproto_find, nil, "find", nil, 1), true, false, true)
o._putProp("pop", r.newNativeFunc(r.arrayproto_pop, nil, "pop", nil, 0), true, false, true)
o._putProp("push", r.newNativeFunc(r.arrayproto_push, nil, "push", nil, 1), true, false, true)
o._putProp("join", r.newNativeFunc(r.arrayproto_join, nil, "join", nil, 1), true, false, true)
Expand All @@ -1090,7 +1134,6 @@ func (r *Runtime) createArrayProto(val *Object) objectImpl {
o._putProp("some", r.newNativeFunc(r.arrayproto_some, nil, "some", nil, 1), true, false, true)
o._putProp("forEach", r.newNativeFunc(r.arrayproto_forEach, nil, "forEach", nil, 1), true, false, true)
o._putProp("map", r.newNativeFunc(r.arrayproto_map, nil, "map", nil, 1), true, false, true)
o._putProp("filter", r.newNativeFunc(r.arrayproto_filter, nil, "filter", nil, 1), true, false, true)
o._putProp("reduce", r.newNativeFunc(r.arrayproto_reduce, nil, "reduce", nil, 1), true, false, true)
o._putProp("reduceRight", r.newNativeFunc(r.arrayproto_reduceRight, nil, "reduceRight", nil, 1), true, false, true)
valuesFunc := r.newNativeFunc(r.arrayproto_values, nil, "values", nil, 0)
Expand Down
49 changes: 28 additions & 21 deletions tc39_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,30 @@ var (
"test/annexB/built-ins/escape/escape-above-astral.js": true, // \u{xxxxx}

// cross-realm
"test/built-ins/Symbol/unscopables/cross-realm.js": true,
"test/built-ins/Symbol/toStringTag/cross-realm.js": true,
"test/built-ins/Symbol/toPrimitive/cross-realm.js": true,
"test/built-ins/Symbol/split/cross-realm.js": true,
"test/built-ins/Symbol/species/cross-realm.js": true,
"test/built-ins/Symbol/search/cross-realm.js": true,
"test/built-ins/Symbol/replace/cross-realm.js": true,
"test/built-ins/Symbol/match/cross-realm.js": true,
"test/built-ins/Symbol/keyFor/cross-realm.js": true,
"test/built-ins/Symbol/iterator/cross-realm.js": true,
"test/built-ins/Symbol/isConcatSpreadable/cross-realm.js": true,
"test/built-ins/Symbol/hasInstance/cross-realm.js": true,
"test/built-ins/Symbol/for/cross-realm.js": true,
"test/built-ins/WeakSet/proto-from-ctor-realm.js": true,
"test/built-ins/WeakMap/proto-from-ctor-realm.js": true,
"test/built-ins/Map/proto-from-ctor-realm.js": true,
"test/built-ins/Set/proto-from-ctor-realm.js": true,
"test/built-ins/Object/proto-from-ctor.js": true,
"test/built-ins/Array/from/proto-from-ctor-realm.js": true,
"test/built-ins/Array/of/proto-from-ctor-realm.js": true,
"test/built-ins/Symbol/unscopables/cross-realm.js": true,
"test/built-ins/Symbol/toStringTag/cross-realm.js": true,
"test/built-ins/Symbol/toPrimitive/cross-realm.js": true,
"test/built-ins/Symbol/split/cross-realm.js": true,
"test/built-ins/Symbol/species/cross-realm.js": true,
"test/built-ins/Symbol/search/cross-realm.js": true,
"test/built-ins/Symbol/replace/cross-realm.js": true,
"test/built-ins/Symbol/match/cross-realm.js": true,
"test/built-ins/Symbol/keyFor/cross-realm.js": true,
"test/built-ins/Symbol/iterator/cross-realm.js": true,
"test/built-ins/Symbol/isConcatSpreadable/cross-realm.js": true,
"test/built-ins/Symbol/hasInstance/cross-realm.js": true,
"test/built-ins/Symbol/for/cross-realm.js": true,
"test/built-ins/WeakSet/proto-from-ctor-realm.js": true,
"test/built-ins/WeakMap/proto-from-ctor-realm.js": true,
"test/built-ins/Map/proto-from-ctor-realm.js": true,
"test/built-ins/Set/proto-from-ctor-realm.js": true,
"test/built-ins/Object/proto-from-ctor.js": true,
"test/built-ins/Array/from/proto-from-ctor-realm.js": true,
"test/built-ins/Array/of/proto-from-ctor-realm.js": true,
"test/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-non-array.js": true,
"test/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-array.js": true,
"test/built-ins/Array/prototype/filter/create-proto-from-ctor-realm-non-array.js": true,
"test/built-ins/Array/prototype/filter/create-proto-from-ctor-realm-array.js": true,

// class
"test/language/statements/class/subclass/builtin-objects/Symbol/symbol-valid-as-extends-value.js": true,
Expand Down Expand Up @@ -104,10 +108,13 @@ var (
"22.1.2.1",
"22.1.2.3",
"22.1.2.5",
//"22.1.3.1",
"22.1.3.1",
"22.1.3.3",
"22.1.3.4",
"22.1.3.5",
"22.1.3.6",
"22.1.3.7",
"22.1.3.8",
"22.1.3.29",
"23.1",
"23.2",
Expand Down

0 comments on commit 3274eaa

Please sign in to comment.