Skip to content

Commit

Permalink
First prototype of flatbuffer-based persistence.
Browse files Browse the repository at this point in the history
This prototype obviously isn't including everything needed to
fully interpret or reconstitute the full scope, but it does
express structure. FlatIRWriter contains a main that persists a
simple script and then accesses that persisted IR directly from
a memory-mapped buffer. If the back-and-forth through the
flatbuffer does not introduce too much overhead, this should mean
we can start to explore interpreting directly from disk, without
any pass to physically construct all IR objects right away. We
will be able to start interpreting immediately upon opening the
persisted file, and then lazily stand up the richer structures
needed for full interp and JIT.
headius committed Jun 7, 2016
1 parent e8cdd5e commit ecdf4fd
Showing 12 changed files with 414 additions and 13 deletions.
3 changes: 3 additions & 0 deletions core/pom.rb
Original file line number Diff line number Diff line change
@@ -79,6 +79,9 @@
jar 'org.slf4j:slf4j-api:1.7.12', :scope => 'provided', :optional => true
jar 'org.slf4j:slf4j-simple:1.7.12', :scope => 'test'

# Flatbuffers pushed to maven by David Moten
jar 'com.github.davidmoten:flatbuffers-java:1.3.0.1'

plugin_management do
plugin( 'org.eclipse.m2e:lifecycle-mapping:1.0.0',
'lifecycleMappingMetadata' => {
5 changes: 5 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -276,6 +276,11 @@ DO NOT MODIFIY - GENERATED CODE
<version>1.7.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.davidmoten</groupId>
<artifactId>flatbuffers-java</artifactId>
<version>1.3.0.1</version>
</dependency>
</dependencies>
<build>
<defaultGoal>package</defaultGoal>
39 changes: 32 additions & 7 deletions core/src/main/java/org/jruby/ir/Operation.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jruby.ir;

import org.jruby.ir.persistence.flat.OperationFlat;

class OpFlags {
final static int f_has_side_effect = 0x00001; // Used by analyses
final static int f_can_raise_exception = 0x00002; // Used by analyses
@@ -42,7 +44,7 @@ public enum Operation {
B_FALSE(OpFlags.f_is_jump_or_branch),

/** argument receive in methods and blocks **/
RECV_SELF(0),
RECV_SELF(0, OperationFlat.RECEIVE_SELF),
RECV_PRE_REQD_ARG(OpFlags.f_is_arg_receive),
RECV_POST_REQD_ARG(OpFlags.f_is_arg_receive),
RECV_KW_ARG(OpFlags.f_is_arg_receive),
@@ -55,7 +57,7 @@ public enum Operation {

/** Instruction to reify an passed-in block to a Proc for def foo(&b) */
REIFY_CLOSURE(0),
LOAD_FRAME_CLOSURE(0),
LOAD_FRAME_CLOSURE(0, OperationFlat.LOAD_FRAME_CLOSURE),

/* By default, call instructions cannot be deleted even if their results
* aren't used by anyone unless we know more about what the call is,
@@ -74,7 +76,7 @@ public enum Operation {
/* specialized calls */
CALL_1F(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_1D(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_1O(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_1O(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception, OperationFlat.CALL_1_OBJ),
CALL_1OB(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
CALL_0O(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
NORESULT_CALL_1O(OpFlags.f_has_side_effect | OpFlags.f_is_call | OpFlags.f_can_raise_exception),
@@ -88,7 +90,7 @@ public enum Operation {
YIELD(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),

/** returns -- returns unwind stack, etc. */
RETURN(OpFlags.f_has_side_effect | OpFlags.f_is_return),
RETURN(OpFlags.f_has_side_effect | OpFlags.f_is_return, OperationFlat.RETURN),
/* These two insructions use exceptions to exit closures
* BREAK is a return because it can only be used within closures
* and the net result is to return from the closure. */
@@ -138,7 +140,7 @@ public enum Operation {
PUT_FIELD(OpFlags.f_is_store | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),

/** debugging ops **/
LINE_NUM(OpFlags.f_is_book_keeping_op | OpFlags.f_is_debug_op),
LINE_NUM(OpFlags.f_is_book_keeping_op | OpFlags.f_is_debug_op, OperationFlat.LINE_NUMBER),
TRACE(OpFlags.f_is_book_keeping_op | OpFlags.f_is_debug_op | OpFlags.f_has_side_effect),

/** JRuby-impl instructions **/
@@ -156,7 +158,7 @@ public enum Operation {
CHECK_ARITY(OpFlags.f_is_book_keeping_op | OpFlags.f_can_raise_exception),
CHECK_FOR_LJE(OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception),
CLASS_VAR_MODULE(0),
COPY(0),
COPY(0, OperationFlat.COPY),
GET_ENCODING(0),
MASGN_OPT(0),
MASGN_REQD(0),
@@ -227,10 +229,29 @@ public enum Operation {
PREPARE_NO_BLOCK_ARGS(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect | OpFlags.f_can_raise_exception);

public final OpClass opClass;
private int flags;
private final int flags;
private final short flat;

private static final Operation[] FLAT_MAP = new Operation[Operation.values().length];

static {
for (Operation op : Operation.values()) {
if (op.flat == -1) continue;
FLAT_MAP[op.flat] = op;
}
}

public static Operation flatMap(short flat) {
return FLAT_MAP[flat];
}

Operation(int flags) {
this(flags, (short) -1);
}

Operation(int flags, short flat) {
this.flags = flags;
this.flat = flat;

if (this.isArgReceive()) {
this.opClass = OpClass.ARG_OP;
@@ -251,6 +272,10 @@ public enum Operation {
}
}

public short getFlat() {
return flat;
}

public boolean transfersControl() {
return (flags & (OpFlags.f_is_jump_or_branch | OpFlags.f_is_return | OpFlags.f_is_exception)) > 0;
}
37 changes: 31 additions & 6 deletions core/src/main/java/org/jruby/ir/operands/OperandType.java
Original file line number Diff line number Diff line change
@@ -5,14 +5,16 @@
*/
package org.jruby.ir.operands;

import org.jruby.ir.persistence.flat.OperandTypeFlat;

public enum OperandType {

ARRAY("ary", (byte) 'A'),
AS_STRING("tostr", (byte) 'a'),
BIGNUM("big", (byte) 'B'),
BOOLEAN("bool", (byte) 'b'),
COMPLEX("com", (byte) 'C'),
CURRENT_SCOPE("scope", (byte) 's'),
CURRENT_SCOPE("scope", (byte) 's', OperandTypeFlat.CURRENT_SCOPE),
DYNAMIC_SYMBOL("dsym", (byte) 'd'),
FIXNUM("fix", (byte) 'f'),
FLOAT("flo", (byte) 'F'),
@@ -27,14 +29,14 @@ public enum OperandType {
RANGE("rng", (byte) '.'),
RATIONAL("rat", (byte) 'r'),
REGEXP("reg", (byte) '/'),
SCOPE_MODULE("mod", (byte) '_'),
SELF("self", (byte) 'S'),
SCOPE_MODULE("mod", (byte) '_', OperandTypeFlat.SCOPE_MODULE),
SELF("self", (byte) 'S', OperandTypeFlat.SELF),
SPLAT("splat", (byte) '*'),
STANDARD_ERROR("stderr", (byte) 'E'),
STRING_LITERAL("str", (byte) '\''),
STRING_LITERAL("str", (byte) '\'', OperandTypeFlat.STRING_LITERAL),
SVALUE("sval", (byte) 'V'),
SYMBOL("sym", (byte) ':'),
TEMPORARY_VARIABLE("reg", (byte) 't'),
TEMPORARY_VARIABLE("reg", (byte) 't', OperandTypeFlat.TEMPORARY_VARIABLE),
UNBOXED_BOOLEAN("rawbool", (byte) 'v'),
UNBOXED_FIXNUM("rawfix", (byte) 'j'),
UNBOXED_FLOAT("rawflo", (byte) 'J'),
@@ -49,17 +51,40 @@ public enum OperandType {

private final String shortName;
private final byte coded;
private final byte flat;
private static final OperandType[] byteToOperand = new OperandType[256];

OperandType(String shortName, byte coded) {
private static final OperandType[] FLAT_MAP = new OperandType[OperandType.values().length];

static {
for (OperandType opType : OperandType.values()) {
if (opType.flat == -1) continue;
FLAT_MAP[opType.flat] = opType;
}
}

public static OperandType flatMap(byte flat) {
return FLAT_MAP[flat];
}

OperandType(String shortName, byte coded, byte flat) {
this.shortName = shortName;
this.coded = coded;
this.flat = flat;
}

OperandType(String shortName, byte coded) {
this(shortName, coded, (byte) -1);
}

public byte getCoded() {
return coded;
}

public byte getFlat() {
return flat;
}

@Override
public String toString() {
return name().toLowerCase();
112 changes: 112 additions & 0 deletions core/src/main/java/org/jruby/ir/persistence/flat/FlatIRWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package org.jruby.ir.persistence.flat;

import com.google.flatbuffers.FlatBufferBuilder;
import org.jruby.ParseResult;
import org.jruby.Ruby;
import org.jruby.ast.RootNode;
import org.jruby.ir.IRBuilder;
import org.jruby.ir.IRScope;
import org.jruby.ir.IRScriptBody;
import org.jruby.ir.Operation;
import org.jruby.ir.instructions.Instr;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.OperandType;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class FlatIRWriter {
public static int createIRScopeFlat(FlatBufferBuilder builder, IRScope scope) {
int nameOffset = builder.createString(scope.getName());

int[] children = new int[scope.getLexicalScopes().size()];

for (int i = 0; i < scope.getLexicalScopes().size(); i++) {
IRScope child = scope.getLexicalScopes().get(i);

children[i] = createIRScopeFlat(builder, child);
}

int childrenOffset = IRScopeFlat.createLexicalChildrenVector(builder, children);

int closuresOffset = IRScopeFlat.createNestedClosuresVector(builder, new int[0]);

Instr[] instrs = scope.getInterpreterContext().getInstructions();
int[] instrOffsets = new int[instrs.length];

for (int i = 0; i < instrs.length; i++) {
Instr instr = instrs[i];

if (instr.getOperation().getFlat() == -1) throw new RuntimeException("unsupported operation: " + instr.getOperation());

Operand[] operands = instr.getOperands();
int[] operandOffsets = new int[operands.length];

for (int j = 0; j < operands.length; j++) {
Operand operand = operands[j];

if (operand.getOperandType().getFlat() == -1) throw new RuntimeException("unsupported operand: " + operand.getOperandType());

operandOffsets[j] = OperandFlat.createOperandFlat(builder, operand.getOperandType().getFlat());
}

int operandsOffset = InstrFlat.createOperandsVector(builder, operandOffsets);

instrOffsets[i] = InstrFlat.createInstrFlat(builder, instr.getOperation().getFlat(), operandsOffset);
}

int instrsOffset = IRScopeFlat.createInstrsVector(builder, instrOffsets);

return IRScopeFlat.createIRScopeFlat(builder, nameOffset, closuresOffset, childrenOffset, instrsOffset);
}

public static void main(String[] args) {
Ruby runtime = Ruby.newInstance();
byte[] src = "puts 'hello'".getBytes();
ParseResult result = runtime.parseFromMain("blah.rb", new ByteArrayInputStream(src));
InterpreterContext ic = IRBuilder.buildRoot(runtime.getIRManager(), (RootNode) result);
IRScope scope = ic.getScope();
FlatBufferBuilder builder = new FlatBufferBuilder();
int index = createIRScopeFlat(builder, scope);

builder.finish(index);

ByteBuffer buffer = builder.dataBuffer();
int size = buffer.limit();

try {
FileOutputStream out = new FileOutputStream("blah.ir");
out.getChannel().write(buffer);
out.close();
} catch (Throwable t) {
throw new RuntimeException(t);
}

try {
RandomAccessFile file = new RandomAccessFile("blah.ir", "rw");
buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, size);
} catch (Throwable t) {
throw new RuntimeException(t);
}

System.out.println("persisted and loaded:");
IRScopeFlat scopeFlat = IRScopeFlat.getRootAsIRScopeFlat(buffer);
System.out.println("IRScope: " + scopeFlat.name());
System.out.println("Instructions:");
InstrFlat instrFlat = new InstrFlat();
for (int i = 0; i < scopeFlat.instrsLength(); i++) {
scopeFlat.instrs(instrFlat, i);
System.out.println(" " + Operation.flatMap(instrFlat.operation()));
OperandFlat operandFlat = new OperandFlat();
for (int j = 0; j < instrFlat.operandsLength(); j++) {
instrFlat.operands(operandFlat, j);
System.out.println(" " + OperandType.flatMap(operandFlat.operandType()));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// automatically generated, do not modify

package org.jruby.ir.persistence.flat;

import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;

@SuppressWarnings("unused")
public final class IRClosureFlat extends Table {
public static IRClosureFlat getRootAsIRClosureFlat(ByteBuffer _bb) { return getRootAsIRClosureFlat(_bb, new IRClosureFlat()); }
public static IRClosureFlat getRootAsIRClosureFlat(ByteBuffer _bb, IRClosureFlat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public IRClosureFlat __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }

public IRScopeFlat scope() { return scope(new IRScopeFlat()); }
public IRScopeFlat scope(IRScopeFlat obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }

public static int createIRClosureFlat(FlatBufferBuilder builder,
int scopeOffset) {
builder.startObject(1);
IRClosureFlat.addScope(builder, scopeOffset);
return IRClosureFlat.endIRClosureFlat(builder);
}

public static void startIRClosureFlat(FlatBufferBuilder builder) { builder.startObject(1); }
public static void addScope(FlatBufferBuilder builder, int scopeOffset) { builder.addOffset(0, scopeOffset, 0); }
public static int endIRClosureFlat(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
};

58 changes: 58 additions & 0 deletions core/src/main/java/org/jruby/ir/persistence/flat/IRScopeFlat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// automatically generated, do not modify

package org.jruby.ir.persistence.flat;

import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;

@SuppressWarnings("unused")
public final class IRScopeFlat extends Table {
public static IRScopeFlat getRootAsIRScopeFlat(ByteBuffer _bb) { return getRootAsIRScopeFlat(_bb, new IRScopeFlat()); }
public static IRScopeFlat getRootAsIRScopeFlat(ByteBuffer _bb, IRScopeFlat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public IRScopeFlat __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }

public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
public IRClosureFlat nestedClosures(int j) { return nestedClosures(new IRClosureFlat(), j); }
public IRClosureFlat nestedClosures(IRClosureFlat obj, int j) { int o = __offset(6); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
public int nestedClosuresLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; }
public IRScopeFlat lexicalChildren(int j) { return lexicalChildren(new IRScopeFlat(), j); }
public IRScopeFlat lexicalChildren(IRScopeFlat obj, int j) { int o = __offset(8); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
public int lexicalChildrenLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; }
public InstrFlat instrs(int j) { return instrs(new InstrFlat(), j); }
public InstrFlat instrs(InstrFlat obj, int j) { int o = __offset(10); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
public int instrsLength() { int o = __offset(10); return o != 0 ? __vector_len(o) : 0; }

public static int createIRScopeFlat(FlatBufferBuilder builder,
int nameOffset,
int nestedClosuresOffset,
int lexicalChildrenOffset,
int instrsOffset) {
builder.startObject(4);
IRScopeFlat.addInstrs(builder, instrsOffset);
IRScopeFlat.addLexicalChildren(builder, lexicalChildrenOffset);
IRScopeFlat.addNestedClosures(builder, nestedClosuresOffset);
IRScopeFlat.addName(builder, nameOffset);
return IRScopeFlat.endIRScopeFlat(builder);
}

public static void startIRScopeFlat(FlatBufferBuilder builder) { builder.startObject(4); }
public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); }
public static void addNestedClosures(FlatBufferBuilder builder, int nestedClosuresOffset) { builder.addOffset(1, nestedClosuresOffset, 0); }
public static int createNestedClosuresVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
public static void startNestedClosuresVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static void addLexicalChildren(FlatBufferBuilder builder, int lexicalChildrenOffset) { builder.addOffset(2, lexicalChildrenOffset, 0); }
public static int createLexicalChildrenVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
public static void startLexicalChildrenVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static void addInstrs(FlatBufferBuilder builder, int instrsOffset) { builder.addOffset(3, instrsOffset, 0); }
public static int createInstrsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
public static void startInstrsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endIRScopeFlat(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
public static void finishIRScopeFlatBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset); }
};

40 changes: 40 additions & 0 deletions core/src/main/java/org/jruby/ir/persistence/flat/InstrFlat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// automatically generated, do not modify

package org.jruby.ir.persistence.flat;

import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;

@SuppressWarnings("unused")
public final class InstrFlat extends Table {
public static InstrFlat getRootAsInstrFlat(ByteBuffer _bb) { return getRootAsInstrFlat(_bb, new InstrFlat()); }
public static InstrFlat getRootAsInstrFlat(ByteBuffer _bb, InstrFlat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public InstrFlat __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }

public short operation() { int o = __offset(4); return o != 0 ? bb.getShort(o + bb_pos) : 0; }
public OperandFlat operands(int j) { return operands(new OperandFlat(), j); }
public OperandFlat operands(OperandFlat obj, int j) { int o = __offset(6); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
public int operandsLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; }

public static int createInstrFlat(FlatBufferBuilder builder,
short operation,
int operandsOffset) {
builder.startObject(2);
InstrFlat.addOperands(builder, operandsOffset);
InstrFlat.addOperation(builder, operation);
return InstrFlat.endInstrFlat(builder);
}

public static void startInstrFlat(FlatBufferBuilder builder) { builder.startObject(2); }
public static void addOperation(FlatBufferBuilder builder, short operation) { builder.addShort(0, operation, 0); }
public static void addOperands(FlatBufferBuilder builder, int operandsOffset) { builder.addOffset(1, operandsOffset, 0); }
public static int createOperandsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
public static void startOperandsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endInstrFlat(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
};

32 changes: 32 additions & 0 deletions core/src/main/java/org/jruby/ir/persistence/flat/OperandFlat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// automatically generated, do not modify

package org.jruby.ir.persistence.flat;

import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;

@SuppressWarnings("unused")
public final class OperandFlat extends Table {
public static OperandFlat getRootAsOperandFlat(ByteBuffer _bb) { return getRootAsOperandFlat(_bb, new OperandFlat()); }
public static OperandFlat getRootAsOperandFlat(ByteBuffer _bb, OperandFlat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public OperandFlat __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }

public byte operandType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }

public static int createOperandFlat(FlatBufferBuilder builder,
byte operandType) {
builder.startObject(1);
OperandFlat.addOperandType(builder, operandType);
return OperandFlat.endOperandFlat(builder);
}

public static void startOperandFlat(FlatBufferBuilder builder) { builder.startObject(1); }
public static void addOperandType(FlatBufferBuilder builder, byte operandType) { builder.addByte(0, operandType, 0); }
public static int endOperandFlat(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// automatically generated, do not modify

package org.jruby.ir.persistence.flat;

public final class OperandTypeFlat {
private OperandTypeFlat() { }
public static final byte TEMPORARY_VARIABLE = 0;
public static final byte CURRENT_SCOPE = 1;
public static final byte SCOPE_MODULE = 2;
public static final byte STRING_LITERAL = 3;
public static final byte SELF = 4;

private static final String[] names = { "TEMPORARY_VARIABLE", "CURRENT_SCOPE", "SCOPE_MODULE", "STRING_LITERAL", "SELF", };

public static String name(int e) { return names[e]; }
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// automatically generated, do not modify

package org.jruby.ir.persistence.flat;

public final class OperationFlat {
private OperationFlat() { }
public static final short COPY = 0;
public static final short RECEIVE_SELF = 1;
public static final short LINE_NUMBER = 2;
public static final short CALL_1_OBJ = 3;
public static final short RETURN = 4;
public static final short LOAD_IMPLICIT_CLOSURE = 5;
public static final short LOAD_FRAME_CLOSURE = 6;

private static final String[] names = { "COPY", "RECEIVE_SELF", "LINE_NUMBER", "CALL_1_OBJ", "RETURN", "LOAD_IMPLICIT_CLOSURE", "LOAD_FRAME_CLOSURE", };

public static String name(int e) { return names[e]; }
};

32 changes: 32 additions & 0 deletions core/src/main/resources/jruby.fbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace org.jruby.ir.persistence.flat;

table IRScopeFlat {
name:string;
//lexicalParent:IRScopeFlat;
nestedClosures:[IRClosureFlat];
lexicalChildren:[IRScopeFlat];
instrs:[InstrFlat];
}

table IRClosureFlat {
scope:IRScopeFlat;
}

enum OperationFlat : short {
COPY, RECEIVE_SELF, LINE_NUMBER, CALL_1_OBJ, RETURN, LOAD_IMPLICIT_CLOSURE, LOAD_FRAME_CLOSURE
}

table InstrFlat {
operation:OperationFlat;
operands:[OperandFlat];
}

enum OperandTypeFlat : byte {
TEMPORARY_VARIABLE, CURRENT_SCOPE, SCOPE_MODULE, STRING_LITERAL, SELF
}

table OperandFlat {
operandType:OperandTypeFlat;
}

root_type IRScopeFlat;

0 comments on commit ecdf4fd

Please sign in to comment.