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
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.
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.
30 global.Proxy = new $Object();
32 var $Proxy = global.Proxy
34 $Proxy.create = function(handler, proto) {
35 if (!IS_SPEC_OBJECT(handler))
36 throw MakeTypeError("handler_non_object", ["create"])
37 if (IS_UNDEFINED(proto))
39 else if (!(IS_SPEC_OBJECT(proto) || proto === null))
40 throw MakeTypeError("proto_non_object", ["create"])
41 return %CreateJSProxy(handler, proto)
44 $Proxy.createFunction = function(handler, callTrap, constructTrap) {
45 if (!IS_SPEC_OBJECT(handler))
46 throw MakeTypeError("handler_non_object", ["create"])
47 if (!IS_SPEC_FUNCTION(callTrap))
48 throw MakeTypeError("trap_function_expected", ["createFunction", "call"])
49 if (IS_UNDEFINED(constructTrap)) {
50 constructTrap = DerivedConstructTrap(callTrap)
51 } else if (IS_SPEC_FUNCTION(constructTrap)) {
52 // Make sure the trap receives 'undefined' as this.
53 var construct = constructTrap
54 constructTrap = function() {
55 return %Apply(construct, void 0, arguments, 0, %_ArgumentsLength());
58 throw MakeTypeError("trap_function_expected",
59 ["createFunction", "construct"])
61 return %CreateJSFunctionProxy(
62 handler, callTrap, constructTrap, $Function.prototype)
67 ////////////////////////////////////////////////////////////////////////////////
69 ////////////////////////////////////////////////////////////////////////////////
71 function DerivedConstructTrap(callTrap) {
73 var proto = this.prototype
74 if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype
75 var obj = new $Object()
77 var result = %Apply(callTrap, obj, arguments, 0, %_ArgumentsLength());
78 return IS_SPEC_OBJECT(result) ? result : obj
82 function DelegateCallAndConstruct(callTrap, constructTrap) {
84 return %Apply(%_IsConstructCall() ? constructTrap : callTrap,
85 this, arguments, 0, %_ArgumentsLength())
89 function DerivedGetTrap(receiver, name) {
90 var desc = this.getPropertyDescriptor(name)
91 if (IS_UNDEFINED(desc)) { return desc }
92 if ('value' in desc) {
95 if (IS_UNDEFINED(desc.get)) { return desc.get }
96 // The proposal says: desc.get.call(receiver)
97 return %_CallFunction(receiver, desc.get)
101 function DerivedSetTrap(receiver, name, val) {
102 var desc = this.getOwnPropertyDescriptor(name)
104 if ('writable' in desc) {
107 this.defineProperty(name, desc)
114 // The proposal says: desc.set.call(receiver, val)
115 %_CallFunction(receiver, val, desc.set)
122 desc = this.getPropertyDescriptor(name)
124 if ('writable' in desc) {
132 // The proposal says: desc.set.call(receiver, val)
133 %_CallFunction(receiver, val, desc.set)
140 this.defineProperty(name, {
144 configurable: true});
148 function DerivedHasTrap(name) {
149 return !!this.getPropertyDescriptor(name)
152 function DerivedHasOwnTrap(name) {
153 return !!this.getOwnPropertyDescriptor(name)
156 function DerivedKeysTrap() {
157 var names = this.getOwnPropertyNames()
158 var enumerableNames = []
159 for (var i = 0, count = 0; i < names.length; ++i) {
161 var desc = this.getOwnPropertyDescriptor(TO_STRING_INLINE(name))
162 if (!IS_UNDEFINED(desc) && desc.enumerable) {
163 enumerableNames[count++] = names[i]
166 return enumerableNames
169 function DerivedEnumerateTrap() {
170 var names = this.getPropertyNames()
171 var enumerableNames = []
172 for (var i = 0, count = 0; i < names.length; ++i) {
174 var desc = this.getPropertyDescriptor(TO_STRING_INLINE(name))
175 if (!IS_UNDEFINED(desc) && desc.enumerable) {
176 enumerableNames[count++] = names[i]
179 return enumerableNames
182 function ProxyEnumerate(proxy) {
183 var handler = %GetHandler(proxy)
184 if (IS_UNDEFINED(handler.enumerate)) {
185 return %Apply(DerivedEnumerateTrap, handler, [], 0, 0)
187 return ToStringArray(handler.enumerate(), "enumerate")