-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
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 truffle-head
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
- 9.1.0.0
- 9.0.5.0
Showing
42 changed files
with
2,901 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
fails:String#unpack with format 'M' calls #to_str to coerce the directives string | ||
fails:String#unpack with format 'm' calls #to_str to coerce the directives string | ||
fails:String#unpack with format 'M' ignores the count or '*' modifier and decodes the entire string | ||
fails:String#unpack with format 'm' ignores the count or '*' modifier and decodes the entire string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
fails:String#unpack with format 'Z' calls #to_str to coerce the directives string | ||
fails:String#unpack with format 'Z' stops decoding at NULL bytes when passed the '*' modifier | ||
fails:String#unpack with format 'Z' decodes the number of bytes specified by the count modifier and truncates the decoded string at the first NULL byte |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
truffle/src/main/java/org/jruby/truffle/format/nodes/UnpackRootNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; | ||
import com.oracle.truffle.api.frame.FrameSlotTypeException; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.nodes.RootNode; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.format.runtime.PackEncoding; | ||
import org.jruby.truffle.format.runtime.PackFrameDescriptor; | ||
import org.jruby.truffle.format.runtime.PackResult; | ||
import org.jruby.truffle.runtime.RubyLanguage; | ||
import org.jruby.truffle.runtime.array.ArrayUtils; | ||
|
||
public class UnpackRootNode extends RootNode { | ||
|
||
private final String description; | ||
private final PackEncoding encoding; | ||
|
||
@Child private PackNode child; | ||
|
||
@CompilationFinal private int expectedLength = ArrayUtils.capacity(0, 0); | ||
|
||
public UnpackRootNode(String description, PackEncoding encoding, PackNode child) { | ||
super(RubyLanguage.class, SourceSection.createUnavailable("unpack", description), PackFrameDescriptor.FRAME_DESCRIPTOR); | ||
this.description = description; | ||
this.encoding = encoding; | ||
this.child = child; | ||
} | ||
|
||
@Override | ||
public Object execute(VirtualFrame frame) { | ||
frame.setObject(PackFrameDescriptor.SOURCE_SLOT, frame.getArguments()[0]); | ||
frame.setInt(PackFrameDescriptor.SOURCE_LENGTH_SLOT, (int) frame.getArguments()[1]); | ||
frame.setInt(PackFrameDescriptor.SOURCE_POSITION_SLOT, 0); | ||
frame.setObject(PackFrameDescriptor.OUTPUT_SLOT, new Object[expectedLength]); | ||
frame.setInt(PackFrameDescriptor.OUTPUT_POSITION_SLOT, 0); | ||
frame.setBoolean(PackFrameDescriptor.TAINT_SLOT, false); | ||
|
||
child.execute(frame); | ||
|
||
final int outputLength; | ||
|
||
try { | ||
outputLength = frame.getInt(PackFrameDescriptor.OUTPUT_POSITION_SLOT); | ||
} catch (FrameSlotTypeException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
|
||
if (outputLength > expectedLength) { | ||
CompilerDirectives.transferToInterpreterAndInvalidate(); | ||
expectedLength = ArrayUtils.capacity(expectedLength, outputLength); | ||
} | ||
|
||
final Object[] output; | ||
|
||
try { | ||
output = (Object[]) frame.getObject(PackFrameDescriptor.OUTPUT_SLOT); | ||
} catch (FrameSlotTypeException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
|
||
final boolean taint; | ||
|
||
try { | ||
taint = frame.getBoolean(PackFrameDescriptor.TAINT_SLOT); | ||
} catch (FrameSlotTypeException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
|
||
return new PackResult(output, outputLength, taint, encoding); | ||
} | ||
|
||
@Override | ||
public boolean isCloningAllowed() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return description; | ||
} | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
truffle/src/main/java/org/jruby/truffle/format/nodes/control/AtUnpackNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.control; | ||
|
||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.exceptions.OutsideOfStringException; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
public class AtUnpackNode extends PackNode { | ||
|
||
private final int position; | ||
|
||
public AtUnpackNode(RubyContext context, int position) { | ||
super(context); | ||
this.position = position; | ||
} | ||
|
||
@Override | ||
public Object execute(VirtualFrame frame) { | ||
if (position > getSourceLength(frame)) { | ||
throw new OutsideOfStringException(); | ||
} | ||
|
||
setSourcePosition(frame, position); | ||
|
||
return null; | ||
} | ||
|
||
} |
55 changes: 55 additions & 0 deletions
55
truffle/src/main/java/org/jruby/truffle/format/nodes/control/BackUnpackNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.control; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.exceptions.OutsideOfStringException; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
public class BackUnpackNode extends PackNode { | ||
|
||
private boolean star; | ||
|
||
public BackUnpackNode(RubyContext context, boolean star) { | ||
super(context); | ||
this.star = star; | ||
} | ||
|
||
@Override | ||
public Object execute(VirtualFrame frame) { | ||
final int position = getSourcePosition(frame); | ||
|
||
if (star) { | ||
final int remaining = getSourceLength(frame) - position; | ||
|
||
final int target = position - remaining; | ||
|
||
if (target < 0) { | ||
CompilerDirectives.transferToInterpreter(); | ||
throw new OutsideOfStringException(); | ||
} | ||
|
||
setSourcePosition(frame, target); | ||
} else { | ||
if (position == 0) { | ||
CompilerDirectives.transferToInterpreter(); | ||
throw new OutsideOfStringException(); | ||
} | ||
|
||
setSourcePosition(frame, position - 1); | ||
} | ||
|
||
|
||
return null; | ||
} | ||
|
||
} |
44 changes: 44 additions & 0 deletions
44
truffle/src/main/java/org/jruby/truffle/format/nodes/control/ForwardUnpackNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.control; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.exceptions.OutsideOfStringException; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
public class ForwardUnpackNode extends PackNode { | ||
|
||
private boolean toEnd; | ||
|
||
public ForwardUnpackNode(RubyContext context, boolean toEnd) { | ||
super(context); | ||
this.toEnd = toEnd; | ||
} | ||
|
||
@Override | ||
public Object execute(VirtualFrame frame) { | ||
if (toEnd) { | ||
setSourcePosition(frame, getSourceLength(frame)); | ||
} else { | ||
final int position = getSourcePosition(frame); | ||
|
||
if (position + 1 > getSourceLength(frame)) { | ||
throw new OutsideOfStringException(); | ||
} | ||
|
||
setSourcePosition(frame, getSourcePosition(frame) + 1); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
} |
46 changes: 46 additions & 0 deletions
46
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeByteNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = PackNode.class), | ||
}) | ||
public abstract class DecodeByteNode extends PackNode { | ||
|
||
public boolean signed; | ||
|
||
public DecodeByteNode(RubyContext context, boolean signed) { | ||
super(context); | ||
this.signed = signed; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public int decode(VirtualFrame frame, byte value) { | ||
if (signed) { | ||
return value; | ||
} else { | ||
return value & 0xff; | ||
} | ||
} | ||
|
||
} |
45 changes: 45 additions & 0 deletions
45
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeFloat32Node.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = PackNode.class), | ||
}) | ||
public abstract class DecodeFloat32Node extends PackNode { | ||
|
||
public DecodeFloat32Node(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue decode(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public float decode(VirtualFrame frame, int value) { | ||
return Float.intBitsToFloat(value); | ||
} | ||
|
||
} |
48 changes: 48 additions & 0 deletions
48
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeFloat64Node.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = PackNode.class), | ||
}) | ||
public abstract class DecodeFloat64Node extends PackNode { | ||
|
||
public DecodeFloat64Node(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue decode(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public double decode(VirtualFrame frame, long value) { | ||
return Double.longBitsToDouble(value); | ||
} | ||
|
||
} |
50 changes: 50 additions & 0 deletions
50
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeInteger16BigNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "bytes", type = PackNode.class), | ||
}) | ||
public abstract class DecodeInteger16BigNode extends PackNode { | ||
|
||
public DecodeInteger16BigNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue decode(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public short decode(VirtualFrame frame, byte[] bytes) { | ||
final ByteBuffer buffer = ByteBuffer.wrap(bytes); | ||
buffer.order(ByteOrder.BIG_ENDIAN); | ||
return buffer.getShort(); | ||
} | ||
|
||
} |
53 changes: 53 additions & 0 deletions
53
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeInteger16LittleNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode; | ||
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "bytes", type = PackNode.class), | ||
}) | ||
public abstract class DecodeInteger16LittleNode extends PackNode { | ||
|
||
public DecodeInteger16LittleNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue decode(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public short decode(VirtualFrame frame, byte[] bytes) { | ||
final ByteBuffer buffer = ByteBuffer.wrap(bytes); | ||
buffer.order(ByteOrder.LITTLE_ENDIAN); | ||
return buffer.getShort(); | ||
} | ||
|
||
} |
50 changes: 50 additions & 0 deletions
50
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeInteger32BigNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "bytes", type = PackNode.class), | ||
}) | ||
public abstract class DecodeInteger32BigNode extends PackNode { | ||
|
||
public DecodeInteger32BigNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue decode(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public int decode(VirtualFrame frame, byte[] bytes) { | ||
final ByteBuffer buffer = ByteBuffer.wrap(bytes); | ||
buffer.order(ByteOrder.BIG_ENDIAN); | ||
return buffer.getInt(); | ||
} | ||
|
||
} |
50 changes: 50 additions & 0 deletions
50
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeInteger32LittleNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "bytes", type = PackNode.class), | ||
}) | ||
public abstract class DecodeInteger32LittleNode extends PackNode { | ||
|
||
public DecodeInteger32LittleNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue decode(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public int decode(VirtualFrame frame, byte[] bytes) { | ||
final ByteBuffer buffer = ByteBuffer.wrap(bytes); | ||
buffer.order(ByteOrder.LITTLE_ENDIAN); | ||
return buffer.getInt(); | ||
} | ||
|
||
} |
50 changes: 50 additions & 0 deletions
50
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeInteger64BigNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "bytes", type = PackNode.class), | ||
}) | ||
public abstract class DecodeInteger64BigNode extends PackNode { | ||
|
||
public DecodeInteger64BigNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue decode(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public long decode(VirtualFrame frame, byte[] bytes) { | ||
final ByteBuffer buffer = ByteBuffer.wrap(bytes); | ||
buffer.order(ByteOrder.BIG_ENDIAN); | ||
return buffer.getLong(); | ||
} | ||
|
||
} |
50 changes: 50 additions & 0 deletions
50
truffle/src/main/java/org/jruby/truffle/format/nodes/decode/DecodeInteger64LittleNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.decode; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "bytes", type = PackNode.class), | ||
}) | ||
public abstract class DecodeInteger64LittleNode extends PackNode { | ||
|
||
public DecodeInteger64LittleNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue decode(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject decode(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public long decode(VirtualFrame frame, byte[] bytes) { | ||
final ByteBuffer buffer = ByteBuffer.wrap(bytes); | ||
buffer.order(ByteOrder.LITTLE_ENDIAN); | ||
return buffer.getLong(); | ||
} | ||
|
||
} |
131 changes: 131 additions & 0 deletions
131
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadBERNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jcodings.Encoding; | ||
import org.jruby.RubyBignum; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.nodes.core.FixnumOrBignumNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
import org.jruby.util.ByteList; | ||
import org.jruby.util.StringSupport; | ||
|
||
import java.math.BigInteger; | ||
import java.nio.ByteBuffer; | ||
|
||
/** | ||
* Read a string that contains UU-encoded data and write as actual binary | ||
* data. | ||
*/ | ||
@NodeChildren({ | ||
@NodeChild(value = "source", type = SourceNode.class), | ||
}) | ||
public abstract class ReadBERNode extends PackNode { | ||
|
||
@Child private FixnumOrBignumNode fixnumOrBignumNode; | ||
|
||
private final int length; | ||
private final boolean ignoreStar; | ||
|
||
public ReadBERNode(RubyContext context, int length, boolean ignoreStar) { | ||
super(context); | ||
fixnumOrBignumNode = FixnumOrBignumNode.create(context, null); | ||
this.length = length; | ||
this.ignoreStar = ignoreStar; | ||
} | ||
|
||
@Specialization | ||
protected Object encode(VirtualFrame frame, byte[] source) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
// TODO CS 28-Dec-15 should write our own optimizable version of BER | ||
|
||
/* | ||
* Copied from JRuby's Pack class. | ||
* | ||
* **** BEGIN LICENSE BLOCK ***** | ||
* Version: EPL 1.0/GPL 2.0/LGPL 2.1 | ||
* | ||
* The contents of this file are subject to the Eclipse Public | ||
* License Version 1.0 (the "License"); you may not use this file | ||
* except in compliance with the License. You may obtain a copy of | ||
* the License at http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Software distributed under the License is distributed on an "AS | ||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* rights and limitations under the License. | ||
* | ||
* Copyright (C) 2002-2004 Jan Arne Petersen <jpetersen@uni-bonn.de> | ||
* Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se> | ||
* Copyright (C) 2003-2004 Thomas E Enebo <enebo@acm.org> | ||
* Copyright (C) 2004 Charles O Nutter <headius@headius.com> | ||
* Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de> | ||
* Copyright (C) 2005 Derek Berner <derek.berner@state.nm.us> | ||
* Copyright (C) 2006 Evan Buswell <ebuswell@gmail.com> | ||
* Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com> | ||
* Copyright (C) 2009 Joseph LaFata <joe@quibb.org> | ||
* | ||
* Alternatively, the contents of this file may be used under the terms of | ||
* either of the GNU General Public License Version 2 or later (the "GPL"), | ||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), | ||
* in which case the provisions of the GPL or the LGPL are applicable instead | ||
* of those above. If you wish to allow use of your version of this file only | ||
* under the terms of either the GPL or the LGPL, and not to allow others to | ||
* use your version of this file under the terms of the EPL, indicate your | ||
* decision by deleting the provisions above and replace them with the notice | ||
* and other provisions required by the GPL or the LGPL. If you do not delete | ||
* the provisions above, a recipient may use your version of this file under | ||
* the terms of any one of the EPL, the GPL or the LGPL. | ||
***** END LICENSE BLOCK *****/ | ||
|
||
final ByteBuffer encode = ByteBuffer.wrap(source, getSourcePosition(frame), getSourceLength(frame) - getSourcePosition(frame)); | ||
|
||
long ul = 0; | ||
long ulmask = (0xfe << 56) & 0xffffffff; | ||
BigInteger big128 = BigInteger.valueOf(128); | ||
int pos = encode.position(); | ||
|
||
ul <<= 7; | ||
ul |= encode.get(pos) & 0x7f; | ||
if((encode.get(pos++) & 0x80) == 0) { | ||
setSourcePosition(frame, getSourcePosition(frame) + pos); | ||
return ul; | ||
} else if((ul & ulmask) == 0) { | ||
BigInteger big = BigInteger.valueOf(ul); | ||
while(pos < encode.limit()) { | ||
BigInteger mulResult = big.multiply(big128); | ||
BigInteger v = mulResult.add(BigInteger.valueOf(encode.get(pos) & 0x7f)); | ||
big = v; | ||
if((encode.get(pos++) & 0x80) == 0) { | ||
setSourcePosition(frame, getSourcePosition(frame) + pos); | ||
return fixnumOrBignumNode.fixnumOrBignum(big); | ||
} | ||
} | ||
} | ||
|
||
try { | ||
encode.position(pos); | ||
} catch (IllegalArgumentException e) { | ||
//throw runtime.newArgumentError("in `unpack': poorly encoded input"); | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
} |
177 changes: 177 additions & 0 deletions
177
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadBase64StringNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
/* | ||
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jcodings.Encoding; | ||
import org.jcodings.specific.ASCIIEncoding; | ||
import org.jruby.RubyString; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.format.runtime.exceptions.FormatException; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
import org.jruby.util.ByteList; | ||
import org.jruby.util.Pack; | ||
import org.jruby.util.StringSupport; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = SourceNode.class), | ||
}) | ||
public abstract class ReadBase64StringNode extends PackNode { | ||
|
||
private final int requestedLength; | ||
|
||
public ReadBase64StringNode(RubyContext context, int requestedLength) { | ||
super(context); | ||
this.requestedLength = requestedLength; | ||
} | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, byte[] source) { | ||
// Bit string logic copied from jruby.util.Pack - see copyright and authorship there | ||
|
||
final ByteBuffer encode = ByteBuffer.wrap(source, getSourcePosition(frame), getSourceLength(frame) - getSourcePosition(frame)); | ||
|
||
int occurrences = requestedLength; | ||
|
||
int length = encode.remaining()*3/4; | ||
byte[] lElem = new byte[length]; | ||
int a = -1, b = -1, c = 0, d; | ||
int index = 0; | ||
int s = -1; | ||
|
||
if (occurrences == 0){ | ||
if (encode.remaining()%4 != 0) { | ||
throw new FormatException("invalid base64"); | ||
} | ||
while (encode.hasRemaining() && s != '=') { | ||
a = b = c = -1; | ||
d = -2; | ||
|
||
// obtain a | ||
s = Pack.safeGet(encode); | ||
a = Pack.b64_xtable[s]; | ||
if (a == -1) throw new FormatException("invalid base64"); | ||
|
||
// obtain b | ||
s = Pack.safeGet(encode); | ||
b = Pack.b64_xtable[s]; | ||
if (b == -1) throw new FormatException("invalid base64"); | ||
|
||
// obtain c | ||
s = Pack.safeGet(encode); | ||
c = Pack.b64_xtable[s]; | ||
if (s == '=') { | ||
if (Pack.safeGet(encode) != '=') throw new FormatException("invalid base64"); | ||
break; | ||
} | ||
if (c == -1) throw new FormatException("invalid base64"); | ||
|
||
// obtain d | ||
s = Pack.safeGet(encode); | ||
d = Pack.b64_xtable[s]; | ||
if (s == '=') break; | ||
if (d == -1) throw new FormatException("invalid base64"); | ||
|
||
// calculate based on a, b, c and d | ||
lElem[index++] = (byte)((a << 2 | b >> 4) & 255); | ||
lElem[index++] = (byte)((b << 4 | c >> 2) & 255); | ||
lElem[index++] = (byte)((c << 6 | d) & 255); | ||
} | ||
|
||
if (encode.hasRemaining()) throw new FormatException("invalid base64"); | ||
|
||
if (a != -1 && b != -1) { | ||
if (c == -1 && s == '=') { | ||
if ((b & 15) > 0) throw new FormatException("invalid base64"); | ||
lElem[index++] = (byte)((a << 2 | b >> 4) & 255); | ||
} else if(c != -1 && s == '=') { | ||
if ((c & 3) > 0) throw new FormatException("invalid base64"); | ||
lElem[index++] = (byte)((a << 2 | b >> 4) & 255); | ||
lElem[index++] = (byte)((b << 4 | c >> 2) & 255); | ||
} | ||
} | ||
} | ||
else { | ||
|
||
while (encode.hasRemaining()) { | ||
a = b = c = d = -1; | ||
|
||
// obtain a | ||
s = Pack.safeGet(encode); | ||
while (((a = Pack.b64_xtable[s]) == -1) && encode.hasRemaining()) { | ||
s = Pack.safeGet(encode); | ||
} | ||
if (a == -1) break; | ||
|
||
// obtain b | ||
s = Pack.safeGet(encode); | ||
while (((b = Pack.b64_xtable[s]) == -1) && encode.hasRemaining()) { | ||
s = Pack.safeGet(encode); | ||
} | ||
if (b == -1) break; | ||
|
||
// obtain c | ||
s = Pack.safeGet(encode); | ||
while (((c = Pack.b64_xtable[s]) == -1) && encode.hasRemaining()) { | ||
if (s == '=') break; | ||
s = Pack.safeGet(encode); | ||
} | ||
if ((s == '=') || c == -1) { | ||
if (s == '=') { | ||
encode.position(encode.position() - 1); | ||
} | ||
break; | ||
} | ||
|
||
// obtain d | ||
s = Pack.safeGet(encode); | ||
while (((d = Pack.b64_xtable[s]) == -1) && encode.hasRemaining()) { | ||
if (s == '=') break; | ||
s = Pack.safeGet(encode); | ||
} | ||
if ((s == '=') || d == -1) { | ||
if (s == '=') { | ||
encode.position(encode.position() - 1); | ||
} | ||
break; | ||
} | ||
|
||
// calculate based on a, b, c and d | ||
lElem[index++] = (byte)((a << 2 | b >> 4) & 255); | ||
lElem[index++] = (byte)((b << 4 | c >> 2) & 255); | ||
lElem[index++] = (byte)((c << 6 | d) & 255); | ||
} | ||
|
||
if (a != -1 && b != -1) { | ||
if (c == -1 && s == '=') { | ||
lElem[index++] = (byte)((a << 2 | b >> 4) & 255); | ||
} else if(c != -1 && s == '=') { | ||
lElem[index++] = (byte)((a << 2 | b >> 4) & 255); | ||
lElem[index++] = (byte)((b << 4 | c >> 2) & 255); | ||
} | ||
} | ||
} | ||
|
||
final Encoding encoding = Encoding.load("ASCII"); | ||
final ByteList result = new ByteList(lElem, 0, index, encoding, false); | ||
setSourcePosition(frame, encode.position()); | ||
|
||
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), result, StringSupport.CR_UNKNOWN, null); | ||
} | ||
|
||
} |
97 changes: 97 additions & 0 deletions
97
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadBinaryStringNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
import org.jruby.util.ByteList; | ||
import org.jruby.util.StringSupport; | ||
|
||
import java.util.Arrays; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "source", type = SourceNode.class), | ||
}) | ||
public abstract class ReadBinaryStringNode extends PackNode { | ||
|
||
final boolean readToEnd; | ||
final boolean readToNull; | ||
final int count; | ||
final boolean trimTrailingSpaces; | ||
final boolean trimTrailingNulls; | ||
|
||
public ReadBinaryStringNode(RubyContext context, boolean readToEnd, boolean readToNull, int count, boolean trimTrailingSpaces, boolean trimTrailingNulls) { | ||
super(context); | ||
this.readToEnd = readToEnd; | ||
this.readToNull = readToNull; | ||
this.count = count; | ||
this.trimTrailingSpaces = trimTrailingSpaces; | ||
this.trimTrailingNulls = trimTrailingNulls; | ||
} | ||
|
||
@Specialization(guards = "isNull(source)") | ||
public void read(VirtualFrame frame, Object source) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
// Advance will handle the error | ||
advanceSourcePosition(frame, count); | ||
|
||
throw new IllegalStateException(); | ||
} | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, byte[] source) { | ||
final int start = getSourcePosition(frame); | ||
|
||
int length; | ||
ByteList result; | ||
|
||
if (readToEnd) { | ||
length = 0; | ||
|
||
while (start + length < getSourceLength(frame) && (!readToNull || (start + length < getSourceLength(frame) && source[start + length] != 0))) { | ||
length++; | ||
} | ||
} else if (readToNull) { | ||
length = 0; | ||
|
||
while (start + length < getSourceLength(frame) && length < count && (!readToNull || (start + length < getSourceLength(frame) && source[start + length] != 0))) { | ||
length++; | ||
} | ||
} else { | ||
length = count; | ||
|
||
if (start + length >= getSourceLength(frame)) { | ||
length = getSourceLength(frame) - start; | ||
} | ||
} | ||
|
||
int usedLength = length; | ||
|
||
while (usedLength > 0 && ((trimTrailingSpaces && source[start + usedLength - 1] == ' ') || (trimTrailingNulls && source[start + usedLength - 1] == 0))) { | ||
usedLength--; | ||
} | ||
|
||
result = new ByteList(source, start, usedLength, true); | ||
|
||
setSourcePosition(frame, start + length); | ||
|
||
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), result, StringSupport.CR_UNKNOWN, null); | ||
} | ||
|
||
} |
89 changes: 89 additions & 0 deletions
89
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadBitStringNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jcodings.Encoding; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
import org.jruby.util.ByteList; | ||
import org.jruby.util.StringSupport; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = SourceNode.class), | ||
}) | ||
public abstract class ReadBitStringNode extends PackNode { | ||
|
||
private final ByteOrder byteOrder; | ||
private final boolean star; | ||
private final int length; | ||
|
||
public ReadBitStringNode(RubyContext context, ByteOrder byteOrder, boolean star, int length) { | ||
super(context); | ||
this.byteOrder = byteOrder; | ||
this.star = star; | ||
this.length = length; | ||
} | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, byte[] source) { | ||
// Bit string logic copied from jruby.util.Pack - see copyright and authorship there | ||
|
||
final ByteBuffer encode = ByteBuffer.wrap(source, getSourcePosition(frame), getSourceLength(frame) - getSourcePosition(frame)); | ||
|
||
int occurrences = length; | ||
byte[] lElem; | ||
|
||
if (byteOrder == ByteOrder.BIG_ENDIAN) { | ||
if (star || occurrences > encode.remaining() * 8) { | ||
occurrences = encode.remaining() * 8; | ||
} | ||
int bits = 0; | ||
lElem = new byte[occurrences]; | ||
for (int lCurByte = 0; lCurByte < occurrences; lCurByte++) { | ||
if ((lCurByte & 7) != 0) { | ||
bits <<= 1; | ||
} else { | ||
bits = encode.get(); | ||
} | ||
lElem[lCurByte] = (bits & 128) != 0 ? (byte)'1' : (byte)'0'; | ||
} | ||
} else { | ||
if (star || occurrences > encode.remaining() * 8) { | ||
occurrences = encode.remaining() * 8; | ||
} | ||
int bits = 0; | ||
lElem = new byte[occurrences]; | ||
for (int lCurByte = 0; lCurByte < occurrences; lCurByte++) { | ||
if ((lCurByte & 7) != 0) { | ||
bits >>>= 1; | ||
} else { | ||
bits = encode.get(); | ||
} | ||
lElem[lCurByte] = (bits & 1) != 0 ? (byte)'1' : (byte)'0'; | ||
} | ||
} | ||
|
||
final Encoding encoding = Encoding.load("ASCII"); | ||
final ByteList result = new ByteList(lElem, encoding, false); | ||
setSourcePosition(frame, encode.position()); | ||
|
||
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), result, StringSupport.CR_UNKNOWN, null); | ||
} | ||
|
||
} |
53 changes: 53 additions & 0 deletions
53
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadByteNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.util.Arrays; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "source", type = SourceNode.class), | ||
}) | ||
public abstract class ReadByteNode extends PackNode { | ||
|
||
public ReadByteNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization(guards = "isNull(source)") | ||
public void read(VirtualFrame frame, Object source) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
// Advance will handle the error | ||
advanceSourcePosition(frame, 1); | ||
|
||
throw new IllegalStateException(); | ||
} | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, byte[] source) { | ||
int index = advanceSourcePositionNoThrow(frame); | ||
|
||
if (index == -1) { | ||
return getContext().getCoreLibrary().getNilObject(); | ||
} | ||
|
||
return source[index]; | ||
} | ||
|
||
} |
63 changes: 63 additions & 0 deletions
63
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadBytesNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.util.Arrays; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "source", type = SourceNode.class), | ||
}) | ||
public abstract class ReadBytesNode extends PackNode { | ||
|
||
private final int count; | ||
private final boolean consumePartial; | ||
|
||
public ReadBytesNode(RubyContext context, int count, boolean consumePartial) { | ||
super(context); | ||
this.count = count; | ||
this.consumePartial = consumePartial; | ||
} | ||
|
||
@Specialization(guards = "isNull(source)") | ||
public void read(VirtualFrame frame, Object source) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
// Advance will handle the error | ||
advanceSourcePosition(frame, count); | ||
|
||
throw new IllegalStateException(); | ||
} | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, byte[] source) { | ||
int index = advanceSourcePositionNoThrow(frame, count, consumePartial); | ||
|
||
if (index == -1) { | ||
if (consumePartial) { | ||
return MissingValue.INSTANCE; | ||
} else { | ||
return getContext().getCoreLibrary().getNilObject(); | ||
} | ||
} | ||
|
||
return Arrays.copyOfRange(source, index, index + count); | ||
} | ||
|
||
} |
90 changes: 90 additions & 0 deletions
90
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadHexStringNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jcodings.Encoding; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
import org.jruby.util.ByteList; | ||
import org.jruby.util.Pack; | ||
import org.jruby.util.StringSupport; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = SourceNode.class), | ||
}) | ||
public abstract class ReadHexStringNode extends PackNode { | ||
|
||
private final ByteOrder byteOrder; | ||
private final boolean star; | ||
private final int length; | ||
|
||
public ReadHexStringNode(RubyContext context, ByteOrder byteOrder, boolean star, int length) { | ||
super(context); | ||
this.byteOrder = byteOrder; | ||
this.star = star; | ||
this.length = length; | ||
} | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, byte[] source) { | ||
// Bit string logic copied from jruby.util.Pack - see copyright and authorship there | ||
|
||
final ByteBuffer encode = ByteBuffer.wrap(source, getSourcePosition(frame), getSourceLength(frame) - getSourcePosition(frame)); | ||
|
||
int occurrences = length; | ||
byte[] lElem; | ||
|
||
if (byteOrder == ByteOrder.BIG_ENDIAN) { | ||
if (star || occurrences > encode.remaining() * 2) { | ||
occurrences = encode.remaining() * 2; | ||
} | ||
int bits = 0; | ||
lElem = new byte[occurrences]; | ||
for (int lCurByte = 0; lCurByte < occurrences; lCurByte++) { | ||
if ((lCurByte & 1) != 0) { | ||
bits <<= 4; | ||
} else { | ||
bits = encode.get(); | ||
} | ||
lElem[lCurByte] = Pack.sHexDigits[(bits >>> 4) & 15]; | ||
} | ||
} else { | ||
if (star || occurrences > encode.remaining() * 2) { | ||
occurrences = encode.remaining() * 2; | ||
} | ||
int bits = 0; | ||
lElem = new byte[occurrences]; | ||
for (int lCurByte = 0; lCurByte < occurrences; lCurByte++) { | ||
if ((lCurByte & 1) != 0) { | ||
bits >>>= 4; | ||
} else { | ||
bits = encode.get(); | ||
} | ||
lElem[lCurByte] = Pack.sHexDigits[bits & 15]; | ||
} | ||
} | ||
|
||
final Encoding encoding = Encoding.load("ASCII"); | ||
final ByteList result = new ByteList(lElem, encoding, false); | ||
setSourcePosition(frame, encode.position()); | ||
|
||
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), result, StringSupport.CR_UNKNOWN, null); | ||
} | ||
|
||
} |
86 changes: 86 additions & 0 deletions
86
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadMIMEStringNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jcodings.Encoding; | ||
import org.jruby.RubyString; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
import org.jruby.util.ByteList; | ||
import org.jruby.util.Pack; | ||
import org.jruby.util.StringSupport; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = SourceNode.class), | ||
}) | ||
public abstract class ReadMIMEStringNode extends PackNode { | ||
|
||
private final int length; | ||
|
||
public ReadMIMEStringNode(RubyContext context, int length) { | ||
super(context); | ||
this.length = length; | ||
} | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, byte[] source) { | ||
// Bit string logic copied from jruby.util.Pack - see copyright and authorship there | ||
|
||
final ByteBuffer encode = ByteBuffer.wrap(source, getSourcePosition(frame), getSourceLength(frame) - getSourcePosition(frame)); | ||
|
||
int occurrences = length; | ||
|
||
byte[] lElem = new byte[Math.max(encode.remaining(),0)]; | ||
int index = 0; | ||
for(;;) { | ||
if (!encode.hasRemaining()) break; | ||
int c = Pack.safeGet(encode); | ||
if (c != '=') { | ||
lElem[index++] = (byte)c; | ||
} else { | ||
if (!encode.hasRemaining()) break; | ||
encode.mark(); | ||
int c1 = Pack.safeGet(encode); | ||
if (c1 == '\n' || (c1 == '\r' && (c1 = Pack.safeGet(encode)) == '\n')) continue; | ||
int d1 = Character.digit(c1, 16); | ||
if (d1 == -1) { | ||
encode.reset(); | ||
break; | ||
} | ||
encode.mark(); | ||
if (!encode.hasRemaining()) break; | ||
int c2 = Pack.safeGet(encode); | ||
int d2 = Character.digit(c2, 16); | ||
if (d2 == -1) { | ||
encode.reset(); | ||
break; | ||
} | ||
byte value = (byte)(d1 << 4 | d2); | ||
lElem[index++] = value; | ||
} | ||
} | ||
|
||
final Encoding encoding = Encoding.load("ASCII"); | ||
final ByteList result = new ByteList(lElem, 0, index, encoding, false); | ||
setSourcePosition(frame, encode.position()); | ||
|
||
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), result, StringSupport.CR_UNKNOWN, null); | ||
} | ||
|
||
} |
97 changes: 97 additions & 0 deletions
97
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadUTF8CharacterNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.nio.ByteBuffer; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "source", type = SourceNode.class), | ||
}) | ||
public abstract class ReadUTF8CharacterNode extends PackNode { | ||
|
||
public ReadUTF8CharacterNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization(guards = "isNull(source)") | ||
public void read(VirtualFrame frame, Object source) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
// Advance will handle the error | ||
advanceSourcePosition(frame, 1); | ||
|
||
throw new IllegalStateException(); | ||
} | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, byte[] source) { | ||
final int index = getSourcePosition(frame); | ||
final int sourceLength = getSourceLength(frame); | ||
|
||
if (index == -1) { | ||
//return getContext().getCoreLibrary().getNilObject(); | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
if (index >= sourceLength) { | ||
return MissingValue.INSTANCE; | ||
} | ||
|
||
long codepoint = source[index] & 0xff; | ||
final int length; | ||
|
||
if (codepoint >> 7 == 0) { | ||
length = 1; | ||
codepoint &= 0b01111111; | ||
} else if (codepoint >> 5 == 0b00000110) { | ||
length = 2; | ||
codepoint &= 0b00011111; | ||
} else if (codepoint >> 4 == 0b00001110) { | ||
length = 3; | ||
codepoint &= 0b00001111; | ||
} else if (codepoint >> 3 == 0b00011110) { | ||
length = 4; | ||
codepoint &= 0b00000111; | ||
} else if (codepoint >> 2 == 0b00111110) { | ||
length = 5; | ||
codepoint &= 0b00000011; | ||
} else if (codepoint >> 1 == 0b01111110) { | ||
length = 6; | ||
codepoint &= 0b00000001; | ||
} else { | ||
// Not UTF-8, so just pass the first byte through | ||
length = 1; | ||
} | ||
|
||
if (index + length > sourceLength) { | ||
return MissingValue.INSTANCE; | ||
} | ||
|
||
for (int n = 1; n < length; n++) { | ||
codepoint <<= 6; | ||
codepoint |= source[index + n] & 0b00111111; | ||
} | ||
|
||
setSourcePosition(frame, index + length); | ||
|
||
return codepoint; | ||
} | ||
|
||
} |
193 changes: 193 additions & 0 deletions
193
truffle/src/main/java/org/jruby/truffle/format/nodes/read/ReadUUStringNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.read; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jcodings.Encoding; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.nodes.SourceNode; | ||
import org.jruby.truffle.format.runtime.exceptions.NoImplicitConversionException; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
import org.jruby.util.ByteList; | ||
import org.jruby.util.Pack; | ||
import org.jruby.util.StringSupport; | ||
|
||
import java.nio.ByteBuffer; | ||
|
||
/** | ||
* Read a string that contains UU-encoded data and write as actual binary | ||
* data. | ||
*/ | ||
@NodeChildren({ | ||
@NodeChild(value = "source", type = SourceNode.class), | ||
}) | ||
public abstract class ReadUUStringNode extends PackNode { | ||
|
||
private final int length; | ||
private final boolean ignoreStar; | ||
|
||
public ReadUUStringNode(RubyContext context, int length, boolean ignoreStar) { | ||
super(context); | ||
this.length = length; | ||
this.ignoreStar = ignoreStar; | ||
} | ||
|
||
/*@Specialization | ||
public Object write(long bytes) { | ||
throw new NoImplicitConversionException(bytes, "String"); | ||
} | ||
@Specialization(guards = "isEmpty(bytes)") | ||
public Object writeEmpty(VirtualFrame frame, ByteList bytes) { | ||
return null; | ||
} | ||
@Specialization(guards = "!isEmpty(bytes)") | ||
public Object write(VirtualFrame frame, ByteList bytes) { | ||
writeBytes(frame, encode(bytes)); | ||
return null; | ||
}*/ | ||
|
||
@Specialization | ||
protected Object encode(VirtualFrame frame, byte[] source) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
// TODO CS 28-Dec-15 should write our own optimizable version of UU | ||
|
||
/* | ||
* Copied from JRuby's Pack class. | ||
* | ||
* **** BEGIN LICENSE BLOCK ***** | ||
* Version: EPL 1.0/GPL 2.0/LGPL 2.1 | ||
* | ||
* The contents of this file are subject to the Eclipse Public | ||
* License Version 1.0 (the "License"); you may not use this file | ||
* except in compliance with the License. You may obtain a copy of | ||
* the License at http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Software distributed under the License is distributed on an "AS | ||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* rights and limitations under the License. | ||
* | ||
* Copyright (C) 2002-2004 Jan Arne Petersen <jpetersen@uni-bonn.de> | ||
* Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se> | ||
* Copyright (C) 2003-2004 Thomas E Enebo <enebo@acm.org> | ||
* Copyright (C) 2004 Charles O Nutter <headius@headius.com> | ||
* Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de> | ||
* Copyright (C) 2005 Derek Berner <derek.berner@state.nm.us> | ||
* Copyright (C) 2006 Evan Buswell <ebuswell@gmail.com> | ||
* Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com> | ||
* Copyright (C) 2009 Joseph LaFata <joe@quibb.org> | ||
* | ||
* Alternatively, the contents of this file may be used under the terms of | ||
* either of the GNU General Public License Version 2 or later (the "GPL"), | ||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), | ||
* in which case the provisions of the GPL or the LGPL are applicable instead | ||
* of those above. If you wish to allow use of your version of this file only | ||
* under the terms of either the GPL or the LGPL, and not to allow others to | ||
* use your version of this file under the terms of the EPL, indicate your | ||
* decision by deleting the provisions above and replace them with the notice | ||
* and other provisions required by the GPL or the LGPL. If you do not delete | ||
* the provisions above, a recipient may use your version of this file under | ||
* the terms of any one of the EPL, the GPL or the LGPL. | ||
***** END LICENSE BLOCK *****/ | ||
|
||
final ByteBuffer encode = ByteBuffer.wrap(source, getSourcePosition(frame), getSourceLength(frame) - getSourcePosition(frame)); | ||
|
||
int length = encode.remaining() * 3 / 4; | ||
byte[] lElem = new byte[length]; | ||
int index = 0; | ||
int s = 0; | ||
int total = 0; | ||
if (length > 0) s = encode.get(); | ||
while (encode.hasRemaining() && s > ' ' && s < 'a') { | ||
int a, b, c, d; | ||
byte[] hunk = new byte[3]; | ||
|
||
int len = (s - ' ') & 077; | ||
s = safeGet(encode); | ||
total += len; | ||
if (total > length) { | ||
len -= total - length; | ||
total = length; | ||
} | ||
|
||
while (len > 0) { | ||
int mlen = len > 3 ? 3 : len; | ||
|
||
if (encode.hasRemaining() && s >= ' ') { | ||
a = (s - ' ') & 077; | ||
s = safeGet(encode); | ||
} else | ||
a = 0; | ||
if (encode.hasRemaining() && s >= ' ') { | ||
b = (s - ' ') & 077; | ||
s = safeGet(encode); | ||
} else | ||
b = 0; | ||
if (encode.hasRemaining() && s >= ' ') { | ||
c = (s - ' ') & 077; | ||
s = safeGet(encode); | ||
} else | ||
c = 0; | ||
if (encode.hasRemaining() && s >= ' ') { | ||
d = (s - ' ') & 077; | ||
s = safeGet(encode); | ||
} else | ||
d = 0; | ||
hunk[0] = (byte)((a << 2 | b >> 4) & 255); | ||
hunk[1] = (byte)((b << 4 | c >> 2) & 255); | ||
hunk[2] = (byte)((c << 6 | d) & 255); | ||
|
||
for (int i = 0; i < mlen; i++) lElem[index++] = hunk[i]; | ||
len -= mlen; | ||
} | ||
if (s == '\r') { | ||
s = safeGet(encode); | ||
} | ||
if (s == '\n') { | ||
s = safeGet(encode); | ||
} | ||
else if (encode.hasRemaining()) { | ||
if (safeGet(encode) == '\n') { | ||
safeGet(encode); // Possible Checksum Byte | ||
} else if (encode.hasRemaining()) { | ||
encode.position(encode.position() - 1); | ||
} | ||
} | ||
} | ||
|
||
final Encoding encoding = Encoding.load("ASCII"); | ||
final ByteList result = new ByteList(lElem, 0, index, encoding, false); | ||
|
||
setSourcePosition(frame, encode.position()); | ||
|
||
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), result, StringSupport.CR_UNKNOWN, null); | ||
} | ||
|
||
private static int safeGet(ByteBuffer encode) { | ||
while (encode.hasRemaining()) { | ||
int got = encode.get() & 0xff; | ||
|
||
if (got != 0) return got; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
} |
82 changes: 82 additions & 0 deletions
82
truffle/src/main/java/org/jruby/truffle/format/nodes/type/AsUnsignedNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.type; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.nodes.core.FixnumOrBignumNode; | ||
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode; | ||
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.math.BigInteger; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = PackNode.class), | ||
}) | ||
public abstract class AsUnsignedNode extends PackNode { | ||
|
||
@Child private FixnumOrBignumNode fixnumOrBignumNode; | ||
|
||
public AsUnsignedNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public MissingValue asUnsigned(VirtualFrame frame, MissingValue missingValue) { | ||
return missingValue; | ||
} | ||
|
||
@Specialization(guards = "isNil(nil)") | ||
public DynamicObject asUnsigned(VirtualFrame frame, DynamicObject nil) { | ||
return nil; | ||
} | ||
|
||
@Specialization | ||
public int asUnsigned(VirtualFrame frame, short value) { | ||
return value & 0xffff; | ||
} | ||
|
||
@Specialization | ||
public long asUnsigned(VirtualFrame frame, int value) { | ||
return value & 0xffffffffL; | ||
} | ||
|
||
@Specialization | ||
public Object asUnsigned(VirtualFrame frame, long value) { | ||
if (fixnumOrBignumNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
fixnumOrBignumNode = insert(FixnumOrBignumNode.create(getContext(), getSourceSection())); | ||
} | ||
|
||
return fixnumOrBignumNode.fixnumOrBignum(asUnsigned(value)); | ||
} | ||
|
||
private static final long UNSIGNED_LONG_MASK = 0x7fffffffffffffffL; | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
private BigInteger asUnsigned(long value) { | ||
BigInteger bigIntegerValue = BigInteger.valueOf(value & UNSIGNED_LONG_MASK); | ||
|
||
if (value < 0) { | ||
bigIntegerValue = bigIntegerValue.setBit(Long.SIZE - 1); | ||
} | ||
|
||
return bigIntegerValue; | ||
} | ||
|
||
|
||
} |
65 changes: 65 additions & 0 deletions
65
truffle/src/main/java/org/jruby/truffle/format/nodes/write/WriteValueNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.nodes.write; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import org.jruby.truffle.format.nodes.PackNode; | ||
import org.jruby.truffle.format.runtime.MissingValue; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import java.util.Arrays; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = PackNode.class), | ||
}) | ||
public abstract class WriteValueNode extends PackNode { | ||
|
||
public WriteValueNode(RubyContext context) { | ||
super(context); | ||
} | ||
|
||
@Specialization | ||
public Object doWrite(VirtualFrame frame, MissingValue value) { | ||
return null; | ||
} | ||
|
||
@Specialization(guards = "!isMissingValue(value)") | ||
public Object doWrite(VirtualFrame frame, Object value) { | ||
Object[] output = ensureCapacity(frame, 1); | ||
final int outputPosition = getOutputPosition(frame); | ||
output[outputPosition] = value; | ||
setOutputPosition(frame, outputPosition + 1); | ||
return null; | ||
} | ||
|
||
private Object[] ensureCapacity(VirtualFrame frame, int length) { | ||
Object[] output = (Object[]) getOutput(frame); | ||
final int outputPosition = getOutputPosition(frame); | ||
|
||
if (outputPosition + length > output.length) { | ||
// If we ran out of output byte[], deoptimize and next time we'll allocate more | ||
|
||
CompilerDirectives.transferToInterpreterAndInvalidate(); | ||
output = Arrays.copyOf(output, (output.length + length) * 2); | ||
setOutput(frame, output); | ||
} | ||
|
||
return output; | ||
} | ||
|
||
protected boolean isMissingValue(Object object) { | ||
return object instanceof MissingValue; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
truffle/src/main/java/org/jruby/truffle/format/parser/UnpackCompiler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.parser; | ||
|
||
import com.oracle.truffle.api.CallTarget; | ||
import com.oracle.truffle.api.Truffle; | ||
import org.antlr.v4.runtime.ANTLRInputStream; | ||
import org.antlr.v4.runtime.CommonTokenStream; | ||
import org.jruby.truffle.format.nodes.PackRootNode; | ||
import org.jruby.truffle.format.nodes.UnpackRootNode; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
import org.jruby.truffle.format.parser.PackLexer; | ||
import org.jruby.truffle.format.parser.PackParser; | ||
|
||
public class UnpackCompiler { | ||
|
||
private final RubyContext context; | ||
private final RubyNode currentNode; | ||
|
||
public UnpackCompiler(RubyContext context, RubyNode currentNode) { | ||
this.context = context; | ||
this.currentNode = currentNode; | ||
} | ||
|
||
public CallTarget compile(String format) { | ||
if (format.length() > 32) { | ||
format = PackCompiler.recoverLoop(format); | ||
} | ||
|
||
final PackErrorListener errorListener = new PackErrorListener(context, currentNode); | ||
|
||
final ANTLRInputStream input = new ANTLRInputStream(format); | ||
|
||
final PackLexer lexer = new PackLexer(input); | ||
lexer.removeErrorListeners(); | ||
lexer.addErrorListener(errorListener); | ||
|
||
final CommonTokenStream tokens = new CommonTokenStream(lexer); | ||
|
||
final PackParser parser = new PackParser(tokens); | ||
|
||
final UnpackTreeBuilder builder = new UnpackTreeBuilder(context, currentNode); | ||
parser.addParseListener(builder); | ||
|
||
parser.removeErrorListeners(); | ||
parser.addErrorListener(errorListener); | ||
|
||
parser.sequence(); | ||
|
||
return Truffle.getRuntime().createCallTarget( | ||
new UnpackRootNode(PackCompiler.describe(format), builder.getEncoding(), builder.getNode())); | ||
} | ||
|
||
} |
595 changes: 595 additions & 0 deletions
595
truffle/src/main/java/org/jruby/truffle/format/parser/UnpackTreeBuilder.java
Large diffs are not rendered by default.
Oops, something went wrong.
19 changes: 19 additions & 0 deletions
19
truffle/src/main/java/org/jruby/truffle/format/runtime/MissingValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.format.runtime; | ||
|
||
public class MissingValue { | ||
|
||
public static MissingValue INSTANCE = new MissingValue(); | ||
|
||
private MissingValue() { | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters