-
Notifications
You must be signed in to change notification settings - Fork 2
/
CompiledScript.h
206 lines (173 loc) · 7.08 KB
/
CompiledScript.h
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#pragma once
#include "interfaces.h"
#include "Vocab99x.h"
#include "Compile\PMachine.h"
#include "Compile\SCO.h"
class sci::Script;
class sci::FunctionBase;
class IDecompileLookups;
//
// Information gleaned from the actual script resources.
//
class ICompiledScriptLookups
{
public:
virtual std::string LookupSelectorName(WORD wIndex) = 0;
virtual std::string LookupKernelName(WORD wIndex) = 0;
virtual std::string LookupClassName(WORD wIndex) = 0;
virtual bool LookupSpeciesPropertyList(WORD wIndex, std::vector<WORD> &props) = 0;
virtual bool LookupSpeciesPropertyListAndValues(WORD wIndex, std::vector<WORD> &props, std::vector<WORD> &values) = 0;
};
class ICompiledScriptSpecificLookups
{
public:
enum ObjectType
{
ObjectTypeSaid,
ObjectTypeString,
ObjectTypeClass,
};
virtual std::string LookupObjectName(WORD wOffset, ObjectType &type) const = 0;
};
class IPrivateSpeciesLookups
{
public:
virtual std::string LookupClassName(WORD wIndex) = 0;
virtual bool LookupSpeciesPropertyList(WORD wIndex, std::vector<WORD> &props) = 0;
virtual bool LookupSpeciesPropertyListAndValues(WORD wIndex, std::vector<WORD> &props, std::vector<WORD> &values) = 0;
};
//
// Information gleaned from the .sco object files that the compiler generates for linking.
//
class IObjectFileScriptLookups
{
public:
virtual std::string ReverseLookupGlobalVariableName(WORD wIndex) = 0;
virtual std::string ReverseLookupPublicExportName(WORD wScript, WORD wIndex) = 0;
};
class GlobalCompiledScriptLookups : public ICompiledScriptLookups
{
public:
bool Load();
std::string LookupSelectorName(WORD wIndex);
std::string LookupKernelName(WORD wIndex);
std::string LookupClassName(WORD wIndex);
bool LookupSpeciesPropertyList(WORD wIndex, std::vector<WORD> &props);
bool LookupSpeciesPropertyListAndValues(WORD wIndex, std::vector<WORD> &props, std::vector<WORD> &values);
private:
SelectorTable _selectors;
KernelTable _kernels;
GlobalClassTable _classes;
};
class ObjectFileScriptLookups : public IObjectFileScriptLookups
{
public:
std::string ReverseLookupGlobalVariableName(WORD wIndex);
std::string ReverseLookupPublicExportName(WORD wScript, WORD wIndex);
private:
bool _GetSCOFile(WORD wScript, CSCOFile &scoFile);
bool _LoadSCOFile(WORD wScript);
std::map<WORD, CSCOFile> _mapScriptToObject;
};
class ILookupPropertyName
{
public:
virtual std::string LookupPropertyName(ICompiledScriptLookups *pLookup, WORD wPropertyIndex) = 0;
};
struct CodeSection
{
WORD begin;
WORD end;
};
class CompiledObjectBase : public ILookupPropertyName
{
public:
CompiledObjectBase() { _fInstance = FALSE; }
bool IsInstance() { return _fInstance; }
bool Create(sci::istream &stream, BOOL fClass, WORD *pwOffset);
std::string &GetName() { return _strName; }
void SetName(PCTSTR pszName) { _strName = pszName; }
WORD GetSuperClass() { return _wSuperClass; }
WORD GetSpecies() { return _wSpecies; }
void AdjustName(PCTSTR pszNewName) { ASSERT(!_fInstance); _strName = pszNewName; }
std::vector<WORD> &GetProperties() { return _propertySelectors; }
std::vector<WORD> &GetMethods() { return _functionSelectors; }
std::vector<WORD> &GetPropertyValues() { return _propertyValues; }
std::vector<WORD> &GetMethodCodePointersTO() { return _functionOffsetsTO; }
void DebugOut(std::ostream &out, bool fRN = false) const;
void Disassemble(std::ostream &out,
ICompiledScriptLookups *pLookups,
IObjectFileScriptLookups *pOFLookups,
ICompiledScriptSpecificLookups *pScriptThings,
const std::vector<BYTE> &scriptResource,
const std::vector<CodeSection> &codeSections,
std::set<WORD> &codePointers);
void DecompileObject(sci::Script &script,
IDecompileLookups &lookups,
const std::vector<BYTE> &scriptResource,
const std::vector<CodeSection> &codeSections,
std::set<WORD> &codePointers);
// ILookupNames
std::string LookupPropertyName(ICompiledScriptLookups *pLookup, WORD wPropertyIndex);
protected:
WORD _wSpecies;
WORD _wSuperClass;
std::string _strName;
WORD _wInfo;
// These start from the 4th position (e.g. leave out species, superclass, --info-- and name)
std::vector<WORD> _propertySelectors;
std::vector<WORD> _propertyValues;
std::vector<WORD> _functionSelectors; // selectors for the methods
std::vector<WORD> _functionOffsetsTO;
bool _fInstance;
WORD _wPosInResource;
// If anything else is added, make sure to add it to the = operator.
};
//
// This represents all the information in a compiled script resources
//
class CompiledScript : /*public ILookupNames, */ public IPrivateSpeciesLookups, public ICompiledScriptSpecificLookups
{
public:
~CompiledScript();
CompiledScript(WORD wScript) { _wScript = wScript; }
BOOL Load(int iScriptNumber);
bool Load(sci::istream &byteStream);
std::vector<CompiledObjectBase*> &GetObjects() { return _objects; }
WORD GetScriptNumber() { return _wScript; }
void DebugOut(std::ostream &out, bool fRN = false) const;
void Disassemble(std::ostream &out, ICompiledScriptLookups *pLookups, IObjectFileScriptLookups *pOFLookups, ILookupNames *pWords, const std::string *pMessage = NULL);
sci::Script *Decompile(IDecompileLookups &lookups, ILookupNames *pWords);
// ICompiledScriptSpecificLookups
std::string LookupObjectName(WORD wOffset, ObjectType &type) const;
// IPrivateSpeciesLookups
std::string LookupClassName(WORD wIndex);
bool LookupSpeciesPropertyList(WORD wIndex, std::vector<WORD> &props);
bool LookupSpeciesPropertyListAndValues(WORD wIndex, std::vector<WORD> &props, std::vector<WORD> &values);
private:
bool _ReadExports(sci::istream &stream);
bool _ReadStrings(sci::istream &stream, WORD wDataSize);
bool _ReadSaids(sci::istream &stream, WORD wDataSize);
std::string _SaidSequenceToString(std::vector<WORD> saidSequence, ILookupNames *pWords);
void _DisassembleFunction(std::ostream &out, ICompiledScriptLookups *pLookups, IObjectFileScriptLookups *pOFLookups, WORD wCodeOffset, std::set<WORD> &sortedCodePointers);
void _DecompileFunction(sci::FunctionBase &func, IDecompileLookups &lookups, WORD wCodeOffsetTO, std::set<WORD> &sortedCodePointersTO);
std::set<WORD> _FindInternalCallsTO();
bool _IsInCodeSection(WORD wOffset);
CompiledObjectBase *_FindObjectWithSpecies(WORD wIndex);
std::vector<CompiledObjectBase*> _objects;
std::vector<WORD> _objectsOffsetTO;
std::vector<WORD> _exportsTO;
std::vector<std::string> _strings;
std::vector<WORD> _stringsOffset;
std::vector<std::string> _saidStrings;
std::vector<std::vector<WORD> > _saids;
std::vector<WORD> _saidsOffset;
std::vector<WORD> _localVars;
std::map<WORD, WORD> _synonyms;
WORD _wScript;
BOOL _fPreloadText;
std::vector<BYTE> _scriptResource;
std::vector<CodeSection> _codeSections;
};
int GetOperandSize(BYTE bOpcode, OperandType operandType);
WORD CalcOffset(WORD wOperandStart, WORD wRelOffset, bool bByte, BYTE bRawOpcode);