Javet — Patch V8 Function at Source Code Level

Why is That Important?

Functions can be changed on the fly at JavaScript code level via Javet API. Why to choose this approach? Because sometimes local scoped context is required which is usually called closure. E.g:

const a = function () {
const b = 1;
return () => b;
}
const x = a();
console.log(x());
// Output is: 1

How?

getSourceCode() and setSourceCode(String sourceCode) are designed for getting and setting the source code. setSourceCode(String sourceCode) actually performs the follow steps.

def setSourceCode(sourceCode):
existingSourceCode = v8Function.getSourceCode()
(startPosition, endPosition) = v8Function.getPosition()
newSourceCode = existingSourceCode[:startPosition] + sourceCode + existingSourceCode[endPosition:]
v8Function.setSourceCode(newSourceCode)
v8Function.setPosition(startPosition, startPosition + len(sourceCode))
Memory Layout of V8 Function
originalSourceCode = v8ValueFunction.getSourceCode()
v8ValueFunction.setSourceCode(sourceCode)
v8ValueFunction.call(...)
v8ValueFunction.setSourceCode(originalSourceCode)
originalSourceCode = v8ValueFunction.getSourceCode()
if (v8ValueFunction.getJSScopeType().isClass()) {
try {
v8ValueFunction.callVoid(null);
// Now v8ValueFunction.getJSScopeType().isFunction() is true
} catch (JavetException e) {
}
}
v8ValueFunction.setSourceCode(sourceCode) // true
v8ValueFunction.call(...)
v8ValueFunction.setSourceCode(originalSourceCode)
Lifecycle of V8 Function

What is the Source Code of a Function in V8?

When V8 calculates start position of a function, it does not include the keyword function and function name. E.g.

function abc(a, b, c) { ... } // Source code is (a, b, c) { ... }

(a, b, c) => { ... } // Source code is (a, b, c) => { ... }

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store