void CodeGenVisitor::JIT(Expression* e) { StatementList* sl = new StatementList(); sl->addStatement(new ReturnStatement(e)); FunctionDefinition* fd = new FunctionDefinition(Type::INT, "", new ParameterList(), sl); value_ = 0; fd->accept(this); if (!value_) { delete fd; throw "error evaluating expression"; } llvm::Function* f = dynamic_cast<llvm::Function*>(value_); void* fPtr = ee_->getPointerToFunction(f); // some casting ... because we like magic int (*fP)() = (int (*)())(intptr_t)fPtr; std::cout << "Evaluated to: " << fP() << std::endl; // throw it away f->eraseFromParent(); }
void Compiler::appendBaseConstructor(FunctionDefinition const& _constructor) { CompilerContext::LocationSetter locationSetter(m_context, _constructor); FunctionType constructorType(_constructor); if (!constructorType.getParameterTypes().empty()) { solAssert(m_baseArguments.count(&_constructor), ""); std::vector<ASTPointer<Expression>> const* arguments = m_baseArguments[&_constructor]; solAssert(arguments, ""); for (unsigned i = 0; i < arguments->size(); ++i) compileExpression(*(arguments->at(i)), constructorType.getParameterTypes()[i]); } _constructor.accept(*this); }
void Compiler::appendConstructor(FunctionDefinition const& _constructor) { CompilerContext::LocationSetter locationSetter(m_context, _constructor); // copy constructor arguments from code to memory and then to stack, they are supplied after the actual program if (!_constructor.getParameters().empty()) { unsigned argumentSize = 0; for (ASTPointer<VariableDeclaration> const& var: _constructor.getParameters()) if (var->getType()->isDynamicallySized()) { argumentSize = 0; break; } else argumentSize += var->getType()->getCalldataEncodedSize(); CompilerUtils(m_context).fetchFreeMemoryPointer(); if (argumentSize == 0) { // argument size is dynamic, use CODESIZE to determine it m_context.appendProgramSize(); // program itself // CODESIZE is program plus manually added arguments m_context << eth::Instruction::CODESIZE << eth::Instruction::SUB; } else m_context << u256(argumentSize); // stack: <memptr> <argument size> m_context << eth::Instruction::DUP1; m_context.appendProgramSize(); m_context << eth::Instruction::DUP4 << eth::Instruction::CODECOPY; m_context << eth::Instruction::ADD; CompilerUtils(m_context).storeFreeMemoryPointer(); appendCalldataUnpacker( FunctionType(_constructor).getParameterTypes(), true, CompilerUtils::freeMemoryPointer + 0x20 ); } _constructor.accept(*this); }