id_value = identifier(QStringLiteral("value"));
id_get = identifier(QStringLiteral("get"));
id_set = identifier(QStringLiteral("set"));
+ id_eval = identifier(QStringLiteral("eval"));
objectPrototype = new (memoryManager) ObjectPrototype();
stringPrototype = new (memoryManager) StringPrototype(rootContext);
glo->defineReadonlyProperty(this, QStringLiteral("NaN"), Value::fromDouble(nan("")));
glo->defineReadonlyProperty(this, QStringLiteral("Infinity"), Value::fromDouble(INFINITY));
- glo->defineDefaultProperty(rootContext, QStringLiteral("eval"), Value::fromObject(new (memoryManager) EvalFunction(rootContext)));
+ evalFunction = new (memoryManager) EvalFunction(rootContext);
+ glo->defineDefaultProperty(rootContext, QStringLiteral("eval"), Value::fromObject(evalFunction));
glo->defineDefaultProperty(rootContext, QStringLiteral("parseInt"), GlobalFunctions::method_parseInt, 2);
glo->defineDefaultProperty(rootContext, QStringLiteral("parseFloat"), GlobalFunctions::method_parseFloat, 1);
struct SyntaxErrorPrototype;
struct TypeErrorPrototype;
struct URIErrorPrototype;
+struct EvalFunction;
class RegExp;
TypeErrorPrototype *typeErrorPrototype;
URIErrorPrototype *uRIErrorPrototype;
+ EvalFunction *evalFunction;
+
QVector<PropertyDescriptor> argumentsAccessors;
String *id_length;
String *id_value;
String *id_get;
String *id_set;
+ String *id_eval;
struct ExceptionHandler {
ExecutionContext *context;
#include "qv4object.h"
#include "qv4ir_p.h"
#include "qv4objectproto.h"
+#include "qv4globalobject.h"
#include "private/qlocale_tools_p.h"
#include <QtCore/qmath.h>
Value thisObject = base ? Value::fromObject(base) : Value::undefinedValue();
+ if (o == context->engine->evalFunction && name == context->engine->id_eval)
+ return static_cast<EvalFunction *>(o)->call(context, thisObject, args, argc, true);
+
return o->call(context, thisObject, args, argc);
}
}
+EvalFunction::EvalFunction(ExecutionContext *scope)
+ : FunctionObject(scope)
+{
+ name = scope->engine->id_eval;
+}
-Value EvalFunction::call(ExecutionContext *context, Value /*thisObject*/, Value *args, int argc)
+Value EvalFunction::call(ExecutionContext *context, Value /*thisObject*/, Value *args, int argc, bool directCall)
{
if (argc < 1)
return Value::undefinedValue();
if (!args[0].isString())
return args[0];
- // ### how to determine this correctly?
- bool directCall = true;
-
const QString code = args[0].stringValue()->toQString();
QQmlJS::VM::Function *f = parseSource(context, QStringLiteral("eval code"), code, QQmlJS::Codegen::EvalCode);
if (!f)
bool strict = f->isStrict || context->strictMode;
- ExecutionContext k, *ctx;
+ ExecutionContext k;
+
+ ExecutionContext *ctx = context;
if (!directCall) {
- qDebug() << "!direct";
- // ###
- } else if (strict) {
+ // the context for eval should be the global scope
+ while (ctx->parent)
+ ctx = ctx->parent;
+ }
+
+ if (strict) {
ctx = &k;
ctx->initCallContext(context, context->thisObject, this, args, argc);
- } else {
- // use the surrounding context
- ctx = context;
}
// set the correct strict mode flag on the context
return result;
}
-EvalFunction::EvalFunction(ExecutionContext *scope)
- : FunctionObject(scope)
+
+Value EvalFunction::call(ExecutionContext *context, Value thisObject, Value *args, int argc)
{
- name = scope->engine->newString(QLatin1String("eval"));
+ // indirect call
+ return call(context, thisObject, args, argc, false);
}
QQmlJS::VM::Function *EvalFunction::parseSource(QQmlJS::VM::ExecutionContext *ctx,
QQmlJS::Codegen::Mode mode);
virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
+ Value call(ExecutionContext *context, Value thisObject, Value *args, int argc, bool directCall);
};
struct GlobalFunctions
# Tests failing that are supposed to pass.
-10.4.2-1-1 failing
10.4.2-1-2 failing
-10.4.2-1-3 failing
-10.4.2-1-4 failing
-10.4.2-1-5 failing
10.4.3-1-104 failing
10.4.3-1-106 failing
10.4.3-1-17-s failing