我想知道下面描述的步骤是如何完成的:
感谢。
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;
}
答案 0 :(得分:1)
duk_dump_function和duk_load_function是Duktape提供的用于转换为字节码的功能:
首先,只需加载您的文件:
// Step 1 (a): char* sourceCode; int sourceLen; { // load from file (excuse lack of error catching...) ifstream fscript(sourceCodeFilePath,ios::in | ios::binary); fscript.seekg(0,ios::end); sourceLen= fscript.tellg(); buffer = new char[sourceLen]; fscript.seekg(0); fscript.read(sourceCode,sourceLen); }
然后,在编译javascript时,脚本被编译为'功能' (实际上是一块未执行的全局代码)到堆栈中:
// Step 1 (b): // compile source code duk_compile_lstring(ctx,0,sourceCode,sourceLen); // compiles to an ECMAScript function and puts it on the stack top // dump the code into a buffer duk_dump_function(ctx); // replaces the stack top function with its bytecode
从这一点开始,代码的其余部分应该在堆栈顶部拾取缓冲区。
至于恢复它:
// Step 2 (a): // replaces the buffer on the stack top with the original function duk_load_function(ctx); // since this is a global script, it must be executed before calling the invidual functions duk_call(ctx,0); // perhaps consider using duk_pcall() instead
此时,ctx
堆的全局对象现在包含属性funcA
和funcB
。
这些可以这样获得和调用:
// Step 2 (b): // push the global object on the stack to get its properties duk_push_global_object(ctx); // obtain the function with the name "funcA" and push it on the stack duk_get_prop_string(ctx,-1,"funcA"); // key name / global function name duk_require_function(ctx,-1); // require this is a function before calling it // now invoke it! // duk_push_* arguments here duk_call(ctx,0); // 0: number of arguments // duk_get_* (ctx,-1); to obtain return value // pop function return value duk_pop(ctx); // current stack top: global object // get next function duk_get_prop_string(ctx,-1,"funcB"); // require it's a function duk_require_function(ctx,-1); // invoke it! duk_call(ctx,0); // pop return and global object off stack duk_pop_2(ctx);