summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/ArrayPrototype.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp44
1 files changed, 13 insertions, 31 deletions
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index ab0c3d4..7615ffc 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2003 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
@@ -32,6 +32,7 @@
#include "Lookup.h"
#include "ObjectPrototype.h"
#include "Operations.h"
+#include "StringRecursionChecker.h"
#include <algorithm>
#include <wtf/Assertions.h>
#include <wtf/HashSet.h>
@@ -168,15 +169,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
return throwVMTypeError(exec);
JSArray* thisObj = asArray(thisValue);
- HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
- if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
- return throwVMError(exec, createStackOverflowError(exec));
- }
-
- bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
- if (alreadyVisited)
- return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoiding infinite recursion.
+ StringRecursionChecker checker(exec, thisObj);
+ if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
+ return earlyReturnValue;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned totalSize = length ? length - 1 : 0;
@@ -209,7 +204,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
if (exec->hadException())
break;
}
- arrayVisitedElements.remove(thisObj);
if (!totalSize)
return JSValue::encode(jsEmptyString(exec));
Vector<UChar> buffer;
@@ -234,15 +228,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
return throwVMTypeError(exec);
JSObject* thisObj = asArray(thisValue);
- HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
- if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
- return throwVMError(exec, createStackOverflowError(exec));
- }
-
- bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
- if (alreadyVisited)
- return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoding infinite recursion.
+ StringRecursionChecker checker(exec, thisObj);
+ if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
+ return earlyReturnValue;
JSStringBuilder strBuffer;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
@@ -264,7 +252,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
strBuffer.append(str);
}
}
- arrayVisitedElements.remove(thisObj);
+
return JSValue::encode(strBuffer.build(exec));
}
@@ -272,15 +260,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
- HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
- if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
- return throwVMError(exec, createStackOverflowError(exec));
- }
-
- bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
- if (alreadyVisited)
- return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoding infinite recursion.
+ StringRecursionChecker checker(exec, thisObj);
+ if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
+ return earlyReturnValue;
JSStringBuilder strBuffer;
@@ -335,7 +317,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
if (!element.isUndefinedOrNull())
strBuffer.append(element.toString(exec));
}
- arrayVisitedElements.remove(thisObj);
+
return JSValue::encode(strBuffer.build(exec));
}