1 32 package org.jruby; 33 34 import java.util.Iterator ; 35 36 import org.jruby.runtime.Block; 37 import org.jruby.runtime.CallbackFactory; 38 import org.jruby.runtime.ThreadContext; 39 import org.jruby.runtime.builtin.IRubyObject; 40 41 public class RubyObjectSpace { 42 43 46 public static RubyModule createObjectSpaceModule(Ruby runtime) { 47 RubyModule objectSpaceModule = runtime.defineModule("ObjectSpace"); 48 CallbackFactory callbackFactory = runtime.callbackFactory(RubyObjectSpace.class); 49 objectSpaceModule.defineModuleFunction("each_object", callbackFactory.getOptSingletonMethod("each_object")); 50 objectSpaceModule.defineFastModuleFunction("garbage_collect", callbackFactory.getFastSingletonMethod("garbage_collect")); 51 objectSpaceModule.defineFastModuleFunction("_id2ref", callbackFactory.getFastSingletonMethod("id2ref", RubyFixnum.class)); 52 objectSpaceModule.defineModuleFunction("define_finalizer", 53 callbackFactory.getOptSingletonMethod("define_finalizer")); 54 objectSpaceModule.defineModuleFunction("undefine_finalizer", 55 callbackFactory.getOptSingletonMethod("undefine_finalizer")); 56 57 return objectSpaceModule; 58 } 59 60 public static IRubyObject define_finalizer(IRubyObject recv, IRubyObject[] args, Block block) { 61 RubyProc proc = null; 62 if(recv.checkArgumentCount(args,1,2) == 2) { 63 if(args[1] instanceof RubyProc) { 64 proc = (RubyProc)args[1]; 65 } else { 66 proc = (RubyProc)args[1].convertToType("Proc","to_proc",true); 67 } 68 } else { 69 proc = recv.getRuntime().newProc(false, block); 70 } 71 IRubyObject obj = args[0]; 72 long id = RubyNumeric.fix2long(obj.id()); 73 recv.getRuntime().getObjectSpace().addFinalizer(obj,id,proc); 74 return recv; 75 } 76 77 public static IRubyObject undefine_finalizer(IRubyObject recv, IRubyObject[] args, Block block) { 78 recv.checkArgumentCount(args,1,1); 79 recv.getRuntime().getObjectSpace().removeFinalizers(RubyNumeric.fix2long(args[0].id())); 80 return recv; 81 } 82 83 public static IRubyObject id2ref(IRubyObject recv, RubyFixnum id) { 84 Ruby runtime = id.getRuntime(); 85 long longId = id.getLongValue(); 86 if (longId == 0) { 87 return runtime.getFalse(); 88 } else if (longId == 2) { 89 return runtime.getTrue(); 90 } else if (longId == 4) { 91 return runtime.getNil(); 92 } else if (longId % 2 != 0) { return runtime.newFixnum((longId - 1) / 2); 94 } else { 95 IRubyObject object = runtime.getObjectSpace().id2ref(longId); 96 if (object == null) 97 runtime.newRangeError("not an id value"); 98 return object; 99 } 100 } 101 102 public static IRubyObject each_object(IRubyObject recv, IRubyObject[] args, Block block) { 103 RubyModule rubyClass; 104 if (args.length == 0) { 105 rubyClass = recv.getRuntime().getObject(); 106 } else { 107 rubyClass = (RubyModule) args[0]; 108 } 109 int count = 0; 110 Iterator iter = recv.getRuntime().getObjectSpace().iterator(rubyClass); 111 IRubyObject obj = null; 112 ThreadContext context = recv.getRuntime().getCurrentContext(); 113 while ((obj = (IRubyObject)iter.next()) != null) { 114 count++; 115 context.yield(obj, block); 116 } 117 return recv.getRuntime().newFixnum(count); 118 } 119 120 public static IRubyObject garbage_collect(IRubyObject recv) { 121 return RubyGC.start(recv); 122 } 123 } 124 | Popular Tags |