10 people like it.
Like the snippet!
IronJS Boxing Struct
This is the struct IronJS uses internally to do NaN-tagging of boxed values, using the technique described here http://blog.mozilla.com/rob-sayre/2010/08/02/mozillas-new-javascript-value-representation/ and here http://article.gmane.org/gmane.comp.lang.lua.general/58908
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
|
open System
open System.Reflection
open System.Reflection.Emit
open System.Runtime.InteropServices
open System.Globalization
//------------------------------------------------------------------------------
// A dynamic value whos type is unknown at runtime.
type [<NoComparison>] [<StructLayout(LayoutKind.Explicit)>] BoxedValue =
struct
//Reference Types
[<FieldOffset(0)>] val mutable Clr : Object
[<FieldOffset(0)>] val mutable Object : CommonObject
[<FieldOffset(0)>] val mutable Array : ArrayObject
[<FieldOffset(0)>] val mutable Func : FunctionObject
[<FieldOffset(0)>] val mutable String : String
[<FieldOffset(0)>] val mutable Scope : BoxedValue array
//Value Types
[<FieldOffset(8)>] val mutable Bool : bool
[<FieldOffset(8)>] val mutable Number : double
//Type & Tag
[<FieldOffset(12)>] val mutable Tag : uint32
[<FieldOffset(14)>] val mutable Marker : uint16
member x.IsNumber = x.Marker < Markers.Tagged
member x.IsTagged = x.Marker > Markers.Number
member x.IsString = x.IsTagged && x.Tag = TypeTags.String
member x.IsObject = x.IsTagged && x.Tag >= TypeTags.Object
member x.IsFunction = x.IsTagged && x.Tag >= TypeTags.Function
member x.IsBoolean = x.IsTagged && x.Tag = TypeTags.Bool
member x.IsUndefined = x.IsTagged && x.Tag = TypeTags.Undefined
member x.IsClr = x.IsTagged && x.Tag = TypeTags.Clr
member x.IsPrimitive =
if x.IsNumber then
true
else
match x.Tag with
| TypeTags.String
| TypeTags.Bool -> true
| _ -> false
member x.ClrBoxed =
if x.IsNumber
then x.Number :> obj
elif x.Tag = TypeTags.Bool
then x.Bool :> obj
else x.Clr
member x.Unbox<'a>() = x.ClrBoxed :?> 'a
static member Box(value:CommonObject) =
let mutable box = BoxedValue()
box.Clr <- value
box.Tag <- TypeTags.Object
box
static member Box(value:FunctionObject) =
let mutable box = BoxedValue()
box.Clr <- value
box.Tag <- TypeTags.Function
box
static member Box(value:String) =
let mutable box = BoxedValue()
box.Clr <- value
box.Tag <- TypeTags.String
box
static member Box(value:double) =
let mutable box = BoxedValue()
box.Number <- value
box
static member Box(value:bool) =
let mutable box = BoxedValue()
box.Number <- TaggedBools.ToTagged value
box
static member Box(value:Object) =
let mutable box = BoxedValue()
box.Clr <- value
box.Tag <- TypeTags.Clr
box
static member Box(value:Object, tag:uint32) =
let mutable box = BoxedValue()
box.Clr <- value
box.Tag <- tag
box
static member Box(value:Undefined) =
Utils2.BoxedUndefined
end
|
namespace System
namespace System.Reflection
namespace System.Reflection.Emit
namespace System.Runtime
namespace System.Runtime.InteropServices
namespace System.Globalization
Multiple items
type NoComparisonAttribute =
inherit Attribute
new : unit -> NoComparisonAttribute
Full name: Microsoft.FSharp.Core.NoComparisonAttribute
--------------------
new : unit -> NoComparisonAttribute
Multiple items
type StructLayoutAttribute =
inherit Attribute
new : layoutKind:LayoutKind -> StructLayoutAttribute + 1 overload
val Pack : int
val Size : int
val CharSet : CharSet
member Value : LayoutKind
Full name: System.Runtime.InteropServices.StructLayoutAttribute
--------------------
StructLayoutAttribute(layoutKind: LayoutKind) : unit
StructLayoutAttribute(layoutKind: int16) : unit
type LayoutKind =
| Sequential = 0
| Explicit = 2
| Auto = 3
Full name: System.Runtime.InteropServices.LayoutKind
field LayoutKind.Explicit = 2
type BoxedValue =
struct
val mutable Clr: Object
val mutable Object: obj
val mutable Array: obj
val mutable Func: obj
val mutable String: String
val mutable Scope: BoxedValue array
val mutable Bool: bool
val mutable Number: double
val mutable Tag: uint32
val mutable Marker: uint16
...
end
Full name: Script.BoxedValue
Multiple items
type FieldOffsetAttribute =
inherit Attribute
new : offset:int -> FieldOffsetAttribute
member Value : int
Full name: System.Runtime.InteropServices.FieldOffsetAttribute
--------------------
FieldOffsetAttribute(offset: int) : unit
BoxedValue.Clr: Object
Multiple items
type Object =
new : unit -> obj
member Equals : obj:obj -> bool
member GetHashCode : unit -> int
member GetType : unit -> Type
member ToString : unit -> string
static member Equals : objA:obj * objB:obj -> bool
static member ReferenceEquals : objA:obj * objB:obj -> bool
Full name: System.Object
--------------------
Object() : unit
Multiple items
BoxedValue.Object: obj
--------------------
type Object =
new : unit -> obj
member Equals : obj:obj -> bool
member GetHashCode : unit -> int
member GetType : unit -> Type
member ToString : unit -> string
static member Equals : objA:obj * objB:obj -> bool
static member ReferenceEquals : objA:obj * objB:obj -> bool
Full name: System.Object
--------------------
Object() : unit
Multiple items
BoxedValue.Array: obj
--------------------
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...
Full name: System.Array
Multiple items
BoxedValue.Func: obj
--------------------
type Func<'TResult> =
delegate of unit -> 'TResult
Full name: System.Func<_>
--------------------
type Func<'T,'TResult> =
delegate of 'T -> 'TResult
Full name: System.Func<_,_>
--------------------
type Func<'T1,'T2,'TResult> =
delegate of 'T1 * 'T2 -> 'TResult
Full name: System.Func<_,_,_>
--------------------
type Func<'T1,'T2,'T3,'TResult> =
delegate of 'T1 * 'T2 * 'T3 -> 'TResult
Full name: System.Func<_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 -> 'TResult
Full name: System.Func<_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'TResult
Full name: System.Func<_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'T16,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
Multiple items
BoxedValue.String: String
--------------------
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
BoxedValue.Scope: BoxedValue array
type 'T array = 'T []
Full name: Microsoft.FSharp.Core.array<_>
BoxedValue.Bool: bool
type bool = Boolean
Full name: Microsoft.FSharp.Core.bool
BoxedValue.Number: double
Multiple items
val double : value:'T -> float (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.double
--------------------
type double = Double
Full name: Microsoft.FSharp.Core.double
BoxedValue.Tag: uint32
Multiple items
val uint32 : value:'T -> uint32 (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.uint32
--------------------
type uint32 = UInt32
Full name: Microsoft.FSharp.Core.uint32
BoxedValue.Marker: uint16
Multiple items
val uint16 : value:'T -> uint16 (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.uint16
--------------------
type uint16 = UInt16
Full name: Microsoft.FSharp.Core.uint16
val x : byref<BoxedValue>
member BoxedValue.IsNumber : bool
Full name: Script.BoxedValue.IsNumber
member BoxedValue.IsTagged : bool
Full name: Script.BoxedValue.IsTagged
member BoxedValue.IsString : bool
Full name: Script.BoxedValue.IsString
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
member BoxedValue.IsObject : bool
Full name: Script.BoxedValue.IsObject
member BoxedValue.IsFunction : bool
Full name: Script.BoxedValue.IsFunction
member BoxedValue.IsBoolean : bool
Full name: Script.BoxedValue.IsBoolean
member BoxedValue.IsUndefined : bool
Full name: Script.BoxedValue.IsUndefined
member BoxedValue.IsClr : bool
Full name: Script.BoxedValue.IsClr
member BoxedValue.IsPrimitive : bool
Full name: Script.BoxedValue.IsPrimitive
member BoxedValue.ClrBoxed : obj
Full name: Script.BoxedValue.ClrBoxed
type obj = Object
Full name: Microsoft.FSharp.Core.obj
member BoxedValue.Unbox : unit -> 'a
Full name: Script.BoxedValue.Unbox
static member BoxedValue.Box : value:'d -> BoxedValue
Full name: Script.BoxedValue.Box
val value : 'd
val mutable box : BoxedValue
static member BoxedValue.Box : value:'c -> BoxedValue
Full name: Script.BoxedValue.Box
val value : 'c
static member BoxedValue.Box : value:String -> BoxedValue
Full name: Script.BoxedValue.Box
val value : String
static member BoxedValue.Box : value:double -> BoxedValue
Full name: Script.BoxedValue.Box
val value : double
static member BoxedValue.Box : value:bool -> BoxedValue
Full name: Script.BoxedValue.Box
val value : bool
static member BoxedValue.Box : value:Object -> BoxedValue
Full name: Script.BoxedValue.Box
val value : Object
static member BoxedValue.Box : value:Object * tag:uint32 -> BoxedValue
Full name: Script.BoxedValue.Box
val tag : uint32
static member BoxedValue.Box : value:'a -> 'b
Full name: Script.BoxedValue.Box
val value : 'a
More information