Skip to content

Commit 703932a

Browse files
Copy paste scala-backend sources
To go further back in history, continue from https://github.com/dotty-staging/scala/tree/5db0a5cb748b1a9f22ee167fb28a336cfa20a0fc
1 parent 732f7e2 commit 703932a

16 files changed

+6953
-0
lines changed
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/* NSC -- new Scala compiler
2+
* Copyright 2005-2013 LAMP/EPFL
3+
* @author Martin Odersky
4+
*/
5+
6+
package scala
7+
package tools.nsc
8+
package backend
9+
10+
object ScalaPrimitivesOps extends ScalaPrimitivesOps
11+
12+
class ScalaPrimitivesOps {
13+
// Arithmetic unary operations
14+
final val POS = 1 // +x
15+
final val NEG = 2 // -x
16+
final val NOT = 3 // ~x
17+
18+
// Arithmetic binary operations
19+
final val ADD = 10 // x + y
20+
final val SUB = 11 // x - y
21+
final val MUL = 12 // x * y
22+
final val DIV = 13 // x / y
23+
final val MOD = 14 // x % y
24+
25+
// Bitwise operations
26+
final val OR = 20 // x | y
27+
final val XOR = 21 // x ^ y
28+
final val AND = 22 // x & y
29+
30+
// Shift operations
31+
final val LSL = 30 // x << y
32+
final val LSR = 31 // x >>> y
33+
final val ASR = 32 // x >> y
34+
35+
// Comparison operations
36+
final val ID = 40 // x eq y
37+
final val NI = 41 // x ne y
38+
final val EQ = 42 // x == y
39+
final val NE = 43 // x != y
40+
final val LT = 44 // x < y
41+
final val LE = 45 // x <= y
42+
final val GE = 46 // x > y
43+
final val GT = 47 // x >= y
44+
45+
// Boolean unary operations
46+
final val ZNOT = 50 // !x
47+
48+
// Boolean binary operations
49+
final val ZOR = 60 // x || y
50+
final val ZAND = 61 // x && y
51+
52+
// Array operations
53+
final val LENGTH = 70 // x.length
54+
final val APPLY = 71 // x(y)
55+
final val UPDATE = 72 // x(y) = z
56+
57+
// Any operations
58+
final val IS = 80 // x.is[y]
59+
final val AS = 81 // x.as[y]
60+
final val HASH = 87 // x.##
61+
62+
// AnyRef operations
63+
final val SYNCHRONIZED = 90 // x.synchronized(y)
64+
65+
// String operations
66+
final val CONCAT = 100 // String.valueOf(x)+String.valueOf(y)
67+
68+
// coercions
69+
final val COERCE = 101
70+
71+
// RunTime operations
72+
final val BOX = 110 // RunTime.box_<X>(x)
73+
final val UNBOX = 111 // RunTime.unbox_<X>(x)
74+
final val NEW_ZARRAY = 112 // RunTime.zarray(x)
75+
final val NEW_BARRAY = 113 // RunTime.barray(x)
76+
final val NEW_SARRAY = 114 // RunTime.sarray(x)
77+
final val NEW_CARRAY = 115 // RunTime.carray(x)
78+
final val NEW_IARRAY = 116 // RunTime.iarray(x)
79+
final val NEW_LARRAY = 117 // RunTime.larray(x)
80+
final val NEW_FARRAY = 118 // RunTime.farray(x)
81+
final val NEW_DARRAY = 119 // RunTime.darray(x)
82+
final val NEW_OARRAY = 120 // RunTime.oarray(x)
83+
84+
final val ZARRAY_LENGTH = 131 // RunTime.zarray_length(x)
85+
final val BARRAY_LENGTH = 132 // RunTime.barray_length(x)
86+
final val SARRAY_LENGTH = 133 // RunTime.sarray_length(x)
87+
final val CARRAY_LENGTH = 134 // RunTime.carray_length(x)
88+
final val IARRAY_LENGTH = 135 // RunTime.iarray_length(x)
89+
final val LARRAY_LENGTH = 136 // RunTime.larray_length(x)
90+
final val FARRAY_LENGTH = 137 // RunTime.farray_length(x)
91+
final val DARRAY_LENGTH = 138 // RunTime.darray_length(x)
92+
final val OARRAY_LENGTH = 139 // RunTime.oarray_length(x)
93+
94+
final val ZARRAY_GET = 140 // RunTime.zarray_get(x,y)
95+
final val BARRAY_GET = 141 // RunTime.barray_get(x,y)
96+
final val SARRAY_GET = 142 // RunTime.sarray_get(x,y)
97+
final val CARRAY_GET = 143 // RunTime.carray_get(x,y)
98+
final val IARRAY_GET = 144 // RunTime.iarray_get(x,y)
99+
final val LARRAY_GET = 145 // RunTime.larray_get(x,y)
100+
final val FARRAY_GET = 146 // RunTime.farray_get(x,y)
101+
final val DARRAY_GET = 147 // RunTime.darray_get(x,y)
102+
final val OARRAY_GET = 148 // RunTime.oarray_get(x,y)
103+
104+
final val ZARRAY_SET = 150 // RunTime.zarray(x,y,z)
105+
final val BARRAY_SET = 151 // RunTime.barray(x,y,z)
106+
final val SARRAY_SET = 152 // RunTime.sarray(x,y,z)
107+
final val CARRAY_SET = 153 // RunTime.carray(x,y,z)
108+
final val IARRAY_SET = 154 // RunTime.iarray(x,y,z)
109+
final val LARRAY_SET = 155 // RunTime.larray(x,y,z)
110+
final val FARRAY_SET = 156 // RunTime.farray(x,y,z)
111+
final val DARRAY_SET = 157 // RunTime.darray(x,y,z)
112+
final val OARRAY_SET = 158 // RunTime.oarray(x,y,z)
113+
114+
final val B2B = 200 // RunTime.b2b(x)
115+
final val B2S = 201 // RunTime.b2s(x)
116+
final val B2C = 202 // RunTime.b2c(x)
117+
final val B2I = 203 // RunTime.b2i(x)
118+
final val B2L = 204 // RunTime.b2l(x)
119+
final val B2F = 205 // RunTime.b2f(x)
120+
final val B2D = 206 // RunTime.b2d(x)
121+
122+
final val S2B = 210 // RunTime.s2b(x)
123+
final val S2S = 211 // RunTime.s2s(x)
124+
final val S2C = 212 // RunTime.s2c(x)
125+
final val S2I = 213 // RunTime.s2i(x)
126+
final val S2L = 214 // RunTime.s2l(x)
127+
final val S2F = 215 // RunTime.s2f(x)
128+
final val S2D = 216 // RunTime.s2d(x)
129+
130+
final val C2B = 220 // RunTime.c2b(x)
131+
final val C2S = 221 // RunTime.c2s(x)
132+
final val C2C = 222 // RunTime.c2c(x)
133+
final val C2I = 223 // RunTime.c2i(x)
134+
final val C2L = 224 // RunTime.c2l(x)
135+
final val C2F = 225 // RunTime.c2f(x)
136+
final val C2D = 226 // RunTime.c2d(x)
137+
138+
final val I2B = 230 // RunTime.i2b(x)
139+
final val I2S = 231 // RunTime.i2s(x)
140+
final val I2C = 232 // RunTime.i2c(x)
141+
final val I2I = 233 // RunTime.i2i(x)
142+
final val I2L = 234 // RunTime.i2l(x)
143+
final val I2F = 235 // RunTime.i2f(x)
144+
final val I2D = 236 // RunTime.i2d(x)
145+
146+
final val L2B = 240 // RunTime.l2b(x)
147+
final val L2S = 241 // RunTime.l2s(x)
148+
final val L2C = 242 // RunTime.l2c(x)
149+
final val L2I = 243 // RunTime.l2i(x)
150+
final val L2L = 244 // RunTime.l2l(x)
151+
final val L2F = 245 // RunTime.l2f(x)
152+
final val L2D = 246 // RunTime.l2d(x)
153+
154+
final val F2B = 250 // RunTime.f2b(x)
155+
final val F2S = 251 // RunTime.f2s(x)
156+
final val F2C = 252 // RunTime.f2c(x)
157+
final val F2I = 253 // RunTime.f2i(x)
158+
final val F2L = 254 // RunTime.f2l(x)
159+
final val F2F = 255 // RunTime.f2f(x)
160+
final val F2D = 256 // RunTime.f2d(x)
161+
162+
final val D2B = 260 // RunTime.d2b(x)
163+
final val D2S = 261 // RunTime.d2s(x)
164+
final val D2C = 262 // RunTime.d2c(x)
165+
final val D2I = 263 // RunTime.d2i(x)
166+
final val D2L = 264 // RunTime.d2l(x)
167+
final val D2F = 265 // RunTime.d2f(x)
168+
final val D2D = 266 // RunTime.d2d(x)
169+
170+
/** Check whether the given operation code is an array operation. */
171+
def isArrayOp(code: Int): Boolean =
172+
isArrayNew(code) | isArrayLength(code) | isArrayGet(code) | isArraySet(code)
173+
174+
def isArrayNew(code: Int): Boolean = code match {
175+
case NEW_ZARRAY | NEW_BARRAY | NEW_SARRAY | NEW_CARRAY |
176+
NEW_IARRAY | NEW_LARRAY | NEW_FARRAY | NEW_DARRAY |
177+
NEW_OARRAY => true
178+
case _ => false
179+
}
180+
181+
def isArrayLength(code: Int): Boolean = code match {
182+
case ZARRAY_LENGTH | BARRAY_LENGTH | SARRAY_LENGTH | CARRAY_LENGTH |
183+
IARRAY_LENGTH | LARRAY_LENGTH | FARRAY_LENGTH | DARRAY_LENGTH |
184+
OARRAY_LENGTH | LENGTH => true
185+
case _ => false
186+
}
187+
188+
def isArrayGet(code: Int): Boolean = code match {
189+
case ZARRAY_GET | BARRAY_GET | SARRAY_GET | CARRAY_GET |
190+
IARRAY_GET | LARRAY_GET | FARRAY_GET | DARRAY_GET |
191+
OARRAY_GET | APPLY => true
192+
case _ => false
193+
}
194+
195+
def isArraySet(code: Int): Boolean = code match {
196+
case ZARRAY_SET | BARRAY_SET | SARRAY_SET | CARRAY_SET |
197+
IARRAY_SET | LARRAY_SET | FARRAY_SET | DARRAY_SET |
198+
OARRAY_SET | UPDATE => true
199+
case _ => false
200+
}
201+
202+
/** Check whether the given code is a comparison operator */
203+
def isComparisonOp(code: Int): Boolean = code match {
204+
case ID | NI | EQ | NE |
205+
LT | LE | GT | GE => true
206+
207+
case _ => false
208+
}
209+
def isUniversalEqualityOp(code: Int): Boolean = (code == EQ) || (code == NE)
210+
def isReferenceEqualityOp(code: Int): Boolean = (code == ID) || (code == NI)
211+
212+
def isArithmeticOp(code: Int): Boolean = code match {
213+
case POS | NEG | NOT => true; // unary
214+
case ADD | SUB | MUL |
215+
DIV | MOD => true; // binary
216+
case OR | XOR | AND |
217+
LSL | LSR | ASR => true; // bitwise
218+
case _ => false
219+
}
220+
221+
def isLogicalOp(code: Int): Boolean = code match {
222+
case ZNOT | ZAND | ZOR => true
223+
case _ => false
224+
}
225+
226+
def isShiftOp(code: Int): Boolean = code match {
227+
case LSL | LSR | ASR => true
228+
case _ => false
229+
}
230+
231+
def isBitwiseOp(code: Int): Boolean = code match {
232+
case OR | XOR | AND => true
233+
case _ => false
234+
}
235+
236+
def isCoercion(code: Int): Boolean = (code >= B2B) && (code <= D2D)
237+
238+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/* NSC -- new Scala compiler
2+
* Copyright 2005-2013 LAMP/EPFL
3+
* @author Martin Odersky
4+
*/
5+
6+
package scala.tools.nsc
7+
package backend
8+
9+
import scala.collection.mutable
10+
11+
/**
12+
* Simple implementation of a worklist algorithm. A processing
13+
* function is applied repeatedly to the first element in the
14+
* worklist, as long as the stack is not empty.
15+
*
16+
* The client class should mix-in this class and initialize the worklist
17+
* field and define the `processElement` method. Then call the `run` method
18+
* providing a function that initializes the worklist.
19+
*
20+
* @author Martin Odersky
21+
* @version 1.0
22+
* @see [[scala.tools.nsc.backend.icode.Linearizers]]
23+
*/
24+
trait WorklistAlgorithm {
25+
type Elem
26+
class WList {
27+
private[this] var list: List[Elem] = Nil
28+
def isEmpty = list.isEmpty
29+
def nonEmpty = !isEmpty
30+
def push(e: Elem): Unit = { list = e :: list }
31+
def pop(): Elem = {
32+
val head = list.head
33+
list = list.tail
34+
head
35+
}
36+
def pushAll(xs: Iterable[Elem]): Unit = xs.foreach(push)
37+
def clear(): Unit = list = Nil
38+
39+
}
40+
41+
val worklist: WList
42+
43+
/**
44+
* Run the iterative algorithm until the worklist remains empty.
45+
* The initializer is run once before the loop starts and should
46+
* initialize the worklist.
47+
*/
48+
def run(initWorklist: => Unit) = {
49+
initWorklist
50+
51+
while (worklist.nonEmpty)
52+
processElement(dequeue)
53+
}
54+
55+
/**
56+
* Process the current element from the worklist.
57+
*/
58+
def processElement(e: Elem): Unit
59+
60+
/**
61+
* Remove and return the first element to be processed from the worklist.
62+
*/
63+
def dequeue: Elem
64+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* NSC -- new Scala compiler
2+
* Copyright 2005-2014 LAMP/EPFL
3+
* @author Martin Odersky
4+
*/
5+
6+
package scala.tools.nsc.backend.jvm
7+
8+
import scala.tools.asm.tree.{AbstractInsnNode, ClassNode, MethodNode}
9+
import java.io.PrintWriter
10+
import scala.tools.asm.util.{TraceClassVisitor, TraceMethodVisitor, Textifier}
11+
import scala.tools.asm.ClassReader
12+
13+
object AsmUtils {
14+
15+
/**
16+
* Print the bytecode of methods generated by GenBCode to the standard output. Only methods
17+
* whose name contains `traceMethodPattern` are traced.
18+
*/
19+
final val traceMethodEnabled = sys.env.contains("printBCODE")
20+
final val traceMethodPattern = sys.env.getOrElse("printBCODE", "")
21+
22+
/**
23+
* Print the bytecode of classes generated by GenBCode to the standard output.
24+
*/
25+
final val traceClassEnabled = false
26+
final val traceClassPattern = ""
27+
28+
/**
29+
* Print the bytedcode of classes as they are serialized by the ASM library. The serialization
30+
* performed by `asm.ClassWriter` can change the code generated by GenBCode. For example, it
31+
* introduces stack map frames, it computes the maximal stack sizes, and it replaces dead
32+
* code by NOPs (see also https://github.com/scala/scala/pull/3726#issuecomment-42861780).
33+
*/
34+
final val traceSerializedClassEnabled = false
35+
final val traceSerializedClassPattern = ""
36+
37+
def traceMethod(mnode: MethodNode): Unit = {
38+
println(s"Bytecode for method ${mnode.name}")
39+
val p = new Textifier
40+
val tracer = new TraceMethodVisitor(p)
41+
mnode.accept(tracer)
42+
val w = new PrintWriter(System.out)
43+
p.print(w)
44+
w.flush()
45+
}
46+
47+
def traceClass(cnode: ClassNode): Unit = {
48+
println(s"Bytecode for class ${cnode.name}")
49+
val w = new PrintWriter(System.out)
50+
cnode.accept(new TraceClassVisitor(w))
51+
w.flush()
52+
}
53+
54+
def traceClass(bytes: Array[Byte]): Unit = traceClass(readClass(bytes))
55+
56+
def readClass(bytes: Array[Byte]): ClassNode = {
57+
val node = new ClassNode()
58+
new ClassReader(bytes).accept(node, 0)
59+
node
60+
}
61+
62+
def instructionString(instruction: AbstractInsnNode): String = instruction.getOpcode match {
63+
case -1 => instruction.toString
64+
case op => scala.tools.asm.util.Printer.OPCODES(op)
65+
}
66+
}

0 commit comments

Comments
 (0)