Encapsulate and protect all accesses to the vtable of Heap objects
[platform/upstream/qtdeclarative.git] / src / qml / jsruntime / qv4functionobject_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL21$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** $QT_END_LICENSE$
31 **
32 ****************************************************************************/
33 #ifndef QV4FUNCTIONOBJECT_H
34 #define QV4FUNCTIONOBJECT_H
35
36 #include "qv4object_p.h"
37 #include "qv4function_p.h"
38 #include "qv4context_p.h"
39 #include <private/qv4mm_p.h>
40
41 QT_BEGIN_NAMESPACE
42
43 struct QQmlSourceLocation;
44
45 namespace QV4 {
46
47 namespace Heap {
48
49 struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
50     enum {
51         Index_Prototype = 0,
52         Index_ProtoConstructor = 0
53     };
54
55     FunctionObject(QV4::ExecutionContext *scope, QV4::String *name, bool createProto = false);
56     FunctionObject(QV4::ExecutionContext *scope, QV4::Function *function, bool createProto = false);
57     FunctionObject(QV4::ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
58     FunctionObject(ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
59     FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name);
60     FunctionObject(ExecutionContext *scope, const ReturnedValue name);
61     FunctionObject(InternalClass *ic, QV4::Object *prototype);
62     ~FunctionObject();
63
64     unsigned int formalParameterCount() { return function ? function->compiledFunction->nFormals : 0; }
65     unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; }
66     bool needsActivation() const { return function ? function->needsActivation() : false; }
67
68     Pointer<ExecutionContext> scope;
69     Function *function;
70 };
71
72 struct FunctionCtor : FunctionObject {
73     FunctionCtor(QV4::ExecutionContext *scope);
74 };
75
76 struct FunctionPrototype : FunctionObject {
77     FunctionPrototype(InternalClass *ic, QV4::Object *prototype);
78 };
79
80 struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
81     BuiltinFunction(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *));
82     ReturnedValue (*code)(QV4::CallContext *);
83 };
84
85 struct IndexedBuiltinFunction : FunctionObject {
86     inline IndexedBuiltinFunction(QV4::ExecutionContext *scope, uint index, ReturnedValue (*code)(QV4::CallContext *ctx, uint index));
87     ReturnedValue (*code)(QV4::CallContext *, uint index);
88     uint index;
89 };
90
91 struct SimpleScriptFunction : FunctionObject {
92     enum {
93         Index_Name = FunctionObject::Index_Prototype + 1,
94         Index_Length
95     };
96     SimpleScriptFunction(QV4::ExecutionContext *scope, Function *function, bool createProto);
97 };
98
99 struct ScriptFunction : SimpleScriptFunction {
100     ScriptFunction(QV4::ExecutionContext *scope, Function *function);
101 };
102
103 struct BoundFunction : FunctionObject {
104     BoundFunction(QV4::ExecutionContext *scope, QV4::FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs);
105     Pointer<FunctionObject> target;
106     Value boundThis;
107     Pointer<MemberData> boundArgs;
108 };
109
110 }
111
112 struct Q_QML_EXPORT FunctionObject: Object {
113     enum {
114         IsFunctionObject = true
115     };
116     V4_OBJECT2(FunctionObject, Object)
117     Q_MANAGED_TYPE(FunctionObject)
118     V4_NEEDS_DESTROY
119
120     Heap::ExecutionContext *scope() const { return d()->scope; }
121     Function *function() const { return d()->function; }
122
123     ReturnedValue name() const;
124     unsigned int formalParameterCount() const { return d()->formalParameterCount(); }
125     unsigned int varCount() const { return d()->varCount(); }
126
127     void init(String *name, bool createProto);
128
129     ReturnedValue newInstance();
130
131     using Object::construct;
132     using Object::call;
133     static ReturnedValue construct(const Managed *that, CallData *);
134     static ReturnedValue call(const Managed *that, CallData *d);
135
136     static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
137
138     ReturnedValue protoProperty() { return memberData()->data[Heap::FunctionObject::Index_Prototype].asReturnedValue(); }
139
140     bool needsActivation() const { return d()->needsActivation(); }
141     bool strictMode() const { return d()->function ? d()->function->isStrict() : false; }
142     bool isBinding() const;
143     bool isBoundFunction() const;
144
145     QQmlSourceLocation sourceLocation() const;
146
147     static void markObjects(Heap::Base *that, ExecutionEngine *e);
148 };
149
150 template<>
151 inline const FunctionObject *Value::as() const {
152     return isManaged() && m() && m()->vtable()->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : 0;
153 }
154
155
156 struct FunctionCtor: FunctionObject
157 {
158     V4_OBJECT2(FunctionCtor, FunctionObject)
159
160     static ReturnedValue construct(const Managed *that, CallData *callData);
161     static ReturnedValue call(const Managed *that, CallData *callData);
162 };
163
164 struct FunctionPrototype: FunctionObject
165 {
166     V4_OBJECT2(FunctionPrototype, FunctionObject)
167
168     void init(ExecutionEngine *engine, Object *ctor);
169
170     static ReturnedValue method_toString(CallContext *ctx);
171     static ReturnedValue method_apply(CallContext *ctx);
172     static ReturnedValue method_call(CallContext *ctx);
173     static ReturnedValue method_bind(CallContext *ctx);
174 };
175
176 struct Q_QML_EXPORT BuiltinFunction: FunctionObject {
177     V4_OBJECT2(BuiltinFunction, FunctionObject)
178
179     static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
180     {
181         return scope->engine()->memoryManager->alloc<BuiltinFunction>(scope, name, code);
182     }
183
184     static ReturnedValue construct(const Managed *, CallData *);
185     static ReturnedValue call(const Managed *that, CallData *callData);
186 };
187
188 struct IndexedBuiltinFunction: FunctionObject
189 {
190     V4_OBJECT2(IndexedBuiltinFunction, FunctionObject)
191
192     static ReturnedValue construct(const Managed *m, CallData *)
193     {
194         return static_cast<const IndexedBuiltinFunction *>(m)->engine()->throwTypeError();
195     }
196
197     static ReturnedValue call(const Managed *that, CallData *callData);
198 };
199
200 Heap::IndexedBuiltinFunction::IndexedBuiltinFunction(QV4::ExecutionContext *scope, uint index,
201                                                      ReturnedValue (*code)(QV4::CallContext *ctx, uint index))
202     : Heap::FunctionObject(scope),
203       code(code)
204     , index(index)
205 {
206 }
207
208
209 struct SimpleScriptFunction: FunctionObject {
210     V4_OBJECT2(SimpleScriptFunction, FunctionObject)
211
212     static ReturnedValue construct(const Managed *, CallData *callData);
213     static ReturnedValue call(const Managed *that, CallData *callData);
214
215     Heap::Object *protoForConstructor();
216 };
217
218 struct ScriptFunction: SimpleScriptFunction {
219     V4_OBJECT2(ScriptFunction, FunctionObject)
220
221     static ReturnedValue construct(const Managed *, CallData *callData);
222     static ReturnedValue call(const Managed *that, CallData *callData);
223 };
224
225
226 struct BoundFunction: FunctionObject {
227     V4_OBJECT2(BoundFunction, FunctionObject)
228
229     static Heap::BoundFunction *create(ExecutionContext *scope, FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs)
230     {
231         return scope->engine()->memoryManager->alloc<BoundFunction>(scope, target, boundThis, boundArgs);
232     }
233
234     Heap::FunctionObject *target() const { return d()->target; }
235     Value boundThis() const { return d()->boundThis; }
236     Heap::MemberData *boundArgs() const { return d()->boundArgs; }
237
238     static ReturnedValue construct(const Managed *, CallData *d);
239     static ReturnedValue call(const Managed *that, CallData *dd);
240
241     static void markObjects(Heap::Base *that, ExecutionEngine *e);
242 };
243
244 }
245
246 QT_END_NAMESPACE
247
248 #endif // QMLJS_OBJECTS_H