Get rid of variableEnvironment
Found out that the variableEnv is only required for two use cases: To expose the exception in the catch statement, and to create temporary environments for the with() statment. Both can be better handled differently and don't require the overhead of two environments. Change-Id: I149e1fd7bdfc3267544b141b6f94e46e42cf641b Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
parent
f00cf7cfae
commit
f26d5c36cf
|
@ -50,16 +50,16 @@ FunctionState::~FunctionState()
|
|||
|
||||
VM::Value *FunctionState::argument(unsigned idx)
|
||||
{
|
||||
if (idx < _context->variableEnvironment->argumentCount)
|
||||
return _context->variableEnvironment->arguments + idx;
|
||||
if (idx < _context->lexicalEnvironment->argumentCount)
|
||||
return _context->lexicalEnvironment->arguments + idx;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
VM::Value *FunctionState::local(unsigned idx)
|
||||
{
|
||||
if (idx < _context->variableEnvironment->varCount)
|
||||
return _context->variableEnvironment->locals + idx;
|
||||
if (idx < _context->lexicalEnvironment->varCount)
|
||||
return _context->lexicalEnvironment->locals + idx;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ Value __qmljs_llvm_return(ExecutionContext */*ctx*/, Value *result)
|
|||
|
||||
Value *__qmljs_llvm_get_argument(ExecutionContext *ctx, int index)
|
||||
{
|
||||
return &ctx->variableEnvironment->arguments[index];
|
||||
return &ctx->lexicalEnvironment->arguments[index];
|
||||
}
|
||||
|
||||
void __qmljs_llvm_init_undefined(Value *result)
|
||||
|
|
|
@ -53,7 +53,7 @@ using namespace QQmlJS::Moth;
|
|||
|
||||
static inline VM::Value *tempValue(QQmlJS::VM::ExecutionContext *context, QVector<VM::Value> &stack, int index)
|
||||
{
|
||||
VM::DeclarativeEnvironment *varEnv = context->variableEnvironment;
|
||||
VM::DeclarativeEnvironment *varEnv = context->lexicalEnvironment;
|
||||
|
||||
#ifdef DO_TRACE_INSTR
|
||||
const char *kind;
|
||||
|
@ -231,21 +231,21 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
|
|||
}
|
||||
}
|
||||
#endif // DO_TRACE_INSTR
|
||||
quint32 argStart = instr.args - context->variableEnvironment->varCount;
|
||||
quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
|
||||
TRACE(Call, "value index = %d, argStart = %d, argc = %d, result temp index = %d", instr.destIndex, argStart, instr.argc, instr.targetTempIndex);
|
||||
VM::Value *args = stack.data() + argStart;
|
||||
TEMP(instr.targetTempIndex) = __qmljs_call_value(context, VM::Value::undefinedValue(), TEMP(instr.destIndex), args, instr.argc);
|
||||
MOTH_END_INSTR(CallValue)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallProperty)
|
||||
quint32 argStart = instr.args - context->variableEnvironment->varCount;
|
||||
quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
|
||||
VM::Value *args = stack.data() + argStart;
|
||||
VM::Value base = TEMP(instr.baseTemp);
|
||||
TEMP(instr.targetTempIndex) = __qmljs_call_property(context, base, instr.name, args, instr.argc);
|
||||
MOTH_END_INSTR(CallProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(CallBuiltin)
|
||||
quint32 argStart = instr.args - context->variableEnvironment->varCount;
|
||||
quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
|
||||
VM::Value *args = stack.data() + argStart;
|
||||
void *buf;
|
||||
switch (instr.builtin) {
|
||||
|
@ -325,20 +325,20 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
|
|||
MOTH_END_INSTR(CallBuiltinDeleteValue)
|
||||
|
||||
MOTH_BEGIN_INSTR(CreateValue)
|
||||
quint32 argStart = instr.args - context->variableEnvironment->varCount;
|
||||
quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
|
||||
VM::Value *args = stack.data() + argStart;
|
||||
TEMP(instr.targetTempIndex) = __qmljs_construct_value(context, TEMP(instr.func), args, instr.argc);
|
||||
MOTH_END_INSTR(CreateValue)
|
||||
|
||||
MOTH_BEGIN_INSTR(CreateProperty)
|
||||
quint32 argStart = instr.args - context->variableEnvironment->varCount;
|
||||
quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
|
||||
VM::Value *args = stack.data() + argStart;
|
||||
TEMP(instr.targetTempIndex) = __qmljs_construct_property(context, TEMP(instr.base), instr.name, args, instr.argc);
|
||||
MOTH_END_INSTR(CreateProperty)
|
||||
|
||||
MOTH_BEGIN_INSTR(CreateActivationProperty)
|
||||
TRACE(inline, "property name = %s, argc = %d", instr.name->toQString().toUtf8().constData(), instr.argc);
|
||||
quint32 argStart = instr.args - context->variableEnvironment->varCount;
|
||||
quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
|
||||
VM::Value *args = stack.data() + argStart;
|
||||
TEMP(instr.targetTempIndex) = __qmljs_construct_activation_property(context, instr.name, args, instr.argc);
|
||||
MOTH_END_INSTR(CreateActivationProperty)
|
||||
|
|
|
@ -158,7 +158,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
|
|||
//
|
||||
VM::Object *glo = newObject(/*rootContext*/);
|
||||
globalObject = Value::fromObject(glo);
|
||||
rootContext->variableEnvironment->activation = glo;
|
||||
rootContext->lexicalEnvironment->activation = glo;
|
||||
|
||||
glo->__put__(rootContext, identifier(QStringLiteral("Object")), objectCtor);
|
||||
glo->__put__(rootContext, identifier(QStringLiteral("String")), stringCtor);
|
||||
|
|
|
@ -215,9 +215,8 @@ void ExecutionContext::init(ExecutionEngine *eng)
|
|||
{
|
||||
engine = eng;
|
||||
parent = 0;
|
||||
variableEnvironment = new DeclarativeEnvironment;
|
||||
variableEnvironment->init(eng);
|
||||
lexicalEnvironment = variableEnvironment;
|
||||
lexicalEnvironment = new DeclarativeEnvironment;
|
||||
lexicalEnvironment->init(eng);
|
||||
thisObject = Value::nullValue();
|
||||
eng->exception = Value::undefinedValue();
|
||||
}
|
||||
|
@ -312,9 +311,8 @@ void ExecutionContext::initCallContext(ExecutionContext *parent, const Value tha
|
|||
engine = parent->engine;
|
||||
this->parent = parent;
|
||||
|
||||
variableEnvironment = new DeclarativeEnvironment;
|
||||
variableEnvironment->init(f, args, argc);
|
||||
lexicalEnvironment = variableEnvironment;
|
||||
lexicalEnvironment = new DeclarativeEnvironment;
|
||||
lexicalEnvironment->init(f, args, argc);
|
||||
|
||||
thisObject = that;
|
||||
|
||||
|
@ -325,13 +323,13 @@ void ExecutionContext::initCallContext(ExecutionContext *parent, const Value tha
|
|||
void ExecutionContext::leaveCallContext()
|
||||
{
|
||||
// ## Should rather be handled by a the activation object having a ref to the environment
|
||||
if (variableEnvironment->activation) {
|
||||
delete[] variableEnvironment->locals;
|
||||
variableEnvironment->locals = 0;
|
||||
if (lexicalEnvironment->activation) {
|
||||
delete[] lexicalEnvironment->locals;
|
||||
lexicalEnvironment->locals = 0;
|
||||
}
|
||||
|
||||
delete variableEnvironment;
|
||||
variableEnvironment = 0;
|
||||
delete lexicalEnvironment;
|
||||
lexicalEnvironment = 0;
|
||||
|
||||
if (engine->debugger)
|
||||
engine->debugger->justLeft(this);
|
||||
|
|
|
@ -112,7 +112,6 @@ struct ExecutionContext
|
|||
ExecutionContext *parent;
|
||||
// ### Should be a general environment
|
||||
DeclarativeEnvironment *lexicalEnvironment;
|
||||
DeclarativeEnvironment *variableEnvironment;
|
||||
Value thisObject;
|
||||
|
||||
void init(ExecutionEngine *eng);
|
||||
|
@ -135,11 +134,11 @@ struct ExecutionContext
|
|||
void inplaceBitOp(Value value, String *name, BinOp op);
|
||||
bool deleteProperty(String *name);
|
||||
|
||||
inline uint argumentCount() const { return variableEnvironment->argumentCount; }
|
||||
inline uint argumentCount() const { return lexicalEnvironment->argumentCount; }
|
||||
inline Value argument(unsigned int index = 0)
|
||||
{
|
||||
if (index < variableEnvironment->argumentCount)
|
||||
return variableEnvironment->arguments[index];
|
||||
if (index < lexicalEnvironment->argumentCount)
|
||||
return lexicalEnvironment->arguments[index];
|
||||
return Value::undefinedValue();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -499,7 +499,6 @@ Value EvalFunction::call(ExecutionContext *context, Value /*thisObject*/, Value
|
|||
ctx->parent = context;
|
||||
ctx->thisObject = context->thisObject;
|
||||
ctx->lexicalEnvironment = context->lexicalEnvironment;
|
||||
ctx->variableEnvironment = context->variableEnvironment;
|
||||
}
|
||||
|
||||
Value result = f->code(ctx, f->codeData);
|
||||
|
@ -580,11 +579,11 @@ QQmlJS::IR::Function *EvalFunction::parseSource(QQmlJS::VM::ExecutionContext *ct
|
|||
__qmljs_throw_type_error(ctx);
|
||||
}
|
||||
|
||||
if (!ctx->variableEnvironment->activation)
|
||||
ctx->variableEnvironment->activation = new QQmlJS::VM::Object();
|
||||
if (!ctx->lexicalEnvironment->activation)
|
||||
ctx->lexicalEnvironment->activation = new QQmlJS::VM::Object();
|
||||
|
||||
foreach (const QString *local, globalCode->locals) {
|
||||
ctx->variableEnvironment->activation->__put__(ctx, *local, QQmlJS::VM::Value::undefinedValue());
|
||||
ctx->lexicalEnvironment->activation->__put__(ctx, *local, QQmlJS::VM::Value::undefinedValue());
|
||||
}
|
||||
return globalCode;
|
||||
}
|
||||
|
|
|
@ -500,7 +500,7 @@ struct FunctionObject: Object {
|
|||
bool strictMode;
|
||||
|
||||
FunctionObject(ExecutionContext *scope)
|
||||
: scope(scope->variableEnvironment)
|
||||
: scope(scope->lexicalEnvironment)
|
||||
, name(0)
|
||||
, formalParameterList(0)
|
||||
, formalParameterCount(0)
|
||||
|
|
|
@ -1960,8 +1960,8 @@ Value FunctionPrototype::method_call(ExecutionContext *ctx)
|
|||
Value thisArg = ctx->argument(0);
|
||||
QVector<Value> args(ctx->argumentCount() ? ctx->argumentCount() - 1 : 0);
|
||||
if (ctx->argumentCount())
|
||||
qCopy(ctx->variableEnvironment->arguments + 1,
|
||||
ctx->variableEnvironment->arguments + ctx->argumentCount(), args.begin());
|
||||
qCopy(ctx->lexicalEnvironment->arguments + 1,
|
||||
ctx->lexicalEnvironment->arguments + ctx->argumentCount(), args.begin());
|
||||
return __qmljs_call_value(ctx, thisArg, ctx->thisObject, args.data(), args.size());
|
||||
}
|
||||
|
||||
|
|
|
@ -191,11 +191,11 @@ 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, variableEnvironment)), reg);
|
||||
loadPtr(Address(ContextRegister, offsetof(ExecutionContext, lexicalEnvironment)), reg);
|
||||
loadPtr(Address(reg, offsetof(DeclarativeEnvironment, arguments)), reg);
|
||||
offset = arg * sizeof(Value);
|
||||
} else if (t->index < _function->locals.size()) {
|
||||
loadPtr(Address(ContextRegister, offsetof(ExecutionContext, variableEnvironment)), reg);
|
||||
loadPtr(Address(ContextRegister, offsetof(ExecutionContext, lexicalEnvironment)), reg);
|
||||
loadPtr(Address(reg, offsetof(DeclarativeEnvironment, locals)), reg);
|
||||
offset = t->index * sizeof(Value);
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue