Skip to content

Commit

Permalink
continue Object rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexicon226 committed Jul 11, 2024
1 parent 09ac268 commit 8275816
Show file tree
Hide file tree
Showing 18 changed files with 513 additions and 825 deletions.
175 changes: 57 additions & 118 deletions src/compiler/CodeObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const Marshal = @import("Marshal.zig");
const Instruction = @import("Instruction.zig");
const OpCode = @import("opcodes.zig").OpCode;
const Object = @import("../vm/Object.zig");
const Result = Marshal.Result;
const Reference = Marshal.Reference;
const FlagRef = Marshal.FlagRef;

Expand All @@ -18,91 +17,41 @@ const CodeObject = @This();
name: []const u8,
filename: []const u8,

consts: Object,
names: Object,
consts: *const Object,
names: *const Object,
varnames: *const Object,

/// https://github.com/python/cpython/blob/3.10/Objects/lnotab_notes.txt
lnotab_obj: Object,
lnotab: std.AutoHashMapUnmanaged(u32, u32) = .{},
// lnotab_obj: Object,
// lnotab: std.AutoHashMapUnmanaged(u32, u32) = .{},

argcount: u32,
posonlyargcount: u32,
kwonlyargcount: u32,
stacksize: u32,
nlocals: u32,
firstlineno: u32,

code: []const u8,
flags: u32,

/// Only exist after `co.process()` is run.
instructions: ?[]const Instruction = null,
instructions: []const Instruction,

// variable elements of the codeobject
varnames: []Object,
index: usize = 0,

/// Assumes the same allocator was used to allocate every field
pub fn deinit(co: *CodeObject, allocator: std.mem.Allocator) void {
pub fn deinit(co: *const CodeObject, allocator: std.mem.Allocator) void {
allocator.free(co.name);
allocator.free(co.filename);
allocator.free(co.code);

co.consts.deinit(allocator);
co.names.deinit(allocator);
co.varnames.deinit(allocator);
// co.freevars.deinit(allocator);
// co.cellvars.deinit(allocator);

for (co.varnames) |*varname| {
varname.deinit(allocator);
}
allocator.free(co.varnames);

if (co.instructions) |insts| {
allocator.free(insts);
}

co.lnotab.deinit(allocator);
co.lnotab_obj.deinit(allocator);
allocator.free(co.instructions);

co.* = undefined;
}

/// Duplicates the CodeObject and allocates using the provided allocator.
///
/// Caller owns the memory.
pub fn clone(co: *const CodeObject, allocator: std.mem.Allocator) !CodeObject {
return .{
.name = try allocator.dupe(u8, co.name),
.filename = try allocator.dupe(u8, co.filename),
.code = try allocator.dupe(u8, co.code),

.argcount = co.argcount,
.posonlyargcount = co.posonlyargcount,
.kwonlyargcount = co.kwonlyargcount,
.stacksize = co.stacksize,
.nlocals = co.nlocals,
.firstlineno = co.firstlineno,
.flags = co.flags,

.consts = try co.consts.clone(allocator),
.names = try co.names.clone(allocator),
// .freevars = try co.freevars.clone(allocator),
// .cellvars = try co.cellvars.clone(allocator),
.lnotab_obj = try co.lnotab_obj.clone(allocator),

.instructions = if (co.instructions) |insts| try allocator.dupe(Instruction, insts) else null,
.lnotab = try co.lnotab.clone(allocator),

.varnames = varnames: {
const new_varnames = try allocator.alloc(Object, co.varnames.len);
for (new_varnames, co.varnames) |*new_varname, varname| {
new_varname.* = try varname.clone(allocator);
}
break :varnames new_varnames;
},
.index = co.index,
};
// co.lnotab.deinit(allocator);
// co.lnotab_obj.deinit(allocator);
}

pub fn format(
Expand All @@ -119,35 +68,35 @@ pub fn format(
try writer.print("Argument count:\t{d}\n", .{self.argcount});
try writer.print("Stack size:\t{d}\n", .{self.stacksize});

const consts_tuple = self.consts.get(.tuple);
if (consts_tuple.len != 0) {
try writer.writeAll("Constants:\n");
for (consts_tuple, 0..) |con, i| {
try writer.print("\t{d}: {}\n", .{ i, con });
}
}

const names_tuple = self.names.get(.tuple);
if (names_tuple.len != 0) {
try writer.writeAll("Names:\n");
for (names_tuple, 0..) |name, i| {
try writer.print("\t{d}: {}\n", .{ i, name });
}
}

if (self.varnames.len != 0) {
try writer.writeAll("Variables:\n");
for (self.varnames, 0..) |varname, i| {
try writer.print("\t{d}: {}\n", .{ i, varname });
}
}
// const consts_tuple = self.consts.get(.tuple);
// if (consts_tuple.len != 0) {
// try writer.writeAll("Constants:\n");
// for (consts_tuple, 0..) |con, i| {
// try writer.print("\t{d}: {}\n", .{ i, con });
// }
// }

// const names_tuple = self.names.get(.tuple);
// if (names_tuple.len != 0) {
// try writer.writeAll("Names:\n");
// for (names_tuple, 0..) |name, i| {
// try writer.print("\t{d}: {}\n", .{ i, name });
// }
// }

// if (self.varnames.len != 0) {
// try writer.writeAll("Variables:\n");
// for (self.varnames, 0..) |varname, i| {
// try writer.print("\t{d}: {}\n", .{ i, varname });
// }
// }
}

pub fn process(
co: *CodeObject,
bytes: []const u8,
allocator: std.mem.Allocator,
) !void {
const bytes = co.code;
const num_instructions = bytes.len / 2;
const instructions = try allocator.alloc(Instruction, num_instructions);

Expand All @@ -163,44 +112,34 @@ pub fn process(

co.instructions = instructions;
co.index = 0;
try co.unpackLnotab(allocator);
// try co.unpackLnotab(allocator);
}

pub fn unpackLnotab(
co: *CodeObject,
allocator: std.mem.Allocator,
) !void {
const lnotab = co.lnotab_obj;
const array = lnotab.get(.string);

var lineno: u32 = 0;
var addr: u32 = 0;

var iter = std.mem.window(u8, array, 2, 2);
while (iter.next()) |entry| {
const addr_incr, var line_incr = entry[0..2].*;
addr += addr_incr;
if (line_incr >= 0x80) {
line_incr -%= 255;
}
lineno += line_incr;

try co.lnotab.put(allocator, addr, lineno);
}
}
// pub fn unpackLnotab(
// co: *CodeObject,
// allocator: std.mem.Allocator,
// ) !void {
// const lnotab = co.lnotab_obj;
// const array = lnotab.get(.string);

// var lineno: u32 = 0;
// var addr: u32 = 0;

// var iter = std.mem.window(u8, array, 2, 2);
// while (iter.next()) |entry| {
// const addr_incr, var line_incr = entry[0..2].*;
// addr += addr_incr;
// if (line_incr >= 0x80) {
// line_incr -%= 255;
// }
// lineno += line_incr;

// try co.lnotab.put(allocator, addr, lineno);
// }
// }

// Helper functions

pub fn getName(co: *const CodeObject, namei: u8) []u8 {
const names_tuple = co.names.get(.tuple);
return names_tuple[namei].get(.string);
}

pub fn getConst(co: *const CodeObject, namei: u8) Object {
const consts_tuple = co.consts.get(.tuple);
return consts_tuple[namei];
}

/// Converts an index into this CodeObject's instructions
/// into a line number in the file_name of the CodeObject.
///
Expand Down
36 changes: 18 additions & 18 deletions src/compiler/Instruction.zig
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn format2(
std.debug.assert(unused_fmt_bytes.len == 0);

const inst = ctx.inst;
const co = ctx.co;
// const co = ctx.co;

const extra = inst.extra;

Expand All @@ -56,23 +56,23 @@ fn format2(
if (@intFromEnum(inst.op) < 90) return;

switch (inst.op) {
.LOAD_CONST,
=> try writer.print("{d} ({})", .{ extra, co.getConst(extra) }),
.LOAD_NAME,
.STORE_NAME,
.IMPORT_NAME,
.LOAD_METHOD,
=> try writer.print("{d} ({s})", .{ extra, co.getName(extra) }),
.CALL_FUNCTION,
.CALL_METHOD,
=> try writer.print("{d}", .{extra}),
.MAKE_FUNCTION,
=> {
const ty: Object.Payload.PythonFunction.ArgType = @enumFromInt(extra);
try writer.print("{s}", .{@tagName(ty)});
},
.BUILD_TUPLE,
=> try writer.print("({d})", .{extra}),
// .LOAD_CONST,
// => try writer.print("{d} ({})", .{ extra, co.getConst(extra) }),
// .LOAD_NAME,
// .STORE_NAME,
// .IMPORT_NAME,
// .LOAD_METHOD,
// => try writer.print("{d} ({s})", .{ extra, co.getName(extra) }),
// .CALL_FUNCTION,
// .CALL_METHOD,
// => try writer.print("{d}", .{extra}),
// // .MAKE_FUNCTION,
// // => {
// // const ty: Object.Payload.PythonFunction.ArgType = @enumFromInt(extra);
// // try writer.print("{s}", .{@tagName(ty)});
// // },
// .BUILD_TUPLE,
// => try writer.print("({d})", .{extra}),
else => try writer.print("TODO payload {d}", .{extra}),
}
}
Expand Down
Loading

0 comments on commit 8275816

Please sign in to comment.