Previously pragma save_local_names was only used to store information of
variables of coroutines to be inspected by Python code. Extend this to
all local variables.
Standard struct definition where not usable in dynamic settings
(e.g. to_type()), as the definition was not registered to the corresponding
struct name and type.
Python can register global struct definitions via ldmud.register_struct().
Also added corresponding namespace ldmud.registered_structs that contains
all registered struct types.
Prototype-only functions are detected by looking at the first opcode of the
function. If the prototype has optional arguments, then the first bytes is
a jump table for argument initialization. The detection needs to look beyond
that.
For every prototype-only function the compiler creates a stub at the end that
throws the undefined function error. However this stub was missing the jump
table for optional arguments, writing the error opcode in its place instead.
This resulted in an invalid table and missing opcode after the table.
Both could result in a crash, depending on whether the function is called
with or without the optional argument.
The pattern leaked (Thanks, Daniel Nilsson for the fix).
An explicitly passed preposition array would leak.
Arguments were treated as unprotected lvalues, even though they are protected.
The cleanup routine was not called, thus leaking data in global variables.
When pragma save_local_names was in effect, a former local variable could
lead to the compile error "Missing variable information" as the compiler
was trying to save that name as well.
When a variable, function or struct given via a lookup mapping or
closure to compile_string() was used in different closures
(e.g., used directly and used in an inline closure), the necessary
values were only added to one of the generated lambda closures,
resulting in a crash when executing the other.
Several functions use apply_return_value to store the result of a callback
call. transfer_svalue() should override any previous value in it, but if
it contains an lvalue, the new value will be assigned to the lvalue instead.
Use pop_apply_value() instead, it makes sure, this doesn't happen.
When use_object_variables is true and the object has virtual as well as
non-virtual variables, the access to the non-virtual variables by
compile_string() was off by the number of virtual variables.
Added build option --enable-anl to enable asynchronous lookup for
net_connect() and logged on players. For the later replacing the ERQ
calls, thereby entirely removing the necessity of ERQ for the driver.
(At least) on Intel processors modulo division is done together with normal
division resulting in an exception when the division results exceeds the
value range. Therefore fix the special case of __INT_MIN__ % -1, where
division would not be allowed, but modulo is well defined.
Efuns like call_out, add_action, map or filter will throw immediately when
they're given an uncallable closure for callback. Also improved structure
of call_lambda() and fixed giving an error message without a control stack
entry. (Fixes#908)
ldmud.registered_efuns contains all registered Python efuns and
ldmud.registered_types provides all registered Python types.
Those are read-only, for manipulation there is (un)register_efun/type().
As LDMud doesn't support NaN and +/-Inf anyways, supporting negative zeros
is only confusing. So collapse them into normal zeroes. (This was the
case before LDMud 3.5.0 with the old float format anyways.)
get_type_info(cl, 3) should return the program/inherit containing the
target function, but instead returned the object's main program.
Similarly closure_to_string() did not print the inherit name for
inherited functions.
variable_exists() could sometimes end up in an endless loop trying to
find the correct inherit entry due to a mixup of virtual and non-virtual
variable indices.
compile_string() with .detect_end != 0 stops compilation without an error
when the following token (character/word) cannot continue a parsed expression
or block.
Fully support the LPC type system in Python, providing representations
for basic types (int, float, string, bytes), named (lightweight) object
types, concrete struct types and union types.
The global interpreter lock is acquired during initialization and never
released. So if any Python modules start additional threads they can
hardly run, because the lock is held by the main thread mostly all of
the time.
Add a new type 'lpctype' to contain a type object, describing a compile-time
type, together with a decltype() operator and to_lpctype() and check_type()
efuns.