Пример #1
0
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction2(int fntype, int fn, int code1, int code2)
{
  int size2;
  unsigned char *block;
  unsigned char *outp;

  int myfunc;
  int sizes1=((int *)code1)[0];
  int sizes2=((int *)code2)[0];

  myfunc = getFunctionAddress(fntype, fn, &size2);

  block=(unsigned char *)newTmpBlock(2+size2+sizes1+sizes2+4);

  ((int*)block)[0]=2+size2+sizes1+sizes2;
  outp=block+4;
  memcpy(outp,(char*)code1+4,sizes1); 
  outp+=sizes1;
  *outp++ = X86_PUSH_EAX;
  memcpy(outp,(char*)code2+4,sizes2); 
  outp+=sizes2;
  *outp++ = X86_POP_EBX;

  memcpy(block+4+2+sizes1+sizes2,(void*)myfunc,size2);

  g_evallib_computTableTop++;

  return ((int)(block));

}
Пример #2
0
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction1(int fntype, int fn, int code)
{
  int size,size2;
  char *block;
  int myfunc;
  void *func1;
  
  size =((int *)code)[0];
  func1 = (void *)(code+4);

  myfunc = getFunctionAddress(fntype, fn, &size2);

  block=(char *)newTmpBlock(4+size+size2);
  ((int*)block)[0]=size+size2;

  memcpy(block+4, func1, size);
  memcpy(block+size+4,(void*)myfunc,size2);

  g_evallib_computTableTop++;

  return ((int)(block));
}
Пример #3
0
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3)
{
  int sizes1=((int *)code1)[0];
  int sizes2=((int *)code2)[0];
  int sizes3=((int *)code3)[0];

  if (fntype == MATH_FN && fn == 0) // special case: IF
  {
    void *func3;
    int size;
    int *ptr;
    char *block;

    unsigned char *newblock2,*newblock3;

    newblock2=newBlock(sizes2+1);
    memcpy(newblock2,(char*)code2+4,sizes2);
    newblock2[sizes2]=X86_RET;

    newblock3=newBlock(sizes3+1);
    memcpy(newblock3,(char*)code3+4,sizes3);
    newblock3[sizes3]=X86_RET;

    l_stats[2]+=sizes2+sizes3+2;
    
    func3 = realAddress(_asm_if,_asm_if_end,&size);

    block=(char *)newTmpBlock(4+sizes1+size);
    ((int*)block)[0]=sizes1+size;
    memcpy(block+4,(char*)code1+4,sizes1);
    ptr=(int *)(block+4+sizes1);
    memcpy(ptr,func3,size);

    ptr=findFBlock((char*)ptr); *ptr++=(int)newblock2;
    ptr=findFBlock((char*)ptr); *ptr=(int)newblock3;

    return (int)block;

  }
  else
  {
    int size2;
    unsigned char *block;
    unsigned char *outp;

    int myfunc;
  
    myfunc = getFunctionAddress(fntype, fn, &size2);

    block=(unsigned char *)newTmpBlock(4+size2+sizes1+sizes2+sizes3+4);

    ((int*)block)[0]=4+size2+sizes1+sizes2+sizes3;
    outp=block+4;
    memcpy(outp,(char*)code1+4,sizes1); 
    outp+=sizes1;
    *outp++ = X86_PUSH_EAX;
    memcpy(outp,(char*)code2+4,sizes2); 
    outp+=sizes2;
    *outp++ = X86_PUSH_EAX;
    memcpy(outp,(char*)code3+4,sizes3); 
    outp+=sizes3;
    *outp++ = X86_POP_EBX;
    *outp++ = X86_POP_ECX;

    memcpy(block+4+4+sizes1+sizes2+sizes3,(void*)myfunc,size2);
    g_evallib_computTableTop++;

    return ((int)(block));  
  }
}
Пример #4
0
int test1() {
    // Get global context - not sure what the impact is of sharing
    // the global context
    llvm::LLVMContext &context = llvm::getGlobalContext();

    // Module is the translation unit
    std::unique_ptr<llvm::Module> theModule =
        std::unique_ptr<llvm::Module>(new llvm::Module("ravi", context));
    llvm::Module *module = theModule.get();
    llvm::IRBuilder<> builder(context);

#if defined(_WIN32) && (!defined(_WIN64) || LLVM_VERSION_MINOR < 7)
    // On Windows we get error saying incompatible object format
    // Reading posts on mailining lists I found that the issue is that COEFF
    // format is not supported and therefore we need to set -elf as the object
    // format
    auto triple = llvm::sys::getProcessTriple();
    // module->setTargetTriple("x86_64-pc-win32-elf");
    module->setTargetTriple(triple + "-elf");
#endif

    // create a GCObject structure as defined in lobject.h
    llvm::StructType *structType =
        llvm::StructType::create(context, "RaviGCObject");
    llvm::PointerType *pstructType =
        llvm::PointerType::get(structType, 0); // pointer to RaviGCObject
    std::vector<llvm::Type *> elements;
    elements.push_back(pstructType);
    elements.push_back(llvm::Type::getInt8Ty(context));
    elements.push_back(llvm::Type::getInt8Ty(context));
    structType->setBody(elements);
    structType->dump();

    // Create printf declaration
    std::vector<llvm::Type *> args;
    args.push_back(llvm::Type::getInt8PtrTy(context));
    // accepts a char*, is vararg, and returns int
    llvm::FunctionType *printfType =
        llvm::FunctionType::get(builder.getInt32Ty(), args, true);
    llvm::Constant *printfFunc =
        module->getOrInsertFunction("printf", printfType);

    // Create the testfunc()
    args.clear();
    args.push_back(pstructType);
    llvm::FunctionType *funcType =
        llvm::FunctionType::get(builder.getInt32Ty(), args, false);
    llvm::Function *mainFunc = llvm::Function::Create(
                                   funcType, llvm::Function::ExternalLinkage, "testfunc", module);
    llvm::BasicBlock *entry =
        llvm::BasicBlock::Create(context, "entrypoint", mainFunc);
    builder.SetInsertPoint(entry);

    // printf format string
    llvm::Value *formatStr = builder.CreateGlobalStringPtr("value = %d\n");

    // Get the first argument which is RaviGCObject *
    auto argiter = mainFunc->arg_begin();
    llvm::Value *arg1 = argiter++;
    arg1->setName("obj");

    // Now we need a GEP for the second field in RaviGCObject
    std::vector<llvm::Value *> values;
    llvm::APInt zero(32, 0);
    llvm::APInt one(32, 1);
    // This is the array offset into RaviGCObject*
    values.push_back(
        llvm::Constant::getIntegerValue(llvm::Type::getInt32Ty(context), zero));
    // This is the field offset
    values.push_back(
        llvm::Constant::getIntegerValue(llvm::Type::getInt32Ty(context), one));

    // Create the GEP value
    llvm::Value *arg1_a = builder.CreateGEP(arg1, values, "ptr");

    // Now retrieve the data from the pointer address
    llvm::Value *tmp1 = builder.CreateLoad(arg1_a, "a");
    // As the retrieved value is a byte - convert to int i
    llvm::Value *tmp2 =
        builder.CreateZExt(tmp1, llvm::Type::getInt32Ty(context), "i");

    // Call the printf function
    values.clear();
    values.push_back(formatStr);
    values.push_back(tmp2);
    builder.CreateCall(printfFunc, values);

    // return i
    builder.CreateRet(tmp2);
    module->dump();

    // Lets create the MCJIT engine
    std::string errStr;
#if LLVM_VERSION_MINOR > 5
    std::unique_ptr<llvm::Module> module_(module);
    auto engine = llvm::EngineBuilder(std::move(module_))
                  .setErrorStr(&errStr)
                  .setEngineKind(llvm::EngineKind::JIT)
                  .create();
#else
    auto engine = llvm::EngineBuilder(module)
                  .setErrorStr(&errStr)
                  .setEngineKind(llvm::EngineKind::JIT)
                  .setUseMCJIT(true)
                  .create();
#endif
    if (!engine) {
        std::cerr << "Failed to construct MCJIT ExecutionEngine: " << errStr
                  << "\n";
        return 1;
    }

    // Now lets compile our function into machine code
    std::string funcname = "testfunc";
    myfunc_t funcptr = (myfunc_t)engine->getFunctionAddress(funcname);
    if (funcptr == nullptr) {
        std::cerr << "Failed to obtain compiled function\n";
        return 1;
    }

    // Run the function and test results.
    RaviGCObject obj = {NULL, 42, 65};
    int ans = funcptr(&obj);
    printf("The answer is %d\n", ans);
    return ans == 42 ? 0 : 1;
}