authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-30 15:39:11+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-03 12:50:18-05:00
loga0ca30ce014f4abd9d31ea335e8860fd1b110495
tree577b3043e5d720b0916589bf3f9aa07a94b9baa5
parentfd7c7be33c95fd1bd77010378b407fc9fb4933e2
signature Commit is signed but in an unrecognized format.

move more startup code to std lib


6 files changed, 79 insertions(+), 114 deletions(-)

lib/std/builtin.zig+16
......@@ -348,6 +348,22 @@ pub const Endian = enum {
348348 Little,
349349};
350350
351/// This data structure is used by the Zig language code generation and
352/// therefore must be kept in sync with the compiler implementation.
353pub const OutType = enum {
354 Unknown,
355 Exe,
356 Lib,
357 Obj,
358};
359
360/// This data structure is used by the Zig language code generation and
361/// therefore must be kept in sync with the compiler implementation.
362pub const LinkType = enum {
363 Static,
364 Dynamic,
365};
366
351367/// This data structure is used by the Zig language code generation and
352368/// therefore must be kept in sync with the compiler implementation.
353369pub const Version = struct {
lib/std/special/start.zig+43-12
......@@ -19,21 +19,52 @@ const is_mips = switch (builtin.arch) {
1919};
2020
2121comptime {
22 if (builtin.link_libc) {
23 @export("main", main, .Strong);
24 } else if (builtin.os == .windows) {
25 @export("WinMainCRTStartup", WinMainCRTStartup, .Strong);
26 } else if (is_wasm and builtin.os == .freestanding) {
27 @export("_start", wasm_freestanding_start, .Strong);
28 } else if (builtin.os == .uefi) {
29 @export("EfiMain", EfiMain, .Strong);
30 } else if (is_mips) {
31 if (!@hasDecl(root, "__start")) @export("__start", _start, .Strong);
32 } else {
33 if (!@hasDecl(root, "_start")) @export("_start", _start, .Strong);
22 switch (builtin.output_type) {
23 .Unknown => unreachable,
24 .Exe => {
25 if (builtin.link_libc) {
26 if (!@hasDecl(root, "main") or
27 @typeInfo(@typeOf(root.main)).Fn.calling_convention != .C)
28 {
29 @export("main", main, .Weak);
30 }
31 } else if (builtin.os == .windows) {
32 if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup")) {
33 @export("WinMainCRTStartup", WinMainCRTStartup, .Strong);
34 }
35 } else if (is_wasm and builtin.os == .freestanding) {
36 if (!@hasDecl(root, "_start")) @export("_start", wasm_freestanding_start, .Strong);
37 } else if (builtin.os == .uefi) {
38 if (!@hasDecl(root, "EfiMain")) @export("EfiMain", EfiMain, .Strong);
39 } else if (is_mips) {
40 if (!@hasDecl(root, "__start")) @export("__start", _start, .Strong);
41 } else {
42 if (!@hasDecl(root, "_start")) @export("_start", _start, .Strong);
43 }
44 },
45 .Lib => {
46 if (builtin.os == .windows and builtin.link_type == .Dynamic and
47 !@hasDecl(root, "_DllMainCRTStartup"))
48 {
49 @export("_DllMainCRTStartup", _DllMainCRTStartup, .Strong);
50 }
51 },
52 .Obj => {},
3453 }
3554}
3655
56stdcallcc fn _DllMainCRTStartup(
57 hinstDLL: std.os.windows.HINSTANCE,
58 fdwReason: std.os.windows.DWORD,
59 lpReserved: std.os.windows.LPVOID,
60) std.os.windows.BOOL {
61 if (@hasDecl(root, "DllMain")) {
62 return root.DllMain(hinstDLL, fdwReason, lpReserved);
63 }
64
65 return std.os.windows.TRUE;
66}
67
3768extern fn wasm_freestanding_start() void {
3869 // This is marked inline because for some reason LLVM in release mode fails to inline it,
3970 // and we want fewer call frames in stack traces.
lib/std/special/start_lib.zig deleted-21
......@@ -1,21 +0,0 @@
1// This file is included in the compilation unit when exporting a DLL on windows.
2
3const root = @import("root");
4const std = @import("std");
5const builtin = @import("builtin");
6
7comptime {
8 @export("_DllMainCRTStartup", _DllMainCRTStartup, builtin.GlobalLinkage.Strong);
9}
10
11stdcallcc fn _DllMainCRTStartup(
12 hinstDLL: std.os.windows.HINSTANCE,
13 fdwReason: std.os.windows.DWORD,
14 lpReserved: std.os.windows.LPVOID,
15) std.os.windows.BOOL {
16 if (@hasDecl(root, "DllMain")) {
17 return root.DllMain(hinstDLL, fdwReason, lpReserved);
18 }
19
20 return std.os.windows.TRUE;
21}
src/all_types.hpp-2
......@@ -2061,7 +2061,6 @@ struct CodeGen {
20612061 ZigList<TldVar *> global_vars;
20622062
20632063 ZigFn *cur_fn;
2064 ZigFn *main_fn;
20652064 ZigFn *panic_fn;
20662065
20672066 ZigFn *largest_frame_fn;
......@@ -2081,7 +2080,6 @@ struct CodeGen {
20812080 uint32_t target_abi_index;
20822081 uint32_t target_oformat_index;
20832082 bool is_big_endian;
2084 bool have_pub_main;
20852083 bool have_c_main;
20862084 bool have_winmain;
20872085 bool have_winmain_crt_startup;
src/analyze.cpp-38
......@@ -3304,17 +3304,6 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node) {
33043304 return fn_entry;
33053305}
33063306
3307static bool scope_is_root_decls(Scope *scope) {
3308 while (scope) {
3309 if (scope->id == ScopeIdDecls) {
3310 ScopeDecls *scope_decls = (ScopeDecls *)scope;
3311 return is_top_level_struct(scope_decls->container_type);
3312 }
3313 scope = scope->parent;
3314 }
3315 zig_unreachable();
3316}
3317
33183307ZigType *get_test_fn_type(CodeGen *g) {
33193308 if (g->test_fn_type)
33203309 return g->test_fn_type;
......@@ -3353,7 +3342,6 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, G
33533342}
33543343
33553344static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3356 ZigType *import = tld_fn->base.import;
33573345 AstNode *source_node = tld_fn->base.source_node;
33583346 if (source_node->type == NodeTypeFnProto) {
33593347 AstNodeFnProto *fn_proto = &source_node->data.fn_proto;
......@@ -3433,12 +3421,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
34333421 if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) {
34343422 fn_table_entry->inferred_async_node = fn_table_entry->proto_node;
34353423 }
3436
3437 if (scope_is_root_decls(tld_fn->base.parent_scope) && import == g->root_import) {
3438 if (g->have_pub_main && buf_eql_str(tld_fn->base.name, "main")) {
3439 g->main_fn = fn_table_entry;
3440 }
3441 }
34423424 } else if (source_node->type == NodeTypeTestDecl) {
34433425 ZigFn *fn_table_entry = create_fn_raw(g, FnInlineAuto);
34443426
......@@ -4813,26 +4795,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
48134795 ast_print(stderr, root_node, 0);
48144796 }
48154797
4816 if (source_kind == SourceKindRoot) {
4817 // Look for main
4818 for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
4819 AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);
4820
4821 if (top_level_decl->type == NodeTypeFnDef) {
4822 AstNode *proto_node = top_level_decl->data.fn_def.fn_proto;
4823 assert(proto_node->type == NodeTypeFnProto);
4824 Buf *proto_name = proto_node->data.fn_proto.name;
4825
4826 bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub);
4827 if (is_pub) {
4828 if (buf_eql_str(proto_name, "main")) {
4829 g->have_pub_main = true;
4830 }
4831 }
4832 }
4833 }
4834 }
4835
48364798 for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
48374799 AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);
48384800 scan_decls(g, import_entry->data.structure.decls_scope, top_level_decl);
src/codegen.cpp+20-41
......@@ -8229,7 +8229,7 @@ TargetSubsystem detect_subsystem(CodeGen *g) {
82298229 if (g->zig_target->os == OsWindows) {
82308230 if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic))
82318231 return TargetSubsystemAuto;
8232 if (g->have_c_main || g->have_pub_main || g->is_test_build)
8232 if (g->have_c_main || g->is_test_build)
82338233 return TargetSubsystemConsole;
82348234 if (g->have_winmain || g->have_winmain_crt_startup)
82358235 return TargetSubsystemWindows;
......@@ -8375,6 +8375,24 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
83758375 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
83768376 buf_appendf(contents, "pub const endian = %s;\n", endian_str);
83778377 }
8378 const char *out_type = nullptr;
8379 switch (g->out_type) {
8380 case OutTypeUnknown:
8381 out_type = "Unknown";
8382 break;
8383 case OutTypeExe:
8384 out_type = "Exe";
8385 break;
8386 case OutTypeLib:
8387 out_type = "Lib";
8388 break;
8389 case OutTypeObj:
8390 out_type = "Obj";
8391 break;
8392 }
8393 buf_appendf(contents, "pub const output_type = OutType.%s;\n", out_type);
8394 const char *link_type = g->is_dynamic ? "Dynamic" : "Static";
8395 buf_appendf(contents, "pub const link_type = LinkType.%s;\n", link_type);
83788396 buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
83798397 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
83808398 buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
......@@ -9148,38 +9166,6 @@ static Buf *get_resolved_root_src_path(CodeGen *g) {
91489166 return resolved_path;
91499167}
91509168
9151static bool want_startup_code(CodeGen *g) {
9152 // Test builds get handled separately.
9153 if (g->is_test_build)
9154 return false;
9155
9156 // WASM freestanding can still have an entry point but other freestanding targets do not.
9157 if (g->zig_target->os == OsFreestanding && !target_is_wasm(g->zig_target))
9158 return false;
9159
9160 // Declaring certain export functions means skipping the start code
9161 if (g->have_c_main || g->have_winmain || g->have_winmain_crt_startup)
9162 return false;
9163
9164 // If there is a pub main in the root source file, that means we need start code.
9165 if (g->have_pub_main) {
9166 return true;
9167 } else {
9168 if (g->zig_target->os == OsUefi)
9169 return false;
9170 }
9171
9172 if (g->out_type == OutTypeExe) {
9173 // For build-exe, we might add start code even though there is no pub main, so that the
9174 // programmer gets the "no pub main" compile error. However if linking libc and there is
9175 // a C source file, that might have main().
9176 return g->c_source_files.length == 0 || g->libc_link_lib == nullptr;
9177 }
9178
9179 // For objects and libraries, and we don't have pub main, no start code.
9180 return false;
9181}
9182
91839169static void gen_root_source(CodeGen *g) {
91849170 Buf *resolved_path = get_resolved_root_src_path(g);
91859171 if (resolved_path == nullptr)
......@@ -9241,21 +9227,14 @@ static void gen_root_source(CodeGen *g) {
92419227 assert(g->panic_fn != nullptr);
92429228 }
92439229
9244
92459230 if (!g->error_during_imports) {
92469231 semantic_analyze(g);
92479232 }
92489233 report_errors_and_maybe_exit(g);
92499234
9250 if (want_startup_code(g)) {
9235 if (!g->is_test_build) {
92519236 g->start_import = add_special_code(g, create_start_pkg(g, g->root_package), "start.zig");
92529237 }
9253 if (g->zig_target->os == OsWindows && !g->have_dllmain_crt_startup &&
9254 g->out_type == OutTypeLib && g->is_dynamic)
9255 {
9256 g->start_import = add_special_code(g, create_start_pkg(g, g->root_package), "start_lib.zig");
9257 }
9258
92599238 if (!g->error_during_imports) {
92609239 semantic_analyze(g);
92619240 }