proxy.js revision 3fb3ca8c7ca439d408449a395897395c0faae8d1
1// Copyright 2011 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28global.Proxy = new $Object(); 29 30var $Proxy = global.Proxy 31 32var fundamentalTraps = [ 33 "getOwnPropertyDescriptor", 34 "getPropertyDescriptor", 35 "getOwnPropertyNames", 36 "getPropertyNames", 37 "defineProperty", 38 "delete", 39 "fix", 40] 41 42var derivedTraps = [ 43 "has", 44 "hasOwn", 45 "get", 46 "set", 47 "enumerate", 48 "keys", 49] 50 51var functionTraps = [ 52 "callTrap", 53 "constructTrap", 54] 55 56$Proxy.createFunction = function(handler, callTrap, constructTrap) { 57 handler.callTrap = callTrap 58 handler.constructTrap = constructTrap 59 $Proxy.create(handler) 60} 61 62$Proxy.create = function(handler, proto) { 63 if (!IS_SPEC_OBJECT(handler)) 64 throw MakeTypeError("handler_non_object", ["create"]) 65 if (!IS_SPEC_OBJECT(proto)) proto = null // Mozilla does this... 66 return %CreateJSProxy(handler, proto) 67} 68 69 70 71 72//////////////////////////////////////////////////////////////////////////////// 73// Builtins 74//////////////////////////////////////////////////////////////////////////////// 75 76function DerivedGetTrap(receiver, name) { 77 var desc = this.getPropertyDescriptor(name) 78 if (IS_UNDEFINED(desc)) { return desc } 79 if ('value' in desc) { 80 return desc.value 81 } else { 82 if (IS_UNDEFINED(desc.get)) { return desc.get } 83 // The proposal says: desc.get.call(receiver) 84 return %_CallFunction(receiver, desc.get) 85 } 86} 87 88function DerivedSetTrap(receiver, name, val) { 89 var desc = this.getOwnPropertyDescriptor(name) 90 if (desc) { 91 if ('writable' in desc) { 92 if (desc.writable) { 93 desc.value = val 94 this.defineProperty(name, desc) 95 return true 96 } else { 97 return false 98 } 99 } else { // accessor 100 if (desc.set) { 101 // The proposal says: desc.set.call(receiver, val) 102 %_CallFunction(receiver, val, desc.set) 103 return true 104 } else { 105 return false 106 } 107 } 108 } 109 desc = this.getPropertyDescriptor(name) 110 if (desc) { 111 if ('writable' in desc) { 112 if (desc.writable) { 113 // fall through 114 } else { 115 return false 116 } 117 } else { // accessor 118 if (desc.set) { 119 // The proposal says: desc.set.call(receiver, val) 120 %_CallFunction(receiver, val, desc.set) 121 return true 122 } else { 123 return false 124 } 125 } 126 } 127 this.defineProperty(name, { 128 value: val, 129 writable: true, 130 enumerable: true, 131 configurable: true}); 132 return true; 133} 134 135function DerivedHasTrap(name) { 136 return !!this.getPropertyDescriptor(name) 137} 138 139function DerivedKeysTrap() { 140 var names = this.getOwnPropertyNames() 141 var enumerableNames = [] 142 for (var i = 0, count = 0; i < names.length; ++i) { 143 var name = names[i] 144 if (this.getOwnPropertyDescriptor(TO_STRING_INLINE(name)).enumerable) { 145 enumerableNames[count++] = names[i] 146 } 147 } 148 return enumerableNames 149} 150