217217import static org .jruby .api .Access .errnoModule ;
218218import static org .jruby .api .Access .loadService ;
219219import static org .jruby .api .Convert .asFixnum ;
220+ import static org .jruby .api .Convert .asSymbol ;
220221import static org .jruby .api .Create .newEmptyString ;
221222import static org .jruby .api .Create .newFrozenString ;
222223import static org .jruby .api .Error .*;
@@ -335,36 +336,35 @@ private Ruby(RubyInstanceConfig config) {
335336 classClass .setMetaClass (classClass );
336337 refinementClass .setMetaClass (classClass );
337338
338- RubyClass metaClass ;
339- metaClass = basicObjectClass .makeMetaClass (classClass ); // runtime needed for 3 things:
340- metaClass = objectClass .makeMetaClass (metaClass ); // 1. ObjectSpace
341- metaClass = moduleClass .makeMetaClass (metaClass ); // 2. Access 'Class' for makeMetaClass
342- classClass .makeMetaClass (metaClass ); // 3. booting check to ignore logging singletons
343- refinementClass .makeMetaClass (metaClass );
339+ var metaClass = basicObjectClass .makeMetaClassBootstrap (classClass , classClass );
340+ metaClass = objectClass .makeMetaClassBootstrap (metaClass , classClass );
341+ metaClass = moduleClass .makeMetaClassBootstrap (metaClass , classClass );
342+ classClass .makeMetaClassBootstrap (metaClass , classClass );
343+ refinementClass .makeMetaClassBootstrap (metaClass , classClass );
344344
345- RubyObject .createObjectClass (objectClass );
346- RubyModule .createModuleClass (moduleClass );
347- RubyClass .createClassClass (this , classClass );
345+ RubyObject .finishObjectClass (objectClass );
346+ RubyModule .finishModuleClass (moduleClass );
347+ RubyClass .finishClassClass (this , classClass );
348348
349349 // set constants now that they're initialized
350- basicObjectClass .setConstant ("BasicObject" , basicObjectClass ); // FIXME: We know these sets will work so make something primal
351- objectClass .setConstant ("BasicObject" , basicObjectClass ); // just for these (to remove all checks which would require
352- objectClass .setConstant ("Object" , objectClass ); // runtime.
353- objectClass .setConstant ("Class" , classClass );
354- objectClass .setConstant ("Module" , moduleClass );
355- objectClass .setConstant ("Refinement" , refinementClass );
350+ basicObjectClass .defineConstantBootstrap ("BasicObject" , basicObjectClass );
351+ objectClass .defineConstantBootstrap ("BasicObject" , basicObjectClass );
352+ objectClass .defineConstantBootstrap ("Object" , objectClass );
353+ objectClass .defineConstantBootstrap ("Class" , classClass );
354+ objectClass .defineConstantBootstrap ("Module" , moduleClass );
355+ objectClass .defineConstantBootstrap ("Refinement" , refinementClass );
356356
357357 // specializer for RubyObject subclasses
358358 objectSpecializer = new RubyObjectSpecializer (this );
359359
360- kernelModule = defineModuleUnder ("Kernel" , objectClass ); // Initialize Kernel and include into Object
360+ kernelModule = defineModuleBootstrap ("Kernel" ); // Initialize Kernel and include into Object
361361 topSelf = new RubyObject (this , objectClass ); // Object is ready, create top self
362362
363363 // nil, true, and false all are set in TC so they need to be created above (both class and instances).
364- // their methods are added afterwards since no dispatch happens until after first TC is defined.
365- nilClass = defineClass ( "NilClass" , objectClass , NOT_ALLOCATABLE_ALLOCATOR );
366- falseClass = defineClass ( "FalseClass" , objectClass , NOT_ALLOCATABLE_ALLOCATOR );
367- trueClass = defineClass ( "TrueClass" , objectClass , NOT_ALLOCATABLE_ALLOCATOR );
364+ // their methods are added afterward since no dispatch happens until after first TC is defined.
365+ nilClass = RubyClass . newClassBootstrap ( this , objectClass , "NilClass" );
366+ falseClass = RubyClass . newClassBootstrap ( this , objectClass , "FalseClass" );
367+ trueClass = RubyClass . newClassBootstrap ( this , objectClass , "TrueClass" );
368368
369369 nilObject = new RubyNil (this , nilClass );
370370 nilPrefilledArray = new IRubyObject [NIL_PREFILLED_ARRAY_SIZE ];
@@ -1391,24 +1391,6 @@ public RubyClass fastGetClass(String internedName) {
13911391 return getClass (internedName );
13921392 }
13931393
1394- /**
1395- * Define a new class under the Object namespace. Roughly equivalent to
1396- * rb_define_class in MRI. This is an internal API. Please use
1397- * {@link org.jruby.api.Define#defineClass(ThreadContext, String, RubyClass, ObjectAllocator)} instead.
1398- * For bootstrappin we still need a non-ThreadContext define for nil and boolean class definition
1399- * as they are required before we can initialize our topmost ThreadContext.
1400- *
1401- * @param name The name for the new class
1402- * @param superClass The super class for the new class
1403- * @param allocator An ObjectAllocator instance that can construct
1404- * instances of the new class.
1405- * @return The new class
1406- */
1407- @ Extension
1408- public RubyClass defineClass (String name , RubyClass superClass , ObjectAllocator allocator ) {
1409- return defineClassUnder (name , superClass , allocator , objectClass , null );
1410- }
1411-
14121394 /**
14131395 * A variation of defineClass that allows passing in an array of supplementary
14141396 * call sites for improving dynamic invocation performance.
@@ -1421,7 +1403,12 @@ public RubyClass defineClass(String name, RubyClass superClass, ObjectAllocator
14211403 */
14221404 @ Deprecated (since = "10.0" )
14231405 public RubyClass defineClass (String name , RubyClass superClass , ObjectAllocator allocator , CallSite [] callSites ) {
1424- return defineClassUnder (name , superClass , allocator , objectClass , callSites );
1406+ return defineClassUnder (getCurrentContext (), name , superClass , allocator , objectClass , callSites );
1407+ }
1408+
1409+ @ Deprecated (since = "10.0" )
1410+ public RubyClass defineClass (String name , RubyClass superClass , ObjectAllocator allocator ) {
1411+ return defineClassUnder (getCurrentContext (), name , superClass , allocator , objectClass , null );
14251412 }
14261413
14271414 /**
@@ -1442,15 +1429,20 @@ public RubyClass defineClass(String name, RubyClass superClass, ObjectAllocator
14421429 @ Extension
14431430 @ Deprecated (since = "10.0" )
14441431 public RubyClass defineClassUnder (String name , RubyClass superClass , ObjectAllocator allocator , RubyModule parent ) {
1445- return defineClassUnder (name , superClass , allocator , parent , null );
1432+ return defineClassUnder (runtimeError .getCurrentContext (), name , superClass , allocator , parent , null );
1433+ }
1434+
1435+ @ Deprecated (since = "10.0" )
1436+ public RubyClass defineClassUnder (String id , RubyClass superClass , ObjectAllocator allocator , RubyModule parent , CallSite [] callSites ) {
1437+ return defineClassUnder (getCurrentContext (), id , superClass , allocator , parent , callSites );
14461438 }
14471439
14481440 /**
14491441 * A variation of defineClassUnder that allows passing in an array of
14501442 * supplementary call sites to improve dynamic invocation. This is an internal API. Please
1451- * use {@link org.jruby.api.Define#defineClassUnder(ThreadContext, String, RubyClass, ObjectAllocator, RubyModule)}
1452- * or {@link org.jruby.RubyModule#defineClassUnder(ThreadContext, String, RubyClass, ObjectAllocator)} instead.
1443+ * use {@link org.jruby.RubyModule#defineClassUnder(ThreadContext, String, RubyClass, ObjectAllocator)} instead.
14531444 *
1445+ * @param context the current thread context
14541446 * @param id The name for the new class as an ISO-8859_1 String (id-value)
14551447 * @param superClass The super class for the new class
14561448 * @param allocator An ObjectAllocator instance that can construct
@@ -1459,32 +1451,36 @@ public RubyClass defineClassUnder(String name, RubyClass superClass, ObjectAlloc
14591451 * @param callSites The array of call sites to add
14601452 * @return The new class
14611453 */
1462- public RubyClass defineClassUnder (String id , RubyClass superClass , ObjectAllocator allocator , RubyModule parent , CallSite [] callSites ) {
1463- IRubyObject classObj = parent .getConstantAt (id );
1464-
1465- if (classObj != null ) {
1466- if (!(classObj instanceof RubyClass )) throw typeError (getCurrentContext (), str (this , ids (this , id ), " is not a class" ));
1467- RubyClass klazz = (RubyClass )classObj ;
1468- if (klazz .getSuperClass ().getRealClass () != superClass ) {
1469- throw newNameError (str (this , ids (this , id ), " is already defined" ), newSymbol (id ));
1470- }
1471- // If we define a class in Ruby, but later want to allow it to be defined in Java,
1472- // the allocator needs to be updated
1473- if (klazz .getAllocator () != allocator ) klazz .allocator (allocator );
1474- return klazz ;
1475- }
1454+ public RubyClass defineClassUnder (ThreadContext context , String id , RubyClass superClass , ObjectAllocator allocator ,
1455+ RubyModule parent , CallSite [] callSites ) {
1456+ IRubyObject object = parent .getConstantAt (id );
1457+ if (object != null ) return foundExistingClass (context , id , superClass , allocator , object );
14761458
14771459 boolean parentIsObject = parent == objectClass ;
14781460
1479- if (superClass == null ) {
1480- IRubyObject className = parentIsObject ? ids (this , id ) :
1481- parent .toRubyString (getCurrentContext ()).append (newString ("::" )).append (ids (this , id ));
1482- warn (getCurrentContext (), str (this , "no super class for '" , className , "', Object assumed" ));
1461+ if (superClass == null ) superClass = determineSuperClass (context , id , parent , parentIsObject );
1462+
1463+ return RubyClass .newClass (context , superClass , id , allocator , parent , !parentIsObject , callSites );
1464+ }
1465+
1466+ private RubyClass determineSuperClass (ThreadContext context , String id , RubyModule parent , boolean parentIsObject ) {
1467+ IRubyObject className = parentIsObject ? ids (this , id ) :
1468+ parent .toRubyString (context ).append (newString ("::" )).append (ids (this , id ));
1469+ warn (context , str (this , "no super class for '" , className , "', Object assumed" ));
1470+
1471+ return objectClass ;
1472+ }
1473+
1474+ private RubyClass foundExistingClass (ThreadContext context , String id , RubyClass superClass , ObjectAllocator allocator , IRubyObject obj ) {
1475+ if (!(obj instanceof RubyClass klazz )) throw typeError (context , str (this , ids (this , id ), " is not a class" ));
14831476
1484- superClass = objectClass ;
1477+ if (klazz .getSuperClass ().getRealClass () != superClass ) {
1478+ throw newNameError (str (this , ids (this , id ), " is already defined" ), asSymbol (context , id ));
14851479 }
1480+ // If we define a class in Ruby, but later want to allow it to be defined in Java, the allocator needs to be updated
1481+ if (klazz .getAllocator () != allocator ) klazz .allocator (allocator );
14861482
1487- return RubyClass . newClass ( this , superClass , id , allocator , parent , ! parentIsObject , callSites ) ;
1483+ return klazz ;
14881484 }
14891485
14901486 /**
@@ -1495,9 +1491,23 @@ public RubyClass defineClassUnder(String id, RubyClass superClass, ObjectAllocat
14951491 * @return The new module
14961492 */
14971493 @ Deprecated (since = "10.0" )
1498- @ Extension
14991494 public RubyModule defineModule (String name ) {
1500- return defineModuleUnder (name , objectClass );
1495+ return defineModuleUnder (getCurrentContext (), name , objectClass );
1496+ }
1497+
1498+ /**
1499+ * This is only for defining kernel. The reason we have this is so all other define methods
1500+ * can count on ThreadContext being available. These are defined before that point.
1501+ * @param name The name for the new class
1502+ * @return The new module
1503+ */
1504+ public RubyModule defineModuleBootstrap (String name ) {
1505+ return RubyModule .newModuleBootstrap (this , name , objectClass );
1506+ }
1507+
1508+ @ Deprecated (since = "10.0" )
1509+ public RubyModule defineModuleUnder (String name , RubyModule parent ) {
1510+ return defineModuleUnder (getCurrentContext (), name , parent );
15011511 }
15021512
15031513 /**
@@ -1511,22 +1521,24 @@ public RubyModule defineModule(String name) {
15111521 * module
15121522 * @return The new module
15131523 */
1514- @ Extension
1515- public RubyModule defineModuleUnder (String name , RubyModule parent ) {
1524+ public RubyModule defineModuleUnder (ThreadContext context , String name , RubyModule parent ) {
15161525 IRubyObject moduleObj = parent .getConstantAt (name );
15171526
15181527 boolean parentIsObject = parent == objectClass ;
15191528
1520- if (moduleObj != null ) {
1521- if (moduleObj .isModule ()) return (RubyModule ) moduleObj ;
1529+ return moduleObj != null ?
1530+ foundExistingModule (context , parent , moduleObj , parentIsObject ) :
1531+ RubyModule .newModule (context , name , parent , !parentIsObject , null , -1 );
1532+ }
15221533
1523- RubyString typeName = parentIsObject ?
1524- types (this , moduleObj .getMetaClass ()) : types (this , parent , moduleObj .getMetaClass ());
1534+ private RubyModule foundExistingModule (ThreadContext context , RubyModule parent , IRubyObject moduleObj ,
1535+ boolean parentIsObject ) {
1536+ if (moduleObj .isModule ()) return (RubyModule ) moduleObj ;
15251537
1526- throw typeError ( getCurrentContext (), str ( this , typeName , " is not a module" ));
1527- }
1538+ RubyString typeName = parentIsObject ?
1539+ types ( this , moduleObj . getMetaClass ()) : types ( this , parent , moduleObj . getMetaClass ());
15281540
1529- return RubyModule . newModule ( this , name , parent , ! parentIsObject );
1541+ throw typeError ( context , str ( this , typeName , " is not a module" ) );
15301542 }
15311543
15321544 /**
@@ -3037,7 +3049,7 @@ public void loadScope(IRScope scope, boolean wrap) {
30373049
30383050 if (wrap ) {
30393051 // toss an anonymous module into the search path
3040- scope .getStaticScope ().setModule (RubyModule . newModule (this ));
3052+ scope .getStaticScope ().setModule (new RubyModule (this ));
30413053 }
30423054
30433055 runInterpreter (getCurrentContext (), scope , self );
@@ -3070,7 +3082,7 @@ public StaticScope setupWrappedToplevel(IRubyObject self, StaticScope top) {
30703082 RubyModule wrapper = loadService .getWrapperSelf ();
30713083
30723084 if (wrapper == null || wrapper .isNil ()) {
3073- wrapper = RubyModule . newModule (this );
3085+ wrapper = new RubyModule (this );
30743086 }
30753087
30763088 // toss an anonymous module into the search path
0 commit comments