diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index 813fad5ca..0b148e178 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -21,10 +21,14 @@ import java.util.Map; import org.teavm.classlib.impl.DeclaringClassMetadataGenerator; import org.teavm.classlib.java.lang.annotation.TAnnotation; import org.teavm.classlib.java.lang.reflect.TAnnotatedElement; +import org.teavm.interop.Address; +import org.teavm.interop.DelegateTo; import org.teavm.platform.Platform; import org.teavm.platform.PlatformClass; import org.teavm.platform.metadata.ClassResource; import org.teavm.platform.metadata.ClassScopedMetadataProvider; +import org.teavm.runtime.RuntimeClass; +import org.teavm.runtime.RuntimeJavaObject; public class TClass extends TObject implements TAnnotatedElement { TString name; @@ -61,6 +65,7 @@ public class TClass extends TObject implements TAnnotatedElement { return Platform.isAssignable(obj.getPlatformClass(), platformClass); } + @DelegateTo("getNameLowLevel") public TString getName() { if (name == null) { name = TString.wrap(Platform.getName(platformClass)); @@ -68,6 +73,11 @@ public class TClass extends TObject implements TAnnotatedElement { return name; } + private RuntimeJavaObject getNameLowLevel() { + RuntimeClass runtimeClass = Address.ofObject(this).toStructure(); + return runtimeClass.name; + } + public TString getSimpleName() { if (simpleName == null) { if (isArray()) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TStackTraceElement.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TStackTraceElement.java index bf609ee65..207addf93 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TStackTraceElement.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TStackTraceElement.java @@ -19,10 +19,6 @@ import java.util.Objects; import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.util.TObjects; -/** - * - * @author Alexey Andreev - */ public final class TStackTraceElement extends TObject implements TSerializable { private TString declaringClass; private TString methodName; @@ -89,6 +85,7 @@ public final class TStackTraceElement extends TObject implements TSerializable { } else { sb.append(TString.wrap("Unknown Source")); } + sb.append(TString.wrap(")")); return sb.toString(); } } diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java index 0bd751f89..29e7195e4 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java @@ -17,9 +17,11 @@ package org.teavm.classlib.java.lang; import org.teavm.classlib.java.io.TPrintStream; import org.teavm.classlib.java.util.TArrays; +import org.teavm.interop.DelegateTo; import org.teavm.interop.Remove; import org.teavm.interop.Rename; import org.teavm.interop.Superclass; +import org.teavm.runtime.ExceptionHandling; @Superclass("java.lang.Object") public class TThrowable extends RuntimeException { @@ -29,6 +31,7 @@ public class TThrowable extends RuntimeException { private boolean suppressionEnabled; private boolean writableStackTrace; private TThrowable[] suppressed = new TThrowable[0]; + private TStackTraceElement[] stackTrace; @SuppressWarnings("unused") @Rename("fakeInit") @@ -97,10 +100,18 @@ public class TThrowable extends RuntimeException { } @Override + @DelegateTo("fillInStackTraceLowLevel") public Throwable fillInStackTrace() { return this; } + private TThrowable fillInStackTraceLowLevel() { + int stackSize = ExceptionHandling.callStackSize() - 1; + stackTrace = new TStackTraceElement[stackSize]; + ExceptionHandling.fillStackTrace((StackTraceElement[]) (Object) stackTrace, 2); + return this; + } + @Rename("getMessage") public TString getMessage0() { return message; @@ -143,15 +154,25 @@ public class TThrowable extends RuntimeException { public void printStackTrace(TPrintStream stream) { stream.println(TString.wrap(getClass().getName() + ": " + getMessage())); + if (stackTrace != null) { + for (TStackTraceElement element : stackTrace) { + stream.print(TString.wrap(" at ")); + stream.println(element); + } + } + if (cause != null && cause != this) { + stream.print(TString.wrap("Caused by: ")); + cause.printStackTrace(stream); + } } @Rename("getStackTrace") public TStackTraceElement[] getStackTrace0() { - return new TStackTraceElement[0]; + return stackTrace != null ? stackTrace.clone() : new TStackTraceElement[0]; } public void setStackTrace(@SuppressWarnings("unused") TStackTraceElement[] stackTrace) { - // do nothing + this.stackTrace = stackTrace.clone(); } @Rename("getSuppressed") diff --git a/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java b/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java index 7df10fbee..19538bed2 100644 --- a/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java +++ b/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java @@ -282,7 +282,7 @@ public class WasmTarget implements TeaVMTarget { Decompiler decompiler = new Decompiler(classes, controller.getClassLoader(), new HashSet<>(), new HashSet<>()); - WasmStringPool stringPool = new WasmStringPool(classGenerator, binaryWriter); + WasmStringPool stringPool = classGenerator.getStringPool(); WasmGenerationContext context = new WasmGenerationContext(classes, module, controller.getDiagnostics(), vtableProvider, tagRegistry, stringPool); @@ -302,7 +302,7 @@ public class WasmTarget implements TeaVMTarget { context.addIntrinsic(mutatorIntrinsic); context.addIntrinsic(new ShadowStackIntrinsic()); ExceptionHandlingIntrinsic exceptionHandlingIntrinsic = new ExceptionHandlingIntrinsic(binaryWriter, - classGenerator); + classGenerator, stringPool); context.addIntrinsic(exceptionHandlingIntrinsic); WasmGenerator generator = new WasmGenerator(decompiler, classes, context, classGenerator, binaryWriter); diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/CallSiteBinaryGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/CallSiteBinaryGenerator.java index 5a588e0dd..3a91c7246 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/CallSiteBinaryGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/CallSiteBinaryGenerator.java @@ -16,34 +16,50 @@ package org.teavm.backend.wasm.generate; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.teavm.backend.wasm.binary.BinaryWriter; import org.teavm.backend.wasm.binary.DataPrimitives; import org.teavm.backend.wasm.binary.DataStructure; import org.teavm.backend.wasm.binary.DataValue; import org.teavm.model.ValueType; import org.teavm.model.lowlevel.CallSiteDescriptor; +import org.teavm.model.lowlevel.CallSiteLocation; import org.teavm.model.lowlevel.ExceptionHandlerDescriptor; public class CallSiteBinaryGenerator { private static final int CALL_SITE_HANDLER_COUNT = 0; private static final int CALL_SITE_FIRST_HANDLER = 1; + private static final int CALL_SITE_LOCATION = 2; private static final int EXCEPTION_HANDLER_ID = 0; private static final int EXCEPTION_HANDLER_CLASS = 1; + private static final int LOCATION_FILE = 0; + private static final int LOCATION_CLASS = 1; + private static final int LOCATION_METHOD = 2; + private static final int LOCATION_LINE_NUMBER = 3; private DataStructure callSiteStructure = new DataStructure((byte) 0, DataPrimitives.INT, + DataPrimitives.ADDRESS, DataPrimitives.ADDRESS); private DataStructure exceptionHandlerStructure = new DataStructure((byte) 0, DataPrimitives.INT, DataPrimitives.ADDRESS); + private DataStructure locationStructure = new DataStructure((byte) 0, + DataPrimitives.ADDRESS, + DataPrimitives.ADDRESS, + DataPrimitives.ADDRESS, + DataPrimitives.INT); private BinaryWriter writer; private WasmClassGenerator classGenerator; + private WasmStringPool stringPool; - public CallSiteBinaryGenerator(BinaryWriter writer, WasmClassGenerator classGenerator) { + public CallSiteBinaryGenerator(BinaryWriter writer, WasmClassGenerator classGenerator, WasmStringPool stringPool) { this.writer = writer; this.classGenerator = classGenerator; + this.stringPool = stringPool; } public int writeCallSites(List callSites) { @@ -53,7 +69,7 @@ public class CallSiteBinaryGenerator { int firstCallSite = -1; List binaryCallSites = new ArrayList<>(); - for (CallSiteDescriptor callSite : callSites) { + for (int i = 0; i < callSites.size(); i++) { DataValue binaryCallSite = callSiteStructure.createValue(); int address = writer.append(binaryCallSite); if (firstCallSite < 0) { @@ -62,6 +78,8 @@ public class CallSiteBinaryGenerator { binaryCallSites.add(binaryCallSite); } + Map locationCache = new HashMap<>(); + for (int callSiteId = 0; callSiteId < callSites.size(); ++callSiteId) { DataValue binaryCallSite = binaryCallSites.get(callSiteId); CallSiteDescriptor callSite = callSites.get(callSiteId); @@ -91,6 +109,23 @@ public class CallSiteBinaryGenerator { binaryExceptionHandler.setAddress(EXCEPTION_HANDLER_CLASS, classPointer); } } + + int locationAddress = locationCache.computeIfAbsent(callSite.getLocation(), location -> { + DataValue binaryLocation = locationStructure.createValue(); + int address = writer.append(binaryLocation); + if (location.getFileName() != null) { + binaryLocation.setAddress(LOCATION_FILE, stringPool.getStringPointer(location.getFileName())); + } + if (location.getClassName() != null) { + binaryLocation.setAddress(LOCATION_CLASS, stringPool.getStringPointer(location.getClassName())); + } + if (location.getMethodName() != null) { + binaryLocation.setAddress(LOCATION_METHOD, stringPool.getStringPointer(location.getMethodName())); + } + binaryLocation.setInt(LOCATION_LINE_NUMBER, location.getLineNumber()); + return address; + }); + binaryCallSite.setAddress(CALL_SITE_LOCATION, locationAddress); } return firstCallSite; diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/WasmClassGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/WasmClassGenerator.java index fefcc59f5..164941abe 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/WasmClassGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/WasmClassGenerator.java @@ -57,6 +57,7 @@ public class WasmClassGenerator { private List functionTable = new ArrayList<>(); private VirtualTableProvider vtableProvider; private TagRegistry tagRegistry; + private WasmStringPool stringPool; private DataStructure objectStructure = new DataStructure((byte) 0, DataPrimitives.INT, /* class */ DataPrimitives.ADDRESS /* monitor/hash code */); @@ -67,6 +68,7 @@ public class WasmClassGenerator { DataPrimitives.INT, /* flags */ DataPrimitives.INT, /* tag */ DataPrimitives.INT, /* canary */ + DataPrimitives.ADDRESS, /* name */ DataPrimitives.ADDRESS, /* item type */ DataPrimitives.ADDRESS, /* array type */ DataPrimitives.INT, /* isInstance function */ @@ -79,11 +81,12 @@ public class WasmClassGenerator { private static final int CLASS_FLAGS = 2; private static final int CLASS_TAG = 3; private static final int CLASS_CANARY = 4; - private static final int CLASS_ITEM_TYPE = 5; - private static final int CLASS_ARRAY_TYPE = 6; - private static final int CLASS_IS_INSTANCE = 7; - private static final int CLASS_PARENT = 8; - private static final int CLASS_LAYOUT = 9; + private static final int CLASS_NAME = 5; + private static final int CLASS_ITEM_TYPE = 6; + private static final int CLASS_ARRAY_TYPE = 7; + private static final int CLASS_IS_INSTANCE = 8; + private static final int CLASS_PARENT = 9; + private static final int CLASS_LAYOUT = 10; public WasmClassGenerator(ClassReaderSource classSource, VirtualTableProvider vtableProvider, TagRegistry tagRegistry, BinaryWriter binaryWriter) { @@ -91,6 +94,11 @@ public class WasmClassGenerator { this.vtableProvider = vtableProvider; this.tagRegistry = tagRegistry; this.binaryWriter = binaryWriter; + this.stringPool = new WasmStringPool(this, binaryWriter); + } + + public WasmStringPool getStringPool() { + return stringPool; } private void addClass(ValueType type) { @@ -204,6 +212,7 @@ public class WasmClassGenerator { int tag = ranges.stream().mapToInt(range -> range.lower).min().orElse(0); header.setInt(CLASS_TAG, tag); header.setInt(CLASS_CANARY, RuntimeClass.computeCanary(occupiedSize, tag)); + header.setAddress(CLASS_NAME, stringPool.getStringPointer(name)); header.setInt(CLASS_IS_INSTANCE, functionTable.size()); functionTable.add(WasmMangling.mangleIsSupertype(ValueType.object(name))); header.setAddress(CLASS_PARENT, parentPtr); diff --git a/core/src/main/java/org/teavm/backend/wasm/intrinsics/ExceptionHandlingIntrinsic.java b/core/src/main/java/org/teavm/backend/wasm/intrinsics/ExceptionHandlingIntrinsic.java index 3f9037523..408e1b3f3 100644 --- a/core/src/main/java/org/teavm/backend/wasm/intrinsics/ExceptionHandlingIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/wasm/intrinsics/ExceptionHandlingIntrinsic.java @@ -21,6 +21,7 @@ import org.teavm.ast.InvocationExpr; import org.teavm.backend.wasm.binary.BinaryWriter; import org.teavm.backend.wasm.generate.CallSiteBinaryGenerator; import org.teavm.backend.wasm.generate.WasmClassGenerator; +import org.teavm.backend.wasm.generate.WasmStringPool; import org.teavm.backend.wasm.model.expression.WasmExpression; import org.teavm.backend.wasm.model.expression.WasmInt32Constant; import org.teavm.backend.wasm.model.expression.WasmIntBinary; @@ -28,14 +29,18 @@ import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation; import org.teavm.backend.wasm.model.expression.WasmIntType; import org.teavm.model.MethodReference; import org.teavm.model.lowlevel.CallSiteDescriptor; +import org.teavm.runtime.CallSite; import org.teavm.runtime.ExceptionHandling; public class ExceptionHandlingIntrinsic implements WasmIntrinsic { private CallSiteBinaryGenerator callSiteBinaryGenerator; + private WasmClassGenerator classGenerator; private List constants = new ArrayList<>(); - public ExceptionHandlingIntrinsic(BinaryWriter binaryWriter, WasmClassGenerator classGenerator) { - callSiteBinaryGenerator = new CallSiteBinaryGenerator(binaryWriter, classGenerator); + public ExceptionHandlingIntrinsic(BinaryWriter binaryWriter, WasmClassGenerator classGenerator, + WasmStringPool stringPool) { + callSiteBinaryGenerator = new CallSiteBinaryGenerator(binaryWriter, classGenerator, stringPool); + this.classGenerator = classGenerator; } @Override @@ -63,9 +68,10 @@ public class ExceptionHandlingIntrinsic implements WasmIntrinsic { constant.setLocation(invocation.getLocation()); constants.add(constant); + int callSiteSize = classGenerator.getClassSize(CallSite.class.getName()); WasmExpression id = manager.generate(invocation.getArguments().get(0)); - WasmExpression offset = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SHL, - id, new WasmInt32Constant(3)); + WasmExpression offset = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.MUL, + id, new WasmInt32Constant(callSiteSize)); return new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, constant, offset); } diff --git a/core/src/main/java/org/teavm/model/lowlevel/CallSiteDescriptor.java b/core/src/main/java/org/teavm/model/lowlevel/CallSiteDescriptor.java index 64723c0ca..c42323aaa 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/CallSiteDescriptor.java +++ b/core/src/main/java/org/teavm/model/lowlevel/CallSiteDescriptor.java @@ -21,15 +21,21 @@ import java.util.List; public class CallSiteDescriptor { private int id; private List handlers = new ArrayList<>(); + private CallSiteLocation location; - public CallSiteDescriptor(int id) { + public CallSiteDescriptor(int id, CallSiteLocation location) { this.id = id; + this.location = location; } public int getId() { return id; } + public CallSiteLocation getLocation() { + return location; + } + public List getHandlers() { return handlers; } diff --git a/core/src/main/java/org/teavm/model/lowlevel/CallSiteLocation.java b/core/src/main/java/org/teavm/model/lowlevel/CallSiteLocation.java new file mode 100644 index 000000000..07775b803 --- /dev/null +++ b/core/src/main/java/org/teavm/model/lowlevel/CallSiteLocation.java @@ -0,0 +1,66 @@ +/* + * Copyright 2017 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.model.lowlevel; + +import java.util.Objects; + +public class CallSiteLocation { + private String fileName; + private String className; + private String methodName; + private int lineNumber; + + public CallSiteLocation(String fileName, String className, String methodName, int lineNumber) { + this.fileName = fileName; + this.className = className; + this.methodName = methodName; + this.lineNumber = lineNumber; + } + + public String getFileName() { + return fileName; + } + + public String getClassName() { + return className; + } + + public String getMethodName() { + return methodName; + } + + public int getLineNumber() { + return lineNumber; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof CallSiteLocation)) { + return false; + } + CallSiteLocation other = (CallSiteLocation) obj; + return Objects.equals(fileName, other.fileName) && Objects.equals(className, other.className) + && Objects.equals(methodName, other.methodName) && lineNumber == other.lineNumber; + } + + @Override + public int hashCode() { + return Objects.hash(fileName, className, methodName, lineNumber); + } +} diff --git a/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java b/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java index c6878c8ce..c6d340eb4 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java +++ b/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java @@ -190,7 +190,11 @@ public class ExceptionHandlingShadowStackContributor { } } - CallSiteDescriptor callSite = new CallSiteDescriptor(callSites.size()); + String fileName = insn.getLocation() != null ? insn.getLocation().getFileName() : null; + int lineNumber = insn.getLocation() != null ? insn.getLocation().getLine() : -1; + CallSiteLocation location = new CallSiteLocation(fileName, method.getClassName(), method.getName(), + lineNumber); + CallSiteDescriptor callSite = new CallSiteDescriptor(callSites.size(), location); callSites.add(callSite); List pre = setLocation(getInstructionsBeforeCallSite(callSite), insn.getLocation()); List post = getInstructionsAfterCallSite(block, next, callSite, currentJointSources); diff --git a/core/src/main/java/org/teavm/runtime/CallSite.java b/core/src/main/java/org/teavm/runtime/CallSite.java index 915f7a18d..0db59557f 100644 --- a/core/src/main/java/org/teavm/runtime/CallSite.java +++ b/core/src/main/java/org/teavm/runtime/CallSite.java @@ -24,4 +24,5 @@ import org.teavm.interop.Unmanaged; public class CallSite extends Structure { public int handlerCount; public ExceptionHandler firstHandler; + public CallSiteLocation location; } diff --git a/core/src/main/java/org/teavm/runtime/CallSiteLocation.java b/core/src/main/java/org/teavm/runtime/CallSiteLocation.java new file mode 100644 index 000000000..ec133d90f --- /dev/null +++ b/core/src/main/java/org/teavm/runtime/CallSiteLocation.java @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.runtime; + +import org.teavm.interop.Structure; + +public class CallSiteLocation extends Structure { + public String fileName; + public String className; + public String methodName; + public int lineNumber; +} diff --git a/core/src/main/java/org/teavm/runtime/ExceptionHandling.java b/core/src/main/java/org/teavm/runtime/ExceptionHandling.java index 2294f87a5..72c0136b4 100644 --- a/core/src/main/java/org/teavm/runtime/ExceptionHandling.java +++ b/core/src/main/java/org/teavm/runtime/ExceptionHandling.java @@ -21,7 +21,6 @@ import org.teavm.interop.StaticInit; import org.teavm.interop.Structure; import org.teavm.interop.Unmanaged; -@Unmanaged @StaticInit public final class ExceptionHandling { private ExceptionHandling() { @@ -32,12 +31,14 @@ public final class ExceptionHandling { private static Throwable thrownException; @Export(name = "sys$catchException") + @Unmanaged public static Throwable catchException() { Throwable exception = thrownException; thrownException = null; return exception; } + @Unmanaged public static void throwException(Throwable exception) { thrownException = exception; @@ -64,4 +65,41 @@ public final class ExceptionHandling { stackFrame = ShadowStack.getNextStackFrame(stackFrame); } } + + @Unmanaged + public static int callStackSize() { + Address stackFrame = ShadowStack.getStackTop(); + int size = 0; + while (stackFrame != null) { + stackFrame = ShadowStack.getNextStackFrame(stackFrame); + size++; + } + return size; + } + + @Unmanaged + public static void fillStackTrace(StackTraceElement[] target, int skip) { + Address stackFrame = ShadowStack.getNextStackFrame(ShadowStack.getNextStackFrame(ShadowStack.getStackTop())); + int index = 0; + while (stackFrame != null && index < target.length) { + int callSiteId = ShadowStack.getCallSiteId(stackFrame); + CallSite callSite = findCallSiteById(callSiteId); + CallSiteLocation location = callSite.location; + StackTraceElement element = createElement(location != null ? location.className : "", + location != null ? location.methodName : "", location != null ? location.fileName : null, + location != null ? location.lineNumber : -1); + if (skip > 0) { + skip--; + } else { + target[index++] = element; + } + + stackFrame = ShadowStack.getNextStackFrame(stackFrame); + } + } + + private static StackTraceElement createElement(String className, String methodName, String fileName, + int lineNumber) { + return new StackTraceElement(className, methodName, fileName, lineNumber); + } } diff --git a/core/src/main/java/org/teavm/runtime/RuntimeClass.java b/core/src/main/java/org/teavm/runtime/RuntimeClass.java index f4b04ee1e..67f092298 100644 --- a/core/src/main/java/org/teavm/runtime/RuntimeClass.java +++ b/core/src/main/java/org/teavm/runtime/RuntimeClass.java @@ -26,6 +26,7 @@ public class RuntimeClass extends RuntimeJavaObject { public int flags; public int tag; public int canary; + public RuntimeJavaObject name; public RuntimeClass itemType; public RuntimeClass arrayType; public IsSupertypeFunction isSupertypeOf; diff --git a/platform/src/main/java/org/teavm/platform/Platform.java b/platform/src/main/java/org/teavm/platform/Platform.java index 5ce1184b5..854436780 100644 --- a/platform/src/main/java/org/teavm/platform/Platform.java +++ b/platform/src/main/java/org/teavm/platform/Platform.java @@ -172,7 +172,6 @@ public final class Platform { return cls.itemType; } - @DelegateTo("getNameLowLevel") public static String getName(PlatformClass cls) { return cls.getMetadata().getName(); }