Merge branch 'master' into synchronized-methods

This commit is contained in:
Alexey Andreev 2015-04-01 19:23:03 +03:00
commit 5faaa1d061
7 changed files with 55 additions and 27 deletions

View File

@ -1358,9 +1358,9 @@ public class TArrays extends TObject {
if (a == null) { if (a == null) {
return 0; return 0;
} }
int hash = 0xA5A537FC; int hash = 1;
for (int i = 0; i < a.length; ++i) { for (int i = 0; i < a.length; ++i) {
hash = TInteger.rotateLeft(a[i], 4) ^ TInteger.rotateRight(a[i], 7) ^ TInteger.rotateLeft(hash, 13); hash = 31 * hash + a[i];
} }
return hash; return hash;
} }
@ -1369,9 +1369,9 @@ public class TArrays extends TObject {
if (a == null) { if (a == null) {
return 0; return 0;
} }
int hash = 0xA5A537FC; int hash = 1;
for (int i = 0; i < a.length; ++i) { for (int i = 0; i < a.length; ++i) {
hash = TInteger.rotateLeft(a[i], 4) ^ TInteger.rotateRight(a[i], 7) ^ TInteger.rotateLeft(hash, 13); hash = 31 * hash + a[i];
} }
return hash; return hash;
} }
@ -1380,9 +1380,9 @@ public class TArrays extends TObject {
if (a == null) { if (a == null) {
return 0; return 0;
} }
int hash = 0xA5A537FC; int hash = 1;
for (int i = 0; i < a.length; ++i) { for (int i = 0; i < a.length; ++i) {
hash = TInteger.rotateLeft(a[i], 4) ^ TInteger.rotateRight(a[i], 7) ^ TInteger.rotateLeft(hash, 13); hash = 31 * hash + a[i];
} }
return hash; return hash;
} }
@ -1391,9 +1391,9 @@ public class TArrays extends TObject {
if (a == null) { if (a == null) {
return 0; return 0;
} }
int hash = 0xA5A537FC; int hash = 1;
for (int i = 0; i < a.length; ++i) { for (int i = 0; i < a.length; ++i) {
hash = TInteger.rotateLeft(a[i], 4) ^ TInteger.rotateRight(a[i], 7) ^ TInteger.rotateLeft(hash, 13); hash = 31 * hash + a[i];
} }
return hash; return hash;
} }

View File

@ -65,7 +65,7 @@ public final class ModelUtils {
return copy; return copy;
} }
private static void copyAnnotations(AnnotationContainerReader src, AnnotationContainer dst) { public static void copyAnnotations(AnnotationContainerReader src, AnnotationContainer dst) {
for (AnnotationReader annot : src.all()) { for (AnnotationReader annot : src.all()) {
dst.add(copyAnnotation(annot)); dst.add(copyAnnotation(annot));
} }

View File

@ -479,7 +479,7 @@ public final class JS {
}; };
} }
public static <T extends JSObject> Iterable<String> iterate(final JSStringArrayReader array) { public static Iterable<String> iterate(final JSStringArrayReader array) {
return new Iterable<String>() { return new Iterable<String>() {
@Override public Iterator<String> iterator() { @Override public Iterator<String> iterator() {
return new Iterator<String>() { return new Iterator<String>() {

View File

@ -15,10 +15,7 @@
*/ */
package org.teavm.jso; package org.teavm.jso;
import java.lang.annotation.ElementType; import java.lang.annotation.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** /**
* *
@ -26,5 +23,6 @@ import java.lang.annotation.Target;
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Inherited
public @interface JSFunctor { public @interface JSFunctor {
} }

View File

@ -35,17 +35,16 @@ public class JSBodyGenerator implements Generator {
boolean isStatic = annot.getValue("isStatic").getBoolean(); boolean isStatic = annot.getValue("isStatic").getBoolean();
List<AnnotationValue> paramNames = annot.getValue("params").getList(); List<AnnotationValue> paramNames = annot.getValue("params").getList();
int bodyParamCount = method.parameterCount(); int bodyParamCount = isStatic ? method.parameterCount() : method.parameterCount() - 1;
int offset = isStatic ? 1 : 0;
writer.append("if (!").appendMethodBody(methodRef).append(".$native)").ws().append('{').indent().newLine(); writer.append("if (!").appendMethodBody(methodRef).append(".$native)").ws().append('{').indent().newLine();
writer.appendMethodBody(methodRef).append(".$native").ws().append('=').ws().append("function("); writer.appendMethodBody(methodRef).append(".$native").ws().append('=').ws().append("function(");
int count = method.parameterCount() + (isStatic ? 0 : 1); int count = method.parameterCount();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
if (i > 0) { if (i > 0) {
writer.append(',').ws(); writer.append(',').ws();
} }
writer.append('_').append(context.getParameterName(i + offset)); writer.append('_').append(context.getParameterName(i + 1));
} }
writer.append(')').ws().append('{').softNewLine().indent(); writer.append(')').ws().append('{').softNewLine().indent();
@ -68,7 +67,7 @@ public class JSBodyGenerator implements Generator {
if (i > 0) { if (i > 0) {
writer.append(',').ws(); writer.append(',').ws();
} }
writer.append('_').append(context.getParameterName(i + offset)); writer.append('_').append(context.getParameterName(i + 1));
} }
writer.append(");").softNewLine(); writer.append(");").softNewLine();
writer.outdent().append("};").softNewLine(); writer.outdent().append("};").softNewLine();
@ -81,7 +80,7 @@ public class JSBodyGenerator implements Generator {
if (i > 0) { if (i > 0) {
writer.append(',').ws(); writer.append(',').ws();
} }
writer.append(context.getParameterName(i + offset)); writer.append(context.getParameterName(i + 1));
} }
writer.append(");").softNewLine(); writer.append(");").softNewLine();
} }

View File

@ -23,6 +23,7 @@ import org.teavm.jso.*;
import org.teavm.model.*; import org.teavm.model.*;
import org.teavm.model.instructions.*; import org.teavm.model.instructions.*;
import org.teavm.model.util.InstructionVariableMapper; import org.teavm.model.util.InstructionVariableMapper;
import org.teavm.model.util.ModelUtils;
import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.ProgramUtils;
/** /**
@ -80,7 +81,11 @@ class JavascriptNativeProcessor {
public void processFinalMethods(ClassHolder cls) { public void processFinalMethods(ClassHolder cls) {
// TODO: don't allow final methods to override anything // TODO: don't allow final methods to override anything
for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) { for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) {
if (method.hasModifier(ElementModifier.FINAL) && method.getProgram() != null) { if (method.hasModifier(ElementModifier.STATIC)) {
continue;
}
if (method.hasModifier(ElementModifier.FINAL) && method.getProgram() != null &&
method.getProgram().basicBlockCount() > 0) {
ValueType[] staticSignature = getStaticSignature(method.getReference()); ValueType[] staticSignature = getStaticSignature(method.getReference());
MethodHolder callerMethod = new MethodHolder(new MethodDescriptor(method.getName() + "$static", MethodHolder callerMethod = new MethodHolder(new MethodDescriptor(method.getName() + "$static",
staticSignature)); staticSignature));
@ -115,6 +120,7 @@ class JavascriptNativeProcessor {
} }
} }
callerMethod.setProgram(program); callerMethod.setProgram(program);
ModelUtils.copyAnnotations(method.getAnnotations(), callerMethod.getAnnotations());
cls.addMethod(callerMethod); cls.addMethod(callerMethod);
} }
} }
@ -188,11 +194,13 @@ class JavascriptNativeProcessor {
continue; continue;
} }
if (method.hasModifier(ElementModifier.FINAL)) { if (method.hasModifier(ElementModifier.FINAL)) {
invoke.setMethod(new MethodReference(method.getOwnerName(), method.getName() + "$static", if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) {
getStaticSignature(method.getReference()))); invoke.setMethod(new MethodReference(method.getOwnerName(), method.getName() + "$static",
getStaticSignature(method.getReference())));
invoke.getArguments().add(0, invoke.getInstance());
invoke.setInstance(null);
}
invoke.setType(InvocationType.SPECIAL); invoke.setType(InvocationType.SPECIAL);
invoke.getArguments().add(0, invoke.getInstance());
invoke.setInstance(null);
continue; continue;
} }
CallLocation callLocation = new CallLocation(methodToProcess.getReference(), insn.getLocation()); CallLocation callLocation = new CallLocation(methodToProcess.getReference(), insn.getLocation());
@ -390,6 +398,9 @@ class JavascriptNativeProcessor {
for (int i = 0; i < paramCount; ++i) { for (int i = 0; i < paramCount; ++i) {
params.add(program.createVariable()); params.add(program.createVariable());
} }
if (isStatic) {
program.createVariable();
}
methodToProcess.setProgram(program); methodToProcess.setProgram(program);
// Generate invoke instruction // Generate invoke instruction
@ -398,7 +409,7 @@ class JavascriptNativeProcessor {
invoke.setType(InvocationType.SPECIAL); invoke.setType(InvocationType.SPECIAL);
invoke.setMethod(proxyMethod.getReference()); invoke.setMethod(proxyMethod.getReference());
for (int i = 0; i < paramCount; ++i) { for (int i = 0; i < paramCount; ++i) {
Variable var = program.createVariable(); Variable var = program.variableAt(isStatic ? i + 1 : i);
invoke.getArguments().add(wrapArgument(location, var, paramTypes[i])); invoke.getArguments().add(wrapArgument(location, var, paramTypes[i]));
} }
block.getInstructions().addAll(replacement); block.getInstructions().addAll(replacement);
@ -580,7 +591,7 @@ class JavascriptNativeProcessor {
} }
Variable result = program.createVariable(); Variable result = program.createVariable();
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(new MethodReference(JS.class.getName(), "wrap", type, getWrapperType(type))); insn.setMethod(new MethodReference(JS.class.getName(), "wrap", getWrappedType(type), getWrapperType(type)));
insn.getArguments().add(var); insn.getArguments().add(var);
insn.setReceiver(result); insn.setReceiver(result);
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
@ -589,6 +600,21 @@ class JavascriptNativeProcessor {
return result; return result;
} }
private ValueType getWrappedType(ValueType type) {
if (type instanceof ValueType.Array) {
ValueType itemType = ((ValueType.Array)type).getItemType();
return ValueType.arrayOf(getWrappedType(itemType));
} else if (type instanceof ValueType.Object) {
if (type.isObject("java.lang.String")) {
return type;
} else {
return ValueType.parse(JSObject.class);
}
} else {
return type;
}
}
private ValueType getWrapperType(ValueType type) { private ValueType getWrapperType(ValueType type) {
if (type instanceof ValueType.Array) { if (type instanceof ValueType.Array) {
ValueType itemType = ((ValueType.Array)type).getItemType(); ValueType itemType = ((ValueType.Array)type).getItemType();

View File

@ -64,6 +64,11 @@ class NativeJavascriptClassRepository {
return true; return true;
} }
} }
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
if (isJavaScriptClass(cls.getParent())) {
return true;
}
}
return false; return false;
} }