Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into expr_tree
Browse files Browse the repository at this point in the history
subbuss committed Mar 8, 2012
2 parents 744edda + 9f35c90 commit e041307
Showing 16 changed files with 3,460 additions and 3,352 deletions.
8 changes: 8 additions & 0 deletions bin/generate_parser
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion shared.iml
Original file line number Diff line number Diff line change
@@ -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 />
3 changes: 3 additions & 0 deletions spec/jruby.1.8.mspec
Original file line number Diff line number Diff line change
@@ -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' ]
3 changes: 3 additions & 0 deletions spec/jruby.1.9.mspec
Original file line number Diff line number Diff line change
@@ -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 change: 0 additions & 1 deletion spec/tags/1.9/ruby/core/io/getc_tags.txt

This file was deleted.

4 changes: 2 additions & 2 deletions src/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -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) {
137 changes: 101 additions & 36 deletions src/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
@@ -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);
}
}

4 changes: 2 additions & 2 deletions src/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
@@ -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) {
3 changes: 0 additions & 3 deletions src/org/jruby/RubyThread.java
Original file line number Diff line number Diff line change
@@ -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);
10 changes: 1 addition & 9 deletions src/org/jruby/compiler/ir/IRScope.java
Original file line number Diff line number Diff line change
@@ -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 List<BasicBlock> buildLinearization() {

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 */
2 changes: 2 additions & 0 deletions src/org/jruby/compiler/ir/compiler_pass/CompilerPass.java
Original file line number Diff line number Diff line change
@@ -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;
}
}

17 changes: 15 additions & 2 deletions src/org/jruby/compiler/ir/compiler_pass/DominatorTreeBuilder.java
Original file line number Diff line number Diff line change
@@ -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());
}
13 changes: 12 additions & 1 deletion src/org/jruby/compiler/ir/compiler_pass/LinearizeCFG.java
Original file line number Diff line number Diff line change
@@ -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();
415 changes: 207 additions & 208 deletions src/org/jruby/parser/Ruby19Parser.java

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/org/jruby/parser/Ruby19Parser.y
Original file line number Diff line number Diff line change
@@ -1377,7 +1377,7 @@ block_param_def : tPIPE opt_bv_decl tPIPE {
opt_bv_decl : opt_nl {
$$ = null;
}
| opt_nl ';' bv_dels opt_nl {
| opt_nl ';' bv_decls opt_nl {
$$ = null;
}

6,188 changes: 3,102 additions & 3,086 deletions src/org/jruby/parser/Ruby19YyTables.java

Large diffs are not rendered by default.

0 comments on commit e041307

Please sign in to comment.