Javascript 在Duktape中,如何将JS源文件内容转换为字节码

Javascript 在Duktape中,如何将JS源文件内容转换为字节码,javascript,c++,duktape,Javascript,C++,Duktape,我想知道下面描述的步骤是如何完成的: 如何将JS源文件(test.JS有两个函数,funcA()和funcB())转换为字节码 如何将生成的字节码加载到duktape并调用其中一个函数,比如funcA() 谢谢 test.js: function funcA() { print("funcA()"); } function funcB() { print("funcB()"); } main.cpp int main() { duk_context* ctx = du

我想知道下面描述的步骤是如何完成的:

  • 如何将JS源文件(test.JS有两个函数,funcA()和funcB())转换为字节码
  • 如何将生成的字节码加载到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;
    }
    
    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); } // 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 // 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);