Qt 4.8
qscriptfunction.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtScript module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser
11 ** General Public License version 2.1 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.LGPL included in the
13 ** packaging of this file. Please review the following information to
14 ** ensure the GNU Lesser General Public License version 2.1 requirements
15 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** If you have questions regarding the use of this file, please contact
18 ** us via http://www.qt-project.org/.
19 **
20 ** $QT_END_LICENSE$
21 **
22 ****************************************************************************/
23 
24 #include "config.h"
25 #include "qscriptfunction_p.h"
26 
27 #include "private/qscriptengine_p.h"
28 #include "qscriptcontext.h"
29 #include "private/qscriptcontext_p.h"
30 #include "private/qscriptvalue_p.h"
32 #include "qscriptobject_p.h"
33 
34 #include "JSGlobalObject.h"
35 #include "DebuggerCallFrame.h"
36 #include "Debugger.h"
37 
38 namespace JSC
39 {
42 }
43 
45 
46 namespace QScript
47 {
48 
49 const JSC::ClassInfo FunctionWrapper::info = { "QtNativeFunctionWrapper", &PrototypeFunction::info, 0, 0 };
50 const JSC::ClassInfo FunctionWithArgWrapper::info = { "QtNativeFunctionWithArgWrapper", &PrototypeFunction::info, 0, 0 };
51 
52 FunctionWrapper::FunctionWrapper(JSC::ExecState *exec, int length, const JSC::Identifier &name,
54  : JSC::PrototypeFunction(exec, length, name, proxyCall),
55  data(new Data())
56 {
57  data->function = function;
58 }
59 
61 {
62  delete data;
63 }
64 
65 JSC::ConstructType FunctionWrapper::getConstructData(JSC::ConstructData& consData)
66 {
67  consData.native.function = proxyConstruct;
68  consData.native.function.doNotCallDebuggerFunctionExit();
69  return JSC::ConstructTypeHost;
70 }
71 
72 JSC::JSValue FunctionWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObject *callee,
73  JSC::JSValue thisObject, const JSC::ArgList &args)
74 {
75  FunctionWrapper *self = static_cast<FunctionWrapper*>(callee);
77 
78  JSC::ExecState *oldFrame = eng_p->currentFrame;
79  eng_p->pushContext(exec, thisObject, args, callee);
81 
82  QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p));
83  if (!result.isValid())
85 
86  eng_p->popContext();
87  eng_p->currentFrame = oldFrame;
88 
89  return eng_p->scriptValueToJSCValue(result);
90 }
91 
92 JSC::JSObject* FunctionWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee,
93  const JSC::ArgList &args)
94 {
95  FunctionWrapper *self = static_cast<FunctionWrapper*>(callee);
97 
98  JSC::ExecState *oldFrame = eng_p->currentFrame;
99  eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
101 
102  QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p));
103 
104  if (JSC::Debugger* debugger = eng_p->originalGlobalObject()->debugger())
105  debugger->functionExit(QScriptValuePrivate::get(result)->jscValue, -1);
106 
107  if (!result.isObject())
108  result = ctx->thisObject();
109 
110  eng_p->popContext();
111  eng_p->currentFrame = oldFrame;
112 
113  return JSC::asObject(eng_p->scriptValueToJSCValue(result));
114 }
115 
116 FunctionWithArgWrapper::FunctionWithArgWrapper(JSC::ExecState *exec, int length, const JSC::Identifier &name,
117  QScriptEngine::FunctionWithArgSignature function, void *arg)
118  : JSC::PrototypeFunction(exec, length, name, proxyCall),
119  data(new Data())
120 {
121  data->function = function;
122  data->arg = arg;
123 }
124 
126 {
127  delete data;
128 }
129 
130 JSC::ConstructType FunctionWithArgWrapper::getConstructData(JSC::ConstructData& consData)
131 {
132  consData.native.function = proxyConstruct;
133  return JSC::ConstructTypeHost;
134 }
135 
136 JSC::JSValue FunctionWithArgWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObject *callee,
137  JSC::JSValue thisObject, const JSC::ArgList &args)
138 {
139  FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee);
141 
142  JSC::ExecState *oldFrame = eng_p->currentFrame;
143  eng_p->pushContext(exec, thisObject, args, callee);
145 
146  QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p), self->data->arg);
147 
148  eng_p->popContext();
149  eng_p->currentFrame = oldFrame;
150 
151  return eng_p->scriptValueToJSCValue(result);
152 }
153 
154 JSC::JSObject* FunctionWithArgWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee,
155  const JSC::ArgList &args)
156 {
157  FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee);
159 
160  JSC::ExecState *oldFrame = eng_p->currentFrame;
161  eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
163 
164  QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p) , self->data->arg);
165  if (!result.isObject())
166  result = ctx->thisObject();
167 
168  eng_p->popContext();
169  eng_p->currentFrame = oldFrame;
170 
171  return JSC::asObject(eng_p->scriptValueToJSCValue(result));
172 }
173 
174 } // namespace QScript
175 
The QScriptContext class represents a Qt Script function invocation.
QScriptValue(* FunctionSignature)(QScriptContext *, QScriptEngine *)
QScriptEnginePrivate * scriptEngineFromExec(const JSC::ExecState *exec)
static mach_timebase_info_data_t info
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static QScriptEnginePrivate * get(QScriptEngine *q)
ASSERT_CLASS_FITS_IN_CELL(::QScript::QScriptActivationObject)
static JSC::JSObject * proxyConstruct(JSC::ExecState *, JSC::JSObject *, const JSC::ArgList &)
JSC::CallFrame * pushContext(JSC::CallFrame *exec, JSC::JSValue thisObject, const JSC::ArgList &args, JSC::JSObject *callee, bool calledAsConstructor=false, bool clearScopeChain=false)
JSC native function doesn&#39;t have different stackframe or context.
static QScriptValuePrivate * get(const QScriptValue &q)
QScriptEngine::FunctionSignature function
JSC::ExecState * currentFrame
QScriptValue(* FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *)
FunctionWithArgWrapper(JSC::ExecState *, int length, const JSC::Identifier &, QScriptEngine::FunctionWithArgSignature, void *)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
JSC::JSValue scriptValueToJSCValue(const QScriptValue &value)
static QScriptContext * contextForFrame(JSC::ExecState *frame)
JSC::JSGlobalObject * originalGlobalObject() const
const char * name
virtual JSC::ConstructType getConstructData(JSC::ConstructData &)
#define QT_PREPEND_NAMESPACE(name)
This macro qualifies identifier with the full namespace.
Definition: qglobal.h:87
static const char * data(const QByteArray &arr)
QScriptEngine::FunctionWithArgSignature function
static JSC::JSObject * proxyConstruct(JSC::ExecState *, JSC::JSObject *, const JSC::ArgList &)
static JSC::JSValue JSC_HOST_CALL proxyCall(JSC::ExecState *, JSC::JSObject *, JSC::JSValue, const JSC::ArgList &)
QScriptValue data() const
Returns the internal data of this QScriptValue object.
#define ctx
Definition: qgl.cpp:6094
JSC::JSValue jscValue
static JSC::JSValue JSC_HOST_CALL proxyCall(JSC::ExecState *, JSC::JSObject *, JSC::JSValue, const JSC::ArgList &)
QScriptValue thisObject() const
Returns the `this&#39; object associated with this QScriptContext.
The QScriptValue class acts as a container for the Qt Script data types.
Definition: qscriptvalue.h:57
bool isValid() const
Returns true if this QScriptValue is valid; otherwise returns false.
bool isObject() const
Returns true if this QScriptValue is of the Object type; otherwise returns false. ...
virtual JSC::ConstructType getConstructData(JSC::ConstructData &)