Ignore:
Timestamp:
Mar 22, 2009, 11:01:46 PM (16 years ago)
Author:
[email protected]
Message:

Fix exception handling in API

Reviewed by Cameron Zwarich.

We can't just use the ExecState exception slot for returning exceptions
from class introspection functions provided through the API as many JSC
functions will explicitly clear the ExecState exception when returning.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/tests/testapi.c

    r41895 r41905  
    129129    if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")
    130130        || JSStringIsEqualToUTF8CString(propertyName, "cantFind")
     131        || JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")
    131132        || JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")
    132133        || JSStringIsEqualToUTF8CString(propertyName, "hasPropertyLie")
     
    154155        return JSValueMakeUndefined(context);
    155156    }
    156    
     157
     158    if (JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")) {
     159        return JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
     160    }
     161
    157162    if (JSStringIsEqualToUTF8CString(propertyName, "0")) {
    158163        *exception = JSValueMakeNumber(context, 1);
     
    173178        return true; // pretend we set the property in order to swallow it
    174179   
     180    if (JSStringIsEqualToUTF8CString(propertyName, "throwOnSet")) {
     181        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
     182    }
     183   
    175184    return false;
    176185}
     
    185194   
    186195    if (JSStringIsEqualToUTF8CString(propertyName, "throwOnDelete")) {
    187         *exception = JSValueMakeNumber(context, 2);
     196        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
    188197        return false;
    189198    }
     
    215224    UNUSED_PARAM(exception);
    216225
     226    if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnCall")) {
     227        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
     228        return JSValueMakeUndefined(context);
     229    }
     230
    217231    if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
    218232        return JSValueMakeNumber(context, 1);
     
    226240    UNUSED_PARAM(object);
    227241
     242    if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnConstruct")) {
     243        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
     244        return object;
     245    }
     246
    228247    if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
    229248        return JSValueToObject(context, JSValueMakeNumber(context, 1), exception);
     
    236255    UNUSED_PARAM(context);
    237256    UNUSED_PARAM(constructor);
     257
     258    if (JSValueIsString(context, possibleValue) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, possibleValue, 0), "throwOnHasInstance")) {
     259        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), constructor, JSStringCreateWithUTF8CString("test script"), 1, exception);
     260        return false;
     261    }
    238262
    239263    JSStringRef numberString = JSStringCreateWithUTF8CString("Number");
     
    310334    return jsClass;
    311335}
     336
     337static bool EvilExceptionObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception)
     338{
     339    UNUSED_PARAM(context);
     340    UNUSED_PARAM(constructor);
     341   
     342    JSStringRef hasInstanceName = JSStringCreateWithUTF8CString("hasInstance");
     343    JSValueRef hasInstance = JSObjectGetProperty(context, constructor, hasInstanceName, exception);
     344    JSStringRelease(hasInstanceName);
     345   
     346    JSObjectRef function = JSValueToObject(context, hasInstance, exception);
     347    JSValueRef result = JSObjectCallAsFunction(context, function, constructor, 1, &possibleValue, exception);
     348    return result && JSValueToBoolean(context, result);
     349}
     350
     351static JSValueRef EvilExceptionObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
     352{
     353    UNUSED_PARAM(object);
     354    UNUSED_PARAM(exception);
     355    JSStringRef funcName;
     356    switch (type) {
     357    case kJSTypeNumber:
     358        funcName = JSStringCreateWithUTF8CString("toNumber");
     359        break;
     360    case kJSTypeString:
     361        funcName = JSStringCreateWithUTF8CString("toStringExplicit");
     362        break;
     363    default:
     364        return NULL;
     365        break;
     366    }
     367   
     368    JSValueRef func = JSObjectGetProperty(context, object, funcName, exception);
     369    JSStringRelease(funcName);   
     370    JSObjectRef function = JSValueToObject(context, func, exception);
     371    if (!function)
     372        return NULL;
     373    JSValueRef value = JSObjectCallAsFunction(context, function, object, 0, NULL, exception);
     374    if (!value)
     375        return (JSValueRef)JSStringCreateWithUTF8CString("convertToType failed");
     376    return value;
     377}
     378
     379JSClassDefinition EvilExceptionObject_definition = {
     380    0,
     381    kJSClassAttributeNone,
     382
     383    "EvilExceptionObject",
     384    NULL,
     385
     386    NULL,
     387    NULL,
     388
     389    NULL,
     390    NULL,
     391    NULL,
     392    NULL,
     393    NULL,
     394    NULL,
     395    NULL,
     396    NULL,
     397    NULL,
     398    EvilExceptionObject_hasInstance,
     399    EvilExceptionObject_convertToType,
     400};
     401
     402static JSClassRef EvilExceptionObject_class(JSContextRef context)
     403{
     404    UNUSED_PARAM(context);
     405   
     406    static JSClassRef jsClass;
     407    if (!jsClass)
     408        jsClass = JSClassCreate(&EvilExceptionObject_definition);
     409   
     410    return jsClass;
     411}
     412
    312413
    313414static JSValueRef Base_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
     
    669770    JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);
    670771    JSStringRelease(myObjectIString);
     772   
     773    JSObjectRef EvilExceptionObject = JSObjectMake(context, EvilExceptionObject_class(context), NULL);
     774    JSStringRef EvilExceptionObjectIString = JSStringCreateWithUTF8CString("EvilExceptionObject");
     775    JSObjectSetProperty(context, globalObject, EvilExceptionObjectIString, EvilExceptionObject, kJSPropertyAttributeNone, NULL);
     776    JSStringRelease(EvilExceptionObjectIString);
    671777   
    672778    JSValueRef exception;
Note: See TracChangeset for help on using the changeset viewer.