diff options
author | 2021-05-07 01:26:26 -0700 | |
---|---|---|
committer | 2021-05-07 01:26:26 -0700 | |
commit | fad34bb4abfe1715d4febec6e7de2809bfffb4e2 (patch) | |
tree | 6616f92155a3473c228e46f3c5693c47548761e9 /src/main_wasm.zig | |
parent | dd9e7de689dafb29ed3e79e2b7af54ea097f75e9 (diff) | |
download | bun-fad34bb4abfe1715d4febec6e7de2809bfffb4e2.tar.gz bun-fad34bb4abfe1715d4febec6e7de2809bfffb4e2.tar.zst bun-fad34bb4abfe1715d4febec6e7de2809bfffb4e2.zip |
cool
Former-commit-id: 96ff169e46fcb43d5afbc9a6e2fde039e27e9d5f
Diffstat (limited to 'src/main_wasm.zig')
-rw-r--r-- | src/main_wasm.zig | 254 |
1 files changed, 179 insertions, 75 deletions
diff --git a/src/main_wasm.zig b/src/main_wasm.zig index 83a2498e6..a379b4eb0 100644 --- a/src/main_wasm.zig +++ b/src/main_wasm.zig @@ -11,8 +11,10 @@ const linker = @import("linker.zig"); usingnamespace @import("ast/base.zig"); usingnamespace @import("defines.zig"); const panicky = @import("panic_handler.zig"); +usingnamespace @import("global.zig"); const fs = @import("fs.zig"); - +const Schema = @import("api/schema.zig").Api; +const builtin = std.builtin; const MainPanicHandler = panicky.NewPanicHandler(panicky.default_panic); pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn { @@ -23,84 +25,186 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) nore } } -pub fn main() anyerror!void { - try alloc.setup(std.heap.page_allocator); - var log = logger.Log.init(alloc.dynamic); - var panicker = MainPanicHandler.init(&log); - MainPanicHandler.Singleton = &panicker; +var default_options = std.mem.zeroes(Schema.TransformOptions); + +pub const Uint8Array = packed struct { + pub const Float = @Type(builtin.TypeInfo{ .Float = .{ .bits = 2 * @bitSizeOf(usize) } }); + pub const Abi = if (builtin.target.isWasm()) Float else Uint8Array; + + ptr: [*]u8, + len: usize, + + pub fn toSlice(raw: Abi) []u8 { + const self = @bitCast(Uint8Array, raw); + return self.ptr[0..self.len]; + } + + pub fn fromSlice(slice: []u8) Abi { + const self = Uint8Array{ .ptr = slice.ptr, .len = slice.len }; + return @bitCast(Abi, self); + } + + pub fn empty() Abi { + return Uint8Array.fromSlice(&[0]u8{}); + } + + pub fn encode(comptime SchemaType: type, obj: SchemaType) !Abi { + var list = std.ArrayList(u8).init(alloc.dynamic); + var writer = list.writer(); + try obj.encode(writer); + return Uint8Array.fromSlice(list.toOwnedSlice()); + } + + pub fn decode(self: Abi, comptime SchemaType: type) !SchemaType { + var buf = Uint8Array.toSlice(self); + var stream = std.io.fixedBufferStream(buf); + return try SchemaType.decode(alloc.dynamic, stream.reader()); + } +}; + +pub fn constStrToU8(s: string) []u8 { + return @intToPtr([*]u8, @ptrToInt(s.ptr))[0..s.len]; +} + +pub const Api = struct { + options: *Schema.TransformOptions = &default_options, + files: std.ArrayList(string), + log: logger.Log, + + pub fn transform(self: *Api, request: Schema.Transform) !Schema.TransformResponse { + const opts = try options.TransformOptions.initUncached(alloc.dynamic, request.path.?, request.contents.?); + var source = logger.Source.initFile(opts.entry_point, alloc.dynamic); + + var ast: js_ast.Ast = undefined; + var raw_defines = RawDefines.init(alloc.static); + try raw_defines.put("process.env.NODE_ENV", "\"development\""); + + var user_defines = try DefineData.from_input(raw_defines, &self.log, alloc.static); + var define = try Define.init( + alloc.static, + user_defines, + ); + + switch (opts.loader) { + .json => { + var expr = try json_parser.ParseJSON(&source, &self.log, alloc.dynamic); + var stmt = js_ast.Stmt.alloc(alloc.dynamic, js_ast.S.ExportDefault{ + .value = js_ast.StmtOrExpr{ .expr = expr }, + .default_name = js_ast.LocRef{ .loc = logger.Loc{}, .ref = Ref{} }, + }, logger.Loc{ .start = 0 }); + + var part = js_ast.Part{ + .stmts = &([_]js_ast.Stmt{stmt}), + }; + + ast = js_ast.Ast.initTest(&([_]js_ast.Part{part})); + }, + .jsx, .tsx, .ts, .js => { + var parser = try js_parser.Parser.init(opts, &self.log, &source, define, alloc.dynamic); + var res = try parser.parse(); + ast = res.ast; + }, + else => { + Global.panic("Unsupported loader: {s}", .{opts.loader}); + }, + } + + var _linker = linker.Linker{}; + var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols}); + const printed = try js_printer.printAst( + alloc.dynamic, + ast, + js_ast.Symbol.Map.initList(symbols), + &source, + false, + js_printer.Options{ .to_module_ref = ast.module_ref orelse js_ast.Ref{ .inner_index = 0 } }, + &_linker, + ); + var output_files = try alloc.dynamic.alloc(Schema.OutputFile, 1); + var _data = printed.js[0..printed.js.len]; + var _path = constStrToU8(source.path.text); + + output_files[0] = Schema.OutputFile{ .data = _data, .path = _path }; + + var resp = std.mem.zeroes(Schema.TransformResponse); + resp.status = .success; + resp.files = output_files; + + return resp; + // var source = logger.Source.initFile(file: fs.File, allocator: *std.mem.Allocator) + } +}; + +pub const Exports = struct { + fn init() callconv(.C) u8 { + if (alloc.needs_setup) { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + var allocator = &arena.allocator; + alloc.setup(allocator) catch return 0; + } - const args = try std.process.argsAlloc(alloc.dynamic); - const stdout = std.io.getStdOut(); - const stderr = std.io.getStdErr(); + var _api = alloc.static.create(Api) catch return 0; - if (args.len < 1) { - const len = stderr.write("Pass a file"); - return; + _api.* = Api{ .files = std.ArrayList(string).init(alloc.dynamic), .log = logger.Log.init(alloc.dynamic) }; + api = _api; + + return 1; } - const absolutePath = args[args.len - 2]; - const pathname = fs.PathName.init(absolutePath); - const entryPointName = try alloc.dynamic.alloc(u8, pathname.base.len + pathname.ext.len); - std.mem.copy(u8, entryPointName, pathname.base); - std.mem.copy(u8, entryPointName[pathname.base.len..entryPointName.len], pathname.ext); - - const code = try std.io.getStdIn().readToEndAlloc(alloc.dynamic, 99999999); - - const opts = try options.TransformOptions.initUncached(alloc.dynamic, entryPointName, code); - var source = logger.Source.initFile(opts.entry_point, alloc.dynamic); - var ast: js_ast.Ast = undefined; - - var raw_defines = RawDefines.init(alloc.static); - try raw_defines.put("process.env.NODE_ENV", "\"development\""); - - var user_defines = try DefineData.from_input(raw_defines, &log, alloc.static); - - var define = try Define.init( - alloc.static, - user_defines, - ); - - switch (opts.loader) { - .json => { - var expr = try json_parser.ParseJSON(&source, &log, alloc.dynamic); - var stmt = js_ast.Stmt.alloc(alloc.dynamic, js_ast.S.ExportDefault{ - .value = js_ast.StmtOrExpr{ .expr = expr }, - .default_name = js_ast.LocRef{ .loc = logger.Loc{}, .ref = Ref{} }, - }, logger.Loc{ .start = 0 }); - - var part = js_ast.Part{ - .stmts = &([_]js_ast.Stmt{stmt}), - }; - - ast = js_ast.Ast.initTest(&([_]js_ast.Part{part})); - }, - .jsx, .tsx, .ts, .js => { - var parser = try js_parser.Parser.init(opts, &log, &source, define, alloc.dynamic); - var res = try parser.parse(); - ast = res.ast; - }, - else => { - std.debug.panic("Unsupported loader: {s}", .{opts.loader}); - }, + fn transform(abi: Uint8Array.Abi) callconv(.C) Uint8Array.Abi { + const req: Schema.Transform = Uint8Array.decode(abi, Schema.Transform) catch return Uint8Array.empty(); + alloc.dynamic.free(Uint8Array.toSlice(abi)); + const resp = api.?.transform(req) catch return Uint8Array.empty(); + return Uint8Array.encode(Schema.TransformResponse, resp) catch return Uint8Array.empty(); } - var _linker = linker.Linker{}; - var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols}); - const printed = try js_printer.printAst( - alloc.dynamic, - ast, - js_ast.Symbol.Map.initList(symbols), - false, - js_printer.Options{ .to_module_ref = ast.module_ref orelse js_ast.Ref{ .inner_index = 0 } }, - &_linker, - ); - - // if (std.builtin.mode == std.builtin.Mode.Debug) { - // var fixed_buffer = [_]u8{0} ** 512000; - // var buf_stream = std.io.fixedBufferStream(&fixed_buffer); - - // try ast.toJSON(alloc.dynamic, stderr.writer()); - // } - - _ = try stdout.write(printed.js); + fn malloc(size: usize) callconv(.C) ?*c_void { + if (size == 0) { + return null; + } + //const result = alloc.dynamic.alloc(u8, size) catch return null; + const result = alloc.dynamic.allocFn(alloc.dynamic, size, 1, 1, 0) catch return null; + return result.ptr; + } + fn calloc(num_elements: usize, element_size: usize) callconv(.C) ?*c_void { + const size = num_elements *% element_size; + const c_ptr = @call(.{ .modifier = .never_inline }, malloc, .{size}); + if (c_ptr) |ptr| { + const p = @ptrCast([*]u8, ptr); + @memset(p, 0, size); + } + return c_ptr; + } + fn realloc(c_ptr: ?*c_void, new_size: usize) callconv(.C) ?*c_void { + if (new_size == 0) { + @call(.{ .modifier = .never_inline }, free, .{c_ptr}); + return null; + } else if (c_ptr) |ptr| { + // Use a synthetic slice + const p = @ptrCast([*]u8, ptr); + const result = alloc.dynamic.realloc(p[0..1], new_size) catch return null; + return @ptrCast(*c_void, result.ptr); + } else { + return @call(.{ .modifier = .never_inline }, malloc, .{new_size}); + } + } + fn free(c_ptr: ?*c_void) callconv(.C) void { + if (c_ptr) |ptr| { + // Use a synthetic slice. zee_alloc will free via corresponding metadata. + const p = @ptrCast([*]u8, ptr); + //alloc.dynamic.free(p[0..1]); + _ = alloc.dynamic.resizeFn(alloc.dynamic, p[0..1], 0, 0, 0, 0) catch unreachable; + } + } +}; + +comptime { + @export(Exports.init, .{ .name = "init", .linkage = .Strong }); + @export(Exports.transform, .{ .name = "transform", .linkage = .Strong }); + @export(Exports.malloc, .{ .name = "malloc", .linkage = .Strong }); + @export(Exports.calloc, .{ .name = "calloc", .linkage = .Strong }); + @export(Exports.realloc, .{ .name = "realloc", .linkage = .Strong }); + @export(Exports.free, .{ .name = "free", .linkage = .Strong }); } + +var api: ?*Api = null; |