2

I was working on node and want to see the compiled bytecode . Is there a way we can compile a js file and save the bytecode in a seperate file using node ??

user2225263
  • 277
  • 4
  • 15
  • 1
    javascript isn't compiled (in the traditional sense) - it's an interpreted language – Jaromanda X Apr 18 '17 at 01:11
  • Yeah, I mean interpreted/compiled into bytecode by node. Node do compile JS into bytecode. I did not get your comment. – user2225263 Apr 18 '17 at 01:12
  • 2
    The basic answer is "no". – Pointy Apr 18 '17 at 01:14
  • 1
    Node (or rather V8 JS engine that Node runs on) does **not** compile into bytecode, it is compiled on-the-fly into native code. If you wish to see the generated native code, [this answer](http://stackoverflow.com/questions/277423/how-can-i-see-the-machine-code-generated-by-v8) might be of use. – Amadan Apr 18 '17 at 01:25
  • this link http://stackoverflow.com/questions/277423/how-can-i-see-the-machine-code-generated-by-v8?noredirect=1&lq=1 is pretty much talks about inspecting the v8 code base to see the generated bytecode( this will consume by JVM to convert to native code) . I was just wondering if Node gives us an API to halt the process and flush the compiled output in a file instead of sending it to the CPU. – user2225263 Apr 18 '17 at 01:38
  • JVM is Java Virtual Machine, which has nothing to do with JavaScript. And in V8, again, **there is no bytecode.** From [Wikipedia](https://en.wikipedia.org/wiki/Chrome_V8): "V8 compiles JavaScript directly to native machine code before executing it, instead of more traditional techniques such as interpreting bytecode or compiling the whole program to machine code and executing it from a filesystem. The compiled code is additionally optimized (and re-optimized) dynamically at runtime, based on heuristics of the code's execution profile.". The linked answer shows native assembly, not bytecode. – Amadan Apr 18 '17 at 01:50
  • @user2225263 *I did not get your comment* - perhaps saying javascript is not java may help (your mention of JVM rings alarm bells) – Jaromanda X Apr 18 '17 at 01:54
  • 1
    Note that other JS engines do have bytecode; e.g. SpiderMonkey, used by Mozilla, does have bytecode; and Rhino compiles JavaScript to JVM. None of those are used by Node, though. – Amadan Apr 18 '17 at 01:57
  • I think, I am clear now. I was a bit out-of-the-line as far as V8 working goes. Thanks for the clarification. Appreciated. – user2225263 Apr 18 '17 at 19:25
  • if one still thinks V8 doesnt generate temporary bytecode in 2017, he should read about [ignition component of V8](https://v8project.blogspot.com/2016/08/firing-up-ignition-interpreter.html). and understand it does. – antiplayer Oct 15 '17 at 17:13

2 Answers2

1

You can use --trace_ignition to get the intermediary byte code:

#node --trace_ignition a.js
 -> 0x3aa1c02bf66e @    0 : 80                StackCheck 
 -> 0x3aa1c02bf66f @    1 : 13 13             LdaImmutableCurrentContextSlot [19]
      [ accumulator <- 0xd88d0f93ce9 <JS Function NativeModule (SharedFunctionInfo 0x3aa1c02b86a1)> ]
 -> 0x3aa1c02bf671 @    3 : 1f f7             Star r3
      [ accumulator -> 0xd88d0f93ce9 <JS Function NativeModule (SharedFunctionInfo 0x3aa1c02b86a1)> ]
      [          r3 <- 0xd88d0f93ce9 <JS Function NativeModule (SharedFunctionInfo 0x3aa1c02b86a1)> ]
 -> 0x3aa1c02bf673 @    5 : 21 f7 00 04       LdaNamedProperty r3, [0], [4]
      [          r3 -> 0xd88d0f93ce9 <JS Function NativeModule (SharedFunctionInfo 0x3aa1c02b86a1)> ]
      [ accumulator <- 0x3aa1c02bcb49 <JS Function NativeModule.getSource (SharedFunctionInfo 0x3aa1c02b8c51)> ]
 -> 0x3aa1c02bf677 @    9 : 1f f8             Star r2
      [ accumulator -> 0x3aa1c02bcb49 <JS Function NativeModule.getSource (SharedFunctionInfo 0x3aa1c02b8c51)> ]
      [          r2 <- 0x3aa1c02bcb49 <JS Function NativeModule.getSource (SharedFunctionInfo 0x3aa1c02b8c51)> ]
 -> 0x3aa1c02bf679 @   11 : 21 02 01 06       LdaNamedProperty <this>, [1], [6]
      [      <this> -> 0xd88d0f9a329 <a NativeModule with map 0x11929f412849> ]
      [ accumulator <- 0x3aa1c02bb969 <String[6]: events> ]
 -> 0x3aa1c02bf67d @   15 : 1f f6             Star r4
      [ accumulator -> 0x3aa1c02bb969 <String[6]: events> ]
      [          r4 <- 0x3aa1c02bb969 <String[6]: events> ]
 -> 0x3aa1c02bf67f @   17 : 45 f8 f7 02 02    CallProperty r2, r3-r4, [2]
      [          r2 -> 0x3aa1c02bcb49 <JS Function NativeModule.getSource (SharedFunctionInfo 0x3aa1c02b8c51)> ]
      [          r3 -> 0xd88d0f93ce9 <JS Function NativeModule (SharedFunctionInfo 0x3aa1c02b86a1)> ]
      [          r4 -> 0x3aa1c02bb969 <String[6]: events> ]
      [ accumulator <- 0xd88d0f956f1 <Very long string[15201]> ]
 -> 0x3aa1c02bf684 @   22 : 1f f9             Star r1
      [ accumulator -> 0xd88d0f956f1 <Very long string[15201]> ]
      [          r1 <- 0xd88d0f956f1 <Very long string[15201]> ]

You can use --print_code to get the natively generated code:

#node --print_code -e 'console.log("hello")' > code.txt
#head -100 code.txt
    --- Raw source ---
    (){
      var originAssert = this.assert;
      originAssert.apply = Function.prototype.apply;
      this.assert = assertWrapper;
      assertWrapper.toString = () => originAssert.toString();
      function assertWrapper(){
        if (!!arguments[0]) return;
        originAssert.apply(null, arguments);
      }
    })

    --- Code ---
    source_position = 9
    kind = FUNCTION
    compiler = full-codegen
    Instructions (size = 500)
    0x29b8195043c0     0  55             push rbp
    0x29b8195043c1     1  4889e5         REX.W movq rbp,rsp
    0x29b8195043c4     4  56             push rsi
    0x29b8195043c5     5  57             push rdi
    0x29b8195043c6     6  488b4f2f       REX.W movq rcx,[rdi+0x2f]
    0x29b8195043ca    10  488b4907       REX.W movq rcx,[rcx+0x7]
    0x29b8195043ce    14  83411b01       addl [rcx+0x1b],0x1
    0x29b8195043d2    18  41ff75a0       push [r13-0x60]
    0x29b8195043d6    22  b801000000     movl rax,0x1
    0x29b8195043db    27  e80038f3ff     call FastNewFunctionContextFunction  (0x29b819437be0)    ;; code: BUILTIN
    0x29b8195043e0    32  488bf0         REX.W movq rsi,rax
    0x29b8195043e3    35  488945f8       REX.W movq [rbp-0x8],rax

Hope this helps.

Gireesh Punathil
  • 1,344
  • 8
  • 18
0

You can see the byte code

If you want to see V8's bytecode of JavaScript code, you can print it by calling D8 or Node.js (8.3 or higher) with the flag --print-bytecode. For Chrome, start Chrome from the command line with --js-flags="--print-bytecode", see Run Chromium with flags.

Read full article here Understanding V8 Byte code

Not sure how to print into a file.

Community
  • 1
  • 1
Dinesh Ravi
  • 1,209
  • 1
  • 17
  • 35