Ignore:
Timestamp:
Sep 7, 2017, 1:14:30 AM (8 years ago)
Author:
Yusuke Suzuki
Message:

[JSC] Remove "malloc" and "free" from JSC/API
https://bugs.webkit.org/show_bug.cgi?id=176331

Reviewed by Keith Miller.

Remove "malloc" and "free" manual calls in JSC/API.

  • API/JSValue.mm:

(createStructHandlerMap):

  • API/JSWrapperMap.mm:

(parsePropertyAttributes):
(makeSetterName):
(copyPrototypeProperties):
Use RetainPtr<NSString> to keep NSString. We avoid repeated "char*" to "NSString" conversion.

  • API/ObjcRuntimeExtras.h:

(adoptSystem):
Add adoptSystem to automate calling system free().

(protocolImplementsProtocol):
(forEachProtocolImplementingProtocol):
(forEachMethodInClass):
(forEachMethodInProtocol):
(forEachPropertyInProtocol):
(StringRange::StringRange):
(StringRange::operator const char* const):
(StringRange::get const):
Use CString for backend.

(StructBuffer::StructBuffer):
(StructBuffer::~StructBuffer):
(StringRange::~StringRange): Deleted.
Use fastAlignedMalloc/astAlignedFree to get aligned memory.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSWrapperMap.mm

    r221583 r221723  
    9292        // Copy the character, converting to upper case if necessary.
    9393        // If the character we copy is '\0', then we're done!
    94         if (!(*(output++) = toupper(c)))
     94        if (!(*(output++) = toASCIIUpper(c)))
    9595            goto done;
    9696        // Loop over characters other than ':'.
     
    261261}
    262262
    263 static bool parsePropertyAttributes(objc_property_t property, char*& getterName, char*& setterName)
     263struct Property {
     264    const char* name;
     265    RetainPtr<NSString> getterName;
     266    RetainPtr<NSString> setterName;
     267};
     268
     269static bool parsePropertyAttributes(objc_property_t objcProperty, Property& property)
    264270{
    265271    bool readonly = false;
    266272    unsigned attributeCount;
    267     objc_property_attribute_t* attributes = property_copyAttributeList(property, &attributeCount);
     273    auto attributes = adoptSystem<objc_property_attribute_t[]>(property_copyAttributeList(objcProperty, &attributeCount));
    268274    if (attributeCount) {
    269275        for (unsigned i = 0; i < attributeCount; ++i) {
    270276            switch (*(attributes[i].name)) {
    271277            case 'G':
    272                 getterName = strdup(attributes[i].value);
     278                property.getterName = @(attributes[i].value);
    273279                break;
    274280            case 'S':
    275                 setterName = strdup(attributes[i].value);
     281                property.setterName = @(attributes[i].value);
    276282                break;
    277283            case 'R':
     
    282288            }
    283289        }
    284         free(attributes);
    285290    }
    286291    return readonly;
    287292}
    288293
    289 static char* makeSetterName(const char* name)
     294static RetainPtr<NSString> makeSetterName(const char* name)
    290295{
    291296    size_t nameLength = strlen(name);
    292     char* setterName = (char*)malloc(nameLength + 5); // "set" Name ":\0"
    293     setterName[0] = 's';
    294     setterName[1] = 'e';
    295     setterName[2] = 't';
    296     setterName[3] = toupper(*name);
    297     memcpy(setterName + 4, name + 1, nameLength - 1);
    298     setterName[nameLength + 3] = ':';
    299     setterName[nameLength + 4] = '\0';
    300     return setterName;
     297    // "set" Name ":\0"  => nameLength + 5.
     298    Vector<char, 128> buffer(nameLength + 5);
     299    buffer[0] = 's';
     300    buffer[1] = 'e';
     301    buffer[2] = 't';
     302    buffer[3] = toASCIIUpper(*name);
     303    memcpy(buffer.data() + 4, name + 1, nameLength - 1);
     304    buffer[nameLength + 3] = ':';
     305    buffer[nameLength + 4] = '\0';
     306    return @(buffer.data());
    301307}
    302308
     
    304310{
    305311    // First gather propreties into this list, then handle the methods (capturing the accessor methods).
    306     struct Property {
    307         const char* name;
    308         char* getterName;
    309         char* setterName;
    310     };
    311312    __block Vector<Property> propertyList;
    312313
     
    317318    JSValue *undefined = [JSValue valueWithUndefinedInContext:context];
    318319
    319     forEachPropertyInProtocol(protocol, ^(objc_property_t property){
    320         char* getterName = 0;
    321         char* setterName = 0;
    322         bool readonly = parsePropertyAttributes(property, getterName, setterName);
    323         const char* name = property_getName(property);
    324 
    325         // Add the names of the getter & setter methods to
    326         if (!getterName)
    327             getterName = strdup(name);
    328         accessorMethods[@(getterName)] = undefined;
     320    forEachPropertyInProtocol(protocol, ^(objc_property_t objcProperty) {
     321        const char* name = property_getName(objcProperty);
     322        Property property { name, nullptr, nullptr };
     323        bool readonly = parsePropertyAttributes(objcProperty, property);
     324
     325        // Add the names of the getter & setter methods to
     326        if (!property.getterName)
     327            property.getterName = @(name);
     328        accessorMethods[property.getterName.get()] = undefined;
    329329        if (!readonly) {
    330             if (!setterName)
    331                 setterName = makeSetterName(name);
    332             accessorMethods[@(setterName)] = undefined;
     330            if (!property.setterName)
     331                property.setterName = makeSetterName(name);
     332            accessorMethods[property.setterName.get()] = undefined;
    333333        }
    334334
    335335        // Add the properties to a list.
    336         propertyList.append((Property){ name, getterName, setterName });
     336        propertyList.append(WTFMove(property));
    337337    });
    338338
     
    341341
    342342    // Iterate the propertyList & generate accessor properties.
    343     for (size_t i = 0; i < propertyList.size(); ++i) {
    344         Property& property = propertyList[i];
    345 
    346         JSValue *getter = accessorMethods[@(property.getterName)];
    347         free(property.getterName);
     343    for (auto& property : propertyList) {
     344        JSValue* getter = accessorMethods[property.getterName.get()];
    348345        ASSERT(![getter isUndefined]);
    349346
    350         JSValue *setter = undefined;
     347        JSValue* setter = undefined;
    351348        if (property.setterName) {
    352             setter = accessorMethods[@(property.setterName)];
    353             free(property.setterName);
     349            setter = accessorMethods[property.setterName.get()];
    354350            ASSERT(![setter isUndefined]);
    355351        }
Note: See TracChangeset for help on using the changeset viewer.