javascriptc++node.jsv8

How does the parameter const v8::FunctionCallbackInfo<v8::Value>& args get its value at the C++ level?


Reading the source code and finding different functions that can be called from the js code, for example new TCP, it is not entirely clear how the C++ level accepts arguments to its level for a specific bound function.

For example, this js call is bound

new TCP(TCPConstants.SERVER)

with the following code on С++

void TCPWrap::New(const FunctionCallbackInfo<Value>& args) {
  // This constructor should not be exposed to public javascript.
  // Therefore we assert that we are not trying to call this as a
  // normal function.
  CHECK(args.IsConstructCall());
  CHECK(args[0]->IsInt32());
  Environment* env = Environment::GetCurrent(args);

  int type_value = args[0].As<Int32>()->Value();
  TCPWrap::SocketType type = static_cast<TCPWrap::SocketType>(type_value);

  ProviderType provider;
  switch (type) {
    case SOCKET:
      provider = PROVIDER_TCPWRAP;
      break;
    case SERVER:
      provider = PROVIDER_TCPSERVERWRAP;
      break;
    default:
      UNREACHABLE();
  }

  new TCPWrap(env, args.This(), provider);
}

That is, I want to understand how the C++ level const FunctionCallbackInfo<Value>& args is initialized for the bound function, thanks.


Solution

  • Codesearch finds a single call site of the FunctionCallbackInfo constructor, in api-arguments-inl.h. And that's right before the embedder-provided callback is invoked with this FunctionCallbackInfo instance.

    You'll likely next wonder where values_, argv_, and argc_ are coming from. The answer to that is only a few codesearch clicks away, I'll let you explore the code yourself. You should be able to trace it one step deeper, and then you're at the "magic" boundary where code generated by V8 uses custom-tailored assembly to call out to precompiled C++ functions, so you won't be able to trace it any further by following regular C++ constructs like classes and calls.
    (If you're curious about the deeper details, look for Builtins::Generate_CEntry in builtins-x64.cc, but I doubt that that will be particularly insightful.)