Skip to content

Commit 9358dea

Browse files
committed
[GR-31710] Support building js-launcher with image-builder on module-path.
PullRequest: graal/9671
2 parents 6cae92d + 089232f commit 9358dea

File tree

18 files changed

+257
-74
lines changed

18 files changed

+257
-74
lines changed

sdk/mx.sdk/suite.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@
105105
}
106106
},
107107
"JLINE3" : {
108-
"sha1" : "4cb5f6c20b10912ef3c12f4c4c3ebcdbcbe3a555",
109-
"version" : "3.16.0.1",
108+
"sha1" : "bac1579375a67379d8f308016138f9c37a646dd5",
109+
"version" : "3.16.0.2",
110110
"urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/jline3-shadowed-{version}.jar"],
111111
"license" : "BSD-new",
112112
"requires" : ["java.logging"],
Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,31 @@
11
Args = --features=com.oracle.svm.thirdparty.jline.JLine3Feature \
2-
-H:JNIConfigurationResources=${.}/launcher.jniconfig
2+
-H:JNIConfigurationResources=${.}/launcher.jniconfig \
3+
--add-modules=java.scripting \
4+
--add-reads=org.graalvm.launcher=org.graalvm.nativeimage.base \
5+
--add-reads=org.graalvm.launcher=org.graalvm.nativeimage.pointsto \
6+
--add-reads=org.graalvm.launcher=org.graalvm.nativeimage.builder \
7+
--add-exports=org.graalvm.truffle/com.oracle.truffle.object=ALL-UNNAMED \
8+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api=ALL-UNNAMED \
9+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl=ALL-UNNAMED \
10+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.object=ALL-UNNAMED \
11+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm.tree.analysis=ALL-UNNAMED \
12+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.memory=ALL-UNNAMED \
13+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.object.dsl=ALL-UNNAMED \
14+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.exception=ALL-UNNAMED \
15+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.interop=ALL-UNNAMED \
16+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.profiles=ALL-UNNAMED \
17+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm.signature=ALL-UNNAMED \
18+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm=ALL-UNNAMED \
19+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.dsl=ALL-UNNAMED \
20+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm.tree=ALL-UNNAMED \
21+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.utilities=ALL-UNNAMED \
22+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.source=ALL-UNNAMED \
23+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.library=ALL-UNNAMED \
24+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.staticobject=ALL-UNNAMED \
25+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.debug=ALL-UNNAMED \
26+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.nodes=ALL-UNNAMED \
27+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.frame=ALL-UNNAMED \
28+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.instrumentation=ALL-UNNAMED \
29+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm.commons=ALL-UNNAMED \
30+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.io=ALL-UNNAMED \
31+
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.debug.impl=ALL-UNNAMED

substratevm/mx.substratevm/suite.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,7 @@
10851085
"com.oracle.svm.core.snippets", # Uses of com.oracle.svm.core.snippets.KnownIntrinsics
10861086
"com.oracle.svm.core", # Uses of com.oracle.svm.core.TypeResult
10871087
"com.oracle.svm.core.util", # Uses of com.oracle.svm.core.util.VMError
1088+
"com.oracle.svm.core.jni", # Uses of com.oracle.svm.core.jni.JNIRuntimeAccess
10881089
"com.oracle.svm.jfr", # Uses of com.oracle.svm.jfr.JfrEnabled
10891090
"com.oracle.svm.hosted to java.base",
10901091
"com.oracle.svm.hosted.agent to java.instrument",
@@ -1116,6 +1117,7 @@
11161117
"com.oracle.truffle.api.TruffleLanguage.Provider",
11171118
"com.oracle.truffle.api.instrumentation.TruffleInstrument.Provider",
11181119
"com.oracle.svm.hosted.agent.NativeImageBytecodeInstrumentationAgentExtension",
1120+
"com.oracle.svm.hosted.NativeImageClassLoaderPostProcessing",
11191121
],
11201122
"requiresConcealed": {
11211123
"jdk.internal.vm.ci": [
@@ -1137,12 +1139,14 @@
11371139
"sun.security.jca",
11381140
"sun.security.util",
11391141
"sun.security.provider",
1142+
"sun.security.ssl",
11401143
"com.sun.crypto.provider",
11411144
"sun.reflect.generics.repository",
11421145
"jdk.internal.org.objectweb.asm",
11431146
"sun.util.locale.provider",
11441147
"sun.util.resources",
11451148
"sun.invoke.util",
1149+
"sun.net",
11461150
],
11471151
"java.management": [
11481152
"sun.management",

substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk11/Target_java_lang_Module_JDK11OrLater.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.jdk11;
2626

27-
import java.io.ByteArrayInputStream;
28-
import java.io.InputStream;
29-
import java.util.Arrays;
30-
import java.util.Objects;
31-
3227
import com.oracle.svm.core.annotate.Alias;
3328
import com.oracle.svm.core.annotate.RecomputeFieldValue;
3429
import com.oracle.svm.core.annotate.Substitute;
@@ -39,6 +34,12 @@
3934
import com.oracle.svm.core.jdk.Resources;
4035
import com.oracle.svm.core.jdk.resources.ResourceStorageEntry;
4136

37+
import java.io.ByteArrayInputStream;
38+
import java.io.InputStream;
39+
import java.util.Arrays;
40+
import java.util.Map;
41+
import java.util.Objects;
42+
4243
@SuppressWarnings("unused")
4344
@TargetClass(value = java.lang.Module.class, onlyWith = JDK11OrLater.class)
4445
public final class Target_java_lang_Module_JDK11OrLater {
@@ -96,6 +97,10 @@ private static void addExportsToAllUnnamed0(Module from, String pn) {
9697

9798
@TargetClass(className = "java.lang.Module", innerClass = "ReflectionData", onlyWith = JDK11OrLater.class) //
9899
private static final class Target_java_lang_Module_ReflectionData {
100+
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "java.lang.WeakPairMap") //
101+
static Target_java_lang_WeakPairMap<Module, Module, Boolean> reads;
102+
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "java.lang.WeakPairMap") //
103+
static Target_java_lang_WeakPairMap<Module, Module, Map<String, Boolean>> exports;
99104
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "java.lang.WeakPairMap") //
100105
static Target_java_lang_WeakPairMap<Module, Class<?>, Boolean> uses;
101106
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/APIOption.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,16 @@
7373

7474
APIOptionKind kind() default APIOptionKind.Default;
7575

76+
char WHITESPACE_SEPARATOR = ' ';
77+
7678
/**
7779
* Provide a custom separator that should be used to separate the option name from its option
78-
* values. The default separator is {@code '='}.
80+
* values. The default separator is {@code '='}. If {@code WHITESPACE_SEPARATOR} is used the
81+
* option value has to be passed as the next argument (i.e., separated by whitespace on the
82+
* command line). It is also allowed to provide more than one separator. See e.g. the options
83+
* defined in {@code com.oracle.svm.hosted.NativeImageClassLoaderOptions}
7984
*/
80-
char valueSeparator() default '=';
85+
char[] valueSeparator() default {'='};
8186

8287
/**
8388
* The value that will be passed to a non-boolean option when no {@code =} is specified.

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/SubstrateOptionsParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ public static String commandArgument(OptionKey<?> option, String value, String a
212212
if (apiOption.fixedValue().length == 0) {
213213
if (apiOptionWithValue == null) {
214214
/* First APIOption that accepts value is selected as fallback */
215-
apiOptionWithValue = optionName + apiOption.valueSeparator() + value;
215+
apiOptionWithValue = optionName + apiOption.valueSeparator()[0] + value;
216216
}
217217
} else if (apiOption.fixedValue()[0].equals(value)) {
218218
/* Return requested option expressed as fixed-value APIOption */

substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/APIOptionHandler.java

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class APIOptionHandler extends NativeImage.OptionHandler<NativeImage> {
6464

6565
static final class OptionInfo {
6666
final String[] variants;
67-
final char valueSeparator;
67+
final char[] valueSeparator;
6868
final String builderOption;
6969
final String defaultValue;
7070
final String helpText;
@@ -76,7 +76,7 @@ static final class OptionInfo {
7676
final List<Function<Object, Object>> valueTransformers;
7777
final APIOptionGroup group;
7878

79-
OptionInfo(String[] variants, char valueSeparator, String builderOption, String defaultValue, String helpText, boolean hasPathArguments, boolean defaultFinal, String deprecationWarning,
79+
OptionInfo(String[] variants, char[] valueSeparator, String builderOption, String defaultValue, String helpText, boolean hasPathArguments, boolean defaultFinal, String deprecationWarning,
8080
List<Function<Object, Object>> valueTransformers, APIOptionGroup group, boolean extra) {
8181
this.variants = variants;
8282
this.valueSeparator = valueSeparator;
@@ -150,6 +150,7 @@ private static void extractOption(String optionPrefix, OptionDescriptor optionDe
150150
VMError.guarantee(optionDescriptor.getOptionKey() instanceof HostedOptionKey, "Only HostedOptionKeys are allowed to have array type key values.");
151151
optionValueType = optionValueType.getComponentType();
152152
}
153+
boolean hasFixedValue = apiAnnotation.fixedValue().length > 0;
153154
if (optionValueType.equals(Boolean.class)) {
154155
if (!apiAnnotation.group().equals(APIOption.NullGroup.class)) {
155156
try {
@@ -182,7 +183,7 @@ private static void extractOption(String optionPrefix, OptionDescriptor optionDe
182183
if (apiAnnotation.defaultValue().length > 0) {
183184
VMError.shouldNotReachHere(String.format("Boolean APIOption %s(%s) cannot use APIOption.defaultValue", apiOptionName, rawOptionName));
184185
}
185-
if (apiAnnotation.fixedValue().length > 0) {
186+
if (hasFixedValue) {
186187
VMError.shouldNotReachHere(String.format("Boolean APIOption %s(%s) cannot use APIOption.fixedValue", apiOptionName, rawOptionName));
187188
}
188189
builderOption += apiAnnotation.kind().equals(APIOptionKind.Negated) ? "-" : "+";
@@ -201,13 +202,13 @@ private static void extractOption(String optionPrefix, OptionDescriptor optionDe
201202
if (apiAnnotation.fixedValue().length > 1) {
202203
VMError.shouldNotReachHere(String.format("APIOption %s(%s) cannot have more than one APIOption.fixedValue", apiOptionName, rawOptionName));
203204
}
204-
if (apiAnnotation.fixedValue().length > 0 && apiAnnotation.defaultValue().length > 0) {
205+
if (hasFixedValue && apiAnnotation.defaultValue().length > 0) {
205206
VMError.shouldNotReachHere(String.format("APIOption %s(%s) APIOption.defaultValue and APIOption.fixedValue cannot be combined", apiOptionName, rawOptionName));
206207
}
207208
if (apiAnnotation.defaultValue().length > 0) {
208209
defaultValue = apiAnnotation.defaultValue()[0];
209210
}
210-
if (apiAnnotation.fixedValue().length > 0) {
211+
if (hasFixedValue) {
211212
defaultValue = apiAnnotation.fixedValue()[0];
212213
}
213214

@@ -236,10 +237,26 @@ private static void extractOption(String optionPrefix, OptionDescriptor optionDe
236237
"Class specified as valueTransformer for @APIOption " + apiOptionName + " cannot be loaded or instantiated: " + transformerClass.getTypeName(), ex.getCause());
237238
}
238239
}
240+
if (apiAnnotation.valueSeparator().length == 0) {
241+
throw VMError.shouldNotReachHere(String.format("APIOption %s(%s) does not specify any valueSeparator", apiOptionName, rawOptionName));
242+
}
243+
if (Arrays.asList(apiAnnotation.valueSeparator()).contains(APIOption.WHITESPACE_SEPARATOR)) {
244+
String msgTail = " cannot use APIOption.WHITESPACE_SEPARATOR as value separator";
245+
if (booleanOption) {
246+
throw VMError.shouldNotReachHere(String.format("Boolean APIOption %s(%s)" + msgTail, apiOptionName, rawOptionName));
247+
}
248+
if (hasFixedValue) {
249+
VMError.shouldNotReachHere(String.format("APIOption %s(%s) with fixed value" + msgTail, apiOptionName, rawOptionName));
250+
}
251+
if (defaultValue != null) {
252+
VMError.shouldNotReachHere(String.format("APIOption %s(%s) with default value" + msgTail, apiOptionName, rawOptionName));
253+
}
254+
}
255+
boolean defaultFinal = booleanOption || hasFixedValue;
239256
apiOptions.put(apiOptionName,
240257
new APIOptionHandler.OptionInfo(apiAnnotation.name(), apiAnnotation.valueSeparator(), builderOption, defaultValue, helpText,
241258
apiAnnotation.kind().equals(APIOptionKind.Paths),
242-
booleanOption || apiAnnotation.fixedValue().length > 0, apiAnnotation.deprecated(), valueTransformers, group, apiAnnotation.extra()));
259+
defaultFinal, apiAnnotation.deprecated(), valueTransformers, group, apiAnnotation.extra()));
243260
}
244261
} catch (NoSuchFieldException e) {
245262
/* Does not qualify as APIOption */
@@ -253,8 +270,7 @@ private static String startLowerCase(String str) {
253270
@Override
254271
boolean consume(ArgumentQueue args) {
255272
String headArg = args.peek();
256-
257-
String translatedOption = translateOption(headArg);
273+
String translatedOption = translateOption(args);
258274
if (translatedOption != null) {
259275
args.poll();
260276
nativeImage.addPlainImageBuilderArg(NativeImage.injectHostedOptionOrigin(translatedOption, args.argumentOrigin));
@@ -266,16 +282,18 @@ boolean consume(ArgumentQueue args) {
266282
GroupInfo groupInfo = entry.getValue();
267283
String groupName = APIOption.Utils.optionName(groupInfo.group.name());
268284
String supportedValues = "'" + String.join("', '", groupInfo.supportedValues) + "'";
269-
NativeImage.showError("'" + headArg.substring(groupNameAndSeparator.length()) + "' is not a valid value for the option " + groupName + ". Supported values are " + supportedValues);
285+
NativeImage.showError("In " + args.argumentOrigin + " '" + headArg.substring(groupNameAndSeparator.length()) + "' is not a valid value for the option " + groupName +
286+
". Supported values are " + supportedValues);
270287
}
271288
}
272289
}
273290
return false;
274291
}
275292

276-
String translateOption(String arg) {
293+
String translateOption(ArgumentQueue argQueue) {
277294
OptionInfo option = null;
278295
String[] optionNameAndOptionValue = null;
296+
String argumentOrigin = argQueue.argumentOrigin;
279297
found: for (OptionInfo optionInfo : apiOptions.values()) {
280298
for (String variant : optionInfo.variants) {
281299
String optionName;
@@ -284,29 +302,40 @@ String translateOption(String arg) {
284302
} else {
285303
optionName = APIOption.Utils.groupName(optionInfo.group) + variant;
286304
}
287-
if (arg.equals(optionName)) {
305+
String headArg = argQueue.peek();
306+
if ((optionInfo.defaultFinal || optionInfo.defaultValue != null) && headArg.equals(optionName)) {
288307
option = optionInfo;
289308
optionNameAndOptionValue = new String[]{optionName};
290309
break found;
291310
}
292-
if (arg.startsWith(optionName + optionInfo.valueSeparator)) {
293-
option = optionInfo;
294-
optionNameAndOptionValue = SubstrateUtil.split(arg, Character.toString(optionInfo.valueSeparator), 2);
295-
break found;
311+
for (char valueSeparator : optionInfo.valueSeparator) {
312+
if (valueSeparator == APIOption.WHITESPACE_SEPARATOR && headArg.equals(optionName)) {
313+
argQueue.poll();
314+
String optionValue = argQueue.peek();
315+
if (optionValue == null) {
316+
NativeImage.showError(headArg + " from " + argumentOrigin + " requires option argument");
317+
}
318+
option = optionInfo;
319+
optionNameAndOptionValue = new String[]{headArg, optionValue};
320+
break found;
321+
} else if (headArg.startsWith(optionName + valueSeparator)) {
322+
option = optionInfo;
323+
optionNameAndOptionValue = SubstrateUtil.split(headArg, Character.toString(valueSeparator), 2);
324+
break found;
325+
}
296326
}
297327
}
298-
299328
}
300329
if (option != null) {
301330
if (!option.deprecationWarning.isEmpty()) {
302-
NativeImage.showWarning("Using a deprecated option " + optionNameAndOptionValue[0] + ". " + option.deprecationWarning);
331+
NativeImage.showWarning("Using a deprecated option " + optionNameAndOptionValue[0] + " from " + argumentOrigin + ". " + option.deprecationWarning);
303332
}
304333
String builderOption = option.builderOption;
305334
/* If option is in group, defaultValue has different use */
306335
String optionValue = option.group != null ? null : option.defaultValue;
307336
if (optionNameAndOptionValue.length == 2) {
308337
if (option.defaultFinal) {
309-
NativeImage.showError("Passing values to option " + optionNameAndOptionValue[0] + " is not supported.");
338+
NativeImage.showError("Passing values to option " + optionNameAndOptionValue[0] + " from " + argumentOrigin + " is not supported.");
310339
}
311340
optionValue = optionNameAndOptionValue[1];
312341
}

0 commit comments

Comments
 (0)