Skip to content

Commit

Permalink
feat(sandboxing): -Dmemory_limit
Browse files Browse the repository at this point in the history
  • Loading branch information
giann committed Jan 19, 2024
1 parent 62d1b8e commit 3a7281a
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 9 deletions.
7 changes: 7 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const BuzzGCOptions = struct {
initial_gc: usize,
next_gc_ratio: usize,
next_full_gc_ratio: usize,
memory_limit: ?usize,

pub fn step(self: BuzzGCOptions, options: *Build.Step.Options) void {
options.addOption(@TypeOf(self.debug), "gc_debug", self.debug);
Expand All @@ -51,6 +52,7 @@ const BuzzGCOptions = struct {
options.addOption(@TypeOf(self.initial_gc), "initial_gc", self.initial_gc);
options.addOption(@TypeOf(self.next_gc_ratio), "next_gc_ratio", self.next_gc_ratio);
options.addOption(@TypeOf(self.next_full_gc_ratio), "next_full_gc_ratio", self.next_full_gc_ratio);
options.addOption(@TypeOf(self.memory_limit), "memory_limit", self.memory_limit);
}
};

Expand Down Expand Up @@ -211,6 +213,11 @@ pub fn build(b: *Build) !void {
"next_full_gc_ratio",
"Ratio applied to get the next full GC threshold",
) orelse 4,
.memory_limit = b.option(
usize,
"memory_limit",
"Memory limit",
) orelse null,
},
.jit = .{
.debug = b.option(
Expand Down
1 change: 1 addition & 0 deletions src/Codegen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub const Error = error{
CantCompile,
UnwrappedNull,
OutOfBound,
ReachedMaximumMemoryUsage,
} || std.mem.Allocator.Error || std.fmt.BufPrintError;

pub const Frame = struct {
Expand Down
7 changes: 6 additions & 1 deletion src/Jit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ const ZigType = @import("zigtypes.zig").Type;
const ExternApi = @import("jit_extern_api.zig").ExternApi;
const api = @import("lib/buzz_api.zig");

pub const Error = error{ CantCompile, UnwrappedNull, OutOfBound } || std.mem.Allocator.Error || std.fmt.BufPrintError;
pub const Error = error{
CantCompile,
UnwrappedNull,
OutOfBound,
ReachedMaximumMemoryUsage,
} || std.mem.Allocator.Error || std.fmt.BufPrintError;

const OptJump = struct {
current_insn: std.ArrayList(m.MIR_insn_t),
Expand Down
5 changes: 5 additions & 0 deletions src/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ pub const Error = error{
CantCompile,
UnwrappedNull,
OutOfBound,
ReachedMaximumMemoryUsage,
} || std.mem.Allocator.Error || std.fmt.BufPrintError || CompileError;

const ParseFn = *const fn (*Self, bool) Error!Ast.Node.Index;
Expand Down Expand Up @@ -708,6 +709,10 @@ pub fn parse(self: *Self, source: []const u8, file_name: []const u8) !?Ast {
}
} else {
if (self.declaration() catch |err| {
if (err == error.ReachedMaximumMemoryUsage) {
return err;
}

if (BuildOptions.debug) {
std.debug.print("Parsing failed with error {}\n", .{err});
}
Expand Down
14 changes: 8 additions & 6 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,10 @@ pub fn main() !void {

if (flavor == .Repl) {
repl(allocator) catch |err| {
if (BuildOptions.debug) {
std.debug.print("Failed with error {}\n", .{err});
}
std.io.getStdErr().writer().print(
"Failed with error {s}\n",
.{@errorName(err)},
) catch unreachable;

std.os.exit(1);
};
Expand All @@ -277,9 +278,10 @@ pub fn main() !void {
positionals.items[1..],
flavor,
) catch |err| {
if (BuildOptions.debug) {
std.debug.print("Failed with error {}\n", .{err});
}
std.io.getStdErr().writer().print(
"Failed with error {s}\n",
.{@errorName(err)},
) catch unreachable;

std.os.exit(1);
};
Expand Down
4 changes: 4 additions & 0 deletions src/memory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ pub const GarbageCollector = struct {
try self.collectGarbage();
}

if (BuildOptions.memory_limit != null and self.bytes_allocated > BuildOptions.memory_limit.?) {
return error.ReachedMaximumMemoryUsage;
}

const allocated = try self.allocator.create(T);

if (BuildOptions.gc_debug) {
Expand Down
2 changes: 1 addition & 1 deletion src/obj.zig
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ pub const Obj = struct {
}
}

pub fn typeOf(self: *Self, gc: *GarbageCollector) error{ OutOfMemory, NoSpaceLeft }!*ObjTypeDef {
pub fn typeOf(self: *Self, gc: *GarbageCollector) error{ OutOfMemory, NoSpaceLeft, ReachedMaximumMemoryUsage }!*ObjTypeDef {
return switch (self.obj_type) {
.String => try gc.type_registry.getTypeDef(.{ .def_type = .String }),
.Pattern => try gc.type_registry.getTypeDef(.{ .def_type = .Pattern }),
Expand Down
1 change: 1 addition & 0 deletions src/vm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ pub const VM = struct {
NotInFiber,
FiberOver,
BadNumber,
ReachedMaximumMemoryUsage,
Custom, // TODO: remove when user can use this set directly in buzz code
} || Allocator.Error || std.fmt.BufPrintError;

Expand Down
2 changes: 1 addition & 1 deletion tests/bench/001-btree.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fun btree(int N) > void {
}

fun main([str] args) > void !> any {
int N = if (args.len() > 0) parseInt(args[0]) ?? 0 else 0;
int N = if (args.len() > 0) parseInt(args[0]) ?? 3 else 3;

btree(N);
}

0 comments on commit 3a7281a

Please sign in to comment.