Skip to content

Instantly share code, notes, and snippets.

@DarkDimius
Created April 24, 2013 19:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DarkDimius/5455028 to your computer and use it in GitHub Desktop.
Save DarkDimius/5455028 to your computer and use it in GitHub Desktop.
def readVolatile[T](l: T): T = macro readVolatile_impl[T]
def readVolatile_impl[T: c.WeakTypeTag](c: Context)(l: c.Expr[T]): c.Expr[T] = {
import c.universe._
l.tree match {
case Select(obj, sel) =>
val name = c.Expr[String](Literal(Constant(sel.encoded)))
val objRef = c.Expr[Any](obj)
l.actualType match {
case x if (x =:= typeOf[Int]) => reify {
{
val unsafe = getUnsafe()
val ob = objRef.splice
val obField = ob.getClass.getDeclaredField(name.splice)
val offset = unsafe.fieldOffset(obField)
unsafe.getIntVolatile(ob, offset).asInstanceOf[T]
}
}
case x if (x =:= typeOf[Long]) => reify {
{
val unsafe = getUnsafe()
val ob = objRef.splice
val obField = ob.getClass.getDeclaredField(name.splice)
val offset = unsafe.fieldOffset(obField)
unsafe.getLongVolatile(ob, offset).asInstanceOf[T]
}
}
case x if (x =:= typeOf[Byte]) => reify {
{
val unsafe = getUnsafe()
val ob = objRef.splice
val obField = ob.getClass.getDeclaredField(name.splice)
val offset = unsafe.fieldOffset(obField)
unsafe.getByteVolatile(ob, offset).asInstanceOf[T]
}
}
case x if (x =:= typeOf[Boolean]) => reify {
{
val unsafe = getUnsafe()
val ob = objRef.splice
val obField = ob.getClass.getDeclaredField(name.splice)
val offset = unsafe.fieldOffset(obField)
unsafe.getBooleanVolatile(ob, offset).asInstanceOf[T]
}
}
case x if (x =:= typeOf[Double]) => reify {
{
val unsafe = getUnsafe()
val ob = objRef.splice
val obField = ob.getClass.getDeclaredField(name.splice)
val offset = unsafe.fieldOffset(obField)
unsafe.getDoubleVolatile(ob, offset).asInstanceOf[T]
}
}
case x if (x =:= typeOf[Float]) => reify {
{
val unsafe = getUnsafe()
val ob = objRef.splice
val obField = ob.getClass.getDeclaredField(name.splice)
val offset = unsafe.fieldOffset(obField)
unsafe.getFloatVolatile(ob, offset).asInstanceOf[T]
}
}
case x if(x =:= typeOf[Short]) => reify
{ {
val unsafe = getUnsafe()
val ob = objRef.splice
val obField = ob.getClass.getDeclaredField(name.splice)
val offset = unsafe.fieldOffset(obField)
unsafe.getShortVolatile(ob,offset).asInstanceOf[T]
}
}
case x if(x<:< typeOf[java.lang.Object]) => reify
{ {
val unsafe = getUnsafe()
val ob = objRef.splice
val obField = ob.getClass.getDeclaredField(name.splice)
val offset = unsafe.fieldOffset(obField)
unsafe.getObjectVolatile(ob,offset).asInstanceOf[T]
}
}
case _ => c.abort(l.tree.pos, "field type " + l.actualType + " not supported")
}
case _ => c.abort(l.tree.pos, "Expected <object>.<field>")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment