Skip to content

Commit 9d74404

Browse files
committed
Support nqp::isattrinit properly on P6opaque.
1 parent fc571c1 commit 9d74404

File tree

1 file changed

+62
-2
lines changed

1 file changed

+62
-2
lines changed

src/vm/jvm/runtime/org/perl6/nqp/sixmodel/reprs/P6Opaque.java

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ private void addDelegation(MethodVisitor mv, String methodName,
155155
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perl6/nqp/sixmodel/SixModelObject", methodName,
156156
Type.getMethodDescriptor(retType, argTypes));
157157

158-
mv.visitInsn(retType == Type.VOID_TYPE ? Opcodes.RETURN : Opcodes.ARETURN);
158+
mv.visitInsn(retType == Type.VOID_TYPE ? Opcodes.RETURN :
159+
retType == Type.LONG_TYPE ? Opcodes.LRETURN :
160+
Opcodes.ARETURN);
159161
mv.visitLabel(label);
160162
mv.visitInsn(Opcodes.POP);
161163
}
@@ -279,6 +281,34 @@ private void generateJVMType(ThreadContext tc, STable st, List<AttrInfo> attrInf
279281
}
280282
}
281283

284+
/* is_attribute_initialized */
285+
MethodVisitor isInitVisitor;
286+
Label isInitSwitch = null;
287+
Label[] isInitLabels = null;
288+
Label isInitDefault = new Label();
289+
Label isInitNull = new Label();
290+
{
291+
String descriptor = Type.getMethodDescriptor(Type.LONG_TYPE,
292+
new Type[] { tcType, smoType, Type.getType(String.class), Type.LONG_TYPE });
293+
isInitVisitor = cw.visitMethod(Opcodes.ACC_PUBLIC, "is_attribute_initialized", descriptor, null, null);
294+
isInitVisitor.visitCode();
295+
addDelegation(isInitVisitor, "is_attribute_initialized", Type.LONG_TYPE,
296+
new Type[] { tcType, smoType, Type.getType(String.class), Type.LONG_TYPE }, false);
297+
298+
isInitVisitor.visitVarInsn(Opcodes.LLOAD, 4);
299+
isInitVisitor.visitInsn(Opcodes.L2I);
300+
301+
if (attrInfoList.size() > 0) {
302+
isInitLabels = new Label[attrInfoList.size()];
303+
for (int i = 0; i < attrInfoList.size(); i++) {
304+
isInitLabels[i] = new Label();
305+
}
306+
isInitSwitch = new Label();
307+
isInitVisitor.visitLabel(isInitSwitch);
308+
isInitVisitor.visitTableSwitchInsn(0, attrInfoList.size() - 1, isInitDefault, isInitLabels);
309+
}
310+
}
311+
282312
/* Now add all of the required fields and fill out the methods. */
283313
for (int i = 0; i < attrInfoList.size(); i++) {
284314
AttrInfo attr = attrInfoList.get(i);
@@ -324,6 +354,15 @@ private void generateJVMType(ThreadContext tc, STable st, List<AttrInfo> attrInf
324354
getBoxedVisitor.visitInsn(Opcodes.ARETURN);
325355
}
326356

357+
/* Add is init code. */
358+
isInitVisitor.visitLabel(isInitLabels[i]);
359+
isInitVisitor.visitVarInsn(Opcodes.ALOAD, 0);
360+
isInitVisitor.visitFieldInsn(Opcodes.GETFIELD, className, field, desc);
361+
isInitVisitor.visitJumpInsn(Opcodes.IFNULL, isInitNull);
362+
isInitVisitor.visitInsn(Opcodes.ICONST_1);
363+
isInitVisitor.visitInsn(Opcodes.I2L);
364+
isInitVisitor.visitInsn(Opcodes.LRETURN);
365+
327366
/* Native variants should just throw. */
328367
bindNativeVisitor.visitLabel(bindNativeLabels[i]);
329368
bindNativeVisitor.visitVarInsn(Opcodes.ALOAD, 0);
@@ -344,6 +383,12 @@ private void generateJVMType(ThreadContext tc, STable st, List<AttrInfo> attrInf
344383
getNativeVisitor.visitLabel(getNativeLabels[i]);
345384
attr.st.REPR.inlineGet(tc, attr.st, getNativeVisitor, className, prefix);
346385

386+
/* Add is init code. */
387+
isInitVisitor.visitLabel(isInitLabels[i]);
388+
isInitVisitor.visitInsn(Opcodes.ICONST_1);
389+
isInitVisitor.visitInsn(Opcodes.I2L);
390+
isInitVisitor.visitInsn(Opcodes.LRETURN);
391+
347392
/* Reference variants should just throw. */
348393
bindBoxedVisitor.visitLabel(bindBoxedLabels[i]);
349394
bindBoxedVisitor.visitVarInsn(Opcodes.ALOAD, 0);
@@ -426,9 +471,24 @@ private void generateJVMType(ThreadContext tc, STable st, List<AttrInfo> attrInf
426471
getNativeVisitor.visitJumpInsn(Opcodes.GOTO, getNativeSwitch);
427472
else
428473
getNativeVisitor.visitInsn(Opcodes.RETURN);
429-
430474
getNativeVisitor.visitMaxs(6, 6);
431475
getNativeVisitor.visitEnd();
476+
477+
/* Finish is_attribute_initialized. */
478+
isInitVisitor.visitLabel(isInitDefault);
479+
isInitVisitor.visitVarInsn(Opcodes.ALOAD, 0);
480+
isInitVisitor.visitVarInsn(Opcodes.ALOAD, 2);
481+
isInitVisitor.visitVarInsn(Opcodes.ALOAD, 3);
482+
isInitVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, "resolveAttribute",
483+
"(Lorg/perl6/nqp/sixmodel/SixModelObject;Ljava/lang/String;)I");
484+
if (attrInfoList.size() > 0)
485+
isInitVisitor.visitJumpInsn(Opcodes.GOTO, isInitSwitch);
486+
isInitVisitor.visitLabel(isInitNull);
487+
isInitVisitor.visitInsn(Opcodes.ICONST_1);
488+
isInitVisitor.visitInsn(Opcodes.I2L);
489+
isInitVisitor.visitInsn(Opcodes.LRETURN);
490+
isInitVisitor.visitMaxs(0, 0);
491+
isInitVisitor.visitEnd();
432492

433493
/* Finally, add empty constructor and generate the JVM storage class. */
434494
MethodVisitor constructor = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);

0 commit comments

Comments
 (0)