+class WeakValueRef {
+public:
+ WeakValueRef()
+ : m_tag(NotSet)
+ {
+ }
+
+ ~WeakValueRef()
+ {
+ clear();
+ }
+
+ void clear()
+ {
+ switch (m_tag) {
+ case NotSet:
+ return;
+ case Primitive:
+ u.m_primitive = JSC::JSValue();
+ return;
+ case Object:
+ u.m_object.clear();
+ return;
+ case String:
+ u.m_string.clear();
+ return;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ bool isClear() const
+ {
+ switch (m_tag) {
+ case NotSet:
+ return true;
+ case Primitive:
+ return !u.m_primitive;
+ case Object:
+ return !u.m_object;
+ case String:
+ return !u.m_string;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ bool isSet() const { return m_tag != NotSet; }
+ bool isPrimitive() const { return m_tag == Primitive; }
+ bool isObject() const { return m_tag == Object; }
+ bool isString() const { return m_tag == String; }
+
+ void setPrimitive(JSC::JSValue primitive)
+ {
+ ASSERT(!isSet());
+ ASSERT(!u.m_primitive);
+ ASSERT(primitive.isPrimitive());
+ m_tag = Primitive;
+ u.m_primitive = primitive;
+ }
+
+ void setObject(JSC::JSObject* object, void* context)
+ {
+ ASSERT(!isSet());
+ ASSERT(!u.m_object);
+ m_tag = Object;
+ JSC::Weak<JSC::JSObject> weak(object, managedValueHandleOwner(), context);
+ u.m_object.swap(weak);
+ }
+
+ void setString(JSC::JSString* string, void* context)
+ {
+ ASSERT(!isSet());
+ ASSERT(!u.m_object);
+ m_tag = String;
+ JSC::Weak<JSC::JSString> weak(string, managedValueHandleOwner(), context);
+ u.m_string.swap(weak);
+ }
+
+ JSC::JSObject* object()
+ {
+ ASSERT(isObject());
+ return u.m_object.get();
+ }
+
+ JSC::JSValue primitive()
+ {
+ ASSERT(isPrimitive());
+ return u.m_primitive;
+ }
+
+ JSC::JSString* string()
+ {
+ ASSERT(isString());
+ return u.m_string.get();
+ }
+
+private:
+ enum WeakTypeTag { NotSet, Primitive, Object, String };
+ WeakTypeTag m_tag;
+ union WeakValueUnion {
+ public:
+ WeakValueUnion ()
+ : m_primitive(JSC::JSValue())
+ {
+ }
+
+ ~WeakValueUnion()
+ {
+ ASSERT(!m_primitive);
+ }
+
+ JSC::JSValue m_primitive;
+ JSC::Weak<JSC::JSObject> m_object;
+ JSC::Weak<JSC::JSString> m_string;
+ } u;
+};
+