Changeset 4206 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Apr 29, 2003, 11:26:29 AM (22 years ago)
Author:
darin
Message:

Reviewed by John.

  • fixed 2959353 -- eliminate globally initialized objects from JavaScriptCore
  • JavaScriptCore.pbproj/project.pbxproj: Added fpconst.cpp.
  • kjs/fpconst.cpp: Added. Defines KJS::NaN and KJS::Inf in a way that does not require a framework init routine.
  • kjs/identifier.h: Use a new KJS_IDENTIFIER_EACH_GLOBAL macro so we can do things to the entire set of identifiers easily. Also added an init function that sets up these globals in a way that does not require a framework init routine.
  • kjs/identifier.cpp: (Identifier::init): Initialize the property ane globals in a way that does not require a framework init routine.
  • kjs/internal.cpp: (InterpreterImp::initGlobalObject): Call Identifier::init.
  • kjs/ustring.h: Remove UChar::null and UString::null, and add UString::null(). We can't have a global object of a class that has a constructor if we want to avoid framework init routines, and luckily very little code relies on these.
  • kjs/ustring.cpp: (UCharReference::ref): Use our own global specific to this function rather than returning UChar::null when past the end of the string. This is dangerous because if the caller modifies it, that affects what all subsequent callers will see. (UString::Rep::create): Added assertions. (UString::UString): Got rid of code here that used to set up UString::null. (UString::null): Added. Returns a global null string, and can be used in some of the places where we used to use the UString::null global. (UString::operator[]): Fixed case where this used to return UChar::null to return '\0' instead.
  • kjs/regexp.cpp: (RegExp::match): Change uses of UString::null to UString::null().
Location:
trunk/JavaScriptCore/kjs
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/identifier.cpp

    r3745 r4206  
    2020 */
    2121
     22// For JavaScriptCore we need to avoid having static constructors.
     23// Our strategy is to declare the global objects with a different type (initialized to 0)
     24// and then use placement new to initialize the global objects later. This is not completely
     25// portable, and it would be good to figure out a 100% clean way that still avoids code that
     26// runs at init time.
     27
     28#if APPLE_CHANGES
     29#define AVOID_STATIC_CONSTRUCTORS 1
     30#endif
     31
     32#if AVOID_STATIC_CONSTRUCTORS
     33#define KJS_IDENTIFIER_HIDE_GLOBALS 1
     34#endif
     35
    2236#include "identifier.h"
    2337
     
    4357
    4458#endif
    45 
    46 extern const Identifier argumentsPropertyName("arguments");
    47 extern const Identifier calleePropertyName("callee");
    48 extern const Identifier constructorPropertyName("constructor");
    49 extern const Identifier lengthPropertyName("length");
    50 extern const Identifier messagePropertyName("message");
    51 extern const Identifier namePropertyName("name");
    52 extern const Identifier prototypePropertyName("prototype");
    53 extern const Identifier specialPrototypePropertyName("__proto__");
    54 extern const Identifier toLocaleStringPropertyName("toLocaleString");
    55 extern const Identifier toStringPropertyName("toString");
    56 extern const Identifier valueOfPropertyName("valueOf");
    5759
    5860const int _minTableSize = 64;
     
    301303}
    302304
     305// Global constants for property name strings.
     306
     307#if !AVOID_STATIC_CONSTRUCTORS
     308    // Define an Identifier in the normal way.
     309    #define DEFINE_GLOBAL(name, string) extern const Identifier name ## PropertyName(string);
     310#else
     311    // Define an Identifier-sized array of pointers to avoid static initialization.
     312    // Use an array of pointers instead of an array of char in case there is some alignment issue.
     313    #define DEFINE_GLOBAL(name, string) \
     314        void * name ## PropertyName[(sizeof(Identifier) + sizeof(void *) - 1) / sizeof(void *)];
     315#endif
     316
     317#define CALL_DEFINE_GLOBAL(name) DEFINE_GLOBAL(name, #name)
     318KJS_IDENTIFIER_EACH_GLOBAL(CALL_DEFINE_GLOBAL)
     319DEFINE_GLOBAL(specialPrototype, "__proto__")
     320
     321void Identifier::init()
     322{
     323#if AVOID_STATIC_CONSTRUCTORS
     324    static bool initialized;
     325    if (!initialized) {
     326        // Use placement new to initialize the globals.
     327        #define PLACEMENT_NEW_GLOBAL(name, string) new (&name ## PropertyName) Identifier(string);
     328        #define CALL_PLACEMENT_NEW_GLOBAL(name) PLACEMENT_NEW_GLOBAL(name, #name)
     329        KJS_IDENTIFIER_EACH_GLOBAL(CALL_PLACEMENT_NEW_GLOBAL)
     330        PLACEMENT_NEW_GLOBAL(specialPrototype, "__proto__")
     331        initialized = true;
     332    }
     333#endif
     334}
     335
    303336} // namespace KJS
  • trunk/JavaScriptCore/kjs/identifier.h

    r3745 r4206  
    3030        friend class PropertyMap;
    3131    public:
     32        static void init();
     33
    3234        Identifier() { }
    3335        Identifier(const char *s) : _ustring(add(s)) { }
     
    99101        { return Identifier::equal(a, b); }
    100102
    101     extern const Identifier argumentsPropertyName;
    102     extern const Identifier calleePropertyName;
    103     extern const Identifier constructorPropertyName;
    104     extern const Identifier lengthPropertyName;
    105     extern const Identifier messagePropertyName;
    106     extern const Identifier namePropertyName;
    107     extern const Identifier prototypePropertyName;
    108     extern const Identifier specialPrototypePropertyName;
    109     extern const Identifier toLocaleStringPropertyName;
    110     extern const Identifier toStringPropertyName;
    111     extern const Identifier valueOfPropertyName;
     103    // List of property names, passed to a macro so we can do set them up various
     104    // ways without repeating the list.
     105    #define KJS_IDENTIFIER_EACH_GLOBAL(macro) \
     106        macro(arguments) \
     107        macro(callee) \
     108        macro(constructor) \
     109        macro(length) \
     110        macro(message) \
     111        macro(name) \
     112        macro(prototype) \
     113        macro(toLocaleString) \
     114        macro(toString) \
     115        macro(valueOf)
     116
     117    // Define external global variables for all property names above (and one more).
     118#if !KJS_IDENTIFIER_HIDE_GLOBALS
     119    #define KJS_IDENTIFIER_DECLARE_GLOBAL(name) extern const Identifier name ## PropertyName;
     120    KJS_IDENTIFIER_EACH_GLOBAL(KJS_IDENTIFIER_DECLARE_GLOBAL)
     121    KJS_IDENTIFIER_DECLARE_GLOBAL(specialPrototype)
     122    #undef KJS_IDENTIFIER_DECLARE_GLOBAL
     123#endif
    112124
    113125}
  • trunk/JavaScriptCore/kjs/internal.cpp

    r4087 r4206  
    5555using namespace KJS;
    5656
     57#if !APPLE_CHANGES
     58
    5759namespace KJS {
    5860#ifdef WORDS_BIGENDIAN
     
    7072  const double Inf = *(const double*) Inf_Bytes;
    7173};
     74
     75#endif // APPLE_CHANGES
    7276
    7377static pthread_once_t interpreterLockOnce = PTHREAD_ONCE_INIT;
     
    548552void InterpreterImp::initGlobalObject()
    549553{
     554  Identifier::init();
     555 
    550556  // Contructor prototype objects (Object.prototype, Array.prototype etc)
    551557
  • trunk/JavaScriptCore/kjs/regexp.cpp

    r1791 r4206  
    101101  *pos = -1;
    102102  if (i > s.size() || s.isNull())
    103     return UString::null;
     103    return UString::null();
    104104
    105105#ifdef HAVE_PCREPOSIX
     
    110110  if (!pcregex || pcre_exec(pcregex, NULL, buffer.c_str(), buffer.size(), i,
    111111                  0, ovector ? *ovector : 0L, ovecsize) == PCRE_ERROR_NOMATCH)
    112     return UString::null;
     112    return UString::null();
    113113
    114114  if (!ovector)
    115     return UString::null; // don't rely on the return value if you pass ovector==0
     115    return UString::null(); // don't rely on the return value if you pass ovector==0
    116116#else
    117117  const uint maxMatch = 10;
     
    121121  if (regexec(&preg, str + i, maxMatch, rmatch, 0)) {
    122122    free(str);
    123     return UString::null;
     123    return UString::null();
    124124  }
    125125  free(str);
  • trunk/JavaScriptCore/kjs/ustring.cpp

    r3736 r4206  
    117117}
    118118
    119 UChar UChar::null((char)0);
    120119UString::Rep UString::Rep::null = { 0, 0, 0, 1, 1 };
    121120UString::Rep UString::Rep::empty = { 0, 0, 0, 1, 1 };
    122 UString UString::null;
    123121const int normalStatBufferSize = 4096;
    124122static char *statBuffer = 0;
     
    155153  if (offset < str->rep->len)
    156154    return *(str->rep->dat + offset);
    157   else
    158     return UChar::null;
     155  else {
     156    static UChar callerBetterNotModifyThis('\0');
     157    return callerBetterNotModifyThis;
     158  }
    159159}
    160160
     
    253253UString::UString()
    254254{
    255   null.rep = &Rep::null;
    256255  attach(&Rep::null);
    257256}
     
    320319  memcpy(d + aSize, b.data(), bSize * sizeof(UChar));
    321320  rep = Rep::create(d, length);
     321}
     322
     323const UString &UString::null()
     324{
     325    static UString n;
     326    return n;
    322327}
    323328
     
    551556{
    552557  if (pos >= size())
    553     return UChar::null;
    554 
    555   return ((UChar *)data())[pos];
     558    return '\0';
     559  return data()[pos];
    556560}
    557561
  • trunk/JavaScriptCore/kjs/ustring.h

    r4188 r4206  
    9898     */
    9999    UChar toUpper() const;
    100     /**
    101      * A static instance of UChar(0).
    102      */
    103     static UChar null;
    104100
    105101    unsigned short uc;
     
    410406     * Static instance of a null string.
    411407     */
    412     static UString null;
     408    static const UString &null();
    413409#ifdef KJS_DEBUG_MEM
    414410    /**
Note: See TracChangeset for help on using the changeset viewer.