-
-
Notifications
You must be signed in to change notification settings - Fork 17
Resolve core attribute arguments, runtime setters, safely #291
Description
Some builtin attributes will need to resolve symbolnames :native($libname)
at run-time, not only constants at parse-time. Users might want the same, as for users the import call gets the string also verbatim, which has to call eval on it.
This was why Attribute::Handlers was added, but this is bad practice, unsafe and should not be used. Esp. not for core builtins, and there's still no way set CV properties at run-time, such as native <=> dl_load_file(CvFFILIB(cv))
or CvXSUB = dl_find_symbol(:symbol($name))
.
So we need a way to set those CV properties.
For strings maybe the UTF8 status or FLAGS. Or ENCODING, if we add that.
Originally perl added an op, such as prototype(cvref|name)
. This does not scale for more properties. It would need new keywords native
and symbol
for the ffi. No.
apply_attrs() creates the following: attributes->import(stash, sv, args)
, which we should use
to do attributes->import(__PACKAGE__, \&cv, "native", $libname);
attributes.pm/xsutils would then be extended to understand it. We only need to defer the load_module call to run-time.
We could also add a MODIFY_CODE_ATTRIBUTES handler to core to catch these new attributes.
But these work only on package names, not types, and we would only add it for main::
. Which would make it hard for other packages. So it's a very bad idea.
Better would be generic introspection, as in a proper language or perl6. i.e. treat a CVREF as object with access to all fields. autobox alike.
The setter would be a lvalue method then: \&mysql_ffi_fetch->NATIVE = "mysqlclient.6.so";
Use with via the cvref or via the GV slot:
*mysql_ffi_fetch{CODE}->NATIVE = "mysqlclient.6.so";
*mysql_ffi_fetch{CODE}->SYMBOL = "mysql_fetch";
The 1st cvref method syntax-errors with Can't modify reference to subroutine entry in list assignment
, the 2nd GV method errors with Can't call method "NATIVE" on unblessed reference
at run-time.
We need it only for the internal setter at run-time, it doesn't even need to be parsed. Though it would be beneficial to do so, if not as keyword/op.
This will be fixed with the ffi merge.