aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-05-20 15:24:51 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-05-31 15:03:33 +0200
commitc8c2db3f5b157131542025ce556d248c7a916a00 (patch)
tree4c91465c8935b880c6dd42cb427fa3b173d52157 /src/qml/compiler
parent0f035c0ad79ca41a1473b64a4c0077e7085d3700 (diff)
Split QV4::Value into a static and a dynamic part
The static part can be used for compilation and won't resolve managed objects. This allows us to remove all the remaining V4_BOOTSTRAP. Change-Id: Id2f6feb64c48beb2a407697881aea8c0d791a532 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp2
-rw-r--r--src/qml/compiler/qv4codegen.cpp57
-rw-r--r--src/qml/compiler/qv4codegen_p.h3
-rw-r--r--src/qml/compiler/qv4compileddata.cpp8
-rw-r--r--src/qml/compiler/qv4compileddata_p.h7
-rw-r--r--src/qml/compiler/qv4compiler.cpp2
-rw-r--r--src/qml/compiler/qv4compilercontext.cpp2
-rw-r--r--src/qml/compiler/qv4executablecompilationunit.cpp10
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp8
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
10 files changed, 61 insertions, 40 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 6f46648572..3e5798ba8b 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -39,7 +39,7 @@
#include "qqmlirbuilder_p.h"
-#include <private/qv4value_p.h>
+#include <private/qv4staticvalue_p.h>
#include <private/qv4compileddata_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qqmljslexer_p.h>
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index b145ceb51e..b7e3e20fd0 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -48,7 +48,7 @@
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qv4stringtoarrayindex_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4staticvalue_p.h>
#include <private/qv4compilercontext_p.h>
#include <private/qv4compilercontrolflow_p.h>
#include <private/qv4bytecodegenerator_p.h>
@@ -267,13 +267,26 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr)
return exprResult();
if (expr.isConstant()) {
- auto v = Value::fromReturnedValue(expr.constant);
+ auto v = StaticValue::fromReturnedValue(expr.constant);
if (v.isNumber()) {
switch (op) {
case Not:
return Reference::fromConst(this, Encode(!v.toBoolean()));
case UMinus:
- return Reference::fromConst(this, Runtime::UMinus::call(v));
+ // This duplicates some of the logic from Runtime::UMinus::call()
+ ReturnedValue r;
+ if (v.isInteger()) {
+ int intVal = v.integerValue();
+ if (intVal && intVal != std::numeric_limits<int>::min())
+ r = QV4::Encode(-intVal);
+ else
+ r = QV4::Encode(-double(intVal));
+ } else if (v.isDouble()) {
+ r = QV4::Encode(-v.doubleValue());
+ } else {
+ r = QV4::Encode(-v.int_32());
+ }
+ return Reference::fromConst(this, r);
case UPlus:
return expr;
case Compl:
@@ -1006,7 +1019,7 @@ bool Codegen::visit(ClassExpression *ast)
return false;
r.storeOnStack(heritage.stackSlot());
} else {
- Reference::fromConst(this, Value::emptyValue().asReturnedValue()).loadInAccumulator();
+ Reference::fromConst(this, StaticValue::emptyValue().asReturnedValue()).loadInAccumulator();
heritage.storeConsumeAccumulator();
}
@@ -1083,7 +1096,7 @@ bool Codegen::visit(ArrayPattern *ast)
if (args == -1)
args = temp;
if (!arg) {
- auto c = Reference::fromConst(this, Value::emptyValue().asReturnedValue());
+ auto c = Reference::fromConst(this, StaticValue::emptyValue().asReturnedValue());
(void) c.storeOnStack(temp);
} else {
RegisterScope scope(this);
@@ -1144,7 +1157,8 @@ bool Codegen::visit(ArrayPattern *ast)
while (it) {
for (Elision *elision = it->elision; elision; elision = elision->next) {
- Reference::fromConst(this, Value::emptyValue().asReturnedValue()).loadInAccumulator();
+ Reference::fromConst(
+ this, StaticValue::emptyValue().asReturnedValue()).loadInAccumulator();
pushAccumulator();
}
@@ -1538,9 +1552,9 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
}
case QSOperator::BitAnd:
if (right.isConstant()) {
- int rightAsInt = Value::fromReturnedValue(right.constant).toInt32();
+ int rightAsInt = StaticValue::fromReturnedValue(right.constant).toInt32();
if (left.isConstant()) {
- int result = Value::fromReturnedValue(left.constant).toInt32() & rightAsInt;
+ int result = StaticValue::fromReturnedValue(left.constant).toInt32() & rightAsInt;
return Reference::fromConst(this, Encode(result));
}
left.loadInAccumulator();
@@ -1556,9 +1570,9 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
break;
case QSOperator::BitOr:
if (right.isConstant()) {
- int rightAsInt = Value::fromReturnedValue(right.constant).toInt32();
+ int rightAsInt = StaticValue::fromReturnedValue(right.constant).toInt32();
if (left.isConstant()) {
- int result = Value::fromReturnedValue(left.constant).toInt32() | rightAsInt;
+ int result = StaticValue::fromReturnedValue(left.constant).toInt32() | rightAsInt;
return Reference::fromConst(this, Encode(result));
}
left.loadInAccumulator();
@@ -1574,9 +1588,9 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
break;
case QSOperator::BitXor:
if (right.isConstant()) {
- int rightAsInt = Value::fromReturnedValue(right.constant).toInt32();
+ int rightAsInt = StaticValue::fromReturnedValue(right.constant).toInt32();
if (left.isConstant()) {
- int result = Value::fromReturnedValue(left.constant).toInt32() ^ rightAsInt;
+ int result = StaticValue::fromReturnedValue(left.constant).toInt32() ^ rightAsInt;
return Reference::fromConst(this, Encode(result));
}
left.loadInAccumulator();
@@ -1594,7 +1608,7 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
if (right.isConstant()) {
left.loadInAccumulator();
Instruction::UShrConst ushr;
- ushr.rhs = Value::fromReturnedValue(right.constant).toInt32() & 0x1f;
+ ushr.rhs = StaticValue::fromReturnedValue(right.constant).toInt32() & 0x1f;
bytecodeGenerator->addInstruction(ushr);
} else {
right.loadInAccumulator();
@@ -1607,7 +1621,7 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
if (right.isConstant()) {
left.loadInAccumulator();
Instruction::ShrConst shr;
- shr.rhs = Value::fromReturnedValue(right.constant).toInt32() & 0x1f;
+ shr.rhs = StaticValue::fromReturnedValue(right.constant).toInt32() & 0x1f;
bytecodeGenerator->addInstruction(shr);
} else {
right.loadInAccumulator();
@@ -1620,7 +1634,7 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
if (right.isConstant()) {
left.loadInAccumulator();
Instruction::ShlConst shl;
- shl.rhs = Value::fromReturnedValue(right.constant).toInt32() & 0x1f;
+ shl.rhs = StaticValue::fromReturnedValue(right.constant).toInt32() & 0x1f;
bytecodeGenerator->addInstruction(shl);
} else {
right.loadInAccumulator();
@@ -1748,7 +1762,7 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe
qSwap(left, right); // null==a -> a==null
if (right.isConstant()) {
- Value c = Value::fromReturnedValue(right.constant);
+ StaticValue c = StaticValue::fromReturnedValue(right.constant);
if (c.isNull() || c.isUndefined()) {
left.loadInAccumulator();
if (oper == QSOperator::Equal) {
@@ -2022,7 +2036,9 @@ Codegen::Arguments Codegen::pushArgs(ArgumentList *args)
argc = 0;
for (ArgumentList *it = args; it; it = it->next) {
if (it->isSpreadElement) {
- Reference::fromConst(this, Value::emptyValue().asReturnedValue()).storeOnStack(calldata + argc);
+ Reference::fromConst(
+ this,
+ StaticValue::emptyValue().asReturnedValue()).storeOnStack(calldata + argc);
++argc;
}
RegisterScope scope(this);
@@ -2999,7 +3015,8 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
functionEndsWithReturn = endsWithReturn(_module, body);
// reserve the js stack frame (Context & js Function & accumulator)
- bytecodeGenerator->newRegisterArray(sizeof(CallData)/sizeof(Value) - 1 + _context->arguments.size());
+ bytecodeGenerator->newRegisterArray(
+ sizeof(CallData) / sizeof(StaticValue) - 1 + _context->arguments.size());
bool _inFormalParameterList = false;
qSwap(_inFormalParameterList, inFormalParameterList);
@@ -4314,7 +4331,7 @@ QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // the loads below are empty str
Instruction::LoadUndefined load;
codegen->bytecodeGenerator->addInstruction(load);
} else {
- Value p = Value::fromReturnedValue(constant);
+ StaticValue p = StaticValue::fromReturnedValue(constant);
if (p.isNumber()) {
double d = p.asDouble();
int i = static_cast<int>(d);
@@ -4325,7 +4342,7 @@ QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // the loads below are empty str
return;
}
Instruction::LoadInt load;
- load.value = Value::fromReturnedValue(constant).toInt32();
+ load.value = StaticValue::fromReturnedValue(constant).toInt32();
codegen->bytecodeGenerator->addInstruction(load);
return;
}
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index e519da0142..6d5f8c0951 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -258,7 +258,8 @@ public:
}
static Reference fromArgument(Codegen *cg, int index, bool isVolatile) {
Reference r(cg, StackSlot);
- r.theStackSlot = Moth::StackSlot::createRegister(index + sizeof(CallData)/sizeof(Value) - 1);
+ r.theStackSlot = Moth::StackSlot::createRegister(
+ index + sizeof(CallData) / sizeof(StaticValue) - 1);
r.stackSlotIsLocalOrArgument = true;
r.isVolatile = isVolatile;
return r;
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 0fed0a03b2..813868b0ae 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qv4compileddata_p.h"
-#include <private/qv4value_p.h>
+#include <private/qv4staticvalue_p.h>
#include <private/qqmlirbuilder_p.h>
#include <QCoreApplication>
#include <QCryptographicHash>
@@ -144,13 +144,13 @@ void CompilationUnit::setUnitData(const Unit *unitData, const QmlUnit *qmlUnit,
qmlData = qmlUnit ? qmlUnit : data->qmlUnit();
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- Value *bigEndianConstants = new Value[data->constantTableSize];
+ StaticValue *bigEndianConstants = new StaticValue[data->constantTableSize];
const quint64_le *littleEndianConstants = data->constants();
for (uint i = 0; i < data->constantTableSize; ++i)
- bigEndianConstants[i] = Value::fromReturnedValue(littleEndianConstants[i]);
+ bigEndianConstants[i] = StaticValue::fromReturnedValue(littleEndianConstants[i]);
constants = bigEndianConstants;
#else
- constants = reinterpret_cast<const Value*>(data->constants());
+ constants = reinterpret_cast<const StaticValue*>(data->constants());
#endif
m_fileName = !fileName.isEmpty() ? fileName : stringAt(data->sourceFileIndex);
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 94b64694ae..63738d6002 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -88,6 +88,7 @@ struct Document;
}
namespace QV4 {
+struct StaticValue;
namespace Heap {
struct Module;
@@ -1070,10 +1071,10 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnitBase
// pointers either to data->constants() or little-endian memory copy.
QV4::Heap::String **runtimeStrings = nullptr; // Array
- const Value* constants = nullptr;
- QV4::Value *runtimeRegularExpressions = nullptr;
+ const StaticValue* constants = nullptr;
+ QV4::StaticValue *runtimeRegularExpressions = nullptr;
QV4::Heap::InternalClass **runtimeClasses = nullptr;
- const Value** imports = nullptr;
+ const StaticValue** imports = nullptr;
};
Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value);
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 4a54e5a44b..8722263b04 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -40,7 +40,7 @@
#include <qv4compiler_p.h>
#include <qv4compileddata_p.h>
#include <qv4codegen_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4staticvalue_p.h>
#include <private/qv4alloca_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsast_p.h>
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp
index d1a5fee92b..88837b0feb 100644
--- a/src/qml/compiler/qv4compilercontext.cpp
+++ b/src/qml/compiler/qv4compilercontext.cpp
@@ -156,7 +156,7 @@ Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::AS
result.isConst = false;
return result;
} else {
- result.index = argIdx + sizeof(CallData)/sizeof(Value) - 1;
+ result.index = argIdx + sizeof(CallData) / sizeof(StaticValue) - 1;
result.scope = 0;
result.type = ResolvedName::Stack;
result.isConst = false;
diff --git a/src/qml/compiler/qv4executablecompilationunit.cpp b/src/qml/compiler/qv4executablecompilationunit.cpp
index 97c828d4d8..c68f6a7cbf 100644
--- a/src/qml/compiler/qv4executablecompilationunit.cpp
+++ b/src/qml/compiler/qv4executablecompilationunit.cpp
@@ -102,7 +102,7 @@ static QString toString(QV4::ReturnedValue v)
return result;
}
-static void dumpConstantTable(const Value *constants, uint count)
+static void dumpConstantTable(const StaticValue *constants, uint count)
{
QDebug d = qDebug();
d.nospace() << right;
@@ -320,7 +320,7 @@ void ExecutableCompilationUnit::markObjects(QV4::MarkStack *markStack)
}
if (runtimeRegularExpressions) {
for (uint i = 0; i < data->regexpTableSize; ++i)
- runtimeRegularExpressions[i].mark(markStack);
+ Value::fromStaticValue(runtimeRegularExpressions[i]).mark(markStack);
}
if (runtimeClasses) {
for (uint i = 0; i < data->jsClassTableSize; ++i)
@@ -458,8 +458,8 @@ Heap::Module *ExecutableCompilationUnit::instantiate(ExecutionEngine *engine)
const uint importCount = data->importEntryTableSize;
if (importCount > 0) {
- imports = new const Value *[importCount];
- memset(imports, 0, importCount * sizeof(Value *));
+ imports = new const StaticValue *[importCount];
+ memset(imports, 0, importCount * sizeof(StaticValue *));
}
for (uint i = 0; i < importCount; ++i) {
const CompiledData::ImportEntry &entry = data->importEntryTable()[i];
@@ -517,7 +517,7 @@ const Value *ExecutableCompilationUnit::resolveExportRecursively(
if (index == UINT_MAX)
return nullptr;
if (index >= module()->scope->locals.size)
- return imports[index - module()->scope->locals.size];
+ return &(imports[index - module()->scope->locals.size]->asValue<Value>());
return &module()->scope->locals[index];
}
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 8a9bd66103..640a908dd3 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -41,6 +41,8 @@
#include <private/qv4compileddata_p.h>
#include <private/qv4calldata_p.h>
+#include <QtCore/qdebug.h>
+
using namespace QV4;
using namespace QV4::Moth;
@@ -110,9 +112,9 @@ const int InstrInfo::argumentCount[] = {
QString dumpRegister(int reg, int nFormals)
{
Q_STATIC_ASSERT(offsetof(CallData, function) == 0);
- Q_STATIC_ASSERT(offsetof(CallData, context) == sizeof(Value));
- Q_STATIC_ASSERT(offsetof(CallData, accumulator) == 2*sizeof(Value));
- Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 3*sizeof(Value));
+ Q_STATIC_ASSERT(offsetof(CallData, context) == sizeof(StaticValue));
+ Q_STATIC_ASSERT(offsetof(CallData, accumulator) == 2*sizeof(StaticValue));
+ Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 3*sizeof(StaticValue));
if (reg == CallData::Function)
return QStringLiteral("(function)");
else if (reg == CallData::Context)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 5338583164..ec81701160 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -51,7 +51,7 @@
// We mean it.
//
#include <private/qv4global_p.h>
-#include <private/qv4runtime_p.h>
+#include <private/qv4staticvalue_p.h>
#include <private/qv4compileddata_p.h> // for CompiledData::CodeOffsetToLine used by the dumper
#include <qendian.h>