llvm::BasicBlock* SwitchExpression::HandleDefault(std::map<std::string, llvm::BasicBlock*>& association, WasmFunction* fct, llvm::IRBuilder<>& builder) const { // So the default block can be defined by a case node or an expression node. VariableCaseDefinition* variable_def = dynamic_cast<VariableCaseDefinition*>(default_); if (variable_def != nullptr) { // Then return the pointer from the association, it should have been created. return association[variable_def->GetString()]; } // Otherwise we have a ExpressionCaseDefinition. ExpressionCaseDefinition* expr_case = dynamic_cast<ExpressionCaseDefinition*>(default_); assert(expr_case != nullptr); Expression* expr = expr_case->GetExpression(); // Create a block for it. BasicBlock* default_code = BasicBlock::Create(llvm::getGlobalContext(), "default", fct->GetFunction()); builder.SetInsertPoint(default_code); // Now generate the code. expr->Codegen(fct, builder); // Now return the block. return default_code; }
llvm::Value* BlockExpression::Codegen(WasmFunction* fct, llvm::IRBuilder<>& builder) { // For now, there is no reason to really care about block. for (std::list<Expression*>::const_iterator it = list_->begin(); it != list_->end(); it++) { Expression* expr = *it; expr->Codegen(fct, builder); } return nullptr; }
void WasmScript::GenerateGeneralScriptCalls(WasmFile* file) { // Now generate this function prototype: execute_script: // Returns a integer is the result of all script. // If successful, returns -1. // It will fail otherwise and return the line number of the failure. // This method has no parameters. std::vector<llvm::Type*> params; // Then get the result: integer. llvm::Type* result_type = llvm::Type::getInt32Ty(llvm::getGlobalContext()); WasmModule* wasm_module = file->GetAssertModule(); llvm::Module* module = wasm_module->GetModule(); // Finally, create the function type. llvm::FunctionType* fct_type = llvm::FunctionType::get(result_type, params, false); const char* name = "execute_script"; llvm::Function* fct = llvm::Function::Create(fct_type, Function::ExternalLinkage, name, module); // Now create the first bb. llvm::BasicBlock* bb = llvm::BasicBlock::Create(getGlobalContext(), "entry", fct); llvm::IRBuilder<> builder(getGlobalContext()); builder.SetInsertPoint(bb); WasmFunction* wasm_fct = new WasmFunction(nullptr, name, fct, wasm_module, INT_32); const char* result_name = "result"; Variable* result = new Variable(result_name); wasm_fct->Allocate(result_name, llvm::Type::getInt32Ty(llvm::getGlobalContext()), builder); // Now generate our IR and then use our codegen for it. for (auto elem : script_elems_) { Expression* expr = nullptr; if (dynamic_cast<WasmInvoke*>(elem) != nullptr) { expr = HandleInvoke(elem); } else { CallExpression* call = HandleAssert(wasm_module, elem); // Set the value in a local. SetLocal* set = new SetLocal(result, call); // In the assert_return case, we want to compare this to -1. Const* minus_one = new Const(INT_32, new ValueHolder(-1)); Operation* op = new Operation(NE_OPER, INT_32); Binop* cmp = new Binop(op, set, minus_one); // Now we can generate the return 0; GetLocal* get = new GetLocal(result); ReturnExpression* return_expr = new ReturnExpression(get); // Finally, generate the AST for this assert. IfExpression* inst = new IfExpression(cmp, return_expr); expr = inst; } // Now we can generate it. expr->Codegen(wasm_fct, builder); delete expr, expr = nullptr; } Const* one = new Const(INT_32, new ValueHolder(-1)); ReturnExpression* return_expr = new ReturnExpression(one); return_expr->Codegen(wasm_fct, builder); delete return_expr, return_expr = nullptr; }