| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | namespace factor { | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Compile code in boot image so that we can execute the startup quotation
 | 
					
						
							|  |  |  | // Allocates memory
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | void factor_vm::prepare_boot_image() { | 
					
						
							|  |  |  |   std::cout << "*** Stage 2 early init... " << std::flush; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-05 08:44:37 -04:00
										 |  |  |   // Compile all words.
 | 
					
						
							| 
									
										
										
										
											2015-12-04 07:57:57 -05:00
										 |  |  |   data_root<array> words(instances(WORD_TYPE), this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cell n_words = array_capacity(words.untagged()); | 
					
						
							|  |  |  |   for (cell i = 0; i < n_words; i++) { | 
					
						
							|  |  |  |     data_root<word> word(array_nth(words.untagged(), i), this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FACTOR_ASSERT(!word->entry_point); | 
					
						
							|  |  |  |     jit_compile_word(word.value(), word->def, false); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   update_code_heap_words(true); | 
					
						
							| 
									
										
										
										
											2015-12-04 07:57:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-05 08:44:37 -04:00
										 |  |  |   // Initialize all quotations
 | 
					
						
							| 
									
										
										
										
											2015-12-04 07:57:57 -05:00
										 |  |  |   data_root<array> quotations(instances(QUOTATION_TYPE), this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cell n_quots = array_capacity(quotations.untagged()); | 
					
						
							|  |  |  |   for (cell i = 0; i < n_quots; i++) { | 
					
						
							|  |  |  |     data_root<quotation> quot(array_nth(quotations.untagged(), i), this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!quot->entry_point) | 
					
						
							|  |  |  |       quot->entry_point = lazy_jit_compile_entry_point(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-10 04:07:57 -05:00
										 |  |  |   special_objects[OBJ_STAGE2] = special_objects[OBJ_CANONICAL_TRUE]; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   std::cout << "done" << std::endl; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | void factor_vm::init_factor(vm_parameters* p) { | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  |   // Kilobytes
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   p->datastack_size = align_page(p->datastack_size << 10); | 
					
						
							|  |  |  |   p->retainstack_size = align_page(p->retainstack_size << 10); | 
					
						
							|  |  |  |   p->callstack_size = align_page(p->callstack_size << 10); | 
					
						
							|  |  |  |   p->callback_size = align_page(p->callback_size << 10); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  |   // Megabytes
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   p->young_size <<= 20; | 
					
						
							|  |  |  |   p->aging_size <<= 20; | 
					
						
							|  |  |  |   p->tenured_size <<= 20; | 
					
						
							|  |  |  |   p->code_size <<= 20; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  |   // Disable GC during init as a sanity check
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   gc_off = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  |   // OS-specific initialization
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   early_init(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 17:12:16 -04:00
										 |  |  |   p->executable_path = vm_executable_path(); | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (p->image_path == NULL) { | 
					
						
							|  |  |  |     if (embedded_image_p()) { | 
					
						
							|  |  |  |       p->embedded_image = true; | 
					
						
							| 
									
										
										
										
											2016-05-13 17:12:16 -04:00
										 |  |  |       p->image_path = safe_strdup(p->executable_path); | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |     } else | 
					
						
							|  |  |  |       p->image_path = default_image_path(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-13 00:53:47 -04:00
										 |  |  |   srand((unsigned int)nano_count()); | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   init_ffi(); | 
					
						
							| 
									
										
										
										
											2016-11-22 21:50:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   datastack_size = p->datastack_size; | 
					
						
							|  |  |  |   retainstack_size = p->retainstack_size; | 
					
						
							|  |  |  |   callstack_size = p->callstack_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ctx = NULL; | 
					
						
							|  |  |  |   spare_ctx = new_context(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-04 17:30:16 -04:00
										 |  |  |   callbacks = new callback_heap(p->callback_size, this); | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   load_image(p); | 
					
						
							| 
									
										
										
										
											2016-08-18 20:58:19 -04:00
										 |  |  |   max_pic_size = (int)p->max_pic_size; | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   special_objects[OBJ_CELL_SIZE] = tag_fixnum(sizeof(cell)); | 
					
						
							|  |  |  |   special_objects[OBJ_ARGS] = false_object; | 
					
						
							|  |  |  |   special_objects[OBJ_EMBEDDED] = false_object; | 
					
						
							| 
									
										
										
										
											2015-08-29 17:09:01 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   cell aliens[][2] = { | 
					
						
							| 
									
										
										
										
											2016-11-21 14:40:25 -05:00
										 |  |  |     {OBJ_STDIN,           (cell)stdin}, | 
					
						
							|  |  |  |     {OBJ_STDOUT,          (cell)stdout}, | 
					
						
							|  |  |  |     {OBJ_STDERR,          (cell)stderr}, | 
					
						
							| 
									
										
										
										
											2015-08-29 17:09:01 -04:00
										 |  |  |     {OBJ_CPU,             (cell)FACTOR_CPU_STRING}, | 
					
						
							| 
									
										
										
										
											2016-05-13 17:12:16 -04:00
										 |  |  |     {OBJ_EXECUTABLE,      (cell)safe_strdup(p->executable_path)}, | 
					
						
							|  |  |  |     {OBJ_IMAGE,           (cell)safe_strdup(p->image_path)}, | 
					
						
							| 
									
										
										
										
											2015-08-29 17:09:01 -04:00
										 |  |  |     {OBJ_OS,              (cell)FACTOR_OS_STRING}, | 
					
						
							|  |  |  |     {OBJ_VM_COMPILE_TIME, (cell)FACTOR_COMPILE_TIME}, | 
					
						
							|  |  |  |     {OBJ_VM_COMPILER,     (cell)FACTOR_COMPILER_VERSION}, | 
					
						
							|  |  |  |     {OBJ_VM_GIT_LABEL,    (cell)FACTOR_STRINGIZE(FACTOR_GIT_LABEL)}, | 
					
						
							| 
									
										
										
										
											2015-08-30 06:21:20 -04:00
										 |  |  |     {OBJ_VM_VERSION,      (cell)FACTOR_STRINGIZE(FACTOR_VERSION)}, | 
					
						
							|  |  |  | #if defined(WINDOWS)
 | 
					
						
							| 
									
										
										
										
											2015-08-30 06:44:33 -04:00
										 |  |  |     {WIN_EXCEPTION_HANDLER, (cell)&factor::exception_handler} | 
					
						
							| 
									
										
										
										
											2015-08-30 06:21:20 -04:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-08-29 17:09:01 -04:00
										 |  |  |   }; | 
					
						
							|  |  |  |   int n_items = sizeof(aliens) / sizeof(cell[2]); | 
					
						
							|  |  |  |   for (int n = 0; n < n_items; n++) { | 
					
						
							|  |  |  |     cell idx = aliens[n][0]; | 
					
						
							|  |  |  |     special_objects[idx] = allot_alien(false_object, aliens[n][1]); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  |   // We can GC now
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   gc_off = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!to_boolean(special_objects[OBJ_STAGE2])) | 
					
						
							|  |  |  |     prepare_boot_image(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (p->signals) | 
					
						
							|  |  |  |     init_signals(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (p->console) | 
					
						
							|  |  |  |     open_console(); | 
					
						
							| 
									
										
										
										
											2011-11-10 18:14:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Allocates memory
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | void factor_vm::pass_args_to_factor(int argc, vm_char** argv) { | 
					
						
							|  |  |  |   growable_array args(this); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-23 01:39:52 -05:00
										 |  |  |   for (fixnum i = 0; i < argc; i++) | 
					
						
							| 
									
										
										
										
											2013-05-13 00:53:47 -04:00
										 |  |  |     args.add(allot_alien(false_object, (cell)argv[i])); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   args.trim(); | 
					
						
							|  |  |  |   special_objects[OBJ_ARGS] = args.elements.value(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | void factor_vm::stop_factor() { | 
					
						
							|  |  |  |   c_to_factor_toplevel(special_objects[OBJ_SHUTDOWN_QUOT]); | 
					
						
							| 
									
										
										
										
											2009-10-20 00:28:18 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | char* factor_vm::factor_eval_string(char* string) { | 
					
						
							|  |  |  |   void* func = alien_offset(special_objects[OBJ_EVAL_CALLBACK]); | 
					
						
							|  |  |  |   CODE_TO_FUNCTION_POINTER(func); | 
					
						
							|  |  |  |   return ((char * (*)(char*)) func)(string); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | void factor_vm::factor_eval_free(char* result) { free(result); } | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | void factor_vm::factor_yield() { | 
					
						
							|  |  |  |   void* func = alien_offset(special_objects[OBJ_YIELD_CALLBACK]); | 
					
						
							|  |  |  |   CODE_TO_FUNCTION_POINTER(func); | 
					
						
							|  |  |  |   ((void(*)()) func)(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | void factor_vm::factor_sleep(long us) { | 
					
						
							|  |  |  |   void* func = alien_offset(special_objects[OBJ_SLEEP_CALLBACK]); | 
					
						
							|  |  |  |   CODE_TO_FUNCTION_POINTER(func); | 
					
						
							|  |  |  |   ((void(*)(long)) func)(us); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | void factor_vm::start_standalone_factor(int argc, vm_char** argv) { | 
					
						
							|  |  |  |   vm_parameters p; | 
					
						
							| 
									
										
										
										
											2016-05-12 22:12:57 -04:00
										 |  |  |   p.init_from_args(argc, argv); | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   init_factor(&p); | 
					
						
							|  |  |  |   pass_args_to_factor(argc, argv); | 
					
						
							| 
									
										
										
										
											2016-05-01 17:36:41 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (p.fep) | 
					
						
							|  |  |  |     factorbug(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   c_to_factor_toplevel(special_objects[OBJ_STARTUP_QUOT]); | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:09 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | factor_vm* new_factor_vm() { | 
					
						
							|  |  |  |   THREADHANDLE thread = thread_id(); | 
					
						
							|  |  |  |   factor_vm* newvm = new factor_vm(thread); | 
					
						
							|  |  |  |   register_vm_with_thread(newvm); | 
					
						
							|  |  |  |   thread_vms[thread] = newvm; | 
					
						
							| 
									
										
										
										
											2009-10-02 13:00:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  |   return newvm; | 
					
						
							| 
									
										
										
										
											2009-10-02 13:00:01 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 21:59:58 -04:00
										 |  |  | VM_C_API void start_standalone_factor(int argc, vm_char** argv) { | 
					
						
							|  |  |  |   factor_vm* newvm = new_factor_vm(); | 
					
						
							| 
									
										
										
										
											2016-05-12 22:12:57 -04:00
										 |  |  |   newvm->start_standalone_factor(argc, argv); | 
					
						
							|  |  |  |   delete newvm; | 
					
						
							| 
									
										
										
										
											2009-08-24 13:34:30 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |