JavaScript: Teach API graphs about (some) promisification and bound arguments.#4706
Conversation
|
Evaluation showed a mild overall slowdown; for details see internal issue. I'll leave this in draft state until we've decided what to do about the BDD issue. |
| boundArgs = 0 | ||
| or | ||
| exists(DataFlow::CallNode promisify | | ||
| promisify = API::moduleImport(["util", "bluebird"]).getMember("promisify").getACall() |
There was a problem hiding this comment.
Hm, double recursion through API::moduleImport().getMember().getACall() and trackUseNode. Seems safer to just use local data flow to recognize promisify calls.
| exists(DataFlow::PartialInvokeNode pin, DataFlow::Node pred, int predBoundArgs | | ||
| trackUseNode(nd, promisified, predBoundArgs, t.continue()).flowsTo(pred) and | ||
| result = pin.getBoundFunction(pred, boundArgs - predBoundArgs) and | ||
| boundArgs <= 10 |
There was a problem hiding this comment.
I'd add a lower bound as well, just to be safe.
BindPartialCall currently sets boundArgs like this,
boundArgs = getNumArgument() - 1which can in principle be negative. We could try to enforce that getBoundFunction never holds for a negative boundArgs value but it seems more robust to check it here.
|
|
||
| private DataFlow::SourceNode awaited(DataFlow::InvokeNode call, DataFlow::TypeTracker t) { | ||
| t.startInPromise() and | ||
| exists(MkSyntheticCallbackArg(_, _, call)) |
1ce199f to
40183b1
Compare
Following a suggestion by Asger, we track use nodes through calls to `promisify`. When we see a call to a promisified function, we introduce a new synthetic API-graph node representing the callback argument synthesised by the promisification, and track the result of the call to an `await` (or other promise resolution), which is then considered to be a use of the first parameter of the synthetic callback (the zeroth parameter being an error code, which we do not model yet).
40183b1 to
f40b406
Compare
|
Rebased; let's see if the recent CodeQL improvements have fixed the BDD-node exhaustion problem. If so, I'll set off another performance evaluation. |
|
Performance looks reasonable (internal link). As discussed, I'm happy to wait for this PR to be merged until more critical ones have gone in, just to make sure we still have enough breathing room in terms of BDD nodes. |
|
@max-schaefer happy to merge as is. If you're referring to #4772 I'd like to hold on to that a bit, since it's not currently clear if it's helping. |
To be honest, I've lost context a bit, so I don't remember exactly which other PRs I was afraid of conflicting with. I trust your judgement on this! |
The first commit is an implementation of @asgerf's excellent suggestion for how to deal with
util.promisifyand friends (though notpromisifyAllyet) with an eye towards removing some ad-hoc handling in the NoSQL library. That turned out to also need a model of bound arguments, which is added in the second commit.On the whole, this is a somewhat ambitious set of changes, which will need a careful evaluation. I also know of several other improvements to the API-graphs library that are currently in flight; I'm happy to rebase this over those changes.