Changeset 35775 in webkit for trunk/JavaScriptCore/API


Ignore:
Timestamp:
Aug 15, 2008, 12:43:48 AM (17 years ago)
Author:
[email protected]
Message:

Reviewed by Geoff Garen.

JSStringRef is created context-free, but can get linked to one via an identifier table,
breaking an implicit API contract.

Made JSStringRef point to OpaqueJSString, which is a new string object separate from UString.

Location:
trunk/JavaScriptCore/API
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/APICast.h

    r35442 r35775  
    4141typedef const struct OpaqueJSContext* JSContextRef;
    4242typedef struct OpaqueJSContext* JSGlobalContextRef;
    43 typedef struct OpaqueJSString* JSStringRef;
    4443typedef struct OpaqueJSPropertyNameAccumulator* JSPropertyNameAccumulatorRef;
    4544typedef const struct OpaqueJSValue* JSValueRef;
     
    6160{
    6261    return reinterpret_cast<KJS::JSValue*>(const_cast<OpaqueJSValue*>(v));
    63 }
    64 
    65 inline KJS::UString::Rep* toJS(JSStringRef b)
    66 {
    67     return reinterpret_cast<KJS::UString::Rep*>(b);
    6862}
    6963
     
    9185{
    9286    return reinterpret_cast<JSValueRef*>(const_cast<const KJS::JSValue**>(v));
    93 }
    94 
    95 inline JSStringRef toRef(KJS::UString::Rep* s)
    96 {
    97     return reinterpret_cast<JSStringRef>(s);
    9887}
    9988
  • trunk/JavaScriptCore/API/JSBase.cpp

    r35604 r35775  
    3030#include "APICast.h"
    3131#include "completion.h"
     32#include "OpaqueJSString.h"
    3233#include <kjs/ExecState.h>
    3334#include <kjs/InitializeThreading.h>
     
    4445
    4546    JSObject* jsThisObject = toJS(thisObject);
    46     UString::Rep* scriptRep = toJS(script);
    47     UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
    4847
    4948    // Interpreter::evaluate sets "this" to the global object if it is NULL
    5049    JSGlobalObject* globalObject = exec->dynamicGlobalObject();
    51     Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), UString(sourceURLRep), startingLineNumber, UString(scriptRep), jsThisObject);
     50    Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), sourceURL->ustring(), startingLineNumber, script->ustring(), jsThisObject);
    5251
    5352    if (completion.complType() == Throw) {
     
    6968    exec->globalData().heap->registerThread();
    7069
    71     UString::Rep* scriptRep = toJS(script);
    72     UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
    73     Completion completion = Interpreter::checkSyntax(exec->dynamicGlobalObject()->globalExec(), UString(sourceURLRep), startingLineNumber, UString(scriptRep));
     70    Completion completion = Interpreter::checkSyntax(exec->dynamicGlobalObject()->globalExec(), sourceURL->ustring(), startingLineNumber, script->ustring());
    7471    if (completion.complType() == Throw) {
    7572        if (exception)
  • trunk/JavaScriptCore/API/JSCallbackObjectFunctions.h

    r35478 r35775  
    3434#include "JSString.h"
    3535#include "JSStringRef.h"
     36#include "OpaqueJSString.h"
    3637#include "PropertyNameArray.h"
    3738#include <wtf/Vector.h>
     
    106107    JSContextRef ctx = toRef(exec);
    107108    JSObjectRef thisRef = toRef(this);
    108     JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
     109    RefPtr<OpaqueJSString> propertyNameRef;
    109110   
    110111    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    111112        // optional optimization to bypass getProperty in cases when we only need to know if the property exists
    112113        if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
    113             if (hasProperty(ctx, thisRef, propertyNameRef)) {
     114            if (!propertyNameRef)
     115                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
     116            if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
    114117                slot.setCustom(this, callbackGetter);
    115118                return true;
    116119            }
    117120        } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
    118             if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) {
     121            if (!propertyNameRef)
     122                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
     123            if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot()))) {
    119124                // cache the value so we don't have to compute it again
    120125                // FIXME: This violates the PropertySlot design a little bit.
     
    154159    JSContextRef ctx = toRef(exec);
    155160    JSObjectRef thisRef = toRef(this);
    156     JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
     161    RefPtr<OpaqueJSString> propertyNameRef;
    157162    JSValueRef valueRef = toRef(value);
    158163   
    159164    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    160165        if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
    161             if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
     166            if (!propertyNameRef)
     167                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
     168            if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot())))
    162169                return;
    163170        }
     
    168175                    return;
    169176                if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
    170                     if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
     177                    if (!propertyNameRef)
     178                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
     179                    if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot())))
    171180                        return;
    172181                } else
     
    199208    JSContextRef ctx = toRef(exec);
    200209    JSObjectRef thisRef = toRef(this);
    201     JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
     210    RefPtr<OpaqueJSString> propertyNameRef;
    202211   
    203212    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    204213        if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
    205             if (deleteProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
     214            if (!propertyNameRef)
     215                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
     216            if (deleteProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
    206217                return true;
    207218        }
     
    431442   
    432443    JSObjectRef thisRef = toRef(thisObj);
    433     JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
     444    RefPtr<OpaqueJSString> propertyNameRef;
    434445   
    435446    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
     
    437448            if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep()))
    438449                if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
    439                     if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
     450                    if (!propertyNameRef)
     451                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
     452                    if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
    440453                        return toJS(value);
    441454                }
     
    477490   
    478491    JSObjectRef thisRef = toRef(thisObj);
    479     JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
     492    RefPtr<OpaqueJSString> propertyNameRef;
    480493   
    481494    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
    482495        if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
    483             if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
     496            if (!propertyNameRef)
     497                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
     498            if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
    484499                return toJS(value);
    485500        }
  • trunk/JavaScriptCore/API/JSObjectRef.cpp

    r35478 r35775  
    3737#include "JSGlobalObject.h"
    3838#include "JSObject.h"
     39#include "JSRetainPtr.h"
    3940#include "JSString.h"
    4041#include "JSValueRef.h"
     
    8687    exec->globalData().heap->registerThread();
    8788
    88     Identifier nameID = name ? Identifier(exec, toJS(name)) : Identifier(exec, "anonymous");
     89    Identifier nameID = name ? name->identifier(exec) : Identifier(exec, "anonymous");
    8990   
    9091    return toRef(new (exec) JSCallbackFunction(exec, callAsFunction, nameID));
     
    110111    exec->globalData().heap->registerThread();
    111112
    112     UString::Rep* bodyRep = toJS(body);
    113     UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
    114    
    115     Identifier nameID = name ? Identifier(exec, toJS(name)) : Identifier(exec, "anonymous");
     113    Identifier nameID = name ? name->identifier(exec) : Identifier(exec, "anonymous");
    116114   
    117115    ArgList args;
    118116    for (unsigned i = 0; i < parameterCount; i++)
    119         args.append(jsString(exec, UString(toJS(parameterNames[i]))));
    120     args.append(jsString(exec, UString(bodyRep)));
    121 
    122     JSObject* result = constructFunction(exec, args, nameID, UString(sourceURLRep), startingLineNumber);
     117        args.append(jsString(exec, UString(parameterNames[i]->ustring())));
     118    args.append(jsString(exec, body->ustring()));
     119
     120    JSObject* result = constructFunction(exec, args, nameID, sourceURL->ustring(), startingLineNumber);
    123121    if (exec->hadException()) {
    124122        if (exception)
     
    150148
    151149    JSObject* jsObject = toJS(object);
    152     UString::Rep* nameRep = toJS(propertyName);
    153    
    154     return jsObject->hasProperty(exec, Identifier(exec, nameRep));
     150   
     151    return jsObject->hasProperty(exec, propertyName->identifier(exec));
    155152}
    156153
     
    161158
    162159    JSObject* jsObject = toJS(object);
    163     UString::Rep* nameRep = toJS(propertyName);
    164 
    165     JSValue* jsValue = jsObject->get(exec, Identifier(exec, nameRep));
     160
     161    JSValue* jsValue = jsObject->get(exec, propertyName->identifier(exec));
    166162    if (exec->hadException()) {
    167163        if (exception)
     
    178174
    179175    JSObject* jsObject = toJS(object);
    180     Identifier name(exec, toJS(propertyName));
     176    Identifier name(propertyName->identifier(exec));
    181177    JSValue* jsValue = toJS(value);
    182178
     
    232228
    233229    JSObject* jsObject = toJS(object);
    234     UString::Rep* nameRep = toJS(propertyName);
    235 
    236     bool result = jsObject->deleteProperty(exec, Identifier(exec, nameRep));
     230
     231    bool result = jsObject->deleteProperty(exec,  propertyName->identifier(exec));
    237232    if (exec->hadException()) {
    238233        if (exception)
     
    338333}
    339334
    340 struct OpaqueJSPropertyNameArray
    341 {
    342     OpaqueJSPropertyNameArray(JSGlobalData* globalData) : refCount(0), array(globalData)
     335struct OpaqueJSPropertyNameArray {
     336    OpaqueJSPropertyNameArray(JSGlobalData* globalData)
     337        : refCount(0)
     338        , globalData(globalData)
    343339    {
    344340    }
    345341   
    346342    unsigned refCount;
    347     PropertyNameArray array;
     343    JSGlobalData* globalData;
     344    Vector<JSRetainPtr<JSStringRef> > array;
    348345};
    349346
     
    354351    exec->globalData().heap->registerThread();
    355352
    356     JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(&exec->globalData());
    357     jsObject->getPropertyNames(exec, propertyNames->array);
     353    JSGlobalData* globalData = &exec->globalData();
     354
     355    JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(globalData);
     356    PropertyNameArray array(globalData);
     357    jsObject->getPropertyNames(exec, array);
     358
     359    size_t size = array.size();
     360    propertyNames->array.reserveCapacity(size);
     361    for (size_t i = 0; i < size; ++i)
     362        propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].ustring()).releaseRef()));
    358363   
    359364    return JSPropertyNameArrayRetain(propertyNames);
     
    379384JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index)
    380385{
    381     return toRef(array->array[static_cast<unsigned>(index)].ustring().rep());
     386    return array->array[static_cast<unsigned>(index)].get();
    382387}
    383388
     
    385390{
    386391    PropertyNameArray* propertyNames = toJS(array);
    387     UString::Rep* rep = toJS(propertyName);
    388392
    389393    propertyNames->globalData()->heap->registerThread();
    390394
    391     propertyNames->add(Identifier(propertyNames->globalData(), rep));
    392 }
     395    propertyNames->add(propertyName->identifier(propertyNames->globalData()));
     396}
  • trunk/JavaScriptCore/API/JSStringRef.cpp

    r35478 r35775  
    2828#include "JSStringRef.h"
    2929
    30 #include <wtf/Platform.h>
    31 
    32 #include "APICast.h"
    33 #include <kjs/JSType.h>
    34 #include <kjs/JSString.h>
    35 #include <kjs/operations.h>
    36 #include <kjs/ustring.h>
    37 #include <kjs/JSValue.h>
     30#include "OpaqueJSString.h"
    3831#include <wtf/unicode/UTF8.h>
    3932
     
    4336JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars)
    4437{
    45     return toRef(UString(chars, static_cast<int>(numChars)).rep()->ref());
     38    return OpaqueJSString::create(chars, numChars).releaseRef();
    4639}
    4740
    4841JSStringRef JSStringCreateWithUTF8CString(const char* string)
    4942{
    50     RefPtr<UString::Rep> result = UString::Rep::createFromUTF8(string);
    51     if (result.get() == &UString::Rep::null)
    52         return 0;
     43    if (string) {
     44        size_t length = strlen(string);
     45        Vector<UChar, 1024> buffer(length);
     46        UChar* p = buffer.data();
     47        if (conversionOK == convertUTF8ToUTF16(&string, string + length, &p, p + length))
     48            return OpaqueJSString::create(buffer.data(), p - buffer.data()).releaseRef();
     49    }
    5350
    54     return toRef(result.release().releaseRef());
     51    // Null string.
     52    return OpaqueJSString::create().releaseRef();
    5553}
    5654
    5755JSStringRef JSStringRetain(JSStringRef string)
    5856{
    59     UString::Rep* rep = toJS(string);
    60     return toRef(rep->ref());
     57    string->ref();
     58    return string;
    6159}
    6260
    6361void JSStringRelease(JSStringRef string)
    6462{
    65     UString::Rep* rep = toJS(string);
    66     bool needsLocking = rep->identifierTable();
    67     if (needsLocking) {
    68         // It is wasteful to take the lock for non-shared contexts, but we don't have a good way
    69         // to determine what the context is.
    70         rep->deref();
    71     } else
    72         rep->deref();
     63    string->deref();
    7364}
    7465
    7566size_t JSStringGetLength(JSStringRef string)
    7667{
    77     UString::Rep* rep = toJS(string);
    78     return rep->size();
     68    return string->length();
    7969}
    8070
    8171const JSChar* JSStringGetCharactersPtr(JSStringRef string)
    8272{
    83     UString::Rep* rep = toJS(string);
    84     return reinterpret_cast<const JSChar*>(rep->data());
     73    return string->characters();
    8574}
    8675
    8776size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string)
    8877{
    89     UString::Rep* rep = toJS(string);
    90    
    9178    // Any UTF8 character > 3 bytes encodes as a UTF16 surrogate pair.
    92     return rep->size() * 3 + 1; // + 1 for terminating '\0'
     79    return string->length() * 3 + 1; // + 1 for terminating '\0'
    9380}
    9481
    9582size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize)
    9683{
    97     UString::Rep* rep = toJS(string);
    98     CString cString = UString(rep).UTF8String();
     84    if (!bufferSize)
     85        return 0;
    9986
    100     size_t length = std::min(bufferSize, cString.size() + 1); // + 1 for terminating '\0'
    101     memcpy(buffer, cString.c_str(), length);
    102     return length;
     87    char* p = buffer;
     88    const UChar* d = string->characters();
     89    ConversionResult result = convertUTF16ToUTF8(&d, d + string->length(), &p, p + bufferSize - 1, true);
     90    *p++ = '\0';
     91    if (result != conversionOK && result != targetExhausted)
     92        return 0;
     93
     94    return p - buffer;
    10395}
    10496
    10597bool JSStringIsEqual(JSStringRef a, JSStringRef b)
    10698{
    107     UString::Rep* aRep = toJS(a);
    108     UString::Rep* bRep = toJS(b);
    109    
    110     return UString(aRep) == UString(bRep);
     99    unsigned len = a->length();
     100    return len == b->length() && 0 == memcmp(a->characters(), b->characters(), len * sizeof(UChar));
    111101}
    112102
  • trunk/JavaScriptCore/API/JSStringRefCF.cpp

    r35227 r35775  
    3030#include "APICast.h"
    3131#include "JSStringRef.h"
     32#include "OpaqueJSString.h"
    3233#include <kjs/ustring.h>
    3334#include <kjs/JSValue.h>
    34 
    35 using namespace KJS;
     35#include <wtf/OwnArrayPtr.h>
    3636
    3737JSStringRef JSStringCreateWithCFString(CFStringRef string)
    3838{
    3939    CFIndex length = CFStringGetLength(string);
    40     UString::Rep* rep;
    41     if (!length)
    42         rep = UString("").rep()->ref();
    43     else {
    44         UniChar* buffer = static_cast<UniChar*>(fastMalloc(sizeof(UniChar) * length));
    45         CFStringGetCharacters(string, CFRangeMake(0, length), buffer);
     40    if (length) {
     41        OwnArrayPtr<UniChar> buffer(new UniChar[length]);
     42        CFStringGetCharacters(string, CFRangeMake(0, length), buffer.get());
    4643        COMPILE_ASSERT(sizeof(UniChar) == sizeof(UChar), unichar_and_uchar_must_be_same_size);
    47         rep = UString(reinterpret_cast<UChar*>(buffer), length, false).rep()->ref();
     44        return OpaqueJSString::create(buffer.get(), length).releaseRef();
     45    } else {
     46        return OpaqueJSString::create(0, 0).releaseRef();
    4847    }
    49     return toRef(rep);
    50 }
     48    }
    5149
    5250CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string)
    5351{
    54     UString::Rep* rep = toJS(string);
    55     return CFStringCreateWithCharacters(alloc, reinterpret_cast<const UniChar*>(rep->data()), rep->size());
     52    return CFStringCreateWithCharacters(alloc, reinterpret_cast<const UniChar*>(string->characters()), string->length());
    5653}
  • trunk/JavaScriptCore/API/JSValueRef.cpp

    r35478 r35775  
    189189    exec->globalData().heap->registerThread();
    190190
    191     UString::Rep* rep = toJS(string);
    192     return toRef(jsString(exec, UString(rep)));
     191    return toRef(jsString(exec, string->ustring()));
    193192}
    194193
     
    224223    JSValue* jsValue = toJS(value);
    225224   
    226     JSStringRef stringRef = toRef(jsValue->toString(exec).rep()->ref());
    227     if (exec->hadException()) {
    228         if (exception)
    229             *exception = toRef(exec->exception());
    230         exec->clearException();
    231         stringRef = 0;
    232     }
    233     return stringRef;
     225    RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue->toString(exec)));
     226    if (exec->hadException()) {
     227        if (exception)
     228            *exception = toRef(exec->exception());
     229        exec->clearException();
     230        stringRef.clear();
     231    }
     232    return stringRef.release().releaseRef();
    234233}
    235234
Note: See TracChangeset for help on using the changeset viewer.