public static String scriptToClass(String name) { if (name.equals("-e")) { return "DashE"; } else { return JavaNameMangler.mangledFilenameForStartupClasspath(name); } }
public JITClassGenerator( String className, String methodName, String key, Ruby ruby, DefaultMethod method, JITCounts counts) { this.packageName = JITCompiler.RUBY_JIT_PREFIX; if (RubyInstanceConfig.JAVA_VERSION == Opcodes.V1_7) { // recent Java 7 seems to have a bug that leaks definitions across cousin classloaders // so we force the class name to be unique to this runtime digestString = getHashForString(key) + Math.abs(ruby.hashCode()); } else { digestString = getHashForString(key); } this.className = packageName + "/" + className.replace('.', '/') + CLASS_METHOD_DELIMITER + JavaNameMangler.mangleMethodName(methodName) + "_" + digestString; this.name = this.className.replaceAll("/", "."); this.bodyNode = method.getBodyNode(); this.argsNode = method.getArgsNode(); this.methodName = methodName; filename = calculateFilename(argsNode, bodyNode); staticScope = method.getStaticScope(); asmCompiler = new StandardASMCompiler(this.className, filename); this.ruby = ruby; this.counts = counts; }
public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) { String[] nameComponents = name.split(":"); String methodName = JavaNameMangler.demangleMethodName(nameComponents[1]); CallType callType = nameComponents[0].equals("callFunctional") ? CallType.FUNCTIONAL : CallType.VARIABLE; InvokeSite site = new SelfInvokeSite(type, methodName, callType); return InvokeSite.bootstrap(site, lookup); }
public static CallSite bootstrap( MethodHandles.Lookup lookup, String name, MethodType type, String splatmapString) { String[] targetAndMethod = name.split(":"); String superName = JavaNameMangler.demangleMethodName(targetAndMethod[1]); InvokeSite site; switch (targetAndMethod[0]) { case "invokeInstanceSuper": site = new InstanceSuperInvokeSite(type, superName, splatmapString); break; case "invokeClassSuper": site = new ClassSuperInvokeSite(type, superName, splatmapString); break; default: throw new RuntimeException("invalid super call: " + name); } return InvokeSite.bootstrap(site, lookup); }
private RubyStackTraceElement[] transformBacktrace(Map<String, String> boundMethods) { List<RubyStackTraceElement> trace = new ArrayList<RubyStackTraceElement>(javaTrace.length); // used for duplicating the previous Ruby frame when masking native calls boolean dupFrame = false; String dupFrameName = null; // a running index into the Ruby backtrace stack, incremented for each // interpreter frame we encounter in the Java backtrace. int rubyFrameIndex = rubyTrace == null ? -1 : rubyTrace.length - 1; // no Java trace, can't generate hybrid trace // TODO: Perhaps just generate the interpreter trace? Is this path ever hit? if (javaTrace == null) { return null; } for (int i = 0; i < javaTrace.length; i++) { StackTraceElement element = javaTrace[i]; if (element.getFileName() != null && (element.getFileName().endsWith(".rb") || element.getFileName().equals("-e") || element.getClassName().startsWith(JITCompiler.RUBY_JIT_PREFIX + ".") || element.getMethodName().contains("$RUBY$") || element.getMethodName().contains("__file__"))) { if (element.getLineNumber() == -1) { continue; } String methodName = element.getMethodName(); String className = element.getClassName(); // FIXME: Formalize jitted method structure so this isn't quite as hacky if (className.startsWith(JITCompiler.RUBY_JIT_PREFIX)) { // pull out and demangle the method name methodName = className.substring( JITCompiler.RUBY_JIT_PREFIX.length() + 1, className.lastIndexOf("_")); methodName = JavaNameMangler.demangleMethodName(methodName); RubyStackTraceElement rubyElement = new RubyStackTraceElement( className, methodName, element.getFileName(), element.getLineNumber(), false); // dup if masking native and previous frame was native if (maskNative && dupFrame) { dupFrame = false; trace.add( new RubyStackTraceElement( rubyElement.getClassName(), dupFrameName, rubyElement.getFileName(), rubyElement.getLineNumber(), rubyElement.isBinding())); } trace.add(rubyElement); // if it's a synthetic call, use it but gobble up parent calls // TODO: need to formalize this better if (element.getMethodName().contains("$RUBY$SYNTHETIC")) { // gobble up at least one parent, and keep going if there's more synthetic frames while (element.getMethodName().indexOf("$RUBY$SYNTHETIC") != -1 && ++i < javaTrace.length) { element = javaTrace[i]; } } continue; } int RUBYindex = methodName.indexOf("$RUBY$"); if (RUBYindex >= 0) { // if it's a synthetic call, use it but gobble up parent calls // TODO: need to formalize this better methodName = methodName.substring(RUBYindex); if (methodName.startsWith("$RUBY$SYNTHETIC")) { methodName = methodName.substring("$RUBY$SYNTHETIC".length()); methodName = JavaNameMangler.demangleMethodName(methodName); if (methodName.equals("__file__")) { methodName = "(root)"; } RubyStackTraceElement rubyElement = new RubyStackTraceElement( className, methodName, element.getFileName(), element.getLineNumber(), false); // dup if masking native and previous frame was native if (maskNative && dupFrame) { dupFrame = false; trace.add( new RubyStackTraceElement( rubyElement.getClassName(), dupFrameName, rubyElement.getFileName(), rubyElement.getLineNumber(), rubyElement.isBinding())); } trace.add(rubyElement); // gobble up at least one parent, and keep going if there's more synthetic frames while (element.getMethodName().indexOf("$RUBY$SYNTHETIC") != -1 && ++i < javaTrace.length) { element = javaTrace[i]; } continue; } methodName = methodName.substring("$RUBY$".length()); methodName = JavaNameMangler.demangleMethodName(methodName); RubyStackTraceElement rubyElement = new RubyStackTraceElement( className, methodName, element.getFileName(), element.getLineNumber(), false); // dup if masking native and previous frame was native if (maskNative && dupFrame) { dupFrame = false; trace.add( new RubyStackTraceElement( rubyElement.getClassName(), dupFrameName, rubyElement.getFileName(), rubyElement.getLineNumber(), rubyElement.isBinding())); } trace.add(rubyElement); continue; } if (methodName.equals("__file__") && !element.getFileName().endsWith("AbstractScript.java")) { methodName = "(root)"; RubyStackTraceElement rubyElement = new RubyStackTraceElement( className, methodName, element.getFileName(), element.getLineNumber(), false); // dup if masking native and previous frame was native if (maskNative && dupFrame) { dupFrame = false; trace.add( new RubyStackTraceElement( rubyElement.getClassName(), dupFrameName, rubyElement.getFileName(), rubyElement.getLineNumber(), rubyElement.isBinding())); } trace.add(rubyElement); continue; } } String dotClassMethod = element.getClassName() + "." + element.getMethodName(); String rubyName = null; if (fullTrace || (rubyName = boundMethods.get(dotClassMethod)) != null) { String filename = element.getFileName(); // stick package on the beginning if (filename == null) { filename = element.getClassName().replaceAll("\\.", "/"); } else { int lastDot = element.getClassName().lastIndexOf('.'); if (lastDot != -1) { filename = element.getClassName().substring(0, lastDot + 1).replaceAll("\\.", "/") + filename; } } if (maskNative) { // for Kernel#caller, don't show .java frames in the trace dupFrame = true; dupFrameName = rubyName; continue; } else { if (rubyName == null) rubyName = element.getMethodName(); trace.add( new RubyStackTraceElement( element.getClassName(), rubyName, filename, element.getLineNumber(), false)); } // if not full trace, we're done; don't check interpreted marker if (!fullTrace) { continue; } } String classMethod = element.getClassName() + "." + element.getMethodName(); FrameType frameType = FrameType.INTERPRETED_FRAMES.get(classMethod); if (frameType != null && rubyFrameIndex >= 0) { // Frame matches one of our markers for "interpreted" calls BacktraceElement rubyFrame = rubyTrace[rubyFrameIndex]; RubyStackTraceElement rubyElement = new RubyStackTraceElement( rubyFrame.klass, rubyFrame.method, rubyFrame.filename, rubyFrame.line + 1, false); // dup if masking native and previous frame was native if (maskNative && dupFrame) { dupFrame = false; trace.add( new RubyStackTraceElement( rubyElement.getClassName(), dupFrameName, rubyElement.getFileName(), rubyElement.getLineNumber(), rubyElement.isBinding())); } trace.add(rubyElement); rubyFrameIndex--; continue; } } RubyStackTraceElement[] rubyStackTrace = new RubyStackTraceElement[trace.size()]; return (RubyStackTraceElement[]) trace.toArray(rubyStackTrace); }