proxy.js revision 589d6979ff2ef66fca2d8fa51404c369ca5e9250
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 32$Proxy.create = function(handler, proto) { 33 if (!IS_SPEC_OBJECT(handler)) 34 throw MakeTypeError("handler_non_object", ["create"]) 35 if (!IS_SPEC_OBJECT(proto)) proto = null // Mozilla does this... 36 return %CreateJSProxy(handler, proto) 37} 38 39$Proxy.createFunction = function(handler, callTrap, constructTrap) { 40 if (!IS_SPEC_OBJECT(handler)) 41 throw MakeTypeError("handler_non_object", ["create"]) 42 if (!IS_SPEC_FUNCTION(callTrap)) 43 throw MakeTypeError("trap_function_expected", ["createFunction", "call"]) 44 if (IS_UNDEFINED(constructTrap)) { 45 constructTrap = callTrap 46 } else if (!IS_SPEC_FUNCTION(constructTrap)) { 47 throw MakeTypeError("trap_function_expected", 48 ["createFunction", "construct"]) 49 } 50 return %CreateJSFunctionProxy( 51 handler, callTrap, constructTrap, $Function.prototype) 52} 53 54 55 56//////////////////////////////////////////////////////////////////////////////// 57// Builtins 58//////////////////////////////////////////////////////////////////////////////// 59 60function DelegateCallAndConstruct(callTrap, constructTrap) { 61 return function() { 62 return %Apply(%_IsConstructCall() ? constructTrap : callTrap, 63 this, arguments, 0, %_ArgumentsLength()) 64 } 65} 66 67function DerivedGetTrap(receiver, name) { 68 var desc = this.getPropertyDescriptor(name) 69 if (IS_UNDEFINED(desc)) { return desc } 70 if ('value' in desc) { 71 return desc.value 72 } else { 73 if (IS_UNDEFINED(desc.get)) { return desc.get } 74 // The proposal says: desc.get.call(receiver) 75 return %_CallFunction(receiver, desc.get) 76 } 77} 78 79function DerivedSetTrap(receiver, name, val) { 80 var desc = this.getOwnPropertyDescriptor(name) 81 if (desc) { 82 if ('writable' in desc) { 83 if (desc.writable) { 84 desc.value = val 85 this.defineProperty(name, desc) 86 return true 87 } else { 88 return false 89 } 90 } else { // accessor 91 if (desc.set) { 92 // The proposal says: desc.set.call(receiver, val) 93 %_CallFunction(receiver, val, desc.set) 94 return true 95 } else { 96 return false 97 } 98 } 99 } 100 desc = this.getPropertyDescriptor(name) 101 if (desc) { 102 if ('writable' in desc) { 103 if (desc.writable) { 104 // fall through 105 } else { 106 return false 107 } 108 } else { // accessor 109 if (desc.set) { 110 // The proposal says: desc.set.call(receiver, val) 111 %_CallFunction(receiver, val, desc.set) 112 return true 113 } else { 114 return false 115 } 116 } 117 } 118 this.defineProperty(name, { 119 value: val, 120 writable: true, 121 enumerable: true, 122 configurable: true}); 123 return true; 124} 125 126function DerivedHasTrap(name) { 127 return !!this.getPropertyDescriptor(name) 128} 129 130function DerivedHasOwnTrap(name) { 131 return !!this.getOwnPropertyDescriptor(name) 132} 133 134function DerivedKeysTrap() { 135 var names = this.getOwnPropertyNames() 136 var enumerableNames = [] 137 for (var i = 0, count = 0; i < names.length; ++i) { 138 var name = names[i] 139 if (this.getOwnPropertyDescriptor(TO_STRING_INLINE(name)).enumerable) { 140 enumerableNames[count++] = names[i] 141 } 142 } 143 return enumerableNames 144} 145