Skip to content

add non-GCC support to compile.c and potion.c #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 79 additions & 62 deletions core/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "opcodes.h"
#include "asm.h"

PN potion_proto_load(Potion *P, PN up, u8 pn, u8 **ptr);

#define PN_ASM1(ins, _a) f->asmb = (PN)potion_asm_op(P, (PNAsm *)f->asmb, (u8)ins, (int)_a, 0)
#define PN_ASM2(ins, _a, _b) f->asmb = (PN)potion_asm_op(P, (PNAsm *)f->asmb, (u8)ins, (int)_a, (int)_b)

Expand Down Expand Up @@ -200,7 +202,7 @@ PN potion_proto_string(Potion *P, PN cl, PN self) {
potion_source_asmb(P, f, loop, 0, t->a[n], reg); \
}
#endif
#define PN_BLOCK(reg, blk, sig) ({ \
#define PN_BLOCK(reg, blk, sig) do { \
PN block = potion_send(blk, PN_compile, (PN)f, sig); \
PN_SIZE num = PN_PUT(f->protos, block); \
PN_ASM2(OP_PROTO, reg, num); \
Expand All @@ -209,32 +211,35 @@ PN potion_proto_string(Potion *P, PN cl, PN self) {
if (numup != PN_NONE) PN_ASM2(OP_GETUPVAL, reg, numup); \
else PN_ASM2(OP_GETLOCAL, reg, PN_GET(f->locals, v)); \
}); \
})
#define PN_UPVAL(name) ({ \
PN_SIZE numl = PN_GET(f->locals, name); \
PN_SIZE numup = PN_NONE; \
if (numl == PN_NONE) { \
numup = PN_GET(f->upvals, name); \
if (numup == PN_NONE) { \
vPN(Proto) up = f; \
int depth = 1; \
while (PN_IS_PROTO(up->source)) { \
up = (struct PNProto *)up->source; \
if (PN_NONE != (numup = PN_GET(up->locals, name))) break; \
depth++; \
} \
if (numup != PN_NONE) { \
up = f; \
while (depth--) { \
up->upvals = PN_PUSH(up->upvals, name); \
up = (struct PNProto *)up->source; \
} \
} \
numup = PN_GET(f->upvals, name); \
} \
} \
numup; \
})
} while(0);

#define PN_UPVAL(name) potion_upval(P, f, name)
inline PN_SIZE potion_upval(Potion *P, struct PNProto * volatile f, PN name) {
PN_SIZE numl = PN_GET(f->locals, name);
PN_SIZE numup = PN_NONE;
if (numl == PN_NONE) {
numup = PN_GET(f->upvals, name);
if (numup == PN_NONE) {
vPN(Proto) up = f;
int depth = 1;
while (PN_IS_PROTO(up->source)) {
up = (struct PNProto *)up->source;
if (PN_NONE != (numup = PN_GET(up->locals, name))) break;
depth++;
}
if (numup != PN_NONE) {
up = f;
while (depth--) {
up->upvals = PN_PUSH(up->upvals, name);
up = (struct PNProto *)up->source;
}
}
numup = PN_GET(f->upvals, name);
}
}
return numup;
}

#define PN_ARG_TABLE(args, reg, inc) potion_arg_asmb(P, f, loop, args, &reg, inc)
#define SRC_TUPLE_AT(src,i) PN_SRC((PN_TUPLE_AT(PN_S(src,0), i)))

Expand Down Expand Up @@ -800,7 +805,7 @@ PN potion_sig_compile(Potion *P, vPN(Proto) f, PN src) {
vPN(Source) t = PN_SRC(src);
if (t->part == AST_LIST && PN_S(t,0) != PN_NIL) {
//PN_TUPLE_EACH(PN_S(t,0), i, v, {
({ struct PNTuple * volatile __tv = ((struct PNTuple *)potion_fwd(PN_S(t,0)));
struct PNTuple * volatile __tv = ((struct PNTuple *)potion_fwd(PN_S(t,0)));
if (__tv->len != 0) {
DBG_c("--- sig compile ---\n");
PN_SIZE i;
Expand Down Expand Up @@ -861,7 +866,6 @@ PN potion_sig_compile(Potion *P, vPN(Proto) f, PN src) {
}
}
}}}
});
}
return sig;
}
Expand Down Expand Up @@ -906,36 +910,49 @@ PN potion_source_compile(Potion *P, PN cl, PN self, PN source, PN sig) {
return (PN)f;
}

#define READ_U8(ptr) ({u8 rpu = *ptr; ptr += sizeof(u8); rpu;})
#define READ_PN(pn, ptr) ({PN rpn = *(PN *)ptr; ptr += pn; rpn;})
#define READ_CONST(pn, ptr) ({ \
PN val = READ_PN(pn, ptr); \
if (PN_IS_PTR(val)) { \
if (val & 2) { \
size_t len = ((val ^ 2) >> 4) - 1; \
val = potion_decimal(P, (char *)ptr, len); \
ptr += len; \
} else { \
size_t len = (val >> 4) - 1; \
val = PN_STRN((char *)ptr, len); \
ptr += len; \
} \
} \
val; \
})
#define READ_U8(ptr) potion_read_u8(ptr)
inline u8 potion_read_u8(u8 * ptr){
u8 rpu = *ptr; ptr += sizeof(u8); return rpu;
}


#define READ_PN(pn, ptr) potion_read_pn(pn, (PN *)ptr)
inline PN potion_read_pn(PN pn, PN * ptr) {
PN rpn = *ptr; ptr += pn; return rpn;
}

#define READ_CONST(pn, ptr) potion_read_const(P, pn, ptr)
inline PN potion_read_const(Potion *P, PN pn, u8 *ptr) {
PN val = READ_PN(pn, ptr);
if (PN_IS_PTR(val)) {
if (val & 2) {
size_t len = ((val ^ 2) >> 4) - 1;
val = potion_decimal(P, (char *)ptr, len);
ptr += len;
} else {
size_t len = (val >> 4) - 1;
val = PN_STRN((char *)ptr, len);
ptr += len;
}
}
return val;
}

#define READ_TUPLE(ptr) \
long i = 0, count = READ_U8(ptr); \
PN tup = potion_tuple_with_size(P, (PN_SIZE)count); \
for (; i < count; i++)
#define READ_VALUES(pn, ptr) ({ \
READ_TUPLE(ptr) PN_TUPLE_AT(tup, i) = READ_CONST(pn, ptr); \
tup; \
})
#define READ_PROTOS(pn, ptr) ({ \
READ_TUPLE(ptr) PN_TUPLE_AT(tup, i) = potion_proto_load(P, (PN)f, pn, &(ptr)); \
tup; \
})
#define READ_VALUES(pn, ptr) potion_read_values(P, pn, ptr)
inline PN potion_read_values(Potion *P, u8 pn, u8 *ptr) {
READ_TUPLE(ptr) PN_TUPLE_AT(tup, i) = READ_CONST(pn, ptr);
return tup;
}

#define READ_PROTOS(pn, ptr) potion_read_protos(P, f, pn, ptr)
inline PN potion_read_protos(Potion *P, struct PNProto * volatile f, u8 pn, u8 *ptr) {
READ_TUPLE(ptr) PN_TUPLE_AT(tup, i) = potion_proto_load(P, (PN)f, pn, &(ptr));
return tup;
}

// TODO: this byte string is volatile, need to avoid using ptr
PN potion_proto_load(Potion *P, PN up, u8 pn, u8 **ptr) {
Expand Down Expand Up @@ -980,9 +997,9 @@ PN potion_source_load(Potion *P, PN cl, PN buf) {
}

// TODO: switch to dump methods
#define WRITE_U8(un, ptr) ({*ptr = (u8)un; ptr += sizeof(u8);})
#define WRITE_PN(pn, ptr) ({*(PN *)ptr = pn; ptr += sizeof(PN);})
#define WRITE_CONST(val, ptr) ({ \
#define WRITE_U8(un, ptr) (*ptr = (u8)un, ptr += sizeof(u8))
#define WRITE_PN(pn, ptr) (*(PN *)ptr = pn, ptr += sizeof(PN))
#define WRITE_CONST(val, ptr) do { \
if (PN_IS_STR(val)) { \
PN count = (PN_STR_LEN(val)+1) << 4; \
WRITE_PN(count, ptr); \
Expand All @@ -998,18 +1015,18 @@ PN potion_source_load(Potion *P, PN cl, PN buf) {
PN cval = (PN_IS_PTR(val) ? PN_NIL : val); \
WRITE_PN(cval, ptr); \
} \
})
} while (0);
#define WRITE_TUPLE(tup, ptr) \
long i = 0, count = PN_TUPLE_LEN(tup); \
WRITE_U8(count, ptr); \
for (; i < count; i++)
#define WRITE_VALUES(tup, ptr) ({ \
#define WRITE_VALUES(tup, ptr) do { \
WRITE_TUPLE(tup, ptr) WRITE_CONST(PN_TUPLE_AT(tup, i), ptr); \
})
#define WRITE_PROTOS(tup, ptr) ({ \
} while (0);
#define WRITE_PROTOS(tup, ptr) do { \
WRITE_TUPLE(tup, ptr) ptr += potion_proto_dumpbc(P, PN_TUPLE_AT(tup, i), \
out, (char *)ptr - PN_STR_PTR(out)); \
})
} while (0);

///\memberof PNProto
/// compile to bytecode
Expand Down
38 changes: 19 additions & 19 deletions core/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef unsigned char u8;
(N)->siz = sizeof(*(N)->ptr) * S; \
(N)->len = 0

#define PN_FLEX_NEEDS(X, N, V, T, S) ({ \
#define PN_FLEX_NEEDS(X, N, V, T, S) do { \
PN_SIZE capa = (N)->siz / sizeof(*(N)->ptr); \
if (capa < (N)->len + X) { \
while (capa < (N)->len + X) \
Expand All @@ -46,24 +46,24 @@ typedef unsigned char u8;
PN_REALLOC(N, V, T, capa); \
(N)->siz = capa; \
} \
})

#define PN_ATOI(X,N,B) ({ \
char *Ap = X; \
long Ai = 0; \
size_t Al = N; \
while (Al--) { \
if ((*Ap >= '0') && (*Ap <= '9')) \
Ai = (Ai * B) + (*Ap - '0'); \
else if ((*Ap >= 'A') && (*Ap <= 'F')) \
Ai = (Ai * B) + ((*Ap - 'A') + 10); \
else if ((*Ap >= 'a') && (*Ap <= 'f')) \
Ai = (Ai * B) + ((*Ap - 'a') + 10); \
else break; \
Ap++; \
} \
Ai; \
})
} while(0);


#define PN_ATOI(X,N,B) potion_atoi(X, N, B)
inline static long potion_atoi(char *Ap, size_t Al, const long B) {
long Ai = 0;
while (Al--) {
if ((*Ap >= '0') && (*Ap <= '9'))
Ai = (Ai * B) + (*Ap - '0');
else if ((*Ap >= 'A') && (*Ap <= 'F'))
Ai = (Ai * B) + ((*Ap - 'A') + 10);
else if ((*Ap >= 'a') && (*Ap <= 'f'))
Ai = (Ai * B) + ((*Ap - 'a') + 10);
else break;
Ap++;
}
return Ai;
}

/// .pnb binary dump header
struct PNBHeader {
Expand Down
24 changes: 19 additions & 5 deletions core/potion.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ and optionally args, statically typed via signature strings.
# include <sys/stat.h>
#endif

#ifdef _MSC_VER
typedef unsigned short _mode_t;
typedef _mode_t mode_t;
#endif

#define _XSTR(s) _STR(s)
#define _STR(s) #s
#define POTION_VERSION _XSTR(POTION_MAJOR) "." _XSTR(POTION_MINOR)
Expand Down Expand Up @@ -241,14 +246,14 @@ struct PNVtable;
#define PN_GET_TUPLE(t) ((struct PNTuple *)potion_fwd((PN)t))
#define PN_TUPLE_LEN(t) PN_GET_TUPLE(t)->len
#define PN_TUPLE_AT(t, n) PN_GET_TUPLE(t)->set[n]
#define PN_TUPLE_COUNT(T, I, B) ({ \
#define PN_TUPLE_COUNT(T, I, B) do { \
struct PNTuple * volatile __t##I = PN_GET_TUPLE(T); \
if (__t##I->len != 0) { \
PN_SIZE I; \
for (I = 0; I < __t##I->len; I++) B \
} \
})
#define PN_TUPLE_EACH(T, I, V, B) ({ \
} while(0);
#define PN_TUPLE_EACH(T, I, V, B) do { \
struct PNTuple * volatile __t##V = PN_GET_TUPLE(T); \
if (__t##V->len != 0) { \
PN_SIZE I; \
Expand All @@ -257,7 +262,7 @@ struct PNVtable;
B \
} \
} \
})
} while(0);

///
/// standard objects act like C structs
Expand Down Expand Up @@ -688,13 +693,18 @@ static inline struct PNData *potion_data_alloc(Potion *P, int siz) {
/// method caches
/// (more great stuff from ian piumarta)
///
#define potion_send(RCV, MSG, ARGS...) ({ \

#ifndef _MSC_VER
# define potion_send(RCV, MSG, ARGS...) ({ \
PN r = (PN)(RCV); \
PN c = potion_bind(P, r, (MSG)); \
if (PN_IS_CLOSURE(c)) \
c = ((struct PNClosure *)c)->method(P, c, r, ##ARGS); \
c; \
})
#else
# define potion_send(RCV, MSG, ...) potion_send_real(P, RCV, MSG, __VA_ARGS__)
#endif

#define potion_method(RCV, MSG, FN, SIG) \
potion_send(RCV, PN_def, potion_str(P, MSG), PN_FUNC(FN, SIG))
Expand Down Expand Up @@ -834,4 +844,8 @@ PN_F potion_jit_proto(Potion *, PN);
PN potion_load(Potion *, PN, PN, PN);
PN potion_class_find(Potion *, PN);

#ifdef _MSC_VER
PN potion_send_real(Potion *P, PN rcv, PN msg, ...);
#endif

#endif
28 changes: 27 additions & 1 deletion front/potion.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef _MSC_VER
# include <unistd.h>
#endif

#include "potion.h"
#include "internal.h"
Expand Down Expand Up @@ -392,3 +394,27 @@ int main(int argc, char *argv[]) {
#endif
return 0;
}

#ifdef _MSC_VER
PN potion_send_real(Potion * P, PN rcv, PN msg, ...) {
PN c = potion_bind(P, rcv, msg);
if (PN_IS_CLOSURE(c)) {
void * method = ((struct PNClosure *)c)->method;
//untested
__asm {
mov eax, rcv
mov msg, eax
mov eax, c
mov rcv, eax
//Potion * P remains unmodified
mov eax, method
mov esp, ebp
pop ebp
//head of stack is return address now, simulating call
jmp eax
};
//c = ((struct PNClosure *)c)->method(P, c, rcv, ##ARGS);
}
return c;
}
#endif