1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 // This file relies on the fact that the following declaration has been made
9 // var $Object = global.Object;
11 var $Proxy = new $Object();
13 // -------------------------------------------------------------------
15 function ProxyCreate(handler, proto) {
16 if (!IS_SPEC_OBJECT(handler))
17 throw MakeTypeError("handler_non_object", ["create"])
18 if (IS_UNDEFINED(proto))
20 else if (!(IS_SPEC_OBJECT(proto) || IS_NULL(proto)))
21 throw MakeTypeError("proto_non_object", ["create"])
22 return %CreateJSProxy(handler, proto)
25 function ProxyCreateFunction(handler, callTrap, constructTrap) {
26 if (!IS_SPEC_OBJECT(handler))
27 throw MakeTypeError("handler_non_object", ["create"])
28 if (!IS_SPEC_FUNCTION(callTrap))
29 throw MakeTypeError("trap_function_expected", ["createFunction", "call"])
30 if (IS_UNDEFINED(constructTrap)) {
31 constructTrap = DerivedConstructTrap(callTrap)
32 } else if (IS_SPEC_FUNCTION(constructTrap)) {
33 // Make sure the trap receives 'undefined' as this.
34 var construct = constructTrap
35 constructTrap = function() {
36 return %Apply(construct, UNDEFINED, arguments, 0, %_ArgumentsLength());
39 throw MakeTypeError("trap_function_expected",
40 ["createFunction", "construct"])
42 return %CreateJSFunctionProxy(
43 handler, callTrap, constructTrap, $Function.prototype)
47 // -------------------------------------------------------------------
49 function SetUpProxy() {
50 %CheckIsBootstrapping()
52 var global_proxy = %GlobalProxy(global);
53 global_proxy.Proxy = $Proxy;
55 // Set up non-enumerable properties of the Proxy object.
56 InstallFunctions($Proxy, DONT_ENUM, [
57 "create", ProxyCreate,
58 "createFunction", ProxyCreateFunction
65 // -------------------------------------------------------------------
68 function DerivedConstructTrap(callTrap) {
70 var proto = this.prototype
71 if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype
72 var obj = { __proto__: proto };
73 var result = %Apply(callTrap, obj, arguments, 0, %_ArgumentsLength());
74 return IS_SPEC_OBJECT(result) ? result : obj
78 function DelegateCallAndConstruct(callTrap, constructTrap) {
80 return %Apply(%_IsConstructCall() ? constructTrap : callTrap,
81 this, arguments, 0, %_ArgumentsLength())
85 function DerivedGetTrap(receiver, name) {
86 var desc = this.getPropertyDescriptor(name)
87 if (IS_UNDEFINED(desc)) { return desc }
88 if ('value' in desc) {
91 if (IS_UNDEFINED(desc.get)) { return desc.get }
92 // The proposal says: desc.get.call(receiver)
93 return %_CallFunction(receiver, desc.get)
97 function DerivedSetTrap(receiver, name, val) {
98 var desc = this.getOwnPropertyDescriptor(name)
100 if ('writable' in desc) {
103 this.defineProperty(name, desc)
110 // The proposal says: desc.set.call(receiver, val)
111 %_CallFunction(receiver, val, desc.set)
118 desc = this.getPropertyDescriptor(name)
120 if ('writable' in desc) {
128 // The proposal says: desc.set.call(receiver, val)
129 %_CallFunction(receiver, val, desc.set)
136 this.defineProperty(name, {
140 configurable: true});
144 function DerivedHasTrap(name) {
145 return !!this.getPropertyDescriptor(name)
148 function DerivedHasOwnTrap(name) {
149 return !!this.getOwnPropertyDescriptor(name)
152 function DerivedKeysTrap() {
153 var names = this.getOwnPropertyNames()
154 var enumerableNames = []
155 for (var i = 0, count = 0; i < names.length; ++i) {
157 if (IS_SYMBOL(name)) continue
158 var desc = this.getOwnPropertyDescriptor(TO_STRING_INLINE(name))
159 if (!IS_UNDEFINED(desc) && desc.enumerable) {
160 enumerableNames[count++] = names[i]
163 return enumerableNames
166 function DerivedEnumerateTrap() {
167 var names = this.getPropertyNames()
168 var enumerableNames = []
169 for (var i = 0, count = 0; i < names.length; ++i) {
171 if (IS_SYMBOL(name)) continue
172 var desc = this.getPropertyDescriptor(TO_STRING_INLINE(name))
173 if (!IS_UNDEFINED(desc)) {
174 if (!desc.configurable) {
175 throw MakeTypeError("proxy_prop_not_configurable",
176 [this, "getPropertyDescriptor", name])
178 if (desc.enumerable) enumerableNames[count++] = names[i]
181 return enumerableNames
184 function ProxyEnumerate(proxy) {
185 var handler = %GetHandler(proxy)
186 if (IS_UNDEFINED(handler.enumerate)) {
187 return %Apply(DerivedEnumerateTrap, handler, [], 0, 0)
189 return ToNameArray(handler.enumerate(), "enumerate", false)