tvcutsem/harmony-reflect

Can't trap invoke for all methods of a given proxy

angus-c opened this issue · 2 comments

I suspect this is because the get trap is overriding the apply trap because the method is accessed before it is invoked. But wanted to check it's not due to my own bad code. Thanks!...

require('harmony-reflect');
function getApplyProxy(fn) {
  console.log(fn); //logged as expected
  //get trap also required?...
  return Proxy(
    fn,
    { apply: function() {
       console.log(arguments)
    }}
  )
}

var fnMonitor = Proxy(
  {},
  { get: function(t,p) {
    return (typeof t[p] == 'function' ? getApplyProxy(t[p]) : t[p]);
  }}
);

var Obj = function() {};
Obj.prototype = fnMonitor;

var a = new Obj;
a.fn = function() {};
a.fn(); //undefined(!)

You get undefined because a.fn in the last line of code will not trigger the fnMonitor proxy's get trap, but instead it will just retrieve the property assigned to it on the previous line and execute that function.

If you make an object (call it the "child") inherit from a proxy, like you did here with a, then the proxy's "get" and "set" traps only get invoked for properties that the child object does not define itself.

Think of method lookup as starting at the child. If the child defines the property, it is returned immediately. If the child does not define it, lookup continues in the child's prototype. When this prototype chain traversal hits a proxy, the proxy's "get" trap is called.

So, your fnMonitor trick would work fine for catching all non-existent property accesses on a (like __noSuchMethod__ in Spidermonkey) but it doesn't work for intercepting existing properties.

got it - thanks for clarifying

On Mon, Oct 21, 2013 at 1:34 PM, Tom Van Cutsem notifications@github.comwrote:

You get undefined because a.fn in the last line of code will _not_trigger the
fnMonitor proxy's get trap, but instead it will just retrieve the
property assigned to it on the previous line and execute that function.

If you make an object (call it the "child") inherit from a proxy, like you
did here with a, then the proxy's "get" and "set" traps only get invoked
for properties that the child object does not define itself.

Think of method lookup as starting at the child. If the child defines the
property, it is returned immediately. If the child does not define it,
lookup continues in the child's prototype. When this prototype chain
traversal hits a proxy, the proxy's "get" trap is called.

So, your fnMonitor trick would work fine for catching all non-existent
property accesses on a (like noSuchMethod in Spidermonkey) but it
doesn't work for intercepting existing properties.


Reply to this email directly or view it on GitHubhttps://github.com//issues/22#issuecomment-26753680
.