From b34e25414e4d4665d7f68a8936a1418ca344ff3d Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 24 Mar 2021 18:52:54 +0300 Subject: [PATCH] C: fix support for resources --- .../resources/org/teavm/backend/c/resource.c | 2 +- .../resources/org/teavm/backend/c/string.c | 4 +++ .../platform/plugin/MetadataCIntrinsic.java | 10 +----- .../teavm/platform/plugin/PlatformPlugin.java | 1 + .../platform/plugin/ResourceCTransformer.java | 34 +++++++++++++++++++ .../plugin/ResourceProgramTransformer.java | 27 +++++++++++---- 6 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 platform/src/main/java/org/teavm/platform/plugin/ResourceCTransformer.java diff --git a/core/src/main/resources/org/teavm/backend/c/resource.c b/core/src/main/resources/org/teavm/backend/c/resource.c index 16261fb5e..6ce23ebbc 100644 --- a/core/src/main/resources/org/teavm/backend/c/resource.c +++ b/core/src/main/resources/org/teavm/backend/c/resource.c @@ -29,7 +29,7 @@ TeaVM_Array* teavm_resourceMapKeys(TeaVM_ResourceMap *map) { void** data = TEAVM_ARRAY_DATA(array, void*); for (int32_t i = 0; i < map->size; ++i) { if (map->entries[i].key != NULL) { - data[index++] = map->entries[i].key; + data[index++] = *map->entries[i].key; } } diff --git a/core/src/main/resources/org/teavm/backend/c/string.c b/core/src/main/resources/org/teavm/backend/c/string.c index 4ec81f6a9..f4b2f23dd 100644 --- a/core/src/main/resources/org/teavm/backend/c/string.c +++ b/core/src/main/resources/org/teavm/backend/c/string.c @@ -19,6 +19,10 @@ int32_t teavm_hashCode(TeaVM_String* string) { } int32_t teavm_equals(TeaVM_String* first, TeaVM_String* second) { + if (first == second) { + return 1; + } + if (first->characters->size != second->characters->size) { return 0; } diff --git a/platform/src/main/java/org/teavm/platform/plugin/MetadataCIntrinsic.java b/platform/src/main/java/org/teavm/platform/plugin/MetadataCIntrinsic.java index b62f85d2c..3f97dfc5f 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/MetadataCIntrinsic.java +++ b/platform/src/main/java/org/teavm/platform/plugin/MetadataCIntrinsic.java @@ -204,7 +204,7 @@ class MetadataCIntrinsic implements Generator { int hashCode = key.hashCode(); int collisionRatio = 0; while (true) { - int index = mod(hashCode++, table.length); + int index = Integer.remainderUnsigned(hashCode++, table.length); if (table[index] == null) { table[index] = key; break; @@ -249,14 +249,6 @@ class MetadataCIntrinsic implements Generator { context.writerBefore().outdent().print("}"); } - private static int mod(int a, int b) { - a %= b; - if (a < 0) { - a += b; - } - return a; - } - class MethodGenerator { private MethodReference targetMethod; private MetadataGenerator generator; diff --git a/platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java b/platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java index fd6f8d7d9..df606a5bd 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java +++ b/platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java @@ -95,6 +95,7 @@ public class PlatformPlugin implements TeaVMPlugin, MetadataRegistration { TeaVMCHost cHost = host.getExtension(TeaVMCHost.class); if (cHost != null) { + host.add(new ResourceCTransformer()); MetadataCIntrinsic metadataCIntrinsic = new MetadataCIntrinsic(); cHost.addGenerator(ctx -> { metadataCIntrinsic.init(ctx.getClassSource(), ctx.getClassLoader(), diff --git a/platform/src/main/java/org/teavm/platform/plugin/ResourceCTransformer.java b/platform/src/main/java/org/teavm/platform/plugin/ResourceCTransformer.java new file mode 100644 index 000000000..1c9ff0098 --- /dev/null +++ b/platform/src/main/java/org/teavm/platform/plugin/ResourceCTransformer.java @@ -0,0 +1,34 @@ +/* + * Copyright 2014 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.platform.plugin; + +import org.teavm.model.ClassHolder; +import org.teavm.model.ClassHolderTransformer; +import org.teavm.model.ClassHolderTransformerContext; +import org.teavm.model.MethodHolder; +import org.teavm.model.Program; + +class ResourceCTransformer implements ClassHolderTransformer { + @Override + public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) { + for (MethodHolder method : cls.getMethods()) { + Program program = method.getProgram(); + if (program != null) { + new ResourceProgramTransformer(context.getHierarchy(), program).removeCasts(); + } + } + } +} diff --git a/platform/src/main/java/org/teavm/platform/plugin/ResourceProgramTransformer.java b/platform/src/main/java/org/teavm/platform/plugin/ResourceProgramTransformer.java index 2c328cd0b..9b3f23f0f 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/ResourceProgramTransformer.java +++ b/platform/src/main/java/org/teavm/platform/plugin/ResourceProgramTransformer.java @@ -61,18 +61,31 @@ class ResourceProgramTransformer { insn.delete(); } } else if (insn instanceof CastInstruction) { - CastInstruction cast = (CastInstruction) insn; - if (hierarchy.isSuperType(RESOURCE, cast.getTargetType(), false)) { - AssignInstruction assign = new AssignInstruction(); - assign.setReceiver(cast.getReceiver()); - assign.setAssignee(cast.getValue()); - assign.setLocation(cast.getLocation()); - insn.replace(assign); + removeCastToResource((CastInstruction) insn); + } + } + } + + void removeCasts() { + for (BasicBlock block : program.getBasicBlocks()) { + for (Instruction insn : block) { + if (insn instanceof CastInstruction) { + removeCastToResource((CastInstruction) insn); } } } } + private void removeCastToResource(CastInstruction cast) { + if (hierarchy.isSuperType(RESOURCE, cast.getTargetType(), false)) { + AssignInstruction assign = new AssignInstruction(); + assign.setReceiver(cast.getReceiver()); + assign.setAssignee(cast.getValue()); + assign.setLocation(cast.getLocation()); + cast.replace(assign); + } + } + private List transformInvoke(InvokeInstruction insn) { if (insn.getType() != InvocationType.VIRTUAL) { return null;