aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm_runtime.cpp2
-rw-r--r--main.cpp4
-rw-r--r--moth/qv4vme_moth.cpp8
-rw-r--r--qmljs_engine.cpp4
-rw-r--r--qmljs_engine.h5
-rw-r--r--qmljs_environment.cpp165
-rw-r--r--qmljs_environment.h53
-rw-r--r--qmljs_objects.cpp12
-rw-r--r--qmljs_objects.h27
-rw-r--r--qmljs_runtime.cpp4
-rw-r--r--qv4ecmaobjects.cpp135
-rw-r--r--qv4isel_masm.cpp6
12 files changed, 279 insertions, 146 deletions
diff --git a/llvm_runtime.cpp b/llvm_runtime.cpp
index b911ad4880..553f2fd1ac 100644
--- a/llvm_runtime.cpp
+++ b/llvm_runtime.cpp
@@ -55,7 +55,7 @@ void __qmljs_llvm_return(ExecutionContext *ctx, Value *result)
Value *__qmljs_llvm_get_argument(ExecutionContext *ctx, int index)
{
- return &ctx->arguments[index];
+ return &ctx->variableEnvironment->arguments[index];
}
void __qmljs_llvm_init_undefined(Value *result)
diff --git a/main.cpp b/main.cpp
index 1e8acfdaaa..d147d04a91 100644
--- a/main.cpp
+++ b/main.cpp
@@ -71,7 +71,7 @@ struct Print: FunctionObject
virtual void call(ExecutionContext *ctx)
{
- for (unsigned int i = 0; i < ctx->argumentCount; ++i) {
+ for (unsigned int i = 0; i < ctx->argumentCount(); ++i) {
String *s = ctx->argument(i).toString(ctx);
if (i)
std::cout << ' ';
@@ -89,7 +89,7 @@ struct TestHarnessError: FunctionObject
{
errorOccurred = true;
- for (unsigned int i = 0; i < ctx->argumentCount; ++i) {
+ for (unsigned int i = 0; i < ctx->argumentCount(); ++i) {
String *s = ctx->argument(i).toString(ctx);
if (i)
std::cerr << ' ';
diff --git a/moth/qv4vme_moth.cpp b/moth/qv4vme_moth.cpp
index c058002aa2..30a5d3c3a6 100644
--- a/moth/qv4vme_moth.cpp
+++ b/moth/qv4vme_moth.cpp
@@ -68,11 +68,11 @@ static inline VM::Value *tempValue(QQmlJS::VM::ExecutionContext *context, QVecto
if (index < 0) {
const int arg = -index - 1;
- return context->arguments + arg;
- } else if (index < (int) context->varCount) {
- return context->locals + index;
+ return context->variableEnvironment->arguments + arg;
+ } else if (index < (int) context->variableEnvironment->varCount) {
+ return context->variableEnvironment->locals + index;
} else {
- int off = index - context->varCount;
+ int off = index - context->variableEnvironment->varCount;
return stack.data() + off;
}
}
diff --git a/qmljs_engine.cpp b/qmljs_engine.cpp
index 9229dbd9a2..8097639e54 100644
--- a/qmljs_engine.cpp
+++ b/qmljs_engine.cpp
@@ -139,7 +139,7 @@ ExecutionEngine::ExecutionEngine()
//
VM::Object *glo = newObject(/*rootContext*/);
globalObject = Value::fromObject(glo);
- rootContext->activation = glo;
+ rootContext->variableEnvironment->activation = glo;
glo->__put__(rootContext, identifier(QStringLiteral("Object")), objectCtor);
glo->__put__(rootContext, identifier(QStringLiteral("String")), stringCtor);
@@ -324,7 +324,7 @@ Object *ExecutionEngine::newMathObject(ExecutionContext *ctx)
return object;
}
-Object *ExecutionEngine::newActivationObject(ExecutionContext *ctx)
+Object *ExecutionEngine::newActivationObject(DeclarativeEnvironment *ctx)
{
return new ActivationObject(ctx);
}
diff --git a/qmljs_engine.h b/qmljs_engine.h
index ed4b0d4a16..f111979f0d 100644
--- a/qmljs_engine.h
+++ b/qmljs_engine.h
@@ -42,6 +42,7 @@
#define QMLJS_ENGINE_H
#include <qmljs_objects.h>
+#include <qmljs_environment.h>
#include <setjmp.h>
namespace QQmlJS {
@@ -81,7 +82,9 @@ struct URIErrorPrototype;
struct ExecutionEngine
{
+ ExecutionContext *current;
ExecutionContext *rootContext;
+
Value globalObject;
Value objectCtor;
@@ -170,7 +173,7 @@ struct ExecutionEngine
Object *newErrorObject(const Value &value);
Object *newMathObject(ExecutionContext *ctx);
- Object *newActivationObject(ExecutionContext *ctx);
+ Object *newActivationObject(DeclarativeEnvironment *ctx);
Object *newForEachIteratorObject(Object *o);
};
diff --git a/qmljs_environment.cpp b/qmljs_environment.cpp
index 550d619fe1..338006474e 100644
--- a/qmljs_environment.cpp
+++ b/qmljs_environment.cpp
@@ -45,25 +45,134 @@
namespace QQmlJS {
namespace VM {
-void ExecutionContext::init(ExecutionEngine *eng)
+DeclarativeEnvironment::DeclarativeEnvironment(ExecutionEngine *e)
{
- engine = eng;
- parent = 0;
+ engine = e;
+ outer = 0;
arguments = 0;
argumentCount = 0;
locals = 0;
activation = 0;
- thisObject = Value::nullValue();
- result = Value::undefinedValue();
formals = 0;
formalCount = 0;
vars = 0;
varCount = 0;
}
+DeclarativeEnvironment::DeclarativeEnvironment(FunctionObject *f, Value *args, uint argc)
+{
+ outer = f->scope;
+ engine = outer->engine;
+
+ if (f->needsActivation)
+ activation = engine->newActivationObject(this);
+ else
+ activation = 0;
+
+ formals = f->formalParameterList;
+ formalCount = f->formalParameterCount;
+ arguments = args;
+ argumentCount = argc;
+ if (f->needsActivation || argc < formalCount){
+ arguments = new Value[qMax(argc, formalCount)];
+ if (argc)
+ std::copy(args, args + argc, arguments);
+ if (argc < formalCount)
+ std::fill(arguments + argc, arguments + formalCount, Value::undefinedValue());
+ }
+ vars = f->varList;
+ varCount = f->varCount;
+ locals = varCount ? new Value[varCount] : 0;
+ if (varCount)
+ std::fill(locals, locals + varCount, Value::undefinedValue());
+}
+
+bool DeclarativeEnvironment::hasBinding(String *name) const
+{
+ for (unsigned int i = 0; i < varCount; ++i) {
+ if (__qmljs_string_equal(vars[i], name))
+ return true;
+ }
+ for (unsigned int i = 0; i < formalCount; ++i) {
+ if (__qmljs_string_equal(formals[i], name))
+ return true;
+ }
+ return deletableLocals.contains(name->toQString());
+}
+
+void DeclarativeEnvironment::createMutableBinding(String *name, bool deletable)
+{
+ // all non deletable vars should get created at compile time
+ assert(deletable);
+ assert(!hasBinding(name));
+
+ deletableLocals.insert(name->toQString(), Value::undefinedValue());
+}
+
+void DeclarativeEnvironment::setMutableBinding(String *name, Value value, bool strict)
+{
+ // ### throw if strict is true, and it would change an immutable binding
+ for (unsigned int i = 0; i < varCount; ++i) {
+ if (__qmljs_string_equal(vars[i], name)) {
+ locals[i] = value;
+ return;
+ }
+ }
+ for (unsigned int i = 0; i < formalCount; ++i) {
+ if (__qmljs_string_equal(formals[i], name)) {
+ arguments[i] = value;
+ return;
+ }
+ }
+ QHash<QString, Value>::iterator it = deletableLocals.find(name->toQString());
+ if (it != deletableLocals.end()) {
+ *it = value;
+ return;
+ }
+ assert(false);
+}
+
+Value DeclarativeEnvironment::getBindingValue(String *name, bool strict) const
+{
+ for (unsigned int i = 0; i < varCount; ++i) {
+ if (__qmljs_string_equal(vars[i], name))
+ return locals[i];
+ }
+ for (unsigned int i = 0; i < formalCount; ++i) {
+ if (__qmljs_string_equal(formals[i], name))
+ return arguments[i];
+ }
+ QHash<QString, Value>::const_iterator it = deletableLocals.find(name->toQString());
+ if (it != deletableLocals.end())
+ return *it;
+
+ assert(false);
+}
+
+bool DeclarativeEnvironment::deleteBinding(String *name)
+{
+ QHash<QString, Value>::iterator it = deletableLocals.find(name->toQString());
+ if (it != deletableLocals.end()) {
+ deletableLocals.erase(it);
+ return true;
+ }
+ return !hasBinding(name);
+}
+
+
+void ExecutionContext::init(ExecutionEngine *eng)
+{
+ engine = eng;
+ parent = 0;
+ variableEnvironment = new DeclarativeEnvironment(eng);
+ lexicalEnvironment = variableEnvironment;
+ thisObject = Value::nullValue();
+ result = Value::undefinedValue();
+}
+
PropertyDescriptor *ExecutionContext::lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp)
{
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->parent) {
+ for (DeclarativeEnvironment *ctx = lexicalEnvironment; ctx; ctx = ctx->outer) {
if (ctx->activation) {
if (PropertyDescriptor *pd = ctx->activation->__getPropertyDescriptor__(this, name, tmp))
return pd;
@@ -74,7 +183,7 @@ PropertyDescriptor *ExecutionContext::lookupPropertyDescriptor(String *name, Pro
void ExecutionContext::inplaceBitOp(Value value, String *name, BinOp op)
{
- for (ExecutionContext *ctx = this; ctx; ctx = ctx->parent) {
+ for (DeclarativeEnvironment *ctx = lexicalEnvironment; ctx; ctx = ctx->outer) {
if (ctx->activation) {
if (ctx->activation->inplaceBinOp(value, name, op, this))
return;
@@ -117,40 +226,21 @@ void ExecutionContext::throwReferenceError(Value value)
void ExecutionContext::initCallContext(ExecutionContext *parent, const Value that, FunctionObject *f, Value *args, unsigned argc)
{
engine = parent->engine;
- this->parent = f->scope;
- assert(this->parent == f->scope);
- result = Value::undefinedValue();
+ this->parent = parent;
- if (f->needsActivation)
- activation = engine->newActivationObject(this);
- else
- activation = 0;
+ variableEnvironment = new DeclarativeEnvironment(f, args, argc);
+ lexicalEnvironment = variableEnvironment;
thisObject = that;
-
- formals = f->formalParameterList;
- formalCount = f->formalParameterCount;
- arguments = args;
- argumentCount = argc;
- if (f->needsActivation || argc < formalCount){
- arguments = new Value[qMax(argc, formalCount)];
- if (argc)
- std::copy(args, args + argc, arguments);
- if (argc < formalCount)
- std::fill(arguments + argc, arguments + formalCount, Value::undefinedValue());
- }
- vars = f->varList;
- varCount = f->varCount;
- locals = varCount ? new Value[varCount] : 0;
- if (varCount)
- std::fill(locals, locals + varCount, Value::undefinedValue());
+ result = Value::undefinedValue();
}
void ExecutionContext::leaveCallContext()
{
- if (activation) {
- delete[] locals;
- locals = 0;
+ // ## Should rather be handled by a the activation object having a ref to the environment
+ if (variableEnvironment->activation) {
+ delete[] variableEnvironment->locals;
+ variableEnvironment->locals = 0;
}
}
@@ -171,11 +261,12 @@ void ExecutionContext::wireUpPrototype(FunctionObject *f)
result = thisObject;
Value proto = f->__get__(this, engine->id_prototype);
- thisObject.objectValue()->prototype = proto.objectValue();
- if (! thisObject.isObject())
+ if (proto.isObject())
+ thisObject.objectValue()->prototype = proto.objectValue();
+ else
thisObject.objectValue()->prototype = engine->objectPrototype;
-
}
+
} // namespace VM
} // namespace QQmlJS
diff --git a/qmljs_environment.h b/qmljs_environment.h
index 74568cdf25..bbb5cc4839 100644
--- a/qmljs_environment.h
+++ b/qmljs_environment.h
@@ -50,30 +50,47 @@ struct Value;
struct Object;
struct ExecutionEngine;
struct ExecutionContext;
+struct DeclarativeEnvironment;
-struct ExecutionContext {
+// This merges LexicalEnvironment and EnvironmentRecord from
+// Sec. 10.2 into one class
+struct DeclarativeEnvironment
+{
ExecutionEngine *engine;
- ExecutionContext *parent;
+ DeclarativeEnvironment *outer;
+
Object *activation;
- Value thisObject;
Value *arguments;
unsigned int argumentCount;
Value *locals;
- Value result;
String **formals;
unsigned int formalCount;
String **vars;
unsigned int varCount;
- PropertyDescriptor *lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp);
- void inplaceBitOp(Value value, String *name, BinOp op);
+ // these get used for createMutableBinding(..., true).
+ // the only place this is being used is eval(...)
+ QHash<QString, Value> deletableLocals;
- inline Value argument(unsigned int index = 0)
- {
- if (index < argumentCount)
- return arguments[index];
- return Value::undefinedValue();
- }
+ DeclarativeEnvironment(ExecutionEngine *e);
+ DeclarativeEnvironment(FunctionObject *f, Value *args, uint argc);
+
+ bool hasBinding(String *name) const;
+ void createMutableBinding(String *name, bool deletable);
+ void setMutableBinding(String *name, Value value, bool strict);
+ Value getBindingValue(String *name, bool strict) const;
+ bool deleteBinding(String *name);
+};
+
+struct ExecutionContext
+{
+ ExecutionEngine *engine;
+ ExecutionContext *parent;
+ // ### Should be a general environment
+ DeclarativeEnvironment *lexicalEnvironment;
+ DeclarativeEnvironment *variableEnvironment;
+ Value thisObject;
+ Value result;
void init(ExecutionEngine *eng);
@@ -89,9 +106,21 @@ struct ExecutionContext {
void throwTypeError();
void throwReferenceError(Value value);
void throwUnimplemented(const QString &message);
+
+ PropertyDescriptor *lookupPropertyDescriptor(String *name, PropertyDescriptor *tmp);
+ void inplaceBitOp(Value value, String *name, BinOp op);
+
+ inline uint argumentCount() const { return variableEnvironment->argumentCount; }
+ inline Value argument(unsigned int index = 0)
+ {
+ if (index < variableEnvironment->argumentCount)
+ return variableEnvironment->arguments[index];
+ return Value::undefinedValue();
+ }
};
+
} // namespace VM
} // namespace QQmlJS
diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp
index 7552a83a03..4f831b01bf 100644
--- a/qmljs_objects.cpp
+++ b/qmljs_objects.cpp
@@ -554,11 +554,11 @@ int EvalFunction::evaluate(QQmlJS::VM::ExecutionContext *ctx, const QString &fil
return EXIT_FAILURE;
}
- if (!ctx->activation)
- ctx->activation = new QQmlJS::VM::Object();
+ if (!ctx->variableEnvironment->activation)
+ ctx->variableEnvironment->activation = new QQmlJS::VM::Object();
foreach (const QString *local, globalCode->locals) {
- ctx->activation->__put__(ctx, *local, QQmlJS::VM::Value::undefinedValue());
+ ctx->variableEnvironment->activation->__put__(ctx, *local, QQmlJS::VM::Value::undefinedValue());
}
if (mode == Codegen::GlobalCode) {
@@ -668,7 +668,7 @@ PropertyDescriptor *ActivationObject::__getPropertyDescriptor__(ExecutionContext
Value ArgumentsObject::__get__(ExecutionContext *ctx, String *name)
{
if (name->isEqualTo(ctx->engine->id_length))
- return Value::fromDouble(context->argumentCount);
+ return Value::fromInt32(context->argumentCount());
return Object::__get__(ctx, name);
}
@@ -676,8 +676,8 @@ PropertyDescriptor *ArgumentsObject::__getPropertyDescriptor__(ExecutionContext
{
if (context) {
const quint32 i = Value::fromString(name).toUInt32(ctx);
- if (i < context->argumentCount) {
- *to_fill = PropertyDescriptor::fromValue(context->arguments[i]);
+ if (i < context->argumentCount()) {
+ *to_fill = PropertyDescriptor::fromValue(context->argument(i));
to_fill->writable = PropertyDescriptor::Unset;
to_fill->enumberable = PropertyDescriptor::Unset;
return to_fill;
diff --git a/qmljs_objects.h b/qmljs_objects.h
index ce26089e8f..6d0e0fa35d 100644
--- a/qmljs_objects.h
+++ b/qmljs_objects.h
@@ -474,7 +474,7 @@ struct ArrayObject: Object {
};
struct FunctionObject: Object {
- ExecutionContext *scope;
+ DeclarativeEnvironment *scope;
String *name;
String **formalParameterList;
unsigned int formalParameterCount;
@@ -483,7 +483,7 @@ struct FunctionObject: Object {
bool needsActivation;
FunctionObject(ExecutionContext *scope)
- : scope(scope)
+ : scope(scope->variableEnvironment)
, name(0)
, formalParameterList(0)
, formalParameterCount(0)
@@ -554,39 +554,46 @@ protected:
};
struct EvalErrorObject: ErrorObject {
- EvalErrorObject(ExecutionContext *ctx): ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
+ EvalErrorObject(ExecutionContext *ctx)
+ : ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
virtual QString className() { return QStringLiteral("EvalError"); }
};
struct RangeErrorObject: ErrorObject {
- RangeErrorObject(ExecutionContext *ctx): ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
+ RangeErrorObject(ExecutionContext *ctx)
+ : ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
virtual QString className() { return QStringLiteral("RangeError"); }
};
struct ReferenceErrorObject: ErrorObject {
- ReferenceErrorObject(ExecutionContext *ctx): ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
+ ReferenceErrorObject(ExecutionContext *ctx)
+ : ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
virtual QString className() { return QStringLiteral("ReferenceError"); }
};
struct SyntaxErrorObject: ErrorObject {
- SyntaxErrorObject(ExecutionContext *ctx): ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
+ SyntaxErrorObject(ExecutionContext *ctx)
+ : ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
virtual QString className() { return QStringLiteral("SyntaxError"); }
};
struct TypeErrorObject: ErrorObject {
- TypeErrorObject(ExecutionContext *ctx): ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
+ TypeErrorObject(ExecutionContext *ctx)
+ : ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
virtual QString className() { return QStringLiteral("TypeError"); }
};
struct URIErrorObject: ErrorObject {
- URIErrorObject(ExecutionContext *ctx): ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
+ URIErrorObject(ExecutionContext *ctx)
+ : ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
virtual QString className() { return QStringLiteral("URIError"); }
};
struct ActivationObject: Object {
- ExecutionContext *context;
+ DeclarativeEnvironment *context;
Value arguments;
- ActivationObject(ExecutionContext *context): context(context), arguments(Value::undefinedValue()) {}
+ ActivationObject(DeclarativeEnvironment *context)
+ : context(context), arguments(Value::undefinedValue()) {}
virtual QString className() { return QStringLiteral("Activation"); }
virtual ActivationObject *asActivationObject() { return this; }
virtual PropertyDescriptor *__getPropertyDescriptor__(ExecutionContext *ctx, String *name, PropertyDescriptor *to_fill);
diff --git a/qmljs_runtime.cpp b/qmljs_runtime.cpp
index 44226fb593..407348fe6a 100644
--- a/qmljs_runtime.cpp
+++ b/qmljs_runtime.cpp
@@ -197,7 +197,7 @@ Value __qmljs_delete_member(ExecutionContext *ctx, Value base, String *name)
Value __qmljs_delete_property(ExecutionContext *ctx, String *name)
{
- Object *obj = ctx->activation;
+ Object *obj = ctx->lexicalEnvironment->activation;
if (!obj)
obj = ctx->engine->globalObject.objectValue();
return Value::fromBoolean(obj->__delete__(ctx, name, true));
@@ -779,7 +779,7 @@ Value __qmljs_call_property(ExecutionContext *context, Value base, String *name,
Value thisObject;
if (base.isUndefined()) {
- baseObject = context->activation;
+ baseObject = context->lexicalEnvironment->activation;
thisObject = Value::nullValue();
} else {
if (!base.isObject())
diff --git a/qv4ecmaobjects.cpp b/qv4ecmaobjects.cpp
index 652fc4525a..7d0b25b5db 100644
--- a/qv4ecmaobjects.cpp
+++ b/qv4ecmaobjects.cpp
@@ -710,7 +710,7 @@ StringCtor::StringCtor(ExecutionContext *scope)
void StringCtor::construct(ExecutionContext *ctx)
{
Value value;
- if (ctx->argumentCount)
+ if (ctx->argumentCount())
value = Value::fromString(ctx->argument(0).toString(ctx));
else
value = Value::fromString(ctx, QString());
@@ -786,7 +786,7 @@ void StringPrototype::method_charAt(ExecutionContext *ctx)
const QString str = getThisString(ctx);
int pos = 0;
- if (ctx->argumentCount > 0)
+ if (ctx->argumentCount() > 0)
pos = (int) ctx->argument(0).toInteger(ctx);
QString result;
@@ -801,7 +801,7 @@ void StringPrototype::method_charCodeAt(ExecutionContext *ctx)
const QString str = getThisString(ctx);
int pos = 0;
- if (ctx->argumentCount > 0)
+ if (ctx->argumentCount() > 0)
pos = (int) ctx->argument(0).toInteger(ctx);
double result = qSNaN();
@@ -816,8 +816,8 @@ void StringPrototype::method_concat(ExecutionContext *ctx)
{
QString value = getThisString(ctx);
- for (unsigned i = 0; i < ctx->argumentCount; ++i) {
- Value v = __qmljs_to_string(ctx->arguments[i], ctx);
+ for (unsigned i = 0; i < ctx->argumentCount(); ++i) {
+ Value v = __qmljs_to_string(ctx->argument(i), ctx);
assert(v.isString());
value += v.stringValue()->toQString();
}
@@ -830,11 +830,11 @@ void StringPrototype::method_indexOf(ExecutionContext *ctx)
QString value = getThisString(ctx);
QString searchString;
- if (ctx->argumentCount)
+ if (ctx->argumentCount())
searchString = ctx->argument(0).toString(ctx)->toQString();
int pos = 0;
- if (ctx->argumentCount > 1)
+ if (ctx->argumentCount() > 1)
pos = (int) ctx->argument(1).toInteger(ctx);
int index = -1;
@@ -849,8 +849,8 @@ void StringPrototype::method_lastIndexOf(ExecutionContext *ctx)
const QString value = getThisString(ctx);
QString searchString;
- if (ctx->argumentCount) {
- Value v = __qmljs_to_string(ctx->arguments[0], ctx);
+ if (ctx->argumentCount()) {
+ Value v = __qmljs_to_string(ctx->argument(0), ctx);
searchString = v.stringValue()->toQString();
}
@@ -926,11 +926,11 @@ void StringPrototype::method_substr(ExecutionContext *ctx)
const QString value = getThisString(ctx);
double start = 0;
- if (ctx->argumentCount > 0)
+ if (ctx->argumentCount() > 0)
start = ctx->argument(0).toInteger(ctx);
double length = +qInf();
- if (ctx->argumentCount > 1)
+ if (ctx->argumentCount() > 1)
length = ctx->argument(1).toInteger(ctx);
double count = value.length();
@@ -952,10 +952,10 @@ void StringPrototype::method_substring(ExecutionContext *ctx)
double start = 0;
double end = length;
- if (ctx->argumentCount > 0)
+ if (ctx->argumentCount() > 0)
start = ctx->argument(0).toInteger(ctx);
- if (ctx->argumentCount > 1)
+ if (ctx->argumentCount() > 1)
end = ctx->argument(1).toInteger(ctx);
if (qIsNaN(start) || start < 0)
@@ -1006,7 +1006,7 @@ void StringPrototype::method_toLocaleUpperCase(ExecutionContext *ctx)
void StringPrototype::method_fromCharCode(ExecutionContext *ctx)
{
QString str;
- for (unsigned i = 0; i < ctx->argumentCount; ++i) {
+ for (unsigned i = 0; i < ctx->argumentCount(); ++i) {
QChar c(ctx->argument(i).toUInt16(ctx));
str += c;
}
@@ -1029,7 +1029,7 @@ void NumberCtor::construct(ExecutionContext *ctx)
void NumberCtor::call(ExecutionContext *ctx)
{
- double value = ctx->argumentCount ? ctx->argument(0).toNumber(ctx) : 0;
+ double value = ctx->argumentCount() ? ctx->argument(0).toNumber(ctx) : 0;
ctx->result = Value::fromDouble(value);
}
@@ -1143,7 +1143,7 @@ void NumberPrototype::method_toFixed(ExecutionContext *ctx)
if (NumberObject *thisObject = ctx->thisObject.asNumberObject()) {
double fdigits = 0;
- if (ctx->argumentCount > 0)
+ if (ctx->argumentCount() > 0)
fdigits = ctx->argument(0).toInteger(ctx);
if (qIsNaN(fdigits))
@@ -1168,7 +1168,7 @@ void NumberPrototype::method_toExponential(ExecutionContext *ctx)
if (NumberObject *thisObject = ctx->thisObject.asNumberObject()) {
double fdigits = 0;
- if (ctx->argumentCount > 0)
+ if (ctx->argumentCount() > 0)
fdigits = ctx->argument(0).toInteger(ctx);
QString z = QString::number(thisObject->value.asDouble(), 'e', int (fdigits));
@@ -1183,7 +1183,7 @@ void NumberPrototype::method_toPrecision(ExecutionContext *ctx)
if (NumberObject *thisObject = ctx->thisObject.asNumberObject()) {
double fdigits = 0;
- if (ctx->argumentCount > 0)
+ if (ctx->argumentCount() > 0)
fdigits = ctx->argument(0).toInteger(ctx);
ctx->result = Value::fromString(ctx, QString::number(thisObject->value.asDouble(), 'g', int (fdigits)));
@@ -1208,7 +1208,7 @@ void BooleanCtor::construct(ExecutionContext *ctx)
void BooleanCtor::call(ExecutionContext *ctx)
{
- bool value = ctx->argumentCount ? ctx->argument(0).toBoolean(ctx) : 0;
+ bool value = ctx->argumentCount() ? ctx->argument(0).toBoolean(ctx) : 0;
ctx->result = Value::fromBoolean(value);
}
@@ -1255,7 +1255,7 @@ void ArrayCtor::construct(ExecutionContext *ctx)
void ArrayCtor::call(ExecutionContext *ctx)
{
Array value;
- if (ctx->argumentCount == 1 && ctx->argument(0).isNumber()) {
+ if (ctx->argumentCount() == 1 && ctx->argument(0).isNumber()) {
double size = ctx->argument(0).asDouble();
quint32 isize = Value::toUInt32(size);
@@ -1266,7 +1266,7 @@ void ArrayCtor::call(ExecutionContext *ctx)
value.resize(isize);
} else {
- for (unsigned int i = 0; i < ctx->argumentCount; ++i) {
+ for (unsigned int i = 0; i < ctx->argumentCount(); ++i) {
value.assign(i, ctx->argument(i));
}
}
@@ -1322,7 +1322,7 @@ void ArrayPrototype::method_concat(ExecutionContext *ctx)
result.assign(0, Value::fromString(ctx, v));
}
- for (uint i = 0; i < ctx->argumentCount; ++i) {
+ for (uint i = 0; i < ctx->argumentCount(); ++i) {
quint32 k = result.size();
Value arg = ctx->argument(i);
@@ -1420,7 +1420,7 @@ void ArrayPrototype::method_push(ExecutionContext *ctx)
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
uint pos = instance->value.size();
- for (unsigned int i = 0; i < ctx->argumentCount; ++i) {
+ for (unsigned int i = 0; i < ctx->argumentCount(); ++i) {
Value val = ctx->argument(i);
instance->value.assign(pos++, val);
}
@@ -1428,7 +1428,7 @@ void ArrayPrototype::method_push(ExecutionContext *ctx)
} else {
Value r1 = self.property(ctx, ctx->engine->id_length);
quint32 n = !r1.isUndefined() ? r1.toUInt32(ctx) : 0;
- for (unsigned int index = 0; index < ctx->argumentCount; ++index, ++n) {
+ for (unsigned int index = 0; index < ctx->argumentCount(); ++index, ++n) {
Value r3 = ctx->argument(index);
String *name = Value::fromDouble(n).toString(ctx);
self.objectValue()->__put__(ctx, name, r3);
@@ -1505,7 +1505,7 @@ void ArrayPrototype::method_sort(ExecutionContext *ctx)
void ArrayPrototype::method_splice(ExecutionContext *ctx)
{
- if (ctx->argumentCount < 2)
+ if (ctx->argumentCount() < 2)
return;
double start = ctx->argument(0).toInteger(ctx);
@@ -1514,7 +1514,7 @@ void ArrayPrototype::method_splice(ExecutionContext *ctx)
Value self = ctx->thisObject;
if (ArrayObject *instance = self.asArrayObject()) {
QVector<Value> items;
- for (unsigned int i = 2; i < ctx->argumentCount; ++i)
+ for (unsigned int i = 2; i < ctx->argumentCount(); ++i)
items << ctx->argument(i);
ArrayObject *otherInstance = a.asArrayObject();
assert(otherInstance);
@@ -1739,13 +1739,13 @@ void FunctionCtor::construct(ExecutionContext *ctx)
{
QString args;
QString body;
- if (ctx->argumentCount > 0)
- body = ctx->arguments[ctx->argumentCount - 1].toString(ctx)->toQString();
+ if (ctx->argumentCount() > 0)
+ body = ctx->argument(ctx->argumentCount() - 1).toString(ctx)->toQString();
- for (uint i = 0; i < ctx->argumentCount - 1; ++i) {
+ for (uint i = 0; i < ctx->argumentCount() - 1; ++i) {
if (i)
args += QLatin1String(", ");
- args += ctx->arguments[i].toString(ctx)->toQString();
+ args += ctx->argument(i).toString(ctx)->toQString();
}
QString function = QLatin1String("function(") + args + QLatin1String("){") + body + QLatin1String("}");
@@ -1835,9 +1835,10 @@ void FunctionPrototype::method_apply(ExecutionContext *ctx)
void FunctionPrototype::method_call(ExecutionContext *ctx)
{
Value thisArg = ctx->argument(0);
- QVector<Value> args(ctx->argumentCount ? ctx->argumentCount - 1 : 0);
- if (ctx->argumentCount)
- qCopy(ctx->arguments + 1, ctx->arguments + ctx->argumentCount, args.begin());
+ QVector<Value> args(ctx->argumentCount() ? ctx->argumentCount() - 1 : 0);
+ if (ctx->argumentCount())
+ qCopy(ctx->variableEnvironment->arguments + 1,
+ ctx->variableEnvironment->arguments + ctx->argumentCount(), args.begin());
ctx->result = __qmljs_call_value(ctx, thisArg, ctx->thisObject, args.data(), args.size());
}
@@ -1863,10 +1864,10 @@ void DateCtor::construct(ExecutionContext *ctx)
{
double t = 0;
- if (ctx->argumentCount == 0)
+ if (ctx->argumentCount() == 0)
t = currentTime();
- else if (ctx->argumentCount == 1) {
+ else if (ctx->argumentCount() == 1) {
Value arg = ctx->argument(0);
if (DateObject *d = arg.asDateObject())
arg = d->value;
@@ -1879,14 +1880,14 @@ void DateCtor::construct(ExecutionContext *ctx)
t = TimeClip(arg.toNumber(ctx));
}
- else { // ctx->argumentCount() > 1
+ else { // ctx->argumentCount()() > 1
double year = ctx->argument(0).toNumber(ctx);
double month = ctx->argument(1).toNumber(ctx);
- double day = ctx->argumentCount >= 3 ? ctx->argument(2).toNumber(ctx) : 1;
- double hours = ctx->argumentCount >= 4 ? ctx->argument(3).toNumber(ctx) : 0;
- double mins = ctx->argumentCount >= 5 ? ctx->argument(4).toNumber(ctx) : 0;
- double secs = ctx->argumentCount >= 6 ? ctx->argument(5).toNumber(ctx) : 0;
- double ms = ctx->argumentCount >= 7 ? ctx->argument(6).toNumber(ctx) : 0;
+ double day = ctx->argumentCount() >= 3 ? ctx->argument(2).toNumber(ctx) : 1;
+ double hours = ctx->argumentCount() >= 4 ? ctx->argument(3).toNumber(ctx) : 0;
+ double mins = ctx->argumentCount() >= 5 ? ctx->argument(4).toNumber(ctx) : 0;
+ double secs = ctx->argumentCount() >= 6 ? ctx->argument(5).toNumber(ctx) : 0;
+ double ms = ctx->argumentCount() >= 7 ? ctx->argument(6).toNumber(ctx) : 0;
if (year >= 0 && year <= 99)
year += 1900;
t = MakeDate(MakeDay(year, month, day), MakeTime(hours, mins, secs, ms));
@@ -1990,7 +1991,7 @@ void DatePrototype::method_parse(ExecutionContext *ctx)
void DatePrototype::method_UTC(ExecutionContext *ctx)
{
- const int numArgs = ctx->argumentCount;
+ const int numArgs = ctx->argumentCount();
if (numArgs >= 2) {
double year = ctx->argument(0).toNumber(ctx);
double month = ctx->argument(1).toNumber(ctx);
@@ -2238,7 +2239,7 @@ void DatePrototype::method_setSeconds(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = LocalTime(self->value.asDouble());
double sec = ctx->argument(0).toNumber(ctx);
- double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double ms = (ctx->argumentCount() < 2) ? msFromTime(t) : ctx->argument(1).toNumber(ctx);
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2252,7 +2253,7 @@ void DatePrototype::method_setUTCSeconds(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = self->value.asDouble();
double sec = ctx->argument(0).toNumber(ctx);
- double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double ms = (ctx->argumentCount() < 2) ? msFromTime(t) : ctx->argument(1).toNumber(ctx);
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2266,8 +2267,8 @@ void DatePrototype::method_setMinutes(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = LocalTime(self->value.asDouble());
double min = ctx->argument(0).toNumber(ctx);
- double sec = (ctx->argumentCount < 2) ? SecFromTime(t) : ctx->argument(1).toNumber(ctx);
- double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->argument(2).toNumber(ctx);
+ double sec = (ctx->argumentCount() < 2) ? SecFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double ms = (ctx->argumentCount() < 3) ? msFromTime(t) : ctx->argument(2).toNumber(ctx);
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2281,8 +2282,8 @@ void DatePrototype::method_setUTCMinutes(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = self->value.asDouble();
double min = ctx->argument(0).toNumber(ctx);
- double sec = (ctx->argumentCount < 2) ? SecFromTime(t) : ctx->argument(1).toNumber(ctx);
- double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->argument(2).toNumber(ctx);
+ double sec = (ctx->argumentCount() < 2) ? SecFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double ms = (ctx->argumentCount() < 3) ? msFromTime(t) : ctx->argument(2).toNumber(ctx);
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2296,9 +2297,9 @@ void DatePrototype::method_setHours(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = LocalTime(self->value.asDouble());
double hour = ctx->argument(0).toNumber(ctx);
- double min = (ctx->argumentCount < 2) ? MinFromTime(t) : ctx->argument(1).toNumber(ctx);
- double sec = (ctx->argumentCount < 3) ? SecFromTime(t) : ctx->argument(2).toNumber(ctx);
- double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->argument(3).toNumber(ctx);
+ double min = (ctx->argumentCount() < 2) ? MinFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double sec = (ctx->argumentCount() < 3) ? SecFromTime(t) : ctx->argument(2).toNumber(ctx);
+ double ms = (ctx->argumentCount() < 4) ? msFromTime(t) : ctx->argument(3).toNumber(ctx);
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2312,9 +2313,9 @@ void DatePrototype::method_setUTCHours(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = self->value.asDouble();
double hour = ctx->argument(0).toNumber(ctx);
- double min = (ctx->argumentCount < 2) ? MinFromTime(t) : ctx->argument(1).toNumber(ctx);
- double sec = (ctx->argumentCount < 3) ? SecFromTime(t) : ctx->argument(2).toNumber(ctx);
- double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->argument(3).toNumber(ctx);
+ double min = (ctx->argumentCount() < 2) ? MinFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double sec = (ctx->argumentCount() < 3) ? SecFromTime(t) : ctx->argument(2).toNumber(ctx);
+ double ms = (ctx->argumentCount() < 4) ? msFromTime(t) : ctx->argument(3).toNumber(ctx);
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2354,7 +2355,7 @@ void DatePrototype::method_setMonth(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = LocalTime(self->value.asDouble());
double month = ctx->argument(0).toNumber(ctx);
- double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double date = (ctx->argumentCount() < 2) ? DateFromTime(t) : ctx->argument(1).toNumber(ctx);
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2368,7 +2369,7 @@ void DatePrototype::method_setUTCMonth(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = self->value.asDouble();
double month = ctx->argument(0).toNumber(ctx);
- double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double date = (ctx->argumentCount() < 2) ? DateFromTime(t) : ctx->argument(1).toNumber(ctx);
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2408,8 +2409,8 @@ void DatePrototype::method_setUTCFullYear(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = self->value.asDouble();
double year = ctx->argument(0).toNumber(ctx);
- double month = (ctx->argumentCount < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber(ctx);
- double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->argument(2).toNumber(ctx);
+ double month = (ctx->argumentCount() < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double date = (ctx->argumentCount() < 3) ? DateFromTime(t) : ctx->argument(2).toNumber(ctx);
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2423,8 +2424,8 @@ void DatePrototype::method_setFullYear(ExecutionContext *ctx)
if (DateObject *self = ctx->thisObject.asDateObject()) {
double t = LocalTime(self->value.asDouble());
double year = ctx->argument(0).toNumber(ctx);
- double month = (ctx->argumentCount < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber(ctx);
- double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->argument(2).toNumber(ctx);
+ double month = (ctx->argumentCount() < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber(ctx);
+ double date = (ctx->argumentCount() < 3) ? DateFromTime(t) : ctx->argument(2).toNumber(ctx);
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->value.setDouble(t);
ctx->result = self->value;
@@ -2451,13 +2452,13 @@ RegExpCtor::RegExpCtor(ExecutionContext *scope)
void RegExpCtor::construct(ExecutionContext *ctx)
{
-// if (ctx->argumentCount > 2) {
+// if (ctx->argumentCount() > 2) {
// ctx->throwTypeError();
// return;
// }
- Value r = ctx->argumentCount > 0 ? ctx->argument(0) : Value::undefinedValue();
- Value f = ctx->argumentCount > 1 ? ctx->argument(1) : Value::undefinedValue();
+ Value r = ctx->argumentCount() > 0 ? ctx->argument(0) : Value::undefinedValue();
+ Value f = ctx->argumentCount() > 1 ? ctx->argument(1) : Value::undefinedValue();
if (RegExpObject *re = r.asRegExpObject()) {
if (!f.isUndefined()) {
ctx->throwTypeError();
@@ -2501,8 +2502,8 @@ void RegExpCtor::construct(ExecutionContext *ctx)
void RegExpCtor::call(ExecutionContext *ctx)
{
- if (ctx->argumentCount > 0 && ctx->argument(0).asRegExpObject()) {
- if (ctx->argumentCount == 1 || ctx->argument(1).isUndefined()) {
+ if (ctx->argumentCount() > 0 && ctx->argument(0).asRegExpObject()) {
+ if (ctx->argumentCount() == 1 || ctx->argument(1).isUndefined()) {
ctx->result = ctx->argument(0);
return;
}
@@ -2822,7 +2823,7 @@ void MathObject::method_log(ExecutionContext *ctx)
void MathObject::method_max(ExecutionContext *ctx)
{
double mx = -qInf();
- for (unsigned i = 0; i < ctx->argumentCount; ++i) {
+ for (unsigned i = 0; i < ctx->argumentCount(); ++i) {
double x = ctx->argument(i).toNumber(ctx);
if (x > mx || qIsNaN(x))
mx = x;
@@ -2833,7 +2834,7 @@ void MathObject::method_max(ExecutionContext *ctx)
void MathObject::method_min(ExecutionContext *ctx)
{
double mx = qInf();
- for (unsigned i = 0; i < ctx->argumentCount; ++i) {
+ for (unsigned i = 0; i < ctx->argumentCount(); ++i) {
double x = ctx->argument(i).toNumber(ctx);
if ((x == 0 && mx == x && copySign(1.0, x) == -1.0)
|| (x < mx) || qIsNaN(x)) {
diff --git a/qv4isel_masm.cpp b/qv4isel_masm.cpp
index 90b3cb968d..8a8e663e93 100644
--- a/qv4isel_masm.cpp
+++ b/qv4isel_masm.cpp
@@ -180,10 +180,12 @@ InstructionSelection::Pointer InstructionSelection::loadTempAddress(RegisterID r
int32_t offset = 0;
if (t->index < 0) {
const int arg = -t->index - 1;
- loadPtr(Address(ContextRegister, offsetof(ExecutionContext, arguments)), reg);
+ loadPtr(Address(ContextRegister, offsetof(ExecutionContext, variableEnvironment)), reg);
+ loadPtr(Address(reg, offsetof(DeclarativeEnvironment, arguments)), reg);
offset = arg * sizeof(Value);
} else if (t->index < _function->locals.size()) {
- loadPtr(Address(ContextRegister, offsetof(ExecutionContext, locals)), reg);
+ loadPtr(Address(ContextRegister, offsetof(ExecutionContext, variableEnvironment)), reg);
+ loadPtr(Address(reg, offsetof(DeclarativeEnvironment, locals)), reg);
offset = t->index * sizeof(Value);
} else {
const int arg = _function->maxNumberOfArguments + t->index - _function->locals.size();