How to Generate and Run Native Code Dynamically

How to generate and run native code dynamically?

Not sure about linux, but this works on x86/windows.

Update: http://codepad.org/sQoF6kR8

#include <stdio.h>
#include <windows.h>

typedef unsigned char byte;

int arg1;
int arg2;
int res1;

typedef void (*pfunc)(void);

union funcptr {
pfunc x;
byte* y;
};

int main( void ) {

byte* buf = (byte*)VirtualAllocEx( GetCurrentProcess(), 0, 1<<16, MEM_COMMIT, PAGE_EXECUTE_READWRITE );

if( buf==0 ) return 0;

byte* p = buf;

*p++ = 0x50; // push eax
*p++ = 0x52; // push edx

*p++ = 0xA1; // mov eax, [arg2]
(int*&)p[0] = &arg2; p+=sizeof(int*);

*p++ = 0x92; // xchg edx,eax

*p++ = 0xA1; // mov eax, [arg1]
(int*&)p[0] = &arg1; p+=sizeof(int*);

*p++ = 0xF7; *p++ = 0xEA; // imul edx

*p++ = 0xA3; // mov [res1],eax
(int*&)p[0] = &res1; p+=sizeof(int*);

*p++ = 0x5A; // pop edx
*p++ = 0x58; // pop eax
*p++ = 0xC3; // ret

funcptr func;
func.y = buf;

arg1 = 123; arg2 = 321; res1 = 0;

func.x(); // call generated code

printf( "arg1=%i arg2=%i arg1*arg2=%i func(arg1,arg2)=%i\n", arg1,arg2,arg1*arg2,res1 );

}

Dynamically compiling and running a react-native app inside another

This is possible partially via CodePush:

  • Create multiple CodePush environments for different apps. (APP1 APP2 etc)
  • When you boot up your app, make an API call to fetch app list and corresponding code push deployment key.
  • on button click codepush.sync(deployment_key) → restart app and then jump directly to your app (maybe store the app name in AsyncStorage and jump directly to it via navigation)

However, the caveat might be a dealbreaker:

  • your app will be reloaded after selecting the app
  • major react version upgrade(native java/oc changes) would require store release as it can't be handled over JS (might not be dealbreaker)

There is also a better way:

  • create one single container app and one CodePush environment
  • have a central configuration like [{app:"A1", version: 2.0.0}, {app: "A2", version: 1.2.0}]
  • all other apps A1, A2, A3 expose objects which can be exposed as plugin to container app.
  • Your CI handles building the app dynamically form the multiple repository (or better - multiple npm packages generated by different repos) and pushes the JS to CodePush server.
  • it adds all apps from the configuration (bash script to yarn add A1, yarn add a2, yarn add a3) to the container,
  • your app reads the configuration and loads the A1 A2 etc.
  • CD creates new CodePush releases.

This is repeated whenever the central configuration changes (say after A1 publishes npm package they update the central configuration).

It solves the problem of restart as you've all bundles build in to one.

CodePush:
https://learn.microsoft.com/en-us/appcenter/distribution/codepush/react-native#dynamic-deployment-assignment

Or go you might want to through expo's code https://github.com/expo/expo/blob/d56076241cef55b0a93a5c0bb8dc690270e42dcb/home/screens/QRCodeScreen.android.js#L89

How could I generate and execute machine code at runtime?

Your question changed substantially (in july 2017). The initial variant referred to the EX (execute) instruction of IBM mainframes.

how could one generate machine code and execute it at runtime with assembly...?

In practice, you would use some JIT compilation library, and there are many of them. Or you would use some dynamic loader. At the lowest level, they all write some byte sequences representing valid machine code—a sequence of many machine instructions—in a memory segment (of your virtual address space) which has to be made executable (read about the NX bit), and then some of your code would jump indirectly to that address or more often call it indirectly—that is call through a function pointer. Most JVM implementations use JIT compilation techniques.

...and as a bonus, without a JIT compiler library, or "manually"?

Supposing you have some valid machine code for the processor architecture that your program is currently executing on, for example, you could get a memory segment (e.g. mmap(2) on Linux), and then make it executable (e.g. mprotect(2)). Most other operating systems provide similar system calls.


If you use a JIT compilation library like asmjit or libjit or libgccjit or LLVM or many others, you first construct in memory a representation (similar to some abstract syntax tree) of the code to be generated, then ask the JIT library to emit machine code for it. You could even write your own JIT compilation code, but it is a lot of work (you need to understand all the details of your instruction set, e.g. x86 for PCs). By the way, generating fast-running machine code is really difficult, because you need to optimize like compilers do (and to care about details like instruction scheduling, register allocation, etc... see also this), and that is why using an existing JIT compilation library (like libgccjit or LLVM) is preferable (a contrario, simpler JIT libraries like asmjit or libjit or GNU lightning don't optimize much and generate poor machine code).

If you use a dynamic loader (e.g. dlopen(3) on POSIX) you would use some external compiler to produce a shared library (that is a plugin) and then you ask the dynamic linker to load it in your process (and handle appropriate relocations) and get by name (using dlsym(3)) some function addresses from it.

Some language implementations (notably SBCL for Common Lisp) are able to emit on the fly some good machine code at every REPL interaction. In essence their runtime embark a full compiler (containing a JIT compilation part).

A trick I often use on Linux is to emit some C (or C++) code at runtime in some temporary file (that is compiling some domain specific language to C or to C++), fork a compilation of it as a plugin, and dynamically load it. With current (laptops, desktops, servers) computers it is fast enough to stay compatible with an interactive loop.

Read also about eval (in particular the famous SICP book), metaprogramming, multistage programming, self-modifying code, continuations, compilers (the Dragon Book), Scott's Programming Language Pragmatics, and J.Pitrat's blog.

Run dynamically compiled C# code at native speed... how?

Yes, if you invoke via a MethodInfo or a non-specific Delegate, then it will indeed be slow. The trick is: don't do that. Various approaches:

  • for individual methods, go via a basic but typed delegate, such as Action, or as a generic catch-all, Func<object[], object> - and use Delegate.CreateDelegate to create a typed delegate:

    Action doSomething = (Action)Delegate.CreateDelegate(typeof(Action), method);

    another variant of this is to use the Expression API (which has a .Compile() method), or DynamicMethod (which has CreateDelegate()). The key thing: you must get a typed delegate and invoke using typed invoke (not .DynamicInvoke).

  • for more complex cases where you are generating whole types, consider implementing an interface you know about, i.e.

    IFoo foo = (IFoo)Activator.CreateInstance(...);

    again; after the initial cast (which is very cheap) you can just use static code:

    foo.Bar();

Do not use someDelegate.DynamicInvoke(...) or someMethod.Invoke(...) if you are after any kind of performance.

Run dynamically generated assembly in C (GNU/Linux)

I think ultimately to be "JIT" you need to be time sensitive which means generate machine code. You might try putting in some debug code that generates both machine code to run and assembly code to verify, run the assembler compare the machine code from the assembly language to the machine code you generated directly and use that to debug/validate the machine code (if possible, sometimes assemblers want to do their own thing, not what you wanted them to do).

How to create dynamic React Native components

Create a State variable buttonClicked=false

<button onclick={() => setState({buttonClicked=true})}/>
{state.buttonClicked?<button></button>:null}

and update state when button clicked

Please set the style for that created button

Can you dynamically compile and link/load C code into a C program?

On POSIX systems (Linix, Mac, UNIX) you have the dlopen and dlsym functions you can work with. These functions can be used to load a shared library at run time and execute a function from it.

As far as creating a library, the simplest thing to do would be to write the relevant source code to a file, run gcc in a separate process to compile it, then use dlopen/dlsym to run the functions it contains.

For example:

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

const char *libsrc =
"#include <stdio.h>\n"
"\n"
"void f1()\n"
"{\n"
" printf(\"in f1\\n\");\n"
"}\n"
"\n"
"int add(int a, int b)\n"
"{\n"
" return a+b;\n"
"}\n";

int main()
{
FILE *libfile = fopen("mylib.c", "w");
fputs(libsrc, libfile);
fclose(libfile);
system("gcc -fPIC -shared -g -Wall -Wextra -o libmylib.so mylib.c");

void *lib = dlopen("libmylib.so", RTLD_NOW);
if (!lib) {
printf("dlopen failed: %s\n", dlerror());
return 1;
}

void (*f)() = dlsym(lib, "f1");
if (f) {
f();
} else {
printf("dlsym for f1 failed: %s\n", dlerror());
}

int (*a)(int, int) = dlsym(lib, "add");
if (a) {
int x = a(2,3);
printf("x=%d\n", x);
} else {
printf("dlsym for add failed: %s\n", dlerror());
}

dlclose(lib);
return 0;
}


Related Topics



Leave a reply



Submit