2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
29 #include "JSGlobalObject.h"
30 #include "JSCInlines.h"
34 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSProxy
);
36 const ClassInfo
JSProxy::s_info
= { "JSProxy", &Base::s_info
, 0, CREATE_METHOD_TABLE(JSProxy
) };
38 void JSProxy::visitChildren(JSCell
* cell
, SlotVisitor
& visitor
)
40 JSProxy
* thisObject
= jsCast
<JSProxy
*>(cell
);
41 ASSERT_GC_OBJECT_INHERITS(thisObject
, info());
42 Base::visitChildren(thisObject
, visitor
);
43 visitor
.append(&thisObject
->m_target
);
46 void JSProxy::setTarget(VM
& vm
, JSGlobalObject
* globalObject
)
48 ASSERT_ARG(globalObject
, globalObject
);
49 m_target
.set(vm
, this, globalObject
);
50 setPrototype(vm
, globalObject
->prototype());
52 PrototypeMap
& prototypeMap
= vm
.prototypeMap
;
53 if (!prototypeMap
.isPrototype(this))
56 // This is slow but constant time. We think it's very rare for a proxy
57 // to be a prototype, and reasonably rare to retarget a proxy,
58 // so slow constant time is OK.
59 for (size_t i
= 0; i
<= JSFinalObject::maxInlineCapacity(); ++i
)
60 prototypeMap
.clearEmptyObjectStructureForPrototype(this, i
);
63 String
JSProxy::className(const JSObject
* object
)
65 const JSProxy
* thisObject
= jsCast
<const JSProxy
*>(object
);
66 return thisObject
->target()->methodTable()->className(thisObject
->target());
69 bool JSProxy::getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
& slot
)
71 JSProxy
* thisObject
= jsCast
<JSProxy
*>(object
);
72 return thisObject
->target()->methodTable(exec
->vm())->getOwnPropertySlot(thisObject
->target(), exec
, propertyName
, slot
);
75 bool JSProxy::getOwnPropertySlotByIndex(JSObject
* object
, ExecState
* exec
, unsigned propertyName
, PropertySlot
& slot
)
77 JSProxy
* thisObject
= jsCast
<JSProxy
*>(object
);
78 return thisObject
->target()->methodTable(exec
->vm())->getOwnPropertySlotByIndex(thisObject
->target(), exec
, propertyName
, slot
);
81 void JSProxy::put(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
, JSValue value
, PutPropertySlot
& slot
)
83 JSProxy
* thisObject
= jsCast
<JSProxy
*>(cell
);
84 thisObject
->target()->methodTable(exec
->vm())->put(thisObject
->target(), exec
, propertyName
, value
, slot
);
87 void JSProxy::putByIndex(JSCell
* cell
, ExecState
* exec
, unsigned propertyName
, JSValue value
, bool shouldThrow
)
89 JSProxy
* thisObject
= jsCast
<JSProxy
*>(cell
);
90 thisObject
->target()->methodTable(exec
->vm())->putByIndex(thisObject
->target(), exec
, propertyName
, value
, shouldThrow
);
93 bool JSProxy::defineOwnProperty(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, const PropertyDescriptor
& descriptor
, bool shouldThrow
)
95 JSProxy
* thisObject
= jsCast
<JSProxy
*>(object
);
96 return thisObject
->target()->methodTable(exec
->vm())->defineOwnProperty(thisObject
->target(), exec
, propertyName
, descriptor
, shouldThrow
);
99 bool JSProxy::deleteProperty(JSCell
* cell
, ExecState
* exec
, PropertyName propertyName
)
101 JSProxy
* thisObject
= jsCast
<JSProxy
*>(cell
);
102 return thisObject
->target()->methodTable(exec
->vm())->deleteProperty(thisObject
->target(), exec
, propertyName
);
105 bool JSProxy::deletePropertyByIndex(JSCell
* cell
, ExecState
* exec
, unsigned propertyName
)
107 JSProxy
* thisObject
= jsCast
<JSProxy
*>(cell
);
108 return thisObject
->target()->methodTable(exec
->vm())->deletePropertyByIndex(thisObject
->target(), exec
, propertyName
);
111 void JSProxy::getPropertyNames(JSObject
* object
, ExecState
* exec
, PropertyNameArray
& propertyNames
, EnumerationMode mode
)
113 JSProxy
* thisObject
= jsCast
<JSProxy
*>(object
);
114 thisObject
->target()->methodTable(exec
->vm())->getPropertyNames(thisObject
->target(), exec
, propertyNames
, mode
);
117 uint32_t JSProxy::getEnumerableLength(ExecState
* exec
, JSObject
* object
)
119 JSProxy
* thisObject
= jsCast
<JSProxy
*>(object
);
120 return thisObject
->target()->methodTable(exec
->vm())->getEnumerableLength(exec
, thisObject
->target());
123 void JSProxy::getStructurePropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
)
125 // Skip the structure loop, since it is invalid for proxies.
128 void JSProxy::getGenericPropertyNames(JSObject
* object
, ExecState
* exec
, PropertyNameArray
& propertyNames
, EnumerationMode mode
)
130 JSProxy
* thisObject
= jsCast
<JSProxy
*>(object
);
131 // Get *all* of the property names, not just the generic ones, since we skipped the structure
133 thisObject
->target()->methodTable(exec
->vm())->getPropertyNames(thisObject
->target(), exec
, propertyNames
, mode
);
136 void JSProxy::getOwnPropertyNames(JSObject
* object
, ExecState
* exec
, PropertyNameArray
& propertyNames
, EnumerationMode mode
)
138 JSProxy
* thisObject
= jsCast
<JSProxy
*>(object
);
139 thisObject
->target()->methodTable(exec
->vm())->getOwnPropertyNames(thisObject
->target(), exec
, propertyNames
, mode
);