LuaJIT knows the C types it defines, and the lengths of the arrays, but it doesn't check the bounds:
ffi = require("ffi")
ten_ints = ffi.typeof("int [10]")
p1 = ten_ints()
print(ffi.sizeof(p1)) -- 40
var_ints = ffi.typeof("int [?]")
p2 = ffi.new(var_ints, 10)
print(ffi.sizeof(p2)) -- 40
p1[1000000] = 1 -- segfault
p2[1000000] = 1 -- segfault
Is there a way to make it do that, or is my only choice to write wrappers?
Short answer: There is no way, you'll have to write/find your own wrapper.
Here is the explanation from luajit.org
No Hand-holding!
[...] The FFI library provides no memory safety, unlike regular
Lua code. It will happily allow you to dereference a NULL pointer, to
access arrays out of bounds or to misdeclare C functions. If you make
a mistake, your application might crash, just like equivalent C code
would. This behavior is inevitable, since the goal is to provide full
interoperability with C code. Adding extra safety measures, like
bounds checks, would be futile. [...] Likewise there's no way to
infer the valid range of indexes for a returned pointer. Again: the
FFI library is a low-level library.
Related
I was trying to implement vector algebra with generic algorithms and ended up playing with iterators. I have found two examples of not obvious and unexpected behaviour:
if I have pointer p to a struct (instance) with field fi, I can access the field as simply as p.fi (rather than p.*.fi)
if I have a "member" function fun(this: *Self) (where Self = #This()) and an instance s of the struct, I can call the function as simply as s.fun() (rather than (&s).fun())
My questions are:
is it documented (or in any way mentioned) somewhere? I've looked through both language reference and guide from ziglearn.org and didn't find anything
what is it that we observe in these examples? syntactic sugar for two particular cases or are there more general rules from which such behavior can be deduced?
are there more examples of weird pointers' behaviour?
For 1 and 2, you are correct. In Zig the dot works for both struct values and struct pointers transparently. Similarly, namespaced functions also do the right thing when invoked.
The only other similar behavior that I can think of is [] syntax used on arrays. You can use both directly on an array value and an array pointer interchangeably. This is somewhat equivalent to how the dot operates on structs.
const std = #import("std");
pub fn main() !void {
const arr = [_]u8{1,2,3};
const foo = &arr;
std.debug.print("{}", .{arr[2]});
std.debug.print("{}", .{foo[2]});
}
AFAIK these are the only three instances of this behavior. In all other cases if something asks for a pointer you have to explicitly provide it. Even when you pass an array to a function that accepts a slice, you will have to take the array's pointer explicitly.
The authoritative source of information is the language reference but checking it quickly, it doesn't seem to have a dedicated paragraph. Maybe there's some example that I missed though.
https://ziglang.org/documentation/0.8.0/
I first learned this syntax by going through the ziglings course, which is linked to on ziglang.org.
in exercise 43 (https://github.com/ratfactor/ziglings/blob/main/exercises/043_pointers5.zig)
// Note that you don't need to dereference the "pv" pointer to access
// the struct's fields:
//
// YES: pv.x
// NO: pv.*.x
//
// We can write functions that take pointer arguments:
//
// fn foo(v: *Vertex) void {
// v.x += 2;
// v.y += 3;
// v.z += 7;
// }
//
// And pass references to them:
//
// foo(&v1);
The ziglings course goes quite in-depth on a few language topics, so it's definitely work checking out if you're interested.
With regards to other syntax: as the previous answer mentioned, you don't need to dereference array pointers. I'm not sure about anything else (I thought function pointers worked the same, but I just ran some tests and they do not.)
Lightuserdata is different from userdata so what can I do with it? I mean the operations of lightuserdata in lua. Looks like I cannot convert it to any other data type.
One of my case:
My C library returns a C pointer named 'c_pointer', AKA lightuserdata to Lua, and then I want:
my_pointer = c_pointer +4
and then pass 'my_pointer' back to C library. Since I cannot do anything with 'c_pointer', so the expression 'c_pointer + 4' is invalid.
I am wondering are there some practical solutions to this?
Lightuserdata are created by C libraries. They are simply C pointers.
For example, you can use them to refer to data you allocate with malloc, or statically allocate in your module. Your C library can transfer these pointers to the Lua side as a lightuserdata using lua_pushlightuserdata, and later Lua can give it back to your library (or other C code) on the stack. Lua code can use the lightuserdata as any other value, storing it in a table, for example, even as a table key.
ADDENDUM
To answer your revised question, if you want to add an offset to the pointer, do it on the C side. Pass the lightuserdata and the integer offset to C, and let C do the offset using ptr[n]
void * ptr = lua_touserdata(L, idx1);
lua_Integer n = lua_tointeger(L. idx2);
// do something with
((char *)ptr)[n];
Plain Lua has no pointer arithmetic, so as Doug Currie stated you would need to do the pointer arithmetic on the C side.
LuaJIT on the other hand can do pointer arithmetic (via the FFI library), so consider using that instead.
I'm experimenting with enumeration sorts in Z3 as described in How to use enumerated constants after calling of some tactic in Z3? and I noticed that I might have some misunderstanding on how to use C and C++ api properly. Let's consider the following example.
context z3_cont;
Z3_symbol e_names[2 ];
Z3_func_decl e_consts[2];
Z3_func_decl e_testers[2];
e_names[0] = Z3_mk_string_symbol(z3_cont, "x1");
e_names[1] = Z3_mk_string_symbol(z3_cont, "x2");
Z3_symbol e_name = Z3_mk_string_symbol(z3_cont, "enum_type");
Z3_sort new_enum_sort = Z3_mk_enumeration_sort(z3_cont, e_name, 2, e_names, e_consts, e_testers);
sort enum_sort = to_sort(z3_cont, new_enum_sort);
expr e_const0(z3_cont), e_const1(z3_cont);
/* WORKS!
func_decl a_decl = to_func_decl(z3_cont, e_consts[0]);
func_decl b_decl = to_func_decl(z3_cont, e_consts[1]);
e_const0 = a_decl(0, 0);
e_const1 = b_decl(0, 0);
*/
// SEGFAULT when doing cout
e_const0 = to_func_decl(z3_cont, e_consts[0])(0, 0);
e_const1 = to_func_decl(z3_cont, e_consts[1])(0, 0);
cout << e_const0 << " " << e_const1 << endl;
I expected the two variants of code to nicely wrap the C entity Z3_func_decl with a smart pointer so I can use with C++ api, however only the first variant seems to be correct. So my questions are
Is this a correct behavior that the second way doesn't work? If so, how can I better understand the reasons of why it shouldn't?
What happens with unwrapped C entities, as for example Z3_symbol e_name - here I don't wrap it, I don't increment references. So will the memory be managed properly? Is it safe to use it? when the object will be destroyed?
A minor question: I didn't see the to_symbol() function in C++ api. Is it just unnecessary?
Thank you.
Whenever we create a new Z3 AST, Z3 may garbage collect an AST n if the reference counter of n is 0. In the piece of code that works, we wrap e_consts[0] and e_consts[1] before we create any new AST. When we wrap them, the smart pointer will bump their reference counter.
This is why it works. In the piece of code that crashes, we wrap e_consts[0], and then create e_const0 before we wrap e_consts[1]. Thus, the AST referenced by e_consts[1] is deleted before we have the chance to create e_const1.
BTW, in the next official release, we will have support for creating enumeration types in the C++ API: http://z3.codeplex.com/SourceControl/changeset/b2810592e6bb
This change is already available in the nightly builds.
Z3_symbol is not a reference counted object. They are persistent, Z3 maintains a global table of all symbols created. We should view symbols as unique strings.
Note that we can use the class symbol and the constructor symbol::symbol(context & c, Z3_symbol s). The functions to_* are used to wrap objects created using the C API with smart pointers. We usually have a function to_A, if there is a C API function that returns an A object, and there is not function/method equivalent in the C++.
I'm doing a program with FORTRAN that is a bit special. I can only use integer variables, and as you know with these you've got a memory overflow when you try to calculate a factorial superior to 12 or 13. So I made this program to avoid this problem:
http://lendricheolfiles.webs.com/codigo.txt
But something very strange is happening. The program calculates the factorial well 4 or 5 times and then gives a memory overflow message. I'm using Windows 8 and I fear it might be the cause of the failure, or if it's just that I've done something wrong.
Thanks.
Try compiling with run-time subscript checking. In Fortran segmentation faults are generally caused either by subscript errors or by mismatches between actual and dummy arguments (i.e., between arguments in the call to a procedure and the arguments as declared in the procedure). I'll make a wild guess from glancing at your code that you have have a subscript error -- let the compiler find it for you by turning on run-time subscript checking. Most Fortran compilers have this as an compilation option.
P.S. You can also do calculations like this by using already written packages, e.g., the arbitrary precision arithmetic software of David Bailey, et al., available in Fortran 90 at http://crd-legacy.lbl.gov/~dhbailey/mpdist/
M.S.B.'s answer has the gist of your problem: your array indices go out of bounds at a couple of places.
In three loops, cifra - 1 == 0 is out of bounds:
do cifra=ncifras,1,-1
factor(1,cifra-1) = factor(1,cifra)/10 ! factor is (1:2, 1:ncifras)
factor(1,cifra) = mod(factor(1,cifra),10)
enddo
! :
! Same here:
do cifra=ncifras,1,-1
factor(2,cifra-1) = factor(2,cifra)/10
factor(2,cifra) = mod(factor(2,cifra),10)
enddo
!:
do cifra=ncifras,1,-1
sumaprovisional(cifra-1) = sumaprovisional(cifra-1)+(sumaprovisional(cifra)/10)
sumaprovisional(cifra) = mod(sumaprovisional(cifra),10)
enddo
In the next case, the value of cifra - (fila - 1) goes out of bounds:
do fila=1,nfilas
do cifra=1,ncifras
! Out of bounds for all cifra < fila:
sumando(fila,cifra-(fila-1)) = factor(1,cifra)*factor(2,ncifras-(fila-1))
enddo
sumaprovisional = sumaprovisional+sumando(fila,:)
enddo
You should be fine if you rewrite the first three loops as do cifra = ncifras, 2, -1 and the inner loop of the other case as do cifra = fila, ncifras. Also, in the example program you posted, you first have to allocate resultado properly before passing it to the subroutine.
I have to communicate with a dll and it lua and this is the function I use to write strings by bytes:
writeString = function(pid, process, address, value)
local i = 1
while i <= String.Length(value) do
local byte = string.byte(value, i, i)
DLL.CallFunction("hook.dll", "writeMemByte", pid..','..process..','..address + (i-1)..','..byte, DLL_RETURN_TYPE_INTEGER, DLL_CALL_CDECL)
i = i + 1
end
DLL.CallFunction("hook.dll", "writeMemByte", pid..','..process..','..address + (i-1)..',0', DLL_RETURN_TYPE_INTEGER, DLL_CALL_CDECL)
end
I basically need to adapt this to write a double value byte by byte.
I just can't think how to make the memory.writeDouble function.
EDIT: this is my readString function:
readString = function(pid, process, address)
local i, str = 0, ""
repeat
local curByte = DLL.CallFunction("hook.dll", "readMemByte", pid..','..process..','..(address + i), DLL_RETURN_TYPE_INTEGER, DLL_CALL_CDECL)
if curByte == "" then curByte = 0 end
curByte = tonumber(curByte)
str = str .. string.char(curByte)
i = i + 1
until (curByte == 0)
return str
end,
My first recommendation would be: try to find a function that accepts strings representing doubles instead of doubles. Implementing the lua side of that would be incredibly easy, since you already have a writeString - it could be something very similar to this:
writeDouble = function(pid, process, address, value)
writeString(pid, process, address, tostring(value))
end
If you don't have that function, but you have access to the dll source, you can try to add that function yourself; it shouldn't be much more complicated than getting the string and then calling atof on it.
If you really can't modify the dll, then you need to figure out the exact double format that the lib is expecting - there are lots of factors that can change that format. The language and compiler used, the operative systems, and the compiler flags, to cite some.
If the dll uses a standard format, like IEE-754, the format will usually have well documented "translations" from/two bites. Otherwise, it's possible that you'll have to develop them yourself.
Regards and good luck!
There are many libraries available for Lua that do just this.
If you need the resulting byte array (string), string.pack should do it; you can find precompiled binaries for Windows included with Lua for Windows.
If you are more interested in using the double to interface with foreign code, I would recommend taking a different approach using alien, a Foreign Function Interface library that lets you directly call C functions.
If you able to, I even more highly recommend switching to LuaJIT, a Just-In-Time compiler for Lua that provides the power, speed and reach of C and assembly, but with the comfort an flexibility of Lua.
If none of these solutions are viable, I can supply some code to serialise doubles (not accessible at the moment).