The JSC code generator doesn't generate correct code for Constructors
[WebKit-https.git] / Source / WebCore / bindings / scripts / test / V8 / V8TestObj.cpp
index 05b747f..98c6eeb 100644 (file)
 #include "config.h"
 #include "V8TestObj.h"
 
+#include "Dictionary.h"
 #include "ExceptionCode.h"
 #include "HTMLNames.h"
 #include "IDBBindingUtilities.h"
 #include "IDBKey.h"
-#include "OptionsObject.h"
 #include "RuntimeEnabledFeatures.h"
 #include "SVGPropertyTearOff.h"
 #include "SVGStaticPropertyTearOff.h"
 #include "ScriptArguments.h"
 #include "ScriptCallStack.h"
 #include "ScriptCallStackFactory.h"
+#include "ScriptProfile.h"
 #include "SerializedScriptValue.h"
 #include "V8Binding.h"
 #include "V8BindingMacros.h"
@@ -42,6 +43,7 @@
 #include "V8Proxy.h"
 #include "V8SVGDocument.h"
 #include "V8SVGPoint.h"
+#include "V8ScriptProfile.h"
 #include "V8TestCallback.h"
 #include "V8a.h"
 #include "V8any.h"
@@ -51,6 +53,7 @@
 #include "V8d.h"
 #include "V8e.h"
 #include "V8int.h"
+#include "V8sequence.h"
 #include <wtf/GetPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
@@ -217,6 +220,22 @@ static void testObjAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Valu
     return;
 }
 
+static v8::Handle<v8::Value> sequenceAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+    INC_STATS("DOM.TestObj.sequenceAttr._get");
+    TestObj* imp = V8TestObj::toNative(info.Holder());
+    return v8Array(imp->sequenceAttr());
+}
+
+static void sequenceAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+    INC_STATS("DOM.TestObj.sequenceAttr._set");
+    TestObj* imp = V8TestObj::toNative(info.Holder());
+    Vector<ScriptProfile> v = toNativeArray(value);
+    imp->setSequenceAttr(v);
+    return;
+}
+
 static v8::Handle<v8::Value> XMLObjAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     INC_STATS("DOM.TestObj.XMLObjAttr._get");
@@ -885,7 +904,7 @@ static v8::Handle<v8::Value> contentDocumentAttrGetter(v8::Local<v8::String> nam
     INC_STATS("DOM.TestObj.contentDocument._get");
     TestObj* imp = V8TestObj::toNative(info.Holder());
     if (!V8BindingSecurity::shouldAllowAccessToNode(V8BindingState::Only(), imp->contentDocument()))
-    return v8::Handle<v8::Value>();
+        return v8::Handle<v8::Value>(v8::Null());
 
     return toV8(imp->contentDocument());
 }
@@ -1035,6 +1054,27 @@ static v8::Handle<v8::Value> objMethodWithArgsCallback(const v8::Arguments& args
     return toV8(imp->objMethodWithArgs(intArg, strArg, objArg));
 }
 
+static v8::Handle<v8::Value> methodWithSequenceArgCallback(const v8::Arguments& args)
+{
+    INC_STATS("DOM.TestObj.methodWithSequenceArg");
+    if (args.Length() < 1)
+        return throwError("Not enough arguments", V8Proxy::TypeError);
+    TestObj* imp = V8TestObj::toNative(args.Holder());
+    EXCEPTION_BLOCK(sequence*, , V8sequence::HasInstance(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined)) ? V8sequence::toNative(v8::Handle<v8::Object>::Cast(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined))) : 0);
+    imp->methodWithSequenceArg();
+    return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> methodReturningSequenceCallback(const v8::Arguments& args)
+{
+    INC_STATS("DOM.TestObj.methodReturningSequence");
+    if (args.Length() < 1)
+        return throwError("Not enough arguments", V8Proxy::TypeError);
+    TestObj* imp = V8TestObj::toNative(args.Holder());
+    EXCEPTION_BLOCK(int, intArg, toInt32(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined)));
+    return v8Array(imp->methodReturningSequence(intArg));
+}
+
 static v8::Handle<v8::Value> methodThatRequiresAllArgsAndThrowsCallback(const v8::Arguments& args)
 {
     INC_STATS("DOM.TestObj.methodThatRequiresAllArgsAndThrows");
@@ -1086,7 +1126,7 @@ static v8::Handle<v8::Value> optionsObjectCallback(const v8::Arguments& args)
     if (args.Length() < 1)
         return throwError("Not enough arguments", V8Proxy::TypeError);
     TestObj* imp = V8TestObj::toNative(args.Holder());
-    EXCEPTION_BLOCK(OptionsObject, oo, MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined));
+    EXCEPTION_BLOCK(Dictionary, oo, MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined));
     if (args.Length() > 0 && !oo.isUndefinedOrNull() && !oo.isObject()) {
         ec = TYPE_MISMATCH_ERR;
         V8Proxy::setDOMException(ec);
@@ -1096,7 +1136,7 @@ static v8::Handle<v8::Value> optionsObjectCallback(const v8::Arguments& args)
         imp->optionsObject(oo);
         return v8::Handle<v8::Value>();
     }
-    EXCEPTION_BLOCK(OptionsObject, ooo, MAYBE_MISSING_PARAMETER(args, 1, DefaultIsUndefined));
+    EXCEPTION_BLOCK(Dictionary, ooo, MAYBE_MISSING_PARAMETER(args, 1, DefaultIsUndefined));
     if (args.Length() > 1 && !ooo.isUndefinedOrNull() && !ooo.isObject()) {
         ec = TYPE_MISMATCH_ERR;
         V8Proxy::setDOMException(ec);
@@ -1364,7 +1404,7 @@ static v8::Handle<v8::Value> methodWithCallbackArgCallback(const v8::Arguments&
     if (args.Length() < 1)
         return throwError("Not enough arguments", V8Proxy::TypeError);
     TestObj* imp = V8TestObj::toNative(args.Holder());
-    if (args.Length() <= 0 || !args[0]->IsObject())
+    if (args.Length() <= 0 || !args[0]->IsFunction())
         return throwError(TYPE_MISMATCH_ERR);
     RefPtr<TestCallback> callback = V8TestCallback::create(args[0], getScriptExecutionContext());
     imp->methodWithCallbackArg(callback);
@@ -1378,7 +1418,7 @@ static v8::Handle<v8::Value> methodWithNonCallbackArgAndCallbackArgCallback(cons
         return throwError("Not enough arguments", V8Proxy::TypeError);
     TestObj* imp = V8TestObj::toNative(args.Holder());
     EXCEPTION_BLOCK(int, nonCallback, toInt32(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined)));
-    if (args.Length() <= 1 || !args[1]->IsObject())
+    if (args.Length() <= 1 || !args[1]->IsFunction())
         return throwError(TYPE_MISMATCH_ERR);
     RefPtr<TestCallback> callback = V8TestCallback::create(args[1], getScriptExecutionContext());
     imp->methodWithNonCallbackArgAndCallbackArg(nonCallback, callback);
@@ -1391,7 +1431,7 @@ static v8::Handle<v8::Value> methodWithCallbackAndOptionalArgCallback(const v8::
     TestObj* imp = V8TestObj::toNative(args.Holder());
     RefPtr<TestCallback> callback;
     if (args.Length() > 0 && !args[0]->IsNull() && !args[0]->IsUndefined()) {
-        if (!args[0]->IsObject())
+        if (!args[0]->IsFunction())
             return throwError(TYPE_MISMATCH_ERR);
         callback = V8TestCallback::create(args[0], getScriptExecutionContext());
     }
@@ -1490,7 +1530,7 @@ static v8::Handle<v8::Value> overloadedMethod5Callback(const v8::Arguments& args
     if (args.Length() < 1)
         return throwError("Not enough arguments", V8Proxy::TypeError);
     TestObj* imp = V8TestObj::toNative(args.Holder());
-    if (args.Length() <= 0 || !args[0]->IsObject())
+    if (args.Length() <= 0 || !args[0]->IsFunction())
         return throwError(TYPE_MISMATCH_ERR);
     RefPtr<TestCallback> callback = V8TestCallback::create(args[0], getScriptExecutionContext());
     imp->overloadedMethod(callback);
@@ -1530,7 +1570,7 @@ static v8::Handle<v8::Value> overloadedMethodCallback(const v8::Arguments& args)
         return overloadedMethod3Callback(args);
     if (args.Length() == 1)
         return overloadedMethod4Callback(args);
-    if ((args.Length() == 1 && (args[0]->IsNull() || args[0]->IsObject())))
+    if ((args.Length() == 1 && (args[0]->IsNull() || args[0]->IsFunction())))
         return overloadedMethod5Callback(args);
     if ((args.Length() == 1 && (args[0]->IsNull() || V8DOMStringList::HasInstance(args[0]))))
         return overloadedMethod6Callback(args);
@@ -1629,7 +1669,7 @@ static v8::Handle<v8::Value> getSVGDocumentCallback(const v8::Arguments& args)
     ExceptionCode ec = 0;
     {
     if (!V8BindingSecurity::shouldAllowAccessToNode(V8BindingState::Only(), imp->getSVGDocument(ec)))
-        return v8::Handle<v8::Value>();
+        return v8::Handle<v8::Value>(v8::Null());
     RefPtr<SVGDocument> result = imp->getSVGDocument(ec);
     if (UNLIKELY(ec))
         goto fail;
@@ -1761,6 +1801,8 @@ static const BatchedAttribute TestObjAttrs[] = {
     {"stringAttr", TestObjInternal::stringAttrAttrGetter, TestObjInternal::stringAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
     // Attribute 'testObjAttr' (Type: 'attribute' ExtAttr: '')
     {"testObjAttr", TestObjInternal::testObjAttrAttrGetter, TestObjInternal::testObjAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+    // Attribute 'sequenceAttr' (Type: 'attribute' ExtAttr: '')
+    {"sequenceAttr", TestObjInternal::sequenceAttrAttrGetter, TestObjInternal::sequenceAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
     // Attribute 'XMLObjAttr' (Type: 'attribute' ExtAttr: '')
     {"XMLObjAttr", TestObjInternal::XMLObjAttrAttrGetter, TestObjInternal::XMLObjAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
     // Attribute 'create' (Type: 'attribute' ExtAttr: '')
@@ -1861,6 +1903,7 @@ static const BatchedCallback TestObjCallbacks[] = {
     {"voidMethod", TestObjInternal::voidMethodCallback},
     {"intMethod", TestObjInternal::intMethodCallback},
     {"objMethod", TestObjInternal::objMethodCallback},
+    {"methodReturningSequence", TestObjInternal::methodReturningSequenceCallback},
     {"serializedValue", TestObjInternal::serializedValueCallback},
     {"idbKey", TestObjInternal::idbKeyCallback},
     {"optionsObject", TestObjInternal::optionsObjectCallback},
@@ -1948,8 +1991,13 @@ v8::Handle<v8::Value> V8TestObj::constructorCallback(const v8::Arguments& args)
 
     if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
         return args.Holder();
+    if (args.Length() < 1)
+        return throwError("Not enough arguments", V8Proxy::TypeError);
+    if (args.Length() <= 0 || !args[0]->IsFunction())
+        return throwError(TYPE_MISMATCH_ERR);
+    RefPtr<TestCallback> testCallback = V8TestCallback::create(args[0], getScriptExecutionContext());
 
-    RefPtr<TestObj> impl = TestObj::create();
+    RefPtr<TestObj> impl = TestObj::create(testCallback);
     v8::Handle<v8::Object> wrapper = args.Holder();
 
     V8DOMWrapper::setDOMWrapper(wrapper, &info, impl.get());
@@ -2004,6 +2052,12 @@ static v8::Persistent<v8::FunctionTemplate> ConfigureV8TestObjTemplate(v8::Persi
     v8::Handle<v8::Signature> objMethodWithArgsSignature = v8::Signature::New(desc, objMethodWithArgsArgc, objMethodWithArgsArgv);
     proto->Set(v8::String::New("objMethodWithArgs"), v8::FunctionTemplate::New(TestObjInternal::objMethodWithArgsCallback, v8::Handle<v8::Value>(), objMethodWithArgsSignature));
 
+    // Custom Signature 'methodWithSequenceArg'
+    const int methodWithSequenceArgArgc = 1;
+    v8::Handle<v8::FunctionTemplate> methodWithSequenceArgArgv[methodWithSequenceArgArgc] = { V8sequence::GetRawTemplate() };
+    v8::Handle<v8::Signature> methodWithSequenceArgSignature = v8::Signature::New(desc, methodWithSequenceArgArgc, methodWithSequenceArgArgv);
+    proto->Set(v8::String::New("methodWithSequenceArg"), v8::FunctionTemplate::New(TestObjInternal::methodWithSequenceArgCallback, v8::Handle<v8::Value>(), methodWithSequenceArgSignature));
+
     // Custom Signature 'methodThatRequiresAllArgsAndThrows'
     const int methodThatRequiresAllArgsAndThrowsArgc = 2;
     v8::Handle<v8::FunctionTemplate> methodThatRequiresAllArgsAndThrowsArgv[methodThatRequiresAllArgsAndThrowsArgc] = { v8::Handle<v8::FunctionTemplate>(), V8TestObj::GetRawTemplate() };
@@ -2089,20 +2143,19 @@ bool V8TestObj::HasInstance(v8::Handle<v8::Value> value)
 }
 
 
-v8::Handle<v8::Object> V8TestObj::wrapSlow(TestObj* impl)
+v8::Handle<v8::Object> V8TestObj::wrapSlow(PassRefPtr<TestObj> impl)
 {
     v8::Handle<v8::Object> wrapper;
     V8Proxy* proxy = 0;
-    wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl);
+    wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl.get());
     if (UNLIKELY(wrapper.IsEmpty()))
         return wrapper;
 
-    impl->ref();
     v8::Persistent<v8::Object> wrapperHandle = v8::Persistent<v8::Object>::New(wrapper);
 
     if (!hasDependentLifetime)
         wrapperHandle.MarkIndependent();
-    getDOMObjectMap().set(impl, wrapperHandle);
+    getDOMObjectMap().set(impl.leakRef(), wrapperHandle);
     return wrapper;
 }