22 #include "kjs_binding.h"
24 #include <config-khtml.h>
25 #if HAVE_VALGRIND_MEMCHECK_H
27 #include <valgrind/memcheck.h>
28 #define VALGRIND_SUPPORT
33 #include "kjs_range.h"
35 #include <dom/css_stylesheet.h>
36 #include <dom/dom_exception.h>
37 #include <dom/dom2_range.h>
38 #include <dom/dom3_xpath.h>
39 #include <xml/dom2_eventsimpl.h>
40 #include <khtmlpart_p.h>
42 #include "khtml_debug.h"
43 #include <kparts/browserextension.h>
44 #include <kmessagebox.h>
45 #include <QTextDocument>
48 #include "debugger/debugwindow.h"
55 using namespace KJSDebugger;
60 UString DOMObject::toString(ExecState *)
const
62 return "[object " + className() +
"]";
65 HashMap<void *, DOMObject *> *ScriptInterpreter::s_allDomObjects;
68 static InterpreterList *interpreterList;
70 ScriptInterpreter::ScriptInterpreter(JSGlobalObject *global, khtml::ChildFrame *frame)
71 : Interpreter(global), m_frame(frame),
72 m_evt(nullptr), m_inlineCode(false), m_timerCallback(false)
75 qCDebug(KHTML_LOG) <<
"ScriptInterpreter::ScriptInterpreter " <<
this <<
" for part=" << m_frame;
77 if (!interpreterList) {
78 interpreterList =
new InterpreterList;
80 interpreterList->
append(
this);
83 ScriptInterpreter::~ScriptInterpreter()
86 qCDebug(KHTML_LOG) <<
"ScriptInterpreter::~ScriptInterpreter " <<
this <<
" for part=" << m_frame;
88 assert(interpreterList && interpreterList->
contains(
this));
90 if (interpreterList->
isEmpty()) {
91 delete interpreterList;
92 interpreterList =
nullptr;
96 void ScriptInterpreter::forgetDOMObject(
void *objectHandle)
98 if (!interpreterList) {
102 for (
int i = 0; i < interpreterList->
size(); ++i) {
103 interpreterList->
at(i)->m_domObjects.remove(objectHandle);
105 allDomObjects()->remove(objectHandle);
108 void ScriptInterpreter::mark(
bool isMain)
110 Interpreter::mark(isMain);
112 qCDebug(KHTML_LOG) <<
"ScriptInterpreter::mark " <<
this <<
" marking " << m_domObjects.size() <<
" DOM objects";
114 HashMap<void *, DOMObject *>::iterator it = m_domObjects.begin();
115 while (it != m_domObjects.end()) {
117 if (obj->shouldMark()) {
126 return m_frame->m_part.data();
129 bool ScriptInterpreter::isWindowOpenAllowed()
const
132 int id = m_evt->handle()->id();
134 id == DOM::EventImpl::CLICK_EVENT ||
135 id == DOM::EventImpl::MOUSEUP_EVENT ||
id == DOM::EventImpl::MOUSEDOWN_EVENT ||
136 id == DOM::EventImpl::KHTML_ECMA_CLICK_EVENT ||
id == DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT ||
138 id == DOM::EventImpl::KEYDOWN_EVENT ||
id == DOM::EventImpl::KEYPRESS_EVENT ||
139 id == DOM::EventImpl::KEYUP_EVENT ||
141 id == DOM::EventImpl::SELECT_EVENT ||
id == DOM::EventImpl::CHANGE_EVENT ||
142 id == DOM::EventImpl::SUBMIT_EVENT);
148 if (m_inlineCode && !m_timerCallback) {
159 bool ScriptInterpreter::s_disableCPUGuard =
false;
161 void ScriptInterpreter::startCPUGuard()
163 if (s_disableCPUGuard) {
167 unsigned time = 5000;
168 #ifdef VALGRIND_SUPPORT
169 if (RUNNING_ON_VALGRIND) {
174 setTimeoutTime(time);
178 void ScriptInterpreter::stopCPUGuard()
180 if (s_disableCPUGuard) {
186 bool ScriptInterpreter::shouldInterruptScript()
const
189 if (DebugWindow::isBlocked()) {
195 return KMessageBox::warningYesNo(
nullptr,
i18n(
"A script on this page is causing KHTML to freeze. If it continues to run, other applications may become less responsive.\nDo you want to stop the script?"),
i18n(
"JavaScript"),
KGuiItem(
i18n(
"&Stop Script")),
KStandardGuiItem::cont(),
"kjscupguard_alarmhandler") == KMessageBox::Yes;
198 UString::UString(
const QString &d)
200 if (d.length() > UString::maxUChars()) {
205 unsigned int len = d.length();
206 UChar *dat =
static_cast<UChar *
>(fastMalloc(
sizeof(UChar) * len));
207 memcpy(dat, d.unicode(), len *
sizeof(UChar));
208 m_rep = UString::Rep::create(dat, len);
220 if (d.length() > UString::maxUChars()) {
225 unsigned int len = d.length();
226 UChar *dat =
static_cast<UChar *
>(fastMalloc(
sizeof(UChar) * len));
227 memcpy(dat, d.unicode(), len *
sizeof(UChar));
228 m_rep = UString::Rep::create(dat, len);
236 QString UString::qstring()
const
246 QString Identifier::qstring()
const
251 JSValue *valueGetterAdapter(ExecState *exec, JSObject *,
const Identifier &,
const PropertySlot &slot)
254 return static_cast<JSValue *
>(slot.customValue());
257 DOM::NodeImpl *toNode(JSValue *val)
259 JSObject *obj = val->getObject();
260 if (!obj || !obj->inherits(&DOMNode::info)) {
264 const DOMNode *dobj =
static_cast<const DOMNode *
>(obj);
277 DOM::DOMString valueToStringWithNullCheck(ExecState *exec, JSValue *val)
282 return val->toString(exec).domString();
285 QVariant ValueToVariant(ExecState *exec, JSValue *val)
288 switch (val->type()) {
290 res =
QVariant(val->toBoolean(exec));
293 res =
QVariant(val->toNumber(exec));
296 res =
QVariant(val->toString(exec).qstring());
305 void setDOMException(ExecState *exec,
int internalCode)
307 if (internalCode == 0 || exec->hadException()) {
311 const char *
type =
nullptr;
315 JSObject *errorObject =
nullptr;
320 if (DOM::RangeException::isRangeExceptionCode(internalCode)) {
322 code = internalCode - DOM::RangeException::_EXCEPTION_OFFSET;
323 name = DOM::RangeException::codeAsString(code);
324 errorObject =
new RangeException(exec);
327 code = internalCode - DOM::CSSException::_EXCEPTION_OFFSET;
331 code = internalCode - DOM::EventException::_EXCEPTION_OFFSET;
333 }
else if (DOM::XPathException::isXPathExceptionCode(internalCode)) {
335 code = internalCode - DOM::XPathException::_EXCEPTION_OFFSET;
336 name = DOM::XPathException::codeAsString(code);
342 errorObject =
new JSDOMException(exec);
356 qsnprintf(buffer, 99,
"%s: %s Exception %d",
name.string().
toLatin1().
data(), type, code);
358 qsnprintf(buffer, 99,
"%s Exception %d", type, code);
360 errorObject = throwError(exec, GeneralError, buffer);
362 exec->setException(errorObject);
365 errorObject->put(exec, exec->propertyNames().name, jsString(UString(type) +
" Exception"));
366 errorObject->put(exec, exec->propertyNames().message, jsString(name));
367 errorObject->put(exec,
"code", jsNumber(code));
372 switch (value->type()) {
373 case KJS::NumberType: {
378 case KJS::BooleanType:
379 return value->getBoolean() ?
"true" :
"false";
380 case KJS::StringType: {
383 return '"' + s.
qstring() +
'"';
385 case KJS::UndefinedType:
389 case KJS::ObjectType:
390 return "[object " +
static_cast<KJS::JSObject *
>(value)->className().qstring() +
"]";
391 case KJS::GetterSetterType:
392 case KJS::UnspecifiedType:
398 QString exceptionToString(ExecState *exec, JSValue *exceptionObj)
400 QString exceptionMsg = valueToString(exceptionObj);
406 JSObject *valueObj = exceptionObj->getObject();
407 JSValue *protoObj = valueObj ? valueObj->prototype() :
nullptr;
409 bool exception =
false;
410 bool syntaxError =
false;
411 if (protoObj == exec->lexicalInterpreter()->builtinSyntaxErrorPrototype()) {
416 if (protoObj == exec->lexicalInterpreter()->builtinErrorPrototype() ||
417 protoObj == exec->lexicalInterpreter()->builtinEvalErrorPrototype() ||
418 protoObj == exec->lexicalInterpreter()->builtinReferenceErrorPrototype() ||
419 protoObj == exec->lexicalInterpreter()->builtinRangeErrorPrototype() ||
420 protoObj == exec->lexicalInterpreter()->builtinTypeErrorPrototype() ||
421 protoObj == exec->lexicalInterpreter()->builtinURIErrorPrototype()) {
433 JSValue *oldExceptionObj = exec->exception();
434 exec->clearException();
440 JSValue *lineValue = valueObj->get(exec,
"line");
441 JSValue *urlValue = valueObj->get(exec,
"sourceURL");
443 int line = lineValue->toNumber(exec);
444 QString url = urlValue->toString(exec).qstring();
445 exceptionMsg =
i18n(
"Parse error at %1 line %2",
451 exceptionMsg = exceptionObj->toString(exec).qstring();
453 exec->setException(oldExceptionObj);