KJS-API
kjsinterpreter.cpp
Go to the documentation of this file.
00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (C) 2008 Harri Porten (porten@kde.org) 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 * Boston, MA 02110-1301, USA. 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
KDE 4.6 API Reference