Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / inspector / ScriptArguments.cpp
index 292274a..c126dc7 100644 (file)
 #include "config.h"
 #include "core/inspector/ScriptArguments.h"
 
-#include "bindings/v8/ScriptValue.h"
-#include "bindings/v8/V8Binding.h"
+#include "bindings/core/v8/ScriptValue.h"
+#include "bindings/core/v8/V8Binding.h"
+#include "wtf/text/StringBuilder.h"
+#include <v8.h>
 
-namespace WebCore {
+namespace blink {
 
-PassRefPtr<ScriptArguments> ScriptArguments::create(ScriptState* scriptState, Vector<ScriptValue>& arguments)
+namespace {
+
+static const unsigned maxArrayItemsLimit = 10000;
+static const unsigned maxStackDepthLimit = 32;
+
+class V8ValueStringBuilder {
+public:
+    static String toString(v8::Handle<v8::Value> value, v8::Isolate* isolate)
+    {
+        V8ValueStringBuilder builder(isolate);
+        if (!builder.append(value))
+            return String();
+        return builder.toString();
+    }
+
+private:
+    enum {
+        IgnoreNull = 1 << 0,
+        IgnoreUndefined = 1 << 1,
+    };
+
+    V8ValueStringBuilder(v8::Isolate* isolate)
+        : m_arrayLimit(maxArrayItemsLimit)
+        , m_isolate(isolate)
+    {
+    }
+
+    bool append(v8::Handle<v8::Value> value, unsigned ignoreOptions = 0)
+    {
+        if (value.IsEmpty())
+            return true;
+        if ((ignoreOptions & IgnoreNull) && value->IsNull())
+            return true;
+        if ((ignoreOptions & IgnoreUndefined) && value->IsUndefined())
+            return true;
+        if (value->IsString())
+            return append(v8::Handle<v8::String>::Cast(value));
+        if (value->IsStringObject())
+            return append(v8::Handle<v8::StringObject>::Cast(value)->ValueOf());
+        if (value->IsSymbol())
+            return append(v8::Handle<v8::Symbol>::Cast(value));
+        if (value->IsSymbolObject())
+            return append(v8::Handle<v8::SymbolObject>::Cast(value)->ValueOf());
+        if (value->IsNumberObject()) {
+            m_builder.appendNumber(v8::Handle<v8::NumberObject>::Cast(value)->ValueOf());
+            return true;
+        }
+        if (value->IsBooleanObject()) {
+            m_builder.append(v8::Handle<v8::BooleanObject>::Cast(value)->ValueOf() ? "true" : "false");
+            return true;
+        }
+        if (value->IsArray())
+            return append(v8::Handle<v8::Array>::Cast(value));
+        if (toDOMWindow(value, m_isolate)) {
+            m_builder.append("[object Window]");
+            return true;
+        }
+        if (value->IsObject()
+            && !value->IsDate()
+            && !value->IsFunction()
+            && !value->IsNativeError()
+            && !value->IsRegExp())
+            return append(v8::Handle<v8::Object>::Cast(value)->ObjectProtoToString());
+        return append(value->ToString());
+    }
+
+    bool append(v8::Handle<v8::Array> array)
+    {
+        if (m_visitedArrays.contains(array))
+            return true;
+        uint32_t length = array->Length();
+        if (length > m_arrayLimit)
+            return false;
+        if (m_visitedArrays.size() > maxStackDepthLimit)
+            return false;
+
+        bool result = true;
+        m_arrayLimit -= length;
+        m_visitedArrays.append(array);
+        for (uint32_t i = 0; i < length; ++i) {
+            if (i)
+                m_builder.append(',');
+            if (!append(array->Get(i), IgnoreNull | IgnoreUndefined)) {
+                result = false;
+                break;
+            }
+        }
+        m_visitedArrays.removeLast();
+        return result;
+    }
+
+    bool append(v8::Handle<v8::Symbol> symbol)
+    {
+        m_builder.appendLiteral("Symbol(");
+        bool result = append(symbol->Name(), IgnoreUndefined);
+        m_builder.append(')');
+        return result;
+    }
+
+    bool append(v8::Handle<v8::String> string)
+    {
+        if (m_tryCatch.HasCaught())
+            return false;
+        if (!string.IsEmpty())
+            m_builder.append(toCoreString(string));
+        return true;
+    }
+
+    String toString()
+    {
+        if (m_tryCatch.HasCaught())
+            return String();
+        return m_builder.toString();
+    }
+
+    uint32_t m_arrayLimit;
+    v8::Isolate* m_isolate;
+    StringBuilder m_builder;
+    Vector<v8::Handle<v8::Array> > m_visitedArrays;
+    v8::TryCatch m_tryCatch;
+};
+
+} // namespace
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptArguments)
+
+PassRefPtrWillBeRawPtr<ScriptArguments> ScriptArguments::create(ScriptState* scriptState, Vector<ScriptValue>& arguments)
 {
-    return adoptRef(new ScriptArguments(scriptState, arguments));
+    return adoptRefWillBeNoop(new ScriptArguments(scriptState, arguments));
 }
 
 ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>& arguments)
@@ -47,31 +175,21 @@ ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>&
     m_arguments.swap(arguments);
 }
 
-ScriptArguments::~ScriptArguments()
-{
-}
-
 const ScriptValue &ScriptArguments::argumentAt(size_t index) const
 {
     ASSERT(m_arguments.size() > index);
     return m_arguments[index];
 }
 
-bool ScriptArguments::getFirstArgumentAsString(String& result, bool checkForNullOrUndefined)
+bool ScriptArguments::getFirstArgumentAsString(String& result) const
 {
     if (!argumentCount())
         return false;
 
     const ScriptValue& value = argumentAt(0);
     ScriptState::Scope scope(m_scriptState.get());
-    if (checkForNullOrUndefined && (value.isNull() || value.isUndefined()))
-        return false;
-
-    // We intentionally ignore an exception that can be thrown in ToString().
-    v8::TryCatch block;
-    v8::Handle<v8::String> string = value.v8Value()->ToString();
-    result = string.IsEmpty() ? String() : toCoreString(string);
+    result = V8ValueStringBuilder::toString(value.v8Value(), value.isolate());
     return true;
 }
 
-} // namespace WebCore
+} // namespace blink