tvcutsem / harmony-reflect

ES5 shim for ES6 Reflect and Proxy objects
http://www.ecma-international.org/ecma-262/6.0/#sec-reflection
Other
478 stars 48 forks source link

Extending proxy classes #60

Closed thetutlage closed 9 years ago

thetutlage commented 9 years ago

I am in a situation where i want to proxy a base class ( not it's instance ) and let other classes extend that base class and call magical static methods.


var handler = {
  get: function(target,name){
    if(target[name]){
      return target[name]
    }else{
      // call some magic method
      return 'foo'
    }
  },
}

class Model{

}

var proxyModel  = new Proxy(Model,handler)

class User extends proxyModel{

}

But it fails saying 17270 segmentation fault iojs --harmony_proxies test/poly.js

tvcutsem commented 9 years ago

This looks like a bug in the V8 engine. I can reproduce using the following simpler test-case. Note that I'm using the old, raw Proxy API and not even including harmony-reflect, so the error cannot be introduced via this library:

"use strict";
class Model{}
var proxyModel = Proxy.createFunction({}, Model, Model);
class User extends proxyModel {}

Using iojs 3.3.0 on Mac OS X I get:

iojs --harmony_proxies test.js
Segmentation fault: 11

Care to file this against V8 directly?

Meanwhile, if you're in control of class User, you can get around the issue by rewriting User as a function rather than a class declaration (or have a tool like BabelJS do it for you).

marshall007 commented 9 years ago

@tvcutsem I think I'm running into a related issue. If you try to proxy a function that has its __proto__ modified, the prototype of the object you're proxying is not preserved. Here's an example:

function Term () {
  var term = function(field) {
    return term.bracket(field);
  }

  term.__proto__ = this.__proto__;

  var proxy = new Proxy(term, {
    get: function (target, prop, receiver) {
      if (target[prop] !== undefined) {
        return Reflect.get(target, prop, receiver);
      }
      return target(prop);
    }
  });

  // typeof term === Term
  // typeof proxy === Function

  return proxy;
}

Term.prototype.bracket = function () {
  // ...
}
marshall007 commented 9 years ago

I think on this line we need to also look at the prototype of target to determine whether we should use Proxy.createFunction or not (i.e. Object.getPrototypeOf(target) === Function.prototype might be a better check).