llvm::Function* WasmImportFunction::GetFunction(WasmModule* module) { if (function_ == nullptr) { // This probably should be done better but will work like this for now. std::string full_name = module_name_ + "_" + function_name_; // Now what we really want is the parameters of this method. std::vector<llvm::Type*> params; Populate(params); // Add to the name the type of the arguments for the import. // Again, probably not what we want finally but this will work. // My problem right now is how to handle the variadic functions well. for (auto elem : params) { full_name += "_"; full_name += GetTypeName(elem); } BISON_PRINT("Import Function not created yet: Internal name: %s Module: %s Function: %s -> Full %s\n", internal_name_.c_str(), module_name_.c_str(), function_name_.c_str(), full_name.c_str()); // Now get the result type. llvm::Type* result_type = ConvertType(result_); // Finally, create the function type. llvm::FunctionType* fct_type = llvm::FunctionType::get(result_type, params, false); // Now create the function. function_ = llvm::Function::Create(fct_type, llvm::Function::ExternalLinkage, full_name, module->GetModule()); } // Paranoid. assert(function_ != nullptr); // Finally we can return the function_. return function_; }
void Unop::Dump(int tabs) const { BISON_TABBED_PRINT(tabs, "("); if (operation_) { operation_->Dump(); } else { BISON_PRINT("Operation is nullptr"); } BISON_PRINT(" "); if (only_) { only_->Dump(); } else { BISON_PRINT("nullptr"); } BISON_PRINT(")"); }
llvm::Value* HandleTypeCasts(llvm::Value* value, llvm::Type* src_type, llvm::Type* dest_type, bool sign, llvm::IRBuilder<>& builder) { if (dest_type != src_type) { llvm::Type::TypeID src_type_id = src_type->getTypeID(); switch (src_type_id) { case llvm::Type::IntegerTyID: { int src_type_bw = src_type->getIntegerBitWidth(); return HandleTypeCastsFromIntegers(value, src_type_bw, dest_type, sign, builder); } case llvm::Type::FloatTyID: return HandleTypeCastsFromFloats(value, dest_type, sign, builder); case llvm::Type::DoubleTyID: return HandleTypeCastsFromDoubles(value, dest_type, sign, builder); case llvm::Type::PointerTyID: // Probably not good to do this. return value; default: { llvm::Type::TypeID dest_type_id = dest_type->getTypeID(); BISON_PRINT("HandleTypeCast failure: destination is %d and src is %d\n", dest_type_id, src_type_id); (void) dest_type_id; assert(0); break; } } } else { // A bit more code to handle integer case llvm::Type::TypeID dest_type_id = dest_type->getTypeID(); if (dest_type_id == llvm::Type::IntegerTyID) { // Now check sizes. int dest_type_bw = dest_type->getIntegerBitWidth(); int src_type_bw = src_type->getIntegerBitWidth(); // We have a problem here. if (dest_type_bw != src_type_bw) { // Handle difference of sizes. value = HandleIntegerTypeCast(value, dest_type, src_type_bw, dest_type_bw, sign, builder); } } return value; } }
WasmFunction* CallExpression::GetCallee(WasmFunction* fct) const { WasmModule* module = fct->GetModule(); WasmFunction* wfct = nullptr; if (call_id_->IsString()) { const char* name = call_id_->GetString(); wfct = module->GetWasmFunction(name); } else { size_t idx = call_id_->GetIdx(); wfct = module->GetWasmFunction(idx); } if (wfct == nullptr) { BISON_PRINT("Problem with finding %s\n", call_id_->GetString()); } assert(wfct != nullptr); return wfct; }