Fix run-time string handling with regards to the new heap
Changed runtimeStrings to be an array of Heap::String pointers instead of indirect String pointers. Later that member along with other GC related members will go into a managed subclass. Meanwhile the generated code no more loads String pointers directly but just passes the index into the run-time strings to the run-time functions, which in turn will load the heap string into a scoped string. Also replaced the template<T> Value::operator=(T *m) with a non-template overload that takes a Managed *, in order to help the compiler choose the non-template operator=(Heap::Base *) overload. This allows removing a bunch of Value::fromHeapObject calls. Change-Id: I20415c0549d33cca6813441a2495976b66d4c00e Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
e6db292366
commit
f58b5229a3
|
@ -65,13 +65,11 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
|
|||
|
||||
Q_ASSERT(!runtimeStrings);
|
||||
Q_ASSERT(data);
|
||||
runtimeStrings = (QV4::String **)malloc(data->stringTableSize * sizeof(QV4::String*));
|
||||
runtimeStrings = (QV4::Heap::String **)malloc(data->stringTableSize * sizeof(QV4::Heap::String*));
|
||||
// memset the strings to 0 in case a GC run happens while we're within the loop below
|
||||
memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::String*));
|
||||
for (uint i = 0; i < data->stringTableSize; ++i) {
|
||||
// #### GC
|
||||
runtimeStrings[i] = reinterpret_cast<QV4::String*>(engine->newIdentifier(data->stringAt(i)));
|
||||
}
|
||||
memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::Heap::String*));
|
||||
for (uint i = 0; i < data->stringTableSize; ++i)
|
||||
runtimeStrings[i] = engine->newIdentifier(data->stringAt(i));
|
||||
|
||||
runtimeRegularExpressions = new QV4::Value[data->regexpTableSize];
|
||||
// memset the regexps to 0 in case a GC run happens while we're within the loop below
|
||||
|
@ -85,7 +83,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
|
|||
flags |= IR::RegExp::RegExp_IgnoreCase;
|
||||
if (re->flags & CompiledData::RegExp::RegExp_Multiline)
|
||||
flags |= IR::RegExp::RegExp_Multiline;
|
||||
runtimeRegularExpressions[i] = QV4::Value::fromHeapObject(engine->newRegExpObject(data->stringAt(re->stringIndex), flags));
|
||||
runtimeRegularExpressions[i] = engine->newRegExpObject(data->stringAt(re->stringIndex), flags);
|
||||
}
|
||||
|
||||
if (data->lookupTableSize) {
|
||||
|
@ -111,7 +109,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
|
|||
l->classList[j] = 0;
|
||||
l->level = -1;
|
||||
l->index = UINT_MAX;
|
||||
l->name = runtimeStrings[compiledLookups[i].nameIndex];
|
||||
l->nameIndex = compiledLookups[i].nameIndex;
|
||||
if (type == CompiledData::Lookup::Type_IndexedGetter || type == CompiledData::Lookup::Type_IndexedSetter)
|
||||
l->engine = engine;
|
||||
}
|
||||
|
@ -119,13 +117,15 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
|
|||
|
||||
if (data->jsClassTableSize) {
|
||||
runtimeClasses = (QV4::InternalClass**)malloc(data->jsClassTableSize * sizeof(QV4::InternalClass*));
|
||||
Scope scope(engine);
|
||||
ScopedString memberName(scope);
|
||||
|
||||
for (uint i = 0; i < data->jsClassTableSize; ++i) {
|
||||
int memberCount = 0;
|
||||
const CompiledData::JSClassMember *member = data->jsClassAt(i, &memberCount);
|
||||
QV4::InternalClass *klass = engine->objectClass;
|
||||
for (int j = 0; j < memberCount; ++j, ++member)
|
||||
klass = klass->addMember(runtimeStrings[member->nameOffset], member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
|
||||
klass = klass->addMember((memberName = runtimeStrings[member->nameOffset]), member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
|
||||
|
||||
runtimeClasses[i] = klass;
|
||||
}
|
||||
|
@ -174,11 +174,6 @@ void CompilationUnit::markObjects(QV4::ExecutionEngine *e)
|
|||
for (uint i = 0; i < data->regexpTableSize; ++i)
|
||||
runtimeRegularExpressions[i].mark(e);
|
||||
}
|
||||
if (runtimeLookups) {
|
||||
for (uint i = 0; i < data->lookupTableSize; ++i)
|
||||
if (runtimeLookups[i].name)
|
||||
runtimeLookups[i].name->mark(e);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // V4_BOOTSTRAP
|
||||
|
|
|
@ -587,7 +587,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
|
|||
ExecutionEngine *engine;
|
||||
QString fileName() const { return data->stringAt(data->sourceFileIndex); }
|
||||
|
||||
QV4::String **runtimeStrings; // Array
|
||||
QV4::Heap::String **runtimeStrings; // Array
|
||||
QV4::Lookup *runtimeLookups;
|
||||
QV4::Value *runtimeRegularExpressions;
|
||||
QV4::InternalClass **runtimeClasses;
|
||||
|
|
|
@ -219,11 +219,8 @@ Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &s
|
|||
|
||||
void Assembler::loadStringRef(RegisterID reg, const QString &string)
|
||||
{
|
||||
loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), reg);
|
||||
loadPtr(Address(reg, qOffsetOf(QV4::Heap::ExecutionContext, compilationUnit)), reg);
|
||||
loadPtr(Address(reg, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
|
||||
const int id = _isel->registerString(string);
|
||||
loadPtr(Address(reg, id * sizeof(QV4::String*)), reg);
|
||||
move(TrustedImm32(id), reg);
|
||||
}
|
||||
|
||||
void Assembler::storeValue(QV4::Primitive value, IR::Expr *destination)
|
||||
|
|
|
@ -316,8 +316,8 @@ public:
|
|||
{}
|
||||
IR::Expr *value;
|
||||
};
|
||||
struct PointerToString {
|
||||
explicit PointerToString(const QString &string) : string(string) {}
|
||||
struct StringToIndex {
|
||||
explicit StringToIndex(const QString &string) : string(string) {}
|
||||
QString string;
|
||||
};
|
||||
struct Reference {
|
||||
|
@ -446,7 +446,7 @@ public:
|
|||
loadArgumentInRegister(addr, dest, argumentNumber);
|
||||
}
|
||||
}
|
||||
void loadArgumentInRegister(PointerToString temp, RegisterID dest, int argumentNumber)
|
||||
void loadArgumentInRegister(StringToIndex temp, RegisterID dest, int argumentNumber)
|
||||
{
|
||||
Q_UNUSED(argumentNumber);
|
||||
loadStringRef(dest, temp.string);
|
||||
|
@ -662,7 +662,7 @@ public:
|
|||
}
|
||||
|
||||
template <int StackSlot>
|
||||
void loadArgumentOnStack(PointerToString temp, int argumentNumber)
|
||||
void loadArgumentOnStack(StringToIndex temp, int argumentNumber)
|
||||
{
|
||||
Q_UNUSED(argumentNumber);
|
||||
loadStringRef(ScratchRegister, temp.string);
|
||||
|
|
|
@ -313,7 +313,7 @@ void InstructionSelection::callBuiltinInvalid(IR::Name *func, IR::ExprList *args
|
|||
} else {
|
||||
generateFunctionCall(result, Runtime::callActivationProperty,
|
||||
Assembler::EngineRegister,
|
||||
Assembler::PointerToString(*func->id),
|
||||
Assembler::StringToIndex(*func->id),
|
||||
baseAddressForCallData());
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ void InstructionSelection::callBuiltinTypeofMember(IR::Expr *base, const QString
|
|||
IR::Expr *result)
|
||||
{
|
||||
generateFunctionCall(result, Runtime::typeofMember, Assembler::EngineRegister,
|
||||
Assembler::PointerToValue(base), Assembler::PointerToString(name));
|
||||
Assembler::PointerToValue(base), Assembler::StringToIndex(name));
|
||||
}
|
||||
|
||||
void InstructionSelection::callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index,
|
||||
|
@ -336,7 +336,7 @@ void InstructionSelection::callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *
|
|||
void InstructionSelection::callBuiltinTypeofName(const QString &name, IR::Expr *result)
|
||||
{
|
||||
generateFunctionCall(result, Runtime::typeofName, Assembler::EngineRegister,
|
||||
Assembler::PointerToString(name));
|
||||
Assembler::StringToIndex(name));
|
||||
}
|
||||
|
||||
void InstructionSelection::callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result)
|
||||
|
@ -348,7 +348,7 @@ void InstructionSelection::callBuiltinTypeofValue(IR::Expr *value, IR::Expr *res
|
|||
void InstructionSelection::callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result)
|
||||
{
|
||||
generateFunctionCall(result, Runtime::deleteMember, Assembler::EngineRegister,
|
||||
Assembler::Reference(base), Assembler::PointerToString(name));
|
||||
Assembler::Reference(base), Assembler::StringToIndex(name));
|
||||
}
|
||||
|
||||
void InstructionSelection::callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index,
|
||||
|
@ -361,7 +361,7 @@ void InstructionSelection::callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *
|
|||
void InstructionSelection::callBuiltinDeleteName(const QString &name, IR::Expr *result)
|
||||
{
|
||||
generateFunctionCall(result, Runtime::deleteName, Assembler::EngineRegister,
|
||||
Assembler::PointerToString(name));
|
||||
Assembler::StringToIndex(name));
|
||||
}
|
||||
|
||||
void InstructionSelection::callBuiltinDeleteValue(IR::Expr *result)
|
||||
|
@ -388,7 +388,7 @@ void InstructionSelection::callBuiltinUnwindException(IR::Expr *result)
|
|||
|
||||
void InstructionSelection::callBuiltinPushCatchScope(const QString &exceptionName)
|
||||
{
|
||||
generateFunctionCall(Assembler::Void, Runtime::pushCatchScope, Assembler::EngineRegister, Assembler::PointerToString(exceptionName));
|
||||
generateFunctionCall(Assembler::Void, Runtime::pushCatchScope, Assembler::EngineRegister, Assembler::StringToIndex(exceptionName));
|
||||
}
|
||||
|
||||
void InstructionSelection::callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result)
|
||||
|
@ -422,7 +422,7 @@ void InstructionSelection::callBuiltinPopScope()
|
|||
void InstructionSelection::callBuiltinDeclareVar(bool deletable, const QString &name)
|
||||
{
|
||||
generateFunctionCall(Assembler::Void, Runtime::declareVar, Assembler::EngineRegister,
|
||||
Assembler::TrustedImm32(deletable), Assembler::PointerToString(name));
|
||||
Assembler::TrustedImm32(deletable), Assembler::StringToIndex(name));
|
||||
}
|
||||
|
||||
void InstructionSelection::callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args)
|
||||
|
@ -575,7 +575,7 @@ void InstructionSelection::loadQmlScopeObject(IR::Expr *temp)
|
|||
|
||||
void InstructionSelection::loadQmlSingleton(const QString &name, IR::Expr *temp)
|
||||
{
|
||||
generateFunctionCall(temp, Runtime::getQmlSingleton, Assembler::EngineRegister, Assembler::PointerToString(name));
|
||||
generateFunctionCall(temp, Runtime::getQmlSingleton, Assembler::EngineRegister, Assembler::StringToIndex(name));
|
||||
}
|
||||
|
||||
void InstructionSelection::loadConst(IR::Const *sourceConst, IR::Expr *target)
|
||||
|
@ -632,14 +632,14 @@ void InstructionSelection::getActivationProperty(const IR::Name *name, IR::Expr
|
|||
generateLookupCall(target, index, qOffsetOf(QV4::Lookup, globalGetter), Assembler::EngineRegister, Assembler::Void);
|
||||
return;
|
||||
}
|
||||
generateFunctionCall(target, Runtime::getActivationProperty, Assembler::EngineRegister, Assembler::PointerToString(*name->id));
|
||||
generateFunctionCall(target, Runtime::getActivationProperty, Assembler::EngineRegister, Assembler::StringToIndex(*name->id));
|
||||
}
|
||||
|
||||
void InstructionSelection::setActivationProperty(IR::Expr *source, const QString &targetName)
|
||||
{
|
||||
// ### should use a lookup call here
|
||||
generateFunctionCall(Assembler::Void, Runtime::setActivationProperty,
|
||||
Assembler::EngineRegister, Assembler::PointerToString(targetName), Assembler::PointerToValue(source));
|
||||
Assembler::EngineRegister, Assembler::StringToIndex(targetName), Assembler::PointerToValue(source));
|
||||
}
|
||||
|
||||
void InstructionSelection::initClosure(IR::Closure *closure, IR::Expr *target)
|
||||
|
@ -652,10 +652,10 @@ void InstructionSelection::getProperty(IR::Expr *base, const QString &name, IR::
|
|||
{
|
||||
if (useFastLookups) {
|
||||
uint index = registerGetterLookup(name);
|
||||
generateLookupCall(target, index, qOffsetOf(QV4::Lookup, getter), Assembler::PointerToValue(base), Assembler::Void);
|
||||
generateLookupCall(target, index, qOffsetOf(QV4::Lookup, getter), Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::Void);
|
||||
} else {
|
||||
generateFunctionCall(target, Runtime::getProperty, Assembler::EngineRegister,
|
||||
Assembler::PointerToValue(base), Assembler::PointerToString(name));
|
||||
Assembler::PointerToValue(base), Assembler::StringToIndex(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,11 +677,12 @@ void InstructionSelection::setProperty(IR::Expr *source, IR::Expr *targetBase,
|
|||
if (useFastLookups) {
|
||||
uint index = registerSetterLookup(targetName);
|
||||
generateLookupCall(Assembler::Void, index, qOffsetOf(QV4::Lookup, setter),
|
||||
Assembler::EngineRegister,
|
||||
Assembler::PointerToValue(targetBase),
|
||||
Assembler::PointerToValue(source));
|
||||
} else {
|
||||
generateFunctionCall(Assembler::Void, Runtime::setProperty, Assembler::EngineRegister,
|
||||
Assembler::PointerToValue(targetBase), Assembler::PointerToString(targetName),
|
||||
Assembler::PointerToValue(targetBase), Assembler::StringToIndex(targetName),
|
||||
Assembler::PointerToValue(source));
|
||||
}
|
||||
}
|
||||
|
@ -894,7 +895,7 @@ void InstructionSelection::callProperty(IR::Expr *base, const QString &name, IR:
|
|||
baseAddressForCallData());
|
||||
} else {
|
||||
generateFunctionCall(result, Runtime::callProperty, Assembler::EngineRegister,
|
||||
Assembler::PointerToString(name),
|
||||
Assembler::StringToIndex(name),
|
||||
baseAddressForCallData());
|
||||
}
|
||||
}
|
||||
|
@ -1222,7 +1223,7 @@ void InstructionSelection::constructActivationProperty(IR::Name *func, IR::ExprL
|
|||
|
||||
generateFunctionCall(result, Runtime::constructActivationProperty,
|
||||
Assembler::EngineRegister,
|
||||
Assembler::PointerToString(*func->id),
|
||||
Assembler::StringToIndex(*func->id),
|
||||
baseAddressForCallData());
|
||||
}
|
||||
|
||||
|
@ -1240,7 +1241,7 @@ void InstructionSelection::constructProperty(IR::Expr *base, const QString &name
|
|||
}
|
||||
|
||||
generateFunctionCall(result, Runtime::constructProperty, Assembler::EngineRegister,
|
||||
Assembler::PointerToString(name),
|
||||
Assembler::StringToIndex(name),
|
||||
baseAddressForCallData());
|
||||
}
|
||||
|
||||
|
|
|
@ -387,7 +387,7 @@ ReturnedValue ExecutionContext::getProperty(String *name)
|
|||
return v.asReturnedValue();
|
||||
}
|
||||
if (f->function() && f->function()->isNamedExpression()
|
||||
&& name->equals(f->function()->name()))
|
||||
&& name->equals(ScopedString(scope, f->function()->name())))
|
||||
return f.asReturnedValue();
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base)
|
|||
}
|
||||
}
|
||||
if (f->function() && f->function()->isNamedExpression()
|
||||
&& name->equals(f->function()->name()))
|
||||
&& name->equals(ScopedString(scope, f->function()->name())))
|
||||
return c->d()->function->asReturnedValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -337,21 +337,21 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
|
|||
|
||||
sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass));
|
||||
|
||||
objectCtor = Value::fromHeapObject(memoryManager->alloc<ObjectCtor>(rootContext));
|
||||
stringCtor = Value::fromHeapObject(memoryManager->alloc<StringCtor>(rootContext));
|
||||
numberCtor = Value::fromHeapObject(memoryManager->alloc<NumberCtor>(rootContext));
|
||||
booleanCtor = Value::fromHeapObject(memoryManager->alloc<BooleanCtor>(rootContext));
|
||||
arrayCtor = Value::fromHeapObject(memoryManager->alloc<ArrayCtor>(rootContext));
|
||||
functionCtor = Value::fromHeapObject(memoryManager->alloc<FunctionCtor>(rootContext));
|
||||
dateCtor = Value::fromHeapObject(memoryManager->alloc<DateCtor>(rootContext));
|
||||
regExpCtor = Value::fromHeapObject(memoryManager->alloc<RegExpCtor>(rootContext));
|
||||
errorCtor = Value::fromHeapObject(memoryManager->alloc<ErrorCtor>(rootContext));
|
||||
evalErrorCtor = Value::fromHeapObject(memoryManager->alloc<EvalErrorCtor>(rootContext));
|
||||
rangeErrorCtor = Value::fromHeapObject(memoryManager->alloc<RangeErrorCtor>(rootContext));
|
||||
referenceErrorCtor = Value::fromHeapObject(memoryManager->alloc<ReferenceErrorCtor>(rootContext));
|
||||
syntaxErrorCtor = Value::fromHeapObject(memoryManager->alloc<SyntaxErrorCtor>(rootContext));
|
||||
typeErrorCtor = Value::fromHeapObject(memoryManager->alloc<TypeErrorCtor>(rootContext));
|
||||
uRIErrorCtor = Value::fromHeapObject(memoryManager->alloc<URIErrorCtor>(rootContext));
|
||||
objectCtor = memoryManager->alloc<ObjectCtor>(rootContext);
|
||||
stringCtor = memoryManager->alloc<StringCtor>(rootContext);
|
||||
numberCtor = memoryManager->alloc<NumberCtor>(rootContext);
|
||||
booleanCtor = memoryManager->alloc<BooleanCtor>(rootContext);
|
||||
arrayCtor = memoryManager->alloc<ArrayCtor>(rootContext);
|
||||
functionCtor = memoryManager->alloc<FunctionCtor>(rootContext);
|
||||
dateCtor = memoryManager->alloc<DateCtor>(rootContext);
|
||||
regExpCtor = memoryManager->alloc<RegExpCtor>(rootContext);
|
||||
errorCtor = memoryManager->alloc<ErrorCtor>(rootContext);
|
||||
evalErrorCtor = memoryManager->alloc<EvalErrorCtor>(rootContext);
|
||||
rangeErrorCtor = memoryManager->alloc<RangeErrorCtor>(rootContext);
|
||||
referenceErrorCtor = memoryManager->alloc<ReferenceErrorCtor>(rootContext);
|
||||
syntaxErrorCtor = memoryManager->alloc<SyntaxErrorCtor>(rootContext);
|
||||
typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(rootContext);
|
||||
uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(rootContext);
|
||||
|
||||
static_cast<ObjectPrototype *>(objectPrototype.getPointer())->init(this, objectCtor.asObject());
|
||||
static_cast<StringPrototype *>(stringPrototype.getPointer())->init(this, stringCtor.asObject());
|
||||
|
@ -375,18 +375,18 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
|
|||
|
||||
// typed arrays
|
||||
|
||||
arrayBufferCtor = Value::fromHeapObject(memoryManager->alloc<ArrayBufferCtor>(rootContext));
|
||||
arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(rootContext);
|
||||
Scoped<ArrayBufferPrototype> arrayBufferPrototype(scope, memoryManager->alloc<ArrayBufferPrototype>(objectClass));
|
||||
arrayBufferPrototype->init(this, arrayBufferCtor.asObject());
|
||||
arrayBufferClass = InternalClass::create(this, ArrayBuffer::staticVTable(), arrayBufferPrototype);
|
||||
|
||||
dataViewCtor = Value::fromHeapObject(memoryManager->alloc<DataViewCtor>(rootContext));
|
||||
dataViewCtor = memoryManager->alloc<DataViewCtor>(rootContext);
|
||||
Scoped<DataViewPrototype> dataViewPrototype(scope, memoryManager->alloc<DataViewPrototype>(objectClass));
|
||||
dataViewPrototype->init(this, dataViewCtor.asObject());
|
||||
dataViewClass = InternalClass::create(this, DataView::staticVTable(), dataViewPrototype);
|
||||
|
||||
for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
|
||||
typedArrayCtors[i] = Value::fromHeapObject(memoryManager->alloc<TypedArrayCtor>(rootContext, Heap::TypedArray::Type(i)));
|
||||
typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(rootContext, Heap::TypedArray::Type(i));
|
||||
Scoped<TypedArrayPrototype> typedArrayPrototype(scope, memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i)));
|
||||
typedArrayPrototype->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject()));
|
||||
typedArrayClasses[i] = InternalClass::create(this, TypedArray::staticVTable(), typedArrayPrototype);
|
||||
|
|
|
@ -104,7 +104,7 @@ public:
|
|||
}
|
||||
|
||||
void pushForGC(Heap::Base *m) {
|
||||
*jsStackTop = Value::fromHeapObject(m);
|
||||
*jsStackTop = m;
|
||||
++jsStackTop;
|
||||
}
|
||||
Heap::Base *popForGC() {
|
||||
|
|
|
@ -56,9 +56,9 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
|
|||
const quint32 *formalsIndices = compiledFunction->formalsTable();
|
||||
// iterate backwards, so we get the right ordering for duplicate names
|
||||
Scope scope(engine);
|
||||
ScopedString s(scope);
|
||||
ScopedString arg(scope);
|
||||
for (int i = static_cast<int>(compiledFunction->nFormals - 1); i >= 0; --i) {
|
||||
String *arg = compilationUnit->runtimeStrings[formalsIndices[i]];
|
||||
arg = compilationUnit->runtimeStrings[formalsIndices[i]];
|
||||
while (1) {
|
||||
InternalClass *newClass = internalClass->addMember(arg, Attr_NotConfigurable);
|
||||
if (newClass != internalClass) {
|
||||
|
@ -66,13 +66,14 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
|
|||
break;
|
||||
}
|
||||
// duplicate arguments, need some trick to store them
|
||||
arg = (s = engine->memoryManager->alloc<String>(engine, arg->d(), engine->newString(QString(0xfffe)))).getPointer();
|
||||
arg = engine->memoryManager->alloc<String>(engine, arg->d(), engine->newString(QString(0xfffe)));
|
||||
}
|
||||
}
|
||||
|
||||
const quint32 *localsIndices = compiledFunction->localsTable();
|
||||
ScopedString local(scope);
|
||||
for (quint32 i = 0; i < compiledFunction->nLocals; ++i) {
|
||||
String *local = compilationUnit->runtimeStrings[localsIndices[i]];
|
||||
local = compilationUnit->runtimeStrings[localsIndices[i]];
|
||||
internalClass = internalClass->addMember(local, Attr_NotConfigurable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ struct Q_QML_EXPORT Function {
|
|||
ReturnedValue (*codePtr)(ExecutionEngine *, const uchar *));
|
||||
~Function();
|
||||
|
||||
inline String *name() {
|
||||
inline Heap::String *name() {
|
||||
return compilationUnit->runtimeStrings[compiledFunction->nameIndex];
|
||||
}
|
||||
inline QString sourceFile() const { return compilationUnit->fileName(); }
|
||||
|
|
|
@ -71,6 +71,16 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String *
|
|||
f->init(name, createProto);
|
||||
}
|
||||
|
||||
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, Function *function, bool createProto)
|
||||
: Heap::Object(scope->d()->engine->functionClass)
|
||||
, scope(scope->d())
|
||||
{
|
||||
Scope s(scope->engine());
|
||||
ScopedString name(s, function->name());
|
||||
ScopedFunctionObject f(s, this);
|
||||
f->init(name, createProto);
|
||||
}
|
||||
|
||||
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString &name, bool createProto)
|
||||
: Heap::Object(scope->d()->engine->functionClass)
|
||||
, scope(scope->d())
|
||||
|
@ -429,7 +439,7 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
|
|||
DEFINE_OBJECT_VTABLE(SimpleScriptFunction);
|
||||
|
||||
Heap::SimpleScriptFunction::SimpleScriptFunction(QV4::ExecutionContext *scope, Function *function, bool createProto)
|
||||
: Heap::FunctionObject(scope, function->name(), createProto)
|
||||
: Heap::FunctionObject(scope, function, createProto)
|
||||
{
|
||||
setVTable(QV4::SimpleScriptFunction::staticVTable());
|
||||
|
||||
|
@ -468,7 +478,7 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
|
|||
Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that));
|
||||
|
||||
InternalClass *ic = f->internalClassForConstructor();
|
||||
callData->thisObject = Value::fromHeapObject(v4->newObject(ic));
|
||||
callData->thisObject = v4->newObject(ic);
|
||||
|
||||
ExecutionContext *context = v4->currentContext();
|
||||
ExecutionContextSaver ctxSaver(context);
|
||||
|
|
|
@ -58,6 +58,7 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
|
|||
};
|
||||
|
||||
FunctionObject(QV4::ExecutionContext *scope, QV4::String *name, bool createProto = false);
|
||||
FunctionObject(QV4::ExecutionContext *scope, QV4::Function *function, bool createProto = false);
|
||||
FunctionObject(QV4::ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
|
||||
FunctionObject(ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
|
||||
FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name);
|
||||
|
|
|
@ -709,7 +709,7 @@ QString Stringify::Str(const QString &key, ValueRef v)
|
|||
if (!!toJSON) {
|
||||
ScopedCallData callData(scope, 1);
|
||||
callData->thisObject = value;
|
||||
callData->args[0] = Value::fromHeapObject(ctx->d()->engine->newString(key));
|
||||
callData->args[0] = ctx->d()->engine->newString(key);
|
||||
value = toJSON->call(callData);
|
||||
}
|
||||
}
|
||||
|
@ -718,7 +718,7 @@ QString Stringify::Str(const QString &key, ValueRef v)
|
|||
ScopedObject holder(scope, ctx->d()->engine->newObject());
|
||||
holder->put(scope.engine, QString(), value);
|
||||
ScopedCallData callData(scope, 2);
|
||||
callData->args[0] = Value::fromHeapObject(ctx->d()->engine->newString(key));
|
||||
callData->args[0] = ctx->d()->engine->newString(key);
|
||||
callData->args[1] = value;
|
||||
callData->thisObject = holder;
|
||||
value = replacerFunction->call(callData);
|
||||
|
|
|
@ -41,6 +41,9 @@ using namespace QV4;
|
|||
|
||||
ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttributes *attrs)
|
||||
{
|
||||
ExecutionEngine *engine = obj->engine();
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
int i = 0;
|
||||
while (i < Size && obj) {
|
||||
classList[i] = obj->internalClass();
|
||||
|
@ -72,6 +75,9 @@ ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttribute
|
|||
ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
|
||||
{
|
||||
Object *thisObject = obj;
|
||||
ExecutionEngine *engine = obj->engine();
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
int i = 0;
|
||||
while (i < Size && obj) {
|
||||
classList[i] = obj->internalClass();
|
||||
|
@ -228,12 +234,11 @@ void Lookup::indexedSetterObjectInt(Lookup *l, const ValueRef object, const Valu
|
|||
indexedSetterFallback(l, object, index, v);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (Object *o = object->asObject())
|
||||
return o->getLookup(l);
|
||||
|
||||
ExecutionEngine *engine = l->name->engine();
|
||||
Object *proto;
|
||||
switch (object->type()) {
|
||||
case Value::Undefined_Type:
|
||||
|
@ -242,15 +247,18 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object)
|
|||
case Value::Boolean_Type:
|
||||
proto = engine->booleanClass->prototype;
|
||||
break;
|
||||
case Value::Managed_Type:
|
||||
case Value::Managed_Type: {
|
||||
Q_ASSERT(object->isString());
|
||||
proto = engine->stringObjectClass->prototype;
|
||||
if (l->name->equals(engine->id_length.getPointer())) {
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
if (name->equals(engine->id_length.getPointer())) {
|
||||
// special case, as the property is on the object itself
|
||||
l->getter = stringLengthGetter;
|
||||
return stringLengthGetter(l, object);
|
||||
return stringLengthGetter(l, engine, object);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Value::Integer_Type:
|
||||
default: // Number
|
||||
proto = engine->numberClass->prototype;
|
||||
|
@ -279,7 +287,7 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object)
|
|||
return Encode::undefined();
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getterTwoClasses(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getterTwoClasses(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
Lookup l1 = *l;
|
||||
|
||||
|
@ -312,20 +320,20 @@ ReturnedValue Lookup::getterTwoClasses(Lookup *l, const ValueRef object)
|
|||
}
|
||||
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getterFallback(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getterFallback(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
QV4::Scope scope(l->name->engine());
|
||||
QV4::Scope scope(engine);
|
||||
QV4::ScopedObject o(scope, object->toObject(scope.engine));
|
||||
if (!o)
|
||||
return Encode::undefined();
|
||||
QV4::ScopedString s(scope, l->name);
|
||||
return o->get(s.getPointer());
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
return o->get(name);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getter0(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -334,10 +342,10 @@ ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object)
|
|||
if (l->classList[0] == o->internalClass())
|
||||
return o->memberData()->data()[l->index].asReturnedValue();
|
||||
}
|
||||
return getterTwoClasses(l, object);
|
||||
return getterTwoClasses(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -347,10 +355,10 @@ ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object)
|
|||
l->classList[1] == o->prototype()->internalClass())
|
||||
return o->prototype()->memberData()->data()[l->index].asReturnedValue();
|
||||
}
|
||||
return getterTwoClasses(l, object);
|
||||
return getterTwoClasses(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getter2(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -366,10 +374,10 @@ ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object)
|
|||
}
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getter0getter0(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getter0getter0(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -381,10 +389,10 @@ ReturnedValue Lookup::getter0getter0(Lookup *l, const ValueRef object)
|
|||
return o->memberData()->data()[l->index2].asReturnedValue();
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getter0getter1(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getter0getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -397,10 +405,10 @@ ReturnedValue Lookup::getter0getter1(Lookup *l, const ValueRef object)
|
|||
return o->prototype()->memberData()->data()[l->index2].asReturnedValue();
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getter1getter1(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getter1getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -412,14 +420,14 @@ ReturnedValue Lookup::getter1getter1(Lookup *l, const ValueRef object)
|
|||
if (l->classList[2] == o->internalClass() &&
|
||||
l->classList[3] == o->prototype()->internalClass())
|
||||
return o->prototype()->memberData()->data()[l->index2].asReturnedValue();
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
|
||||
|
||||
ReturnedValue Lookup::getterAccessor0(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getterAccessor0(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -437,10 +445,10 @@ ReturnedValue Lookup::getterAccessor0(Lookup *l, const ValueRef object)
|
|||
}
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getterAccessor1(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getterAccessor1(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -459,10 +467,10 @@ ReturnedValue Lookup::getterAccessor1(Lookup *l, const ValueRef object)
|
|||
}
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::getterAccessor2(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::getterAccessor2(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->isManaged()) {
|
||||
// we can safely cast to a QV4::Object here. If object is actually a string,
|
||||
|
@ -486,10 +494,10 @@ ReturnedValue Lookup::getterAccessor2(Lookup *l, const ValueRef object)
|
|||
}
|
||||
}
|
||||
l->getter = getterFallback;
|
||||
return getterFallback(l, object);
|
||||
return getterFallback(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::primitiveGetter0(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::primitiveGetter0(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->type() == l->type) {
|
||||
Object *o = l->proto;
|
||||
|
@ -497,10 +505,10 @@ ReturnedValue Lookup::primitiveGetter0(Lookup *l, const ValueRef object)
|
|||
return o->memberData()->data()[l->index].asReturnedValue();
|
||||
}
|
||||
l->getter = getterGeneric;
|
||||
return getterGeneric(l, object);
|
||||
return getterGeneric(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::primitiveGetter1(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::primitiveGetter1(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->type() == l->type) {
|
||||
Object *o = l->proto;
|
||||
|
@ -509,10 +517,10 @@ ReturnedValue Lookup::primitiveGetter1(Lookup *l, const ValueRef object)
|
|||
return o->prototype()->memberData()->data()[l->index].asReturnedValue();
|
||||
}
|
||||
l->getter = getterGeneric;
|
||||
return getterGeneric(l, object);
|
||||
return getterGeneric(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->type() == l->type) {
|
||||
Object *o = l->proto;
|
||||
|
@ -528,10 +536,10 @@ ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, const ValueRef object)
|
|||
}
|
||||
}
|
||||
l->getter = getterGeneric;
|
||||
return getterGeneric(l, object);
|
||||
return getterGeneric(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (object->type() == l->type) {
|
||||
Object *o = l->proto;
|
||||
|
@ -548,25 +556,25 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, const ValueRef object)
|
|||
}
|
||||
}
|
||||
l->getter = getterGeneric;
|
||||
return getterGeneric(l, object);
|
||||
return getterGeneric(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::stringLengthGetter(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::stringLengthGetter(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (String *s = object->asString())
|
||||
return Encode(s->d()->length());
|
||||
|
||||
l->getter = getterGeneric;
|
||||
return getterGeneric(l, object);
|
||||
return getterGeneric(l, engine, object);
|
||||
}
|
||||
|
||||
ReturnedValue Lookup::arrayLengthGetter(Lookup *l, const ValueRef object)
|
||||
ReturnedValue Lookup::arrayLengthGetter(Lookup *l, ExecutionEngine *engine, const ValueRef object)
|
||||
{
|
||||
if (ArrayObject *a = object->asArrayObject())
|
||||
return a->memberData()->data()[Heap::ArrayObject::LengthPropertyIndex].asReturnedValue();
|
||||
|
||||
l->getter = getterGeneric;
|
||||
return getterGeneric(l, object);
|
||||
return getterGeneric(l, engine, object);
|
||||
}
|
||||
|
||||
|
||||
|
@ -595,7 +603,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine)
|
|||
}
|
||||
}
|
||||
Scope scope(engine);
|
||||
Scoped<String> n(scope, l->name);
|
||||
Scoped<String> n(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
return engine->throwReferenceError(n);
|
||||
}
|
||||
|
||||
|
@ -694,22 +702,22 @@ ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine)
|
|||
return globalGetterGeneric(l, engine);
|
||||
}
|
||||
|
||||
void Lookup::setterGeneric(Lookup *l, const ValueRef object, const ValueRef value)
|
||||
void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value)
|
||||
{
|
||||
Scope scope(l->name->engine());
|
||||
Scope scope(engine);
|
||||
ScopedObject o(scope, object);
|
||||
if (!o) {
|
||||
o = RuntimeHelpers::convertToObject(scope.engine, object);
|
||||
if (!o) // type error
|
||||
return;
|
||||
ScopedString s(scope, l->name);
|
||||
o->put(s.getPointer(), value);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
o->put(name, value);
|
||||
return;
|
||||
}
|
||||
o->setLookup(l, value);
|
||||
}
|
||||
|
||||
void Lookup::setterTwoClasses(Lookup *l, const ValueRef object, const ValueRef value)
|
||||
void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value)
|
||||
{
|
||||
Lookup l1 = *l;
|
||||
|
||||
|
@ -725,20 +733,20 @@ void Lookup::setterTwoClasses(Lookup *l, const ValueRef object, const ValueRef v
|
|||
}
|
||||
|
||||
l->setter = setterFallback;
|
||||
setterFallback(l, object, value);
|
||||
setterFallback(l, engine, object, value);
|
||||
}
|
||||
|
||||
void Lookup::setterFallback(Lookup *l, const ValueRef object, const ValueRef value)
|
||||
void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value)
|
||||
{
|
||||
QV4::Scope scope(l->name->engine());
|
||||
QV4::Scope scope(engine);
|
||||
QV4::ScopedObject o(scope, object->toObject(scope.engine));
|
||||
if (o) {
|
||||
QV4::ScopedString s(scope, l->name);
|
||||
o->put(s.getPointer(), value);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
o->put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
void Lookup::setter0(Lookup *l, const ValueRef object, const ValueRef value)
|
||||
void Lookup::setter0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value)
|
||||
{
|
||||
Object *o = static_cast<Object *>(object->asManaged());
|
||||
if (o && o->internalClass() == l->classList[0]) {
|
||||
|
@ -746,10 +754,10 @@ void Lookup::setter0(Lookup *l, const ValueRef object, const ValueRef value)
|
|||
return;
|
||||
}
|
||||
|
||||
setterTwoClasses(l, object, value);
|
||||
setterTwoClasses(l, engine, object, value);
|
||||
}
|
||||
|
||||
void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef value)
|
||||
void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value)
|
||||
{
|
||||
Object *o = static_cast<Object *>(object->asManaged());
|
||||
if (o && o->internalClass() == l->classList[0]) {
|
||||
|
@ -763,10 +771,10 @@ void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef valu
|
|||
}
|
||||
|
||||
l->setter = setterFallback;
|
||||
setterFallback(l, object, value);
|
||||
setterFallback(l, engine, object, value);
|
||||
}
|
||||
|
||||
void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef value)
|
||||
void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value)
|
||||
{
|
||||
Object *o = static_cast<Object *>(object->asManaged());
|
||||
if (o && o->internalClass() == l->classList[0]) {
|
||||
|
@ -781,10 +789,10 @@ void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef valu
|
|||
}
|
||||
|
||||
l->setter = setterFallback;
|
||||
setterFallback(l, object, value);
|
||||
setterFallback(l, engine, object, value);
|
||||
}
|
||||
|
||||
void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef value)
|
||||
void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value)
|
||||
{
|
||||
Object *o = static_cast<Object *>(object->asManaged());
|
||||
if (o && o->internalClass() == l->classList[0]) {
|
||||
|
@ -802,10 +810,10 @@ void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef valu
|
|||
}
|
||||
|
||||
l->setter = setterFallback;
|
||||
setterFallback(l, object, value);
|
||||
setterFallback(l, engine, object, value);
|
||||
}
|
||||
|
||||
void Lookup::setter0setter0(Lookup *l, const ValueRef object, const ValueRef value)
|
||||
void Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value)
|
||||
{
|
||||
Object *o = static_cast<Object *>(object->asManaged());
|
||||
if (o) {
|
||||
|
@ -820,7 +828,7 @@ void Lookup::setter0setter0(Lookup *l, const ValueRef object, const ValueRef val
|
|||
}
|
||||
|
||||
l->setter = setterFallback;
|
||||
setterFallback(l, object, value);
|
||||
setterFallback(l, engine, object, value);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -49,9 +49,9 @@ struct Lookup {
|
|||
union {
|
||||
ReturnedValue (*indexedGetter)(Lookup *l, const ValueRef object, const ValueRef index);
|
||||
void (*indexedSetter)(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v);
|
||||
ReturnedValue (*getter)(Lookup *l, const ValueRef object);
|
||||
ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
ReturnedValue (*globalGetter)(Lookup *l, ExecutionEngine *engine);
|
||||
void (*setter)(Lookup *l, const ValueRef object, const ValueRef v);
|
||||
void (*setter)(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef v);
|
||||
};
|
||||
union {
|
||||
ExecutionEngine *engine;
|
||||
|
@ -68,7 +68,7 @@ struct Lookup {
|
|||
uint index2;
|
||||
};
|
||||
uint index;
|
||||
String *name;
|
||||
uint nameIndex;
|
||||
|
||||
static ReturnedValue indexedGetterGeneric(Lookup *l, const ValueRef object, const ValueRef index);
|
||||
static ReturnedValue indexedGetterFallback(Lookup *l, const ValueRef object, const ValueRef index);
|
||||
|
@ -78,26 +78,26 @@ struct Lookup {
|
|||
static void indexedSetterFallback(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef value);
|
||||
static void indexedSetterObjectInt(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v);
|
||||
|
||||
static ReturnedValue getterGeneric(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getterTwoClasses(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getterFallback(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getterGeneric(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getterTwoClasses(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getterFallback(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
|
||||
static ReturnedValue getter0(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getter1(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getter2(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getter0getter0(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getter0getter1(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getter1getter1(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getterAccessor0(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getterAccessor1(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getterAccessor2(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue getter0(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getter2(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getter0getter0(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getter0getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getter1getter1(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getterAccessor0(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getterAccessor1(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue getterAccessor2(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
|
||||
static ReturnedValue primitiveGetter0(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue primitiveGetter1(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue primitiveGetterAccessor0(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue primitiveGetterAccessor1(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue stringLengthGetter(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue arrayLengthGetter(Lookup *l, const ValueRef object);
|
||||
static ReturnedValue primitiveGetter0(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue primitiveGetter1(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue primitiveGetterAccessor0(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue stringLengthGetter(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
static ReturnedValue arrayLengthGetter(Lookup *l, ExecutionEngine *engine, const ValueRef object);
|
||||
|
||||
static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionEngine *engine);
|
||||
static ReturnedValue globalGetter0(Lookup *l, ExecutionEngine *engine);
|
||||
|
@ -107,14 +107,14 @@ struct Lookup {
|
|||
static ReturnedValue globalGetterAccessor1(Lookup *l, ExecutionEngine *engine);
|
||||
static ReturnedValue globalGetterAccessor2(Lookup *l, ExecutionEngine *engine);
|
||||
|
||||
static void setterGeneric(Lookup *l, const ValueRef object, const ValueRef value);
|
||||
static void setterTwoClasses(Lookup *l, const ValueRef object, const ValueRef value);
|
||||
static void setterFallback(Lookup *l, const ValueRef object, const ValueRef value);
|
||||
static void setter0(Lookup *l, const ValueRef object, const ValueRef value);
|
||||
static void setterInsert0(Lookup *l, const ValueRef object, const ValueRef value);
|
||||
static void setterInsert1(Lookup *l, const ValueRef object, const ValueRef value);
|
||||
static void setterInsert2(Lookup *l, const ValueRef object, const ValueRef value);
|
||||
static void setter0setter0(Lookup *l, const ValueRef object, const ValueRef value);
|
||||
static void setterGeneric(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value);
|
||||
static void setterTwoClasses(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value);
|
||||
static void setterFallback(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value);
|
||||
static void setter0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value);
|
||||
static void setterInsert0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value);
|
||||
static void setterInsert1(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value);
|
||||
static void setterInsert2(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value);
|
||||
static void setter0setter0(Lookup *l, ExecutionEngine *engine, const ValueRef object, const ValueRef value);
|
||||
|
||||
ReturnedValue lookup(ValueRef thisObject, Object *obj, PropertyAttributes *attrs);
|
||||
ReturnedValue lookup(Object *obj, PropertyAttributes *attrs);
|
||||
|
|
|
@ -458,9 +458,10 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
|
|||
{
|
||||
Scope scope(m->engine());
|
||||
ScopedObject o(scope, static_cast<Object *>(m));
|
||||
ScopedString name(scope, scope.engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
|
||||
InternalClass *c = o->internalClass();
|
||||
uint idx = c->find(l->name);
|
||||
uint idx = c->find(name);
|
||||
if (!o->isArrayObject() || idx != Heap::ArrayObject::LengthPropertyIndex) {
|
||||
if (idx != UINT_MAX && o->internalClass()->propertyData[idx].isData() && o->internalClass()->propertyData[idx].isWritable()) {
|
||||
l->classList[0] = o->internalClass();
|
||||
|
@ -476,12 +477,11 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
|
|||
}
|
||||
}
|
||||
|
||||
ScopedString s(scope, l->name);
|
||||
o->put(s.getPointer(), value);
|
||||
o->put(name, value);
|
||||
|
||||
if (o->internalClass() == c)
|
||||
return;
|
||||
idx = o->internalClass()->find(l->name);
|
||||
idx = o->internalClass()->find(name);
|
||||
if (idx == UINT_MAX)
|
||||
return;
|
||||
l->classList[0] = c;
|
||||
|
@ -1150,7 +1150,9 @@ Heap::ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
|
|||
|
||||
ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
|
||||
{
|
||||
if (l->name->equals(m->engine()->id_length)) {
|
||||
Scope scope(m->engine());
|
||||
ScopedString name(scope, m->engine()->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
if (name->equals(m->engine()->id_length)) {
|
||||
// special case, as the property is on the object itself
|
||||
l->getter = Lookup::arrayLengthGetter;
|
||||
ArrayObject *a = static_cast<ArrayObject *>(m);
|
||||
|
|
|
@ -275,10 +275,17 @@ ReturnedValue Runtime::deleteElement(ExecutionEngine *engine, const ValueRef bas
|
|||
}
|
||||
|
||||
ScopedString name(scope, index->toString(engine));
|
||||
return Runtime::deleteMember(engine, base, name.getPointer());
|
||||
return Runtime::deleteMemberString(engine, base, name.getPointer());
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::deleteMember(ExecutionEngine *engine, const ValueRef base, String *name)
|
||||
ReturnedValue Runtime::deleteMember(ExecutionEngine *engine, const ValueRef base, int nameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
return deleteMemberString(engine, base, name);
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::deleteMemberString(ExecutionEngine *engine, const ValueRef base, String *name)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedObject obj(scope, base->toObject(engine));
|
||||
|
@ -287,9 +294,10 @@ ReturnedValue Runtime::deleteMember(ExecutionEngine *engine, const ValueRef base
|
|||
return Encode(obj->deleteProperty(name));
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::deleteName(ExecutionEngine *engine, String *name)
|
||||
ReturnedValue Runtime::deleteName(ExecutionEngine *engine, int nameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
return Encode(engine->currentContext()->deleteProperty(name));
|
||||
}
|
||||
|
||||
|
@ -543,9 +551,10 @@ QV4::ReturnedValue Runtime::addString(ExecutionEngine *engine, const QV4::ValueR
|
|||
return (engine->memoryManager->alloc<String>(engine, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue();
|
||||
}
|
||||
|
||||
void Runtime::setProperty(ExecutionEngine *engine, const ValueRef object, String *name, const ValueRef value)
|
||||
void Runtime::setProperty(ExecutionEngine *engine, const ValueRef object, int nameIndex, const ValueRef value)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
ScopedObject o(scope, object->toObject(engine));
|
||||
if (!o)
|
||||
return;
|
||||
|
@ -639,14 +648,17 @@ ReturnedValue Runtime::foreachNextPropertyName(const ValueRef foreach_iterator)
|
|||
}
|
||||
|
||||
|
||||
void Runtime::setActivationProperty(ExecutionEngine *engine, String *name, const ValueRef value)
|
||||
void Runtime::setActivationProperty(ExecutionEngine *engine, int nameIndex, const ValueRef value)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
engine->currentContext()->setProperty(name, value);
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::getProperty(ExecutionEngine *engine, const ValueRef object, String *name)
|
||||
ReturnedValue Runtime::getProperty(ExecutionEngine *engine, const ValueRef object, int nameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
|
||||
Scoped<Object> o(scope, object);
|
||||
if (o)
|
||||
|
@ -663,8 +675,10 @@ ReturnedValue Runtime::getProperty(ExecutionEngine *engine, const ValueRef objec
|
|||
return o->get(name);
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::getActivationProperty(ExecutionEngine *engine, String *name)
|
||||
ReturnedValue Runtime::getActivationProperty(ExecutionEngine *engine, int nameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
return engine->currentContext()->getProperty(name);
|
||||
}
|
||||
|
||||
|
@ -886,17 +900,19 @@ ReturnedValue Runtime::callGlobalLookup(ExecutionEngine *engine, uint index, Cal
|
|||
if (!o)
|
||||
return engine->throwTypeError();
|
||||
|
||||
if (o.getPointer() == scope.engine->evalFunction && l->name->equals(scope.engine->id_eval))
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
|
||||
if (o.getPointer() == scope.engine->evalFunction && name->equals(scope.engine->id_eval))
|
||||
return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true);
|
||||
|
||||
return o->call(callData);
|
||||
}
|
||||
|
||||
|
||||
ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, String *name, CallData *callData)
|
||||
ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
|
||||
{
|
||||
Q_ASSERT(callData->thisObject.isUndefined());
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
|
||||
ScopedObject base(scope);
|
||||
Object *baseObj = 0;
|
||||
|
@ -924,9 +940,10 @@ ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, String *n
|
|||
return o->call(callData);
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::callProperty(ExecutionEngine *engine, String *name, CallData *callData)
|
||||
ReturnedValue Runtime::callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
Scoped<Object> baseObject(scope, callData->thisObject);
|
||||
if (!baseObject) {
|
||||
Q_ASSERT(!callData->thisObject.isEmpty());
|
||||
|
@ -954,7 +971,7 @@ ReturnedValue Runtime::callPropertyLookup(ExecutionEngine *engine, uint index, C
|
|||
{
|
||||
Lookup *l = engine->currentContext()->d()->lookups + index;
|
||||
Value v;
|
||||
v = l->getter(l, callData->thisObject);
|
||||
v = l->getter(l, engine, callData->thisObject);
|
||||
if (!v.isObject())
|
||||
return engine->throwTypeError();
|
||||
|
||||
|
@ -1001,9 +1018,10 @@ ReturnedValue Runtime::constructGlobalLookup(ExecutionEngine *engine, uint index
|
|||
}
|
||||
|
||||
|
||||
ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, String *name, CallData *callData)
|
||||
ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
ScopedValue func(scope, engine->currentContext()->getProperty(name));
|
||||
if (scope.engine->hasException)
|
||||
return Encode::undefined();
|
||||
|
@ -1024,10 +1042,11 @@ ReturnedValue Runtime::constructValue(ExecutionEngine *engine, const ValueRef fu
|
|||
return f->construct(callData);
|
||||
}
|
||||
|
||||
ReturnedValue Runtime::constructProperty(ExecutionEngine *engine, String *name, CallData *callData)
|
||||
ReturnedValue Runtime::constructProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedObject thisObject(scope, callData->thisObject.toObject(engine));
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
if (scope.engine->hasException)
|
||||
return Encode::undefined();
|
||||
|
||||
|
@ -1042,7 +1061,7 @@ ReturnedValue Runtime::constructPropertyLookup(ExecutionEngine *engine, uint ind
|
|||
{
|
||||
Lookup *l = engine->currentContext()->d()->lookups + index;
|
||||
Value v;
|
||||
v = l->getter(l, callData->thisObject);
|
||||
v = l->getter(l, engine, callData->thisObject);
|
||||
if (!v.isObject())
|
||||
return engine->throwTypeError();
|
||||
|
||||
|
@ -1085,18 +1104,20 @@ ReturnedValue Runtime::typeofValue(ExecutionEngine *engine, const ValueRef value
|
|||
return res.asReturnedValue();
|
||||
}
|
||||
|
||||
QV4::ReturnedValue Runtime::typeofName(ExecutionEngine *engine, String *name)
|
||||
QV4::ReturnedValue Runtime::typeofName(ExecutionEngine *engine, int nameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
ScopedValue prop(scope, engine->currentContext()->getProperty(name));
|
||||
// typeof doesn't throw. clear any possible exception
|
||||
scope.engine->hasException = false;
|
||||
return Runtime::typeofValue(engine, prop);
|
||||
}
|
||||
|
||||
QV4::ReturnedValue Runtime::typeofMember(ExecutionEngine *engine, const ValueRef base, String *name)
|
||||
QV4::ReturnedValue Runtime::typeofMember(ExecutionEngine *engine, const ValueRef base, int nameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
ScopedObject obj(scope, base->toObject(engine));
|
||||
if (scope.engine->hasException)
|
||||
return Encode::undefined();
|
||||
|
@ -1129,10 +1150,11 @@ ReturnedValue Runtime::unwindException(ExecutionEngine *engine)
|
|||
return engine->catchException(0);
|
||||
}
|
||||
|
||||
void Runtime::pushCatchScope(NoThrowEngine *engine, String *exceptionVarName)
|
||||
void Runtime::pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedValue v(scope, engine->catchException(0));
|
||||
ScopedString exceptionVarName(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[exceptionVarNameIndex]);
|
||||
engine->currentContext()->newCatchContext(exceptionVarName, v);
|
||||
}
|
||||
|
||||
|
@ -1141,8 +1163,10 @@ void Runtime::popScope(ExecutionEngine *engine)
|
|||
engine->popContext();
|
||||
}
|
||||
|
||||
void Runtime::declareVar(ExecutionEngine *engine, bool deletable, String *name)
|
||||
void Runtime::declareVar(ExecutionEngine *engine, bool deletable, int nameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
engine->currentContext()->createMutableBinding(name, deletable);
|
||||
}
|
||||
|
||||
|
@ -1370,9 +1394,10 @@ ReturnedValue Runtime::getQmlImportedScripts(NoThrowEngine *engine)
|
|||
return context->importedScripts.value();
|
||||
}
|
||||
|
||||
QV4::ReturnedValue Runtime::getQmlSingleton(QV4::NoThrowEngine *engine, String *name)
|
||||
QV4::ReturnedValue Runtime::getQmlSingleton(QV4::NoThrowEngine *engine, int nameIndex)
|
||||
{
|
||||
Scope scope(engine);
|
||||
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[nameIndex]);
|
||||
Scoped<QmlContextWrapper> wrapper(scope, engine->qmlContextObject());
|
||||
return wrapper->qmlSingletonWrapper(engine->v8Engine, name);
|
||||
}
|
||||
|
|
|
@ -89,50 +89,51 @@ struct NoThrowEngine : public ExecutionEngine
|
|||
struct Q_QML_PRIVATE_EXPORT Runtime {
|
||||
// call
|
||||
static ReturnedValue callGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData);
|
||||
static ReturnedValue callActivationProperty(ExecutionEngine *engine, String *name, CallData *callData);
|
||||
static ReturnedValue callProperty(ExecutionEngine *engine, String *name, CallData *callData);
|
||||
static ReturnedValue callActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData);
|
||||
static ReturnedValue callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData);
|
||||
static ReturnedValue callPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData);
|
||||
static ReturnedValue callElement(ExecutionEngine *engine, const ValueRef index, CallData *callData);
|
||||
static ReturnedValue callValue(ExecutionEngine *engine, const ValueRef func, CallData *callData);
|
||||
|
||||
// construct
|
||||
static ReturnedValue constructGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData);
|
||||
static ReturnedValue constructActivationProperty(ExecutionEngine *engine, String *name, CallData *callData);
|
||||
static ReturnedValue constructProperty(ExecutionEngine *engine, String *name, CallData *callData);
|
||||
static ReturnedValue constructActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData);
|
||||
static ReturnedValue constructProperty(ExecutionEngine *engine, int nameIndex, CallData *callData);
|
||||
static ReturnedValue constructPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData);
|
||||
static ReturnedValue constructValue(ExecutionEngine *engine, const ValueRef func, CallData *callData);
|
||||
|
||||
// set & get
|
||||
static void setActivationProperty(ExecutionEngine *engine, String *name, const ValueRef value);
|
||||
static void setProperty(ExecutionEngine *engine, const ValueRef object, String *name, const ValueRef value);
|
||||
static void setActivationProperty(ExecutionEngine *engine, int nameIndex, const ValueRef value);
|
||||
static void setProperty(ExecutionEngine *engine, const ValueRef object, int nameIndex, const ValueRef value);
|
||||
static void setElement(ExecutionEngine *engine, const ValueRef object, const ValueRef index, const ValueRef value);
|
||||
static ReturnedValue getProperty(ExecutionEngine *engine, const ValueRef object, String *name);
|
||||
static ReturnedValue getActivationProperty(ExecutionEngine *engine, String *name);
|
||||
static ReturnedValue getProperty(ExecutionEngine *engine, const ValueRef object, int nameIndex);
|
||||
static ReturnedValue getActivationProperty(ExecutionEngine *engine, int nameIndex);
|
||||
static ReturnedValue getElement(ExecutionEngine *engine, const ValueRef object, const ValueRef index);
|
||||
|
||||
// typeof
|
||||
static ReturnedValue typeofValue(ExecutionEngine *engine, const ValueRef val);
|
||||
static ReturnedValue typeofName(ExecutionEngine *engine, String *name);
|
||||
static ReturnedValue typeofMember(ExecutionEngine *engine, const ValueRef base, String *name);
|
||||
static ReturnedValue typeofName(ExecutionEngine *engine, int nameIndex);
|
||||
static ReturnedValue typeofMember(ExecutionEngine *engine, const ValueRef base, int nameIndex);
|
||||
static ReturnedValue typeofElement(ExecutionEngine *engine, const ValueRef base, const ValueRef index);
|
||||
|
||||
// delete
|
||||
static ReturnedValue deleteElement(ExecutionEngine *engine, const ValueRef base, const ValueRef index);
|
||||
static ReturnedValue deleteMember(ExecutionEngine *engine, const ValueRef base, String *name);
|
||||
static ReturnedValue deleteName(ExecutionEngine *engine, String *name);
|
||||
static ReturnedValue deleteMember(ExecutionEngine *engine, const ValueRef base, int nameIndex);
|
||||
static ReturnedValue deleteMemberString(ExecutionEngine *engine, const ValueRef base, String *name);
|
||||
static ReturnedValue deleteName(ExecutionEngine *engine, int nameIndex);
|
||||
|
||||
// exceptions & scopes
|
||||
static void throwException(ExecutionEngine *engine, const ValueRef value);
|
||||
static ReturnedValue unwindException(ExecutionEngine *engine);
|
||||
static void pushWithScope(const ValueRef o, NoThrowEngine *engine);
|
||||
static void pushCatchScope(NoThrowEngine *engine, String *exceptionVarName);
|
||||
static void pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex);
|
||||
static void popScope(ExecutionEngine *engine);
|
||||
|
||||
// closures
|
||||
static ReturnedValue closure(ExecutionEngine *engine, int functionId);
|
||||
|
||||
// function header
|
||||
static void declareVar(ExecutionEngine *engine, bool deletable, String *name);
|
||||
static void declareVar(ExecutionEngine *engine, bool deletable, int nameIndex);
|
||||
static ReturnedValue setupArgumentsObject(ExecutionEngine *engine);
|
||||
static void convertThisToObject(ExecutionEngine *engine);
|
||||
|
||||
|
@ -209,7 +210,7 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
|
|||
static ReturnedValue getQmlImportedScripts(NoThrowEngine *ctx);
|
||||
static ReturnedValue getQmlContextObject(NoThrowEngine *ctx);
|
||||
static ReturnedValue getQmlScopeObject(NoThrowEngine *ctx);
|
||||
static ReturnedValue getQmlSingleton(NoThrowEngine *ctx, String *name);
|
||||
static ReturnedValue getQmlSingleton(NoThrowEngine *ctx, int nameIndex);
|
||||
static ReturnedValue getQmlAttachedProperty(ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex);
|
||||
static ReturnedValue getQmlQObjectProperty(ExecutionEngine *engine, const ValueRef object, int propertyIndex, bool captureRequired);
|
||||
static ReturnedValue getQmlSingletonQObjectProperty(ExecutionEngine *engine, const ValueRef object, int propertyIndex, bool captureRequired);
|
||||
|
|
|
@ -256,7 +256,7 @@ struct Scoped
|
|||
Scoped(const Scope &scope, typename T::Data *t)
|
||||
{
|
||||
ptr = scope.engine->jsStackTop++;
|
||||
*ptr = Value::fromHeapObject(t);
|
||||
*ptr = t;
|
||||
#ifndef QT_NO_DEBUG
|
||||
++scope.size;
|
||||
#endif
|
||||
|
@ -298,7 +298,7 @@ struct Scoped
|
|||
return *this;
|
||||
}
|
||||
Scoped<T> &operator=(typename T::Data *t) {
|
||||
*ptr = Value::fromHeapObject(t);
|
||||
*ptr = t;
|
||||
return *this;
|
||||
}
|
||||
Scoped<T> &operator=(const Value &v) {
|
||||
|
|
|
@ -556,7 +556,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
|
|||
Q_ASSERT(matchStart >= static_cast<uint>(lastEnd));
|
||||
uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
|
||||
callData->args[numCaptures] = Primitive::fromUInt32(matchStart);
|
||||
callData->args[numCaptures + 1] = Value::fromHeapObject(ctx->d()->engine->newString(string));
|
||||
callData->args[numCaptures + 1] = ctx->d()->engine->newString(string);
|
||||
|
||||
replacement = searchCallback->call(callData);
|
||||
result += string.midRef(lastEnd, matchStart - lastEnd);
|
||||
|
|
|
@ -373,13 +373,15 @@ struct Q_QML_PRIVATE_EXPORT Value
|
|||
|
||||
Value &operator =(const ScopedValue &v);
|
||||
Value &operator=(ReturnedValue v) { val = v; return *this; }
|
||||
template<typename T>
|
||||
Value &operator=(T *t) {
|
||||
val = Value::fromManaged(t).val;
|
||||
Value &operator=(Managed *m) {
|
||||
val = Value::fromManaged(m).val;
|
||||
return *this;
|
||||
}
|
||||
Value &operator=(Heap::Base *o) {
|
||||
m = o;
|
||||
#if QT_POINTER_SIZE == 4
|
||||
tag = Managed_Type;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -184,8 +184,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
qDebug("Starting VME with context=%p and code=%p", context, code);
|
||||
#endif // DO_TRACE_INSTR
|
||||
|
||||
QV4::String ** const runtimeStrings = context->d()->compilationUnit->runtimeStrings;
|
||||
|
||||
// setup lookup scopes
|
||||
int scopeDepth = 0;
|
||||
{
|
||||
|
@ -240,7 +238,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
|
||||
MOTH_BEGIN_INSTR(LoadRuntimeString)
|
||||
// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
|
||||
VALUE(instr.result) = runtimeStrings[instr.stringId]->asReturnedValue();
|
||||
VALUE(instr.result) = context->d()->compilationUnit->runtimeStrings[instr.stringId];
|
||||
MOTH_END_INSTR(LoadRuntimeString)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadRegExp)
|
||||
|
@ -254,7 +252,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
|
||||
MOTH_BEGIN_INSTR(LoadName)
|
||||
TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
|
||||
STOREVALUE(instr.result, Runtime::getActivationProperty(engine, runtimeStrings[instr.name]));
|
||||
STOREVALUE(instr.result, Runtime::getActivationProperty(engine, instr.name));
|
||||
MOTH_END_INSTR(LoadName)
|
||||
|
||||
MOTH_BEGIN_INSTR(GetGlobalLookup)
|
||||
|
@ -265,7 +263,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
|
||||
MOTH_BEGIN_INSTR(StoreName)
|
||||
TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
|
||||
Runtime::setActivationProperty(engine, runtimeStrings[instr.name], VALUEPTR(instr.source));
|
||||
Runtime::setActivationProperty(engine, instr.name, VALUEPTR(instr.source));
|
||||
CHECK_EXCEPTION;
|
||||
MOTH_END_INSTR(StoreName)
|
||||
|
||||
|
@ -290,22 +288,22 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
MOTH_END_INSTR(StoreElementLookup)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadProperty)
|
||||
STOREVALUE(instr.result, Runtime::getProperty(engine, VALUEPTR(instr.base), runtimeStrings[instr.name]));
|
||||
STOREVALUE(instr.result, Runtime::getProperty(engine, VALUEPTR(instr.base), instr.name));
|
||||
MOTH_END_INSTR(LoadProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(GetLookup)
|
||||
QV4::Lookup *l = context->d()->lookups + instr.index;
|
||||
STOREVALUE(instr.result, l->getter(l, VALUEPTR(instr.base)));
|
||||
STOREVALUE(instr.result, l->getter(l, engine, VALUEPTR(instr.base)));
|
||||
MOTH_END_INSTR(GetLookup)
|
||||
|
||||
MOTH_BEGIN_INSTR(StoreProperty)
|
||||
Runtime::setProperty(engine, VALUEPTR(instr.base), runtimeStrings[instr.name], VALUEPTR(instr.source));
|
||||
Runtime::setProperty(engine, VALUEPTR(instr.base), instr.name, VALUEPTR(instr.source));
|
||||
CHECK_EXCEPTION;
|
||||
MOTH_END_INSTR(StoreProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(SetLookup)
|
||||
QV4::Lookup *l = context->d()->lookups + instr.index;
|
||||
l->setter(l, VALUEPTR(instr.base), VALUEPTR(instr.source));
|
||||
l->setter(l, engine, VALUEPTR(instr.base), VALUEPTR(instr.source));
|
||||
CHECK_EXCEPTION;
|
||||
MOTH_END_INSTR(SetLookup)
|
||||
|
||||
|
@ -362,7 +360,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
callData->tag = QV4::Value::Integer_Type;
|
||||
callData->argc = instr.argc;
|
||||
callData->thisObject = VALUE(instr.base);
|
||||
STOREVALUE(instr.result, Runtime::callProperty(engine, runtimeStrings[instr.name], callData));
|
||||
STOREVALUE(instr.result, Runtime::callProperty(engine, instr.name, callData));
|
||||
MOTH_END_INSTR(CallProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallPropertyLookup)
|
||||
|
@ -391,7 +389,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
callData->tag = QV4::Value::Integer_Type;
|
||||
callData->argc = instr.argc;
|
||||
callData->thisObject = QV4::Primitive::undefinedValue();
|
||||
STOREVALUE(instr.result, Runtime::callActivationProperty(engine, runtimeStrings[instr.name], callData));
|
||||
STOREVALUE(instr.result, Runtime::callActivationProperty(engine, instr.name, callData));
|
||||
MOTH_END_INSTR(CallActivationProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallGlobalLookup)
|
||||
|
@ -418,7 +416,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
MOTH_END_INSTR(CallBuiltinUnwindException)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope)
|
||||
Runtime::pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), runtimeStrings[instr.name]);
|
||||
Runtime::pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
|
||||
context = engine->currentContext();
|
||||
MOTH_END_INSTR(CallBuiltinPushCatchScope)
|
||||
|
||||
|
@ -441,7 +439,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
MOTH_END_INSTR(CallBuiltinForeachNextPropertyName)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinDeleteMember)
|
||||
STOREVALUE(instr.result, Runtime::deleteMember(engine, VALUEPTR(instr.base), runtimeStrings[instr.member]));
|
||||
STOREVALUE(instr.result, Runtime::deleteMember(engine, VALUEPTR(instr.base), instr.member));
|
||||
MOTH_END_INSTR(CallBuiltinDeleteMember)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript)
|
||||
|
@ -449,11 +447,11 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
MOTH_END_INSTR(CallBuiltinDeleteSubscript)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinDeleteName)
|
||||
STOREVALUE(instr.result, Runtime::deleteName(engine, runtimeStrings[instr.name]));
|
||||
STOREVALUE(instr.result, Runtime::deleteName(engine, instr.name));
|
||||
MOTH_END_INSTR(CallBuiltinDeleteName)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinTypeofMember)
|
||||
STOREVALUE(instr.result, Runtime::typeofMember(engine, VALUEPTR(instr.base), runtimeStrings[instr.member]));
|
||||
STOREVALUE(instr.result, Runtime::typeofMember(engine, VALUEPTR(instr.base), instr.member));
|
||||
MOTH_END_INSTR(CallBuiltinTypeofMember)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript)
|
||||
|
@ -461,7 +459,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
MOTH_END_INSTR(CallBuiltinTypeofSubscript)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
|
||||
STOREVALUE(instr.result, Runtime::typeofName(engine, runtimeStrings[instr.name]));
|
||||
STOREVALUE(instr.result, Runtime::typeofName(engine, instr.name));
|
||||
MOTH_END_INSTR(CallBuiltinTypeofName)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
|
||||
|
@ -469,7 +467,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
MOTH_END_INSTR(CallBuiltinTypeofValue)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
|
||||
Runtime::declareVar(engine, instr.isDeletable, runtimeStrings[instr.varName]);
|
||||
Runtime::declareVar(engine, instr.isDeletable, instr.varName);
|
||||
MOTH_END_INSTR(CallBuiltinDeclareVar)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
|
||||
|
@ -507,7 +505,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
callData->tag = QV4::Value::Integer_Type;
|
||||
callData->argc = instr.argc;
|
||||
callData->thisObject = VALUE(instr.base);
|
||||
STOREVALUE(instr.result, Runtime::constructProperty(engine, runtimeStrings[instr.name], callData));
|
||||
STOREVALUE(instr.result, Runtime::constructProperty(engine, instr.name, callData));
|
||||
MOTH_END_INSTR(CreateProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(ConstructPropertyLookup)
|
||||
|
@ -526,7 +524,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
callData->tag = QV4::Value::Integer_Type;
|
||||
callData->argc = instr.argc;
|
||||
callData->thisObject = QV4::Primitive::undefinedValue();
|
||||
STOREVALUE(instr.result, Runtime::constructActivationProperty(engine, runtimeStrings[instr.name], callData));
|
||||
STOREVALUE(instr.result, Runtime::constructActivationProperty(engine, instr.name, callData));
|
||||
MOTH_END_INSTR(CreateActivationProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(ConstructGlobalLookup)
|
||||
|
@ -691,7 +689,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
MOTH_END_INSTR(LoadScopeObject)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadQmlSingleton)
|
||||
VALUE(instr.result) = Runtime::getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), runtimeStrings[instr.name]);
|
||||
VALUE(instr.result) = Runtime::getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
|
||||
MOTH_END_INSTR(LoadQmlSingleton)
|
||||
|
||||
#ifdef MOTH_THREADED_INTERPRETER
|
||||
|
|
Loading…
Reference in New Issue