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;
}
Пример #2
0
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());
    }
}
Пример #3
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));
  }
}