Current results of few days of reading LLVM docs/tutorials and one day of hacking.
Basically we can create something like:
int foo() {
printf("Hello World\n");
return 42;
}
In run-time. With LLVM. JIT in parrot is getting closer :)
There is full code:
~/src/parrot (opsc_llvm)$ cat llvm.nqp
#! parrot-nqp
pir::load_bytecode("LLVM.pbc");
pir::loadlib("llvm_engine");
# Create new module.
my $module := LLVM::Module.new.BUILD("HELLO");
# Create forward declaration of "printf".
my $printf := $module.add_function(
"printf", # name
LLVM::Type::int32(), # return type
LLVM::Type::pointer(LLVM::Type::int8()), # first arg - char*
:va_args<1> # varargs
);
# Add it to module
my $function := $module.add_function("hello", LLVM::Type::int32());
# Start building our function
my $bb := $function.append_basic_block("the_block");
# We'll use Builder. He've got some brains about how to deal with LLVM.
my $builder := LLVM::Builder.new.BUILD();
# Start within block.
$builder.set_position($bb);
# This will be our argument to "printf"
my $hello_str := $builder.global_string("****** Hello LLVM World ******\n", "");
# Call "printf"
$builder.call($printf, $hello_str);
# Return from function
my $answer := LLVM::Constant::integer(42);
$builder.ret($answer);
# Let's execute it
# We need some engine
my $engine := pir::new__psp("LLVM_Engine", $module.unwrap());
# .create return NCI PMC.
my $call := $engine.create(
$function.unwrap(), # Function to call
"I" # Singnature. In this case - return int, no args
);
# Call it!
my $res := $call();
pir::say("Result of call: $res");
# vim: ft=perl6
~/src/parrot (opsc_llvm)$ ./parrot-nqp llvm.nqp
****** Hello LLVM World ******
Result of call: 42