aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4context_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4context_p.h')
-rw-r--r--src/qml/jsruntime/qv4context_p.h245
1 files changed, 83 insertions, 162 deletions
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index a854c324d0..4efd0bc899 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -68,59 +68,66 @@ struct Function;
struct Function;
struct Identifier;
struct CallContext;
-struct SimpleCallContext;
struct CatchContext;
-struct WithContext;
struct QmlContext;
struct QQmlContextWrapper;
-// Attention: Make sure that this structure is the same size on 32-bit and 64-bit
-// architecture or you'll have to change the JIT code.
struct CallData
{
- // below is to be compatible with Value. Initialize tag to 0
-#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
- uint tag;
-#endif
- int argc;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- uint tag;
-#endif
+ enum Offsets {
+ Function = 0,
+ Context = 1,
+ Accumulator = 2,
+ This = 3,
+ Argc = 4
+ };
+
+ Value function;
+ Value context;
+ Value accumulator;
+ Value thisObject;
+ Value _argc;
+
+ int argc() const {
+ Q_ASSERT(_argc.isInteger());
+ return _argc.int_32();
+ }
+
+ void setArgc(int argc) {
+ Q_ASSERT(argc >= 0);
+ _argc.setInt_32(argc);
+ }
+
inline ReturnedValue argument(int i) const {
- return i < argc ? args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
+ return i < argc() ? args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
}
- Value thisObject;
Value args[1];
+
+ static Q_DECL_CONSTEXPR int HeaderSize() { return offsetof(CallData, args) / sizeof(QV4::Value); }
};
Q_STATIC_ASSERT(std::is_standard_layout<CallData>::value);
-Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 8);
-Q_STATIC_ASSERT(offsetof(CallData, args) == 16);
+Q_STATIC_ASSERT(offsetof(CallData, thisObject) == CallData::This*sizeof(Value));
+Q_STATIC_ASSERT(offsetof(CallData, args) == 5*sizeof(Value));
namespace Heap {
struct QmlContext;
#define ExecutionContextMembers(class, Member) \
- Member(class, NoMark, CallData *, callData) \
Member(class, Pointer, ExecutionContext *, outer) \
- Member(class, NoMark, Lookup *, lookups) \
- Member(class, NoMark, const QV4::Value *, constantTable) \
- Member(class, NoMark, CompiledData::CompilationUnitBase *, compilationUnit) \
- Member(class, NoMark, int, lineNumber) // as member of non-pointer size this has to come last to preserve the ability to
- // translate offsetof of it between 64-bit and 32-bit.
+ Member(class, Pointer, Object *, activation)
DECLARE_HEAP_OBJECT(ExecutionContext, Base) {
- DECLARE_MARK_TABLE(ExecutionContext);
+ DECLARE_MARKOBJECTS(ExecutionContext);
enum ContextType {
Type_GlobalContext = 0x1,
Type_CatchContext = 0x2,
Type_WithContext = 0x3,
Type_QmlContext = 0x4,
- Type_SimpleCallContext = 0x5,
- Type_CallContext = 0x6
+ Type_CallContext = 0x5
};
void init(ContextType t)
@@ -128,105 +135,63 @@ DECLARE_HEAP_OBJECT(ExecutionContext, Base) {
Base::init();
type = t;
- lineNumber = -1;
}
- quint8 type;
- bool strictMode : 8;
+ quint32 type : 8;
+ quint32 nArgs : 24;
#if QT_POINTER_SIZE == 8
- quint8 padding_[6];
-#else
- quint8 padding_[2];
+ quint8 padding_[4];
#endif
};
V4_ASSERT_IS_TRIVIAL(ExecutionContext)
Q_STATIC_ASSERT(sizeof(ExecutionContext) == sizeof(Base) + sizeof(ExecutionContextData) + QT_POINTER_SIZE);
Q_STATIC_ASSERT(std::is_standard_layout<ExecutionContextData>::value);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, callData) == 0);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, outer) == offsetof(ExecutionContextData, callData) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, lookups) == offsetof(ExecutionContextData, outer) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, constantTable) == offsetof(ExecutionContextData, lookups) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, compilationUnit) == offsetof(ExecutionContextData, constantTable) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, lineNumber) == offsetof(ExecutionContextData, compilationUnit) + QT_POINTER_SIZE);
-
-#define SimpleCallContextMembers(class, Member) \
- Member(class, Pointer, Object *, activation) \
- Member(class, NoMark, QV4::Function *, v4Function)
-
-DECLARE_HEAP_OBJECT(SimpleCallContext, ExecutionContext) {
- DECLARE_MARK_TABLE(SimpleCallContext);
-
- void init(ContextType t = Type_SimpleCallContext)
- {
- ExecutionContext::init(t);
- }
-
- inline unsigned int formalParameterCount() const;
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, outer) == 0);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, activation) == offsetof(ExecutionContextData, outer) + QT_POINTER_SIZE);
-};
-V4_ASSERT_IS_TRIVIAL(SimpleCallContext)
-Q_STATIC_ASSERT(std::is_standard_layout<SimpleCallContextData>::value);
-Q_STATIC_ASSERT(offsetof(SimpleCallContextData, activation) == 0);
-Q_STATIC_ASSERT(offsetof(SimpleCallContextData, v4Function) == offsetof(SimpleCallContextData, activation) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(sizeof(SimpleCallContextData) == 2 * QT_POINTER_SIZE);
-Q_STATIC_ASSERT(sizeof(SimpleCallContext) == sizeof(ExecutionContext) + sizeof(SimpleCallContextData));
-
-#if QT_POINTER_SIZE == 8
#define CallContextMembers(class, Member) \
Member(class, Pointer, FunctionObject *, function) \
Member(class, ValueArray, ValueArray, locals)
-#else
-#define CallContextMembers(class, Member) \
- Member(class, Pointer, FunctionObject *, function) \
- Member(class, NoMark, void *, padding) \
- Member(class, ValueArray, ValueArray, locals)
-#endif
-DECLARE_HEAP_OBJECT(CallContext, SimpleCallContext) {
- DECLARE_MARK_TABLE(CallContext);
+DECLARE_HEAP_OBJECT(CallContext, ExecutionContext) {
+ DECLARE_MARKOBJECTS(CallContext);
- using SimpleCallContext::formalParameterCount;
-};
+ void init()
+ {
+ ExecutionContext::init(Type_CallContext);
+ }
+ int argc() const {
+ return static_cast<int>(nArgs);
+ }
+ const Value *args() const {
+ return locals.data() + locals.size;
+ }
+ void setArg(uint index, Value v);
+};
+V4_ASSERT_IS_TRIVIAL(CallContext)
Q_STATIC_ASSERT(std::is_standard_layout<CallContextData>::value);
Q_STATIC_ASSERT(offsetof(CallContextData, function) == 0);
-// IMPORTANT: we cannot do offsetof(CallContextData, locals) in the JIT as the offset does not scale with
-// the pointer size. On 32-bit ARM the offset of the ValueArray is aligned to 8 bytes, on 32-bit x86 for
-// example it is not. Therefore we have a padding in place and always have a distance of 8 bytes.
-Q_STATIC_ASSERT(offsetof(CallContextData, locals) == offsetof(CallContextData, function) + 8);
-
-#define GlobalContextMembers(class, Member) \
- Member(class, Pointer, Object *, global)
-
-DECLARE_HEAP_OBJECT(GlobalContext, ExecutionContext) {
- DECLARE_MARK_TABLE(GlobalContext);
-
- void init(ExecutionEngine *engine);
-};
-V4_ASSERT_IS_TRIVIAL(GlobalContext)
+//### The following size check fails on Win8. With the ValueArray at the end of the
+// CallContextMembers, it doesn't look very useful.
+//#if defined(Q_PROCESSOR_ARM_32) && !defined(Q_OS_IOS)
+//Q_STATIC_ASSERT(sizeof(CallContext) == sizeof(ExecutionContext) + sizeof(CallContextData) + QT_POINTER_SIZE);
+//#else
+//Q_STATIC_ASSERT(sizeof(CallContext) == sizeof(ExecutionContext) + sizeof(CallContextData));
+//#endif
#define CatchContextMembers(class, Member) \
Member(class, Pointer, String *, exceptionVarName) \
Member(class, HeapValue, HeapValue, exceptionValue)
DECLARE_HEAP_OBJECT(CatchContext, ExecutionContext) {
- DECLARE_MARK_TABLE(CatchContext);
+ DECLARE_MARKOBJECTS(CatchContext);
void init(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue);
};
V4_ASSERT_IS_TRIVIAL(CatchContext)
-#define WithContextMembers(class, Member) \
- Member(class, Pointer, Object *, withObject)
-
-DECLARE_HEAP_OBJECT(WithContext, ExecutionContext) {
- DECLARE_MARK_TABLE(WithContext);
-
- void init(ExecutionContext *outerContext, Object *with);
-};
-V4_ASSERT_IS_TRIVIAL(WithContext)
-
}
struct Q_QML_EXPORT ExecutionContext : public Managed
@@ -239,68 +204,39 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
Q_MANAGED_TYPE(ExecutionContext)
V4_INTERNALCLASS(ExecutionContext)
- Heap::CallContext *newCallContext(Function *f, CallData *callData);
- Heap::WithContext *newWithContext(Heap::Object *with);
+ static Heap::CallContext *newCallContext(QV4::CppStackFrame *frame);
+ Heap::ExecutionContext *newWithContext(Heap::Object *with);
Heap::CatchContext *newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue);
void createMutableBinding(String *name, bool deletable);
- void setProperty(String *name, const Value &value);
+ enum Error {
+ NoError,
+ TypeError,
+ RangeError
+ };
+
+ Error setProperty(String *name, const Value &value);
+
ReturnedValue getProperty(String *name);
ReturnedValue getPropertyAndBase(String *name, Value *base);
bool deleteProperty(String *name);
- inline SimpleCallContext *asSimpleCallContext();
- inline const SimpleCallContext *asSimpleCallContext() const;
- inline const CatchContext *asCatchContext() const;
- inline const WithContext *asWithContext() const;
+ inline CallContext *asCallContext();
+ inline const CallContext *asCallContext() const;
+};
- Function *getFunction() const;
+struct Q_QML_EXPORT CallContext : public ExecutionContext
+{
+ V4_MANAGED(CallContext, ExecutionContext)
+ V4_INTERNALCLASS(CallContext)
- Value &thisObject() const {
- return d()->callData->thisObject;
- }
int argc() const {
- return d()->callData->argc;
+ return d()->argc();
}
const Value *args() const {
- return d()->callData->args;
- }
- ReturnedValue argument(int i) const {
- return d()->callData->argument(i);
+ return d()->args();
}
-
- void call(Scope &scope, CallData *callData, QV4::Function *function, const QV4::FunctionObject *f = 0);
- void simpleCall(Scope &scope, CallData *callData, QV4::Function *function);
-};
-
-struct Q_QML_EXPORT SimpleCallContext : public ExecutionContext
-{
- V4_MANAGED(SimpleCallContext, ExecutionContext)
- V4_INTERNALCLASS(SimpleCallContext)
-
- // formals are in reverse order
- Identifier * const *formals() const;
- unsigned int formalCount() const;
- Identifier * const *variables() const;
- unsigned int variableCount() const;
-
- inline ReturnedValue argument(int i) const;
-};
-
-inline ReturnedValue SimpleCallContext::argument(int i) const {
- return i < argc() ? args()[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
-}
-
-struct Q_QML_EXPORT CallContext : public SimpleCallContext
-{
- V4_MANAGED(CallContext, SimpleCallContext)
-};
-
-struct GlobalContext : public ExecutionContext
-{
- V4_MANAGED(GlobalContext, ExecutionContext)
-
};
struct CatchContext : public ExecutionContext
@@ -308,29 +244,14 @@ struct CatchContext : public ExecutionContext
V4_MANAGED(CatchContext, ExecutionContext)
};
-struct WithContext : public ExecutionContext
-{
- V4_MANAGED(WithContext, ExecutionContext)
-};
-
-inline SimpleCallContext *ExecutionContext::asSimpleCallContext()
-{
- return d()->type >= Heap::ExecutionContext::Type_SimpleCallContext ? static_cast<SimpleCallContext *>(this) : 0;
-}
-
-inline const SimpleCallContext *ExecutionContext::asSimpleCallContext() const
-{
- return d()->type >= Heap::ExecutionContext::Type_SimpleCallContext ? static_cast<const SimpleCallContext *>(this) : 0;
-}
-
-inline const CatchContext *ExecutionContext::asCatchContext() const
+inline CallContext *ExecutionContext::asCallContext()
{
- return d()->type == Heap::ExecutionContext::Type_CatchContext ? static_cast<const CatchContext *>(this) : 0;
+ return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<CallContext *>(this) : 0;
}
-inline const WithContext *ExecutionContext::asWithContext() const
+inline const CallContext *ExecutionContext::asCallContext() const
{
- return d()->type == Heap::ExecutionContext::Type_WithContext ? static_cast<const WithContext *>(this) : 0;
+ return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<const CallContext *>(this) : 0;
}
} // namespace QV4