@Override void write(MethodWriter writer) { writer.writeStatementOffset(offset); expression.write(writer); writer.returnValue(); }
/** * Handles writing byte code for variable/method chains for all given possibilities including * String concatenation, compound assignment, regular assignment, and simple reads. Includes * proper duplication for chained assignments and assignments that are also read from. */ @Override void write(MethodWriter writer, Globals globals) { writer.writeDebugInfo(location); // For the case where the assignment represents a String concatenation // we must, depending on the Java version, write a StringBuilder or // track types going onto the stack. This must be done before the // lhs is read because we need the StringBuilder to be placed on the // stack ahead of any potential concatenation arguments. int catElementStackSize = 0; if (cat) { catElementStackSize = writer.writeNewStrings(); } // Cast the lhs to a storeable to perform the necessary operations to store the rhs. AStoreable lhs = (AStoreable) this.lhs; lhs.setup( writer, globals); // call the setup method on the lhs to prepare for a load/store operation if (cat) { // Handle the case where we are doing a compound assignment // representing a String concatenation. writer.writeDup( lhs.accessElementCount(), catElementStackSize); // dup the top element and insert it // before concat helper on stack lhs.load(writer, globals); // read the current lhs's value writer.writeAppendStrings(lhs.actual); // append the lhs's value using the StringBuilder rhs.write(writer, globals); // write the bytecode for the rhs if (!(rhs instanceof EBinary) || !((EBinary) rhs).cat) { // check to see if the rhs has already done a concatenation writer.writeAppendStrings(rhs.actual); // append the rhs's value since it's hasn't already } writer.writeToStrings(); // put the value for string concat onto the stack writer.writeCast(back); // if necessary, cast the String to the lhs actual type if (lhs.read) { writer.writeDup(lhs.actual.sort.size, lhs.accessElementCount()); // if this lhs is also read // from dup the value onto the stack } lhs.store( writer, globals); // store the lhs's value from the stack in its respective variable/field/array } else if (operation != null) { // Handle the case where we are doing a compound assignment that // does not represent a String concatenation. writer.writeDup(lhs.accessElementCount(), 0); // if necessary, dup the previous lhs's value // to be both loaded from and stored to lhs.load(writer, globals); // load the current lhs's value if (lhs.read && post) { writer.writeDup( lhs.actual.sort.size, lhs.accessElementCount()); // dup the value if the lhs is also // read from and is a post increment } writer.writeCast(there); // if necessary cast the current lhs's value // to the promotion type between the lhs and rhs types rhs.write(writer, globals); // write the bytecode for the rhs // XXX: fix these types, but first we need def compound assignment tests. // its tricky here as there are possibly explicit casts, too. // write the operation instruction for compound assignment if (promote.sort == Sort.DEF) { writer.writeDynamicBinaryInstruction( location, promote, Definition.DEF_TYPE, Definition.DEF_TYPE, operation, DefBootstrap.OPERATOR_COMPOUND_ASSIGNMENT); } else { writer.writeBinaryInstruction(location, promote, operation); } writer.writeCast(back); // if necessary cast the promotion type value back to the lhs's type if (lhs.read && !post) { writer.writeDup( lhs.actual.sort.size, lhs.accessElementCount()); // dup the value if the lhs is also // read from and is not a post increment } lhs.store( writer, globals); // store the lhs's value from the stack in its respective variable/field/array } else { // Handle the case for a simple write. rhs.write(writer, globals); // write the bytecode for the rhs rhs if (lhs.read) { writer.writeDup( lhs.actual.sort.size, lhs.accessElementCount()); // dup the value if the lhs is also read from } lhs.store( writer, globals); // store the lhs's value from the stack in its respective variable/field/array } }
@Override void write(MethodWriter writer) { index.write(writer); }