I am doing some modifications to chromium, intending to gather data about the location of invoked JS functions.
As I understand it, the information regarding a function is held in the SharedFunctionInfo object defined by v8. This object has some convenient APIs to get the script's path defining the function and where it is located inside it:
void JavaScriptFrame::PrintFunctionAndOffset(JSFunction function,
AbstractCode code, int code_offset,
FILE* file,
bool print_line_number)
{
SharedFunctionInfo shared = function.shared();
Object maybe_script = shared.script();
Script script = Script::cast(maybe_script);
Object script_name_raw = script.name();
int firstCharPos = shared.StartPosition();
int lastCharPos = shared.EndPosition();
}
This works well for functions defined in .js files, but those indexes are no longer valid as soon as the function is defined in a .html file. This happens because v8 treats all single tags in a .html as isolated individual scripts, and the positions I get are computed referring only to the js code contained in those tags. Therefore, I get random HTML code once I want to extract the js function's code from the .html file using those coordinates.
Ideally, I would like to obtain the 'offset' defining how many characters precede each tag in a .html file. I have looked at various classes implemented by v8, e.g.: frames.cc, objects.cc ... but I need help locating this information as all I have tried was not helpful as of right now. Is it something that I can access from the v8 engine itself?
CodePudding user response:
Unfortunately, as you've noticed, the position information provided by these APIs is only valid for functions defined in JavaScript files and not for those defined in HTML files. This is because V8 treats each script tag in an HTML file as an individual script, so the position information is only valid within the context of that script tag.
To get the position of a function defined in an HTML file, you will need to use a different approach. One option is to use the Script::GetLineNumber method, which takes a character position in a script and returns the line number that position is on. You can then use this line number to get the location of the function in the HTML file. Here's an example of how you might do this:
// Get the SharedFunctionInfo object for the function you're interested in
SharedFunctionInfo shared = function.shared();
// Get the Script object for the function
Object maybe_script = shared.script();
Script script = Script::cast(maybe_script);
// Get the character position of the start and end of the function in the script
int start_position = shared.StartPosition();
int end_position = shared.EndPosition();
// Use the Script::GetLineNumber method to get the line number for each position
int start_line = script.GetLineNumber(start_position);
int end_line = script.GetLineNumber(end_position);
// The function is defined on the range of lines between start_line and end_line in the HTML file
This approach should give you the line numbers where the function is defined in the HTML file, which you can then use to extract the function's code from the file. Note that this approach assumes that the HTML file is not minified or otherwise modified in a way that changes the line numbers of the script tags. It also assumes that the function is defined within a script tag in the HTML file and not in an event handler or other attribute. If either of these assumptions is not true, you may need to use a different approach.