Permalink
Browse files

Merge branch 'master' into expr_tree

  • Loading branch information...
2 parents 744edda + 9f35c90 commit e0413071ffe08e74645fa25b803a8705407210df @subbuss subbuss committed Mar 8, 2012
View
@@ -1,6 +1,14 @@
#!/bin/bash
# Run from your JRuby home directory....More smarts needed here.
+#
+# For 1.8 parser:
+# PATH=$PATH:<path to jay executable> bin/generate_parser DefaultRubyParser
+#
+# For 1.9 parser:
+# PATH=$PATH:<path to jay executable> bin/generate_parser Ruby19Parser Ruby19
+#
+# jay is available from https://github.com/jruby/jay
###### Change these to tastes ######
JAY=jay
View
@@ -382,7 +382,7 @@
<orderEntry type="module-library">
<library>
<CLASSES>
- <root url="jar://$MODULE_DIR$/build_lib/joda-time-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/build_lib/joda-time-2.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
View
@@ -11,6 +11,9 @@ WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin/
SPEC_DIR = File.join(File.dirname(__FILE__), 'ruby') unless defined?(SPEC_DIR)
TAGS_DIR = File.join(File.dirname(__FILE__), 'tags') unless defined?(TAGS_DIR)
+# Add --1.8 to JRUBY_OPTS env so we can be sure it propagates
+ENV['JRUBY_OPTS'] = ENV['JRUBY_OPTS'].to_s + " --1.8"
+
class MSpecScript
# Language features specs
set :language, [ SPEC_DIR + '/language' ]
View
@@ -11,6 +11,9 @@ WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin/
SPEC_DIR = File.join(File.dirname(__FILE__), 'ruby') unless defined?(SPEC_DIR)
TAGS_DIR = File.join(File.dirname(__FILE__), 'tags') unless defined?(TAGS_DIR)
+# Add --1.9 to JRUBY_OPTS env so we can be sure it propagates
+ENV['JRUBY_OPTS'] = ENV['JRUBY_OPTS'].to_s + " --1.9"
+
class MSpecScript
# Language features specs
set :language, [
@@ -1 +0,0 @@
-fails:IO#getc returns the next character from the stream
View
@@ -1388,9 +1388,9 @@ private void initCore() {
if (is1_9()) {
if (RubyInstanceConfig.COROUTINE_FIBERS) {
- LoadService.reflectedLoad(this, "fiber", "org.jruby.ext.fiber.CoroutineFiberLibrary", getJRubyClassLoader(), false);
+ LoadService.reflectedLoad(this, "fiber", "org.jruby.ext.fiber.CoroutineFiberLibrary", getClassLoader(), false);
} else {
- LoadService.reflectedLoad(this, "fiber", "org.jruby.ext.fiber.ThreadFiberLibrary", getJRubyClassLoader(), false);
+ LoadService.reflectedLoad(this, "fiber", "org.jruby.ext.fiber.ThreadFiberLibrary", getClassLoader(), false);
}
} else {
if (RubyInstanceConfig.COROUTINE_FIBERS) {
View
@@ -2363,22 +2363,6 @@ public IRubyObject getc() {
return getRuntime().newFixnum(c);
}
-
- private ByteList fromEncodedBytes(Ruby runtime, Encoding enc, int value) {
- int n;
- try {
- n = value < 0 ? 0 : enc.codeToMbcLength(value);
- } catch (EncodingException ee) {
- n = 0;
- }
-
- if (n <= 0) throw runtime.newRangeError(this.toString() + " out of char range");
-
- ByteList bytes = new ByteList(n);
- enc.codeToMbc(value, bytes.getUnsafeBytes(), 0);
- bytes.setRealSize(n);
- return bytes;
- }
@JRubyMethod(name = "readchar", compat = RUBY1_9)
public IRubyObject readchar19(ThreadContext context) {
@@ -2407,25 +2391,85 @@ public IRubyObject readbyte(ThreadContext context) {
@JRubyMethod(name = "getc", compat = RUBY1_9)
public IRubyObject getc19(ThreadContext context) {
Ruby runtime = context.getRuntime();
- int c = getcCommon();
- if (c == -1) {
- // CRuby checks ferror(f) and retry getc for non-blocking IO
- // read. We checks readability first if possible so retry should
- // not be needed I believe.
- return runtime.getNil();
- }
+ try {
+ OpenFile myOpenFile = getOpenFileChecked();
- Encoding external = getExternalEncoding(runtime);
- ByteList bytes = fromEncodedBytes(runtime, external, (int) c);
- Encoding internal = getInternalEncoding(runtime);
-
- if (internal != null) {
- bytes = RubyString.transcode(context, bytes, external, internal, runtime.getNil());
- }
+ myOpenFile.checkReadable(getRuntime());
+ myOpenFile.setReadBuffered();
+
+ Stream stream = myOpenFile.getMainStreamSafe();
- // TODO: This should be optimized like RubyInteger.chr is for ascii values
- return RubyString.newStringNoCopy(runtime, bytes, external, 0);
+ readCheck(stream);
+ waitReadable(stream);
+ stream.clearerr();
+
+ int c = stream.fgetc();
+
+ if (c == -1) {
+ // CRuby checks ferror(f) and retry getc for non-blocking IO
+ // read. We checks readability first if possible so retry should
+ // not be needed I believe.
+ return runtime.getNil();
+ }
+
+ Encoding external = getExternalEncoding(runtime);
+ Encoding internal = getInternalEncoding(runtime);
+ ByteList bytes = null;
+ boolean shared = false;
+ int cr = 0;
+
+ if (Encoding.isAscii(c)) {
+ if (internal == ASCIIEncoding.INSTANCE) {
+ bytes = RubyInteger.SINGLE_CHAR_BYTELISTS[(int)c];
+ shared = true;
+ } else {
+ bytes = new ByteList(new byte[]{(byte)c}, external, false);
+ shared = false;
+ cr = StringSupport.CR_7BIT;
+ }
+ } else {
+ // potential MBC
+ int len = external.length((byte)c);
+ byte[] byteAry = new byte[len];
+
+ byteAry[0] = (byte)c;
+ for (int i = 1; i < len; i++) {
+ c = (byte)stream.fgetc();
+ if (c == -1) {
+ bytes = new ByteList(byteAry, 0, i - 1, external, false);
+ cr = StringSupport.CR_BROKEN;
+ }
+ byteAry[i] = (byte)c;
+ }
+
+ if (bytes == null) {
+ cr = StringSupport.CR_VALID;
+ bytes = new ByteList(byteAry, external, false);
+ }
+ }
+
+ if (cr != StringSupport.CR_BROKEN && external != internal) {
+ bytes = RubyString.transcode(context, bytes, external, internal, runtime.getNil());
+ }
+
+ if (internal == null) internal = external;
+
+ if (shared) {
+ return RubyString.newStringShared(runtime, bytes, cr);
+ } else {
+ return RubyString.newStringNoCopy(runtime, bytes, internal, cr);
+ }
+
+ } catch (InvalidValueException ex) {
+ throw getRuntime().newErrnoEINVALError();
+ } catch (BadDescriptorException e) {
+ throw getRuntime().newErrnoEBADFError();
+ } catch (EOFException e) {
+ throw getRuntime().newEOFError();
+ } catch (IOException e) {
+ throw getRuntime().newIOErrorFromException(e);
+ }
}
public int getcCommon() {
@@ -3105,16 +3149,35 @@ public IRubyObject each_charInternal(final ThreadContext context, final Block bl
return this;
}
- @JRubyMethod
+ public IRubyObject each_charInternal19(final ThreadContext context, final Block block) {
+ IRubyObject ch;
+
+ while(!(ch = getc19(context)).isNil()) {
+ block.yield(context, ch);
+ }
+ return this;
+ }
+
+ @JRubyMethod(compat = RUBY1_8)
public IRubyObject each_char(final ThreadContext context, final Block block) {
return block.isGiven() ? each_charInternal(context, block) : enumeratorize(context.getRuntime(), this, "each_char");
}
- @JRubyMethod
+ @JRubyMethod(name = "each_char", compat = RUBY1_9)
+ public IRubyObject each_char19(final ThreadContext context, final Block block) {
+ return block.isGiven() ? each_charInternal19(context, block) : enumeratorize(context.getRuntime(), this, "each_char");
+ }
+
+ @JRubyMethod(compat = RUBY1_8)
public IRubyObject chars(final ThreadContext context, final Block block) {
return block.isGiven() ? each_charInternal(context, block) : enumeratorize(context.getRuntime(), this, "chars");
}
+ @JRubyMethod(name = "chars", compat = RUBY1_9)
+ public IRubyObject chars19(final ThreadContext context, final Block block) {
+ return block.isGiven() ? each_charInternal19(context, block) : enumeratorize(context.getRuntime(), this, "chars");
+ }
+
@JRubyMethod
public IRubyObject codepoints(final ThreadContext context, final Block block) {
return eachCodePointCommon(context, block, "codepoints");
@@ -4373,7 +4436,8 @@ public static ModeFlags newModeFlags(Ruby runtime, String mode) {
try {
return new ModeFlags(mode);
} catch (InvalidValueException ive) {
- throw runtime.newErrnoEINVALError();
+ // This is used by File and StringIO, which seem to want an ArgumentError instead of EINVAL
+ throw runtime.newArgumentError("illegal access mode " + mode);
}
}
@@ -4398,7 +4462,8 @@ public static IOOptions newIOOptions(Ruby runtime, String mode) {
try {
return new IOOptions(runtime, mode);
} catch (InvalidValueException ive) {
- throw runtime.newErrnoEINVALError();
+ // This is used by File and StringIO, which seem to want an ArgumentError instead of EINVAL
+ throw runtime.newArgumentError("illegal access mode " + mode);
}
}
@@ -2414,7 +2414,7 @@ public IRubyObject inspect19() {
result.cat('"');
int prev = p;
while (p < end) {
- int cc;
+ int cc = 0;
int n = StringSupport.preciseLength(enc, bytes, p, end);
if (n <= 0) {
@@ -2432,7 +2432,7 @@ public IRubyObject inspect19() {
if ((enc.isAsciiCompatible() || isUnicode) &&
(c == '"' || c == '\\' ||
(c == '#' && p < end && (StringSupport.preciseLength(enc, bytes, p, end) > 0) &&
- (cc = codePoint(runtime, enc, bytes, p, end)) == '$' && cc == '@' && cc == '{'))) {
+ (cc = codePoint(runtime, enc, bytes, p, end)) == '$' || cc == '@' || cc == '{'))) {
if (p - n > prev) result.cat(bytes, prev, p - n - prev);
result.cat('\\');
if (enc.isAsciiCompatible() || enc == resultEnc) {
@@ -241,9 +241,6 @@ public synchronized void dispose() {
// unlock all locked locks
unlockAll();
- // clear all thread locals
- clearThreadLocals();
-
// reset thread priority to initial if pooling
if (Options.THREADPOOL_ENABLED.load()) {
threadImpl.setPriority(initialPriority);
@@ -12,7 +12,6 @@
import org.jruby.RubyModule;
import org.jruby.compiler.ir.compiler_pass.CFGBuilder;
import org.jruby.compiler.ir.compiler_pass.CompilerPass;
-import org.jruby.compiler.ir.compiler_pass.DominatorTreeBuilder;
import org.jruby.compiler.ir.compiler_pass.IRPrinter;
import org.jruby.compiler.ir.compiler_pass.InlineTest;
import org.jruby.compiler.ir.compiler_pass.LinearizeCFG;
@@ -1112,7 +1111,7 @@ public DataFlowProblem getDataFlowSolution(String name) {
if (linearizedBBList != null) return linearizedBBList; // Already linearized
- linearizedBBList = CFGLinearizer.linearize(cfg());
+ linearizedBBList = CFGLinearizer.linearize(cfg);
return linearizedBBList;
}
@@ -1242,13 +1241,6 @@ public void buildCFG(List<Instr> instrList) {
CFG newBuild = new CFG(this);
newBuild.build(instrList);
cfg = newBuild;
- }
-
- public void buildDominatorTree(DominatorTreeBuilder builder) {
- depends(cfg());
-
- // FIXME: Add result from this build and add to CFG as a field, then add depends() for htings which use it.
- builder.buildDominatorTree(cfg, cfg.postOrderList(), cfg.getMaxNodeID());
}
/* Record a begin block -- not all scope implementations can handle them */
@@ -57,8 +57,10 @@ public Object run(IRScope scope) {
switch (dependency.b) { // type of dependency
case RETRIEVE:
data[i] = makeSureDependencyHasRunOnce(dependency.a, scope);
+ break;
case RERUN:
data[i] = executeDependency(dependency.a, scope);
+ break;
}
}
@@ -1,10 +1,13 @@
package org.jruby.compiler.ir.compiler_pass;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.jruby.compiler.ir.IRScope;
+import org.jruby.compiler.ir.Tuple;
import org.jruby.compiler.ir.representations.BasicBlock;
import org.jruby.compiler.ir.representations.CFG;
import org.jruby.util.log.Logger;
@@ -13,18 +16,28 @@
public class DominatorTreeBuilder extends CompilerPass {
private static String[] NAMES = new String[] {"build_dominator", "dominator"};
private static final Logger LOG = LoggerFactory.getLogger("DominatorTreeBuilder");
-
+ public static List<Tuple<Class<CompilerPass>, DependencyType>> DEPENDENCIES = new ArrayList<Tuple<Class<CompilerPass>, DependencyType>>() {{
+ add(new Tuple(CFGBuilder.class, CompilerPass.DependencyType.RETRIEVE));
+ }};
+
public String getLabel() {
return "Build Dominator Tree";
}
public boolean isPreOrder() {
return false;
}
+
+ @Override
+ public List<Tuple<Class<CompilerPass>, DependencyType>> getDependencies() {
+ return DEPENDENCIES;
+ }
public Object execute(IRScope scope, Object... data) {
+ CFG cfg = (CFG) data[0];
+
try {
- scope.buildDominatorTree(this);
+ buildDominatorTree(cfg, cfg.postOrderList(), cfg.getMaxNodeID());
} catch (Exception e) {
LOG.debug("Caught exception building dom tree for {}", scope.cfg());
}
@@ -1,17 +1,28 @@
package org.jruby.compiler.ir.compiler_pass;
+import java.util.ArrayList;
+import java.util.List;
import org.jruby.compiler.ir.IRScope;
+import org.jruby.compiler.ir.Tuple;
public class LinearizeCFG extends CompilerPass {
public static String[] NAMES = new String[] { "linearize", "linearize_cfg" };
-
+ public static List<Tuple<Class<CompilerPass>, DependencyType>> DEPENDENCIES = new ArrayList<Tuple<Class<CompilerPass>, DependencyType>>() {{
+ add(new Tuple(CFGBuilder.class, CompilerPass.DependencyType.RETRIEVE));
+ }};
+
public String getLabel() {
return "Linearize CFG";
}
public boolean isPreOrder() {
return true;
}
+
+ @Override
+ public List<Tuple<Class<CompilerPass>, DependencyType>> getDependencies() {
+ return DEPENDENCIES;
+ }
public Object execute(IRScope scope, Object... data) {
scope.buildLinearization();
Oops, something went wrong.

0 comments on commit e041307

Please sign in to comment.