Skip to content

Instantly share code, notes, and snippets.

@tromey
Last active August 5, 2017 14:11
Show Gist options
  • Save tromey/20d7edf9ca5d58630347843041189690 to your computer and use it in GitHub Desktop.
Save tromey/20d7edf9ca5d58630347843041189690 to your computer and use it in GitHub Desktop.
line table hacking

First, do a full (not artifact) build with the spidermonkey shell enabled. You'll need this in your .mozconfig:

ac_add_options --enable-js-shell
ac_add_options --enable-debug

This takes a while. Once it is finished you can run the shell to verify that the dis function works:

$ ./obj-x86_64-pc-linux-gnu/dist/bin/js
js> dis(() => {})
flags: LAMBDA ARROW
loc     op
-----   --
main:
00000:  retrval                         # 

Source notes:
 ofs line    pc  delta desc     args
---- ---- ----- ------ -------- ------
  0:    1     0 [   0] colspan 11

You can use disfile to inspect top-level scripts (outside of a function); just pass the file name to disfile.

You don't normally need to know the semantics of each opcode in order to understand what is going on; instead it's usually enough to follow the flow control opcodes.

Here's an example showing a member expression:

js> dis((x) => { x.a(); })
flags: LAMBDA ARROW
loc     op
-----   --
main:
00000:  getarg 0                        # x
00003:  dup                             # x x
00004:  callprop "a"                    # x x.a
00009:  swap                            # x.a x
00010:  call-ignores-rv 0               # x.a(...)
00013:  pop                             # 
00014:  retrval                         # 

Source notes:
 ofs line    pc  delta desc     args
---- ---- ----- ------ -------- ------
  0:    3     0 [   0] colspan 13
  2:    3    14 [  14] xdelta  
  3:    3    14 [   0] colspan 7

Here you can see that the call (instruction at PC=10) doesn't have its own column number. We'd probably want it to emit a column for the . at PC=4.

SpiderMonkey works by parsing the text into an AST, and then walking the AST to create the bytecode. The parser is in js/src/frontend/Parser.cpp. However, in many cases (like this one) the issue is actually in the bytecode emission. That's in js/src/frontend/BytecodeEmitter.cpp.

Tests for the debugger API are in js/src/jit-test/tests/debug/. You may want to look at Script-getAllColumnOffsets-01.js (and similar) for examples of how to write these. See js/src/jit-test/README for information on running the tests.

@bomsy
Copy link

bomsy commented Aug 5, 2017

got it to work, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment