vm: rename userenv to special_objects
parent
6597e0ea3a
commit
810e309e0c
|
@ -21,7 +21,7 @@ void factor_vm::init_callbacks(cell size)
|
||||||
|
|
||||||
void callback_heap::update(callback *stub)
|
void callback_heap::update(callback *stub)
|
||||||
{
|
{
|
||||||
tagged<array> code_template(parent->userenv[CALLBACK_STUB]);
|
tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
|
||||||
|
|
||||||
cell rel_class = untag_fixnum(array_nth(code_template.untagged(),1));
|
cell rel_class = untag_fixnum(array_nth(code_template.untagged(),1));
|
||||||
cell offset = untag_fixnum(array_nth(code_template.untagged(),3));
|
cell offset = untag_fixnum(array_nth(code_template.untagged(),3));
|
||||||
|
@ -35,7 +35,7 @@ void callback_heap::update(callback *stub)
|
||||||
|
|
||||||
callback *callback_heap::add(code_block *compiled)
|
callback *callback_heap::add(code_block *compiled)
|
||||||
{
|
{
|
||||||
tagged<array> code_template(parent->userenv[CALLBACK_STUB]);
|
tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
|
||||||
tagged<byte_array> insns(array_nth(code_template.untagged(),0));
|
tagged<byte_array> insns(array_nth(code_template.untagged(),0));
|
||||||
cell size = array_capacity(insns.untagged());
|
cell size = array_capacity(insns.untagged());
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,8 @@ template<typename TargetGeneration, typename Policy> struct collector {
|
||||||
trace_registered_locals();
|
trace_registered_locals();
|
||||||
trace_registered_bignums();
|
trace_registered_bignums();
|
||||||
|
|
||||||
for(int i = 0; i < USER_ENV; i++) trace_handle(&parent->userenv[i]);
|
for(cell i = 0; i < special_object_count; i++)
|
||||||
|
trace_handle(&parent->special_objects[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trace_contexts()
|
void trace_contexts()
|
||||||
|
|
|
@ -80,9 +80,9 @@ void factor_vm::nest_stacks(stack_frame *magic_frame)
|
||||||
|
|
||||||
new_ctx->magic_frame = magic_frame;
|
new_ctx->magic_frame = magic_frame;
|
||||||
|
|
||||||
/* save per-callback userenv */
|
/* save per-callback special_objects */
|
||||||
new_ctx->current_callback_save = userenv[CURRENT_CALLBACK_ENV];
|
new_ctx->current_callback_save = special_objects[OBJ_CURRENT_CALLBACK];
|
||||||
new_ctx->catchstack_save = userenv[CATCHSTACK_ENV];
|
new_ctx->catchstack_save = special_objects[OBJ_CATCHSTACK];
|
||||||
|
|
||||||
new_ctx->next = ctx;
|
new_ctx->next = ctx;
|
||||||
ctx = new_ctx;
|
ctx = new_ctx;
|
||||||
|
@ -102,9 +102,9 @@ void factor_vm::unnest_stacks()
|
||||||
ds = ctx->datastack_save;
|
ds = ctx->datastack_save;
|
||||||
rs = ctx->retainstack_save;
|
rs = ctx->retainstack_save;
|
||||||
|
|
||||||
/* restore per-callback userenv */
|
/* restore per-callback special_objects */
|
||||||
userenv[CURRENT_CALLBACK_ENV] = ctx->current_callback_save;
|
special_objects[OBJ_CURRENT_CALLBACK] = ctx->current_callback_save;
|
||||||
userenv[CATCHSTACK_ENV] = ctx->catchstack_save;
|
special_objects[OBJ_CATCHSTACK] = ctx->catchstack_save;
|
||||||
|
|
||||||
context *old_ctx = ctx;
|
context *old_ctx = ctx;
|
||||||
ctx = old_ctx->next;
|
ctx = old_ctx->next;
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct context {
|
||||||
/* memory region holding current retain stack */
|
/* memory region holding current retain stack */
|
||||||
segment *retainstack_region;
|
segment *retainstack_region;
|
||||||
|
|
||||||
/* saved userenv slots on entry to callback */
|
/* saved special_objects slots on entry to callback */
|
||||||
cell catchstack_save;
|
cell catchstack_save;
|
||||||
cell current_callback_save;
|
cell current_callback_save;
|
||||||
|
|
||||||
|
|
|
@ -419,9 +419,8 @@ void factor_vm::factorbug()
|
||||||
print_callstack();
|
print_callstack();
|
||||||
else if(strcmp(cmd,"e") == 0)
|
else if(strcmp(cmd,"e") == 0)
|
||||||
{
|
{
|
||||||
int i;
|
for(cell i = 0; i < special_object_count; i++)
|
||||||
for(i = 0; i < USER_ENV; i++)
|
dump_cell((cell)&special_objects[i]);
|
||||||
dump_cell((cell)&userenv[i]);
|
|
||||||
}
|
}
|
||||||
else if(strcmp(cmd,"g") == 0)
|
else if(strcmp(cmd,"g") == 0)
|
||||||
dump_generations();
|
dump_generations();
|
||||||
|
|
|
@ -187,21 +187,21 @@ void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cac
|
||||||
emit_class_lookup(index,PIC_HI_TAG_TUPLE);
|
emit_class_lookup(index,PIC_HI_TAG_TUPLE);
|
||||||
|
|
||||||
/* Do a cache lookup. */
|
/* Do a cache lookup. */
|
||||||
emit_with(parent->userenv[MEGA_LOOKUP],cache.value());
|
emit_with(parent->special_objects[MEGA_LOOKUP],cache.value());
|
||||||
|
|
||||||
/* If we end up here, the cache missed. */
|
/* If we end up here, the cache missed. */
|
||||||
emit(parent->userenv[JIT_PROLOG]);
|
emit(parent->special_objects[JIT_PROLOG]);
|
||||||
|
|
||||||
/* Push index, method table and cache on the stack. */
|
/* Push index, method table and cache on the stack. */
|
||||||
push(methods.value());
|
push(methods.value());
|
||||||
push(tag_fixnum(index));
|
push(tag_fixnum(index));
|
||||||
push(cache.value());
|
push(cache.value());
|
||||||
word_call(parent->userenv[MEGA_MISS_WORD]);
|
word_call(parent->special_objects[MEGA_MISS_WORD]);
|
||||||
|
|
||||||
/* Now the new method has been stored into the cache, and its on
|
/* Now the new method has been stored into the cache, and its on
|
||||||
the stack. */
|
the stack. */
|
||||||
emit(parent->userenv[JIT_EPILOG]);
|
emit(parent->special_objects[JIT_EPILOG]);
|
||||||
emit(parent->userenv[JIT_EXECUTE_JUMP]);
|
emit(parent->special_objects[JIT_EXECUTE_JUMP]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
|
||||||
{
|
{
|
||||||
/* If the error handler is set, we rewind any C stack frames and
|
/* If the error handler is set, we rewind any C stack frames and
|
||||||
pass the error to user-space. */
|
pass the error to user-space. */
|
||||||
if(!current_gc && to_boolean(userenv[BREAK_ENV]))
|
if(!current_gc && to_boolean(special_objects[OBJ_BREAK]))
|
||||||
{
|
{
|
||||||
/* If error was thrown during heap scan, we re-enable the GC */
|
/* If error was thrown during heap scan, we re-enable the GC */
|
||||||
gc_off = false;
|
gc_off = false;
|
||||||
|
@ -55,7 +55,7 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
|
||||||
else
|
else
|
||||||
callstack_top = ctx->callstack_top;
|
callstack_top = ctx->callstack_top;
|
||||||
|
|
||||||
throw_impl(userenv[BREAK_ENV],callstack_top,this);
|
throw_impl(special_objects[OBJ_BREAK],callstack_top,this);
|
||||||
}
|
}
|
||||||
/* Error was thrown in early startup before error handler is set, just
|
/* Error was thrown in early startup before error handler is set, just
|
||||||
crash. */
|
crash. */
|
||||||
|
@ -71,7 +71,7 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
|
||||||
|
|
||||||
void factor_vm::general_error(vm_error_type error, cell arg1, cell arg2, stack_frame *callstack_top)
|
void factor_vm::general_error(vm_error_type error, cell arg1, cell arg2, stack_frame *callstack_top)
|
||||||
{
|
{
|
||||||
throw_error(allot_array_4(userenv[ERROR_ENV],
|
throw_error(allot_array_4(special_objects[OBJ_ERROR],
|
||||||
tag_fixnum(error),arg1,arg2),callstack_top);
|
tag_fixnum(error),arg1,arg2),callstack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ void factor_vm::do_stage1_init()
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
compile_all_words();
|
compile_all_words();
|
||||||
userenv[STAGE2_ENV] = true_object;
|
special_objects[OBJ_STAGE2] = true_object;
|
||||||
|
|
||||||
std::cout << "done\n";
|
std::cout << "done\n";
|
||||||
}
|
}
|
||||||
|
@ -149,17 +149,17 @@ void factor_vm::init_factor(vm_parameters *p)
|
||||||
|
|
||||||
init_profiler();
|
init_profiler();
|
||||||
|
|
||||||
userenv[CPU_ENV] = allot_alien(false_object,(cell)FACTOR_CPU_STRING);
|
special_objects[OBJ_CPU] = allot_alien(false_object,(cell)FACTOR_CPU_STRING);
|
||||||
userenv[OS_ENV] = allot_alien(false_object,(cell)FACTOR_OS_STRING);
|
special_objects[OBJ_OS] = allot_alien(false_object,(cell)FACTOR_OS_STRING);
|
||||||
userenv[CELL_SIZE_ENV] = tag_fixnum(sizeof(cell));
|
special_objects[OBJ_CELL_SIZE] = tag_fixnum(sizeof(cell));
|
||||||
userenv[EXECUTABLE_ENV] = allot_alien(false_object,(cell)p->executable_path);
|
special_objects[OBJ_EXECUTABLE] = allot_alien(false_object,(cell)p->executable_path);
|
||||||
userenv[ARGS_ENV] = false_object;
|
special_objects[OBJ_ARGS] = false_object;
|
||||||
userenv[EMBEDDED_ENV] = false_object;
|
special_objects[OBJ_EMBEDDED] = false_object;
|
||||||
|
|
||||||
/* We can GC now */
|
/* We can GC now */
|
||||||
gc_off = false;
|
gc_off = false;
|
||||||
|
|
||||||
if(!to_boolean(userenv[STAGE2_ENV]))
|
if(!to_boolean(special_objects[OBJ_STAGE2]))
|
||||||
do_stage1_init();
|
do_stage1_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ void factor_vm::pass_args_to_factor(int argc, vm_char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
args.trim();
|
args.trim();
|
||||||
userenv[ARGS_ENV] = args.elements.value();
|
special_objects[OBJ_ARGS] = args.elements.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::start_factor(vm_parameters *p)
|
void factor_vm::start_factor(vm_parameters *p)
|
||||||
|
@ -182,13 +182,13 @@ void factor_vm::start_factor(vm_parameters *p)
|
||||||
if(p->fep) factorbug();
|
if(p->fep) factorbug();
|
||||||
|
|
||||||
nest_stacks(NULL);
|
nest_stacks(NULL);
|
||||||
c_to_factor_toplevel(userenv[BOOT_ENV]);
|
c_to_factor_toplevel(special_objects[OBJ_BOOT]);
|
||||||
unnest_stacks();
|
unnest_stacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
char *factor_vm::factor_eval_string(char *string)
|
char *factor_vm::factor_eval_string(char *string)
|
||||||
{
|
{
|
||||||
char *(*callback)(char *) = (char *(*)(char *))alien_offset(userenv[EVAL_CALLBACK_ENV]);
|
char *(*callback)(char *) = (char *(*)(char *))alien_offset(special_objects[OBJ_EVAL_CALLBACK]);
|
||||||
return callback(string);
|
return callback(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,13 +199,13 @@ void factor_vm::factor_eval_free(char *result)
|
||||||
|
|
||||||
void factor_vm::factor_yield()
|
void factor_vm::factor_yield()
|
||||||
{
|
{
|
||||||
void (*callback)() = (void (*)())alien_offset(userenv[YIELD_CALLBACK_ENV]);
|
void (*callback)() = (void (*)())alien_offset(special_objects[OBJ_YIELD_CALLBACK]);
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::factor_sleep(long us)
|
void factor_vm::factor_sleep(long us)
|
||||||
{
|
{
|
||||||
void (*callback)(long) = (void (*)(long))alien_offset(userenv[SLEEP_CALLBACK_ENV]);
|
void (*callback)(long) = (void (*)(long))alien_offset(special_objects[OBJ_SLEEP_CALLBACK]);
|
||||||
callback(us);
|
callback(us);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
vm/image.cpp
18
vm/image.cpp
|
@ -6,7 +6,7 @@ namespace factor
|
||||||
/* Certain special objects in the image are known to the runtime */
|
/* Certain special objects in the image are known to the runtime */
|
||||||
void factor_vm::init_objects(image_header *h)
|
void factor_vm::init_objects(image_header *h)
|
||||||
{
|
{
|
||||||
memcpy(userenv,h->userenv,sizeof(userenv));
|
memcpy(special_objects,h->special_objects,sizeof(special_objects));
|
||||||
|
|
||||||
true_object = h->true_object;
|
true_object = h->true_object;
|
||||||
bignum_zero = h->bignum_zero;
|
bignum_zero = h->bignum_zero;
|
||||||
|
@ -183,8 +183,8 @@ void factor_vm::relocate_object(object *object,
|
||||||
where it is loaded, we need to fix up pointers in the image. */
|
where it is loaded, we need to fix up pointers in the image. */
|
||||||
void factor_vm::relocate_data(cell data_relocation_base, cell code_relocation_base)
|
void factor_vm::relocate_data(cell data_relocation_base, cell code_relocation_base)
|
||||||
{
|
{
|
||||||
for(cell i = 0; i < USER_ENV; i++)
|
for(cell i = 0; i < special_object_count; i++)
|
||||||
data_fixup(&userenv[i],data_relocation_base);
|
data_fixup(&special_objects[i],data_relocation_base);
|
||||||
|
|
||||||
data_fixup(&true_object,data_relocation_base);
|
data_fixup(&true_object,data_relocation_base);
|
||||||
data_fixup(&bignum_zero,data_relocation_base);
|
data_fixup(&bignum_zero,data_relocation_base);
|
||||||
|
@ -263,7 +263,7 @@ void factor_vm::load_image(vm_parameters *p)
|
||||||
relocate_code(h.data_relocation_base);
|
relocate_code(h.data_relocation_base);
|
||||||
|
|
||||||
/* Store image path name */
|
/* Store image path name */
|
||||||
userenv[IMAGE_ENV] = allot_alien(false_object,(cell)p->image_path);
|
special_objects[OBJ_IMAGE] = allot_alien(false_object,(cell)p->image_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the current image to disk */
|
/* Save the current image to disk */
|
||||||
|
@ -292,8 +292,8 @@ bool factor_vm::save_image(const vm_char *filename)
|
||||||
h.bignum_pos_one = bignum_pos_one;
|
h.bignum_pos_one = bignum_pos_one;
|
||||||
h.bignum_neg_one = bignum_neg_one;
|
h.bignum_neg_one = bignum_neg_one;
|
||||||
|
|
||||||
for(cell i = 0; i < USER_ENV; i++)
|
for(cell i = 0; i < special_object_count; i++)
|
||||||
h.userenv[i] = (save_env_p(i) ? userenv[i] : false_object);
|
h.special_objects[i] = (save_env_p(i) ? special_objects[i] : false_object);
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
|
@ -326,9 +326,9 @@ void factor_vm::primitive_save_image_and_exit()
|
||||||
gc_root<byte_array> path(dpop(),this);
|
gc_root<byte_array> path(dpop(),this);
|
||||||
path.untag_check(this);
|
path.untag_check(this);
|
||||||
|
|
||||||
/* strip out userenv data which is set on startup anyway */
|
/* strip out special_objects data which is set on startup anyway */
|
||||||
for(cell i = 0; i < USER_ENV; i++)
|
for(cell i = 0; i < special_object_count; i++)
|
||||||
if(!save_env_p(i)) userenv[i] = false_object;
|
if(!save_env_p(i)) special_objects[i] = false_object;
|
||||||
|
|
||||||
gc(collect_full_op,
|
gc(collect_full_op,
|
||||||
0, /* requested size */
|
0, /* requested size */
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct image_header {
|
||||||
/* tagged pointer to bignum -1 */
|
/* tagged pointer to bignum -1 */
|
||||||
cell bignum_neg_one;
|
cell bignum_neg_one;
|
||||||
/* Initial user environment */
|
/* Initial user environment */
|
||||||
cell userenv[USER_ENV];
|
cell special_objects[special_object_count];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vm_parameters {
|
struct vm_parameters {
|
||||||
|
|
|
@ -86,9 +86,9 @@ void inline_cache_jit::emit_check(cell klass)
|
||||||
{
|
{
|
||||||
cell code_template;
|
cell code_template;
|
||||||
if(TAG(klass) == FIXNUM_TYPE && untag_fixnum(klass) < HEADER_TYPE)
|
if(TAG(klass) == FIXNUM_TYPE && untag_fixnum(klass) < HEADER_TYPE)
|
||||||
code_template = parent->userenv[PIC_CHECK_TAG];
|
code_template = parent->special_objects[PIC_CHECK_TAG];
|
||||||
else
|
else
|
||||||
code_template = parent->userenv[PIC_CHECK];
|
code_template = parent->special_objects[PIC_CHECK];
|
||||||
|
|
||||||
emit_with(code_template,klass);
|
emit_with(code_template,klass);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
|
||||||
|
|
||||||
/* Yes? Jump to method */
|
/* Yes? Jump to method */
|
||||||
cell method = array_nth(cache_entries.untagged(),i + 1);
|
cell method = array_nth(cache_entries.untagged(),i + 1);
|
||||||
emit_with(parent->userenv[PIC_HIT],method);
|
emit_with(parent->special_objects[PIC_HIT],method);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate machine code to handle a cache miss, which ultimately results in
|
/* Generate machine code to handle a cache miss, which ultimately results in
|
||||||
|
@ -133,7 +133,7 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
|
||||||
push(methods.value());
|
push(methods.value());
|
||||||
push(tag_fixnum(index));
|
push(tag_fixnum(index));
|
||||||
push(cache_entries.value());
|
push(cache_entries.value());
|
||||||
word_special(parent->userenv[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD]);
|
word_special(parent->special_objects[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
code_block *factor_vm::compile_inline_cache(fixnum index,cell generic_word_,cell methods_,cell cache_entries_,bool tail_call_p)
|
code_block *factor_vm::compile_inline_cache(fixnum index,cell generic_word_,cell methods_,cell cache_entries_,bool tail_call_p)
|
||||||
|
|
|
@ -16,9 +16,9 @@ normal operation. */
|
||||||
|
|
||||||
void factor_vm::init_c_io()
|
void factor_vm::init_c_io()
|
||||||
{
|
{
|
||||||
userenv[STDIN_ENV] = allot_alien(false_object,(cell)stdin);
|
special_objects[OBJ_STDIN] = allot_alien(false_object,(cell)stdin);
|
||||||
userenv[STDOUT_ENV] = allot_alien(false_object,(cell)stdout);
|
special_objects[OBJ_STDOUT] = allot_alien(false_object,(cell)stdout);
|
||||||
userenv[STDERR_ENV] = allot_alien(false_object,(cell)stderr);
|
special_objects[OBJ_STDERR] = allot_alien(false_object,(cell)stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::io_error()
|
void factor_vm::io_error()
|
||||||
|
|
|
@ -79,8 +79,8 @@ void jit::emit_with(cell code_template_, cell argument_) {
|
||||||
|
|
||||||
void jit::emit_class_lookup(fixnum index, cell type)
|
void jit::emit_class_lookup(fixnum index, cell type)
|
||||||
{
|
{
|
||||||
emit_with(parent->userenv[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
|
emit_with(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
|
||||||
emit(parent->userenv[type]);
|
emit(parent->special_objects[type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Facility to convert compiled code offsets to quotation offsets.
|
/* Facility to convert compiled code offsets to quotation offsets.
|
||||||
|
|
29
vm/jit.hpp
29
vm/jit.hpp
|
@ -21,26 +21,31 @@ struct jit {
|
||||||
void literal(cell literal) { literals.add(literal); }
|
void literal(cell literal) { literals.add(literal); }
|
||||||
void emit_with(cell code_template_, cell literal_);
|
void emit_with(cell code_template_, cell literal_);
|
||||||
|
|
||||||
void push(cell literal) {
|
void push(cell literal)
|
||||||
emit_with(parent->userenv[JIT_PUSH_IMMEDIATE],literal);
|
{
|
||||||
|
emit_with(parent->special_objects[JIT_PUSH_IMMEDIATE],literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void word_jump(cell word_) {
|
void word_jump(cell word_)
|
||||||
|
{
|
||||||
gc_root<word> word(word_,parent);
|
gc_root<word> word(word_,parent);
|
||||||
literal(tag_fixnum(xt_tail_pic_offset));
|
literal(tag_fixnum(xt_tail_pic_offset));
|
||||||
literal(word.value());
|
literal(word.value());
|
||||||
emit(parent->userenv[JIT_WORD_JUMP]);
|
emit(parent->special_objects[JIT_WORD_JUMP]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void word_call(cell word) {
|
void word_call(cell word)
|
||||||
emit_with(parent->userenv[JIT_WORD_CALL],word);
|
{
|
||||||
|
emit_with(parent->special_objects[JIT_WORD_CALL],word);
|
||||||
}
|
}
|
||||||
|
|
||||||
void word_special(cell word) {
|
void word_special(cell word)
|
||||||
emit_with(parent->userenv[JIT_WORD_SPECIAL],word);
|
{
|
||||||
|
emit_with(parent->special_objects[JIT_WORD_SPECIAL],word);
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit_subprimitive(cell word_) {
|
void emit_subprimitive(cell word_)
|
||||||
|
{
|
||||||
gc_root<word> word(word_,parent);
|
gc_root<word> word(word_,parent);
|
||||||
gc_root<array> code_pair(word->subprimitive,parent);
|
gc_root<array> code_pair(word->subprimitive,parent);
|
||||||
literals.append(untag<array>(array_nth(code_pair.untagged(),0)));
|
literals.append(untag<array>(array_nth(code_pair.untagged(),0)));
|
||||||
|
@ -49,7 +54,8 @@ struct jit {
|
||||||
|
|
||||||
void emit_class_lookup(fixnum index, cell type);
|
void emit_class_lookup(fixnum index, cell type);
|
||||||
|
|
||||||
fixnum get_position() {
|
fixnum get_position()
|
||||||
|
{
|
||||||
if(computing_offset_p)
|
if(computing_offset_p)
|
||||||
{
|
{
|
||||||
/* If this is still on, emit() didn't clear it,
|
/* If this is still on, emit() didn't clear it,
|
||||||
|
@ -60,7 +66,8 @@ struct jit {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_position(fixnum position_) {
|
void set_position(fixnum position_)
|
||||||
|
{
|
||||||
if(computing_offset_p)
|
if(computing_offset_p)
|
||||||
position = position_;
|
position = position_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ NS_DURING
|
||||||
NS_VOIDRETURN;
|
NS_VOIDRETURN;
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
dpush(allot_alien(false_object,(cell)localException));
|
dpush(allot_alien(false_object,(cell)localException));
|
||||||
quot = userenv[COCOA_EXCEPTION_ENV];
|
quot = special_objects[OBJ_COCOA_EXCEPTION];
|
||||||
if(!tagged<object>(quot).type_p(QUOTATION_TYPE))
|
if(!tagged<object>(quot).type_p(QUOTATION_TYPE))
|
||||||
{
|
{
|
||||||
/* No Cocoa exception handler was registered, so
|
/* No Cocoa exception handler was registered, so
|
||||||
|
|
|
@ -14,7 +14,7 @@ code_block *factor_vm::compile_profiling_stub(cell word_)
|
||||||
gc_root<word> word(word_,this);
|
gc_root<word> word(word_,this);
|
||||||
|
|
||||||
jit jit(code_block_profiling,word.value(),this);
|
jit jit(code_block_profiling,word.value(),this);
|
||||||
jit.emit_with(userenv[JIT_PROFILING],word.value());
|
jit.emit_with(special_objects[JIT_PROFILING],word.value());
|
||||||
|
|
||||||
return jit.to_code_block();
|
return jit.to_code_block();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,29 +38,29 @@ so this results in a big speedup for relatively little effort. */
|
||||||
|
|
||||||
bool quotation_jit::primitive_call_p(cell i, cell length)
|
bool quotation_jit::primitive_call_p(cell i, cell length)
|
||||||
{
|
{
|
||||||
return (i + 2) == length && array_nth(elements.untagged(),i + 1) == parent->userenv[JIT_PRIMITIVE_WORD];
|
return (i + 2) == length && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_PRIMITIVE_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::fast_if_p(cell i, cell length)
|
bool quotation_jit::fast_if_p(cell i, cell length)
|
||||||
{
|
{
|
||||||
return (i + 3) == length
|
return (i + 3) == length
|
||||||
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(QUOTATION_TYPE)
|
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(QUOTATION_TYPE)
|
||||||
&& array_nth(elements.untagged(),i + 2) == parent->userenv[JIT_IF_WORD];
|
&& array_nth(elements.untagged(),i + 2) == parent->special_objects[JIT_IF_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::fast_dip_p(cell i, cell length)
|
bool quotation_jit::fast_dip_p(cell i, cell length)
|
||||||
{
|
{
|
||||||
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->userenv[JIT_DIP_WORD];
|
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_DIP_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::fast_2dip_p(cell i, cell length)
|
bool quotation_jit::fast_2dip_p(cell i, cell length)
|
||||||
{
|
{
|
||||||
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->userenv[JIT_2DIP_WORD];
|
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_2DIP_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::fast_3dip_p(cell i, cell length)
|
bool quotation_jit::fast_3dip_p(cell i, cell length)
|
||||||
{
|
{
|
||||||
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->userenv[JIT_3DIP_WORD];
|
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_3DIP_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::mega_lookup_p(cell i, cell length)
|
bool quotation_jit::mega_lookup_p(cell i, cell length)
|
||||||
|
@ -68,13 +68,13 @@ bool quotation_jit::mega_lookup_p(cell i, cell length)
|
||||||
return (i + 4) <= length
|
return (i + 4) <= length
|
||||||
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(FIXNUM_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)
|
&& tagged<object>(array_nth(elements.untagged(),i + 2)).type_p(ARRAY_TYPE)
|
||||||
&& array_nth(elements.untagged(),i + 3) == parent->userenv[MEGA_LOOKUP_WORD];
|
&& array_nth(elements.untagged(),i + 3) == parent->special_objects[MEGA_LOOKUP_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::declare_p(cell i, cell length)
|
bool quotation_jit::declare_p(cell i, cell length)
|
||||||
{
|
{
|
||||||
return (i + 2) <= length
|
return (i + 2) <= length
|
||||||
&& array_nth(elements.untagged(),i + 1) == parent->userenv[JIT_DECLARE_WORD];
|
&& array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_DECLARE_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::stack_frame_p()
|
bool quotation_jit::stack_frame_p()
|
||||||
|
@ -133,7 +133,7 @@ void quotation_jit::iterate_quotation()
|
||||||
set_position(0);
|
set_position(0);
|
||||||
|
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
emit(parent->userenv[JIT_PROLOG]);
|
emit(parent->special_objects[JIT_PROLOG]);
|
||||||
|
|
||||||
cell i;
|
cell i;
|
||||||
cell length = array_capacity(elements.untagged());
|
cell length = array_capacity(elements.untagged());
|
||||||
|
@ -152,23 +152,23 @@ void quotation_jit::iterate_quotation()
|
||||||
if(parent->to_boolean(obj.as<word>()->subprimitive))
|
if(parent->to_boolean(obj.as<word>()->subprimitive))
|
||||||
emit_subprimitive(obj.value());
|
emit_subprimitive(obj.value());
|
||||||
/* The (execute) primitive is special-cased */
|
/* The (execute) primitive is special-cased */
|
||||||
else if(obj.value() == parent->userenv[JIT_EXECUTE_WORD])
|
else if(obj.value() == parent->special_objects[JIT_EXECUTE_WORD])
|
||||||
{
|
{
|
||||||
if(i == length - 1)
|
if(i == length - 1)
|
||||||
{
|
{
|
||||||
if(stack_frame) emit(parent->userenv[JIT_EPILOG]);
|
if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
emit(parent->userenv[JIT_EXECUTE_JUMP]);
|
emit(parent->special_objects[JIT_EXECUTE_JUMP]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
emit(parent->userenv[JIT_EXECUTE_CALL]);
|
emit(parent->special_objects[JIT_EXECUTE_CALL]);
|
||||||
}
|
}
|
||||||
/* Everything else */
|
/* Everything else */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(i == length - 1)
|
if(i == length - 1)
|
||||||
{
|
{
|
||||||
if(stack_frame) emit(parent->userenv[JIT_EPILOG]);
|
if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
/* Inline cache misses are special-cased.
|
/* Inline cache misses are special-cased.
|
||||||
The calling convention for tail
|
The calling convention for tail
|
||||||
|
@ -178,8 +178,8 @@ void quotation_jit::iterate_quotation()
|
||||||
the inline cache miss primitive, and
|
the inline cache miss primitive, and
|
||||||
we don't want to clobber the saved
|
we don't want to clobber the saved
|
||||||
address. */
|
address. */
|
||||||
if(obj.value() == parent->userenv[PIC_MISS_WORD]
|
if(obj.value() == parent->special_objects[PIC_MISS_WORD]
|
||||||
|| obj.value() == parent->userenv[PIC_MISS_TAIL_WORD])
|
|| obj.value() == parent->special_objects[PIC_MISS_TAIL_WORD])
|
||||||
{
|
{
|
||||||
word_special(obj.value());
|
word_special(obj.value());
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ void quotation_jit::iterate_quotation()
|
||||||
{
|
{
|
||||||
literal(tag_fixnum(0));
|
literal(tag_fixnum(0));
|
||||||
literal(obj.value());
|
literal(obj.value());
|
||||||
emit(parent->userenv[JIT_PRIMITIVE]);
|
emit(parent->special_objects[JIT_PRIMITIVE]);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
@ -215,12 +215,12 @@ void quotation_jit::iterate_quotation()
|
||||||
mutually recursive in the library, but both still work) */
|
mutually recursive in the library, but both still work) */
|
||||||
if(fast_if_p(i,length))
|
if(fast_if_p(i,length))
|
||||||
{
|
{
|
||||||
if(stack_frame) emit(parent->userenv[JIT_EPILOG]);
|
if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
|
|
||||||
emit_quot(array_nth(elements.untagged(),i));
|
emit_quot(array_nth(elements.untagged(),i));
|
||||||
emit_quot(array_nth(elements.untagged(),i + 1));
|
emit_quot(array_nth(elements.untagged(),i + 1));
|
||||||
emit(parent->userenv[JIT_IF]);
|
emit(parent->special_objects[JIT_IF]);
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
@ -228,21 +228,21 @@ void quotation_jit::iterate_quotation()
|
||||||
else if(fast_dip_p(i,length))
|
else if(fast_dip_p(i,length))
|
||||||
{
|
{
|
||||||
emit_quot(obj.value());
|
emit_quot(obj.value());
|
||||||
emit(parent->userenv[JIT_DIP]);
|
emit(parent->special_objects[JIT_DIP]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
/* 2dip */
|
/* 2dip */
|
||||||
else if(fast_2dip_p(i,length))
|
else if(fast_2dip_p(i,length))
|
||||||
{
|
{
|
||||||
emit_quot(obj.value());
|
emit_quot(obj.value());
|
||||||
emit(parent->userenv[JIT_2DIP]);
|
emit(parent->special_objects[JIT_2DIP]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
/* 3dip */
|
/* 3dip */
|
||||||
else if(fast_3dip_p(i,length))
|
else if(fast_3dip_p(i,length))
|
||||||
{
|
{
|
||||||
emit_quot(obj.value());
|
emit_quot(obj.value());
|
||||||
emit(parent->userenv[JIT_3DIP]);
|
emit(parent->special_objects[JIT_3DIP]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -276,8 +276,8 @@ void quotation_jit::iterate_quotation()
|
||||||
set_position(length);
|
set_position(length);
|
||||||
|
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
emit(parent->userenv[JIT_EPILOG]);
|
emit(parent->special_objects[JIT_EPILOG]);
|
||||||
emit(parent->userenv[JIT_RETURN]);
|
emit(parent->special_objects[JIT_RETURN]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@ namespace factor
|
||||||
void factor_vm::primitive_getenv()
|
void factor_vm::primitive_getenv()
|
||||||
{
|
{
|
||||||
fixnum e = untag_fixnum(dpeek());
|
fixnum e = untag_fixnum(dpeek());
|
||||||
drepl(userenv[e]);
|
drepl(special_objects[e]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_setenv()
|
void factor_vm::primitive_setenv()
|
||||||
{
|
{
|
||||||
fixnum e = untag_fixnum(dpop());
|
fixnum e = untag_fixnum(dpop());
|
||||||
cell value = dpop();
|
cell value = dpop();
|
||||||
userenv[e] = value;
|
special_objects[e] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_exit()
|
void factor_vm::primitive_exit()
|
||||||
|
|
66
vm/run.hpp
66
vm/run.hpp
|
@ -1,39 +1,39 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
#define USER_ENV 70
|
static const cell special_object_count = 70;
|
||||||
|
|
||||||
enum special_object {
|
enum special_object {
|
||||||
NAMESTACK_ENV, /* used by library only */
|
OBJ_NAMESTACK, /* used by library only */
|
||||||
CATCHSTACK_ENV, /* used by library only, per-callback */
|
OBJ_CATCHSTACK, /* used by library only, per-callback */
|
||||||
|
|
||||||
CURRENT_CALLBACK_ENV = 2, /* used by library only, per-callback */
|
OBJ_CURRENT_CALLBACK = 2, /* used by library only, per-callback */
|
||||||
WALKER_HOOK_ENV, /* non-local exit hook, used by library only */
|
OBJ_WALKER_HOOK, /* non-local exit hook, used by library only */
|
||||||
CALLCC_1_ENV, /* used to pass the value in callcc1 */
|
OBJ_CALLCC_1, /* used to pass the value in callcc1 */
|
||||||
|
|
||||||
BREAK_ENV = 5, /* quotation called by throw primitive */
|
OBJ_BREAK = 5, /* quotation called by throw primitive */
|
||||||
ERROR_ENV, /* a marker consed onto kernel errors */
|
OBJ_ERROR, /* a marker consed onto kernel errors */
|
||||||
|
|
||||||
CELL_SIZE_ENV = 7, /* sizeof(cell) */
|
OBJ_CELL_SIZE = 7, /* sizeof(cell) */
|
||||||
CPU_ENV, /* CPU architecture */
|
OBJ_CPU, /* CPU architecture */
|
||||||
OS_ENV, /* operating system name */
|
OBJ_OS, /* operating system name */
|
||||||
|
|
||||||
ARGS_ENV = 10, /* command line arguments */
|
OBJ_ARGS = 10, /* command line arguments */
|
||||||
STDIN_ENV, /* stdin FILE* handle */
|
OBJ_STDIN, /* stdin FILE* handle */
|
||||||
STDOUT_ENV, /* stdout FILE* handle */
|
OBJ_STDOUT, /* stdout FILE* handle */
|
||||||
|
|
||||||
IMAGE_ENV = 13, /* image path name */
|
OBJ_IMAGE = 13, /* image path name */
|
||||||
EXECUTABLE_ENV, /* runtime executable path name */
|
OBJ_EXECUTABLE, /* runtime executable path name */
|
||||||
|
|
||||||
EMBEDDED_ENV = 15, /* are we embedded in another app? */
|
OBJ_EMBEDDED = 15, /* are we embedded in another app? */
|
||||||
EVAL_CALLBACK_ENV, /* used when Factor is embedded in a C app */
|
OBJ_EVAL_CALLBACK, /* used when Factor is embedded in a C app */
|
||||||
YIELD_CALLBACK_ENV, /* used when Factor is embedded in a C app */
|
OBJ_YIELD_CALLBACK, /* used when Factor is embedded in a C app */
|
||||||
SLEEP_CALLBACK_ENV, /* used when Factor is embedded in a C app */
|
OBJ_SLEEP_CALLBACK, /* used when Factor is embedded in a C app */
|
||||||
|
|
||||||
COCOA_EXCEPTION_ENV = 19, /* Cocoa exception handler quotation */
|
OBJ_COCOA_EXCEPTION = 19, /* Cocoa exception handler quotation */
|
||||||
|
|
||||||
BOOT_ENV = 20, /* boot quotation */
|
OBJ_BOOT = 20, /* boot quotation */
|
||||||
GLOBAL_ENV, /* global namespace */
|
OBJ_GLOBAL, /* global namespace */
|
||||||
|
|
||||||
/* Quotation compilation in quotations.c */
|
/* Quotation compilation in quotations.c */
|
||||||
JIT_PROLOG = 23,
|
JIT_PROLOG = 23,
|
||||||
|
@ -79,25 +79,25 @@ enum special_object {
|
||||||
MEGA_LOOKUP_WORD,
|
MEGA_LOOKUP_WORD,
|
||||||
MEGA_MISS_WORD,
|
MEGA_MISS_WORD,
|
||||||
|
|
||||||
UNDEFINED_ENV = 60, /* default quotation for undefined words */
|
OBJ_UNDEFINED = 60, /* default quotation for undefined words */
|
||||||
|
|
||||||
STDERR_ENV = 61, /* stderr FILE* handle */
|
OBJ_STDERR = 61, /* stderr FILE* handle */
|
||||||
|
|
||||||
STAGE2_ENV = 62, /* have we bootstrapped? */
|
OBJ_STAGE2 = 62, /* have we bootstrapped? */
|
||||||
|
|
||||||
CURRENT_THREAD_ENV = 63,
|
OBJ_CURRENT_THREAD = 63,
|
||||||
|
|
||||||
THREADS_ENV = 64,
|
OBJ_THREADS = 64,
|
||||||
RUN_QUEUE_ENV = 65,
|
OBJ_RUN_QUEUE = 65,
|
||||||
SLEEP_QUEUE_ENV = 66,
|
OBJ_SLEEP_QUEUE = 66,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FIRST_SAVE_ENV BOOT_ENV
|
#define OBJ_FIRST_SAVE OBJ_BOOT
|
||||||
#define LAST_SAVE_ENV STAGE2_ENV
|
#define OBJ_LAST_SAVE OBJ_STAGE2
|
||||||
|
|
||||||
inline static bool save_env_p(cell i)
|
inline static bool save_env_p(cell i)
|
||||||
{
|
{
|
||||||
return (i >= FIRST_SAVE_ENV && i <= LAST_SAVE_ENV);
|
return (i >= OBJ_FIRST_SAVE && i <= OBJ_LAST_SAVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct factor_vm
|
||||||
cell decks_offset;
|
cell decks_offset;
|
||||||
|
|
||||||
/* TAGGED user environment data; see getenv/setenv prims */
|
/* TAGGED user environment data; see getenv/setenv prims */
|
||||||
cell userenv[USER_ENV];
|
cell special_objects[special_object_count];
|
||||||
|
|
||||||
/* Data stack and retain stack sizes */
|
/* Data stack and retain stack sizes */
|
||||||
cell ds_size, rs_size;
|
cell ds_size, rs_size;
|
||||||
|
|
|
@ -13,7 +13,7 @@ word *factor_vm::allot_word(cell name_, cell vocab_, cell hashcode_)
|
||||||
new_word->hashcode = hashcode_;
|
new_word->hashcode = hashcode_;
|
||||||
new_word->vocabulary = vocab.value();
|
new_word->vocabulary = vocab.value();
|
||||||
new_word->name = name.value();
|
new_word->name = name.value();
|
||||||
new_word->def = userenv[UNDEFINED_ENV];
|
new_word->def = special_objects[OBJ_UNDEFINED];
|
||||||
new_word->props = false_object;
|
new_word->props = false_object;
|
||||||
new_word->counter = tag_fixnum(0);
|
new_word->counter = tag_fixnum(0);
|
||||||
new_word->pic_def = false_object;
|
new_word->pic_def = false_object;
|
||||||
|
|
Loading…
Reference in New Issue