2009-05-02 05:04:19 -04:00
|
|
|
#include "master.hpp"
|
|
|
|
|
2009-05-04 02:46:13 -04:00
|
|
|
namespace factor
|
|
|
|
{
|
|
|
|
|
2009-05-02 05:04:19 -04:00
|
|
|
/* Simple non-optimizing compiler.
|
|
|
|
|
|
|
|
This is one of the two compilers implementing Factor; the second one is written
|
|
|
|
in Factor and performs advanced optimizations. See core/compiler/compiler.factor.
|
|
|
|
|
|
|
|
The non-optimizing compiler compiles a quotation at a time by concatenating
|
|
|
|
machine code chunks; prolog, epilog, call word, jump to word, etc. These machine
|
|
|
|
code chunks are generated from Factor code in core/cpu/.../bootstrap.factor.
|
|
|
|
|
|
|
|
Calls to words and constant quotations (referenced by conditionals and dips)
|
|
|
|
are direct jumps to machine code blocks. Literals are also referenced directly
|
|
|
|
without going through the literal table.
|
|
|
|
|
|
|
|
It actually does do a little bit of very simple optimization:
|
|
|
|
|
|
|
|
1) Tail call optimization.
|
|
|
|
|
|
|
|
2) If a quotation is determined to not call any other words (except for a few
|
|
|
|
special words which are open-coded, see below), then no prolog/epilog is
|
|
|
|
generated.
|
|
|
|
|
|
|
|
3) When in tail position and immediately preceded by literal arguments, the
|
|
|
|
'if' is generated inline, instead of as a call to the 'if' word.
|
|
|
|
|
|
|
|
4) When preceded by a quotation, calls to 'dip', '2dip' and '3dip' are
|
|
|
|
open-coded as retain stack manipulation surrounding a subroutine call.
|
|
|
|
|
|
|
|
5) Sub-primitives are primitive words which are implemented in assembly and not
|
|
|
|
in the VM. They are open-coded and no subroutine call is generated. This
|
|
|
|
includes stack shufflers, some fixnum arithmetic words, and words such as tag,
|
|
|
|
slot and eq?. A primitive call is relatively expensive (two subroutine calls)
|
|
|
|
so this results in a big speedup for relatively little effort. */
|
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
bool quotation_jit::primitive_call_p(cell i)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
return (i + 2) == array_capacity(elements.untagged())
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i)).type_p(FIXNUM_TYPE)
|
2009-09-23 14:26:54 -04:00
|
|
|
&& array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_PRIMITIVE_WORD];
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
bool quotation_jit::fast_if_p(cell i)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
return (i + 3) == array_capacity(elements.untagged())
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE)
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(QUOTATION_TYPE)
|
2009-09-23 14:26:54 -04:00
|
|
|
&& array_nth(elements.untagged(),i + 2) == parent_vm->userenv[JIT_IF_WORD];
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
bool quotation_jit::fast_dip_p(cell i)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
return (i + 2) <= array_capacity(elements.untagged())
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE)
|
2009-09-23 14:26:54 -04:00
|
|
|
&& array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_DIP_WORD];
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
bool quotation_jit::fast_2dip_p(cell i)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
return (i + 2) <= array_capacity(elements.untagged())
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE)
|
2009-09-23 14:26:54 -04:00
|
|
|
&& array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_2DIP_WORD];
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
bool quotation_jit::fast_3dip_p(cell i)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
return (i + 2) <= array_capacity(elements.untagged())
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE)
|
2009-09-23 14:26:54 -04:00
|
|
|
&& array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_3DIP_WORD];
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
bool quotation_jit::mega_lookup_p(cell i)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
return (i + 3) < array_capacity(elements.untagged())
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i)).type_p(ARRAY_TYPE)
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(FIXNUM_TYPE)
|
|
|
|
&& tagged<object>(array_nth(elements.untagged(),i + 2)).type_p(ARRAY_TYPE)
|
2009-09-23 14:26:54 -04:00
|
|
|
&& array_nth(elements.untagged(),i + 3) == parent_vm->userenv[MEGA_LOOKUP_WORD];
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
bool quotation_jit::stack_frame_p()
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
fixnum length = array_capacity(elements.untagged());
|
|
|
|
fixnum i;
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
for(i = 0; i < length - 1; i++)
|
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
cell obj = array_nth(elements.untagged(),i);
|
|
|
|
switch(tagged<object>(obj).type())
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 02:00:30 -04:00
|
|
|
case WORD_TYPE:
|
2009-09-23 14:26:54 -04:00
|
|
|
if(parent_vm->untag<word>(obj)->subprimitive == F)
|
2009-05-02 05:04:19 -04:00
|
|
|
return true;
|
2009-05-04 02:00:30 -04:00
|
|
|
break;
|
|
|
|
case QUOTATION_TYPE:
|
2009-05-02 10:19:09 -04:00
|
|
|
if(fast_dip_p(i) || fast_2dip_p(i) || fast_3dip_p(i))
|
2009-05-02 05:04:19 -04:00
|
|
|
return true;
|
2009-05-04 02:00:30 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocates memory */
|
2009-05-02 10:19:09 -04:00
|
|
|
void quotation_jit::iterate_quotation()
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
bool stack_frame = stack_frame_p();
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
set_position(0);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
if(stack_frame)
|
2009-09-23 14:26:54 -04:00
|
|
|
emit(parent_vm->userenv[JIT_PROLOG]);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
cell i;
|
|
|
|
cell length = array_capacity(elements.untagged());
|
2009-05-02 05:04:19 -04:00
|
|
|
bool tail_call = false;
|
|
|
|
|
|
|
|
for(i = 0; i < length; i++)
|
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
set_position(i);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-09-23 14:26:54 -04:00
|
|
|
gc_root<object> obj(array_nth(elements.untagged(),i),parent_vm);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
switch(obj.type())
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
|
|
|
case WORD_TYPE:
|
|
|
|
/* Intrinsics */
|
2009-05-04 05:50:24 -04:00
|
|
|
if(obj.as<word>()->subprimitive != F)
|
2009-05-02 10:19:09 -04:00
|
|
|
emit_subprimitive(obj.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
/* The (execute) primitive is special-cased */
|
2009-09-23 14:26:54 -04:00
|
|
|
else if(obj.value() == parent_vm->userenv[JIT_EXECUTE_WORD])
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
|
|
|
if(i == length - 1)
|
|
|
|
{
|
2009-09-23 14:26:54 -04:00
|
|
|
if(stack_frame) emit(parent_vm->userenv[JIT_EPILOG]);
|
2009-05-02 10:19:09 -04:00
|
|
|
tail_call = true;
|
2009-09-23 14:26:54 -04:00
|
|
|
emit(parent_vm->userenv[JIT_EXECUTE_JUMP]);
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
else
|
2009-09-23 14:26:54 -04:00
|
|
|
emit(parent_vm->userenv[JIT_EXECUTE_CALL]);
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
/* Everything else */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(i == length - 1)
|
|
|
|
{
|
2009-09-23 14:26:54 -04:00
|
|
|
if(stack_frame) emit(parent_vm->userenv[JIT_EPILOG]);
|
2009-05-02 10:19:09 -04:00
|
|
|
tail_call = true;
|
2009-05-06 23:44:30 -04:00
|
|
|
/* Inline cache misses are special-cased.
|
|
|
|
The calling convention for tail
|
|
|
|
calls stores the address of the next
|
|
|
|
instruction in a register. However,
|
|
|
|
PIC miss stubs themselves tail-call
|
|
|
|
the inline cache miss primitive, and
|
|
|
|
we don't want to clobber the saved
|
|
|
|
address. */
|
2009-09-23 14:26:54 -04:00
|
|
|
if(obj.value() == parent_vm->userenv[PIC_MISS_WORD]
|
|
|
|
|| obj.value() == parent_vm->userenv[PIC_MISS_TAIL_WORD])
|
2009-05-06 23:04:01 -04:00
|
|
|
{
|
|
|
|
word_special(obj.value());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
word_jump(obj.value());
|
|
|
|
}
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
else
|
2009-05-02 10:19:09 -04:00
|
|
|
word_call(obj.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WRAPPER_TYPE:
|
2009-05-04 05:50:24 -04:00
|
|
|
push(obj.as<wrapper>()->object);
|
2009-05-02 05:04:19 -04:00
|
|
|
break;
|
|
|
|
case FIXNUM_TYPE:
|
|
|
|
/* Primitive calls */
|
2009-05-02 10:19:09 -04:00
|
|
|
if(primitive_call_p(i))
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-09-23 14:26:54 -04:00
|
|
|
emit_with(parent_vm->userenv[JIT_PRIMITIVE],obj.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
tail_call = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QUOTATION_TYPE:
|
|
|
|
/* 'if' preceeded by two literal quotations (this is why if and ? are
|
|
|
|
mutually recursive in the library, but both still work) */
|
2009-05-02 10:19:09 -04:00
|
|
|
if(fast_if_p(i))
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-09-23 14:26:54 -04:00
|
|
|
if(stack_frame) emit(parent_vm->userenv[JIT_EPILOG]);
|
2009-05-02 10:19:09 -04:00
|
|
|
tail_call = true;
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
if(compiling)
|
|
|
|
{
|
2009-09-23 14:26:54 -04:00
|
|
|
parent_vm->jit_compile(array_nth(elements.untagged(),i),relocate);
|
|
|
|
parent_vm->jit_compile(array_nth(elements.untagged(),i + 1),relocate);
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-06 21:04:49 -04:00
|
|
|
literal(array_nth(elements.untagged(),i));
|
|
|
|
literal(array_nth(elements.untagged(),i + 1));
|
2009-09-23 14:26:54 -04:00
|
|
|
emit(parent_vm->userenv[JIT_IF]);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
i += 2;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* dip */
|
2009-05-02 10:19:09 -04:00
|
|
|
else if(fast_dip_p(i))
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
|
|
|
if(compiling)
|
2009-09-23 14:26:54 -04:00
|
|
|
parent_vm->jit_compile(obj.value(),relocate);
|
|
|
|
emit_with(parent_vm->userenv[JIT_DIP],obj.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
i++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* 2dip */
|
2009-05-02 10:19:09 -04:00
|
|
|
else if(fast_2dip_p(i))
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
|
|
|
if(compiling)
|
2009-09-23 14:26:54 -04:00
|
|
|
parent_vm->jit_compile(obj.value(),relocate);
|
|
|
|
emit_with(parent_vm->userenv[JIT_2DIP],obj.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
i++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* 3dip */
|
2009-05-02 10:19:09 -04:00
|
|
|
else if(fast_3dip_p(i))
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
|
|
|
if(compiling)
|
2009-09-23 14:26:54 -04:00
|
|
|
parent_vm->jit_compile(obj.value(),relocate);
|
|
|
|
emit_with(parent_vm->userenv[JIT_3DIP],obj.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
i++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ARRAY_TYPE:
|
|
|
|
/* Method dispatch */
|
2009-05-02 10:19:09 -04:00
|
|
|
if(mega_lookup_p(i))
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
emit_mega_cache_lookup(
|
2009-05-04 05:50:24 -04:00
|
|
|
array_nth(elements.untagged(),i),
|
|
|
|
untag_fixnum(array_nth(elements.untagged(),i + 1)),
|
|
|
|
array_nth(elements.untagged(),i + 2));
|
2009-05-02 05:04:19 -04:00
|
|
|
i += 3;
|
|
|
|
tail_call = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
2009-05-02 10:19:09 -04:00
|
|
|
push(obj.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!tail_call)
|
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
set_position(length);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
if(stack_frame)
|
2009-09-23 14:26:54 -04:00
|
|
|
emit(parent_vm->userenv[JIT_EPILOG]);
|
|
|
|
emit(parent_vm->userenv[JIT_RETURN]);
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-23 14:05:46 -04:00
|
|
|
void factor_vm::set_quot_xt(quotation *quot, code_block *code)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-05 12:07:20 -04:00
|
|
|
if(code->type != QUOTATION_TYPE)
|
2009-05-04 05:50:24 -04:00
|
|
|
critical_error("Bad param to set_quot_xt",(cell)code);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
quot->code = code;
|
2009-05-04 05:50:24 -04:00
|
|
|
quot->xt = code->xt();
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocates memory */
|
2009-09-23 14:05:46 -04:00
|
|
|
void factor_vm::jit_compile(cell quot_, bool relocating)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-08-17 16:37:09 -04:00
|
|
|
gc_root<quotation> quot(quot_,this);
|
2009-05-12 04:09:15 -04:00
|
|
|
if(quot->code) return;
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-08-17 16:37:09 -04:00
|
|
|
quotation_jit compiler(quot.value(),true,relocating,this);
|
2009-05-04 05:50:24 -04:00
|
|
|
compiler.iterate_quotation();
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
code_block *compiled = compiler.to_code_block();
|
2009-05-02 10:19:09 -04:00
|
|
|
set_quot_xt(quot.untagged(),compiled);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
if(relocating) relocate_code_block(compiled);
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-09-23 14:05:46 -04:00
|
|
|
inline void factor_vm::primitive_jit_compile()
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
|
|
|
jit_compile(dpop(),true);
|
|
|
|
}
|
|
|
|
|
2009-08-17 16:37:08 -04:00
|
|
|
PRIMITIVE(jit_compile)
|
|
|
|
{
|
2009-09-23 13:05:17 -04:00
|
|
|
PRIMITIVE_GETVM()->primitive_jit_compile();
|
2009-08-17 16:37:08 -04:00
|
|
|
}
|
|
|
|
|
2009-05-02 05:04:19 -04:00
|
|
|
/* push a new quotation on the stack */
|
2009-09-23 14:05:46 -04:00
|
|
|
inline void factor_vm::primitive_array_to_quotation()
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
quotation *quot = allot<quotation>(sizeof(quotation));
|
2009-05-02 05:04:19 -04:00
|
|
|
quot->array = dpeek();
|
|
|
|
quot->cached_effect = F;
|
|
|
|
quot->cache_counter = F;
|
2009-05-12 04:09:15 -04:00
|
|
|
quot->xt = (void *)lazy_jit_compile;
|
|
|
|
quot->code = NULL;
|
2009-05-04 05:50:24 -04:00
|
|
|
drepl(tag<quotation>(quot));
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-08-17 16:37:08 -04:00
|
|
|
PRIMITIVE(array_to_quotation)
|
|
|
|
{
|
2009-09-23 13:05:17 -04:00
|
|
|
PRIMITIVE_GETVM()->primitive_array_to_quotation();
|
2009-08-17 16:37:08 -04:00
|
|
|
}
|
|
|
|
|
2009-09-23 14:05:46 -04:00
|
|
|
inline void factor_vm::primitive_quotation_xt()
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
quotation *quot = untag_check<quotation>(dpeek());
|
|
|
|
drepl(allot_cell((cell)quot->xt));
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-08-17 16:37:08 -04:00
|
|
|
PRIMITIVE(quotation_xt)
|
|
|
|
{
|
2009-09-23 13:05:17 -04:00
|
|
|
PRIMITIVE_GETVM()->primitive_quotation_xt();
|
2009-08-17 16:37:08 -04:00
|
|
|
}
|
|
|
|
|
2009-09-23 14:05:46 -04:00
|
|
|
void factor_vm::compile_all_words()
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-08-17 16:37:09 -04:00
|
|
|
gc_root<array> words(find_all_words(),this);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
cell i;
|
|
|
|
cell length = array_capacity(words.untagged());
|
2009-05-02 05:04:19 -04:00
|
|
|
for(i = 0; i < length; i++)
|
|
|
|
{
|
2009-08-17 16:37:09 -04:00
|
|
|
gc_root<word> word(array_nth(words.untagged(),i),this);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
if(!word->code || !word_optimized_p(word.untagged()))
|
|
|
|
jit_compile_word(word.value(),word->def,false);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
update_word_xt(word.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-08-17 16:37:08 -04:00
|
|
|
iterate_code_heap(factor::relocate_code_block);
|
|
|
|
}
|
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
/* Allocates memory */
|
2009-09-23 14:05:46 -04:00
|
|
|
fixnum factor_vm::quot_code_offset_to_scan(cell quot_, cell offset)
|
2009-05-02 10:19:09 -04:00
|
|
|
{
|
2009-08-17 16:37:09 -04:00
|
|
|
gc_root<quotation> quot(quot_,this);
|
|
|
|
gc_root<array> array(quot->array,this);
|
2009-05-02 10:19:09 -04:00
|
|
|
|
2009-08-17 16:37:09 -04:00
|
|
|
quotation_jit compiler(quot.value(),false,false,this);
|
2009-05-04 06:07:14 -04:00
|
|
|
compiler.compute_position(offset);
|
|
|
|
compiler.iterate_quotation();
|
2009-05-02 10:19:09 -04:00
|
|
|
|
2009-05-04 06:07:14 -04:00
|
|
|
return compiler.get_position();
|
2009-05-02 10:19:09 -04:00
|
|
|
}
|
2009-05-04 02:00:30 -04:00
|
|
|
|
2009-09-23 14:05:46 -04:00
|
|
|
cell factor_vm::lazy_jit_compile_impl(cell quot_, stack_frame *stack)
|
2009-05-04 02:00:30 -04:00
|
|
|
{
|
2009-08-17 16:37:09 -04:00
|
|
|
gc_root<quotation> quot(quot_,this);
|
2009-05-04 02:00:30 -04:00
|
|
|
stack_chain->callstack_top = stack;
|
|
|
|
jit_compile(quot.value(),true);
|
|
|
|
return quot.value();
|
|
|
|
}
|
2009-05-04 02:46:13 -04:00
|
|
|
|
2009-09-23 14:05:46 -04:00
|
|
|
VM_ASM_API cell lazy_jit_compile_impl(cell quot_, stack_frame *stack, factor_vm *myvm)
|
2009-08-17 16:37:08 -04:00
|
|
|
{
|
2009-08-25 02:55:51 -04:00
|
|
|
ASSERTVM();
|
2009-08-19 14:40:09 -04:00
|
|
|
return VM_PTR->lazy_jit_compile_impl(quot_,stack);
|
2009-08-17 16:37:08 -04:00
|
|
|
}
|
|
|
|
|
2009-09-23 14:05:46 -04:00
|
|
|
inline void factor_vm::primitive_quot_compiled_p()
|
2009-05-12 04:09:15 -04:00
|
|
|
{
|
|
|
|
tagged<quotation> quot(dpop());
|
2009-08-17 16:37:15 -04:00
|
|
|
quot.untag_check(this);
|
2009-05-12 04:09:15 -04:00
|
|
|
dpush(tag_boolean(quot->code != NULL));
|
|
|
|
}
|
|
|
|
|
2009-08-17 16:37:08 -04:00
|
|
|
PRIMITIVE(quot_compiled_p)
|
|
|
|
{
|
2009-09-23 13:05:17 -04:00
|
|
|
PRIMITIVE_GETVM()->primitive_quot_compiled_p();
|
2009-08-17 16:37:08 -04:00
|
|
|
}
|
|
|
|
|
2009-05-04 02:46:13 -04:00
|
|
|
}
|