void Tree::insertBuiltInTypesInGlobalNameBindings() { // Start generating the object class. auto objectClass = ClassDefinition::create(Keyword::objectString, &globalNameBindings); globalNameBindings.insertClass(Keyword::objectString, objectClass); objectClass->generateDefaultConstructor(); // Add method: // virtual bool equals(object obj) auto equalsMethod = MethodDefinition::create(BuiltInTypes::objectEqualsMethodName, Type::create(Type::Boolean), false, objectClass); auto objectType = Type::create(Type::Object); objectType->setDefinition(objectClass); equalsMethod->addArgument(objectType, "obj"); equalsMethod->setIsVirtual(true); objectClass->appendMember(equalsMethod); // Add method: // virtual int hash() auto hashMethod = MethodDefinition::create(BuiltInTypes::objectHashMethodName, Type::create(Type::Boolean), false, objectClass); hashMethod->setIsVirtual(true); objectClass->appendMember(hashMethod); // Create the primitive types (and some other types). auto viodClass = insertBuiltInType("void"); insertBuiltInType("_"); insertBuiltInType("lambda"); insertBuiltInType(Keyword::funString); insertBuiltInType("implicit"); auto byteClass = insertBuiltInType(Keyword::byteString); auto charClass = insertBuiltInType(Keyword::charString); auto floatClass = insertBuiltInType(Keyword::floatString); auto intClass = insertBuiltInType(Keyword::intString); auto longClass = insertBuiltInType(Keyword::longString); auto boolClass = insertBuiltInType(Keyword::boolString); // Now that the primitive types exist we can set the definitions of the // return types of the methods in the object class. objectClass->getDefaultConstructor()->getReturnType()->setDefinition( viodClass); equalsMethod->getReturnType()->setDefinition(boolClass); hashMethod->getReturnType()->setDefinition(intClass); // Add equals() methods to the primitive types. addEqualsMethod(byteClass, Type::Byte); addEqualsMethod(charClass, Type::Char); addEqualsMethod(floatClass, Type::Float); addEqualsMethod(intClass, Type::Integer); addEqualsMethod(longClass, Type::Integer); addEqualsMethod(boolClass, Type::Boolean); }
void travCompare(astree* root) { int sym = root->symbol; root->block = blockcount; int left = getReturnType(root->children[0]); int right = getReturnType(root->children[1]); switch (sym) { case TOK_EQ: case TOK_NE: if( left == right || left == TOK_NULL || right == TOK_NULL) { return; } else { errprintf("%zu.%zu.%zu Comparison is not of same type.\n", root->filenr, root->linenr,root->offset); } break; case TOK_GE: case TOK_GT: case TOK_LE: case TOK_LT: if ( left == right && (right == TOK_INTCON || right == TOK_CHARCON)) { return; } else { errprintf("%zu.%zu.%zu Comparison is not of same type" " or is not of primitive type.\n", root->filenr, root->linenr,root->offset); } break; } }
void ReturnNode::generateIntermediateCode(IntermediateCode *intermediateCode, vector<Instruction *>*instructionVector) { ImmediateArgument *zeroImmediate = new ImmediateArgument(0); ImmediateArgument *oneImmediate = new ImmediateArgument(1); if(getReturnType()==DATA_TYPE_BOOLEAN){ expression_->setFalseLabelNumber( intermediateCode->getNextLabelNumber() ); expression_->setTrueLabelNumber( LABEL_FALL ); } expression_->generateIntermediateCode(intermediateCode, instructionVector); if(getReturnType()==DATA_TYPE_INTEGER) intermediateCode->addInstruction(instructionVector, new ReturnInstruction(expression_->getAddress())); else if(getReturnType()==DATA_TYPE_BOOLEAN){ int label = (getNextLabelNumber()==LABEL_FALL)?intermediateCode->getNextLabelNumber():getNextLabelNumber(); InstructionLabel *instructionLabel = new InstructionLabel(label); intermediateCode->addInstruction(instructionVector, new ReturnInstruction( oneImmediate )); intermediateCode->addInstruction(instructionVector, new GotoInstruction( instructionLabel )); intermediateCode->setPendingLabelNumber( expression_->getFalseLabelNumber() ); intermediateCode->addInstruction(instructionVector, new ReturnInstruction( zeroImmediate )); if(getNextLabelNumber()==LABEL_FALL) intermediateCode->setPendingLabelNumber( label ); intermediateCode->addInstructionArgumentToCleanUpList( instructionLabel ); } intermediateCode->addInstructionArgumentToCleanUpList( oneImmediate ); intermediateCode->addInstructionArgumentToCleanUpList( zeroImmediate ); }
// {_,Float}:rp_get_original_return(...) static cell AMX_NATIVE_CALL rp_get_return(AMX *amx, cell *params) { if (PARAMS_COUNT == 0) { MF_LogError(amx, AMX_ERR_NATIVE, "%s called without destination parameters.", __FUNCTION__); return 0; } if (!g_currentHandler) { MF_LogError(amx, AMX_ERR_NATIVE, "Trying get return value without active hook."); return 0; } auto func = &g_currentHandler->func; dword value; double fvalue; bool success; switch (func->getReturnRegister()) { case r_eax: success = g_hookManager.getReturn(&value); break; case r_st0: success = g_hookManager.getReturn(&fvalue); *(float *)&value = (float)fvalue; break; default: setError("Function without return type."); return 0; // no return } if (!success) { MF_LogError(amx, AMX_ERR_NATIVE, "%s", g_lastError); return 0; } if (PARAMS_COUNT == 2) { if (func->getReturnType() != bt_string) { MF_LogError(amx, AMX_ERR_NATIVE, "Return value isn't string."); return 0; } // TODO: implement getting of array via ConvertToAmxArray g_amxxapi.SetAmxString(amx, params[1], (char *)value, params[2]); return value; } cell* addr = g_amxxapi.GetAmxAddr(amx, params[1]); *addr = ConvertToAmxType(value, func->getReturnType()); return 1; }
llvm::Function* genFunctionTranslationStub(Module& module, llvm::Function* function, SEM::FunctionType functionType, SEM::FunctionType translatedFunctionType) { const auto llvmTranslatedFunctionType = genFunctionType(module, translatedFunctionType); const auto stubIdPair = std::make_pair(function, llvmTranslatedFunctionType); const auto iterator = module.functionPtrStubMap().find(stubIdPair); if (iterator != module.functionPtrStubMap().end()) { return iterator->second; } const auto argInfo = getFunctionArgInfo(module, functionType); const auto translatedArgInfo = getFunctionArgInfo(module, translatedFunctionType); const auto llvmFunction = createTranslationStubFunction(module, function, translatedArgInfo); module.functionPtrStubMap().insert(std::make_pair(stubIdPair, llvmFunction)); Function functionGenerator(module, *llvmFunction, translatedArgInfo); auto& builder = functionGenerator.getBuilder(); const auto returnVar = argInfo.hasReturnVarArgument() ? translatedArgInfo.hasReturnVarArgument() ? functionGenerator.getReturnVar() : genAlloca(functionGenerator, translatedFunctionType.returnType()) : nullptr; TranslatedArguments arguments = getTranslatedArguments(functionGenerator, functionType, translatedFunctionType, returnVar, argInfo, translatedArgInfo); const auto result = genRawFunctionCall(functionGenerator, argInfo, function, arguments); if (argInfo.hasReturnVarArgument() && !translatedArgInfo.hasReturnVarArgument()) { builder.CreateRet(builder.CreateLoad(returnVar)); } else { if (llvmTranslatedFunctionType->getReturnType()->isVoidTy()) { builder.CreateRetVoid(); } else { if (result->getType()->isPointerTy()) { builder.CreateRet(builder.CreatePointerCast(result, llvmTranslatedFunctionType->getReturnType())); } else { builder.CreateRet(result); } } } return llvmFunction; }
void FunctionNode::generateCCode(ostream &out) { switch(getReturnType()) { case DATA_TYPE_INTEGER: out << "int"; break; case DATA_TYPE_BOOLEAN: out << "char"; break; case DATA_TYPE_VOID: out << "void"; break; default: break; } out << " "; const char *str = getIdentifier(); while(*str) { out << (char)tolower(*str); str++; } this->declarations_->generateCCode(out); this->statements_->generateCCode(out); out << "}" << endl; }
void checkCall(astree* curr) { if(lookup(curr->children[0]->lexinfo)) { symbol *fnSym = lookupSym(curr->children[0]->lexinfo); if(curr->children.size()-1!=fnSym->parameters->size()) { errprintf("%zu.%zu.%zu Parameters of defined function" " do not match\n", curr->children[0]->filenr,curr->children[0]->linenr, curr->children[0]->offset); } else { for(size_t i = 0; i<fnSym->parameters->size(); i++) { int paramType = getIdentReturn(fnSym->parameters->at(i)); int callParam = getReturnType(curr->children[i+1]); if(paramType!=callParam) { if(callParam == TOK_NULL) continue; errprintf("%zu.%zu.%zu Argument type does not match" " defined function argument type.\n",curr-> children[i+1]->filenr,curr->children[i+1]-> linenr,curr->children[i+1]->offset); } } } } else { errprintf("%zu.%zu.%zu Function not defined\n", curr->children[0]->filenr,curr->children[0]->linenr, curr->children[0]->offset); } }
void FunctionCallNode::generateIntermediateCode(IntermediateCode *intermediateCode, vector<Instruction *>*instructionVector) { actualParameterList_->generateIntermediateCode(intermediateCode, instructionVector); IdentifierArgument *functionIdentifierArgument = new IdentifierArgument(functionInfo_);//remember to delete it somewhere TemporaryArgument *dest = intermediateCode->getNextTemporary(); ImmediateArgument *zeroImmediate = new ImmediateArgument(0); InstructionLabel *trueLabel = new InstructionLabel(getTrueLabelNumber()); InstructionLabel *falseLabel = new InstructionLabel(getFalseLabelNumber()); this->setAddress(dest); intermediateCode->addInstruction(instructionVector, new CallInstruction(functionIdentifierArgument, actualParameterList_->getAddress(), dest) ); if(getReturnType()==DATA_TYPE_BOOLEAN){ if(getFalseLabelNumber()==LABEL_FALL) intermediateCode->addInstruction(instructionVector, new ConditionalGotoInstruction( RELATIONAL_OPERATOR_DIFFERENT, getAddress(), zeroImmediate, trueLabel ) ); else if(getTrueLabelNumber()==LABEL_FALL) intermediateCode->addInstruction(instructionVector, new ConditionalGotoInstruction( RELATIONAL_OPERATOR_EQUAL, getAddress(), zeroImmediate, falseLabel ) ); else{ intermediateCode->addInstruction(instructionVector, new ConditionalGotoInstruction( RELATIONAL_OPERATOR_DIFFERENT, getAddress(), zeroImmediate, trueLabel ) ); intermediateCode->addInstruction(instructionVector, new GotoInstruction( falseLabel ) ); } } intermediateCode->addInstructionArgumentToCleanUpList(functionIdentifierArgument); intermediateCode->addInstructionArgumentToCleanUpList(falseLabel); intermediateCode->addInstructionArgumentToCleanUpList(trueLabel); intermediateCode->addInstructionArgumentToCleanUpList(zeroImmediate); }
bool ThunkBuilder::buildIL() { TR::IlType *pWord = typeDictionary()->PointerTo(Word); uint32_t numArgs = _numCalleeParams+1; TR::IlValue **args = (TR::IlValue **) comp()->trMemory()->allocateHeapMemory(numArgs * sizeof(TR::IlValue *)); // first argument is the target address args[0] = Load("target"); // followed by the actual arguments for (uint32_t p=0; p < _numCalleeParams; p++) { uint32_t a=p+1; args[a] = ConvertTo(_calleeParamTypes[p], LoadAt(pWord, IndexAt(pWord, Load("args"), ConstInt32(p)))); } TR::IlValue *retValue = ComputedCall("thunkCallee", numArgs, args); if (getReturnType() != NoType) Return(retValue); Return(); return true; }
bool typechkArr ( astree* node, astree* node1) { int right2 = getReturnType(node1->children[1]); int right1 = getReturnType(node1->children[0]); if(right2!=TOK_INTCON) { errprintf("%zu.%zu.%zu Array size allocator not of type int.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); return false; } else if(node->symbol == right1) { return true; } else { errprintf("%zu.%zu.%zu Type check error: %s does not match %s\n" ,node->children[0]->filenr,node->children[0]->linenr, node->children[0]->offset,get_yytname(node->symbol), get_yytname(right1)); return false; } }
void Tree::lookupAndSetTypeDefinitionInCurrentTree( Type* type, const NameBindings& scope, const Location& location) { auto definition = scope.lookupType(type->getName()); if (definition == nullptr) { Trace::error("Unknown type: " + type->getName(), location); } type->setDefinition(definition); auto classDefinition = definition->dynCast<ClassDefinition>(); if (classDefinition != nullptr && classDefinition == getCurrentClass()) { classDefinition->setRecursive(true); } if (type->isFunction()) { auto signature = type->getFunctionSignature(); lookupAndSetTypeDefinitionInCurrentTree(signature->getReturnType(), scope, location); for (auto argumentType: signature->getArguments()) { lookupAndSetTypeDefinitionInCurrentTree(argumentType, scope, location); } } if (type->hasGenericTypeParameters()) { // The type has generic type parameters. This means the type must refer // to a generic class. if (classDefinition == nullptr) { Trace::error("Only classes can take type parameters: " + type->getName(), location); } if (!classDefinition->isGeneric()) { Trace::error("Only generic classes can take type parameters: " + type->getName(), location); } for (auto typeParameter: type->getGenericTypeParameters()) { lookupAndSetTypeDefinitionInCurrentTree(typeParameter, scope, location); } } }
/* taken from http://delta.affinix.com/2006/08/14/invokemethodwithvariants/ thanks to Justin Karneges once again :) */ bool MaiaXmlRpcServerConnection::invokeMethodWithVariants(QObject *obj, const QByteArray &method, const QVariantList &args, QVariant *ret, Qt::ConnectionType type) { // QMetaObject::invokeMethod() has a 10 argument maximum if(args.count() > 10) return false; QList<QByteArray> argTypes; for(int n = 0; n < args.count(); ++n) argTypes += args[n].typeName(); // get return type int metatype = 0; QByteArray retTypeName = getReturnType(obj->metaObject(), method, argTypes); if(!retTypeName.isEmpty() && retTypeName != "QVariant") { metatype = QMetaType::type(retTypeName.data()); if(metatype == 0) // lookup failed return false; } QGenericArgument arg[10]; for(int n = 0; n < args.count(); ++n) arg[n] = QGenericArgument(args[n].typeName(), args[n].constData()); QGenericReturnArgument retarg; QVariant retval; if(metatype != 0) { retval = QVariant(metatype, (const void *)0); retarg = QGenericReturnArgument(retval.typeName(), retval.data()); } else { /* QVariant */ retarg = QGenericReturnArgument("QVariant", &retval); } if(retTypeName.isEmpty()) { /* void */ if(!QMetaObject::invokeMethod(obj, method.data(), type, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9])) return false; } else { if(!QMetaObject::invokeMethod(obj, method.data(), type, retarg, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9])) return false; } if(retval.isValid() && ret) *ret = retval; return true; }
bool ArCentralForwarder::internalRequestOnce( ArServerClient *client, ArNetPacket *packet, bool tcp) { ReturnType returnType = RETURN_NONE; returnType = getReturnType(packet->getCommand()); // chop off the footer packet->setAddedFooter(true); /* if (strcmp(myClient->getName(packet->getCommand(), true), "getPictureCam1") == 0) printf("Request once for getPictureCam1...\n"); */ // if its video and the last broadcast or request was very recently // then ignore it so we don't wind up using up our wireless // bandwidth // MPL taking this out since it may be causing some problems /* if (returnType == RETURN_VIDEO && (myLastBroadcast[packet->getCommand()]->mSecSince() < 25 || myLastRequest[packet->getCommand()]->mSecSince() < 25)) { ArLog::log(ArLog::Normal, "Ignoring a RETURN_VIDEO of %s since request or broadcast was recent", myClient->getName(packet->getCommand(), true)); return; } */ // if its a type where we keep track then put it into the list if (returnType == RETURN_SINGLE || returnType == RETURN_UNTIL_EMPTY || returnType == RETURN_VIDEO || returnType == RETURN_VIDEO_OPTIM) { //if (returnType == RETURN_UNTIL_EMPTY) //printf("Trying to request once %s\n", myClient->getName(packet->getCommand(), true)); checkRequestOnces(packet->getCommand()); myRequestOnces[packet->getCommand()]->push_back(client); } bool ret; ArLog::log(ArLog::Verbose, "%sRequesting %s once", myPrefix.c_str(), myClient->getName(packet->getCommand())); if (tcp) ret = myClient->requestOnceByCommand(packet->getCommand(), packet); else ret = myClient->requestOnceByCommandUdp(packet->getCommand(), packet); setLastRequest(packet->getCommand()); return ret; }
bool AcdkOrbIdl::writeField(StringBuffer& sb, const ClazzInfo* ci, const ClazzFieldInfo* fi, int flags) { if (_noFields == true) return false; if ((fi->flags & MiPublic) == false) return false; if ((flags & MiStatic) && ((fi->flags & MiStatic) == false)) return false; if (((flags & MiStatic) == false) && (fi->flags & MiStatic)) return false; if (isException(fi->type) == true) return false; sb << " attribute " << getReturnType(fi->type) << " " << paramName(fi->name) << ";\n"; return true; }
void traverseFunc(astree* root, int symbol) { for (size_t a = 0; a < root->children.size(); ++a) { int sym = root->children[a]->symbol; astree* curr = root->children[a]; switch(sym) { case TOK_VARDECL: case '=': travVardecl(curr); break; case TOK_IF: case TOK_WHILE: validCompare(curr); symbol_stack.push_back(nullptr); blockcount++; traverseAstree(curr->children[1]); blockcount--; symbol_stack.pop_back(); break; case TOK_IFELSE: validCompare(curr); symbol_stack.push_back(nullptr); blockcount++; traverseAstree(curr->children[1]); blockcount--; symbol_stack.pop_back(); symbol_stack.push_back(nullptr); blockcount++; traverseAstree(curr->children[2]); blockcount--; symbol_stack.pop_back(); break; case TOK_RETURN: if( getReturnType(curr->children[0]) != symbol ) { char *tname = (char* )get_yytname (symbol); if (strstr (tname, "TOK_") == tname) tname += 4; errprintf("%zu.%zu.%zu Return type does not match return" " type of " "function (%s)\n", curr->filenr, curr->linenr, curr->offset, tname); } break; case TOK_CALL: checkCall(curr); break; } } }
entity *buildFuncEntity(ANTLR3_BASE_TREE *scope) { char *string; static int func_n = 0; entity *e = malloc(sizeof(entity)); e->name = (char *)scope->toString(scope->getChild(scope, 0))->chars; e->classe = FUNC_DECLARATION; e->type = getReturnType(scope); e->infos = scope->getChildCount(scope->getChild(scope, 1)); e->etiquette = malloc(sizeof(char) * 10); // Create unique etiquette for the function sprintf(e->etiquette, "FUNC_%d", func_n++); return e; }
void FunctionNode::debug(ASTDebugger * astDebugger, int nodeLevel) { astDebugger->openParentNode("Function/Procedure", nodeLevel); string functionIdentifier = "Identifier: "; functionIdentifier += getIdentifier(); string functionReturnType = "Return Type: "; functionReturnType += getDataTypeName( getReturnType() ); astDebugger->insertLeafNode(functionIdentifier.c_str(), nodeLevel + 1); astDebugger->insertLeafNode(functionReturnType.c_str(), nodeLevel + 1); this->declarations_->debug(astDebugger, nodeLevel + 1); this->statements_->debug(astDebugger, nodeLevel + 1); astDebugger->closeParentNode("Function/Procedure", nodeLevel); }
// rp_set_raw_return(aby:value) static cell AMX_NATIVE_CALL rp_set_raw_return(AMX *amx, cell *params) { if (PARAMS_COUNT == 0) { MF_LogError(amx, AMX_ERR_NATIVE, "%s called without source parameters.", __FUNCTION__); return 0; } if (!g_currentHandler) { MF_LogError(amx, AMX_ERR_NATIVE, "Trying get return value without active hook."); return 0; } auto func = &g_currentHandler->func; dword value = params[1]; switch (func->getReturnType()) { case bt_short: value = (dword)short(value); break; case bt_word: value &= 0xFFFF; break; case bt_char: value = (dword)char(value); break; case bt_byte: value &= 0xFF; break; case bt_float: case bt_double: return g_hookManager.setReturnValue((double)*(float *)&value); case bt_unknown: case bt_void: setError("Function without return type."); return 0; // no return } return g_hookManager.setReturnValue(value); }
void ArCentralForwarder::internalRequestChanged(long interval, unsigned int command) { /* if (strcmp(myClient->getName(command, true), "getPictureCam1") == 0) printf("Changed getPictureCam1 to %d...\n", interval); */ if (interval == -2) { ArLog::log(ArLog::Verbose, "%sStopping request for %s", myPrefix.c_str(), myClient->getName(command, true)); myClient->requestStopByCommand(command); setLastRequest(command); } else { ReturnType returnType; returnType = getReturnType(command); if (returnType == RETURN_VIDEO && interval != -1) { ArLog::log(ArLog::Verbose, "%sIgnoring a RETURN_VIDEO attempted request of %s at %d interval since RETURN_VIDEOs cannot request at an interval", myPrefix.c_str(), myClient->getName(command, true), interval); return; } if (returnType == RETURN_VIDEO_OPTIM && interval != -1) { ArLog::log(ArLog::Verbose, "%sIgnoring a RETURN_VIDEO_OPTIM attempted request of %s at %d interval since RETURN_VIDEOs cannot request at an interval", myPrefix.c_str(), myClient->getName(command, true), interval); return; } ArLog::log(ArLog::Verbose, "%sRequesting %s at interval of %ld", myPrefix.c_str(), myClient->getName(command, true), interval); myClient->requestByCommand(command, interval); setLastRequest(command); // if the interval is -1 then also requestOnce it so that anyone // connecting after the first connection can actually get data too myClient->requestOnceByCommand(command); } }
bool AcdkOrbIdl::writeMethod(StringBuffer& sb, const ClazzInfo* ci, const ClazzMethodInfo* mi, int flags) { if ((mi->flags & MiPublic) == false) return false; if (isCompatible(ci, mi) == false) return false; if (_suppressDublicatedMethods == true && isMethodDefinedInSuper(ci, getLabel(mi)) == true) return false; if (flags & MiStatic) { if ((mi->flags & MiMiConstructor) == false && (mi->flags & MiStatic) == false) return false; } else { if ((mi->flags & MiMiConstructor) || (mi->flags & MiStatic)) return false; } if (strcmp(mi->name, "getClass") == 0) return false; if (mi->altlabel != 0) sb << "\n // orginal method name: " << (char*)mi->name << "\n "; sb << " "; sb << getReturnType(mi->returnType) << " "; if (flags & MiStatic && (mi->flags & MiMiConstructor)) sb << "createCor"; sb << (char*)getLabel(mi) << "("; for (int i = 0; mi->methodArgs[i] != 0; ++i) { if (i != 0) sb << ", "; writeMethodArg(sb, ci, mi, mi->methodArgs[i]); } sb << ");\n"; return true; }
void FunctionNode::generateIntermediateCode(IntermediateCode *intermediateCode) { declarations_->generateIntermediateCode(intermediateCode); //NopInstruction *nopInstruction = new NopInstruction(); //FunctionLabel *functionLabel = new FunctionLabel(getIdentifier()); //nopInstruction->setLabel( functionLabel ); //intermediateCode->addInstruction(nopInstruction, false); statements_->setNextLabelNumber( LABEL_FALL ); vector<Instruction *> *instructionVector = intermediateCode->addInstructionVector(getIdentifier()); statements_->generateIntermediateCode(intermediateCode, instructionVector ); if(getReturnType()==DATA_TYPE_VOID){ intermediateCode->addInstruction(instructionVector, new ReturnInstruction() ); }else{ intermediateCode->addInstruction(instructionVector, new NopInstruction() ); } //intermediateCode->addInstructionArgumentToCleanUpList(functionLabel); }
void travVardecl(astree* root) { astree* node = root->children[0]; astree* node1 = root->children[1]; root->block = blockcount; int sym = node->symbol; int otherSym = getReturnType(node1); switch(sym) { case TOK_INT: checkDecl(node); if(otherSym==TOK_INTCON || otherSym==TOK_NULL) { symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_int); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else if(otherSym == TOK_NEWARRAY) { insertArr(node, node1); } break; case TOK_CHAR: checkDecl(node); if(otherSym==TOK_CHARCON || otherSym==TOK_NULL) { symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_char); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else if(otherSym == TOK_NEWARRAY) { insertArr(node, node1); } break; case TOK_BOOL: checkDecl(node); if(otherSym==TOK_TRUE || otherSym==TOK_FALSE || otherSym==TOK_NULL) { symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_bool); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else if (otherSym == TOK_NEWARRAY) { insertArr(node, node1); } break; case TOK_STRING: checkDecl(node); if(otherSym == TOK_NEWSTRING) { if(node1->children[0]->symbol == TOK_INTCON || otherSym==TOK_NULL) { symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_string); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0] ->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else { errprintf("%zu.%zu.%zu String size allocator not of " "type int.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); } } else if (otherSym == TOK_STRINGCON || otherSym==TOK_NULL) { if(otherSym!=TOK_NULL) strvec.push_back(node1->lexinfo); symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_string); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else if(otherSym == TOK_NEWARRAY) { insertArr(node, node1); } break; case TOK_TYPEID: if(otherSym == TOK_TYPEID || otherSym==TOK_NULL || otherSym == TOK_STRUCT) { if(node1->symbol != TOK_CALL) { string leftStr = *node->lexinfo; string rightStr = *node1->children[0]->lexinfo; if(leftStr != rightStr) { errprintf("%zu.%zu.%zu Type mismatch between constructor " "and declaration.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); } } else { if(lookup(node1->children[0]->lexinfo)) { symbol* funcSym = lookupSym(node1->children[0]->lexinfo); string leftStr = *node->lexinfo; string rightStr = funcSym->type_id; if(leftStr != rightStr) { errprintf("%zu.%zu.%zu Type mismatch between constructor " "and declaration.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); } } } symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_struct); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); newSym->type_id = *node->lexinfo; if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else { errprintf("%zu.%zu.%zu Variable not allocated correctly.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); } break; case TOK_IDENT: if(lookup(node->lexinfo)) { symbol* newSym = lookupSym(node->lexinfo); int type = getIdentReturn(newSym); if(type==TOK_STRUCT&&otherSym==TOK_TYPEID) { if(newSym->type_id!=*node1->children[0]->lexinfo) { errprintf("%zu.%zu.%zu Variable being reassigned wrong " "type",node->filenr,node->linenr,node->offset); } } } else { errprintf("%zu.%zu.%zu" " Variable being referenced is undefined\n",node->filenr, node->linenr,node->offset); } } }
// rp_set_arg(number, ...) static cell AMX_NATIVE_CALL rp_set_arg(AMX *amx, cell *params) { if (PARAMS_COUNT < 2) { MF_LogError(amx, AMX_ERR_NATIVE, "%s called without source parameters.", __FUNCTION__); return 0; } if (!g_currentHandler) { MF_LogError(amx, AMX_ERR_NATIVE, "Trying set arg without active hook."); return 0; } auto func = &g_currentHandler->func; if (func->getArgsCount() < (size_t)params[1]) { MF_LogError(amx, AMX_ERR_NATIVE, "Can't set %i arg, function has only %i arguments.", params[1], func->getArgsCount()); return 0; } auto arg = func->getArgs() + params[1] - 1; dword value; if (PARAMS_COUNT == 3) // array { if (arg->count <= 1) { MF_LogError(amx, AMX_ERR_NATIVE, "Argument %i is not array.", params[1]); return 0; } cell* src = (cell *)(amx->base + (size_t)(((AMX_HEADER *)amx->base)->dat + params[2])); value = ConvertFromAmxArray(src, params[3], func->getReturnType()); } else { value = *g_amxxapi.GetAmxAddr(amx, params[2]); switch (arg->type) { //cse bt_int: case bt_short: value = (dword)short(value); break; case bt_word: value &= 0xFFFF; break; case bt_char: value = (dword)char(value); break; case bt_byte: value &= 0xFF; break; case bt_cbase: value = isEntIndex(value) ? (dword)CBaseOfIndex(value) : value; break; case bt_entvars: value = isEntIndex(value) ? (dword)EntvarsOfIndex(value) : value; break; case bt_edict: value = isEntIndex(value) ? (dword)EdictOfIndex(value) : value; break; case bt_client: value = (value <= (dword)gpGlobals->maxClients ) ? (dword)ClientOfIndex(value) : value; break; case bt_string: value = (dword)getAmxStringTemp(amx, params[2]); break; case bt_float: case bt_double: return g_hookManager.setArg(params[1], (double)*(float *)&value); case bt_unknown: case bt_void: setError("Invalid argument type."); return 0; } } return g_hookManager.setArg(params[1], value); }
// rp_set_return(...) static cell AMX_NATIVE_CALL rp_set_return(AMX *amx, cell *params) { if (PARAMS_COUNT == 0) { MF_LogError(amx, AMX_ERR_NATIVE, "%s called without source parameters.", __FUNCTION__); return 0; } if (!g_currentHandler) { MF_LogError(amx, AMX_ERR_NATIVE, "Trying get return value without active hook."); return 0; } auto func = &g_currentHandler->func; if (PARAMS_COUNT == 2) // array { cell* src = (cell *)(amx->base + (size_t)(((AMX_HEADER *)amx->base)->dat + params[1])); dword value = ConvertFromAmxArray(src, *g_amxxapi.GetAmxAddr(amx, params[2]), func->getReturnType()); return g_hookManager.setReturnValue(value) ? 1 : 0; } dword value = *g_amxxapi.GetAmxAddr(amx, params[1]); switch (func->getReturnType()) { //cse bt_int: case bt_short: value = (dword)short(value); break; case bt_word: value &= 0xFFFF; break; case bt_char: value = (dword)char(value); break; case bt_byte: value &= 0xFF; break; case bt_cbase: value = isEntIndex(value) ? (dword)CBaseOfIndex(value) : value; break; case bt_entvars: value = isEntIndex(value) ? (dword)EntvarsOfIndex(value) : value; break; case bt_edict: value = isEntIndex(value) ? (dword)EdictOfIndex(value) : value; break; case bt_client: value = (/*(int)value >= 0 &&*/ value <= (dword)gpGlobals->maxClients ) ? (dword)ClientOfIndex(value) : value; break; case bt_string: value = (dword)getAmxStringTemp(amx, params[1]); break; case bt_float: case bt_double: return g_hookManager.setReturnValue((double)*(float *)&value); case bt_unknown: case bt_void: setError("Function without return type."); return 0; // no return } return g_hookManager.setReturnValue(value) ? 1 : 0; }
int getReturnType(astree* root) { int sym = root->symbol; switch(sym) { case TOK_NULL: return sym; break; case TOK_INTCON: return sym; break; case TOK_CHARCON: return sym; break; case TOK_BOOL: return sym; break; case TOK_IDENT: if(lookup(root->lexinfo)) { symbol* val = lookupSym(root->lexinfo); return getIdentReturn(val); } else { errprintf("%zu.%zu.%zu" " Variable being referenced is undefined\n",root->filenr, root->linenr,root->offset); return -1; } break; case '+': case '-': case '*': case '/': case '%': { int left = getReturnType(root->children[0]); int right = getReturnType(root->children[1]); if(right == left && right == TOK_INTCON) { return right; } else { errprintf("%zu.%zu.%zu Type check error: %s " "does not match %s\n" ,root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset,get_yytname(left) ,get_yytname(right)); return right; } break; } case TOK_NEWARRAY: return TOK_NEWARRAY; break; case TOK_NEWSTRING: return TOK_NEWSTRING; break; case TOK_CALL: checkCall(root); return getReturnType(root->children[0]); break; case TOK_POS: case TOK_NEG: return getReturnType(root->children[0]); break; case TOK_NEW: return getReturnType(root->children[0]); break; case TOK_TYPEID: return TOK_TYPEID; break; case '.': if(lookup(root->children[0]->lexinfo)) { symbol* tempSym = lookupSym(root->children[0]->lexinfo); string structType = tempSym->type_id; if(structType == "") { errprintf("%zu.%zu.%zu Referenced struct not defined\n", root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset); return -1; } if(lookup(&structType)) { symbol* structSym = lookupSym(&structType); symbol_table* tab = structSym->fields; auto fi = tab->find(root->children[1]->lexinfo); if(fi!=tab->cend()) { symbol* structField = fi->second; return getIdentReturn(structField); } else { errprintf("%zu.%zu.%zu Field not defined\n", root->children[1]->filenr,root->children[1]->linenr, root->children[1]->offset); } } } else { errprintf("%zu.%zu.%zu Referenced struct not defined\n", root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset); } return -1; break; case TOK_ORD: if(getReturnType(root->children[0])==TOK_CHARCON) { return TOK_INTCON; } else { errprintf("%zu.%zu.%zu Ord must be called on type char\n", root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset); } break; case TOK_CHR: if(getReturnType(root->children[0])==TOK_INTCON) { return TOK_CHARCON; } else { errprintf("%zu.%zu.%zu Chr must be called on type int\n", root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset); } break; } }
FunctionEntity *FunctionEntity::clone() { return new FunctionEntity(getIdentifier(), getLineNumber(), getParameterListTypes(), getReturnType()); }
void ArCentralForwarder::receiveData(ArNetPacket *packet) { ReturnType returnType; std::list<ArServerClient *>::iterator it; ArServerClient *client; // chop off the old footer //packet->setLength(packet->getLength() - ArNetPacket::FOOTER_LENGTH); packet->setAddedFooter(true); /* if (strcmp(myClient->getName(packet->getCommand(), true), "getPictureCam1") == 0) printf("Got getPictureCam1...\n"); */ returnType = getReturnType(packet->getCommand()); //printf("Got a packet in for %s %d\n", myClient->getName(packet->getCommand(), true), packet->getCommand()); // this part is seeing if it came from a request_once, if so we // don't service anything else (so we take care of those things that // only happen once better then the ones that are mixing... but that // should be okay) checkRequestOnces(packet->getCommand()); if ((returnType == RETURN_SINGLE || returnType == RETURN_UNTIL_EMPTY) && (it = myRequestOnces[packet->getCommand()]->begin()) != myRequestOnces[packet->getCommand()]->end()) { //if (returnType == RETURN_UNTIL_EMPTY) //printf("Got a packet for %s with length %d %d\n", myClient->getName(packet->getCommand(), true), packet->getDataLength(), packet->getLength()); client = (*it); if (client != NULL) { if (packet->getPacketSource() == ArNetPacket::TCP) client->sendPacketTcp(packet); else if (packet->getPacketSource() == ArNetPacket::UDP) client->sendPacketUdp(packet); else { client->sendPacketTcp(packet); ArLog::log(ArLog::Normal, "%sDon't know what type of packet %s is (%d)", myPrefix.c_str(), myClient->getName(packet->getCommand(), true), packet->getPacketSource()); } } if ((returnType == RETURN_UNTIL_EMPTY && packet->getDataLength() == 0) || returnType == RETURN_SINGLE) { //if (returnType == RETURN_UNTIL_EMPTY) //printf("Got final packet for for %s\n", myClient->getName(packet->getCommand(), true)); myRequestOnces[packet->getCommand()]->pop_front(); } } else if (returnType == RETURN_VIDEO) { // what we do here is send it to the ones that have requested it // but aren't listening for the broadcast... then we broadcast it // to everyone whose listening... this should ensure that everyone // just gets the packet once as often as we see it... while ((it = myRequestOnces[packet->getCommand()]->begin()) != myRequestOnces[packet->getCommand()]->end()) { //printf("Sent a single return_single_and_broadcast for %s\n", myClient->getName(packet->getCommand(), true)); client = (*it); if (client != NULL && client->getFrequency(packet->getCommand()) == -2) { if (packet->getPacketSource() == ArNetPacket::TCP) client->sendPacketTcp(packet); else if (packet->getPacketSource() == ArNetPacket::UDP) client->sendPacketUdp(packet); else { client->sendPacketTcp(packet); ArLog::log(ArLog::Normal, "%sDon't know what type of packet %s is (%d)", myPrefix.c_str(), myClient->getName(packet->getCommand(), true), packet->getPacketSource()); } } myRequestOnces[packet->getCommand()]->pop_front(); } //printf("Broadcast return_single_and_broadcast for %s\n", myClient->getName(packet->getCommand(), true)); myLastBroadcast[packet->getCommand()]->setToNow(); if (packet->getPacketSource() == ArNetPacket::TCP) { myServer->broadcastPacketTcpByCommand(packet, packet->getCommand()); } else if (packet->getPacketSource() == ArNetPacket::UDP) { myServer->broadcastPacketUdpByCommand(packet, packet->getCommand()); } else { myServer->broadcastPacketTcpByCommand(packet, packet->getCommand()); ArLog::log(ArLog::Normal, "%sDon't know what type of packet %s is (%d)", myPrefix.c_str(), myClient->getName(packet->getCommand(), true), packet->getPacketSource()); } } else if (returnType == RETURN_VIDEO_OPTIM) { // what we do here is send it to the ones that have requested it while ((it = myRequestOnces[packet->getCommand()]->begin()) != myRequestOnces[packet->getCommand()]->end()) { client = (*it); /* ArLog::log(ArLog::Normal, "%sSent a return_video_optim for %s to %s", myPrefix.c_str(), myClient->getName(packet->getCommand(), true), client->getIPString()); */ if (client != NULL) { if (packet->getPacketSource() == ArNetPacket::TCP) client->sendPacketTcp(packet); else if (packet->getPacketSource() == ArNetPacket::UDP) client->sendPacketUdp(packet); else { client->sendPacketTcp(packet); ArLog::log(ArLog::Normal, "%sDon't know what type of packet %s is (%d)", myPrefix.c_str(), myClient->getName(packet->getCommand(), true), packet->getPacketSource()); } } myRequestOnces[packet->getCommand()]->pop_front(); } } else { myLastBroadcast[packet->getCommand()]->setToNow(); if (packet->getPacketSource() == ArNetPacket::TCP) { myServer->broadcastPacketTcpByCommand(packet, packet->getCommand()); } else if (packet->getPacketSource() == ArNetPacket::UDP) { myServer->broadcastPacketUdpByCommand(packet, packet->getCommand()); } else { myServer->broadcastPacketTcpByCommand(packet, packet->getCommand()); ArLog::log(ArLog::Normal, "%sDon't know what type of packet %s is (%d)", myPrefix.c_str(), myClient->getName(packet->getCommand(), true), packet->getPacketSource()); } } }