Reviewed by Eric.
[WebKit-https.git] / JavaScriptGlue / JSValueWrapper.cpp
1 //
2 // JSValueWrapper.cpp
3 //
4 #include "JSValueWrapper.h"
5 #include "JavaScriptCore/IdentifierSequencedSet.h"
6
7 JSValueWrapper::JSValueWrapper(ValueImp *inValue, ExecState *inExec)
8     : fValue(inValue), fExec(inExec)
9 {
10 }
11
12 JSValueWrapper::~JSValueWrapper()
13 {
14 }
15
16 ValueImp *JSValueWrapper::GetValue()
17 {
18     return fValue;
19 }
20 ExecState* JSValueWrapper::GetExecState() const
21 {
22     return fExec;
23 }
24
25
26 void JSValueWrapper::GetJSObectCallBacks(JSObjectCallBacks& callBacks)
27 {
28     callBacks.dispose = (JSObjectDisposeProcPtr)JSValueWrapper::JSObjectDispose;
29     callBacks.equal = (JSObjectEqualProcPtr)0;
30     callBacks.copyPropertyNames = (JSObjectCopyPropertyNamesProcPtr)JSValueWrapper::JSObjectCopyPropertyNames;
31     callBacks.copyCFValue = (JSObjectCopyCFValueProcPtr)JSValueWrapper::JSObjectCopyCFValue;
32     callBacks.copyProperty = (JSObjectCopyPropertyProcPtr)JSValueWrapper::JSObjectCopyProperty;
33     callBacks.setProperty = (JSObjectSetPropertyProcPtr)JSValueWrapper::JSObjectSetProperty;
34     callBacks.callFunction = (JSObjectCallFunctionProcPtr)JSValueWrapper::JSObjectCallFunction;
35 }
36
37 void JSValueWrapper::JSObjectDispose(void *data)
38 {
39     JSValueWrapper* ptr = (JSValueWrapper*)data;
40     delete ptr;
41 }
42
43
44 CFArrayRef JSValueWrapper::JSObjectCopyPropertyNames(void *data)
45 {
46     InterpreterLock lock;
47
48     CFMutableArrayRef result = 0;
49     JSValueWrapper* ptr = (JSValueWrapper*)data;
50     if (ptr)
51     {
52         ExecState* exec = ptr->GetExecState();
53         ObjectImp *object = ptr->GetValue()->toObject(exec);
54         IdentifierSequencedSet list;
55                 object->getPropertyNames(exec, list);
56         IdentifierSequencedSetIterator iterator = list.begin();
57
58         while (iterator != list.end()) {
59             Identifier name = *iterator;
60             CFStringRef nameStr = IdentifierToCFString(name);
61
62             if (!result)
63             {
64                 result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
65             }
66             if (result && nameStr)
67             {
68                 CFArrayAppendValue(result, nameStr);
69             }
70             ReleaseCFType(nameStr);
71             ++iterator;
72         }
73
74     }
75     return result;
76 }
77
78
79 JSObjectRef JSValueWrapper::JSObjectCopyProperty(void *data, CFStringRef propertyName)
80 {
81     InterpreterLock lock;
82
83     JSObjectRef result = 0;
84     JSValueWrapper* ptr = (JSValueWrapper*)data;
85     if (ptr)
86     {
87         ExecState* exec = ptr->GetExecState();
88         ValueImp *propValue = ptr->GetValue()->toObject(exec)->get(exec, CFStringToIdentifier(propertyName));
89         JSValueWrapper* wrapperValue = new JSValueWrapper(propValue, exec);
90
91         JSObjectCallBacks callBacks;
92         GetJSObectCallBacks(callBacks);
93         result = JSObjectCreateInternal(wrapperValue, &callBacks, JSValueWrapper::JSObjectMark, kJSUserObjectDataTypeJSValueWrapper);
94
95         if (!result)
96         {
97             delete wrapperValue;
98         }
99     }
100     return result;
101 }
102
103 void JSValueWrapper::JSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue)
104 {
105     InterpreterLock lock;
106
107     JSValueWrapper* ptr = (JSValueWrapper*)data;
108     if (ptr)
109     {
110         ExecState* exec = ptr->GetExecState();
111         ValueImp *value = JSObjectKJSValue((JSUserObject*)jsValue);
112         ObjectImp *objValue = ptr->GetValue()->toObject(exec);
113         objValue->put(exec, CFStringToIdentifier(propertyName), value);
114     }
115 }
116
117 JSObjectRef JSValueWrapper::JSObjectCallFunction(void *data, JSObjectRef thisObj, CFArrayRef args)
118 {
119     InterpreterLock lock;
120
121     JSObjectRef result = 0;
122     JSValueWrapper* ptr = (JSValueWrapper*)data;
123     if (ptr)
124     {
125         ExecState* exec = ptr->GetExecState();
126
127         ValueImp *value = JSObjectKJSValue((JSUserObject*)thisObj);
128         ObjectImp *ksjThisObj = value->toObject(exec);
129         ObjectImp *objValue = ptr->GetValue()->toObject(exec);
130
131         List listArgs;
132         CFIndex argCount = args ? CFArrayGetCount(args) : 0;
133         for (CFIndex i = 0; i < argCount; i++)
134         {
135             JSObjectRef jsArg = (JSObjectRef)CFArrayGetValueAtIndex(args, i);
136             ValueImp *kgsArg = JSObjectKJSValue((JSUserObject*)jsArg);
137             listArgs.append(kgsArg);
138         }
139
140         ValueImp *resultValue = objValue->call(exec, ksjThisObj, listArgs);
141         JSValueWrapper* wrapperValue = new JSValueWrapper(resultValue, ptr->GetExecState());
142         JSObjectCallBacks callBacks;
143         GetJSObectCallBacks(callBacks);
144         result = JSObjectCreate(wrapperValue, &callBacks);
145         if (!result)
146         {
147             delete wrapperValue;
148         }
149     }
150     return result;
151 }
152
153 CFTypeRef JSValueWrapper::JSObjectCopyCFValue(void *data)
154 {
155     InterpreterLock lock;
156
157     CFTypeRef result = 0;
158     JSValueWrapper* ptr = (JSValueWrapper*)data;
159     if (ptr)
160     {
161         result = KJSValueToCFType(ptr->fValue, ptr->fExec);
162     }
163     return result;
164 }
165
166 void JSValueWrapper::JSObjectMark(void *data)
167 {
168     JSValueWrapper* ptr = (JSValueWrapper*)data;
169     if (ptr)
170     {
171         ptr->fValue->mark();
172     }
173 }