F(CallBuiltinDeleteSubscript, callBuiltinDeleteSubscript) \
F(CallBuiltinDeleteName, callBuiltinDeleteName) \
F(CallBuiltinDeleteValue, callBuiltinDeleteValue) \
+ F(CallBuiltinTypeofMember, callBuiltinTypeofMember) \
+ F(CallBuiltinTypeofSubscript, callBuiltinTypeofSubscript) \
+ F(CallBuiltinTypeofName, callBuiltinTypeofName) \
+ F(CallBuiltinTypeofValue, callBuiltinTypeofValue) \
F(CallBuiltinDeclareVar, callBuiltinDeclareVar) \
F(CreateValue, createValue) \
F(CreateProperty, createProperty) \
struct instr_callBuiltin {
MOTH_INSTR_HEADER
enum {
- builtin_typeof,
builtin_throw,
builtin_rethrow,
builtin_create_exception_handler,
int tempIndex;
int targetTempIndex;
};
+ struct instr_callBuiltinTypeofMember {
+ MOTH_INSTR_HEADER
+ int base;
+ VM::String *member;
+ int targetTempIndex;
+ };
+ struct instr_callBuiltinTypeofSubscript {
+ MOTH_INSTR_HEADER
+ int base;
+ int index;
+ int targetTempIndex;
+ };
+ struct instr_callBuiltinTypeofName {
+ MOTH_INSTR_HEADER
+ VM::String *name;
+ int targetTempIndex;
+ };
+ struct instr_callBuiltinTypeofValue {
+ MOTH_INSTR_HEADER
+ int tempIndex;
+ int targetTempIndex;
+ };
struct instr_callBuiltinDeclareVar {
MOTH_INSTR_HEADER
bool isDeletable;
instr_callBuiltinDeleteSubscript callBuiltinDeleteSubscript;
instr_callBuiltinDeleteName callBuiltinDeleteName;
instr_callBuiltinDeleteValue callBuiltinDeleteValue;
+ instr_callBuiltinTypeofMember callBuiltinTypeofMember;
+ instr_callBuiltinTypeofSubscript callBuiltinTypeofSubscript;
+ instr_callBuiltinTypeofName callBuiltinTypeofName;
+ instr_callBuiltinTypeofValue callBuiltinTypeofValue;
instr_callBuiltinDeclareVar callBuiltinDeclareVar;
instr_createValue createValue;
instr_createProperty createProperty;
} break;
case IR::Name::builtin_typeof: {
- IR::Temp *arg = c->args->expr->asTemp();
- assert(arg != 0);
-
- Instruction::CallBuiltin call;
- call.builtin = Instruction::CallBuiltin::builtin_typeof;
- prepareCallArgs(c->args, call.argc, call.args);
- call.targetTempIndex = targetTempIndex;
- addInstruction(call);
+ if (IR::Member *m = c->args->expr->asMember()) {
+ Instruction::CallBuiltinTypeofMember call;
+ call.base = m->base->asTemp()->index;
+ call.member = engine()->identifier(*m->name);
+ call.targetTempIndex = targetTempIndex;
+ addInstruction(call);
+ } else if (IR::Subscript *ss = c->args->expr->asSubscript()) {
+ Instruction::CallBuiltinTypeofSubscript call;
+ call.base = ss->base->asTemp()->index;
+ call.index = ss->index->asTemp()->index;
+ call.targetTempIndex = targetTempIndex;
+ addInstruction(call);
+ } else if (IR::Name *n = c->args->expr->asName()) {
+ Instruction::CallBuiltinTypeofName call;
+ call.name = engine()->identifier(*n->id);
+ call.targetTempIndex = targetTempIndex;
+ addInstruction(call);
+ } else if (IR::Temp *arg = c->args->expr->asTemp()){
+ assert(arg != 0);
+ Instruction::CallBuiltinTypeofValue call;
+ call.tempIndex = arg->index;
+ call.targetTempIndex = targetTempIndex;
+ addInstruction(call);
+ } else {
+ assert(false);
+ }
} break;
case IR::Name::builtin_delete: {
VM::Value *args = stack + argStart;
void *buf;
switch (instr.builtin) {
- case Instr::instr_callBuiltin::builtin_typeof:
- Q_ASSERT(instr.argc == 1);
- TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof(args[0], context);
- break;
case Instr::instr_callBuiltin::builtin_throw:
TRACE(builtin_throw, "Throwing now...%s", "");
Q_ASSERT(instr.argc == 1);
TEMP(instr.targetTempIndex) = VM::Value::fromBoolean(false);
MOTH_END_INSTR(CallBuiltinDeleteValue)
+ MOTH_BEGIN_INSTR(CallBuiltinTypeofMember)
+ TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof_member(TEMP(instr.base), instr.member, context);
+ MOTH_END_INSTR(CallBuiltinTypeofMember)
+
+ MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript)
+ TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof_element(TEMP(instr.base), TEMP(instr.index), context);
+ MOTH_END_INSTR(CallBuiltinTypeofSubscript)
+
+ MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
+ TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof_name(instr.name, context);
+ MOTH_END_INSTR(CallBuiltinTypeofName)
+
+ MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
+ TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof(TEMP(instr.tempIndex), context);
+ MOTH_END_INSTR(CallBuiltinTypeofValue)
+
MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
__qmljs_builtin_declare_var(context, instr.isDeletable, instr.varName);
MOTH_END_INSTR(CallBuiltinDeleteValue)