Low-level Swift


(Romain Goyet) #1

Hi everyone,

In the introduction to Swift
<https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/>,
it is presented as an "industrial-quality systems programming language".
According to Wikipedia
<https://en.wikipedia.org/wiki/System_programming_language>, this means
that I could expect to be able to write device drivers or operating systems
in Swift.

However it seems like this claim is only partially true, since several
important low-level features seem to be completely missing:

- Is it possible to generate volatile memory accesses
<http://llvm.org/docs/LangRef.html#volatile-memory-accesses> in Swift?
Writing device drivers is virtually impossible without a way to guarantee
certain memory operations are actually made (and not optimized-out).

- Is it possible to embed raw binary data in Swift? For example, an
equivalent of the following C code "const int8_t foo[6] =
{0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo:
[Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being
able to embed raw binary data is very important in a low-level environment:
for example, you may need to feed specific data to a device for an
initialization sequence at a point where you don't have a filesystem
available yet.

There might be other aspects that I'm overlooking right now, but I think
that's enough to start a discussion: is Swift really meant to be a systems
programming language?

Thanks,

- Romain


(Charles Constant) #2

I think by "systems programming language" we're talking in relative terms,
but I don't know about writing drivers in Swift.

Have you filed a feature request in radar? If you have want to reference
mine, feel free: radar://21464610 "Real-time Swift" sister-language, or
"real time" feature subset

I think it would be sweet if Swift someday is able to replace C++ for
writing AudioUnits, etc. I know others hope the same thing. Eg: I heard
Chris Liscio say the same on a podcast a couple months back.

···

On Thu, Jan 7, 2016 at 3:52 AM, Romain Goyet via swift-evolution < swift-evolution@swift.org> wrote:

Hi everyone,

In the introduction to Swift
<https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/>,
it is presented as an "industrial-quality systems programming language".
According to Wikipedia
<https://en.wikipedia.org/wiki/System_programming_language>, this means
that I could expect to be able to write device drivers or operating systems
in Swift.

However it seems like this claim is only partially true, since several
important low-level features seem to be completely missing:

- Is it possible to generate volatile memory accesses
<http://llvm.org/docs/LangRef.html#volatile-memory-accesses> in Swift?
Writing device drivers is virtually impossible without a way to guarantee
certain memory operations are actually made (and not optimized-out).

- Is it possible to embed raw binary data in Swift? For example, an
equivalent of the following C code "const int8_t foo[6] =
{0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo:
[Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being
able to embed raw binary data is very important in a low-level environment:
for example, you may need to feed specific data to a device for an
initialization sequence at a point where you don't have a filesystem
available yet.

There might be other aspects that I'm overlooking right now, but I think
that's enough to start a discussion: is Swift really meant to be a systems
programming language?

Thanks,

- Romain

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Brent Royal-Gordon) #3

- Is it possible to embed raw binary data in Swift? For example, an equivalent of the following C code "const int8_t foo[6] = {0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo: [Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being able to embed raw binary data is very important in a low-level environment: for example, you may need to feed specific data to a device for an initialization sequence at a point where you don't have a filesystem available yet.

The raw binary data equivalent is a tuple. For instance, I believe this will have the exact memory layout you're looking for:

  let foo: (Int8, Int8, Int8, Int8, Int8, Int8) = (0x00, 0x11, 0x22, 0x33, 0x44, 0x55)

There might be other aspects that I'm overlooking right now, but I think that's enough to start a discussion: is Swift really meant to be a systems programming language?

I think it's probably more accurate to say that Swift *aspires* to be a systems programming language. It is already fast enough and has low enough overhead, but some of the features needed aren't there yet, and aren't considered a priority over more common use cases like application programming.

···

--
Brent Royal-Gordon
Architechies


(Austin Zheng) #4

I'd think the hypothetical way in Swift to write to configuration registers
would be to create an UnsafeMutablePointer<Int64> (or some other raw
integer type) from a raw memory address, and then get/set the contents
using the 'memory' property. Not sure if the compiler is "smart" enough to
optimize out memory accesses made using that mechanism, although I would
assume no.

Austin

···

On Thu, Jan 7, 2016 at 3:52 AM, Romain Goyet via swift-evolution < swift-evolution@swift.org> wrote:

Hi everyone,

In the introduction to Swift
<https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/>,
it is presented as an "industrial-quality systems programming language".
According to Wikipedia
<https://en.wikipedia.org/wiki/System_programming_language>, this means
that I could expect to be able to write device drivers or operating systems
in Swift.

However it seems like this claim is only partially true, since several
important low-level features seem to be completely missing:

- Is it possible to generate volatile memory accesses
<http://llvm.org/docs/LangRef.html#volatile-memory-accesses> in Swift?
Writing device drivers is virtually impossible without a way to guarantee
certain memory operations are actually made (and not optimized-out).

- Is it possible to embed raw binary data in Swift? For example, an
equivalent of the following C code "const int8_t foo[6] =
{0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo:
[Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being
able to embed raw binary data is very important in a low-level environment:
for example, you may need to feed specific data to a device for an
initialization sequence at a point where you don't have a filesystem
available yet.

There might be other aspects that I'm overlooking right now, but I think
that's enough to start a discussion: is Swift really meant to be a systems
programming language?

Thanks,

- Romain

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Joe Groff) #5

Hi everyone,

In the introduction to Swift <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/>, it is presented as an "industrial-quality systems programming language".
According to Wikipedia <https://en.wikipedia.org/wiki/System_programming_language>, this means that I could expect to be able to write device drivers or operating systems in Swift.

However it seems like this claim is only partially true, since several important low-level features seem to be completely missing:

- Is it possible to generate volatile memory accesses <http://llvm.org/docs/LangRef.html#volatile-memory-accesses> in Swift? Writing device drivers is virtually impossible without a way to guarantee certain memory operations are actually made (and not optimized-out).

We haven't designed APIs for this yet, but the LLVM instructions for volatile and atomic operations are available in the stdlib-private 'Builtin' module, should you want to experiment.

- Is it possible to embed raw binary data in Swift? For example, an equivalent of the following C code "const int8_t foo[6] = {0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo: [Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being able to embed raw binary data is very important in a low-level environment: for example, you may need to feed specific data to a device for an initialization sequence at a point where you don't have a filesystem available yet.

We also haven't designed a story for this yet. We have some support for optimizing constant literal initializations like this into static initializers, but need to do more work to be able to guarantee it.

There might be other aspects that I'm overlooking right now, but I think that's enough to start a discussion: is Swift really meant to be a systems programming language?

Like Austin said, that's a long term goal, and I think you can get pretty far today if you're careful and understand the compiler and runtime, but we're a long ways away from really productizing our low-level programming support to a degree I'd feel comfortable advertising.

-Joe

···

On Jan 7, 2016, at 3:52 AM, Romain Goyet via swift-evolution <swift-evolution@swift.org> wrote:


(Chris Lattner) #6

Yep, Brent is right here, this is currently an aspirational goal. Rust and C (as two examples) are currently better than Swift at certain types of system programming tasks.

"Certain types" is key here, because (as with many terms) “system programming language” means different things to different people. My goal is for [likely a subset of] Swift to eventually scale down to the smallest firmware, boot loaders, and micro-controllers. At the same time, I think it should be able to be a fantastic kernel/driver programming language, a great compiler implementation language, and many other things that some people consider to be system programming tasks.

There is a bunch of different work that we need to do to make this happen, and it is likely post-Swift 3. It is my belief that this will all slot into cleanly to the current design, but we’ll have to test that theory when we get there. Volatile access, inline assembly, careful control over memory allocation and copies, control over struct field layout, and many other things are sure to come up.

-Chris

···

On Jan 7, 2016, at 12:33 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

- Is it possible to embed raw binary data in Swift? For example, an equivalent of the following C code "const int8_t foo[6] = {0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo: [Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being able to embed raw binary data is very important in a low-level environment: for example, you may need to feed specific data to a device for an initialization sequence at a point where you don't have a filesystem available yet.

The raw binary data equivalent is a tuple. For instance, I believe this will have the exact memory layout you're looking for:

  let foo: (Int8, Int8, Int8, Int8, Int8, Int8) = (0x00, 0x11, 0x22, 0x33, 0x44, 0x55)

There might be other aspects that I'm overlooking right now, but I think that's enough to start a discussion: is Swift really meant to be a systems programming language?

I think it's probably more accurate to say that Swift *aspires* to be a systems programming language. It is already fast enough and has low enough overhead, but some of the features needed aren't there yet, and aren't considered a priority over more common use cases like application programming.


(Félix Cloutier) #7

It is. This:

func foo(ptr: UnsafeMutablePointer<Int32>) {
  ptr.memory = 4
  ptr.memory = 5
}

compiles to:

define hidden void @_TF4test3fooFGVSs20UnsafeMutablePointerVSs5Int32_T_(i8* nocapture) #1 {
entry:
  %.value = bitcast i8* %0 to i32*
  store i32 5, i32* %.value, align 4
  ret void
}

Notice how it's "missing" a store.

Félix

···

Le 7 janv. 2016 à 15:54:36, Austin Zheng via swift-evolution <swift-evolution@swift.org> a écrit :

I'd think the hypothetical way in Swift to write to configuration registers would be to create an UnsafeMutablePointer<Int64> (or some other raw integer type) from a raw memory address, and then get/set the contents using the 'memory' property. Not sure if the compiler is "smart" enough to optimize out memory accesses made using that mechanism, although I would assume no.

Austin

On Thu, Jan 7, 2016 at 3:52 AM, Romain Goyet via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi everyone,

In the introduction to Swift <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/>, it is presented as an "industrial-quality systems programming language".
According to Wikipedia <https://en.wikipedia.org/wiki/System_programming_language>, this means that I could expect to be able to write device drivers or operating systems in Swift.

However it seems like this claim is only partially true, since several important low-level features seem to be completely missing:

- Is it possible to generate volatile memory accesses <http://llvm.org/docs/LangRef.html#volatile-memory-accesses> in Swift? Writing device drivers is virtually impossible without a way to guarantee certain memory operations are actually made (and not optimized-out).

- Is it possible to embed raw binary data in Swift? For example, an equivalent of the following C code "const int8_t foo[6] = {0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo: [Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being able to embed raw binary data is very important in a low-level environment: for example, you may need to feed specific data to a device for an initialization sequence at a point where you don't have a filesystem available yet.

There might be other aspects that I'm overlooking right now, but I think that's enough to start a discussion: is Swift really meant to be a systems programming language?

Thanks,

- Romain

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Goffredo Marocchi) #8

Hello Chris,

For many, this is also the era of domain specific languages and I think that maybe Swift's aspirational goal of doing everything (scaling from low level device driver code, to rapid prototyping, to graphically rich and versatile application, to embedded devices, etc...) might put a big burden on the language and on the compiler.

Do you see Swift putting more and more emphasis to interoperability with other languages which might have better characteristic at dealing with a specific domain than Swift does currently with maybe also some push to extend those languages to inter operate better and better?

···

Sent from my iPhone

On 9 Jan 2016, at 19:16, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 7, 2016, at 12:33 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

- Is it possible to embed raw binary data in Swift? For example, an equivalent of the following C code "const int8_t foo[6] = {0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo: [Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being able to embed raw binary data is very important in a low-level environment: for example, you may need to feed specific data to a device for an initialization sequence at a point where you don't have a filesystem available yet.

The raw binary data equivalent is a tuple. For instance, I believe this will have the exact memory layout you're looking for:

   let foo: (Int8, Int8, Int8, Int8, Int8, Int8) = (0x00, 0x11, 0x22, 0x33, 0x44, 0x55)

There might be other aspects that I'm overlooking right now, but I think that's enough to start a discussion: is Swift really meant to be a systems programming language?

I think it's probably more accurate to say that Swift *aspires* to be a systems programming language. It is already fast enough and has low enough overhead, but some of the features needed aren't there yet, and aren't considered a priority over more common use cases like application programming.

Yep, Brent is right here, this is currently an aspirational goal. Rust and C (as two examples) are currently better than Swift at certain types of system programming tasks.

"Certain types" is key here, because (as with many terms) “system programming language” means different things to different people. My goal is for [likely a subset of] Swift to eventually scale down to the smallest firmware, boot loaders, and micro-controllers. At the same time, I think it should be able to be a fantastic kernel/driver programming language, a great compiler implementation language, and many other things that some people consider to be system programming tasks.

There is a bunch of different work that we need to do to make this happen, and it is likely post-Swift 3. It is my belief that this will all slot into cleanly to the current design, but we’ll have to test that theory when we get there. Volatile access, inline assembly, careful control over memory allocation and copies, control over struct field layout, and many other things are sure to come up.

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Austin Zheng) #9

Indeed, that's good to know. Thanks for the clarification!

Austin

···

On Thu, Jan 7, 2016 at 1:22 PM, Félix Cloutier <felixcca@yahoo.ca> wrote:

It is. This:

func foo(ptr: UnsafeMutablePointer<Int32>) {
ptr.memory = 4
ptr.memory = 5
}

compiles to:

define hidden void
@_TF4test3fooFGVSs20UnsafeMutablePointerVSs5Int32_T_(i8* nocapture) #1 {
entry:
  %.value = bitcast i8* %0 to i32*
  store i32 5, i32* %.value, align 4
  ret void
}

Notice how it's "missing" a store.

Félix

Le 7 janv. 2016 à 15:54:36, Austin Zheng via swift-evolution < > swift-evolution@swift.org> a écrit :

I'd think the hypothetical way in Swift to write to configuration
registers would be to create an UnsafeMutablePointer<Int64> (or some other
raw integer type) from a raw memory address, and then get/set the contents
using the 'memory' property. Not sure if the compiler is "smart" enough to
optimize out memory accesses made using that mechanism, although I would
assume no.

Austin

On Thu, Jan 7, 2016 at 3:52 AM, Romain Goyet via swift-evolution < > swift-evolution@swift.org> wrote:

Hi everyone,

In the introduction to Swift
<https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/>,
it is presented as an "industrial-quality systems programming language".
According to Wikipedia
<https://en.wikipedia.org/wiki/System_programming_language>, this means
that I could expect to be able to write device drivers or operating systems
in Swift.

However it seems like this claim is only partially true, since several
important low-level features seem to be completely missing:

- Is it possible to generate volatile memory accesses
<http://llvm.org/docs/LangRef.html#volatile-memory-accesses> in Swift?
Writing device drivers is virtually impossible without a way to guarantee
certain memory operations are actually made (and not optimized-out).

- Is it possible to embed raw binary data in Swift? For example, an
equivalent of the following C code "const int8_t foo[6] =
{0x00,0x11,0x22,0x33,0x44,0x55};"? The simple Swift equivalent, "let foo:
[Int8] = [0x0,0x1,0x2,0x3,0x4,0x6];" is obviously wildly different. Being
able to embed raw binary data is very important in a low-level environment:
for example, you may need to feed specific data to a device for an
initialization sequence at a point where you don't have a filesystem
available yet.

There might be other aspects that I'm overlooking right now, but I think
that's enough to start a discussion: is Swift really meant to be a systems
programming language?

Thanks,

- Romain

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #10

Hello Chris,

For many, this is also the era of domain specific languages and I think that maybe Swift's aspirational goal of doing everything (scaling from low level device driver code, to rapid prototyping, to graphically rich and versatile application, to embedded devices, etc...) might put a big burden on the language and on the compiler.

Yes, this goal is loaded with engineering/design tradeoffs that we will have to carefully balance.

Do you see Swift putting more and more emphasis to interoperability with other languages which might have better characteristic at dealing with a specific domain than Swift does currently with maybe also some push to extend those languages to inter operate better and better?

Swift currently has pretty great interop with C and ObjC through the ClangImporter. Extending that to C++ is natural once we have time to tackle it and do it right.

I see no reason that we couldn’t have importers for other languages implemented in the same way. For example, it would be very interesting for swift to be able to import a Java or C# package and just call methods directly on their objects, just like we do for ObjC.

-Chris

···

On Jan 9, 2016, at 12:27 PM, Goffredo Marocchi <panajev@gmail.com> wrote: