void BytecodeGenerationVisitor::visitCallNode(CallNode* node) { const Signature& sign = code->functionByName(node->name())->signature(); AstFunction* f = currentScope->lookupFunction(node->name()); for (unsigned int i = 0; i < node->parametersNumber(); i++) { AstVar* v = f->scope()->lookupVariable(sign[i + 1].second); uint16_t varId = getVarId(v); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_LOADVAR]); bytecode->addInt16(varId); } for (unsigned int i = 0; i < node->parametersNumber(); i++) { node->parameterAt(i)->visit(this); if (currentType == VT_INT && sign[i + 1].first == VT_DOUBLE) { bytecode->addInsn(BC_I2D); } else if (currentType == VT_DOUBLE && sign[i + 1].first == VT_INT) { bytecode->addInsn(BC_D2I); } } for (int i = node->parametersNumber(); i > 0; i--) { AstVar* v = f->scope()->lookupVariable(sign[i].second); uint16_t varId = getVarId(v); bytecode->addInsn(insnByUntypedInsn[sign[i].first][UT_STOREVAR]); bytecode->addInt16(varId); } bytecode->addInsn(BC_CALL); bytecode->addInt16(code->functionByName(node->name())->id()); if (sign[0].first == VT_VOID) { for (unsigned int i = node->parametersNumber(); i > 0; i--) { AstVar* v = f->scope()->lookupVariable(sign[i].second); uint16_t varId = getVarId(v); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]); bytecode->addInt16(varId); } } else { for (unsigned int i = node->parametersNumber(); i > 0; i--) { AstVar* v = f->scope()->lookupVariable(sign[i].second); uint16_t varId = getVarId(v); bytecode->addInsn(BC_SWAP); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]); bytecode->addInt16(varId); } } currentType = sign[0].first; }
void ByteCodeVisitor::visitCallNode(mathvm::CallNode *node) { unsigned long stackSize = currStack->size(); AstFunction *astFunction = currScope->lookupFunction(node->name(), true); AstFunctionInfo *functionInfo = (AstFunctionInfo *) astFunction->info(); Scope *parameterScope = astFunction->scope(); if (node->parametersNumber() != parameterScope->variablesCount()) { error("parameters number mistmach in calling %s", node->name().c_str()); } vector<VarType> declaredParameters; declaredParameters.reserve(parameterScope->variablesCount()); Scope::VarIterator varIterator(parameterScope); while (varIterator.hasNext()) { declaredParameters.push_back(varIterator.next()->type()); } vector<VarType>::reverse_iterator it = declaredParameters.rbegin(); for (uint32_t i = node->parametersNumber(); i > 0; --i, ++it) { AstNode *n = node->parameterAt(i - 1); n->visit(this); cast(topStack(), (*it)); } insn(BC_CALL); typed(functionInfo->function->id()); if (astFunction->returnType() != VT_VOID) { pushStack(astFunction->returnType()); } }
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)); } }