KJS-API
kjsinterpreter.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kjsinterpreter.h"
00023 #include "kjsprivate.h"
00024 #include "kjs/interpreter.h"
00025 #include "kjs/completion.h"
00026 #include "kjs/object.h"
00027 #include <QString>
00028 #include <stdio.h>
00029
00030 using namespace KJS;
00031
00032 class KJSResultHandle
00033 {
00034 public:
00035 KJSResultHandle() : rc(1), val(KJSUndefined()) { }
00036
00037 int rc;
00038 KJSObject val;
00039 UString errMsg;
00040
00041 void ref() { ++rc; }
00042 void deref() { if (--rc == 0) delete this; }
00043 };
00044
00045 KJSResult::KJSResult()
00046 : hnd(new KJSResultHandle())
00047 {
00048 }
00049
00050 KJSResult::KJSResult(const KJSResult& r)
00051 {
00052 hnd = r.hnd;
00053 hnd->ref();
00054 }
00055
00056 KJSResult& KJSResult::operator=(const KJSResult& r)
00057 {
00058 if (hnd != r.hnd) {
00059 r.hnd->ref();
00060 hnd->deref();
00061 hnd = r.hnd;
00062 }
00063
00064 return *this;
00065 }
00066
00067 KJSResult::~KJSResult()
00068 {
00069 hnd->deref();
00070 }
00071
00072 bool KJSResult::isException() const
00073 {
00074 return !hnd->errMsg.isNull();
00075 }
00076
00077 QString KJSResult::errorMessage() const
00078 {
00079 return toQString(hnd->errMsg);
00080 }
00081
00082 KJSObject KJSResult::value() const
00083 {
00084 return hnd->val;
00085 }
00086
00087 KJSInterpreter::KJSInterpreter()
00088 : globCtx(0)
00089 {
00090 Interpreter* ip = new Interpreter();
00091 ip->ref();
00092 hnd = INTERPRETER_HANDLE(ip);
00093 }
00094
00095 KJSInterpreter::KJSInterpreter(const KJSGlobalObject& global)
00096 : globCtx(0)
00097 {
00098 JSValue* gv = JSVALUE(&global);
00099 assert(gv->isObject());
00100 JSObject* go = static_cast<JSObject*>(gv);
00101 Interpreter* ip = new Interpreter(go);
00102 ip->ref();
00103 assert(go->prototype()->isObject());
00104 JSObject* p = static_cast<JSObject*>(go->prototype());
00105 JSObject* objectProto = ip->builtinObjectPrototype();
00106 p->setPrototype(objectProto);
00107 hnd = INTERPRETER_HANDLE(ip);
00108 }
00109
00110 KJSInterpreter::KJSInterpreter(const KJSInterpreter& other)
00111 : globCtx(0)
00112 {
00113 Interpreter* ip = INTERPRETER(&other);
00114 ip->ref();
00115 hnd = INTERPRETER_HANDLE(ip);
00116 globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec());
00117 }
00118
00119 KJSInterpreter& KJSInterpreter::operator=(const KJSInterpreter& other)
00120 {
00121 Interpreter* thisIp = INTERPRETER(this);
00122 Interpreter* otherIp = INTERPRETER(&other);
00123 if (otherIp != thisIp) {
00124 otherIp->ref();
00125 thisIp->deref();
00126 hnd = INTERPRETER_HANDLE(otherIp);
00127 globCtx.hnd = EXECSTATE_HANDLE(otherIp->globalExec());
00128 }
00129 return *this;
00130 }
00131
00132 KJSInterpreter::KJSInterpreter(KJSInterpreterHandle* h)
00133 : hnd(h), globCtx(0)
00134 {
00135 Interpreter* ip = INTERPRETER(this);
00136 globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec());
00137 }
00138
00139 KJSInterpreter::~KJSInterpreter()
00140 {
00141 Interpreter* ip = INTERPRETER(this);
00142 ip->deref();
00143 ip = 0;
00144 }
00145
00146 KJSContext* KJSInterpreter::globalContext()
00147 {
00148 Interpreter* ip = INTERPRETER(this);
00149
00150 globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec());
00151 return &globCtx;
00152 }
00153
00154 KJSObject KJSInterpreter::globalObject()
00155 {
00156 Interpreter* ip = INTERPRETER(this);
00157
00158 return KJSObject(JSVALUE_HANDLE(ip->globalObject()));
00159 }
00160
00161 KJSResult KJSInterpreter::evaluate(const QString& sourceURL,
00162 int startingLineNumber,
00163 const QString& code,
00164 KJSObject* thisValue)
00165 {
00166 Interpreter* ip = INTERPRETER(this);
00167
00168 JSValue* tv = thisValue ? JSVALUE(thisValue) : 0;
00169 KJS::Completion c = ip->evaluate(toUString(sourceURL), startingLineNumber,
00170 toUString(code), tv);
00171
00172 KJSResult res;
00173 if (c.complType() == Throw) {
00174 ExecState* exec = ip->globalExec();
00175 UString msg = c.value()->toString(exec);
00176 #if 0
00177 JSObject* resObj = c.value()->toObject(exec);
00178 CString message = resObj->toString(exec).UTF8String();
00179 int line = resObj->toObject(exec)->get(exec, "line")->toUInt32(exec);
00180
00181 if (!sourceURL.isEmpty())
00182 fprintf(stderr, "%s (line %d): ", qPrintable(sourceURL), line);
00183 fprintf(stderr, "%s\n", msg.c_str());
00184 #endif
00185 fprintf(stderr, "evaluate() threw an exception\n");
00186 res.hnd->errMsg = msg;
00187 } else {
00188 if (c.isValueCompletion())
00189 res.hnd->val = KJSObject(JSVALUE_HANDLE(c.value()));
00190 }
00191
00192 return res;
00193 }
00194
00195 KJSResult KJSInterpreter::evaluate(const QString& code,
00196 KJSObject* thisValue)
00197 {
00198 return evaluate("<string>", 0, code, thisValue);
00199 }
00200
00201 bool KJSInterpreter::normalizeCode(const QString& code, QString* normalized,
00202 int* errLine, QString* errMsg)
00203 {
00204 assert(normalized);
00205
00206 UString codeOut, msg;
00207 bool success = Interpreter::normalizeCode(toUString(code), &codeOut,
00208 errLine, &msg);
00209
00210 *normalized = toQString(codeOut);
00211 if (errMsg)
00212 *errMsg = toQString(msg);
00213
00214 return success;
00215 }
00216