@Override public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) { context.getProgressIndicator().setText(myValidator.getProgressIndicatorText()); final List<ProcessingItem> processedItems = new ArrayList<ProcessingItem>(); final List<LocalInspectionTool> inspections = new ArrayList<LocalInspectionTool>(); for (final Class aClass : myValidator.getInspectionToolClasses(context)) { try { inspections.add((LocalInspectionTool) aClass.newInstance()); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new Error(e); } } for (int i = 0; i < items.length; i++) { final MyValidatorProcessingItem item = (MyValidatorProcessingItem) items[i]; context.getProgressIndicator().checkCanceled(); context.getProgressIndicator().setFraction((double) i / items.length); try { ourCompilationThreads.set(Boolean.TRUE); if (checkFile(inspections, item, context)) { processedItems.add(item); } } finally { ourCompilationThreads.set(Boolean.FALSE); } } return processedItems.toArray(new ProcessingItem[processedItems.size()]); }
private boolean checkUnderReadAction( final MyValidatorProcessingItem item, final CompileContext context, final Computable<Map<ProblemDescriptor, HighlightDisplayLevel>> runnable) { return DumbService.getInstance(context.getProject()) .runReadActionInSmartMode( new Computable<Boolean>() { @Override public Boolean compute() { final PsiFile file = item.getPsiFile(); if (file == null) return false; final Document document = myPsiDocumentManager.getCachedDocument(file); if (document != null && myPsiDocumentManager.isUncommited(document)) { final String url = file.getViewProvider().getVirtualFile().getUrl(); context.addMessage( CompilerMessageCategory.WARNING, CompilerBundle.message("warning.text.file.has.been.changed"), url, -1, -1); return false; } if (reportProblems(context, runnable.compute())) return false; return true; } }); }
@Override public boolean isCompilableFile(VirtualFile file, CompileContext context) { if (!(file.getFileType() instanceof JetFileType)) { return false; } Module module = context.getModuleByFile(file); if (module == null) { return false; } return ProjectStructureUtil.isJsKotlinModule(module); }
private static void addMessages( @NotNull final CompileContext context, @NotNull final Map<CompilerMessageCategory, List<String>> messages, @NotNull final String url) { for (final CompilerMessageCategory category : messages.keySet()) { final List<String> messageList = messages.get(category); for (final String message : messageList) { context.addMessage(category, message, url, -1, -1); } } }
public final CompileContext compile() throws RecognitionException { CompileContext _localctx = new CompileContext(_ctx, getState()); enterRule(_localctx, 0, RULE_compile); try { enterOuterAlt(_localctx, 1); { setState(4); expression(0); setState(5); match(EOF); } } catch (RecognitionException re) { _localctx.exception = re; _errHandler.reportError(this, re); _errHandler.recover(this, re); } finally { exitRule(); } return _localctx; }
@Override @NotNull public ProcessingItem[] getProcessingItems(final CompileContext context) { final Project project = context.getProject(); if (project.isDefault() || !ValidationConfiguration.shouldValidate(this, context)) { return ProcessingItem.EMPTY_ARRAY; } final ExcludesConfiguration excludesConfiguration = ValidationConfiguration.getExcludedEntriesConfiguration(project); final List<ProcessingItem> items = DumbService.getInstance(project) .runReadActionInSmartMode( new Computable<List<ProcessingItem>>() { @Override public List<ProcessingItem> compute() { final CompileScope compileScope = context.getCompileScope(); if (!myValidator.isAvailableOnScope(compileScope)) return null; final ArrayList<ProcessingItem> items = new ArrayList<ProcessingItem>(); final Processor<VirtualFile> processor = new Processor<VirtualFile>() { @Override public boolean process(VirtualFile file) { if (!file.isValid()) { return true; } if (myCompilerManager.isExcludedFromCompilation(file) || excludesConfiguration.isExcluded(file)) { return true; } final Module module = context.getModuleByFile(file); if (module != null) { final PsiFile psiFile = myPsiManager.findFile(file); if (psiFile != null) { items.add(new MyValidatorProcessingItem(psiFile)); } } return true; } }; ContainerUtil.process( myValidator.getFilesToProcess(myPsiManager.getProject(), context), processor); return items; } }); if (items == null) return ProcessingItem.EMPTY_ARRAY; return items.toArray(new ProcessingItem[items.size()]); }
@Nullable private static Module getModule( @NotNull CompileContext context, @NotNull Chunk<Module> moduleChunk) { if (moduleChunk.getNodes().size() != 1) { context.addMessage( CompilerMessageCategory.ERROR, "K2JSCompiler does not support multiple modules.", null, -1, -1); return null; } return moduleChunk.getNodes().iterator().next(); }
@Override protected Expr opt(final CompileContext cc) throws QueryException { if (allAreValues() && exprs[0].size() < UNROLL_LIMIT) { // unroll the loop cc.info(QueryText.OPTUNROLL_X, this); final Value seq = (Value) exprs[0]; final int len = (int) seq.size(); // fn:for-each(...) final Expr[] results = new Expr[len]; for (int i = 0; i < len; i++) { results[i] = new DynFuncCall(info, sc, exprs[1], seq.itemAt(i)).optimize(cc); } return new List(info, results).optimize(cc); } return this; }
@Override public GenerationItem[] generate( final CompileContext context, final GenerationItem[] items, final VirtualFile outputRootDirectory) { if (items == null || items.length <= 0) { return EMPTY_GENERATION_ITEM_ARRAY; } context.getProgressIndicator().setText("Compiling RenderScript files..."); final GenerationItem[] generationItems = doGenerate(context, items, outputRootDirectory); final Set<VirtualFile> generatedVFiles = new HashSet<VirtualFile>(); final HashSet<VirtualFile> visited = new HashSet<VirtualFile>(); outputRootDirectory.refresh(false, true); AndroidUtils.collectFiles(outputRootDirectory, visited, generatedVFiles); if (context instanceof CompileContextEx) { ((CompileContextEx) context).markGenerated(generatedVFiles); } return generationItems; }
@Override public void finished( boolean aborted, int errors, int warnings, final CompileContext compileContext) { try { for (CompilerMessageCategory category : CompilerMessageCategory.values()) { for (CompilerMessage message : compileContext.getMessages(category)) { final String msg = message.getMessage(); if (category != CompilerMessageCategory.INFORMATION || !msg.startsWith("Compilation completed successfully")) { myMessages.add(category + ": " + msg); } } } if (errors > 0) { fail("Compiler errors occurred! " + StringUtil.join(myMessages, "\n")); } assertFalse("Code did not compile!", aborted); } catch (Throwable t) { myError = t; } finally { mySemaphore.up(); } }
private boolean reportProblems( CompileContext context, Map<ProblemDescriptor, HighlightDisplayLevel> problemsMap) { if (problemsMap.isEmpty()) { return false; } boolean errorsReported = false; for (Map.Entry<ProblemDescriptor, HighlightDisplayLevel> entry : problemsMap.entrySet()) { ProblemDescriptor problemDescriptor = entry.getKey(); final PsiElement element = problemDescriptor.getPsiElement(); final PsiFile psiFile = element.getContainingFile(); if (psiFile == null) continue; final VirtualFile virtualFile = psiFile.getVirtualFile(); if (virtualFile == null) continue; final CompilerMessageCategory category = myValidator.getCategoryByHighlightDisplayLevel(entry.getValue(), virtualFile, context); final Document document = myPsiDocumentManager.getDocument(psiFile); final int offset = problemDescriptor.getStartElement().getTextOffset(); assert document != null; final int line = document.getLineNumber(offset); final int column = offset - document.getLineStartOffset(line); context.addMessage( category, problemDescriptor.getDescriptionTemplate(), virtualFile.getUrl(), line + 1, column + 1); if (CompilerMessageCategory.ERROR == category) { errorsReported = true; } } return errorsReported; }
public static boolean isModuleAffected(CompileContext context, Module module) { return ArrayUtil.find(context.getCompileScope().getAffectedModules(), module) >= 0; }
/** * A private helper routine to make the compiler code more sane. * * <p>This processes a single definition in a dependency tree. It works as a single step in a * breadth first traversal of the tree, accumulating children in the 'deps' set, and updating the * compile context with the current definition. * * <p>Note that once the definition has been retrieved, this code uses the 'canonical' descriptor * from the definition, discarding the incoming descriptor. * * @param descriptor the descriptor that we are currently handling, must not be in the compiling * defs. * @param cc the compile context to allow us to accumulate information. * @param deps the set of dependencies that we are accumulating. * @throws QuickFixException if the definition is not found, or validateDefinition() throws one. */ private <D extends Definition> D getHelper( DefDescriptor<D> descriptor, CompileContext cc, Set<DefDescriptor<?>> deps) throws QuickFixException { CompilingDef<D> cd = cc.getCompiling(descriptor); if (cd.def != null) { return cd.def; } try { if (!fillCompilingDef(cd, cc.context)) { // // At this point, we have failed to get the def, so we should throw an // error. The first stanza is to provide a more useful error description // including the set of components using the missing component. // if (!cd.parents.isEmpty()) { StringBuilder sb = new StringBuilder(); Location handy = null; for (Definition parent : cd.parents) { handy = parent.getLocation(); if (sb.length() != 0) { sb.append(", "); } sb.append(parent.getDescriptor().toString()); } throw new DefinitionNotFoundException(descriptor, handy, sb.toString()); } throw new DefinitionNotFoundException(descriptor); } // // Ok. We have a def. let's figure out what to do with it. // Set<DefDescriptor<?>> newDeps = Sets.newHashSet(); cd.def.appendDependencies(newDeps); // // FIXME: this code will go away with preloads. // This pulls in the context preloads. not pretty, but it works. // if (!cc.addedPreloads && cd.descriptor.getDefType().equals(DefType.APPLICATION)) { cc.addedPreloads = true; Set<String> preloads = cc.context.getPreloads(); for (String preload : preloads) { if (!preload.contains("_")) { DependencyDefImpl.Builder ddb = new DependencyDefImpl.Builder(); ddb.setResource(preload); ddb.setType("APPLICATION,COMPONENT,STYLE,EVENT"); ddb.build().appendDependencies(newDeps); } } } for (DefDescriptor<?> dep : newDeps) { if (!defs.containsKey(dep)) { CompilingDef<?> depcd = cc.getCompiling(dep); depcd.parents.add(cd.def); } } deps.addAll(newDeps); cc.dependencies.put(cd.descriptor, cd.def); return cd.def; } catch (DefinitionNotFoundException dnfe) { // // In the case that we have a DefinitionNotFoundException for our current descriptor, // cache the fact that we didn't find one. // if (dnfe.getDescriptor().equals(descriptor)) { cd.def = null; defs.put(descriptor, cd.def); if (cd.cacheable) { defsCache.put(descriptor, Optional.fromNullable(cd.def)); } } throw dnfe; } }
@Nullable public static String findResourcesCacheDirectory( @NotNull Module module, boolean createIfNotFound, @Nullable CompileContext context) { final Project project = module.getProject(); final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(project); if (extension == null) { if (context != null) { context.addMessage( CompilerMessageCategory.ERROR, "Cannot get compiler settings for project " + project.getName(), null, -1, -1); } return null; } final String projectOutputDirUrl = extension.getCompilerOutputUrl(); if (projectOutputDirUrl == null) { if (context != null) { context.addMessage( CompilerMessageCategory.ERROR, "Cannot find output directory for project " + project.getName(), null, -1, -1); } return null; } final String pngCacheDirPath = VfsUtil.urlToPath(projectOutputDirUrl) + '/' + RESOURCES_CACHE_DIR_NAME + '/' + module.getName(); final String pngCacheDirOsPath = FileUtil.toSystemDependentName(pngCacheDirPath); final File pngCacheDir = new File(pngCacheDirOsPath); if (pngCacheDir.exists()) { if (pngCacheDir.isDirectory()) { return pngCacheDirOsPath; } else { if (context != null) { context.addMessage( CompilerMessageCategory.ERROR, "Cannot create directory " + pngCacheDirOsPath + " because file already exists", null, -1, -1); } return null; } } if (!createIfNotFound) { return null; } if (!pngCacheDir.mkdirs()) { if (context != null) { context.addMessage( CompilerMessageCategory.ERROR, "Cannot create directory " + pngCacheDirOsPath, null, -1, -1); } return null; } return pngCacheDirOsPath; }
public static boolean isReleaseBuild(@NotNull CompileContext context) { final Boolean value = context.getCompileScope().getUserData(RELEASE_BUILD_KEY); return value != null && value.booleanValue(); }
private static GenerationItem[] doGenerate( @NotNull final CompileContext context, @NotNull final GenerationItem[] items, VirtualFile outputRootDirectory) { if (context.getProject().isDisposed()) { return EMPTY_GENERATION_ITEM_ARRAY; } // we have one item per module there, so clear output directory final String genRootPath = FileUtil.toSystemDependentName(outputRootDirectory.getPath()); final File genRootDir = new File(genRootPath); if (genRootDir.exists()) { if (!FileUtil.delete(genRootDir)) { context.addMessage( CompilerMessageCategory.ERROR, "Cannot delete directory " + genRootPath, null, -1, -1); return EMPTY_GENERATION_ITEM_ARRAY; } if (!genRootDir.mkdir()) { context.addMessage( CompilerMessageCategory.ERROR, "Cannot create directory " + genRootPath, null, -1, -1); return EMPTY_GENERATION_ITEM_ARRAY; } } final List<GenerationItem> results = new ArrayList<GenerationItem>(items.length); for (final GenerationItem item : items) { if (item instanceof MyGenerationItem) { final MyGenerationItem genItem = (MyGenerationItem) item; if (!AndroidCompileUtil.isModuleAffected(context, genItem.myModule)) { continue; } boolean success = true; for (final VirtualFile sourceFile : genItem.myFiles) { final String depFolderOsPath = getDependencyFolder(context.getProject(), sourceFile, outputRootDirectory); try { final Map<CompilerMessageCategory, List<String>> messages = AndroidCompileUtil.toCompilerMessageCategoryKeys( AndroidRenderscript.execute( genItem.mySdkLocation, genItem.myAndroidTarget, sourceFile.getPath(), genRootPath, depFolderOsPath, genItem.myRawDirPath)); ApplicationManager.getApplication() .runReadAction( new Runnable() { public void run() { if (context.getProject().isDisposed()) { return; } addMessages(context, messages, sourceFile.getUrl()); } }); if (messages.get(CompilerMessageCategory.ERROR).size() > 0) { success = false; } } catch (final IOException e) { ApplicationManager.getApplication() .runReadAction( new Runnable() { public void run() { if (context.getProject().isDisposed()) return; context.addMessage( CompilerMessageCategory.ERROR, e.getMessage(), sourceFile.getUrl(), -1, -1); } }); success = false; } } if (success) { results.add(genItem); } } } outputRootDirectory.refresh(false, true); return results.toArray(new GenerationItem[results.size()]); }
public static void generate(GeneratingCompiler compiler, final CompileContext context) { if (context == null) { return; } final Set<Module> affectedModules = new HashSet<Module>(); Collections.addAll(affectedModules, context.getCompileScope().getAffectedModules()); ApplicationManager.getApplication() .invokeAndWait( new Runnable() { @Override public void run() { for (Module module : affectedModules) { if (module.isDisposed() || module.getProject().isDisposed()) { continue; } final AndroidFacet facet = AndroidFacet.getInstance(module); if (facet != null) { AndroidCompileUtil.createGenModulesAndSourceRoots(facet); } } } }, ModalityState.defaultModalityState()); List<GeneratingCompiler.GenerationItem> itemsToGenerate = new ArrayList<GeneratingCompiler.GenerationItem>(); for (GeneratingCompiler.GenerationItem item : compiler.getGenerationItems(context)) { if (affectedModules.contains(item.getModule())) { itemsToGenerate.add(item); } } GeneratingCompiler.GenerationItem[] items = itemsToGenerate.toArray(new GeneratingCompiler.GenerationItem[itemsToGenerate.size()]); final boolean[] run = {true}; final VirtualFile[] files = getFilesToCheckReadonlyStatus(items); if (files.length > 0) { ApplicationManager.getApplication() .invokeAndWait( new Runnable() { @Override public void run() { ApplicationManager.getApplication() .runReadAction( new Runnable() { @Override public void run() { final Project project = context.getProject(); run[0] = !project.isDisposed() && ReadonlyStatusHandler.ensureFilesWritable(project, files); } }); } }, ModalityState.defaultModalityState()); } if (run[0]) { compiler.generate(context, items, null); } }
private static byte[] compileBytes( Rule rule, Class helperClass, String helperName, String compiledHelperName, boolean compileToBytecode) throws Exception { ClassWriter cw = new ClassWriter(0); FieldVisitor fv; MethodVisitor mv; AnnotationVisitor av0; // create the class as a subclass of the rule helper class, appending Compiled to the front // of the class name and a unique number to the end of the class helperName // also ensure it implements the HelperAdapter interface // // public class foo.bar.Compiled_<helper>_<NNN> extends foo.bar.<helper> implements // HelperAdapter cw.visit( V1_5, ACC_PUBLIC + ACC_SUPER, compiledHelperName, null, helperName, new String[] {"org/jboss/byteman/rule/helper/HelperAdapter"}); // we need to install the source file name { String fullFileName = rule.getFile(); int idx = fullFileName.lastIndexOf(java.io.File.separatorChar); String basicFileName = (idx < 0 ? fullFileName : fullFileName.substring(idx + 1)); String debug = "// compiled from: " + fullFileName + "\n// generated by Byteman\n"; cw.visitSource(basicFileName, debug); } { // we need a Hashmap field to hold the bindings // // private HashMap<String, Object> bindingMap; fv = cw.visitField( ACC_PRIVATE, "bindingMap", "Ljava/util/HashMap;", "Ljava/util/HashMap<Ljava/lang/String;Ljava/lang/Object;>;", null); fv.visitEnd(); } { // and a rule field to hold the rule // // private Rule rule; fv = cw.visitField( ACC_PRIVATE, "rule", "Lorg/jboss/byteman/rule/Rule;", "Lorg/jboss/byteman/rule/Rule;", null); fv.visitEnd(); } { // we need a constructor which takes a Rule as argument // if the helper implements a constructor which takes a Rule as argument then we invoke it // otherwise we invoke the empty helper constructor Constructor superConstructor = null; try { superConstructor = helperClass.getDeclaredConstructor(Rule.class); } catch (NoSuchMethodException e) { // hmm, ok see if there is an empty constructor } catch (SecurityException e) { throw new CompileException( "Compiler.compileBytes : unable to access constructor for helper class " + helperClass.getCanonicalName()); } boolean superWantsRule = (superConstructor != null); if (!superWantsRule) { try { superConstructor = helperClass.getDeclaredConstructor(); } catch (NoSuchMethodException e) { throw new CompileException( "Compiler.compileBytes : no valid constructor found for helper class " + helperClass.getCanonicalName()); } catch (SecurityException e) { throw new CompileException( "Compiler.compileBytes : unable to access constructor for helper class " + helperClass.getCanonicalName()); } } // // public Compiled<helper>_<NNN>()Rule rule) mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/jboss/byteman/rule/Rule;)V", null, null); mv.visitCode(); // super(); // // or // // super(Rule); if (superWantsRule) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, helperName, "<init>", "(Lorg/jboss/byteman/rule/Rule;)V"); } else { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, helperName, "<init>", "()V"); } // bindingMap = new HashMap<String, Object); mv.visitVarInsn(ALOAD, 0); mv.visitTypeInsn(NEW, "java/util/HashMap"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V"); mv.visitFieldInsn(PUTFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); // this.rule = rule mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); // return; mv.visitInsn(RETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { // create the execute method // // public void execute(Bindings bindings, Object recipient, Object[] args) throws // ExecuteException mv = cw.visitMethod( ACC_PUBLIC, "execute", "(Ljava/lang/Object;[Ljava/lang/Object;)V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // if (Transformer.isVerbose()) mv.visitMethodInsn(INVOKESTATIC, "org/jboss/byteman/agent/Transformer", "isVerbose", "()Z"); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); // then // System.out.println(rule.getName() + " execute"); mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getName", "()Ljava/lang/String;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitLdcInsn(" execute()"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); // end if mv.visitLabel(l0); Bindings bindings = rule.getBindings(); Iterator<Binding> iterator = bindings.iterator(); while (iterator.hasNext()) { Binding binding = iterator.next(); String name = binding.getName(); if (binding.isAlias()) { // lookups and updates will use the aliased name continue; } if (binding.isHelper()) { // bindingMap.put(name, this); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitLdcInsn(name); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); } else if (binding.isRecipient()) { // bindingMap.put(name, recipient); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitLdcInsn(name); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); // } else if (binding.isParam() || binding.isLocalVar() || binding.isReturn() || // binding.isThrowable() || binding.isParamCount() || binding.isParamArray()) // { } else if (!binding.isBindVar()) { // bindingMap.put(name, args[binding.getCallArrayIndex()]); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitLdcInsn(name); mv.visitVarInsn(ALOAD, 2); mv.visitLdcInsn(binding.getCallArrayIndex()); mv.visitInsn(AALOAD); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); } } // execute0() mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, compiledHelperName, "execute0", "()V"); // now restore update bindings iterator = bindings.iterator(); while (iterator.hasNext()) { Binding binding = iterator.next(); if (binding.isAlias()) { continue; } String name = binding.getName(); if (binding.isUpdated()) { // if (binding.isParam() || binding.isLocalVar() || binding.isReturn()) { if (!binding.isBindVar()) { int idx = binding.getCallArrayIndex(); // Object value = bindingMap.get(name); // args[idx] = value; mv.visitVarInsn(ALOAD, 2); // args mv.visitLdcInsn(idx); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitLdcInsn(name); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(AASTORE); } } } // return mv.visitInsn(RETURN); mv.visitMaxs(4, 3); mv.visitEnd(); } { // create the setBinding method // // public void setBinding(String name, Object value) mv = cw.visitMethod( ACC_PUBLIC, "setBinding", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null); mv.visitCode(); // bindingMap.put(name, value); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); // return mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } { // create the getBinding method // // public Object getBinding(String name) mv = cw.visitMethod( ACC_PUBLIC, "getBinding", "(Ljava/lang/String;)Ljava/lang/Object;", null, null); mv.visitCode(); // {TOS} <== bindingMap.get(name); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); // return {TOS} mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { // create the getName method // // public String getName() mv = cw.visitMethod(ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null); mv.visitCode(); // {TOS} <== rule.getName() mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getName", "()Ljava/lang/String;"); // return {TOS} mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } // create the getAccessibleField method // // public Object getAccessibleField(Object owner, int fieldIndex) { mv = cw.visitMethod( ACC_PUBLIC, "getAccessibleField", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, null); mv.visitCode(); // {TOS} <== rule.getAccessibleField(owner, fieldIndex); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getAccessibleField", "(Ljava/lang/Object;I)Ljava/lang/Object;"); // return {TOS} mv.visitInsn(ARETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } // create the setAccessibleField method // // public void setAccessibleField(Object owner, Object value, int fieldIndex) // rule.setAccessibleField(owner, value, fieldIndex); { mv = cw.visitMethod( ACC_PUBLIC, "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V", null, null); mv.visitCode(); // rule.setAccessibleField(owner, value, fieldIndex); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V"); // return mv.visitInsn(RETURN); mv.visitMaxs(4, 4); mv.visitEnd(); } // create the invokeAccessibleMethod method // // public Object invokeAccessibleMethod(Object target, Object[] args, int methodIndex) // {TOS} <== rule.invokeAccessibleMethod(target, args, methodIndex); { mv = cw.visitMethod( ACC_PUBLIC, "invokeAccessibleMethod", "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;", null, null); mv.visitCode(); // rule.invokeAccessibleMethod(target, args, fieldIndex); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "invokeAccessibleMethod", "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;"); // return {TOS} mv.visitInsn(ARETURN); mv.visitMaxs(4, 4); mv.visitEnd(); } if (compileToBytecode) { // we generate a single execute0 method if we want to run compiled and get // the event, condiiton and action to insert the relevant bytecode to implement // bind(), test() and fire() { // create the execute0() method // // private void execute0() mv = cw.visitMethod( ACC_PRIVATE, "execute0", "()V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); CompileContext compileContext = new CompileContext(mv); // make sure we set the first line number before generating any code compileContext.notifySourceLine(rule.getLine()); compileContext.addLocalCount(3); // for this and 2 object args // bind(); rule.getEvent().compile(mv, compileContext); // if (test()) rule.getCondition().compile(mv, compileContext); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); compileContext.addStackCount(-1); // then rule.getAction().compile(mv, compileContext); // fire(); // end if mv.visitLabel(l0); // this will match the ENDRULE line compileContext.notifySourceEnd(); // return mv.visitInsn(RETURN); // need to specify correct Maxs values mv.visitMaxs(compileContext.getStackMax(), compileContext.getLocalMax()); mv.visitEnd(); } } else { // we generate the following methods if we want to run interpreted { // create the execute0() method // // private void execute0() mv = cw.visitMethod( ACC_PRIVATE, "execute0", "()V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // bind(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "bind", "()V"); // if (test()) mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "test", "()Z"); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); // then // fire(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "fire", "()V"); // end if mv.visitLabel(l0); // return mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { // create the bind method // // private void bind() mv = cw.visitMethod( ACC_PRIVATE, "bind", "()V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // rule.getEvent().interpret(this); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getEvent", "()Lorg/jboss/byteman/rule/Event;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Event", "interpret", "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;"); mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { // create the test method // // private boolean test() mv = cw.visitMethod( ACC_PRIVATE, "test", "()Z", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // {TOS} <== rule.getCondition().interpret(this); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getCondition", "()Lorg/jboss/byteman/rule/Condition;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Condition", "interpret", "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;"); mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean"); // unbox the returned Boolean mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); // return {TOS} mv.visitInsn(IRETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { // create the fire method // // private void fire() mv = cw.visitMethod( ACC_PRIVATE, "fire", "()V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // rule.getAction().interpret(this); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getAction", "()Lorg/jboss/byteman/rule/Action;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Action", "interpret", "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;"); // return mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } } cw.visitEnd(); return cw.toByteArray(); }