Releases: ponylang/ponyc
0.51.0
Update glibc Linux Docker base image
Previously our glibc Linux Docker images where based on Ubuntu 20.04. They've been updated to use Ubuntu 22.04.
Update to LLVM 14.0.3
We've updated the LLVM used to build Pony to 14.0.3.
Don't include debug information in release versions of ponyc
At some point in the past, we turned on an option PONY_ALWAYS_ASSERT when building ponyc and the runtime. The result of this option was to not only turn on all debug assertions, but also, turn on almost all debug code in the runtime and the ponyc compiler.
The inclusion of assertions was great for error reports from users for compiler bugs. However, it was also including code that would make the compiler slower and use more memory. It was also including code that made the runtime slower for all compiled Pony programs.
We've turned off PONY_ALWAYS_ASSERT. Programs will be somewhat faster, the compiler will be a little faster, and the compiler will use a little less memory. In return, if you report a compiler bug, we'll definitely need a minimal reproduction to have any idea what is causing your bug.
Add prebuilt ponyc binaries for MacOS on Apple Silicon
We've added prebuilt ponyc binaries specifically made to work MacOS Monterey on Apple Silicon. You can install them with ponyup that is now also available for MacOS on Apple Silicon.
Disable incorrect runtime assert for ASIO thread shutdown.
In a rare race condition, a runtime assertion failure related to destruction of the runtime ASIO thread's message queue could be observed during program termination, causing a program crash instead of graceful termination.
This change removes the invalid runtime assertion for that case, because the invariant it was meant to ensure does not apply or hold for the specific case of terminating the runtime ASIO thread, even though it still holds and is still being tested for the more common case of individual actor terminator.
[0.51.0] - 2022-05-29
Fixed
- Disable incorrect runtime assert for ASIO thread shutdown. (PR #4122)
Added
- Add prebuilt ponyc releases on MacOS for Apple Silicon (PR #4119)
Changed
0.50.0
Fix compiler crash with exhaustive match in generics
Previously, there was an interesting edge case in our handling of exhaustive match with generics that could result in a compiler crash. It's been fixed.
Fixed parameter names not being checked
In 2018, when we removed case functions from Pony, we also removed the checking to make sure that parameters names were valid.
We've added checking of parameter names to make sure they match the naming rules for parameters in Pony.
Fixed bug that caused the compiler to crash
We've fixed a bug that caused a compiler crash.
Allow overriding the return type of FFI functions
With the approval of RFC 68, we made FFI declarations mandatory, and with that, also removed the ability to separately specify a return type for an FFI function at the call site, like so:
use @printf[I32](fmt: Pointer[U8] tag, ...)
actor Main
new create(env: Env) =>
@printf[I32]("Hello, world!\n".cstring())
Since the return type at the call site needed to match the return type of the declaration, we removed this syntax on the grounds of it being redundant.
That change, however, made it impossible to write safe bindings for type-generic C functions, which might return different types depending on how they are used. Let's imagine an example with a generic list:
struct List;
struct List* list_create();
void list_free(struct List* list);
void list_push(struct List* list, void *data);
void* list_pop(struct List* list);
We want to use this API from Pony to store our own Point2D
struct types. We can write the declarations as follows:
use @list_create[Pointer[_List]]()
use @list_free[None](list: Pointer[_List])
use @list_push[None](list: Pointer[_List], data: Point)
use @list_pop[NullablePointer[Point]](list: Pointer[_List])
primitive _List
struct Point2D
var x: U64 = 0
var y: U64 = 0
The problem with these declarations is that the list_push
and list_pop
functions can only operate with lists of elements of type Point2D
. If we wanted to use these functions with different types, we would modify list_push
to take an element of type Pointer[None]
, which represents the void*
type. Until now, however, there was no way of making list_pop
truly generic:
use @list_push[None](list: Pointer[_List], data: Pointer[None])
use @list_pop[Pointer[None]](list: Pointer[_List])
// OK
let point_list = @list_create()
@list_push(list, NullablePointer[Point2D].create(Point2D))
// OK
let string_list = @list_create()
@list_push(string_list, "some data".cstring())
// Compiler error: couldn't find 'x' in 'Pointer'
let point_x = @list_pop(point_list)
point.x
// Compiler error: wanted Pointer[U8 val] ref^, got Pointer[None val] ref
let head = String.from_cstring(@list_pop(string_list))
With this release, one can make list_pop
generic by specifying its return type when calling it:
use @list_pop[Pointer[None]](list: Pointer[_List])
// OK
let point_x = @list_pop[Point](point_list)
point.x
// OK
let head = String.from_cstring(@list_pop[Pointer[U8]](string_list))
Note that the declaration for list_pop
is still needed. The return type of an FFI function call without an explicit return type will default to the return type of its declaration.
When specifying a different return type for an FFI function, make sure that the new type is compatible with the type specified in the declaration. Two types are compatible with each other if they have the same ABI size and they can be safely cast to each other. Currently, the compiler allows the following type casts:
- Any struct type can be cast to any other struct.
- Pointers and integers can be cast to each other.
Specifying an incompatible type will result in a compile-time error
Don't allow FFI calls in default methods or behaviors
In Pony, when you use
an external library, you import the public types defined by that library. An exception to this rule is FFI declarations: any FFI declarations in a library will not be visible by external users. Given that the compiler only allows a single FFI declaration per package for any given function, if external FFI declarations were imported, deciding which declaration to use would be ambiguous.
When added to the fact that every FFI function must have a matching declaration, a consequence of not importing external declarations is that if a library contains a public interface or trait with default methods (or behaviors), performing an FFI call on those methods will render them unusable to external consumers.
Consider the following code:
// src/lib/lib.pony
use @printf[I32](fmt: Pointer[None] tag, ...)
trait Foo
fun apply() =>
@printf("Hello from trait Foo\n".cstring())
// src/main.pony
use "./lib"
actor Main is Foo
new create(env: Env) =>
this.apply()
Up until ponyc 0.49.1, the above failed to compile, because main.pony
never defined an FFI declaration for printf
. One way of making the above code compile is by moving the call to @printf
to a separate type:
// src/lib/lib.pony
use @printf[I32](fmt: Pointer[None] tag, ...)
trait Foo
fun apply() =>
Printf("Hello from trait Foo\n")
primitive Printf
fun apply(str: String) =>
@printf(str.cstring())
// src/main.pony
use "./lib"
actor Main is Foo
new create(env: Env) =>
this.apply()
Given that the original error is not immediately obvious, starting from this release, it is now a compile error to call FFI functions in default methods (or behaviors). However, this means that code that used to be legal will now fail with a compiler error. For example:
use @printf[I32](fmt: Pointer[None] tag, ...)
actor Main is _PrivateFoo
new create(env: Env) =>
this.apply()
trait _PrivateFoo
fun apply() =>
// Error: can't call an FFI function in a default method or behavior.
@printf("Hello from private trait _PrivateFoo\n".cstring())
As mentioned above, to fix the code above, you will need to move any FFI calls to external function:
use @printf[I32](fmt: Pointer[None] tag, ...)
actor Main is _PrivateFoo
new create(env: Env) =>
this.apply()
trait _PrivateFoo
fun apply() =>
// OK
Printf("Hello from private trait _PrivateFoo\n")
primitive Printf
fun apply(str: String) =>
@printf(str.cstring())
We believe that the impact of this change should be small, given the usability problems outlined above.
Fix concurrency bugs in runtime on Arm
Due to some incorrect memory ordering usage within various atomic operations in the runtime, it was possible for "bad things to happen" on Arm platforms. "Bad things" being violations of invariants in the runtime that could lead to incorrect runtime behavior that could exhibit in a variety of ways.
We've strengthened a number of memory orderings on Arm which should address the issues we have observed.
Fix a runtime fault for Windows IOCP w/ memtrack messages.
When the runtime is compiled with -DUSE_MEMTRACK_MESSAGES
on
Windows, the code path for asynchronous I/O events wasn't
initializing the pony context prior to its first use,
which would likely cause a runtime crash or other undesirable
behavior.
The -DUSE_MEMTRACK_MESSAGES
feature is rarely used, and has
perhaps never been used on Windows, so that explains why
we haven't had a crash reported for this code path.
Now that path has been fixed by rearranging the order of the code.
Add prebuilt ponyc binaries for Ubuntu 22.04
We've added prebuilt ponyc binaries specifically made to work on Ubuntu 22.04.
You can opt into using the Ubuntu binaries when using ponyup by running:
ponyup default ubuntu22.04
[0.50.0] - 2022-04-30
Fixed
- Fix crash with exhaustive match and generics (PR #4057)
- Fix parameter names not being checked (PR #4061)
- Fix compiler crash in HeapToStack optimization pass (PR #4067)
- Strengthen the ordering for some atomic operations (PR #4083)
- Fix a runtime fault for Windows IOCP w/ memtrack messages. (PR #4094)
Added
- Allow to override the return type of FFI functions (PR #4060)
- Add prebuilt ponyc releases for Ubuntu 22.04 (PR #4097)
Changed
- Don't allow FFI calls in default methods or behaviors (PR #4065)
0.49.1
Fix soundness bug introduced
We previously switched our underlying type system model. In the process, a soundness hole was introduced where users could assign values to variables with an ephemeral capability. This could lead to "very bad things".
The hole was introduced in May of 2021 by PR #3643. We've closed the hole so that code such as the following will again be rejected by the compiler.
let map: Map[String, Array[String]] trn^ = recover trn Map[String, Array[String]] end
[0.49.1] - 2022-03-13
Fixed
- Ban unstable variables (PR #4018)
0.49.0
Add workaround for compiler assertion failure in Promise.flatten_next
Under certain conditions a specific usage of Promise.flatten_next
and Promise.next
could trigger a compiler assertion, whose root-cause is still under investigation.
The workaround avoids the code-path that triggers the assertion. We still need a full solution.
Take exhaustive match into account when checking for field initialization
Previously, exhaustive matches were handled after we verified that an object's fields were initialized. This lead to the code such as the following not passing compiler checks:
primitive Foo
fun apply() : (U32 | None) => 1
type Bar is (U32 | None)
actor Main
let bar : Bar
new create(env : Env) =>
match Foo()
| let result : U32 =>
bar = result
| None =>
bar = 0
end
Field initialization is now done in a later pass after exhaustiveness checking has been done.
Fix compiler crash related to using tuples as a generic constraint
Tuple types aren't legal constraints on generics in Pony and we have a check in an early compiler pass to detect and report that error. However, it was previously possible to "sneak" a tuple type as a generic constraint past the earlier check in the compiler by "smuggling" it in a type alias.
The type aliases aren't flattened into their various components until after the code that disallows tuples as generic constraints which would result in the following code causing ponyc to assert:
type Blocksize is (U8, U32)
class Block[T: Blocksize]
We've added an additional check to the compiler in a later pass to report an error on the "smuggled" tuple type as a constraint.
Add greatest common divisor to math
package
Code to determine the greatest common divisor for two integers has been added to the standard library:
use "math"
actor Main
new create(env: Env) =>
try
let gcd = GreatestCommonDivisor[I64](10, 20)?
env.out.print(gcd.string())
else
env.out.print("No GCD")
end
Add least common multiple to math
package
Code to determine the least common multiple of two unsigned integers has been added to the standard library:
use "math"
actor Main
new create(env: Env) =>
try
let lcm = LeastCommonMultiple[U64](10, 20)?
env.out.print(lcm.string())
else
env.out.print("No LCM")
end
Fix incorrect "field not initialized" error with while/else
Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields:
actor Main
var _s: (String | None)
new create(env: Env) =>
var i: USize = 0
while i < 5 do
_s = i.string()
i = i + 1
else
_s = ""
end
Fix incorrect "field not initialized" error with try/else
Previously, due to a bug in the compiler's try/else handling code, the following code would be rejected as not initializing all object fields:
actor Main
var _s: (String | None)
new create(env: Env) =>
try
_s = "".usize()?.string()
else
_s = None
end
Fix compiler crash related to using tuples in a union as a generic constraint
Tuple types aren't legal constraints on generics in Pony and we have a check in an early compiler pass to detect and report that error. However, it was previously possible to "sneak" a tuple type as a generic constraint past the earlier check in the compiler by "smuggling" it in a type union in a type alias.
The type aliases aren't flattened into their various components until after the code that disallows tuples as generic constraints which would result in the following code causing ponyc to assert:
type Blocksize is (U64 | (U8, U32))
class Block[T: Blocksize]
We've added an additional check to the compiler in a later pass to report an error on the "smuggled" tuple type as a constraint.
Fix incorrect code returned by ANSI.erase
erase
was intended to erase all characters to the left of the cursor but was instead returning the code to erase all characters to the right.
Reimplement with
The with
keyword has been little used in most Pony programs. with
was implemented as "sugar" over the try/else/then
construct. Over the course of time, this became problematic as changes were made to make try
more friendly. However, these try
changes negatively impacted with
. Prior to this change, with
had become barely usable. We've reimplemented with
to address the usability problems that built up over time. with
is no longer sugar over try
and as such, shouldn't develop any unrelated problems going forward. However, the reimplemented with
is a breaking change.
Because with
was sugar over try
, the full expression was with/else
. Any error that occurred within a with
block would be handled by provided else
. The existence of with/else
rather than pure with
was not a principled choice. The else
only existed because it was needed to satisfy error-handling in the try
based implementation. Our new implementation of with
does not have the optional else
clause. All error handling is in the hands of the programmer like it would be with any other Pony construct.
Previously, you would have had:
with obj = SomeObjectThatNeedsDisposing() do
// use obj
else
// only run if an error has occurred
end
Now, you would do:
try
with obj = SomeObjectThatNeedsDisposing() do
// use obj
end
else
// only run if an error has occurred
end
Or perhaps:
with obj = SomeObjectThatNeedsDisposing() do
try
// use obj
else
// only run if an error has occurred
end
end
The new with
block guarantees that dispose
will be called on all with
condition variables before jumping away whether due to an error
or a control flow structure such as return
.
This first version of the "new with
" maintains one weakness that the previous implementation suffered from; you can't use an iso
variable as a with
condition. The following code will not compile:
use @pony_exitcode[None](code: I32)
class Disposable
var _exit_code: I32
new iso create() =>
_exit_code = 0
fun ref set_exit(code: I32) =>
_exit_code = code
fun dispose() =>
@pony_exitcode(_exit_code)
actor Main
new create(env: Env) =>
with d = Disposable do
d.set_exit(10)
end
A future improvement to the with
implementation will allow the usage of iso
variables as with
conditions.
Fix the interfaces for Iter's map
and map_stateful
methods to be less strict
The map_stateful
and map
methods on an Iter (from the itertools package) were too strict in what they required, requiring a B^
in order to produce an Iter[B]
.
This change correctly makes them only require B
.
Use symbol table from definition scope when looking up references from default method bodies
Previously, symbols from default method bodies were only looked up in the local scope of the file into which they were included. This resulted in compilation errors if said symbol wasn't available in the local scope.
Issues #3737 and #2150 were both examples of this problem.
We've updated definition lookup to check if the enclosing method is provided by a trait or interface and if it is, to also check to definition scope for any needed symbols.
Remove logger
package from the standard library
The logger
package is intentionally limited in its functionality and leans heavily into reducing messaging overhead between actors to the point of intentionally sacrificing functionality.
Our stated belief as a core team has been that the standard library isn't "batteries included". We have also stated that libraries were we believe it would be "relatively easy" for multiple competing standards to appear in the community shouldn't be included in the standard library unless other factors make inclusion important.
Some other factor we have discussed in the past include:
- Not having a standard library version would make interop between different 3rd-party Pony libraries difficult.
- The functionality is required or called for by an interface in one or more standard library classes.
- We consider the having the functionality provided to be core to the "getting started with Pony experience".
We don't believe that any of above 3 points apply to the logger
package. Therefore, we've removed logger
from the standard library and turned it into it's own stand alone library.
If you were using the logger
package, visit it's new home and follow the "How to Use" directions.
Fix call receiver type casting in LLVM IR
In some rare cases (such as in the PonyCheck library), ponyc
was generating LLVM that did not use the correct pointer types for call site receiver arguments. This did not result in unsafe code at runtime, but it was still a violation of the LLVM type system, and it caused the "Verification" step of compilation to fail when enabled.
To fix this issue, we introduced an LLVM bitcast at such call sites to cast the receiver pointer to the correct LLVM type.
Rename ponybench
package to match standard library naming conventions
We recently realized that when we renamed large portions of the standard library to conform with our naming standards, that we missed the ponybench
package. To conform with the naming convention, the ponybench
package as been renamed to pony_bench
.
You'll need to update your test code from:
use "ponybench"
to
use "pony_bench"
Add PonyCheck to the standard library
PonyCheck, a property based testing library, has been added to the standard library. PonyCheck was previously its own project...
0.48.0
Add a pony primitive that exposes scheduler information
Previously, when users wanted to optimize the parallelizing work based on the maximum number of actors that can be run at a single time, we were pointing them to using the private runtime method @ponyint_sched_cores()
.
This was problematic for two reasons:
- We were pointing users at an internal implementation method that we hadn't promised not to change.
- We were requiring users to muck about with FFI for something that has become somewhat common for users wanting to maximize performance want to know.
We've now exposed some information about scheduler threads via a new package runtime_info
thereby resolving both of the problems mentioned above.
Pony users should expect to see additional information added to the runtime_info
package moving forward.
Anyone who was using the internal ponyint_sched_cores()
FFI call will need to update to using runtime_info
as the internal function has been removed.
Stop creating prebuilt ponyc releases for Ubuntu 21.04
Ubuntu 21.04 hit its end-of-life at the end of January 2022. We are no longer build prebuilt ponyc releases for it. If you are still using Ubuntu 21.04 and need ponyc for 21.04, you'll have to build from source.
The next Ubuntu LTS release is coming in April of 2022 and we'll be adding prebuilt ponyc for it. If have upgraded to a non-LTS Ubuntu after 21.04 that s still supported and would like us to do ponyc releases for it, please let us know via a GitHub issue or via the Ponylang Zulip.
Fix runtime crash when tracing class iso containing struct val
Prior to this fix, you could crash the runtime if you sent a val
struct wrapper in an iso
class. For example:
use "collections"
struct val Foo
class Bar
let f: Foo = Foo
actor Main
new create(env: Env) =>
for i in Range(0, 20000) do
inspect(recover Bar end)
end
be inspect(wrap: Bar iso) =>
None // Do something with wrap.f
Revert "prevent non-opaque structs from being used as behaviour parameters"
The bug that #3781 aka "prevent non-opaque structs from being used as behaviour parameters" was an attempt at preventing, as only partially solved by the change.
We've introduced a full fix in #3993 that removes the need for #3871.
Update to LLVM 13.0.1
We've updated the LLVM used to build Pony to 13.0.1.
Remove out parameter from pony_os_stdin_read
The signature of the pony_os_stdin_read
function has been simplified to remove the bool* out_again
parameter.
-PONY_API size_t pony_os_stdin_read(char* buffer, size_t space, bool* out_again)
+PONY_API size_t pony_os_stdin_read(char* buffer, size_t space)
It is permitted to call the pony_os_stdin_read
function again in a loop if the return value is greater than zero, and the platform is not windows. Given that those two conditions are enough information to make a decision, the out_again
parameter is not needed, and can be removed.
Technically this is a breaking change, because the function is prefixed with pony_
and is thus a public API. But it is unlikely that any code out there is directly using the pony_os_stdin_read
function, apart from the Stdin
actor in the standard library, which has been updated in its internal implementation details to match the new signature.
Expose additional scheduler information in the runtime_info package
Three additional methods have been added to SchedulerInfo
.
- minimum_schedulers
Returns the minimum number of schedulers that will be active.
- scaling_is_active
Returns if scheduler scaling is on
- will_yield_cpu
Returns if scheduler threads are yielding the CPU to other processes when they have no work to do.
Add additional methods to itertools
Previously there were methods for Iter
within itertools
which, while originally planned, where not implemented. These methods have now been implemented.
The added methods are:
dedup
which removes local duplicates from consecutive identical elements via a provided hash functioninterleave
which alternates values between two iterators until both run outinterleave_shortest
which alternates values between two iterators until one of them runs outintersperse
which yields a given value after everyn
elements of the iteratorstep_by
which yields everyn
th element of the iteratorunique
which removes global duplicates of identical elements via a provided hash function
[0.48.0] - 2022-02-08
Fixed
- Fix runtime crash when tracing class iso containing struct val (PR #3993)
Added
- Add a pony primitive that exposes scheduler information (PR #3984)
- Expose additional scheduler info via the runtime_info package (PR #3988)
- Add additional methods to itertools (PR #3992)
Changed
0.47.0
Remove simplebuiltin compiler option
The ponyc option simplebuiltin
was never useful to users but had been exposed for testing purposes for Pony developers. We've removed the need for the "simplebuiltin" package for testing and have remove both it and the compiler option.
Technically, this is a breaking change, but no end-users should be impacted.
Fix return checking in behaviours and constructors
Our checks to make sure that the usage of return in behaviours and constructors was overly restrictive. It was checking for any usage of return
that had a value including when the return wasn't from the method itself.
For example:
actor Main
new create(env: Env) =>
let f = {() => if true then return None end}
Would return an error despite the return being in a lambda and therefore not returning a value from the constructor.
Fix issue that could lead to a muted actor being run
A small logical flaw was discovered in the Pony runtime backpressure system that could lead to an actor that has been muted to prevent it from overloading other actors to be run despite a rule that says muted actors shouldn't be run.
The series of events that need to happen are exceedingly unlikely but we do seem them from time to time in our Arm64 runtime stress tests. In the event that a muted actor was run, if an even more unlikely confluence of events was to occur, then "very bad things" could happen in the Pony runtime where "very bad things" means "we the Pony developers are unable to reason about what might happen".
Remove library mode option from ponyc
From the very early days of the Pony runtime, a "library mode" has been around that allows you to compile a Pony program to a C compatible library that you can then start up using various runtime APIs to do things like initialize the runtime, create actors, send messages and more. We've made extensive changes to the runtime over the years and have no faith that library mode and its related functionality work.
Our lack of faith extends back many years and we've stated as the Pony core team that we don't consider library mode to be supported; until now, we haven't done anything about what "not supported" means.
With this release, library mode has been removed as an option.
Don't allow interfaces to have private methods
When Pony allowed interfaces to have private methods, it was possible to use an interface to break encapsulation for objects and access private methods from outside their enclosing package.
The following code used to be legal Pony code but will now fail with a compiler error:
actor Main
new create(env: Env) =>
let x: String ref = "sailor".string()
let y: Foo = x
y._set(0, 'f')
env.out.print("Hello, " + x)
interface Foo
fun ref _set(i: USize, value: U8): U8
If you were previously using interfaces with private methods in your code, you'll need to switch them to being traits and then use nominal typing on all the implementers.
For example:
interface Foo
fun ref _bar()
would become:
trait Foo
fun ref _bar()
And any objects that need to provide Foo
would be changed from:
class ProvidesFoo
to
class ProvidesFoo is Foo
We believe that the only impact of this change will primarily be a single interface in the standard library AsioEventNotify
and updates that need to be done to deal with it changing from an interface to a trait.
If you are unable to make the changes above, it means that you were taking the encapsulation violation bug we've fixed and will need to rethink your design. If you need assistance with such a redesign, please stop by the Pony Zulip and we'll do what we can to help.
Change builtin/AsioEventNotify
from an interface to a trait
The "Don't allow interfaces to have private methods" change that is part of this release required that we change the AsioEventNotify
interface to a trait.
If you are one of the few users outside of the standard library to be using the ASIO subsystem directly in your Pony code, you'll need to make an update to
conform to this change.
Where previously you had something like:
class AsioEventReceivingClass
be _event_notify(event: AsioEventID, flags: U32, arg: U32) =>
...
You'll need to switch to using nominal typing rather than structural:
class AsioEventReceivingClass is AsioEventNotify
be _event_notify(event: AsioEventID, flags: U32, arg: U32) =>
...
As far as we know, there are two codebases that will be impacted by this change:
Fix compiler assertion failure when assigning error to a variable
This release fixes a compiler assertion failure being triggered when one attempted to assign an error expression surrounded by parenthesis to a variable.
Add "nodoc" annotation
The can be used to control the pony compilers documentation generation, any structure that can have a docstring (except packages) can be annotated with \nodoc\ to prevent documentation from being generated.
This replaces a hack that has existed in the documentation generation system for several years to filter out items that were "for testing" by looking for Test and _Test at the beginning of the name as well as providing UnitTest or TestList.
Note that the "should we include this package" hack to filter oupackages called "test" and "builtin_test" still exists for the timbeing until we have further discussion.
[0.47.0] - 2022-02-02
Fixed
- Fix return checking in behaviours and constructors (PR #3971)
- Fix issue that could lead to a muted actor being run (PR #3974)
- Fix loophole that allowed interfaces to be used to violate encapsulation (PR #3973)
- Fix compiler assertion failure when assigning error to a variable (PR #3980)
Added
- Add "nodoc" annotation (PR #3978)
Changed
- Remove simplebuiltin compiler option (PR #3965)
- Remove library mode option from ponyc (PR #3975)
- Change
builtin/AsioEventNotify
from an interface to a trait (PR #3973) - Don't allow interfaces to have private methods (PR #3973)
- Remove hack that prevented documentation generation for "test classes" (PR #3978)
0.46.0
Stop creating Centos 8 releases
CentOS 8 has been end-of-lifed and will be receiving no further updates. As per our policy, we will no longer be building regular releases for CentOS 8. Existing releases can still be installed via ponyup, but no additional releases will be done.
Our CentOS 8 support has been replaced by support for Rocky 8.
Hide C header implementation details related to actor pad size.
Previously, in the pony.h
header that exposes the "public API" of the Pony runtime, information about the size of an actor struct was published as public information.
This change removes that from the public header into a private header, to hide
implementation details that may be subject to change in future versions of the Pony runtime.
This change does not impact Pony programs - only C programs using the pony.h
header to use the Pony runtime in some other way than inside of a Pony program, or to create custom actors written in C.
Change type of Env.root to AmbientAuth
Previously, Env.root currently had the type (AmbientAuth | None) to allow for creation of artificial Env instances without AmbientAuth. Yet, there was no observable usage of this feature. It required extra work to make use of, as one always needs a pattern match or an as expression with a surrounding try. We've changed Env.root to only be AmbientAuth, no longer requiring a pattern match or a try.
To adjust your code to take this breaking change into account, you'd do the following. Where you previously had code like:
try
TCPListener(env.root as AmbientAuth, Listener(env.out))
else
env.out.print("unable to use the network")
end
You can now do:
TCPListener(env.root, Listener(env.out))
The same change can be made if you were pattern matching on the type of env.root.
[0.46.0] - 2022-01-16
Changed
0.45.2
Clarify wording for some subtyping errors
The wording of a small number of errors relating to the subtyping of capabilities were improved.
These were previously technically incorrect, or otherwise unnecessarily obtuse.
Fix inability to fully build pony on Raspberry PI 4's with 64-bit Raspbian
Building on 64-bit Raspbian needs the flag -fPIC
instead of -fpic
which is used by default on Unix builds.
We've added a Makefile flag pic_flag
that you can set to either -fpic
or -fPIC
for both libs and configure steps, e.g. make libs pic_flag=-fPIC
and make configure pic_flag=-fPIC
. It will default to -fpic
if not specified.
Added build instructions for 64-bit Raspbian
We've gotten Pony building on 64-bit Raspbian running on Raspberry Pi 4 model B boards. The installation is a little different than other Linux distributions that you can build Pony on, so we've added instructions specific to 64-bit Raspbian.
0.45.1
Fix underlying time source for Time.nanos() on macOS
Previously, we were using mach_absolute_time
on macOS to get the number of ticks since boot, with the assumption that ticks increment at nanosecond intervals. However, as noted by Apple, this assumption is flawed on Apple Silicon, and will also affect any binaries that were built on Intel, as the Rosetta 2 translator will not apply any time conversion.
The recommended replacement to mach_absolute_time
is to use clock_gettime_nsec_np
with a clock of type CLOCK_UPTIME_RAW
.
Fix cli
package from mangling option arguments with equal signs
The current command parser in the cli
package cuts option arguments of String
type at the first equal sign. This release fixes the problem for long options (--option=foo=bar
) and for short options such as -O=foo=bar
. Short options such as -Ofoo=bar
will continue to raise an "ambiguous args" error.
The code below shows the bug, with the option argument being cut short at the first equal sign. The code below prints "foo" instead of the complete value, "foo=bar". The same is true when uses the short version of the option, like -t=foo=bar
.
use "cli"
actor Main
new create(env: Env) =>
try
let cs =
CommandSpec.leaf("simple", "", [
OptionSpec.string("test" where short' = 't')
])?
let args: Array[String] = [
"ignored"; "--test=foo=bar"
]
let cmdErr = CommandParser(cs).parse(args) as Command
env.out.print(cmdErr.option("test").string())
end
[0.45.1] - 2021-12-02
Fixed
0.45.0
Remove options package
Removes the options package, which was deprecated in version 0.26.0 in favor of the cli package.
An example program using the options package is immediately below, while the rewrite with the cli package follows it.
use "options"
actor Main
let _env: Env
// Some values we can set via command line options
var _a_string: String = "default"
var _a_number: USize = 0
var _a_unumber: USize = 0
var _a_float: Float = F64(0.0)
new create(env: Env) =>
_env = env
try
arguments()?
end
_env.out.print("The String is " + _a_string)
_env.out.print("The Number is " + _a_number.string())
_env.out.print("The UNumber is " + _a_unumber.string())
_env.out.print("The Float is " + _a_float.string())
fun ref arguments() ? =>
var options = Options(_env.args)
options
.add("string", "t", StringArgument)
.add("number", "i", I64Argument)
.add("unumber", "u", U64Argument)
.add("float", "c", F64Argument)
for option in options do
match option
| ("string", let arg: String) => _a_string = arg
| ("number", let arg: I64) => _a_number = arg.usize()
| ("unumber", let arg: U64) => _a_unumber = arg.usize()
| ("float", let arg: F64) => _a_float = arg
| let err: ParseError => err.report(_env.out) ; usage() ; error
end
end
fun ref usage() =>
// this exists inside a doc-string to create the docs you are reading
// in real code, we would use a single string literal for this but
// docstrings are themselves string literals and you can't put a
// string literal in a string literal. That would lead to total
// protonic reversal. In your own code, use a string literal instead
// of string concatenation for this.
_env.out.print(
"program [OPTIONS]\n" +
" --string N a string argument. Defaults to 'default'.\n" +
" --number N a number argument. Defaults to 0.\n" +
" --unumber N a unsigned number argument. Defaults to 0.\n" +
" --float N a floating point argument. Defaults to 0.0.\n"
)
use "cli"
actor Main
new create(env: Env) =>
let cs =
try
CommandSpec.leaf("run", "", [
OptionSpec.string("string", "String argument"
where short' = 't', default' = "default")
OptionSpec.i64("number", "Number argument"
where short' = 'i', default' = 0)
OptionSpec.u64("unumber", "Unsigned number argument"
where short' = 'u', default' = 0)
OptionSpec.f64("float", "Float argument"
where short' = 'c', default' = 0.0)
], [])? .> add_help()?
else
env.exitcode(-1) // some kind of coding error
return
end
let cmd =
match CommandParser(cs).parse(env.args, env.vars)
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(env.out)
env.exitcode(0)
return
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
return
end
let string = cmd.option("string").string()
let number = cmd.option("number").i64()
let unumber = cmd.option("unumber").u64()
let float = cmd.option("float").f64()
env.out.print("The String is " + string)
env.out.print("The Number is " + number.string())
env.out.print("The UNumber is " + unumber.string())
env.out.print("The Float is " + float.string())
Fix erratic cycle detector triggering on some Arm systems
Triggering of cycle detector runs was based on an assumption that our "tick" time source would monotonically increase. That is, that the values seen by getting a tick would always increase in value.
This assumption is true as long as we have a hardware source of ticks to use. However, on some Arm systems, the hardware cycle counter isn't available to user code. On these these, we fall back to use clock_gettime
as a source of ticks. When clock_gettime
is the source of ticks, the ticks are no longer monotonically increasing.
Usage of the cycle detector with the non-monotonically increasing tick sources would cause the cycle detector run very infrequently and somewhat erratically. This was most likely to be seen on hardware like the Raspberry Pi.
Fix non-release build crashes on Arm
We've fixed a cause of "random" crashes that impacted at minimum, debug versions of Pony programs running on 32-bit Arm builds on the Raspberry Pi 4.
It's likely that the crashes impacted debug versions of Pony programs running on all Arm systems, but we don't have enough testing infrastructure to know for sure.
Add Ubuntu 21.04 nightly builds and releases builds
We've added nightly and release builds of ponyc that are built on Ubuntu 21.04. We'll continue supporting them through the end of life of this non-LTS version of Ubuntu.
Fix major source of runtime instability on non-x86 based platforms
We've replaced our existing code for handling the ABA problem when running on Arm CPUs. The implementation we replaced was buggy and resulted in runtime instability including crashes and memory corruption.
Update to LLVM 13.0.0
We've updated the LLVM used to build Pony to 13.0.0.
Fix segfaults with debug builds on 64-bit Arm
Debug builds on 64-bit Arm platforms were segfaulting. The code generated when doing ponyc --debug
wouldn't work and would eventually crash. We believe the source to be an LLVM bug but, aren't certain.
We've introduced a work around that fixes the segfault problem, but does some optimization of debug builds for 64-bit Arm platforms. Additional investigation is underway. You can track progress by following issue #3874.
Add Graviton 64-bit Arm CPUs as a supported architecture
We've add continuous integration testing on AWS Graviton instances via CirrusCI. All code changes going forward will be tested on Graviton.
This provides us some fairly good coverage for "64-bit Arm" support in general although various other platforms like the Raspberry Pi 4B and Apple M1 chips are still "best effort" as we don't have any CI for them and we've found them to be somewhat different than Graviton.
Added build instructions for 32-bit Raspbian
We've gotten Pony building on 32-bit Raspbian running on Raspberry Pi 4 model B boards. The installation is a little different than other Linux distributions that you can build Pony on, so we've added instructions specific to 32-bit Raspbian.
Add Apple Silicon as a supported platform
Pony is now supported on Apple Silicon (M1 processors). Our support is "best effort" for now, since we currently lack continuous integration for Apple Silicon. Users on this platform will need to install Pony from source for the time being.
Fixed incorrect version in ponyc nightly builds
The build system facility that allowed us to set arbitrary versions in builds was broken. The end result was nightly builds not having meaningful results when ponyc --version
was run.
[0.45.0] - 2021-11-01
Fixed
- Fix erratic cycle detector triggering on some Arm systems (PR #3854)
- Fix non-release build crashes on Arm (PR #3860)
- Fix major source of runtime instability on non-x86 based platforms (PR #3871)
- Fix segfaults with debug mode code on 64-bit Arm (PR #3875)
- Fix incorrect version in nightly ponyc builds (PR #3895)
Added
- Add Ubuntu 21.04 nightly builds and releases builds (PR #3866)
- Add 64-bit Arm (Graviton) as a supported platform (PR #3876)
- Add build instructions for 32-bit Raspbian (PR #3879)
- Add Apple Silicon as a supported platform (PR #3883)