-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathevil.pas
More file actions
111 lines (103 loc) · 2.55 KB
/
evil.pas
File metadata and controls
111 lines (103 loc) · 2.55 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
program evil;
{$mode objfpc}
{$H+}
uses
{$ifdef unix}cthreads, {$endif}SysUtils, Classes, ScriptEngine;
type
// Helper class to print stack trace, including global variables
TSEStackTraceHandler = class
procedure PrintVariables(Message: String; StackTraceArray: TSEStackTraceSymbolArray);
end;
procedure TSEStackTraceHandler.PrintVariables(Message: String; StackTraceArray: TSEStackTraceSymbolArray);
procedure PrintNode(const Root: Boolean; const StackNode: PSEStackTraceSymbol; const Spacing: String);
var
I: Integer;
S: String;
begin
// Do not show compiler's hidden variables
if (not Root) and (StackNode^.Name.IndexOf('___') = 0) then
Exit;
S := StackNode^.Value;
if Length(S) > 40 then
begin
SetLength(S, 40);
S := S + '...';
end;
if Root then
Writeln('--- ', StackNode^.Name, ' ---')
else
Writeln(Spacing, StackNode^.Name + ' (' + ValueKindNames[StackNode^.Kind] + '): ' + S);
for I := 0 to Length(StackNode^.Childs) - 1 do
PrintNode(False, @StackNode^.Childs[I], Spacing + ' ');
end;
var
I: Integer;
begin
for I := 0 to Length(StackTraceArray) - 1 do
begin
PrintNode(True, @StackTraceArray[I], ' ');
end;
end;
var
SE: TScriptEngine;
SL: TStrings;
IsD: Boolean = False;
IsO: Boolean = True;
IsA: Boolean = False;
IsP: Boolean = True;
I: Integer;
AsmStr: String;
begin
if ParamCount < 1 then
begin
Writeln('Usage: evil <options> [script file]');
Writeln('Options: ');
Writeln(' -d : Disassembly');
Writeln(' -do : Disable optimizations');
Writeln(' -da : Disable assertions');
Writeln(' -dp : Disable parallel garbage collector');
Halt;
end;
if ParamCount > 1 then
begin
for I := 1 to ParamCount - 1 do
case ParamStr(I) of
'-d':
IsD := True;
'-do':
IsO := False;
'-da':
IsA := True;
'-dp':
IsP := False;
end;
end;
Randomize;
GC.EnableParallel := IsP;
SE := TScriptEngine.Create;
SE.OptimizePeephole := IsO;
SE.OptimizeConstantFolding := IsO;
SE.OptimizeAsserts := IsA;
SE.StackTraceHandler := @TSEStackTraceHandler(nil).PrintVariables;
SL := TStringList.Create;
try
try
SL.LoadFromFile(ParamStr(ParamCount));
SE.Source := SL.Text;
if IsD then
begin
SE.Lex;
SE.Parse;
SEDisAsm(SE.VM, AsmStr);
Writeln(AsmStr);
end else
SE.Exec;
except
on E: Exception do
Writeln(E.Message);
end;
finally
SE.Free;
SL.Free;
end;
end.