Какая связь между классом `v8 :: Isolate` и` v8 :: internal :: Isolate` в V8 - PullRequest
0 голосов
/ 30 июня 2019

Я недавно изучаю исходный код V8.Есть 2 определения класса Isolate, одно в v8::Isolate, а другое в v8::internal::Isolate.Кажется, что v8::Isolate использует v8::internal::Isolate, но я не мог понять связь между этими двумя определениями /

Я пытался изучить определения обоих классов, v8::Isolate в https://github.com/v8/v8/blob/master/include/v8.h#L7391 и v8::internal::Isolate в https://github.com/v8/v8/blob/master/src/execution/isolate.h#L452

, но не может понять это.

Точнее говоря, в v8::Isolate::New (https://github.com/v8/v8/blob/master/src/api/api.cc#L7903), возвращается объект C ++тип v8::Isolate.

Isolate* Isolate::New(const Isolate::CreateParams& params) {
  Isolate* isolate = Allocate();
  Initialize(isolate, params);
  return isolate;
}

Но внутренне в функции Allocate он возвращает объект типа v8::internal::Isolate и возвращает его в v8::Isolate

Isolate* Isolate::Allocate() {
    return reinterpret_cast<Isolate*>(i::Isolate::New());
}

Как можно возразитькласса v8::Isolate отлиты от v8::internal::Isolate?

Может ли кто-нибудь, знакомый с V8, дать мне какое-нибудь руководство?

1 Ответ

1 голос
/ 01 июля 2019

Этот метод не является чем-то необычным для библиотек: v8::internal::Isolate - это реализация, но ее детали полностью инкапсулированы в библиотеке и скрыты от общедоступного API. v8::Isolate это просто непрозрачная ссылка. Наблюдайте, как у него нет полей; Embedders ничего не знает о том, как он выглядит в памяти (или вообще имеет ли он представление в памяти - насколько они могут быть связаны с файловым дескриптором ядра). Причина такой инкапсуляции, конечно же, заключается в том, чтобы разделить задачи и сделать компоненты независимыми друг от друга: библиотека может изменить внутреннее определение класса без необходимости в средствах вставки (то есть они не могут зависеть от внутреннего состояния). так что гарантируется, что они не будут нарушены изменениями, их даже не нужно перекомпилировать, потому что публичный API [и ABI] не меняется при изменении макета внутреннего класса).

Рассмотрим уменьшенный пример, демонстрирующий принцип:

/* public API */

class BlackBox {
public:
  static BlackBox* Create();
  void DoSomething();
}

void StandaloneFunction(BlackBox* box);


/* internal implementation */

class TheRealThing {
 public:
  TheRealThing(int value) : value_(value) {}

 private:
  int value_;
}

BlackBox* BlackBox::Create() {
  TheRealThing* real = new TheRealThing(42);
  return reinterpret_cast<BlackBox*>(real);
}

void BlackBox::DoSomething() {
  TheRealThing* real = reinterpret_cast<TheRealThing*>(this);
  printf("Hello %d\n", real->value_);
}

void StandaloneFunction(BlackBox* box) {
  TheRealThing* real = reinterpret_cast<TheRealThing*>(box);
  printf("Good bye %d\n", real->value_);
}
...