• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "JavaScriptProfile.h"
28 
29 #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
30 
31 #include "JavaScriptProfileNode.h"
32 #include <profiler/Profile.h>
33 #include <JavaScriptCore/APICast.h>
34 #include <JavaScriptCore/JSObjectRef.h>
35 #include <JavaScriptCore/JSStringRef.h>
36 #include <JavaScriptCore/OpaqueJSString.h>
37 #include <runtime/JSObject.h>
38 #include <runtime/JSValue.h>
39 #include <wtf/StdLibExtras.h>
40 
41 using namespace JSC;
42 
43 namespace WebCore {
44 
45 // Cache
46 
47 typedef HashMap<Profile*, JSObject*> ProfileMap;
48 
profileCache()49 static ProfileMap& profileCache()
50 {
51     DEFINE_STATIC_LOCAL(ProfileMap, staticProfiles, ());
52     return staticProfiles;
53 }
54 
55 // Static Values
56 
57 static JSClassRef ProfileClass();
58 
getTitleCallback(JSContextRef ctx,JSObjectRef thisObject,JSStringRef,JSValueRef *)59 static JSValueRef getTitleCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
60 {
61     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
62         return JSValueMakeUndefined(ctx);
63 
64     Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
65     return JSValueMakeString(ctx, OpaqueJSString::create(profile->title()).get());
66 }
67 
getHeadCallback(JSContextRef ctx,JSObjectRef thisObject,JSStringRef,JSValueRef *)68 static JSValueRef getHeadCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
69 {
70     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
71         return JSValueMakeUndefined(ctx);
72 
73     ExecState* exec = toJS(ctx);
74     Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
75     return toRef(exec, toJS(exec, profile->head()));
76 }
77 
getUniqueIdCallback(JSContextRef ctx,JSObjectRef thisObject,JSStringRef,JSValueRef *)78 static JSValueRef getUniqueIdCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef, JSValueRef*)
79 {
80     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
81         return JSValueMakeUndefined(ctx);
82 
83     Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
84     return JSValueMakeNumber(ctx, profile->uid());
85 }
86 
87 // Static Functions
88 
focus(JSContextRef ctx,JSObjectRef,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef *)89 static JSValueRef focus(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
90 {
91     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
92         return JSValueMakeUndefined(ctx);
93 
94     if (argumentCount < 1)
95         return JSValueMakeUndefined(ctx);
96 
97     if (!JSValueIsObjectOfClass(ctx, arguments[0], ProfileNodeClass()))
98         return JSValueMakeUndefined(ctx);
99 
100     Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
101     profile->focus(static_cast<ProfileNode*>(JSObjectGetPrivate(const_cast<JSObjectRef>(arguments[0]))));
102 
103     return JSValueMakeUndefined(ctx);
104 }
105 
exclude(JSContextRef ctx,JSObjectRef,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef *)106 static JSValueRef exclude(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
107 {
108     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
109         return JSValueMakeUndefined(ctx);
110 
111     if (argumentCount < 1)
112         return JSValueMakeUndefined(ctx);
113 
114     if (!JSValueIsObjectOfClass(ctx, arguments[0], ProfileNodeClass()))
115         return JSValueMakeUndefined(ctx);
116 
117     Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
118     profile->exclude(static_cast<ProfileNode*>(JSObjectGetPrivate(const_cast<JSObjectRef>(arguments[0]))));
119 
120     return JSValueMakeUndefined(ctx);
121 }
122 
restoreAll(JSContextRef ctx,JSObjectRef,JSObjectRef thisObject,size_t,const JSValueRef[],JSValueRef *)123 static JSValueRef restoreAll(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments*/, JSValueRef* /*exception*/)
124 {
125     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileClass()))
126         return JSValueMakeUndefined(ctx);
127 
128     Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
129     profile->restoreAll();
130 
131     return JSValueMakeUndefined(ctx);
132 }
133 
finalize(JSObjectRef object)134 static void finalize(JSObjectRef object)
135 {
136     Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(object));
137     profileCache().remove(profile);
138     profile->deref();
139 }
140 
ProfileClass()141 JSClassRef ProfileClass()
142 {
143     static JSStaticValue staticValues[] = {
144         { "title", getTitleCallback, 0, kJSPropertyAttributeNone },
145         { "head", getHeadCallback, 0, kJSPropertyAttributeNone },
146         { "uid", getUniqueIdCallback, 0, kJSPropertyAttributeNone },
147         { 0, 0, 0, 0 }
148     };
149 
150     static JSStaticFunction staticFunctions[] = {
151         { "focus", focus, kJSPropertyAttributeNone },
152         { "exclude", exclude, kJSPropertyAttributeNone },
153         { "restoreAll", restoreAll, kJSPropertyAttributeNone },
154         { 0, 0, 0 }
155     };
156 
157     static JSClassDefinition classDefinition = {
158         0, kJSClassAttributeNone, "Profile", 0, staticValues, staticFunctions,
159         0, finalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
160     };
161 
162     static JSClassRef profileClass = JSClassCreate(&classDefinition);
163     return profileClass;
164 }
165 
toJS(ExecState * exec,Profile * profile)166 JSValue toJS(ExecState* exec, Profile* profile)
167 {
168     if (!profile)
169         return jsNull();
170 
171     JSObject* profileWrapper = profileCache().get(profile);
172     if (profileWrapper)
173         return profileWrapper;
174 
175     profile->ref();
176     profileWrapper = toJS(JSObjectMake(toRef(exec), ProfileClass(), static_cast<void*>(profile)));
177     profileCache().set(profile, profileWrapper);
178     return profileWrapper;
179 }
180 
181 } // namespace WebCore
182 
183 #endif // ENABLE(JAVASCRIPT_DEBUGGER)
184