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

Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API07.pallav
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSAbul Hasan
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlinintelliyole
 
Let's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APILet's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APIMario Fusco
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...Philip Schwarz
 
JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)WebStackAcademy
 
Module design pattern i.e. express js
Module design pattern i.e. express jsModule design pattern i.e. express js
Module design pattern i.e. express jsAhmed Assaf
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented ProgrammingScott Wlaschin
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced JavascriptAdieu
 
RxJS - The Basics & The Future
RxJS - The Basics & The FutureRxJS - The Basics & The Future
RxJS - The Basics & The FutureTracy Lee
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentationritika1
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event LoopDesignveloper
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.David Gómez García
 
Exploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaExploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaJorge Vásquez
 

What's hot (20)

Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Let's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APILet's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java API
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
 
Optional in Java 8
Optional in Java 8Optional in Java 8
Optional in Java 8
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
 
JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)
 
Module design pattern i.e. express js
Module design pattern i.e. express jsModule design pattern i.e. express js
Module design pattern i.e. express js
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Php with MYSQL Database
Php with MYSQL DatabasePhp with MYSQL Database
Php with MYSQL Database
 
RxJS - The Basics & The Future
RxJS - The Basics & The FutureRxJS - The Basics & The Future
RxJS - The Basics & The Future
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentation
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
 
Fabricjs ppt
Fabricjs pptFabricjs ppt
Fabricjs ppt
 
Exploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaExploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in Scala
 
Workshop 21: React Router
Workshop 21: React RouterWorkshop 21: React Router
Workshop 21: React Router
 

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

DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 

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