2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file js_overlay_support.cpp
23 #include <dpl/log/log.h>
24 #include <dpl/foreach.h>
25 #include <JavaScriptCore/JavaScript.h>
27 #include <js_overlay_support.h>
29 namespace JSOverlaySupport {
30 class JSFunctionDispatcher
35 //required to unprotect object in destructor;
37 JSObjectPtr originalFunction;
38 JSObjectPtr overlayFunction;
41 static JSClassRef getClassRef();
44 static JSClassDefinition m_classInfo;
47 static void initialize(JSContextRef context, JSObjectRef object);
49 static void finalize(JSObjectRef object);
51 static JSValueRef callAsFunction(JSContextRef ctx,
53 JSObjectRef thisObject,
55 const JSValueRef arguments[],
56 JSValueRef* exception);
59 JSObjectPtr createWrappedFunction(
60 JSGlobalContextRef ctx,
61 const JSObjectPtr& originalFunction,
62 const JSObjectPtr& overlayFunction,
63 const std::string& name)
65 LogDebug("Creation overlay for function: " << name);
66 JSStringRef name_js = JSStringCreateWithUTF8CString(name.c_str());
68 JSFunctionDispatcher::PrivateData* priv =
69 new JSFunctionDispatcher::PrivateData;
71 priv->overlayFunction = overlayFunction;
72 priv->originalFunction = originalFunction;
74 auto fun = JSObjectMake(ctx, JSFunctionDispatcher::getClassRef(), priv);
76 JSStringRelease(name_js);
78 LogDebug("JSValueProtect invoked for: "
79 << overlayFunction->getObject() << " "
80 << originalFunction->getObject() << " Wrapper:"
83 //the value is unprotected in finalize of the JSFunctionDispatcher object
85 static_cast<JSObjectRef>(
86 overlayFunction->getObject()));
88 return JSObjectPtr(new JSObject(fun));
91 JSClassDefinition JSFunctionDispatcher::m_classInfo = {
93 kJSClassAttributeNone,
111 JSClassRef JSFunctionDispatcher::getClassRef()
113 static auto classRef = JSClassCreate(&m_classInfo);
117 void JSFunctionDispatcher::initialize(JSContextRef /*context*/,
118 JSObjectRef /*object*/)
120 LogDebug("Initialize");
123 void JSFunctionDispatcher::finalize(JSObjectRef object)
125 LogDebug("finalize");
127 PrivateData* priv = static_cast<PrivateData*>(JSObjectGetPrivate(object));
129 JSValueUnprotect(priv->context,
130 static_cast<JSObjectRef>(
131 priv->overlayFunction->getObject()));
136 JSValueRef JSFunctionDispatcher::callAsFunction(
137 JSContextRef context,
139 JSObjectRef thisObject,
140 size_t argumentCount,
141 const JSValueRef arguments[],
142 JSValueRef* exception)
144 LogDebug("Dispatcher invoked");
146 JSValueRef result = JSValueMakeUndefined(context);
148 JSFunctionDispatcher::PrivateData* priv =
149 static_cast<JSFunctionDispatcher::PrivateData*>
150 (JSObjectGetPrivate(object));
153 LogError("Private object is NULL");
157 //call overlayed function
158 if (priv->overlayFunction->getObject()) {
159 LogDebug("Overlayed function will be invoked...");
160 result = JSObjectCallAsFunction(
162 static_cast<JSObjectRef>(
163 priv->overlayFunction->getObject()),
170 //call original function
171 if (priv->originalFunction->getObject()) {
172 LogDebug("Original function will be invoked..");
173 result = JSObjectCallAsFunction(
175 static_cast<JSObjectRef>(
176 priv->originalFunction->getObject()),