diff options
Diffstat (limited to 'Source/WebCore/bindings/js/JSDOMBinding.h')
-rw-r--r-- | Source/WebCore/bindings/js/JSDOMBinding.h | 661 |
1 files changed, 16 insertions, 645 deletions
diff --git a/Source/WebCore/bindings/js/JSDOMBinding.h b/Source/WebCore/bindings/js/JSDOMBinding.h index 097ce6b26..34890157c 100644 --- a/Source/WebCore/bindings/js/JSDOMBinding.h +++ b/Source/WebCore/bindings/js/JSDOMBinding.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2003-2006, 2008-2009, 2013, 2016 Apple Inc. All rights reserved. * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> * Copyright (C) 2009 Google, Inc. All rights reserved. * Copyright (C) 2012 Ericsson AB. All rights reserved. @@ -21,653 +21,24 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef JSDOMBinding_h -#define JSDOMBinding_h +#pragma once -#include "JSDOMGlobalObject.h" -#include "JSDOMWrapper.h" -#include "DOMWrapperWorld.h" -#include "ScriptWrappable.h" -#include "ScriptWrappableInlines.h" -#include "WebCoreTypedArrayController.h" +// FIXME: Remove this header. + +#include "ExceptionOr.h" +#include "JSDOMWrapperCache.h" #include <cstddef> -#include <heap/Weak.h> -#include <heap/WeakInlines.h> -#include <runtime/Error.h> -#include <runtime/FunctionPrototype.h> +#include <heap/HeapInlines.h> +#include <heap/SlotVisitorInlines.h> +#include <runtime/AuxiliaryBarrierInlines.h> #include <runtime/JSArray.h> -#include <runtime/JSArrayBuffer.h> -#include <runtime/JSDataView.h> -#include <runtime/JSTypedArrays.h> +#include <runtime/JSCJSValueInlines.h> +#include <runtime/JSCellInlines.h> +#include <runtime/JSObjectInlines.h> #include <runtime/Lookup.h> -#include <runtime/ObjectPrototype.h> -#include <runtime/Operations.h> -#include <runtime/TypedArrayInlines.h> -#include <runtime/TypedArrays.h> +#include <runtime/ObjectConstructor.h> +#include <runtime/StructureInlines.h> +#include <runtime/WriteBarrier.h> #include <wtf/Forward.h> -#include <wtf/Noncopyable.h> +#include <wtf/GetPtr.h> #include <wtf/Vector.h> - -namespace JSC { -class HashEntry; -} - -namespace WebCore { - -class DOMStringList; - -class CachedScript; -class Document; -class DOMWindow; -class Frame; -class HTMLDocument; -class URL; -class Node; - -typedef int ExceptionCode; - -DOMWindow& activeDOMWindow(JSC::ExecState*); -DOMWindow& firstDOMWindow(JSC::ExecState*); - -// Base class for all constructor objects in the JSC bindings. -class DOMConstructorObject : public JSDOMWrapper { - typedef JSDOMWrapper Base; -public: - static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) - { - return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); - } - -protected: - static const unsigned StructureFlags = JSC::ImplementsHasInstance | JSC::OverridesVisitChildren | JSDOMWrapper::StructureFlags; - DOMConstructorObject(JSC::Structure* structure, JSDOMGlobalObject* globalObject) - : JSDOMWrapper(structure, globalObject) - { - } -}; - -JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*); -JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, JSC::Structure*, const JSC::ClassInfo*); - -inline JSDOMGlobalObject* deprecatedGlobalObjectForPrototype(JSC::ExecState* exec) -{ - // FIXME: Callers to this function should be using the global object - // from which the object is being created, instead of assuming the lexical one. - // e.g. subframe.document.body should use the subframe's global object, not the lexical one. - return JSC::jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()); -} - -template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::VM& vm, JSDOMGlobalObject* globalObject) -{ - if (JSC::Structure* structure = getCachedDOMStructure(globalObject, WrapperClass::info())) - return structure; - return cacheDOMStructure(globalObject, WrapperClass::createStructure(vm, globalObject, WrapperClass::createPrototype(vm, globalObject)), WrapperClass::info()); -} - -template<class WrapperClass> inline JSC::Structure* deprecatedGetDOMStructure(JSC::ExecState* exec) -{ - // FIXME: This function is wrong. It uses the wrong global object for creating the prototype structure. - return getDOMStructure<WrapperClass>(exec->vm(), deprecatedGlobalObjectForPrototype(exec)); -} - -template<class WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject) -{ - return JSC::jsCast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(vm, JSC::jsCast<JSDOMGlobalObject*>(globalObject))->storedPrototype())); -} - -inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld& world, JSC::ArrayBuffer*) -{ - return static_cast<WebCoreTypedArrayController*>(world.vm()->m_typedArrayController.get())->wrapperOwner(); -} - -inline void* wrapperContext(DOMWrapperWorld& world, JSC::ArrayBuffer*) -{ - return &world; -} - -inline JSDOMWrapper* getInlineCachedWrapper(DOMWrapperWorld&, void*) { return 0; } -inline bool setInlineCachedWrapper(DOMWrapperWorld&, void*, JSDOMWrapper*, JSC::WeakHandleOwner*, void*) { return false; } -inline bool clearInlineCachedWrapper(DOMWrapperWorld&, void*, JSDOMWrapper*) { return false; } - -inline JSDOMWrapper* getInlineCachedWrapper(DOMWrapperWorld& world, ScriptWrappable* domObject) -{ - if (!world.isNormal()) - return 0; - return domObject->wrapper(); -} - -inline JSC::JSArrayBuffer* getInlineCachedWrapper(DOMWrapperWorld& world, JSC::ArrayBuffer* buffer) -{ - if (!world.isNormal()) - return 0; - return buffer->m_wrapper.get(); -} - -inline bool setInlineCachedWrapper(DOMWrapperWorld& world, ScriptWrappable* domObject, JSDOMWrapper* wrapper, JSC::WeakHandleOwner* wrapperOwner, void* context) -{ - if (!world.isNormal()) - return false; - domObject->setWrapper(wrapper, wrapperOwner, context); - return true; -} - -inline bool setInlineCachedWrapper(DOMWrapperWorld& world, JSC::ArrayBuffer* domObject, JSC::JSArrayBuffer* wrapper, JSC::WeakHandleOwner* wrapperOwner, void* context) -{ - if (!world.isNormal()) - return false; - domObject->m_wrapper = JSC::Weak<JSC::JSArrayBuffer>(wrapper, wrapperOwner, context); - return true; -} - -inline bool clearInlineCachedWrapper(DOMWrapperWorld& world, ScriptWrappable* domObject, JSDOMWrapper* wrapper) -{ - if (!world.isNormal()) - return false; - domObject->clearWrapper(wrapper); - return true; -} - -inline bool clearInlineCachedWrapper(DOMWrapperWorld& world, JSC::ArrayBuffer* domObject, JSC::JSArrayBuffer* wrapper) -{ - if (!world.isNormal()) - return false; - weakClear(domObject->m_wrapper, wrapper); - return true; -} - -template <typename DOMClass> inline JSC::JSObject* getCachedWrapper(DOMWrapperWorld& world, DOMClass* domObject) -{ - if (JSC::JSObject* wrapper = getInlineCachedWrapper(world, domObject)) - return wrapper; - return world.m_wrappers.get(domObject); -} - -template <typename DOMClass, typename WrapperClass> inline void cacheWrapper(DOMWrapperWorld& world, DOMClass* domObject, WrapperClass* wrapper) -{ - JSC::WeakHandleOwner* owner = wrapperOwner(world, domObject); - void* context = wrapperContext(world, domObject); - if (setInlineCachedWrapper(world, domObject, wrapper, owner, context)) - return; - weakAdd(world.m_wrappers, (void*)domObject, JSC::Weak<JSC::JSObject>(wrapper, owner, context)); -} - -template <typename DOMClass, typename WrapperClass> inline void uncacheWrapper(DOMWrapperWorld& world, DOMClass* domObject, WrapperClass* wrapper) -{ - if (clearInlineCachedWrapper(world, domObject, wrapper)) - return; - weakRemove(world.m_wrappers, (void*)domObject, wrapper); -} - -#define CREATE_DOM_WRAPPER(exec, globalObject, className, object) createWrapper<JS##className>(exec, globalObject, static_cast<className*>(object)) -template<class WrapperClass, class DOMClass> inline JSDOMWrapper* createWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node) -{ - ASSERT(node); - ASSERT(!getCachedWrapper(currentWorld(exec), node)); - WrapperClass* wrapper = WrapperClass::create(getDOMStructure<WrapperClass>(exec->vm(), globalObject), globalObject, node); - // FIXME: The entire function can be removed, once we fix caching. - // This function is a one-off hack to make Nodes cache in the right global object. - cacheWrapper(currentWorld(exec), node, wrapper); - return wrapper; -} - -template<class WrapperClass, class DOMClass> inline JSC::JSValue wrap(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* domObject) -{ - if (!domObject) - return JSC::jsNull(); - if (JSC::JSObject* wrapper = getCachedWrapper(currentWorld(exec), domObject)) - return wrapper; - return createWrapper<WrapperClass>(exec, globalObject, domObject); -} - -template<class WrapperClass, class DOMClass> inline JSC::JSValue getExistingWrapper(JSC::ExecState* exec, DOMClass* domObject) -{ - ASSERT(domObject); - return getCachedWrapper(currentWorld(exec), domObject); -} - -template<class WrapperClass, class DOMClass> inline JSC::JSValue createNewWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* domObject) -{ - ASSERT(domObject); - ASSERT(!getCachedWrapper(currentWorld(exec), domObject)); - return createWrapper<WrapperClass>(exec, globalObject, domObject); -} - -inline JSC::JSValue argumentOrNull(JSC::ExecState* exec, unsigned index) -{ - return index >= exec->argumentCount() ? JSC::JSValue() : exec->argument(index); -} - -void addImpureProperty(const AtomicString&); - -const JSC::HashTable& getHashTableForGlobalData(JSC::VM&, const JSC::HashTable& staticTable); - -void reportException(JSC::ExecState*, JSC::JSValue exception, CachedScript* = 0); -void reportCurrentException(JSC::ExecState*); - -// Convert a DOM implementation exception code into a JavaScript exception in the execution state. -void setDOMException(JSC::ExecState*, ExceptionCode); - -JSC::JSValue jsStringWithCache(JSC::ExecState*, const String&); -JSC::JSValue jsString(JSC::ExecState*, const URL&); // empty if the URL is null -inline JSC::JSValue jsStringWithCache(JSC::ExecState* exec, const AtomicString& s) -{ - return jsStringWithCache(exec, s.string()); -} - -JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&); // null if the string is null -JSC::JSValue jsStringOrNull(JSC::ExecState*, const URL&); // null if the URL is null - -JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const String&); // undefined if the string is null -JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const URL&); // undefined if the URL is null - -// See JavaScriptCore for explanation: Should be used for any string that is already owned by another -// object, to let the engine know that collecting the JSString wrapper is unlikely to save memory. -JSC::JSValue jsOwnedStringOrNull(JSC::ExecState*, const String&); - -String propertyNameToString(JSC::PropertyName); - -AtomicString propertyNameToAtomicString(JSC::PropertyName); -AtomicStringImpl* findAtomicString(JSC::PropertyName); - -String valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null -String valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null or undefined - -inline int32_t finiteInt32Value(JSC::JSValue value, JSC::ExecState* exec, bool& okay) -{ - double number = value.toNumber(exec); - okay = std::isfinite(number); - return JSC::toInt32(number); -} - -enum IntegerConversionConfiguration { - NormalConversion, - EnforceRange, - // FIXME: Implement Clamp -}; - -int32_t toInt32EnforceRange(JSC::ExecState*, JSC::JSValue); -uint32_t toUInt32EnforceRange(JSC::ExecState*, JSC::JSValue); - -int8_t toInt8(JSC::ExecState*, JSC::JSValue, IntegerConversionConfiguration); -uint8_t toUInt8(JSC::ExecState*, JSC::JSValue, IntegerConversionConfiguration); - -int16_t toInt16(JSC::ExecState*, JSC::JSValue, IntegerConversionConfiguration); -uint16_t toUInt16(JSC::ExecState*, JSC::JSValue, IntegerConversionConfiguration); - -/* - Convert a value to an integer as per <http://www.w3.org/TR/WebIDL/>. - The conversion fails if the value cannot be converted to a number or, - if EnforceRange is specified, the value is outside the range of the - destination integer type. -*/ -inline int32_t toInt32(JSC::ExecState* exec, JSC::JSValue value, IntegerConversionConfiguration configuration) -{ - if (configuration == EnforceRange) - return toInt32EnforceRange(exec, value); - return value.toInt32(exec); -} - -inline uint32_t toUInt32(JSC::ExecState* exec, JSC::JSValue value, IntegerConversionConfiguration configuration) -{ - if (configuration == EnforceRange) - return toUInt32EnforceRange(exec, value); - return value.toUInt32(exec); -} - -int64_t toInt64(JSC::ExecState*, JSC::JSValue, IntegerConversionConfiguration); -uint64_t toUInt64(JSC::ExecState*, JSC::JSValue, IntegerConversionConfiguration); - -// Returns a Date instance for the specified value, or null if the value is NaN or infinity. -JSC::JSValue jsDateOrNull(JSC::ExecState*, double); -// NaN if the value can't be converted to a date. -double valueToDate(JSC::ExecState*, JSC::JSValue); - -// Validates that the passed object is a sequence type per section 4.1.13 of the WebIDL spec. -inline JSC::JSObject* toJSSequence(JSC::ExecState* exec, JSC::JSValue value, unsigned& length) -{ - JSC::JSObject* object = value.getObject(); - if (!object) { - throwVMError(exec, createTypeError(exec, "Value is not a sequence")); - return 0; - } - - JSC::JSValue lengthValue = object->get(exec, exec->propertyNames().length); - if (exec->hadException()) - return 0; - - if (lengthValue.isUndefinedOrNull()) { - throwVMError(exec, createTypeError(exec, "Value is not a sequence")); - return 0; - } - - length = lengthValue.toUInt32(exec); - if (exec->hadException()) - return 0; - - return object; -} - -inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, JSC::ArrayBuffer* buffer) -{ - if (!buffer) - return JSC::jsNull(); - if (JSC::JSValue result = getExistingWrapper<JSC::JSArrayBuffer>(exec, buffer)) - return result; - buffer->ref(); - JSC::JSArrayBuffer* wrapper = JSC::JSArrayBuffer::create(exec->vm(), globalObject->arrayBufferStructure(), buffer); - cacheWrapper(currentWorld(exec), buffer, wrapper); - return wrapper; -} - -inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, JSC::ArrayBufferView* view) -{ - if (!view) - return JSC::jsNull(); - return view->wrap(exec, globalObject); -} - -template <typename T> -inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<T> ptr) -{ - return toJS(exec, globalObject, ptr.get()); -} - -template <typename T> -inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<T>& vector) -{ - JSC::JSArray* array = constructEmptyArray(exec, 0, vector.size()); - - for (size_t i = 0; i < vector.size(); ++i) - array->putDirectIndex(exec, i, toJS(exec, globalObject, vector[i])); - - return array; -} - -template <typename T> -inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<RefPtr<T>>& vector) -{ - JSC::JSArray* array = constructEmptyArray(exec, 0, vector.size()); - - for (size_t i = 0; i < vector.size(); ++i) - array->putDirectIndex(exec, i, toJS(exec, globalObject, vector[i].get())); - - return array; -} - -inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject*, const String& value) -{ - return jsStringOrNull(exec, value); -} - -template <class T> -struct JSValueTraits { - static inline JSC::JSValue arrayJSValue(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, const T& value) - { - return toJS(exec, globalObject, WTF::getPtr(value)); - } -}; - -template<> -struct JSValueTraits<String> { - static inline JSC::JSValue arrayJSValue(JSC::ExecState* exec, JSDOMGlobalObject*, const String& value) - { - return jsStringWithCache(exec, value); - } -}; - -template<> -struct JSValueTraits<float> { - static inline JSC::JSValue arrayJSValue(JSC::ExecState*, JSDOMGlobalObject*, const float& value) - { - return JSC::jsNumber(value); - } -}; - -template<> -struct JSValueTraits<unsigned long> { - static inline JSC::JSValue arrayJSValue(JSC::ExecState*, JSDOMGlobalObject*, const unsigned long& value) - { - return JSC::jsNumber(value); - } -}; - -template <typename T, size_t inlineCapacity> -JSC::JSValue jsArray(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<T, inlineCapacity>& iterator) -{ - JSC::MarkedArgumentBuffer list; - typename Vector<T, inlineCapacity>::const_iterator end = iterator.end(); - typedef JSValueTraits<T> TraitsType; - - for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter) - list.append(TraitsType::arrayJSValue(exec, globalObject, *iter)); - - return JSC::constructArray(exec, 0, globalObject, list); -} - -JSC::JSValue jsArray(JSC::ExecState*, JSDOMGlobalObject*, PassRefPtr<DOMStringList>); - -inline PassRefPtr<JSC::ArrayBufferView> toArrayBufferView(JSC::JSValue value) -{ - JSC::JSArrayBufferView* wrapper = JSC::jsDynamicCast<JSC::JSArrayBufferView*>(value); - if (!wrapper) - return 0; - return wrapper->impl(); -} - -inline PassRefPtr<JSC::Int8Array> toInt8Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Int8Adaptor>(value); } -inline PassRefPtr<JSC::Int16Array> toInt16Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Int16Adaptor>(value); } -inline PassRefPtr<JSC::Int32Array> toInt32Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Int32Adaptor>(value); } -inline PassRefPtr<JSC::Uint8Array> toUint8Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Uint8Adaptor>(value); } -inline PassRefPtr<JSC::Uint8ClampedArray> toUint8ClampedArray(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Uint8ClampedAdaptor>(value); } -inline PassRefPtr<JSC::Uint16Array> toUint16Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Uint16Adaptor>(value); } -inline PassRefPtr<JSC::Uint32Array> toUint32Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Uint32Adaptor>(value); } -inline PassRefPtr<JSC::Float32Array> toFloat32Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Float32Adaptor>(value); } -inline PassRefPtr<JSC::Float64Array> toFloat64Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Float64Adaptor>(value); } - -inline PassRefPtr<JSC::DataView> toDataView(JSC::JSValue value) -{ - JSC::JSDataView* wrapper = JSC::jsDynamicCast<JSC::JSDataView*>(value); - if (!wrapper) - return 0; - return wrapper->typedImpl(); -} - -template<class T> struct NativeValueTraits; - -template<> -struct NativeValueTraits<String> { - static inline bool nativeValue(JSC::ExecState* exec, JSC::JSValue jsValue, String& indexedValue) - { - indexedValue = jsValue.toString(exec)->value(exec); - return true; - } -}; - -template<> -struct NativeValueTraits<unsigned> { - static inline bool nativeValue(JSC::ExecState* exec, JSC::JSValue jsValue, unsigned& indexedValue) - { - if (!jsValue.isNumber()) - return false; - - indexedValue = jsValue.toUInt32(exec); - if (exec->hadException()) - return false; - - return true; - } -}; - -template<> -struct NativeValueTraits<float> { - static inline bool nativeValue(JSC::ExecState* exec, JSC::JSValue jsValue, float& indexedValue) - { - indexedValue = jsValue.toFloat(exec); - return !exec->hadException(); - } -}; - -template <class T, class JST> -Vector<RefPtr<T>> toRefPtrNativeArray(JSC::ExecState* exec, JSC::JSValue value, T* (*toT)(JSC::JSValue value)) -{ - if (!isJSArray(value)) - return Vector<RefPtr<T>>(); - - Vector<RefPtr<T>> result; - JSC::JSArray* array = asArray(value); - size_t size = array->length(); - result.reserveInitialCapacity(size); - for (size_t i = 0; i < size; ++i) { - JSC::JSValue element = array->getIndex(exec, i); - if (element.inherits(JST::info())) - result.uncheckedAppend((*toT)(element)); - else { - throwVMError(exec, createTypeError(exec, "Invalid Array element type")); - return Vector<RefPtr<T>>(); - } - } - return result; -} - -template <class T> -Vector<T> toNativeArray(JSC::ExecState* exec, JSC::JSValue value) -{ - unsigned length = 0; - if (isJSArray(value)) { - JSC::JSArray* array = asArray(value); - length = array->length(); - } else - toJSSequence(exec, value, length); - - JSC::JSObject* object = value.getObject(); - Vector<T> result; - result.reserveInitialCapacity(length); - typedef NativeValueTraits<T> TraitsType; - - for (unsigned i = 0; i < length; ++i) { - T indexValue; - if (!TraitsType::nativeValue(exec, object->get(exec, i), indexValue)) - return Vector<T>(); - result.uncheckedAppend(indexValue); - } - return result; -} - -template <class T> -Vector<T> toNativeArguments(JSC::ExecState* exec, size_t startIndex = 0) -{ - size_t length = exec->argumentCount(); - ASSERT(startIndex <= length); - - Vector<T> result; - result.reserveInitialCapacity(length); - typedef NativeValueTraits<T> TraitsType; - - for (size_t i = startIndex; i < length; ++i) { - T indexValue; - if (!TraitsType::nativeValue(exec, exec->argument(i), indexValue)) - return Vector<T>(); - result.uncheckedAppend(indexValue); - } - return result; -} - -bool shouldAllowAccessToNode(JSC::ExecState*, Node*); -bool shouldAllowAccessToFrame(JSC::ExecState*, Frame*); -bool shouldAllowAccessToFrame(JSC::ExecState*, Frame*, String& message); -bool shouldAllowAccessToDOMWindow(JSC::ExecState*, DOMWindow&, String& message); - -void printErrorMessageForFrame(Frame*, const String& message); -JSC::EncodedJSValue objectToStringFunctionGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::PropertyName); - -inline JSC::JSValue jsStringWithCache(JSC::ExecState* exec, const String& s) -{ - StringImpl* stringImpl = s.impl(); - if (!stringImpl || !stringImpl->length()) - return jsEmptyString(exec); - - if (stringImpl->length() == 1) { - UChar singleCharacter = (*stringImpl)[0u]; - if (singleCharacter <= JSC::maxSingleCharacterString) { - JSC::VM* vm = &exec->vm(); - return vm->smallStrings.singleCharacterString(static_cast<unsigned char>(singleCharacter)); - } - } - - JSStringCache& stringCache = currentWorld(exec).m_stringCache; - JSStringCache::AddResult addResult = stringCache.add(stringImpl, nullptr); - if (addResult.isNewEntry) - addResult.iterator->value = JSC::jsString(exec, String(stringImpl)); - return JSC::JSValue(addResult.iterator->value.get()); -} - -inline String propertyNameToString(JSC::PropertyName propertyName) -{ - return propertyName.publicName(); -} - -inline AtomicString propertyNameToAtomicString(JSC::PropertyName propertyName) -{ - return AtomicString(propertyName.publicName()); -} - -template <class ThisImp> -inline const JSC::HashEntry* getStaticValueSlotEntryWithoutCaching(JSC::ExecState* exec, JSC::PropertyName propertyName) -{ - const JSC::HashEntry* entry = ThisImp::info()->propHashTable(exec)->entry(exec, propertyName); - if (!entry) // not found, forward to parent - return getStaticValueSlotEntryWithoutCaching<typename ThisImp::Base>(exec, propertyName); - return entry; -} - -template <> -inline const JSC::HashEntry* getStaticValueSlotEntryWithoutCaching<JSDOMWrapper>(JSC::ExecState*, JSC::PropertyName) -{ - return 0; -} - -template<typename T> -class HasMemoryCostMemberFunction { - typedef char YesType; - struct NoType { - char padding[8]; - }; - - template<typename U> - static decltype(static_cast<U*>(nullptr)->memoryCost(), YesType()) test(int); - - template<typename U> - static NoType test(...); - -public: - static const bool value = sizeof(test<T>(0)) == sizeof(YesType); -}; - -template <typename T, bool hasReportCostFunction = HasMemoryCostMemberFunction<T>::value > struct ReportMemoryCost; -template <typename T> struct ReportMemoryCost<T, true> { - static void reportMemoryCost(JSC::ExecState* exec, T* impl) - { - exec->heap()->reportExtraMemoryCost(impl->memoryCost()); - } -}; -template <typename T> struct ReportMemoryCost<T, false> { - static void reportMemoryCost(JSC::ExecState*, T*) - { - } -}; - -enum SecurityReportingOption { - DoNotReportSecurityError, - ReportSecurityError, -}; - -class BindingSecurity { -public: - static bool shouldAllowAccessToNode(JSC::ExecState*, Node*); - static bool shouldAllowAccessToDOMWindow(JSC::ExecState*, DOMWindow&, SecurityReportingOption = ReportSecurityError); - static bool shouldAllowAccessToFrame(JSC::ExecState*, Frame*, SecurityReportingOption = ReportSecurityError); -}; - -} // namespace WebCore - -#endif // JSDOMBinding_h |