Roll out r34020 as it causes recursion tests to fail.
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 May 2008 09:53:25 +0000 (09:53 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 May 2008 09:53:25 +0000 (09:53 +0000)
RS=Maciej

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@34024 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/object.cpp

index db610d1..6b25f38 100644 (file)
@@ -1,5 +1,14 @@
 2008-05-22  Oliver Hunt  <oliver@apple.com>
 
+        RS=Maciej.
+
+        Roll out r34020 as it causes recursion tests to fail.
+
+        * kjs/object.cpp:
+        (KJS::JSObject::call):
+
+2008-05-22  Oliver Hunt  <oliver@apple.com>
+
         Reviewed by Mark.
 
         Don't leak the SymbolTable when compiling eval code.
index 6be6c08..1a5b8d6 100644 (file)
 #include <profiler/Profiler.h>
 #include <wtf/Assertions.h>
 
+// maximum global call stack size. Protects against accidental or
+// malicious infinite recursions. Define to -1 if you want no limit.
+// In real-world testing it appears ok to bump the stack depth count to 500.
+// This of course is dependent on stack frame size.
+#define KJS_MAX_STACK 500
+
+#define JAVASCRIPT_CALL_TRACING 0
 #define JAVASCRIPT_MARK_TRACING 0
 
+#if JAVASCRIPT_CALL_TRACING
+static bool _traceJavaScript = false;
+
+extern "C" {
+    void setTraceJavaScript(bool f)
+    {
+        _traceJavaScript = f;
+    }
+
+    static bool traceJavaScript()
+    {
+        return _traceJavaScript;
+    }
+}
+#endif
+
 namespace KJS {
 
 // ------------------------------ Object ---------------------------------------
@@ -44,6 +67,31 @@ JSValue *JSObject::call(ExecState *exec, JSObject *thisObj, const List &args)
 {
   ASSERT(implementsCall());
 
+#if KJS_MAX_STACK > 0
+  static int depth = 0; // sum of all extant function calls
+
+#if JAVASCRIPT_CALL_TRACING
+    static bool tracing = false;
+    if (traceJavaScript() && !tracing) {
+        tracing = true;
+        for (int i = 0; i < depth; i++)
+            putchar (' ');
+        printf ("*** calling:  %s\n", toString(exec).ascii());
+        for (int j = 0; j < args.size(); j++) {
+            for (int i = 0; i < depth; i++)
+                putchar (' ');
+            printf ("*** arg[%d] = %s\n", j, args[j]->toString(exec).ascii());
+        }
+        tracing = false;
+    }
+#endif
+
+  if (++depth > KJS_MAX_STACK) {
+    --depth;
+    return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+  }
+#endif
+
 #if JAVASCRIPT_PROFILING
     Profiler::profiler()->willExecute(exec, this);
 #endif
@@ -54,6 +102,21 @@ JSValue *JSObject::call(ExecState *exec, JSObject *thisObj, const List &args)
     Profiler::profiler()->didExecute(exec, this);
 #endif
 
+
+#if KJS_MAX_STACK > 0
+  --depth;
+#endif
+
+#if JAVASCRIPT_CALL_TRACING
+    if (traceJavaScript() && !tracing) {
+        tracing = true;
+        for (int i = 0; i < depth; i++)
+            putchar (' ');
+        printf ("*** returning:  %s\n", ret->toString(exec).ascii());
+        tracing = false;
+    }
+#endif
+
   return ret;
 }