[bun.js] Implement Blob

This commit is contained in:
Jarred Sumner
2022-03-13 06:08:10 -07:00
parent 6d71749c70
commit f4504292cf
17 changed files with 1546 additions and 635 deletions

View File

@@ -28,10 +28,15 @@ const To = Base.To;
const Request = WebCore.Request;
const d = Base.d;
const FetchEvent = WebCore.FetchEvent;
const URLPath = @import("../../../http/url_path.zig");
const URL = @import("../../../query_string_map.zig").URL;
route: *const FilesystemRouter.Match,
route_holder: FilesystemRouter.Match = undefined,
needs_deinit: bool = false,
query_string_map: ?QueryStringMap = null,
param_map: ?QueryStringMap = null,
params_list_holder: FilesystemRouter.Param.List = .{},
script_src: ?string = null,
script_src_buf: [1024]u8 = undefined,
@@ -65,42 +70,101 @@ pub fn match(
return null;
}
if (js.JSValueIsObjectOfClass(ctx, arguments[0], FetchEvent.Class.get().*)) {
if (FetchEvent.Class.loaded and js.JSValueIsObjectOfClass(ctx, arguments[0], FetchEvent.Class.get().*)) {
return matchFetchEvent(ctx, To.Zig.ptr(FetchEvent, arguments[0]), exception);
}
// if (js.JSValueIsString(ctx, arguments[0])) {
// return matchPathName(ctx, arguments[0], exception);
// }
if (js.JSValueIsObjectOfClass(ctx, arguments[0], Request.Class.get().*)) {
return matchRequest(ctx, To.Zig.ptr(Request, arguments[0]), exception);
var router = JavaScript.VirtualMachine.vm.bundler.router orelse {
JSError(getAllocator(ctx), "Bun.match needs a framework configured with routes", .{}, ctx, exception);
return null;
};
var arg = JSC.JSValue.fromRef(arguments[0]);
var path_: ?ZigString.Slice = null;
var pathname: string = "";
defer {
if (path_) |path| {
path.deinit();
}
}
return null;
if (arg.isString()) {
var path_string = arg.getZigString(ctx.ptr());
path_ = path_string.toSlice(bun.default_allocator);
var url = URL.parse(path_.?.slice());
pathname = url.pathname;
} else if (arg.as(Request)) |req| {
var path_string = req.url;
path_ = path_string.toSlice(bun.default_allocator);
var url = URL.parse(path_.?.slice());
pathname = url.pathname;
}
if (path_ == null) {
JSError(getAllocator(ctx), "Expected string, FetchEvent, or Request", .{}, ctx, exception);
return null;
}
const url_path = URLPath.parse(path_.?.slice()) catch {
JSError(getAllocator(ctx), "Could not parse URL path", .{}, ctx, exception);
return null;
};
var match_params_fallback = std.heap.stackFallback(1024, bun.default_allocator);
var match_params_allocator = match_params_fallback.get();
var match_params = FilesystemRouter.Param.List{};
match_params.ensureTotalCapacity(match_params_allocator, 16) catch unreachable;
var prev_allocator = router.routes.allocator;
router.routes.allocator = match_params_allocator;
defer router.routes.allocator = prev_allocator;
if (router.routes.matchPage("", url_path, &match_params)) |matched| {
var match_ = matched;
var params_list = match_.params.clone(bun.default_allocator) catch unreachable;
var instance = getAllocator(ctx).create(Router) catch unreachable;
instance.* = Router{
.route_holder = match_,
.route = undefined,
};
instance.params_list_holder = params_list;
instance.route = &instance.route_holder;
instance.route_holder.params = &instance.params_list_holder;
instance.script_src_buf_writer = ScriptSrcStream{ .pos = 0, .buffer = std.mem.span(&instance.script_src_buf) };
return Instance.make(ctx, instance);
}
// router.routes.matchPage
return JSC.JSValue.jsNull().asObjectRef();
}
fn matchRequest(
ctx: js.JSContextRef,
request: *const Request,
exception: js.ExceptionRef,
_: js.ExceptionRef,
) js.JSObjectRef {
return createRouteObject(ctx, request.request_context, exception);
return createRouteObject(ctx, request.request_context);
}
fn matchFetchEvent(
ctx: js.JSContextRef,
fetch_event: *const FetchEvent,
exception: js.ExceptionRef,
_: js.ExceptionRef,
) js.JSObjectRef {
return createRouteObject(ctx, fetch_event.request_context, exception);
return createRouteObject(ctx, fetch_event.request_context);
}
fn createRouteObject(ctx: js.JSContextRef, req: *const http.RequestContext, _: js.ExceptionRef) js.JSValueRef {
fn createRouteObject(ctx: js.JSContextRef, req: *const http.RequestContext) js.JSValueRef {
const route = &(req.matched_route orelse {
return js.JSValueMakeNull(ctx);
});
return createRouteObjectFromMatch(ctx, route);
}
fn createRouteObjectFromMatch(
ctx: js.JSContextRef,
route: *const FilesystemRouter.Match,
) js.JSValueRef {
var router = getAllocator(ctx).create(Router) catch unreachable;
router.* = Router{
.route = route,
@@ -276,6 +340,13 @@ pub fn finalize(
if (this.query_string_map) |*map| {
map.deinit();
}
if (this.needs_deinit) {
this.params_list_holder.deinit(bun.default_allocator);
this.params_list_holder = .{};
this.needs_deinit = false;
bun.default_allocator.destroy(this);
}
}
pub fn getPathname(

View File

@@ -1720,6 +1720,17 @@ pub const ArrayBuffer = extern struct {
}
pub fn toJS(this: ArrayBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.JSValue {
if (this.typed_array_type == .ArrayBuffer) {
return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(
ctx,
this.ptr,
this.byte_len,
MarkedArrayBuffer_deallocator,
@intToPtr(*anyopaque, @ptrToInt(&bun.default_allocator)),
exception,
));
}
return JSC.JSValue.fromRef(JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy(
ctx,
this.typed_array_type.toC(),
@@ -1865,39 +1876,41 @@ const DocType = JSC.Cloudflare.DocType;
const EndTag = JSC.Cloudflare.EndTag;
const DocEnd = JSC.Cloudflare.DocEnd;
const AttributeIterator = JSC.Cloudflare.AttributeIterator;
const Blob = JSC.WebCore.Blob;
pub const JSPrivateDataPtr = TaggedPointerUnion(.{
ResolveError,
BuildError,
Response,
Request,
FetchEvent,
Headers,
AttributeIterator,
BigIntStats,
Blob,
Body,
Router,
BuildError,
Comment,
DescribeScope,
DirEnt,
DocEnd,
DocType,
Element,
EndTag,
Expect,
ExpectPrototype,
FetchEvent,
FetchTaskletContext,
Headers,
HTMLRewriter,
JSNode,
LazyPropertiesObject,
ModuleNamespace,
FetchTaskletContext,
DescribeScope,
Expect,
ExpectPrototype,
NodeFS,
Request,
ResolveError,
Response,
Router,
Stats,
BigIntStats,
DirEnt,
Transpiler,
TextEncoder,
TextDecoder,
TimeoutTask,
HTMLRewriter,
Element,
Comment,
TextChunk,
DocType,
EndTag,
DocEnd,
AttributeIterator,
TextDecoder,
TextEncoder,
TimeoutTask,
Transpiler,
});
pub inline fn GetJSPrivateData(comptime Type: type, ref: js.JSObjectRef) ?*Type {

View File

@@ -1,4 +1,5 @@
#include "BunClientData.h"
#include "GCDefferalContext.h"
#include "ZigGlobalObject.h"
#include "helpers.h"
#include "root.h"
@@ -42,7 +43,6 @@
#include <wtf/text/StringImpl.h>
#include <wtf/text/StringView.h>
#include <wtf/text/WTFString.h>
extern "C" {
JSC__JSValue SystemError__toErrorInstance(const SystemError* arg0,
@@ -237,12 +237,20 @@ void JSC__JSValue__jsonStringify(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg
unsigned char JSC__JSValue__jsType(JSC__JSValue JSValue0)
{
JSC::JSValue jsValue = JSC::JSValue::decode(JSValue0);
if (JSC::JSCell* cell = jsValue.asCell())
return cell->type();
// if the value is NOT a cell
// asCell will return an invalid pointer rather than a nullptr
if (jsValue.isCell())
return jsValue.asCell()->type();
return 0;
}
JSC__JSValue JSC__JSValue__parseJSON(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1)
{
JSC::JSValue jsValue = JSC::JSValue::decode(JSValue0);
return JSC::JSValue::encode(JSC::JSONParse(arg1, jsValue.toWTFString(arg1)));
}
void JSC__JSGlobalObject__deleteModuleRegistryEntry(JSC__JSGlobalObject* global, ZigString* arg1)
{
JSC::JSMap* map = JSC::jsDynamicCast<JSC::JSMap*>(
@@ -2148,6 +2156,14 @@ void JSC__VM__holdAPILock(JSC__VM* arg0, void* ctx, void (*callback)(void* arg0)
callback(ctx);
}
void JSC__VM__deferGC(JSC__VM* vm, void* ctx, void (*callback)(void* arg0))
{
JSC::GCDeferralContext deferralContext(reinterpret_cast<JSC__VM&>(vm));
JSC::DisallowGC disallowGC;
callback(ctx);
}
void JSC__VM__deleteAllCode(JSC__VM* arg1, JSC__JSGlobalObject* globalObject)
{
JSC::JSLockHolder locker(globalObject->vm());

View File

@@ -88,6 +88,18 @@ pub const ZigString = extern struct {
ptr: [*]const u8,
len: usize,
pub fn clone(this: ZigString, allocator: std.mem.Allocator) !ZigString {
var sliced = this.toSlice(allocator);
if (!sliced.allocated) {
var str = ZigString.init(try allocator.dupe(u8, sliced.slice()));
str.mark();
str.markUTF8();
return str;
}
return this;
}
pub const shim = Shimmer("", "ZigString", @This());
pub const Slice = struct {
@@ -106,7 +118,7 @@ pub const ZigString = extern struct {
return @intToPtr([*]u8, @ptrToInt(this.ptr))[0..this.len];
}
pub fn deinit(this: *Slice) void {
pub fn deinit(this: *const Slice) void {
if (!this.allocated) {
return;
}
@@ -261,7 +273,7 @@ pub const ZigString = extern struct {
}
pub fn trimmedSlice(this: *const ZigString) []const u8 {
return std.mem.trim(u8, this.ptr[0..@minimum(this.len, std.math.maxInt(u32))], " \r\n");
return strings.trim(this.ptr[0..@minimum(this.len, std.math.maxInt(u32))], " \r\n");
}
pub fn toValueAuto(this: *const ZigString, global: *JSGlobalObject) JSValue {
@@ -1603,6 +1615,7 @@ pub const JSValue = enum(u64) {
GetterSetter,
CustomGetterSetter,
/// For 32-bit architectures, this wraps a 64-bit JSValue
APIValueWrapper,
NativeExecutable,
@@ -1824,6 +1837,16 @@ pub const JSValue = enum(u64) {
return cppFn("jsType", .{this});
}
pub fn jsTypeLoose(
this: JSValue,
) JSType {
if (this.isNumber()) {
return JSType.NumberObject;
}
return this.jsType();
}
pub fn createEmptyObject(global: *JSGlobalObject, len: usize) JSValue {
return cppFn("createEmptyObject", .{ global, len });
}
@@ -2230,6 +2253,13 @@ pub const JSValue = enum(u64) {
});
}
pub fn parseJSON(this: JSValue, globalObject: *JSGlobalObject) JSValue {
return cppFn("parseJSON", .{
this,
globalObject,
});
}
pub inline fn asRef(this: JSValue) C_API.JSValueRef {
return @intToPtr(C_API.JSValueRef, @intCast(usize, @enumToInt(this)));
}
@@ -2246,7 +2276,7 @@ pub const JSValue = enum(u64) {
return @intToPtr(*anyopaque, @enumToInt(this));
}
pub const Extern = [_][]const u8{ "symbolKeyFor", "symbolFor", "getSymbolDescription", "createInternalPromise", "asInternalPromise", "asArrayBuffer_", "getReadableStreamState", "getWritableStreamState", "fromEntries", "createTypeError", "createRangeError", "createObject2", "getIfPropertyExistsImpl", "jsType", "jsonStringify", "kind_", "isTerminationException", "isSameValue", "getLengthOfArray", "toZigString", "createStringArray", "createEmptyObject", "putRecord", "asPromise", "isClass", "getNameProperty", "getClassName", "getErrorsProperty", "toInt32", "toBoolean", "isInt32", "isIterable", "forEach", "isAggregateError", "toZigException", "isException", "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "getIfExists", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isUndefined", "isNull", "isUndefinedOrNull", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell", "isCallable" };
pub const Extern = [_][]const u8{ "parseJSON", "symbolKeyFor", "symbolFor", "getSymbolDescription", "createInternalPromise", "asInternalPromise", "asArrayBuffer_", "getReadableStreamState", "getWritableStreamState", "fromEntries", "createTypeError", "createRangeError", "createObject2", "getIfPropertyExistsImpl", "jsType", "jsonStringify", "kind_", "isTerminationException", "isSameValue", "getLengthOfArray", "toZigString", "createStringArray", "createEmptyObject", "putRecord", "asPromise", "isClass", "getNameProperty", "getClassName", "getErrorsProperty", "toInt32", "toBoolean", "isInt32", "isIterable", "forEach", "isAggregateError", "toZigException", "isException", "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "getIfExists", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isUndefined", "isNull", "isUndefinedOrNull", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell", "isCallable" };
};
extern "c" fn Microtask__run(*Microtask, *JSGlobalObject) void;
@@ -2386,6 +2416,10 @@ pub const VM = extern struct {
cppFn("holdAPILock", .{ this, ctx, callback });
}
pub fn deferGC(this: *VM, ctx: ?*anyopaque, callback: fn (ctx: ?*anyopaque) callconv(.C) void) void {
cppFn("deferGC", .{ this, ctx, callback });
}
pub fn deleteAllCode(
vm: *VM,
global_object: *JSGlobalObject,
@@ -2459,7 +2493,7 @@ pub const VM = extern struct {
});
}
pub const Extern = [_][]const u8{ "holdAPILock", "runGC", "generateHeapSnapshot", "isJITEnabled", "deleteAllCode", "create", "deinit", "setExecutionForbidden", "executionForbidden", "isEntered", "throwError", "drainMicrotasks", "whenIdle", "shrinkFootprint", "setExecutionTimeLimit", "clearExecutionTimeLimit" };
pub const Extern = [_][]const u8{ "deferGC", "holdAPILock", "runGC", "generateHeapSnapshot", "isJITEnabled", "deleteAllCode", "create", "deinit", "setExecutionForbidden", "executionForbidden", "isEntered", "throwError", "drainMicrotasks", "whenIdle", "shrinkFootprint", "setExecutionTimeLimit", "clearExecutionTimeLimit" };
};
pub const ThrowScope = extern struct {

View File

@@ -1,4 +1,4 @@
//-- AUTOGENERATED FILE -- 1647061500
//-- AUTOGENERATED FILE -- 1647165586
// clang-format off
#pragma once

View File

@@ -1,5 +1,5 @@
// clang-format: off
//-- AUTOGENERATED FILE -- 1647061500
//-- AUTOGENERATED FILE -- 1647165586
#pragma once
#include <stddef.h>
@@ -490,6 +490,7 @@ CPP_DECL void JSC__JSValue__jsonStringify(JSC__JSValue JSValue0, JSC__JSGlobalOb
CPP_DECL JSC__JSValue JSC__JSValue__jsTDZValue();
CPP_DECL unsigned char JSC__JSValue__jsType(JSC__JSValue JSValue0);
CPP_DECL JSC__JSValue JSC__JSValue__jsUndefined();
CPP_DECL JSC__JSValue JSC__JSValue__parseJSON(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1);
CPP_DECL void JSC__JSValue__putRecord(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, ZigString* arg2, ZigString* arg3, size_t arg4);
CPP_DECL JSC__JSValue JSC__JSValue__symbolFor(JSC__JSGlobalObject* arg0, ZigString* arg1);
CPP_DECL bool JSC__JSValue__symbolKeyFor(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, ZigString* arg2);
@@ -522,6 +523,7 @@ CPP_DECL JSC__JSValue JSC__Exception__value(JSC__Exception* arg0);
CPP_DECL void JSC__VM__clearExecutionTimeLimit(JSC__VM* arg0);
CPP_DECL JSC__VM* JSC__VM__create(unsigned char HeapType0);
CPP_DECL void JSC__VM__deferGC(JSC__VM* arg0, void* arg1, void (* ArgFn2)(void* arg0));
CPP_DECL void JSC__VM__deinit(JSC__VM* arg0, JSC__JSGlobalObject* arg1);
CPP_DECL void JSC__VM__deleteAllCode(JSC__VM* arg0, JSC__JSGlobalObject* arg1);
CPP_DECL void JSC__VM__drainMicrotasks(JSC__VM* arg0);

View File

@@ -338,6 +338,7 @@ pub extern fn JSC__JSValue__jsonStringify(JSValue0: JSC__JSValue, arg1: [*c]JSC_
pub extern fn JSC__JSValue__jsTDZValue(...) JSC__JSValue;
pub extern fn JSC__JSValue__jsType(JSValue0: JSC__JSValue) u8;
pub extern fn JSC__JSValue__jsUndefined(...) JSC__JSValue;
pub extern fn JSC__JSValue__parseJSON(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject) JSC__JSValue;
pub extern fn JSC__JSValue__putRecord(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, arg2: [*c]ZigString, arg3: [*c]ZigString, arg4: usize) void;
pub extern fn JSC__JSValue__symbolFor(arg0: [*c]JSC__JSGlobalObject, arg1: [*c]ZigString) JSC__JSValue;
pub extern fn JSC__JSValue__symbolKeyFor(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, arg2: [*c]ZigString) bool;
@@ -360,6 +361,7 @@ pub extern fn JSC__Exception__getStackTrace(arg0: [*c]JSC__Exception, arg1: [*c]
pub extern fn JSC__Exception__value(arg0: [*c]JSC__Exception) JSC__JSValue;
pub extern fn JSC__VM__clearExecutionTimeLimit(arg0: [*c]JSC__VM) void;
pub extern fn JSC__VM__create(HeapType0: u8) [*c]JSC__VM;
pub extern fn JSC__VM__deferGC(arg0: [*c]JSC__VM, arg1: ?*anyopaque, ArgFn2: ?fn (?*anyopaque) callconv(.C) void) void;
pub extern fn JSC__VM__deinit(arg0: [*c]JSC__VM, arg1: [*c]JSC__JSGlobalObject) void;
pub extern fn JSC__VM__deleteAllCode(arg0: [*c]JSC__VM, arg1: [*c]JSC__JSGlobalObject) void;
pub extern fn JSC__VM__drainMicrotasks(arg0: [*c]JSC__VM) void;

View File

@@ -111,7 +111,7 @@ static bool isTaggedExternalPtr(const unsigned char* ptr)
static const WTF::String toString(ZigString str)
{
if (str.len == 0 || str.ptr == nullptr) {
return WTF::Stzring();
return WTF::String();
}
if (UNLIKELY(isTaggedUTF8Ptr(str.ptr))) {
return WTF::String::fromUTF8(untag(str.ptr), str.len);

View File

@@ -102,6 +102,7 @@ pub const GlobalClasses = [_]type{
WebCore.TextDecoder.Constructor.Class,
JSC.Cloudflare.HTMLRewriter.Class,
WebCore.Blob.Class,
// The last item in this array becomes "process.env"
Bun.EnvironmentVariables.Class,
@@ -1951,16 +1952,19 @@ pub const VirtualMachine = struct {
}
}
pub fn tick(this: *EventLoop) void {
this.tickConcurrent();
while (true) {
this.tickConcurrent();
while (this.tickWithCount() > 0) {}
this.tickConcurrent();
while (this.tickWithCount() > 0) {}
if (this.tickWithCount() == 0) break;
}
}
pub fn waitForTasks(this: *EventLoop) void {
this.tickConcurrent();
this.tick();
while (this.pending_tasks_count.load(.Monotonic) > 0) {
while (this.tickWithCount() > 0) {}
this.tick();
}
}
@@ -3429,7 +3433,7 @@ pub const EventListenerMixin = struct {
fetch_event.* = FetchEvent{
.request_context = request_context,
.request = Request{ .request_context = request_context },
.request = try Request.fromRequestContext(request_context),
.onPromiseRejectionCtx = @as(*anyopaque, ctx),
.onPromiseRejectionHandler = FetchEventRejectionHandler.onRejection,
};

View File

@@ -391,6 +391,7 @@ pub const ArgumentsSlice = struct {
remaining: []const JSC.JSValue,
arena: std.heap.ArenaAllocator = std.heap.ArenaAllocator.init(bun.default_allocator),
all: []const JSC.JSValue,
threw: bool = false,
pub fn from(arguments: []const JSC.JSValueRef) ArgumentsSlice {
return init(@ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]);

View File

@@ -685,17 +685,20 @@ pub const TestScope = struct {
this.promise = null;
}
while (this.promise.?.status(vm.global.vm()) == JSC.JSPromise.Status.Pending) {
var status = JSC.JSPromise.Status.Pending;
var vm_ptr = vm.global.vm();
while (this.promise != null and status == JSC.JSPromise.Status.Pending) : (status = this.promise.?.status(vm_ptr)) {
vm.tick();
}
switch (this.promise.?.status(vm.global.vm())) {
switch (status) {
.Rejected => {
vm.defaultErrorHandler(this.promise.?.result(vm.global.vm()), null);
return .{ .fail = this.counter.actual };
},
else => {
// don't care about the result
_ = this.promise.?.result(vm.global.vm());
if (this.promise != null)
// don't care about the result
_ = this.promise.?.result(vm.global.vm());
},
}
}
@@ -849,8 +852,11 @@ pub const DescribeScope = struct {
var i: TestRunner.Test.ID = 0;
while (i < end) {
// the test array could resize in the middle of this loop
this.current_test_id = i;
const result = TestScope.run(&tests[i]);
var test_ = tests[i];
const result = TestScope.run(&test_);
tests[i] = test_;
// invalidate it
this.current_test_id = std.math.maxInt(TestRunner.Test.ID);

File diff suppressed because it is too large Load Diff