/*
 * Copyright (c) 2007 Wayne Meissner. All rights reserved.
 *
 * For licensing, see LICENSE.SPECS
 */

#include <stdlib.h>
#include <stdbool.h>
#ifndef _WIN32
# include <pthread.h>
#else
# include <windows.h>
# include <process.h>
#endif

#define R(T, rtype) rtype testClosureVr##T(rtype (*closure)(void)) { \
    return closure != NULL ? (*closure)() : (rtype) 0; \
}

#define P(T, ptype) void testClosure##T##rV(void (*closure)(ptype), ptype a1) { \
    if (closure != NULL) (*closure)(a1); \
}

void testClosureVrV(void (*closure)(void))
{
    (*closure)();
}

R(Z, bool);
R(B, char);
R(S, short);
R(I, int);
R(L, long);
R(J, long long);
R(LL, long long);
R(F, float);
R(D, double);
R(P, const void*);


P(Z, bool);
P(B, char);
P(S, short);
P(I, int);
P(L, long);
P(J, long long);
P(LL, long long);
P(F, float);
P(D, double);
P(P, const void*);
P(UL, unsigned long);

#if defined(_WIN32) && !defined(_WIN64)
bool __stdcall testClosureStdcall(long *a1, void __stdcall(*closure)(void *, long), long a2) { \
    void* sp_pre;
    void* sp_post;

    asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
    (*closure)(a1, a2);
    asm volatile (" movl %%esp,%0" : "=g" (sp_post));

    /* %esp before pushing parameters on the stack and after the call returns
     * should be equal, if both sides respects the stdcall convention */
    return sp_pre == sp_post;
}
#endif

void testOptionalClosureBrV(void (*closure)(char), char a1)
{
    if (closure) {
        (*closure)(a1);
    }
}


struct ThreadVrV {
    void (*closure)(void);
    int count;
};

static void *
threadVrV(void *arg)
{
    struct ThreadVrV* t = (struct ThreadVrV *) arg;
    
    int i;
    for (i = 0; i < t->count; i++) {
        (*t->closure)();
    }
    
    return NULL;
}

void testThreadedClosureVrV(void (*closure)(void), int n)
{
	struct ThreadVrV arg = {closure, n};
#ifndef _WIN32
    pthread_t t;
    pthread_create(&t, NULL, threadVrV, &arg);
    pthread_join(t, NULL);
#else
    HANDLE hThread = (HANDLE) _beginthread((void (*)(void *))threadVrV, 0, &arg);
    WaitForSingleObject(hThread, INFINITE);	
#endif
}

struct s8f32s32 {
    char s8;
    float f32;
    int s32;
};

// Takes a struct argument
void testClosureTrV(void (*closure)(struct s8f32s32 s), struct s8f32s32* s)
{
    (*closure)(*s);
}

// Returns a struct value
struct s8f32s32 testClosureVrT(struct s8f32s32 (*closure)())
{
    return (*closure)();
}

typedef int (*returnTypeClosure_t)(int) ;
typedef returnTypeClosure_t (*lookupClosure_t)();

int testReturnsClosure(lookupClosure_t lookup, int val)
{
    returnTypeClosure_t func = lookup ? (*lookup)() : NULL;
    return func ? (*func)(val) : 0;
}

static int multiplyByTwo(int value)
{
    return value * 2;
}

returnTypeClosure_t testReturnsFunctionPointer()
{
    return multiplyByTwo;
}

typedef int (*argumentClosure_t)(int);
typedef int (*withArgumentClosure_t)(argumentClosure_t, int);

int testArgumentClosure(withArgumentClosure_t closure_with, argumentClosure_t closure_arg, int val)
{
    return (*closure_with)(closure_arg, val);
}


//
// These macros produce functions of the form:
// testClosureBIrV(void (*closure)(char, int), char a1, int a2) {}
//
#define C2_(J1, J2, N1, N2) \
void testClosure##J1##J2##rV(void (*closure)(N1, N2), N1 a1, N2 a2) \
{ \
    if (closure != NULL) (*closure)(a1, a2); \
}

#define C2(J, N) \
    C2_(B, J, char, N) \
    C2_(S, J, short, N) \
    C2_(I, J, int, N) \
    C2_(LL, J, long long, N) \
    C2_(F, J, float, N) \
    C2_(D, J, double, N) \


C2(B, char);
C2(S, short);
C2(I, int);
C2(LL, long long);
C2(F, float);
C2(D, double);

#define C3_(J1, J2, J3, N1, N2, N3) \
void testClosure##J1##J2##J3##rV(void (*closure)(N1, N2, N3), N1 a1, N2 a2, N3 a3) \
{ \
    (*closure)(a1, a2, a3); \
}


#define C3(J, N) \
    C3_(B, J, B, char, N, char) \
    C3_(S, J, S, short, N, short) \
    C3_(I, J, I, int, N, int) \
    C3_(LL, J, LL, long long, N, long long) \
    C3_(F, J, F, float, N, float) \
    C3_(D, J, D, double, N, double) \

C3(B, char);
C3(S, short);
C3(I, int);
C3(LL, long long);
C3(F, float);
C3(D, double);
C3_(B, S, I, char, short, int);
C3_(B, S, LL, char, short, long long);
C3_(LL, S, B, long long, short, char);
C3_(LL, B, S, long long, char, short);


