SlideShare a Scribd company logo
1 of 88
Download to read offline
Proxies
                              are Awesome!
                                    Brendan Eich
                          (w/ Mark Miller & Tom Van Cutsem)




Tuesday, September 28, 2010
ECMAScript 5 (ES5)



Tuesday, September 28, 2010
ES5 Review
           • Array extras
           • JSON (based on json2.js)
           • Strict Mode (“use strict”)
           • Object meta-programming API
            • accessor properties (getters & setters)
            • mutability and enumerability controls
            • “javascript.lang.reflect”
           • In Firefox 4, IE9 (w/o strict?), WebKit nightlies
Tuesday, September 28, 2010
ES5 Property Descriptors
  • Data vs. accessor properties
  • Property attributes
      var point =
        { x: 5,
          y: 8,
          get r() { return Math.sqrt(this.x*this.x + this.y*this.y); } };
      Object.getOwnPropertyDescriptor(point, ‘x’);
          { value: 5,
            writable: true,
            enumerable: true,
            configurable: true }

      Object.getOwnPropertyDescriptor(point, ‘r’);
          { get: function () { return Math.sqrt(this.x*this.x + ...); },
            set: undefined,
            enumerable: true,
            configurable: true }
Tuesday, September 28, 2010
Property Descriptor Maps
  var point =
    { x: 5,
      y: 8,
      get r() { return Math.sqrt(this.x*this.x + this.y*this.y); } };


  Object.defineProperty(point, ‘z’, {
    value: 0,
    enumerable: true,
    writable: false,
    configurable: false });



  var point = Object.create(
    Object.prototype,
    { x: { value: 5, ... }, y: { value: 8, ... },
      r: { get: function() {...}, enumerable: true, ... },
      z: { value: 0, enumerable: true, ... } });




Tuesday, September 28, 2010
Property Descriptor Maps
  var point =
    { x: 5,
      y: 8,
      get r() { return Math.sqrt(this.x*this.x + this.y*this.y); } };


  Object.defineProperty(point, ‘z’, {
    value: 0,
    enumerable: true,
    writable: false,                                  name   pd
    configurable: false });                             x    {...}
                                                        y    {...}
                                                        r    {...}
  var point = Object.create(                             z   {...}
    Object.prototype,
    { x: { value: 5, ... }, y: { value: 8, ... },
      r: { get: function() {...}, enumerable: true, ... },
      z: { value: 0, enumerable: true, ... } });




Tuesday, September 28, 2010
Tamper-proofing Objects
          var point =
            { x: 5,
              y: 8,
              get r() { return Math.sqrt(this.x*this.x + this.y*this.y); } };




          Object.preventExtensions(point);
          point.z = 0; // can’t add new properties



          Object.seal(point);
          delete point.x; // can’t delete properties


          Object.freeze(point);
          point.x = 7; // can’t assign properties




Tuesday, September 28, 2010
ES-Harmony Proxies



Tuesday, September 28, 2010
Dynamic Proxies

         •    Generic handling of property access:

             •     Generic wrappers: security, aspects, logging, profiling, ...

             •     Stratified form of SpiderMonkey’s __noSuchMethod__
                   js> o = {__noSuchMethod__: function (id, args) { print(id, args); }}

                   ({__noSuchMethod__:(function (id, args) {print(id, args);})})

                   js> o.m(1,2,3)

                   m 1,2,3


         •    Generic handling of other operations applicable to objects:

             •     Virtual objects: persistent objects, remote objects, ...

             •     Emulate the dreaded “host objects”

Tuesday, September 28, 2010
Example w/ just ES5: logging
   function makePoint(x, y) {
     return {
        x: x,
        y: y,
        ...
     };
   }




Tuesday, September 28, 2010
Example w/ just ES5: logging
   function makePoint(x, y) {
     return {
        x: x,
        y: y,
        ...
     };
   }
  function makeLoggedPoint(p) {
    return {
       get x() {
          log(‘get’,‘x’,p); return p.x;
       },
       set x(v) {
          log(‘set’,‘x’,p,v); p.x = v;
       },
       // get y, set y, ...
    };
  }
  var lp = makeLoggedPoint(makePoint(1,2));
Tuesday, September 28, 2010
Example w/ just ES5: logging
   function makePoint(x, y) {
     return {
        x: x,
        y: y,
        ...
     };
   }
  function makeLoggedPoint(p) {
    return {                              Too ad hoc. What about:
       get x() {                           • logging other data types
       },
          log(‘get’,‘x’,p); return p.x;
                                           • profiling, persistence,
       set x(v) {                          access control, ...
          log(‘set’,‘x’,p,v); p.x = v;
       },
       // get y, set y, ...
    };
  }
  var lp = makeLoggedPoint(makePoint(1,2));
Tuesday, September 28, 2010
Logging: static ES5 “proxies”
function makeLogger(obj) {
  var proxy = Object.create(Object.getProtoypeOf(obj), {});
  Object.getOwnPropertyNames(obj).forEach(function(name) {
    var pd = Object.getOwnPropertyDescriptor(obj, name);
    Object.defineProperty(proxy, name, {
      get: function() {
         log(‘get’, name, obj);
         return obj[name];
      },
      set: function(v) {
         log(‘set’, name, obj, v);
         obj[name] = v;
      },
      // copy attributes from pd
    });
  });
  return proxy;
}


Tuesday, September 28, 2010
Logging: static ES5 “proxies”
function makeLogger(obj) {
  var proxy = Object.create(Object.getProtoypeOf(obj), {});
  Object.getOwnPropertyNames(obj).forEach(function(name) {
    var pd = Object.getOwnPropertyDescriptor(obj, name);
    Object.defineProperty(proxy, name, {
      get: function() {
         log(‘get’, name, obj);

      },
         return obj[name];
                                    • proxy doesn’t reflect
      set: function(v) {            structural changes made to ‘obj’
         log(‘set’, name, obj, v);
         obj[name] = v;
                                    • structural changes made to
      },
                                    proxy are not reflected in ‘obj’
      // copy attributes from pd    • structural changes:
    });
  });
                                      • add/delete properties
  return proxy;                       • change property attributes
}


Tuesday, September 28, 2010
Logging: dynamic (harmony) proxies
   function makeLogger(obj) {
     var proxy = Proxy.create({
       get: function(rcvr, name) {
          log(‘get’, name, obj);
          return obj[name];
       },
       set: function(rcvr, name, val) {
          log(‘set’, name, obj, val);
          obj[name] = val;
          return true;
       },
       ...
     }, Object.getPrototypeOf(obj));
     return proxy;
   }




Tuesday, September 28, 2010
Logging: dynamic (harmony) proxies
   function makeLogger(obj) {
     var proxy = Proxy.create({
       get: function(rcvr, name) {
          log(‘get’, name, obj);                         handler
          return obj[name];
       },
       set: function(rcvr, name, val) {                            meta
          log(‘set’, name, obj, val);
                                          base
          obj[name] = val;
          return true;
       },
       ...                                       proxy
     }, Object.getPrototypeOf(obj));
     return proxy;
   }




Tuesday, September 28, 2010
Stratified API
            var proxy = Proxy.create(handler, proto);



                                                                handler


                                                                          meta
          base




                                                        proxy




Tuesday, September 28, 2010
Stratified API
            var proxy = Proxy.create(handler, proto);


            handler.get(proxy, ‘foo’)
                                                                handler


                                                                          meta
          base
                    proxy.foo



                                                        proxy




Tuesday, September 28, 2010
Stratified API
            var proxy = Proxy.create(handler, proto);


            handler.get(proxy, ‘foo’)
                                                                handler
            handler.set(proxy, ‘foo’, 42)



                                                                          meta
          base
                    proxy.foo
                    proxy.foo = 42

                                                        proxy




Tuesday, September 28, 2010
Stratified API
            var proxy = Proxy.create(handler, proto);


            handler.get(proxy, ‘foo’)
                                                                handler
            handler.set(proxy, ‘foo’, 42)

            handler.get(proxy, ‘foo’).apply(proxy,[1,2,3])

                                                                          meta
          base
                    proxy.foo
                    proxy.foo = 42
                    proxy.foo(1,2,3)                    proxy




Tuesday, September 28, 2010
Stratified API
            var proxy = Proxy.create(handler, proto);


            handler.get(proxy, ‘foo’)
                                                                handler
            handler.set(proxy, ‘foo’, 42)

            handler.get(proxy, ‘foo’).apply(proxy,[1,2,3])

            handler.get(proxy, ‘get’)                                     meta
          base
                    proxy.foo
                    proxy.foo = 42
                    proxy.foo(1,2,3)                    proxy
                    proxy.get




Tuesday, September 28, 2010
Stratified API
            var proxy = Proxy.create(handler, proto);


            handler.get(proxy, ‘foo’)
                                                                handler
            handler.set(proxy, ‘foo’, 42)

            handler.get(proxy, ‘foo’).apply(proxy,[1,2,3])

            handler.get(proxy, ‘get’)                                     meta
          base
                    proxy.foo
                    proxy.foo = 42
                    proxy.foo(1,2,3)                    proxy         proto
                    proxy.get




Tuesday, September 28, 2010
Not just property accesses
            var proxy = Proxy.create(handler, proto);




                                                                handler



                                                                          meta
          base




                                                        proxy




Tuesday, September 28, 2010
Not just property accesses
            var proxy = Proxy.create(handler, proto);

              handler.has(‘foo’)



                                                                handler



                                                                          meta
          base

              ‘foo’ in proxy

                                                        proxy




Tuesday, September 28, 2010
Not just property accesses
            var proxy = Proxy.create(handler, proto);

              handler.has(‘foo’)

              handler.delete(‘foo’)

                                                                handler



                                                                          meta
          base

              ‘foo’ in proxy

              delete proxy.foo                          proxy




Tuesday, September 28, 2010
Not just property accesses
            var proxy = Proxy.create(handler, proto);

              handler.has(‘foo’)

              handler.delete(‘foo’)
              var props = handler.enumerate();
                                                                handler
              for (var i=0;i<props.length;i++) {
                var prop = props[i]; ...
              }
                                                                          meta
          base

              ‘foo’ in proxy

              delete proxy.foo                          proxy
              for (var prop in proxy) { ... }




Tuesday, September 28, 2010
Not just property accesses
            var proxy = Proxy.create(handler, proto);

              handler.has(‘foo’)

              handler.delete(‘foo’)
              var props = handler.enumerate();
                                                                handler
              for (var i=0;i<props.length;i++) {
                var prop = props[i]; ...
              }
              handler.defineProperty(‘foo’, pd)                           meta
          base

              ‘foo’ in proxy

              delete proxy.foo                          proxy
              for (var prop in proxy) { ... }

              Object.defineProperty(proxy,‘foo’, pd)


Tuesday, September 28, 2010
But not quite everything, either
            var proxy = Proxy.create(handler, proto);




                                                                handler



                                                                          meta
          base




                                                        proxy




Tuesday, September 28, 2010
But not quite everything, either
            var proxy = Proxy.create(handler, proto);




                                                                handler



                                                                          meta
          base

              proxy === obj

                                                        proxy




Tuesday, September 28, 2010
But not quite everything, either
            var proxy = Proxy.create(handler, proto);




                                                                handler



                                                                          meta
          base

              proxy === obj

              Object.getPrototypeOf(proxy) => proto     proxy         proto




Tuesday, September 28, 2010
But not quite everything, either
            var proxy = Proxy.create(handler, proto);




                                                                handler



                                                                          meta
          base

              proxy === obj

              Object.getPrototypeOf(proxy) => proto     proxy         proto
              proxy instanceof SomeFunction




Tuesday, September 28, 2010
But not quite everything, either
            var proxy = Proxy.create(handler, proto);




                                                                handler



                                                                          meta
          base

              proxy === obj

              Object.getPrototypeOf(proxy) => proto     proxy         proto
              proxy instanceof SomeFunction

              typeof proxy => “object”


Tuesday, September 28, 2010
Full Handler API
                                                            handler


                                proxy

Object.getOwnPropertyDescriptor(proxy)              handler.getOwnPropertyDescriptor(name)
     Object.getPropertyDescriptor(proxy)            handler.getPropertyDescriptor(name)
    Object.defineProperty(proxy,name,pd)            handler.defineProperty(name, pd)
        Object.getOwnPropertyNames(proxy)  handler.getOwnPropertyNames()
                                delete proxy.name   handler.delete(name) 
                  for (name in proxy) { ... }  handler.enumerate()
           Object.{freeze|seal|...}(proxy)          handler.fix()
                                    name in proxy   handler.has(name)
  ({}).hasOwnProperty.call(proxy, name)             handler.hasOwn(name)
                                    receiver.name   handler.get(receiver, name)
                              receiver.name = val   handler.set(receiver, name, val)
                               Object.keys(proxy)   handler.keys()
                  for (name in proxy) { ... }       handler.iterate()

Tuesday, September 28, 2010
Fundamental vs Derived Traps
                                                         handler


                              proxy

                                               Fundamental traps
     Object.getOwnPropertyDescriptor(proxy)    handler.getOwnPropertyDescriptor(name)
        Object.getPropertyDescriptor(proxy)    handler.getPropertyDescriptor(name)
       Object.defineProperty(proxy,name,pd)    handler.defineProperty(name, pd)
          Object.getOwnPropertyNames(proxy)    handler.getOwnPropertyNames()
                          delete proxy.name    handler.delete(name) 
                for (name in proxy) { ... }    handler.enumerate() -> [string]
            Object.{freeze|seal|...}(proxy)    handler.fix()




                                               Derived traps
                              name in proxy    handler.has(name)
      ({}).hasOwnProperty.call(proxy, name)    handler.hasOwn(name)
                              receiver.name    handler.get(receiver, name)
                        receiver.name = val    handler.set(receiver, name, val)
                         Object.keys(proxy)    handler.keys()
                for (name in proxy) { ... }    handler.iterate() -> iterator




Tuesday, September 28, 2010
Function Proxies
        JavaScript functions are objects. Additionally,
        they are also callable and constructible
     var call = function() { ... };
     var construct = function() { ... };
     var funproxy = Proxy.createFunction(handler, call, construct);

                                                 handler
                                                           call construct




                                                    funproxy



Tuesday, September 28, 2010
Function Proxies
        JavaScript functions are objects. Additionally,
        they are also callable and constructible
     var call = function() { ... };
     var construct = function() { ... };
     var funproxy = Proxy.createFunction(handler, call, construct);

                  call(1,2,3)                    handler
                                                           call construct



                  funproxy(1,2,3)


                                                    funproxy



Tuesday, September 28, 2010
Function Proxies
        JavaScript functions are objects. Additionally,
        they are also callable and constructible
     var call = function() { ... };
     var construct = function() { ... };
     var funproxy = Proxy.createFunction(handler, call, construct);

                  call(1,2,3)                    handler
                                                           call construct
                  construct(1,2,3)




                  funproxy(1,2,3)

                  new funproxy(1,2,3)
                                                    funproxy



Tuesday, September 28, 2010
Function Proxies
        JavaScript functions are objects. Additionally,
        they are also callable and constructible
     var call = function() { ... };
     var construct = function() { ... };
     var funproxy = Proxy.createFunction(handler, call, construct);

                  call(1,2,3)                         handler
                                                                call construct
                  construct(1,2,3)
                  handler.get(funproxy,‘prototype’)


                  funproxy(1,2,3)

                  new funproxy(1,2,3)

                  funproxy.prototype                     funproxy



Tuesday, September 28, 2010
Function Proxies
        JavaScript functions are objects. Additionally,
        they are also callable and constructible
     var call = function() { ... };
     var construct = function() { ... };
     var funproxy = Proxy.createFunction(handler, call, construct);

                  call(1,2,3)                         handler
                                                                call construct
                  construct(1,2,3)
                  handler.get(funproxy,‘prototype’)


                  funproxy(1,2,3)

                  new funproxy(1,2,3)

                  funproxy.prototype                     funproxy
                  typeof funproxy => “function”


Tuesday, September 28, 2010
Function Proxies
        JavaScript functions are objects. Additionally,
        they are also callable and constructible
     var call = function() { ... };
     var construct = function() { ... };
     var funproxy = Proxy.createFunction(handler, call, construct);

                  call(1,2,3)                          handler
                                                                 call construct
                  construct(1,2,3)
                  handler.get(funproxy,‘prototype’)


                  funproxy(1,2,3)

                  new funproxy(1,2,3)

                  funproxy.prototype                      funproxy
                  typeof funproxy => “function”
                  Object.getPrototypeOf(funproxy) => Function.prototype
Tuesday, September 28, 2010
Dilemma: Invoke vs Get+Call
               • Fundamental vs derived traps = tradeoff in
                     performance (method allocation or caching)
                     vs. consistency
                              var p = Proxy.create({
                                get:    function(receiver, name) { ... },
                                invoke: function(receiver, name, args) { ... },
                                ...
                              });

                              p.x;      // get(p,'x')
                              p.m(a);   // invoke(p, 'm', [a])


               • invoke can intercept arguments
               • but notably, JS methods can be extracted as
                     functions and called later (functional FTW!)
               • breaks invariant o.m.call(o) <=> o.m()
Tuesday, September 28, 2010
Selective Interception




                                                       meta
                 base




                                   object




Tuesday, September 28, 2010
Selective Interception

                   VM territory (C++)



                                                             meta
                 base




                                   object

                                            JavaScript territory


Tuesday, September 28, 2010
Selective Interception

                   VM territory (C++)
                                      VM handler


                                                                    meta
                 base




                                   object

                                                   JavaScript territory


Tuesday, September 28, 2010
Selective Interception

                   VM territory (C++)
                              VM handler   VM handler


                                                                         meta
                 base




                 host object           object

                                                        JavaScript territory


Tuesday, September 28, 2010
Selective Interception

                   VM territory (C++)
                              VM handler   VM handler              handler


                                                                             meta
                 base




                 host object           object              proxy

                                                        JavaScript territory


Tuesday, September 28, 2010
Selective Interception

                   VM territory (C++)
                              VM handler   VM handler              handler


                                                                             meta
                 base




                 host object           object              proxy

                                                        JavaScript territory


Tuesday, September 28, 2010
Selective Interception

                   VM territory (C++)                      Self-hosted
                              VM handler   VM handler              handler


                                                                             meta
                 base




                 host object           object              proxy

                                                        JavaScript territory


Tuesday, September 28, 2010
Selective Interception

                   VM territory (C++)                      Self-hosted
                              VM handler   VM handler              handler


                                                                             meta
                 base




                 host object           object              proxy

                                                        JavaScript territory


Tuesday, September 28, 2010
Example: no-op forwarding proxy
                                                     handler

    function ForwardingHandler(obj) {
      this.target = obj;                           proxy    target
    }
    ForwardingHandler.prototype = {
      has: function(name) { return name in this.target; },
      get: function(rcvr,name) { return this.target[name]; },
      set: function(rcvr,name,val) { this.target[name]=val;return true; },
      delete: function(name) { return delete this.target[name]; }
      enumerate: function() {
        var props = [];
         for (name in this.target) { props.push(name); };
         return props;
      },
      ...
    }

    var proxy = Proxy.create(new ForwardingHandler(o),
                             Object.getPrototypeOf(o));
Tuesday, September 28, 2010
Example: counting property access
            function makeSimpleProfiler(target) {
              var forwarder = new ForwardingHandler(target);
              var count = Object.create(null);
              forwarder.get = function(rcvr, name) {
                 count[name] = (count[name] || 0) + 1;
                 return this.target[name];
              };
              return {
                 proxy: Proxy.create(forwarder,
                                     Object.getPrototypeOf(target)),
                 get stats() { return count; }
              }
            }




Tuesday, September 28, 2010
Example: counting property access
            function makeSimpleProfiler(target) {
              var forwarder = new ForwardingHandler(target);
              var count = Object.create(null);
              forwarder.get = function(rcvr, name) {
                 count[name] = (count[name] || 0) + 1;
                 return this.target[name];
              };
              return {
                 proxy: Proxy.create(forwarder,
                                     Object.getPrototypeOf(target)),
                 get stats() { return count; }
              }
            }

            var subject = { ... };
            var profiler = makeSimpleProfiler(subject);
            runApp(profiler.proxy);
            display(profiler.stats);

Tuesday, September 28, 2010
Fixing a Proxy
            var proxy = Proxy.create(handler, proto);



                                                                handler


                                                                          meta
          base




                                                        proxy




Tuesday, September 28, 2010
Fixing a Proxy
            var proxy = Proxy.create(handler, proto);



                                                                handler


                                                                          meta
          base

           Object.freeze(proxy)

           Object.seal(proxy)
                                                        proxy
           Object.preventExtensions(proxy)




Tuesday, September 28, 2010
Fixing a Proxy
            var proxy = Proxy.create(handler, proto);


           var pdmap = handler.fix();
           if (pdmap === undefined) throw TypeError();           handler
           become(proxy,
                  Object.freeze(
                     Object.create(proto, pdmap)));
                                                                           meta
          base

           Object.freeze(proxy)

           Object.seal(proxy)
                                                         proxy
           Object.preventExtensions(proxy)




Tuesday, September 28, 2010
Fixing a Proxy
            var proxy = Proxy.create(handler, proto);


           var pdmap = handler.fix();
           if (pdmap === undefined) throw TypeError();           handler
           become(proxy,
                  Object.freeze(
                     Object.create(proto, pdmap)));
                                                                           meta
          base

           Object.freeze(proxy)

           Object.seal(proxy)
                                                         proxy
           Object.preventExtensions(proxy)




                                         fix
                              Trapping          Fixed
Tuesday, September 28, 2010
Fixing a Proxy
            var proxy = Proxy.create(handler, proto);


           var pdmap = handler.fix();
           if (pdmap === undefined) throw TypeError();
           become(proxy,
                  Object.freeze(
                     Object.create(proto, pdmap)));
                                                                 meta
          base

           Object.freeze(proxy)

           Object.seal(proxy)
                                                         proxy
           Object.preventExtensions(proxy)




                                         fix
                              Trapping          Fixed
Tuesday, September 28, 2010
Meta-level Shifting
                                                        handler


                              proxy
    Object.getOwnPropertyDescriptor(proxy)    handler.getOwnPropertyDescriptor(name)
       Object.getPropertyDescriptor(proxy)    handler.getPropertyDescriptor(name)
      Object.defineProperty(proxy,name,pd)    handler.defineProperty(name, pd)
         Object.getOwnPropertyNames(proxy)    handler.getOwnPropertyNames()
                         delete proxy.name    handler.delete(name) 
               for (name in proxy) { ... }    handler.enumerate()
           Object.{freeze|seal|...}(proxy)    handler.fix()
                             name in proxy    handler.has(name)
     ({}).hasOwnProperty.call(proxy, name)    handler.hasOwn(name)
                             receiver.name    handler.get(receiver, name)
                       receiver.name = val    handler.set(receiver, name, val)
                        Object.keys(proxy)    handler.keys()
               for (name in proxy) { ... }    handler.iterate()


        base-level: many operations           meta-level: all operations reified as
                on objects                           invocations of traps


Tuesday, September 28, 2010
Meta-level Shifting
 a proxy whose                                           μhandler

handler is a proxy
                              handler


     handler.getOwnPropertyDescriptor(name)   μhandler.get(handler,   ‘getOwnP..’)(name)
     handler.getPropertyDescriptor(name)      μhandler.get(handler,   ‘getProp..’)(name)
     handler.defineOwnProperty(name, pd)      μhandler.get(handler,   ‘define...’)(name,pd)
     handler.delete(name)                     μhandler.get(handler,   ‘delete’)(name)
     handler.getOwnPropertyNames()            μhandler.get(handler,   ‘getOwnP..’)()
     handler.enumerate()                      μhandler.get(handler,   ‘enumerate’)()
     handler.fix()                            μhandler.get(handler,   ‘fix’)()
     handler.has(name)                        μhandler.get(handler,   ‘has’)(name)
     handler.hasOwn(name)                     μhandler.get(handler,   ‘hasOwn’)(name)
     handler.get(receiver, name)              μhandler.get(handler,   ‘get’)(receiver,name)
     handler.set(receiver, name, val)         μhandler.get(handler,   ‘set’)(receiver,name,val)
     handler.keys()                           μhandler.get(handler,   ‘keys’)()
     handler.iterate()                        μhandler.get(handler,   ‘iterate’)()

   meta-level: all operations reified as           meta-meta-level: all operations
          invocations of traps                   reified as invocations of ‘get’ trap


Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          • Firefox security wrappers (anti-XSS, XUL, etc.)
          • Google Caja: capability-secure subset
          • Object-capability model: an object is powerless
                unless given a reference to other objects
          • References can be made revocable through a
                membrane




Tuesday, September 28, 2010
Example: Membranes
          function makeSimpleMembrane(initTarget) {
            var enabled = true;




          }

Tuesday, September 28, 2010
Example: Membranes
          function makeSimpleMembrane(initTarget) {
            var enabled = true;




            return {
               wrapper: wrap(initTarget),
               revoke: function() { enabled = false; }
            };
          }

Tuesday, September 28, 2010
Example: Membranes
          function makeSimpleMembrane(initTarget) {
            var enabled = true;




            function wrap(target) {
              if (Object.isPrimitive(target)) { return target; }
              var baseHandler = new ForwardingHandler(target);
              var revokeHandler = Proxy.create({
                get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }
              });




            }
            return {
               wrapper: wrap(initTarget),
               revoke: function() { enabled = false; }
            };
          }

Tuesday, September 28, 2010
Example: Membranes
          function makeSimpleMembrane(initTarget) {
            var enabled = true;




            function wrap(target) {
              if (Object.isPrimitive(target)) { return target; }
              var baseHandler = new ForwardingHandler(target);
              var revokeHandler = Proxy.create({
                get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }
              });

              if (typeof target === “function”) {
                return Proxy.createFunction(revokeHandler, wrapFunction(target));
              }
              return Proxy.create(revokeHandler, wrap(Object.getPrototypeOf(target)));
            }
            return {
               wrapper: wrap(initTarget),
               revoke: function() { enabled = false; }
            };
          }

Tuesday, September 28, 2010
Example: Membranes
          function makeSimpleMembrane(initTarget) {
            var enabled = true;
            function wrapFunction(f) {
              return function() { // variable-argument function
                if (!enabled) { throw new Error("revoked"); }
               return wrap(f.apply(wrap(this), arguments.map(wrap)));
              }
            }
            function wrap(target) {
              if (Object.isPrimitive(target)) { return target; }
              var baseHandler = new ForwardingHandler(target);
              var revokeHandler = Proxy.create({
                get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }
              });

              if (typeof target === “function”) {
                return Proxy.createFunction(revokeHandler, wrapFunction(target));
              }
              return Proxy.create(revokeHandler, wrap(Object.getPrototypeOf(target)));
            }
            return {
               wrapper: wrap(initTarget),
               revoke: function() { enabled = false; }
            };
          }

Tuesday, September 28, 2010
Prior Work



                        handler


                                               meta
   base



              proxy




Tuesday, September 28, 2010
Prior Work



                        handler            mirror     ProxyHandler   InvocationHandler


                                                                                   meta
   base



              proxy               mirage            proxy      java.lang.reflect.Proxy




Tuesday, September 28, 2010
Prior Work



                        handler             mirror     ProxyHandler   InvocationHandler


                                                                                     meta
   base



              proxy                mirage            proxy       java.lang.reflect.Proxy

 # traps                      13             30              3               1

Tuesday, September 28, 2010
Making JavaScript Extensible


          • Extending JavaScript today: “Host objects”
                (the IE DOM; anything implemented in C++)
          • Proxies are sufficiently powerful to emulate most
                of the behavior of host objects in JavaScript itself
          • Two possible avenues to close the gap:
           • Make proxies even more powerful
           • Make host objects only as powerful as proxies
Tuesday, September 28, 2010
Status

         • Presented at ECMA TC-39 meetings
         • Approved for inclusion in ES-Harmony
         • http://wiki.ecmascript.org/doku.php?
              id=harmony:proxies
         • In Firefox 4 already, thanks to Andreas Gal!
          • The basis of all of Gecko’s security wrappers
          • Used by Zaphod (Narcissus as JS engine add-on,
                   source at http://github.com/taustin/Zaphod/)


Tuesday, September 28, 2010
Lessons for Web Standards
           • Standards need savvy academic research
           • Standards must evolve quickly on the Web
           • They can’t evolve without prototype trials
           • These experiments need tons of user-testing
           • To reach users at scale, prototypes must ship
           • Ecma TC39 committed to prototyping specs
                 before finalizing standards
           • Committee members work together, no
                 blind-siding, to uphold Harmony (it’s social!)

Tuesday, September 28, 2010
Micro-benchmark Results




Tuesday, September 28, 2010
Micro-benchmark: Overhead




Tuesday, September 28, 2010
Proxies: Summary

         •    Proxies enable:

             •     Generic wrappers: access control, profiling,
                   adaptors, test injection, etc.

             •     Virtual objects: persistent objects, remote objects,
                   emulated host objects, ...

         •    API:

             •     Robust: stratified, not all operations intercepted

             •     Secure: can’t trap non-proxy or fixed objects

             •     Performance: no overhead for non-proxy objects


Tuesday, September 28, 2010
Conclusions

               • ES5 provides new meta-programming APIs
               • ES-Harmony Proxies: robust dynamic meta-
                     programming for virtual objects, wrappers
               • Proxies help put developers in control of
                     extending JavaScript, instead of Ecma TC39
               • JavaScript: the Revenge of Smalltalk!


Tuesday, September 28, 2010

More Related Content

What's hot

Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해beom kyun choi
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8LivePerson
 
Spring boot
Spring bootSpring boot
Spring bootsdeeg
 
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slidesSpring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slidesHitesh-Java
 
Reactive programming
Reactive programmingReactive programming
Reactive programmingSUDIP GHOSH
 
Architecture java j2 ee a partager
Architecture java j2 ee a partagerArchitecture java j2 ee a partager
Architecture java j2 ee a partageraliagadir
 
Spring framework IOC and Dependency Injection
Spring framework  IOC and Dependency InjectionSpring framework  IOC and Dependency Injection
Spring framework IOC and Dependency InjectionAnuj Singh Rajput
 
Building a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring BootBuilding a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring BootOmri Spector
 
Using API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconUsing API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconAntonio Peric-Mazar
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring FrameworkDineesha Suraweera
 

What's hot (20)

Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Spring framework core
Spring framework coreSpring framework core
Spring framework core
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Grails Spring Boot
Grails Spring BootGrails Spring Boot
Grails Spring Boot
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 
Spring boot
Spring bootSpring boot
Spring boot
 
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slidesSpring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
 
Reactive programming
Reactive programmingReactive programming
Reactive programming
 
Flask Basics
Flask BasicsFlask Basics
Flask Basics
 
Spring AOP
Spring AOPSpring AOP
Spring AOP
 
Architecture java j2 ee a partager
Architecture java j2 ee a partagerArchitecture java j2 ee a partager
Architecture java j2 ee a partager
 
Introduction to spring boot
Introduction to spring bootIntroduction to spring boot
Introduction to spring boot
 
Rest in flask
Rest in flaskRest in flask
Rest in flask
 
Spring framework IOC and Dependency Injection
Spring framework  IOC and Dependency InjectionSpring framework  IOC and Dependency Injection
Spring framework IOC and Dependency Injection
 
Java Spring Framework
Java Spring FrameworkJava Spring Framework
Java Spring Framework
 
Building a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring BootBuilding a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring Boot
 
Using API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconUsing API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonycon
 
Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 

Similar to Proxies are Awesome!

HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScriptJulie Iskander
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
Bindings: the zen of montage
Bindings: the zen of montageBindings: the zen of montage
Bindings: the zen of montageKris Kowal
 
Get started with YUI
Get started with YUIGet started with YUI
Get started with YUIAdam Lu
 
JSConf: All You Can Leet
JSConf: All You Can LeetJSConf: All You Can Leet
JSConf: All You Can Leetjohndaviddalton
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascriptMiao Siyu
 
ekb.py - Python VS ...
ekb.py - Python VS ...ekb.py - Python VS ...
ekb.py - Python VS ...it-people
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design PatternsStefano Fago
 
Understanding JavaScript
Understanding JavaScriptUnderstanding JavaScript
Understanding JavaScriptnodejsbcn
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Juriy Zaytsev
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingIstanbul Tech Talks
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016Manoj Kumar
 
Javascript Basics
Javascript BasicsJavascript Basics
Javascript Basicsmsemenistyi
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 

Similar to Proxies are Awesome! (20)

HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
 
ECMAScript 5: Новое в JavaScript
ECMAScript 5: Новое в JavaScriptECMAScript 5: Новое в JavaScript
ECMAScript 5: Новое в JavaScript
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
Bindings: the zen of montage
Bindings: the zen of montageBindings: the zen of montage
Bindings: the zen of montage
 
Get started with YUI
Get started with YUIGet started with YUI
Get started with YUI
 
JSConf: All You Can Leet
JSConf: All You Can LeetJSConf: All You Can Leet
JSConf: All You Can Leet
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascript
 
ekb.py - Python VS ...
ekb.py - Python VS ...ekb.py - Python VS ...
ekb.py - Python VS ...
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design Patterns
 
Understanding JavaScript
Understanding JavaScriptUnderstanding JavaScript
Understanding JavaScript
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Say Hello To Ecmascript 5
Say Hello To Ecmascript 5
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function Programming
 
25-functions.ppt
25-functions.ppt25-functions.ppt
25-functions.ppt
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
Javascript Basics
Javascript BasicsJavascript Basics
Javascript Basics
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 

More from Brendan Eich

Always bet on JS - Finjs.io NYC 2016
Always bet on JS - Finjs.io NYC 2016Always bet on JS - Finjs.io NYC 2016
Always bet on JS - Finjs.io NYC 2016Brendan Eich
 
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScriptExtensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScriptBrendan Eich
 
The Same-Origin Saga
The Same-Origin SagaThe Same-Origin Saga
The Same-Origin SagaBrendan Eich
 
Value Objects, Full Throttle (to be updated for spring TC39 meetings)
Value Objects, Full Throttle (to be updated for spring TC39 meetings)Value Objects, Full Throttle (to be updated for spring TC39 meetings)
Value Objects, Full Throttle (to be updated for spring TC39 meetings)Brendan Eich
 
JS Responsibilities
JS ResponsibilitiesJS Responsibilities
JS ResponsibilitiesBrendan Eich
 
Value objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressValue objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressBrendan Eich
 
Mozilla Research Party Talk
Mozilla Research Party TalkMozilla Research Party Talk
Mozilla Research Party TalkBrendan Eich
 
Mozilla's NodeConf talk
Mozilla's NodeConf talkMozilla's NodeConf talk
Mozilla's NodeConf talkBrendan Eich
 

More from Brendan Eich (20)

Int64
Int64Int64
Int64
 
Always bet on JS - Finjs.io NYC 2016
Always bet on JS - Finjs.io NYC 2016Always bet on JS - Finjs.io NYC 2016
Always bet on JS - Finjs.io NYC 2016
 
dotJS 2015
dotJS 2015dotJS 2015
dotJS 2015
 
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScriptExtensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
 
Fluent15
Fluent15Fluent15
Fluent15
 
The Same-Origin Saga
The Same-Origin SagaThe Same-Origin Saga
The Same-Origin Saga
 
Taysom seminar
Taysom seminarTaysom seminar
Taysom seminar
 
Fluent14
Fluent14Fluent14
Fluent14
 
Value Objects, Full Throttle (to be updated for spring TC39 meetings)
Value Objects, Full Throttle (to be updated for spring TC39 meetings)Value Objects, Full Throttle (to be updated for spring TC39 meetings)
Value Objects, Full Throttle (to be updated for spring TC39 meetings)
 
My dotJS Talk
My dotJS TalkMy dotJS Talk
My dotJS Talk
 
Web futures
Web futuresWeb futures
Web futures
 
JS Responsibilities
JS ResponsibilitiesJS Responsibilities
JS Responsibilities
 
Value objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressValue objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progress
 
Mozilla Research Party Talk
Mozilla Research Party TalkMozilla Research Party Talk
Mozilla Research Party Talk
 
Splash
SplashSplash
Splash
 
JSLOL
JSLOLJSLOL
JSLOL
 
Capitol js
Capitol jsCapitol js
Capitol js
 
Paren free
Paren freeParen free
Paren free
 
Txjs talk
Txjs talkTxjs talk
Txjs talk
 
Mozilla's NodeConf talk
Mozilla's NodeConf talkMozilla's NodeConf talk
Mozilla's NodeConf talk
 

Recently uploaded

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 

Proxies are Awesome!

  • 1. Proxies are Awesome! Brendan Eich (w/ Mark Miller & Tom Van Cutsem) Tuesday, September 28, 2010
  • 2. ECMAScript 5 (ES5) Tuesday, September 28, 2010
  • 3. ES5 Review • Array extras • JSON (based on json2.js) • Strict Mode (“use strict”) • Object meta-programming API • accessor properties (getters & setters) • mutability and enumerability controls • “javascript.lang.reflect” • In Firefox 4, IE9 (w/o strict?), WebKit nightlies Tuesday, September 28, 2010
  • 4. ES5 Property Descriptors • Data vs. accessor properties • Property attributes var point = { x: 5, y: 8, get r() { return Math.sqrt(this.x*this.x + this.y*this.y); } }; Object.getOwnPropertyDescriptor(point, ‘x’); { value: 5, writable: true, enumerable: true, configurable: true } Object.getOwnPropertyDescriptor(point, ‘r’); { get: function () { return Math.sqrt(this.x*this.x + ...); }, set: undefined, enumerable: true, configurable: true } Tuesday, September 28, 2010
  • 5. Property Descriptor Maps var point = { x: 5, y: 8, get r() { return Math.sqrt(this.x*this.x + this.y*this.y); } }; Object.defineProperty(point, ‘z’, { value: 0, enumerable: true, writable: false, configurable: false }); var point = Object.create( Object.prototype, { x: { value: 5, ... }, y: { value: 8, ... }, r: { get: function() {...}, enumerable: true, ... }, z: { value: 0, enumerable: true, ... } }); Tuesday, September 28, 2010
  • 6. Property Descriptor Maps var point = { x: 5, y: 8, get r() { return Math.sqrt(this.x*this.x + this.y*this.y); } }; Object.defineProperty(point, ‘z’, { value: 0, enumerable: true, writable: false, name pd configurable: false }); x {...} y {...} r {...} var point = Object.create( z {...} Object.prototype, { x: { value: 5, ... }, y: { value: 8, ... }, r: { get: function() {...}, enumerable: true, ... }, z: { value: 0, enumerable: true, ... } }); Tuesday, September 28, 2010
  • 7. Tamper-proofing Objects var point = { x: 5, y: 8, get r() { return Math.sqrt(this.x*this.x + this.y*this.y); } }; Object.preventExtensions(point); point.z = 0; // can’t add new properties Object.seal(point); delete point.x; // can’t delete properties Object.freeze(point); point.x = 7; // can’t assign properties Tuesday, September 28, 2010
  • 9. Dynamic Proxies • Generic handling of property access: • Generic wrappers: security, aspects, logging, profiling, ... • Stratified form of SpiderMonkey’s __noSuchMethod__ js> o = {__noSuchMethod__: function (id, args) { print(id, args); }} ({__noSuchMethod__:(function (id, args) {print(id, args);})}) js> o.m(1,2,3) m 1,2,3 • Generic handling of other operations applicable to objects: • Virtual objects: persistent objects, remote objects, ... • Emulate the dreaded “host objects” Tuesday, September 28, 2010
  • 10. Example w/ just ES5: logging function makePoint(x, y) { return { x: x, y: y, ... }; } Tuesday, September 28, 2010
  • 11. Example w/ just ES5: logging function makePoint(x, y) { return { x: x, y: y, ... }; } function makeLoggedPoint(p) { return { get x() { log(‘get’,‘x’,p); return p.x; }, set x(v) { log(‘set’,‘x’,p,v); p.x = v; }, // get y, set y, ... }; } var lp = makeLoggedPoint(makePoint(1,2)); Tuesday, September 28, 2010
  • 12. Example w/ just ES5: logging function makePoint(x, y) { return { x: x, y: y, ... }; } function makeLoggedPoint(p) { return { Too ad hoc. What about: get x() { • logging other data types }, log(‘get’,‘x’,p); return p.x; • profiling, persistence, set x(v) { access control, ... log(‘set’,‘x’,p,v); p.x = v; }, // get y, set y, ... }; } var lp = makeLoggedPoint(makePoint(1,2)); Tuesday, September 28, 2010
  • 13. Logging: static ES5 “proxies” function makeLogger(obj) { var proxy = Object.create(Object.getProtoypeOf(obj), {}); Object.getOwnPropertyNames(obj).forEach(function(name) { var pd = Object.getOwnPropertyDescriptor(obj, name); Object.defineProperty(proxy, name, { get: function() { log(‘get’, name, obj); return obj[name]; }, set: function(v) { log(‘set’, name, obj, v); obj[name] = v; }, // copy attributes from pd }); }); return proxy; } Tuesday, September 28, 2010
  • 14. Logging: static ES5 “proxies” function makeLogger(obj) { var proxy = Object.create(Object.getProtoypeOf(obj), {}); Object.getOwnPropertyNames(obj).forEach(function(name) { var pd = Object.getOwnPropertyDescriptor(obj, name); Object.defineProperty(proxy, name, { get: function() { log(‘get’, name, obj); }, return obj[name]; • proxy doesn’t reflect set: function(v) { structural changes made to ‘obj’ log(‘set’, name, obj, v); obj[name] = v; • structural changes made to }, proxy are not reflected in ‘obj’ // copy attributes from pd • structural changes: }); }); • add/delete properties return proxy; • change property attributes } Tuesday, September 28, 2010
  • 15. Logging: dynamic (harmony) proxies function makeLogger(obj) { var proxy = Proxy.create({ get: function(rcvr, name) { log(‘get’, name, obj); return obj[name]; }, set: function(rcvr, name, val) { log(‘set’, name, obj, val); obj[name] = val; return true; }, ... }, Object.getPrototypeOf(obj)); return proxy; } Tuesday, September 28, 2010
  • 16. Logging: dynamic (harmony) proxies function makeLogger(obj) { var proxy = Proxy.create({ get: function(rcvr, name) { log(‘get’, name, obj); handler return obj[name]; }, set: function(rcvr, name, val) { meta log(‘set’, name, obj, val); base obj[name] = val; return true; }, ... proxy }, Object.getPrototypeOf(obj)); return proxy; } Tuesday, September 28, 2010
  • 17. Stratified API var proxy = Proxy.create(handler, proto); handler meta base proxy Tuesday, September 28, 2010
  • 18. Stratified API var proxy = Proxy.create(handler, proto); handler.get(proxy, ‘foo’) handler meta base proxy.foo proxy Tuesday, September 28, 2010
  • 19. Stratified API var proxy = Proxy.create(handler, proto); handler.get(proxy, ‘foo’) handler handler.set(proxy, ‘foo’, 42) meta base proxy.foo proxy.foo = 42 proxy Tuesday, September 28, 2010
  • 20. Stratified API var proxy = Proxy.create(handler, proto); handler.get(proxy, ‘foo’) handler handler.set(proxy, ‘foo’, 42) handler.get(proxy, ‘foo’).apply(proxy,[1,2,3]) meta base proxy.foo proxy.foo = 42 proxy.foo(1,2,3) proxy Tuesday, September 28, 2010
  • 21. Stratified API var proxy = Proxy.create(handler, proto); handler.get(proxy, ‘foo’) handler handler.set(proxy, ‘foo’, 42) handler.get(proxy, ‘foo’).apply(proxy,[1,2,3]) handler.get(proxy, ‘get’) meta base proxy.foo proxy.foo = 42 proxy.foo(1,2,3) proxy proxy.get Tuesday, September 28, 2010
  • 22. Stratified API var proxy = Proxy.create(handler, proto); handler.get(proxy, ‘foo’) handler handler.set(proxy, ‘foo’, 42) handler.get(proxy, ‘foo’).apply(proxy,[1,2,3]) handler.get(proxy, ‘get’) meta base proxy.foo proxy.foo = 42 proxy.foo(1,2,3) proxy proto proxy.get Tuesday, September 28, 2010
  • 23. Not just property accesses var proxy = Proxy.create(handler, proto); handler meta base proxy Tuesday, September 28, 2010
  • 24. Not just property accesses var proxy = Proxy.create(handler, proto); handler.has(‘foo’) handler meta base ‘foo’ in proxy proxy Tuesday, September 28, 2010
  • 25. Not just property accesses var proxy = Proxy.create(handler, proto); handler.has(‘foo’) handler.delete(‘foo’) handler meta base ‘foo’ in proxy delete proxy.foo proxy Tuesday, September 28, 2010
  • 26. Not just property accesses var proxy = Proxy.create(handler, proto); handler.has(‘foo’) handler.delete(‘foo’) var props = handler.enumerate(); handler for (var i=0;i<props.length;i++) { var prop = props[i]; ... } meta base ‘foo’ in proxy delete proxy.foo proxy for (var prop in proxy) { ... } Tuesday, September 28, 2010
  • 27. Not just property accesses var proxy = Proxy.create(handler, proto); handler.has(‘foo’) handler.delete(‘foo’) var props = handler.enumerate(); handler for (var i=0;i<props.length;i++) { var prop = props[i]; ... } handler.defineProperty(‘foo’, pd) meta base ‘foo’ in proxy delete proxy.foo proxy for (var prop in proxy) { ... } Object.defineProperty(proxy,‘foo’, pd) Tuesday, September 28, 2010
  • 28. But not quite everything, either var proxy = Proxy.create(handler, proto); handler meta base proxy Tuesday, September 28, 2010
  • 29. But not quite everything, either var proxy = Proxy.create(handler, proto); handler meta base proxy === obj proxy Tuesday, September 28, 2010
  • 30. But not quite everything, either var proxy = Proxy.create(handler, proto); handler meta base proxy === obj Object.getPrototypeOf(proxy) => proto proxy proto Tuesday, September 28, 2010
  • 31. But not quite everything, either var proxy = Proxy.create(handler, proto); handler meta base proxy === obj Object.getPrototypeOf(proxy) => proto proxy proto proxy instanceof SomeFunction Tuesday, September 28, 2010
  • 32. But not quite everything, either var proxy = Proxy.create(handler, proto); handler meta base proxy === obj Object.getPrototypeOf(proxy) => proto proxy proto proxy instanceof SomeFunction typeof proxy => “object” Tuesday, September 28, 2010
  • 33. Full Handler API handler proxy Object.getOwnPropertyDescriptor(proxy) handler.getOwnPropertyDescriptor(name) Object.getPropertyDescriptor(proxy) handler.getPropertyDescriptor(name) Object.defineProperty(proxy,name,pd) handler.defineProperty(name, pd) Object.getOwnPropertyNames(proxy)  handler.getOwnPropertyNames() delete proxy.name handler.delete(name)  for (name in proxy) { ... }  handler.enumerate() Object.{freeze|seal|...}(proxy) handler.fix() name in proxy handler.has(name) ({}).hasOwnProperty.call(proxy, name) handler.hasOwn(name) receiver.name handler.get(receiver, name) receiver.name = val handler.set(receiver, name, val) Object.keys(proxy) handler.keys() for (name in proxy) { ... } handler.iterate() Tuesday, September 28, 2010
  • 34. Fundamental vs Derived Traps handler proxy Fundamental traps Object.getOwnPropertyDescriptor(proxy) handler.getOwnPropertyDescriptor(name) Object.getPropertyDescriptor(proxy) handler.getPropertyDescriptor(name) Object.defineProperty(proxy,name,pd) handler.defineProperty(name, pd) Object.getOwnPropertyNames(proxy)  handler.getOwnPropertyNames() delete proxy.name handler.delete(name)  for (name in proxy) { ... }  handler.enumerate() -> [string] Object.{freeze|seal|...}(proxy) handler.fix() Derived traps name in proxy handler.has(name) ({}).hasOwnProperty.call(proxy, name) handler.hasOwn(name) receiver.name handler.get(receiver, name) receiver.name = val handler.set(receiver, name, val) Object.keys(proxy) handler.keys() for (name in proxy) { ... } handler.iterate() -> iterator Tuesday, September 28, 2010
  • 35. Function Proxies JavaScript functions are objects. Additionally, they are also callable and constructible var call = function() { ... }; var construct = function() { ... }; var funproxy = Proxy.createFunction(handler, call, construct); handler call construct funproxy Tuesday, September 28, 2010
  • 36. Function Proxies JavaScript functions are objects. Additionally, they are also callable and constructible var call = function() { ... }; var construct = function() { ... }; var funproxy = Proxy.createFunction(handler, call, construct); call(1,2,3) handler call construct funproxy(1,2,3) funproxy Tuesday, September 28, 2010
  • 37. Function Proxies JavaScript functions are objects. Additionally, they are also callable and constructible var call = function() { ... }; var construct = function() { ... }; var funproxy = Proxy.createFunction(handler, call, construct); call(1,2,3) handler call construct construct(1,2,3) funproxy(1,2,3) new funproxy(1,2,3) funproxy Tuesday, September 28, 2010
  • 38. Function Proxies JavaScript functions are objects. Additionally, they are also callable and constructible var call = function() { ... }; var construct = function() { ... }; var funproxy = Proxy.createFunction(handler, call, construct); call(1,2,3) handler call construct construct(1,2,3) handler.get(funproxy,‘prototype’) funproxy(1,2,3) new funproxy(1,2,3) funproxy.prototype funproxy Tuesday, September 28, 2010
  • 39. Function Proxies JavaScript functions are objects. Additionally, they are also callable and constructible var call = function() { ... }; var construct = function() { ... }; var funproxy = Proxy.createFunction(handler, call, construct); call(1,2,3) handler call construct construct(1,2,3) handler.get(funproxy,‘prototype’) funproxy(1,2,3) new funproxy(1,2,3) funproxy.prototype funproxy typeof funproxy => “function” Tuesday, September 28, 2010
  • 40. Function Proxies JavaScript functions are objects. Additionally, they are also callable and constructible var call = function() { ... }; var construct = function() { ... }; var funproxy = Proxy.createFunction(handler, call, construct); call(1,2,3) handler call construct construct(1,2,3) handler.get(funproxy,‘prototype’) funproxy(1,2,3) new funproxy(1,2,3) funproxy.prototype funproxy typeof funproxy => “function” Object.getPrototypeOf(funproxy) => Function.prototype Tuesday, September 28, 2010
  • 41. Dilemma: Invoke vs Get+Call • Fundamental vs derived traps = tradeoff in performance (method allocation or caching) vs. consistency var p = Proxy.create({   get:    function(receiver, name) { ... },   invoke: function(receiver, name, args) { ... },   ... }); p.x; // get(p,'x') p.m(a); // invoke(p, 'm', [a]) • invoke can intercept arguments • but notably, JS methods can be extracted as functions and called later (functional FTW!) • breaks invariant o.m.call(o) <=> o.m() Tuesday, September 28, 2010
  • 42. Selective Interception meta base object Tuesday, September 28, 2010
  • 43. Selective Interception VM territory (C++) meta base object JavaScript territory Tuesday, September 28, 2010
  • 44. Selective Interception VM territory (C++) VM handler meta base object JavaScript territory Tuesday, September 28, 2010
  • 45. Selective Interception VM territory (C++) VM handler VM handler meta base host object object JavaScript territory Tuesday, September 28, 2010
  • 46. Selective Interception VM territory (C++) VM handler VM handler handler meta base host object object proxy JavaScript territory Tuesday, September 28, 2010
  • 47. Selective Interception VM territory (C++) VM handler VM handler handler meta base host object object proxy JavaScript territory Tuesday, September 28, 2010
  • 48. Selective Interception VM territory (C++) Self-hosted VM handler VM handler handler meta base host object object proxy JavaScript territory Tuesday, September 28, 2010
  • 49. Selective Interception VM territory (C++) Self-hosted VM handler VM handler handler meta base host object object proxy JavaScript territory Tuesday, September 28, 2010
  • 50. Example: no-op forwarding proxy handler function ForwardingHandler(obj) { this.target = obj; proxy target } ForwardingHandler.prototype = {   has: function(name) { return name in this.target; },   get: function(rcvr,name) { return this.target[name]; },   set: function(rcvr,name,val) { this.target[name]=val;return true; },   delete: function(name) { return delete this.target[name]; }   enumerate: function() {     var props = []; for (name in this.target) { props.push(name); }; return props;   }, ... } var proxy = Proxy.create(new ForwardingHandler(o),                          Object.getPrototypeOf(o)); Tuesday, September 28, 2010
  • 51. Example: counting property access function makeSimpleProfiler(target) { var forwarder = new ForwardingHandler(target); var count = Object.create(null); forwarder.get = function(rcvr, name) { count[name] = (count[name] || 0) + 1; return this.target[name]; }; return { proxy: Proxy.create(forwarder, Object.getPrototypeOf(target)), get stats() { return count; } } } Tuesday, September 28, 2010
  • 52. Example: counting property access function makeSimpleProfiler(target) { var forwarder = new ForwardingHandler(target); var count = Object.create(null); forwarder.get = function(rcvr, name) { count[name] = (count[name] || 0) + 1; return this.target[name]; }; return { proxy: Proxy.create(forwarder, Object.getPrototypeOf(target)), get stats() { return count; } } } var subject = { ... }; var profiler = makeSimpleProfiler(subject); runApp(profiler.proxy); display(profiler.stats); Tuesday, September 28, 2010
  • 53. Fixing a Proxy var proxy = Proxy.create(handler, proto); handler meta base proxy Tuesday, September 28, 2010
  • 54. Fixing a Proxy var proxy = Proxy.create(handler, proto); handler meta base Object.freeze(proxy) Object.seal(proxy) proxy Object.preventExtensions(proxy) Tuesday, September 28, 2010
  • 55. Fixing a Proxy var proxy = Proxy.create(handler, proto); var pdmap = handler.fix(); if (pdmap === undefined) throw TypeError(); handler become(proxy, Object.freeze( Object.create(proto, pdmap))); meta base Object.freeze(proxy) Object.seal(proxy) proxy Object.preventExtensions(proxy) Tuesday, September 28, 2010
  • 56. Fixing a Proxy var proxy = Proxy.create(handler, proto); var pdmap = handler.fix(); if (pdmap === undefined) throw TypeError(); handler become(proxy, Object.freeze( Object.create(proto, pdmap))); meta base Object.freeze(proxy) Object.seal(proxy) proxy Object.preventExtensions(proxy) fix Trapping Fixed Tuesday, September 28, 2010
  • 57. Fixing a Proxy var proxy = Proxy.create(handler, proto); var pdmap = handler.fix(); if (pdmap === undefined) throw TypeError(); become(proxy, Object.freeze( Object.create(proto, pdmap))); meta base Object.freeze(proxy) Object.seal(proxy) proxy Object.preventExtensions(proxy) fix Trapping Fixed Tuesday, September 28, 2010
  • 58. Meta-level Shifting handler proxy Object.getOwnPropertyDescriptor(proxy) handler.getOwnPropertyDescriptor(name) Object.getPropertyDescriptor(proxy) handler.getPropertyDescriptor(name) Object.defineProperty(proxy,name,pd) handler.defineProperty(name, pd) Object.getOwnPropertyNames(proxy)  handler.getOwnPropertyNames() delete proxy.name handler.delete(name)  for (name in proxy) { ... }  handler.enumerate() Object.{freeze|seal|...}(proxy) handler.fix() name in proxy handler.has(name) ({}).hasOwnProperty.call(proxy, name) handler.hasOwn(name) receiver.name handler.get(receiver, name) receiver.name = val handler.set(receiver, name, val) Object.keys(proxy) handler.keys() for (name in proxy) { ... }  handler.iterate() base-level: many operations meta-level: all operations reified as on objects invocations of traps Tuesday, September 28, 2010
  • 59. Meta-level Shifting a proxy whose μhandler handler is a proxy handler handler.getOwnPropertyDescriptor(name) μhandler.get(handler, ‘getOwnP..’)(name) handler.getPropertyDescriptor(name) μhandler.get(handler, ‘getProp..’)(name) handler.defineOwnProperty(name, pd) μhandler.get(handler, ‘define...’)(name,pd) handler.delete(name)  μhandler.get(handler, ‘delete’)(name) handler.getOwnPropertyNames() μhandler.get(handler, ‘getOwnP..’)() handler.enumerate() μhandler.get(handler, ‘enumerate’)() handler.fix() μhandler.get(handler, ‘fix’)() handler.has(name) μhandler.get(handler, ‘has’)(name) handler.hasOwn(name) μhandler.get(handler, ‘hasOwn’)(name) handler.get(receiver, name) μhandler.get(handler, ‘get’)(receiver,name) handler.set(receiver, name, val) μhandler.get(handler, ‘set’)(receiver,name,val) handler.keys() μhandler.get(handler, ‘keys’)() handler.iterate() μhandler.get(handler, ‘iterate’)() meta-level: all operations reified as meta-meta-level: all operations invocations of traps reified as invocations of ‘get’ trap Tuesday, September 28, 2010
  • 60. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 61. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 62. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 63. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 64. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 65. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 66. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 67. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 68. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 69. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 70. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 71. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 72. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 73. Example: Membranes • Firefox security wrappers (anti-XSS, XUL, etc.) • Google Caja: capability-secure subset • Object-capability model: an object is powerless unless given a reference to other objects • References can be made revocable through a membrane Tuesday, September 28, 2010
  • 74. Example: Membranes function makeSimpleMembrane(initTarget) {   var enabled = true; } Tuesday, September 28, 2010
  • 75. Example: Membranes function makeSimpleMembrane(initTarget) {   var enabled = true;   return { wrapper: wrap(initTarget), revoke: function() { enabled = false; } }; } Tuesday, September 28, 2010
  • 76. Example: Membranes function makeSimpleMembrane(initTarget) {   var enabled = true;   function wrap(target) {     if (Object.isPrimitive(target)) { return target; }     var baseHandler = new ForwardingHandler(target);     var revokeHandler = Proxy.create({       get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }     });   }   return { wrapper: wrap(initTarget), revoke: function() { enabled = false; } }; } Tuesday, September 28, 2010
  • 77. Example: Membranes function makeSimpleMembrane(initTarget) {   var enabled = true;   function wrap(target) {     if (Object.isPrimitive(target)) { return target; }     var baseHandler = new ForwardingHandler(target);     var revokeHandler = Proxy.create({       get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }     }); if (typeof target === “function”) { return Proxy.createFunction(revokeHandler, wrapFunction(target)); }     return Proxy.create(revokeHandler, wrap(Object.getPrototypeOf(target)));   }   return { wrapper: wrap(initTarget), revoke: function() { enabled = false; } }; } Tuesday, September 28, 2010
  • 78. Example: Membranes function makeSimpleMembrane(initTarget) {   var enabled = true; function wrapFunction(f) {     return function() { // variable-argument function if (!enabled) { throw new Error("revoked"); }      return wrap(f.apply(wrap(this), arguments.map(wrap))); } }   function wrap(target) {     if (Object.isPrimitive(target)) { return target; }     var baseHandler = new ForwardingHandler(target);     var revokeHandler = Proxy.create({       get: function(rcvr, name) { return wrapFunction(baseHandler[name]); }     }); if (typeof target === “function”) { return Proxy.createFunction(revokeHandler, wrapFunction(target)); }     return Proxy.create(revokeHandler, wrap(Object.getPrototypeOf(target)));   }   return { wrapper: wrap(initTarget), revoke: function() { enabled = false; } }; } Tuesday, September 28, 2010
  • 79. Prior Work handler meta base proxy Tuesday, September 28, 2010
  • 80. Prior Work handler mirror ProxyHandler InvocationHandler meta base proxy mirage proxy java.lang.reflect.Proxy Tuesday, September 28, 2010
  • 81. Prior Work handler mirror ProxyHandler InvocationHandler meta base proxy mirage proxy java.lang.reflect.Proxy # traps 13 30 3 1 Tuesday, September 28, 2010
  • 82. Making JavaScript Extensible • Extending JavaScript today: “Host objects” (the IE DOM; anything implemented in C++) • Proxies are sufficiently powerful to emulate most of the behavior of host objects in JavaScript itself • Two possible avenues to close the gap: • Make proxies even more powerful • Make host objects only as powerful as proxies Tuesday, September 28, 2010
  • 83. Status • Presented at ECMA TC-39 meetings • Approved for inclusion in ES-Harmony • http://wiki.ecmascript.org/doku.php? id=harmony:proxies • In Firefox 4 already, thanks to Andreas Gal! • The basis of all of Gecko’s security wrappers • Used by Zaphod (Narcissus as JS engine add-on, source at http://github.com/taustin/Zaphod/) Tuesday, September 28, 2010
  • 84. Lessons for Web Standards • Standards need savvy academic research • Standards must evolve quickly on the Web • They can’t evolve without prototype trials • These experiments need tons of user-testing • To reach users at scale, prototypes must ship • Ecma TC39 committed to prototyping specs before finalizing standards • Committee members work together, no blind-siding, to uphold Harmony (it’s social!) Tuesday, September 28, 2010
  • 87. Proxies: Summary • Proxies enable: • Generic wrappers: access control, profiling, adaptors, test injection, etc. • Virtual objects: persistent objects, remote objects, emulated host objects, ... • API: • Robust: stratified, not all operations intercepted • Secure: can’t trap non-proxy or fixed objects • Performance: no overhead for non-proxy objects Tuesday, September 28, 2010
  • 88. Conclusions • ES5 provides new meta-programming APIs • ES-Harmony Proxies: robust dynamic meta- programming for virtual objects, wrappers • Proxies help put developers in control of extending JavaScript, instead of Ecma TC39 • JavaScript: the Revenge of Smalltalk! Tuesday, September 28, 2010