Daniel Colascione schrieb am So., 4. Okt. 2015 um 21:34 Uhr: > On 10/04/2015 02:41 AM, Philipp Stephani wrote: > > > > > > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > > > > I think it's important that this is a pointer to a struct (for type > > > safety and size correctness) rather than just an arbitrary type. > > > > A typedef is exactly as typesafe. The question of whether to use a > > struct or a typedef is aesthetic. I strongly prefer a typedef, just > like > > pthreads, and I believe that the people who advocate using structs > > directly are simply wrong. > > > > > > Ah, I'm not against the typedef, I'm just asking whether you would make > > it part of the API contract that it's a typedef of a struct pointer, or > > whether it can be any type. > > The problem with defining it as a pointer type is that NULL is now the > invalid sentinel value, which seems incompatible with both making this > thing literally a Lisp_Object and Qnil having all zero bits. > > That's why I strongly prefer making emacs_value a _pointer_ to a > Lisp_Object, where we store the Lisp_Object in an array owned by the > emacs_env. This way, allocating local values is very cheap. > Aurélien, is that something you agree with and could implement? > > > > Modules can use make_global_reference to allocate a global > > reference > > > (i.e., a GC root) for any emacs_value; modules must then free > > these > > > references explicitly. > > > > > > All routines (except make_global_reference) that return > > emacs_value > > > values return local references. It's up to modules to register > > > long-lived references explicitly. > > > > > > > > > In which cases would global references be necessary? > > > > Any time you want to hold onto a lisp value outside the dynamic > extent > > of your emacs_env. > > > > > > Isn't the dynamic extent of the emacs_env the whole program, starting > > from the module initializer? > > Not necessarily. An emacs_env is valid only for the current call into > module code on the current thread. So if we call module-function-1, wait > for it to return, then call module-function-2, the two calls can have > different environments, and using local references from one might not be > valid on the other. (This approach opens up very important optimizations > in JNI, and it'd be good for us to use the same approach.) A global > reference is just an emacs_env in a heap-allocated object we register as > a GC root. > > (To answer the question another way: global references are GC roots.) > > OK, IIUC the examples in Aurélien's branch are then invalid because they store the result of intern("nil") in a static variable, right? One more thing: is equality of two emacs_value objects defined? Right now it's `eq', but that's probably also an implementation detail. If equality is not defined as `eq', we also need a "null" function in the environment that returns bool, otherwise there would be no way to implement conditions.