KJS

kjsinterpreter.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2008 Harri Porten ([email protected])
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21 
22 #include "kjsinterpreter.h"
23 #include "kjsprivate.h"
24 #include "kjs/interpreter.h"
25 #include "kjs/completion.h"
26 #include "kjs/object.h"
27 #include "kjs/JSVariableObject.h"
28 #include <QString>
29 #include <stdio.h>
30 
31 using namespace KJS;
32 
33 class KJSResultHandle
34 {
35 public:
36  KJSResultHandle() : rc(1), val(KJSUndefined()) { }
37 
38  int rc;
39  KJSObject val;
40  UString errMsg;
41 
42  void ref()
43  {
44  ++rc;
45  }
46  void deref()
47  {
48  if (--rc == 0) {
49  delete this;
50  }
51  }
52 };
53 
55  : hnd(new KJSResultHandle())
56 {
57 }
58 
60 {
61  hnd = r.hnd;
62  hnd->ref();
63 }
64 
66 {
67  if (hnd != r.hnd) {
68  r.hnd->ref();
69  hnd->deref();
70  hnd = r.hnd;
71  }
72 
73  return *this;
74 }
75 
77 {
78  hnd->deref();
79 }
80 
82 {
83  return !hnd->errMsg.isNull();
84 }
85 
87 {
88  return toQString(hnd->errMsg);
89 }
90 
91 KJSObject KJSResult::value() const
92 {
93  return hnd->val;
94 }
95 
97  : globCtx(nullptr)
98 {
99  Interpreter *ip = new Interpreter();
100  ip->ref();
101  hnd = INTERPRETER_HANDLE(ip);
102 }
103 
105  : globCtx(nullptr)
106 {
107  JSValue *gv = JSVALUE(&global);
108  assert(JSValue::isObject(gv));
109  JSObject *go = static_cast<JSObject *>(gv);
110  assert(go->isGlobalObject());
111  Interpreter *ip = new Interpreter(static_cast<JSGlobalObject *>(go));
112  ip->ref();
113  assert(JSValue::isObject(go->prototype()));
114  JSObject *p = static_cast<JSObject *>(go->prototype());
115  JSObject *objectProto = ip->builtinObjectPrototype();
116  p->setPrototype(objectProto);
117  hnd = INTERPRETER_HANDLE(ip);
118 }
119 
121  : globCtx(nullptr)
122 {
123  Interpreter *ip = INTERPRETER(&other);
124  ip->ref();
125  hnd = INTERPRETER_HANDLE(ip);
126  globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec());
127 }
128 
130 {
131  Interpreter *thisIp = INTERPRETER(this);
132  Interpreter *otherIp = INTERPRETER(&other);
133  if (otherIp != thisIp) {
134  otherIp->ref();
135  thisIp->deref();
136  hnd = INTERPRETER_HANDLE(otherIp);
137  globCtx.hnd = EXECSTATE_HANDLE(otherIp->globalExec());
138  }
139  return *this;
140 }
141 
142 KJSInterpreter::KJSInterpreter(KJSInterpreterHandle *h)
143  : hnd(h), globCtx(nullptr)
144 {
145  Interpreter *ip = INTERPRETER(this);
146  ip->ref();
147  globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec());
148 }
149 
151 {
152  Interpreter *ip = INTERPRETER(this);
153  ip->deref();
154  ip = nullptr;
155 }
156 
158 {
159  Interpreter *ip = INTERPRETER(this);
160 
161  globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec());
162  return &globCtx;
163 }
164 
166 {
167  Interpreter *ip = INTERPRETER(this);
168 
169  return KJSObject(JSVALUE_HANDLE(ip->globalObject()));
170 }
171 
173  int startingLineNumber,
174  const QString &code,
175  KJSObject *thisValue)
176 {
177  Interpreter *ip = INTERPRETER(this);
178 
179  JSValue *tv = thisValue ? JSVALUE(thisValue) : nullptr;
180  KJS::Completion c = ip->evaluate(toUString(sourceURL), startingLineNumber,
181  toUString(code), tv);
182 
183  KJSResult res;
184  if (c.complType() == Throw) {
185  ExecState *exec = ip->globalExec();
186  UString msg = JSValue::toString(c.value(), exec);
187 #if 0
188  JSObject *resObj = c.value()->toObject(exec);
189  CString message = resObj->toString(exec).UTF8String();
190  int line = resObj->toObject(exec)->get(exec, "line")->toUInt32(exec);
191 
192  if (!sourceURL.isEmpty()) {
193  fprintf(stderr, "%s (line %d): ", qPrintable(sourceURL), line);
194  }
195  fprintf(stderr, "%s\n", msg.c_str());
196 #endif
197  fprintf(stderr, "evaluate() threw an exception\n");
198  res.hnd->errMsg = msg;
199  } else {
200  if (c.isValueCompletion()) {
201  res.hnd->val = KJSObject(JSVALUE_HANDLE(c.value()));
202  }
203  }
204 
205  return res;
206 }
207 
209  KJSObject *thisValue)
210 {
211  return evaluate(QLatin1String("<string>"), 0, code, thisValue);
212 }
213 
214 void KJSInterpreter::setTimeoutTime(unsigned mSecs)
215 {
216  Interpreter *ip = INTERPRETER(this);
217  ip->setTimeoutTime(mSecs);
218 }
219 
221 {
222  Interpreter *ip = INTERPRETER(this);
223  ip->startTimeoutCheck();
224 }
225 
227 {
228  Interpreter *ip = INTERPRETER(this);
229  ip->stopTimeoutCheck();
230 }
231 
232 bool KJSInterpreter::normalizeCode(const QString &code, QString *normalized,
233  int *errLine, QString *errMsg)
234 {
235  assert(normalized);
236 
237  UString codeOut, msg;
238  bool success = Interpreter::normalizeCode(toUString(code), &codeOut,
239  errLine, &msg);
240 
241  *normalized = toQString(codeOut);
242  if (errMsg) {
243  *errMsg = toQString(msg);
244  }
245 
246  return success;
247 }
248 
~KJSResult()
Frees resources held by this result object.
void stopTimeoutCheck()
Stops measurement of execution time after the initial startTimeoutCheck() call.
A class representing a JavaScript interpreter.
KJSObject globalObject()
Returns the object that is used as the global object during all script execution performed by this in...
JSGlobalObject * globalObject() const
Returns the object that is used as the global object during all script execution performed by this in...
JSValue is the base type for all primitives (Undefined, Null, Boolean, String, Number) and objects in...
Definition: value.h:58
static bool normalizeCode(const QString &codeIn, QString *codeOut, int *errLine=nullptr, QString *errMsg=nullptr)
Reformat the given script code to an easy to read format with only one statement per line.
void ref()
A class representing an undefined JavaScript value.
Definition: kjsobject.h:187
KJSInterpreter()
Constructs an interpreter with a default global object.
KJSInterpreter & operator=(const KJSInterpreter &other)
Assign another interpreter instance to this object.
void setTimeoutTime(unsigned mSecs)
Call this function in preparation of startTimeoutCheck() to set the number of milliseconds that a scr...
KJSContext * globalContext()
Returns a handle to the global execution context.
virtual ExecState * globalExec()
Returns the execution state object which can be used to execute scripts using this interpreter at a t...
void deref()
ComplType complType() const
Returns the type of this completion.
Definition: completion.h:61
bool isException() const
Returns true if the script evaluation has caused an exception.
Completion objects are used to convey the return status and value from functions.
Definition: completion.h:52
Represents the current state of script execution.
Definition: ExecState.h:53
QString errorMessage() const
Returns the error message if this is an exception result.
KJSResult & operator=(const KJSResult &)
Assigns the properties of another result object to this one.
bool isEmpty() const const
A class representing a global object of an execution environment.
Definition: kjsobject.h:279
Interpreter objects can be used to evaluate ECMAScript code.
Definition: interpreter.h:56
JSObject * builtinObjectPrototype() const
Returns the builtin "Object.prototype" object.
A class representing a JavaScript execution context.
Definition: kjscontext.h:41
A class representing a JavaScript value.
Definition: kjsobject.h:48
Completion evaluate(const UString &sourceURL, int startingLineNumber, const UChar *code, int codeLength, JSValue *thisV=nullptr)
Evaluates the supplied ECMAScript code.
KJSResult()
Constructs a default result object.
bool isValueCompletion() const
Returns true if this is a value completion, false otherwise.
Definition: completion.h:86
8 bit char based string class
Definition: ustring.h:124
JSValue * value() const
Returns the value of this completion if it is of type value-completion, 0 otherwise.
Definition: completion.h:70
KJSResult evaluate(const QString &sourceURL, int startingLineNumber, const QString &code, KJSObject *thisValue=nullptr)
Evaluates a piece of code with a "this" set to (optionally set) value.
A class representing the result of a script evaluation.
QString message
void startTimeoutCheck()
Start measuring executing time until the timeout value specified via setTimeoutTime().
~KJSInterpreter()
Destructs this interpreter and frees resources it has allocated.
Unicode string class.
Definition: ustring.h:153
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Mar 26 2023 03:56:21 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.