summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/ProxyObject.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/runtime/ProxyObject.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/runtime/ProxyObject.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/ProxyObject.cpp311
1 files changed, 0 insertions, 311 deletions
diff --git a/Source/JavaScriptCore/runtime/ProxyObject.cpp b/Source/JavaScriptCore/runtime/ProxyObject.cpp
deleted file mode 100644
index 6ea856d73..000000000
--- a/Source/JavaScriptCore/runtime/ProxyObject.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ProxyObject.h"
-
-#include "Error.h"
-#include "IdentifierInlines.h"
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "ObjectConstructor.h"
-#include "SlotVisitorInlines.h"
-#include "StructureInlines.h"
-
-namespace JSC {
-
-STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ProxyObject);
-
-const ClassInfo ProxyObject::s_info = { "ProxyObject", &Base::s_info, 0, CREATE_METHOD_TABLE(ProxyObject) };
-
-ProxyObject::ProxyObject(VM& vm, Structure* structure)
- : Base(vm, structure)
-{
-}
-
-void ProxyObject::finishCreation(VM& vm, ExecState* exec, JSValue target, JSValue handler)
-{
- Base::finishCreation(vm);
- if (!target.isObject()) {
- throwTypeError(exec, ASCIILiteral("A Proxy's 'target' should be an Object"));
- return;
- }
- if (ProxyObject* targetAsProxy = jsDynamicCast<ProxyObject*>(target)) {
- // FIXME: Add tests for this once we implement Proxy.revoke(.).
- // https://bugs.webkit.org/show_bug.cgi?id=154321
- if (targetAsProxy->handler().isNull()) {
- throwTypeError(exec, ASCIILiteral("If a Proxy's handler is another Proxy object, the other Proxy object must have a non-null handler."));
- return;
- }
- }
- if (!handler.isObject()) {
- throwTypeError(exec, ASCIILiteral("A Proxy's 'handler' should be an Object"));
- return;
- }
-
- m_target.set(vm, this, jsCast<JSObject*>(target));
- m_handler.set(vm, this, handler);
-}
-
-static EncodedJSValue performProxyGet(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName)
-{
- VM& vm = exec->vm();
- JSObject* thisObject = jsCast<JSObject*>(JSValue::decode(thisValue)); // This might be a value where somewhere in __proto__ chain lives a ProxyObject.
- JSObject* proxyObjectAsObject = thisObject;
- // FIXME: make it so that custom getters take both the |this| value and the slotBase (property holder).
- // https://bugs.webkit.org/show_bug.cgi?id=154320
- while (true) {
- if (LIKELY(proxyObjectAsObject->inherits(ProxyObject::info())))
- break;
-
- Structure& structure = *vm.heap.structureIDTable().get(proxyObjectAsObject->structureID());
- JSValue prototype = structure.storedPrototype();
- RELEASE_ASSERT(prototype.isObject());
- proxyObjectAsObject = asObject(prototype);
- }
-
- ProxyObject* proxyObject = jsCast<ProxyObject*>(proxyObjectAsObject);
- JSValue handlerValue = proxyObject->handler();
- if (handlerValue.isNull())
- return throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
-
- JSObject* handler = jsCast<JSObject*>(handlerValue);
- CallData callData;
- CallType callType;
- JSValue getHandler = handler->getMethod(exec, callData, callType, vm.propertyNames->get, ASCIILiteral("'get' property of a Proxy's handler object should be callable."));
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- JSObject* target = proxyObject->target();
- if (getHandler.isUndefined())
- return JSValue::encode(target->get(exec, propertyName));
-
- MarkedArgumentBuffer arguments;
- arguments.append(target);
- arguments.append(identifierToSafePublicJSValue(vm, Identifier::fromUid(&vm, propertyName.uid())));
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- arguments.append(thisObject);
- JSValue trapResult = call(exec, getHandler, callType, callData, handler, arguments);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- PropertyDescriptor descriptor;
- if (target->getOwnPropertyDescriptor(exec, propertyName, descriptor)) {
- if (descriptor.isDataDescriptor() && !descriptor.configurable() && !descriptor.writable()) {
- if (!sameValue(exec, descriptor.value(), trapResult))
- return throwVMTypeError(exec, ASCIILiteral("Proxy handler's 'get' result of a non-configurable and non-writable property should be the same value as the target's property."));
- } else if (descriptor.isAccessorDescriptor() && !descriptor.configurable() && descriptor.getter().isUndefined()) {
- if (!trapResult.isUndefined())
- return throwVMTypeError(exec, ASCIILiteral("Proxy handler's 'get' result of a non-configurable accessor property without a getter should be undefined."));
- }
- }
-
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- return JSValue::encode(trapResult);
-}
-
-bool ProxyObject::performInternalMethodGetOwnProperty(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
- VM& vm = exec->vm();
- slot.setValue(this, None, jsUndefined()); // We do this to protect against any bad actors. Nobody should depend on this value.
- JSValue handlerValue = this->handler();
- if (handlerValue.isNull()) {
- throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
- return false;
- }
-
- JSObject* handler = jsCast<JSObject*>(handlerValue);
- CallData callData;
- CallType callType;
- JSValue getOwnPropertyDescriptorMethod = handler->getMethod(exec, callData, callType, makeIdentifier(vm, "getOwnPropertyDescriptor"), ASCIILiteral("'getOwnPropertyDescriptor' property of a Proxy's handler should be callable."));
- if (exec->hadException())
- return false;
- JSObject* target = this->target();
- if (getOwnPropertyDescriptorMethod.isUndefined())
- return target->methodTable(vm)->getOwnPropertySlot(target, exec, propertyName, slot);
-
- MarkedArgumentBuffer arguments;
- arguments.append(target);
- arguments.append(identifierToSafePublicJSValue(vm, Identifier::fromUid(&vm, propertyName.uid())));
- if (exec->hadException())
- return false;
- JSValue trapResult = call(exec, getOwnPropertyDescriptorMethod, callType, callData, handler, arguments);
- if (exec->hadException())
- return false;
-
- if (!trapResult.isUndefined() && !trapResult.isObject()) {
- throwVMTypeError(exec, ASCIILiteral("result of 'getOwnPropertyDescriptor' call should either be an Object or undefined."));
- return false;
- }
-
- PropertyDescriptor targetPropertyDescriptor;
- bool isTargetPropertyDescriptorDefined = target->getOwnPropertyDescriptor(exec, propertyName, targetPropertyDescriptor);
- if (exec->hadException())
- return false;
-
- if (trapResult.isUndefined()) {
- if (!isTargetPropertyDescriptorDefined)
- return false;
- if (!targetPropertyDescriptor.configurable()) {
- throwVMTypeError(exec, ASCIILiteral("When the result of 'getOwnPropertyDescriptor' is undefined the target must be configurable."));
- return false;
- }
- // FIXME: this doesn't work if 'target' is another Proxy. We don't have isExtensible implemented in a way that fits w/ Proxys.
- // https://bugs.webkit.org/show_bug.cgi?id=154375
- if (!target->isExtensible()) {
- // FIXME: Come up with a test for this error. I'm not sure how to because
- // Object.seal(o) will make all fields [[Configurable]] false.
- // https://bugs.webkit.org/show_bug.cgi?id=154376
- throwVMTypeError(exec, ASCIILiteral("When 'getOwnPropertyDescriptor' returns undefined, the 'target' of a Proxy should be extensible."));
- return false;
- }
-
- return false;
- }
-
- PropertyDescriptor trapResultAsDescriptor;
- toPropertyDescriptor(exec, trapResult, trapResultAsDescriptor);
- if (exec->hadException())
- return false;
- bool throwException = false;
- bool valid = validateAndApplyPropertyDescriptor(exec, nullptr, propertyName, target->isExtensible(),
- trapResultAsDescriptor, isTargetPropertyDescriptorDefined, targetPropertyDescriptor, throwException);
- if (!valid) {
- throwVMTypeError(exec, ASCIILiteral("Result from 'getOwnPropertyDescriptor' fails the IsCompatiblePropertyDescriptor test."));
- return false;
- }
-
- if (!trapResultAsDescriptor.configurable()) {
- if (!isTargetPropertyDescriptorDefined || targetPropertyDescriptor.configurable()) {
- throwVMTypeError(exec, ASCIILiteral("Result from 'getOwnPropertyDescriptor' can't be non-configurable when the 'target' doesn't have it as an own property or if it is a configurable own property on 'target'."));
- return false;
- }
- }
-
- return true;
-}
-
-bool ProxyObject::performHasProperty(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
- VM& vm = exec->vm();
- slot.setValue(this, None, jsUndefined()); // Nobody should rely on our value, but be safe and protect against any bad actors reading our value.
-
- JSValue handlerValue = this->handler();
- if (handlerValue.isNull()) {
- throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object."));
- return false;
- }
-
- JSObject* handler = jsCast<JSObject*>(handlerValue);
- CallData callData;
- CallType callType;
- JSValue hasMethod = handler->getMethod(exec, callData, callType, vm.propertyNames->has, ASCIILiteral("'has' property of a Proxy's handler should be callable."));
- if (exec->hadException())
- return false;
- JSObject* target = this->target();
- if (hasMethod.isUndefined())
- return target->methodTable(vm)->getOwnPropertySlot(target, exec, propertyName, slot);
-
- MarkedArgumentBuffer arguments;
- arguments.append(target);
- arguments.append(identifierToSafePublicJSValue(vm, Identifier::fromUid(&vm, propertyName.uid())));
- if (exec->hadException())
- return false;
- JSValue trapResult = call(exec, hasMethod, callType, callData, handler, arguments);
- if (exec->hadException())
- return false;
-
- bool trapResultAsBool = trapResult.toBoolean(exec);
- if (exec->hadException())
- return false;
-
- if (!trapResultAsBool) {
- PropertyDescriptor descriptor;
- bool isPropertyDescriptorDefined = target->getOwnPropertyDescriptor(exec, propertyName, descriptor);
- if (exec->hadException())
- return false;
- if (isPropertyDescriptorDefined) {
- if (!descriptor.configurable()) {
- throwVMTypeError(exec, ASCIILiteral("Proxy 'has' must return 'true' for non-configurable properties."));
- return false;
- }
- if (!target->isExtensible()) {
- throwVMTypeError(exec, ASCIILiteral("Proxy 'has' must return 'true' for a non-extensible 'target' object with a configurable property."));
- return false;
- }
- }
- }
-
- return trapResultAsBool;
-}
-
-bool ProxyObject::getOwnPropertySlotCommon(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
- slot.disableCaching();
- switch (slot.internalMethodType()) {
- case PropertySlot::InternalMethodType::Get:
- slot.setCustom(this, CustomAccessor, performProxyGet);
- return true;
- case PropertySlot::InternalMethodType::GetOwnProperty:
- return performInternalMethodGetOwnProperty(exec, propertyName, slot);
- case PropertySlot::InternalMethodType::HasProperty:
- return performHasProperty(exec, propertyName, slot);
- default:
- return false;
- }
-
- RELEASE_ASSERT_NOT_REACHED();
- return false;
-}
-
-bool ProxyObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
- ProxyObject* thisObject = jsCast<ProxyObject*>(object);
- return thisObject->getOwnPropertySlotCommon(exec, propertyName, slot);
-}
-
-bool ProxyObject::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
-{
- ProxyObject* thisObject = jsCast<ProxyObject*>(object);
- Identifier ident = Identifier::from(exec, propertyName);
- if (exec->hadException())
- return false;
- return thisObject->getOwnPropertySlotCommon(exec, ident.impl(), slot);
-}
-
-void ProxyObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
- ProxyObject* thisObject = jsCast<ProxyObject*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, info());
- Base::visitChildren(thisObject, visitor);
-
- visitor.append(&thisObject->m_target);
- visitor.append(&thisObject->m_handler);
-}
-
-} // namespace JSC