4 cache dd ? ; pointer to FileCache
\r
10 next dd ? ; pointer to another FileCache
\r
17 ; eax - tokenized source, null when file not found
\r
18 ; esi - source path in persistent storage
\r
19 mov ebx,[file_source_cache]
\r
24 je get_erroneous_source
\r
29 jc source_file_not_found
\r
34 jc error_reading_file
\r
42 jc error_reading_file
\r
45 mov [source_text_length],ecx
\r
47 mov [source_text],eax
\r
49 mov ecx,[source_text_length]
\r
51 mov byte [edx+ecx],0
\r
53 jc error_reading_file
\r
56 call tokenize_source
\r
57 mov eax,[source_text]
\r
60 mov eax,[tokenization_buffer]
\r
62 mov ebx,[file_source_cache]
\r
64 mov eax,[tokenization_buffer]
\r
66 source_file_not_found:
\r
69 mov ebx,[file_source_cache]
\r
76 mov ebx,[file_source_cache]
\r
78 get_erroneous_source:
\r
80 mov edx,_error_reading_file
\r
87 ; esi - ASCIIZ source string
\r
89 ; eax - tokenized source
\r
90 ; esi - source text in persistent storage
\r
96 mov [source_text_length],ecx
\r
97 mov ebx,[memory_source_cache]
\r
100 jc adapt_memory_source
\r
102 adapt_memory_source:
\r
103 mov [source_text],esi
\r
104 call tokenize_source
\r
105 mov eax,[tokenization_buffer]
\r
106 mov esi,[source_text]
\r
107 mov ecx,[source_text_length]
\r
108 mov ebx,[memory_source_cache]
\r
110 mov eax,[tokenization_buffer]
\r
115 ; [source_text] - ASCIIZ text
\r
116 ; [source_text_length] = length of text (including terminating character)
\r
118 ; [tokenization_buffer] - tokenized source
\r
119 ; [tokenization_buffer_length] = length of tokenized source
\r
120 mov ecx,[source_text_length]
\r
123 call malloc_growable
\r
124 mov [tokenization_buffer],eax
\r
125 mov [tokenization_buffer_length],ecx
\r
127 sub eax,[source_text]
\r
128 sub eax,[source_text_length]
\r
129 mov [buffer_end_offset],eax
\r
130 mov esi,[source_text]
\r
131 mov edi,[tokenization_buffer]
\r
132 mov [last_token],0Ah
\r
134 mov eax,[buffer_end_offset]
\r
138 jae tokenization_buffer_reserve_ok
\r
140 sub ecx,[source_text]
\r
141 mov eax,[source_text_length]
\r
142 mul [tokenization_buffer_length]
\r
146 mov eax,[tokenization_buffer]
\r
148 sub edi,[tokenization_buffer]
\r
150 mov [tokenization_buffer],eax
\r
151 mov [tokenization_buffer_length],ecx
\r
153 sub eax,[source_text]
\r
154 sub eax,[source_text_length]
\r
155 mov [buffer_end_offset],eax
\r
156 tokenization_buffer_reserve_ok:
\r
157 movzx eax,byte [esi]
\r
159 mov ah,[characters+eax]
\r
161 je control_character
\r
163 jnz make_name_token
\r
166 mov [last_token],al
\r
171 mov [last_token],22h
\r
186 jne copy_string_character
\r
188 jne finish_string_token
\r
190 copy_string_character:
\r
195 mov byte [edi-5],27h
\r
196 finish_string_token:
\r
203 je make_string_token
\r
205 je make_string_token
\r
207 mov [last_token],1Ah
\r
219 movzx eax,byte [esi]
\r
221 mov ah,[characters+eax]
\r
223 je finish_name_token
\r
235 jne character_token
\r
241 cmp [last_token],20h
\r
242 je mark_end_of_line
\r
245 mov byte [edi-1],0Ah
\r
246 mov [last_token],0Ah
\r
254 mov eax,[tokenization_buffer]
\r
257 mov [tokenization_buffer],eax
\r
258 mov [tokenization_buffer_length],ecx
\r
271 cmp [last_token],0Ah
\r
273 cmp [last_token],20h
\r
277 mov [last_token],al
\r
284 ; ebx - FileData, null when file not found
\r
285 ; esi - file path in persistent storage
\r
287 mov ebx,[file_data_cache]
\r
290 jc initialize_file_data
\r
293 initialize_file_data:
\r
296 jc remember_file_not_found
\r
298 mov ecx,sizeof.FileData
\r
305 jc file_not_seekable
\r
306 mov dword [edi+FileData.length],eax
\r
307 mov dword [edi+FileData.length+4],edx
\r
311 mov [eax+FileData.cache],ecx
\r
312 mov ebx,[file_data_cache]
\r
319 remember_file_not_found:
\r
322 mov ebx,[file_data_cache]
\r
331 ; edi - buffer for data
\r
332 ; [file_offset] = offset of data
\r
333 ; [data_length] = length of data
\r
335 ; cf set when read failed
\r
337 mov [file_data],ebx
\r
338 lea eax,[ebx+FileData.cache]
\r
339 mov [file_cache_pointer],eax
\r
341 read_from_file_cache:
\r
342 mov ecx,[data_length]
\r
346 jz new_trailing_file_cache_entry
\r
347 mov eax,dword [file_offset]
\r
348 mov edx,dword [file_offset+4]
\r
349 sub eax,dword [ebx+FileCache.offset]
\r
350 sbb edx,dword [ebx+FileCache.offset+4]
\r
351 jc new_file_cache_entry
\r
353 mov edx,[ebx+FileCache.length]
\r
357 jbe length_to_read_ok
\r
360 sub [data_length],ecx
\r
361 add dword [file_offset],ecx
\r
362 adc dword [file_offset+4],0
\r
364 lea esi,[ebx+sizeof.FileCache+eax]
\r
373 lea eax,[ebx+FileCache.next]
\r
374 mov [file_cache_pointer],eax
\r
376 jmp read_from_file_cache
\r
380 new_trailing_file_cache_entry:
\r
381 mov ebx,[file_data]
\r
382 mov ecx,dword [ebx+FileData.length]
\r
383 mov edx,dword [ebx+FileData.length+4]
\r
384 cmp ecx,dword [file_offset]
\r
385 jne measure_cache_gap
\r
386 cmp edx,dword [file_offset+4]
\r
387 jne measure_cache_gap
\r
390 new_file_cache_entry:
\r
391 mov ecx,dword [ebx+FileCache.offset]
\r
392 mov edx,dword [ebx+FileCache.offset+4]
\r
394 mov eax,dword [file_offset]
\r
397 sbb edx,dword [file_offset+4]
\r
398 jnz compute_aligned_length
\r
399 cmp ecx,[data_length]
\r
400 jbe read_into_cache
\r
401 compute_aligned_length:
\r
402 mov eax,dword [file_offset]
\r
404 add eax,[data_length]
\r
410 jnz use_aligned_length
\r
412 jae read_into_cache
\r
413 use_aligned_length:
\r
417 add ecx,sizeof.FileCache
\r
420 mov eax,[file_cache_pointer]
\r
423 mov [ebx+FileCache.next],edx
\r
424 pop [ebx+FileCache.length]
\r
425 mov eax,dword [file_offset]
\r
427 mov edx,dword [file_offset+4]
\r
428 mov dword [ebx+FileCache.offset],eax
\r
429 mov dword [ebx+FileCache.offset+4],edx
\r
434 jc file_access_error
\r
435 mov eax,dword [edi+FileCache.offset]
\r
436 mov edx,dword [edi+FileCache.offset+4]
\r
439 jc file_access_error
\r
440 lea edx,[edi+sizeof.FileCache]
\r
441 mov ecx,[edi+FileCache.length]
\r
443 jc file_access_error
\r
446 jmp read_from_file_cache
\r