1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39#ifndef QV4STACKFRAME_H
40#define QV4STACKFRAME_H
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists purely as an
47// implementation detail. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51//
52
53#include <private/qv4context_p.h>
54#include <private/qv4enginebase_p.h>
55#include <private/qv4calldata_p.h>
56#include <private/qv4function_p.h>
57
58QT_BEGIN_NAMESPACE
59
60namespace QV4 {
61
62struct Q_QML_EXPORT CppStackFrame {
63 EngineBase *engine;
64 Value *savedStackTop;
65 CppStackFrame *parent;
66 Function *v4Function;
67 CallData *jsFrame;
68 const Value *originalArguments;
69 int originalArgumentsCount;
70 int instructionPointer;
71 const char *yield;
72 const char *unwindHandler;
73 const char *unwindLabel;
74 int unwindLevel;
75 bool yieldIsIterator;
76 bool callerCanHandleTailCall;
77 bool pendingTailCall;
78 bool isTailCalling;
79
80 void init(EngineBase *engine, Function *v4Function, const Value *argv, int argc, bool callerCanHandleTailCall = false) {
81 this->engine = engine;
82
83 this->v4Function = v4Function;
84 originalArguments = argv;
85 originalArgumentsCount = argc;
86 instructionPointer = 0;
87 yield = nullptr;
88 unwindHandler = nullptr;
89 unwindLabel = nullptr;
90 unwindLevel = 0;
91 yieldIsIterator = false;
92 this->callerCanHandleTailCall = callerCanHandleTailCall;
93 pendingTailCall = false;
94 isTailCalling = false;
95 }
96
97 void push() {
98 parent = engine->currentStackFrame;
99 engine->currentStackFrame = this;
100 savedStackTop = engine->jsStackTop;
101 }
102
103 void pop() {
104 engine->currentStackFrame = parent;
105 engine->jsStackTop = savedStackTop;
106 }
107
108 static uint requiredJSStackFrameSize(uint nRegisters) {
109 return CallData::HeaderSize() + nRegisters;
110 }
111 static uint requiredJSStackFrameSize(Function *v4Function) {
112 return CallData::HeaderSize() + v4Function->compiledFunction->nRegisters;
113 }
114 uint requiredJSStackFrameSize() const {
115 return requiredJSStackFrameSize(v4Function);
116 }
117 void setupJSFrame(Value *stackSpace, const Value &function, const Heap::ExecutionContext *scope,
118 const Value &thisObject, const Value &newTarget = Value::undefinedValue()) {
119 setupJSFrame(stackSpace, function, scope, thisObject, newTarget,
120 nFormals: v4Function->compiledFunction->nFormals, nRegisters: v4Function->compiledFunction->nRegisters);
121 }
122 void setupJSFrame(Value *stackSpace, const Value &function, const Heap::ExecutionContext *scope,
123 const Value &thisObject, const Value &newTarget, uint nFormals, uint nRegisters)
124 {
125 jsFrame = reinterpret_cast<CallData *>(stackSpace);
126 jsFrame->function = function;
127 jsFrame->context = scope->asReturnedValue();
128 jsFrame->accumulator = Encode::undefined();
129 jsFrame->thisObject = thisObject;
130 jsFrame->newTarget = newTarget;
131
132 uint argc = uint(originalArgumentsCount);
133 if (argc > nFormals)
134 argc = nFormals;
135 jsFrame->setArgc(argc);
136
137 memcpy(dest: jsFrame->args, src: originalArguments, n: argc*sizeof(Value));
138 Q_STATIC_ASSERT(Encode::undefined() == 0);
139 memset(s: jsFrame->args + argc, c: 0, n: (nRegisters - argc)*sizeof(Value));
140
141 if (v4Function && v4Function->compiledFunction) {
142 const int firstDeadZoneRegister = v4Function->compiledFunction->firstTemporalDeadZoneRegister;
143 const int registerDeadZoneSize = v4Function->compiledFunction->sizeOfRegisterTemporalDeadZone;
144
145 const Value * tdzEnd = stackSpace + firstDeadZoneRegister + registerDeadZoneSize;
146 for (Value *v = stackSpace + firstDeadZoneRegister; v < tdzEnd; ++v)
147 *v = Value::emptyValue().asReturnedValue();
148 }
149 }
150
151 QString source() const;
152 QString function() const;
153 inline QV4::ExecutionContext *context() const {
154 return static_cast<ExecutionContext *>(&jsFrame->context);
155 }
156 int lineNumber() const;
157
158 inline QV4::Heap::CallContext *callContext() const {
159 Heap::ExecutionContext *ctx = static_cast<ExecutionContext &>(jsFrame->context).d();\
160 while (ctx->type != Heap::ExecutionContext::Type_CallContext)
161 ctx = ctx->outer;
162 return static_cast<Heap::CallContext *>(ctx);
163 }
164 ReturnedValue thisObject() const;
165};
166
167}
168
169QT_END_NAMESPACE
170
171#endif
172

source code of qtdeclarative/src/qml/jsruntime/qv4stackframe_p.h