Commit Graph

457 Commits

Author SHA1 Message Date
Lars Knoll a1964f0b8e Cleanup RegExpObject
Move properties from RegExpObject to getters in RegExp.prototype
to be compliant with the JS spec.

Implement support for the sticky flags ('y') and correctly parse
the flags in the RegExp constructor.

Change-Id: I5cf05d14e8139cf30d46235b8d466fb96084fcb7
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-08-15 14:24:23 +00:00
Simon Hausmann 8bebd12c1b Improve error handling for non-existent file imports
Change-Id: Ic043d30738c97836cf6afada6ee7cade23bf50f9
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2018-08-14 17:45:41 +00:00
Lars Knoll 886d463061 Enable unicode regular expressions
Add support for the 'u' flag for regular expressions.

Change-Id: I409054eaa9c50183619752d14f2638f5a38c0ea7
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-08-10 14:16:12 +00:00
Simon Hausmann 82da798499 Add initial basic support for ES6 modules
The entry point from the parsing perspective into modules is not
QV4::Script but QV4::ExecutionEngine::compileModule.

For convenience, the ESModule AST node gets a body, which is the
statement list connected between the ModuleItemList items that are not
import/export declarations.

The QV4::Module allocates a call context where the exported variables
are stored as named locals. This will also become the module namespace
object.

The imports in turn is an array of value pointers that point into the
locals array of the context of the imported modules.

The default module loading in ExecutionEngine assumes the accessibility
of module urls via QFile (so local file system or resource). This is
what qmljs also uses and QJSEngine as well via public API in the future.

The test runner compiles the modules manually and injects them, because
they need to be compiled together with the test harness code.

The QML type loader will the mechanism for injection in the future for
module imports from .qml files.

Change-Id: I93be9cfe54c651fdbd08c5e1d22d58f47284e54f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2018-08-09 13:18:39 +00:00
Lars Knoll d046de0ddb Setup the prototype correctly when subclassing error objects
Change-Id: I5e394ef8d4d6d87bedb26070d51660e3ebe3ab1b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-08-06 10:00:45 +00:00
Lars Knoll 245cb6b6a3 Fix a couple of test failures related to error objects
Set up the prototype chain for error objects correctly, and make
them inherit from the right classes.

Change-Id: I7bb12b3bb285950a1bff25e5c62954287a95970a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-08-02 20:25:18 +00:00
Lars Knoll 4ac9cf7896 Fix the remaining test failures with non strict arguments objects
Change-Id: Ib50f602263dd0146d792fb3d12bd5971585fda30
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-07-30 20:45:06 +00:00
Lars Knoll fc01254cf8 Fix class members that are generators
Properly support member functions that are generators in classes.

Change-Id: I5fc8d5b58a17c61a446b43d6576bb83de5ecd920
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-07-03 11:19:03 +00:00
Lars Knoll 2666fe4a14 Move the C++ and JS stack frame definitions into it's own file
Change-Id: I86e89e07197aec6071809c2d32bd5c98cb7ac6f6
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-07-03 08:08:49 +00:00
Lars Knoll 0b6bc89c61 Remove ExecutionEngine::setCurrentContext()
It's unused and shouldn't exist. Also de-inline currentContext()
to avoid a dependency on the CppStackFrame in the header.

Change-Id: I44724f8097883dc1b1064430778f45f7811460df
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-07-03 08:08:46 +00:00
Lars Knoll 32c33ee9ab Get rid of Value::asArrayIndex()
It was only used in a few places now, that can be replaced by
either using a PropertyKey, or by limiting the fast path
optimization in the runtime to array indices smaller than
INT_MAX. Since there are less branches this should even be
faster for pretty much all use cases.

Change-Id: Ib4f2f2f3e27f14ad180b810546e82ac83170b106
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-07-02 19:29:52 +00:00
Lars Knoll 56bff8f7ab Clean up the property key API in StringOrSymbol
Get rid of makeIdentifier(), as toPropertyKey() will take
care of it.

Rename identifier() to propertyKey() and check that the
key is valid.

Remove String/StringOrSymbol::asArrayIndex(), we don't need it
anymore.

Change-Id: I3c490fabc1475c9ea288b49b1638b6fa1bc237b7
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-07-02 19:29:43 +00:00
Lars Knoll db695c5b1d Unify the get and getIndexed vtable functions of QV4::Object
This finalizes the refactoring of Object's vtable API. Also added
the receiver argument to the method as required by the ES7 spec.

Change-Id: I36f9989211c47458788fe9f7e929862bcfe7b845
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-07-02 19:29:29 +00:00
Lars Knoll eae4756f74 Add a MemberFunction function object
Member functions in ES7 can not be called as constructors and
will throw a type error when trying.

Some more fixes are needed here, as they also do not have a
prototype property.

Change-Id: Ieb920163acaa68d4ff0ff73ae4c1015e883b406f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-06-26 10:04:18 +00:00
Yulong Bai 74f4065caa Add basic support for EcmaScript classes
Most of the class creation is done inside the runtime
in the CreateClass method. Added a corresponding
instruction to the interpreter and jit.

The compiled data now contains an array of classes
containing the compile time generated layout of the class.

Currently, classes without an explicit constructor and
classes with inheritance are not supported.

Done-with: Yulong Bai <yulong.bai@qt.io>
Change-Id: I0185dcc1e3b0b8f44deff74e44a8262fc646aa9e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-06-26 10:03:56 +00:00
Liang Qi 8597f74e52 Merge "Merge remote-tracking branch 'origin/5.11' into dev" into refs/staging/dev 2018-06-25 10:16:26 +00:00
Ulf Hermann fbf6f7400a Merge remote-tracking branch 'origin/5.11' into dev
Conflicts:
	src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
	src/quick/handlers/qquickhandlerpoint.cpp
	src/quick/handlers/qquicksinglepointhandler.cpp
	tests/auto/qml/ecmascripttests/test262

Change-Id: I8908ec8c6116ca626fbd269af7625d4c429429ca
2018-06-25 12:15:55 +02:00
Lars Knoll 1596112e14 Add Proxy support for prototype handling
Cleanup get/setPrototypeOf and fix some smaller incompatibilities
in the default implementation for Object.

Add the methods to the vtable and reimplement them according to
spec for ProxyObjects.

Clean up the Object.prototype.get/setPrototypeOf/__proto__ methods
and fix a smaller bug in the Reflect API for those methods.

Change-Id: I6e438753332ec4db963d6cdcf86f340ff212777a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-06-25 07:36:48 +00:00
Lars Knoll f5a7953df3 Partial Proxy support
get, set and deleteProperty proxying is implemented,
the others require some more changes in our engine.

Change-Id: I4dd4b154b1a582f5e36cdc9429fa049fd37d5167
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-06-25 07:36:17 +00:00
Lars Knoll 12bc11e5af Add support for Reflect
Implemented all methods in Reflect, only some smaller
bugs left in there.

Change-Id: I53d2304d0e59566aec64e200cd995e02afcfc33e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-06-21 19:43:41 +00:00
Lars Knoll d1693c14b4 revert change 353164263c
The change was too aggressive in trying to avoid marking
the array data. We didn't catch all cases where on could be
inserting a GC controlled object into the array data. Let's
be safe and always mark the content of array data objects.

Task-number: QTBUG-68894
Change-Id: Ifbb628be898c0903596b1a483212384295b01df5
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
2018-06-19 14:20:44 +00:00
Robin Burchell a0fcf724ef Add the start of a Map from ES7
Like Set, for the time being, this is baseed on top of ArrayObject: two
of them, one for keys, one for values. Again, this goes against the
spirit of the spec (which requires nonlinear access), but having the API
present is at least a start, and the implementation is easily changed.

Change-Id: Idcf0ad8d92eb5daac734d52e8e2dd4c8e0dd5109
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2018-06-01 11:53:37 +00:00
Robin Burchell 19f657d995 Add the start of a Set from ES7
Based on top of an ArrayObject for now, which is admittedly a bit of a
cheat and not matching the "spirit" of the spec. OTOH, that makes it
easy to write, and is presumably quite lightweight, so perhaps this is acceptable
as a starting point.

Change-Id: Ibc98137965b3e75635b960a2f88c251d45e6e837
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2018-05-30 20:57:17 +00:00
Lars Knoll 3ccd529e35 Implement toPrimitive() the way the ES7 spec wants it
Add Dat.prototype[Symbol.toPrimitive] and make use of those
methods in the toPrimitive implementation.

Change-Id: I82a9a94dcae6822100de364373b3f4de1e3d749b
Reviewed-by: Robin Burchell <robin.burchell@crimson.no>
2018-05-28 10:40:08 +00:00
Lars Knoll 6cbc287c06 Cleanup JS stack allocations
Avoid double writes to the stack, and use scope.alloc() for
most allocations on the stack.

Change-Id: I8b89273c1b6796d955fc8eeb72c67cff208ef786
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-26 06:49:04 +00:00
Lars Knoll de95f4da8b Fix the inheritance structure for typed arrays
Change-Id: I8a16c1f5e0252b4ea85ff8f623beb39df747e383
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-24 08:09:33 +00:00
Lars Knoll b254bbb82b Merge remote-tracking branch 'origin/5.11' into dev
Change-Id: I0127f2c16de1d930bdd8cbccd42ec6785f31ab96
2018-05-24 09:15:57 +02:00
Lars Knoll 3de014db9e Fixup the throwTypeError internal function
Make the function conform to section 9.2.7.1 of the spec.

Change-Id: Ieb3295198f407d4404e06a54efb51a8b8496bbd7
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-23 13:19:28 +00:00
Simon Hausmann 60176efa78 Fix crash when incubating objects with non-existent initial properties
When incubation is triggered from C++ and reaches the state of setting
the initial properties (as supplied to incubateObject), we'd set
engine->currentStackFrame to a CppStackFrame that provides access to the
correct QML context. As we're not called from the interpreter, the
v4Function pointer would be a null pointer. If during the initial
property setting an exception is thrown (due to non-existent property
access) and a back-trace is created, we'd end up dereferencing
v4Function.

Change-Id: I7f6b0ba7893bfb4186f55d4c213b4bb602d29aa0
Task-number: QTBUG-68416
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2018-05-23 11:06:34 +00:00
Lars Knoll cc8cb4b442 Implement Symbol.species getter functions
Change-Id: I18b3e382e679f95d7cb53b4ed03be2513ea0204b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-15 18:21:10 +00:00
Lars Knoll c4ef0d6e4b Call iterator.return when required in destructuring assignments
Array destructuring assignments require a call to iterator.return if
the iterator hasn't been exhausted during destructuring.

Change-Id: I39fe4bc01bef6fb2ad3bda92caf6779fbbddc8e2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-14 19:32:42 +00:00
Lars Knoll 3d5ba9f86e Add instructions to simplify for-of loops
Added an IteratorNext instruction to fetch the next
iteration value (empty if the iterator is done).

This will also help to implement array destructuring without
requiring huge amounts of byte code.

Change-Id: If96c1e81471e5e2b0b7b2af122238d87741aa371
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-13 12:55:20 +00:00
Lars Knoll 4cf7e80c57 Ensure we have a lexical scope for global code
This requires a bit more work than simply pushing a
new BlockContext for the lexically declared variables,
as eval() and the Function constructor operate on the
global scope (including the lexically declared names).

To fix this introduce Push/PopScriptContext instructions,
that create a BlockContext for the lexically declared
vars and pushes that one as a global script context that
eval and friends use.

Change-Id: I0fd0b0f682f82e250545e874fe93978449fe5e46
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-11 07:17:05 +00:00
Lars Knoll 8e69a9868c Avoid accessing an object with this == nullptr
Get rid of a circular dependency when initializing
StringObject.prototype, by setting it's string value
later during the initialization process.

Change-Id: I5bdaff3936c1f8af12c4d53f95747b8aa43f4ef6
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-04 18:13:09 +00:00
Lars Knoll 4f086e3aac Rename ForeachIterator to ForInIterator
As it's being used for for(... in ...) loops. Also add a ES6
compatible iterator interface to it, so that we can unify
the handling of for-in and for-of.

Change-Id: I264f88ed049484945f5ea7e8bdf0227187456ba2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-04 18:12:50 +00:00
Lars Knoll 1f9fdd1af7 The length property of function objects is configurable
Change-Id: I657be2e2eb4dfd86850bb73e85d4ddd24f0b8986
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-03 20:05:18 +00:00
Lars Knoll 5747a75302 Add Generator support
Add support for ES6 generators. Those are currently
always executed in the interpreter (we never JIT them),
to simplify the initial implementation.

Most functionality, except for 'yield *' expressions
are supported. 'yield *' will have to wait until we
support for(... of ...)

Change-Id: I7c059d1e3b301cbcb79e3746b4bec346738fd426
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-03 20:05:14 +00:00
Lars Knoll 8761cbd4f7 Implement StringIterator
Add support for String.prototype[Symbol.iterator] and the
StringIterator object.

Change-Id: I72c4f988e4f363be1af51f9cc5f8e83af43cd151
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:20:29 +00:00
Lars Knoll 7d46d72510 Implement support for arguments[Symbol.iterator]
Change-Id: Ieb60e2d8f41c38146b588bc8cd225a2a567e0956
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:20:25 +00:00
Lars Knoll c7fe748850 Cleanup creation code for builtin functions
Centralize the code in FunctionObject::createBuiltinFunction and setup
function names and length properties there.

Change-Id: I21f1d42b475070ee091d96d97387149af1dc47f2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:20:21 +00:00
Robin Burchell a4207b2f95 Add Array Iterator objects from ES6 (22.1.5)
And implement / expose them via:
    22.1.3.4 - Array.prototype.entries()
    22.1.3.13 - Array.prototype.keys()
    22.1.3.29 - Array.prototype.values()
    22.1.3.31 - Array.prototype[Symbol.iterator]

Most tests for Array iterators now pass.

At the same time, expose them on TypedArray's prototype:
    - 22.2.3.15 %TypedArray%.prototype.keys
    - 22.2.3.29 %TypedArray%.prototype.values
    - 22.2.3.6 %TypedArray%.prototype.entries
    - 22.2.3.31 %TypedArray%.prototype[Symbol.iterator]

For TypedArray, test coverage improves a tiny bit (3 passing tests), but the
vast majority fail as it seems like the object structure for TypedArray is
currently incomplete as far as ES6 expects.

It seems that ES6 expects the object structure to be:
* %TypedArray% (inherits FunctionObject)
    (this is the TypedArray intrinsic object, and responsible for initializing
    the TypedArray instances)

* All the TypedArray ctors (e.g. UInt8Array)
    These inherit %TypedArray%, and make a super call to it to do their work

* %TypedArrayPrototype% (inherits Object)
    (this is the initial prototype for %TypedArray%)
    * All the ctors have their own separate instance of this
    * The instances also make use it

So, for instance, a lot of the tests attempt to access the prototype like:
    var proto = Object.getPrototypeOf(Int8Array)
    var keys = proto.prototype.keys

As ES6 expects Int8Array.prototype to be %TypedArray% (22.2.5), this expands to:
    Object.getPrototypeOf(%TypedArray%)
which it expects to be %TypedArrayPrototype%.

But since we have no intrinsic object, and the ctors inherit
FunctionObject, we instead return the wrong prototype into 'var proto'.

Change-Id: I5e1a95a0420ecb70a0e35a5df3f65557510c5925
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:20:13 +00:00
Lars Knoll 37b85ca10e Add SymbolObject, well known symbols and fix most remaining issues
Added SymbolObject, the equivalent to StringObject which was
still missing so far. Added the predefined standard symbols,
and fixed most test failures related to symbols.

Change-Id: I1e28b439e7c4f5141b4a09bd8fb666c60691f192
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:18:45 +00:00
Lars Knoll 360a48aa3f Implement Symbol.for and Symbol.keyFor
Change-Id: I5fde731b3a1a6d7c15154881ed82549b2800d104
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:18:41 +00:00
Lars Knoll bab5e5adf5 Partial Symbol support
Added basic infrastructure to create symbols and convert them
back to strings. In addition, storing and retrieving of symbol
based properties in Objects works.

Change-Id: I185f7aa46e7afa19db5a801102142892e03b7bf1
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:18:36 +00:00
Lars Knoll a6da23bb5f Garbage collect identifiers
Implemented by storing a backpointer to the Heap object
in the identifier.

Since identifiers now point back to their originating
String or Symbol, we can now easily mark all identifiers
that are still in use and collect those that aren't.

Since Identifiers are 64bit also add support for holding an
array index in there. With that an identifier can describe
any kind of property that can be accessed in an object. This
helps speed up and simplify some code paths.

To make this possible, we need to register all
IdentifierHash instances with the identifier table, so that
we can properly mark those identifiers.

Change-Id: Icadbaf5712ab9d252d4e71aa4a520e86b14cd2a0
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:18:32 +00:00
Lars Knoll 3c090c80c5 Remove String dependency from InternalClass
This is required, so we can also use Symbols in
the internal classes.

Change-Id: I630e7aa7b8b16d5a94041f8d18515fd582f94264
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:18:23 +00:00
Lars Knoll 922e6f42b4 Rework catch context handling
Remove the need for a specialized catch context, instead
use a regular block context, that also captures the
catched variable.

This also removes the need to do lookups by name inside
a catch expression.

Change-Id: I8b037add7f423922e2a76b4c0da646ca7e25813a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-05-02 14:17:51 +00:00
Lars Knoll 7e854bc568 Clean up handling of the 'caller' property
This brings it closer in line with the ES8 spec. Also
remove a couple of tests testing the 'caller' property
of non strict functions, as it's not mandated by the
spec and we never set it.

Change-Id: Icece8a03989c474df1eae0e4e77b356e49575b32
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-04-26 20:26:56 +00:00
Lars Knoll ce2f9621e0 Get rid of some outdated code
There's no point in trying to treat syntax errors specially here.

Change-Id: Idde8f9c9669f183e1b8f5b17bb7e4299fc5f1e5f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-04-12 13:59:21 +00:00
Lars Knoll 6002b48c3c garbage collect InternalClass
Internal classes are now allocated and collected through
the GC. As they are important to the deletion of other
objects (because of the vtable pointer living inside the
internal class), they need to get destroyed after regular
objects have been sweeped. Achieve this by using a separate
block allocator for internal class objects.

Our lookups do often contain pointers to internal classes,
so those need to be marked as well, so we don't accidentally
collect them.

Change-Id: I4762b054361c70c31f79f920f669ea0e8551601f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2018-04-12 13:59:08 +00:00