This commit is contained in:
gingerBill
2018-03-23 15:23:31 +00:00
4 changed files with 173 additions and 65 deletions
+105 -46
View File
@@ -3,10 +3,36 @@ foreign import api "system:api"
Handle :: distinct int; Handle :: distinct int;
Errno :: distinct int; Errno :: distinct int;
O_RDONLY :: 1; O_RDONLY :: 0x00001;
O_WRONLY :: 2; O_WRONLY :: 0x00002;
O_CREATE :: 4; O_RDWR :: 0x00003;
O_TRUNC :: 4; O_CREATE :: 0x00040;
O_EXCL :: 0x00080;
O_TRUNC :: 0x00200;
O_APPEND :: 0x00400;
ERROR_NONE : Errno : -1 ;
ERROR_UNKNOWN_OPERATION_FAILURE : Errno : -7 ;
ERROR_PATH_NOT_WITHIN_MOUNTED_VOLUME : Errno : -14;
ERROR_PATH_NOT_FOUND : Errno : -15;
ERROR_FILE_EXISTS : Errno : -19;
ERROR_FILE_NOT_FOUND : Errno : -20;
ERROR_DRIVE_ERROR_FILE_DAMAGED : Errno : -21;
ERROR_ACCESS_NOT_WITHIN_FILE_BOUNDS : Errno : -22;
ERROR_ACCESS_DENIED : Errno : -23;
ERROR_FILE_IN_EXCLUSIVE_USE : Errno : -24;
ERROR_FILE_CANNOT_GET_EXCLUSIVE_USE : Errno : -25;
ERROR_INCORRECT_NODE_TYPE : Errno : -26;
ERROR_EVENT_NOT_SET : Errno : -27;
ERROR_TIMEOUT_REACHED : Errno : -29;
ERROR_REQUEST_CLOSED_BEFORE_COMPLETE : Errno : -30;
ERROR_NO_CHARACTER_AT_COORDINATE : Errno : -31;
ERROR_FILE_ON_READ_ONLY_VOLUME : Errno : -32;
ERROR_USER_CANCELED_IO : Errno : -33;
ERROR_DRIVE_CONTROLLER_REPORTED : Errno : -35;
ERROR_COULD_NOT_ISSUE_PACKET : Errno : -36;
ERROR_NOT_IMPLEMENTED : Errno : 1;
OS_Node_Type :: enum i32 { OS_Node_Type :: enum i32 {
File = 0, File = 0,
@@ -18,22 +44,23 @@ OS_Node_Information :: struct {
id: [16]byte, id: [16]byte,
ntype: OS_Node_Type, ntype: OS_Node_Type,
size: i64, size: i64,
// Our additions...
position: i64, position: i64,
} }
foreign api { foreign api {
@(link_name="OSHelloWorld") os_hello_world :: proc() ---; @(link_name="OSPrintDirect") OSPrintDirect :: proc(str: ^u8, length: int) ---;
@(link_name="OSPrintDirect") os_print_direct :: proc(str: cstring, length: int) ---; @(link_name="malloc") OSMalloc :: proc(bytes: int) -> rawptr ---;
@(link_name="OSHeapAllocate") os_heap_allocate :: proc(bytes: int, zero: bool) -> rawptr ---; @(link_name="free") OSFree :: proc(address: rawptr) ---;
@(link_name="OSHeapFree") os_heap_free :: proc(address: rawptr) ---; @(link_name="OSOpenNode") OSOpenNode :: proc(path: ^u8, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---;
@(link_name="OSOpenNode") os_open_node :: proc(path: cstring, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---; @(link_name="OSResizeFile") OSResizeFile :: proc(handle: Handle, new_size: u64) -> Errno ---;
@(link_name="OSResizeFile") os_resize_file :: proc(handle: Handle, new_size: u64) -> Errno ---; @(link_name="OSCloseHandle") OSCloseHandle :: proc(handle: Handle) ---;
@(link_name="OSCloseHandle") os_close_handle :: proc(handle: Handle) ---; @(link_name="OSWriteFileSync") OSWriteFileSync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
@(link_name="OSWriteFileSync") os_write_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---; @(link_name="OSReadFileSync") OSReadFileSync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
@(link_name="OSReadFileSync") os_read_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---; @(link_name="realloc") OSRealloc :: proc(address: rawptr, size: int) -> rawptr ---;
@(link_name="OSInitialiseAPI") os_initialise_api :: proc() -> int ---; @(link_name="OSGetThreadID") OSGetThreadID :: proc(handle: Handle) -> int ---;
@(link_name="OSTerminateProcess") os_terminate_process :: proc(handle: Handle) ---; @(link_name="OSRefreshNodeInformation") OSRefreshNodeInformation :: proc(information: ^OS_Node_Information) ---;
@(link_name="realloc") os_heap_reallocate :: proc(address: rawptr, size: int) -> rawptr ---;
} }
stdin := Handle(-1); // Not implemented stdin := Handle(-1); // Not implemented
@@ -41,56 +68,91 @@ stdout := Handle(0);
stderr := Handle(0); stderr := Handle(0);
current_thread_id :: proc() -> int { current_thread_id :: proc() -> int {
// Not implemented return OSGetThreadID(Handle(0x1000));
return -1;
} }
heap_alloc :: proc(size: int) -> rawptr { heap_alloc :: proc(size: int) -> rawptr {
return os_heap_allocate(size, true); return OSMalloc(size);
} }
heap_free :: proc(address: rawptr) { heap_free :: proc(address: rawptr) {
os_heap_free(address); OSFree(address);
} }
heap_resize :: proc(address: rawptr, new_size: int) -> rawptr { heap_resize :: proc(address: rawptr, new_size: int) -> rawptr {
return os_heap_reallocate(address, new_size); return OSRealloc(address, new_size);
} }
open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) { open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) {
information := new(OS_Node_Information); flags : u64 = 0;
error := os_open_node(&path[0], len(path), u64(mode), information);
if error < -1 do return 0, 1; if mode & O_CREATE == O_CREATE {
information.position = 0; flags = flags | 0x9000; // Fail if found and create directories leading to the file if they don't exist
if mode&O_TRUNC==O_TRUNC { } else {
error := os_resize_file(information.handle, 0); flags = flags | 0x2000; // Fail if not found
if error < -1 do return 0, 1;
} }
return Handle(uintptr(information)), 0;
if mode & O_EXCL == O_EXCL {
flags = flags | 0x111; // Block opening the node for any reason
}
if mode & O_RDONLY == O_RDONLY {
flags = flags | 0x2; // Read access
}
if mode & O_WRONLY == O_WRONLY {
flags = flags | 0x220; // Write and resize access
}
if mode & O_TRUNC == O_TRUNC {
flags = flags | 0x200; // Resize access
}
information := new(OS_Node_Information);
error := OSOpenNode(&path[0], len(path), flags, information);
if error < ERROR_NONE {
free(information);
return 0, error;
}
if mode & O_TRUNC == O_TRUNC {
error := OSResizeFile(information.handle, 0);
if error < ERROR_NONE do return 0, ERROR_UNKNOWN_OPERATION_FAILURE;
}
if mode & O_APPEND == O_APPEND {
information.position = information.size;
} else {
information.position = 0;
}
return Handle(uintptr(information)), ERROR_NONE;
} }
close :: proc(fd: Handle) { close :: proc(fd: Handle) {
information := (^OS_Node_Information)(uintptr(fd)); information := (^OS_Node_Information)(uintptr(fd));
os_close_handle(information.handle); OSCloseHandle(information.handle);
free(information); free(information);
} }
file_size :: proc(fd: Handle) -> (i64, Errno) { file_size :: proc(fd: Handle) -> (i64, Errno) {
// Not (properly) implemented x : OS_Node_Information;
information := cast(^OS_Node_Information)uintptr(fd); OSRefreshNodeInformation(&x);
return information.size,0; return x.size, ERROR_NONE;
} }
write :: proc(fd: Handle, data: []byte) -> (int, Errno) { write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
if fd == 0 { if fd == 0 {
os_print_direct(&data[0], len(data)); OSPrintDirect(&data[0], len(data));
return len(data), 0; return len(data), ERROR_NONE;
} else if fd == 1 { } else if fd == 1 {
assert(false); assert(false);
return 0, 1; return 0, ERROR_NOT_IMPLEMENTED;
} }
information := (^OS_Node_Information)(uintptr(fd)); information := (^OS_Node_Information)(uintptr(fd));
count := os_write_file_sync(information.handle, information.position, i64(len(data)), &data[0]); count := OSWriteFileSync(information.handle, information.position, i64(len(data)), &data[0]);
if count < 0 do return 0, 1; if count < 0 do return 0, 1;
information.position += count; information.position += count;
return int(count), 0; return int(count), 0;
@@ -99,15 +161,12 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
read :: proc(fd: Handle, data: []byte) -> (int, Errno) { read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
if (fd == 0 || fd == 1) { if (fd == 0 || fd == 1) {
assert(false); assert(false);
return 0, 1; return 0, ERROR_NOT_IMPLEMENTED;
} }
information := (^OS_Node_Information)(uintptr(fd));
count := os_read_file_sync(information.handle, information.position, i64(len(data)), &data[0]);
if count < 0 do return 0, 1;
information.position += count;
return int(count), 0;
}
os_terminate_this_process :: proc() { information := (^OS_Node_Information)(uintptr(fd));
os_terminate_process(0x1001); count := OSReadFileSync(information.handle, information.position, i64(len(data)), &data[0]);
if count < 0 do return 0, ERROR_UNKNOWN_OPERATION_FAILURE;
information.position += count;
return int(count), ERROR_NONE;
} }
+2
View File
@@ -16,6 +16,8 @@ struct BuildContext {
String command; String command;
String out_filepath; String out_filepath;
String resource_filepath;
bool has_resource;
String opt_flags; String opt_flags;
String llc_flags; String llc_flags;
String link_flags; String link_flags;
+6 -5
View File
@@ -1603,11 +1603,12 @@ void check_decl_attributes(Checker *c, Array<AstNode *> attributes, DeclAttribut
if (value != nullptr) { if (value != nullptr) {
Operand op = {}; Operand op = {};
check_expr(c, &op, value); check_expr(c, &op, value);
if (op.mode ) if (op.mode) {
if (op.mode != Addressing_Constant) { if (op.mode != Addressing_Constant) {
error(value, "An attribute element must be constant"); error(value, "An attribute element must be constant");
} else { } else {
ev = op.value; ev = op.value;
}
} }
} }
+60 -14
View File
@@ -46,7 +46,6 @@ i32 system_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) {
defer (gb_temp_arena_memory_end(tmp)); defer (gb_temp_arena_memory_end(tmp));
cmd = string_to_string16(string_buffer_allocator, make_string(cast(u8 *)cmd_line, cmd_len-1)); cmd = string_to_string16(string_buffer_allocator, make_string(cast(u8 *)cmd_line, cmd_len-1));
if (CreateProcessW(nullptr, cmd.text, if (CreateProcessW(nullptr, cmd.text,
nullptr, nullptr, true, 0, nullptr, nullptr, nullptr, nullptr, true, 0, nullptr, nullptr,
&start_info, &pi)) { &start_info, &pi)) {
@@ -202,6 +201,7 @@ enum BuildFlagKind {
BuildFlag_Invalid, BuildFlag_Invalid,
BuildFlag_OutFile, BuildFlag_OutFile,
BuildFlag_ResourceFile,
BuildFlag_OptimizationLevel, BuildFlag_OptimizationLevel,
BuildFlag_ShowTimings, BuildFlag_ShowTimings,
BuildFlag_ThreadCount, BuildFlag_ThreadCount,
@@ -241,6 +241,7 @@ void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, Bu
bool parse_build_flags(Array<String> args) { bool parse_build_flags(Array<String> args) {
auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT); auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String); add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String);
add_flag(&build_flags, BuildFlag_ResourceFile, str_lit("resource"), BuildFlagParam_String);
add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer); add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer);
add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None);
add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer); add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer);
@@ -388,6 +389,24 @@ bool parse_build_flags(Array<String> args) {
} }
break; break;
} }
case BuildFlag_ResourceFile: {
GB_ASSERT(value.kind == ExactValue_String);
String path = value.value_string;
path = string_trim_whitespace(path);
if (is_import_path_valid(path)) {
if(!string_ends_with(path, str_lit(".rc"))) {
gb_printf_err("Invalid -resource path %.*s, missing .rc\n", LIT(path));
bad_flags = true;
break;
}
build_context.resource_filepath = substring(path, 0, string_extension_position(path));
build_context.has_resource = true;
} else {
gb_printf_err("Invalid -resource path, got %.*s\n", LIT(path));
bad_flags = true;
}
break;
}
case BuildFlag_OptimizationLevel: case BuildFlag_OptimizationLevel:
GB_ASSERT(value.kind == ExactValue_Integer); GB_ASSERT(value.kind == ExactValue_Integer);
build_context.optimization_level = cast(i32)value.value_integer; build_context.optimization_level = cast(i32)value.value_integer;
@@ -602,6 +621,7 @@ void remove_temp_files(String output_base) {
EXT_REMOVE(".bc"); EXT_REMOVE(".bc");
#if defined(GB_SYSTEM_WINDOWS) #if defined(GB_SYSTEM_WINDOWS)
EXT_REMOVE(".obj"); EXT_REMOVE(".obj");
EXT_REMOVE(".res");
#else #else
EXT_REMOVE(".o"); EXT_REMOVE(".o");
#endif #endif
@@ -839,18 +859,44 @@ int main(int arg_count, char **arg_ptr) {
link_settings = gb_string_append_fmt(link_settings, " /DEBUG"); link_settings = gb_string_append_fmt(link_settings, " /DEBUG");
} }
exit_code = system_exec_command_line_app("msvc-link", true, if(build_context.has_resource) {
"link \"%.*s.obj\" -OUT:\"%.*s.%s\" %s " exit_code = system_exec_command_line_app("msvc-link", true,
"/defaultlib:libcmt " "rc /nologo /fo \"%.*s.res\" \"%.*s.rc\"",
// "/nodefaultlib " LIT(output_base),
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE " LIT(build_context.resource_filepath)
" %.*s " );
" %s "
"", if (exit_code != 0) {
LIT(output_base), LIT(output_base), output_ext, return exit_code;
lib_str, LIT(build_context.link_flags), }
link_settings
); exit_code = system_exec_command_line_app("msvc-link", true,
"link \"%.*s.obj\" \"%.*s.res\" -OUT:\"%.*s.%s\" %s "
"/defaultlib:libcmt "
// "/nodefaultlib "
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
" %.*s "
" %s "
"",
LIT(output_base), LIT(output_base), LIT(output_base), output_ext,
lib_str, LIT(build_context.link_flags),
link_settings
);
} else {
exit_code = system_exec_command_line_app("msvc-link", true,
"link \"%.*s.obj\" -OUT:\"%.*s.%s\" %s "
"/defaultlib:libcmt "
// "/nodefaultlib "
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
" %.*s "
" %s "
"",
LIT(output_base), LIT(output_base), output_ext,
lib_str, LIT(build_context.link_flags),
link_settings
);
}
if (exit_code != 0) { if (exit_code != 0) {
return exit_code; return exit_code;
} }
@@ -967,7 +1013,7 @@ int main(int arg_count, char **arg_ptr) {
#endif #endif
, linker, LIT(output_base), LIT(output_base), output_ext, , linker, LIT(output_base), LIT(output_base), output_ext,
lib_str, lib_str,
str_eq_ignore_case(cross_compile_target, str_lit("Essence")) ? "" : "-lc -lm", str_eq_ignore_case(cross_compile_target, str_lit("Essence")) ? "-lfreetype -lglue" : "-lc -lm",
LIT(build_context.link_flags), LIT(build_context.link_flags),
link_settings, link_settings,
LIT(cross_compile_lib_dir) LIT(cross_compile_lib_dir)