void BytecodeGenerationVisitor::visitFunctionNode(FunctionNode* node) {
	Bytecode* currentBytecode = bytecode;
	vector<const AstVar*> prevLocals = locals;
	locals.clear();
	
	if (code->functionByName(node->name()) == 0) {
		AstFunction* astFunction = node->body()->scope()->lookupFunction(node->name());
		BytecodeFunction *bytecodeFunction = new BytecodeFunction(astFunction);
		code->addFunction(bytecodeFunction);
		bytecode = bytecodeFunction->bytecode();
	} else {
		bytecode = ((BytecodeFunction*)(code->functionByName(node->name())))->bytecode();
	}
	
	VarType prevReturnType = returnType;
	returnType = node -> returnType();
	
	if (node->body()->nodeAt(0)->isNativeCallNode()) {
		node->body()->nodeAt(0)->visit(this);	// TODO
	} else {
		node->body()->visit(this);
	}
	
	locals = prevLocals;
	returnType = prevReturnType;
	bytecode = currentBytecode;
}
示例#2
0
Status* BytecodeVisitor::translateBytecode(Code *code, AstFunction *top) {
    code_ = code;
    BytecodeFunction* bf = new BytecodeFunction(top);
    code_->addFunction(bf);
    try {
        translateFunction(top);
        bf->bytecode()->addInsn(BC_STOP);
    } catch(std::runtime_error* e) {
        return Status::Error(e->what());
    } catch(...) {
        return Status::Error("Translate error");
    }

    return Status::Ok();

}
示例#3
0
void BytecodeGenerator::secondRun(Scope * scope) {
  Scope::FunctionIterator it(scope);
  while (it.hasNext()) {
    AstFunction *func = it.next();
    BytecodeFunction *bcf =
        (BytecodeFunction*) code->functionByName(func->name());
    fBC = bcf->bytecode();
    currentFun = bcf->id();
    returnType = func->returnType();
    func->node()->body()->visit(this);
    bcf->setLocalsNumber(localsCounter[currentFun]);
  }

  for (size_t i = 0; i < scope->childScopeNumber(); ++i) {
    secondRun(scope->childScopeAt(i));
  }
}
示例#4
0
void BytecodeGenerator::firstRun(Scope * scope) {
  Scope::FunctionIterator it(scope);
  while (it.hasNext()) {
    AstFunction *func = it.next();
    BytecodeFunction *bcf = new BytecodeFunction(func);
    currentFun = code->addFunction(bcf);
    initFunLocals(currentFun);
    Scope::VarIterator vi(func->scope());
    fBC = bcf->bytecode();    
    while (vi.hasNext()) {
    	AstVar * var = vi.next();
    	int index = localsCounter[currentFun];
			incFunLocals(currentFun);
			varIds[var] = make_pair(currentFun, index);
      storeVar(var);
    }
	}
	for (size_t i = 0; i < scope->childScopeNumber(); ++i) {
    firstRun(scope->childScopeAt(i));
  }
}
示例#5
0
 Bytecode* bc() {
     return bf_->bytecode();
 }
示例#6
0
Status* InterpreterCodeImpl::execute(std::vector<Var*>& vars) {
    ByteStack stack;
    typedef std::map<uint16_t, ByteStorage> VarMap;
    VarMap var_map;

    for (std::vector<Var*>::iterator it = vars.begin(); it != vars.end(); ++it) {
        if ((*it)->name() == "#__INTERPRETER_TRACING__#") {
            m_trace = true;
        }
    }

    BytecodeFunction* function = (BytecodeFunction*) functionById(0);
    Bytecode* bytecode = function->bytecode();

    for (size_t bci = 0; bci < bytecode->length();) {
        Instruction insn = BC_INVALID;
        size_t length = 1;  // size of the BC_INVALID
        decodeInsn(bytecode, bci, insn, length);
        switch (insn) {
            case BC_INVALID:
                return new Status("BC_INVALID", bci);
                break;

            case BC_DLOAD:
                stack.pushTyped(bytecode->getDouble(bci + 1));
                break;
            case BC_ILOAD:
                stack.pushTyped(bytecode->getInt64(bci + 1));
                break;
            case BC_SLOAD:
                stack.pushTyped(bytecode->getUInt16(bci + 1));
                break;

            case BC_DLOAD0:
                stack.pushTyped(double(0));
                break;
            case BC_ILOAD0:
                stack.pushTyped(int64_t(0));
                break;
            case BC_SLOAD0:
                stack.pushTyped(uint16_t(0));
                break;
            case BC_DLOAD1:
                stack.pushTyped(double(1));
                break;
            case BC_ILOAD1:
                stack.pushTyped(int64_t(1));
                break;

            case BC_DADD:
                stack.pushDouble(stack.popDouble() + stack.popDouble());
                break;
            case BC_IADD:
                stack.pushInt64(stack.popInt64() + stack.popInt64());
                break;
            case BC_DSUB:
                stack.pushDouble(stack.popDouble() - stack.popDouble());
                break;
            case BC_ISUB:
                stack.pushInt64(stack.popInt64() - stack.popInt64());
                break;
            case BC_DMUL:
                stack.pushDouble(stack.popDouble() * stack.popDouble());
                break;
            case BC_IMUL:
                stack.pushInt64(stack.popInt64() * stack.popInt64());
                break;
            case BC_DDIV:
                stack.pushDouble(stack.popDouble() / stack.popDouble());
                break;
            case BC_IDIV:
                stack.pushInt64(stack.popInt64() / stack.popInt64());
                break;
            case BC_IMOD:
                stack.pushInt64(stack.popInt64() % stack.popInt64());
                break;
            case BC_DNEG:
                stack.pushDouble(-stack.popDouble());
                break;
            case BC_INEG:
                stack.pushInt64(-stack.popInt64());
                break;

            case BC_IPRINT:
                std::cout << stack.popInt64();
                break;
            case BC_DPRINT:
                std::cout << stack.popDouble();
                break;
            case BC_SPRINT:
                std::cout << constantById(stack.popUInt16());
                break;
            case BC_POP:
                stack.pop();
                break;

            case BC_LOADDVAR0:
                stack.pushDouble(var_map[0].getDouble());
                break;
            case BC_LOADDVAR1:
                stack.pushDouble(var_map[1].getDouble());
                break;
            case BC_LOADDVAR2:
                stack.pushDouble(var_map[2].getDouble());
                break;
            case BC_LOADDVAR3:
                stack.pushDouble(var_map[3].getDouble());
                break;

            case BC_LOADIVAR0:
                stack.pushInt64(var_map[0].getInt64());
                break;
            case BC_LOADIVAR1:
                stack.pushInt64(var_map[1].getInt64());
                break;
            case BC_LOADIVAR2:
                stack.pushInt64(var_map[2].getInt64());
                break;
            case BC_LOADIVAR3:
                stack.pushInt64(var_map[3].getInt64());
                break;

            case BC_LOADSVAR0:
                stack.pushUInt16(var_map[0].getUInt16());
                break;
            case BC_LOADSVAR1:
                stack.pushUInt16(var_map[1].getUInt16());
                break;
            case BC_LOADSVAR2:
                stack.pushUInt16(var_map[2].getUInt16());
                break;
            case BC_LOADSVAR3:
                stack.pushUInt16(var_map[3].getUInt16());
                break;

            case BC_STOREDVAR0:
                var_map[0].setDouble(stack.popDouble());
                break;
            case BC_STOREIVAR0:
                var_map[0].setInt64(stack.popInt64());
                break;
            case BC_STORESVAR0:
                var_map[0].setUInt16(stack.popUInt16());
                break;

            case BC_LOADDVAR:
                stack.pushDouble(var_map[bytecode->getUInt16(bci + 1)].getDouble());
                break;
            case BC_LOADIVAR:
                stack.pushInt64(var_map[bytecode->getUInt16(bci + 1)].getInt64());
                break;
            case BC_LOADSVAR:
                stack.pushUInt16(var_map[bytecode->getUInt16(bci + 1)].getUInt16());
                break;

            case BC_STOREDVAR:
                var_map[bytecode->getUInt16(bci + 1)].setDouble(stack.popDouble());
                break;
            case BC_STOREIVAR:
                var_map[bytecode->getUInt16(bci + 1)].setInt64(stack.popInt64());
                break;
            case BC_STORESVAR:
            //                  out << name << " @" << getUInt16(bci + 1);
                var_map[bytecode->getUInt16(bci + 1)].setUInt16(stack.popUInt16());
                break;

            //              case BC_LOADCTXDVAR:
            //              case BC_STORECTXDVAR:
            //              case BC_LOADCTXIVAR:
            //              case BC_STORECTXIVAR:
            //              case BC_LOADCTXSVAR:
            //              case BC_STORECTXSVAR:
            ////                  out << name << " @" << getUInt16(bci + 1)
            ////                      << ":" << getUInt16(bci + 3);
            //                  break;
            case BC_IFICMPNE:
                if (stack.popInt64() != stack.popInt64()) {
                    bci += bytecode->getInt16(bci + 1) + 1;
                    continue;
                }
                break;
            case BC_IFICMPE:
                if (stack.popInt64() == stack.popInt64()) {
                    bci += bytecode->getInt16(bci + 1) + 1;
                    continue;
                }
                break;
            case BC_IFICMPG:
                if (stack.popInt64() > stack.popInt64()) {
                    bci += bytecode->getInt16(bci + 1) + 1;
                    continue;
                }
                break;
            case BC_IFICMPGE:
                if (stack.popInt64() >= stack.popInt64()) {
                    bci += bytecode->getInt16(bci + 1) + 1;
                    continue;
                }
                break;
            case BC_IFICMPL: 
                if (stack.popInt64() < stack.popInt64()) {
                    bci += bytecode->getInt16(bci + 1) + 1;
                    continue;
                }
                break;
            case BC_IFICMPLE:
                if (stack.popInt64() <= stack.popInt64()) {
                    bci += bytecode->getInt16(bci + 1) + 1;
                    continue;
                }
                break;
            case BC_JA:
                bci += bytecode->getInt16(bci + 1) + 1;
                continue;
                break;
            case BC_CALL://{
                stack.pushTyped(bci + length);
                stack.pushTyped(function->id());

//                std::clog << "saving return address: " << function->id() << ":" << bci + length << std::endl;
//                uint16_t f = stack.popUInt16();
//                size_t b = stack.popTyped<size_t>();
//                std::clog << "checking return address: " << f << ":" << b << std::endl;
//                stack.pushTyped(bci + length);
//                stack.pushTyped(function->id());

                function = (BytecodeFunction*) functionById(bytecode->getUInt16(bci + 1));
                if (!function) {
                  return new Status("Unresolved function ID\n", bci);
                }
                bytecode = function->bytecode();
                bci = 0;
                continue;
                break;//}
            case BC_CALLNATIVE:
                return new Status("Native functions are currently not supported\n", bci);
                break;
            case BC_RETURN: {
                uint16_t new_function_id = stack.popUInt16();
//                std::clog << "new func id=" << new_function_id << std::endl;
                function = (BytecodeFunction*) functionById(new_function_id);
                if (!function) {
                  return new Status("Unresolved function ID\n", bci);
                }
                bytecode = function->bytecode();
                size_t new_bci = stack.popTyped<size_t>();
//                std::clog << "new bci=" << new_bci << std::endl;
                bci = new_bci;
                continue;
                break;
            }
            case BC_BREAK:
                return new Status("Breakpoints are currently not supported\n", bci);
                break;
            default:
                return new Status("Unknown or unsupported instruction\n", bci);
        }
        bci += length;
    }
#ifdef ENABLE_TRACING
    std::cout << "Result = " << var_map[0].getInt64() << std::endl;
#endif
    return 0;
}
示例#7
0
Bytecode* Context::bytecodeByFunctionId(uint16_t id) {
  BytecodeFunction* function = functionById(id);
  return (function == 0) ? 0 : function->bytecode();
}