blob: 4e44cd4ef3d069709d4ad8855803e1765b40ce5e [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// 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
Ben Murdoch257744e2011-11-30 15:57:28 +000032$Proxy.create = function(handler, proto) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000033 if (!IS_SPEC_OBJECT(handler))
34 throw MakeTypeError("handler_non_object", ["create"])
35 if (!IS_SPEC_OBJECT(proto)) proto = null // Mozilla does this...
Ben Murdoch257744e2011-11-30 15:57:28 +000036 return %CreateJSProxy(handler, proto)
37}
38
Ben Murdoch589d6972011-11-30 16:04:58 +000039$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}
Ben Murdoch257744e2011-11-30 15:57:28 +000053
54
55
56////////////////////////////////////////////////////////////////////////////////
57// Builtins
58////////////////////////////////////////////////////////////////////////////////
59
Ben Murdoch589d6972011-11-30 16:04:58 +000060function DelegateCallAndConstruct(callTrap, constructTrap) {
61 return function() {
62 return %Apply(%_IsConstructCall() ? constructTrap : callTrap,
63 this, arguments, 0, %_ArgumentsLength())
64 }
65}
66
Ben Murdoch257744e2011-11-30 15:57:28 +000067function DerivedGetTrap(receiver, name) {
68 var desc = this.getPropertyDescriptor(name)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000069 if (IS_UNDEFINED(desc)) { return desc }
Ben Murdoch257744e2011-11-30 15:57:28 +000070 if ('value' in desc) {
71 return desc.value
72 } else {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000073 if (IS_UNDEFINED(desc.get)) { return desc.get }
74 // The proposal says: desc.get.call(receiver)
75 return %_CallFunction(receiver, desc.get)
Ben Murdoch257744e2011-11-30 15:57:28 +000076 }
77}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000078
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
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000130function DerivedHasOwnTrap(name) {
131 return !!this.getOwnPropertyDescriptor(name)
132}
133
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000134function 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}