177 lines
4.1 KiB
PHP
177 lines
4.1 KiB
PHP
|
|
||
|
struct Error
|
||
|
flags dd ? ; ERR_#
|
||
|
message dd ?
|
||
|
symbol dd ?
|
||
|
preprocessed_data dd ?
|
||
|
preprocessed_length dd ?
|
||
|
next dd ? ; pointer to another Error
|
||
|
; source SourceContext
|
||
|
ends
|
||
|
|
||
|
ERR_CUSTOM = 1
|
||
|
|
||
|
register_volatile_error:
|
||
|
; in:
|
||
|
; edx - 32-bit length followed by string data
|
||
|
; ebx - data for message formatting (only relevant for non-custom messages that contain % character)
|
||
|
; out:
|
||
|
; edx - Error
|
||
|
; preserves: eax, ebx, ecx, esi, edi
|
||
|
cmp [next_pass_needed],0
|
||
|
jne error_ignored
|
||
|
push eax ebx ecx esi edi
|
||
|
or [message_volatile],1
|
||
|
jmp get_error_line
|
||
|
register_delayed_error:
|
||
|
; in:
|
||
|
; edx - error message
|
||
|
; esi - SourceContext
|
||
|
; ebx - data for message formatting (only relevant for non-custom messages that contain % character)
|
||
|
; out:
|
||
|
; edx - Error
|
||
|
; preserves: eax, ebx, ecx, esi, edi
|
||
|
cmp [next_pass_needed],0
|
||
|
jne error_ignored
|
||
|
push eax ebx ecx esi edi
|
||
|
and [message_volatile],0
|
||
|
and [error_line_start],0
|
||
|
and [error_line_end],0
|
||
|
jmp add_error
|
||
|
register_error:
|
||
|
; in:
|
||
|
; edx - error message
|
||
|
; ebx - data for message formatting (only relevant for non-custom messages that contain % character)
|
||
|
; out:
|
||
|
; edx - Error, null when error was not registered
|
||
|
; preserves: eax, ebx, ecx, esi, edi
|
||
|
cmp [next_pass_needed],0
|
||
|
jne error_ignored
|
||
|
push eax ebx ecx esi edi
|
||
|
and [message_volatile],0
|
||
|
get_error_line:
|
||
|
mov eax,[line_start]
|
||
|
mov [error_line_start],eax
|
||
|
mov ecx,[line_end]
|
||
|
cmp [number_of_line_embeddings],0
|
||
|
je error_line_end_ok
|
||
|
mov eax,[line_embeddings]
|
||
|
mov ecx,[eax+LineEmbedding.previous_end]
|
||
|
error_line_end_ok:
|
||
|
mov [error_line_end],ecx
|
||
|
xor esi,esi
|
||
|
add_error:
|
||
|
mov [error_symbol],ebx
|
||
|
lea ebx,[first_error]
|
||
|
xor ecx,ecx
|
||
|
find_last_error:
|
||
|
mov eax,[ebx]
|
||
|
test eax,eax
|
||
|
jz last_error_found
|
||
|
lea ebx,[eax+Error.next]
|
||
|
inc ecx
|
||
|
cmp ecx,[maximum_number_of_errors]
|
||
|
jb find_last_error
|
||
|
pop edi esi ecx ebx eax
|
||
|
xor edx,edx
|
||
|
retn
|
||
|
last_error_found:
|
||
|
cmp [message_volatile],0
|
||
|
jne prepare_volatile_error
|
||
|
test esi,esi
|
||
|
jnz prepare_error
|
||
|
mov esi,[source_context]
|
||
|
prepare_error:
|
||
|
mov ecx,[esi+SourceContext.number_of_entries]
|
||
|
imul ecx,sizeof.SourceEntry
|
||
|
add ecx,sizeof.SourceContext
|
||
|
cmp [esi+ecx-sizeof.SourceEntry+SourceEntry.type],SOURCE_CALM
|
||
|
jne error_source_context_ready
|
||
|
mov eax,[calm_instruction_number]
|
||
|
mov [esi+ecx-sizeof.SourceEntry+SourceEntry.line_number],eax
|
||
|
and [error_line_start],0
|
||
|
and [error_line_end],0
|
||
|
error_source_context_ready:
|
||
|
add ecx,sizeof.Error
|
||
|
add ecx,[error_line_end]
|
||
|
sub ecx,[error_line_start]
|
||
|
mov edi,edx
|
||
|
call malloc
|
||
|
mov [ebx],eax
|
||
|
mov [eax+Error.message],edi
|
||
|
mov ecx,[error_symbol]
|
||
|
mov [eax+Error.symbol],ecx
|
||
|
xor ecx,ecx
|
||
|
mov [eax+Error.flags],ecx
|
||
|
mov [eax+Error.next],ecx
|
||
|
lea edi,[eax+sizeof.Error]
|
||
|
push eax
|
||
|
call clone_source_context
|
||
|
pop edx
|
||
|
store_preprocessed_data:
|
||
|
mov [edx+Error.preprocessed_data],edi
|
||
|
mov esi,[error_line_start]
|
||
|
mov ecx,[error_line_end]
|
||
|
sub ecx,esi
|
||
|
mov [edx+Error.preprocessed_length],ecx
|
||
|
rep movsb
|
||
|
pop edi esi ecx ebx eax
|
||
|
retn
|
||
|
error_ignored:
|
||
|
xor edx,edx
|
||
|
retn
|
||
|
prepare_volatile_error:
|
||
|
mov esi,edx
|
||
|
mov eax,[source_context]
|
||
|
mov ecx,[eax+SourceContext.number_of_entries]
|
||
|
imul ecx,sizeof.SourceEntry
|
||
|
add ecx,sizeof.SourceContext
|
||
|
cmp [eax+ecx-sizeof.SourceEntry+SourceEntry.type],SOURCE_CALM
|
||
|
jne volatile_error_source_context_ready
|
||
|
mov edx,[calm_instruction_number]
|
||
|
mov [eax+ecx-sizeof.SourceEntry+SourceEntry.line_number],edx
|
||
|
and [error_line_start],0
|
||
|
and [error_line_end],0
|
||
|
volatile_error_source_context_ready:
|
||
|
add ecx,sizeof.Error
|
||
|
add ecx,[error_line_end]
|
||
|
sub ecx,[error_line_start]
|
||
|
mov edi,ecx
|
||
|
add ecx,[esi]
|
||
|
inc ecx
|
||
|
call malloc
|
||
|
add edi,eax
|
||
|
mov [ebx],eax
|
||
|
mov edx,eax
|
||
|
mov [edx+Error.message],edi
|
||
|
xor eax,eax
|
||
|
mov [edx+Error.next],eax
|
||
|
mov [edx+Error.flags],eax
|
||
|
lodsd
|
||
|
mov ecx,eax
|
||
|
rep movsb
|
||
|
xor al,al
|
||
|
stosb
|
||
|
mov esi,[source_context]
|
||
|
lea edi,[edx+sizeof.Error]
|
||
|
push edx
|
||
|
call clone_source_context
|
||
|
pop edx
|
||
|
jmp store_preprocessed_data
|
||
|
|
||
|
discard_errors:
|
||
|
mov eax,[first_error]
|
||
|
test eax,eax
|
||
|
jnz discard_error
|
||
|
retn
|
||
|
discard_error:
|
||
|
add eax,sizeof.Error
|
||
|
call release_source_context
|
||
|
sub eax,sizeof.Error
|
||
|
mov ebx,[eax+Error.next]
|
||
|
call mfree
|
||
|
mov eax,ebx
|
||
|
test eax,eax
|
||
|
jnz discard_error
|
||
|
mov [first_error],eax
|
||
|
retn
|