Skip to content

Commit

Permalink
Try to avoid class init hacks by forcing accesses through Format.
Browse files Browse the repository at this point in the history
headius committed May 21, 2018

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
1 parent 9d6f877 commit 6b7d821
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions core/src/main/java/org/jruby/util/RubyDateFormatter.java
Original file line number Diff line number Diff line change
@@ -145,21 +145,32 @@ enum Format {
FORMAT_MICROSEC_EPOCH;

Format() {}

Format(char conversion) {
CONVERSION2TOKEN[conversion] = new Token(this);
addToConversions(conversion, new Token(this));
}

Format(char conversion, char alias) {
this(conversion);
CONVERSION2TOKEN[alias] = CONVERSION2TOKEN[conversion];
addToConversions(alias, conversionToToken(conversion));
}

// This is still an ugly side effect but avoids jruby/jruby#5179 or class init hacks by forcing all accesses
// to initialize the Format class via the Token class.
private static void addToConversions(char conversion, Token token) {
CONVERSION2TOKEN[conversion] = token;
}

private static Token conversionToToken(int conversion) {
return CONVERSION2TOKEN[conversion];
}
}
static final Format INSTANTIATE_ENUM = Format.FORMAT_WEEK_LONG;

public static void main(String[] args) {
// composed + special, keys of the switch below
StringBuilder buf = new StringBuilder("cDxFnQRrTXtvZ+z");
for (int i = 'A'; i <= 'z'; i++) {
if (CONVERSION2TOKEN[i] != null) {
if (Format.conversionToToken(i) != null) {
buf.append((char) i);
}
}
@@ -184,7 +195,7 @@ public static Token str(String str) {
}

public static Token format(char c) {
return CONVERSION2TOKEN[c];
return Format.conversionToToken(c);
}

public static Token zoneOffsetColons(int colons) {
@@ -227,10 +238,6 @@ public String toString() {
public RubyDateFormatter(ThreadContext context) {
super();
this.context = context;
// FIXME: Java does not seem to initialize the enum values until the first one is accessed but during
// construction of enum values we set the enum values into a static array. We look at that static array
// before we formally reference a Format. The following line will work around this by forcing enum loading...someone change this code :P
Format staticInitializerHack = Format.FORMAT_SPECIAL;
lexer = new StrftimeLexer((Reader) null);
}

0 comments on commit 6b7d821

Please sign in to comment.