Merge branch 'Xe-expose-callMain'

closes #3891
This commit is contained in:
Andrew Kelley 2019-12-12 18:56:39 -05:00
commit 7699b5b997
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
14 changed files with 115 additions and 131 deletions

View File

@ -412,6 +412,13 @@ pub const CallOptions = struct {
};
};
/// This function type is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const TestFn = struct {
name: []const u8,
func: fn()anyerror!void,
};
/// This function type is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const PanicFn = fn ([]const u8, ?*StackTrace) noreturn;
@ -424,6 +431,10 @@ pub const panic: PanicFn = if (@hasDecl(root, "panic")) root.panic else default_
/// therefore must be kept in sync with the compiler implementation.
pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn {
@setCold(true);
if (@hasDecl(root, "os") and @hasDecl(root.os, "panic")) {
root.os.panic(msg, error_return_trace);
unreachable;
}
switch (os) {
.freestanding => {
while (true) {

View File

@ -187,19 +187,23 @@ pub fn abort() noreturn {
}
windows.kernel32.ExitProcess(3);
}
if (builtin.link_libc) {
system.abort();
if (!builtin.link_libc and builtin.os == .linux) {
raise(SIGABRT) catch {};
// TODO the rest of the implementation of abort() from musl libc here
raise(SIGKILL) catch {};
exit(127);
}
if (builtin.os == .uefi) {
exit(0); // TODO choose appropriate exit code
}
if (builtin.os == .wasi) {
@breakpoint();
exit(1);
}
raise(SIGABRT) catch {};
// TODO the rest of the implementation of abort() from musl libc here
raise(SIGKILL) catch {};
exit(127);
system.abort();
}
pub const RaiseError = UnexpectedError;

View File

@ -83,7 +83,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn
@setCold(true);
std.debug.panic("{}", msg);
}
if (builtin.os != .freestanding) {
if (builtin.os != .freestanding and builtin.os != .other) {
std.os.abort();
}
while (true) {}

View File

@ -1,9 +1,9 @@
const std = @import("std");
const io = std.io;
const builtin = @import("builtin");
const test_fn_list = builtin.test_functions;
pub fn main() anyerror!void {
const test_fn_list = builtin.test_functions;
var ok_count: usize = 0;
var skip_count: usize = 0;
var progress = std.Progress{};
@ -16,7 +16,9 @@ pub fn main() anyerror!void {
var test_node = root_node.start(test_fn.name, null);
test_node.activate();
progress.refresh();
if (progress.terminal == null) std.debug.warn("{}/{} {}...", .{ i + 1, test_fn_list.len, test_fn.name });
if (progress.terminal == null) {
std.debug.warn("{}/{} {}...", .{ i + 1, test_fn_list.len, test_fn.name });
}
if (test_fn.func()) |_| {
ok_count += 1;
test_node.end();

View File

@ -1,8 +1,8 @@
// This file is included in the compilation unit when exporting an executable.
const root = @import("root");
const std = @import("std");
const builtin = @import("builtin");
const std = @import("std.zig");
const builtin = std.builtin;
const assert = std.debug.assert;
const uefi = std.os.uefi;
@ -17,6 +17,7 @@ const is_mips = switch (builtin.arch) {
.mips, .mipsel, .mips64, .mips64el => true,
else => false,
};
const start_sym_name = if (is_mips) "__start" else "_start";
comptime {
if (builtin.output_mode == .Lib and builtin.link_mode == .Dynamic) {
@ -34,14 +35,10 @@ comptime {
}
} else if (builtin.os == .uefi) {
if (!@hasDecl(root, "EfiMain")) @export("EfiMain", EfiMain, .Strong);
} else if (builtin.os != .freestanding) {
if (is_mips) {
if (!@hasDecl(root, "__start")) @export("__start", _start, .Strong);
} else {
if (!@hasDecl(root, "_start")) @export("_start", _start, .Strong);
}
} else if (is_wasm) {
if (!@hasDecl(root, "_start")) @export("_start", wasm_freestanding_start, .Strong);
} else if (is_wasm and builtin.os == .freestanding) {
if (!@hasDecl(root, start_sym_name)) @export(start_sym_name, wasm_freestanding_start, .Strong);
} else if (builtin.os != .other and builtin.os != .freestanding) {
if (!@hasDecl(root, start_sym_name)) @export(start_sym_name, _start, .Strong);
}
}
}
@ -247,7 +244,7 @@ async fn callMainAsync(loop: *std.event.Loop) u8 {
// This is not marked inline because it is called with @asyncCall when
// there is an event loop.
fn callMain() u8 {
pub fn callMain() u8 {
switch (@typeInfo(@TypeOf(root.main).ReturnType)) {
.NoReturn => {
root.main();

View File

@ -1,5 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
const builtin = std.builtin;
export var _tls_index: u32 = std.os.windows.TLS_OUT_OF_INDEXES;
export var _tls_start: u8 linksection(".tls") = 0;

View File

@ -65,6 +65,13 @@ pub const time = @import("time.zig");
pub const unicode = @import("unicode.zig");
pub const valgrind = @import("valgrind.zig");
pub const zig = @import("zig.zig");
pub const start = @import("start.zig");
// This forces the start.zig file to be imported, and the comptime logic inside that
// file decides whether to export any appropriate start symbols.
comptime {
_ = start;
}
test "" {
meta.refAllDecls(@This());

View File

@ -2003,10 +2003,11 @@ struct CodeGen {
ZigPackage *std_package;
ZigPackage *test_runner_package;
ZigPackage *compile_var_package;
ZigPackage *root_pkg; // @import("root")
ZigPackage *main_pkg; // usually same as root_pkg, except for `zig test`
ZigType *compile_var_import;
ZigType *root_import;
ZigType *start_import;
ZigType *test_runner_import;
struct {
ZigType *entry_bool;
@ -2179,7 +2180,6 @@ struct CodeGen {
Buf *root_out_name;
Buf *test_filter;
Buf *test_name_prefix;
ZigPackage *root_package;
Buf *zig_lib_dir;
Buf *zig_std_dir;
Buf *dynamic_linker_path;

View File

@ -3536,7 +3536,7 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope
return;
ZigType *import = get_scope_import(&decls_scope->base);
if (import->data.structure.root_struct->package != g->root_package)
if (import->data.structure.root_struct->package != g->main_pkg)
return;
Buf *decl_name_buf = node->data.test_decl.name;
@ -3577,7 +3577,7 @@ void update_compile_var(CodeGen *g, Buf *name, ZigValue *value) {
resolve_top_level_decl(g, tld, tld->source_node, false);
assert(tld->id == TldIdVar);
TldVar *tld_var = (TldVar *)tld;
tld_var->var->const_value = value;
copy_const_val(tld_var->var->const_value, value);
tld_var->var->var_type = value->type;
tld_var->var->align_bytes = get_abi_alignment(g, value->type);
}
@ -9178,3 +9178,42 @@ bool is_anon_container(ZigType *ty) {
ty->data.structure.special == StructSpecialInferredTuple ||
ty->data.structure.special == StructSpecialInferredStruct);
}
bool is_opt_err_set(ZigType *ty) {
return ty->id == ZigTypeIdErrorSet ||
(ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet);
}
// Returns whether the x_optional field of ZigValue is active.
bool type_has_optional_repr(ZigType *ty) {
if (ty->id != ZigTypeIdOptional) {
return false;
} else if (get_codegen_ptr_type(ty) != nullptr) {
return false;
} else if (is_opt_err_set(ty)) {
return false;
} else {
return true;
}
}
void copy_const_val(ZigValue *dest, ZigValue *src) {
memcpy(dest, src, sizeof(ZigValue));
if (src->special != ConstValSpecialStatic)
return;
dest->parent.id = ConstParentIdNone;
if (dest->type->id == ZigTypeIdStruct) {
dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count);
for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {
copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i]);
dest->data.x_struct.fields[i]->parent.id = ConstParentIdStruct;
dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest;
dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i;
}
} else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) {
dest->data.x_optional = create_const_vals(1);
copy_const_val(dest->data.x_optional, src->data.x_optional);
dest->data.x_optional->parent.id = ConstParentIdOptionalPayload;
dest->data.x_optional->parent.data.p_optional_payload.optional_val = dest;
}
}

View File

@ -276,4 +276,7 @@ Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_targe
ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path);
ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry);
bool is_anon_container(ZigType *ty);
void copy_const_val(ZigValue *dest, ZigValue *src);
bool type_has_optional_repr(ZigType *ty);
bool is_opt_err_set(ZigType *ty);
#endif

View File

@ -8440,11 +8440,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
if (g->is_test_build) {
buf_appendf(contents,
"const TestFn = struct {\n"
"name: []const u8,\n"
"func: fn()anyerror!void,\n"
"};\n"
"pub const test_functions = {}; // overwritten later\n"
"pub var test_functions: []TestFn = undefined; // overwritten later\n"
);
}
@ -8535,23 +8531,23 @@ static Error define_builtin_compile_vars(CodeGen *g) {
}
}
assert(g->root_package);
assert(g->main_pkg);
assert(g->std_package);
g->compile_var_package = new_package(buf_ptr(this_dir), builtin_zig_basename, "builtin");
g->compile_var_package->package_table.put(buf_create_from_str("std"), g->std_package);
g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
ZigPackage *root_pkg;
if (g->is_test_build) {
if (g->test_runner_package == nullptr) {
g->test_runner_package = create_test_runner_pkg(g);
}
root_pkg = g->test_runner_package;
g->root_pkg = g->test_runner_package;
} else {
root_pkg = g->root_package;
g->root_pkg = g->main_pkg;
}
g->std_package->package_table.put(buf_create_from_str("root"), root_pkg);
g->compile_var_package->package_table.put(buf_create_from_str("std"), g->std_package);
g->main_pkg->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
g->main_pkg->package_table.put(buf_create_from_str("root"), g->root_pkg);
g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
g->std_package->package_table.put(buf_create_from_str("root"), g->root_pkg);
g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents,
SourceKindPkgMain);
@ -8670,7 +8666,7 @@ static void init(CodeGen *g) {
// no longer reference DW_AT_comp_dir, for the purpose of being able to support the
// common practice of stripping all but the line number sections from an executable.
const char *compile_unit_dir = target_os_is_darwin(g->zig_target->os) ? "." :
buf_ptr(&g->root_package->root_src_dir);
buf_ptr(&g->main_pkg->root_src_dir);
ZigLLVMDIFile *compile_unit_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(g->root_out_name),
compile_unit_dir);
@ -9083,30 +9079,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
}
}
static ZigType *add_special_code(CodeGen *g, ZigPackage *package, const char *basename) {
Buf *code_basename = buf_create_from_str(basename);
Buf path_to_code_src = BUF_INIT;
os_path_join(g->zig_std_special_dir, code_basename, &path_to_code_src);
Buf *resolve_paths[] = {&path_to_code_src};
Buf *resolved_path = buf_alloc();
*resolved_path = os_path_resolve(resolve_paths, 1);
Buf *import_code = buf_alloc();
Error err;
if ((err = file_fetch(g, resolved_path, import_code))) {
zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err));
}
return add_source_file(g, package, resolved_path, import_code, SourceKindPkgMain);
}
static ZigPackage *create_start_pkg(CodeGen *g, ZigPackage *pkg_with_main) {
ZigPackage *package = codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "start.zig", "std.special");
package->package_table.put(buf_create_from_str("root"), pkg_with_main);
return package;
}
static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
static void update_test_functions_builtin_decl(CodeGen *g) {
Error err;
assert(g->is_test_build);
@ -9166,16 +9139,15 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
update_compile_var(g, buf_create_from_str("test_functions"), test_fn_slice);
assert(g->test_runner_package != nullptr);
g->test_runner_import = add_special_code(g, g->test_runner_package, "test_runner.zig");
}
static Buf *get_resolved_root_src_path(CodeGen *g) {
// TODO memoize
if (buf_len(&g->root_package->root_src_path) == 0)
if (buf_len(&g->main_pkg->root_src_path) == 0)
return nullptr;
Buf rel_full_path = BUF_INIT;
os_path_join(&g->root_package->root_src_dir, &g->root_package->root_src_path, &rel_full_path);
os_path_join(&g->main_pkg->root_src_dir, &g->main_pkg->root_src_path, &rel_full_path);
Buf *resolved_path = buf_alloc();
Buf *resolve_paths[] = {&rel_full_path};
@ -9198,7 +9170,7 @@ static void gen_root_source(CodeGen *g) {
exit(1);
}
ZigType *root_import_alias = add_source_file(g, g->root_package, resolved_path, source_code, SourceKindRoot);
ZigType *root_import_alias = add_source_file(g, g->main_pkg, resolved_path, source_code, SourceKindRoot);
assert(root_import_alias == g->root_import);
assert(g->root_out_name);
@ -9250,16 +9222,8 @@ static void gen_root_source(CodeGen *g) {
}
report_errors_and_maybe_exit(g);
if (!g->is_test_build) {
g->start_import = add_special_code(g, create_start_pkg(g, g->root_package), "start.zig");
}
if (!g->error_during_imports) {
semantic_analyze(g);
}
if (g->is_test_build) {
create_test_compile_var_and_add_test_runner(g);
g->start_import = add_special_code(g, create_start_pkg(g, g->test_runner_package), "start.zig");
update_test_functions_builtin_decl(g);
if (!g->error_during_imports) {
semantic_analyze(g);
}
@ -10058,7 +10022,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
CacheHash *ch = &g->cache_hash;
cache_init(ch, manifest_dir);
add_cache_pkg(g, ch, g->root_package);
add_cache_pkg(g, ch, g->main_pkg);
if (g->linker_script != nullptr) {
cache_file(ch, buf_create_from_str(g->linker_script));
}
@ -10141,7 +10105,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
}
static bool need_llvm_module(CodeGen *g) {
return buf_len(&g->root_package->root_src_path) != 0;
return buf_len(&g->main_pkg->root_src_path) != 0;
}
static void resolve_out_paths(CodeGen *g) {
@ -10388,8 +10352,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
assert(g->compile_var_package != nullptr);
pkg->package_table.put(buf_create_from_str("std"), g->std_package);
ZigPackage *main_pkg = g->is_test_build ? g->test_runner_package : g->root_package;
pkg->package_table.put(buf_create_from_str("root"), main_pkg);
pkg->package_table.put(buf_create_from_str("root"), g->root_pkg);
pkg->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
}
@ -10516,15 +10479,13 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
buf_len(&resolved_root_src_path) - buf_len(&resolved_main_pkg_path) - 1);
}
g->root_package = new_package(buf_ptr(root_pkg_path), buf_ptr(rel_root_src_path), "");
g->main_pkg = new_package(buf_ptr(root_pkg_path), buf_ptr(rel_root_src_path), "");
g->std_package = new_package(buf_ptr(g->zig_std_dir), "std.zig", "std");
g->root_package->package_table.put(buf_create_from_str("std"), g->std_package);
g->main_pkg->package_table.put(buf_create_from_str("std"), g->std_package);
} else {
g->root_package = new_package(".", "", "");
g->main_pkg = new_package(".", "", "");
}
g->root_package->package_table.put(buf_create_from_str("root"), g->root_package);
g->zig_std_special_dir = buf_alloc();
os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);

View File

@ -1216,7 +1216,7 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const
jw_end_object(jw);
jw_object_field(jw, "rootPkg");
anal_dump_pkg_ref(&ctx, g->root_package);
anal_dump_pkg_ref(&ctx, g->main_pkg);
// Poke the functions
for (size_t i = 0; i < g->fn_defs.length; i += 1) {

View File

@ -232,7 +232,6 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr,
ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on);
static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
static void copy_const_val(ZigValue *dest, ZigValue *src);
static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);
static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
ZigType *ptr_type);
@ -718,11 +717,6 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
return result;
}
static bool is_opt_err_set(ZigType *ty) {
return ty->id == ZigTypeIdErrorSet ||
(ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet);
}
static bool is_tuple(ZigType *type) {
return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple;
}
@ -11451,40 +11445,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
}
}
// Returns whether the x_optional field of ZigValue is active.
static bool type_has_optional_repr(ZigType *ty) {
if (ty->id != ZigTypeIdOptional) {
return false;
} else if (get_codegen_ptr_type(ty) != nullptr) {
return false;
} else if (is_opt_err_set(ty)) {
return false;
} else {
return true;
}
}
static void copy_const_val(ZigValue *dest, ZigValue *src) {
memcpy(dest, src, sizeof(ZigValue));
if (src->special != ConstValSpecialStatic)
return;
dest->parent.id = ConstParentIdNone;
if (dest->type->id == ZigTypeIdStruct) {
dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count);
for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {
copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i]);
dest->data.x_struct.fields[i]->parent.id = ConstParentIdStruct;
dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest;
dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i;
}
} else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) {
dest->data.x_optional = create_const_vals(1);
copy_const_val(dest->data.x_optional, src->data.x_optional);
dest->data.x_optional->parent.id = ConstParentIdOptionalPayload;
dest->data.x_optional->parent.data.p_optional_payload.optional_val = dest;
}
}
static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr,
CastOp cast_op,
ZigValue *other_val, ZigType *other_type,

View File

@ -623,7 +623,7 @@ int main(int argc, char **argv) {
ZigPackage *build_pkg = codegen_create_package(g, buf_ptr(&build_file_dirname),
buf_ptr(&build_file_basename), "std.special");
g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg);
g->main_pkg->package_table.put(buf_create_from_str("@build"), build_pkg);
g->enable_cache = get_cache_opt(enable_cache, true);
codegen_build_and_link(g);
if (root_progress_node != nullptr) {
@ -1269,7 +1269,7 @@ int main(int argc, char **argv) {
codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix));
}
add_package(g, cur_pkg, g->root_package);
add_package(g, cur_pkg, g->main_pkg);
if (cmd == CmdBuild || cmd == CmdRun || cmd == CmdTest) {
g->c_source_files = c_source_files;