On Apr 20, 2011, at 6:16 PM, Jian Li wrote:

> Hi,
> 
> I've just found a problem in our generated code for handling optional 
> parameters. Suppose we define a method with optional parameter in numeric 
> type, like the following in IDL:
>          Foo bar(in [Optional] long long start, in [Optional] long long end);
> 
> And we declare our C++ method as the following. Note that the default value 
> of the 2nd parameter is not 0.
>          PassRefPtr<Foo> bar(long long start = 0, long long end = 
> std::numeric_limits<long long>::max());
> 
> If we call the JS method with only 1 parameter, everything works as expected. 
> However, if we call the JS method with 2 parameters and pass 'undefined' as 
> the 2nd parameter, we trigger the problem.

Is it actually a bug that explicitly passing undefined acts like passing 0, 
instead of like an omitted parameter? I think it's correct per Web IDL. What's 
the specific case where this is a problem?

Regards,
Maciej

> 
> By looking into the generated JSC code below, I found out that we are 
> converting undefined JS value to 0 and pass it to the function. As the 
> result, the default parameter value in the declaration is not respected.
> EncodedJSValue JSC_HOST_CALL jsFooPrototypeFunctionFoo(ExecState* exec)
> {
> 
>     JSValue thisValue = exec->hostThisValue();
>     if (!thisValue.inherits(&JSFoo::s_info))
>         return throwVMTypeError(exec);
>     JSFoo* castedThis = static_cast<JSFoo*>(asObject(thisValue));
>     Foo* imp = static_cast<Foo*>(castedThis->impl());
> 
>     int argsCount = exec->argumentCount();
>     if (argsCount <= 0) {
>         JSC::JSValue result = toJS(exec, castedThis->globalObject(), 
> WTF::getPtr(imp->bar()));
>         return JSValue::encode(result);
>     }
> 
>     long long start(static_cast<long 
> long>(exec->argument(0).toInteger(exec)));
>     if (exec->hadException())
>         return JSValue::encode(jsUndefined());
>     if (argsCount <= 1) {
>         JSC::JSValue result = toJS(exec, castedThis->globalObject(), 
> WTF::getPtr(imp->bar(start)));
>         return JSValue::encode(result);
>     }
> 
>     long long end(static_cast<long long>(exec->argument(1).toInteger(exec)));
>     if (exec->hadException())
>         return JSValue::encode(jsUndefined());
> 
>     JSC::JSValue result = toJS(exec, castedThis->globalObject(), 
> WTF::getPtr(imp->bar(start, end)));
>     return JSValue::encode(result);
> }
> 
> One solution is to add the default value support in IDL. For example, we can 
> change the above definition of bar to something like:
>          Foo bar(in [Optional, DefaultValue=0] long long start, in [Optional, 
> DefaultValue=2147483647] long long end);
> 
> Or the other way is to add a bool parameter for each optional parameter in 
> the class method declaration, that is used to indicate if the passing 
> parameter is defined or not. This would involve the change to both code 
> generator scripts and the existing implementations.
> 
> How do you think? Personally I like the 1st approach since it is simpler.
> 
> Thanks,
> 
> Jian
> 
> 
> _______________________________________________
> webkit-dev mailing list
> webkit-dev@lists.webkit.org
> http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

Reply via email to