@@ -11,14 +11,14 @@ module Elm.Kernel
12import Control.Monad (liftM, liftM2)
12import Control.Monad (liftM, liftM2)
13import Data.Binary (Binary, get, put, getWord8, putWord8)
13import Data.Binary (Binary, get, put, getWord8, putWord8)
14−import qualified Data.ByteString as BS
14+import qualified Data.ByteString.Internal as B
15−import Data.Coerce (coerce)
16import qualified Data.List as List
15import qualified Data.List as List
17import qualified Data.Map as Map
16import qualified Data.Map as Map
18import qualified Data.Name as Name
17import qualified Data.Name as Name
19−import qualified Data.Utf8 as Utf8
20import Data.Word (Word8, Word16)
18import Data.Word (Word8, Word16)
21−import Foreign.Ptr (Ptr, plusPtr)
19+import Foreign.Ptr (Ptr, plusPtr, minusPtr)
20+import Foreign.ForeignPtr (ForeignPtr)
21+import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
23import qualified AST.Source as Src
23import qualified AST.Source as Src
24import qualified Elm.ModuleName as ModuleName
24import qualified Elm.ModuleName as ModuleName
@@ -36,7 +36,7 @@ import qualified Reporting.Annotation as A
39− = JS (Utf8.VeryLong UNCHECKED)
39+ = JS B.ByteString
40 | ElmVar ModuleName.Canonical Name.Name
40 | ElmVar ModuleName.Canonical Name.Name
41 | JsVar Name.Name Name.Name
41 | JsVar Name.Name Name.Name
42 | ElmField Name.Name
42 | ElmField Name.Name
@@ -46,9 +46,6 @@ data Chunk
53-- COUNT FIELDS
50-- COUNT FIELDS
@@ -83,13 +80,13 @@ type Foreigns =
83 Map.Map ModuleName.Raw Pkg.Name
80 Map.Map ModuleName.Raw Pkg.Name
86−fromByteString :: Pkg.Name -> Foreigns -> BS.ByteString -> Maybe Content
83+fromByteString :: Pkg.Name -> Foreigns -> B.ByteString -> Maybe Content
87fromByteString pkg foreigns bytes =
84fromByteString pkg foreigns bytes =
88− case P.fromByteString (parser pkg foreigns) bytes of
85+ case P.fromByteString (parser pkg foreigns) toError bytes of
89− P.Ok content _ ->
86+ Right content ->
90 Just content
87 Just content
92− P.Err () ->
89+ Left () ->
@@ -120,21 +117,21 @@ ignoreError _ _ _ =
121parseChunks :: VarTable -> Enums -> Fields -> Parser () [Chunk]
118parseChunks :: VarTable -> Enums -> Fields -> Parser () [Chunk]
122parseChunks vtable enums fields =
119parseChunks vtable enums fields =
123− P.Parser $ \(P.State pos end indent row col) cok _ cerr _ ->
120+ P.Parser $ \(P.State src pos end indent row col) cok _ cerr _ ->
125 (# chunks, newPos, newRow, newCol #) =
122 (# chunks, newPos, newRow, newCol #) =
126− chompChunks vtable enums fields pos end row col pos []
123+ chompChunks vtable enums fields src pos end row col pos []
128 if newPos == end then
125 if newPos == end then
129− cok chunks (P.State newPos end indent newRow newCol)
126+ cok chunks (P.State src newPos end indent newRow newCol)
131 cerr row col toError
128 cerr row col toError
134−chompChunks :: VarTable -> Enums -> Fields -> Ptr Word8 -> Ptr Word8 -> Word16 -> Word16 -> Ptr Word8 -> [Chunk] -> (# [Chunk], Ptr Word8, Word16, Word16 #)
131+chompChunks :: VarTable -> Enums -> Fields -> ForeignPtr Word8 -> Ptr Word8 -> Ptr Word8 -> Word16 -> Word16 -> Ptr Word8 -> [Chunk] -> (# [Chunk], Ptr Word8, Word16, Word16 #)
135−chompChunks vs es fs pos end row col lastPos revChunks =
132+chompChunks vs es fs src pos end row col lastPos revChunks =
136 if pos >= end then
133 if pos >= end then
137− let !js = Utf8.fromPtr lastPos end in
134+ let !js = toByteString src lastPos end in
138 (# reverse (JS js : revChunks), pos, row, col #)
135 (# reverse (JS js : revChunks), pos, row, col #)
@@ -145,24 +142,34 @@ chompChunks vs es fs pos end row col lastPos revChunks =
145 !pos3 = plusPtr pos 3
142 !pos3 = plusPtr pos 3
147 if pos3 <= end && unsafeIndex pos1 == 0x5F {-_-} then
144 if pos3 <= end && unsafeIndex pos1 == 0x5F {-_-} then
148− let !js = Utf8.fromPtr lastPos pos in
145+ let !js = toByteString src lastPos pos in
149− chompTag vs es fs pos3 end row (col + 3) (JS js : revChunks)
146+ chompTag vs es fs src pos3 end row (col + 3) (JS js : revChunks)
151− chompChunks vs es fs pos1 end row (col + 1) lastPos revChunks
148+ chompChunks vs es fs src pos1 end row (col + 1) lastPos revChunks
153 else if word == 0x0A {-\n-} then
150 else if word == 0x0A {-\n-} then
154− chompChunks vs es fs (plusPtr pos 1) end (row + 1) 1 lastPos revChunks
151+ chompChunks vs es fs src (plusPtr pos 1) end (row + 1) 1 lastPos revChunks
158 !newPos = plusPtr pos (getCharWidth pos end word)
155 !newPos = plusPtr pos (getCharWidth pos end word)
160− chompChunks vs es fs newPos end row (col + 1) lastPos revChunks
157+ chompChunks vs es fs src newPos end row (col + 1) lastPos revChunks
160+toByteString :: ForeignPtr Word8 -> Ptr Word8 -> Ptr Word8 -> B.ByteString
161+toByteString src pos end =
163+ !off = minusPtr pos (unsafeForeignPtrToPtr src)
164+ !len = minusPtr end pos
163-- relies on external checks in chompChunks
170-- relies on external checks in chompChunks
164−chompTag :: VarTable -> Enums -> Fields -> Ptr Word8 -> Ptr Word8 -> Word16 -> Word16 -> [Chunk] -> (# [Chunk], Ptr Word8, Word16, Word16 #)
171+chompTag :: VarTable -> Enums -> Fields -> ForeignPtr Word8 -> Ptr Word8 -> Ptr Word8 -> Word16 -> Word16 -> [Chunk] -> (# [Chunk], Ptr Word8, Word16, Word16 #)
165−chompTag vs es fs pos end row col revChunks =
172+chompTag vs es fs src pos end row col revChunks =
167 (# newPos, newCol #) = Var.chompInnerChars pos end col
174 (# newPos, newCol #) = Var.chompInnerChars pos end col
168 !tagPos = plusPtr pos (-1)
175 !tagPos = plusPtr pos (-1)
@@ -172,7 +179,7 @@ chompTag vs es fs pos end row col revChunks =
173 !name = Name.fromPtr pos newPos
180 !name = Name.fromPtr pos newPos
175− chompChunks vs es fs newPos end row newCol newPos $
182+ chompChunks vs es fs src newPos end row newCol newPos $
176 ElmField name : revChunks
183 ElmField name : revChunks
@@ -183,7 +190,7 @@ chompTag vs es fs pos end row col revChunks =
183 (enum, newEnums) =
190 (enum, newEnums) =
184 lookupEnum (word - 0x30) name es
191 lookupEnum (word - 0x30) name es
186− chompChunks vs newEnums fs newPos end row newCol newPos $
193+ chompChunks vs newEnums fs src newPos end row newCol newPos $
187 JsEnum enum : revChunks
194 JsEnum enum : revChunks
189 else if 0x61 {-a-} <= word && word <= 0x7A {-z-} then
196 else if 0x61 {-a-} <= word && word <= 0x7A {-z-} then
@@ -191,19 +198,19 @@ chompTag vs es fs pos end row col revChunks =
191 (field, newFields) =
198 (field, newFields) =
192 lookupField name fs
199 lookupField name fs
194− chompChunks vs es newFields newPos end row newCol newPos $
201+ chompChunks vs es newFields src newPos end row newCol newPos $
195 JsField field : revChunks
202 JsField field : revChunks
197 else if name == "DEBUG" then
204 else if name == "DEBUG" then
198− chompChunks vs es fs newPos end row newCol newPos (Debug : revChunks)
205+ chompChunks vs es fs src newPos end row newCol newPos (Debug : revChunks)
200 else if name == "PROD" then
207 else if name == "PROD" then
201− chompChunks vs es fs newPos end row newCol newPos (Prod : revChunks)
208+ chompChunks vs es fs src newPos end row newCol newPos (Prod : revChunks)
204 case Map.lookup name vs of
211 case Map.lookup name vs of
205 Just chunk ->
212 Just chunk ->
206− chompChunks vs es fs newPos end row newCol newPos (chunk : revChunks)
213+ chompChunks vs es fs src newPos end row newCol newPos (chunk : revChunks)
208 Nothing ->
215 Nothing ->
209 (# revChunks, pos, row, col #)
216 (# revChunks, pos, row, col #)
@@ -335,7 +342,7 @@ toName (A.At _ exposed) =
335instance Binary Chunk where
342instance Binary Chunk where
336 put chunk =
343 put chunk =
337 case chunk of
344 case chunk of
338− JS a -> putWord8 0 >> put (coerce a :: Utf8.String)
345+ JS a -> putWord8 0 >> put a
339 ElmVar a b -> putWord8 1 >> put a >> put b
346 ElmVar a b -> putWord8 1 >> put a >> put b
340 JsVar a b -> putWord8 2 >> put a >> put b
347 JsVar a b -> putWord8 2 >> put a >> put b
341 ElmField a -> putWord8 3 >> put a
348 ElmField a -> putWord8 3 >> put a
@@ -347,7 +354,7 @@ instance Binary Chunk where
348 do word <- getWord8
355 do word <- getWord8
349 case word of
356 case word of
350− 0 -> liftM toJS get
357+ 0 -> liftM JS get
351 1 -> liftM2 ElmVar get get
358 1 -> liftM2 ElmVar get get
352 2 -> liftM2 JsVar get get
359 2 -> liftM2 JsVar get get
353 3 -> liftM ElmField get
360 3 -> liftM ElmField get
@@ -356,8 +363,3 @@ instance Binary Chunk where
356 6 -> return Debug
363 6 -> return Debug
357 7 -> return Prod
364 7 -> return Prod
358 _ -> error "problem deserializing Elm.Kernel.Chunk"
365 _ -> error "problem deserializing Elm.Kernel.Chunk"
361−toJS :: Utf8.String -> Chunk