Changeset 630 for trunk

Show
Ignore:
Timestamp:
08/15/08 12:39:56 (5 months ago)
Author:
weyrick
Message:

some work on the runtime output buffering and some llvm module work gives us a hello world module

Location:
trunk/rphp
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/rphp/compiler/pDriver.cpp

    r629 r630  
    2727#include <boost/algorithm/string.hpp> 
    2828 
     29#include "llvm/GlobalVariable.h" 
    2930#include "llvm/System/DynamicLibrary.h" 
    3031#include "llvm/Bitcode/ReaderWriter.h" 
     
    5657 */ 
    5758void pDriver::execute(string fileName) { 
    58     cout << "executing file: " << fileName << endl; 
     59    //cout << "executing file: " << fileName << endl; 
    5960    // TODO: determine file type, then run executeBC or executePHP 
    6061    executeBC(fileName); 
     
    6566 */ 
    6667void pDriver::executeBC(string fileName) { 
    67  
    68     cout << "executing compiled bytecode: " << fileName << endl; 
    6968 
    7069    // Now we create the JIT. 
     
    123122    EE->runStaticConstructorsDestructors(true); 
    124123 
    125     cout << "module ran, return value is: " << gv.IntVal.toStringSigned(10) << endl; 
    126  
    127124    delete EE; 
    128125 
     
    185182 
    186183    // Create the main function: first create the type 'int ()' 
    187     llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::Int32Ty, std::vector<const llvm::Type*>(), 
     184    llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::VoidTy, std::vector<const llvm::Type*>(), 
    188185                                        /*not vararg*/false); 
    189186 
     
    196193    llvm::BasicBlock *BB = llvm::BasicBlock::Create("EntryBlock", F); 
    197194 
    198     // RUNTIME startup/shutdown test 
     195    // ** STARTUP ** 
     196    // runtime engine pointer type 
    199197    const llvm::Type* rEnginePointer = llvm::PointerType::get(llvm::Type::Int8Ty,0); 
     198 
     199    // startup function type 
    200200    llvm::FunctionType *runtimeStartupFuncType = llvm::FunctionType::get(rEnginePointer, std::vector<const llvm::Type*>(), false); 
     201    // startup function 
    201202    llvm::Function *runtimeStartupFunc = llvm::Function::Create(runtimeStartupFuncType, llvm::Function::ExternalLinkage, "rphp_newRuntimeEngine", M); 
    202  
     203    // startup instruction call 
    203204    llvm::Instruction *runtimeStartInstr = llvm::CallInst::Create(runtimeStartupFunc, "runtime"); 
    204205 
     206    // ** hello world ** 
     207    llvm::ArrayType* ArrayTy_0 = llvm::ArrayType::get(llvm::IntegerType::get(8), 12); 
     208    llvm::PointerType* PointerTy_4 = llvm::PointerType::get(llvm::IntegerType::get(8), 0); 
     209    llvm::GlobalVariable* gvar_array__str = new llvm::GlobalVariable( 
     210    /*Type=*/ArrayTy_0, 
     211    /*isConstant=*/true, 
     212    /*Linkage=*/llvm::GlobalValue::InternalLinkage, 
     213    /*Initializer=*/0, // has initializer, specified below 
     214    /*Name=*/".str", 
     215    M); 
     216 
     217    // Constant Definitions 
     218    llvm::Constant* const_array_7 = llvm::ConstantArray::get("hello world", true); 
     219    std::vector<llvm::Constant*> const_ptr_8_indices; 
     220    llvm::Constant* const_int32_9 = llvm::Constant::getNullValue(llvm::IntegerType::get(32)); 
     221    const_ptr_8_indices.push_back(const_int32_9); 
     222    const_ptr_8_indices.push_back(const_int32_9); 
     223    llvm::Constant* const_ptr_8 = llvm::ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_8_indices[0], const_ptr_8_indices.size() ); 
     224    llvm::UndefValue* const_int32_10 = llvm::UndefValue::get(llvm::IntegerType::get(32)); 
     225 
     226    // Global Variable Definitions 
     227    gvar_array__str->setInitializer(const_array_7); 
     228 
     229    // argument sig for print function 
     230    std::vector<const llvm::Type*> printSig; 
     231    printSig.push_back(rEnginePointer); 
     232    printSig.push_back(PointerTy_4); 
     233    // print function type 
     234    llvm::FunctionType *printFuncType = llvm::FunctionType::get(llvm::Type::VoidTy, printSig, false); 
     235    // print function 
     236    llvm::Function *printFunc = llvm::Function::Create(printFuncType, llvm::Function::ExternalLinkage, "rphp_print_cstr", M); 
     237    // push args 
     238    std::vector<llvm::Value*> printArgsV; 
     239    printArgsV.push_back(runtimeStartInstr); 
     240    printArgsV.push_back(const_ptr_8); 
     241    // print instruction call 
     242    llvm::Instruction *printInstr = llvm::CallInst::Create(printFunc, printArgsV.begin(), printArgsV.end()); 
     243 
     244 
     245    //  ** SHUTDOWN ** 
     246    // argument sig for shutdown function 
    205247    std::vector<const llvm::Type*> engineSig(1, rEnginePointer); 
     248    // shutdown function type 
    206249    llvm::FunctionType *runtimeDeleteFuncType = llvm::FunctionType::get(llvm::Type::VoidTy, engineSig, false); 
     250    // shutdown function 
    207251    llvm::Function *runtimeDeleteFunc = llvm::Function::Create(runtimeDeleteFuncType, llvm::Function::ExternalLinkage, "rphp_deleteRuntimeEngine", M); 
    208252 
    209     std::vector<llvm::Value*> ArgsV; 
    210     ArgsV.push_back(runtimeStartInstr); 
    211  
    212     llvm::Instruction *runtimeDeleteInstr = llvm::CallInst::Create(runtimeDeleteFunc, ArgsV.begin(), ArgsV.end()); 
     253    // push args 
     254    std::vector<llvm::Value*> shutdownArgsV; 
     255    shutdownArgsV.push_back(runtimeStartInstr); 
     256 
     257    // shutdown instruction call 
     258    llvm::Instruction *runtimeDeleteInstr = llvm::CallInst::Create(runtimeDeleteFunc, shutdownArgsV.begin(), shutdownArgsV.end()); 
    213259 
    214260    // Get pointers to the constant integers... 
    215     llvm::Value *Two = llvm::ConstantInt::get(llvm::Type::Int32Ty, 2); 
    216     llvm::Value *Three = llvm::ConstantInt::get(llvm::Type::Int32Ty, 3); 
     261    //llvm::Value *Two = llvm::ConstantInt::get(llvm::Type::Int32Ty, 2); 
     262    //llvm::Value *Three = llvm::ConstantInt::get(llvm::Type::Int32Ty, 3); 
    217263 
    218264    // Create the add instruction... does not insert... 
    219     llvm::Instruction *Add = llvm::BinaryOperator::create(llvm::Instruction::Add, Two, Three, 
    220                                                 "addresult"); 
     265    //llvm::Instruction *Add = llvm::BinaryOperator::create(llvm::Instruction::Add, Two, Three, "addresult"); 
    221266 
    222267    // explicitly insert it into the basic block... 
    223     BB->getInstList().push_back(Add); 
     268    //BB->getInstList().push_back(Add); 
    224269 
    225270    BB->getInstList().push_back(runtimeStartInstr); 
     271    BB->getInstList().push_back(printInstr); 
    226272    BB->getInstList().push_back(runtimeDeleteInstr); 
    227273 
    228274    // Create the return instruction and add it to the basic block 
    229     BB->getInstList().push_back(llvm::ReturnInst::Create(Add)); 
     275    BB->getInstList().push_back(llvm::ReturnInst::Create()); 
     276    //BB->getInstList().push_back(llvm::ReturnInst::Create(Add)); 
    230277 
    231278    if (llvm::verifyModule(*M, llvm::PrintMessageAction)) { 
  • trunk/rphp/runtime/include/pOutputBuffer.h

    r598 r630  
    2626    class pOutputBuffer { 
    2727 
    28         // default size of a new output buffer 
    29         // note that for unicode strings, memory space is 2*defBufSize 
    30         static const std::size_t defBufSize = 512; 
     28    public: 
    3129 
    3230        typedef enum { bufTypeBinary, bufTypeUnicode } bufTypeT; 
    3331 
    34         private: 
    35              
    36             pUString *uBuffer; 
    37             pBString *bBuffer; 
    38             bufTypeT bType; 
    39  
    40         public: 
    41  
    4232            // constructors 
    4333 
    44             // default builds a unicode buffer, default size 
    45             pOutputBuffer() : uBuffer(new pUString(defBufSize,' ',0)), bType(bufTypeUnicode) { } 
    46  
    47             // specify type, default size 
    48             pOutputBuffer(bufTypeT t) : bType(t) { 
     34            // specify type 
     35            pOutputBuffer(bufTypeT t) : bBuffer(0), uBuffer(0), bType(t) { 
    4936                switch (t) { 
    5037                    case bufTypeBinary: 
    51                         bBuffer = new pBString(defBufSize,' '); 
     38                        bBuffer = new pBString(); 
    5239                        break; 
    5340                    case bufTypeUnicode: 
    54                         uBuffer = new pUString(defBufSize,' ',0); 
    55                         break; 
    56                 } 
    57             } 
    58  
    59             // specify type, size 
    60             pOutputBuffer(bufTypeT t, std::size_t s) : bType(t) { 
    61                 switch (t) { 
    62                     case bufTypeBinary: 
    63                         bBuffer = new pBString(s,' '); 
    64                         break; 
    65                     case bufTypeUnicode: 
    66                         uBuffer = new pUString(s,' ',0); 
     41                        uBuffer = new pUString(); 
    6742                        break; 
    6843                } 
     
    7752            } 
    7853 
     54            const char* getRawBuffer() { 
     55                switch (bType) { 
     56                    case bufTypeBinary: 
     57                        return bBuffer->c_str(); 
     58                    case bufTypeUnicode: 
     59                        return (const char*)uBuffer->getTerminatedBuffer(); 
     60                } 
     61            } 
     62 
     63            void operator<< (const pBString& str) { 
     64                switch (bType) { 
     65                    case bufTypeBinary: 
     66                        bBuffer->append(str); 
     67                        break; 
     68                    case bufTypeUnicode: 
     69                        // TODO: this doesn't seem so efficient. but how often will it be used? 
     70                        uBuffer->append(pUString(str.c_str(),str.length(), US_INV)); 
     71                        break; 
     72                } 
     73            } 
     74 
     75            void operator<< (const pUString& str) { 
     76                if (bType == bufTypeBinary) { 
     77                    // convert to unicode buffer 
     78                    uBuffer = new pUString(bBuffer->c_str(), bBuffer->length(), US_INV); 
     79                    delete bBuffer; 
     80                } 
     81                uBuffer->append(str); 
     82            } 
     83 
     84    private: 
     85 
     86            pUString *uBuffer; 
     87            pBString *bBuffer; 
     88            bufTypeT bType; 
     89 
    7990    }; 
    8091 
  • trunk/rphp/runtime/include/pOutputManager.h

    r598 r630  
    2222#include <stack> 
    2323#include "pOutputBuffer.h" 
     24#include "pTypes.h" 
    2425 
    2526namespace rphp { 
     27 
     28    class pRuntimeEngine; 
    2629 
    2730    class pOutputManager { 
    2831 
    2932        private: 
    30             std::stack<pOutputBuffer> bufferStack; 
     33            pRuntimeEngine* runtime; 
     34            std::stack<pOutputBuffer*> bufferStack; 
    3135 
    3236        public: 
    3337 
    3438            // constructors 
    35             pOutputManager() { 
     39            pOutputManager(pRuntimeEngine *r) : runtime(r) { 
    3640                // default output buffer 
    37                 bufferStack.push(pOutputBuffer()); 
     41                // TODO: check the runtime config for which type of default buffer to use 
     42                bufferStack.push(new pOutputBuffer(pOutputBuffer::bufTypeBinary)); 
     43            } 
     44 
     45            ~pOutputManager() { 
     46                flushAndFreeAll(); 
     47            } 
     48 
     49            // flush one or more buffers 
     50            void flushAndFreeAll(); 
     51 
     52            // printing to the current buffer 
     53            void print(pBString str) { 
     54                if (bufferStack.empty()) 
     55                    return; 
     56                *bufferStack.top() << str; 
     57            } 
     58 
     59            void print(pUString str) { 
     60                if (bufferStack.empty()) 
     61                    return; 
     62                *bufferStack.top() << str; 
    3863            } 
    3964 
  • trunk/rphp/runtime/include/pRuntime.h

    r629 r630  
    3131 
    3232        private: 
    33  
    34             // output buffering management 
    35             pOutputManager* outputManager; 
    36  
    3733            // extension manager 
    3834            // --> for loading and registering dynamic extensions (pcre, mysql, etc) and their associated functions, classes 
     
    6965            pFunctionManager* functionManager; 
    7066 
     67            // output buffering management 
     68            pOutputManager* outputManager; 
     69 
    7170    }; 
    7271 
     
    8281    void rphp_deleteRuntimeEngine(rphp::pRuntimeEngine*); 
    8382 
     83    // print to runtime output buffer 
     84    void rphp_print_cstr(rphp::pRuntimeEngine*, char* str); 
     85 
    8486} 
    8587 
  • trunk/rphp/runtime/pOutputManager.cpp

    r598 r630  
    1717 * ***** END LICENSE BLOCK ***** */ 
    1818 
     19#include <iostream> 
    1920#include "pOutputManager.h" 
    2021 
    2122namespace rphp { 
     23 
     24void pOutputManager::flushAndFreeAll() { 
     25    while( !bufferStack.empty() ) { 
     26        std::cout << bufferStack.top()->getRawBuffer(); 
     27        delete bufferStack.top(); 
     28        bufferStack.pop(); 
     29    } 
     30} 
    2231 
    2332 
  • trunk/rphp/runtime/pRuntime.cpp

    r629 r630  
    2020#include "pRuntime.h" 
    2121#include "pExtManager.h" 
     22#include "pOutputManager.h" 
    2223#include "pFunctionManager.h" 
    2324 
     
    2526 
    2627pRuntimeEngine::pRuntimeEngine() : extManager(new pExtManager(this)), 
    27                                    functionManager(new pFunctionManager(this)) 
     28                                   functionManager(new pFunctionManager(this)), 
     29                                   outputManager(new pOutputManager(this)) 
    2830{ 
    29     std::cout << "runtime is starting" << std::endl; 
    30  
    3131    // runtime initialization 
    3232    extManager->startUp(); 
     
    3737pRuntimeEngine::~pRuntimeEngine() { 
    3838 
    39     std::cout << "runtime is shutting down" << std::endl; 
    40  
    4139    // runtime shutdown 
     40    delete outputManager; // will flush 
    4241    delete functionManager; 
    4342    delete extManager; 
     
    5251    // create a new runtime engine 
    5352    rphp::pRuntimeEngine* rphp_newRuntimeEngine() { 
    54         std::cout << "in C API runtime now" << std::endl; 
    5553        rphp::pRuntimeEngine* rt = new rphp::pRuntimeEngine(); 
    5654        return rt; 
     
    5957    // destroy runtime engine 
    6058    void rphp_deleteRuntimeEngine(rphp::pRuntimeEngine* e) { 
    61         std::cout << "closing in C API runtime now" << std::endl; 
    6259        delete e; 
    6360    } 
    6461 
     62    // print a c string to the current output buffer in the given runtime 
     63    void rphp_print_cstr(rphp::pRuntimeEngine* e, char* str) { 
     64        e->outputManager->print(rphp::pBString(str)); 
     65    } 
     66 
     67 
    6568} 
    6669