aboutsummaryrefslogtreecommitdiff
path: root/src/main_wasm.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-07 01:26:26 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-07 01:26:26 -0700
commitfad34bb4abfe1715d4febec6e7de2809bfffb4e2 (patch)
tree6616f92155a3473c228e46f3c5693c47548761e9 /src/main_wasm.zig
parentdd9e7de689dafb29ed3e79e2b7af54ea097f75e9 (diff)
downloadbun-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.zig254
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;