/// <summary> Convert the value to a number.
 /// 
 /// See ECMA 9.3.
 /// </summary>
 public static double ToNumber (object val)
 {
     for (; ; ) {
         if (val is double)
             return (double)val;
         if (CliHelper.IsNumber (val))
             return Convert.ToDouble (val);
         if (val == null)
             return +0.0;
         if (val == Undefined.Value)
             return double.NaN;
         if (val is string)
             return ToNumber ((string)val);
         if (val is bool)
             return ((bool)val) ? 1 : +0.0;
         if (val is IScriptable) {
             val = ((IScriptable)val).GetDefaultValue (typeof (long));
             if (val is IScriptable)
                 throw ScriptRuntime.errorWithClassName ("msg.primitive.expected", val);
             continue;
         }
         ScriptRuntime.WarnAboutNonJSObject (val);
         return double.NaN;
     }
 }
 /// <summary> Convert the value to a boolean.
 /// 
 /// See ECMA 9.2.
 /// </summary>
 public static bool ToBoolean (object val)
 {
     for (; ; ) {
         if (val is bool)
             return ((bool)val);
         if (val == null || val == Undefined.Value)
             return false;
         if (val is string)
             return ((string)val).Length != 0;
         if (CliHelper.IsNumber (val)) {
             double d = Convert.ToDouble (val);
             return (!double.IsNaN (d) && d != 0.0);
         }
         if (val is IScriptable) {
             if (Context.CurrentContext.VersionECMA1) {
                 // pure ECMA
                 return true;
             }
             // ECMA extension
             val = ((IScriptable)val).GetDefaultValue (typeof (bool));
             if (val is IScriptable)
                 throw ScriptRuntime.errorWithClassName ("msg.primitive.expected", val);
             continue;
         }
         ScriptRuntime.WarnAboutNonJSObject (val);
         return true;
     }
 }