-
Notifications
You must be signed in to change notification settings - Fork 207
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
metering: tolerate bound "getMeter" in metered source code #1247
Comments
Hm, I suppose allowing So renaming identifiers sounds like the less-broken approach. |
Renaming the evaled code identifiers leads to a world of pain, especially once we support direct eval. Better is to have the injected |
we stopped doing code-transformation -based metering ages ago, this is no longer relevant |
Describe the bug
It looks like the identifier
getMeter
is entirely taboo in source code which is subject to the metering transform. Any source which happens to use this name (even in the normal "non free variable" case, where it defines a new function or variable with the name and references the one it just defined) will be rejected. This can be a bit surprising.The specific case where we saw source code being rejected was when the Zoe contract facet, bundled and loaded into a new (dynamic, metered) vat, was itself trying to impose metering on the new contract code (at this point in ZCF development, ZCF was using the same
evalContractBundle
that non-split Zoe was, and non-split zoe must do within-same-vat metering by creating agetMeter
endowment; ZCF was then corrected to not impose metering, because it's already running in a metered dynamic vat, and the immediate rejection problem went away).We certainly need to prohibit this confined code from successfully accessing the
getMeter
global lexical, because the one that metering references can be used to both increment and decrement the meter, and the confined code should not be able to refill its own meter. The transformation must not allow a freegetMeter
reference in the input survive to the output.I think the current transformation accomplishes this by throwing an exception if the parser ever reaches an identifier spelled
getMeter
. This effectively rejects any reference togetMeter
, whether it's bound or not.Ideally, the metering transform would only pay attention to unbound/free references to
getMeter
, so thatconst getMeter = 1; getMeter+2;
would pass. That would reduce much of the surprise.Another approach would be to rename any instances of
getMeter
into something else (maybegetMeter_1
). This would have to be a "Hilbert Hotel" -style renaming, because there might already be a variable namedgetMeter_1
(which must be renamed togetMeter_2
, etc). This changes the behavior of error messages and debug tools, and could break code which does e.g.let x = { getMeter: 1 }; x['get'+'Meter']
, but might be easier than a context/scope-sensitive transform.To Reproduce
Create a dynamic vat like:
Bundle that and load it into a dynamic vat.
The
createVat(bundle)
will fail, with an error somewhat likeIdentifier getMeter is reserved for metering code
.For a quick way to reproduce this, edit
packages/SwingSet/test/metering/metered-dynamic-vat.js
to insert aconst getMeter = 1;
anywhere in the file, then runnode -r esm test/metering/test-dynamic-vat.js
.cc @michaelfig because he wrote the transform and is probably the only one who understands Babel enough to pull this off.
We might defer fixing this long enough to switch to XS-based metering (and remove the transform altogether), although there a number of non-XS environments where we might still want transform-based metering, in which case this would be nice to have fixed.
The text was updated successfully, but these errors were encountered: