Skip to content

Instantly share code, notes, and snippets.

@tom-tan
Last active August 29, 2015 14:03
Show Gist options
  • Save tom-tan/919e832bf6528e8c32f1 to your computer and use it in GitHub Desktop.
Save tom-tan/919e832bf6528e8c32f1 to your computer and use it in GitHub Desktop.
// Written in the D programming language.
/**
This module includes helper functions to anotate unsafe operations as trusted operations.
See: http://dlang.org/function.html
Here is the list of unsafe operations described in the spec.
- No casting from a pointer type to any type other than void*.
- No casting from any non-pointer type to a pointer type.
- No modification of pointer values.
- Cannot access unions that have pointers or references overlapping with other types.
- Calling any system functions.
- No catching of exceptions that are not derived from class Exception.
- No inline assembler.
- No explicit casting of mutable objects to immutable.
- No explicit casting of immutable objects to mutable.
- No explicit casting of thread local objects to shared.
- No explicit casting of shared objects to thread local.
- No taking the address of a local variable or function parameter.
- Cannot access __gshared variables.
*/
module trusted_wrapper;
// No casting from a pointer type to any type other than void*.
// TODO
// No casting from any non-pointer type to a pointer type.
// TODO
/// No modification of pointer values.
T* trustedPtrArithmetic(string op, T)(T* ptr, size_t s) @trusted pure nothrow @nogc
if (op == "+" || op == "-")
{
return mixin("ptr" ~ op ~ "s");
}
///
@safe unittest
{
auto a = [0, 1, 2];
int* b = a.ptr.trustedPtrArithmetic!"+"(1);
assert(*b == 1);
}
// Cannot access unions that have pointers or references overlapping with other types.
// TODO
/// Calling any system functions.
template assumeTrusted(alias F)
{
import std.traits;
static assert(isUnsafe!F);
alias ArgType = ParameterTypeTuple!F;
static auto assumeTrusted(ArgType args) @trusted
{
return F(args);
}
}
///
@safe unittest
{
auto bar(int b) @system { return b+1; }
auto b = assumeTrusted!bar(5);
assert(b == 6);
// applicable to 0-ary function
auto foo() @system { return 3; }
auto a = assumeTrusted!foo;
assert(a == 3);
// It can be used for alias
alias trustedBar = assumeTrusted!bar;
alias trustedFoo = assumeTrusted!foo;
assert(is(typeof(trustedFoo) == function));
}
// No catching of exceptions that are not derived from class Exception.
// TODO
// No inline assembler.
// TODO
// No explicit casting of mutable objects to immutable.
// TODO
// No explicit casting of immutable objects to mutable.
// TODO
// No explicit casting of thread local objects to shared.
// TODO
// No explicit casting of shared objects to thread local.
// TODO
/// No taking the address of a local variable or function parameter.
T* trustedRef(T)(ref T buf) @trusted pure nothrow @nogc
{
return &buf;
}
///
@safe unittest
{
int a;
int* p = a.trustedRef;
}
// Cannot access __gshared variables.
// TODO
/**
Annotate a pointer slicing as @trusted
This is not in the spec.
*/
T[] trustedPtrSlicing(T)(T* ptr, size_t lb, size_t ub) @trusted pure nothrow @nogc
{
return ptr[lb..ub];
}
///
@safe unittest
{
auto a = [0,1,2];
auto b = a.ptr.trustedPtrSlicing(0, a.length);
assert(a.ptr is b.ptr);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment