From 8ee7e8124afcc8bd62a44bdf3896dbe2da8c29bf Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 15 Jan 2015 17:08:40 -0700 Subject: [PATCH] fix broken interpreter build due to out-of-order class initialization When we initialize the vtables for bootstrap Java classes such as java.lang.NullPointerException (i.e. classes which the VM has built-in knowledge of), we assign the superclass's vtable to any class which has no declared virtual methods of its own. However, that vtable will be null if we haven't initialized the superclass yet. Therefore, we must order this process such that no class is initialized until after all its superclasses. --- src/tools/type-generator/main.cpp | 17 +++++++++++++++-- test/NullPointer.java | 6 ++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/tools/type-generator/main.cpp b/src/tools/type-generator/main.cpp index 32dcf6f7f0..c981d13194 100644 --- a/src/tools/type-generator/main.cpp +++ b/src/tools/type-generator/main.cpp @@ -1408,8 +1408,20 @@ void writeInitializations(Output* out, Module& module) } } -void writeJavaInitialization(Output* out, Class* cl) +void writeJavaInitialization(Output* out, + Class* cl, + std::set& alreadyInited) { + if (alreadyInited.find(cl) != alreadyInited.end()) { + return; + } + + alreadyInited.insert(cl); + + if (cl->super) { + writeJavaInitialization(out, cl->super, alreadyInited); + } + out->write("bootJavaClass(t, Gc::"); out->write(capitalize(cl->name)); out->write("Type, "); @@ -1436,10 +1448,11 @@ void writeJavaInitialization(Output* out, Class* cl) void writeJavaInitializations(Output* out, Module& module) { + std::set alreadyInited; for (const auto p : module.classes) { Class* cl = p.second; if (cl->javaName.size()) { - writeJavaInitialization(out, cl); + writeJavaInitialization(out, cl, alreadyInited); } } } diff --git a/test/NullPointer.java b/test/NullPointer.java index 6c6e5c7b50..8d3abdc6fa 100644 --- a/test/NullPointer.java +++ b/test/NullPointer.java @@ -16,6 +16,12 @@ public class NullPointer { } public static void main(String[] args) { + try { + ((Object) null).getClass(); + } catch (Exception e) { + e.printStackTrace(); + } + try { throw_(null); throw new RuntimeException();