#include <fcntl.h>
#include <errno.h>
#include <malloc.h>
+#include <time.h>
#include <stdlib.h>
#include <stdarg.h>
+//------------------------------------------------------------------------------
+// TIME / DURATION
+//------------------------------------------------------------------------------
+u64 bh_time_curr();
+u64 bh_time_duration(u64 old);
+
#endif // ifndef BH_NO_IMAP
+
+
+
+
+
+
+u64 bh_time_curr() {
+ struct timespec spec;
+ clock_gettime(CLOCK_MONOTONIC, &spec);
+
+ time_t sec = spec.tv_sec;
+ u64 ms = spec.tv_nsec / 1000000;
+ if (ms > 999) {
+ sec++;
+ ms = 0;
+ }
+
+ return sec * 1000 + ms;
+}
+
+u64 bh_time_duration(u64 old) {
+ u64 curr = bh_time_curr();
+ return curr - old;
+}
+
#endif // ifdef BH_DEFINE
#endif // ifndef BH_H
#endif
+
+
+#ifdef REPORT_TIMES
+// CLEANUP: Move this to another file
+typedef struct TimerStackElem {
+ char* label;
+ u64 time;
+} TimerStackElem;
+
+static bh_arr(TimerStackElem) global_timer_stack;
+
+void timer_stack_init() {
+ global_timer_stack = NULL;
+ bh_arr_new(global_heap_allocator, global_timer_stack, 4);
+}
+
+void timer_stack_push(char* label) {
+ TimerStackElem elem;
+ elem.label = label;
+ elem.time = bh_time_curr();
+ bh_arr_push(global_timer_stack, elem);
+}
+
+void timer_stack_pop() {
+ TimerStackElem elem = bh_arr_pop(global_timer_stack);
+ u64 duration = bh_time_duration(elem.time);
+ bh_printf("[Time] %s took %lms.\n", elem.label, duration);
+}
+#endif
+
+
+
static const char* docstring = "Onyx compiler version " VERSION "\n"
"\n"
"The compiler for the Onyx programming language.\n"
static CompilerProgress process_source_file(CompilerState* compiler_state, char* filename) {
if (bh_table_has(bh_file_contents, compiler_state->loaded_files, filename)) return ONYX_COMPILER_PROGRESS_SUCCESS;
+#ifdef REPORT_TIMES
+ timer_stack_push(bh_aprintf(global_heap_allocator, "Parsing '%s'", filename));
+#endif
+
bh_file file;
bh_file_error err = bh_file_open(&file, filename);
ParseResults results = parse_source_file(compiler_state, &fc);
merge_parse_results(compiler_state, &results);
+#ifdef REPORT_TIMES
+ timer_stack_pop();
+#endif
+
if (onyx_has_errors()) {
return ONYX_COMPILER_PROGRESS_FAILED_PARSE;
} else {
static i32 onyx_compile(CompilerState* compiler_state) {
+#ifdef REPORT_TIMES
+ timer_stack_push("Parsing");
+#endif
+
// NOTE: While the queue is not empty, process the next file
while (!bh_arr_is_empty(compiler_state->queued_files)) {
CompilerProgress result = process_source_file(compiler_state, (char *) compiler_state->queued_files[0]);
bh_arr_fastdelete(compiler_state->queued_files, 0);
}
+#ifdef REPORT_TIMES
+ timer_stack_pop();
+
+ timer_stack_push("Checking semantics");
+ timer_stack_push("Initializing builtins");
+#endif
+
initialize_builtins(compiler_state->ast_alloc, &compiler_state->prog_info);
if (onyx_has_errors()) {
return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS;
sizeof(Entity),
sort_entities);
+#ifdef REPORT_TIMES
+ timer_stack_pop();
+#endif
+
// NOTE: Check types and semantic rules
if (compiler_state->options->verbose_output)
bh_printf("[Checking semantics]\n");
onyx_sempass_init(compiler_state->sp_alloc, compiler_state->ast_alloc);
onyx_sempass(&compiler_state->prog_info);
+#ifdef REPORT_TIMES
+ timer_stack_pop();
+#endif
+
if (onyx_has_errors()) {
return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS;
}
if (compiler_state->options->verbose_output)
bh_printf("[Generating WASM]\n");
+#ifdef REPORT_TIMES
+ timer_stack_push("Code generation");
+ timer_stack_push("Generating WASM");
+#endif
+
compiler_state->wasm_mod = onyx_wasm_module_create(compiler_state->options->allocator);
onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->prog_info);
return ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN;
}
+#ifdef REPORT_TIMES
+ timer_stack_pop();
+ timer_stack_push("Write to file");
+#endif
// NOTE: Output to file
bh_file output_file;
onyx_wasm_module_write_to_file(&compiler_state->wasm_mod, output_file);
+#ifdef REPORT_TIMES
+ timer_stack_pop();
+ timer_stack_pop();
+#endif
+
return ONYX_COMPILER_PROGRESS_SUCCESS;
}