'length' property of DOM bindings functions returns wrong value
[WebKit-https.git] / Source / WebCore / bindings / scripts / test / JS / JSTestTypedefs.cpp
index eb79041..e58757b 100644 (file)
@@ -71,7 +71,7 @@ EncodedJSValue JSC_HOST_CALL JSTestTypedefsConstructor::constructJSTestTypedefs(
     JSTestTypedefsConstructor* castedThis = jsCast<JSTestTypedefsConstructor*>(exec->callee());
     if (exec->argumentCount() < 2)
         return throwVMError(exec, createNotEnoughArgumentsError(exec));
-    const String& hello(MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).isEmpty() ? String() : MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).toString(exec)->value(exec));
+    const String& hello(exec->argument(0).isEmpty() ? String() : exec->argument(0).toString(exec)->value(exec));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     if (exec->argumentCount() <= 1 || !exec->argument(1).isFunction())
@@ -90,10 +90,10 @@ JSTestTypedefsConstructor::JSTestTypedefsConstructor(Structure* structure, JSDOM
 
 void JSTestTypedefsConstructor::finishCreation(ExecState* exec, JSDOMGlobalObject* globalObject)
 {
-    Base::finishCreation(exec->globalData());
+    Base::finishCreation(exec->vm());
     ASSERT(inherits(&s_info));
-    putDirect(exec->globalData(), exec->propertyNames().prototype, JSTestTypedefsPrototype::self(exec, globalObject), DontDelete | ReadOnly);
-    putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
+    putDirect(exec->vm(), exec->propertyNames().prototype, JSTestTypedefsPrototype::self(exec, globalObject), DontDelete | ReadOnly);
+    putDirect(exec->vm(), exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
 }
 
 bool JSTestTypedefsConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
@@ -116,12 +116,12 @@ ConstructType JSTestTypedefsConstructor::getConstructData(JSCell*, ConstructData
 
 static const HashTableValue JSTestTypedefsPrototypeTableValues[] =
 {
-    { "func", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionFunc), (intptr_t)1, NoIntrinsic },
-    { "multiTransferList", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionMultiTransferList), (intptr_t)4, NoIntrinsic },
-    { "setShadow", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionSetShadow), (intptr_t)5, NoIntrinsic },
+    { "func", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionFunc), (intptr_t)0, NoIntrinsic },
+    { "multiTransferList", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionMultiTransferList), (intptr_t)1, NoIntrinsic },
+    { "setShadow", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionSetShadow), (intptr_t)3, NoIntrinsic },
     { "methodWithSequenceArg", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionMethodWithSequenceArg), (intptr_t)1, NoIntrinsic },
     { "nullableArrayArg", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionNullableArrayArg), (intptr_t)1, NoIntrinsic },
-    { "funcWithClamp", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionFuncWithClamp), (intptr_t)2, NoIntrinsic },
+    { "funcWithClamp", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionFuncWithClamp), (intptr_t)1, NoIntrinsic },
     { "immutablePointFunction", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionImmutablePointFunction), (intptr_t)0, NoIntrinsic },
     { "stringArrayFunction", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionStringArrayFunction), (intptr_t)1, NoIntrinsic },
     { "stringArrayFunction2", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestTypedefsPrototypeFunctionStringArrayFunction2), (intptr_t)1, NoIntrinsic },
@@ -157,15 +157,15 @@ JSTestTypedefs::JSTestTypedefs(Structure* structure, JSDOMGlobalObject* globalOb
 {
 }
 
-void JSTestTypedefs::finishCreation(JSGlobalData& globalData)
+void JSTestTypedefs::finishCreation(VM& vm)
 {
-    Base::finishCreation(globalData);
+    Base::finishCreation(vm);
     ASSERT(inherits(&s_info));
 }
 
 JSObject* JSTestTypedefs::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
 {
-    return JSTestTypedefsPrototype::create(exec->globalData(), globalObject, JSTestTypedefsPrototype::createStructure(globalObject->globalData(), globalObject, globalObject->objectPrototype()));
+    return JSTestTypedefsPrototype::create(exec->vm(), globalObject, JSTestTypedefsPrototype::createStructure(globalObject->vm(), globalObject, globalObject->objectPrototype()));
 }
 
 void JSTestTypedefs::destroy(JSC::JSCell* cell)
@@ -280,7 +280,10 @@ void setJSTestTypedefsUnsignedLongLongAttr(ExecState* exec, JSObject* thisObject
     UNUSED_PARAM(exec);
     JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
-    impl->setUnsignedLongLongAttr(static_cast<unsigned long long>(value.toInteger(exec)));
+    unsigned long long nativeValue(toUInt64(exec, value, NormalConversion));
+    if (exec->hadException())
+        return;
+    impl->setUnsignedLongLongAttr(nativeValue);
 }
 
 
@@ -289,7 +292,10 @@ void setJSTestTypedefsImmutableSerializedScriptValue(ExecState* exec, JSObject*
     UNUSED_PARAM(exec);
     JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
-    impl->setImmutableSerializedScriptValue(SerializedScriptValue::create(exec, value, 0, 0));
+    RefPtr<SerializedScriptValue> nativeValue(SerializedScriptValue::create(exec, value, 0, 0));
+    if (exec->hadException())
+        return;
+    impl->setImmutableSerializedScriptValue(nativeValue);
 }
 
 
@@ -298,7 +304,10 @@ void setJSTestTypedefsAttrWithGetterException(ExecState* exec, JSObject* thisObj
     UNUSED_PARAM(exec);
     JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
-    impl->setAttrWithGetterException(value.toInt32(exec));
+    int nativeValue(toInt32(exec, value, NormalConversion));
+    if (exec->hadException())
+        return;
+    impl->setAttrWithGetterException(nativeValue);
 }
 
 
@@ -308,7 +317,10 @@ void setJSTestTypedefsAttrWithSetterException(ExecState* exec, JSObject* thisObj
     JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
     ExceptionCode ec = 0;
-    impl->setAttrWithSetterException(value.toInt32(exec), ec);
+    int nativeValue(toInt32(exec, value, NormalConversion));
+    if (exec->hadException())
+        return;
+    impl->setAttrWithSetterException(nativeValue, ec);
     setDOMException(exec, ec);
 }
 
@@ -318,7 +330,10 @@ void setJSTestTypedefsStringAttrWithGetterException(ExecState* exec, JSObject* t
     UNUSED_PARAM(exec);
     JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
-    impl->setStringAttrWithGetterException(value.isEmpty() ? String() : value.toString(exec)->value(exec));
+    const String& nativeValue(value.isEmpty() ? String() : value.toString(exec)->value(exec));
+    if (exec->hadException())
+        return;
+    impl->setStringAttrWithGetterException(nativeValue);
 }
 
 
@@ -328,7 +343,10 @@ void setJSTestTypedefsStringAttrWithSetterException(ExecState* exec, JSObject* t
     JSTestTypedefs* castedThis = jsCast<JSTestTypedefs*>(thisObject);
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
     ExceptionCode ec = 0;
-    impl->setStringAttrWithSetterException(value.isEmpty() ? String() : value.toString(exec)->value(exec), ec);
+    const String& nativeValue(value.isEmpty() ? String() : value.toString(exec)->value(exec));
+    if (exec->hadException())
+        return;
+    impl->setStringAttrWithSetterException(nativeValue, ec);
     setDOMException(exec, ec);
 }
 
@@ -355,7 +373,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionFunc(ExecState* exec
 
     if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSlong[]::s_info))
         return throwVMTypeError(exec);
-    Vector<int> x(toNativeArray<int>(exec, MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined)));
+    Vector<int> x(toNativeArray<int>(exec, exec->argument(0)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     impl->func(x);
@@ -372,7 +390,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionMultiTransferList(Ex
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
     if (exec->argumentCount() < 1)
         return throwVMError(exec, createNotEnoughArgumentsError(exec));
-    RefPtr<SerializedScriptValue> first(SerializedScriptValue::create(exec, MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined), 0, 0));
+    RefPtr<SerializedScriptValue> first(SerializedScriptValue::create(exec, exec->argument(0), 0, 0));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
@@ -382,7 +400,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionMultiTransferList(Ex
         return JSValue::encode(jsUndefined());
     }
 
-    Array* tx(toArray(MAYBE_MISSING_PARAMETER(exec, 1, DefaultIsUndefined)));
+    Array* tx(toArray(exec->argument(1)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     if (argsCount <= 2) {
@@ -390,7 +408,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionMultiTransferList(Ex
         return JSValue::encode(jsUndefined());
     }
 
-    RefPtr<SerializedScriptValue> second(SerializedScriptValue::create(exec, MAYBE_MISSING_PARAMETER(exec, 2, DefaultIsUndefined), 0, 0));
+    RefPtr<SerializedScriptValue> second(SerializedScriptValue::create(exec, exec->argument(2), 0, 0));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     if (argsCount <= 3) {
@@ -398,7 +416,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionMultiTransferList(Ex
         return JSValue::encode(jsUndefined());
     }
 
-    Array* txx(toArray(MAYBE_MISSING_PARAMETER(exec, 3, DefaultIsUndefined)));
+    Array* txx(toArray(exec->argument(3)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     impl->multiTransferList(first, tx, second, txx);
@@ -415,13 +433,13 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionSetShadow(ExecState*
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
     if (exec->argumentCount() < 3)
         return throwVMError(exec, createNotEnoughArgumentsError(exec));
-    float width(MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).toFloat(exec));
+    float width(exec->argument(0).toFloat(exec));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
-    float height(MAYBE_MISSING_PARAMETER(exec, 1, DefaultIsUndefined).toFloat(exec));
+    float height(exec->argument(1).toFloat(exec));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
-    float blur(MAYBE_MISSING_PARAMETER(exec, 2, DefaultIsUndefined).toFloat(exec));
+    float blur(exec->argument(2).toFloat(exec));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
@@ -431,7 +449,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionSetShadow(ExecState*
         return JSValue::encode(jsUndefined());
     }
 
-    const String& color(MAYBE_MISSING_PARAMETER(exec, 3, DefaultIsUndefined).isEmpty() ? String() : MAYBE_MISSING_PARAMETER(exec, 3, DefaultIsUndefined).toString(exec)->value(exec));
+    const String& color(exec->argument(3).isEmpty() ? String() : exec->argument(3).toString(exec)->value(exec));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     if (argsCount <= 4) {
@@ -439,7 +457,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionSetShadow(ExecState*
         return JSValue::encode(jsUndefined());
     }
 
-    float alpha(MAYBE_MISSING_PARAMETER(exec, 4, DefaultIsUndefined).toFloat(exec));
+    float alpha(exec->argument(4).toFloat(exec));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     impl->setShadow(width, height, blur, color, alpha);
@@ -456,7 +474,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionMethodWithSequenceAr
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
     if (exec->argumentCount() < 1)
         return throwVMError(exec, createNotEnoughArgumentsError(exec));
-    Vector<RefPtr<SerializedScriptValue>> sequenceArg((toRefPtrNativeArray<SerializedScriptValue, JSSerializedScriptValue>(exec, MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined), &toSerializedScriptValue)));
+    Vector<RefPtr<SerializedScriptValue>> sequenceArg((toRefPtrNativeArray<SerializedScriptValue, JSSerializedScriptValue>(exec, exec->argument(0), &toSerializedScriptValue)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
@@ -474,7 +492,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionNullableArrayArg(Exe
     TestTypedefs* impl = static_cast<TestTypedefs*>(castedThis->impl());
     if (exec->argumentCount() < 1)
         return throwVMError(exec, createNotEnoughArgumentsError(exec));
-    Vector<String> arrayArg(toNativeArray<String>(exec, MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined)));
+    Vector<String> arrayArg(toNativeArray<String>(exec, exec->argument(0)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     impl->nullableArrayArg(arrayArg);
@@ -496,7 +514,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionFuncWithClamp(ExecSt
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
-    if (!isnan(arg1NativeValue))
+    if (!std::isnan(arg1NativeValue))
         arg1 = clampTo<unsigned long long>(arg1NativeValue);
 
 
@@ -511,7 +529,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionFuncWithClamp(ExecSt
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
-    if (!isnan(arg2NativeValue))
+    if (!std::isnan(arg2NativeValue))
         arg2 = clampTo<unsigned long long>(arg2NativeValue);
 
     impl->funcWithClamp(arg1, arg2);
@@ -542,7 +560,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionStringArrayFunction(
     if (exec->argumentCount() < 1)
         return throwVMError(exec, createNotEnoughArgumentsError(exec));
     ExceptionCode ec = 0;
-    Vector<String> values(toNativeArray<String>(exec, MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined)));
+    Vector<String> values(toNativeArray<String>(exec, exec->argument(0)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
@@ -562,7 +580,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionStringArrayFunction2
     if (exec->argumentCount() < 1)
         return throwVMError(exec, createNotEnoughArgumentsError(exec));
     ExceptionCode ec = 0;
-    Vector<String> values(toNativeArray<String>(exec, MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined)));
+    Vector<String> values(toNativeArray<String>(exec, exec->argument(0)));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
@@ -609,9 +627,40 @@ void JSTestTypedefsOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* conte
     jsTestTypedefs->releaseImpl();
 }
 
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern "C" { extern void (*const __identifier("??_7TestTypedefs@WebCore@@6B@")[])(); }
+#else
+extern "C" { extern void* _ZTVN7WebCore12TestTypedefsE[]; }
+#endif
+#endif
 JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, TestTypedefs* impl)
 {
-    return wrap<JSTestTypedefs>(exec, globalObject, impl);
+    if (!impl)
+        return jsNull();
+    if (JSValue result = getExistingWrapper<JSTestTypedefs>(exec, impl)) return result;
+
+#if ENABLE(BINDING_INTEGRITY)
+    void* actualVTablePointer = *(reinterpret_cast<void**>(impl));
+#if PLATFORM(WIN)
+    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7TestTypedefs@WebCore@@6B@"));
+#else
+    void* expectedVTablePointer = &_ZTVN7WebCore12TestTypedefsE[2];
+#if COMPILER(CLANG)
+    // If this fails TestTypedefs does not have a vtable, so you need to add the
+    // ImplementationLacksVTable attribute to the interface definition
+    COMPILE_ASSERT(__is_polymorphic(TestTypedefs), TestTypedefs_is_not_polymorphic);
+#endif
+#endif
+    // If you hit this assertion you either have a use after free bug, or
+    // TestTypedefs has subclasses. If TestTypedefs has subclasses that get passed
+    // to toJS() we currently require TestTypedefs you to opt out of binding hardening
+    // by adding the SkipVTableValidation attribute to the interface IDL definition
+    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+    ReportMemoryCost<TestTypedefs>::reportMemoryCost(exec, impl);
+    return createNewWrapper<JSTestTypedefs>(exec, globalObject, impl);
 }
 
 TestTypedefs* toTestTypedefs(JSC::JSValue value)