all: add stdcall attribute, unhandled exception handler, get_raw_stdin, v_realloc
							parent
							
								
									a849d46e3f
								
							
						
					
					
						commit
						f0a9b88ac4
					
				| 
						 | 
					@ -158,7 +158,16 @@ TODO
 | 
				
			||||||
	print_backtrace()
 | 
						print_backtrace()
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[unsafe_fn]
 | 
				
			||||||
 | 
					pub fn v_realloc(b byteptr, n int) byteptr {
 | 
				
			||||||
 | 
						ptr := C.realloc(b, n)
 | 
				
			||||||
 | 
						if ptr == 0 {
 | 
				
			||||||
 | 
							panic('realloc($n) failed')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ptr
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn v_calloc(n int) byteptr {
 | 
					pub fn v_calloc(n int) byteptr {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,7 @@ fn builtin_init() {
 | 
				
			||||||
		C.SetConsoleMode(C.GetStdHandle(C.STD_OUTPUT_HANDLE), C.ENABLE_PROCESSED_OUTPUT | 0x0004) // enable_virtual_terminal_processing
 | 
							C.SetConsoleMode(C.GetStdHandle(C.STD_OUTPUT_HANDLE), C.ENABLE_PROCESSED_OUTPUT | 0x0004) // enable_virtual_terminal_processing
 | 
				
			||||||
		C.setbuf(C.stdout, 0)
 | 
							C.setbuf(C.stdout, 0)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						add_unhandled_exception_handler()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn print_backtrace_skipping_top_frames(skipframes int) bool {
 | 
					fn print_backtrace_skipping_top_frames(skipframes int) bool {
 | 
				
			||||||
| 
						 | 
					@ -139,3 +140,56 @@ fn print_backtrace_skipping_top_frames_mingw(skipframes int) bool {
 | 
				
			||||||
	eprintln('print_backtrace_skipping_top_frames_mingw is not implemented')
 | 
						eprintln('print_backtrace_skipping_top_frames_mingw is not implemented')
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//TODO copypaste from os
 | 
				
			||||||
 | 
					// we want to be able to use this here without having to `import os`
 | 
				
			||||||
 | 
					struct ExceptionRecord {
 | 
				
			||||||
 | 
					pub:
 | 
				
			||||||
 | 
						// status_ constants
 | 
				
			||||||
 | 
						code u32
 | 
				
			||||||
 | 
						flags u32
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						record &ExceptionRecord
 | 
				
			||||||
 | 
						address voidptr
 | 
				
			||||||
 | 
						param_count u32
 | 
				
			||||||
 | 
						// params []voidptr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 struct ContextRecord {
 | 
				
			||||||
 | 
						// TODO
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ExceptionPointers {
 | 
				
			||||||
 | 
					pub:
 | 
				
			||||||
 | 
						exception_record &ExceptionRecord
 | 
				
			||||||
 | 
						context_record &ContextRecord
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type VectoredExceptionHandler fn(&ExceptionPointers)u32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn C.AddVectoredExceptionHandler(u32, VectoredExceptionHandler)
 | 
				
			||||||
 | 
					fn add_vectored_exception_handler(handler VectoredExceptionHandler) {
 | 
				
			||||||
 | 
						C.AddVectoredExceptionHandler(1, handler)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[windows_stdcall]
 | 
				
			||||||
 | 
					fn unhandled_exception_handler(e &ExceptionPointers) u32 {
 | 
				
			||||||
 | 
						match e.exception_record.code {
 | 
				
			||||||
 | 
							// These are 'used' by the backtrace printer 
 | 
				
			||||||
 | 
							// so we dont want to catch them...
 | 
				
			||||||
 | 
							0x4001000A, 0x40010006 {
 | 
				
			||||||
 | 
								return 0
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								println('Unhandled Exception 0x${e.exception_record.code:X}')
 | 
				
			||||||
 | 
								print_backtrace_skipping_top_frames(5)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn add_unhandled_exception_handler() {
 | 
				
			||||||
 | 
						add_vectored_exception_handler(unhandled_exception_handler)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -102,3 +102,38 @@ const (
 | 
				
			||||||
	o_noctty	= 0			// make file non-controlling tty (ignored on Windows)
 | 
						o_noctty	= 0			// make file non-controlling tty (ignored on Windows)
 | 
				
			||||||
	o_nonblock	= 0			// don't block on opening file (ignored on Windows)
 | 
						o_nonblock	= 0			// don't block on opening file (ignored on Windows)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						status_access_violation =          0xC0000005
 | 
				
			||||||
 | 
						status_in_page_error =             0xC0000006
 | 
				
			||||||
 | 
						status_invalid_handle =            0xC0000008
 | 
				
			||||||
 | 
						status_invalid_parameter =         0xC000000D
 | 
				
			||||||
 | 
						status_no_memory =                 0xC0000017
 | 
				
			||||||
 | 
						status_illegal_instruction =       0xC000001D
 | 
				
			||||||
 | 
						status_noncontinuable_exception =  0xC0000025
 | 
				
			||||||
 | 
						status_invalid_disposition =       0xC0000026
 | 
				
			||||||
 | 
						status_array_bounds_exceeded =     0xC000008C
 | 
				
			||||||
 | 
						status_float_denormal_operand =    0xC000008D
 | 
				
			||||||
 | 
						status_float_divide_by_zero =      0xC000008E
 | 
				
			||||||
 | 
						status_float_inexact_result =      0xC000008F
 | 
				
			||||||
 | 
						status_float_invalid_operation =   0xC0000090
 | 
				
			||||||
 | 
						status_float_overflow =            0xC0000091
 | 
				
			||||||
 | 
						status_float_stack_check =         0xC0000092
 | 
				
			||||||
 | 
						status_float_underflow =           0xC0000093
 | 
				
			||||||
 | 
						status_integer_divide_by_zero =    0xC0000094
 | 
				
			||||||
 | 
						status_integer_overflow =          0xC0000095
 | 
				
			||||||
 | 
						status_privileged_instruction =    0xC0000096
 | 
				
			||||||
 | 
						status_stack_overflow =            0xC00000FD
 | 
				
			||||||
 | 
						status_dll_not_found =             0xC0000135
 | 
				
			||||||
 | 
						status_ordinal_not_found =         0xC0000138
 | 
				
			||||||
 | 
						status_entrypoint_not_found =      0xC0000139
 | 
				
			||||||
 | 
						status_control_c_exit =            0xC000013A
 | 
				
			||||||
 | 
						status_dll_init_failed =           0xC0000142
 | 
				
			||||||
 | 
						status_float_multiple_faults =     0xC00002B4
 | 
				
			||||||
 | 
						status_float_multiple_traps =      0xC00002B5
 | 
				
			||||||
 | 
						status_reg_nat_consumption =       0xC00002C9
 | 
				
			||||||
 | 
						status_heap_corruption =           0xC0000374
 | 
				
			||||||
 | 
						status_stack_buffer_overrun =      0xC0000409
 | 
				
			||||||
 | 
						status_invalid_cruntime_parameter = 0xC0000417
 | 
				
			||||||
 | 
						status_assertion_failure =         0xC0000420
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										24
									
								
								vlib/os/os.v
								
								
								
								
							
							
						
						
									
										24
									
								
								vlib/os/os.v
								
								
								
								
							| 
						 | 
					@ -787,6 +787,30 @@ pub fn get_raw_line() string {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn get_raw_stdin() []byte {
 | 
				
			||||||
 | 
						$if windows {
 | 
				
			||||||
 | 
							unsafe {
 | 
				
			||||||
 | 
								block_bytes := 512
 | 
				
			||||||
 | 
								mut buf := malloc(block_bytes)
 | 
				
			||||||
 | 
								h_input := C.GetStdHandle(std_input_handle)
 | 
				
			||||||
 | 
								mut bytes_read := 0
 | 
				
			||||||
 | 
								mut offset := 0
 | 
				
			||||||
 | 
								for {
 | 
				
			||||||
 | 
									pos := buf + offset
 | 
				
			||||||
 | 
									res := C.ReadFile(h_input, pos, block_bytes, &bytes_read, 0)
 | 
				
			||||||
 | 
									if !res {
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									offset += bytes_read
 | 
				
			||||||
 | 
									buf = v_realloc(buf, offset + block_bytes + (block_bytes-bytes_read))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return array{element_size: 1 data: voidptr(buf) len: offset cap: offset }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} $else {
 | 
				
			||||||
 | 
							panic('get_raw_stdin not implemented on this platform...')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn get_lines() []string {
 | 
					pub fn get_lines() []string {
 | 
				
			||||||
	mut line := ''
 | 
						mut line := ''
 | 
				
			||||||
	mut inputstr := []string{}
 | 
						mut inputstr := []string{}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -311,3 +311,38 @@ pub fn (mut f File) close() {
 | 
				
			||||||
	C.fflush(f.cfile)
 | 
						C.fflush(f.cfile)
 | 
				
			||||||
	C.fclose(f.cfile)
 | 
						C.fclose(f.cfile)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct ExceptionRecord {
 | 
				
			||||||
 | 
					pub:
 | 
				
			||||||
 | 
						// status_ constants
 | 
				
			||||||
 | 
						code u32
 | 
				
			||||||
 | 
						flags u32
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						record &ExceptionRecord
 | 
				
			||||||
 | 
						address voidptr
 | 
				
			||||||
 | 
						param_count u32
 | 
				
			||||||
 | 
						// params []voidptr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct ContextRecord {
 | 
				
			||||||
 | 
						// TODO
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct ExceptionPointers {
 | 
				
			||||||
 | 
					pub:
 | 
				
			||||||
 | 
						exception_record &ExceptionRecord
 | 
				
			||||||
 | 
						context_record &ContextRecord
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub type VectoredExceptionHandler fn(&ExceptionPointers)u32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is defined in builtin because we use vectored exception handling
 | 
				
			||||||
 | 
					// for our unhandled exception handler on windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// As a result this definition is commented out to prevent
 | 
				
			||||||
 | 
					// duplicate definitions from displeasing the compiler
 | 
				
			||||||
 | 
					// fn C.AddVectoredExceptionHandler(u32, VectoredExceptionHandler)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn add_vectored_exception_handler(first bool, handler VectoredExceptionHandler) {
 | 
				
			||||||
 | 
						C.AddVectoredExceptionHandler(u32(first), handler)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,8 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	fn_start_pos := g.out.len
 | 
						fn_start_pos := g.out.len
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mut msvc_attrs := ''
 | 
				
			||||||
	match g.attr {
 | 
						match g.attr {
 | 
				
			||||||
		'inline' {
 | 
							'inline' {
 | 
				
			||||||
			g.write('inline ')
 | 
								g.write('inline ')
 | 
				
			||||||
| 
						 | 
					@ -95,6 +97,14 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
 | 
				
			||||||
		'_pure' {
 | 
							'_pure' {
 | 
				
			||||||
			g.write('__attribute__((const)) ')
 | 
								g.write('__attribute__((const)) ')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// windows attributes (msvc/mingw)
 | 
				
			||||||
 | 
							// prefixed by windows to indicate they're for advanced users only and not really supported by V.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							'windows_stdcall' {
 | 
				
			||||||
 | 
								msvc_attrs += '__stdcall '
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			// nothing but keep V happy
 | 
								// nothing but keep V happy
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -174,8 +184,8 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
 | 
				
			||||||
				g.write('static ')
 | 
									g.write('static ')
 | 
				
			||||||
				g.definitions.write('static ')
 | 
									g.definitions.write('static ')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			g.definitions.write('$type_name ${name}(')
 | 
								g.definitions.write('$type_name $msvc_attrs ${name}(')
 | 
				
			||||||
			g.write('$type_name ${name}(')
 | 
								g.write('$type_name $msvc_attrs ${name}(')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fargs, fargtypes := g.fn_args(it.args, it.is_variadic)
 | 
							fargs, fargtypes := g.fn_args(it.args, it.is_variadic)
 | 
				
			||||||
		if it.no_body || (g.pref.use_cache && it.is_builtin) {
 | 
							if it.no_body || (g.pref.use_cache && it.is_builtin) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue