mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
native, builder: enable processing of .v files in the builtin
module (for now most functions there are blacklisted) (#18735)
This commit is contained in:
parent
0ce3e46823
commit
f3942417c4
@ -13,9 +13,16 @@ pub fn start() {
|
||||
}
|
||||
|
||||
pub fn compile_native(mut b builder.Builder) {
|
||||
// v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare'))
|
||||
files := [b.pref.path]
|
||||
if b.pref.is_verbose {
|
||||
println('all .v files before:')
|
||||
}
|
||||
mut files := b.get_builtin_files()
|
||||
files << b.get_user_files()
|
||||
b.set_module_lookup_paths()
|
||||
if b.pref.is_verbose {
|
||||
println('all .v files:')
|
||||
println(files)
|
||||
}
|
||||
build_native(mut b, files, b.pref.out_name)
|
||||
}
|
||||
|
||||
|
@ -2560,7 +2560,7 @@ fn (mut c Amd64) multi_assign_stmt(node ast.AssignStmt) {
|
||||
})
|
||||
}
|
||||
else {
|
||||
c.g.n_error('Unsupported assign instruction')
|
||||
c.g.n_error('Unsupported assign instruction (${node.op})')
|
||||
}
|
||||
}
|
||||
} else if left_type.is_pure_float() {
|
||||
@ -2640,7 +2640,7 @@ fn (mut c Amd64) assign_stmt(node ast.AssignStmt) {
|
||||
})
|
||||
}
|
||||
else {
|
||||
c.g.n_error('Unsupported assign instruction')
|
||||
c.g.n_error('Unsupported assign instruction (${node.op})')
|
||||
}
|
||||
}
|
||||
} else if typ.is_pure_float() {
|
||||
@ -2679,7 +2679,7 @@ fn (mut c Amd64) assign_stmt(node ast.AssignStmt) {
|
||||
}
|
||||
} else {
|
||||
if node.op !in [.assign, .decl_assign] {
|
||||
c.g.n_error('Unsupported assign instruction')
|
||||
c.g.n_error('Unsupported assign instruction (${node.op})')
|
||||
}
|
||||
ts := c.g.table.sym(typ)
|
||||
match ts.kind {
|
||||
|
37
vlib/v/gen/native/blacklist.v
Normal file
37
vlib/v/gen/native/blacklist.v
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2019-2023 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
module native
|
||||
|
||||
// this is a TEMPORARY system used to enable/disable parts of the
|
||||
// builtin module until more of `builtin` is supported by native
|
||||
|
||||
/*
|
||||
already compiling functions:
|
||||
string.+
|
||||
string.clone
|
||||
string.free
|
||||
ArrayFlags.set
|
||||
ArrayFlags.clear
|
||||
u8.vstring_with_len
|
||||
Error.msg
|
||||
Error.code
|
||||
MessageError.code
|
||||
MessageError.free
|
||||
u64.hex
|
||||
VAssertMetaInfo.free"
|
||||
__new_array
|
||||
new_array_from_c_array
|
||||
new_array_from_c_array_no_alloc
|
||||
...
|
||||
*/
|
||||
|
||||
// false: whitelist function
|
||||
// true: blacklist function
|
||||
const whitelist = {
|
||||
'main.main': false
|
||||
}
|
||||
|
||||
fn (g Gen) is_blacklisted(name string, is_builtin bool) bool {
|
||||
return native.whitelist[name] or { is_builtin }
|
||||
}
|
@ -116,6 +116,9 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||
ast.TypeOf {
|
||||
g.gen_typeof_expr(node, false)
|
||||
}
|
||||
ast.SizeOf {
|
||||
g.gen_sizeof_expr(node)
|
||||
}
|
||||
else {
|
||||
g.n_error('expr: unhandled node type: ${node.type_name()}')
|
||||
}
|
||||
@ -283,6 +286,14 @@ fn (mut g Gen) gen_typeof_expr(node ast.TypeOf, newline bool) {
|
||||
g.code_gen.learel(g.code_gen.main_reg(), g.allocate_string('${str}${nl}', 3, .rel32))
|
||||
}
|
||||
|
||||
fn (mut g Gen) gen_sizeof_expr(node ast.SizeOf) {
|
||||
ts := g.table.sym(node.typ)
|
||||
if ts.language == .v && ts.kind in [.placeholder, .any] {
|
||||
g.v_error('unknown type `${ts.name}`', node.pos)
|
||||
}
|
||||
g.code_gen.mov64(g.code_gen.main_reg(), g.get_type_size(node.typ))
|
||||
}
|
||||
|
||||
fn (mut g Gen) gen_print_from_expr(expr ast.Expr, typ ast.Type, name string) {
|
||||
newline := name in ['println', 'eprintln']
|
||||
fd := if name in ['eprint', 'eprintln'] { 2 } else { 1 }
|
||||
|
@ -128,6 +128,17 @@ mut:
|
||||
|
||||
type Register = Amd64Register | Arm64Register
|
||||
|
||||
fn (r Register) str() string {
|
||||
return match r {
|
||||
Amd64Register {
|
||||
'${r as Amd64Register}'
|
||||
}
|
||||
Arm64Register {
|
||||
'${r as Arm64Register}'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum RelocType {
|
||||
rel8
|
||||
rel16
|
||||
@ -322,6 +333,7 @@ pub fn gen(files []&ast.File, table &ast.Table, out_name string, pref_ &pref.Pre
|
||||
structs: []Struct{len: table.type_symbols.len}
|
||||
eval: eval.new_eval(table, pref_)
|
||||
}
|
||||
|
||||
g.code_gen.g = g
|
||||
g.generate_header()
|
||||
g.init_builtins()
|
||||
@ -976,10 +988,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
||||
} else {
|
||||
node.name
|
||||
}
|
||||
if node.no_body || !g.is_used_by_main(node) {
|
||||
if g.pref.is_verbose {
|
||||
println(term.italic(term.green('\n-> skipping unused function `${name}`')))
|
||||
}
|
||||
if node.no_body || !g.is_used_by_main(node) || g.is_blacklisted(name, node.is_builtin) {
|
||||
return
|
||||
}
|
||||
if g.pref.is_verbose {
|
||||
@ -988,9 +997,6 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
||||
if node.is_deprecated {
|
||||
g.warning('fn_decl: ${name} is deprecated', node.pos)
|
||||
}
|
||||
if node.is_builtin {
|
||||
g.warning('fn_decl: ${name} is builtin', node.pos)
|
||||
}
|
||||
|
||||
g.stack_var_pos = 0
|
||||
g.stack_depth = 0
|
||||
|
@ -70,15 +70,22 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
}
|
||||
ast.HashStmt {
|
||||
words := node.val.split(' ')
|
||||
mut unsupported := false
|
||||
for word in words {
|
||||
if word.len != 2 {
|
||||
g.n_error('opcodes format: xx xx xx xx\nhash statements are not allowed with the native backend, use the C backend for extended C interoperability.')
|
||||
unsupported = true
|
||||
break
|
||||
}
|
||||
b := unsafe { C.strtol(&char(word.str), 0, 16) }
|
||||
// b := word.u8()
|
||||
// println('"$word" $b')
|
||||
g.write8(b)
|
||||
}
|
||||
|
||||
if unsupported {
|
||||
g.warning('opcodes format: xx xx xx xx\nhash statements are not allowed with the native backend, use the C backend for extended C interoperability.',
|
||||
node.pos)
|
||||
}
|
||||
}
|
||||
ast.Module {}
|
||||
ast.Return {
|
||||
@ -90,10 +97,14 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
ast.AssertStmt {
|
||||
g.code_gen.gen_assert(node)
|
||||
}
|
||||
ast.GlobalDecl {
|
||||
g.warning('globals are not supported yet', node.pos)
|
||||
}
|
||||
ast.Import {} // do nothing here
|
||||
ast.StructDecl {}
|
||||
ast.EnumDecl {}
|
||||
ast.TypeDecl {}
|
||||
ast.InterfaceDecl {}
|
||||
else {
|
||||
eprintln('native.stmt(): bad node: ' + node.type_name())
|
||||
}
|
||||
@ -119,9 +130,15 @@ fn (mut g Gen) gen_forc_stmt(node ast.ForCStmt) {
|
||||
.gt {
|
||||
jump_addr = g.code_gen.cjmp(.jle)
|
||||
}
|
||||
.ge {
|
||||
jump_addr = g.code_gen.cjmp(.jl)
|
||||
}
|
||||
.lt {
|
||||
jump_addr = g.code_gen.cjmp(.jge)
|
||||
}
|
||||
.le {
|
||||
jump_addr = g.code_gen.cjmp(.jg)
|
||||
}
|
||||
else {
|
||||
g.n_error('unsupported conditional in for-c loop')
|
||||
}
|
||||
|
@ -1,38 +1,47 @@
|
||||
// because of an issue with checker, all C.* functions have to be declared first
|
||||
fn C.isalpha(c int) int
|
||||
fn C.isdigit(c int) int
|
||||
fn C.malloc(n u64) voidptr
|
||||
fn C.free(ptr voidptr)
|
||||
fn C.memset(ptr voidptr, c int, n u64) voidptr
|
||||
|
||||
fn main() {
|
||||
charutil()
|
||||
memory()
|
||||
}
|
||||
|
||||
fn charutil() {
|
||||
// only linux supports linking right now
|
||||
$if linux {
|
||||
// ascii for `V`
|
||||
v_is_alpha := C.isalpha(86)
|
||||
if v_is_alpha != 0 {
|
||||
println('ok 1')
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
assert v_is_alpha != 0
|
||||
|
||||
null_is_alpha := C.isalpha(0)
|
||||
if null_is_alpha == 0 {
|
||||
println('ok 2')
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
assert null_is_alpha == 0
|
||||
|
||||
// ascii for `3`
|
||||
three_is_digit := C.isdigit(51)
|
||||
if three_is_digit != 0 {
|
||||
println('ok 3')
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
} $else {
|
||||
println('ok 1')
|
||||
println('ok 2')
|
||||
println('ok 3')
|
||||
assert three_is_digit != 0
|
||||
}
|
||||
}
|
||||
|
||||
fn memory() {
|
||||
$if linux {
|
||||
// allocate some memory
|
||||
buf := &int(C.malloc(100))
|
||||
assert buf != unsafe { nil }
|
||||
|
||||
C.memset(buf, 0, 100)
|
||||
assert *buf == 0
|
||||
|
||||
unsafe {
|
||||
*buf = 123456
|
||||
*(buf + sizeof(int)) = 100
|
||||
}
|
||||
|
||||
assert *buf == 123456
|
||||
assert *(buf + sizeof(int)) == 100
|
||||
C.free(voidptr(buf))
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
ok 1
|
||||
ok 2
|
||||
ok 3
|
Loading…
Reference in New Issue
Block a user