wrap up -bare

pull/2764/head
Alexander Medvednikov 2019-11-14 10:23:44 +03:00
parent 6eaa2db533
commit 34c4565f7c
7 changed files with 70 additions and 53 deletions

View File

@ -109,6 +109,9 @@ fn (v mut V) cc() {
a << '-shared -fPIC '// -Wl,-z,defs' a << '-shared -fPIC '// -Wl,-z,defs'
v.out_name = v.out_name + '.so' v.out_name = v.out_name + '.so'
} }
if v.pref.is_bare {
a << '-nostdlib $vdir/vlib/os/bare/bare.S'
}
if v.pref.build_mode == .build_module { if v.pref.build_mode == .build_module {
// Create the modules & out directory if it's not there. // Create the modules & out directory if it's not there.
mut out_dir := if v.dir.starts_with('vlib') { mut out_dir := if v.dir.starts_with('vlib') {
@ -279,7 +282,7 @@ start:
return return
} }
*/ */
verror(err) verror(err)
return return
} }
if res.exit_code != 0 { if res.exit_code != 0 {

View File

@ -2,7 +2,7 @@ module compiler
const ( const (
CommonCHeaders = ' c_headers = '
#include <stdio.h> // TODO remove all these includes, define all function signatures and types manually #include <stdio.h> // TODO remove all these includes, define all function signatures and types manually
#include <stdlib.h> #include <stdlib.h>
@ -10,7 +10,6 @@ CommonCHeaders = '
//#include "fns.h" //#include "fns.h"
#include <signal.h> #include <signal.h>
#include <stdarg.h> // for va_list #include <stdarg.h> // for va_list
#include <inttypes.h> // int64_t etc
#include <string.h> // memcpy #include <string.h> // memcpy
#ifndef _WIN32 #ifndef _WIN32
@ -105,35 +104,6 @@ CommonCHeaders = '
#include <pthread.h> #include <pthread.h>
#endif #endif
//================================== TYPEDEFS ================================*/
typedef int64_t i64;
typedef int16_t i16;
typedef int8_t i8;
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t byte;
typedef uint32_t rune;
typedef float f32;
typedef double f64;
typedef unsigned char* byteptr;
typedef int* intptr;
typedef void* voidptr;
typedef struct array array;
typedef struct map map;
typedef array array_string;
typedef array array_int;
typedef array array_byte;
typedef array array_f32;
typedef array array_f64;
typedef map map_int;
typedef map map_string;
#ifndef bool
typedef int bool;
#define true 1
#define false 0
#endif
//============================== HELPER C MACROS =============================*/ //============================== HELPER C MACROS =============================*/
#define _PUSH(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push(arr, &tmp);} #define _PUSH(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push(arr, &tmp);}
@ -175,4 +145,39 @@ var map_string = function() {}
var map_int = function() {} var map_int = function() {}
' '
c_builtin_types = '
//================================== TYPEDEFS ================================*/
#include <inttypes.h> // int64_t etc
typedef int64_t i64;
typedef int16_t i16;
typedef int8_t i8;
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t byte;
typedef uint32_t rune;
typedef float f32;
typedef double f64;
typedef unsigned char* byteptr;
typedef int* intptr;
typedef void* voidptr;
typedef struct array array;
typedef struct map map;
typedef array array_string;
typedef array array_int;
typedef array array_byte;
typedef array array_f32;
typedef array array_f64;
typedef map map_int;
typedef map map_string;
#ifndef bool
typedef int bool;
#define true 1
#define false 0
#endif
'
) )

View File

@ -1136,7 +1136,7 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
! (expected == 'byte*' && got.contains(']byte')) && ! (expected == 'byte*' && got.contains(']byte')) &&
! (expected == 'byte*' && got == 'string') && ! (expected == 'byte*' && got == 'string') &&
//! (expected == 'void*' && got == 'array_int') { //! (expected == 'void*' && got == 'array_int') {
! (expected == 'byte*' && got == 'byteptr') { ! (expected == 'byte*' && got == 'byteptr') && !p.pref.is_bare {
p.cgen.set_placeholder(ph, '& /*112 e="$expected" g="$got" */') p.cgen.set_placeholder(ph, '& /*112 e="$expected" g="$got" */')
} }
} }

View File

@ -234,7 +234,10 @@ pub fn (v mut V) compile() {
$if js { $if js {
cgen.genln(js_headers) cgen.genln(js_headers)
} $else { } $else {
cgen.genln(CommonCHeaders) cgen.genln(c_builtin_types)
if !v.pref.is_bare {
cgen.genln(c_headers)
}
} }
v.generate_hotcode_reloading_declarations() v.generate_hotcode_reloading_declarations()
// We need the cjson header for all the json decoding that will be done in // We need the cjson header for all the json decoding that will be done in
@ -295,8 +298,10 @@ pub fn (v mut V) compile() {
def.writeln(cgen.includes.join_lines()) def.writeln(cgen.includes.join_lines())
def.writeln(cgen.typedefs.join_lines()) def.writeln(cgen.typedefs.join_lines())
def.writeln(v.type_definitions()) def.writeln(v.type_definitions())
def.writeln('\nstring _STR(const char*, ...);\n') if !v.pref.is_bare {
def.writeln('\nstring _STR_TMP(const char*, ...);\n') def.writeln('\nstring _STR(const char*, ...);\n')
def.writeln('\nstring _STR_TMP(const char*, ...);\n')
}
def.writeln(cgen.fns.join_lines()) // fn definitions def.writeln(cgen.fns.join_lines()) // fn definitions
def.writeln(v.interface_table()) def.writeln(v.interface_table())
} $else { } $else {
@ -353,6 +358,7 @@ fn (v mut V) generate_init() {
} }
} }
consts_init_body := v.cgen.consts_init.join_lines() consts_init_body := v.cgen.consts_init.join_lines()
if !v.pref.is_bare {
// vlib can't have `init_consts()` // vlib can't have `init_consts()`
v.cgen.genln('void init() { v.cgen.genln('void init() {
g_str_buf=malloc(1000); g_str_buf=malloc(1000);
@ -396,6 +402,7 @@ string _STR_TMP(const char *fmt, ...) {
') ')
} }
}
} }
pub fn (v mut V) generate_main() { pub fn (v mut V) generate_main() {
@ -403,12 +410,12 @@ pub fn (v mut V) generate_main() {
$if js { return } $if js { return }
if v.pref.is_vlines { if v.pref.is_vlines {
///// After this point, the v files are compiled. // After this point, the v files are compiled.
///// The rest is auto generated code, which will not have // The rest is auto generated code, which will not have
///// different .v source file/line numbers. // different .v source file/line numbers.
lines_so_far := cgen.lines.join('\n').count('\n') + 5 lines_so_far := cgen.lines.join('\n').count('\n') + 5
cgen.genln('') cgen.genln('')
cgen.genln('////////////////// Reset the file/line numbers //////////') cgen.genln('// Reset the file/line numbers')
cgen.lines << '#line $lines_so_far "${cescaped_path(os.realpath(cgen.out_path))}"' cgen.lines << '#line $lines_so_far "${cescaped_path(os.realpath(cgen.out_path))}"'
cgen.genln('') cgen.genln('')
} }
@ -460,7 +467,9 @@ pub fn (v mut V) generate_main() {
pub fn (v mut V) gen_main_start(add_os_args bool){ pub fn (v mut V) gen_main_start(add_os_args bool){
v.cgen.genln('int main(int argc, char** argv) { ') v.cgen.genln('int main(int argc, char** argv) { ')
v.cgen.genln(' init();') if !v.pref.is_bare {
v.cgen.genln(' init();')
}
if add_os_args && 'os' in v.table.imports { if add_os_args && 'os' in v.table.imports {
v.cgen.genln(' os__args = os__init_os_args(argc, (byteptr*)argv);') v.cgen.genln(' os__args = os__init_os_args(argc, (byteptr*)argv);')
} }

View File

@ -2137,7 +2137,7 @@ fn (p mut Parser) string_expr() {
Calling a C function sometimes requires a call to a string method Calling a C function sometimes requires a call to a string method
C.fun('ssss'.to_wide()) => fun(string_to_wide(tos3("ssss"))) C.fun('ssss'.to_wide()) => fun(string_to_wide(tos3("ssss")))
*/ */
if (p.calling_c && p.peek() != .dot) || (p.pref.translated && p.mod == 'main') { if (p.calling_c && p.peek() != .dot) || p.pref.is_bare || (p.pref.translated && p.mod == 'main') {
p.gen('"$f"') p.gen('"$f"')
} }
else if p.is_sql { else if p.is_sql {

View File

@ -1,13 +1,13 @@
.intel_syntax noprefix .intel_syntax noprefix
.text .text
.globl _start, syscall5 .globl _start, main__syscall5
_start: _start:
xor rbp,rbp xor rbp,rbp
pop rdi pop rdi
mov rsi,rsp mov rsi,rsp
and rsp,-16 and rsp,-16
call main call main__main
mov rdi,rax /* syscall param 1 = rax (ret value of main) */ mov rdi,rax /* syscall param 1 = rax (ret value of main) */
mov rax,60 /* SYS_exit */ mov rax,60 /* SYS_exit */
@ -16,7 +16,7 @@
ret /* should never be reached, but if the OS somehow fails ret /* should never be reached, but if the OS somehow fails
to kill us, it will cause a segmentation fault */ to kill us, it will cause a segmentation fault */
syscall5: main__syscall5:
mov rax,rdi mov rax,rdi
mov rdi,rsi mov rdi,rsi
mov rsi,rdx mov rsi,rdx

View File

@ -1,16 +1,16 @@
fn syscall5(number, arg1, arg2, arg3, arg4, arg5 voidptr) voidptr fn syscall5(number, arg1, arg2, arg3, arg4, arg5 voidptr) voidptr
fn write(fd int, data voidptr, nbytes u64) int { fn write(fd int, data voidptr, nbytes u64) int {
return syscall5( return syscall5(
1, // SYS_write 1, // SYS_write
fd, fd,
data, data,
nbytes, nbytes,
0, // ignored 0, // ignored
0 // ignored 0 // ignored
) )
} }
fn main() { fn main() {
C.write(1, "hallo\n", 6) write(1, "hallo\n", 6)
} }