KJS

ExecState.h
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 1999-2001 Harri Porten ([email protected])
4  * Copyright (C) 2001 Peter Kelly ([email protected])
5  * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
6  * Copyright (C) 2008 Maksim Orlovich ([email protected])
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB. If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24 
25 #ifndef ExecState_H
26 #define ExecState_H
27 
28 #include "completion.h"
29 #include "value.h"
30 #include "types.h"
31 #include "CommonIdentifiers.h"
32 #include "scope_chain.h"
33 #include "LocalStorage.h"
34 #include "wtf/Vector.h"
35 #include "PropertyNameArray.h"
36 
37 namespace KJS
38 {
39 class ActivationImp;
40 class Interpreter;
41 class FunctionImp;
42 class FunctionBodyNode;
43 class ProgramNode;
44 class JSGlobalObject;
45 
46 enum CodeType { GlobalCode, EvalCode, FunctionCode };
47 
48 /**
49  * Represents the current state of script execution. This object allows you
50  * obtain a handle the interpreter that is currently executing the script,
51  * and also the current execution context.
52  */
53 class KJS_EXPORT ExecState : Noncopyable
54 {
55  friend class Interpreter;
56  friend class FunctionImp;
57  friend class GlobalFuncImp;
58 public:
59  /**
60  * Returns the interpreter associated with this execution state
61  *
62  * @return The interpreter executing the script
63  */
65  {
66  return m_interpreter;
67  }
68 
69  /**
70  * Returns the interpreter associated with the current scope's
71  * global object
72  *
73  * @return The interpreter currently in scope
74  */
75  Interpreter *lexicalInterpreter() const;
76 
77  /**
78  * This describes how an exception should be handled
79  */
80  enum HandlerType {
81  JumpToCatch, ///< jump to the specified address
82  PopScope, ///< remove a scope chain entry, and run the next handler
83  RemoveDeferred, ///< remove any deferred exception object, and run the next entry
84  Silent ///< just update the exception object. For debugger-type use only
85  };
86 
87  void pushExceptionHandler(HandlerType type, Addr addr = 0);
88 
89  void popExceptionHandler();
90 
91  // Cleanup depth entries from the stack, w/o running jumps
92  void quietUnwind(int depth);
93 
94  void setMachineRegisters(const unsigned char *pcBase, const unsigned char **pcLoc, LocalStorageEntry **machineLocalStoreLoc)
95  {
96  m_pcBase = pcBase;
97  m_pc = pcLoc;
98  m_machineLocalStore = machineLocalStoreLoc;
99  }
100 
101  /**
102  The below methods deal with deferring of completions inside finally clauses.
103  Essentially, we clear any set exceptions and memorize any non-normal completion
104  (including the target addresses for the continue/break statements) on
105  the m_deferredCompletions stack. If the 'finally' finishes normally,
106  we will resume the previous completion. If not, finally's abnormal
107  termination is handled as usually; a RemoveDeferred cleanup stack
108  entry is added to unwind m_deferredCompletions if that happens.
109  */
110 
112  {
113  pushExceptionHandler(RemoveDeferred);
114  m_deferredCompletions.append(abruptCompletion());
115  clearException();
116  }
117 
118  /**
119  This resumes dispatch of a completion that was deferred due to a try ... finally,
120  handling it as appropriate for whether it's inside an another try-finally.
121  This will handle all the cases itself except for one: return,
122  for which it will return the value to return (otherwise returning 0)
123  */
124  JSValue *reactivateCompletion(bool insideTryFinally);
125 
126  /**
127  * Set the exception associated with this execution state,
128  * updating the program counter appropriately, and executing any relevant EH cleanups.
129  * @param e The JSValue of the exception being set
130  */
131  void setException(JSValue *e);
132 
133  /**
134  * Records an abrupt completion of code, and jumps to the closest catch or finally.
135  * This always happens for exceptions, but can also happen for continue/break/return when
136  * they're inside try ... finally, since that case gets routed through the EH machinery.
137  */
138  void setAbruptCompletion(Completion comp);
139 
140  /**
141  * Clears the exception or other abnormal completion set on this execution state.
142  */
144  {
145  m_completion = Completion();
146  }
147 
148  /**
149  * Returns the exception associated with this execution state.
150  * @return The current execution state exception
151  */
153  {
154  return m_completion.complType() == Throw ? m_completion.value() : nullptr;
155  }
156 
157  /**
158  * Use this to check if an exception was thrown in the current
159  * execution state.
160  *
161  * @return Whether an exception was thrown
162  */
163  bool hadException() const
164  {
165  return m_completion.complType() == Throw;
166  }
167 
168  Completion abruptCompletion() const
169  {
170  return m_completion;
171  }
172 
173  /**
174  * Returns the scope chain for this execution context. This is used for
175  * variable lookup, with the list being searched from start to end until a
176  * variable is found.
177  *
178  * @return The execution context's scope chain
179  */
180  const ScopeChain &scopeChain() const
181  {
182  return scope;
183  }
184 
185  /**
186  * Returns the variable object for the execution context. This contains a
187  * property for each variable declared in the execution context.
188  *
189  * @return The execution context's variable object
190  */
191  JSObject *variableObject() const
192  {
193  return m_variable;
194  }
195  void setVariableObject(JSObject *v)
196  {
197  m_variable = v;
198  }
199 
200  /**
201  * Returns the "this" value for the execution context. This is the value
202  * returned when a script references the special variable "this". It should
203  * always be an Object, unless application-specific code has passed in a
204  * different type.
205  *
206  * The object that is used as the "this" value depends on the type of
207  * execution context - for global contexts, the global object is used. For
208  * function objewcts, the value is given by the caller (e.g. in the case of
209  * obj.func(), obj would be the "this" value). For code executed by the
210  * built-in "eval" function, the this value is the same as the calling
211  * context.
212  *
213  * @return The execution context's "this" value
214  */
215  JSObject *thisValue() const
216  {
217  return m_thisVal;
218  }
219 
220  /**
221  * Returns the context from which the current context was invoked. For
222  * global code this will be a null context (i.e. one for which
223  * isNull() returns true). You should check isNull() on the returned
224  * value before calling any of its methods.
225  *
226  * @return The calling execution context
227  */
229  {
230  return m_callingExec;
231  }
232 
233  /**
234  * Returns the execState of a previous nested evaluation session, if any.
235  */
237  {
238  return m_savedExec;
239  }
240 
241  JSObject *activationObject()
242  {
243  assert(m_codeType == FunctionCode);
244  return m_variable;
245  }
246 
247  CodeType codeType()
248  {
249  return m_codeType;
250  }
251  FunctionBodyNode *currentBody()
252  {
253  return m_currentBody;
254  }
255  FunctionImp *function() const
256  {
257  return m_function;
258  }
259 
260  void pushVariableObjectScope(JSVariableObject *s)
261  {
262  scope.pushVariableObject(s);
263  }
264  void pushScope(JSObject *s)
265  {
266  scope.push(s);
267  }
268  void popScope()
269  {
270  scope.pop();
271  }
272 
273  void mark();
274 
275  void initLocalStorage(LocalStorageEntry *store, size_t size)
276  {
277  m_localStore = store;
278  m_localStoreSize = size;
279  }
280 
281  void updateLocalStorage(LocalStorageEntry *newStore)
282  {
283  m_localStore = newStore;
284  *m_machineLocalStore = newStore;
285  }
286 
287  LocalStorageEntry *localStorage()
288  {
289  return m_localStore;
290  }
291 
292  // This is a workaround to avoid accessing the global variables for these identifiers in
293  // important property lookup functions, to avoid taking PIC branches in Mach-O binaries
294  const CommonIdentifiers &propertyNames() const
295  {
296  return *m_propertyNames;
297  }
298 
299  // Compatibility stuff:
300  ExecState *context()
301  {
302  return this;
303  }
304  ExecState *callingContext()
305  {
306  return callingExecState();
307  }
308 protected:
309  ExecState(Interpreter *intp, ExecState *save);
310  ~ExecState();
311  void markSelf();
312 
313  Interpreter *m_interpreter;
314  Completion m_completion;
315  CommonIdentifiers *m_propertyNames;
316  ExecState *m_callingExec;
317  ExecState *m_savedExec; // in case of recursion of evaluation. Needed to mark things properly;
318  // note that this is disjoint from the above, since that's only used for
319  // eval/function, while this is for global.
320 
321  FunctionBodyNode *m_currentBody;
322  FunctionImp *m_function;
323 
324  ScopeChain scope;
325  JSObject *m_variable;
326  JSObject *m_thisVal;
327 
328  LocalStorageEntry *m_localStore;
329  size_t m_localStoreSize;
330 
331  struct ExceptionHandler {
332  ExceptionHandler() {}
333  ExceptionHandler(HandlerType type, Addr dest):
334  type(type), dest(dest) {}
335 
337  Addr dest;
338  };
339 
340  const unsigned char *m_pcBase; // The address of pc = 0
341  const unsigned char **m_pc; // Where the current fetch address is stored
342  LocalStorageEntry **m_machineLocalStore; // Machine's copy of m_localStore
343  WTF::Vector<ExceptionHandler, 4> m_exceptionHandlers;
344  WTF::Vector<Completion, 4> m_deferredCompletions;
345 
346  CodeType m_codeType;
347 };
348 
349 typedef ExecState Context; // Compatibility only
350 
351 class GlobalExecState : public ExecState
352 {
353 public:
354  GlobalExecState(Interpreter *intp, JSGlobalObject *global);
355 };
356 
357 class InterpreterExecState : public ExecState
358 {
359 public:
360  InterpreterExecState(Interpreter *intp, JSGlobalObject *global, JSObject *thisObject, ProgramNode *);
361 };
362 
363 class EvalExecState : public ExecState
364 {
365 public:
366  EvalExecState(Interpreter *intp, JSGlobalObject *global, ProgramNode *body, ExecState *callingExecState);
367 };
368 
369 // Note: this does not push the activation on the scope chain,
370 // as the activation is not initialized at this point.
371 class FunctionExecState : public ExecState
372 {
373 public:
374  FunctionExecState(Interpreter *intp, JSObject *thisObject,
375  FunctionBodyNode *, ExecState *callingExecState, FunctionImp *);
376 };
377 
378 } // namespace KJS
379 
380 #endif // ExecState_H
JSObject * thisValue() const
Returns the "this" value for the execution context.
Definition: ExecState.h:215
JSValue is the base type for all primitives (Undefined, Null, Boolean, String, Number) and objects in...
Definition: value.h:58
Type type(const QSqlDatabase &db)
virtual bool setException(ScriptableExtension *callerPrincipal, const QString &message)
bool hadException() const
Use this to check if an exception was thrown in the current execution state.
Definition: ExecState.h:163
@ PopScope
remove a scope chain entry, and run the next handler
Definition: ExecState.h:82
void(* HandlerType)(int)
Completion objects are used to convey the return status and value from functions.
Definition: completion.h:52
void clearException()
Clears the exception or other abnormal completion set on this execution state.
Definition: ExecState.h:143
JSObject * variableObject() const
Returns the variable object for the execution context.
Definition: ExecState.h:191
Represents the current state of script execution.
Definition: ExecState.h:53
void deferCompletion()
The below methods deal with deferring of completions inside finally clauses.
Definition: ExecState.h:111
Interpreter objects can be used to evaluate ECMAScript code.
Definition: interpreter.h:56
const ScopeChain & scopeChain() const
Returns the scope chain for this execution context.
Definition: ExecState.h:180
@ RemoveDeferred
remove any deferred exception object, and run the next entry
Definition: ExecState.h:83
@ JumpToCatch
jump to the specified address
Definition: ExecState.h:81
Implementation class for internal Functions.
Interpreter * dynamicInterpreter() const
Returns the interpreter associated with this execution state.
Definition: ExecState.h:64
ExecState * savedExecState()
Returns the execState of a previous nested evaluation session, if any.
Definition: ExecState.h:236
JSValue * exception() const
Returns the exception associated with this execution state.
Definition: ExecState.h:152
ExecState * callingExecState()
Returns the context from which the current context was invoked.
Definition: ExecState.h:228
HandlerType
This describes how an exception should be handled.
Definition: ExecState.h:80
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Wed May 25 2022 03:58:40 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.