code-playpad 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/JAVA-COMPATIBILITY.md +12 -12
- package/README.md +104 -14
- package/dist/COMPILER-LICENSE-AUDIT.md +104 -0
- package/dist/COMPILER-NOTICES.txt +16973 -0
- package/dist/THIRD-PARTY-NOTICES.txt +102 -0
- package/dist/cdn.js +2 -2
- package/dist/compiler-license-manifest.json +198 -0
- package/dist/{config-D9w0xYhX.js → config-cwuPIQ48.js} +1 -1
- package/dist/cpp-D2TrExLz.js +1 -0
- package/dist/cpp-DakNa4ys.js +6 -0
- package/dist/dist--J_vhCIU.js +14 -0
- package/dist/{dist-B5vq9x6M.js → dist-BIgiGgKu.js} +1 -1
- package/dist/dist-BNvM_BAY.js +6 -0
- package/dist/{dist-XlpaG2JF.js → dist-BkpKCrXQ.js} +1 -1
- package/dist/{dist-BKRQwpg6.js → dist-CJxiVI4a.js} +1 -1
- package/dist/dist-CNOK8CHE.js +6 -0
- package/dist/dist-D25hs99E.js +10 -0
- package/dist/dist-D2igTc4m.js +6 -0
- package/dist/{dist-CqpVTRAq.js → dist-D7jBL3Ib.js} +9 -9
- package/dist/dist-DXjodKfp.js +6 -0
- package/dist/dist-DfFrsBkU.js +8 -0
- package/dist/dist-Vr-fb58P.js +12 -0
- package/dist/{element-DaStU7U7.js → element-BQWrbSEp.js} +7 -7
- package/dist/element.js +1 -1
- package/dist/{hints-v5iHTd1l.js → hints-CCMgezw9.js} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/java-DeBiVPXO.js +6 -0
- package/dist/java-Xf1xYcVv.js +1 -0
- package/dist/{java-library-bitset.generated-Duwl7F-b.js → java-library-bitset.generated-C3m-nf8F.js} +1 -1
- package/dist/{java-library-math.generated-DmUvund7.js → java-library-math.generated-BQwpn8sQ.js} +1 -1
- package/dist/{java-library-regex.generated-a8crcad3.js → java-library-regex.generated-ItYSF2aV.js} +1 -1
- package/dist/java-library-time.generated-Dl0XA7nZ.js +6 -0
- package/dist/java-library.generated-B7ib0gOX.js +6 -0
- package/dist/{javascript-CSfl5gbA.js → javascript-CTY3U1Mc.js} +4 -2
- package/dist/{javascript-CX-lsX2u.js → javascript-DkarEcEB.js} +4 -2
- package/dist/{pyodide-Crdd9em4.js → pyodide-B1U3JD9Z.js} +2 -2
- package/dist/{pyodide-CdDlM0du.js → pyodide-BGBI232i.js} +1 -1
- package/dist/react.js +1 -1
- package/dist/runtime/compiler-assets.d.ts +5 -0
- package/dist/runtime/compiler-cache.d.ts +9 -0
- package/dist/runtime/config.d.ts +11 -0
- package/dist/runtime/cpp/assets.d.ts +6 -0
- package/dist/runtime/cpp/project.d.ts +9 -0
- package/dist/runtime/cpp/worker.d.ts +1 -0
- package/dist/runtime/cpp-worker.generated.d.ts +1 -0
- package/dist/runtime/cpp.d.ts +3 -0
- package/dist/runtime/java-library-bitset.generated.d.ts +2 -2
- package/dist/runtime/java-library-math.generated.d.ts +2 -2
- package/dist/runtime/java-library-regex.generated.d.ts +2 -2
- package/dist/runtime/java-library-time.generated.d.ts +3 -3
- package/dist/runtime/java-library.generated.d.ts +3 -3
- package/dist/runtime/java-worker.generated.d.ts +3 -3
- package/dist/runtime/worker-runtime.d.ts +1 -0
- package/dist/standalone.js +9 -9
- package/dist/types.d.ts +13 -1
- package/dist/worker-runtime-DfYet3xy.js +9 -0
- package/dist/worker-runtime-Dq71SbjR.js +4 -0
- package/package.json +18 -6
- package/dist/dist-BThnYaQ5.js +0 -12
- package/dist/dist-CnC1nMtN.js +0 -6
- package/dist/dist-D0FPZcUi.js +0 -8
- package/dist/dist-DOsLUKSb.js +0 -10
- package/dist/dist-D_qJovVA.js +0 -14
- package/dist/dist-DlIO0dzi.js +0 -6
- package/dist/dist-DmrP6yta.js +0 -6
- package/dist/java-DIL6bxPF.js +0 -1
- package/dist/java-DxQWnfHu.js +0 -6
- package/dist/java-library-time.generated-mFyqZ0pg.js +0 -6
- package/dist/java-library.generated-1yFV284B.js +0 -6
- package/dist/worker-runtime-C8pmmgW9.js +0 -4
- package/dist/worker-runtime-CNPpMRo1.js +0 -9
package/JAVA-COMPATIBILITY.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
<!-- GENERATED by scripts/sync-java.mjs from java-online-compiler@0.
|
|
1
|
+
<!-- GENERATED by scripts/sync-java.mjs from java-online-compiler@0.39.0 (b00eddf254edc4545e4856c2bf729adfc6d7265c). Do not edit. -->
|
|
2
2
|
|
|
3
|
-
> This is the compatibility table of the Java engine that code-playpad ships (engine 0.
|
|
3
|
+
> This is the compatibility table of the Java engine that code-playpad ships (engine 0.39.0).
|
|
4
4
|
> Paths such as `tests/…`, `SPEC.md` and `docs/…` refer to the engine's source (`java-engine/` in code-playpad's repository), which is not part of the package.
|
|
5
5
|
|
|
6
|
-
# Compatibility — engine 0.
|
|
6
|
+
# Compatibility — engine 0.39.0 (Stage A, compact source files, objects, numbers and control flow, collections, lambdas, practice mode, String, format, regex, Math, Random, System, Scanner and IO.readln, inheritance, interfaces, Object, instanceof, enums, records, exceptions, hash order, fixed collections, TreeMap, TreeSet, LinkedList, Stack, lambdas, method references, generic classes and methods, var, annotations, varargs, anonymous classes, streams, subList, local classes, raw types, float, byte and short, pattern matching, sealed classes, BigInteger, BigDecimal, EnumMap, EnumSet, fast I/O, static imports, initializer blocks, text blocks, enum constant bodies, Interface.super, ListIterator, reversed views, access-ordered LinkedHashMap, var lambda parameters, array clone, library subclasses, bridge methods, Vector, Hashtable, StringBuffer, StringJoiner, java.util.regex, outer.new, BitSet, parallel streams, java.time dates, AbstractList, LocalTime, LocalDateTime, Duration, Instant, time zones, packages)
|
|
7
7
|
|
|
8
8
|
This document records what the engine accepts, what it rejects, and the evidence that it behaves like Java. Every method of every library class, with its status and the tests that call it, is in docs/feature-manifest.json (`npm run manifest`). The reference is Java SE 25 (SPEC.md §4), and what the engine implements is **a documented subset of Java 25**, not "Java 25".
|
|
9
9
|
|
|
@@ -41,9 +41,10 @@ Every feature has one status:
|
|
|
41
41
|
| **Enums** (JLS 8.9) | Supported with limits | Nested or top-level, with fields, constructors (with the hidden name and ordinal, so NPE messages say `<parameter3>`), methods, static members, and `implements`. `values()` (a new array each time), `valueOf(String)` (`IllegalArgumentException: No enum constant Main.Color.PURPLE`, `NullPointerException: Name is null`, with the enum's own frame), `name()`, `ordinal()`, `compareTo` (by ordinal), `toString()` (overridable), `getDeclaringClass()`, `equals` and `hashCode` (identity). The constants are made when the enum initializes, before its other static fields; an exception there is `ExceptionInInitializerError`. `switch` on an enum, with simple or qualified labels (`case RED`, `case Color.RED`); a switch expression naming every constant needs no `default`; a null selector fails as the JDK's does (`Cannot invoke "Main$Color.ordinal()"`). Enums are Comparable, so they sort and queue in declaration order. javac's errors: `enum classes may not be instantiated`, `modifier public not allowed here`, `name() in E cannot override name() in Enum`. `EnumMap` and `EnumSet` are supported (see *Library*). Constants with a class body (`PLUS { int apply(int a, int b) { return a + b; } }`): each is an anonymous subclass of the enum (`Main$Op$1`, numbered with the anonymous classes of the constants' arguments, before the members'), with its own fields, methods, `super` calls and initializer blocks; `getClass()` is the body's class and `getDeclaringClass()` the enum, also in EnumMap and EnumSet. An enum may leave abstract methods to its constants' bodies. javac's errors: `<anonymous Main$Op$2> is not abstract and does not override abstract method apply(int,int) in Op`, `Op is abstract; cannot be instantiated` (a constant without a body), `non-static variable symbol cannot be referenced from a static context` (the enum's private members are not inherited by a body), `equals(Object) in <anonymous Main$Op$1> cannot override equals(Object) in Enum`. |
|
|
42
42
|
| **Records** (JLS 8.10) | Supported with limits | Nested or top-level, with components, accessors (generated, or declared: `invalid accessor method in record R`), the canonical constructor (generated, compact `R { ... }` with the fields assigned after its body, or explicit), other constructors (which must call another: `constructor is not canonical, so it must invoke another constructor of class R`), static fields and methods, instance methods, and `implements`. `toString()` (`Point[x=1, y=2]`, components as String.valueOf shows them, with the record's own frame when one fails), `equals` (doubles compared as `Double.compare` does) and `hashCode` (`31 * h + hash(component)`) as the JDK computes them, unless declared. javac's errors: `field declaration must be static`, `cannot assign a value to final variable v`. Generic records (`record Pair<A, B>(A first, B second)`) are supported; so are local records and record patterns (see *Pattern matching*). |
|
|
43
43
|
| `getClass()`, `X.class` | Supported with limits | A `Class` value per class: `getName()` (`Main$Node`, `[I`), `getSimpleName()` (`Node`, `int[]`), `isInterface()`, `isArray()`, printing as `class Main$Node`, and `==` between classes, as `equals` methods use it. `X.class` is a `Class<X>` (so `new EnumMap<>(Day.class)` infers its key type); `Class<?>` may be declared. The reflection methods are unsupported. |
|
|
44
|
-
| Running a file, and programs in several files (JEP 458) | Supported with limits | Behaves like `java <entry>` in source-file mode. The program's other `.java` files (`Session.java` beside `Main.java`) are compiled as the JDK's launcher compiles them: a file when the program first names the class it is named after, so a file nothing names is never compiled, and its errors never reported. Each file has its own imports. A class of the entry file wins over another file's of the same name. Errors and stack traces name each file (`Session.java:2: error: …`, `at Session.describe(Session.java:5)`); where the JDK prints another file's absolute path on disk, the engine prints its name. A file's warnings print again when the program first uses one of its classes, as the launcher's second compilation prints them (a class literal, `Helper.class`, is not counted as a use). Limits: 32 files, 500,000 characters per file and 1,000,000 together. A requested entry that is not among the files fails as `java Missing.java` does (`Error: Could not find or load main class Missing.java`); another file never runs in its place.
|
|
44
|
+
| Running a file, and programs in several files (JEP 458) | Supported with limits | Behaves like `java <entry>` in source-file mode. The program's other `.java` files (`Session.java` beside `Main.java`) are compiled as the JDK's launcher compiles them: a file when the program first names the class it is named after, so a file nothing names is never compiled, and its errors never reported. Each file has its own imports. A class of the entry file wins over another file's of the same name. Errors and stack traces name each file (`Session.java:2: error: …`, `at Session.describe(Session.java:5)`); where the JDK prints another file's absolute path on disk, the engine prints its name. A file's warnings print again when the program first uses one of its classes, as the launcher's second compilation prints them (a class literal, `Helper.class`, is not counted as a use). Limits: 32 files, 500,000 characters per file and 1,000,000 together. A requested entry that is not among the files fails as `java Missing.java` does (`Error: Could not find or load main class Missing.java`); another file never runs in its place. Folders are packages (see the next row); a name with `\\` is reported as not supported. A file first needed by the launch file's declarations (an import, a field's or parameter's type) rather than its code is compiled, as by the launcher, only when the program first loads one of its classes: its code's errors print then, after the output so far, with exit status 2, and a class never loaded is never compiled (ADR 0033). Unsupported: another compact source file with a `main`, and using another file's secondary class (one not named after its file) from outside that file, which the JDK finds only if that file happened to be compiled first. |
|
|
45
|
+
| Packages: `package` declarations, files in folders (ADR 0033) | Supported with limits | `util/Tool.java` declares `package util;` and holds class `util.Tool`, found as the launcher finds it: under the root that the entry's package gives (`app/Main.java` in package `app`: the root is the folder above `app`; `src/Main.java` in no package: `src/`). Single-type, on-demand and static imports of the program's classes and member classes, fully qualified names (`util.MathUtil.square(3)`, `new app.model.Item()`), and JLS 6.4.1's order: the file's classes, single-type imports (the library's too), the package's classes, then on-demand imports, two of which giving a name are javac's `reference to Stack is ambiguous`. Access across packages (JLS 6.6): `Hidden is not public in util; cannot be accessed from outside package`, the same for package-private members and member classes, `describe() has protected access in Shape` (protected members from subclasses, instance ones through the subclass; protected constructors through `super(...)` and anonymous classes), and an inaccessible overload is listed as not applicable. A named package does not see the unnamed one. Binary names everywhere: `getClass().getName()` is `util.Counter`, `getPackageName()` is `util`, stack traces are `at util.MathUtil.boom(MathUtil.java:6)`, uncaught exceptions `errors.AppException: …`. javac's errors for an entry whose folders do not match its package (`end of path to source file does not match its package name app: Main.java`), a package in a compact file, a missing package or class (`package nope does not exist`; `cannot find symbol` with `location: package util`), two imports of one simple name, and an import of the file's own class. Not supported: a file whose package is not its folder's (`util/Tool.java` declaring another package or none; javac reports `bad source file`), and on-demand imports of a class's member types (`import util.Outer.*;`). |
|
|
45
46
|
| No class / no usable main | Supported | `error: no class declared in source file`; `error: can't find main(String[]) or main() method in class: Main`; `error: can't find class: Main`; for a compact file, `compact source file does not have main method in the form of void main() or void main(String[] args)` |
|
|
46
|
-
| `import`: single-type and on-demand | Supported with limits | `import java.util.List;` and `import java.util.*;` for the supported java.util classes (see *Library*); the java.lang ones need no import. A compact source file sees java.util without imports, as Java 25's implicit `import module java.base` gives it. A wrong name gets javac's error: `package java.utill does not exist`, or `cannot find symbol` with `location: package java.util`. Real JDK classes outside the subset (`
|
|
47
|
+
| `import`: single-type and on-demand | Supported with limits | `import java.util.List;` and `import java.util.*;` for the supported java.util classes (see *Library*); the java.lang ones need no import. A compact source file sees java.util without imports, as Java 25's implicit `import module java.base` gives it. A wrong name gets javac's error: `package java.utill does not exist`, or `cannot find symbol` with `location: package java.util`. Real JDK classes outside the subset (`Clock`, `UUID`, …) are unsupported where they are used. Fully qualified names work without an import, in types and in expressions, for every package the subset has: `java.util.stream.IntStream.range(0, 3)`, `java.util.Map.Entry.comparingByKey()`; `java.time.Clock.systemUTC()` is unsupported, not `cannot find symbol`. Classes of java.io, java.math, java.util.function and java.util.stream that the subset has are imported the same way. |
|
|
47
48
|
| `import static`: single and on-demand (JLS 7.5.3, 7.5.4) | Supported | Methods and fields of the supported classes: `import static java.lang.Math.*;`, `import static java.lang.System.out;`, `import static java.util.stream.Collectors.*;`, `import static java.util.Map.entry;`, and member types (`import static java.util.Map.Entry;`). A simple name means the program's own local, field or method first, then a single import, then an on-demand one (JLS 6.4.1). A method of the class or an enclosing one, Object's included, hides every import of that name, so `toString(a)` with `Arrays.*` imported is javac's `method toString in class Object cannot be applied`. Overloads from several on-demand imports are resolved together (`sort(int[])` from Arrays, `sort(List)` from Collections). javac's errors: `reference to MAX_VALUE is ambiguous` (fields, and methods equally specific in two classes), `cannot find symbol` with `symbol: static foo`, a missing class or package, `static import only from classes and interfaces`. Imported constants are constants (switch labels). Importing from a JDK class outside the subset (`TimeUnit`) is fine until a name from it is used, which is unsupported. |
|
|
48
49
|
| Variable-arity methods and constructors (`int... xs`, JLS 8.4.1) | Supported | Chosen in the third phase of overload resolution, as javac chooses (`f(int)` over `f(int...)`, `g(Integer)` over `g(int...)`); the trailing arguments go into a new array, or an array is passed as it is. javac's `varargs parameter must be the last parameter`, `varargs mismatch; …`, and its `[unchecked]` warnings for a parameter type the run cannot check: `Possible heap pollution from parameterized vararg type T` at the declaration and `unchecked generic array creation for varargs parameter of type List<Integer>[]` at the call, unless the method is `@SafeVarargs`. |
|
|
49
50
|
| **Anonymous classes** (JLS 15.9.5) | Supported with limits | `new Comparator<Integer>() { public int compare(...) { ... } }`, `new Shape("sq") { double area() { ... } }`, `new Iterator<>() { ... }`: extending a class of the program (its constructor's arguments passed on) or a built-in exception, or implementing an interface of the program or the library's `Comparable`, `Comparator`, `Iterable`, `Iterator` and functional interfaces (`Runnable`, `Function`, …), with fields, methods, `@Override`, and the diamond inferred from where the object goes. Named as javac names them (`Main$1`, `Main$Holder$1`, `Main$2$1`, in source order per enclosing class), so stack traces, `getClass().getName()` and `<anonymous Main$1>` in diagnostics match; `getSimpleName()` is empty. They capture effectively final locals of the code around them into javac's `val$x` fields (NPE messages say `"this.val$s"`) and use the enclosing instance's members. javac's errors: `<anonymous Main$1> is not abstract and does not override abstract method …`, `anonymous class implements interface; cannot have arguments`, `cannot inherit from final F`, `local variables referenced from an inner class must be final or effectively final`. Extending an inner class or a library class is unsupported. |
|
|
@@ -52,7 +53,7 @@ Every feature has one status:
|
|
|
52
53
|
| **Generic classes, interfaces, records and methods** (JLS 8.1.2, 8.4.4) | Supported with limits | `class Node<T>`, `class BST<K extends Comparable<K>, V> implements Iterable<K>`, `interface Fn<A, B>`, `static <T extends Comparable<? super T>> void sort(T[] a)`, `<R> Pair<K, R> withValue(R r)`. Members are seen through the type arguments (`T val` of a `Node<Integer>` is an `Integer`; a type variable's members are its bound's), supertypes are parameterized (`class Strs extends Base<String>`, with the bridge methods javac generates so overriding dispatches), the diamond and generic methods are inferred from the arguments, the target, implicit lambdas' bodies and the parameter a diamond is passed to, and explicit type arguments (`Main.<Integer>repeat(7, 2)`) work. Bounds are checked: `type argument String is not within bounds of type-variable T`, `inference variable T has incompatible bounds` (with javac's `upper bounds`, `lower bounds` and `equality constraints` lines), `cannot infer type arguments for Box<>`. javac's other errors: `non-static type variable T cannot be referenced from a static context`, `generic array creation`, `unexpected type` for `new T()`, `wrong number of type arguments`, `name clash: … have the same erasure`, `cannot use '<>' with non-generic class`. Every diagnostic that names a type variable ends with javac's `where T is a type-variable:` clause. As javac does, a generic member's value is checked against the type it has where it is used, so `Integer[] a = box.items` fails with the JDK's `ClassCastException` when the array is really an `Object[]`. Raw types of the program's generic classes are supported as the library's are (see *Generic types at use sites*). Generic constructors are unsupported. |
|
|
53
54
|
| Annotations (JLS 9.7) | Supported with limits | `@Override`, `@SuppressWarnings` (a string or an array of them; `"unchecked"` and `"deprecation"` silence those warnings on the class, method, field or local declaration, and `"all"` silences nothing, as in the source launcher), `@FunctionalInterface` (javac's `Unexpected @FunctionalInterface annotation` with its reason), `@SafeVarargs` (javac's `Invalid SafeVarargs annotation` errors) and `@Deprecated` (`since`, `forRemoval`; on a local variable, javac's `[deprecation] … has no effect on this variable declaration` warning), on classes, methods, constructors, fields, parameters and locals. javac's errors: `cannot find symbol` for an unknown annotation, `annotation interface not applicable to this kind of declaration`, `… is not a repeatable annotation interface`, `annotation @SuppressWarnings is missing a default value for the element 'value'`, `incompatible types` for a non-String value. Other annotations (the JDK's, or declared with `@interface`), annotations on types and type arguments, and values other than literals are unsupported. |
|
|
54
55
|
| Warnings | Supported | javac's `[unchecked]` and `[deprecation]` warnings, as the source launcher prints them: before the program's output on a run, among the errors in source order when compilation fails, and counted (`1 warning`, `2 warnings`) after the errors. |
|
|
55
|
-
|
|
|
56
|
+
| Declaring annotation interfaces | Unsupported | |
|
|
56
57
|
|
|
57
58
|
## Types and values
|
|
58
59
|
|
|
@@ -146,7 +147,7 @@ Every feature has one status:
|
|
|
146
147
|
| `Collectors` | Supported with limits | `toList`, `toUnmodifiableList`, `toSet`, `toCollection`, `toMap` (two, three or four arguments; a duplicate key is the JDK's `IllegalStateException: Duplicate key a (attempted merging values 1 and 1)`), `groupingBy` (one, two or three arguments), `partitioningBy` (`{false=..., true=...}`), `counting` (a `Long`), `summingInt`/`Long`/`Double`, `averagingInt`/`Long`/`Double`, `summarizingInt`/`Long`/`Double`, `joining` (with a delimiter, prefix and suffix), `mapping`, `filtering`, `flatMapping`, `collectingAndThen`, `reducing`, `minBy`, `maxBy`, `teeing` (`downstream1`, `merger` NPE messages). Maps are filled as the JDK fills them (`groupingBy` through `computeIfAbsent`, so a `HashMap` prints in the JDK's order). `toUnmodifiableSet`/`Map` and the concurrent collectors are unsupported. Type arguments are inferred as javac infers them in the common forms: `collect(Collectors.toList())`, `groupingBy(w -> w.charAt(0), TreeMap::new, Collectors.counting())`, `collectingAndThen(Collectors.toList(), List::size)`. |
|
|
147
148
|
| `Optional`, `OptionalInt`, `OptionalLong`, `OptionalDouble`, `IntSummaryStatistics` (and `Long`, `Double`) | Supported | `of`, `ofNullable`, `empty`, `get`/`getAsInt`/…, `isPresent`, `isEmpty`, `orElse`, `orElseGet`, `orElseThrow` (with or without a supplier), `ifPresent`, `ifPresentOrElse`, `map`, `flatMap`, `filter`, `or`, `stream`; printed as `Optional[3]`, `Optional.empty`, `OptionalDouble[1.5]`; `NoSuchElementException: No value present`. The statistics' `getCount`, `getSum`, `getMin`, `getMax`, `getAverage`, `accept`, and `IntSummaryStatistics{count=3, sum=80, min=20, average=26.666667, max=30}`. |
|
|
148
149
|
| `BitSet` | Supported | `set`, `clear`, `flip` (one bit or a range, `set(i, boolean)`), `get` (a bit, or a range as a new BitSet), `length`, `size`, `isEmpty`, `cardinality`, `nextSetBit`, `nextClearBit`, `previousSetBit`, `previousClearBit`, `and`, `or`, `xor`, `andNot`, `intersects`, `clone`, `valueOf(long[])`, `toLongArray`, `stream`, `toString` (`{1, 3, 64}`), `equals` and `hashCode` (the JDK's). Its words as the JDK lays them out: `size()` starts at 64 (or the bits asked for, rounded up to 64), grows to twice as many words or what is needed, and `clone()` trims it unless the size came from the constructor. The JDK's messages: `bitIndex < 0: -1`, `fromIndex: 5 > toIndex: 3`, `nbits < 0: -1`. |
|
|
149
|
-
| **`java.time`** (ADRs 0025, 0029) | Supported with limits | `LocalDate` (`of`, `parse`, `ofEpochDay`, `ofYearDay`, `now()` from the browser's clock, the getters, `plus`/`minus` days, weeks, months and years (the day clamped to the month: `2024-01-31` plus a month is `2024-02-29`), `plus(long, TemporalUnit)`, `plus(TemporalAmount)`, `with…`, `atTime`, `atStartOfDay`, `isBefore`/`isAfter`/`isEqual`, `until`, `datesUntil`, `format`, `toString` with the JDK's year signs, `hashCode`, Comparable). `LocalTime` (`of`, `ofSecondOfDay`, `ofNanoOfDay`, `parse`, `now()`, `MIN`/`MAX`/`MIDNIGHT`/`NOON`, the getters, `plus`/`minus` hours to nanoseconds around the clock, `with…`, `truncatedTo`, `until`, `atDate`, `toSecondOfDay`, `toNanoOfDay`, `format`, `toString` as the JDK's: `09:05`, `01:02:03.400`, `01:02:03.000000007`). `LocalDateTime` (`of` with all its overloads, `parse`, `now()`, the date's and the time's getters and `with…`, `plus`/`minus` from years to nanoseconds with the days carried, `until` that leaves out an incomplete last day, `truncatedTo`, `toLocalDate`/`toLocalTime`, `format`, `2024-01-31T22:30`). `Duration` (`of…`, `between` two times or date-times, `parse`, `plus`/`minus`, `multipliedBy`, `dividedBy`, `negated`, `abs`, `truncatedTo`, `to…` and `to…Part`, `PT2H15M` and `PT-1M-29.5S`, long overflow as the JDK's `ArithmeticException`). `Period` (`between` with the JDK's borrow, `of…`, the getters, `normalized`, `multipliedBy`, `P1Y2M3D`), `DayOfWeek` and `Month` (`of`, `getValue`, `plus`, `minus`, `length`), `ChronoUnit` (`between` for any of the three types; a unit a type does not have is the JDK's `UnsupportedTemporalTypeException: Unsupported unit: Hours`), and `DateTimeFormatter` (`ofPattern` with the letters `y u M L d D E H h k K m s S n a` and
|
|
150
|
+
| **`java.time`** (ADRs 0025, 0029, 0032) | Supported with limits | `LocalDate` (`of`, `parse`, `ofEpochDay`, `ofYearDay`, `now()` from the browser's clock, the getters, `plus`/`minus` days, weeks, months and years (the day clamped to the month: `2024-01-31` plus a month is `2024-02-29`), `plus(long, TemporalUnit)`, `plus(TemporalAmount)`, `with…`, `atTime`, `atStartOfDay`, `isBefore`/`isAfter`/`isEqual`, `until`, `datesUntil`, `format`, `toString` with the JDK's year signs, `hashCode`, Comparable). `LocalTime` (`of`, `ofSecondOfDay`, `ofNanoOfDay`, `parse`, `now()`, `MIN`/`MAX`/`MIDNIGHT`/`NOON`, the getters, `plus`/`minus` hours to nanoseconds around the clock, `with…`, `truncatedTo`, `until`, `atDate`, `toSecondOfDay`, `toNanoOfDay`, `format`, `toString` as the JDK's: `09:05`, `01:02:03.400`, `01:02:03.000000007`). `LocalDateTime` (`of` with all its overloads, `parse`, `now()`, the date's and the time's getters and `with…`, `plus`/`minus` from years to nanoseconds with the days carried, `until` that leaves out an incomplete last day, `truncatedTo`, `toLocalDate`/`toLocalTime`, `format`, `2024-01-31T22:30`). `Duration` (`of…`, `between` two times or date-times, `parse`, `plus`/`minus`, `multipliedBy`, `dividedBy`, `negated`, `abs`, `truncatedTo`, `to…` and `to…Part`, `PT2H15M` and `PT-1M-29.5S`, long overflow as the JDK's `ArithmeticException`). `Period` (`between` with the JDK's borrow, `of…`, the getters, `normalized`, `multipliedBy`, `P1Y2M3D`), `DayOfWeek` and `Month` (`of`, `getValue`, `plus`, `minus`, `length`), `ChronoUnit` (`between` for any of the three types; a unit a type does not have is the JDK's `UnsupportedTemporalTypeException: Unsupported unit: Hours`), and `DateTimeFormatter` (`ofPattern` with the letters `y u M L d D E H h k K m s S n a`, quoted text and optional sections (`yyyy-MM-dd[ HH:mm[:ss]]`: printed when the value has their fields, tried and skipped when parsing), `ISO_LOCAL_DATE`, `ISO_LOCAL_TIME`, `ISO_LOCAL_DATE_TIME`). The parameter types are the JDK's interfaces (`Temporal`, `TemporalAmount`, `TemporalUnit`, `TemporalAccessor`), which a program can name. Mixing types works as on the JDK: `Duration.between(time, dateTime)` takes the date-time's time, the other way round is `Unable to obtain LocalDateTime from TemporalAccessor`, and `date.plus(duration)` is `Unsupported unit: Seconds`. Parsing resolves as the JDK's: an `ofPattern` formatter clamps `31/04` to April 30, the ISO ones reject `2024-02-30`, `h` needs `a`; the JDK's `DateTimeException` and `DateTimeParseException` messages, with the cause, and helpful `NullPointerException` messages. A switch on `DayOfWeek`, `Month`, `ChronoUnit` or `RoundingMode` takes their constants as labels. `now()` reads the clock to the millisecond (the JDK's to the microsecond). `Instant` (`ofEpochSecond`, `ofEpochMilli`, `parse`, `now()`, `EPOCH`/`MIN`/`MAX`, `plus`/`minus` up to days, `until`, `truncatedTo`, `atZone`, `toEpochMilli`, `2023-11-14T22:13:20.123Z`). `ZoneId` (`of` with region IDs, offsets and `UTC`/`GMT`/`UT` prefixes, `systemDefault()`, `normalized`, the JDK's `ZoneRulesException: Unknown time-zone ID` and invalid-format messages), `ZoneOffset` (`of` read as the JDK reads it, `ofHours`, `ofHoursMinutes`, `ofHoursMinutesSeconds`, `ofTotalSeconds`, `UTC`/`MIN`/`MAX`, the JDK's range and sign messages) and `ZonedDateTime` (`of`, `ofInstant`, `parse`, `now`, the getters, `withZoneSameInstant`/`withZoneSameLocal`, `withEarlierOffsetAtOverlap`/`withLaterOffsetAtOverlap`, `withFixedOffsetZone`, `plus`/`minus` with dates local and times on the instant, `until`, `truncatedTo`, `toInstant`, `toEpochSecond`, `2024-03-10T03:30-04:00[America/New_York]`). A zone's rules are the browser's (`Intl`): a daylight saving gap moves the time forward and an overlap keeps the earlier offset, as on the JDK; the browser's time zone data can be a different version from the JDK's. `LocalDateTime.atZone`, `toInstant(ZoneOffset)`, `toEpochSecond(ZoneOffset)`, `ofInstant`, `ofEpochSecond`, `LocalDate.atStartOfDay(ZoneId)`, `now(ZoneId)` and `from` on each type. The formatter's zone letters `VV`, `X`, `x` and `Z`, and `ISO_OFFSET_DATE_TIME`, `ISO_ZONED_DATE_TIME` and `ISO_INSTANT`. `ZoneRules` (`getRules()`), `OffsetDateTime` and `OffsetTime` (they exist only so that `date.atTime(null)` is ambiguous, as in javac), `Clock`, the localized letters `O`, `z`, `v` and `ZZZZ`, other pattern letters, `getDisplayName` and printing a formatter are unsupported or engine limitations, as is a parse whose JDK message lists fields it could not resolve (the JDK's order of them changes from run to run). |
|
|
150
151
|
| `EnumMap`, `EnumSet` | Supported | An enum's constants in ordinal order. `EnumMap(Class)`, `(EnumMap)`, `(Map)` (an empty non-EnumMap is `IllegalArgumentException: Specified map is empty`), with every `Map` method; a null key is the JDK's NPE on `put` and simply absent on `get`, `containsKey` and `remove`. `EnumSet.noneOf`, `allOf`, `of` (one to five constants, or varargs), `range` (`C > A` when reversed), `complementOf`, `copyOf` (`Collection is empty`), `clone`, with every `Set` method plus `removeAll` and `retainAll`; its iterator walks a snapshot, so removing while iterating never fails, as on the JDK. `getClass()` is `java.util.EnumMap` and `java.util.RegularEnumSet` (`JumboEnumSet` above 64 constants). |
|
|
151
152
|
| `java.math.BigInteger` | Supported | `ZERO`, `ONE`, `TWO`, `TEN`, `valueOf` (sharing -16..16 as the JDK does, so `valueOf(1) == ONE`), `new BigInteger(String[, radix])` with the JDK's messages (`Zero length BigInteger`, `For input string: "x10"` naming the failing digit group, `Radix out of range`, `Illegal embedded sign character`); `add`, `subtract`, `multiply`, `divide`, `remainder`, `mod`, `divideAndRemainder`, `pow`, `modPow`, `modInverse`, `gcd`, `abs`, `negate`, `signum`, `sqrt`, `min`, `max`, `compareTo`, `equals`, `hashCode` (the JDK's), `toString` (any radix), the `…Value` and `…ValueExact` conversions, bit operations (`shiftLeft`, `and`, `testBit`, `bitLength`, `bitCount`, …), `isProbablePrime`, `nextProbablePrime`, with the JDK's `ArithmeticException` messages. `%d`, `%x` and `%o` format it (signed: `-ff`). Comparable, so it sorts and keys TreeMaps; content-equal in HashMaps. Non-ASCII digits are an engine limitation; `probablePrime` and `toByteArray` are unsupported. |
|
|
152
153
|
| `java.math.BigDecimal`, `RoundingMode`, `MathContext` | Supported | A BigInteger unscaled value and a scale, as the JDK's: `new BigDecimal(String)` (with its messages), `(double)` (the double's exact value: `0.1000000000000000055511151231257827021181583404541015625`), `(int)`, `(long)`, `(BigInteger[, scale])`, `valueOf(double)` (via `Double.toString`), `valueOf(long[, scale])` (sharing 0..10 as the JDK does); `add`, `subtract`, `multiply` (scale rules as documented), `divide` exact (the preferred scale, or the smallest that holds the quotient: `5 / 0.25` is `2E+1`; `Non-terminating decimal expansion; no exact representable decimal result.`), with a scale and `RoundingMode`, or a `MathContext`; `divideToIntegralValue`, `remainder`, `setScale` (`Rounding necessary`), `round`, `sqrt`, `pow`, `movePointLeft`/`Right`, `scaleByPowerOfTen`, `stripTrailingZeros`, `precision`, `unscaledValue`, `compareTo` (by value) and `equals` (value and scale: `1.10` is not `1.1`), `hashCode` (the JDK's), `toString` (scientific when the JDK's is: `1E+2`, `1.234E-7`), `toPlainString`, the conversions. All eight `RoundingMode`s (`values()`, `valueOf`, `name`, `ordinal`) and `MathContext` (`DECIMAL32`, `DECIMAL64`, `DECIMAL128`, `UNLIMITED`, its constructors). `%f`, `%e` and `%g` format a BigDecimal from its exact digits. Scanner's `nextBigInteger` and `nextBigDecimal` read them. The `MathContext` forms of `add` and the other arithmetic, `ulp` and `toEngineeringString` are unsupported. |
|
|
@@ -184,7 +185,7 @@ These all use javac's wording and caret positions, as evidenced by `tests/jdk-ca
|
|
|
184
185
|
- `non-static … cannot be referenced from a static context`
|
|
185
186
|
- `… has private access in …`
|
|
186
187
|
- `invalid method declaration; return type required`, `modifier static not allowed here`, `explicit constructor invocation may only appear within a constructor body`
|
|
187
|
-
- **Method and constructor calls
|
|
188
|
+
- **Method and constructor calls** (0.37.0 brought javac's longer forms, ADR 0031: a generic owner with its type variables, `method put in interface Map<K,V>`, and its `where` lines; a generic library candidate as declared, `Collections.<T#1>sort(List<T#1>)`, with javac's inference reasons and numbered type variables; a lambda argument whose body does not fit, reported as the call's argument mismatch; a diamond that cannot be inferred, `cannot infer type arguments for Pair<>`; a wildcard receiver captured, `List.add(CAP#1)`; every JDK overload a call could mean, listed in the JDK's order):
|
|
188
189
|
- `method f in class Main cannot be applied to given types;` with `required`/`found`/`reason` (and the same for constructors)
|
|
189
190
|
- `no suitable method found for …` / `no suitable constructor found for …`, with every candidate and why it does not apply
|
|
190
191
|
- `reference to f is ambiguous`
|
|
@@ -192,7 +193,7 @@ These all use javac's wording and caret positions, as evidenced by `tests/jdk-ca
|
|
|
192
193
|
- **Reachability (JLS 14.22):** after `return`/`break`/`continue`, after loops that cannot exit, and for a `while (false)` or `for (; false; )` body. `if (false)` is allowed.
|
|
193
194
|
- **`missing return statement`**
|
|
194
195
|
- **Error order:** one top-level class at a time, in source order: its attribution errors (nested classes where they are declared), then reachability, then definite assignment, with nested classes first. **Once any error has been reported, flow analysis does not run**, exactly as in javac, so a type error hides a missing return in the same file, and so does an error in an earlier class.
|
|
195
|
-
- **Syntax, lexical, and number-literal errors:** as in 0.1.0.
|
|
196
|
+
- **Syntax, lexical, and number-literal errors:** as in 0.1.0, and since 0.35.0 every one of them, as javac's recovery finds them (ADR 0030): a missing `;`, `)`, `]`, `}` or `>` is reported and taken as there; an expression or statement that cannot be read is reported and skipped to the next statement; a cascade from one mistake is not reported; a lexical error (`"hi;`, `'ab'`, `#`) is reported where the parse reaches it, and silences what follows from it. With a syntax error in the file, as with javac, no other kind of error is reported. At most 100 errors are shown, with javac's `only showing the first 100 errors` line.
|
|
196
197
|
|
|
197
198
|
**Output format:** the same as `java Main.java`. **Warnings:** none (JDK 25 source-file mode prints none for these programs either).
|
|
198
199
|
|
|
@@ -228,10 +229,9 @@ These all use javac's wording and caret positions, as evidenced by `tests/jdk-ca
|
|
|
228
229
|
| Case | JDK 25 | Engine | How the tests compare it |
|
|
229
230
|
| --- | --- | --- | --- |
|
|
230
231
|
| Exceptions thrown inside the JDK (`charAt` out of range, `println` of a null `char[]`, any library method), inside a `toString()` called by `println`, `+` or a collection, or during class initialization or instance creation; and every trace `printStackTrace()` prints | The program's frames plus the JDK's own frames (`at java.base/…` such as `String.valueOf`, the source launcher's five frames below `main`, `at jdk.compiler/…`) | Same messages and program frames, without the JDK's frames. `... N more` counts the launcher's frames, so it is the JDK's number | Identical once the JDK's frames are removed |
|
|
231
|
-
| `no suitable method found for sort(...)` with a generic `Arrays.sort` candidate |
|
|
232
|
+
| `no suitable method found for sort(...)` with a generic `Arrays.sort` candidate given an array of arrays or a lambda it cannot type | Inference details such as `upper bounds: int[],Object` | The candidates as javac lists them (`Arrays.<T#1>sort(T#1[],…)`, its `where` clause), with a narrower reason for those | Each error's header, source line and caret identical |
|
|
232
233
|
| `StackOverflowError` trace length | Capped at 1024 frames; 1019 were printed in the recorded case | 1024 frames | First lines identical |
|
|
233
|
-
|
|
|
234
|
-
| Several syntax errors in one file | javac may report several | The engine stops at the first | (by design, ADR 0001) |
|
|
234
|
+
| Several syntax errors in one file, lexical ones among them | Every one javac's recovery finds | The same errors in nearly every case: the engine recovers as javac does (ADR 0030; 87 recorded cases of beginners' mistakes). Where its recovery takes another path, the first error is still javac's, and later ones may differ (`void static() { }`; an unclosed text block whose `\"""` hides its end) | Identical for the recorded cases; first diagnostic for the one text block case |
|
|
235
235
|
| Printing an array or an object without `toString()` (`[I@5fdba6f9`, `Node@6dde5c8c`), or `hashCode()` | Random identity hash | Deterministic per-run hash with the same format | Format checked by unit tests |
|
|
236
236
|
| `Math.sin`, `exp`, `pow`, `log` and the other transcendental functions | Results of the platform's math library | JavaScript's; about 3% of probed values differed in the last digit (accepted by the owner, 2026-10-18) | The recorded cases print them with `printf("%.12f")`; unit tests allow a few ulps. Java permits this: `Math`, unlike `StrictMath`, need not be reproducible across platforms |
|
|
237
237
|
| Unseeded `new Random()`, `Math.random()`, `System.currentTimeMillis()`, `nanoTime()`, `identityHashCode` | Differ on every run | Differ on every run (identity hashes are per-run, as above) | Ranges checked by unit tests |
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ entirely in the reader's browser. No backend, no iframe, no sign-up.
|
|
|
9
9
|
**[Live demo →](https://code-playpad.swengr.com)**
|
|
10
10
|
|
|
11
11
|
```html
|
|
12
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.
|
|
12
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.9.0/dist/standalone.js"></script>
|
|
13
13
|
|
|
14
14
|
<code-playpad height="auto">
|
|
15
15
|
print("hello from a static page")
|
|
@@ -159,6 +159,20 @@ under a second. The engine stops a runaway program after 200 million steps
|
|
|
159
159
|
the evidence behind it and every known difference from the JDK, is in
|
|
160
160
|
[JAVA-COMPATIBILITY.md](https://cdn.jsdelivr.net/npm/code-playpad/JAVA-COMPATIBILITY.md), which ships in the package.
|
|
161
161
|
|
|
162
|
+
## Experimental C/C++
|
|
163
|
+
|
|
164
|
+
`language="c"` (C17) and `language="cpp"` (C++20) compile and run in a worker
|
|
165
|
+
with a real Clang compiler, prefilled stdin and Stop. They are experimental:
|
|
166
|
+
|
|
167
|
+
- **You host the compiler.** It is not in the npm package and there is no
|
|
168
|
+
hosted copy yet. Build the pinned toolchain from this repository, host it,
|
|
169
|
+
and call `configureCpp({ indexURL })`. Without that, Run explains what is
|
|
170
|
+
missing and downloads nothing.
|
|
171
|
+
- **Not yet tested on physical phones.** Desktop Chromium, WebKit and Firefox
|
|
172
|
+
pass; iPhone Safari and Android Chrome have not been run.
|
|
173
|
+
|
|
174
|
+
See [setup and limits](https://github.com/stancs/code-playpad/blob/main/docs/COMPILER-RUNTIMES.md).
|
|
175
|
+
|
|
162
176
|
## Download size
|
|
163
177
|
|
|
164
178
|
What a page downloads once a reader presses Run, with the CDN build, as
|
|
@@ -171,33 +185,46 @@ actually sent.
|
|
|
171
185
|
| Python | **166.3 KB** | Pyodide, about **6.0 MB** (a 3.3 MB wasm file and a 2.4 MB standard library) | 165.8 KB |
|
|
172
186
|
| JavaScript | **180.4 KB** | nothing | 179.9 KB |
|
|
173
187
|
| TypeScript | **227.3 KB** (0.5.2: with the 46.9 KB transform) | nothing (before 0.5.2: Sucrase from esm.sh, 72 KB) | 179.9 KB |
|
|
174
|
-
| Java | **
|
|
175
|
-
| Java, with collections | **
|
|
176
|
-
|
|
|
188
|
+
| Java | **288.1 KB** (0.8.0: engine 0.39) | nothing | 216.4 KB |
|
|
189
|
+
| Java, with collections | **373.1 KB** (0.8.0) | nothing | 233.2 KB |
|
|
190
|
+
| C or C++ (experimental) | **187.0 KB** | the compiler, about **29.9 MB**, from the host you configure | — |
|
|
191
|
+
| All five | 520.0 KB | Pyodide and the C/C++ compiler | 273.9 KB |
|
|
177
192
|
|
|
178
193
|
- **Every row includes a 144.5 KB shared base:** the editor (CodeMirror) and
|
|
179
194
|
the widget, the same as in 0.3.0.
|
|
180
195
|
- **Each language adds:**
|
|
181
196
|
- Python: 21.7 KB.
|
|
182
197
|
- JavaScript/TypeScript: 35.9 KB.
|
|
183
|
-
- Java:
|
|
198
|
+
- Java: 143.5 KB (the 124.5 KB engine plus 19 KB of Java syntax
|
|
184
199
|
highlighting).
|
|
185
200
|
- The first Java program that uses collections, `StringBuilder` or another
|
|
186
|
-
library class also adds the
|
|
201
|
+
library class also adds the 85.0 KB Java library, once per page.
|
|
187
202
|
- Since 0.7.0, four parts of the library load only for the first program
|
|
188
|
-
that uses them: `java.time`
|
|
203
|
+
that uses them: `java.time` 16.8 KB, `java.math` 6.7 KB,
|
|
189
204
|
`Pattern`/`Matcher` 2.7 KB and `BitSet` 2.3 KB. The rows above leave
|
|
190
205
|
them out.
|
|
191
|
-
-
|
|
206
|
+
- C/C++: 42.5 KB (the 7.9 KB runtime plus 34.6 KB of C/C++ syntax
|
|
207
|
+
highlighting). See the C/C++ note below.
|
|
208
|
+
- The Java figures for 0.8.0 are the 0.4.0 measurements plus what the
|
|
192
209
|
engine's two chunks changed by in the build's gzip sizes (engines 0.28
|
|
193
|
-
to 0.
|
|
194
|
-
APIs, regex, java.time
|
|
195
|
-
of the library).
|
|
210
|
+
to 0.39 added the collection staples, library subclasses, the tutorial
|
|
211
|
+
APIs, regex, java.time, javac's error recovery and messages, packages
|
|
212
|
+
and more; 0.32 moved the rarely used classes out of the library).
|
|
213
|
+
- **C and C++ (experimental)** were measured on 2026-10-29 as
|
|
214
|
+
the difference between pages with and without C/C++. Measured that day,
|
|
215
|
+
whole pages come out 4–8 KB larger than this table, with or without the
|
|
216
|
+
C/C++ code, so the C/C++ and All five rows add the measured 42.5 KB to this
|
|
217
|
+
table's figures. The compiler is the large part: Clang 15.2 MB, the linker 8.8 MB,
|
|
218
|
+
and headers and libraries 5.9 MB, gzipped as a host would typically send
|
|
219
|
+
them. It downloads on the first Run, from the address given to
|
|
220
|
+
`configureCpp` (you host it), and is cached after that. C and C++ share it, so a page
|
|
221
|
+
with both downloads it once. 0.3.0 had no C/C++, so its All five figure is
|
|
222
|
+
its four-language page.
|
|
196
223
|
- **Java grew** from 0.3.0 because the subset did, from basic Java to most of
|
|
197
224
|
what practice programs use (see the version history). The owner treats
|
|
198
225
|
download size as secondary to coverage. The package's size checks still
|
|
199
226
|
catch accidental growth: 128 KiB for the Java chunk, 96 KiB for its
|
|
200
|
-
library and
|
|
227
|
+
library and 24 KiB for each part of it.
|
|
201
228
|
- **Languages load lazily.** A Java page never fetches the Python or
|
|
202
229
|
JavaScript runtimes, and Python and JavaScript pages never fetch Java. As a
|
|
203
230
|
result, Python-only and JavaScript-only pages are the same size as in 0.3.0.
|
|
@@ -217,7 +244,7 @@ actually sent.
|
|
|
217
244
|
### From a CDN — nothing to install
|
|
218
245
|
|
|
219
246
|
```html
|
|
220
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.
|
|
247
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.9.0/dist/standalone.js"></script>
|
|
221
248
|
```
|
|
222
249
|
|
|
223
250
|
This is the `standalone` build: CodeMirror is bundled in, so a static blog post
|
|
@@ -848,7 +875,64 @@ warms every other page on the site.
|
|
|
848
875
|
|
|
849
876
|
## Version history
|
|
850
877
|
|
|
851
|
-
|
|
878
|
+
### 0.9.0
|
|
879
|
+
|
|
880
|
+
Adds experimental C and C++. Nothing else changed: Python, JavaScript,
|
|
881
|
+
TypeScript and Java behave as in 0.8.0, and existing pages grow by about
|
|
882
|
+
0.5 KB.
|
|
883
|
+
|
|
884
|
+
- **`language="c"` and `language="cpp"`** (C17 and C++20) compile with Clang 20
|
|
885
|
+
and link with LLD, compiled to WebAssembly, in a worker. Multiple files,
|
|
886
|
+
prefilled stdin, Stop, a wall-clock limit and streamed output all work.
|
|
887
|
+
Programs get stdin, stdout and stderr only; exceptions and threads are not
|
|
888
|
+
supported, and live interactive stdin is not implemented.
|
|
889
|
+
- **`configureCpp({ indexURL })` is required.** The compiler (about 29.9 MB
|
|
890
|
+
gzipped) is not in this package and has no hosted copy yet, so you build and
|
|
891
|
+
host it yourself. Its files are checked by SHA-256 and cached after the first
|
|
892
|
+
Run. Without the setting, Run explains what is missing and downloads nothing.
|
|
893
|
+
- **Tested on desktop only:** Chromium, WebKit and Firefox. Physical iPhone and
|
|
894
|
+
Android runs have not been done.
|
|
895
|
+
- **`RunOptions`** gains `onProgress` and `timeoutMs`, and `Result` gains
|
|
896
|
+
`memory`.
|
|
897
|
+
- **New optional peer dependency:** `@codemirror/lang-cpp`, for highlighting
|
|
898
|
+
with a bundler.
|
|
899
|
+
|
|
900
|
+
### 0.8.0
|
|
901
|
+
|
|
902
|
+
Java engine 0.34.1 → 0.39.0, each change checked against JDK 25. Nothing
|
|
903
|
+
else changed: Python, JavaScript and TypeScript, the element's API and its
|
|
904
|
+
markup are as in 0.7.0. One Java behavior a page may notice: a file in a
|
|
905
|
+
folder (`util/Tool.java`) used to be reported as unsupported; it is now a
|
|
906
|
+
class of that folder's package, as on the JDK.
|
|
907
|
+
|
|
908
|
+
- **Every syntax error, as javac reports them.** A program with two missing
|
|
909
|
+
semicolons now shows both errors, not just the first, with javac's
|
|
910
|
+
wording and carets; a mistake that confuses the parser does not produce a
|
|
911
|
+
cascade of errors javac would not show. Unclosed string and character
|
|
912
|
+
literals no longer hide the syntax errors after them.
|
|
913
|
+
- **Optional sections in date patterns.** `DateTimeFormatter.ofPattern`
|
|
914
|
+
takes `[...]` sections (`yyyy-MM-dd[ HH:mm[:ss]]`), as the JDK does, and
|
|
915
|
+
`date.atTime(null)` is javac's ambiguity error.
|
|
916
|
+
- **javac's longer error messages.** A call that does not fit names the
|
|
917
|
+
method's owner and its type variables as javac does (`method put in
|
|
918
|
+
interface Map<K,V>`), candidate lists show generic methods as declared
|
|
919
|
+
(`Collections.<T#1>sort(List<T#1>)`) and every JDK overload, and a lambda
|
|
920
|
+
whose body does not fit is reported as the call's mismatch. Calls javac
|
|
921
|
+
rejects but the engine ran, such as `add(1)` on a
|
|
922
|
+
`List<? extends Number>`, are now errors.
|
|
923
|
+
- **Instants and time zones.** `Instant`, `ZoneId`, `ZoneOffset` and
|
|
924
|
+
`ZonedDateTime`, with the browser's time zone rules and the JDK's handling
|
|
925
|
+
of daylight saving gaps and overlaps
|
|
926
|
+
(`2024-03-10T03:30-04:00[America/New_York]`), the formatter's zone letters
|
|
927
|
+
(`VV`, `X`, `x`, `Z`) and the ISO offset, zoned and instant formats.
|
|
928
|
+
- **Packages.** Java files in folders: `util/Tool.java` declares
|
|
929
|
+
`package util;`, and files in other folders import it, with javac's
|
|
930
|
+
import rules and its errors for access across packages. A helper file that
|
|
931
|
+
the launch file needs only for its declarations is compiled when its class
|
|
932
|
+
first loads, as the JDK's launcher does, so its errors appear at that
|
|
933
|
+
point in the run.
|
|
934
|
+
|
|
935
|
+
Markup and API written against 0.1.3 still work on 0.9.0, with one exception, in
|
|
852
936
|
0.5.1: an `entry` that names none of a widget's files is now an error.
|
|
853
937
|
|
|
854
938
|
### 0.7.0
|
|
@@ -1148,6 +1232,12 @@ their own MIT licences, reproduced in full in `dist/THIRD-PARTY-NOTICES.txt`.
|
|
|
1148
1232
|
Pyodide (MPL-2.0) is fetched from a CDN at runtime and is not redistributed by
|
|
1149
1233
|
this package.
|
|
1150
1234
|
|
|
1235
|
+
Experimental C/C++ downloads separate compiler assets with additional
|
|
1236
|
+
third-party terms; those assets are not MIT-only. Their notices ship in
|
|
1237
|
+
`dist/COMPILER-NOTICES.txt`. The pinned C/C++ rebuild passes its scoped license
|
|
1238
|
+
inventory gate; see the [compiler license audit](docs/COMPILER-LICENSE-AUDIT.md)
|
|
1239
|
+
and [rebuild and remaining gates](docs/CPP-REBUILD.md).
|
|
1240
|
+
|
|
1151
1241
|
The Java engine is original code under the same MIT licence. Java is a trademark
|
|
1152
1242
|
of Oracle and/or its affiliates; code-playpad is not affiliated with, endorsed
|
|
1153
1243
|
by, or certified by Oracle, and its Java support is a documented subset, not a
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Compiler license audit — 2026-10-27
|
|
2
|
+
|
|
3
|
+
**Disposition: the project's own code remains MIT. The license inventory gate
|
|
4
|
+
passes for the pinned rebuilt C/C++ artifact set and its notice companions.**
|
|
5
|
+
Release still needs the owner's approval. The old browsercc
|
|
6
|
+
binary set is superseded, not retroactively cleared. See [CPP-REBUILD.md](CPP-REBUILD.md)
|
|
7
|
+
for exact scope, build evidence and remaining non-license release gates.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## What is cleared and what was added
|
|
11
|
+
|
|
12
|
+
The bundled integration uses `@bjorn3/browser_wasi_shim` 0.4.2 under its MIT option
|
|
13
|
+
and adapts the MIT Weblings worker protocol/sysroot format at
|
|
14
|
+
`d0cd7a9f3af7d8249b3948ac0e19d2afc0d01633`. Their full notices already reside in
|
|
15
|
+
`dist/THIRD-PARTY-NOTICES.txt`; the distribution check now verifies both the names
|
|
16
|
+
and complete text. The CodeMirror C++ grammar retains its MIT notice too.
|
|
17
|
+
The project's LICENSE is unchanged. No compiler binaries are committed or packed.
|
|
18
|
+
|
|
19
|
+
Added a separate `third-party/compiler/manifest.json` and source notice corpus.
|
|
20
|
+
Each snapshot records its immutable source URL and SHA-256. The build emits
|
|
21
|
+
`dist/COMPILER-NOTICES.txt`, this audit, and `compiler-license-manifest.json` so
|
|
22
|
+
npm consumers receive the findings and available external notices. The local
|
|
23
|
+
asset-preparation script also copies these companions beside each toolchain.
|
|
24
|
+
The rebuilt C/C++ additions resolve its scoped inventory gaps.
|
|
25
|
+
|
|
26
|
+
`npm run check:compiler-licenses` verifies notice hashes. Adding `-- --release`
|
|
27
|
+
fails until the owner sets `releaseApproved`. Use `-- --release --toolchain=cpp`
|
|
28
|
+
for the rebuilt C/C++ license gate, which passes. This is an explicit
|
|
29
|
+
compiler release gate, not a claim that a normal build is approved for release.
|
|
30
|
+
|
|
31
|
+
## Historical browsercc C/C++ findings (superseded by the pinned rebuild)
|
|
32
|
+
|
|
33
|
+
The reviewed npm archive is browsercc 0.1.1, source
|
|
34
|
+
`86168bacf0fe7c662e3e65a2e3006ceb159cd0dc`; exact asset hashes are recorded in
|
|
35
|
+
`src/runtime/cpp/assets.ts` and the audit manifest. The wrapper's MIT LICENSE
|
|
36
|
+
has no explicit copyright-holder line; it is preserved verbatim. Package metadata
|
|
37
|
+
names Daniel Bertalan as author; no invented copyright line was added.
|
|
38
|
+
|
|
39
|
+
The recipe builds Clang/LLD from LLVM 20.1.2 (`58df0ef89dd64126512e4ee27b4ac3fd8ddf6247`).
|
|
40
|
+
It obtains libc++, libc++abi and compiler builtins from WASI SDK 25's LLVM revision
|
|
41
|
+
`ab4b5a2db582958af1ee308a790cfdb42bd24720`, and wasi-libc revision
|
|
42
|
+
`574b88da481569b65a237cb80daf9a2d5aeaf82d`. These are distinct LLVM inputs.
|
|
43
|
+
Their primary license texts are retained, including LLVM exceptions and legacy
|
|
44
|
+
NCSA terms. wasi-libc's umbrella references Apache/LLVM, Apache, MIT, cloudlibc
|
|
45
|
+
BSD-2-Clause, musl MIT, musl-fts BSD-3-Clause and allocator notices; these referenced
|
|
46
|
+
texts and allocator attribution headers are included.
|
|
47
|
+
|
|
48
|
+
The recipe explicitly removes sysroot `share/` and VERSION (share/ was later
|
|
49
|
+
confirmed to contain symbol/configuration data, not a standalone license bundle),
|
|
50
|
+
and the distributed
|
|
51
|
+
sysroot contains no standalone license/copyright files. It also selects Emscripten
|
|
52
|
+
`latest`, with no immutable SDK revision or complete linked-host-library list.
|
|
53
|
+
The compiler Wasm files contain no producer/custom metadata that resolves that
|
|
54
|
+
version. Root LLVM notices explicitly defer to component/file-level third-party
|
|
55
|
+
terms; copying only the root license is not a complete compiler notice bundle.
|
|
56
|
+
|
|
57
|
+
**Historical C/C++ blockers (resolved by replacement):** obtain upstream provenance plus a complete notice/SBOM bundle,
|
|
58
|
+
or rebuild from pinned LLVM, Emscripten and WASI inputs while preserving notices.
|
|
59
|
+
Account for Emscripten glue, linked libc/libc++/allocator code, and LLVM's included
|
|
60
|
+
third-party code. Compare any replacement hashes and rerun browser/size tests.
|
|
61
|
+
The current CDN pointer does not make the missing attribution irrelevant.
|
|
62
|
+
|
|
63
|
+
## Rust (removed 2026-10-29)
|
|
64
|
+
|
|
65
|
+
An experimental Rust runtime was removed before release. Its compiler came
|
|
66
|
+
from a fork whose custom backend commits carry no license of their own, so no
|
|
67
|
+
license review could clear it. The owner chose not to seek one; any future Rust
|
|
68
|
+
runtime would replace those commits with project-authored code. Its audit, notice
|
|
69
|
+
corpus and evidence remain in git history on branch `codex/c-cpp-runtime`.
|
|
70
|
+
|
|
71
|
+
## Distribution and generated user programs
|
|
72
|
+
|
|
73
|
+
Retain upstream copyright/license texts and applicable NOTICE files; identify
|
|
74
|
+
modified upstream files where required by their licenses. Our separately authored
|
|
75
|
+
integration remains MIT. Upstream recipe modifications (sysroot rearrangement,
|
|
76
|
+
added bits/stdc++.h and stripped sections) are not our original authorship and need provenance in any replacement distribution.
|
|
77
|
+
|
|
78
|
+
Compiling a user's program does not by itself relicense its original source.
|
|
79
|
+
Linked libc/libc++ and other runtime code have their own terms. LLVM's
|
|
80
|
+
exception is relevant to embedded object code, not a blanket exemption for
|
|
81
|
+
redistributing the compiler, unrelated libraries or all generated programs.
|
|
82
|
+
Don't tell downstream users that every output is automatically MIT or obligation-free.
|
|
83
|
+
|
|
84
|
+
## Release checklist / owner actions
|
|
85
|
+
|
|
86
|
+
1. Keep C/C++ scoped to the rebuilt, verified hashes and notice companions.
|
|
87
|
+
2. Publish complete, immutable compiler distributions with companion notices;
|
|
88
|
+
test the actual CDN compression, CORS and notice URLs. Current transfers are
|
|
89
|
+
measured with a local gzip mirror, not verified production hosting.
|
|
90
|
+
3. Complete physical iPhone Safari and Android Chrome memory/lifecycle/cache
|
|
91
|
+
testing. Desktop Chromium, WebKit and Firefox pass 22 checks each.
|
|
92
|
+
4. Run the packed React/bundler/CSP checks, and decide interactive-input scope.
|
|
93
|
+
See compiler-validation.md for the detailed non-license gates.
|
|
94
|
+
|
|
95
|
+
Sources: immutable URLs for every retained text are in the manifest; the build
|
|
96
|
+
recipe is [browsercc](https://github.com/BertalanD/browsercc/blob/86168bacf0fe7c662e3e65a2e3006ceb159cd0dc/build.sh),
|
|
97
|
+
superseded by the pinned rebuild in `toolchains/cpp/`.
|
|
98
|
+
|
|
99
|
+
Validation: notice hashes, 77 tests, typecheck, build and distribution checks pass.
|
|
100
|
+
The npm dry-run (2026-10-29, after Rust's removal) contains all three audit
|
|
101
|
+
companions (932,733 bytes compressed, 77 files). Local asset preparation copies
|
|
102
|
+
them beside the toolchain. The combined release check fails until the owner
|
|
103
|
+
approves release; the rebuilt C/C++ check passes; successful packaging is not
|
|
104
|
+
release clearance.
|