From 754c387d1bd9b6ec3c5905754f6157acca2f3bb9 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 8 Oct 2022 13:14:26 +0300 Subject: [PATCH] cgen,checker: support simple voidptr casts in consts, without delaying the initialisation to _vinit (#15996) --- vlib/dl/dl.v | 2 ++ vlib/dl/dl_nix.c.v | 6 +++++- vlib/dl/rtld_next_test.v | 14 ++++++++++++++ vlib/v/ast/comptime_const_values.v | 22 ++++++++++++++++++++++ vlib/v/checker/comptime.v | 4 ++++ vlib/v/gen/c/cgen.v | 3 +++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 vlib/dl/rtld_next_test.v diff --git a/vlib/dl/dl.v b/vlib/dl/dl.v index 2cb59fbf2..2dbdac9fc 100644 --- a/vlib/dl/dl.v +++ b/vlib/dl/dl.v @@ -4,6 +4,8 @@ pub const version = 1 pub const dl_ext = get_shared_library_extension() +pub const rtld_next = voidptr(-1) + // get_shared_library_extension returns the platform dependent shared library extension // i.e. .dll on windows, .so on most unixes, .dylib on macos. [inline] diff --git a/vlib/dl/dl_nix.c.v b/vlib/dl/dl_nix.c.v index 66c8f6918..595460d5d 100644 --- a/vlib/dl/dl_nix.c.v +++ b/vlib/dl/dl_nix.c.v @@ -38,5 +38,9 @@ pub fn sym(handle voidptr, symbol string) voidptr { // that occurred from a call to one of the `dl` functions, since the last // call to dlerror() pub fn dlerror() string { - return unsafe { cstring_to_vstring(C.dlerror()) } + sptr := C.dlerror() + if sptr == unsafe { nil } { + return '' + } + return unsafe { cstring_to_vstring(sptr) } } diff --git a/vlib/dl/rtld_next_test.v b/vlib/dl/rtld_next_test.v new file mode 100644 index 000000000..5aae237bb --- /dev/null +++ b/vlib/dl/rtld_next_test.v @@ -0,0 +1,14 @@ +import dl + +type RealOpen = fn (charptr, int, int) int + +fn test_rtld_next() { + $if windows { + println('skipping test_rtld_next on windows') + return + } + real_open := RealOpen((dl.sym(dl.rtld_next, 'open'))) + println(ptr_str(real_open)) + assert real_open != unsafe { nil } + assert dl.dlerror() == '' +} diff --git a/vlib/v/ast/comptime_const_values.v b/vlib/v/ast/comptime_const_values.v index 450aeee15..4780b2a21 100644 --- a/vlib/v/ast/comptime_const_values.v +++ b/vlib/v/ast/comptime_const_values.v @@ -13,6 +13,7 @@ pub type ComptTimeConstValue = EmptyExpr | u32 | u64 | u8 + | voidptr pub fn empty_comptime_const_expr() ComptTimeConstValue { return EmptyExpr(0) @@ -42,6 +43,17 @@ pub fn (val ComptTimeConstValue) int() ?int { return none } +pub fn (val ComptTimeConstValue) voidptr() ?voidptr { + match val { + i8, i16, int, i64 { return voidptr(i64(val)) } + u8, u16, u32, u64 { return voidptr(u64(val)) } + rune { return voidptr(u64(val)) } + voidptr { return val } + string, EmptyExpr, f32, f64 {} + } + return none +} + pub fn (val ComptTimeConstValue) i64() ?i64 { match val { i8 { @@ -88,6 +100,9 @@ pub fn (val ComptTimeConstValue) i64() ?i64 { rune { return int(val) } + voidptr { + return i64(val) + } EmptyExpr {} } return none @@ -164,6 +179,9 @@ pub fn (val ComptTimeConstValue) u64() ?u64 { string { return val.u64() } + voidptr { + return u64(val) + } rune {} EmptyExpr {} } @@ -210,6 +228,7 @@ pub fn (val ComptTimeConstValue) f64() ?f64 { string { return val.f64() } + voidptr {} rune {} EmptyExpr {} } @@ -254,6 +273,9 @@ pub fn (val ComptTimeConstValue) string() ?string { string { return val } + voidptr { + return ptr_str(val) + } EmptyExpr {} } return none diff --git a/vlib/v/checker/comptime.v b/vlib/v/checker/comptime.v index 0b4ef8534..a14e8cec7 100644 --- a/vlib/v/checker/comptime.v +++ b/vlib/v/checker/comptime.v @@ -224,6 +224,10 @@ fn (mut c Checker) eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.Comp if expr.typ == ast.f64_type { return cast_expr_value.f64() or { return none } } + if expr.typ == ast.voidptr_type { + ptrvalue := cast_expr_value.voidptr() or { return none } + return ast.ComptTimeConstValue(ptrvalue) + } } ast.InfixExpr { left := c.eval_comptime_const_expr(expr.left, nlevel + 1)? diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 63434baaa..402f271d7 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4716,6 +4716,9 @@ fn (mut g Gen) const_decl_precomputed(mod string, name string, field_name string g.cleanups[mod].writeln('\tstring_free(&$cname);') } } + voidptr { + g.const_decl_write_precomputed(mod, styp, cname, field_name, '(voidptr)(0x$ct_value)') + } ast.EmptyExpr { return false } -- 2.39.5