public void emit(IRScriptBody script) { String clsName = jvm.scriptToClass(script.getName()); jvm.pushscript(clsName, script.getFileName()); emitScope(script, "__script__", 0); jvm.cls().visitEnd(); jvm.popclass(); }
public byte[] code() { return jvm.code(); }
public String emitScope(IRScope scope, String name, int arity) { this.currentScope = scope; name = name + scope.getLineNumber(); jvm.pushmethod(name, arity); Tuple<Instr[], Map<Integer,Label[]>> t = scope.prepareForCompilation(); Instr[] instrs = t.a; Map<Integer, Label[]> jumpTable = t.b; IRBytecodeAdapter m = jvm.method(); for (int i = 0; i < instrs.length; i++) { Instr instr = instrs[i]; if (jumpTable.get(i) != null) { for (Label label : jumpTable.get(i)) m.mark(jvm.methodData().getLabel(label)); } visit(instr); } jvm.popmethod(); return name; }
jvm.pushmethod(name, scope, signature, specificArity); if (scopeMap.get(scopeField) == null) { scopeMap.put(scopeField, scope); jvm.cls().visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_VOLATILE, scopeField, ci(IRScope.class), null, null).visitEnd(); rescueEndForStart.put(currentRegionStart, jvm.methodData().getLabel(bb.getLabel())); org.objectweb.asm.Label start = jvm.methodData().getLabel(bb.getLabel()); Label rescueLabel = exceptionTable.get(bb); if (rescueLabel != null && (end = rescueEndForStart.get(bb.getLabel())) != null) { org.objectweb.asm.Label rescue = jvm.methodData().getLabel(rescueLabel); jvmAdapter().trycatch(start, end, rescue, p(Throwable.class)); jvm.popmethod(); currentScopeName = savedScopeName;
@Override public void CheckArityInstr(CheckArityInstr checkarityinstr) { if (jvm.methodData().specificArity >= 0) { // no arity check in specific arity path } else { checkArity(checkarityinstr.required, checkarityinstr.opt, checkarityinstr.rest, checkarityinstr.receivesKeywords, checkarityinstr.restKey); } }
@Override public void Self(Self self) { // %self is in JVM-local-2 always jvm.method().loadLocal(2); }
public ClassVisitor cls() { return clsData().cls; }
protected void emitVarargsMethodWrapper(IRScope scope, String variableName, String specificName, Signature variableSignature, Signature specificSignature) { jvm.pushmethod(variableName, scope, variableSignature, false); IRBytecodeAdapter m = jvmMethod(); // check arity org.jruby.runtime.Signature scopeSig = scope.getStaticScope().getSignature(); checkArity(scopeSig.required(), scopeSig.opt(), scopeSig.hasRest(), scopeSig.hasKwargs(), scopeSig.keyRest()); // push leading args m.loadContext(); m.loadStaticScope(); m.loadSelf(); // unwrap specific args if (scopeSig.required() > 0) { for (int i = 0; i < scopeSig.required(); i++) { m.loadArgs(); jvmAdapter().pushInt(i); jvmAdapter().aaload(); } } // push trailing args m.loadBlock(); m.loadFrameClass(); m.loadFrameName(); // invoke specific-arity version and return Method specificMethod = new Method(specificName, Type.getType(specificSignature.type().returnType()), IRRuntimeHelpers.typesFromSignature(specificSignature)); jvmAdapter().invokestatic(m.getClassData().clsName, specificName, specificMethod.getDescriptor()); jvmAdapter().areturn(); jvm.popmethod(); }
public Class defineFromBytecode(IRScope scope, byte[] code, ClassDefiningClassLoader jrubyClassLoader) { file = scope.getFile(); lastLine = -1; Class result = jrubyClassLoader.defineClass(c(JVM.scriptToClass(file)), code); for (Map.Entry<String, IRScope> entry : scopeMap.entrySet()) { try { result.getField(entry.getKey()).set(null, entry.getValue()); } catch (Exception e) { throw new NotCompilableException(e); } } return result; }
public void pushscript(String clsName, String filename) { PrintWriter pw = new PrintWriter(System.out); writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); clsStack.push(new ClassData(clsName, writer)); cls().visit(RubyInstanceConfig.JAVA_VERSION, ACC_PUBLIC + ACC_SUPER, clsName, null, p(Object.class), null); cls().visitSource(filename, null); pw.flush(); }
public String emitScope(IRScope scope, String name, int arity) { this.currentScope = scope; name = name + scope.getLineNumber(); jvm.pushmethod(name, arity); Tuple<Instr[], Map<Integer,Label[]>> t = scope.prepareForCompilation(); Instr[] instrs = t.a; Map<Integer, Label[]> jumpTable = t.b; IRBytecodeAdapter m = jvm.method(); for (int i = 0; i < instrs.length; i++) { Instr instr = instrs[i]; if (jumpTable.get(i) != null) { for (Label label : jumpTable.get(i)) m.mark(jvm.methodData().getLabel(label)); } visit(instr); } jvm.popmethod(); return name; }
jvm.pushmethod(name, scope, signature, specificArity); if (scopeMap.get(scopeField) == null) { scopeMap.put(scopeField, scope); jvm.cls().visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_VOLATILE, scopeField, ci(IRScope.class), null, null).visitEnd(); rescueEndForStart.put(currentRegionStart, jvm.methodData().getLabel(bb.getLabel())); org.objectweb.asm.Label start = jvm.methodData().getLabel(bb.getLabel()); Label rescueLabel = exceptionTable.get(bb); if (rescueLabel != null && (end = rescueEndForStart.get(bb.getLabel())) != null) { org.objectweb.asm.Label rescue = jvm.methodData().getLabel(rescueLabel); jvmAdapter().trycatch(start, end, rescue, p(Throwable.class)); jvm.popmethod(); currentScopeName = savedScopeName;
@Override public void CheckArityInstr(CheckArityInstr checkarityinstr) { if (jvm.methodData().specificArity >= 0) { // no arity check in specific arity path } else { checkArity(checkarityinstr.required, checkarityinstr.opt, checkarityinstr.rest, checkarityinstr.receivesKeywords, checkarityinstr.restKey); } }
@Override public void ReceiveRestArgInstr(ReceiveRestArgInstr instr) { // FIXME: Only works when args is in an array rather than being flattened out // FIXME: Missing kwargs 2.0 support (kwArgHashCount value) jvm.method().loadContext(); jvm.method().adapter.pushInt(instr.numUsedArgs); // MIN reqd args jvm.method().adapter.pushInt(instr.getArgIndex()); // args array offset jvm.method().adapter.aload(3); // FIXME: what is the correct lvar index for args[]? jvm.method().invokeHelper("irLoadRestArg", IRubyObject.class, ThreadContext.class, int.class, int.class, IRubyObject[].class); }
public IRBytecodeAdapter method() { return clsData().method(); }
protected void emitVarargsMethodWrapper(IRScope scope, String variableName, String specificName, Signature variableSignature, Signature specificSignature) { jvm.pushmethod(variableName, scope, variableSignature, false); IRBytecodeAdapter m = jvmMethod(); // check arity org.jruby.runtime.Signature scopeSig = scope.getStaticScope().getSignature(); checkArity(scopeSig.required(), scopeSig.opt(), scopeSig.hasRest(), scopeSig.hasKwargs(), scopeSig.keyRest()); // push leading args m.loadContext(); m.loadStaticScope(); m.loadSelf(); // unwrap specific args if (scopeSig.required() > 0) { for (int i = 0; i < scopeSig.required(); i++) { m.loadArgs(); jvmAdapter().pushInt(i); jvmAdapter().aaload(); } } // push trailing args m.loadBlock(); m.loadFrameClass(); m.loadFrameName(); // invoke specific-arity version and return Method specificMethod = new Method(specificName, Type.getType(specificSignature.type().returnType()), IRRuntimeHelpers.typesFromSignature(specificSignature)); jvmAdapter().invokestatic(m.getClassData().clsName, specificName, specificMethod.getDescriptor()); jvmAdapter().areturn(); jvm.popmethod(); }
public Class defineFromBytecode(IRScope scope, byte[] code, ClassDefiningClassLoader jrubyClassLoader) { file = scope.getFile(); lastLine = -1; Class result = jrubyClassLoader.defineClass(c(JVM.scriptToClass(file)), code); for (Map.Entry<String, IRScope> entry : scopeMap.entrySet()) { try { result.getField(entry.getKey()).set(null, entry.getValue()); } catch (Exception e) { throw new NotCompilableException(e); } } return result; }