mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
all: add stdcall attribute, unhandled exception handler, get_raw_stdin, v_realloc
This commit is contained in:
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
Block a user