Espruino Internals #4849
Replies: 1 comment
-
Posted at 2015-04-09 by @gfwilliams And then...
You'd have to look further into the code - look at the comments here: https://github.com/espruino/Espruino/blob/master/src/jsutils.h#L254
The 2nd column 'Name' is just the name of the field - it doesn't really mean anything other than being descriptive (and possibly the name of the variable)
Some variable types have just a single child. See
Yes. jswrapper may 'make' the global variable if it doesn't already exist though.
see 'lvalue' on wikipedia - a Name in Espruino is one of those - a variable that is a pointer to another. For instance in
It skips the name. In the case above, 'jsvSkipName(a)' would skip over 'a' and return 1.
JsExecIfo->root is basically the value of the 'global' variable. jsVar[JSVAR_CACHE_SIZE] holds all variables, including 'global'. Posted at 2015-04-09 by alexanderbrevig Extremely useful! Sticky or link to here from github README maybe? Good job with the writeup! Posted at 2015-04-09 by @gfwilliams Good idea - I'll put a link on http://www.espruino.com/Internals Posted at 2015-08-05 by RandyHarmon Sorry if I've missed this detail in existing communication. I'm interested in how variable names are stored (with its data?) and matched from executing code. I'm assuming if Espruino uses a linked list for variables, that a variable name from executing source has to be found in the JsVar structure? I'm particularly curious about the string-length overheads (on mem & CPU both) during execution of code having variable names, and what optimizations may already be in use or available (e.g. pre-munging var names with Esprima, or ???). Another angle on optimization (if relevant) is code-path frequency, in that (assuming a given variable name is evaluated faster if shorter), we could rewrite most-commonly-ACCESSED vars with the shortest names (it's hard to think Esprima could help much with that) Another question has to do with namespacing of vars. It seems to me that an object global.JUNK = { foo: 'bar' } implies a variable 'foo' in JUNK's namespace (yes?) which puts an interesting twist on potentially rewriting 'foo'. Seems like JUNK has a linked list of its properties, but again with the variable-name question. Finally, if I have obj1 = { foo: "bar" }; obj2 = obj1, then these two variables both point to the same object. Probably the answer about var names will demonstrate how this is implemented too, but if not, that extra info would be interesting too. Thanks in advance. R Posted at 2015-08-06 by @gfwilliams Have you checked out http://www.espruino.com/Performance and http://www.espruino.com/Internals ? If you something like Variable names of 4 chars or left are stored in a single JsVar, so are very efficient (so minified code works great). Also, if the value they represent is small (for instance a 16 bit int) it is stored in the exact same JsVar. If not (for instance it's an object) it points to another JsVar that represents the object. The initial search is pretty quick too, as Espruino does something like:
To take advantage of this, modules are already minified.
Because you've got linked lists, if you've got a bunch of functions/variables you're better off adding your own tree structure by putting them in objects as you suggest. Generally you'd do that anyway though... So for instance my car's ECU uses Espruino, and it has a bunch of pins that control things. I put those in an object called
It's best to poke around with the
So you actually have just 5 JsVars (the number with the
But if
Suddenly its only 4 JsVars, because both In the same way, if you had a long name that wouldn't fit in one var, another one gets added:
Now the object itself takes 4 blocks, so the whole thing (obj1 and obj2) takes 6. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2015-04-09 by @gfwilliams
I recently got asked some pretty deep questions about Espruino by e-mail - I'm copying here as they're probably useful to anyone hacking on Espruino...
'Native' is information for functions that are implemented as native code rather than JavaScript (so basically compiled C code). 'Ref' contains references to other children/siblings in the linked list/tree structure.
See http://en.wikipedia.org/wiki/Union_type#C.2FC.2B.2B
Basically unions overlap in memory, so all the elements of JsVarData share the same bytes. There is some documentation under the definition that describes how bytes are used for different types of variable:
https://github.com/espruino/Espruino/blob/master/src/jsvar.h#L144
Also:
http://www.espruino.com/Internals
“nextSibling”, ”prevSibling” are when the JsVar is used in a linked list
refs is for reference counting - it's the number of references to the JsVar - if that is 0 and there are no locks then the variable can be freed.
”firstChild” and “lastChild” point to the beginning and end of a linked list of children.
The best way to get an idea of how they're all used is to type
trace()
in Espruino. This will dump out the datastructure in a human readable form (to see how, look at jsvTrace).It's a linked list. But a JsVar can have children, in which case it is a linked list of children too.
[A5,A6]
goes toJsVar(Array, JsVar(Name_int, 0, JsVar(Pin,A5)), JsVar(Name_int, 1, JsVar(Pin, A6)))
(Note: the use of JsVar() is just pseudo-code to denote a tree structure)
But arrays can be 'packed' - if you used a simple number like
[4,5]
you'd get:JsVar(Array, JsVar(Name_int_int, 0, 4), JsVar(Name_int_int, 1, 5))
It actually doesn't go into JsExecIfo->root as it isn't a global variable, but it's stored as a linked list while executing the function
digitalWrite
Beta Was this translation helpful? Give feedback.
All reactions