mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
C: add option to generate shorter output file names to workaround msvc bug
This commit is contained in:
parent
2f7f4e7782
commit
1fa48560c6
|
@ -1,35 +1,33 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="build-teavm-fast" type="MavenRunConfiguration" factoryName="Maven">
|
<configuration default="false" name="build-teavm-fast" type="MavenRunConfiguration" factoryName="Maven">
|
||||||
<MavenRunConfigurationSettings>
|
<MavenSettings>
|
||||||
<option name="alwaysUpdateSnapshots" value="false" />
|
<option name="myGeneralSettings" />
|
||||||
<option name="checksumPolicy" />
|
<option name="myRunnerSettings" />
|
||||||
<option name="commandLine" value="-e install -DskipTests -Dteavm.build.all=false -Pwith-cli -Dmaven.javadoc.skip=true" />
|
<option name="myRunnerParameters">
|
||||||
<option name="environment">
|
<MavenRunnerParameters>
|
||||||
<map />
|
<option name="profiles">
|
||||||
|
<set />
|
||||||
|
</option>
|
||||||
|
<option name="goals">
|
||||||
|
<list>
|
||||||
|
<option value="-e" />
|
||||||
|
<option value="install" />
|
||||||
|
<option value="-DskipTests" />
|
||||||
|
<option value="-Dteavm.build.all=false" />
|
||||||
|
<option value="-Pwith-cli" />
|
||||||
|
<option value="-Dmaven.javadoc.skip=true" />
|
||||||
|
<option value="-T4" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="pomFileName" />
|
||||||
|
<option name="profilesMap">
|
||||||
|
<map />
|
||||||
|
</option>
|
||||||
|
<option name="resolveToWorkspace" value="false" />
|
||||||
|
<option name="workingDirPath" value="$PROJECT_DIR$" />
|
||||||
|
</MavenRunnerParameters>
|
||||||
</option>
|
</option>
|
||||||
<option name="failureBehavior" />
|
</MavenSettings>
|
||||||
<option name="jreName" />
|
|
||||||
<option name="localRepository" />
|
|
||||||
<option name="mavenHome" value="Bundled (Maven 3)" />
|
|
||||||
<option name="mavenProperties">
|
|
||||||
<map />
|
|
||||||
</option>
|
|
||||||
<option name="nonRecursive" value="false" />
|
|
||||||
<option name="outputLevel" />
|
|
||||||
<option name="passParentEnvs" value="true" />
|
|
||||||
<option name="printErrorStackTraces" value="false" />
|
|
||||||
<option name="profilesMap">
|
|
||||||
<map />
|
|
||||||
</option>
|
|
||||||
<option name="resolveToWorkspace" value="false" />
|
|
||||||
<option name="skipTests" value="false" />
|
|
||||||
<option name="threads" value="4" />
|
|
||||||
<option name="usePluginRegistry" value="false" />
|
|
||||||
<option name="userSettings" />
|
|
||||||
<option name="vmOptions" />
|
|
||||||
<option name="workOffline" value="false" />
|
|
||||||
<option name="workingDirectory" value="$PROJECT_DIR$" />
|
|
||||||
</MavenRunConfigurationSettings>
|
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
|
@ -41,9 +41,11 @@ import org.teavm.backend.c.generate.ClassGenerationContext;
|
||||||
import org.teavm.backend.c.generate.ClassGenerator;
|
import org.teavm.backend.c.generate.ClassGenerator;
|
||||||
import org.teavm.backend.c.generate.CodeGenerationVisitor;
|
import org.teavm.backend.c.generate.CodeGenerationVisitor;
|
||||||
import org.teavm.backend.c.generate.CodeWriter;
|
import org.teavm.backend.c.generate.CodeWriter;
|
||||||
|
import org.teavm.backend.c.generate.FileNameProvider;
|
||||||
import org.teavm.backend.c.generate.GenerationContext;
|
import org.teavm.backend.c.generate.GenerationContext;
|
||||||
import org.teavm.backend.c.generate.IncludeManager;
|
import org.teavm.backend.c.generate.IncludeManager;
|
||||||
import org.teavm.backend.c.generate.OutputFileUtil;
|
import org.teavm.backend.c.generate.OutputFileUtil;
|
||||||
|
import org.teavm.backend.c.generate.SimpleFileNameProvider;
|
||||||
import org.teavm.backend.c.generate.SimpleIncludeManager;
|
import org.teavm.backend.c.generate.SimpleIncludeManager;
|
||||||
import org.teavm.backend.c.generate.SimpleStringPool;
|
import org.teavm.backend.c.generate.SimpleStringPool;
|
||||||
import org.teavm.backend.c.generate.StringPoolGenerator;
|
import org.teavm.backend.c.generate.StringPoolGenerator;
|
||||||
|
@ -154,6 +156,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
|
|
||||||
private TeaVMTargetController controller;
|
private TeaVMTargetController controller;
|
||||||
private NameProvider rawNameProvider;
|
private NameProvider rawNameProvider;
|
||||||
|
private FileNameProvider fileNames = new SimpleFileNameProvider();
|
||||||
private ClassInitializerEliminator classInitializerEliminator;
|
private ClassInitializerEliminator classInitializerEliminator;
|
||||||
private ClassInitializerTransformer classInitializerTransformer;
|
private ClassInitializerTransformer classInitializerTransformer;
|
||||||
private ShadowStackTransformer shadowStackTransformer;
|
private ShadowStackTransformer shadowStackTransformer;
|
||||||
|
@ -214,6 +217,10 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
this.obfuscated = obfuscated;
|
this.obfuscated = obfuscated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFileNames(FileNameProvider fileNames) {
|
||||||
|
this.fileNames = fileNames;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ClassHolderTransformer> getTransformers() {
|
public List<ClassHolderTransformer> getTransformers() {
|
||||||
List<ClassHolderTransformer> transformers = new ArrayList<>();
|
List<ClassHolderTransformer> transformers = new ArrayList<>();
|
||||||
|
@ -402,8 +409,8 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
boolean vmAssertions = Boolean.parseBoolean(System.getProperty("teavm.c.vmAssertions", "false"));
|
boolean vmAssertions = Boolean.parseBoolean(System.getProperty("teavm.c.vmAssertions", "false"));
|
||||||
boolean gcStats = Boolean.parseBoolean(System.getProperty("teavm.c.gcStats", "false"));
|
boolean gcStats = Boolean.parseBoolean(System.getProperty("teavm.c.gcStats", "false"));
|
||||||
GenerationContext context = new GenerationContext(vtableProvider, characteristics,
|
GenerationContext context = new GenerationContext(vtableProvider, characteristics,
|
||||||
controller.getDependencyInfo(), stringPool, nameProvider, controller.getDiagnostics(), classes,
|
controller.getDependencyInfo(), stringPool, nameProvider, fileNames,
|
||||||
intrinsics, generators, asyncMethods::contains, buildTarget,
|
controller.getDiagnostics(), classes, intrinsics, generators, asyncMethods::contains, buildTarget,
|
||||||
controller.getClassInitializerInfo(), incremental, longjmpUsed,
|
controller.getClassInitializerInfo(), incremental, longjmpUsed,
|
||||||
vmAssertions, vmAssertions || heapDump, obfuscated);
|
vmAssertions, vmAssertions || heapDump, obfuscated);
|
||||||
|
|
||||||
|
@ -497,7 +504,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
classGenerator.generateClass(writer, headerWriter, cls);
|
classGenerator.generateClass(writer, headerWriter, cls);
|
||||||
}
|
}
|
||||||
String name = ClassGenerator.fileName(className);
|
String name = fileNames.fileName(className);
|
||||||
OutputFileUtil.write(writer, name + ".c", buildTarget);
|
OutputFileUtil.write(writer, name + ".c", buildTarget);
|
||||||
OutputFileUtil.write(headerWriter, name + ".h", buildTarget);
|
OutputFileUtil.write(headerWriter, name + ".h", buildTarget);
|
||||||
if (incremental) {
|
if (incremental) {
|
||||||
|
@ -512,7 +519,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
BufferedCodeWriter writer = new BufferedCodeWriter(false);
|
BufferedCodeWriter writer = new BufferedCodeWriter(false);
|
||||||
BufferedCodeWriter headerWriter = new BufferedCodeWriter(false);
|
BufferedCodeWriter headerWriter = new BufferedCodeWriter(false);
|
||||||
classGenerator.generateType(writer, headerWriter, type);
|
classGenerator.generateType(writer, headerWriter, type);
|
||||||
String name = ClassGenerator.fileName(type);
|
String name = fileNames.fileName(type);
|
||||||
OutputFileUtil.write(writer, name + ".c", buildTarget);
|
OutputFileUtil.write(writer, name + ".c", buildTarget);
|
||||||
OutputFileUtil.write(headerWriter, name + ".h", buildTarget);
|
OutputFileUtil.write(headerWriter, name + ".h", buildTarget);
|
||||||
if (incremental) {
|
if (incremental) {
|
||||||
|
@ -525,7 +532,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
Collection<? extends String> classNames) throws IOException {
|
Collection<? extends String> classNames) throws IOException {
|
||||||
BufferedCodeWriter writer = new BufferedCodeWriter(false);
|
BufferedCodeWriter writer = new BufferedCodeWriter(false);
|
||||||
|
|
||||||
IncludeManager includes = new SimpleIncludeManager(writer);
|
IncludeManager includes = new SimpleIncludeManager(context.getFileNames(), writer);
|
||||||
includes.init("callsites.c");
|
includes.init("callsites.c");
|
||||||
|
|
||||||
if (!incremental) {
|
if (!incremental) {
|
||||||
|
@ -600,7 +607,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
|
|
||||||
private void generateStrings(BuildTarget buildTarget, GenerationContext context) throws IOException {
|
private void generateStrings(BuildTarget buildTarget, GenerationContext context) throws IOException {
|
||||||
BufferedCodeWriter writer = new BufferedCodeWriter(false);
|
BufferedCodeWriter writer = new BufferedCodeWriter(false);
|
||||||
IncludeManager includes = new SimpleIncludeManager(writer);
|
IncludeManager includes = new SimpleIncludeManager(context.getFileNames(), writer);
|
||||||
includes.init("strings.c");
|
includes.init("strings.c");
|
||||||
BufferedCodeWriter headerWriter = new BufferedCodeWriter(false);
|
BufferedCodeWriter headerWriter = new BufferedCodeWriter(false);
|
||||||
|
|
||||||
|
@ -664,7 +671,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateSpecialFunctions(GenerationContext context, CodeWriter writer) {
|
private void generateSpecialFunctions(GenerationContext context, CodeWriter writer) {
|
||||||
IncludeManager includes = new SimpleIncludeManager(writer);
|
IncludeManager includes = new SimpleIncludeManager(context.getFileNames(), writer);
|
||||||
includes.init("special.c");
|
includes.init("special.c");
|
||||||
includes.includePath("core.h");
|
includes.includePath("core.h");
|
||||||
includes.includePath("string.h");
|
includes.includePath("string.h");
|
||||||
|
@ -731,7 +738,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
private void generateMainFile(GenerationContext context, ListableClassHolderSource classes,
|
private void generateMainFile(GenerationContext context, ListableClassHolderSource classes,
|
||||||
List<? extends ValueType> types, BuildTarget buildTarget) throws IOException {
|
List<? extends ValueType> types, BuildTarget buildTarget) throws IOException {
|
||||||
BufferedCodeWriter writer = new BufferedCodeWriter(false);
|
BufferedCodeWriter writer = new BufferedCodeWriter(false);
|
||||||
IncludeManager includes = new SimpleIncludeManager(writer);
|
IncludeManager includes = new SimpleIncludeManager(fileNames, writer);
|
||||||
includes.init("main.c");
|
includes.init("main.c");
|
||||||
includes.includePath("runtime.h");
|
includes.includePath("runtime.h");
|
||||||
includes.includePath("strings.h");
|
includes.includePath("strings.h");
|
||||||
|
@ -750,7 +757,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
writer.println("#define __USE_XOPEN");
|
writer.println("#define __USE_XOPEN");
|
||||||
writer.println("#define _GNU_SOURCE");
|
writer.println("#define _GNU_SOURCE");
|
||||||
|
|
||||||
IncludeManager includes = new SimpleIncludeManager(writer);
|
IncludeManager includes = new SimpleIncludeManager(fileNames, writer);
|
||||||
includes.init("all.c");
|
includes.init("all.c");
|
||||||
for (String file : allFiles) {
|
for (String file : allFiles) {
|
||||||
includes.includePath(file);
|
includes.includePath(file);
|
||||||
|
@ -787,10 +794,10 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
files.add("virtcall.c");
|
files.add("virtcall.c");
|
||||||
|
|
||||||
for (String className : classes.getClassNames()) {
|
for (String className : classes.getClassNames()) {
|
||||||
files.add(ClassGenerator.fileName(className) + ".c");
|
files.add(fileNames.fileName(className) + ".c");
|
||||||
}
|
}
|
||||||
for (ValueType type : types) {
|
for (ValueType type : types) {
|
||||||
files.add(ClassGenerator.fileName(type) + ".c");
|
files.add(fileNames.fileName(type) + ".c");
|
||||||
}
|
}
|
||||||
|
|
||||||
files.add("main.c");
|
files.add("main.c");
|
||||||
|
|
|
@ -208,7 +208,7 @@ public class ClassGenerator {
|
||||||
|
|
||||||
public void generateClass(CodeWriter writer, CodeWriter headerWriter, ClassHolder cls) {
|
public void generateClass(CodeWriter writer, CodeWriter headerWriter, ClassHolder cls) {
|
||||||
ValueType type = ValueType.object(cls.getName());
|
ValueType type = ValueType.object(cls.getName());
|
||||||
init(writer, headerWriter, fileName(cls.getName()), type);
|
init(writer, headerWriter, context.getFileNames().fileName(cls.getName()), type);
|
||||||
|
|
||||||
generateStringPoolDecl(type);
|
generateStringPoolDecl(type);
|
||||||
generateClassStructure(cls);
|
generateClassStructure(cls);
|
||||||
|
@ -228,7 +228,7 @@ public class ClassGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateType(CodeWriter writer, CodeWriter headerWriter, ValueType type) {
|
public void generateType(CodeWriter writer, CodeWriter headerWriter, ValueType type) {
|
||||||
init(writer, headerWriter, fileName(type), type);
|
init(writer, headerWriter, context.getFileNames().fileName(type), type);
|
||||||
generateStringPoolDecl(type);
|
generateStringPoolDecl(type);
|
||||||
includes.includeType(type);
|
includes.includeType(type);
|
||||||
generateVirtualTable(type);
|
generateVirtualTable(type);
|
||||||
|
@ -239,14 +239,14 @@ public class ClassGenerator {
|
||||||
staticGcRoots = null;
|
staticGcRoots = null;
|
||||||
classLayout = null;
|
classLayout = null;
|
||||||
|
|
||||||
includes = new SimpleIncludeManager(writer);
|
includes = new SimpleIncludeManager(context.getFileNames(), writer);
|
||||||
includes.init(fileName + ".c");
|
includes.init(fileName + ".c");
|
||||||
prologueWriter = writer.fragment();
|
prologueWriter = writer.fragment();
|
||||||
codeWriter = writer.fragment();
|
codeWriter = writer.fragment();
|
||||||
this.headerWriter = headerWriter;
|
this.headerWriter = headerWriter;
|
||||||
|
|
||||||
headerWriter.println("#pragma once");
|
headerWriter.println("#pragma once");
|
||||||
headerIncludes = new SimpleIncludeManager(headerWriter);
|
headerIncludes = new SimpleIncludeManager(context.getFileNames(), headerWriter);
|
||||||
headerIncludes.init(fileName + ".h");
|
headerIncludes.init(fileName + ".h");
|
||||||
headerIncludes.includePath("runtime.h");
|
headerIncludes.includePath("runtime.h");
|
||||||
|
|
||||||
|
@ -1438,103 +1438,4 @@ public class ClassGenerator {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String fileName(ValueType type) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
fileNameRec(type, sb);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void fileNameRec(ValueType type, StringBuilder sb) {
|
|
||||||
if (type instanceof ValueType.Object) {
|
|
||||||
sb.append("classes/");
|
|
||||||
escape(((ValueType.Object) type).getClassName(), sb);
|
|
||||||
} else if (type instanceof ValueType.Array) {
|
|
||||||
sb.append("arrays/");
|
|
||||||
fileNameRec(((ValueType.Array) type).getItemType(), sb);
|
|
||||||
} else if (type instanceof ValueType.Primitive) {
|
|
||||||
sb.append("primitives/");
|
|
||||||
switch (((ValueType.Primitive) type).getKind()) {
|
|
||||||
case BOOLEAN:
|
|
||||||
sb.append("boolean");
|
|
||||||
break;
|
|
||||||
case BYTE:
|
|
||||||
sb.append("byte");
|
|
||||||
break;
|
|
||||||
case SHORT:
|
|
||||||
sb.append("short");
|
|
||||||
break;
|
|
||||||
case CHARACTER:
|
|
||||||
sb.append("char");
|
|
||||||
break;
|
|
||||||
case INTEGER:
|
|
||||||
sb.append("int");
|
|
||||||
break;
|
|
||||||
case LONG:
|
|
||||||
sb.append("long");
|
|
||||||
break;
|
|
||||||
case FLOAT:
|
|
||||||
sb.append("float");
|
|
||||||
break;
|
|
||||||
case DOUBLE:
|
|
||||||
sb.append("double");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (type == ValueType.VOID) {
|
|
||||||
sb.append("primitives/void");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fileName(String className) {
|
|
||||||
StringBuilder sb = new StringBuilder("classes/");
|
|
||||||
escape(className, sb);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void escape(String className, StringBuilder sb) {
|
|
||||||
for (int i = 0; i < className.length(); ++i) {
|
|
||||||
char c = className.charAt(i);
|
|
||||||
switch (c) {
|
|
||||||
case '.':
|
|
||||||
sb.append('/');
|
|
||||||
break;
|
|
||||||
case '@':
|
|
||||||
sb.append("@@");
|
|
||||||
break;
|
|
||||||
case '/':
|
|
||||||
sb.append("@s");
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
sb.append("@b");
|
|
||||||
break;
|
|
||||||
case ':':
|
|
||||||
sb.append("@c");
|
|
||||||
break;
|
|
||||||
case ';':
|
|
||||||
sb.append("@e");
|
|
||||||
break;
|
|
||||||
case '*':
|
|
||||||
sb.append("@m");
|
|
||||||
break;
|
|
||||||
case '"':
|
|
||||||
sb.append("@q");
|
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
sb.append("@l");
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
sb.append("@g");
|
|
||||||
break;
|
|
||||||
case '|':
|
|
||||||
sb.append("@p");
|
|
||||||
break;
|
|
||||||
case '$':
|
|
||||||
sb.append("@d");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sb.append(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1565,9 +1565,7 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String escapeFileName(String name) {
|
public String escapeFileName(String name) {
|
||||||
StringBuilder sb = new StringBuilder();
|
return context.getFileNames().escapeName(name);
|
||||||
ClassGenerator.escape(name, sb);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 konso.
|
||||||
|
*
|
||||||
|
* 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.backend.c.generate;
|
||||||
|
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
public interface FileNameProvider {
|
||||||
|
String fileName(String className);
|
||||||
|
|
||||||
|
String fileName(ValueType type);
|
||||||
|
|
||||||
|
String escapeName(String name);
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ public class GenerationContext {
|
||||||
private DependencyInfo dependencies;
|
private DependencyInfo dependencies;
|
||||||
private StringPool stringPool;
|
private StringPool stringPool;
|
||||||
private NameProvider names;
|
private NameProvider names;
|
||||||
|
private FileNameProvider fileNames;
|
||||||
private Diagnostics diagnostics;
|
private Diagnostics diagnostics;
|
||||||
private ClassReaderSource classSource;
|
private ClassReaderSource classSource;
|
||||||
private List<Intrinsic> intrinsics;
|
private List<Intrinsic> intrinsics;
|
||||||
|
@ -53,9 +54,9 @@ public class GenerationContext {
|
||||||
private boolean obfuscated;
|
private boolean obfuscated;
|
||||||
|
|
||||||
public GenerationContext(VirtualTableProvider virtualTableProvider, Characteristics characteristics,
|
public GenerationContext(VirtualTableProvider virtualTableProvider, Characteristics characteristics,
|
||||||
DependencyInfo dependencies, StringPool stringPool, NameProvider names, Diagnostics diagnostics,
|
DependencyInfo dependencies, StringPool stringPool, NameProvider names, FileNameProvider fileNames,
|
||||||
ClassReaderSource classSource, List<Intrinsic> intrinsics, List<Generator> generators,
|
Diagnostics diagnostics, ClassReaderSource classSource, List<Intrinsic> intrinsics,
|
||||||
Predicate<MethodReference> asyncMethods, BuildTarget buildTarget,
|
List<Generator> generators, Predicate<MethodReference> asyncMethods, BuildTarget buildTarget,
|
||||||
ClassInitializerInfo classInitializerInfo, boolean incremental, boolean longjmp, boolean vmAssertions,
|
ClassInitializerInfo classInitializerInfo, boolean incremental, boolean longjmp, boolean vmAssertions,
|
||||||
boolean heapDump, boolean obfuscated) {
|
boolean heapDump, boolean obfuscated) {
|
||||||
this.virtualTableProvider = virtualTableProvider;
|
this.virtualTableProvider = virtualTableProvider;
|
||||||
|
@ -63,6 +64,7 @@ public class GenerationContext {
|
||||||
this.dependencies = dependencies;
|
this.dependencies = dependencies;
|
||||||
this.stringPool = stringPool;
|
this.stringPool = stringPool;
|
||||||
this.names = names;
|
this.names = names;
|
||||||
|
this.fileNames = fileNames;
|
||||||
this.diagnostics = diagnostics;
|
this.diagnostics = diagnostics;
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
this.intrinsics = new ArrayList<>(intrinsics);
|
this.intrinsics = new ArrayList<>(intrinsics);
|
||||||
|
@ -105,6 +107,10 @@ public class GenerationContext {
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FileNameProvider getFileNames() {
|
||||||
|
return fileNames;
|
||||||
|
}
|
||||||
|
|
||||||
public Diagnostics getDiagnostics() {
|
public Diagnostics getDiagnostics() {
|
||||||
return diagnostics;
|
return diagnostics;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ class GeneratorContextImpl implements GeneratorContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileGenerator createFile(BufferedCodeWriter writer, String path) {
|
private FileGenerator createFile(BufferedCodeWriter writer, String path) {
|
||||||
IncludeManager includes = new SimpleIncludeManager(writer);
|
IncludeManager includes = new SimpleIncludeManager(context.getFileNames(), writer);
|
||||||
includes.init(path);
|
includes.init(path);
|
||||||
FileGeneratorImpl generator = new FileGeneratorImpl(path, writer, includes);
|
FileGeneratorImpl generator = new FileGeneratorImpl(path, writer, includes);
|
||||||
fileGenerators.add(generator);
|
fileGenerators.add(generator);
|
||||||
|
@ -130,9 +130,7 @@ class GeneratorContextImpl implements GeneratorContext {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String escapeFileName(String name) {
|
public String escapeFileName(String name) {
|
||||||
StringBuilder sb = new StringBuilder();
|
return context.getFileNames().escapeName(name);
|
||||||
ClassGenerator.escape(name, sb);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,11 +20,16 @@ import java.util.Set;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
public abstract class IncludeManager {
|
public abstract class IncludeManager {
|
||||||
|
private FileNameProvider fileNames;
|
||||||
private String currentFileName;
|
private String currentFileName;
|
||||||
private Set<String> includedFiles = new HashSet<>();
|
private Set<String> includedFiles = new HashSet<>();
|
||||||
private Set<String> includedClasses = new HashSet<>();
|
private Set<String> includedClasses = new HashSet<>();
|
||||||
private Set<ValueType> includedTypes = new HashSet<>();
|
private Set<ValueType> includedTypes = new HashSet<>();
|
||||||
|
|
||||||
|
public IncludeManager(FileNameProvider fileNames) {
|
||||||
|
this.fileNames = fileNames;
|
||||||
|
}
|
||||||
|
|
||||||
public void init(String currentFileName) {
|
public void init(String currentFileName) {
|
||||||
this.currentFileName = currentFileName;
|
this.currentFileName = currentFileName;
|
||||||
includedFiles.clear();
|
includedFiles.clear();
|
||||||
|
@ -63,14 +68,14 @@ public abstract class IncludeManager {
|
||||||
if (!includedClasses.add(className)) {
|
if (!includedClasses.add(className)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
includePath(ClassGenerator.fileName(className) + ".h");
|
includePath(fileNames.fileName(className) + ".h");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void includeType(ValueType type) {
|
public void includeType(ValueType type) {
|
||||||
if (!includedTypes.add(type)) {
|
if (!includedTypes.add(type)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
includePath(ClassGenerator.fileName(type) + ".h");
|
includePath(fileNames.fileName(type) + ".h");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void includePath(String fileName) {
|
public void includePath(String fileName) {
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 konso.
|
||||||
|
*
|
||||||
|
* 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.backend.c.generate;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
public class ShorteningFileNameProvider implements FileNameProvider {
|
||||||
|
private final FileNameProvider nameProvider;
|
||||||
|
private final Map<String, String> names = new HashMap<>();
|
||||||
|
private final Set<String> usedNames = new HashSet<>();
|
||||||
|
|
||||||
|
public ShorteningFileNameProvider(FileNameProvider nameProvider) {
|
||||||
|
this.nameProvider = nameProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fileName(String className) {
|
||||||
|
return unique(shorten(nameProvider.fileName(className)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fileName(ValueType type) {
|
||||||
|
return unique(shorten(nameProvider.fileName(type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeName(String name) {
|
||||||
|
return unique(shorten(nameProvider.escapeName(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String unique(String name) {
|
||||||
|
return names.computeIfAbsent(name, n -> {
|
||||||
|
if (usedNames.add(n)) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
int suffix = 1;
|
||||||
|
while (true) {
|
||||||
|
String candidate = n + "_" + suffix++;
|
||||||
|
if (usedNames.add(candidate)) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String shorten(String name) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int index = 0;
|
||||||
|
while (true) {
|
||||||
|
int next = name.indexOf('/', index);
|
||||||
|
if (next < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (next > index) {
|
||||||
|
sb.append(name.charAt(index));
|
||||||
|
}
|
||||||
|
sb.append('/');
|
||||||
|
index = next + 1;
|
||||||
|
}
|
||||||
|
return sb.append(name, index, name.length()).toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 konso.
|
||||||
|
*
|
||||||
|
* 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.backend.c.generate;
|
||||||
|
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
public class SimpleFileNameProvider implements FileNameProvider {
|
||||||
|
@Override
|
||||||
|
public String fileName(String className) {
|
||||||
|
StringBuilder sb = new StringBuilder("classes/");
|
||||||
|
escape(className, sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fileName(ValueType type) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
fileNameRec(type, sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fileNameRec(ValueType type, StringBuilder sb) {
|
||||||
|
if (type instanceof ValueType.Object) {
|
||||||
|
sb.append("classes/");
|
||||||
|
escape(((ValueType.Object) type).getClassName(), sb);
|
||||||
|
} else if (type instanceof ValueType.Array) {
|
||||||
|
sb.append("arrays/");
|
||||||
|
fileNameRec(((ValueType.Array) type).getItemType(), sb);
|
||||||
|
} else if (type instanceof ValueType.Primitive) {
|
||||||
|
sb.append("primitives/");
|
||||||
|
switch (((ValueType.Primitive) type).getKind()) {
|
||||||
|
case BOOLEAN:
|
||||||
|
sb.append("boolean");
|
||||||
|
break;
|
||||||
|
case BYTE:
|
||||||
|
sb.append("byte");
|
||||||
|
break;
|
||||||
|
case SHORT:
|
||||||
|
sb.append("short");
|
||||||
|
break;
|
||||||
|
case CHARACTER:
|
||||||
|
sb.append("char");
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
sb.append("int");
|
||||||
|
break;
|
||||||
|
case LONG:
|
||||||
|
sb.append("long");
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
sb.append("float");
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
sb.append("double");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (type == ValueType.VOID) {
|
||||||
|
sb.append("primitives/void");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeName(String name) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
escape(name, sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void escape(String className, StringBuilder sb) {
|
||||||
|
for (int i = 0; i < className.length(); ++i) {
|
||||||
|
char c = className.charAt(i);
|
||||||
|
switch (c) {
|
||||||
|
case '.':
|
||||||
|
sb.append('/');
|
||||||
|
break;
|
||||||
|
case '@':
|
||||||
|
sb.append("@@");
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
sb.append("@s");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
sb.append("@b");
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
sb.append("@c");
|
||||||
|
break;
|
||||||
|
case ';':
|
||||||
|
sb.append("@e");
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
sb.append("@m");
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
sb.append("@q");
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
sb.append("@l");
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
sb.append("@g");
|
||||||
|
break;
|
||||||
|
case '|':
|
||||||
|
sb.append("@p");
|
||||||
|
break;
|
||||||
|
case '$':
|
||||||
|
sb.append("@d");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sb.append(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,8 @@ public class SimpleIncludeManager extends IncludeManager {
|
||||||
private CodeWriter writer;
|
private CodeWriter writer;
|
||||||
private CodeWriter emptyLine;
|
private CodeWriter emptyLine;
|
||||||
|
|
||||||
public SimpleIncludeManager(CodeWriter writer) {
|
public SimpleIncludeManager(FileNameProvider fileNames, CodeWriter writer) {
|
||||||
|
super(fileNames);
|
||||||
this.writer = writer.fragment();
|
this.writer = writer.fragment();
|
||||||
emptyLine = writer.fragment();
|
emptyLine = writer.fragment();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.teavm.backend.c.CTarget;
|
import org.teavm.backend.c.CTarget;
|
||||||
import org.teavm.backend.c.generate.CNameProvider;
|
import org.teavm.backend.c.generate.CNameProvider;
|
||||||
|
import org.teavm.backend.c.generate.ShorteningFileNameProvider;
|
||||||
|
import org.teavm.backend.c.generate.SimpleFileNameProvider;
|
||||||
import org.teavm.backend.javascript.JavaScriptTarget;
|
import org.teavm.backend.javascript.JavaScriptTarget;
|
||||||
import org.teavm.backend.wasm.WasmTarget;
|
import org.teavm.backend.wasm.WasmTarget;
|
||||||
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
|
@ -108,6 +110,7 @@ public class TeaVMTool {
|
||||||
private ReferenceCache referenceCache;
|
private ReferenceCache referenceCache;
|
||||||
private boolean longjmpSupported = true;
|
private boolean longjmpSupported = true;
|
||||||
private boolean heapDump;
|
private boolean heapDump;
|
||||||
|
private boolean shortFileNames;
|
||||||
|
|
||||||
public File getTargetDirectory() {
|
public File getTargetDirectory() {
|
||||||
return targetDirectory;
|
return targetDirectory;
|
||||||
|
@ -261,6 +264,10 @@ public class TeaVMTool {
|
||||||
this.heapDump = heapDump;
|
this.heapDump = heapDump;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setShortFileNames(boolean shortFileNames) {
|
||||||
|
this.shortFileNames = shortFileNames;
|
||||||
|
}
|
||||||
|
|
||||||
public void setProgressListener(TeaVMProgressListener progressListener) {
|
public void setProgressListener(TeaVMProgressListener progressListener) {
|
||||||
this.progressListener = progressListener;
|
this.progressListener = progressListener;
|
||||||
}
|
}
|
||||||
|
@ -342,6 +349,9 @@ public class TeaVMTool {
|
||||||
cTarget.setLongjmpUsed(longjmpSupported);
|
cTarget.setLongjmpUsed(longjmpSupported);
|
||||||
cTarget.setHeapDump(heapDump);
|
cTarget.setHeapDump(heapDump);
|
||||||
cTarget.setObfuscated(obfuscated);
|
cTarget.setObfuscated(obfuscated);
|
||||||
|
cTarget.setFileNames(shortFileNames
|
||||||
|
? new ShorteningFileNameProvider(new SimpleFileNameProvider())
|
||||||
|
: new SimpleFileNameProvider());
|
||||||
return cTarget;
|
return cTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,5 +82,7 @@ public interface BuildStrategy {
|
||||||
|
|
||||||
void setHeapDump(boolean heapDump);
|
void setHeapDump(boolean heapDump);
|
||||||
|
|
||||||
|
void setShortFileNames(boolean shortFileNames);
|
||||||
|
|
||||||
BuildResult build() throws BuildException;
|
BuildResult build() throws BuildException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
private TeaVMProgressListener progressListener;
|
private TeaVMProgressListener progressListener;
|
||||||
private Properties properties = new Properties();
|
private Properties properties = new Properties();
|
||||||
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
||||||
|
private boolean shortFileNames;
|
||||||
|
|
||||||
public InProcessBuildStrategy(ClassLoaderFactory classLoaderFactory) {
|
public InProcessBuildStrategy(ClassLoaderFactory classLoaderFactory) {
|
||||||
this.classLoaderFactory = classLoaderFactory;
|
this.classLoaderFactory = classLoaderFactory;
|
||||||
|
@ -220,6 +221,11 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
this.heapDump = heapDump;
|
this.heapDump = heapDump;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShortFileNames(boolean shortFileNames) {
|
||||||
|
this.shortFileNames = shortFileNames;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BuildResult build() throws BuildException {
|
public BuildResult build() throws BuildException {
|
||||||
TeaVMTool tool = new TeaVMTool();
|
TeaVMTool tool = new TeaVMTool();
|
||||||
|
@ -250,6 +256,7 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
tool.setMaxHeapSize(maxHeapSize);
|
tool.setMaxHeapSize(maxHeapSize);
|
||||||
tool.setLongjmpSupported(longjmpSupported);
|
tool.setLongjmpSupported(longjmpSupported);
|
||||||
tool.setHeapDump(heapDump);
|
tool.setHeapDump(heapDump);
|
||||||
|
tool.setShortFileNames(shortFileNames);
|
||||||
|
|
||||||
tool.getProperties().putAll(properties);
|
tool.getProperties().putAll(properties);
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,11 @@ public class RemoteBuildStrategy implements BuildStrategy {
|
||||||
request.heapDump = heapDump;
|
request.heapDump = heapDump;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShortFileNames(boolean shortFileNames) {
|
||||||
|
request.shortFileNames = shortFileNames;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BuildResult build() throws BuildException {
|
public BuildResult build() throws BuildException {
|
||||||
RemoteBuildResponse response;
|
RemoteBuildResponse response;
|
||||||
|
|
|
@ -163,6 +163,7 @@ public class BuildDaemon extends UnicastRemoteObject implements RemoteBuildServi
|
||||||
tool.setMaxHeapSize(request.maxHeapSize);
|
tool.setMaxHeapSize(request.maxHeapSize);
|
||||||
tool.setLongjmpSupported(request.longjmpSupported);
|
tool.setLongjmpSupported(request.longjmpSupported);
|
||||||
tool.setHeapDump(request.heapDump);
|
tool.setHeapDump(request.heapDump);
|
||||||
|
tool.setShortFileNames(request.shortFileNames);
|
||||||
|
|
||||||
for (String sourceDirectory : request.sourceDirectories) {
|
for (String sourceDirectory : request.sourceDirectories) {
|
||||||
tool.addSourceFileProvider(new DirectorySourceFileProvider(new File(sourceDirectory)));
|
tool.addSourceFileProvider(new DirectorySourceFileProvider(new File(sourceDirectory)));
|
||||||
|
|
|
@ -50,4 +50,5 @@ public class RemoteBuildRequest implements Serializable {
|
||||||
public int maxHeapSize;
|
public int maxHeapSize;
|
||||||
public boolean longjmpSupported;
|
public boolean longjmpSupported;
|
||||||
public boolean heapDump;
|
public boolean heapDump;
|
||||||
|
public boolean shortFileNames;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,9 @@ public class TeaVMCompileMojo extends AbstractMojo {
|
||||||
@Parameter(property = "teavm.heapDump", defaultValue = "false")
|
@Parameter(property = "teavm.heapDump", defaultValue = "false")
|
||||||
private boolean heapDump;
|
private boolean heapDump;
|
||||||
|
|
||||||
|
@Parameter(property = "teavm.shortFileNames", defaultValue = "false")
|
||||||
|
private boolean shortFileNames;
|
||||||
|
|
||||||
private void setupBuilder(BuildStrategy builder) throws MojoExecutionException {
|
private void setupBuilder(BuildStrategy builder) throws MojoExecutionException {
|
||||||
builder.setLog(new MavenTeaVMToolLog(getLog()));
|
builder.setLog(new MavenTeaVMToolLog(getLog()));
|
||||||
try {
|
try {
|
||||||
|
@ -182,6 +185,7 @@ public class TeaVMCompileMojo extends AbstractMojo {
|
||||||
builder.setSourceFilesCopied(sourceFilesCopied);
|
builder.setSourceFilesCopied(sourceFilesCopied);
|
||||||
builder.setMinHeapSize(minHeapSize * 1024 * 1024);
|
builder.setMinHeapSize(minHeapSize * 1024 * 1024);
|
||||||
builder.setMaxHeapSize(maxHeapSize * 1024 * 1024);
|
builder.setMaxHeapSize(maxHeapSize * 1024 * 1024);
|
||||||
|
builder.setShortFileNames(shortFileNames);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
throw new MojoExecutionException("Unexpected error occurred", e);
|
throw new MojoExecutionException("Unexpected error occurred", e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user