Last active
August 29, 2015 14:03
-
-
Save tom-tan/919e832bf6528e8c32f1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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