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