Looking at the above image, the JS code is compiled to assembly code.

To run the compiled code, it allocates a space on the memory, moves the code to the allocated space and jumps to the memory space.

At the jump, execution now begins from the compiled code. Hence, it has crossed a boundary.

The code being executed now isn’t a C++ code but JS code. All are now in assembly.

If the compiled JS code execution ends, it jumps back to the C++ code.

The C++ code and JS code here doesn’t mean the C++ source code or the JS source code. No. It is the assembly code generated from their source codes by the compiler is what is being executed. You can say C++ code and JS code to differentiate which assembly code being run.

Call from JS to C++

Functions in C++ source code can be called from a JS code.

Example:

// script.js

let f = 90

function send() {

var f= 100

}

send()

sendMe()

In this code, we defined send function but there is no sendMe function.

The sendMe function will be defined in our C++ app:

// v8_demo.cpp

include "v8.h"; void sendMe() {

cout << "Greetings from C++ land";

} int main() {

Maybe<Local> result = v8::Script::Compile('script.js');

result->Run();

}

Note: the above snippets won’t run. Its just for demo purposes.

Here, we have the sendMe function.

See what happens. On execution, our v8_demo.cpp runs like this:

MEMORY

; v8_demo.cpp

x00 sendMe:

x01 push ""Greetings from C++ land""

x02 call cout

x03 ret

x04

x05 main:

x06 push "script.js"

x07 call Compile

x08 push eax

x09 call Run

x10

x11

x12

x13

x14

x15

x16

x17

x18

x19

x20

see the sendMe function is present. Execution starts from main and proceeds downwards. On x07 , the script.js is compiled and pushed to memory.

MEMORY

; v8_demo.cpp

x00 sendMe:

x01 push ""Greetings from C++ land""

x02 call cout

x03 ret

x04

x05 main:

x06 push "script.js"

x07 ➥ call Compile

x08 push eax

x09 call Run

x10

x11 ;script.js

x12 mov 90,f

x13 send:

x14 push 100

x15 call send

x16 call sendMe

x17

x18

x19

x20

See our script.js assembly code in memory. :) Here, there is no C++ or JS code. Everything is in assembly. Like I said earlier, we can just demarcate like, here is assembly code from the C++ script and here is assembly code from JS script.

So, when Run x09 is executed,

MEMORY

; v8_demo.cpp

x00 sendMe:

x01 push ""Greetings from C++ land""

x02 call cout

x03 ret

x04

x05 main:

x06 push "script.js"

x07 call Compile

x08 push eax

x09 ➥ call Run

x10

x11 ;script.js

x12 mov 90,f

x13 send:

x14 push 100

x15 call send

x16 call sendMe

x17

x18

x19

x20

it jumps to the JS assembly code memory space x12 .

Note: Run is a v8 API to run the compiled JS code after compilation.

MEMORY

; v8_demo.cpp

x00 sendMe:

x01 push ""Greetings from C++ land""

x02 call cout

x03 ret

x04

x05 main:

x06 push "script.js"

x07 call Compile

x08 push eax

x09 call Run

x10

x11 ;script.js

x12 ➥ mov 90,f

x13 send:

x14 push 100

x15 call send

x16 call sendMe

x17

x18

x19

x20

Here, the code we wrote in script.js is executed in assembly form.

When execution reach x15 call send , it jumps to x13 send: and executes its block, after that, it returns and calls sendMe .

MEMORY

; v8_demo.cpp

x00 sendMe:

x01 push ""Greetings from C++ land""

x02 call cout

x03 ret

x04

x05 main:

x06 push "script.js"

x07 call Compile

x08 push eax

x09 call Run

x10

x11 ;script.js

x12 mov 90,f

x13 send:

x14 push 100

x15 call send

x16 ➥ call sendMe

x17

x18

x19

x20

This function wasn’t defined in our script.js , but because it was defined in v8_demo.cpp , it is now available in memory. It can be called because the assembly form of script.js and v8_demo.cpp , now executes in one language and in the same memory space.

So, execution jumps to x00 sendMe: , the start of the sendMe function.

MEMORY

; v8_demo.cpp

x00 ➥ sendMe:

x01 push ""Greetings from C++ land""

x02 call cout

x03 ret

x04

x05 main:

x06 push "script.js"

x07 call Compile

x08 push eax

x09 call Run

x10

x11 ;script.js

x12 mov 90,f

x13 send:

x14 push 100

x15 call send

x16 call sendMe

x17

x18

x19

x20

:) Greetings from C++ land is displayed !!

So, this kind of jump is called Crossing the C++/JS boundary .

Likewise call from C++ to JS is feasible, provided the function is defined in JS land.

Conclusion

You see it is quite simple, no magic, no big deal. Whenever you hear "Crossing C++/JS" , always picture everything running in assembly and in the same memory space.

In our next articles, we will dive in deep to see how some major Node.js APIs works underneath:

setTimeout

process.nextTick

setImmediate

Promise

setInterval

If you have any question regarding this or anything I should add, correct or remove, feel free to comment, email or DM me. Thanks !!! 👍