Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2010-07-22 22:09:37 +0000
committerStephan Herrmann2010-07-22 22:09:37 +0000
commit9a06c38edca4e454a99e6ab52188201654353ccb (patch)
tree9ed25fcafa7c4e82683a7fdf5bc8ded186666971 /othersrc
parent368dbb02c7f2143f6d6249d36600acd1099dba25 (diff)
downloadorg.eclipse.objectteams-9a06c38edca4e454a99e6ab52188201654353ccb.tar.gz
org.eclipse.objectteams-9a06c38edca4e454a99e6ab52188201654353ccb.tar.xz
org.eclipse.objectteams-9a06c38edca4e454a99e6ab52188201654353ccb.zip
Project is no longer needed, content was moved to plugins/org.eclipse.objectteams.runtime
Diffstat (limited to 'othersrc')
-rw-r--r--othersrc/OTRE/.classpath7
-rw-r--r--othersrc/OTRE/.project17
-rw-r--r--othersrc/OTRE/.settings/org.eclipse.jdt.core.prefs70
-rw-r--r--othersrc/OTRE/MANIFEST.MF5
-rw-r--r--othersrc/OTRE/about.html28
-rw-r--r--othersrc/OTRE/otre-src-jar.jardesc16
-rw-r--r--othersrc/OTRE/otre_agent.jardesc14
-rw-r--r--othersrc/OTRE/otre_min.jardesc16
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseCallRedirection.java1455
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java1907
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/ClassEnhancer.java79
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/Decapsulation.java417
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java182
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/OTConstants.java181
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/OTREInternalError.java62
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java2266
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/RepositoryAccess.java125
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java756
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java174
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java1004
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/ThreadActivation.java181
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java143
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java272
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/otreAgent.java48
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AnnotationHelper.java102
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java80
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundClass.java80
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundMethod.java48
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/CallinBindingManager.java1323
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/DebugUtil.java155
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/FieldDescriptor.java53
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/ListValueHashMap.java103
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/MethodBinding.java395
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/RoleBaseBinding.java228
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/SuperMethodDescriptor.java33
-rw-r--r--othersrc/OTRE/src/org/eclipse/objectteams/otre/util/TeamIdDispenser.java69
-rw-r--r--othersrc/OTRE/src/org/objectteams/DoublyWeakHashMap.java106
-rw-r--r--othersrc/OTRE/src/org/objectteams/DuplicateRoleException.java48
-rw-r--r--othersrc/OTRE/src/org/objectteams/IBaseMigratable.java35
-rw-r--r--othersrc/OTRE/src/org/objectteams/IBoundBase.java28
-rw-r--r--othersrc/OTRE/src/org/objectteams/IConfined.java24
-rw-r--r--othersrc/OTRE/src/org/objectteams/ILiftingParticipant.java40
-rw-r--r--othersrc/OTRE/src/org/objectteams/ITeam.java206
-rw-r--r--othersrc/OTRE/src/org/objectteams/ITeamMigratable.java36
-rw-r--r--othersrc/OTRE/src/org/objectteams/IllegalRoleCreationException.java35
-rw-r--r--othersrc/OTRE/src/org/objectteams/ImplicitTeamActivation.java45
-rw-r--r--othersrc/OTRE/src/org/objectteams/LiftingFailedException.java46
-rw-r--r--othersrc/OTRE/src/org/objectteams/LiftingVetoException.java45
-rw-r--r--othersrc/OTRE/src/org/objectteams/ResultNotProvidedException.java61
-rw-r--r--othersrc/OTRE/src/org/objectteams/RoleCastException.java39
-rw-r--r--othersrc/OTRE/src/org/objectteams/Team.java520
-rw-r--r--othersrc/OTRE/src/org/objectteams/TeamThreadManager.java121
-rw-r--r--othersrc/OTRE/src/org/objectteams/UnsupportedFeatureException.java60
-rw-r--r--othersrc/OTRE/src/org/objectteams/WrongRoleException.java57
54 files changed, 0 insertions, 13646 deletions
diff --git a/othersrc/OTRE/.classpath b/othersrc/OTRE/.classpath
deleted file mode 100644
index 3532c7495..000000000
--- a/othersrc/OTRE/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
- <classpathentry combineaccessrules="false" kind="src" path="/org.apache.bcel"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/othersrc/OTRE/.project b/othersrc/OTRE/.project
deleted file mode 100644
index 9f6b8319b..000000000
--- a/othersrc/OTRE/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>OTRE</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
diff --git a/othersrc/OTRE/.settings/org.eclipse.jdt.core.prefs b/othersrc/OTRE/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 1aa712415..000000000
--- a/othersrc/OTRE/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,70 +0,0 @@
-#Thu Sep 18 21:57:35 CEST 2008
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.5
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.5
diff --git a/othersrc/OTRE/MANIFEST.MF b/othersrc/OTRE/MANIFEST.MF
deleted file mode 100644
index c759b23fd..000000000
--- a/othersrc/OTRE/MANIFEST.MF
+++ /dev/null
@@ -1,5 +0,0 @@
-Manifest-Version: 1.0
-Premain-Class: org.eclipse.objectteams.otre.jplis.otreAgent
-Can-Redefine-Classes: true
-Built-By: resix
-
diff --git a/othersrc/OTRE/about.html b/othersrc/OTRE/about.html
deleted file mode 100644
index 47048bd42..000000000
--- a/othersrc/OTRE/about.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
-<title>About</title>
-</head>
-<body lang="EN-US">
-<h2>About This Content</h2>
-
-<p>Feb 3, 2010</p>
-<h3>License</h3>
-
-<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
-indicated below, the Content is provided to you under the terms and conditions of the
-Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
-at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
-
-<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
-being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
-apply to your use of any object code in the Content. Check the Redistributor's license that was
-provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
-indicated below, the terms and conditions of the EPL still apply to any source code in the Content
-and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
-
-</body>
-</html> \ No newline at end of file
diff --git a/othersrc/OTRE/otre-src-jar.jardesc b/othersrc/OTRE/otre-src-jar.jardesc
deleted file mode 100644
index 755677629..000000000
--- a/othersrc/OTRE/otre-src-jar.jardesc
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<jardesc>
- <jar path="org.eclipse.objectteams.runtime/lib/otre.jar"/>
- <options buildIfNeeded="true" compress="true" descriptionLocation="/OTRE/otre-src-jar.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
- <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
- <selectedProjects/>
- <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
- <sealing sealJar="false">
- <packagesToSeal/>
- <packagesToUnSeal/>
- </sealing>
- </manifest>
- <selectedElements exportClassFiles="false" exportJavaFiles="true" exportOutputFolder="true">
- <javaElement handleIdentifier="=OTRE/src"/>
- </selectedElements>
-</jardesc>
diff --git a/othersrc/OTRE/otre_agent.jardesc b/othersrc/OTRE/otre_agent.jardesc
deleted file mode 100644
index cf1515f36..000000000
--- a/othersrc/OTRE/otre_agent.jardesc
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<jardesc>
- <jar path="org.eclipse.objectteams.otdt/lib/otre_agent.jar"/>
- <options overwrite="false" compress="true" exportErrors="false" exportWarnings="true" saveDescription="true" descriptionLocation="/OTRE/otre_agent.jardesc" useSourceFolders="false" buildIfNeeded="true"/>
- <manifest manifestVersion="1.0" usesManifest="true" reuseManifest="false" saveManifest="false" generateManifest="false" manifestLocation="/OTRE/MANIFEST.MF">
- <sealing sealJar="false">
- <packagesToSeal/>
- <packagesToUnSeal/>
- </sealing>
- </manifest>
- <selectedElements exportClassFiles="true" exportOutputFolder="false" exportJavaFiles="false">
- <javaElement handleIdentifier="=OTRE/src&lt;org.eclipse.objectteams.otre.jplis{otreAgent.java"/>
- </selectedElements>
-</jardesc>
diff --git a/othersrc/OTRE/otre_min.jardesc b/othersrc/OTRE/otre_min.jardesc
deleted file mode 100644
index 9eded8f00..000000000
--- a/othersrc/OTRE/otre_min.jardesc
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<jardesc>
- <jar path="org.eclipse.objectteams.otdt/lib/otre_min.jar"/>
- <options buildIfNeeded="true" compress="true" descriptionLocation="/OTRE/otre_min.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
- <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
- <selectedProjects/>
- <manifest generateManifest="false" manifestLocation="/OTRE/MANIFEST.MF" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
- <sealing sealJar="false">
- <packagesToSeal/>
- <packagesToUnSeal/>
- </sealing>
- </manifest>
- <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
- <javaElement handleIdentifier="=OTRE/src&lt;org.objectteams"/>
- </selectedElements>
-</jardesc>
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseCallRedirection.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseCallRedirection.java
deleted file mode 100644
index 9766c82bd..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseCallRedirection.java
+++ /dev/null
@@ -1,1455 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: BaseCallRedirection.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import org.apache.bcel.classfile.*;
-import org.apache.bcel.generic.*;
-import org.apache.bcel.*;
-
-import java.util.*;
-
-import org.eclipse.objectteams.otre.util.*;
-
-/**
- * for callin-role-methods with recursive method-calls (base calls) we add a
- * method with extendend signature.
- * Within the extendend method recursive calls are replaced by the corresponding
- * (chaining)base-call.<p>
- * For example:
- * <pre>
- * callin m1() { m1(); } -->
- * callin m1(Team _OT$teams[], int _OT$teamIDs[],
- * int _OT$idx, int _OT$baseMethTag){
- * liftToRole(b1._OT$m1$chain(Team _OT$teams[],
- * int _OT$teamIDs[],
- * int _OT$idx,
- * int _OT$baseMethTag));
- * }
- * </pre>
- *
- * @version $Id: BaseCallRedirection.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-public class BaseCallRedirection extends ObjectTeamsTransformation {
-
- static class IHPair {
- private InstructionHandle _ih1, _ih2;
- public IHPair (InstructionHandle ih1, InstructionHandle ih2) {
- _ih1 = ih1;
- _ih2 = ih2;
- }
- public InstructionHandle fst() {return _ih1; }
- public InstructionHandle snd() {return _ih2; }
- }
-
- public BaseCallRedirection(ClassLoader loader, SharedState state) {
- super(loader, state);
- }
-
- /**
- * @param ce
- * @param cg
- */
- public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
- factory = new InstructionFactory(cg);
- String class_name = cg.getClassName();
-
- if (state.interfaceTransformedClasses.contains(class_name)) {
- return; //already transformed!
- }
-
- ConstantPoolGen cpg = cg.getConstantPool();
- checkReadClassAttributes(ce, cg, class_name, cpg);
-
- if (!CallinBindingManager.isRole(class_name)) {
- return;
- }
-
- if (!cg.isInterface()) {
- Set<String> boundBaseMethods = CallinBindingManager.getBoundRoleMethods(class_name);
- addBaseCallSurrogatesForReplaceBindings(ce, boundBaseMethods, cg);
- }
-
- Method[] methods = cg.getMethods();
- for (int i=0; i<methods.length; i++) {
- Method m = methods[i];
- String method_name = m.getName();
- String method_signature = m.getSignature();
-
- if (candidateForImplicitActivation(m, cg, cpg)) { // TODO: check the other preconditions, like not abstact etc.
- cg.replaceMethod(m, genImplicitActivation(m, class_name, cpg, true));
- }
-
- if (!isCallin(m, cg))
- continue;
- if (logging) printLogMessage(method_name + " in " + class_name
- + " IS A CALLIN-METHOD!");
- if (method_name.startsWith(OT_PREFIX)) {
- method_name = revertToOriginalName(method_name);
- if (logging) printLogMessage("Reverted tsuper name to " + method_name);
- }
- // code SHOULD contain at least one base call.
- if(logging) printLogMessage("----->will add another method " + method_name
- + " with enhanced signature");
-
-//{SH: retrench signature because otherwise the binding will not be found,
-// as a result an empty basecall surrogate will be generated leading to repetetive methods...
-// TODO(SH) is this the proper way to retrench??
- String enhancedPrefix = "([Lorg/objectteams/Team;[IIII[Ljava/lang/Object;";
- if (method_signature.startsWith(enhancedPrefix))
- method_signature = "("+method_signature.substring(enhancedPrefix.length());
-// SH}
-
- boolean roleMethodIsBound = CallinBindingManager.roleMethodHasBinding(class_name,
- method_name,
- method_signature);
-
- //if (mbs.isEmpty()) {
- if (!roleMethodIsBound) {
- if (logging) printLogMessage("callin method " + method_name
- + " was not bound in this class!!!");
- }
- MethodGen baseCallSurrogate = null;
- if (!IS_COMPILER_13X_PLUS) { // since 1.3.0 this part is legacy:
- if (!roleMethodIsBound && !methodHasCallinFlags(m, cg, OVERRIDING) && !m.isStatic()) {
- // method not bound in current class and doesn't inherit a base call surrogate
- baseCallSurrogate = generateEmptyBaseCallSurrogate(cg, m);
- }
- if (baseCallSurrogate != null)
- ce.addMethod(baseCallSurrogate.getMethod(), cg);
- }
-
- }
- state.interfaceTransformedClasses.add(class_name);
- }
-
- /**
- * Generates an "empty" base call surrogate method, which just throws an 'Error'.
- * This method should normaly never be called, but overwritten in a subclass.
- * It has to be generated just for the wellformedness of the class file.
- * @param cg
- * @param m
- * @param mbs
- * @param baseClassName
- * @return
- */
- private MethodGen generateEmptyBaseCallSurrogate(ClassGen cg, Method m/*, List mbs*/) {
- if (m.getName().startsWith(OT_PREFIX))
- return null; // ot-internal methods don't need this?
-
- ConstantPoolGen cpg = cg.getConstantPool();
- String class_name = cg.getClassName();
- MethodGen mg = newMethodGen(m, class_name, cpg);
-
- if (isTSuperWrapper(mg)) {
- // tsuper wrapper do not need base call surrogates
- return null;
- }
-
- // role method already was enhanced by compiler
- Type[] enhancedArgumentTypes = mg.getArgumentTypes();
- if (IS_COMPILER_GREATER_123) {
- // add super flag between enhancement and real arguments:
- int len = enhancedArgumentTypes.length;
- Type[] newArgumentTypes = new Type[len+1];
- System.arraycopy(enhancedArgumentTypes, 0, newArgumentTypes, 0, EXTRA_ARGS);
- newArgumentTypes[EXTRA_ARGS] = Type.BOOLEAN;
- System.arraycopy(enhancedArgumentTypes, EXTRA_ARGS, newArgumentTypes, EXTRA_ARGS+1, len-EXTRA_ARGS);
- enhancedArgumentTypes = newArgumentTypes;
- }
- Type enhancedReturnType = mg.getReturnType();
-
-// {SH: interface method has no argument names? generate dummy names:
- String[] argumentNames = new String[enhancedArgumentTypes.length];
- for (int i = 0; i < argumentNames.length; i++) {
- argumentNames[i] = "arg"+i;
- }
-
- // role method already was enhanced by compiler:
- String[] enhancedArgumentNames = argumentNames;
-// }
- InstructionList il = new InstructionList();
- //int accessFlags = m.getAccessFlags();
- int accessFlags = Constants.ACC_PROTECTED; // no unanticipated calls possible
-
-// {SH: interface methods must be public abstract:
- if (cg.isInterface())
- accessFlags = Constants.ACC_ABSTRACT|Constants.ACC_PUBLIC;
-// }
-
- MethodGen baseCallSurrogate = new MethodGen(accessFlags,
- enhancedReturnType,
- enhancedArgumentTypes,
- enhancedArgumentNames,
- getBaseCallSurrogateName(m.getName(), m.isStatic(), class_name /*genRoleInterfaceName(class_name)*/),
- class_name,
- il, cpg);
-// {SH: no code for interface method:
- if (!cg.isInterface()) {
- // orig:
- if (logging)
- printLogMessage("Exception has to be thrown!");
-
- createThrowInternalError(cpg, il, new InstructionList(new PUSH(cpg, "Binding-Error: base-call impossible!")));
-
- il.append(InstructionFactory.createNull(enhancedReturnType));
- il.append(InstructionFactory.createReturn(enhancedReturnType));
-
- if (debugging)
- baseCallSurrogate.addLineNumber(il.getStart(), STEP_OVER_LINENUMBER);
- }
-// }
-
- il.setPositions();
- baseCallSurrogate.removeNOPs();
- baseCallSurrogate.setMaxStack();
- baseCallSurrogate.setMaxLocals();
- return baseCallSurrogate;
- }
-
- /**
- * @param mg
- * @return
- */
- private static boolean isTSuperWrapper(MethodGen mg) {
- Type[] argTypes = mg.getArgumentTypes();
- if (argTypes.length == 0) {
- return false; // no tsuper marker interface argument existing
- }
- String lastArgument = (argTypes[argTypes.length - 1]).toString();
- return lastArgument.contains(OTDT_PREFIX);
- }
-
- /**
- * Adds base call surrogate method for all role method bindings in the current role class.
- * Thereby method bindings which are defined in super roles are accumulated and
- * considered as well.
- * @param ce the ClassEnhancer to which the new method has to be added
- * @param boundRoleMethods the bound methods of the role class
- * @param cg the ClassGen for the role class
- */
- private void addBaseCallSurrogatesForReplaceBindings(ClassEnhancer ce, Set<String> boundRoleMethods, ClassGen cg)
- {
- Iterator<String> it = boundRoleMethods.iterator();
- while (it.hasNext()) {
- String nameAndSignature = it.next();
- int dotIndex = nameAndSignature.indexOf('.');
- String methodName = nameAndSignature.substring(0, dotIndex);
- String methodSignature = nameAndSignature.substring(dotIndex + 1);
- List<MethodBinding> mbs = CallinBindingManager.getBindingsForRoleMethod(cg.getClassName(),
- methodName,
- methodSignature);
- MethodBinding anyMethodBinding = mbs.get(0);
- if (!anyMethodBinding.isReplace()) {
- continue;
- }
- mbs.addAll(CallinBindingManager.getInheritedRoleMethodBindings(cg.getClassName(),
- methodName,
- methodSignature));
-
- if (anyMethodBinding.hasStaticRoleMethod())
- continue; // base call surrogates for static methods are generated within the enclosing team class
- // TODO: remove this check as soon as static replace method bindings are no longer in 'CallinMethodMappings'
- MethodGen baseCallSurrogate = genBaseCallSurrogate(cg, mbs);
- ce.addOrReplaceMethod(baseCallSurrogate.getMethod(), cg);
- }
- }
-
- /**
- * Generates base call surrogate method for the role method for which the method bindings 'mbs' are.
- * Thereby a switch-case for each bound base method is generated.
- * This method is only for nonstatic role methods. Base call surrogates for static methods
- * are generated within the enclosing team class
- * @param cg the ClassGen for the role class
- * @param mbs the method bindings for one role method
- * @param baseClassName the name of the base class
- */
- MethodGen genBaseCallSurrogate(ClassGen cg, List<MethodBinding> mbs) {
-
- //baseClassName would not be needed here, if I could find out the root-base-class-type...
- ConstantPoolGen cpg = cg.getConstantPool();
- String class_name = cg.getClassName();
-
- MethodBinding anyBindingForRoleMethod = mbs.get(0);
- String baseClassName = anyBindingForRoleMethod.getRootBoundBase();
- String roleMethodSignature = anyBindingForRoleMethod.getRoleMethodSignature();
-
- Type[] enhancedArgumentTypes;
- {
- Type[] argTypesTail = Type.getArgumentTypes(roleMethodSignature);
- if (IS_COMPILER_GREATER_123) {
- // add super flag between enhancement and real arguments:
- int len = argTypesTail.length;
- System.arraycopy(argTypesTail, 0, argTypesTail=new Type[len+1], 1, len);
- argTypesTail[0] = Type.BOOLEAN;
- }
- enhancedArgumentTypes = enhanceArgumentTypes(argTypesTail);
- }
- Type enhancedReturnType = generalizeReturnType(Type.getReturnType(roleMethodSignature));
- String methodName = anyBindingForRoleMethod.getRoleMethodName();
- InstructionList il = new InstructionList();
- int accessFlags = Constants.ACC_PROTECTED;
-
- MethodGen baseCallSurrogate = new MethodGen(accessFlags,
- enhancedReturnType,
- enhancedArgumentTypes,
- null, // no explicit names
- getBaseCallSurrogateName(methodName, false,
- genRoleInterfaceName(class_name)),
- class_name,
- il, cpg);
-
- ObjectType baseClass = new ObjectType(baseClassName);
- ObjectType outerClass;
- {
- String outerClassName = getOuterClassName(class_name);
- outerClass = new ObjectType(outerClassName);
- }
-
- LocalVariableGen otResult = null;
-
- otResult = baseCallSurrogate.addLocalVariable("_OT$result",
- enhancedReturnType, null, null);
-
- il.insert(InstructionFactory.createStore(enhancedReturnType,
- otResult.getIndex()));
- il.insert(new ACONST_NULL());
- il.setPositions(); // about to retrieve instruction handles.
-
- if (logging) printLogMessage("base-call switch has to be inserted!");
- InstructionList loading = new InstructionList();
- loading.append(InstructionFactory.createThis());
- int index = 1;
- for (int i = 0; i < enhancedArgumentTypes.length; i++) {
- loading.append(InstructionFactory.createLoad(enhancedArgumentTypes[i],index));
- index += enhancedArgumentTypes[i].getSize();
- }
-
- Type[] argumentTypes = Type.getArgumentTypes(roleMethodSignature);
- Type returnType = Type.getReturnType(roleMethodSignature);
-
- if (debugging) {
- baseCallSurrogate.addLineNumber(il.getStart(), STEP_OVER_LINENUMBER);
- }
-
- boolean generateSuperAccess = false;
- List<SuperMethodDescriptor> superAccesses = IS_COMPILER_GREATER_123 ? CallinBindingManager.getSuperAccesses(baseClassName) : null;
- if (superAccesses != null) {
- outer: for (SuperMethodDescriptor superMethod : superAccesses) {
- for (MethodBinding methodBinding : mbs) {
- if ( superMethod.methodName.equals(methodBinding.getBaseMethodName())
- && superMethod.signature.equals(methodBinding.getBaseMethodSignature()))
- {
- generateSuperAccess = true;
- break outer;
- }
- }
- }
- }
-
- BranchInstruction ifSuper = new IFEQ(null);
- GotoInstruction skipElse = new GOTO(null);
- if (generateSuperAccess) {
- // gen: if (isSuperAccess) { _OT$base._OT$m$super(args); } else ...
- il.append(InstructionFactory.createLoad(Type.BOOLEAN, EXTRA_ARGS+1)); // last synthetic arg is super-flag
- il.append(ifSuper);
- il.append(genBaseCallSwitch(cpg, mbs, baseCallSurrogate,
- argumentTypes,
- outerClass, baseClass,
- returnType,
- otResult, loading, true));
- il.append(skipElse);
- }
- InstructionList
- basecall = genBaseCallSwitch(cpg, mbs, baseCallSurrogate,
- argumentTypes,
- outerClass, baseClass,
- returnType,
- otResult, loading, false);
- InstructionHandle callStart = basecall.getStart(); // store handle before append eats the list
- il.append(basecall);
- if (generateSuperAccess) {
- ifSuper.setTarget(callStart);
- skipElse.setTarget(il.append(new NOP()));
- }
-
- il.append(InstructionFactory.createLoad(enhancedReturnType, otResult.getIndex()));
- il.append(InstructionFactory.createReturn(enhancedReturnType));
-
- il.setPositions();
- baseCallSurrogate.removeNOPs();
- baseCallSurrogate.setMaxStack();
- baseCallSurrogate.setMaxLocals();
- return baseCallSurrogate;
- }
-
-/*
- Type findBaseFieldType(JavaClass c, ConstantPoolGen cpg) {
- Field[] fields = c.getFields();
- for (int l=0; l<fields.length; l++) {
- Field f = fields[l];
- if (f.getName().equals(BASE)) {
- FieldGen fg = new FieldGen(f, cpg);
- return fg.getType();
- }
- }
- JavaClass superClass = Repository.lookupClass(c.getSuperclassName());
- // BCEL bug: super class of "Object" is "Object":
- //System.err.println("Superclass of "+ c.getClassName()+" is " +c.getSuperclassName());
- if (!superClass.getClassName().equals("java.lang.Object")) {
- return findBaseFieldType(superClass, cpg);
- }
- return null;
- }*/
-
- /**
- * Iterate through the instructions of a callin method.
- * <ul>
- * <li>Adjust local variable instructions due to inserted extra arguments.
- * <li>Replace base-calls and calls to activate.
- * </ul>
- * @param cg
- * @param m
- * @param mbs List<MethodBinding>
- * @return MethodGen
- */
- MethodGen replaceBaseCalls(ClassGen cg, Method m, List<MethodBinding> mbs) {
-
- int indexOffset = m.isStatic() ? -1 : 0; // argument indices are decremented for static methods,
- // because of the missing 'this'
-
- ConstantPoolGen cpg = cg.getConstantPool();
- String class_name = cg.getClassName();
- String method_name = m.getName();
-
- MethodGen mg = newMethodGen(m, class_name, cpg);
-
- Type[] argumentTypes = mg.getArgumentTypes();
- Type returnType = mg.getReturnType();
-
- Type[] enhancedArgumentTypes = enhanceArgumentTypes(mg.getArgumentTypes());
-// {SH abstract methods may not have argument names??
- String[] argumentNames;
- if (m.isAbstract()) {
- argumentNames = new String[argumentTypes.length];
- int index = 0;
- for (int i = 0; i < argumentNames.length; i++) {
- argumentNames[i] = "arg" + index/* i */;
- index += argumentTypes[i].getSize();
- }
-
-/*
-// load regular arguments:
- int index = 1;
- for (int i=0; i<argTypes.length; i++) {
- il.append(InstructionFactory.createLoad(argTypes[i],index));
- index += argTypes[i].getSize();
- }
-//*/
-
- } else {
- argumentNames = mg.getArgumentNames();
- }
- String[] enhancedArgumentNames = enhanceArgumentNames(argumentNames);
-// orig: String[] enhancedArgumentNames = enhanceArgumentNames(mg.getArgumentNames());
-// SH}
-
- Type enhancedMethodReturnType = generalizeReturnType(m.getSignature());
-
-// {SH instruction list may be null for abstract method
-// orig: InstructionList il = mg.getInstructionList().copy();
- InstructionList il = mg.getInstructionList();
- if (il != null)
- il = il.copy();
- else
- il = new InstructionList();
-// SH}
-
- MethodGen enhancedMethod = new MethodGen(m.getAccessFlags(),
- enhancedMethodReturnType,
- enhancedArgumentTypes,
- enhancedArgumentNames,
- method_name, class_name,
- il, cpg);
- //not needed??:
- // or not??????
- copyLocalVariables(mg, enhancedMethod);
- copyLineNumbers(mg, enhancedMethod);
-
- boolean returnValueAdded = (returnType == Type.VOID)
- && (enhancedMethodReturnType != Type.VOID);
-
- // all exception handlers of this method, which have to be updated later.
- CodeExceptionGen [] handlers = copyExceptionHandlers(mg, enhancedMethod, il);
- // list of instruction handles (old and new) that are replaced in the sequel
- ArrayList<IHPair> replacedInstructions = new ArrayList<IHPair>(); // of IHPair;
- // set of instruction handles which signal TargetLostException during delete().
- HashSet<InstructionHandle> targetLost = new HashSet<InstructionHandle>(); // of InstructionHandle
-
- // create LocalVariable Object _OT$result:
- LocalVariableGen otResult = null;
-
- int slot = mg.getMaxLocals() + EXTRA_ARGS-indexOffset;
- otResult = enhancedMethod.addLocalVariable("_OT$result", enhancedMethodReturnType,
- slot, null, null);
-
- // subtract EXTRA_ARGS since this offset will be added again below.
- il.insert(InstructionFactory.createStore(enhancedMethodReturnType,
- otResult.getIndex() - EXTRA_ARGS));
-
- il.insert(new ACONST_NULL());
- il.setPositions(); // about to retrieve instruction handles.
-
- InstructionHandle[] ihs = il.getInstructionHandles();
- //printLogMessage("every call of base." + method_name + "(...) will be replaced by "
- // + liftMethodName + BASE + "."+baseChainMethodName+"(...))");
-
- int actInstruction = 0;
- int offset = EXTRA_ARGS;
- while (actInstruction < ihs.length) {
- Instruction act_instruction = ihs[actInstruction].getInstruction();
-/****************************** variable index adaption: **********************************/
- if(act_instruction instanceof LocalVariableInstruction) {
- // add offset to the index of every variable load or store instruction,
- // because of the inserted EXTRA_ARGS arguments:
- LocalVariableInstruction localVariableInstruction = (LocalVariableInstruction) act_instruction;
- if (localVariableInstruction.getIndex() != 0 || (enhancedMethod.isStatic())) { // 'this' stays at index 0
- if (localVariableInstruction instanceof StoreInstruction) {
- localVariableInstruction =
- InstructionFactory.createStore(localVariableInstruction.getType(cpg),
- offset+localVariableInstruction.getIndex());
- } else if (localVariableInstruction instanceof LoadInstruction) {
- localVariableInstruction =
- InstructionFactory.createLoad(localVariableInstruction.getType(cpg),
- offset+localVariableInstruction.getIndex());
- } else if (localVariableInstruction instanceof IINC) {
- localVariableInstruction.setIndex(offset+localVariableInstruction.getIndex());
- // TODO: check, if this is enough for all kinds of LocalVariableInstructions
- // and if there are more instructions which use variable indizes!!
- }
- ihs[actInstruction].setInstruction(localVariableInstruction);
- }
- } else if (act_instruction instanceof RET) {
- RET ret = (RET)act_instruction;
- if (ret.getIndex() != 0)
- ihs[actInstruction].setInstruction(new RET(offset + ret.getIndex()));
-
-/*************************** "super"- & "tsuper"-call enhancement: **********************************/
- } else if (super_or_tsuper_instruction(act_instruction, method_name, cpg) ) {
-
- InvokeInstruction ii = (InvokeInstruction)act_instruction;
- InstructionHandle next = ihs[actInstruction+1];
- InstructionList changedArea;
- InstructionHandle[] delim = new InstructionHandle[2];
- int stackDepth = computeArgumentStackDepth(cpg, ii);
- InstructionList loading = pruneLoading(il, ihs, actInstruction,
- stackDepth, cpg,
- targetLost, delim, true);
- if (loading == null) {
- actInstruction++;
- continue;
- }
-
- changedArea = genEnhancedSuperCall(cpg, ii, enhancedMethod, loading);
- if (returnValueAdded) {
- changedArea.append(InstructionFactory.createStore(
- enhancedMethodReturnType, otResult.getIndex()));
- } else {
- InstructionHandle ih = adjustValue(changedArea, changedArea.getEnd(), enhancedMethodReturnType, returnType);
- if (debugging && ih != null)
- mg.addLineNumber(ih, STEP_OVER_LINENUMBER);
- }
- replacedInstructions.add(new IHPair(delim[0], changedArea.getStart()));
- replacedInstructions.add(new IHPair(delim[1], changedArea.getEnd()));
-
- il.insert(next, changedArea);
- actInstruction++;
- continue;
-
-/*************************** "activate" substitution and base-call generation: ************/
- //} else if (act_instruction instanceof INVOKEVIRTUAL) {
- // INVOKEVIRTUAL iv = (INVOKEVIRTUAL)act_instruction;
- } else if (act_instruction instanceof InvokeInstruction) {
- InvokeInstruction iv = (InvokeInstruction)act_instruction;
- String iv_name = iv.getName(cpg);
-
- // FIXME(SH): is this still needed?
- // - activate is commented-out,
- // - base call is now generated by the compiler.
- if(!(iv_name.equals(method_name) ||
- iv_name.equals("activate")))
- {
- actInstruction++;
- continue;
- }
- InstructionHandle next = ihs[actInstruction+1];
- InstructionList changedArea;
- InstructionHandle[] delim = new InstructionHandle[2];
- /*
- if (iv_name.equals("activate")) {
- // blank original invokevirtual:
- ihs[actInstruction].setInstruction(new NOP());
- Type [] ivArgTypes = iv.getArgumentTypes(cpg);
- int activateArgCount = ivArgTypes.length;
- InstructionList loading = null;
- if (activateArgCount == 1)
- loading = pruneLoading (il, ihs, actInstruction,
- ivArgTypes[0].getSize(), cpg,
- targetLost, delim, false);
- changedArea = enhanceActivateCall(factory, cpg, loading, iv);
- if (activateArgCount == 1) {
- replacedInstructions.add(new IHPair(delim[0],
- changedArea.getStart()));
- replacedInstructions.add(new IHPair(delim[1],
- changedArea.getEnd()));
- }
- } else*/ { // base call:
- int stackDepth = computeArgumentStackDepth(cpg, iv);
- boolean deleteThis = true;
-
- if(enhancedMethod.isStatic())
- deleteThis = false;
-
- /*
- if (iv.getOpcode()==Constants.INVOKESTATIC)
- deleteThis = false;
- */
- InstructionList loading = pruneLoading(il, ihs, actInstruction,
- stackDepth, cpg,
- targetLost, delim, /*true*/deleteThis);
- //System.err.println(loading);
- if (loading == null) {
- actInstruction++;
- continue;
- }
-
- // insert call of base-call surrogate method:
- String roleInterfaceName = genRoleInterfaceName(cg.getClassName());
-
- String calleeClassName = null;
- if(m.isStatic()) {
- calleeClassName = extractTeamName(roleInterfaceName);
- }
- changedArea = genBaseCallSurrogateCall(cpg, iv, enhancedMethod, loading, extractRoleName(roleInterfaceName), calleeClassName);
-
- if (returnValueAdded) {
- changedArea.append(InstructionFactory.createStore(enhancedMethodReturnType,
- otResult.getIndex()));
- } else {
- InstructionHandle ih = adjustValue(changedArea, changedArea.getEnd(), enhancedMethodReturnType, returnType);
- if (debugging && ih != null)
- mg.addLineNumber(ih, STEP_OVER_LINENUMBER);
- }
- replacedInstructions.add(new IHPair(delim[0], changedArea.getStart()));
- replacedInstructions.add(new IHPair(delim[1], changedArea.getEnd()));
-
- } // if (activate or base call)
-
- il.insert(next, changedArea);
-
-
-/*************************** "return" enhancements: ************/
- } else if (act_instruction instanceof ReturnInstruction) {
- // replace return statement by result preparation and a new return statement
- // construct back to front, to keep the insertion position!
- InstructionHandle oldReturn = ihs[actInstruction];
- InstructionHandle replacedPos = oldReturn;
- il.append(oldReturn, InstructionFactory.createReturn(enhancedMethodReturnType));
- if (returnValueAdded) {
- // load ot_result:
- oldReturn.setInstruction(InstructionFactory.createLoad(enhancedMethodReturnType,
- otResult.getIndex()));
- } else {
- oldReturn.setInstruction(new NOP());
- replacedPos =
- adjustValue(il, oldReturn, returnType, enhancedMethodReturnType);
- if (debugging && replacedPos != null)
- mg.addLineNumber(replacedPos, STEP_OVER_LINENUMBER);
- }
- if (replacedPos != null)
- replacedInstructions.add(new IHPair(oldReturn, replacedPos));
- } // conditional over instruction types
- actInstruction++;
- } //end while
-
- // tidy:
- checkUpdate(handlers, replacedInstructions, targetLost);
- enhancedMethod.removeNOPs();
- il.setPositions();
- enhancedMethod.setMaxStack();
- enhancedMethod.setMaxLocals();
-
- return enhancedMethod;
- }
-
- /**
- * Given an invokevirtual compute the space its arguments use on the stack.
- * @param cpg
- * @param iv
- * @return int stack size.
- */
- static int computeArgumentStackDepth(ConstantPoolGen cpg, InvokeInstruction ii) {
- Type [] iiargs = ii.getArgumentTypes(cpg);
- int depth=0;
- for (int i=0; i<iiargs.length; i++)
- depth += iiargs[i].getSize();
- return depth;
- }
-
- /**
- * Copy all local variables from <tt>src</tt> to <tt>dest</tt>.
- * While doing so, increment their index by EXTRA_ARGS.
- */
- static void copyLocalVariables(MethodGen src, MethodGen dest) {
- Type[] argumentTypes = src.getArgumentTypes();
- LocalVariableGen[] lvgs = src.getLocalVariables();
- for (int l=argumentTypes.length; l<lvgs.length; l++) {
- LocalVariableGen lvg = lvgs[l];
- if (lvg.getIndex() > 0) {
- dest.addLocalVariable(lvg.getName(),
- lvg.getType(),
- lvg.getIndex()+(EXTRA_ARGS+1), // +1?????
- null, null);
- //System.err.println("adding:" +src.getClassName() +" "+src.getName()+" "+lvg.getName() +" " + lvg.getType() +" "+ (lvg.getIndex()+(EXTRA_ARGS+1)));
- }
- }
- }
- /** Copy all line numbers from <tt>src</tt> to <tt>dest</tt>. */
- static void copyLineNumbers(MethodGen src, MethodGen dest) {
- InstructionList il_dest = dest.getInstructionList();
- il_dest.setPositions();
- LineNumberGen[] src_lng = src.getLineNumbers();
- for (int i=0; i<src_lng.length; i++) {
- int position = src_lng[i].getInstruction().getPosition();
- InstructionHandle ih = il_dest.findHandle(position);
- dest.addLineNumber(ih, src_lng[i].getSourceLine());
- }
- }
- /**
- * Prune a invokevirtual portion from a given instruction list.
- * Note, that arguments don't include 'this', which is not pruned but blanked
- * (need to keep as possible jump target).
- * @param il the source list
- * @param ihs array of handles of this list
- * @param idx points to a invokevirtual that shall be removed
- * @param stackDepth size of the called method's arguments on the stack.
- * This is how deep we need to cut into the stack.
- * @param cpg
- * @param targetLost set of lost InstructionHandles to be filled
- * @param delim array of two handles, which should be filled with start and end of
- * the pruned region.
- * @param blankThis should the 'this' call target be overwritten?
- * @return InstructionList a copy of the original value loading.
- */
- static InstructionList pruneLoading (InstructionList il, InstructionHandle[] ihs, int idx,
- int stackDepth, ConstantPoolGen cpg,
- HashSet<InstructionHandle> targetLost, InstructionHandle[] delim,
- boolean blankThis)
- {
- InstructionList nlist = new InstructionList();
- InstructionHandle start = ihs[idx];
- InstructionHandle end = ihs[idx--];
- while (stackDepth > 0) {
- start = ihs[idx--];
- Instruction instr = start.getInstruction();
- stackDepth -= stackDiff(instr, cpg);
- nlist.insert(instr);
- }
- if (blankThis) {
- if (!isALoad0(ihs[idx].getInstruction()))
- return null;
- ihs[idx].setInstruction(new NOP()); // keep as jump target but delete 'this'
- }
- delim[0] = start;
- delim[1] = end;
- safeDelete(il, start, end, targetLost);
- return nlist;
- }
-
- static boolean isALoad0(Instruction i) {
- if (!(i instanceof ALOAD)) return false;
- return ((ALOAD)i).getIndex() == 0;
- }
-
- /** Get the lenght of the longest base method signature in mbs.
- * @param mbs List of {@link MethodBinding MethodBinding}
- */
-// static int getMaxBaseArgLen (List mbs) {
-// int max=0;
-// Iterator it = mbs.iterator();
-// while (it.hasNext()) {
-// MethodBinding mb = (MethodBinding)it.next();
-// String sign = mb.getBaseMethodSignature();
-// int len = Type.getArgumentTypes(sign).length;
-// if (len>max) max = len;
-// }
-// return max;
-// }
-
- /**
- * Generate a dispatching switch statement which calls the proper base method.
- * @param cpg
- * @param mbs list of MethodBinding that applies to this callin method
- * @param enhancedMethod the enhanced callin method
- * @param roleArgumentTypes arg types of the callin method
- * @param outerClass the Team
- * @param baseClass the base bound to this role
- * @param returnType the return type of the original callin method
- * @param otResult the local variable storing the base call result
- * @param loading an instruction list holding the original instructions for
- * loading parameters
- * @return InstructionList the complete replacement implementing the base call.
- */
- InstructionList genBaseCallSwitch (ConstantPoolGen cpg,
- List<MethodBinding> mbs, MethodGen enhancedMethod,
- Type[] roleArgumentTypes,
- ObjectType outerClass, ObjectType baseClass,
- Type returnType, LocalVariableGen otResult,
- InstructionList loading,
- boolean isSuperAccess)
- {
-
- String className = enhancedMethod.getClassName();
- Type enhancedMethodReturnType = enhancedMethod.getReturnType();
- boolean callinHasReturnValue = returnType != Type.VOID;
-
- InstructionList il = new InstructionList();
-
- // Setup a variable which holds the result of this base call.
- // This variabel is local to this segment of code and used only
- // to transport this result out off the switch statement.
- int localResult = -1;
- LocalVariableGen lg = null;
- if (callinHasReturnValue) {
- lg = enhancedMethod.addLocalVariable("_OT$tmpResult", returnType,
- null, null);
- localResult = lg.getIndex();
- il.append(InstructionFactory.createNull (returnType));
- il.append(InstructionFactory.createStore(returnType, localResult));
- }
-
- // ---- Prepare the switch: ----
- InstructionHandle switchStart = il.append
- (InstructionFactory.createLoad(Type.INT, BASE_METH_ARG));
- // generated: _OT$baseMethTag
-
- removeDuplicatedBaseMethodTags(mbs);
-
- // one break for each case clause
- int numberOfCases = mbs.size();
- GOTO[] breaks = new GOTO[numberOfCases];
- for (int i=0; i<numberOfCases; i++)
- breaks[i] = new GOTO(null);
-
- int[] matches = new int[numberOfCases];
- InstructionHandle[] targets = new InstructionHandle[numberOfCases];
- int caseCounter = 0;
-
- Iterator<MethodBinding> it = mbs.iterator();
- while (it.hasNext()) {
-
- MethodBinding mb = it.next();
-
- String wrapperName = mb.getWrapperName();
- int[] paramPositions = CallinBindingManager.getParamPositions(outerClass.getClassName(),
- wrapperName);
- if (logging) printLogMessage("param pos(" + wrapperName + ")=" + paramPositions);
-
- matches[caseCounter] = CallinBindingManager.getBaseCallTag(mb.getBaseClassName(),
- mb.getBaseMethodName(),
- mb.getBaseMethodSignature());
- InstructionHandle nextBranch = il.append(new NOP());
-
- short invocationKind = isSuperAccess
- ? Constants.INVOKESTATIC
- : Constants.INVOKEVIRTUAL;
-
- String boundBaseClassName = mb.getBaseClassName();
- if (boundBaseClassName.indexOf(OTDT_PREFIX) != -1) {
- // if base is a role class, switch now to the interface part to support base-side implicit inheritance:
- boundBaseClassName = ObjectTeamsTransformation.genRoleInterfaceName(boundBaseClassName);
- invocationKind = Constants.INVOKEINTERFACE;
- }
- String baseMethodName = mb.getBaseMethodName();
- String baseMethodSignature = mb.getBaseMethodSignature();
- Type[] baseMethodArgumentTypes = Type.getArgumentTypes(baseMethodSignature);
- Type baseMethodReturnType = Type.getReturnType (baseMethodSignature);
-
- String baseChainMethodName;
- Type baseChainReturnType;
- Type[] enhancedBaseArgumentTypes;
- if (isSuperAccess) {
- baseChainMethodName = OT_PREFIX+baseMethodName+"$super";
- baseChainReturnType = returnType;
- // base arguments are un-enhanced but have a leading base instance:
- int len = baseMethodArgumentTypes.length;
- System.arraycopy(baseMethodArgumentTypes, 0, enhancedBaseArgumentTypes=new Type[len+1], 1, len);
- enhancedBaseArgumentTypes[0] = baseClass;
- } else {
- baseChainMethodName = genChainMethName(baseMethodName);
- baseChainReturnType = object; // ALWAYS
- enhancedBaseArgumentTypes = enhanceArgumentTypes(baseMethodArgumentTypes);
- }
-
- // --- call target: ---
-
- // if base class type is a role type _OT$base field has role interface type:
- {
- String baseClassName = baseClass.toString();
- if (baseClassName.indexOf(OTDT_PREFIX) != -1) {
- baseClass = new ObjectType(ObjectTeamsTransformation.genRoleInterfaceName(baseClassName));
- if(logging) printLogMessage(baseClassName + " --> " + ObjectTeamsTransformation.genRoleInterfaceName(baseClassName));
- }
- }
-
- // load '_OT$base' field:
- InstructionHandle baseCallLine = il.append(InstructionFactory.createThis());
- il.append(factory.createFieldAccess(className, BASE, baseClass, Constants.GETFIELD));
-
- if (!baseClass.getClassName().equals(boundBaseClassName)) {
- // playedBy has been refined in the sub role;
- // create a cast to the sub base class:
- il.append(factory.createCast(baseClass, new ObjectType(boundBaseClassName)));
- }
-
- // --- load arguments of the new method: ---
- // (letters refer to document parameter-passing.odg)
-
- // (u) generate extra arguments (indices are equal at role and base):
- if (!isSuperAccess)
- for (int idx = 0; idx < EXTRA_ARGS; idx++)
- il.append(InstructionFactory.createLoad(enhancedMethod.getArgumentTypes()[idx],
- idx+1/*translating non-static*/));
-
- // (v)(w)(x) split loading sequence and transfer source-level arguments
- // (includes reverse-application of parameter mappings):
-
- // Start at EXTRA_ARGS, because one set of enhancement has already been loaded,
- // except when doing super access which only has one extra arg: base instance.
- int start = isSuperAccess ? 1 : EXTRA_ARGS;
- il.append(translateLoads(splitLoading(cpg,
- loading.copy(),
- roleArgumentTypes),
- enhancedMethod.getArgumentTypes(),
- enhancedBaseArgumentTypes,
- paramPositions,
- extractTeamName(enhancedMethod.getClassName()),
- className,
- new BaseMethodInfo(mb.baseMethodIsCallin(), false/*static*/, mb.getTranslationFlags()),
- start,
- cpg));
- // --- done loading ---
-
- // invoke the chaining method of the base class (base-call!):
- il.append(factory.createInvoke(boundBaseClassName,
- baseChainMethodName,
- baseChainReturnType,
- enhancedBaseArgumentTypes,
- invocationKind
- ));
-
- boolean resultLiftingNecessary = ((mb.getTranslationFlags()&1)!=0);
-
- if (resultLiftingNecessary) { // call the static lift-method:
- // STATIC_PARTS_OK: in role: lift method call
-//TODO: lift method args!
- String liftMethodName = mb.getLiftMethodName();
- Type liftMethodReturnType = Type.getReturnType(mb.getLiftMethodSignature());
- Type[] liftMethodArgs = Type.getArgumentTypes(mb.getLiftMethodSignature());
-
- il.append(factory.createCast(baseChainReturnType, baseMethodReturnType));
- il.append(InstructionFactory.createThis());
-
- int nestingDepth = countOccurrences(className, '$') -1;
- il.append(factory.createGetField(className, "this$" + nestingDepth, outerClass ));
-
- il.append(new SWAP()); // -> .., this$0, (BaseType)result
- //il.append(new ICONST(LIFT_ARG_RES));
-
- il.append(factory.createInvoke(outerClass.getClassName(),
- liftMethodName,
- liftMethodReturnType,
- liftMethodArgs,
- Constants.INVOKEVIRTUAL));
- }
-
- InstructionHandle afterBaseCallLine = il.append(new NOP());
-
- if (baseChainReturnType != Type.VOID) {
- // adjust the return value to the type expected by the WRAPPER:
- il.append(new DUP()); // keep for adjustment below
- if (!resultLiftingNecessary)
- adjustValue(il, null, baseChainReturnType, enhancedMethodReturnType);
- il.append(InstructionFactory.createStore(enhancedMethodReturnType,
- otResult.getIndex())); // store "globally"
- // this store is needed to tunnel unused results through the callin.
-
- // adjust the return value to the type expected by the ORIGINAL CALLIN:
- adjustValue(il, null, baseChainReturnType, returnType);
- if (callinHasReturnValue)
- il.append(InstructionFactory.createStore(returnType, localResult)); // store "locally"
- // this store is useful for callins which make use of the result.
- }
-
- targets[caseCounter] = nextBranch;
- il.append(breaks[caseCounter]);
- // generated: break;
-
- caseCounter++;
-
- if (debugging) {
- enhancedMethod.addLineNumber(baseCallLine, STEP_INTO_LINENUMBER);
- enhancedMethod.addLineNumber(afterBaseCallLine, STEP_OVER_LINENUMBER);
- }
- }
- // Default case: throw an exception reporting the situation:
- // create: String msg = ("Unhandled base-call case!"+base_method_tag)
- InstructionList messagePush = new InstructionList();
- messagePush.append(factory.createNew(OTConstants.STRING_BUFFER_NAME));
- messagePush.append(new DUP());
- messagePush.append(factory.createInvoke(OTConstants.STRING_BUFFER_NAME, Constants.CONSTRUCTOR_NAME, Type.VOID, new Type[0], Constants.INVOKESPECIAL));
- messagePush.append(new PUSH(cpg, "Unhandled base-call case: "));
- messagePush.append(factory.createInvoke(OTConstants.STRING_BUFFER_NAME, "append", Type.STRINGBUFFER, new Type[]{Type.STRING}, Constants.INVOKEVIRTUAL));
- messagePush.append(InstructionFactory.createLoad(Type.INT, BASE_METH_ARG));
- messagePush.append(factory.createInvoke(OTConstants.STRING_BUFFER_NAME, "append", Type.STRINGBUFFER, new Type[]{Type.INT}, Constants.INVOKEVIRTUAL));
- messagePush.append(factory.createInvoke(OTConstants.STRING_BUFFER_NAME, "toString", Type.STRING, new Type[0], Constants.INVOKEVIRTUAL));
- // create: throw new OTREInternalError(msg)
- InstructionHandle defaultCase = createThrowInternalError(cpg, il, messagePush);
-
- InstructionHandle afterSwitch = il.append(new NOP()); // all breaks point here.
-
- il.append(switchStart, createLookupSwitch(matches, targets, breaks,
- defaultCase, afterSwitch));
-
- // retrieve locally stored result:
- if (callinHasReturnValue) {
- il.append(InstructionFactory.createLoad(returnType, localResult));
- lg.setStart(il.getStart()); // restrict local variable to this segment.
- lg.setEnd(il.getEnd());
- }
-
- return il;
- }
-
- /**
- * Removes duplicated method bindings with the same base call tag from the list, to avoid duplicated
- * cases in the base call surrogate-switch.
- * @param mbs
- */
- private static void removeDuplicatedBaseMethodTags(List<MethodBinding> mbs) {
- if (mbs.size() < 2) // nothing to remove
- return;
-
- MethodBinding[] mbArray = mbs.toArray(new MethodBinding[mbs.size()]);
-
- Comparator<MethodBinding> baseCallTagComparator = new Comparator<MethodBinding>() {
- public int compare(MethodBinding firstMB, MethodBinding secondMB) {
- int firstBaseTag = CallinBindingManager.getBaseCallTag(firstMB.getBaseClassName(),
- firstMB.getBaseMethodName(),
- firstMB.getBaseMethodSignature());
- int secondBaseTag = CallinBindingManager.getBaseCallTag(secondMB.getBaseClassName(),
- secondMB.getBaseMethodName(),
- secondMB.getBaseMethodSignature());
-
- if (firstBaseTag < secondBaseTag)
- return -1;
- if (firstBaseTag > secondBaseTag)
- return 1;
- return 0;
- }
- };
- Arrays.sort(mbArray, baseCallTagComparator);
- for (int i = 0; i + 1 < mbArray.length; i++) {
- if (baseCallTagComparator.compare(mbArray[i], mbArray[i + 1]) == 0) {
- mbs.remove(mbArray[i + 1]);
- }
- }
- }
-
-
- /**
- * @param className
- * @return
- */
- private static String extractTeamName(String roleClassName) {
- int lastDollarIndex = roleClassName.lastIndexOf('$');
- return roleClassName.substring(0, lastDollarIndex);
- }
-
- /**
- * @param className
- * @return
- */
- private static String extractRoleName(String roleClassName) {
- int lastDollarIndex = roleClassName.lastIndexOf('$');
- return roleClassName.substring(lastDollarIndex+1, roleClassName.length());
- }
-
- /**
- * FIXME(SH): obsolete!
- * @param baseMethodReturnType
- * @param returnType
- * @return
- */
-// private static boolean returnTypeCompatible(Type from, Type to) {
-// System.out.println("test for " + from + "->" + to);
-// if (from.equals(to))
-// return true;
-// if (from instanceof ObjectType && to instanceof ObjectType) {// how to handle compatible basic types??
-// ObjectType otFrom = (ObjectType) from;
-// ObjectType otTo = (ObjectType) to;
-// if (otFrom.subclassOf(otTo))
-// return true;
-// }
-// return false;
-// }
-
- /**
- * Copy all exception handlers of a method.
- * @param source the method from where to copy
- * @param dest the method where to copy to
- * @param il instructions of `dest' which must still have the same positions
- * as the instructions in `source'.
- * @return an array of handler generators, which still has to be maintained,
- * whenever instructions are replaced in the methods instruction list.
- */
- static CodeExceptionGen[] copyExceptionHandlers(MethodGen source,
- MethodGen dest,
- InstructionList il) {
- il.setPositions(); // needed to retrieve handles by position.
- CodeExceptionGen[] excGens = source.getExceptionHandlers();
- CodeExceptionGen[] newGens = new CodeExceptionGen[excGens.length];
- if ((excGens != null) && excGens.length > 0) {
- for (int hcount=0; hcount<excGens.length; hcount++) {
- CodeExceptionGen excGen = excGens[hcount];
- InstructionHandle excStart = il.findHandle(excGen.getStartPC().getPosition());
- InstructionHandle excEnd = il.findHandle(excGen.getEndPC().getPosition());
- InstructionHandle excHandler = il.findHandle(excGen.getHandlerPC().getPosition());
- ObjectType catchType = excGen.getCatchType();
- newGens[hcount] =
- dest.addExceptionHandler(excStart, excEnd, excHandler, catchType);
- }
- }
- return newGens;
- }
-
- /**
- * Update the positions of all exception handlers.
- * @param handlers the handlers of this method.
- * @param replaced a pair of InstructionHandles, the first is replaced by the second.
- */
- static void updateHandlers (CodeExceptionGen[] handlers, IHPair replaced) {
- InstructionHandle old = replaced.fst();
- InstructionHandle neu = replaced.snd();
- for (int i=0; i<handlers.length; i++) {
- // System.out.println("handler "+handlers[i]);
- if (handlers[i].containsTarget(old) && (old != neu)) {
- // System.out.println("update "+old+"->"+neu);
- handlers[i].updateTarget(old, neu);
- }
- }
- }
-
- /**
- * Delete a range of instructions, whithout throwing TargetLostException.
- * @param il the list to delete from
- * @param start handle to first instruction to delete.
- * @param end handle to last instruction to delete.
- * @param collect a set of InstructionHandle which are still targeted.
- */
- static void safeDelete(InstructionList il,
- InstructionHandle start, InstructionHandle end,
- HashSet<InstructionHandle> collect)
- {
- try {
- il.delete(start, end);
- } catch(TargetLostException e) {
- // System.out.print("Loosing:"+e+" ");
- InstructionHandle [] targets = e.getTargets();
- for (int tcount = 0; tcount < targets.length; tcount++) {
- collect.add(targets[tcount]);
- // System.out.println(targets[tcount]+"!!");
- }
- }
- }
-
- /**
- * Update all exceptions handlers with respect to all instructions that were replaced.
- * Check that this covers all instruction handles in 'lost'.
- * @param handles the exception handlers of this method.
- * @param replacedList list of IHPairs describing what has been modified.
- * @param lost set of instruction handles that were still referred to when
- * they were deleted. All these handles should be updated.
- */
- static void checkUpdate(CodeExceptionGen[] handlers, ArrayList<IHPair> replacedList, HashSet<InstructionHandle> lost) {
- // System.out.println("Update "+replacedList+"/"+lost);
- Iterator<IHPair> iter = replacedList.iterator();
- while (iter.hasNext()) {
- IHPair replaced = iter.next();
- updateHandlers(handlers, replaced);
- lost.remove(replaced.fst());
- }
- if (!lost.isEmpty()) {
- System.err.println("Warning: "+lost.size()+" target(s) lost: ");
- Iterator<InstructionHandle> it = lost.iterator();
- while (it.hasNext())
- System.out.println(it.next());
- }
- }
-
- /**
- * While adding extra args to an activate call:
- * <ul>
- * <li>Check whether an activationLevel was passed (single argument)
- * <li>if so, insert the loading sequence for that expression.
- * <li>also the return differs (void or int), should however be
- * consistent between plain and enhanced version.
- * <li>decrement "idx" so this team is the currently active in the chain.
- * </ul>
- * @param factory
- * @param cpg
- * @param loading sequence, which loads "level" argument, else null.
- * @param iv the invokevirtual for "activate", used to inspect the
- * original signature.
- * @return the full sequence for loading the arguments, but not the
- * call target (because that's the enclosing team and is kept
- * unmodified in the original instruction list).
- */
-// static InstructionList enhanceActivateCall (final InstructionFactory factory,
-// ConstantPoolGen cpg,
-// InstructionList loading,
-// INVOKEVIRTUAL iv) {
-// InstructionList changedArea = new InstructionList();
-//
-// // load arguments of the new method:
-// int index = 1;
-// Type[] enhancedArgumentTypes = enhanceArgumentTypes(iv.getArgumentTypes(cpg),
-// 0, false, false);
-// Type returnType = Type.VOID;
-// int kount = enhancedArgumentTypes.length;
-// if (iv.getArgumentTypes(cpg).length == 1) {
-// kount--; // "level" loaded separately via 'loading'
-// returnType = Type.INT;
-// }
-//
-// for (int k=0; k<kount; k++) {
-// changedArea.append(InstructionFactory.createLoad(enhancedArgumentTypes[k], index));
-// index += enhancedArgumentTypes[k].getSize();
-// }
-// if (loading != null)
-// changedArea.append(loading);
-//
-// // invoke the overloaded activate method:
-// changedArea.append(factory.createInvoke("org.objectteams.Team",
-// "activate",
-// returnType,
-// enhancedArgumentTypes,
-// Constants.INVOKEVIRTUAL));
-//
-// // generate: idx--;
-// changedArea.append(InstructionFactory.createLoad(Type.INT, IDX_ARG));
-// changedArea.append(new ICONST(1));
-// changedArea.append(new ISUB());
-// changedArea.append(InstructionFactory.createStore(Type.INT, IDX_ARG));
-//
-// return changedArea;
-// }
-
- /**
- * Generates the instructions to call the enhanced version of the 'super' respectively 'tsuper'
- * call in a role method.
- * @param cpg the constant pool
- * @param ii the original invoke instruction
- * @param enhancedMethod the enhanced role method
- * @param loading the originally loaded arguments
- * @return the instruction list containing the method call ingredients
- */
- @SuppressWarnings("deprecation") // ii.getClassName() is deprecated
- InstructionList genEnhancedSuperCall(ConstantPoolGen cpg, InvokeInstruction ii,
- MethodGen enhancedMethod, InstructionList loading)
- {
- Type returnType = enhancedMethod.getReturnType();
- //Type[] argTypes = enhancedMethod.getArgumentTypes();
- Type[] argTypes = enhanceArgumentTypes(ii.getArgumentTypes(cpg));
- InstructionList il = new InstructionList();
-
- il.append(InstructionFactory.createThis());
- // load all additional arguments of the enhanced method (first EXTRA_ARGS):
- int index = 1;
- for (int i=0; i<EXTRA_ARGS; i++) {
- il.append(InstructionFactory.createLoad(argTypes[i],index));
- index += argTypes[i].getSize();
- }
- // load arguments of the originally call:
- il.append(loading);
-
- // call super.<enhancedMethod>:
- short kind=0;
- if (ii instanceof INVOKESPECIAL)
- kind = Constants.INVOKESPECIAL;
- else
- kind = Constants.INVOKEVIRTUAL;
-
- il.append(factory.createInvoke(ii.getClassName(cpg), // deprecated but we're safe because we have not array here (super/tsuper call)
- ii.getMethodName(cpg),
- returnType,
- argTypes,
- kind));
- return il;
- }
-
- /**
- * Generates the instructions to call the base call surrogate method.
- * @param cpg the constant pool
- * @param iv the original invoke instruction
- * @param enhancedMethod the enhanced role method
- * @param loading the originally loaded arguments
- * @return the instruction list containing the method call ingredients
- */
- @SuppressWarnings("deprecation") // iv.getClassName is deprecated
- InstructionList genBaseCallSurrogateCall(ConstantPoolGen cpg, InvokeInstruction/*INVOKEVIRTUAL*/ iv,
- MethodGen enhancedMethod, InstructionList loading,
- String roleClassName, String calleeClassName) //JU: added String roleClassName and teamClassName to the method signature
- {
- int indexOffset = enhancedMethod.isStatic()?-1:0; // argument indexes are decremented for static methods,
- // because of the missing 'this'
- // for static methods callee is 'null' -> substitute by current class (JU)
- if(calleeClassName == null) {
- calleeClassName = iv.getClassName(cpg); // deprecated but we're safe because we have not array here (activate() call)
- }
-
- Type returnType = enhancedMethod.getReturnType();
- //Type[] argTypes = enhancedMethod.getArgumentTypes();
- Type[] argTypes = enhanceArgumentTypes(iv.getArgumentTypes(cpg));
- InstructionList il = new InstructionList();
-
- String methodName = getBaseCallSurrogateName(enhancedMethod.getName(),
- enhancedMethod.isStatic(),
- roleClassName);
- short invokeKind;
-
- if (!enhancedMethod.isStatic()) {
- il.append(InstructionFactory.createThis());
- invokeKind = Constants.INVOKEVIRTUAL;
-
- } else { // role method is static:
- invokeKind = Constants.INVOKESTATIC;
- }
-
- // load all additional arguments of the enhanced method (first EXTRA_ARGS):
- int index = 1;
- for (int i = 0; i < argTypes.length; i++) {
- if(i < EXTRA_ARGS){ // skip original arguments
- il.append(InstructionFactory.createLoad(argTypes[i], index+indexOffset));
- }
- //calculate the next index
- index += argTypes[i].getSize();
- }
- // load arguments of the originally call:
- il.append(loading);
-
- // call _OT$<enhancedMethod>$base():
- il.append(factory.createInvoke(calleeClassName,
- methodName,
- returnType,
- argTypes,
- invokeKind/*Constants.INVOKEVIRTUAL*/));
- return il;
- }
-
-
- /**
- * Checks, if a given instuction is a super or a tsuper call
- * @param instr the instruction to check
- * @param method_name the name of the method from wich the 'inst' came
- * @param cpg the constant pool
- * @return true, if 'inst' is a super or tsuper call
- */
- private static boolean super_or_tsuper_instruction(Instruction instr, String method_name, ConstantPoolGen cpg) {
- if (isTSuperCall(instr, method_name, cpg))
- return true;
- if (isSuperCall(instr, method_name, cpg))
- return true;
- return false;
- }
-
- private static boolean isTSuperCall(Instruction instr, String method_name, ConstantPoolGen cpg) {
- if (instr instanceof INVOKEVIRTUAL) {
- INVOKEVIRTUAL iv = (INVOKEVIRTUAL)instr;
- String iv_name = iv.getName(cpg);
- Type[] argTypes = iv.getArgumentTypes(cpg);
- if (argTypes.length<1) // no tsuper marker interface parameter!
- return false;
- String lastArgument = (argTypes[argTypes.length-1]).toString();
- if (iv_name.equals(method_name) && (lastArgument.indexOf(TSUPER_PREFIX)!=-1)) {
- // if iv == <method_name>(..., TSuper__OT__<SuperTeamName>) -->
- if(logging) printLogMessage("tsuper-call to " + iv_name + " has to be enhanced!");
- return true;
- }
- }
- return false;
- }
-
- private static boolean isSuperCall(Instruction instr, String method_name, ConstantPoolGen cpg) {
- if (instr instanceof INVOKESPECIAL) {
- INVOKESPECIAL is = (INVOKESPECIAL)instr;
- String is_name = is.getName(cpg);
-
- if(is_name.equals(method_name)) {
- if(logging) printLogMessage("super-call to " + is_name + " has to be enhanced!");
- return true;
- }
- }
- return false;
- }
-
- /**
- * Generates the base call surrogate name for a given method name.
- * @param method_name the name of the role method
- * @param staticFlag
- * @param roleClassName the name of the role method
- * @return the base call surrogate name
- */
- private static String getBaseCallSurrogateName(String method_name, boolean staticFlag, String roleClassName) {
- //JU: for static methods the role class name should be inserted
- if(staticFlag) {
- return OT_PREFIX+roleClassName+"$"+method_name+"$base";
- }
- return OT_PREFIX+method_name+"$base";
- }
-
- /**
- * Reverts a method name to its original by returning the substring after the last '$'
- * until the end.
- * @param method_name method name to be adjusted
- * @return the original method name
- */
- private static String revertToOriginalName(String method_name) {
- int p = method_name.lastIndexOf('$');
- return method_name.substring(p + 1);
- }
-
-/*
- * (non-Javadoc)
- *
- * @see org.eclipse.objectteams.otre.common.ObjectTeamsTransformation#doTransformCode(org.apache.bcel.generic.ClassGen)
- */
- public void doTransformCode(ClassGen cg) {
- // nothing to do
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java
deleted file mode 100644
index d6f4aba6f..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java
+++ /dev/null
@@ -1,1907 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: BaseMethodTransformation.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import static org.eclipse.objectteams.otre.StaticSliceBaseTransformation._OT_ACTIVE_TEAMS;
-import static org.eclipse.objectteams.otre.StaticSliceBaseTransformation._OT_ACTIVE_TEAM_IDS;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.Map.Entry;
-
-import org.eclipse.objectteams.otre.util.CallinBindingManager;
-import org.eclipse.objectteams.otre.util.DebugUtil;
-import org.eclipse.objectteams.otre.util.ListValueHashMap;
-import org.eclipse.objectteams.otre.util.MethodBinding;
-import org.eclipse.objectteams.otre.util.TeamIdDispenser;
-
-import org.apache.bcel.Constants;
-import org.apache.bcel.classfile.Field;
-import org.apache.bcel.classfile.LineNumber;
-import org.apache.bcel.classfile.LineNumberTable;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.generic.AASTORE;
-import org.apache.bcel.generic.ACONST_NULL;
-import org.apache.bcel.generic.ALOAD;
-import org.apache.bcel.generic.ANEWARRAY;
-import org.apache.bcel.generic.ARRAYLENGTH;
-import org.apache.bcel.generic.ATHROW;
-import org.apache.bcel.generic.ArrayType;
-import org.apache.bcel.generic.BasicType;
-import org.apache.bcel.generic.BranchInstruction;
-import org.apache.bcel.generic.ClassGen;
-import org.apache.bcel.generic.ConstantPoolGen;
-import org.apache.bcel.generic.DUP;
-import org.apache.bcel.generic.DUP_X1;
-import org.apache.bcel.generic.FieldGen;
-import org.apache.bcel.generic.GOTO;
-import org.apache.bcel.generic.IADD;
-import org.apache.bcel.generic.ICONST;
-
-import org.apache.bcel.generic.IFNE;
-import org.apache.bcel.generic.IFNONNULL;
-import org.apache.bcel.generic.IF_ICMPLT;
-import org.apache.bcel.generic.IINC;
-import org.apache.bcel.generic.INVOKESPECIAL;
-import org.apache.bcel.generic.Instruction;
-import org.apache.bcel.generic.InstructionConstants;
-import org.apache.bcel.generic.InstructionFactory;
-import org.apache.bcel.generic.InstructionHandle;
-import org.apache.bcel.generic.InstructionList;
-import org.apache.bcel.generic.InvokeInstruction;
-import org.apache.bcel.generic.LDC;
-import org.apache.bcel.generic.LocalVariableGen;
-import org.apache.bcel.generic.MONITOREXIT;
-import org.apache.bcel.generic.MethodGen;
-import org.apache.bcel.generic.NOP;
-import org.apache.bcel.generic.ObjectType;
-import org.apache.bcel.generic.POP;
-import org.apache.bcel.generic.PUSH;
-import org.apache.bcel.generic.TABLESWITCH;
-import org.apache.bcel.generic.Type;
-
-
-/**
- * Insert dispatch code into base methods affected by callin bindings. <p>
- * If a loaded class contains binding declarations (transmitted by attributes)
- * these are stored for further determination of necessity for base-method-transforming.
- * Classes for which a callin binding exists will be transformed:
- * (base-class)methods <i>m()</i> which are changed by a callin will be copied to
- * <tt>_OT$<i>m</i>$orig()</tt>.
- * Hereafter the original method <i>m()</i> will be transformend depending on the
- * callin-modifier:
- * <ul>
- * <li> replace: only the (role-)callin-method is called
- * <li> after: first the original-method <tt>_OT$<i>m</i>$orig()</tt> is called and
- * then the callin-method
- * <li> before: first the the callin-method is called and then original-method
- * <tt>_OT$<i>m</i>$orig()</tt>
- * </ul>
- *
- * @version $Id: BaseMethodTransformation.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-
-public class BaseMethodTransformation
- extends ObjectTeamsTransformation
-{
- // configurability for stepping behavior of the chaining wrapper:
- private static boolean SHOW_ORIG_CALL = true;
- private static boolean SHOW_RECURSIVE_CALL = true;
- private static boolean SHOW_ROLE_CALL = true;
- static {
- String callinStepping = System.getProperty("ot.debug.callin.stepping");
- if (callinStepping != null) {
- SHOW_ORIG_CALL = SHOW_RECURSIVE_CALL = SHOW_ROLE_CALL = false;
- StringTokenizer tokens = new StringTokenizer(callinStepping, ",");
- while (tokens.hasMoreTokens()) {
- String token = tokens.nextToken();
- if ("orig".equals(token))
- SHOW_ORIG_CALL = true;
- else if ("recurse".equals(token))
- SHOW_RECURSIVE_CALL = true;
- else if ("role".equals(token))
- SHOW_ROLE_CALL = true;
- }
- }
- }
-
- // method of o.o.Team:
- private static final String IS_ACTIVE = "isActive"; //$NON-NLS-1$
-
- private final static int NORESULT = -1;
-
- // methods awaiting statements as an initial wrapper:
- private HashSet<String/*methodName*/> pendingInitialWrappers;
- // methods awaiting a super call to an existing initial wrapper:
- private HashSet<String/*methodName*/> pendingSuperDelegationWrappers;
-
- public boolean useReflection = false;
-
- public BaseMethodTransformation(ClassLoader loader, SharedState state) {
- super(loader, state);
- }
- /**
- * The code transformer only replaces the original code with
- * the initial wrapper.
- */
- public void doTransformCode(ClassGen cg) {
- factory = new InstructionFactory(cg);
- ConstantPoolGen cpg = cg.getConstantPool();
- String class_name = cg.getClassName();
-
- Method[] methods = cg.getMethods();
- for (int i=0; i<methods.length; i++) {
- Method m = methods[i];
- //if (m.isNative())
- // continue;
- if (m.isVolatile())
- continue; // don't touch bridge methods
-
- String method_name = m.getName();
-
- if (CallinBindingManager.isBoundBaseClass(class_name)
- && !CallinBindingManager.hasBoundBaseParent(class_name)
- && method_name.equals(Constants.CONSTRUCTOR_NAME))
- {
- addToConstructor(m, getInitializedRoleSet(cg.getClassName(), false), cg, cpg);
- continue;
- }
-
- String method_signature = m.getSignature();
-
- if (state.interfaceTransformedClasses.contains(class_name)) {
- if (pendingInitialWrappers.contains(method_name + '.' + method_signature))
- cg.replaceMethod(m, m = generateInitialWrapper(m, class_name, cg.getMajor(), cpg));
- else if (pendingSuperDelegationWrappers.contains(method_name + '.' + method_signature))
- cg.replaceMethod(m, m = generateSuperCall(m, cg, cpg));
-
- Method replacement = checkReplaceWickedSuper(class_name, m, cpg);
- if (replacement != null)
- cg.replaceMethod(m, replacement);
- }
- }
- }
-
- /*
- * If a base method m1 has a super-call super.m2() and if that method m2 is callin-bound
- * we currently bypass aspect dispatch to avoid infinite recursions.
- */
- private Method checkReplaceWickedSuper(String className, Method m, ConstantPoolGen cpg)
- {
- if (m.isAbstract() || m.isNative())
- return null;
- MethodGen mg = newMethodGen(m, className, cpg);
- String method_name = m.getName();
- InstructionHandle[] ihs = mg.getInstructionList().getInstructionHandles();
- boolean found = false;
- for (InstructionHandle ih : ihs) {
- if (ih.getInstruction() instanceof INVOKESPECIAL) {
- Instruction actInstruction = ih.getInstruction();
- INVOKESPECIAL is = (INVOKESPECIAL)actInstruction;
- String is_name = is.getName(cpg);
- if ( !is_name.equals(method_name) // not same method
- && !is_name.equals("<init>")) // not ctor call
- {
- @SuppressWarnings("deprecation") // type of is (invokespecial) cannot be array type
- String superClassName = is.getClassName(cpg);
- if ( !superClassName.equals(className) // not private method of same class
- && CallinBindingManager.isBoundBaseMethod( // target method is callin-affected
- superClassName,
- is_name,
- is.getSignature(cpg)))
- {
- found = true;
- if(logging) printLogMessage("wicked super-call to " + is_name //$NON-NLS-1$
- + " has to be redirected to the orig-version!"); //$NON-NLS-1$
- ih.setInstruction(factory.createInvoke(superClassName,
- "_OT$"+is_name+"$orig",
- is.getReturnType(cpg),
- is.getArgumentTypes(cpg),
- Constants.INVOKESPECIAL));
- }
- }
- }
- }
- if (found)
- return mg.getMethod();
- return null;
- }
-
- /**
- * Main entry for this transformer.
- */
- public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
- String class_name = cg.getClassName();
- //SourceMapGeneration sourceMapGen = new SourceMapGeneration(cg);
-
- ConstantPoolGen cpg = cg.getConstantPool();
- factory = new InstructionFactory(cg);
- if (CallinBindingManager.isBoundBaseClass(class_name) && !cg.isInterface()) {
- // TODO: where to add the role set infrastructure, if only an interface is bound? Implementing classes?
- if (cg.containsField(OTConstants.ROLE_SET) == null && !CallinBindingManager.hasBoundBaseParent(class_name)) {
- ce.addField(generateRoleSet(cpg, class_name), cg);
- ce.addMethod(generateAddRole(cpg, class_name), cg);
- ce.addMethod(generateRemoveRole(cpg, class_name), cg);
- ce.addImplements(OTConstants.IBOUND_BASE, cg);
- }
- }
-
- if (pendingInitialWrappers == null)
- pendingInitialWrappers = new HashSet<String>();
- if (pendingSuperDelegationWrappers == null)
- pendingSuperDelegationWrappers = new HashSet<String>();
-
-
- checkReadClassAttributes(ce, cg, class_name, cpg);
-
- //JU: change the class modifier to 'public' if decapsulation required
- if(CallinBindingManager.checkBaseClassModifierChange(class_name) && !cg.isPublic()) {
- cg.setAccessFlags(makePublicFlags(cg.getAccessFlags()));
- }
-
- Collection<MethodBinding> inheritedBindings = CallinBindingManager.getInheritedCallinBindings(class_name);
-
-// if (inheritedSigns!=null && !inheritedSigns.isEmpty()) {
-// Iterator itx = inheritedSigns.iterator();
-// while (itx.hasNext()) {
-// System.err.print(class_name+" : ");
-// String[] next = (String[])itx.next();
-// System.err.println(next[0] +" " +next[1]) ;
-// }
-// }
- /*
- String[] interfaceNames = cg.getInterfaceNames();
- Collection interfaceInheritedSigns = new LinkedList();
- //System.err.println("searching inherited bindings for: "+class_name);
- for (int i=0; i<interfaceNames.length;i++) {
- if (!interfaceNames[i].equals(class_name))
- interfaceInheritedSigns.addAll(CallinBindingManager.getInterfaceInheritedCallinBindings(interfaceNames[i]));
- }*/
- /*
- if (!interfaceInheritedSigns.isEmpty()) {
- System.err.println("BMT: searching inherited bindings for: "+class_name);
- for (Iterator iterator = interfaceInheritedSigns.iterator(); iterator.hasNext();) {
- String[] element = (String[]) iterator.next();
- System.err.println(element[0]+element[1]);
- }
- }*/
- //inheritedSigns.addAll(interfaceInheritedSigns);
-
- // if class is already transformed by this transformer
- /*
- if (interfaceTransformedClasses.contains(class_name))
- continue;
- */
-
- if(cg.isInterface()) {
- // may need to add an interface version of the chaining wrapper, to be called for a base-call
- int lastDollar = class_name.lastIndexOf('$');
- if (lastDollar != -1) {
- // try inserting __OT__ to last type name segment
- String roleClassName = class_name.substring(0, lastDollar+1)+"__OT__"+class_name.substring(lastDollar+1);
- if (CallinBindingManager.isBoundBaseClass(roleClassName)) {
- Method[] methods = cg.getMethods();
- for (int i=0; i<methods.length; i++) {
- Method m = methods[i];
- if (m.isVolatile()) // bridge method!
- continue;
- String method_name = m.getName();
- String signature = m.getSignature();
- Collection<MethodBinding> bindingsForMethod = CallinBindingManager .
- getBindingForBaseMethod(roleClassName, method_name, signature);
- if (bindingsForMethod!= null) {
- MethodGen chainGen = generateChainingWrapper(class_name, cpg,
- m.getAccessFlags()|Constants.ACC_ABSTRACT, method_name, signature, null/*argumentNames*/);
- if (cg.containsMethod(chainGen.getName(), chainGen.getSignature()) == null)
- ce.addMethod(chainGen.getMethod(), cg);
- }
- }
- }
- }
-
- //CallinBindingManager.addBoundBaseInterface(class_name); // <- this is to late, implementing class may be loaded before!!
- return; // No transfomations neccessary for interfaces.
- }
-
- boolean haveDirectCallin =
- CallinBindingManager.isBoundBaseClass(class_name);
- // IMPLICIT_INHERITANCE
- if (inheritedBindings.size() == 0 && !haveDirectCallin /*&& interfaceInheritedSigns.size()==0*/) {
- if(logging) printLogMessage("\nCallins: nothing to do for class " + class_name); //$NON-NLS-1$
- return; // nothing to do
- }
-
- if(logging) printLogMessage("\nCallin bindings may be changing class " //$NON-NLS-1$
- + class_name + ':');
-
- // A field to optimize class-literal in initial wrapper:
- if (cg.getMajor() < 49) {// pre 1.5?
- if (cg.containsField(OTConstants.SELF_CLASS) == null)
- ce.addField(new FieldGen(Constants.ACC_PROTECTED|Constants.ACC_STATIC,
- classType,
- OTConstants.SELF_CLASS,
- cpg)
- .getField(),
- cg);
- }
-
- Method[] methods = cg.getMethods();
- for (int i=0; i<methods.length; i++) {
- Method m = methods[i];
- if (m.isVolatile()) // bridge method!
- continue;
- String method_name = m.getName();
- String method_signature = m.getSignature();
-
- Collection<MethodBinding> bindingsForMethod = null;
- // IMPLICIT_INHERITANCE
- if (haveDirectCallin)
- bindingsForMethod = CallinBindingManager .
- getBindingForBaseMethod(class_name, method_name, m.getSignature());
-
- //JU: added the following statement to determine overridden static base methods
- //Collection inheritedCallinBindings = CallinBindingManager.getInheritedCallinBindings(class_name);
- //CH: removed it again, because it is the same as 'inheritedSigns'!
-
- MethodGen mg = null;
- int firstLine = STEP_OVER_LINENUMBER;
- /*if (bindingsForMethod != null || containsSign(inheritedSigns, m)*/ /*|| containsSign(interfaceInheritedSigns, m)*/ //) {
- MethodBinding inheritedBinding = matchingBinding(inheritedBindings, m, false);
- String method_key = method_name+'.'+method_signature;
- if (bindingsForMethod != null || (inheritedBinding != null && !m.isStatic() && !m.isPrivate())) {
-
- mg = newMethodGen(m, class_name, cpg);
- Method orig_method;
-
- String name_orig = genOrigMethName(method_name);
- if (cg.containsMethod(name_orig, m.getSignature())!=null) {
- continue;// method was already copied to orig-version!
- }
-
- if (debugging)
- firstLine = findFirstLineNumber(m);
-
- mg.setName(name_orig);
-
- // TODO(SH): store this match, or keep previous?
- if (matchingBinding(inheritedBindings, m, true) != null) // this method was adapted in a super class
- replaceSuperCalls(mg, method_name, cpg);
-
- orig_method = mg.getMethod();
- ce.addMethod(orig_method, cg);
- if(logging) printLogMessage("Method " + method_name + " was backuped as " //$NON-NLS-1$ //$NON-NLS-2$
- + name_orig + '.');
-
- if (inheritedBinding != null) {
- if (method_signature.equals(inheritedBinding.getBaseMethodSignature()))
- pendingSuperDelegationWrappers.add(method_key);
- else // override with covariant return: at the VM-level this is a *new* method, need a new initial wrapper
- pendingInitialWrappers.add(method_key);
- }
- }
-
- /*if (bindingsForMethod != null || (containsSign(inheritedSigns,m) && m.isStatic())*/ /*|| containsSign(interfaceInheritedSigns, m)*/ //) {
- //CH: changed 'inheritedCallinBindings' to 'inheritedSigns', because it was the same.
- if (bindingsForMethod != null) {
- //add method '_OT$<method_name>$chain' :
- mg = getConcretMethodGen(m, class_name, cpg);
- MethodGen chainGen = generateChainingWrapper(class_name, cpg,
- mg.getAccessFlags(), method_name, method_signature, mg.getArgumentNames());
- Method chain = generateChainingWrapperBody(class_name, cg, cpg,
- mg, method_name, method_signature, chainGen, firstLine);
-
- if (cg.containsMethod(chain.getName(), chain.getSignature()) == null)
- ce.addMethod(chain, cg);
-
- pendingInitialWrappers.add(method_key);
- pendingSuperDelegationWrappers.remove(method_key); // might have prematurely added this above
- }
- if (mg == null)
- if (logging) printLogMessage("No method binding (direct or inherited) found for " //$NON-NLS-1$
- + method_name);
- }
- state.interfaceTransformedClasses.add(class_name);
- }
-
- private int findFirstLineNumber(Method m) {
- LineNumberTable lnt = m.getLineNumberTable();
- if (lnt != null && lnt.getTableLength() > 0) {
- LineNumber[] lineNumberTable = lnt.getLineNumberTable();
- for (int i=0; i<lineNumberTable.length; i++) {
- int lineNumber = lineNumberTable[i].getLineNumber();
- if (lineNumber != OTConstants.STEP_OVER_LINENUMBER)
- return lineNumber;
- }
- return lineNumberTable[0].getLineNumber();
- }
- return STEP_OVER_LINENUMBER; // make it a valid line number
- }
-
- /**
- * "super"-calls in callin bound base methods have to be redirected to the _OT$...$orig version, if the
- * super-method is bound (and thus renamed to _OT$..$orig) too.
- *
- * @param orig_method the copied method
- * @param method_name the prior name of the copied method
- * @param cpg the corresponding constang pool
- */
- private void replaceSuperCalls(MethodGen orig_method, String method_name, ConstantPoolGen cpg) {
- // search for super calls:
- InstructionList il = orig_method.getInstructionList();
- InstructionHandle[] ihs = il.getInstructionHandles();
- int actInstrIndex = 0;
- while (actInstrIndex < ihs.length) {
- if (ihs[actInstrIndex].getInstruction() instanceof INVOKESPECIAL) {
- Instruction actInstruction = ihs[actInstrIndex].getInstruction();
- INVOKESPECIAL is = (INVOKESPECIAL)actInstruction;
- String is_name = is.getName(cpg);
- if(is_name.equals(method_name)) {
- @SuppressWarnings("deprecation") // type if is (invokespecial) cannot be array type
- String superClassName = is.getClassName(cpg);
- if(logging) printLogMessage("super-call to " + is_name //$NON-NLS-1$
- + " has to be redirected to the orig-version!"); //$NON-NLS-1$
- // generate and set an instruction calling the orig-version of the super method:
- InvokeInstruction superOrigCall = factory.createInvoke(superClassName,
- orig_method.getName(),
- orig_method.getReturnType(),
- orig_method.getArgumentTypes(),
- Constants.INVOKESPECIAL);
- ihs[actInstrIndex].setInstruction(superOrigCall);
- }
- }
- actInstrIndex++;
- }
- // redirect them ( change called method name to _OT$..$orig ) if super-method has been renamed:
- // -->
- }
-
- /**
- * Is method `m' contained in `baseMethodBindings'?
- * @param nameSigns list of MethodBinding
- * @param m
- * @param strict if true covariance must not be considered
- * @return the matching binding from baseMethodBindings or null.
- */
- static MethodBinding matchingBinding (Collection<MethodBinding> baseMethodBindings, Method m, boolean strict)
- {
- for (MethodBinding binding: baseMethodBindings)
- if (binding.matchesMethod(m.getName(), m.getSignature(), strict))
- return binding;
-
- return null;
- }
-
- /**
- * Get a MethodGen for `m'.
- * If `m' is abstract setup a new concrete method.
- */
- static MethodGen getConcretMethodGen (Method m, String class_name, ConstantPoolGen cpg) {
- MethodGen mg;
- String signature = m.getSignature();
- Type[] argTypes = Type.getArgumentTypes(signature);
- if (m.isAbstract()) {
- Type returnType = Type.getReturnType(signature);
- InstructionList il = new InstructionList();
- il.append(new NOP());
- mg = new MethodGen(m.getAccessFlags()&~Constants.ACC_ABSTRACT,
- returnType, argTypes,
- null, // names are unknown
- m.getName(), class_name,
- il, cpg);
- } else {
- mg = wipeMethod(m, class_name, cpg);
- }
- if (debugging) {
- mg.removeLocalVariables();
- int slot = 0;
- // create local variable table for "this" and arguments:
- if (!m.isAbstract())
- mg.addLocalVariable("this", new ObjectType(class_name), slot++, null, null);
- for (int i=0; i<argTypes.length; i++)
- mg.addLocalVariable("arg"+i, argTypes[i], slot++, null, null);
- mg.setMaxLocals();
- }
- return mg;
- }
-
- /**
- * Generate the initial wrapper for the passed mehtod.
- * It binds callin dispatch to Team-unaware client code.
- * @param m the original method
- * @param class_name the name of the appropriate class
- * @param major
- * @param cpg the ConstantPoolGen of the class
- * @return the generated method
- */
- private Method generateInitialWrapper(Method m,
- String class_name,
- int major,
- ConstantPoolGen cpg)
- {
- MethodGen mg = getConcretMethodGen(m, class_name, cpg);
-
- String method_name = m.getName();
- Type returnType = mg.getReturnType();
- Type chainReturnType = object;
- Type[] argTypes = mg.getArgumentTypes();
-
- String name_chain = genChainMethName(method_name);
-
- InstructionList il = mg.getInstructionList();
-
- InstructionHandle startSynchronized;
- InstructionHandle chainCall;
- int monitor;
- // start generating
- {
- LocalVariableGen lg; // used for several local variables
-
- // Team[] _OT$teams;
- int teams;
- lg = mg.addLocalVariable(TEAMS, teamArray, null, null);
- teams = lg.getIndex();
-
- // synchronized (TopMostBoundBaseClass.class) {
- Pair<Integer,InstructionHandle> monitorResult = addClassMonitorEnter(mg, il, CallinBindingManager.getTopmostBoundBase(class_name), major, cpg);
- monitor = monitorResult.first;
- if (debugging)
- // no natural lines in this method: step-over until chain call, which has step-into: debugging => addLineNumber
- mg.addLineNumber(monitorResult.second, STEP_OVER_LINENUMBER);
-
- // _OT$teams= new Teams[_OT$activeTeams.length];
- startSynchronized= // begin area protected by exception handler
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(InstructionConstants.ARRAYLENGTH);
- il.append((Instruction)factory.createNewArray(teamType, (short) 1));
- il.append(InstructionFactory.createStore(Type.OBJECT, teams));
-
- // _OT$teamIDs=new int[_OT$activeTeamIDs.length];
- int teamIDs;
- lg = mg.addLocalVariable(TEAMIDS, intArray, null, null);
- teamIDs = lg.getIndex();
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
- il.append(InstructionConstants.ARRAYLENGTH);
- il.append((Instruction)factory.createNewArray(Type.INT, (short) 1));
- il.append(InstructionFactory.createStore(Type.OBJECT, teamIDs));
-
- // for (int i=0; i<_OT$activeTeams.length; ...
- int for_index;
- lg = mg.addLocalVariable("i", Type.INT, null, null); //$NON-NLS-1$
- for_index = lg.getIndex();
- il.append(new PUSH(cpg, 0));
- il.append(InstructionFactory.createStore(Type.INT, for_index));
- InstructionHandle for_start =
- il.append(InstructionFactory.createLoad(Type.INT, for_index));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(InstructionConstants.ARRAYLENGTH);
- BranchInstruction if_loop_finished =
- InstructionFactory.createBranchInstruction(Constants.IF_ICMPGE, null);
- il.append(if_loop_finished);
-
- // if (!_OT$activeTeams[i].isActive()) {
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(InstructionFactory.createLoad(Type.INT, for_index));
- il.append(InstructionConstants.AALOAD);
- il.append(factory.createInvoke(OTConstants.teamName, IS_ACTIVE, Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEINTERFACE));
- BranchInstruction if_team_isactive =
- InstructionFactory.createBranchInstruction(Constants.IFNE, null);
- il.append(if_team_isactive);
-
- // invalidate activation of current team:
- // _OT$teams[i]= null;
- il.append(InstructionFactory.createLoad(Type.OBJECT, teams));
- il.append(InstructionFactory.createLoad(Type.INT, for_index));
- il.append(InstructionConstants.ACONST_NULL);
- il.append(InstructionConstants.AASTORE);
-
- // _OT$teamIDs[i]= -1;
- il.append(InstructionFactory.createLoad(Type.OBJECT, teamIDs));
- il.append(InstructionFactory.createLoad(Type.INT, for_index));
- il.append(new PUSH(cpg, -1));
- il.append(InstructionConstants.IASTORE);
- BranchInstruction goto_continue =
- InstructionFactory.createBranchInstruction(Constants.GOTO, null);
- il.append(goto_continue);
-
- // } else { adopt activation of current team:
- // _OT$teams[i]= _OT$activeTeams[i];
- InstructionHandle adopt_activation =
- il.append(InstructionFactory.createLoad(Type.OBJECT, teams));
- il.append(InstructionFactory.createLoad(Type.INT, for_index));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(InstructionFactory.createLoad(Type.INT, for_index));
- il.append(InstructionConstants.AALOAD);
- il.append(InstructionConstants.AASTORE);
-
- // _OT$teamIDs[i]= _OT$activeTeamIDs[i];
- il.append(InstructionFactory.createLoad(Type.OBJECT, teamIDs));
- il.append(InstructionFactory.createLoad(Type.INT, for_index));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
- il.append(InstructionFactory.createLoad(Type.INT, for_index));
- il.append(InstructionConstants.IALOAD);
- il.append(InstructionConstants.IASTORE);
-
- // closing the above for: i++ and jump back:
- InstructionHandle do_continue =
- il.append(new IINC(for_index, 1));
- il.append(InstructionFactory.createBranchInstruction(Constants.GOTO, for_start));
-
- // link jump instructions to their targets:
- InstructionHandle loop_finished = il.append(new NOP()); // synthetic jump target
- if_loop_finished.setTarget(loop_finished);
- if_team_isactive.setTarget(adopt_activation);
- goto_continue.setTarget(do_continue);
-
- // No more access to array fields, release monitor:
- il.append(InstructionFactory.createLoad(Type.OBJECT, monitor));
- il.append(new MONITOREXIT());
-
- // load special arguments:
- if(!m.isStatic()) { // "this" cannot be accessed by static methods
- chainCall= il.append(InstructionFactory.createThis()); // this
- } else {
- chainCall= il.append(new NOP());
- }
-
- if (debugging)
- mg.addLineNumber(chainCall, STEP_INTO_LINENUMBER);
- // ih now points to end of area protected by exception handler
-
- il.append(InstructionFactory.createLoad(teamArray, teams)); // _OT$teams
- il.append(InstructionFactory.createLoad(intArray, teamIDs)); // _OT$teamIDs
- il.append(new ICONST(0)); // _OT$idx = 0
- il.append(new ICONST(0)); // _OT$bindIdx = 0
- il.append(new ICONST(-1)); // _OT$baseMethTag is unused here
- il.append(new ACONST_NULL()); // _OT$unusedArgs = null
- }
-
-
- // load regular arguments:
- int index = m.isStatic()?0:1;
- // chaining wrapper is always public, so never user INVOKESPECIAL:
- short invocationKind = m.isStatic()?Constants.INVOKESTATIC:Constants.INVOKEVIRTUAL;
-
- for (int i=0; i<argTypes.length; i++) {
- il.append(InstructionFactory.createLoad(argTypes[i],index));
- index += argTypes[i].getSize();
- }
- //
- il.append(factory.createInvoke(class_name, name_chain,
- chainReturnType,
- enhanceArgumentTypes(argTypes),
- invocationKind));
- // generated invoke: _OT$<method_name>$chain (a1,.. aN)
-
-
- adjustValue(il, null, chainReturnType, returnType);
- il.append(InstructionFactory.createReturn(returnType));
-
- // handler for exception within synchronized:
- LocalVariableGen ex= mg.addLocalVariable("exceptionInSynchronized", Type.THROWABLE, il.getEnd(), null); //$NON-NLS-1$
- InstructionHandle handler=
- il.append(InstructionFactory.createStore(Type.THROWABLE, ex.getIndex()));
- il.append(InstructionFactory.createLoad(Type.OBJECT, monitor));
- il.append(new MONITOREXIT());
- il.append(InstructionFactory.createLoad(Type.THROWABLE, ex.getIndex()));
- il.append(new ATHROW());
- mg.addExceptionHandler(startSynchronized, chainCall, handler, Type.THROWABLE);
-
- // tidy:
- mg.setMaxStack();
- mg.setMaxLocals();
- Method generatedMethod = mg.getMethod();
- il.dispose();
- return generatedMethod;
- }
-
- /**
- * Generate a version of the passed method which only calls its super method
- * (which will eventually call an initial-wrapper in a directly bound class).
- * @param m the original method
- * @param cg the ClassGen of the appropriate class
- * @param cpg the ConstantPoolGen of the class
- * @return the generated method
- */
- Method generateSuperCall (Method m,
- ClassGen cg,
- ConstantPoolGen cpg)
- {
- short invocationKind = m.isStatic() ? Constants.INVOKESTATIC : Constants.INVOKESPECIAL;
- MethodGen mg = getConcretMethodGen(m, cg.getClassName(), cpg);
-
- String method_name = m.getName();
- Type returnType = mg.getReturnType();
- Type[] argTypes = mg.getArgumentTypes();
- InstructionList il = mg.getInstructionList();
-
- if(logging) printLogMessage("\nReplacing with call to super: " + method_name); //$NON-NLS-1$
- // start generating
- if(!m.isStatic()){ //JU
- il.append(InstructionFactory.createThis());
- }
- int index = 1;
- for (int i=0; i<argTypes.length; i++) {
- il.append(InstructionFactory.createLoad(argTypes[i],index));
- index += argTypes[i].getSize();
- }
- il.append(factory.createInvoke(cg.getSuperclassName(), method_name,
- returnType, argTypes,
- invocationKind));
- il.append(InstructionFactory.createReturn(returnType));
- // generated invoke: return super.<method_name> (a1,.. aN)
-
- // tidy:
- mg.setMaxStack();
- mg.setMaxLocals();
- Method generatedMethod = mg.getMethod();
- il.dispose();
- return generatedMethod;
- }
-
-
- /**
- * Generate a chaining wrapper for the original method described by the passed arguments.
- * @param class_name the name of the appropriate class
- * @param cpg the ConstantPoolGen of the class
- * @param accessFlags raw flags of the method to add, visibility will however be ignored/set to public inside
- * @param method_name the name of the original method
- * @param method_signature the signature of the original method
- * @param argumentNames source level argument names, may be null
- * @return an new method with an empty instruction list
- */
- MethodGen generateChainingWrapper(String class_name,
- ConstantPoolGen cpg,
- int accessFlags,
- String method_name,
- String method_signature,
- String[] argumentNames)
- {
- Type[] argumentTypes = Type.getArgumentTypes(method_signature);
- if (argumentNames == null) {
- argumentNames = new String[argumentTypes.length];
- for (int i = 0; i < argumentNames.length; i++)
- argumentNames[i] = "arg"+i;
- }
- return new MethodGen(makePublicFlags(accessFlags), // the chaining wrapper has to be 'public' because it will be called by base calls:
- object, // ALWAYS!
- enhanceArgumentTypes(argumentTypes),
- enhanceArgumentNames(argumentNames),
- genChainMethName(method_name),
- class_name,
- new InstructionList(),
- cpg);
- }
-
- /**
- * Create the instructions for the chaining wrapper, which includes dispatch code
- * and the termination condition for the recursion.
- * @param class_name
- * @param cg
- * @param cpg
- * @param mg
- * @param method_name
- * @param method_signature
- * @param chainMethod
- * @param firstLine
- * @return
- */
- Method generateChainingWrapperBody(String class_name,
- ClassGen cg,
- ConstantPoolGen cpg,
- MethodGen mg,
- String method_name,
- String method_signature,
- MethodGen chainMethod,
- int firstLine)
- {
- Type origReturnType = mg.getReturnType();
- Type[] argumentTypes = mg.getArgumentTypes();
- Type enhancedReturnType = chainMethod.getReturnType();
- InstructionList il = chainMethod.getInstructionList();
-
- // All chaining calls return an Object.
- // Need to store this in a local variable to keep the stack
- // balanced, because each section (before, replace, after)
- // is guarded by its own exception handler, and they don't
- // like pending objects on the stack.
- InstructionHandle ih;
- int result, ot_team;
- {
- LocalVariableGen lg =
- chainMethod.addLocalVariable("_OT$result", enhancedReturnType, //$NON-NLS-1$
- null, null);
- result = lg.getIndex();
- ih = il.append(InstructionFactory.createNull(enhancedReturnType));
- if (debugging)
- chainMethod.addLineNumber(ih, STEP_OVER_LINENUMBER);
- lg.setStart(il.append(InstructionFactory.createStore(enhancedReturnType, result)));
- // generated: RType _OT$result = null;
-
- lg = chainMethod.addLocalVariable("_OT$team", teamType, null, null); //$NON-NLS-1$
- ot_team = lg.getIndex();
- // generated: Team _OT$team;
- }
-
- int indexOffset = chainMethod.isStatic() ? -1 : 0; // argument indizes are decremented for static methods,
- // because of the missing 'this'
- short invocationKind = getInvocationType(mg);
-
- il.append(InstructionFactory.createLoad(Type.INT, IDX_ARG + indexOffset));
- il.append(InstructionFactory.createLoad(teamArray, TEAMS_ARG + indexOffset));
- il.append(new ARRAYLENGTH());
- IF_ICMPLT recursionNotYetTerminated = new IF_ICMPLT(null);
- il.append(recursionNotYetTerminated);
- // generated: if (_OT$teams.length < _OT$idx) {
-
-
- // load arguments:
- if (!chainMethod.isStatic()) {
- ih = il.append(InstructionFactory.createThis());
- } else {
- ih = il.append(new NOP());
- }
- if (debugging)
- chainMethod.addLineNumber(ih, SHOW_ORIG_CALL ? firstLine : STEP_INTO_LINENUMBER); // show orig call at method header ("dispatching")
-
- int index = EXTRA_ARGS + 1;
- for (int i = 0; i < argumentTypes.length; i++) {
- il.append(InstructionFactory.createLoad(argumentTypes[i], index + indexOffset));
- index += argumentTypes[i].getSize();
- }
- //
- il.append(factory.createInvoke(class_name, genOrigMethName(method_name),
- origReturnType, argumentTypes,
- invocationKind));
- // generated: this._OT$<method_name>$orig (a1,.., aN) for nonstatic case
- // _OT$<method_name>$orig (a1,.., aN) for static case
-
- if (debugging)
- chainMethod.addLineNumber(il.append(new NOP()), STEP_OVER_LINENUMBER);
-
- adjustValue(il, null, origReturnType, enhancedReturnType);
- il.append(InstructionFactory.createReturn(enhancedReturnType));
- // generated: return _OT$result;
-
- ih = il.append(new NOP());
- recursionNotYetTerminated.setTarget(ih);
- // generated: ; (end of the if part)
-
- il.append(InstructionFactory.createLoad(teamArray, TEAMS_ARG + indexOffset));
- il.append(InstructionFactory.createLoad(Type.INT, IDX_ARG + indexOffset));
- il.append(InstructionFactory.createArrayLoad(teamType));
- il.append(InstructionFactory.createStore(teamType, ot_team));
- // generated: _OT$team = _OT$teams[_OT$idx];
-
- // ---------------------------------------------
- createDispatchCode(chainMethod, il,
- class_name, method_name,
- method_signature, result, ot_team, cg, firstLine);
- // ---------------------------------------------
-
- ih = il.append(InstructionFactory.createLoad(enhancedReturnType, result));
- il.append(InstructionFactory.createReturn(enhancedReturnType));
- // generated: return _OT$result;
- if (debugging)
- chainMethod.addLineNumber(ih, STEP_OVER_LINENUMBER);
-
- // tidy:
- chainMethod.removeNOPs();
- try { // [SH]: overcautious: I once saw this CCE with no clue, why it happened :(
- chainMethod.setMaxStack();
- } catch (ClassCastException cce) {
- System.err.println(chainMethod);
- cce.printStackTrace();
- }
- chainMethod.setMaxLocals();
- //chainMethod.removeNOPs();
- Method generated = chainMethod.getMethod();
- il.dispose();
- return generated;
- }
-
- private short getInvocationType(MethodGen chainMethod) {
- if (chainMethod.isStatic())
- return Constants.INVOKESTATIC;
- if (chainMethod.isPrivate())
- return Constants.INVOKESPECIAL;
- else
- return Constants.INVOKEVIRTUAL;
- }
-
- /**
- * @param i
- * @return
- */
- private static int makePublicFlags(int flags) {
- if ((flags & Constants.ACC_PUBLIC) != 0) {
- return flags;
- }
- if ((flags & Constants.ACC_PRIVATE) != 0) {
- flags &= ~Constants.ACC_PRIVATE;
- } else if ((flags & Constants.ACC_PROTECTED) != 0) {
- flags &= ~Constants.ACC_PROTECTED;
- }
- flags |= Constants.ACC_PUBLIC;
- return flags;
- }
-
- /**
- * Generate the dispatch code by which a chaining wrapper invokes the
- * callin method(s).
- * This consists of three switch blocks: before, replace, after.
- * @param chainMethod the chaining wrapper method
- * @param il the InstructionList of the chaining wrapper
- * @param class_name the name of the appropriate class
- * @param method_name the name of the original method
- * @param method_signature the signature of the original method
- * @param result the index of the '_OT$result' variable
- * @param ot_team the index of the variable containing the team currently processed by the chaining wrapper
- * @param cg the ClassGen of the appropriate class
- * @param firstLine the first real source line of this method
- */
- void createDispatchCode(MethodGen chainMethod, InstructionList il,
- String class_name, String method_name,
- String method_signature, int result, int ot_team, ClassGen cg, int firstLine)
- {
-
- // get bindings for actually modified methods and sort them by callin-modifier:
- // modifier -> ArrayList<MethodBinding>
- HashMap<String, ArrayList<MethodBinding>> sortedMethodBindings = new HashMap<String, ArrayList<MethodBinding>>();
- Collection<MethodBinding> callinsForMethod;
- callinsForMethod = CallinBindingManager.getBindingForBaseMethod(class_name,
- method_name, method_signature);
- //System.err.println(class_name +" : "+callinsForMethod);
- List<MethodBinding> inheritedMethodBindings = CallinBindingManager.getInheritedBaseMethodBindings(class_name, method_name, method_signature);
- //System.err.println(inheritedMethodBindings);
-
- //--------------------------------------------------------------------------------------------
- //JU: initialize callinsForMethod for overridden static base methods (begin)
-// if(chainMethod.isStatic()){
-// if(callinsForMethod == null) {
-// callinsForMethod = new LinkedList();
-// }
-//
-// Collection classesDefBindingsToStaticMethods = CallinBindingManager.getInheritedCallinBindingsForStaticMethods(class_name, method_name, method_signature);
-// Iterator classesIt = classesDefBindingsToStaticMethods.iterator();
-// while(classesIt.hasNext()){
-// String superClassName = (String) classesIt.next();
-// Collection callinsFromSuperClasses = CallinBindingManager.getBindingForBaseMethod(superClassName, method_name, method_signature);
-// callinsForMethod.addAll(callinsFromSuperClasses);
-// }
-// }
- //JU: (end)
- //----------------------------------------------------------------------------------------------
- if (!chainMethod.isStatic())
- callinsForMethod.addAll(inheritedMethodBindings);
-
- /*
- String[] interfaceNames = cg.getInterfaceNames();
- Collection interfaceInheritedMethodBindings = new LinkedList();
- for (int i=0; i<interfaceNames.length;i++) {
- if (!interfaceNames[i].equals(class_name))
- interfaceInheritedMethodBindings.addAll(
- CallinBindingManager.getInterfaceInheritedMethodBindings(method_name,
- method_signature,
- interfaceNames[i]));
- }
-
- if (callinsForMethod == null)
- callinsForMethod = new LinkedList();
-
- callinsForMethod.addAll(interfaceInheritedMethodBindings);
- */
- ListValueHashMap<MethodBinding> beforeBindings = new ListValueHashMap<MethodBinding>();
- ListValueHashMap<MethodBinding> replaceBindings = new ListValueHashMap<MethodBinding>();
- ListValueHashMap<MethodBinding> afterBindings = new ListValueHashMap<MethodBinding>();
-
- Iterator<MethodBinding> it = callinsForMethod.iterator();
- while (it.hasNext()) {
- MethodBinding methodBinding = it.next();
- //sourceMapGen.addSourceMapInfo(methodBinding);
- String modifier = methodBinding.getModifier();
- ArrayList<MethodBinding> bindings = sortedMethodBindings.get(modifier);
- if (bindings == null) {
- bindings = new ArrayList<MethodBinding>();
- sortedMethodBindings.put(modifier, bindings);
- }
- bindings.add(methodBinding);
- // ----> added for predecedence purpose:
- String teamName = methodBinding.getTeamClassName();
- if (modifier.equals("before")) { //$NON-NLS-1$
- beforeBindings.put(teamName, methodBinding);
- } else if (modifier.equals("replace")) { //$NON-NLS-1$
- replaceBindings.put(teamName, methodBinding);
- } else if (modifier.equals("after")) { //$NON-NLS-1$
- afterBindings.put(teamName, methodBinding);
- }
- // <---
- }
-
- // if any team has multiple bindings, we need to insert additional checks to avoid duplicate
- // invocation of before/after causes during recursion.
- boolean useBindingIdx = false;
- for (LinkedList<MethodBinding> perTeamMethods : replaceBindings.valueSet())
- if (perTeamMethods.size() > 1) {
- useBindingIdx = true;
- break;
- }
-
- /****************************************************************************/
- // before callin :
- if (sortedMethodBindings.containsKey("before")) { //$NON-NLS-1$
- if(logging) printLogMessage("before bindings will be applied..."); //$NON-NLS-1$
- il.append(createSwitch(
- beforeBindings,
- chainMethod, ot_team,
- NORESULT, firstLine, cg.getMajor(), useBindingIdx));
- if(logging) printLogMessage("before bindings: " //$NON-NLS-1$
- + sortedMethodBindings.get("before")); //$NON-NLS-1$
- }
- /****************************************************************************/
- // replacement callin or direct recursion :
- if (sortedMethodBindings.containsKey("replace")) { //$NON-NLS-1$
- if(logging) printLogMessage("recursive call and replace bindings will be applied..."); //$NON-NLS-1$
- il.append(createSwitch(
- replaceBindings,
- chainMethod, ot_team,
- result, firstLine, cg.getMajor(), useBindingIdx));
- if(logging) printLogMessage("replace bindings: " //$NON-NLS-1$
- + sortedMethodBindings.get("replace")); //$NON-NLS-1$
- } else {
- if(logging) printLogMessage("recursive chain-method call will be done..."); //$NON-NLS-1$
- // recursive call:
-
- createRecursiveCall(il, chainMethod, result, 1, 0, method_name, method_signature, firstLine);
- }
- /****************************************************************************/
- // after callin :
- if (sortedMethodBindings.containsKey("after")) { //$NON-NLS-1$
- if(logging) printLogMessage("after bindings will be applied..."); //$NON-NLS-1$
- il.append(createSwitch(
- afterBindings,
- chainMethod, ot_team,
- /*NORESULT*/result, firstLine, cg.getMajor(), useBindingIdx));
- if(logging) printLogMessage("after bindings: " //$NON-NLS-1$
- + sortedMethodBindings.get("after")); //$NON-NLS-1$
- }
- }
-
- /**
- * Create a switch statement which contains one case for each MethodBinding
- * in a given list.
- * The switch block is furthermore wrapped in a try-catch block.
- * Herein all {@link org.objectteams.LiftingVetoException LiftingVetoException}
- * are caught, and possibly reported (if Dot.log.lift ist set).
- * @param methodBindings hash map of team names to 'MethodBinding' lists
- * @param mg method being generated.
- * @param ot_team index of local variable <tt>_OT$team</tt>
- * @param ot_result index of local variable <tt>_OT$result</tt>
- */
- private InstructionList createSwitch(ListValueHashMap<MethodBinding> methodBindings, MethodGen mg,
- int ot_team, int ot_result,
- int firstLine,
- int major,
- boolean useBindingIdx)
- {
- InstructionList il = new InstructionList();
-
- boolean handlesReplacement = false;
-
- int indexOffset = mg.isStatic()?-1:0; // argument indizes are decremented for static methods,
- // because of the missing 'this'
-
- // load value to be switched:
- il.append(InstructionFactory.createLoad(intArray, TEAMIDS_ARG+indexOffset));
- il.append(InstructionFactory.createLoad(Type.INT, IDX_ARG+indexOffset));
- InstructionHandle switchStart = il.append(InstructionFactory.createArrayLoad(Type.INT));
- // generated: _OT$teamIDs[_OT$idx]
-
- int numberOfCases = methodBindings.size();
-
- // one break for each case clause
- GOTO[] breaks = new GOTO[numberOfCases];
- for (int i = 0; i < numberOfCases; i++)
- breaks[i] = new GOTO(null);
-
- int[] matches = new int[numberOfCases];
- InstructionHandle[] targets = new InstructionHandle[numberOfCases];
-
- int caseCounter = 0;
-
- List<MethodBinding> methodBindingsForTeam = null;
- MethodBinding mb = null;
- Iterator <Entry<String, LinkedList<MethodBinding>>> teamIterator = methodBindings.entrySet().iterator();
- while (teamIterator.hasNext()) {
- Entry<String, LinkedList<MethodBinding>> entry = teamIterator.next();
- String teamName = entry.getKey();
- methodBindingsForTeam = CallinBindingManager.sortMethodBindings(entry.getValue(), teamName);
- //System.out.println(methodBindings.get(teamName));
-
- /*MethodBinding*/ mb = methodBindingsForTeam.get(0);
-
- matches[caseCounter] = TeamIdDispenser.getTeamId(teamName);
- InstructionHandle nextBranch = il.append(new NOP());
-
- // generate (_OT$teamID == teamId) branch here:
-
- // ========== create Cases: ==========
- if (mb.isReplace()) { // distinct treatment of replacement:
- handlesReplacement = true;
- createReplaceCase(mg, il,
- teamName, methodBindingsForTeam,
- ot_result, ot_team, major, firstLine);
- } else { // before or after callin:
- BranchInstruction ifBindingIdx = null;
- if (useBindingIdx) {
- // only if bindingIdx == 0
- il.append(InstructionFactory.createLoad(Type.INT, BIND_IDX_ARG+indexOffset));
- ifBindingIdx= new IFNE(null);
- il.append(ifBindingIdx);
- }
- createBeforeAfterCase(mg, il, teamName,
- methodBindingsForTeam, ot_result, ot_team, major, firstLine);
- if (useBindingIdx) {
- ifBindingIdx.setTarget(il.append(new NOP()));
- }
- }
-
- // ===================================
-
- targets[caseCounter] = nextBranch;
- /*InstructionHandle break_instr =*/ il.append(breaks[caseCounter]);
- // generated: break;
-
- caseCounter++;
- } // end of while
-
- // generate default branch here:
- InstructionHandle defaultBranch = il.append(new NOP());
- if (handlesReplacement)
- createRecursiveCall(il, mg, ot_result, 1, 0, mb.getBaseMethodName(), mb.getBaseMethodSignature(), firstLine);
-
- InstructionHandle afterSwitch = il.append(new NOP()); // all breaks point here.
-
- // ===== assemble the switch ====
- il.append(switchStart,
- createLookupSwitch(matches, targets, breaks,
- defaultBranch, afterSwitch)
- );
- // ==============================
-
- // wrap everything in a try {} catch (LiftingVetoException e) {..}
- InstructionHandle endTry = il.getEnd();
-
- GOTO skipHdlr = null;
- skipHdlr = new GOTO(null);
- il.append(skipHdlr);
- // generated: goto normal exit
-
- InstructionHandle hdlr = il.append(new NOP());
- il.append(DebugUtil.createReportExc(factory));
-
- // catch: proceed with recursion if caught in a replace call
- if (handlesReplacement)
- createRecursiveCall(il, mg, ot_result, 1, 0, mb.getBaseMethodName(), mb.getBaseMethodSignature(), firstLine);
-
- mg.addExceptionHandler(il.getStart(), endTry, hdlr, liftingVeto);
-
- InstructionHandle nop = il.append(new NOP());
- skipHdlr.setTarget(nop);
-
- return il;
- }
-
- /** Create the recursice call of this chaining method.
- * @param il insert the call into this list.
- * @param mg this chaining method
- * @param ot_result stack index of the _OT$result variable or NORESULT.
- * @param idx_offset TODO
- * @param bindIdx_offset TODO
- * @param methodName TODO
- * @param methodSignature TODO
- */
- void createRecursiveCall (InstructionList il,
- MethodGen mg,
- int ot_result, int idx_offset, int bindIdx_offset, String methodName, String methodSignature, int firstLine)
- {
- InstructionHandle ih = !mg.isStatic()
- ? il.append(InstructionFactory.createThis())
- : il.append(new NOP());
- if (debugging)
- mg.addLineNumber(ih, SHOW_RECURSIVE_CALL ? firstLine : STEP_INTO_LINENUMBER); // show recursive call at method header ("dispatching")
-
- Type[] argTypes = mg.getArgumentTypes();
- Type returnType = mg.getReturnType();
- short invocationKind = getInvocationType(mg);
-
- // arguments: no adjustment except idx++.
- int index = 1;
- int indexOffset = mg.isStatic()?-1:0; // argument indizes are decremented for static methods,
- // because of the missing 'this'
- for (int i=0; i<argTypes.length; i++) {
- il.append(InstructionFactory.createLoad(argTypes[i], index+indexOffset));
- if (index == OTConstants.IDX_ARG && idx_offset != 0) { // _OT$idx has to be incremented (adding idx_offset)
- il.append(new ICONST(idx_offset));
- il.append(new IADD());
- } else if (index == OTConstants.BIND_IDX_ARG) { // _OT$bindIdx has to be incremented (adding bindIdx_offset)
- if (bindIdx_offset == 0) { // bindArg argument has to be set to '0'
- il.append(new POP()); // remove loaded _OT$bindIdx
- il.append(new ICONST(0)); // replace it by '0'
- } else {
- il.append(new ICONST(bindIdx_offset));
- il.append(new IADD());
- }
- }
- index += argTypes[i].getSize();
- }
- il.append(factory.createInvoke(mg.getClassName(), mg.getName(),
- returnType, argTypes,
- invocationKind));
-
- il.append(InstructionFactory.createStore(returnType, ot_result));
-
- // _OT$result = _OT$<method_name>$chain(_OT$teams, _OT$teamIDs, _OT$idx+1,
- // a1, .., aN);
- if (debugging)
- mg.addLineNumber(il.append(new NOP()), STEP_OVER_LINENUMBER);
- }
-
-
- /**
- * Create a block for a before or after callin as a case with a surrounding switch.
- * @param mg TODO
- * @param il InstructionList being assembled.
- * @param teamClassName name of a Team which has a callin to this method.
- * @param sortedMBList MethodBindings describing the callins (already processed by CallinBindingManager.sortMethodBindings)
- * @param ot_result index of local variable <tt>_OT$result</tt>.
- * @param ot_team index of local variable <tt>_OT$team</tt>.l
- * @param major
- * @param firstLine the first real source line of this method
- */
- void createBeforeAfterCase(MethodGen mg,
- InstructionList il, String teamClassName,
- List<MethodBinding> sortedMBList, int ot_result, int ot_team,
- int major, int firstLine)
- {
-
- MethodBinding mb = sortedMBList.get(0);
- ConstantPoolGen cpg = mg.getConstantPool();
-
- // after bindings are processed back-to-front:
- if (mb.isAfter()) {
- List<MethodBinding> reverse = new ArrayList<MethodBinding>(sortedMBList.size());
- for(int i=sortedMBList.size()-1; i>=0; i--)
- reverse.add(sortedMBList.get(i));
- sortedMBList = reverse;
- }
-
- Iterator<MethodBinding> it = sortedMBList.iterator();
- while (it.hasNext()) {
- /*MethodBinding nextMethodBinding*/mb = it.next();
-
- String baseMethodSignature = mb.getBaseMethodSignature();
- Type[] baseArgTypes = Type.getArgumentTypes(baseMethodSignature);
- Type baseReturnType = Type.getReturnType(baseMethodSignature);
-
- Type[] wrapperArgTypes = Type.getArgumentTypes(mb.getWrapperSignature());
- int argsLen = wrapperArgTypes.length - 1; // don't count base arg.
-
- il.append(InstructionFactory.createLoad(teamType, ot_team));
-
- int packedArgPos = 0;
- InstructionHandle argArray = null;
- if (useReflection) {
- il.append(factory.createInvoke("java.lang.Object", "getClass", classType, new Type[0], Constants.INVOKEVIRTUAL));
- il.append(new LDC(cpg.addString(mb.getWrapperName())));
- pushTypeArray(il, wrapperArgTypes, major, cpg);
- il.append(factory.createInvoke("java.lang.Class", "getMethod", methodType, OTConstants.getMethodSignature, Constants.INVOKEVIRTUAL));
-
- il.append(InstructionFactory.createLoad(teamType, ot_team));
- // generated:
- // _OT$team.getClass().getMethod(<wrapperName>, <wrapper sign>)
- // _OT$team
- argArray = il.append(new ANEWARRAY(cpg.addClass(object)));
-
- } else {
- il.append(factory.createCast(teamType, new ObjectType(teamClassName)));
- // generated: (<TeamClass>)_OT$team
- }
-
- // first argument: base object:
- packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
- {
- if (!mg.isStatic())
- il.append(InstructionFactory.createThis());
- else
- il.append(InstructionFactory.createNull(Type.OBJECT)); // no base object
- }
- checkPackValue1(il, useReflection, Type.OBJECT);
-
- // second argument: base result (if appropriate)
- if ( mb.isAfter() && !baseReturnType.equals(Type.VOID)) { // after callin wrapper get the base method result as second argument
- packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
- {
- il.append(InstructionFactory.createLoad(object, ot_result));
- adjustValue(il, null, object, baseReturnType);
- argsLen --; // the second (result) arg is also not part of the arg list
- }
- checkPackValue1(il, useReflection, baseReturnType);
- }
-
- // ------- load regular args: --------
-
- // stack positions for load instructions (one-based for non-statics, since 0 == this)
- int stackIndex = EXTRA_ARGS + (mg.isStatic() ? 0 : 1);
- // where within baseArgTypes do source arguments start?
- int firstArg = 0;
-
- if (mb.baseMethodIsCallin()) {
- // skip enhancement of this callin method (lower role).
- firstArg += EXTRA_ARGS;
- stackIndex += EXTRA_ARGS;
- argsLen += EXTRA_ARGS;
- }
- for (int i = firstArg; i < argsLen; i++) {
- if(logging) printLogMessage("loading " + baseArgTypes[i].toString()); //$NON-NLS-1$
-
- packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
- {
- il.append(InstructionFactory.createLoad(baseArgTypes[i],stackIndex));
- }
- checkPackValue1(il, useReflection, baseArgTypes[i]);
-
- stackIndex += baseArgTypes[i].getSize();
- }
-
- InstructionHandle callinCall;
- if (useReflection) {
- // this information was missing above:
- il.insert(argArray, createIntegerPush(cpg, packedArgPos));
-
- callinCall = il.append(factory.createInvoke("java.lang.reflect.Method", "invoke", object, new Type[]{object, objectArray}, Constants.INVOKEVIRTUAL));
- il.append(new POP()); // before/after wrappers return void
- } else {
- callinCall = il.append(factory.createInvoke(teamClassName,
- mb.getWrapperName(),
- Type.VOID, wrapperArgTypes,
- Constants.INVOKEVIRTUAL));
- }
- if (debugging) {
- mg.addLineNumber(callinCall, SHOW_ROLE_CALL ? firstLine : STEP_INTO_LINENUMBER); // show role call at method header ("dispatching")
- mg.addLineNumber(il.append(new NOP()), STEP_OVER_LINENUMBER);
- }
- }
- }
-
- /* this and the next method serve as a bracket for all pushes that may or may not require
- * packing in an array, the array must already exist on the stack. */
- private int checkPackValue0(InstructionList il, boolean doPack, int argCount, ConstantPoolGen cpg) {
- if (doPack) {
- il.append(new DUP());
- il.append(createIntegerPush(cpg, argCount));
- return argCount+1;
- } else {
- return argCount;
- }
- }
- private void checkPackValue1(InstructionList il, boolean doPack, Type argType) {
- if (doPack) {
- if (argType instanceof BasicType)
- il.append(createBoxing((BasicType)argType));
- il.append(new AASTORE());
- }
- }
- /* Push an array of Class representing the signature given by argTypes. */
- private void pushTypeArray(InstructionList il, Type[] argTypes, int major, ConstantPoolGen cpg) {
- il.append(createIntegerPush(cpg, argTypes.length));
- il.append(new ANEWARRAY(cpg.addClass(classType)));
- for (int i=0; i<argTypes.length; i++) {
- Type type = argTypes[i];
- il.append(new DUP());
- il.append(createIntegerPush(cpg, i));
- if (type instanceof BasicType) {
- il.append(factory.createFieldAccess(toObjectTypeName((BasicType)type), "TYPE", classType, Constants.GETSTATIC));
- } else if (type instanceof ObjectType) {
- appendClassLiteral(il, ((ObjectType)type).getClassName(), major, cpg);
- } else if (type instanceof ArrayType) {
- String prefix = "";
- while (type instanceof ArrayType) {
- prefix += '[';
- type = ((ArrayType)type).getElementType();
- }
- String elemTypeName = null;
- if (type instanceof ObjectType)
- elemTypeName = "L"+((ObjectType)type).getClassName()+';';
- else if (type instanceof BasicType)
- elemTypeName = ((BasicType)type).getSignature();
- appendClassLiteral(il, prefix+elemTypeName, major, cpg);
- } else {
- throw new OTREInternalError("unsupported type in signature "+type);
- }
- il.append(new AASTORE());
- }
- }
-
- /**
- * Create a block for a replace callin as a case within a surrounding switch. If there are multiple bindings from the
- * same team to this base method, the bindings are sorted according to the precedence list of this team.
- * @param mg base method being generated.
- * @param il instruction list being assembled.
- * @param teamClassName name of a Team which has a callin to this method.
- * @param sortedMBList MethodBindings describing the callins (already processed by CallinBindingManager.sortMethodBindings)
- * @param ot_result index of a local variable <tt>_OT$result</tt>.
- * @param ot_team index of local variable <tt>_OT$team</tt>.
- * @param major class file version
- */
- void createReplaceCase(MethodGen mg, InstructionList il,
- String teamClassName, List<MethodBinding> sortedMBList,
- int ot_result, int ot_team, int major, int firstLine)
- {
-
- int indexOffset = mg.isStatic() ? -1 : 0; // argument indizes are decremented for static methods,
- // because of the missing 'this'
- boolean multipleBindings = sortedMBList.size() > 1;
-
- LocalVariableGen unused_args_lg = mg.addLocalVariable(UNUSED, objectArray, null, null);
- int unused_args = unused_args_lg.getIndex();
- unused_args_lg.setStart(il.append(new NOP()));
- if (multipleBindings) {
- InstructionList addition = new InstructionList();
- // load value to be switched:
-
- InstructionHandle switchStart = addition.append(InstructionFactory.createLoad(Type.INT, BIND_IDX_ARG+indexOffset));
- // loaded _OT$bindIdx
-
- int numberOfCases = sortedMBList.size();
-
- // one break for each case clause
- GOTO[] breaks = new GOTO[numberOfCases];
- for (int i=0; i<numberOfCases; i++)
- breaks[i] = new GOTO(null);
-
- int[] matches = new int[numberOfCases];
- InstructionHandle[] targets = new InstructionHandle[numberOfCases];
-
- int caseCounter = 0;
- Iterator<MethodBinding> mbIterator = sortedMBList.iterator();
- MethodBinding mb = null; // safe because loop will definitely be entered (mbList.size() > 1)
- while (mbIterator.hasNext()) {
- mb = mbIterator.next();
- matches[caseCounter] = caseCounter;
- InstructionHandle nextBranch = addition.append(new NOP());
- // ========== create Cases: ===========
- addition.append(createSingleReplaceCallin(mg, teamClassName, mb, ot_result, ot_team, unused_args, multipleBindings, mg.isStatic(), major, firstLine));
- // ==============================
- targets[caseCounter] = nextBranch;
- /*InstructionHandle break_instr =*/ addition.append(breaks[caseCounter]);
- // generated: break;
- caseCounter++;
- }
- // ========== create default: ===========
- InstructionHandle defaultBranch = addition.append(new NOP());
- createRecursiveCall(addition, mg, ot_result, 1, 0, mb.getBaseMethodName(), mb.getBaseMethodSignature(), firstLine);
- // ==============================
-
- InstructionHandle afterSwitch = addition.append(new NOP()); // all breaks point here.
-
- for (int i=0; i<numberOfCases; i++)
- breaks[i].setTarget(afterSwitch);
-
- addition.append(switchStart, new TABLESWITCH(matches, targets, defaultBranch));
- // wrap everything in a try {} catch (LiftingVetoException e) {..}
- InstructionHandle endTry = addition.getEnd();
-
- GOTO skipHdlr = null;
- skipHdlr = new GOTO(null);
- addition.append(skipHdlr);
- // generated: goto normal exit
-
- InstructionHandle hdlr = addition.append(new NOP());
- addition.append(DebugUtil.createReportExc(factory));
-
- // ========== create catch instructions: ===========
- createRecursiveCall(addition, mg, ot_result, 0, 1, mb.getBaseMethodName(), mb.getBaseMethodSignature(), firstLine);
- // =====================================
- mg.addExceptionHandler(addition.getStart(), endTry, hdlr, liftingVeto);
-
- InstructionHandle nop = addition.append(new NOP());
- skipHdlr.setTarget(nop);
- il.append(addition);
- } else { // only a single replace callin:
- MethodBinding mb = sortedMBList.get(0); // default, if only one binding exists
- il.append(createSingleReplaceCallin(mg, teamClassName, mb, ot_result, ot_team, unused_args, multipleBindings, mg.isStatic(), major, firstLine));
- }
- unused_args_lg.setEnd(il.getEnd());
- }
-
- /**
- * Creates a single replace callin call.
- *
- * @param mg base method being generated.
- * @param connectorClassName name of a Team which has a callin to this method.
- * @param mb the 'MethodBinding' for this callin.
- * @param ot_result index of a local variable <tt>_OT$result</tt>.
- * @param ot_team index of local variable <tt>_OT$team</tt>.
- * @param unused_args index of local variable <tt>_OT$unused_args</tt>.
- * @param multipleBindings flag indicating if there are multiple bindings in this case
- * @param staticBaseMethod TODO
- * @param major class file version
- * @param firstLine first real source line number of this method
- * @return instruction list for the callin call
- */
- private InstructionList createSingleReplaceCallin(MethodGen mg, String connectorClassName, MethodBinding mb, int ot_result, int ot_team, int unused_args, boolean multipleBindings, boolean staticBaseMethod, int major, int firstLine)
- {
- // Sequence of values to load is (letters refer to document parameter-passing.odg):
- // (f) _OT$team: call target for invoking the callin-wrapper
- // (g) baseObject: this or null
- // (h) enhancement: [Team[IIII[Object;
- // idxs are being manipulated here,
- // unusedArgs[] is allocated and filled with
- // (i) - (int,Team) if current method is static role method.
- // (j) - enhancement arguments, if current method is callin method
- // (k) regular arguments.
-
- // ------------------------------------------
- // prepare Types:
- // ------------------------------------------
- Type[] chainArgTypes = mg.getArgumentTypes();
- Type[] baseArgTypes = Type.getArgumentTypes(mb.getBaseMethodSignature());
- Type[] roleArgTypes = Type.getArgumentTypes(mb.getRoleMethodSignature());
- roleArgTypes = enhanceArgumentTypes(roleArgTypes);
- String wrapperName = mb.getWrapperName();
- Type wrapperReturnType = Type.getReturnType(mb.getWrapperSignature());
-
- Type[] wrapperArgTypes = Type.getArgumentTypes(mb.getWrapperSignature());
-
- // calculate return type:
- Type chainReturnType = mg.getReturnType();
-
- ConstantPoolGen cpg = mg.getConstantPool();
- InstructionList il = new InstructionList();
- // (f):
- il.append(InstructionFactory.createLoad(teamType, ot_team));
-
- int packedArgPos = 0;
- InstructionHandle argArray = null;
- if (useReflection) {
- il.append(factory.createInvoke("java.lang.Object", "getClass", classType, new Type[0], Constants.INVOKEVIRTUAL));
- il.append(new LDC(cpg.addString(mb.getWrapperName())));
- pushTypeArray(il, wrapperArgTypes, major, cpg);
- il.append(factory.createInvoke("java.lang.Class", "getMethod", methodType, OTConstants.getMethodSignature, Constants.INVOKEVIRTUAL));
-
- il.append(InstructionFactory.createLoad(teamType, ot_team));
- // generated:
- // _OT$team.getClass().getMethod(<wrapperName>, <wrapper sign>)
- // _OT$team
- argArray = il.append(new ANEWARRAY(cpg.addClass(object)));
- } else {
- il.append(factory.createCast(teamType, new ObjectType(connectorClassName)));
- // generated: (<TeamClass>)_OT$team
- }
-
- // (g):
- packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
- {
- if(!staticBaseMethod)
- il.append(InstructionFactory.createThis());
- else
- il.append(InstructionFactory.createNull(Type.OBJECT)); // no base object
- }
- checkPackValue1(il, useReflection, Type.OBJECT);
-
- // ----------------------------------------
- // (h) Load Extra Arguments:
- // ----------------------------------------
- int staticOffset = staticBaseMethod?-1:0; // argument indizes are decremented for static methods,
- // because of the missing 'this'
- // first 4 extra arguments: _OT$teams, _OT$teamIDs, _OT$idx, _OT$bindIdx
- for (int i=0; i<4; i++) { // If this is called only once _OT$idx has to be incremented, else _OT$bindIdx has to be incremented
- packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
- {
- il.append(InstructionFactory.createLoad(chainArgTypes[i], i+1+staticOffset));
- if (!multipleBindings && i+1+staticOffset == OTConstants.IDX_ARG+staticOffset) {// _OT$idx++:
- il.append(new ICONST(1));
- il.append(new IADD());
- } else if (multipleBindings && i+1+staticOffset == OTConstants.BIND_IDX_ARG+staticOffset) {// _OT$bindIdx:
- il.append(new ICONST(1));
- il.append(new IADD());
- }
- }
- checkPackValue1(il, useReflection, chainArgTypes[i]);
- }
- // _OT$baseMethTag:
- int base_meth_tag = CallinBindingManager.getBaseCallTag(mb.getBaseClassName(),
- mb.getBaseMethodName(),
- mb.getBaseMethodSignature());
-// //JU: added this if-statement (begin) ----------------------------------------------
-// if(staticBaseMethod && !mg.getClassName().equals(mb.getBaseClassName())){
-// //the method binding is a dummy -> the callin wrapper is performed
-// //with an invalid base method tag value -> an exception will be thrown
-// base_meth_tag = INVALID_BASE_METHOD_TAG;
-// }
-// //JU (end) --------------------------------------------------------------------------
-
- packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
- {
- il.append(createIntegerPush(cpg, base_meth_tag));
- }
- checkPackValue1(il, useReflection, Type.INT);
-
- // collect regular args first, insert into il later:
- InstructionList regularArgs = new InstructionList();
-
- // put "new Object[]" on stack, later containing unused arguments:
- packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
- {
- il.append(createIntegerPush(cpg, baseArgTypes.length));
- // enough space to hold ALL base arguments
- // Note that the callin wrapper may add more elements to this array.
- il.append((Instruction)factory.createNewArray(object, (short)1));
- il.append(InstructionFactory.createStore(objectArray, unused_args));
- // generated: _OT$unusedArgs = new Object[<n_base_args>];
-
- // ----------------------------------------
- // handle more arguments: load regular ones, store unused arguments into the array:
- // ----------------------------------------
- int unusedArgsIdx = 0; // index into Object[].
-
- int stackIdx = EXTRA_ARGS + 1 + staticOffset; // one-based, since 0 == this (unless static)
- int regularArgsStart = EXTRA_ARGS;
- boolean baseIsStaticCallin = mb.baseMethodIsCallin() && staticBaseMethod;
- if (baseIsStaticCallin) {
- // (i) need these synthetic arguments up-front: "int dummy, Team enclosingTeam"
- storeUnusedArg(il, unused_args, 0, // constant
- new ICONST(0),
- Type.INT,
- cpg);
- storeUnusedArg(il, unused_args, 1, // constant
- new ALOAD(regularArgsStart+1),
- OTConstants.teamType,
- cpg);
-
- // consumed first two parameters into unusedArgs:
- regularArgsStart+=2;
- stackIdx += 2;
- unusedArgsIdx += 2;
- }
- for (int i=regularArgsStart; i<chainArgTypes.length; i++) {
- Type argType = chainArgTypes[i];
- Instruction loadingInstruction = InstructionFactory.createLoad(argType, stackIdx);
- if (isRegularArg(i, mb.baseMethodIsCallin(), staticBaseMethod)) {
- // (k) collect loading instruction, for appending after _OT$unusedArgs.
- packedArgPos = checkPackValue0(regularArgs, useReflection, packedArgPos, cpg);
- {
- regularArgs.append(loadingInstruction);
- }
- checkPackValue0(regularArgs, useReflection, packedArgPos, cpg);
- } else {
- // (j) store unused arg
- storeUnusedArg(il, unused_args, unusedArgsIdx++, loadingInstruction, argType, cpg);
- // generated: _OT$unusedArgs[<unusedArgsIdx>] = maybeBox(a<index>);
- }
- stackIdx += argType.getSize();
- }
- il.append(InstructionFactory.createLoad(objectArray, unused_args));
- }
- checkPackValue1(il, useReflection, objectArray);
-
- // (k) insert previously assembled load-sequence:
- il.append(regularArgs);
-
- // ============= INVOKEVIRTUAL (wrapper) =============
- InstructionHandle callinCall;
- if (useReflection) {
- // this information was missing above:
- il.insert(argArray, createIntegerPush(cpg, packedArgPos));
-
- callinCall = il.append(factory.createInvoke("java.lang.reflect.Method", "invoke", object, new Type[]{object, objectArray}, Constants.INVOKEVIRTUAL));
- wrapperReturnType = Type.OBJECT;
- } else {
- callinCall = il.append(factory.createInvoke(connectorClassName, wrapperName,
- wrapperReturnType,
- wrapperArgTypes,
- Constants.INVOKEVIRTUAL));
- }
- if (debugging) {
- mg.addLineNumber(callinCall, SHOW_ROLE_CALL ? firstLine : STEP_INTO_LINENUMBER); // show role call at method header ("dispatching")
- mg.addLineNumber(il.append(new NOP()), STEP_OVER_LINENUMBER);
- }
-
- adjustValue(il, null, wrapperReturnType, chainReturnType);
- il.append(InstructionFactory.createStore(chainReturnType, ot_result));
-
- return il;
- }
-
- /**
- * Store an unused value (loaded by pushInstruction) into _OT$unusedArgs
- */
- private void storeUnusedArg(InstructionList il,
- int unused_args,
- int arrayIndex,
- Instruction pushInstruction,
- Type argType,
- ConstantPoolGen cpg)
- {
- il.append(InstructionFactory.createLoad(objectArray, unused_args));
- il.append(createIntegerPush(cpg, arrayIndex));
- il.append(pushInstruction);
- if (argType instanceof BasicType)
- il.append(createBoxing((BasicType)argType));
- il.append(InstructionFactory.createArrayStore(objectArray));
- }
-
- /**
- * Is the parameter at position idx mapped (by paramPositions or implicitly)?
- * Cut off head:
- * - (int,Team) if present (static role method)
- * - enhancement (possible twice)
- * @param idx parameter index of enhanced signature
- */
- static boolean isRegularArg (int idx, boolean baseIsCallin, boolean baseIsStatic) {
- if (baseIsCallin && baseIsStatic) // FIXME(SH): should be baseIsRole instead of baseIsCallin!
- idx -= 2;
- int firstVisible = EXTRA_ARGS + (baseIsCallin?EXTRA_ARGS:0); // skip one or two enhancements
- return idx >= firstVisible;
- }
-
- /**
- * Given an argument of type <tt>actual</tt>, must
- * we use type <tt>formal</tt> in signatures,
- * because it is a supertype of <tt>actual</tt>?
- */
- static Type checkWiden (Type actual, Type formal) {
- if (!actual.equals(formal)
- && actual instanceof ObjectType
- && formal instanceof ObjectType)
- {
- ObjectType actualObj = (ObjectType)actual;
- ObjectType formalObj = (ObjectType)formal;
- if (RepositoryAccess.safeSubclassOf(actualObj, formalObj))
- return formalObj;
- }
- return actual;
- }
-
- /**
- * Create an instruction list for initializing the role set field on-demand.
- * @param valueRequired should the role set be on the stack after this sequence?
- * @param cg the ClassGen of the appropriate class
- */
- private InstructionList getInitializedRoleSet(String class_name, boolean valueRequired) {;
- InstructionList il = new InstructionList();
-
- // try to retrieve existing set:
- il.append(new ALOAD(0));
- il.append(factory.createGetField(class_name, OTConstants.ROLE_SET, OTConstants.roleSetType));
- if (valueRequired)
- il.append(new DUP()); // a spare value to keep on the stack if successful
-
- // if (roleSet == null) ..
- IFNONNULL branch = new IFNONNULL(null);
- il.append(branch);
-
- // conditionally create the set:
- if (valueRequired)
- il.append(new POP()); // remove useless "null", replace with DUP_X1 below
- il.append(new ALOAD(0));
- il.append(factory.createNew(OTConstants.roleSetType));
- il.append(new DUP());
- il.append(factory.createInvoke(OTConstants.roleSetType.getClassName(),
- Constants.CONSTRUCTOR_NAME,
- Type.VOID,
- Type.NO_ARGS,
- Constants.INVOKESPECIAL));
- if (valueRequired)
- il.append(new DUP_X1()); // push below pending "this"
-
- // store in the field:
- il.append(factory.createPutField(class_name, OTConstants.ROLE_SET, OTConstants.roleSetType));
-
- // endif
- branch.setTarget(il.append(new NOP()));
- return il;
- }
-
- /**
- * Generates the field '_OT$roleSet' which is used to store the added roles.
- * @param cpg the ClassGen of the appropriate class
- * @param class_name the name of the class
- * @return the generated field
- */
- private Field generateRoleSet(ConstantPoolGen cpg, String class_name) {
- FieldGen fg = new FieldGen(Constants.ACC_PROTECTED|Constants.ACC_TRANSIENT,
- OTConstants.roleSetType,
- OTConstants.ROLE_SET,
- cpg);
- return fg.getField();
- }
-
- /**
- * Generates the method 'public void _OT$addRole(Object role)' which adds the passed object
- * to the role set of this base class.
- * @param cpg the ClassGen of the appropriate class
- * @param class_name the name of the class
- * @return the generated method
- */
- private Method generateAddRole(ConstantPoolGen cpg, String class_name) {
-
- InstructionList il = new InstructionList();
- MethodGen mg = new MethodGen(Constants.ACC_PUBLIC,
- Type.VOID,
- new Type[] { Type.OBJECT },
- new String[] {"role"},
- OTConstants.ADD_ROLE, class_name,
- il, cpg);
-
- il.append(getInitializedRoleSet(class_name, /*valueRequired*/true));
-
- il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
- il.append(factory.createInvoke(OTConstants.roleSetType.getClassName(),
- "add",
- Type.BOOLEAN,
- new Type[] {Type.OBJECT},
- Constants.INVOKEVIRTUAL));
- il.append(new POP());
- il.append(InstructionFactory.createReturn(Type.VOID));
- mg.removeNOPs();
- mg.setMaxStack();
- mg.setMaxLocals(2);
- return mg.getMethod();
- }
-
- /**
- * Generates the method 'public void _OT$removeRole(Object role)' which removes the passed object
- * from the role set of this base class.
- * @param cpg the ClassGen of the appropriate class
- * @param class_name the name of the class
- * @return the generated method
- */
- private Method generateRemoveRole(ConstantPoolGen cpg, String class_name) {
-
- InstructionList il = new InstructionList();
- MethodGen mg = new MethodGen(Constants.ACC_PUBLIC,
- Type.VOID,
- new Type[] { Type.OBJECT },
- new String[] {"role"},
- OTConstants.REMOVE_ROLE, class_name,
- il, cpg);
- il.append(new ALOAD(0));
- il.append(factory.createGetField(class_name, OTConstants.ROLE_SET, OTConstants.roleSetType));
- il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
- il.append(factory.createInvoke(OTConstants.roleSetType.getClassName(),
- "remove",
- Type.BOOLEAN,
- new Type[] {Type.OBJECT},
- Constants.INVOKEVIRTUAL));
- il.append(new POP());
- il.append(InstructionFactory.createReturn(Type.VOID));
- mg.removeNOPs();
- mg.setMaxStack(2);
- mg.setMaxLocals(2);
- return mg.getMethod();
- }
-
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ClassEnhancer.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ClassEnhancer.java
deleted file mode 100644
index ce12bb706..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ClassEnhancer.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2005-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ClassEnhancer.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import org.apache.bcel.classfile.Field;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.generic.ClassGen;
-import org.apache.bcel.generic.ConstantPoolGen;
-
-
-
-/**
- * This interface is used to abstract from the BCEL external transformations.
- *
- * @author Christine Hundt
- * @author Juergen Widiker
- * @author Stephan Herrmann
- */
-public interface ClassEnhancer {
-
- /**
- * Adds the interface 'interfaceName' to the implements clause of class 'cg'.
- */
- public void addImplements(String interfaceName, ClassGen cg);
-
- /**
- * Adds the method 'm' to the class represented by 'cg'.
- * @param m the method to be added
- * @param cg the ClassGen of the appropriate class
- */
- void addMethod(Method m, ClassGen cg);
-
- /**
- * Adds method 'm' to the class 'cg' or, if a method with the
- * same name and signature already exists, replace that method.
- * @param method
- * @param cg
- */
- void addOrReplaceMethod(Method method, ClassGen cg);
-
- /**
- * Adds the field 'f' to the class represented by 'cg'.
- * @param f
- * @param cg
- */
- void addField(Field f, ClassGen cg);
-
- /**
- * Loads the class named 'className'.
- * @param className the name of the class to be loaded
- * @param client the transformer on behalf of which we are called, can be used to call checkReadClassAttributes.
- */
- void loadClass(String className, ObjectTeamsTransformation client);
-
- /**
- * Decapsulation of the method 'm'. This means that the access modifier of this method is set to 'public'.
- * @param m the name of the method to be decapsulated
- * @param className the name of the belonging class
- * @param packageName the name of the belonging package
- * @param cpg the ConstantPoolGen of the class
- */
- void decapsulateMethod(Method m, ClassGen cg, String packageName, ConstantPoolGen cpg);
-
-
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/Decapsulation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/Decapsulation.java
deleted file mode 100644
index 8442cbdfd..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/Decapsulation.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2003, 2009 Technical University Berlin, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: Decapsulation.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.objectteams.otre.util.CallinBindingManager;
-import org.eclipse.objectteams.otre.util.FieldDescriptor;
-import org.eclipse.objectteams.otre.util.SuperMethodDescriptor;
-
-import org.apache.bcel.Constants;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.generic.ClassGen;
-import org.apache.bcel.generic.ConstantPoolGen;
-import org.apache.bcel.generic.InstructionFactory;
-import org.apache.bcel.generic.InstructionList;
-import org.apache.bcel.generic.MethodGen;
-import org.apache.bcel.generic.ObjectType;
-import org.apache.bcel.generic.Type;
-
-/**
- * For each base method that is bound by callout and has
- * insufficient visibility, the visibility is set to public.
- * Check whether the affected base class resides in a sealed package.
- * In that case dissallow decapsulation by throwing an IllegalAccessError.
- *
- * @version $Id: Decapsulation.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Stephan Herrmann
- */
-public class Decapsulation
- extends ObjectTeamsTransformation
- implements Constants
-{
-
-// HashSet modifiedPackages = new HashSet();
-
- public static class SharedState extends ObjectTeamsTransformation.SharedState {
- private HashSet<String/*callout accessed fields*/> generatedFieldCalloutAccessors = new HashSet<String>();
- private HashSet<String/*super-accessed methods (sign)*/> generatedSuperAccessors = new HashSet<String>();
- }
- @Override
- SharedState state() {
- return (SharedState)this.state;
- }
-
- public Decapsulation(ClassLoader loader, SharedState state) {
- super(loader, state);
- // FIXME(SH): can we ever release this transformer and its state?
- synchronized(ObjectTeamsTransformation.reentrentTransformations) {
- ObjectTeamsTransformation.reentrentTransformations.add(this);
- }
- }
-
- /**
- * Main entry for this transformer.
- */
-// @SuppressWarnings("unchecked")
- public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
- String class_name = cg.getClassName();
- ConstantPoolGen cpg = cg.getConstantPool();
-
- // if class is already transformed by this transformer
- if (state.interfaceTransformedClasses.contains(class_name))
- return;
-
- checkReadClassAttributes(ce, cg, class_name, cpg);
-
- // next step starts to transform, so record this class now.
- state.interfaceTransformedClasses.add(class_name);
-
- generateFieldAccessForCallout(ce, cg, class_name, cpg);
-
- generateSuperAccessors(ce, cg, class_name, cpg);
-
- HashSet<String> calloutBindings = CallinBindingManager.getCalloutBindings(class_name);
-
- if (calloutBindings == null) {
- if(logging) printLogMessage("\nClass " + class_name
- + " requires no callout adjustment.");
- return;
- }
-
- if(logging) printLogMessage("\nCallout bindings might be changing class "
- + class_name + ":");
-
- HashSet<String> oldStyleBinding = new HashSet<String>();
-
- // try new style decapsulation first (since 1.2.8):
- for (String calloutBinding : calloutBindings) {
- DecapsulationDescriptor desc = new DecapsulationDescriptor();
- if (!desc.decode(calloutBinding, cg))
- oldStyleBinding.add(calloutBinding); // old style attribute
- else if (!desc.existsAlready)
- ce.addMethod(desc.generate(class_name, cpg), cg);
- }
-
- if (oldStyleBinding.isEmpty()) return;
-
- // --> follows: old style decapsulation for remaining bindings:
- int pos = class_name.lastIndexOf('.');
- String package_name = "NO_PACKAGE";
- if (pos != -1)
- package_name = class_name.substring(0,pos);
-
- Method[] methods = cg.getMethods();
- for (int i = 0; i < methods.length; i++) {
- Method m = methods[i];
- String method_name = m.getName();
-
- boolean requiresAdjustment = CallinBindingManager.
- requiresCalloutAdjustment(oldStyleBinding,
- method_name,
- m.getSignature());
-
- if (requiresAdjustment) {
- ce.decapsulateMethod(m, cg, package_name, cpg);
- }
- }
- }
- class DecapsulationDescriptor {
- short invokeKind;
- String targetClass;
- String methodName;
- String methodSign;
- Type returnType;
- Type[] args;
- String accessorName;
-
- boolean existsAlready;
-
- /**
- * new style encoding is
- * targetClassName ('!' | '?') methodName '.' methodSign
- */
- boolean decode(String encodedBinding, ClassGen cg) {
- int sepPos = encodedBinding.indexOf('!');
- if (sepPos != -1) { // static method:
- invokeKind = INVOKESTATIC;
- } else {
- sepPos = encodedBinding.indexOf('?');
- if (sepPos != -1) {
- invokeKind = INVOKEVIRTUAL;
- } else {
- return false; // old style
- }
- }
- targetClass = encodedBinding.substring(0, sepPos);
- int sigPos = encodedBinding.indexOf('(', sepPos);
- methodName = encodedBinding.substring(sepPos+1, sigPos);
- methodSign = encodedBinding.substring(sigPos);
-
- returnType = Type.getReturnType(methodSign);
- args = Type.getArgumentTypes(methodSign);
-
- accessorName = "_OT$decaps$"+methodName;
- existsAlready = cg.containsMethod(accessorName, methodSign) != null;
- if (invokeKind == INVOKEVIRTUAL) {
- Method existing = cg.containsMethod(methodName, methodSign);
- if (existing != null && existing.isPrivate())
- invokeKind = INVOKESPECIAL; // accessing private
- }
-
- return true;
- }
- Method generate(String currentClass, ConstantPoolGen cpg) {
- InstructionList il = new InstructionList();
- int instanceOffset = 0;
- short flags = Constants.ACC_PUBLIC;
- if (invokeKind != INVOKESTATIC) {
- instanceOffset=1;
- il.append(InstructionFactory.createThis());
- } else {
- flags |= Constants.ACC_STATIC;
- }
- int pos= 0;
- for (int i = 0; i < args.length; i++) {
- il.append(InstructionFactory.createLoad(args[i], pos+instanceOffset));
- pos += args[i].getSize();
- }
- il.append(new InstructionFactory(cpg).createInvoke(targetClass, methodName, returnType, args, invokeKind));
- il.append(InstructionFactory.createReturn(returnType));
- MethodGen newMethod = new MethodGen(flags, returnType, args, /*argNames*/null, accessorName, currentClass, il, cpg);
- newMethod.setMaxLocals();
- newMethod.setMaxStack();
- return newMethod.getMethod();
- }
- }
-
- /**
- * Generates getter and setter methods for all fields of the class 'class_name' which are accessed via callout.
- * Informations are received via attributs (CallinBindingManager).
- * @param cg the ClassGen of the appropriate class
- * @param class_name the name of the class
- * @param cpg the ConstantPoolGen of the class
- * @param es the ExtensionSet to add the new access methods
- */
- private void generateFieldAccessForCallout(ClassEnhancer ce, ClassGen cg, String class_name, ConstantPoolGen cpg) {
- InstructionFactory factory = null;
-
- HashSet<String> addedAccessMethods = state().generatedFieldCalloutAccessors;
-
- List<FieldDescriptor> getter = CallinBindingManager.getCalloutGetFields(class_name);
- if (getter != null) {
- factory = new InstructionFactory(cg);
- Iterator<FieldDescriptor> it = getter.iterator();
- while (it.hasNext()) {
- FieldDescriptor fd = it.next();
- String key = "get_" + class_name +"." + fd.getFieldName() + fd.getFieldSignature();
- if (logging)
- printLogMessage("Generating getter method "+key);
- if (addedAccessMethods == null)
- addedAccessMethods = new HashSet<String>();
- if (addedAccessMethods.contains(key))
- continue; // this getter has already been created
- ce.addMethod(generateGetter(cpg, class_name, fd, factory), cg);
- addedAccessMethods.add(key);
- }
- }
-
- List<FieldDescriptor> setter = CallinBindingManager.getCalloutSetFields(class_name);
- if (setter != null) {
- if (factory == null)
- factory = new InstructionFactory(cg);
- Iterator<FieldDescriptor> it = setter.iterator();
- while (it.hasNext()) {
- FieldDescriptor fd = it.next();
- String key = "set_"+ class_name +"." + fd.getFieldName()+fd.getFieldSignature();
- if (logging)
- printLogMessage("Generating setter method "+key);
- if (addedAccessMethods == null)
- addedAccessMethods = new HashSet<String>();
- if (addedAccessMethods.contains(key))
- continue; // this setter has already been created
- ce.addMethod(generateSetter(cpg, class_name, fd, factory), cg);
- addedAccessMethods.add(key);
- }
- }
- }
-
-
- /**
- * Generates a getter method for the field described by 'fd' in the class 'class_name'.
- * @param cpg the ConstantPoolGen of the class
- * @param class_name the name of the class
- * @param fd the FieldDescriptor describing the affected field
- * @param factory an InstructionFactory for this class
- * @return the generated getter method
- */
- private Method generateGetter(ConstantPoolGen cpg, String class_name, FieldDescriptor fd, InstructionFactory factory) {
- String fieldName = fd.getFieldName();
- Type fieldType = Type.getType(fd.getFieldSignature());
- Type baseType = new ObjectType(class_name);
-
- InstructionList il = new InstructionList();
- String[] argumentNames;
- Type[] argumentTypes;
- if (fd.isStaticField()) {
- argumentNames = new String[0];
- argumentTypes = new Type[0];
- } else {
- argumentNames = new String[] {"base_obj"};
- argumentTypes = new Type[] {baseType};
- }
- MethodGen mg = new MethodGen((Constants.ACC_PUBLIC|Constants.ACC_STATIC),
- fieldType,
- argumentTypes,
- argumentNames,
- OT_PREFIX+"get$"+fieldName,
- class_name,
- il, cpg);
- if (!fd.isStaticField())
- il.append(InstructionFactory.createLoad(baseType, 0)); // first argument is at slot 0 in static methods
- short fieldKind = fd.isStaticField()?Constants.GETSTATIC:Constants.GETFIELD;
- il.append(factory.createFieldAccess(class_name, fieldName, fieldType, fieldKind));
- il.append(InstructionFactory.createReturn(fieldType));
-
- mg.removeNOPs();
- mg.setMaxStack();
- mg.setMaxLocals();
- return mg.getMethod();
- }
-
-
- /**
- * Generates a setter method for the field described by 'fd' in the class 'class_name'.
- * @param cpg the ConstantPoolGen of the class
- * @param class_name the name of the class
- * @param fd the FieldDescriptor describing the affected field
- * @param factory an InstructionFactory for this class
- * @return the generated getter method
- */
- private Method generateSetter(ConstantPoolGen cpg, String class_name, FieldDescriptor fd, InstructionFactory factory ) {
- String fieldName = fd.getFieldName();
- Type fieldType = Type.getType(fd.getFieldSignature());
- Type baseType = new ObjectType(class_name);
-
- Type[] argumentTypes;
- String[] argumentNames;
- if (fd.isStaticField()) {
- argumentTypes = new Type[] { fieldType};
- argumentNames = new String[] {"new_value"};
- } else {
- argumentTypes = new Type[] {baseType, fieldType};
- argumentNames = new String[] {"base_obj", "new_value"};
- }
-
- InstructionList il = new InstructionList();
- MethodGen mg = new MethodGen((Constants.ACC_PUBLIC|Constants.ACC_STATIC),
- Type.VOID,
- argumentTypes,
- argumentNames,
- OT_PREFIX+"set$"+fieldName,
- class_name,
- il, cpg);
-
- int argumentPosition; // position for the argument holding the new field value.
- if (!fd.isStaticField()) {
- il.append(InstructionFactory.createLoad(baseType, 0)); // first argument is at slot 0 in static methods
- argumentPosition = 1;
- } else {
- argumentPosition = 0;
- }
- il.append(InstructionFactory.createLoad(fieldType, argumentPosition));
- short fieldKind = fd.isStaticField()?Constants.PUTSTATIC:Constants.PUTFIELD;
- il.append(factory.createFieldAccess(class_name, fieldName, fieldType, fieldKind));
- il.append(InstructionFactory.createReturn(Type.VOID));
-
- mg.removeNOPs();
- mg.setMaxStack();
- mg.setMaxLocals();
- return mg.getMethod();
- }
-
- private void generateSuperAccessors(ClassEnhancer ce, ClassGen cg, String class_name, ConstantPoolGen cpg) {
- InstructionFactory factory = null;
-
- HashSet<String> addedAccessMethods = state().generatedSuperAccessors;
-
- List<SuperMethodDescriptor> methods = CallinBindingManager.getSuperAccesses(class_name);
- if (methods != null) {
- factory = new InstructionFactory(cg);
- for (SuperMethodDescriptor superMethod : methods) {
- String key = superMethod.methodName+'.'+superMethod.signature;
- if (logging)
- printLogMessage("Generating super access method "+key);
- if (addedAccessMethods == null)
- addedAccessMethods = new HashSet<String>();
- if (addedAccessMethods.contains(key))
- continue; // this accessor has already been created
- ce.addMethod(generateSuperAccessor(cpg, class_name, superMethod, factory), cg);
- addedAccessMethods.add(key);
- }
- }
- }
-
- private Method generateSuperAccessor(ConstantPoolGen cpg, String className, SuperMethodDescriptor superMethod, InstructionFactory factory)
- {
- int endPos = superMethod.signature.indexOf(')');
- String segment = superMethod.signature.substring(1, endPos);
- String[] typeNames = (segment.length() > 0) ? segment.split(",") : new String[0];
- Type[] argTypes = new Type[typeNames.length];
- for (int i = 0; i < argTypes.length; i++)
- argTypes[i] = Type.getType(typeNames[i]);
-
- int index = superMethod.signature.lastIndexOf(')') + 1;
- Type returnType = Type.getType(superMethod.signature.substring(index));
-
- Type baseType = new ObjectType(className);
- Type[] wrapperTypes = new Type[argTypes.length+1];
- System.arraycopy(argTypes, 0, wrapperTypes, 1, argTypes.length);
- wrapperTypes[0] = baseType;
- String[] argNames = new String[wrapperTypes.length];
- for (int i = 0; i < argNames.length; i++) {
- argNames[i] = "arg"+i;
- }
- InstructionList il = new InstructionList();
- MethodGen mg = new MethodGen((Constants.ACC_PUBLIC|Constants.ACC_STATIC),
- returnType,
- wrapperTypes,
- argNames,
- OT_PREFIX+superMethod.methodName+"$super",
- className,
- il, cpg);
- il.append(InstructionFactory.createLoad(baseType, 0)); // first argument is base instance
- for (int i = 0; i < argTypes.length; i++)
- il.append(InstructionFactory.createLoad(argTypes[i], i+1));
-
- // if super method is also callin bound directly invoke the orig-version
- // (to avoid that BaseMethodTransformation.checkReplaceWickedSuper() has to rewrite this code again):
- String methodName = (CallinBindingManager.isBoundBaseMethod(superMethod.superClass, superMethod.methodName, superMethod.signature))
- ? genOrigMethName(superMethod.methodName)
- : superMethod.methodName;
-
- il.append(factory.createInvoke(superMethod.superClass, methodName, returnType, argTypes, INVOKESPECIAL));
- il.append(InstructionFactory.createReturn(returnType));
- mg.setMaxStack();
- mg.setMaxLocals();
- return mg.getMethod();
- }
-
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java
deleted file mode 100644
index e43204c57..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2009 Stephan Herrmann
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: LiftingParticipantTransformation.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Stephan Herrmann - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-
-import java.lang.reflect.Field;
-
-import org.objectteams.Team;
-
-import org.apache.bcel.Constants;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.generic.ALOAD;
-import org.apache.bcel.generic.BranchInstruction;
-import org.apache.bcel.generic.ClassGen;
-import org.apache.bcel.generic.ConstantPoolGen;
-import org.apache.bcel.generic.DUP;
-import org.apache.bcel.generic.GOTO;
-import org.apache.bcel.generic.IFNULL;
-import org.apache.bcel.generic.INVOKESPECIAL;
-import org.apache.bcel.generic.InstructionFactory;
-import org.apache.bcel.generic.InstructionHandle;
-import org.apache.bcel.generic.InstructionList;
-import org.apache.bcel.generic.LDC;
-import org.apache.bcel.generic.MethodGen;
-import org.apache.bcel.generic.NEW;
-import org.apache.bcel.generic.NOP;
-import org.apache.bcel.generic.ObjectType;
-import org.apache.bcel.generic.POP;
-import org.apache.bcel.generic.Type;
-
-/**
- * If the property ot.lifting.participant is set transform all lift methods and insert
- * static calls to createRole(Team,Object,String)Object; to the registered lifting participant
- * before creating a new role. If createRole returns non-null then that value is taken
- * as the new role, otherwise lifting proceeds as normal, i.e., normally creates a new role.
- *
- * @author stephan
- * @since 1.3.1
- */
-public class LiftingParticipantTransformation extends ObjectTeamsTransformation {
-
-
- private static String PARTICIPANT_NAME = System.getProperty("ot.lifting.participant");
- private static boolean checked = false;
-
- final private static String LIFT_PREFIX = "_OT$liftTo";
-
- private static final String WRONG_ROLE_EXCEPTION = "org.objectteams.WrongRoleException";
- private static final String LIFTING_FAILED_EXCEPTION = "org.objectteams.LiftingFailedException";
- private static final String LIFTING_VETO_EXCEPTION = "org.objectteams.LiftingVetoException";
-
- private static final ObjectType iLiftingParticipant = new ObjectType("org.objectteams.ILiftingParticipant");
-
- private static final String CREATE_ROLE_METHOD = "createRole";
- private static final String LIFTING_PARTICIPANT_FIELD = "_OT$liftingParticipant";
-
- public LiftingParticipantTransformation(ClassLoader loader, SharedState state) { super(loader, state); }
-
- public void doTransformCode(ClassGen cg)
- {
- if (!classNeedsTeamExtensions(cg)) return;
-
- synchronized (LiftingParticipantTransformation.class) {
- try {
- checkInitParticipant();
- } catch (Exception e) {
- new IllegalArgumentException("Lifting participant "+PARTICIPANT_NAME+" is invalid.", e).printStackTrace();
- PARTICIPANT_NAME = null;
- }
- if (PARTICIPANT_NAME == null)
- return;
- }
-
- factory = new InstructionFactory(cg);
- ConstantPoolGen cpg = cg.getConstantPool();
- String class_name = cg.getClassName();
-
- // FIXME(SH): evaluate inclusion/exclusion filter per className
-
- Method[] methods = cg.getMethods();
- for (int i=0; i<methods.length; i++) {
- Method m = methods[i];
- if (!m.getName().startsWith(LIFT_PREFIX))
- continue;
-
- cg.replaceMethod(m, m = weaveLiftingParticipant(m, class_name, cpg));
- }
- }
-
- private void checkInitParticipant() throws Exception {
- if (checked) return;
- checked = true;
-
- Field participantField = Team.class.getField(LIFTING_PARTICIPANT_FIELD);
- Object participant = participantField.get(null);
-
- if (PARTICIPANT_NAME != null)
- {
- // initialize from property "ot.lifting.participant"
- if (participant != null)
- throw new IllegalStateException("liftingParticipant already installed.");
- // install a shared instance into class Team:
- Class<?> participantClass = loader.loadClass(PARTICIPANT_NAME);
- participantField.set(null, participantClass.newInstance());
- }
- else if (participant != null)
- {
- // field was already initialized by a third party
-
- // fetch the class name to signal that transformations are needed.
- PARTICIPANT_NAME = participant.getClass().getName();
- }
- }
-
- private Method weaveLiftingParticipant(Method m, String className, ConstantPoolGen cpg) {
- MethodGen mg = newMethodGen(m, className, cpg);
- InstructionList il = mg.getInstructionList();
- InstructionHandle[] ihs = il.getInstructionHandles();
- for (int i=0; i<ihs.length; i++) {
- InstructionHandle ih = ihs[i];
- if (ih.getInstruction() instanceof NEW)
- {
- NEW newInstr = (NEW) ih.getInstruction();
- Type newType = newInstr.getType(cpg);
- String newTypeName = newType.toString();
-
- // don't transform creation of these exceptions:
- if (newTypeName.equals(LIFTING_FAILED_EXCEPTION)) continue;
- if (newTypeName.equals(LIFTING_VETO_EXCEPTION)) continue;
- if (newTypeName.equals(WRONG_ROLE_EXCEPTION)) continue;
-
- ih.setInstruction(new NOP()); // keep this handle for the enclosing switch
-
- InstructionList inset = new InstructionList();
- // fetch instance of lifting participant from Team._OT$liftingParticipant
- inset.append(factory.createFieldAccess(teamClassType.getClassName(),
- LIFTING_PARTICIPANT_FIELD,
- iLiftingParticipant,
- Constants.GETSTATIC));
- inset.append(new ALOAD(0)); // load the team
- inset.append(new ALOAD(1)); // load the base
- inset.append(new LDC(cpg.addString(newTypeName))); // load the role class name
- inset.append(factory.createInvoke(iLiftingParticipant.getClassName(), // receiver type
- CREATE_ROLE_METHOD, // method
- object, // return type
- new Type[] {teamType, object, string},// arg types
- Constants.INVOKEINTERFACE));
- inset.append(new DUP()); // keep value after null-check
- BranchInstruction isNull = new IFNULL(null);
- inset.append(isNull);
- inset.append(factory.createCast(object, newType));
- // let goto skip: 0: new R, 1: dup, 2: aload_0, 3: aload_1, (4: cast if needed), 4: o. 5: invokespecial<init>
- int invokeOffset = 4;
- if (!(ihs[i+invokeOffset].getInstruction() instanceof INVOKESPECIAL))
- invokeOffset++;
- inset.append(new GOTO(ihs[i+invokeOffset+1])); // one past above sequence
-
- // continue here if null, i.e., perform the original new-instruction
- InstructionHandle goOn = inset.append(new POP()); // discard dup'ed value from above
- isNull.setTarget(goOn);
- inset.append(newInstr); // re-insert deleted first instruction
-
- il.append(ih, inset);
- }
- }
- return mg.getMethod();
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTConstants.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTConstants.java
deleted file mode 100644
index fb2acfa9e..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTConstants.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: OTConstants.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import org.apache.bcel.generic.*;
-
-
-/**
- * Constants for the Object Teams Runtime Environment
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-public interface OTConstants {
- // ------------------------------------------
- // ---------- Types: ------------------------
- // ------------------------------------------
- /** Type <tt>java.lang.Object</tt> */
- ObjectType object = new ObjectType("java.lang.Object");
- /** Type <tt>java.lang.Object</tt> */
- ObjectType string = new ObjectType("java.lang.String");
- /** Type <tt>java.lang.Class</tt> */
- ObjectType classType = new ObjectType("java.lang.Class");
- /** Signature of java.lang.Class#getMethod(String, Class...) */
- public static final Type[] getMethodSignature = new Type[]{string, new ArrayType(classType, 1)};
- /** Type <tt>java.lang.reflect.Method</tt> */
- ObjectType methodType = new ObjectType("java.lang.reflect.Method");
- /** Type <tt>org.objectteams.Team</tt> */
- String teamName = "org.objectteams.ITeam";
- ObjectType teamType = new ObjectType(teamName);
- String teamClassName = "org.objectteams.Team";
- ObjectType teamClassType = new ObjectType(teamClassName);
- /** Type <tt>org.objectteams.LiftingVetoException</tt> */
- ObjectType liftingVeto = new ObjectType("org.objectteams.LiftingVetoException");
- /** Type <tt>org.eclipse.objectteams.otre.OTREInternalError</tt> */
- ObjectType internalError = new ObjectType("org.eclipse.objectteams.otre.OTREInternalError");
- /** Type <tt>org.objectteams.ResultNotProvidedError</tt> */
- ObjectType notProvidedError = new ObjectType("org.objectteams.ResultNotProvidedError");
- /** Type <tt>org.objectteams.UnsupportedFeatureException</tt> */
- ObjectType unsupportedFeature = new ObjectType("org.objectteams.UnsupportedFeatureException");
-
- ObjectType threadType = new ObjectType("java.lang.Thread");
-
- /** Type <tt>org.objectteams.Team[]</tt> */
- ArrayType teamArray = new ArrayType(teamType, 1);
- /** Type <tt>int[]</tt> */
- ArrayType intArray = new ArrayType(Type.INT, 1);
- /** Type <tt>java.lang.Object[]</tt> */
- ArrayType objectArray = new ArrayType(object, 1);
-
- ObjectType roleSetType = new ObjectType("java.util.HashSet");
-
- ObjectType nullPointerException = new ObjectType("java.lang.NullPointerException");
-
- String STRING_BUFFER_NAME = "java.lang.StringBuffer";
-
- // ============ VERSION: ==============
- public static final int OT_VERSION_MAJOR = 0;
- public static final int OT_VERSION_MINOR = 8;
- public static final int OT_REVISION = 18;
-
- // required compiler revision in the 0.9 stream:
- public static final int OT09_REVISION = 26;
-
- // required compiler revision in the 1.0 stream:
- public static final int OT10_REVISION = 0;
-
- // required compiler revision in the 1.1 stream:
- public static final int OT11_REVISION = 0;
-
- // required compiler revision in the 1.2 stream:
- public static final int OT12_REVISION = 0;
-
- // required compiler revision in the 1.3 stream:
- public static final int OT13_REVISION = 0;
-
- // required compiler revision in the 1.4 stream:
- public static final int OT14_REVISION = 1;
-
- // required compiler revision in the 1.5 stream:
- public static final int OT15_REVISION = 0;
-
- // ------------------------------------------
- // ---------- Flags and Modifiers: ----------
- // ------------------------------------------
- /** Bytecode encoding of modifier <tt>team</tt> */
- final static int TEAM = 0x8000;
-
- // 'CallinFlags':
- final static int OVERRIDING =1; // this role method is inherited from the super role
- final static int WRAPPER =2; // this is a role method wrapper (in a team)
-
- // ------------------------------------------
- // ---------- Names: ------------------------
- // ------------------------------------------
- /** General prefix to mark all generated names. */
- final static String OT_PREFIX = "_OT$";
- /** Name of the base reference of roles. */
- final static String BASE = "_OT$base";
- /** Name of the getBase method of roles (ifc and class). */
- final static String GET_BASE = "_OT$getBase";
- /** Prefix for otdt. */
- final static String OTDT_PREFIX = "__OT__";
- /** Tsuper marker interface prefix. */
- final static String TSUPER_PREFIX = "TSuper__OT__";
- /** field for storing the class object in JVM < 5 */
- final static String SELF_CLASS = "_OT$self_class$";
-
- // -----------------------------------------
- // ---------- Signature enhancement --------
- // -----------------------------------------
-
- /** Name of synthetic parameter. */
- final static String TEAMS = "_OT$teams";
- /** Name of synthetic parameter. */
- final static String TEAMIDS = "_OT$teamIDs";
- /** Name of synthetic parameter. */
- final static String IDX = "_OT$idx";
- /** Name of synthetic parameter. */
- final static String BIND_IDX = "_OT$bindIdx";
- /** Name of synthetic parameter. */
- final static String UNUSED = "_OT$unusedArgs";
- /** Name of synthetic parameter. */
- final static String BASE_METH_TAG = "_OT$baseMethTag";
-
- /** Number of extra arguments in enhanced signatures. */
- static final int EXTRA_ARGS = 6;
- /** Position of generated argument. */
- static final int TEAMS_ARG = 1;
- /** Position of generated argument. */
- static final int TEAMIDS_ARG = 2;
- /** Position of generated argument. */
- static final int IDX_ARG = 3;
- /** Position of generated argument. */
- static final int BIND_IDX_ARG = 4;
- /** Position of generated argument. */
- static final int BASE_METH_ARG = 5; // ## really const? also UNUSED?
- /** Position of generated argument. */
- static final int UNUSED_ARG = 6;
-
- // ---------- Features to prevent/aid garbage collection: ----------
- String ROLE_SET = OT_PREFIX + "roleSet"; // field HashSet _OT$roleSet;
- String ADD_ROLE = OT_PREFIX + "addRole"; // method void _OT$addRole(Object)
- String REMOVE_ROLE = OT_PREFIX + "removeRole"; // method void _OT$removeRole(Object)
-
- String IBOUND_BASE = "org.objectteams.IBoundBase"; // interface comprising the above methods.
-
-
- // -----------------------------------------
- // ---------- Other constants --------
- // -----------------------------------------
- /** Marker for comment lines in the team config file. */
- static final String COMMENT_MARKER = "#";
- /** Constant for invalid base method tags (a method can not be relocated from a base call). */
- static final int INVALID_BASE_METHOD_TAG = -2;
-
- // --------------------------------------------------------------
- // ---------- Separator for static replace binding keys ---------
- // --------------------------------------------------------------
- static final String STATIC_REPLACE_BINDING_SEPARATOR = "..";
-
- // ------------------------------------------------------------------------------------
- // ---------- Linenumbers with more information. ----------------------
- // ---------- (semantic linenumber) For debugging purpose. ------
- // ------------------------------------------------------------------------------------
- static final int STEP_OVER_LINENUMBER = Short.MAX_VALUE *2;
- static final int STEP_INTO_LINENUMBER = STEP_OVER_LINENUMBER - 1;
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTREInternalError.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTREInternalError.java
deleted file mode 100644
index 04110e261..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTREInternalError.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2003-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id$
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-/**
- * @author stephan
- */
-public class OTREInternalError extends Error {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private static final String _bugmsg =
- "An error occurred in the Object Teams runtime environment.\n"+
- "We would appreciate if you send a bug report to bugs@ObjectTeams.org.\n"+
- "Please include your program (if possible) and the following diagnostic\n"+
- "in your report. -- Thank you. The OT/J developers\n";
- /**
- *
- */
- public OTREInternalError() {
- super(_bugmsg);
- }
-
- /**
- * @param message
- */
- public OTREInternalError(String message) {
- super(_bugmsg+message);
- }
-
- /**
- * @param cause
- */
- public OTREInternalError(Throwable cause) {
- super(_bugmsg+cause.toString());
- }
-
- /**
- * @param message
- * @param cause
- */
- public OTREInternalError(String message, Throwable cause) {
- super(_bugmsg+message+cause.toString());
- }
-
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java
deleted file mode 100644
index b569a96fb..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java
+++ /dev/null
@@ -1,2266 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ObjectTeamsTransformation.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.eclipse.objectteams.otre.util.AnnotationHelper;
-import org.eclipse.objectteams.otre.util.AttributeReadingGuard;
-import org.eclipse.objectteams.otre.util.CallinBindingManager;
-import org.eclipse.objectteams.otre.util.RoleBaseBinding;
-
-import org.apache.bcel.Constants;
-import org.apache.bcel.classfile.Attribute;
-import org.apache.bcel.classfile.Constant;
-import org.apache.bcel.classfile.ConstantUtf8;
-import org.apache.bcel.classfile.InnerClass;
-import org.apache.bcel.classfile.InnerClasses;
-import org.apache.bcel.classfile.JavaClass;
-import org.apache.bcel.classfile.LineNumberTable;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.classfile.StackMap;
-import org.apache.bcel.classfile.Unknown;
-import org.apache.bcel.generic.*;
-
-/**
- * Superclass for all transformations in this package.
- * This class and its subclasses does not directly depend on JPLIS.
- *
- * Contains common fields and methods.
- *
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-public abstract class ObjectTeamsTransformation
- implements OTConstants
-{
-
- // ------------------------------------------
- // ---------- Flags: ------------------------
- // ------------------------------------------
-
- /** Check whether <tt>flags</tt> denote a generated callin wrapper. */
- static boolean isCallinWrapper(Method m, ClassGen cg) {
- return methodHasCallinFlags(m, cg, WRAPPER);
- }
-
- /** Check whether <tt>flags</tt> denote a callin method from the source code. */
- static boolean isCallin(Method m, ClassGen cg) {
- return (methodHasCallinFlags(m, cg, 0) && !isCallinWrapper(m, cg));
- }
-
-
- // ------------------------------------------
- // ---------- Names: ------------------------
- // ------------------------------------------
-
- /** Generate the name for a backup of a method. */
- static String genOrigMethName(String methName) {
- return "_OT$" + methName + "$orig";
- }
-
- /** Generate the name for a chaining wrapper. */
- static String genChainMethName(String methName) {
- return "_OT$" + methName + "$chain";
- }
-
- static ArrayList<ObjectTeamsTransformation> reentrentTransformations = new ArrayList<ObjectTeamsTransformation>();
-
- /** Common factory for all tranformers.
- * To be initialized once we get a class for transformation. */
- InstructionFactory factory;
-
- /** State shared among all instances that work for the same class loader. */
- public static class SharedState {
- /** ArrayList of classes whose interfaces have already been transformed by this transformer/classloader combo. */
- ArrayList<String> interfaceTransformedClasses = new ArrayList<String>();
- }
- /** Reference to the shared state of transformers. */
- final SharedState state;
-
- SharedState state() {
- return state;
- }
-
- /** Which class loader are we working for? */
- protected ClassLoader loader;
-
- public ObjectTeamsTransformation(ClassLoader loader, SharedState state) {
- this.loader = loader;
- this.state = state;
- }
-
- // ------------------------------------------
- // ---------- Logging: ----------------------
- // ------------------------------------------
- /** Initialized from property <tt>ot.log</tt>. */
- static boolean logging = false;
-
- static {
- if(System.getProperty("ot.log") != null)
- logging = true;
- }
-
- /** Print <tt>message</tt> only if <tt>logging</tt> is true. */
- public static void printLogMessage(String message) {
- System.out.println(message);
- }
-
- // ------------------------------------------
- // ---------- use the following file as config file for additional active teams: --------
- // ------------------------------------------
- /** Initialized from property <tt>ot.teamconfig</tt>. */
-
- static String TEAM_CONFIG_FILE = null;
-
- static {
- TEAM_CONFIG_FILE = System.getProperty("ot.teamconfig");
- }
-
- // ------------------------------------------
- // ---------- Compatibility with different compiler versions: --------
- // ------------------------------------------
-
- // compiler 1.2.4 introduces isSuperAccess flag for basecall surrogate:
- protected static boolean IS_COMPILER_GREATER_123 = false;
-
- protected static boolean IS_COMPILER_13X_PLUS = false;
-
- protected static boolean IS_COMPILER_14X_PLUS = false;
-
- // ------------------------------------------
- // ---------- This flag must currently be true for OT/Equinox: ----------------------
- // ------------------------------------------
- /** Initialized from property <tt>ot.equinox</tt>. */
- public static boolean WORKAROUND_REPOSITORY = false;
-
- static {
- if(System.getProperty("ot.equinox") != null)
- WORKAROUND_REPOSITORY = true;
- }
-
- // ------------------------------------------
- // ---------- Debugging: ----------------------
- // ------------------------------------------
- /** Initialized from property <tt>ot.debug</tt>. */
- static boolean debugging = false;
-
- static {
- if(System.getProperty("ot.debug") != null)
- debugging = true;
- }
-
- // -------------------------------------------------------
- // ---------- Modes for implicit team activateion --------
- // -------------------------------------------------------
- enum ImplicitActivationMode { NEVER, ANNOTATED, ALWAYS }
- static ImplicitActivationMode implicitActivationMode = ImplicitActivationMode.ANNOTATED;
- static {
- String prop = System.getProperty("ot.implicit.team.activation");
- for (ImplicitActivationMode mode : ImplicitActivationMode.values()) {
- if (mode.name().equals(prop)) {
- implicitActivationMode = mode;
- break;
- }
- }
- }
-
- // -----------------------------------------
- // ---------- Signature enhancement --------
- // -----------------------------------------
-
- /**
- * Prepend hidden arguments to the signature.
- * This methods only treats argument names.
- * @see #enhanceArgumentTypes
- * The arguments are:
- * <dl>
- * <dt><tt>Team[] _OT$teams</tt></dt>
- * <dd>array of active Teams affecting the current base method.
- * <dt><tt>int[] _OT$teamIDs</tt></dt>
- * <dd>array of IDs of the above Teams.
- * <dt><tt>int _OT$idx</tt></dt>
- * <dd>index into above arrays: the Team currently being processed.
- * <dt><tt>Object[] _OT$unusedArgs</tt></dt>
- * <dd>array of arguments which are unused by the current role method.
- * </dl>
- * @param argumentNames array of original argument names.
- * @return augmented array of argument names.
- */
- static String[] enhanceArgumentNames(String[] argumentNames) {
- return enhanceArgumentNames(argumentNames, 0);
- }
-
- /**
- * Prepend hidden arguments to the signature.
- * This methods only treats argument names.
- * @see #enhanceArgumentTypes
- * The arguments are:
- * <dl>
- * <dt><tt>Team[] _OT$teams</tt></dt>
- * <dd>array of active Teams affecting the current base method.
- * <dt><tt>int[] _OT$teamIDs</tt></dt>
- * <dd>array of IDs of the above Teams.
- * <dt><tt>int _OT$idx</tt></dt>
- * <dd>index into above arrays: the Team currently being processed.
- * <dt><tt>Object[] _OT$unusedArgs</tt></dt>
- * <dd>array of arguments which are unused by the current role method.
- * </dl>
- * @param argumentNames array of original argument names.
- * @param idx position where new arguments should be inserted into
- * <tt>originalArgumentTypes</tt>.
- * @return augmented array of argument names.
- */
- static String[] enhanceArgumentNames(String[] argumentNames, int idx) {
-
- String[] enhancedArgumentNames =
- new String[argumentNames.length + EXTRA_ARGS];
-
- for (int j=0; j<idx; j++)
- enhancedArgumentNames[j] = argumentNames[j];
-
- enhancedArgumentNames [idx + TEAMS_ARG - 1] = TEAMS;
- enhancedArgumentNames [idx + TEAMIDS_ARG - 1] = TEAMIDS;
- enhancedArgumentNames [idx + IDX_ARG - 1] = IDX;
- enhancedArgumentNames [idx + BIND_IDX_ARG - 1] = BIND_IDX;
- enhancedArgumentNames [idx + BASE_METH_ARG - 1] = BASE_METH_TAG;
- enhancedArgumentNames [idx + UNUSED_ARG - 1] = UNUSED;
-
- for (int j = idx; j < argumentNames.length; j++)
- enhancedArgumentNames[j + EXTRA_ARGS] = argumentNames[j];
-
- return enhancedArgumentNames;
- }
-
- /**
- * @see #enhanceArgumentTypes(Type[])
- * @param signature String from which to extract the argument types.
- * @return
- */
- static Type[] enhanceArgumentTypes(String signature) {
- Type[] types = Type.getArgumentTypes(signature);
- return enhanceArgumentTypes(types);
- }
-
- /**
- * Prepend hidden arguments to the signature.
- * This methods only treats argument types.
- * @see #enhanceArgumentNames
- *
- * @param originalArgumentTypes array of original argument types.
- * @return augmented array of argument names.
- */
- static Type[] enhanceArgumentTypes(Type[] originalArgumentTypes) {
- return enhanceArgumentTypes(originalArgumentTypes, 0, true);
- }
-
- /**
- * Prepend hidden arguments to the signature.
- * This methods only treats argument types.
- * @see #enhanceArgumentNames
- *
- * @param originalArgumentTypes array of original argument types.
- * @param idx position where new arguments should be inserted into
- * <tt>originalArgumentTypes</tt>.
- * @param createUnused should the <tt>unusedArgs</tt> argument be created?
- * @return augmented array of argument types.
- */
- static Type[] enhanceArgumentTypes(Type[] originalArgumentTypes,
- int idx,
- boolean createUnused)
- {
- // creates enhanced argument type array:
- // ..(a1,.., aN) -> ..(Team[], int[], int, Object[], a1, .., aN)
- int offset = createUnused ? EXTRA_ARGS : EXTRA_ARGS-1;
-
- Type[] enhancedArgumentTypes =
- new Type[originalArgumentTypes.length+offset];
-
- for (int j=0; j<idx; j++)
- enhancedArgumentTypes[j] = originalArgumentTypes[j];
-
- enhancedArgumentTypes [idx+TEAMS_ARG - 1] = teamArray;
- enhancedArgumentTypes [idx+TEAMIDS_ARG - 1] = intArray;
- enhancedArgumentTypes [idx+IDX_ARG - 1] = Type.INT;
- enhancedArgumentTypes [idx+BIND_IDX_ARG - 1] = Type.INT;
- enhancedArgumentTypes [idx+BASE_METH_ARG - 1] = Type.INT;
- if (createUnused) {
- enhancedArgumentTypes [idx+UNUSED_ARG - 1] = objectArray;
- }
-
- for (int j = idx; j < originalArgumentTypes.length; j++)
- enhancedArgumentTypes[j + EXTRA_ARGS] = originalArgumentTypes[j];
-
- return enhancedArgumentTypes;
- }
-
- /**
- * Remove the arguments previously added by
- * {@link #enhanceArgumentTypes enhanceArgumentTypes}.
- *
- * @param enhancedArgumentTypes
- * @param staticFlag
- * @return
- */
- // FIXME(SH): obsolete
- public static Type[] _retrenchArgumentTypes(Type[] enhancedArgumentTypes, boolean staticFlag) {
- // create retrenched argument type array:
- // ..(Team[], int[], int, Object[], a1, .., aN) -> ..(a1,.., aN)
-
- int offset = staticFlag? -1 : 0;
-
- Type[] retrenchedArgumentTypes =
- new Type[enhancedArgumentTypes.length - EXTRA_ARGS + offset];
-
- for (int j = EXTRA_ARGS; j < enhancedArgumentTypes.length + offset; j++)
- retrenchedArgumentTypes[j - EXTRA_ARGS] = enhancedArgumentTypes[j];
-
- return retrenchedArgumentTypes;
- }
-
- // ---------------------------------------------------
- // ---------- further type and value conversions -----
- // ---------------------------------------------------
-
- /**
- * @see #generalizeReturnType(Type)
- * @param signature String from which to extract the return type.
- */
- static Type generalizeReturnType (String signature) {
- Type type = Type.getReturnType(signature);
- return generalizeReturnType(type);
- }
-
- /**
- * Given a return type, determine a reference type to which this type can be
- * converted. "Object" if type is VOID.
- *
- * @param type
- * @return
- */
- static Type generalizeReturnType (Type type) {
- if (type instanceof ReferenceType) return type;
- return object;
- }
-
- /**
- * Get the generalized return type from <tt>sign1</tt>, unless
- * <tt>sing2</tt> has void return type. In the latter case return
- * <tt>Object</tt>.
- *
- * @see #generalizeReturnType(Type)
- * @param sign1
- * @param sign2
- * @return
- */
- static Type generalizeReturnType (String sign1, String sign2) {
- Type type = Type.getReturnType(sign2);
- if (type == Type.VOID) return object;
- return generalizeReturnType(sign1);
- }
-
- /**
- * Assuming a value of type <tt>oldType</tt> on the stack, convert it to a
- * value of type <tt>newType</tt>. Changes instruction list <tt>il</tt>
- * after position <tt>ih</tt> or at its end if <tt>ih</tt> is null.
- *
- * @param il
- * @param ih
- * @param oldType
- * @param newType
- * @return the first inserted instruction or null if no adjustment needed
- */
- InstructionHandle adjustValue (InstructionList il, InstructionHandle ih,
- Type oldType, Type newType) {
- if (ih == null)
- ih = il.getEnd();
- if (oldType.equals(newType))
- return null;
-
- if (newType == Type.VOID)
- return il.append(ih, new POP());
- else if (oldType == Type.VOID)
- return il.append(ih, InstructionFactory.ACONST_NULL);
- else if (oldType instanceof BasicType)
- return il.append(ih, createBoxing((BasicType)oldType));
- else if (newType instanceof BasicType)
- return il.append(ih, createUnboxing((BasicType)newType));
- else
- return il.append(ih, factory.createCast(oldType, newType));
- }
-
- // ------------------------------------------
- // ---------- (Un-)Boxing: ------------------
- // ------------------------------------------
-
- /**
- * Get the name of the class suitable for boxing <tt>basicType</tt>.
- *
- * @param basicType
- * @return
- */
- static String toObjectTypeName(BasicType basicType) {
- String result = "";
- switch (basicType.getType()) {
- case Constants.T_BOOLEAN : result = "java.lang.Boolean"; break;
- case Constants.T_INT : result = "java.lang.Integer"; break;
- case Constants.T_FLOAT : result = "java.lang.Float"; break;
- case Constants.T_DOUBLE : result = "java.lang.Double"; break;
- case Constants.T_SHORT : result = "java.lang.Short"; break;
- case Constants.T_BYTE : result = "java.lang.Byte"; break;
- case Constants.T_CHAR : result = "java.lang.Character"; break;
- case Constants.T_LONG : result = "java.lang.Long"; break;
- default: throw new Error("OTRE failure: Basic Type not supported!!"+basicType);
- }
- return result;
- }
-
- /**
- * Create the instructions needed for boxing a basic type value. The value
- * is expected on the stack an will be replaced by the boxed value.
- *
- * @param basicType type of the value on the stack.
- * @return an InstructionList containing the conversion instructions.
- */
- InstructionList createBoxing(BasicType basicType) {
- InstructionList il = new InstructionList();
- String boxedTypeName = toObjectTypeName(basicType);
- // .., result
- il.append(factory.createNew(boxedTypeName)); // .., result, box,
-
- if (basicType.equals(Type.DOUBLE) || basicType.equals(Type.LONG)) {
- // 'double' and 'long' are category 2 computational type:
- il.append(new DUP_X2()); // .., box, result, box
- il.append(new DUP_X2()); // .., box, box, result, box
- } else {
- il.append(new DUP_X1()); // .., box, result, box
- il.append(new DUP_X1()); // .., box, box, result, box
- }
- il.append(new POP()); // .., box, box, result
- il.append(factory.createInvoke(boxedTypeName,
- Constants.CONSTRUCTOR_NAME,
- Type.VOID,
- new Type[] { basicType },
- Constants.INVOKESPECIAL));
- return il;
- }
-
- /**
- * Create the instructions needed for unboxing a basic type value. The value
- * is expected on the stack an will be replaced by the unboxed value.
- *
- * @param basicType expected type after unboxing.
- * @return an InstructionList containing the conversion instructions.
- */
- InstructionList createUnboxing(BasicType basicType) {
- InstructionList il = new InstructionList();
- String boxedTypeName = toObjectTypeName(basicType);
- il.append(factory.createCast(object,
- new ObjectType(boxedTypeName)));
- il.append(factory.createInvoke(boxedTypeName,
- basicType.toString() + "Value",
- basicType,
- Type.NO_ARGS,
- Constants.INVOKEVIRTUAL));
- return il;
- }
-
- /** Push an integer constant using the most appropriate/compact instruction. */
- Instruction createIntegerPush(ConstantPoolGen cpg, int val) {
- if (val <= 5)
- return new ICONST(val);
- if (val <= Byte.MAX_VALUE)
- return new BIPUSH((byte)val);
- if (val <= Short.MAX_VALUE)
- return new SIPUSH((short)val);
- return new LDC(cpg.addInteger(val));
- }
-
- /**
- * Create a throwing instruction for an OTREInternalError.
- *
- * @param cpg
- * @param il instruction list to generate into
- * @param messagePush push sequence producing the exception message.
- * @return handle to the first generated instruction
- */
- InstructionHandle createThrowInternalError(ConstantPoolGen cpg, InstructionList il, InstructionList messagePush) {
- InstructionHandle start = il.append(factory.createNew(OTConstants.internalError));
- il.append(new DUP());
- il.append(messagePush);
- il.append(factory.createInvoke(OTConstants.internalError.getClassName(),
- Constants.CONSTRUCTOR_NAME,
- Type.VOID,
- new Type[] { Type.STRING },
- Constants.INVOKESPECIAL));
- il.append(new ATHROW());
- return start;
- }
-
- /**
- * Create a lookswitch from its constituents. Since JVM 1.4 this requires
- * sorting of matches.
- *
- * @param matches
- * @param targets
- * @param breaks an array of breaks (GOTOs) whose target will
- * be updated to point to <tt>afterSwitch</tt>
- * @param defaultBranch
- * @param afterSwitch
- * @return the generated instruction.
- */
- static BranchInstruction createLookupSwitch (int[] matches,
- InstructionHandle[] targets,
- GOTO[] breaks,
- InstructionHandle defaultBranch,
- InstructionHandle afterSwitch) {
-
- int numberOfCases = matches.length;
- for (int i = 0; i < numberOfCases; i++)
- breaks[i].setTarget(afterSwitch);
-
- HashMap<Integer, InstructionHandle> match_target_mapping = new HashMap<Integer, InstructionHandle>();
- for (int i = 0; i < numberOfCases; i++)
- match_target_mapping.put(Integer.valueOf(matches[i]), targets[i]);
-
- Arrays.sort(matches);
- for (int i = 0; i < numberOfCases; i++)
- targets[i] = match_target_mapping.get(Integer.valueOf(matches[i]));
-
- BranchInstruction inst = new LOOKUPSWITCH(matches, targets, defaultBranch);
- return inst;
- }
-
-
- /**
- * Read all byte code attributes for a given class. Side-Effect: depending
- * on the Referenced-Team attribute, additional classes may be scheduled for
- * loading.
- *
- * @param ce
- * @param cg
- * @param class_name
- * @param cpg
- */
- public void checkReadClassAttributes(ClassEnhancer ce,
- ClassGen cg,
- String class_name,
- ConstantPoolGen cpg)
- {
- AttributeReadingGuard guard = AttributeReadingGuard.getInstanceForLoader(this.loader);
- boolean addTeamInitializations = false;
- List<String> classesToLoad;
- synchronized (guard) {
- if (!guard.iAmTheFirst(class_name))
- return;
- if (AttributeReadingGuard.isFirstLoadedClass())
- addTeamInitializations = true;
- // scan for attributes here, because this transformer is applied first:
- Attribute[] attrsClass = cg.getAttributes();
- classesToLoad = scanClassOTAttributes(attrsClass, class_name, cpg, cg);
-
- guard.workDone(class_name);
- }
- if (addTeamInitializations)
- addTeamInitializations(cg, ce);
-
- Iterator<String> it = classesToLoad.iterator();
- while (it.hasNext()) {
- String next = it.next();
- if(logging) printLogMessage("Loading of class " + next + " will be forced now!");
- ce.loadClass(next, this);
- }
-
- // scan for parameter bindings:
- Method[] possibleRoleMethods = cg.getMethods();
- for (int i=0; i<possibleRoleMethods.length; i++) {
- Method meth = possibleRoleMethods[i];
- Attribute[] attrsMethod = meth.getAttributes();
- scanMethodOTAttributes(attrsMethod, class_name, meth.getName(), cpg);
- }
- if(logging) printLogMessage(this.getClass().getName()
- + " picked up the attributes for class " + class_name );
- }
-
- // --- helpers for adding line numbers at the front of a method ---
- // unfortunately BCEL does not sort line numbers, but the debugger expects them sorted.
- class Pair<F,S> {
- F first;
- S second;
- Pair(F f, S s) {
- this.first = f;
- this.second = s;
- }
- }
- @SuppressWarnings("unchecked") // can't declare array of generics
- Pair<InstructionHandle, Integer>[] saveLineNumbers(MethodGen method, ConstantPoolGen cpg) {
- LineNumberTable lnt = method.getLineNumberTable(cpg);
- InstructionHandle[] ihs = method.getInstructionList().getInstructionHandles();
- Pair<InstructionHandle, Integer>[] oldLines = new Pair[lnt.getTableLength()];
- {
- int cur = -1;
- int n = 0;
- for (int i=0; i<ihs.length; i++) {
- int next = lnt.getSourceLine(ihs[i].getPosition());
- if (next > cur) // reached a new source line
- oldLines[n++] = new Pair<InstructionHandle, Integer>(ihs[i], new Integer(next));
- cur = next;
- }
- }
- return oldLines;
- }
- /** Append the saved line numbers to the end of the method's line number table. */
- void restoreLineNumbers(MethodGen method, Pair<InstructionHandle, Integer>[] oldLines) {
- for (int i=0; i<oldLines.length; i++) {
- if (oldLines[i] == null)
- continue;
- InstructionHandle ih = oldLines[i].first;
- int line = oldLines[i].second.intValue();
- method.addLineNumber(ih, line);
- }
- }
-
- /**
- * Adds team initialization for all teams in the config file.
- *
- * @param cg
- * @param ce
- */
- private void addTeamInitializations(ClassGen cg, ClassEnhancer ce) {
- String main_class_name = cg.getClassName();
- ConstantPoolGen cpg = cg.getConstantPool();
- InstructionFactory factory = new InstructionFactory(cpg);
- Method main = cg.containsMethod("main", "([Ljava/lang/String;)V");
- if (main == null) {
- // JPLIS launching may intercept system classes before the custom main.
- // reset the guard in order to retry with subsequent classes.
- AttributeReadingGuard.reset();
- return; // no main method in the first loaded class...
- }
-
- MethodGen mainMethod = newMethodGen(main, main_class_name, cpg);
- InstructionList il = mainMethod.getInstructionList();
-
- int startLine = -1;
- Pair<InstructionHandle,Integer>[] oldLines = null;
- if (debugging) {
- LineNumberTable lnt = mainMethod.getLineNumberTable(cpg);
- if (lnt != null) {
- startLine = lnt.getSourceLine(0);
- oldLines = saveLineNumbers(mainMethod, cpg);
- }
- }
-
- if (TEAM_CONFIG_FILE != null) {
-
- InstructionList teamInitializations = new InstructionList();
- List<String> teamsToInitialize = getTeamsFromConfigFile();
- Iterator<String> teamIt = teamsToInitialize.iterator();
- while (teamIt.hasNext()) {
- String nextTeam = teamIt.next();
- JavaClass teamClass = null;
- try {
- teamClass = RepositoryAccess.lookupClass(nextTeam);
- } catch (ClassNotFoundException cfne) {
- System.err.println("Config error: Team class '"+nextTeam+ "' in config file '"+ TEAM_CONFIG_FILE+"' can not be found!");
- System.err.println("Main class = "+main_class_name+
- ", class loader = "+(this.loader!=null?this.loader.getClass().getName():"null")+
- ", transformer = "+this.getClass().getName());
- continue;
- }
- ClassGen teamClassGen = new ClassGen(teamClass);
- if (teamClassGen.containsMethod(Constants.CONSTRUCTOR_NAME, "()V") == null) {
- System.err.println("Activation failed: Team class '"+nextTeam+ "' has no default constuctor!");
- continue;
- }
- ce.loadClass(nextTeam, this);
- if (logging)
- printLogMessage("Adding initialization of team " + nextTeam
- + " to main method of class " + main_class_name);
- teamInitializations.append(factory.createNew(nextTeam));
- teamInitializations.append(new DUP());
- teamInitializations.append(factory.createInvoke(nextTeam,
- Constants.CONSTRUCTOR_NAME,
- Type.VOID,
- Type.NO_ARGS,
- Constants.INVOKESPECIAL));
- teamInitializations.append(factory.createGetStatic(OTConstants.teamClassName,
- "ALL_THREADS",
- OTConstants.threadType));
- teamInitializations.append(factory.createInvoke(nextTeam,
- "activate",
- Type.VOID,
- new Type[] {OTConstants.threadType},
- Constants.INVOKEVIRTUAL));
- }
- il.insert(teamInitializations);
- }
- // register main thread with TeamThreadManager:
- InstructionHandle cursor;
- cursor = il.insert(new ICONST(1)); // isMain=true
- cursor = il.append(cursor, new ACONST_NULL()); // parent=null
- cursor = il.append(cursor, factory.createInvoke("org.objectteams.TeamThreadManager",
- "newThreadStarted",
- Type.BOOLEAN,
- new Type[]{Type.BOOLEAN, OTConstants.threadType},
- Constants.INVOKESTATIC));
- cursor = il.append(cursor, new POP()); // don't use boolean return
-
- il.setPositions();
- if (debugging && startLine > 0) {
- mainMethod.removeLineNumbers(); // fresh start, to ensure correct order
- mainMethod.addLineNumber(il.getStart(), startLine-1); // new number to the front
- restoreLineNumbers(mainMethod, oldLines); // append old numbers
- }
- mainMethod.setInstructionList(il);
- mainMethod.setMaxStack();
- mainMethod.setMaxLocals();
-
- cg.replaceMethod(main, mainMethod.getMethod());
- }
-
- /**
- * @return a list of teams in the team initialization config file
- */
- private static List<String> getTeamsFromConfigFile() {
- List<String> result = new LinkedList<String>();
- try {
- FileInputStream fstream = new FileInputStream(TEAM_CONFIG_FILE);
- BufferedReader in = new BufferedReader(new InputStreamReader(fstream));
- while (in.ready()) {
- String nextLine = in.readLine();
- String nextTeam = nextLine.trim();
- if (nextTeam.startsWith(COMMENT_MARKER))
- continue; // this is a comment line
- if (!nextTeam.equals("")) {
- result.add(nextTeam.trim());
- }
- }
- in.close();
- } catch (Exception e) {
- System.err.println("File input error: config file '" + TEAM_CONFIG_FILE + "' can not be found!");
- }
- return result;
- }
-
- // -------------------------------------------------------------------------------------------------
- // -------- store and return adapted bases for OT/Equinox --------------
- // this data is collected by scanClassOTAttributes and must be collected by the caller
- // before processing the next class.
- // -------------------------------------------------------------------------------------------------
- public HashSet<String> adaptedBases = new HashSet<String>();
-
- /** Internal API for {@link org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer} */
- public Collection<String> fetchAdaptedBases() {
- HashSet<String> result;
- result = new HashSet<String>(adaptedBases);
- adaptedBases.clear();
- return result;
- }
-
- // -------------------------------------------------------------------------------------------------
- /**
- * Container for base method properties
- */
- public static class BaseMethodInfo {
- private String baseClassName;
- private String baseMethodName;
- private String baseMethodSignature;
- boolean isCallin;
- private boolean isRoleMethod;
- boolean isStatic;
- private int[] parameterPositions;
- int translationFlags;
-
- BaseMethodInfo(String base_class_name, String base_method_name,
- String base_method_signature, boolean isCallin,
- boolean isRoleMethod, boolean isStatic,
- int[] parameter_positions, int translationFlags)
- {
- this.baseClassName = base_class_name;
- this.baseMethodName = base_method_name;
- this.baseMethodSignature = base_method_signature;
- this.isCallin = isCallin;
- this.isRoleMethod = isRoleMethod;
- this.isStatic = isStatic;
- this.parameterPositions = parameter_positions;
- this.translationFlags = translationFlags;
- }
- /** Minimal version to pass some info into #translateLoads(): */
- BaseMethodInfo(boolean isCallin, boolean isStatic, int translationFlags)
- {
- this.isCallin = isCallin;
- this.isStatic = isStatic;
- this.translationFlags = translationFlags;
- }
-
- public boolean isStaticRoleMethod() {
- return this.isRoleMethod && this.isStatic;
- }
-
- String getBaseClassName() {
- return baseClassName;
- }
-
- String getBaseMethodName() {
- return baseMethodName;
- }
-
- String getBaseMethodSignature() {
- return baseMethodSignature;
- }
-
- int[] getParameterPositions() {
- return parameterPositions;
- }
- }
-
- /**
- * Scan the Attributes found in the class class_name for binding attributes
- * and registers them in the CallinBindingManager.
- *
- * @param attributes the Attributes to be examined
- * @param class_name the name of the class where the Attributes were found
- * @param cpg the classes ConstantPoolGen
- * @return an ArrayList containing the names of classes which have
- * to be loaded immediately
- */
- ArrayList<String> scanClassOTAttributes(Attribute[] attributes,
- String class_name,
- ConstantPoolGen cpg,
- ClassGen cg)
- {
- if(logging) printLogMessage("Inspecting " + class_name);
- ArrayList<String> classesToLoad = new ArrayList<String>();
- String base_class_name = null;
- for (int k=0; k<attributes.length; k++) {
- Attribute actAttr = attributes[k];
- Unknown attr = isOTAttribute(actAttr);
-
- if (attr != null) { //this is a callin attribute
- String attrName = attr.getName();
- if(logging) printLogMessage("CallinBindingAttribute: " + attrName);
- byte[] indizes = attr.getBytes();
- int count = combineTwoBytes(indizes, 0);
- int numberOfEntries=0;
- String [] names;
- if (attrName.equals("OTClassFlags")) {
- int classFlags = combineTwoBytes(indizes, 0);
- String flagsString = "";
- if ((classFlags & 1) != 0) {
- flagsString = "team ";
- // TODO: use this instead of team modifier
- }
- if ((classFlags & 2) != 0) {
- flagsString += "role";
- CallinBindingManager.addRole(class_name);
- }
- if (logging) {
- printLogMessage("OTClassFlags:");
- printLogMessage("\t" + flagsString);
- }
- } else if (attrName.equals("CallinRoleBaseBindings")) {
- numberOfEntries = 2;
- int i = 2;
- int n = 2 * count * numberOfEntries; // n = count << 2;
- names = new String[numberOfEntries];
- while (i <= n) {
- i = scanStrings(names, indizes, i, cpg);
- String role_name = names[0];
- String base_name = names[1];
- if(logging) printLogMessage("**** Binding: " + role_name
- + " playedBy " + base_name);
-
- //set binding:
- CallinBindingManager.addRoleBaseBinding(role_name, base_name, class_name);
- CallinBindingManager.addTeamBaseRelation(class_name, base_name);
-
- // [OT/Equinox] store adapted bases:
- adaptedBases.add(base_name);
-
- // super roles have to be loaded first for binding inheritance purpose:
- // not necessary anymore?
- //classesToLoad.addAll(getSuperRoles(role_name, attributes, cpg));
- // roles themselve have to be loaded too:
- classesToLoad.add(role_name);
- }
- } else if (attrName.equals("BoundClassesHierarchy")) {
- numberOfEntries = 2;
- int i = 2;
- int n = 2 * count * numberOfEntries; // n = count << 2;
- names = new String[numberOfEntries];
- while (i <= n) {
- i = scanStrings(names, indizes, i, cpg);
- String sub_name = names[0];
- String super_name = names[1];
-
- CallinBindingManager.addBoundSuperclassLink(sub_name, super_name);
- if(logging)printLogMessage("**** super-class link: "+sub_name
- +" -> "+super_name);
- }
- } else if (attrName.equals("CallinMethodMappings")) {
- //numberOfEntries = 6;
- int i = 2;
- for (int n=0; n<count;n++) {
- // JSR-045 support:
- names = new String[1];
- i = scanStrings(names, indizes, i, cpg);
- String binding_file_name = names[0];
- int binding_line_number = combineTwoBytes(indizes, i);
- i += 2;
- int binding_line_offset = combineTwoBytes(indizes, i);
- i += 2;
- boolean is_static_role_method = false;
- boolean covariant_base_return= false;
- // regular stuff:
- numberOfEntries = 3;
- names = new String[numberOfEntries];
- i = scanStrings(names, indizes, i, cpg);
- String wrapper_name = null;
- String wrapper_signature = null;
- // first 3 names:
- int index = 0;
-
- String binding_label = names[index++];
- String role_method_name = names[index++];
- String role_method_signature = names[index++];
-
- { // a flag:
- int flags = combineTwoBytes(indizes, i);
- is_static_role_method = (flags & 1) != 0;
- // flag value 4 is "inherited"
- covariant_base_return = (flags & 8) != 0;
- i+=2;
- }
- // 3 more names
- numberOfEntries = 3;
- names = new String[numberOfEntries];
- i = scanStrings(names, indizes, i, cpg);
- index = 0;
- //if (NEW_COMPILER_VERSION)
- // static_role_method = see attribute
-
- String lift_method_name = names[index++];
- String lift_method_signature = names[index++];
- String binding_modifier = names[index++];
-
- int base_len = combineTwoBytes(indizes, i);
- i += 2;
-
- names = new String[4];
- for (int n_base = 0; n_base < base_len; n_base++) {
- i = scanStrings(names, indizes, i, cpg);
- String base_method_name = names[0];
- String base_method_signature = names[1];
- wrapper_name = names[2];
- wrapper_signature = names[3];
-
- byte baseFlags = indizes[i++];
- boolean baseIsCallin = (baseFlags & 1) != 0;
- boolean baseIsStatic = (baseFlags & 2) != 0;
- int translationFlags = (combineTwoBytes(indizes, i)<<16) + combineTwoBytes(indizes, i+2);
- i += 4;
-
- if(logging) {
- printLogMessage("**** Binding: " + binding_label + ":"
- + role_method_name + role_method_signature
- + " <- " + binding_modifier + " "
- + base_method_name + base_method_signature);
- printLogMessage("**** Wrapper: " + wrapper_name
- + wrapper_signature);
- }
- //set binding:
- CallinBindingManager.addMethodBinding(class_name,
- base_class_name, // previously read from PlayedBy attribute
- binding_file_name,
- binding_line_number,
- binding_line_offset,
- binding_label,
- role_method_name,
- role_method_signature,
- is_static_role_method,
- wrapper_name,
- wrapper_signature,
- binding_modifier,
- base_method_name,
- base_method_signature,
- baseIsStatic,
- baseIsCallin,
- covariant_base_return,
- translationFlags,
- lift_method_name,
- lift_method_signature);
-
- }
- }
- } else if (attrName.equals("OTSpecialAccess")) {
- numberOfEntries = 3;
- int i = 2;
- for (int j = 0; j < count; j++) {
- short kind = indizes[i++];
- switch (kind) {
- case 1: // DecapsulatedMethodAccess
- names = new String[numberOfEntries];
- i = scanStrings(names, indizes, i, cpg);
- if(logging) printLogMessage("**** Callout: " + names[0] + "."
- + names[1]+ " " + names[2]);
- CallinBindingManager.addCalloutBinding(names[0], names[1], names[2]);
- break;
- case 2: // CalloutFieldAccess
- short flags = indizes[i++];
- String accessMode = (flags & 1) == 1 ? "set" : "get";
- boolean isStaticField = (flags & 2) != 0;
- names = new String[numberOfEntries];
- i = scanStrings(names, indizes, i, cpg);
- if (logging)
- printLogMessage("**** Callout bound field: " + accessMode+(isStaticField?" static ":" ")
- + names[2]+ " " + names[1]);
- CallinBindingManager.addCalloutBoundFileds(names[0], names[1], names[2], accessMode, isStaticField);
-
- synchronized(reentrentTransformations) {
- for (ObjectTeamsTransformation transformation : reentrentTransformations)
- transformation.state.interfaceTransformedClasses.remove(names[0]);
- }
-
- break;
- case 3: // SuperMethodAccess
- numberOfEntries = 4;
- names = new String[numberOfEntries];
- i = scanStrings(names, indizes, i, cpg);
- if(logging) printLogMessage("**** SuperAccess: " + names[0] + "."
- + names[2]+ names[3]+" superclass "+names[1]);
- CallinBindingManager.addSuperAccess(names[0], names[1], names[2], names[3]);
- break;
- }
- }
- // adapted baseclasses (w/ or w/o decapsulation):
- count = combineTwoBytes(indizes, i);
- i += 2;
- names = new String[1];
- for (int j=0; j<count; j++) {
- i = scanStrings(names, indizes, i, cpg);
- byte flag = indizes[i++];
- if (flag == 1) {
- CallinBindingManager.addBaseClassForModifierChange(names[0]);
- } else {
- // [OT/Equinox]: store adapted bases:
- adaptedBases.add(names[0]);
- }
- }
- } else if (attrName.equals("ReferencedTeams")) {
- numberOfEntries = 1;
- int i = 2;
- int n = 2 * count * numberOfEntries; // n = count << 1;
- names = new String[numberOfEntries];
- while (i <= n) {
- i = scanStrings(names, indizes, i, cpg);
- String referenced_team = names[0];
- if(logging) printLogMessage("**** found ReferencedTeams: " + referenced_team);
- classesToLoad.add(referenced_team);
-
- }
- } else if (attrName.equals("PlayedBy")) {
- names = new String[1];
- scanStrings(names, indizes, 0, cpg);
- base_class_name = names[0];
- int langle = base_class_name.indexOf('<');
- if (langle > -1) // it's an anchored type p.T$R<@C.o.f>, cut off everything after and including '<'.
- base_class_name = base_class_name.substring(0, langle-1);
- if(logging) printLogMessage("**** found PlayedBy: " + base_class_name);
- // base_class_name is stored for later use, when method bindings are found.
- CallinBindingManager.addSuperRoleLink(cg.getClassName(), cg.getSuperclassName());
- // this information is NOT NEEDED at moment!
- } else if (attrName.equals("OTCompilerVersion")) {
- int encodedVersion = combineTwoBytes(indizes, 0);
- int major = encodedVersion >>> 9;
- int minor = (encodedVersion >>> 5) & 0xF;
- int revision = encodedVersion & 0x1F;
- if(logging) printLogMessage("**** class file was produced by compiler version "
- + major + "." + minor + "." + revision + " ****");
- IS_COMPILER_GREATER_123 = false; // reset, may be updated below
- // 1.5 stream:
- if (major == 1 && minor == 5) {
- if (revision < OT15_REVISION) {
- if (class_name.startsWith(OTConstants.teamClassName))
- continue; // no specific byte codes in ooTeam and its inner classes.
- throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
- }
- IS_COMPILER_GREATER_123 = true;
- IS_COMPILER_13X_PLUS = true;
- IS_COMPILER_14X_PLUS = true;
- // 1.4 stream:
- } else if (major == 1 && minor == 4) {
- if (revision < OT14_REVISION) {
- if (class_name.startsWith(OTConstants.teamClassName))
- continue; // no specific byte codes in ooTeam and its inner classes.
- throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
- }
- IS_COMPILER_GREATER_123 = true;
- IS_COMPILER_13X_PLUS = true;
- IS_COMPILER_14X_PLUS = true;
- // 1.3 stream:
- } else if (major == 1 && minor == 3) {
- if (revision < OT13_REVISION) {
- if (class_name.startsWith(OTConstants.teamClassName))
- continue; // no specific byte codes in ooTeam and its inner classes.
- throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
- }
- IS_COMPILER_GREATER_123 = true;
- IS_COMPILER_13X_PLUS = true;
- // 1.2 stream:
- } else if (major == 1 && minor == 2) {
- if (revision < OT12_REVISION) {
- if (class_name.startsWith(OTConstants.teamClassName))
- continue; // no specific byte codes in ooTeam and its inner classes.
- throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
- }
- if (revision > 3)
- IS_COMPILER_GREATER_123 = true;
- // 1.1 stream:
- } else if (major == 1 && minor == 1) {
- if (revision < OT11_REVISION) {
- if (class_name.startsWith(OTConstants.teamClassName))
- continue; // no specific byte codes in ooTeam and its inner classes.
- throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
- }
- // 1.0 stream:
- } else if (major == 1 && minor == 0) {
- if (revision < OT10_REVISION) {
- if (class_name.startsWith(OTConstants.teamClassName))
- continue; // no specific byte codes in ooTeam and its inner classes.
- throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
- }
- // 0.9 stream:
- } else if (major == 0 && minor == 9) {
- if (revision < OT09_REVISION) {
- if (class_name.startsWith(OTConstants.teamClassName))
- continue; // no specific byte codes in ooTeam and its inner classes.
- throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
- }
- // 0.8 stream (OBSOLETE!)
- } else {
- if (major != OT_VERSION_MAJOR)
- throw new InternalError("OTRE: Class " + class_name + " has unsupported major version " + major);
- if (minor != OT_VERSION_MINOR)
- throw new InternalError("OTRE: Class " + class_name + " has unsupported minor version " + minor);
- if (revision < OT_REVISION)
- throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
- }
- } else if (attrName.equals("CallinPrecedence")) {
- List<String> precedenceList = new LinkedList<String>();
- numberOfEntries = 1;
- int i = 2;
- int n = 2 * count * numberOfEntries; // n = count << 1;
- names = new String[numberOfEntries];
- while (i <= n) {
- i = scanStrings(names, indizes, i, cpg);
- String binding_label = names[0];
- precedenceList.add(binding_label);
- }
- if(logging) printLogMessage("**** found precedence list for " + class_name + ": "
- + precedenceList + " ****");
- CallinBindingManager.addPrecedenceList(precedenceList, class_name);
- }
- }
- }
- return classesToLoad;
- }
-
- /**
- * Read some strings from a byte array.
- * @param entries Result array to be provided by caller.
- * @param indizes buffer of read bytes to be provided by caller,
- * consists if indizes into the constant pool
- * @param i current index into indizes
- * @param cpg the pool.
- * @result updated value of <tt>i</tt>.
- */
- public static int scanStrings(String[] entries,
- byte[] indizes,
- int i,
- ConstantPoolGen cpg)
- {
- for (int j = 0; j < entries.length; j++) {
- int nextIndex = combineTwoBytes(indizes, i);
- ConstantUtf8 cons = (ConstantUtf8)cpg.getConstant(nextIndex);
- String content = cons.getBytes();
- entries[j] = content;
- i += 2;
- }
- return i;
- }
-
- /**
- * Scan the Attributes found in the method <tt>method_name</tt> for binding attributes
- * and registers them in the {@link CallinBindingManager CallinBindingManager}.
- *
- * @param attributes the Attributes to be examined
- * @param class_name the name of the class where the Attributes were found
- * @param method_name the name of the method where the Attributes were found
- * @param cpg
- */
- static void scanMethodOTAttributes(Attribute[] attributes,
- String class_name,
- String method_name,
- ConstantPoolGen cpg)
- {
- for (int k = 0; k < attributes.length; k++) {
- Attribute actAttr = attributes[k];
- Unknown attr = isOTAttribute(actAttr);
- if (attr != null) { //this is an OT attribute
- String attrName = attr.getName();
- if(logging) printLogMessage("CallinBindingAttribute(" + method_name + ") :"
- + attrName);
- if (attrName.equals("CallinParamMappings")) {
- byte[] indizes = attr.getBytes();
- int [] positions = null;
- if (indizes == null) throw new RuntimeException("Unexpected null attr");
- int count = combineTwoBytes(indizes, 0);
- positions = new int[count];
- int p = 2;
- for (int i = 0; i < count; i++, p += 2) {
- positions[i] = combineTwoBytes(indizes, p);
- // System.out.println(" "+i+"<-"+positions[i]);
- }
- CallinBindingManager.addParameterBinding(class_name,
- method_name,
- positions);
- // Here it is correct to use the (wrapper) method name without a signature,
- // because for overloaded methods there are separate wrappers with unique (mangled) names.
- }
- }
- }
- }
-
-
- /**
- * Determines, if the given Attribute is a callin-attribute.
- *
- * @param attr the Attriute to be checked
- * @return the Attribute casted to Unknown, for later use, if true
- * null, if it is not a callin-attribute
- */
- static Unknown isOTAttribute(Attribute attr) {
- if (attr instanceof Unknown) {
- Unknown unknown = (Unknown)attr;
- String attrName = unknown.getName();
- if (attrName.equals("CallinRoleBaseBindings") ||
- attrName.equals("BoundClassesHierarchy") ||
- attrName.equals("CallinMethodMappings") ||
- attrName.equals("CallinParamMappings") ||
- attrName.equals("CallinFlags") ||
- attrName.equals("OTSpecialAccess") ||
- attrName.equals("WrappedRoleSignature") ||
- attrName.equals("WrappedBaseSignature") ||
- attrName.equals("ReferencedTeams") ||
- attrName.equals("PlayedBy") ||
- attrName.equals("Modifiers") ||
- attrName.equals("OTCompilerVersion") ||
- attrName.equals("OTClassFlags") ||
- attrName.equals("OTJoinPoints") ||
- attrName.equals("CallinPrecedence") ||
- attrName.equals("StaticReplaceBindings"))
- {
- return unknown;
- }
- }
- return null;
- }
-
- /**
- * Combines two int's representing the higher and the lower part
- * of a two byte number.
- *
- * @param first the first (higer?) byte
- * @param second the second (lower?) byte
- * @return the combined number
- */
- public static int combineTwoBytes(byte [] indizes, int start) {
- int first = indizes[start];
- int second = indizes[start + 1];
- int twoBytes = 0;
-
- twoBytes = twoBytes | (first & 0xff);
- twoBytes = twoBytes << 8;
- twoBytes = twoBytes | (second & 0xff);
- return twoBytes;
- }
-
- /**
- * Returns a list of names of all super classes of class 'role_name' which are inner
- * classes of the enclosing team, what are all super roles of the
- * role 'role_name'.
- *
- * @param role_name the name of the role class
- * @param attributes the attributes of the enclosing team class
- * @param cpg the constant pool of the enclosing team class
- * @return the list of super role names
- */
- /*
- private List getSuperRoles(String role_name, Attribute[] attributes, ConstantPoolGen cpg) {
- LinkedList superRoleNames = new LinkedList();
- JavaClass[] super_classes = Repository.getSuperClasses(role_name);
- if (super_classes.length < 2) {// extends only Object, or none?
- return superRoleNames;
- }
- LinkedList innerClassNames = new LinkedList();
- for (int i=0; i<attributes.length; i++) {
- Attribute actAttr = attributes[i];
- if (actAttr instanceof InnerClasses) {
- InnerClass[] inners = ((InnerClasses)actAttr).getInnerClasses();
- for (int j=0; j<inners.length; j++) {
- int name_index = inners[j].getInnerNameIndex();
- Constant name_c = cpg.getConstant(name_index);
- String name = ((ConstantUtf8)name_c).getBytes();
- int outer_class_index = inners[j].getOuterClassIndex();
- Constant outer_c = cpg.getConstant(outer_class_index);
- String outerName = ((ConstantClass)outer_c).getBytes(cpg.getConstantPool());
- outerName = outerName.replace('/', '.');
- innerClassNames.add(outerName + "$" +name);
- }
- }
- }
- for (int i=0; i<super_classes.length; i++) {
- String superClassName = super_classes[i].getClassName();
- if (innerClassNames.contains(superClassName)) {
- superRoleNames.addFirst(superClassName);
- }
- }
- return superRoleNames;
- }*/
-
- /** Create a MethodGen and remove some unwanted code attributes (which would need special translation which we don't have) */
- protected static MethodGen newMethodGen(Method m, String class_name, ConstantPoolGen cp) {
- MethodGen mg = new MethodGen(m, class_name, cp);
- List<Attribute> attributesToRemove = new ArrayList<Attribute>();
- for (Attribute attr : mg.getCodeAttributes())
- if (attr instanceof Unknown || attr instanceof StackMap)
- attributesToRemove.add(attr);
- for (Attribute attr : attributesToRemove)
- mg.removeCodeAttribute(attr);
- return mg;
- }
-
- /**
- * Remove all contents of a method as preparation for adding a new implementation
- *
- * @param m The original method
- * @param class_name The class containing the method
- * @param cpg The class' constant pool
- * @return An empty method generator with the same declaration as m
- * and no implementation.
- */
- protected static MethodGen wipeMethod(Method m, String class_name, ConstantPoolGen cpg) {
- MethodGen mg;
- mg = new MethodGen(m, class_name, cpg);
- mg.getInstructionList().dispose(); //throw away the old implementation
- mg.removeLineNumbers();
- mg.removeLocalVariables();
- mg.removeExceptionHandlers();
- mg.removeAttributes();
- mg.removeCodeAttributes();
- return mg;
- }
-
- /**
- * Add instructions of InstructionList il after the super constructor call of this constuctor.
- *
- * @param m the constructor method
- * @param addedCode the InstructionList containing the instructions to be added
- * @param cg the ClassGen
- * @param cpg the constant pool
- */
- static void addToConstructor(Method m, InstructionList addedCode, ClassGen cg, ConstantPoolGen cpg) {
- String class_name = cg.getClassName();
- MethodGen mg = newMethodGen(m, class_name, cpg);
- InstructionList il = mg.getInstructionList().copy();
- InstructionHandle[] ihs = il.getInstructionHandles();
-
- MethodGen newConstructor = new MethodGen(mg.getAccessFlags(),
- mg.getReturnType(),
- mg.getArgumentTypes(),
- mg.getArgumentNames(),
- mg.getName(),
- class_name,
- il,
- cpg );
-
-//[SH:]
- updateCopiedMethod(mg, il, ihs, newConstructor);
-//[:HS]
-
- int stackDepth = 0;
- int actInstrIndex = 0;
-
- boolean pauseStackCounting = false;
- InstructionHandle gotoTarget = null;
-
- // skip everything up to and including super() or this() call
- while (!((ihs[actInstrIndex].getInstruction() instanceof INVOKESPECIAL)
- && (stackDepth - (ihs[actInstrIndex].getInstruction().consumeStack(cpg))) == 0)) {
-
- Instruction actInstruction = ihs[actInstrIndex].getInstruction();
-
- if (gotoTarget != null && actInstruction.equals(gotoTarget.getInstruction())) {
- pauseStackCounting = false;
- gotoTarget = null;
- }
-
- if (actInstruction instanceof GotoInstruction) {
- GotoInstruction gotoInsruction = (GotoInstruction)actInstruction;
- gotoTarget = gotoInsruction.getTarget();
- pauseStackCounting = true;
- }
- if (!pauseStackCounting) {
- stackDepth -= actInstruction.consumeStack(cpg);
- stackDepth += actInstruction.produceStack(cpg);
- }
-
- actInstrIndex++;
- }
-
- InstructionHandle ih = ihs[actInstrIndex];
- INVOKESPECIAL invoke = (INVOKESPECIAL)ih.getInstruction();
- String specialName = invoke.getName(cpg);
- if (!specialName.equals(Constants.CONSTRUCTOR_NAME)) {
- System.err.println("###ALERT: " + specialName);
- return;
- }
-
- if (logging) printLogMessage("Adding code to " + class_name + "." + m.getName());
-
- // calculate the length of the added code BEFORE it is inserted into the instruction list:
-//[SH:] extracted for adding further manipulation of addedCode:
- int addedCodeLength = padCodeToAdd(addedCode);
-//[:HS]
-
- InstructionHandle startOfAddedCode = il.append(ih, addedCode);
-
- il.setPositions();
-
- newConstructor.setInstructionList(il);
- newConstructor.setMaxStack();
- newConstructor.setMaxLocals();
-//[SH:] if an unused local variable was copied in updateCopiedMethod()
-// we have to adjust max_locals,
-// because unused locals are not found by setMaxLocals().
- newConstructor.setMaxLocals(Math.max(newConstructor.getMaxLocals(), mg.getMaxLocals()));
-//[:HS]
-
- copyAndAdjustLineNumbers(mg, newConstructor, addedCodeLength, startOfAddedCode);
-
- cg.replaceMethod(m, newConstructor.getMethod());
- }
-
- /**
- * Pads a given instruction list to multiples of 4 returning the padded length.
- * Note that clients of this function must not call removeNOPs()!
- *
- * Rationale:
- * switch instructions pad the lists of jmp targets to start at an offset % 4 == 0.
- * In order to ensure that this padding will not change when inserting new bytes
- * the added bytes have to be a multiple of 4.
- */
- static int padCodeToAdd(InstructionList addedCode) {
-//[orig:]
- int addedCodeLength = 0;
- Instruction[] instr = addedCode.getInstructions();
- for (int i = 0; i < instr.length; i++) {
- addedCodeLength += instr[i].getLength();
- }
-//[:giro]
- while (addedCodeLength % 4 > 0) {
- addedCode.append(new NOP());
- addedCodeLength++;
- }
- return addedCodeLength;
- }
-
-//[SH:] helper methods for more complete method copying:
-
- /** After a method (incl. its instruction list) has been copied,
- * we need to manually copy some more properties:
- * + local variables
- * + declared exceptions
- * + exception handlers.
- */
- static void updateCopiedMethod(MethodGen methodOrig,
- InstructionList ilCopy,
- InstructionHandle[] ihsCopy,
- MethodGen methodCopy)
- {
- // local variables:
- LocalVariableGen[] oldLocals = methodOrig.getLocalVariables();
- int argLen = methodOrig.getArgumentTypes().length;
- if (!methodOrig.isStatic())
- argLen++; // this
- if (oldLocals.length > argLen) {
- InstructionList oldIL = methodOrig.getInstructionList();
- int maxLocals = methodOrig.getMaxLocals();
- for (int i = argLen; i<oldLocals.length; i++) {
- LocalVariableGen var = oldLocals[i];
- LocalVariableGen newVar =
- methodCopy.addLocalVariable(var.getName(), var.getType(),
- mapIH(var.getStart(), oldIL, ihsCopy),
- mapIH(var.getEnd(), oldIL, ihsCopy));
- newVar.setIndex(var.getIndex());
- // reset, addLocalVariable might have changed this.
- methodCopy.setMaxLocals(maxLocals);
- }
- }
- // declared exceptions:
- BaseCallRedirection.copyExceptionHandlers(methodOrig, methodCopy, ilCopy);
- // exception handlers:
- for(String excName : methodOrig.getExceptions())
- methodCopy.addException(excName);
- }
-
- static InstructionHandle mapIH(InstructionHandle alienIH, InstructionList oldIL, InstructionHandle[] newIHs)
- {
- int position = alienIH.getPosition();
- int[] newPositions = oldIL.getInstructionPositions();
- for (int i=0; i<newPositions.length; i++) {
- if (newPositions[i] == position)
- return newIHs[i];
- }
- return null;
- }
-//[:HS]
-
- /**
- * Copy all line numbers from <tt>src</tt> to <tt>dest</tt>.
- * For bytecode instructions after the added code area an offset has to be added to the
- * bytecode positions of the line numbers.
- * If in debug modus (flag 'debugging') add 'STEP_OVER_LINENUMBER' for the added code.
- *
- * @param src The source method.
- * @param dest The destination method.
- * @param offset The offest to be added (the length of the added code list).
- * @param startOfAddedCode InstructionHandle to the beginning of the added code.
- */
- static void copyAndAdjustLineNumbers(MethodGen src, MethodGen dest, int offset, InstructionHandle startOfAddedCode) {
- InstructionList il_dest = dest.getInstructionList();
- LineNumberGen[] src_lng = src.getLineNumbers();
- boolean addedCodeHasLineNumber = false;
-
- for (int i = 0; i < src_lng.length; i++) {
- int position = src_lng[i].getInstruction().getPosition();
- if (position == startOfAddedCode.getPosition()) { // add the line number for added code here:
- dest.addLineNumber(startOfAddedCode, STEP_OVER_LINENUMBER);
- addedCodeHasLineNumber = true;
- continue;
- }
- if (position >= startOfAddedCode.getPosition()) // move line numbers, because of inserted code (add offset)
- position += offset;
- InstructionHandle ih = il_dest.findHandle(position);
- if (ih == null) {
- System.err.println("Handle not found!");
- } else {
- dest.addLineNumber(ih, src_lng[i].getSourceLine());
- }
- }
- if (!addedCodeHasLineNumber) { // no custom code after added code: add line number now:
- dest.addLineNumber(startOfAddedCode, STEP_OVER_LINENUMBER);
- }
- }
-
- /**
- * Test if a method has the given 'callin_flag'.
- *
- * @param m the method to search
- * @param cg the ClassGen
- * @param callin_flags the flags to check for; 0 means any callin flags
- * @return true, if the method has the callin flag
- */
- public static boolean methodHasCallinFlags(Method m, ClassGen cg, int callin_flags) {
- boolean found = false;
- Attribute[] attributes = m.getAttributes();
- for (int i = 0; i < attributes.length; i++) {
- Attribute actAttr = attributes[i];
- if (!(actAttr instanceof Unknown))
- continue;
- Unknown attr = (Unknown)actAttr;
- if (!(attr.getName().equals("CallinFlags")))
- continue;
- if (callin_flags == 0)
- return true;
- byte [] bytes = attr.getBytes();
- int flags = combineTwoBytes(bytes, 0);
- if ((flags & callin_flags) != 0) {
- if(logging) printLogMessage("Found CallinFlag " + callin_flags + " for "
- + cg.getClassName() + "." + m.getName() + ".");
- found = true;
- }
- }
- return found;
- }
-
- /**
- * A team needs to get added the team specific part, if it is a non-abstract team and
- * not the class org.objectteams.Team itself.
- *
- * @param cg the class to be tested
- * @return true if this is a team which has to be extended
- */
- protected static boolean classNeedsTeamExtensions(ClassGen cg) {
- return ((cg.getAccessFlags() & OTConstants.TEAM) != 0) // must be a team
- && ((cg.getAccessFlags() & Constants.ACC_ABSTRACT) == 0) // and non-abstract
- && !(cg.getClassName().equals(OTConstants.teamClassName)); // and not o.o.Team itself.
- }
-
- /**
- * Generates the name of the implementing role for the given role interface name.
- * (Inserts the '__OT__' marker.)
- *
- * @param roleName the role interface name
- * @return the implementing role class name
- */
- protected static String genImplementingRoleName(String roleName) {
- int lastDollar = roleName.lastIndexOf('$');
- StringBuilder sb = new StringBuilder(roleName);
- sb.insert(lastDollar + 1, OTDT_PREFIX);
- return sb.toString();
- }
-
- /**
- * Generates the name of the role interface the given role class is implementing.
- *(Removes the '__OT__' marker.)
- *
- * @param roleName the role class name
- * @return the implemented role interface
- */
- public static String genRoleInterfaceName(String roleName) {
- int lastDollar = roleName.lastIndexOf('$');
- StringBuilder sb = new StringBuilder(roleName);
- sb.delete(lastDollar + 1, lastDollar + 1 + OTDT_PREFIX.length());
- return sb.toString();
- }
-
- protected static boolean isReflectiveOTMethod(String methodName, String methodSignature) {
- if ((methodName.equals("hasRole") && methodSignature.equals("(Ljava/lang/Object;)Z"))
- || (methodName.equals("hasRole") && methodSignature.equals("(Ljava/lang/Object;Ljava/lang/Class;)Z"))
- || (methodName.equals("getRole") && methodSignature.equals("(Ljava/lang/Object;)Ljava/lang/Object;"))
- || (methodName.equals("getRole") && methodSignature.equals("(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;"))
- || (methodName.equals("getAllRoles") && methodSignature.equals("()[Ljava/lang/Object;"))
- || (methodName.equals("getAllRoles") && methodSignature.equals("(Ljava/lang/Class;)[Ljava/lang/Object;"))
- || (methodName.equals("unregisterRole") && methodSignature.equals("(Ljava/lang/Object;)V"))
- || (methodName.equals("unregisterRole") && methodSignature.equals("(Ljava/lang/Object;Ljava/lang/Class;)V"))
- )
- return true;
- return false;
- }
-
- /**
- * Calculates the name of the outer class.
- *
- * @param className the full name of the inner class
- * @return the name of the outer class
- */
- public static String getOuterClassName(String className) {
- int dollarIndex = className.lastIndexOf('$');
- if (dollarIndex == -1) // no outer class exists!
- return null;
- String outerClassName = className.substring(0, dollarIndex);
- return outerClassName;
- }
-
- /**
- * @param m
- * @param cg
- * @return
- */
- static boolean candidateForImplicitActivation(Method m, ClassGen cg, ConstantPoolGen cpg) {
- if (!IS_COMPILER_14X_PLUS)
- implicitActivationMode = ImplicitActivationMode.ALWAYS;
- switch (implicitActivationMode) {
- case NEVER:
- return false;
- case ANNOTATED :
- if ( AnnotationHelper.containsImplicitActivationAttribute(m.getAttributes(), cpg)
- || AnnotationHelper.containsImplicitActivationAttribute(cg.getAttributes(), cpg))
- return canImplicitlyActivate(m);
- return false;
- case ALWAYS:
- if (!canImplicitlyActivate(m))
- return false;
-
- Attribute[] attributes = m.getAttributes();
- for(Attribute a : attributes) {
- if (a instanceof Unknown) {
- Unknown attr = (Unknown) a;
- String attrName = attr.getName();
- if ("RoleClassMethodModifiers".equals(attrName)) {
- byte[] bytes = attr.getBytes();
- int flags = combineTwoBytes(bytes, 0);
- if (flags == 0 ||/* flags == 2 || */flags == 4) {
- // 0: default, 2: private, 4: protected
- return false;
- }
- }
- }
- }
- if (!m.isPublic())
- return false; // m originally wasn't public
-
- String className = cg.getClassName();
- return !(CallinBindingManager.isRole(className) && cg.isProtected());
- default:
- return false; // cannot happen switch is exhaustive.
- }
- }
-
- private static boolean canImplicitlyActivate(Method m) {
- String methodName = m.getName();
- String methodSignature = m.getSignature();
- boolean isCandidate =
- (!m.isAbstract()) &&
- (!m.isStatic()) &&
- (!methodName.startsWith(OT_PREFIX)) &&
- (!methodName.equals(Constants.CONSTRUCTOR_NAME)) &&
- (!(methodName.equals("activate") && methodSignature.equals("()V"))) &&
- (!(methodName.equals("deactivate") && methodSignature.equals("()V"))) &&
- (!isReflectiveOTMethod(m.getName(), methodSignature));
- return isCandidate;
- }
-
- /**
- * @param s
- * @param c
- * @return
- */
- static int countOccurrences(String s, char c) {
- int count = 0;
- int idx = s.indexOf(c);
- while (idx != -1) {
- idx = s.indexOf(c, idx + 1);
- count++;
- }
- return count;
- }
-
- /**
- * This method performs the changes for implicit Team activation.
- * @param m a method for which implicit activation will be enabled.
- * @param className the class name for 'm'.
- * @param cpg the constant pool of the class 'className'.
- * @param activateOuter true, if the surrounding team has to be activated
- * @return
- */
- Method genImplicitActivation(Method m, String className, ConstantPoolGen cpg, boolean activateOuter) {
- String targetName = className;
- int nestingDepth = 0;
- ObjectType outerClass = null;
- if (activateOuter) {
- outerClass = new ObjectType(getOuterClassName(className));
- nestingDepth = countOccurrences(className, '$') - 1;
- targetName = outerClass.getClassName();
- }
- MethodGen mg = newMethodGen(m, className, cpg);
- InstructionList il = mg.getInstructionList();
- InstructionList prefix = new InstructionList();
- InstructionHandle try_start = il.getStart();
- // ---> new implicit activation
- prefix.append(InstructionFactory.createThis());
- if (activateOuter) {// this is for a role method: activate the outer team
- // FIXME(SH): check replacing this$n with _OT$getTeam()
- prefix.append(factory.createGetField(className, "this$" + nestingDepth, outerClass));
- }
- prefix.append(factory.createInvoke(targetName, "_OT$implicitlyActivate",
- Type.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
- // <-- new implicit activation
- if (debugging)
- mg.addLineNumber(prefix.getStart() , STEP_OVER_LINENUMBER);
- il.insert(prefix);
-
- InstructionList postfix = new InstructionList();
- // ---> new implicit deactivation
- postfix.append(InstructionFactory.createThis());
- if (activateOuter) {// this is for a role method: deactivate the outer team
- postfix.append(factory.createGetField(className, "this$"+nestingDepth, outerClass));
- }
- postfix.append(factory.createInvoke(targetName,
- "_OT$implicitlyDeactivate", Type.VOID, Type.NO_ARGS,
- Constants.INVOKEVIRTUAL));
- // <-- new implicit deactivation
-
- insertBeforeReturn(mg, il, postfix);
-
- /**
- * **** add an exception handler which calls deactivate before throwing
- * the exception (finaly-simulation): ***
- */
- ObjectType throwable = new ObjectType("java.lang.Throwable");
- LocalVariableGen exception = mg.addLocalVariable(
- "_OT$thrown_exception", throwable, null, null);
- InstructionHandle try_end = il.getEnd();
- InstructionList postfix_ex = postfix.copy();
- if (debugging)
- mg.addLineNumber(postfix_ex.getStart(), STEP_OVER_LINENUMBER);
- postfix_ex.insert(InstructionFactory.createStore(throwable, exception
- .getIndex()));
- postfix_ex.append(InstructionFactory.createLoad(throwable, exception
- .getIndex()));
- postfix_ex.append(new ATHROW());
- InstructionHandle deactivation_handler = il.append(il.getEnd(),
- postfix_ex);
- mg.addExceptionHandler(try_start, try_end, deactivation_handler,
- throwable);
- /** ******************************************************************** */
-
- mg.setInstructionList(il);
- mg.setMaxLocals();
- mg.setMaxStack();
-
- if (!debugging)
- return mg.getMethod();
-
- /* sorting the line numbers per start pc: */
- Method newMethod = mg.getMethod();
- MethodGen newMethodGen = new MethodGen(newMethod, className, cpg);
-
- LineNumberGen[] lineNumbers = newMethodGen.getLineNumbers();
-
- newMethodGen.removeLineNumbers();
-
- Arrays.sort(lineNumbers, new Comparator<LineNumberGen>() {
- public int compare(LineNumberGen ln1, LineNumberGen ln2) {
- int firstLineNumberPC = ln1.getLineNumber().getStartPC();
- int secondLineNumberPC = ln2.getLineNumber().getStartPC();
-
- if (firstLineNumberPC < secondLineNumberPC)
- return -1;
- if (firstLineNumberPC > secondLineNumberPC)
- return 1;
- return 0;
- }
- });
-
- for (int i = 0; i<lineNumbers.length; i++) {
- newMethodGen.addLineNumber(lineNumbers[i].getInstruction(), lineNumbers[i].getSourceLine());
- }
-
- return newMethodGen.getMethod();
- }
-
- /**
- * How many bytes does an instruction produce on the stack?
- */
- static protected int stackDiff(Instruction instr, ConstantPoolGen cpg) {
- return instr.produceStack(cpg) - instr.consumeStack(cpg);
- }
-
- /**
- * Split an instruction list that loads method arguments into
- * one list for each argument.
- * @param cpg
- * @param src the original loading sequence (will be destroyed by this method).
- * @param argumentTypes source-level argument types of the callin method.
- * @return array of load sequences, same order as before but split into individual arguments.
- */
- protected InstructionList[] splitLoading(ConstantPoolGen cpg, InstructionList src, Type[] argumentTypes) {
- int len = argumentTypes.length;
- InstructionList[] res = new InstructionList[len];
- // starting right _before_ an invoke instruction we loop backwards
- // to find those values on the stack that would be passed to the method.
- for (int idx = len-1; idx>=0; idx--) {
- // new sub-list:
- res[idx] = new InstructionList();
- // how many bytes to expect on the stack:
- int expectedArgSize = argumentTypes[idx].getSize();
- // loop until we have a sequence that produces the expected number of bytes:
- while (expectedArgSize > 0) {
- InstructionHandle loadH = src.getEnd();
- Instruction load = loadH.getInstruction();
- expectedArgSize -= stackDiff(load, cpg);
- try {
- // transfer instruction from src to res[roleIdx]:
- res[idx].insert(load);
- src.delete(loadH);
- } catch (TargetLostException e) {
- throw new OTREInternalError(e);
- }
- }
- }
- return res;
- }
-
- /**
- * Translate the parameter loading of a base call to the correct sequence
- * expected by the base chaining wrapper.
- * Treats tunneled arguments but not current enhancement args.
- * Tasks performed:
- * <ul>
- * <li>pick load sequences from <tt>splitLoad</tt>
- * <li>extract unused args from Object[]
- * <li>insert casting or lowering if needed.
- * </ul>
- * More documentation is found in document parameter-passing.odg.
- *
- * @param splitLoad one list of load instructions for each argument, ordered as found in the bytecode.
- * @param enhancedRoleArgumentTypes enhanced role arguments
- * @param enhancedBaseArgumentTypes arguments of the base chaining wrapper.
- * @param parameterPosition encoded parameter mappings.
- * @param teamName The name of the team containing the role class.
- * @param enclosingRoleName enclosing role class or null for static replace/base-call.
- * @param baseIsCallin is the base method a callin method?
- * @param baseIsStaticRoleMethod is the base method a static role method?
- * @param one byte for each parameter, signalling if lowering is required
- * @return a complete loading sequence for all source-level and tunneled arguments
- */
- protected InstructionList translateLoads(InstructionList[] splitLoad,
- Type[] enhancedRoleArgumentTypes,
- Type[] enhancedBaseArgumentTypes,
- int[] parameterPositions,
- String teamName,
- String enclosingRoleName,
- BaseMethodInfo baseMethod,
- int start,
- ConstantPoolGen cpg)
- {
- boolean isStatic = baseMethod.isStatic;
- boolean baseIsStaticRoleMethod = baseMethod.isStaticRoleMethod();
- boolean baseIsCallin = baseMethod.isCallin;
- int translationFlags = baseMethod.translationFlags;
-
- InstructionList il = new InstructionList();
-
- // index into "Object[] _OT$unusedArgs" (points to first arg that has not yet been consumed):
- int nextUnusedArg = 0;
- // index into enhancedBaseArgumentTypes:
- int baseIdx;
- // source-level version of baseIdx, i.e., ignoring any enhanced arguments:
- int baseSrcIdx;
- // index into roleArgumentTypes:
- int roleIdx;
- // source-level version of roleIdx, i.e., ignoring any enhanced arguments:
- int roleSrcIdx;
-
- // == Note: letters (u-x) below refer to document parameter-passing.odg. ==
- // Skip enhancements that are already loaded (given in start).
- for (baseIdx = start; baseIdx < enhancedBaseArgumentTypes.length; baseIdx++) {
- baseSrcIdx = baseIdx-start; // (u) skip first enhancement (already loaded)
- if (baseIsStaticRoleMethod)
- baseSrcIdx -= 2; // (v) not mapped but extracted from unusedArgs
- if (baseIsCallin)
- baseSrcIdx -= EXTRA_ARGS; // (w) not mapped but extracted from unusedArgs
-
- // value-dispatching: where to find this parameters?
- if (baseSrcIdx < 0) {
- // (v) or (w)
- roleSrcIdx = -1;
- } else {
- // (x) merge arguments from unused and real:
- int numAvailableRoleArgs = enhancedRoleArgumentTypes.length-EXTRA_ARGS;
- if (!isStatic && IS_COMPILER_GREATER_123)
- numAvailableRoleArgs--; // don't count isSuperAccess
- roleSrcIdx = getMappedRolePosition(baseSrcIdx, parameterPositions, numAvailableRoleArgs);
- }
-
- // got all information, fetch it now:
- Type baseArgumentType = enhancedBaseArgumentTypes[baseIdx];
- if (roleSrcIdx == -1) {
- // not mapped, retrieve from _OT$unusedArgs:
- retrieveFromUnusedArg(il, nextUnusedArg++, baseArgumentType, cpg);
- } else {
- // mapped, fetch from splitLoad:
- roleIdx = roleSrcIdx+EXTRA_ARGS; // role always has an additional set of enhancements
- if (IS_COMPILER_GREATER_123 && !isStatic) roleIdx++; // (+ isSuperAccess)
- Type roleArgumentType = enhancedRoleArgumentTypes[roleIdx];
- il.append(splitLoad[roleSrcIdx]);
- if (!roleArgumentType.equals(baseArgumentType)) {
- convertParamToBase(il, teamName, enclosingRoleName, roleArgumentType, baseArgumentType,
- (translationFlags & (2<<baseSrcIdx)) != 0);
- }
- }
- }
- if (il.isEmpty())
- il.append(new NOP()); // ensure caller receives at least one instruction handle (for line number)
- return il;
- }
-
- /* Is the base arg identified by 'baseIdx' mapped to a role parameter?
- * If so: which role position is it mapped to?
- * If not: return -1
- */
- private int getMappedRolePosition(int baseSrcIdx,
- int[] parameterPositions,
- int numAvailableRoleArgs)
- {
- if (parameterPositions == null) {
- if (baseSrcIdx < numAvailableRoleArgs) // as many as available ...
- return baseSrcIdx; // in original order.
- } else {
- // search parameter mapping:
- for (int i = 0; i < parameterPositions.length; i++) {
- if (parameterPositions[i] == baseSrcIdx+1) // positions are one-based (base side)
- return i;
- }
- }
- return -1;
- }
-
- /* Retrieve an unused (tunneled) argument from position 'unusedIdx' of the _OT$unusedArgs array. */
- private void retrieveFromUnusedArg(InstructionList il,
- int unusedIdx,
- Type baseArgumentType,
- ConstantPoolGen cpg)
- {
- il.append(InstructionFactory.createLoad(objectArray, /*this*/1 + (UNUSED_ARG-1))); // 'UNUSED_ARG' is one-based
- il.append(createIntegerPush(cpg, unusedIdx));
- il.append(InstructionFactory.createArrayLoad(objectArray));
- if (baseArgumentType instanceof BasicType)
- il.append(createUnboxing((BasicType) baseArgumentType));
- else // ObjectTypes just have to be re-casted
- il.append(factory.createCast(object, baseArgumentType));
- }
-
- /* May perform any of these conversions: casting, lowering, array-lowering.
- * Conversion is generated into 'il'.
- */
- private void convertParamToBase(InstructionList il,
- String teamName,
- String enclosingRoleName,
- Type roleArgumentType,
- Type baseArgumentType,
- boolean loweringFlag)
- {
- if (roleArgumentType instanceof ObjectType
- && baseArgumentType instanceof ObjectType)
- {
- if (loweringFlag) {
- lowerObject(il, teamName, roleArgumentType, baseArgumentType);
- } else {
- if(logging) printLogMessage("Try to cast " + roleArgumentType +
- " to " + baseArgumentType);
- il.append(factory.createCast(roleArgumentType,
- baseArgumentType));
- }
- } else
- if ( roleArgumentType instanceof BasicType
- && baseArgumentType instanceof ObjectType)
- {
- il.append(createBoxing((BasicType)roleArgumentType));
- } else
- if ( roleArgumentType instanceof ObjectType
- && baseArgumentType instanceof BasicType)
- {
- il.append(createUnboxing((BasicType)baseArgumentType));
- } else
- if ( roleArgumentType instanceof ArrayType
- && baseArgumentType instanceof ArrayType)
- {
- lowerArray(il, teamName, enclosingRoleName, roleArgumentType, baseArgumentType);
- } else {
- throw new OTREInternalError("OTRE internal error:"+
- "No way to make types conform\n"+
- "role type "+roleArgumentType+
- " -> "+baseArgumentType);
- }
- }
-
- /* Lower one object from roleArgumentType to baseArgumentType. */
- private void lowerObject(InstructionList il,
- String teamName,
- Type roleArgumentType,
- Type baseArgumentType)
- {
- String roleIfcName = ((ObjectType)roleArgumentType).getClassName();
- // use interface implementing role type for base-field access!
- String roleClassName = ObjectTeamsTransformation.genImplementingRoleName(roleIfcName);
-
- int dollarIdx = roleClassName.lastIndexOf('$');
- if (dollarIdx == -1) {
- throw new OTREInternalError("OTRE internal error:" +
- "No way to make types conform\n" +
- "role type " + roleArgumentType +
- " -> " + baseArgumentType);
- }
- boolean isNested = dollarIdx != roleClassName.indexOf('$'); // is last == first?
- String strengthenedRoleName = teamName + roleClassName.substring(dollarIdx);
-
- // baseArgumentType may be imprecise due to cast in param mapping,
- // try a RBB instead to find the exact base type
- RoleBaseBinding rbb = CallinBindingManager.getRoleBaseBinding(strengthenedRoleName);
- if (rbb != null)
- baseArgumentType = new ObjectType(rbb.getBaseClassName());
-
- if (isNested) {
- // cannot use field access here, because role strengthening would require resolved information
- // so use the _OT$getBase() method instead:
- short kind = (roleIfcName.lastIndexOf('$') == roleIfcName.lastIndexOf("$__OT__")) // last segment is roleclass?
- ? Constants.INVOKEVIRTUAL
- : Constants.INVOKEINTERFACE;
- il.append(factory.createInvoke(roleIfcName, GET_BASE, baseArgumentType, new Type[0], kind));
- } else {
- // access field via the role class:
- il.append(factory.createCast(roleArgumentType, new ObjectType(strengthenedRoleName)));
-
- // optimized version directly accessing the field:
- il.append(factory.createGetField(strengthenedRoleName,
- BASE,
- baseArgumentType));
- }
- }
-
- /* Lower from roleArgumentType[] to baseArgumentType[]. */
- private void lowerArray(InstructionList il, String teamName, String enclosingRoleName, Type roleArgumentType, Type baseArgumentType) {
- ArrayType array = (ArrayType)roleArgumentType;
- String roleName =((ObjectType)array.getElementType()).getClassName();
- int dollarIdx = roleName.lastIndexOf('$');
- String pureRoleName = roleName.substring(dollarIdx + 1);
- String transformMethodName = getArrayLoweringMethodName(pureRoleName, array.getDimensions());
- if (enclosingRoleName != null) {
- // fetch team from enclosing role:
- il.append(InstructionFactory.createThis());
- // FIXME(SH): is this$0 always correct (nesting!)??
- il.append(factory.createGetField(enclosingRoleName, "this$0", new ObjectType(teamName)));
- } else {
- // "this" is the team:
- il.append(InstructionFactory.createThis());
- }
- il.append(new SWAP()); // 'push' team instance below the role array
- il.append(factory.createInvoke(teamName,
- transformMethodName,
- baseArgumentType,
- new Type[]{roleArgumentType},
- Constants.INVOKEVIRTUAL));
- }
-
- private String getArrayLoweringMethodName(String roleName, int dimensions) {
- return "_OT$transformArray" + roleName + "_OT$" + dimensions;
- }
-
- public List<String> getInnerClassNames(ClassGen cg, ConstantPoolGen cpg) {
- Attribute[] attributes = cg.getAttributes();
- LinkedList<String> innerClassNames = new LinkedList<String>();
- for (int i = 0; i < attributes.length; i++) {
- Attribute actAttr = attributes[i];
- if (actAttr instanceof InnerClasses) {
- InnerClass[] inners = ((InnerClasses)actAttr).getInnerClasses();
- for (int j=0; j<inners.length; j++) {
- int name_index = inners[j].getInnerNameIndex();
- Constant name_c = cpg.getConstant(name_index);
- String name = ((ConstantUtf8)name_c).getBytes();
- innerClassNames.add(name);
- }
- }
- }
- return innerClassNames;
- }
-
- /**
- * Create a monitor enter using a class literal
- * @param mg target method to which a local variable is added which holds the monitor object
- * @param il instruction list to append to
- * @param class_name name of the class literal to use as monitor
- * @param major major class file version, used to determine how to translate class literals
- * @param cpg constant pool gen
- * @return the slot index of the monitor local variable and the handle of the first generated instruction.
- */
- protected Pair<Integer,InstructionHandle> addClassMonitorEnter(MethodGen mg,
- InstructionList il,
- String class_name,
- int major,
- ConstantPoolGen cpg)
- {
- int monitor;
- InstructionHandle ih=
- appendClassLiteral(il, class_name, major, cpg);
- il.append(new DUP()); // for store and monitorenter
- LocalVariableGen lg2=
- mg.addLocalVariable("monitor", Type.OBJECT, il.getStart(), null); //$NON-NLS-1$
- monitor= lg2.getIndex();
- il.append(InstructionFactory.createStore(Type.OBJECT, monitor)); // for use by monitorexit
- il.append(new MONITORENTER());
- return new Pair<Integer, InstructionHandle>(monitor, ih);
- }
-
- /**
- * Append an instruction sequence for loading the class literal for `class_name'.
- * @param il instruction list to append to
- * @param class_name class name of the class literal
- * @param major java version as stored in the byte code.
- * @param cpg for generating bytes
- * @return the handle of the first instruction of the sequence.
- */
- protected InstructionHandle appendClassLiteral(InstructionList il,
- String class_name,
- int major,
- ConstantPoolGen cpg)
- {
- if (major >= 49) // java 5
- return il.append(new LDC(cpg.addClass(new ObjectType(class_name))));
- // pre java 5, do it the hard way:
- // if (_OT$self_class$ != null)
- InstructionHandle start=
- il.append(factory.createFieldAccess(class_name, OTConstants.SELF_CLASS, classType, Constants.GETSTATIC));
- il.append(new DUP()); // keep a copy as a potential result
- BranchInstruction checkLoaded=
- InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
- il.append(checkLoaded);
- il.append(new POP()); // discard null from above
- // _OT$self_class$= Class.forName(<class_name>); // never fails, it is THIS class
- il.append(new LDC(cpg.addString(class_name)));
- il.append(factory.createInvoke("java.lang.Class",
- "forName",
- classType,
- new Type[]{new ObjectType("java.lang.String")},
- Constants.INVOKESTATIC));
- il.append(new DUP()); // keep a copy as the result
- il.append(factory.createFieldAccess(class_name, OTConstants.SELF_CLASS, classType, Constants.PUTSTATIC));
-
- checkLoaded.setTarget(il.append(new NOP()));
- return start;
- }
-
- @SuppressWarnings("unchecked")
- public static void insertBeforeReturn(MethodGen mg, InstructionList il, InstructionList insertion) {
- // InstructionFinder is broken see https://issues.apache.org/bugzilla/show_bug.cgi?id=40044
- // which is fixed in r516724 (2007-03-10) but latest release bcel 5.2 is 6. June 2006.
-// Iterator<InstructionHandle[]> ihIt = new InstructionFinder(il).search("ReturnInstruction");
-// while (ihIt.hasNext()) {
-// InstructionHandle[] ihAr = ihIt.next();
-// InstructionList insertionCopy = insertion.copy();
-// if (debugging)
-// mg.addLineNumber(insertionCopy.getStart(), STEP_OVER_LINENUMBER);
-// InstructionHandle inserted = il.insert(ihAr[0], insertionCopy); // instruction lists can not be reused
-// il.redirectBranches(ihAr[0], inserted);// SH: retarget all jumps that targeted at the return instruction
-// }
- Iterator<InstructionHandle>ihIt = il.iterator();
- while (ihIt.hasNext()) {
- InstructionHandle ihAr = ihIt.next();
- if (!(ihAr.getInstruction() instanceof ReturnInstruction))
- continue;
- InstructionList insertionCopy = insertion.copy();
- if (debugging)
- mg.addLineNumber(insertionCopy.getStart(), STEP_OVER_LINENUMBER);
- InstructionHandle inserted = il.insert(ihAr, insertionCopy); // instruction lists can not be reused
- il.redirectBranches(ihAr, inserted);// SH: retarget all jumps that targeted at the return instruction
- }
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/RepositoryAccess.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/RepositoryAccess.java
deleted file mode 100644
index 4a249262d..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/RepositoryAccess.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- *
- * Copyright 2010 Stephan Herrmann
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id$
- *
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- *
- * Contributors:
- * Stephan Herrmann - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import java.util.HashMap;
-
-import org.apache.bcel.Repository;
-import org.apache.bcel.classfile.JavaClass;
-import org.apache.bcel.generic.ObjectType;
-import org.apache.bcel.util.ClassLoaderRepository;
-
-/**
- * Provides a classloader aware access to one or more class repositories.
- * All access methods are static, but context is passed by setting a per-thread
- * current repository using {@link #setClassLoader(ClassLoader)}.
- * @since 0.7.0
- */
-public class RepositoryAccess {
-
- /** One class repository per class loader. */
- private static HashMap<ClassLoader,ClassLoaderRepository> repositories = new HashMap<ClassLoader,ClassLoaderRepository>();
- /** One current repository per thread. */
- private static ThreadLocal<ClassLoaderRepository> currentRepository = new ThreadLocal<ClassLoaderRepository>();
-
- /**
- * Setup a repository for the given class loader and make it the current repository for the current thread.
- * @param loader class loader, may be null
- * @return the previously active class repository for this thread
- */
- public static synchronized ClassLoaderRepository setClassLoader(ClassLoader loader) {
- ClassLoaderRepository clr = null;
- if (loader != null) { // avoid creating ClassLoaderRepository with null loader
- clr = repositories.get(loader);
- if (clr == null)
- repositories.put(loader, clr = new ClassLoaderRepository(loader));
- }
- ClassLoaderRepository prev = currentRepository.get();
- currentRepository.set(clr);
- return prev;
- }
-
- /** Reset the class repository for the current thread. */
- public static synchronized void resetRepository(ClassLoaderRepository repository) {
- currentRepository.set(repository);
- }
-
- public static JavaClass lookupClass(String className)
- throws ClassNotFoundException
- {
- ClassLoaderRepository clr = currentRepository.get();
- if (clr != null)
- return clr.loadClass(className);
- return Repository.lookupClass(className);
- }
-
- public static JavaClass[] getSuperClasses(String className)
- throws ClassNotFoundException
- {
- ClassLoaderRepository clr = currentRepository.get();
- JavaClass jc;
- if (clr != null)
- jc = clr.loadClass(className);
- else
- jc = Repository.lookupClass(className);
- return jc.getSuperClasses();
- }
-
- public static boolean implementationOf(String className, String ifcName)
- throws ClassNotFoundException
- {
- ClassLoaderRepository clr = currentRepository.get();
- JavaClass jc, ifc;
- if (clr != null) {
- jc = clr.loadClass(className);
- ifc= clr.loadClass(ifcName);
- } else {
- jc = Repository.lookupClass(className);
- ifc= Repository.lookupClass(ifcName);
- }
- return jc.implementationOf(ifc);
- }
-
- public static boolean safeSubclassOf(ObjectType subClass, ObjectType superClass) {
- try {
- String subClassName = subClass.getClassName();
- String superClassName = superClass.getClassName();
- return instanceOf(subClassName, superClassName);
- } catch (ClassNotFoundException e) {
- // consider classes as incommensurable if they can't both be loaded in the current class loader
- return false;
- } catch (ClassCircularityError e) {
- // assume that circularity was caused by resolving framework classes during class loading
- return false;
- }
- }
-
- protected static boolean instanceOf(String subClassName, String superClassName)
- throws ClassNotFoundException
- {
- ClassLoaderRepository clr = currentRepository.get();
- JavaClass subJClass, superJClass;
- if (clr != null) {
- subJClass = clr.loadClass(subClassName);
- superJClass= clr.loadClass(superClassName);
- } else {
- subJClass = Repository.lookupClass(subClassName);
- superJClass= Repository.lookupClass(superClassName);
- }
- return subJClass.instanceOf(superJClass);
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java
deleted file mode 100644
index 5e5844f04..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: StaticSliceBaseTransformation.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import org.apache.bcel.classfile.*;
-import org.apache.bcel.generic.*;
-import org.apache.bcel.*;
-
-import org.eclipse.objectteams.otre.util.*;
-
-
-/**
- * Adds to base classes with callin bindings what can be literally pasted in:
- *
- * Fields:
- * protected static Team[] _OT$activeTeams;
- * protected static int[] _OT$activeTeamIDs;
- * Methods:
- * public static void _OT$addTeam(Team team, in team_id)
- * public static void _OT$removeTeam(Team team)
- * Static initialization (adds clinit method, if not yet presented):
- * _OT$activeTeams = new Team[0];
- * _OT$activeTeamIDs = new int[0];
- *
- *
- * @version $Id: StaticSliceBaseTransformation.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-public class StaticSliceBaseTransformation
- extends ObjectTeamsTransformation
-{
- static final String _OT_ACTIVE_TEAMS= "_OT$activeTeams"; //$NON-NLS-1$
- static final String _OT_ACTIVE_TEAM_IDS= "_OT$activeTeamIDs"; //$NON-NLS-1$
-
- public StaticSliceBaseTransformation(ClassLoader loader, SharedState state) { super(loader, state); }
-
- public void doTransformCode(ClassGen cg) {
- if (cg.isInterface())
- return; // can't add implementation
- // IMPLICIT_INHERITANCE
-
- String class_name = cg.getClassName();
- if (!CallinBindingManager.isBoundBaseClass(class_name)
- /*&& !CallinBindingManager.containsBoundBaseInterface(cg.getInterfaceNames())*/)
- return; //only (base-)classes with callin bindings need this addition
- /*// this only works if teams are only added at the root bound base class
- if (CallinBindingManager.isBoundBaseClass(cg.getSuperclassName()))
- continue; // team infrastructur already added by super class
- */
- if (CallinBindingManager.hasBoundBaseParent(class_name))
- return; // team infrastructure already has been added to a super class
-
- ConstantPoolGen cpg = cg.getConstantPool();
- factory = new InstructionFactory(cpg);
- addStaticInitializations(cg, cpg);
- }
-
- /**
- * @param ce
- * @param cg
- */
- public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
- String class_name = cg.getClassName();
- ConstantPoolGen cpg = cg.getConstantPool();
-
- checkReadClassAttributes(ce, cg, class_name, cpg);
-
- if (cg.isInterface())
- return; // can't add implementation
- if (state.interfaceTransformedClasses.contains(class_name))
- return; // class has already been transformed by this transformer
- // IMPLICIT_INHERITANCE
- if (!CallinBindingManager.isBoundBaseClass(class_name)
- /*&& !CallinBindingManager.containsBoundBaseInterface(cg.getInterfaceNames())*/)
- return; //only (base-)classes with callin bindings need this addition
- /*// this only works if teams are only added at the root bound base class
- if (CallinBindingManager.isBoundBaseClass(cg.getSuperclassName()))
- continue; // team infrastructur already added by super class
- */
- if (CallinBindingManager.hasBoundBaseParent(class_name))
- return; // team infrastructure already has been added to a super class
- if(logging) printLogMessage("StaticSliceBaseTransformer transforms "+ class_name);
-
- if(CallinBindingManager.isRole(class_name)) {
- addImplicitSubclassNotificationInfrastructure(ce, cg);
- }
-
- // addition of the fields '_OT$activeTeams' and '_OT$activeTeamIDs':
- int accessFlags = Constants.ACC_PROTECTED | Constants.ACC_STATIC;
-
- FieldGen activeTeamsField = new FieldGen(accessFlags, teamArray, _OT_ACTIVE_TEAMS, cpg);
- ce.addField(activeTeamsField.getField(), cg);
- // generated global variable: protected static Team[] _OT$activeTeams;
-
- FieldGen activeTeamIDsField = new FieldGen(accessFlags, intArray, _OT_ACTIVE_TEAM_IDS, cpg);
- ce.addField(activeTeamIDsField.getField(), cg);
- // generated global variable: protected static int[] _OT$activeTeamIDs;
-
- factory = new InstructionFactory(cpg);
-
- // implementation of method '_OT$addTeam'
- ce.addMethod(genAddTeam(class_name, cg.getMajor(), cpg).getMethod(), cg);
-
- // implementation of method '_OT$removeTeam':
- ce.addMethod(genRemoveTeam(class_name, cg.getMajor(), cpg).getMethod(), cg);
-
- // implementation of the static class initialization method '<clinit>':
- /* Adding static initializations requires the addition of the clinit method, if not yet presented.
- * This requires synchronization with other transformers (TeamInterfaceImplementer)
- * which may do the same this. This is done via 'TeamIdDispenser.clinitAdded(class_name)'.
- */
- Method clinit = cg.containsMethod(Constants.STATIC_INITIALIZER_NAME, "()V");
-
- if (clinit != null || TeamIdDispenser.clinitAdded(class_name, loader)) {
- // the clinit-Method only has to be extended by the code transformation of this transformer
- state.interfaceTransformedClasses.add(class_name);
- return;
- }
-
- InstructionList il = new InstructionList();
- MethodGen clinitMethod = new MethodGen(Constants.ACC_STATIC,
- Type.VOID,
- Type.NO_ARGS,
- new String[] { },
- Constants.STATIC_INITIALIZER_NAME, class_name,
- il, cpg);
-
- il.append(InstructionFactory.createReturn(Type.VOID));
-
- clinitMethod.setMaxStack();
- clinitMethod.setMaxLocals();
-
- ce.addMethod(clinitMethod.getMethod(), cg);
-
-/***********************************************************************************************************/
- il.dispose();
- state.interfaceTransformedClasses.add(class_name);
- }
-
- /* Code to be generated:
- public static void _OT$addTeam(Team team, int teamID)
- {
- int l;
- // Second part of the "if" below: Avoid duplicate entry of the same team.
- // Assumption (see r17473): this strategy assumes that a team instance
- // can only be duplicated directly after the first registration.
- // Reason: registerAtBases() calling addTeam() for multiple sub-bases
- // which share the same _OT$activateTeams et al fields from a common super-base.
- if((l = _OT$activeTeams.length) != 0 && _OT$activeTeams[0] == team)
- {
- return;
- } else
- {
- Team newTeams[] = new Team[l + 1];
- int newTeamIDs[] = new int[l + 1];
- System.arraycopy(_OT$activeTeams, 0, newTeams, 1, l);
- System.arraycopy(_OT$activeTeamIDs, 0, newTeamIDs, 1, l);
- _OT$activeTeams = newTeams;
- _OT$activeTeamIDs = newTeamIDs;
- _OT$activeTeams[0] = team;
- _OT$activeTeamIDs[0] = teamID;
- return;
- }
- }
- */
- private MethodGen genAddTeam(String class_name, int major, ConstantPoolGen cpg) {
- LocalVariableGen lg;
- InstructionList il;
- il = new InstructionList();
- MethodGen addTeamMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNCHRONIZED,
- Type.VOID,
- new Type[] { teamType, Type.INT },
- new String[] { "team", "teamID" },
- "_OT$addTeam", class_name,
- il, cpg);
- // synchronized (BaseClass.class) {
- int monitor = addClassMonitorEnter(addTeamMethod, il, class_name, major, cpg).first;
-
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(new ARRAYLENGTH());
- lg = addTeamMethod.addLocalVariable("l", Type.INT, null, null);
- int l = lg.getIndex();
- il.append(new DUP());
- lg.setStart(il.append(InstructionFactory.createStore(Type.INT, l)));
- // generated: int l = _OT$activeTeams.length;
-
- // add duplication check:
- BranchHandle emptyArray =
- il.append(new IFEQ(null));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(new ICONST(0));
- il.append(InstructionFactory.createArrayLoad(teamType));
- il.append(new ALOAD(0));
- BranchHandle noDuplication =
- il.append(new IF_ACMPNE(null));
- GOTO earlyExit = new GOTO(null);
- il.append(earlyExit);
- InstructionHandle skipReturn = il.append(new NOP());
- emptyArray.setTarget(skipReturn);
- noDuplication.setTarget(skipReturn);
- // generated: if (l > 0 && _OT$activeTeams[0] == team ) return;
-
- lg = addTeamMethod.addLocalVariable("newTeams", teamArray, null, null);
- int newTeams = lg.getIndex();
- il.append(InstructionFactory.createLoad(Type.INT, l));
- il.append(new ICONST(1));
- il.append(new IADD());
- il.append((Instruction)factory.createNewArray(teamType, (short)1));
- //this are very strange (but necessary!?) casts...
- lg.setStart(il.append(InstructionFactory.createStore(teamArray, newTeams)));
- // generated: Team[] newTeams = new Team[l+1];
-
- lg = addTeamMethod.addLocalVariable("newTeamIDs", intArray, null, null);
- int newTeamIDs = lg.getIndex();
- il.append(InstructionFactory.createLoad(Type.INT, l));
- il.append(new ICONST(1));
- il.append(new IADD());
- il.append((Instruction)factory.createNewArray(Type.INT, (short)1));
- //this are very strange (but necessary!?) casts...
- lg.setStart(il.append(InstructionFactory.createStore(intArray, newTeamIDs)));
- // generated: int[] newTeamIDs = new int[l+1];
-
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(new ICONST(0));
- il.append(InstructionFactory.createLoad(teamArray, newTeams));
- il.append(new ICONST(1));
- il.append(InstructionFactory.createLoad(Type.INT, l));
- ObjectType object = new ObjectType("java.lang.Object");
- il.append(factory.createInvoke("java.lang.System", "arraycopy",
- Type.VOID,
- new Type[] {object, Type.INT, object, Type.INT, Type.INT },
- Constants.INVOKESTATIC));
- // generated: System.arraycopy(_OT$activeTeams, 0, newTeams, 1, l);
-
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
- il.append(new ICONST(0));
- il.append(InstructionFactory.createLoad(intArray, newTeamIDs));
- il.append(new ICONST(1));
- il.append(InstructionFactory.createLoad(Type.INT, l));
- il.append(factory.createInvoke("java.lang.System", "arraycopy",
- Type.VOID,
- new Type[] {object, Type.INT, object, Type.INT, Type.INT },
- Constants.INVOKESTATIC));
- // generated: System.arraycopy(_OT$activeTeamIDs, 0, newTeamIDs, 1, l);
-
- il.append(InstructionFactory.createLoad(teamArray, newTeams));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.PUTSTATIC));
- // generated: _OT$activeTeams = newTeams;
-
- il.append(InstructionFactory.createLoad(intArray, newTeamIDs));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.PUTSTATIC));
- // generated: _OT$activeTeamIDs = newTeamIDs;
-
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(new ICONST(0));
- il.append(new ALOAD(0));
- il.append(InstructionFactory.createArrayStore(teamType));
- // generated: _OT$activeTeams[0] = team;
-
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
- il.append(new ICONST(0));
- il.append(new ILOAD(1));
- il.append(InstructionFactory.createArrayStore(Type.INT));
- // generated: _OT$activeTeamIDs[0] = teamID;
-
- if (CallinBindingManager.isRole(class_name)) {
- il.append(new ALOAD(0));
- il.append(new ILOAD(1));
- il.append(factory.createInvoke(class_name, "_OT$activateNotify", Type.VOID, new Type[] { teamType, Type.INT }, Constants.INVOKESTATIC));
- // generated: _OT$activateNotify(team, teamID);
- }
-
- // No more access to array fields, release monitor:
- InstructionHandle exitSequence =
- il.append(InstructionFactory.createLoad(Type.OBJECT, monitor));
- il.append(new MONITOREXIT());
- earlyExit.setTarget(exitSequence);
-
- il.append(InstructionFactory.createReturn(Type.VOID));
-
- addTeamMethod.setMaxStack();
- addTeamMethod.setMaxLocals();
- addTeamMethod.removeNOPs();
- return addTeamMethod;
- }
-
- /* Code to be generated:
- public static void _OT$removeTeam(Team team)
- {
- int l;
- if((l = _OT$activeTeams.length) == 0)
- return;
- boolean found = false;
- int newLen= l-1;
- Team newTeams[] = new Team[newLen];
- int newTeamIDs[] = new int[newLen];
- for(int i = 0; i < l; i++)
- if(!found)
- {
- if(_OT$activeTeams[i] == team)
- {
- found = true;
- } else if (i<newLen) { // coded as: jump if (newLen<=i)
- {
- newTeams[i] = _OT$activeTeams[i];
- newTeamIDs[i] = _OT$activeTeamIDs[i];
- }
- } else
- {
- newTeams[i - 1] = _OT$activeTeams[i];
- newTeamIDs[i - 1] = _OT$activeTeamIDs[i];
- }
-
- if(found)
- {
- _OT$activeTeams = newTeams;
- _OT$activeTeamIDs = newTeamIDs;
- }
- }
- */
- private MethodGen genRemoveTeam(String class_name, int major, ConstantPoolGen cpg)
- {
- LocalVariableGen lg;
- InstructionList il;
- int l;
- BranchHandle emptyArray;
- int newTeams;
- int newTeamIDs;
- il = new InstructionList();
- MethodGen removeTeamMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNCHRONIZED,
- Type.VOID,
- new Type[] { teamType },
- new String[] { "team" },
- "_OT$removeTeam", class_name,
- il, cpg);
-
- // synchronized (BaseClass.class) {
- int monitor = addClassMonitorEnter(removeTeamMethod, il, class_name, major, cpg).first;
-
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(new ARRAYLENGTH());
- lg = removeTeamMethod.addLocalVariable("l", Type.INT, null, null);
- //int l = lg.getIndex();
- l = lg.getIndex();
- il.append(new DUP());
- lg.setStart(il.append(InstructionFactory.createStore(Type.INT, l)));
- // generated: int l = _OT$activeTeams.length;
-
- emptyArray = il.append(new IFNE(null));
- GOTO earlyExit = new GOTO(null);
- il.append(earlyExit);
- emptyArray.setTarget(il.append(new NOP()));
- // generated: if (l == 0) return;
-
- lg = removeTeamMethod.addLocalVariable("found", Type.BOOLEAN, null, null);
- int found = lg.getIndex();
- il.append(new ICONST(0));
- lg.setStart(il.append(InstructionFactory.createStore(Type.BOOLEAN, found)));
- // generated: boolean found = false;
-
- lg = removeTeamMethod.addLocalVariable("newTeams", teamArray, null, null);
- newTeams = lg.getIndex();
- il.append(InstructionFactory.createLoad(Type.INT, l));
- // [SH]: variable newLen
- LocalVariableGen lgNewLen= removeTeamMethod.addLocalVariable("newLen", Type.INT, il.getEnd(), null);
- il.append(new ICONST(1));
- il.append(new ISUB());
- // [SH] store for later use:
- il.append(new DUP());
- il.append(InstructionFactory.createStore(Type.INT, lgNewLen.getIndex()));
- // [HS] generated: "newLen= l-1;"
- il.append((Instruction)factory.createNewArray(teamType, (short)1));
- lg.setStart(il.append(InstructionFactory.createStore(teamArray, newTeams)));
- // generated: Team[] newTeams = new Team[newLen];
-
- lg = removeTeamMethod.addLocalVariable("newTeamIDs", intArray, null, null);
- //int newTeamIDs = lg.getIndex();
- newTeamIDs = lg.getIndex();
- //[SH]:
- il.append(InstructionFactory.createLoad(Type.INT, lgNewLen.getIndex()));
- il.append((Instruction)factory.createNewArray(Type.INT, (short)1));
- lg.setStart(il.append(InstructionFactory.createStore(intArray, newTeamIDs)));
- // generated: int[] newTeamIDs = new int[newLen];
-
- // start for-loop
- lg = removeTeamMethod.addLocalVariable("i", Type.INT, null, null);
- int loopCounter = lg.getIndex();
- il.append(new ICONST(0));
- lg.setStart(il.append(InstructionFactory.createStore(Type.INT, loopCounter)));
- GOTO try_leave_loop = new GOTO(null);
- il.append(try_leave_loop);
- InstructionHandle i_lower_l = il.append(new NOP());
- // loop body:
- il.append(InstructionFactory.createLoad(Type.BOOLEAN, found));
- IFNE already_found = new IFNE(null);
- il.append(already_found);
-
- // outer if part:
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(new ILOAD(loopCounter));
- il.append(InstructionFactory.createArrayLoad(teamType));
- il.append(new ALOAD(0)); //first parameter
- IF_ACMPNE teams_not_equal = new IF_ACMPNE(null);
- il.append(teams_not_equal);
-
- // inner if part:
- il.append(new ICONST(1));
- il.append(InstructionFactory.createStore(Type.BOOLEAN, found));
- GOTO skip_outer_else_part = new GOTO(null);
- il.append(skip_outer_else_part);
-
- // inner else part:
- teams_not_equal.setTarget(il.append(new NOP()));
-
- // [SH] sanity check:
- il.append(InstructionFactory.createLoad(Type.INT, lgNewLen.getIndex()));
- il.append(new ILOAD(loopCounter));
- IF_ICMPLE if_len_le_i= new IF_ICMPLE(null);
- il.append(if_len_le_i);
- // [HS] generated: else if (!(newLen <= i)) {
- il.append(new ALOAD(newTeams));
- il.append(new ILOAD(loopCounter));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(new ILOAD(loopCounter));
- il.append(InstructionFactory.createArrayLoad(teamType));
- il.append(new AASTORE());
- // generated: newTeams[i] = _OT$activeTeams[i];
-
- il.append(new ALOAD(newTeamIDs));
- il.append(new ILOAD(loopCounter));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
- il.append(new ILOAD(loopCounter));
- il.append(InstructionFactory.createArrayLoad(Type.INT));
- il.append(new IASTORE());
- // generated: newTeamIDs[i] = _OT$activeTeamIDs[i];
-
- GOTO end_of_loop = new GOTO(null);
- il.append(end_of_loop);
-
- // outer else part:
- already_found.setTarget(il.append(new NOP()));
- il.append(new ALOAD(newTeams));
- il.append(new ILOAD(loopCounter));
- il.append(new ICONST(1));
- il.append(new ISUB());
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
- il.append(new ILOAD(loopCounter));
- il.append(InstructionFactory.createArrayLoad(teamType));
- il.append(new AASTORE());
- // generated: newTeams[i-1] = _OT$activeTeams[i];
-
- il.append(new ALOAD(newTeamIDs));
- il.append(new ILOAD(loopCounter));
- il.append(new ICONST(1));
- il.append(new ISUB());
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
- il.append(new ILOAD(loopCounter));
- il.append(InstructionFactory.createArrayLoad(Type.INT));
- il.append(new IASTORE());
- // generated: newTeamIDs[i-1] = _OT$activeTeamIDs[i];
-
- skip_outer_else_part.setTarget(il.append(new NOP()));
- // [SH] connect "else if" from above:
- if_len_le_i.setTarget(il.getEnd());
- end_of_loop.setTarget(il.append(new IINC(loopCounter, 1)));
- try_leave_loop.setTarget(il.append(InstructionFactory.createLoad(Type.INT, loopCounter)));
- il.append(new ILOAD(l));
- il.append(new IF_ICMPLT(i_lower_l));
- // end for-loop
-
- il.append(InstructionFactory.createLoad(Type.BOOLEAN, found));
- BranchHandle notFound = il.append(new IFEQ(null));
- // generated: if (found) {
-
- il.append(InstructionFactory.createLoad(teamArray, newTeams));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.PUTSTATIC));
- // generated: _OT$activeTeams = newTeams;
-
- il.append(InstructionFactory.createLoad(intArray, newTeamIDs));
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.PUTSTATIC));
- // generated: _OT$activeTeamIDs = newTeamIDs;
-
- if (CallinBindingManager.isRole(class_name)) {
- il.append(new ALOAD(0));
- il.append(factory.createInvoke(class_name, "_OT$deactivateNotify", Type.VOID, new Type[] { teamType }, Constants.INVOKESTATIC));
- // generated: _OT$deactivateNotify(team);
- }
-
- // No more access to array fields, release monitor:
- InstructionHandle exitSequence =
- il.append(InstructionFactory.createLoad(Type.OBJECT, monitor));
- il.append(new MONITOREXIT());
- earlyExit.setTarget(exitSequence);
- notFound.setTarget(exitSequence);
-
- il.append(InstructionFactory.createReturn(Type.VOID));
-
- removeTeamMethod.setMaxStack();
- removeTeamMethod.setMaxLocals();
- removeTeamMethod.removeNOPs();
- return removeTeamMethod;
- }
-
- /**
- * Add infrastructure for implicit subclasses to register and be notified. This 'observer' mechanism
- * is necessary, because an implicit subclass does not inherit the addition/removal
- * of a team at the implicit superclass.
- * @param ce The ClassEnhancer object to add methods and fields.
- * @param cg The ClassGen object representing the current class.
- */
- private void addImplicitSubclassNotificationInfrastructure(ClassEnhancer ce, ClassGen cg) {
-
- ConstantPoolGen cpg = cg.getConstantPool();
- factory = new InstructionFactory(cpg);
- String class_name = cg.getClassName();
- ObjectType linkedListType = new ObjectType("java.util.LinkedList");
- int accessFlags = Constants.ACC_PROTECTED | Constants.ACC_STATIC;
- FieldGen teamRegistrationObserversField = new FieldGen(accessFlags, linkedListType, "_OT$teamRegistrationObservers", cpg);
- ce.addField(teamRegistrationObserversField.getField(), cg);
-
-/***********************************************************************************************************/
-
- InstructionList il = new InstructionList();
-
- MethodGen observerRegistrationMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
- Type.VOID,
- new Type[] { classType },
- new String[] { "implicitSubClass" },
- "_OT$registerObserver", class_name,
- il, cpg);
-
- il.append(factory.createFieldAccess(class_name, "_OT$teamRegistrationObservers", linkedListType, Constants.GETSTATIC));
- il.append(InstructionFactory.createLoad(classType, 0));
- il.append(factory.createInvoke("java.util.LinkedList", "add", Type.BOOLEAN, new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL));
- il.append(new POP());
- il.append(new RETURN());
-
- observerRegistrationMethod.setMaxStack(2);
- observerRegistrationMethod.setMaxLocals();
-
- ce.addMethod(observerRegistrationMethod.getMethod(), cg);
-/***********************************************************************************************************/
- il = new InstructionList();
-
- MethodGen activateNotifyMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
- Type.VOID,
- new Type[] { teamType, Type.INT },
- new String[] { "team", "teamID" },
- "_OT$activateNotify", class_name,
- il, cpg);
-
- createNotifyMethodImplementation(activateNotifyMethod, cpg, class_name);
-
- ce.addMethod(activateNotifyMethod.getMethod(), cg);
-/***********************************************************************************************************/
- il = new InstructionList();
-
- MethodGen deactivateNotifyMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
- Type.VOID,
- new Type[] { teamType },
- new String[] { "team" },
- "_OT$deactivateNotify", class_name,
- il, cpg);
- createNotifyMethodImplementation(deactivateNotifyMethod, cpg, class_name);
-
- ce.addMethod(deactivateNotifyMethod.getMethod(), cg);
- }
-
-
- /**
- * Create implementation of methods '_OT$activateNotify' and _OT$deactivateNotify'.
- * @param notifyMethod Method which has to be implemented.
- * @param cpg Corresponding constant pool.
- * @param class_name Name of the class for wich to implement the method.
- */
- private void createNotifyMethodImplementation(MethodGen notifyMethod, ConstantPoolGen cpg, String class_name) {
- boolean isActivateMethod = notifyMethod.getName().equals("_OT$activateNotify");
-// int methodArgs = isActivateMethod ? 2 : 1;
-
- int iteratorIdx = isActivateMethod ? 2 : 1;
- int curClassIdx = isActivateMethod ? 3 : 2;
- int anotherIdx1 = isActivateMethod ? 4 : 3;
- int anotherIdx2 = isActivateMethod ? 5 : 4;
- String methodToInvoke = isActivateMethod ? "_OT$addTeam" : "_OT$removeTeam";
-
- InstructionList il = notifyMethod.getInstructionList();
- il.append(factory.createFieldAccess(class_name, "_OT$teamRegistrationObservers", new ObjectType("java.util.LinkedList"), Constants.GETSTATIC));
- BranchInstruction ifnonnull_3 = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
- il.append(ifnonnull_3);
- il.append(InstructionFactory.createReturn(Type.VOID));
- InstructionHandle ih_7 = il.append(factory.createFieldAccess(class_name, "_OT$teamRegistrationObservers", new ObjectType("java.util.LinkedList"), Constants.GETSTATIC));
- il.append(factory.createInvoke("java.util.LinkedList", "iterator", new ObjectType("java.util.Iterator"), Type.NO_ARGS, Constants.INVOKEVIRTUAL));
- il.append(InstructionFactory.createStore(Type.OBJECT,iteratorIdx));
- InstructionHandle ih_14 = il.append(InstructionFactory.createLoad(Type.OBJECT,iteratorIdx));
- il.append(factory.createInvoke("java.util.Iterator", "hasNext", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEINTERFACE));
- BranchInstruction ifeq_20 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
- il.append(ifeq_20);
- il.append(InstructionFactory.createLoad(Type.OBJECT,iteratorIdx));
- il.append(factory.createInvoke("java.util.Iterator", "next", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEINTERFACE));
- il.append(factory.createCheckCast(classType));
- il.append(InstructionFactory.createStore(Type.OBJECT,curClassIdx));
- il.append(InstructionConstants.ACONST_NULL);
- il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx1));
- InstructionHandle ih_36 = il.append(InstructionFactory.createLoad(Type.OBJECT,curClassIdx));
- il.append(new PUSH(cpg, methodToInvoke));
- il.append(new PUSH(cpg,iteratorIdx));
- il.append((Instruction)factory.createNewArray(classType, (short) 1));
- il.append(InstructionConstants.DUP);
-
- il.append(new PUSH(cpg, 0));
- il.append(new PUSH(cpg, OTConstants.teamName));
- il.append(factory.createInvoke("java.lang.Class", "forName",
- classType, new Type[] { Type.STRING },
- Constants.INVOKESTATIC));
-
- il.append(InstructionConstants.AASTORE);
- if (isActivateMethod){ // add the integer argument:
- il.append(InstructionConstants.DUP);
- il.append(new PUSH(cpg, 1));
- il.append(factory.createFieldAccess("java.lang.Integer", "TYPE", classType, Constants.GETSTATIC));
- il.append(InstructionConstants.AASTORE);
- }
- il.append(factory.createInvoke("java.lang.Class", "getMethod", new ObjectType("java.lang.reflect.Method"), new Type[] { Type.STRING, new ArrayType(classType, 1) }, Constants.INVOKEVIRTUAL));
- InstructionHandle ih_76 = il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx1));
- BranchInstruction goto_78 = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
- il.append(goto_78);
- InstructionHandle ih_81 = il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx2));
- il.append(factory.createFieldAccess("java.lang.System", "err", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
- il.append(new PUSH(cpg, "activateNotifyMethod not found!"));
- il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
- InstructionHandle ih_91 = il.append(InstructionFactory.createLoad(Type.OBJECT,anotherIdx1));
- BranchInstruction ifnull_93 = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
- il.append(ifnull_93);
- il.append(InstructionFactory.createLoad(Type.OBJECT,anotherIdx1));
- il.append(InstructionConstants.ACONST_NULL);
- il.append(new PUSH(cpg,iteratorIdx));
- il.append((Instruction)factory.createNewArray(Type.OBJECT, (short) 1));
- il.append(InstructionConstants.DUP);
- il.append(new PUSH(cpg, 0));
- il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
- il.append(InstructionConstants.AASTORE);
-
- if (isActivateMethod) { // load the integer argument:
- il.append(InstructionConstants.DUP);
- il.append(new PUSH(cpg, 1));
- il.append(factory.createNew("java.lang.Integer"));
- il.append(InstructionConstants.DUP);
- il.append(InstructionFactory.createLoad(Type.INT, 1));
- il.append(factory.createInvoke("java.lang.Integer", Constants.CONSTRUCTOR_NAME, Type.VOID, new Type[] { Type.INT }, Constants.INVOKESPECIAL));
- il.append(InstructionConstants.AASTORE);
- }
- il.append(factory.createInvoke("java.lang.reflect.Method", "invoke", Type.OBJECT, new Type[] { Type.OBJECT, new ArrayType(Type.OBJECT, 1) }, Constants.INVOKEVIRTUAL));
- InstructionHandle ih_121 = il.append(InstructionConstants.POP);
- InstructionHandle ih_122;
- BranchInstruction goto_122 = InstructionFactory.createBranchInstruction(Constants.GOTO, ih_14);
- ih_122 = il.append(goto_122);
- InstructionHandle ih_125 = il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx2));
- il.append(factory.createFieldAccess("java.lang.System", "err", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
- il.append(new PUSH(cpg, "Can not call activateNotifyMethod!"));
- il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
- BranchInstruction goto_135 = InstructionFactory.createBranchInstruction(Constants.GOTO, ih_14);
- il.append(goto_135);
- InstructionHandle ih_138 = il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx2));
- il.append(factory.createFieldAccess("java.lang.System", "err", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
- il.append(new PUSH(cpg, "InvocationTargetException"));
- il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
- BranchInstruction goto_148 = InstructionFactory.createBranchInstruction(Constants.GOTO, ih_14);
- il.append(goto_148);
- InstructionHandle ih_151 = il.append(InstructionFactory.createReturn(Type.VOID));
- ifnonnull_3.setTarget(ih_7);
- ifeq_20.setTarget(ih_151);
- goto_78.setTarget(ih_91);
- ifnull_93.setTarget(ih_122);
- notifyMethod.addExceptionHandler(ih_36, ih_76, ih_81, new ObjectType("java.lang.NoSuchMethodException"));
- notifyMethod.addExceptionHandler(ih_91, ih_121, ih_125, new ObjectType("java.lang.IllegalAccessException"));
- notifyMethod.addExceptionHandler(ih_91, ih_121, ih_138, new ObjectType("java.lang.reflect.InvocationTargetException"));
-
- notifyMethod.setMaxStack();
- notifyMethod.setMaxLocals();
- }
-
- /**
- * Adds initialization of the team array and the team index array to the static initializer of this class.
- * If this base class is a role at the same time, then also add initialization of the observer list.
- * @param cg The representation of the class.
- * @param cpg The constant pool of the class.
- */
- private void addStaticInitializations(ClassGen cg, ConstantPoolGen cpg) {
- Method clinitMethod = cg.containsMethod(Constants.STATIC_INITIALIZER_NAME, "()V");
- /* The clinit method always exists at this moment, because it has been added
- * by the interface transformer part of this transformer if necessary.
- */
- MethodGen mg = newMethodGen(clinitMethod, cg.getClassName(), cpg);
- InstructionList il = mg.getInstructionList();
- // add static initialization for added static fields at start of the <clinit> method:
- il.insert(inizializeStaticFields(cg.getClassName()));
- mg.setMaxStack();
- mg.setMaxLocals();
- Method newClinit = mg.getMethod();
- cg.replaceMethod(clinitMethod, newClinit);
- il.dispose();
- // Reuse instruction handles
- }
-
- /**
- * @param class_name
- * @return
- */
- private InstructionList inizializeStaticFields(String class_name) {
- // STATIC_PARTS_TODO : in base: static initialization of team fields
- InstructionList il = new InstructionList();
- il.append(new ICONST(0));
- il.append((Instruction)factory.createNewArray(teamType, (short)1));
- //this are very strange (but necessary!?) casts...
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.PUTSTATIC));
- //generated: _OT$activeTeams = new Team[0];
-
- il.append(new ICONST(0));
- il.append((Instruction)factory.createNewArray(Type.INT, (short)1));
- //this are very strange (but necessary!?) casts...
- il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.PUTSTATIC));
- //generated: _OT$activeTeamIDs = new int[0];
-
- if (CallinBindingManager.isRole(class_name)) {
- ObjectType linkedListType = new ObjectType("java.util.LinkedList");
- il.append(factory.createNew(linkedListType));
- il.append(new DUP());
- il.append(factory.createInvoke("java.util.LinkedList",
- Constants.CONSTRUCTOR_NAME,
- Type.VOID, Type.NO_ARGS,
- Constants.INVOKESPECIAL));
-
- il.append(factory.createFieldAccess(class_name,
- "_OT$teamRegistrationObservers",
- linkedListType, Constants.PUTSTATIC ));
-
- //generated: _OT$teamRegistrationObservers = new LinkedList();
- }
- return il;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java
deleted file mode 100644
index 1a0db28b4..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: SubBoundBaseMethodRedefinition.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import org.apache.bcel.classfile.*;
-import org.apache.bcel.generic.*;
-import org.apache.bcel.*;
-
-import java.util.*;
-
-import org.eclipse.objectteams.otre.util.*;
-
-/**
- * Redefines inherited (and not redefined) base methods in subclasses with a
- * call to the super method if they are bound for the subclass only. This is
- * done in order to provide a place for the BaseMethodTransformer to weave in
- * the callin code.
- *
- * @version $Id: SubBoundBaseMethodRedefinition.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-
-public class SubBoundBaseMethodRedefinition
- extends ObjectTeamsTransformation {
-
- public SubBoundBaseMethodRedefinition(ClassLoader loader, SharedState state) { super(loader, state); }
-
- /**
- * Main entry for this transformer.
- */
- public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
- String class_name = cg.getClassName();
- ConstantPoolGen cpg = cg.getConstantPool();
-
- factory = new InstructionFactory(cg);
-
- checkReadClassAttributes(ce, cg, class_name, cpg);
-
- // if class is already transformed by this transformer
- if (state.interfaceTransformedClasses.contains(class_name)) {
- return;
- }
-
- List<MethodBinding> mbsForClass = CallinBindingManager
- .getMethodBindingsForBaseClass(class_name);
- if (mbsForClass.isEmpty()) {
- return; // no bindings for this base class
- }
-
- List<MethodBinding> inheritedBoundMethods = getInheritedBoundMethods(mbsForClass, cg);
-
- addSubBoundMethodRedefinitions(inheritedBoundMethods, ce, cg);
- state.interfaceTransformedClasses.add(class_name);
- }
-
- /**
- * Adds redefinitions with calls to the super method to all methods
- * contained in the 'inheritedBoundMethods' list.
- *
- * @param inheritedBoundMethods
- * The list of method bindings for inherited methods.
- * @param ce
- * ClassEnhancer with the extension set of this class.
- * @param cg
- * The ClassGen object for the transformed class.
- */
- private void addSubBoundMethodRedefinitions(List<MethodBinding> inheritedBoundMethods,
- ClassEnhancer ce, ClassGen cg) {
- List<String> alreadyAddedRedefinitions = new LinkedList<String>();
-
- Iterator<MethodBinding> it = inheritedBoundMethods.iterator();
- while (it.hasNext()) {
- MethodBinding mb = it.next();
- String baseMethodKey = mb.getBaseMethodName() + "."
- + mb.getBaseMethodSignature();
-
- if (alreadyAddedRedefinitions.contains(baseMethodKey)) {
- continue;
- }
- Method m = genMethodRedefinition(mb, cg);
-
- ce.addMethod(m, cg);
- if(logging) printLogMessage("Added " + baseMethodKey + " to " + cg.getClassName());
- alreadyAddedRedefinitions.add(baseMethodKey);
- }
- }
-
- /**
- * Generates a (redefining) method, which just calls its super version.
- *
- * @param mb
- * A method binding containing the method to be redefined.
- * @param cg
- * The ClassGen object for the transformed class.
- * @return The generated method.
- */
- private Method genMethodRedefinition(MethodBinding mb, ClassGen cg) {
- boolean staticMethod = mb.hasStaticBaseMethod();
- short invocationKind = staticMethod ? Constants.INVOKESTATIC : Constants.INVOKESPECIAL;
-
- String methodName = mb.getBaseMethodName();
- String methodSignature = mb.getBaseMethodSignature();
- String className = mb.getBaseClassName();
- Type returnType = Type.getReturnType(methodSignature);
- Type[] argTypes = Type.getArgumentTypes(methodSignature);
- InstructionList il = new InstructionList();
-
- int accFlags = Constants.ACC_PUBLIC;
- if (staticMethod) {
- accFlags = accFlags | Constants.ACC_STATIC;
- }
- MethodGen redefinition = new MethodGen(accFlags, returnType, argTypes,
- null, methodName, className, il,
- cg.getConstantPool());
-
- if(!staticMethod){
- il.append(InstructionFactory.createThis());
- }
- // load all arguments:
- int index = 1;
- for (int i = 0; i < argTypes.length; i++) {
- il.append(InstructionFactory.createLoad(argTypes[i], index));
- index += argTypes[i].getSize();
- }
- il.append(factory.createInvoke(cg.getSuperclassName(), methodName,
- returnType, argTypes, invocationKind));
- il.append(InstructionFactory.createReturn(returnType));
-
- redefinition.removeNOPs();
- il.setPositions();
- redefinition.setMaxStack();
- redefinition.setMaxLocals();
- return redefinition.getMethod();
- }
-
- /**
- * Selects all method bindings from the 'mbsForClass' list which methods are
- * inherited only (not defined in the class itself).
- *
- * @param mbsForClass
- * The method bindings of the transformed class.
- * @param cg
- * The ClassGen object for the transformed class.
- * @return A sublist of 'mbsForClass' containing all bindings for methods
- * which are inherited only.
- *
- */
- private static List<MethodBinding> getInheritedBoundMethods(List<MethodBinding> mbsForClass, ClassGen cg) {
- List<MethodBinding> inheritedBoundMethod = new LinkedList<MethodBinding>();
- Iterator<MethodBinding> it = mbsForClass.iterator();
- while (it.hasNext()) {
- MethodBinding mb = it.next();
- if ((cg.containsMethod(mb.getBaseMethodName(), mb
- .getBaseMethodSignature())) == null)
- inheritedBoundMethod.add(mb);
- }
- return inheritedBoundMethod;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java
deleted file mode 100644
index 8ce3abac3..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java
+++ /dev/null
@@ -1,1004 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: TeamInterfaceImplementation.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import org.apache.bcel.classfile.*;
-import org.apache.bcel.generic.*;
-import org.apache.bcel.*;
-
-import java.util.*;
-
-import org.eclipse.objectteams.otre.util.*;
-
-/**
- * Adds the general Team infrastructure to team classes.
- *
- * Fields: public (static) final_OT$ID <- static if 'ot.no_static' ist set
- * Methods: public int activate(int level) public int deactivate(int level)
- * public int _OT$getID() Static initialization (adds clinit method, if not yet
- * presented) OR to every constructor: <- if 'ot.no_static' is set _OT$ID =
- * TeamIdDispenser.getTeamId(class_name)
- *
- * Enables implicit team activation for normal (user defined) public team-level
- * methods. A call to 'activate' is woven at the beginning of the method. A call
- * to 'deactivate' is woven before every return and at every thrown exception.
- *
- * @version $Id: TeamInterfaceImplementation.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-public class TeamInterfaceImplementation
- extends ObjectTeamsTransformation {
-
-
- public TeamInterfaceImplementation(ClassLoader loader, SharedState state) {
- super(loader, state);
- }
-
- /**
- * @param cg
- */
- public void doTransformCode(ClassGen cg) {
- factory = new InstructionFactory(cg);
-
- if (!classNeedsTeamExtensions(cg)) {
- return;
- }
-
- ConstantPoolGen cpg = cg.getConstantPool();
- String class_name = cg.getClassName();
- genImplicitActivation(cg, cpg);
-
- InstructionList implicitSuperRoleRegistrations = genImplicitSuperRegistration(cg, cpg);
- if (!implicitSuperRoleRegistrations.isEmpty()) {
- // add implicitSuperRoleRegistrations to the static initializer:
- Method clinitMethod = cg.containsMethod(Constants.STATIC_INITIALIZER_NAME, "()V");
- addToMethodStart(implicitSuperRoleRegistrations, clinitMethod, cg, cpg);
- }
-
- if (CallinBindingManager.getBasesPerTeam(class_name) == null) {
- return; // this team does not adapt any base class
- }
-
- /**
- * ******************* add initialization of the field '_OT$ID' to the static initializer : ******
- */
- int nextTeamId = TeamIdDispenser.getTeamId(class_name);
-
- /*
- * The clinit method always exists at this moment, because it has
- * been added by the interface transformer part of this transformer
- * if necessary.
- */
- addStaticInitializations(nextTeamId, cg, cpg);
- }
-
- /**
- * Add initialization of "_OT$ID" with 'nextTeamID' to the static
- * initializer of this team class.
- *
- * @param nextTeamId
- * the id which will be associated with the currently transformed
- * team
- * @param cg
- * the ClassGen for the given team class
- * @param cpg
- * the constant pool ot the team
- */
- private void addStaticInitializations(int nextTeamId, ClassGen cg,
- ConstantPoolGen cpg) {
- Method clinitMethod = cg.containsMethod(
- Constants.STATIC_INITIALIZER_NAME, "()V");
- MethodGen mg = newMethodGen(clinitMethod, cg.getClassName(), cpg);
- InstructionList il = mg.getInstructionList();
-
- InstructionList addedInitialization = new InstructionList();
- addedInitialization.append(createIntegerPush(cpg, nextTeamId));
- addedInitialization.append(factory.createFieldAccess(cg.getClassName(),
- "_OT$ID", Type.INT, Constants.PUTSTATIC));
- // generated: _OT$ID = <id dispensed by TeamIdDispenser>;
-
- // add static initialization for added static field at the beginning of
- // the <clinit> method:
- il.insert(addedInitialization);
- mg.setMaxStack();
- mg.setMaxLocals();
-
- Method newClinit = mg.getMethod();
- cg.replaceMethod(clinitMethod, newClinit);
-
- il.dispose(); // Reuse instruction handles
- }
-
- /**
- * For all roles in the current team which have tsuper versions:
- * Generate instruction list containig calls to registration methods
- * the implicit super roles.
- *
- * @param cg The ClassGen of the current team.
- * @param cpg The constant pool of the current team.
- * @return The instruction list containing the registration calls.
- */
- private InstructionList genImplicitSuperRegistration(ClassGen cg, ConstantPoolGen cpg) {
- InstructionList il = new InstructionList();
- List<String> inheritedRoleNames = getInheritedRoleNames(cg, cpg);
- if (inheritedRoleNames.isEmpty())
- return il; // nothing to do
- Iterator<String> iter = inheritedRoleNames.iterator();
- while (iter.hasNext()) {
- String roleName = iter.next();
- String unqualifiedRoleName = roleName.substring(roleName.lastIndexOf('$') + 1);
- if (CallinBindingManager.isBoundBaseAndRoleClass(roleName)) {
- String potientialImplicitSuperRoleName = cg.getSuperclassName() + '$' + unqualifiedRoleName;
-
- if (!CallinBindingManager.isBoundBaseAndRoleClass(potientialImplicitSuperRoleName)) {
- // Only bound base classes have the infrastructure for notifying
- // implicit subclasses about team activation!
- continue;
- }
- il.append(new PUSH(cpg, roleName));
- il.append(factory.createInvoke("java.lang.Class", "forName",
- classType, new Type[] { Type.STRING },
- Constants.INVOKESTATIC));
- il.append(factory.createInvoke(potientialImplicitSuperRoleName, "_OT$registerObserver",
- Type.VOID, new Type [] { classType },
- Constants.INVOKESTATIC));
- }
- }
- return il;
- }
-
- public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
- String class_name = cg.getClassName();
- ConstantPoolGen cpg = cg.getConstantPool();
-
- checkReadClassAttributes(ce, cg, class_name, cpg);
-
- if (state.interfaceTransformedClasses.contains(class_name)) {
- return; // class has already been transformed by this transformer
- }
-
- if (!classNeedsTeamExtensions(cg)) {
- return;
- }
-
- factory = new InstructionFactory(cg);
-
- /**
- * ********** empty implementation of the static class initialization method '<clinit>' ***
- * NOTE: this is unnecessary in some cases, but checking is too complicated
- */
- addStaticInitializer(cg, cpg, class_name, ce);
-
- List<String> handledBases = CallinBindingManager.getBasesPerTeam(class_name);
- // TeamInterfaceImplementer only registers teams at bases, wich are part
- // of a 'CallinRoleBaseBinding'-attribute of the team.
- if (handledBases == null) {
- return; // this team does not adapt any base class
- }
-
- if(logging) printLogMessage("Adding the general Team infrastructure to "
- + class_name);
-
- /**
- * ******************* addition of the field '_OT$ID'
- * **********************************
- */
-
- int accessFlags = Constants.ACC_PUBLIC | Constants.ACC_FINAL | Constants.ACC_STATIC;
-
- FieldGen IDField = new FieldGen(accessFlags, Type.INT, "_OT$ID", cpg);
- ce.addField(IDField.getField(), cg);
- // generated global variable: public final static int _OT$ID;
-
- factory = new InstructionFactory(cpg);
- InstructionList il;
-
- /**
- * ******************* implementation of method '_OT$getID'
- * ************************
- */
-
- il = new InstructionList();
- MethodGen getIDMethod = new MethodGen(Constants.ACC_PUBLIC, Type.INT,
- Type.NO_ARGS, new String[] {}, "_OT$getID", class_name, il, cpg);
-
- il.append(factory.createFieldAccess(class_name, "_OT$ID", Type.INT,
- Constants.GETSTATIC));
- il.append(InstructionFactory.createReturn(Type.INT));
-
- getIDMethod.setMaxStack();
- getIDMethod.setMaxLocals();
-
- ce.addMethod(getIDMethod.getMethod(), cg);
-
- /**
- * ***************** implementation of team (un)registration methods
- * **********************
- */
-
- ce.addMethod(generateTeamRegistrationMethod(cpg, class_name,
- handledBases), cg);
-
- ce.addMethod(generateTeamUnregistrationMethod(cpg, class_name,
- handledBases), cg);
-
- /**
- * ***************** implementation of base call surrogtes for static methods
- * **********************
- */
- Method [] base_call_surrogates = generateStaticBaseCallSurrogates(class_name, cpg, cg);
- for(int i=0; i<base_call_surrogates.length;i++) {
- // perhaps the compiler already generated an empty surrogate for an unbound super-role?
- // (see X.1.5-otjld-callin-from-static-base-method-12a)
- ce.addOrReplaceMethod(base_call_surrogates[i], cg);
- }
-
- /** *************************************************************************** */
-
- il.dispose();
- state.interfaceTransformedClasses.add(class_name);
- }
-
- /**
- * Add the given instruction list to the start of the givern method.
- * @param additionalInstructions
- * @param method
- * @param cg
- * @param cpg
- */
- private void addToMethodStart(InstructionList additionalInstructions, Method method, ClassGen cg, ConstantPoolGen cpg) {
- MethodGen mg = newMethodGen(method, cg.getClassName(), cpg);
- InstructionList il = mg.getInstructionList();
- il.insert(additionalInstructions);
- mg.setMaxStack();
- mg.setMaxLocals();
-
- Method newMethod = mg.getMethod();
- cg.replaceMethod(method, newMethod);
- il.dispose(); // Reuse instruction handles
- }
-
- /**
- * Generate the static initializer method 'clinit'.
- * @param cpg The constant pool
- * @param class_name The name of the class
- * @param cg The ClassGen for the class
- * @return The static initialier for this class
- */
- void addStaticInitializer(ClassGen cg, ConstantPoolGen cpg, String class_name, ClassEnhancer ce) {
- /*
- * Adding static initializations requires the addition of the clinit
- * method, if not yet presented. This requires synchronization with
- * other transformers (TeamInterfaceImplementer) which may do the
- * same this. This is done via 'TeamIdDispenser.clinitAdded(class_name)'.
- */
- Method existingClinit = cg.containsMethod(Constants.STATIC_INITIALIZER_NAME, "()V");
- if (existingClinit == null && !TeamIdDispenser.clinitAdded(class_name, loader)) {
- // otherwise the clinit-Method already exists and only has to be extended
- // by the code transformation of this transformer
- InstructionList il = new InstructionList();
- MethodGen clinitMethodGen = new MethodGen(Constants.ACC_STATIC,
- Type.VOID, Type.NO_ARGS, new String[] {},
- Constants.STATIC_INITIALIZER_NAME, class_name, il, cpg);
-
- il.append(InstructionFactory.createReturn(Type.VOID));
-
- clinitMethodGen.setMaxStack();
- clinitMethodGen.setMaxLocals();
- Method clinitMethod = clinitMethodGen.getMethod();
- ce.addMethod(clinitMethod, cg);
- }
- }
-
- /**
- * Generates the ' _OT$registerAtBases()' method. This method registers the
- * team at every adapted base class by calling the respective 'addTeam'
- * method.
- *
- * @param cpg
- * The ConstantPoolGen of the team class.
- * @param class_name
- * The name of the team class.
- * @param handledBases
- * The list of teams adapted by (roles of) this team.
- * @return The generated 'activate' method.
- */
- Method generateTeamRegistrationMethod(ConstantPoolGen cpg,
- String class_name, List<String> handledBases)
- {
- InstructionList il = new InstructionList();
- MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, Type.VOID,
- Type.NO_ARGS, null, "_OT$registerAtBases", class_name, il, cpg);
-
- Iterator<String> it = handledBases.iterator();
- while (it.hasNext()) {
- String actBase = it.next();
- //if (CallinBindingManager.hasBoundBaseParent(actBase))
- // continue; // team was already added to a super base class
- // problem: bound base parent could be bound to another team class!!!
-
- //String boundBase = CallinBindingManager.getBoundBaseParent(actBase);
- //if (boundBase != null && handledBases.contains(boundBase))
- // continue;
- if (CallinBindingManager.teamAdaptsSuperBase(class_name, actBase))
- continue;
-
- InstructionHandle startTry = il.append(new ALOAD(0));
-
- il.append(factory.createFieldAccess(class_name, "_OT$ID", Type.INT,
- Constants.GETSTATIC));
- // Note: the method _OT$addTeam may be found in a super classes (topmostBoundBase),
- // but we'll simply leave this lookup to the VM
- il.append(factory.createInvoke(actBase, "_OT$addTeam", Type.VOID,
- new Type[] { teamType, Type.INT }, Constants.INVOKESTATIC));
- // generated: <actBase>._OT$addTeam(this, _OT$ID);
-
- addNoSuchMethodErrorHandling(startTry, il.getEnd(), getErrorMessage(class_name, actBase, "Activation"), il, mg, cpg);
- }
- il.append(new RETURN());
-
- mg.setMaxStack();
- mg.setMaxLocals();
- return mg.getMethod();
- }
-
- /**
- * Direct inverse of generateTeamRegistrationMethod(..). Generates the '
- * _OT$unregisterFromBases' method. This method deregisters the team at
- * every adapted base class by calling the respective 'removeTeam' method.
- *
- * @param cpg
- * The ConstantPoolGen of the team class.
- * @param class_name
- * The name of the team class.
- * @param handledBases
- * The list of teams adapted by (roles of) this team.
- * @return The generated 'deactivate' method.
- */
- Method generateTeamUnregistrationMethod(ConstantPoolGen cpg,
- String class_name, List<String> handledBases) {
-
- InstructionList il = new InstructionList();
- MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, Type.VOID,
- Type.NO_ARGS, null, "_OT$unregisterFromBases", class_name, il,
- cpg);
-
- Iterator<String> it = handledBases.iterator();
- while (it.hasNext()) {
- String actBase = it.next();
- //if (CallinBindingManager.hasBoundBaseParent(actBase))
- // continue; // team was only added to a super base class
- // problem: bound base parent could be bound to another team class!!!
-
- // String boundBase = CallinBindingManager.getBoundBaseParent(actBase);
- //if (boundBase != null && handledBases.contains(boundBase))
- // continue;
- if (CallinBindingManager.teamAdaptsSuperBase(class_name, actBase))
- continue;
-
- InstructionHandle startTry = il.append(new ALOAD(0));
-
- il.append(factory.createInvoke(actBase, "_OT$removeTeam",
- Type.VOID, new Type[] { teamType }, Constants.INVOKESTATIC));
- // generated: <actBase>._OT$removeTeam(this, _OT$ID);
-
- addNoSuchMethodErrorHandling(startTry, il.getEnd(), getErrorMessage(class_name, actBase, "Deactivation"), il, mg, cpg);
- }
- il.append(new RETURN());
-
- mg.setMaxStack();
- mg.setMaxLocals();
- return mg.getMethod();
- }
-
- private String getErrorMessage(String teamName, String baseName, String action) {
- String errorMessage = action+" of team '" + teamName + "' failed! Callins of this team have NOT been WOVEN into base class '" + baseName + "'!\n"
- + "This is probably caused by a loading order problem.";
- return errorMessage;
- }
-
- /**
- * Adds an exception handler to the given method which catches 'java.lang.NoSuchMethodError's
- * caused by missing team registration methods in base classes. Causes the throwing of an
- * 'org.objectteams.UnsupportedFeatureException'.
- *
- * @param startTry handle to the start of the try block
- * @param endTry handle to the end of the try block
- * @param errorMessage the error message to be printed when throwing the exception
- * @param il instruction list of the method
- * @param mg MethodGen of the method
- * @param cpg corresponding ConstantPoolGen
- */
- private void addNoSuchMethodErrorHandling(InstructionHandle startTry, InstructionHandle endTry,
- String errorMessage, InstructionList il, MethodGen mg,
- ConstantPoolGen cpg) {
- GOTO skipHdlr = null;
- skipHdlr = new GOTO(null);
- il.append(skipHdlr);
- // generated: goto normal exit
-
- // throw away the expection reference:
- InstructionHandle hdlr = il.append(new POP());
-
- il.append(factory.createNew(OTConstants.unsupportedFeature));
- il.append(new DUP());
- il.append(new PUSH(cpg, errorMessage));
- il.append(factory.createInvoke(OTConstants.unsupportedFeature.getClassName(),
- Constants.CONSTRUCTOR_NAME,
- Type.VOID,
- new Type[] { Type.STRING },
- Constants.INVOKESPECIAL));
- il.append(new ATHROW());
-
- InstructionHandle nop = il.append(new NOP());
- skipHdlr.setTarget(nop);
- mg.addExceptionHandler(startTry, endTry, hdlr, new ObjectType("java.lang.NoSuchMethodError"));
- }
-
- /**
- * Generate implicit Team activation for each "normal" public method.
- *
- * @param cg
- * class for which methods are to be augmented.
- * @param cpg
- * the constant pool of the class 'cg'.
- */
- void genImplicitActivation(ClassGen cg, ConstantPoolGen cpg) {
- Method[] methods = cg.getMethods();
- for (int i = 0; i < methods.length; i++) {
- Method m = methods[i];
- if (candidateForImplicitActivation(m, cg, cpg)) {
- if(logging) printLogMessage("Adding implicit activation to " + m.getName());
- cg.replaceMethod(m, genImplicitActivation(m, cg.getClassName(), cpg, false));
- }
- }
- }
-
- /**
- * Scans the team attribute StaticReplaceBinding and generates an array of base call surrogates
- *
- * @param class_name
- * @param cpg
- * @param cg
- * @return
- */
- private Method [] generateStaticBaseCallSurrogates(String class_name, ConstantPoolGen cpg, ClassGen cg){
-
- Set<String> roleMethodKeys = new HashSet<String>();
-
- //------------------------------------------------------------------------------------------
- // scan static replace bindings attributes
- //------------------------------------------------------------------------------------------
- Attribute [] attributes = cg.getAttributes();
- for(int k=0; k<attributes.length; k++){
-
- Unknown attr = isOTAttribute(attributes[k]);
- if(attr == null) continue;
-
- if(attr.getName().equals("StaticReplaceBindings")) {
-
- byte[] indizes = attr.getBytes();
- int count = combineTwoBytes(indizes, 0);
- int numberOfEntries=0;
- String [] names;
- numberOfEntries = 5;
- int i = 2;
-
- for (int n=0; n<count;n++) {
- names = new String[numberOfEntries];
- i = scanStrings(names, indizes, i, cpg);
- int index = 0;
- String role_name = names[index++];
- String role_method_name = names[index++];
- String role_method_signature = names[index++];
- String lift_method_name = names[index++];
- String lift_method_signature = names[index++];
-
- String roleMethodKey = genRoleMethodKey(class_name, role_name, role_method_name, role_method_signature, lift_method_name, lift_method_signature);
- roleMethodKeys.add(roleMethodKey);
-
- int base_len = combineTwoBytes(indizes, i);
- BaseMethodInfo baseMethod;
- i += 2;
- names = new String[3];
- for (int n_base = 0; n_base < base_len; n_base++) {
- int [] positions = null;
-
- i = scanStrings(names, indizes, i, cpg);
-
- int flags = indizes[i++];
- boolean baseIsCallin = (flags & 1) != 0;
- boolean baseIsRoleMethod = (flags & 2) != 0;
- boolean baseIsStatic = (flags & 4) != 0;
- //parameter positions scanning
- int pos_len = combineTwoBytes(indizes, i);
- i+=2;
-
- if(pos_len > 0) {
- positions = new int[pos_len];
- }
-
- for(int pos = 0; pos < pos_len; pos++){
- positions[pos] = combineTwoBytes(indizes,i);
- i += 2;
- }
- int translationFlags = (combineTwoBytes(indizes, i)<<16) + combineTwoBytes(indizes, i+2);
- i+=4;
- baseMethod = new BaseMethodInfo(names[0], names[1], names[2],
- baseIsCallin, baseIsRoleMethod, baseIsStatic,
- positions, translationFlags);
-
- CallinBindingManager.assignBaseCallTag(names[0],names[1],names[2]);
- CallinBindingManager.addStaticReplaceBindingForRoleMethod(roleMethodKey, baseMethod);
- }
- }
- break;
- }
- }
-
- //------------------------------------------------------------------------------------------
- // generate base call surrogates
- //------------------------------------------------------------------------------------------
- Iterator<String> roleMethodIter = roleMethodKeys.iterator();
- int count = roleMethodKeys.size();
- Method [] generatedSurrogates = new Method[count];
-
- int j = 0;
-
- while(roleMethodIter.hasNext()) {
- String roleMethodKey = roleMethodIter.next();
- LinkedList<BaseMethodInfo> baseMethods = CallinBindingManager.getStaticReplaceBindingsForRoleMethod(roleMethodKey);
-
- //split the key into team class name, role class name, role method name and role method signature
- int firstPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR);
- int secondPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR, firstPointIndex+1);
- int thirdPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR, secondPointIndex+1);
- int fourthPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR, thirdPointIndex+1);
- int fifthPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR, fourthPointIndex+1);
-
- String role_name = roleMethodKey.substring(firstPointIndex+2, secondPointIndex);
- String role_method_name = roleMethodKey.substring(secondPointIndex+2, thirdPointIndex);
- String role_method_signature = roleMethodKey.substring(thirdPointIndex+2, fourthPointIndex);
- String lift_method_name = null;
- String lift_method_signature = null;
- // SH: without this check we get
- // StringIndexOutOfBoundsException: String index out of range: -1
- // I hope this patch is correct..
- if ( fourthPointIndex + 2 <= fifthPointIndex
- && fifthPointIndex + 2 < roleMethodKey.length())
- {
- lift_method_name = roleMethodKey.substring(fourthPointIndex+2, fifthPointIndex);
- lift_method_signature = roleMethodKey.substring(fifthPointIndex+2, roleMethodKey.length());
- }
-
- generatedSurrogates[j] = genBaseCallSurrogate(cg, role_name, role_method_name,
- role_method_signature,
- lift_method_name, lift_method_signature, baseMethods);
- j++;
- }
-
- return generatedSurrogates;
- }
-
- /**
- * Generates a base call surrogate for a given static role method
- * @param cg
- * @param role_name
- * @param role_method_name
- * @param role_method_signature
- * @param lift_method_name
- * @param lift_method_signature
- * @param base_methods
- * @return
- */
- private Method genBaseCallSurrogate(ClassGen cg,
- String role_name,
- String role_method_name,
- String role_method_signature,
- String lift_method_name,
- String lift_method_signature,
- LinkedList<BaseMethodInfo> base_methods)
- {
- ConstantPoolGen cpg = cg.getConstantPool();
- String class_name = cg.getClassName();
-
- if (base_methods.isEmpty()) {
- return null;
- }
- Type[] enhancedArgumentTypes = enhanceArgumentTypes(Type.getArgumentTypes(role_method_signature));
- Type enhancedReturnType = generalizeReturnType(Type.getReturnType(role_method_signature));
- String[] enhancedArgumentNames = null;
- InstructionList il = new InstructionList();
- int accessFlags = Constants.ACC_PROTECTED;
-
- MethodGen baseCallSurrogate = new MethodGen(accessFlags,
- enhancedReturnType,
- enhancedArgumentTypes,
- enhancedArgumentNames,
- getBaseCallSurrogateName(role_name, role_method_name),
- class_name,
- il, cpg);
-
-
- LocalVariableGen otResult = null;
-
- /*
- int slot = enhancedArgumentTypes.length+1;
- otResult = baseCallSurrogate.addLocalVariable("_OT$result",
- enhancedReturnType,
- slot, null, null);
- */
- otResult = baseCallSurrogate.addLocalVariable("_OT$result",
- enhancedReturnType, null, null);
-
- il.insert(InstructionFactory.createStore(enhancedReturnType,
- otResult.getIndex()));
- il.insert(new ACONST_NULL());
- il.setPositions(); // about to retrieve instruction handles.
-
- if(logging) printLogMessage("base-call switch has to be inserted!");
- InstructionList loading = new InstructionList();
- loading.append(InstructionFactory.createThis());
- int index = 1;
- for (int i = 0; i < enhancedArgumentTypes.length; i++) {
- loading.append(InstructionFactory.createLoad(enhancedArgumentTypes[i],index));
- index += enhancedArgumentTypes[i].getSize();
- }
-
- Type[] argumentTypes = Type.getArgumentTypes(role_method_signature);
- Type returnType = Type.getReturnType(role_method_signature);
-
- if (debugging) {
- baseCallSurrogate.addLineNumber(il.getStart(), STEP_OVER_LINENUMBER);
- }
-
- il.append(genBaseCallSwitch(cpg, base_methods, baseCallSurrogate,
- argumentTypes,
- returnType,
- lift_method_name,
- lift_method_signature,
- otResult, loading, cg.getClassName()));
-
- il.append(InstructionFactory.createLoad(enhancedReturnType, otResult.getIndex()));
- il.append(InstructionFactory.createReturn(enhancedReturnType));
-
- il.setPositions();
- baseCallSurrogate.removeNOPs();
- baseCallSurrogate.setMaxStack();
- baseCallSurrogate.setMaxLocals();
- return baseCallSurrogate.getMethod();
- }
-
- private static String getBaseCallSurrogateName(String class_name, String method_name){
- // base call surrogate for static callin methods:
- // name contains role class name and role method name,
- // because its generated into the team.
- return OT_PREFIX + class_name + "$" + method_name + "$base";
- }
-
- /**
- * Generate a dispatching switch statement which calls the proper base method.
- * @param cpg
- * @param base_methods list of BaseMethodInfo that applies to this callin method
- * @param enhancedMethod the enhanced callin method
- * @param argumentTypes arg types of the callin method
- * @param returnType the return type of the original callin method
- * @param liftMethodSignature
- * @param otResult the local variable storing the base call result
- * @param loading an instruction list holding the original instructions for
- * loading parameters
- * @param teamName
- * @param lift_method_name
- * @return InstructionList the complete replacement implementing the base call.
- */
- InstructionList genBaseCallSwitch (ConstantPoolGen cpg,
- LinkedList<BaseMethodInfo> base_methods, MethodGen enhancedMethod,
- Type[] argumentTypes,
- Type returnType, String liftMethodName, String liftMethodSignature,
- LocalVariableGen otResult, InstructionList loading, String teamName)
- {
-
- short invocationKind = Constants.INVOKESTATIC;
-
- String className = enhancedMethod.getClassName();
- Type enhancedMethodReturnType = enhancedMethod.getReturnType();
- boolean callinHasReturnValue = returnType != Type.VOID;
-
- InstructionList il = new InstructionList();
-
- // Setup a variable which holds the result of this base call.
- // This variabel is local to this segment of code and used only
- // to transport this result out off the switch statement.
- int localResult = -1;
- LocalVariableGen lg = null;
- if (callinHasReturnValue) {
- lg = enhancedMethod.addLocalVariable("_OT$tmpResult", returnType,
- null, null);
- localResult = lg.getIndex();
- il.append(InstructionFactory.createNull (returnType));
- il.append(InstructionFactory.createStore(returnType, localResult));
- }
-
- // ---- Prepare the switch: ----
- InstructionHandle switchStart = il.append
- (InstructionFactory.createLoad(Type.INT, BASE_METH_ARG));
- // generated: _OT$baseMethTag
-
- //base_methods may contain duplicates!
- //baseMethodTags is used to determine the number of cases without duplicates
- HashSet<Integer> baseMethodTags = new HashSet<Integer>();
- Iterator<BaseMethodInfo> iter = base_methods.iterator();
- while(iter.hasNext()) {
- BaseMethodInfo baseMethod = iter.next();
- //baseMethodTags.add(CallinBindingManager.getBaseCallTag( baseMethod.getBaseClassName(),
- // baseMethod.getBaseMethodName(),
- // baseMethod.getBaseMethodSignature()));
- int baseMethodTag = CallinBindingManager.getBaseCallTag(baseMethod.getBaseClassName(),
- baseMethod.getBaseMethodName(),
- baseMethod.getBaseMethodSignature());
- baseMethodTags.add(Integer.valueOf(baseMethodTag));
- }
-
- // one break for each case clause
- int numberOfCases = baseMethodTags.size();
-
- GOTO[] breaks = new GOTO[numberOfCases];
- for (int i=0; i<numberOfCases; i++)
- breaks[i] = new GOTO(null);
-
- int[] matches = new int[numberOfCases];
- InstructionHandle[] targets = new InstructionHandle[numberOfCases];
- int caseCounter = 0;
-
- //now baseMethodTags is used to store the handled tags
- baseMethodTags.clear();
-
- //JU:
- Type[] enhancedMethodArguments = enhancedMethod.getArgumentTypes();
- Type[] enhancedArgumentsForBaseCall = new Type[enhancedMethodArguments.length - 1];
- System.arraycopy(enhancedMethodArguments, 0,
- enhancedArgumentsForBaseCall, 0,
- enhancedArgumentsForBaseCall.length);
-
- Iterator<BaseMethodInfo> it = base_methods.iterator();
- while (it.hasNext()) {
-
- BaseMethodInfo baseMethod = it.next();
- String baseClassName = baseMethod.getBaseClassName();
- String baseMethodName = baseMethod.getBaseMethodName();
- String baseMethodSignature = baseMethod.getBaseMethodSignature();
- int base_method_tag = CallinBindingManager.getBaseCallTag(baseClassName, baseMethodName, baseMethodSignature);
-
- //if the current baseMethod is a dulpicate:
- // workaround for jdk 1.4:
- Integer bmt = Integer.valueOf(base_method_tag);
- //if(baseMethodTags.contains(base_method_tag)){
- if (baseMethodTags.contains(bmt)) {
- continue;
- }
-
- //baseMethodTags.add(base_method_tag);
- baseMethodTags.add(bmt);
-
- int [] parameterPositions = baseMethod.getParameterPositions();
- int len = Type.getArgumentTypes(baseMethodSignature).length;
-
- // if the base method is a callin method as well, further enhance the signature:
- if (baseMethod.isCallin)
- len += EXTRA_ARGS;
-
-
- matches[caseCounter] = CallinBindingManager.getBaseCallTag(baseClassName, baseMethodName, baseMethodSignature);
- InstructionHandle nextBranch = il.append(new NOP());
-
- Type[] baseMethodArgumentTypes = Type.getArgumentTypes(baseMethodSignature);
- Type baseMethodReturnType = Type.getReturnType (baseMethodSignature);
- String baseChainMethodName = genChainMethName(baseMethodName);
- Type baseChainReturnType = object; // ALWAYS
- Type[] enhancedBaseArgumentTypes = enhanceArgumentTypes(baseMethodArgumentTypes);
-
- boolean resultLiftingNecessary = false;
-
- // TODO (SH): if both types are ObjectType we should probably use subclassOf() ??
- // (don't lift if simple polymorphism suffices!)
- //TODO: if the base method return type is a subtype of the role method return type no lifting has to take place!! is this allowed??
- //if (!returnTypeCompatible(baseMethodReturnType, returnType) && callinHasReturnValue)
- if (/*!baseMethodReturnType.equals(object) &&*/
- !baseMethodReturnType.equals(returnType)
- && !(baseMethodReturnType instanceof BasicType) // requires boxing not lifting
- && !(returnType instanceof BasicType) // requires unboxing not lifting
- && callinHasReturnValue)
- {
- resultLiftingNecessary = true;
- }
-
- // --- load arguments of the new method: ---
- // (letters refer to document parameter-passing.odg)
-
- // (u) generate extra arguments (indices are equal at role and base):
- for (int idx = 0; idx < EXTRA_ARGS; idx++)
- il.append(InstructionFactory.createLoad(enhancedMethodArguments[idx],
- idx+1)); // first arg is "this" (enclosing team)
-
- // (v)(w)(x) split loading sequence and transfer source-level arguments
- // (includes reverse-application of parameter mappings):
- InstructionHandle baseCallLine = il.append(translateLoads(splitLoading(cpg,
- loading.copy(),
- argumentTypes),
- enhancedMethodArguments,
- enhancedBaseArgumentTypes,
- parameterPositions,
- teamName,
- null,
- baseMethod,
- EXTRA_ARGS/*start*/,
- cpg));
- // --- done loading ---
-
- // invoke the chaining method of the base class (base-call!):
- il.append(factory.createInvoke(baseClassName,
- baseChainMethodName,
- baseChainReturnType,
- enhancedBaseArgumentTypes,
- invocationKind));
-
- // FIXME(SH): if this assert holds, remove computing of resultLiftingNecessary above.
- assert resultLiftingNecessary == ((baseMethod.translationFlags & 1) != 0);
-
- if (resultLiftingNecessary) { // call the lift-method:
- Type[] liftMethodArgs = Type.getArgumentTypes(liftMethodSignature);
- Type liftMethodReturnType = Type.getReturnType(liftMethodSignature);
-
- // cast result of base call:
- il.append(factory.createCast(baseChainReturnType, baseMethodReturnType));
-
- // load the team instance at which to call the lift method:
- il.append(InstructionFactory.createThis());
- il.append(factory.createCast(object, new ObjectType(teamName)));
-
- // put them in correct order:
- il.append(new SWAP()); // -> .., this$0, (BaseType)result
-
- il.append(factory.createInvoke(teamName,
- liftMethodName,
- liftMethodReturnType,
- liftMethodArgs,
- Constants.INVOKEVIRTUAL));
- }
-
- // adjust the return value to the type expected by the WRAPPER:
- il.append(new DUP()); // keep for adjustment below
- if (!resultLiftingNecessary)
- adjustValue(il, null, baseChainReturnType, enhancedMethodReturnType);
- il.append(InstructionFactory.createStore(enhancedMethodReturnType,
- otResult.getIndex())); // store "globally"
- // this store is needed to tunnel unused results through the callin.
-
- InstructionHandle afterBaseCallLine = il.append(new NOP());
-
- // adjust the return value to the type expected by the ORIGINAL CALLIN:
- adjustValue(il, null, baseChainReturnType, returnType);
- if (callinHasReturnValue) {
- il.append(InstructionFactory.createStore(returnType, localResult)); // store "locally"
- }
- // this store is useful for callins which make use of the result.
-
- targets[caseCounter] = nextBranch;
- il.append(breaks[caseCounter]);
- // generated: break;
-
- caseCounter++;
-
- if (debugging) {
- enhancedMethod.addLineNumber(baseCallLine, STEP_INTO_LINENUMBER);
- enhancedMethod.addLineNumber(afterBaseCallLine, STEP_OVER_LINENUMBER);
- }
- }
-
- //JU: added the follwing part (begin) -----------------------------------------------------
- InstructionHandle defaultBranch = il.append(new NOP());
-
- if (logging)
- printLogMessage("Exeption has to be thrown! Base-Call is impossible.");
-
- il.append(factory.createNew(OTConstants.unsupportedFeature));
- il.append(new DUP());
- // ## FIXME: fix otld$
- il.append(new PUSH(cpg, "Binding-Error: base-call from " + className + "." + enhancedMethod.getName()
- + "impossible! This problem is documented in OTLD $XY."));
- il.append(factory.createInvoke(OTConstants.unsupportedFeature.getClassName(),
- Constants.CONSTRUCTOR_NAME,
- Type.VOID,
- new Type[] { Type.STRING },
- Constants.INVOKESPECIAL));
- il.append(new ATHROW());
- //JU: (end) --------------------------------------------------------------------------------
-
- InstructionHandle afterSwitch = il.append(new NOP()); // all breaks point here.
-
- il.append(switchStart, createLookupSwitch(matches, targets, breaks,
- defaultBranch, afterSwitch));
-
- // retrieve locally stored result:
- if (callinHasReturnValue) {
- il.append(InstructionFactory.createLoad(returnType, localResult));
- lg.setStart(il.getStart()); // restrict local variable to this segment.
- lg.setEnd(il.getEnd());
- }
- return il;
- }
-
- /**
- * Generates a key for the given role method parameters
- *
- * @param teamClassName
- * @param roleClassName
- * @param roleMethodName
- * @param roleMethodSignature
- * @param liftMethodSignature
- * @return
- */
- private static String genRoleMethodKey(String teamClassName,
- String roleClassName, String roleMethodName,
- String roleMethodSignature, String liftMethodName,
- String liftMethodSignature)
- {
- StringBuilder roleMethodKey = new StringBuilder(64);
- roleMethodKey.append(teamClassName);
- roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
- roleMethodKey.append(roleClassName);
- roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
- roleMethodKey.append(roleMethodName);
- roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
- roleMethodKey.append(roleMethodSignature);
- roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
- roleMethodKey.append(liftMethodName);
- roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
- roleMethodKey.append(liftMethodSignature);
- return roleMethodKey.toString();
- }
-
- /**
- * Read the InheritedRoles attribute and return the list of inherited roles.
- * @param cg The ClassGen of the inspected class.
- * @param cpg The constant pool of the instpected class.
- * @return A list of inherited role names.
- */
- private List<String> getInheritedRoleNames(ClassGen cg, ConstantPoolGen cpg) {
- Attribute[] attributes = cg.getAttributes();
- LinkedList<String> inheritedRoleNames = new LinkedList<String>();
- for (int i = 0; i < attributes.length; i++) {
- Attribute actAttr = attributes[i];
- if (actAttr instanceof Unknown) {
- Unknown attr = (Unknown)actAttr;
- byte[] indizes = attr.getBytes();
- int count = combineTwoBytes(indizes, 0);
- if (attr.getName().equals("InheritedRoles")) {
- int j = 2;
- while (j<=2*count) {
- String[] names = new String[1];
- j = scanStrings(names, indizes, j, cpg);
- String inherited_role = names[0];
- inheritedRoleNames.add(inherited_role);
- }
- }
- }
- }
- return inheritedRoleNames;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ThreadActivation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ThreadActivation.java
deleted file mode 100644
index 983929721..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ThreadActivation.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ThreadActivation.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre;
-
-import java.util.HashSet;
-
-import org.apache.bcel.classfile.*;
-import org.apache.bcel.generic.*;
-import org.apache.bcel.*;
-
-import static org.eclipse.objectteams.otre.ObjectTeamsTransformation.newMethodGen;
-
-/**
- * This transformer inserts a notification call to the TeamThreadManager at the
- * beginning of every run()-Method in Subtypes of java.lang.Thread or java.lang.Runnable.
- * Thre TeamThreadManager then ensures the thread activation of the current thread
- * for every global active team instance.
- *
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-public class ThreadActivation
-{
- // name of a generated field that stores the thread which created a given runnable:
- private static final String CREATION_THREAD = "_OT$creationThread";
- HashSet<String> transformableClasses = new HashSet<String>();
-
- private boolean shouldTransform(ClassGen cg) {
- Method runMethode = cg.containsMethod("run", "()V");
- if (runMethode == null || runMethode.isAbstract()) {
- // this class contains no concrete run() method
- return false;
- }
- String class_name = cg.getClassName();
- // check if this class is a subtype of Thread or Runnable:
- try {
- return RepositoryAccess.implementationOf(class_name, "java.lang.Runnable") || RepositoryAccess.instanceOf(class_name, "java.lang.Thread");
- } catch (ClassNotFoundException cfne) {
- if (ObjectTeamsTransformation.WORKAROUND_REPOSITORY) {
- return false;
- }
- else
- throw new RuntimeException("Could not find class being loaded", cfne); // rethrow
- }
- }
- public void doTransformInterface(ClassEnhancer enhancer, ClassGen cg) {
- if (!shouldTransform(cg))
- return;
-
- // if class is already transformed by this transformer
- if (this.transformableClasses.contains(cg.getClassName()))
- return;
-
- this.transformableClasses.add(cg.getClassName());
- FieldGen field = new FieldGen(Constants.ACC_PRIVATE, OTConstants.threadType, CREATION_THREAD, cg.getConstantPool());
- enhancer.addField(field.getField(), cg);
- }
- /**
- *
- */
- public void doTransformCode(ClassGen cg) {
- if (!this.transformableClasses.contains(cg.getClassName()))
- return;
-
- this.transformableClasses.remove(cg.getClassName());
-
- InstructionFactory factory = new InstructionFactory(cg);
-
- for (Method method : cg.getMethods()) {
- MethodGen mg = isRootCtor(method, cg);
- if (mg != null)
- enhanceConstructor(cg, factory, method, mg);
- }
-
- enhanceRunMethod(cg, factory);
- }
- private void enhanceRunMethod(ClassGen cg, InstructionFactory factory) {
- String class_name = cg.getClassName();
- ConstantPoolGen cpg = cg.getConstantPool();
-
- Method runMethode = cg.containsMethod("run", "()V"); // existence checked in transformInterface
-
- MethodGen mg = newMethodGen(runMethode, class_name, cpg);
- InstructionList il = mg.getInstructionList();
- InstructionHandle try_start = il.getStart();
-
- /** *** Insert a call to TeamThreadManager.newThreadStarted() at the beginning of the run() method: ****** */
- InstructionList threadActivation = new InstructionList();
- threadActivation.append(new ICONST(0)); // isMain = false
- threadActivation.append(InstructionConstants.ALOAD_0); // parent=this._OT$creationThread;
- threadActivation.append(factory.createFieldAccess(class_name, CREATION_THREAD, OTConstants.threadType, Constants.GETFIELD));
- threadActivation.append(factory.createInvoke("org.objectteams.TeamThreadManager",
- "newThreadStarted",
- Type.BOOLEAN,
- new Type[]{Type.BOOLEAN, OTConstants.threadType},
- Constants.INVOKESTATIC));
- LocalVariableGen flag = mg.addLocalVariable("_OT$isThreadStart", Type.BOOLEAN, il.getStart(), il.getEnd());
- threadActivation.append(new ISTORE(flag.getIndex()));
- il.insert(threadActivation);
-
- /** *** Insert a call to TeamThreadManager.threadEnded() before every return of the run() method: ******** */
- InstructionList threadDeactivation = new InstructionList();
- threadDeactivation.append(new ILOAD(flag.getIndex()));
- BranchInstruction ifIsThreadStarted = new IFEQ(null);
- threadDeactivation.append(ifIsThreadStarted);
- threadDeactivation.append(factory.createInvoke("org.objectteams.TeamThreadManager",
- "threadEnded",
- Type.VOID,
- Type.NO_ARGS,
- Constants.INVOKESTATIC));
- ifIsThreadStarted.setTarget(threadDeactivation.append(new NOP()));
-
- ObjectTeamsTransformation.insertBeforeReturn(mg, il, threadDeactivation);
-
- /** **** Add an exception handler which calls TeamThreadManager.threadEnded() *****
- * ***** before throwing the exception (finaly-simulation): */
- ObjectType throwable = new ObjectType("java.lang.Throwable");
- LocalVariableGen exception = mg.addLocalVariable(
- "_OT$thrown_exception", throwable, null, null);
- InstructionHandle try_end = il.getEnd();
- InstructionList deactivation_ex = threadDeactivation.copy();
- deactivation_ex.insert(InstructionFactory.createStore(throwable, exception.getIndex()));
- deactivation_ex.append(InstructionFactory.createLoad(throwable, exception.getIndex()));
- deactivation_ex.append(new ATHROW());
- InstructionHandle deactivation_handler = il.append(il.getEnd(), deactivation_ex);
- mg.addExceptionHandler(try_start, try_end, deactivation_handler, throwable);
- /** ******************************************************************** */
-
- mg.setMaxStack();
- mg.setMaxLocals();
- Method generatedMethod = mg.getMethod();
- cg.replaceMethod(runMethode, generatedMethod);
- threadActivation.dispose();
- il.dispose();
- }
- // is method a constructor that does not invoke another this()-ctor?
- @SuppressWarnings("deprecation")
- private MethodGen isRootCtor(Method method, ClassGen cg) {
- if (!method.getName().equals("<init>"))
- return null;
- String className = cg.getClassName();
- ConstantPoolGen cpg = cg.getConstantPool();
- MethodGen mg = newMethodGen(method, className, cpg);
- InstructionList il = mg.getInstructionList();
- InstructionHandle ih = il.getStart();
- while (ih != null && ih.getInstruction().getOpcode() != Constants.INVOKESPECIAL) {
- ih = ih.getNext();
- }
- if (ih == null)
- return null;
- if (((InvokeInstruction)ih.getInstruction()).getClassName(cpg).equals(className)) // unsafe due to object/array ambiguity, but we have no array (is an invokespecial!)
- return null; // this-call
- return mg;
- }
- // add statements to store the thread that created this runnable
- private void enhanceConstructor(ClassGen cg, InstructionFactory factory, Method initMethod, MethodGen mg) {
- String class_name = cg.getClassName();
- InstructionList il = mg.getInstructionList();
- il.insert(il.getEnd(), InstructionConstants.ALOAD_0);
- il.insert(il.getEnd(), factory.createInvoke("java.lang.Thread", "currentThread", OTConstants.threadType, new Type[0], Constants.INVOKESTATIC));
- il.insert(il.getEnd(), factory.createFieldAccess(class_name, CREATION_THREAD, OTConstants.threadType, Constants.PUTFIELD));
- mg.setMaxStack();
- mg.setMaxLocals();
- cg.replaceMethod(initMethod, mg.getMethod());
- il.dispose();
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java
deleted file mode 100644
index 10d2c7d00..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2005-2008 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: JPLISEnhancer.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.jplis;
-
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.eclipse.objectteams.otre.ClassEnhancer;
-import org.eclipse.objectteams.otre.OTREInternalError;
-import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
-
-import org.apache.bcel.Constants;
-import org.apache.bcel.classfile.ClassParser;
-import org.apache.bcel.classfile.Field;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.classfile.Utility;
-import org.apache.bcel.generic.ClassGen;
-import org.apache.bcel.generic.ConstantPoolGen;
-import org.apache.bcel.generic.MethodGen;
-
-
-/**
-* This class implements the ClassEnhancer interface with the JPLIS (Java5) specific behavior.
-*
-* @author Christine Hundt
-* @author Juergen Widiker
-* @author Stephan Herrmann
-*/
-
-public class JPLISEnhancer implements ClassEnhancer {
-
- private ClassLoader loader;
-
- public JPLISEnhancer(ClassGen cg, ClassLoader loader) {
- this.loader = loader;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.objectteams.otre.ClassEnhancer#addImplements(java.lang.String, org.apache.bcel.generic.ClassGen)
- */
- public void addImplements(String interfaceName, ClassGen cg) {
- cg.addInterface(interfaceName);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.objectteams.otre.common.ClassEnhancer#addMethod(org.apache.bcel.classfile.Method, de.fub.bytecode.generic.ClassGen)
- */
- public void addMethod(Method m, ClassGen cg) {
- if (cg.containsMethod(m.getName(), m.getSignature()) != null)
- new OTREInternalError("Warning: repetive adding of method "
- + m.getName() + m.getSignature()
- + " to class " + cg.getClassName())
- .printStackTrace();
- cg.addMethod(m);
- }
-
- public void addOrReplaceMethod(Method method, ClassGen cg) {
- Method existingMethod = cg.containsMethod(method.getName(), method.getSignature());
- if (existingMethod == null)
- addMethod(method, cg);
- else
- cg.replaceMethod(existingMethod, method);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.objectteams.otre.common.ClassEnhancer#addField(org.apache.bcel.classfile.Field, de.fub.bytecode.generic.ClassGen)
- */
- public void addField(Field f, ClassGen cg) {
- if (cg.containsField(f.getName()) != null)
- new OTREInternalError("Warning: repetitive adding of field "
- + f.getName() + f.getSignature()
- + " to class " + cg.getClassName())
- .printStackTrace();
- cg.addField(f);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.objectteams.otre.common.ClassEnhancer#loadClass(java.lang.String)
- */
- public void loadClass(String className, ObjectTeamsTransformation client) {
- // SH: no forced class loading within OT/Equinox
- if(System.getProperty("ot.equinox") != null)
- return;
- try {
- String binaryName = className.replace('.', '/');
- InputStream is = loader.getResourceAsStream(binaryName+".class");
- if (is != null) {
- ClassGen cg = new ClassGen(new ClassParser(is, className).parse());
- client.checkReadClassAttributes(this, cg, className, cg.getConstantPool());
- }
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.objectteams.otre.common.ClassEnhancer#decapsulateMethod(org.apache.bcel.classfile.Method, java.lang.String, de.fub.bytecode.generic.ConstantPoolGen)
- */
- public void decapsulateMethod(Method m, ClassGen cg, String packageName, ConstantPoolGen cpg) {
- String className = cg.getClassName();
- int flags = m.getAccessFlags();
- MethodGen mg = new MethodGen(m, className, cpg); // no need to remove attributes, code remains unchanged
-
- if ((flags & Constants.ACC_PUBLIC) == 0) {
- int newFlags = flags;
- newFlags &= ~(Constants.ACC_PROTECTED|Constants.ACC_PRIVATE); // clear old visibility
- newFlags |= Constants.ACC_PUBLIC; // set new visibility
- mg.setAccessFlags(newFlags);
- if(System.getProperty("ot.log") != null)
- ObjectTeamsTransformation.printLogMessage("Adjusting from "
- + Utility.accessToString(flags)
- + " to public:\n\t"
- + className
- + "." + m);
- if (!packageName.equals("NO_PACKAGE"))
- checkSeal(packageName, className);
- }
- cg.replaceMethod(m, mg.getMethod());
- }
-
- private static void checkSeal(String package_name, String class_name) {
- Package pckg = Package.getPackage(package_name);
- if ( (pckg != null) && pckg.isSealed())
- throw new IllegalAccessError(
- "OT/J callout binding:\n"
- +"Trying to break sealed "+pckg);
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java
deleted file mode 100644
index d0f5d05ac..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2005-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ObjectTeamsTransformer.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.jplis;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.security.ProtectionDomain;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.bcel.classfile.ClassParser;
-import org.apache.bcel.classfile.JavaClass;
-import org.apache.bcel.generic.ClassGen;
-import org.apache.bcel.util.ClassLoaderRepository;
-import org.eclipse.objectteams.otre.BaseCallRedirection;
-import org.eclipse.objectteams.otre.BaseMethodTransformation;
-import org.eclipse.objectteams.otre.Decapsulation;
-import org.eclipse.objectteams.otre.LiftingParticipantTransformation;
-import org.eclipse.objectteams.otre.OTConstants;
-import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
-import org.eclipse.objectteams.otre.RepositoryAccess;
-import org.eclipse.objectteams.otre.StaticSliceBaseTransformation;
-import org.eclipse.objectteams.otre.SubBoundBaseMethodRedefinition;
-import org.eclipse.objectteams.otre.TeamInterfaceImplementation;
-import org.eclipse.objectteams.otre.ThreadActivation;
-import org.eclipse.objectteams.otre.util.AttributeReadingGuard;
-import org.eclipse.objectteams.otre.util.CallinBindingManager;
-
-
-/**
- * Main entry into the OTRE when using JPLIS
- *
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-public class ObjectTeamsTransformer implements ClassFileTransformer {
-
- // force loading all transformer classes to reduce risk of deadlock in class loading.
- static Class<?>[] transformerClasses = new Class<?>[] {
- BaseCallRedirection.class,
- BaseMethodTransformation.class,
- Decapsulation.class,
- LiftingParticipantTransformation.class,
- StaticSliceBaseTransformation.class,
- SubBoundBaseMethodRedefinition.class,
- TeamInterfaceImplementation.class,
- ThreadActivation.class
- };
-
- /**
- * One instance of this class is used per class loader to ensure disjoint scopes.
- */
- static class StateGroup {
- ObjectTeamsTransformation.SharedState bcrState = new ObjectTeamsTransformation.SharedState();
- ObjectTeamsTransformation.SharedState bmtState = new ObjectTeamsTransformation.SharedState();
- Decapsulation.SharedState decState = new Decapsulation.SharedState();
- ObjectTeamsTransformation.SharedState lptState = new ObjectTeamsTransformation.SharedState();
- ObjectTeamsTransformation.SharedState ssbtState = new ObjectTeamsTransformation.SharedState();
- ObjectTeamsTransformation.SharedState sbbmrState = new ObjectTeamsTransformation.SharedState();
- ObjectTeamsTransformation.SharedState tiiState = new ObjectTeamsTransformation.SharedState();
- }
- static Map<ClassLoader, StateGroup> states = new HashMap<ClassLoader, StateGroup>();
-
- static boolean warmedUp = false;
- /*
- * (non-Javadoc)
- *
- * @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader,
- * java.lang.String, java.lang.Class, java.security.ProtectionDomain,
- * byte[])
- */
- public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
- ProtectionDomain protectionDomain, byte[] classfileBuffer)
- throws IllegalClassFormatException
- {
- if (warmedUp)
- return internalTransform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
- synchronized (loader) {
- try {
- return internalTransform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
- } finally {
- warmedUp = true;
- }
- }
- }
- public byte[] internalTransform(ClassLoader loader, String className, Class<?> classBeingRedefined,
- ProtectionDomain protectionDomain, byte[] classfileBuffer)
- throws IllegalClassFormatException
- {
- if ( className.startsWith("org/eclipse/objectteams/otre")
- || className.startsWith("org/apache/bcel")
- || className.equals("java/util/LinkedHashMap$KeyIterator")) // saw class loading circularity caused by accessing this class
- {
- // skip OTRE and BCEL classes
- return null;
- }
- if (classBeingRedefined != null) {
- System.out.println("Redefinition!");
- return null;
- }
-
- // state sharing among transformers:
- StateGroup states = ObjectTeamsTransformer.states.get(loader);
- if (states == null)
- ObjectTeamsTransformer.states.put(loader, states = new StateGroup());
- //
- // One fresh instance of each transformer for a given class:
- //
- BaseCallRedirection baseCallRedirection
- = new BaseCallRedirection( loader, states.bcrState);
- BaseMethodTransformation baseMethodTransformation
- = new BaseMethodTransformation( loader, states.bmtState);
- Decapsulation decapsulation
- = new Decapsulation( loader, states.decState);
- LiftingParticipantTransformation liftingParticipantTransformation
- = new LiftingParticipantTransformation( loader, states.lptState);
- StaticSliceBaseTransformation staticSliceBaseTransformation
- = new StaticSliceBaseTransformation( loader, states.ssbtState);
- SubBoundBaseMethodRedefinition subBoundBaseMethodRedefinition
- = new SubBoundBaseMethodRedefinition( loader, states.sbbmrState);
- TeamInterfaceImplementation teamInterfaceImplementation
- = new TeamInterfaceImplementation( loader, states.tiiState);
- ThreadActivation threadActivation
- = new ThreadActivation();
-
- // tell Repository about the class loader for improved lookupClass()
- ClassLoaderRepository prevRepository = RepositoryAccess.setClassLoader(loader);
-
- InputStream is = new ByteArrayInputStream(classfileBuffer);
- try {
- JavaClass java_class = new ClassParser(is, className).parse();
- //Repository.addClass(java_class);
- ClassGen cg = new ClassGen(java_class);
-
- JPLISEnhancer jpe = new JPLISEnhancer(cg, loader);
-
- Collection<String> adaptedBases; // [OT/Equinox]
- // [OT/Equinox] remember the first transformation which holds adaptedBases
- adaptedBases= setFirstTransformation(subBoundBaseMethodRedefinition);
- // [OT/Equinox] if class has previously been transformed fetch the list of
- // adapted bases from the CallinBindingManager instead of reading it now.
- if ( (cg.getAccessFlags() & OTConstants.TEAM) != 0
- && !AttributeReadingGuard.getInstanceForLoader(loader).iAmTheFirst(cg.getClassName()))
- {
- List<String> basesOfTeam = CallinBindingManager.getBasesPerTeam(cg.getClassName());
- if (basesOfTeam != null)
- adaptedBases.addAll(basesOfTeam);
- }
- subBoundBaseMethodRedefinition.doTransformInterface(jpe, cg);
- baseCallRedirection.doTransformInterface(jpe, cg);
- decapsulation.doTransformInterface(jpe, cg);
- try {
- baseMethodTransformation.useReflection = (loader == null); // bootstrap classes cannot be called directly
- baseMethodTransformation.doTransformInterface(jpe, cg);
- } catch (Throwable t) {
- System.err.println("Error transforming class: "+cg.getClassName());
- t.printStackTrace();
- }
- staticSliceBaseTransformation.doTransformInterface(jpe, cg);
- teamInterfaceImplementation.doTransformInterface(jpe, cg);
-
-// subBoundBaseMethodRedefinition.doTransformInterface(jpe, cg);
-// baseCallRedirection.doTransformInterface(jpe, cg);
-// decapsulation.doTransformInterface(jpe, cg);
-// baseMethodTransformation.doTransformInterface(jpe, cg);
-// staticSliceBaseTransformation.doTransformInterface(jpe, cg);
-// teamInterfaceImplementation.doTransformInterface(jpe, cg);
- threadActivation.doTransformInterface(jpe, cg);
-
-
-// baseCallRedirection.doTransformCode(cg); // empty method
- baseMethodTransformation.doTransformCode(cg);
- liftingParticipantTransformation.doTransformCode(cg);
- staticSliceBaseTransformation.doTransformCode(cg);
- teamInterfaceImplementation.doTransformCode(cg);
- threadActivation.doTransformCode(cg);
-
- JavaClass new_java_class = cg.getJavaClass();
- if (dumping) {
- new_java_class.dump("jplis_dump/" + className + ".class");
- }
- return new_java_class.getBytes();
- } catch (IOException e) {
- System.err.println("ClassFileTransformer could not parse class file buffer to JavaClass");
- e.printStackTrace();
- } catch (RuntimeException re) {
- re.printStackTrace();
- throw re;
- } finally {
- // restore previous repository:
- RepositoryAccess.resetRepository(prevRepository);
- }
- return null;
- }
-
- /**
- * External API (for OT/Equinox):
- * Destructively fetch the set of adapted base classes
- * recorded since the last call to this method.
- *
- * @return
- */
- public Collection<String> fetchAdaptedBases() {
- if (this.firstTransformation == null)
- return null;
- Collection<String>result= this.firstTransformation.fetchAdaptedBases();
- this.firstTransformation= null;
- return result;
- }
-
- /**
- * External API (for OT/Equinox):
- * Read the OT-Attributes of a class without loading the class.
- * @throws IOException
- * @throws ClassFormatError
- */
- public void readOTAttributes(InputStream file, String fileName, ClassLoader loader)
- throws ClassFormatError, IOException
- {
- ClassParser cp = new ClassParser(file, fileName);
- ClassGen cg = new ClassGen(cp.parse());
- JPLISEnhancer jpe = new JPLISEnhancer(cg, /*loader (unused)*/null);
- ClassLoaderRepository prevRepository = RepositoryAccess.setClassLoader(loader);
- try {
- setFirstTransformation(new ObjectTeamsTransformation(loader, null) {});
- firstTransformation.checkReadClassAttributes(jpe, cg, cg.getClassName(), cg.getConstantPool());
- } finally {
- RepositoryAccess.resetRepository(prevRepository);
- }
- }
-
- // helper structure for above:
- /* The first transformation performed holds the list of adapted bases. */
- private ObjectTeamsTransformation firstTransformation;
-
- /* @return the collection of adapted bases currently in use. */
- private Collection<String> setFirstTransformation(ObjectTeamsTransformation t) {
- if (this.firstTransformation != null)
- t.adaptedBases= this.firstTransformation.adaptedBases; // collect into existing
- this.firstTransformation= t;
- return t.adaptedBases;
- }
-
- // ------------------------------------------
- // ---------- Class file dumping: ----------------------
- // ------------------------------------------
- /** Initialized from property <tt>ot.dump</tt>. */
- static boolean dumping = false;
- static {
- if(System.getProperty("ot.dump")!=null)
- dumping = true;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/otreAgent.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/otreAgent.java
deleted file mode 100644
index ee6077f11..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/otreAgent.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2005-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: otreAgent.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.jplis;
-
-import java.lang.instrument.Instrumentation;
-
-/**
-*
-* @version $Id: otreAgent.java 23408 2010-02-03 18:07:35Z stephan $
-* @author Christine Hundt
-*/
-public class otreAgent {
-
- private static Instrumentation instCopy;
-// private static String optionsCopy;
-
- private static ObjectTeamsTransformer otTransformer;
-
- public static void premain(String options, Instrumentation inst) {
- instCopy = inst;
-// optionsCopy = options;
-
- // add all necessary transformers:
- otTransformer = new ObjectTeamsTransformer();
- instCopy.addTransformer(otTransformer);
-
- /* All future class definitions will be seen by the transformer,
- except definitions of classes upon which any registered transformer is dependent. */
- }
-
- public static Instrumentation getInstrumentation() {
- return instCopy;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AnnotationHelper.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AnnotationHelper.java
deleted file mode 100644
index 0b45daae6..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AnnotationHelper.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2009 Stephan Herrmann
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id$
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Stephan Herrmann - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
-import org.objectteams.ImplicitTeamActivation;
-
-import org.apache.bcel.classfile.Attribute;
-import org.apache.bcel.classfile.Unknown;
-import org.apache.bcel.generic.ConstantPoolGen;
-
-/**
- * Helper class for parsing / skipping runtime visible annotations.
- *
- * @author stephan
- * @since 1.4.0
- */
-public class AnnotationHelper {
-
- /**
- * Does any of the given attributes contain an {@link ImplicitTeamActivation} annotation?
- * @param attrs attributes to inspect
- * @param cpg constant pool for string lookup
- * @return true if an {@link ImplicitTeamActivation} annotation was found.
- */
- public static boolean containsImplicitActivationAttribute(Attribute[] attrs, ConstantPoolGen cpg) {
- if (attrs != null) {
- for (Attribute attr : attrs) {
- if (attr instanceof Unknown && ((Unknown)attr).getName().equals("RuntimeVisibleAnnotations")) {
- Unknown unknown = (Unknown) attr;
- byte[] bytes = unknown.getBytes();
- int len = ObjectTeamsTransformation.combineTwoBytes(bytes, 0);
- int i = 2;
- String[] names = new String[1];
- for (int n=0; n<len; n++) {
- i = ObjectTeamsTransformation.scanStrings(names, bytes, i, cpg);
- if ("Lorg/objectteams/ImplicitTeamActivation;".equals(names[0]))
- return true;
- i = skipNameValuePairs(bytes, i, names[0], cpg);
- }
- }
- }
- }
- return false;
- }
-
- private static int skipNameValuePairs(byte[] bytes, int i, String typeName, ConstantPoolGen cpg) {
- int numPairs = ObjectTeamsTransformation.combineTwoBytes(bytes, i);
- i+=2;
- for (int p=0; p<numPairs; p++)
- i = skipElementValue(bytes, i+2 /*skip name*/, typeName, cpg);
- return i;
- }
-
- private static int skipElementValue(byte[] bytes, int i, String typeName, ConstantPoolGen cpg) {
- short tag = bytes[i++];
- switch (tag) {
- case 'B': // byte
- case 'C': // char
- case 'D': // double
- case 'F': // float
- case 'I': // int
- case 'J': // long
- case 'S': // short
- case 'Z': // boolean
- case 's': // String
- case 'c': // Class
- i+=2; break;
- case 'e': // Enum constant
- i+=4; break;
- case '@': // Annotation
- String[] typeName2 = new String[1];
- i = ObjectTeamsTransformation.scanStrings(typeName2, bytes, i, cpg); // nested annotation type
- i = skipNameValuePairs(bytes, i, typeName2[0], cpg);
- break;
- case '[': // Array
- int numArrayVals = ObjectTeamsTransformation.combineTwoBytes(bytes, i);
- i+=2;
- for (int j = 0; j < numArrayVals; j++)
- i = skipElementValue(bytes, i, typeName, cpg);
- break;
- default:
- throw new RuntimeException("Unexpected element value kind in annotation: " + typeName);
- }
- return i;
- }
-
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java
deleted file mode 100644
index 4d72e02d8..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: AttributeReadingGuard.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Christine Hundt
- * @author Stephan Herrmann
- */
-public class AttributeReadingGuard {
-
- private static Map<ClassLoader, AttributeReadingGuard> instances = new HashMap<ClassLoader, AttributeReadingGuard>();
- private static AttributeReadingGuard defaultInstance = new AttributeReadingGuard();
-
- private ArrayList<String> servedClasses = new ArrayList<String>();
-
- // this one flag is really global (concerns the one main class of the application):
- private static boolean firstLoaded = true;
-
- /**
- * @param className
- * @return
- */
- public boolean iAmTheFirst(String className) {
- return !this.servedClasses.contains(className);
- }
-
- /**
- * Processing the given class is done.
- * @param className
- */
- public void workDone(String className) {
- this.servedClasses.add(className);
- }
-
- /**
- * @return whether this class is the first being loaded => possibly the main class.
- */
- public static synchronized boolean isFirstLoadedClass() {
- if (!firstLoaded)
- return false;
- firstLoaded = false;
- return true;
- }
-
- /** First loaded class has no main => it was a false alarm. */
- public static void reset() {
- firstLoaded = true;
- }
-
- /**
- * Since actual data are stored in an instance, static methods need to retrieve the appropriate
- * instance regarding the given class loader.
- */
- public static AttributeReadingGuard getInstanceForLoader(ClassLoader loader) {
- if (loader == null)
- return defaultInstance;
-
- AttributeReadingGuard instance = instances.get(loader);
- if (instance == null)
- instances.put(loader, instance = new AttributeReadingGuard());
- return instance;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundClass.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundClass.java
deleted file mode 100644
index 63bbb979e..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundClass.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id$
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-import java.util.HashSet;
-
-import org.apache.bcel.generic.ObjectType;
-
-/**
- * @version $Id: BoundClass.java,v 1.8 2006-12-19 21:31:30 stephan Exp $
- * @author Christine Hundt
- */
-public class BoundClass {
- private String name;
-
- private BoundClass _super;
- //private BoundClass _tsuper;
- private HashSet<String> adaptingTeams = new HashSet<String>();
-
- public BoundClass(String className, String teamName) {
- name = className;
- this.adaptingTeams.add(teamName);
- _super = null;
- }
-
- public String getName() {
- return name;
- }
-
- public boolean isAdaptedByTeam(String teamName) {
- return this.adaptingTeams.contains(teamName);
- }
-
- public void addAdaptingTeam(String teamName) {
- this.adaptingTeams.add(teamName);
- }
-
- public void setSuper(BoundClass superClass) {
- _super = superClass;
- }
-
- public BoundClass getSuper() {
- return _super;
- }
-
- public boolean isSubClassOf(String anotherClass) {
- BoundClass superClass = _super;
- while (superClass!=null) {
- if (superClass.getName().equals(anotherClass)) {
- return true;
- }
- superClass = superClass.getSuper();
- }
- return false;
- }
-
- public void updateSuper(BoundClass newSuperBaseClass, ObjectType newSuperBaseType) {
- // FIXME(SH): implement ;-)
- // test if newSuperBaseType is above or below _super.
- // also check if tsupers (i.e., more than one super) must be treated as well.
- }
-
-// public String toString() {
-// return name;
-// }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundMethod.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundMethod.java
deleted file mode 100644
index 4a4a8fbdc..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundMethod.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: BoundMethod.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-/**
- * @author Christine Hundt
- * @version $Id: BoundMethod.java 23408 2010-02-03 18:07:35Z stephan $
- */
-public class BoundMethod {
- private String name;
- private String signature;
- private boolean isCallin;
-
-// private MethodBinding binding;
-
- public BoundMethod(String methodName, String methodSignature, boolean isCallin, MethodBinding methodBinding) {
- name = methodName;
- signature = methodSignature;
- this.isCallin = isCallin;
-// binding = methodBinding;
- }
-
- public String getName() {
- return name;
- }
-
- public String getSignature() {
- return signature;
- }
-
- public boolean getIsCallin() {
- return this.isCallin;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/CallinBindingManager.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/CallinBindingManager.java
deleted file mode 100644
index 2ef71a958..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/CallinBindingManager.java
+++ /dev/null
@@ -1,1323 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: CallinBindingManager.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-//import org.apache.bcel.generic.Type; // just for javadoc.
-import org.apache.bcel.classfile.JavaClass;
-import org.apache.bcel.generic.ObjectType;
-
-import org.eclipse.objectteams.otre.OTREInternalError;
-import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
-import org.eclipse.objectteams.otre.RepositoryAccess;
-import org.eclipse.objectteams.otre.ObjectTeamsTransformation.BaseMethodInfo;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * @version $Id: CallinBindingManager.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Christine Hundt
- */
-@SuppressWarnings("nls")
-public class CallinBindingManager {
- // map of bindings for role classes: roleClassName -> RoleBaseBinding
- private static HashMap<String, RoleBaseBinding> roleBindings = new HashMap<String, RoleBaseBinding>();
-
- // map of bindings for base classes: baseClassName -> List[RoleBaseBinding]
- private static ListValueHashMap<RoleBaseBinding> baseBindings = new ListValueHashMap<RoleBaseBinding>();
-
- // maps a team to its handled bases: teamClassName -> List[BaseClassName]
- private static ListValueHashMap<String> basesPerTeam = new ListValueHashMap<String>();
-
- // maps a team to its contained roles: teamClassName -> List[RoleClassName]
- private static ListValueHashMap<String> rolesPerTeam = new ListValueHashMap<String>();
-
- /**
- * Add super-link of the BoundRole object for the RoleBaseBinding of 'className' to 'superClassName'.
- * @param className the name of the class for which to add the super-link
- * @param superClassName the name of the super class to be linked
- */
- public static void addSuperRoleLink(String className, String superClassName) {
- if (!roleBindings.containsKey(superClassName))
- return; // no super role class stored!
- RoleBaseBinding rbbSuper = roleBindings.get(superClassName);
- RoleBaseBinding rbb = roleBindings.get(className);
- // establish link from the role to its super role class:
- rbb.getRoleClass().setSuper(rbbSuper.getRoleClass());
- }
-
- /**
- * @param baseClassName
- */
- private static void addSuperBaseLink(String teamClassName, String baseClassName, RoleBaseBinding rbb)
- {
- BoundClass baseClass = rbb.getBaseClass();
- ObjectType baseClassType = new ObjectType(baseClassName);
- // clone the set for re-entrance:
- Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it = getBaseBindingsCloneIterator();
- while (it.hasNext()) {
- Entry<String, LinkedList<RoleBaseBinding>> entry = it.next();
- String currentBaseClassName = entry.getKey();
- if (currentBaseClassName.equals(baseClassName)) continue;
- ObjectType currentType = new ObjectType(currentBaseClassName);
- // BoundClass objects are unique per base object, so just take the first binding:
- BoundClass currentBaseClass = entry.getValue().getFirst().getBaseClass();
- if(RepositoryAccess.safeSubclassOf(baseClassType, currentType)) {
- BoundClass rbbSuper = baseClass.getSuper();
- if (rbbSuper != null) {
- if (rbbSuper.getName().equals(currentBaseClassName))
- continue; // no need for action: already set.
- baseClass.updateSuper(currentBaseClass, currentType);
- }
- baseClass.setSuper(currentBaseClass);
- }
- else if (RepositoryAccess.safeSubclassOf(currentType, baseClassType)) {
- BoundClass currentSuper = currentBaseClass.getSuper();
- // if sub base classes may be registered before super base class,
- // this case has to be considered too:
- if (currentSuper != null) {
- if (currentSuper.getName().equals(baseClassName))
- continue; // no need for action: already set.
- currentBaseClass.updateSuper(baseClass, baseClassType);
- }
- currentBaseClass.setSuper(baseClass);
- }
- }
- }
-
- /**
- * Declare role playedBy base.
- *
- * @param roleClassName the name of the played role class
- * @param baseClassName the name of the playing base class
- */
- public static void addRoleBaseBinding(String roleClassName, String baseClassName, String teamClassName) {
- RoleBaseBinding rbb = roleBindings.get(roleClassName);
- if (rbb == null) {
- rbb = new RoleBaseBinding(roleClassName, baseClassName, teamClassName);
- roleBindings.put(roleClassName, rbb);
- }
- addSuperBaseLink(teamClassName, baseClassName, rbb);
- synchronized (baseBindings) {
- baseBindings.put(baseClassName, rbb);
- }
- addTeamRoleRelation(teamClassName, roleClassName);
- }
-
- /**
- * @param teamClassName
- * @param baseClassName
- */
- public static void addTeamBaseRelation(String teamClassName, String baseClassName) {
- JavaClass baseClass = null;
- try {
- baseClass = RepositoryAccess.lookupClass(baseClassName);
- } catch (ClassNotFoundException e) {
- // FIXME(SH): where to log?
- e.printStackTrace();
- }
- if (baseClass != null && baseClass.isInterface()) {
- // TODO (SH): need to register with all implementing classes!
- if (logging) {
- ObjectTeamsTransformation.printLogMessage("*** Skipping base " + baseClassName + ": is an interface");
- ObjectTeamsTransformation.printLogMessage("Classses implementing the interface " + baseClassName + " have to be transformed!");
- }
- addBoundBaseInterface(baseClassName);
- } else {
- List<String> bases = basesPerTeam.get(teamClassName);
- if (bases==null || !bases.contains(baseClassName))
- basesPerTeam.put(teamClassName, baseClassName);
- }
- }
-
- /**
- * @param teamClassName
- * @return
- */
- public static List<String> getBasesPerTeam(String teamClassName) {
- // (PH): return empty list instead of null when team has no bases?
- return basesPerTeam.get(teamClassName);
- }
-
- /**
- * @param teamClassName
- * @param roleClassName
- */
- public static void addTeamRoleRelation(String teamClassName, String roleClassName) {
- List<String> roles = rolesPerTeam.get(teamClassName);
- if (roles == null || !roles.contains(roleClassName))
- rolesPerTeam.put(teamClassName, roleClassName);
- }
-
- /**
- * @param teamClassName
- * @return
- */
- public static List<String> getRolePerTeam(String teamClassName) {
- return rolesPerTeam.get(teamClassName);
- }
-
- private static LinkedList<String> allRoles = new LinkedList<String>();
-
- /**
- * @param roleName
- */
- public static void addRole(String roleName) {
- allRoles.add(roleName);
- }
-
- /**
- * @param roleName
- * @return
- */
- public static boolean isRole(String roleName) {
- return allRoles.contains(roleName);
- }
-
-
- /**
- * Declare binding of a pair of methods.
- * @param roleClassName
- * @param bindingFileName TODO
- * @param bindingLineNumber TODO
- * @param bindingLineOffset TODO
- * @param roleMethodName
- * @param roleMethodSignature signature ready for interpretation by
- * {@link Type org.apache.bcel.generic.Type}
- * @param isStaticRoleMethod TODO
- * @param modifier "before", "after" or "replace"
- * @param baseMethodName
- * @param baseMethodSignature
- * @param isStaticBaseMethod is the base method static?
- * @param baseIsCallin is the base method a callin method?
- * @param translationFlags one bit for the result and for each argument indicating whether lifting/lowering is needed
- * @param liftMethodName
- * @param liftMethodSignature
- */
- public static void addMethodBinding(
- String roleClassName, String baseClassName,
- String bindingFileName, int bindingLineNumber, int bindingLineOffset,
- String bindingLabel, String roleMethodName, String roleMethodSignature, boolean isStaticRoleMethod,
- String wrapperName, String wrapperSignature, String modifier,
- String baseMethodName, String baseMethodSignature,
- boolean isStaticBaseMethod, boolean baseIsCallin, boolean covariantBaseReturn,
- int translationFlags, String liftMethodName, String liftMethodSignature)
- {
- RoleBaseBinding rbb = roleBindings.get(roleClassName);
- if (rbb == null) {
- // no binding found, create it now:
- if (baseClassName == null)
- throw new OTREInternalError("PlayedBy attribute must be read before method bindings.");
- int lastDollar = roleClassName.lastIndexOf('$');
- String teamClassName = roleClassName.substring(0, lastDollar);
- rbb = new RoleBaseBinding(roleClassName, baseClassName, teamClassName);
- roleBindings.put(roleClassName, rbb);
- }
- //System.err.println(rbb.getRoleClass().getName()+"<-*->"+rbb.getBaseClass().getName());
- rbb.addMethodBinding(bindingFileName, bindingLineNumber, bindingLineOffset,
- bindingLabel, roleMethodName, roleMethodSignature, isStaticRoleMethod,
- wrapperName, wrapperSignature, modifier,
- baseMethodName, baseMethodSignature,
- isStaticBaseMethod, baseIsCallin, covariantBaseReturn,
- translationFlags,
- liftMethodName, liftMethodSignature);
-
- if (modifier.equals("replace"))
- assignBaseCallTag(rbb.getBaseClassName(), baseMethodName, baseMethodSignature);
- }
-
- /**
- * Get all callin bindings for a given base method.
- * @param className the base class
- * @param methodName the base method
- * @return Collection of <pre>MethodBinding</pre>
- */
- public static Collection<MethodBinding> getBindingForBaseMethod(String baseClassName, String baseMethodName, String baseMethodSignature)
- {
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
- LinkedList<MethodBinding> resultList = new LinkedList<MethodBinding>();
- if (rbbList != null) {
- Iterator<RoleBaseBinding> it = rbbList.iterator();
- while (it.hasNext()) {
- RoleBaseBinding rbb = it.next();
- List<MethodBinding> mbs = rbb.getBaseMethodBindings(baseMethodName, baseMethodSignature);
- if (mbs != null)
- addFiltered(resultList, mbs, baseMethodName, baseMethodSignature);
- }
- }
- // IMPLICIT_INHERITANCE
- addFiltered(resultList,
- getImplicitlyInheritedBaseMethodBindings(baseClassName, baseMethodName, baseMethodSignature),
- baseMethodName,
- baseMethodSignature);
- if (resultList.isEmpty())
- return null;
- return resultList;
- }
- /** variant of the above, optimized for computing only a boolean result instead of a complete list. */
- public static boolean isBoundBaseMethod(String baseClassName, String baseMethodName, String baseMethodSignature)
- {
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
- if (rbbList != null) {
- for (RoleBaseBinding rbb : rbbList) {
- List<MethodBinding> mbs = rbb.getBaseMethodBindings(baseMethodName, baseMethodSignature);
- if (mbs != null)
- for (MethodBinding mb : mbs)
- if (mb.matchesMethod(baseMethodName, baseMethodSignature, /* strict */ true))
- return true;
- }
- }
- // IMPLICIT_INHERITANCE
- for (MethodBinding mb : getImplicitlyInheritedBaseMethodBindings(baseClassName, baseMethodName, baseMethodSignature))
- if (mb.matchesMethod(baseMethodName, baseMethodSignature, /* strict */ true))
- return true;
- return false;
- }
- // add bindings from candidates to resultList, perhaps checking
- // full signatures (i.e., if not covariantBaseReturn).
- private static void addFiltered(Collection<MethodBinding> resultList,
- Collection<MethodBinding> candidates,
- String name,
- String fullSignature)
- {
- for (MethodBinding methodBinding : candidates)
- if (methodBinding.matchesMethod(name, fullSignature, /*strict*/false))
- resultList.add(methodBinding);
- }
-
- /**
- * Gets all implicitly inherited method bindings for the given base method.
- * Note: the result can only contain elements for base classes which are
- * roles at the same time!
- * @param baseClassName the name of the base class
- * @param baseMethodName the name of the base mehtod
- * @param baseMethodSignature the descriptor or the base method signature
- * @return a Collection with all implicitly inherited method bindings
- */
- private static Collection<MethodBinding> getImplicitlyInheritedBaseMethodBindings(String baseClassName, String baseMethodName, String baseMethodSignature) {
- List<MethodBinding> resultList = new LinkedList<MethodBinding>();
-
- if (!isRole(baseClassName))
- return resultList; // only roles can have implicit super types
-
- Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it = getBaseBindingsCloneIterator();
-
- while (it.hasNext()) {
- Entry<String, LinkedList<RoleBaseBinding>> entry = it.next();
- String have = entry.getKey();
- // look for true superClass (not same):
- if (have.equals(baseClassName))
- continue;
- if (isImplicitSubtype(baseClassName, have)) {
- // now we have an implicit superClass:
- if (logging)
- ObjectTeamsTransformation.printLogMessage(baseClassName
- + " implicitly inherits callin bindings from " + have);
- // collect the signatures of all bound base methods:
- List<RoleBaseBinding> rbbList = entry.getValue();
- if (rbbList != null) {
- Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
- while (rbb_it.hasNext()) {
- RoleBaseBinding rbb = rbb_it.next();
- List<MethodBinding> mbs = rbb.getBaseMethodBindings(baseMethodName, baseMethodSignature);
- if (mbs != null)
- resultList.addAll(mbs);
- }
- }
- }
- }
- //if (!resultList.isEmpty())
- // System.err.println(resultList);
- return resultList;
- }
-
- /**
- * Get all callin bindings that a given base class may inherit from its superclass.
- * @param className
- * @result list of MethodBinding
- */
- public static Collection<MethodBinding> getInheritedCallinBindings (String className) {
-/*
- List classBindings = baseBindings.get(className);
- if (classBindings!=null) {
- // any RoleBaseBinding contains the corresponding BoundClass object for the super base:
- RoleBaseBinding anyRBB = (RoleBaseBinding)classBindings.get(0);
- // problem: if a sub base class is not explicitly bound to a role class no corresponding
- // BoundClass object exists. How can we access the super bindings via the
- // super-link??
- BoundClass bc = anyRBB.getBaseClass();
- //System.out.println("-----------");
- while (bc.getSuper()!=null) {
- System.out.println(bc.getName());
- bc = bc.getSuper();
- }
- //System.out.println("-----------");
- }
-*/
-
- List<MethodBinding> result = new LinkedList<MethodBinding>();
- ObjectType current = new ObjectType(className);
- // clone for re-entrance:
- Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it= getBaseBindingsCloneIterator();
- while (it.hasNext()) {
- Entry<String, LinkedList<RoleBaseBinding>> entry = it.next();
- String have = entry.getKey();
- // look for true superClass (not same):
- if (have.equals(className)) continue;
- ObjectType haveType = new ObjectType(have);
- if (RepositoryAccess.safeSubclassOf(current, haveType)) {
- // now we have a true superClass:
- if (logging)
- ObjectTeamsTransformation.printLogMessage(className
- + " inherits callin bindings from " + have);
- // collect the signatures of all bound base methods:
- List<RoleBaseBinding> rbbList = entry.getValue();
- if (rbbList != null) {
- Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
- while (rbb_it.hasNext()) {
- RoleBaseBinding rbb = rbb_it.next();
- result.addAll(rbb.getBaseMethodBindings());
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Get all super classes defining callin bindings that a given static base
- * method may inherit.
- *
- * @author juerwid
- * @param className
- * @param methodName
- * @param methodSignaturte
- * @result list of <String[] {class_name}>
- */
- public static Collection<String> getInheritedCallinBindingsForStaticMethods(
- String className, String methodName, String methodSignature)
- {
- List<String> result = new LinkedList<String>();
- ObjectType current = new ObjectType(className);
- // clone for re-entrance:
- Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it = getBaseBindingsCloneIterator();
- boolean getNextClass = false;
- while (it.hasNext()) {
- Entry<String,LinkedList<RoleBaseBinding>> entry = it.next();
- String have = entry.getKey();
- // look for true superClass (not same):
- if (have.equals(className)) continue;
- ObjectType haveType = new ObjectType(have);
- if (RepositoryAccess.safeSubclassOf(current, haveType)) {
- // now we have a true superClass:
- if (logging)
- ObjectTeamsTransformation.printLogMessage(className
- + " inherits callin bindings from " + have);
- // collect the signatures of all bound base methods:
- LinkedList<RoleBaseBinding> rbbList = entry.getValue();
- if (rbbList != null) {
- Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
- while (rbb_it.hasNext() && !getNextClass) {
- RoleBaseBinding rbb = rbb_it.next();
- List<String[]> methods = rbb.getBaseSignatures();
- Iterator<String[]> methodsIter = methods.iterator();
- while(methodsIter.hasNext() && !getNextClass){
- String[] aMethod = methodsIter.next();
- if(methodName.equals(aMethod[0]) && methodSignature.equals(aMethod[1])){
- result.add(have);
- getNextClass = true;
- }
- }
- }
- if(getNextClass){
- getNextClass = false;
- continue;
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Checks if 'subType' is an implicit subtype of 'superType'.
- * To be true the role name parts have to be equal and the
- * team name parts have to be in a 'real' subtype relationship.
- *
- * @param subType the name of the potential subtype.
- * @param superType the name of the potential supertype.
- * @return true, if subType implicitly inherits from superType.
- */
- private static boolean isImplicitSubtype(String subType, String superType) {
- //System.err.println(subType +" -?-> " + superType);
- int dollarIdxSub = subType.lastIndexOf('$');
- int dollarIdxSuper = superType.lastIndexOf('$');
- if (dollarIdxSub==-1 || dollarIdxSuper==-1)
- return false; // no roles
- String pureSubType = subType.substring(dollarIdxSub+1, subType.length());
- String pureSuperType = superType.substring(dollarIdxSuper+1, superType.length());
- if (!pureSubType.equals(pureSuperType))
- return false;// no identical role names
-
- String subTeamName = subType.substring(0, dollarIdxSub);
- String superTeamName = superType.substring(0,dollarIdxSuper);
-
- ObjectType subTeamType = new ObjectType(subTeamName);
- ObjectType superTeamType = new ObjectType(superTeamName);
- if (RepositoryAccess.safeSubclassOf(subTeamType, superTeamType)) {
- if (logging)
- ObjectTeamsTransformation.printLogMessage(subType
- + " implicitly inherits method bindings from " + superType);
- //System.err.println(subType + " implicitly inherits method bindings from " + superType);
- return true;
- }
- return false; // no inheritance relation between teams
- }
-
- /**
- * Get all inherited method bindings for a given base method, which are
- * bindings declared for a super base class.
- *
- * the actual base class has additional bindings for this method!
- * @param baseClassName the name of the role class
- * @param baseMethodName the name of the role method
- * @param baseMethodSignature the signature of the role method
- * @result a List containing all inherited bindings for the role method
- */
- public static List<MethodBinding> getInheritedBaseMethodBindings(String baseClassName, String baseMethodName, String baseMethodSignature) {
-
- List<MethodBinding> inheritedMethodBindings = new LinkedList<MethodBinding>();
- if (!isBoundBaseClass(baseClassName)) {
- return inheritedMethodBindings;
- }
- LinkedList<RoleBaseBinding> baseBindingsForBase = baseBindings.get(baseClassName);
- if (baseBindingsForBase == null)
- return inheritedMethodBindings;
-
- Iterator<RoleBaseBinding> it = baseBindingsForBase.iterator();
- while (it.hasNext()) {
- RoleBaseBinding rbb = it.next();
- BoundClass bc = rbb.getBaseClass();
- while (bc.getSuper() != null) {
- bc = bc.getSuper();
- String superRoleName = bc.getName();
- Collection<MethodBinding> superRoleMethodBindings = CallinBindingManager.getBindingForBaseMethod(
- superRoleName,
- baseMethodName,
- baseMethodSignature);
- if (superRoleMethodBindings!=null)
- inheritedMethodBindings.addAll(superRoleMethodBindings);
- }
- }
- return inheritedMethodBindings;
- }
-
- /**
- * Get all inherited method bindings for a given role method, which are
- * bindings declared in a super role class. The actual role class has
- * additional bindings for this method!
- *
- * @param roleClassName the name of the role class
- * @param roleMethodName the name of the role method
- * @param roleMethodSignature the signature of the role method
- * @result a List containing all inherited bindings for the role method
- */
- public static List<MethodBinding> getInheritedRoleMethodBindings(String roleClassName, String roleMethodName, String roleMethodSignature) {
- List<MethodBinding> inheritedMethodBindings = new LinkedList<MethodBinding>();
- if (!isBoundRoleClass(roleClassName)) {
- return inheritedMethodBindings;
- }
- RoleBaseBinding rbb = roleBindings.get(roleClassName);
- BoundClass bc = rbb.getRoleClass();
- while (bc.getSuper() != null) {
- bc = bc.getSuper();
- String superRoleName = bc.getName();
- List<MethodBinding> superRoleMethodBindings = CallinBindingManager.getBindingsForRoleMethod(
- superRoleName,
- roleMethodName,
- roleMethodSignature);
- inheritedMethodBindings.addAll(superRoleMethodBindings);
- }
- return inheritedMethodBindings;
- }
-
- /**
- * All bindings for a given role method concerning its base class.
- *
- * @return List of MethodBinding
- */
- public static List<MethodBinding> getBindingsForRoleMethod(String roleClassName,
- String roleMethodName, String roleMethodSignature)
- {
- RoleBaseBinding rbb = roleBindings.get(roleClassName);
- if (rbb==null) {
- return new LinkedList<MethodBinding>();
- }
- List<MethodBinding> roleMethodBindings = rbb.getRoleMethodBindings(roleMethodName, roleMethodSignature);
- if (roleMethodBindings == null) {
- return new LinkedList<MethodBinding>();
- }
- return roleMethodBindings;
- }
-
- /**
- * @param className
- * @return
- */
- public static boolean isBoundBaseClass(String className) {
- // and has at least one method binding?
- boolean result = baseBindings.containsKey(className);
- if (result || !isRole(className)) {
- return result;
- }
- else {// bound implicit super class?
- Iterator<String> it = getBaseBindingsKeyIterator();
- while (it.hasNext()) {
- String have = it.next();
- // look for true superClass (not same):
- if (have.equals(className))
- continue;
- if (isImplicitSubtype(className, have))
- return true;
- }
- return result;
- }
- }
-
- /**
- * @param className
- * @return
- */
- public static boolean isBoundBaseAndRoleClass(String className) {
- // and has at least one method binding?
- if (baseBindings.containsKey(className))
- return true;
- // bound implicit super class?
- Iterator<String> it = getBaseBindingsKeyIterator();
- while (it.hasNext()) {
- String have = it.next();
- // look for true superClass (not same):
- if (have.equals(className))
- continue;
- if (isImplicitSubtype(className, have))
- return true;
- }
- return false;
- }
-
- /**
- * @param baseClassName
- * @return
- */
- public static boolean hasBoundBaseParent(String baseClassName) {
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
- if (rbbList != null) {
- Iterator<RoleBaseBinding> it = rbbList.iterator();
- while (it.hasNext()) {
- RoleBaseBinding rbb = it.next();
- if (rbb.getBaseClass().getSuper()!=null)
- return true;
- }
- }
- // IMPLICIT_INHERITANCE
- //if (isUnboundSubBase(baseClassName))
- // return true;
- return false;
- }
-
-
- /**
- * Returns the name of the topmost bound base class.
- *
- * @param baseClassName
- * @return
- */
- public static String getTopmostBoundBase(String baseClassName) {
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
- if (rbbList != null) {
- // assumption: EVERY BoundClass object has been connected to its bound super classes.
- RoleBaseBinding anyRBB = rbbList.get(0);
- BoundClass bc = anyRBB.getBaseClass();
- while (bc.getSuper() != null) {
- bc = bc.getSuper();
- }
- return bc.getName();
- }
- return baseClassName;
- }
-
- /**
- * @param baseClassName
- * @return
- */
- public static String getBoundBaseParent(String baseClassName) {
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
- if (rbbList != null) {
- Iterator<RoleBaseBinding> it = rbbList.iterator();
- while (it.hasNext()) {
- RoleBaseBinding rbb = it.next();
- BoundClass bc = rbb.getBaseClass().getSuper();
- if (bc!=null)
- return bc.getName();
- }
- }
- // IMPLICIT_INHERITANCE
- //if (isUnboundSubBase(baseClassName))
- // return true;
- return null;
- }
-
- /**
- * @param teamClassName
- * @param baseClassName
- * @return
- */
- public static boolean teamAdaptsSuperBase(String teamClassName, String baseClassName) {
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
- if (rbbList != null && !rbbList.isEmpty()) {
- RoleBaseBinding rbb = rbbList.getFirst(); // all entries refer to the same base class.
- BoundClass bc = rbb.getBaseClass().getSuper();
- while (bc!=null) {
- if (bc.isAdaptedByTeam(teamClassName))
- return true;
- bc = bc.getSuper();
- }
- }
- return false;
- }
-
- /**
- * @param baseClassName
- * @return
- */
-// private static boolean isUnboundSubBase(String baseClassName) {
-// ObjectType current = new ObjectType(baseClassName);
-// if (!checkLookup(current.getClassName())) // TODO: workaround for classes loaded from special locations
-// return false;
-// Iterator /* String */ it = baseBindings.keySet().iterator();
-// while (it.hasNext()) {
-// String have = (String)it.next();
-// // look for true superClass (not same):
-// if (have.equals(baseClassName)) continue;
-// ObjectType haveType = new ObjectType(have);
-// //System.err.println(current + " : "+haveType);
-// //System.err.println(org.apache.bcel.Repository.lookupClass(have));
-// if (!checkLookup(haveType.getClassName())) // TODO: workaround for classes loaded from special locations
-// continue;
-// if (current.subclassOf(haveType)) {
-// return true;
-// }
-// }
-// return false;
-// }
-
- /**
- * @param className
- * @return
- */
- public static boolean isBoundRoleClass(String className) {
- return roleBindings.containsKey(className);
- }
-
- /**
- * @param className
- * @return
- */
- public static RoleBaseBinding getRoleBaseBinding(String roleClassName) {
- return roleBindings.get(roleClassName);
- }
-
- /**
- * @param roleClassName
- * @return
- */
- public static List<MethodBinding> getMethodBindingsForRoleClass(String roleClassName)
- {
- RoleBaseBinding rbb = roleBindings.get(roleClassName);
- return rbb.getRoleMethodBindings();
- }
-
- /**
- * @param roleClassName
- * @return
- */
- public static Set<String> getBoundRoleMethods(String roleClassName) {
- Set<String> roleMethodKeySet = new HashSet<String>();
- if (roleBindings.get(roleClassName) != null) {
- RoleBaseBinding rbb = roleBindings.get(roleClassName);
- roleMethodKeySet = rbb.getRoleMethodSignatures();
- }
- return roleMethodKeySet;
- }
-
- /**
- * @param baseClassName
- * @return
- */
- public static List<MethodBinding> getMethodBindingsForBaseClass(String baseClassName)
- {
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
- LinkedList<MethodBinding> resultList = new LinkedList<MethodBinding>();
- if (rbbList != null) {
- Iterator<RoleBaseBinding> it = rbbList.iterator();
- while (it.hasNext()) {
- RoleBaseBinding rbb = it.next();
- resultList.addAll(rbb.getRoleMethodBindings());
- }
- }
- return resultList;
- }
-
- // --------------------------------------------------
- // discriminate base methods by tag per callin
- // --------------------------------------------------
- // baseClass.baseMeth.baseMethodSignature -> tag
- private static HashMap<String, Integer> baseCallTags = new HashMap<String, Integer>();
- // -- follow access methods for baseCallTags:
-
- /**
- * @param baseClass
- * @param baseMeth
- * @param baseMethodSignature
- */
- public static void assignBaseCallTag (String baseClass, String baseMeth,
- String baseMethodSignature)
- {
- // every base method bound by a replace callin gets an unique tag:
- String key = baseClass+"."+baseMeth+"."+baseMethodSignature;
- int tag = baseCallTags.size();
- if (!baseCallTags.containsKey(key))
- baseCallTags.put(key, Integer.valueOf(tag));
- }
-
- public static int getBaseCallTag (String base_class_name,
- String base_method_name,
- String base_method_signature) {
- String key = base_class_name + "." + base_method_name
- + "." + base_method_signature;
- return baseCallTags.get(key).intValue();
- }
-
- // ----------------------------------------------
- // Map argument positions:
- // ----------------------------------------------
- // teamName -> callinWrapperName -> int[]
- private static HashMap<String, HashMap<String, int[]>> paramMappings = new HashMap<String, HashMap<String, int[]>>();
- // -- follow access methods for paramMappings:
-
- /**
- * @param teamName
- * @param methodWrapper
- * @param positions
- */
- public static void addParameterBinding (String teamName,
- String methodWrapper,
- int[] positions) {
- HashMap<String, int[]> teamMap = paramMappings.get(teamName);
- if (teamMap == null) {
- teamMap = new HashMap<String, int[]>();
- paramMappings.put(teamName, teamMap);
- }
- teamMap.put(methodWrapper, positions);
- }
-
- public static boolean hasParamMappings (String teamName, String methodWrapper)
- {
- HashMap<String,int[]> teamMap = paramMappings.get(teamName);
- if (teamMap == null) return false;
- return teamMap.containsKey(methodWrapper);
- }
-
- /** Get parameter positions for the given team or any super team. */
- public static int[] getParamPositions (String teamName, String methodWrapper)
- {
- int[] positions = getExactParamPositions(teamName, methodWrapper);
- if (positions != null)
- return positions;
- // inherit parameter mappings from super teams: -- >>
- Iterator<String> superTeams = getSuperTeamsWithParamMappigs(teamName).iterator();
- while (superTeams.hasNext()) {
- positions = getExactParamPositions(superTeams.next(), methodWrapper);
- if (positions != null) // found (the!) parameter mapping
- return positions;
- }
- return null;
- }
- /** Get parameter positions for exactly the given team (no super teams). */
- private static int[] getExactParamPositions(String teamName, String methodWrapper) {
- HashMap<String,int[]>teamMap = paramMappings.get(teamName);
- if (teamMap == null)
- return null;
- return teamMap.get(methodWrapper);
- }
-
- private static List<String> getSuperTeamsWithParamMappigs(String teamName) {
- LinkedList<String> result = new LinkedList<String>();
- try {
- for (JavaClass superTeam : RepositoryAccess.getSuperClasses(teamName))
- if (paramMappings.get(superTeam.getClassName()) != null)
- result.add(superTeam.getClassName());
- } catch (ClassNotFoundException e) {
- // FIXME(SH): where to log to?
- e.printStackTrace();
- // continue, just nothing added to result
- }
- return result;
- }
-
- // -----------------------------------------------
- // callout bindings that require adjustment:
- // -----------------------------------------------
- // baseClass -> HashSet (method_name+signature)
- private static HashMap<String, HashSet<String>> calloutBindings = new HashMap<String, HashSet<String>>();
-
- /**
- * @param clazz
- * @param meth
- * @param sign
- */
- public static void addCalloutBinding(String clazz, String meth, String sign) {
- HashSet<String> bindings = calloutBindings.get(clazz);
- if (bindings == null) {
- bindings = new HashSet<String>();
- calloutBindings.put(clazz, bindings);
- }
- bindings.add(meth + sign);
- }
-
- /**
- * @param clazz
- * @return
- */
- public static HashSet<String> getCalloutBindings (String clazz) {
- return calloutBindings.get(clazz);
- }
-
- /**
- * @param bindings
- * @param method_name
- * @param signature
- * @return
- */
- public static boolean requiresCalloutAdjustment(HashSet<String> bindings,
- String method_name,
- String signature)
- {
- return bindings.contains(method_name+signature);
- }
-
- // -----------------------------------------------
- // callouts to base class fields are stored here for furher reading and get/set method generation:
- // -----------------------------------------------
- private static ListValueHashMap<FieldDescriptor> calloutSetFields = new ListValueHashMap<FieldDescriptor>();
- private static ListValueHashMap<FieldDescriptor> calloutGetFields = new ListValueHashMap<FieldDescriptor>();
-
-
- /**
- * @param roleClassName
- * @param fieldName
- * @param fieldSignature
- * @param accessMode
- * @param isStaticField
- */
- public static void addCalloutBoundFileds(String baseClassName, String fieldName,
- String fieldSignature, String accessMode, boolean isStaticField)
- {
- FieldDescriptor fd = new FieldDescriptor(fieldName, fieldSignature, isStaticField);
-
- if (accessMode.equals("get")) {
- calloutGetFields.put(baseClassName, fd);
- } else if (accessMode.equals("set")) {
- calloutSetFields.put(baseClassName, fd);
- } else {
- throw new OTREInternalError("CalloutFieldAccess attribute contains wrong access mode: "+accessMode);
- }
- }
-
- /**
- * @param baseClassName
- * @return
- */
- public static List<FieldDescriptor> getCalloutGetFields(String baseClassName) {
- return calloutGetFields.get(baseClassName);
- }
-
- /**
- * @param baseClassName
- * @return
- */
- public static List<FieldDescriptor> getCalloutSetFields(String baseClassName) {
- return calloutSetFields.get(baseClassName);
- }
-
- // -----------------------------------------------
- // base calls to super methods via special accessor
- // -----------------------------------------------
- private static ListValueHashMap<SuperMethodDescriptor> superMethods = new ListValueHashMap<SuperMethodDescriptor>();
-
- public static void addSuperAccess(String baseClassName, String superClassName, String methodName, String signature) {
- SuperMethodDescriptor superMethod = new SuperMethodDescriptor(methodName, baseClassName, superClassName, signature);
- superMethods.put(baseClassName, superMethod);
- }
- public static List<SuperMethodDescriptor> getSuperAccesses(String class_name) {
- return superMethods.get(class_name);
- }
-
- // -----------------------------------------------
- // bound interfaces have to be registered, for implementing classes to inherit callin bindings:
- // -----------------------------------------------
- private static List<String> boundBaseInterfaces = new LinkedList<String>();
-
- /**
- * @param baseInterfaceName The name of the bound base interface.
- */
- public static void addBoundBaseInterface(String baseInterfaceName) {
- if (!boundBaseInterfaces.contains(baseInterfaceName))
- boundBaseInterfaces.add(baseInterfaceName);
- }
-
- /**
- * @param interfaceName
- * @return
- */
- public static Collection<String[]> getInterfaceInheritedCallinBindings(String interfaceName) {
- List<String[]> result = new LinkedList<String[]>();
- //System.err.println(interfaceName);
- //System.err.println(boundBaseInterfaces);
- if (boundBaseInterfaces.contains(interfaceName)) {
- if (logging)
- ObjectTeamsTransformation.printLogMessage(interfaceName
- + " bequests callin bindings to implementing class");
- // collect the signatures of all bound base methods:
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(interfaceName);
- if (rbbList != null) {
- Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
- while (rbb_it.hasNext()) {
- RoleBaseBinding rbb = rbb_it.next();
- result.addAll(rbb.getBaseSignatures());
-
- // System.err.println("inheriting binding: "+rbb);
- }
- }
- }
- return result;
- }
-
- /**
- * @param methodName
- * @param methodSignature
- * @param interfaceName
- * @return
- */
- public static Collection<MethodBinding> getInterfaceInheritedMethodBindings(
- String methodName, String methodSignature, String interfaceName) {
- List<MethodBinding> result = new LinkedList<MethodBinding>();
- if (boundBaseInterfaces.contains(interfaceName)) {
- LinkedList<RoleBaseBinding> rbbList = baseBindings.get(interfaceName);
- if (rbbList != null) {
- Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
- while (rbb_it.hasNext()) {
- RoleBaseBinding rbb = rbb_it.next();
- List<MethodBinding> mbs = rbb.getBaseMethodBindings(methodName, methodSignature);
- if (mbs != null)
- result.addAll(mbs);
- }
- }
- }
- return result;
- }
-
- /**
- * @param interfaceNames
- * @return
- */
- public static boolean containsBoundBaseInterface(String[] interfaceNames) {
- for (int i = 0; i < interfaceNames.length; i++) {
- if (boundBaseInterfaces.contains(interfaceNames[i]))
- return true;
- }
- return false;
- }
-
- // -----------------------------------------------
- // precedence can be set for a list of method bindings:
- // -----------------------------------------------
-
- private static ListValueHashMap<List<String>> precedencePerTeam = new ListValueHashMap<List<String>>();
-
- /**
- * Add a precedence list for the given team.
- * @param precedenceList the list of binding labels defining their precedence
- * @param teamName the name of the team for which the precedence list was defined
- */
- public static void addPrecedenceList(List<String> precedenceList, String teamName) {
- precedencePerTeam.put(teamName, precedenceList);
- }
-
- /**
- * Sorts the method binding list according to the given precedence for the team
- * @param mbList the list of 'MethodBinding's to be sorted
- * @param teamName the name of the corresponding team
- * @return the sorted 'MethodBindig' list
- */
- public static List<MethodBinding> sortMethodBindings(List<MethodBinding> mbList, String teamName) {
- if (mbList.size() < 2)
- return mbList; // nothing to sort
- String outermostTeamName;
- int dollarIdx = teamName.indexOf('$');
- if (dollarIdx > 0)
- outermostTeamName = teamName.substring(0, dollarIdx);
- else outermostTeamName = teamName;
-
- List<List<String>> precedenceList = precedencePerTeam.get(outermostTeamName);
- if (precedenceList==null) {
- // mbList has to be reduced by removing overridden bindings:
- return removeOverridden(mbList);
- }
-
- LinkedList<MethodBinding> sortedMethodBindings = new LinkedList<MethodBinding>();
- Iterator<List<String>> predIt = precedenceList.iterator();
-
- while (predIt.hasNext()) {
- List<String> plainList = predIt.next();
- Iterator<String> plainIt = plainList.iterator();
-
- while (plainIt.hasNext()) {
- boolean foundOne = false;
- String label = plainIt.next();
- Iterator<MethodBinding> mbIter = mbList.iterator();
- List<MethodBinding> alreadySorted = new LinkedList<MethodBinding>();
-
- while (mbIter.hasNext()) {
- MethodBinding mb = mbIter.next();
-
- if (mb.getQualifiedBindingLabel().equals(label)) { // mb exactly fits binding label:
- alreadySorted.add(mb);
- if (!foundOne) {
- sortedMethodBindings.add(mb);
- foundOne = true;
- } else checkInheritance(sortedMethodBindings.getLast(), mb);
-
- } else if (mb.inheritsBindingLabel(label, teamName)) { // mb inherits binding label:
- alreadySorted.add(mb);
- if (!foundOne) {
- sortedMethodBindings.add(mb);
- foundOne = true;
- } else {// maybe it is a subtype of the already added?
- MethodBinding lastAdded = sortedMethodBindings.getLast();
- if (mb.overridesMethodBinding(lastAdded)) {
- sortedMethodBindings.set(sortedMethodBindings.size()-1, mb);
- foundOne = true;
- } else checkInheritance(sortedMethodBindings.getLast(), mb);
- }
- }
- }
- if (foundOne) {
- Iterator<MethodBinding> sortedIter = alreadySorted.iterator();
- while (sortedIter.hasNext()) {
- MethodBinding mb = sortedIter.next();
- mbList.remove(mb);
- }
- }
- }
- }
-// if (mbList.size() > 0) {
-// System.err.println("ERROR: Unsortable method bindings: " + mbList +"!");
-// // assumption: all remaining method bindings are overridden! TODO: check assumption!
-// }
- return sortedMethodBindings;
- }
-
- /**
- * Removes overridden method bindings from the given list. Assumes that
- * all bindings in the list are in a sub/super type relationship.
- * @param mbList the method binding list
- * @return the most specific method binding overriding all others
- */
- private static List<MethodBinding> removeOverridden(List<MethodBinding> mbList) {
- MethodBinding mostSpecificMB = mbList.get(0);
- Iterator<MethodBinding> mbIter = mbList.iterator();
- while (mbIter.hasNext()) {
- MethodBinding mb = mbIter.next();
- if (mb.overridesMethodBinding(mostSpecificMB)) {
- mostSpecificMB = mb;
- } else checkInheritance(mostSpecificMB, mb);
- }
- List<MethodBinding> resultList = new LinkedList<MethodBinding>();
- resultList.add(mostSpecificMB);
- return resultList;
- }
-
- /**
- * Checks if 'subMB' 'inherits' from 'superMB'. Used to check if assumptions
- * about the precedence lists are fulfilled.
- *
- * @param subMB the overriding method binding
- * @param superMB the overridden method binding
- */
- private static void checkInheritance(MethodBinding subMB, MethodBinding superMB) {
- if (! (subMB.equals(superMB) || subMB.overridesMethodBinding(superMB))) {
- //System.err.println("sub: " + subMB + "\n super: " + superMB);
- throw new OTREInternalError("Wrong assumption! Broken precedence list possible.");
- }
- }
-
- // ------------------------------------------
- // ---------- Logging: ----------------------
- // ------------------------------------------
- /** Initialized from property <tt>ot.log</tt>. */
- static boolean logging = false;
- /** Initialized from property <tt>otequinox.debug</tt> */
- static boolean OTEQUINOX_WARN = false;
- static {
- if(System.getProperty("ot.log") != null)
- logging = true;
- String warnlevel = System.getProperty("otequinox.debug");
- if (warnlevel != null) {
- warnlevel = warnlevel.toUpperCase();
- if (warnlevel.startsWith("INFO") || warnlevel.equals("OK"))
- OTEQUINOX_WARN = true;
- }
- }
-
- // -----------------------------------------------
- // static replace callin bindings have to be stored in the team, special treatment:
- // -----------------------------------------------
-
- // maps an implemented role method to its base methods: roleMethod -> List[baseMethod] // added by JU
- private static ListValueHashMap<BaseMethodInfo> staticReplaceBindings = new ListValueHashMap<BaseMethodInfo>();
-
- /**
- * Adds a base method to its implemented role method (static replace bindings).
- *
- * @param roleMethodKey a string structured according team_class_ name.role_class_name.role_method_name.role_method_signature
- * @param baseMethodInfo an Object contained base class name, base method name and base method signature
- */
- public static void addStaticReplaceBindingForRoleMethod(String roleMethodKey, BaseMethodInfo baseMethodInfo) {
- staticReplaceBindings.put(roleMethodKey, baseMethodInfo);
- }
-
- /**
- * Returns static method bindings for the given role method
- * @param roleMethodKey
- * @return
- */
- public static LinkedList<BaseMethodInfo> getStaticReplaceBindingsForRoleMethod(String roleMethodKey) {
- return staticReplaceBindings.get(roleMethodKey);
- }
-
- /**
- * @param roleClassName
- * @param roleMethodName
- * @param roleMethodSignature
- * @return
- */
- public static boolean roleMethodHasBinding(String roleClassName, String roleMethodName, String roleMethodSignature) {
- RoleBaseBinding rbb = roleBindings.get(roleClassName);
- if (rbb == null) {
- return false;
- }
- return rbb.hasRoleMethodBinding(roleMethodName, roleMethodSignature);
- }
-
- // -----------------------------------------------
- // access modifiers of some base classes have to be changed to 'public' (decapsulation)
- // the names of these classes are stored in baseClassesForModifierChange
- // -----------------------------------------------
- private static LinkedList<String> baseClassesForModifierChange = new LinkedList<String>();
-
- /**
- * Adds the given class name to the list of class names intended for decapsulation
- * @param className
- */
- public static void addBaseClassForModifierChange(String className){
- baseClassesForModifierChange.add(className);
- }
-
- /**
- * Checks whether a class name is contained in the list of classes intended for decapsulation
- * @param className
- * @return
- */
- public static boolean checkBaseClassModifierChange(String className) {
- Iterator<String> iter = baseClassesForModifierChange.iterator();
- while(iter.hasNext()) {
- if(className.equals(iter.next())){
- return true;
- }
- }
- return false;
- }
-
- public static void addBoundSuperclassLink(String sub_name, String super_name) {
- synchronized (baseBindings) {
- bases:
- for (RoleBaseBinding subBinding : baseBindings.getFlattenValues()) {
- if (subBinding.getBaseClassName().equals(sub_name)) {
- for (RoleBaseBinding superBinding : baseBindings.getFlattenValues()) {
- if (subBinding == superBinding) continue;
- if (superBinding.getBaseClassName().equals(super_name)) {
- subBinding.getBaseClass().setSuper(superBinding.getBaseClass());
- break bases;
- }
- }
- }
- }
- }
- }
-
- /** Either retrieve an existing BoundClass for `className' are create a new one.
- * If an existing one is used it is updated for the new adapting team.
- */
- public static BoundClass getBoundBaseClass(String className, String teamClassName) {
- for (RoleBaseBinding subBinding : baseBindings.getFlattenValues()) {
- if (subBinding.getBaseClassName().equals(className)) {
- BoundClass baseClass = subBinding.getBaseClass();
- baseClass.addAdaptingTeam(teamClassName);
- return baseClass;
- }
- }
- return new BoundClass(className, teamClassName);
- }
-
- // ==== HELPERS FOR RE-ENTRANCE SAFETY: ====
-
- private static Iterator<String> getBaseBindingsKeyIterator() {
- synchronized (baseBindings) {
- ArrayList<String> list = new ArrayList<String>();
- list.addAll(baseBindings.keySet());
- Iterator<String> it = list.iterator();
- return it;
- }
- }
-
- private static Iterator<Entry<String, LinkedList<RoleBaseBinding>>> getBaseBindingsCloneIterator() {
- synchronized (baseBindings) {
- ArrayList<Entry<String, LinkedList<RoleBaseBinding>>> list = new ArrayList<Entry<String,LinkedList<RoleBaseBinding>>>();
- list.addAll(baseBindings.entrySet());
- Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it = list.iterator();
- return it;
- }
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/DebugUtil.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/DebugUtil.java
deleted file mode 100644
index c6e8d8072..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/DebugUtil.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2003-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: DebugUtil.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-import org.apache.bcel.generic.*;
-import org.apache.bcel.Constants;
-import java.util.Iterator;
-
-import org.eclipse.objectteams.otre.OTConstants;
-
-/**
- * @author Stephan Herrmann
- */
-@SuppressWarnings("nls")
-public class DebugUtil {
-
- // -----------------------------------------
- // -------- Development utilities ---------
- // -----------------------------------------
-
- /**
- * Creates an the instructions necessary to "System.out.println"
- * the given string.
- *
- * @param cpg the constant pool of the class where this instructions
- * will be inserted
- * @param string the String to be printed
- * @return an InstructionList containing the necessary instructions
- */
- public static InstructionList createPrintln(ConstantPoolGen cpg,
- InstructionFactory factory,
- String string)
- {
- InstructionList il = new InstructionList();
- ObjectType p_stream = new ObjectType("java.io.PrintStream");
-
- il.append(factory.createFieldAccess("java.lang.System", "out",
- p_stream,
- Constants.GETSTATIC));
- il.append(new PUSH(cpg, string + "\n"));
- il.append(factory.createInvoke("java.io.PrintStream", "print",
- Type.VOID,
- new Type[] { Type.STRING },
- Constants.INVOKEVIRTUAL));
- return il;
- }
-
- /**
- * Create a <tt>System.out.println</tt> call for an <tt>Object</tt>
- * argument. The argument is assumed to be on the stack and will not
- * be consumed.
- */
- public static InstructionList createPrintlnObj(InstructionFactory factory) {
- InstructionList il = new InstructionList();
- ObjectType p_stream = new ObjectType("java.io.PrintStream");
-
- il.append(new DUP());
- il.append(factory.createFieldAccess("java.lang.System", "out",
- p_stream,
- Constants.GETSTATIC));
- il.append(new SWAP());
- il.append(factory.createInvoke("java.io.PrintStream", "print",
- Type.VOID,
- new Type[] { OTConstants.object },
- Constants.INVOKEVIRTUAL));
- return il;
- }
-
- /**
- * Create a <tt>System.out.println</tt> call for an <tt>Exception</tt>
- * argument. The argument is assumed to be on the stack and _will_
- * be consumed. This effect is however only performed, if
- * the property ot.log.lift is set.
- */
- public static InstructionList createReportExc(InstructionFactory factory) {
- InstructionList il = new InstructionList();
- if (System.getProperty("ot.log.lift") == null) {
- il.append(new POP());
- } else {
- ObjectType p_stream = new ObjectType("java.io.PrintStream");
-
- il.append(factory.createFieldAccess("java.lang.System", "out",
- p_stream,
- Constants.GETSTATIC));
- il.append(new SWAP());
- il.append(factory.createInvoke("java.io.PrintStream", "println",
- Type.VOID,
- new Type[] { OTConstants.object },
- Constants.INVOKEVIRTUAL));
- }
- return il;
- }
-
- /**
- * Create a <tt>System.out.println</tt> call for an <tt>int</tt>
- * argument. The argument is assumed to be on the stack and will not
- * be consumed.
- */
- public static InstructionList createPrintlnInt(InstructionFactory factory) {
- InstructionList il = new InstructionList();
- ObjectType p_stream = new ObjectType("java.io.PrintStream");
-
- il.append(new DUP());
- il.append(factory.createFieldAccess("java.lang.System", "out",
- p_stream,
- Constants.GETSTATIC));
- il.append(new SWAP());
- il.append(factory.createInvoke("java.io.PrintStream", "print",
- Type.VOID,
- new Type[] { Type.INT },
- Constants.INVOKEVIRTUAL));
- return il;
- }
-
- public static InstructionList createPrintlnBool(ConstantPoolGen cp) {
- InstructionList il= new InstructionList();
- int out = cp.addFieldref("java.lang.System", "out",
- "Ljava/io/PrintStream;");
- int println = cp.addMethodref("java.io.PrintStream", "println",
- "(Z)V");
- il.append(new DUP());
- il.append(new GETSTATIC(out));
- il.append(new SWAP());
- il.append(new INVOKEVIRTUAL(println));
- return il;
- }
-
- @SuppressWarnings("unchecked")
- public static void printIL (InstructionList il, ConstantPoolGen cpg) {
- int off = 0;
- Iterator<InstructionHandle> it = il.iterator();
- while(it.hasNext()) {
- Instruction i = it.next().getInstruction();
- off += i.produceStack(cpg);
- off -= i.consumeStack(cpg);
- System.out.print(off);
- System.out.println(" = "+i);
- }
- }
-
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/FieldDescriptor.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/FieldDescriptor.java
deleted file mode 100644
index 30a3dd026..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/FieldDescriptor.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: FieldDescriptor.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-/**
- * @author resix
- */
-public class FieldDescriptor {
- private String fieldName;
- private String fieldSignature;
- private boolean isStaticField;
-
- public FieldDescriptor(String name, String signature, boolean is_static) {
- fieldName = name;
- fieldSignature = signature;
- isStaticField = is_static;
- }
-
- /**
- * @return Returns the fieldName.
- */
- public String getFieldName() {
- return fieldName;
- }
-
- /**
- * @return Returns the fieldSignature.
- */
- public String getFieldSignature() {
- return fieldSignature;
- }
-
- /**
- * @return Returns the isStaticField.
- */
- public boolean isStaticField() {
- return isStaticField;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/ListValueHashMap.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/ListValueHashMap.java
deleted file mode 100644
index 8b7b463ed..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/ListValueHashMap.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ListValueHashMap.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * @author resix
- */
-public class ListValueHashMap<ValueType> {
- private HashMap<String, LinkedList<ValueType>> hashMap = new HashMap<String, LinkedList<ValueType>>();
- //redundant structure for faster access:
- private LinkedList<ValueType> flattenValues = new LinkedList<ValueType>();
-
- /**
- * @param key
- * @param value
- */
- public void put(String key, ValueType value) {
- LinkedList<ValueType> list;
- if (!hashMap.containsKey(key)) {
- list = new LinkedList<ValueType>();
- } else {
- list = hashMap.get(key);
- }
- list.add(value);
- hashMap.put(key, list);
- flattenValues.add(value);
- }
-
- /**
- * @return
- */
- public List<ValueType> getFlattenValues() {
- return flattenValues;
- }
-
- /**
- * @param key
- * @return
- */
- public LinkedList<ValueType> get(String key) {
- if (!hashMap.containsKey(key)) {
- return null;
- }
- return hashMap.get(key);
- }
-
- public boolean containsKey(Object o) {
- return hashMap.containsKey(o);
- }
-
- public Set<String> keySet() {
- return hashMap.keySet();
- }
-
- public Set<Entry<String, LinkedList<ValueType>>> entrySet() {
- return hashMap.entrySet();
- }
-
- public int size() {
- return hashMap.size();
- }
-
- public String toString() {
- StringBuilder result = new StringBuilder(32);
- Iterator<Entry<String,LinkedList<ValueType>>> it = hashMap.entrySet().iterator();
- while (it.hasNext()) {
- Entry<String,LinkedList<ValueType>> entry = it.next();
- result.append(entry.getKey());
- result.append(": ");
- result.append(entry.getValue().toString());
- result.append("\n");
- }
- if (result.length() == 0)
- return super.toString();
- return result.toString();
- }
-
- public Collection<LinkedList<ValueType>> valueSet() {
- return hashMap.values();
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/MethodBinding.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/MethodBinding.java
deleted file mode 100644
index ecc543659..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/MethodBinding.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: MethodBinding.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-import org.eclipse.objectteams.otre.OTConstants;
-
-/**
- * @version $Id: MethodBinding.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Christine Hundt
- */
-public class MethodBinding {
-
- private String bindingFileName;
- private int bindingLineNumber;
- private int bindingLineOffset;
-
- private String bindingLabel;
-
- private BoundMethod baseMethod;
- private BoundMethod roleMethod;
-
- private boolean isStaticBaseMethod;
- private boolean isStaticRoleMethod;
- private boolean covariantBaseReturn;
-
- private int translationFlags;
-
- private String wrapperName;
- private String wrapperSignature;
-
- private String modifier;
- private String liftMethodName;
- private String liftMethodSignature;
-
- private String roleClassName;
-
- // back reference for the class binding containing this method binding.
- private RoleBaseBinding classBinding;
-
- /**
- *
- */
- public MethodBinding() {}
-
- /**
- * @param bindingFileName
- * @param bindingLineNumber
- * @param bindingLineOffest
- * @param bindingLabel
- * @param roleMethodName
- * @param roleMethodSignature
- * @param isStaticRoleMethod
- * @param wrapperName
- * @param wrapperSignature
- * @param modifier
- * @param baseMethodName
- * @param baseMethodSignature
- * @param isStaticBaseMethod
- * @param baseIsCallin
- * @param liftMethodName
- * @param liftMethodSignature
- * @param classBinding
- */
- public MethodBinding(
- String bindingFileName, int bindingLineNumber, int bindingLineOffest,
- String bindingLabel, String roleMethodName, String roleMethodSignature, boolean isStaticRoleMethod,
- String wrapperName, String wrapperSignature, String modifier,
- String baseMethodName, String baseMethodSignature,
- boolean isStaticBaseMethod, boolean baseIsCallin, boolean covariantBaseReturn,
- int translationFlags,
- String liftMethodName, String liftMethodSignature, RoleBaseBinding classBinding)
- {
- this.bindingFileName = bindingFileName;
- this.bindingLineNumber = bindingLineNumber;
- this.bindingLineOffset = bindingLineOffest;
-
- this.bindingLabel = bindingLabel;
- roleMethod = new BoundMethod(roleMethodName, roleMethodSignature, false, this);
- baseMethod = new BoundMethod(baseMethodName, baseMethodSignature, baseIsCallin, this);
- // BoundMethod object for one method is not unique!
- // but if it would be unique the 'binding' link would not be unique
- this.isStaticRoleMethod = isStaticRoleMethod;
- this.isStaticBaseMethod = isStaticBaseMethod;
- this.covariantBaseReturn = covariantBaseReturn;
- this.translationFlags = translationFlags;
- this.wrapperName = wrapperName;
- this.wrapperSignature = wrapperSignature;
- this.modifier = modifier;
- this.liftMethodName = liftMethodName;
- this.liftMethodSignature = liftMethodSignature;
- this.classBinding = classBinding;
- this.roleClassName = classBinding.getRoleClassName();
- }
-
- /**
- * @return
- */
- public String getRoleClassName() {
- return roleClassName;
- }
-
- /**
- * @return
- */
- public String getBindingFileName() {
- return bindingFileName;
- }
-
- /**
- * @return
- */
- public int getBindingLineNumber() {
- return bindingLineNumber;
- }
-
- /**
- * @return
- */
- public int getBindingLineOffset() {
- return bindingLineOffset;
- }
-
- /**
- * @return
- */
- public String getBindingLabel() {
- return bindingLabel;
- }
-
- /**
- * @return
- */
- public String getQualifiedBindingLabel() {
- String result = roleClassName;
- // remove the outermost team (use the '$' to distinguish pack1.Team1$Role from Team1$__OT__Team2$Role):
- result = result.substring(result.indexOf('$') + 1);
- // replace "$" by "." in the role class name:
- result = result.replace('$', '.');
- // remove "__OT__" prefixes in role class names:
- result = result.replace(OTConstants.OTDT_PREFIX, ""); //$NON-NLS-1$
- // add the binding label and return:
- return result + '.' + bindingLabel;
- }
-
- /**
- * @return
- */
- public String getRoleMethodName() {
- return roleMethod.getName();
- }
-
- /**
- * @return
- */
- public String getRoleMethodSignature() {
- return roleMethod.getSignature();
- }
-
- /**
- * @return
- */
- public String getWrapperName() {
- return wrapperName;
- }
-
- /**
- * @return
- */
- public String getWrapperSignature() {
- return wrapperSignature;
- }
-
- /**
- * @return
- */
- public String getBaseClassName() {
- return classBinding.getBaseClassName();
- }
-
- /**
- * @return
- */
- public String getBaseMethodName() {
- return baseMethod.getName();
- }
-
- /**
- * @return
- */
- public String getBaseMethodSignature() {
- return baseMethod.getSignature();
- }
-
- /**
- * @return
- */
- public boolean baseMethodIsCallin() {
- return baseMethod.getIsCallin();
- }
-
- /**
- * @return
- */
- public String getModifier() {
- return modifier;
- }
-
- /**
- * @return
- */
- public boolean isReplace() {
- return modifier.equals("replace");
- }
-
- /**
- * @return
- */
- public boolean isAfter() {
- return modifier.equals("after");
- }
-
- /**
- * @return
- */
- public boolean isBefore() {
- return modifier.equals("before");
- }
-
- /**
- * @return Returns the liftMethodName.
- */
- public String getLiftMethodName() {
- return liftMethodName;
- }
-
- /**
- * @return Returns the liftMethodSignature.
- */
- public String getLiftMethodSignature() {
- return liftMethodSignature;
- }
-
- /**
- * @return Returns the corresponding class binding.
- */
- public RoleBaseBinding getClassBinding() {
- return classBinding;
- }
-
- /**
- * Returns the most super bound base class of the base class belonging to
- * this MethodBinding. Note: only consider base classes bound by roles of
- * the corresponding team!
- *
- * @return the most super bound base class
- */
- public String getRootBoundBase() {
- BoundClass bc = classBinding.getRoleClass();
- while (bc.getSuper() != null && CallinBindingManager.isBoundRoleClass(bc.getSuper().getName()) ) {
- bc = bc.getSuper();
- }
- RoleBaseBinding rbb = CallinBindingManager.getRoleBaseBinding(bc.getName());
- return rbb.getBaseClassName();
- }
-
- /**
- * Returns the name of the team surrounding the role class of this binding.
- *
- * @return the name of the corresponding team
- */
- public String getTeamClassName() {
- int dollarIndex = roleClassName.lastIndexOf('$');
- // return everything before the last '$', because for nested teams there are more than one:
- return roleClassName.substring(0, dollarIndex);
- }
-
- /**
- * @param anotherMB
- * @return
- */
- public boolean overridesMethodBinding(MethodBinding anotherMB) {
- if (anotherMB == null)
- return false;
- if (!bindingLabel.equals(anotherMB.getBindingLabel()))
- return false;
- return classBinding.getRoleClass().isSubClassOf(anotherMB.getClassBinding().getRoleClassName());
- }
-
- /**
- * @param bindingLabel
- * @param teamName
- * @return
- */
- public boolean inheritsBindingLabel(String bindingLabel, String teamName) {
- String prefix = teamName + "$__OT__";
- int dotIndex = bindingLabel.lastIndexOf('.');
- String classOfLabel = prefix + bindingLabel.substring(0, dotIndex);
- if (!bindingLabel.substring(dotIndex + 1).equals(this.bindingLabel))
- return false;
-
- if (classBinding.getRoleClass().isSubClassOf(classOfLabel))
- return true;
- return false;
- }
-
- /**
- * @param mb
- * @return
- */
- public boolean equals(MethodBinding mb) {
- return roleMethod.getName().equals(mb.getRoleMethodName())
- && roleMethod.getSignature().equals(mb.getRoleMethodSignature())
- && classBinding.getBaseClassName().equals(mb.getBaseClassName())
- && baseMethod.getName().equals(mb.getBaseMethodName())
- && baseMethod.getSignature().equals(mb.getBaseMethodSignature())
- && modifier.equals(mb.getModifier());
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- public String toString() {
- StringBuilder result = new StringBuilder(32);
- result.append("\t");
- result.append(getQualifiedBindingLabel());
- result.append(": ");
- result.append(roleMethod.getName());
- result.append(roleMethod.getSignature());
- result.append(" <-> ");
- result.append(modifier);
- result.append(" ");
- result.append(baseMethod.getName());
- result.append(baseMethod.getSignature());
- if (this.covariantBaseReturn)
- result.append('+');
- return result.toString();
- }
-
- /**
- * @return
- */
- public boolean hasStaticRoleMethod() {
- return isStaticRoleMethod;
- }
-
- /**
- * @return
- */
- public boolean hasStaticBaseMethod() {
- return isStaticBaseMethod;
- }
-
- public int getTranslationFlags() {
- return this.translationFlags;
- }
-
- /** For base methods provide a key without the trailing return type to cater for covariance. */
- static String getBaseMethodKey(String baseMethodName, String baseMethodSignature) {
- int pos= baseMethodSignature.lastIndexOf(')');
- String baseMethodKey = baseMethodName + '.' + baseMethodSignature.substring(0, pos+1);
- return baseMethodKey;
- }
-
- /**
- * Is the method specified by mName and mSig a match for this method binding?
- * @param mName method name
- * @param mSig full method signature
- * @param strict if true covariance is not supported
- */
- public boolean matchesMethod(String mName, String mSig, boolean strict) {
- String baseMethodName = getBaseMethodName();
- String baseMethodSignature = getBaseMethodSignature();
- if (this.covariantBaseReturn && !strict) {
- return getBaseMethodKey(mName, mSig).equals(
- getBaseMethodKey(baseMethodName, baseMethodSignature));
- } else {
- return mName.equals(baseMethodName)
- && mSig.equals(baseMethodSignature);
- }
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/RoleBaseBinding.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/RoleBaseBinding.java
deleted file mode 100644
index 2a8c30b84..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/RoleBaseBinding.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: RoleBaseBinding.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @version $Id: RoleBaseBinding.java 23408 2010-02-03 18:07:35Z stephan $
- * @author Christine Hundt
- */
-public class RoleBaseBinding {
-
- private BoundClass roleClass;
- private BoundClass baseClass;
-
- private ListValueHashMap<MethodBinding> roleMethodBindings = new ListValueHashMap<MethodBinding>();
- private ListValueHashMap<MethodBinding> baseMethodBindings = new ListValueHashMap<MethodBinding>();
-
- /**
- *
- */
- public RoleBaseBinding() {
- }
-
- /**
- * @param _roleClassName
- * @param _baseClassName
- * @param teamClassName
- */
- public RoleBaseBinding(String _roleClassName, String _baseClassName, String teamClassName) {
- roleClass = new BoundClass(_roleClassName, teamClassName);
- baseClass = CallinBindingManager.getBoundBaseClass(_baseClassName, teamClassName);
- }
-
- /**
- * @param bindingFileName
- * @param bindingLineNumber
- * @param bindingLineOffset
- * @param bindingLabel
- * @param roleMethodName
- * @param roleMethodSignature
- * @param isStaticRoleMethod
- * @param wrapperName
- * @param wrapperSignature
- * @param modifier
- * @param baseMethodName
- * @param baseMethodSignature
- * @param isStaticBaseMethod
- * @param baseIsCallin
- * @param translationFlags
- * @param liftMethodName
- * @param liftMethodSignature
- */
- public void addMethodBinding(
- String bindingFileName, int bindingLineNumber, int bindingLineOffset,
- String bindingLabel, String roleMethodName, String roleMethodSignature,
- boolean isStaticRoleMethod, String wrapperName, String wrapperSignature, String modifier,
- String baseMethodName, String baseMethodSignature,
- boolean isStaticBaseMethod, boolean baseIsCallin, boolean covariantBaseReturn,
- int translationFlags, String liftMethodName, String liftMethodSignature)
- {
- MethodBinding mb = new MethodBinding(bindingFileName, bindingLineNumber, bindingLineOffset,
- bindingLabel, roleMethodName, roleMethodSignature, isStaticRoleMethod,
- wrapperName, wrapperSignature, modifier,
- baseMethodName, baseMethodSignature,
- isStaticBaseMethod, baseIsCallin, covariantBaseReturn,
- translationFlags,
- liftMethodName,
- liftMethodSignature, this);
- // TODO: check, if the key has to include the 'binding_label'
- String baseMethodKey = MethodBinding.getBaseMethodKey(baseMethodName, baseMethodSignature);
- String roleMethodKey = roleMethodName + '.' + roleMethodSignature;
- roleMethodBindings.put(roleMethodKey, mb);
- baseMethodBindings.put(baseMethodKey, mb);
- }
-
- /**
- * @return
- */
- public List<MethodBinding> getBaseMethodBindings() {
- return baseMethodBindings.getFlattenValues();
- }
-
- /**
- * @param baseMethodName
- * @param baseMethodSignature
- * @return
- */
- public List<MethodBinding> getBaseMethodBindings(String baseMethodName, String baseMethodSignature) {
- String baseMethodKey = MethodBinding.getBaseMethodKey(baseMethodName, baseMethodSignature);
- return baseMethodBindings.get(baseMethodKey);
- }
-
- /**
- * @return
- */
- public List<MethodBinding> getRoleMethodBindings() {
- return roleMethodBindings.getFlattenValues();
- }
-
- /**
- * @param roleMethodName
- * @param roleMethodSignature
- * @return
- */
- public List<MethodBinding> getRoleMethodBindings(String roleMethodName, String roleMethodSignature) {
- String roleMethodKey = roleMethodName + '.' + roleMethodSignature;
- return roleMethodBindings.get(roleMethodKey);
- }
-
- /**
- * @param roleMethodName
- * @param roleMethodSignature
- * @return
- */
- public boolean hasRoleMethodBinding(String roleMethodName, String roleMethodSignature) {
- String signatureWithoutReturnType = roleMethodSignature.substring(0, roleMethodSignature.lastIndexOf(')') + 1);
- Set<String> bindingKeys = roleMethodBindings.keySet();
- Iterator<String> it = bindingKeys.iterator();
- while (it.hasNext()) {
- String key = it.next();
- String keyWithoutReturnType = key.substring(0, key.lastIndexOf(')') + 1);
- if (keyWithoutReturnType.equals(roleMethodName + '.'
- + signatureWithoutReturnType))
- return true;
- }
- return false;
- }
-
- public Set<String> getRoleMethodSignatures() {
- return roleMethodBindings.keySet();
- }
-
- /**
- * @return
- */
- public BoundClass getRoleClass() {
- return roleClass;
- }
-
- /**
- * @return
- */
- public BoundClass getBaseClass() {
- return baseClass;
- }
-
- /**
- * @return
- */
- public String getRoleClassName() {
- return roleClass.getName();
- }
-
- /**
- * @return
- */
- public String getBaseClassName() {
- return baseClass.getName();
- }
-
- /**
- * Collect all base method signatures for this role-base pair.
- * @result List <String[] {name, signature}>
- */
- public List<String[]> getBaseSignatures () {
- List<String[]> result = new LinkedList<String[]>();
- List<MethodBinding> baseMethodBindingList = getBaseMethodBindings();
- Iterator<MethodBinding> it = baseMethodBindingList.iterator();
- while (it.hasNext()) {
- MethodBinding mb = it.next();
- result.add(new String [] {
- mb.getBaseMethodName(),
- mb.getBaseMethodSignature()
- });
- }
- return result;
- }
-
- /**
- * @param rbb
- * @return
- */
- public boolean equals(RoleBaseBinding rbb) {
- return roleClass.getName().equals(rbb.getRoleClassName())
- && baseClass.getName().equals(rbb.getBaseClassName());
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- public String toString() {
- StringBuilder out = new StringBuilder(64);
- out.append(roleClass.getName());
- out.append(" <-> ");
- out.append(baseClass.getName());
- out.append("\nmethod bindings:\n");
- List<MethodBinding> mbsList = getBaseMethodBindings();
- Iterator<MethodBinding> it = mbsList.iterator();
- while (it.hasNext()) {
- MethodBinding mb = it.next();
- out.append("\n");
- out.append(mb.getBaseMethodName());
- out.append(".");
- out.append(mb.getBaseMethodSignature());
- out.append(":");
- out.append(mb.toString());
- }
- return out.toString();
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/SuperMethodDescriptor.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/SuperMethodDescriptor.java
deleted file mode 100644
index 02b9c04de..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/SuperMethodDescriptor.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2008 Technical University Berlin, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: SuperMethodDescriptor.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-
-/** Representation of a base-super method call, requiring a special access method. */
-public class SuperMethodDescriptor {
- public String methodName;
- public String declaringClass;
- public String superClass;
- public String signature;
- public SuperMethodDescriptor(String methodName, String declaringClass,
- String superClass, String signature) {
- super();
- this.methodName = methodName;
- this.declaringClass = declaringClass;
- this.superClass = superClass;
- this.signature = signature;
- }
-}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/TeamIdDispenser.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/TeamIdDispenser.java
deleted file mode 100644
index 100a0a1da..000000000
--- a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/TeamIdDispenser.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: TeamIdDispenser.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otre.util;
-import java.util.*;
-
-public class TeamIdDispenser {
-
- private static Map<ClassLoader, TeamIdDispenser> instances = new HashMap<ClassLoader, TeamIdDispenser>();
- private static TeamIdDispenser defaultInstance = new TeamIdDispenser();
-
- static int lastDispensedId = 0;
- private static HashMap<String, Integer> teamIDs = new HashMap<String, Integer>();
-
-// @SuppressWarnings("unchecked")
- private static int produceNextTeamId(String team_name) {
- lastDispensedId++;
- Integer teamId = Integer.valueOf(lastDispensedId);
- teamIDs.put(team_name, teamId);
- return lastDispensedId;
- }
-
- public static int getTeamId(String class_name) {
- Integer teamId = teamIDs.get(class_name);
- if (teamId != null)
- // the team <class_name> already has a team-id assigned
- return teamId.intValue();
- else return produceNextTeamId(class_name);
- }
-
- // Data shared among different transformers of the same class loader:
- // REFACTOR: move the following to a better place:
- private ArrayList<String> clinitAddedClasses = new ArrayList<String>();
- public static boolean clinitAdded(String class_name, ClassLoader loader) {
- TeamIdDispenser instance = getInstanceForLoader(loader);
- if (instance.clinitAddedClasses.contains(class_name))
- return true;
-
- instance.clinitAddedClasses.add(class_name);
- return false;
- }
-
- /**
- * Since actual data are stored in an instance, static methods need to retrieve the appropriate
- * instance regarding the given class loader.
- */
- private static TeamIdDispenser getInstanceForLoader(ClassLoader loader) {
- if (loader == null)
- return defaultInstance;
-
- TeamIdDispenser instance = instances.get(loader);
- if (instance == null)
- instances.put(loader, instance = new TeamIdDispenser());
- return instance;
- }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/DoublyWeakHashMap.java b/othersrc/OTRE/src/org/objectteams/DoublyWeakHashMap.java
deleted file mode 100644
index 05a2f91fa..000000000
--- a/othersrc/OTRE/src/org/objectteams/DoublyWeakHashMap.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2010 Stephan Herrmann.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id$
- *
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- *
- * Contributors:
- * Stephan Herrmann - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-/**
- * This class defines hash maps where both key and value are weak references.
- * It is implemented by delegating to a WeakHashMap and additionally
- * wrapping the value in a WeakReference.
- *
- * @author stephan
- * @since 0.7.0
- * @param <K> type of keys: a base class
- * @param <V> type of values: a role class
- */
-public class DoublyWeakHashMap<K,V> implements Map<K,V> {
-
- private WeakHashMap<K, WeakReference<V>> map;
-
- public DoublyWeakHashMap() {
- this.map = new WeakHashMap<K, WeakReference<V>>();
- }
-
- public int size() {
- return this.map.size();
- }
-
- public boolean isEmpty() {
- return this.map.isEmpty();
- }
-
- // used from hasRole() and lifting (duplicate role check)
- public boolean containsKey(Object key) {
- return this.map.containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- throw new UnsupportedFeatureException("Method containsValue is not implemented for internal class DoublyWeakHashMap.");
- }
-
- // used from getRole()
- public V get(Object key) {
- WeakReference<V> valRef = this.map.get(key);
- return valRef == null ? null : valRef.get();
- }
-
- // used from migrateToBase() and lifting constructor
- public synchronized V put(K key, V value) {
- this.map.put(key, new WeakReference<V>(value));
- return value;
- }
-
- // used from unregisterRole(), migrateToBase()
- public synchronized V remove(Object key) {
- WeakReference<V> value = this.map.remove(key);
- return (value == null) ? null : value.get();
- }
-
- public void putAll(Map<? extends K, ? extends V> t) {
- for (Entry<? extends K, ? extends V> entry : t.entrySet())
- this.map.put(entry.getKey(), new WeakReference<V>(entry.getValue()));
- }
-
- public void clear() {
- this.map.clear();
- }
-
- public Set<K> keySet() {
- return this.map.keySet();
- }
-
- // used from getAllRoles() et al.
- public synchronized Collection<V> values() {
- ArrayList<V> result = new ArrayList<V>(this.map.size());
- for (WeakReference<V> valRef : this.map.values()) {
- V value = valRef.get();
- if (value != null)
- result.add(value);
- }
- return result;
- }
-
- public Set<java.util.Map.Entry<K, V>> entrySet() {
- throw new UnsupportedFeatureException("Method entrySet is not implemented for internal class DoublyWeakHashMap.");
- }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/DuplicateRoleException.java b/othersrc/OTRE/src/org/objectteams/DuplicateRoleException.java
deleted file mode 100644
index ae3e851a9..000000000
--- a/othersrc/OTRE/src/org/objectteams/DuplicateRoleException.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: DuplicateRoleException.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * Signal a violation of OTJLD 2.4.1(c).
- * Also Team.getRole(Object) may throw a DuplicateRoleException if
- * more than one role is found for the given base object
- * (in that case those roles are found in different role-caches).
- *
- *
- * @author stephan
- * @version $Id: DuplicateRoleException.java 23408 2010-02-03 18:07:35Z stephan $
- */
-public class DuplicateRoleException extends RuntimeException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * @param message
- */
- public DuplicateRoleException(String roleClassName) {
- super("Failed to create a role instance of type "+roleClassName+"\n"+
- "A role for the given base object already exists (OTJLD 2.4.1(c)).");
- }
-
- public DuplicateRoleException(String roleName1, String roleName2) {
- super("Ambiguous role instances: found a role in hierarchies "+
- roleName1+" and "+roleName2);
- }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/IBaseMigratable.java b/othersrc/OTRE/src/org/objectteams/IBaseMigratable.java
deleted file mode 100644
index edc9202ba..000000000
--- a/othersrc/OTRE/src/org/objectteams/IBaseMigratable.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2008 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: IBaseMigratable.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * Marker interface: if a role declares to implement this interface
- * the compiler will generate the method defined herein, and prepare
- * the role so that the migration will indeed be possible.
- *
- * @author stephan
- * @since 1.2.5
- */
-public interface IBaseMigratable {
- /**
- * Migrate the current role to the otherBase.
- *
- * @param otherBase new base that this role should adapt, must
- * be of a valid base type for the current role.
- */
- <B> void migrateToBase(B otherBase);
-}
diff --git a/othersrc/OTRE/src/org/objectteams/IBoundBase.java b/othersrc/OTRE/src/org/objectteams/IBoundBase.java
deleted file mode 100644
index 9f196bf92..000000000
--- a/othersrc/OTRE/src/org/objectteams/IBoundBase.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2007-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: IBoundBase.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * Super type for all bound base classes. Purely internal class, not intended for client use.
- * @author Stephan Herrmann
- */
-public interface IBoundBase {
- /** Method to be used by generated code, only (lifting constructor). */
- void _OT$addRole(Object aRole);
- /** Method to be used by generated code, only (unregisterRole()). */
- void _OT$removeRole(Object aRole);
-} \ No newline at end of file
diff --git a/othersrc/OTRE/src/org/objectteams/IConfined.java b/othersrc/OTRE/src/org/objectteams/IConfined.java
deleted file mode 100644
index 8ead4b473..000000000
--- a/othersrc/OTRE/src/org/objectteams/IConfined.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: IConfined.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * Special interface that does not extend Object
- *
- * @author stephan
- */
-public interface IConfined {} \ No newline at end of file
diff --git a/othersrc/OTRE/src/org/objectteams/ILiftingParticipant.java b/othersrc/OTRE/src/org/objectteams/ILiftingParticipant.java
deleted file mode 100644
index 408d0873e..000000000
--- a/othersrc/OTRE/src/org/objectteams/ILiftingParticipant.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2009 Stephan Herrmann
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ILiftingParticipant.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Stephan Herrmann - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * A lifting participant hooks into the lifting process.
- *
- * @author stephan
- * @since 1.3.1
- */
-public interface ILiftingParticipant {
- /**
- * This method is called when lifting does not find a suitable role within the
- * team's internal role cache. If this method returns a non-null value,
- * this value is considered by the runtime as being the desired role
- * (i.e., it must be castable to that role type), and no new role is created.
- * If this method returns null, lifting proceeds as normal, i.e.,
- * a fresh role is created using the default lifting constructor.
- *
- * @param teamInstance
- * @param baseInstance
- * @param roleClassName
- * @return either null or an instance of the class specified by roleClassName
- */
- Object createRole(ITeam teamInstance, Object baseInstance, String roleClassName);
-}
diff --git a/othersrc/OTRE/src/org/objectteams/ITeam.java b/othersrc/OTRE/src/org/objectteams/ITeam.java
deleted file mode 100644
index b77c5f092..000000000
--- a/othersrc/OTRE/src/org/objectteams/ITeam.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2010 Stephan Herrmann.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ITeam.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Stephan Herrmann - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * Public interface of all team classes.
- */
-public interface ITeam {
-
- /**
- * Interface for all role classes that should allow explicit lowering.
- * The interface provides a phantom method <pre>&lt;B&gt; B lower()</pre>
- * where B is the bound base class of the implementing role class.
- * There is no need to implement the method lower, since this is done by the compiler.
- */
- public interface ILowerable {
- // internal method needed for cast and instanceof
- ITeam _OT$getTeam();
- }
-
- /**
- * This role interface has no properties not even those of java.lang.Object.
- */
- public interface IConfined extends org.objectteams.IConfined {
- // internal method needed for cast and instanceof
- ITeam _OT$getTeam();
- }
-
-
- /**
- * Activates the team and therefore all of its callin bindings.
- * This activation applies to the current thread only.
- */
- public abstract void activate();
-
- /**
- * Deactivates the team and therefore all of its callin bindings.
- * This deactivation applies to the current thread only.
- */
- public abstract void deactivate();
-
- /**
- * Activates the team and therefore all of its callin bindings for passed thread.
- * If the constant 'Team.ALL_THREADS' is passed, this activation globally applies to all threads.
- */
- public abstract void activate(Thread thread);
-
- /**
- * Deactivates the team and therefore all of its callin bindings for passed thread.
- * If the constant 'Team.ALL_THREADS' is passed, this deactivation globally applies to all threads.
- */
- public abstract void deactivate(Thread thread);
-
- /**
- * Checks, if the team instance is active for the current thread.
- * @return true, if the team is active, false else.
- */
- public abstract boolean isActive();
-
- /**
- * Checks, if the team instance is active for the 'thread'.
- * @param thread The thread for which to check activity.
- * @return true, if the team is active for 'thread', false else.
- */
- public abstract boolean isActive(Thread thread);
-
- /**
- * Does given base object have a role in this team?
- * This method will consider roles of any type.
- *
- * @param aBase any object, i.e., no checks are performed whether the base object's
- * class is bound by any role class in this team.
- * @return
- */
- public abstract boolean hasRole(Object aBase);
-
- /**
- * Does given base object have a role in this team?
- * The role must be an instance of the specified role type.
- *
- * @param aBase any object, i.e., no checks are performed whether the base object's
- * class is bound by any role class in this team.
- * @param roleType Class instance specifying the required role type.
- * TODO (SH): is it legal to pass an unbound role class?
- * @throws IllegalArgumentException if <code>roleType</code> does not represent a member type of this team.
- * @return
- */
- public abstract boolean hasRole(Object aBase, Class<?> roleType) throws IllegalArgumentException;
-
- /**
- * Retrieve a role for a given base object.
- * If more than one role exists, a DuplicateRoleException is thrown.
- *
- * @param aBase
- * @return
- */
- public abstract Object getRole(Object aBase);
-
- /**
- * Retrieve a role for a given base object.
- * The role must be an instance of the specified role type.
- *
- * @param aBase any object, i.e., no checks are performed whether the base object's
- * class is bound by any role class in this team.
- * @param roleType Class instance specifying the required role type.
- * @return
- * @throws IllegalArgumentException if <code>roleType</code> does not represent a member type of this team.
- */
- public abstract <T> T getRole(Object aBase, Class<T> roleType) throws IllegalArgumentException;
-
- /**
- * Retrieve all bound roles registered in the current team.
- *
- * This method uses internal structures of weak references.
- * For that reason it may return role instances which were about to be reclaimed
- * by the garbage collector.
- * If performance permits, it is thus advisable to always call System.gc()
- * prior to calling getAllRoles() in order to achieve deterministic results
- *
- * @return a non-null array.
- */
- public abstract Object[] getAllRoles();
-
- /**
- * Retrieve all bound roles registered in the current team that
- * are instance of roleType or a subtype thereof.
- *
- * This method uses internal structures of weak references.
- * For that reason it may return role instances which were about to be reclaimed
- * by the garbage collector.
- * If performance permits, it is thus advisable to always call System.gc()
- * prior to calling getAllRoles() in order to achieve deterministic results
- *
- * @param roleType must be a top-most bound role of this team.
- * @return a non-null array.
- * @throws IllegalArgumentException if <code>roleType</code> does not represent a member type of this team.
- */
- public abstract <T> T[] getAllRoles(Class<T> roleType) throws IllegalArgumentException;
-
- /**
- * Query whether any role instance of this team instance is currently executing a
- * method due to a callin binding.
- * @return
- */
- public abstract boolean isExecutingCallin();
-
- /**
- * Remove a role from the internal registry, which means that the role will no longer be
- * considered during lifting.
- *
- * @param aRole
- */
- public abstract void unregisterRole(Object aRole);
-
- /**
- * Remove a role from the internal registry, which means that the role will no longer be
- * considered during lifting.
- *
- * @param aRole
- * @param roleType
- * @throws IllegalArgumentException if <code>roleType</code> does not represent a member type of this team.
- */
- public abstract void unregisterRole(Object aRole, Class<?> roleType) throws IllegalArgumentException;
-
- /**
- * Not API.
- * This method saves the activation state of the team for the current thread.
- * If active, it also saves, if the activation was explicit or implicit.
- * This method has to be called by the generated code when entering a within block,
- * before the activation.
- */
- public int _OT$saveActivationState();
-
- /**
- * Not API.
- * This method restores the former saved activation state of the team for the current thread.
- * If active, it also restores, if the activation was explicit or implicit.
- * This method has to be called by the generated code when leaving a within block
- * (in the finally block).
- */
- public void _OT$restoreActivationState(int old_state);
-
- /**
- * Not API, for use by TeamThreadManager, only.
- */
- public boolean internalIsActiveSpecificallyFor(Thread t);
-
- /**
- * Not API, for use by TeamThreadManager, only.
- */
- public void deactivateForEndedThread(Thread thread);
-} \ No newline at end of file
diff --git a/othersrc/OTRE/src/org/objectteams/ITeamMigratable.java b/othersrc/OTRE/src/org/objectteams/ITeamMigratable.java
deleted file mode 100644
index 39be5661f..000000000
--- a/othersrc/OTRE/src/org/objectteams/ITeamMigratable.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2008 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ITeamMigratable.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * Marker interface: if a role declares to implement this interface
- * the compiler will generate the method defined herein, and prepare
- * the role so that the migration will indeed be possible.
- * Note, that a migratable role does not obey the family guarantee.
- *
- * @author stephan
- * @since 1.2.5
- */
-public interface ITeamMigratable {
- /**
- * Migrate the current role to the otherTeam.
- *
- * @param otherTeam new team that should adopt this role
- * @return the migrated (and re-typed) role (actually of type R<@otherTeam>). FIXME(SH)
- */
- <R> R migrateToTeam(final ITeam otherTeam);
-}
diff --git a/othersrc/OTRE/src/org/objectteams/IllegalRoleCreationException.java b/othersrc/OTRE/src/org/objectteams/IllegalRoleCreationException.java
deleted file mode 100644
index f745d739b..000000000
--- a/othersrc/OTRE/src/org/objectteams/IllegalRoleCreationException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2007-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: IllegalRoleCreationException.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * Exception to be thrown when a bound role is being instantiated but
- * the constructor does not assign a base object.
- *
- * @author stephan
- */
-@SuppressWarnings("serial")
-public class IllegalRoleCreationException extends RuntimeException {
- public IllegalRoleCreationException() {
- super();
- }
-
- @Override
- public String getMessage() {
- return "Cannot instantiate a bound role using a default constructor of its tsuper class";
- }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/ImplicitTeamActivation.java b/othersrc/OTRE/src/org/objectteams/ImplicitTeamActivation.java
deleted file mode 100644
index 09eda9679..000000000
--- a/othersrc/OTRE/src/org/objectteams/ImplicitTeamActivation.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2009 Stephan Herrmann
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id$
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Stephan Herrmann - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * This marker annotation enables implicit team activation for the annotated element:
- * <ul>
- * <li>If attached to a method the effect is that each call to this method implicitly
- * activates the enclosing team.</li>
- * <li>If attached to a class it has the same effect as annotating all contained methods.</li>
- * </ul>
- * See <a href="http://www.objectteams.org/def/1.3/s5.html#s5.3">OTJLD ยง 5.3</a>.
- * <p>
- * This annotation is only evaluated if the property <code>ot.implicit.team.activation</code>
- * is set to the string <code>ANNOTATED</code>.
- * </p>
- * @author stephan
- * @since 1.4.0
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD, ElementType.TYPE})
-public @interface ImplicitTeamActivation {
- /* no members, pure marker annotation. */
-}
diff --git a/othersrc/OTRE/src/org/objectteams/LiftingFailedException.java b/othersrc/OTRE/src/org/objectteams/LiftingFailedException.java
deleted file mode 100644
index 99f2dd279..000000000
--- a/othersrc/OTRE/src/org/objectteams/LiftingFailedException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2003-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: LiftingFailedException.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * This exception signals that lifting failed due to unresolved
- * binding ambiguity.
- */
-public class LiftingFailedException extends RuntimeException {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private Object base;
- private String roleType;
-
- /**
- * @param base the object that should be lifted
- * @param roleType the name of the role type for which
- * lifting was attempted.
- */
- public LiftingFailedException(Object base, String roleType) {
- this.base = base;
- this.roleType = roleType;
- }
-
- public String getMessage() {
- return "\nFailed to lift '" + base + "' of " + base.getClass()
- + " to type '" + roleType
- + "'\n(See OT/J definition para. 2.3.4(c)).";
- }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/LiftingVetoException.java b/othersrc/OTRE/src/org/objectteams/LiftingVetoException.java
deleted file mode 100644
index 3a9b83aea..000000000
--- a/othersrc/OTRE/src/org/objectteams/LiftingVetoException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2003-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: LiftingVetoException.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * This exception is used by the language implementation
- * to signal a failed lifting due to a guard predicate that evaluated to false.
- * @author Stephan Herrmann
- */
-public class LiftingVetoException extends RuntimeException {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- ITeam aTeam = null;
- Object base = null;
-
- public LiftingVetoException(ITeam aTeam, Object base) {
- this.aTeam = aTeam;
- this.base = base;
- }
-
- public LiftingVetoException() {
- super("");
- }
-
- public String toString() {
- return "Team " + aTeam + " refuses to lift " + base
- + "\n(this exception should not be seen in applications).";
- }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/ResultNotProvidedException.java b/othersrc/OTRE/src/org/objectteams/ResultNotProvidedException.java
deleted file mode 100644
index b6baccbc5..000000000
--- a/othersrc/OTRE/src/org/objectteams/ResultNotProvidedException.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: ResultNotProvidedException.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * @author resix
- */
-public class ResultNotProvidedException extends RuntimeException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private static final String _bugmsg =
- "\nNo base call executed! Result value was uninitialized!\n(see OT/J language definition para. 4.3(e)).";
-
- /**
- *
- */
- public ResultNotProvidedException() {
- super(_bugmsg);
- }
-
- /**
- * @param message
- */
- public ResultNotProvidedException(String message) {
- super(_bugmsg + "\n" + message);
- StackTraceElement[] ste = new StackTraceElement[0];
- setStackTrace(ste);
- }
-
- /**
- * @param cause
- */
- public ResultNotProvidedException(Throwable cause) {
- super(_bugmsg + cause.toString());
- }
-
- /**
- * @param message
- * @param cause
- */
- public ResultNotProvidedException(String message, Throwable cause) {
- super(_bugmsg + message/* +cause.toString() */);
- }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/RoleCastException.java b/othersrc/OTRE/src/org/objectteams/RoleCastException.java
deleted file mode 100644
index f6608c944..000000000
--- a/othersrc/OTRE/src/org/objectteams/RoleCastException.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: RoleCastException.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * This exception is thrown if a cast to a role class fails due to
- * different enclosing team instances.
- * @author Stephan Herrmann
- */
-public class RoleCastException extends ClassCastException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private static final String MSG =
- "Different enclosing team instances (see OT/J language definition para. 1.2.4(b)).";
-
- /* (non-Javadoc)
- * @see java.lang.Throwable#getMessage()
- */
- public String getMessage() {
- return MSG;
- }
-} \ No newline at end of file
diff --git a/othersrc/OTRE/src/org/objectteams/Team.java b/othersrc/OTRE/src/org/objectteams/Team.java
deleted file mode 100644
index 5feaccacf..000000000
--- a/othersrc/OTRE/src/org/objectteams/Team.java
+++ /dev/null
@@ -1,520 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2002-2007 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: Team.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.WeakHashMap;
-
-/**
- * This is the root class of all team definitions.
- * Any class with the <tt>team</tt> modifier implicitly
- * inherits from this class.
- *
- */
-public /* team */ class Team implements ITeam {
- // Technical note: comments starting with //$Debug are intended
- // for a standalone tool that generates an interface
- // which the debugger needs in order to know about line numbers in this class.
-
- /*
- * Synchronization: This class supports two levels of synchronization:
- * <ul>
- * <li>Fields of <code>Team</code> are synchronized
- * using <code>this</code> as the monitor.
- * <li>Those calls that (un)register a team at its base classes are synchronized
- * via <code>registrationLock</code>
- * </ul>
- * This allows releasing the lock on <code>this</code> before calling to the base class.
- * Note, that the synchronized portion of each initial-wrapper is also synchronized
- * (against <code>_OT$addTeam/_OT$removeTeam</code>) and that it calls back to
- * the registered teams (method <code>isActive()</code>).
- * Without <code>registrationLock</code> this situation could easily deadlock:
- * Thread1: <pre>t.activate() -> Base._OT$addTeam()</pre>: owns t, waits for Base.
- * Thread2: <pre>b.bm() (initial wrapper) -> t.isActive()</pre>: owns Base, waits for t.
- */
-
- /**
- * Internal field used by the runtime to install a lifting participant if one is configured.
- */
- public static ILiftingParticipant _OT$liftingParticipant = null;
-
- /**
- * Default constructor for debugging purpose.
- */
- public Team() {} //$Debug(TeamConstructor)
-
- /*
- * manual copy-inheritance of a role interface from ITeam.
- */
- public interface ILowerable extends ITeam.ILowerable {}
-
- /*
- * manual copy-inheritance of a role interface from ITeam.
- */
- public interface IConfined extends ITeam.IConfined {}
-
- /**
- * Special role type that<ul>
- * <li> does not extend java.lang.Object
- * <li> may not leak references outside the team.
- * </ul>
- */
- protected interface Confined {
- /* internal method needed for cast and instanceof
- * (this method will be generated for role classes) */
- ITeam _OT$getTeam();
- }
-
- /**
- * This class would have been generated by the OT-compiler.
- * Don't explicitly use it in client code!
- */
- protected class __OT__Confined implements Confined {
- // internal method needed for cast and instanceof
- public ITeam _OT$getTeam() {
- return Team.this; //$Debug(ConfinedGetTeam)
- }
- }
-
- /**
- * Internal function for identifying a Team.
- * Should not be called by client code.
- */
- public int _OT$getID () {return -1;}
-
- /**
- * The constant <code>ALL_THREADS</code> is used for global team (de-)activation.
- */
- public static final Thread ALL_THREADS = new Thread();
-
- private static final int _OT$UNREGISTERED = 0;
- private static final int _OT$REGISTERED = 1;
- private int _OT$registrationState = _OT$UNREGISTERED;
-
- private boolean _OT$globalActive = false;
-
- private ThreadLocal<Integer> _OT$implicitActivationsPerThread = new ThreadLocal<Integer>() {
- protected synchronized Integer initialValue() {
- return Integer.valueOf(0);
- }
- };
-
- private boolean _OT$lazyGlobalActiveFlag = false;
-
- /**
- * <code>_OT$activatedThreads</code> contains all threads for which this team instance is active.
- * key = activated thread
- * value = Boolean(true) for explicit activation | Boolean(false) for implicit activation.
- */
- private WeakHashMap<Thread, Boolean> _OT$activatedThreads = new WeakHashMap<Thread, Boolean>();
-
- /** This lock is used to protect activate/deactivate methods <strong>including</strong>
- * the calls to doRegistration/doUnregistration.
- */
- private Object _OT$registrationLock= new Object();
-
- /**
- * {@inheritDoc}
- */
- public void activate() {
- activate(Thread.currentThread());
- }
-
- /**
- * {@inheritDoc}
- */
- public void deactivate() {
- deactivate(Thread.currentThread());
- }
-
- /**
- * {@inheritDoc}
- */
- public void activate(Thread thread) {
- // acquire both locks to avoid incomplete execution:
- synchronized (this._OT$registrationLock) {
- synchronized (this) {
- if (thread.equals(ALL_THREADS)) {
- _OT$globalActive = true;
- _OT$lazyGlobalActiveFlag = true;
- TeamThreadManager.addGlobalActiveTeam(this);
- } else { // activation only for 'thread':
- // register 'thread' as active:
- _OT$activatedThreads.put(thread, Boolean.TRUE);
- }
- } // release this before calling synchronized base class methods
- doRegistration(); //$Debug(ActivateMethod)
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void deactivate(Thread thread) {
- // acquire both locks to avoid incomplete execution:
- synchronized (this._OT$registrationLock) {
- boolean shouldUnregister= false;
- synchronized(this) {
- if (thread.equals(ALL_THREADS)) {
- _OT$globalActive = false;
- TeamThreadManager.removeGlobalActiveTeam(this);
- // unregister all threads:
- _OT$activatedThreads.clear();
- shouldUnregister= true;
- } else { // deactivation only for 'thread':
- if (_OT$lazyGlobalActiveFlag) {
- // be eager now: activate for all (other) threads:
- _OT$activateForAllThreads();
- }
- // deactivate for 'thread', no longer active:
- _OT$activatedThreads.remove(thread);
- if (!_OT$lazyGlobalActiveFlag && _OT$activatedThreads.isEmpty()) {
- shouldUnregister= true;
- }
- }
- _OT$lazyGlobalActiveFlag = false;
- } // release this before calling synchronized base class methods
- if (shouldUnregister) //$Debug(DeactivateMethod)
- doUnregistration();
- }
- }
-
- public void deactivateForEndedThread(Thread thread) {
- synchronized (_OT$registrationLock) {
- boolean shouldUnregister= false;
- synchronized (this) {
- _OT$activatedThreads.remove(thread);
- if (!_OT$lazyGlobalActiveFlag && _OT$activatedThreads.isEmpty())
- shouldUnregister= true;
- }
- if (shouldUnregister)
- doUnregistration();
- }
- }
-
- private void _OT$activateForAllThreads() {
- HashSet threads = TeamThreadManager.getExistingThreads();
- Iterator it = threads.iterator();
- while (it.hasNext()) {
- Thread a_thread = (Thread) it.next();
- activate(a_thread); // use smaller activate version (no ALL_THREADS, no registerAtBases,...
- }
- }
-
- /**
- * This method is used for implicit activation in team-level methods.
- * Implicit activation only applies to the current thread.
- * Don't call it from client code.
- */
- public void _OT$implicitlyActivate() {
- synchronized (this._OT$registrationLock) {
- boolean shouldRegister= false;
- synchronized (this) {
- // this method is used for debugging purpose (team monitor)
- Thread currentThread = Thread.currentThread();
- if (!_OT$activatedThreads.containsKey(currentThread)) {
- // register 'thread' as active:
- _OT$activatedThreads.put(currentThread, Boolean.FALSE);
- shouldRegister= true;
- }
- // increment thread local implicit activaion counter:
- int implActCount = (_OT$implicitActivationsPerThread.get()).intValue();
- _OT$implicitActivationsPerThread.set(Integer.valueOf(implActCount + 1 ));
- }
- if (shouldRegister) //$Debug(ImplicitActivateMethod)
- doRegistration();
- }
- }
-
- /**
- * This method is used for implicitly deactivation in team-level methods.
- * It respects explicit activation changes and nested calls to team-level methods.
- * Implicit deactivation only applies to the current thread.
- * Don't call it from client code.
- */
- public void _OT$implicitlyDeactivate() {
- synchronized (this._OT$registrationLock) {
- boolean shouldUnregister= false;
- synchronized(this) {
- // this method is used for debugging purpose (team monitor)
- Thread currentThread = Thread.currentThread();
- boolean explicitlyActivated = false;
- if (_OT$activatedThreads.containsKey(currentThread)) {
- explicitlyActivated = ((Boolean) _OT$activatedThreads.get(currentThread)).booleanValue();
- }
- if (!explicitlyActivated
- && !_OT$lazyGlobalActiveFlag // no explicit activation overriding the implicit one
- && ((_OT$implicitActivationsPerThread.get()).intValue() == 1)) // this is the last implicit activation
- {
- _OT$activatedThreads.remove(currentThread);
- if (_OT$activatedThreads.isEmpty()) // there are not other threads for which this theam is active
- {
- shouldUnregister= true;
- }
- }
- // decrement thread local implicit activaion counter:
- int implActCount = (_OT$implicitActivationsPerThread.get()).intValue();
- _OT$implicitActivationsPerThread.set(Integer.valueOf(implActCount - 1));
- }
- if (shouldUnregister) //$Debug(ImplicitDeactivateMethod)
- doUnregistration();
- }
- }
-
- /**
- * Define whether per-thread activation of this team should be inheritable
- * such that the team will be activated automatically for any new threads
- * that are spawned from a thread for which the team is already active at that time.
- *
- * @param inheritable whether or not activation should be inheritable to new threads
- */
- public void setInheritableActivation(boolean inheritable) {
- if (inheritable)
- TeamThreadManager.registerTeamForActivationInheritance(this);
- else
- TeamThreadManager.unRegisterTeamForActivationInheritance(this);
- }
-
- // not API (for use by the TeamThreadManager)
- public boolean internalIsActiveSpecificallyFor(Thread t) {
- return this._OT$activatedThreads.containsKey(t);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isActive() {
- return isActive(Thread.currentThread());
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isActive(Thread thread) {
- if (thread.equals(ALL_THREADS)) {
- return _OT$globalActive;
- }
- if (_OT$lazyGlobalActiveFlag) {
- return true;
- } else {
- //if (!TeamThreadManager.getExistingThreads().contains(thread)) { // this thread is already finished!
- if (!thread.isAlive()) { // this thread is already finished!
- throw new IllegalThreadStateException("Called 'isActive(...)' for a thread which is no longer running!");
- }
- return _OT$activatedThreads.containsKey(thread);
- }
- }
-
-// ***** for restoring the activation state after a within block: ---->*****
- private static final int _OT$INACTIVE = 0;
- private static final int _OT$IMPLICIT_ACTIVE = 1;
- private static final int _OT$EXPLICIT_ACTIVE = 2;
-
- /**
- * {@inheritDoc}
- */
- public synchronized int _OT$saveActivationState() {
- int old_state = _OT$INACTIVE;
- if (_OT$lazyGlobalActiveFlag) {
- old_state = _OT$EXPLICIT_ACTIVE;
- } else {
- Thread current_thread = Thread.currentThread();
- if (_OT$activatedThreads.containsKey(current_thread)) {
- old_state = _OT$IMPLICIT_ACTIVE;
- if (((Boolean)_OT$activatedThreads.get(current_thread)).booleanValue()) {
- old_state = _OT$EXPLICIT_ACTIVE;
- }
- }
- }
- return old_state;
- }
-
- /**
- * {@inheritDoc}
- */
- public void _OT$restoreActivationState(int old_state) {
- synchronized (_OT$registrationLock) {
- if (old_state == _OT$INACTIVE) // team was inactive before:
- deactivate();
- else { // team was active before: has to be reactivated:
- boolean explicit = (old_state == _OT$EXPLICIT_ACTIVE);
- synchronized (this) {
- _OT$activatedThreads.put(Thread.currentThread(), Boolean.valueOf(explicit));
- }
- doRegistration();
- }
- }
- }
-// ***** <----for restoring the activation state after a within block. *****
-
-
- private void doRegistration() {
- if (_OT$registrationState == _OT$UNREGISTERED) {
- _OT$registerAtBases();
- _OT$registrationState = _OT$REGISTERED;
- }
- }
-
- private void doUnregistration() {
- if (_OT$registrationState == _OT$REGISTERED) {
- _OT$unregisterFromBases();
- _OT$registrationState = _OT$UNREGISTERED;
- }
- }
-
- /**
- * This method will be implemented by generated code in subteams.
- * It registers the team at every base playing one of its roles.
- * Don't call it from client code.
- */
- public void _OT$registerAtBases() {}
-
- /**
- * This method will be implemented by generated code in subteams.
- * It unregisters the team from every base playing one of its roles.
- * Don't call it from client code.
- */
- public void _OT$unregisterFromBases() {}
-
- //public int _OT$activationState = -1; // TODO: remove usage of this from generated code
-
-
- /**
- * {@inheritDoc}
- */
- public boolean hasRole(Object aBase) {
- // overriding method to be generated by the compiler for each team with bound roles.
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean hasRole(Object aBase, Class<?> roleType) throws IllegalArgumentException {
- // overriding method to be generated by the compiler for each team with bound roles.
- throw new IllegalArgumentException("No such bound role type in this team: "+roleType.getName());
- }
-
- /**
- * {@inheritDoc}
- */
- public Object getRole(Object aBase) {
- // overriding method to be generated by the compiler for each team with bound roles.
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- public <T> T getRole(Object aBase, Class<T> roleType) throws IllegalArgumentException {
- // overriding method to be generated by the compiler for each team with bound roles.
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- public Object[] getAllRoles() {
- // overriding method to be generated by the compiler for each team with bound roles.
- return new Object[0];
- }
-
- /**
- * {@inheritDoc}
- */
- public <T> T[] getAllRoles(Class<T> roleType) throws IllegalArgumentException {
- // overriding method to be generated by the compiler for each team with bound roles.
- throw new IllegalArgumentException("Class org.objectteams.Team has no bound roles.");
- }
-
- /** Internal variable to be set from generated code. */
- private boolean _OT$isExecutingCallin = false;
-
- /**
- * Method only for internal use by generated code.
- */
- public boolean _OT$setExecutingCallin(boolean newFlag) {
- boolean oldVal = _OT$isExecutingCallin;
- _OT$isExecutingCallin = newFlag;
- return oldVal;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isExecutingCallin() {
- return _OT$isExecutingCallin;
- }
-
- /**
- * {@inheritDoc}
- */
- public void unregisterRole(Object aRole) {
- // overriding method to be generated by the compiler for each team with bound roles.
- }
-
- /**
- * {@inheritDoc}
- */
- public void unregisterRole(Object aRole, Class<?> roleType) throws IllegalArgumentException {
- // overriding method to be generated by the compiler for each team with bound roles.
- }
-
- @Override
- protected void finalize() throws Throwable {
- // nop, hook for the debugger
- @SuppressWarnings("unused")
- int i= 2+3; // Note: body must not be empty for debuggger to be able to stop.
- } // $Debug(FinalizeMethod)
-
- /**
- * If a serializable team wishes to persist its global activation status it must
- * call this method from its writeObject() method and correspondingly call
- * {@link #readGlobalActivationState(ObjectInputStream)} from its readObject().
- */
- protected void writeGlobalActivationState(ObjectOutputStream out) throws IOException {
- out.writeBoolean(this._OT$globalActive);
- }
- /**
- * If a serializable team wishes to persist its global activation status it must
- * call this method from its readObject() method and correspondingly call
- * {@link #writeGlobalActivationState(ObjectOutputStream)} from its writeObject().
- * If a team is restored that was globally active when serialized, it will be activated
- * correspondingly during deserialization when this method is called.
- */
- protected void readGlobalActivationState(ObjectInputStream in) throws IOException {
- this._OT$globalActive = in.readBoolean();
- if (this._OT$globalActive) {
- this._OT$lazyGlobalActiveFlag = true;
- this.doRegistration();
- }
- }
- /**
- * Serializable teams must invoke this method once from their readObject() method
- * in order to re-initialize internal data structures.
- */
- protected void restore() { /* empty; implementation will be generated for each serializable sub-class. */ }
- /**
- * Serializable teams must invoke this method from their readObject() method
- * for each role that has been retrieved and shall be re-registered for this team.
- */
- protected void restoreRole(Class<?> clazz, Object role) { /* empty; implementation will be generated for each serializable sub-class. */ }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/TeamThreadManager.java b/othersrc/OTRE/src/org/objectteams/TeamThreadManager.java
deleted file mode 100644
index debccb712..000000000
--- a/othersrc/OTRE/src/org/objectteams/TeamThreadManager.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2006-2008 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: TeamThreadManager.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-import java.util.HashSet;
-import java.util.WeakHashMap;
-
-
-/**
- * This class is for internal use, only.
- *
- * Maintain information about existing threads as to manage
- * team activation per thread vs. globally.
- *
- * @author Chistine Hundt
- * @author Stephan Herrmann
- */
-public class TeamThreadManager {
-
- private static Object token = new Object();
-
- private static HashSet<ITeam> globalActiveTeams = new HashSet<ITeam>();
- private static WeakHashMap<ITeam,Object> teamsWithActivationInheritance = new WeakHashMap<ITeam,Object>();
- private static HashSet<Thread> existingThreads = new HashSet<Thread>();
-
- public static boolean newThreadStarted(boolean isMain, Thread parent) {
- Thread currentThread = Thread.currentThread();
- // already registered?
- if (existingThreads.contains(currentThread))
- return false;
- // workaround for application hang on Mac OS with Apple JVM:
- if (System.getProperty("os.name").startsWith("Mac"))
- if (currentThread.getName().equals("AWT-Shutdown"))
- return false;
-
- ITeam[] globalTeams;
- ITeam[] inheritableTeams;
- synchronized (TeamThreadManager.class) {
- existingThreads.add(currentThread);
- if (isMain) {
- for (Thread thread : fetchSystemThreads(currentThread))
- if (thread != null)
- existingThreads.add(thread);
- }
-
- globalTeams = globalActiveTeams.toArray(new ITeam[globalActiveTeams.size()]);
- inheritableTeams = teamsWithActivationInheritance.keySet().toArray(new ITeam[teamsWithActivationInheritance.size()]);
- }
- // activate teams outside synchronized block:
- for (ITeam t : globalTeams)
- t.activate(currentThread); // small version? global -> already registered...!
- if (parent != null)
- for (ITeam t : inheritableTeams)
- if (t.internalIsActiveSpecificallyFor(parent))
- t.activate(currentThread); // pass activation from parent to child thread
- return true;
- }
-
- /* Fetch all existing threads existing at this point in time. Result array is padded with nulls. */
- private static Thread[] fetchSystemThreads(Thread currentThread) {
- ThreadGroup group = currentThread.getThreadGroup();
- {
- ThreadGroup parentGroup;
- while ((parentGroup= group.getParent()) != null)
- group = parentGroup;
- }
- int size = group.activeCount();
- Thread[] allThreads;
- do {
- size += 2;
- allThreads = new Thread[size];
- } while (group.enumerate(allThreads) == size);
- return allThreads;
- }
-
- public static void threadEnded() {
- ITeam[] teamsToDeactivate = internalThreadEnded();
- // + remove per thread activation:
- for (ITeam t : teamsToDeactivate)
- //t.deactivate(Thread.currentThread()); // small version?
- t.deactivateForEndedThread(Thread.currentThread());
- }
- private synchronized static ITeam[] internalThreadEnded() {
- existingThreads.remove(Thread.currentThread());
- // fetch all global active teams for deactivation:
- return globalActiveTeams.toArray(new ITeam[globalActiveTeams.size()]);
- }
-
- public synchronized static void addGlobalActiveTeam(ITeam t) {
- globalActiveTeams.add(t);
- }
-
- public synchronized static void removeGlobalActiveTeam(ITeam t) {
- globalActiveTeams.remove(t);
- }
-
- public static HashSet<Thread> getExistingThreads() {
- return existingThreads;
- }
- public static void registerTeamForActivationInheritance(ITeam aTeam) {
- teamsWithActivationInheritance.put(aTeam,token);
- }
- public static void unRegisterTeamForActivationInheritance(ITeam aTeam) {
- teamsWithActivationInheritance.remove(aTeam);
- }
-
-}
diff --git a/othersrc/OTRE/src/org/objectteams/UnsupportedFeatureException.java b/othersrc/OTRE/src/org/objectteams/UnsupportedFeatureException.java
deleted file mode 100644
index 9b1c1ffcf..000000000
--- a/othersrc/OTRE/src/org/objectteams/UnsupportedFeatureException.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2004-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: UnsupportedFeatureException.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * @author resix
- */
-public class UnsupportedFeatureException extends RuntimeException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private static final String _bugmsg = "\nThe program encountered an unsupported situation! ";
-
- /**
- *
- */
- public UnsupportedFeatureException() {
- super(_bugmsg);
- }
-
- /**
- * @param message
- */
- public UnsupportedFeatureException(String message) {
- super(_bugmsg + "\n" + message);
- StackTraceElement[] ste = new StackTraceElement[0];
- setStackTrace(ste);
- }
-
- /**
- * @param cause
- */
- public UnsupportedFeatureException(Throwable cause) {
- super(_bugmsg + cause.toString());
- }
-
- /**
- * @param message
- * @param cause
- */
- public UnsupportedFeatureException(String message, Throwable cause) {
- super(_bugmsg + message/*+cause.toString()*/);
- }
-}
diff --git a/othersrc/OTRE/src/org/objectteams/WrongRoleException.java b/othersrc/OTRE/src/org/objectteams/WrongRoleException.java
deleted file mode 100644
index ed76541e3..000000000
--- a/othersrc/OTRE/src/org/objectteams/WrongRoleException.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**********************************************************************
- * This file is part of the "Object Teams Runtime Environment"
- *
- * Copyright 2003-2009 Berlin Institute of Technology, Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: WrongRoleException.java 23408 2010-02-03 18:07:35Z stephan $
- *
- * Please visit http://www.objectteams.org for updates and contact.
- *
- * Contributors:
- * Berlin Institute of Technology - Initial API and implementation
- **********************************************************************/
-package org.objectteams;
-
-/**
- * This exception is thrown by the OT/J infra structure if a role for a given base object
- * was requested during lifting, but a role with an incompatible type was already
- * registered for that base object. Can only happen if a compile time warning occurred.
- * @author Stephan Herrmann
- */
-public class WrongRoleException extends RuntimeException {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private Class<?> clazz;
- private Object base;
- private Object role;
-
- /**
- * @param clazz
- * @param base
- * @param role
- */
- public WrongRoleException (Class<?> clazz, Object base, Object role) {
- this.clazz = clazz;
- this.base = base;
- this.role = role;
- }
-
- public String getMessage() {
- String baseClazz = base.getClass().getName();
- String roleClazz = role.getClass().getName();
- return "The compiler has warned you about ambiguous role bindings.\n"
- + "Now lifting to " + clazz
- + " fails with the following objects\n"
- + "(see OT/J language definition para. 2.3.4(d)):\n"
- + "Provided:\n Base object: " + base + "\n" + " Base type: "
- + baseClazz + "\n"
- + "Found in cache:\n Role object: " + role + "\n"
- + " Role type: " + roleClazz;
- }
-}

Back to the top