1/* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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. 24 */ 25 26#ifndef JSDictionary_h 27#define JSDictionary_h 28 29#include "MessagePort.h" 30#include <heap/Strong.h> 31#include <heap/StrongInlines.h> 32#include <interpreter/CallFrame.h> 33#include <runtime/Operations.h> 34#include <wtf/Forward.h> 35 36namespace WebCore { 37 38class ArrayValue; 39class CSSFontFaceRule; 40class Dictionary; 41class DOMError; 42class DOMWindow; 43class EventTarget; 44class MediaKeyError; 45class MediaStream; 46class Node; 47class ScriptValue; 48class SerializedScriptValue; 49class Storage; 50class TrackBase; 51class VoidCallback; 52 53#if ENABLE(SCRIPTED_SPEECH) 54class SpeechRecognitionResultList; 55#endif 56 57class JSDictionary { 58public: 59 JSDictionary(JSC::ExecState* exec, JSC::JSObject* initializerObject) 60 : m_exec(exec) 61 { 62 if (exec && initializerObject) 63 m_initializerObject = JSC::Strong<JSC::JSObject>(exec->vm(), initializerObject); 64 } 65 66 // Returns false if any exceptions were thrown, regardless of whether the property was found. 67 template <typename Result> 68 bool tryGetProperty(const char* propertyName, Result&) const; 69 template <typename T, typename Result> 70 bool tryGetProperty(const char* propertyName, T* context, void (*setter)(T* context, const Result&)) const; 71 72 // Returns true if the property was found in the dictionary, and the value could be converted to the desired type. 73 template <typename Result> 74 bool get(const char* propertyName, Result&) const; 75 bool getWithUndefinedOrNullCheck(const String& propertyName, String& value) const; 76 77 JSC::ExecState* execState() const { return m_exec; } 78 JSC::JSObject* initializerObject() const { return m_initializerObject.get(); } 79 bool isValid() const { return m_exec && m_initializerObject; } 80 81private: 82 template <typename Result> 83 struct IdentitySetter { 84 static void identitySetter(Result* context, const Result& result) 85 { 86 *context = result; 87 } 88 }; 89 90 enum GetPropertyResult { 91 ExceptionThrown, 92 NoPropertyFound, 93 PropertyFound 94 }; 95 96 template <typename T, typename Result> 97 GetPropertyResult tryGetPropertyAndResult(const char* propertyName, T* context, void (*setter)(T* context, const Result&)) const; 98 GetPropertyResult tryGetProperty(const char* propertyName, JSC::JSValue&) const; 99 100 static void convertValue(JSC::ExecState*, JSC::JSValue, bool& result); 101 static void convertValue(JSC::ExecState*, JSC::JSValue, int& result); 102 static void convertValue(JSC::ExecState*, JSC::JSValue, unsigned& result); 103 static void convertValue(JSC::ExecState*, JSC::JSValue, unsigned short& result); 104 static void convertValue(JSC::ExecState*, JSC::JSValue, unsigned long& result); 105 static void convertValue(JSC::ExecState*, JSC::JSValue, unsigned long long& result); 106 static void convertValue(JSC::ExecState*, JSC::JSValue, double& result); 107 static void convertValue(JSC::ExecState*, JSC::JSValue, Dictionary& result); 108 static void convertValue(JSC::ExecState*, JSC::JSValue, String& result); 109 static void convertValue(JSC::ExecState*, JSC::JSValue, ScriptValue& result); 110 static void convertValue(JSC::ExecState*, JSC::JSValue, Vector<String>& result); 111 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<SerializedScriptValue>& result); 112 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<DOMWindow>& result); 113 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<EventTarget>& result); 114 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<Node>& result); 115 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<Storage>& result); 116 static void convertValue(JSC::ExecState*, JSC::JSValue, MessagePortArray& result); 117#if ENABLE(VIDEO_TRACK) 118 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<TrackBase>& result); 119#endif 120 static void convertValue(JSC::ExecState*, JSC::JSValue, HashSet<AtomicString>& result); 121 static void convertValue(JSC::ExecState*, JSC::JSValue, ArrayValue& result); 122 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<Uint8Array>& result); 123#if ENABLE(ENCRYPTED_MEDIA) 124 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<MediaKeyError>& result); 125#endif 126#if ENABLE(MEDIA_STREAM) 127 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<MediaStream>& result); 128#endif 129#if ENABLE(FONT_LOAD_EVENTS) 130 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<CSSFontFaceRule>& result); 131 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<DOMError>& result); 132 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<VoidCallback>& result); 133#endif 134#if ENABLE(SCRIPTED_SPEECH) 135 static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<SpeechRecognitionResultList>&); 136#endif 137 138 JSC::ExecState* m_exec; 139 JSC::Strong<JSC::JSObject> m_initializerObject; 140}; 141 142template <typename T, typename Result> 143bool JSDictionary::tryGetProperty(const char* propertyName, T* context, void (*setter)(T* context, const Result&)) const 144{ 145 return tryGetPropertyAndResult(propertyName, context, setter) != ExceptionThrown; 146} 147 148template <typename Result> 149bool JSDictionary::tryGetProperty(const char* propertyName, Result& finalResult) const 150{ 151 return tryGetPropertyAndResult(propertyName, &finalResult, IdentitySetter<Result>::identitySetter) != ExceptionThrown; 152} 153 154template <typename Result> 155bool JSDictionary::get(const char* propertyName, Result& finalResult) const 156{ 157 return tryGetPropertyAndResult(propertyName, &finalResult, IdentitySetter<Result>::identitySetter) == PropertyFound; 158} 159 160template <typename T, typename Result> 161JSDictionary::GetPropertyResult JSDictionary::tryGetPropertyAndResult(const char* propertyName, T* context, void (*setter)(T* context, const Result&)) const 162{ 163 JSC::JSValue value; 164 GetPropertyResult getPropertyResult = tryGetProperty(propertyName, value); 165 switch (getPropertyResult) { 166 case ExceptionThrown: 167 return getPropertyResult; 168 case PropertyFound: { 169 Result result; 170 convertValue(m_exec, value, result); 171 172 if (m_exec->hadException()) 173 return ExceptionThrown; 174 175 setter(context, result); 176 break; 177 } 178 case NoPropertyFound: 179 break; 180 } 181 182 return getPropertyResult; 183} 184 185} // namespace WebCore 186 187#endif // JSDictionary_h 188