| ... | @@ -95,7 +95,7 @@ fn parseObject(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { | ... | @@ -95,7 +95,7 @@ fn parseObject(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 95 | if (members.entries.len == 0) { | 95 | if (members.entries.len == 0) { |
| 96 | return .empty_object; | 96 | return .empty_object; |
| 97 | } | 97 | } |
| 98 | return try p.addObject(alloc, &members); | 98 | return try p.addObject(&members); |
| 99 | } | 99 | } |
| 100 | | 100 | |
| 101 | fn parseArray(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { | 101 | fn parseArray(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| ... | @@ -132,7 +132,7 @@ fn parseArray(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { | ... | @@ -132,7 +132,7 @@ fn parseArray(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 132 | if (elements.items.len == 0) { | 132 | if (elements.items.len == 0) { |
| 133 | return .empty_array; | 133 | return .empty_array; |
| 134 | } | 134 | } |
| 135 | return try p.addArray(alloc, elements.items); | 135 | return try p.addArray(elements.items); |
| 136 | } | 136 | } |
| 137 | | 137 | |
| 138 | fn parseString(alloc: std.mem.Allocator, p: *Parser) anyerror!?StringIndex { | 138 | fn parseString(alloc: std.mem.Allocator, p: *Parser) anyerror!?StringIndex { |
| ... | @@ -179,7 +179,7 @@ fn parseString(alloc: std.mem.Allocator, p: *Parser) anyerror!?StringIndex { | ... | @@ -179,7 +179,7 @@ fn parseString(alloc: std.mem.Allocator, p: *Parser) anyerror!?StringIndex { |
| 179 | else => return error.MalformedJson, | 179 | else => return error.MalformedJson, |
| 180 | } | 180 | } |
| 181 | } | 181 | } |
| 182 | return try p.addStr(alloc, characters.items); | 182 | return try p.addStr(characters.items); |
| 183 | } | 183 | } |
| 184 | | 184 | |
| 185 | fn parseNumber(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { | 185 | fn parseNumber(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| ... | @@ -224,7 +224,7 @@ fn parseNumber(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { | ... | @@ -224,7 +224,7 @@ fn parseNumber(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 224 | if (characters.items.len == l) return error.MalformedJson; | 224 | if (characters.items.len == l) return error.MalformedJson; |
| 225 | } | 225 | } |
| 226 | | 226 | |
| 227 | return try p.addNumber(alloc, characters.items); | 227 | return try p.addNumber(characters.items); |
| 228 | } | 228 | } |
| 229 | | 229 | |
| 230 | fn parseWs(p: *Parser) !void { | 230 | fn parseWs(p: *Parser) !void { |
| ... | @@ -260,9 +260,9 @@ pub const Parser = struct { | ... | @@ -260,9 +260,9 @@ pub const Parser = struct { |
| 260 | p.parser.data.appendAssumeCapacity(@intFromEnum(Value.Tag.null)); | 260 | p.parser.data.appendAssumeCapacity(@intFromEnum(Value.Tag.null)); |
| 261 | p.parser.data.appendAssumeCapacity(@intFromEnum(Value.Tag.true)); | 261 | p.parser.data.appendAssumeCapacity(@intFromEnum(Value.Tag.true)); |
| 262 | p.parser.data.appendAssumeCapacity(@intFromEnum(Value.Tag.false)); | 262 | p.parser.data.appendAssumeCapacity(@intFromEnum(Value.Tag.false)); |
| 263 | _ = try p.addStr(allocator, ""); | 263 | _ = try p.addStr(""); |
| 264 | std.debug.assert(try p.addArray(allocator, &.{}) == .empty_array); | 264 | std.debug.assert(try p.addArray(&.{}) == .empty_array); |
| 265 | std.debug.assert(try p.addObject(allocator, &ObjectHashMap{}) == .empty_object); | 265 | std.debug.assert(try p.addObject(&ObjectHashMap{}) == .empty_object); |
| 266 | | 266 | |
| 267 | return p; | 267 | return p; |
| 268 | } | 268 | } |
| ... | @@ -280,10 +280,11 @@ pub const Parser = struct { | ... | @@ -280,10 +280,11 @@ pub const Parser = struct { |
| 280 | pub usingnamespace intrusive_parser.Mixin(@This()); | 280 | pub usingnamespace intrusive_parser.Mixin(@This()); |
| 281 | | 281 | |
| 282 | // tag(u8) + len(u32) + member_keys(N * u32) + member_values(N * u32) | 282 | // tag(u8) + len(u32) + member_keys(N * u32) + member_values(N * u32) |
| 283 | pub fn addObject(p: *Parser, alloc: std.mem.Allocator, members: *const ObjectHashMap) !ValueIndex { | 283 | pub fn addObject(p: *Parser, members: *const ObjectHashMap) !ValueIndex { |
| 284 | const t = tracer.trace(@src(), "({d})", .{members.entries.len}); | 284 | const t = tracer.trace(@src(), "({d})", .{members.entries.len}); |
| 285 | defer t.end(); | 285 | defer t.end(); |
| 286 | | 286 | |
| | 287 | const alloc = p.parser.allocator; |
| 287 | const r = p.parser.data.items.len; | 288 | const r = p.parser.data.items.len; |
| 288 | const l = members.entries.len; | 289 | const l = members.entries.len; |
| 289 | if (l > std.math.maxInt(u32)) return error.MalformedJson; | 290 | if (l > std.math.maxInt(u32)) return error.MalformedJson; |
| ... | @@ -295,22 +296,24 @@ pub const Parser = struct { | ... | @@ -295,22 +296,24 @@ pub const Parser = struct { |
| 295 | return @enumFromInt(r); | 296 | return @enumFromInt(r); |
| 296 | } | 297 | } |
| 297 | | 298 | |
| 298 | pub fn addObjectFromConst(p: *Parser, alloc: std.mem.Allocator, members: []const struct { StringIndex, ValueIndex }) !ValueIndex { | 299 | pub fn addObjectFromConst(p: *Parser, members: []const struct { StringIndex, ValueIndex }) !ValueIndex { |
| 299 | const t = tracer.trace(@src(), "({d})", .{members.len}); | 300 | const t = tracer.trace(@src(), "({d})", .{members.len}); |
| 300 | defer t.end(); | 301 | defer t.end(); |
| 301 | | 302 | |
| | 303 | const alloc = p.parser.allocator; |
| 302 | var map = ObjectHashMap{}; | 304 | var map = ObjectHashMap{}; |
| 303 | defer map.deinit(alloc); | 305 | defer map.deinit(alloc); |
| 304 | try map.ensureTotalCapacity(alloc, members.len); | 306 | try map.ensureTotalCapacity(alloc, members.len); |
| 305 | for (members) |member| map.putAssumeCapacity(member[0], member[1]); | 307 | for (members) |member| map.putAssumeCapacity(member[0], member[1]); |
| 306 | return p.addObject(alloc, &map); | 308 | return p.addObject(&map); |
| 307 | } | 309 | } |
| 308 | | 310 | |
| 309 | // tag(u8) + len(u32) + items(N * u32) | 311 | // tag(u8) + len(u32) + items(N * u32) |
| 310 | pub fn addArray(p: *Parser, alloc: std.mem.Allocator, items: []const ValueIndex) !ValueIndex { | 312 | pub fn addArray(p: *Parser, items: []const ValueIndex) !ValueIndex { |
| 311 | const t = tracer.trace(@src(), "({d})", .{items.len}); | 313 | const t = tracer.trace(@src(), "({d})", .{items.len}); |
| 312 | defer t.end(); | 314 | defer t.end(); |
| 313 | | 315 | |
| | 316 | const alloc = p.parser.allocator; |
| 314 | const r = p.parser.data.items.len; | 317 | const r = p.parser.data.items.len; |
| 315 | const l = items.len; | 318 | const l = items.len; |
| 316 | if (l > std.math.maxInt(u32)) return error.MalformedJson; | 319 | if (l > std.math.maxInt(u32)) return error.MalformedJson; |
| ... | @@ -322,16 +325,17 @@ pub const Parser = struct { | ... | @@ -322,16 +325,17 @@ pub const Parser = struct { |
| 322 | } | 325 | } |
| 323 | | 326 | |
| 324 | // tag(u8) + len(u32) + bytes(N) | 327 | // tag(u8) + len(u32) + bytes(N) |
| 325 | pub fn addStr(p: *Parser, alloc: std.mem.Allocator, str: string) !StringIndex { | 328 | pub fn addStr(p: *Parser, str: string) !StringIndex { |
| 326 | const t = tracer.trace(@src(), "({d})", .{str.len}); | 329 | const t = tracer.trace(@src(), "({d})", .{str.len}); |
| 327 | defer t.end(); | 330 | defer t.end(); |
| 328 | | 331 | |
| | 332 | const alloc = p.parser.allocator; |
| 329 | return @enumFromInt(try p.parser.addStr(alloc, str)); | 333 | return @enumFromInt(try p.parser.addStr(alloc, str)); |
| 330 | } | 334 | } |
| 331 | | 335 | |
| 332 | // tag(u8) + len(u32) + bytes(N) | 336 | // tag(u8) + len(u32) + bytes(N) |
| 333 | pub fn addStrV(p: *Parser, alloc: std.mem.Allocator, str: string) !ValueIndex { | 337 | pub fn addStrV(p: *Parser, str: string) !ValueIndex { |
| 334 | return @enumFromInt(@intFromEnum(try p.addStr(alloc, str))); | 338 | return @enumFromInt(@intFromEnum(try p.addStr(str))); |
| 335 | } | 339 | } |
| 336 | | 340 | |
| 337 | const Adapter = struct { | 341 | const Adapter = struct { |
| ... | @@ -351,10 +355,11 @@ pub const Parser = struct { | ... | @@ -351,10 +355,11 @@ pub const Parser = struct { |
| 351 | } | 355 | } |
| 352 | }; | 356 | }; |
| 353 | | 357 | |
| 354 | pub fn addNumber(p: *Parser, alloc: std.mem.Allocator, v: []const u8) !ValueIndex { | 358 | pub fn addNumber(p: *Parser, v: []const u8) !ValueIndex { |
| 355 | const t = tracer.trace(@src(), "({s})", .{v}); | 359 | const t = tracer.trace(@src(), "({s})", .{v}); |
| 356 | defer t.end(); | 360 | defer t.end(); |
| 357 | | 361 | |
| | 362 | const alloc = p.parser.allocator; |
| 358 | const adapter: AdapterNum = .{ .p = p }; | 363 | const adapter: AdapterNum = .{ .p = p }; |
| 359 | const res = try p.numbers_map.getOrPutAdapted(alloc, v, adapter); | 364 | const res = try p.numbers_map.getOrPutAdapted(alloc, v, adapter); |
| 360 | if (res.found_existing) return @enumFromInt(@intFromEnum(res.value_ptr.*)); | 365 | if (res.found_existing) return @enumFromInt(@intFromEnum(res.value_ptr.*)); |