Home » Language IDEs » Objectteams » Change code generated for base call in callin
Change code generated for base call in callin [message #1791082] |
Fri, 22 June 2018 14:07 |
|
Hi,
I want to change the code generated by the otj adoption of the JDT for a basecall in a callin.
Currently, it will be generated as this$0._OT$callNext(...);
I want to generate something different and I am looking for the place where this happens. I am currently looking at o.e.o.o.i.core.compiler.ast.BaseCallMessageSend#prepareSuperAccess which prepares the arguments for the base call.
I think I did not discovered where directly the callNext() is generated, or am I already at the right spot? Maybe, I just have a knot in my head.
Cheers,
Lars
[Updated on: Mon, 25 June 2018 07:51] Report message to a moderator
|
|
|
Re: Change code generated for base call in callin [message #1791362 is a reply to message #1791082] |
Thu, 28 June 2018 11:53 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
This is a bit hidden, I agree.
BaseCallMessageSend is of course a good place to look.
From "base.thisMethod(arg1)" we go to "this$0._OT$callNext(_OT$baseArg, _OT$teams, _OT$index, _OT$callinIds, _OT$boundMethodId, _OT$args, new Object[] { arg1 }, 1)" in several steps:
- Re-arrange (pack) arguments in BCMS.prepareSuperAccess() (name of the method is no longer accurate, I admit)
- "Enhance" this signature, i.e., prepend the _OT$... arguments in TransformStatementsVisitor.visit(MessageSend,BlockScope).
- Adjust the receiver in BaseReference.adjustReceiver() to become "MyTeam.this" (from where codegen creates this$0)
- Replace the selector in BCMS.resolveType() to go from "thisMethod" to "_OT$callNext".
- Finally, if the method is non-void, the message send is wrapped in an assignment "_OT$result = ..."
Does this help?
Stephan
|
|
| |
Re: Change code generated for base call in callin [message #1794093 is a reply to message #1793661] |
Thu, 23 August 2018 12:14 |
Lars Schütze Messages: 16 Registered: June 2018 |
Junior Member |
|
|
Okay, now it gets little bit interesting.
Before, BCMS put into the wrappee the qualified this reference of the receiver type (i.e., the role type name) to become R.this or MyTeam.this (BCMS#81, BCMS#89) I want to point to another class (namely holding the bootstrap method of the invokedynamic).
this._wrappee = gen.qualifiedTypeReference(new char[][] { dynamicCallinBootstrapTypeName });
When running the code, it cannot resolve the mentioned type
[javac] ----------
[javac] 12. ERROR in /Users/lschuetze/Development/repos/role-benchmarks/benchmarks/objectteams-compiler-work/invy/src/benchmark/bank/CallinTransaction.java (at line 30)
[javac] base.deposit(amount);
[javac] ^^^^^^^^^^^^^^^^^^^^
[javac] org.eclipse.objectteams.otredyn.runtime.dynamic.CallinBootstrap cannot be resolved toa type
[javac] ----------
How can I add that type to the scope to be resolved? I already tried to add it to the runtime (via ant class path) during javac.
I was now trying different possible methods of the generator without any success.
I also have the feeling, because BaseReference inherits from ThisReference, that I have to change that to become a subclass of NameReference and everything that follows from that refactoring.
[Updated on: Thu, 23 August 2018 13:56] Report message to a moderator
|
|
| | | |
Re: Change code generated for base call in callin [message #1794316 is a reply to message #1794314] |
Tue, 28 August 2018 19:53 |
Lars Schütze Messages: 16 Registered: June 2018 |
Junior Member |
|
|
I think I have to work out some class loader problem in combination with Java 9, or with class path things and ant.
Quote:Did you add that line to the compiler class BaseReference or did you let the compiler generate this into the target code?
I added that line to the compiler class to be sure that it is present when ant javac task tries to compile code. But, that also fails at runtime.
Adding a class from the same package works using TestBootstrap t = new TestBootstrap(); , but referencing a class as base-reference from the same package via in BaseReference this._wrappee = gen.qualifiedTypeReference(new char[][] { "org.eclipse.objectteams.otdt.internal.core.compiler.ast.TestBootstrap".toCharArray() }); also results in a [javac] org.eclipse.objectteams.otdt.internal.core.compiler.ast.TestBootstrap cannot be resolved to a type
[Updated on: Tue, 28 August 2018 19:56] Report message to a moderator
|
|
| |
Re: Change code generated for base call in callin [message #1794416 is a reply to message #1794317] |
Thu, 30 August 2018 11:40 |
Lars Schütze Messages: 16 Registered: June 2018 |
Junior Member |
|
|
Quote:That NameEnvironment is the compile time representation of the -classpath argument passed to the compiler. From your previous post, I would expect, e.g., classes from otre_min.jar and otredyn.jar to be found during LE.askForType, no?
The LookupEnvironment::nameEnvironment contains both jars, askForType also is called with things like Team, Confined etc., but it seems to be just classes from runtime plugin from org.objectteams and nothing from org.eclipse.objectteams.*
Also, when I change the qualified base reference to this._wrappee = gen.qualifiedTypeReference(CharOperation.splitOn('.', "org.eclipse.objectteams.otdt.internal.core.compiler.ast.TestBootstrap".toCharArray())); the error is [javac] base.limited(20.0f);
[javac] ^^^^^^^^^^^^^^^^^^^
[javac] org.eclipse.objectteams.otdt cannot be resolved to a type
[javac] ----------
[Updated on: Thu, 30 August 2018 11:50] Report message to a moderator
|
|
|
Re: Change code generated for base call in callin [message #1794428 is a reply to message #1794416] |
Thu, 30 August 2018 13:53 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
Quote:The LookupEnvironment::nameEnvironment contains both jars
good.
Quote:askForType also is called with things like Team, Confined etc., but it seems to be just classes from runtime plugin from org.objectteams and nothing from org.eclipse.objectteams.*
You should be able to debug right from BaseReference.resolveType(), right where it says "this._wrappee.resolveType(scope)" up until LE.askForType(), right? One implicit assumption: _wrappee is set before resolveTypes(), is it?
Quote: Also, when I change the qualified base reference to ... "org.eclipse.objectteams.otdt.internal.core.compiler.ast.TestBootstrap"
this shouldn't surprise, since that would need org.eclipse.jdt.core on the build path in the current compiler invocation, and from the above I assume it isn't. Somehow, you seem to assume that the compiler can always find its own classes during compilation, which it can't. Classes loaded into the JVM have no relation to the set of classes observable via NameEnvironment.
So, why don't you go back to org.eclipse.objectteams.otredyn.runtime.dynamic.CallinBootstrap, ensure it is contained in one of the jars visible to NameEnvironment. Then see if NameEnvironment can find the type during compilation (via askForType of course).
|
|
|
Re: Change code generated for base call in callin [message #1794432 is a reply to message #1794428] |
Thu, 30 August 2018 14:36 |
Lars Schütze Messages: 16 Registered: June 2018 |
Junior Member |
|
|
Quote:You should be able to debug right from BaseReference.resolveType(), right where it says "this._wrappee.resolveType(scope)" up until LE.askForType(), right? One implicit assumption: _wrappee is set before resolveTypes(), is it? Yes, I AM ! :-) It is set and it also find it now. So, classpath works and also the QualifiedReference is set now in the right way! Thanks.
Quote:this shouldn't surprise, since that would need org.eclipse.jdt.core on the build path in the current compiler invocation, and from the above I assume it isn't. Somehow, you seem to assume that the compiler can always find its own classes during compilation, which it can't. Classes loaded into the JVM have no relation to the set of classes observable via NameEnvironment. Yeah, I was assuming that somehow.
[javac] base.deposit(amount);
[javac] ^^^^^^^^^^^^^^^^^^^^
[javac] Illegal method in base call, can only call base version of the enclosing method deposit(float) (OTJLD 4.3(a)). Now I have to work me through the static semantics checks. I've already seen that you sometimes switch between the "shadow" AST. I'll have t debug where it fails and then adapt these parts.
Thanks anyway for your help!
|
|
| |
Re: Change code generated for base call in callin [message #1794453 is a reply to message #1794436] |
Thu, 30 August 2018 18:48 |
Lars Schütze Messages: 16 Registered: June 2018 |
Junior Member |
|
|
Quote:First thing to check: what is the problemId in the given ProblemMethodBinding In MethodBinding::problemReason there is a 1 (ProblemReasons.NotFound) and in ProblemReporter::handle the problemId is IProblem.BaseCallNotSameMethod.
In BaseCallProblemReporterWrapper::invalidMethod it goes into this._wrappee.baseCallNotSameMethod(enclosingMethodDecl, messageSend); because problemMethod.closestMatch is null.
Now I have to adjust the generated arguments, because they differ to _OT$callNext.
The interesting part will be that I have to pack some arguments on the stack where part of it will be consumed by invoking the static bootstrap method and the others by invoking the resulting callsite.
Since InvokeDynamic is a little bit different than normal virtual method calls I am a little bit puzzled how I am approaching this from the compiler POV. Using ASM library it is quite easy <put runtime arguments on stack>
<mDescr:= create a type descriptor of the method that should result from the bootstrap>
newInstructions.add(new InvokeDynamicInsnNode(method.name.replaceAll("[<>]", ""), mDescr /* method.descr */, bootstrapHandle, joinpointDescr));
However, it fails already before even generating code. So, how can I make it treat that reference and selector special in the sense of an invokedynamic?
[Updated on: Mon, 03 September 2018 09:52] Report message to a moderator
|
|
|
Re: Change code generated for base call in callin [message #1795085 is a reply to message #1794453] |
Fri, 14 September 2018 08:25 |
Lars Schütze Messages: 16 Registered: June 2018 |
Junior Member |
|
|
For now, base calls will be expanded to point to the bootstrap method (which I now named CallinBootstrap::callNext). Therefore, I changed MethodSignatureEnhancer to add the j.l.invoke.MethodHandles.Lookup, String, j.l.invoke.MethodType plus the old enhanced arguments to those base calls.
However, I noticed that this code is shared among replace callin methods that are enhanced. The compiler does work for now, but now role methods signature will be enhanced to MethodHandle(__OT__Source,Lookup,String,MethodType,IBoundBase2,ITeam[],int,int[],int,Object[],float)Object
The idea was to change base calls to point to the invokedynamic bootstrap and leave role methods untouched. Now I have to understand all the places where MSE::ENHANCING_ARG_LENGTH and MSE::enhanceArguments() and MSE::enhanceParameters() is used and substitute those places with a method which qualifies on if it is concerned with a base call or not.
For now I just NOP the extra arguments in the first bootstrap method with MethodHandles.inserArguments(roleMethod, 1, null, null, null) which kind of deletes these unused arguments.
I still did not find out how to change the former base call to an invokedynamic. For now, it just calls the static bootstrap method. Can you help me and point me to the location where those decisions are done?
[Updated on: Fri, 14 September 2018 09:20] Report message to a moderator
|
|
| | | | | | |
Goto Forum:
Current Time: Tue Apr 23 15:34:31 GMT 2024
Powered by FUDForum. Page generated in 0.04755 seconds
|