Skip to content

Commit

Permalink
Merge branch 'master' into truffle-head
Browse files Browse the repository at this point in the history
Conflicts:
	core/src/main/java/org/jruby/truffle/runtime/core/RubyBignum.java
	spec/truffle/tags/language/method_tags.txt
  • Loading branch information
chrisseaton committed Dec 12, 2014
2 parents 81a4810 + e47a9da commit 78db904
Show file tree
Hide file tree
Showing 47 changed files with 644 additions and 233 deletions.
46 changes: 0 additions & 46 deletions core/src/main/java/org/jruby/RubyEncoding.java
Expand Up @@ -85,14 +85,6 @@ public static RubyClass createEncodingClass(Ruby runtime) {
private RubyEncoding(Ruby runtime, byte[] name, int p, int end, boolean isDummy) {
this(runtime, new ByteList(name, p, end), null, isDummy);
}

private RubyEncoding(Ruby runtime, byte[] name, boolean isDummy) {
this(runtime, name, 0, name.length, isDummy);
}

private RubyEncoding(Ruby runtime, Encoding encoding) {
this(runtime, new ByteList(encoding.getName()), encoding, false);
}

private RubyEncoding(Ruby runtime, byte[] name, Encoding encoding, boolean isDummy) {
this(runtime, new ByteList(name), encoding, isDummy);
Expand All @@ -119,14 +111,6 @@ public static RubyEncoding newEncoding(Ruby runtime, byte[] name, int p, int end
return new RubyEncoding(runtime, name, p, end, isDummy);
}

public static RubyEncoding newEncoding(Ruby runtime, byte[] name, boolean isDummy) {
return new RubyEncoding(runtime, name, isDummy);
}

public static RubyEncoding newEncoding(Ruby runtime, Encoding encoding) {
return new RubyEncoding(runtime, encoding);
}

public final Encoding getEncoding() {
// TODO: make threadsafe
if (encoding == null) encoding = getRuntime().getEncodingService().loadEncoding(name);
Expand Down Expand Up @@ -535,34 +519,4 @@ public static IRubyObject setDefaultInternal(ThreadContext context, IRubyObject
EncodingUtils.rbEncSetDefaultInternal(context, encoding);
return encoding;
}

@Deprecated
public static IRubyObject getDefaultInternal(IRubyObject recv) {
return getDefaultExternal(recv.getRuntime().getCurrentContext(), recv);
}

@Deprecated
public static IRubyObject setDefaultInternal(IRubyObject recv, IRubyObject encoding) {
return setDefaultExternal(recv.getRuntime().getCurrentContext(), recv, encoding);
}

@Deprecated
public static IRubyObject getDefaultExternal(Ruby runtime) {
return runtime.getEncodingService().getDefaultExternal();
}

@Deprecated
public static IRubyObject getDefaultInternal(Ruby runtime) {
return runtime.getEncodingService().getDefaultInternal();
}

@Deprecated
public static IRubyObject convertEncodingToRubyEncoding(Ruby runtime, Encoding defaultEncoding) {
return runtime.getEncodingService().convertEncodingToRubyEncoding(defaultEncoding);
}

@Deprecated
public static Encoding getEncodingFromObject(Ruby runtime, IRubyObject arg) {
return runtime.getEncodingService().getEncodingFromObject(arg);
}
}
20 changes: 20 additions & 0 deletions core/src/main/java/org/jruby/RubySymbol.java
Expand Up @@ -149,6 +149,15 @@ final ByteList getBytes() {
return symbolBytes;
}

/**
* RubySymbol is created by passing in a String and bytes are extracted from that. We will
* pass in encoding of that string after construction but before use so it does not forget
* what it is.
*/
public void associateEncoding(Encoding encoding) {
symbolBytes.setEncoding(encoding);
}

/** short circuit for Symbol key comparison
*
*/
Expand Down Expand Up @@ -185,6 +194,17 @@ public static RubySymbol newSymbol(Ruby runtime, String name) {
return runtime.getSymbolTable().getSymbol(name);
}

// FIXME: same bytesequences will fight over encoding of the symbol once cached. I think largely
// this will only happen in some ISO_8859_?? encodings making symbols at the same time so it should
// be pretty rare.
public static RubySymbol newSymbol(Ruby runtime, String name, Encoding encoding) {
RubySymbol newSymbol = newSymbol(runtime, name);

newSymbol.associateEncoding(encoding);

return newSymbol;
}

/**
* @see org.jruby.compiler.Constantizable
*/
Expand Down
23 changes: 15 additions & 8 deletions core/src/main/java/org/jruby/RubyThread.java
Expand Up @@ -63,9 +63,12 @@

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;

import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;
import org.jruby.runtime.ClassIndex;
Expand Down Expand Up @@ -1152,7 +1155,9 @@ public synchronized IRubyObject run() {
*/
public boolean sleep(long millis) throws InterruptedException {
assert this == getRuntime().getCurrentContext().getThread();
if (executeTask(getContext(), new Object[]{this, millis, 0}, SLEEP_TASK2) >= millis) {
Semaphore sem = new Semaphore(1);
sem.acquire();
if (executeTask(getContext(), new Object[]{sem, millis, 0}, SLEEP_TASK2) >= millis) {
return true;
} else {
return false;
Expand Down Expand Up @@ -1221,20 +1226,22 @@ public void wakeup() {
private static final class SleepTask2 implements Task<Object[], Long> {
@Override
public Long run(ThreadContext context, Object[] data) throws InterruptedException {
Object syncObj = data[0];
long millis = (Long)data[1];
int nanos = (Integer)data[2];
synchronized (syncObj) {
long start = System.currentTimeMillis();
syncObj.wait(millis, nanos);
// TODO: nano handling?
return System.currentTimeMillis() - start;

long start = System.currentTimeMillis();
// TODO: nano handling?
if (millis == 0) {
((Semaphore) data[0]).acquire();
} else {
((Semaphore) data[0]).tryAcquire(millis, TimeUnit.MILLISECONDS);
}
return System.currentTimeMillis() - start;
}

@Override
public void wakeup(RubyThread thread, Object[] data) {
thread.getNativeThread().interrupt();
((Semaphore)data[0]).release();
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ast/KeywordRestArgNode.java
Expand Up @@ -12,7 +12,7 @@ public KeywordRestArgNode(ISourcePosition position, String name, int index) {
}

@Override
public Object accept(NodeVisitor visitor) {
public <T> T accept(NodeVisitor<T> visitor) {
return visitor.visitKeywordRestArgNode(this);
}

Expand Down
15 changes: 12 additions & 3 deletions core/src/main/java/org/jruby/ast/SymbolNode.java
Expand Up @@ -33,20 +33,25 @@
package org.jruby.ast;

import java.util.List;
import org.jcodings.Encoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.ast.types.ILiteralNode;
import org.jruby.ast.types.INameNode;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.util.ByteList;

/**
* Represents a symbol (:symbol_name).
*/
public class SymbolNode extends Node implements ILiteralNode, INameNode {
private String name;
private final String name;
private final Encoding encoding;

public SymbolNode(ISourcePosition position, String name) {
public SymbolNode(ISourcePosition position, ByteList value) {
super(position);
this.name = name;
this.name = value.toString().intern();
encoding = value.lengthEnc() != value.length() ? value.getEncoding() : USASCIIEncoding.INSTANCE;
}

public NodeType getNodeType() {
Expand All @@ -64,6 +69,10 @@ public <T> T accept(NodeVisitor<T> iVisitor) {
public String getName() {
return name;
}

public Encoding getEncoding() {
return encoding;
}

public List<Node> childNodes() {
return EMPTY_LIST;
Expand Down
9 changes: 6 additions & 3 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
@@ -1,5 +1,6 @@
package org.jruby.ir;

import org.jcodings.specific.ASCIIEncoding;
import org.jruby.EvalType;
import org.jruby.Ruby;
import org.jruby.RubyInstanceConfig;
Expand Down Expand Up @@ -1710,14 +1711,16 @@ private IRMethod defineNewMethod(MethodDefNode defNode, IRScope parent, boolean
public Operand buildDefn(MethodDefNode node, IRScope s) { // Instance method
IRMethod method = defineNewMethod(node, s, true);
addInstr(s, new DefineInstanceMethodInstr(method));
return new Symbol(method.getName());
// FIXME: Method name should save encoding
return new Symbol(method.getName(), ASCIIEncoding.INSTANCE);
}

public Operand buildDefs(DefsNode node, IRScope s) { // Class method
Operand container = build(node.getReceiverNode(), s);
IRMethod method = defineNewMethod(node, s, false);
addInstr(s, new DefineClassMethodInstr(container, method));
return new Symbol(method.getName());
// FIXME: Method name should save encoding
return new Symbol(method.getName(), ASCIIEncoding.INSTANCE);
}

protected LocalVariable getArgVariable(IRScope s, String name, int depth) {
Expand Down Expand Up @@ -3293,7 +3296,7 @@ public Operand buildSValue(SValueNode node, IRScope s) {

public Operand buildSymbol(SymbolNode node) {
// SSS: Since symbols are interned objects, no need to copyAndReturnValue(...)
return new Symbol(node.getName());
return new Symbol(node.getName(), node.getEncoding());
}

public Operand buildTrue() {
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/ir/IRClosure.java
@@ -1,5 +1,6 @@
package org.jruby.ir;

import org.jcodings.specific.USASCIIEncoding;
import org.jruby.ir.instructions.*;
import org.jruby.ir.interpreter.ClosureInterpreterContext;
import org.jruby.ir.interpreter.InterpreterContext;
Expand Down Expand Up @@ -191,7 +192,8 @@ public void addInstr(Instr i) {
keywordArgs.add(0, new KeyValuePair<Operand, Operand>(Symbol.KW_REST_ARG_DUMMY, ((ReceiveArgBase) i).getResult()));
} else if (i instanceof ReceiveKeywordArgInstr) {
ReceiveKeywordArgInstr rkai = (ReceiveKeywordArgInstr)i;
keywordArgs.add(new KeyValuePair<Operand, Operand>(new Symbol(rkai.argName), rkai.getResult()));
// FIXME: This lost encoding information when name was converted to string earlier in IRBuilder
keywordArgs.add(new KeyValuePair<Operand, Operand>(new Symbol(rkai.argName, USASCIIEncoding.INSTANCE), rkai.getResult()));
} else if (i instanceof ReceiveRestArgInstr) {
blockArgs.add(new Splat(((ReceiveRestArgInstr)i).getResult()));
} else if (i instanceof ReceiveArgBase) {
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/ir/IRMethod.java
@@ -1,5 +1,6 @@
package org.jruby.ir;

import org.jcodings.specific.USASCIIEncoding;
import org.jruby.internal.runtime.methods.IRMethodArgs;
import org.jruby.ir.instructions.Instr;
import org.jruby.ir.instructions.ReceiveArgBase;
Expand Down Expand Up @@ -69,7 +70,8 @@ public void addInstr(Instr i) {
keywordArgs.add(0, new KeyValuePair<Operand, Operand>(Symbol.KW_REST_ARG_DUMMY, ((ReceiveArgBase) i).getResult()));
} else if (i instanceof ReceiveKeywordArgInstr) {
ReceiveKeywordArgInstr rkai = (ReceiveKeywordArgInstr)i;
keywordArgs.add(new KeyValuePair<Operand, Operand>(new Symbol(rkai.argName), rkai.getResult()));
// FIXME: This lost encoding information when name was converted to string earlier in IRBuilder
keywordArgs.add(new KeyValuePair<Operand, Operand>(new Symbol(rkai.argName, USASCIIEncoding.INSTANCE), rkai.getResult()));
} else if (i instanceof ReceiveRestArgInstr) {
callArgs.add(new Splat(((ReceiveRestArgInstr)i).getResult(), true));
} else if (i instanceof ReceiveArgBase) {
Expand Down
@@ -1,5 +1,6 @@
package org.jruby.ir.instructions;

import org.jcodings.specific.USASCIIEncoding;
import org.jruby.RubyModule;
import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
Expand All @@ -20,7 +21,8 @@ public class ConstMissingInstr extends CallInstr implements ResultInstr, FixedAr
private final String missingConst;

public ConstMissingInstr(Variable result, Operand currentModule, String missingConst) {
super(Operation.CONST_MISSING, CallType.FUNCTIONAL, result, new MethAddr("const_missing"), currentModule, new Operand[]{new Symbol(missingConst)}, null);
// FIXME: Missing encoding knowledge of the constant name.
super(Operation.CONST_MISSING, CallType.FUNCTIONAL, result, new MethAddr("const_missing"), currentModule, new Operand[]{new Symbol(missingConst, USASCIIEncoding.INSTANCE)}, null);

this.missingConst = missingConst;
}
Expand Down
17 changes: 14 additions & 3 deletions core/src/main/java/org/jruby/ir/operands/Symbol.java
@@ -1,26 +1,37 @@
package org.jruby.ir.operands;

import org.jcodings.Encoding;
import org.jcodings.specific.ASCIIEncoding;
import org.jruby.RubySymbol;
import org.jruby.ir.IRVisitor;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

public class Symbol extends Reference {
public static final Symbol KW_REST_ARG_DUMMY = new Symbol("");
public static final Symbol KW_REST_ARG_DUMMY = new Symbol("", ASCIIEncoding.INSTANCE);

public Symbol(String name) {
private final Encoding encoding;

public Symbol(String name, Encoding encoding) {
super(OperandType.SYMBOL, name);

this.encoding = encoding;
}

@Override
public boolean canCopyPropagate() {
return true;
}

public Encoding getEncoding() {
return encoding;
}

@Override
public Object retrieve(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
return context.runtime.newSymbol(getName());
return RubySymbol.newSymbol(context.runtime, getName(), encoding);
}

@Override
Expand Down
@@ -1,6 +1,7 @@
package org.jruby.ir.persistence;

import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.RubyInstanceConfig;
import org.jruby.ir.IRClosure;
import org.jruby.ir.IRManager;
Expand Down Expand Up @@ -57,7 +58,8 @@ public Operand decode(OperandType type) {
case STANDARD_ERROR: return new StandardError();
case STRING_LITERAL: return new StringLiteral(d.decodeString());
case SVALUE: return new SValue(d.decodeOperand());
case SYMBOL: return new Symbol(d.decodeString());
// FIXME: This is broken since there is no encode/decode for encoding
case SYMBOL: return new Symbol(d.decodeString(), USASCIIEncoding.INSTANCE);
case TEMPORARY_VARIABLE: return decodeTemporaryVariable();
case UNBOXED_BOOLEAN: return new UnboxedBoolean(d.decodeBoolean());
case UNBOXED_FIXNUM: return new UnboxedFixnum(d.decodeLong());
Expand Down
8 changes: 6 additions & 2 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Expand Up @@ -971,8 +971,12 @@ public static RubyRegexp constructRubyRegexp(ThreadContext context, RubyString p

// Used by JIT
public static RubyEncoding retrieveEncoding(ThreadContext context, String name) {
Encoding encoding = context.runtime.getEncodingService().findEncodingOrAliasEntry(name.getBytes()).getEncoding();
return context.runtime.getEncodingService().getEncoding(encoding);
return context.runtime.getEncodingService().getEncoding(retrieveJCodingsEncoding(context, name));
}

// Used by JIT
public static Encoding retrieveJCodingsEncoding(ThreadContext context, String name) {
return context.runtime.getEncodingService().findEncodingOrAliasEntry(name.getBytes()).getEncoding();
}

// Used by JIT
Expand Down
Expand Up @@ -6,20 +6,17 @@

import com.headius.invokebinder.Signature;
import org.jcodings.Encoding;
import org.jruby.*;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.compiler.impl.SkinnyMethodAdapter;
import org.jruby.ir.operands.UndefinedValue;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.JavaNameMangler;
import org.jruby.util.RegexpOptions;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;

Expand Down Expand Up @@ -249,7 +246,7 @@ public org.objectweb.asm.Label newLabel() {
*
* @param sym the symbol's string identifier
*/
public abstract void pushSymbol(String sym);
public abstract void pushSymbol(String sym, Encoding encoding);

/**
* Push the JRuby runtime on the stack.
Expand Down

0 comments on commit 78db904

Please sign in to comment.