Skip to content

Commit

Permalink
IR2JVM: Metaclass definition and processing.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Apr 28, 2012
1 parent 5255451 commit 68a2204
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
51 changes: 51 additions & 0 deletions src/org/jruby/ir/instructions/DefineMetaClassInstr.java
Expand Up @@ -4,20 +4,25 @@
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyFixnum;
import org.jruby.RubyModule;
import org.jruby.RubySymbol;
import org.jruby.internal.runtime.methods.CompiledIRMethod;
import org.jruby.ir.IRModuleBody;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.Variable;
import org.jruby.ir.Operation;
import org.jruby.ir.targets.JVM;
import org.jruby.ir.transformations.inlining.InlinerInfo;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.internal.runtime.methods.InterpretedIRMethod;
import org.jruby.javasupport.util.RuntimeHelpers;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.CodegenUtils;

public class DefineMetaClassInstr extends Instr implements ResultInstr {
private IRModuleBody metaClassBody;
Expand Down Expand Up @@ -71,4 +76,50 @@ public Object interpret(ThreadContext context, DynamicScope currDynScope, IRubyO
metaClassBody.getStaticScope().setModule(singletonClass);
return new InterpretedIRMethod(metaClassBody, Visibility.PUBLIC, singletonClass);
}

@Override
public void compile(JVM jvm) {
StaticScope scope = metaClassBody.getStaticScope();
if (scope.getRequiredArgs() > 3 || scope.getRestArg() >= 0 || scope.getOptionalArgs() != 0) {
throw new RuntimeException("can't compile variable method: " + this);
}

String scopeString = RuntimeHelpers.encodeScope(scope);

// new CompiledIRMethod
jvm.method().adapter.newobj(CodegenUtils.p(CompiledIRMethod.class));
jvm.method().adapter.dup();

// emit method body and get handle
jvm.emit(metaClassBody); // handle

// add'l args for CompiledIRMethod constructor
jvm.method().adapter.ldc(metaClassBody.getName());
jvm.method().adapter.ldc(metaClassBody.getFileName());
jvm.method().adapter.ldc(metaClassBody.getLineNumber());

//// static scope
jvm.method().adapter.aload(0);
jvm.method().adapter.aload(1);
jvm.method().adapter.ldc(scopeString);
jvm.method().adapter.invokestatic(CodegenUtils.p(RuntimeHelpers.class), "decodeLocalScope", "(Lorg/jruby/runtime/ThreadContext;Lorg/jruby/parser/StaticScope;Ljava/lang/String;)Lorg/jruby/parser/StaticScope;");

// get singleton class
jvm.method().pushRuntime();
jvm.emit(object);
jvm.method().invokeHelper("getSingletonClass", RubyClass.class, Ruby.class, IRubyObject.class);

// set into StaticScope
jvm.method().adapter.dup2();
jvm.method().adapter.invokevirtual(CodegenUtils.p(StaticScope.class), "setModule", CodegenUtils.sig(void.class, RubyModule.class));

jvm.method().adapter.getstatic(CodegenUtils.p(Visibility.class), "PUBLIC", CodegenUtils.ci(Visibility.class));
jvm.method().adapter.swap();

// invoke constructor
jvm.method().adapter.invokespecial(CodegenUtils.p(CompiledIRMethod.class), "<init>", "(Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/String;ILorg/jruby/parser/StaticScope;Lorg/jruby/runtime/Visibility;Lorg/jruby/RubyModule;)V");

// store
jvm.method().storeLocal(jvm.methodData().local(getResult()));
}
}
5 changes: 5 additions & 0 deletions src/org/jruby/ir/targets/IRBytecodeAdapter.java
Expand Up @@ -73,6 +73,11 @@ public void push(String sym) {
adapter.invokedynamic("symbol", sig(JVM.OBJECT, ThreadContext.class), Bootstrap.symbol(), sym);
}

public void pushRuntime() {
adapter.aload(0);
adapter.getfield(p(ThreadContext.class), "runtime", ci(Ruby.class));
}

public void loadLocal(int i) {
adapter.aload(i);
}
Expand Down
8 changes: 6 additions & 2 deletions src/org/jruby/ir/targets/JVM.java
Expand Up @@ -165,10 +165,14 @@ public void emit(IRMethod method) {
}

public void emit(IRModuleBody method) {
emitScope(method, method.getName(), 0);
String name = method.getName();
if (name.indexOf("DUMMY_MC") != -1) {
name = "METACLASS:" + Math.abs(method.hashCode());
}
emitScope(method, name, 0);

// push a method handle for binding purposes
method().pushHandle(clsData().clsName, method.getName(), method.getStaticScope().getRequiredArgs());
method().pushHandle(clsData().clsName, name, method.getStaticScope().getRequiredArgs());
}

public void emitScope(IRScope scope, String name, int arity) {
Expand Down

0 comments on commit 68a2204

Please sign in to comment.