String concatenation optimization.

This commit is contained in:
James Roseborough
2010-07-28 14:53:39 +00:00
parent 55947437dd
commit 6965c9bb71
2 changed files with 23 additions and 5 deletions

View File

@@ -45,30 +45,34 @@ public final class Buffer {
return LuaString.valueOf(bytes, 0, length).tojstring();
}
public final void append( byte b ) {
public final Buffer append( byte b ) {
ensureCapacity( length + 1 );
bytes[ length++ ] = b;
return this;
}
public final void append( LuaValue val ) {
public final Buffer append( LuaValue val ) {
if ( ! val.isstring() )
val.error("attempt to concatenate a '"+val.typename()+"' value");
append( val.strvalue() );
return this;
}
public final void append( LuaString str ) {
public final Buffer append( LuaString str ) {
final int alen = str.length();
ensureCapacity( length + alen );
str.copyInto( 0, bytes, length, alen );
length += alen;
return this;
}
public final void append( String str ) {
public final Buffer append( String str ) {
char[] chars = str.toCharArray();
final int alen = LuaString.lengthAsUtf8( chars );
ensureCapacity( length + alen );
LuaString.encodeToUtf8( chars, bytes, length );
length += alen;
return this;
}
public final void setLength( int length ) {

View File

@@ -533,11 +533,25 @@ public class JavaCodeGen {
case Lua.OP_LE: out(evalLuaValue(exp.lhs)+".lteq("+evalNumber(exp.rhs)+")"); return;
case Lua.OP_EQ: out(evalLuaValue(exp.lhs)+".eq("+evalLuaValue(exp.rhs)+")"); return;
case Lua.OP_NEQ: out(evalLuaValue(exp.lhs)+".neq("+evalLuaValue(exp.rhs)+")"); return;
case Lua.OP_CONCAT: out(evalLuaValue(exp.lhs)+".concat("+evalLuaValue(exp.rhs)+")"); return;
case Lua.OP_CONCAT:
if ( isConcatExp(exp.rhs) ) {
out( "new Buffer().append("+evalLuaValue(exp.lhs)+")" );
Exp e = exp.rhs;
for ( ; isConcatExp(e); e=((BinopExp)e).rhs )
out( ".append("+evalLuaValue(((BinopExp)e).lhs)+")" );
out( ".append("+evalLuaValue(e)+")" );
out( ".tostring()" );
} else
out(evalLuaValue(exp.lhs)+".concat("+evalLuaValue(exp.rhs)+")");
return;
default: throw new IllegalStateException("unknown bin op:"+exp.op);
}
}
private boolean isConcatExp(Exp e) {
return (e instanceof BinopExp) && (((BinopExp)e).op == Lua.OP_CONCAT);
}
public void visit(UnopExp exp) {
exp.rhs.accept(this);
switch ( exp.op ) {