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) {
|
pub fn compile_native(mut b builder.Builder) {
|
||||||
// v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare'))
|
if b.pref.is_verbose {
|
||||||
files := [b.pref.path]
|
println('all .v files before:')
|
||||||
|
}
|
||||||
|
mut files := b.get_builtin_files()
|
||||||
|
files << b.get_user_files()
|
||||||
b.set_module_lookup_paths()
|
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)
|
build_native(mut b, files, b.pref.out_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2560,7 +2560,7 @@ fn (mut c Amd64) multi_assign_stmt(node ast.AssignStmt) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.g.n_error('Unsupported assign instruction')
|
c.g.n_error('Unsupported assign instruction (${node.op})')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if left_type.is_pure_float() {
|
} else if left_type.is_pure_float() {
|
||||||
@ -2640,7 +2640,7 @@ fn (mut c Amd64) assign_stmt(node ast.AssignStmt) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.g.n_error('Unsupported assign instruction')
|
c.g.n_error('Unsupported assign instruction (${node.op})')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if typ.is_pure_float() {
|
} else if typ.is_pure_float() {
|
||||||
@ -2679,7 +2679,7 @@ fn (mut c Amd64) assign_stmt(node ast.AssignStmt) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if node.op !in [.assign, .decl_assign] {
|
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)
|
ts := c.g.table.sym(typ)
|
||||||
match ts.kind {
|
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 {
|
ast.TypeOf {
|
||||||
g.gen_typeof_expr(node, false)
|
g.gen_typeof_expr(node, false)
|
||||||
}
|
}
|
||||||
|
ast.SizeOf {
|
||||||
|
g.gen_sizeof_expr(node)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
g.n_error('expr: unhandled node type: ${node.type_name()}')
|
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))
|
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) {
|
fn (mut g Gen) gen_print_from_expr(expr ast.Expr, typ ast.Type, name string) {
|
||||||
newline := name in ['println', 'eprintln']
|
newline := name in ['println', 'eprintln']
|
||||||
fd := if name in ['eprint', 'eprintln'] { 2 } else { 1 }
|
fd := if name in ['eprint', 'eprintln'] { 2 } else { 1 }
|
||||||
|
@ -128,6 +128,17 @@ mut:
|
|||||||
|
|
||||||
type Register = Amd64Register | Arm64Register
|
type Register = Amd64Register | Arm64Register
|
||||||
|
|
||||||
|
fn (r Register) str() string {
|
||||||
|
return match r {
|
||||||
|
Amd64Register {
|
||||||
|
'${r as Amd64Register}'
|
||||||
|
}
|
||||||
|
Arm64Register {
|
||||||
|
'${r as Arm64Register}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum RelocType {
|
enum RelocType {
|
||||||
rel8
|
rel8
|
||||||
rel16
|
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}
|
structs: []Struct{len: table.type_symbols.len}
|
||||||
eval: eval.new_eval(table, pref_)
|
eval: eval.new_eval(table, pref_)
|
||||||
}
|
}
|
||||||
|
|
||||||
g.code_gen.g = g
|
g.code_gen.g = g
|
||||||
g.generate_header()
|
g.generate_header()
|
||||||
g.init_builtins()
|
g.init_builtins()
|
||||||
@ -976,10 +988,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
|||||||
} else {
|
} else {
|
||||||
node.name
|
node.name
|
||||||
}
|
}
|
||||||
if node.no_body || !g.is_used_by_main(node) {
|
if node.no_body || !g.is_used_by_main(node) || g.is_blacklisted(name, node.is_builtin) {
|
||||||
if g.pref.is_verbose {
|
|
||||||
println(term.italic(term.green('\n-> skipping unused function `${name}`')))
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if g.pref.is_verbose {
|
if g.pref.is_verbose {
|
||||||
@ -988,9 +997,6 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
|||||||
if node.is_deprecated {
|
if node.is_deprecated {
|
||||||
g.warning('fn_decl: ${name} is deprecated', node.pos)
|
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_var_pos = 0
|
||||||
g.stack_depth = 0
|
g.stack_depth = 0
|
||||||
|
@ -70,15 +70,22 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||||||
}
|
}
|
||||||
ast.HashStmt {
|
ast.HashStmt {
|
||||||
words := node.val.split(' ')
|
words := node.val.split(' ')
|
||||||
|
mut unsupported := false
|
||||||
for word in words {
|
for word in words {
|
||||||
if word.len != 2 {
|
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 := unsafe { C.strtol(&char(word.str), 0, 16) }
|
||||||
// b := word.u8()
|
// b := word.u8()
|
||||||
// println('"$word" $b')
|
// println('"$word" $b')
|
||||||
g.write8(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.Module {}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
@ -90,10 +97,14 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||||||
ast.AssertStmt {
|
ast.AssertStmt {
|
||||||
g.code_gen.gen_assert(node)
|
g.code_gen.gen_assert(node)
|
||||||
}
|
}
|
||||||
|
ast.GlobalDecl {
|
||||||
|
g.warning('globals are not supported yet', node.pos)
|
||||||
|
}
|
||||||
ast.Import {} // do nothing here
|
ast.Import {} // do nothing here
|
||||||
ast.StructDecl {}
|
ast.StructDecl {}
|
||||||
ast.EnumDecl {}
|
ast.EnumDecl {}
|
||||||
ast.TypeDecl {}
|
ast.TypeDecl {}
|
||||||
|
ast.InterfaceDecl {}
|
||||||
else {
|
else {
|
||||||
eprintln('native.stmt(): bad node: ' + node.type_name())
|
eprintln('native.stmt(): bad node: ' + node.type_name())
|
||||||
}
|
}
|
||||||
@ -119,9 +130,15 @@ fn (mut g Gen) gen_forc_stmt(node ast.ForCStmt) {
|
|||||||
.gt {
|
.gt {
|
||||||
jump_addr = g.code_gen.cjmp(.jle)
|
jump_addr = g.code_gen.cjmp(.jle)
|
||||||
}
|
}
|
||||||
|
.ge {
|
||||||
|
jump_addr = g.code_gen.cjmp(.jl)
|
||||||
|
}
|
||||||
.lt {
|
.lt {
|
||||||
jump_addr = g.code_gen.cjmp(.jge)
|
jump_addr = g.code_gen.cjmp(.jge)
|
||||||
}
|
}
|
||||||
|
.le {
|
||||||
|
jump_addr = g.code_gen.cjmp(.jg)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
g.n_error('unsupported conditional in for-c loop')
|
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
|
// because of an issue with checker, all C.* functions have to be declared first
|
||||||
fn C.isalpha(c int) int
|
fn C.isalpha(c int) int
|
||||||
fn C.isdigit(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() {
|
fn main() {
|
||||||
charutil()
|
charutil()
|
||||||
|
memory()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn charutil() {
|
fn charutil() {
|
||||||
|
// only linux supports linking right now
|
||||||
$if linux {
|
$if linux {
|
||||||
// ascii for `V`
|
// ascii for `V`
|
||||||
v_is_alpha := C.isalpha(86)
|
v_is_alpha := C.isalpha(86)
|
||||||
if v_is_alpha != 0 {
|
assert v_is_alpha != 0
|
||||||
println('ok 1')
|
|
||||||
} else {
|
|
||||||
assert false
|
|
||||||
}
|
|
||||||
|
|
||||||
null_is_alpha := C.isalpha(0)
|
null_is_alpha := C.isalpha(0)
|
||||||
if null_is_alpha == 0 {
|
assert null_is_alpha == 0
|
||||||
println('ok 2')
|
|
||||||
} else {
|
|
||||||
assert false
|
|
||||||
}
|
|
||||||
|
|
||||||
// ascii for `3`
|
// ascii for `3`
|
||||||
three_is_digit := C.isdigit(51)
|
three_is_digit := C.isdigit(51)
|
||||||
if three_is_digit != 0 {
|
assert three_is_digit != 0
|
||||||
println('ok 3')
|
|
||||||
} else {
|
|
||||||
assert false
|
|
||||||
}
|
|
||||||
} $else {
|
|
||||||
println('ok 1')
|
|
||||||
println('ok 2')
|
|
||||||
println('ok 3')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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