Skip to content
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

Lua tidy-up to reduce delta against esp32 branch. #3468

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

jmattsson
Copy link
Member

  • This PR is for the dev branch rather than for the release branch.
  • This PR is compliant with the other contributing guidelines as well (if not, please describe why).
  • I have thoroughly tested my contribution.
  • [n/a] The code changes are reflected in the documentation at docs/*.

These should hopefully be completely uncontentious changes, as there
are no functional changes in this commit.

There is still a delta against the esp32 branch, but to harmonise that fully
requires a bit more work.

This commit includes:

  • Some LUA_USE_xxx #ifdef changes, since in many ways the ESP32 is
    closer to a host build than an ESP8266 build.

  • A bunch of compiler warnings tidy-ups.

  • A couple of readability/maintainability improvements (e.g. LROT_END
    definition using named member initialisation, prototype declarations
    moved to header file(s)).

  • Some 64bit correctness for 64bit host builds.

@jmattsson
Copy link
Member Author

MSVC strikes again. I'll push a fix when I have a some uninterrupted dev time.

These should hopefully be completely uncontentious changes.

There is still a delta against the esp32 branch, but to harmonise that
requires a bit more work.

This commit includes:

- Some LUA_USE_xxx #ifdef changes, since in many ways the ESP32 is
  closer to a host build than an ESP8266 build.

- A bunch of warnings tidy-ups.

- A couple of readability/maintainability improvements (e.g. LROT_END
  definition using named member initialisation, prototype declarations
  moved to header file(s)).
Copy link
Collaborator

@TerryE TerryE left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Johny, just a quit read through. I leave it to you to wildcard the use of the UNUSED() macro. I need to understand the extra meta fields on the ROTable declarations, or are this just a keyed recoding of the positional initialiser?

@@ -258,6 +258,7 @@ LROT_END(utf8, LROT_TABLEREF(utf8_meta), 0)


LUAMOD_API int luaopen_utf8 (lua_State *L) {
(void)L;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's actually an UNUSED(v) macro in llimits.h

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I hadn't noticed that. Happy to swap over to that both here and on the esp32 branch then. Stay tuned... :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I think that UNUSED(var) is more obvious to the reader.

@@ -465,6 +465,8 @@ struct lua_Debug {
struct CallInfo *i_ci; /* active function */
};

int lua_main(void);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hummed and harred about where to export lua_main(). This is roughly equivalent to main() in std lua.c. lua.h is the public interface to the Lua API, and this main entry is not part of the API and in general if and module writer were to attempt to call this, it would be a disaster. This is why I left the entry hidden , and declared is extern in the file that requires it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, on the other hand, letting others declare things extern elsewhere is a recipe for subtle breakage if the actual prototype does change (been there, done that 😞). Maybe it should simply be dumped into its own header file that gets included by lua.c to ensure the declaration and definition match?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In many ways I'd be more happy with that. Or at least a non-"Lua public API" section of lua.h that is gated by an #ifdef clause. I did that in lua_nodemcu.h IIRC because I came across a case where a module developer was trying to poke around the Lua engine intervals to implement the module.

@@ -42,12 +42,15 @@
** created; the seed is used to randomize hashes.
*/
#if !defined(luai_makeseed)
#if defined(LUA_USE_ESP)
#if defined(LUA_USE_ESP8266)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the ccount register also available on the ESP32? If so, then this should be LUA_USE_ESP

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ccount is an Xtensa thing. The ESP32-C3 (and upcoming ESP32-H2) is a RISC-V core.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup but wouldn't we be introducing a new LUA_USE_RISCV category or at least review this hierarchy of USE source tailoring macros?

@@ -80,7 +80,7 @@
** wo is the offset of aligned word in bytes 0,4,8,..
** bo is the field within the word in bits 0..31
*/
#ifdef LUA_USE_ESP
#if defined(LUA_USE_ESP8266)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another one that also applies to the ESP32?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. RISC-V does not take kindly to Xtensa assembly :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As previous comment. Perhaps we need to do that review sooner rather than later.

@@ -84,6 +78,8 @@ int luaO_ceillog2 (unsigned int x) {
x--;
while (x >= 256) { l += 8; x >>= 8; }
return l + log_2[x];
#else
return (x == 1) ? 0 : 32 - __builtin_clz(x - 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this builtin also available for the ESP8266? If so then we should be using it rather than a more cludgy asm construct. Where can I get a list of builtins that apply to the ESP32 and ESP8266 compiler?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's part of the standard builtins provided by gcc/clang. See e.g. gcc docs. I did run into an issue where on x86_64 compiled without optimisations it would error at runtime, so I left the host builds with the slow implementation.

* See Xtensa Instruction Set Architecture (ISA) Refman P 462 */
asm volatile ("nsau %0, %1;" :"=r"(x) : "r"(x));
return 31 - x;
return 31 - __builtin_clz(x);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same point about use of builtins vs asm() as below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah on Xtensa __builtin_clz() translates to a nsau instruction.

@@ -28,7 +28,7 @@
#define LUA_TUPVAL (LAST_TAG+2)
#define LUA_TDEADKEY (LAST_TAG+3)

#ifdef LUA_USE_ESP
#ifdef LUA_USE_ESP8266
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the ESP32 support unaligned data fetches from IRAM and IFLASH?. If so then how many extra clocks? The access macros add one extra register instruction to use an aligned read. If this is still faster then why have this difference between the ESP8266 and ESP32 versions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this is predominantly an Xtensa vs RISC-V issue here. But yes, data memory regions are byte accessible. Some optimisation may be possible, but has not been a priority for me at this point - getting NodeMCU to run on all the different ESP32 SoCs has been :)

@@ -309,7 +309,7 @@ LUA_API int (lua_pushlfsindex) (lua_State *L) {
* one upvalue that must be the set to the _ENV variable when its closure is
* created, and as such this parallels some ldo.c processing.
*/
LUA_API int (lua_pushlfsfunc) (lua_State *L) {
LUA_API int lua_pushlfsfunc(lua_State *L) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard pattern is to add the parentheses where a define macro might be encoded to force sensible compile errors here. Why change this?

Ditto on following cases.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard pattern is to only parenthesise function names only when typedef'ing function pointer types. Why would these be different? If someone #defines a function name to something else, surely that is on them?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just feel that we should follow the standard Lua coding standards where practical

@@ -427,7 +427,9 @@ static const char *readF (lua_State *L, void *ud, size_t *size) {

static void eraseLFS(LFSflashState *F) {
lu_int32 i;
#ifdef LUA_USE_ESP
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely, the use of bare printf() statements for ESP code is generally deprecated. We should use the appropriate equivalent. Whatever we need a clear coding standard here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The printf()s aren't mine. I merely added the #ifdefs because having host-side LFS image generation tell me it's erasing flash was misleading at best.
(Okay, technically I believe I moved one of the printfs to reduce the number of ifdefs I needed)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this, we should move towards POSIX compliant source wherever practical. The real issue here is that printing should be deprecated, except for very specific circumstances, as it will be unusual for a human or logging system to be 'listening' to the serial output, mainly development debugging. This .... progress bar is really a development tool.

@@ -436,11 +438,13 @@ static void eraseLFS(LFSflashState *F) {
#ifdef LUA_USE_ESP
if (*f == ~0 && !memcmp(f, f + 1, FLASH_PAGE_SIZE - sizeof(*f)))
continue;
printf(".");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above re use of print. The code skips the erase where it is not need and this makes flashing of smaller LFS images a lot faster. The dots are a pretty useful visual progress bar

@TerryE TerryE self-requested a review September 25, 2021 17:59
@jmattsson
Copy link
Member Author

I need to understand the extra meta fields on the ROTable declarations, or are this just a keyed recoding of the positional initialiser?

That is purely a change from array-style initialisation ({ 1, 2, 3 }) to named member initialisation ({ .x = 1, .y = 2, .z = 3}). I had a hard time working out what got set to what when I was chasing something through this code, and the ROTable struct being composed through two levels of indirect #defines was doing my head in. Aside from being a bit more readable, longer term the named member initialisation is a bit safer in the face of changing structures too (also been there, done that, have the scars...).

@nwf nwf added this to the 2022 rel 1 milestone Jan 2, 2022
@marcelstoer
Copy link
Member

Johny, any chance to revive this old PR? Reducing deltas between our branches would certainly be desirable I guess.

@jmattsson
Copy link
Member Author

Honestly, I think the ship has sailed at this point Marcel. Both personally and at $work we have moved on from the venerable 8266. It's been a couple of years since I last actively touched an 8266 and even then it was only in maintenance mode. Even when I prepared this PR I wasn't working with the 8266 any longer. Between that, my limited time availability, and Terry not having (had?) time/interest to skill up on the ESP32 ecosystem I don't think this will happen. We could leave the PR sitting around in the hope that changes, or we could close it. I'm happy to leave the source branch there should it ever become relevant again.

@marcelstoer
Copy link
Member

I think the ship has sailed at this point Marcel [..] We could leave the PR sitting around in the hope that changes, or we could close it.

I fully agree and I don't mind closing this one. I asked because I see a third option: merging what's already there.

@HHHartmann
Copy link
Member

Especially not sure about Terry's comment in app/lua/lnodemcu.h
So would rather not like to see at least that part in the esp8266 branch

@jmattsson
Copy link
Member Author

@HHHartmann I had a re-read of that comment and it does not make sense to me. There is no re-ordering, it is merely a change to using designated initalization to avoid bugs creeping in if there is reordering of actual structure declaration at some point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants