javascript — в Duktape, как преобразовать содержимое исходного файла JS в байт-код

Я хотел бы знать, как выполняется шаг, описанный ниже:

  1. Как преобразовать исходный файл JS (test.js с двумя функциями, funcA () и funcB ()) в байт-код?
  2. Как загрузить сгенерированный байт-код в duktape и вызвать одну из функций, скажем, funcA ()?

Благодарю.

test.js:

function funcA() {
print("funcA()");
}

function funcB() {
print("funcB()");
}

main.cpp

int main() {
duk_context* ctx = duk_create_heap_default();

std::string byteCodeBuff; // buffer where to save the byte code;

{ // generate the bytecode from 'sourceFilePath'

const char* sourceCodeFilePath = "test.js"; // contains the JS code
//  Step 1 How to 'dump' the 'sourceFilePath' to bytecode buffer ???

// get the duktape bytecode
duk_size_t bufferSize = 0;
const char* bytecode = (const char*)duk_get_buffer(ctx, -1, &bufferSize);

// save the bytecode to byteCodeBuff
byteCodeBuff.assign(bytecode,bufferSize);

duk_pop(ctx);  // bytecode buffer
}

{ // load the bytecode into duktape

const size_t length = byteCodeBuff.size();    // bytecode length
const char* bytecode = &byteCodeBuff.front(); // pointer to bytecode

char* dukBuff = (char*)duk_push_fixed_buffer(ctx, length); // push a duk buffer to stack
memcpy(dukBuff, bytecode, length); // copy the bytecode to the duk buffer

// Step 2 ??? How start using the bytecode
// ??? How to invoke funcA()
// ??? How to invoke funcB()
}

duk_destroy_heap(ctx);

return 0;
}

2

Решение

duk_dump_function а также duk_load_function являются ли функции, предоставляемые Duktape для преобразования в и из байт-кода:

Сначала загрузите ваш файл:

// Шаг 1 (а):
char * sourceCode;
int sourceLen;
{// загрузка из файла (простите за отсутствие ошибок ...)
ifstream fscript (sourceCodeFilePath, ios :: in | ios :: binary);
fscript.seekg (0, IOS :: конец);
sourceLen = fscript.tellg ();
буфер = новый символ [sourceLen];
fscript.seekg (0);
fscript.read (SourceCode, sourceLen);
}

Затем, при компиляции javascript, скрипт компилируется как «функция» (на самом деле кусок неисполненного глобального кода) в стек:

// Шаг 1 (б):

// скомпилировать исходный код
duk_compile_lstring (CTX, 0, SourceCode, sourceLen); // компилируется в функцию ECMAScript и помещает ее в верхнюю часть стека

// сбросить код в буфер
duk_dump_function (CTX); // заменяет функцию вершины стека ее байт-кодом

С этого момента остальная часть вашего кода должна забрать буфер на вершине стека.

Что касается его восстановления:

// Шаг 2 (а):
// заменяет буфер на вершине стека исходной функцией
duk_load_function (CTX);

// так как это глобальный скрипт, он должен быть выполнен перед вызовом невидимых функций
duk_call (CTX, 0); // возможно, рассмотрите возможность использования duk_pcall ()

На данный момент, ctx глобальный объект кучи теперь содержит свойства funcA а также funcB,
Они могут быть получены и вызваны как таковые:

// Шаг 2 (б):
// помещаем глобальный объект в стек, чтобы получить его свойства
duk_push_global_object (CTX);

// получаем функцию с именем «funcA» и помещаем ее в стек
duk_get_prop_string (CTX, -1, "funcA"); // имя ключа / глобальное имя функции

duk_require_function (CTX, -1); // Требуем, чтобы это была функция перед вызовом

// теперь вызываем это!
// duk_push_ * аргументы здесь
duk_call (CTX, 0); // 0: количество аргументов

// duk_get_ * (ctx, -1); получить возвращаемое значение

// возвращаемое значение поп-функции
duk_pop (CTX);

// текущая вершина стека: глобальный объект

// получить следующую функцию
duk_get_prop_string (CTX, -1, "funcB");

// Требуем, чтобы это была функция
duk_require_function (CTX, -1);

// вызвать его!
duk_call (CTX, 0);

// всплывающее возвращение и глобальный объект вне стека
duk_pop_2 (CTX);
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]