1- public class JSRef : Equatable {
1+ public class JSObjectRef : Equatable {
22 let id : UInt32
33 fileprivate init ( id: UInt32 ) {
44 self . id = id
55 }
6- public static func global( ) -> JSRef {
6+ public static func global( ) -> JSObjectRef {
77 . init( id: _JS_Predef_Value_Global)
88 }
99
1010 deinit {
1111
1212 }
1313
14- public static func == ( lhs: JSRef , rhs: JSRef ) -> Bool {
14+ public static func == ( lhs: JSObjectRef , rhs: JSObjectRef ) -> Bool {
1515 return lhs. id == rhs. id
1616 }
1717}
@@ -20,7 +20,7 @@ public enum JSValue: Equatable {
2020 case boolean( Bool )
2121 case string( String )
2222 case number( Int32 )
23- case object( JSRef )
23+ case object( JSObjectRef )
2424}
2525
2626protocol JSValueConvertible {
@@ -35,76 +35,126 @@ extension Bool: JSValueConvertible {
3535
3636import _CJavaScriptKit
3737
38- public func getJSValue ( this : JSRef , name : String ) -> JSValue {
38+ struct RawJSValue {
3939 var kind : JavaScriptValueKind = JavaScriptValueKind_Invalid
4040 var payload1 : JavaScriptPayload = 0
4141 var payload2 : JavaScriptPayload = 0
42- _get_js_value ( this. id, name, Int32 ( name. count) , & kind, & payload1, & payload2)
43- switch kind {
44- case JavaScriptValueKind_Invalid:
45- fatalError ( )
46- case JavaScriptValueKind_Boolean:
47- return . boolean( payload1 != 0 )
48- case JavaScriptValueKind_Number:
49- return . number( Int32 ( bitPattern: payload1) )
50- case JavaScriptValueKind_String:
51- let buffer = malloc ( Int ( payload2) ) !. assumingMemoryBound ( to: UInt8 . self)
52- _load_string ( payload1 as JavaScriptValueId , buffer)
53- let string = String ( decodingCString: UnsafePointer ( buffer) , as: UTF8 . self)
54- return . string( string)
55- case JavaScriptValueKind_Object:
56- return . object( JSRef ( id: payload1) )
57- default :
58- fatalError ( " unreachable " )
42+ }
43+
44+ extension RawJSValue : JSValueConvertible {
45+ func jsValue( ) -> JSValue {
46+ switch kind {
47+ case JavaScriptValueKind_Invalid:
48+ fatalError ( )
49+ case JavaScriptValueKind_Boolean:
50+ return . boolean( payload1 != 0 )
51+ case JavaScriptValueKind_Number:
52+ return . number( Int32 ( bitPattern: payload1) )
53+ case JavaScriptValueKind_String:
54+ // +1 for null terminator
55+ let buffer = malloc ( Int ( payload2 + 1 ) ) !. assumingMemoryBound ( to: UInt8 . self)
56+ defer { free ( buffer) }
57+ _load_string ( payload1 as JavaScriptValueId , buffer)
58+ buffer [ Int ( payload2) ] = 0
59+ let string = String ( decodingCString: UnsafePointer ( buffer) , as: UTF8 . self)
60+ return . string( string)
61+ case JavaScriptValueKind_Object:
62+ return . object( JSObjectRef ( id: payload1) )
63+ default :
64+ fatalError ( " unreachable " )
65+ }
5966 }
6067}
6168
62- public func setJSValue( this: JSRef , name: String , value: JSValue ) {
63-
64- let kind : JavaScriptValueKind
65- let payload1 : JavaScriptPayload
66- let payload2 : JavaScriptPayload
67- switch value {
68- case let . boolean( boolValue) :
69- kind = JavaScriptValueKind_Boolean
70- payload1 = boolValue ? 1 : 0
71- payload2 = 0
72- case let . number( numberValue) :
73- kind = JavaScriptValueKind_Number
74- payload1 = JavaScriptPayload ( bitPattern: numberValue)
75- payload2 = 0
76- case var . string( stringValue) :
77- kind = JavaScriptValueKind_String
78- stringValue. withUTF8 { bufferPtr in
79- let ptrValue = UInt32 ( UInt ( bitPattern: bufferPtr. baseAddress!) )
80- _set_js_value (
81- this. id, name, Int32 ( name. count) ,
82- kind, ptrValue, JavaScriptPayload ( bufferPtr. count)
83- )
69+ extension JSValue {
70+ func withRawJSValue< T> ( _ body: ( RawJSValue ) -> T ) -> T {
71+ let kind : JavaScriptValueKind
72+ let payload1 : JavaScriptPayload
73+ let payload2 : JavaScriptPayload
74+ switch self {
75+ case let . boolean( boolValue) :
76+ kind = JavaScriptValueKind_Boolean
77+ payload1 = boolValue ? 1 : 0
78+ payload2 = 0
79+ case let . number( numberValue) :
80+ kind = JavaScriptValueKind_Number
81+ payload1 = JavaScriptPayload ( bitPattern: numberValue)
82+ payload2 = 0
83+ case var . string( stringValue) :
84+ kind = JavaScriptValueKind_String
85+ return stringValue. withUTF8 { bufferPtr in
86+ let ptrValue = UInt32 ( UInt ( bitPattern: bufferPtr. baseAddress!) )
87+ let rawValue = RawJSValue ( kind: kind, payload1: ptrValue, payload2: JavaScriptPayload ( bufferPtr. count) )
88+ return body ( rawValue)
89+ }
90+ case let . object( ref) :
91+ kind = JavaScriptValueKind_Object
92+ payload1 = ref. id
93+ payload2 = 0
8494 }
85- return
86- case let . object( ref) :
87- kind = JavaScriptValueKind_Object
88- payload1 = ref. id
89- payload2 = 0
95+ let rawValue = RawJSValue ( kind: kind, payload1: payload1, payload2: payload2)
96+ return body ( rawValue)
97+ }
98+ }
99+
100+ public func getJSValue( this: JSObjectRef , name: String ) -> JSValue {
101+ var rawValue = RawJSValue ( )
102+ _get_prop ( this. id, name, Int32 ( name. count) ,
103+ & rawValue. kind,
104+ & rawValue. payload1, & rawValue. payload2)
105+ return rawValue. jsValue ( )
106+ }
107+
108+ public func setJSValue( this: JSObjectRef , name: String , value: JSValue ) {
109+ value. withRawJSValue { rawValue in
110+ _set_prop ( this. id, name, Int32 ( name. count) , rawValue. kind, rawValue. payload1, rawValue. payload2)
111+ }
112+ }
113+
114+
115+ public func getJSValue( this: JSObjectRef , index: Int32 ) -> JSValue {
116+ var rawValue = RawJSValue ( )
117+ _get_subscript ( this. id, index,
118+ & rawValue. kind,
119+ & rawValue. payload1, & rawValue. payload2)
120+ return rawValue. jsValue ( )
121+ }
122+
123+
124+ public func setJSValue( this: JSObjectRef , index: Int32 , value: JSValue ) {
125+ value. withRawJSValue { rawValue in
126+ _set_subscript ( this. id, index,
127+ rawValue. kind,
128+ rawValue. payload1, rawValue. payload2)
90129 }
91- _set_js_value ( this. id, name, Int32 ( name. count) , kind, payload1, payload2)
92130}
93131
94132
95133#if Xcode
96- func _set_js_value (
134+ func _set_prop (
97135 _ _this: JavaScriptValueId ,
98136 _ prop: UnsafePointer < Int8 > ! , _ length: Int32 ,
99137 _ kind: JavaScriptValueKind ,
100138 _ payload1: JavaScriptPayload ,
101139 _ payload2: JavaScriptPayload ) { fatalError ( ) }
102- func _get_js_value (
140+ func _get_prop (
103141 _ _this: JavaScriptValueId ,
104142 _ prop: UnsafePointer < Int8 > ! , _ length: Int32 ,
105143 _ kind: UnsafeMutablePointer < JavaScriptValueKind > ! ,
106144 _ payload1: UnsafeMutablePointer < JavaScriptPayload > ! ,
107145 _ payload2: UnsafeMutablePointer < JavaScriptPayload > ! ) { fatalError ( ) }
146+ func _set_subscript(
147+ _ _this: JavaScriptValueId ,
148+ _ index: Int32 ,
149+ _ kind: JavaScriptValueKind ,
150+ _ payload1: JavaScriptPayload ,
151+ _ payload2: JavaScriptPayload ) { fatalError ( ) }
152+ func _get_subscript(
153+ _ _this: JavaScriptValueId ,
154+ _ index: Int32 ,
155+ _ kind: UnsafeMutablePointer < JavaScriptValueKind > ! ,
156+ _ payload1: UnsafeMutablePointer < JavaScriptPayload > ! ,
157+ _ payload2: UnsafeMutablePointer < JavaScriptPayload > ! ) { fatalError ( ) }
108158func _load_string(
109159 _ ref: JavaScriptValueId ,
110160 _ buffer: UnsafeMutablePointer < UInt8 > ! ) { fatalError ( ) }
0 commit comments