* this routine because there may be name-specific
* instructions before and after the value.
*/
InstructionList generateGetOrSet(IASNode iNode, int opcode, InstructionList rhs)
{
InstructionList result = createInstructionList(iNode);
// Note: numerous microoptimization opportunities here
// to avoid storing values in temps by creative use of
// OP_dup and OP_swap, especially in getproperty gen.
if ( this.compileTimeQualifier != null && this.runtimeName != null )
{
// Generate MultinameL type code.
Binding name_temp = currentScope.allocateTemp();
result.addAll(this.runtimeName);
result.addInstruction(OP_dup);
result.addInstruction(name_temp.setlocal());
// findprop(MultinameL) consumes a name from the value stack.
result.addInstruction(OP_findpropstrict, this.compileTimeQualifier);
result.addInstruction(name_temp.getlocal());
if ( rhs != null )
result.addAll(rhs);
// get/setprop(MultinameL) consumes a name from the value stack.
result.addInstruction(opcode, this.compileTimeQualifier);
}
else if ( this.runtimeQualifier != null && this.runtimeName != null )
{
// Generate RTQnameL type code.
Binding name_temp = currentScope.allocateTemp();
Binding qual_temp = currentScope.allocateTemp();
Name rtqnl = new Name(CONSTANT_RTQnameL, null, null);
result.addAll(getRuntimeName(iNode));
result.addInstruction(name_temp.setlocal());
result.addAll(getRuntimeQualifier(iNode));
result.addInstruction(OP_dup);
result.addInstruction(qual_temp.setlocal());
result.addInstruction(name_temp.getlocal());
// findprop(RTQNameL) consumes namespace and name from the value stack.
result.addInstruction(OP_findpropstrict, rtqnl);
result.addInstruction(qual_temp.getlocal());
result.addInstruction(name_temp.getlocal());
if ( rhs != null )
result.addAll(rhs);
// get/setprop(RTQNameL) consumes namespace and name from the value stack.
result.addInstruction(opcode, rtqnl);
currentScope.releaseTemp(name_temp);
currentScope.releaseTemp(qual_temp);
}
else
{
// Last valid combination generates a RTQname.
assert(this.runtimeQualifier != null && this.compileTimeName != null) : "Unknown runtime name configuration: " + this.toString();
Name rtqn = new Name(CONSTANT_RTQname, null, this.compileTimeName.getBaseName());
result.addAll(getRuntimeQualifier(iNode));
result.addInstruction(OP_dup);
// findprop(RTQName) consumes a namespace from the value stack.
result.addInstruction(OP_findpropstrict, rtqn);
result.addInstruction(OP_swap);
if ( rhs != null )
result.addAll(rhs);
// get/setprop(RTQName) consumes a namespace from the value stack.
result.addInstruction(opcode, rtqn);
}
return result;
}