[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
darin
darin at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:06:37 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit 7b978750ac46c5e87b79c81ba642a281301e30ce
Author: darin <darin at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Nov 22 09:04:55 2002 +0000
JavaScriptCore:
- change ScopeChain to be a singly linked list shares tails, gives 11% gain on iBench
* kjs/context.h:
(ContextImp::pushScope): Make inline, use push instead of prepend, and pass imp pointer.
(ContextImp::popScope): Make inline, use pop instead of removeFirst.
* kjs/function.cpp: (DeclaredFunctionImp::DeclaredFunctionImp): No need to copy.
* kjs/function_object.cpp: (FunctionObjectImp::construct): Use push instead of
prepend, and pass imp pointer.
* kjs/internal.cpp: (ContextImp::ContextImp): Use clear, push instead of prepend,
and pass imp pointers.
* kjs/nodes.cpp: (ResolveNode::evaluateReference): Use isEmpty, pop, and top instead
of ScopeChainIterator.
* kjs/object.h: Change _scope to be a NoRefScopeChain.
* kjs/object.cpp: No need to initialize _scope any more, since it's not a NoRefScopeChain.
* kjs/scope_chain.h: Rewrite, different implementation and interface.
* kjs/scope_chain.cpp: More of the same.
WebCore:
* khtml/ecma/kjs_dom.cpp: (DOMNode::pushEventHandlerScope): Change to push handlers
on an existing scope chain rather than returning one. Name change too.
* khtml/ecma/kjs_dom.h: More of the same.
* khtml/ecma/kjs_html.cpp: (KJS::HTMLElement::pushEventHandlerScope): And here.
* khtml/ecma/kjs_html.h: And here.
* khtml/ecma/kjs_events.cpp: (JSEventListener::handleEvent): Use the pushEventHandlerScope
function, and also don't worry about optimizing the "no change" case, because that already
works pretty efficiently.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@2824 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 56c82a7..fb72c15 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,23 @@
+2002-11-22 Darin Adler <darin at apple.com>
+
+ - change ScopeChain to be a singly linked list shares tails, gives 11% gain on iBench
+
+ * kjs/context.h:
+ (ContextImp::pushScope): Make inline, use push instead of prepend, and pass imp pointer.
+ (ContextImp::popScope): Make inline, use pop instead of removeFirst.
+ * kjs/function.cpp: (DeclaredFunctionImp::DeclaredFunctionImp): No need to copy.
+ * kjs/function_object.cpp: (FunctionObjectImp::construct): Use push instead of
+ prepend, and pass imp pointer.
+ * kjs/internal.cpp: (ContextImp::ContextImp): Use clear, push instead of prepend,
+ and pass imp pointers.
+ * kjs/nodes.cpp: (ResolveNode::evaluateReference): Use isEmpty, pop, and top instead
+ of ScopeChainIterator.
+ * kjs/object.h: Change _scope to be a NoRefScopeChain.
+ * kjs/object.cpp: No need to initialize _scope any more, since it's not a NoRefScopeChain.
+
+ * kjs/scope_chain.h: Rewrite, different implementation and interface.
+ * kjs/scope_chain.cpp: More of the same.
+
2002-11-22 Maciej Stachowiak <mjs at apple.com>
- a simple change for .5% gain on ibench - instead of unmarking
diff --git a/JavaScriptCore/ChangeLog-2002-12-03 b/JavaScriptCore/ChangeLog-2002-12-03
index 56c82a7..fb72c15 100644
--- a/JavaScriptCore/ChangeLog-2002-12-03
+++ b/JavaScriptCore/ChangeLog-2002-12-03
@@ -1,3 +1,23 @@
+2002-11-22 Darin Adler <darin at apple.com>
+
+ - change ScopeChain to be a singly linked list shares tails, gives 11% gain on iBench
+
+ * kjs/context.h:
+ (ContextImp::pushScope): Make inline, use push instead of prepend, and pass imp pointer.
+ (ContextImp::popScope): Make inline, use pop instead of removeFirst.
+ * kjs/function.cpp: (DeclaredFunctionImp::DeclaredFunctionImp): No need to copy.
+ * kjs/function_object.cpp: (FunctionObjectImp::construct): Use push instead of
+ prepend, and pass imp pointer.
+ * kjs/internal.cpp: (ContextImp::ContextImp): Use clear, push instead of prepend,
+ and pass imp pointers.
+ * kjs/nodes.cpp: (ResolveNode::evaluateReference): Use isEmpty, pop, and top instead
+ of ScopeChainIterator.
+ * kjs/object.h: Change _scope to be a NoRefScopeChain.
+ * kjs/object.cpp: No need to initialize _scope any more, since it's not a NoRefScopeChain.
+
+ * kjs/scope_chain.h: Rewrite, different implementation and interface.
+ * kjs/scope_chain.cpp: More of the same.
+
2002-11-22 Maciej Stachowiak <mjs at apple.com>
- a simple change for .5% gain on ibench - instead of unmarking
diff --git a/JavaScriptCore/ChangeLog-2003-10-25 b/JavaScriptCore/ChangeLog-2003-10-25
index 56c82a7..fb72c15 100644
--- a/JavaScriptCore/ChangeLog-2003-10-25
+++ b/JavaScriptCore/ChangeLog-2003-10-25
@@ -1,3 +1,23 @@
+2002-11-22 Darin Adler <darin at apple.com>
+
+ - change ScopeChain to be a singly linked list shares tails, gives 11% gain on iBench
+
+ * kjs/context.h:
+ (ContextImp::pushScope): Make inline, use push instead of prepend, and pass imp pointer.
+ (ContextImp::popScope): Make inline, use pop instead of removeFirst.
+ * kjs/function.cpp: (DeclaredFunctionImp::DeclaredFunctionImp): No need to copy.
+ * kjs/function_object.cpp: (FunctionObjectImp::construct): Use push instead of
+ prepend, and pass imp pointer.
+ * kjs/internal.cpp: (ContextImp::ContextImp): Use clear, push instead of prepend,
+ and pass imp pointers.
+ * kjs/nodes.cpp: (ResolveNode::evaluateReference): Use isEmpty, pop, and top instead
+ of ScopeChainIterator.
+ * kjs/object.h: Change _scope to be a NoRefScopeChain.
+ * kjs/object.cpp: No need to initialize _scope any more, since it's not a NoRefScopeChain.
+
+ * kjs/scope_chain.h: Rewrite, different implementation and interface.
+ * kjs/scope_chain.cpp: More of the same.
+
2002-11-22 Maciej Stachowiak <mjs at apple.com>
- a simple change for .5% gain on ibench - instead of unmarking
diff --git a/JavaScriptCore/kjs/context.h b/JavaScriptCore/kjs/context.h
index 5e0be1f..880b447 100644
--- a/JavaScriptCore/kjs/context.h
+++ b/JavaScriptCore/kjs/context.h
@@ -46,8 +46,8 @@ namespace KJS {
FunctionImp *function() const { return _function; }
const List *arguments() const { return _arguments; }
- void pushScope(const Object &s);
- void popScope();
+ void pushScope(const Object &s) { scope.push(s.imp()); }
+ void popScope() { scope.pop(); }
LabelStack *seenLabels() { return &ls; }
void mark();
diff --git a/JavaScriptCore/kjs/function.cpp b/JavaScriptCore/kjs/function.cpp
index 7315a5a..b95ba8a 100644
--- a/JavaScriptCore/kjs/function.cpp
+++ b/JavaScriptCore/kjs/function.cpp
@@ -260,7 +260,7 @@ DeclaredFunctionImp::DeclaredFunctionImp(ExecState *exec, const Identifier &n,
{
Value protect(this);
body->ref();
- setScope(sc.copy());
+ setScope(sc);
}
DeclaredFunctionImp::~DeclaredFunctionImp()
diff --git a/JavaScriptCore/kjs/function_object.cpp b/JavaScriptCore/kjs/function_object.cpp
index 826e5e0..fc63137 100644
--- a/JavaScriptCore/kjs/function_object.cpp
+++ b/JavaScriptCore/kjs/function_object.cpp
@@ -234,7 +234,7 @@ Object FunctionObjectImp::construct(ExecState *exec, const List &args)
}
ScopeChain scopeChain;
- scopeChain.prepend(exec->interpreter()->globalObject());
+ scopeChain.push(exec->interpreter()->globalObject().imp());
FunctionBodyNode *bodyNode = progNode;
FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null, bodyNode,
diff --git a/JavaScriptCore/kjs/internal.cpp b/JavaScriptCore/kjs/internal.cpp
index a84b747..c930558 100644
--- a/JavaScriptCore/kjs/internal.cpp
+++ b/JavaScriptCore/kjs/internal.cpp
@@ -377,25 +377,25 @@ ContextImp::ContextImp(Object &glob, InterpreterImp *interpreter, Object &thisV,
switch(type) {
case EvalCode:
if (_callingContext) {
- scope = _callingContext->scopeChain().copy();
+ scope = _callingContext->scopeChain();
variable = _callingContext->variableObject();
thisVal = _callingContext->thisValue();
break;
} // else same as GlobalCode
case GlobalCode:
- scope = ScopeChain();
- scope.prepend(glob);
+ scope.clear();
+ scope.push(glob.imp());
thisVal = Object(static_cast<ObjectImp*>(glob.imp()));
break;
case FunctionCode:
case AnonymousCode:
if (type == FunctionCode) {
- scope = func->scope().copy();
- scope.prepend(activation);
+ scope = func->scope();
+ scope.push(activation.imp());
} else {
- scope = ScopeChain();
- scope.prepend(glob);
- scope.prepend(activation);
+ scope.clear();
+ scope.push(glob.imp());
+ scope.push(activation.imp());
}
variable = activation; // TODO: DontDelete ? (ECMA 10.2.3)
thisVal = thisV;
@@ -410,16 +410,6 @@ ContextImp::~ContextImp()
_interpreter->setContext(_callingContext);
}
-void ContextImp::pushScope(const Object &s)
-{
- scope.prepend(s);
-}
-
-void ContextImp::popScope()
-{
- scope.removeFirst();
-}
-
void ContextImp::mark()
{
for (ContextImp *context = this; context; context = context->_callingContext)
diff --git a/JavaScriptCore/kjs/nodes.cpp b/JavaScriptCore/kjs/nodes.cpp
index 5e4949e..4d5d453 100644
--- a/JavaScriptCore/kjs/nodes.cpp
+++ b/JavaScriptCore/kjs/nodes.cpp
@@ -218,11 +218,10 @@ Value ResolveNode::evaluate(ExecState *exec)
Reference ResolveNode::evaluateReference(ExecState *exec)
{
- const ScopeChain chain = exec->context().scopeChain();
- ScopeChainIterator scope = chain.begin();
+ ScopeChain chain = exec->context().scopeChain();
- while (scope != chain.end()) {
- ObjectImp *o = static_cast<ObjectImp*>((*scope).imp());
+ while (!chain.isEmpty()) {
+ ObjectImp *o = chain.top();
//cout << "Resolve: looking at '" << ident.ascii() << "'"
// << " in " << (void*)o << " " << o->classInfo()->className << endl;
@@ -231,7 +230,8 @@ Reference ResolveNode::evaluateReference(ExecState *exec)
// << " in " << (void*)o << " " << o->classInfo()->className << endl;
return Reference(o, ident);
}
- scope++;
+
+ chain.pop();
}
// identifier not found
diff --git a/JavaScriptCore/kjs/object.cpp b/JavaScriptCore/kjs/object.cpp
index b6dd5a2..1d514a7 100644
--- a/JavaScriptCore/kjs/object.cpp
+++ b/JavaScriptCore/kjs/object.cpp
@@ -53,19 +53,18 @@ Object Object::dynamicCast(const Value &v)
// ------------------------------ ObjectImp ------------------------------------
ObjectImp::ObjectImp(const Object &proto)
- : _proto(static_cast<ObjectImp*>(proto.imp())), _internalValue(0L), _scope(true)
+ : _proto(static_cast<ObjectImp*>(proto.imp())), _internalValue(0L)
{
//fprintf(stderr,"ObjectImp::ObjectImp %p\n",(void*)this);
}
ObjectImp::ObjectImp(ObjectImp *proto)
- : _proto(proto), _internalValue(0L), _scope(true)
+ : _proto(proto), _internalValue(0L)
{
//fprintf(stderr,"ObjectImp::ObjectImp %p\n",(void*)this);
}
-ObjectImp::ObjectImp() :
- _scope(true)
+ObjectImp::ObjectImp()
{
//fprintf(stderr,"ObjectImp::ObjectImp %p\n",(void*)this);
_proto = NullImp::staticNull;
diff --git a/JavaScriptCore/kjs/object.h b/JavaScriptCore/kjs/object.h
index 05c5155..69d78d0 100644
--- a/JavaScriptCore/kjs/object.h
+++ b/JavaScriptCore/kjs/object.h
@@ -602,7 +602,7 @@ namespace KJS {
PropertyMap _prop;
ValueImp *_proto;
ValueImp *_internalValue;
- ScopeChain _scope;
+ NoRefScopeChain _scope;
};
/**
diff --git a/JavaScriptCore/kjs/scope_chain.cpp b/JavaScriptCore/kjs/scope_chain.cpp
index c3fd770..a9ec527 100644
--- a/JavaScriptCore/kjs/scope_chain.cpp
+++ b/JavaScriptCore/kjs/scope_chain.cpp
@@ -1,8 +1,6 @@
-// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
- * Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
- * Copyright (C) 2001 Peter Kelly (pmk at post.com)
+ * Copyright (C) 2002 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,209 +21,113 @@
#include "scope_chain.h"
-namespace KJS {
-
- struct ScopeChainNode {
- ScopeChainNode(const Value &val, ScopeChainNode *p, ScopeChainNode *n)
- : member(val.imp()), prev(p), next(n) { }
- ScopeChainNode(ValueImp *val, ScopeChainNode *p, ScopeChainNode *n)
- : member(val), prev(p), next(n) { }
- ValueImp *member;
- ScopeChainNode *prev, *next;
- };
-
- struct ScopeChainHookNode : public ScopeChainNode {
- ScopeChainHookNode(bool needsMarking) : ScopeChainNode(Value(), this, this),
- listRefCount(1), nodesRefCount(needsMarking ? 0 : 1) { }
- int listRefCount;
- int nodesRefCount;
- };
-
-// ------------------------------ ScopeChainIterator ---------------------------------
-
-ValueImp* ScopeChainIterator::operator->() const
-{
- return node->member;
-}
-
-Value ScopeChainIterator::operator*() const
-{
- return Value(node->member);
-}
-
-Value ScopeChainIterator::operator++()
-{
- node = node->next;
- return Value(node->member);
-}
-
-Value ScopeChainIterator::operator++(int)
-{
- const ScopeChainNode *n = node;
- ++*this;
- return Value(n->member);
-}
-
-// ------------------------------ ScopeChain -----------------------------------------
-
-ScopeChain::ScopeChain(bool needsMarking) : hook(new ScopeChainHookNode(needsMarking)), m_needsMarking(needsMarking)
-{
-}
-
-ScopeChain::ScopeChain(const ScopeChain& l) : hook(l.hook), m_needsMarking(false)
-{
- ++hook->listRefCount;
- if (hook->nodesRefCount++ == 0)
- refAll();
-}
-
-ScopeChain& ScopeChain::operator=(const ScopeChain& l)
-{
- ScopeChain(l).swap(*this);
- return *this;
-}
-
-ScopeChain::~ScopeChain()
-{
- if (!m_needsMarking)
- if (--hook->nodesRefCount == 0)
- derefAll();
-
- if (--hook->listRefCount == 0) {
- assert(hook->nodesRefCount == 0);
- clearInternal();
- delete hook;
- }
-}
-
-void ScopeChain::mark() const
-{
- ScopeChainNode *n = hook->next;
- while (n != hook) {
- if (!n->member->marked())
- n->member->mark();
- n = n->next;
- }
-}
-
-void ScopeChain::append(const Value& val)
-{
- ScopeChainNode *n = new ScopeChainNode(val, hook->prev, hook);
- if (hook->nodesRefCount)
- n->member->ref();
- hook->prev->next = n;
- hook->prev = n;
-}
-
-void ScopeChain::prepend(const Value& val)
-{
- ScopeChainNode *n = new ScopeChainNode(val, hook, hook->next);
- if (hook->nodesRefCount)
- n->member->ref();
- hook->next->prev = n;
- hook->next = n;
-}
+#include "object.h"
-void ScopeChain::prepend(ValueImp *val)
-{
- ScopeChainNode *n = new ScopeChainNode(val, hook, hook->next);
- if (hook->nodesRefCount)
- n->member->ref();
- hook->next->prev = n;
- hook->next = n;
-}
+namespace KJS {
-void ScopeChain::prependList(const ScopeChain& lst)
+ScopeChainNode::ScopeChainNode(ScopeChainNode *n, ObjectImp *o)
+ : next(n), object(o), nodeAndObjectRefCount(1), nodeOnlyRefCount(0)
{
- ScopeChainNode *otherHook = lst.hook;
- ScopeChainNode *n = otherHook->prev;
- while (n != otherHook) {
- prepend(n->member);
- n = n->prev;
- }
+ o->ref();
}
-void ScopeChain::removeFirst()
+inline void ScopeChain::ref() const
{
- erase(hook->next);
+ for (ScopeChainNode *n = _node; n; n = n->next) {
+ if (n->nodeAndObjectRefCount++ != 0)
+ break;
+ n->object->ref();
+ }
}
-void ScopeChain::clearInternal()
+ScopeChain::ScopeChain(const NoRefScopeChain &c)
+ : _node(c._node)
{
- ScopeChainNode *n = hook->next;
- while (n != hook) {
- n = n->next;
- delete n->prev;
- }
-
- hook->next = hook;
- hook->prev = hook;
+ ref();
}
-ScopeChain ScopeChain::copy() const
+ScopeChain &ScopeChain::operator=(const ScopeChain &c)
{
- ScopeChain newScopeChain;
- newScopeChain.prependList(*this);
- return newScopeChain;
+ c.ref();
+ deref();
+ _node = c._node;
+ return *this;
}
-ScopeChainIterator ScopeChain::begin() const
+void ScopeChain::push(ObjectImp *o)
{
- return ScopeChainIterator(hook->next);
+ _node = new ScopeChainNode(_node, o);
}
-ScopeChainIterator ScopeChain::end() const
+void ScopeChain::pop()
{
- return ScopeChainIterator(hook);
+ ScopeChainNode *oldNode = _node;
+ assert(oldNode);
+ ScopeChainNode *newNode = oldNode->next;
+ _node = newNode;
+
+ // Three cases:
+ // 1) This was not the last reference of the old node.
+ // In this case we move our ref from the old to the new node.
+ // 2) This was the last reference of the old node, but there are garbage collected references.
+ // In this case, the new node doesn't get any new ref, and the object is deref'd.
+ // 3) This was the last reference of the old node.
+ // In this case the object is deref'd and the entire node goes.
+ if (--oldNode->nodeAndObjectRefCount != 0) {
+ if (newNode)
+ ++newNode->nodeAndObjectRefCount;
+ } else {
+ oldNode->object->deref();
+ if (oldNode->nodeOnlyRefCount == 0)
+ delete oldNode;
+ }
}
-void ScopeChain::erase(ScopeChainNode *n)
+void ScopeChain::release()
{
- if (n != hook) {
- if (hook->nodesRefCount)
- n->member->deref();
- n->next->prev = n->prev;
- n->prev->next = n->next;
- delete n;
- }
+ ScopeChainNode *n = _node;
+ do {
+ ScopeChainNode *next = n->next;
+ n->object->deref();
+ if (n->nodeOnlyRefCount == 0)
+ delete n;
+ n = next;
+ } while (n && --n->nodeAndObjectRefCount == 0);
}
-void ScopeChain::refAll() const
+inline void NoRefScopeChain::ref() const
{
- for (ScopeChainNode *n = hook->next; n != hook; n = n->next)
- n->member->ref();
+ for (ScopeChainNode *n = _node; n; n = n->next)
+ if (n->nodeOnlyRefCount++ != 0)
+ break;
}
-void ScopeChain::derefAll() const
+NoRefScopeChain &NoRefScopeChain::operator=(const ScopeChain &c)
{
- for (ScopeChainNode *n = hook->next; n != hook; n = n->next)
- n->member->deref();
+ c.ref();
+ deref();
+ _node = c._node;
+ return *this;
}
-void ScopeChain::swap(ScopeChain &other)
+void NoRefScopeChain::mark()
{
- if (!m_needsMarking)
- if (other.hook->nodesRefCount++ == 0)
- other.refAll();
- if (!other.m_needsMarking)
- if (hook->nodesRefCount++ == 0)
- refAll();
-
- if (!m_needsMarking)
- if (--hook->nodesRefCount == 0)
- derefAll();
- if (!other.m_needsMarking)
- if (--other.hook->nodesRefCount == 0)
- other.derefAll();
-
- ScopeChainHookNode *tmp = hook;
- hook = other.hook;
- other.hook = tmp;
+ for (ScopeChainNode *n = _node; n; n = n->next) {
+ ObjectImp *o = n->object;
+ if (!o->marked())
+ o->mark();
+ }
}
-bool ScopeChain::isEmpty() const
+void NoRefScopeChain::release()
{
- return hook->next == hook;
+ ScopeChainNode *n = _node;
+ do {
+ ScopeChainNode *next = n->next;
+ if (n->nodeAndObjectRefCount == 0)
+ delete n;
+ n = next;
+ } while (n && --n->nodeOnlyRefCount == 0);
}
} // namespace KJS
diff --git a/JavaScriptCore/kjs/scope_chain.h b/JavaScriptCore/kjs/scope_chain.h
index 469eb17..bd7d5d7 100644
--- a/JavaScriptCore/kjs/scope_chain.h
+++ b/JavaScriptCore/kjs/scope_chain.h
@@ -1,8 +1,6 @@
-// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
- * Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
- * Copyright (C) 2001 Peter Kelly (pmk at post.com)
+ * Copyright (C) 2002 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,124 +22,70 @@
#ifndef KJS_SCOPE_CHAIN_H
#define KJS_SCOPE_CHAIN_H
-#include "value.h"
-
-// internal data types
-
namespace KJS {
- class ScopeChain;
- class ScopeChainIterator;
- class ScopeChainNode;
- class ScopeChainHookNode;
-
- /**
- * @short Iterator for @ref KJS::ScopeChain objects.
- */
- class ScopeChainIterator {
- friend class ScopeChain;
- ScopeChainIterator() : node(0) { }
- ScopeChainIterator(ScopeChainNode *n) : node(n) { }
- public:
- /**
- * Construct an iterator that points to the first element of the list.
- * @param l The list the iterator will operate on.
- */
- ScopeChainIterator(const ScopeChain &l);
- /**
- * Dereference the iterator.
- * @return A pointer to the element the iterator operates on.
- */
- ValueImp* operator->() const;
- Value operator*() const;
- /**
- * Postfix increment operator.
- * @return The element after the increment.
- */
- Value operator++();
- /**
- * Prefix increment operator.
- */
- Value operator++(int);
- /**
- * Compare the iterator with another one.
- * @return True if the two iterators operate on the same list element.
- * False otherwise.
- */
- bool operator==(const ScopeChainIterator &it) const { return node == it.node; }
- /**
- * Check for inequality with another iterator.
- * @return True if the two iterators operate on different list elements.
- */
- bool operator!=(const ScopeChainIterator &it) const { return node != it.node; }
- private:
- ScopeChainNode *node;
- };
-
- /**
- * @short Native list type.
- *
- * ScopeChain is a native ECMAScript type. ScopeChain values are only used for
- * intermediate results of expression evaluation and cannot be stored
- * as properties of objects.
- *
- * The list is explicitly shared. Note that while copy() returns a
- * copy of the list the referenced objects are still shared.
- */
- class ScopeChain {
- friend class ScopeChainIterator;
- public:
- ScopeChain(bool needsMarking = false);
- ScopeChain(const ScopeChain& l);
- ScopeChain &operator=(const ScopeChain& l);
-
- ~ScopeChain();
-
- /**
- * Insert an object at the beginning of the list.
- *
- * @param val Pointer to object.
- */
- void prepend(const Value& val);
- /**
- * Remove the element at the beginning of the list.
- */
- void removeFirst();
- /**
- * Returns a shallow copy of the list. Ownership is passed to the user
- * who is responsible for deleting the list then.
- */
- ScopeChain copy() const;
- /**
- * @return A @ref KJS::ScopeChainIterator pointing to the first element.
- */
- ScopeChainIterator begin() const;
- /**
- * @return A @ref KJS::ScopeChainIterator pointing to the last element.
- */
- ScopeChainIterator end() const;
-
- bool isEmpty() const;
+ class NoRefScopeChain;
+ class ObjectImp;
- void mark() const;
+ class ScopeChainNode {
+ public:
+ ScopeChainNode(ScopeChainNode *n, ObjectImp *o);
- // temporary
- void prependList(const ScopeChain &);
- void append(const Value &);
+ ScopeChainNode *next;
+ ObjectImp *object;
+ short nodeAndObjectRefCount;
+ short nodeOnlyRefCount;
+ };
- private:
+ class ScopeChain {
+ friend class NoRefScopeChain;
+ public:
+ ScopeChain() : _node(0) { }
+ ~ScopeChain() { deref(); }
- void prepend(ValueImp *val);
- void erase(ScopeChainNode *n);
- void clearInternal();
- void refAll() const;
- void derefAll() const;
- void swap(ScopeChain &other);
-
- ScopeChainHookNode *hook;
- bool m_needsMarking;
- };
-
-}; // namespace
+ ScopeChain(const ScopeChain &c) : _node(c._node)
+ { if (_node) ++_node->nodeAndObjectRefCount; }
+ ScopeChain(const NoRefScopeChain &);
+ ScopeChain &operator=(const ScopeChain &);
+
+ bool isEmpty() const { return !_node; }
+ ObjectImp *top() const { return _node->object; }
+
+ void clear() { deref(); _node = 0; }
+ void push(ObjectImp *);
+ void pop();
+
+ private:
+ ScopeChainNode *_node;
+
+ void deref() { if (_node && --_node->nodeAndObjectRefCount == 0) release(); }
+ void ref() const;
+
+ void release();
+ };
+
+ class NoRefScopeChain {
+ friend class ScopeChain;
+ public:
+ NoRefScopeChain() : _node(0) { }
+ ~NoRefScopeChain() { deref(); }
+
+ NoRefScopeChain &operator=(const ScopeChain &c);
+
+ void mark();
+
+ private:
+ ScopeChainNode *_node;
+
+ void deref() { if (_node && --_node->nodeOnlyRefCount == 0) release(); }
+ void ref() const;
+
+ void release();
+
+ NoRefScopeChain(const NoRefScopeChain &);
+ NoRefScopeChain &operator=(const NoRefScopeChain &);
+ };
+
+}; // namespace KJS
#endif // KJS_SCOPE_CHAIN_H
diff --git a/WebCore/ChangeLog-2002-12-03 b/WebCore/ChangeLog-2002-12-03
index 8bae0fb..2732b69 100644
--- a/WebCore/ChangeLog-2002-12-03
+++ b/WebCore/ChangeLog-2002-12-03
@@ -1,3 +1,15 @@
+2002-11-22 Darin Adler <darin at apple.com>
+
+ * khtml/ecma/kjs_dom.cpp: (DOMNode::pushEventHandlerScope): Change to push handlers
+ on an existing scope chain rather than returning one. Name change too.
+ * khtml/ecma/kjs_dom.h: More of the same.
+ * khtml/ecma/kjs_html.cpp: (KJS::HTMLElement::pushEventHandlerScope): And here.
+ * khtml/ecma/kjs_html.h: And here.
+
+ * khtml/ecma/kjs_events.cpp: (JSEventListener::handleEvent): Use the pushEventHandlerScope
+ function, and also don't worry about optimizing the "no change" case, because that already
+ works pretty efficiently.
+
2002-11-22 David Hyatt <hyatt at apple.com>
Fix for the weather.com, slate and espn malformations that
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 8bae0fb..2732b69 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,15 @@
+2002-11-22 Darin Adler <darin at apple.com>
+
+ * khtml/ecma/kjs_dom.cpp: (DOMNode::pushEventHandlerScope): Change to push handlers
+ on an existing scope chain rather than returning one. Name change too.
+ * khtml/ecma/kjs_dom.h: More of the same.
+ * khtml/ecma/kjs_html.cpp: (KJS::HTMLElement::pushEventHandlerScope): And here.
+ * khtml/ecma/kjs_html.h: And here.
+
+ * khtml/ecma/kjs_events.cpp: (JSEventListener::handleEvent): Use the pushEventHandlerScope
+ function, and also don't worry about optimizing the "no change" case, because that already
+ works pretty efficiently.
+
2002-11-22 David Hyatt <hyatt at apple.com>
Fix for the weather.com, slate and espn malformations that
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 8bae0fb..2732b69 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,15 @@
+2002-11-22 Darin Adler <darin at apple.com>
+
+ * khtml/ecma/kjs_dom.cpp: (DOMNode::pushEventHandlerScope): Change to push handlers
+ on an existing scope chain rather than returning one. Name change too.
+ * khtml/ecma/kjs_dom.h: More of the same.
+ * khtml/ecma/kjs_html.cpp: (KJS::HTMLElement::pushEventHandlerScope): And here.
+ * khtml/ecma/kjs_html.h: And here.
+
+ * khtml/ecma/kjs_events.cpp: (JSEventListener::handleEvent): Use the pushEventHandlerScope
+ function, and also don't worry about optimizing the "no change" case, because that already
+ works pretty efficiently.
+
2002-11-22 David Hyatt <hyatt at apple.com>
Fix for the weather.com, slate and espn malformations that
diff --git a/WebCore/force-js-clean-timestamp b/WebCore/force-js-clean-timestamp
index f188739..6efee9f 100644
--- a/WebCore/force-js-clean-timestamp
+++ b/WebCore/force-js-clean-timestamp
@@ -1 +1 @@
-List -> ScopeChain 11/21 - Darin
+ScopeChain API 11/21 - Darin
diff --git a/WebCore/khtml/ecma/kjs_dom.cpp b/WebCore/khtml/ecma/kjs_dom.cpp
index 5b41a31..c69ca1d 100644
--- a/WebCore/khtml/ecma/kjs_dom.cpp
+++ b/WebCore/khtml/ecma/kjs_dom.cpp
@@ -415,9 +415,8 @@ Value DOMNode::getListener(int eventId) const
return Null();
}
-ScopeChain DOMNode::eventHandlerScope(ExecState *) const
+void DOMNode::pushEventHandlerScope(ExecState *, ScopeChain &) const
{
- return ScopeChain();
}
Value DOMNodeProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
diff --git a/WebCore/khtml/ecma/kjs_dom.h b/WebCore/khtml/ecma/kjs_dom.h
index 67bd378..3084c59 100644
--- a/WebCore/khtml/ecma/kjs_dom.h
+++ b/WebCore/khtml/ecma/kjs_dom.h
@@ -51,7 +51,7 @@ namespace KJS {
virtual UString toString(ExecState *exec) const;
void setListener(ExecState *exec, int eventId, Value func) const;
Value getListener(int eventId) const;
- virtual ScopeChain eventHandlerScope(ExecState *exec) const;
+ virtual void pushEventHandlerScope(ExecState *exec, ScopeChain &scope) const;
enum { NodeName, NodeValue, NodeType, ParentNode, ParentElement,
ChildNodes, FirstChild, LastChild, PreviousSibling, NextSibling,
diff --git a/WebCore/khtml/ecma/kjs_events.cpp b/WebCore/khtml/ecma/kjs_events.cpp
index f9c5cc8..92454b8 100644
--- a/WebCore/khtml/ecma/kjs_events.cpp
+++ b/WebCore/khtml/ecma/kjs_events.cpp
@@ -72,16 +72,12 @@ void JSEventListener::handleEvent(DOM::Event &evt)
// Add the event's target element to the scope
// (and the document, and the form - see KJS::HTMLElement::eventHandlerScope)
Object thisObj = Object::dynamicCast(getDOMNode(exec,evt.currentTarget()));
- ScopeChain scope;
ScopeChain oldScope = listener.scope();
//if (thisVal.type() != NullType)
if ( !thisObj.isNull() ) {
- scope = static_cast<DOMNode*>(thisObj.imp())->eventHandlerScope(exec);
- if ( !scope.isEmpty() ) {
- ScopeChain curScope = oldScope.copy();
- curScope.prependList( scope );
- listener.setScope( curScope );
- }
+ ScopeChain scope = oldScope;
+ static_cast<DOMNode*>(thisObj.imp())->pushEventHandlerScope(exec, scope);
+ listener.setScope( scope );
}
Window *window = static_cast<Window*>(win.imp());
@@ -92,9 +88,7 @@ void JSEventListener::handleEvent(DOM::Event &evt)
Value retval = listener.call(exec, thisObj, args);
- if ( !scope.isEmpty() ) {
- listener.setScope( oldScope );
- }
+ listener.setScope( oldScope );
window->setCurrentEvent( 0 );
interpreter->setCurrentEvent( 0 );
diff --git a/WebCore/khtml/ecma/kjs_html.cpp b/WebCore/khtml/ecma/kjs_html.cpp
index dd95a3d..95594cd 100644
--- a/WebCore/khtml/ecma/kjs_html.cpp
+++ b/WebCore/khtml/ecma/kjs_html.cpp
@@ -1739,23 +1739,22 @@ UString KJS::HTMLElement::toString(ExecState *exec) const
return DOMElement::toString(exec);
}
-ScopeChain KJS::HTMLElement::eventHandlerScope(ExecState *exec) const
+void KJS::HTMLElement::pushEventHandlerScope(ExecState *exec, ScopeChain &scope) const
{
DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
- ScopeChain scope;
- // The element is the first one, so that it is the most prioritary
- scope.append(getDOMNode(exec,element));
+ // The document is put on first, fall back to searching it only after the element and form.
+ scope.push(static_cast<ObjectImp *>(getDOMNode(exec, element.ownerDocument()).imp()));
+ // The form is next, searched before the document, but after the element itself.
DOM::Node form = element.parentNode();
while (!form.isNull() && form.elementId() != ID_FORM)
form = form.parentNode();
if (!form.isNull())
- scope.append(getDOMNode(exec,form));
+ scope.push(static_cast<ObjectImp *>(getDOMNode(exec, form).imp()));
- // The document is the last one, so that it is the least prioritary
- scope.append(getDOMNode(exec,element.ownerDocument()));
- return scope;
+ // The element is on top, searched first.
+ scope.push(static_cast<ObjectImp *>(getDOMNode(exec, element).imp()));
}
HTMLElementFunction::HTMLElementFunction(ExecState *exec, int i, int len)
diff --git a/WebCore/khtml/ecma/kjs_html.h b/WebCore/khtml/ecma/kjs_html.h
index 8d2affd..b43d8cd 100644
--- a/WebCore/khtml/ecma/kjs_html.h
+++ b/WebCore/khtml/ecma/kjs_html.h
@@ -61,7 +61,7 @@ namespace KJS {
void putValue(ExecState *exec, int token, const Value& value, int);
virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
virtual UString toString(ExecState *exec) const;
- virtual ScopeChain eventHandlerScope(ExecState *exec) const;
+ virtual void pushEventHandlerScope(ExecState *exec, ScopeChain &scope) const;
virtual const ClassInfo* classInfo() const;
static const ClassInfo info;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list