diff --git a/extlib/benz/codegen.c b/extlib/benz/codegen.c index f260e7b7..85f4c53f 100644 --- a/extlib/benz/codegen.c +++ b/extlib/benz/codegen.c @@ -615,6 +615,8 @@ typedef struct codegen_context { /* constant object pool */ int *ints; size_t klen, kcapa; + double *nums; + size_t flen, fcapa; pic_value *pool; size_t plen, pcapa; @@ -649,6 +651,10 @@ codegen_context_init(pic_state *pic, codegen_context *cxt, codegen_context *up, cxt->klen = 0; cxt->kcapa = PIC_POOL_SIZE; + cxt->nums = pic_calloc(pic, PIC_POOL_SIZE, sizeof(double)); + cxt->flen = 0; + cxt->fcapa = PIC_POOL_SIZE; + create_activation(pic, cxt); } @@ -667,10 +673,12 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt) irep->u.s.code = pic_realloc(pic, cxt->code, sizeof(pic_code) * cxt->clen); irep->u.s.irep = pic_realloc(pic, cxt->irep, sizeof(union irep_node) * cxt->ilen); irep->u.s.ints = pic_realloc(pic, cxt->ints, sizeof(int) * cxt->klen); + irep->u.s.nums = pic_realloc(pic, cxt->nums, sizeof(double) * cxt->flen); irep->pool = pic_realloc(pic, cxt->pool, sizeof(pic_value) * cxt->plen); irep->ncode = cxt->clen; irep->nirep = cxt->ilen; irep->nints = cxt->klen; + irep->nnums = cxt->flen; irep->npool = cxt->plen; irep->list.next = pic->ireps.next; @@ -691,7 +699,8 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt) #define check_code_size(pic, cxt) check_size(pic, cxt, c, code, pic_code) #define check_irep_size(pic, cxt) check_size(pic, cxt, i, irep, struct pic_irep *) #define check_pool_size(pic, cxt) check_size(pic, cxt, p, pool, pic_value) -#define check_ints_size(pic, cxt) check_size(pic, cxt, k, ints, pic_value) +#define check_ints_size(pic, cxt) check_size(pic, cxt, k, ints, int) +#define check_nums_size(pic, cxt) check_size(pic, cxt, f, nums, double) #define emit_n(pic, cxt, ins) do { \ check_code_size(pic, cxt); \ @@ -947,6 +956,12 @@ codegen_quote(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos) cxt->ints[pidx] = pic_int(obj); emit_i(pic, cxt, OP_PUSHINT, pidx); break; + case PIC_TT_FLOAT: + check_nums_size(pic, cxt); + pidx = (int)cxt->flen++; + cxt->nums[pidx] = pic_float(obj); + emit_i(pic, cxt, OP_PUSHFLOAT, pidx); + break; case PIC_TT_NIL: emit_n(pic, cxt, OP_PUSHNIL); break; diff --git a/extlib/benz/include/picrin/irep.h b/extlib/benz/include/picrin/irep.h index a83b073a..c01ac2b9 100644 --- a/extlib/benz/include/picrin/irep.h +++ b/extlib/benz/include/picrin/irep.h @@ -28,11 +28,13 @@ struct pic_irep { struct { int code_offset; int ints_offset; + int nums_offset; int irep_offset; } p; struct { pic_code *code; int *ints; + double *nums; union irep_node { int offset; struct pic_irep *i; @@ -40,7 +42,7 @@ struct pic_irep { } s; } u; pic_value *pool; /* pool of heap objects */ - size_t ncode, nirep, nints, npool; + size_t ncode, nirep, nints, nnums, npool; }; void pic_irep_incref(pic_state *, struct pic_irep *); diff --git a/extlib/benz/include/picrin/opcode.h b/extlib/benz/include/picrin/opcode.h index ed268ed7..e27a4a12 100644 --- a/extlib/benz/include/picrin/opcode.h +++ b/extlib/benz/include/picrin/opcode.h @@ -17,6 +17,7 @@ enum pic_opcode { OP_PUSHTRUE, OP_PUSHFALSE, OP_PUSHINT, + OP_PUSHFLOAT, OP_PUSHCHAR, OP_PUSHEOF, OP_PUSHCONST, @@ -83,6 +84,9 @@ pic_dump_code(pic_code c) case OP_PUSHINT: printf("OP_PUSHINT\t%d\n", c.a); break; + case OP_PUSHFLOAT: + printf("OP_PUSHFLAOT\t%d\n", c.a); + break; case OP_PUSHCHAR: printf("OP_PUSHCHAR\t%c\n", c.a); break; diff --git a/extlib/benz/proc.c b/extlib/benz/proc.c index c1dc7d24..7db30357 100644 --- a/extlib/benz/proc.c +++ b/extlib/benz/proc.c @@ -18,6 +18,7 @@ pic_irep_decref(pic_state *pic, struct pic_irep *irep) if (--irep->refc == 0) { pic_free(pic, irep->u.s.code); pic_free(pic, irep->u.s.ints); + pic_free(pic, irep->u.s.nums); pic_free(pic, irep->pool); /* unchain before decref children ireps */ diff --git a/extlib/benz/vm.c b/extlib/benz/vm.c index 349ec61d..7cbfa2be 100644 --- a/extlib/benz/vm.c +++ b/extlib/benz/vm.c @@ -353,7 +353,8 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv) #if PIC_DIRECT_THREADED_VM static const void *oplabels[] = { &&L_OP_NOP, &&L_OP_POP, &&L_OP_PUSHUNDEF, &&L_OP_PUSHNIL, &&L_OP_PUSHTRUE, - &&L_OP_PUSHFALSE, &&L_OP_PUSHINT, &&L_OP_PUSHCHAR, &&L_OP_PUSHEOF, &&L_OP_PUSHCONST, + &&L_OP_PUSHFALSE, &&L_OP_PUSHINT, &&L_OP_PUSHFLOAT, + &&L_OP_PUSHCHAR, &&L_OP_PUSHEOF, &&L_OP_PUSHCONST, &&L_OP_GREF, &&L_OP_GSET, &&L_OP_LREF, &&L_OP_LSET, &&L_OP_CREF, &&L_OP_CSET, &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_NOT, &&L_OP_CALL, &&L_OP_TAILCALL, &&L_OP_RET, &&L_OP_LAMBDA, &&L_OP_CONS, &&L_OP_CAR, &&L_OP_CDR, &&L_OP_NILP, @@ -410,6 +411,10 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv) PUSH(pic_int_value(pic->ci->irep->u.s.ints[c.a])); NEXT; } + CASE(OP_PUSHFLOAT) { + PUSH(pic_float_value(pic->ci->irep->u.s.nums[c.a])); + NEXT; + } CASE(OP_PUSHCHAR) { PUSH(pic_char_value(pic->ci->irep->u.s.ints[c.a])); NEXT;