aboutsummaryrefslogtreecommitdiff
path: root/src-self-hosted/module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-07-14 18:27:51 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-07-14 18:27:51 -0400
commit4d920cee6e8be2f2ae2cfd9067358c65b977568a (patch)
tree2c04de6151b7448dec9958d0a91234ea0ba9a15d /src-self-hosted/module.zig
parentda3acacc14331a6be33445c3bfd204e2cccabddd (diff)
parent28c3d4809bc6d497ac81892bc7eb03b95d8c2b32 (diff)
downloadzig-4d920cee6e8be2f2ae2cfd9067358c65b977568a.tar.gz
zig-4d920cee6e8be2f2ae2cfd9067358c65b977568a.zip
Merge remote-tracking branch 'origin/master' into llvm7
Diffstat (limited to 'src-self-hosted/module.zig')
-rw-r--r--src-self-hosted/module.zig579
1 files changed, 0 insertions, 579 deletions
diff --git a/src-self-hosted/module.zig b/src-self-hosted/module.zig
deleted file mode 100644
index 5ce1a7965a..0000000000
--- a/src-self-hosted/module.zig
+++ /dev/null
@@ -1,579 +0,0 @@
-const std = @import("std");
-const os = std.os;
-const io = std.io;
-const mem = std.mem;
-const Allocator = mem.Allocator;
-const Buffer = std.Buffer;
-const llvm = @import("llvm.zig");
-const c = @import("c.zig");
-const builtin = @import("builtin");
-const Target = @import("target.zig").Target;
-const warn = std.debug.warn;
-const Token = std.zig.Token;
-const ArrayList = std.ArrayList;
-const errmsg = @import("errmsg.zig");
-const ast = std.zig.ast;
-const event = std.event;
-const assert = std.debug.assert;
-
-pub const Module = struct {
- loop: *event.Loop,
- name: Buffer,
- root_src_path: ?[]const u8,
- module: llvm.ModuleRef,
- context: llvm.ContextRef,
- builder: llvm.BuilderRef,
- target: Target,
- build_mode: builtin.Mode,
- zig_lib_dir: []const u8,
-
- version_major: u32,
- version_minor: u32,
- version_patch: u32,
-
- linker_script: ?[]const u8,
- cache_dir: []const u8,
- libc_lib_dir: ?[]const u8,
- libc_static_lib_dir: ?[]const u8,
- libc_include_dir: ?[]const u8,
- msvc_lib_dir: ?[]const u8,
- kernel32_lib_dir: ?[]const u8,
- dynamic_linker: ?[]const u8,
- out_h_path: ?[]const u8,
-
- is_test: bool,
- each_lib_rpath: bool,
- strip: bool,
- is_static: bool,
- linker_rdynamic: bool,
-
- clang_argv: []const []const u8,
- llvm_argv: []const []const u8,
- lib_dirs: []const []const u8,
- rpath_list: []const []const u8,
- assembly_files: []const []const u8,
- link_objects: []const []const u8,
-
- windows_subsystem_windows: bool,
- windows_subsystem_console: bool,
-
- link_libs_list: ArrayList(*LinkLib),
- libc_link_lib: ?*LinkLib,
-
- err_color: errmsg.Color,
-
- verbose_tokenize: bool,
- verbose_ast_tree: bool,
- verbose_ast_fmt: bool,
- verbose_cimport: bool,
- verbose_ir: bool,
- verbose_llvm_ir: bool,
- verbose_link: bool,
-
- darwin_frameworks: []const []const u8,
- darwin_version_min: DarwinVersionMin,
-
- test_filters: []const []const u8,
- test_name_prefix: ?[]const u8,
-
- emit_file_type: Emit,
-
- kind: Kind,
-
- link_out_file: ?[]const u8,
- events: *event.Channel(Event),
-
- exported_symbol_names: event.Locked(Decl.Table),
-
- // TODO handle some of these earlier and report them in a way other than error codes
- pub const BuildError = error{
- OutOfMemory,
- EndOfStream,
- BadFd,
- Io,
- IsDir,
- Unexpected,
- SystemResources,
- SharingViolation,
- PathAlreadyExists,
- FileNotFound,
- AccessDenied,
- PipeBusy,
- FileTooBig,
- SymLinkLoop,
- ProcessFdQuotaExceeded,
- NameTooLong,
- SystemFdQuotaExceeded,
- NoDevice,
- PathNotFound,
- NoSpaceLeft,
- NotDir,
- FileSystem,
- OperationAborted,
- IoPending,
- BrokenPipe,
- WouldBlock,
- FileClosed,
- DestinationAddressRequired,
- DiskQuota,
- InputOutput,
- NoStdHandles,
- Overflow,
- NotSupported,
- };
-
- pub const Event = union(enum) {
- Ok,
- Fail: []errmsg.Msg,
- Error: BuildError,
- };
-
- pub const DarwinVersionMin = union(enum) {
- None,
- MacOS: []const u8,
- Ios: []const u8,
- };
-
- pub const Kind = enum {
- Exe,
- Lib,
- Obj,
- };
-
- pub const LinkLib = struct {
- name: []const u8,
- path: ?[]const u8,
-
- /// the list of symbols we depend on from this lib
- symbols: ArrayList([]u8),
- provided_explicitly: bool,
- };
-
- pub const Emit = enum {
- Binary,
- Assembly,
- LlvmIr,
- };
-
- pub fn create(
- loop: *event.Loop,
- name: []const u8,
- root_src_path: ?[]const u8,
- target: *const Target,
- kind: Kind,
- build_mode: builtin.Mode,
- zig_lib_dir: []const u8,
- cache_dir: []const u8,
- ) !*Module {
- var name_buffer = try Buffer.init(loop.allocator, name);
- errdefer name_buffer.deinit();
-
- const context = c.LLVMContextCreate() orelse return error.OutOfMemory;
- errdefer c.LLVMContextDispose(context);
-
- const module = c.LLVMModuleCreateWithNameInContext(name_buffer.ptr(), context) orelse return error.OutOfMemory;
- errdefer c.LLVMDisposeModule(module);
-
- const builder = c.LLVMCreateBuilderInContext(context) orelse return error.OutOfMemory;
- errdefer c.LLVMDisposeBuilder(builder);
-
- const events = try event.Channel(Event).create(loop, 0);
- errdefer events.destroy();
-
- return loop.allocator.create(Module{
- .loop = loop,
- .events = events,
- .name = name_buffer,
- .root_src_path = root_src_path,
- .module = module,
- .context = context,
- .builder = builder,
- .target = target.*,
- .kind = kind,
- .build_mode = build_mode,
- .zig_lib_dir = zig_lib_dir,
- .cache_dir = cache_dir,
-
- .version_major = 0,
- .version_minor = 0,
- .version_patch = 0,
-
- .verbose_tokenize = false,
- .verbose_ast_tree = false,
- .verbose_ast_fmt = false,
- .verbose_cimport = false,
- .verbose_ir = false,
- .verbose_llvm_ir = false,
- .verbose_link = false,
-
- .linker_script = null,
- .libc_lib_dir = null,
- .libc_static_lib_dir = null,
- .libc_include_dir = null,
- .msvc_lib_dir = null,
- .kernel32_lib_dir = null,
- .dynamic_linker = null,
- .out_h_path = null,
- .is_test = false,
- .each_lib_rpath = false,
- .strip = false,
- .is_static = false,
- .linker_rdynamic = false,
- .clang_argv = [][]const u8{},
- .llvm_argv = [][]const u8{},
- .lib_dirs = [][]const u8{},
- .rpath_list = [][]const u8{},
- .assembly_files = [][]const u8{},
- .link_objects = [][]const u8{},
- .windows_subsystem_windows = false,
- .windows_subsystem_console = false,
- .link_libs_list = ArrayList(*LinkLib).init(loop.allocator),
- .libc_link_lib = null,
- .err_color = errmsg.Color.Auto,
- .darwin_frameworks = [][]const u8{},
- .darwin_version_min = DarwinVersionMin.None,
- .test_filters = [][]const u8{},
- .test_name_prefix = null,
- .emit_file_type = Emit.Binary,
- .link_out_file = null,
- .exported_symbol_names = event.Locked(Decl.Table).init(loop, Decl.Table.init(loop.allocator)),
- });
- }
-
- fn dump(self: *Module) void {
- c.LLVMDumpModule(self.module);
- }
-
- pub fn destroy(self: *Module) void {
- self.events.destroy();
- c.LLVMDisposeBuilder(self.builder);
- c.LLVMDisposeModule(self.module);
- c.LLVMContextDispose(self.context);
- self.name.deinit();
-
- self.a().destroy(self);
- }
-
- pub fn build(self: *Module) !void {
- if (self.llvm_argv.len != 0) {
- var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.a(), [][]const []const u8{
- [][]const u8{"zig (LLVM option parsing)"},
- self.llvm_argv,
- });
- defer c_compatible_args.deinit();
- // TODO this sets global state
- c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr);
- }
-
- _ = try async<self.a()> self.buildAsync();
- }
-
- async fn buildAsync(self: *Module) void {
- while (true) {
- // TODO directly awaiting async should guarantee memory allocation elision
- // TODO also async before suspending should guarantee memory allocation elision
- (await (async self.addRootSrc() catch unreachable)) catch |err| {
- await (async self.events.put(Event{ .Error = err }) catch unreachable);
- return;
- };
- await (async self.events.put(Event.Ok) catch unreachable);
- // for now we stop after 1
- return;
- }
- }
-
- async fn addRootSrc(self: *Module) !void {
- const root_src_path = self.root_src_path orelse @panic("TODO handle null root src path");
- // TODO async/await os.path.real
- const root_src_real_path = os.path.real(self.a(), root_src_path) catch |err| {
- try printError("unable to get real path '{}': {}", root_src_path, err);
- return err;
- };
- errdefer self.a().free(root_src_real_path);
-
- // TODO async/await readFileAlloc()
- const source_code = io.readFileAlloc(self.a(), root_src_real_path) catch |err| {
- try printError("unable to open '{}': {}", root_src_real_path, err);
- return err;
- };
- errdefer self.a().free(source_code);
-
- var parsed_file = ParsedFile{
- .tree = try std.zig.parse(self.a(), source_code),
- .realpath = root_src_real_path,
- };
- errdefer parsed_file.tree.deinit();
-
- const tree = &parsed_file.tree;
-
- // create empty struct for it
- const decls = try Scope.Decls.create(self.a(), null);
- errdefer decls.destroy();
-
- var it = tree.root_node.decls.iterator(0);
- while (it.next()) |decl_ptr| {
- const decl = decl_ptr.*;
- switch (decl.id) {
- ast.Node.Id.Comptime => @panic("TODO"),
- ast.Node.Id.VarDecl => @panic("TODO"),
- ast.Node.Id.FnProto => {
- const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);
-
- const name = if (fn_proto.name_token) |name_token| tree.tokenSlice(name_token) else {
- @panic("TODO add compile error");
- //try self.addCompileError(
- // &parsed_file,
- // fn_proto.fn_token,
- // fn_proto.fn_token + 1,
- // "missing function name",
- //);
- continue;
- };
-
- const fn_decl = try self.a().create(Decl.Fn{
- .base = Decl{
- .id = Decl.Id.Fn,
- .name = name,
- .visib = parseVisibToken(tree, fn_proto.visib_token),
- .resolution = Decl.Resolution.Unresolved,
- },
- .value = Decl.Fn.Val{ .Unresolved = {} },
- .fn_proto = fn_proto,
- });
- errdefer self.a().destroy(fn_decl);
-
- // TODO make this parallel
- try await try async self.addTopLevelDecl(tree, &fn_decl.base);
- },
- ast.Node.Id.TestDecl => @panic("TODO"),
- else => unreachable,
- }
- }
- }
-
- async fn addTopLevelDecl(self: *Module, tree: *ast.Tree, decl: *Decl) !void {
- const is_export = decl.isExported(tree);
-
- {
- const exported_symbol_names = await try async self.exported_symbol_names.acquire();
- defer exported_symbol_names.release();
-
- if (try exported_symbol_names.value.put(decl.name, decl)) |other_decl| {
- @panic("TODO report compile error");
- }
- }
- }
-
- pub fn link(self: *Module, out_file: ?[]const u8) !void {
- warn("TODO link");
- return error.Todo;
- }
-
- pub fn addLinkLib(self: *Module, name: []const u8, provided_explicitly: bool) !*LinkLib {
- const is_libc = mem.eql(u8, name, "c");
-
- if (is_libc) {
- if (self.libc_link_lib) |libc_link_lib| {
- return libc_link_lib;
- }
- }
-
- for (self.link_libs_list.toSliceConst()) |existing_lib| {
- if (mem.eql(u8, name, existing_lib.name)) {
- return existing_lib;
- }
- }
-
- const link_lib = try self.a().create(LinkLib{
- .name = name,
- .path = null,
- .provided_explicitly = provided_explicitly,
- .symbols = ArrayList([]u8).init(self.a()),
- });
- try self.link_libs_list.append(link_lib);
- if (is_libc) {
- self.libc_link_lib = link_lib;
- }
- return link_lib;
- }
-
- fn a(self: Module) *mem.Allocator {
- return self.loop.allocator;
- }
-};
-
-fn printError(comptime format: []const u8, args: ...) !void {
- var stderr_file = try std.io.getStdErr();
- var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
- const out_stream = &stderr_file_out_stream.stream;
- try out_stream.print(format, args);
-}
-
-fn parseVisibToken(tree: *ast.Tree, optional_token_index: ?ast.TokenIndex) Visib {
- if (optional_token_index) |token_index| {
- const token = tree.tokens.at(token_index);
- assert(token.id == Token.Id.Keyword_pub);
- return Visib.Pub;
- } else {
- return Visib.Private;
- }
-}
-
-pub const Scope = struct {
- id: Id,
- parent: ?*Scope,
-
- pub const Id = enum {
- Decls,
- Block,
- };
-
- pub const Decls = struct {
- base: Scope,
- table: Decl.Table,
-
- pub fn create(a: *Allocator, parent: ?*Scope) !*Decls {
- const self = try a.create(Decls{
- .base = Scope{
- .id = Id.Decls,
- .parent = parent,
- },
- .table = undefined,
- });
- errdefer a.destroy(self);
-
- self.table = Decl.Table.init(a);
- errdefer self.table.deinit();
-
- return self;
- }
-
- pub fn destroy(self: *Decls) void {
- self.table.deinit();
- self.table.allocator.destroy(self);
- self.* = undefined;
- }
- };
-
- pub const Block = struct {
- base: Scope,
- };
-};
-
-pub const Visib = enum {
- Private,
- Pub,
-};
-
-pub const Decl = struct {
- id: Id,
- name: []const u8,
- visib: Visib,
- resolution: Resolution,
-
- pub const Table = std.HashMap([]const u8, *Decl, mem.hash_slice_u8, mem.eql_slice_u8);
-
- pub fn isExported(base: *const Decl, tree: *ast.Tree) bool {
- switch (base.id) {
- Id.Fn => {
- const fn_decl = @fieldParentPtr(Fn, "base", base);
- return fn_decl.isExported(tree);
- },
- else => return false,
- }
- }
-
- pub const Resolution = enum {
- Unresolved,
- InProgress,
- Invalid,
- Ok,
- };
-
- pub const Id = enum {
- Var,
- Fn,
- CompTime,
- };
-
- pub const Var = struct {
- base: Decl,
- };
-
- pub const Fn = struct {
- base: Decl,
- value: Val,
- fn_proto: *const ast.Node.FnProto,
-
- // TODO https://github.com/ziglang/zig/issues/683 and then make this anonymous
- pub const Val = union {
- Unresolved: void,
- Ok: *Value.Fn,
- };
-
- pub fn externLibName(self: Fn, tree: *ast.Tree) ?[]const u8 {
- return if (self.fn_proto.extern_export_inline_token) |tok_index| x: {
- const token = tree.tokens.at(tok_index);
- break :x switch (token.id) {
- Token.Id.Extern => tree.tokenSlicePtr(token),
- else => null,
- };
- } else null;
- }
-
- pub fn isExported(self: Fn, tree: *ast.Tree) bool {
- if (self.fn_proto.extern_export_inline_token) |tok_index| {
- const token = tree.tokens.at(tok_index);
- return token.id == Token.Id.Keyword_export;
- } else {
- return false;
- }
- }
- };
-
- pub const CompTime = struct {
- base: Decl,
- };
-};
-
-pub const Value = struct {
- pub const Fn = struct {};
-};
-
-pub const Type = struct {
- id: Id,
-
- pub const Id = enum {
- Type,
- Void,
- Bool,
- NoReturn,
- Int,
- Float,
- Pointer,
- Array,
- Struct,
- ComptimeFloat,
- ComptimeInt,
- Undefined,
- Null,
- Optional,
- ErrorUnion,
- ErrorSet,
- Enum,
- Union,
- Fn,
- Opaque,
- Promise,
- };
-
- pub const Struct = struct {
- base: Type,
- decls: *Scope.Decls,
- };
-};
-
-pub const ParsedFile = struct {
- tree: ast.Tree,
- realpath: []const u8,
-};