We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Options: https://github.com/zhaojh329/lua-ffi https://github.com/q66/cffi-lua
Or roll our own:
c11 = require("c11") lpegrex = require("lpegrex") node = c11([[ struct A { int a; short b; char c; void * d; char field_0x100; char e[100]; char * f; }; ]], "struct_test") type_size_lookup = { ["char"] = 1, ["byte"] = 1, ["short"] = 2, ["int"] = 4, ["void *"] = 4, ["char *"] = 4, } type_getter_lookup = { ["char"] = "readByte", ["byte"] = "readByte", ["short"] = "readSmallInteger", ["int"] = "readInteger", ["void *"] = "readInteger", ["char *"] = "readInteger", ["char[*]"] = "readString", } type_setter_lookup = { ["char"] = "writeByte", ["byte"] = "writeByte", ["short"] = "writeSmallInteger", ["int"] = "writeInteger", ["void *"] = "writeInteger", ["char *"] = "writeInteger", ["char[*]"] = "writeString", } -- todo implement this before c11 parsing type_preprocessor = { ["undefined"] = "char", ["byte"] = "char", ["undefined2"] = "short", ["undefined4"] = "int", } function generate_struct(node, ignore_prefix) local ignoring = false if ignore_prefix ~= nil then ignoring = true end if node.tag ~= "struct-or-union-specifier" then error() end if node[1] ~= "struct" then error() end name = node[3] print(string.format("generate_struct: struct name: %s", name)) sdl = node[4] offset = 0 getters = {} setters = {} for k, sd in ipairs(sdl) do type_size = nil sql = sd[1] tp = sql[1] type_string = tp[1] dl = sd[2] sdr = dl[1] d = sdr[1] pointer_string = nil if d[1].tag == "identifier" then id = d[1] identifier_string = id[1] full_type_string = type_string elseif d[1].tag == "pointer" then p = d[1] id = p[3] identifier_string = id[1] pointer_string = (pointer_string or "") .. "*" full_type_string = type_string .. " " .. pointer_string elseif d[1].tag == "declarator-subscript" then node_to_solve = d[1] subscript = d[1] id = subscript[1] identifier_string = id[1] integer_constant = subscript[3] type_size = integer_constant[1] * type_size_lookup[type_string] -- error("node_to_solve") full_type_string = type_string .. "[*]" else error(d[1].tag) end if ignoring and identifier_string:sub(1, ignore_prefix:len()) == ignore_prefix then -- continue else -- if identifier_string == "new" or identifier_string == "at" then -- error(string.format("reserved name: %s", identifier_string)) -- end if type_size == nil then type_size = type_size_lookup[full_type_string] end if type_size == nil then error(full_type_string) end print(string.format("name: %s, type: %s, size: %s, offset: %s", identifier_string, full_type_string, type_size, offset)) g = type_getter_lookup[full_type_string] if g == nil then error(full_type_string) end if full_type_string == "char[*]" then getter = string.format([[ if k == "%s" then return %s(address + %s, %s) end ]], identifier_string, g, offset, type_size) s = type_setter_lookup[full_type_string] if s == nil then error(full_type_string) end setter = string.format([[ if k == "%s" then if v:len() >= %s then error("string too large") end return %s(address + %s, v) end ]], identifier_string, type_size, s, offset) else getter = string.format([[ if k == "%s" then return %s(address + %s) end ]], identifier_string, g, offset) s = type_setter_lookup[full_type_string] if s == nil then error(full_type_string) end setter = string.format([[ if k == "%s" then return %s(address + %s, v) end ]], identifier_string, s, offset) end table.insert(getters, getter) table.insert(setters, setter) end offset = offset + type_size end size = offset return string.format([[ return function(address) local allocated = false local deallocated = nil local size = %s if address == nil then print("allocating") allocated = true deallocated = false address = allocate(size) end if type(address) ~= "number" then error("not a valid address:" .. tostring(address)) end local mt = { __index = function(t, k) %s end, __newindex = function(t, k, v) %s end, __gc = function(t) if allocated and deallocated == false then deallocate(address) deallocated = true end end, __len = function(t) return size end, } return setmetatable({}, mt) end ]], size, table.concat(getters, "\n\n"), table.concat(setters, "\n\n")) end function translation_unit_to_struct_specifier(node) return node[1][1][1][1][1] -- todo: ignores possibility of multiple struct definitions end lua = generate_struct(translation_unit_to_struct_specifier(node)) compile = load(lua, "generator", 't', { error = error, tostring = tostring, print = print, type = type, table = table, string = string, setmetatable = setmetatable, allocate = function(size) fakeResult = 0x400000 + size; print(string.format("allocate %s => %X", size, fakeResult)); return fakeResult end, deallocate = function(address) print(string.format("deallocate %X", address)) end, readByte = function(address) print(string.format("readByte %X", address)) end, readSmallInteger = function(address) print(string.format("readSmallInteger %X", address)) end, readInteger = function(address) print(string.format("readInteger %X", address)) end, readString = function(address, size) print(string.format("readString %X %s", address, size)) end, writeByte = function(address) print(string.format("writeByte %X", address)) end, writeSmallInteger = function(address) print(string.format("writeSmallInteger %X", address)) end, writeInteger = function(address) print(string.format("writeInteger %X", address)) end, writeString = function(address, data) print(string.format("writeString %X %s", address, data)) end, }) A = compile() a = A(0x400000) b = A() -- allocated print(#b) b = nil collectgarbage()
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Options:
https://github.com/zhaojh329/lua-ffi
https://github.com/q66/cffi-lua
Or roll our own:
The text was updated successfully, but these errors were encountered: