vm: use iostreams instead of printf for debug messages, clean up a few things
parent
af855b7fa9
commit
40351d40be
|
@ -286,7 +286,7 @@ struct literal_references_updater {
|
||||||
if(parent->relocation_type_of(rel) == RT_IMMEDIATE)
|
if(parent->relocation_type_of(rel) == RT_IMMEDIATE)
|
||||||
{
|
{
|
||||||
cell offset = parent->relocation_offset_of(rel) + (cell)(compiled + 1);
|
cell offset = parent->relocation_offset_of(rel) + (cell)(compiled + 1);
|
||||||
array *literals = parent->untag<array>(compiled->literals);
|
array *literals = untag<array>(compiled->literals);
|
||||||
fixnum absolute_value = array_nth(literals,index);
|
fixnum absolute_value = array_nth(literals,index);
|
||||||
parent->store_address_in_code_block(parent->relocation_class_of(rel),offset,absolute_value);
|
parent->store_address_in_code_block(parent->relocation_class_of(rel),offset,absolute_value);
|
||||||
}
|
}
|
||||||
|
@ -457,10 +457,10 @@ code_block *factor_vm::allot_code_block(cell size, code_block_type type)
|
||||||
cell used, total_free, max_free;
|
cell used, total_free, max_free;
|
||||||
code->allocator->usage(&used,&total_free,&max_free);
|
code->allocator->usage(&used,&total_free,&max_free);
|
||||||
|
|
||||||
print_string("Code heap stats:\n");
|
std::cout << "Code heap stats:\n";
|
||||||
print_string("Used: "); print_cell(used); nl();
|
std::cout << "Used: " << used << "\n";
|
||||||
print_string("Total free space: "); print_cell(total_free); nl();
|
std::cout << "Total free space: " << total_free << "\n";
|
||||||
print_string("Largest free block: "); print_cell(max_free); nl();
|
std::cout << "Largest free block: " << max_free << "\n";
|
||||||
fatal_error("Out of memory in add-compiled-block",0);
|
fatal_error("Out of memory in add-compiled-block",0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
|
||||||
|
|
||||||
if(immediate_p(pointer)) return;
|
if(immediate_p(pointer)) return;
|
||||||
|
|
||||||
object *untagged = parent->untag<object>(pointer);
|
object *untagged = untag<object>(pointer);
|
||||||
if(!policy.should_copy_p(untagged))
|
if(!policy.should_copy_p(untagged))
|
||||||
{
|
{
|
||||||
policy.visited_object(untagged);
|
policy.visited_object(untagged);
|
||||||
|
|
|
@ -120,7 +120,7 @@ cell factor_vm::object_size(cell tagged)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Size of the object pointed to by an untagged pointer */
|
/* Size of the object pointed to by an untagged pointer */
|
||||||
cell object::size()
|
cell object::size() const
|
||||||
{
|
{
|
||||||
if(free_p()) return ((free_heap_block *)this)->size();
|
if(free_p()) return ((free_heap_block *)this)->size();
|
||||||
|
|
||||||
|
|
208
vm/debug.cpp
208
vm/debug.cpp
|
@ -3,36 +3,31 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
void factor_vm::print_chars(string* str)
|
std::ostream &operator<<(std::ostream &out, const string *str)
|
||||||
{
|
{
|
||||||
cell i;
|
for(cell i = 0; i < string_capacity(str); i++)
|
||||||
for(i = 0; i < string_capacity(str); i++)
|
out << (char)str->nth(i);
|
||||||
putchar(string_nth(str,i));
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::print_word(word* word, cell nesting)
|
void factor_vm::print_word(word* word, cell nesting)
|
||||||
{
|
{
|
||||||
if(tagged<object>(word->vocabulary).type_p(STRING_TYPE))
|
if(tagged<object>(word->vocabulary).type_p(STRING_TYPE))
|
||||||
{
|
std::cout << untag<string>(word->vocabulary) << ":";
|
||||||
print_chars(untag<string>(word->vocabulary));
|
|
||||||
print_string(":");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tagged<object>(word->name).type_p(STRING_TYPE))
|
if(tagged<object>(word->name).type_p(STRING_TYPE))
|
||||||
print_chars(untag<string>(word->name));
|
std::cout << untag<string>(word->name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
print_string("#<not a string: ");
|
std::cout << "#<not a string: ";
|
||||||
print_nested_obj(word->name,nesting);
|
print_nested_obj(word->name,nesting);
|
||||||
print_string(">");
|
std::cout << ">";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::print_factor_string(string* str)
|
void factor_vm::print_factor_string(string *str)
|
||||||
{
|
{
|
||||||
putchar('"');
|
std::cout << '"' << str << '"';
|
||||||
print_chars(str);
|
|
||||||
putchar('"');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::print_array(array* array, cell nesting)
|
void factor_vm::print_array(array* array, cell nesting)
|
||||||
|
@ -51,12 +46,12 @@ void factor_vm::print_array(array* array, cell nesting)
|
||||||
|
|
||||||
for(i = 0; i < length; i++)
|
for(i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
print_string(" ");
|
std::cout << " ";
|
||||||
print_nested_obj(array_nth(array,i),nesting);
|
print_nested_obj(array_nth(array,i),nesting);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(trimmed)
|
if(trimmed)
|
||||||
print_string("...");
|
std::cout << "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::print_tuple(tuple *tuple, cell nesting)
|
void factor_vm::print_tuple(tuple *tuple, cell nesting)
|
||||||
|
@ -64,12 +59,10 @@ void factor_vm::print_tuple(tuple *tuple, cell nesting)
|
||||||
tuple_layout *layout = untag<tuple_layout>(tuple->layout);
|
tuple_layout *layout = untag<tuple_layout>(tuple->layout);
|
||||||
cell length = to_fixnum(layout->size);
|
cell length = to_fixnum(layout->size);
|
||||||
|
|
||||||
print_string(" ");
|
std::cout << " ";
|
||||||
print_nested_obj(layout->klass,nesting);
|
print_nested_obj(layout->klass,nesting);
|
||||||
|
|
||||||
cell i;
|
|
||||||
bool trimmed;
|
bool trimmed;
|
||||||
|
|
||||||
if(length > 10 && !full_output)
|
if(length > 10 && !full_output)
|
||||||
{
|
{
|
||||||
trimmed = true;
|
trimmed = true;
|
||||||
|
@ -78,21 +71,21 @@ void factor_vm::print_tuple(tuple *tuple, cell nesting)
|
||||||
else
|
else
|
||||||
trimmed = false;
|
trimmed = false;
|
||||||
|
|
||||||
for(i = 0; i < length; i++)
|
for(cell i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
print_string(" ");
|
std::cout << " ";
|
||||||
print_nested_obj(tuple->data()[i],nesting);
|
print_nested_obj(tuple->data()[i],nesting);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(trimmed)
|
if(trimmed)
|
||||||
print_string("...");
|
std::cout << "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::print_nested_obj(cell obj, fixnum nesting)
|
void factor_vm::print_nested_obj(cell obj, fixnum nesting)
|
||||||
{
|
{
|
||||||
if(nesting <= 0 && !full_output)
|
if(nesting <= 0 && !full_output)
|
||||||
{
|
{
|
||||||
print_string(" ... ");
|
std::cout << " ... ";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +94,7 @@ void factor_vm::print_nested_obj(cell obj, fixnum nesting)
|
||||||
switch(tagged<object>(obj).type())
|
switch(tagged<object>(obj).type())
|
||||||
{
|
{
|
||||||
case FIXNUM_TYPE:
|
case FIXNUM_TYPE:
|
||||||
print_fixnum(untag_fixnum(obj));
|
std::cout << untag_fixnum(obj);
|
||||||
break;
|
break;
|
||||||
case WORD_TYPE:
|
case WORD_TYPE:
|
||||||
print_word(untag<word>(obj),nesting - 1);
|
print_word(untag<word>(obj),nesting - 1);
|
||||||
|
@ -110,30 +103,27 @@ void factor_vm::print_nested_obj(cell obj, fixnum nesting)
|
||||||
print_factor_string(untag<string>(obj));
|
print_factor_string(untag<string>(obj));
|
||||||
break;
|
break;
|
||||||
case F_TYPE:
|
case F_TYPE:
|
||||||
print_string("f");
|
std::cout << "f";
|
||||||
break;
|
break;
|
||||||
case TUPLE_TYPE:
|
case TUPLE_TYPE:
|
||||||
print_string("T{");
|
std::cout << "T{";
|
||||||
print_tuple(untag<tuple>(obj),nesting - 1);
|
print_tuple(untag<tuple>(obj),nesting - 1);
|
||||||
print_string(" }");
|
std::cout << " }";
|
||||||
break;
|
break;
|
||||||
case ARRAY_TYPE:
|
case ARRAY_TYPE:
|
||||||
print_string("{");
|
std::cout << "{";
|
||||||
print_array(untag<array>(obj),nesting - 1);
|
print_array(untag<array>(obj),nesting - 1);
|
||||||
print_string(" }");
|
std::cout << " }";
|
||||||
break;
|
break;
|
||||||
case QUOTATION_TYPE:
|
case QUOTATION_TYPE:
|
||||||
print_string("[");
|
std::cout << "[";
|
||||||
quot = untag<quotation>(obj);
|
quot = untag<quotation>(obj);
|
||||||
print_array(untag<array>(quot->array),nesting - 1);
|
print_array(untag<array>(quot->array),nesting - 1);
|
||||||
print_string(" ]");
|
std::cout << " ]";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
print_string("#<type ");
|
std::cout << "#<type " << tagged<object>(obj).type() << " @ ";
|
||||||
print_cell(tagged<object>(obj).type());
|
std::cout << std::hex << obj << std::dec << ">";
|
||||||
print_string(" @ ");
|
|
||||||
print_cell_hex(obj);
|
|
||||||
print_string(">");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,19 +138,19 @@ void factor_vm::print_objects(cell *start, cell *end)
|
||||||
for(; start <= end; start++)
|
for(; start <= end; start++)
|
||||||
{
|
{
|
||||||
print_obj(*start);
|
print_obj(*start);
|
||||||
nl();
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::print_datastack()
|
void factor_vm::print_datastack()
|
||||||
{
|
{
|
||||||
print_string("==== DATA STACK:\n");
|
std::cout << "==== DATA STACK:\n";
|
||||||
print_objects((cell *)ds_bot,(cell *)ds);
|
print_objects((cell *)ds_bot,(cell *)ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::print_retainstack()
|
void factor_vm::print_retainstack()
|
||||||
{
|
{
|
||||||
print_string("==== RETAIN STACK:\n");
|
std::cout << "==== RETAIN STACK:\n";
|
||||||
print_objects((cell *)rs_bot,(cell *)rs);
|
print_objects((cell *)rs_bot,(cell *)rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,34 +161,48 @@ struct stack_frame_printer {
|
||||||
void operator()(stack_frame *frame)
|
void operator()(stack_frame *frame)
|
||||||
{
|
{
|
||||||
parent->print_obj(parent->frame_executing(frame));
|
parent->print_obj(parent->frame_executing(frame));
|
||||||
print_string("\n");
|
std::cout << std::endl;
|
||||||
parent->print_obj(parent->frame_scan(frame));
|
parent->print_obj(parent->frame_scan(frame));
|
||||||
print_string("\n");
|
std::cout << std::endl;
|
||||||
print_string("word/quot addr: ");
|
std::cout << "word/quot addr: ";
|
||||||
print_cell_hex((cell)parent->frame_executing(frame));
|
std::cout << std::hex << (cell)parent->frame_executing(frame) << std::dec;
|
||||||
print_string("\n");
|
std::cout << std::endl;
|
||||||
print_string("word/quot xt: ");
|
std::cout << "word/quot xt: ";
|
||||||
print_cell_hex((cell)frame->xt);
|
std::cout << std::hex << (cell)frame->xt << std::dec;
|
||||||
print_string("\n");
|
std::cout << std::endl;
|
||||||
print_string("return address: ");
|
std::cout << "return address: ";
|
||||||
print_cell_hex((cell)FRAME_RETURN_ADDRESS(frame,parent));
|
std::cout << std::hex << (cell)FRAME_RETURN_ADDRESS(frame,parent) << std::dec;
|
||||||
print_string("\n");
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void factor_vm::print_callstack()
|
void factor_vm::print_callstack()
|
||||||
{
|
{
|
||||||
print_string("==== CALL STACK:\n");
|
std::cout << "==== CALL STACK:\n";
|
||||||
stack_frame_printer printer(this);
|
stack_frame_printer printer(this);
|
||||||
iterate_callstack(ctx,printer);
|
iterate_callstack(ctx,printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct padded_address {
|
||||||
|
cell value;
|
||||||
|
|
||||||
|
explicit padded_address(cell value_) : value(value_) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const padded_address &value)
|
||||||
|
{
|
||||||
|
char prev = out.fill('0');
|
||||||
|
out.width(sizeof(cell) * 2);
|
||||||
|
out << std::hex << value.value << std::dec;
|
||||||
|
out.fill(prev);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
void factor_vm::dump_cell(cell x)
|
void factor_vm::dump_cell(cell x)
|
||||||
{
|
{
|
||||||
print_cell_hex_pad(x); print_string(": ");
|
std::cout << padded_address(x) << ": ";
|
||||||
x = *(cell *)x;
|
x = *(cell *)x;
|
||||||
print_cell_hex_pad(x); print_string(" tag "); print_cell(TAG(x));
|
std::cout << padded_address(x) << " tag " << TAG(x) << std::endl;
|
||||||
nl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::dump_memory(cell from, cell to)
|
void factor_vm::dump_memory(cell from, cell to)
|
||||||
|
@ -212,11 +216,11 @@ void factor_vm::dump_memory(cell from, cell to)
|
||||||
template<typename Generation>
|
template<typename Generation>
|
||||||
void factor_vm::dump_generation(const char *name, Generation *gen)
|
void factor_vm::dump_generation(const char *name, Generation *gen)
|
||||||
{
|
{
|
||||||
print_string(name); print_string(": ");
|
std::cout << name << ": ";
|
||||||
print_string("Start="); print_cell(gen->start);
|
std::cout << "Start=" << gen->start;
|
||||||
print_string(", size="); print_cell(gen->size);
|
std::cout << ", size=" << gen->size;
|
||||||
print_string(", end="); print_cell(gen->end);
|
std::cout << ", end=" << gen->end;
|
||||||
nl();
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::dump_generations()
|
void factor_vm::dump_generations()
|
||||||
|
@ -225,11 +229,9 @@ void factor_vm::dump_generations()
|
||||||
dump_generation("Aging",data->aging);
|
dump_generation("Aging",data->aging);
|
||||||
dump_generation("Tenured",data->tenured);
|
dump_generation("Tenured",data->tenured);
|
||||||
|
|
||||||
print_string("Cards: base=");
|
std::cout << "Cards:";
|
||||||
print_cell((cell)data->cards);
|
std::cout << "base=" << (cell)data->cards << ", ";
|
||||||
print_string(", size=");
|
std::cout << "size=" << (cell)(data->cards_end - data->cards) << std::endl;
|
||||||
print_cell((cell)(data->cards_end - data->cards));
|
|
||||||
nl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::dump_objects(cell type)
|
void factor_vm::dump_objects(cell type)
|
||||||
|
@ -242,10 +244,9 @@ void factor_vm::dump_objects(cell type)
|
||||||
{
|
{
|
||||||
if(type == TYPE_COUNT || tagged<object>(obj).type_p(type))
|
if(type == TYPE_COUNT || tagged<object>(obj).type_p(type))
|
||||||
{
|
{
|
||||||
print_cell_hex_pad(obj);
|
std::cout << padded_address(obj) << " ";
|
||||||
print_string(" ");
|
|
||||||
print_nested_obj(obj,2);
|
print_nested_obj(obj,2);
|
||||||
nl();
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,10 +264,9 @@ struct data_references_finder {
|
||||||
{
|
{
|
||||||
if(look_for == *scan)
|
if(look_for == *scan)
|
||||||
{
|
{
|
||||||
print_cell_hex_pad(obj);
|
std::cout << padded_address(obj) << " ";
|
||||||
print_string(" ");
|
|
||||||
parent->print_nested_obj(obj,2);
|
parent->print_nested_obj(obj,2);
|
||||||
nl();
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -311,9 +311,9 @@ struct code_block_printer {
|
||||||
status = "allocated";
|
status = "allocated";
|
||||||
}
|
}
|
||||||
|
|
||||||
print_cell_hex((cell)scan); print_string(" ");
|
std::cout << std::hex << (cell)scan << std::dec << " ";
|
||||||
print_cell_hex(size); print_string(" ");
|
std::cout << std::hex << size << std::dec << " ";
|
||||||
print_string(status); print_string("\n");
|
std::cout << status << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -322,40 +322,40 @@ void factor_vm::dump_code_heap()
|
||||||
{
|
{
|
||||||
code_block_printer printer(this);
|
code_block_printer printer(this);
|
||||||
code->allocator->iterate(printer);
|
code->allocator->iterate(printer);
|
||||||
print_cell(printer.reloc_size); print_string(" bytes of relocation data\n");
|
std::cout << printer.reloc_size << " bytes of relocation data\n";
|
||||||
print_cell(printer.literal_size); print_string(" bytes of literal data\n");
|
std::cout << printer.literal_size << " bytes of literal data\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::factorbug()
|
void factor_vm::factorbug()
|
||||||
{
|
{
|
||||||
if(fep_disabled)
|
if(fep_disabled)
|
||||||
{
|
{
|
||||||
print_string("Low level debugger disabled\n");
|
std::cout << "Low level debugger disabled\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open_console(); */
|
/* open_console(); */
|
||||||
|
|
||||||
print_string("Starting low level debugger...\n");
|
std::cout << "Starting low level debugger...\n";
|
||||||
print_string(" Basic commands:\n");
|
std::cout << " Basic commands:\n";
|
||||||
print_string("q -- continue executing Factor - NOT SAFE\n");
|
std::cout << "q -- continue executing Factor - NOT SAFE\n";
|
||||||
print_string("im -- save image to fep.image\n");
|
std::cout << "im -- save image to fep.image\n";
|
||||||
print_string("x -- exit Factor\n");
|
std::cout << "x -- exit Factor\n";
|
||||||
print_string(" Advanced commands:\n");
|
std::cout << " Advanced commands:\n";
|
||||||
print_string("d <addr> <count> -- dump memory\n");
|
std::cout << "d <addr> <count> -- dump memory\n";
|
||||||
print_string("u <addr> -- dump object at tagged <addr>\n");
|
std::cout << "u <addr> -- dump object at tagged <addr>\n";
|
||||||
print_string(". <addr> -- print object at tagged <addr>\n");
|
std::cout << ". <addr> -- print object at tagged <addr>\n";
|
||||||
print_string("t -- toggle output trimming\n");
|
std::cout << "t -- toggle output trimming\n";
|
||||||
print_string("s r -- dump data, retain stacks\n");
|
std::cout << "s r -- dump data, retain stacks\n";
|
||||||
print_string(".s .r .c -- print data, retain, call stacks\n");
|
std::cout << ".s .r .c -- print data, retain, call stacks\n";
|
||||||
print_string("e -- dump environment\n");
|
std::cout << "e -- dump environment\n";
|
||||||
print_string("g -- dump generations\n");
|
std::cout << "g -- dump generations\n";
|
||||||
print_string("data -- data heap dump\n");
|
std::cout << "data -- data heap dump\n";
|
||||||
print_string("words -- words dump\n");
|
std::cout << "words -- words dump\n";
|
||||||
print_string("tuples -- tuples dump\n");
|
std::cout << "tuples -- tuples dump\n";
|
||||||
print_string("refs <addr> -- find data heap references to object\n");
|
std::cout << "refs <addr> -- find data heap references to object\n";
|
||||||
print_string("push <addr> -- push object on data stack - NOT SAFE\n");
|
std::cout << "push <addr> -- push object on data stack - NOT SAFE\n";
|
||||||
print_string("code -- code heap dump\n");
|
std::cout << "code -- code heap dump\n";
|
||||||
|
|
||||||
bool seen_command = false;
|
bool seen_command = false;
|
||||||
|
|
||||||
|
@ -363,7 +363,7 @@ void factor_vm::factorbug()
|
||||||
{
|
{
|
||||||
char cmd[1024];
|
char cmd[1024];
|
||||||
|
|
||||||
print_string("READY\n");
|
std::cout << "READY\n";
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
if(scanf("%1000s",cmd) <= 0)
|
if(scanf("%1000s",cmd) <= 0)
|
||||||
|
@ -403,7 +403,7 @@ void factor_vm::factorbug()
|
||||||
{
|
{
|
||||||
cell addr = read_cell_hex();
|
cell addr = read_cell_hex();
|
||||||
print_obj(addr);
|
print_obj(addr);
|
||||||
print_string("\n");
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
else if(strcmp(cmd,"t") == 0)
|
else if(strcmp(cmd,"t") == 0)
|
||||||
full_output = !full_output;
|
full_output = !full_output;
|
||||||
|
@ -436,9 +436,9 @@ void factor_vm::factorbug()
|
||||||
else if(strcmp(cmd,"refs") == 0)
|
else if(strcmp(cmd,"refs") == 0)
|
||||||
{
|
{
|
||||||
cell addr = read_cell_hex();
|
cell addr = read_cell_hex();
|
||||||
print_string("Data heap references:\n");
|
std::cout << "Data heap references:\n";
|
||||||
find_data_references(addr);
|
find_data_references(addr);
|
||||||
nl();
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
else if(strcmp(cmd,"words") == 0)
|
else if(strcmp(cmd,"words") == 0)
|
||||||
dump_objects(WORD_TYPE);
|
dump_objects(WORD_TYPE);
|
||||||
|
@ -452,14 +452,14 @@ void factor_vm::factorbug()
|
||||||
else if(strcmp(cmd,"code") == 0)
|
else if(strcmp(cmd,"code") == 0)
|
||||||
dump_code_heap();
|
dump_code_heap();
|
||||||
else
|
else
|
||||||
print_string("unknown command\n");
|
std::cout << "unknown command\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_die()
|
void factor_vm::primitive_die()
|
||||||
{
|
{
|
||||||
print_string("The die word was called by the library. Unless you called it yourself,\n");
|
std::cout << "The die word was called by the library. Unless you called it yourself,\n";
|
||||||
print_string("you have triggered a bug in Factor. Please report.\n");
|
std::cout << "you have triggered a bug in Factor. Please report.\n";
|
||||||
factorbug();
|
factorbug();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,22 +5,24 @@ namespace factor
|
||||||
|
|
||||||
void fatal_error(const char *msg, cell tagged)
|
void fatal_error(const char *msg, cell tagged)
|
||||||
{
|
{
|
||||||
print_string("fatal_error: "); print_string(msg);
|
std::cout << "fatal_error: " << msg;
|
||||||
print_string(": "); print_cell_hex(tagged); nl();
|
std::cout << ": " << std::hex << tagged << std::dec;
|
||||||
|
std::cout << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void critical_error(const char *msg, cell tagged)
|
void critical_error(const char *msg, cell tagged)
|
||||||
{
|
{
|
||||||
print_string("You have triggered a bug in Factor. Please report.\n");
|
std::cout << "You have triggered a bug in Factor. Please report.\n";
|
||||||
print_string("critical_error: "); print_string(msg);
|
std::cout << "critical_error: " << msg;
|
||||||
print_string(": "); print_cell_hex(tagged); nl();
|
std::cout << ": " << std::hex << tagged << std::dec;
|
||||||
|
std::cout << std::endl;
|
||||||
tls_vm()->factorbug();
|
tls_vm()->factorbug();
|
||||||
}
|
}
|
||||||
|
|
||||||
void out_of_memory()
|
void out_of_memory()
|
||||||
{
|
{
|
||||||
print_string("Out of memory\n\n");
|
std::cout << "Out of memory\n\n";
|
||||||
tls_vm()->dump_generations();
|
tls_vm()->dump_generations();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -59,10 +61,10 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
|
||||||
crash. */
|
crash. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
print_string("You have triggered a bug in Factor. Please report.\n");
|
std::cout << "You have triggered a bug in Factor. Please report.\n";
|
||||||
print_string("early_error: ");
|
std::cout << "early_error: ";
|
||||||
print_obj(error);
|
print_obj(error);
|
||||||
nl();
|
std::cout << std::endl;
|
||||||
factorbug();
|
factorbug();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ void factor_vm::default_parameters(vm_parameters *p)
|
||||||
p->max_pic_size = 3;
|
p->max_pic_size = 3;
|
||||||
|
|
||||||
p->fep = false;
|
p->fep = false;
|
||||||
|
p->verbosegc = false;
|
||||||
p->signals = true;
|
p->signals = true;
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
@ -86,6 +87,7 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char **
|
||||||
else if(factor_arg(arg,STRING_LITERAL("-callbacks=%d"),&p->callback_size));
|
else if(factor_arg(arg,STRING_LITERAL("-callbacks=%d"),&p->callback_size));
|
||||||
else if(STRCMP(arg,STRING_LITERAL("-fep")) == 0) p->fep = true;
|
else if(STRCMP(arg,STRING_LITERAL("-fep")) == 0) p->fep = true;
|
||||||
else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false;
|
else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false;
|
||||||
|
else if(STRCMP(arg,STRING_LITERAL("-verbosegc")) == 0) p->verbosegc = true;
|
||||||
else if(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3;
|
else if(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3;
|
||||||
else if(STRCMP(arg,STRING_LITERAL("-console")) == 0) p->console = true;
|
else if(STRCMP(arg,STRING_LITERAL("-console")) == 0) p->console = true;
|
||||||
}
|
}
|
||||||
|
@ -94,14 +96,13 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char **
|
||||||
/* Do some initialization that we do once only */
|
/* Do some initialization that we do once only */
|
||||||
void factor_vm::do_stage1_init()
|
void factor_vm::do_stage1_init()
|
||||||
{
|
{
|
||||||
print_string("*** Stage 2 early init... ");
|
std::cout << "*** Stage 2 early init... ";
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
compile_all_words();
|
compile_all_words();
|
||||||
userenv[STAGE2_ENV] = true_object;
|
userenv[STAGE2_ENV] = true_object;
|
||||||
|
|
||||||
print_string("done\n");
|
std::cout << "done\n";
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::init_factor(vm_parameters *p)
|
void factor_vm::init_factor(vm_parameters *p)
|
||||||
|
@ -141,6 +142,8 @@ void factor_vm::init_factor(vm_parameters *p)
|
||||||
if(p->signals)
|
if(p->signals)
|
||||||
init_signals();
|
init_signals();
|
||||||
|
|
||||||
|
verbosegc = p->verbosegc;
|
||||||
|
|
||||||
if(p->console)
|
if(p->console)
|
||||||
open_console();
|
open_console();
|
||||||
|
|
||||||
|
|
11
vm/gc.cpp
11
vm/gc.cpp
|
@ -37,6 +37,9 @@ void factor_vm::gc(gc_op op,
|
||||||
|
|
||||||
current_gc = new gc_state(op);
|
current_gc = new gc_state(op);
|
||||||
|
|
||||||
|
if(verbosegc)
|
||||||
|
std::cout << "GC requested, op=" << op << std::endl;
|
||||||
|
|
||||||
/* Keep trying to GC higher and higher generations until we don't run out
|
/* Keep trying to GC higher and higher generations until we don't run out
|
||||||
of space */
|
of space */
|
||||||
if(setjmp(current_gc->gc_unwind))
|
if(setjmp(current_gc->gc_unwind))
|
||||||
|
@ -60,6 +63,9 @@ void factor_vm::gc(gc_op op,
|
||||||
critical_error("Bad GC op\n",op);
|
critical_error("Bad GC op\n",op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(verbosegc)
|
||||||
|
std::cout << "GC rewind, op=" << op << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(current_gc->op)
|
switch(current_gc->op)
|
||||||
|
@ -91,11 +97,14 @@ void factor_vm::gc(gc_op op,
|
||||||
|
|
||||||
delete current_gc;
|
delete current_gc;
|
||||||
current_gc = NULL;
|
current_gc = NULL;
|
||||||
|
|
||||||
|
if(verbosegc)
|
||||||
|
std::cout << "GC done, op=" << op << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_minor_gc()
|
void factor_vm::primitive_minor_gc()
|
||||||
{
|
{
|
||||||
gc(collect_nursery_op,
|
gc(collect_full_op,
|
||||||
0, /* requested size */
|
0, /* requested size */
|
||||||
true, /* trace contexts? */
|
true, /* trace contexts? */
|
||||||
false /* compact code heap? */);
|
false /* compact code heap? */);
|
||||||
|
|
26
vm/image.cpp
26
vm/image.cpp
|
@ -31,11 +31,8 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
|
||||||
|
|
||||||
if((cell)bytes_read != h->data_size)
|
if((cell)bytes_read != h->data_size)
|
||||||
{
|
{
|
||||||
print_string("truncated image: ");
|
std::cout << "truncated image: " << bytes_read << " bytes read, ";
|
||||||
print_fixnum(bytes_read);
|
std::cout << h->data_size << " bytes expected\n";
|
||||||
print_string(" bytes read, ");
|
|
||||||
print_cell(h->data_size);
|
|
||||||
print_string(" bytes expected\n");
|
|
||||||
fatal_error("load_data_heap failed",0);
|
fatal_error("load_data_heap failed",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,11 +51,8 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p)
|
||||||
size_t bytes_read = fread(code->allocator->first_block(),1,h->code_size,file);
|
size_t bytes_read = fread(code->allocator->first_block(),1,h->code_size,file);
|
||||||
if(bytes_read != h->code_size)
|
if(bytes_read != h->code_size)
|
||||||
{
|
{
|
||||||
print_string("truncated image: ");
|
std::cout << "truncated image: " << bytes_read << " bytes read, ";
|
||||||
print_fixnum(bytes_read);
|
std::cout << h->code_size << " bytes expected\n";
|
||||||
print_string(" bytes read, ");
|
|
||||||
print_cell(h->code_size);
|
|
||||||
print_string(" bytes expected\n");
|
|
||||||
fatal_error("load_code_heap failed",0);
|
fatal_error("load_code_heap failed",0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,8 +237,8 @@ void factor_vm::load_image(vm_parameters *p)
|
||||||
FILE *file = OPEN_READ(p->image_path);
|
FILE *file = OPEN_READ(p->image_path);
|
||||||
if(file == NULL)
|
if(file == NULL)
|
||||||
{
|
{
|
||||||
print_string("Cannot open image file: "); print_native_string(p->image_path); nl();
|
std::cout << "Cannot open image file: " << p->image_path << std::endl;
|
||||||
print_string(strerror(errno)); nl();
|
std::cout << strerror(errno) << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,8 +275,8 @@ bool factor_vm::save_image(const vm_char *filename)
|
||||||
file = OPEN_WRITE(filename);
|
file = OPEN_WRITE(filename);
|
||||||
if(file == NULL)
|
if(file == NULL)
|
||||||
{
|
{
|
||||||
print_string("Cannot open image file: "); print_native_string(filename); nl();
|
std::cout << "Cannot open image file: " << filename << std::endl;
|
||||||
print_string(strerror(errno)); nl();
|
std::cout << strerror(errno) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,9 +303,7 @@ bool factor_vm::save_image(const vm_char *filename)
|
||||||
if(fclose(file)) ok = false;
|
if(fclose(file)) ok = false;
|
||||||
|
|
||||||
if(!ok)
|
if(!ok)
|
||||||
{
|
std::cout << "save-image failed: " << strerror(errno) << std::endl;
|
||||||
print_string("save-image failed: "); print_string(strerror(errno)); nl();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct vm_parameters {
|
||||||
cell young_size, aging_size, tenured_size;
|
cell young_size, aging_size, tenured_size;
|
||||||
cell code_size;
|
cell code_size;
|
||||||
bool fep;
|
bool fep;
|
||||||
|
bool verbosegc;
|
||||||
bool console;
|
bool console;
|
||||||
bool signals;
|
bool signals;
|
||||||
cell max_pic_size;
|
cell max_pic_size;
|
||||||
|
|
|
@ -233,10 +233,10 @@ void *factor_vm::inline_cache_miss(cell return_address)
|
||||||
set_call_target(return_address,xt);
|
set_call_target(return_address,xt);
|
||||||
|
|
||||||
#ifdef PIC_DEBUG
|
#ifdef PIC_DEBUG
|
||||||
printf("Updated %s call site 0x%lx with 0x%lx\n",
|
std::cout << "Updated "
|
||||||
tail_call_site_p(return_address) ? "tail" : "non-tail",
|
<< (tail_call_site_p(return_address) ? "tail" : "non-tail")
|
||||||
return_address,
|
<< " call site 0x" << std::hex << return_address << std::dec
|
||||||
(cell)xt);
|
<< " with " << std::hex << (cell)xt << std::dec;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return xt;
|
return xt;
|
||||||
|
|
|
@ -43,7 +43,7 @@ struct jit {
|
||||||
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(parent->untag<array>(array_nth(code_pair.untagged(),0)));
|
literals.append(untag<array>(array_nth(code_pair.untagged(),0)));
|
||||||
emit(array_nth(code_pair.untagged(),1));
|
emit(array_nth(code_pair.untagged(),1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,25 +112,25 @@ struct header {
|
||||||
|
|
||||||
explicit header(cell value_) : value(value_ << TAG_BITS) {}
|
explicit header(cell value_) : value(value_ << TAG_BITS) {}
|
||||||
|
|
||||||
void check_header()
|
void check_header() const
|
||||||
{
|
{
|
||||||
#ifdef FACTOR_DEBUG
|
#ifdef FACTOR_DEBUG
|
||||||
assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT);
|
assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
cell hi_tag()
|
cell hi_tag() const
|
||||||
{
|
{
|
||||||
check_header();
|
check_header();
|
||||||
return value >> TAG_BITS;
|
return value >> TAG_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool forwarding_pointer_p()
|
bool forwarding_pointer_p() const
|
||||||
{
|
{
|
||||||
return TAG(value) == GC_COLLECTED;
|
return TAG(value) == GC_COLLECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
object *forwarding_pointer()
|
object *forwarding_pointer() const
|
||||||
{
|
{
|
||||||
return (object *)UNTAG(value);
|
return (object *)UNTAG(value);
|
||||||
}
|
}
|
||||||
|
@ -147,13 +147,13 @@ struct object {
|
||||||
NO_TYPE_CHECK;
|
NO_TYPE_CHECK;
|
||||||
header h;
|
header h;
|
||||||
|
|
||||||
cell size();
|
cell size() const;
|
||||||
|
|
||||||
cell *slots() { return (cell *)this; }
|
cell *slots() const { return (cell *)this; }
|
||||||
|
|
||||||
/* Only valid for objects in tenured space; must fast to free_heap_block
|
/* Only valid for objects in tenured space; must fast to free_heap_block
|
||||||
to do anything with it if its free */
|
to do anything with it if its free */
|
||||||
bool free_p()
|
bool free_p() const
|
||||||
{
|
{
|
||||||
return h.value & 1 == 1;
|
return h.value & 1 == 1;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ struct array : public object {
|
||||||
/* tagged */
|
/* tagged */
|
||||||
cell capacity;
|
cell capacity;
|
||||||
|
|
||||||
cell *data() { return (cell *)(this + 1); }
|
cell *data() const { return (cell *)(this + 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These are really just arrays, but certain elements have special
|
/* These are really just arrays, but certain elements have special
|
||||||
|
@ -187,7 +187,7 @@ struct bignum : public object {
|
||||||
/* tagged */
|
/* tagged */
|
||||||
cell capacity;
|
cell capacity;
|
||||||
|
|
||||||
cell *data() { return (cell *)(this + 1); }
|
cell *data() const { return (cell *)(this + 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct byte_array : public object {
|
struct byte_array : public object {
|
||||||
|
@ -201,7 +201,7 @@ struct byte_array : public object {
|
||||||
cell padding1;
|
cell padding1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename Scalar> Scalar *data() { return (Scalar *)(this + 1); }
|
template<typename Scalar> Scalar *data() const { return (Scalar *)(this + 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Assembly code makes assumptions about the layout of this struct */
|
/* Assembly code makes assumptions about the layout of this struct */
|
||||||
|
@ -214,7 +214,9 @@ struct string : public object {
|
||||||
/* tagged */
|
/* tagged */
|
||||||
cell hashcode;
|
cell hashcode;
|
||||||
|
|
||||||
u8 *data() { return (u8 *)(this + 1); }
|
u8 *data() const { return (u8 *)(this + 1); }
|
||||||
|
|
||||||
|
cell nth(cell i) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The compiled code heap is structured into blocks. */
|
/* The compiled code heap is structured into blocks. */
|
||||||
|
@ -222,12 +224,12 @@ struct heap_block
|
||||||
{
|
{
|
||||||
cell header;
|
cell header;
|
||||||
|
|
||||||
bool free_p()
|
bool free_p() const
|
||||||
{
|
{
|
||||||
return header & 1 == 1;
|
return header & 1 == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell size()
|
cell size() const
|
||||||
{
|
{
|
||||||
cell bytes = header >> 3;
|
cell bytes = header >> 3;
|
||||||
#ifdef FACTOR_DEBUG
|
#ifdef FACTOR_DEBUG
|
||||||
|
@ -258,12 +260,12 @@ struct code_block : public heap_block
|
||||||
cell literals; /* tagged pointer to array or f */
|
cell literals; /* tagged pointer to array or f */
|
||||||
cell relocation; /* tagged pointer to byte-array or f */
|
cell relocation; /* tagged pointer to byte-array or f */
|
||||||
|
|
||||||
void *xt()
|
void *xt() const
|
||||||
{
|
{
|
||||||
return (void *)(this + 1);
|
return (void *)(this + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
code_block_type type()
|
code_block_type type() const
|
||||||
{
|
{
|
||||||
return (code_block_type)((header >> 1) & 0x3);
|
return (code_block_type)((header >> 1) & 0x3);
|
||||||
}
|
}
|
||||||
|
@ -273,12 +275,12 @@ struct code_block : public heap_block
|
||||||
header = ((header & ~0x7) | (type << 1));
|
header = ((header & ~0x7) | (type << 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pic_p()
|
bool pic_p() const
|
||||||
{
|
{
|
||||||
return type() == code_block_pic;
|
return type() == code_block_pic;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool optimized_p()
|
bool optimized_p() const
|
||||||
{
|
{
|
||||||
return type() == code_block_optimized;
|
return type() == code_block_optimized;
|
||||||
}
|
}
|
||||||
|
@ -376,13 +378,13 @@ struct callstack : public object {
|
||||||
/* tagged */
|
/* tagged */
|
||||||
cell length;
|
cell length;
|
||||||
|
|
||||||
stack_frame *frame_at(cell offset)
|
stack_frame *frame_at(cell offset) const
|
||||||
{
|
{
|
||||||
return (stack_frame *)((char *)(this + 1) + offset);
|
return (stack_frame *)((char *)(this + 1) + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_frame *top() { return (stack_frame *)(this + 1); }
|
stack_frame *top() const { return (stack_frame *)(this + 1); }
|
||||||
stack_frame *bottom() { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
|
stack_frame *bottom() const { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tuple : public object {
|
struct tuple : public object {
|
||||||
|
@ -390,7 +392,7 @@ struct tuple : public object {
|
||||||
/* tagged layout */
|
/* tagged layout */
|
||||||
cell layout;
|
cell layout;
|
||||||
|
|
||||||
cell *data() { return (cell *)(this + 1); }
|
cell *data() const { return (cell *)(this + 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
/* Forward-declare this since it comes up in function prototypes */
|
/* Forward-declare this since it comes up in function prototypes */
|
||||||
namespace factor
|
namespace factor
|
||||||
|
|
|
@ -37,8 +37,6 @@ typedef wchar_t vm_char;
|
||||||
#define OPEN_READ(path) _wfopen(path,L"rb")
|
#define OPEN_READ(path) _wfopen(path,L"rb")
|
||||||
#define OPEN_WRITE(path) _wfopen(path,L"wb")
|
#define OPEN_WRITE(path) _wfopen(path,L"wb")
|
||||||
|
|
||||||
#define print_native_string(string) wprintf(L"%s",string)
|
|
||||||
|
|
||||||
/* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
|
/* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
|
||||||
#define EPOCH_OFFSET 0x019db1ded53e8000LL
|
#define EPOCH_OFFSET 0x019db1ded53e8000LL
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ bool quotation_jit::stack_frame_p()
|
||||||
switch(tagged<object>(obj).type())
|
switch(tagged<object>(obj).type())
|
||||||
{
|
{
|
||||||
case WORD_TYPE:
|
case WORD_TYPE:
|
||||||
if(!parent->to_boolean(parent->untag<word>(obj)->subprimitive))
|
if(!parent->to_boolean(untag<word>(obj)->subprimitive))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case QUOTATION_TYPE:
|
case QUOTATION_TYPE:
|
||||||
|
@ -112,7 +112,7 @@ void quotation_jit::emit_quot(cell quot_)
|
||||||
{
|
{
|
||||||
gc_root<quotation> quot(quot_,parent);
|
gc_root<quotation> quot(quot_,parent);
|
||||||
|
|
||||||
array *elements = parent->untag<array>(quot->array);
|
array *elements = untag<array>(quot->array);
|
||||||
|
|
||||||
/* If the quotation consists of a single word, compile a direct call
|
/* If the quotation consists of a single word, compile a direct call
|
||||||
to the word. */
|
to the word. */
|
||||||
|
|
|
@ -3,20 +3,20 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
cell factor_vm::string_nth(string* str, cell index)
|
cell string::nth(cell index) const
|
||||||
{
|
{
|
||||||
/* If high bit is set, the most significant 16 bits of the char
|
/* If high bit is set, the most significant 16 bits of the char
|
||||||
come from the aux vector. The least significant bit of the
|
come from the aux vector. The least significant bit of the
|
||||||
corresponding aux vector entry is negated, so that we can
|
corresponding aux vector entry is negated, so that we can
|
||||||
XOR the two components together and get the original code point
|
XOR the two components together and get the original code point
|
||||||
back. */
|
back. */
|
||||||
cell lo_bits = str->data()[index];
|
cell lo_bits = data()[index];
|
||||||
|
|
||||||
if((lo_bits & 0x80) == 0)
|
if((lo_bits & 0x80) == 0)
|
||||||
return lo_bits;
|
return lo_bits;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
byte_array *aux = untag<byte_array>(str->aux);
|
byte_array *aux = untag<byte_array>(this->aux);
|
||||||
cell hi_bits = aux->data<u16>()[index];
|
cell hi_bits = aux->data<u16>()[index];
|
||||||
return (hi_bits << 7) ^ lo_bits;
|
return (hi_bits << 7) ^ lo_bits;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ void factor_vm::primitive_string_nth()
|
||||||
{
|
{
|
||||||
string *str = untag<string>(dpop());
|
string *str = untag<string>(dpop());
|
||||||
cell index = untag_fixnum(dpop());
|
cell index = untag_fixnum(dpop());
|
||||||
dpush(tag_fixnum(string_nth(str,index)));
|
dpush(tag_fixnum(str->nth(index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_set_string_nth_fast()
|
void factor_vm::primitive_set_string_nth_fast()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static cell string_capacity(string *str)
|
inline static cell string_capacity(const string *str)
|
||||||
{
|
{
|
||||||
return untag_fixnum(str->length);
|
return untag_fixnum(str->length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ template<typename Type> Type *factor_vm::untag_check(cell value)
|
||||||
return tagged<Type>(value).untag_check(this);
|
return tagged<Type>(value).untag_check(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> Type *factor_vm::untag(cell value)
|
template<typename Type> Type *untag(cell value)
|
||||||
{
|
{
|
||||||
return tagged<Type>(value).untagged();
|
return tagged<Type>(value).untagged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,38 +11,6 @@ vm_char *safe_strdup(const vm_char *str)
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't use printf directly, because format directives are not portable.
|
|
||||||
Instead we define the common cases here. */
|
|
||||||
void nl()
|
|
||||||
{
|
|
||||||
fputs("\n",stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_string(const char *str)
|
|
||||||
{
|
|
||||||
fputs(str,stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_cell(cell x)
|
|
||||||
{
|
|
||||||
printf(CELL_FORMAT,x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_cell_hex(cell x)
|
|
||||||
{
|
|
||||||
printf(CELL_HEX_FORMAT,x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_cell_hex_pad(cell x)
|
|
||||||
{
|
|
||||||
printf(CELL_HEX_PAD_FORMAT,x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_fixnum(fixnum x)
|
|
||||||
{
|
|
||||||
printf(FIXNUM_FORMAT,x);
|
|
||||||
}
|
|
||||||
|
|
||||||
cell read_cell_hex()
|
cell read_cell_hex()
|
||||||
{
|
{
|
||||||
cell cell;
|
cell cell;
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
vm_char *safe_strdup(const vm_char *str);
|
vm_char *safe_strdup(const vm_char *str);
|
||||||
void print_string(const char *str);
|
|
||||||
void nl();
|
|
||||||
void print_cell(cell x);
|
|
||||||
void print_cell_hex(cell x);
|
|
||||||
void print_cell_hex_pad(cell x);
|
void print_cell_hex_pad(cell x);
|
||||||
void print_fixnum(fixnum x);
|
|
||||||
cell read_cell_hex();
|
cell read_cell_hex();
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,9 @@ struct factor_vm
|
||||||
/* GC is off during heap walking */
|
/* GC is off during heap walking */
|
||||||
bool gc_off;
|
bool gc_off;
|
||||||
|
|
||||||
|
/* GC logging */
|
||||||
|
bool verbosegc;
|
||||||
|
|
||||||
/* Data heap */
|
/* Data heap */
|
||||||
data_heap *data;
|
data_heap *data;
|
||||||
|
|
||||||
|
@ -327,7 +330,7 @@ struct factor_vm
|
||||||
inline void set_array_nth(array *array, cell slot, cell value);
|
inline void set_array_nth(array *array, cell slot, cell value);
|
||||||
|
|
||||||
//strings
|
//strings
|
||||||
cell string_nth(string* str, cell index);
|
cell string_nth(const string *str, cell index);
|
||||||
void set_string_nth_fast(string *str, cell index, cell ch);
|
void set_string_nth_fast(string *str, cell index, cell ch);
|
||||||
void set_string_nth_slow(string *str_, cell index, cell ch);
|
void set_string_nth_slow(string *str_, cell index, cell ch);
|
||||||
void set_string_nth(string *str, cell index, cell ch);
|
void set_string_nth(string *str, cell index, cell ch);
|
||||||
|
@ -450,8 +453,9 @@ struct factor_vm
|
||||||
inline double untag_float_check(cell tagged);
|
inline double untag_float_check(cell tagged);
|
||||||
inline fixnum float_to_fixnum(cell tagged);
|
inline fixnum float_to_fixnum(cell tagged);
|
||||||
inline double fixnum_to_float(cell tagged);
|
inline double fixnum_to_float(cell tagged);
|
||||||
|
|
||||||
|
// tagged
|
||||||
template<typename Type> Type *untag_check(cell value);
|
template<typename Type> Type *untag_check(cell value);
|
||||||
template<typename Type> Type *untag(cell value);
|
|
||||||
|
|
||||||
//io
|
//io
|
||||||
void init_c_io();
|
void init_c_io();
|
||||||
|
|
Loading…
Reference in New Issue