Recursive function calls

36 views
Skip to first unread message

itre...@gmail.com

unread,
May 11, 2011, 3:36:47 PM5/11/11
to asmjit-dev
Hi all—

I'm using AsmJit to generate some functions that will recursively call
themselves. All the given examples I can find load the address of
function like this:

GPVar address(c.newGP());
c.mov(address, imm((sysint_t)(void*)(*callee)->native));
ECall* ctx = c.call(address);

That's all well and good, but the trouble is I want to call a
generated function, in this case, one that isn't finished being built
at the time the 'call' is generated, and thus doesn't have an address.
Any thoughts, ideas, or workarounds?

Many thanks!

Petr Kobalíček

unread,
May 11, 2011, 8:32:25 PM5/11/11
to asmji...@googlegroups.com
Hi,

currently this is quite non-explored area. There was a problem using
two functions and calling function which has not generated yet. If you
can generate all functions using one Compiler instance then it should
work, but I think that more support should be added to AsmJit to
simplify it.

I added small example called testfuncrecursive1.cpp to the AsmJit-svn.

It looks like this:

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

#include <AsmJit/Compiler.h>
#include <AsmJit/Logger.h>
#include <AsmJit/MemoryManager.h>

// Type of generated function.
typedef int (*MyFn)(int);

int main(int argc, char* argv[])
{
using namespace AsmJit;
Compiler c;

// Log compiler output.
FileLogger logger(stderr);
c.setLogger(&logger);

ECall* ctx;
Label skip(c.newLabel());

EFunction* func = c.newFunction(CALL_CONV_DEFAULT,
FunctionBuilder1<int, int>());
func->setHint(FUNCTION_HINT_NAKED, true);

GPVar var(c.argGP(0));
c.cmp(var, imm(1));
c.jle(skip);

GPVar tmp(c.newGP(VARIABLE_TYPE_INT32));
c.mov(tmp, var);
c.dec(tmp);

ctx = c.call(func->getEntryLabel());
ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder1<int, int>());
ctx->setArgument(0, tmp);
ctx->setReturn(tmp);
c.mul_lo_hi(var, c.newGP(VARIABLE_TYPE_INT32), tmp);

c.bind(skip);
c.ret(var);
c.endFunction();

MyFn fn = function_cast<MyFn>(c.make());
printf("Factorial 5 == %d\n", fn(5));
MemoryManager::getGlobal()->free((void*)fn);

return 0;
}

and it works;)

Best regards
Petr Kobalicek

Reply all
Reply to author
Forward
0 new messages