asmblah / uniter

🎉 PHP in the browser and Node.js => Docs: https://phptojs.com/
https://asmblah.github.io/uniter/
Other
446 stars 42 forks source link

runtime.pausable is undefined #31

Closed IngwiePhoenix closed 8 years ago

IngwiePhoenix commented 8 years ago

So, I basically have the prototype of my plugin done.

However, there is an issue I do not quite comprehend...

/Users/Ingwie/Work/uniter/uniter-webpack/testcase/out/bundle.js:4438
                    pausable = runtime.pausable,
                                      ^

TypeError: Cannot read property 'pausable' of undefined
    at _.extend.compile (/Users/Ingwie/Work/uniter/uniter-webpack/testcase/out/bundle.js:4438:36)
    at Object.<anonymous> (/Users/Ingwie/Work/uniter/uniter-webpack/testcase/out/bundle.js:51:16)
    at __webpack_require__ (/Users/Ingwie/Work/uniter/uniter-webpack/testcase/out/bundle.js:20:30)
    at /Users/Ingwie/Work/uniter/uniter-webpack/testcase/out/bundle.js:40:18
    at Object.<anonymous> (/Users/Ingwie/Work/uniter/uniter-webpack/testcase/out/bundle.js:43:10)
    at Module._compile (module.js:398:26)
    at Object.Module._extensions..js (module.js:405:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:430:10)

That maps to:

    _.extend(Runtime.prototype, {
        compile: function (wrapper) {
            var runtime = this,
                pausable = runtime.pausable, // <---- This line.
                phpCommon = runtime.phpCommon;

            return function (options, environment) {

Which is phpcore/src/Runtime.js.

Now, this is the code that bootstraps phpruntime:

var phpRuntime = require("phpruntime/sync");
var phpEnv = phpRuntime.createEnvironment();
var _ = require("microdash");

// Set up defaults...
var stdout = phpEnv.getStdout();
var stderr = phpEnv.getStderr();

// # I/O for console. STDIN is unused by default.
stdout.on("data",function(str){
    console.log(str);
});
stderr.on("data",function(str){
    console.error(str);
});

// Simply add some options.
function makeOptions(userOpt) {
    var baseOpt = phpEnv.getOptions();
    var targetObj = _.extend({}, baseOpt, userOpt);
    return targetObj;
}

module.exports = {
    makeOptions: makeOptions,
    getEnvironment: function(){ return phpEnv; }
};

And this is the actual "executor":

/* 0 */
/***/ function(module, exports, __webpack_require__) {

        // Imports
        var compile = __webpack_require__(/* phpruntime/sync */1).compile;
        var $ENV = __webpack_require__(/* lib/Runtime.js */87); // This is the script from above!
        // Build the context
        var makeCtx = compile(function(stdin, stdout, stderr, tools, namespace) {
            var namespaceScope = tools.createNamespaceScope(namespace),
                namespaceResult, scope = tools.globalScope,
                currentClass = null;
            stdout.write(tools.valueFactory.createString("Hello, world!").coerceToString().getNative());
            tools.valueFactory.coerce(__webpack_require__(/* demo2.php */88));
            return tools.valueFactory.createNull();
        });

        var options = $ENV.makeOptions({
            path: "<internal: " + module.id + ">"
        });

        var ctx = makeCtx(options, $ENV.getEnvironment());
        // Expose the exporter object
        // If the underlying code would assign a primitive, we can\'t assign properties to it.
        // So we make an abstraction!
        var exp1 = {},
            exp2;
        ctx.expose(exp1, "exports");
        exp2 = new Object(exp2);
        // Run and return.
        var rt = ctx.execute();
        Object.defineProperty(exp2, "__phpReturn", {
            value: rt,
            variable: false
        });
        Object.defineProperty(exp2, "__phpExports", {
            value: exp1,
            variable: false
        });
        module.exports = exp2;

/***/ },

Did I miss something, maybe? o.o

asmblah commented 8 years ago

Hi @IngwiePhoenix, I'm on my phone at the moment so I can't check but it looks like the problem is where you copy a reference to the .compile() method from the runtime (var compile = ...) - there's a few ways to fix but the easiest would be to instead store the runtime instance in a var and call it as runtime.compile(...) rather than compile(...). Eg 'var runtime = __webpack_require(1);' ... 'var makeCtx = runtime.compile(...);'

IngwiePhoenix commented 8 years ago

Yeah, that was indeed the issue... xD

And once you pointed it out, i facedesked.

Grabbing a reference to a function makes it lose its context. So either i would've used .apply/.call or statically bind using .bind... So I just decided to use your idea, and problem solved :) It works now.

Im waiting for @sokra to answer a few questions in webpack, and then i can code the remaining parts. ^.^

Thanks for the reply!