This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch groovy-replace
in repository https://gitbox.apache.org/repos/asf/skywalking.git

commit 1f5a421f4abe4a71f1d42d8a7abc38cb825d0b00
Author: Wu Sheng <[email protected]>
AuthorDate: Tue Mar 3 15:18:40 2026 +0800

    Add LocalVariableTable to all MAL generated methods (metadata, closures, 
filters)
    
    Previously only run() had LVT. Now all generated methods have named locals
    in debuggers/decompilers instead of var0/var1/var2:
    - metadata(): this, _samples, _scopeLabels, _aggLabels, _pct
    - tag/instance apply(Map): this, param name
    - tag/instance apply(Object) bridge: this, o
    - forEach accept(): this, element, tags
    - decorate accept(): this, _arg, param name
    - filter test(): this, param name
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../analyzer/v2/compiler/MALClassGenerator.java    | 94 ++++++++++++++++------
 1 file changed, 71 insertions(+), 23 deletions(-)

diff --git 
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALClassGenerator.java
 
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALClassGenerator.java
index e5f74bc919..b8b28a164a 100644
--- 
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALClassGenerator.java
+++ 
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALClassGenerator.java
@@ -161,9 +161,9 @@ public final class MALClassGenerator {
         }
     }
 
-    private void addRunLocalVariableTable(final javassist.CtMethod method,
-                                          final String className,
-                                          final int tempCount) {
+    private void addLocalVariableTable(final javassist.CtMethod method,
+                                       final String className,
+                                       final String[][] vars) {
         try {
             final javassist.bytecode.MethodInfo mi = method.getMethodInfo();
             final javassist.bytecode.CodeAttribute code = 
mi.getCodeAttribute();
@@ -172,23 +172,16 @@ public final class MALClassGenerator {
             }
             final javassist.bytecode.ConstPool cp = mi.getConstPool();
             final int len = code.getCodeLength();
-            final String sfDesc = "L" + SF.replace('.', '/') + ";";
 
             final javassist.bytecode.LocalVariableAttribute lva =
                 new javassist.bytecode.LocalVariableAttribute(cp);
             lva.addEntry(0, len,
                 cp.addUtf8Info("this"),
                 cp.addUtf8Info("L" + className.replace('.', '/') + ";"), 0);
-            lva.addEntry(0, len,
-                cp.addUtf8Info("samples"),
-                cp.addUtf8Info("Ljava/util/Map;"), 1);
-            lva.addEntry(0, len,
-                cp.addUtf8Info(RUN_VAR),
-                cp.addUtf8Info(sfDesc), 2);
-            for (int i = 0; i < tempCount; i++) {
+            for (int i = 0; i < vars.length; i++) {
                 lva.addEntry(0, len,
-                    cp.addUtf8Info("_t" + i),
-                    cp.addUtf8Info(sfDesc), 3 + i);
+                    cp.addUtf8Info(vars[i][0]),
+                    cp.addUtf8Info(vars[i][1]), i + 1);
             }
             code.getAttributes().add(lva);
         } catch (Exception e) {
@@ -196,6 +189,19 @@ public final class MALClassGenerator {
         }
     }
 
+    private void addRunLocalVariableTable(final javassist.CtMethod method,
+                                          final String className,
+                                          final int tempCount) {
+        final String sfDesc = "L" + SF.replace('.', '/') + ";";
+        final String[][] vars = new String[2 + tempCount][];
+        vars[0] = new String[]{"samples", "Ljava/util/Map;"};
+        vars[1] = new String[]{RUN_VAR, sfDesc};
+        for (int i = 0; i < tempCount; i++) {
+            vars[2 + i] = new String[]{"_t" + i, sfDesc};
+        }
+        addLocalVariableTable(method, className, vars);
+    }
+
     /**
      * Compiles a MAL expression into a MalExpression implementation.
      *
@@ -276,7 +282,12 @@ public final class MALClassGenerator {
             log.debug("MAL compileFilter test():\n{}", filterBody);
         }
 
-        ctClass.addMethod(CtNewMethod.make(filterBody, ctClass));
+        final javassist.CtMethod testMethod =
+            CtNewMethod.make(filterBody, ctClass);
+        ctClass.addMethod(testMethod);
+        addLocalVariableTable(testMethod, className, new String[][]{
+            {paramName, "Ljava/util/Map;"}
+        });
 
         writeClassFile(ctClass);
 
@@ -344,7 +355,15 @@ public final class MALClassGenerator {
         final javassist.CtMethod runMethod = CtNewMethod.make(runBody, 
ctClass);
         ctClass.addMethod(runMethod);
         addRunLocalVariableTable(runMethod, className, runTempCounter);
-        ctClass.addMethod(CtNewMethod.make(metadataBody, ctClass));
+        final javassist.CtMethod metaMethod =
+            CtNewMethod.make(metadataBody, ctClass);
+        ctClass.addMethod(metaMethod);
+        addLocalVariableTable(metaMethod, className, new String[][]{
+            {"_samples", "Ljava/util/List;"},
+            {"_scopeLabels", "Ljava/util/Set;"},
+            {"_aggLabels", "Ljava/util/Set;"},
+            {"_pct", "[I"}
+        });
 
         writeClassFile(ctClass);
 
@@ -489,7 +508,12 @@ public final class MALClassGenerator {
             if (log.isDebugEnabled()) {
                 log.debug("ForEach closure body:\n{}", sb);
             }
-            ctClass.addMethod(CtNewMethod.make(sb.toString(), ctClass));
+            final javassist.CtMethod m = CtNewMethod.make(sb.toString(), 
ctClass);
+            ctClass.addMethod(m);
+            addLocalVariableTable(m, className, new String[][]{
+                {elementParam, "Ljava/lang/String;"},
+                {tagsParam, "Ljava/util/Map;"}
+            });
         } else if (isPropertiesExtractor) {
             // PropertiesExtractor: Map<String,String> 
apply(Map<String,String> tags)
             // Body is typically a single map literal expression
@@ -525,10 +549,19 @@ public final class MALClassGenerator {
             }
             sb.append("}\n");
 
-            ctClass.addMethod(CtNewMethod.make(sb.toString(), ctClass));
-            ctClass.addMethod(CtNewMethod.make(
+            final javassist.CtMethod applyMap =
+                CtNewMethod.make(sb.toString(), ctClass);
+            ctClass.addMethod(applyMap);
+            addLocalVariableTable(applyMap, className, new String[][]{
+                {paramName, "Ljava/util/Map;"}
+            });
+            final javassist.CtMethod applyObj = CtNewMethod.make(
                 "public Object apply(Object o) { return apply((java.util.Map) 
o); }",
-                ctClass));
+                ctClass);
+            ctClass.addMethod(applyObj);
+            addLocalVariableTable(applyObj, className, new String[][]{
+                {"o", "Ljava/lang/Object;"}
+            });
         } else if (DECORATE_FUNCTION_TYPE.equals(info.interfaceType)) {
             // DecorateFunction: void accept(MeterEntity)
             // Closure param operates on MeterEntity bean properties 
(getters/setters).
@@ -547,7 +580,13 @@ public final class MALClassGenerator {
             if (log.isDebugEnabled()) {
                 log.debug("Decorate closure body:\n{}", sb);
             }
-            ctClass.addMethod(CtNewMethod.make(sb.toString(), ctClass));
+            final javassist.CtMethod acceptMethod =
+                CtNewMethod.make(sb.toString(), ctClass);
+            ctClass.addMethod(acceptMethod);
+            addLocalVariableTable(acceptMethod, className, new String[][]{
+                {"_arg", "Ljava/lang/Object;"},
+                {paramName, "L" + METER_ENTITY_FQCN.replace('.', '/') + ";"}
+            });
         } else {
             // TagFunction: Map<String,String> apply(Map<String,String> tags)
             final String paramName = params.isEmpty() ? "it" : params.get(0);
@@ -562,10 +601,19 @@ public final class MALClassGenerator {
             sb.append("}\n");
 
             // Also add the Object apply(Object) bridge method
-            ctClass.addMethod(CtNewMethod.make(sb.toString(), ctClass));
-            ctClass.addMethod(CtNewMethod.make(
+            final javassist.CtMethod tagApply =
+                CtNewMethod.make(sb.toString(), ctClass);
+            ctClass.addMethod(tagApply);
+            addLocalVariableTable(tagApply, className, new String[][]{
+                {paramName, "Ljava/util/Map;"}
+            });
+            final javassist.CtMethod tagBridge = CtNewMethod.make(
                 "public Object apply(Object o) { return apply((java.util.Map) 
o); }",
-                ctClass));
+                ctClass);
+            ctClass.addMethod(tagBridge);
+            addLocalVariableTable(tagBridge, className, new String[][]{
+                {"o", "Ljava/lang/Object;"}
+            });
         }
 
         writeClassFile(ctClass);

Reply via email to