Ignore:
Timestamp:
Jun 14, 2017, 10:57:27 PM (8 years ago)
Author:
[email protected]
Message:

[Cocoa] Objective-C class whose name begins with an underscore can’t be exported to JavaScript
https://bugs.webkit.org/show_bug.cgi?id=168578

Reviewed by Geoff Garen.

  • API/JSWrapperMap.mm:

(allocateConstructorForCustomClass): Updated for change to forEachProtocolImplementingProtocol.
(-[JSObjCClassInfo allocateConstructorAndPrototype]): Ditto.
(-[JSWrapperMap classInfoForClass:]): If the class name begins with an underscore, check if

it defines conformance to a JSExport-derived protocol and if so, avoid using the
superclass as a substitute as we’d normally do.

  • API/ObjcRuntimeExtras.h:

(forEachProtocolImplementingProtocol): Added a "stop" argument to the block to let callers

bail out.

  • API/tests/JSExportTests.mm:

(+[JSExportTests classNamePrefixedWithUnderscoreTest]): New test for this.
(runJSExportTests): Run new test.

File:
1 edited

Legend:

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

    r217240 r218316  
    11/*
    2  * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015, 2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    413413    Protocol *exportProtocol = getJSExportProtocol();
    414414    for (Class currentClass = cls; currentClass; currentClass = class_getSuperclass(currentClass)) {
    415         forEachProtocolImplementingProtocol(currentClass, exportProtocol, ^(Protocol *protocol) {
     415        forEachProtocolImplementingProtocol(currentClass, exportProtocol, ^(Protocol *protocol, bool&) {
    416416            forEachMethodInProtocol(protocol, YES, YES, ^(SEL selector, const char*) {
    417417                const char* name = sel_getName(selector);
     
    491491
    492492        Protocol *exportProtocol = getJSExportProtocol();
    493         forEachProtocolImplementingProtocol(m_class, exportProtocol, ^(Protocol *protocol){
     493        forEachProtocolImplementingProtocol(m_class, exportProtocol, ^(Protocol *protocol, bool&){
    494494            copyPrototypeProperties(context, m_class, protocol, prototype);
    495495            copyMethodsToObject(context, m_class, protocol, NO, constructor);
     
    588588
    589589    // Skip internal classes beginning with '_' - just copy link to the parent class's info.
    590     if ('_' == *class_getName(cls))
    591         return m_classMap[cls] = [self classInfoForClass:class_getSuperclass(cls)];
     590    if ('_' == *class_getName(cls)) {
     591        bool conformsToExportProtocol = false;
     592        forEachProtocolImplementingProtocol(cls, getJSExportProtocol(), [&conformsToExportProtocol](Protocol *, bool& stop) {
     593            conformsToExportProtocol = true;
     594            stop = true;
     595        });
     596
     597        if (!conformsToExportProtocol)
     598            return m_classMap[cls] = [self classInfoForClass:class_getSuperclass(cls)];
     599    }
    592600
    593601    return m_classMap[cls] = [[[JSObjCClassInfo alloc] initForClass:cls] autorelease];
Note: See TracChangeset for help on using the changeset viewer.