void BytecodeGenerator::visitCallNode(CallNode* node) {
    BytecodeFunction* funToCall = _state.bcFunByName(node->name());
    assert(funToCall);
    Bytecode* bc = _state.currentBcToFill();
    for(size_t i = node->parametersNumber(); i > 0; --i) {
        node->parameterAt(i - 1)->visit(this);
        VarType expectedArgType = funToCall->parameterType(i - 1);
        VarType actualArgType = nodeType(node->parameterAt(i - 1));
        if(actualArgType != expectedArgType) {
            Instruction castInsn = actualArgType == VT_INT ? BC_I2D : BC_D2I;
            bc->addInsn(castInsn);
        }
    }
    bc->addInsn(BC_CALL);
    bc->addInt16(funToCall->id());
}
Exemple #2
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));
  }
}
    void BytecodeVisitor::visitCallNode(CallNode *node) {
        LOG_Visitor("visitCallNode");

        BytecodeFunction *calledFunction = context->getFunction(node->name());
        if (node->parametersNumber() != calledFunction->parametersNumber()) {
            throw TranslationError("Incorrect number of parameters at calling function " + calledFunction->name(), node->position());
        }

        for (int32_t i = node->parametersNumber() - 1; i >= 0; --i) {
            uint32_t j = (uint32_t) i;
            node->parameterAt(j)->visit(this);
            cast(calledFunction->parameterType(j), node, "casting call-node parameters");
        }

        uint16_t functionID = calledFunction->id();
        bc()->addInsn(BC_CALL);
        bc()->addUInt16(functionID);
        topOfStackType = calledFunction->returnType();
    }
void BytecodeVisitor::visitCallNode(CallNode *node) {
    BytecodeFunction* bf = (BytecodeFunction*) code_->functionByName(node->name());
    if (!bf) {
        throw new runtime_error("Function does not exist");
    }
    if (node->parametersNumber() != bf->parametersNumber()) {
        throw new runtime_error("Uncorrect parameters number");
    }

    for (size_t i = node->parametersNumber(); node->parametersNumber() > 0 && i > 0; --i) {
        node->parameterAt(i-1)->visit(this);
        castTos(bf->parameterType(i-1));
    }


    bc()->addInsn(BC_CALL);
    bc()->addUInt16(bf->id());

    setTosType(bf->returnType());
}
Exemple #5
0
 Id id()
     { return fn->id(); }
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;
}