Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unsafe context #1758

Open
insinfo opened this issue Jul 26, 2021 · 19 comments
Open

unsafe context #1758

insinfo opened this issue Jul 26, 2021 · 19 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@insinfo
Copy link

insinfo commented Jul 26, 2021

The Unsafe Context would make it possible to optimize certain codes, such as numerical operations, mathematical calculations, layout calculations, vector operations, image processing, this would help for example to optimize certain parts of the flutter (IOS,ANDROID,Desktop) , would also bring many benefits to dart on the server-side backend, speed improvement in running command line applications etc.

It has great potential to bring many benefits, improved interoperability with C/C++ FFI, and WebASM.

with the Insecure Context it would be possible to make manual memory allocations, and use Atomics and SIMD intrinsics.

the implementation of this feature could be similar to java's Unsafe class or C#'s unsafe

Unsafe allows developers to

Directly access CPU and other hardware features
Create an object but not run its constructor
Create a truly anonymous class without the usual verification
Manually manage off-heap memory
Do many other seemingly "impossible things"

along with the Unsafe Context, it would bring intrinsic SIMD and Atomics

Example

if (Avx2.IsSupported) {
intrinsicsAvx2();
}
unsafe int intrinsicsAvx2() {
    int vectorSize = 256 / 8 / 4;
    var accVector = Vector256<int>.Zero;
    int i;
    var array = Array;
    fixed (int* ptr = array) {
        for (i = 0; i <= array.Length - vectorSize; i += vectorSize) {
            var v = Avx2.LoadVector256(ptr + i);
            accVector = Avx2.Add(accVector, v);
        }
    }
    int result = 0;
    var temp = stackalloc int[vectorSize];
    Avx2.Store(temp, accVector);
    for (int j = 0; j < vectorSize; j++) {
        result += temp[j];
    }   
    for (; i < array.Length; i++) {
        result += array[i];
    }
    return result;
}
@insinfo insinfo added the feature Proposed language feature that solves one or more problems label Jul 26, 2021
@Levi-Lesches
Copy link

Can you elaborate on exactly what you mean by "Unsafe Contexts"? Is there a difference between "Unsafe" and "Insecure"?

Do many other seemingly "impossible things"

Again, being specific will help here. Not just with what you want, but how you propose it be done. It's a lot to say "do the impossible" with no more explanation!

The only Dart-specific request I see in your comment is

Create an object but not run its constructor

Can you describe in a bit of detail what the resulting value would be? What does it mean to have an object with none of its fields set? When you run a constructor, even an empty one such as the following:

class A {
  final bool condition = true;
  const A():
}

I believe the constructor is still being run -- it's setting condition to true implicitly. Even if I'm wrong about that, the following is still troubling:

class B {
  final bool condition;
  const B(this.condition);
}

What should condition be? It can't be null. How about this:

class C {
  final bool? condition;
  const C([this.condition]);
}

What should condition be here? It's not null, because if the constructor doesn't run, it's never been set to null (for more on that, see the difference between an uninitialized late value and null: #324, as well as undefined vs null: #877). Generative constructors are a big deal in Dart, and getting rid of the guarantee that they are always run before the object is used is a big deal (see this StackOverflow question).

@insinfo
Copy link
Author

insinfo commented Jul 27, 2021

Maybe I've misexpressed myself, but what I mean by "unsafe context" would basically be a block of code where the garbage collector doesn't get involved, where you can handle memory allocations and deallocations manually, a block of code that you can handle pointers, basically a piece of unmanaged code.

example of c# like

class TestPointer {
     unsafe void run() {
        int[] arr = {10, 7, 13, 54, 99};
        fixed(int *ptr = arr)
        for ( int i = 0; i < 5; i++)
        {
           print("arr[{0}] = {1}", i, *(ptr + i));
        }
     }
  }

Do many other seemingly "impossible things"

What I meant by that was that it would be possible to do things that are otherwise unfeasible to do with manageable code (GC)

https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/language-specification/unsafe-code
https://blogs.oracle.com/javamagazine/the-unsafe-class-unsafe-at-any-speed

This feature does not affect current developers, it would not change the philosophy of dart at all, it would be a resource for experienced programmers to get the most out of dart and at some points where you need maximum performance you could easily without leaving dart create optimized code .

@GMChristo
Copy link

this is a good think to gain more control on Dynamic memory allocation to improve the time of processament, every this whithout any interruption from the garbage collector

@mraleph
Copy link
Member

mraleph commented Jul 27, 2021

Some of the features you are asking for already exist - they live in dart:ffi library, which allows direct access to native memory and manual memory management.

There is no support for stack allocation or inline assembly/intrinsics yet. I have been entertaining some ideas of how we could expose something like inline assembly in Dart but have not made any definitive designs or prototypes for that yet.

Though if you want to write sizable chunks of unmanaged code then I’d say you should better use an unmanaged language of your choice and bind to the result through dart:ffi.

@insinfo
Copy link
Author

insinfo commented Jul 27, 2021

I have been entertaining some ideas of how we could expose something like inline assembly in Dart

Good to know I'm not the only one thinking about it, the idea is definitely not to write sizable chunks of unmanaged code.

The idea would be to have small pieces of code that could be optimized to extract maximum performance from the available hardware.

some syntactic sugar for that would be nice, maybe a reserved word to separate the scope from unmanaged code would be nice

@ygordaudt
Copy link

It sounds good.

@ChristianKleineidam
Copy link

Dart code is supposed to be able to be compiled into many different platforms. If you propose a semantics like "unsafe context" you have to specify what it will do in all the contexts into which darts currently compiles.

It's not clear to me why you want to write the highly performance relevant code in dart. Why not use FFI and write it in C or Rust?

@ChristianKleineidam
Copy link

along with the Unsafe Context, it would bring intrinsic SIMD and Atomics

What do you want to do with SIMD's that's currently not possible with Dart's SIMD support?

@insinfo
Copy link
Author

insinfo commented Jul 30, 2021

C# and Java also runs in multiple environments and has a form of unsafe, ie running in multiple environments is not an obstacle.

@insinfo
Copy link
Author

insinfo commented Jul 30, 2021

The idea of "unsafe context", goes beyond SIMD, as I said above, having an unsafe code area would allow manual memory manipulation, use of pointers, atomics, etc. It facilitates code optimization in small chunks without relying on FFI and without depending on other programming languages, just like you have inline assembly in C++ or unsafe in C# or Unsafe class in java.

@insinfo
Copy link
Author

insinfo commented Jul 30, 2021

When you are in an insecure context, it is the programmer who has to worry about the environment that is available, check the OS, the hardware if the given instruction is available, that is, the complexity is not on the runtime or implementation side of the language and yes in the programmer who will use this feature.

@leonardomw
Copy link

Good idea! @insinfo

@ChristianKleineidam
Copy link

Java only runs in the Java Virtual Machine and not multiple different enviroments in the sense that Flutter does.

@ykmnkmi
Copy link

ykmnkmi commented Aug 2, 2021

For web application it can be contain JS code (prefer blocks):

void setupAudioWorkletProcessor() {
  unsafe('js') {
    registerProcessor('some-audio-worklet-processor', class extends AudioWorkletProcessor {
      constructor() {
        super();
        // ...
      }

      process(inputs, outputs, parameters) {
        // ...
      }
    });
  } else {
    throw UnsupportedError('unsupported plafrom');
  }  
}

@insinfo
Copy link
Author

insinfo commented Aug 2, 2021

@ChristianKleineidam
Firstly "Flutter" is not "dart", secondly we can't limit the dart language just because a certain platform doesn't support a feature. Following your reasoning, dart cannot have FFI because FFI is not supported in javascript, javascript does not support interacting with C libraries. In other words, its argument is not valid.

And what's more, in the future dart will be compiled for WebAssembly, and in WebAssembly unsafe will work

@ChristianKleineidam
Copy link

Flutter isn't Dart but Dart is intended to be "A client-optimized language for fast apps on any platform".

@insinfo
Copy link
Author

insinfo commented Aug 3, 2021

"fast apps on any platform"

This part hasn't been reached as it could, the garbage collector interrupting execution all the time doesn't help at all, no multithreading support doesn't help either, but the "unsafe context" can help with that, bringing possibilities of optimization of parts of the code, in a more integrated and easier way

@PlugFox
Copy link

PlugFox commented Aug 4, 2021

FFI

@insinfo
Copy link
Author

insinfo commented Apr 26, 2023

@PlugFox
it's not the same thing as FFI it's more like C# unsafe, that you can handle raw pointers in a syntax but c style almost like it's c inline

Unsafe code, pointer types, and function pointers
Article

Most of the C# code you write is "verifiably safe code." Verifiably safe code means .NET tools can verify that the code is safe. In general, safe code doesn't directly access memory using pointers. It also doesn't allocate raw memory. It creates managed objects instead.

C# supports an unsafe context, in which you may write unverifiable code. In an unsafe context, code may use pointers, allocate and free blocks of memory, and call methods using function pointers. Unsafe code in C# isn't necessarily dangerous; it's just code whose safety cannot be verified.

Unsafe code has the following properties:

Methods, types, and code blocks can be defined as unsafe.
In some cases, unsafe code may increase an application's performance by removing array bounds checks.
Unsafe code is required when you call native functions that require pointers.
Using unsafe code introduces security and stability risks.
The code that contains unsafe blocks must be compiled with the AllowUnsafeBlocks compiler option.

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

9 participants