summaryrefslogtreecommitdiff
path: root/src/conversion.rs
AgeCommit message (Collapse)Author
2018-09-26Improve the situation with numerical conversionkyren
This is a somewhat involved change with two breaking API changes: 1) Lua::coerce_xxx methods now return Option (this is easier and faster than dealing with Result) 2) rlua numeric conversions now allow more loss of precision conversions (e.g. 1.5f32 to 1i32) The logic for the first breaking change is that mostly the coerce methods are probably used internally, and they make sense as low-level fallible casts and are now used as such, and there's no reason to confuse things with a Result with a large error type and force the user to match on the error which will hopefully only be FromLuaConversionError anyway. The logic for the second change is that it matches the behavior of num_traits::cast, and is more consistent in that *some* loss of precision conversions were previously allowed (e.g. f64 to f32). The problem is that now, Lua::coerce_integer and Lua::unpack::<i64> have different behavior when given, for example, the number 1.5. I still think this is the best option, though, because the Lua::coerce_xxx methods represent how Lua works internally and the standard C API cast functions that Lua provides, and the ToLua / FromLua code represents the most common form of fallible Rust numeric conversion. I could revert this change and turn `Lua::eval::<i64>("1.5", None)` back into an error, but it seems inconsistent to allow f64 -> f32 loss of precision but not f64 -> i64 loss of precision.
2018-09-24Return rlua::Error on out of range numeric conversions using num_traits::castkyren
2018-09-04Initial design for non-'static scoped userdatakyren
Uses the same UserData trait, and should at least in theory support everything that 'static UserData does, except that any functions added that rely on AnyUserData are pretty much useless. Probably pretty slow and I'm not sure how to make it dramatically faster, which is a shame because generally when you need non'-static userdata you might be creating it kind of a lot (if it was long-lived, it would probably be 'static). Haven't added tests yet, will do that next.
2018-08-05format with up-to-date rustfmtkyren
2018-03-19Clean up some lifetime specificationkyren
2018-03-11A lot of performance changes.kyren
Okay, so this is kind of a mega-commit of a lot of performance related changes to rlua, some of which are pretty complicated. There are some small improvements here and there, but most of the benefits of this change are from a few big changes. The simplest big change is that there is now `protect_lua` as well as `protect_lua_call`, which allows skipping a lightuserdata parameter and some stack manipulation in some cases. Second simplest is the change to use Vec instead of VecDeque for MultiValue, and to have MultiValue be used as a sort of "backwards-only" Vec so that ToLuaMulti / FromLuaMulti still work correctly. The most complex change, though, is a change to the way LuaRef works, so that LuaRef can optionally point into the Lua stack instead of only registry values. At state creation a set number of stack slots is reserved for the first N LuaRef types (currently 16), and space for these are also allocated separately allocated at callback time. There is a huge breaking change here, which is that now any LuaRef types MUST only be used with the Lua on which they were created, and CANNOT be used with any other Lua callback instance. This mostly will affect people using LuaRef types from inside a scope callback, but hopefully in those cases `Function::bind` will be a suitable replacement. On the plus side, the rules for LuaRef types are easier to state now. There is probably more easy-ish perf on the table here, but here's the preliminary results, based on my very limited benchmarks: create table time: [314.13 ns 315.71 ns 317.44 ns] change: [-36.154% -35.670% -35.205%] (p = 0.00 < 0.05) create array 10 time: [2.9731 us 2.9816 us 2.9901 us] change: [-16.996% -16.600% -16.196%] (p = 0.00 < 0.05) Performance has improved. create string table 10 time: [5.6904 us 5.7164 us 5.7411 us] change: [-53.536% -53.309% -53.079%] (p = 0.00 < 0.05) Performance has improved. call add function 3 10 time: [5.1134 us 5.1222 us 5.1320 us] change: [-4.1095% -3.6910% -3.1781%] (p = 0.00 < 0.05) Performance has improved. call callback add 2 10 time: [5.4408 us 5.4480 us 5.4560 us] change: [-6.4203% -5.7780% -5.0013%] (p = 0.00 < 0.05) Performance has improved. call callback append 10 time: [9.8243 us 9.8410 us 9.8586 us] change: [-26.937% -26.702% -26.469%] (p = 0.00 < 0.05) Performance has improved. create registry 10 time: [3.7005 us 3.7089 us 3.7174 us] change: [-8.4965% -8.1042% -7.6926%] (p = 0.00 < 0.05) Performance has improved. I think that a lot of these benchmarks are too "easy", and most API usage is going to be more like the 'create string table 10' benchmark, where there are a lot of handles and tables and strings, so I think that 25%-50% improvement is a good guess for most use cases.
2018-03-08Simplify stack_guard / stack_err_guardkyren
The expected change is always zero, because stack_guard / stack_err_guard are always used at `rlua` entry / exit points.
2018-02-06Lots of changes, not sure if actually safe yet.kyren
* Make Lua Send * Add Send bounds to (nearly) all instances where userdata and functions are passed to Lua * Add a "scope" method which takes a callback that accepts a `Scope`, and give `Scope` the ability to create functions and userdata that are !Send, *and also functions that are not even 'static!*.
2018-01-26ACTUALLY expose `RegistryKey` APIkyren
Also fixes a safety issue with RegistryKey, where you could use RegistryKeys with mismatching Lua instances.
2017-12-04more reorganization in an attempt to shrink the size of lua.rskyren
2017-12-04Move function and thread into their own modules, auto-formattingkyren
2017-12-03I believe this is all the external API changes necessary for 'm' safetykyren
2017-10-24Fix some clippy lints, possible edge case API incompatibility around HashMapkyren
2017-10-23auto-formattingkyren
2017-09-30more reorganization, move simple type defines to types.rs modulekyren
2017-09-30crudely move LightUserData/UserData/AnyUserData to their own modulekyren
2017-09-15Move string and table wrappers into own filesJonas Schievink
2017-08-02Remove expected field from FromLuaConversionErrorJonas Schievink
2017-08-01Enhance error messagesJonas Schievink
2017-07-29Relax requirements for UserData to impl FromLuaJonas Schievink
This was only allowed for `UserData` implementors that are also `Copy`. This relaxes the requirement to be `Clone` instead. While `Copy` makes sense to prevent allocations and other potentially costly operations, other `FromLua` impls already do pretty expensive stuff, so this seems worth it.
2017-07-24Do several more Lua prefix renames, add prelude modulekyren
Rename the following: LuaNil => Nil LuaExternalError => ExternalError LuaExternalResult => ExternalResult LuaCallback => Callback (internal only) Use qualified re-exports at the top of the module. Add a new public 'prelude' module which re-exports everything with a non-conflicting name (Adds back the Lua prefix), and is meant to be imported unqualified.
2017-07-23Rename `LuaString` to `String`Jonas Schievink
This required a lot of little adjustments where we used std's `String` before. In downstream code, this shouldn't be necessary, as you can just do `use rlua::String as LuaString` to disambiguate.
2017-07-23Remove the `Lua*` prefix from most typesJonas Schievink
cc #15 Doesn't touch `LuaString` mainly because that's a *lot* of renaming work and the code looks weird. Also I want feedback before I proceed.
2017-07-19Rename LightUserData to LuaLightUserData for consistencykyren
I know, this is the opposite of PR #17 wishes to do, please don't take this as an indication that I would wish to do the opposite. I actually want to discuss PR #17 with you, but I'm not sure about it yet, and my pedantry will not allow me to let this remain inconsistent in the meantime. This way, either way it's consistent haha.
2017-06-25Another major API change, out of stack space is not an Errkyren
It, ahem "should not" be possible to exhaust lua stack space in normal usage, and causing stack errors to be Err is slightly obnoxious. I have been wanting to make this change for a while, and removing the callback API from tables makes this sensible *I think*. I can think of a couple of ways that this is not technically true, but I think that they are acceptable, or should be handled differently. One, you can make arbitrarily sized LuaVariadic values. I think this is maybe a bug already, because there is an argument limit in Lua which is lower than the stack limit. I'm not sure what happens there, but if it is a stack based panic, (or any panic?) it is a bug. Two, I believe that if you recurse over and over between lua -> rust -> lua -> rust etc, and call rlua API functions, you might get a stack panic. I think for trusted lua code, this is morally equivalent to a regular stack overflow in plain rust, which is already.. well it's not a panic but it's some kind of safe crash I'm not sure, so I think this is acceptable. For *untrusted* lua code, this could theoretically be a problem if the API provided a callback that would call back into lua, then some lua script could force a stack based panic. There are so many concerns with untrusted lua code, and this library is NOT safe enough yet for untrusted code (it doesn't even provide an option to limit lua to the safe API subset yet!), so this is not currently an issue. When the library provides support for "safe lua", it should come with big warnings anyway, and being able to force a stack panic is pretty minor in comparison. I think if there are other ways to cause unbounded stack usage, that it is a bug, or there can be an error just for that situation, like argument count limits. This commit also fixes several stupid bugs with tests, stack checking, and panics.
2017-06-25Simplification of error typeskyren
The multi-level error types were a mistake. Probably should have waited on the cargo version bump, oh well.
2017-06-25This is a SLIGHTLY better implementation I think.kyren
2017-06-25Not sure I like everything about this approach yetkyren
2017-06-24Lots of LuaError changeskyren
It is possible that I have gone too far here into error discrimination and should scale it back, not sure yet.
2017-06-24Big API incompatible error change, remove dependency on error_chainkyren
The current situation with error_chain is less than ideal, and there are lots of conflicting interests that are impossible to meet at once. Here is an unorganized brain dump of the current situation, stay awhile and listen! This change was triggered ultimately by the desire to make LuaError implement Clone, and this is currently impossible with error_chain. LuaError must implement Clone to be a proper lua citizen that can live as userdata within a lua runtime, because there is no way to limit what the lua runtime can do with a received error. Currently, this is solved by there being a rule that the error will "expire" if the error is passed back into rust, and this is very sub-optimal. In fact, one could easily imagine a scenario where lua is for example memoizing some function, and if the function has ever errored in the past the function should continue returning the same error, and this situation immediately fails with this restriciton in place. Additionally, there are other more minor problems with error_chain which make the API less good than it could be, or limit how we can use error_chain. This change has already solved a small bug in a Chucklefish project, where the conversion from an external error type (Borrow[Mut]Error) was allowed but not intended for user code, and was accidentally used. Additionally, pattern matching on error_chain errors, which should be common when dealing with Lua, is less convenient than a hand rolled error type. So, if we decide not to use error_chain, we now have a new set of problems if we decide interoperability with error_chain is important. The first problem we run into is that there are two natural bounds for wrapped errors that we would pick, (Error + Send + Sync), or just Error, and neither of them will interoperate well with error_chain. (Error + Send + Sync) means we can't wrap error chain errors into LuaError::ExternalError (they're missing the Sync bound), and having the bounds be just Error means the opposite, that we can't hold a LuaError inside an error_chain error. We could just decide that interoperability with error_chain is the most important qualification, and pick (Error + Send), but this causes a DIFFERENT set of problems. The rust ecosystem has the two primary error bounds as Error or (Error + Send + Sync), and there are Into impls from &str / String to Box<Error + Send + Sync> for example, but NOT (Error + Send). This means that we are forced to manually recreate the conversions from &str / String to LuaError rather than relying on a single Into<Box<Error + Send + Sync>> bound, but this means that string conversions have a different set of methods than other error types for external error conversion. I have not been able to figure out an API that I am happy with that uses the (Error + Send) bound. Box<Error> is obnoxious because not having errors implement Send causes needless problems in a multithreaded context, so that leaves (Error + Send + Sync). This is actually a completely reasonable bound for external errors, and has the nice String Into impls that we would want, the ONLY problem is that it is a pain to interoperate with the current version of error_chain. It would be nice to be able to specify the traits that an error generated by the error_chain macro would implement, and this is apparently in progress in the error_chain library. This would solve both the problem with not being able to implement Clone and the problems with (Error + Send) bounds. I am not convinced that this library should go back to using error_chain when that functionality is in stable error_chain though, because of the other minor usability problems with using error_chain. In that theoretical situation, the downside of NOT using error_chain is simply that there would not be automatic stacktraces of LuaError. This is not a huge problem, because stack traces of lua errors are not extremely useful, and for external errors it is not too hard to create a different version of the LuaExternalResult / LuaExternalError traits and do conversion from an error_chain type into a type that will print the stacktrace on display, or use downcasting in the error causes. So in summary, this library is no longer using error_chain, and probably will not use it again in the future. Currently this means that to interoperate with error_chain, you should use error_chain 0.8.1, which derives Sync on errors, or wait for a version that supports user defined trait derives. In the future when error_chain supports user defined trait derives, users may have to take an extra step to make wrapped external errors print the stacktrace that they capture. This change works, but is not entirely complete. There is no error documentation yet, and the change brought to a head an ugly module organization problem. There will be more commits for documentation and reorganization, then a new stable version of rlua.
2017-06-23Change LuaError ToLua approachkyren
Lua should be consistent independent of the way they are produced. pcall in lua should produce the same sort of error that would be returned by a LuaError conversion. The situation is not currently great, because LuaError is not Clone, so passing a LuaError back into rust will result in the error being "consumed".
2017-06-23Add ToString metamethod, make LuaError implement LuaUserDatakyren
LuaError implementing LuaUserData makes it easy to return LuaResult from a callback to implement callback functions that can error.
2017-06-20Method renames, remove ToLua / FromLua impls for Setskyren
There is no single obvious form for a set in lua, and it is not very difficult to accept a table and convert the sequence values into a set. Also rename some methods as per discussion.
2017-06-19Big API change for tableskyren
Removes the callback versions of loops over LuaTable, instead now there are 'pairs' and 'ipairs' iterators over them.
2017-06-18Rename `LuaString::get` to `to_str`Jonas Schievink
This is what similar types in libstd do (`CStr::to_str`, `OsStr::to_str`, `Path::to_str`).
2017-05-25Correct checking of LuaRef origin, support lightuserdatakyren
All lua types should now be at least somewhat usable from rust, if incompletely so. Any lua value should be readable in Rust as a LuaValue, pop_value should never panic except in internal logic errors.
2017-05-24Basic coroutine support, currently very slightly brokenkyren
There is no longer any protection in passing LuaValue between independent states, it is being re-added
2017-05-21Initial importkyren