From b748315304f29dc05a996b024e858e0ff1f73744 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 14:59:27 +0200 Subject: [PATCH] Support @MethodName and @MethodDesc --- .../InterceptionInstrumenter.java | 33 ++++++++++++++++--- .../instrumentation/MethodData.java | 6 ++++ .../instrumentation/MethodDataImpl.java | 18 +++++++++- .../instrumentation/MethodDesc.java | 27 +++++++++++++++ .../instrumentation/MethodName.java | 27 +++++++++++++++ 5 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 7d4a04a68ea..a539293fbe4 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -145,6 +145,8 @@ public class InterceptionInstrumenter { private static MethodData getMethodData(FieldData interceptorField, Method method) { Annotation[][] parameterAnnotations = method.getParameterAnnotations(); int thisParameterIndex = -1; + int methodNameParameterIndex = -1; + int methodDescParameterIndex = -1; for (int i = 0; i < parameterAnnotations.length; i++) { for (Annotation annotation : parameterAnnotations[i]) { if (annotation instanceof This) { @@ -153,6 +155,18 @@ public class InterceptionInstrumenter { } thisParameterIndex = i; } + else if (annotation instanceof MethodName) { + if (methodNameParameterIndex > -1) { + throw new IllegalArgumentException("Multiple @MethodName parameters in " + method); + } + methodNameParameterIndex = i; + } + else if (annotation instanceof MethodDesc) { + if (methodDescParameterIndex > -1) { + throw new IllegalArgumentException("Multiple @MethodDesc parameters in " + method); + } + methodDescParameterIndex = i; + } } } return new MethodDataImpl( @@ -161,7 +175,10 @@ public class InterceptionInstrumenter { method.getName(), Type.getMethodDescriptor(method), method.getParameterTypes().length, - thisParameterIndex); + thisParameterIndex, + methodNameParameterIndex, + methodDescParameterIndex + ); } private void addDumpTask(final Object interceptor, final Method method, final MethodInstrumenter instrumenter) { @@ -293,7 +310,7 @@ public class InterceptionInstrumenter { if (enterDataWritten) return; enterDataWritten = true; for (MethodData methodData : enterData) { - invokeMethod(access, desc, getInstructionAdapter(), methodData); + invokeMethod(access, name, desc, getInstructionAdapter(), methodData); } } @@ -309,7 +326,7 @@ public class InterceptionInstrumenter { case ARETURN: case ATHROW: for (MethodData methodData : exitData) { - invokeMethod(access, desc, getInstructionAdapter(), methodData); + invokeMethod(access, name, desc, getInstructionAdapter(), methodData); } break; } @@ -348,7 +365,7 @@ public class InterceptionInstrumenter { return cw.toByteArray(); } - private static void invokeMethod(int access, String instrumentedMethodDesc, InstructionAdapter ia, MethodData methodData) { + private static void invokeMethod(int access, String instrumentedMethodName, String instrumentedMethodDesc, InstructionAdapter ia, MethodData methodData) { FieldData field = methodData.getOwnerField(); ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc()); ia.checkcast(field.getRuntimeType()); @@ -360,7 +377,7 @@ public class InterceptionInstrumenter { int base = isStatic ? 0 : 1; int parametersUsed = 0; for (int i = 0; i < parameterCount; i++) { - if (methodData.getThisParameterIndex() == i) { + if (i == methodData.getThisParameterIndex()) { if (isStatic) { // static method, 'this' is null ia.aconst(null); @@ -370,6 +387,12 @@ public class InterceptionInstrumenter { ia.load(0, OBJECT_TYPE); } } + else if (i == methodData.getMethodNameParameterIndex()) { + ia.aconst(instrumentedMethodName); + } + else if (i == methodData.getMethodDescParameterIndex()) { + ia.aconst(instrumentedMethodDesc); + } else { ia.load(base + parametersUsed, parameterTypes[parametersUsed]); parametersUsed++; diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java index 8340bcb05ff..1d7f266b0ad 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -22,4 +22,10 @@ interface MethodData extends MemberData { // -1 for no @This parameter int getThisParameterIndex(); + + // -1 for no @MethodName + int getMethodNameParameterIndex(); + + // -1 for no @MethodDesc + int getMethodDescParameterIndex(); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java index 5b59c0f2f91..fa2b385441e 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java @@ -20,6 +20,8 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { private final FieldData ownerField; private final int parameterCount; private final int thisParameterIndex; + private final int methodNameParameterIndex; + private final int methodDescParameterIndex; MethodDataImpl( FieldData ownerField, @@ -27,12 +29,16 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { String name, String desc, int parameterCount, - int thisParameterIndex + int thisParameterIndex, + int methodNameParameterIndex, + int methodDescParameterIndex ) { super(declaringClass, name, desc); this.ownerField = ownerField; this.parameterCount = parameterCount; this.thisParameterIndex = thisParameterIndex; + this.methodNameParameterIndex = methodNameParameterIndex; + this.methodDescParameterIndex = methodDescParameterIndex; } @Override @@ -49,4 +55,14 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { public int getThisParameterIndex() { return thisParameterIndex; } + + @Override + public int getMethodNameParameterIndex() { + return methodNameParameterIndex; + } + + @Override + public int getMethodDescParameterIndex() { + return methodDescParameterIndex; + } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java new file mode 100644 index 00000000000..b0d7ba77786 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface MethodDesc { +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java new file mode 100644 index 00000000000..38c4bdbbca2 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface MethodName { +}