001: /*
002:
003: Derby - Class org.apache.derby.iapi.services.compiler.MethodBuilder
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.services.compiler;
023:
024: /**
025: MethodBuilder is used to generate the code for a method.
026: <P>
027:
028: The code for a method is built in a way that corresponds to the
029: layout of the stack machine that is the Java Virtual Machine.
030: Values are pushed on the stack, moved about on the stack
031: and then popped off the stack by operations such as method
032: calls. An understanding of hoe the JVM operates is useful
033: before using this class.
034:
035: <P>
036: All the method descriptions below are generating bytecode
037: to achieved the desired behaviour when the generated class
038: is loaded. None of this class's methods calls actually
039: invoke methods or create objects described by the callers.
040: */
041: public interface MethodBuilder {
042:
043: /**
044: * Declare the method throws an exception.
045: Must be called before any code is added
046: to the method.
047: */
048: public void addThrownException(String exceptionClass);
049:
050: /**
051: * return the name of the method.
052: */
053: public String getName();
054:
055: /**
056: Indicate the method is complete. Once this
057: call has been made the caller must discard
058: the reference to this object.
059: */
060: public void complete();
061:
062: /**
063: Push a parameter value.
064: <PRE>
065: Stack ... =>
066: ...,param_value
067: </PRE>
068: @param id position of the parameter (zero based).
069: */
070: public void getParameter(int id);
071:
072: /**
073: Push a byte constant onto the stack
074: <PRE>
075: Stack ... =>
076: ...,byte_value
077: </PRE>
078: */
079: public void push(byte value);
080:
081: /**
082: Push a boolean constant onto the stack
083: <PRE>
084: Stack ... =>
085: ...,boolean_value
086: </PRE>
087: */
088: public void push(boolean value);
089:
090: /**
091: Push a short constant onto the stack
092: <PRE>
093: Stack ... =>
094: ...,short_value
095: </PRE>
096: */
097: public void push(short value);
098:
099: /**
100: Push a int constant onto the stack
101: <PRE>
102: Stack ... =>
103: ...,int_value
104: </PRE>
105: */
106: public void push(int value);
107:
108: /**
109: Push a long constant onto the stack
110: <PRE>
111: Stack ... =>
112: ...,long_value
113: </PRE>
114: */
115: public void push(long value);
116:
117: /**
118: Push a float constant onto the stack
119: <PRE>
120: Stack ... =>
121: ...,float_value
122: </PRE>
123: */
124: public void push(float value);
125:
126: /**
127: Push a double constant onto the stack
128: <PRE>
129: Stack ... =>
130: ...,double_value
131: </PRE>
132: */
133: public void push(double value);
134:
135: /**
136: Push a String constant onto the stack
137: <PRE>
138: Stack ... =>
139: ...,String_value
140: </PRE>
141: */
142: public void push(String value);
143:
144: /**
145: Push a typed null onto the stack
146: <PRE>
147: Stack ... =>
148: ...,null
149: </PRE>
150: */
151: public void pushNull(String className);
152:
153: /**
154: Push the contents of the local field onto the stack.
155: This call pushes the this instance required to access the field itself.
156: <PRE>
157: Stack ... =>
158: ...,field_value
159: </PRE>
160:
161: */
162: public void getField(LocalField field);
163:
164: /**
165: Push the contents of the described field onto the stack.
166: This call requires the instance (reference) to be pushed by the caller.
167:
168: <PRE>
169: Stack ...,field_ref =>
170: ...,field_value
171: </PRE>
172:
173: */
174: public void getField(String declaringClass, String fieldName,
175: String fieldType);
176:
177: /**
178: Push the contents of the described static field onto the stack.
179: <PRE>
180: Stack ... =>
181: ...,field_value
182: </PRE>
183: */
184: public void getStaticField(String declaringClass, String fieldName,
185: String fieldType);
186:
187: /**
188: Pop the top stack value and store it in the local field.
189: This call pushes the this instance required to access the field itself.
190: This call does not leave any value on the stack.
191:
192: <PRE>
193: Stack ...,value =>
194: ...
195: </PRE>
196: */
197: public void setField(LocalField field);
198:
199: /**
200: Pop the top stack value and store it in the local field.
201: This call pushes the this instance required to access the field itself.
202: Like the Java language 'field = value', this leaves the value on the stack.
203:
204: <PRE>
205: Stack ...,value =>
206: ...,value
207: </PRE>
208: */
209: public void putField(LocalField field);
210:
211: /**
212: Pop the top stack value and store it in the instance field of this class.
213: This call pushes the this instance required to access the field itself.
214: Like the Java language 'field = value', this leaves the value on the stack.
215:
216: <PRE>
217: Stack ...,value =>
218: ...,value
219: </PRE>
220: */
221: public void putField(String fieldName, String fieldType);
222:
223: /**
224: Pop the top stack value and store it in the field.
225: This call requires the instance to be pushed by the caller.
226: Like the Java language 'field = value', this leaves the value on the stack.
227:
228: <PRE>
229: Stack ...,field_ref,value =>
230: ...,value
231: </PRE>
232: */
233: public void putField(String declaringClass, String fieldName,
234: String fieldType);
235:
236: /**
237: Initiate a sequence that calls a constructor, equivalent to the new operator in Java.
238: After this call, the caller must push any arguments and then complete the
239: construction with a call to pushNewComplete(). Only arguments to the constructor
240: can be pushed onto the stack between the pushNewStart() and pushNewComplete() method
241: calls.
242:
243: <PRE>
244: Stack ... => [unchanged]
245: ...
246: </PRE>
247:
248: @param className class name of object to be created.
249: */
250: public void pushNewStart(String className);
251:
252: /**
253: Complete the sequence that was started with pushNewStart().
254: Pop the arguments to the constructor and push the reference
255: to the newly created object.
256:
257: <PRE>
258: Stack ...,value* => [numArgs number of values will be popped]
259: ...,new_ref
260: </PRE>
261:
262: @param numArgs number of arguments to the constructor (can be 0).
263: */
264: public void pushNewComplete(int numArgs);
265:
266: /**
267: Create an instance of an array and push it onto the stack.
268:
269: <PRE>
270: Stack ... =>
271: ...,array_ref
272: </PRE>
273:
274: @param className - type of array.
275: @param size - number of elements in the array
276: */
277: public void pushNewArray(String className, int size);
278:
279: /**
280: Push this onto the stack.
281: <PRE>
282: Stack ... =>
283: ...,this_ref
284: </PRE>
285: */
286: public void pushThis();
287:
288: /**
289: Upcast the top stack value. This is used for correct method resolution
290: by upcasting method parameters. It does not put any casting code into the
291: byte code stream. Can only be used for refrences.
292: <PRE>
293: Stack ...,ref =>
294: ...,ref
295: </PRE>
296: */
297: public void upCast(String className);
298:
299: /**
300: Cast the top stack value. Correctly down-casts a reference or casts
301: a primitive type (e.g. int to short).
302: <PRE>
303: Stack ...,value =>
304: ...,cast_value
305: </PRE>
306:
307: @param className type (primitive, interface or class) to cast to.
308: */
309: public void cast(String className);
310:
311: /**
312: Pop the top stack value and push a boolean that is the result of
313: an instanceof check on the popped reference.
314: <PRE>
315: Stack ...,ref =>
316: ...,boolean_value
317: </PRE>.
318: */
319: public void isInstanceOf(String className);
320:
321: /**
322: * Pop the top value off the stack
323: <PRE>
324: Stack ..., value =>
325: ...
326: </PRE>.
327: */
328: public void pop();
329:
330: /**
331: End a statement.
332: Pops the top-word of the stack, if any.
333: Must only be called if zero or one item exists
334: on the stack.
335: <PRE>
336: Stack value =>
337: :empty:
338: or
339:
340: Stack :empty: =>
341: :empty:
342:
343: </PRE>.
344: */
345: public void endStatement();
346:
347: /**
348: Return from a method, optionally with a value.
349: Must only be called if zero or one item exists
350: on the stack. If the stack contains a single
351: value then that is popped and used as the returned value.
352: <PRE>
353: Stack value =>
354: :empty:
355: or
356:
357: Stack :empty: =>
358: :empty:
359:
360: </PRE>.
361: */
362: public void methodReturn();
363:
364: /**
365: Initiate a conditional sequence.
366: The top value on the stack (a reference) is popped and compared to 'null'.
367: If the value is null then the code following this call until the startElseCode()
368: will be executed at runtime, otherwise the code following startElseCode() until
369: the completeConditional() is called.
370: <BR>
371: E.g.
372:
373: <PRE>
374: mb.callMethod(...); // pushes an object onto the stack
375: mb.conditionalIfNull();
376: mb.push(3);
377: mb.startElseCode();
378: mb.push(5);
379: mb.completeConditional();
380: // at this point 3 or 5 will be on the stack
381: </PRE>
382:
383: Each path through the ?: statement must leave the stack at the same depth
384: as the other.
385: <BR>
386: If the if or else code pops values from the stack that were before the conditional
387: value, then they must use the same number of values from the stack.
388:
389: <PRE>
390: Stack ...,ref =>
391: ...
392: </PRE>.
393:
394: */
395:
396: public void conditionalIfNull();
397:
398: /**
399: Initiate a conditional sequence.
400: The top value on the stack must be a boolean and will be popped. If it
401: is true then the code following this call until the startElseCode()
402: will be executed at runtime, otherwise the code following startElseCode() until
403: the completeConditional() is called. See conditionalIfNull() for example
404: and restrictions.
405:
406: <PRE>
407: Stack ...,boolean_value =>
408: ...
409: </PRE>.
410: */
411: public void conditionalIf();
412:
413: /**
414: Complete the true code path of a conditional.
415: */
416: public void startElseCode();
417:
418: /**
419: Complete a conditional which completes the false code path.
420: */
421: public void completeConditional();
422:
423: /**
424: Call a method. The instance (receiver or reference) for non-static methods
425: must be pushed by the caller. The instance (for non-static) and the arguments
426: are popped of the stack, and the return value (if any) is pushed onto the stack.
427: <BR>
428: The type needs to be one of:
429: <UL>
430: <LI> VMOpcode.INVOKESTATIC - call a static method
431: <LI> VMOpcode.INVOKEVIRTUAL - call method declared in the class or super-class.
432: <LI> VMOpcode.INVOKEINTERFACE - call a method declared in an interface
433: </UL>
434:
435:
436: <PRE>
437: static methods
438:
439: Stack ...,value* => [numArgs number of values will be popped]
440: ...,return_value [void methods will not push a value]
441:
442: non-static methods
443:
444: Stack ...,ref,value* => [numArgs number of values will be popped]
445: ...,return_value [void methods will not push a value]
446: </PRE>
447:
448: <BR>
449: The type of the arguments to the methods must exactly match the declared types
450: of the parameters to the methods. If a argument is of the incorrect type the
451: caller must up cast it or down cast it.
452:
453: @param type type of method invocation
454: @param declaringClass Class or interface the method is declared in. If it is a non-static
455: method call then if declaringClass is null, the declared type is taken to be the
456: type of the reference that will be popped.
457:
458: @param methodName name of the method
459: @param returnType class name or primitive type (including "void") of the return type of the method, can not be null.
460: @param numArgs number of arguments to the method (can be 0).
461:
462: */
463: public int callMethod(short type, String declaringClass,
464: String methodName, String returnType, int numArgs);
465:
466: /**
467: Return an object that efficiently (to the implementation) describes a zero-argument method and
468: can be used with the single argument callMethod(). Descriptions for the parameters to this
469: method are the same as the five argument callMethod(). This allows the caller to cache frequently
470: used methods. The returned object is only valid for use by this MethodBuilder.
471: <BR>
472: This call does not affect the Stack.
473: */
474: public Object describeMethod(short opcode, String declaringClass,
475: String methodName, String returnType);
476:
477: /**
478: Call a method previously described by describeMethod().
479: <PRE>
480: static methods
481:
482: Stack ...,value* => [numArgs number of values will be popped]
483: ...,return_value [void methods will not push a value]
484:
485: non-static methods
486:
487: Stack ...,ref,value* => [numArgs number of values will be popped]
488: ...,return_value [void methods will not push a value]
489: </PRE>
490:
491: */
492: public int callMethod(Object methodDescriptor);
493:
494: /**
495: Call super(). Caller must only add this to a constructor.
496: <PRE>
497:
498: Stack ... =>
499: ...
500: </PRE>
501:
502: */
503: public void callSuper();
504:
505: /**
506: Pop an array refrence off the stack and push an element from that array.
507: <PRE>
508: Stack ...,array_ref =>
509: ...,value
510: </PRE>
511:
512: @param element Offset into the array (zero based)
513: */
514: public void getArrayElement(int element);
515:
516: /**
517: Pop an array reference off the stack, store a value in the array at the passed in offset.
518: <PRE>
519: Stack ...,array_ref, value =>
520: ...
521: </PRE>
522:
523: @param element Offset into the array (zero based)
524: */
525: public void setArrayElement(int element);
526:
527: /**
528: Swap the top two values on the stack.
529: <PRE>
530: Stack ...,valueA,valueB =>
531: ...,valueB,valueA
532: </PRE>
533: */
534: public void swap();
535:
536: /**
537: Duplicate the top value on the stack.
538: <PRE>
539: Stack ...,value =>
540: ...,value,value
541: </PRE>
542: */
543: public void dup();
544:
545: /**
546: Tell if statement number in this method builder hits limit. This
547: method builder keeps a counter of how many statements are added to it.
548: Caller should call this function every time it tries to add a statement
549: to this method builder (counter is increased by 1), then the function
550: returns whether the accumulated statement number hits a limit.
551: The reason of doing this is that Java compiler has a limit of 64K code
552: size for each method. We might hit this limit if an extremely long
553: insert statement is issued, for example (see beetle 4293). Counting
554: statement number is an approximation without too much overhead.
555: */
556: public boolean statementNumHitLimit(int noStatementsAdded);
557: }
|