cgen: support a `[_naked]` fn attribute (#10418)
parent
7878bad95e
commit
6576d876fc
|
@ -7260,7 +7260,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
|||
&& (node.is_method || node.name !in ['panic', 'exit']) {
|
||||
if c.inside_anon_fn {
|
||||
c.error('missing return at the end of an anonymous function', node.pos)
|
||||
} else {
|
||||
} else if !node.attrs.contains('_naked') {
|
||||
c.error('missing return at end of function `$node.name`', node.pos)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -332,7 +332,8 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
|||
} else {
|
||||
g.defer_stmts = []
|
||||
}
|
||||
if node.return_type != ast.void_type && node.stmts.len > 0 && node.stmts.last() !is ast.Return {
|
||||
if node.return_type != ast.void_type && node.stmts.len > 0 && node.stmts.last() !is ast.Return
|
||||
&& !node.attrs.contains('_naked') {
|
||||
default_expr := g.type_default(node.return_type)
|
||||
// TODO: perf?
|
||||
if default_expr == '{0}' {
|
||||
|
@ -1354,6 +1355,9 @@ fn (mut g Gen) write_fn_attrs(attrs []ast.Attr) string {
|
|||
// repeated invocations of the function with the same argument values.
|
||||
g.write('__attribute__((const)) ')
|
||||
}
|
||||
'_naked' {
|
||||
g.write('__attribute__((naked)) ')
|
||||
}
|
||||
'windows_stdcall' {
|
||||
// windows attributes (msvc/mingw)
|
||||
// prefixed by windows to indicate they're for advanced users only and not really supported by V.
|
||||
|
|
|
@ -342,7 +342,8 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
short_fn_name := name
|
||||
is_main := short_fn_name == 'main' && p.mod == 'main'
|
||||
mut is_test := (short_fn_name.starts_with('test_') || short_fn_name.starts_with('testsuite_'))
|
||||
&& (p.file_base.ends_with('_test.v') || p.file_base.ends_with('_test.vv'))
|
||||
&& (p.file_base.ends_with('_test.v')
|
||||
|| p.file_base.all_before_last('.v').all_before_last('.').ends_with('_test'))
|
||||
|
||||
// Register
|
||||
if is_method {
|
||||
|
|
|
@ -900,7 +900,7 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
|||
p.check(.name)
|
||||
}
|
||||
// dots are part of instructions for some riscv extensions
|
||||
if arch in [.rv32, .rv64] {
|
||||
if arch in [.rv32, .rv64, .amd64] {
|
||||
for p.tok.kind == .dot {
|
||||
name += '.'
|
||||
p.next()
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[_naked]
|
||||
fn naked_fn() {
|
||||
asm amd64 {
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
mov rsp, rbp
|
||||
pop rbp
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
fn test_naked_attr() {
|
||||
naked_fn()
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
[_naked]
|
||||
fn naked_fn() {
|
||||
asm i386 {
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
fn test_naked_attr() {
|
||||
naked_fn()
|
||||
}
|
Loading…
Reference in New Issue