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

Using Xcore with Xtext
Using Xcore with XtextUsing Xcore with Xtext
Using Xcore with XtextHolger Schill
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022Alexander Ioffe
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Scott Wlaschin
 
Be Smart, Constrain Your Types to Free Your Brain!
Be Smart, Constrain Your Types to Free Your Brain!Be Smart, Constrain Your Types to Free Your Brain!
Be Smart, Constrain Your Types to Free Your Brain!Jorge Vásquez
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Julien Truffaut
 
The JVM is your friend
The JVM is your friendThe JVM is your friend
The JVM is your friendKai Koenig
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀Shengyou Fan
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Scott Wlaschin
 
Know your app: Add metrics to Java with Micrometer | DevNation Tech Talk
Know your app: Add metrics to Java with Micrometer | DevNation Tech TalkKnow your app: Add metrics to Java with Micrometer | DevNation Tech Talk
Know your app: Add metrics to Java with Micrometer | DevNation Tech TalkRed Hat Developers
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Roman Elizarov
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOJorge Vásquez
 
Java: Regular Expression
Java: Regular ExpressionJava: Regular Expression
Java: Regular ExpressionMasudul Haque
 
Python GUI Programming
Python GUI ProgrammingPython GUI Programming
Python GUI ProgrammingRTS Tech
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and EffectsMartin Odersky
 

What's hot (20)

JQuery selectors
JQuery selectors JQuery selectors
JQuery selectors
 
Using Xcore with Xtext
Using Xcore with XtextUsing Xcore with Xtext
Using Xcore with Xtext
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
 
React js
React jsReact js
React js
 
JQuery UI
JQuery UIJQuery UI
JQuery UI
 
Be Smart, Constrain Your Types to Free Your Brain!
Be Smart, Constrain Your Types to Free Your Brain!Be Smart, Constrain Your Types to Free Your Brain!
Be Smart, Constrain Your Types to Free Your Brain!
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!
 
The JVM is your friend
The JVM is your friendThe JVM is your friend
The JVM is your friend
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
 
Java vs OOP
Java vs OOPJava vs OOP
Java vs OOP
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)
 
Know your app: Add metrics to Java with Micrometer | DevNation Tech Talk
Know your app: Add metrics to Java with Micrometer | DevNation Tech TalkKnow your app: Add metrics to Java with Micrometer | DevNation Tech Talk
Know your app: Add metrics to Java with Micrometer | DevNation Tech Talk
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
 
Java: Regular Expression
Java: Regular ExpressionJava: Regular Expression
Java: Regular Expression
 
Python GUI Programming
Python GUI ProgrammingPython GUI Programming
Python GUI Programming
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 

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

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
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
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
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
 
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
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
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
 
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
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
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
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 

Recently uploaded (20)

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
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
 
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
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
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...
 
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...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
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
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

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