Compute record layout
@@ -25,12 +25,15 @@ end
-- don't need to be passed to a following pass.
--
-- _cvar:
--- In Decl nodes.
+-- In Decl nodes. (see @decl)
--
-- _lua_entry_point
-- _titan_entry_point
-- In Toplevel.Func nodes.
-- Names of the C functions that we generate for each titan function
+--
+-- _layout:
+-- In Toplevel.Record nodes. (see @records)
local whole_file_template = [[
/* This file was generated by the Titan compiler. Do not edit by hand */
@@ -53,6 +56,8 @@ local whole_file_template = [[
#include "math.h"
+${STRUCTS}
+
${DEFINE_FUNCTIONS}
${LUAOPEN_FUNCTION}
@@ -129,7 +134,7 @@ local function ctype(typ)
end
--
---
+-- @decl
--
local function new_cvar(name, ctyp, comment)
@@ -465,6 +470,48 @@ local function gc_cond_gc(ctx)
})
end
+--
+-- @records
+--
+
+-- Compute the layout for the gc fields stored in the UValue array.
+-- We use a C struct to compute the layout of fields stored in mem part.
+local function rec_compute_layout(rec)
+ local index = 0
+ local pos = {}
+ for _, field in ipairs(rec.field_decls) do
+ local typ = rec._field_types[field.name]
+ if types.is_gc(typ) then
+ pos[field] = index
+ index = index + 1
+ end
+ end
+ return { pos = pos, size = index }
+end
+
+local function rec_struct_name(rec)
+ return string.format("struct record_%s", rec.name)
+end
+
+local function rec_declare_struct(rec)
+ local fields = {}
+ for _, field in ipairs(rec.field_decls) do
+ local typ = rec._field_types[field.name]
+ if not types.is_gc(typ) then
+ local decl = string.format("%s %s;", ctype(typ), field.name)
+ table.insert(fields, decl)
+ end
+ end
+ return util.render([[
+ $NAME {
+ $FIELDS
+ };
+ ]], {
+ NAME = rec_struct_name(rec),
+ FIELDS = table.concat(fields, "\n"),
+ })
+end
+
--
--
--
@@ -813,6 +860,15 @@ end
-- @return (string) C code for the whole module
generate_program = function(prog, modname)
+ -- Records
+ local structs = {}
+ for _, tl_node in ipairs(prog) do
+ if tl_node._tag == ast.Toplevel.Record then
+ tl_node._layout = rec_compute_layout(tl_node)
+ table.insert(structs, rec_declare_struct(tl_node))
+ end
+ end
+
-- Name all the function entry points
for _, tl_node in ipairs(prog) do
if tl_node._tag == ast.Toplevel.Func then
@@ -843,6 +899,7 @@ generate_program = function(prog, modname)
generate_luaopen(prog, modname)
local code = util.render(whole_file_template, {
+ STRUCTS = table.concat(structs, "\n\n"),
DEFINE_FUNCTIONS = define_functions,
LUAOPEN_FUNCTION = luaopen_function,
})
