aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-14 23:07:45 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-15 18:21:10 +0000
commitcc8cb4b442fe28f1b601d6f1f27e8c59231007be (patch)
treefd5c2a0039691eace1e6af804578b7db0107817c
parent3fae4819d33d22039f01ce26e1549b5d0fcc96cf (diff)
Implement Symbol.species getter functions
Change-Id: I18b3e382e679f95d7cb53b4ed03be2513ea0204b Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp2
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp7
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4engine.cpp3
-rw-r--r--src/qml/jsruntime/qv4engine_p.h4
-rw-r--r--src/qml/jsruntime/qv4object.cpp10
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp1
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp2
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations12
10 files changed, 35 insertions, 12 deletions
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index 95dd5444c3..e841295fe2 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -151,6 +151,8 @@ void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor)
ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(1));
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
ctor->defineDefaultProperty(QStringLiteral("isView"), ArrayBufferCtor::method_isView, 1);
+ ctor->addSymbolSpecies();
+
defineDefaultProperty(engine->id_constructor(), (o = ctor));
defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, nullptr);
defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 71ffc29fca..87d4c33917 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -94,6 +94,8 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(1));
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
ctor->defineDefaultProperty(QStringLiteral("isArray"), method_isArray, 1);
+ ctor->addSymbolSpecies();
+
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
defineDefaultProperty(engine->id_toString(), method_toString, 0);
defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString, 0);
@@ -1103,3 +1105,8 @@ ReturnedValue ArrayPrototype::method_values(const FunctionObject *b, const Value
return ao->asReturnedValue();
}
+ReturnedValue ArrayPrototype::method_get_species(const FunctionObject *, const Value *thisObject, const Value *, int)
+{
+ return thisObject->asReturnedValue();
+}
+
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index 9416176863..31067b0c39 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -105,6 +105,10 @@ struct ArrayPrototype: ArrayObject
static ReturnedValue method_reduce(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_reduceRight(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_values(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+
+ // while this function is implemented here, it's the same for many other JS classes, so the corresponding JS function
+ // is instantiated in the engine, and it can be added to any JS object through Object::addSymbolSpecies()
+ static ReturnedValue method_get_species(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 96855b6155..6edf7ddf37 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -422,6 +422,9 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
jsObjects[ArrayIteratorProto] = memoryManager->allocObject<ArrayIteratorPrototype>(newInternalClass(ArrayIteratorPrototype::staticVTable(), iteratorPrototype()));
jsObjects[StringIteratorProto] = memoryManager->allocObject<StringIteratorPrototype>(newInternalClass(StringIteratorPrototype::staticVTable(), iteratorPrototype()));
+ str = newString(QStringLiteral("get [Symbol.species]"));
+ jsObjects[GetSymbolSpecies] = FunctionObject::createBuiltinFunction(this, str, ArrayPrototype::method_get_species, 0);
+
static_cast<ObjectPrototype *>(objectPrototype())->init(this, objectCtor());
static_cast<StringPrototype *>(stringPrototype())->init(this, stringCtor());
static_cast<SymbolPrototype *>(symbolPrototype())->init(this, symbolCtor());
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index e90be8e896..99594cc81a 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -215,6 +215,8 @@ public:
ArrayBuffer_Ctor,
DataView_Ctor,
+ GetSymbolSpecies,
+
Eval_Function,
GetStack_Function,
ThrowerObject,
@@ -247,6 +249,8 @@ public:
FunctionObject *dataViewCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + DataView_Ctor); }
FunctionObject *typedArrayCtors;
+ FunctionObject *getSymbolSpecies() const { return reinterpret_cast<FunctionObject *>(jsObjects + GetSymbolSpecies); }
+
Object *objectPrototype() const { return reinterpret_cast<Object *>(jsObjects + ObjectProto); }
Object *symbolPrototype() const { return reinterpret_cast<Object *>(jsObjects + SymbolProto); }
Object *arrayPrototype() const { return reinterpret_cast<Object *>(jsObjects + ArrayProto); }
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 586fa1ee4b..cf988f093a 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -50,6 +50,7 @@
#include "qv4string_p.h"
#include "qv4identifiertable_p.h"
#include "qv4jscall_p.h"
+#include "qv4symbol_p.h"
#include <stdint.h>
@@ -221,6 +222,15 @@ void Object::defineReadonlyConfigurableProperty(StringOrSymbol *name, const Valu
insertMember(name, value, Attr_ReadOnly_ButConfigurable);
}
+void Object::addSymbolSpecies()
+{
+ Scope scope(engine());
+ ScopedProperty p(scope);
+ p->setGetter(scope.engine->getSymbolSpecies());
+ p->setSetter(nullptr);
+ insertMember(scope.engine->symbol_species(), p, QV4::Attr_Accessor|QV4::Attr_NotWritable|QV4::Attr_NotEnumerable);
+}
+
void Heap::Object::markObjects(Heap::Base *b, MarkStack *stack)
{
Base::markObjects(b, stack);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index b5aac35722..7cc99376be 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -292,6 +292,8 @@ struct Q_QML_EXPORT Object: Managed {
void defineReadonlyConfigurableProperty(const QString &name, const Value &value);
void defineReadonlyConfigurableProperty(StringOrSymbol *name, const Value &value);
+ void addSymbolSpecies();
+
void insertMember(StringOrSymbol *s, const Value &v, PropertyAttributes attributes = Attr_Data) {
Scope scope(engine());
ScopedProperty p(scope);
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 0b1979dfcc..52dd4a5a57 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -277,6 +277,7 @@ void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(2));
+ ctor->addSymbolSpecies();
// Properties deprecated in the spec but required by "the web" :(
ctor->defineAccessorProperty(QStringLiteral("lastMatch"), method_get_lastMatch_n<0>, nullptr);
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index ea83f4940b..36ab5b219f 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -407,6 +407,8 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(3));
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
ctor->defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement));
+ ctor->addSymbolSpecies();
+
defineDefaultProperty(engine->id_constructor(), (o = ctor));
defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, nullptr);
defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, nullptr);
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 6b426a4420..cd4b227c2d 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -20,10 +20,6 @@ language/statements/with/let-identifier-with-newline.js sloppyFails
# ----- test failures that should be fixed
-built-ins/Array/Symbol.species/length.js fails
-built-ins/Array/Symbol.species/return-value.js fails
-built-ins/Array/Symbol.species/symbol-species-name.js fails
-built-ins/Array/Symbol.species/symbol-species.js fails
built-ins/Array/from/Array.from-descriptor.js fails
built-ins/Array/from/Array.from-name.js fails
built-ins/Array/from/Array.from_arity.js fails
@@ -251,10 +247,6 @@ built-ins/Array/prototype/toLocaleString/primitive_this_value_getter.js strictFa
built-ins/Array/prototype/unshift/clamps-to-integer-limit.js fails
built-ins/Array/prototype/unshift/length-near-integer-limit.js fails
built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js fails
-built-ins/ArrayBuffer/Symbol.species/length.js fails
-built-ins/ArrayBuffer/Symbol.species/return-value.js fails
-built-ins/ArrayBuffer/Symbol.species/symbol-species-name.js fails
-built-ins/ArrayBuffer/Symbol.species/symbol-species.js fails
built-ins/ArrayBuffer/data-allocation-after-object-creation.js fails
built-ins/ArrayBuffer/isView/arg-is-dataview-subclass-instance.js fails
built-ins/ArrayBuffer/isView/arg-is-typedarray-subclass-instance.js fails
@@ -1591,10 +1583,6 @@ built-ins/RegExp/S15.10.3.1_A2_T1.js fails
built-ins/RegExp/S15.10.3.1_A2_T2.js fails
built-ins/RegExp/S15.10.4.1_A2_T1.js fails
built-ins/RegExp/S15.10.4.1_A2_T2.js fails
-built-ins/RegExp/Symbol.species/length.js fails
-built-ins/RegExp/Symbol.species/return-value.js fails
-built-ins/RegExp/Symbol.species/symbol-species-name.js fails
-built-ins/RegExp/Symbol.species/symbol-species.js fails
built-ins/RegExp/call_with_non_regexp_same_constructor.js fails
built-ins/RegExp/call_with_regexp_match_falsy.js fails
built-ins/RegExp/call_with_regexp_not_same_constructor.js fails