mirror of
https://github.com/janet-lang/janet
synced 2024-12-23 15:00:27 +00:00
Fix large function compilation issue.
This commit is contained in:
parent
f4fc4a0bcc
commit
6822400abe
@ -266,7 +266,7 @@ value."
|
|||||||
subloop
|
subloop
|
||||||
(tuple ':= bindings (tuple + bindings inc)))))
|
(tuple ':= bindings (tuple + bindings inc)))))
|
||||||
:keys (do
|
:keys (do
|
||||||
(def $dict (gensym "dict"))
|
(def $dict (gensym))
|
||||||
(def preds @['and (tuple not= nil bindings)])
|
(def preds @['and (tuple not= nil bindings)])
|
||||||
(def subloop (doone (+ i 3) preds))
|
(def subloop (doone (+ i 3) preds))
|
||||||
(tuple 'do
|
(tuple 'do
|
||||||
@ -276,9 +276,9 @@ value."
|
|||||||
subloop
|
subloop
|
||||||
(tuple ':= bindings (tuple next $dict bindings)))))
|
(tuple ':= bindings (tuple next $dict bindings)))))
|
||||||
:in (do
|
:in (do
|
||||||
(def $len (gensym "len"))
|
(def $len (gensym))
|
||||||
(def $i (gensym "i"))
|
(def $i (gensym))
|
||||||
(def $indexed (gensym "indexed"))
|
(def $indexed (gensym))
|
||||||
(def preds @['and (tuple < $i $len)])
|
(def preds @['and (tuple < $i $len)])
|
||||||
(def subloop (doone (+ i 3) preds))
|
(def subloop (doone (+ i 3) preds))
|
||||||
(tuple 'do
|
(tuple 'do
|
||||||
@ -295,7 +295,7 @@ value."
|
|||||||
(defmacro for
|
(defmacro for
|
||||||
"Similar to loop, but accumulates the loop body into an array and returns that."
|
"Similar to loop, but accumulates the loop body into an array and returns that."
|
||||||
[head & body]
|
[head & body]
|
||||||
(def $accum (gensym "accum"))
|
(def $accum (gensym))
|
||||||
(tuple 'do
|
(tuple 'do
|
||||||
(tuple 'def $accum @[])
|
(tuple 'def $accum @[])
|
||||||
(tuple 'loop head
|
(tuple 'loop head
|
||||||
@ -1062,8 +1062,8 @@ onvalue."
|
|||||||
(do
|
(do
|
||||||
(file.write stdout " [" source "]")
|
(file.write stdout " [" source "]")
|
||||||
(if source-line (file.write stdout " on line "
|
(if source-line (file.write stdout " on line "
|
||||||
(string source-line) ", column " (string source-col))))
|
(string source-line) ", column " (string source-col)))))
|
||||||
(if pc (file.write stdout " at (pc=" (string pc) ")")))
|
(if pc (file.write stdout " (pc=" (string pc) ")"))
|
||||||
(when tail (file.write stdout " (tailcall)"))
|
(when tail (file.write stdout " (tailcall)"))
|
||||||
(file.write stdout "\n"))))
|
(file.write stdout "\n"))))
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ DstSlot dstc_cslot(Dst x) {
|
|||||||
DstSlot dstc_nearslot(DstCompiler *c, DstcRegisterTemp tag) {
|
DstSlot dstc_nearslot(DstCompiler *c, DstcRegisterTemp tag) {
|
||||||
DstSlot ret;
|
DstSlot ret;
|
||||||
ret.flags = DST_SLOTTYPE_ANY;
|
ret.flags = DST_SLOTTYPE_ANY;
|
||||||
ret.index = dstc_getreg_temp(c, tag);
|
ret.index = dstc_allocnear(c, tag);
|
||||||
ret.constant = dst_wrap_nil();
|
ret.constant = dst_wrap_nil();
|
||||||
ret.envindex = -1;
|
ret.envindex = -1;
|
||||||
return ret;
|
return ret;
|
||||||
@ -111,7 +111,7 @@ DstSlot dstc_nearslot(DstCompiler *c, DstcRegisterTemp tag) {
|
|||||||
DstSlot dstc_farslot(DstCompiler *c) {
|
DstSlot dstc_farslot(DstCompiler *c) {
|
||||||
DstSlot ret;
|
DstSlot ret;
|
||||||
ret.flags = DST_SLOTTYPE_ANY;
|
ret.flags = DST_SLOTTYPE_ANY;
|
||||||
ret.index = dstc_getreg(c);
|
ret.index = dstc_allocfar(c);
|
||||||
ret.constant = dst_wrap_nil();
|
ret.constant = dst_wrap_nil();
|
||||||
ret.envindex = -1;
|
ret.envindex = -1;
|
||||||
return ret;
|
return ret;
|
||||||
@ -314,7 +314,7 @@ DstSlot dstc_gettarget(DstFopts opts) {
|
|||||||
slot.envindex = -1;
|
slot.envindex = -1;
|
||||||
slot.constant = dst_wrap_nil();
|
slot.constant = dst_wrap_nil();
|
||||||
slot.flags = 0;
|
slot.flags = 0;
|
||||||
slot.index = dstc_getreg_temp(opts.compiler, DSTC_REGTEMP_3);
|
slot.index = dstc_allocnear(opts.compiler, DSTC_REGTEMP_3);
|
||||||
}
|
}
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
@ -399,13 +399,13 @@ static DstSlot dstc_call(DstFopts opts, DstSlot *slots, DstSlot fun) {
|
|||||||
dstc_pushslots(c, slots);
|
dstc_pushslots(c, slots);
|
||||||
int32_t fun_register;
|
int32_t fun_register;
|
||||||
if (opts.flags & DST_FOPTS_TAIL) {
|
if (opts.flags & DST_FOPTS_TAIL) {
|
||||||
fun_register = dstc_to_reg(c, fun);
|
fun_register = dstc_regfar(c, fun, DSTC_REGTEMP_0);
|
||||||
dstc_emit(c, DOP_TAILCALL | (fun_register << 8));
|
dstc_emit(c, DOP_TAILCALL | (fun_register << 8));
|
||||||
retslot = dstc_cslot(dst_wrap_nil());
|
retslot = dstc_cslot(dst_wrap_nil());
|
||||||
retslot.flags = DST_SLOT_RETURNED;
|
retslot.flags = DST_SLOT_RETURNED;
|
||||||
} else {
|
} else {
|
||||||
retslot = dstc_gettarget(opts);
|
retslot = dstc_gettarget(opts);
|
||||||
fun_register = dstc_to_tempreg(c, fun, DSTC_REGTEMP_0);
|
fun_register = dstc_regnear(c, fun, DSTC_REGTEMP_0);
|
||||||
dstc_emit(c, DOP_CALL |
|
dstc_emit(c, DOP_CALL |
|
||||||
(retslot.index << 8) |
|
(retslot.index << 8) |
|
||||||
(fun_register << 16));
|
(fun_register << 16));
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
|
|
||||||
/* Get a register */
|
/* Get a register */
|
||||||
int32_t dstc_getreg(DstCompiler *c) {
|
int32_t dstc_allocfar(DstCompiler *c) {
|
||||||
int32_t reg = dstc_regalloc_1(&c->scope->ra);
|
int32_t reg = dstc_regalloc_1(&c->scope->ra);
|
||||||
if (reg > 0xFFFF) {
|
if (reg > 0xFFFF) {
|
||||||
dstc_cerror(c, "ran out of internal registers");
|
dstc_cerror(c, "ran out of internal registers");
|
||||||
@ -34,7 +34,7 @@ int32_t dstc_getreg(DstCompiler *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get a register less than 256 */
|
/* Get a register less than 256 */
|
||||||
int32_t dstc_getreg_temp(DstCompiler *c, DstcRegisterTemp tag) {
|
int32_t dstc_allocnear(DstCompiler *c, DstcRegisterTemp tag) {
|
||||||
return dstc_regalloc_temp(&c->scope->ra, tag);
|
return dstc_regalloc_temp(&c->scope->ra, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,10 +107,10 @@ static void dstc_loadconst(DstCompiler *c, Dst k, int32_t reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a slot to a two byte register */
|
/* Convert a slot to a two byte register */
|
||||||
int32_t dstc_to_reg(DstCompiler *c, DstSlot s) {
|
int32_t dstc_regfar(DstCompiler *c, DstSlot s, DstcRegisterTemp tag) {
|
||||||
int32_t reg;
|
int32_t reg;
|
||||||
if (s.flags & (DST_SLOT_CONSTANT | DST_SLOT_REF)) {
|
if (s.flags & (DST_SLOT_CONSTANT | DST_SLOT_REF)) {
|
||||||
reg = dstc_getreg(c);
|
reg = dstc_allocnear(c, tag);
|
||||||
dstc_loadconst(c, s.constant, reg);
|
dstc_loadconst(c, s.constant, reg);
|
||||||
/* If we also are a reference, deref the one element array */
|
/* If we also are a reference, deref the one element array */
|
||||||
if (s.flags & DST_SLOT_REF) {
|
if (s.flags & DST_SLOT_REF) {
|
||||||
@ -119,8 +119,8 @@ int32_t dstc_to_reg(DstCompiler *c, DstSlot s) {
|
|||||||
(reg << 8) |
|
(reg << 8) |
|
||||||
DOP_GET_INDEX);
|
DOP_GET_INDEX);
|
||||||
}
|
}
|
||||||
} else if (s.envindex >= 0 || s.index > 0xFF) {
|
} else if (s.envindex >= 0) {
|
||||||
reg = dstc_getreg(c);
|
reg = dstc_allocnear(c, tag);
|
||||||
dstc_emit(c,
|
dstc_emit(c,
|
||||||
((uint32_t)(s.index) << 24) |
|
((uint32_t)(s.index) << 24) |
|
||||||
((uint32_t)(s.envindex) << 16) |
|
((uint32_t)(s.envindex) << 16) |
|
||||||
@ -134,10 +134,10 @@ int32_t dstc_to_reg(DstCompiler *c, DstSlot s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a slot to a temporary 1 byte register */
|
/* Convert a slot to a temporary 1 byte register */
|
||||||
int32_t dstc_to_tempreg(DstCompiler *c, DstSlot s, DstcRegisterTemp tag) {
|
int32_t dstc_regnear(DstCompiler *c, DstSlot s, DstcRegisterTemp tag) {
|
||||||
int32_t reg;
|
int32_t reg;
|
||||||
if (s.flags & (DST_SLOT_CONSTANT | DST_SLOT_REF)) {
|
if (s.flags & (DST_SLOT_CONSTANT | DST_SLOT_REF)) {
|
||||||
reg = dstc_getreg_temp(c, tag);
|
reg = dstc_allocnear(c, tag);
|
||||||
dstc_loadconst(c, s.constant, reg);
|
dstc_loadconst(c, s.constant, reg);
|
||||||
/* If we also are a reference, deref the one element array */
|
/* If we also are a reference, deref the one element array */
|
||||||
if (s.flags & DST_SLOT_REF) {
|
if (s.flags & DST_SLOT_REF) {
|
||||||
@ -146,15 +146,15 @@ int32_t dstc_to_tempreg(DstCompiler *c, DstSlot s, DstcRegisterTemp tag) {
|
|||||||
(reg << 8) |
|
(reg << 8) |
|
||||||
DOP_GET_INDEX);
|
DOP_GET_INDEX);
|
||||||
}
|
}
|
||||||
} else if (s.envindex >= 0 || s.index > 0xFF) {
|
} else if (s.envindex >= 0) {
|
||||||
reg = dstc_getreg_temp(c, tag);
|
reg = dstc_allocnear(c, tag);
|
||||||
dstc_emit(c,
|
dstc_emit(c,
|
||||||
((uint32_t)(s.index) << 24) |
|
((uint32_t)(s.index) << 24) |
|
||||||
((uint32_t)(s.envindex) << 16) |
|
((uint32_t)(s.envindex) << 16) |
|
||||||
((uint32_t)(reg) << 8) |
|
((uint32_t)(reg) << 8) |
|
||||||
DOP_LOAD_UPVALUE);
|
DOP_LOAD_UPVALUE);
|
||||||
} else if (s.index > 0xFF) {
|
} else if (s.index > 0xFF) {
|
||||||
reg = dstc_getreg_temp(c, tag);
|
reg = dstc_allocnear(c, tag);
|
||||||
dstc_emit(c,
|
dstc_emit(c,
|
||||||
((uint32_t)(s.index) << 16) |
|
((uint32_t)(s.index) << 16) |
|
||||||
((uint32_t)(reg) << 8) |
|
((uint32_t)(reg) << 8) |
|
||||||
@ -175,7 +175,7 @@ void dstc_free_reg(DstCompiler *c, DstSlot s, int32_t reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if two slots are equal */
|
/* Check if two slots are equal */
|
||||||
int dstc_sequal(DstSlot lhs, DstSlot rhs) {
|
static int dstc_sequal(DstSlot lhs, DstSlot rhs) {
|
||||||
if (lhs.flags == rhs.flags &&
|
if (lhs.flags == rhs.flags &&
|
||||||
lhs.index == rhs.index &&
|
lhs.index == rhs.index &&
|
||||||
lhs.envindex == rhs.envindex) {
|
lhs.envindex == rhs.envindex) {
|
||||||
@ -190,7 +190,7 @@ int dstc_sequal(DstSlot lhs, DstSlot rhs) {
|
|||||||
|
|
||||||
/* Move values from one slot to another. The destination must
|
/* Move values from one slot to another. The destination must
|
||||||
* be writeable (not a literal). */
|
* be writeable (not a literal). */
|
||||||
int dstc_copy(
|
void dstc_copy(
|
||||||
DstCompiler *c,
|
DstCompiler *c,
|
||||||
DstSlot dest,
|
DstSlot dest,
|
||||||
DstSlot src) {
|
DstSlot src) {
|
||||||
@ -202,11 +202,11 @@ int dstc_copy(
|
|||||||
/* Can't write to constants */
|
/* Can't write to constants */
|
||||||
if (dest.flags & DST_SLOT_CONSTANT) {
|
if (dest.flags & DST_SLOT_CONSTANT) {
|
||||||
dstc_cerror(c, "cannot write to constant");
|
dstc_cerror(c, "cannot write to constant");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Short circuit if dest and source are equal */
|
/* Short circuit if dest and source are equal */
|
||||||
if (dstc_sequal(dest, src)) return 0;
|
if (dstc_sequal(dest, src)) return;
|
||||||
|
|
||||||
/* Types of slots - src */
|
/* Types of slots - src */
|
||||||
/* constants */
|
/* constants */
|
||||||
@ -243,19 +243,19 @@ int dstc_copy(
|
|||||||
(dest.index << 8) |
|
(dest.index << 8) |
|
||||||
DOP_MOVE_NEAR);
|
DOP_MOVE_NEAR);
|
||||||
}
|
}
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process: src -> srclocal -> destlocal -> dest */
|
/* Process: src -> srclocal -> destlocal -> dest */
|
||||||
|
|
||||||
/* src -> srclocal */
|
/* src -> srclocal */
|
||||||
srclocal = dstc_to_tempreg(c, src, DSTC_REGTEMP_0);
|
srclocal = dstc_regnear(c, src, DSTC_REGTEMP_0);
|
||||||
|
|
||||||
/* Pull down dest (find destlocal) */
|
/* Pull down dest (find destlocal) */
|
||||||
if (dest.flags & DST_SLOT_REF) {
|
if (dest.flags & DST_SLOT_REF) {
|
||||||
writeback = 1;
|
writeback = 1;
|
||||||
destlocal = srclocal;
|
destlocal = srclocal;
|
||||||
reflocal = dstc_getreg_temp(c, DSTC_REGTEMP_1);
|
reflocal = dstc_allocnear(c, DSTC_REGTEMP_1);
|
||||||
dstc_emit(c,
|
dstc_emit(c,
|
||||||
(dstc_const(c, dest.constant) << 16) |
|
(dstc_const(c, dest.constant) << 16) |
|
||||||
(reflocal << 8) |
|
(reflocal << 8) |
|
||||||
@ -302,13 +302,12 @@ int dstc_copy(
|
|||||||
dstc_regalloc_free(&c->scope->ra, reflocal);
|
dstc_regalloc_free(&c->scope->ra, reflocal);
|
||||||
}
|
}
|
||||||
dstc_free_reg(c, src, srclocal);
|
dstc_free_reg(c, src, srclocal);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Instruction templated emitters */
|
/* Instruction templated emitters */
|
||||||
|
|
||||||
static int32_t emit1s(DstCompiler *c, uint8_t op, DstSlot s, int32_t rest) {
|
static int32_t emit1s(DstCompiler *c, uint8_t op, DstSlot s, int32_t rest) {
|
||||||
int32_t reg = dstc_to_tempreg(c, s, DSTC_REGTEMP_0);
|
int32_t reg = dstc_regnear(c, s, DSTC_REGTEMP_0);
|
||||||
int32_t label = dst_v_count(c->buffer);
|
int32_t label = dst_v_count(c->buffer);
|
||||||
dstc_emit(c, op | (reg << 8) | (rest << 16));
|
dstc_emit(c, op | (reg << 8) | (rest << 16));
|
||||||
dstc_free_reg(c, s, reg);
|
dstc_free_reg(c, s, reg);
|
||||||
@ -316,7 +315,7 @@ static int32_t emit1s(DstCompiler *c, uint8_t op, DstSlot s, int32_t rest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t dstc_emit_s(DstCompiler *c, uint8_t op, DstSlot s) {
|
int32_t dstc_emit_s(DstCompiler *c, uint8_t op, DstSlot s) {
|
||||||
int32_t reg = dstc_to_reg(c, s);
|
int32_t reg = dstc_regfar(c, s, DSTC_REGTEMP_0);
|
||||||
int32_t label = dst_v_count(c->buffer);
|
int32_t label = dst_v_count(c->buffer);
|
||||||
dstc_emit(c, op | (reg << 8));
|
dstc_emit(c, op | (reg << 8));
|
||||||
dstc_free_reg(c, s, reg);
|
dstc_free_reg(c, s, reg);
|
||||||
@ -345,8 +344,8 @@ int32_t dstc_emit_su(DstCompiler *c, uint8_t op, DstSlot s, uint16_t immediate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int32_t emit2s(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, int32_t rest) {
|
static int32_t emit2s(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, int32_t rest) {
|
||||||
int32_t reg1 = dstc_to_tempreg(c, s1, DSTC_REGTEMP_0);
|
int32_t reg1 = dstc_regnear(c, s1, DSTC_REGTEMP_0);
|
||||||
int32_t reg2 = dstc_to_tempreg(c, s2, DSTC_REGTEMP_1);
|
int32_t reg2 = dstc_regnear(c, s2, DSTC_REGTEMP_1);
|
||||||
int32_t label = dst_v_count(c->buffer);
|
int32_t label = dst_v_count(c->buffer);
|
||||||
dstc_emit(c, op | (reg1 << 8) | (reg2 << 16) | (rest << 24));
|
dstc_emit(c, op | (reg1 << 8) | (reg2 << 16) | (rest << 24));
|
||||||
dstc_free_reg(c, s1, reg1);
|
dstc_free_reg(c, s1, reg1);
|
||||||
@ -355,8 +354,8 @@ static int32_t emit2s(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, int32_
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t dstc_emit_ss(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2) {
|
int32_t dstc_emit_ss(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2) {
|
||||||
int32_t reg1 = dstc_to_tempreg(c, s1, DSTC_REGTEMP_0);
|
int32_t reg1 = dstc_regnear(c, s1, DSTC_REGTEMP_0);
|
||||||
int32_t reg2 = dstc_to_reg(c, s2);
|
int32_t reg2 = dstc_regfar(c, s2, DSTC_REGTEMP_1);
|
||||||
int32_t label = dst_v_count(c->buffer);
|
int32_t label = dst_v_count(c->buffer);
|
||||||
dstc_emit(c, op | (reg1 << 8) | (reg2 << 16));
|
dstc_emit(c, op | (reg1 << 8) | (reg2 << 16));
|
||||||
dstc_free_reg(c, s1, reg1);
|
dstc_free_reg(c, s1, reg1);
|
||||||
@ -373,9 +372,9 @@ int32_t dstc_emit_ssu(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, uint8_
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t dstc_emit_sss(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, DstSlot s3) {
|
int32_t dstc_emit_sss(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, DstSlot s3) {
|
||||||
int32_t reg1 = dstc_to_tempreg(c, s1, DSTC_REGTEMP_0);
|
int32_t reg1 = dstc_regnear(c, s1, DSTC_REGTEMP_0);
|
||||||
int32_t reg2 = dstc_to_tempreg(c, s2, DSTC_REGTEMP_1);
|
int32_t reg2 = dstc_regnear(c, s2, DSTC_REGTEMP_1);
|
||||||
int32_t reg3 = dstc_to_tempreg(c, s3, DSTC_REGTEMP_2);
|
int32_t reg3 = dstc_regnear(c, s3, DSTC_REGTEMP_2);
|
||||||
int32_t label = dst_v_count(c->buffer);
|
int32_t label = dst_v_count(c->buffer);
|
||||||
dstc_emit(c, op | (reg1 << 8) | (reg2 << 16) | (reg3 << 24));
|
dstc_emit(c, op | (reg1 << 8) | (reg2 << 16) | (reg3 << 24));
|
||||||
dstc_free_reg(c, s1, reg1);
|
dstc_free_reg(c, s1, reg1);
|
||||||
|
@ -27,11 +27,11 @@
|
|||||||
|
|
||||||
void dstc_emit(DstCompiler *c, uint32_t instr);
|
void dstc_emit(DstCompiler *c, uint32_t instr);
|
||||||
|
|
||||||
int32_t dstc_getreg(DstCompiler *c);
|
int32_t dstc_allocfar(DstCompiler *c);
|
||||||
int32_t dstc_getreg_temp(DstCompiler *c, DstcRegisterTemp);
|
int32_t dstc_allocnear(DstCompiler *c, DstcRegisterTemp);
|
||||||
|
|
||||||
int32_t dstc_to_reg(DstCompiler *c, DstSlot s);
|
int32_t dstc_regfar(DstCompiler *c, DstSlot s, DstcRegisterTemp tag);
|
||||||
int32_t dstc_to_tempreg(DstCompiler *c, DstSlot s, DstcRegisterTemp tag);
|
int32_t dstc_regnear(DstCompiler *c, DstSlot s, DstcRegisterTemp tag);
|
||||||
void dstc_free_reg(DstCompiler *c, DstSlot s, int32_t reg);
|
void dstc_free_reg(DstCompiler *c, DstSlot s, int32_t reg);
|
||||||
|
|
||||||
int32_t dstc_emit_s(DstCompiler *c, uint8_t op, DstSlot s);
|
int32_t dstc_emit_s(DstCompiler *c, uint8_t op, DstSlot s);
|
||||||
@ -45,6 +45,6 @@ int32_t dstc_emit_ssu(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, uint8_
|
|||||||
int32_t dstc_emit_sss(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, DstSlot s3);
|
int32_t dstc_emit_sss(DstCompiler *c, uint8_t op, DstSlot s1, DstSlot s2, DstSlot s3);
|
||||||
|
|
||||||
/* Move value from one slot to another. Cannot copy to constant slots. */
|
/* Move value from one slot to another. Cannot copy to constant slots. */
|
||||||
int dstc_copy(DstCompiler *c, DstSlot dest, DstSlot src);
|
void dstc_copy(DstCompiler *c, DstSlot dest, DstSlot src);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -29,6 +29,7 @@ void dstc_regalloc_init(DstcRegisterAllocator *ra) {
|
|||||||
ra->count = 0;
|
ra->count = 0;
|
||||||
ra->capacity = 0;
|
ra->capacity = 0;
|
||||||
ra->max = 0;
|
ra->max = 0;
|
||||||
|
ra->regtemps = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dstc_regalloc_deinit(DstcRegisterAllocator *ra) {
|
void dstc_regalloc_deinit(DstcRegisterAllocator *ra) {
|
||||||
@ -126,9 +127,16 @@ int32_t dstc_regalloc_1(DstcRegisterAllocator *ra) {
|
|||||||
* without being freed. */
|
* without being freed. */
|
||||||
void dstc_regalloc_free(DstcRegisterAllocator *ra, int32_t reg) {
|
void dstc_regalloc_free(DstcRegisterAllocator *ra, int32_t reg) {
|
||||||
/* We cannot free reserved slots */
|
/* We cannot free reserved slots */
|
||||||
if (reg < 0 || (reg >= 240 && reg <= 255))
|
if (reg < 0)
|
||||||
return;
|
return;
|
||||||
|
if (reg >= 0xF0 && reg <= 0xFF) {
|
||||||
|
ra->regtemps &= ~(1 << (reg - 0xF0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
int32_t chunk = reg >> 5;
|
int32_t chunk = reg >> 5;
|
||||||
|
/* Outside normal chunk range */
|
||||||
|
if (chunk >= ra->count)
|
||||||
|
return;
|
||||||
int32_t bit = reg & 0x1F;
|
int32_t bit = reg & 0x1F;
|
||||||
ra->chunks[chunk] &= ~ithbit(bit);
|
ra->chunks[chunk] &= ~ithbit(bit);
|
||||||
}
|
}
|
||||||
@ -139,6 +147,8 @@ void dstc_regalloc_free(DstcRegisterAllocator *ra, int32_t reg) {
|
|||||||
int32_t dstc_regalloc_temp(DstcRegisterAllocator *ra, DstcRegisterTemp nth) {
|
int32_t dstc_regalloc_temp(DstcRegisterAllocator *ra, DstcRegisterTemp nth) {
|
||||||
int32_t oldmax = ra->max;
|
int32_t oldmax = ra->max;
|
||||||
int32_t reg = dstc_regalloc_1(ra);
|
int32_t reg = dstc_regalloc_1(ra);
|
||||||
|
dst_assert(~(ra->regtemps & (1 << nth)), "regtemp already allocated");
|
||||||
|
ra->regtemps |= 1 << nth;
|
||||||
if (reg > 0xFF) {
|
if (reg > 0xFF) {
|
||||||
reg = 0xF0 + nth;
|
reg = 0xF0 + nth;
|
||||||
ra->max = (reg > oldmax) ? reg : oldmax;
|
ra->max = (reg > oldmax) ? reg : oldmax;
|
||||||
@ -146,8 +156,9 @@ int32_t dstc_regalloc_temp(DstcRegisterAllocator *ra, DstcRegisterTemp nth) {
|
|||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if a range is free. Returns the next index to check if not free,
|
/* Disable multi-slot allocation for now. */
|
||||||
* -1 if free. */
|
|
||||||
|
/*
|
||||||
static int32_t checkrange(DstcRegisterAllocator *ra, int32_t start, int32_t end) {
|
static int32_t checkrange(DstcRegisterAllocator *ra, int32_t start, int32_t end) {
|
||||||
int32_t startchunk = start / 32;
|
int32_t startchunk = start / 32;
|
||||||
int32_t endchunk = end / 32;
|
int32_t endchunk = end / 32;
|
||||||
@ -161,7 +172,6 @@ static int32_t checkrange(DstcRegisterAllocator *ra, int32_t start, int32_t end)
|
|||||||
uint32_t block = ra->chunks[chunk];
|
uint32_t block = ra->chunks[chunk];
|
||||||
uint32_t masking = mask & block;
|
uint32_t masking = mask & block;
|
||||||
if (masking) {
|
if (masking) {
|
||||||
/* If block is full, skip it completely. */
|
|
||||||
int32_t nextbit = (block == 0xFFFFFFFF)
|
int32_t nextbit = (block == 0xFFFFFFFF)
|
||||||
? 32
|
? 32
|
||||||
: count_trailing_zeros(masking) + 1;
|
: count_trailing_zeros(masking) + 1;
|
||||||
@ -171,7 +181,6 @@ static int32_t checkrange(DstcRegisterAllocator *ra, int32_t start, int32_t end)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark a range */
|
|
||||||
static void markrange(DstcRegisterAllocator *ra, int32_t start, int32_t end) {
|
static void markrange(DstcRegisterAllocator *ra, int32_t start, int32_t end) {
|
||||||
int32_t startchunk = start / 32;
|
int32_t startchunk = start / 32;
|
||||||
int32_t endchunk = end / 32;
|
int32_t endchunk = end / 32;
|
||||||
@ -185,7 +194,6 @@ static void markrange(DstcRegisterAllocator *ra, int32_t start, int32_t end) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free a range of registers. */
|
|
||||||
void dstc_regalloc_freerange(DstcRegisterAllocator *ra, int32_t start, int32_t n) {
|
void dstc_regalloc_freerange(DstcRegisterAllocator *ra, int32_t start, int32_t n) {
|
||||||
int32_t end = start + n - 1;
|
int32_t end = start + n - 1;
|
||||||
int32_t startchunk = start / 32;
|
int32_t startchunk = start / 32;
|
||||||
@ -200,8 +208,6 @@ void dstc_regalloc_freerange(DstcRegisterAllocator *ra, int32_t start, int32_t n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate n contiguous registers. Returns the first register
|
|
||||||
* in the range allocated. */
|
|
||||||
int32_t dstc_regalloc_n(DstcRegisterAllocator *ra, int32_t n) {
|
int32_t dstc_regalloc_n(DstcRegisterAllocator *ra, int32_t n) {
|
||||||
int32_t start = 0, end = 0, next = 0;
|
int32_t start = 0, end = 0, next = 0;
|
||||||
while (next >= 0) {
|
while (next >= 0) {
|
||||||
@ -210,15 +216,11 @@ int32_t dstc_regalloc_n(DstcRegisterAllocator *ra, int32_t n) {
|
|||||||
next = checkrange(ra, start, end);
|
next = checkrange(ra, start, end);
|
||||||
}
|
}
|
||||||
markrange(ra, start, end);
|
markrange(ra, start, end);
|
||||||
/* Set max */
|
|
||||||
if (end > ra->max)
|
if (end > ra->max)
|
||||||
ra->max = end;
|
ra->max = end;
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates registers for a function call. Tries to not move the callee,
|
|
||||||
* but will find nargs + 1 other contiguous registers if there is not enough
|
|
||||||
* space after the callee. */
|
|
||||||
int32_t dstc_regalloc_call(DstcRegisterAllocator *ra, int32_t callee, int32_t nargs) {
|
int32_t dstc_regalloc_call(DstcRegisterAllocator *ra, int32_t callee, int32_t nargs) {
|
||||||
if (checkrange(ra, callee, callee + nargs) < 0) {
|
if (checkrange(ra, callee, callee + nargs) < 0) {
|
||||||
markrange(ra, callee + 1, callee + nargs);
|
markrange(ra, callee + 1, callee + nargs);
|
||||||
@ -227,3 +229,4 @@ int32_t dstc_regalloc_call(DstcRegisterAllocator *ra, int32_t callee, int32_t na
|
|||||||
return dstc_regalloc_n(ra, nargs + 1);
|
return dstc_regalloc_n(ra, nargs + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
@ -44,6 +44,7 @@ typedef struct {
|
|||||||
int32_t count; /* number of chunks in chunks */
|
int32_t count; /* number of chunks in chunks */
|
||||||
int32_t capacity; /* amount allocated for chunks */
|
int32_t capacity; /* amount allocated for chunks */
|
||||||
int32_t max; /* The maximum allocated register so far */
|
int32_t max; /* The maximum allocated register so far */
|
||||||
|
int32_t regtemps; /* Hold which tempregistered are alloced. */
|
||||||
} DstcRegisterAllocator;
|
} DstcRegisterAllocator;
|
||||||
|
|
||||||
void dstc_regalloc_init(DstcRegisterAllocator *ra);
|
void dstc_regalloc_init(DstcRegisterAllocator *ra);
|
||||||
@ -51,56 +52,15 @@ void dstc_regalloc_deinit(DstcRegisterAllocator *ra);
|
|||||||
|
|
||||||
int32_t dstc_regalloc_1(DstcRegisterAllocator *ra);
|
int32_t dstc_regalloc_1(DstcRegisterAllocator *ra);
|
||||||
void dstc_regalloc_free(DstcRegisterAllocator *ra, int32_t reg);
|
void dstc_regalloc_free(DstcRegisterAllocator *ra, int32_t reg);
|
||||||
void dstc_regalloc_freerange(DstcRegisterAllocator *ra, int32_t regstart, int32_t n);
|
|
||||||
int32_t dstc_regalloc_temp(DstcRegisterAllocator *ra, DstcRegisterTemp nth);
|
int32_t dstc_regalloc_temp(DstcRegisterAllocator *ra, DstcRegisterTemp nth);
|
||||||
int32_t dstc_regalloc_n(DstcRegisterAllocator *ra, int32_t n);
|
|
||||||
int32_t dstc_regalloc_call(DstcRegisterAllocator *ra, int32_t callee, int32_t nargs);
|
|
||||||
void dstc_regalloc_clone(DstcRegisterAllocator *dest, DstcRegisterAllocator *src);
|
void dstc_regalloc_clone(DstcRegisterAllocator *dest, DstcRegisterAllocator *src);
|
||||||
void dstc_regalloc_touch(DstcRegisterAllocator *ra, int32_t reg);
|
void dstc_regalloc_touch(DstcRegisterAllocator *ra, int32_t reg);
|
||||||
|
|
||||||
/* Test code */
|
/* Mutli-slot allocation disabled */
|
||||||
/*
|
/*
|
||||||
#include <stdio.h>
|
int32_t dstc_regalloc_n(DstcRegisterAllocator *ra, int32_t n);
|
||||||
static void printreg(DstcRegisterAllocator *ra) {
|
int32_t dstc_regalloc_call(DstcRegisterAllocator *ra, int32_t callee, int32_t nargs);
|
||||||
printf("count=%d, cap=%d, max=%d\n", ra->count, ra->capacity, ra->max);
|
void dstc_regalloc_freerange(DstcRegisterAllocator *ra, int32_t regstart, int32_t n);
|
||||||
for (int row = 0; row < ra->count; row++) {
|
|
||||||
uint32_t chunk = ra->chunks[row];
|
|
||||||
putc('[', stdout);
|
|
||||||
for (int i = 0; i < 32; i++) {
|
|
||||||
putc(
|
|
||||||
(chunk & (1 << i))
|
|
||||||
? '*'
|
|
||||||
: '.', stdout);
|
|
||||||
}
|
|
||||||
putc(']', stdout);
|
|
||||||
putc('\n', stdout);
|
|
||||||
}
|
|
||||||
putc('\n', stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void runtest(void) {
|
|
||||||
DstcRegisterAllocator ra, rb;
|
|
||||||
dstc_regalloc_init(&ra);
|
|
||||||
int32_t a = dstc_regalloc_1(&ra);
|
|
||||||
int32_t b = dstc_regalloc_1(&ra);
|
|
||||||
int32_t c = dstc_regalloc_1(&ra);
|
|
||||||
int32_t d = dstc_regalloc_1(&ra);
|
|
||||||
int32_t e = dstc_regalloc_1(&ra);
|
|
||||||
printreg(&ra);
|
|
||||||
dstc_regalloc_free(&ra, b);
|
|
||||||
dstc_regalloc_free(&ra, d);
|
|
||||||
printreg(&ra);
|
|
||||||
int32_t x = dstc_regalloc_n(&ra, 32);
|
|
||||||
printreg(&ra);
|
|
||||||
dstc_regalloc_1(&ra);
|
|
||||||
printreg(&ra);
|
|
||||||
int32_t y = dstc_regalloc_n(&ra, 101);
|
|
||||||
printreg(&ra);
|
|
||||||
dstc_regalloc_clone(&rb, &ra);
|
|
||||||
printreg(&rb);
|
|
||||||
dstc_regalloc_deinit(&ra);
|
|
||||||
dstc_regalloc_deinit(&rb);
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,8 +63,8 @@ static void destructure(DstCompiler *c,
|
|||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
DstSlot nextright;
|
DstSlot nextright;
|
||||||
Dst subval = values[i];
|
Dst subval = values[i];
|
||||||
right_register = dstc_to_tempreg(c, right, DSTC_REGTEMP_0);
|
right_register = dstc_regnear(c, right, DSTC_REGTEMP_0);
|
||||||
subval_register = dstc_getreg_temp(c, DSTC_REGTEMP_1);
|
subval_register = dstc_allocnear(c, DSTC_REGTEMP_1);
|
||||||
if (i < 0x100) {
|
if (i < 0x100) {
|
||||||
dstc_emit(c, DOP_GET_INDEX |
|
dstc_emit(c, DOP_GET_INDEX |
|
||||||
(subval_register << 8) |
|
(subval_register << 8) |
|
||||||
@ -72,7 +72,7 @@ static void destructure(DstCompiler *c,
|
|||||||
(i << 24));
|
(i << 24));
|
||||||
} else {
|
} else {
|
||||||
DstSlot islot = dstc_cslot(dst_wrap_integer(i));
|
DstSlot islot = dstc_cslot(dst_wrap_integer(i));
|
||||||
int32_t i_register = dstc_to_tempreg(c, islot, DSTC_REGTEMP_2);
|
int32_t i_register = dstc_regnear(c, islot, DSTC_REGTEMP_2);
|
||||||
dstc_emit(c, DOP_GET_INDEX |
|
dstc_emit(c, DOP_GET_INDEX |
|
||||||
(subval_register << 8) |
|
(subval_register << 8) |
|
||||||
(right_register << 16) |
|
(right_register << 16) |
|
||||||
@ -88,8 +88,6 @@ static void destructure(DstCompiler *c,
|
|||||||
dstc_free_reg(c, right, right_register);
|
dstc_free_reg(c, right, right_register);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Free right */
|
|
||||||
dstc_freeslot(c, right);
|
|
||||||
break;
|
break;
|
||||||
case DST_TABLE:
|
case DST_TABLE:
|
||||||
case DST_STRUCT:
|
case DST_STRUCT:
|
||||||
@ -100,9 +98,9 @@ static void destructure(DstCompiler *c,
|
|||||||
DstSlot nextright;
|
DstSlot nextright;
|
||||||
DstSlot kslot = dstc_value(dstc_fopts_default(c), kv->key);
|
DstSlot kslot = dstc_value(dstc_fopts_default(c), kv->key);
|
||||||
|
|
||||||
right_register = dstc_to_tempreg(c, right, DSTC_REGTEMP_0);
|
right_register = dstc_regnear(c, right, DSTC_REGTEMP_0);
|
||||||
subval_register = dstc_getreg_temp(c, DSTC_REGTEMP_1);
|
subval_register = dstc_allocnear(c, DSTC_REGTEMP_1);
|
||||||
k_register = dstc_to_tempreg(c, kslot, DSTC_REGTEMP_2);
|
k_register = dstc_regnear(c, kslot, DSTC_REGTEMP_2);
|
||||||
dstc_emit(c, DOP_GET |
|
dstc_emit(c, DOP_GET |
|
||||||
(subval_register << 8) |
|
(subval_register << 8) |
|
||||||
(right_register << 16) |
|
(right_register << 16) |
|
||||||
@ -117,11 +115,8 @@ static void destructure(DstCompiler *c,
|
|||||||
dstc_free_reg(c, right, right_register);
|
dstc_free_reg(c, right, right_register);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Free right */
|
|
||||||
dstc_freeslot(c, right);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DstSlot dstc_varset(DstFopts opts, int32_t argn, const Dst *argv) {
|
DstSlot dstc_varset(DstFopts opts, int32_t argn, const Dst *argv) {
|
||||||
@ -193,7 +188,7 @@ static DstSlot namelocal(DstCompiler *c, Dst head, int32_t flags, DstSlot ret) {
|
|||||||
ret.index > 0xFF) {
|
ret.index > 0xFF) {
|
||||||
/* Slot is not able to be named */
|
/* Slot is not able to be named */
|
||||||
DstSlot localslot;
|
DstSlot localslot;
|
||||||
localslot.index = dstc_getreg(c);
|
localslot.index = dstc_allocfar(c);
|
||||||
/* infer type? */
|
/* infer type? */
|
||||||
localslot.flags = flags;
|
localslot.flags = flags;
|
||||||
localslot.envindex = -1;
|
localslot.envindex = -1;
|
||||||
|
@ -169,15 +169,8 @@ int dst_core_struct(DstArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dst_core_gensym(DstArgs args) {
|
int dst_core_gensym(DstArgs args) {
|
||||||
DST_MAXARITY(args, 1);
|
DST_FIXARITY(args, 0);
|
||||||
if (args.n == 0) {
|
DST_RETURN_SYMBOL(args, dst_symbol_gen());
|
||||||
DST_RETURN_SYMBOL(args, dst_symbol_gen(NULL, 0));
|
|
||||||
} else {
|
|
||||||
const uint8_t *s;
|
|
||||||
int32_t len;
|
|
||||||
DST_ARG_BYTES(s, len, args, 0);
|
|
||||||
DST_RETURN_SYMBOL(args, dst_symbol_gen(s, len));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int dst_core_gccollect(DstArgs args) {
|
int dst_core_gccollect(DstArgs args) {
|
||||||
|
@ -201,48 +201,52 @@ const uint8_t *dst_symbol_from_string(const uint8_t *str) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper for creating a unique string. Increment an integer
|
/* Store counter for genysm to avoid quadratic behavior */
|
||||||
* represented as an array of integer digits. */
|
DST_THREAD_LOCAL uint8_t gensym_counter[8] = {'_', '0', '0', '0', '0', '0', '0', 0};
|
||||||
static void inc_counter(uint8_t *digits, int base, int len) {
|
|
||||||
int i;
|
/* Increment the gensym buffer */
|
||||||
uint8_t carry = 1;
|
static void inc_gensym(void) {
|
||||||
for (i = len - 1; i >= 0; --i) {
|
for (int i = sizeof(gensym_counter) - 2; i; i--) {
|
||||||
digits[i] += carry;
|
if (gensym_counter[i] == '9') {
|
||||||
carry = 0;
|
gensym_counter[i] = 'a';
|
||||||
if (digits[i] == base) {
|
} else if (gensym_counter[i] == 'z') {
|
||||||
digits[i] = 0;
|
gensym_counter[i] = 'A';
|
||||||
carry = 1;
|
} else if (gensym_counter[i] == 'Z') {
|
||||||
|
gensym_counter[i] = '0';
|
||||||
|
} else {
|
||||||
|
gensym_counter[i]++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate a unique symbol. This is used in the library function gensym. The
|
/* Generate a unique symbol. This is used in the library function gensym. The
|
||||||
* symbol will be of the format prefix_XXXXXX, where X is a base64 digit, and
|
* symbol will be of the format _XXXXXX, where X is a base64 digit, and
|
||||||
* prefix is the argument passed. */
|
* prefix is the argument passed. No prefix for speed. */
|
||||||
const uint8_t *dst_symbol_gen(const uint8_t *buf, int32_t len) {
|
const uint8_t *dst_symbol_gen(void) {
|
||||||
const uint8_t **bucket = NULL;
|
const uint8_t **bucket = NULL;
|
||||||
|
uint8_t *sym;
|
||||||
int32_t hash = 0;
|
int32_t hash = 0;
|
||||||
uint8_t counter[6] = {63, 63, 63, 63, 63, 63};
|
int status;
|
||||||
/* Leave spaces for 6 base 64 digits and two dashes. That means 64^6 possible suffixes, which
|
/* Leave spaces for 6 base 64 digits and two dashes. That means 64^6 possible suffixes, which
|
||||||
* is enough for resolving collisions. */
|
* is enough for resolving collisions. */
|
||||||
int32_t newlen = len + 7;
|
do {
|
||||||
int32_t newbufsize = newlen + 2 * sizeof(int32_t) + 1;
|
hash = dst_string_calchash(
|
||||||
uint8_t *str = (uint8_t *)dst_gcalloc(DST_MEMORY_SYMBOL, newbufsize) + 2 * sizeof(int32_t);
|
gensym_counter,
|
||||||
dst_string_length(str) = newlen;
|
sizeof(gensym_counter) - 1);
|
||||||
memcpy(str, buf, len);
|
bucket = dst_symcache_findmem(
|
||||||
str[len] = '_';
|
gensym_counter,
|
||||||
str[newlen] = 0;
|
sizeof(gensym_counter) - 1,
|
||||||
uint8_t *saltbuf = str + len + 1;
|
hash,
|
||||||
int status = 1;
|
&status);
|
||||||
while (status) {
|
} while (status && (inc_gensym(), 1));
|
||||||
int i;
|
sym = (uint8_t *) dst_gcalloc(
|
||||||
inc_counter(counter, 64, 6);
|
DST_MEMORY_SYMBOL,
|
||||||
for (i = 0; i < 6; ++i)
|
2 * sizeof(int32_t) + sizeof(gensym_counter)) +
|
||||||
saltbuf[i] = dst_base64[counter[i]];
|
(2 * sizeof(int32_t));
|
||||||
hash = dst_string_calchash(str, newlen);
|
memcpy(sym, gensym_counter, sizeof(gensym_counter));
|
||||||
bucket = dst_symcache_findmem(str, newlen, hash, &status);
|
dst_string_length(sym) = sizeof(gensym_counter) - 1;
|
||||||
}
|
dst_string_hash(sym) = hash;
|
||||||
dst_string_hash(str) = hash;
|
dst_symcache_put((const uint8_t *)sym, bucket);
|
||||||
dst_symcache_put((const uint8_t *)str, bucket);
|
return (const uint8_t *)sym;
|
||||||
return (const uint8_t *)str;
|
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ void dst_puts(const uint8_t *str);
|
|||||||
const uint8_t *dst_symbol(const uint8_t *str, int32_t len);
|
const uint8_t *dst_symbol(const uint8_t *str, int32_t len);
|
||||||
const uint8_t *dst_symbol_from_string(const uint8_t *str);
|
const uint8_t *dst_symbol_from_string(const uint8_t *str);
|
||||||
const uint8_t *dst_csymbol(const char *str);
|
const uint8_t *dst_csymbol(const char *str);
|
||||||
const uint8_t *dst_symbol_gen(const uint8_t *buf, int32_t len);
|
const uint8_t *dst_symbol_gen();
|
||||||
#define dst_symbolv(str, len) dst_wrap_symbol(dst_symbol((str), (len)))
|
#define dst_symbolv(str, len) dst_wrap_symbol(dst_symbol((str), (len)))
|
||||||
#define dst_csymbolv(cstr) dst_wrap_symbol(dst_csymbol(cstr))
|
#define dst_csymbolv(cstr) dst_wrap_symbol(dst_csymbol(cstr))
|
||||||
|
|
||||||
|
@ -238,12 +238,11 @@
|
|||||||
# Gensym tests
|
# Gensym tests
|
||||||
|
|
||||||
(assert (not= (gensym) (gensym)) "two gensyms not equal")
|
(assert (not= (gensym) (gensym)) "two gensyms not equal")
|
||||||
(assert (not= (gensym 'abc) (gensym 'abc)) "two gensyms with arg not equal")
|
|
||||||
((fn []
|
((fn []
|
||||||
(def syms (table))
|
(def syms (table))
|
||||||
(var count 0)
|
(var count 0)
|
||||||
(while (< count 128)
|
(while (< count 128)
|
||||||
(put syms (gensym 'beep) true)
|
(put syms (gensym) true)
|
||||||
(:= count (+ 1 count)))
|
(:= count (+ 1 count)))
|
||||||
(assert (= (length syms) 128) "many symbols")))
|
(assert (= (length syms) 128) "many symbols")))
|
||||||
|
|
||||||
|
@ -161,4 +161,10 @@
|
|||||||
(testmarsh @{1 2 3 4} "marshal table")
|
(testmarsh @{1 2 3 4} "marshal table")
|
||||||
(testmarsh {1 2 3 4} "marshal struct")
|
(testmarsh {1 2 3 4} "marshal struct")
|
||||||
|
|
||||||
|
# Large functions
|
||||||
|
(def manydefs (for [i :range [0 300]] (tuple 'def (gensym) (string "value_" i))))
|
||||||
|
(array.push manydefs (tuple * 10000 3 5 7 9))
|
||||||
|
(def f (compile (tuple.prepend manydefs 'do) *env*))
|
||||||
|
(assert (= (f) (* 10000 3 5 7 9)) "long function compilation")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
Loading…
Reference in New Issue
Block a user