]> gitweb.factorcode.org Git - factor.git/blob - vm/factor.cpp
xmode.marker: faster update-match-group
[factor.git] / vm / factor.cpp
1 #include "master.hpp"
2
3 namespace factor {
4
5 // Compile code in boot image so that we can execute the startup quotation
6 // Allocates memory
7 void factor_vm::prepare_boot_image() {
8   std::cout << "*** Stage 2 early init... " << std::flush;
9
10   // Compile all words.
11   data_root<array> words(instances(WORD_TYPE), this);
12
13   cell n_words = array_capacity(words.untagged());
14   for (cell i = 0; i < n_words; i++) {
15     data_root<word> word(array_nth(words.untagged(), i), this);
16
17     FACTOR_ASSERT(!word->entry_point);
18     jit_compile_word(word.value(), word->def, false);
19   }
20   update_code_heap_words(true);
21
22   // Initialize all quotations
23   data_root<array> quotations(instances(QUOTATION_TYPE), this);
24
25   cell n_quots = array_capacity(quotations.untagged());
26   for (cell i = 0; i < n_quots; i++) {
27     data_root<quotation> quot(array_nth(quotations.untagged(), i), this);
28
29     if (!quot->entry_point)
30       quot->entry_point = lazy_jit_compile_entry_point();
31   }
32
33   special_objects[OBJ_STAGE2] = special_objects[OBJ_CANONICAL_TRUE];
34
35   std::cout << "done" << std::endl;
36 }
37
38 void factor_vm::init_factor(vm_parameters* p) {
39   // Kilobytes
40   p->datastack_size = align_page(p->datastack_size << 10);
41   p->retainstack_size = align_page(p->retainstack_size << 10);
42   p->callstack_size = align_page(p->callstack_size << 10);
43   p->callback_size = align_page(p->callback_size << 10);
44
45   // Megabytes
46   p->young_size <<= 20;
47   p->aging_size <<= 20;
48   p->tenured_size <<= 20;
49   p->code_size <<= 20;
50
51   // Disable GC during init as a sanity check
52   gc_off = true;
53
54   // OS-specific initialization
55   early_init();
56
57   p->executable_path = vm_executable_path();
58
59   if (p->image_path == NULL) {
60     if (embedded_image_p()) {
61       p->embedded_image = true;
62       p->image_path = safe_strdup(p->executable_path);
63     } else
64       p->image_path = default_image_path();
65   }
66
67   srand((unsigned int)nano_count());
68   init_ffi();
69
70   datastack_size = p->datastack_size;
71   retainstack_size = p->retainstack_size;
72   callstack_size = p->callstack_size;
73
74   ctx = NULL;
75   spare_ctx = new_context();
76
77   callbacks = new callback_heap(p->callback_size, this);
78   load_image(p);
79   max_pic_size = (int)p->max_pic_size;
80   special_objects[OBJ_CELL_SIZE] = tag_fixnum(sizeof(cell));
81   special_objects[OBJ_ARGS] = false_object;
82   special_objects[OBJ_EMBEDDED] = false_object;
83
84   cell aliens[][2] = {
85     {OBJ_STDIN,           (cell)stdin},
86     {OBJ_STDOUT,          (cell)stdout},
87     {OBJ_STDERR,          (cell)stderr},
88     {OBJ_CPU,             (cell)FACTOR_CPU_STRING},
89     {OBJ_EXECUTABLE,      (cell)safe_strdup(p->executable_path)},
90     {OBJ_IMAGE,           (cell)safe_strdup(p->image_path)},
91     {OBJ_OS,              (cell)FACTOR_OS_STRING},
92     {OBJ_VM_COMPILE_TIME, (cell)FACTOR_COMPILE_TIME},
93     {OBJ_VM_COMPILER,     (cell)FACTOR_COMPILER_VERSION},
94     {OBJ_VM_GIT_LABEL,    (cell)FACTOR_STRINGIZE(FACTOR_GIT_LABEL)},
95     {OBJ_VM_VERSION,      (cell)FACTOR_STRINGIZE(FACTOR_VERSION)},
96 #if defined(WINDOWS)
97     {WIN_EXCEPTION_HANDLER, (cell)&factor::exception_handler}
98 #endif
99   };
100   int n_items = sizeof(aliens) / sizeof(cell[2]);
101   for (int n = 0; n < n_items; n++) {
102     cell idx = aliens[n][0];
103     special_objects[idx] = allot_alien(false_object, aliens[n][1]);
104   }
105
106   // We can GC now
107   gc_off = false;
108
109   if (!to_boolean(special_objects[OBJ_STAGE2]))
110     prepare_boot_image();
111
112   if (p->signals)
113     init_signals();
114
115   if (p->console)
116     open_console();
117
118 }
119
120 // Allocates memory
121 void factor_vm::pass_args_to_factor(int argc, vm_char** argv) {
122   growable_array args(this);
123
124   for (fixnum i = 0; i < argc; i++)
125     args.add(allot_alien(false_object, (cell)argv[i]));
126
127   args.trim();
128   special_objects[OBJ_ARGS] = args.elements.value();
129 }
130
131 void factor_vm::stop_factor() {
132   c_to_factor_toplevel(special_objects[OBJ_SHUTDOWN_QUOT]);
133 }
134
135 char* factor_vm::factor_eval_string(char* string) {
136   void* func = alien_offset(special_objects[OBJ_EVAL_CALLBACK]);
137   CODE_TO_FUNCTION_POINTER(func);
138   return ((char * (*)(char*)) func)(string);
139 }
140
141 void factor_vm::factor_eval_free(char* result) { free(result); }
142
143 void factor_vm::factor_yield() {
144   void* func = alien_offset(special_objects[OBJ_YIELD_CALLBACK]);
145   CODE_TO_FUNCTION_POINTER(func);
146   ((void(*)()) func)();
147 }
148
149 void factor_vm::factor_sleep(long us) {
150   void* func = alien_offset(special_objects[OBJ_SLEEP_CALLBACK]);
151   CODE_TO_FUNCTION_POINTER(func);
152   ((void(*)(long)) func)(us);
153 }
154
155 void factor_vm::start_standalone_factor(int argc, vm_char** argv) {
156   vm_parameters p;
157   p.init_from_args(argc, argv);
158   init_factor(&p);
159   pass_args_to_factor(argc, argv);
160
161   if (p.fep)
162     factorbug();
163
164   c_to_factor_toplevel(special_objects[OBJ_STARTUP_QUOT]);
165 }
166
167 factor_vm* new_factor_vm() {
168   THREADHANDLE thread = thread_id();
169   factor_vm* newvm = new factor_vm(thread);
170   register_vm_with_thread(newvm);
171   thread_vms[thread] = newvm;
172
173   return newvm;
174 }
175
176 VM_C_API void start_standalone_factor(int argc, vm_char** argv) {
177   factor_vm* newvm = new_factor_vm();
178   newvm->start_standalone_factor(argc, argv);
179   delete newvm;
180 }
181
182 }