[webkit-changes] cvs commit: JavaScriptCore/bindings/objc objc_class.mm objc_utility.h objc_utility.mm

Geoffrey ggaren at opensource.apple.com
Tue Dec 20 10:34:32 PST 2005


ggaren      05/12/20 10:34:32

  Modified:    .        ChangeLog
               .        ChangeLog
               bindings/objc objc_class.mm objc_utility.h objc_utility.mm
  Added:       fast/js  objc-big-method-name-expected.txt
                        objc-big-method-name.html
  Log:
  JavaScriptCore:
  
          Reviewed by Maciej.
  
          Fixed <rdar://problem/4370397> Missing return statement in
          JSMethodNameToObjcMethodName.
  
          JSMethodNameToObjcMethodName had a check for a name being too long, but
          the check was missing a return statement.
  
          A lot of this code was confusing and some of it was wrong, so I fixed
          it up, added some asserts to catch this type of bug in the future,
          changed some comments, and renamed some variables.
  
          The two advantages of the new algorithm are (1) It makes writing past
          the end of the buffer virtually impossible because the test on the main
          loop is "while (not past end of buffer)" and (2) It's twice as fast
          because it doesn't call strlen. (There's no need to call strlen when
          we're walking the string ourselves.)
  
          methodsNamed also supports arbitrary-length method names now. Just in
          case the AppKit folks start getting REALLY verbose...
  
          * bindings/objc/objc_class.mm:
          (KJS::Bindings::ObjcClass::methodsNamed):
          * bindings/objc/objc_utility.h:
          * bindings/objc/objc_utility.mm:
          (KJS::Bindings::JSMethodNameToObjcMethodName):
  
  LayoutTests:
  
          Layout test for <rdar://problem/4370397> Missing return statement in
          JSMethodNameToObjcMethodName.
  
          * fast/js/objc-big-method-name-expected.txt: Added.
          * fast/js/objc-big-method-name.html: Added.
  
  Revision  Changes    Path
  1.173     +8 -0      LayoutTests/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/LayoutTests/ChangeLog,v
  retrieving revision 1.172
  retrieving revision 1.173
  diff -u -r1.172 -r1.173
  --- ChangeLog	19 Dec 2005 22:16:24 -0000	1.172
  +++ ChangeLog	20 Dec 2005 18:34:28 -0000	1.173
  @@ -1,3 +1,11 @@
  +2005-12-19  Geoffrey Garen  <ggaren at apple.com>
  +
  +        Layout test for <rdar://problem/4370397> Missing return statement in
  +        JSMethodNameToObjcMethodName.
  +
  +        * fast/js/objc-big-method-name-expected.txt: Added.
  +        * fast/js/objc-big-method-name.html: Added.
  +
   2005-12-19  Mitz Pettel  <opendarwin.org at mitzpettel.com>
   
           Reviewed by Darin, committed by Adele.
  
  
  
  1.1                  LayoutTests/fast/js/objc-big-method-name-expected.txt
  
  Index: objc-big-method-name-expected.txt
  ===================================================================
  This test checks for a regression against rdar://problem/4370397 Missing return statement in JSMethodNameToObjcMethodName.
  
  If the test passes, you will see a "success" message below.
  
  success: no crash.
  
  
  
  1.1                  LayoutTests/fast/js/objc-big-method-name.html
  
  Index: objc-big-method-name.html
  ===================================================================
  <html>
  <head>
  <script>
  function print(message) {
      var paragraph = document.createElement("p");
      paragraph.appendChild(document.createTextNode(message));
      document.getElementById("console").appendChild(paragraph);
  }
  
  function test() {
      if (window.layoutTestController) {
          layoutTestController.dumpAsText();
      }
  
      var method = "console.";
      for (var i = 0; i < 6000; i++)
          method += "a";
      method += "()";
      try {
          eval(method);
      }
      catch (e) {}
      
      print("success: no crash.");
  }
  </script>
  </head>
  <body onload="test();">
  <p>This test checks for a regression against <i>rdar://problem/4370397 Missing return statement in JSMethodNameToObjcMethodName</i>.</p>
  <p>If the test passes, you will see a "success" message below.</p>
  <hr>
  <div id='console'/>
  </body>
  </html>
  
  
  
  1.914     +29 -0     JavaScriptCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/ChangeLog,v
  retrieving revision 1.913
  retrieving revision 1.914
  diff -u -r1.913 -r1.914
  --- ChangeLog	19 Dec 2005 20:48:21 -0000	1.913
  +++ ChangeLog	20 Dec 2005 18:34:29 -0000	1.914
  @@ -1,3 +1,32 @@
  +2005-12-19  Geoffrey Garen  <ggaren at apple.com>
  +  
  +        Reviewed by Maciej.
  +
  +        Fixed <rdar://problem/4370397> Missing return statement in
  +        JSMethodNameToObjcMethodName.
  +
  +        JSMethodNameToObjcMethodName had a check for a name being too long, but
  +        the check was missing a return statement.
  +
  +        A lot of this code was confusing and some of it was wrong, so I fixed
  +        it up, added some asserts to catch this type of bug in the future, 
  +        changed some comments, and renamed some variables.
  +
  +        The two advantages of the new algorithm are (1) It makes writing past
  +        the end of the buffer virtually impossible because the test on the main
  +        loop is "while (not past end of buffer)" and (2) It's twice as fast
  +        because it doesn't call strlen. (There's no need to call strlen when
  +        we're walking the string ourselves.) 
  +        
  +        methodsNamed also supports arbitrary-length method names now. Just in 
  +        case the AppKit folks start getting REALLY verbose...
  +
  +        * bindings/objc/objc_class.mm:
  +        (KJS::Bindings::ObjcClass::methodsNamed):
  +        * bindings/objc/objc_utility.h:
  +        * bindings/objc/objc_utility.mm:
  +        (KJS::Bindings::JSMethodNameToObjcMethodName):
  +
   2005-12-19  Darin Adler  <darin at apple.com>
   
           Originally done by both George Staikos and Alexey Proskuryakov.
  
  
  
  1.14      +14 -10    JavaScriptCore/bindings/objc/objc_class.mm
  
  Index: objc_class.mm
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/bindings/objc/objc_class.mm,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- objc_class.mm	11 Dec 2005 02:05:38 -0000	1.13
  +++ objc_class.mm	20 Dec 2005 18:34:31 -0000	1.14
  @@ -87,19 +87,21 @@
       return _isa->name;
   }
   
  -MethodList ObjcClass::methodsNamed(const char *_name, Instance *instance) const
  +MethodList ObjcClass::methodsNamed(const char *JSName, Instance *instance) const
   {
       MethodList methodList;
  -    char name[4096];
  -    
  -    JSMethodNameToObjCMethodName (_name, name, 4096);
  -    
  -    if (*name == 0) {
  -        return methodList;
  +    char fixedSizeBuffer[1024];
  +    char *buffer = fixedSizeBuffer;
  +
  +    if (!convertJSMethodNameToObjc(JSName, buffer, sizeof(fixedSizeBuffer))) {
  +        int length = strlen(JSName) + 1;
  +        buffer = new char[length];
  +        if (!buffer || !convertJSMethodNameToObjc(JSName, buffer, length))
  +            return methodList;
       }
           
  -    CFStringRef methodName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
  -    Method *method = (Method *)CFDictionaryGetValue (_methods, methodName);
  +    CFStringRef methodName = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingASCII);
  +    Method *method = (Method *)CFDictionaryGetValue(_methods, methodName);
       if (method) {
           CFRelease (methodName);
           methodList.addMethod(method);
  @@ -131,7 +133,7 @@
                   }
   
                   if ((mappedName && [mappedName isEqual:(NSString *)methodName]) ||
  -                    strcmp ((const char *)objcMethod->method_name, name) == 0) {
  +                    strcmp ((const char *)objcMethod->method_name, buffer) == 0) {
                       Method *aMethod = new ObjcMethod (thisClass, (const char *)objcMethod->method_name);
                       CFDictionaryAddValue ((CFMutableDictionaryRef)_methods, methodName, aMethod);
                       methodList.addMethod (aMethod);
  @@ -143,6 +145,8 @@
       }
       
       CFRelease (methodName);
  +    if (buffer != fixedSizeBuffer)
  +        delete [] buffer;
   
       return methodList;
   }
  
  
  
  1.8       +1 -1      JavaScriptCore/bindings/objc/objc_utility.h
  
  Index: objc_utility.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/bindings/objc/objc_utility.h,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- objc_utility.h	11 Dec 2005 02:05:39 -0000	1.7
  +++ objc_utility.h	20 Dec 2005 18:34:31 -0000	1.8
  @@ -70,7 +70,7 @@
   JSValue *convertObjcValueToValue(ExecState *exec, void *buffer, ObjcValueType type);
   ObjcValueType objcValueTypeForType(const char *type);
   
  -void JSMethodNameToObjCMethodName(const char *name, char *name, unsigned int length);
  +bool convertJSMethodNameToObjc(const char *JSName, char *buffer, size_t bufferSize);
   
   void *createObjcInstanceForValue(JSValue *value, const RootObject *origin, const RootObject *current);
   
  
  
  
  1.24      +40 -28    JavaScriptCore/bindings/objc/objc_utility.mm
  
  Index: objc_utility.mm
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/bindings/objc/objc_utility.mm,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- objc_utility.mm	11 Dec 2005 02:05:39 -0000	1.23
  +++ objc_utility.mm	20 Dec 2005 18:34:31 -0000	1.24
  @@ -42,41 +42,53 @@
   namespace Bindings {
   
   /*
  -    The default name concatenates the components of the
  -    ObjectiveC selector name and replaces ':' with '_'.  '_' characters
  -    are escaped with an additional '$', i.e. '_' becomes "$_".  '$' are
  -    also escaped, i.e.
  -        ObjectiveC name         Default script name
  -        moveTo::                move__
  +    By default, a JavaScript method name is produced by concatenating the 
  +    components of an ObjectiveC method name, replacing ':' with '_', and 
  +    escaping '_' and '$' with a leading '$', such that '_' becomes "$_" and 
  +    '$' becomes "$$". For example:
  +
  +    ObjectiveC name         Default JavaScript name
  +        moveTo::                moveTo__
           moveTo_                 moveTo$_
           moveTo$_                moveTo$$$_
  -    @result Returns the name to be used to represent the specificed selector in the
  +
  +    This function performs the inverse of that operation.
  + 
  +    @result Fills 'buffer' with the ObjectiveC method name that corresponds to 'JSName'. 
  +            Returns true for success, false for failure. (Failure occurs when 'buffer' 
  +            is not big enough to hold the result.)
   */
  -void JSMethodNameToObjCMethodName(const char *name, char *buffer, unsigned int len)
  +bool convertJSMethodNameToObjc(const char *JSName, char *buffer, size_t bufferSize)
   {
  -    const char *np = name;
  -    char *bp;
  -
  -    if (strlen(name)*2+1 > len){
  -        *buffer = 0;
  -    }
  -
  -    bp = buffer;
  -    while (*np) {
  -        if (*np == '$') {
  -            np++;
  -            *bp++ = *np++;
  -            continue;
  -        }
  +    assert(JSName && buffer);
  +    
  +    const char *sp = JSName; // source pointer
  +    char *dp = buffer; // destination pointer
  +        
  +    char *end = buffer + bufferSize;
  +    while (dp < end) {
  +        if (*sp == '$') {
  +            ++sp;
  +            *dp = *sp;
  +        } else if (*sp == '_')
  +            *dp = ':';
  +	else
  +            *dp = *sp;
  +
  +        // If a future coder puts funny ++ operators above, we might write off the end 
  +        // of the buffer in the middle of this loop. Let's make sure to check for that.
  +        assert(dp < end);
           
  -        if (*np == '_') {
  -            np++;
  -            *bp++ = ':';
  +        if (*sp == 0) { // We finished converting JSName
  +            assert(strlen(JSName) < bufferSize);
  +            return true;
           }
  -        else
  -            *bp++ = *np++;
  +        
  +        ++sp; 
  +        ++dp;
       }
  -    *bp++ = 0;
  +
  +    return false; // We ran out of buffer before converting JSName
   }
   
   /*
  
  
  



More information about the webkit-changes mailing list