-
Notifications
You must be signed in to change notification settings - Fork 194
Add no_std support #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add no_std support #103
Conversation
I got Rhai working on an stm32f103 with 64KB of FLASH. With this change the library was barely too big (77KB), however after temporarily removing some language features (who needs functions, variables and if-statements?) I managed to get Rhai down to 37KB. https://twitter.com/victorkoenders/status/1235247234356310016 |
@VictorKoenders I have been thinking. Why does cutting off functions, variables and if-statements cut down on code size? AFAIK those features are quite simple to implement, and adds little code to the code base. The significant elephant features are arrays, resolving array indexing, and custom types (with dot getters/setters chain). I'd imagine that simply by cutting off custom types, you'd probably cut down 1/4 of the code size. Another probably 1/4 if you cut arrays. However, maybe you need custom types to expose features in your embedded system... but those can easily be flattened into a bunch of function-based API instead. So if it were for me, I'd be dropping custom types but keeping functions, because function definitions mostly use code that are common for evaluation function calls... |
Sorry my week's been busy. I'll finish the code before the end of the week.
The large space saver is that the code ignores more tokens and has less complexity. The embedded version simply panics if it encounters a token it does not recognize. Because in my case all I had was a From what I can tell, a large part of the rhai binary rhai is because of text-to-AST parsing. If that could be offloaded somewhere else, and have the AST send over and executed on the microcontroller, rhai would easily fit on a 64KB chip. In the future I can look into exporting and importing AST so this could be possible.
This is probably true. Disabling builtins already saved almost 50%. I think in my experiment I removed all variable assignment so rustc was probably able to optimize away most variables and types. |
OK, I did some experiments with the examples. These program sizes are for standard release builds for x64 with standard library:
The same minimal build for Therefore:
Your code size might be different for an ARM CPU, and for a Notice that, as predicted, turning off functions does not yield any size savings simply because most of the function-call mechanisms remain in-place. |
So the major reduction ones are: arrays/indexing (as predicted), and floating-point support. Your milage may vary because |
As expected, removing functions does not make the code size any smaller. |
I realize that by doing Rebuilding for size in 32-bits on a Windows system:
So, as you can see, the main space savers are:
So, the conclusion is: I'd suggest you simply disable arrays, standard library, other integer types and math checking. Just by disabling arrays, you'll probably save enough for you to put back the while/if/let statements etc. If you don't need floating-point, disable that also, but as long as you disable the standard library, it probably doesn't add much. |
@schungx I've re-applied all the changes. I also moved all the imports to With all the stuff going on in the world I'm not able to test this on a microcontroller any time soon. However seeing as this compiles and with the size optimalizations you've done, I'm certain it works fine. The codebase itself already worked and if people want to reduce the file size they can work it out. |
This adds no_std support to Rhai. The dependant crates are responsible for making sure the
alloc
crate is enabled. I've used https://github.com/rust-embedded/alloc-cortex-m for this.The reason I chose for a feature called
no_std
, instead of adding a default featurestd
, is because we need to import several crates when we're not compiling from std. In most cases we have less dependencies.std::error::Error
, which is locked to std because of methods that are now deprecated. Core-error aims to be a replacement crate.core
does not have support for floating point mathematics by default, and there are 2 places wheref64::pow
andf64::powi
are called. Libm provides those functions on different platforms.Two new features are added in this PR:
no_std
: this enables#![no_std]
and switches all imports to usecore
andalloc
.default_buildins
: This enables all the methods insrc/builtin.rs
. This feature is enabled by default. If users of this crate (including myself) are limited for space on their target platform, disabling this feature saves a nice 80KB (out of 155KB).Closes #19