Commit 74f6ed62 authored by darin's avatar darin

JavaScriptCore:

        * kjs/*: Roll KDE 3.0.2 changes in. Also switch to not using APPLE_CHANGES
	for some of the changes that we definitely want to contribute upstream.

WebCore:

	* khtml/*: Roll KDE 3.0.2 changes in. Also switch to not using APPLE_CHANGES
	for some of the changes that we definitely want to contribute upstream.

        * WebCore.pbproj/project.pbxproj: Add KWQStyle.mm, remove KWQStyle.h, moving contents
	into qstyle.h.

        * kwq/KWQApplication.mm: (QApplication::globalStrut): Remove _logNotYetImplemented().

        * kwq/KWQButton.mm: (QButton::QButton): Use plain release, not autorelease.
        * kwq/KWQComboBox.mm: (QComboBox::init): Use plain release, not autorelease.
        * kwq/KWQListBox.mm: (QListBox::QListBox): Use plain release, not autorelease.
        * kwq/KWQPainter.mm: (QPainter::drawArc): Use plain release, not autorelease.

        * kwq/KWQKHTMLPartBrowserExtension.mm: Remove import of KWQKHTMLPartImpl.h, now that
	it's always part of khtml_part.h.
        * kwq/KWQKHTMLPartImpl.cpp: Simplify.
        * kwq/KWQKHTMLPartImpl.h: Add wrapper to allow multiple inclusion. Don't include
	khtml_part.h any more, since that file now includes this one to minimize changes to
	KDE code that needs to get to functions in here.
        * kwq/KWQKHTMLPartImpl.mm:
        (KHTMLPart::onURL), (KHTMLPart::nodeActivated), (KHTMLPart::setStatusBarText):
	Moved here from khtml_part.cpp.
        * kwq/KWQLoaderImpl.mm: Include khtml_part.h instead of KWQKHTMLPartImpl.h.

        * kwq/KWQPushButton.mm:
        (buttonFontMetrics), (QPushButton::fontMetrics): Added. Used by the form code to size buttons.
        * kwq/KWQStyle.mm: Added.
        (QStyle::sizeFromContents): Added. Used by the form code to size buttons.

        * kwq/KWQStyle.h: Removed.
        * kwq/qt/qstyle.h: Moved contents of KWQStyle.h in here.
        * kwq/qt/qwidget.h: Include <qstyle.h> rather than KWQStyle.h.

        * kwq/WebCoreBridge.mm: (-[WebCoreBridge isFrameSet]): Call straight to impl.

        * kwq/kdeui/klineedit.h: Add KLineEdit::frameWidth().
        * kwq/qt/qnamespace.h: Remove GUIStyle, MacStyle, and WindowsStyle.
        * kwq/qt/qpaintdevice.h: Add QInternal, QInternal::Printer, and QPaintDevice::devType().
        * kwq/qt/qpainter.h: Add QPainter::device().
        * kwq/qt/qpushbutton.h: Add QPushButton::fontMetrics().


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@1623 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 339ec9b4
2002-07-21 Darin Adler <darin@apple.com>
* kjs/*: Roll KDE 3.0.2 changes in. Also switch to not using APPLE_CHANGES
for some of the changes that we definitely want to contribute upstream.
2002-07-21 Maciej Stachowiak <mjs@apple.com>
* Makefile.am: Remove products from symroots on `make clean'.
......
2002-07-21 Darin Adler <darin@apple.com>
* kjs/*: Roll KDE 3.0.2 changes in. Also switch to not using APPLE_CHANGES
for some of the changes that we definitely want to contribute upstream.
2002-07-21 Maciej Stachowiak <mjs@apple.com>
* Makefile.am: Remove products from symroots on `make clean'.
......
2002-07-21 Darin Adler <darin@apple.com>
* kjs/*: Roll KDE 3.0.2 changes in. Also switch to not using APPLE_CHANGES
for some of the changes that we definitely want to contribute upstream.
2002-07-21 Maciej Stachowiak <mjs@apple.com>
* Makefile.am: Remove products from symroots on `make clean'.
......
......@@ -360,16 +360,19 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
{
Value jObj = thisObj.get(exec,UString::from(j));
int cmp;
if ( useSortFunction )
{
if (jObj.type() == UndefinedType) {
cmp = 1;
} else if (minObj.type() == UndefinedType) {
cmp = -1;
} else if (useSortFunction) {
List l;
l.append(jObj);
l.append(minObj);
Object thisObj = exec->interpreter()->globalObject();
cmp = sortFunction.call(exec,thisObj, l ).toInt32(exec);
}
else
} else {
cmp = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
}
if ( cmp < 0 )
{
themin = j;
......
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
*
* This library is free software; you can redistribute it and/or
......@@ -31,12 +31,14 @@
#include "debugger.h"
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
using namespace KJS;
// ------------------------------ FunctionImp ----------------------------------
// ----------------------------- FunctionImp ----------------------------------
const ClassInfo FunctionImp::info = {"Function", &InternalFunctionImp::info, 0, 0};
......@@ -99,7 +101,7 @@ Value FunctionImp::call(ExecState *exec, Object &thisObj, const List &args)
}
Object func(this);
int cont = dbg->callEvent(exec,sid,lineno,func,args);
bool cont = dbg->callEvent(exec,sid,lineno,func,args);
if (!cont) {
dbg->imp()->abort();
return Undefined();
......@@ -107,36 +109,34 @@ Value FunctionImp::call(ExecState *exec, Object &thisObj, const List &args)
}
// enter a new execution context
ContextImp *ctx = new ContextImp(globalObj, exec, thisObj,
codeType(), exec->context().imp(), this, args);
ExecState *newExec = new ExecState(exec->interpreter(),ctx);
newExec->setException(exec->exception()); // could be null
ContextImp ctx(globalObj, exec, thisObj, codeType(),
exec->context().imp(), this, args);
ExecState newExec(exec->interpreter(), &ctx);
newExec.setException(exec->exception()); // could be null
// In order to maintain our "arguments" property, we maintain a list of arguments
// properties from earlier in the execution stack. Upon return, we restore the
// previous arguments object using popArgs().
// Note: this does not appear to be part of the spec
if (codeType() == FunctionCode) {
assert(ctx->activationObject().inherits(&ActivationImp::info));
Object argsObj = static_cast<ActivationImp*>(ctx->activationObject().imp())->argumentsObject();
put(newExec,"arguments", argsObj, DontDelete|DontEnum|ReadOnly);
pushArgs(newExec,argsObj);
assert(ctx.activationObject().inherits(&ActivationImp::info));
Object argsObj = static_cast<ActivationImp*>(ctx.activationObject().imp())->argumentsObject();
put(&newExec, "arguments", argsObj, DontDelete|DontEnum|ReadOnly);
pushArgs(&newExec, argsObj);
}
// assign user supplied arguments to parameters
processParameters(newExec,args);
processParameters(&newExec, args);
// add variable declarations (initialized to undefined)
processVarDecls(newExec);
processVarDecls(&newExec);
Completion comp = execute(newExec);
Completion comp = execute(&newExec);
// if an exception occured, propogate it back to the previous execution object
if (newExec->hadException())
exec->setException(newExec->exception());
if (newExec.hadException())
exec->setException(newExec.exception());
if (codeType() == FunctionCode)
popArgs(newExec);
delete newExec;
delete ctx;
popArgs(&newExec);
#ifdef KJS_VERBOSE
if (comp.complType() == Throw)
......@@ -430,34 +430,27 @@ Value GlobalFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args
break;
}
case ParseInt: {
String str = args[0].toString(exec);
CString cstr = args[0].toString(exec).cstring();
int radix = args[1].toInt32(exec);
if (radix == 0)
radix = 10;
else if (radix < 2 || radix > 36) {
char* endptr;
errno = 0;
long value = strtol(cstr.c_str(), &endptr, radix);
if (errno != 0 || endptr == cstr.c_str())
res = Number(NaN);
return res;
}
/* TODO: use radix */
// Can't use toULong(), we want to accept floating point values too
double value = str.value().toDouble( true /*tolerant*/ );
if ( isNaN(value) )
res = Number(NaN);
else
res = Number(static_cast<long>(value)); // remove floating-point part
res = Number(value);
break;
}
case ParseFloat: {
String str = args[0].toString(exec);
res = Number(str.value().toDouble( true /*tolerant*/ ));
case ParseFloat:
res = Number(args[0].toString(exec).toDouble( true /*tolerant*/ ));
break;
}
case IsNaN:
res = Boolean(isNaN(args[0].toNumber(exec)));
break;
case IsFinite: {
Number n = args[0].toNumber(exec);
res = Boolean(!n.isNaN() && !n.isInf());
double n = args[0].toNumber(exec);
res = Boolean(!isNaN(n) && !isInf(n));
break;
}
case Escape: {
......@@ -484,9 +477,9 @@ Value GlobalFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args
case UnEscape: {
UString s, str = args[0].toString(exec);
int k = 0, len = str.size();
UChar u;
while (k < len) {
const UChar *c = str.data() + k;
UChar u;
if (*c == UChar('%') && k <= len - 6 && *(c+1) == UChar('u')) {
u = Lexer::convertUnicode((c+2)->unicode(), (c+3)->unicode(),
(c+4)->unicode(), (c+5)->unicode());
......
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
*
* This library is free software; you can redistribute it and/or
......@@ -836,25 +836,15 @@ void InterpreterImp::initGlobalObject()
static_cast<ObjectImp*>(global.imp())->setPrototype(b_ObjectPrototype);
// Constructors (Object, Array, etc.)
ObjectObjectImp *objectObj = new ObjectObjectImp(globExec,objProto,funcProto);
b_Object = Object(objectObj);
FunctionObjectImp *funcObj = new FunctionObjectImp(globExec,funcProto);
b_Function = Object(funcObj);
ArrayObjectImp *arrayObj = new ArrayObjectImp(globExec,funcProto,arrayProto);
b_Array = Object(arrayObj);
StringObjectImp *stringObj = new StringObjectImp(globExec,funcProto,stringProto);
b_String = Object(stringObj);
BooleanObjectImp *booleanObj = new BooleanObjectImp(globExec,funcProto,booleanProto);
b_Boolean = Object(booleanObj);
NumberObjectImp *numberObj = new NumberObjectImp(globExec,funcProto,numberProto);
b_Number = Object(numberObj);
DateObjectImp *dateObj = new DateObjectImp(globExec,funcProto,dateProto);
b_Date = Object(dateObj);
RegExpObjectImp *regexpObj = new RegExpObjectImp(globExec,regexpProto,funcProto);
b_RegExp = Object(regexpObj);
ErrorObjectImp *errorObj = new ErrorObjectImp(globExec,funcProto,errorProto);
b_Error = Object(errorObj);
b_Object = Object(new ObjectObjectImp(globExec, objProto, funcProto));
b_Function = Object(new FunctionObjectImp(globExec, funcProto));
b_Array = Object(new ArrayObjectImp(globExec, funcProto, arrayProto));
b_String = Object(new StringObjectImp(globExec, funcProto, stringProto));
b_Boolean = Object(new BooleanObjectImp(globExec, funcProto, booleanProto));
b_Number = Object(new NumberObjectImp(globExec, funcProto, numberProto));
b_Date = Object(new DateObjectImp(globExec, funcProto, dateProto));
b_RegExp = Object(new RegExpObjectImp(globExec, funcProto, regexpProto));
b_Error = Object(new ErrorObjectImp(globExec, funcProto, errorProto));
// Error object prototypes
b_evalErrorPrototype = Object(new NativeErrorPrototypeImp(globExec,errorProto,EvalError,
......@@ -1016,7 +1006,7 @@ Completion InterpreterImp::evaluate(const UString &code, const Value &thisV)
return Completion(Break);
}
// no program node means a syntax occurred
// no program node means a syntax error occurred
if (!progNode) {
Object err = Error::create(globExec,SyntaxError,errMsg.ascii(),errLine);
err.put(globExec,"sid",Number(sid));
......
......@@ -299,6 +299,7 @@ Interpreter::CompatMode Interpreter::compatMode() const
}
#ifdef KJS_DEBUG_MEM
#include "lexer.h"
void Interpreter::finalCheck()
{
fprintf(stderr,"Interpreter::finalCheck()\n");
......@@ -311,6 +312,9 @@ void Interpreter::finalCheck()
fprintf(stderr,"ListImp::count = %d\n", KJS::ListImp::count);
Node::finalCheck();
Collector::finalCheck();
Lexer::globalClear();
List::globalClear();
UString::globalClear();
}
#endif
......
......@@ -91,6 +91,14 @@ Lexer *Lexer::curr()
return currLexer;
}
#ifdef KJS_DEBUG_MEM
void Lexer::globalClear()
{
delete currLexer;
currLexer = 0L;
}
#endif
void Lexer::setCode(const UChar *c, unsigned int len)
{
yylineno = 1;
......
......@@ -111,6 +111,12 @@ namespace KJS {
static bool isIdentLetter(unsigned short c);
static bool isDecimalDigit(unsigned short c);
#ifdef KJS_DEBUG_MEM
/**
* Clear statically allocated resources
*/
static void globalClear();
#endif
private:
void record8(unsigned short c);
......
......@@ -140,13 +140,8 @@ bool MathFuncImp::implementsCall() const
Value MathFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
{
Value v = args[0];
Number n = v.toNumber(exec);
double arg = n.value();
Value v2 = args[1];
Number n2 = v2.toNumber(exec);
double arg2 = n2.value();
double arg = args[0].toNumber(exec);
double arg2 = args[1].toNumber(exec);
double result;
switch (id) {
......@@ -240,7 +235,7 @@ Value MathFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
case MathObjectImp::Round:
if (isNaN(arg))
result = arg;
if (isInf(arg) || isInf(-arg))
else if (isInf(arg) || isInf(-arg))
result = arg;
else if (arg == -0.5)
result = 0;
......
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
*
* This library is free software; you can redistribute it and/or
......@@ -73,7 +73,7 @@ using namespace KJS;
return List(); // will be picked up by KJS_CHECKEXCEPTION
#ifdef KJS_DEBUG_MEM
std::list<Node *> Node::s_nodes;
std::list<Node *> * Node::s_nodes = 0L;
#endif
// ------------------------------ Node -----------------------------------------
......@@ -82,28 +82,26 @@ Node::Node()
line = Lexer::curr()->lineNo();
refcount = 0;
#ifdef KJS_DEBUG_MEM
s_nodes.push_back( this );
if (!s_nodes)
s_nodes = new std::list<Node *>;
s_nodes->push_back(this);
#endif
}
Node::~Node()
{
#ifdef KJS_DEBUG_MEM
s_nodes.remove( this );
s_nodes->remove( this );
#endif
}
#ifdef KJS_DEBUG_MEM
void Node::finalCheck()
{
#ifdef APPLE_CHANGES
fprintf( stderr, "Node::finalCheck(): list count : %d\n", (int)s_nodes.size() );
#else
fprintf( stderr, "Node::finalCheck(): list count : %d\n", s_nodes.size() );
#endif
std::list<Node *>::iterator it = s_nodes.begin();
for ( uint i = 0; it != s_nodes.end() ; ++it, ++i )
fprintf( stderr, "[%d] Still having node %p (%s) (refcount %d)\n", i, (void*)*it, typeid( **it ).name(), (*it)->refcount );
delete s_nodes;
s_nodes = 0L;
}
#endif
......@@ -746,6 +744,16 @@ Value FunctionCallNode::evaluate(ExecState *exec)
return throwError(exec, TypeError, "Expression does not allow calls.");
}
#if KJS_MAX_STACK > 0
static int depth = 0; // sum of all concurrent interpreters
if (++depth > KJS_MAX_STACK) {
#ifndef NDEBUG
printInfo(exec, "Exceeded maximum function call depth", v, line);
#endif
return throwError(exec, RangeError, "Exceeded maximum call stack size.");
}
#endif
Value thisVal;
if (e.type() == ReferenceType)
thisVal = e.getBase(exec);
......@@ -770,6 +778,10 @@ Value FunctionCallNode::evaluate(ExecState *exec)
Object thisObj = Object::dynamicCast(thisVal);
Value result = func.call(exec,thisObj, argList);
#if KJS_MAX_STACK > 0
--depth;
#endif
return result;
}
......@@ -3139,7 +3151,6 @@ Completion SourceElementsNode::execute(ExecState *exec)
{
KJS_CHECKEXCEPTION
#ifdef APPLE_CHANGES
Completion c1 = element->execute(exec);
KJS_CHECKEXCEPTION;
if (c1.complType() != Normal)
......@@ -3156,54 +3167,21 @@ Completion SourceElementsNode::execute(ExecState *exec)
}
return c1;
#else
if (!elements)
return element->execute(exec);
Completion c1 = elements->execute(exec);
KJS_CHECKEXCEPTION
if (c1.complType() != Normal)
return c1;
Completion c2 = element->execute(exec);
KJS_CHECKEXCEPTION
// The spec says to return c2 here, but it seems that mozilla returns c1 if
// c2 doesn't have a value
if (c2.complType() == Normal && c2.value().isNull())
return c1;
else
return c2;
#endif
}
// ECMA 14
void SourceElementsNode::processFuncDecl(ExecState *exec)
{
#ifdef APPLE_CHANGES
for (SourceElementsNode *node = this; node; node = node->elements) {
node->element->processFuncDecl(exec);
}
#else
if (elements)
elements->processFuncDecl(exec);
element->processFuncDecl(exec);
#endif
}
void SourceElementsNode::processVarDecls(ExecState *exec)
{
#ifdef APPLE_CHANGES
for (SourceElementsNode *node = this; node; node = node->elements) {
node->element->processVarDecls(exec);
}
#else
if (elements)
elements->processVarDecls(exec);
element->processVarDecls(exec);
#endif
}
ProgramNode::ProgramNode(SourceElementsNode *s): FunctionBodyNode(s) {
......
......@@ -101,7 +101,7 @@ namespace KJS {
private:
#ifdef KJS_DEBUG_MEM
// List of all nodes, for debugging purposes. Don't remove!
static std::list<Node *> s_nodes;
static std::list<Node *> *s_nodes;
#endif
// disallow assignment
Node& operator=(const Node&);
......
......@@ -27,6 +27,10 @@
// Objects
// maximum global call stack size. Protects against accidental or
// malicious infinite recursions. Define to -1 if you want no limit.
#define KJS_MAX_STACK 1000
#include "value.h"
#include "types.h"
......
......@@ -244,17 +244,17 @@ Value KJS::add(ExecState *exec, const Value &v1, const Value &v2, char oper)
// ECMA 11.5
Value KJS::mult(ExecState *exec, const Value &v1, const Value &v2, char oper)
{
Number n1 = v1.toNumber(exec);
Number n2 = v2.toNumber(exec);
double n1 = v1.toNumber(exec);
double n2 = v2.toNumber(exec);
double result;
if (oper == '*')
result = n1.value() * n2.value();
result = n1 * n2;
else if (oper == '/')
result = n1.value() / n2.value();
result = n1 / n2;
else
result = fmod(n1.value(), n2.value());
result = fmod(n1, n2);
return Number(result);
}
......@@ -28,17 +28,17 @@
using namespace KJS;
RegExp::RegExp(const UString &p, int f)
: pattern(p), flags(f)
: pattern(p), flgs(f)
{
#ifdef HAVE_PCREPOSIX
int pcreflags = 0;
const char *perrormsg;
int errorOffset;
if (flags & IgnoreCase)
if (flgs & IgnoreCase)
pcreflags |= PCRE_CASELESS;
if (flags & Multiline)
if (flgs & Multiline)
pcreflags |= PCRE_MULTILINE;
pcregex = pcre_compile(p.ascii(), pcreflags,
......
......@@ -44,6 +44,7 @@ namespace KJS {
enum { None = 0, Global = 1, IgnoreCase = 2, Multiline = 4 };
RegExp(const UString &p, int f = None);
~RegExp();
int flags() const { return flgs; }
UString match(const UString &s, int i = -1, int *pos = 0L, int **ovector = 0L);
// test is unused. The JS spec says that RegExp.test should use
// RegExp.exec, so it has to store $1 etc.
......@@ -51,7 +52,7 @@ namespace KJS {
uint subPatterns() const { return nrSubPatterns; }
private:
const UString &pattern;
int flags;
int flgs;
#ifndef HAVE_PCREPOSIX
regex_t preg;
......
......@@ -149,8 +149,9 @@ RegExpImp::~RegExpImp()
// ------------------------------ RegExpObjectImp ------------------------------
RegExpObjectImp::RegExpObjectImp(ExecState *exec,
RegExpPrototypeImp *regProto,
FunctionPrototypeImp *funcProto)
FunctionPrototypeImp *funcProto,
RegExpPrototypeImp *regProto)
: InternalFunctionImp(funcProto), lastOvector(0L), lastNrSubPatterns(0)
{
Value protect(this);
......@@ -175,7 +176,7 @@ int **RegExpObjectImp::registerRegexp( const RegExp* re, const UString& s )
return &lastOvector;
}
Value RegExpObjectImp::arrayOfMatches(ExecState *exec, const UString &result) const
Object RegExpObjectImp::arrayOfMatches(ExecState *exec, const UString &result) const
{
List list;
// The returned array contains 'result' as first item, followed by the list of matches
......@@ -186,10 +187,13 @@ Value RegExpObjectImp::arrayOfMatches(ExecState *exec, const UString &result) co
UString substring = lastString.substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
list.append(String(substring));
}
return exec->interpreter()->builtinArray().construct(exec, list);
Object arr = exec->interpreter()->builtinArray().construct(exec, list);
arr.put(exec, "index", Number(lastOvector[0]));
arr.put(exec, "input", String(lastString));
return arr;
}
Value RegExpObjectImp::get(ExecState *, const UString &p) const
Value RegExpObjectImp::get(ExecState *exec, const UString &p) const
{
if (p[0] == '$' && lastOvector)
{
......@@ -205,7 +209,7 @@ Value RegExpObjectImp::get(ExecState *, const UString &p) const
return String("");
}
}
return Undefined();
return InternalFunctionImp::get(exec, p);
}