+2006-09-27 Kevin McCullough <KMcCullough@apple.com>
+
+ Reviewed by Adele.
+
+ Fixes a GC stack overflow crash.
+ The change is to move from a linked list implementation of Parameters to a Vector.
+ The problem with the linked list is that each one creates it's own stack frame when being destroyed and in extreme cases this caused the stack to overflow.
+
+ * kjs/function.cpp:
+ (KJS::Parameter::Parameter):
+ (KJS::FunctionImp::addParameter):
+ (KJS::FunctionImp::parameterString):
+ (KJS::FunctionImp::processParameters):
+ (KJS::FunctionImp::lengthGetter):
+ (KJS::FunctionImp::getParameterName):
+ * kjs/function.h:
+
2006-09-27 Steve Falkenburg <sfalken@apple.com>
Fix last path fix.
class Parameter {
public:
+ Parameter() {};
Parameter(const Identifier &n) : name(n) { }
Identifier name;
- OwnPtr<Parameter> next;
+// OwnPtr<Parameter> next;
};
FunctionImp::FunctionImp(ExecState *exec, const Identifier &n, FunctionBodyNode* b)
void FunctionImp::addParameter(const Identifier &n)
{
- OwnPtr<Parameter> *p = ¶m;
- while (*p)
- p = &(*p)->next;
-
- p->set(new Parameter(n));
+ params.append(Parameter(n));
}
UString FunctionImp::parameterString() const
{
UString s;
- const Parameter *p = param.get();
- while (p) {
- if (!s.isEmpty())
- s += ", ";
- s += p->name.ustring();
- p = p->next.get();
- }
+
+ for(Vector<Parameter>::const_iterator it = params.begin(); it < params.end(); it++) {
+ if (!s.isEmpty())
+ s += ", ";
+ s += it->name.ustring();
+ }
return s;
}
name().isEmpty() ? "(internal)" : name().ascii());
#endif
- if (param) {
+ if(params.size() != 0) {
ListIterator it = args.begin();
- Parameter *p = param.get();
+
JSValue *v = *it;
- while (p) {
+ for(Vector<Parameter>::iterator pit = params.begin(); pit < params.end(); pit++) {
if (it != args.end()) {
#ifdef KJS_VERBOSE
fprintf(stderr, "setting parameter %s ", p->name.ascii());
printInfo(exec,"to", *it);
#endif
- variable->put(exec, p->name, v);
+ variable->put(exec, pit->name, v);
v = ++it;
} else
- variable->put(exec, p->name, jsUndefined());
- p = p->next.get();
+ variable->put(exec, pit->name, jsUndefined());
}
}
#ifdef KJS_VERBOSE
JSValue *FunctionImp::lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
{
- FunctionImp *thisObj = static_cast<FunctionImp *>(slot.slotBase());
- const Parameter *p = thisObj->param.get();
- int count = 0;
- while (p) {
- ++count;
- p = p->next.get();
- }
- return jsNumber(count);
+ FunctionImp *thisObj = static_cast<FunctionImp *>(slot.slotBase());
+ return jsNumber(thisObj->params.size());
}
bool FunctionImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
*/
Identifier FunctionImp::getParameterName(int index)
{
- int i = 0;
- Parameter *p = param.get();
-
- if(!p)
- return Identifier::null();
+ if(params.size() == 0)
+ return Identifier::null();
- // skip to the parameter we want
- while (i++ < index && (p = p->next.get()))
- ;
+ if (index > static_cast<int>(params.size()))
+ return Identifier::null();
- if (!p)
- return Identifier::null();
-
- Identifier name = p->name;
+ Identifier name = params[index].name;
- // Are there any subsequent parameters with the same name?
- while ((p = p->next.get()))
- if (p->name == name)
- return Identifier::null();
-
- return name;
+ // Are there any subsequent parameters with the same name?
+ for (Vector<Parameter>::iterator it = &(params[index+1]); it < params.end(); it++)
+ if (it->name == name)
+ return Identifier::null();
+
+ return name;
}
// ------------------------------ DeclaredFunctionImp --------------------------