Skip to content

Commit 715754d

Browse files
pjstadigstuarthalloway
authored andcommitted
Mark line number after emitting children.
Marking the line number before emitting children leads to incorrect line numbers when a runtime error occurs. For example, when (foo bar baz) is emitted the compiler will visit the line number for the expression, then emit the children expressions ('bar' and 'baz') which will mark their own line numbers, then come back and emit the invoke bytecode for 'foo', but since the last line number to be marked was that of 'baz', if 'foo' throws an exception the line number of 'baz' will be reported instead of the line number for the expression as a whole. This same issue was being manifested with special forms and inlined functions, and was especially bad in the case of the threading macro '->', because it is usually spread across several lines, and the line number reported could end up being very different than the line actually causing an exception. Signed-off-by: Stuart Halloway <[email protected]>
1 parent d760db1 commit 715754d

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

src/jvm/clojure/lang/Compiler.java

+17-9
Original file line numberDiff line numberDiff line change
@@ -1165,10 +1165,10 @@ public boolean canEmitPrimitive(){
11651165
}
11661166

11671167
public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){
1168-
gen.visitLineNumber(line, gen.mark());
11691168
if(targetClass != null && field != null)
11701169
{
11711170
target.emit(C.EXPRESSION, objx, gen);
1171+
gen.visitLineNumber(line, gen.mark());
11721172
gen.checkCast(getType(targetClass));
11731173
gen.getField(getType(targetClass), fieldName, Type.getType(field.getType()));
11741174
}
@@ -1177,10 +1177,10 @@ public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){
11771177
}
11781178

11791179
public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
1180-
gen.visitLineNumber(line, gen.mark());
11811180
if(targetClass != null && field != null)
11821181
{
11831182
target.emit(C.EXPRESSION, objx, gen);
1183+
gen.visitLineNumber(line, gen.mark());
11841184
gen.checkCast(getType(targetClass));
11851185
gen.getField(getType(targetClass), fieldName, Type.getType(field.getType()));
11861186
//if(context != C.STATEMENT)
@@ -1193,6 +1193,7 @@ public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
11931193
else
11941194
{
11951195
target.emit(C.EXPRESSION, objx, gen);
1196+
gen.visitLineNumber(line, gen.mark());
11961197
gen.push(fieldName);
11971198
gen.push(requireField);
11981199
gen.invokeStatic(REFLECTOR_TYPE, invokeNoArgInstanceMember);
@@ -1215,12 +1216,12 @@ public Object evalAssign(Expr val) {
12151216

12161217
public void emitAssign(C context, ObjExpr objx, GeneratorAdapter gen,
12171218
Expr val){
1218-
gen.visitLineNumber(line, gen.mark());
12191219
if(targetClass != null && field != null)
12201220
{
12211221
target.emit(C.EXPRESSION, objx, gen);
12221222
gen.checkCast(Type.getType(targetClass));
12231223
val.emit(C.EXPRESSION, objx, gen);
1224+
gen.visitLineNumber(line, gen.mark());
12241225
gen.dupX1();
12251226
HostExpr.emitUnboxArg(objx, gen, field.getType());
12261227
gen.putField(Type.getType(targetClass), fieldName, Type.getType(field.getType()));
@@ -1230,6 +1231,7 @@ public void emitAssign(C context, ObjExpr objx, GeneratorAdapter gen,
12301231
target.emit(C.EXPRESSION, objx, gen);
12311232
gen.push(fieldName);
12321233
val.emit(C.EXPRESSION, objx, gen);
1234+
gen.visitLineNumber(line, gen.mark());
12331235
gen.invokeStatic(REFLECTOR_TYPE, setInstanceFieldMethod);
12341236
}
12351237
if(context == C.STATEMENT)
@@ -1310,8 +1312,8 @@ public Object evalAssign(Expr val) {
13101312

13111313
public void emitAssign(C context, ObjExpr objx, GeneratorAdapter gen,
13121314
Expr val){
1313-
gen.visitLineNumber(line, gen.mark());
13141315
val.emit(C.EXPRESSION, objx, gen);
1316+
gen.visitLineNumber(line, gen.mark());
13151317
gen.dup();
13161318
HostExpr.emitUnboxArg(objx, gen, field.getType());
13171319
gen.putStatic(Type.getType(c), fieldName, Type.getType(field.getType()));
@@ -1532,14 +1534,14 @@ public boolean canEmitPrimitive(){
15321534
}
15331535

15341536
public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){
1535-
gen.visitLineNumber(line, gen.mark());
15361537
if(method != null)
15371538
{
15381539
Type type = Type.getType(method.getDeclaringClass());
15391540
target.emit(C.EXPRESSION, objx, gen);
15401541
//if(!method.getDeclaringClass().isInterface())
15411542
gen.checkCast(type);
15421543
MethodExpr.emitTypedArgs(objx, gen, method.getParameterTypes(), args);
1544+
gen.visitLineNumber(line, gen.mark());
15431545
if(context == C.RETURN)
15441546
{
15451547
ObjMethod method = (ObjMethod) METHOD.deref();
@@ -1556,14 +1558,14 @@ public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){
15561558
}
15571559

15581560
public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
1559-
gen.visitLineNumber(line, gen.mark());
15601561
if(method != null)
15611562
{
15621563
Type type = Type.getType(method.getDeclaringClass());
15631564
target.emit(C.EXPRESSION, objx, gen);
15641565
//if(!method.getDeclaringClass().isInterface())
15651566
gen.checkCast(type);
15661567
MethodExpr.emitTypedArgs(objx, gen, method.getParameterTypes(), args);
1568+
gen.visitLineNumber(line, gen.mark());
15671569
if(context == C.RETURN)
15681570
{
15691571
ObjMethod method = (ObjMethod) METHOD.deref();
@@ -1582,6 +1584,7 @@ public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
15821584
target.emit(C.EXPRESSION, objx, gen);
15831585
gen.push(methodName);
15841586
emitArgsAsArray(args, objx, gen);
1587+
gen.visitLineNumber(line, gen.mark());
15851588
if(context == C.RETURN)
15861589
{
15871590
ObjMethod method = (ObjMethod) METHOD.deref();
@@ -1727,10 +1730,10 @@ public void emitIntrinsicPredicate(C context, ObjExpr objx, GeneratorAdapter gen
17271730
}
17281731

17291732
public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){
1730-
gen.visitLineNumber(line, gen.mark());
17311733
if(method != null)
17321734
{
17331735
MethodExpr.emitTypedArgs(objx, gen, method.getParameterTypes(), args);
1736+
gen.visitLineNumber(line, gen.mark());
17341737
//Type type = Type.getObjectType(className.replace('.', '/'));
17351738
if(context == C.RETURN)
17361739
{
@@ -1760,10 +1763,10 @@ public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){
17601763
}
17611764

17621765
public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
1763-
gen.visitLineNumber(line, gen.mark());
17641766
if(method != null)
17651767
{
17661768
MethodExpr.emitTypedArgs(objx, gen, method.getParameterTypes(), args);
1769+
gen.visitLineNumber(line, gen.mark());
17671770
//Type type = Type.getObjectType(className.replace('.', '/'));
17681771
if(context == C.RETURN)
17691772
{
@@ -1789,10 +1792,12 @@ else if(retClass != void.class)
17891792
}
17901793
else
17911794
{
1795+
gen.visitLineNumber(line, gen.mark());
17921796
gen.push(c.getName());
17931797
gen.invokeStatic(RT_TYPE, forNameMethod);
17941798
gen.push(methodName);
17951799
emitArgsAsArray(args, objx, gen);
1800+
gen.visitLineNumber(line, gen.mark());
17961801
if(context == C.RETURN)
17971802
{
17981803
ObjMethod method = (ObjMethod) METHOD.deref();
@@ -3255,6 +3260,7 @@ public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
32553260
gen.getStatic(objx.objtype, objx.thunkNameStatic(siteIndex),ObjExpr.ILOOKUP_THUNK_TYPE);
32563261
gen.dup(); //thunk, thunk
32573262
target.emit(C.EXPRESSION, objx, gen); //thunk,thunk,target
3263+
gen.visitLineNumber(line, gen.mark());
32583264
gen.dupX2(); //target,thunk,thunk,target
32593265
gen.invokeInterface(ObjExpr.ILOOKUP_THUNK_TYPE, Method.getMethod("Object get(Object)")); //target,thunk,result
32603266
gen.dupX2(); //result,target,thunk,result
@@ -3626,15 +3632,16 @@ public Object eval() {
36263632
}
36273633

36283634
public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
3629-
gen.visitLineNumber(line, gen.mark());
36303635
if(isProtocol)
36313636
{
3637+
gen.visitLineNumber(line, gen.mark());
36323638
emitProto(context,objx,gen);
36333639
}
36343640

36353641
else
36363642
{
36373643
fexpr.emit(C.EXPRESSION, objx, gen);
3644+
gen.visitLineNumber(line, gen.mark());
36383645
gen.checkCast(IFN_TYPE);
36393646
emitArgsAndCall(0, context,objx,gen);
36403647
}
@@ -3704,6 +3711,7 @@ void emitArgsAndCall(int firstArgToEmit, C context, ObjExpr objx, GeneratorAdapt
37043711
}
37053712
MethodExpr.emitArgsAsArray(restArgs, objx, gen);
37063713
}
3714+
gen.visitLineNumber(line, gen.mark());
37073715

37083716
if(context == C.RETURN)
37093717
{

0 commit comments

Comments
 (0)