Created
December 10, 2013 04:26
-
-
Save chewxy/7885712 to your computer and use it in GitHub Desktop.
Pointer Tagging in Go
This file contains 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
package main | |
import ( | |
"fmt" | |
"github.com/chewxy/gogogadget" | |
"unsafe" | |
) | |
func main() { | |
var x int64 = 1234 | |
// xPointer is of the *int64 type, meaning it points to | |
// an object in memory that is a int64 | |
var xPointer *int64 = &x | |
// converts xPointer into an unsafe.Pointer, which is then converted | |
// into uintptr, which is then converted into uint | |
var xPointerUint uint = uint(uintptr(unsafe.Pointer(xPointer))) | |
// Prints the binary representation | |
fmt.Println(gogogadget.BinaryRepresentation(xPointerUint)) | |
// makes xPointerUint into a tagged pointer | |
// this destroys any capability of xPointerUint's | |
// capability to be used as a pointer | |
TagPointer(&xPointerUint, uint(5)) | |
fmt.Println(gogogadget.BinaryRepresentation(xPointerUint)) | |
// get a new uint for rtnPointer and tag | |
rtnPointer := ReturnPointer(&xPointerUint) | |
tag := ReturnTag(&xPointerUint) | |
// convert rtnPointer into a *int64, then indirect to get the RestoredValue | |
RestoredValue := *(*int64)(unsafe.Pointer(uintptr(rtnPointer))) | |
fmt.Println(RestoredValue) | |
fmt.Println(tag) | |
} | |
func TagPointer(ptr *uint, i uint) { | |
x := (*ptr | i) | |
*ptr = x | |
} | |
func ReturnPointer(ptr *uint) uint { | |
return (*ptr &^ uint(7)) | |
} | |
func ReturnTag(ptr *uint) uint { | |
return *ptr & uint(7) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment