Skip to content

Commit

Permalink
native, builtin, ast: handle ast.HashStmt correctly and reduce macr…
Browse files Browse the repository at this point in the history
…o usage in `builtin` (vlang#19498)
  • Loading branch information
Spydr06 authored and Wertzui123 committed Oct 8, 2023
1 parent bc818ae commit 79f93e6
Show file tree
Hide file tree
Showing 18 changed files with 277 additions and 130 deletions.
4 changes: 3 additions & 1 deletion vlib/builtin/backtraces.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ pub fn print_backtrace() {
$if freestanding {
println(bare_backtrace())
} $else {
$if tinyc {
$if native {
// TODO: native backtrace solution
} $else $if tinyc {
C.tcc_backtrace(c'Backtrace')
} $else {
// NOTE: TCC doesn't have the unwind library
Expand Down
5 changes: 4 additions & 1 deletion vlib/builtin/backtraces_nix.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
eprintln('Some libc implementations like musl simply do not provide it.')
return false
}
$if no_backtrace ? {
$if native {
eprintln('native backend does not support backtraces yet.')
return false
} $else $if no_backtrace ? {
return false
} $else {
$if linux && !freestanding {
Expand Down
2 changes: 1 addition & 1 deletion vlib/builtin/backtraces_windows.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ fn print_backtrace_skipping_top_frames_mingw(skipframes int) bool {
fn C.tcc_backtrace(fmt &char) int

fn print_backtrace_skipping_top_frames_tcc(skipframes int) bool {
$if tinyc {
$if tinyc && !native {
$if no_backtrace ? {
eprintln('backtraces are disabled')
return false
Expand Down
8 changes: 6 additions & 2 deletions vlib/builtin/builtin.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ fn panic_debug(line_no int, file string, mod string, fn_name string, s string) {
eprintln(' file: ${file}:${line_no}')
eprintln(' v hash: ${vcommithash()}')
eprintln('=========================================')
$if exit_after_panic_message ? {
$if native {
C.exit(1) // TODO: native backtraces
} $else $if exit_after_panic_message ? {
C.exit(1)
} $else $if no_backtrace ? {
C.exit(1)
Expand Down Expand Up @@ -107,7 +109,9 @@ pub fn panic(s string) {
eprint('V panic: ')
eprintln(s)
eprintln('v hash: ${vcommithash()}')
$if exit_after_panic_message ? {
$if native {
C.exit(1) // TODO: native backtraces
} $else $if exit_after_panic_message ? {
C.exit(1)
} $else $if no_backtrace ? {
C.exit(1)
Expand Down
29 changes: 23 additions & 6 deletions vlib/builtin/builtin_windows.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module builtin
// g_original_codepage - used to restore the original windows console code page when exiting
__global g_original_codepage = u32(0)

// utf8 to stdout needs C.SetConsoleOutputCP(C.CP_UTF8)
// utf8 to stdout needs C.SetConsoleOutputCP(cp_utf8)
fn C.GetConsoleOutputCP() u32

fn C.SetConsoleOutputCP(wCodePageID u32) bool
Expand All @@ -23,13 +23,21 @@ fn is_terminal(fd int) int {
return int(mode)
}

const (
std_output_handle = -11
std_error_handle = -12
enable_processed_output = 1
enable_wrap_at_eol_output = 2
evable_virtual_terminal_processing = 4
)

fn builtin_init() {
g_original_codepage = C.GetConsoleOutputCP()
C.SetConsoleOutputCP(C.CP_UTF8)
C.SetConsoleOutputCP(cp_utf8)
C.atexit(restore_codepage)
if is_terminal(1) > 0 {
C.SetConsoleMode(C.GetStdHandle(C.STD_OUTPUT_HANDLE), C.ENABLE_PROCESSED_OUTPUT | C.ENABLE_WRAP_AT_EOL_OUTPUT | 0x0004) // enable_virtual_terminal_processing
C.SetConsoleMode(C.GetStdHandle(C.STD_ERROR_HANDLE), C.ENABLE_PROCESSED_OUTPUT | C.ENABLE_WRAP_AT_EOL_OUTPUT | 0x0004) // enable_virtual_terminal_processing
C.SetConsoleMode(C.GetStdHandle(std_output_handle), enable_processed_output | enable_wrap_at_eol_output | evable_virtual_terminal_processing)
C.SetConsoleMode(C.GetStdHandle(std_error_handle), enable_processed_output | enable_wrap_at_eol_output | evable_virtual_terminal_processing)
unsafe {
C.setbuf(C.stdout, 0)
C.setbuf(C.stderr, 0)
Expand Down Expand Up @@ -110,15 +118,24 @@ fn break_if_debugger_attached() {
}
}

const (
format_message_allocate_buffer = 0x00000100
format_message_argument_array = 0x00002000
format_message_from_hmodule = 0x00000800
format_message_from_string = 0x00000400
format_message_from_system = 0x00001000
format_message_ignore_inserts = 0x00000200
)

// return an error message generated from WinAPI's `LastError`
pub fn winapi_lasterr_str() string {
err_msg_id := C.GetLastError()
if err_msg_id == 8 {
// handle this case special since `FormatMessage()` might not work anymore
// handle this case special since `FormatMessageW()` might not work anymore
return 'insufficient memory'
}
mut msgbuf := &u16(0)
res := C.FormatMessage(C.FORMAT_MESSAGE_ALLOCATE_BUFFER | C.FORMAT_MESSAGE_FROM_SYSTEM | C.FORMAT_MESSAGE_IGNORE_INSERTS,
res := C.FormatMessageW(format_message_allocate_buffer | format_message_from_system | format_message_ignore_inserts,
0, err_msg_id, 0, voidptr(&msgbuf), 0, 0)
err_msg := if res == 0 {
'Win-API error ${err_msg_id}'
Expand Down
2 changes: 1 addition & 1 deletion vlib/builtin/cfns.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ fn C.FindClose(hFindFile voidptr)
// macro
fn C.MAKELANGID(lgid voidptr, srtid voidptr) int

fn C.FormatMessage(dwFlags u32, lpSource voidptr, dwMessageId u32, dwLanguageId u32, lpBuffer voidptr, nSize u32, arguments ...voidptr) u32
fn C.FormatMessageW(dwFlags u32, lpSource voidptr, dwMessageId u32, dwLanguageId u32, lpBuffer voidptr, nSize u32, arguments ...voidptr) u32

fn C.CloseHandle(voidptr) int

Expand Down
37 changes: 28 additions & 9 deletions vlib/builtin/float.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ module builtin
// [if !nofloat]
import strconv

#include <float.h>
$if !native {
#include <float.h>
}

/*
-----------------------------------
----- f64 to string functions -----
Expand Down Expand Up @@ -185,10 +188,18 @@ fn f64_min(a f64, b f64) f64 {
pub fn (a f32) eq_epsilon(b f32) bool {
hi := f32_max(f32_abs(a), f32_abs(b))
delta := f32_abs(a - b)
if hi > f32(1.0) {
return delta <= hi * (4 * f32(C.FLT_EPSILON))
} else {
return (1 / (4 * f32(C.FLT_EPSILON))) * delta <= hi
$if native {
if hi > f32(1.0) {
return delta <= hi * (4 * 1e-5)
} else {
return (1 / (4 * 1e-5)) * delta <= hi
}
} $else {
if hi > f32(1.0) {
return delta <= hi * (4 * f32(C.FLT_EPSILON))
} else {
return (1 / (4 * f32(C.FLT_EPSILON))) * delta <= hi
}
}
}

Expand All @@ -199,9 +210,17 @@ pub fn (a f32) eq_epsilon(b f32) bool {
pub fn (a f64) eq_epsilon(b f64) bool {
hi := f64_max(f64_abs(a), f64_abs(b))
delta := f64_abs(a - b)
if hi > 1.0 {
return delta <= hi * (4 * f64(C.DBL_EPSILON))
} else {
return (1 / (4 * f64(C.DBL_EPSILON))) * delta <= hi
$if native {
if hi > 1.0 {
return delta <= hi * (4 * 1e-9)
} else {
return (1 / (4 * 1e-9)) * delta <= hi
}
} $else {
if hi > 1.0 {
return delta <= hi * (4 * f64(C.DBL_EPSILON))
} else {
return (1 / (4 * f64(C.DBL_EPSILON))) * delta <= hi
}
}
}
6 changes: 4 additions & 2 deletions vlib/clipboard/clipboard_windows.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,16 @@ pub fn (mut cb Clipboard) free() {
cb.foo = 0
}

const cp_utf8 = 65001

// the string.to_wide doesn't work with SetClipboardData, don't know why
fn to_wide(text string) C.HGLOBAL {
len_required := C.MultiByteToWideChar(C.CP_UTF8, C.MB_ERR_INVALID_CHARS, text.str,
len_required := C.MultiByteToWideChar(clipboard.cp_utf8, C.MB_ERR_INVALID_CHARS, text.str,
text.len + 1, C.NULL, 0)
buf := C.GlobalAlloc(C.GMEM_MOVEABLE, i64(sizeof(u16)) * len_required)
if buf != C.HGLOBAL(C.NULL) {
mut locked := &u16(C.GlobalLock(buf))
C.MultiByteToWideChar(C.CP_UTF8, C.MB_ERR_INVALID_CHARS, text.str, text.len + 1,
C.MultiByteToWideChar(clipboard.cp_utf8, C.MB_ERR_INVALID_CHARS, text.str, text.len + 1,
locked, len_required)
unsafe {
locked[len_required - 1] = u16(0)
Expand Down
6 changes: 3 additions & 3 deletions vlib/os/os_windows.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ pub fn get_module_filename(handle HANDLE) !string {
return string_from_wide2(buf, sz)
}
else {
// Must handled with GetLastError and converted by FormatMessage
// Must handled with GetLastError and converted by FormatMessageW
return error('Cannot get file name from handle')
}
}
Expand All @@ -231,7 +231,7 @@ pub fn get_module_filename(handle HANDLE) !string {
panic('this should be unreachable') // TODO remove unreachable after loop
}

// Ref - https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagea#parameters
// Ref - https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-FormatMessageWa#parameters
const (
format_message_allocate_buffer = 0x00000100
format_message_argument_array = 0x00002000
Expand Down Expand Up @@ -261,7 +261,7 @@ fn ptr_win_get_error_msg(code u32) voidptr {
if code > u32(os.max_error_code) {
return buf
}
C.FormatMessage(os.format_message_allocate_buffer | os.format_message_from_system | os.format_message_ignore_inserts,
C.FormatMessageW(os.format_message_allocate_buffer | os.format_message_from_system | os.format_message_ignore_inserts,
0, code, 0, voidptr(&buf), 0, 0)
return buf
}
Expand Down
57 changes: 35 additions & 22 deletions vlib/v/eval/eval.v
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,38 @@ pub fn (mut e Eval) register_symbol_stmts(stmts []ast.Stmt, mod string, file str
}
}

pub fn (mut e Eval) comptime_cond(cond ast.Expr) bool {
match cond {
ast.Ident {
match cond.name {
'native' {
return false
}
'windows' {
return e.pref.os == .windows
}
else {
e.error('unknown compile time if')
}
}
}
ast.PrefixExpr {
match cond.op {
.not {
return !e.comptime_cond(cond.right)
}
else {
e.error('unsupported prefix expression')
}
}
}
else {
e.error('unsupported expression')
}
}
return false
}

pub fn (mut e Eval) register_symbol(stmt ast.Stmt, mod string, file string) {
match stmt {
ast.Module {
Expand Down Expand Up @@ -226,28 +258,9 @@ pub fn (mut e Eval) register_symbol(stmt ast.Stmt, mod string, file string) {
e.error('only comptime ifs are allowed in top level')
}
for i, branch in x.branches {
mut do_if := false
println('branch:${branch}')
cond := branch.cond
match cond {
ast.Ident {
match cond.name {
'windows' {
do_if = e.pref.os == .windows
}
else {
e.error('unknown compile time if')
}
}
do_if = do_if || x.branches.len == i + 1
if do_if {
e.register_symbol_stmts(branch.stmts, mod, file)
break
}
}
else {
e.error('unsupported expression')
}
if e.comptime_cond(branch.cond) || x.branches.len == i + 1 {
e.register_symbol_stmts(branch.stmts, mod, file)
break
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions vlib/v/gen/native/amd64.v
Original file line number Diff line number Diff line change
Expand Up @@ -2125,9 +2125,9 @@ fn (mut c Amd64) assign_right_expr(node ast.AssignStmt, i int, right ast.Expr, n
}
ast.IfExpr {
if right.is_comptime {
if stmts := c.g.comptime_conditional(right) {
for j, stmt in stmts {
if j + 1 != stmts.len {
if branch := c.g.comptime_conditional(right) {
for j, stmt in branch.stmts {
if j + 1 != branch.stmts.len {
c.g.stmt(stmt)
continue
}
Expand Down
16 changes: 14 additions & 2 deletions vlib/v/gen/native/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,33 @@ fn (mut g Gen) comptime_at(node ast.AtExpr) string {
return node.val
}

fn (mut g Gen) comptime_conditional(node ast.IfExpr) ?[]ast.Stmt {
fn (mut g Gen) comptime_conditional(node ast.IfExpr) ?ast.IfBranch {
if node.branches.len == 0 {
return none
}

for i, branch in node.branches {
// handle $else branch, which does not have a condition
if (node.has_else && i + 1 == node.branches.len) || g.comptime_is_truthy(branch.cond) {
return branch.stmts
return branch
}
}

return none
}

fn (mut g Gen) should_emit_hash_stmt(node ast.HashStmt) bool {
if node.ct_conds.len == 0 {
return true
}

mut emit := true
for cond in node.ct_conds {
emit = emit && g.comptime_is_truthy(cond)
}
return emit
}

fn (mut g Gen) comptime_is_truthy(cond ast.Expr) bool {
match cond {
ast.BoolLiteral {
Expand Down
6 changes: 4 additions & 2 deletions vlib/v/gen/native/elf.v
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ pub fn (mut g Gen) find_o_path(fname string) string {
}

pub fn (mut g Gen) get_lpaths() string {
lpaths := match g.pref.arch {
mut lpaths := match g.pref.arch {
.amd64 {
g.prepend_vobjpath(['/usr/lib/x86_64-linux-gnu', '/usr/lib64', '/lib64', '/usr/lib',
'/lib'])
Expand All @@ -932,6 +932,7 @@ pub fn (mut g Gen) get_lpaths() string {
['/dev/null']
}
}
lpaths << g.linker_include_paths
return lpaths.map('-L${it}').join(' ')
}

Expand Down Expand Up @@ -960,7 +961,7 @@ pub fn (mut g Gen) link_elf_file(obj_file string) {
else { '/dev/null' }
}

linker_args := [
mut linker_args := [
'-v',
lpaths,
'-m ${arch}',
Expand All @@ -975,6 +976,7 @@ pub fn (mut g Gen) link_elf_file(obj_file string) {
'${obj_file}',
'-o ${g.out_name}',
]
linker_args << g.linker_libs
slinker_args := linker_args.join(' ')

mut ld := 'ld'
Expand Down
Loading

0 comments on commit 79f93e6

Please sign in to comment.