получение локализованной «глобальной» области видимости для функции v8

0

Я хочу создать своего рода локализованную область действия, которая будет действовать как набор глобальных элементов внутри определенной функции, но я хочу наследовать все глобальные переменные, которые могут уже существовать.

Однако должен быть более простой способ сделать это, чем то, что я делаю.

То, что я делаю прямо сейчас, это преобразовать объект области, который я хочу использовать, в строку, состоящую из объявлений и назначений var, в javascript. Я помещаю это внутри анонимной функции, которая возвращает мой исходный код функции и вызывает анонимную функцию, чтобы дать мне внутреннюю функцию.

Макрос MAKESTRING использует строковый поток для определения строки

std::prefix_code = convert_object_to_vars(scope);
std::code = MAKESTRING("(function() { " << prefix_code << "return (" << fdefinition << "); })()");
v8::TryCatch try_catch;
v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::NewFromUtf8(_isolate, code.c_str()));
if (try_catch.HasCaught())
    return v8::Undefined(_isolate);
if (script.IsEmpty())
    return v8::Undefined(_isolate);
v8::Local<v8::Value> result = script->Run();
if (try_catch.HasCaught())
    return v8::Undefined(_isolate);
if (!result->IsFunction())
    return v8::Undefined(_isolate);
return result

Переменная scope - это просто объект v8 :: Object, состоящий из пар значений ключа, описывающий различные переменные, которые существуют в области и их начальные значения.

Функция convert_object_to_vars - это то, где вещи становятся dicey... хотя это, похоже, работает, я должен явно писать код в функции convert для обработки каждого нового типа, который я хочу поддерживать, и по мере добавления дополнительных пользовательских типов эта функция быстро растет по сложности, поэтому я не уверен, что это долгосрочное решение. Кроме того, большая часть кода на convert_object_to_vars также должна быть реплицирована в другую функцию, которая возвращает удобочитаемое представление такого объекта.

Должен быть более простой способ.

  • 0
    Похоже , вы пытаетесь заново изобретать with .
  • 0
    Это не было бы плохим способом описать это.
Показать ещё 1 комментарий
Теги:
v8

1 ответ

0

Недавно я столкнулся с этой проблемой при разработке собственного дополнения к потоковым пулам.

Ключом к тому, чтобы это работать, - это настроить контекст, который будет выполнять функция, с помощью глобальных переменных, которые вы хотите получить в функции.

Это должно произойти до того, как вы скомпилируете и запустите стробированную функцию. Я привел небольшой пример ниже. myGlobalProperty будет доступен как глобальный внутри функции, потому что он был скомпилирован и запущен в текущем введенном контексте.

// configure context before executing function
HandleScope scope;
Handle<Object> contextObject = Context::GetCurrent()->Global();
contextObject->Set(String::NewSymbol("myGlobalProperty"), Object::New());

// turn function into string
String::Utf8Value funcStr(functionToExecute->ToString());
string funcToExe(*funcStr);
funcToExe.insert(0, "(");
funcToExe.append(")()");

// compile and run the function
// this will execute within the currently entered and configured context
Handle<Script> functionScript = Script::New(String::New(funcToExe.c_str()));
functionScript->Run();

Если вы хотите получить доступ к глобальным переменным после выполнения функции. Вам нужно будет получить к ним доступ через контекст, как показано ниже:

Handle<Value> myGlobal = contextObject->Get(String::NewSymbol("myGlobalProperty"));

Ещё вопросы

Сообщество Overcoder
Наверх
Меню