Пример #1
0
void Interpreter::loadFunParamsInCtx(uint16_t id) {
    BytecodeFunction* fun = ((BytecodeFunction*)_code->functionById(id));
	uint16_t n = fun->parametersNumber();
    FunctionContext* ctx = this->topContext();

    //cout << "loading params: " << n << endl;
    //cout << "stack size " << _stack.size() << endl;


    for (uint16_t i = 0; i < n; ++i) {
        VarType type = fun->parameterType(i);
        switch (type) {
            case VT_INT:
                ctx->storeInt(ctx->getId(), i, popInt());
                //cout << "int loaded from bc" << endl;
                break;
            case VT_DOUBLE:
            	ctx->storeDouble(ctx->getId(), i, popDouble());
            	//cout << "double loaded from bc" << endl;
            	break;
            default:
            	//cout << "loading STRIG or INVALID from bc" << endl;
            	assert(false);
            	break;
        }
    }
}
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;
}
Пример #3
0
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());
}
Пример #4
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();

}
Пример #5
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));
  }
}
Пример #6
0
    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();
    }
Пример #7
0
void BytecodeVisitor::translateFunction(AstFunction *f) {
    BytecodeFunction* bf = (BytecodeFunction *) code_->functionByName(f->name());
    ScopeContext* new_context = new ScopeContext(bf, f->scope(), context_);
    context_ = new_context;

    for (uint i = 0; i < f->parametersNumber(); ++i) {
        AstVar* var = f->scope()->lookupVariable(f->parameterName(i), false);
        storeVar(var);
    }

    f->node()->visit(this);

    bf->setLocalsNumber(context_->getLocalsNum());
    bf->setScopeId(context_->getId());

    context_ = new_context->getParent();
    delete new_context;

}
Пример #8
0
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());
}
Пример #9
0
 StackObj getContextVar(uint16_t context_id, uint16_t var_id) {
     if (context_id == bf_->scopeId()) {
         if (scope_vars.size() < var_id) {
             throw new std::runtime_error("Uncorrect var");
         }
         return scope_vars[var_id];
     } else if (parent_ != NULL) {
         return parent_->getContextVar(context_id, var_id);
     } else {
         throw new std::runtime_error("Uncorrect var");
     }
 }
Пример #10
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));
  }
}
Пример #11
0
        void storeContextVar(StackObj var, uint16_t context_id, uint16_t var_id) {
            if (context_id == bf_->scopeId()) {
                if (scope_vars.size() < var_id) {
                    throw new runtime_error("Uncorrect var");
                }
                scope_vars[var_id] = var;
            } else if (parent_ != NULL) {
                parent_->storeContextVar(var, context_id, var_id);
            } else {
                throw new std::runtime_error("Uncorrect Var");
            }

        }
Пример #12
0
 Id id()
     { return fn->id(); }
Пример #13
0
 Bytecode* bc() {
     return bf_->bytecode();
 }
Пример #14
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;
}
Пример #15
0
Bytecode* Context::bytecodeByFunctionId(uint16_t id) {
  BytecodeFunction* function = functionById(id);
  return (function == 0) ? 0 : function->bytecode();
}